2 * Copyright (C) 2003, 2004 Marco Pesenti Gritti
3 * Copyright (C) 2003, 2004, 2005 Christian Persch
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include "egg-editable-toolbar.h"
25 #include "egg-toolbars-model.h"
26 #include "egg-toolbar-editor.h"
28 #include <gtk/gtkvseparator.h>
29 #include <gtk/gtkiconfactory.h>
30 #include <gtk/gtkwindow.h>
31 #include <gtk/gtkmain.h>
32 #include <gtk/gtkdnd.h>
33 #include <gtk/gtkhbox.h>
34 #include <gtk/gtkimage.h>
35 #include <gtk/gtktoggleaction.h>
36 #include <gtk/gtkcheckmenuitem.h>
37 #include <gtk/gtkimagemenuitem.h>
38 #include <gtk/gtkseparatormenuitem.h>
39 #include <gtk/gtkmenu.h>
40 #include <gtk/gtkstock.h>
41 #include <gtk/gtklabel.h>
42 #include <gtk/gtkbutton.h>
43 #include <gtk/gtktoolbar.h>
44 #include <gtk/gtktoolitem.h>
45 #include <gtk/gtktoolbutton.h>
46 #include <gtk/gtkseparatortoolitem.h>
47 #include <glib/gi18n.h>
50 static void egg_editable_toolbar_class_init (EggEditableToolbarClass *klass);
51 static void egg_editable_toolbar_init (EggEditableToolbar *etoolbar);
53 #define MIN_TOOLBAR_HEIGHT 20
54 #define EGG_ITEM_NAME "egg-item-name"
55 #define STOCK_DRAG_MODE "stock_drag-mode"
57 static const GtkTargetEntry dest_drag_types[] = {
58 {EGG_TOOLBAR_ITEM_TYPE, GTK_TARGET_SAME_APP, 0},
77 static guint egg_editable_toolbar_signals[LAST_SIGNAL] = { 0 };
79 static GObjectClass *parent_class = NULL;
81 #define EGG_EDITABLE_TOOLBAR_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EGG_TYPE_EDITABLE_TOOLBAR, EggEditableToolbarPrivate))
83 struct _EggEditableToolbarPrivate
85 GtkUIManager *manager;
86 EggToolbarsModel *model;
89 GtkWidget *fixed_toolbar;
92 GtkActionGroup *actions;
95 GList *visibility_paths;
96 GPtrArray *visibility_actions;
101 GtkToolbar *dnd_toolbar;
102 GtkToolItem *dnd_toolitem;
106 egg_editable_toolbar_get_type (void)
108 static GType type = 0;
110 if (G_UNLIKELY (type == 0))
112 const GTypeInfo our_info = {
113 sizeof (EggEditableToolbarClass),
114 NULL, /* base_init */
115 NULL, /* base_finalize */
116 (GClassInitFunc) egg_editable_toolbar_class_init,
118 NULL, /* class_data */
119 sizeof (EggEditableToolbar),
121 (GInstanceInitFunc) egg_editable_toolbar_init
124 type = g_type_register_static (GTK_TYPE_VBOX,
125 "EggEditableToolbar",
133 get_dock_position (EggEditableToolbar *etoolbar,
139 l = gtk_container_get_children (GTK_CONTAINER (etoolbar));
140 result = g_list_index (l, dock);
147 get_toolbar_position (EggEditableToolbar *etoolbar, GtkWidget *toolbar)
149 return get_dock_position (etoolbar, toolbar->parent);
153 get_n_toolbars (EggEditableToolbar *etoolbar)
158 l = gtk_container_get_children (GTK_CONTAINER (etoolbar));
159 result = g_list_length (l);
166 get_dock_nth (EggEditableToolbar *etoolbar,
172 l = gtk_container_get_children (GTK_CONTAINER (etoolbar));
173 result = g_list_nth_data (l, position);
180 get_toolbar_nth (EggEditableToolbar *etoolbar,
187 dock = get_dock_nth (etoolbar, position);
188 g_return_val_if_fail (dock != NULL, NULL);
190 l = gtk_container_get_children (GTK_CONTAINER (dock));
191 result = GTK_WIDGET (l->data);
198 find_action (EggEditableToolbar *etoolbar,
202 GtkAction *action = NULL;
204 l = gtk_ui_manager_get_action_groups (etoolbar->priv->manager);
206 g_return_val_if_fail (name != NULL, NULL);
208 for (; l != NULL; l = l->next)
212 tmp = gtk_action_group_get_action (GTK_ACTION_GROUP (l->data), name);
221 drag_data_delete_cb (GtkWidget *widget,
222 GdkDragContext *context,
223 EggEditableToolbar *etoolbar)
225 int pos, toolbar_pos;
227 widget = gtk_widget_get_ancestor (widget, GTK_TYPE_TOOL_ITEM);
228 g_return_if_fail (widget != NULL);
229 g_return_if_fail (EGG_IS_EDITABLE_TOOLBAR (etoolbar));
231 pos = gtk_toolbar_get_item_index (GTK_TOOLBAR (widget->parent),
232 GTK_TOOL_ITEM (widget));
233 toolbar_pos = get_toolbar_position (etoolbar, widget->parent);
235 egg_toolbars_model_remove_item (etoolbar->priv->model,
240 drag_begin_cb (GtkWidget *widget,
241 GdkDragContext *context,
242 EggEditableToolbar *etoolbar)
247 gtk_widget_hide (widget);
249 action = g_object_get_data (G_OBJECT (widget), "gtk-action");
250 if (action == NULL) return;
252 flags = egg_toolbars_model_get_name_flags (etoolbar->priv->model,
253 gtk_action_get_name (action));
254 if (!(flags & EGG_TB_MODEL_NAME_INFINITE))
256 flags &= ~EGG_TB_MODEL_NAME_USED;
257 egg_toolbars_model_set_name_flags (etoolbar->priv->model,
258 gtk_action_get_name (action),
264 drag_end_cb (GtkWidget *widget,
265 GdkDragContext *context,
266 EggEditableToolbar *etoolbar)
271 if (gtk_widget_get_parent (widget) != NULL)
273 gtk_widget_show (widget);
275 action = g_object_get_data (G_OBJECT (widget), "gtk-action");
276 if (action == NULL) return;
278 flags = egg_toolbars_model_get_name_flags (etoolbar->priv->model,
279 gtk_action_get_name (action));
280 if (!(flags & EGG_TB_MODEL_NAME_INFINITE))
282 flags |= EGG_TB_MODEL_NAME_USED;
283 egg_toolbars_model_set_name_flags (etoolbar->priv->model,
284 gtk_action_get_name (action),
291 drag_data_get_cb (GtkWidget *widget,
292 GdkDragContext *context,
293 GtkSelectionData *selection_data,
296 EggEditableToolbar *etoolbar)
298 EggToolbarsModel *model;
302 g_return_if_fail (EGG_IS_EDITABLE_TOOLBAR (etoolbar));
303 model = egg_editable_toolbar_get_model (etoolbar);
305 name = g_object_get_data (G_OBJECT (widget), EGG_ITEM_NAME);
308 name = g_object_get_data (G_OBJECT (gtk_widget_get_parent (widget)), EGG_ITEM_NAME);
309 g_return_if_fail (name != NULL);
312 data = egg_toolbars_model_get_data (model, selection_data->target, name);
315 gtk_selection_data_set (selection_data, selection_data->target, 8, (unsigned char *)data, strlen (data));
321 move_item_cb (GtkAction *action,
322 EggEditableToolbar *etoolbar)
324 GtkWidget *toolitem = gtk_widget_get_ancestor (egg_editable_toolbar_get_selected (etoolbar), GTK_TYPE_TOOL_ITEM);
325 GtkTargetList *list = gtk_target_list_new (dest_drag_types, G_N_ELEMENTS (dest_drag_types));
327 GdkEvent *realevent = gtk_get_current_event();
328 GdkEventMotion event;
329 event.type = GDK_MOTION_NOTIFY;
330 event.window = realevent->any.window;
331 event.send_event = FALSE;
333 event.time = gdk_event_get_time (realevent);
334 gdk_event_get_state (realevent, &event.state);
335 gdk_event_get_coords (realevent, &event.x, &event.y);
336 gdk_event_get_root_coords (realevent, &event.x_root, &event.y_root);
338 gtk_drag_begin (toolitem, list, GDK_ACTION_MOVE, 1, (GdkEvent *)&event);
339 gtk_target_list_unref (list);
343 remove_item_cb (GtkAction *action,
344 EggEditableToolbar *etoolbar)
346 GtkWidget *toolitem = gtk_widget_get_ancestor (egg_editable_toolbar_get_selected (etoolbar), GTK_TYPE_TOOL_ITEM);
347 int pos, toolbar_pos;
349 toolbar_pos = get_toolbar_position (etoolbar, toolitem->parent);
350 pos = gtk_toolbar_get_item_index (GTK_TOOLBAR (toolitem->parent),
351 GTK_TOOL_ITEM (toolitem));
353 egg_toolbars_model_remove_item (etoolbar->priv->model,
356 if (egg_toolbars_model_n_items (etoolbar->priv->model, toolbar_pos) == 0)
358 egg_toolbars_model_remove_toolbar (etoolbar->priv->model, toolbar_pos);
363 remove_toolbar_cb (GtkAction *action,
364 EggEditableToolbar *etoolbar)
366 GtkWidget *selected = egg_editable_toolbar_get_selected (etoolbar);
367 GtkWidget *toolbar = gtk_widget_get_ancestor (selected, GTK_TYPE_TOOLBAR);
370 toolbar_pos = get_toolbar_position (etoolbar, toolbar);
371 egg_toolbars_model_remove_toolbar (etoolbar->priv->model, toolbar_pos);
375 popup_context_deactivate (GtkMenuShell *menu,
376 EggEditableToolbar *etoolbar)
378 egg_editable_toolbar_set_selected (etoolbar, NULL);
379 g_object_notify (G_OBJECT (etoolbar), "selected");
383 popup_context_menu_cb (GtkWidget *toolbar,
387 EggEditableToolbar *etoolbar)
389 if (etoolbar->priv->popup_path != NULL)
393 egg_editable_toolbar_set_selected (etoolbar, toolbar);
394 g_object_notify (G_OBJECT (etoolbar), "selected");
396 menu = GTK_MENU (gtk_ui_manager_get_widget (etoolbar->priv->manager,
397 etoolbar->priv->popup_path));
398 g_return_if_fail (menu != NULL);
399 gtk_menu_popup (menu, NULL, NULL, NULL, NULL, button_number, gtk_get_current_event_time ());
400 g_signal_connect_object (menu, "selection-done",
401 G_CALLBACK (popup_context_deactivate),
407 button_press_event_cb (GtkWidget *widget,
408 GdkEventButton *event,
409 EggEditableToolbar *etoolbar)
411 if (event->button == 3 && etoolbar->priv->popup_path != NULL)
415 egg_editable_toolbar_set_selected (etoolbar, widget);
416 g_object_notify (G_OBJECT (etoolbar), "selected");
418 menu = GTK_MENU (gtk_ui_manager_get_widget (etoolbar->priv->manager,
419 etoolbar->priv->popup_path));
420 g_return_val_if_fail (menu != NULL, FALSE);
421 gtk_menu_popup (menu, NULL, NULL, NULL, NULL, event->button, event->time);
422 g_signal_connect_object (menu, "selection-done",
423 G_CALLBACK (popup_context_deactivate),
433 configure_item_sensitivity (GtkToolItem *item, EggEditableToolbar *etoolbar)
438 name = g_object_get_data (G_OBJECT (item), EGG_ITEM_NAME);
439 action = name ? find_action (etoolbar, name) : NULL;
443 g_object_notify (G_OBJECT (action), "sensitive");
446 gtk_tool_item_set_use_drag_window (item,
447 (etoolbar->priv->edit_mode > 0) ||
448 GTK_IS_SEPARATOR_TOOL_ITEM (item));
453 configure_item_cursor (GtkToolItem *item,
454 EggEditableToolbar *etoolbar)
456 EggEditableToolbarPrivate *priv = etoolbar->priv;
457 GtkWidget *widget = GTK_WIDGET (item);
459 if (widget->window != NULL)
461 if (priv->edit_mode > 0)
465 cursor = gdk_cursor_new (GDK_HAND2);
466 gdk_window_set_cursor (widget->window, cursor);
467 gdk_cursor_unref (cursor);
469 gtk_drag_source_set (widget, GDK_BUTTON1_MASK, dest_drag_types,
470 G_N_ELEMENTS (dest_drag_types), GDK_ACTION_MOVE);
474 gdk_window_set_cursor (GTK_WIDGET(item)->window, NULL);
481 configure_item_tooltip (GtkToolItem *item)
483 GtkAction *action = g_object_get_data (G_OBJECT (item),
488 g_object_notify (G_OBJECT (action), "tooltip");
494 connect_widget_signals (GtkWidget *proxy, EggEditableToolbar *etoolbar)
496 if (GTK_IS_CONTAINER (proxy))
498 gtk_container_forall (GTK_CONTAINER (proxy),
499 (GtkCallback) connect_widget_signals,
500 (gpointer) etoolbar);
503 if (GTK_IS_TOOL_ITEM (proxy))
505 g_signal_connect_object (proxy, "drag_begin",
506 G_CALLBACK (drag_begin_cb),
508 g_signal_connect_object (proxy, "drag_end",
509 G_CALLBACK (drag_end_cb),
511 g_signal_connect_object (proxy, "drag_data_get",
512 G_CALLBACK (drag_data_get_cb),
514 g_signal_connect_object (proxy, "drag_data_delete",
515 G_CALLBACK (drag_data_delete_cb),
519 if (GTK_IS_BUTTON (proxy) || GTK_IS_TOOL_ITEM (proxy))
521 g_signal_connect_object (proxy, "button-press-event",
522 G_CALLBACK (button_press_event_cb),
528 action_sensitive_cb (GtkAction *action,
532 EggEditableToolbar *etoolbar = EGG_EDITABLE_TOOLBAR
533 (gtk_widget_get_ancestor (GTK_WIDGET (item), EGG_TYPE_EDITABLE_TOOLBAR));
535 if (etoolbar->priv->edit_mode > 0)
537 gtk_widget_set_sensitive (GTK_WIDGET (item), TRUE);
542 create_item_from_action (EggEditableToolbar *etoolbar,
547 g_return_val_if_fail (name != NULL, NULL);
549 if (strcmp (name, "_separator") == 0)
551 item = gtk_separator_tool_item_new ();
555 GtkAction *action = find_action (etoolbar, name);
556 if (action == NULL) return NULL;
558 item = GTK_TOOL_ITEM (gtk_action_create_tool_item (action));
560 /* Normally done on-demand by the GtkUIManager, but no
561 * such demand may have been made yet, so do it ourselves.
563 gtk_action_set_accel_group
564 (action, gtk_ui_manager_get_accel_group(etoolbar->priv->manager));
566 g_signal_connect_object (action, "notify::sensitive",
567 G_CALLBACK (action_sensitive_cb), item, 0);
570 gtk_widget_show (GTK_WIDGET (item));
572 g_object_set_data_full (G_OBJECT (item), EGG_ITEM_NAME,
573 g_strdup (name), g_free);
579 create_item_from_position (EggEditableToolbar *etoolbar,
580 int toolbar_position,
586 name = egg_toolbars_model_item_nth (etoolbar->priv->model, toolbar_position, position);
587 item = create_item_from_action (etoolbar, name);
593 toolbar_drag_data_received_cb (GtkToolbar *toolbar,
594 GdkDragContext *context,
597 GtkSelectionData *selection_data,
600 EggEditableToolbar *etoolbar)
602 /* This function can be called for two reasons
604 * (1) drag_motion() needs an item to pass to
605 * gtk_toolbar_set_drop_highlight_item(). We can
606 * recognize this case by etoolbar->priv->pending being TRUE
607 * We should just create an item and return.
609 * (2) The drag has finished, and drag_drop() wants us to
610 * actually add a new item to the toolbar.
613 GdkAtom type = selection_data->type;
614 const char *data = (char *)selection_data->data;
618 gboolean used = FALSE;
620 /* Find out where the drop is occuring, and the name of what is being dropped. */
621 if (selection_data->length >= 0)
623 ipos = gtk_toolbar_get_drop_index (toolbar, x, y);
624 name = egg_toolbars_model_get_name (etoolbar->priv->model, type, data, FALSE);
627 used = ((egg_toolbars_model_get_name_flags (etoolbar->priv->model, name) & EGG_TB_MODEL_NAME_USED) != 0);
631 /* If we just want a highlight item, then . */
632 if (etoolbar->priv->dnd_pending > 0)
634 etoolbar->priv->dnd_pending--;
636 if (name != NULL && etoolbar->priv->dnd_toolbar == toolbar && !used)
638 etoolbar->priv->dnd_toolitem = create_item_from_action (etoolbar, name);
639 gtk_toolbar_set_drop_highlight_item (etoolbar->priv->dnd_toolbar,
640 etoolbar->priv->dnd_toolitem, ipos);
645 gtk_toolbar_set_drop_highlight_item (toolbar, NULL, 0);
646 etoolbar->priv->dnd_toolbar = NULL;
647 etoolbar->priv->dnd_toolitem = NULL;
649 /* If we don't have a name to use yet, try to create one. */
650 if (name == NULL && selection_data->length >= 0)
652 name = egg_toolbars_model_get_name (etoolbar->priv->model, type, data, TRUE);
655 if (name != NULL && !used)
657 gint tpos = get_toolbar_position (etoolbar, GTK_WIDGET (toolbar));
658 egg_toolbars_model_add_item (etoolbar->priv->model, tpos, ipos, name);
659 gtk_drag_finish (context, TRUE, context->action == GDK_ACTION_MOVE, time);
663 gtk_drag_finish (context, FALSE, context->action == GDK_ACTION_MOVE, time);
671 toolbar_drag_drop_cb (GtkToolbar *toolbar,
672 GdkDragContext *context,
676 EggEditableToolbar *etoolbar)
680 target = gtk_drag_dest_find_target (GTK_WIDGET (toolbar), context, NULL);
681 if (target != GDK_NONE)
683 gtk_drag_get_data (GTK_WIDGET (toolbar), context, target, time);
691 toolbar_drag_motion_cb (GtkToolbar *toolbar,
692 GdkDragContext *context,
696 EggEditableToolbar *etoolbar)
698 GdkAtom target = gtk_drag_dest_find_target (GTK_WIDGET (toolbar), context, NULL);
699 if (target == GDK_NONE)
701 gdk_drag_status (context, 0, time);
705 /* Make ourselves the current dnd toolbar, and request a highlight item. */
706 if (etoolbar->priv->dnd_toolbar != toolbar)
708 etoolbar->priv->dnd_toolbar = toolbar;
709 etoolbar->priv->dnd_toolitem = NULL;
710 etoolbar->priv->dnd_pending++;
711 gtk_drag_get_data (GTK_WIDGET (toolbar), context, target, time);
714 /* If a highlight item is available, use it. */
715 else if (etoolbar->priv->dnd_toolitem)
717 gint ipos = gtk_toolbar_get_drop_index (etoolbar->priv->dnd_toolbar, x, y);
718 gtk_toolbar_set_drop_highlight_item (etoolbar->priv->dnd_toolbar,
719 etoolbar->priv->dnd_toolitem, ipos);
722 gdk_drag_status (context, context->suggested_action, time);
728 toolbar_drag_leave_cb (GtkToolbar *toolbar,
729 GdkDragContext *context,
731 EggEditableToolbar *etoolbar)
733 gtk_toolbar_set_drop_highlight_item (toolbar, NULL, 0);
735 /* If we were the current dnd toolbar target, remove the item. */
736 if (etoolbar->priv->dnd_toolbar == toolbar)
738 etoolbar->priv->dnd_toolbar = NULL;
739 etoolbar->priv->dnd_toolitem = NULL;
744 configure_drag_dest (EggEditableToolbar *etoolbar,
747 EggToolbarsItemType *type;
748 GtkTargetList *targets;
751 /* Make every toolbar able to receive drag-drops. */
752 gtk_drag_dest_set (GTK_WIDGET (toolbar), 0,
753 dest_drag_types, G_N_ELEMENTS (dest_drag_types),
754 GDK_ACTION_MOVE | GDK_ACTION_COPY);
756 /* Add any specialist drag-drop abilities. */
757 targets = gtk_drag_dest_get_target_list (GTK_WIDGET (toolbar));
758 list = egg_toolbars_model_get_types (etoolbar->priv->model);
762 if (type->new_name != NULL || type->get_name != NULL)
763 gtk_target_list_add (targets, type->type, 0, 0);
769 toggled_visibility_cb (GtkToggleAction *action,
770 EggEditableToolbar *etoolbar)
772 EggEditableToolbarPrivate *priv = etoolbar->priv;
774 EggTbModelFlags flags;
778 visible = gtk_toggle_action_get_active (action);
779 for (i = 0; i < priv->visibility_actions->len; i++)
780 if (g_ptr_array_index (priv->visibility_actions, i) == action)
783 g_return_if_fail (i < priv->visibility_actions->len);
785 dock = get_dock_nth (etoolbar, i);
788 gtk_widget_show (dock);
792 gtk_widget_hide (dock);
795 if (priv->save_hidden)
797 flags = egg_toolbars_model_get_flags (priv->model, i);
801 flags &= ~(EGG_TB_MODEL_HIDDEN);
805 flags |= (EGG_TB_MODEL_HIDDEN);
808 egg_toolbars_model_set_flags (priv->model, i, flags);
813 toolbar_visibility_refresh (EggEditableToolbar *etoolbar)
815 EggEditableToolbarPrivate *priv = etoolbar->priv;
816 gint n_toolbars, n_items, i, j, k;
817 GtkToggleAction *action;
821 char action_name[40];
825 if (priv == NULL || priv->model == NULL || priv->manager == NULL ||
826 priv->visibility_paths == NULL || priv->actions == NULL)
831 if (priv->visibility_actions == NULL)
833 priv->visibility_actions = g_ptr_array_new ();
836 if (priv->visibility_id != 0)
838 gtk_ui_manager_remove_ui (priv->manager, priv->visibility_id);
841 priv->visibility_id = gtk_ui_manager_new_merge_id (priv->manager);
843 showing = GTK_WIDGET_VISIBLE (etoolbar);
845 n_toolbars = egg_toolbars_model_n_toolbars (priv->model);
846 for (i = 0; i < n_toolbars; i++)
848 string = g_string_sized_new (0);
849 n_items = egg_toolbars_model_n_items (priv->model, i);
850 for (k = 0, j = 0; j < n_items; j++)
852 GValue value = { 0, };
856 name = egg_toolbars_model_item_nth (priv->model, i, j);
857 if (name == NULL) continue;
858 action = find_action (etoolbar, name);
859 if (action == NULL) continue;
861 g_value_init (&value, G_TYPE_STRING);
862 g_object_get_property (G_OBJECT (action), "label", &value);
863 name = g_value_get_string (&value);
866 g_value_unset (&value);
869 k += g_utf8_strlen (name, -1) + 2;
872 g_string_append (string, ", ");
875 g_value_unset (&value);
879 g_string_append (string, name);
880 g_value_unset (&value);
884 g_string_append (string, " ...");
887 tmp = g_string_free (string, FALSE);
888 for (j = 0, k = 0; tmp[j]; j++)
890 if (tmp[j] == '_') continue;
895 /* Translaters: This string is for a toggle to display a toolbar.
896 * The name of the toolbar is automatically computed from the widgets
897 * on the toolbar, and is placed at the %s. Note the _ before the %s
898 * which is used to add mnemonics. We know that this is likely to
899 * produce duplicates, but don't worry about it. If your language
900 * normally has a mnemonic at the start, please use the _. If not,
902 action_label = g_strdup_printf (_("Show “_%s”"), tmp);
905 sprintf(action_name, "ToolbarToggle%d", i);
907 if (i >= priv->visibility_actions->len)
909 action = gtk_toggle_action_new (action_name, action_label, NULL, NULL);
910 g_ptr_array_add (priv->visibility_actions, action);
911 g_signal_connect_object (action, "toggled",
912 G_CALLBACK (toggled_visibility_cb),
914 gtk_action_group_add_action (priv->actions, GTK_ACTION (action));
918 action = g_ptr_array_index (priv->visibility_actions, i);
919 g_object_set (action, "label", action_label, NULL);
922 gtk_action_set_visible (GTK_ACTION (action), (egg_toolbars_model_get_flags (priv->model, i)
923 & EGG_TB_MODEL_NOT_REMOVABLE) == 0);
924 gtk_action_set_sensitive (GTK_ACTION (action), showing);
925 gtk_toggle_action_set_active (action, GTK_WIDGET_VISIBLE
926 (get_dock_nth (etoolbar, i)));
928 for (list = priv->visibility_paths; list != NULL; list = g_list_next (list))
930 gtk_ui_manager_add_ui (priv->manager, priv->visibility_id,
931 (const char *)list->data, action_name, action_name,
932 GTK_UI_MANAGER_MENUITEM, FALSE);
935 g_free (action_label);
938 gtk_ui_manager_ensure_update (priv->manager);
940 while (i < priv->visibility_actions->len)
942 action = g_ptr_array_index (priv->visibility_actions, i);
943 g_ptr_array_remove_index_fast (priv->visibility_actions, i);
944 gtk_action_group_remove_action (priv->actions, GTK_ACTION (action));
950 create_dock (EggEditableToolbar *etoolbar)
952 GtkWidget *toolbar, *hbox;
954 hbox = gtk_hbox_new (0, FALSE);
956 toolbar = gtk_toolbar_new ();
957 gtk_toolbar_set_show_arrow (GTK_TOOLBAR (toolbar), TRUE);
958 gtk_widget_show (toolbar);
959 gtk_box_pack_start (GTK_BOX (hbox), toolbar, TRUE, TRUE, 0);
961 g_signal_connect (toolbar, "drag_drop",
962 G_CALLBACK (toolbar_drag_drop_cb), etoolbar);
963 g_signal_connect (toolbar, "drag_motion",
964 G_CALLBACK (toolbar_drag_motion_cb), etoolbar);
965 g_signal_connect (toolbar, "drag_leave",
966 G_CALLBACK (toolbar_drag_leave_cb), etoolbar);
968 g_signal_connect (toolbar, "drag_data_received",
969 G_CALLBACK (toolbar_drag_data_received_cb), etoolbar);
970 g_signal_connect (toolbar, "popup_context_menu",
971 G_CALLBACK (popup_context_menu_cb), etoolbar);
973 configure_drag_dest (etoolbar, GTK_TOOLBAR (toolbar));
979 set_fixed_style (EggEditableToolbar *t, GtkToolbarStyle style)
981 g_return_if_fail (GTK_IS_TOOLBAR (t->priv->fixed_toolbar));
982 gtk_toolbar_set_style (GTK_TOOLBAR (t->priv->fixed_toolbar),
983 style == GTK_TOOLBAR_ICONS ? GTK_TOOLBAR_BOTH_HORIZ : style);
987 unset_fixed_style (EggEditableToolbar *t)
989 g_return_if_fail (GTK_IS_TOOLBAR (t->priv->fixed_toolbar));
990 gtk_toolbar_unset_style (GTK_TOOLBAR (t->priv->fixed_toolbar));
994 toolbar_changed_cb (EggToolbarsModel *model,
996 EggEditableToolbar *etoolbar)
999 EggTbModelFlags flags;
1000 GtkToolbarStyle style;
1002 flags = egg_toolbars_model_get_flags (model, position);
1003 toolbar = get_toolbar_nth (etoolbar, position);
1005 if (flags & EGG_TB_MODEL_ICONS)
1007 style = GTK_TOOLBAR_ICONS;
1009 else if (flags & EGG_TB_MODEL_TEXT)
1011 style = GTK_TOOLBAR_TEXT;
1013 else if (flags & EGG_TB_MODEL_BOTH)
1015 style = GTK_TOOLBAR_BOTH;
1017 else if (flags & EGG_TB_MODEL_BOTH_HORIZ)
1019 style = GTK_TOOLBAR_BOTH_HORIZ;
1023 gtk_toolbar_unset_style (GTK_TOOLBAR (toolbar));
1024 if (position == 0 && etoolbar->priv->fixed_toolbar)
1026 unset_fixed_style (etoolbar);
1031 gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), style);
1032 if (position == 0 && etoolbar->priv->fixed_toolbar)
1034 set_fixed_style (etoolbar, style);
1037 toolbar_visibility_refresh (etoolbar);
1041 unparent_fixed (EggEditableToolbar *etoolbar)
1043 GtkWidget *toolbar, *dock;
1044 g_return_if_fail (GTK_IS_TOOLBAR (etoolbar->priv->fixed_toolbar));
1046 toolbar = etoolbar->priv->fixed_toolbar;
1047 dock = get_dock_nth (etoolbar, 0);
1049 if (dock && toolbar->parent != NULL)
1051 gtk_container_remove (GTK_CONTAINER (dock), toolbar);
1056 update_fixed (EggEditableToolbar *etoolbar)
1058 GtkWidget *toolbar, *dock;
1059 if (!etoolbar->priv->fixed_toolbar) return;
1061 toolbar = etoolbar->priv->fixed_toolbar;
1062 dock = get_dock_nth (etoolbar, 0);
1064 if (dock && toolbar && toolbar->parent == NULL)
1066 gtk_box_pack_end (GTK_BOX (dock), toolbar, FALSE, TRUE, 0);
1068 gtk_widget_show (toolbar);
1070 gtk_widget_set_size_request (dock, -1, -1);
1071 gtk_widget_queue_resize_no_redraw (dock);
1076 toolbar_added_cb (EggToolbarsModel *model,
1078 EggEditableToolbar *etoolbar)
1082 dock = create_dock (etoolbar);
1083 if ((egg_toolbars_model_get_flags (model, position) & EGG_TB_MODEL_HIDDEN) == 0)
1084 gtk_widget_show (dock);
1086 gtk_widget_set_size_request (dock, -1, MIN_TOOLBAR_HEIGHT);
1088 gtk_box_pack_start (GTK_BOX (etoolbar), dock, TRUE, TRUE, 0);
1090 gtk_box_reorder_child (GTK_BOX (etoolbar), dock, position);
1092 gtk_widget_show_all (dock);
1094 update_fixed (etoolbar);
1096 toolbar_visibility_refresh (etoolbar);
1100 toolbar_removed_cb (EggToolbarsModel *model,
1102 EggEditableToolbar *etoolbar)
1106 if (position == 0 && etoolbar->priv->fixed_toolbar != NULL)
1108 unparent_fixed (etoolbar);
1111 dock = get_dock_nth (etoolbar, position);
1112 gtk_widget_destroy (dock);
1114 update_fixed (etoolbar);
1116 toolbar_visibility_refresh (etoolbar);
1120 item_added_cb (EggToolbarsModel *model,
1123 EggEditableToolbar *etoolbar)
1129 toolbar = get_toolbar_nth (etoolbar, tpos);
1130 item = create_item_from_position (etoolbar, tpos, ipos);
1131 if (item == NULL) return;
1133 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, ipos);
1135 connect_widget_signals (GTK_WIDGET (item), etoolbar);
1136 configure_item_tooltip (item);
1137 configure_item_cursor (item, etoolbar);
1138 configure_item_sensitivity (item, etoolbar);
1140 dock = get_dock_nth (etoolbar, tpos);
1141 gtk_widget_set_size_request (dock, -1, -1);
1142 gtk_widget_queue_resize_no_redraw (dock);
1144 toolbar_visibility_refresh (etoolbar);
1148 item_removed_cb (EggToolbarsModel *model,
1149 int toolbar_position,
1151 EggEditableToolbar *etoolbar)
1153 EggEditableToolbarPrivate *priv = etoolbar->priv;
1158 toolbar = get_toolbar_nth (etoolbar, toolbar_position);
1159 item = GTK_WIDGET (gtk_toolbar_get_nth_item
1160 (GTK_TOOLBAR (toolbar), position));
1161 g_return_if_fail (item != NULL);
1163 if (item == priv->selected)
1168 gtk_container_remove (GTK_CONTAINER (toolbar), item);
1170 toolbar_visibility_refresh (etoolbar);
1174 egg_editable_toolbar_build (EggEditableToolbar *etoolbar)
1176 int i, l, n_items, n_toolbars;
1177 EggToolbarsModel *model = etoolbar->priv->model;
1179 g_return_if_fail (model != NULL);
1180 g_return_if_fail (etoolbar->priv->manager != NULL);
1182 n_toolbars = egg_toolbars_model_n_toolbars (model);
1184 for (i = 0; i < n_toolbars; i++)
1186 GtkWidget *toolbar, *dock;
1188 dock = create_dock (etoolbar);
1189 if ((egg_toolbars_model_get_flags (model, i) & EGG_TB_MODEL_HIDDEN) == 0)
1190 gtk_widget_show (dock);
1191 gtk_box_pack_start (GTK_BOX (etoolbar), dock, TRUE, TRUE, 0);
1192 toolbar = get_toolbar_nth (etoolbar, i);
1194 n_items = egg_toolbars_model_n_items (model, i);
1195 for (l = 0; l < n_items; l++)
1199 item = create_item_from_position (etoolbar, i, l);
1202 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, l);
1204 connect_widget_signals (GTK_WIDGET (item), etoolbar);
1205 configure_item_tooltip (item);
1206 configure_item_sensitivity (item, etoolbar);
1210 egg_toolbars_model_remove_item (model, i, l);
1218 gtk_widget_set_size_request (dock, -1, MIN_TOOLBAR_HEIGHT);
1222 update_fixed (etoolbar);
1225 for (i = 0; i < n_toolbars; i ++)
1227 toolbar_changed_cb (model, i, etoolbar);
1232 egg_editable_toolbar_disconnect_model (EggEditableToolbar *toolbar)
1234 EggToolbarsModel *model = toolbar->priv->model;
1236 g_signal_handlers_disconnect_by_func
1237 (model, G_CALLBACK (item_added_cb), toolbar);
1238 g_signal_handlers_disconnect_by_func
1239 (model, G_CALLBACK (item_removed_cb), toolbar);
1240 g_signal_handlers_disconnect_by_func
1241 (model, G_CALLBACK (toolbar_added_cb), toolbar);
1242 g_signal_handlers_disconnect_by_func
1243 (model, G_CALLBACK (toolbar_removed_cb), toolbar);
1244 g_signal_handlers_disconnect_by_func
1245 (model, G_CALLBACK (toolbar_changed_cb), toolbar);
1249 egg_editable_toolbar_deconstruct (EggEditableToolbar *toolbar)
1251 EggToolbarsModel *model = toolbar->priv->model;
1254 g_return_if_fail (model != NULL);
1256 if (toolbar->priv->fixed_toolbar)
1258 unset_fixed_style (toolbar);
1259 unparent_fixed (toolbar);
1262 children = gtk_container_get_children (GTK_CONTAINER (toolbar));
1263 g_list_foreach (children, (GFunc) gtk_widget_destroy, NULL);
1264 g_list_free (children);
1268 egg_editable_toolbar_set_model (EggEditableToolbar *etoolbar,
1269 EggToolbarsModel *model)
1271 EggEditableToolbarPrivate *priv = etoolbar->priv;
1273 if (priv->model == model) return;
1277 egg_editable_toolbar_disconnect_model (etoolbar);
1278 egg_editable_toolbar_deconstruct (etoolbar);
1280 g_object_unref (priv->model);
1283 priv->model = g_object_ref (model);
1285 egg_editable_toolbar_build (etoolbar);
1287 toolbar_visibility_refresh (etoolbar);
1289 g_signal_connect (model, "item_added",
1290 G_CALLBACK (item_added_cb), etoolbar);
1291 g_signal_connect (model, "item_removed",
1292 G_CALLBACK (item_removed_cb), etoolbar);
1293 g_signal_connect (model, "toolbar_added",
1294 G_CALLBACK (toolbar_added_cb), etoolbar);
1295 g_signal_connect (model, "toolbar_removed",
1296 G_CALLBACK (toolbar_removed_cb), etoolbar);
1297 g_signal_connect (model, "toolbar_changed",
1298 G_CALLBACK (toolbar_changed_cb), etoolbar);
1302 egg_editable_toolbar_init (EggEditableToolbar *etoolbar)
1304 EggEditableToolbarPrivate *priv;
1306 priv = etoolbar->priv = EGG_EDITABLE_TOOLBAR_GET_PRIVATE (etoolbar);
1308 priv->save_hidden = TRUE;
1310 g_signal_connect (etoolbar, "notify::visible",
1311 G_CALLBACK (toolbar_visibility_refresh), NULL);
1315 egg_editable_toolbar_dispose (GObject *object)
1317 EggEditableToolbar *etoolbar = EGG_EDITABLE_TOOLBAR (object);
1318 EggEditableToolbarPrivate *priv = etoolbar->priv;
1321 if (priv->fixed_toolbar != NULL)
1323 g_object_unref (priv->fixed_toolbar);
1324 priv->fixed_toolbar = NULL;
1327 if (priv->visibility_paths)
1329 children = priv->visibility_paths;
1330 g_list_foreach (children, (GFunc) g_free, NULL);
1331 g_list_free (children);
1332 priv->visibility_paths = NULL;
1335 if (priv->manager != NULL)
1337 if (priv->visibility_id)
1339 gtk_ui_manager_remove_ui (priv->manager, priv->visibility_id);
1340 priv->visibility_id = 0;
1343 g_object_unref (priv->manager);
1344 priv->manager = NULL;
1349 egg_editable_toolbar_disconnect_model (etoolbar);
1350 g_object_unref (priv->model);
1354 G_OBJECT_CLASS (parent_class)->dispose (object);
1358 egg_editable_toolbar_set_ui_manager (EggEditableToolbar *etoolbar,
1359 GtkUIManager *manager)
1361 static const GtkActionEntry actions[] = {
1362 { "MoveToolItem", STOCK_DRAG_MODE, N_("_Move on Toolbar"), NULL,
1363 N_("Move the selected item on the toolbar"), G_CALLBACK (move_item_cb) },
1364 { "RemoveToolItem", GTK_STOCK_REMOVE, N_("_Remove from Toolbar"), NULL,
1365 N_("Remove the selected item from the toolbar"), G_CALLBACK (remove_item_cb) },
1366 { "RemoveToolbar", GTK_STOCK_DELETE, N_("_Delete Toolbar"), NULL,
1367 N_("Remove the selected toolbar"), G_CALLBACK (remove_toolbar_cb) },
1370 etoolbar->priv->manager = g_object_ref (manager);
1372 etoolbar->priv->actions = gtk_action_group_new ("ToolbarActions");
1373 gtk_action_group_set_translation_domain (etoolbar->priv->actions, GETTEXT_PACKAGE);
1374 gtk_action_group_add_actions (etoolbar->priv->actions, actions,
1375 G_N_ELEMENTS (actions), etoolbar);
1376 gtk_ui_manager_insert_action_group (manager, etoolbar->priv->actions, -1);
1377 g_object_unref (etoolbar->priv->actions);
1379 toolbar_visibility_refresh (etoolbar);
1382 GtkWidget * egg_editable_toolbar_get_selected (EggEditableToolbar *etoolbar)
1384 return etoolbar->priv->selected;
1388 egg_editable_toolbar_set_selected (EggEditableToolbar *etoolbar,
1391 GtkWidget *toolbar, *toolitem;
1394 etoolbar->priv->selected = widget;
1396 toolbar = (widget != NULL) ? gtk_widget_get_ancestor (widget, GTK_TYPE_TOOLBAR) : NULL;
1397 toolitem = (widget != NULL) ? gtk_widget_get_ancestor (widget, GTK_TYPE_TOOL_ITEM) : NULL;
1401 gint tpos = get_toolbar_position (etoolbar, toolbar);
1402 editable = ((egg_toolbars_model_get_flags (etoolbar->priv->model, tpos) & EGG_TB_MODEL_NOT_EDITABLE) == 0);
1409 gtk_action_set_visible (find_action (etoolbar, "RemoveToolbar"), (toolbar != NULL) && (etoolbar->priv->edit_mode > 0));
1410 gtk_action_set_visible (find_action (etoolbar, "RemoveToolItem"), (toolitem != NULL) && editable);
1411 gtk_action_set_visible (find_action (etoolbar, "MoveToolItem"), (toolitem != NULL) && editable);
1415 set_edit_mode (EggEditableToolbar *etoolbar,
1418 EggEditableToolbarPrivate *priv = etoolbar->priv;
1421 i = priv->edit_mode;
1428 g_return_if_fail (priv->edit_mode > 0);
1431 i *= priv->edit_mode;
1435 for (i = get_n_toolbars (etoolbar)-1; i >= 0; i--)
1439 toolbar = get_toolbar_nth (etoolbar, i);
1440 n_items = gtk_toolbar_get_n_items (GTK_TOOLBAR (toolbar));
1442 if (n_items == 0 && priv->edit_mode == 0)
1444 egg_toolbars_model_remove_toolbar (priv->model, i);
1448 for (l = 0; l < n_items; l++)
1452 item = gtk_toolbar_get_nth_item (GTK_TOOLBAR (toolbar), l);
1454 configure_item_cursor (item, etoolbar);
1455 configure_item_sensitivity (item, etoolbar);
1463 egg_editable_toolbar_set_property (GObject *object,
1465 const GValue *value,
1468 EggEditableToolbar *etoolbar = EGG_EDITABLE_TOOLBAR (object);
1472 case PROP_UI_MANAGER:
1473 egg_editable_toolbar_set_ui_manager (etoolbar, g_value_get_object (value));
1475 case PROP_TOOLBARS_MODEL:
1476 egg_editable_toolbar_set_model (etoolbar, g_value_get_object (value));
1479 egg_editable_toolbar_set_selected (etoolbar, g_value_get_object (value));
1481 case PROP_POPUP_PATH:
1482 etoolbar->priv->popup_path = g_strdup (g_value_get_string (value));
1484 case PROP_EDIT_MODE:
1485 set_edit_mode (etoolbar, g_value_get_boolean (value));
1488 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1494 egg_editable_toolbar_get_property (GObject *object,
1499 EggEditableToolbar *etoolbar = EGG_EDITABLE_TOOLBAR (object);
1503 case PROP_UI_MANAGER:
1504 g_value_set_object (value, etoolbar->priv->manager);
1506 case PROP_TOOLBARS_MODEL:
1507 g_value_set_object (value, etoolbar->priv->model);
1510 g_value_set_object (value, etoolbar->priv->selected);
1512 case PROP_EDIT_MODE:
1513 g_value_set_boolean (value, etoolbar->priv->edit_mode>0);
1516 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1522 egg_editable_toolbar_class_init (EggEditableToolbarClass *klass)
1524 GObjectClass *object_class = G_OBJECT_CLASS (klass);
1526 parent_class = g_type_class_peek_parent (klass);
1528 object_class->dispose = egg_editable_toolbar_dispose;
1529 object_class->set_property = egg_editable_toolbar_set_property;
1530 object_class->get_property = egg_editable_toolbar_get_property;
1532 egg_editable_toolbar_signals[ACTION_REQUEST] =
1533 g_signal_new ("action_request",
1534 G_OBJECT_CLASS_TYPE (object_class),
1536 G_STRUCT_OFFSET (EggEditableToolbarClass, action_request),
1537 NULL, NULL, g_cclosure_marshal_VOID__STRING,
1538 G_TYPE_NONE, 1, G_TYPE_STRING);
1540 g_object_class_install_property (object_class,
1542 g_param_spec_object ("ui-manager",
1545 GTK_TYPE_UI_MANAGER,
1546 G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
1547 g_object_class_install_property (object_class,
1548 PROP_TOOLBARS_MODEL,
1549 g_param_spec_object ("model",
1552 EGG_TYPE_TOOLBARS_MODEL,
1553 G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
1554 g_object_class_install_property (object_class,
1556 g_param_spec_object ("selected",
1558 "Selected toolitem",
1560 G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
1562 g_object_class_install_property (object_class,
1564 g_param_spec_string ("popup-path",
1568 G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
1570 g_object_class_install_property (object_class,
1572 g_param_spec_boolean ("edit-mode",
1576 G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
1578 g_type_class_add_private (object_class, sizeof (EggEditableToolbarPrivate));
1582 egg_editable_toolbar_new (GtkUIManager *manager,
1583 const char *popup_path)
1585 return GTK_WIDGET (g_object_new (EGG_TYPE_EDITABLE_TOOLBAR,
1586 "ui-manager", manager,
1587 "popup-path", popup_path,
1592 egg_editable_toolbar_new_with_model (GtkUIManager *manager,
1593 EggToolbarsModel *model,
1594 const char *popup_path)
1596 return GTK_WIDGET (g_object_new (EGG_TYPE_EDITABLE_TOOLBAR,
1597 "ui-manager", manager,
1599 "popup-path", popup_path,
1604 egg_editable_toolbar_get_edit_mode (EggEditableToolbar *etoolbar)
1606 EggEditableToolbarPrivate *priv = etoolbar->priv;
1608 return priv->edit_mode > 0;
1612 egg_editable_toolbar_set_edit_mode (EggEditableToolbar *etoolbar,
1615 set_edit_mode (etoolbar, mode);
1616 g_object_notify (G_OBJECT (etoolbar), "edit-mode");
1620 egg_editable_toolbar_add_visibility (EggEditableToolbar *etoolbar,
1623 etoolbar->priv->visibility_paths = g_list_prepend
1624 (etoolbar->priv->visibility_paths, g_strdup (path));
1628 egg_editable_toolbar_show (EggEditableToolbar *etoolbar,
1631 EggEditableToolbarPrivate *priv = etoolbar->priv;
1632 EggToolbarsModel *model = priv->model;
1635 n_toolbars = egg_toolbars_model_n_toolbars (model);
1636 for (i = 0; i < n_toolbars; i++)
1638 const char *toolbar_name;
1640 toolbar_name = egg_toolbars_model_toolbar_nth (model, i);
1641 if (strcmp (toolbar_name, name) == 0)
1643 gtk_widget_show (get_dock_nth (etoolbar, i));
1649 egg_editable_toolbar_hide (EggEditableToolbar *etoolbar,
1652 EggEditableToolbarPrivate *priv = etoolbar->priv;
1653 EggToolbarsModel *model = priv->model;
1656 n_toolbars = egg_toolbars_model_n_toolbars (model);
1657 for (i = 0; i < n_toolbars; i++)
1659 const char *toolbar_name;
1661 toolbar_name = egg_toolbars_model_toolbar_nth (model, i);
1662 if (strcmp (toolbar_name, name) == 0)
1664 gtk_widget_hide (get_dock_nth (etoolbar, i));
1670 egg_editable_toolbar_set_fixed (EggEditableToolbar *etoolbar,
1671 GtkToolbar *toolbar)
1673 EggEditableToolbarPrivate *priv = etoolbar->priv;
1675 g_return_if_fail (!toolbar || GTK_IS_TOOLBAR (toolbar));
1677 if (priv->fixed_toolbar)
1679 unparent_fixed (etoolbar);
1680 g_object_unref (priv->fixed_toolbar);
1681 priv->fixed_toolbar = NULL;
1686 priv->fixed_toolbar = GTK_WIDGET (toolbar);
1687 gtk_toolbar_set_show_arrow (toolbar, FALSE);
1688 g_object_ref_sink (toolbar);
1691 update_fixed (etoolbar);
1694 #define DEFAULT_ICON_HEIGHT 20
1695 #define DEFAULT_ICON_WIDTH 0
1698 fake_expose_widget (GtkWidget *widget,
1701 GdkWindow *tmp_window;
1702 GdkEventExpose event;
1704 event.type = GDK_EXPOSE;
1705 event.window = pixmap;
1706 event.send_event = FALSE;
1707 event.area = widget->allocation;
1708 event.region = NULL;
1711 tmp_window = widget->window;
1712 widget->window = pixmap;
1713 gtk_widget_send_expose (widget, (GdkEvent *) &event);
1714 widget->window = tmp_window;
1717 /* We should probably experiment some more with this.
1718 * Right now the rendered icon is pretty good for most
1719 * themes. However, the icon is slightly large for themes
1720 * with large toolbar icons.
1723 new_pixbuf_from_widget (GtkWidget *widget)
1727 GtkRequisition requisition;
1728 GtkAllocation allocation;
1734 icon_width = DEFAULT_ICON_WIDTH;
1736 if (!gtk_icon_size_lookup_for_settings (gtk_settings_get_default (),
1737 GTK_ICON_SIZE_LARGE_TOOLBAR,
1741 icon_height = DEFAULT_ICON_HEIGHT;
1744 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1746 gtk_container_add (GTK_CONTAINER (window), widget);
1747 gtk_widget_realize (window);
1748 gtk_widget_show (widget);
1749 gtk_widget_realize (widget);
1750 gtk_widget_map (widget);
1752 /* Gtk will never set the width or height of a window to 0. So setting the width to
1753 * 0 and than getting it will provide us with the minimum width needed to render
1754 * the icon correctly, without any additional window background noise.
1755 * This is needed mostly for pixmap based themes.
1757 gtk_window_set_default_size (GTK_WINDOW (window), icon_width, icon_height);
1758 gtk_window_get_size (GTK_WINDOW (window),&icon_width, &icon_height);
1760 gtk_widget_size_request (window, &requisition);
1763 allocation.width = icon_width;
1764 allocation.height = icon_height;
1765 gtk_widget_size_allocate (window, &allocation);
1766 gtk_widget_size_request (window, &requisition);
1768 /* Create a pixmap */
1769 visual = gtk_widget_get_visual (window);
1770 pixmap = gdk_pixmap_new (NULL, icon_width, icon_height, visual->depth);
1771 gdk_drawable_set_colormap (GDK_DRAWABLE (pixmap), gtk_widget_get_colormap (window));
1773 /* Draw the window */
1774 gtk_widget_ensure_style (window);
1775 g_assert (window->style);
1776 g_assert (window->style->font_desc);
1778 fake_expose_widget (window, pixmap);
1779 fake_expose_widget (widget, pixmap);
1781 pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, icon_width, icon_height);
1782 gdk_pixbuf_get_from_drawable (pixbuf, pixmap, NULL, 0, 0, 0, 0, icon_width, icon_height);
1784 gtk_widget_destroy (window);
1790 new_separator_pixbuf ()
1792 GtkWidget *separator;
1795 separator = gtk_vseparator_new ();
1796 pixbuf = new_pixbuf_from_widget (separator);
1801 update_separator_image (GtkImage *image)
1803 GdkPixbuf *pixbuf = new_separator_pixbuf ();
1804 gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
1805 g_object_unref (pixbuf);
1809 style_set_cb (GtkWidget *widget,
1810 GtkStyle *previous_style,
1814 update_separator_image (image);
1819 _egg_editable_toolbar_new_separator_image (void)
1821 GtkWidget *image = gtk_image_new ();
1822 update_separator_image (GTK_IMAGE (image));
1823 g_signal_connect (G_OBJECT (image), "style_set",
1824 G_CALLBACK (style_set_cb), GTK_IMAGE (image));
1830 egg_editable_toolbar_get_model (EggEditableToolbar *etoolbar)
1832 return etoolbar->priv->model;