Commit e59c2874 authored by Paolo Borelli's avatar Paolo Borelli Committed by Matthias Clasen

Add a needs-attention child property to GtkStack

The child property is watched by the StackSwicther which in turns sets a
needs-attention css class on the corresponding button, so that the theme
can for instance show a throbbing animation if one of the hidden pages
needs the user attention.

https://bugzilla.gnome.org/show_bug.cgi?id=707153
parent 8d83d989
......@@ -82,7 +82,8 @@ enum
CHILD_PROP_NAME,
CHILD_PROP_TITLE,
CHILD_PROP_ICON_NAME,
CHILD_PROP_POSITION
CHILD_PROP_POSITION,
CHILD_PROP_NEEDS_ATTENTION
};
typedef struct _GtkStackChildInfo GtkStackChildInfo;
......@@ -92,6 +93,7 @@ struct _GtkStackChildInfo {
gchar *name;
gchar *title;
gchar *icon_name;
gboolean needs_attention;
};
typedef struct {
......@@ -416,6 +418,23 @@ gtk_stack_class_init (GtkStackClass *klass)
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.
*
* Since: 3.12
*/
gtk_container_class_install_child_property (container_class, CHILD_PROP_NEEDS_ATTENTION,
g_param_spec_boolean ("needs-attention",
P_("Needs Attention"),
P_("Whether this page needs attention"),
FALSE,
GTK_PARAM_READWRITE));
}
/**
......@@ -548,6 +567,10 @@ gtk_stack_get_child_property (GtkContainer *container,
g_value_set_int (value, i);
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;
......@@ -615,6 +638,11 @@ gtk_stack_set_child_property (GtkContainer *container,
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 (container, child, "needs-attention");
break;
default:
GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
break;
......@@ -1001,6 +1029,7 @@ gtk_stack_add (GtkContainer *container,
child_info->name = NULL;
child_info->title = NULL;
child_info->icon_name = NULL;
child_info->needs_attention = FALSE;
priv->children = g_list_append (priv->children, child_info);
......
......@@ -68,6 +68,7 @@ gtk_stack_switcher_init (GtkStackSwitcher *switcher)
priv->buttons = g_hash_table_new (g_direct_hash, g_direct_equal);
context = gtk_widget_get_style_context (GTK_WIDGET (switcher));
gtk_style_context_add_class (context, "stack-switcher");
gtk_style_context_add_class (context, GTK_STYLE_CLASS_LINKED);
gtk_orientable_set_orientation (GTK_ORIENTABLE (switcher), GTK_ORIENTATION_HORIZONTAL);
......@@ -138,6 +139,25 @@ 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_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
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,
......@@ -165,6 +185,8 @@ update_button (GtkStackSwitcher *self,
g_free (title);
g_free (icon_name);
update_needs_attention (widget, button, priv->stack);
}
static void
......@@ -201,6 +223,20 @@ on_position_updated (GtkWidget *widget,
gtk_box_reorder_child (GTK_BOX (self), button, position);
}
static void
on_needs_attention_updated (GtkWidget *widget,
GParamSpec *pspec,
GtkStackSwitcher *self)
{
GtkWidget *button;
GtkStackSwitcherPrivate *priv;
priv = gtk_stack_switcher_get_instance_private (self);
button = g_hash_table_lookup (priv->buttons, widget);
update_button (self, widget, button);
}
static void
add_child (GtkStackSwitcher *self,
GtkWidget *widget)
......@@ -230,6 +266,7 @@ add_child (GtkStackSwitcher *self,
g_signal_connect (widget, "child-notify::title", G_CALLBACK (on_title_icon_updated), self);
g_signal_connect (widget, "child-notify::icon-name", G_CALLBACK (on_title_icon_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_hash_table_insert (priv->buttons, widget, button);
}
......@@ -269,6 +306,10 @@ on_child_changed (GtkWidget *widget,
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
priv->in_child_changed = FALSE;
}
g_hash_table_foreach (priv->buttons,
(GHFunc)update_needs_attention,
priv->stack);
}
static void
......
......@@ -754,6 +754,17 @@ struct _GtkStyleContextClass
*/
#define GTK_STYLE_CLASS_TITLEBAR "titlebar"
/**
* GTK_STYLE_CLASS_NEEDS_ATTENTION:
*
* A CSS class used when an element needs the user attention,
* for instance a button in a stack switcher corresponding to
* a hidden page that changed state.
*
* Since: 3.12
*/
#define GTK_STYLE_CLASS_NEEDS_ATTENTION "needs-attention"
/* Predefined set of widget regions */
/**
......
......@@ -144,6 +144,7 @@ main (gint argc,
gtk_container_child_set (GTK_CONTAINER (stack), w2,
"name", "2",
"title", "2",
"needs-attention", TRUE,
NULL);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment