diff options
author | Charles Kerr <charles.kerr@canonical.com> | 2013-06-24 02:34:25 +0000 |
---|---|---|
committer | Tarmac <Unknown> | 2013-06-24 02:34:25 +0000 |
commit | 49b6a15237aad7359f417724288acc8d285e9d71 (patch) | |
tree | a0cc26abb75a9d4acfd14d4ea0f490d611dc8e7a | |
parent | 8f8d487e5a29c1d483e9edd2067e17e4b8c0e205 (diff) | |
parent | db32e752ebd0a368e30d65ffd9c2f360a473fecc (diff) | |
download | ayatana-ido-49b6a15237aad7359f417724288acc8d285e9d71.tar.gz ayatana-ido-49b6a15237aad7359f417724288acc8d285e9d71.tar.bz2 ayatana-ido-49b6a15237aad7359f417724288acc8d285e9d71.zip |
Adds support for the guest menuitem.
A guest menuitem is the same as a user menuitem except for how it uses its action's state, so instead of adding a new class, this patch adds a new factory method (ido_guest_menu_item_new_from_model) and private action state handler.
Approved by Ted Gould, PS Jenkins bot.
-rw-r--r-- | debian/libido3-0.1-0.symbols | 2 | ||||
-rw-r--r-- | example/menus.c | 82 | ||||
-rw-r--r-- | src/idomenuitemfactory.c | 3 | ||||
-rw-r--r-- | src/idousermenuitem.c | 239 | ||||
-rw-r--r-- | src/idousermenuitem.h | 12 |
5 files changed, 213 insertions, 125 deletions
diff --git a/debian/libido3-0.1-0.symbols b/debian/libido3-0.1-0.symbols index d253c59..d245d43 100644 --- a/debian/libido3-0.1-0.symbols +++ b/debian/libido3-0.1-0.symbols @@ -26,6 +26,7 @@ libido3-0.1.so.0 libido3-0.1-0 #MINVER# ido_entry_menu_item_get_entry@Base 0.1.0 ido_entry_menu_item_get_type@Base 0.1.0 ido_entry_menu_item_new@Base 0.1.0 + ido_guest_menu_item_new_from_model@Base 0replaceme ido_init@Base 13.10.0daily13.06.19 ido_location_menu_item_get_type@Base 13.10.0daily13.06.19 ido_location_menu_item_new@Base 13.10.0daily13.06.19 @@ -86,6 +87,7 @@ libido3-0.1.so.0 libido3-0.1-0 #MINVER# ido_user_menu_item_new_from_model@Base 13.10.0daily13.06.19 ido_user_menu_item_set_current_user@Base 13.10.0daily13.06.19 ido_user_menu_item_set_icon@Base 13.10.0daily13.06.19 + ido_user_menu_item_set_icon_from_file@Base 0replaceme ido_user_menu_item_set_label@Base 13.10.0daily13.06.19 ido_user_menu_item_set_logged_in@Base 13.10.0daily13.06.19 ido_media_player_menu_item_get_type@Base 0replaceme diff --git a/example/menus.c b/example/menus.c index 1675f45..d30f920 100644 --- a/example/menus.c +++ b/example/menus.c @@ -19,6 +19,28 @@ slider_released (GtkWidget *widget, gpointer user_data) g_print ("released\n"); } +static GtkWidget * +create_user_menu (const char * username, + const char * filename, + gboolean is_logged_in, + gboolean is_active) +{ + GtkWidget * ret; + GFile * file = filename ? g_file_new_for_path (filename) : NULL; + GIcon * icon = file ? g_file_icon_new (file) : NULL; + + ret = g_object_new (IDO_USER_MENU_ITEM_TYPE, + "label", username, + "icon", icon, + "is-logged-in", is_logged_in, + "is-current-user", is_active, + NULL); + + g_clear_object (&icon); + g_clear_object (&file); + return ret; +} + int main (int argc, char *argv[]) { @@ -100,44 +122,28 @@ main (int argc, char *argv[]) *** Users **/ - menuitem = gtk_separator_menu_item_new (); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); - - menuitem = ido_user_menu_item_new (); - g_object_set (menuitem, - "label", "Guest", - "icon-filename", NULL, - "is-logged-in", FALSE, - "is-current-user", FALSE, - NULL); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); - - menuitem = ido_user_menu_item_new (); - g_object_set (menuitem, - "label", "Bobby Fischer", - "icon-filename", "/usr/share/pixmaps/faces/chess.jpg", - "is-logged-in", FALSE, - "is-current-user", FALSE, - NULL); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); - - menuitem = ido_user_menu_item_new (); - g_object_set (menuitem, - "label", "Linus Torvalds", - "icon-filename", "/usr/share/pixmaps/faces/penguin.jpg", - "is-logged-in", TRUE, - "is-current-user", FALSE, - NULL); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); - - menuitem = ido_user_menu_item_new (); - g_object_set (menuitem, "label", "Mark Shuttleworth", - "icon-filename", "/usr/share/pixmaps/faces/astronaut.jpg", - "is-logged-in", TRUE, - "is-current-user", TRUE, - NULL); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); - + gtk_menu_shell_append (GTK_MENU_SHELL (menu), + create_user_menu ("Guest", + NULL, + FALSE, FALSE)); + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), + create_user_menu ("Bobby Fischer", + "/usr/share/pixmaps/faces/chess.jpg", + FALSE, FALSE)); + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), + create_user_menu ("Linus Torvalds", + "/usr/share/pixmaps/faces/penguin.jpg", + TRUE, FALSE)); + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), + create_user_menu ("Mark Shuttleworth", + "/usr/share/pixmaps/faces/astronaut.jpg", + TRUE, TRUE)); + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), ido_user_menu_item_new ()); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new ()); /* Add the menubar */ gtk_menu_shell_append (GTK_MENU_SHELL (menubar), root); diff --git a/src/idomenuitemfactory.c b/src/idomenuitemfactory.c index 650c95f..5ded309 100644 --- a/src/idomenuitemfactory.c +++ b/src/idomenuitemfactory.c @@ -54,6 +54,9 @@ ido_menu_item_factory_create_menu_item (UbuntuMenuItemFactory *factory, if (g_str_equal (type, "indicator.user-menu-item")) item = ido_user_menu_item_new_from_model (menuitem, actions); + if (g_str_equal (type, "indicator.guest-menu-item")) + item = ido_guest_menu_item_new_from_model (menuitem, actions); + else if (g_str_equal (type, "com.canonical.indicator.calendar")) item = ido_calendar_menu_item_new_from_model (menuitem, actions); diff --git a/src/idousermenuitem.c b/src/idousermenuitem.c index 4c6e81d..e6ba710 100644 --- a/src/idousermenuitem.c +++ b/src/idousermenuitem.c @@ -34,7 +34,7 @@ enum { PROP_0, PROP_LABEL, - PROP_ICON_FILENAME, + PROP_ICON, PROP_IS_LOGGED_IN, PROP_IS_CURRENT_USER, PROP_LAST @@ -51,7 +51,7 @@ struct _IdoUserMenuItemPrivate gboolean is_logged_in; gboolean is_current_user; gchar * label; - gchar * icon_filename; + GIcon * icon; }; G_DEFINE_TYPE (IdoUserMenuItem, ido_user_menu_item, GTK_TYPE_MENU_ITEM); @@ -76,8 +76,8 @@ my_get_property (GObject * o, g_value_set_string (value, self->priv->label); break; - case PROP_ICON_FILENAME: - g_value_set_string (value, self->priv->icon_filename); + case PROP_ICON: + g_value_set_object (value, self->priv->icon); break; case PROP_IS_LOGGED_IN: @@ -108,8 +108,8 @@ my_set_property (GObject * o, ido_user_menu_item_set_label (self, g_value_get_string (value)); break; - case PROP_ICON_FILENAME: - ido_user_menu_item_set_icon (self, g_value_get_string (value)); + case PROP_ICON: + ido_user_menu_item_set_icon (self, g_value_get_object (value)); break; case PROP_IS_LOGGED_IN: @@ -130,6 +130,10 @@ my_set_property (GObject * o, static void my_dispose (GObject *object) { + IdoUserMenuItem * self = IDO_USER_MENU_ITEM (object); + + g_clear_object (&self->priv->icon); + G_OBJECT_CLASS (ido_user_menu_item_parent_class)->dispose (object); } @@ -139,7 +143,6 @@ my_finalize (GObject *object) IdoUserMenuItem * self = IDO_USER_MENU_ITEM (object); g_free (self->priv->label); - g_free (self->priv->icon_filename); G_OBJECT_CLASS (ido_user_menu_item_parent_class)->finalize (object); } @@ -167,11 +170,11 @@ ido_user_menu_item_class_init (IdoUserMenuItemClass *klass) "J. Random User", prop_flags); - properties[PROP_ICON_FILENAME] = g_param_spec_string ("icon-filename", - "The icon's filename", - "The icon to display", - NULL, - prop_flags); + properties[PROP_ICON] = g_param_spec_object ("icon", + "Icon", + "The user's GIcon", + G_TYPE_OBJECT, + prop_flags); properties[PROP_IS_LOGGED_IN] = g_param_spec_boolean ("is-logged-in", "is logged in", @@ -287,49 +290,31 @@ ido_user_menu_item_primitive_draw_cb_gtk_3 (GtkWidget * widget, ***/ void -ido_user_menu_item_set_icon (IdoUserMenuItem * self, const char * icon_filename) +ido_user_menu_item_set_icon (IdoUserMenuItem * self, GIcon * icon) { - gboolean updated = FALSE; IdoUserMenuItemPrivate * p = self->priv; GtkImage * image = GTK_IMAGE (p->user_image); - /* make a private copy of the icon name */ - g_free (p->icon_filename); - self->priv->icon_filename = g_strdup (icon_filename); + g_clear_object (&p->icon); - /* now try to use it */ - if (icon_filename && *icon_filename) - { - int width = 18; /* arbitrary default values */ - int height = 18; - GError * err = NULL; - GdkPixbuf * pixbuf = NULL; - - /* load the image */ - gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, &height); - pixbuf = gdk_pixbuf_new_from_file_at_size (icon_filename, - width, height, &err); - if (err == NULL) - { - gtk_image_set_from_pixbuf (image, pixbuf); - g_object_unref (pixbuf); - updated = TRUE; - } - else - { - g_warning ("Couldn't load the image \"%s\": %s", - icon_filename, err->message); - g_clear_error (&err); - } - } + if (icon != NULL) + g_object_ref (icon); + else + icon = g_themed_icon_new_with_default_fallbacks (FALLBACK_ICON_NAME); - /* as a fallback, use the default user icon */ - if (!updated) - { - gtk_image_set_from_icon_name (image, - FALLBACK_ICON_NAME, - GTK_ICON_SIZE_MENU); - } + gtk_image_set_from_gicon (image, icon, GTK_ICON_SIZE_MENU); +} + +void +ido_user_menu_item_set_icon_from_file (IdoUserMenuItem * self, const char * filename) +{ + GFile * file = filename ? g_file_new_for_path (filename) : NULL; + GIcon * icon = file ? g_file_icon_new (file) : NULL; + + ido_user_menu_item_set_icon (self, icon); + + g_clear_object (&icon); + g_clear_object (&file); } void @@ -357,6 +342,86 @@ ido_user_menu_item_new (void) return GTK_WIDGET (g_object_new (IDO_USER_MENU_ITEM_TYPE, NULL)); } +/*** +**** +***/ + +/** + * This is a helper function for creating user menuitems for both + * "indicator.user-menu-item" and "indicator.guest-menu-item", + * since they only differ in how they use their action's state. + */ +static GtkMenuItem * +user_menu_item_new_from_model (GMenuItem * menuitem, + GActionGroup * actions, + GCallback state_changed_callback) +{ + guint i; + guint n; + IdoUserMenuItem * ido_user; + gchar * str; + gchar * action; + GVariant * v; + GParameter parameters[4]; + + /* create the ido_user */ + + n = 0; + + if (g_menu_item_get_attribute (menuitem, G_MENU_ATTRIBUTE_LABEL, "s", &str)) + { + GParameter p = { "label", G_VALUE_INIT }; + g_value_init (&p.value, G_TYPE_STRING); + g_value_take_string (&p.value, str); + parameters[n++] = p; + } + + if ((v = g_menu_item_get_attribute_value (menuitem, G_MENU_ATTRIBUTE_ICON, NULL))) + { + GParameter p = { "icon", G_VALUE_INIT }; + GIcon * icon = g_icon_deserialize (v); + g_value_init (&p.value, G_TYPE_OBJECT); + g_value_take_object (&p.value, icon); + g_variant_unref (v); + parameters[n++] = p; + } + + g_assert (n <= G_N_ELEMENTS (parameters)); + ido_user = g_object_newv (IDO_USER_MENU_ITEM_TYPE, n, parameters); + + for (i=0; i<n; i++) + g_value_unset (¶meters[i].value); + + /* gie it an ActionHelper */ + + if (g_menu_item_get_attribute (menuitem, G_MENU_ATTRIBUTE_ACTION, "s", &action)) + { + IdoActionHelper *helper; + GVariant *target; + + target = g_menu_item_get_attribute_value (menuitem, G_MENU_ATTRIBUTE_TARGET, G_VARIANT_TYPE_ANY); + + helper = ido_action_helper_new (GTK_WIDGET (ido_user), actions, action, target); + g_signal_connect (helper, "action-state-changed", + state_changed_callback, NULL); + + g_signal_connect_object (ido_user, "activate", + G_CALLBACK (ido_action_helper_activate), + helper, G_CONNECT_SWAPPED); + g_signal_connect_swapped (ido_user, "destroy", G_CALLBACK (g_object_unref), helper); + + if (target) + g_variant_unref (target); + g_free (action); + } + + return GTK_MENU_ITEM (ido_user); +} + +/*** +**** indicator.user-menu-item handler +***/ + /** * user_menu_item_state_changed: * @@ -370,22 +435,21 @@ user_menu_item_state_changed (IdoActionHelper *helper, GVariant *state, gpointer user_data) { + gboolean is_logged_in = FALSE; + gboolean is_current_user = FALSE; IdoUserMenuItem *item; GVariant *target; GVariant *v; item = IDO_USER_MENU_ITEM (ido_action_helper_get_widget (helper)); - ido_user_menu_item_set_current_user (item, FALSE); - ido_user_menu_item_set_logged_in (item, FALSE); - target = ido_action_helper_get_action_target (helper); g_return_if_fail (g_variant_is_of_type (target, G_VARIANT_TYPE_STRING)); if ((v = g_variant_lookup_value (state, "active-user", G_VARIANT_TYPE_STRING))) { if (g_variant_equal (v, target)) - ido_user_menu_item_set_current_user (item, TRUE); + is_current_user = TRUE; g_variant_unref (v); } @@ -399,12 +463,16 @@ user_menu_item_state_changed (IdoActionHelper *helper, while ((user = g_variant_iter_next_value (&it))) { if (g_variant_equal (user, target)) - ido_user_menu_item_set_logged_in (item, TRUE); + is_logged_in = TRUE; + g_variant_unref (user); } g_variant_unref (v); } + + ido_user_menu_item_set_logged_in (item, is_logged_in); + ido_user_menu_item_set_current_user (item, is_current_user); } /** @@ -419,39 +487,44 @@ GtkMenuItem * ido_user_menu_item_new_from_model (GMenuItem *menuitem, GActionGroup *actions) { - IdoUserMenuItem *item; - gchar *label; - gchar *action; - - item = IDO_USER_MENU_ITEM (ido_user_menu_item_new ()); - - if (g_menu_item_get_attribute (menuitem, "label", "s", &label)) - { - ido_user_menu_item_set_label (item, label); - g_free (label); - } - - if (g_menu_item_get_attribute (menuitem, "action", "s", &action)) - { - IdoActionHelper *helper; - GVariant *target; + return user_menu_item_new_from_model (menuitem, + actions, + G_CALLBACK(user_menu_item_state_changed)); +} - target = g_menu_item_get_attribute_value (menuitem, "target", G_VARIANT_TYPE_ANY); +/*** +**** indicator.guest-menu-item handler +***/ - helper = ido_action_helper_new (GTK_WIDGET (item), actions, action, target); - g_signal_connect (helper, "action-state-changed", - G_CALLBACK (user_menu_item_state_changed), NULL); +static void +guest_menu_item_state_changed (IdoActionHelper *helper, + GVariant *state, + gpointer user_data) +{ + IdoUserMenuItem * item = IDO_USER_MENU_ITEM (ido_action_helper_get_widget (helper)); + gboolean b; - g_signal_connect_object (item, "activate", - G_CALLBACK (ido_action_helper_activate), - helper, G_CONNECT_SWAPPED); - g_signal_connect_swapped (item, "destroy", G_CALLBACK (g_object_unref), helper); + if ((g_variant_lookup (state, "is-active", "b", &b))) + ido_user_menu_item_set_current_user (item, b); - if (target) - g_variant_unref (target); - g_free (action); - } + if ((g_variant_lookup (state, "is-logged-in", "b", &b))) + ido_user_menu_item_set_current_user (item, b); +} - return GTK_MENU_ITEM (item); +/** + * ido_guest_menu_item_new_from_model: + * + * Creates an #IdoUserMenuItem. If @menuitem contains an action, the + * widget is bound to that action in @actions. + * + * Returns: (transfer full): a new #IdoUserMenuItem + */ +GtkMenuItem * +ido_guest_menu_item_new_from_model (GMenuItem *menuitem, + GActionGroup *actions) +{ + return user_menu_item_new_from_model (menuitem, + actions, + G_CALLBACK(guest_menu_item_state_changed)); } diff --git a/src/idousermenuitem.h b/src/idousermenuitem.h index d51f6c7..d1d5729 100644 --- a/src/idousermenuitem.h +++ b/src/idousermenuitem.h @@ -56,14 +56,18 @@ GType ido_user_menu_item_get_type (void) G_GNUC_CONST; GtkWidget* ido_user_menu_item_new(void); -void ido_user_menu_item_set_icon (IdoUserMenuItem * self, const char * icon_name); -void ido_user_menu_item_set_logged_in (IdoUserMenuItem * self, gboolean is_logged_in); -void ido_user_menu_item_set_current_user (IdoUserMenuItem * self, gboolean is_current_user); -void ido_user_menu_item_set_label (IdoUserMenuItem * self, const char * label); +void ido_user_menu_item_set_icon (IdoUserMenuItem * self, GIcon * icon); +void ido_user_menu_item_set_icon_from_file (IdoUserMenuItem * self, const char * filename); +void ido_user_menu_item_set_logged_in (IdoUserMenuItem * self, gboolean is_logged_in); +void ido_user_menu_item_set_current_user (IdoUserMenuItem * self, gboolean is_current_user); +void ido_user_menu_item_set_label (IdoUserMenuItem * self, const char * label); GtkMenuItem * ido_user_menu_item_new_from_model (GMenuItem *menuitem, GActionGroup *actions); +GtkMenuItem * ido_guest_menu_item_new_from_model (GMenuItem *menuitem, + GActionGroup *actions); + G_END_DECLS #endif |