summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErnestas Kulik <ernestask@gnome.org>2018-07-25 15:44:08 +0300
committerErnestas Kulik <ekulik@redhat.com>2019-06-29 14:33:41 +0200
commita0c32d90a3fb8ad2604e68e2959d804e62638252 (patch)
tree5bd7a51299a344b68adfe871b24c41640e36e201
parent08f2c09cb6d2c0b6f46ab79b19770e7af0020702 (diff)
downloadnautilus-a0c32d90a3fb8ad2604e68e2959d804e62638252.tar.gz
canvas-dnd: Fix DnD shadows
-rw-r--r--src/nautilus-canvas-dnd.c153
-rw-r--r--src/nautilus-canvas-dnd.h4
-rw-r--r--src/nautilus-selection-canvas-item.c30
3 files changed, 82 insertions, 105 deletions
diff --git a/src/nautilus-canvas-dnd.c b/src/nautilus-canvas-dnd.c
index c43ac5e4c..a73aecedf 100644
--- a/src/nautilus-canvas-dnd.c
+++ b/src/nautilus-canvas-dnd.c
@@ -135,6 +135,9 @@ create_selection_shadow (NautilusCanvasContainer *container,
x2 = x1 + item->icon_width;
y2 = y1 + item->icon_height;
+ eel_canvas_w2c (canvas, x1, y1, &x1, &y1);
+ eel_canvas_w2c (canvas, x2, y2, &x2, &y2);
+
if (x2 >= min_x && x1 <= max_x && y2 >= min_y && y1 <= max_y)
{
eel_canvas_item_new
@@ -151,20 +154,6 @@ create_selection_shadow (NautilusCanvasContainer *container,
return EEL_CANVAS_ITEM (group);
}
-/* Set the affine instead of the x and y position.
- * Simple, and setting x and y was broken at one point.
- */
-static void
-set_shadow_position (EelCanvasItem *shadow,
- double x,
- double y)
-{
- eel_canvas_item_set (shadow,
- "x", x, "y", y,
- NULL);
-}
-
-
/* Source-side handling of the drag. */
/* iteration glue struct */
@@ -176,29 +165,6 @@ typedef struct
} CanvasGetDataBinderContext;
static void
-canvas_rect_world_to_widget (EelCanvas *canvas,
- EelDRect *world_rect,
- EelIRect *widget_rect)
-{
- EelDRect window_rect;
- GtkAdjustment *hadj, *vadj;
-
- hadj = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (canvas));
- vadj = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (canvas));
-
- eel_canvas_world_to_window (canvas,
- world_rect->x0, world_rect->y0,
- &window_rect.x0, &window_rect.y0);
- eel_canvas_world_to_window (canvas,
- world_rect->x1, world_rect->y1,
- &window_rect.x1, &window_rect.y1);
- widget_rect->x0 = (int) window_rect.x0 - gtk_adjustment_get_value (hadj);
- widget_rect->y0 = (int) window_rect.y0 - gtk_adjustment_get_value (vadj);
- widget_rect->x1 = (int) window_rect.x1 - gtk_adjustment_get_value (hadj);
- widget_rect->y1 = (int) window_rect.y1 - gtk_adjustment_get_value (vadj);
-}
-
-static void
canvas_widget_to_world (EelCanvas *canvas,
double widget_x,
double widget_y,
@@ -217,10 +183,9 @@ icon_get_data_binder (NautilusCanvasIcon *icon,
{
CanvasGetDataBinderContext *context;
EelDRect world_rect;
- EelIRect widget_rect;
- char *uri;
+ g_autofree char *uri = NULL;
NautilusCanvasContainer *container;
- NautilusFile *file;
+ g_autoptr (NautilusFile) file = NULL;
context = (CanvasGetDataBinderContext *) data;
@@ -230,8 +195,6 @@ icon_get_data_binder (NautilusCanvasIcon *icon,
world_rect = nautilus_canvas_item_get_icon_rectangle (icon->item);
- canvas_rect_world_to_widget (EEL_CANVAS (container), &world_rect, &widget_rect);
-
uri = nautilus_canvas_container_get_icon_uri (container, icon);
file = nautilus_file_get_by_uri (uri);
g_free (uri);
@@ -240,28 +203,17 @@ icon_get_data_binder (NautilusCanvasIcon *icon,
if (uri == NULL)
{
g_warning ("no URI for one of the iterated icons");
- nautilus_file_unref (file);
return TRUE;
}
- widget_rect = eel_irect_offset_by (widget_rect,
- -container->details->dnd_info->drag_info.start_x,
- -container->details->dnd_info->drag_info.start_y);
-
- widget_rect = eel_irect_scale_by (widget_rect,
- 1 / EEL_CANVAS (container)->pixels_per_unit);
-
/* pass the uri, mouse-relative x/y and icon width/height */
context->iteratee (uri,
- (int) widget_rect.x0,
- (int) widget_rect.y0,
- widget_rect.x1 - widget_rect.x0,
- widget_rect.y1 - widget_rect.y0,
+ world_rect.x0,
+ world_rect.y0,
+ world_rect.x1 - world_rect.x0,
+ world_rect.y1 - world_rect.y0,
context->iteratee_data);
- g_free (uri);
- nautilus_file_unref (file);
-
return TRUE;
}
@@ -341,7 +293,6 @@ nautilus_canvas_container_position_shadow (NautilusCanvasContainer *container,
int y)
{
EelCanvasItem *shadow;
- double world_x, world_y;
shadow = container->details->dnd_info->shadow;
if (shadow == NULL)
@@ -349,10 +300,14 @@ nautilus_canvas_container_position_shadow (NautilusCanvasContainer *container,
return;
}
- canvas_widget_to_world (EEL_CANVAS (container), x, y,
- &world_x, &world_y);
+ x -= container->details->dnd_info->drag_info.start_x;
+ y -= container->details->dnd_info->drag_info.start_y;
- set_shadow_position (shadow, world_x, world_y);
+ /* This is used as an offset when drawing the selection item.
+ * Offsetting by the position of the cursor would be a bit too much,
+ * so we only take the delta from the start position.
+ */
+ eel_canvas_item_set (shadow, "x", (double) x, "y", (double) y, NULL);
eel_canvas_item_show (shadow);
}
@@ -453,6 +408,30 @@ nautilus_canvas_container_ensure_drag_data (NautilusCanvasContainer *container,
}
static void
+remove_hover_timer (NautilusCanvasDndInfo *dnd_info)
+{
+ if (dnd_info->hover_id != 0)
+ {
+ g_source_remove (dnd_info->hover_id);
+ dnd_info->hover_id = 0;
+ }
+}
+
+static void
+nautilus_canvas_container_free_drag_data (NautilusCanvasContainer *container)
+{
+ NautilusCanvasDndInfo *dnd_info;
+
+ dnd_info = container->details->dnd_info;
+
+ g_clear_pointer (&dnd_info->shadow, eel_canvas_item_destroy);
+ g_clear_pointer (&dnd_info->drag_info.selection_data, gtk_selection_data_free);
+ g_clear_pointer (&dnd_info->target_uri, g_free);
+
+ remove_hover_timer (dnd_info);
+}
+
+static void
drag_end_callback (GtkWidget *widget,
GdkDrag *context,
gpointer data)
@@ -474,6 +453,8 @@ drag_end_callback (GtkWidget *widget,
container->details->dnd_source_info->selection_cache = NULL;
nautilus_window_end_dnd (window, context);
+
+ nautilus_canvas_container_free_drag_data (container);
}
static NautilusCanvasIcon *
@@ -952,30 +933,6 @@ nautilus_canvas_dnd_update_drop_target (NautilusCanvasContainer *container,
}
static void
-remove_hover_timer (NautilusCanvasDndInfo *dnd_info)
-{
- if (dnd_info->hover_id != 0)
- {
- g_source_remove (dnd_info->hover_id);
- dnd_info->hover_id = 0;
- }
-}
-
-static void
-nautilus_canvas_container_free_drag_data (NautilusCanvasContainer *container)
-{
- NautilusCanvasDndInfo *dnd_info;
-
- dnd_info = container->details->dnd_info;
-
- g_clear_pointer (&dnd_info->shadow, eel_canvas_item_destroy);
- g_clear_pointer (&dnd_info->drag_info.selection_data, gtk_selection_data_free);
- g_clear_pointer (&dnd_info->target_uri, g_free);
-
- remove_hover_timer (dnd_info);
-}
-
-static void
drag_leave_callback (GtkWidget *widget,
GdkDrop *drop,
gpointer data)
@@ -1016,6 +973,9 @@ drag_begin_callback (GtkWidget *widget,
start_y = container->details->dnd_info->drag_info.start_y +
gtk_adjustment_get_value (gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (container)));
+ container->details->dnd_info->x = start_x;
+ container->details->dnd_info->y = start_y;
+
paintable = nautilus_canvas_item_get_drag_paintable (container->details->drag_icon->item);
/* compute the image's offset */
@@ -1162,6 +1122,9 @@ drag_motion_callback (GtkWidget *widget,
container = NAUTILUS_CANVAS_CONTAINER (widget);
+ container->details->dnd_info->x = x;
+ container->details->dnd_info->y = y;
+
nautilus_canvas_container_ensure_drag_data (container, drop);
nautilus_canvas_container_position_shadow (container, x, y);
nautilus_canvas_dnd_update_drop_target (container, drop, x, y);
@@ -1206,8 +1169,8 @@ drag_drop_callback (GtkWidget *widget,
* make sure it is going to be called at least once.
*/
dnd_info->drag_info.drop_occurred = TRUE;
- dnd_info->drop_x = x;
- dnd_info->drop_y = y;
+ dnd_info->x = x;
+ dnd_info->y = y;
get_data_on_first_target_we_support (widget, drop, x, y);
@@ -1261,8 +1224,8 @@ drag_data_received_callback (GtkWidget *widget,
{
nautilus_canvas_container_dropped_canvas_feedback (widget,
data,
- dnd_info->drop_x,
- dnd_info->drop_y);
+ dnd_info->x,
+ dnd_info->y);
}
/* this is the second use case of this callback.
@@ -1285,8 +1248,8 @@ drag_data_received_callback (GtkWidget *widget,
receive_dropped_text (container,
(char *) text,
drop,
- dnd_info->drop_x,
- dnd_info->drop_y);
+ dnd_info->x,
+ dnd_info->y);
success = TRUE;
}
else if (gtk_selection_data_targets_include_uri (data))
@@ -1294,8 +1257,8 @@ drag_data_received_callback (GtkWidget *widget,
receive_dropped_uri_list (container,
(char *) gtk_selection_data_get_data (data),
drop,
- dnd_info->drop_x,
- dnd_info->drop_y);
+ dnd_info->x,
+ dnd_info->y);
success = TRUE;
}
else if (gdk_content_formats_contain_mime_type (formats,
@@ -1303,8 +1266,8 @@ drag_data_received_callback (GtkWidget *widget,
{
nautilus_canvas_container_receive_dropped_icons (container,
drop,
- dnd_info->drop_x,
- dnd_info->drop_y);
+ dnd_info->x,
+ dnd_info->y);
}
if (success)
diff --git a/src/nautilus-canvas-dnd.h b/src/nautilus-canvas-dnd.h
index b200ba26a..a094068d0 100644
--- a/src/nautilus-canvas-dnd.h
+++ b/src/nautilus-canvas-dnd.h
@@ -40,8 +40,8 @@ typedef struct {
EelCanvasItem *shadow;
guint hover_id;
- int drop_x;
- int drop_y;
+ int x;
+ int y;
} NautilusCanvasDndInfo;
diff --git a/src/nautilus-selection-canvas-item.c b/src/nautilus-selection-canvas-item.c
index 6d9dca17b..3c74b8d4d 100644
--- a/src/nautilus-selection-canvas-item.c
+++ b/src/nautilus-selection-canvas-item.c
@@ -64,28 +64,42 @@ nautilus_selection_canvas_item_snapshot (EelCanvasItem *item,
int x2;
int y2;
GtkStyleContext *context;
+ int x_offset;
+ int y_offset;
self = NAUTILUS_SELECTION_CANVAS_ITEM (item);
- x1 = self->priv->x1;
- y1 = self->priv->y1;
- x2 = self->priv->x2;
- y2 = self->priv->y2;
+ x1 = MIN (self->priv->x1, self->priv->x2);
+ y1 = MIN (self->priv->y1, self->priv->y2);
+ x2 = MAX (self->priv->x1, self->priv->x2);
+ y2 = MAX (self->priv->y1, self->priv->y2);
+ context = gtk_widget_get_style_context (GTK_WIDGET (item->canvas));
+ if (EEL_IS_CANVAS_GROUP (item->parent))
+ {
+ EelCanvasGroup *group;
+
+ group = EEL_CANVAS_GROUP (item->parent);
- if (x2 <= x1 || y2 <= y1)
+ x_offset = group->xpos;
+ y_offset = group->ypos;
+ }
+ else
{
- return;
+ x_offset = 0;
+ y_offset = 0;
}
- context = gtk_widget_get_style_context (GTK_WIDGET (item->canvas));
-
gtk_style_context_save (context);
gtk_style_context_add_class (context, GTK_STYLE_CLASS_RUBBERBAND);
+ gtk_snapshot_offset (snapshot, x_offset, y_offset);
+
gtk_snapshot_render_background (snapshot, context, x1, y1, x2 - x1, y2 - y1);
gtk_snapshot_render_frame (snapshot, context, x1, y1, x2 - x1, y2 - y1);
+ gtk_snapshot_offset (snapshot, -x_offset, -y_offset);
+
gtk_style_context_restore (context);
}