1 /* gtktoolitem.c
2  *
3  * Copyright (C) 2002 Anders Carlsson <andersca@gnome.org>
4  * Copyright (C) 2002 James Henstridge <james@daa.com.au>
5  * Copyright (C) 2003 Soeren Sandmann <sandmann@daimi.au.dk>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include "config.h"
22 
23 #include "gtktoolitem.h"
24 
25 #include <string.h>
26 
27 #include "gtkmarshalers.h"
28 #include "gtktoolshell.h"
29 #include "gtkseparatormenuitem.h"
30 #include "gtksizerequest.h"
31 #include "deprecated/gtkactivatable.h"
32 #include "gtkintl.h"
33 #include "gtkprivate.h"
34 #include "gtkwidgetprivate.h"
35 
36 /**
37  * SECTION:gtktoolitem
38  * @short_description: The base class of widgets that can be added to GtkToolShell
39  * @Title: GtkToolItem
40  * @see_also: #GtkToolbar, #GtkToolButton, #GtkSeparatorToolItem
41  *
42  * #GtkToolItems are widgets that can appear on a toolbar. To
43  * create a toolbar item that contain something else than a button, use
44  * gtk_tool_item_new(). Use gtk_container_add() to add a child
45  * widget to the tool item.
46  *
47  * For toolbar items that contain buttons, see the #GtkToolButton,
48  * #GtkToggleToolButton and #GtkRadioToolButton classes.
49  *
50  * See the #GtkToolbar class for a description of the toolbar widget, and
51  * #GtkToolShell for a description of the tool shell interface.
52  */
53 
54 /**
55  * GtkToolItem:
56  *
57  * The GtkToolItem struct contains only private data.
58  * It should only be accessed through the functions described below.
59  */
60 
61 enum {
62   CREATE_MENU_PROXY,
63   TOOLBAR_RECONFIGURED,
64   LAST_SIGNAL
65 };
66 
67 enum {
68   PROP_0,
69   PROP_VISIBLE_HORIZONTAL,
70   PROP_VISIBLE_VERTICAL,
71   PROP_IS_IMPORTANT,
72 
73   /* activatable properties */
74   PROP_ACTIVATABLE_RELATED_ACTION,
75   PROP_ACTIVATABLE_USE_ACTION_APPEARANCE
76 };
77 
78 
79 struct _GtkToolItemPrivate
80 {
81   gchar *tip_text;
82   gchar *tip_private;
83 
84   guint visible_horizontal    : 1;
85   guint visible_vertical      : 1;
86   guint homogeneous           : 1;
87   guint expand                : 1;
88   guint use_drag_window       : 1;
89   guint is_important          : 1;
90   guint use_action_appearance : 1;
91 
92   GdkWindow *drag_window;
93   gchar *menu_item_id;
94   GtkWidget *menu_item;
95 
96   GtkAction *action;
97 };
98 
99 static void gtk_tool_item_finalize     (GObject         *object);
100 static void gtk_tool_item_dispose      (GObject         *object);
101 static void gtk_tool_item_parent_set   (GtkWidget       *toolitem,
102 				        GtkWidget       *parent);
103 static void gtk_tool_item_set_property (GObject         *object,
104 					guint            prop_id,
105 					const GValue    *value,
106 					GParamSpec      *pspec);
107 static void gtk_tool_item_get_property (GObject         *object,
108 					guint            prop_id,
109 					GValue          *value,
110 					GParamSpec      *pspec);
111 static void gtk_tool_item_property_notify (GObject      *object,
112 					   GParamSpec   *pspec);
113 static void gtk_tool_item_realize       (GtkWidget      *widget);
114 static void gtk_tool_item_unrealize     (GtkWidget      *widget);
115 static void gtk_tool_item_map           (GtkWidget      *widget);
116 static void gtk_tool_item_unmap         (GtkWidget      *widget);
117 static void gtk_tool_item_get_preferred_width
118                                         (GtkWidget      *widget,
119                                          gint           *minimum,
120                                          gint           *natural);
121 static void gtk_tool_item_get_preferred_height
122                                         (GtkWidget      *widget,
123                                          gint           *minimum,
124                                          gint           *natural);
125 static void gtk_tool_item_size_allocate (GtkWidget      *widget,
126 					 GtkAllocation  *allocation);
127 
128 static void gtk_tool_item_activatable_interface_init (GtkActivatableIface  *iface);
129 static void gtk_tool_item_update                     (GtkActivatable       *activatable,
130 						      GtkAction            *action,
131 						      const gchar          *property_name);
132 static void gtk_tool_item_sync_action_properties     (GtkActivatable       *activatable,
133 						      GtkAction            *action);
134 static void gtk_tool_item_set_related_action         (GtkToolItem          *item,
135 						      GtkAction            *action);
136 static void gtk_tool_item_set_use_action_appearance  (GtkToolItem          *item,
137 						      gboolean              use_appearance);
138 
139 static guint toolitem_signals[LAST_SIGNAL] = { 0 };
140 
141 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
142 G_DEFINE_TYPE_WITH_CODE (GtkToolItem, gtk_tool_item, GTK_TYPE_BIN,
143                          G_ADD_PRIVATE (GtkToolItem)
144 			 G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTIVATABLE,
145 						gtk_tool_item_activatable_interface_init))
146 G_GNUC_END_IGNORE_DEPRECATIONS;
147 
148 static void
gtk_tool_item_class_init(GtkToolItemClass * klass)149 gtk_tool_item_class_init (GtkToolItemClass *klass)
150 {
151   GObjectClass *object_class;
152   GtkWidgetClass *widget_class;
153 
154   object_class = (GObjectClass *)klass;
155   widget_class = (GtkWidgetClass *)klass;
156 
157   object_class->set_property = gtk_tool_item_set_property;
158   object_class->get_property = gtk_tool_item_get_property;
159   object_class->finalize     = gtk_tool_item_finalize;
160   object_class->dispose      = gtk_tool_item_dispose;
161   object_class->notify       = gtk_tool_item_property_notify;
162 
163   widget_class->realize       = gtk_tool_item_realize;
164   widget_class->unrealize     = gtk_tool_item_unrealize;
165   widget_class->map           = gtk_tool_item_map;
166   widget_class->unmap         = gtk_tool_item_unmap;
167   widget_class->get_preferred_width = gtk_tool_item_get_preferred_width;
168   widget_class->get_preferred_height = gtk_tool_item_get_preferred_height;
169   widget_class->size_allocate = gtk_tool_item_size_allocate;
170   widget_class->parent_set    = gtk_tool_item_parent_set;
171 
172   gtk_container_class_handle_border_width (GTK_CONTAINER_CLASS (klass));
173 
174   klass->create_menu_proxy = _gtk_tool_item_create_menu_proxy;
175 
176   g_object_class_install_property (object_class,
177 				   PROP_VISIBLE_HORIZONTAL,
178 				   g_param_spec_boolean ("visible-horizontal",
179 							 P_("Visible when horizontal"),
180 							 P_("Whether the toolbar item is visible when the toolbar is in a horizontal orientation."),
181 							 TRUE,
182 							 GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
183   g_object_class_install_property (object_class,
184 				   PROP_VISIBLE_VERTICAL,
185 				   g_param_spec_boolean ("visible-vertical",
186 							 P_("Visible when vertical"),
187 							 P_("Whether the toolbar item is visible when the toolbar is in a vertical orientation."),
188 							 TRUE,
189 							 GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
190   g_object_class_install_property (object_class,
191  				   PROP_IS_IMPORTANT,
192  				   g_param_spec_boolean ("is-important",
193  							 P_("Is important"),
194  							 P_("Whether the toolbar item is considered important. When TRUE, toolbar buttons show text in GTK_TOOLBAR_BOTH_HORIZ mode"),
195  							 FALSE,
196  							 GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
197 
198   g_object_class_override_property (object_class, PROP_ACTIVATABLE_RELATED_ACTION, "related-action");
199   g_object_class_override_property (object_class, PROP_ACTIVATABLE_USE_ACTION_APPEARANCE, "use-action-appearance");
200 
201 
202 /**
203  * GtkToolItem::create-menu-proxy:
204  * @tool_item: the object the signal was emitted on
205  *
206  * This signal is emitted when the toolbar needs information from @tool_item
207  * about whether the item should appear in the toolbar overflow menu. In
208  * response the tool item should either
209  *
210  * - call gtk_tool_item_set_proxy_menu_item() with a %NULL
211  *   pointer and return %TRUE to indicate that the item should not appear
212  *   in the overflow menu
213  *
214  * - call gtk_tool_item_set_proxy_menu_item() with a new menu
215  *   item and return %TRUE, or
216  *
217  * - return %FALSE to indicate that the signal was not handled by the item.
218  *   This means that the item will not appear in the overflow menu unless
219  *   a later handler installs a menu item.
220  *
221  * The toolbar may cache the result of this signal. When the tool item changes
222  * how it will respond to this signal it must call gtk_tool_item_rebuild_menu()
223  * to invalidate the cache and ensure that the toolbar rebuilds its overflow
224  * menu.
225  *
226  * Returns: %TRUE if the signal was handled, %FALSE if not
227  **/
228   toolitem_signals[CREATE_MENU_PROXY] =
229     g_signal_new (I_("create-menu-proxy"),
230 		  G_OBJECT_CLASS_TYPE (klass),
231 		  G_SIGNAL_RUN_LAST,
232 		  G_STRUCT_OFFSET (GtkToolItemClass, create_menu_proxy),
233 		  _gtk_boolean_handled_accumulator, NULL,
234 		  _gtk_marshal_BOOLEAN__VOID,
235 		  G_TYPE_BOOLEAN, 0);
236 
237 /**
238  * GtkToolItem::toolbar-reconfigured:
239  * @tool_item: the object the signal was emitted on
240  *
241  * This signal is emitted when some property of the toolbar that the
242  * item is a child of changes. For custom subclasses of #GtkToolItem,
243  * the default handler of this signal use the functions
244  * - gtk_tool_shell_get_orientation()
245  * - gtk_tool_shell_get_style()
246  * - gtk_tool_shell_get_icon_size()
247  * - gtk_tool_shell_get_relief_style()
248  * to find out what the toolbar should look like and change
249  * themselves accordingly.
250  **/
251   toolitem_signals[TOOLBAR_RECONFIGURED] =
252     g_signal_new (I_("toolbar-reconfigured"),
253 		  G_OBJECT_CLASS_TYPE (klass),
254 		  G_SIGNAL_RUN_LAST,
255 		  G_STRUCT_OFFSET (GtkToolItemClass, toolbar_reconfigured),
256 		  NULL, NULL,
257 		  NULL,
258 		  G_TYPE_NONE, 0);
259 
260   gtk_widget_class_set_css_name (widget_class, "toolitem");
261 }
262 
263 static void
gtk_tool_item_init(GtkToolItem * toolitem)264 gtk_tool_item_init (GtkToolItem *toolitem)
265 {
266   gtk_widget_set_can_focus (GTK_WIDGET (toolitem), FALSE);
267 
268   toolitem->priv = gtk_tool_item_get_instance_private (toolitem);
269   toolitem->priv->visible_horizontal = TRUE;
270   toolitem->priv->visible_vertical = TRUE;
271   toolitem->priv->homogeneous = FALSE;
272   toolitem->priv->expand = FALSE;
273   toolitem->priv->use_action_appearance = TRUE;
274 }
275 
276 static void
gtk_tool_item_finalize(GObject * object)277 gtk_tool_item_finalize (GObject *object)
278 {
279   GtkToolItem *item = GTK_TOOL_ITEM (object);
280 
281   g_free (item->priv->menu_item_id);
282 
283   if (item->priv->menu_item)
284     g_object_unref (item->priv->menu_item);
285 
286   G_OBJECT_CLASS (gtk_tool_item_parent_class)->finalize (object);
287 }
288 
289 static void
gtk_tool_item_dispose(GObject * object)290 gtk_tool_item_dispose (GObject *object)
291 {
292   GtkToolItem *item = GTK_TOOL_ITEM (object);
293 
294   if (item->priv->action)
295     {
296       G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
297       gtk_activatable_do_set_related_action (GTK_ACTIVATABLE (item), NULL);
298       G_GNUC_END_IGNORE_DEPRECATIONS;
299       item->priv->action = NULL;
300     }
301   G_OBJECT_CLASS (gtk_tool_item_parent_class)->dispose (object);
302 }
303 
304 
305 static void
gtk_tool_item_parent_set(GtkWidget * toolitem,GtkWidget * prev_parent)306 gtk_tool_item_parent_set (GtkWidget   *toolitem,
307 			  GtkWidget   *prev_parent)
308 {
309   if (gtk_widget_get_parent (GTK_WIDGET (toolitem)) != NULL)
310     gtk_tool_item_toolbar_reconfigured (GTK_TOOL_ITEM (toolitem));
311 }
312 
313 static void
gtk_tool_item_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)314 gtk_tool_item_set_property (GObject      *object,
315 			    guint         prop_id,
316 			    const GValue *value,
317 			    GParamSpec   *pspec)
318 {
319   GtkToolItem *toolitem = GTK_TOOL_ITEM (object);
320 
321   switch (prop_id)
322     {
323     case PROP_VISIBLE_HORIZONTAL:
324       gtk_tool_item_set_visible_horizontal (toolitem, g_value_get_boolean (value));
325       break;
326     case PROP_VISIBLE_VERTICAL:
327       gtk_tool_item_set_visible_vertical (toolitem, g_value_get_boolean (value));
328       break;
329     case PROP_IS_IMPORTANT:
330       gtk_tool_item_set_is_important (toolitem, g_value_get_boolean (value));
331       break;
332     case PROP_ACTIVATABLE_RELATED_ACTION:
333       gtk_tool_item_set_related_action (toolitem, g_value_get_object (value));
334       break;
335     case PROP_ACTIVATABLE_USE_ACTION_APPEARANCE:
336       gtk_tool_item_set_use_action_appearance (toolitem, g_value_get_boolean (value));
337       break;
338     default:
339       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
340       break;
341     }
342 }
343 
344 static void
gtk_tool_item_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)345 gtk_tool_item_get_property (GObject    *object,
346 			    guint       prop_id,
347 			    GValue     *value,
348 			    GParamSpec *pspec)
349 {
350   GtkToolItem *toolitem = GTK_TOOL_ITEM (object);
351 
352   switch (prop_id)
353     {
354     case PROP_VISIBLE_HORIZONTAL:
355       g_value_set_boolean (value, toolitem->priv->visible_horizontal);
356       break;
357     case PROP_VISIBLE_VERTICAL:
358       g_value_set_boolean (value, toolitem->priv->visible_vertical);
359       break;
360     case PROP_IS_IMPORTANT:
361       g_value_set_boolean (value, toolitem->priv->is_important);
362       break;
363     case PROP_ACTIVATABLE_RELATED_ACTION:
364       g_value_set_object (value, toolitem->priv->action);
365       break;
366     case PROP_ACTIVATABLE_USE_ACTION_APPEARANCE:
367       g_value_set_boolean (value, toolitem->priv->use_action_appearance);
368       break;
369     default:
370       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
371       break;
372     }
373 }
374 
375 static void
gtk_tool_item_property_notify(GObject * object,GParamSpec * pspec)376 gtk_tool_item_property_notify (GObject    *object,
377 			       GParamSpec *pspec)
378 {
379   GtkToolItem *tool_item = GTK_TOOL_ITEM (object);
380 
381   if (tool_item->priv->menu_item && strcmp (pspec->name, "sensitive") == 0)
382     gtk_widget_set_sensitive (tool_item->priv->menu_item,
383 			      gtk_widget_get_sensitive (GTK_WIDGET (tool_item)));
384 
385   if (G_OBJECT_CLASS (gtk_tool_item_parent_class)->notify)
386     G_OBJECT_CLASS (gtk_tool_item_parent_class)->notify (object, pspec);
387 }
388 
389 static void
create_drag_window(GtkToolItem * toolitem)390 create_drag_window (GtkToolItem *toolitem)
391 {
392   GtkAllocation allocation;
393   GtkWidget *widget;
394   GdkWindowAttr attributes;
395   gint attributes_mask;
396 
397   g_return_if_fail (toolitem->priv->use_drag_window == TRUE);
398 
399   widget = GTK_WIDGET (toolitem);
400 
401   gtk_widget_get_allocation (widget, &allocation);
402 
403   attributes.window_type = GDK_WINDOW_CHILD;
404   attributes.x = allocation.x;
405   attributes.y = allocation.y;
406   attributes.width = allocation.width;
407   attributes.height = allocation.height;
408   attributes.wclass = GDK_INPUT_ONLY;
409   attributes.event_mask = gtk_widget_get_events (widget);
410   attributes.event_mask |= (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
411 
412   attributes_mask = GDK_WA_X | GDK_WA_Y;
413 
414   toolitem->priv->drag_window = gdk_window_new (gtk_widget_get_parent_window (widget),
415 					  &attributes, attributes_mask);
416   gtk_widget_register_window (widget, toolitem->priv->drag_window);
417 }
418 
419 static void
gtk_tool_item_realize(GtkWidget * widget)420 gtk_tool_item_realize (GtkWidget *widget)
421 {
422   GtkToolItem *toolitem;
423   GdkWindow *window;
424 
425   toolitem = GTK_TOOL_ITEM (widget);
426   gtk_widget_set_realized (widget, TRUE);
427 
428   window = gtk_widget_get_parent_window (widget);
429   gtk_widget_set_window (widget, window);
430   g_object_ref (window);
431 
432   if (toolitem->priv->use_drag_window)
433     create_drag_window(toolitem);
434 }
435 
436 static void
destroy_drag_window(GtkToolItem * toolitem)437 destroy_drag_window (GtkToolItem *toolitem)
438 {
439   if (toolitem->priv->drag_window)
440     {
441       gtk_widget_unregister_window (GTK_WIDGET (toolitem), toolitem->priv->drag_window);
442       gdk_window_destroy (toolitem->priv->drag_window);
443       toolitem->priv->drag_window = NULL;
444     }
445 }
446 
447 static void
gtk_tool_item_unrealize(GtkWidget * widget)448 gtk_tool_item_unrealize (GtkWidget *widget)
449 {
450   GtkToolItem *toolitem;
451 
452   toolitem = GTK_TOOL_ITEM (widget);
453 
454   destroy_drag_window (toolitem);
455 
456   GTK_WIDGET_CLASS (gtk_tool_item_parent_class)->unrealize (widget);
457 }
458 
459 static void
gtk_tool_item_map(GtkWidget * widget)460 gtk_tool_item_map (GtkWidget *widget)
461 {
462   GtkToolItem *toolitem;
463 
464   toolitem = GTK_TOOL_ITEM (widget);
465   GTK_WIDGET_CLASS (gtk_tool_item_parent_class)->map (widget);
466   if (toolitem->priv->drag_window)
467     gdk_window_show (toolitem->priv->drag_window);
468 }
469 
470 static void
gtk_tool_item_unmap(GtkWidget * widget)471 gtk_tool_item_unmap (GtkWidget *widget)
472 {
473   GtkToolItem *toolitem;
474 
475   toolitem = GTK_TOOL_ITEM (widget);
476   if (toolitem->priv->drag_window)
477     gdk_window_hide (toolitem->priv->drag_window);
478   GTK_WIDGET_CLASS (gtk_tool_item_parent_class)->unmap (widget);
479 }
480 
481 static void
gtk_tool_item_get_preferred_width(GtkWidget * widget,gint * minimum,gint * natural)482 gtk_tool_item_get_preferred_width (GtkWidget *widget,
483                                    gint      *minimum,
484                                    gint      *natural)
485 {
486   GtkWidget *child;
487 
488   *minimum = *natural = 0;
489 
490   child = gtk_bin_get_child (GTK_BIN (widget));
491   if (child && gtk_widget_get_visible (child))
492     gtk_widget_get_preferred_width (child, minimum, natural);
493 }
494 
495 static void
gtk_tool_item_get_preferred_height(GtkWidget * widget,gint * minimum,gint * natural)496 gtk_tool_item_get_preferred_height (GtkWidget *widget,
497                                     gint      *minimum,
498                                     gint      *natural)
499 {
500   GtkWidget *child;
501 
502   *minimum = *natural = 0;
503 
504   child = gtk_bin_get_child (GTK_BIN (widget));
505   if (child && gtk_widget_get_visible (child))
506     gtk_widget_get_preferred_height (child, minimum, natural);
507 }
508 
509 static void
gtk_tool_item_size_allocate(GtkWidget * widget,GtkAllocation * allocation)510 gtk_tool_item_size_allocate (GtkWidget     *widget,
511 			     GtkAllocation *allocation)
512 {
513   GtkToolItem *toolitem = GTK_TOOL_ITEM (widget);
514   GtkAllocation child_allocation;
515   GtkWidget *child;
516 
517   gtk_widget_set_allocation (widget, allocation);
518 
519   if (toolitem->priv->drag_window)
520     gdk_window_move_resize (toolitem->priv->drag_window,
521                             allocation->x,
522                             allocation->y,
523                             allocation->width,
524                             allocation->height);
525 
526   child = gtk_bin_get_child (GTK_BIN (widget));
527   if (child && gtk_widget_get_visible (child))
528     {
529       child_allocation.x = allocation->x;
530       child_allocation.y = allocation->y;
531       child_allocation.width = allocation->width;
532       child_allocation.height = allocation->height;
533 
534       gtk_widget_size_allocate (child, &child_allocation);
535     }
536 
537   _gtk_widget_set_simple_clip (widget, NULL);
538 }
539 
540 gboolean
_gtk_tool_item_create_menu_proxy(GtkToolItem * item)541 _gtk_tool_item_create_menu_proxy (GtkToolItem *item)
542 {
543   GtkWidget *menu_item;
544   gboolean visible_overflown;
545   gboolean ret = FALSE;
546 
547   G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
548 
549   if (item->priv->action)
550     {
551       g_object_get (item->priv->action, "visible-overflown", &visible_overflown, NULL);
552 
553       if (visible_overflown)
554 	{
555 	  menu_item = gtk_action_create_menu_item (item->priv->action);
556 
557 	  g_object_ref_sink (menu_item);
558       	  gtk_tool_item_set_proxy_menu_item (item, "gtk-action-menu-item", menu_item);
559 	  g_object_unref (menu_item);
560 	}
561       else
562 	gtk_tool_item_set_proxy_menu_item (item, "gtk-action-menu-item", NULL);
563 
564       ret = TRUE;
565     }
566 
567   G_GNUC_END_IGNORE_DEPRECATIONS;
568 
569   return ret;
570 }
571 
572 static void
gtk_tool_item_activatable_interface_init(GtkActivatableIface * iface)573 gtk_tool_item_activatable_interface_init (GtkActivatableIface *iface)
574 {
575   iface->update = gtk_tool_item_update;
576   iface->sync_action_properties = gtk_tool_item_sync_action_properties;
577 }
578 
579 static void
gtk_tool_item_update(GtkActivatable * activatable,GtkAction * action,const gchar * property_name)580 gtk_tool_item_update (GtkActivatable *activatable,
581 		      GtkAction      *action,
582 	     	      const gchar    *property_name)
583 {
584   G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
585 
586   if (strcmp (property_name, "visible") == 0)
587     {
588       if (gtk_action_is_visible (action))
589 	gtk_widget_show (GTK_WIDGET (activatable));
590       else
591 	gtk_widget_hide (GTK_WIDGET (activatable));
592     }
593   else if (strcmp (property_name, "sensitive") == 0)
594     gtk_widget_set_sensitive (GTK_WIDGET (activatable), gtk_action_is_sensitive (action));
595   else if (strcmp (property_name, "tooltip") == 0)
596     gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (activatable),
597 				    gtk_action_get_tooltip (action));
598   else if (strcmp (property_name, "visible-horizontal") == 0)
599     gtk_tool_item_set_visible_horizontal (GTK_TOOL_ITEM (activatable),
600 					  gtk_action_get_visible_horizontal (action));
601   else if (strcmp (property_name, "visible-vertical") == 0)
602     gtk_tool_item_set_visible_vertical (GTK_TOOL_ITEM (activatable),
603 					gtk_action_get_visible_vertical (action));
604   else if (strcmp (property_name, "is-important") == 0)
605     gtk_tool_item_set_is_important (GTK_TOOL_ITEM (activatable),
606 				    gtk_action_get_is_important (action));
607 
608   G_GNUC_END_IGNORE_DEPRECATIONS;
609 }
610 
611 static void
gtk_tool_item_sync_action_properties(GtkActivatable * activatable,GtkAction * action)612 gtk_tool_item_sync_action_properties (GtkActivatable *activatable,
613 				      GtkAction      *action)
614 {
615   if (!action)
616     return;
617 
618   G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
619 
620   if (gtk_action_is_visible (action))
621     gtk_widget_show (GTK_WIDGET (activatable));
622   else
623     gtk_widget_hide (GTK_WIDGET (activatable));
624 
625   gtk_widget_set_sensitive (GTK_WIDGET (activatable), gtk_action_is_sensitive (action));
626 
627   gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (activatable),
628 				  gtk_action_get_tooltip (action));
629   gtk_tool_item_set_visible_horizontal (GTK_TOOL_ITEM (activatable),
630 					gtk_action_get_visible_horizontal (action));
631   gtk_tool_item_set_visible_vertical (GTK_TOOL_ITEM (activatable),
632 				      gtk_action_get_visible_vertical (action));
633   gtk_tool_item_set_is_important (GTK_TOOL_ITEM (activatable),
634 				  gtk_action_get_is_important (action));
635 
636   G_GNUC_END_IGNORE_DEPRECATIONS;
637 }
638 
639 static void
gtk_tool_item_set_related_action(GtkToolItem * item,GtkAction * action)640 gtk_tool_item_set_related_action (GtkToolItem *item,
641 				  GtkAction   *action)
642 {
643   if (item->priv->action == action)
644     return;
645 
646   G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
647   gtk_activatable_do_set_related_action (GTK_ACTIVATABLE (item), action);
648   G_GNUC_END_IGNORE_DEPRECATIONS;
649 
650   item->priv->action = action;
651 
652   if (action)
653     {
654       gtk_tool_item_rebuild_menu (item);
655     }
656 }
657 
658 static void
gtk_tool_item_set_use_action_appearance(GtkToolItem * item,gboolean use_appearance)659 gtk_tool_item_set_use_action_appearance (GtkToolItem *item,
660 					 gboolean     use_appearance)
661 {
662   if (item->priv->use_action_appearance != use_appearance)
663     {
664       item->priv->use_action_appearance = use_appearance;
665 
666       G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
667       gtk_activatable_sync_action_properties (GTK_ACTIVATABLE (item), item->priv->action);
668       G_GNUC_END_IGNORE_DEPRECATIONS;
669     }
670 }
671 
672 
673 /**
674  * gtk_tool_item_new:
675  *
676  * Creates a new #GtkToolItem
677  *
678  * Returns: the new #GtkToolItem
679  *
680  * Since: 2.4
681  **/
682 GtkToolItem *
gtk_tool_item_new(void)683 gtk_tool_item_new (void)
684 {
685   GtkToolItem *item;
686 
687   item = g_object_new (GTK_TYPE_TOOL_ITEM, NULL);
688 
689   return item;
690 }
691 
692 /**
693  * gtk_tool_item_get_ellipsize_mode:
694  * @tool_item: a #GtkToolItem
695  *
696  * Returns the ellipsize mode used for @tool_item. Custom subclasses of
697  * #GtkToolItem should call this function to find out how text should
698  * be ellipsized.
699  *
700  * Returns: a #PangoEllipsizeMode indicating how text in @tool_item
701  * should be ellipsized.
702  *
703  * Since: 2.20
704  **/
705 PangoEllipsizeMode
gtk_tool_item_get_ellipsize_mode(GtkToolItem * tool_item)706 gtk_tool_item_get_ellipsize_mode (GtkToolItem *tool_item)
707 {
708   GtkWidget *parent;
709 
710   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), PANGO_ELLIPSIZE_NONE);
711 
712   parent = gtk_widget_get_parent (GTK_WIDGET (tool_item));
713   if (!parent || !GTK_IS_TOOL_SHELL (parent))
714     return PANGO_ELLIPSIZE_NONE;
715 
716   return gtk_tool_shell_get_ellipsize_mode (GTK_TOOL_SHELL (parent));
717 }
718 
719 /**
720  * gtk_tool_item_get_icon_size:
721  * @tool_item: a #GtkToolItem
722  *
723  * Returns the icon size used for @tool_item. Custom subclasses of
724  * #GtkToolItem should call this function to find out what size icons
725  * they should use.
726  *
727  * Returns: (type int): a #GtkIconSize indicating the icon size
728  * used for @tool_item
729  *
730  * Since: 2.4
731  **/
732 GtkIconSize
gtk_tool_item_get_icon_size(GtkToolItem * tool_item)733 gtk_tool_item_get_icon_size (GtkToolItem *tool_item)
734 {
735   GtkWidget *parent;
736 
737   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_ICON_SIZE_LARGE_TOOLBAR);
738 
739   parent = gtk_widget_get_parent (GTK_WIDGET (tool_item));
740   if (!parent || !GTK_IS_TOOL_SHELL (parent))
741     return GTK_ICON_SIZE_LARGE_TOOLBAR;
742 
743   return gtk_tool_shell_get_icon_size (GTK_TOOL_SHELL (parent));
744 }
745 
746 /**
747  * gtk_tool_item_get_orientation:
748  * @tool_item: a #GtkToolItem
749  *
750  * Returns the orientation used for @tool_item. Custom subclasses of
751  * #GtkToolItem should call this function to find out what size icons
752  * they should use.
753  *
754  * Returns: a #GtkOrientation indicating the orientation
755  * used for @tool_item
756  *
757  * Since: 2.4
758  **/
759 GtkOrientation
gtk_tool_item_get_orientation(GtkToolItem * tool_item)760 gtk_tool_item_get_orientation (GtkToolItem *tool_item)
761 {
762   GtkWidget *parent;
763 
764   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_ORIENTATION_HORIZONTAL);
765 
766   parent = gtk_widget_get_parent (GTK_WIDGET (tool_item));
767   if (!parent || !GTK_IS_TOOL_SHELL (parent))
768     return GTK_ORIENTATION_HORIZONTAL;
769 
770   return gtk_tool_shell_get_orientation (GTK_TOOL_SHELL (parent));
771 }
772 
773 /**
774  * gtk_tool_item_get_toolbar_style:
775  * @tool_item: a #GtkToolItem
776  *
777  * Returns the toolbar style used for @tool_item. Custom subclasses of
778  * #GtkToolItem should call this function in the handler of the
779  * GtkToolItem::toolbar_reconfigured signal to find out in what style
780  * the toolbar is displayed and change themselves accordingly
781  *
782  * Possibilities are:
783  * - %GTK_TOOLBAR_BOTH, meaning the tool item should show
784  *   both an icon and a label, stacked vertically
785  * - %GTK_TOOLBAR_ICONS, meaning the toolbar shows only icons
786  * - %GTK_TOOLBAR_TEXT, meaning the tool item should only show text
787  * - %GTK_TOOLBAR_BOTH_HORIZ, meaning the tool item should show
788  *   both an icon and a label, arranged horizontally
789  *
790  * Returns: A #GtkToolbarStyle indicating the toolbar style used
791  * for @tool_item.
792  *
793  * Since: 2.4
794  **/
795 GtkToolbarStyle
gtk_tool_item_get_toolbar_style(GtkToolItem * tool_item)796 gtk_tool_item_get_toolbar_style (GtkToolItem *tool_item)
797 {
798   GtkWidget *parent;
799 
800   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_TOOLBAR_ICONS);
801 
802   parent = gtk_widget_get_parent (GTK_WIDGET (tool_item));
803   if (!parent || !GTK_IS_TOOL_SHELL (parent))
804     return GTK_TOOLBAR_ICONS;
805 
806   return gtk_tool_shell_get_style (GTK_TOOL_SHELL (parent));
807 }
808 
809 /**
810  * gtk_tool_item_get_relief_style:
811  * @tool_item: a #GtkToolItem
812  *
813  * Returns the relief style of @tool_item. See gtk_button_set_relief().
814  * Custom subclasses of #GtkToolItem should call this function in the handler
815  * of the #GtkToolItem::toolbar_reconfigured signal to find out the
816  * relief style of buttons.
817  *
818  * Returns: a #GtkReliefStyle indicating the relief style used
819  * for @tool_item.
820  *
821  * Since: 2.4
822  **/
823 GtkReliefStyle
gtk_tool_item_get_relief_style(GtkToolItem * tool_item)824 gtk_tool_item_get_relief_style (GtkToolItem *tool_item)
825 {
826   GtkWidget *parent;
827 
828   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_RELIEF_NONE);
829 
830   parent = gtk_widget_get_parent (GTK_WIDGET (tool_item));
831   if (!parent || !GTK_IS_TOOL_SHELL (parent))
832     return GTK_RELIEF_NONE;
833 
834   return gtk_tool_shell_get_relief_style (GTK_TOOL_SHELL (parent));
835 }
836 
837 /**
838  * gtk_tool_item_get_text_alignment:
839  * @tool_item: a #GtkToolItem:
840  *
841  * Returns the text alignment used for @tool_item. Custom subclasses of
842  * #GtkToolItem should call this function to find out how text should
843  * be aligned.
844  *
845  * Returns: a #gfloat indicating the horizontal text alignment
846  * used for @tool_item
847  *
848  * Since: 2.20
849  **/
850 gfloat
gtk_tool_item_get_text_alignment(GtkToolItem * tool_item)851 gtk_tool_item_get_text_alignment (GtkToolItem *tool_item)
852 {
853   GtkWidget *parent;
854 
855   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_ORIENTATION_HORIZONTAL);
856 
857   parent = gtk_widget_get_parent (GTK_WIDGET (tool_item));
858   if (!parent || !GTK_IS_TOOL_SHELL (parent))
859     return 0.5;
860 
861   return gtk_tool_shell_get_text_alignment (GTK_TOOL_SHELL (parent));
862 }
863 
864 /**
865  * gtk_tool_item_get_text_orientation:
866  * @tool_item: a #GtkToolItem
867  *
868  * Returns the text orientation used for @tool_item. Custom subclasses of
869  * #GtkToolItem should call this function to find out how text should
870  * be orientated.
871  *
872  * Returns: a #GtkOrientation indicating the text orientation
873  * used for @tool_item
874  *
875  * Since: 2.20
876  */
877 GtkOrientation
gtk_tool_item_get_text_orientation(GtkToolItem * tool_item)878 gtk_tool_item_get_text_orientation (GtkToolItem *tool_item)
879 {
880   GtkWidget *parent;
881 
882   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_ORIENTATION_HORIZONTAL);
883 
884   parent = gtk_widget_get_parent (GTK_WIDGET (tool_item));
885   if (!parent || !GTK_IS_TOOL_SHELL (parent))
886     return GTK_ORIENTATION_HORIZONTAL;
887 
888   return gtk_tool_shell_get_text_orientation (GTK_TOOL_SHELL (parent));
889 }
890 
891 /**
892  * gtk_tool_item_get_text_size_group:
893  * @tool_item: a #GtkToolItem
894  *
895  * Returns the size group used for labels in @tool_item.
896  * Custom subclasses of #GtkToolItem should call this function
897  * and use the size group for labels.
898  *
899  * Returns: (transfer none): a #GtkSizeGroup
900  *
901  * Since: 2.20
902  */
903 GtkSizeGroup *
gtk_tool_item_get_text_size_group(GtkToolItem * tool_item)904 gtk_tool_item_get_text_size_group (GtkToolItem *tool_item)
905 {
906   GtkWidget *parent;
907 
908   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), NULL);
909 
910   parent = gtk_widget_get_parent (GTK_WIDGET (tool_item));
911   if (!parent || !GTK_IS_TOOL_SHELL (parent))
912     return NULL;
913 
914   return gtk_tool_shell_get_text_size_group (GTK_TOOL_SHELL (parent));
915 }
916 
917 /**
918  * gtk_tool_item_set_expand:
919  * @tool_item: a #GtkToolItem
920  * @expand: Whether @tool_item is allocated extra space
921  *
922  * Sets whether @tool_item is allocated extra space when there
923  * is more room on the toolbar then needed for the items. The
924  * effect is that the item gets bigger when the toolbar gets bigger
925  * and smaller when the toolbar gets smaller.
926  *
927  * Since: 2.4
928  */
929 void
gtk_tool_item_set_expand(GtkToolItem * tool_item,gboolean expand)930 gtk_tool_item_set_expand (GtkToolItem *tool_item,
931 			  gboolean     expand)
932 {
933   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
934 
935   expand = expand != FALSE;
936 
937   if (tool_item->priv->expand != expand)
938     {
939       tool_item->priv->expand = expand;
940       gtk_widget_child_notify (GTK_WIDGET (tool_item), "expand");
941       gtk_widget_queue_resize (GTK_WIDGET (tool_item));
942     }
943 }
944 
945 /**
946  * gtk_tool_item_get_expand:
947  * @tool_item: a #GtkToolItem
948  *
949  * Returns whether @tool_item is allocated extra space.
950  * See gtk_tool_item_set_expand().
951  *
952  * Returns: %TRUE if @tool_item is allocated extra space.
953  *
954  * Since: 2.4
955  **/
956 gboolean
gtk_tool_item_get_expand(GtkToolItem * tool_item)957 gtk_tool_item_get_expand (GtkToolItem *tool_item)
958 {
959   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), FALSE);
960 
961   return tool_item->priv->expand;
962 }
963 
964 /**
965  * gtk_tool_item_set_homogeneous:
966  * @tool_item: a #GtkToolItem
967  * @homogeneous: whether @tool_item is the same size as other homogeneous items
968  *
969  * Sets whether @tool_item is to be allocated the same size as other
970  * homogeneous items. The effect is that all homogeneous items will have
971  * the same width as the widest of the items.
972  *
973  * Since: 2.4
974  **/
975 void
gtk_tool_item_set_homogeneous(GtkToolItem * tool_item,gboolean homogeneous)976 gtk_tool_item_set_homogeneous (GtkToolItem *tool_item,
977 			       gboolean     homogeneous)
978 {
979   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
980 
981   homogeneous = homogeneous != FALSE;
982 
983   if (tool_item->priv->homogeneous != homogeneous)
984     {
985       tool_item->priv->homogeneous = homogeneous;
986       gtk_widget_child_notify (GTK_WIDGET (tool_item), "homogeneous");
987       gtk_widget_queue_resize (GTK_WIDGET (tool_item));
988     }
989 }
990 
991 /**
992  * gtk_tool_item_get_homogeneous:
993  * @tool_item: a #GtkToolItem
994  *
995  * Returns whether @tool_item is the same size as other homogeneous
996  * items. See gtk_tool_item_set_homogeneous().
997  *
998  * Returns: %TRUE if the item is the same size as other homogeneous
999  * items.
1000  *
1001  * Since: 2.4
1002  **/
1003 gboolean
gtk_tool_item_get_homogeneous(GtkToolItem * tool_item)1004 gtk_tool_item_get_homogeneous (GtkToolItem *tool_item)
1005 {
1006   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), FALSE);
1007 
1008   return tool_item->priv->homogeneous;
1009 }
1010 
1011 /**
1012  * gtk_tool_item_get_is_important:
1013  * @tool_item: a #GtkToolItem
1014  *
1015  * Returns whether @tool_item is considered important. See
1016  * gtk_tool_item_set_is_important()
1017  *
1018  * Returns: %TRUE if @tool_item is considered important.
1019  *
1020  * Since: 2.4
1021  **/
1022 gboolean
gtk_tool_item_get_is_important(GtkToolItem * tool_item)1023 gtk_tool_item_get_is_important (GtkToolItem *tool_item)
1024 {
1025   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), FALSE);
1026 
1027   return tool_item->priv->is_important;
1028 }
1029 
1030 /**
1031  * gtk_tool_item_set_is_important:
1032  * @tool_item: a #GtkToolItem
1033  * @is_important: whether the tool item should be considered important
1034  *
1035  * Sets whether @tool_item should be considered important. The #GtkToolButton
1036  * class uses this property to determine whether to show or hide its label
1037  * when the toolbar style is %GTK_TOOLBAR_BOTH_HORIZ. The result is that
1038  * only tool buttons with the “is_important” property set have labels, an
1039  * effect known as “priority text”
1040  *
1041  * Since: 2.4
1042  **/
1043 void
gtk_tool_item_set_is_important(GtkToolItem * tool_item,gboolean is_important)1044 gtk_tool_item_set_is_important (GtkToolItem *tool_item, gboolean is_important)
1045 {
1046   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
1047 
1048   is_important = is_important != FALSE;
1049 
1050   if (is_important != tool_item->priv->is_important)
1051     {
1052       tool_item->priv->is_important = is_important;
1053 
1054       gtk_widget_queue_resize (GTK_WIDGET (tool_item));
1055 
1056       g_object_notify (G_OBJECT (tool_item), "is-important");
1057     }
1058 }
1059 
1060 /**
1061  * gtk_tool_item_set_tooltip_text:
1062  * @tool_item: a #GtkToolItem
1063  * @text: text to be used as tooltip for @tool_item
1064  *
1065  * Sets the text to be displayed as tooltip on the item.
1066  * See gtk_widget_set_tooltip_text().
1067  *
1068  * Since: 2.12
1069  **/
1070 void
gtk_tool_item_set_tooltip_text(GtkToolItem * tool_item,const gchar * text)1071 gtk_tool_item_set_tooltip_text (GtkToolItem *tool_item,
1072 			        const gchar *text)
1073 {
1074   GtkWidget *child;
1075 
1076   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
1077 
1078   child = gtk_bin_get_child (GTK_BIN (tool_item));
1079   if (child)
1080     gtk_widget_set_tooltip_text (child, text);
1081 }
1082 
1083 /**
1084  * gtk_tool_item_set_tooltip_markup:
1085  * @tool_item: a #GtkToolItem
1086  * @markup: markup text to be used as tooltip for @tool_item
1087  *
1088  * Sets the markup text to be displayed as tooltip on the item.
1089  * See gtk_widget_set_tooltip_markup().
1090  *
1091  * Since: 2.12
1092  **/
1093 void
gtk_tool_item_set_tooltip_markup(GtkToolItem * tool_item,const gchar * markup)1094 gtk_tool_item_set_tooltip_markup (GtkToolItem *tool_item,
1095 				  const gchar *markup)
1096 {
1097   GtkWidget *child;
1098 
1099   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
1100 
1101   child = gtk_bin_get_child (GTK_BIN (tool_item));
1102   if (child)
1103     gtk_widget_set_tooltip_markup (child, markup);
1104 }
1105 
1106 /**
1107  * gtk_tool_item_set_use_drag_window:
1108  * @tool_item: a #GtkToolItem
1109  * @use_drag_window: Whether @tool_item has a drag window.
1110  *
1111  * Sets whether @tool_item has a drag window. When %TRUE the
1112  * toolitem can be used as a drag source through gtk_drag_source_set().
1113  * When @tool_item has a drag window it will intercept all events,
1114  * even those that would otherwise be sent to a child of @tool_item.
1115  *
1116  * Since: 2.4
1117  **/
1118 void
gtk_tool_item_set_use_drag_window(GtkToolItem * toolitem,gboolean use_drag_window)1119 gtk_tool_item_set_use_drag_window (GtkToolItem *toolitem,
1120 				   gboolean     use_drag_window)
1121 {
1122   g_return_if_fail (GTK_IS_TOOL_ITEM (toolitem));
1123 
1124   use_drag_window = use_drag_window != FALSE;
1125 
1126   if (toolitem->priv->use_drag_window != use_drag_window)
1127     {
1128       toolitem->priv->use_drag_window = use_drag_window;
1129 
1130       if (use_drag_window)
1131 	{
1132 	  if (!toolitem->priv->drag_window &&
1133               gtk_widget_get_realized (GTK_WIDGET (toolitem)))
1134 	    {
1135 	      create_drag_window(toolitem);
1136 	      if (gtk_widget_get_mapped (GTK_WIDGET (toolitem)))
1137 		gdk_window_show (toolitem->priv->drag_window);
1138 	    }
1139 	}
1140       else
1141 	{
1142 	  destroy_drag_window (toolitem);
1143 	}
1144     }
1145 }
1146 
1147 /**
1148  * gtk_tool_item_get_use_drag_window:
1149  * @tool_item: a #GtkToolItem
1150  *
1151  * Returns whether @tool_item has a drag window. See
1152  * gtk_tool_item_set_use_drag_window().
1153  *
1154  * Returns: %TRUE if @tool_item uses a drag window.
1155  *
1156  * Since: 2.4
1157  **/
1158 gboolean
gtk_tool_item_get_use_drag_window(GtkToolItem * toolitem)1159 gtk_tool_item_get_use_drag_window (GtkToolItem *toolitem)
1160 {
1161   g_return_val_if_fail (GTK_IS_TOOL_ITEM (toolitem), FALSE);
1162 
1163   return toolitem->priv->use_drag_window;
1164 }
1165 
1166 /**
1167  * gtk_tool_item_set_visible_horizontal:
1168  * @tool_item: a #GtkToolItem
1169  * @visible_horizontal: Whether @tool_item is visible when in horizontal mode
1170  *
1171  * Sets whether @tool_item is visible when the toolbar is docked horizontally.
1172  *
1173  * Since: 2.4
1174  **/
1175 void
gtk_tool_item_set_visible_horizontal(GtkToolItem * toolitem,gboolean visible_horizontal)1176 gtk_tool_item_set_visible_horizontal (GtkToolItem *toolitem,
1177 				      gboolean     visible_horizontal)
1178 {
1179   g_return_if_fail (GTK_IS_TOOL_ITEM (toolitem));
1180 
1181   visible_horizontal = visible_horizontal != FALSE;
1182 
1183   if (toolitem->priv->visible_horizontal != visible_horizontal)
1184     {
1185       toolitem->priv->visible_horizontal = visible_horizontal;
1186 
1187       g_object_notify (G_OBJECT (toolitem), "visible-horizontal");
1188 
1189       gtk_widget_queue_resize (GTK_WIDGET (toolitem));
1190     }
1191 }
1192 
1193 /**
1194  * gtk_tool_item_get_visible_horizontal:
1195  * @tool_item: a #GtkToolItem
1196  *
1197  * Returns whether the @tool_item is visible on toolbars that are
1198  * docked horizontally.
1199  *
1200  * Returns: %TRUE if @tool_item is visible on toolbars that are
1201  * docked horizontally.
1202  *
1203  * Since: 2.4
1204  **/
1205 gboolean
gtk_tool_item_get_visible_horizontal(GtkToolItem * toolitem)1206 gtk_tool_item_get_visible_horizontal (GtkToolItem *toolitem)
1207 {
1208   g_return_val_if_fail (GTK_IS_TOOL_ITEM (toolitem), FALSE);
1209 
1210   return toolitem->priv->visible_horizontal;
1211 }
1212 
1213 /**
1214  * gtk_tool_item_set_visible_vertical:
1215  * @tool_item: a #GtkToolItem
1216  * @visible_vertical: whether @tool_item is visible when the toolbar
1217  * is in vertical mode
1218  *
1219  * Sets whether @tool_item is visible when the toolbar is docked
1220  * vertically. Some tool items, such as text entries, are too wide to be
1221  * useful on a vertically docked toolbar. If @visible_vertical is %FALSE
1222  * @tool_item will not appear on toolbars that are docked vertically.
1223  *
1224  * Since: 2.4
1225  **/
1226 void
gtk_tool_item_set_visible_vertical(GtkToolItem * toolitem,gboolean visible_vertical)1227 gtk_tool_item_set_visible_vertical (GtkToolItem *toolitem,
1228 				    gboolean     visible_vertical)
1229 {
1230   g_return_if_fail (GTK_IS_TOOL_ITEM (toolitem));
1231 
1232   visible_vertical = visible_vertical != FALSE;
1233 
1234   if (toolitem->priv->visible_vertical != visible_vertical)
1235     {
1236       toolitem->priv->visible_vertical = visible_vertical;
1237 
1238       g_object_notify (G_OBJECT (toolitem), "visible-vertical");
1239 
1240       gtk_widget_queue_resize (GTK_WIDGET (toolitem));
1241     }
1242 }
1243 
1244 /**
1245  * gtk_tool_item_get_visible_vertical:
1246  * @tool_item: a #GtkToolItem
1247  *
1248  * Returns whether @tool_item is visible when the toolbar is docked vertically.
1249  * See gtk_tool_item_set_visible_vertical().
1250  *
1251  * Returns: Whether @tool_item is visible when the toolbar is docked vertically
1252  *
1253  * Since: 2.4
1254  **/
1255 gboolean
gtk_tool_item_get_visible_vertical(GtkToolItem * toolitem)1256 gtk_tool_item_get_visible_vertical (GtkToolItem *toolitem)
1257 {
1258   g_return_val_if_fail (GTK_IS_TOOL_ITEM (toolitem), FALSE);
1259 
1260   return toolitem->priv->visible_vertical;
1261 }
1262 
1263 /**
1264  * gtk_tool_item_retrieve_proxy_menu_item:
1265  * @tool_item: a #GtkToolItem
1266  *
1267  * Returns the #GtkMenuItem that was last set by
1268  * gtk_tool_item_set_proxy_menu_item(), ie. the #GtkMenuItem
1269  * that is going to appear in the overflow menu.
1270  *
1271  * Returns: (transfer none): The #GtkMenuItem that is going to appear in the
1272  * overflow menu for @tool_item.
1273  *
1274  * Since: 2.4
1275  **/
1276 GtkWidget *
gtk_tool_item_retrieve_proxy_menu_item(GtkToolItem * tool_item)1277 gtk_tool_item_retrieve_proxy_menu_item (GtkToolItem *tool_item)
1278 {
1279   gboolean retval;
1280 
1281   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), NULL);
1282 
1283   g_signal_emit (tool_item, toolitem_signals[CREATE_MENU_PROXY], 0,
1284 		 &retval);
1285 
1286   return tool_item->priv->menu_item;
1287 }
1288 
1289 /**
1290  * gtk_tool_item_get_proxy_menu_item:
1291  * @tool_item: a #GtkToolItem
1292  * @menu_item_id: a string used to identify the menu item
1293  *
1294  * If @menu_item_id matches the string passed to
1295  * gtk_tool_item_set_proxy_menu_item() return the corresponding #GtkMenuItem.
1296  *
1297  * Custom subclasses of #GtkToolItem should use this function to
1298  * update their menu item when the #GtkToolItem changes. That the
1299  * @menu_item_ids must match ensures that a #GtkToolItem
1300  * will not inadvertently change a menu item that they did not create.
1301  *
1302  * Returns: (transfer none) (nullable): The #GtkMenuItem passed to
1303  *     gtk_tool_item_set_proxy_menu_item(), if the @menu_item_ids
1304  *     match.
1305  *
1306  * Since: 2.4
1307  **/
1308 GtkWidget *
gtk_tool_item_get_proxy_menu_item(GtkToolItem * tool_item,const gchar * menu_item_id)1309 gtk_tool_item_get_proxy_menu_item (GtkToolItem *tool_item,
1310 				   const gchar *menu_item_id)
1311 {
1312   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), NULL);
1313   g_return_val_if_fail (menu_item_id != NULL, NULL);
1314 
1315   if (tool_item->priv->menu_item_id && strcmp (tool_item->priv->menu_item_id, menu_item_id) == 0)
1316     return tool_item->priv->menu_item;
1317 
1318   return NULL;
1319 }
1320 
1321 /**
1322  * gtk_tool_item_rebuild_menu:
1323  * @tool_item: a #GtkToolItem
1324  *
1325  * Calling this function signals to the toolbar that the
1326  * overflow menu item for @tool_item has changed. If the
1327  * overflow menu is visible when this function it called,
1328  * the menu will be rebuilt.
1329  *
1330  * The function must be called when the tool item changes what it
1331  * will do in response to the #GtkToolItem::create-menu-proxy signal.
1332  *
1333  * Since: 2.6
1334  */
1335 void
gtk_tool_item_rebuild_menu(GtkToolItem * tool_item)1336 gtk_tool_item_rebuild_menu (GtkToolItem *tool_item)
1337 {
1338   GtkWidget *parent;
1339   GtkWidget *widget;
1340 
1341   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
1342 
1343   widget = GTK_WIDGET (tool_item);
1344 
1345   parent = gtk_widget_get_parent (widget);
1346   if (GTK_IS_TOOL_SHELL (parent))
1347     gtk_tool_shell_rebuild_menu (GTK_TOOL_SHELL (parent));
1348 }
1349 
1350 /**
1351  * gtk_tool_item_set_proxy_menu_item:
1352  * @tool_item: a #GtkToolItem
1353  * @menu_item_id: a string used to identify @menu_item
1354  * @menu_item: (nullable): a #GtkMenuItem to use in the overflow menu, or %NULL
1355  *
1356  * Sets the #GtkMenuItem used in the toolbar overflow menu. The
1357  * @menu_item_id is used to identify the caller of this function and
1358  * should also be used with gtk_tool_item_get_proxy_menu_item().
1359  *
1360  * See also #GtkToolItem::create-menu-proxy.
1361  *
1362  * Since: 2.4
1363  **/
1364 void
gtk_tool_item_set_proxy_menu_item(GtkToolItem * tool_item,const gchar * menu_item_id,GtkWidget * menu_item)1365 gtk_tool_item_set_proxy_menu_item (GtkToolItem *tool_item,
1366 				   const gchar *menu_item_id,
1367 				   GtkWidget   *menu_item)
1368 {
1369   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
1370   g_return_if_fail (menu_item == NULL || GTK_IS_MENU_ITEM (menu_item));
1371   g_return_if_fail (menu_item_id != NULL);
1372 
1373   g_free (tool_item->priv->menu_item_id);
1374 
1375   tool_item->priv->menu_item_id = g_strdup (menu_item_id);
1376 
1377   if (tool_item->priv->menu_item != menu_item)
1378     {
1379       if (tool_item->priv->menu_item)
1380 	g_object_unref (tool_item->priv->menu_item);
1381 
1382       if (menu_item)
1383 	{
1384 	  g_object_ref_sink (menu_item);
1385 
1386 	  gtk_widget_set_sensitive (menu_item,
1387 				    gtk_widget_get_sensitive (GTK_WIDGET (tool_item)));
1388 	}
1389 
1390       tool_item->priv->menu_item = menu_item;
1391     }
1392 }
1393 
1394 /**
1395  * gtk_tool_item_toolbar_reconfigured:
1396  * @tool_item: a #GtkToolItem
1397  *
1398  * Emits the signal #GtkToolItem::toolbar_reconfigured on @tool_item.
1399  * #GtkToolbar and other #GtkToolShell implementations use this function
1400  * to notify children, when some aspect of their configuration changes.
1401  *
1402  * Since: 2.14
1403  **/
1404 void
gtk_tool_item_toolbar_reconfigured(GtkToolItem * tool_item)1405 gtk_tool_item_toolbar_reconfigured (GtkToolItem *tool_item)
1406 {
1407   /* The slightely inaccurate name "gtk_tool_item_toolbar_reconfigured" was
1408    * choosen over "gtk_tool_item_tool_shell_reconfigured", since the function
1409    * emits the "toolbar-reconfigured" signal, not "tool-shell-reconfigured".
1410    * It's not possible to rename the signal, and emitting another name than
1411    * indicated by the function name would be quite confusing. That's the
1412    * price of providing stable APIs.
1413    */
1414   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
1415 
1416   g_signal_emit (tool_item, toolitem_signals[TOOLBAR_RECONFIGURED], 0);
1417 
1418   if (tool_item->priv->drag_window)
1419     gdk_window_raise (tool_item->priv->drag_window);
1420 
1421   gtk_widget_queue_resize (GTK_WIDGET (tool_item));
1422 }
1423