diff options
Diffstat (limited to 'gtk/gtkconstraintlayout.c')
-rw-r--r-- | gtk/gtkconstraintlayout.c | 585 |
1 files changed, 527 insertions, 58 deletions
diff --git a/gtk/gtkconstraintlayout.c b/gtk/gtkconstraintlayout.c index b5375c596a..405d080164 100644 --- a/gtk/gtkconstraintlayout.c +++ b/gtk/gtkconstraintlayout.c @@ -72,16 +72,38 @@ #include "gtksizerequest.h" #include "gtkwidgetprivate.h" -struct _GtkConstraintLayoutChild +typedef struct { - GtkLayoutChild parent_instance; - /* 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 * to be freed. */ GHashTable *bound_attributes; +} ConstraintSolverChildData; + +struct _GtkConstraintLayoutChild +{ + GtkLayoutChild parent_instance; + + ConstraintSolverChildData data; +}; + +struct _GtkConstraintGuide +{ + GObject parent_instance; + + int min_width; + int min_height; + int nat_width; + int nat_height; + + GtkConstraintLayout *layout; + + ConstraintSolverChildData data; + + GtkConstraintRef *width_constraint[2]; + GtkConstraintRef *height_constraint[2]; }; struct _GtkConstraintLayout @@ -105,6 +127,9 @@ struct _GtkConstraintLayout * parent widget, using the public API objects. */ GHashTable *constraints; + + /* HashSet<GtkConstraintGuide> */ + GHashTable *guides; }; G_DEFINE_TYPE (GtkConstraintLayoutChild, gtk_constraint_layout_child, GTK_TYPE_LAYOUT_CHILD) @@ -154,44 +179,20 @@ get_attribute_name (GtkConstraintAttribute attr) } static GtkConstraintVariable * -get_child_attribute (GtkConstraintLayoutChild *self, - GtkConstraintSolver *solver, - GtkWidget *widget, - GtkConstraintAttribute attr) +get_attribute (ConstraintSolverChildData *self, + GtkConstraintSolver *solver, + const char *prefix, + GtkConstraintAttribute attr) { - GtkTextDirection text_dir; const char *attr_name; GtkConstraintVariable *res; - g_assert (attr != GTK_CONSTRAINT_ATTRIBUTE_NONE); - - /* Resolve the start/end attributes depending on the layout's text direction */ - if (attr == GTK_CONSTRAINT_ATTRIBUTE_START) - { - text_dir = gtk_widget_get_direction (widget); - if (text_dir == GTK_TEXT_DIR_RTL) - attr = GTK_CONSTRAINT_ATTRIBUTE_RIGHT; - else - attr = GTK_CONSTRAINT_ATTRIBUTE_LEFT; - } - else if (attr == GTK_CONSTRAINT_ATTRIBUTE_END) - { - text_dir = gtk_widget_get_direction (widget); - if (text_dir == GTK_TEXT_DIR_RTL) - attr = GTK_CONSTRAINT_ATTRIBUTE_LEFT; - else - attr = GTK_CONSTRAINT_ATTRIBUTE_RIGHT; - } - attr_name = get_attribute_name (attr); res = g_hash_table_lookup (self->bound_attributes, attr_name); if (res != NULL) return res; - res = gtk_constraint_solver_create_variable (solver, - gtk_widget_get_name (widget), - attr_name, - 0.0); + res = gtk_constraint_solver_create_variable (solver, prefix, attr_name, 0.0); g_hash_table_insert (self->bound_attributes, (gpointer) attr_name, res); /* Some attributes are really constraints computed from other @@ -207,8 +208,8 @@ get_child_attribute (GtkConstraintLayoutChild *self, GtkConstraintVariable *left, *width; GtkConstraintExpression *expr; - left = get_child_attribute (self, solver, widget, GTK_CONSTRAINT_ATTRIBUTE_LEFT); - width = get_child_attribute (self, solver, widget, GTK_CONSTRAINT_ATTRIBUTE_WIDTH); + left = get_attribute (self, solver, prefix, GTK_CONSTRAINT_ATTRIBUTE_LEFT); + width = get_attribute (self, solver, prefix, GTK_CONSTRAINT_ATTRIBUTE_WIDTH); gtk_constraint_expression_builder_init (&builder, solver); gtk_constraint_expression_builder_term (&builder, left); @@ -229,8 +230,8 @@ get_child_attribute (GtkConstraintLayoutChild *self, GtkConstraintVariable *top, *height; GtkConstraintExpression *expr; - top = get_child_attribute (self, solver, widget, GTK_CONSTRAINT_ATTRIBUTE_TOP); - height = get_child_attribute (self, solver, widget, GTK_CONSTRAINT_ATTRIBUTE_HEIGHT); + top = get_attribute (self, solver, prefix, GTK_CONSTRAINT_ATTRIBUTE_TOP); + height = get_attribute (self, solver, prefix, GTK_CONSTRAINT_ATTRIBUTE_HEIGHT); gtk_constraint_expression_builder_init (&builder, solver); gtk_constraint_expression_builder_term (&builder, top); @@ -251,8 +252,8 @@ get_child_attribute (GtkConstraintLayoutChild *self, GtkConstraintVariable *left, *width; GtkConstraintExpression *expr; - left = get_child_attribute (self, solver, widget, GTK_CONSTRAINT_ATTRIBUTE_LEFT); - width = get_child_attribute (self, solver, widget, GTK_CONSTRAINT_ATTRIBUTE_WIDTH); + left = get_attribute (self, solver, prefix, GTK_CONSTRAINT_ATTRIBUTE_LEFT); + width = get_attribute (self, solver, prefix, GTK_CONSTRAINT_ATTRIBUTE_WIDTH); gtk_constraint_expression_builder_init (&builder, solver); gtk_constraint_expression_builder_term (&builder, width); @@ -275,8 +276,8 @@ get_child_attribute (GtkConstraintLayoutChild *self, GtkConstraintVariable *top, *height; GtkConstraintExpression *expr; - top = get_child_attribute (self, solver, widget, GTK_CONSTRAINT_ATTRIBUTE_TOP); - height = get_child_attribute (self, solver, widget, GTK_CONSTRAINT_ATTRIBUTE_HEIGHT); + top = get_attribute (self, solver, prefix, GTK_CONSTRAINT_ATTRIBUTE_TOP); + height = get_attribute (self, solver, prefix, GTK_CONSTRAINT_ATTRIBUTE_HEIGHT); gtk_constraint_expression_builder_init (&builder, solver); gtk_constraint_expression_builder_term (&builder, height); @@ -325,12 +326,81 @@ get_child_attribute (GtkConstraintLayoutChild *self, return res; } +static GtkConstraintAttribute +resolve_direction (GtkConstraintAttribute attr, + GtkWidget *widget) +{ + GtkTextDirection text_dir; + + /* Resolve the start/end attributes depending on the layout's text direction */ + + if (widget) + text_dir = gtk_widget_get_direction (widget); + else + text_dir = GTK_TEXT_DIR_LTR; + + if (attr == GTK_CONSTRAINT_ATTRIBUTE_START) + { + if (text_dir == GTK_TEXT_DIR_RTL) + attr = GTK_CONSTRAINT_ATTRIBUTE_RIGHT; + else + attr = GTK_CONSTRAINT_ATTRIBUTE_LEFT; + } + else if (attr == GTK_CONSTRAINT_ATTRIBUTE_END) + { + if (text_dir == GTK_TEXT_DIR_RTL) + attr = GTK_CONSTRAINT_ATTRIBUTE_LEFT; + else + attr = GTK_CONSTRAINT_ATTRIBUTE_RIGHT; + } + + return attr; +} + +static GtkConstraintVariable * +get_child_attribute (GtkConstraintLayoutChild *self, + GtkConstraintSolver *solver, + GtkWidget *widget, + GtkConstraintAttribute attr) +{ + const char *prefix = gtk_widget_get_name (widget); + + attr = resolve_direction (attr, widget); + + return get_attribute (&self->data, solver, prefix, attr); +} + +static GtkConstraintVariable * +get_guide_attribute (GtkConstraintLayout *layout, + GtkConstraintGuide *guide, + GtkConstraintSolver *solver, + GtkConstraintAttribute attr) +{ + GtkLayoutManager *manager = GTK_LAYOUT_MANAGER (layout); + GtkWidget *widget = gtk_layout_manager_get_widget (manager); + + attr = resolve_direction (attr, widget); + + return get_attribute (&guide->data, solver, "guide", attr); +} + +static void +clear_constraint_solver_data (GtkConstraintSolver *solver, + ConstraintSolverChildData *data) +{ + g_clear_pointer (&data->bound_attributes, g_hash_table_unref); +} + static void gtk_constraint_layout_child_finalize (GObject *gobject) { GtkConstraintLayoutChild *self = GTK_CONSTRAINT_LAYOUT_CHILD (gobject); + GtkLayoutManager *manager; + GtkConstraintSolver *solver; - g_clear_pointer (&self->bound_attributes, g_hash_table_unref); + manager = gtk_layout_child_get_layout_manager (GTK_LAYOUT_CHILD (self)); + solver = gtk_constraint_layout_get_solver (GTK_CONSTRAINT_LAYOUT (manager)); + clear_constraint_solver_data (solver, &self->data); G_OBJECT_CLASS (gtk_constraint_layout_child_parent_class)->finalize (gobject); } @@ -346,7 +416,7 @@ gtk_constraint_layout_child_class_init (GtkConstraintLayoutChildClass *klass) static void gtk_constraint_layout_child_init (GtkConstraintLayoutChild *self) { - self->bound_attributes = + self->data.bound_attributes = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) gtk_constraint_variable_unref); @@ -361,6 +431,7 @@ gtk_constraint_layout_finalize (GObject *gobject) g_clear_pointer (&self->bound_attributes, g_hash_table_unref); g_clear_pointer (&self->constraints, g_hash_table_unref); + g_clear_pointer (&self->guides, g_hash_table_unref); G_OBJECT_CLASS (gtk_constraint_layout_parent_class)->finalize (gobject); } @@ -553,7 +624,7 @@ layout_add_constraint (GtkConstraintLayout *self, GtkConstraintExpression *expr; GtkConstraintSolver *solver; GtkConstraintAttribute attr; - GtkWidget *target_widget, *source_widget; + GtkConstraintTarget *target, *source; GtkWidget *layout_widget; if (gtk_constraint_is_attached (constraint)) @@ -572,25 +643,33 @@ layout_add_constraint (GtkConstraintLayout *self, return; attr = gtk_constraint_get_target_attribute (constraint); - target_widget = gtk_constraint_get_target_widget (constraint); - if (target_widget == NULL || target_widget == layout_widget) + target = gtk_constraint_get_target (constraint); + if (target == NULL || target == GTK_CONSTRAINT_TARGET (layout_widget)) { /* A NULL target widget is assumed to be referring to the layout itself */ target_attr = get_layout_attribute (self, layout_widget, attr); } - else if (gtk_widget_get_parent (target_widget) == layout_widget) + else if (GTK_IS_WIDGET (target) && + gtk_widget_get_parent (GTK_WIDGET (target)) == layout_widget) { GtkLayoutChild *child_info; - child_info = gtk_layout_manager_get_layout_child (GTK_LAYOUT_MANAGER (self), target_widget); + child_info = gtk_layout_manager_get_layout_child (GTK_LAYOUT_MANAGER (self), GTK_WIDGET (target)); target_attr = get_child_attribute (GTK_CONSTRAINT_LAYOUT_CHILD (child_info), solver, - target_widget, + GTK_WIDGET (target), attr); } + else if (GTK_IS_CONSTRAINT_GUIDE (target)) + { + GtkConstraintGuide *guide; + + guide = (GtkConstraintGuide*)g_hash_table_lookup (self->guides, target); + target_attr = get_guide_attribute (self, guide, solver, attr); + } else { - g_critical ("Unknown target widget '%s'", gtk_widget_get_name (target_widget)); + g_critical ("Unknown target widget '%p'", target); target_attr = NULL; } @@ -598,7 +677,7 @@ layout_add_constraint (GtkConstraintLayout *self, return; attr = gtk_constraint_get_source_attribute (constraint); - source_widget = gtk_constraint_get_source_widget (constraint); + source = gtk_constraint_get_source (constraint); /* The constraint is a constant */ if (attr == GTK_CONSTRAINT_ATTRIBUTE_NONE) @@ -607,23 +686,31 @@ layout_add_constraint (GtkConstraintLayout *self, } else { - if (source_widget == NULL || source_widget == layout_widget) + if (source == NULL || source == GTK_CONSTRAINT_TARGET (layout_widget)) { source_attr = get_layout_attribute (self, layout_widget, attr); } - else if (gtk_widget_get_parent (source_widget) == layout_widget) + else if (GTK_IS_WIDGET (source) && + gtk_widget_get_parent (GTK_WIDGET (source)) == layout_widget) { GtkLayoutChild *child_info; - child_info = gtk_layout_manager_get_layout_child (GTK_LAYOUT_MANAGER (self), source_widget); + child_info = gtk_layout_manager_get_layout_child (GTK_LAYOUT_MANAGER (self), GTK_WIDGET (source)); source_attr = get_child_attribute (GTK_CONSTRAINT_LAYOUT_CHILD (child_info), solver, - source_widget, + GTK_WIDGET (source), attr); } + else if (GTK_IS_CONSTRAINT_GUIDE (source)) + { + GtkConstraintGuide *guide; + + guide = (GtkConstraintGuide*)g_hash_table_lookup (self->guides, source); + source_attr = get_guide_attribute (self, guide, solver, attr); + } else { - g_critical ("Unknown source widget '%s'", gtk_widget_get_name (source_widget)); + g_critical ("Unknown source widget '%p'", source); source_attr = NULL; return; } @@ -871,7 +958,6 @@ gtk_constraint_layout_allocate (GtkLayoutManager *manager, gtk_widget_get_preferred_size (child, &min_req, &nat_req); - width_var = get_child_attribute (child_info, solver, child, GTK_CONSTRAINT_ATTRIBUTE_WIDTH); @@ -972,6 +1058,11 @@ gtk_constraint_layout_allocate (GtkLayoutManager *manager, gtk_constraint_solver_remove_constraint (solver, stay_l); } +static void update_min_width (GtkConstraintGuide *guide); +static void update_nat_width (GtkConstraintGuide *guide); +static void update_min_height (GtkConstraintGuide *guide); +static void update_nat_height (GtkConstraintGuide *guide); + static void gtk_constraint_layout_root (GtkLayoutManager *manager) { @@ -991,9 +1082,18 @@ gtk_constraint_layout_root (GtkLayoutManager *manager) while (g_hash_table_iter_next (&iter, &key, NULL)) { GtkConstraint *constraint = key; - layout_add_constraint (self, constraint); } + + g_hash_table_iter_init (&iter, self->guides); + while (g_hash_table_iter_next (&iter, &key, NULL)) + { + GtkConstraintGuide *guide = key; + update_min_width (guide); + update_nat_width (guide); + update_min_height (guide); + update_nat_height (guide); + } } static void @@ -1011,7 +1111,6 @@ gtk_constraint_layout_unroot (GtkLayoutManager *manager) while (g_hash_table_iter_next (&iter, &key, NULL)) { GtkConstraint *constraint = key; - gtk_constraint_detach (constraint); } @@ -1047,6 +1146,11 @@ gtk_constraint_layout_init (GtkConstraintLayout *self) g_hash_table_new_full (NULL, NULL, (GDestroyNotify) g_object_unref, NULL); + + self->guides = + g_hash_table_new_full (NULL, NULL, + (GDestroyNotify) g_object_unref, + NULL); } /** @@ -1116,3 +1220,368 @@ gtk_constraint_layout_remove_constraint (GtkConstraintLayout *manager, gtk_layout_manager_layout_changed (GTK_LAYOUT_MANAGER (manager)); } + +static void +gtk_constraint_guide_constraint_target_iface_init (GtkConstraintTargetInterface *iface) +{ +} + +struct _GtkConstraintGuideClass { + GObjectClass parent_class; +}; + +enum { + PROP_MIN_WIDTH = 1, + PROP_MIN_HEIGHT, + PROP_NAT_WIDTH, + PROP_NAT_HEIGHT, + LAST_PROP +}; + +static GParamSpec *guide_props[LAST_PROP]; + +G_DEFINE_TYPE_WITH_CODE (GtkConstraintGuide, gtk_constraint_guide, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (GTK_TYPE_CONSTRAINT_TARGET, + gtk_constraint_guide_constraint_target_iface_init)) + +static void +gtk_constraint_guide_init (GtkConstraintGuide *guide) +{ + guide->data.bound_attributes = + g_hash_table_new_full (g_str_hash, g_str_equal, + NULL, + (GDestroyNotify) gtk_constraint_variable_unref); +} + +static void +update_min_width (GtkConstraintGuide *guide) +{ + GtkConstraintSolver *solver; + GtkConstraintVariable *var; + + if (!guide->layout) + return; + + solver = guide->layout->solver; + + if (!solver) + return; + + if (guide->width_constraint[0] != NULL) + gtk_constraint_solver_remove_constraint (solver, guide->width_constraint[0]); + + var = get_guide_attribute (guide->layout, guide, solver, GTK_CONSTRAINT_ATTRIBUTE_WIDTH); + guide->width_constraint[0] = + gtk_constraint_solver_add_constraint (solver, + var, + GTK_CONSTRAINT_RELATION_GE, + gtk_constraint_expression_new (guide->min_width), + GTK_CONSTRAINT_WEIGHT_REQUIRED); +} + +static void +update_min_height (GtkConstraintGuide *guide) +{ + GtkConstraintSolver *solver; + GtkConstraintVariable *var; + + if (!guide->layout) + return; + + solver = guide->layout->solver; + + if (!solver) + return; + + if (guide->height_constraint[0] != NULL) + gtk_constraint_solver_remove_constraint (solver, guide->height_constraint[0]); + + var = get_guide_attribute (guide->layout, guide, solver, GTK_CONSTRAINT_ATTRIBUTE_HEIGHT); + guide->height_constraint[0] = + gtk_constraint_solver_add_constraint (solver, + var, + GTK_CONSTRAINT_RELATION_GE, + gtk_constraint_expression_new (guide->min_height), + GTK_CONSTRAINT_WEIGHT_REQUIRED); +} + +static void +update_nat_width (GtkConstraintGuide *guide) +{ + GtkConstraintSolver *solver; + GtkConstraintVariable *var; + + if (!guide->layout) + return; + + solver = guide->layout->solver; + + if (!solver) + return; + + if (guide->width_constraint[1] != NULL) + gtk_constraint_solver_remove_constraint (solver, guide->width_constraint[1]); + + var = get_guide_attribute (guide->layout, guide, solver, GTK_CONSTRAINT_ATTRIBUTE_WIDTH); + guide->width_constraint[1] = + gtk_constraint_solver_add_constraint (solver, + var, + GTK_CONSTRAINT_RELATION_EQ, + gtk_constraint_expression_new (guide->nat_width), + GTK_CONSTRAINT_WEIGHT_MEDIUM); +} + +static void +update_nat_height (GtkConstraintGuide *guide) +{ + GtkConstraintSolver *solver; + GtkConstraintVariable *var; + + if (!guide->layout) + return; + + solver = guide->layout->solver; + + if (!solver) + return; + + if (guide->height_constraint[1] != NULL) + gtk_constraint_solver_remove_constraint (solver, guide->height_constraint[1]); + + var = get_guide_attribute (guide->layout, guide, solver, GTK_CONSTRAINT_ATTRIBUTE_HEIGHT); + guide->height_constraint[1] = + gtk_constraint_solver_add_constraint (solver, + var, + GTK_CONSTRAINT_RELATION_EQ, + gtk_constraint_expression_new (guide->nat_height), + GTK_CONSTRAINT_WEIGHT_MEDIUM); +} + +static void +set_min_width (GtkConstraintGuide *guide, + int min_width) +{ + if (guide->min_width == min_width) + return; + + guide->min_width = min_width; + g_object_notify_by_pspec (G_OBJECT (guide), + guide_props[PROP_MIN_WIDTH]); + + update_min_width (guide); +} + +static void +set_min_height (GtkConstraintGuide *guide, + int min_height) +{ + if (guide->min_height == min_height) + return; + + guide->min_height = min_height; + g_object_notify_by_pspec (G_OBJECT (guide), + guide_props[PROP_MIN_HEIGHT]); + + update_min_height (guide); +} + +static void +set_nat_width (GtkConstraintGuide *guide, + int nat_width) +{ + if (guide->nat_width == nat_width) + return; + + guide->nat_width = nat_width; + g_object_notify_by_pspec (G_OBJECT (guide), + guide_props[PROP_NAT_WIDTH]); + + update_nat_width (guide); +} +static void +set_nat_height (GtkConstraintGuide *guide, + int nat_height) +{ + if (guide->nat_height == nat_height) + return; + + guide->nat_height = nat_height; + g_object_notify_by_pspec (G_OBJECT (guide), + guide_props[PROP_NAT_HEIGHT]); + + update_nat_height (guide); +} + +static void +gtk_constraint_guide_set_property (GObject *gobject, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GtkConstraintGuide *self = GTK_CONSTRAINT_GUIDE (gobject); + + switch (prop_id) + { + case PROP_MIN_WIDTH: + set_min_width (self, g_value_get_int (value)); + break; + + case PROP_MIN_HEIGHT: + set_min_height (self, g_value_get_int (value)); + break; + + case PROP_NAT_WIDTH: + set_nat_width (self, g_value_get_int (value)); + break; + + case PROP_NAT_HEIGHT: + set_nat_height (self, g_value_get_int (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + break; + } +} + +static void +gtk_constraint_guide_get_property (GObject *gobject, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GtkConstraintGuide *self = GTK_CONSTRAINT_GUIDE (gobject); + + switch (prop_id) + { + case PROP_MIN_WIDTH: + g_value_set_int (value, self->min_width); + break; + + case PROP_MIN_HEIGHT: + g_value_set_int (value, self->min_height); + break; + + case PROP_NAT_WIDTH: + g_value_set_int (value, self->nat_width); + break; + + case PROP_NAT_HEIGHT: + g_value_set_int (value, self->nat_height); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + break; + } +} + +static void +gtk_constraint_guide_finalize (GObject *object) +{ + GtkConstraintGuide *self = GTK_CONSTRAINT_GUIDE (object); + GtkConstraintSolver *solver; + + if (self->layout) + { + solver = gtk_constraint_layout_get_solver (self->layout); + clear_constraint_solver_data (solver, &self->data); + } + + G_OBJECT_CLASS (gtk_constraint_guide_parent_class)->finalize (object); +} + +static void +gtk_constraint_guide_class_init (GtkConstraintGuideClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->finalize = gtk_constraint_guide_finalize; + object_class->set_property = gtk_constraint_guide_set_property; + object_class->get_property = gtk_constraint_guide_get_property; + + guide_props[PROP_MIN_WIDTH] = + g_param_spec_int ("min-width", + "Minimum width", + "Minimum width", + 0, G_MAXINT, 0, + G_PARAM_READWRITE| + G_PARAM_EXPLICIT_NOTIFY); + guide_props[PROP_MIN_HEIGHT] = + g_param_spec_int ("min-height", + "Minimum height", + "Minimum height", + 0, G_MAXINT, 0, + G_PARAM_READWRITE| + G_PARAM_EXPLICIT_NOTIFY); + guide_props[PROP_NAT_WIDTH] = + g_param_spec_int ("nat-width", + "Natural width", + "Natural width", + 0, G_MAXINT, 0, + G_PARAM_READWRITE| + G_PARAM_EXPLICIT_NOTIFY); + guide_props[PROP_NAT_HEIGHT] = + g_param_spec_int ("nat-height", + "Natural height", + "Natural height", + 0, G_MAXINT, 0, + G_PARAM_READWRITE| + G_PARAM_EXPLICIT_NOTIFY); + + g_object_class_install_properties (object_class, LAST_PROP, guide_props); +} + +/** + * gtk_constraint_layout_add_guide: + * @layout: a #GtkConstraintLayout + * @guide: (transfer full): a #GtkConstraintGuide object + * + * Adds a guide to @layout. A guide can be used as + * the source or target of constraints, like a widget, + * but it is not visible. + * + * The @manager acquires the ownership of @guide after calling + * this function. + */ +void +gtk_constraint_layout_add_guide (GtkConstraintLayout *layout, + GtkConstraintGuide *guide) +{ + g_return_if_fail (GTK_IS_CONSTRAINT_LAYOUT (layout)); + g_return_if_fail (GTK_IS_CONSTRAINT_GUIDE (guide)); + g_return_if_fail (guide->layout == NULL); + + guide->layout = layout; + + g_hash_table_add (layout->guides, guide); + + gtk_layout_manager_layout_changed (GTK_LAYOUT_MANAGER (layout)); +} + +/** + * gtk_constraint_layout_remove_guide: + * @layout: a #GtkConstraintManager + * @guide: a #GtkConstraintGuide object + * + * Removes @guide from the layout manager, + * so that it no longer influences the layout. + */ +void +gtk_constraint_layout_remove_guide (GtkConstraintLayout *layout, + GtkConstraintGuide *guide) +{ + GtkConstraintSolver *solver; + + g_return_if_fail (GTK_IS_CONSTRAINT_LAYOUT (layout)); + g_return_if_fail (GTK_IS_CONSTRAINT_GUIDE (guide)); + g_return_if_fail (guide->layout == layout); + + solver = gtk_constraint_layout_get_solver (guide->layout); + clear_constraint_solver_data (solver, &guide->data); + guide->layout = NULL; + + g_hash_table_remove (layout->guides, guide); + + gtk_layout_manager_layout_changed (GTK_LAYOUT_MANAGER (layout)); +} |