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