GtkImageMenuItem



Hi,

Implemented ImageMenuItem which just lets you put a widget next to the
menu text. It takes any widget, but it's called ImageMenuItem because
using something other than a widget that displays an image is
unlikely, and I can't think of a better name. 

The API is like this:

GtkWidget* gtk_image_menu_item_new       (GtkWidget        *widget,
                                          const gchar      *label);
void       gtk_image_menu_item_add_image (GtkImageMenuItem *image_menu_item,
                                          GtkWidget        *child);
GtkWidget* gtk_image_menu_item_get_image (GtkImageMenuItem *image_menu_item);

Full patch appended, will apply shortly. This widget allows
implementing stock support in the item factory.

BTW, the way that toggle_size_request/toggle_size_allocate work means
that menu items can't be placed in a container that doesn't special
case them, because the toggle size isn't included in
widget->requisition. Dunno if this has already been discussed, is this
intentional or just a bug?

Havoc

Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gtk+/ChangeLog,v
retrieving revision 1.1712
diff -u -u -r1.1712 ChangeLog
--- ChangeLog	2001/02/09 00:40:44	1.1712
+++ ChangeLog	2001/02/10 19:00:09
@@ -1,3 +1,22 @@
+2001-02-10  Havoc Pennington  <hp pobox com>
+
+	* gtk/gtkmenubar.c (gtk_menu_bar_size_request): consider toggle
+	size in the size request 
+	(gtk_menu_bar_size_allocate): consider toggle size here
+
+	* gtk/gtkimagemenuitem.h, gtkimagemenuitem.c: Menu item
+	that displays a widget in the toggle slot
+
+	* gtk/testgtk.c: test GtkImageMenuItem
+	 
+	* gtk/gtkmenuitem.h: Use "gint" not "guint16" for toggle size
+	request and allocation
+
+	* gtk/gtkmenu.c (gtk_menu_size_request): use gint not guint16x
+
+	* gtk/gtkcheckmenuitem.c
+	(gtk_check_menu_item_toggle_size_request): ditto
+	
 2001-02-08  Havoc Pennington  <hp redhat com>
 
 	* gtk/gtkbin.c (gtk_bin_add): better error message if you try to
Index: gtk/Makefile.am
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/Makefile.am,v
retrieving revision 1.150
diff -u -u -r1.150 Makefile.am
--- gtk/Makefile.am	2001/02/08 23:36:51	1.150
+++ gtk/Makefile.am	2001/02/10 19:00:09
@@ -104,6 +104,7 @@
 	gtkhsv.h		\
 	gtkiconfactory.h	\
 	gtkimage.h		\
+	gtkimagemenuitem.h	\
 	gtkimcontext.h		\
 	gtkimmodule.h		\
 	gtkimmulticontext.h	\
@@ -260,6 +261,7 @@
 	gtkhsv.c		\
 	gtkiconfactory.c	\
 	gtkimage.c		\
+	gtkimagemenuitem.c	\
 	gtkimcontext.c		\
 	gtkimcontextsimple.c	\
 	gtkimcontextsimple.h	\
Index: gtk/gtk.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtk.h,v
retrieving revision 1.42
diff -u -u -r1.42 gtk.h
--- gtk/gtk.h	2001/02/04 07:26:31	1.42
+++ gtk/gtk.h	2001/02/10 19:00:09
@@ -82,6 +82,7 @@
 #include <gtk/gtkhseparator.h>
 #include <gtk/gtkiconfactory.h>
 #include <gtk/gtkimage.h>
+#include <gtk/gtkimagemenuitem.h>
 #include <gtk/gtkimcontext.h>
 #include <gtk/gtkimmulticontext.h>
 #include <gtk/gtkinputdialog.h>
