[gtk-mac-integration] Add support for icons in menus.
- From: John Ralls <jralls src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk-mac-integration] Add support for icons in menus.
- Date: Thu, 27 Sep 2012 20:23:02 +0000 (UTC)
commit 4620977eb3c6129cb4ff35d3a9ef422a8e6a5a73
Author: Julien Woillez <jwoillez gmail com>
Date: Fri Aug 31 11:30:49 2012 -1000
Add support for icons in menus.
src/cocoa_menu_item.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 105 insertions(+), 0 deletions(-)
---
diff --git a/src/cocoa_menu_item.c b/src/cocoa_menu_item.c
index f0637f0..03bd856 100644
--- a/src/cocoa_menu_item.c
+++ b/src/cocoa_menu_item.c
@@ -31,6 +31,7 @@
#include "cocoa_menu_item.h"
#include "cocoa_menu.h"
#include "getlabel.h"
+#include "gtk-mac-image-utils.h"
#import "GNSMenuBar.h"
//#define DEBUG(format, ...) g_printerr ("%s: " format, G_STRFUNC, ## __VA_ARGS__)
@@ -446,6 +447,107 @@ cocoa_menu_item_sync (GtkWidget* menu_item)
}
/*
+ * nsimage_from_pixbuf:
+ * @pixbuf: The GdkPixbuf* to convert
+ *
+ * Create an NSImage from a CGImageRef.
+ * Lifted from http://www.cocoadev.com/index.pl?CGImageRef
+ *
+ * Returns: An auto-released NSImage*
+ */
+static NSImage*
+nsimage_from_pixbuf(GdkPixbuf *pixbuf)
+{
+ CGImageRef image = NULL;
+ NSRect imageRect = NSMakeRect(0.0, 0.0, 0.0, 0.0);
+ CGContextRef imageContext = nil;
+ NSImage* newImage = nil;
+
+ g_return_val_if_fail (pixbuf != NULL, NULL);
+ image = gtkosx_create_cgimage_from_pixbuf (pixbuf);
+ // Get the image dimensions.
+ imageRect.size.height = CGImageGetHeight(image);
+ imageRect.size.width = CGImageGetWidth(image);
+
+ // Create a new image to receive the Quartz image data.
+ newImage = [[[NSImage alloc] initWithSize:imageRect.size] autorelease];
+ [newImage lockFocus];
+
+ // Get the Quartz context and draw.
+ imageContext = (CGContextRef)[[NSGraphicsContext currentContext]
+ graphicsPort];
+ CGContextDrawImage(imageContext, *(CGRect*)&imageRect, image);
+ [newImage unlockFocus];
+ CGImageRelease (image);
+ return newImage;
+}
+
+/*
+ * If the menu item does contain an image Widget, depending of what this widget is,
+ * get a PixBuf with the following method:
+ * - menu_item is GtkImage of type GTK_IMAGE_PIXBUF: use gtk_image_get_pixbuf()
+ * - menu_item is GtkImage of type GTK_IMAGE_STOCK: use gtk_widget_render_icon()
+ * - menu_item is GtkWidget: use gtk_offscreen_window_get_pixbuf() on GtkOffscreenWindow
+ */
+static void
+cocoa_menu_item_add_item_image (_GNSMenuItem* cocoa_item, GtkWidget* menu_item)
+{
+ GtkWidget *menu_image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM(menu_item));
+
+ if (menu_image) {
+ NSImage *image = nil;
+ if (GTK_IS_IMAGE (menu_image)) {
+ if (gtk_image_get_storage_type(GTK_IMAGE(menu_image)) == GTK_IMAGE_PIXBUF) {
+ DEBUG("Menu image is GTK_IMAGE_PIXBUF\n");
+ GdkPixbuf *pixbuf = gtk_image_get_pixbuf(GTK_IMAGE(menu_image));
+ image = nsimage_from_pixbuf(pixbuf);
+ }
+ else if (gtk_image_get_storage_type(GTK_IMAGE(menu_image)) == GTK_IMAGE_STOCK) {
+ DEBUG("Menu image is GTK_IMAGE_STOCK\n");
+ gchar *stock_id;
+ GtkIconSize size;
+ gtk_image_get_stock(GTK_IMAGE(menu_image), &stock_id, &size);
+ GdkPixbuf *pixbuf = gtk_widget_render_icon(menu_image, stock_id, size, "");
+ image = nsimage_from_pixbuf(pixbuf);
+ g_object_unref(pixbuf);
+ }
+ }
+ if (!image) {
+ DEBUG("Menu image is GTK_WIDGET\n");
+ // Take menu image widget out of menu item
+ g_object_ref(menu_image);
+ gtk_widget_unparent (menu_image);
+ GTK_IMAGE_MENU_ITEM(menu_item)->image = NULL;
+ g_object_notify(G_OBJECT(menu_item), "image");
+ // Put menu image widget in Offscreen Window, take a pixbuf
+ GtkWidget *offscreenWindow = gtk_offscreen_window_new();
+ gtk_container_add(GTK_CONTAINER(offscreenWindow), menu_image);
+ // Show with proper size
+ gtk_widget_show_all(offscreenWindow);
+ GtkRequisition req;
+ GtkAllocation alloc;
+ gtk_widget_size_request (menu_image, &req);
+ alloc.x = alloc.y = 0;
+ alloc.width = req.width;
+ alloc.height = req.height;
+ gtk_widget_size_allocate (menu_image, &alloc);
+ while (gtk_events_pending ())
+ gtk_main_iteration_do (FALSE);
+ // Take a pixbuf of the offscreen window, convert to image
+ GdkPixbuf *pixbuf = gtk_offscreen_window_get_pixbuf(GTK_OFFSCREEN_WINDOW(offscreenWindow));
+ image = nsimage_from_pixbuf(pixbuf);
+ g_object_unref(pixbuf);
+ // Take menu image widget out of offscreen window, back into menu item
+ gtk_container_remove(GTK_CONTAINER(offscreenWindow), menu_image);
+ gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item), menu_image);
+ g_object_unref(menu_image);
+ }
+ [cocoa_item setImage: image];
+ }
+
+}
+
+/*
* Public Functions
*/
@@ -487,6 +589,9 @@ cocoa_menu_item_add_item (NSMenu* cocoa_menu, GtkWidget* menu_item, int index)
DEBUG ("\tan item\n");
}
cocoa_menu_item_connect (menu_item, (_GNSMenuItem*) cocoa_item, label);
+ if (GTK_IS_IMAGE_MENU_ITEM (menu_item)) {
+ cocoa_menu_item_add_item_image(cocoa_item, menu_item);
+ }
[ cocoa_item setEnabled:YES];
/* connect GtkMenuItem and _GNSMenuItem so that we can notice changes
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]