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 /lib/egg/eggtoolbar.c | |
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.
Diffstat (limited to 'lib/egg/eggtoolbar.c')
-rw-r--r-- | lib/egg/eggtoolbar.c | 246 |
1 files changed, 241 insertions, 5 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, |