[gtk/stackpage: 2/3] stack: Convert child properties to a child meta object
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/stackpage: 2/3] stack: Convert child properties to a child meta object
- Date: Wed, 6 Feb 2019 18:10:22 +0000 (UTC)
commit f2db092e6a2942d19a5bcf026627bbdbf4b6d62d
Author: Matthias Clasen <mclasen redhat com>
Date: Wed Feb 6 12:54:18 2019 -0500
stack: Convert child properties to a child meta object
Create a GtkStackPage public object which holds the former
child properties of GtkStack.
Adjust all callers
demos/widget-factory/widget-factory.c | 2 +-
gtk/gtkmenusectionbox.c | 2 +-
gtk/gtkstack.c | 513 ++++++++++++++++++----------------
gtk/gtkstack.h | 10 +
gtk/gtkstacksidebar.c | 33 ++-
gtk/gtkstackswitcher.c | 63 ++---
6 files changed, 337 insertions(+), 286 deletions(-)
---
diff --git a/demos/widget-factory/widget-factory.c b/demos/widget-factory/widget-factory.c
index e9cd3c3a7d..df0352b39a 100644
--- a/demos/widget-factory/widget-factory.c
+++ b/demos/widget-factory/widget-factory.c
@@ -556,7 +556,7 @@ set_needs_attention (GtkWidget *page, gboolean needs_attention)
GtkWidget *stack;
stack = gtk_widget_get_parent (page);
- gtk_container_child_set (GTK_CONTAINER (stack), page,
+ g_object_set (gtk_container_get_child_meta (GTK_CONTAINER (stack), page),
"needs-attention", needs_attention,
NULL);
}
diff --git a/gtk/gtkmenusectionbox.c b/gtk/gtkmenusectionbox.c
index 7b21eebc13..7439345373 100644
--- a/gtk/gtkmenusectionbox.c
+++ b/gtk/gtkmenusectionbox.c
@@ -303,7 +303,7 @@ gtk_menu_section_box_insert_func (GtkMenuTrackerItem *item,
g_object_bind_property (item, "sensitive", widget, "sensitive", G_BINDING_SYNC_CREATE);
get_ancestors (GTK_WIDGET (box->toplevel), GTK_TYPE_STACK, &stack, &parent);
- gtk_container_child_get (GTK_CONTAINER (stack), parent, "name", &name, NULL);
+ g_object_get (gtk_stack_get_page (GTK_STACK (stack), parent), "name", &name, NULL);
gtk_menu_section_box_new_submenu (item, box->toplevel, widget, name);
g_free (name);
}
diff --git a/gtk/gtkstack.c b/gtk/gtkstack.c
index 860af7f59a..35643c4424 100644
--- a/gtk/gtkstack.c
+++ b/gtk/gtkstack.c
@@ -92,6 +92,35 @@
* filter events out events to the last_child widget during transitions
*/
+typedef struct {
+ GList *children;
+
+ GtkStackPage *visible_child;
+
+ gboolean hhomogeneous;
+ gboolean vhomogeneous;
+
+ GtkStackTransitionType transition_type;
+ guint transition_duration;
+
+ GtkStackPage *last_visible_child;
+ GskRenderNode *last_visible_node;
+ GtkAllocation last_visible_surface_allocation;
+ guint tick_id;
+ GtkProgressTracker tracker;
+ gboolean first_frame_skipped;
+
+ gint last_visible_widget_width;
+ gint last_visible_widget_height;
+
+ gboolean interpolate_size;
+
+ GtkStackTransitionType active_transition_type;
+
+} GtkStackPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (GtkStack, gtk_stack, GTK_TYPE_CONTAINER)
+
enum {
PROP_0,
PROP_HOMOGENEOUS,
@@ -117,9 +146,10 @@ enum
LAST_CHILD_PROP
};
-typedef struct _GtkStackChildInfo GtkStackChildInfo;
+typedef struct _GtkStackPage GtkStackPage;
-struct _GtkStackChildInfo {
+struct _GtkStackPage {
+ GObject instance;
GtkWidget *widget;
gchar *name;
gchar *title;
@@ -128,35 +158,196 @@ struct _GtkStackChildInfo {
GtkWidget *last_focus;
};
-typedef struct {
- GList *children;
+static GParamSpec *stack_props[LAST_PROP] = { NULL, };
+static GParamSpec *stack_child_props[LAST_CHILD_PROP] = { NULL, };
- GtkStackChildInfo *visible_child;
+G_DEFINE_TYPE (GtkStackPage, gtk_stack_page, G_TYPE_OBJECT)
- gboolean hhomogeneous;
- gboolean vhomogeneous;
+static void
+gtk_stack_page_init (GtkStackPage *page)
+{
+}
- GtkStackTransitionType transition_type;
- guint transition_duration;
+static void
+gtk_stack_page_finalize (GObject *object)
+{
+ GtkStackPage *page = GTK_STACK_PAGE (object);
- GtkStackChildInfo *last_visible_child;
- GskRenderNode *last_visible_node;
- GtkAllocation last_visible_surface_allocation;
- guint tick_id;
- GtkProgressTracker tracker;
- gboolean first_frame_skipped;
+ g_free (page->name);
+ g_free (page->title);
+ g_free (page->icon_name);
- gint last_visible_widget_width;
- gint last_visible_widget_height;
+ if (page->last_focus)
+ g_object_remove_weak_pointer (G_OBJECT (page->last_focus),
+ (gpointer *)&page->last_focus);
- gboolean interpolate_size;
+ G_OBJECT_CLASS (gtk_stack_page_parent_class)->finalize (object);
+}
- GtkStackTransitionType active_transition_type;
+static void
+gtk_stack_page_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkStackPage *info = GTK_STACK_PAGE (object);
+ GtkWidget *stack = gtk_widget_get_parent (GTK_WIDGET (info->widget));
+ GtkStackPrivate *priv = gtk_stack_get_instance_private (GTK_STACK (stack));
-} GtkStackPrivate;
+ switch (property_id)
+ {
+ case CHILD_PROP_NAME:
+ g_value_set_string (value, info->name);
+ break;
-static GParamSpec *stack_props[LAST_PROP] = { NULL, };
-static GParamSpec *stack_child_props[LAST_CHILD_PROP] = { NULL, };
+ case CHILD_PROP_TITLE:
+ g_value_set_string (value, info->title);
+ break;
+
+ case CHILD_PROP_ICON_NAME:
+ g_value_set_string (value, info->icon_name);
+ break;
+
+ case CHILD_PROP_POSITION:
+ g_value_set_int (value, g_list_index (priv->children, info));
+ break;
+
+ case CHILD_PROP_NEEDS_ATTENTION:
+ g_value_set_boolean (value, info->needs_attention);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void reorder_child (GtkStack *stack,
+ GtkWidget *child,
+ gint position);
+
+static void
+gtk_stack_page_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GtkStackPage *info = GTK_STACK_PAGE (object);
+ GtkStack *stack = GTK_STACK (gtk_widget_get_parent (GTK_WIDGET (info->widget)));
+ GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
+ GtkStackPage *info2;
+ gchar *name;
+ GList *l;
+
+ switch (property_id)
+ {
+ case CHILD_PROP_NAME:
+ name = g_value_dup_string (value);
+ for (l = priv->children; l != NULL; l = l->next)
+ {
+ info2 = l->data;
+ if (info == info2)
+ continue;
+ if (g_strcmp0 (info2->name, name) == 0)
+ {
+ g_warning ("Duplicate child name in GtkStack: %s", name);
+ break;
+ }
+ }
+
+ g_free (info->name);
+ info->name = name;
+g_print ("stack page name: %s\n", name);
+
+ g_object_notify_by_pspec (object, pspec);
+
+ if (priv->visible_child == info)
+ g_object_notify_by_pspec (G_OBJECT (stack),
+ stack_props[PROP_VISIBLE_CHILD_NAME]);
+
+ break;
+
+ case CHILD_PROP_TITLE:
+ g_free (info->title);
+ info->title = g_value_dup_string (value);
+ g_object_notify_by_pspec (object, pspec);
+ break;
+
+ case CHILD_PROP_ICON_NAME:
+ g_free (info->icon_name);
+ info->icon_name = g_value_dup_string (value);
+ g_object_notify_by_pspec (object, pspec);
+ break;
+
+ case CHILD_PROP_POSITION:
+ reorder_child (stack, info->widget, g_value_get_int (value));
+ break;
+
+ case CHILD_PROP_NEEDS_ATTENTION:
+ info->needs_attention = g_value_get_boolean (value);
+ g_object_notify_by_pspec (object, pspec);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+static void
+gtk_stack_page_class_init (GtkStackPageClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ object_class->finalize = gtk_stack_page_finalize;
+ object_class->get_property = gtk_stack_page_get_property;
+ object_class->set_property = gtk_stack_page_set_property;
+
+ stack_child_props[CHILD_PROP_NAME] =
+ g_param_spec_string ("name",
+ P_("Name"),
+ P_("The name of the child page"),
+ NULL,
+ GTK_PARAM_READWRITE);
+
+ stack_child_props[CHILD_PROP_TITLE] =
+ g_param_spec_string ("title",
+ P_("Title"),
+ P_("The title of the child page"),
+ NULL,
+ GTK_PARAM_READWRITE);
+
+ stack_child_props[CHILD_PROP_ICON_NAME] =
+ g_param_spec_string ("icon-name",
+ P_("Icon name"),
+ P_("The icon name of the child page"),
+ NULL,
+ GTK_PARAM_READWRITE);
+
+ stack_child_props[CHILD_PROP_POSITION] =
+ g_param_spec_int ("position",
+ P_("Position"),
+ P_("The index of the child in the parent"),
+ -1, G_MAXINT,
+ 0,
+ GTK_PARAM_READWRITE);
+
+ /**
+ * GtkStack:needs-attention:
+ *
+ * Sets a flag specifying whether the child requires the user attention.
+ * This is used by the #GtkStackSwitcher to change the appearance of the
+ * corresponding button when a page needs attention and it is not the
+ * current one.
+ */
+ stack_child_props[CHILD_PROP_NEEDS_ATTENTION] =
+ g_param_spec_boolean ("needs-attention",
+ P_("Needs Attention"),
+ P_("Whether this page needs attention"),
+ FALSE,
+ GTK_PARAM_READWRITE);
+
+ g_object_class_install_properties (object_class, LAST_CHILD_PROP, stack_child_props);
+}
static void gtk_stack_add (GtkContainer *widget,
GtkWidget *child);
@@ -190,19 +381,9 @@ static void gtk_stack_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
-static void gtk_stack_get_child_property (GtkContainer *container,
- GtkWidget *child,
- guint property_id,
- GValue *value,
- GParamSpec *pspec);
-static void gtk_stack_set_child_property (GtkContainer *container,
- GtkWidget *child,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec);
static void gtk_stack_unschedule_ticks (GtkStack *stack);
-
-G_DEFINE_TYPE_WITH_PRIVATE (GtkStack, gtk_stack, GTK_TYPE_CONTAINER)
+static GObject *gtk_stack_get_child_meta (GtkContainer *container,
+ GtkWidget *widget);
static void
gtk_stack_finalize (GObject *obj)
@@ -319,8 +500,7 @@ gtk_stack_class_init (GtkStackClass *klass)
container_class->add = gtk_stack_add;
container_class->remove = gtk_stack_remove;
container_class->forall = gtk_stack_forall;
- container_class->set_child_property = gtk_stack_set_child_property;
- container_class->get_child_property = gtk_stack_get_child_property;
+ container_class->get_child_meta = gtk_stack_get_child_meta;
stack_props[PROP_HOMOGENEOUS] =
g_param_spec_boolean ("homogeneous", P_("Homogeneous"), P_("Homogeneous sizing"),
@@ -374,51 +554,6 @@ gtk_stack_class_init (GtkStackClass *klass)
g_object_class_install_properties (object_class, LAST_PROP, stack_props);
- stack_child_props[CHILD_PROP_NAME] =
- g_param_spec_string ("name",
- P_("Name"),
- P_("The name of the child page"),
- NULL,
- GTK_PARAM_READWRITE);
-
- stack_child_props[CHILD_PROP_TITLE] =
- g_param_spec_string ("title",
- P_("Title"),
- P_("The title of the child page"),
- NULL,
- GTK_PARAM_READWRITE);
-
- stack_child_props[CHILD_PROP_ICON_NAME] =
- g_param_spec_string ("icon-name",
- P_("Icon name"),
- P_("The icon name of the child page"),
- NULL,
- GTK_PARAM_READWRITE);
-
- stack_child_props[CHILD_PROP_POSITION] =
- g_param_spec_int ("position",
- P_("Position"),
- P_("The index of the child in the parent"),
- -1, G_MAXINT,
- 0,
- GTK_PARAM_READWRITE);
-
- /**
- * GtkStack:needs-attention:
- *
- * Sets a flag specifying whether the child requires the user attention.
- * This is used by the #GtkStackSwitcher to change the appearance of the
- * corresponding button when a page needs attention and it is not the
- * current one.
- */
- stack_child_props[CHILD_PROP_NEEDS_ATTENTION] =
- g_param_spec_boolean ("needs-attention",
- P_("Needs Attention"),
- P_("Whether this page needs attention"),
- FALSE,
- GTK_PARAM_READWRITE);
-
- gtk_container_class_install_child_properties (container_class, LAST_CHILD_PROP, stack_child_props);
gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_STACK_ACCESSIBLE);
gtk_widget_class_set_css_name (widget_class, I_("stack"));
@@ -437,12 +572,12 @@ gtk_stack_new (void)
return g_object_new (GTK_TYPE_STACK, NULL);
}
-static GtkStackChildInfo *
+static GtkStackPage *
find_child_info_for_widget (GtkStack *stack,
GtkWidget *child)
{
GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
- GtkStackChildInfo *info;
+ GtkStackPage *info;
GList *l;
for (l = priv->children; l != NULL; l = l->next)
@@ -464,7 +599,7 @@ reorder_child (GtkStack *stack,
GList *l;
GList *old_link = NULL;
GList *new_link = NULL;
- GtkStackChildInfo *child_info = NULL;
+ GtkStackPage *child_info = NULL;
gint num = 0;
l = priv->children;
@@ -481,7 +616,7 @@ reorder_child (GtkStack *stack,
if (old_link == NULL)
{
- GtkStackChildInfo *info;
+ GtkStackPage *info;
info = l->data;
/* Keep trying to find the current position and link location of the child */
@@ -507,126 +642,6 @@ reorder_child (GtkStack *stack,
gtk_container_child_notify_by_pspec (GTK_CONTAINER (stack), child, stack_child_props[CHILD_PROP_POSITION]);
}
-static void
-gtk_stack_get_child_property (GtkContainer *container,
- GtkWidget *child,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GtkStack *stack = GTK_STACK (container);
- GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
- GtkStackChildInfo *info;
-
- info = find_child_info_for_widget (stack, child);
- if (info == NULL)
- {
- GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
- return;
- }
-
- switch (property_id)
- {
- case CHILD_PROP_NAME:
- g_value_set_string (value, info->name);
- break;
-
- case CHILD_PROP_TITLE:
- g_value_set_string (value, info->title);
- break;
-
- case CHILD_PROP_ICON_NAME:
- g_value_set_string (value, info->icon_name);
- break;
-
- case CHILD_PROP_POSITION:
- g_value_set_int (value, g_list_index (priv->children, info));
- break;
-
- case CHILD_PROP_NEEDS_ATTENTION:
- g_value_set_boolean (value, info->needs_attention);
- break;
-
- default:
- GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
- break;
- }
-}
-
-static void
-gtk_stack_set_child_property (GtkContainer *container,
- GtkWidget *child,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GtkStack *stack = GTK_STACK (container);
- GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
- GtkStackChildInfo *info;
- GtkStackChildInfo *info2;
- gchar *name;
- GList *l;
-
- info = find_child_info_for_widget (stack, child);
- if (info == NULL)
- {
- GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
- return;
- }
-
- switch (property_id)
- {
- case CHILD_PROP_NAME:
- name = g_value_dup_string (value);
- for (l = priv->children; l != NULL; l = l->next)
- {
- info2 = l->data;
- if (info == info2)
- continue;
- if (g_strcmp0 (info2->name, name) == 0)
- {
- g_warning ("Duplicate child name in GtkStack: %s", name);
- break;
- }
- }
-
- g_free (info->name);
- info->name = name;
-
- gtk_container_child_notify_by_pspec (container, child, pspec);
-
- if (priv->visible_child == info)
- g_object_notify_by_pspec (G_OBJECT (stack),
- stack_props[PROP_VISIBLE_CHILD_NAME]);
-
- break;
-
- case CHILD_PROP_TITLE:
- g_free (info->title);
- info->title = g_value_dup_string (value);
- gtk_container_child_notify_by_pspec (container, child, pspec);
- break;
-
- case CHILD_PROP_ICON_NAME:
- g_free (info->icon_name);
- info->icon_name = g_value_dup_string (value);
- gtk_container_child_notify_by_pspec (container, child, pspec);
- break;
-
- case CHILD_PROP_POSITION:
- reorder_child (stack, child, g_value_get_int (value));
- break;
-
- case CHILD_PROP_NEEDS_ATTENTION:
- info->needs_attention = g_value_get_boolean (value);
- gtk_container_child_notify_by_pspec (container, child, pspec);
- break;
-
- default:
- GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
- break;
- }
-}
static inline gboolean
is_left_transition (GtkStackTransitionType transition_type)
@@ -922,12 +937,12 @@ gtk_stack_start_transition (GtkStack *stack,
static void
set_visible_child (GtkStack *stack,
- GtkStackChildInfo *child_info,
+ GtkStackPage *child_info,
GtkStackTransitionType transition_type,
guint transition_duration)
{
GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
- GtkStackChildInfo *info;
+ GtkStackPage *info;
GtkWidget *widget = GTK_WIDGET (stack);
GList *l;
GtkWidget *toplevel;
@@ -1061,7 +1076,7 @@ stack_child_visibility_notify_cb (GObject *obj,
GtkStack *stack = GTK_STACK (user_data);
GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
GtkWidget *child = GTK_WIDGET (obj);
- GtkStackChildInfo *child_info;
+ GtkStackPage *child_info;
child_info = find_child_info_for_widget (stack, child);
@@ -1079,6 +1094,12 @@ stack_child_visibility_notify_cb (GObject *obj,
}
}
+static void
+gtk_stack_add_internal (GtkStack *stack,
+ GtkWidget *child,
+ const char *name,
+ const char *title);
+
/**
* gtk_stack_add_titled:
* @stack: a #GtkStack
@@ -1100,11 +1121,7 @@ gtk_stack_add_titled (GtkStack *stack,
g_return_if_fail (GTK_IS_STACK (stack));
g_return_if_fail (GTK_IS_WIDGET (child));
- gtk_container_add_with_properties (GTK_CONTAINER (stack),
- child,
- "name", name,
- "title", title,
- NULL);
+ gtk_stack_add_internal (stack, child, name, title);
}
/**
@@ -1124,10 +1141,7 @@ gtk_stack_add_named (GtkStack *stack,
g_return_if_fail (GTK_IS_STACK (stack));
g_return_if_fail (GTK_IS_WIDGET (child));
- gtk_container_add_with_properties (GTK_CONTAINER (stack),
- child,
- "name", name,
- NULL);
+ gtk_stack_add_internal (stack, child, name, NULL);
}
static void
@@ -1135,15 +1149,26 @@ gtk_stack_add (GtkContainer *container,
GtkWidget *child)
{
GtkStack *stack = GTK_STACK (container);
+
+ gtk_stack_add_internal (stack, child, NULL, NULL);
+}
+
+static void
+gtk_stack_add_internal (GtkStack *stack,
+ GtkWidget *child,
+ const char *name,
+ const char *title)
+{
GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
- GtkStackChildInfo *child_info;
+ GtkStackPage *child_info;
+g_print ("add internal %s\n", name);
g_return_if_fail (child != NULL);
- child_info = g_slice_new (GtkStackChildInfo);
+ child_info = g_object_new (GTK_TYPE_STACK_PAGE, NULL);
child_info->widget = child;
- child_info->name = NULL;
- child_info->title = NULL;
+ child_info->name = g_strdup (name);
+ child_info->title = g_strdup (title);
child_info->icon_name = NULL;
child_info->needs_attention = FALSE;
child_info->last_focus = NULL;
@@ -1156,7 +1181,7 @@ gtk_stack_add (GtkContainer *container,
g_signal_connect (child, "notify::visible",
G_CALLBACK (stack_child_visibility_notify_cb), stack);
- gtk_container_child_notify_by_pspec (container, child, stack_child_props[CHILD_PROP_POSITION]);
+ g_object_notify_by_pspec (G_OBJECT (child_info), stack_child_props[CHILD_PROP_POSITION]);
if (priv->visible_child == NULL &&
gtk_widget_get_visible (child))
@@ -1172,7 +1197,7 @@ gtk_stack_remove (GtkContainer *container,
{
GtkStack *stack = GTK_STACK (container);
GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
- GtkStackChildInfo *child_info;
+ GtkStackPage *child_info;
gboolean was_visible;
child_info = find_child_info_for_widget (stack, child);
@@ -1197,20 +1222,26 @@ gtk_stack_remove (GtkContainer *container,
gtk_widget_unparent (child);
- g_free (child_info->name);
- g_free (child_info->title);
- g_free (child_info->icon_name);
-
- if (child_info->last_focus)
- g_object_remove_weak_pointer (G_OBJECT (child_info->last_focus),
- (gpointer *)&child_info->last_focus);
-
- g_slice_free (GtkStackChildInfo, child_info);
+ g_object_unref (child_info);
if ((priv->hhomogeneous || priv->vhomogeneous) && was_visible)
gtk_widget_queue_resize (GTK_WIDGET (stack));
}
+static GObject *
+gtk_stack_get_child_meta (GtkContainer *container,
+ GtkWidget *child)
+{
+ return G_OBJECT (find_child_info_for_widget (GTK_STACK (container), child));
+}
+
+GtkStackPage *
+gtk_stack_get_page (GtkStack *stack,
+ GtkWidget *child)
+{
+ return find_child_info_for_widget (stack, child);
+}
+
/**
* gtk_stack_get_child_by_name:
* @stack: a #GtkStack
@@ -1227,7 +1258,7 @@ gtk_stack_get_child_by_name (GtkStack *stack,
const gchar *name)
{
GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
- GtkStackChildInfo *info;
+ GtkStackPage *info;
GList *l;
g_return_val_if_fail (GTK_IS_STACK (stack), NULL);
@@ -1243,6 +1274,12 @@ gtk_stack_get_child_by_name (GtkStack *stack,
return NULL;
}
+GtkWidget *
+gtk_stack_page_get_child (GtkStackPage *page)
+{
+ return page->widget;
+}
+
/**
* gtk_stack_set_homogeneous:
* @stack: a #GtkStack
@@ -1630,7 +1667,7 @@ gtk_stack_set_visible_child (GtkStack *stack,
GtkWidget *child)
{
GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
- GtkStackChildInfo *child_info;
+ GtkStackPage *child_info;
g_return_if_fail (GTK_IS_STACK (stack));
g_return_if_fail (GTK_IS_WIDGET (child));
@@ -1694,7 +1731,7 @@ gtk_stack_set_visible_child_full (GtkStack *stack,
GtkStackTransitionType transition)
{
GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
- GtkStackChildInfo *child_info, *info;
+ GtkStackPage *child_info, *info;
GList *l;
g_return_if_fail (GTK_IS_STACK (stack));
@@ -1731,7 +1768,7 @@ gtk_stack_forall (GtkContainer *container,
{
GtkStack *stack = GTK_STACK (container);
GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
- GtkStackChildInfo *child_info;
+ GtkStackPage *child_info;
GList *l;
l = priv->children;
@@ -1753,7 +1790,7 @@ gtk_stack_compute_expand (GtkWidget *widget,
GtkStack *stack = GTK_STACK (widget);
GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
gboolean hexpand, vexpand;
- GtkStackChildInfo *child_info;
+ GtkStackPage *child_info;
GtkWidget *child;
GList *l;
@@ -2088,7 +2125,7 @@ gtk_stack_measure (GtkWidget *widget,
{
GtkStack *stack = GTK_STACK (widget);
GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
- GtkStackChildInfo *child_info;
+ GtkStackPage *child_info;
GtkWidget *child;
gint child_min, child_nat;
GList *l;
diff --git a/gtk/gtkstack.h b/gtk/gtkstack.h
index b9b4701cf4..3af14e4216 100644
--- a/gtk/gtkstack.h
+++ b/gtk/gtkstack.h
@@ -41,6 +41,9 @@ G_BEGIN_DECLS
typedef struct _GtkStack GtkStack;
typedef struct _GtkStackClass GtkStackClass;
+#define GTK_TYPE_STACK_PAGE (gtk_stack_page_get_type ())
+G_DECLARE_FINAL_TYPE (GtkStackPage, gtk_stack_page, GTK, STACK_PAGE, GObject)
+
typedef enum {
GTK_STACK_TRANSITION_TYPE_NONE,
GTK_STACK_TRANSITION_TYPE_CROSSFADE,
@@ -86,6 +89,13 @@ void gtk_stack_add_titled (GtkStack
GtkWidget *child,
const gchar *name,
const gchar *title);
+
+GDK_AVAILABLE_IN_ALL
+GtkStackPage * gtk_stack_get_page (GtkStack *stack,
+ GtkWidget *child);
+GDK_AVAILABLE_IN_ALL
+GtkWidget * gtk_stack_page_get_child (GtkStackPage *page);
+
GDK_AVAILABLE_IN_ALL
GtkWidget * gtk_stack_get_child_by_name (GtkStack *stack,
const gchar *name);
diff --git a/gtk/gtkstacksidebar.c b/gtk/gtkstacksidebar.c
index 552dcab9f8..1a0c856d29 100644
--- a/gtk/gtkstacksidebar.c
+++ b/gtk/gtkstacksidebar.c
@@ -140,7 +140,7 @@ sort_list (GtkListBoxRow *row1,
{
item = gtk_bin_get_child (GTK_BIN (row1));
widget = g_object_get_data (G_OBJECT (item), "stack-child");
- gtk_container_child_get (GTK_CONTAINER (priv->stack), widget,
+ g_object_get (gtk_container_get_child_meta (GTK_CONTAINER (priv->stack), widget),
"position", &left,
NULL);
}
@@ -149,7 +149,7 @@ sort_list (GtkListBoxRow *row1,
{
item = gtk_bin_get_child (GTK_BIN (row2));
widget = g_object_get_data (G_OBJECT (item), "stack-child");
- gtk_container_child_get (GTK_CONTAINER (priv->stack), widget,
+ g_object_get (gtk_container_get_child_meta (GTK_CONTAINER (priv->stack), widget),
"position", &right,
NULL);
}
@@ -227,10 +227,10 @@ update_row (GtkStackSidebar *sidebar,
gboolean needs_attention;
GtkStyleContext *context;
- gtk_container_child_get (GTK_CONTAINER (priv->stack), widget,
- "title", &title,
- "needs-attention", &needs_attention,
- NULL);
+ g_object_get (gtk_container_get_child_meta (GTK_CONTAINER (priv->stack), widget),
+ "title", &title,
+ "needs-attention", &needs_attention,
+ NULL);
item = gtk_bin_get_child (GTK_BIN (row));
gtk_label_set_text (GTK_LABEL (item), title);
@@ -275,6 +275,7 @@ add_child (GtkWidget *widget,
GtkStackSidebarPrivate *priv = gtk_stack_sidebar_get_instance_private (sidebar);
GtkWidget *item;
GtkWidget *row;
+ GObject *page;
/* Check we don't actually already know about this widget */
if (g_hash_table_lookup (priv->rows, widget))
@@ -291,13 +292,14 @@ add_child (GtkWidget *widget,
update_row (sidebar, widget, row);
/* Hook up for events */
- g_signal_connect (widget, "child-notify::title",
+ page = gtk_container_get_child_meta (GTK_CONTAINER (priv->stack), widget);
+ g_signal_connect (widget, "notify::visible",
G_CALLBACK (on_child_updated), sidebar);
- g_signal_connect (widget, "child-notify::needs-attention",
+ g_signal_connect (page, "notify::title",
G_CALLBACK (on_child_updated), sidebar);
- g_signal_connect (widget, "notify::visible",
+ g_signal_connect (page, "notify::needs-attention",
G_CALLBACK (on_child_updated), sidebar);
- g_signal_connect (widget, "child-notify::position",
+ g_signal_connect (page, "notify::position",
G_CALLBACK (on_position_updated), sidebar);
g_object_set_data (G_OBJECT (item), I_("stack-child"), widget);
@@ -316,8 +318,15 @@ remove_child (GtkWidget *widget,
if (!row)
return;
- g_signal_handlers_disconnect_by_func (widget, on_child_updated, sidebar);
- g_signal_handlers_disconnect_by_func (widget, on_position_updated, sidebar);
+ if (priv->stack)
+ {
+ GObject *page = gtk_container_get_child_meta (GTK_CONTAINER (priv->stack), widget);
+ if (page)
+ {
+ g_signal_handlers_disconnect_by_func (page, on_child_updated, sidebar);
+ g_signal_handlers_disconnect_by_func (page, on_position_updated, sidebar);
+ }
+ }
gtk_container_remove (GTK_CONTAINER (priv->list), row);
g_hash_table_remove (priv->rows, widget);
diff --git a/gtk/gtkstackswitcher.c b/gtk/gtkstackswitcher.c
index 3fb4dde191..a751624045 100644
--- a/gtk/gtkstackswitcher.c
+++ b/gtk/gtkstackswitcher.c
@@ -159,25 +159,6 @@ rebuild_child (GtkWidget *self,
}
}
-static void
-update_needs_attention (GtkWidget *widget, GtkWidget *button, gpointer data)
-{
- GtkContainer *container;
- gboolean needs_attention;
- GtkStyleContext *context;
-
- container = GTK_CONTAINER (data);
- gtk_container_child_get (container, widget,
- "needs-attention", &needs_attention,
- NULL);
-
- context = gtk_widget_get_style_context (button);
- if (needs_attention)
- gtk_style_context_add_class (context, GTK_STYLE_CLASS_NEEDS_ATTENTION);
- else
- gtk_style_context_remove_class (context, GTK_STYLE_CLASS_NEEDS_ATTENTION);
-}
-
static void
update_button (GtkStackSwitcher *self,
GtkWidget *widget,
@@ -185,23 +166,29 @@ update_button (GtkStackSwitcher *self,
{
gchar *title;
gchar *icon_name;
+ gboolean needs_attention;
GtkStackSwitcherPrivate *priv;
-
+ GtkStyleContext *context;
priv = gtk_stack_switcher_get_instance_private (self);
- gtk_container_child_get (GTK_CONTAINER (priv->stack), widget,
- "title", &title,
- "icon-name", &icon_name,
- NULL);
+ g_object_get (gtk_stack_get_page (priv->stack, widget),
+ "title", &title,
+ "icon-name", &icon_name,
+ "needs-attention", &needs_attention,
+ NULL);
rebuild_child (button, icon_name, title);
gtk_widget_set_visible (button, gtk_widget_get_visible (widget) && (title != NULL || icon_name != NULL));
+ context = gtk_widget_get_style_context (button);
+ if (needs_attention)
+ gtk_style_context_add_class (context, GTK_STYLE_CLASS_NEEDS_ATTENTION);
+ else
+ gtk_style_context_remove_class (context, GTK_STYLE_CLASS_NEEDS_ATTENTION);
+
g_free (title);
g_free (icon_name);
-
- update_needs_attention (widget, button, priv->stack);
}
static void
@@ -354,6 +341,7 @@ add_child (GtkWidget *widget,
GtkWidget *button;
GList *group;
GtkStackSwitcherPrivate *priv;
+ GtkStackPage *page;
priv = gtk_stack_switcher_get_instance_private (self);
@@ -362,6 +350,7 @@ add_child (GtkWidget *widget,
gtk_widget_set_focus_on_click (button, FALSE);
gtk_check_button_set_draw_indicator (GTK_CHECK_BUTTON (button), FALSE);
+ page = gtk_stack_get_page (GTK_STACK (priv->stack), widget);
update_button (self, widget, button);
group = gtk_container_get_children (GTK_CONTAINER (self));
@@ -376,10 +365,10 @@ add_child (GtkWidget *widget,
g_object_set_data (G_OBJECT (button), "stack-child", widget);
g_signal_connect (button, "clicked", G_CALLBACK (on_button_clicked), self);
g_signal_connect (widget, "notify::visible", G_CALLBACK (on_title_icon_visible_updated), self);
- g_signal_connect (widget, "child-notify::title", G_CALLBACK (on_title_icon_visible_updated), self);
- g_signal_connect (widget, "child-notify::icon-name", G_CALLBACK (on_title_icon_visible_updated), self);
- g_signal_connect (widget, "child-notify::position", G_CALLBACK (on_position_updated), self);
- g_signal_connect (widget, "child-notify::needs-attention", G_CALLBACK (on_needs_attention_updated), self);
+ g_signal_connect (page, "notify::title", G_CALLBACK (on_title_icon_visible_updated), self);
+ g_signal_connect (page, "notify::icon-name", G_CALLBACK (on_title_icon_visible_updated), self);
+ g_signal_connect (page, "notify::position", G_CALLBACK (on_position_updated), self);
+ g_signal_connect (page, "notify::needs-attention", G_CALLBACK (on_needs_attention_updated), self);
g_hash_table_insert (priv->buttons, widget, button);
}
@@ -393,10 +382,16 @@ remove_child (GtkWidget *widget,
priv = gtk_stack_switcher_get_instance_private (self);
- g_signal_handlers_disconnect_by_func (widget, on_title_icon_visible_updated, self);
- g_signal_handlers_disconnect_by_func (widget, on_position_updated, self);
- g_signal_handlers_disconnect_by_func (widget, on_needs_attention_updated, self);
-
+ if (priv->stack)
+ {
+ GtkStackPage *page = gtk_stack_get_page (priv->stack, widget);
+ if (page)
+ {
+ g_signal_handlers_disconnect_by_func (page, on_title_icon_visible_updated, self);
+ g_signal_handlers_disconnect_by_func (page, on_position_updated, self);
+ g_signal_handlers_disconnect_by_func (page, on_needs_attention_updated, self);
+ }
+ }
button = g_hash_table_lookup (priv->buttons, widget);
gtk_container_remove (GTK_CONTAINER (self), button);
g_hash_table_remove (priv->buttons, widget);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]