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:
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user