[gtk+] widget-factory: Add an automatic help overlay



commit 3306ce68196b38f0c6e26867c597c40de295ebc8
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed Oct 21 00:14:38 2015 -0400

    widget-factory: Add an automatic help overlay
    
    This commit add some more keyboard shortcuts to gtk3-widget-factory,
    and adds a help overlay documenting them. This examle uses the
    automatic resource loading support in GtkApplication.

 demos/widget-factory/Makefile.am                  |    1 +
 demos/widget-factory/help-overlay.ui              |   92 +++++++++++++++
 demos/widget-factory/widget-factory.c             |  130 ++++++++++++++++++++-
 demos/widget-factory/widget-factory.gresource.xml |    3 +
 demos/widget-factory/widget-factory.ui            |   11 ++-
 5 files changed, 231 insertions(+), 6 deletions(-)
---
diff --git a/demos/widget-factory/Makefile.am b/demos/widget-factory/Makefile.am
index bc08f4b..a6bfbdc 100644
--- a/demos/widget-factory/Makefile.am
+++ b/demos/widget-factory/Makefile.am
@@ -64,6 +64,7 @@ EXTRA_DIST +=                                 \
        widget-factory.ui               \
        widget-factory.css              \
        menus.ui                        \
+       help-overlay.ui                 \
        widget-factory.gresource.xml    \
        data/source.svg                 \
        data/symbolic-source.svg
diff --git a/demos/widget-factory/help-overlay.ui b/demos/widget-factory/help-overlay.ui
new file mode 100644
index 0000000..5f2d99f
--- /dev/null
+++ b/demos/widget-factory/help-overlay.ui
@@ -0,0 +1,92 @@
+<interface>
+  <object class="GtkShortcutsWindow" id="help_overlay">
+    <child>
+      <object class="GtkShortcutsSection">
+        <property name="visible">1</property>
+        <child>
+          <object class="GtkShortcutsGroup">
+            <property name="visible">1</property>
+            <property name="title">General</property>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">F1</property>
+                <property name="title">Show About Dialog</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;Primary&gt;q</property>
+                <property name="title">Quit</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;Primary&gt;d</property>
+                <property name="title">Switch to dark theme</property>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkShortcutsGroup">
+            <property name="visible">1</property>
+            <property name="title">Traditional</property>
+            <property name="view">page2</property>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;Primary&gt;s</property>
+                <property name="title">Search</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">Delete</property>
+                <property name="title">Delete</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;Primary&gt;b</property>
+                <property name="title">Set background</property>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkShortcutsGroup">
+            <property name="visible">1</property>
+            <property name="title">Modern</property>
+            <property name="view">page3</property>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;Primary&gt;o</property>
+                <property name="title">Open a file</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;Primary&gt;r</property>
+                <property name="title">Start recording</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">1</property>
+                <property name="accelerator">&lt;Primary&gt;l</property>
+                <property name="title">Lock or unlock</property>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/demos/widget-factory/widget-factory.c b/demos/widget-factory/widget-factory.c
index 4f3aa53..92de85d 100644
--- a/demos/widget-factory/widget-factory.c
+++ b/demos/widget-factory/widget-factory.c
@@ -69,6 +69,13 @@ get_busy (GSimpleAction *action,
   gtk_widget_set_sensitive (window, FALSE);
 }
 
