diff options
Diffstat (limited to 'lib/egg/eggtoolbar.c')
-rw-r--r-- | lib/egg/eggtoolbar.c | 2773 |
1 files changed, 0 insertions, 2773 deletions
diff --git a/lib/egg/eggtoolbar.c b/lib/egg/eggtoolbar.c deleted file mode 100644 index dcad2f9f6..000000000 --- a/lib/egg/eggtoolbar.c +++ /dev/null @@ -1,2773 +0,0 @@ -/* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * GtkToolbar copyright (C) Federico Mena - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* - * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -#undef GTK_DISABLE_DEPRECATED - -#include <gtk/gtkarrow.h> -#include "eggtoolbar.h" -#include "eggradiotoolbutton.h" -#include "eggseparatortoolitem.h" -#include <gtk/gtkmenu.h> -#include <gtk/gtkradiobutton.h> -#include <gtk/gtktoolbar.h> -#include <gtk/gtkbindings.h> -#include <gdk/gdkkeysyms.h> -#include "eggmarshalers.h" -#include <gtk/gtkmain.h> -#include <gtk/gtkstock.h> -#include <gtk/gtklabel.h> -#include <gtk/gtkprivate.h> -#include <string.h> - -#define DEFAULT_IPADDING 0 -#define DEFAULT_SPACE_SIZE 5 -#define DEFAULT_SPACE_STYLE GTK_TOOLBAR_SPACE_LINE - -#define DEFAULT_ICON_SIZE GTK_ICON_SIZE_LARGE_TOOLBAR -#define DEFAULT_TOOLBAR_STYLE GTK_TOOLBAR_BOTH - -#define SPACE_LINE_DIVISION 10 -#define SPACE_LINE_START 3 -#define SPACE_LINE_END 7 - -#ifndef _ -# define _(s) (s) -#endif - -enum { - PROP_0, - PROP_ORIENTATION, - PROP_TOOLBAR_STYLE, - PROP_SHOW_ARROW -}; - -enum { - CHILD_PROP_0, - CHILD_PROP_EXPAND, - CHILD_PROP_HOMOGENEOUS, - CHILD_PROP_PACK_END, -}; - -enum { - ORIENTATION_CHANGED, - STYLE_CHANGED, - POPUP_CONTEXT_MENU, - MOVE_FOCUS, - FOCUS_ENDS, - LAST_SIGNAL -}; - -static void egg_toolbar_init (EggToolbar *toolbar); -static void egg_toolbar_finalize (GObject *object); -static void egg_toolbar_class_init (EggToolbarClass *klass); - -static void egg_toolbar_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void egg_toolbar_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); - -static gint egg_toolbar_expose (GtkWidget *widget, - GdkEventExpose *event); -static void egg_toolbar_realize (GtkWidget *widget); -static void egg_toolbar_unrealize (GtkWidget *widget); -static void egg_toolbar_size_request (GtkWidget *widget, - GtkRequisition *requisition); -static void egg_toolbar_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); -static void egg_toolbar_style_set (GtkWidget *widget, - GtkStyle *prev_style); -static void egg_toolbar_direction_changed (GtkWidget *widget, - GtkTextDirection previous_direction); -static gboolean egg_toolbar_focus (GtkWidget *widget, - GtkDirectionType dir); -static void egg_toolbar_screen_changed (GtkWidget *widget, - GdkScreen *previous_screen); -static void egg_toolbar_map (GtkWidget *widget); -static void egg_toolbar_unmap (GtkWidget *widget); - -static void egg_toolbar_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time_); -static gboolean egg_toolbar_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time_); -static void egg_toolbar_set_child_property (GtkContainer *container, - GtkWidget *child, - guint property_id, - const GValue *value, - GParamSpec *pspec); -static void egg_toolbar_get_child_property (GtkContainer *container, - GtkWidget *child, - guint property_id, - GValue *value, - GParamSpec *pspec); - -static void egg_toolbar_add (GtkContainer *container, - GtkWidget *widget); -static void egg_toolbar_remove (GtkContainer *container, - GtkWidget *widget); -static void egg_toolbar_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data); -static GType egg_toolbar_child_type (GtkContainer *container); - -static void egg_toolbar_real_orientation_changed (EggToolbar *toolbar, - GtkOrientation orientation); -static void egg_toolbar_real_style_changed (EggToolbar *toolbar, - GtkToolbarStyle style); - -static gboolean egg_toolbar_move_focus (EggToolbar *toolbar, - GtkDirectionType dir); -static gboolean egg_toolbar_focus_ends (EggToolbar *toolbar, - gboolean home); - -static gboolean egg_toolbar_button_press (GtkWidget *toolbar, - GdkEventButton *event); -static gboolean egg_toolbar_arrow_button_press (GtkWidget *button, - GdkEventButton *event, - EggToolbar *toolbar); -static void egg_toolbar_arrow_button_clicked (GtkWidget *button, - EggToolbar *toolbar); -static void egg_toolbar_update_button_relief (EggToolbar *toolbar); -static GtkReliefStyle get_button_relief (EggToolbar *toolbar); -static gint get_space_size (EggToolbar *toolbar); -static EggToolbarSpaceStyle get_space_style (EggToolbar *toolbar); -static gint get_internal_padding (EggToolbar *toolbar); -static void egg_toolbar_remove_tool_item (EggToolbar *toolbar, - EggToolItem *item); - -static GtkWidget *egg_toolbar_internal_insert_element (EggToolbar *toolbar, - EggToolbarChildType type, - GtkWidget *widget, - const char *text, - const char *tooltip_text, - const char *tooltip_private_text, - GtkWidget *icon, - GtkSignalFunc callback, - gpointer user_data, - gint position, - gboolean use_stock); - - -#define PRIVATE_KEY "egg-toolbar-private" - -#define EGG_TOOLBAR_GET_PRIVATE(toolbar) (g_object_get_data (G_OBJECT (toolbar), PRIVATE_KEY)) - -typedef enum { - DONT_KNOW, - OLD_API, - NEW_API -} ApiMode; - -typedef struct -{ - GList *items; - - GtkWidget *arrow; - GtkWidget *arrow_button; - - gboolean show_arrow; - - gint drop_index; - GdkWindow *drag_highlight; - GtkMenu *menu; - - GdkWindow *event_window; - ApiMode api_mode; -} EggToolbarPrivate; - -static GtkContainerClass *parent_class = NULL; -static guint toolbar_signals [LAST_SIGNAL] = { 0 }; - -GType -egg_toolbar_get_type (void) -{ - static GtkType type = 0; - - if (!type) - { - static const GTypeInfo type_info = - { - sizeof (EggToolbarClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) egg_toolbar_class_init, - (GClassFinalizeFunc) NULL, - NULL, - sizeof (EggToolbar), - 0, /* n_preallocs */ - (GInstanceInitFunc) egg_toolbar_init, - }; - - type = g_type_register_static (GTK_TYPE_CONTAINER, - "EggToolbar", - &type_info, 0); - } - - return type; -} - -static void -add_arrow_bindings (GtkBindingSet *binding_set, - guint keysym, - GtkDirectionType dir) -{ - guint keypad_keysym = keysym - GDK_Left + GDK_KP_Left; - - gtk_binding_entry_add_signal (binding_set, keysym, 0, - "move_focus", 1, - GTK_TYPE_DIRECTION_TYPE, dir); - gtk_binding_entry_add_signal (binding_set, keypad_keysym, 0, - "move_focus", 1, - GTK_TYPE_DIRECTION_TYPE, dir); -} - -static void -add_ctrl_tab_bindings (GtkBindingSet *binding_set, - GdkModifierType modifiers, - GtkDirectionType direction) -{ - gtk_binding_entry_add_signal (binding_set, - GDK_Tab, GDK_CONTROL_MASK | modifiers, - "move_focus", 1, - GTK_TYPE_DIRECTION_TYPE, direction); - gtk_binding_entry_add_signal (binding_set, - GDK_KP_Tab, GDK_CONTROL_MASK | modifiers, - "move_focus", 1, - GTK_TYPE_DIRECTION_TYPE, direction); -} - -static void -egg_toolbar_class_init (EggToolbarClass *klass) -{ - GObjectClass *gobject_class; - GtkWidgetClass *widget_class; - GtkContainerClass *container_class; - GtkBindingSet *binding_set; - - parent_class = g_type_class_peek_parent (klass); - - gobject_class = (GObjectClass *)klass; - widget_class = (GtkWidgetClass *)klass; - container_class = (GtkContainerClass *)klass; - - gobject_class->set_property = egg_toolbar_set_property; - gobject_class->get_property = egg_toolbar_get_property; - gobject_class->finalize = egg_toolbar_finalize; - - widget_class->button_press_event = egg_toolbar_button_press; - widget_class->expose_event = egg_toolbar_expose; - widget_class->size_request = egg_toolbar_size_request; - widget_class->size_allocate = egg_toolbar_size_allocate; - widget_class->style_set = egg_toolbar_style_set; - widget_class->direction_changed = egg_toolbar_direction_changed; - widget_class->focus = egg_toolbar_focus; - widget_class->screen_changed = egg_toolbar_screen_changed; - widget_class->realize = egg_toolbar_realize; - widget_class->unrealize = egg_toolbar_unrealize; - widget_class->map = egg_toolbar_map; - widget_class->unmap = egg_toolbar_unmap; - - widget_class->drag_leave = egg_toolbar_drag_leave; - widget_class->drag_motion = egg_toolbar_drag_motion; - - container_class->add = egg_toolbar_add; - container_class->remove = egg_toolbar_remove; - container_class->forall = egg_toolbar_forall; - container_class->child_type = egg_toolbar_child_type; - container_class->get_child_property = egg_toolbar_get_child_property; - container_class->set_child_property = egg_toolbar_set_child_property; - - klass->orientation_changed = egg_toolbar_real_orientation_changed; - klass->style_changed = egg_toolbar_real_style_changed; - klass->move_focus = egg_toolbar_move_focus; - klass->focus_ends = egg_toolbar_focus_ends; - - toolbar_signals[ORIENTATION_CHANGED] = - g_signal_new ("orientation_changed", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EggToolbarClass, orientation_changed), - NULL, NULL, - g_cclosure_marshal_VOID__ENUM, - G_TYPE_NONE, 1, - GTK_TYPE_ORIENTATION); - toolbar_signals[STYLE_CHANGED] = - g_signal_new ("style_changed", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EggToolbarClass, style_changed), - NULL, NULL, - g_cclosure_marshal_VOID__ENUM, - G_TYPE_NONE, 1, - GTK_TYPE_TOOLBAR_STYLE); - toolbar_signals[POPUP_CONTEXT_MENU] = - g_signal_new ("popup_context_menu", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EggToolbarClass, popup_context_menu), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - toolbar_signals[MOVE_FOCUS] = - g_signal_new ("move_focus", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (EggToolbarClass, move_focus), - NULL, NULL, - _egg_marshal_BOOLEAN__ENUM, - G_TYPE_BOOLEAN, 1, - GTK_TYPE_DIRECTION_TYPE); - toolbar_signals[FOCUS_ENDS] = - g_signal_new ("focus_ends", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (EggToolbarClass, focus_ends), - NULL, NULL, - _egg_marshal_BOOLEAN__BOOLEAN, - G_TYPE_BOOLEAN, 1, - G_TYPE_BOOLEAN); - - /* properties */ - g_object_class_install_property (gobject_class, - PROP_ORIENTATION, - g_param_spec_enum ("orientation", - _("Orientation"), - _("The orientation of the toolbar"), - GTK_TYPE_ORIENTATION, - GTK_ORIENTATION_HORIZONTAL, - G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_class, - PROP_TOOLBAR_STYLE, - g_param_spec_enum ("toolbar_style", - _("Toolbar Style"), - _("How to draw the toolbar"), - GTK_TYPE_TOOLBAR_STYLE, - GTK_TOOLBAR_ICONS, - G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, - PROP_SHOW_ARROW, - g_param_spec_boolean ("show_arrow", - _("Show Arrow"), - _("If an arrow should be shown if the toolbar doesn't fit"), - FALSE, - G_PARAM_READWRITE)); - - /* child properties */ - gtk_container_class_install_child_property (container_class, - CHILD_PROP_EXPAND, - g_param_spec_boolean ("expand", - _("Expand"), - _("Whether the item should receive extra space when the toolbar grows"), - TRUE, - G_PARAM_READWRITE)); - - gtk_container_class_install_child_property (container_class, - CHILD_PROP_HOMOGENEOUS, - g_param_spec_boolean ("homogeneous", - _("Homogeneous"), - _("Whether the item should be the same size as other homogeneous items"), - TRUE, - G_PARAM_READWRITE)); - - gtk_container_class_install_child_property (container_class, - CHILD_PROP_PACK_END, - g_param_spec_uint ("pack_end", - _("Pack End"), - _("Whether the item is positioned at the end of the toolbar"), - 0, G_MAXINT, 0, - G_PARAM_READWRITE)); - - /* style properties */ - gtk_widget_class_install_style_property (widget_class, - g_param_spec_int ("space_size", - _("Spacer size"), - _("Size of spacers"), - 0, - G_MAXINT, - DEFAULT_SPACE_SIZE, - G_PARAM_READABLE)); - - gtk_widget_class_install_style_property (widget_class, - g_param_spec_int ("internal_padding", - _("Internal padding"), - _("Amount of border space between the toolbar shadow and the buttons"), - 0, - G_MAXINT, - DEFAULT_IPADDING, - G_PARAM_READABLE)); - - gtk_widget_class_install_style_property (widget_class, - g_param_spec_enum ("space_style", - _("Space style"), - _("Whether spacers are vertical lines or just blank"), - GTK_TYPE_TOOLBAR_SPACE_STYLE, - DEFAULT_SPACE_STYLE, - G_PARAM_READABLE)); - - gtk_widget_class_install_style_property (widget_class, - g_param_spec_enum ("button_relief", - _("Button relief"), - _("Type of bevel around toolbar buttons"), - GTK_TYPE_RELIEF_STYLE, - GTK_RELIEF_NONE, - G_PARAM_READABLE)); - gtk_widget_class_install_style_property (widget_class, - g_param_spec_enum ("shadow_type", - _("Shadow type"), - _("Style of bevel around the toolbar"), - GTK_TYPE_SHADOW_TYPE, - GTK_SHADOW_OUT, - G_PARAM_READABLE)); - - gtk_settings_install_property (g_param_spec_enum ("gtk-toolbar-style", - _("Toolbar style"), - _("Whether default toolbars have text only, text and icons, icons only, etc."), - GTK_TYPE_TOOLBAR_STYLE, - DEFAULT_TOOLBAR_STYLE, - G_PARAM_READWRITE)); - - gtk_settings_install_property (g_param_spec_enum ("gtk-toolbar-icon-size", - _("Toolbar icon size"), - _("Size of icons in default toolbars"), - GTK_TYPE_ICON_SIZE, - DEFAULT_ICON_SIZE, - G_PARAM_READWRITE)); - - binding_set = gtk_binding_set_by_class (klass); - - add_arrow_bindings (binding_set, GDK_Left, GTK_DIR_LEFT); - add_arrow_bindings (binding_set, GDK_Right, GTK_DIR_RIGHT); - add_arrow_bindings (binding_set, GDK_Up, GTK_DIR_UP); - add_arrow_bindings (binding_set, GDK_Down, GTK_DIR_DOWN); - - gtk_binding_entry_add_signal (binding_set, GDK_KP_Home, 0, - "focus_ends", 1, - G_TYPE_BOOLEAN, TRUE); - gtk_binding_entry_add_signal (binding_set, GDK_Home, 0, - "focus_ends", 1, - G_TYPE_BOOLEAN, TRUE); - gtk_binding_entry_add_signal (binding_set, GDK_KP_End, 0, - "focus_ends", 1, - G_TYPE_BOOLEAN, FALSE); - gtk_binding_entry_add_signal (binding_set, GDK_End, 0, - "focus_ends", 1, - G_TYPE_BOOLEAN, FALSE); - - add_ctrl_tab_bindings (binding_set, 0, GTK_DIR_RIGHT); - add_ctrl_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_LEFT); -} - -static void -egg_toolbar_finalize (GObject *object) -{ - EggToolbar *toolbar = EGG_TOOLBAR (object); - EggToolbarPrivate *priv; - - if (toolbar->tooltips) - g_object_unref (GTK_OBJECT (toolbar->tooltips)); - - priv = g_object_get_data (object, PRIVATE_KEY); - g_free (priv); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -egg_toolbar_init (EggToolbar *toolbar) -{ - EggToolbarPrivate *priv; - - GTK_WIDGET_UNSET_FLAGS (toolbar, GTK_CAN_FOCUS); - GTK_WIDGET_SET_FLAGS (toolbar, GTK_NO_WINDOW); - - priv = g_new0 (EggToolbarPrivate, 1); - g_object_set_data (G_OBJECT (toolbar), PRIVATE_KEY, priv); - - toolbar->orientation = GTK_ORIENTATION_HORIZONTAL; - toolbar->style = DEFAULT_TOOLBAR_STYLE; - toolbar->icon_size = DEFAULT_ICON_SIZE; - toolbar->tooltips = gtk_tooltips_new (); - g_object_ref (toolbar->tooltips); - gtk_object_sink (GTK_OBJECT (toolbar->tooltips)); - - priv->arrow_button = gtk_toggle_button_new (); - g_signal_connect (priv->arrow_button, "button_press_event", - G_CALLBACK (egg_toolbar_arrow_button_press), toolbar); - g_signal_connect (priv->arrow_button, "clicked", - G_CALLBACK (egg_toolbar_arrow_button_clicked), toolbar); - gtk_button_set_relief (GTK_BUTTON (priv->arrow_button), - get_button_relief (toolbar)); - - priv->api_mode = DONT_KNOW; - -#if 0 - /* FIXME: enable this when we can depend on gtk+ 2.3.0 */ - gtk_button_set_focus_on_click (GTK_BUTTON (priv->arrow_button), FALSE); -#endif - - priv->arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE); - gtk_widget_show (priv->arrow); - gtk_container_add (GTK_CONTAINER (priv->arrow_button), priv->arrow); - - gtk_widget_set_parent (priv->arrow_button, GTK_WIDGET (toolbar)); - - /* which child position a drop will occur at */ - priv->drop_index = -1; - priv->drag_highlight = NULL; - - priv->menu = NULL; -} - -static gboolean -toolbar_item_visible (EggToolbar *toolbar, - EggToolItem *item) -{ - if (GTK_WIDGET_VISIBLE (item) && - ((toolbar->orientation == GTK_ORIENTATION_HORIZONTAL && item->visible_horizontal) || - (toolbar->orientation == GTK_ORIENTATION_VERTICAL && item->visible_vertical))) - { - EggToolbarPrivate *priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - - /* With the old toolbar you could hide a button by calling gtk_widget_hide() - * on it. This doesn't work with the new API because the EggToolItem will not be - * hidden. - */ - if (priv->api_mode == OLD_API) - { - GtkWidget *bin_child = GTK_BIN (item)->child; - - if (bin_child && !GTK_WIDGET_VISIBLE (bin_child)) - return FALSE; - } - - return TRUE; - } - - return FALSE; -} - -static gboolean -toolbar_item_is_homogeneous (EggToolbar *toolbar, - EggToolItem *item) -{ - gboolean result = FALSE; - - if (item->homogeneous && !EGG_IS_SEPARATOR_TOOL_ITEM (item)) - result = TRUE; - - if (item->is_important && - toolbar->style == GTK_TOOLBAR_BOTH_HORIZ && - toolbar->orientation == GTK_ORIENTATION_HORIZONTAL) - { - result = FALSE; - } - - return result; -} - -static void -egg_toolbar_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - EggToolbar *toolbar = EGG_TOOLBAR (object); - - switch (prop_id) - { - case PROP_ORIENTATION: - egg_toolbar_set_orientation (toolbar, g_value_get_enum (value)); - break; - case PROP_TOOLBAR_STYLE: - egg_toolbar_set_style (toolbar, g_value_get_enum (value)); - break; - case PROP_SHOW_ARROW: - egg_toolbar_set_show_arrow (toolbar, g_value_get_boolean (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -egg_toolbar_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - EggToolbar *toolbar = EGG_TOOLBAR (object); - EggToolbarPrivate *priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - - switch (prop_id) - { - case PROP_ORIENTATION: - g_value_set_enum (value, toolbar->orientation); - break; - case PROP_TOOLBAR_STYLE: - g_value_set_enum (value, toolbar->style); - break; - case PROP_SHOW_ARROW: - g_value_set_boolean (value, priv->show_arrow); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -egg_toolbar_map (GtkWidget *widget) -{ - EggToolbarPrivate *priv = EGG_TOOLBAR_GET_PRIVATE (widget); - - GTK_WIDGET_CLASS (parent_class)->map (widget); - - if (priv->event_window) - gdk_window_show_unraised (priv->event_window); -} - -static void -egg_toolbar_unmap (GtkWidget *widget) -{ - EggToolbarPrivate *priv = EGG_TOOLBAR_GET_PRIVATE (widget); - - if (priv->event_window) - gdk_window_hide (priv->event_window); - - GTK_WIDGET_CLASS (parent_class)->unmap (widget); -} - -static void -egg_toolbar_paint_space_line (GtkWidget *widget, - GdkRectangle *area, - EggToolItem *item) -{ - EggToolbar *toolbar; - GtkAllocation *allocation; - gint space_size; - - g_return_if_fail (GTK_BIN (item)->child == NULL); - - toolbar = EGG_TOOLBAR (widget); - - allocation = >K_WIDGET (item)->allocation; - space_size = get_space_size (toolbar); - - if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL) - gtk_paint_vline (widget->style, widget->window, - GTK_WIDGET_STATE (widget), area, widget, - "toolbar", - allocation->y + allocation->height * - SPACE_LINE_START / SPACE_LINE_DIVISION, - allocation->y + allocation->height * - SPACE_LINE_END / SPACE_LINE_DIVISION, - allocation->x + (space_size-widget->style->xthickness)/2); - else if (toolbar->orientation == GTK_ORIENTATION_VERTICAL) - gtk_paint_hline (widget->style, widget->window, - GTK_WIDGET_STATE (widget), area, widget, - "toolbar", - allocation->x + allocation->width * - SPACE_LINE_START / SPACE_LINE_DIVISION, - allocation->x + allocation->width * - SPACE_LINE_END / SPACE_LINE_DIVISION, - allocation->y + (space_size-widget->style->ythickness)/2); -} - -static void -egg_toolbar_realize (GtkWidget *widget) -{ - EggToolbar *toolbar = EGG_TOOLBAR (widget); - EggToolbarPrivate *priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - - GdkWindowAttr attributes; - gint attributes_mask; - gint border_width; - - GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); - - border_width = GTK_CONTAINER (widget)->border_width; - - attributes.wclass = GDK_INPUT_ONLY; - attributes.window_type = GDK_WINDOW_CHILD; - attributes.x = widget->allocation.x + border_width; - attributes.y = widget->allocation.y + border_width; - attributes.width = widget->allocation.width - border_width * 2; - attributes.height = widget->allocation.height - border_width * 2; - attributes.event_mask = gtk_widget_get_events (widget); - /* FIXME: does GDK_EXPOSURE_MASK make sense for an input-only window? - * If it doesn't, then it should be removed here and in gtkbutton.c, - * gtkmenuitem.c, and maybe other places - */ - attributes.event_mask |= (GDK_EXPOSURE_MASK | - GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK | - GDK_ENTER_NOTIFY_MASK | - GDK_LEAVE_NOTIFY_MASK); - - attributes_mask = GDK_WA_X | GDK_WA_Y; - - widget->window = gtk_widget_get_parent_window (widget); - g_object_ref (widget->window); - - priv->event_window = gdk_window_new (gtk_widget_get_parent_window (widget), - &attributes, attributes_mask); - gdk_window_set_user_data (priv->event_window, toolbar); -} - -static void -egg_toolbar_unrealize (GtkWidget *widget) -{ - EggToolbarPrivate *priv = EGG_TOOLBAR_GET_PRIVATE (widget); - - if (priv->drag_highlight) - { - gdk_window_set_user_data (priv->drag_highlight, NULL); - gdk_window_destroy (priv->drag_highlight); - priv->drag_highlight = NULL; - } - - if (priv->event_window) - { - gdk_window_set_user_data (priv->event_window, NULL); - gdk_window_destroy (priv->event_window); - priv->event_window = NULL; - } - - if (GTK_WIDGET_CLASS (parent_class)->unrealize) - (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget); -} - -static gint -egg_toolbar_expose (GtkWidget *widget, - GdkEventExpose *event) -{ - EggToolbar *toolbar = EGG_TOOLBAR (widget); - EggToolbarPrivate *priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - - GList *items; - gint border_width; - - border_width = GTK_CONTAINER (widget)->border_width; - - if (GTK_WIDGET_DRAWABLE (widget)) - { - GtkShadowType shadow_type; - - gtk_widget_style_get (widget, "shadow_type", &shadow_type, NULL); - - gtk_paint_box (widget->style, - widget->window, - GTK_WIDGET_STATE (widget), - shadow_type, - &event->area, widget, "toolbar", - border_width + widget->allocation.x, - border_width + widget->allocation.y, - widget->allocation.width - 2 * border_width, - widget->allocation.height - 2 * border_width); - } - - items = priv->items; - while (items) - { - EggToolItem *item = EGG_TOOL_ITEM (items->data); - - if (GTK_BIN (item)->child) - gtk_container_propagate_expose (GTK_CONTAINER (widget), - GTK_WIDGET (item), - event); - else if (GTK_WIDGET_MAPPED (item) && get_space_style (toolbar) == GTK_TOOLBAR_SPACE_LINE) - egg_toolbar_paint_space_line (widget, &event->area, item); - - items = items->next; - } - - gtk_container_propagate_expose (GTK_CONTAINER (widget), - priv->arrow_button, - event); - - return FALSE; -} - -static void -egg_toolbar_size_request (GtkWidget *widget, - GtkRequisition *requisition) -{ - EggToolbar *toolbar = EGG_TOOLBAR (widget); - EggToolbarPrivate *priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - gint space_size = get_space_size (toolbar); - GList *list; - gint max_child_height; - gint max_child_width; - gint max_homogeneous_child_width; - gint max_homogeneous_child_height; - gint homogeneous_size; - gint long_req; - gint pack_end_size; - gint pack_front_size; - gint ipadding; - GtkRequisition arrow_requisition; - - max_homogeneous_child_width = 0; - max_homogeneous_child_height = 0; - max_child_width = 0; - max_child_height = 0; - for (list = priv->items; list != NULL; list = list->next) - { - GtkRequisition requisition; - EggToolItem *item = list->data; - - if (!toolbar_item_visible (toolbar, item)) - continue; - - gtk_widget_size_request (GTK_WIDGET (item), &requisition); - - max_child_width = MAX (max_child_width, requisition.width); - max_child_height = MAX (max_child_height, requisition.height); - - if (toolbar_item_is_homogeneous (toolbar, item) && GTK_BIN (item)->child) - { - max_homogeneous_child_width = MAX (max_homogeneous_child_width, requisition.width); - max_homogeneous_child_height = MAX (max_homogeneous_child_height, requisition.height); - } - } - - if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL) - homogeneous_size = max_homogeneous_child_width; - else - homogeneous_size = max_homogeneous_child_height; - - pack_end_size = 0; - pack_front_size = 0; - for (list = priv->items; list != NULL; list = list->next) - { - EggToolItem *item = list->data; - guint size; - - if (!toolbar_item_visible (toolbar, item)) - continue; - - if (!GTK_BIN (item)->child) - { - size = space_size; - } - else if (item->homogeneous) - { - size = homogeneous_size; - } - else - { - GtkRequisition requisition; - - gtk_widget_size_request (GTK_WIDGET (item), &requisition); - - if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL) - size = requisition.width; - else - size = requisition.height; - } - - if (item->pack_end) - pack_end_size += size; - else - pack_front_size += size; - } - - if (priv->show_arrow) - { - gtk_widget_size_request (priv->arrow_button, &arrow_requisition); - - if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL) - long_req = arrow_requisition.width; - else - long_req = arrow_requisition.height; - - /* There is no point requesting space for the arrow if that would take - * up more space than all the items combined - */ - long_req = MIN (long_req, pack_front_size + pack_end_size); - } - else - { - arrow_requisition.height = 0; - arrow_requisition.width = 0; - - long_req = pack_end_size + pack_front_size; - } - - if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL) - { - requisition->width = long_req; - requisition->height = MAX (max_child_height, arrow_requisition.height); - } - else - { - requisition->height = long_req; - requisition->width = MAX (max_child_width, arrow_requisition.width); - } - - /* Extra spacing */ - ipadding = get_internal_padding (toolbar); - - requisition->width += 2 * (ipadding + GTK_CONTAINER (toolbar)->border_width); - requisition->height += 2 * (ipadding + GTK_CONTAINER (toolbar)->border_width); - - toolbar->button_maxw = max_homogeneous_child_width; - toolbar->button_maxh = max_homogeneous_child_height; -} - -static void -fixup_allocation_for_rtl (gint total_size, - GtkAllocation *allocation) -{ - allocation->x += (total_size - (2 * allocation->x + allocation->width)); -} - -static void -fixup_allocation_for_vertical (GtkAllocation *allocation) -{ - gint tmp; - - tmp = allocation->x; - allocation->x = allocation->y; - allocation->y = tmp; - - tmp = allocation->width; - allocation->width = allocation->height; - allocation->height = tmp; -} - -static gint -get_item_size (EggToolbar *toolbar, - GtkWidget *child) -{ - GtkRequisition requisition; - EggToolItem *item = EGG_TOOL_ITEM (child); - - if (!GTK_BIN (item)->child) - return get_space_size (toolbar); - - gtk_widget_get_child_requisition (child, &requisition); - - if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL) - { - if (toolbar_item_is_homogeneous (toolbar, item)) - return toolbar->button_maxw; - else - return requisition.width; - } - else - { - if (toolbar_item_is_homogeneous (toolbar, item)) - return toolbar->button_maxh; - else - return requisition.height; - } -} - -static void -egg_toolbar_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) -{ - EggToolbar *toolbar = EGG_TOOLBAR (widget); - EggToolbarPrivate *priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - gint space_size; - GtkAllocation *allocations; - GtkAllocation arrow_allocation; - gint arrow_size; - gint size, pos, short_size; - GList *list; - gint i; - gboolean need_arrow; - gint n_expand_items; - gint border_width; - gint available_size; - gint n_items; - gint needed_size; - GList *items; - GtkRequisition arrow_requisition; - - widget->allocation = *allocation; - - space_size = get_space_size (toolbar); - - border_width = GTK_CONTAINER (toolbar)->border_width; - - if (GTK_WIDGET_REALIZED (widget)) - { - gdk_window_move_resize (priv->event_window, - allocation->x + border_width, - allocation->y + border_width, - allocation->width - border_width * 2, - allocation->height - border_width * 2); - } - - border_width += get_internal_padding (toolbar); - - gtk_widget_get_child_requisition (GTK_WIDGET (priv->arrow_button), - &arrow_requisition); - - if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL) - { - available_size = size = allocation->width - 2 * border_width; - short_size = allocation->height - 2 * border_width; - arrow_size = arrow_requisition.width; - } - else - { - available_size = size = allocation->height - 2 * border_width; - short_size = allocation->width - 2 * border_width; - arrow_size = arrow_requisition.height; - } - - n_items = g_list_length (priv->items); - allocations = g_new0 (GtkAllocation, n_items); - - needed_size = 0; - for (list = priv->items; list != NULL; list = list->next) - { - EggToolItem *item = list->data; - - if (toolbar_item_visible (toolbar, item)) - needed_size += get_item_size (toolbar, GTK_WIDGET (item)); - } - - need_arrow = (needed_size > available_size) && priv->show_arrow; - - if (need_arrow) - size = available_size - arrow_size; - else - size = available_size; - - items = g_list_copy (priv->items); - - /* calculate widths of pack end items */ - for (list = g_list_last (items), i = 0; list != NULL; list = list->prev, ++i) - { - EggToolItem *item = list->data; - GtkAllocation *allocation = &(allocations[n_items - i - 1]); - gint item_size; - - if (!item->pack_end || !toolbar_item_visible (toolbar, item)) - continue; - - item_size = get_item_size (toolbar, GTK_WIDGET (item)); - if (item_size <= size) - { - size -= item_size; - allocation->width = item_size; - item->overflow_item = FALSE; - } - else - { - while (list) - { - item = list->data; - if (item->pack_end) - item->overflow_item = TRUE; - - list = list->prev; - } - break; - } - } - - /* calculate widths of pack front items */ - for (list = items, i = 0; list != NULL; list = list->next, ++i) - { - EggToolItem *item = list->data; - gint item_size; - - if (item->pack_end || !toolbar_item_visible (toolbar, item)) - continue; - - item_size = get_item_size (toolbar, GTK_WIDGET (item)); - if (item_size <= size) - { - size -= item_size; - allocations[i].width = item_size; - item->overflow_item = FALSE; - } - else - { - while (list) - { - item = list->data; - if (!item->pack_end) - item->overflow_item = TRUE; - list = list->next; - } - break; - } - } - - if (need_arrow) - { - arrow_allocation.width = arrow_size; - arrow_allocation.height = short_size; - } - - /* expand expandable items */ - n_expand_items = 0; - for (list = priv->items; list != NULL; list = list->next) - { - EggToolItem *item = list->data; - - if (toolbar_item_visible (toolbar, item) && item->expand && - !item->overflow_item && GTK_BIN (item)->child) - { - n_expand_items++; - } - } - - for (list = items, i = 0; list != NULL; list = list->next, ++i) - { - EggToolItem *item = list->data; - - if (toolbar_item_visible (toolbar, item) && item->expand && - !item->overflow_item && GTK_BIN (item)->child) - { - gint extra = size / n_expand_items; - if (size % n_expand_items != 0) - extra++; - - allocations[i].width += extra; - size -= extra; - n_expand_items--; - } - } - - g_assert (n_expand_items == 0); - - /* position pack front items */ - pos = border_width; - for (list = items, i = 0; list != NULL; list = list->next, ++i) - { - EggToolItem *item = list->data; - - if (toolbar_item_visible (toolbar, item) && !item->overflow_item && !item->pack_end) - { - allocations[i].x = pos; - allocations[i].y = border_width; - allocations[i].height = short_size; - - pos += allocations[i].width; - } - } - - /* position pack end items */ - pos = available_size + border_width; - for (list = g_list_last (items), i = 0; list != NULL; list = list->prev, ++i) - { - EggToolItem *item = list->data; - - if (toolbar_item_visible (toolbar, item) && !item->overflow_item && item->pack_end) - { - GtkAllocation *allocation = &(allocations[n_items - i - 1]); - - allocation->x = pos - allocation->width; - allocation->y = border_width; - allocation->height = short_size; - - pos -= allocation->width; - } - } - - /* position arrow */ - if (need_arrow) - { - arrow_allocation.x = pos - arrow_allocation.width; - arrow_allocation.y = border_width; - } - - /* fix up allocations in the vertical or RTL cases */ - if (toolbar->orientation == GTK_ORIENTATION_VERTICAL) - { - for (i = 0; i < n_items; ++i) - fixup_allocation_for_vertical (&(allocations[i])); - - if (need_arrow) - fixup_allocation_for_vertical (&arrow_allocation); - } - else if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL) - { - for (i = 0; i < n_items; ++i) - fixup_allocation_for_rtl (available_size, &(allocations[i])); - - if (need_arrow) - fixup_allocation_for_rtl (available_size, &arrow_allocation); - } - - /* translate the items by allocation->(x,y) */ - for (i = 0; i < n_items; ++i) - { - allocations[i].x += allocation->x; - allocations[i].y += allocation->y; - } - - if (need_arrow) - { - arrow_allocation.x += allocation->x; - arrow_allocation.y += allocation->y; - } - - /* finally allocate the items */ - for (list = items, i = 0; list != NULL; list = list->next, i++) - { - EggToolItem *item = list->data; - - if (toolbar_item_visible (toolbar, item) && !item->overflow_item) - { - gtk_widget_size_allocate (GTK_WIDGET (item), &(allocations[i])); - gtk_widget_set_child_visible (GTK_WIDGET (item), TRUE); - } - else - { - gtk_widget_set_child_visible (GTK_WIDGET (item), FALSE); - } - } - - if (need_arrow) - { - gtk_widget_size_allocate (GTK_WIDGET (priv->arrow_button), - &arrow_allocation); - gtk_widget_show (GTK_WIDGET (priv->arrow_button)); - } - else - { - gtk_widget_hide (GTK_WIDGET (priv->arrow_button)); - } - - g_free (allocations); - g_list_free (items); -} - -static void -egg_toolbar_style_set (GtkWidget *widget, - GtkStyle *prev_style) -{ - if (GTK_WIDGET_REALIZED (widget)) - gtk_style_set_background (widget->style, widget->window, widget->state); - - if (prev_style) - egg_toolbar_update_button_relief (EGG_TOOLBAR (widget)); -} - -static void -egg_toolbar_direction_changed (GtkWidget *widget, - GtkTextDirection previous_dir) -{ - EggToolbar *toolbar = EGG_TOOLBAR (widget); - EggToolbarPrivate *priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - - if (toolbar->orientation == GTK_ORIENTATION_VERTICAL) - { - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) - gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_RIGHT, GTK_SHADOW_NONE); - else - gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_LEFT, GTK_SHADOW_NONE); - } - - GTK_WIDGET_CLASS (parent_class)->direction_changed (widget, previous_dir); -} - -static GList * -egg_toolbar_list_children_in_focus_order (EggToolbar *toolbar, - GtkDirectionType dir) -{ - EggToolbarPrivate *priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - GList *result = NULL; - GList *list; - - for (list = priv->items; list != NULL; list = list->next) - { - EggToolItem *item = list->data; - if (!item->pack_end) - result = g_list_prepend (result, item); - } - - for (list = priv->items; list != NULL; list = list->next) - { - EggToolItem *item = list->data; - - if (item->pack_end) - result = g_list_prepend (result, item); - } - - result = g_list_prepend (result, priv->arrow_button); - - if (dir == GTK_DIR_RIGHT || dir == GTK_DIR_DOWN || dir == GTK_DIR_TAB_FORWARD) - result = g_list_reverse (result); - - if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL) - result = g_list_reverse (result); - - return result; -} - -static gboolean -egg_toolbar_focus_ends (EggToolbar *toolbar, - gboolean home) -{ - GList *children, *list; - GtkDirectionType dir = home? GTK_DIR_RIGHT : GTK_DIR_LEFT; - - children = egg_toolbar_list_children_in_focus_order (toolbar, dir); - - if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL) - { - children = g_list_reverse (children); - if (dir == GTK_DIR_RIGHT) - dir = GTK_DIR_LEFT; - else - dir = GTK_DIR_RIGHT; - } - - for (list = children; list != NULL; list = list->next) - { - GtkWidget *child = list->data; - - if (GTK_CONTAINER (toolbar)->focus_child == child) - break; - - if (GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir)) - break; - } - - g_list_free (children); - - return TRUE; -} - -static gboolean -egg_toolbar_move_focus (EggToolbar *toolbar, - GtkDirectionType dir) -{ - GList *list; - gboolean try_focus = FALSE; - GList *children = egg_toolbar_list_children_in_focus_order (toolbar, dir); - - for (list = children; list != NULL; list = list->next) - { - GtkWidget *child = list->data; - - if (try_focus && GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir)) - break; - - if (child == GTK_CONTAINER (toolbar)->focus_child) - try_focus = TRUE; - } - - g_list_free (children); - - return TRUE; -} - -/* The focus handler for the toolbar. It called when the user presses TAB or otherwise - * tries to focus the toolbar. - */ -static gboolean -egg_toolbar_focus (GtkWidget *widget, - GtkDirectionType dir) -{ - EggToolbar *toolbar = EGG_TOOLBAR (widget); - GList *children, *list; - - /* if focus is already somewhere inside the toolbar then return FALSE. - * The only way focus can stay inside the toolbar is when the user presses - * arrow keys or Ctrl TAB (both of which are handled by the - * egg_toolbar_move_focus() keybinding function. - */ - if (GTK_CONTAINER (widget)->focus_child) - return FALSE; - - children = egg_toolbar_list_children_in_focus_order (toolbar, dir); - - for (list = children; list != NULL; list = list->next) - { - GtkWidget *child = list->data; - - if (GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir)) - return TRUE; - } - - g_list_free (children); - - return FALSE; -} - -static void -style_change_notify (EggToolbar *toolbar) -{ - if (!toolbar->style_set) - { - /* pretend it was set, then unset, thus reverting to new default */ - toolbar->style_set = TRUE; - egg_toolbar_unset_style (toolbar); - } -} - -static void -icon_size_change_notify (EggToolbar *toolbar) -{ - if (!toolbar->icon_size_set) - { - /* pretend it was set, then unset, thus reverting to new default */ - toolbar->icon_size_set = TRUE; - egg_toolbar_unset_icon_size (toolbar); - } -} - -static GtkSettings * -toolbar_get_settings (EggToolbar *toolbar) -{ - return g_object_get_data (G_OBJECT (toolbar), "egg-toolbar-settings"); -} - -static void -egg_toolbar_screen_changed (GtkWidget *widget, - GdkScreen *previous_screen) -{ - EggToolbar *toolbar = EGG_TOOLBAR (widget); - GtkSettings *old_settings = toolbar_get_settings (toolbar); - GtkSettings *settings; - - if (gtk_widget_has_screen (GTK_WIDGET (toolbar))) - settings = gtk_widget_get_settings (GTK_WIDGET (toolbar)); - else - settings = NULL; - - if (settings == old_settings) - return; - - if (old_settings) - { - g_signal_handler_disconnect (old_settings, toolbar->style_set_connection); - g_signal_handler_disconnect (old_settings, toolbar->icon_size_connection); - - g_object_unref (old_settings); - } - - if (settings) - { - toolbar->style_set_connection = - g_signal_connect_swapped (settings, - "notify::gtk-toolbar-style", - G_CALLBACK (style_change_notify), - toolbar); - toolbar->icon_size_connection = - g_signal_connect_swapped (settings, - "notify::gtk-toolbar-icon-size", - G_CALLBACK (icon_size_change_notify), - toolbar); - - g_object_ref (settings); - g_object_set_data (G_OBJECT (toolbar), "egg-toolbar-settings", settings); - } - else - g_object_set_data (G_OBJECT (toolbar), "egg-toolbar-settings", NULL); - - style_change_notify (toolbar); - icon_size_change_notify (toolbar); -} - -static void -find_drop_pos (EggToolbar *toolbar, - gint x, - gint y, - gint *drop_index, - gint *drop_pos) -{ - EggToolbarPrivate *priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - GtkOrientation orientation; - GtkTextDirection direction; - GList *items; - EggToolItem *item; - gint border_width; - gint best_distance, best_pos, best_index, index; - - orientation = toolbar->orientation; - direction = gtk_widget_get_direction (GTK_WIDGET (toolbar)); - border_width = GTK_CONTAINER (toolbar)->border_width + get_internal_padding (toolbar); - - items = priv->items; - if (!items) - { - *drop_index = 0; - if (orientation == GTK_ORIENTATION_HORIZONTAL) - { - if (direction == GTK_TEXT_DIR_LTR) - *drop_pos = border_width; - else - *drop_pos = GTK_WIDGET (toolbar)->allocation.width - border_width; - } - else - { - *drop_pos = border_width; - } - return; - } - - /* initial conditions */ - item = EGG_TOOL_ITEM (items->data); - best_index = 0; - if (orientation == GTK_ORIENTATION_HORIZONTAL) - { - if (direction == GTK_TEXT_DIR_LTR) - best_pos = GTK_WIDGET (item)->allocation.x; - else - best_pos = GTK_WIDGET (item)->allocation.x + - GTK_WIDGET (item)->allocation.width; - best_distance = ABS (best_pos - x); - } - else - { - best_pos = GTK_WIDGET (item)->allocation.y; - best_distance = ABS (best_pos - y); - } - - index = 0; - while (items) - { - item = EGG_TOOL_ITEM (items->data); - index++; - if (GTK_WIDGET_DRAWABLE (item) && !item->pack_end) - { - gint pos, distance; - - if (orientation == GTK_ORIENTATION_HORIZONTAL) - { - if (direction == GTK_TEXT_DIR_LTR) - pos = GTK_WIDGET (item)->allocation.x + - GTK_WIDGET (item)->allocation.width; - else - pos = GTK_WIDGET (item)->allocation.x; - distance = ABS (pos - x); - } - else - { - pos = GTK_WIDGET (item)->allocation.y + - GTK_WIDGET (item)->allocation.height; - distance = ABS (pos - y); - } - if (distance < best_distance) - { - best_index = index; - best_pos = pos; - best_distance = distance; - } - } - items = items->next; - } - *drop_index = best_index; - *drop_pos = best_pos; -} - -static void -egg_toolbar_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time_) -{ - EggToolbar *toolbar = EGG_TOOLBAR (widget); - EggToolbarPrivate *priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - - if (priv->drag_highlight) - { - gdk_window_set_user_data (priv->drag_highlight, NULL); - gdk_window_destroy (priv->drag_highlight); - priv->drag_highlight = NULL; - } - - priv->drop_index = -1; -} - -static gboolean -egg_toolbar_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time_) -{ - EggToolbar *toolbar = EGG_TOOLBAR (widget); - EggToolbarPrivate *priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - gint new_index, new_pos; - - find_drop_pos(toolbar, x, y, &new_index, &new_pos); - - if (!priv->drag_highlight) - { - GdkWindowAttr attributes; - guint attributes_mask; - - attributes.window_type = GDK_WINDOW_CHILD; - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.visual = gtk_widget_get_visual (widget); - attributes.colormap = gtk_widget_get_colormap (widget); - attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK | GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK; - attributes.width = 1; - attributes.height = 1; - attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP; - priv->drag_highlight = gdk_window_new (widget->window, - &attributes, attributes_mask); - gdk_window_set_user_data (priv->drag_highlight, widget); - gdk_window_set_background (priv->drag_highlight, - &widget->style->fg[widget->state]); - } - - if (priv->drop_index < 0 || - priv->drop_index != new_index) - { - gint border_width = GTK_CONTAINER (toolbar)->border_width; - priv->drop_index = new_index; - if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL) - { - gdk_window_move_resize (priv->drag_highlight, - widget->allocation.x + new_pos - 1, - widget->allocation.y + border_width, - 2, widget->allocation.height-border_width*2); - } - else - { - gdk_window_move_resize (priv->drag_highlight, - widget->allocation.x + border_width, - widget->allocation.y + new_pos - 1, - widget->allocation.width-border_width*2, 2); - } - } - - gdk_window_show (priv->drag_highlight); - - gdk_drag_status (context, context->suggested_action, time_); - - return TRUE; -} - -static void -egg_toolbar_get_child_property (GtkContainer *container, - GtkWidget *child, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - EggToolItem *item = EGG_TOOL_ITEM (child); - - switch (property_id) - { - case CHILD_PROP_PACK_END: - g_value_set_boolean (value, item->pack_end); - break; - - case CHILD_PROP_HOMOGENEOUS: - g_value_set_boolean (value, item->homogeneous); - break; - - case CHILD_PROP_EXPAND: - g_value_set_boolean (value, item->expand); - break; - - default: - GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec); - break; - } -} - -static void -egg_toolbar_set_child_property (GtkContainer *container, - GtkWidget *child, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) - { - case CHILD_PROP_PACK_END: - egg_tool_item_set_pack_end (EGG_TOOL_ITEM (child), g_value_get_boolean (value)); - break; - - case CHILD_PROP_HOMOGENEOUS: - egg_tool_item_set_homogeneous (EGG_TOOL_ITEM (child), g_value_get_boolean (value)); - break; - - case CHILD_PROP_EXPAND: - egg_tool_item_set_homogeneous (EGG_TOOL_ITEM (child), g_value_get_boolean (value)); - break; - - default: - GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec); - break; - } -} - -static void -egg_toolbar_add (GtkContainer *container, - GtkWidget *widget) -{ - EggToolbar *toolbar; - - g_return_if_fail (EGG_IS_TOOLBAR (container)); - g_return_if_fail (widget != NULL); - - toolbar = EGG_TOOLBAR (container); - - if (EGG_IS_TOOL_ITEM (widget)) - egg_toolbar_insert (toolbar, EGG_TOOL_ITEM (widget), 0); - else - egg_toolbar_append_widget (toolbar, widget, NULL, NULL); -} - -static void -egg_toolbar_remove (GtkContainer *container, - GtkWidget *widget) -{ - EggToolbar *toolbar; - EggToolItem *item = NULL; - - g_return_if_fail (EGG_IS_TOOLBAR (container)); - - toolbar = EGG_TOOLBAR (container); - - if (EGG_IS_TOOL_ITEM (widget)) - { - item = EGG_TOOL_ITEM (widget); - } - else - { - EggToolbarPrivate *priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - GList *list; - - for (list = priv->items; list != NULL; list = list->next) - { - if (GTK_BIN (list->data)->child == widget) - { - item = list->data; - break; - } - } - } - - g_return_if_fail (item != NULL); - - egg_toolbar_remove_tool_item (EGG_TOOLBAR (container), item); -} - -static void -egg_toolbar_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data) -{ - EggToolbar *toolbar = EGG_TOOLBAR (container); - EggToolbarPrivate *priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - GList *items; - - g_return_if_fail (callback != NULL); - - items = priv->items; - - while (items) - { - EggToolItem *item = EGG_TOOL_ITEM (items->data); - - items = items->next; - - (*callback) (GTK_WIDGET (item), callback_data); - } - - if (include_internals) - (* callback) (priv->arrow_button, callback_data); -} - -static GType -egg_toolbar_child_type (GtkContainer *container) -{ - return EGG_TYPE_TOOL_ITEM; -} - -static void -egg_toolbar_reconfigured (EggToolbar *toolbar) -{ - EggToolbarPrivate *priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - GList *items; - - items = priv->items; - while (items) - { - EggToolItem *item = EGG_TOOL_ITEM (items->data); - - egg_tool_item_toolbar_reconfigured (item); - - items = items->next; - } -} - -static void -egg_toolbar_real_orientation_changed (EggToolbar *toolbar, - GtkOrientation orientation) -{ - EggToolbarPrivate *priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - if (toolbar->orientation != orientation) - { - toolbar->orientation = orientation; - - if (orientation == GTK_ORIENTATION_HORIZONTAL) - gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_DOWN, GTK_SHADOW_NONE); - else if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR) - gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_RIGHT, GTK_SHADOW_NONE); - else - gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_LEFT, GTK_SHADOW_NONE); - - egg_toolbar_reconfigured (toolbar); - - gtk_widget_queue_resize (GTK_WIDGET (toolbar)); - g_object_notify (G_OBJECT (toolbar), "orientation"); - } -} - -static void -egg_toolbar_real_style_changed (EggToolbar *toolbar, - GtkToolbarStyle style) -{ - if (toolbar->style != style) - { - toolbar->style = style; - - egg_toolbar_reconfigured (toolbar); - - gtk_widget_queue_resize (GTK_WIDGET (toolbar)); - g_object_notify (G_OBJECT (toolbar), "toolbar_style"); - } -} - -static void -menu_position_func (GtkMenu *menu, - gint *x, - gint *y, - gboolean *push_in, - gpointer user_data) -{ - EggToolbar *toolbar = EGG_TOOLBAR (user_data); - EggToolbarPrivate *priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - GtkRequisition req; - GtkRequisition menu_req; - - gdk_window_get_origin (GTK_BUTTON (priv->arrow_button)->event_window, x, y); - gtk_widget_size_request (priv->arrow_button, &req); - gtk_widget_size_request (GTK_WIDGET (menu), &menu_req); - - if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL) - { - *y += priv->arrow_button->allocation.height; - if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR) - *x += priv->arrow_button->allocation.width - req.width; - else - *x += req.width - menu_req.width; - } - else - { - if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR) - *x += priv->arrow_button->allocation.width; - else - *x -= menu_req.width; - *y += priv->arrow_button->allocation.height - req.height; - } - - *push_in = TRUE; -} - -static void -menu_deactivated (GtkWidget *menu, - EggToolbar *toolbar) -{ - EggToolbarPrivate *priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->arrow_button), FALSE); -} - -static void -remove_item (GtkWidget *menu_item, - gpointer data) -{ - gtk_container_remove (GTK_CONTAINER (menu_item->parent), menu_item); -} - -static void -show_menu (EggToolbar *toolbar, - GdkEventButton *event) -{ - EggToolbarPrivate *priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - GList *list; - - if (priv->menu) - { - gtk_container_foreach (GTK_CONTAINER (priv->menu), remove_item, NULL); - gtk_widget_destroy (GTK_WIDGET (priv->menu)); - } - - priv->menu = GTK_MENU (gtk_menu_new ()); - g_signal_connect (priv->menu, "deactivate", G_CALLBACK (menu_deactivated), toolbar); - - for (list = priv->items; list != NULL; list = list->next) - { - EggToolItem *item = list->data; - - if (toolbar_item_visible (toolbar, item) && item->overflow_item) - { - GtkWidget *menu_item = egg_tool_item_retrieve_proxy_menu_item (item); - - if (menu_item) - { - g_assert (GTK_IS_MENU_ITEM (menu_item)); - gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), menu_item); - } - } - } - - gtk_widget_show_all (GTK_WIDGET (priv->menu)); - - gtk_menu_popup (GTK_MENU (priv->menu), NULL, NULL, - menu_position_func, toolbar, - event? event->button : 0, event? event->time : gtk_get_current_event_time()); -} - -static void -egg_toolbar_arrow_button_clicked (GtkWidget *button, - EggToolbar *toolbar) -{ - EggToolbarPrivate *priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->arrow_button)) && - (!priv->menu || !GTK_WIDGET_VISIBLE (GTK_WIDGET (priv->menu)))) - { - /* We only get here when the button is clicked with the keybaord, - * because mouse button presses result in the menu being shown so - * that priv->menu would be non-NULL and visible. - */ - show_menu (toolbar, NULL); - gtk_menu_shell_select_first (GTK_MENU_SHELL (priv->menu), FALSE); - } -} - -static gboolean -egg_toolbar_arrow_button_press (GtkWidget *button, - GdkEventButton *event, - EggToolbar *toolbar) -{ - show_menu (toolbar, event); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); - - return TRUE; -} - -static gboolean -egg_toolbar_button_press (GtkWidget *toolbar, - GdkEventButton *event) -{ - if (event->button == 3) - g_signal_emit (toolbar, toolbar_signals[POPUP_CONTEXT_MENU], 0, NULL); - - return FALSE; -} - -static void -egg_toolbar_update_button_relief (EggToolbar *toolbar) -{ - EggToolbarPrivate *priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - - egg_toolbar_reconfigured (toolbar); - - gtk_button_set_relief (GTK_BUTTON (priv->arrow_button), get_button_relief (toolbar)); -} - -static GtkReliefStyle -get_button_relief (EggToolbar *toolbar) -{ - GtkReliefStyle button_relief = GTK_RELIEF_NORMAL; - - gtk_widget_ensure_style (GTK_WIDGET (toolbar)); - - gtk_widget_style_get (GTK_WIDGET (toolbar), - "button_relief", &button_relief, - NULL); - - return button_relief; -} - -static gint -get_space_size (EggToolbar *toolbar) -{ - gint space_size = DEFAULT_SPACE_SIZE; - - gtk_widget_style_get (GTK_WIDGET (toolbar), - "space_size", &space_size, - NULL); - - return space_size; -} - -static EggToolbarSpaceStyle -get_space_style (EggToolbar *toolbar) -{ - EggToolbarSpaceStyle space_style = DEFAULT_SPACE_STYLE; - - gtk_widget_style_get (GTK_WIDGET (toolbar), - "space_style", &space_style, - NULL); - - - return space_style; -} - -static gint -get_internal_padding (EggToolbar *toolbar) -{ - gint ipadding = 0; - - gtk_widget_style_get (GTK_WIDGET (toolbar), - "internal_padding", &ipadding, - NULL); - - return ipadding; -} - -static gboolean -egg_toolbar_check_old_api (EggToolbar *toolbar) -{ - EggToolbarPrivate *priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - - if (priv->api_mode == NEW_API) - { - g_warning ("mixing deprecated and non-deprecated EggToolbar API is not allowed"); - return FALSE; - } - - priv->api_mode = OLD_API; - return TRUE; -} - -static gboolean -egg_toolbar_check_new_api (EggToolbar *toolbar) -{ - EggToolbarPrivate *priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - - if (priv->api_mode == OLD_API) - { - g_warning ("mixing deprecated and non-deprecated EggToolbar API is not allowed"); - return FALSE; - } - - priv->api_mode = NEW_API; - return TRUE; -} - -static void -egg_toolbar_insert_tool_item (EggToolbar *toolbar, - EggToolItem *item, - gint pos) -{ - EggToolbarPrivate *priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - - priv->items = g_list_insert (priv->items, item, pos); - toolbar->num_children++; - - gtk_widget_set_parent (GTK_WIDGET (item), GTK_WIDGET (toolbar)); -} - -static void -egg_toolbar_remove_tool_item (EggToolbar *toolbar, - EggToolItem *item) -{ - EggToolbarPrivate *priv; - GList *tmp; - - g_return_if_fail (EGG_IS_TOOLBAR (toolbar)); - g_return_if_fail (EGG_IS_TOOL_ITEM (item)); - - priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - - for (tmp = priv->items; tmp != NULL; tmp = tmp->next) - { - GtkWidget *child = tmp->data; - - if (child == GTK_WIDGET (item)) - { - gboolean was_visible; - - was_visible = GTK_WIDGET_VISIBLE (item); - gtk_widget_unparent (GTK_WIDGET (item)); - - priv->items = g_list_remove_link (priv->items, tmp); - toolbar->num_children--; - - if (was_visible && GTK_WIDGET_VISIBLE (toolbar)) - gtk_widget_queue_resize (GTK_WIDGET (toolbar)); - - break; - } - } -} - -GtkWidget * -egg_toolbar_new (void) -{ - EggToolbar *toolbar; - - toolbar = g_object_new (EGG_TYPE_TOOLBAR, NULL); - - return GTK_WIDGET (toolbar); -} - -void -egg_toolbar_insert (EggToolbar *toolbar, - EggToolItem *item, - gint pos) -{ - g_return_if_fail (EGG_IS_TOOLBAR (toolbar)); - g_return_if_fail (EGG_IS_TOOL_ITEM (item)); - - if (!egg_toolbar_check_new_api (toolbar)) - return; - - egg_toolbar_insert_tool_item (toolbar, item, pos); -} - -gint -egg_toolbar_get_item_index (EggToolbar *toolbar, - EggToolItem *item) -{ - EggToolbarPrivate *priv; - - g_return_val_if_fail (EGG_IS_TOOLBAR (toolbar), -1); - g_return_val_if_fail (EGG_IS_TOOL_ITEM (item), -1); - - if (!egg_toolbar_check_new_api (toolbar)) - return -1; - - priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - g_return_val_if_fail (g_list_find (priv->items, item) != NULL, -1); - - return g_list_index (priv->items, item); -} - -void -egg_toolbar_set_orientation (EggToolbar *toolbar, - GtkOrientation orientation) -{ - g_return_if_fail (EGG_IS_TOOLBAR (toolbar)); - - g_signal_emit (toolbar, toolbar_signals[ORIENTATION_CHANGED], 0, orientation); -} - -GtkOrientation -egg_toolbar_get_orientation (EggToolbar *toolbar) -{ - g_return_val_if_fail (EGG_IS_TOOLBAR (toolbar), GTK_ORIENTATION_HORIZONTAL); - - return toolbar->orientation; -} - -void -egg_toolbar_set_style (EggToolbar *toolbar, - GtkToolbarStyle style) -{ - g_return_if_fail (EGG_IS_TOOLBAR (toolbar)); - - toolbar->style_set = TRUE; - g_signal_emit (toolbar, toolbar_signals[STYLE_CHANGED], 0, style); - - -} - -GtkToolbarStyle -egg_toolbar_get_style (EggToolbar *toolbar) -{ - g_return_val_if_fail (EGG_IS_TOOLBAR (toolbar), DEFAULT_TOOLBAR_STYLE); - - return toolbar->style; -} - -void -egg_toolbar_unset_style (EggToolbar *toolbar) -{ - GtkToolbarStyle style; - - g_return_if_fail (EGG_IS_TOOLBAR (toolbar)); - - if (toolbar->style_set) - { - GtkSettings *settings = toolbar_get_settings (toolbar); - - if (settings) - g_object_get (settings, - "gtk-toolbar-style", &style, - NULL); - else - style = DEFAULT_TOOLBAR_STYLE; - - if (style != toolbar->style) - g_signal_emit (toolbar, toolbar_signals[STYLE_CHANGED], 0, style); - - toolbar->style_set = FALSE; - } -} - -void -egg_toolbar_set_tooltips (EggToolbar *toolbar, - gboolean enable) -{ - g_return_if_fail (EGG_IS_TOOLBAR (toolbar)); - - if (enable) - gtk_tooltips_enable (toolbar->tooltips); - else - gtk_tooltips_disable (toolbar->tooltips); -} - -gboolean -egg_toolbar_get_tooltips (EggToolbar *toolbar) -{ - g_return_val_if_fail (EGG_IS_TOOLBAR (toolbar), FALSE); - - return toolbar->tooltips->enabled; -} - -gint -egg_toolbar_get_n_items (EggToolbar *toolbar) -{ - EggToolbarPrivate *priv; - - g_return_val_if_fail (EGG_IS_TOOLBAR (toolbar), -1); - - if (!egg_toolbar_check_new_api (toolbar)) - return -1; - - priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - - return g_list_length (priv->items); -} - -/* - * returns NULL if n is out of range - */ -EggToolItem * -egg_toolbar_get_nth_item (EggToolbar *toolbar, - gint n) -{ - EggToolbarPrivate *priv; - - g_return_val_if_fail (EGG_IS_TOOLBAR (toolbar), NULL); - - if (!egg_toolbar_check_new_api (toolbar)) - return NULL; - - priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - - return g_list_nth_data (priv->items, n); -} - -void -egg_toolbar_set_icon_size (EggToolbar *toolbar, - GtkIconSize icon_size) -{ - g_return_if_fail (EGG_IS_TOOLBAR (toolbar)); - - toolbar->icon_size_set = TRUE; - - if (toolbar->icon_size == icon_size) - return; - - toolbar->icon_size = icon_size; - - egg_toolbar_reconfigured (toolbar); - - gtk_widget_queue_resize (GTK_WIDGET (toolbar)); -} - -GtkIconSize -egg_toolbar_get_icon_size (EggToolbar *toolbar) -{ - g_return_val_if_fail (EGG_IS_TOOLBAR (toolbar), DEFAULT_ICON_SIZE); - - return toolbar->icon_size; -} - -GtkReliefStyle -egg_toolbar_get_relief_style (EggToolbar *toolbar) -{ - g_return_val_if_fail (EGG_IS_TOOLBAR (toolbar), GTK_RELIEF_NONE); - - return get_button_relief (toolbar); -} - -void -egg_toolbar_unset_icon_size (EggToolbar *toolbar) -{ - GtkIconSize size; - - g_return_if_fail (EGG_IS_TOOLBAR (toolbar)); - - if (toolbar->icon_size_set) - { - GtkSettings *settings = toolbar_get_settings (toolbar); - - if (settings) - { - g_object_get (settings, - "gtk-toolbar-icon-size", &size, - NULL); - } - else - size = DEFAULT_ICON_SIZE; - - if (size != toolbar->icon_size) - egg_toolbar_set_icon_size (toolbar, size); - - toolbar->icon_size_set = FALSE; - } -} - -void -egg_toolbar_set_show_arrow (EggToolbar *toolbar, - gboolean show_arrow) -{ - EggToolbarPrivate *priv; - - g_return_if_fail (EGG_IS_TOOLBAR (toolbar)); - - priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - show_arrow = show_arrow != FALSE; - - if (priv->show_arrow != show_arrow) - { - priv->show_arrow = show_arrow; - - if (!priv->show_arrow) - gtk_widget_hide (priv->arrow_button); - - gtk_widget_queue_resize (GTK_WIDGET (toolbar)); - g_object_notify (G_OBJECT (toolbar), "show_arrow"); - } -} - -gboolean -egg_toolbar_get_show_arrow (EggToolbar *toolbar) -{ - EggToolbarPrivate *priv; - - g_return_val_if_fail (EGG_IS_TOOLBAR (toolbar), FALSE); - - if (!egg_toolbar_check_new_api (toolbar)) - return FALSE; - - priv = EGG_TOOLBAR_GET_PRIVATE (toolbar); - - return priv->show_arrow; -} - -gint -egg_toolbar_get_drop_index (EggToolbar *toolbar, - gint x, - gint y) -{ - gint drop_index, drop_pos; - - g_return_val_if_fail (EGG_IS_TOOLBAR (toolbar), FALSE); - - if (!egg_toolbar_check_new_api (toolbar)) - return -1; - - find_drop_pos (toolbar, x, y, &drop_index, &drop_pos); - - return drop_index; -} - -GtkWidget * -egg_toolbar_append_item (EggToolbar *toolbar, - const char *text, - const char *tooltip_text, - const char *tooltip_private_text, - GtkWidget *icon, - GtkSignalFunc callback, - gpointer user_data) -{ - return egg_toolbar_insert_element (toolbar, EGG_TOOLBAR_CHILD_BUTTON, - NULL, text, - tooltip_text, tooltip_private_text, - icon, callback, user_data, - toolbar->num_children); -} - -GtkWidget * -egg_toolbar_prepend_item (EggToolbar *toolbar, - const char *text, - const char *tooltip_text, - const char *tooltip_private_text, - GtkWidget *icon, - GtkSignalFunc callback, - gpointer user_data) -{ - return egg_toolbar_insert_element (toolbar, EGG_TOOLBAR_CHILD_BUTTON, - NULL, text, - tooltip_text, tooltip_private_text, - icon, callback, user_data, - 0); -} - -GtkWidget * -egg_toolbar_insert_item (EggToolbar *toolbar, - const char *text, - const char *tooltip_text, - const char *tooltip_private_text, - GtkWidget *icon, - GtkSignalFunc callback, - gpointer user_data, - gint position) -{ - return egg_toolbar_insert_element (toolbar, EGG_TOOLBAR_CHILD_BUTTON, - NULL, text, - tooltip_text, tooltip_private_text, - icon, callback, user_data, - position); -} - -GtkWidget* -egg_toolbar_insert_stock (EggToolbar *toolbar, - const gchar *stock_id, - const char *tooltip_text, - const char *tooltip_private_text, - GtkSignalFunc callback, - gpointer user_data, - gint position) -{ - return egg_toolbar_internal_insert_element (toolbar, EGG_TOOLBAR_CHILD_BUTTON, - NULL, stock_id, - tooltip_text, tooltip_private_text, - NULL, callback, user_data, - position, TRUE); -} - -void -egg_toolbar_append_space (EggToolbar *toolbar) -{ - egg_toolbar_insert_element (toolbar, EGG_TOOLBAR_CHILD_SPACE, - NULL, NULL, - NULL, NULL, - NULL, NULL, NULL, - toolbar->num_children); -} - -void -egg_toolbar_prepend_space (EggToolbar *toolbar) -{ - egg_toolbar_insert_element (toolbar, EGG_TOOLBAR_CHILD_SPACE, - NULL, NULL, - NULL, NULL, - NULL, NULL, NULL, - 0); -} - -void -egg_toolbar_insert_space (EggToolbar *toolbar, - gint position) -{ - egg_toolbar_insert_element (toolbar, EGG_TOOLBAR_CHILD_SPACE, - NULL, NULL, - NULL, NULL, - NULL, NULL, NULL, - position); -} - -void -egg_toolbar_remove_space (EggToolbar *toolbar, - gint position) -{ - EggToolItem *item; - - g_return_if_fail (EGG_IS_TOOLBAR (toolbar)); - - if (!egg_toolbar_check_old_api (toolbar)) - return; - - item = g_list_nth_data (toolbar->children, position); - - if (!item) - { - g_warning ("Toolbar position %d doesn't exist", position); - return; - } - - if (GTK_BIN (item)->child) - { - g_warning ("Toolbar position %d is not a space", position); - } - - egg_toolbar_remove_tool_item (toolbar, item); -} - -void -egg_toolbar_append_widget (EggToolbar *toolbar, - GtkWidget *widget, - const gchar *tooltip_text, - const gchar *tooltip_private_text) -{ - egg_toolbar_insert_element (toolbar, EGG_TOOLBAR_CHILD_WIDGET, - widget, NULL, - tooltip_text, tooltip_private_text, - NULL, NULL, NULL, - toolbar->num_children); -} - -void -egg_toolbar_prepend_widget (EggToolbar *toolbar, - GtkWidget *widget, - const gchar *tooltip_text, - const gchar *tooltip_private_text) -{ - egg_toolbar_insert_element (toolbar, EGG_TOOLBAR_CHILD_WIDGET, - widget, NULL, - tooltip_text, tooltip_private_text, - NULL, NULL, NULL, - 0); -} - -void -egg_toolbar_insert_widget (EggToolbar *toolbar, - GtkWidget *widget, - const char *tooltip_text, - const char *tooltip_private_text, - gint position) -{ - egg_toolbar_insert_element (toolbar, EGG_TOOLBAR_CHILD_WIDGET, - widget, NULL, - tooltip_text, tooltip_private_text, - NULL, NULL, NULL, - position); -} - -GtkWidget* -egg_toolbar_append_element (EggToolbar *toolbar, - GtkToolbarChildType type, - GtkWidget *widget, - const char *text, - const char *tooltip_text, - const char *tooltip_private_text, - GtkWidget *icon, - GtkSignalFunc callback, - gpointer user_data) -{ - return egg_toolbar_insert_element (toolbar, type, widget, text, - tooltip_text, tooltip_private_text, - icon, callback, user_data, - toolbar->num_children); -} - -GtkWidget * -egg_toolbar_prepend_element (EggToolbar *toolbar, - GtkToolbarChildType type, - GtkWidget *widget, - const char *text, - const char *tooltip_text, - const char *tooltip_private_text, - GtkWidget *icon, - GtkSignalFunc callback, - gpointer user_data) -{ - return egg_toolbar_insert_element (toolbar, type, widget, text, - tooltip_text, tooltip_private_text, - icon, callback, user_data, 0); -} - -GtkWidget * -egg_toolbar_insert_element (EggToolbar *toolbar, - EggToolbarChildType type, - GtkWidget *widget, - const char *text, - const char *tooltip_text, - const char *tooltip_private_text, - GtkWidget *icon, - GtkSignalFunc callback, - gpointer user_data, - gint position) -{ - return egg_toolbar_internal_insert_element (toolbar, type, widget, text, - tooltip_text, tooltip_private_text, - icon, callback, user_data, position, FALSE); -} - -static gchar * -elide_underscores (const gchar *original) -{ - gchar *q, *result; - const gchar *p; - gboolean last_underscore; - - q = result = g_malloc (strlen (original) + 1); - last_underscore = FALSE; - - for (p = original; *p; p++) - { - if (!last_underscore && *p == '_') - last_underscore = TRUE; - else - { - last_underscore = FALSE; - *q++ = *p; - } - } - - *q = '\0'; - - return result; -} - -static GtkWidget * -egg_toolbar_internal_insert_element (EggToolbar *toolbar, - EggToolbarChildType type, - GtkWidget *widget, - const char *text, - const char *tooltip_text, - const char *tooltip_private_text, - GtkWidget *icon, - GtkSignalFunc callback, - gpointer user_data, - gint position, - gboolean use_stock) -{ - EggToolbarChild *child; - EggToolItem *item = NULL; - - g_return_val_if_fail (EGG_IS_TOOLBAR (toolbar), NULL); - - if (!egg_toolbar_check_old_api (toolbar)) - return NULL; - - if (type == EGG_TOOLBAR_CHILD_WIDGET) - g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); - else if (type != EGG_TOOLBAR_CHILD_RADIOBUTTON) - g_return_val_if_fail (widget == NULL, NULL); - - child = g_new (EggToolbarChild, 1); - - child->type = type; - child->icon = NULL; - child->label = NULL; - - switch (type) - { - case EGG_TOOLBAR_CHILD_SPACE: - item = egg_separator_tool_item_new (); - child->widget = NULL; - break; - - case EGG_TOOLBAR_CHILD_WIDGET: - item = egg_tool_item_new (); - child->widget = widget; - gtk_container_add (GTK_CONTAINER (item), child->widget); - break; - - case EGG_TOOLBAR_CHILD_BUTTON: - item = egg_tool_button_new (); - child->widget = EGG_TOOL_BUTTON (item)->button; - break; - - case EGG_TOOLBAR_CHILD_TOGGLEBUTTON: - item = egg_toggle_tool_button_new (); - child->widget = EGG_TOOL_BUTTON (item)->button; - break; - - case EGG_TOOLBAR_CHILD_RADIOBUTTON: - item = egg_radio_tool_button_new (widget - ? gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget)) - : NULL); - child->widget = EGG_TOOL_BUTTON (item)->button; - break; - } - - gtk_widget_show (GTK_WIDGET (item)); - - if (type == EGG_TOOLBAR_CHILD_BUTTON || - type == EGG_TOOLBAR_CHILD_RADIOBUTTON || - type == EGG_TOOLBAR_CHILD_TOGGLEBUTTON) - { - if (text) - { - if (use_stock) - { - GtkStockItem stock_item; - gchar *label_text; - - egg_tool_button_set_stock_id (EGG_TOOL_BUTTON (item), text); - - gtk_stock_lookup (text, &stock_item); - label_text = elide_underscores (stock_item.label); - child->label = GTK_WIDGET (gtk_label_new (label_text)); - g_free (label_text); - } - else - { - child->label = gtk_label_new (text); - } - egg_tool_button_set_label_widget (EGG_TOOL_BUTTON (item), child->label); - gtk_widget_show (child->label); - } - - if (icon) - { - child->icon = icon; - egg_tool_button_set_icon_widget (EGG_TOOL_BUTTON (item), icon); - - /* Applications depend on the toolbar showing the widget for them */ - gtk_widget_show (GTK_WIDGET (icon)); - } - - /* - * We need to connect to the button's clicked callback because some - * programs may rely on that the widget in the callback is a GtkButton - */ - if (callback) - g_signal_connect (child->widget, "clicked", - callback, user_data); - } - - if ((type != GTK_TOOLBAR_CHILD_SPACE) && tooltip_text) - egg_tool_item_set_tooltip (item, toolbar->tooltips, - tooltip_text, tooltip_private_text); - - toolbar->children = g_list_insert (toolbar->children, child, position); - - egg_toolbar_insert_tool_item (toolbar, item, position); - - return child->widget; -} |