aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorMarco Pesenti Gritti <marco@it.gnome.org>2003-04-01 03:22:58 +0800
committerMarco Pesenti Gritti <mpeseng@src.gnome.org>2003-04-01 03:22:58 +0800
commit7f0ed6fc4aa39684c079b391b28840cfdfacc7af (patch)
tree9f00ef9f7190dc1a541205df5cf320198a7fbf45 /lib
parent8c10e78e46c4427326cc9cb7162aa65346048102 (diff)
downloadgsoc2013-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.
Diffstat (limited to 'lib')
-rw-r--r--lib/egg/eggtoolbar.c246
-rw-r--r--lib/egg/eggtoolbar.h9
-rw-r--r--lib/egg/eggtoolitem.c154
-rw-r--r--lib/egg/eggtoolitem.h8
-rwxr-xr-xlib/widgets/ephy-editable-toolbar.c164
-rwxr-xr-xlib/widgets/ephy-toolbars-group.c20
-rwxr-xr-xlib/widgets/ephy-toolbars-group.h2
7 files changed, 455 insertions, 148 deletions
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,