[gtk/constraint-list-model: 14/18] constraint editor: Use the list models



commit a442e6e8de796b655a948f4153c898aecec760da
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Jul 1 20:15:55 2019 -0400

    constraint editor: Use the list models
    
    Instead of handrolling our own list models,
    use the ones provided by GtkConstraintLayout.

 demos/constraint-editor/constraint-editor-window.c |   7 +-
 demos/constraint-editor/constraint-editor.c        |   3 +-
 demos/constraint-editor/constraint-view.c          | 240 ++++++++++-----------
 demos/constraint-editor/guide-editor.c             |   3 +-
 4 files changed, 121 insertions(+), 132 deletions(-)
---
diff --git a/demos/constraint-editor/constraint-editor-window.c 
b/demos/constraint-editor/constraint-editor-window.c
index a8fa33464d..debbd7da51 100644
--- a/demos/constraint-editor/constraint-editor-window.c
+++ b/demos/constraint-editor/constraint-editor-window.c
@@ -295,13 +295,16 @@ create_widget_func (gpointer item,
   ConstraintEditorWindow *win = user_data;
   const char *name;
   GtkWidget *row, *box, *label, *button;
+  char *str;
 
   name = (const char *)g_object_get_data (G_OBJECT (item), "name");
 
   row = gtk_list_box_row_new ();
-  g_object_set_data (G_OBJECT (row), "item", item);
+  g_object_set_data_full (G_OBJECT (row), "item", g_object_ref (item), g_object_unref);
   box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-  label = gtk_label_new (name);
+  str = g_strdup_printf ("%s %p", name, item);
+  label = gtk_label_new (str);
+  g_free (str);
   g_object_set (label,
                 "margin", 10,
                 NULL);
diff --git a/demos/constraint-editor/constraint-editor.c b/demos/constraint-editor/constraint-editor.c
index 5a85b35ecf..95d854ee9c 100644
--- a/demos/constraint-editor/constraint-editor.c
+++ b/demos/constraint-editor/constraint-editor.c
@@ -395,7 +395,8 @@ constraint_editor_constructed (GObject *object)
       double constant;
 
       nick = (char *)g_object_get_data (G_OBJECT (editor->constraint), "name");
-      gtk_editable_set_text (GTK_EDITABLE (editor->name), nick);
+      if (nick)
+        gtk_editable_set_text (GTK_EDITABLE (editor->name), nick);
 
       target = gtk_constraint_get_target (editor->constraint);
       nick = get_target_name (target);
diff --git a/demos/constraint-editor/constraint-view.c b/demos/constraint-editor/constraint-view.c
index 7a4b094df5..8a050dbf8b 100644
--- a/demos/constraint-editor/constraint-view.c
+++ b/demos/constraint-editor/constraint-view.c
@@ -21,7 +21,7 @@ struct _ConstraintView
 {
   GtkWidget parent;
 
-  GListStore *store;
+  GListModel *model;
 
   GtkWidget *drag_widget;
 };
@@ -37,7 +37,7 @@ constraint_view_dispose (GObject *object)
   while ((child = gtk_widget_get_first_child (GTK_WIDGET (view))) != NULL)
     gtk_widget_unparent (child);
 
-  g_clear_object (&view->store);
+  g_clear_object (&view->model);
 
   G_OBJECT_CLASS (constraint_view_parent_class)->dispose (object);
 }
@@ -70,30 +70,38 @@ update_weak_position (ConstraintView *self,
                                                constraint);
       g_object_set_data (G_OBJECT (child), "x-constraint", NULL);
     }
-  constraint = gtk_constraint_new_constant (child,
-                                            GTK_CONSTRAINT_ATTRIBUTE_CENTER_X,
-                                            GTK_CONSTRAINT_RELATION_EQ,
-                                            x,
-                                            GTK_CONSTRAINT_STRENGTH_WEAK);
-  gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
-                                        constraint);
-  g_object_set_data (G_OBJECT (child), "x-constraint", constraint);
+  if (x != -100)
+    {
+      constraint = gtk_constraint_new_constant (child,
+                                                GTK_CONSTRAINT_ATTRIBUTE_CENTER_X,
+                                                GTK_CONSTRAINT_RELATION_EQ,
+                                                x,
+                                                GTK_CONSTRAINT_STRENGTH_WEAK);
+      g_object_set_data (G_OBJECT (constraint), "internal", "yes");
+      gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
+                                            constraint);
+      g_object_set_data (G_OBJECT (child), "x-constraint", constraint);
+    }
 
   constraint = (GtkConstraint *)g_object_get_data (G_OBJECT (child), "y-constraint");
   if (constraint)
     {
       gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager),
