[gtk/wip/otte/listview: 87/157] inspector: Make the recorder node list use a ListView
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/listview: 87/157] inspector: Make the recorder node list use a ListView
- Date: Fri, 13 Dec 2019 07:01:01 +0000 (UTC)
commit d7822e312e7721e8cc14895f4e3f1b5d01e75f4b
Author: Benjamin Otte <otte redhat com>
Date: Mon Oct 14 06:50:40 2019 +0200
inspector: Make the recorder node list use a ListView
It's quite a bit faster now, but the code is also a bit more awkward.
Pain points:
- GtkTreeListModel cannot be created in UI files because it needs
a CreateModelFunc.
Using a signal for this doesn't work because autoexpand wants to
expand the model before the signal handler is connected.
- The list item factory usage is still awkward. It's bearable here
because the list items are very simple, but still.
gtk/gtktreeexpander.c | 1 +
gtk/inspector/recorder.c | 119 +++++++++++++++++++++++++++-------------------
gtk/inspector/recorder.ui | 5 +-
3 files changed, 72 insertions(+), 53 deletions(-)
---
diff --git a/gtk/gtktreeexpander.c b/gtk/gtktreeexpander.c
index 868261f8cc..b86b48da8e 100644
--- a/gtk/gtktreeexpander.c
+++ b/gtk/gtktreeexpander.c
@@ -186,6 +186,7 @@ gtk_tree_expander_clear_list_row (GtkTreeExpander *self)
return;
g_signal_handler_disconnect (self->list_row, self->notify_handler);
+ self->notify_handler = 0;
g_clear_object (&self->list_row);
}
diff --git a/gtk/inspector/recorder.c b/gtk/inspector/recorder.c
index a605179188..778d97007f 100644
--- a/gtk/inspector/recorder.c
+++ b/gtk/inspector/recorder.c
@@ -21,11 +21,14 @@
#include <gtk/gtkbox.h>
#include <gtk/gtkfilechooserdialog.h>
+#include <gtk/gtkfunctionslistitemfactory.h>
#include <gtk/gtklabel.h>
#include <gtk/gtklistbox.h>
+#include <gtk/gtklistview.h>
#include <gtk/gtkmessagedialog.h>
#include <gtk/gtkpicture.h>
#include <gtk/gtkpopover.h>
+#include <gtk/gtksingleselection.h>
#include <gtk/gtktogglebutton.h>
#include <gtk/gtktreeexpander.h>
#include <gtk/gtktreelistmodel.h>
@@ -50,6 +53,8 @@ struct _GtkInspectorRecorderPrivate
{
GListModel *recordings;
GtkTreeListModel *render_node_model;
+ GListStore *render_node_root_model;
+ GtkSingleSelection *render_node_selection;
GtkWidget *recordings_list;
GtkWidget *render_node_view;
@@ -294,40 +299,56 @@ node_name (GskRenderNode *node)
}
}
-static GtkWidget *
-create_widget_for_render_node (gpointer row_item,
- gpointer unused)
+static void
+setup_widget_for_render_node (GtkListItem *list_item,
+ gpointer unused)
+{
+ GtkWidget *expander, *box, *child;
+
+ /* expander */
+ expander = gtk_tree_expander_new ();
+ gtk_list_item_set_child (list_item, expander);
+
+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3);
+ gtk_tree_expander_set_child (GTK_TREE_EXPANDER (expander), box);
+
+ /* icon */
+ child = gtk_image_new ();
+ gtk_container_add (GTK_CONTAINER (box), child);
+
+ /* name */
+ child = gtk_label_new (NULL);
+ gtk_container_add (GTK_CONTAINER (box), child);
+}
+
+static void
+bind_widget_for_render_node (GtkListItem *list_item,
+ gpointer unused)
{
GdkPaintable *paintable;
GskRenderNode *node;
- GtkWidget *row, *expander, *box, *child;
+ GtkTreeListRow *row_item;
+ GtkWidget *expander, *box, *child;
char *name;
+ row_item = gtk_list_item_get_item (list_item);
paintable = gtk_tree_list_row_get_item (row_item);
node = gtk_render_node_paintable_get_render_node (GTK_RENDER_NODE_PAINTABLE (paintable));
- row = gtk_list_box_row_new ();
/* expander */
- expander = gtk_tree_expander_new ();
+ expander = gtk_list_item_get_child (list_item);
gtk_tree_expander_set_list_row (GTK_TREE_EXPANDER (expander), row_item);
- gtk_container_add (GTK_CONTAINER (row), expander);
-
- box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3);
- gtk_tree_expander_set_child (GTK_TREE_EXPANDER (expander), box);
+ box = gtk_tree_expander_get_child (GTK_TREE_EXPANDER (expander));
/* icon */
- child = gtk_image_new_from_paintable (paintable);
- gtk_container_add (GTK_CONTAINER (box), child);
+ child = gtk_widget_get_first_child (box);
+ gtk_image_set_from_paintable (GTK_IMAGE (child), paintable);
/* name */
name = node_name (node);
- child = gtk_label_new (name);
+ child = gtk_widget_get_last_child (box);
+ gtk_label_set_label (GTK_LABEL (child), name);
g_free (name);
- gtk_container_add (GTK_CONTAINER (box), child);
-
- g_object_unref (paintable);
-
- return row;
}
static void
@@ -343,11 +364,8 @@ recordings_list_row_selected (GtkListBox *box,
else
recording = NULL;
- g_clear_object (&priv->render_node_model);
-
if (GTK_INSPECTOR_IS_RENDER_RECORDING (recording))
{
- GListStore *root_model;
graphene_rect_t bounds;
GskRenderNode *node;
GdkPaintable *paintable;
@@ -357,14 +375,10 @@ recordings_list_row_selected (GtkListBox *box,
paintable = gtk_render_node_paintable_new (node, &bounds);
gtk_picture_set_paintable (GTK_PICTURE (priv->render_node_view), paintable);
- root_model = g_list_store_new (GDK_TYPE_PAINTABLE);
- g_list_store_append (root_model, paintable);
- priv->render_node_model = gtk_tree_list_model_new (FALSE,
- G_LIST_MODEL (root_model),
- TRUE,
- create_list_model_for_render_node_paintable,
- NULL, NULL);
- g_object_unref (root_model);
+ g_list_store_splice (priv->render_node_root_model,
+ 0, g_list_model_get_n_items (G_LIST_MODEL (priv->render_node_root_model)),
+ (gpointer[1]) { paintable },
+ 1);
g_object_unref (paintable);
g_print ("%u render nodes\n", g_list_model_get_n_items (G_LIST_MODEL (priv->render_node_model)));
@@ -372,14 +386,9 @@ recordings_list_row_selected (GtkListBox *box,
else
{
gtk_picture_set_paintable (GTK_PICTURE (priv->render_node_view), NULL);
+ g_list_store_remove_all (priv->render_node_root_model);
}
-
- gtk_list_box_bind_model (GTK_LIST_BOX (priv->render_node_list),
- G_LIST_MODEL (priv->render_node_model),
- create_widget_for_render_node,
- NULL, NULL);
-
if (recording)
g_object_unref (recording);
}
@@ -896,20 +905,16 @@ get_selected_node (GtkInspectorRecorder *recorder)
{
GtkInspectorRecorderPrivate *priv = gtk_inspector_recorder_get_instance_private (recorder);
GtkTreeListRow *row_item;
- GtkListBoxRow *row;
GdkPaintable *paintable;
GskRenderNode *node;
- row = gtk_list_box_get_selected_row (GTK_LIST_BOX (priv->render_node_list));
- if (row == NULL)
+ row_item = gtk_single_selection_get_selected_item (priv->render_node_selection);
+ if (row_item == NULL)
return NULL;
- row_item = g_list_model_get_item (G_LIST_MODEL (priv->render_node_model),
- gtk_list_box_row_get_index (row));
paintable = gtk_tree_list_row_get_item (row_item);
node = gtk_render_node_paintable_get_render_node (GTK_RENDER_NODE_PAINTABLE (paintable));
g_object_unref (paintable);
- g_object_unref (row_item);
return node;
}
@@ -924,14 +929,10 @@ render_node_list_selection_changed (GtkListBox *list,
GdkPaintable *paintable;
GtkTreeListRow *row_item;
- if (row == NULL)
- {
- gtk_widget_set_sensitive (priv->render_node_save_button, FALSE);
- return;
- }
+ row_item = gtk_single_selection_get_selected_item (priv->render_node_selection);
+ if (row_item == NULL)
+ return;
- row_item = g_list_model_get_item (G_LIST_MODEL (priv->render_node_model),
- gtk_list_box_row_get_index (row));
paintable = gtk_tree_list_row_get_item (row_item);
gtk_widget_set_sensitive (priv->render_node_save_button, TRUE);
@@ -940,7 +941,6 @@ render_node_list_selection_changed (GtkListBox *list,
populate_render_node_properties (GTK_LIST_STORE (priv->render_node_properties), node);
g_object_unref (paintable);
- g_object_unref (row_item);
}
static void
@@ -1210,6 +1210,8 @@ gtk_inspector_recorder_dispose (GObject *object)
GtkInspectorRecorderPrivate *priv = gtk_inspector_recorder_get_instance_private (recorder);
g_clear_object (&priv->render_node_model);
+ g_clear_object (&priv->render_node_root_model);
+ g_clear_object (&priv->render_node_selection);
G_OBJECT_CLASS (gtk_inspector_recorder_parent_class)->dispose (object);
}
@@ -1250,7 +1252,6 @@ gtk_inspector_recorder_class_init (GtkInspectorRecorderClass *klass)
gtk_widget_class_bind_template_callback (widget_class, recordings_clear_all);
gtk_widget_class_bind_template_callback (widget_class, recordings_list_row_selected);
- gtk_widget_class_bind_template_callback (widget_class, render_node_list_selection_changed);
gtk_widget_class_bind_template_callback (widget_class, render_node_save);
gtk_widget_class_bind_template_callback (widget_class, node_property_activated);
}
@@ -1259,6 +1260,7 @@ static void
gtk_inspector_recorder_init (GtkInspectorRecorder *recorder)
{
GtkInspectorRecorderPrivate *priv = gtk_inspector_recorder_get_instance_private (recorder);
+ GtkListItemFactory *factory;
gtk_widget_init_template (GTK_WIDGET (recorder));
@@ -1268,6 +1270,23 @@ gtk_inspector_recorder_init (GtkInspectorRecorder *recorder)
recorder,
NULL);
+ priv->render_node_root_model = g_list_store_new (GDK_TYPE_PAINTABLE);
+ priv->render_node_model = gtk_tree_list_model_new (FALSE,
+ G_LIST_MODEL (priv->render_node_root_model),
+ TRUE,
+ create_list_model_for_render_node_paintable,
+ NULL, NULL);
+ priv->render_node_selection = gtk_single_selection_new (G_LIST_MODEL (priv->render_node_model));
+ g_signal_connect (priv->render_node_selection, "notify::selected-item", G_CALLBACK
(render_node_list_selection_changed), recorder);
+
+ factory = gtk_functions_list_item_factory_new (setup_widget_for_render_node,
+ bind_widget_for_render_node,
+ NULL, NULL);
+ gtk_list_view_set_factory (GTK_LIST_VIEW (priv->render_node_list), factory);
+ g_object_unref (factory);
+ gtk_list_view_set_model (GTK_LIST_VIEW (priv->render_node_list),
+ G_LIST_MODEL (priv->render_node_selection));
+
priv->render_node_properties = GTK_TREE_MODEL (gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_BOOLEAN, GDK_TYPE_TEXTURE));
gtk_tree_view_set_model (GTK_TREE_VIEW (priv->node_property_tree), priv->render_node_properties);
g_object_unref (priv->render_node_properties);
diff --git a/gtk/inspector/recorder.ui b/gtk/inspector/recorder.ui
index e0f5e74c30..4230a0890d 100644
--- a/gtk/inspector/recorder.ui
+++ b/gtk/inspector/recorder.ui
@@ -73,15 +73,14 @@
<object class="GtkFrame">
<child>
<object class="GtkScrolledWindow">
- <property name="hscrollbar-policy">never</property>
<property name="propagate-natural-width">1</property>
<style>
<class name="sidebar"/>
</style>
<child>
- <object class="GtkListBox" id="render_node_list">
+ <object class="GtkListView" id="render_node_list">
<property name="vexpand">1</property>
- <signal name="row-selected" handler="render_node_list_selection_changed"/>
+ <property name="hexpand">1</property>
</object>
</child>
</object>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]