[gnome-builder/gnome-builder-3-24] pnl: use indexes rather than position child properties
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/gnome-builder-3-24] pnl: use indexes rather than position child properties
- Date: Fri, 14 Apr 2017 21:15:23 +0000 (UTC)
commit a54fae3a29f01b0c8e6653bcb999e1dc0a0297d5
Author: Christian Hergert <chergert redhat com>
Date: Fri Apr 14 14:12:43 2017 -0700
pnl: use indexes rather than position child properties
The position child property of GtkStack is not reliable, so we want to use
our own indexing into the children to determine which to focus.
This fixes a long standing issue where the right panel could have two
items that were highlighted.
contrib/pnl/pnl-tab-strip.c | 107 +++++++++++++++++++++++++++++--------------
1 files changed, 73 insertions(+), 34 deletions(-)
---
diff --git a/contrib/pnl/pnl-tab-strip.c b/contrib/pnl/pnl-tab-strip.c
index aacd468..ddb8479 100644
--- a/contrib/pnl/pnl-tab-strip.c
+++ b/contrib/pnl/pnl-tab-strip.c
@@ -45,8 +45,8 @@ set_tab_state (GSimpleAction *action,
{
PnlTabStrip *self = user_data;
PnlTabStripPrivate *priv = pnl_tab_strip_get_instance_private (self);
+ GtkWidget *nth_child;
PnlTab *tab = NULL;
- const GList *iter;
GList *list;
gint stateval;
@@ -60,31 +60,41 @@ set_tab_state (GSimpleAction *action,
stateval = g_variant_get_int32 (state);
list = gtk_container_get_children (GTK_CONTAINER (priv->stack));
+ nth_child = g_list_nth_data (list, stateval);
+ g_clear_pointer (&list, g_list_free);
+
+ g_print ("set_tab_state(%d)\n", stateval);
- for (iter = list; iter != NULL; iter = iter->next)
+ if (nth_child != NULL)
{
- GtkWidget *child = iter->data;
- gint position = 0;
+ tab = g_object_get_data (G_OBJECT (nth_child), "PNL_TAB");
+ gtk_stack_set_visible_child (priv->stack, nth_child);
+ /*
+ * When clicking an active toggle button, we get the state callback but then
+ * the toggle button disables the checked state. So ensure it stays on by
+ * manually setting the state.
+ */
+ if (PNL_IS_TAB (tab))
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tab), TRUE);
+ }
+}
- gtk_container_child_get (GTK_CONTAINER (priv->stack), GTK_WIDGET (child),
- "position", &position,
- NULL);
+static void
+pnl_tab_strip_update_action_targets (PnlTabStrip *self)
+{
+ const GList *iter;
+ GList *list;
+ gint i;
- if (position == stateval)
- {
- tab = g_object_get_data (G_OBJECT (child), "PNL_TAB");
- gtk_stack_set_visible_child (priv->stack, child);
- break;
- }
- }
+ g_assert (PNL_IS_TAB_STRIP (self));
- /*
- * When clicking an active toggle button, we get the state callback but then
- * the toggle button disables the checked state. So ensure it stays on by
- * manually setting the state.
- */
- if (PNL_IS_TAB (tab))
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tab), TRUE);
+ list = gtk_container_get_children (GTK_CONTAINER (self));
+
+ for (i = 0, iter = list; iter != NULL; iter = iter->next, i++)
+ {
+ PnlTab *tab = iter->data;
+ gtk_actionable_set_action_target (GTK_ACTIONABLE (tab), "i", i);
+ }
g_list_free (list);
}
@@ -103,6 +113,22 @@ pnl_tab_strip_add (GtkContainer *container,
pnl_tab_set_edge (PNL_TAB (widget), priv->edge);
GTK_CONTAINER_CLASS (pnl_tab_strip_parent_class)->add (container, widget);
+
+ pnl_tab_strip_update_action_targets (self);
+}
+
+static void
+pnl_tab_strip_remove (GtkContainer *container,
+ GtkWidget *widget)
+{
+ PnlTabStrip *self = (PnlTabStrip *)container;
+
+ g_assert (PNL_IS_TAB_STRIP (self));
+ g_assert (GTK_IS_WIDGET (widget));
+
+ GTK_CONTAINER_CLASS (pnl_tab_strip_parent_class)->remove (container, widget);
+
+ pnl_tab_strip_update_action_targets (self);
}
static void
@@ -113,6 +139,8 @@ pnl_tab_strip_destroy (GtkWidget *widget)
g_assert (PNL_IS_TAB_STRIP (self));
+ gtk_widget_insert_action_group (GTK_WIDGET (self), "tab-strip", NULL);
+
pnl_tab_strip_set_stack (self, NULL);
g_clear_object (&priv->action);
@@ -180,6 +208,7 @@ pnl_tab_strip_class_init (PnlTabStripClass *klass)
widget_class->destroy = pnl_tab_strip_destroy;
container_class->add = pnl_tab_strip_add;
+ container_class->remove = pnl_tab_strip_remove;
properties [PROP_EDGE] =
g_param_spec_enum ("edge",
@@ -229,7 +258,7 @@ pnl_tab_strip_child_position_changed (PnlTabStrip *self,
GVariant *state;
GtkWidget *parent;
PnlTab *tab;
- guint position;
+ gint position = -1;
g_assert (PNL_IS_TAB_STRIP (self));
g_assert (GTK_IS_WIDGET (child));
@@ -237,20 +266,34 @@ pnl_tab_strip_child_position_changed (PnlTabStrip *self,
tab = g_object_get_data (G_OBJECT (child), "PNL_TAB");
if (!tab || !PNL_IS_TAB (tab))
- return;
+ {
+ g_warning ("Child %s (%p) is missing backpointer to tab",
+ G_OBJECT_TYPE_NAME (child), child);
+ return;
+ }
parent = gtk_widget_get_parent (child);
+ g_assert (GTK_IS_STACK (parent));
+
gtk_container_child_get (GTK_CONTAINER (parent), child,
"position", &position,
NULL);
+ if (position < 0)
+ {
+ g_warning ("Improbable position for child, %d", position);
+ return;
+ }
+
gtk_container_child_set (GTK_CONTAINER (self), GTK_WIDGET (tab),
"position", position,
NULL);
state = g_variant_new_int32 (position);
gtk_actionable_set_action_target_value (GTK_ACTIONABLE (tab), state);
+
+ pnl_tab_strip_update_action_targets (self);
}
static void
@@ -272,6 +315,8 @@ pnl_tab_strip_child_title_changed (PnlTabStrip *self,
parent = gtk_widget_get_parent (child);
+ g_assert (GTK_IS_STACK (parent));
+
gtk_container_child_get (GTK_CONTAINER (parent), child,
"title", &title,
NULL);
@@ -322,23 +367,14 @@ pnl_tab_strip_stack_add (PnlTabStrip *self,
GtkStack *stack)
{
PnlTabStripPrivate *priv = pnl_tab_strip_get_instance_private (self);
- GVariant *target;
PnlTab *tab;
- gint position = 0;
g_assert (PNL_IS_TAB_STRIP (self));
g_assert (GTK_IS_WIDGET (widget));
g_assert (GTK_IS_STACK (stack));
- gtk_container_child_get (GTK_CONTAINER (stack), widget,
- "position", &position,
- NULL);
-
- target = g_variant_new_int32 (position);
-
tab = g_object_new (PNL_TYPE_TAB,
"action-name", "tab-strip.tab",
- "action-target", target,
"edge", priv->edge,
"widget", widget,
NULL);
@@ -385,7 +421,10 @@ pnl_tab_strip_stack_remove (PnlTabStrip *self,
tab = g_object_get_data (G_OBJECT (widget), "PNL_TAB");
if (PNL_IS_TAB (tab))
- gtk_container_remove (GTK_CONTAINER (self), GTK_WIDGET (tab));
+ {
+ g_object_set_data (G_OBJECT (widget), "PNL_TAB", NULL);
+ gtk_container_remove (GTK_CONTAINER (self), GTK_WIDGET (tab));
+ }
}
GtkWidget *
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]