From fde21b57cd9ae74cc63cb9e35f90ea1385450505 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 11 Apr 2019 23:42:31 -0400 Subject: [PATCH] inspector: Improve property list editing Replace the treeview with popups on the property page with a listbox with inline editing. --- gtk/inspector/object-tree.c | 12 +-- gtk/inspector/prop-editor.c | 165 +++++++++++++++-------------- gtk/inspector/prop-list.c | 201 +++++++++++++++++++----------------- gtk/inspector/prop-list.ui | 138 ++++++++++--------------- 4 files changed, 250 insertions(+), 266 deletions(-) diff --git a/gtk/inspector/object-tree.c b/gtk/inspector/object-tree.c index 9dae1d5183..f2caf34708 100644 --- a/gtk/inspector/object-tree.c +++ b/gtk/inspector/object-tree.c @@ -814,13 +814,13 @@ destroy_controller (GtkEventController *controller) } static void -root (GtkWidget *widget) +map (GtkWidget *widget) { GtkInspectorObjectTree *wt = GTK_INSPECTOR_OBJECT_TREE (widget); GtkEventController *controller; GtkWidget *toplevel; - GTK_WIDGET_CLASS (gtk_inspector_object_tree_parent_class)->root (widget); + GTK_WIDGET_CLASS (gtk_inspector_object_tree_parent_class)->map (widget); toplevel = gtk_widget_get_toplevel (widget); @@ -833,14 +833,14 @@ root (GtkWidget *widget) } static void -unroot (GtkWidget *widget) +unmap (GtkWidget *widget) { GtkWidget *toplevel; toplevel = gtk_widget_get_toplevel (widget); g_object_set_data (G_OBJECT (toplevel), "object-controller", NULL); - GTK_WIDGET_CLASS (gtk_inspector_object_tree_parent_class)->unroot (widget); + GTK_WIDGET_CLASS (gtk_inspector_object_tree_parent_class)->unmap (widget); } static gboolean @@ -1196,8 +1196,8 @@ gtk_inspector_object_tree_class_init (GtkInspectorObjectTreeClass *klass) object_class->dispose = gtk_inspector_object_tree_dispose; - widget_class->root = root; - widget_class->unroot = unroot; + widget_class->map = map; + widget_class->unmap = unmap; signals[OBJECT_ACTIVATED] = g_signal_new ("object-activated", diff --git a/gtk/inspector/prop-editor.c b/gtk/inspector/prop-editor.c index 958b3182a1..a9e186613d 100644 --- a/gtk/inspector/prop-editor.c +++ b/gtk/inspector/prop-editor.c @@ -29,10 +29,9 @@ #include "gtkcellrenderertext.h" #include "gtkcolorbutton.h" #include "gtkcolorchooser.h" -#include "gtkcolorchooserwidget.h" #include "gtkcombobox.h" +#include "gtkfontbutton.h" #include "gtkfontchooser.h" -#include "gtkfontchooserwidget.h" #include "gtkiconview.h" #include "gtklabel.h" #include "gtkpopover.h" @@ -44,6 +43,8 @@ #include "gtkwidgetprivate.h" #include "gtkcssnodeprivate.h" #include "gtklistbox.h" +#include "gtkcomboboxtext.h" +#include "gtkmenubutton.h" struct _GtkInspectorPropEditorPrivate { @@ -412,6 +413,7 @@ strv_changed (GObject *object, GParamSpec *pspec, gpointer data) g_value_unset (&val); } + static void bool_modified (GtkToggleButton *tb, ObjectProperty *p) { @@ -439,24 +441,19 @@ bool_changed (GObject *object, GParamSpec *pspec, gpointer data) unblock_controller (G_OBJECT (tb)); } - gtk_button_set_label (GTK_BUTTON (tb), - g_value_get_boolean (&val) ? "TRUE" : "FALSE"); - g_value_unset (&val); } static void -enum_modified (GtkToggleButton *button, ObjectProperty *p) +enum_modified (GtkComboBox *combo, ObjectProperty *p) { gint i; GEnumClass *eclass; GValue val = G_VALUE_INIT; - if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) - return; + i = gtk_combo_box_get_active (combo); eclass = G_ENUM_CLASS (g_type_class_peek (p->spec->value_type)); - i = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button), "index")); g_value_init (&val, p->spec->value_type); g_value_set_enum (&val, eclass->values[i].value); @@ -467,12 +464,10 @@ enum_modified (GtkToggleButton *button, ObjectProperty *p) static void enum_changed (GObject *object, GParamSpec *pspec, gpointer data) { - GtkWidget *viewport; - GtkWidget *box; - GList *children, *c; + GtkComboBox *combo = GTK_COMBO_BOX (data); GValue val = G_VALUE_INIT; GEnumClass *eclass; - gint i, j; + gint i; eclass = G_ENUM_CLASS (g_type_class_peek (pspec->value_type)); @@ -488,21 +483,9 @@ enum_changed (GObject *object, GParamSpec *pspec, gpointer data) } g_value_unset (&val); - viewport = gtk_bin_get_child (GTK_BIN (data)); - box = gtk_bin_get_child (GTK_BIN (viewport)); - children = gtk_container_get_children (GTK_CONTAINER (box)); - - for (c = children; c; c = c->next) - block_controller (G_OBJECT (c->data)); - - for (c = children, j = 0; c; c = c->next, j++) - { - if (j == i) - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (c->data), TRUE); - } - - for (c = children; c; c = c->next) - unblock_controller (G_OBJECT (c->data)); + block_controller (G_OBJECT (combo)); + gtk_combo_box_set_active (combo, i); + unblock_controller (G_OBJECT (combo)); } static void @@ -530,6 +513,38 @@ flags_modified (GtkCheckButton *button, ObjectProperty *p) g_value_unset (&val); } +static char * +flags_to_string (GFlagsClass *flags_class, + guint value) +{ + GString *str; + GFlagsValue *flags_value; + + str = g_string_new (NULL); + + while ((str->len == 0 || value != 0) && + (flags_value = g_flags_get_first_value (flags_class, value)) != NULL) + { + if (str->len > 0) + g_string_append (str, " | "); + + g_string_append (str, flags_value->value_nick); + + value &= ~flags_value->value; + } + + /* Show the extra bits */ + if (value != 0 || str->len == 0) + { + if (str->len > 0) + g_string_append (str, " | "); + + g_string_append_printf (str, "0x%x", value); + } + + return g_string_free (str, FALSE); +} + static void flags_changed (GObject *object, GParamSpec *pspec, gpointer data) { @@ -538,8 +553,11 @@ flags_changed (GObject *object, GParamSpec *pspec, gpointer data) GFlagsClass *fclass; guint flags; gint i; + GtkPopover *popover; + GtkWidget *sw; GtkWidget *viewport; GtkWidget *box; + char *str; fclass = G_FLAGS_CLASS (g_type_class_peek (pspec->value_type)); @@ -548,7 +566,13 @@ flags_changed (GObject *object, GParamSpec *pspec, gpointer data) flags = g_value_get_flags (&val); g_value_unset (&val); - viewport = gtk_bin_get_child (GTK_BIN (data)); + str = flags_to_string (fclass, flags); + gtk_button_set_label (GTK_BUTTON (data), str); + g_free (str); + + popover = gtk_menu_button_get_popover (GTK_MENU_BUTTON (data)); + sw = gtk_bin_get_child (GTK_BIN (popover)); + viewport = gtk_bin_get_child (GTK_BIN (sw)); box = gtk_bin_get_child (GTK_BIN (viewport)); children = gtk_container_get_children (GTK_CONTAINER (box)); @@ -633,15 +657,7 @@ pointer_changed (GObject *object, GParamSpec *pspec, gpointer data) static gchar * object_label (GObject *obj, GParamSpec *pspec) { - const gchar *name; - - if (obj) - name = g_type_name (G_TYPE_FROM_INSTANCE (obj)); - else if (pspec) - name = g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)); - else - name = C_("type name", "Unknown"); - return g_strdup_printf (_("Object: %p (%s)"), obj, name); + return g_strdup_printf ("%p", obj); } static void @@ -877,7 +893,7 @@ property_editor (GObject *object, } else if (type == G_TYPE_PARAM_BOOLEAN) { - prop_edit = gtk_toggle_button_new_with_label (""); + prop_edit = gtk_check_button_new_with_label (""); g_object_connect_property (object, spec, G_CALLBACK (bool_changed), @@ -889,42 +905,24 @@ property_editor (GObject *object, else if (type == G_TYPE_PARAM_ENUM) { { - GtkWidget *box; GEnumClass *eclass; - GtkWidget *first; gint j; - prop_edit = gtk_scrolled_window_new (NULL, NULL); - g_object_set (prop_edit, - "expand", TRUE, - "hscrollbar-policy", GTK_POLICY_NEVER, - "vscrollbar-policy", GTK_POLICY_NEVER, - NULL); - box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - gtk_widget_show (box); - gtk_container_add (GTK_CONTAINER (prop_edit), box); + prop_edit = gtk_combo_box_text_new (); eclass = G_ENUM_CLASS (g_type_class_ref (spec->value_type)); j = 0; - first = NULL; while (j < eclass->n_values) { - GtkWidget *b; - - b = gtk_radio_button_new_with_label_from_widget ((GtkRadioButton*)first, eclass->values[j].value_name); - if (first == NULL) - first = b; - g_object_set_data (G_OBJECT (b), "index", GINT_TO_POINTER (j)); - gtk_widget_show (b); - gtk_container_add (GTK_CONTAINER (box), b); - connect_controller (G_OBJECT (b), "toggled", - object, spec, G_CALLBACK (enum_modified)); + gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (prop_edit), + eclass->values[j].value_name, + eclass->values[j].value_nick); ++j; } - if (j >= 10) - g_object_set (prop_edit, "vscrollbar-policy", GTK_POLICY_AUTOMATIC, NULL); + connect_controller (G_OBJECT (prop_edit), "changed", + object, spec, G_CALLBACK (enum_modified)); g_type_class_unref (eclass); @@ -937,18 +935,25 @@ property_editor (GObject *object, { { GtkWidget *box; + GtkWidget *sw; + GtkWidget *popover; GFlagsClass *fclass; gint j; - prop_edit = gtk_scrolled_window_new (NULL, NULL); - g_object_set (prop_edit, + popover = gtk_popover_new (NULL); + prop_edit = gtk_menu_button_new (); + gtk_menu_button_set_popover (GTK_MENU_BUTTON (prop_edit), popover); + + sw = gtk_scrolled_window_new (NULL, NULL); + gtk_container_add (GTK_CONTAINER (popover), sw); + g_object_set (sw, "expand", TRUE, "hscrollbar-policy", GTK_POLICY_NEVER, "vscrollbar-policy", GTK_POLICY_NEVER, NULL); box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_widget_show (box); - gtk_container_add (GTK_CONTAINER (prop_edit), box); + gtk_container_add (GTK_CONTAINER (sw), box); fclass = G_FLAGS_CLASS (g_type_class_ref (spec->value_type)); @@ -956,7 +961,7 @@ property_editor (GObject *object, { GtkWidget *b; - b = gtk_check_button_new_with_label (fclass->values[j].value_name); + b = gtk_check_button_new_with_label (fclass->values[j].value_nick); g_object_set_data (G_OBJECT (b), "index", GINT_TO_POINTER (j)); gtk_widget_show (b); gtk_container_add (GTK_CONTAINER (box), b); @@ -965,7 +970,7 @@ property_editor (GObject *object, } if (j >= 10) - g_object_set (prop_edit, "vscrollbar-policy", GTK_POLICY_AUTOMATIC, NULL); + g_object_set (sw, "vscrollbar-policy", GTK_POLICY_AUTOMATIC, NULL); g_type_class_unref (fclass); @@ -997,11 +1002,18 @@ property_editor (GObject *object, else if (type == G_TYPE_PARAM_OBJECT && g_type_is_a (G_PARAM_SPEC_VALUE_TYPE (spec), G_TYPE_LIST_MODEL)) { + GtkWidget *popover; GtkWidget *box; + GtkWidget *sw; GListModel *model; - prop_edit = gtk_scrolled_window_new (NULL, NULL); - g_object_set (prop_edit, + popover = gtk_popover_new (NULL); + prop_edit = gtk_menu_button_new (); + gtk_menu_button_set_popover (GTK_MENU_BUTTON (prop_edit), popover); + + sw = gtk_scrolled_window_new (NULL, NULL); + gtk_container_add (GTK_CONTAINER (popover), sw); + g_object_set (sw, "expand", TRUE, "hscrollbar-policy", GTK_POLICY_NEVER, "vscrollbar-policy", GTK_POLICY_NEVER, @@ -1017,7 +1029,7 @@ property_editor (GObject *object, gtk_list_box_bind_model (GTK_LIST_BOX (box), model, create_row, editor, NULL); g_object_unref (model); - gtk_container_add (GTK_CONTAINER (prop_edit), box); + gtk_container_add (GTK_CONTAINER (sw), box); } else if (type == G_TYPE_PARAM_OBJECT) { @@ -1042,7 +1054,7 @@ property_editor (GObject *object, else if (type == G_TYPE_PARAM_BOXED && G_PARAM_SPEC_VALUE_TYPE (spec) == GDK_TYPE_RGBA) { - prop_edit = gtk_color_chooser_widget_new (); + prop_edit = gtk_color_button_new (); gtk_color_chooser_set_use_alpha (GTK_COLOR_CHOOSER (prop_edit), TRUE); g_object_connect_property (object, spec, @@ -1055,7 +1067,7 @@ property_editor (GObject *object, else if (type == G_TYPE_PARAM_BOXED && G_PARAM_SPEC_VALUE_TYPE (spec) == PANGO_TYPE_FONT_DESCRIPTION) { - prop_edit = gtk_font_chooser_widget_new (); + prop_edit = gtk_font_button_new (); g_object_connect_property (object, spec, G_CALLBACK (font_changed), @@ -1104,9 +1116,8 @@ gtk_inspector_prop_editor_init (GtkInspectorPropEditor *editor) { editor->priv = gtk_inspector_prop_editor_get_instance_private (editor); g_object_set (editor, - "orientation", GTK_ORIENTATION_VERTICAL, + "orientation", GTK_ORIENTATION_HORIZONTAL, "spacing", 10, - "margin", 10, NULL); } @@ -1644,10 +1655,6 @@ constructed (GObject *object) spec = find_property (editor); - label = gtk_label_new (g_param_spec_get_nick (spec)); - gtk_widget_show (label); - gtk_container_add (GTK_CONTAINER (editor), label); - can_modify = ((spec->flags & G_PARAM_WRITABLE) != 0 && (spec->flags & G_PARAM_CONSTRUCT_ONLY) == 0); diff --git a/gtk/inspector/prop-list.c b/gtk/inspector/prop-list.c index 97edae10fc..3e5662223a 100644 --- a/gtk/inspector/prop-list.c +++ b/gtk/inspector/prop-list.c @@ -39,17 +39,8 @@ #include "gtkstack.h" #include "gtkeventcontrollerkey.h" #include "gtklayoutmanager.h" - -enum -{ - COLUMN_NAME, - COLUMN_VALUE, - COLUMN_TYPE, - COLUMN_DEFINED_AT, - COLUMN_TOOLTIP, - COLUMN_WRITABLE, - COLUMN_ATTRIBUTE -}; +#include "gtklistbox.h" +#include "gtksizegroup.h" enum { @@ -61,15 +52,15 @@ enum struct _GtkInspectorPropListPrivate { GObject *object; - GtkListStore *model; - GHashTable *prop_iters; gulong notify_handler_id; GtkInspectorObjectTree *object_tree; - GtkTreeViewColumn *name_column; - GtkTreeViewColumn *attribute_column; - GtkWidget *tree; GtkWidget *search_entry; GtkWidget *search_stack; + GtkWidget *list2; + GtkSizeGroup *names; + GtkSizeGroup *types; + GtkSizeGroup *values; + GtkSizeGroup *origins; }; G_DEFINE_TYPE_WITH_PRIVATE (GtkInspectorPropList, gtk_inspector_prop_list, GTK_TYPE_BOX) @@ -89,18 +80,22 @@ show_search_entry (GtkInspectorPropList *pl) pl->priv->search_entry); } +static gboolean +filter_func (GtkListBoxRow *row, + gpointer data) +{ + GtkInspectorPropList *pl = data; + GParamSpec *pspec = (GParamSpec *)g_object_get_data (G_OBJECT (row), "pspec"); + const char *text = gtk_editable_get_text (GTK_EDITABLE (pl->priv->search_entry)); + + return g_str_has_prefix (pspec->name, text); +} + static void gtk_inspector_prop_list_init (GtkInspectorPropList *pl) { pl->priv = gtk_inspector_prop_list_get_instance_private (pl); gtk_widget_init_template (GTK_WIDGET (pl)); - gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (pl->priv->model), - COLUMN_NAME, - GTK_SORT_ASCENDING); - pl->priv->prop_iters = g_hash_table_new_full (g_str_hash, - g_str_equal, - NULL, - (GDestroyNotify) gtk_tree_iter_free); } static void @@ -168,43 +163,6 @@ show_object (GtkInspectorPropEditor *editor, gtk_inspector_object_tree_activate_object (pl->priv->object_tree, object); } -static void -row_activated (GtkTreeView *tv, - GtkTreePath *path, - GtkTreeViewColumn *col, - GtkInspectorPropList *pl) -{ - GtkTreeIter iter; - GdkRectangle rect; - gchar *name; - GtkWidget *editor; - GtkWidget *popover; - - gtk_tree_model_get_iter (GTK_TREE_MODEL (pl->priv->model), &iter, path); - gtk_tree_model_get (GTK_TREE_MODEL (pl->priv->model), &iter, COLUMN_NAME, &name, -1); - gtk_tree_view_get_cell_area (tv, path, col, &rect); - gtk_tree_view_convert_bin_window_to_widget_coords (tv, rect.x, rect.y, &rect.x, &rect.y); - - popover = gtk_popover_new (GTK_WIDGET (tv)); - gtk_popover_set_pointing_to (GTK_POPOVER (popover), &rect); - - editor = gtk_inspector_prop_editor_new (pl->priv->object, name); - gtk_widget_show (editor); - - gtk_container_add (GTK_CONTAINER (popover), editor); - - if (gtk_inspector_prop_editor_should_expand (GTK_INSPECTOR_PROP_EDITOR (editor))) - gtk_widget_set_vexpand (popover, TRUE); - - g_signal_connect (editor, "show-object", G_CALLBACK (show_object), pl); - - gtk_popover_popup (GTK_POPOVER (popover)); - - g_signal_connect (popover, "unmap", G_CALLBACK (gtk_widget_destroy), NULL); - - g_free (name); -} - static void cleanup_object (GtkInspectorPropList *pl); static void @@ -213,7 +171,11 @@ finalize (GObject *object) GtkInspectorPropList *pl = GTK_INSPECTOR_PROP_LIST (object); cleanup_object (pl); - g_hash_table_unref (pl->priv->prop_iters); + + g_object_unref (pl->priv->names); + g_object_unref (pl->priv->types); + g_object_unref (pl->priv->values); + g_object_unref (pl->priv->origins); G_OBJECT_CLASS (gtk_inspector_prop_list_parent_class)->finalize (object); } @@ -225,18 +187,40 @@ constructed (GObject *object) pl->priv->search_stack = gtk_widget_get_parent (pl->priv->search_entry); - gtk_tree_view_set_search_entry (GTK_TREE_VIEW (pl->priv->tree), - GTK_EDITABLE (pl->priv->search_entry)); - g_signal_connect (pl->priv->search_entry, "stop-search", G_CALLBACK (search_close_clicked), pl); - gtk_search_entry_set_key_capture_widget (GTK_SEARCH_ENTRY (pl->priv->search_entry), - GTK_WIDGET (pl->priv->tree)); g_signal_connect_swapped (pl->priv->search_entry, "search-started", G_CALLBACK (show_search_entry), pl); + g_signal_connect_swapped (pl->priv->search_entry, "search-changed", + G_CALLBACK (gtk_list_box_invalidate_filter), pl->priv->list2); + + gtk_list_box_set_filter_func (GTK_LIST_BOX (pl->priv->list2), filter_func, pl, NULL); } +static void +map (GtkWidget *widget) +{ + GtkInspectorPropList *pl = GTK_INSPECTOR_PROP_LIST (widget); + GtkWidget *toplevel; + + GTK_WIDGET_CLASS (gtk_inspector_prop_list_parent_class)->map (widget); + + toplevel = gtk_widget_get_toplevel (widget); + gtk_search_entry_set_key_capture_widget (GTK_SEARCH_ENTRY (pl->priv->search_entry), toplevel); +} + +static void +unmap (GtkWidget *widget) +{ + GtkInspectorPropList *pl = GTK_INSPECTOR_PROP_LIST (widget); + + gtk_search_entry_set_key_capture_widget (GTK_SEARCH_ENTRY (pl->priv->search_entry), NULL); + + GTK_WIDGET_CLASS (gtk_inspector_prop_list_parent_class)->unmap (widget); +} + + static void gtk_inspector_prop_list_class_init (GtkInspectorPropListClass *klass) { @@ -248,6 +232,9 @@ gtk_inspector_prop_list_class_init (GtkInspectorPropListClass *klass) object_class->set_property = set_property; object_class->constructed = constructed; + widget_class->map = map; + widget_class->unmap = unmap; + g_object_class_install_property (object_class, PROP_OBJECT_TREE, g_param_spec_object ("object-tree", "Object Tree", "Object tree", GTK_TYPE_WIDGET, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); @@ -257,11 +244,11 @@ gtk_inspector_prop_list_class_init (GtkInspectorPropListClass *klass) GTK_TYPE_WIDGET, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/libgtk/inspector/prop-list.ui"); - gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorPropList, model); - 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_callback (widget_class, row_activated); - gtk_widget_class_bind_template_callback (widget_class, search_close_clicked); + gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorPropList, list2); + gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorPropList, names); + gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorPropList, types); + gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorPropList, values); + gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorPropList, origins); } /* Like g_strdup_value_contents, but keeps the type name separate */ @@ -366,16 +353,19 @@ strdup_value_contents (const GValue *value, } } -static void -gtk_inspector_prop_list_update_prop (GtkInspectorPropList *pl, - GtkTreeIter *iter, - GParamSpec *prop) +static GtkWidget * +gtk_inspector_prop_list_create_row (GtkInspectorPropList *pl, + GParamSpec *prop) { GValue gvalue = {0}; gchar *value; gchar *type; gchar *attribute = NULL; gboolean writable; + GtkWidget *row; + GtkWidget *box; + GtkWidget *label; + GtkWidget *widget; g_value_init (&gvalue, prop->value_type); g_object_get_property (pl->priv->object, prop->name, &gvalue); @@ -404,20 +394,42 @@ gtk_inspector_prop_list_update_prop (GtkInspectorPropList *pl, writable = ((prop->flags & G_PARAM_WRITABLE) != 0) && ((prop->flags & G_PARAM_CONSTRUCT_ONLY) == 0); - gtk_list_store_set (pl->priv->model, iter, - COLUMN_NAME, prop->name, - COLUMN_VALUE, value ? value : "", - COLUMN_TYPE, type ? type : "", - COLUMN_DEFINED_AT, g_type_name (prop->owner_type), - COLUMN_TOOLTIP, g_param_spec_get_blurb (prop), - COLUMN_WRITABLE, writable, - COLUMN_ATTRIBUTE, attribute ? attribute : "", - -1); + row = gtk_list_box_row_new (); + gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (row), FALSE); + g_object_set_data (G_OBJECT (row), "pspec", prop); + + box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_container_add (GTK_CONTAINER (row), box); + + label = gtk_label_new (prop->name); + gtk_widget_set_sensitive (label, writable); + gtk_label_set_xalign (GTK_LABEL (label), 0); + gtk_size_group_add_widget (pl->priv->names, label); + gtk_container_add (GTK_CONTAINER (box), label); + + label = gtk_label_new (type ? type : ""); + gtk_widget_set_sensitive (label, writable); + gtk_label_set_xalign (GTK_LABEL (label), 0); + gtk_size_group_add_widget (pl->priv->types, label); + gtk_container_add (GTK_CONTAINER (box), label); + + label = gtk_label_new (g_type_name (prop->owner_type)); + gtk_widget_set_sensitive (label, writable); + gtk_label_set_xalign (GTK_LABEL (label), 0); + gtk_size_group_add_widget (pl->priv->origins, label); + gtk_container_add (GTK_CONTAINER (box), label); + + widget = gtk_inspector_prop_editor_new (pl->priv->object, prop->name); + gtk_size_group_add_widget (pl->priv->values, widget); + gtk_container_add (GTK_CONTAINER (box), widget); + g_signal_connect (widget, "show-object", G_CALLBACK (show_object), pl); g_free (value); g_free (type); g_free (attribute); g_value_unset (&gvalue); + + return row; } static void @@ -425,14 +437,14 @@ gtk_inspector_prop_list_prop_changed_cb (GObject *pspec, GParamSpec *prop, GtkInspectorPropList *pl) { - GtkTreeIter *iter; - if (!pl->priv->object) return; +#if 0 iter = g_hash_table_lookup (pl->priv->prop_iters, prop->name); if (iter != NULL) gtk_inspector_prop_list_update_prop (pl, iter, prop); +#endif } static void @@ -444,20 +456,16 @@ cleanup_object (GtkInspectorPropList *pl) pl->priv->object = NULL; pl->priv->notify_handler_id = 0; - - g_hash_table_remove_all (pl->priv->prop_iters); - if (pl->priv->model) - gtk_list_store_clear (pl->priv->model); } gboolean gtk_inspector_prop_list_set_object (GtkInspectorPropList *pl, GObject *object) { - GtkTreeIter iter; GParamSpec **props; guint num_properties; guint i; + GtkWidget *w; if (!object) return FALSE; @@ -470,22 +478,23 @@ gtk_inspector_prop_list_set_object (GtkInspectorPropList *pl, gtk_editable_set_text (GTK_EDITABLE (pl->priv->search_entry), ""); gtk_stack_set_visible_child_name (GTK_STACK (pl->priv->search_stack), "title"); - gtk_tree_view_column_set_visible (pl->priv->attribute_column, GTK_IS_CELL_RENDERER (object)); props = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &num_properties); pl->priv->object = object; + while ((w = gtk_widget_get_first_child (pl->priv->list2)) != NULL) + gtk_widget_destroy (w); + for (i = 0; i < num_properties; i++) { GParamSpec *prop = props[i]; + GtkWidget *row; if (! (prop->flags & G_PARAM_READABLE)) continue; - gtk_list_store_append (pl->priv->model, &iter); - gtk_inspector_prop_list_update_prop (pl, &iter, prop); - - g_hash_table_insert (pl->priv->prop_iters, (gpointer) prop->name, gtk_tree_iter_copy (&iter)); + row = gtk_inspector_prop_list_create_row (pl, prop); + gtk_container_add (GTK_CONTAINER (pl->priv->list2), row); } g_free (props); diff --git a/gtk/inspector/prop-list.ui b/gtk/inspector/prop-list.ui index e59b239ebb..623ce5e3fa 100644 --- a/gtk/inspector/prop-list.ui +++ b/gtk/inspector/prop-list.ui @@ -1,106 +1,54 @@ + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + +