[totem] grilo: Use popover for the source selection
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [totem] grilo: Use popover for the source selection
- Date: Tue, 28 Jan 2014 17:05:15 +0000 (UTC)
commit a8601eed030d8a8d2e4bed32b47736b22c56cab2
Author: Bastien Nocera <hadess hadess net>
Date: Sun Jan 26 17:40:45 2014 +0100
grilo: Use popover for the source selection
https://bugzilla.gnome.org/show_bug.cgi?id=723031
src/plugins/grilo/totem-search-entry.c | 235 ++++++++++++++++++--------------
1 files changed, 135 insertions(+), 100 deletions(-)
---
diff --git a/src/plugins/grilo/totem-search-entry.c b/src/plugins/grilo/totem-search-entry.c
index cb1c674..c9645a0 100644
--- a/src/plugins/grilo/totem-search-entry.c
+++ b/src/plugins/grilo/totem-search-entry.c
@@ -38,9 +38,8 @@ static guint signals[LAST_SIGNAL] = { 0, };
struct _TotemSearchEntryPrivate {
GtkWidget *entry;
- GtkWidget *button;
- GtkWidget *menu;
- GSList *group;
+ GtkWidget *popover;
+ GtkWidget *listbox;
GdTaggedEntryTag *tag;
};
@@ -50,7 +49,7 @@ totem_search_entry_finalize (GObject *obj)
TotemSearchEntry *self = TOTEM_SEARCH_ENTRY (obj);
g_clear_object (&self->priv->tag);
- g_clear_pointer (&self->priv->group, g_slist_free);
+ g_clear_object (&self->priv->popover);
G_OBJECT_CLASS (totem_search_entry_parent_class)->finalize (obj);
}
@@ -68,10 +67,71 @@ entry_activate_cb (GtkEntry *entry,
}
static void
+tag_clicked_cb (GdTaggedEntry *entry,
+ GdTaggedEntryTag *tag,
+ TotemSearchEntry *self)
+{
+ cairo_rectangle_int_t rect;
+
+ if (gd_tagged_entry_tag_get_area (tag, &rect)) {
+ gtk_popover_set_pointing_to (GTK_POPOVER (self->priv->popover), &rect);
+ gtk_widget_show (self->priv->popover);
+ }
+}
+
+static void
+listbox_row_activated (GtkListBox *list_box,
+ GtkListBoxRow *row,
+ gpointer user_data)
+{
+ TotemSearchEntry *self = user_data;
+ GList *children, *l;
+
+ children = gtk_container_get_children (GTK_CONTAINER (list_box));
+ for (l = children; l != NULL; l = l->next) {
+ GtkWidget *check;
+
+ check = g_object_get_data (G_OBJECT (l->data), "check");
+ if (l->data == row) {
+ const char *label;
+
+ gtk_widget_set_opacity (check, 1.0);
+ label = g_object_get_data (G_OBJECT (l->data), "label");
+ gd_tagged_entry_tag_set_label (self->priv->tag, label);
+ g_object_notify (G_OBJECT (self), "selected-id");
+ } else {
+ gtk_widget_set_opacity (check, 0.0);
+ }
+ }
+ g_list_free (children);
+}
+
+static int
+sort_sources (GtkListBoxRow *row_a,
+ GtkListBoxRow *row_b,
+ gpointer user_data)
+{
+ int prio_a, prio_b;
+ const char *name_a, *name_b;
+
+ prio_a = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (row_a), "priority"));
+ prio_b = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (row_b), "priority"));
+
+ if (prio_a > prio_b)
+ return -1;
+ if (prio_b > prio_a)
+ return 1;
+
+ name_a = g_object_get_data (G_OBJECT (row_a), "label");
+ name_b = g_object_get_data (G_OBJECT (row_b), "label");
+
+ return 0 - g_utf8_collate (name_a, name_b);
+}
+
+static void
totem_search_entry_init (TotemSearchEntry *self)
{
GtkWidget *entry;
- GtkWidget *button;
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, TOTEM_TYPE_SEARCH_ENTRY, TotemSearchEntryPrivate);
@@ -85,16 +145,23 @@ totem_search_entry_init (TotemSearchEntry *self)
self->priv->entry = entry;
- /* Button */
- button = gtk_menu_button_new ();
- gtk_box_pack_start (GTK_BOX (self),
- button,
- FALSE, TRUE, 0);
- gtk_widget_show (button);
+ /* Popover */
+ self->priv->popover = gtk_popover_new (GTK_WIDGET (self));
+ gtk_popover_set_modal (GTK_POPOVER (self->priv->popover), TRUE);
+ gtk_popover_set_position (GTK_POPOVER (self->priv->popover), GTK_POS_BOTTOM);
+
+ self->priv->listbox = gtk_list_box_new ();
+ gtk_list_box_set_activate_on_single_click (GTK_LIST_BOX (self->priv->listbox), TRUE);
+ gtk_list_box_set_sort_func (GTK_LIST_BOX (self->priv->listbox), sort_sources, self, NULL);
+ gtk_widget_show (self->priv->listbox);
+ gtk_container_add (GTK_CONTAINER (self->priv->popover), self->priv->listbox);
- self->priv->button = button;
+ g_signal_connect (self->priv->listbox, "row-activated",
+ G_CALLBACK (listbox_row_activated), self);
/* Connect signals */
+ g_signal_connect (self->priv->entry, "tag-clicked",
+ G_CALLBACK (tag_clicked_cb), self);
g_signal_connect (self->priv->entry, "activate",
G_CALLBACK (entry_activate_cb), self);
}
@@ -163,73 +230,19 @@ totem_search_entry_new (void)
return g_object_new (TOTEM_TYPE_SEARCH_ENTRY, NULL);
}
-static void
-item_toggled (GtkCheckMenuItem *item,
- TotemSearchEntry *self)
+static GtkWidget *
+padded_label_new (const char *text)
{
- const char *label;
+ GtkWidget *widget;
- if (gtk_check_menu_item_get_active (item)) {
- label = g_object_get_data (G_OBJECT (item), "label");
- gd_tagged_entry_tag_set_label (self->priv->tag, label);
- g_object_notify (G_OBJECT (self), "selected-id");
- }
-}
+ widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
+ gtk_widget_set_margin_top (widget, 10);
+ gtk_widget_set_margin_bottom (widget, 10);
+ gtk_widget_set_margin_start (widget, 10);
+ gtk_widget_set_margin_end (widget, 10);
+ gtk_box_pack_start (GTK_BOX (widget), gtk_label_new (text), FALSE, FALSE, 0);
-static void
-foreach_menu_item_cb (GtkWidget *item,
- GList **list)
-{
- *list = g_list_prepend (*list, item);
-}
-
-static int
-sort_sources (gconstpointer a,
- gconstpointer b)
-{
- int prio_a, prio_b;
- const char *name_a, *name_b;
-
- prio_a = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (a), "priority"));
- prio_b = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (b), "priority"));
-
- if (prio_a > prio_b)
- return -1;
- if (prio_b > prio_a)
- return 1;
-
- name_a = g_object_get_data (G_OBJECT (a), "label");
- name_b = g_object_get_data (G_OBJECT (b), "label");
-
- return 0 - g_utf8_collate (name_a, name_b);
-}
-
-static void
-insert_item_sorted (TotemSearchEntry *self,
- int priority,
- GtkWidget *item)
-{
- GList *children = NULL;
- GList *l;
- int n;
-
- gtk_container_foreach (GTK_CONTAINER (self->priv->menu),
- (GtkCallback) foreach_menu_item_cb,
- &children);
- children = g_list_reverse (children);
- children = g_list_insert_sorted (children, item, sort_sources);
-
- for (n = 0, l = children; l != NULL; n++, l = l->next) {
- if (l->data == item)
- break;
- }
-
- g_list_free (children);
-
- gtk_menu_shell_insert (GTK_MENU_SHELL (self->priv->menu), item, n);
- if (priority == 50)
- gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
- gtk_widget_show (item);
+ return widget;
}
void
@@ -239,29 +252,42 @@ totem_search_entry_add_source (TotemSearchEntry *self,
int priority)
{
GtkWidget *item;
+ GtkWidget *check;
+ GtkWidget *box;
g_return_if_fail (TOTEM_IS_SEARCH_ENTRY (self));
- if (self->priv->menu == NULL) {
- self->priv->menu = gtk_menu_new ();
- gtk_menu_button_set_popup (GTK_MENU_BUTTON (self->priv->button),
- self->priv->menu);
+ if (self->priv->tag == NULL) {
self->priv->tag = gd_tagged_entry_tag_new (label);
gd_tagged_entry_tag_set_has_close_button (self->priv->tag, FALSE);
gd_tagged_entry_insert_tag (GD_TAGGED_ENTRY (self->priv->entry), self->priv->tag, -1);
}
- item = gtk_radio_menu_item_new_with_label (self->priv->group, label);
- self->priv->group = g_slist_prepend (self->priv->group, item);
+ item = gtk_list_box_row_new ();
+ box = padded_label_new (label);
+ gtk_container_add (GTK_CONTAINER (item), box);
+ check = gtk_image_new ();
+ gtk_image_set_from_icon_name (GTK_IMAGE (check), "object-select-symbolic", GTK_ICON_SIZE_MENU);
+ gtk_widget_set_opacity (check, 0.0);
+ g_object_set (check, "icon-size", GTK_ICON_SIZE_MENU, NULL);
+ gtk_box_pack_start (GTK_BOX (box), check, FALSE, FALSE, 0);
+ gtk_box_reorder_child (GTK_BOX (box), check, 0);
+
+ g_object_set_data (G_OBJECT (item), "check", check);
g_object_set_data_full (G_OBJECT (item), "id", g_strdup (id), g_free);
g_object_set_data_full (G_OBJECT (item), "label", g_strdup (label), g_free);
g_object_set_data (G_OBJECT (item), "priority", GINT_TO_POINTER (priority));
- g_signal_connect (item, "toggled",
- G_CALLBACK (item_toggled), self);
+ gtk_widget_show_all (item);
+ gtk_list_box_insert (GTK_LIST_BOX (self->priv->listbox), item, -1);
- insert_item_sorted (self, priority, item);
+ /* Is this the local one? */
+ if (priority == 50) {
+ listbox_row_activated (GTK_LIST_BOX (self->priv->listbox),
+ GTK_LIST_BOX_ROW (item),
+ self);
+ }
}
void
@@ -280,8 +306,7 @@ totem_search_entry_remove_source (TotemSearchEntry *self,
num_items = 1;
if (num_items == 0) {
- gtk_menu_button_set_popup (GTK_MENU_BUTTON (self->priv->button), NULL);
- g_clear_object (&self->priv->menu);
+ g_clear_object (&self->priv->popover);
gd_tagged_entry_remove_tag (GD_TAGGED_ENTRY (self->priv->entry), self->priv->tag);
g_clear_object (&self->priv->tag);
}
@@ -298,42 +323,52 @@ totem_search_entry_get_text (TotemSearchEntry *self)
const char *
totem_search_entry_get_selected_id (TotemSearchEntry *self)
{
- GSList *l;
+ GList *children, *l;
+ const char *id = NULL;
g_return_val_if_fail (TOTEM_IS_SEARCH_ENTRY (self), NULL);
+ children = gtk_container_get_children (GTK_CONTAINER (self->priv->listbox));
+ for (l = children; l != NULL; l = l->next) {
+ GtkWidget *check;
- for (l = self->priv->group ; l != NULL; l = l->next) {
- GtkCheckMenuItem *item = l->data;
-
- if (gtk_check_menu_item_get_active (item) != FALSE)
- return g_object_get_data (G_OBJECT (item), "id");
+ check = g_object_get_data (G_OBJECT (l->data), "check");
+ if (gtk_widget_get_opacity (check) == 1.0) {
+ id = g_object_get_data (G_OBJECT (l->data), "id");
+ break;
+ }
}
+ g_list_free (children);
- return NULL;
+ return id;
}
void
totem_search_entry_set_selected_id (TotemSearchEntry *self,
const char *id)
{
- GSList *l;
+ GList *children, *l;
g_return_if_fail (TOTEM_IS_SEARCH_ENTRY (self));
g_return_if_fail (id != NULL);
- for (l = self->priv->group ; l != NULL; l = l->next) {
- GtkCheckMenuItem *item = l->data;
+ children = gtk_container_get_children (GTK_CONTAINER (self->priv->listbox));
+ for (l = children; l != NULL; l = l->next) {
const char *item_id;
- item_id = g_object_get_data (G_OBJECT (item), "id");
+ item_id = g_object_get_data (G_OBJECT (l->data), "id");
if (g_strcmp0 (item_id, id) == 0) {
- gtk_check_menu_item_set_active (item, TRUE);
- return;
+ listbox_row_activated (GTK_LIST_BOX (self->priv->listbox),
+ GTK_LIST_BOX_ROW (l->data),
+ self);
+ goto end;
}
}
g_warning ("Could not find ID '%s' in TotemSearchEntry %p",
id, self);
+
+end:
+ g_list_free (children);
}
GtkEntry *
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]