[gnome-games/wip/exalm/libhandy2: 8/9] ui: Add PreferencesSidebar



commit 8695dada52ae338f40f35417877f40c15156e71d
Author: Alexander Mikhaylenko <exalm7659 gmail com>
Date:   Wed Sep 12 15:02:49 2018 +0500

    ui: Add PreferencesSidebar

 data/org.gnome.Games.gresource.xml |   1 +
 data/ui/preferences-sidebar.ui     |  23 +++++++
 src/meson.build                    |   1 +
 src/ui/preferences-sidebar.vala    | 135 +++++++++++++++++++++++++++++++++++++
 4 files changed, 160 insertions(+)
---
diff --git a/data/org.gnome.Games.gresource.xml b/data/org.gnome.Games.gresource.xml
index b9f080cb..58742033 100644
--- a/data/org.gnome.Games.gresource.xml
+++ b/data/org.gnome.Games.gresource.xml
@@ -34,6 +34,7 @@
     <file preprocess="xml-stripblanks">ui/preferences-page-plugins.ui</file>
     <file preprocess="xml-stripblanks">ui/preferences-page-plugins-item.ui</file>
     <file preprocess="xml-stripblanks">ui/preferences-page-video.ui</file>
+    <file preprocess="xml-stripblanks">ui/preferences-sidebar.ui</file>
     <file preprocess="xml-stripblanks">ui/preferences-subpage-gamepad.ui</file>
     <file preprocess="xml-stripblanks">ui/preferences-subpage-keyboard.ui</file>
     <file preprocess="xml-stripblanks">ui/preferences-window.ui</file>
diff --git a/data/ui/preferences-sidebar.ui b/data/ui/preferences-sidebar.ui
new file mode 100644
index 00000000..bf07f154
--- /dev/null
+++ b/data/ui/preferences-sidebar.ui
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <template class="GamesPreferencesSidebar" parent="GtkBin">
+    <property name="visible">True</property>
+    <style>
+      <class name="sidebar"/>
+    </style>
+    <child>
+      <object class="GtkScrolledWindow">
+        <property name="visible">True</property>
+        <property name="hscrollbar-policy">never</property>
+        <child>
+          <object class="GtkListBox" id="list">
+            <property name="visible">True</property>
+            <property name="margin-top">4</property>
+            <property name="margin-bottom">4</property>
+            <signal name="row-activated" handler="row_activated"/>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/src/meson.build b/src/meson.build
index 9a886051..fcd62b54 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -157,6 +157,7 @@ vala_sources = [
   'ui/preferences-page-plugins.vala',
   'ui/preferences-page-plugins-item.vala',
   'ui/preferences-page-video.vala',
+  'ui/preferences-sidebar.vala',
   'ui/preferences-subpage.vala',
   'ui/preferences-subpage-gamepad.vala',
   'ui/preferences-subpage-keyboard.vala',
diff --git a/src/ui/preferences-sidebar.vala b/src/ui/preferences-sidebar.vala
new file mode 100644
index 00000000..dad206e7
--- /dev/null
+++ b/src/ui/preferences-sidebar.vala
@@ -0,0 +1,135 @@
+// This file is part of GNOME Games. License: GPL-3.0+.
+
+[GtkTemplate (ui = "/org/gnome/Games/ui/preferences-sidebar.ui")]
+private class Games.PreferencesSidebar: Gtk.Bin {
+       private Gtk.Stack _stack;
+       public Gtk.Stack stack {
+               get {
+                       return _stack;
+               }
+               set {
+                       if (_stack != null) {
+                               clear_sidebar ();
+                               _stack = null;
+                       }
+
+                       _stack = value;
+
+                       if (_stack != null)
+                               populate_sidebar ();
+
+                       queue_resize ();
+               }
+       }
+
+       private bool _folded;
+       public bool folded {
+               get { return _folded; }
+               set {
+                       _folded = value;
+
+                       if (_folded)
+                               list.selection_mode = Gtk.SelectionMode.NONE;
+                       else {
+                               list.selection_mode = Gtk.SelectionMode.SINGLE;
+                               on_child_changed ();
+                       }
+               }
+       }
+
+       public signal void row_selected ();
+
+       [GtkChild]
+       private Gtk.ListBox list;
+       private HashTable<Gtk.Widget, Gtk.ListBoxRow> rows;
+       private bool in_child_changed;
+
+       static construct {
+               set_css_name ("stacksidebar");
+       }
+
+       construct {
+               rows = new HashTable<Gtk.Widget, Gtk.ListBoxRow> (null, null);
+       }
+
+       [GtkCallback]
+       private void row_activated (Gtk.ListBox box, Gtk.ListBoxRow? row) {
+               if (in_child_changed)
+                       return;
+
+               if (row == null)
+                       return;
+
+               var bin = row as Gtk.Bin;
+               var item = bin.get_child ();
+               Gtk.Widget widget = item.get_data ("stack-child");
+               stack.visible_child = widget;
+
+               row_selected ();
+       }
+
+       private void update_row (Gtk.Widget widget, Gtk.Widget row) {
+               var title = "";
+
+               stack.child_get (widget, "title", out title, null);
+
+               var bin = row as Gtk.Bin;
+               var item = bin.get_child () as Gtk.Label;
+               item.label = title;
+
+               row.visible = title != null;
+       }
+
+       private void add_child (Gtk.Widget widget) {
+               /* Check we don't actually already know about this widget */
+               if (widget in rows)
+                       return;
+
+               /* Make a pretty item when we add kids */
+               var item = new Gtk.Label ("");
+               item.halign = Gtk.Align.START;
+               item.valign = Gtk.Align.START;
+               var row = new Gtk.ListBoxRow ();
+               row.add (item);
+               item.show ();
+
+               update_row (widget, row);
+
+               item.set_data ("stack-child", widget);
+               rows[widget] = row;
+               list.add (row);
+       }
+
+       private void remove_child (Gtk.Widget widget) {
+               var row = rows[widget];
+               if (row == null)
+                       return;
+
+               list.remove (row);
+               rows.remove (widget);
+       }
+
+       private void populate_sidebar () {
+               stack.foreach (add_child);
+
+               var widget = stack.get_visible_child ();
+               if (widget != null) {
+                       var row = rows[widget];
+                       list.select_row (row);
+               }
+       }
+
+       private void clear_sidebar () {
+               stack.foreach (remove_child);
+       }
+
+       private void on_child_changed () {
+               var child = stack.get_visible_child ();
+               var row = rows[child];
+               if (row != null) {
+                       in_child_changed = true;
+                       list.select_row (row);
+                       in_child_changed = false;
+               }
+       }
+}


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