aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Uebernickel <lars.uebernickel@canonical.com>2012-01-14 23:51:10 +0100
committerLars Uebernickel <lars.uebernickel@canonical.com>2012-01-14 23:51:10 +0100
commit1e56f31341ecdb60456929a3d6d07bb16409b399 (patch)
tree8c0946f0345af7324b1a217d33e9dad2fff0b4ae
parent1b671f1d837a97fb60fe03958f6e1b704981607a (diff)
downloadayatana-indicator-printers-1e56f31341ecdb60456929a3d6d07bb16409b399.tar.gz
ayatana-indicator-printers-1e56f31341ecdb60456929a3d6d07bb16409b399.tar.bz2
ayatana-indicator-printers-1e56f31341ecdb60456929a3d6d07bb16409b399.zip
Add the possibility to set an icon on indicator-menu-item
-rw-r--r--src/indicator-menu-item.c83
-rw-r--r--src/indicator-menu-item.h5
-rw-r--r--src/indicator-printers-menu.c1
-rw-r--r--src/indicator-printers.c77
4 files changed, 165 insertions, 1 deletions
diff --git a/src/indicator-menu-item.c b/src/indicator-menu-item.c
index 72faad6..afdf980 100644
--- a/src/indicator-menu-item.c
+++ b/src/indicator-menu-item.c
@@ -11,6 +11,7 @@ G_DEFINE_TYPE (IndicatorMenuItem, indicator_menu_item, GTK_TYPE_MENU_ITEM)
struct _IndicatorMenuItemPrivate
{
+ GtkImage *image;
GtkWidget *label;
GtkWidget *right_label;
gboolean right_is_lozenge;
@@ -19,6 +20,8 @@ struct _IndicatorMenuItemPrivate
enum {
PROP_0,
+ PROP_ICON,
+ PROP_ICON_NAME,
PROP_LABEL,
PROP_RIGHT,
PROP_RIGHT_IS_LOZENGE,
@@ -99,10 +102,19 @@ indicator_menu_item_get_property (GObject *object,
GValue *value,
GParamSpec *pspec)
{
+ IndicatorMenuItem *self = INDICATOR_MENU_ITEM (object);
IndicatorMenuItemPrivate *priv = MENU_ITEM_PRIVATE (object);
switch (property_id)
{
+ case PROP_ICON:
+ g_value_set_object (value, indicator_menu_item_get_icon (self));
+ break;
+
+ case PROP_ICON_NAME:
+ g_value_set_string (value, indicator_menu_item_get_icon_name (self));
+ break;
+
case PROP_LABEL:
g_value_set_string (value, gtk_label_get_label (GTK_LABEL (priv->label)));
break;
@@ -131,6 +143,16 @@ indicator_menu_item_set_property (GObject *object,
switch (property_id)
{
+ case PROP_ICON:
+ indicator_menu_item_set_icon (INDICATOR_MENU_ITEM (object),
+ g_value_get_object (value));
+ break;
+
+ case PROP_ICON_NAME:
+ indicator_menu_item_set_icon_name (INDICATOR_MENU_ITEM (object),
+ g_value_get_string (value));
+ break;
+
case PROP_LABEL:
indicator_menu_item_set_label (INDICATOR_MENU_ITEM (object),
g_value_get_string (value));
@@ -158,6 +180,7 @@ indicator_menu_item_dispose (GObject *object)
{
IndicatorMenuItemPrivate *priv = MENU_ITEM_PRIVATE (object);
+ g_clear_object (&priv->image);
g_clear_object (&priv->label);
g_clear_object (&priv->right_label);
@@ -176,6 +199,18 @@ indicator_menu_item_class_init (IndicatorMenuItemClass *klass)
object_class->set_property = indicator_menu_item_set_property;
object_class->dispose = indicator_menu_item_dispose;
+ properties[PROP_ICON] = g_param_spec_object ("icon",
+ "Icon",
+ "Icon for this menu item",
+ GDK_TYPE_PIXBUF,
+ G_PARAM_READWRITE);
+
+ properties[PROP_ICON_NAME] = g_param_spec_string ("icon-name",
+ "Icon name",
+ "Name of the themed icon",
+ "",
+ G_PARAM_READWRITE);
+
properties[PROP_LABEL] = g_param_spec_string ("label",
"Label",
"The text for the main label",
@@ -211,6 +246,10 @@ indicator_menu_item_init (IndicatorMenuItem *self)
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, spacing);
+ priv->image = g_object_new (GTK_TYPE_IMAGE, NULL);
+ g_object_ref_sink (priv->image);
+ gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (priv->image), FALSE, FALSE, 0);
+
priv->label = g_object_new (GTK_TYPE_LABEL,
"xalign", 0.0,
NULL);
@@ -265,3 +304,47 @@ indicator_menu_item_set_right (IndicatorMenuItem *self,
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_RIGHT]);
}
+
+GdkPixbuf *
+indicator_menu_item_get_icon (IndicatorMenuItem *self)
+{
+ IndicatorMenuItemPrivate *priv = MENU_ITEM_PRIVATE (self);
+ if (gtk_image_get_storage_type (priv->image) == GTK_IMAGE_PIXBUF)
+ return gtk_image_get_pixbuf (priv->image);
+ else
+ return NULL;
+}
+
+
+void
+indicator_menu_item_set_icon (IndicatorMenuItem *self,
+ GdkPixbuf *icon)
+{
+ IndicatorMenuItemPrivate *priv = MENU_ITEM_PRIVATE (self);
+ gtk_image_set_from_pixbuf (priv->image, icon);
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ICON]);
+}
+
+
+const gchar *
+indicator_menu_item_get_icon_name (IndicatorMenuItem *self)
+{
+ IndicatorMenuItemPrivate *priv = MENU_ITEM_PRIVATE (self);
+ const gchar *name = NULL;
+
+ if (gtk_image_get_storage_type (priv->image) == GTK_IMAGE_ICON_NAME)
+ gtk_image_get_icon_name (priv->image, &name, NULL);
+
+ return name;
+}
+
+
+void
+indicator_menu_item_set_icon_name (IndicatorMenuItem *self,
+ const gchar *name)
+{
+ IndicatorMenuItemPrivate *priv = MENU_ITEM_PRIVATE (self);
+ gtk_image_set_from_icon_name (priv->image, name, GTK_ICON_SIZE_MENU);
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ICON_NAME]);
+}
+
diff --git a/src/indicator-menu-item.h b/src/indicator-menu-item.h
index 39c456a..a5f3407 100644
--- a/src/indicator-menu-item.h
+++ b/src/indicator-menu-item.h
@@ -48,6 +48,11 @@ IndicatorMenuItem *indicator_menu_item_new (void);
void indicator_menu_item_set_right (IndicatorMenuItem *self, const gchar *text);
void indicator_menu_item_set_label (IndicatorMenuItem *self, const gchar *text);
+const gchar * indicator_menu_item_get_icon_name (IndicatorMenuItem *self);
+void indicator_menu_item_set_icon (IndicatorMenuItem *self, GdkPixbuf *icon);
+GdkPixbuf * indicator_menu_item_get_icon (IndicatorMenuItem *self);
+void indicator_menu_item_set_icon_name (IndicatorMenuItem *self, const gchar *name);
+
G_END_DECLS
#endif
diff --git a/src/indicator-printers-menu.c b/src/indicator-printers-menu.c
index c6a76da..b8a2360 100644
--- a/src/indicator-printers-menu.c
+++ b/src/indicator-printers-menu.c
@@ -81,6 +81,7 @@ add_printer_menuitem (IndicatorPrintersMenu *self,
DbusmenuMenuitem *child;
child = dbusmenu_menuitem_new ();
+ dbusmenu_menuitem_property_set (child, "indicator-icon-name", "printer");
dbusmenu_menuitem_property_set (child, "indicator-label", printer);
dbusmenu_menuitem_property_set (child, "indicator-right", "Paused");
dbusmenu_menuitem_property_set (child, "type", "indicator-item");
diff --git a/src/indicator-printers.c b/src/indicator-printers.c
index 3a642ac..6ae984c 100644
--- a/src/indicator-printers.c
+++ b/src/indicator-printers.c
@@ -79,6 +79,55 @@ indicator_printers_class_init (IndicatorPrintersClass *klass)
}
+static GdkPixbuf *
+gdk_pixbuf_new_from_encoded_data (guchar *data,
+ gsize length)
+{
+ GInputStream * input;
+ GError *err = NULL;
+ GdkPixbuf *img;
+
+ input = g_memory_input_stream_new_from_data(data, length, NULL);
+ if (input == NULL)
+ return NULL;
+
+ img = gdk_pixbuf_new_from_stream(input, NULL, &err);
+ if (err) {
+ g_warning("%s", err->message);
+ g_error_free(err);
+ }
+
+ g_object_unref(input);
+ return img;
+}
+
+
+static GdkPixbuf *
+g_variant_get_image (GVariant *value)
+{
+ const gchar *strvalue = NULL;
+ gsize length = 0;
+ guchar *icondata;
+ GdkPixbuf *img;
+
+ if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
+ strvalue = g_variant_get_string(value, NULL);
+
+ if (!strvalue || !*strvalue) {
+ g_warning ("%s: value does not contain a base64 encoded image",
+ __func__);
+ return NULL;
+ }
+
+ icondata = g_base64_decode(strvalue, &length);
+ img = gdk_pixbuf_new_from_encoded_data (icondata, length);
+
+ g_free(icondata);
+ return img;
+}
+
+
+
static gboolean
is_string_property (const gchar *name,
const gchar *prop,
@@ -89,6 +138,16 @@ is_string_property (const gchar *name,
}
+static gboolean
+is_image_property (const gchar *name,
+ const gchar *prop,
+ GVariant *value)
+{
+ return !g_strcmp0 (name, prop) &&
+ g_variant_is_of_type (value, G_VARIANT_TYPE_STRING);
+}
+
+
static void
indicator_prop_change_cb (DbusmenuMenuitem *mi,
gchar *prop,
@@ -101,6 +160,13 @@ indicator_prop_change_cb (DbusmenuMenuitem *mi,
indicator_menu_item_set_label (menuitem, g_variant_get_string (value, NULL));
else if (is_string_property (prop, "indicator-right", value))
indicator_menu_item_set_right (menuitem, g_variant_get_string (value, NULL));
+ else if (is_string_property (prop, "indicator-icon-name", value))
+ indicator_menu_item_set_icon_name (menuitem, g_variant_get_string (value, NULL));
+ else if (is_image_property (prop, "indicator-icon", value)) {
+ GdkPixbuf *pb = g_variant_get_image (value);
+ indicator_menu_item_set_icon (menuitem, pb);
+ g_object_unref (pb);
+ }
}
@@ -111,18 +177,27 @@ new_indicator_item (DbusmenuMenuitem *newitem,
gpointer user_data)
{
GtkWidget *menuitem;
- const gchar *text, *right_text;
+ const gchar *icon_name, *text, *right_text;
+ GVariant *icon;
gboolean is_lozenge;
+ icon_name = dbusmenu_menuitem_property_get (newitem, "indicator-icon-name");
+ icon = dbusmenu_menuitem_property_get_variant (newitem, "indicator-icon");
text = dbusmenu_menuitem_property_get (newitem, "indicator-label");
right_text = dbusmenu_menuitem_property_get (newitem, "indicator-right");
is_lozenge = dbusmenu_menuitem_property_get_bool (newitem, "indicator-right-is-lozenge");
menuitem = g_object_new (INDICATOR_TYPE_MENU_ITEM,
+ "icon-name", icon_name,
"label", text,
"right", right_text,
"right-is-lozenge", is_lozenge,
NULL);
+ if (icon) {
+ GdkPixbuf *pb = g_variant_get_image (icon);
+ indicator_menu_item_set_icon (INDICATOR_MENU_ITEM (menuitem), pb);
+ g_object_unref (pb);
+ }
gtk_widget_show_all (menuitem);
dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client),