[gtk+] inspector: Show object title in the properties tab



commit 7a1c5845ef6f579763d3493106ce4b17bfd5d103
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Nov 22 11:41:24 2014 -0500

    inspector: Show object title in the properties tab
    
    Replace the search bar with a search entry in a stack to make
    this work without unseemly height changes.

 gtk/inspector/prop-list.c  |  152 ++++++++++++++++++++++++++++++++++++--------
 gtk/inspector/prop-list.ui |   51 ++++++++++++++-
 2 files changed, 171 insertions(+), 32 deletions(-)
---
diff --git a/gtk/inspector/prop-list.c b/gtk/inspector/prop-list.c
index aa8837e..cefce2f 100644
--- a/gtk/inspector/prop-list.c
+++ b/gtk/inspector/prop-list.c
@@ -33,7 +33,9 @@
 #include "gtktreeview.h"
 #include "gtktreeselection.h"
 #include "gtkpopover.h"
-#include "gtksearchbar.h"
+#include "gtksearchentry.h"
+#include "gtklabel.h"
+#include "gtkstack.h"
 
 enum
 {
@@ -64,46 +66,131 @@ struct _GtkInspectorPropListPrivate
   GtkTreeViewColumn *attribute_column;
   GtkWidget *tree;
   GtkWidget *search_entry;
-  GtkWidget *search_bar;
+  GtkWidget *search_stack;
+  GtkWidget *object_title;
 };
 
 G_DEFINE_TYPE_WITH_PRIVATE (GtkInspectorPropList, gtk_inspector_prop_list, GTK_TYPE_BOX)
 
+static void
+search_close_clicked (GtkWidget            *button,
+                      GtkInspectorPropList *pl)
+{
+  gtk_entry_set_text (GTK_ENTRY (pl->priv->search_entry), "");
+  gtk_stack_set_visible_child_name (GTK_STACK (pl->priv->search_stack), "title");
+}
+
+static gboolean
+is_keynav_event (GdkEvent *event)
+{
+  GdkModifierType state = 0;
+  guint keyval;
+
+  if (!gdk_event_get_keyval (event, &keyval))
+    return FALSE;
+
+  gdk_event_get_state (event, &state);
+
+  if (keyval == GDK_KEY_Tab       || keyval == GDK_KEY_KP_Tab ||
+      keyval == GDK_KEY_Up        || keyval == GDK_KEY_KP_Up ||
+      keyval == GDK_KEY_Down      || keyval == GDK_KEY_KP_Down ||
+      keyval == GDK_KEY_Left      || keyval == GDK_KEY_KP_Left ||
+      keyval == GDK_KEY_Right     || keyval == GDK_KEY_KP_Right ||
+      keyval == GDK_KEY_Home      || keyval == GDK_KEY_KP_Home ||
+      keyval == GDK_KEY_End       || keyval == GDK_KEY_KP_End ||
+      keyval == GDK_KEY_Page_Up   || keyval == GDK_KEY_KP_Page_Up ||
+      keyval == GDK_KEY_Page_Down || keyval == GDK_KEY_KP_Page_Down ||
+      ((state & (GDK_CONTROL_MASK | GDK_MOD1_MASK)) != 0))
+        return TRUE;
+
+  /* Other navigation events should get automatically
+   * ignored as they will not change the content of the entry
+   */
+  return FALSE;
+}
+
+static void
+preedit_changed_cb (GtkEntry  *entry,
+                    GtkWidget *popup,
+                    gboolean  *preedit_changed)
+{
+  *preedit_changed = TRUE;
+}
+
 static gboolean
 key_press_event (GtkWidget            *window,
                  GdkEvent             *event,
                  GtkInspectorPropList *pl)
 {
-  if (gtk_widget_get_mapped (GTK_WIDGET (pl)))
+  gboolean handled;
+  gboolean preedit_changed;
+  guint preedit_change_id;
+  gboolean res;
+  gchar *old_text, *new_text;
+
+  if (!gtk_widget_get_mapped (GTK_WIDGET (pl)))
+    return GDK_EVENT_PROPAGATE;
+
+  if (is_keynav_event (event) ||
+      event->key.keyval == GDK_KEY_space ||
+      event->key.keyval == GDK_KEY_Menu)
+    return GDK_EVENT_PROPAGATE;
+ 
+  if (event->key.keyval == GDK_KEY_Return ||
+      event->key.keyval == GDK_KEY_ISO_Enter ||
+      event->key.keyval == GDK_KEY_KP_Enter)
     {
-      if (event->key.keyval == GDK_KEY_Return ||
-          event->key.keyval == GDK_KEY_ISO_Enter ||
-          event->key.keyval == GDK_KEY_KP_Enter)
+      GtkTreeSelection *selection;
+      GtkTreeModel *model;
+      GtkTreeIter iter;
+      GtkTreePath *path;
+
+      selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (pl->priv->tree));
+      if (gtk_tree_selection_get_selected (selection, &model, &iter))
         {
-          GtkTreeSelection *selection;
-          GtkTreeModel *model;
-          GtkTreeIter iter;
-          GtkTreePath *path;
-
-          selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (pl->priv->tree));
-          if (gtk_tree_selection_get_selected (selection, &model, &iter))
-            {
-              path = gtk_tree_model_get_path (model, &iter);
-              gtk_tree_view_row_activated (GTK_TREE_VIEW (pl->priv->tree),
-                                           path,
-                                           pl->priv->name_column);
-              gtk_tree_path_free (path);
-
-              return GDK_EVENT_STOP;
-            }
-          else
-            return GDK_EVENT_PROPAGATE;
+          path = gtk_tree_model_get_path (model, &iter);
+          gtk_tree_view_row_activated (GTK_TREE_VIEW (pl->priv->tree),
+                                       path,
+                                       pl->priv->name_column);
+          gtk_tree_path_free (path);
+
+          return GDK_EVENT_STOP;
         }
