diff options
author | Matthias Clasen <mclasen@redhat.com> | 2014-05-03 03:08:23 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2014-05-03 03:08:23 -0400 |
commit | 34566964844d0a6bf1b910c28530e30cb0b20900 (patch) | |
tree | f791bacd6e99770a287807dec0b08e754d3a5338 | |
parent | 85c68925fe7f7e7abfb400f05bf318a92f838f11 (diff) | |
download | gtk+-parasite.tar.gz |
parasite: Display child properties tooparasite
-rw-r--r-- | modules/other/parasite/parasite.h | 1 | ||||
-rw-r--r-- | modules/other/parasite/prop-list.c | 115 | ||||
-rw-r--r-- | modules/other/parasite/prop-list.h | 4 | ||||
-rw-r--r-- | modules/other/parasite/property-cell-renderer.c | 99 | ||||
-rw-r--r-- | modules/other/parasite/window.c | 26 |
5 files changed, 215 insertions, 30 deletions
diff --git a/modules/other/parasite/parasite.h b/modules/other/parasite/parasite.h index 3a24b9c7fb..34ad6a77a9 100644 --- a/modules/other/parasite/parasite.h +++ b/modules/other/parasite/parasite.h @@ -36,6 +36,7 @@ typedef struct GtkWidget *window; GtkWidget *widget_tree; GtkWidget *prop_list; + GtkWidget *child_prop_list; GtkWidget *action_list; GtkWidget *python_shell; diff --git a/modules/other/parasite/prop-list.c b/modules/other/parasite/prop-list.c index 9fa4c108fa..5196ba3b9d 100644 --- a/modules/other/parasite/prop-list.c +++ b/modules/other/parasite/prop-list.c @@ -33,6 +33,11 @@ enum NUM_COLUMNS }; +enum +{ + PROP_ZERO, + PROP_CHILD_PROPS +}; struct _ParasitePropListPrivate { @@ -40,6 +45,9 @@ struct _ParasitePropListPrivate GtkListStore *model; GHashTable *prop_iters; GList *signal_cnxs; + gboolean child_props; + GtkTreeViewColumn *name_col; + GtkTreeViewColumn *value_col; }; #define PARASITE_PROPLIST_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), PARASITE_TYPE_PROPLIST, ParasitePropListPrivate)) @@ -73,6 +81,7 @@ parasite_proplist_init (ParasitePropList *proplist, gtk_tree_view_column_set_resizable (column, TRUE); gtk_tree_view_column_set_sort_order (column, GTK_SORT_ASCENDING); gtk_tree_view_column_set_sort_column_id (column, COLUMN_NAME); + proplist->priv->name_col = column; renderer = parasite_property_cell_renderer_new (); g_object_set (G_OBJECT (renderer), "scale", TREE_TEXT_SCALE, NULL); @@ -84,12 +93,71 @@ parasite_proplist_init (ParasitePropList *proplist, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (proplist), column); gtk_tree_view_column_set_resizable (column, TRUE); + proplist->priv->value_col = column; gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (proplist->priv->model), COLUMN_NAME, GTK_SORT_ASCENDING); } +static void +parasite_proplist_set_child_props (ParasitePropList *proplist, + gboolean child_props) +{ + GList *cells; + + proplist->priv->child_props = child_props; + + if (child_props) + gtk_tree_view_column_set_title (proplist->priv->name_col, "Child Property"); + else + gtk_tree_view_column_set_title (proplist->priv->name_col, "Property"); + + cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (proplist->priv->value_col)); + g_object_set (cells->data, "is-child-property", child_props, NULL); + g_list_free (cells); +} + +static void +parasite_proplist_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec) +{ + ParasitePropList *proplist = PARASITE_PROPLIST (object); + + switch (param_id) + { + case PROP_CHILD_PROPS: + g_value_set_boolean (value, proplist->priv->child_props); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void +parasite_proplist_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec) +{ + ParasitePropList *proplist = PARASITE_PROPLIST (object); + + switch (param_id) + { + case PROP_CHILD_PROPS: + parasite_proplist_set_child_props (proplist, g_value_get_boolean (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + static void parasite_proplist_class_init (ParasitePropListClass *klass) @@ -97,6 +165,12 @@ parasite_proplist_class_init (ParasitePropListClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); + object_class->get_property = parasite_proplist_get_property; + object_class->set_property = parasite_proplist_set_property; + + g_object_class_install_property (object_class, PROP_CHILD_PROPS, + g_param_spec_boolean ("child-properties", "Child properties", "Child properties", + FALSE, G_PARAM_READWRITE)); g_type_class_add_private (object_class, sizeof (ParasitePropListPrivate)); } @@ -110,8 +184,18 @@ parasite_prop_list_update_prop (ParasitePropList *proplist, gchar *value; g_value_init (&gvalue, prop->value_type); - g_object_get_property (G_OBJECT (proplist->priv->widget), - prop->name, &gvalue); + if (proplist->priv->child_props) + { + GtkWidget *parent; + + parent = gtk_widget_get_parent (proplist->priv->widget); + gtk_container_child_get_property (GTK_CONTAINER (parent), + proplist->priv->widget, + prop->name, &gvalue); + } + else + g_object_get_property (G_OBJECT (proplist->priv->widget), + prop->name, &gvalue); if (G_VALUE_HOLDS_ENUM (&gvalue)) { @@ -176,9 +260,11 @@ parasite_proplist_get_type (void) GtkWidget * -parasite_proplist_new (void) +parasite_proplist_new (gboolean child_props) { - return GTK_WIDGET (g_object_new (PARASITE_TYPE_PROPLIST, NULL)); + return GTK_WIDGET (g_object_new (PARASITE_TYPE_PROPLIST, + "child-properties", child_props, + NULL)); } void @@ -207,8 +293,20 @@ parasite_proplist_set_widget (ParasitePropList *proplist, g_hash_table_remove_all (proplist->priv->prop_iters); gtk_list_store_clear (proplist->priv->model); - props = g_object_class_list_properties (G_OBJECT_GET_CLASS (widget), - &num_properties); + if (proplist->priv->child_props) + { + GtkWidget *parent; + + parent = gtk_widget_get_parent (widget); + if (!parent) + return; + + props = gtk_container_class_list_child_properties (G_OBJECT_GET_CLASS (parent), + &num_properties); + } + else + props = g_object_class_list_properties (G_OBJECT_GET_CLASS (widget), + &num_properties); for (i = 0; i < num_properties; i++) { @@ -226,7 +324,10 @@ parasite_proplist_set_widget (ParasitePropList *proplist, gtk_tree_iter_copy (&iter)); /* Listen for updates */ - signal_name = g_strdup_printf ("notify::%s", prop->name); + if (proplist->priv->child_props) + signal_name = g_strdup_printf ("child-notify::%s", prop->name); + else + signal_name = g_strdup_printf ("notify::%s", prop->name); handler = g_signal_connect (G_OBJECT (widget), signal_name, G_CALLBACK (parasite_proplist_prop_changed_cb), diff --git a/modules/other/parasite/prop-list.h b/modules/other/parasite/prop-list.h index c88e583d45..bfa1f4a3f3 100644 --- a/modules/other/parasite/prop-list.h +++ b/modules/other/parasite/prop-list.h @@ -55,9 +55,9 @@ typedef struct _ParasitePropListClass G_BEGIN_DECLS GType parasite_proplist_get_type (void); -GtkWidget *parasite_proplist_new (void); +GtkWidget *parasite_proplist_new (gboolean child_props); void parasite_proplist_set_widget (ParasitePropList *proplist, - GtkWidget *widget); + GtkWidget *widget); G_END_DECLS diff --git a/modules/other/parasite/property-cell-renderer.c b/modules/other/parasite/property-cell-renderer.c index 1f6052daf1..6cb8505e97 100644 --- a/modules/other/parasite/property-cell-renderer.c +++ b/modules/other/parasite/property-cell-renderer.c @@ -33,6 +33,7 @@ typedef struct { GObject *object; char *name; + gboolean is_child_property; } ParasitePropertyCellRendererPrivate; @@ -61,7 +62,8 @@ enum { PROP_0, PROP_OBJECT, - PROP_NAME + PROP_NAME, + PROP_IS_CHILD_PROPERTY }; @@ -92,6 +94,10 @@ parasite_property_cell_renderer_class_init (ParasitePropertyCellRendererClass *k g_param_spec_string ("name", "Name", "The property name", NULL, G_PARAM_READWRITE)); + g_object_class_install_property (object_class, PROP_IS_CHILD_PROPERTY, + g_param_spec_boolean ("is-child-property", "Child property", "Child property", + FALSE, G_PARAM_READWRITE)); + g_type_class_add_private (object_class, sizeof (ParasitePropertyCellRendererPrivate)); } @@ -114,6 +120,10 @@ parasite_property_cell_renderer_get_property (GObject *object, g_value_set_string (value, priv->name); break; + case PROP_IS_CHILD_PROPERTY: + g_value_set_boolean (value, priv->is_child_property); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); break; @@ -142,12 +152,79 @@ parasite_property_cell_renderer_set_property (GObject *object, g_object_notify (object, "name"); break; + case PROP_IS_CHILD_PROPERTY: + priv->is_child_property = g_value_get_boolean (value); + g_object_notify (object, "is-child-property"); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); break; } } +static GParamSpec * +find_prop (GtkCellRenderer *renderer) +{ + ParasitePropertyCellRendererPrivate *priv = + PARASITE_PROPERTY_CELL_RENDERER_GET_PRIVATE (renderer); + + if (priv->is_child_property) + { + GtkWidget *widget; + GtkWidget *parent; + + widget = GTK_WIDGET (priv->object); + parent = gtk_widget_get_parent (widget); + + return gtk_container_class_find_child_property (G_OBJECT_GET_CLASS (parent), priv->name); + } + + return g_object_class_find_property (G_OBJECT_GET_CLASS (priv->object), priv->name); +} + +static void +get_value (GtkCellRenderer *renderer, + GValue *gvalue) +{ + ParasitePropertyCellRendererPrivate *priv = + PARASITE_PROPERTY_CELL_RENDERER_GET_PRIVATE (renderer); + + if (priv->is_child_property) + { + GtkWidget *widget; + GtkWidget *parent; + + widget = GTK_WIDGET (priv->object); + parent = gtk_widget_get_parent (widget); + + gtk_container_child_get_property (GTK_CONTAINER (parent), widget, priv->name, gvalue); + } + else + g_object_get_property (priv->object, priv->name, gvalue); +} + +static void +set_value (GtkCellRenderer *renderer, + GValue *gvalue) +{ + ParasitePropertyCellRendererPrivate *priv = + PARASITE_PROPERTY_CELL_RENDERER_GET_PRIVATE (renderer); + + if (priv->is_child_property) + { + GtkWidget *widget; + GtkWidget *parent; + + widget = GTK_WIDGET (priv->object); + parent = gtk_widget_get_parent (widget); + + gtk_container_child_set_property (GTK_CONTAINER (parent), widget, priv->name, gvalue); + } + else + g_object_set_property (priv->object, priv->name, gvalue); +} + static GtkCellEditable * parasite_property_cell_renderer_start_editing (GtkCellRenderer *renderer, GdkEvent *event, @@ -159,20 +236,17 @@ parasite_property_cell_renderer_start_editing (GtkCellRenderer *renderer, { PangoFontDescription *font_desc; GtkCellEditable *editable = NULL; - GObject *object; - const char *name; GValue gvalue = { 0 }; GParamSpec *prop; - g_object_get (renderer, "object", &object, "name", &name, NULL); - - prop = g_object_class_find_property (G_OBJECT_GET_CLASS (object), name); + prop = find_prop (renderer); if (!(prop->flags & G_PARAM_WRITABLE)) return NULL; g_value_init (&gvalue, prop->value_type); - g_object_get_property (object, name, &gvalue); + + get_value (renderer, &gvalue); if (G_VALUE_HOLDS_ENUM (&gvalue) || G_VALUE_HOLDS_BOOLEAN (&gvalue)) { @@ -308,9 +382,6 @@ parasite_property_cell_renderer_start_editing (GtkCellRenderer *renderer, G_CALLBACK (parasite_property_cell_renderer_stop_editing), renderer); - g_object_set_data_full (G_OBJECT (editable), "_prop_name", g_strdup (name), g_free); - g_object_set_data (G_OBJECT (editable), "_prop_object", object); - return editable; } @@ -318,15 +389,11 @@ static void parasite_property_cell_renderer_stop_editing (GtkCellEditable *editable, GtkCellRenderer *renderer) { - GObject *object; - const gchar *name; GValue gvalue = { 0 }; GParamSpec *prop; - object = g_object_get_data (G_OBJECT (editable), "_prop_object"); - name = g_object_get_data (G_OBJECT (editable), "_prop_name"); + prop = find_prop (renderer); - prop = g_object_class_find_property (G_OBJECT_GET_CLASS (object), name); g_value_init (&gvalue, prop->value_type); if (GTK_IS_ENTRY (editable)) @@ -388,7 +455,7 @@ parasite_property_cell_renderer_stop_editing (GtkCellEditable *editable, } } - g_object_set_property (object, name, &gvalue); + set_value (renderer, &gvalue); g_value_unset (&gvalue); } diff --git a/modules/other/parasite/window.c b/modules/other/parasite/window.c index 6d09426617..f8769f415f 100644 --- a/modules/other/parasite/window.c +++ b/modules/other/parasite/window.c @@ -33,8 +33,8 @@ on_widget_tree_selection_changed (ParasiteWidgetTree *widget_tree, parasite_widget_tree_get_selected_widget (widget_tree); if (selected != NULL) { - parasite_proplist_set_widget (PARASITE_PROPLIST (parasite->prop_list), - selected); + parasite_proplist_set_widget (PARASITE_PROPLIST (parasite->prop_list), selected); + parasite_proplist_set_widget (PARASITE_PROPLIST (parasite->child_prop_list), selected); /* Flash the widget. */ gtkparasite_flash_widget (parasite, selected); @@ -66,20 +66,36 @@ create_widget_list_pane (ParasiteWindow *parasite) static GtkWidget * create_prop_list_pane (ParasiteWindow *parasite) { + GtkWidget *paned; GtkWidget *swin; + paned = gtk_paned_new (GTK_ORIENTATION_VERTICAL); + swin = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin), GTK_SHADOW_IN); gtk_widget_set_size_request (swin, 250, -1); - - parasite->prop_list = parasite_proplist_new (); + parasite->prop_list = parasite_proplist_new (FALSE); gtk_widget_show (parasite->prop_list); gtk_container_add (GTK_CONTAINER (swin), parasite->prop_list); + gtk_widget_show (swin); + gtk_container_add (GTK_CONTAINER (paned), swin); - return swin; + swin = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin), + GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin), + GTK_SHADOW_IN); + gtk_widget_set_size_request (swin, 250, -1); + parasite->child_prop_list = parasite_proplist_new (TRUE); + gtk_widget_show (parasite->child_prop_list); + gtk_container_add (GTK_CONTAINER (swin), parasite->child_prop_list); + gtk_widget_show (swin); + gtk_container_add (GTK_CONTAINER (paned), swin); + + return paned; } static void |