[gtk/constraint-grid-2: 4/10] constraint layout: go back to keeping constraints



commit 267227aa75c390a37d99c7e0925517597d7bee4e
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Jun 29 04:17:46 2019 +0000

    constraint layout: go back to keeping constraints
    
    We want to minimize changes to the solver, so
    keep the size constraints around and only update
    them when the size changes.

 gtk/gtkconstraintlayout.c | 171 ++++++++++++++++++++--------------------------
 1 file changed, 75 insertions(+), 96 deletions(-)
---
diff --git a/gtk/gtkconstraintlayout.c b/gtk/gtkconstraintlayout.c
index 094098d4eb..b3d0fe1d63 100644
--- a/gtk/gtkconstraintlayout.c
+++ b/gtk/gtkconstraintlayout.c
@@ -75,10 +75,21 @@
 #include "gtksizerequest.h"
 #include "gtkwidgetprivate.h"
 
+enum {
+  MIN_WIDTH,
+  MIN_HEIGHT,
+  NAT_WIDTH,
+  NAT_HEIGHT,
+  LAST_VALUE
+};
+
 struct _GtkConstraintLayoutChild
 {
   GtkLayoutChild parent_instance;
 
+  int values[LAST_VALUE];
+  GtkConstraintRef *constraints[LAST_VALUE];
+
   /* HashTable<static string, Variable>; a hash table of variables,
    * one for each attribute; we use these to query and suggest the
    * values for the solver. The string is static and does not need
@@ -691,6 +702,58 @@ layout_add_constraint (GtkConstraintLayout *self,
                                           gtk_constraint_get_weight (constraint));
 }
 
+static void
+update_child_constraint (GtkConstraintLayout       *self,
+                         GtkConstraintLayoutChild  *child_info,
+                         GtkWidget                 *child,
+                         int                        index,
+                         int                        value)
+{
+
+  GtkConstraintVariable *var;
+  int attr[LAST_VALUE] = {
+    GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
+    GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
+    GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
+    GTK_CONSTRAINT_ATTRIBUTE_HEIGHT
+  };
+  int relation[LAST_VALUE] = {
+    GTK_CONSTRAINT_RELATION_GE,
+    GTK_CONSTRAINT_RELATION_GE,
+    GTK_CONSTRAINT_RELATION_EQ,
+    GTK_CONSTRAINT_RELATION_EQ
+  };
+
+  if (child_info->values[index] != value)
+    {
+      child_info->values[index] = value;
+
+      if (child_info->constraints[index])
+        gtk_constraint_solver_remove_constraint (self->solver,
+                                                 child_info->constraints[index]);
+
+      var = get_child_attribute (self, child, attr[index]);
+
+      if (relation[index] == GTK_CONSTRAINT_RELATION_EQ)
+        {
+          gtk_constraint_variable_set_value (var, value);
+          child_info->constraints[index] =
+            gtk_constraint_solver_add_stay_variable (self->solver,
+                                                     var,
+                                                     GTK_CONSTRAINT_WEIGHT_MEDIUM);
+        }
+      else
+        {
+          child_info->constraints[index] =
+            gtk_constraint_solver_add_constraint (self->solver,
+                                                  var,
+                                                  relation[index],
+                                                  gtk_constraint_expression_new (value),
+                                                  GTK_CONSTRAINT_WEIGHT_REQUIRED);
+        }
+    }
+}
+
 static void
 gtk_constraint_layout_measure (GtkLayoutManager *manager,
                                GtkWidget        *widget,
@@ -704,7 +767,6 @@ gtk_constraint_layout_measure (GtkLayoutManager *manager,
   GtkConstraintLayout *self = GTK_CONSTRAINT_LAYOUT (manager);
   GtkConstraintVariable *size, *opposite_size;
   GtkConstraintSolver *solver;
-  GPtrArray *size_constraints;
   GtkWidget *child;
   int min_value;
   int nat_value;
@@ -713,8 +775,6 @@ gtk_constraint_layout_measure (GtkLayoutManager *manager,
   if (solver == NULL)
     return;
 
-  size_constraints = g_ptr_array_new ();
-
   /* We measure each child in the layout and impose restrictions on the
    * minimum and natural size, so we can solve the size of the overall
    * layout later on
@@ -723,8 +783,7 @@ gtk_constraint_layout_measure (GtkLayoutManager *manager,
        child != NULL;
        child = _gtk_widget_get_next_sibling (child))
     {
-      GtkConstraintVariable *width_var, *height_var;
-      GtkConstraintRef *constraint;
+      GtkConstraintLayoutChild *info;
       GtkRequisition min_req, nat_req;
 
       if (!gtk_widget_should_layout (child))
@@ -732,39 +791,12 @@ gtk_constraint_layout_measure (GtkLayoutManager *manager,
 
       gtk_widget_get_preferred_size (child, &min_req, &nat_req);
 
-      width_var = get_child_attribute (self, child, GTK_CONSTRAINT_ATTRIBUTE_WIDTH);
-
-      constraint =
-        gtk_constraint_solver_add_constraint (solver,
-                                              width_var,
-                                              GTK_CONSTRAINT_RELATION_GE,
-                                              gtk_constraint_expression_new (min_req.width),
-                                              GTK_CONSTRAINT_WEIGHT_REQUIRED);
-      g_ptr_array_add (size_constraints, constraint);
+      info = GTK_CONSTRAINT_LAYOUT_CHILD (gtk_layout_manager_get_layout_child (manager, child));
 
-      gtk_constraint_variable_set_value (width_var, nat_req.width);
-      constraint =
-        gtk_constraint_solver_add_stay_variable (solver,
-                                                 width_var,
-                                                 GTK_CONSTRAINT_WEIGHT_MEDIUM);
-      g_ptr_array_add (size_constraints, constraint);
-
-      height_var = get_child_attribute (self, child, GTK_CONSTRAINT_ATTRIBUTE_HEIGHT);
-
-      constraint =
-        gtk_constraint_solver_add_constraint (solver,
-                                              height_var,
-                                              GTK_CONSTRAINT_RELATION_GE,
-                                              gtk_constraint_expression_new (min_req.height),
-                                              GTK_CONSTRAINT_WEIGHT_REQUIRED);
-      g_ptr_array_add (size_constraints, constraint);
-
-      gtk_constraint_variable_set_value (height_var, nat_req.height);
-      constraint =
-        gtk_constraint_solver_add_stay_variable (solver,
-                                                 height_var,
-                                                 GTK_CONSTRAINT_WEIGHT_MEDIUM);
-      g_ptr_array_add (size_constraints, constraint);
+      update_child_constraint (self, info, child, MIN_WIDTH, min_req.width);
+      update_child_constraint (self, info, child, MIN_HEIGHT, min_req.height);
+      update_child_constraint (self, info, child, NAT_WIDTH, nat_req.width);
+      update_child_constraint (self, info, child, NAT_HEIGHT, nat_req.height);
     }
 
   switch (orientation)
@@ -815,15 +847,6 @@ gtk_constraint_layout_measure (GtkLayoutManager *manager,
                      min_value, nat_value,
                      for_size));
 
-  for (guint i = 0; i < size_constraints->len; i++)
-    {
-      GtkConstraintRef *ref = g_ptr_array_index (size_constraints, i);
-
-      gtk_constraint_solver_remove_constraint (solver, ref);
-    }
-
-  g_ptr_array_unref (size_constraints);
-
   if (minimum != NULL)
     *minimum = min_value;
 
@@ -843,7 +866,6 @@ gtk_constraint_layout_allocate (GtkLayoutManager *manager,
   GtkConstraintSolver *solver;
   GtkConstraintVariable *layout_top, *layout_height;
   GtkConstraintVariable *layout_left, *layout_width;
-  GPtrArray *size_constraints;
   GtkWidget *child;
 
   solver = gtk_constraint_layout_get_solver (self);
@@ -882,8 +904,6 @@ gtk_constraint_layout_allocate (GtkLayoutManager *manager,
                      gtk_constraint_variable_get_value (layout_width),
                      gtk_constraint_variable_get_value (layout_height)));
 
-  size_constraints = g_ptr_array_new ();
-
   /* We reset the constraints on the size of each child, so we are sure the
    * layout is up to date
    */
@@ -891,48 +911,20 @@ gtk_constraint_layout_allocate (GtkLayoutManager *manager,
        child != NULL;
        child = _gtk_widget_get_next_sibling (child))
     {
-      GtkConstraintVariable *width_var, *height_var;
       GtkRequisition min_req, nat_req;
-      GtkConstraintRef *constraint;
+      GtkConstraintLayoutChild *info;
 
       if (!gtk_widget_should_layout (child))
         continue;
 
       gtk_widget_get_preferred_size (child, &min_req, &nat_req);
 
-      width_var = get_child_attribute (self, child, GTK_CONSTRAINT_ATTRIBUTE_WIDTH);
+      info = GTK_CONSTRAINT_LAYOUT_CHILD (gtk_layout_manager_get_layout_child (manager, child));
 
-      constraint =
-        gtk_constraint_solver_add_constraint (solver,
-                                              width_var,
-                                              GTK_CONSTRAINT_RELATION_GE,
-                                              gtk_constraint_expression_new (min_req.width),
-                                              GTK_CONSTRAINT_WEIGHT_REQUIRED);
-      g_ptr_array_add (size_constraints, constraint);
-
-      gtk_constraint_variable_set_value (width_var, nat_req.width);
-      constraint =
-        gtk_constraint_solver_add_stay_variable (solver,
-                                                 width_var,
-                                                 GTK_CONSTRAINT_WEIGHT_MEDIUM);
-      g_ptr_array_add (size_constraints, constraint);
-
-      height_var = get_child_attribute (self, child, GTK_CONSTRAINT_ATTRIBUTE_HEIGHT);
-
-      constraint =
-        gtk_constraint_solver_add_constraint (solver,
-                                              height_var,
-                                              GTK_CONSTRAINT_RELATION_GE,
-                                              gtk_constraint_expression_new (min_req.height),
-                                              GTK_CONSTRAINT_WEIGHT_REQUIRED);
-      g_ptr_array_add (size_constraints, constraint);
-
-      gtk_constraint_variable_set_value (height_var, nat_req.height);
-      constraint =
-        gtk_constraint_solver_add_stay_variable (solver,
-                                                 height_var,
-                                                 GTK_CONSTRAINT_WEIGHT_MEDIUM);
-      g_ptr_array_add (size_constraints, constraint);
+      update_child_constraint (self, info, child, MIN_WIDTH, min_req.width);
+      update_child_constraint (self, info, child, MIN_HEIGHT, min_req.height);
+      update_child_constraint (self, info, child, NAT_WIDTH, nat_req.width);
+      update_child_constraint (self, info, child, NAT_HEIGHT, nat_req.height);
     }
 
   for (child = _gtk_widget_get_first_child (widget);
@@ -1000,16 +992,6 @@ gtk_constraint_layout_allocate (GtkLayoutManager *manager,
     }
 #endif
 
-  /* The constraints on the children sizes can be removed now */
-  for (guint i = 0; i < size_constraints->len; i++)
-    {
-      GtkConstraintRef *ref = g_ptr_array_index (size_constraints, i);
-
-      gtk_constraint_solver_remove_constraint (solver, ref);
-    }
-
-  g_ptr_array_unref (size_constraints);
-
   /* The allocation stay constraints are not needed any more */
   gtk_constraint_solver_remove_constraint (solver, stay_w);
   gtk_constraint_solver_remove_constraint (solver, stay_h);
@@ -1342,13 +1324,10 @@ add_child_constraints (GtkConstraintLayout     *self,
                        GtkConstraintVariable  **cols,
                        GPtrArray               *refs)
 {
-  GtkConstraintLayoutChild *info;
   GtkConstraintVariable *var;
   GtkConstraintVariable *var1;
   GtkConstraintRef *ref;
 
-  info = GTK_CONSTRAINT_LAYOUT_CHILD (gtk_layout_manager_get_layout_child (GTK_LAYOUT_MANAGER (self), 
child->child));
-
   var = get_child_attribute (self, child->child, GTK_CONSTRAINT_ATTRIBUTE_LEFT);
   var1 = cols[child->left];
 


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