From 62d044c3be5b8fc1fcad41300581c9c8a9ef02ab Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Sat, 14 Jan 2012 13:55:36 +0100 Subject: Optionally draw the right label as a lozenge --- src/indicator-menu-item.c | 100 +++++++++++++++++++++++++++++++++++++++++++++- src/indicator-printers.c | 3 ++ 2 files changed, 101 insertions(+), 2 deletions(-) diff --git a/src/indicator-menu-item.c b/src/indicator-menu-item.c index 224c6f3..72faad6 100644 --- a/src/indicator-menu-item.c +++ b/src/indicator-menu-item.c @@ -1,6 +1,8 @@ #include "indicator-menu-item.h" +#include + G_DEFINE_TYPE (IndicatorMenuItem, indicator_menu_item, GTK_TYPE_MENU_ITEM) @@ -11,6 +13,7 @@ struct _IndicatorMenuItemPrivate { GtkWidget *label; GtkWidget *right_label; + gboolean right_is_lozenge; }; @@ -18,12 +21,78 @@ enum { PROP_0, PROP_LABEL, PROP_RIGHT, + PROP_RIGHT_IS_LOZENGE, N_PROPERTIES }; static GParamSpec *properties[N_PROPERTIES]; +static gint +gtk_widget_get_font_size (GtkWidget *widget) +{ + const PangoFontDescription *font; + + font = gtk_style_context_get_font (gtk_widget_get_style_context (widget), + gtk_widget_get_state_flags (widget)); + + return pango_font_description_get_size (font) / PANGO_SCALE; +} + +static void +cairo_lozenge (cairo_t *cr, double x, double y, double w, double h) +{ + double radius = MIN (w / 2.0, h / 2.0); + double x1 = x + w - radius; + double x2 = x + radius; + double y1 = y + radius; + double y2 = y + h - radius; + + cairo_move_to (cr, x+radius, y); + cairo_arc (cr, x1, y1, radius, M_PI * 1.5, M_PI * 2); + cairo_arc (cr, x1, y2, radius, 0, M_PI * 0.5); + cairo_arc (cr, x2, y2, radius, M_PI * 0.5, M_PI); + cairo_arc (cr, x2, y1, radius, M_PI, M_PI * 1.5); +} + +static gboolean +detail_label_draw (GtkWidget *widget, + cairo_t *cr, + gpointer data) +{ + GtkAllocation allocation; + double x, y, w, h; + GdkRGBA color; + PangoLayout * layout; + gboolean is_lozenge = *(gboolean *)data; + + gtk_widget_get_allocation (widget, &allocation); + x = 0; + y = 0; + w = allocation.width; + h = allocation.height; + + gtk_style_context_get_color (gtk_widget_get_style_context (widget), + gtk_widget_get_state_flags (widget), + &color); + gdk_cairo_set_source_rgba (cr, &color); + + if (is_lozenge) { + gint font_size = gtk_widget_get_font_size (widget); + cairo_set_line_width (cr, 1.0); + cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); + cairo_lozenge (cr, x - font_size / 2.0, y, w + font_size, h); + } + + layout = gtk_label_get_layout (GTK_LABEL(widget)); + cairo_move_to (cr, x, y); + pango_cairo_layout_path (cr, layout); + cairo_fill (cr); + + return TRUE; +} + + static void indicator_menu_item_get_property (GObject *object, guint property_id, @@ -42,6 +111,10 @@ indicator_menu_item_get_property (GObject *object, g_value_set_string (value, gtk_label_get_label (GTK_LABEL (priv->right_label))); break; + case PROP_RIGHT_IS_LOZENGE: + g_value_set_boolean (value, priv->right_is_lozenge); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -54,12 +127,13 @@ indicator_menu_item_set_property (GObject *object, const GValue *value, GParamSpec *pspec) { + IndicatorMenuItemPrivate *priv = MENU_ITEM_PRIVATE (object); + switch (property_id) { case PROP_LABEL: indicator_menu_item_set_label (INDICATOR_MENU_ITEM (object), g_value_get_string (value)); - break; case PROP_RIGHT: @@ -67,6 +141,12 @@ indicator_menu_item_set_property (GObject *object, g_value_get_string (value)); break; + case PROP_RIGHT_IS_LOZENGE: + priv->right_is_lozenge = g_value_get_boolean (value); + gtk_widget_queue_draw (priv->right_label); + break; + + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -108,6 +188,12 @@ indicator_menu_item_class_init (IndicatorMenuItemClass *klass) "", G_PARAM_READWRITE); + properties[PROP_RIGHT_IS_LOZENGE] = g_param_spec_boolean ("right-is-lozenge", + "Right is a lozenge", + "Whether the right label is displayed as a lonzenge", + FALSE, + G_PARAM_READWRITE); + g_object_class_install_properties (object_class, N_PROPERTIES, properties); } @@ -136,10 +222,20 @@ indicator_menu_item_init (IndicatorMenuItem *self) NULL); gtk_style_context_add_class (gtk_widget_get_style_context (priv->right_label), "accelerator"); + g_signal_connect (priv->right_label, + "draw", + G_CALLBACK (detail_label_draw), + &priv->right_is_lozenge); g_object_ref_sink (priv->right_label); - gtk_box_pack_start (GTK_BOX (hbox), priv->right_label, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (hbox), + priv->right_label, + FALSE, + FALSE, + gtk_widget_get_font_size (priv->right_label) / 2.0 + 1); gtk_container_add (GTK_CONTAINER (self), hbox); + + priv->right_is_lozenge = FALSE; } diff --git a/src/indicator-printers.c b/src/indicator-printers.c index a384ef5..e13ab59 100644 --- a/src/indicator-printers.c +++ b/src/indicator-printers.c @@ -112,13 +112,16 @@ new_indicator_item (DbusmenuMenuitem *newitem, { GtkWidget *menuitem; const gchar *text, *right_text; + gboolean is_lozenge; 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, "label", text, "right", right_text, + "right-is-lozenge", is_lozenge, NULL); gtk_widget_show_all (menuitem); -- cgit v1.2.3