diff options
author | Marco Pesenti Gritti <marco@it.gnome.org> | 2003-04-01 03:22:58 +0800 |
---|---|---|
committer | Marco Pesenti Gritti <mpeseng@src.gnome.org> | 2003-04-01 03:22:58 +0800 |
commit | 7f0ed6fc4aa39684c079b391b28840cfdfacc7af (patch) | |
tree | 9f00ef9f7190dc1a541205df5cf320198a7fbf45 | |
parent | 8c10e78e46c4427326cc9cb7162aa65346048102 (diff) | |
download | gsoc2013-epiphany-7f0ed6fc4aa39684c079b391b28840cfdfacc7af.tar gsoc2013-epiphany-7f0ed6fc4aa39684c079b391b28840cfdfacc7af.tar.gz gsoc2013-epiphany-7f0ed6fc4aa39684c079b391b28840cfdfacc7af.tar.bz2 gsoc2013-epiphany-7f0ed6fc4aa39684c079b391b28840cfdfacc7af.tar.lz gsoc2013-epiphany-7f0ed6fc4aa39684c079b391b28840cfdfacc7af.tar.xz gsoc2013-epiphany-7f0ed6fc4aa39684c079b391b28840cfdfacc7af.tar.zst gsoc2013-epiphany-7f0ed6fc4aa39684c079b391b28840cfdfacc7af.zip |
Use the new EggToolbar apis. Better drop feedback, separators drag and
2003-03-31 Marco Pesenti Gritti <marco@it.gnome.org>
* lib/egg/eggtoolbar.c: (egg_toolbar_class_init),
(egg_toolbar_init), (egg_toolbar_unrealize), (egg_toolbar_expose),
(egg_toolbar_size_allocate), (find_drop_pos),
(egg_toolbar_drag_leave), (egg_toolbar_drag_motion),
(egg_toolbar_get_item_index), (egg_toolbar_get_show_arrow),
(egg_toolbar_get_drop_index):
* lib/egg/eggtoolbar.h:
* lib/egg/eggtoolitem.c: (egg_tool_item_get_type),
(egg_tool_item_class_init), (create_drag_window),
(egg_tool_item_realize), (egg_tool_item_unrealize),
(egg_tool_item_map), (egg_tool_item_unmap),
(egg_tool_item_size_allocate), (egg_tool_item_set_tooltip),
(egg_tool_item_set_use_drag_window):
* lib/egg/eggtoolitem.h:
* lib/widgets/ephy-editable-toolbar.c: (drag_data_received_cb),
(drag_data_get_cb), (connect_item_drag_source),
(disconnect_item_drag_source), (popup_toolbar_context_menu),
(setup_toolbar), (do_merge), (ephy_editable_toolbar_init),
(hide_editor), (update_editor_sheet), (show_editor):
* lib/widgets/ephy-toolbars-group.c: (add_action),
(ephy_toolbars_group_add_item), (parse_item_list):
* lib/widgets/ephy-toolbars-group.h:
Use the new EggToolbar apis. Better drop feedback,
separators drag and code cleanups.
-rw-r--r-- | ChangeLog | 28 | ||||
-rw-r--r-- | lib/egg/eggtoolbar.c | 246 | ||||
-rw-r--r-- | lib/egg/eggtoolbar.h | 9 | ||||
-rw-r--r-- | lib/egg/eggtoolitem.c | 154 | ||||
-rw-r--r-- | lib/egg/eggtoolitem.h | 8 | ||||
-rwxr-xr-x | lib/widgets/ephy-editable-toolbar.c | 164 | ||||
-rwxr-xr-x | lib/widgets/ephy-toolbars-group.c | 20 | ||||
-rwxr-xr-x | lib/widgets/ephy-toolbars-group.h | 2 |
8 files changed, 483 insertions, 148 deletions
@@ -1,3 +1,31 @@ +2003-03-31 Marco Pesenti Gritti <marco@it.gnome.org> + + * lib/egg/eggtoolbar.c: (egg_toolbar_class_init), + (egg_toolbar_init), (egg_toolbar_unrealize), (egg_toolbar_expose), + (egg_toolbar_size_allocate), (find_drop_pos), + (egg_toolbar_drag_leave), (egg_toolbar_drag_motion), + (egg_toolbar_get_item_index), (egg_toolbar_get_show_arrow), + (egg_toolbar_get_drop_index): + * lib/egg/eggtoolbar.h: + * lib/egg/eggtoolitem.c: (egg_tool_item_get_type), + (egg_tool_item_class_init), (create_drag_window), + (egg_tool_item_realize), (egg_tool_item_unrealize), + (egg_tool_item_map), (egg_tool_item_unmap), + (egg_tool_item_size_allocate), (egg_tool_item_set_tooltip), + (egg_tool_item_set_use_drag_window): + * lib/egg/eggtoolitem.h: + * lib/widgets/ephy-editable-toolbar.c: (drag_data_received_cb), + (drag_data_get_cb), (connect_item_drag_source), + (disconnect_item_drag_source), (popup_toolbar_context_menu), + (setup_toolbar), (do_merge), (ephy_editable_toolbar_init), + (hide_editor), (update_editor_sheet), (show_editor): + * lib/widgets/ephy-toolbars-group.c: (add_action), + (ephy_toolbars_group_add_item), (parse_item_list): + * lib/widgets/ephy-toolbars-group.h: + + Use the new EggToolbar apis. Better drop feedback, + separators drag and code cleanups. + 2003-03-30 David Bordoley <bordoley@msu.edu> * src/bookmarks/ephy-bookmark-properties.c: (build_ui): diff --git a/lib/egg/eggtoolbar.c b/lib/egg/eggtoolbar.c index 7fb5c0605..8d3f058c3 100644 --- a/lib/egg/eggtoolbar.c +++ b/lib/egg/eggtoolbar.c @@ -33,7 +33,7 @@ #include <gtk/gtkradiobutton.h> #include <gtk/gtktoolbar.h> -#define DEFAULT_IPADDING 2 +#define DEFAULT_IPADDING 0 #define DEFAULT_SPACE_SIZE 5 #define DEFAULT_SPACE_STYLE GTK_TOOLBAR_SPACE_LINE @@ -82,6 +82,7 @@ static void egg_toolbar_get_property (GObject *object, 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, @@ -96,6 +97,15 @@ static gboolean egg_toolbar_focus (GtkWidget *widget, static void egg_toolbar_screen_changed (GtkWidget *widget, GdkScreen *previous_screen); +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_add (GtkContainer *container, GtkWidget *widget); static void egg_toolbar_remove (GtkContainer *container, @@ -152,6 +162,9 @@ typedef struct GtkWidget *arrow; gboolean show_arrow; + + gint drop_index; + GdkWindow *drag_highlight; } EggToolbarPrivate; static GtkContainerClass *parent_class = NULL; @@ -209,6 +222,10 @@ egg_toolbar_class_init (EggToolbarClass *klass) 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->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; @@ -354,10 +371,14 @@ egg_toolbar_init (EggToolbar *toolbar) gtk_widget_show (priv->arrow); gtk_container_add (GTK_CONTAINER (priv->button), priv->arrow); - gtk_widget_set_parent (priv->button, GTK_WIDGET (toolbar)); + gtk_widget_set_parent (priv->button, GTK_WIDGET (toolbar)); g_signal_connect (GTK_WIDGET (toolbar), "button_press_event", G_CALLBACK (egg_toolbar_button_press), toolbar); + + /* which child position a drop will occur at */ + priv->drop_index = -1; + priv->drag_highlight = NULL; } static void @@ -485,6 +506,22 @@ egg_toolbar_realize (GtkWidget *widget) widget->style = gtk_style_attach (widget->style, widget->window); } +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 (GTK_WIDGET_CLASS (parent_class)->unrealize) + (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget); +} + static gint egg_toolbar_expose (GtkWidget *widget, GdkEventExpose *event) @@ -508,7 +545,7 @@ egg_toolbar_expose (GtkWidget *widget, GTK_WIDGET_STATE (widget), shadow_type, &event->area, widget, "toolbar", - widget->allocation.x + border_width, + border_width, border_width, widget->allocation.width - border_width, widget->allocation.height - border_width); @@ -532,7 +569,7 @@ egg_toolbar_expose (GtkWidget *widget, gtk_container_propagate_expose (GTK_CONTAINER (widget), priv->button, event); - + return FALSE; } @@ -716,7 +753,10 @@ egg_toolbar_size_allocate (GtkWidget *widget, total_size = 0; number_expandable = 0; space_size = get_space_size (toolbar); - + + gtk_widget_style_get (widget, "internal_padding", &ipadding, NULL); + border_width += ipadding; + available_width = allocation->width - 2 * border_width; available_height = allocation->height - 2 * border_width; if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL) @@ -1151,6 +1191,173 @@ egg_toolbar_screen_changed (GtkWidget *widget, 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, ipadding; + 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; + gtk_widget_style_get (GTK_WIDGET (toolbar), "internal_padding", + &ipadding, NULL); + border_width += ipadding; + + 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_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, + new_pos - 1, border_width, + 2, widget->allocation.height-border_width*2); + } + else + { + gdk_window_move_resize (priv->drag_highlight, + border_width, new_pos - 1, + widget->allocation.width-border_width*2, 2); + } + } + + gdk_window_show (priv->drag_highlight); + gdk_window_raise (priv->drag_highlight); + + gdk_drag_status (context, context->suggested_action, time_); + + return TRUE; +} + static void egg_toolbar_add (GtkContainer *container, @@ -1513,6 +1720,21 @@ egg_toolbar_insert_tool_item (EggToolbar *toolbar, GTK_WIDGET_UNSET_FLAGS (item, GTK_CAN_FOCUS); } +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); + + 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) @@ -1700,6 +1922,20 @@ egg_toolbar_get_show_arrow (EggToolbar *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); + + find_drop_pos (toolbar, x, y, &drop_index, &drop_pos); + + return drop_index; +} + GtkWidget * egg_toolbar_append_item (EggToolbar *toolbar, const char *text, diff --git a/lib/egg/eggtoolbar.h b/lib/egg/eggtoolbar.h index 84d7df6ca..0b07962aa 100644 --- a/lib/egg/eggtoolbar.h +++ b/lib/egg/eggtoolbar.h @@ -89,7 +89,7 @@ struct _EggToolbar guint style_set_connection; guint icon_size_connection; - + guint style_set : 1; guint icon_size_set : 1; }; @@ -124,6 +124,9 @@ void egg_toolbar_insert_tool_item (EggToolbar *toolbar, void egg_toolbar_remove_tool_item (EggToolbar *toolbar, EggToolItem *item); +gint egg_toolbar_get_item_index (EggToolbar *toolbar, + EggToolItem *item); + /* Style functions */ void egg_toolbar_set_show_arrow (EggToolbar *toolbar, gboolean show_arrow); @@ -143,7 +146,9 @@ GtkToolbarStyle egg_toolbar_get_style (EggToolbar *toolbar); GtkIconSize egg_toolbar_get_icon_size (EggToolbar *toolbar); gboolean egg_toolbar_get_tooltips (EggToolbar *toolbar); GList* egg_toolbar_get_tool_items (EggToolbar *toolbar); - +gint egg_toolbar_get_drop_index (EggToolbar *toolbar, + gint x, + gint y); #ifndef EGG_DISABLE_DEPRECATED diff --git a/lib/egg/eggtoolitem.c b/lib/egg/eggtoolitem.c index 59556ffab..8f93ac369 100644 --- a/lib/egg/eggtoolitem.c +++ b/lib/egg/eggtoolitem.c @@ -21,6 +21,7 @@ #include "eggtoolitem.h" #include "eggmarshalers.h" +#include <gtk/gtkseparatormenuitem.h> #ifndef _ # define _(s) (s) @@ -57,6 +58,10 @@ static void egg_tool_item_get_property (GObject *object, GValue *value, GParamSpec *pspec); +static void egg_tool_item_realize (GtkWidget *widget); +static void egg_tool_item_unrealize (GtkWidget *widget); +static void egg_tool_item_map (GtkWidget *widget); +static void egg_tool_item_unmap (GtkWidget *widget); static void egg_tool_item_size_request (GtkWidget *widget, GtkRequisition *requisition); static void egg_tool_item_size_allocate (GtkWidget *widget, @@ -71,7 +76,7 @@ static guint toolitem_signals[LAST_SIGNAL] = { 0 }; GType egg_tool_item_get_type (void) { - static GType type = 0; + static GtkType type = 0; if (!type) { @@ -125,7 +130,11 @@ egg_tool_item_class_init (EggToolItemClass *klass) object_class->set_property = egg_tool_item_set_property; object_class->get_property = egg_tool_item_get_property; - widget_class->size_request = egg_tool_item_size_request; + widget_class->realize = egg_tool_item_realize; + widget_class->unrealize = egg_tool_item_unrealize; + widget_class->map = egg_tool_item_map; + widget_class->unmap = egg_tool_item_unmap; + widget_class->size_request = egg_tool_item_size_request; widget_class->size_allocate = egg_tool_item_size_allocate; klass->create_menu_proxy = egg_tool_item_create_menu_proxy; @@ -280,6 +289,92 @@ egg_tool_item_get_property (GObject *object, } static void +create_drag_window (EggToolItem *toolitem) +{ + GtkWidget *widget; + GdkWindowAttr attributes; + gint attributes_mask, border_width; + + g_return_if_fail (toolitem->use_drag_window == TRUE); + + widget = GTK_WIDGET (toolitem); + border_width = GTK_CONTAINER (toolitem)->border_width; + + 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.wclass = GDK_INPUT_ONLY; + attributes.event_mask = gtk_widget_get_events (widget); + attributes.event_mask |= (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); + + attributes_mask = GDK_WA_X | GDK_WA_Y; + + toolitem->drag_window = gdk_window_new (gtk_widget_get_parent_window (widget), + &attributes, attributes_mask); + gdk_window_set_user_data (toolitem->drag_window, toolitem); +} + +static void +egg_tool_item_realize (GtkWidget *widget) +{ + EggToolItem *toolitem; + + toolitem = EGG_TOOL_ITEM (widget); + GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); + + widget->window = gtk_widget_get_parent_window (widget); + g_object_ref (widget->window); + + if (toolitem->use_drag_window) + create_drag_window(toolitem); + + widget->style = gtk_style_attach (widget->style, widget->window); +} + +static void +egg_tool_item_unrealize (GtkWidget *widget) +{ + EggToolItem *toolitem; + + toolitem = EGG_TOOL_ITEM (widget); + + if (toolitem->drag_window) + { + gdk_window_set_user_data (toolitem->drag_window, NULL); + gdk_window_destroy (toolitem->drag_window); + toolitem->drag_window = NULL; + } + GTK_WIDGET_CLASS (parent_class)->unrealize (widget); +} + +static void +egg_tool_item_map (GtkWidget *widget) +{ + EggToolItem *toolitem; + + toolitem = EGG_TOOL_ITEM (widget); + GTK_WIDGET_CLASS (parent_class)->map (widget); + if (toolitem->drag_window) + { + gdk_window_raise (toolitem->drag_window); + gdk_window_show (toolitem->drag_window); + } +} + +static void +egg_tool_item_unmap (GtkWidget *widget) +{ + EggToolItem *toolitem; + + toolitem = EGG_TOOL_ITEM (widget); + if (toolitem->drag_window) + gdk_window_hide (toolitem->drag_window); + GTK_WIDGET_CLASS (parent_class)->unmap (widget); +} + +static void egg_tool_item_size_request (GtkWidget *widget, GtkRequisition *requisition) { @@ -296,19 +391,30 @@ static void egg_tool_item_size_allocate (GtkWidget *widget, GtkAllocation *allocation) { - GtkBin *bin = GTK_BIN (widget); + EggToolItem *toolitem = EGG_TOOL_ITEM (widget); GtkAllocation child_allocation; + gint border_width; + GtkWidget *child; widget->allocation = *allocation; - - if (bin->child && GTK_WIDGET_VISIBLE (bin->child)) + border_width = GTK_CONTAINER (widget)->border_width; + + if (toolitem->drag_window && GTK_WIDGET_REALIZED (widget)) + gdk_window_move_resize (toolitem->drag_window, + widget->allocation.x + border_width, + widget->allocation.y + border_width, + widget->allocation.width - border_width * 2, + widget->allocation.height - border_width * 2); + + child = GTK_BIN (toolitem)->child; + if (child && GTK_WIDGET_VISIBLE (child)) { - child_allocation.x = allocation->x + GTK_CONTAINER (widget)->border_width; - child_allocation.y = allocation->y + GTK_CONTAINER (widget)->border_width; - child_allocation.width = allocation->width - GTK_CONTAINER (widget)->border_width * 2; - child_allocation.height = allocation->height - GTK_CONTAINER (widget)->border_width * 2; + child_allocation.x = allocation->x + border_width; + child_allocation.y = allocation->y + border_width; + child_allocation.width = allocation->width - border_width * 2; + child_allocation.height = allocation->height - border_width * 2; - gtk_widget_size_allocate (bin->child, &child_allocation); + gtk_widget_size_allocate (child, &child_allocation); } } @@ -414,3 +520,31 @@ egg_tool_item_set_tooltip (EggToolItem *tool_item, g_signal_emit (tool_item, toolitem_signals[SET_TOOLTIP], 0, tooltips, tip_text, tip_private); } + +void +egg_tool_item_set_use_drag_window (EggToolItem *toolitem, + gboolean use_drag_window) +{ + g_return_if_fail (EGG_IS_TOOL_ITEM (toolitem)); + + toolitem->use_drag_window = use_drag_window; + + if (use_drag_window) + { + if (!toolitem->drag_window && GTK_WIDGET_REALIZED (toolitem)) + { + create_drag_window(toolitem); + if (GTK_WIDGET_MAPPED (toolitem)) + gdk_window_show (toolitem->drag_window); + } + } + else + { + if (toolitem->drag_window) + { + gdk_window_set_user_data (toolitem->drag_window, NULL); + gdk_window_destroy (toolitem->drag_window); + toolitem->drag_window = NULL; + } + } +} diff --git a/lib/egg/eggtoolitem.h b/lib/egg/eggtoolitem.h index 222e095f9..4c4fea46a 100644 --- a/lib/egg/eggtoolitem.h +++ b/lib/egg/eggtoolitem.h @@ -45,12 +45,15 @@ struct _EggToolItem gchar *tip_text; gchar *tip_private; - + + GdkWindow *drag_window; + guint visible_horizontal : 1; guint visible_vertical : 1; guint homogeneous : 1; guint expandable : 1; guint pack_end : 1; + guint use_drag_window : 1; }; struct _EggToolItemClass @@ -94,5 +97,8 @@ void egg_tool_item_set_tooltip (EggToolItem *tool_item, GtkTooltips *tooltips, const gchar *tip_text, const gchar *tip_private); +void egg_tool_item_set_use_drag_window (EggToolItem *toolitem, + gboolean use_drag_window); + #endif /* __EGG_TOOL_ITEM_H__ */ diff --git a/lib/widgets/ephy-editable-toolbar.c b/lib/widgets/ephy-editable-toolbar.c index 2af974a87..e65015d3a 100755 --- a/lib/widgets/ephy-editable-toolbar.c +++ b/lib/widgets/ephy-editable-toolbar.c @@ -29,19 +29,27 @@ #include <libgnome/gnome-i18n.h> #include <string.h> +enum +{ + X_TOOLBAR_ITEM +}; + static GtkTargetEntry dest_drag_types [] = { - { "EPHY_TOOLBAR_BUTTON", 0, 0 }, + { "application/x-toolbar-item", 0, X_TOOLBAR_ITEM }, /* FIXME generic way to add types */ - { EPHY_DND_URL_TYPE, 0, 1 }, + { EPHY_DND_URL_TYPE, 0, 2 }, { EPHY_DND_TOPIC_TYPE, 0, 2 } }; +static int n_dest_drag_types = G_N_ELEMENTS (dest_drag_types); static GtkTargetEntry source_drag_types [] = { - { "EPHY_TOOLBAR_BUTTON", 0, 0 } + { "application/x-toolbar-item", 0, X_TOOLBAR_ITEM }, }; +static int n_source_drag_types = G_N_ELEMENTS (source_drag_types); + enum { RESPONSE_ADD_TOOLBAR @@ -238,31 +246,20 @@ drag_data_received_cb (GtkWidget *widget, EphyEditableToolbar *etoolbar) { EphyToolbarsToolbar *toolbar; - EphyToolbarsToolbar *parent; - EphyToolbarsItem *sibling; const char *type = NULL; GdkAtom target; EggAction *action = NULL; + int pos; g_return_if_fail (IS_EPHY_EDITABLE_TOOLBAR (etoolbar)); - LOG ("Drag data received") + LOG ("Drag data received %s", selection_data->data) toolbar = (EphyToolbarsToolbar *)g_object_get_data (G_OBJECT (widget), "toolbar_data"); + pos = egg_toolbar_get_drop_index (EGG_TOOLBAR (widget), x, y); - if (!toolbar) - { - sibling = (EphyToolbarsItem *)g_object_get_data (G_OBJECT (widget), "item_data"); - g_return_if_fail (sibling != NULL); - parent = sibling->parent; - } - else - { - sibling = NULL; - parent = toolbar; - } - - g_return_if_fail (parent != NULL); + /* HACK placeholder are implemented as separators */ + pos = pos/3 + 1; target = gtk_drag_dest_find_target (widget, context, NULL); if (target == gdk_atom_intern (EPHY_DND_URL_TYPE, FALSE)) @@ -293,11 +290,18 @@ drag_data_received_cb (GtkWidget *widget, if (action) { - ephy_toolbars_group_add_item (etoolbar->priv->group, parent, sibling, + ephy_toolbars_group_add_item (etoolbar->priv->group, toolbar, pos, action->name); etoolbar->priv->toolbars_dirty = TRUE; - queue_ui_update (etoolbar); } + else if (strcmp (selection_data->data, "separator") == 0) + { + ephy_toolbars_group_add_item (etoolbar->priv->group, toolbar, pos, + "separator"); + etoolbar->priv->toolbars_dirty = TRUE; + } + + queue_ui_update (etoolbar); } static void @@ -331,9 +335,17 @@ drag_data_get_cb (GtkWidget *widget, g_return_if_fail (IS_EPHY_EDITABLE_TOOLBAR (etoolbar)); action = EGG_ACTION (g_object_get_data (G_OBJECT (widget), "egg-action")); - target = action->name; - LOG ("Drag data get %s", action->name); + if (action) + { + LOG ("Drag data get %s", action->name); + target = action->name; + } + else + { + LOG ("Drag data get %s", separator); + target = "separator"; + } gtk_selection_data_set (selection_data, selection_data->target, @@ -431,6 +443,13 @@ connect_item_drag_source (EphyToolbarsItem *item, EphyEditableToolbar *etoolbar) g_object_set_data (G_OBJECT (toolitem), "drag_source_set", GINT_TO_POINTER (TRUE)); + egg_tool_item_set_use_drag_window (EGG_TOOL_ITEM (toolitem), TRUE); + + g_object_set_data (G_OBJECT (toolitem), "item_data", item); + + gtk_drag_source_set (toolitem, GDK_BUTTON1_MASK, + source_drag_types, n_source_drag_types, + GDK_ACTION_MOVE); g_signal_connect (toolitem, "drag_data_get", G_CALLBACK (drag_data_get_cb), etoolbar); @@ -455,6 +474,8 @@ disconnect_item_drag_source (EphyToolbarsItem *item, EphyEditableToolbar *etoolb g_object_set_data (G_OBJECT (toolitem), "drag_source_set", GINT_TO_POINTER (FALSE)); + egg_tool_item_set_use_drag_window (EGG_TOOL_ITEM (toolitem), FALSE); + g_signal_handlers_disconnect_by_func (toolitem, G_CALLBACK (drag_data_get_cb), etoolbar); @@ -524,7 +545,7 @@ static void popup_toolbar_context_menu (EggToolbar *toolbar, ContextMenuData *data) { GtkWidget *widget; - + widget = egg_menu_merge_get_widget (data->etoolbar->priv->popup_merge, "/popups/EphyToolbarPopup"); @@ -556,7 +577,7 @@ setup_toolbar (EphyToolbarsToolbar *toolbar, EphyEditableToolbar *etoolbar) g_object_set_data (G_OBJECT (widget), "drag_dest_set", GINT_TO_POINTER (TRUE)); gtk_drag_dest_set (widget, GTK_DEST_DEFAULT_ALL, - dest_drag_types, 3, + dest_drag_types, n_dest_drag_types, GDK_ACTION_MOVE | GDK_ACTION_COPY); g_signal_connect (widget, "drag_data_received", G_CALLBACK (drag_data_received_cb), @@ -582,38 +603,6 @@ setup_toolbar (EphyToolbarsToolbar *toolbar, EphyEditableToolbar *etoolbar) } static void -setup_item (EphyToolbarsItem *item, EphyEditableToolbar *etoolbar) -{ - GtkWidget *toolitem; - char *path; - - g_return_if_fail (IS_EPHY_EDITABLE_TOOLBAR (etoolbar)); - g_return_if_fail (item != NULL); - - path = ephy_toolbars_group_get_path (etoolbar->priv->group, item); - g_return_if_fail (path != NULL); - - toolitem = get_item_widget (etoolbar, item); - g_object_set_data (G_OBJECT (toolitem), "item_data", item); - - LOG ("Setup drag dest for toolbar item %s %p", path, toolitem); - - if (!g_object_get_data (G_OBJECT (toolitem), "drag_dest_set")) - { - g_object_set_data (G_OBJECT (toolitem), "drag_dest_set", - GINT_TO_POINTER (TRUE)); - gtk_drag_dest_set (toolitem, GTK_DEST_DEFAULT_ALL, - dest_drag_types, 3, - GDK_ACTION_COPY | GDK_ACTION_MOVE); - g_signal_connect (toolitem, "drag_data_received", - G_CALLBACK (drag_data_received_cb), - etoolbar); - } - - g_free (path); -} - -static void ensure_toolbar_min_size (EphyToolbarsToolbar *toolbar, EphyEditableToolbar *t) { GtkWidget *widget; @@ -664,9 +653,6 @@ do_merge (EphyEditableToolbar *t) ephy_toolbars_group_foreach_toolbar (t->priv->group, (EphyToolbarsGroupForeachToolbarFunc) setup_toolbar, t); - ephy_toolbars_group_foreach_item (t->priv->group, - (EphyToolbarsGroupForeachItemFunc) - setup_item, t); if (t->priv->edit_mode) { @@ -827,9 +813,9 @@ ephy_editable_toolbar_init (EphyEditableToolbar *t) { ephy_toolbar_popups[i].user_data = t; } - + t->priv->popup_merge = egg_menu_merge_new (); - + t->priv->popup_action_group = egg_action_group_new ("ToolbarPopupActions"); egg_action_group_add_actions (t->priv->popup_action_group, ephy_toolbar_popups, @@ -887,7 +873,6 @@ hide_editor (EphyEditableToolbar *etoolbar) { g_return_if_fail (IS_EPHY_EDITABLE_TOOLBAR (etoolbar)); - gtk_grab_remove (GTK_WIDGET (etoolbar->priv->editor)); gtk_widget_hide (GTK_WIDGET (etoolbar->priv->editor)); } @@ -1050,7 +1035,7 @@ update_editor_sheet (EphyEditableToolbar *etoolbar) gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (etoolbar->priv->scrolled_window), table); gtk_drag_dest_set (table, GTK_DEST_DEFAULT_ALL, - dest_drag_types, 3, GDK_ACTION_MOVE); + dest_drag_types, n_dest_drag_types, GDK_ACTION_MOVE); g_signal_connect (table, "drag_data_received", G_CALLBACK (editor_drag_data_received_cb), etoolbar); @@ -1120,52 +1105,6 @@ update_editor_sheet (EphyEditableToolbar *etoolbar) g_list_free (to_drag); } -static gboolean -button_press_cb (GtkWidget *w, - GdkEvent *event, - EphyEditableToolbar *etoolbar) -{ - GtkWidget *widget; - GtkWidget *toolitem; - - g_return_val_if_fail (IS_EPHY_EDITABLE_TOOLBAR (etoolbar), FALSE); - - widget = gtk_get_event_widget (event); - toolitem = gtk_widget_get_ancestor (widget, EGG_TYPE_TOOL_ITEM); - - if (toolitem == NULL && - event->type == GDK_BUTTON_PRESS && - EGG_IS_TOOLBAR (widget)) - { - if (event->button.button == 3) - { - gtk_widget_event (widget, event); - return FALSE; - } - else - { - gtk_drag_begin (widget, - gtk_target_list_new (source_drag_types, 1), - GDK_ACTION_MOVE, 1, event); - return TRUE; - } - } - else if (toolitem == NULL) return FALSE; - - switch (event->type) - { - case GDK_BUTTON_PRESS: - gtk_drag_begin (toolitem, - gtk_target_list_new (source_drag_types, 1), - GDK_ACTION_MOVE, 1, event); - return TRUE; - default: - break; - } - - return FALSE; -} - static void show_editor (EphyEditableToolbar *etoolbar) { @@ -1175,11 +1114,6 @@ show_editor (EphyEditableToolbar *etoolbar) g_return_if_fail (editor != NULL); gtk_widget_show (GTK_WIDGET (editor)); - gtk_grab_add (editor); - - g_signal_connect (editor, "button_press_event", - G_CALLBACK (button_press_cb), - etoolbar); } static void diff --git a/lib/widgets/ephy-toolbars-group.c b/lib/widgets/ephy-toolbars-group.c index 0a11b6285..9a1d47528 100755 --- a/lib/widgets/ephy-toolbars-group.c +++ b/lib/widgets/ephy-toolbars-group.c @@ -179,7 +179,7 @@ free_item_node (EphyToolbarsItem *item) static void add_action (EphyToolbarsGroup *t, GNode *parent, - GNode *sibling, + int pos, const char *name) { EphyToolbarsItem *item; @@ -193,17 +193,16 @@ add_action (EphyToolbarsGroup *t, item->parent = parent->data; node = g_node_new (item); - g_node_insert_before (parent, sibling, node); + g_node_insert (parent, pos, node); } void ephy_toolbars_group_add_item (EphyToolbarsGroup *t, EphyToolbarsToolbar *parent, - EphyToolbarsItem *sibling, + int pos, const char *name) { GNode *parent_node; - GNode *sibling_node = NULL; g_return_if_fail (IS_EPHY_TOOLBARS_GROUP (t)); g_return_if_fail (parent != NULL); @@ -211,14 +210,7 @@ ephy_toolbars_group_add_item (EphyToolbarsGroup *t, parent_node = g_node_find (t->priv->toolbars, G_IN_ORDER, G_TRAVERSE_ALL, parent); - if (sibling) - { - sibling_node = g_node_find (t->priv->toolbars, G_IN_ORDER, - G_TRAVERSE_ALL, sibling); - g_return_if_fail (sibling_node != NULL); - } - - add_action (t, parent_node, sibling_node, name); + add_action (t, parent_node, pos, name); toolbars_group_save (t); @@ -237,13 +229,13 @@ parse_item_list (EphyToolbarsGroup *t, xmlChar *verb; verb = xmlGetProp (child, "verb"); - add_action (t, parent, NULL, verb); + add_action (t, parent, -1, verb); xmlFree (verb); } else if (xmlStrEqual (child->name, "separator")) { - add_action (t, parent, NULL, "separator"); + add_action (t, parent, -1, "separator"); } child = child->next; diff --git a/lib/widgets/ephy-toolbars-group.h b/lib/widgets/ephy-toolbars-group.h index 8be71cb23..1d1c12a7d 100755 --- a/lib/widgets/ephy-toolbars-group.h +++ b/lib/widgets/ephy-toolbars-group.h @@ -80,7 +80,7 @@ EphyToolbarsToolbar *ephy_toolbars_group_add_toolbar (EphyToolbarsGroup *t); void ephy_toolbars_group_add_item (EphyToolbarsGroup *t, EphyToolbarsToolbar *parent, - EphyToolbarsItem *sibling, + int pos, const char *name); void ephy_toolbars_group_remove_toolbar (EphyToolbarsGroup *t, |