[gtk+] inspector: Show size groups



commit af8fdac00135012651be549bed9fa95d38295715
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue May 20 21:44:48 2014 -0400

    inspector: Show size groups
    
    Add a tab that shows size groups of a widget. The properties
    of the size group are available here, as well as the widgets
    that are part of the size group. We highlight the widgets in
    the application when their row in the inspector is hovered.

 gtk/inspector/Makefile.am   |    2 +
 gtk/inspector/init.c        |    2 +
 gtk/inspector/size-groups.c |  278 +++++++++++++++++++++++++++++++++++++++++++
 gtk/inspector/size-groups.h |   51 ++++++++
 gtk/inspector/window.c      |    3 +
 gtk/inspector/window.ui     |   14 ++
 6 files changed, 350 insertions(+), 0 deletions(-)
---
diff --git a/gtk/inspector/Makefile.am b/gtk/inspector/Makefile.am
index 3a60423..faa5670 100644
--- a/gtk/inspector/Makefile.am
+++ b/gtk/inspector/Makefile.am
@@ -46,6 +46,8 @@ libgtkinspector_la_SOURCES =          \
        resources.c                     \
        signals-list.h                  \
        signals-list.c                  \
+       size-groups.h                   \
+       size-groups.c                   \
        visual.h                        \
        visual.c                        \
        widget-tree.h                   \
diff --git a/gtk/inspector/init.c b/gtk/inspector/init.c
index a82b6f2..35b63f8 100644
--- a/gtk/inspector/init.c
+++ b/gtk/inspector/init.c
@@ -35,6 +35,7 @@
 #include "resource-list.h"
 #include "resources.h"
 #include "signals-list.h"
+#include "size-groups.h"
 #include "visual.h"
 #include "widget-tree.h"
 #include "window.h"
@@ -59,6 +60,7 @@ gtk_inspector_init (void)
   g_type_ensure (GTK_TYPE_INSPECTOR_PYTHON_SHELL);
   g_type_ensure (GTK_TYPE_INSPECTOR_RESOURCE_LIST);
   g_type_ensure (GTK_TYPE_INSPECTOR_SIGNALS_LIST);
+  g_type_ensure (GTK_TYPE_INSPECTOR_SIZE_GROUPS);
   g_type_ensure (GTK_TYPE_INSPECTOR_VISUAL);
   g_type_ensure (GTK_TYPE_INSPECTOR_WIDGET_TREE);
   g_type_ensure (GTK_TYPE_INSPECTOR_WINDOW);
