constraint layout: Provide list models

Provide list models for the constraints and guides,
so we can show them in the inspector, and use them
in e.g. the constraints editor.
This commit is contained in:
Matthias Clasen 2019-07-01 20:14:26 -04:00
parent b2f15a622d
commit 274c47e5ba
3 changed files with 137 additions and 0 deletions

View File

@ -7338,6 +7338,10 @@ gtk_constraint_layout_remove_guide
gtk_constraint_layout_add_constraints_from_description
gtk_constraint_layout_add_constraints_from_descriptionv
<SUBSECTION>
gtk_constraint_layout_observe_constraints
gtk_constraint_layout_observe_guides
<SUBSECTION Standard>
GTK_TYPE_CONSTRAINT_LAYOUT
gtk_constraint_layout_get_type

View File

@ -253,6 +253,9 @@ struct _GtkConstraintLayout
/* HashSet<GtkConstraintGuide> */
GHashTable *guides;
GListStore *constraints_observer;
GListStore *guides_observer;
};
G_DEFINE_TYPE (GtkConstraintLayoutChild, gtk_constraint_layout_child, GTK_TYPE_LAYOUT_CHILD)
@ -534,6 +537,19 @@ gtk_constraint_layout_finalize (GObject *gobject)
{
GtkConstraintLayout *self = GTK_CONSTRAINT_LAYOUT (gobject);
if (self->constraints_observer)
{
g_list_store_remove_all (self->constraints_observer);
g_object_remove_weak_pointer ((GObject *)self->constraints_observer,
(gpointer *)&self->constraints_observer);
}
if (self->guides_observer)
{
g_list_store_remove_all (self->guides_observer);
g_object_remove_weak_pointer ((GObject *)self->guides_observer,
(gpointer *)&self->guides_observer);
}
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);
@ -1709,10 +1725,32 @@ gtk_constraint_layout_add_constraint (GtkConstraintLayout *layout,
layout_add_constraint (layout, constraint);
g_hash_table_add (layout->constraints, constraint);
if (layout->constraints_observer)
g_list_store_append (layout->constraints_observer, constraint);
gtk_layout_manager_layout_changed (GTK_LAYOUT_MANAGER (layout));
}
static void
list_store_remove_item (GListStore *store,
gpointer item)
{
int n_items;
int i;
n_items = g_list_model_get_n_items (G_LIST_MODEL (store));
for (i = 0; i < n_items; i++)
{
gpointer *model_item = g_list_model_get_item (G_LIST_MODEL (store), i);
g_object_unref (model_item);
if (item == model_item)
{
g_list_store_remove (store, i);
break;
}
}
}
/**
* gtk_constraint_layout_remove_constraint:
* @layout: a #GtkConstraintLayout
@ -1731,6 +1769,8 @@ gtk_constraint_layout_remove_constraint (GtkConstraintLayout *layout,
gtk_constraint_detach (constraint);
g_hash_table_remove (layout->constraints, constraint);
if (layout->constraints_observer)
list_store_remove_item (layout->constraints_observer, constraint);
gtk_layout_manager_layout_changed (GTK_LAYOUT_MANAGER (layout));
}
@ -1757,6 +1797,8 @@ gtk_constraint_layout_remove_all_constraints (GtkConstraintLayout *layout)
gtk_constraint_detach (constraint);
g_hash_table_iter_remove (&iter);
}
if (layout->constraints_observer)
g_list_store_remove_all (layout->constraints_observer);
gtk_layout_manager_layout_changed (GTK_LAYOUT_MANAGER (layout));
}
@ -1783,6 +1825,8 @@ gtk_constraint_layout_add_guide (GtkConstraintLayout *layout,
gtk_constraint_guide_set_layout (guide, layout);
g_hash_table_add (layout->guides, guide);
if (layout->guides_observer)
g_list_store_append (layout->guides_observer, guide);
gtk_layout_manager_layout_changed (GTK_LAYOUT_MANAGER (layout));
}
@ -1807,6 +1851,8 @@ gtk_constraint_layout_remove_guide (GtkConstraintLayout *layout,
gtk_constraint_guide_set_layout (guide, NULL);
g_hash_table_remove (layout->guides, guide);
if (layout->guides_observer)
list_store_remove_item (layout->guides_observer, guide);
gtk_layout_manager_layout_changed (GTK_LAYOUT_MANAGER (layout));
}
@ -2026,6 +2072,8 @@ gtk_constraint_layout_add_constraints_from_descriptionv (GtkConstraintLayout *la
layout_add_constraint (layout, constraint);
g_hash_table_add (layout->constraints, constraint);
if (layout->constraints_observer)
g_list_store_append (layout->constraints_observer, constraint);
res = g_list_prepend (res, constraint);
}
@ -2116,3 +2164,83 @@ gtk_constraint_layout_add_constraints_from_description (GtkConstraintLayout *lay
return res;
}
/**
* gtk_constraint_layout_observe_constraints:
* @layout: a #GtkConstraintLayout
*
* Returns a #GListModel to track the constraints that are
* part of @layout.
*
* Calling this function will enable extra internal bookkeeping
* to track constraints and emit signals on the returned listmodel.
* It may slow down operations a lot.
*
* Applications should try hard to avoid calling this function
* because of the slowdowns.
*
* Returns: (transfer full): a #GListModel tracking @layout's
* constraints
*/
GListModel *
gtk_constraint_layout_observe_constraints (GtkConstraintLayout *layout)
{
GHashTableIter iter;
gpointer key;
if (layout->constraints_observer)
return g_object_ref (G_LIST_MODEL (layout->constraints_observer));
layout->constraints_observer = g_list_store_new (GTK_TYPE_CONSTRAINT);
g_object_add_weak_pointer ((GObject *)layout->constraints_observer,
(gpointer *)&layout->constraints_observer);
g_hash_table_iter_init (&iter, layout->constraints);
while (g_hash_table_iter_next (&iter, &key, NULL))
{
GtkConstraint *constraint = key;
g_list_store_append (layout->constraints_observer, constraint);
}
return G_LIST_MODEL (layout->constraints_observer);
}
/**
* gtk_constraint_layout_observe_guides:
* @layout: a #GtkConstraintLayout
*
* Returns a #GListModel to track the guides that are
* part of @layout.
*
* Calling this function will enable extra internal bookkeeping
* to track guides and emit signals on the returned listmodel.
* It may slow down operations a lot.
*
* Applications should try hard to avoid calling this function
* because of the slowdowns.
*
* Returns: (transfer full): a #GListModel tracking @layout's
* guides
*/
GListModel *
gtk_constraint_layout_observe_guides (GtkConstraintLayout *layout)
{
GHashTableIter iter;
gpointer key;
if (layout->guides_observer)
return g_object_ref (G_LIST_MODEL (layout->guides_observer));
layout->guides_observer = g_list_store_new (GTK_TYPE_CONSTRAINT_GUIDE);
g_object_add_weak_pointer ((GObject *)layout->guides_observer,
(gpointer *)&layout->guides_observer);
g_hash_table_iter_init (&iter, layout->guides);
while (g_hash_table_iter_next (&iter, &key, NULL))
{
GtkConstraintGuide *guide = key;
g_list_store_append (layout->guides_observer, guide);
}
return G_LIST_MODEL (layout->guides_observer);
}

View File

@ -85,4 +85,9 @@ GList * gtk_constraint_layout_add_constraints_from_descriptionv
GHashTable *views,
GError **error);
GDK_AVAILABLE_IN_ALL
GListModel * gtk_constraint_layout_observe_constraints (GtkConstraintLayout *layout);
GDK_AVAILABLE_IN_ALL
GListModel * gtk_constraint_layout_observe_guides (GtkConstraintLayout *layout);
G_END_DECLS