[gnome-games/wip/abhinavsingh/gamepad-reassignment: 2/2] temp patch



commit e4804c1b15b51f3578b3a6150b7365ad15671015
Author: theawless <theawless gmail com>
Date:   Mon Jul 10 21:05:49 2017 +0530

    temp patch

 data/Makefile.am                   |    1 +
 data/org.gnome.Games.gresource.xml |    1 +
 data/ui/display-header-bar.ui      |   25 ++++++++++++++++
 data/ui/input-popover.ui           |   31 +++++++++++++++++++
 data/ui/input-reassigner.ui        |   57 ++++++++++++++++++++++++++++++++++++
 src/Makefile.am                    |    3 ++
 src/command/command-runner.vala    |    4 ++
 src/core/input-set.vala            |   10 ++++++
 src/core/runner.vala               |    1 +
 src/dummy/dummy-runner.vala        |    4 ++
 src/retro/retro-input-manager.vala |   55 +++++++++++++++++-----------------
 src/retro/retro-runner.vala        |    4 ++
 src/ui/application-window.vala     |    2 +
 src/ui/display-header-bar.vala     |   16 ++++++++++
 src/ui/input-popover.vala          |   51 ++++++++++++++++++++++++++++++++
 src/ui/input-reassigner.vala       |   46 +++++++++++++++++++++++++++++
 16 files changed, 284 insertions(+), 27 deletions(-)
---
diff --git a/data/Makefile.am b/data/Makefile.am
index 87b56b8..435e1a2 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -37,6 +37,7 @@ EXTRA_DIST = \
        ui/error-display.ui \
        ui/error-info-bar.ui \
        ui/game-icon-view.ui \
+       ui/input-popover.ui \
        ui/media-menu-button.ui \
        ui/media-selector.ui \
        ui/preferences-page-plugins-item.ui \
diff --git a/data/org.gnome.Games.gresource.xml b/data/org.gnome.Games.gresource.xml
index e66ccca..696b046 100644
--- a/data/org.gnome.Games.gresource.xml
+++ b/data/org.gnome.Games.gresource.xml
@@ -16,6 +16,7 @@
     <file preprocess="xml-stripblanks">ui/error-display.ui</file>
     <file preprocess="xml-stripblanks">ui/error-info-bar.ui</file>
     <file preprocess="xml-stripblanks">ui/game-icon-view.ui</file>
+    <file preprocess="xml-stripblanks">ui/input-popover.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-plugins.ui</file>
diff --git a/data/ui/display-header-bar.ui b/data/ui/display-header-bar.ui
index aae8f8d..cd87c90 100644
--- a/data/ui/display-header-bar.ui
+++ b/data/ui/display-header-bar.ui
@@ -92,5 +92,30 @@
         <property name="pack-type">end</property>
       </packing>
     </child>
+    <child>
+      <object class="GtkMenuButton" id="input_button">
+        <property name="visible">False</property>
+        <property name="valign">center</property>
+        <property name="use-underline">True</property>
+        <style>
+          <class name="image-button"/>
+        </style>
+        <child internal-child="accessible">
+          <object class="AtkObject" id="a11y-input">
+            <property name="accessible-name" translatable="yes">input</property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkImage" id="input_image">
+            <property name="visible">True</property>
+            <property name="icon-name">input-gaming-symbolic</property>
+            <property name="icon-size">1</property>
+          </object>
+        </child>
+      </object>
+      <packing>
+        <property name="pack-type">end</property>
+      </packing>
+    </child>
   </template>
 </interface>
