From 9025561994ab31a85b47f825cd096be86dd57299 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Sat, 14 Jan 2012 06:47:32 +0100 Subject: Use a custom menu item which shows printer status on the right --- .bzrignore | 4 +- src/Makefile.am | 4 +- src/indicator-menu-item.c | 171 ++++++++++++++++++++++++++++++++++++++++++ src/indicator-menu-item.h | 54 +++++++++++++ src/indicator-printers-menu.c | 14 ++-- src/indicator-printers.c | 64 ++++++++++++++++ 6 files changed, 303 insertions(+), 8 deletions(-) create mode 100644 src/indicator-menu-item.c create mode 100644 src/indicator-menu-item.h diff --git a/.bzrignore b/.bzrignore index 13759d0..e54d376 100644 --- a/.bzrignore +++ b/.bzrignore @@ -23,6 +23,6 @@ src/.libs/ src/Makefile src/Makefile.in src/indicator-printers-service -src/libprintersmenu.la -src/libprintersmenu_la-indicator-printers.lo +src/*.la +src/*.lo diff --git a/src/Makefile.am b/src/Makefile.am index 5fc0107..5684e70 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,7 +3,9 @@ printersmenulibdir = $(INDICATORDIR) printersmenulib_LTLIBRARIES = libprintersmenu.la libprintersmenu_la_SOURCES = \ indicator-printers.c \ - indicator-printers.h + indicator-printers.h \ + indicator-menu-item.c \ + indicator-menu-item.h libprintersmenu_la_CPPFLAGS = $(APPLET_CFLAGS) libprintersmenu_la_LIBADD = $(APPLET_LIBS) diff --git a/src/indicator-menu-item.c b/src/indicator-menu-item.c new file mode 100644 index 0000000..224c6f3 --- /dev/null +++ b/src/indicator-menu-item.c @@ -0,0 +1,171 @@ + +#include "indicator-menu-item.h" + + +G_DEFINE_TYPE (IndicatorMenuItem, indicator_menu_item, GTK_TYPE_MENU_ITEM) + +#define MENU_ITEM_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), INDICATOR_TYPE_MENU_ITEM, IndicatorMenuItemPrivate)) + +struct _IndicatorMenuItemPrivate +{ + GtkWidget *label; + GtkWidget *right_label; +}; + + +enum { + PROP_0, + PROP_LABEL, + PROP_RIGHT, + N_PROPERTIES +}; + +static GParamSpec *properties[N_PROPERTIES]; + + +static void +indicator_menu_item_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + IndicatorMenuItemPrivate *priv = MENU_ITEM_PRIVATE (object); + + switch (property_id) + { + case PROP_LABEL: + g_value_set_string (value, gtk_label_get_label (GTK_LABEL (priv->label))); + break; + + case PROP_RIGHT: + g_value_set_string (value, gtk_label_get_label (GTK_LABEL (priv->right_label))); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + + +static void +indicator_menu_item_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) + { + case PROP_LABEL: + indicator_menu_item_set_label (INDICATOR_MENU_ITEM (object), + g_value_get_string (value)); + + break; + + case PROP_RIGHT: + indicator_menu_item_set_right (INDICATOR_MENU_ITEM (object), + g_value_get_string (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + + +static void +indicator_menu_item_dispose (GObject *object) +{ + IndicatorMenuItemPrivate *priv = MENU_ITEM_PRIVATE (object); + + g_clear_object (&priv->label); + g_clear_object (&priv->right_label); + + G_OBJECT_CLASS (indicator_menu_item_parent_class)->dispose (object); +} + + +static void +indicator_menu_item_class_init (IndicatorMenuItemClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (IndicatorMenuItemPrivate)); + + object_class->get_property = indicator_menu_item_get_property; + object_class->set_property = indicator_menu_item_set_property; + object_class->dispose = indicator_menu_item_dispose; + + properties[PROP_LABEL] = g_param_spec_string ("label", + "Label", + "The text for the main label", + "", + G_PARAM_READWRITE); + + properties[PROP_RIGHT] = g_param_spec_string ("right", + "Right", + "The text on the right side of the menu item", + "", + G_PARAM_READWRITE); + + g_object_class_install_properties (object_class, N_PROPERTIES, properties); +} + + +static void +indicator_menu_item_init (IndicatorMenuItem *self) +{ + IndicatorMenuItemPrivate *priv = MENU_ITEM_PRIVATE (self); + gint spacing; + GtkWidget *hbox; + + gtk_widget_style_get (GTK_WIDGET (self), + "toggle-spacing", &spacing, + NULL); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, spacing); + + priv->label = g_object_new (GTK_TYPE_LABEL, + "xalign", 0.0, + NULL); + g_object_ref_sink (priv->label); + gtk_box_pack_start (GTK_BOX (hbox), priv->label, TRUE, TRUE, 0); + + priv->right_label = g_object_new (GTK_TYPE_LABEL, + "xalign", 1.0, + NULL); + gtk_style_context_add_class (gtk_widget_get_style_context (priv->right_label), + "accelerator"); + g_object_ref_sink (priv->right_label); + gtk_box_pack_start (GTK_BOX (hbox), priv->right_label, FALSE, FALSE, 0); + + gtk_container_add (GTK_CONTAINER (self), hbox); +} + + +IndicatorMenuItem * +indicator_menu_item_new (void) +{ + return g_object_new (INDICATOR_TYPE_MENU_ITEM, NULL); +} + + +void +indicator_menu_item_set_label (IndicatorMenuItem *self, + const gchar *text) +{ + IndicatorMenuItemPrivate *priv = MENU_ITEM_PRIVATE (self); + gtk_label_set_label (GTK_LABEL (priv->label), text); + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_LABEL]); +} + + +void +indicator_menu_item_set_right (IndicatorMenuItem *self, + const gchar *text) +{ + IndicatorMenuItemPrivate *priv = MENU_ITEM_PRIVATE (self); + gtk_label_set_label (GTK_LABEL (priv->right_label), text); + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_RIGHT]); +} + diff --git a/src/indicator-menu-item.h b/src/indicator-menu-item.h new file mode 100644 index 0000000..39c456a --- /dev/null +++ b/src/indicator-menu-item.h @@ -0,0 +1,54 @@ + +#ifndef INDICATOR_MENU_ITEM_H +#define INDICATOR_MENU_ITEM_H + +#include + +G_BEGIN_DECLS + +#define INDICATOR_TYPE_MENU_ITEM indicator_menu_item_get_type() + +#define INDICATOR_MENU_ITEM(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + INDICATOR_TYPE_MENU_ITEM, IndicatorMenuItem)) + +#define INDICATOR_MENU_ITEM_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + INDICATOR_TYPE_MENU_ITEM, IndicatorMenuItemClass)) + +#define INDICATOR_IS_MENU_ITEM(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + INDICATOR_TYPE_MENU_ITEM)) + +#define INDICATOR_IS_MENU_ITEM_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + INDICATOR_TYPE_MENU_ITEM)) + +#define INDICATOR_MENU_ITEM_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + INDICATOR_TYPE_MENU_ITEM, IndicatorMenuItemClass)) + +typedef struct _IndicatorMenuItem IndicatorMenuItem; +typedef struct _IndicatorMenuItemClass IndicatorMenuItemClass; +typedef struct _IndicatorMenuItemPrivate IndicatorMenuItemPrivate; + +struct _IndicatorMenuItem +{ + GtkMenuItem parent; +}; + +struct _IndicatorMenuItemClass +{ + GtkMenuItemClass parent_class; +}; + +GType indicator_menu_item_get_type (void) G_GNUC_CONST; + +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); + +G_END_DECLS + +#endif + diff --git a/src/indicator-printers-menu.c b/src/indicator-printers-menu.c index 1ff9d5c..c6a76da 100644 --- a/src/indicator-printers-menu.c +++ b/src/indicator-printers-menu.c @@ -81,11 +81,15 @@ add_printer_menuitem (IndicatorPrintersMenu *self, DbusmenuMenuitem *child; child = dbusmenu_menuitem_new (); - dbusmenu_menuitem_property_set (child, "label", printer); - g_signal_connect (child, - "item-activated", - G_CALLBACK (show_system_settings), - 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"); + g_signal_connect_data (child, + "item-activated", + G_CALLBACK (show_system_settings), + g_strdup (printer), + (GClosureNotify) g_free, + 0); dbusmenu_menuitem_child_append(priv->root, child); g_object_unref (child); diff --git a/src/indicator-printers.c b/src/indicator-printers.c index 1f59b27..a384ef5 100644 --- a/src/indicator-printers.c +++ b/src/indicator-printers.c @@ -19,6 +19,7 @@ #include "config.h" #include "indicator-printers.h" +#include "indicator-menu-item.h" #include "dbus-names.h" #include @@ -78,16 +79,79 @@ indicator_printers_class_init (IndicatorPrintersClass *klass) } +static gboolean +is_string_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, + GVariant *value, + gpointer user_data) +{ + IndicatorMenuItem *menuitem = user_data; + + if (is_string_property (prop, "indicator-label", value)) + 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)); +} + + +static gboolean +new_indicator_item (DbusmenuMenuitem *newitem, + DbusmenuMenuitem *parent, + DbusmenuClient *client, + gpointer user_data) +{ + GtkWidget *menuitem; + const gchar *text, *right_text; + + text = dbusmenu_menuitem_property_get (newitem, "indicator-label"); + right_text = dbusmenu_menuitem_property_get (newitem, "indicator-right"); + + menuitem = g_object_new (INDICATOR_TYPE_MENU_ITEM, + "label", text, + "right", right_text, + NULL); + gtk_widget_show_all (menuitem); + + dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), + newitem, + GTK_MENU_ITEM (menuitem), + parent); + + g_signal_connect(G_OBJECT(newitem), + "property-changed", + G_CALLBACK(indicator_prop_change_cb), + menuitem); + + return TRUE; +} + + static void indicator_printers_init (IndicatorPrinters *io) { IndicatorPrintersPrivate *priv = INDICATOR_PRINTERS_GET_PRIVATE (io); DbusmenuGtkMenu *menu; + DbusmenuClient *client; GtkImage *image; menu = dbusmenu_gtkmenu_new(INDICATOR_PRINTERS_DBUS_NAME, INDICATOR_PRINTERS_DBUS_OBJECT_PATH); + client = DBUSMENU_CLIENT (dbusmenu_gtkmenu_get_client (menu)); + dbusmenu_client_add_type_handler(client, + "indicator-item", + new_indicator_item); + image = indicator_image_helper ("printer-symbolic"); gtk_widget_show (GTK_WIDGET (image)); -- cgit v1.2.3