[gnome-builder/wip/chergert/debugger] pnl: use indexes rather than position child properties
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/chergert/debugger] pnl: use indexes rather than position child properties
- Date: Fri, 14 Apr 2017 21:13:08 +0000 (UTC)
commit 05a760d812b0c95ca45ba6ea7a50996004d50f72
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]