-                                               constraint);
+                                                   constraint);
       g_object_set_data (G_OBJECT (child), "y-constraint", NULL);
     }
-  constraint = gtk_constraint_new_constant (child,
-                                            GTK_CONSTRAINT_ATTRIBUTE_CENTER_Y,
-                                            GTK_CONSTRAINT_RELATION_EQ,
-                                            y,
-                                            GTK_CONSTRAINT_STRENGTH_WEAK);
-  gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
-                                        constraint);
-  g_object_set_data (G_OBJECT (child), "y-constraint", constraint);
+  if (y != -100)
+    {
+      constraint = gtk_constraint_new_constant (child,
+                                                GTK_CONSTRAINT_ATTRIBUTE_CENTER_Y,
+                                                GTK_CONSTRAINT_RELATION_EQ,
+                                                y,
+                                                GTK_CONSTRAINT_STRENGTH_WEAK);
+      g_object_set_data (G_OBJECT (constraint), "internal", "yes");
+      gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
+                                            constraint);
+      g_object_set_data (G_OBJECT (child), "y-constraint", constraint);
+    }
 }
 
 static void
@@ -141,15 +149,48 @@ drag_end (GtkGestureDrag *drag,
   self->drag_widget = NULL;
 }
 
+static gboolean
+omit_internal (gpointer item, gpointer user_data)
+{
+  if (g_object_get_data (G_OBJECT (item), "internal"))
+    return FALSE;
+
+  return TRUE;
+}
+
 static void
 constraint_view_init (ConstraintView *self)
 {
+  GtkLayoutManager *manager;
   GtkEventController *controller;
+  GListStore *list;
+  GListModel *all_children;
+  GListModel *all_constraints;
+  GListModel *guides;
+  GListModel *children;
+  GListModel *constraints;
+
+  manager = gtk_constraint_layout_new ();
+  gtk_widget_set_layout_manager (GTK_WIDGET (self), manager);
+
+  all_children = gtk_widget_observe_children (GTK_WIDGET (self));
+  all_constraints = gtk_constraint_layout_observe_constraints (GTK_CONSTRAINT_LAYOUT (manager));
+  guides = gtk_constraint_layout_observe_guides (GTK_CONSTRAINT_LAYOUT (manager));
+  constraints = (GListModel *)gtk_filter_list_model_new (all_constraints, omit_internal, NULL, NULL);
+  children = (GListModel *)gtk_filter_list_model_new (all_children, omit_internal, NULL, NULL);
+
+  list = g_list_store_new (G_TYPE_LIST_MODEL);
+  g_list_store_append (list, children);
+  g_list_store_append (list, guides);
+  g_list_store_append (list, constraints);
+  self->model = G_LIST_MODEL (gtk_flatten_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (list)));
+  g_object_unref (children);
+  g_object_unref (guides);
+  g_object_unref (constraints);
+  g_object_unref (all_children);
+  g_object_unref (all_constraints);
+  g_object_unref (list);
 
-  gtk_widget_set_layout_manager (GTK_WIDGET (self),
-                                 gtk_constraint_layout_new ());
-
-  self->store = g_list_store_new (G_TYPE_OBJECT);
 
   controller = (GtkEventController *)gtk_gesture_drag_new ();
   g_signal_connect (controller, "drag-begin", G_CALLBACK (drag_begin), self);