+static gint current_page = 0;
+static gboolean
+on_page (gint i)
+{
+  return current_page == i;
+}
+
 static void
 activate_search (GSimpleAction *action,
                  GVariant      *parameter,
@@ -77,6 +84,9 @@ activate_search (GSimpleAction *action,
   GtkWidget *window = user_data;
   GtkWidget *searchbar;
 
+  if (!on_page (2))
+    return;
+
   searchbar = GTK_WIDGET (g_object_get_data (G_OBJECT (window), "searchbar"));
   gtk_search_bar_set_search_mode (GTK_SEARCH_BAR (searchbar), TRUE);
 }
@@ -89,10 +99,79 @@ activate_delete (GSimpleAction *action,
   GtkWidget *window = user_data;
   GtkWidget *infobar;
 
+  if (!on_page (2))
+    return;
+
   infobar = GTK_WIDGET (g_object_get_data (G_OBJECT (window), "infobar"));
   gtk_widget_show (infobar);
 }
 
+static void populate_flowbox (GtkWidget *flowbox);
+
+static void
+activate_background (GSimpleAction *action,
+                     GVariant      *parameter,
+                     gpointer       user_data)
+{
+  GtkWidget *window = user_data;
+  GtkWidget *dialog;
+  GtkWidget *flowbox;
+
+  if (!on_page (2))
+    return;
+
+  dialog = GTK_WIDGET (g_object_get_data (G_OBJECT (window), "selection_dialog"));
+  flowbox = GTK_WIDGET (g_object_get_data (G_OBJECT (window), "selection_flowbox"));
+
+  gtk_widget_show (dialog);
+  populate_flowbox (flowbox);
+}
+
+static void
+activate_open (GSimpleAction *action,
+               GVariant      *parameter,
+               gpointer       user_data)
+{
+  GtkWidget *window = user_data;
+  GtkWidget *button;
+
+  if (!on_page (3))
+    return;
+
+  button = GTK_WIDGET (g_object_get_data (G_OBJECT (window), "open_menubutton"));
+  gtk_button_clicked (GTK_BUTTON (button));
+}
+
+static void
+activate_record (GSimpleAction *action,
+                 GVariant      *parameter,
+                 gpointer       user_data)
+{
+  GtkWidget *window = user_data;
+  GtkWidget *button;
+
+  if (!on_page (3))
+    return;
+
+  button = GTK_WIDGET (g_object_get_data (G_OBJECT (window), "record_button"));
+  gtk_button_clicked (GTK_BUTTON (button));
+}
+
+static void
+activate_lock (GSimpleAction *action,
+               GVariant      *parameter,
+               gpointer       user_data)
+{
+  GtkWidget *window = user_data;
+  GtkWidget *button;
+
+  if (!on_page (3))
+    return;
+
+  button = GTK_WIDGET (g_object_get_data (G_OBJECT (window), "lockbutton"));
+  gtk_button_clicked (GTK_BUTTON (button));
+}
+
 static void
 activate_about (GSimpleAction *action,
                 GVariant      *parameter,
@@ -469,14 +548,26 @@ static void
 page_changed_cb (GtkWidget *stack, GParamSpec *pspec, gpointer data)
 {
   const gchar *name;
+  GtkWidget *window;
   GtkWidget *page;
 
   if (gtk_widget_in_destruction (stack))
     return;
 
   name = gtk_stack_get_visible_child_name (GTK_STACK (stack));
+
+  window = gtk_widget_get_ancestor (stack, GTK_TYPE_APPLICATION_WINDOW);
+  g_object_set (gtk_application_window_get_help_overlay (GTK_APPLICATION_WINDOW (window)),
+                "view-name", name,
+                NULL);
+
+  if (g_str_equal (name, "page1"))
+    current_page = 1;
+  else if (g_str_equal (name, "page2"))
+    current_page = 2;
   if (g_str_equal (name, "page3"))
     {
+      current_page = 3;
       page = gtk_stack_get_visible_child (GTK_STACK (stack));
       set_needs_attention (GTK_WIDGET (page), FALSE);
     }
@@ -818,7 +909,7 @@ background_loaded_cb (GObject      *source,
 }
 
 static void
-populate_flowbox (GtkWidget *button, GtkWidget *flowbox)
+populate_flowbox (GtkWidget *flowbox)
 {
   const gchar *location;
   GDir *dir;
@@ -831,7 +922,10 @@ populate_flowbox (GtkWidget *button, GtkWidget *flowbox)
   GdkPixbuf *pixbuf;
   GtkWidget *child;
 
-  g_signal_handlers_disconnect_by_func (button, populate_flowbox, flowbox);
+  if (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (flowbox), "populated")))
+    return;
+
+  g_object_set_data (G_OBJECT (flowbox), "populated", GUINT_TO_POINTER (1));
 
   pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 110, 70);
   gdk_pixbuf_fill (pixbuf, 0xffffffff);
@@ -1379,7 +1473,11 @@ activate (GApplication *app)
     { "dark", NULL, NULL, "false", change_theme_state },
     { "search", activate_search, NULL, NULL, NULL },
     { "delete", activate_delete, NULL, NULL, NULL },
-    { "busy", get_busy, NULL, NULL, NULL }
+    { "busy", get_busy, NULL, NULL, NULL },
+    { "background", activate_background, NULL, NULL, NULL },
+    { "open", activate_open, NULL, NULL, NULL },
+    { "record", activate_record, NULL, NULL, NULL },
+    { "lock", activate_lock, NULL, NULL, NULL },
   };
   struct {
     const gchar *action_and_target;
@@ -1389,10 +1487,15 @@ activate (GApplication *app)
     { "app.quit", { "<Primary>q", NULL } },
     { "win.dark", { "<Primary>d", NULL } },
     { "win.search", { "<Primary>s", NULL } },
-    { "win.delete", { "Delete", NULL } }
+    { "win.delete", { "Delete", NULL } },
+    { "win.background", { "<Primary>b", NULL } },
+    { "win.open", { "<Primary>o", NULL } },
+    { "win.record", { "<Primary>r", NULL } },
+    { "win.lock", { "<Primary>l", NULL } },
   };
   gint i;
   GPermission *permission;
