[rhythmbox] button-bar: watch for model changes properly
- From: Jonathan Matthew <jmatthew src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rhythmbox] button-bar: watch for model changes properly
- Date: Wed, 26 Jun 2013 13:31:40 +0000 (UTC)
commit bf2a1bec0b48b8a0c77f6a5d9877e2bfc872eb4b
Author: Jonathan Matthew <jonathan d14n org>
Date: Wed Jun 26 23:24:33 2013 +1000
button-bar: watch for model changes properly
The top level GMenu doesn't notify of changes to its nested children, so we
need to watch all of the GMenu instances that make up the button bar. On
changes we disconnect and reconnect all the signal handlers.
The buttons and separators added to the grid need to be shown, otherwise items
added after the bar is shown initially don't appear.
Adding a separator at the start of the bar creates an ugly effect that sort of
looks like an extension of the GtkPaned handle, so we don't do that.
widgets/rb-button-bar.c | 60 +++++++++++++++++++++++++++++++++++-----------
1 files changed, 45 insertions(+), 15 deletions(-)
---
diff --git a/widgets/rb-button-bar.c b/widgets/rb-button-bar.c
index b8578e0..6bf73d2 100644
--- a/widgets/rb-button-bar.c
+++ b/widgets/rb-button-bar.c
@@ -35,12 +35,14 @@
static void rb_button_bar_class_init (RBButtonBarClass *klass);
static void rb_button_bar_init (RBButtonBar *bar);
+static void build_button_bar (RBButtonBar *bar);
+
struct _RBButtonBarPrivate
{
GObject *target;
GtkSizeGroup *size_group;
GMenuModel *model;
- guint item_change_id;
+ GHashTable *handlers;
int position;
};
@@ -54,12 +56,30 @@ enum {
};
static void
+clear_handlers (RBButtonBar *bar)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+
+ g_hash_table_iter_init (&iter, bar->priv->handlers);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ gulong id = (gulong)key;
+ g_signal_handler_disconnect (value, id);
+ }
+
+ g_hash_table_remove_all (bar->priv->handlers);
+}
+
+static void
clear_button_bar (RBButtonBar *bar)
{
GList *c, *l;
c = gtk_container_get_children (GTK_CONTAINER (bar));
for (l = c; l != NULL; l = l->next) {
+ if (GTK_IS_LABEL (l->data))
+ continue;
+
gtk_size_group_remove_widget (bar->priv->size_group, l->data);
gtk_container_remove (GTK_CONTAINER (bar), l->data);
}
@@ -76,10 +96,22 @@ signal_button_clicked_cb (GtkButton *button, RBButtonBar *bar)
g_signal_emit (bar->priv->target, signal_id, 0);
}
+static void
+items_changed_cb (GMenuModel *model, int position, int added, int removed, RBButtonBar *bar)
+{
+ clear_handlers (bar);
+ clear_button_bar (bar);
+ build_button_bar (bar);
+}
+
static gboolean
append_menu (RBButtonBar *bar, GMenuModel *menu, gboolean need_separator)
{
int i;
+ gulong id;
+
+ id = g_signal_connect (menu, "items-changed", G_CALLBACK (items_changed_cb), bar);
+ g_hash_table_insert (bar->priv->handlers, (gpointer)id, g_object_ref (menu));
for (i = 0; i < g_menu_model_get_n_items (menu); i++) {
char *label_text;
@@ -101,8 +133,11 @@ append_menu (RBButtonBar *bar, GMenuModel *menu, gboolean need_separator)
if (need_separator) {
GtkWidget *sep;
- sep = gtk_separator_new (GTK_ORIENTATION_VERTICAL);
- gtk_grid_attach (GTK_GRID (bar), sep, bar->priv->position++, 0, 1, 1);
+ if (bar->priv->position > 0) {
+ sep = gtk_separator_new (GTK_ORIENTATION_VERTICAL);
+ gtk_widget_show (sep);
+ gtk_grid_attach (GTK_GRID (bar), sep, bar->priv->position++, 0, 1, 1);
+ }
need_separator = FALSE;
}
@@ -180,6 +215,7 @@ append_menu (RBButtonBar *bar, GMenuModel *menu, gboolean need_separator)
g_object_set_data_full (G_OBJECT (button), "rb-accel", accel, (GDestroyNotify)
g_free);
}
+ gtk_widget_show_all (button);
gtk_size_group_add_widget (bar->priv->size_group, button);
gtk_grid_attach (GTK_GRID (bar), button, bar->priv->position++, 0, 1, 1);
@@ -198,15 +234,10 @@ build_button_bar (RBButtonBar *bar)
waste = gtk_label_new ("");
gtk_widget_set_hexpand (waste, TRUE);
+ gtk_widget_show (waste);
gtk_grid_attach (GTK_GRID (bar), waste, bar->priv->position++, 0, 1, 1);
}
-static void
-items_changed_cb (GMenuModel *model, int position, int added, int removed, RBButtonBar *bar)
-{
- clear_button_bar (bar);
- build_button_bar (bar);
-}
static void
impl_constructed (GObject *object)
@@ -222,7 +253,8 @@ impl_constructed (GObject *object)
bar->priv->size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
- bar->priv->item_change_id = g_signal_connect (bar->priv->model, "items-changed", G_CALLBACK
(items_changed_cb), bar);
+ bar->priv->handlers = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref);
+
build_button_bar (bar);
}
@@ -230,11 +262,9 @@ static void
impl_dispose (GObject *object)
{
RBButtonBar *bar = RB_BUTTON_BAR (object);
-
- if (bar->priv->model != NULL) {
- g_signal_handler_disconnect (bar->priv->model, bar->priv->item_change_id);
- g_clear_object (&bar->priv->model);
- }
+
+ clear_handlers (bar);
+ g_clear_object (&bar->priv->model);
G_OBJECT_CLASS (rb_button_bar_parent_class)->dispose (object);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]