From b224df8109b381d873e805a749e28937408ebf7f Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 29 Jun 2019 04:17:46 +0000 Subject: [PATCH] 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 | 114 +++++++++++++++++++++++--------------- 1 file changed, 69 insertions(+), 45 deletions(-) diff --git a/gtk/gtkconstraintlayout.c b/gtk/gtkconstraintlayout.c index 4339630c21..32fdb4f142 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; 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 @@ -687,6 +698,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, @@ -700,7 +763,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; @@ -709,7 +771,6 @@ gtk_constraint_layout_measure (GtkLayoutManager *manager, if (solver == NULL) return; - size_constraints = g_ptr_array_new (); gtk_constraint_solver_freeze (solver); /* We measure each child in the layout and impose restrictions on the @@ -720,8 +781,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)) @@ -729,39 +789,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); + 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); } gtk_constraint_solver_thaw (solver); @@ -814,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;