[gnome-games/wip/abhinavsingh/keyboard-config] Add basic keyboard testing



commit d95967dac8ee80a36d86e0b0ad03184280c2172d
Author: theawless <theawless gmail com>
Date:   Sun Aug 27 21:59:21 2017 +0530

    Add basic keyboard testing

 data/Makefile.am                         |    1 +
 data/org.gnome.Games.gresource.xml       |    1 +
 data/ui/keyboard-configurer.ui           |   77 ++++++++++++++++
 data/ui/preferences-page-controllers.ui  |   73 ++++++++++++---
 src/Makefile.am                          |    1 +
 src/ui/keyboard-configurer.vala          |  144 ++++++++++++++++++++++++++++++
 src/ui/preferences-page-controllers.vala |   21 +++++
 7 files changed, 303 insertions(+), 15 deletions(-)
---
diff --git a/data/Makefile.am b/data/Makefile.am
index fff2a95..c7ec0fd 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -41,6 +41,7 @@ EXTRA_DIST = \
        ui/gamepad-mapper.ui \
        ui/gamepad-tester.ui \
        ui/game-icon-view.ui \
+       ui/keyboard-configurer.ui \
        ui/media-menu-button.ui \
        ui/media-selector.ui \
        ui/preferences-page-controllers.ui \
diff --git a/data/org.gnome.Games.gresource.xml b/data/org.gnome.Games.gresource.xml
index b8ba7b5..0f0da35 100644
--- a/data/org.gnome.Games.gresource.xml
+++ b/data/org.gnome.Games.gresource.xml
@@ -20,6 +20,7 @@
     <file preprocess="xml-stripblanks">ui/gamepad-mapper.ui</file>
     <file preprocess="xml-stripblanks">ui/gamepad-tester.ui</file>
     <file preprocess="xml-stripblanks">ui/game-icon-view.ui</file>
+    <file preprocess="xml-stripblanks">ui/keyboard-configurer.ui</file>
     <file preprocess="xml-stripblanks">ui/media-menu-button.ui</file>
     <file preprocess="xml-stripblanks">ui/media-selector.ui</file>
     <file preprocess="xml-stripblanks">ui/preferences-page-controllers.ui</file>
diff --git a/data/ui/keyboard-configurer.ui b/data/ui/keyboard-configurer.ui
new file mode 100644
index 0000000..310c8d1
--- /dev/null
+++ b/data/ui/keyboard-configurer.ui
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <template class="GamesKeyboardConfigurer" parent="GtkBox">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="orientation">vertical</property>
+    <property name="can_focus">True</property>
+    <child>
+      <object class="GamesGamepadView" id="gamepad_view">
+        <property name="can_focus">True</property>
+        <property name="visible">True</property>
+        <property name="halign">fill</property>
+        <property name="valign">fill</property>
+        <property name="hexpand">True</property>
+        <property name="vexpand">True</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkActionBar" id="action_bar">
+        <property name="visible">True</property>
+        <child>
+          <object class="GtkButton" id="reset_button">
+            <property name="visible">True</property>
+            <property name="label" translatable="yes">Reset</property>
+            <signal name="clicked" handler="on_reset_clicked"/>
+            <style>
+              <class name="destructive-action"/>
+            </style>
+          </object>
+          <packing>
+            <property name="pack-type">end</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkButton" id="configure_button">
+            <property name="visible">True</property>
+            <property name="label" translatable="yes">Configure</property>
+            <signal name="clicked" handler="on_configure_clicked"/>
+            <style>
+              <class name="suggested-action"/>
+            </style>
+          </object>
+          <packing>
+            <property name="pack-type">start</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </template>
+  <object class="GtkHeaderBar" id="header_bar">
+    <property name="visible">True</property>
+    <child>
+      <object class="GtkButton" id="back_button">
+        <property name="visible">True</property>
+        <signal name="clicked" handler="on_back_clicked"/>
+        <style>
+          <class name="image-button"/>
+        </style>
+        <child internal-child="accessible">
+          <object class="AtkObject" id="a11y-back">
+            <property name="accessible-name" translatable="yes">Back</property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkImage" id="back_image">
+            <property name="visible">True</property>
+            <property name="icon-name">go-previous-symbolic</property>
+            <property name="icon-size">1</property>
+          </object>
+        </child>
+      </object>
+      <packing>
+        <property name="pack-type">start</property>
+      </packing>
+    </child>
+  </object>
+</interface>
diff --git a/data/ui/preferences-page-controllers.ui b/data/ui/preferences-page-controllers.ui
index 09bd294..14f3a14 100644
--- a/data/ui/preferences-page-controllers.ui
+++ b/data/ui/preferences-page-controllers.ui
@@ -23,35 +23,78 @@
             <property name="can_focus">False</property>
             <property name="visible">True</property>
             <child>