Index: gtk/gtkcheckmenuitem.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkcheckmenuitem.c,v
retrieving revision 1.27
diff -u -u -r1.27 gtkcheckmenuitem.c
--- gtk/gtkcheckmenuitem.c	2000/12/13 01:34:38	1.27
+++ gtk/gtkcheckmenuitem.c	2001/02/10 19:00:09
@@ -42,7 +42,7 @@
 						      GdkEventExpose        *event);
 static void gtk_check_menu_item_activate             (GtkMenuItem           *menu_item);
 static void gtk_check_menu_item_toggle_size_request  (GtkMenuItem           *menu_item,
-						      guint16               *requisition);
+						      gint                  *requisition);
 static void gtk_check_menu_item_draw_indicator       (GtkCheckMenuItem      *check_menu_item,
 						      GdkRectangle          *area);
 static void gtk_real_check_menu_item_draw_indicator  (GtkCheckMenuItem      *check_menu_item,
@@ -147,7 +147,7 @@
 
 static void
 gtk_check_menu_item_toggle_size_request (GtkMenuItem *menu_item,
-					 guint16     *requisition)
+					 gint        *requisition)
 {
   g_return_if_fail (menu_item != NULL);
   g_return_if_fail (GTK_IS_CHECK_MENU_ITEM (menu_item));
Index: gtk/gtkimagemenuitem.c
===================================================================
RCS file: gtkimagemenuitem.c
diff -N gtkimagemenuitem.c
--- /dev/null	Tue May  5 16:32:27 1998
+++ gtkimagemenuitem.c	Sat Feb 10 14:00:09 2001
@@ -0,0 +1,383 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2001 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+#include "gtkimagemenuitem.h"
+#include "gtkaccellabel.h"
+#include "gtksignal.h"
+
+static void gtk_image_menu_item_class_init           (GtkImageMenuItemClass *klass);
+static void gtk_image_menu_item_init                 (GtkImageMenuItem      *image_menu_item);
+
+static void gtk_image_menu_item_destroy              (GtkObject        *object);
+static void gtk_image_menu_item_size_request         (GtkWidget        *widget,
+                                                      GtkRequisition   *requisition);
+static void gtk_image_menu_item_size_allocate        (GtkWidget        *widget,
+                                                      GtkAllocation    *allocation);
+static gint gtk_image_menu_item_expose               (GtkWidget             *widget,
+						      GdkEventExpose        *event);
+static void gtk_image_menu_item_remove               (GtkContainer          *container,
+                                                      GtkWidget             *child);
+static void gtk_image_menu_item_toggle_size_request  (GtkMenuItem           *menu_item,
+						      gint                  *requisition);
+
+static void gtk_image_menu_item_map        (GtkWidget      *widget);
+static void gtk_image_menu_item_unmap      (GtkWidget      *widget);
+static void gtk_image_menu_item_forall     (GtkContainer   *container,
+                                            gboolean	    include_internals,
+                                            GtkCallback     callback,
+                                            gpointer        callback_data);
+
+static GtkMenuItemClass *parent_class = NULL;
+
+GtkType
+gtk_image_menu_item_get_type (void)
+{
+  static GtkType image_menu_item_type = 0;
+
+  if (!image_menu_item_type)
+    {
+      static const GtkTypeInfo image_menu_item_info =
+      {
+        "GtkImageMenuItem",
+        sizeof (GtkImageMenuItem),
+        sizeof (GtkImageMenuItemClass),
+        (GtkClassInitFunc) gtk_image_menu_item_class_init,
+        (GtkObjectInitFunc) gtk_image_menu_item_init,
+        /* reserved_1 */ NULL,
+        /* reserved_2 */ NULL,
+        (GtkClassInitFunc) NULL,
+      };
+
+      image_menu_item_type = gtk_type_unique (GTK_TYPE_MENU_ITEM, &image_menu_item_info);
+    }
+
+  return image_menu_item_type;
+}
+
+static void
+gtk_image_menu_item_class_init (GtkImageMenuItemClass *klass)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+  GtkMenuItemClass *menu_item_class;
+  GtkContainerClass *container_class;
+  
+  object_class = (GtkObjectClass*) klass;
+  widget_class = (GtkWidgetClass*) klass;
+  menu_item_class = (GtkMenuItemClass*) klass;
+  container_class = (GtkContainerClass*) klass;
+  
+  parent_class = gtk_type_class (GTK_TYPE_MENU_ITEM);
+
+  object_class->destroy = gtk_image_menu_item_destroy;
+  
+  widget_class->expose_event = gtk_image_menu_item_expose;
+  widget_class->size_request = gtk_image_menu_item_size_request;
+  widget_class->size_allocate = gtk_image_menu_item_size_allocate;
+  widget_class->map = gtk_image_menu_item_map;
+  widget_class->unmap = gtk_image_menu_item_unmap;
+
+  container_class->forall = gtk_image_menu_item_forall;
+  container_class->remove = gtk_image_menu_item_remove;
+  
+  menu_item_class->toggle_size_request = gtk_image_menu_item_toggle_size_request;
+}
+
+static void
+gtk_image_menu_item_init (GtkImageMenuItem *image_menu_item)
+{
+  image_menu_item->image = NULL;
+}
+
+static void
+gtk_image_menu_item_destroy (GtkObject *object)
+{
+  GtkImageMenuItem *image_menu_item;
+
+  image_menu_item = GTK_IMAGE_MENU_ITEM (object);  
+
+  /* If you change forall to treat the image widget as
+   * an internal, then you have to destroy the image widget
+   * here.
+   */
+  
+  (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gtk_image_menu_item_toggle_size_request (GtkMenuItem *menu_item,
+					 gint        *requisition)
+{
+  GtkImageMenuItem *image_menu_item;
+  
+  g_return_if_fail (menu_item != NULL);
+  g_return_if_fail (GTK_IS_IMAGE_MENU_ITEM (menu_item));
+
+  image_menu_item = GTK_IMAGE_MENU_ITEM (menu_item);
+
+  if (image_menu_item->image)
+    *requisition = image_menu_item->image->requisition.width;
+  else
+    *requisition = 0;
+}
+
+
+static void
+gtk_image_menu_item_size_request (GtkWidget      *widget,
+                                  GtkRequisition *requisition)
+{
+  GtkImageMenuItem *image_menu_item;
+  gint child_height = 0;
+  
+  image_menu_item = GTK_IMAGE_MENU_ITEM (widget);
+  
+  if (image_menu_item->image && GTK_WIDGET_VISIBLE (image_menu_item->image))
+    {
+      GtkRequisition child_requisition;
+      
+      gtk_widget_size_request (image_menu_item->image,
+                               &child_requisition);
+
+      child_height = child_requisition.height;
+    }
+  
+  (* GTK_WIDGET_CLASS (parent_class)->size_request) (widget, requisition);
+
+  /* not done with height since that happens via the
+   * toggle_size_request
+   */
+  requisition->height = MAX (requisition->height, child_height);
+  
+  /* Note that GtkMenuShell always size requests before
+   * toggle_size_request, so toggle_size_request will be able to use
+   * image_menu_item->image->requisition
+   */
+}
+
+static void
+gtk_image_menu_item_size_allocate (GtkWidget     *widget,
+                                   GtkAllocation *allocation)
+{
+  GtkImageMenuItem *image_menu_item;
+  
+  image_menu_item = GTK_IMAGE_MENU_ITEM (widget);  
+  
+  (* GTK_WIDGET_CLASS (parent_class)->size_allocate) (widget, allocation);
+
+  if (image_menu_item->image)
+    {
+      gint width, height, x, y;
+      GtkAllocation child_allocation;
+      
+      /* Man this is lame hardcoding action, but I can't
+       * come up with a solution that's really better.
+       */
+      
+      width = image_menu_item->image->requisition.width;
+      height = image_menu_item->image->requisition.height;
+
+      x = (GTK_CONTAINER (image_menu_item)->border_width +
+	   widget->style->xthickness) +
+        (GTK_MENU_ITEM (image_menu_item)->toggle_size - width) / 2;
+      y = (widget->allocation.height - height) / 2;
+
+      child_allocation.width = width;
+      child_allocation.height = height;
+      child_allocation.x = MAX (x, 0);
+      child_allocation.y = MAX (y, 0);
+
+      gtk_widget_size_allocate (image_menu_item->image, &child_allocation);
+    }
+}
+
+static gint
+gtk_image_menu_item_expose (GtkWidget      *widget,
+			    GdkEventExpose *event)
+{
+  GdkEventExpose child_event;
+  GtkImageMenuItem *image_menu_item;
+  
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_IMAGE_MENU_ITEM (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  image_menu_item = GTK_IMAGE_MENU_ITEM (widget);
+  
+  if (GTK_WIDGET_CLASS (parent_class)->expose_event)
+    (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
+
+  child_event = *event;
+  if (image_menu_item->image && GTK_WIDGET_DRAWABLE (image_menu_item->image) &&
+      GTK_WIDGET_NO_WINDOW (image_menu_item->image) &&
+      gtk_widget_intersect (image_menu_item->image, &event->area, &child_event.area))
+    gtk_widget_event (image_menu_item->image, (GdkEvent*) &child_event);
+  
+  return FALSE;
+}
+
+static void
+gtk_image_menu_item_map (GtkWidget *widget)
+{
+  GtkImageMenuItem *image_menu_item;
+
+  g_return_if_fail (GTK_IS_IMAGE_MENU_ITEM (widget));
+
+  image_menu_item = GTK_IMAGE_MENU_ITEM (widget);
+  
+  (* GTK_WIDGET_CLASS (parent_class)->map) (widget);
+
+  if (image_menu_item->image &&
+      GTK_WIDGET_VISIBLE (image_menu_item->image) &&
+      !GTK_WIDGET_MAPPED (image_menu_item->image))
+    gtk_widget_map (image_menu_item->image);
+
+  if (!GTK_WIDGET_NO_WINDOW (widget))
+    gdk_window_show (widget->window);  
+}
+
+static void
+gtk_image_menu_item_unmap (GtkWidget *widget)
+{
+  GtkImageMenuItem *image_menu_item;
+
+  g_return_if_fail (GTK_IS_IMAGE_MENU_ITEM (widget));
+
+  image_menu_item = GTK_IMAGE_MENU_ITEM (widget);
+  
+  (* GTK_WIDGET_CLASS (parent_class)->unmap) (widget);
+  
+  if (!GTK_WIDGET_NO_WINDOW (widget))
+    gdk_window_hide (widget->window);
+  
+  if (image_menu_item->image && GTK_WIDGET_MAPPED (image_menu_item->image))
+    gtk_widget_unmap (image_menu_item->image);  
+}
+
+static void
+gtk_image_menu_item_forall (GtkContainer   *container,
+                            gboolean	    include_internals,
+                            GtkCallback     callback,
+                            gpointer        callback_data)
+{
+  GtkImageMenuItem *image_menu_item;
+
+  g_return_if_fail (GTK_IS_IMAGE_MENU_ITEM (container));
+
+  image_menu_item = GTK_IMAGE_MENU_ITEM (container);
+  
+  (* GTK_CONTAINER_CLASS (parent_class)->forall) (container,
+                                                  include_internals,
+                                                  callback,
+                                                  callback_data);
+
+  if (image_menu_item->image)
+    (* callback) (image_menu_item->image, callback_data);
+}
+
+GtkWidget*
+gtk_image_menu_item_new (GtkWidget   *widget,
+                         const gchar *label)
+{
+  GtkImageMenuItem *image_menu_item;
+  GtkWidget *accel_label;
+  
+  image_menu_item = GTK_IMAGE_MENU_ITEM (g_object_new (GTK_TYPE_IMAGE_MENU_ITEM,
+                                                       NULL));
+
+  accel_label = gtk_accel_label_new (label);
+  gtk_misc_set_alignment (GTK_MISC (accel_label), 0.0, 0.5);
+
+  gtk_container_add (GTK_CONTAINER (image_menu_item), accel_label);
+  gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (accel_label),
+                                    GTK_WIDGET (image_menu_item));
+  gtk_widget_show (accel_label);
+
+  if (widget)
+    gtk_image_menu_item_add_image (image_menu_item, widget);
+  
+  return GTK_WIDGET(image_menu_item);
+}
+
+void
+gtk_image_menu_item_add_image (GtkImageMenuItem *image_menu_item,
+                               GtkWidget        *child)
+{
+  g_return_if_fail (GTK_IS_IMAGE_MENU_ITEM (image_menu_item));
+  g_return_if_fail (image_menu_item->image == NULL);
+  
+  gtk_widget_set_parent (child, GTK_WIDGET (image_menu_item));
+  image_menu_item->image = child;
+
+  if (GTK_WIDGET_REALIZED (child->parent))
+    gtk_widget_realize (child);
+
+  if (GTK_WIDGET_VISIBLE (child->parent) && GTK_WIDGET_VISIBLE (child))
+    {
+      if (GTK_WIDGET_MAPPED (child->parent))
+	gtk_widget_map (child);
+
+      gtk_widget_queue_resize (child);
+    }
+}
+
+GtkWidget*
+gtk_image_menu_item_get_image (GtkImageMenuItem *image_menu_item)
+{
+  g_return_val_if_fail (GTK_IS_IMAGE_MENU_ITEM (image_menu_item), NULL);
+
+  return image_menu_item->image;
+}
+
+void
+gtk_image_menu_item_remove (GtkContainer *container,
+                            GtkWidget    *child)
+{
+  GtkImageMenuItem *image_menu_item;
+
+  image_menu_item = GTK_IMAGE_MENU_ITEM (container);
+
+  if (child == image_menu_item->image)
+    {
+      gboolean widget_was_visible;
+      
+      widget_was_visible = GTK_WIDGET_VISIBLE (child);
+      
+      gtk_widget_unparent (child);
+      image_menu_item->image = NULL;
+      
+      /* queue resize regardless of GTK_WIDGET_VISIBLE (container),
+       * since that's what is needed by toplevels, which derive from GtkBin.
+       */
+      if (widget_was_visible)
+        gtk_widget_queue_resize (GTK_WIDGET (container));
+    }
+  else
+    {
+      (* GTK_CONTAINER_CLASS (parent_class)->remove) (container, child);
+    }
+}
+
+
Index: gtk/gtkimagemenuitem.h
===================================================================
RCS file: gtkimagemenuitem.h
diff -N gtkimagemenuitem.h
--- /dev/null	Tue May  5 16:32:27 1998
+++ gtkimagemenuitem.h	Sat Feb 10 14:00:09 2001
@@ -0,0 +1,77 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+#ifndef __GTK_MENU_IMAGE_ITEM_H__
+#define __GTK_MENU_IMAGE_ITEM_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkmenuitem.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_TYPE_IMAGE_MENU_ITEM            (gtk_image_menu_item_get_type ())
+#define GTK_IMAGE_MENU_ITEM(obj)            (GTK_CHECK_CAST ((obj), GTK_TYPE_IMAGE_MENU_ITEM, GtkImageMenuItem))
+#define GTK_IMAGE_MENU_ITEM_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_IMAGE_MENU_ITEM, GtkImageMenuItemClass))
+#define GTK_IS_IMAGE_MENU_ITEM(obj)         (GTK_CHECK_TYPE ((obj), GTK_TYPE_IMAGE_MENU_ITEM))
+#define GTK_IS_IMAGE_MENU_ITEM_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_IMAGE_MENU_ITEM))
+#define GTK_IMAGE_MENU_ITEM_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_IMAGE_MENU_ITEM, GtkImageMenuItemClass))
+
+
+typedef struct _GtkImageMenuItem       GtkImageMenuItem;
+typedef struct _GtkImageMenuItemClass  GtkImageMenuItemClass;
+
+struct _GtkImageMenuItem
+{
+  GtkMenuItem menu_item;
+
+  /*< private >*/
+  GtkWidget *image;
+};
+
+struct _GtkImageMenuItemClass
+{
+  GtkMenuItemClass parent_class;
+};
+
+
+GtkType	   gtk_image_menu_item_get_type  (void) G_GNUC_CONST;
+GtkWidget* gtk_image_menu_item_new       (GtkWidget        *widget,
+                                          const gchar      *label);
+void       gtk_image_menu_item_add_image (GtkImageMenuItem *image_menu_item,
+                                          GtkWidget        *child);
+GtkWidget* gtk_image_menu_item_get_image (GtkImageMenuItem *image_menu_item);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_IMAGE_MENU_ITEM_H__ */
Index: gtk/gtkmenu.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmenu.c,v
retrieving revision 1.52
diff -u -u -r1.52 gtkmenu.c
--- gtk/gtkmenu.c	2001/02/02 17:53:29	1.52
+++ gtk/gtkmenu.c	2001/02/10 19:00:09
@@ -1089,8 +1089,14 @@
       
       if (GTK_WIDGET_VISIBLE (child))
 	{
-	  guint16 toggle_size;
+	  gint toggle_size;
 
+          /* It's important to size_request the child
+           * before doing the toggle size request, in
+           * case the toggle size request depends on the size
+           * request of a child of the child (e.g. for ImageMenuItem)
+           */
+          
 	  GTK_MENU_ITEM (child)->show_submenu_indicator = TRUE;
 	  gtk_widget_size_request (child, &child_requisition);
 	  
Index: gtk/gtkmenubar.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmenubar.c,v
retrieving revision 1.21
diff -u -u -r1.21 gtkmenubar.c
--- gtk/gtkmenubar.c	2000/12/04 01:15:37	1.21
+++ gtk/gtkmenubar.c	2001/02/10 19:00:09
@@ -237,10 +237,16 @@
 
 	  if (GTK_WIDGET_VISIBLE (child))
 	    {
+              gint toggle_size;
+              
 	      GTK_MENU_ITEM (child)->show_submenu_indicator = FALSE;
 	      gtk_widget_size_request (child, &child_requisition);
-
+              gtk_menu_item_toggle_size_request (GTK_MENU_ITEM (child),
+                                                 &toggle_size);
+              
 	      requisition->width += child_requisition.width;
+              requisition->width += toggle_size;
+              
 	      requisition->height = MAX (requisition->height, child_requisition.height);
 	      /* Support for the right justified help menu */
 	      if ((children == NULL) && GTK_IS_MENU_ITEM(child) &&
@@ -305,11 +311,17 @@
       children = menu_shell->children;
       while (children)
 	{
+          gint toggle_size;          
+
 	  child = children->data;
 	  children = children->next;
 
+          gtk_menu_item_toggle_size_request (GTK_MENU_ITEM (child),
+                                             &toggle_size);
 	  gtk_widget_get_child_requisition (child, &child_requisition);
-	  
+
+          child_requisition.width += toggle_size;
+          
 	  /* Support for the right justified help menu */
 	  if ( (children == NULL) && (GTK_IS_MENU_ITEM(child))
 	      && (GTK_MENU_ITEM(child)->right_justify)) 
@@ -321,6 +333,8 @@
 	    {
 	      child_allocation.width = child_requisition.width;
 
+              gtk_menu_item_toggle_size_allocate (GTK_MENU_ITEM (child),
+                                                  toggle_size);
 	      gtk_widget_size_allocate (child, &child_allocation);
 
 	      child_allocation.x += child_allocation.width + CHILD_SPACING * 2;
Index: gtk/gtkmenuitem.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmenuitem.c,v
retrieving revision 1.45
diff -u -u -r1.45 gtkmenuitem.c
--- gtk/gtkmenuitem.c	2000/12/13 01:34:39	1.45
+++ gtk/gtkmenuitem.c	2001/02/10 19:00:09
@@ -64,9 +64,9 @@
 static void gtk_real_menu_item_deselect             (GtkItem     *item);
 static void gtk_real_menu_item_activate_item        (GtkMenuItem *item);
 static void gtk_real_menu_item_toggle_size_request  (GtkMenuItem *menu_item,
-						     guint16     *requisition);
+						     gint        *requisition);
 static void gtk_real_menu_item_toggle_size_allocate (GtkMenuItem *menu_item,
-						     guint16      allocation);
+						     gint         allocation);
 
 static gint gtk_menu_item_select_timeout (gpointer          data);
 static void gtk_menu_item_popup_submenu  (gpointer     data);
@@ -181,9 +181,9 @@
                     GTK_RUN_FIRST,
                     GTK_CLASS_TYPE (object_class),
                     GTK_SIGNAL_OFFSET (GtkMenuItemClass, toggle_size_allocate),
-                    gtk_marshal_NONE__UINT,
+                    gtk_marshal_NONE__INT,
 		    GTK_TYPE_NONE, 1,
-		    GTK_TYPE_UINT);
+		    GTK_TYPE_INT);
 }
 
 static void
@@ -339,7 +339,7 @@
 
 void
 gtk_menu_item_toggle_size_request (GtkMenuItem *menu_item,
-				   guint16     *requisition)
+				   gint        *requisition)
 {
   g_return_if_fail (menu_item != NULL);
   g_return_if_fail (GTK_IS_MENU_ITEM (menu_item));
@@ -349,7 +349,7 @@
 
 void
 gtk_menu_item_toggle_size_allocate (GtkMenuItem *menu_item,
-				    guint16      allocation)
+				    gint         allocation)
 {
   g_return_if_fail (menu_item != NULL);
   g_return_if_fail (GTK_IS_MENU_ITEM (menu_item));
@@ -652,7 +652,7 @@
 }
 static void
 gtk_real_menu_item_toggle_size_request (GtkMenuItem *menu_item,
-					guint16     *requisition)
+					gint        *requisition)
 {
   g_return_if_fail (menu_item != NULL);
   g_return_if_fail (GTK_IS_MENU_ITEM (menu_item));
@@ -662,7 +662,7 @@
 
 static void
 gtk_real_menu_item_toggle_size_allocate (GtkMenuItem *menu_item,
-					 guint16      allocation)
+					 gint         allocation)
 {
   g_return_if_fail (menu_item != NULL);
   g_return_if_fail (GTK_IS_MENU_ITEM (menu_item));
Index: gtk/gtkmenuitem.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmenuitem.h,v
retrieving revision 1.13
diff -u -u -r1.13 gtkmenuitem.h
--- gtk/gtkmenuitem.h	2000/11/08 17:34:52	1.13
+++ gtk/gtkmenuitem.h	2001/02/10 19:00:09
@@ -81,9 +81,9 @@
   void (* activate)             (GtkMenuItem *menu_item);
   void (* activate_item)        (GtkMenuItem *menu_item);
   void (* toggle_size_request)  (GtkMenuItem *menu_item,
-				 guint16     *requisition);
+				 gint        *requisition);
   void (* toggle_size_allocate) (GtkMenuItem *menu_item,
-				 guint16      allocation);
+				 gint         allocation);
 };
 
 
