[libgd] Implemented gd_stack_reorder_child
- From: Jesse van den Kieboom <jessevdk src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgd] Implemented gd_stack_reorder_child
- Date: Fri, 1 Mar 2013 20:21:32 +0000 (UTC)
commit 42e48be3b7cc5c4a21b684f92628c28c4445f3b7
Author: Jesse van den Kieboom <jessevdk gnome org>
Date: Fri Mar 1 18:34:33 2013 +0100
Implemented gd_stack_reorder_child
This is similar to the reordering API of GtkBox and GtkNotebook.
GdStackSwitcher reorders its buttons accordingly.
https://bugzilla.gnome.org/show_bug.cgi?id=694945
libgd/gd-stack-switcher.c | 18 ++++++++++
libgd/gd-stack.c | 84 ++++++++++++++++++++++++++++++++++++++++++++-
libgd/gd-stack.h | 2 -
3 files changed, 101 insertions(+), 3 deletions(-)
---
diff --git a/libgd/gd-stack-switcher.c b/libgd/gd-stack-switcher.c
index 34f9885..d006254 100644
--- a/libgd/gd-stack-switcher.c
+++ b/libgd/gd-stack-switcher.c
@@ -145,6 +145,23 @@ on_title_icon_updated (GtkWidget *widget,
}
static void
+on_position_updated (GtkWidget *widget,
+ GParamSpec *pspec,
+ GdStackSwitcher *self)
+{
+ GtkWidget *button;
+ gint position;
+
+ button = g_hash_table_lookup (self->priv->buttons, widget);
+
+ gtk_container_child_get (GTK_CONTAINER (self->priv->stack), widget,
+ "position", &position,
+ NULL);
+
+ gtk_box_reorder_child (GTK_BOX (self), button, position);
+}
+
+static void
add_child (GdStackSwitcher *self,
GtkWidget *widget)
{
@@ -175,6 +192,7 @@ add_child (GdStackSwitcher *self,
g_signal_connect (button, "clicked", G_CALLBACK (on_button_clicked), self);
g_signal_connect (widget, "child-notify::title", G_CALLBACK (on_title_icon_updated), self);
g_signal_connect (widget, "child-notify::symbolic-icon-name", G_CALLBACK (on_title_icon_updated), self);
+ g_signal_connect (widget, "child-notify::position", G_CALLBACK (on_position_updated), self);
g_hash_table_insert (self->priv->buttons, widget, button);
}
diff --git a/libgd/gd-stack.c b/libgd/gd-stack.c
index f56f63a..7c57684 100644
--- a/libgd/gd-stack.c
+++ b/libgd/gd-stack.c
@@ -47,7 +47,8 @@ enum
CHILD_PROP_0,
CHILD_PROP_NAME,
CHILD_PROP_TITLE,
- CHILD_PROP_SYMBOLIC_ICON_NAME
+ CHILD_PROP_SYMBOLIC_ICON_NAME,
+ CHILD_PROP_POSITION
};
typedef struct _GdStackChildInfo GdStackChildInfo;
@@ -379,6 +380,13 @@ gd_stack_class_init (GdStackClass * klass)
NULL,
GTK_PARAM_READWRITE));
+ gtk_container_class_install_child_property (container_class, CHILD_PROP_POSITION,
+ g_param_spec_int ("position",
+ "Position",
+ "The index of the child in the parent",
+ -1, G_MAXINT, 0,
+ GTK_PARAM_READWRITE));
+
g_type_class_add_private (klass, sizeof (GdStackPrivate));
}
@@ -408,6 +416,61 @@ find_child_info_for_widget (GdStack *stack,
}
static void
+reorder_child (GdStack *stack,
+ GtkWidget *child,
+ gint position)
+{
+ GdStackPrivate *priv;
+ GList *l;
+ GList *old_link = NULL;
+ GList *new_link = NULL;
+ GdStackChildInfo *child_info;
+ gint num = 0;
+
+ priv = stack->priv;
+
+ l = priv->children;
+
+ /* Loop to find the old position and link of child, new link of child and
+ * total number of children. new_link will be NULL if the child should be
+ * moved to the end (in case of position being < 0 || >= num)
+ */
+ while (l && (new_link == NULL || old_link == NULL))
+ {
+ /* Record the new position if found */
+ if (position == num)
+ new_link = l;
+
+ if (old_link == NULL)
+ {
+ GdStackChildInfo *info;
+ info = l->data;
+
+ /* Keep trying to find the current position and link location of the
+ child */
+ if (info->widget == child)
+ {
+ old_link = l;
+ child_info = info;
+ }
+ }
+
+ l = g_list_next (l);
+ num++;
+ }
+
+ g_return_if_fail (old_link != NULL);
+
+ if (old_link == new_link || (g_list_next (old_link) == NULL && new_link == NULL))
+ return;
+
+ priv->children = g_list_delete_link (priv->children, old_link);
+ priv->children = g_list_insert_before (priv->children, new_link, child_info);
+
+ gtk_widget_child_notify (child, "position");
+}
+
+static void
gd_stack_get_child_property (GtkContainer *container,
GtkWidget *child,
guint property_id,
@@ -416,6 +479,8 @@ gd_stack_get_child_property (GtkContainer *container,
{
GdStack *stack = GD_STACK (container);
GdStackChildInfo *info;
+ GList *list;
+ guint i;
info = find_child_info_for_widget (stack, child);
if (info == NULL)
@@ -438,6 +503,17 @@ gd_stack_get_child_property (GtkContainer *container,
g_value_set_string (value, info->symbolic_icon_name);
break;
+ case CHILD_PROP_POSITION:
+ i = 0;
+ for (list = stack->priv->children; list != NULL; list = g_list_next (list))
+ {
+ if (info == list->data)
+ break;
+ ++i;
+ }
+ g_value_set_int (value, i);
+ break;
+
default:
GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
break;
@@ -487,6 +563,10 @@ gd_stack_set_child_property (GtkContainer *container,
gtk_container_child_notify (container, child, "symbolic-icon-name");
break;
+ case CHILD_PROP_POSITION:
+ reorder_child (stack, child, g_value_get_int (value));
+ break;
+
default:
GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
break;
@@ -776,6 +856,8 @@ gd_stack_add (GtkContainer *container,
g_signal_connect (child, "notify::visible",
G_CALLBACK (stack_child_visibility_notify_cb), stack);
+ gtk_widget_child_notify (child, "position");
+
if (priv->visible_child == NULL &&
gtk_widget_get_visible (child))
set_visible_child (stack, child_info);
diff --git a/libgd/gd-stack.h b/libgd/gd-stack.h
index 49d3fe5..0754455 100644
--- a/libgd/gd-stack.h
+++ b/libgd/gd-stack.h
@@ -80,8 +80,6 @@ void gd_stack_set_transition_type (GdStack *s
GdStackTransitionType type);
GdStackTransitionType gd_stack_get_transition_type (GdStack *stack);
-
-
G_END_DECLS
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]