+  GAction *action;
 
   g_type_ensure (my_text_view_get_type ());
 
@@ -1498,6 +1601,7 @@ activate (GApplication *app)
   stack = (GtkWidget *)gtk_builder_get_object (builder, "toplevel_stack");
   g_signal_connect (widget, "clicked", G_CALLBACK (action_dialog_button_clicked), stack);
   g_signal_connect (stack, "notify::visible-child-name", G_CALLBACK (page_changed_cb), NULL);
+  page_changed_cb (stack, NULL, NULL);
 
   dialog = (GtkWidget *)gtk_builder_get_object (builder, "preference_dialog");
   g_signal_connect (dialog, "response", G_CALLBACK (close_dialog), NULL);
@@ -1507,13 +1611,15 @@ activate (GApplication *app)
   g_signal_connect (widget, "clicked", G_CALLBACK (show_dialog), dialog);
 
   dialog = (GtkWidget *)gtk_builder_get_object (builder, "selection_dialog");
+  g_object_set_data (G_OBJECT (window), "selection_dialog", dialog);
   widget = (GtkWidget *)gtk_builder_get_object (builder, "text3");
   g_signal_connect (dialog, "response", G_CALLBACK (close_selection_dialog), widget);
   widget = (GtkWidget *)gtk_builder_get_object (builder, "selection_dialog_button");
   g_signal_connect (widget, "clicked", G_CALLBACK (show_dialog), dialog);
 
   widget2 = (GtkWidget *)gtk_builder_get_object (builder, "selection_flowbox");
-  g_signal_connect (widget, "clicked", G_CALLBACK (populate_flowbox), widget2);
+  g_object_set_data (G_OBJECT (window), "selection_flowbox", widget2);
+  g_signal_connect_swapped (widget, "clicked", G_CALLBACK (populate_flowbox), widget2);
 
   widget = (GtkWidget *)gtk_builder_get_object (builder, "charletree");
   populate_model ((GtkTreeStore *)gtk_tree_view_get_model (GTK_TREE_VIEW (widget)));
@@ -1538,6 +1644,7 @@ activate (GApplication *app)
   set_accel (GTK_APPLICATION (app), GTK_WIDGET (gtk_builder_get_object (builder, "searchmenuitem")));
   set_accel (GTK_APPLICATION (app), GTK_WIDGET (gtk_builder_get_object (builder, "darkmenuitem")));
   set_accel (GTK_APPLICATION (app), GTK_WIDGET (gtk_builder_get_object (builder, "aboutmenuitem")));