-              <object class="GtkFrame">
+              <object class="GtkBox">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="border_width">12</property>
-                <property name="valign">start</property>
-                <property name="shadow_type">none</property>
+                <property name="orientation">vertical</property>
                 <child>
-                  <object class="GtkAlignment">
+                  <object class="GtkFrame">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="top_padding">12</property>
+                    <property name="border_width">12</property>
+                    <property name="valign">start</property>
+                    <property name="hexpand">True</property>
+                    <property name="shadow_type">none</property>
                     <child>
-                      <object class="GtkListBox" id="gamepads_list_box">
+                      <object class="GtkAlignment">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="selection_mode">none</property>
-                        <signal name="row-activated" handler="gamepads_list_box_row_activated"/>
+                        <property name="top_padding">12</property>
+                        <child>
+                          <object class="GtkListBox" id="gamepads_list_box">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="selection_mode">none</property>
+                            <signal name="row-activated" handler="gamepads_list_box_row_activated"/>
+                          </object>
+                        </child>
+                      </object>
+                    </child>
+                    <child type="label">
+                      <object class="GtkLabel">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">Gamepads</property>
+                        <attributes>
+                          <attribute name="weight" value="bold"/>
+                        </attributes>
                       </object>
                     </child>
                   </object>
                 </child>
-                <child type="label">
-                  <object class="GtkLabel">
+                <child>
+                  <object class="GtkFrame">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="label" translatable="yes">Gamepads</property>
-                    <attributes>
-                      <attribute name="weight" value="bold"/>
-                    </attributes>
+                    <property name="border_width">12</property>
+                    <property name="valign">start</property>
+                    <property name="hexpand">True</property>
+                    <property name="shadow_type">none</property>
+                    <child>
+                      <object class="GtkAlignment">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="top_padding">12</property>
+                        <child>
+                          <object class="GtkListBox" id="keyboard_list_box">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="selection_mode">none</property>
+                            <signal name="row-activated" handler="keyboard_list_box_row_activated"/>
+                          </object>
+                        </child>
+                      </object>
+                    </child>
+                    <child type="label">
+                      <object class="GtkLabel">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">Keyboard</property>
+                        <attributes>
+                          <attribute name="weight" value="bold"/>
+                        </attributes>
+                      </object>
+                    </child>
                   </object>
                 </child>
               </object>
diff --git a/src/Makefile.am b/src/Makefile.am
index 645eb45..a635bf7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -153,6 +153,7 @@ gnome_games_SOURCES = \
        ui/game-icon-view.vala \
        ui/game-thumbnail.vala \
        ui/gamepad-view-configuration.vala \
+       ui/keyboard-configurer.vala \
        ui/media-selector.vala \
        ui/media-menu-button.vala \
        ui/preferences-page.vala \