diff --git a/data/ui/input-popover.ui b/data/ui/input-popover.ui
new file mode 100644
index 0000000..c165de0
--- /dev/null
+++ b/data/ui/input-popover.ui
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <requires lib="gtk+" version="3.16"/>
+  <template class="GamesInputPopover" parent="GtkPopover">
+    <child>
+      <object class="GtkBox">
+        <property name="orientation">vertical</property>
+        <property name="margin-top">6</property>
+        <property name="margin-bottom">6</property>
+        <property name="margin-start">6</property>
+        <property name="margin-end">6</property>
+        <property name="margin">6</property>
+        <property name="spacing">12</property>
+        <property name="visible">true</property>
+        <child>
+          <object class="GtkListBox" id="inputs_list_box">
+            <property name="visible">True</property>
+            <property name="selection_mode">none</property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkButton" id="reassign_button">
+            <property name="visible">True</property>
+            <property name="label" translatable="yes">Reassign</property>
+            <signal name="clicked" handler="on_reassign_clicked"/>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/data/ui/input-reassigner.ui b/data/ui/input-reassigner.ui
new file mode 100644
index 0000000..a2f9e88
--- /dev/null
+++ b/data/ui/input-reassigner.ui
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <template class="GamesInputReassigner" parent="GtkDialog">
+    <property name="destroy-with-parent">True</property>
+    <property name="type_hint">dialog</property>
+    <child internal-child="vbox">
+      <object class="GtkBox">
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">6</property>
+        <property name="margin-top">12</property>
+        <property name="margin-bottom">12</property>
+        <property name="margin-start">12</property>
+        <property name="margin-end">12</property>
+        <child>
+          <object class="GtkLabel" id="info_message">
+            <property name="visible">True</property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkLabel" id="error_message">
+            <property name="visible">True</property>
+            <attributes>
+              <attribute name="foreground" value="red"/>
+            </attributes>
+          </object>
+        </child>
+        <child>
+          <object class="GtkListBox" id="inputs_list_box">
+            <property name="visible">True</property>
+            <property name="selection_mode">none</property>
+          </object>
+        </child>
+      </object>
+    </child>
+    <child type="action">
+      <object class="GtkButton" id="button_apply">
+        <property name="visible">True</property>
+        <property name="can-default">True</property>
+        <property name="label" translatable="yes">Apply</property>
+        <style>
+          <class name="suggested-action"/>
+        </style>
+      </object>
+    </child>
+    <child type="action">
+      <object class="GtkButton" id="button_cancel">
+        <property name="visible">True</property>
+        <property name="label" translatable="yes">Cancel</property>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="apply" default="true">button_apply</action-widget>
+      <action-widget response="cancel">button_cancel</action-widget>
+    </action-widgets>
+  </template>
+</interface>
diff --git a/src/Makefile.am b/src/Makefile.am
index a49476d..a1ac528 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -47,6 +47,7 @@ gnome_games_SOURCES = \
        core/game-collection.vala \
        core/game-uri-adapter.vala \
        core/icon.vala \
+       core/input-set.vala \
        core/input-capabilities.vala \
        core/media.vala \
        core/media-info.vala \
@@ -125,6 +126,8 @@ gnome_games_SOURCES = \
        ui/error-info-bar.vala \
        ui/game-icon-view.vala \
        ui/game-thumbnail.vala \
+       ui/input-popover.vala \
+       ui/input-reassigner.vala \
        ui/media-selector.vala \
        ui/media-menu-button.vala \
        ui/preferences-page.vala \
diff --git a/src/command/command-runner.vala b/src/command/command-runner.vala
index e8b8612..8267c20 100644
--- a/src/command/command-runner.vala
+++ b/src/command/command-runner.vala
@@ -17,6 +17,10 @@ public class Games.CommandRunner : Object, Runner {
                get { return null; }
        }
 
+       internal InputSet? input_set {
+               get { return null; }
+       }
+
        private string[] args;
        private bool watch_child;
 
