[network-manager-applet/menu-rework: 13/18] applet: use custom menu title to overcome indentation and color constraints imposed by menu items



commit b23f1f3c7070b38ea2e93624367ac892db0b4efb
Author: Alexander Sack <asac ubuntu com>
Date:   Wed Sep 23 15:53:51 2009 +0200

    applet: use custom menu title to overcome indentation and color constraints imposed by menu items
    
    add applet_menu_item_create_device_item_helper to applet api and use that
    instead of the markup based menu item approach for creating the device
    title items in the menu
    
    use cairo in "expose" signal handler to overload default rendering behaviour
    for the title menu items

 src/applet-device-bt.c    |    6 +--
 src/applet-device-cdma.c  |    2 +-
 src/applet-device-gsm.c   |   10 +---
 src/applet-device-wifi.c  |   10 +---
 src/applet-device-wired.c |   10 +---
 src/applet.c              |  148 ++++++++++++++++++++++++++++++++++++++++++++-
 src/applet.h              |    7 ++
 7 files changed, 158 insertions(+), 35 deletions(-)
---
diff --git a/src/applet-device-bt.c b/src/applet-device-bt.c
index 401371f..0e8ab8e 100644
--- a/src/applet-device-bt.c
+++ b/src/applet-device-bt.c
@@ -144,7 +144,6 @@ bt_add_menu_item (NMDevice *device,
 	GtkWidget *item;
 	GSList *connections, *all;
 	gboolean carrier = TRUE;
-	char *bold_text;
 
 	all = applet_get_all_connections (applet);
 	connections = utils_filter_connections_for_device (device, all);
@@ -158,10 +157,7 @@ bt_add_menu_item (NMDevice *device,
 		g_assert (text);
 	}
 
-	item = gtk_menu_item_new_with_label ("");
-	bold_text = g_markup_printf_escaped ("<span weight=\"bold\">%s</span>", text);
-	gtk_label_set_markup (GTK_LABEL (gtk_bin_get_child (GTK_BIN (item))), bold_text);
-	g_free (bold_text);
+	item = applet_menu_item_create_device_item_helper (device, applet, text);
 
 	gtk_widget_set_sensitive (item, FALSE);
 	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
diff --git a/src/applet-device-cdma.c b/src/applet-device-cdma.c
index b6979dc..45610f7 100644
--- a/src/applet-device-cdma.c
+++ b/src/applet-device-cdma.c
@@ -268,7 +268,7 @@ cdma_add_menu_item (NMDevice *device,
 		text = g_strdup (_("Mobile Broadband"));
 	}
 
-	item = gtk_menu_item_new_with_label (text);
+	item = applet_menu_item_create_device_item_helper (device, applet, text);
 	g_free (text);
 
 	label = gtk_bin_get_child (GTK_BIN (item));
diff --git a/src/applet-device-gsm.c b/src/applet-device-gsm.c
index 433c3bc..231771f 100644
--- a/src/applet-device-gsm.c
+++ b/src/applet-device-gsm.c
@@ -249,8 +249,6 @@ gsm_add_menu_item (NMDevice *device,
 	char *text;
 	GtkWidget *item;
 	GSList *connections, *all;
-	GtkWidget *label;
-	char *bold_text;
 
 	all = applet_get_all_connections (applet);
 	connections = utils_filter_connections_for_device (device, all);
@@ -269,15 +267,9 @@ gsm_add_menu_item (NMDevice *device,
 		text = g_strdup (_("Mobile Broadband"));
 	}
 
-	item = gtk_menu_item_new_with_label (text);
+	item = applet_menu_item_create_device_item_helper (device, applet, text);
 	g_free (text);
 
-	label = gtk_bin_get_child (GTK_BIN (item));
-	bold_text = g_markup_printf_escaped ("<span weight=\"bold\">%s</span>",
-	                                     gtk_label_get_text (GTK_LABEL (label)));
-	gtk_label_set_markup (GTK_LABEL (label), bold_text);
-	g_free (bold_text);
-
 	gtk_widget_set_sensitive (item, FALSE);
 	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
 	gtk_widget_show (item);
diff --git a/src/applet-device-wifi.c b/src/applet-device-wifi.c
index c545f37..3ed5df1 100644
--- a/src/applet-device-wifi.c
+++ b/src/applet-device-wifi.c
@@ -718,8 +718,6 @@ wireless_add_menu_item (NMDevice *device,
 	int i;
 	NMAccessPoint *active_ap = NULL;
 	GSList *connections = NULL, *all, *sorted_aps = NULL, *iter;
-	GtkWidget *label;
-	char *bold_text;
 	gboolean wireless_enabled = TRUE;
 	GList *menu_list = NULL;
 	GtkWidget *folded_menu_item;
@@ -747,15 +745,9 @@ wireless_add_menu_item (NMDevice *device,
 	} else
 		text = g_strdup (ngettext ("Wireless Network", "Wireless Networks", aps ? aps->len : 0));
 
-	item = gtk_menu_item_new_with_mnemonic (text);
+	item = applet_menu_item_create_device_item_helper (device, applet, text);
 	g_free (text);
 
-	label = gtk_bin_get_child (GTK_BIN (item));
-	bold_text = g_markup_printf_escaped ("<span weight=\"bold\">%s</span>",
-	                                     gtk_label_get_text (GTK_LABEL (label)));
-	gtk_label_set_markup (GTK_LABEL (label), bold_text);
-	g_free (bold_text);
-
 	gtk_widget_set_sensitive (item, FALSE);
 	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
 	gtk_widget_show (item);
diff --git a/src/applet-device-wired.c b/src/applet-device-wired.c
index 3a44789..545e3ce 100644
--- a/src/applet-device-wired.c
+++ b/src/applet-device-wired.c
@@ -194,8 +194,6 @@ wired_add_menu_item (NMDevice *device,
 	GtkWidget *item;
 	GSList *connections, *all;
 	gboolean carrier = TRUE;
-	GtkWidget *label;
-	char *bold_text;
 
 	all = applet_get_all_connections (applet);
 	connections = utils_filter_connections_for_device (device, all);
@@ -220,7 +218,7 @@ wired_add_menu_item (NMDevice *device,
 			text = g_strdup (_("Wired Network"));
 	}
 
-	item = gtk_menu_item_new_with_label (text);
+	item = applet_menu_item_create_device_item_helper (device, applet, text);
 	g_free (text);
 
 	/* Only dim the item if the device supports carrier detection AND
@@ -229,12 +227,6 @@ wired_add_menu_item (NMDevice *device,
  	if (nm_device_get_capabilities (device) & NM_DEVICE_CAP_CARRIER_DETECT)
 		carrier = nm_device_ethernet_get_carrier (NM_DEVICE_ETHERNET (device));
 
-	label = gtk_bin_get_child (GTK_BIN (item));
-	bold_text = g_markup_printf_escaped ("<span weight=\"bold\">%s</span>",
-	                                     gtk_label_get_text (GTK_LABEL (label)));
-	gtk_label_set_markup (GTK_LABEL (label), bold_text);
-	g_free (bold_text);
-
 	gtk_widget_set_sensitive (item, FALSE);
 	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
 	gtk_widget_show (item);
diff --git a/src/applet.c b/src/applet.c
index 6ae516a..979b345 100644
--- a/src/applet.c
+++ b/src/applet.c
@@ -480,10 +480,10 @@ applet_menu_item_favorize_helper (GtkBin *binitem,
 		image_width = gdk_pixbuf_get_width (favoritePixbuf);
 		image_height = gdk_pixbuf_get_height (favoritePixbuf);
 		gtk_container_remove (GTK_CONTAINER (binitem), child);
+		gtk_container_add (GTK_CONTAINER (binitem), box);
 		gtk_widget_set_size_request (placeholder, image_width, image_height);
 		gtk_box_pack_start (GTK_BOX (box), placeholder, FALSE, FALSE, 0);
 		gtk_box_pack_start (GTK_BOX (box), child, TRUE, TRUE, 4);
-		gtk_container_add (GTK_CONTAINER (binitem), box);
 		g_object_unref (child);
 		g_object_set_data (G_OBJECT (binitem), "favorite", GINT_TO_POINTER (1));
 	} else {
@@ -491,9 +491,9 @@ applet_menu_item_favorize_helper (GtkBin *binitem,
 		g_assert (image);
 		g_object_ref (child);
 		gtk_container_remove (GTK_CONTAINER (binitem), child);
+		gtk_container_add (GTK_CONTAINER (binitem), box);
 		gtk_box_pack_start (GTK_BOX (box), image, FALSE, FALSE, 0);
 		gtk_box_pack_start (GTK_BOX (box), child, TRUE, TRUE, 4);
-		gtk_container_add (GTK_CONTAINER (binitem), box);
 		g_object_unref (child);
 		g_object_set_data (G_OBJECT (binitem), "favorite", GINT_TO_POINTER (2));
 	}
@@ -565,6 +565,150 @@ applet_menu_add_items_top_and_fold_sorted_helper (GtkMenu *menu,
 	g_list_free(clone_folded);
 }
 
+static gboolean
+menu_title_item_expose (GtkWidget      *widget,
+                        GdkEventExpose *event)
+{
+	#define TITLE_TEXT_R ((double) 0x5e / 255.0 )
+	#define TITLE_TEXT_G ((double) 0x5e / 255.0 )
+	#define TITLE_TEXT_B ((double) 0x5e / 255.0 )
+/*	#define TITLE_TEXT_R ((double) style->text[GTK_STATE_NORMAL].red / 65535.0)
+	#define TITLE_TEXT_G ((double) style->text[GTK_STATE_NORMAL].green / 65535.0)
+	#define TITLE_TEXT_B ((double) style->text[GTK_STATE_NORMAL].blue / 65535.0) */
+
+	GtkStyle *style = gtk_widget_get_style (widget);
+	GtkWidget *label = gtk_bin_get_child (GTK_BIN (widget));
+	PangoFontDescription *desc = pango_font_description_copy (style->font_desc);
+	cairo_t *cr = gdk_cairo_create (widget->window);
+	GtkImageMenuItem *image_menu_item = GTK_IS_IMAGE_MENU_ITEM (widget) ? GTK_IMAGE_MENU_ITEM (widget) : NULL;
+	GtkImage *icon = image_menu_item ? GTK_IMAGE (gtk_image_menu_item_get_image (image_menu_item)) : NULL;
+	GdkPixbuf *pixbuf = icon ? gtk_image_get_pixbuf (icon) : NULL;
+	PangoLayout *layout_first = pango_cairo_create_layout (cr);
+	PangoLayout *layout_second = pango_cairo_create_layout (cr);
+	int width = 0, height = 0;
+	int extrawidth = 0;
+	gdouble extraheight = 0;
+	int owidth, oheight;
+	char *first, *second;
+	char *secondtext;
+	gdouble xpadding = 5.0;
+	gdouble ypadding = 5.0;
+	gdouble postpadding = 0.0;
+
+	first = g_strdup (gtk_label_get_text (GTK_LABEL (label)));
+	second = strchr (first, ':');
+	if (second) {
+		*second = 0;
+		second++;
+		second++;
+		secondtext = g_strdup_printf ("%s", second);
+	}
+
+	/* lets put together both layout lines */
+	pango_font_description_set_variant (desc, PANGO_VARIANT_SMALL_CAPS);
+	pango_font_description_set_weight (desc, PANGO_WEIGHT_SEMIBOLD);
+	pango_layout_set_font_description (layout_first, desc);
+	pango_layout_set_text (layout_first, first, -1);
+	pango_cairo_update_layout (cr, layout_first);
+	pango_layout_get_size (layout_first, &owidth, &oheight);
+	width = owidth / PANGO_SCALE;
+	height += oheight / PANGO_SCALE;
+
+	if (second) {
+		pango_font_description_set_weight (desc, PANGO_WEIGHT_NORMAL);
+		pango_layout_set_font_description (layout_second, desc);
+		pango_layout_set_text (layout_second, secondtext, -1);
+		pango_cairo_update_layout (cr, layout_second);
+		pango_layout_get_size (layout_second, &owidth, &oheight);
+		width = width < owidth / PANGO_SCALE ? owidth / PANGO_SCALE : width;
+		height += oheight / PANGO_SCALE;
+	}
+
+	if (pixbuf) {
+		gdouble w = gdk_pixbuf_get_width (pixbuf);
+		gdouble h = gdk_pixbuf_get_height (pixbuf);
+		if (width < w)
+			width = w;
+		if (height < h) {
+			extraheight = (h - height) / 2.0;
+			height = h;
+		}
+		extrawidth = gdk_pixbuf_get_width (pixbuf) + 5.0 + 5.0;
+	}
+	width += extrawidth;
+
+	cairo_save (cr);
+	cairo_translate (cr, ((double) event->area.x) , ((double) event->area.y));
+
+	cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0);
+	cairo_rectangle (cr, 0, 0, ((double) event->area.width), ((double) event->area.height - postpadding));
+	cairo_fill (cr);
+
+/* no border atm 
+	cairo_set_source_rgba (cr, 0.1, 0.1, 0.1, 0.6);
+	cairo_rectangle (cr, 0, 0, ((double) event->area.width), 0.5);
+	cairo_fill (cr);
+	cairo_set_source_rgba (cr, 0.6, 0.6, 0.6, 0.4);
+	cairo_rectangle (cr, 0, ((double) event->area.height - postpadding - 0.5), ((double) event->area.width), 0.5);
+	cairo_fill (cr);
+*/
+
+	/* now the in-padding content */
+	cairo_translate (cr, xpadding , ypadding);
+	if (pixbuf) {
+		gdouble x = 0.0;
+		gdouble y = height / 2.0 - gdk_pixbuf_get_height (pixbuf) / 2.0;
+		gdouble w = gdk_pixbuf_get_width (pixbuf);
+		gdouble h = gdk_pixbuf_get_height (pixbuf);
+		gdk_cairo_set_source_pixbuf (cr, pixbuf, x, y);
+		cairo_rectangle (cr, x, y, w, h);
+		cairo_fill (cr);
+	}
+
+	cairo_set_source_rgb (cr, TITLE_TEXT_R, TITLE_TEXT_G, TITLE_TEXT_B);
+	cairo_move_to (cr, extrawidth, extraheight);
+	pango_cairo_show_layout (cr, layout_first);
+
+	if (second) {
+		cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+		cairo_move_to (cr, extrawidth, extraheight + oheight / PANGO_SCALE);
+		pango_cairo_show_layout (cr, layout_second);
+	}
+
+	cairo_restore(cr);
+	pango_font_description_free (desc);
+
+	g_free (first);
+	g_object_unref (layout_first);
+	g_object_unref (layout_second);
+	cairo_destroy (cr);
+
+	gtk_widget_set_size_request (widget, width + 2 * xpadding, height + ypadding + postpadding);
+
+	return TRUE;
+
+	#undef TITLE_TEXT_R
+	#undef TITLE_TEXT_G
+	#undef TITLE_TEXT_B
+}
+
+
+GtkWidget*
+applet_menu_item_create_device_item_helper (NMDevice *device,
+                                            NMApplet *applet,
+                                            const gchar *text)
+{
+	GtkWidget *item = gtk_image_menu_item_new_with_mnemonic (text);
+	NMADeviceClass *klass = get_device_class (device, applet);
+	GdkPixbuf *pixbuf = klass->get_device_icon ? klass->get_device_icon (device, applet) : NULL;
+	GtkWidget *image = pixbuf ? gtk_image_new_from_pixbuf (pixbuf) : NULL;
+	gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
+
+	gtk_widget_set_sensitive (item, FALSE);
+
+	g_signal_connect (item, "expose-event", G_CALLBACK (menu_title_item_expose), NULL);
+	return item;
+}
 
 static void
 applet_clear_notify (NMApplet *applet)
diff --git a/src/applet.h b/src/applet.h
index 13be72c..9a08133 100644
--- a/src/applet.h
+++ b/src/applet.h
@@ -182,6 +182,9 @@ struct NMADeviceClass {
 	                                        char **tip,
 	                                        NMApplet *applet);
 
+	GdkPixbuf *    (*get_device_icon)      (NMDevice *device,
+	                                        NMApplet *applet);
+
 	void           (*get_more_info)        (NMDevice *device,
 	                                        NMConnection *connection,
 	                                        NMApplet *applet,
@@ -239,6 +242,10 @@ void applet_menu_add_items_top_and_fold_sorted_helper (GtkMenu *menu,
                                                        GtkWidget *submenu_item,
                                                        GCompareFunc prio_cmp_func,
                                                        GCompareFunc generic_cmp_func);
+GtkWidget*
+applet_menu_item_create_device_item_helper (NMDevice *device,
+                                            NMApplet *applet,
+                                            const gchar *text);
 
 NMSettingsConnectionInterface *applet_get_exported_connection_for_device (NMDevice *device, NMApplet *applet);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]