+      else
+        return GDK_EVENT_PROPAGATE;
+    }
 
-      return gtk_search_bar_handle_event (GTK_SEARCH_BAR (pl->priv->search_bar), event);
+  if (event->key.keyval == GDK_KEY_Escape)
+    {
+      gtk_entry_set_text (GTK_ENTRY (pl->priv->search_entry), "");
+      gtk_stack_set_visible_child_name (GTK_STACK (pl->priv->search_stack), "title");
+      return GDK_EVENT_STOP;
     }
-  else
-    return GDK_EVENT_PROPAGATE;
+
+  if (!gtk_widget_get_realized (pl->priv->search_entry))
+    gtk_widget_realize (pl->priv->search_entry);
+
+  handled = FALSE;
+  preedit_changed = FALSE;
+  preedit_change_id = g_signal_connect (pl->priv->search_entry, "preedit-changed",
+                                        G_CALLBACK (preedit_changed_cb), &preedit_changed);
+
+  old_text = g_strdup (gtk_entry_get_text (GTK_ENTRY (pl->priv->search_entry)));
+  res = gtk_widget_event (pl->priv->search_entry, event);
+  new_text = g_strdup (gtk_entry_get_text (GTK_ENTRY (pl->priv->search_entry)));
+
+  g_signal_handler_disconnect (pl->priv->search_entry, preedit_change_id);
+
+  if ((res && g_strcmp0 (new_text, old_text) != 0) || preedit_changed)
+    {
+      gtk_stack_set_visible_child_name (GTK_STACK (pl->priv->search_stack), "search");
+      handled = TRUE;
+    }
+
+  g_free (old_text);
+  g_free (new_text);
+
+ return handled ? GDK_EVENT_STOP : GDK_EVENT_PROPAGATE;
 }
 
 static void
@@ -283,8 +370,10 @@ gtk_inspector_prop_list_class_init (GtkInspectorPropListClass *klass)
   gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorPropList, attribute_column);
   gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorPropList, tree);
   gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorPropList, search_entry);
-  gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorPropList, search_bar);
+  gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorPropList, search_stack);
+  gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorPropList, object_title);
   gtk_widget_class_bind_template_callback (widget_class, row_activated);
+  gtk_widget_class_bind_template_callback (widget_class, search_close_clicked);
 }
 
 static void
@@ -392,6 +481,7 @@ gtk_inspector_prop_list_set_object (GtkInspectorPropList *pl,
   GParamSpec **props;
   guint num_properties;
   guint i;
+  const gchar *title;
 
   if (!object)
     return FALSE;
@@ -407,6 +497,12 @@ gtk_inspector_prop_list_set_object (GtkInspectorPropList *pl,
       return TRUE;
     }
 
+  title = (const gchar *)g_object_get_data (object, "gtk-inspector-object-title");
+  gtk_label_set_label (GTK_LABEL (pl->priv->object_title), title);
+
+  gtk_entry_set_text (GTK_ENTRY (pl->priv->search_entry), "");
+  gtk_stack_set_visible_child_name (GTK_STACK (pl->priv->search_stack), "title");
+  
   if (pl->priv->child_properties)
     {
       GtkWidget *parent;
diff --git a/gtk/inspector/prop-list.ui b/gtk/inspector/prop-list.ui
index aa1637f..ba717b8 100644
--- a/gtk/inspector/prop-list.ui
+++ b/gtk/inspector/prop-list.ui
@@ -13,14 +13,57 @@
   <template class="GtkInspectorPropList" parent="GtkBox">
     <property name="orientation">vertical</property>
     <child>
-      <object class="GtkSearchBar" id="search_bar">
+      <object class="GtkStack" id="search_stack">
         <property name="visible">True</property>
-        <property name="show-close-button">True</property>
+        <property name="hhomogeneous">True</property>
+        <property name="vhomogeneous">True</property>
+        <property name="transition-type">crossfade</property>
         <child>
-          <object class="GtkSearchEntry" id="search_entry">
+          <object class="GtkBox" id="search_box">
             <property name="visible">True</property>
-            <property name="max-width-chars">40</property>
+            <property name="orientation">horizontal</property>
+            <property name="spacing">6</property>
+            <property name="margin">6</property>
+            <child type="center">
+              <object class="GtkSearchEntry" id="search_entry">
+                <property name="visible">True</property>
+                <property name="max-width-chars">40</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkButton" id="search_close_button">
+                <property name="visible">True</property>
+                <signal name="clicked" handler="search_close_clicked"/>
+                <style>
+                  <class name="image-button"/>
+                </style>
+                <child>
+                  <object class="GtkImage">
+                    <property name="visible">True</property>
+                    <property name="icon-name">window-close-symbolic</property>
+                    <property name="icon-size">1</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="pack-type">end</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="name">search</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="object_title">
+            <property name="visible">True</property>
+            <property name="margin">10</property>
+            <property name="halign">fill</property>
+            <property name="valign">center</property>
           </object>
+          <packing>
+            <property name="name">title</property>
+          </packing>
         </child>
       </object>
     </child>


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