diff --git a/src/core/input-set.vala b/src/core/input-set.vala
new file mode 100644
index 0000000..df24b9f
--- /dev/null
+++ b/src/core/input-set.vala
@@ -0,0 +1,10 @@
+// This file is part of GNOME Games. License: GPL-3.0+.
+
+private class Games.InputSet : Object {
+       public HashTable<uint, Gamepad?> gamepads { set; get; }
+       public uint keyboard_port { set; get; }
+
+       construct {
+               gamepads = new HashTable<uint, Gamepad?> (GLib.direct_hash, GLib.direct_equal);
+       }
+}
diff --git a/src/core/runner.vala b/src/core/runner.vala
index 25d79b8..df1b1e2 100644
--- a/src/core/runner.vala
+++ b/src/core/runner.vala
@@ -7,6 +7,7 @@ public interface Games.Runner : Object {
        public abstract bool can_quit_safely { get; }
        public abstract bool can_resume { get; }
        public abstract MediaSet? media_set { get; }
+       internal abstract InputSet? input_set { get; }
 
        public abstract bool check_is_valid (out string error_message) throws Error;
        public abstract Gtk.Widget get_display ();
diff --git a/src/dummy/dummy-runner.vala b/src/dummy/dummy-runner.vala
index ce18b22..e5778c9 100644
--- a/src/dummy/dummy-runner.vala
+++ b/src/dummy/dummy-runner.vala
@@ -17,6 +17,10 @@ private class Games.DummyRunner : Object, Runner {
                get { return null; }
        }
 
+       internal InputSet? input_set {
+               get { return null; }
+       }
+
        public bool check_is_valid (out string error_message) throws Error {
                return true;
        }
diff --git a/src/retro/retro-input-manager.vala b/src/retro/retro-input-manager.vala
index 9e0ab5c..09fa239 100644
--- a/src/retro/retro-input-manager.vala
+++ b/src/retro/retro-input-manager.vala
@@ -3,9 +3,12 @@
 private class Games.RetroInputManager : Retro.InputDeviceManager, Retro.Rumble {
        private Retro.VirtualGamepad keyboard;
        private GamepadMonitor gamepad_monitor;
-       private Retro.InputDevice?[] input_devices;
-       private int keyboard_port;
        private bool present_analog_sticks;
+       public InputSet input_set { private set; get; }
+
+       construct {
+               input_set = new InputSet ();
+       }
 
        public RetroInputManager (Gtk.Widget widget, bool present_analog_sticks) {
                this.present_analog_sticks = present_analog_sticks;
@@ -15,66 +18,64 @@ private class Games.RetroInputManager : Retro.InputDeviceManager, Retro.Rumble {
 
                gamepad_monitor = GamepadMonitor.get_instance ();
                gamepad_monitor.foreach_gamepad ((gamepad) => {
-                       var port = input_devices.length;
+                       var port = input_set.gamepads.length;
+                       input_set.gamepads[port] = gamepad;
                        var retro_gamepad = new RetroGamepad (gamepad, present_analog_sticks);
-                       input_devices += retro_gamepad;
                        set_controller_device (port, retro_gamepad);
                        gamepad.unplugged.connect (() => handle_gamepad_unplugged (port));
                });
 
-               keyboard_port = input_devices.length;
-               input_devices += keyboard;
-               set_controller_device (keyboard_port, keyboard);
+               input_set.keyboard_port = input_set.gamepads.length;
+               set_controller_device (input_set.keyboard_port, keyboard);
                gamepad_monitor.gamepad_plugged.connect (handle_gamepad_plugged);
        }
 
        private void handle_gamepad_plugged (Gamepad gamepad) {
                // Plug this gamepad to the port where the keyboard was plugged as a last resort
-               var port = keyboard_port;
+               var port = input_set.keyboard_port;
+               input_set.gamepads[port] = gamepad;
                var retro_gamepad = new RetroGamepad (gamepad, present_analog_sticks);
-               input_devices[port] = retro_gamepad;
                set_controller_device (port, retro_gamepad);
                gamepad.unplugged.connect (() => handle_gamepad_unplugged (port));
 
                // Assign keyboard to another unplugged port if exists and return
-               for (var i = keyboard_port; i < input_devices.length; i++) {
-                       if (input_devices[i] == null) {
+               for (var i = input_set.keyboard_port; i < input_set.gamepads.length; i++) {
+                       if (input_set.gamepads[i] == null) {
                                // Found an unplugged port and so assigning keyboard to it
-                               keyboard_port = i;
-                               input_devices[keyboard_port] = keyboard;
-                               set_controller_device (keyboard_port, keyboard);
+                               input_set.keyboard_port = i;
+                               input_set.gamepads.remove (input_set.keyboard_port);
+                               set_controller_device (input_set.keyboard_port, keyboard);
 
                                return;
                        }
                }
 
                // Now it means that there is no unplugged port so append keyboard to ports
-               keyboard_port = input_devices.length;
-               input_devices += keyboard;
-               set_controller_device (keyboard_port, keyboard);
+               input_set.keyboard_port = input_set.gamepads.length;
+               set_controller_device (input_set.keyboard_port, keyboard);
        }
 
-       private void handle_gamepad_unplugged (int port) {
-               if (keyboard_port > port) {
+       private void handle_gamepad_unplugged (uint port) {
+               if (input_set.keyboard_port > port) {
                        // Remove the controller and shift keyboard to "lesser" port
-                       input_devices[keyboard_port] = null;
-                       remove_controller_device (keyboard_port);
-                       keyboard_port = port;
-                       input_devices[keyboard_port] = keyboard;
-                       set_controller_device (keyboard_port, keyboard);
+                       input_set.gamepads.remove (port);
+                       remove_controller_device (input_set.keyboard_port);
+                       input_set.keyboard_port = port;
+                       set_controller_device (input_set.keyboard_port, keyboard);
                }
                else {
                        // Just remove the controller as no need to shift keyboard
-                       input_devices[port] = null;
+                       input_set.keyboard_port = input_set.keyboard_port;
+                       input_set.gamepads.remove (port);
                        remove_controller_device (port);
                }
        }
 
        private bool set_rumble_state (uint port, Retro.RumbleEffect effect, uint16 strength) {
-               if (port > input_devices.length)
+               if (port > input_set.gamepads.length)
                        return false;
 
-               if (input_devices[port] == null || input_devices[port] == keyboard)
+               if (input_set.gamepads[port] == null)
                        return false;
 
                // TODO Transmit the rumble signal to the gamepad.
diff --git a/src/retro/retro-runner.vala b/src/retro/retro-runner.vala
index 8d7d5f8..3424683 100644
--- a/src/retro/retro-runner.vala
+++ b/src/retro/retro-runner.vala
@@ -34,6 +34,10 @@ public class Games.RetroRunner : Object, Runner {
                get { return _media_set; }
        }
 
+       internal InputSet? input_set {
+               get { return input_manager.input_set; }
+       }
+
        private Retro.Core core;
        private Retro.CairoDisplay video;
        private Retro.PaPlayer audio;
diff --git a/src/ui/application-window.vala b/src/ui/application-window.vala
index 4c157ef..f950c0e 100644
--- a/src/ui/application-window.vala
+++ b/src/ui/application-window.vala
@@ -254,6 +254,8 @@ private class Games.ApplicationWindow : Gtk.ApplicationWindow {
                display_box.runner = runner;
                display_header_bar.media_set = runner.media_set;
                display_box.header_bar.media_set = runner.media_set;
+               display_header_bar.input_set = runner.input_set;
+               display_box.header_bar.input_set = runner.input_set;
 
                is_fullscreen = settings.get_boolean ("fullscreen") && runner.can_fullscreen;
 
diff --git a/src/ui/display-header-bar.vala b/src/ui/display-header-bar.vala
index 5fa6749..ee25990 100644
--- a/src/ui/display-header-bar.vala
+++ b/src/ui/display-header-bar.vala
@@ -6,6 +6,8 @@ private class Games.DisplayHeaderBar : Gtk.HeaderBar {
 
        [GtkChild]
        private MediaMenuButton media_button;
+       [GtkChild]
+       private Gtk.MenuButton input_button;
 
        public string game_title {
                set { title = value; }
@@ -21,7 +23,18 @@ private class Games.DisplayHeaderBar : Gtk.HeaderBar {
                }
        }
 
+       public InputSet? input_set {
+               set {
+                       input_button.visible = (value != null) && value.gamepads.length > 0;
+                       value.notify["keyboard-port"].connect (() => {
+                               input_button.visible = (value != null) && value.gamepads.length > 0;
+                       });
+                       input_popover.input_set = value;
+               }
+       }
+
        private MediaSelector media_selector;
+       private InputPopover input_popover;
 
        [GtkChild]
        private Gtk.Button fullscreen;
@@ -34,6 +47,9 @@ private class Games.DisplayHeaderBar : Gtk.HeaderBar {
        construct {
                settings = new Settings ("org.gnome.Games");
 
+               input_popover = new InputPopover ();
+               input_popover.set_relative_to (input_button);
+               input_button.set_popover (input_popover);
                media_selector = new MediaSelector ();
                media_selector.set_relative_to (media_button);
                media_button.set_popover (media_selector);
diff --git a/src/ui/input-popover.vala b/src/ui/input-popover.vala
new file mode 100644
index 0000000..5366b86
--- /dev/null
+++ b/src/ui/input-popover.vala
@@ -0,0 +1,51 @@
+// This file is part of GNOME Games. License: GPL-3.0+.
+
+[GtkTemplate (ui = "/org/gnome/Games/ui/input-popover.ui")]
+private class Games.InputPopover : Gtk.Popover {
+       private InputSet _input_set;
+       public InputSet input_set {
+               set {
+                       _input_set = value;
+
+                       if (value != null) {
+                               reset_input ();
+                               value.notify["keyboard-port"].connect (reset_input);
+                       }
+               }
+       }
+
+       [GtkChild]
+       private Gtk.ListBox inputs_list_box;
+
+       private void reset_input () {
+               remove_input ();
+               update_input ();
+       }
+
+       private void update_input () {
+               _input_set.gamepads.foreach ((port, gamepad) => {
+                       var box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
+                       box.pack_start (new Gtk.Label (gamepad.name), false, false);
+                       box.margin = 6;
+                       box.show_all ();
+                       list_box.insert (box, (int) port);
+               });
+               var box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
+               box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
+               box.pack_start (new Gtk.Label (_("Keyboard")), false, false);
+               box.margin = 6;
+               box.show_all ();
+               list_box.insert (box, (int) _input_set.keyboard_port);
+       }
+
+       private void remove_input () {
+               list_box.foreach ((child) => child.destroy ());
+       }
+
+       [GtkCallback]
+       private void on_reassign_clicked () {
+               var input_assigner = new InputAssigner ();
+               input_assigner.show ();
+               popdown ();
+       }
+}
diff --git a/src/ui/input-reassigner.vala b/src/ui/input-reassigner.vala
new file mode 100644
index 0000000..574630f
--- /dev/null
+++ b/src/ui/input-reassigner.vala
@@ -0,0 +1,46 @@
+// This file is part of GNOME Games. License: GPL-3.0+.
+
+[GtkTemplate (ui = "/org/gnome/Games/ui/input-reassigner.ui")]
+private class Games.InputReassigner : Gtk.Dialog {
+       private InputSet _input_set;
+       public InputSet input_set { get; }
+
+       [GtkChild]
+       private Gtk.ListBox inputs_list_box;
+       private GamepadMonitor gamepad_monitor;
+
+       construct {
+               gamepad_monitor = GamepadMonitor.get_instance ();
+               gamepad_monitor.gamepads (() => {
+
+               });
+               input_set = new InputSet ();
+               input_set.keyboard_port = null;
+               input_set.notify["keyboard-port"].connect ();
+       }
+
+       private void reset_input () {
+               remove_input ();
+               update_input ();
+       }
+
+       private void update_input () {
+               _input_set.gamepads.foreach ((port, gamepad) => {
+                       var box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
+                       box.pack_start (new Gtk.Label (gamepad.name), false, false);
+                       box.margin = 6;
+                       box.show_all ();
+                       list_box.insert (box, (int) port);
+               });
+               var box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
+               box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
+               box.pack_start (new Gtk.Label (_("Keyboard")), false, false);
+               box.margin = 6;
+               box.show_all ();
+               list_box.insert (box, (int) _input_set.keyboard_port);
+       }
+
+       private void remove_input () {
+               list_box.foreach ((child) => child.destroy ());
+       }
+}


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