parasite: Display child properties too
This commit is contained in:
		| @ -36,6 +36,7 @@ typedef struct | ||||
|     GtkWidget *window; | ||||
|     GtkWidget *widget_tree; | ||||
|     GtkWidget *prop_list; | ||||
|     GtkWidget *child_prop_list; | ||||
|     GtkWidget *python_shell; | ||||
|     GtkWidget *button_path; | ||||
|     GtkWidget *classes_list; | ||||
|  | ||||
| @ -39,7 +39,8 @@ enum | ||||
| enum | ||||
| { | ||||
|   PROP_0, | ||||
|   PROP_WIDGET_TREE | ||||
|   PROP_WIDGET_TREE, | ||||
|   PROP_CHILD_PROPERTIES | ||||
| }; | ||||
|  | ||||
| struct _ParasitePropListPrivate | ||||
| @ -50,6 +51,8 @@ struct _ParasitePropListPrivate | ||||
|   GList *signal_cnxs; | ||||
|   GtkWidget *widget_tree; | ||||
|   GtkTreeViewColumn *property_column; | ||||
|   GtkTreeViewColumn *value_column; | ||||
|   gboolean child_properties; | ||||
| }; | ||||
|  | ||||
| G_DEFINE_TYPE_WITH_PRIVATE (ParasitePropList, parasite_proplist, GTK_TYPE_TREE_VIEW) | ||||
| @ -163,19 +166,20 @@ constructed (GObject *object) | ||||
|   g_object_set (renderer, | ||||
|                 "scale", TREE_TEXT_SCALE, | ||||
|                 "editable", TRUE, | ||||
|                 "is-child-property", pl->priv->child_properties, | ||||
|                 NULL); | ||||
|   column = gtk_tree_view_column_new_with_attributes ("Value", renderer, | ||||
|                                                      "text", COLUMN_VALUE, | ||||
|                                                      "object", COLUMN_OBJECT, | ||||
|                                                      "name", COLUMN_NAME, | ||||
|                                                       NULL); | ||||
|   gtk_tree_view_append_column (GTK_TREE_VIEW (pl), column); | ||||
|   gtk_tree_view_column_set_resizable (column, TRUE); | ||||
|   pl->priv->value_column = gtk_tree_view_column_new_with_attributes ("Value", renderer, | ||||
|                                                                      "text", COLUMN_VALUE, | ||||
|                                                                      "object", COLUMN_OBJECT, | ||||
|                                                                      "name", COLUMN_NAME, | ||||
|                                                                      NULL); | ||||
|   gtk_tree_view_append_column (GTK_TREE_VIEW (pl), pl->priv->value_column); | ||||
|   gtk_tree_view_column_set_resizable (pl->priv->value_column, TRUE); | ||||
|  | ||||
|   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (pl->priv->model), | ||||
|                                         COLUMN_NAME, | ||||
|                                         GTK_SORT_ASCENDING); | ||||
|  gtk_tree_view_column_set_cell_data_func (column, | ||||
|  gtk_tree_view_column_set_cell_data_func (pl->priv->value_column, | ||||
|                                           renderer, | ||||
|                                           (GtkTreeCellDataFunc) draw_columns, | ||||
|                                           pl, | ||||
| @ -212,6 +216,10 @@ get_property (GObject    *object, | ||||
|         g_value_take_object (value, pl->priv->widget_tree); | ||||
|         break; | ||||
|  | ||||
|       case PROP_CHILD_PROPERTIES: | ||||
|         g_value_set_boolean (value, pl->priv->child_properties); | ||||
|         break; | ||||
|  | ||||
|       default: | ||||
|         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); | ||||
|         break; | ||||
| @ -232,6 +240,10 @@ set_property (GObject      *object, | ||||
|         pl->priv->widget_tree = g_value_get_object (value); | ||||
|         break; | ||||
|  | ||||
|       case PROP_CHILD_PROPERTIES: | ||||
|         pl->priv->child_properties = g_value_get_boolean (value); | ||||
|         break; | ||||
|  | ||||
|       default: | ||||
|         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); | ||||
|         break; | ||||
| @ -254,6 +266,9 @@ parasite_proplist_class_init (ParasitePropListClass *klass) | ||||
|                                                          "Widget tree", | ||||
|                                                          GTK_TYPE_WIDGET, | ||||
|                                                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); | ||||
|   g_object_class_install_property (object_class, PROP_CHILD_PROPERTIES, | ||||
|       g_param_spec_boolean ("child-properties", "Child properties", "Child properties", | ||||
|                             FALSE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @ -265,7 +280,17 @@ parasite_prop_list_update_prop (ParasitePropList *pl, | ||||
|   char *value; | ||||
|  | ||||
|   g_value_init(&gvalue, prop->value_type); | ||||
|   g_object_get_property (pl->priv->object, prop->name, &gvalue); | ||||
|   if (pl->priv->child_properties) | ||||
|     { | ||||
|       GtkWidget *parent; | ||||
|  | ||||
|       parent = gtk_widget_get_parent (GTK_WIDGET (pl->priv->object)); | ||||
|       gtk_container_child_get_property (GTK_CONTAINER (parent), | ||||
|                                         GTK_WIDGET (pl->priv->object), | ||||
|                                         prop->name, &gvalue); | ||||
|     } | ||||
|   else | ||||
|     g_object_get_property (pl->priv->object, prop->name, &gvalue); | ||||
|  | ||||
|   if (G_VALUE_HOLDS_ENUM (&gvalue)) | ||||
|     { | ||||
| @ -281,7 +306,7 @@ parasite_prop_list_update_prop (ParasitePropList *pl, | ||||
|  | ||||
|   gtk_list_store_set (pl->priv->model, iter, | ||||
|                       COLUMN_NAME, prop->name, | ||||
|                       COLUMN_VALUE, value, | ||||
|                       COLUMN_VALUE, value ? value : g_strdup (""), | ||||
|                       COLUMN_DEFINED_AT, g_type_name (prop->owner_type), | ||||
|                       COLUMN_OBJECT, pl->priv->object, | ||||
|                       COLUMN_TOOLTIP, g_param_spec_get_blurb (prop), | ||||
| @ -304,10 +329,12 @@ parasite_proplist_prop_changed_cb (GObject *pspec, | ||||
| } | ||||
|  | ||||
| GtkWidget * | ||||
| parasite_proplist_new (GtkWidget *widget_tree) | ||||
| parasite_proplist_new (GtkWidget *widget_tree, | ||||
|                        gboolean   child_properties) | ||||
| { | ||||
|     return g_object_new (PARASITE_TYPE_PROPLIST, | ||||
|                          "widget-tree", widget_tree, | ||||
|                          "child-properties", child_properties, | ||||
|                          NULL); | ||||
| } | ||||
|  | ||||
| @ -336,7 +363,22 @@ parasite_proplist_set_object (ParasitePropList* pl, GObject *object) | ||||
|   g_hash_table_remove_all (pl->priv->prop_iters); | ||||
|   gtk_list_store_clear (pl->priv->model); | ||||
|  | ||||
|   props = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &num_properties); | ||||
|   if (pl->priv->child_properties) | ||||
|     { | ||||
|       GtkWidget *parent; | ||||
|  | ||||
|       if (!GTK_IS_WIDGET (object)) | ||||
|         return; | ||||
|  | ||||
|       parent = gtk_widget_get_parent (GTK_WIDGET (object)); | ||||
|       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 (object), &num_properties); | ||||
|  | ||||
|   for (i = 0; i < num_properties; i++) | ||||
|     { | ||||
|       GParamSpec *prop = props[i]; | ||||
| @ -351,7 +393,10 @@ parasite_proplist_set_object (ParasitePropList* pl, GObject *object) | ||||
|       g_hash_table_insert (pl->priv->prop_iters, (gpointer) prop->name, gtk_tree_iter_copy (&iter)); | ||||
|  | ||||
|       /* Listen for updates */ | ||||
|       signal_name = g_strdup_printf ("notify::%s", prop->name); | ||||
|       if (pl->priv->child_properties) | ||||
|         signal_name = g_strdup_printf ("child-notify::%s", prop->name); | ||||
|       else | ||||
|         signal_name = g_strdup_printf ("notify::%s", prop->name); | ||||
|  | ||||
|       pl->priv->signal_cnxs = | ||||
|             g_list_prepend (pl->priv->signal_cnxs, GINT_TO_POINTER( | ||||
|  | ||||
| @ -49,7 +49,8 @@ typedef struct _ParasitePropListClass { | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| GType      parasite_proplist_get_type   (void); | ||||
| GtkWidget *parasite_proplist_new        (GtkWidget *widget_tree); | ||||
| GtkWidget *parasite_proplist_new        (GtkWidget *widget_tree, | ||||
|                                          gboolean   child_properties); | ||||
| void       parasite_proplist_set_object (ParasitePropList *proplist, | ||||
|                                          GObject          *object); | ||||
|  | ||||
|  | ||||
| @ -28,13 +28,15 @@ struct _ParasitePropertyCellRendererPrivate | ||||
| { | ||||
|   GObject *object; | ||||
|   char *name; | ||||
|   gboolean is_child_property; | ||||
| }; | ||||
|  | ||||
| enum | ||||
| { | ||||
|   PROP_0, | ||||
|   PROP_OBJECT, | ||||
|   PROP_NAME | ||||
|   PROP_NAME, | ||||
|   PROP_IS_CHILD_PROPERTY | ||||
| }; | ||||
|  | ||||
| G_DEFINE_TYPE_WITH_PRIVATE (ParasitePropertyCellRenderer, parasite_property_cell_renderer, GTK_TYPE_CELL_RENDERER_TEXT); | ||||
| @ -63,6 +65,10 @@ get_property (GObject *object, | ||||
|         g_value_set_string(value, r->priv->name); | ||||
|         break; | ||||
|  | ||||
|       case PROP_IS_CHILD_PROPERTY: | ||||
|         g_value_set_boolean (value, r->priv->is_child_property); | ||||
|         break; | ||||
|  | ||||
|       default: | ||||
|         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); | ||||
|         break; | ||||
| @ -88,24 +94,81 @@ set_property (GObject *object, | ||||
|         r->priv->name = g_value_dup_string (value); | ||||
|         break; | ||||
|  | ||||
|       case PROP_IS_CHILD_PROPERTY: | ||||
|         r->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_property (GtkCellRenderer *renderer) | ||||
| { | ||||
|   ParasitePropertyCellRenderer *r = PARASITE_PROPERTY_CELL_RENDERER (renderer); | ||||
|  | ||||
|   if (r->priv->is_child_property) | ||||
|     { | ||||
|       GtkWidget *parent; | ||||
|  | ||||
|       parent = gtk_widget_get_parent (GTK_WIDGET (r->priv->object)); | ||||
|  | ||||
|       return gtk_container_class_find_child_property (G_OBJECT_GET_CLASS (parent), r->priv->name); | ||||
|     } | ||||
|  | ||||
|   return g_object_class_find_property (G_OBJECT_GET_CLASS (r->priv->object), r->priv->name); | ||||
| } | ||||
|  | ||||
| static void | ||||
| get_value (GtkCellRenderer *renderer, | ||||
|            GValue          *gvalue) | ||||
| { | ||||
|   ParasitePropertyCellRenderer *r = PARASITE_PROPERTY_CELL_RENDERER (renderer); | ||||
|  | ||||
|   if (r->priv->is_child_property) | ||||
|     { | ||||
|       GtkWidget *widget; | ||||
|       GtkWidget *parent; | ||||
|  | ||||
|       widget = GTK_WIDGET (r->priv->object); | ||||
|       parent = gtk_widget_get_parent (widget); | ||||
|  | ||||
|       gtk_container_child_get_property (GTK_CONTAINER (parent), widget, r->priv->name, gvalue); | ||||
|     } | ||||
|   else | ||||
|     g_object_get_property (r->priv->object, r->priv->name, gvalue); | ||||
| } | ||||
|  | ||||
| static void | ||||
| set_value (GtkCellRenderer *renderer, | ||||
|            GValue          *gvalue) | ||||
| { | ||||
|   ParasitePropertyCellRenderer *r = PARASITE_PROPERTY_CELL_RENDERER (renderer); | ||||
|  | ||||
|   if (r->priv->is_child_property) | ||||
|     { | ||||
|       GtkWidget *widget; | ||||
|       GtkWidget *parent; | ||||
|  | ||||
|       widget = GTK_WIDGET (r->priv->object); | ||||
|       parent = gtk_widget_get_parent (widget); | ||||
|  | ||||
|       gtk_container_child_set_property (GTK_CONTAINER (parent), widget, r->priv->name, gvalue); | ||||
|     } | ||||
|   else | ||||
|     g_object_set_property (r->priv->object, r->priv->name, gvalue); | ||||
| } | ||||
|  | ||||
| static void | ||||
| stop_editing(GtkCellEditable *editable, GtkCellRenderer *renderer) | ||||
| { | ||||
|     GObject *object; | ||||
|     const char *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 = g_object_class_find_property(G_OBJECT_GET_CLASS(object), name); | ||||
|     prop = find_property (renderer); | ||||
|     g_value_init(&gvalue, prop->value_type); | ||||
|  | ||||
|     if (GTK_IS_ENTRY(editable)) | ||||
| @ -172,7 +235,7 @@ stop_editing(GtkCellEditable *editable, GtkCellRenderer *renderer) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     g_object_set_property(object, name, &gvalue); | ||||
|     set_value (renderer, &gvalue); | ||||
|     g_value_unset(&gvalue); | ||||
| } | ||||
|  | ||||
| @ -187,19 +250,15 @@ start_editing (GtkCellRenderer *renderer, | ||||
| { | ||||
|     PangoFontDescription *font_desc; | ||||
|     GtkCellEditable *editable = NULL; | ||||
|     GObject *object; | ||||
|     const char *name; | ||||
|     GValue gvalue = {0}; | ||||
|     GParamSpec *prop; | ||||
|     ParasitePropertyCellRenderer *r = PARASITE_PROPERTY_CELL_RENDERER (renderer); | ||||
|  | ||||
|     g_object_get(renderer, | ||||
|                  "object", &object, | ||||
|                  "name", &name, | ||||
|                  NULL); | ||||
|     prop = find_property (renderer); | ||||
|  | ||||
|     prop = g_object_class_find_property(G_OBJECT_GET_CLASS(object), name); | ||||
|     g_value_init(&gvalue, prop->value_type); | ||||
|     g_object_get_property(object, name, &gvalue); | ||||
|  | ||||
|     get_value (renderer, &gvalue); | ||||
|  | ||||
|     if (G_VALUE_HOLDS_OBJECT (&gvalue)) | ||||
|       { | ||||
| @ -214,7 +273,7 @@ start_editing (GtkCellRenderer *renderer, | ||||
|               { | ||||
|                 parasite_widget_tree_select_object (widget_tree, prop_object); | ||||
|               } | ||||
|             else if (parasite_widget_tree_find_object (widget_tree, object, &iter)) | ||||
|             else if (parasite_widget_tree_find_object (widget_tree, r->priv->object, &iter)) | ||||
|               { | ||||
|                 parasite_widget_tree_append_object (widget_tree, prop_object, &iter); | ||||
|                 parasite_widget_tree_select_object (widget_tree, prop_object); | ||||
| @ -366,8 +425,6 @@ start_editing (GtkCellRenderer *renderer, | ||||
|     pango_font_description_free(font_desc); | ||||
|  | ||||
|     g_signal_connect(editable, "editing_done", G_CALLBACK (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; | ||||
| } | ||||
| @ -398,6 +455,10 @@ parasite_property_cell_renderer_class_init (ParasitePropertyCellRendererClass *k | ||||
|                              "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)); | ||||
| } | ||||
|  | ||||
| GtkCellRenderer * | ||||
|  | ||||
| @ -42,10 +42,9 @@ on_widget_tree_selection_changed (ParasiteWidgetTree *widget_tree, | ||||
|  | ||||
|   if (selected != NULL) | ||||
|     { | ||||
|       parasite_proplist_set_object (PARASITE_PROPLIST (parasite->prop_list), | ||||
|                                     selected); | ||||
|       parasite_objecthierarchy_set_object (PARASITE_OBJECTHIERARCHY (parasite->oh), | ||||
|                                            selected); | ||||
|       parasite_proplist_set_object (PARASITE_PROPLIST (parasite->prop_list), selected); | ||||
|       parasite_proplist_set_object (PARASITE_PROPLIST (parasite->child_prop_list), selected); | ||||
|       parasite_objecthierarchy_set_object (PARASITE_OBJECTHIERARCHY (parasite->oh), selected); | ||||
|  | ||||
|       if (GTK_IS_WIDGET (selected)) | ||||
|         { | ||||
| @ -135,9 +134,11 @@ create_widget_list_pane(ParasiteWindow *parasite) | ||||
| } | ||||
|  | ||||
| static GtkWidget * | ||||
| create_prop_list_pane(ParasiteWindow *parasite) | ||||
| create_prop_list_pane (ParasiteWindow *parasite, | ||||
|                        gboolean        child_properties) | ||||
| { | ||||
|     GtkWidget *swin; | ||||
|     GtkWidget *pl; | ||||
|  | ||||
|     swin = g_object_new (GTK_TYPE_SCROLLED_WINDOW, | ||||
|                         "hscrollbar-policy", GTK_POLICY_AUTOMATIC, | ||||
| @ -146,8 +147,13 @@ create_prop_list_pane(ParasiteWindow *parasite) | ||||
|                         "width-request", 250, | ||||
|                         NULL); | ||||
|  | ||||
|     parasite->prop_list = parasite_proplist_new (parasite->widget_tree); | ||||
|     gtk_container_add(GTK_CONTAINER(swin), parasite->prop_list); | ||||
|     pl = parasite_proplist_new (parasite->widget_tree, child_properties); | ||||
|     gtk_container_add (GTK_CONTAINER (swin), pl); | ||||
|  | ||||
|     if (child_properties) | ||||
|       parasite->child_prop_list = pl; | ||||
|     else | ||||
|       parasite->prop_list = pl; | ||||
|  | ||||
|     return swin; | ||||
| } | ||||
| @ -273,8 +279,12 @@ gtkparasite_window_create() | ||||
|                        "show-border", FALSE, | ||||
|                        NULL); | ||||
|     gtk_notebook_append_page (GTK_NOTEBOOK (nb), | ||||
|                               create_prop_list_pane (window), | ||||
|                               gtk_label_new ("GObject Properties")); | ||||
|                               create_prop_list_pane (window, FALSE), | ||||
|                               gtk_label_new ("Properties")); | ||||
|  | ||||
|     gtk_notebook_append_page (GTK_NOTEBOOK (nb), | ||||
|                               create_prop_list_pane (window, TRUE), | ||||
|                               gtk_label_new ("Child Properties")); | ||||
|  | ||||
|     window->oh = parasite_objecthierarchy_new (); | ||||
|     gtk_notebook_append_page (GTK_NOTEBOOK (nb), | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Matthias Clasen
					Matthias Clasen