diff --git a/src/ui/keyboard-configurer.vala b/src/ui/keyboard-configurer.vala
new file mode 100644
index 0000000..868d6d0
--- /dev/null
+++ b/src/ui/keyboard-configurer.vala
@@ -0,0 +1,144 @@
+// This file is part of GNOME Games. License: GPL-3.0+.
+
+[GtkTemplate (ui = "/org/gnome/Games/ui/keyboard-configurer.ui")]
+private class Games.KeyboardConfigurer : Gtk.Box {
+       private const GamepadInput[] STANDARD_GAMEPAD_INPUTS = {
+               { EventCode.EV_KEY, EventCode.BTN_A },
+               { EventCode.EV_KEY, EventCode.BTN_B },
+               { EventCode.EV_KEY, EventCode.BTN_X },
+               { EventCode.EV_KEY, EventCode.BTN_Y },
+               { EventCode.EV_KEY, EventCode.BTN_START },
+               { EventCode.EV_KEY, EventCode.BTN_MODE },
+               { EventCode.EV_KEY, EventCode.BTN_SELECT },
+               { EventCode.EV_KEY, EventCode.BTN_THUMBL },
+               { EventCode.EV_KEY, EventCode.BTN_THUMBR },
+               { EventCode.EV_KEY, EventCode.BTN_TL },
+               { EventCode.EV_KEY, EventCode.BTN_TR },
+               { EventCode.EV_KEY, EventCode.BTN_DPAD_UP },
+               { EventCode.EV_KEY, EventCode.BTN_DPAD_LEFT },
+               { EventCode.EV_KEY, EventCode.BTN_DPAD_DOWN },
+               { EventCode.EV_KEY, EventCode.BTN_DPAD_RIGHT },
+               { EventCode.EV_ABS, EventCode.ABS_X },
+               { EventCode.EV_ABS, EventCode.ABS_Y },
+               { EventCode.EV_ABS, EventCode.ABS_RX },
+               { EventCode.EV_ABS, EventCode.ABS_RY },
+               { EventCode.EV_KEY, EventCode.BTN_TL2 },
+               { EventCode.EV_KEY, EventCode.BTN_TR2 },
+       };
+
+       private const GamepadInputPath[] STANDARD_GAMEPAD_INPUT_PATHS = {
+               { { EventCode.EV_ABS, EventCode.ABS_X }, "leftx" },
+               { { EventCode.EV_ABS, EventCode.ABS_Y }, "lefty" },
+               { { EventCode.EV_ABS, EventCode.ABS_RX }, "rightx" },
+               { { EventCode.EV_ABS, EventCode.ABS_RY }, "righty" },
+               { { EventCode.EV_KEY, EventCode.BTN_A }, "a" },
+               { { EventCode.EV_KEY, EventCode.BTN_B }, "b" },
+               { { EventCode.EV_KEY, EventCode.BTN_DPAD_DOWN }, "dpdown" },
+               { { EventCode.EV_KEY, EventCode.BTN_DPAD_LEFT }, "dpleft" },
+               { { EventCode.EV_KEY, EventCode.BTN_DPAD_RIGHT }, "dpright" },
+               { { EventCode.EV_KEY, EventCode.BTN_DPAD_UP }, "dpup" },
+               { { EventCode.EV_KEY, EventCode.BTN_MODE }, "guide" },
+               { { EventCode.EV_KEY, EventCode.BTN_SELECT }, "back" },
+               { { EventCode.EV_KEY, EventCode.BTN_TL }, "leftshoulder" },
+               { { EventCode.EV_KEY, EventCode.BTN_TR }, "rightshoulder" },
+               { { EventCode.EV_KEY, EventCode.BTN_START }, "start" },
+               { { EventCode.EV_KEY, EventCode.BTN_THUMBL }, "leftstick" },
+               { { EventCode.EV_KEY, EventCode.BTN_THUMBR }, "rightstick" },
+               { { EventCode.EV_KEY, EventCode.BTN_TL2 }, "lefttrigger" },
+               { { EventCode.EV_KEY, EventCode.BTN_TR2 }, "righttrigger" },
+               { { EventCode.EV_KEY, EventCode.BTN_Y }, "x" },
+               { { EventCode.EV_KEY, EventCode.BTN_X }, "y" },
+       };
+
+       private const GamepadViewConfiguration STANDARD_GAMEPAD_VIEW_CONFIGURATION = {
+               "resource:///org/gnome/Games/gamepads/standard-gamepad.svg", STANDARD_GAMEPAD_INPUT_PATHS
+       };
+
+       public signal void back ();
+
+       [GtkChild (name = "header_bar")]
+       private Gtk.HeaderBar _header_bar;
+       public Gtk.HeaderBar header_bar {
+               private set {}
+               get { return _header_bar; }
+       }
+
+       [GtkChild]
+       private Gtk.ActionBar action_bar;
+       [GtkChild]
+       private Gtk.Button back_button;
+       [GtkChild]
+       private GamepadView gamepad_view;
+
+       private Retro.VirtualGamepad keyboard;
+
+       construct {
+               keyboard = new Retro.VirtualGamepad (this);
+               try {
+                       gamepad_view.set_configuration (STANDARD_GAMEPAD_VIEW_CONFIGURATION);
+               }
+               catch (Error e) {
+                       critical ("Could not set up gamepad view: %s", e.message);
+               }
+
+               GLib.Timeout.add (10, update_gamepad_view);
+       }
+
+       private bool update_gamepad_view () {
+               if (gamepad_view == null)
+                       return false;
+
+               var enumc = (EnumClass) typeof (Retro.JoypadId).class_ref ();
+               foreach (var enumv in enumc.values) {
+                       var highlight = keyboard.get_button_pressed ((Retro.JoypadId) enumv.value);
+                       var code = get_eventcode_from_joypad_id ((Retro.JoypadId) enumv.value);
+                       gamepad_view.highlight ({ EventCode.EV_KEY, code }, highlight);
+               }
+
+               return true;
+       }
+
+       private uint16 get_eventcode_from_joypad_id (Retro.JoypadId button) {
+               switch (button) {
+               case Retro.JoypadId.B:
+                       return EventCode.BTN_A;
+               case Retro.JoypadId.Y:
+                       return EventCode.BTN_Y;
+               case Retro.JoypadId.SELECT:
+                       return EventCode.BTN_SELECT;
+               case Retro.JoypadId.START:
+                       return EventCode.BTN_START;
+               case Retro.JoypadId.UP:
+                       return EventCode.BTN_DPAD_UP;
+               case Retro.JoypadId.DOWN:
+                       return EventCode.BTN_DPAD_DOWN;
+               case Retro.JoypadId.LEFT:
+                       return EventCode.BTN_DPAD_LEFT;
+               case Retro.JoypadId.RIGHT:
+                       return EventCode.BTN_DPAD_RIGHT;
+               case Retro.JoypadId.A:
+                       return EventCode.BTN_B;
+               case Retro.JoypadId.X:
+                       return EventCode.BTN_X;
+               case Retro.JoypadId.L:
+                       return EventCode.BTN_TL;
+               case Retro.JoypadId.R:
+                       return EventCode.BTN_TR;
+               case Retro.JoypadId.L2:
+                       return EventCode.BTN_TL2;
+               case Retro.JoypadId.R2:
+                       return EventCode.BTN_TR2;
+               case Retro.JoypadId.L3:
+                       return EventCode.BTN_THUMBL;
+               case Retro.JoypadId.R3:
+                       return EventCode.BTN_THUMBR;
+               default:
+                       return EventCode.KEY_MAX;
+               }
+       }
+
+       [GtkCallback]
+       private void on_back_clicked () {
+               back ();
+       }
+}
diff --git a/src/ui/preferences-page-controllers.vala b/src/ui/preferences-page-controllers.vala
index 4f619a9..3cc7bfb 100644
--- a/src/ui/preferences-page-controllers.vala
+++ b/src/ui/preferences-page-controllers.vala
@@ -8,6 +8,8 @@ private class Games.PreferencesPageControllers: Gtk.Stack, PreferencesPage {
        [GtkChild]
        private Gtk.ListBox gamepads_list_box;
        [GtkChild]
+       private Gtk.ListBox keyboard_list_box;
+       [GtkChild]
        private Gtk.Box extra_stack_child_holder;
        [GtkChild]
        private Gtk.HeaderBar default_header_bar;
@@ -26,6 +28,7 @@ private class Games.PreferencesPageControllers: Gtk.Stack, PreferencesPage {
                gamepad_monitor.gamepad_unplugged.connect (rebuild_gamepad_list);
                gamepad_monitor.gamepad_plugged.connect (rebuild_gamepad_list);
                build_gamepad_list ();
+               build_keyboard_list ();
        }
 
        public void visible_page_changed () {
@@ -75,6 +78,24 @@ private class Games.PreferencesPageControllers: Gtk.Stack, PreferencesPage {
                set_visible_child_name ("extra_stack_child");
        }
 
+       private void build_keyboard_list () {
+               var box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
+               box.pack_start (new Gtk.Label ("Keyboard"), false, false);
+               box.margin = 6;
+               box.show_all ();
+               keyboard_list_box.add (box);
+       }
+
+       [GtkCallback]
+       private void keyboard_list_box_row_activated (Gtk.ListBoxRow row_item) {
+               var configurer = new KeyboardConfigurer();
+               back_handler_id = configurer.back.connect (on_back);
+               header_bar_binding = configurer.bind_property ("header-bar", this, "header-bar",
+                                                              BindingFlags.SYNC_CREATE);
+               extra_stack_child_holder.pack_start (configurer);
+               set_visible_child_name ("extra_stack_child");
+       }
+
        private void on_back (Object? emitter) {
                header_bar_binding = null;
                immersive_mode_binding = null;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]