diff --git a/gtk/inspector/size-groups.c b/gtk/inspector/size-groups.c
new file mode 100644
index 0000000..d4b27d1
--- /dev/null
+++ b/gtk/inspector/size-groups.c
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 2014 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+#include <glib/gi18n-lib.h>
+#include "size-groups.h"
+#include "window.h"
+#include "gtkwidgetprivate.h"
+
+
+typedef struct {
+  GtkListBoxRow parent;
+  GtkWidget *widget;
+} SizeGroupRow;
+
+typedef struct {
+  GtkListBoxRowClass parent;
+} SizeGroupRowClass;
+
+enum {
+  PROP_WIDGET = 1,
+  LAST_PROPERTY
+};
+
+GParamSpec *properties[LAST_PROPERTY] = { NULL };
+
+G_DEFINE_TYPE (SizeGroupRow, size_group_row, GTK_TYPE_LIST_BOX_ROW)
+
+static void
+size_group_row_init (SizeGroupRow *row)
+{
+}
+
+static void
+size_group_row_get_property (GObject    *object,
+                             guint       property_id,
+                             GValue     *value,
+                             GParamSpec *pspec)
+{
+  SizeGroupRow *row = (SizeGroupRow*)object;
+
+  switch (property_id)
+    {
+    case PROP_WIDGET:
+      g_value_set_pointer (value, row->widget);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+size_group_row_set_property (GObject      *object,
+                             guint         property_id,
+                             const GValue *value,
+                             GParamSpec   *pspec)
+{
+  SizeGroupRow *row = (SizeGroupRow*)object;
+
+  switch (property_id)
+    {
+    case PROP_WIDGET:
+      if (row->widget)
+        g_object_remove_weak_pointer (G_OBJECT (row->widget), (gpointer *)&row->widget);
+      row->widget = g_value_get_pointer (value);
+      if (row->widget)
+        g_object_add_weak_pointer (G_OBJECT (row->widget), (gpointer *)&row->widget);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+static void
+size_group_row_finalize (GObject *object)
+{
+  SizeGroupRow *row = (SizeGroupRow *)object;
+
+  if (row->widget)
+    g_object_remove_weak_pointer (G_OBJECT (row->widget), (gpointer *)&row->widget);
+
+  G_OBJECT_CLASS (size_group_row_parent_class)->finalize (object);
+}
+
+static void
+size_group_state_flags_changed (GtkWidget     *widget,
+                                GtkStateFlags  old_state)
+{
+  SizeGroupRow *row = (SizeGroupRow*)widget;
+  GtkStateFlags state;
+
+  if (!row->widget)
+    return;
+
+  state = gtk_widget_get_state_flags (widget);
+  if ((state & GTK_STATE_FLAG_PRELIGHT) != (old_state & GTK_STATE_FLAG_PRELIGHT))
+    {
+      if (state & GTK_STATE_FLAG_PRELIGHT)
+        gtk_inspector_start_highlight (row->widget);
+      else
+        gtk_inspector_stop_highlight (row->widget);
+    }
+}
+
+static void
+size_group_row_class_init (SizeGroupRowClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+
+  object_class->finalize = size_group_row_finalize;
+  object_class->get_property = size_group_row_get_property;
+  object_class->set_property = size_group_row_set_property;
+
+  widget_class->state_flags_changed = size_group_state_flags_changed;
+
+  properties[PROP_WIDGET] =
+    g_param_spec_pointer ("widget", "Widget", "Widget", G_PARAM_READWRITE);
+
+  g_object_class_install_properties (object_class, LAST_PROPERTY, properties);
+
+}
+
+G_DEFINE_TYPE (GtkInspectorSizeGroups, gtk_inspector_size_groups, GTK_TYPE_BOX)
+
+static void
+clear_view (GtkInspectorSizeGroups *sl)
+{
+  GList *children, *l;
+  GtkWidget *child;
+
+  children = gtk_container_get_children (GTK_CONTAINER (sl));
+  for (l = children; l; l = l->next)
+    {
+      child = l->data;
+      gtk_container_remove (GTK_CONTAINER (sl), child);
+    }
+  g_list_free (children);
+}
+
+static void
+add_widget (GtkInspectorSizeGroups *sl,
+            GtkListBox             *listbox,
+            GtkWidget              *widget)
+{
+  GtkWidget *row;
+  GtkWidget *label;
+  gchar *text;
+
+  row = g_object_new (size_group_row_get_type (), "widget", widget, NULL);
+  text = g_strdup_printf ("%p (%s)", widget, g_type_name_from_instance ((GTypeInstance*)widget));
+  label = gtk_label_new (text);
+  g_free (text);
+  g_object_set (label, "margin", 10, NULL);
+  gtk_widget_set_halign (label, GTK_ALIGN_START);
+  gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
+  gtk_widget_show (label);
+  gtk_container_add (GTK_CONTAINER (row), label);
+  gtk_container_add (GTK_CONTAINER (listbox), row);
+}
+
+static void
+add_size_group (GtkInspectorSizeGroups *sl,
+                GtkSizeGroup           *group)
+{
+  GtkWidget *frame, *box, *box2;
+  GtkWidget *label, *sw, *combo;
+  GSList *widgets, *l;
+  GtkWidget *listbox;
+
+  frame = gtk_frame_new (NULL);
+  gtk_container_add (GTK_CONTAINER (sl), frame);
+  box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+  gtk_container_add (GTK_CONTAINER (frame), box);
+
+  box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
+  gtk_container_add (GTK_CONTAINER (box), box2);
+
+  label = gtk_label_new (_("Ignore hidden"));
+  g_object_set (label, "margin", 10, NULL);
+  gtk_widget_set_halign (label, GTK_ALIGN_START);
+  gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
+  gtk_box_pack_start (GTK_BOX (box2), label, TRUE, TRUE, 0);
+
+  sw = gtk_switch_new ();
+  g_object_set (sw, "margin", 10, NULL);
+  gtk_widget_set_halign (sw, GTK_ALIGN_END);
+  gtk_widget_set_valign (sw, GTK_ALIGN_BASELINE);
+  g_object_bind_property (group, "ignore-hidden",
+                          sw, "active",
+                          G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+  gtk_box_pack_start (GTK_BOX (box2), sw, FALSE, FALSE, 0);
+
+  box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
+  gtk_container_add (GTK_CONTAINER (box), box2);
+
+  label = gtk_label_new (_("Mode"));
+  g_object_set (label, "margin", 10, NULL);
+  gtk_widget_set_halign (label, GTK_ALIGN_START);
+  gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
+  gtk_box_pack_start (GTK_BOX (box2), label, TRUE, TRUE, 0);
+
+  combo = gtk_combo_box_text_new ();
+  g_object_set (combo, "margin", 10, NULL);
+  gtk_widget_set_halign (combo, GTK_ALIGN_END);
+  gtk_widget_set_valign (combo, GTK_ALIGN_BASELINE);
+  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), _("None"));
+  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), _("Horizontal"));
+  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), _("Vertical"));
+  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), _("Both"));
+  g_object_bind_property (group, "mode",
+                          combo, "active",
+                          G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+  gtk_box_pack_start (GTK_BOX (box2), combo, FALSE, FALSE, 0);
+
+  listbox = gtk_list_box_new ();
+  gtk_container_add (GTK_CONTAINER (box), listbox);
+  gtk_list_box_set_selection_mode (GTK_LIST_BOX (listbox), GTK_SELECTION_NONE);
+
+  widgets = gtk_size_group_get_widgets (group);
+  for (l = widgets; l; l = l->next)
+    add_widget (sl, GTK_LIST_BOX (listbox), GTK_WIDGET (l->data));
+
+  gtk_widget_show_all (frame);
+}
+
+void
+gtk_inspector_size_groups_set_object (GtkInspectorSizeGroups *sl,
+                                      GObject                *object)
+{
+  clear_view (sl);
+  gtk_widget_hide (GTK_WIDGET (sl));
+
+  if (GTK_IS_WIDGET (object))
+    {
+      GSList *groups, *l;
+
+      gtk_widget_show (GTK_WIDGET (sl));
+      groups = _gtk_widget_get_sizegroups (GTK_WIDGET (object));
+      for (l = groups; l; l = l->next)
+        {
+          GtkSizeGroup *group = l->data;
+          add_size_group (sl, group);
+        }
+    }
+}
+
+static void
+gtk_inspector_size_groups_init (GtkInspectorSizeGroups *sl)
+{
+  g_object_set (sl,
+                "orientation", GTK_ORIENTATION_VERTICAL,
+                "margin", 40,
+                "spacing", 20,
+                NULL);
+}
+
+static void
+gtk_inspector_size_groups_class_init (GtkInspectorSizeGroupsClass *klass)
+{
+}
+
+// vim: set et sw=2 ts=2:
diff --git a/gtk/inspector/size-groups.h b/gtk/inspector/size-groups.h
new file mode 100644
index 0000000..2d4ccaa
--- /dev/null
+++ b/gtk/inspector/size-groups.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2014 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _GTK_INSPECTOR_SIZE_GROUPS_H_
+#define _GTK_INSPECTOR_SIZE_GROUPS_H_
+
+#include <gtk/gtk.h>
+
+#define GTK_TYPE_INSPECTOR_SIZE_GROUPS            (gtk_inspector_size_groups_get_type())
+#define GTK_INSPECTOR_SIZE_GROUPS(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), 
GTK_TYPE_INSPECTOR_SIZE_GROUPS, GtkInspectorSizeGroups))
+#define GTK_INSPECTOR_SIZE_GROUPS_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), 
GTK_TYPE_INSPECTOR_SIZE_GROUPS, GtkInspectorSizeGroupsClass))
+#define GTK_INSPECTOR_IS_SIZE_GROUPS(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), 
GTK_TYPE_INSPECTOR_SIZE_GROUPS))
+#define GTK_INSPECTOR_IS_SIZE_GROUPS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), 
GTK_TYPE_INSPECTOR_SIZE_GROUPS))
+#define GTK_INSPECTOR_SIZE_GROUPS_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), 
GTK_TYPE_INSPECTOR_SIZE_GROUPS, GtkInspectorSizeGroupsClass))
+
+
+typedef struct _GtkInspectorSizeGroups
+{
+  GtkBox parent;
+} GtkInspectorSizeGroups;
+
+typedef struct _GtkInspectorSizeGroupsClass
+{
+  GtkBoxClass parent;
+} GtkInspectorSizeGroupsClass;
+
+G_BEGIN_DECLS
+
+GType gtk_inspector_size_groups_get_type   (void);
+void  gtk_inspector_size_groups_set_object (GtkInspectorSizeGroups *sl,
+                                            GObject                *object);
+
+G_END_DECLS
+
+#endif // _GTK_INSPECTOR_SIZE_GROUPS_H_
+
+// vim: set et sw=2 ts=2:
diff --git a/gtk/inspector/window.c b/gtk/inspector/window.c
index 4d8b27f..25290ef 100644
--- a/gtk/inspector/window.c
+++ b/gtk/inspector/window.c
@@ -34,6 +34,7 @@
 #include "python-hooks.h"
 #include "python-shell.h"
 #include "button-path.h"