@@ -102,9 +102,9 @@
 void       gtk_menu_item_deselect             (GtkMenuItem         *menu_item);
 void       gtk_menu_item_activate             (GtkMenuItem         *menu_item);
 void       gtk_menu_item_toggle_size_request  (GtkMenuItem         *menu_item,
-					       guint16             *requisition);
+					       gint                *requisition);
 void       gtk_menu_item_toggle_size_allocate (GtkMenuItem         *menu_item,
-					       guint16              allocation);
+					       gint                 allocation);
 void       gtk_menu_item_right_justify        (GtkMenuItem         *menu_item);
 
 
Index: gtk/testgtk.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/testgtk.c,v
retrieving revision 1.216
diff -u -u -r1.216 testgtk.c
--- gtk/testgtk.c	2001/02/09 00:40:48	1.216
+++ gtk/testgtk.c	2001/02/10 19:00:11
@@ -2703,6 +2703,7 @@
 {
   GtkWidget *menu;
   GtkWidget *menuitem;
+  GtkWidget *image;
   GSList *group;
   char buf[32];
   int i, j;
@@ -2720,6 +2721,13 @@
       gtk_widget_show (menuitem);
     }
 
+  image = gtk_image_new_from_stock (GTK_STOCK_OPEN,
+                                    GTK_ICON_SIZE_MENU);
+  gtk_widget_show (image);
+  menuitem = gtk_image_menu_item_new (image, "Image item");
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+  gtk_widget_show (menuitem);
+  
   for (i = 0, j = 1; i < length; i++, j++)
     {
       sprintf (buf, "item %2d - %d", depth, j);
@@ -2755,6 +2763,7 @@
       GtkWidget *menu;
       GtkWidget *menuitem;
       GtkAccelGroup *accel_group;
+      GtkWidget *image;
       
       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
       
@@ -2792,7 +2801,10 @@
       gtk_menu_bar_append (GTK_MENU_BAR (menubar), menuitem);
       gtk_widget_show (menuitem);
 
-      menuitem = gtk_menu_item_new_with_label ("bar");
+      image = gtk_image_new_from_stock (GTK_STOCK_HELP,
+                                        GTK_ICON_SIZE_MENU);
+      gtk_widget_show (image);
+      menuitem = gtk_image_menu_item_new (image, "Help");
       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (4, 5, TRUE));
       gtk_menu_item_right_justify (GTK_MENU_ITEM (menuitem));
       gtk_menu_bar_append (GTK_MENU_BAR (menubar), menuitem);




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