@@ -179,101 +220,66 @@ constraint_view_add_child (ConstraintView *view,
   gtk_widget_set_parent (frame, GTK_WIDGET (view));
 
   update_weak_position (view, frame, 100, 100);
-
-  g_list_store_append (view->store, frame);
 }
 
 void
 constraint_view_remove_child (ConstraintView *view,
                               GtkWidget      *child)
 {
-  int i;
-
+  update_weak_position (view, child, -100, -100);
   gtk_widget_unparent (child);
-
-  for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (view->store)); i++)
-    {
-      if (g_list_model_get_item (G_LIST_MODEL (view->store), i) == (GObject*)child)
-        {
-          g_list_store_remove (view->store, i);
-          break;
-        }
-    }
 }
 
 void
 constraint_view_add_guide (ConstraintView *view,
                            GtkConstraintGuide *guide)
 {
-  GtkLayoutManager *manager;
+  GtkConstraintLayout *layout;
   GtkWidget *frame;
   GtkWidget *label;
   const char *name;
   GtkConstraint *constraint;
+  struct {
+    const char *name;
+    GtkConstraintAttribute attr;
+  } names[] = {
+    { "left-constraint", GTK_CONSTRAINT_ATTRIBUTE_LEFT },
+    { "top-constraint", GTK_CONSTRAINT_ATTRIBUTE_TOP },
+    { "width-constraint", GTK_CONSTRAINT_ATTRIBUTE_WIDTH },
+    { "height-constraint", GTK_CONSTRAINT_ATTRIBUTE_HEIGHT },
+  };
+  int i;
 
   name = (const char *)g_object_get_data (G_OBJECT (guide), "name");
 
   label = gtk_label_new (name);
   frame = gtk_frame_new (NULL);
   gtk_style_context_add_class (gtk_widget_get_style_context (frame), "guide");
-  g_object_set_data_full (G_OBJECT (frame), "name", g_strdup (name), g_free);
+  g_object_set_data (G_OBJECT (frame), "internal", "yes");
   gtk_container_add (GTK_CONTAINER (frame), label);
   gtk_widget_insert_after (frame, GTK_WIDGET (view), NULL);
 
   g_object_set_data (G_OBJECT (guide), "frame", frame);
   g_object_set_data (G_OBJECT (guide), "label", label);
 
-  manager = gtk_widget_get_layout_manager (GTK_WIDGET (view));
-  gtk_constraint_layout_add_guide (GTK_CONSTRAINT_LAYOUT (manager),
-                                   g_object_ref (guide));
-
-  constraint = gtk_constraint_new (frame,
-                                   GTK_CONSTRAINT_ATTRIBUTE_LEFT,
-                                   GTK_CONSTRAINT_RELATION_EQ,
-                                   guide,
-                                   GTK_CONSTRAINT_ATTRIBUTE_LEFT,
-                                   1.0, 0.0,
-                                   GTK_CONSTRAINT_STRENGTH_REQUIRED);
-  gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
-                                        constraint);
-  g_object_set_data (G_OBJECT (guide), "left-constraint", constraint);
-
-  constraint = gtk_constraint_new (frame,
-                                   GTK_CONSTRAINT_ATTRIBUTE_TOP,
-                                   GTK_CONSTRAINT_RELATION_EQ,
-                                   guide,
-                                   GTK_CONSTRAINT_ATTRIBUTE_TOP,
-                                   1.0, 0.0,
-                                   GTK_CONSTRAINT_STRENGTH_REQUIRED);
-  gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
-                                        constraint);
-  g_object_set_data (G_OBJECT (guide), "top-constraint", constraint);
-
-  constraint = gtk_constraint_new (frame,
-                                   GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
-                                   GTK_CONSTRAINT_RELATION_EQ,
-                                   guide,
-                                   GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
-                                   1.0, 0.0,
-                                   GTK_CONSTRAINT_STRENGTH_REQUIRED);
-  gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
-                                        constraint);
-  g_object_set_data (G_OBJECT (guide), "width-constraint", constraint);
-
-  constraint = gtk_constraint_new (frame,
-                                   GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
-                                   GTK_CONSTRAINT_RELATION_EQ,
-                                   guide,
-                                   GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
-                                   1.0, 0.0,
-                                   GTK_CONSTRAINT_STRENGTH_REQUIRED);
-  gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
-                                        constraint);
-  g_object_set_data (G_OBJECT (guide), "height-constraint", constraint);
+  layout = GTK_CONSTRAINT_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (view)));
+  gtk_constraint_layout_add_guide (layout, g_object_ref (guide));
 
-  update_weak_position (view, frame, 150, 150);
+  for (i = 0; i < G_N_ELEMENTS (names); i++)
+    {
+      constraint = gtk_constraint_new (frame,
+                                       names[i].attr,
+                                       GTK_CONSTRAINT_RELATION_EQ,
+                                       guide,
+                                       names[i].attr,
+                                       1.0, 0.0,
+                                       GTK_CONSTRAINT_STRENGTH_REQUIRED);
+      g_object_set_data (G_OBJECT (constraint), "internal", "yes");
+      gtk_constraint_layout_add_constraint (layout, constraint);
+      g_object_set_data (G_OBJECT (guide), names[i].name, constraint);
+    }
 
-  g_list_store_append (view->store, guide);
+  update_weak_position (view, frame, 150, 150);
 }
 
 void