+#include "size-groups.h"
 #include "data-list.h"
 #include "signals-list.h"
 #include "actions.h"
@@ -70,6 +71,7 @@ on_widget_tree_selection_changed (GtkInspectorWidgetTree *wt,
   gtk_inspector_button_path_set_object (GTK_INSPECTOR_BUTTON_PATH (iw->button_path), selected);
   gtk_inspector_classes_list_set_object (GTK_INSPECTOR_CLASSES_LIST (iw->classes_list), selected);
   gtk_inspector_css_editor_set_object (GTK_INSPECTOR_CSS_EDITOR (iw->widget_css_editor), selected);
+  gtk_inspector_size_groups_set_object (GTK_INSPECTOR_SIZE_GROUPS (iw->size_groups), selected);
   gtk_inspector_data_list_set_object (GTK_INSPECTOR_DATA_LIST (iw->data_list), selected);
   gtk_inspector_actions_set_object (GTK_INSPECTOR_ACTIONS (iw->actions), selected);
   if (GTK_IS_WIDGET (selected))
@@ -168,6 +170,7 @@ gtk_inspector_window_class_init (GtkInspectorWindowClass *klass)
   gtk_widget_class_bind_template_child (widget_class, GtkInspectorWindow, object_hierarchy);
   gtk_widget_class_bind_template_child (widget_class, GtkInspectorWindow, python_shell);
   gtk_widget_class_bind_template_child (widget_class, GtkInspectorWindow, widget_popup);
+  gtk_widget_class_bind_template_child (widget_class, GtkInspectorWindow, size_groups);
   gtk_widget_class_bind_template_child (widget_class, GtkInspectorWindow, data_list);
   gtk_widget_class_bind_template_child (widget_class, GtkInspectorWindow, actions);
 
diff --git a/gtk/inspector/window.ui b/gtk/inspector/window.ui
index 6b29a6d..4ee58ec 100644
--- a/gtk/inspector/window.ui
+++ b/gtk/inspector/window.ui
@@ -198,6 +198,20 @@
                       </object>
                     </child> 
                     <child>
+                      <object class="GtkInspectorSizeGroups" id="size_groups">
+                      </object>
+                      <packing>
+                        <property name="tab_expand">True</property>
+                        <property name="tab_fill">True</property>
+                      </packing>
+                    </child>
+                    <child type="tab">
+                      <object class="GtkLabel">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">Sizegroups</property>
+                      </object>
+                    </child> 
+                    <child>
                       <object class="GtkInspectorDataList" id="data_list">
                       </object>
                       <packing>


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