diff --git a/src/xfdesktop-icon-view.c b/src/xfdesktop-icon-view.c index 66236613..5340a441 100644 --- a/src/xfdesktop-icon-view.c +++ b/src/xfdesktop-icon-view.c @@ -238,6 +238,9 @@ static gboolean xfdesktop_icon_view_drag_motion(GtkWidget *widget, gint x, gint y, guint time_); +static void xfdesktop_icon_view_drag_leave(GtkWidget *widget, + GdkDragContext *context, + guint time_); static gboolean xfdesktop_icon_view_drag_drop(GtkWidget *widget, GdkDragContext *context, gint x, @@ -414,6 +417,7 @@ xfdesktop_icon_view_class_init(XfdesktopIconViewClass *klass) widget_class->draw = xfdesktop_icon_view_draw; widget_class->drag_begin = xfdesktop_icon_view_drag_begin; widget_class->drag_motion = xfdesktop_icon_view_drag_motion; + widget_class->drag_leave = xfdesktop_icon_view_drag_leave; widget_class->drag_drop = xfdesktop_icon_view_drag_drop; widget_class->drag_data_get = xfdesktop_icon_view_drag_data_get; widget_class->drag_data_received = xfdesktop_icon_view_drag_data_received; @@ -1426,6 +1430,97 @@ xfdesktop_xy_to_rowcol(XfdesktopIconView *icon_view, *col = (x - icon_view->priv->xorigin - icon_view->priv->xmargin) / (CELL_SIZE + icon_view->priv->xspacing); } +static inline void +xfdesktop_icon_view_clear_drag_highlight(XfdesktopIconView *icon_view, + GdkDragContext *context) +{ + cairo_rectangle_int_t *cell_highlight; + + cell_highlight = g_object_get_qdata(G_OBJECT(context), + xfdesktop_cell_highlight_quark); + if(!cell_highlight) + return; + + if(0 == cell_highlight->width || 0 == cell_highlight->height) + return; + + /* remove highlight from icon */ + if(icon_view->priv->item_under_pointer) + icon_view->priv->item_under_pointer = NULL; + + gtk_widget_queue_draw_area(GTK_WIDGET(icon_view), + cell_highlight->x, + cell_highlight->y, + cell_highlight->width, + cell_highlight->height); + + cell_highlight->width = cell_highlight->height = 0; +} + +static inline void +xfdesktop_icon_view_draw_drag_highlight(XfdesktopIconView *icon_view, + GdkDragContext *context, + guint16 row, + guint16 col) +{ + GtkWidget *widget = GTK_WIDGET(icon_view); + GdkWindow *window; + XfdesktopIcon *icon; + gint newx, newy; + cairo_rectangle_int_t *cell_highlight; + cairo_region_t *region; + cairo_t *cr; + GdkDrawingContext *gdc; + GtkStyleContext *style; + + window = gtk_widget_get_window(widget); + icon = xfdesktop_icon_view_icon_in_cell(icon_view, row, col); + + newx = icon_view->priv->xorigin + icon_view->priv->xmargin + col * CELL_SIZE + col * icon_view->priv->xspacing; + newy = icon_view->priv->yorigin + icon_view->priv->ymargin + row * CELL_SIZE + row * icon_view->priv->yspacing; + + cell_highlight = g_object_get_qdata(G_OBJECT(context), + xfdesktop_cell_highlight_quark); + + if(cell_highlight) { + if(newx != cell_highlight->x || newy != cell_highlight->y) + xfdesktop_icon_view_clear_drag_highlight(icon_view, context); + } else { + cell_highlight = g_new0(cairo_rectangle_int_t, 1); + g_object_set_qdata_full(G_OBJECT(context), + xfdesktop_cell_highlight_quark, + cell_highlight, (GDestroyNotify)g_free); + } + + cell_highlight->x = newx; + cell_highlight->y = newy; + cell_highlight->width = cell_highlight->height = CELL_SIZE; + + region = cairo_region_create_rectangle(cell_highlight); + gdc = gdk_window_begin_draw_frame(window, region); + cr = gdk_drawing_context_get_cairo_context(gdc); + + style = gtk_widget_get_style_context(widget); + gtk_style_context_save(style); + gtk_style_context_add_class(style, GTK_STYLE_CLASS_RUBBERBAND); + + gtk_render_frame(style, cr, newx, newy, CELL_SIZE, CELL_SIZE); + + gtk_style_context_remove_class(style, GTK_STYLE_CLASS_RUBBERBAND); + gtk_style_context_restore(style); + + if(icon != NULL) { + /* highlight icon */ + icon_view->priv->item_under_pointer = icon; + + xfdesktop_icon_view_paint_icon(icon_view, icon, cell_highlight, cr); + } + + gdk_window_end_draw_frame(window, gdc); + + cairo_region_destroy(region); +} + static gboolean xfdesktop_icon_view_drag_motion(GtkWidget *widget, GdkDragContext *context, @@ -1490,6 +1585,7 @@ xfdesktop_icon_view_drag_motion(GtkWidget *widget, if(xfdesktop_icon_get_position(sel_icon, &sel_row, &sel_col) && sel_row == hover_row && sel_col == hover_col) { + xfdesktop_icon_view_clear_drag_highlight(icon_view, context); return FALSE; } } @@ -1547,6 +1643,15 @@ xfdesktop_icon_view_drag_motion(GtkWidget *widget, return TRUE; } +static void +xfdesktop_icon_view_drag_leave(GtkWidget *widget, + GdkDragContext *context, + guint time_) +{ + xfdesktop_icon_view_clear_drag_highlight(XFDESKTOP_ICON_VIEW(widget), + context); +} + static void xfdesktop_next_slot(XfdesktopIconView *icon_view, gint16 *col, @@ -1784,6 +1889,13 @@ xfdesktop_icon_view_drag_data_received(GtkWidget *widget, info); } + if(action == 0) + xfdesktop_icon_view_clear_drag_highlight(icon_view, context); + else + xfdesktop_icon_view_draw_drag_highlight(icon_view, context, + icon_view->priv->hover_row, + icon_view->priv->hover_col); + gdk_drag_status(context, action, time_); } }