+  set_accel (GTK_APPLICATION (app), GTK_WIDGET (gtk_builder_get_object (builder, "bgmenuitem")));
 
   widget2 = (GtkWidget *)gtk_builder_get_object (builder, "tooltextview");
 
@@ -1580,13 +1687,26 @@ activate (GApplication *app)
   gtk_popover_set_default_widget (GTK_POPOVER (widget), widget3);
   g_signal_connect (widget2, "notify::text", G_CALLBACK (open_popover_text_changed), widget3);
   g_signal_connect_swapped (widget3, "clicked", G_CALLBACK (gtk_widget_hide), widget);
+  widget = (GtkWidget *)gtk_builder_get_object (builder, "open_menubutton");
+  g_object_set_data (G_OBJECT (window), "open_menubutton", widget);
+  widget = (GtkWidget *)gtk_builder_get_object (builder, "record_button");
+  g_object_set_data (G_OBJECT (window), "record_button", widget);
 
   widget = (GtkWidget *)gtk_builder_get_object (builder, "lockbox");
   widget2 = (GtkWidget *)gtk_builder_get_object (builder, "lockbutton");
+  g_object_set_data (G_OBJECT (window), "lockbutton", widget2);
   permission = g_object_new (g_test_permission_get_type (), NULL);
   g_object_bind_property (permission, "allowed",
                           widget, "sensitive",
                           G_BINDING_SYNC_CREATE);
+  action = g_action_map_lookup_action (G_ACTION_MAP (window), "open");
+  g_object_bind_property (permission, "allowed",
+                          action, "enabled",
+                          G_BINDING_SYNC_CREATE);
+  action = g_action_map_lookup_action (G_ACTION_MAP (window), "record");
+  g_object_bind_property (permission, "allowed",
+                          action, "enabled",
+                          G_BINDING_SYNC_CREATE);
   gtk_lock_button_set_permission (GTK_LOCK_BUTTON (widget2), permission);
   g_object_unref (permission);
 
diff --git a/demos/widget-factory/widget-factory.gresource.xml 
b/demos/widget-factory/widget-factory.gresource.xml
index 0a051e5..c709f59 100644
--- a/demos/widget-factory/widget-factory.gresource.xml
+++ b/demos/widget-factory/widget-factory.gresource.xml
@@ -9,4 +9,7 @@
   <gresource prefix="/org/gtk/WidgetFactory/gtk">
     <file preprocess="xml-stripblanks">menus.ui</file>
   </gresource>
+  <gresource prefix="/org/gtk/WidgetFactory/gtk">
+    <file preprocess="xml-stripblanks">help-overlay.ui</file>
+  </gresource>
 </gresources>
diff --git a/demos/widget-factory/widget-factory.ui b/demos/widget-factory/widget-factory.ui
index c27dde1..b90ca34 100644
--- a/demos/widget-factory/widget-factory.ui
+++ b/demos/widget-factory/widget-factory.ui
@@ -2485,6 +2485,15 @@ microphone-sensitivity-medium-symbolic</property>
                                                 <property name="action_name">win.statusbar</property>
                                               </object>
                                             </child>
+                                            <child>
+                                              <object class="GtkMenuItem" id="bgmenuitem">
+                                                <property name="label">_Select Background</property>
+                                                <property name="visible">1</property>
+                                                <property name="use_action_appearance">0</property>
+                                                <property name="use_underline">1</property>
+                                                <property name="action_name">win.background</property>
+                                              </object>
+                                            </child>
                                           </object>
                                         </child>
                                       </object>
@@ -2902,7 +2911,7 @@ microphone-sensitivity-medium-symbolic</property>
                             <property name="halign">start</property>
                             <property name="spacing">6</property>
                             <child>
-                              <object class="GtkMenuButton">
+                              <object class="GtkMenuButton" id="open_menubutton">
                                 <property name="visible">1</property>
                                 <property name="halign">center</property>
                                 <property name="popover">open_popover</property>


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