1 /* GtkToolPalette -- A tool palette with categories and DnD support
2 * Copyright (C) 2008 Openismus GmbH
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 #include "gtktoolpaletteprivate.h"
28 #include "gtkmarshalers.h"
29 #include "gtktypebuiltins.h"
30 #include "gtkprivate.h"
31 #include "gtkscrollable.h"
34 #define DEFAULT_ICON_SIZE GTK_ICON_SIZE_SMALL_TOOLBAR
35 #define DEFAULT_ORIENTATION GTK_ORIENTATION_VERTICAL
36 #define DEFAULT_TOOLBAR_STYLE GTK_TOOLBAR_ICONS
38 #define DEFAULT_CHILD_EXCLUSIVE FALSE
39 #define DEFAULT_CHILD_EXPAND FALSE
42 * SECTION:gtktoolpalette
43 * @Short_description: A tool palette with categories
44 * @Title: GtkToolPalette
46 * A #GtkToolPalette allows you to add #GtkToolItem<!-- -->s to a palette-like
47 * container with different categories and drag and drop support.
49 * A #GtkToolPalette is created with a call to gtk_tool_palette_new().
51 * #GtkToolItem<!-- -->s cannot be added directly to a #GtkToolPalette -
52 * instead they are added to a #GtkToolItemGroup which can than be added
53 * to a #GtkToolPalette. To add a #GtkToolItemGroup to a #GtkToolPalette,
54 * use gtk_container_add().
57 * GtkWidget *palette, *group;
60 * palette = gtk_tool_palette_new ();
61 * group = gtk_tool_item_group_new (_("Test Category"));
62 * gtk_container_add (GTK_CONTAINER (palette), group);
64 * item = gtk_tool_button_new_from_stock (GTK_STOCK_OK);
65 * gtk_tool_item_group_insert (GTK_TOOL_ITEM_GROUP (group), item, -1);
68 * The easiest way to use drag and drop with #GtkToolPalette is to call
69 * gtk_tool_palette_add_drag_dest() with the desired drag source @palette
70 * and the desired drag target @widget. Then gtk_tool_palette_get_drag_item()
71 * can be used to get the dragged item in the #GtkWidget::drag-data-received
72 * signal handler of the drag target.
76 * passive_canvas_drag_data_received (GtkWidget *widget,
77 * GdkDragContext *context,
80 * GtkSelectionData *selection,
88 * /<!-- -->* Get the dragged item *<!-- -->/
89 * palette = gtk_widget_get_ancestor (gtk_drag_get_source_widget (context),
90 * GTK_TYPE_TOOL_PALETTE);
91 * if (palette != NULL)
92 * item = gtk_tool_palette_get_drag_item (GTK_TOOL_PALETTE (palette),
95 * /<!-- -->* Do something with item *<!-- -->/
98 * GtkWidget *target, palette;
100 * palette = gtk_tool_palette_new ();
101 * target = gtk_drawing_area_new ();
103 * g_signal_connect (G_OBJECT (target), "drag-data-received",
104 * G_CALLBACK (passive_canvas_drag_data_received), NULL);
105 * gtk_tool_palette_add_drag_dest (GTK_TOOL_PALETTE (palette), target,
106 * GTK_DEST_DEFAULT_ALL,
107 * GTK_TOOL_PALETTE_DRAG_ITEMS,
114 typedef struct _GtkToolItemGroupInfo GtkToolItemGroupInfo;
115 typedef struct _GtkToolPaletteDragData GtkToolPaletteDragData;
133 CHILD_PROP_EXCLUSIVE,
137 struct _GtkToolItemGroupInfo
139 GtkToolItemGroup *widget;
141 gulong notify_collapsed;
147 struct _GtkToolPalettePrivate
151 GtkAdjustment *hadjustment;
152 GtkAdjustment *vadjustment;
154 GtkIconSize icon_size;
155 gboolean icon_size_set;
156 GtkOrientation orientation;
157 GtkToolbarStyle style;
160 GtkWidget *expanding_child;
162 GtkSizeGroup *text_size_group;
164 GtkSettings *settings;
165 gulong settings_connection;
167 guint drag_source : 2;
169 /* GtkScrollablePolicy needs to be checked when
170 * driving the scrollable adjustment values */
171 guint hscroll_policy : 1;
172 guint vscroll_policy : 1;
175 struct _GtkToolPaletteDragData
177 GtkToolPalette *palette;
181 static GdkAtom dnd_target_atom_item = GDK_NONE;
182 static GdkAtom dnd_target_atom_group = GDK_NONE;
184 static const GtkTargetEntry dnd_targets[] =
186 { "application/x-gtk-tool-palette-item", GTK_TARGET_SAME_APP, 0 },
187 { "application/x-gtk-tool-palette-group", GTK_TARGET_SAME_APP, 0 },
190 static void gtk_tool_palette_set_hadjustment (GtkToolPalette *palette,
191 GtkAdjustment *adjustment);
192 static void gtk_tool_palette_set_vadjustment (GtkToolPalette *palette,
193 GtkAdjustment *adjustment);
196 G_DEFINE_TYPE_WITH_CODE (GtkToolPalette,
199 G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL)
200 G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL))
203 gtk_tool_palette_init (GtkToolPalette *palette)
205 palette->priv = G_TYPE_INSTANCE_GET_PRIVATE (palette,
206 GTK_TYPE_TOOL_PALETTE,
207 GtkToolPalettePrivate);
209 palette->priv->groups = g_ptr_array_sized_new (4);
210 g_ptr_array_set_free_func (palette->priv->groups, g_free);
212 palette->priv->icon_size = DEFAULT_ICON_SIZE;
213 palette->priv->icon_size_set = FALSE;
214 palette->priv->orientation = DEFAULT_ORIENTATION;
215 palette->priv->style = DEFAULT_TOOLBAR_STYLE;
216 palette->priv->style_set = FALSE;
218 palette->priv->text_size_group = gtk_size_group_new (GTK_SIZE_GROUP_BOTH);
222 gtk_tool_palette_reconfigured (GtkToolPalette *palette)
226 for (i = 0; i < palette->priv->groups->len; ++i)
228 GtkToolItemGroupInfo *info = g_ptr_array_index (palette->priv->groups, i);
230 _gtk_tool_item_group_palette_reconfigured (info->widget);
233 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (palette));
237 reset_orientation_style (GtkToolPalette *palette)
239 GtkStyleContext *context;
241 context = gtk_widget_get_style_context (GTK_WIDGET (palette));
243 if (palette->priv->orientation == GTK_ORIENTATION_VERTICAL)
245 gtk_style_context_add_class (context, GTK_STYLE_CLASS_VERTICAL);
246 gtk_style_context_remove_class (context, GTK_STYLE_CLASS_HORIZONTAL);
250 gtk_style_context_add_class (context, GTK_STYLE_CLASS_HORIZONTAL);
251 gtk_style_context_remove_class (context, GTK_STYLE_CLASS_VERTICAL);
256 gtk_tool_palette_set_property (GObject *object,
261 GtkToolPalette *palette = GTK_TOOL_PALETTE (object);
266 if ((guint) g_value_get_enum (value) != palette->priv->icon_size)
268 palette->priv->icon_size = g_value_get_enum (value);
269 gtk_tool_palette_reconfigured (palette);
273 case PROP_ICON_SIZE_SET:
274 if ((guint) g_value_get_enum (value) != palette->priv->icon_size)
276 palette->priv->icon_size_set = g_value_get_enum (value);
277 gtk_tool_palette_reconfigured (palette);
281 case PROP_ORIENTATION:
282 if ((guint) g_value_get_enum (value) != palette->priv->orientation)
284 palette->priv->orientation = g_value_get_enum (value);
285 reset_orientation_style (palette);
286 gtk_tool_palette_reconfigured (palette);
290 case PROP_TOOLBAR_STYLE:
291 if ((guint) g_value_get_enum (value) != palette->priv->style)
293 palette->priv->style = g_value_get_enum (value);
294 gtk_tool_palette_reconfigured (palette);
298 case PROP_HADJUSTMENT:
299 gtk_tool_palette_set_hadjustment (palette, g_value_get_object (value));
302 case PROP_VADJUSTMENT:
303 gtk_tool_palette_set_vadjustment (palette, g_value_get_object (value));
306 case PROP_HSCROLL_POLICY:
307 palette->priv->hscroll_policy = g_value_get_enum (value);
308 gtk_widget_queue_resize (GTK_WIDGET (palette));
311 case PROP_VSCROLL_POLICY:
312 palette->priv->vscroll_policy = g_value_get_enum (value);
313 gtk_widget_queue_resize (GTK_WIDGET (palette));
317 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
323 gtk_tool_palette_get_property (GObject *object,
328 GtkToolPalette *palette = GTK_TOOL_PALETTE (object);
333 g_value_set_enum (value, gtk_tool_palette_get_icon_size (palette));
336 case PROP_ICON_SIZE_SET:
337 g_value_set_boolean (value, palette->priv->icon_size_set);
340 case PROP_ORIENTATION:
341 g_value_set_enum (value, palette->priv->orientation);
344 case PROP_TOOLBAR_STYLE:
345 g_value_set_enum (value, gtk_tool_palette_get_style (palette));
348 case PROP_HADJUSTMENT:
349 g_value_set_object (value, palette->priv->hadjustment);
352 case PROP_VADJUSTMENT:
353 g_value_set_object (value, palette->priv->vadjustment);
356 case PROP_HSCROLL_POLICY:
357 g_value_set_enum (value, palette->priv->hscroll_policy);
360 case PROP_VSCROLL_POLICY:
361 g_value_set_enum (value, palette->priv->vscroll_policy);
365 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
371 gtk_tool_palette_dispose (GObject *object)
373 GtkToolPalette *palette = GTK_TOOL_PALETTE (object);
376 if (palette->priv->hadjustment)
378 g_object_unref (palette->priv->hadjustment);
379 palette->priv->hadjustment = NULL;
382 if (palette->priv->vadjustment)
384 g_object_unref (palette->priv->vadjustment);
385 palette->priv->vadjustment = NULL;
388 for (i = 0; i < palette->priv->groups->len; ++i)
390 GtkToolItemGroupInfo *group = g_ptr_array_index (palette->priv->groups, i);
392 if (group->notify_collapsed)
394 g_signal_handler_disconnect (group->widget, group->notify_collapsed);
395 group->notify_collapsed = 0;
399 if (palette->priv->text_size_group)
401 g_object_unref (palette->priv->text_size_group);
402 palette->priv->text_size_group = NULL;
405 G_OBJECT_CLASS (gtk_tool_palette_parent_class)->dispose (object);
409 gtk_tool_palette_finalize (GObject *object)
411 GtkToolPalette *palette = GTK_TOOL_PALETTE (object);
413 g_ptr_array_free (palette->priv->groups, TRUE);
415 G_OBJECT_CLASS (gtk_tool_palette_parent_class)->finalize (object);
419 gtk_tool_palette_size_request (GtkWidget *widget,
420 GtkRequisition *requisition)
422 GtkToolPalette *palette = GTK_TOOL_PALETTE (widget);
423 GtkRequisition child_requisition;
427 border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
429 requisition->width = 0;
430 requisition->height = 0;
432 for (i = 0; i < palette->priv->groups->len; ++i)
434 GtkToolItemGroupInfo *group = g_ptr_array_index (palette->priv->groups, i);
439 gtk_widget_get_preferred_size (GTK_WIDGET (group->widget),
440 &child_requisition, NULL);
442 if (GTK_ORIENTATION_VERTICAL == palette->priv->orientation)
444 requisition->width = MAX (requisition->width, child_requisition.width);
445 requisition->height += child_requisition.height;
449 requisition->width += child_requisition.width;
450 requisition->height = MAX (requisition->height, child_requisition.height);
454 requisition->width += border_width * 2;
455 requisition->height += border_width * 2;
459 gtk_tool_palette_get_preferred_width (GtkWidget *widget,
463 GtkRequisition requisition;
465 gtk_tool_palette_size_request (widget, &requisition);
467 *minimum = *natural = requisition.width;
471 gtk_tool_palette_get_preferred_height (GtkWidget *widget,
475 GtkRequisition requisition;
477 gtk_tool_palette_size_request (widget, &requisition);
479 *minimum = *natural = requisition.height;
484 gtk_tool_palette_size_allocate (GtkWidget *widget,
485 GtkAllocation *allocation)
487 GtkToolPalette *palette = GTK_TOOL_PALETTE (widget);
488 GtkAdjustment *adjustment = NULL;
489 GtkAllocation child_allocation;
491 gint n_expand_groups = 0;
492 gint remaining_space = 0;
493 gint expand_space = 0;
495 gint page_start, page_size = 0;
500 gint min_offset = -1, max_offset = -1;
504 gint *group_sizes = g_newa (gint, palette->priv->groups->len);
505 GtkTextDirection direction;
507 border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
508 direction = gtk_widget_get_direction (widget);
510 GTK_WIDGET_CLASS (gtk_tool_palette_parent_class)->size_allocate (widget, allocation);
512 if (GTK_ORIENTATION_VERTICAL == palette->priv->orientation)
514 adjustment = palette->priv->vadjustment;
515 page_size = allocation->height;
519 adjustment = palette->priv->hadjustment;
520 page_size = allocation->width;
524 offset = gtk_adjustment_get_value (adjustment);
525 if (GTK_ORIENTATION_HORIZONTAL == palette->priv->orientation &&
526 GTK_TEXT_DIR_RTL == direction)
529 if (GTK_ORIENTATION_VERTICAL == palette->priv->orientation)
530 child_allocation.width = allocation->width - border_width * 2;
532 child_allocation.height = allocation->height - border_width * 2;
534 if (GTK_ORIENTATION_VERTICAL == palette->priv->orientation)
535 remaining_space = allocation->height;
537 remaining_space = allocation->width;
539 /* figure out the required size of all groups to be able to distribute the
540 * remaining space on allocation
542 for (i = 0; i < palette->priv->groups->len; ++i)
544 GtkToolItemGroupInfo *group = g_ptr_array_index (palette->priv->groups, i);
550 widget = GTK_WIDGET (group->widget);
552 if (gtk_tool_item_group_get_n_items (group->widget))
554 if (GTK_ORIENTATION_VERTICAL == palette->priv->orientation)
555 size = _gtk_tool_item_group_get_height_for_width (group->widget, child_allocation.width);
557 size = _gtk_tool_item_group_get_width_for_height (group->widget, child_allocation.height);
559 if (group->expand && !gtk_tool_item_group_get_collapsed (group->widget))
560 n_expand_groups += 1;
565 remaining_space -= size;
566 group_sizes[i] = size;
568 /* if the widget is currently expanding an offset which allows to
569 * display as much of the widget as possible is calculated
571 if (widget == palette->priv->expanding_child)
574 GTK_ORIENTATION_VERTICAL == palette->priv->orientation ?
575 child_allocation.width : child_allocation.height;
582 for (j = 0; j < i; ++j)
583 min_offset += group_sizes[j];
585 max_offset = min_offset + group_sizes[i];
587 real_size = _gtk_tool_item_group_get_size_for_limit
588 (GTK_TOOL_ITEM_GROUP (widget), limit,
589 GTK_ORIENTATION_VERTICAL == palette->priv->orientation,
592 if (size == real_size)
593 palette->priv->expanding_child = NULL;
597 if (n_expand_groups > 0)
599 remaining_space = MAX (0, remaining_space);
600 expand_space = remaining_space / n_expand_groups;
603 if (max_offset != -1)
606 GTK_ORIENTATION_VERTICAL == palette->priv->orientation ?
607 allocation->height : allocation->width;
609 offset = MIN (MAX (offset, max_offset - limit), min_offset);
612 if (remaining_space > 0)
616 child_allocation.y = border_width;
618 if (GTK_ORIENTATION_VERTICAL == palette->priv->orientation)
619 child_allocation.y -= offset;
623 /* allocate all groups at the calculated positions */
624 for (i = 0; i < palette->priv->groups->len; ++i)
626 GtkToolItemGroupInfo *group = g_ptr_array_index (palette->priv->groups, i);
632 widget = GTK_WIDGET (group->widget);
634 if (gtk_tool_item_group_get_n_items (group->widget))
636 gint size = group_sizes[i];
638 if (group->expand && !gtk_tool_item_group_get_collapsed (group->widget))
640 size += MIN (expand_space, remaining_space);
641 remaining_space -= expand_space;
644 if (GTK_ORIENTATION_VERTICAL == palette->priv->orientation)
645 child_allocation.height = size;
647 child_allocation.width = size;
649 if (GTK_ORIENTATION_HORIZONTAL == palette->priv->orientation &&
650 GTK_TEXT_DIR_RTL == direction)
651 child_allocation.x = allocation->width - x - child_allocation.width;
653 child_allocation.x = x;
655 gtk_widget_size_allocate (widget, &child_allocation);
656 gtk_widget_show (widget);
658 if (GTK_ORIENTATION_VERTICAL == palette->priv->orientation)
659 child_allocation.y += child_allocation.height;
661 x += child_allocation.width;
664 gtk_widget_hide (widget);
667 if (GTK_ORIENTATION_VERTICAL == palette->priv->orientation)
669 child_allocation.y += border_width;
670 child_allocation.y += offset;
672 page_start = child_allocation.y;
682 /* update the scrollbar to match the displayed adjustment */
685 gdouble value, lower, upper;
687 if (GTK_ORIENTATION_VERTICAL == palette->priv->orientation ||
688 GTK_TEXT_DIR_LTR == direction)
691 upper = MAX (0, page_start);
693 value = MIN (offset, upper - page_size);
694 gtk_adjustment_clamp_page (adjustment, value, offset + page_size);
698 lower = page_size - MAX (0, page_start);
703 value = MAX (offset, lower);
704 gtk_adjustment_clamp_page (adjustment, offset, value + page_size);
707 gtk_adjustment_configure (adjustment,
718 gtk_tool_palette_draw (GtkWidget *widget,
721 GtkToolPalette *palette = GTK_TOOL_PALETTE (widget);
726 window = gtk_widget_get_window (widget);
728 display = gdk_window_get_display (window);
730 if (!gdk_display_supports_composite (display))
733 cairo_push_group (cr);
735 for (i = 0; i < palette->priv->groups->len; ++i)
737 GtkToolItemGroupInfo *info = g_ptr_array_index (palette->priv->groups, i);
739 _gtk_tool_item_group_paint (info->widget, cr);
742 cairo_pop_group_to_source (cr);
750 gtk_tool_palette_realize (GtkWidget *widget)
752 GtkAllocation allocation;
754 GdkWindowAttr attributes;
755 gint attributes_mask;
758 gtk_widget_set_realized (widget, TRUE);
760 border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
762 gtk_widget_get_allocation (widget, &allocation);
764 attributes.window_type = GDK_WINDOW_CHILD;
765 attributes.x = allocation.x + border_width;
766 attributes.y = allocation.y + border_width;
767 attributes.width = allocation.width - border_width * 2;
768 attributes.height = allocation.height - border_width * 2;
769 attributes.wclass = GDK_INPUT_OUTPUT;
770 attributes.visual = gtk_widget_get_visual (widget);
771 attributes.event_mask = gtk_widget_get_events (widget)
772 | GDK_VISIBILITY_NOTIFY_MASK | GDK_EXPOSURE_MASK
773 | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
774 | GDK_BUTTON_MOTION_MASK;
775 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
777 window = gdk_window_new (gtk_widget_get_parent_window (widget),
778 &attributes, attributes_mask);
779 gtk_widget_set_window (widget, window);
780 gdk_window_set_user_data (window, widget);
782 gtk_style_context_set_background (gtk_widget_get_style_context (widget),
785 gtk_container_forall (GTK_CONTAINER (widget),
786 (GtkCallback) gtk_widget_set_parent_window,
789 gtk_widget_queue_resize_no_redraw (widget);
793 gtk_tool_palette_adjustment_value_changed (GtkAdjustment *adjustment,
796 GtkAllocation allocation;
797 GtkWidget *widget = GTK_WIDGET (data);
799 gtk_widget_get_allocation (widget, &allocation);
800 gtk_tool_palette_size_allocate (widget, &allocation);
804 gtk_tool_palette_add (GtkContainer *container,
807 GtkToolPalette *palette;
808 GtkToolItemGroupInfo *info = g_new0(GtkToolItemGroupInfo, 1);
810 g_return_if_fail (GTK_IS_TOOL_PALETTE (container));
811 g_return_if_fail (GTK_IS_TOOL_ITEM_GROUP (child));
813 palette = GTK_TOOL_PALETTE (container);
815 g_ptr_array_add (palette->priv->groups, info);
816 info->pos = palette->priv->groups->len - 1;
817 info->widget = g_object_ref_sink (child);
819 gtk_widget_set_parent (child, GTK_WIDGET (palette));
823 gtk_tool_palette_remove (GtkContainer *container,
826 GtkToolPalette *palette;
829 g_return_if_fail (GTK_IS_TOOL_PALETTE (container));
830 palette = GTK_TOOL_PALETTE (container);
832 for (i = 0; i < palette->priv->groups->len; ++i)
834 GtkToolItemGroupInfo *info = g_ptr_array_index (palette->priv->groups, i);
835 if (GTK_WIDGET(info->widget) == child)
837 g_object_unref (child);
838 gtk_widget_unparent (child);
840 g_ptr_array_remove_index (palette->priv->groups, i);
846 gtk_tool_palette_forall (GtkContainer *container,
848 GtkCallback callback,
849 gpointer callback_data)
851 GtkToolPalette *palette = GTK_TOOL_PALETTE (container);
855 for (i = 0; i < palette->priv->groups->len; ++i)
857 GtkToolItemGroupInfo *info = g_ptr_array_index (palette->priv->groups, i);
859 callback (GTK_WIDGET (info->widget),
865 gtk_tool_palette_child_type (GtkContainer *container)
867 return GTK_TYPE_TOOL_ITEM_GROUP;
871 gtk_tool_palette_set_child_property (GtkContainer *container,
877 GtkToolPalette *palette = GTK_TOOL_PALETTE (container);
881 case CHILD_PROP_EXCLUSIVE:
882 gtk_tool_palette_set_exclusive (palette, GTK_TOOL_ITEM_GROUP (child),
883 g_value_get_boolean (value));
886 case CHILD_PROP_EXPAND:
887 gtk_tool_palette_set_expand (palette, GTK_TOOL_ITEM_GROUP (child),
888 g_value_get_boolean (value));
892 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, prop_id, pspec);
898 gtk_tool_palette_get_child_property (GtkContainer *container,
904 GtkToolPalette *palette = GTK_TOOL_PALETTE (container);
908 case CHILD_PROP_EXCLUSIVE:
909 g_value_set_boolean (value,
910 gtk_tool_palette_get_exclusive (palette, GTK_TOOL_ITEM_GROUP (child)));
913 case CHILD_PROP_EXPAND:
914 g_value_set_boolean (value,
915 gtk_tool_palette_get_expand (palette, GTK_TOOL_ITEM_GROUP (child)));
919 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, prop_id, pspec);
925 style_change_notify (GtkToolPalette *palette)
927 GtkToolPalettePrivate* priv = palette->priv;
929 if (!priv->style_set)
931 /* pretend it was set, then unset, thus reverting to new default */
932 priv->style_set = TRUE;
933 gtk_tool_palette_unset_style (palette);
938 icon_size_change_notify (GtkToolPalette *palette)
940 GtkToolPalettePrivate* priv = palette->priv;
942 if (!priv->icon_size_set)
944 /* pretend it was set, then unset, thus reverting to new default */
945 priv->icon_size_set = TRUE;
946 gtk_tool_palette_unset_icon_size (palette);
951 gtk_tool_palette_settings_change_notify (GtkSettings *settings,
952 const GParamSpec *pspec,
953 GtkToolPalette *palette)
955 if (strcmp (pspec->name, "gtk-toolbar-style") == 0)
956 style_change_notify (palette);
957 else if (strcmp (pspec->name, "gtk-toolbar-icon-size") == 0)
958 icon_size_change_notify (palette);
962 gtk_tool_palette_screen_changed (GtkWidget *widget,
963 GdkScreen *previous_screen)
965 GtkToolPalette *palette = GTK_TOOL_PALETTE (widget);
966 GtkToolPalettePrivate* priv = palette->priv;
967 GtkSettings *old_settings = priv->settings;
968 GtkSettings *settings;
970 if (gtk_widget_has_screen (GTK_WIDGET (palette)))
971 settings = gtk_widget_get_settings (GTK_WIDGET (palette));
975 if (settings == old_settings)
980 g_signal_handler_disconnect (old_settings, priv->settings_connection);
981 g_object_unref (old_settings);
986 priv->settings_connection =
987 g_signal_connect (settings, "notify",
988 G_CALLBACK (gtk_tool_palette_settings_change_notify),
990 priv->settings = g_object_ref (settings);
993 priv->settings = NULL;
995 gtk_tool_palette_reconfigured (palette);
1000 gtk_tool_palette_class_init (GtkToolPaletteClass *cls)
1002 GObjectClass *oclass = G_OBJECT_CLASS (cls);
1003 GtkWidgetClass *wclass = GTK_WIDGET_CLASS (cls);
1004 GtkContainerClass *cclass = GTK_CONTAINER_CLASS (cls);
1006 oclass->set_property = gtk_tool_palette_set_property;
1007 oclass->get_property = gtk_tool_palette_get_property;
1008 oclass->dispose = gtk_tool_palette_dispose;
1009 oclass->finalize = gtk_tool_palette_finalize;
1011 wclass->get_preferred_width = gtk_tool_palette_get_preferred_width;
1012 wclass->get_preferred_height= gtk_tool_palette_get_preferred_height;
1013 wclass->size_allocate = gtk_tool_palette_size_allocate;
1014 wclass->draw = gtk_tool_palette_draw;
1015 wclass->realize = gtk_tool_palette_realize;
1017 cclass->add = gtk_tool_palette_add;
1018 cclass->remove = gtk_tool_palette_remove;
1019 cclass->forall = gtk_tool_palette_forall;
1020 cclass->child_type = gtk_tool_palette_child_type;
1021 cclass->set_child_property = gtk_tool_palette_set_child_property;
1022 cclass->get_child_property = gtk_tool_palette_get_child_property;
1024 /* Handle screen-changed so we can update our GtkSettings.
1026 wclass->screen_changed = gtk_tool_palette_screen_changed;
1028 g_object_class_override_property (oclass, PROP_ORIENTATION, "orientation");
1030 g_object_class_override_property (oclass, PROP_HADJUSTMENT, "hadjustment");
1031 g_object_class_override_property (oclass, PROP_VADJUSTMENT, "vadjustment");
1032 g_object_class_override_property (oclass, PROP_HSCROLL_POLICY, "hscroll-policy");
1033 g_object_class_override_property (oclass, PROP_VSCROLL_POLICY, "vscroll-policy");
1036 * GtkToolPalette:icon-size:
1038 * The size of the icons in a tool palette is normally determined by
1039 * the #GtkSettings:toolbar-icon-size setting. When this property is set,
1040 * it overrides the setting.
1042 * This should only be used for special-purpose tool palettes, normal
1043 * application tool palettes should respect the user preferences for the
1048 g_object_class_install_property (oclass,
1050 g_param_spec_enum ("icon-size",
1052 P_("Size of icons in this tool palette"),
1055 GTK_PARAM_READWRITE));
1058 * GtkToolPalette:icon-size-set:
1060 * Is %TRUE if the #GtkToolPalette:icon-size property has been set.
1064 g_object_class_install_property (oclass,
1066 g_param_spec_boolean ("icon-size-set",
1067 P_("Icon size set"),
1068 P_("Whether the icon-size property has been set"),
1070 GTK_PARAM_READWRITE));
1073 * GtkToolPalette:toolbar-style:
1075 * The style of items in the tool palette.
1079 g_object_class_install_property (oclass, PROP_TOOLBAR_STYLE,
1080 g_param_spec_enum ("toolbar-style",
1081 P_("Toolbar Style"),
1082 P_("Style of items in the tool palette"),
1083 GTK_TYPE_TOOLBAR_STYLE,
1084 DEFAULT_TOOLBAR_STYLE,
1085 GTK_PARAM_READWRITE));
1089 * GtkToolPalette:exclusive:
1091 * Whether the item group should be the only one that is expanded
1096 gtk_container_class_install_child_property (cclass, CHILD_PROP_EXCLUSIVE,
1097 g_param_spec_boolean ("exclusive",
1099 P_("Whether the item group should be the only expanded at a given time"),
1100 DEFAULT_CHILD_EXCLUSIVE,
1101 GTK_PARAM_READWRITE));
1104 * GtkToolPalette:expand:
1106 * Whether the item group should receive extra space when the palette grows.
1111 gtk_container_class_install_child_property (cclass, CHILD_PROP_EXPAND,
1112 g_param_spec_boolean ("expand",
1114 P_("Whether the item group should receive extra space when the palette grows"),
1115 DEFAULT_CHILD_EXPAND,
1116 GTK_PARAM_READWRITE));
1118 g_type_class_add_private (cls, sizeof (GtkToolPalettePrivate));
1120 dnd_target_atom_item = gdk_atom_intern_static_string (dnd_targets[0].target);
1121 dnd_target_atom_group = gdk_atom_intern_static_string (dnd_targets[1].target);
1125 * gtk_tool_palette_new:
1127 * Creates a new tool palette.
1129 * Returns: a new #GtkToolPalette
1134 gtk_tool_palette_new (void)
1136 return g_object_new (GTK_TYPE_TOOL_PALETTE, NULL);
1140 * gtk_tool_palette_set_icon_size:
1141 * @palette: a #GtkToolPalette
1142 * @icon_size: (type int): the #GtkIconSize that icons in the tool
1143 * palette shall have
1145 * Sets the size of icons in the tool palette.
1150 gtk_tool_palette_set_icon_size (GtkToolPalette *palette,
1151 GtkIconSize icon_size)
1153 GtkToolPalettePrivate *priv;
1155 g_return_if_fail (GTK_IS_TOOL_PALETTE (palette));
1156 g_return_if_fail (icon_size != GTK_ICON_SIZE_INVALID);
1158 priv = palette->priv;
1160 if (!priv->icon_size_set)
1162 priv->icon_size_set = TRUE;
1163 g_object_notify (G_OBJECT (palette), "icon-size-set");
1166 if (priv->icon_size == icon_size)
1169 priv->icon_size = icon_size;
1170 g_object_notify (G_OBJECT (palette), "icon-size");
1172 gtk_tool_palette_reconfigured (palette);
1174 gtk_widget_queue_resize (GTK_WIDGET (palette));
1177 static GtkSettings *
1178 toolpalette_get_settings (GtkToolPalette *palette)
1180 GtkToolPalettePrivate *priv = palette->priv;
1181 return priv->settings;
1185 * gtk_tool_palette_unset_icon_size:
1186 * @palette: a #GtkToolPalette
1188 * Unsets the tool palette icon size set with gtk_tool_palette_set_icon_size(),
1189 * so that user preferences will be used to determine the icon size.
1194 gtk_tool_palette_unset_icon_size (GtkToolPalette *palette)
1196 GtkToolPalettePrivate* priv = palette->priv;
1199 g_return_if_fail (GTK_IS_TOOL_PALETTE (palette));
1201 if (palette->priv->icon_size_set)
1203 GtkSettings *settings = toolpalette_get_settings (palette);
1207 g_object_get (settings,
1208 "gtk-toolbar-icon-size", &size,
1212 size = DEFAULT_ICON_SIZE;
1214 if (size != palette->priv->icon_size)
1216 gtk_tool_palette_set_icon_size (palette, size);
1217 g_object_notify (G_OBJECT (palette), "icon-size");
1220 priv->icon_size_set = FALSE;
1221 g_object_notify (G_OBJECT (palette), "icon-size-set");
1225 /* Set the "toolbar-style" property and do appropriate things.
1226 * GtkToolbar does this by emitting a signal instead of just
1227 * calling a function...
1230 gtk_tool_palette_change_style (GtkToolPalette *palette,
1231 GtkToolbarStyle style)
1233 GtkToolPalettePrivate* priv = palette->priv;
1235 if (priv->style != style)
1237 priv->style = style;
1239 gtk_tool_palette_reconfigured (palette);
1241 gtk_widget_queue_resize (GTK_WIDGET (palette));
1242 g_object_notify (G_OBJECT (palette), "toolbar-style");
1248 * gtk_tool_palette_set_style:
1249 * @palette: a #GtkToolPalette
1250 * @style: the #GtkToolbarStyle that items in the tool palette shall have
1252 * Sets the style (text, icons or both) of items in the tool palette.
1257 gtk_tool_palette_set_style (GtkToolPalette *palette,
1258 GtkToolbarStyle style)
1260 g_return_if_fail (GTK_IS_TOOL_PALETTE (palette));
1262 palette->priv->style_set = TRUE;
1263 gtk_tool_palette_change_style (palette, style);
1268 * gtk_tool_palette_unset_style:
1269 * @palette: a #GtkToolPalette
1271 * Unsets a toolbar style set with gtk_tool_palette_set_style(),
1272 * so that user preferences will be used to determine the toolbar style.
1277 gtk_tool_palette_unset_style (GtkToolPalette *palette)
1279 GtkToolPalettePrivate* priv = palette->priv;
1280 GtkToolbarStyle style;
1282 g_return_if_fail (GTK_IS_TOOL_PALETTE (palette));
1284 if (priv->style_set)
1286 GtkSettings *settings = toolpalette_get_settings (palette);
1289 g_object_get (settings,
1290 "gtk-toolbar-style", &style,
1293 style = DEFAULT_TOOLBAR_STYLE;
1295 if (style != priv->style)
1296 gtk_tool_palette_change_style (palette, style);
1298 priv->style_set = FALSE;
1303 * gtk_tool_palette_get_icon_size:
1304 * @palette: a #GtkToolPalette
1306 * Gets the size of icons in the tool palette.
1307 * See gtk_tool_palette_set_icon_size().
1309 * Returns: (type int): the #GtkIconSize of icons in the tool palette
1314 gtk_tool_palette_get_icon_size (GtkToolPalette *palette)
1316 g_return_val_if_fail (GTK_IS_TOOL_PALETTE (palette), DEFAULT_ICON_SIZE);
1318 return palette->priv->icon_size;
1322 * gtk_tool_palette_get_style:
1323 * @palette: a #GtkToolPalette
1325 * Gets the style (icons, text or both) of items in the tool palette.
1327 * Returns: the #GtkToolbarStyle of items in the tool palette.
1332 gtk_tool_palette_get_style (GtkToolPalette *palette)
1334 g_return_val_if_fail (GTK_IS_TOOL_PALETTE (palette), DEFAULT_TOOLBAR_STYLE);
1336 return palette->priv->style;
1340 _gtk_tool_palette_compare_groups (gconstpointer a,
1343 const GtkToolItemGroupInfo *group_a = a;
1344 const GtkToolItemGroupInfo *group_b = b;
1346 return group_a->pos - group_b->pos;
1350 * gtk_tool_palette_set_group_position:
1351 * @palette: a #GtkToolPalette
1352 * @group: a #GtkToolItemGroup which is a child of palette
1353 * @position: a new index for group
1355 * Sets the position of the group as an index of the tool palette.
1356 * If position is 0 the group will become the first child, if position is
1357 * -1 it will become the last child.
1362 gtk_tool_palette_set_group_position (GtkToolPalette *palette,
1363 GtkToolItemGroup *group,
1366 GtkToolItemGroupInfo *group_new;
1367 GtkToolItemGroupInfo *group_old;
1370 g_return_if_fail (GTK_IS_TOOL_PALETTE (palette));
1371 g_return_if_fail (GTK_IS_TOOL_ITEM_GROUP (group));
1372 g_return_if_fail (position >= -1);
1375 position = palette->priv->groups->len - 1;
1377 g_return_if_fail ((guint) position < palette->priv->groups->len);
1379 group_new = g_ptr_array_index (palette->priv->groups, position);
1381 if (GTK_TOOL_ITEM_GROUP (group) == group_new->widget)
1384 old_position = gtk_tool_palette_get_group_position (palette, group);
1385 g_return_if_fail (old_position >= 0);
1387 group_old = g_ptr_array_index (palette->priv->groups, old_position);
1389 group_new->pos = position;
1390 group_old->pos = old_position;
1392 g_ptr_array_sort (palette->priv->groups, _gtk_tool_palette_compare_groups);
1394 gtk_widget_queue_resize (GTK_WIDGET (palette));
1398 gtk_tool_palette_group_notify_collapsed (GtkToolItemGroup *group,
1402 GtkToolPalette *palette = GTK_TOOL_PALETTE (data);
1405 if (gtk_tool_item_group_get_collapsed (group))
1408 for (i = 0; i < palette->priv->groups->len; ++i)
1410 GtkToolItemGroupInfo *info = g_ptr_array_index (palette->priv->groups, i);
1411 GtkToolItemGroup *current_group = info->widget;
1413 if (current_group && current_group != group)
1414 gtk_tool_item_group_set_collapsed (current_group, TRUE);
1419 * gtk_tool_palette_set_exclusive:
1420 * @palette: a #GtkToolPalette
1421 * @group: a #GtkToolItemGroup which is a child of palette
1422 * @exclusive: whether the group should be exclusive or not
1424 * Sets whether the group should be exclusive or not.
1425 * If an exclusive group is expanded all other groups are collapsed.
1430 gtk_tool_palette_set_exclusive (GtkToolPalette *palette,
1431 GtkToolItemGroup *group,
1434 GtkToolItemGroupInfo *group_info;
1437 g_return_if_fail (GTK_IS_TOOL_PALETTE (palette));
1438 g_return_if_fail (GTK_IS_TOOL_ITEM_GROUP (group));
1440 position = gtk_tool_palette_get_group_position (palette, group);
1441 g_return_if_fail (position >= 0);
1443 group_info = g_ptr_array_index (palette->priv->groups, position);
1445 if (exclusive == group_info->exclusive)
1448 group_info->exclusive = exclusive;
1450 if (group_info->exclusive != (0 != group_info->notify_collapsed))
1452 if (group_info->exclusive)
1454 group_info->notify_collapsed =
1455 g_signal_connect (group, "notify::collapsed",
1456 G_CALLBACK (gtk_tool_palette_group_notify_collapsed),
1461 g_signal_handler_disconnect (group, group_info->notify_collapsed);
1462 group_info->notify_collapsed = 0;
1466 gtk_tool_palette_group_notify_collapsed (group_info->widget, NULL, palette);
1467 gtk_widget_child_notify (GTK_WIDGET (group), "exclusive");
1471 * gtk_tool_palette_set_expand:
1472 * @palette: a #GtkToolPalette
1473 * @group: a #GtkToolItemGroup which is a child of palette
1474 * @expand: whether the group should be given extra space
1476 * Sets whether the group should be given extra space.
1481 gtk_tool_palette_set_expand (GtkToolPalette *palette,
1482 GtkToolItemGroup *group,
1485 GtkToolItemGroupInfo *group_info;
1488 g_return_if_fail (GTK_IS_TOOL_PALETTE (palette));
1489 g_return_if_fail (GTK_IS_TOOL_ITEM_GROUP (group));
1491 position = gtk_tool_palette_get_group_position (palette, group);
1492 g_return_if_fail (position >= 0);
1494 group_info = g_ptr_array_index (palette->priv->groups, position);
1496 if (expand != group_info->expand)
1498 group_info->expand = expand;
1499 gtk_widget_queue_resize (GTK_WIDGET (palette));
1500 gtk_widget_child_notify (GTK_WIDGET (group), "expand");
1505 * gtk_tool_palette_get_group_position:
1506 * @palette: a #GtkToolPalette
1507 * @group: a #GtkToolItemGroup
1509 * Gets the position of @group in @palette as index.
1510 * See gtk_tool_palette_set_group_position().
1512 * Returns: the index of group or -1 if @group is not a child of @palette
1517 gtk_tool_palette_get_group_position (GtkToolPalette *palette,
1518 GtkToolItemGroup *group)
1522 g_return_val_if_fail (GTK_IS_TOOL_PALETTE (palette), -1);
1523 g_return_val_if_fail (GTK_IS_TOOL_ITEM_GROUP (group), -1);
1525 for (i = 0; i < palette->priv->groups->len; ++i)
1527 GtkToolItemGroupInfo *info = g_ptr_array_index (palette->priv->groups, i);
1528 if ((gpointer) group == info->widget)
1536 * gtk_tool_palette_get_exclusive:
1537 * @palette: a #GtkToolPalette
1538 * @group: a #GtkToolItemGroup which is a child of palette
1540 * Gets whether @group is exclusive or not.
1541 * See gtk_tool_palette_set_exclusive().
1543 * Returns: %TRUE if @group is exclusive
1548 gtk_tool_palette_get_exclusive (GtkToolPalette *palette,
1549 GtkToolItemGroup *group)
1552 GtkToolItemGroupInfo *info;
1554 g_return_val_if_fail (GTK_IS_TOOL_PALETTE (palette), DEFAULT_CHILD_EXCLUSIVE);
1555 g_return_val_if_fail (GTK_IS_TOOL_ITEM_GROUP (group), DEFAULT_CHILD_EXCLUSIVE);
1557 position = gtk_tool_palette_get_group_position (palette, group);
1558 g_return_val_if_fail (position >= 0, DEFAULT_CHILD_EXCLUSIVE);
1560 info = g_ptr_array_index (palette->priv->groups, position);
1562 return info->exclusive;
1566 * gtk_tool_palette_get_expand:
1567 * @palette: a #GtkToolPalette
1568 * @group: a #GtkToolItemGroup which is a child of palette
1570 * Gets whether group should be given extra space.
1571 * See gtk_tool_palette_set_expand().
1573 * Returns: %TRUE if group should be given extra space, %FALSE otherwise
1578 gtk_tool_palette_get_expand (GtkToolPalette *palette,
1579 GtkToolItemGroup *group)
1582 GtkToolItemGroupInfo *info;
1584 g_return_val_if_fail (GTK_IS_TOOL_PALETTE (palette), DEFAULT_CHILD_EXPAND);
1585 g_return_val_if_fail (GTK_IS_TOOL_ITEM_GROUP (group), DEFAULT_CHILD_EXPAND);
1587 position = gtk_tool_palette_get_group_position (palette, group);
1588 g_return_val_if_fail (position >= 0, DEFAULT_CHILD_EXPAND);
1590 info = g_ptr_array_index (palette->priv->groups, position);
1592 return info->expand;
1596 * gtk_tool_palette_get_drop_item:
1597 * @palette: a #GtkToolPalette
1598 * @x: the x position
1599 * @y: the y position
1601 * Gets the item at position (x, y).
1602 * See gtk_tool_palette_get_drop_group().
1604 * Returns: (transfer none): the #GtkToolItem at position or %NULL if there is no such item
1609 gtk_tool_palette_get_drop_item (GtkToolPalette *palette,
1613 GtkAllocation allocation;
1614 GtkToolItemGroup *group = gtk_tool_palette_get_drop_group (palette, x, y);
1615 GtkWidget *widget = GTK_WIDGET (group);
1619 gtk_widget_get_allocation (widget, &allocation);
1620 return gtk_tool_item_group_get_drop_item (group,
1629 * gtk_tool_palette_get_drop_group:
1630 * @palette: a #GtkToolPalette
1631 * @x: the x position
1632 * @y: the y position
1634 * Gets the group at position (x, y).
1636 * Returns: (transfer none): the #GtkToolItemGroup at position or %NULL
1637 * if there is no such group
1642 gtk_tool_palette_get_drop_group (GtkToolPalette *palette,
1646 GtkAllocation allocation;
1649 g_return_val_if_fail (GTK_IS_TOOL_PALETTE (palette), NULL);
1651 gtk_widget_get_allocation (GTK_WIDGET (palette), &allocation);
1653 g_return_val_if_fail (x >= 0 && x < allocation.width, NULL);
1654 g_return_val_if_fail (y >= 0 && y < allocation.height, NULL);
1656 for (i = 0; i < palette->priv->groups->len; ++i)
1658 GtkToolItemGroupInfo *group = g_ptr_array_index (palette->priv->groups, i);
1665 widget = GTK_WIDGET (group->widget);
1666 gtk_widget_get_allocation (widget, &allocation);
1668 x0 = x - allocation.x;
1669 y0 = y - allocation.y;
1671 if (x0 >= 0 && x0 < allocation.width &&
1672 y0 >= 0 && y0 < allocation.height)
1673 return GTK_TOOL_ITEM_GROUP (widget);
1680 * gtk_tool_palette_get_drag_item:
1681 * @palette: a #GtkToolPalette
1682 * @selection: a #GtkSelectionData
1684 * Get the dragged item from the selection.
1685 * This could be a #GtkToolItem or a #GtkToolItemGroup.
1687 * Returns: (transfer none): the dragged item in selection
1692 gtk_tool_palette_get_drag_item (GtkToolPalette *palette,
1693 const GtkSelectionData *selection)
1695 GtkToolPaletteDragData *data;
1698 g_return_val_if_fail (GTK_IS_TOOL_PALETTE (palette), NULL);
1699 g_return_val_if_fail (NULL != selection, NULL);
1701 g_return_val_if_fail (gtk_selection_data_get_format (selection) == 8, NULL);
1702 g_return_val_if_fail (gtk_selection_data_get_length (selection) == sizeof (GtkToolPaletteDragData), NULL);
1703 target = gtk_selection_data_get_target (selection);
1704 g_return_val_if_fail (target == dnd_target_atom_item ||
1705 target == dnd_target_atom_group,
1708 data = (GtkToolPaletteDragData*) gtk_selection_data_get_data (selection);
1710 g_return_val_if_fail (data->palette == palette, NULL);
1712 if (dnd_target_atom_item == target)
1713 g_return_val_if_fail (GTK_IS_TOOL_ITEM (data->item), NULL);
1714 else if (dnd_target_atom_group == target)
1715 g_return_val_if_fail (GTK_IS_TOOL_ITEM_GROUP (data->item), NULL);
1721 * gtk_tool_palette_set_drag_source:
1722 * @palette: a #GtkToolPalette
1723 * @targets: the #GtkToolPaletteDragTarget<!-- -->s
1724 * which the widget should support
1726 * Sets the tool palette as a drag source.
1727 * Enables all groups and items in the tool palette as drag sources
1728 * on button 1 and button 3 press with copy and move actions.
1729 * See gtk_drag_source_set().
1734 gtk_tool_palette_set_drag_source (GtkToolPalette *palette,
1735 GtkToolPaletteDragTargets targets)
1739 g_return_if_fail (GTK_IS_TOOL_PALETTE (palette));
1741 if ((palette->priv->drag_source & targets) == targets)
1744 palette->priv->drag_source |= targets;
1746 for (i = 0; i < palette->priv->groups->len; ++i)
1748 GtkToolItemGroupInfo *info = g_ptr_array_index (palette->priv->groups, i);
1750 gtk_container_forall (GTK_CONTAINER (info->widget),
1751 _gtk_tool_palette_child_set_drag_source,
1757 * gtk_tool_palette_add_drag_dest:
1758 * @palette: a #GtkToolPalette
1759 * @widget: a #GtkWidget which should be a drag destination for @palette
1760 * @flags: the flags that specify what actions GTK+ should take for drops
1762 * @targets: the #GtkToolPaletteDragTarget<!-- -->s which the widget
1764 * @actions: the #GdkDragAction<!-- -->s which the widget should suppport
1766 * Sets @palette as drag source (see gtk_tool_palette_set_drag_source())
1767 * and sets @widget as a drag destination for drags from @palette.
1768 * See gtk_drag_dest_set().
1773 gtk_tool_palette_add_drag_dest (GtkToolPalette *palette,
1775 GtkDestDefaults flags,
1776 GtkToolPaletteDragTargets targets,
1777 GdkDragAction actions)
1779 GtkTargetEntry entries[G_N_ELEMENTS (dnd_targets)];
1782 g_return_if_fail (GTK_IS_TOOL_PALETTE (palette));
1783 g_return_if_fail (GTK_IS_WIDGET (widget));
1785 gtk_tool_palette_set_drag_source (palette,
1788 if (targets & GTK_TOOL_PALETTE_DRAG_ITEMS)
1789 entries[n_entries++] = dnd_targets[0];
1790 if (targets & GTK_TOOL_PALETTE_DRAG_GROUPS)
1791 entries[n_entries++] = dnd_targets[1];
1793 gtk_drag_dest_set (widget, flags, entries, n_entries, actions);
1797 _gtk_tool_palette_get_item_size (GtkToolPalette *palette,
1798 GtkRequisition *item_size,
1799 gboolean homogeneous_only,
1800 gint *requested_rows)
1802 GtkRequisition max_requisition;
1806 g_return_if_fail (GTK_IS_TOOL_PALETTE (palette));
1807 g_return_if_fail (NULL != item_size);
1809 max_requisition.width = 0;
1810 max_requisition.height = 0;
1813 /* iterate over all groups and calculate the max item_size and max row request */
1814 for (i = 0; i < palette->priv->groups->len; ++i)
1816 GtkRequisition requisition;
1818 GtkToolItemGroupInfo *group = g_ptr_array_index (palette->priv->groups, i);
1823 _gtk_tool_item_group_item_size_request (group->widget, &requisition, homogeneous_only, &rows);
1825 max_requisition.width = MAX (max_requisition.width, requisition.width);
1826 max_requisition.height = MAX (max_requisition.height, requisition.height);
1827 max_rows = MAX (max_rows, rows);
1830 *item_size = max_requisition;
1832 *requested_rows = max_rows;
1836 gtk_tool_palette_item_drag_data_get (GtkWidget *widget,
1837 GdkDragContext *context,
1838 GtkSelectionData *selection,
1843 GtkToolPaletteDragData drag_data = { GTK_TOOL_PALETTE (data), NULL };
1846 target = gtk_selection_data_get_target (selection);
1848 if (target == dnd_target_atom_item)
1849 drag_data.item = gtk_widget_get_ancestor (widget, GTK_TYPE_TOOL_ITEM);
1852 gtk_selection_data_set (selection, target, 8,
1853 (guchar*) &drag_data, sizeof (drag_data));
1857 gtk_tool_palette_child_drag_data_get (GtkWidget *widget,
1858 GdkDragContext *context,
1859 GtkSelectionData *selection,
1864 GtkToolPaletteDragData drag_data = { GTK_TOOL_PALETTE (data), NULL };
1867 target = gtk_selection_data_get_target (selection);
1869 if (target == dnd_target_atom_group)
1870 drag_data.item = gtk_widget_get_ancestor (widget, GTK_TYPE_TOOL_ITEM_GROUP);
1873 gtk_selection_data_set (selection, target, 8,
1874 (guchar*) &drag_data, sizeof (drag_data));
1878 _gtk_tool_palette_child_set_drag_source (GtkWidget *child,
1881 GtkToolPalette *palette = GTK_TOOL_PALETTE (data);
1883 /* Check drag_source,
1884 * to work properly when called from gtk_tool_item_group_insert().
1886 if (!palette->priv->drag_source)
1889 if (GTK_IS_TOOL_ITEM (child) &&
1890 (palette->priv->drag_source & GTK_TOOL_PALETTE_DRAG_ITEMS))
1892 /* Connect to child instead of the item itself,
1893 * to work arround bug 510377.
1895 if (GTK_IS_TOOL_BUTTON (child))
1896 child = gtk_bin_get_child (GTK_BIN (child));
1901 gtk_drag_source_set (child, GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
1902 &dnd_targets[0], 1, GDK_ACTION_COPY | GDK_ACTION_MOVE);
1904 g_signal_connect (child, "drag-data-get",
1905 G_CALLBACK (gtk_tool_palette_item_drag_data_get),
1908 else if (GTK_IS_BUTTON (child) &&
1909 (palette->priv->drag_source & GTK_TOOL_PALETTE_DRAG_GROUPS))
1911 gtk_drag_source_set (child, GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
1912 &dnd_targets[1], 1, GDK_ACTION_COPY | GDK_ACTION_MOVE);
1914 g_signal_connect (child, "drag-data-get",
1915 G_CALLBACK (gtk_tool_palette_child_drag_data_get),
1921 * gtk_tool_palette_get_drag_target_item:
1923 * Gets the target entry for a dragged #GtkToolItem.
1925 * Returns: (transfer none): the #GtkTargetEntry for a dragged item.
1929 G_CONST_RETURN GtkTargetEntry*
1930 gtk_tool_palette_get_drag_target_item (void)
1932 return &dnd_targets[0];
1936 * gtk_tool_palette_get_drag_target_group:
1938 * Get the target entry for a dragged #GtkToolItemGroup.
1940 * Returns: (transfer none): the #GtkTargetEntry for a dragged group
1944 G_CONST_RETURN GtkTargetEntry*
1945 gtk_tool_palette_get_drag_target_group (void)
1947 return &dnd_targets[1];
1951 _gtk_tool_palette_set_expanding_child (GtkToolPalette *palette,
1954 g_return_if_fail (GTK_IS_TOOL_PALETTE (palette));
1955 palette->priv->expanding_child = widget;
1959 * gtk_tool_palette_get_hadjustment:
1960 * @palette: a #GtkToolPalette
1962 * Gets the horizontal adjustment of the tool palette.
1964 * Returns: (transfer none): the horizontal adjustment of @palette
1968 * Deprecated: 3.0: Use gtk_scrollable_get_hadjustment()
1971 gtk_tool_palette_get_hadjustment (GtkToolPalette *palette)
1973 g_return_val_if_fail (GTK_IS_TOOL_PALETTE (palette), NULL);
1975 return palette->priv->hadjustment;
1979 gtk_tool_palette_set_hadjustment (GtkToolPalette *palette,
1980 GtkAdjustment *adjustment)
1982 GtkToolPalettePrivate *priv = palette->priv;
1984 if (adjustment && priv->hadjustment == adjustment)
1987 if (priv->hadjustment != NULL)
1989 g_signal_handlers_disconnect_by_func (priv->hadjustment,
1990 gtk_tool_palette_adjustment_value_changed,
1992 g_object_unref (priv->hadjustment);
1995 if (adjustment == NULL)
1996 adjustment = gtk_adjustment_new (0.0, 0.0, 0.0,
1999 g_signal_connect (adjustment, "value-changed",
2000 G_CALLBACK (gtk_tool_palette_adjustment_value_changed),
2002 priv->hadjustment = g_object_ref_sink (adjustment);
2003 /* FIXME: Adjustment should probably have it's values updated now */
2004 g_object_notify (G_OBJECT (palette), "hadjustment");
2008 * gtk_tool_palette_get_vadjustment:
2009 * @palette: a #GtkToolPalette
2011 * Gets the vertical adjustment of the tool palette.
2013 * Returns: (transfer none): the vertical adjustment of @palette
2017 * Deprecated: 3.0: Use gtk_scrollable_get_vadjustment()
2020 gtk_tool_palette_get_vadjustment (GtkToolPalette *palette)
2022 g_return_val_if_fail (GTK_IS_TOOL_PALETTE (palette), NULL);
2024 return palette->priv->vadjustment;
2028 gtk_tool_palette_set_vadjustment (GtkToolPalette *palette,
2029 GtkAdjustment *adjustment)
2031 GtkToolPalettePrivate *priv = palette->priv;
2033 if (adjustment && priv->vadjustment == adjustment)
2036 if (priv->vadjustment != NULL)
2038 g_signal_handlers_disconnect_by_func (priv->vadjustment,
2039 gtk_tool_palette_adjustment_value_changed,
2041 g_object_unref (priv->vadjustment);
2044 if (adjustment == NULL)
2045 adjustment = gtk_adjustment_new (0.0, 0.0, 0.0,
2048 g_signal_connect (adjustment, "value-changed",
2049 G_CALLBACK (gtk_tool_palette_adjustment_value_changed),
2051 priv->vadjustment = g_object_ref_sink (adjustment);
2052 /* FIXME: Adjustment should probably have it's values updated now */
2053 g_object_notify (G_OBJECT (palette), "vadjustment");
2057 _gtk_tool_palette_get_size_group (GtkToolPalette *palette)
2059 g_return_val_if_fail (GTK_IS_TOOL_PALETTE (palette), NULL);
2061 return palette->priv->text_size_group;