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.
This commit is contained in:
Matthias Clasen
2019-06-29 04:17:46 +00:00
parent c88e7c180d
commit b224df8109

View File

@@ -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
@@ -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;