@@ -287,12 +293,11 @@ constraint_view_guide_changed (ConstraintView     *view,
   name = (const char *)g_object_get_data (G_OBJECT (guide), "name");
   label = (GtkWidget *)g_object_get_data (G_OBJECT (guide), "label");
   gtk_label_set_label (GTK_LABEL (label), name);
-
-  for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (view->store)); i++)
+  for (i = 0; i < g_list_model_get_n_items (view->model); i++)
     {
-      if (g_list_model_get_item (G_LIST_MODEL (view->store), i) == (GObject*)guide)
+      if (g_list_model_get_item (view->model, i) == (GObject*)guide)
         {
-          g_list_model_items_changed (G_LIST_MODEL (view->store), i, 1, 1);
+          g_list_model_items_changed (view->model, i, 1, 1);
           break;
         }
     }
@@ -302,40 +307,30 @@ void
 constraint_view_remove_guide (ConstraintView     *view,
                               GtkConstraintGuide *guide)
 {
-  GtkLayoutManager *manager;
+  GtkConstraintLayout *layout;
   GtkWidget *frame;
   GtkConstraint *constraint;
+  const char *names[] = {
+    "left-constraint",
+    "top-constraint",
+    "width-constraint",
+    "height-constraint"
+  };
   int i;
 
-  manager = gtk_widget_get_layout_manager (GTK_WIDGET (view));
+  layout = GTK_CONSTRAINT_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (view)));
 
-  constraint = (GtkConstraint*)g_object_get_data (G_OBJECT (guide), "left-constraint");
-  gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager),
-                                           constraint);
-  constraint = (GtkConstraint*)g_object_get_data (G_OBJECT (guide), "top-constraint");
-  gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager),
-                                           constraint);
-  constraint = (GtkConstraint*)g_object_get_data (G_OBJECT (guide), "width-constraint");
-  gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager),
-                                           constraint);
-  constraint = (GtkConstraint*)g_object_get_data (G_OBJECT (guide), "height-constraint");
-  gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager),
-                                           constraint);
+  for (i = 0; i < G_N_ELEMENTS (names); i++)
+    {
+      constraint = (GtkConstraint*)g_object_get_data (G_OBJECT (guide), names[i]);
+      gtk_constraint_layout_remove_constraint (layout, constraint);
+    }
 
   frame = (GtkWidget *)g_object_get_data (G_OBJECT (guide), "frame");
+  update_weak_position (view, frame, -100, -100);
   gtk_widget_unparent (frame);
 
-  gtk_constraint_layout_remove_guide (GTK_CONSTRAINT_LAYOUT (manager),
-                                      guide);
-
-  for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (view->store)); i++)
-    {
-      if (g_list_model_get_item (G_LIST_MODEL (view->store), i) == (GObject*)guide)
-        {
-          g_list_store_remove (view->store, i);
-          break;
-        }
-    }
+  gtk_constraint_layout_remove_guide (layout, guide);
 }
 
 void
@@ -347,8 +342,6 @@ constraint_view_add_constraint (ConstraintView *view,
   manager = gtk_widget_get_layout_manager (GTK_WIDGET (view));
   gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
                                         g_object_ref (constraint));
-
-  g_list_store_append (view->store, constraint);
 }
 
 void
@@ -356,23 +349,14 @@ constraint_view_remove_constraint (ConstraintView *view,
                                    GtkConstraint  *constraint)
 {
   GtkLayoutManager *manager;
-  int i;
 
   manager = gtk_widget_get_layout_manager (GTK_WIDGET (view));
   gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager),
                                            constraint);
-  for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (view->store)); i++)
-    {
-      if (g_list_model_get_item (G_LIST_MODEL (view->store), i) == (GObject*)constraint)
-        {
-          g_list_store_remove (view->store, i);
-          break;
-        }
-    }
 }
 
 GListModel *
 constraint_view_get_model (ConstraintView *view)
 {
-  return G_LIST_MODEL (view->store);
+  return view->model;
 }
diff --git a/demos/constraint-editor/guide-editor.c b/demos/constraint-editor/guide-editor.c
index 39bd08a157..947274f2ad 100644
--- a/demos/constraint-editor/guide-editor.c
+++ b/demos/constraint-editor/guide-editor.c
@@ -239,7 +239,8 @@ guide_editor_constructed (GObject *object)
       int w, h;
 
       nick = (char *)g_object_get_data (G_OBJECT (editor->guide), "name");
-      gtk_editable_set_text (GTK_EDITABLE (editor->name), nick);
+      if (nick)
+        gtk_editable_set_text (GTK_EDITABLE (editor->name), nick);
 
       gtk_constraint_guide_get_min_size (editor->guide, &w, &h);
       gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->min_width), w);


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