1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 2001 Red Hat, Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
29 #include "gtkimagemenuitem.h"
31 #include "gtkaccellabel.h"
33 #include "gtkiconfactory.h"
35 #include "gtkmenubar.h"
36 #include "gtkcontainer.h"
37 #include "gtkwindow.h"
38 #include "gtkactivatable.h"
39 #include "gtksizerequest.h"
42 #include "gtkprivate.h"
46 struct _GtkImageMenuItemPrivate
52 guint always_show_image : 1;
60 PROP_ALWAYS_SHOW_IMAGE
63 static GtkActivatableIface *parent_activatable_iface;
65 static void gtk_image_menu_item_destroy (GtkObject *object);
66 static void gtk_image_menu_item_size_request (GtkWidget *widget,
67 GtkRequisition *requisition);
68 static void gtk_image_menu_item_size_allocate (GtkWidget *widget,
69 GtkAllocation *allocation);
70 static void gtk_image_menu_item_map (GtkWidget *widget);
71 static void gtk_image_menu_item_remove (GtkContainer *container,
73 static void gtk_image_menu_item_toggle_size_request (GtkMenuItem *menu_item,
75 static void gtk_image_menu_item_set_label (GtkMenuItem *menu_item,
77 static G_CONST_RETURN gchar *gtk_image_menu_item_get_label (GtkMenuItem *menu_item);
79 static void gtk_image_menu_item_forall (GtkContainer *container,
80 gboolean include_internals,
82 gpointer callback_data);
84 static void gtk_image_menu_item_finalize (GObject *object);
85 static void gtk_image_menu_item_set_property (GObject *object,
89 static void gtk_image_menu_item_get_property (GObject *object,
93 static void gtk_image_menu_item_screen_changed (GtkWidget *widget,
94 GdkScreen *previous_screen);
96 static void gtk_image_menu_item_recalculate (GtkImageMenuItem *image_menu_item);
98 static void gtk_image_menu_item_activatable_interface_init (GtkActivatableIface *iface);
99 static void gtk_image_menu_item_update (GtkActivatable *activatable,
101 const gchar *property_name);
102 static void gtk_image_menu_item_sync_action_properties (GtkActivatable *activatable,
106 G_DEFINE_TYPE_WITH_CODE (GtkImageMenuItem, gtk_image_menu_item, GTK_TYPE_MENU_ITEM,
107 G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTIVATABLE,
108 gtk_image_menu_item_activatable_interface_init))
112 gtk_image_menu_item_class_init (GtkImageMenuItemClass *klass)
114 GObjectClass *gobject_class = (GObjectClass*) klass;
115 GtkObjectClass *object_class = (GtkObjectClass*) klass;
116 GtkWidgetClass *widget_class = (GtkWidgetClass*) klass;
117 GtkMenuItemClass *menu_item_class = (GtkMenuItemClass*) klass;
118 GtkContainerClass *container_class = (GtkContainerClass*) klass;
120 object_class->destroy = gtk_image_menu_item_destroy;
122 widget_class->screen_changed = gtk_image_menu_item_screen_changed;
123 widget_class->size_request = gtk_image_menu_item_size_request;
124 widget_class->size_allocate = gtk_image_menu_item_size_allocate;
125 widget_class->map = gtk_image_menu_item_map;
127 container_class->forall = gtk_image_menu_item_forall;
128 container_class->remove = gtk_image_menu_item_remove;
130 menu_item_class->toggle_size_request = gtk_image_menu_item_toggle_size_request;
131 menu_item_class->set_label = gtk_image_menu_item_set_label;
132 menu_item_class->get_label = gtk_image_menu_item_get_label;
134 gobject_class->finalize = gtk_image_menu_item_finalize;
135 gobject_class->set_property = gtk_image_menu_item_set_property;
136 gobject_class->get_property = gtk_image_menu_item_get_property;
138 g_object_class_install_property (gobject_class,
140 g_param_spec_object ("image",
142 P_("Child widget to appear next to the menu text"),
144 GTK_PARAM_READWRITE));
146 * GtkImageMenuItem:use-stock:
148 * If %TRUE, the label set in the menuitem is used as a
149 * stock id to select the stock item for the item.
153 g_object_class_install_property (gobject_class,
155 g_param_spec_boolean ("use-stock",
157 P_("Whether to use the label text to create a stock menu item"),
159 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
162 * GtkImageMenuItem:always-show-image:
164 * If %TRUE, the menu item will ignore the #GtkSettings:gtk-menu-images
165 * setting and always show the image, if available.
167 * Use this property if the menuitem would be useless or hard to use
172 g_object_class_install_property (gobject_class,
173 PROP_ALWAYS_SHOW_IMAGE,
174 g_param_spec_boolean ("always-show-image",
175 P_("Always show image"),
176 P_("Whether the image will always be shown"),
178 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
181 * GtkImageMenuItem:accel-group:
183 * The Accel Group to use for stock accelerator keys
187 g_object_class_install_property (gobject_class,
189 g_param_spec_object ("accel-group",
191 P_("The Accel Group to use for stock accelerator keys"),
192 GTK_TYPE_ACCEL_GROUP,
193 GTK_PARAM_WRITABLE));
195 gtk_settings_install_property (g_param_spec_boolean ("gtk-menu-images",
196 P_("Show menu images"),
197 P_("Whether images should be shown in menus"),
199 GTK_PARAM_READWRITE));
201 g_type_class_add_private (object_class, sizeof (GtkImageMenuItemPrivate));
205 gtk_image_menu_item_init (GtkImageMenuItem *image_menu_item)
207 GtkImageMenuItemPrivate *priv;
209 image_menu_item->priv = G_TYPE_INSTANCE_GET_PRIVATE (image_menu_item,
210 GTK_TYPE_IMAGE_MENU_ITEM,
211 GtkImageMenuItemPrivate);
212 priv = image_menu_item->priv;
215 priv->use_stock = FALSE;
220 gtk_image_menu_item_finalize (GObject *object)
222 GtkImageMenuItemPrivate *priv = GTK_IMAGE_MENU_ITEM (object)->priv;
224 g_free (priv->label);
227 G_OBJECT_CLASS (gtk_image_menu_item_parent_class)->finalize (object);
231 gtk_image_menu_item_set_property (GObject *object,
236 GtkImageMenuItem *image_menu_item = GTK_IMAGE_MENU_ITEM (object);
241 gtk_image_menu_item_set_image (image_menu_item, (GtkWidget *) g_value_get_object (value));
244 gtk_image_menu_item_set_use_stock (image_menu_item, g_value_get_boolean (value));
246 case PROP_ALWAYS_SHOW_IMAGE:
247 gtk_image_menu_item_set_always_show_image (image_menu_item, g_value_get_boolean (value));
249 case PROP_ACCEL_GROUP:
250 gtk_image_menu_item_set_accel_group (image_menu_item, g_value_get_object (value));
253 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
259 gtk_image_menu_item_get_property (GObject *object,
264 GtkImageMenuItem *image_menu_item = GTK_IMAGE_MENU_ITEM (object);
269 g_value_set_object (value, gtk_image_menu_item_get_image (image_menu_item));
272 g_value_set_boolean (value, gtk_image_menu_item_get_use_stock (image_menu_item));
274 case PROP_ALWAYS_SHOW_IMAGE:
275 g_value_set_boolean (value, gtk_image_menu_item_get_always_show_image (image_menu_item));
278 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
284 show_image (GtkImageMenuItem *image_menu_item)
286 GtkImageMenuItemPrivate *priv = image_menu_item->priv;
287 GtkSettings *settings = gtk_widget_get_settings (GTK_WIDGET (image_menu_item));
290 if (priv->always_show_image)
293 g_object_get (settings, "gtk-menu-images", &show, NULL);
299 gtk_image_menu_item_map (GtkWidget *widget)
301 GtkImageMenuItem *image_menu_item = GTK_IMAGE_MENU_ITEM (widget);
302 GtkImageMenuItemPrivate *priv = image_menu_item->priv;
304 GTK_WIDGET_CLASS (gtk_image_menu_item_parent_class)->map (widget);
307 g_object_set (priv->image,
308 "visible", show_image (image_menu_item),
313 gtk_image_menu_item_destroy (GtkObject *object)
315 GtkImageMenuItem *image_menu_item = GTK_IMAGE_MENU_ITEM (object);
316 GtkImageMenuItemPrivate *priv = image_menu_item->priv;
319 gtk_container_remove (GTK_CONTAINER (image_menu_item),
322 GTK_OBJECT_CLASS (gtk_image_menu_item_parent_class)->destroy (object);
326 gtk_image_menu_item_toggle_size_request (GtkMenuItem *menu_item,
329 GtkImageMenuItem *image_menu_item = GTK_IMAGE_MENU_ITEM (menu_item);
330 GtkImageMenuItemPrivate *priv = image_menu_item->priv;
331 GtkPackDirection pack_dir;
333 GtkWidget *widget = GTK_WIDGET (menu_item);
335 parent = gtk_widget_get_parent (widget);
337 if (GTK_IS_MENU_BAR (parent))
338 pack_dir = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (parent));
340 pack_dir = GTK_PACK_DIRECTION_LTR;
344 if (priv->image && gtk_widget_get_visible (priv->image))
346 GtkRequisition image_requisition;
347 guint toggle_spacing;
349 gtk_size_request_get_size (GTK_SIZE_REQUEST (priv->image),
350 &image_requisition, NULL);
352 gtk_widget_style_get (GTK_WIDGET (menu_item),
353 "toggle-spacing", &toggle_spacing,
356 if (pack_dir == GTK_PACK_DIRECTION_LTR || pack_dir == GTK_PACK_DIRECTION_RTL)
358 if (image_requisition.width > 0)
359 *requisition = image_requisition.width + toggle_spacing;
363 if (image_requisition.height > 0)
364 *requisition = image_requisition.height + toggle_spacing;
370 gtk_image_menu_item_recalculate (GtkImageMenuItem *image_menu_item)
372 GtkImageMenuItemPrivate *priv = image_menu_item->priv;
373 GtkStockItem stock_item;
375 const gchar *resolved_label = priv->label;
377 if (priv->use_stock && priv->label)
382 image = gtk_image_new_from_stock (priv->label, GTK_ICON_SIZE_MENU);
383 gtk_image_menu_item_set_image (image_menu_item, image);
386 if (gtk_stock_lookup (priv->label, &stock_item))
387 resolved_label = stock_item.label;
389 gtk_menu_item_set_use_underline (GTK_MENU_ITEM (image_menu_item), TRUE);
393 (gtk_image_menu_item_parent_class)->set_label (GTK_MENU_ITEM (image_menu_item), resolved_label);
398 gtk_image_menu_item_set_label (GtkMenuItem *menu_item,
401 GtkImageMenuItemPrivate *priv = GTK_IMAGE_MENU_ITEM (menu_item)->priv;
403 if (priv->label != label)
405 g_free (priv->label);
406 priv->label = g_strdup (label);
408 gtk_image_menu_item_recalculate (GTK_IMAGE_MENU_ITEM (menu_item));
410 g_object_notify (G_OBJECT (menu_item), "label");
415 static G_CONST_RETURN gchar *
416 gtk_image_menu_item_get_label (GtkMenuItem *menu_item)
418 GtkImageMenuItemPrivate *priv = GTK_IMAGE_MENU_ITEM (menu_item)->priv;
424 gtk_image_menu_item_size_request (GtkWidget *widget,
425 GtkRequisition *requisition)
427 GtkImageMenuItem *image_menu_item = GTK_IMAGE_MENU_ITEM (widget);
428 GtkImageMenuItemPrivate *priv = image_menu_item->priv;
429 gint child_width = 0;
430 gint child_height = 0;
431 GtkPackDirection pack_dir;
434 parent = gtk_widget_get_parent (widget);
436 if (GTK_IS_MENU_BAR (parent))
437 pack_dir = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (parent));
439 pack_dir = GTK_PACK_DIRECTION_LTR;
441 if (priv->image && gtk_widget_get_visible (priv->image))
443 GtkRequisition child_requisition;
445 gtk_size_request_get_size (GTK_SIZE_REQUEST (priv->image),
446 &child_requisition, NULL);
448 child_width = child_requisition.width;
449 child_height = child_requisition.height;
452 GTK_WIDGET_CLASS (gtk_image_menu_item_parent_class)->size_request (widget, requisition);
454 /* not done with height since that happens via the
455 * toggle_size_request
457 if (pack_dir == GTK_PACK_DIRECTION_LTR || pack_dir == GTK_PACK_DIRECTION_RTL)
458 requisition->height = MAX (requisition->height, child_height);
460 requisition->width = MAX (requisition->width, child_width);
463 /* Note that GtkMenuShell always size requests before
464 * toggle_size_request, so toggle_size_request will be able to use
465 * priv->image->requisition
470 gtk_image_menu_item_size_allocate (GtkWidget *widget,
471 GtkAllocation *allocation)
473 GtkImageMenuItem *image_menu_item = GTK_IMAGE_MENU_ITEM (widget);
474 GtkImageMenuItemPrivate *priv = image_menu_item->priv;
475 GtkAllocation widget_allocation;
476 GtkPackDirection pack_dir;
479 parent = gtk_widget_get_parent (widget);
481 if (GTK_IS_MENU_BAR (parent))
482 pack_dir = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (parent));
484 pack_dir = GTK_PACK_DIRECTION_LTR;
486 GTK_WIDGET_CLASS (gtk_image_menu_item_parent_class)->size_allocate (widget, allocation);
488 if (priv->image && gtk_widget_get_visible (priv->image))
491 GtkRequisition child_requisition;
492 GtkAllocation child_allocation;
493 guint horizontal_padding, toggle_spacing;
495 gtk_widget_style_get (widget,
496 "horizontal-padding", &horizontal_padding,
497 "toggle-spacing", &toggle_spacing,
500 /* Man this is lame hardcoding action, but I can't
501 * come up with a solution that's really better.
504 gtk_size_request_get_size (GTK_SIZE_REQUEST (priv->image),
505 &child_requisition, NULL);
507 gtk_widget_get_allocation (widget, &widget_allocation);
509 if (pack_dir == GTK_PACK_DIRECTION_LTR ||
510 pack_dir == GTK_PACK_DIRECTION_RTL)
512 offset = gtk_container_get_border_width (GTK_CONTAINER (image_menu_item)) +
513 gtk_widget_get_style (widget)->xthickness;
515 if ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) ==
516 (pack_dir == GTK_PACK_DIRECTION_LTR))
517 x = offset + horizontal_padding +
518 (GTK_MENU_ITEM (image_menu_item)->toggle_size -
519 toggle_spacing - child_requisition.width) / 2;
521 x = widget_allocation.width - offset - horizontal_padding -
522 GTK_MENU_ITEM (image_menu_item)->toggle_size + toggle_spacing +
523 (GTK_MENU_ITEM (image_menu_item)->toggle_size -
524 toggle_spacing - child_requisition.width) / 2;
526 y = (widget_allocation.height - child_requisition.height) / 2;
530 offset = gtk_container_get_border_width (GTK_CONTAINER (image_menu_item)) +
531 gtk_widget_get_style (widget)->ythickness;
533 if ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) ==
534 (pack_dir == GTK_PACK_DIRECTION_TTB))
535 y = offset + horizontal_padding +
536 (GTK_MENU_ITEM (image_menu_item)->toggle_size -
537 toggle_spacing - child_requisition.height) / 2;
539 y = widget_allocation.height - offset - horizontal_padding -
540 GTK_MENU_ITEM (image_menu_item)->toggle_size + toggle_spacing +
541 (GTK_MENU_ITEM (image_menu_item)->toggle_size -
542 toggle_spacing - child_requisition.height) / 2;
544 x = (widget_allocation.width - child_requisition.width) / 2;
547 child_allocation.width = child_requisition.width;
548 child_allocation.height = child_requisition.height;
549 child_allocation.x = widget_allocation.x + MAX (x, 0);
550 child_allocation.y = widget_allocation.y + MAX (y, 0);
552 gtk_widget_size_allocate (priv->image, &child_allocation);
557 gtk_image_menu_item_forall (GtkContainer *container,
558 gboolean include_internals,
559 GtkCallback callback,
560 gpointer callback_data)
562 GtkImageMenuItem *image_menu_item = GTK_IMAGE_MENU_ITEM (container);
563 GtkImageMenuItemPrivate *priv = image_menu_item->priv;
565 GTK_CONTAINER_CLASS (gtk_image_menu_item_parent_class)->forall (container,
570 if (include_internals && priv->image)
571 (* callback) (priv->image, callback_data);
576 gtk_image_menu_item_activatable_interface_init (GtkActivatableIface *iface)
578 parent_activatable_iface = g_type_interface_peek_parent (iface);
579 iface->update = gtk_image_menu_item_update;
580 iface->sync_action_properties = gtk_image_menu_item_sync_action_properties;
584 activatable_update_stock_id (GtkImageMenuItem *image_menu_item, GtkAction *action)
587 const gchar *stock_id = gtk_action_get_stock_id (action);
589 image = gtk_image_menu_item_get_image (image_menu_item);
591 if (GTK_IS_IMAGE (image) &&
592 stock_id && gtk_icon_factory_lookup_default (stock_id))
594 gtk_image_set_from_stock (GTK_IMAGE (image), stock_id, GTK_ICON_SIZE_MENU);
602 activatable_update_gicon (GtkImageMenuItem *image_menu_item, GtkAction *action)
605 GIcon *icon = gtk_action_get_gicon (action);
606 const gchar *stock_id = gtk_action_get_stock_id (action);
608 image = gtk_image_menu_item_get_image (image_menu_item);
610 if (icon && GTK_IS_IMAGE (image) &&
611 !(stock_id && gtk_icon_factory_lookup_default (stock_id)))
613 gtk_image_set_from_gicon (GTK_IMAGE (image), icon, GTK_ICON_SIZE_MENU);
621 activatable_update_icon_name (GtkImageMenuItem *image_menu_item, GtkAction *action)
624 const gchar *icon_name = gtk_action_get_icon_name (action);
626 image = gtk_image_menu_item_get_image (image_menu_item);
628 if (GTK_IS_IMAGE (image) &&
629 (gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_EMPTY ||
630 gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_ICON_NAME))
632 gtk_image_set_from_icon_name (GTK_IMAGE (image), icon_name, GTK_ICON_SIZE_MENU);
637 gtk_image_menu_item_update (GtkActivatable *activatable,
639 const gchar *property_name)
641 GtkImageMenuItem *image_menu_item;
642 gboolean use_appearance;
644 image_menu_item = GTK_IMAGE_MENU_ITEM (activatable);
646 parent_activatable_iface->update (activatable, action, property_name);
648 use_appearance = gtk_activatable_get_use_action_appearance (activatable);
652 if (strcmp (property_name, "stock-id") == 0)
653 activatable_update_stock_id (image_menu_item, action);
654 else if (strcmp (property_name, "gicon") == 0)
655 activatable_update_gicon (image_menu_item, action);
656 else if (strcmp (property_name, "icon-name") == 0)
657 activatable_update_icon_name (image_menu_item, action);
661 gtk_image_menu_item_sync_action_properties (GtkActivatable *activatable,
664 GtkImageMenuItem *image_menu_item;
666 gboolean use_appearance;
668 image_menu_item = GTK_IMAGE_MENU_ITEM (activatable);
670 parent_activatable_iface->sync_action_properties (activatable, action);
675 use_appearance = gtk_activatable_get_use_action_appearance (activatable);
679 image = gtk_image_menu_item_get_image (image_menu_item);
680 if (image && !GTK_IS_IMAGE (image))
682 gtk_image_menu_item_set_image (image_menu_item, NULL);
688 image = gtk_image_new ();
689 gtk_widget_show (image);
690 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (activatable),
694 if (!activatable_update_stock_id (image_menu_item, action) &&
695 !activatable_update_gicon (image_menu_item, action))
696 activatable_update_icon_name (image_menu_item, action);
698 gtk_image_menu_item_set_always_show_image (image_menu_item,
699 gtk_action_get_always_show_image (action));
704 * gtk_image_menu_item_new:
705 * @returns: a new #GtkImageMenuItem.
707 * Creates a new #GtkImageMenuItem with an empty label.
710 gtk_image_menu_item_new (void)
712 return g_object_new (GTK_TYPE_IMAGE_MENU_ITEM, NULL);
716 * gtk_image_menu_item_new_with_label:
717 * @label: the text of the menu item.
718 * @returns: a new #GtkImageMenuItem.
720 * Creates a new #GtkImageMenuItem containing a label.
723 gtk_image_menu_item_new_with_label (const gchar *label)
725 return g_object_new (GTK_TYPE_IMAGE_MENU_ITEM,
732 * gtk_image_menu_item_new_with_mnemonic:
733 * @label: the text of the menu item, with an underscore in front of the
735 * @returns: a new #GtkImageMenuItem
737 * Creates a new #GtkImageMenuItem containing a label. The label
738 * will be created using gtk_label_new_with_mnemonic(), so underscores
739 * in @label indicate the mnemonic for the menu item.
742 gtk_image_menu_item_new_with_mnemonic (const gchar *label)
744 return g_object_new (GTK_TYPE_IMAGE_MENU_ITEM,
745 "use-underline", TRUE,
751 * gtk_image_menu_item_new_from_stock:
752 * @stock_id: the name of the stock item.
753 * @accel_group: (allow-none): the #GtkAccelGroup to add the menu items
754 * accelerator to, or %NULL.
755 * @returns: a new #GtkImageMenuItem.
757 * Creates a new #GtkImageMenuItem containing the image and text from a
758 * stock item. Some stock ids have preprocessor macros like #GTK_STOCK_OK
759 * and #GTK_STOCK_APPLY.
761 * If you want this menu item to have changeable accelerators, then pass in
762 * %NULL for accel_group. Next call gtk_menu_item_set_accel_path() with an
763 * appropriate path for the menu item, use gtk_stock_lookup() to look up the
764 * standard accelerator for the stock item, and if one is found, call
765 * gtk_accel_map_add_entry() to register it.
768 gtk_image_menu_item_new_from_stock (const gchar *stock_id,
769 GtkAccelGroup *accel_group)
771 return g_object_new (GTK_TYPE_IMAGE_MENU_ITEM,
774 "accel-group", accel_group,
779 * gtk_image_menu_item_set_use_stock:
780 * @image_menu_item: a #GtkImageMenuItem
781 * @use_stock: %TRUE if the menuitem should use a stock item
783 * If %TRUE, the label set in the menuitem is used as a
784 * stock id to select the stock item for the item.
789 gtk_image_menu_item_set_use_stock (GtkImageMenuItem *image_menu_item,
792 GtkImageMenuItemPrivate *priv;
794 g_return_if_fail (GTK_IS_IMAGE_MENU_ITEM (image_menu_item));
796 priv = image_menu_item->priv;
798 if (priv->use_stock != use_stock)
800 priv->use_stock = use_stock;
802 gtk_image_menu_item_recalculate (image_menu_item);
804 g_object_notify (G_OBJECT (image_menu_item), "use-stock");
809 * gtk_image_menu_item_get_use_stock:
810 * @image_menu_item: a #GtkImageMenuItem
812 * Checks whether the label set in the menuitem is used as a
813 * stock id to select the stock item for the item.
815 * Returns: %TRUE if the label set in the menuitem is used as a
816 * stock id to select the stock item for the item
821 gtk_image_menu_item_get_use_stock (GtkImageMenuItem *image_menu_item)
823 g_return_val_if_fail (GTK_IS_IMAGE_MENU_ITEM (image_menu_item), FALSE);
825 return image_menu_item->priv->use_stock;
829 * gtk_image_menu_item_set_always_show_image:
830 * @image_menu_item: a #GtkImageMenuItem
831 * @always_show: %TRUE if the menuitem should always show the image
833 * If %TRUE, the menu item will ignore the #GtkSettings:gtk-menu-images
834 * setting and always show the image, if available.
836 * Use this property if the menuitem would be useless or hard to use
842 gtk_image_menu_item_set_always_show_image (GtkImageMenuItem *image_menu_item,
843 gboolean always_show)
845 GtkImageMenuItemPrivate *priv;
847 g_return_if_fail (GTK_IS_IMAGE_MENU_ITEM (image_menu_item));
849 priv = image_menu_item->priv;
851 if (priv->always_show_image != always_show)
853 priv->always_show_image = always_show;
857 if (show_image (image_menu_item))
858 gtk_widget_show (priv->image);
860 gtk_widget_hide (priv->image);
863 g_object_notify (G_OBJECT (image_menu_item), "always-show-image");
868 * gtk_image_menu_item_get_always_show_image:
869 * @image_menu_item: a #GtkImageMenuItem
871 * Returns whether the menu item will ignore the #GtkSettings:gtk-menu-images
872 * setting and always show the image, if available.
874 * Returns: %TRUE if the menu item will always show the image
879 gtk_image_menu_item_get_always_show_image (GtkImageMenuItem *image_menu_item)
881 g_return_val_if_fail (GTK_IS_IMAGE_MENU_ITEM (image_menu_item), FALSE);
883 return image_menu_item->priv->always_show_image;
888 * gtk_image_menu_item_set_accel_group:
889 * @image_menu_item: a #GtkImageMenuItem
890 * @accel_group: the #GtkAccelGroup
892 * Specifies an @accel_group to add the menu items accelerator to
893 * (this only applies to stock items so a stock item must already
894 * be set, make sure to call gtk_image_menu_item_set_use_stock()
895 * and gtk_menu_item_set_label() with a valid stock item first).
897 * If you want this menu item to have changeable accelerators then
898 * you shouldnt need this (see gtk_image_menu_item_new_from_stock()).
903 gtk_image_menu_item_set_accel_group (GtkImageMenuItem *image_menu_item,
904 GtkAccelGroup *accel_group)
906 GtkImageMenuItemPrivate *priv;
907 GtkStockItem stock_item;
909 /* Silent return for the constructor */
913 g_return_if_fail (GTK_IS_IMAGE_MENU_ITEM (image_menu_item));
914 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
916 priv = image_menu_item->priv;
918 if (priv->use_stock && priv->label && gtk_stock_lookup (priv->label, &stock_item))
919 if (stock_item.keyval)
921 gtk_widget_add_accelerator (GTK_WIDGET (image_menu_item),
928 g_object_notify (G_OBJECT (image_menu_item), "accel-group");
933 * gtk_image_menu_item_set_image:
934 * @image_menu_item: a #GtkImageMenuItem.
935 * @image: (allow-none): a widget to set as the image for the menu item.
937 * Sets the image of @image_menu_item to the given widget.
938 * Note that it depends on the show-menu-images setting whether
939 * the image will be displayed or not.
942 gtk_image_menu_item_set_image (GtkImageMenuItem *image_menu_item,
945 GtkImageMenuItemPrivate *priv;
947 g_return_if_fail (GTK_IS_IMAGE_MENU_ITEM (image_menu_item));
949 priv = image_menu_item->priv;
951 if (image == priv->image)
955 gtk_container_remove (GTK_CONTAINER (image_menu_item),
963 gtk_widget_set_parent (image, GTK_WIDGET (image_menu_item));
965 "visible", show_image (image_menu_item),
969 g_object_notify (G_OBJECT (image_menu_item), "image");
973 * gtk_image_menu_item_get_image:
974 * @image_menu_item: a #GtkImageMenuItem
976 * Gets the widget that is currently set as the image of @image_menu_item.
977 * See gtk_image_menu_item_set_image().
979 * Return value: (transfer none): the widget set as image of @image_menu_item
982 gtk_image_menu_item_get_image (GtkImageMenuItem *image_menu_item)
984 g_return_val_if_fail (GTK_IS_IMAGE_MENU_ITEM (image_menu_item), NULL);
986 return image_menu_item->priv->image;
990 gtk_image_menu_item_remove (GtkContainer *container,
993 GtkImageMenuItem *image_menu_item = GTK_IMAGE_MENU_ITEM (container);
994 GtkImageMenuItemPrivate *priv = image_menu_item->priv;
996 if (child == priv->image)
998 gboolean widget_was_visible;
1000 widget_was_visible = gtk_widget_get_visible (child);
1002 gtk_widget_unparent (child);
1005 if (widget_was_visible &&
1006 gtk_widget_get_visible (GTK_WIDGET (container)))
1007 gtk_widget_queue_resize (GTK_WIDGET (container));
1009 g_object_notify (G_OBJECT (image_menu_item), "image");
1013 GTK_CONTAINER_CLASS (gtk_image_menu_item_parent_class)->remove (container, child);
1018 show_image_change_notify (GtkImageMenuItem *image_menu_item)
1020 GtkImageMenuItemPrivate *priv = image_menu_item->priv;
1024 if (show_image (image_menu_item))
1025 gtk_widget_show (priv->image);
1027 gtk_widget_hide (priv->image);
1032 traverse_container (GtkWidget *widget,
1035 if (GTK_IS_IMAGE_MENU_ITEM (widget))
1036 show_image_change_notify (GTK_IMAGE_MENU_ITEM (widget));
1037 else if (GTK_IS_CONTAINER (widget))
1038 gtk_container_forall (GTK_CONTAINER (widget), traverse_container, NULL);
1042 gtk_image_menu_item_setting_changed (GtkSettings *settings)
1046 list = gtk_window_list_toplevels ();
1048 for (l = list; l; l = l->next)
1049 gtk_container_forall (GTK_CONTAINER (l->data),
1050 traverse_container, NULL);
1056 gtk_image_menu_item_screen_changed (GtkWidget *widget,
1057 GdkScreen *previous_screen)
1059 GtkSettings *settings;
1060 guint show_image_connection;
1062 if (!gtk_widget_has_screen (widget))
1065 settings = gtk_widget_get_settings (widget);
1067 show_image_connection =
1068 GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (settings),
1069 "gtk-image-menu-item-connection"));
1071 if (show_image_connection)
1074 show_image_connection =
1075 g_signal_connect (settings, "notify::gtk-menu-images",
1076 G_CALLBACK (gtk_image_menu_item_setting_changed), NULL);
1077 g_object_set_data (G_OBJECT (settings),
1078 I_("gtk-image-menu-item-connection"),
1079 GUINT_TO_POINTER (show_image_connection));
1081 show_image_change_notify (GTK_IMAGE_MENU_ITEM (widget));