[gnome-builder] grid: stub out API for doing DnD for text/uri-list
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] grid: stub out API for doing DnD for text/uri-list
- Date: Wed, 13 Dec 2017 09:35:00 +0000 (UTC)
commit 1787506d75ea673febc64daba71b57dd61a2f155
Author: Christian Hergert <chergert redhat com>
Date: Tue Dec 12 19:22:59 2017 -0800
grid: stub out API for doing DnD for text/uri-list
The goal here is to be able to drop a uri-list on a stack. We
also want to be able to drag it into new splits and such, but
that will come in a future patch.
src/libide/editor/ide-editor-view.c | 2 +
src/libide/layout/ide-layout-grid.c | 232 +++++++++++++++++++++++++++++++++++
src/libide/layout/ide-layout-grid.h | 3 +-
3 files changed, 236 insertions(+), 1 deletions(-)
---
diff --git a/src/libide/editor/ide-editor-view.c b/src/libide/editor/ide-editor-view.c
index 5d4467f..ba28eec 100644
--- a/src/libide/editor/ide-editor-view.c
+++ b/src/libide/editor/ide-editor-view.c
@@ -909,6 +909,8 @@ ide_editor_view_init (IdeEditorView *self)
gtk_widget_init_template (GTK_WIDGET (self));
+ gtk_drag_dest_unset (GTK_WIDGET (self->source_view));
+
ide_layout_view_set_can_split (IDE_LAYOUT_VIEW (self), TRUE);
ide_layout_view_set_menu_id (IDE_LAYOUT_VIEW (self), "ide-editor-view-document-menu");
diff --git a/src/libide/layout/ide-layout-grid.c b/src/libide/layout/ide-layout-grid.c
index 943afec..777276e 100644
--- a/src/libide/layout/ide-layout-grid.c
+++ b/src/libide/layout/ide-layout-grid.c
@@ -18,6 +18,8 @@
#define G_LOG_DOMAIN "ide-layout-grid"
+#include <string.h>
+
#include "ide-object.h"
#include "layout/ide-layout-grid.h"
@@ -53,6 +55,13 @@ typedef struct
GArray *stack_info;
/*
+ * This owned reference is our box highlight theatric that we
+ * animate while doing a DnD drop interaction.
+ */
+ DzlBoxTheatric *drag_theatric;
+ DzlAnimation *drag_anim;
+
+ /*
* This unowned reference is simply used to compare to a new focus
* view to see if we have changed our current view. It is not to
* be used directly, only for pointer comparison.
@@ -62,6 +71,16 @@ typedef struct
typedef struct
{
+ IdeLayoutGridColumn *column;
+ IdeLayoutStack *stack;
+ GdkRectangle area;
+ gint drop;
+ gint x;
+ gint y;
+} DropLocate;
+
+typedef struct
+{
IdeLayoutStack *stack;
guint len;
} StackInfo;
@@ -76,9 +95,18 @@ enum {
enum {
CREATE_STACK,
+ CREATE_VIEW,
N_SIGNALS
};
+enum {
+ DROP_ONTO,
+ DROP_ABOVE,
+ DROP_BELOW,
+ DROP_LEFT_OF,
+ DROP_RIGHT_OF,
+};
+
static void list_model_iface_init (GListModelInterface *iface);
G_DEFINE_TYPE_WITH_CODE (IdeLayoutGrid, ide_layout_grid, DZL_TYPE_MULTI_PANED,
@@ -332,6 +360,198 @@ ide_layout_grid_remove (GtkContainer *container,
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CURRENT_COLUMN]);
}
+static inline gboolean
+rect_contains_point (cairo_rectangle_int_t *rect,
+ gint x,
+ gint y)
+{
+ return x >= rect->x &&
+ y >= rect->y &&
+ x <= (rect->x + rect->width) &&
+ y <= (rect->y + rect->height);
+}
+
+static gboolean
+ide_layout_grid_get_drop_area (IdeLayoutGrid *self,
+ gint x,
+ gint y,
+ GdkRectangle *out_area,
+ IdeLayoutGridColumn **out_column,
+ IdeLayoutStack **out_stack,
+ gint *out_drop)
+{
+ GtkAllocation alloc;
+ GtkWidget *column;
+ GtkWidget *stack = NULL;
+
+ g_assert (IDE_IS_LAYOUT_GRID (self));
+ g_assert (out_area != NULL);
+ g_assert (out_column != NULL);
+ g_assert (out_stack != NULL);
+ g_assert (out_drop != NULL);
+
+ gtk_widget_get_allocation (GTK_WIDGET (self), &alloc);
+
+ column = dzl_multi_paned_get_at_point (DZL_MULTI_PANED (self), x + alloc.x, 0);
+ if (column != NULL)
+ stack = dzl_multi_paned_get_at_point (DZL_MULTI_PANED (column), 0, y + alloc.y);
+
+ if (column != NULL && stack != NULL)
+ {
+ GtkAllocation stack_alloc;
+
+ gtk_widget_get_allocation (stack, &stack_alloc);
+
+ gtk_widget_translate_coordinates (stack,
+ GTK_WIDGET (self),
+ 0, 0,
+ &stack_alloc.x, &stack_alloc.y);
+
+ *out_area = stack_alloc;
+ *out_column = IDE_LAYOUT_GRID_COLUMN (column);
+ *out_stack = IDE_LAYOUT_STACK (stack);
+ *out_drop = DROP_ONTO;
+
+ gtk_widget_translate_coordinates (GTK_WIDGET (self), stack, x, y, &x, &y);
+
+ if (FALSE) {}
+ else if (x < (stack_alloc.width / 4))
+ {
+ out_area->y = 0;
+ out_area->height = alloc.height;
+ out_area->width = stack_alloc.width / 4;
+ *out_drop = DROP_LEFT_OF;
+ }
+ else if (x > (stack_alloc.width / 4 * 3))
+ {
+ out_area->y = 0;
+ out_area->height = alloc.height;
+ out_area->x = dzl_cairo_rectangle_x2 (&stack_alloc) - (stack_alloc.width / 4);
+ out_area->width = stack_alloc.width / 4;
+ *out_drop = DROP_RIGHT_OF;
+ }
+ else if (y < (stack_alloc.height / 4))
+ {
+ out_area->height = stack_alloc.height / 4;
+ *out_drop = DROP_ABOVE;
+ }
+ else if (y > (stack_alloc.height / 4 * 3))
+ {
+ out_area->y = dzl_cairo_rectangle_y2 (&stack_alloc) - (stack_alloc.height / 4);
+ out_area->height = stack_alloc.height / 4;
+ *out_drop = DROP_BELOW;
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+ide_layout_grid_drag_motion (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time_)
+{
+ IdeLayoutGrid *self = (IdeLayoutGrid *)widget;
+ IdeLayoutGridPrivate *priv = ide_layout_grid_get_instance_private (self);
+ IdeLayoutGridColumn *column = NULL;
+ IdeLayoutStack *stack = NULL;
+ DzlAnimation *drag_anim;
+ GdkRectangle area = { 0 };
+ GtkAllocation alloc;
+ gint drop = DROP_ONTO;
+
+ g_assert (IDE_IS_LAYOUT_GRID (self));
+ g_assert (GDK_IS_DRAG_CONTEXT (context));
+
+ if (priv->drag_anim != NULL)
+ {
+ dzl_animation_stop (priv->drag_anim);
+ dzl_clear_weak_pointer (&priv->drag_anim);
+ }
+
+ gtk_widget_get_allocation (GTK_WIDGET (self), &alloc);
+
+ if (!ide_layout_grid_get_drop_area (self, x, y, &area, &column, &stack, &drop))
+ return GDK_EVENT_PROPAGATE;
+
+ if (priv->drag_theatric == NULL)
+ {
+ priv->drag_theatric = g_object_new (DZL_TYPE_BOX_THEATRIC,
+ "x", area.x,
+ "y", area.y,
+ "width", area.width,
+ "height", area.height,
+ "alpha", 0.3,
+ "background", "#729fcf",
+ "target", self,
+ NULL);
+ return GDK_EVENT_STOP;
+ }
+
+ drag_anim = dzl_object_animate (priv->drag_theatric,
+ DZL_ANIMATION_EASE_OUT_CUBIC,
+ 100,
+ gtk_widget_get_frame_clock (GTK_WIDGET (self)),
+ "x", area.x,
+ "width", area.width,
+ "y", area.y,
+ "height", area.height,
+ NULL);
+ dzl_set_weak_pointer (&priv->drag_anim, drag_anim);
+
+ gtk_widget_queue_draw (GTK_WIDGET (self));
+
+ return GDK_EVENT_STOP;
+}
+
+static void
+ide_layout_grid_drag_leave (GtkWidget *widget,
+ GdkDragContext *context,
+ guint time_)
+{
+ IdeLayoutGrid *self = (IdeLayoutGrid *)widget;
+ IdeLayoutGridPrivate *priv = ide_layout_grid_get_instance_private (self);
+
+ g_assert (IDE_IS_LAYOUT_GRID (self));
+ g_assert (GDK_IS_DRAG_CONTEXT (context));
+
+ if (priv->drag_anim != NULL)
+ {
+ dzl_animation_stop (priv->drag_anim);
+ dzl_clear_weak_pointer (&priv->drag_anim);
+ }
+
+ g_clear_object (&priv->drag_theatric);
+ gtk_widget_queue_draw (GTK_WIDGET (self));
+}
+
+static gboolean
+ide_layout_grid_drag_failed (GtkWidget *widget,
+ GdkDragContext *context,
+ GtkDragResult result)
+{
+ IdeLayoutGrid *self = (IdeLayoutGrid *)widget;
+ IdeLayoutGridPrivate *priv = ide_layout_grid_get_instance_private (self);
+
+ g_assert (IDE_IS_LAYOUT_GRID (self));
+ g_assert (GDK_IS_DRAG_CONTEXT (context));
+
+ if (priv->drag_anim != NULL)
+ {
+ dzl_animation_stop (priv->drag_anim);
+ dzl_clear_weak_pointer (&priv->drag_anim);
+ }
+
+ g_clear_object (&priv->drag_theatric);
+ gtk_widget_queue_draw (GTK_WIDGET (self));
+
+ return GDK_EVENT_PROPAGATE;
+}
+
static void
ide_layout_grid_grab_focus (GtkWidget *widget)
{
@@ -418,6 +638,9 @@ ide_layout_grid_class_init (IdeLayoutGridClass *klass)
object_class->get_property = ide_layout_grid_get_property;
object_class->set_property = ide_layout_grid_set_property;
+ widget_class->drag_motion = ide_layout_grid_drag_motion;
+ widget_class->drag_leave = ide_layout_grid_drag_leave;
+ widget_class->drag_failed = ide_layout_grid_drag_failed;
widget_class->grab_focus = ide_layout_grid_grab_focus;
widget_class->hierarchy_changed = ide_layout_grid_hierarchy_changed;
@@ -472,6 +695,15 @@ static void
ide_layout_grid_init (IdeLayoutGrid *self)
{
IdeLayoutGridPrivate *priv = ide_layout_grid_get_instance_private (self);
+ static const GtkTargetEntry target_entries[] = {
+ { "text/uri-list", 0, 0 },
+ };
+
+ gtk_drag_dest_set (GTK_WIDGET (self),
+ GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP,
+ target_entries,
+ G_N_ELEMENTS (target_entries),
+ GDK_ACTION_COPY);
priv->stack_info = g_array_new (FALSE, FALSE, sizeof (StackInfo));
diff --git a/src/libide/layout/ide-layout-grid.h b/src/libide/layout/ide-layout-grid.h
index 1ca4b71..e44ccbd 100644
--- a/src/libide/layout/ide-layout-grid.h
+++ b/src/libide/layout/ide-layout-grid.h
@@ -37,9 +37,10 @@ struct _IdeLayoutGridClass
DzlMultiPanedClass parent_class;
IdeLayoutStack *(*create_stack) (IdeLayoutGrid *self);
+ IdeLayoutView *(*create_view) (IdeLayoutGrid *self,
+ const gchar *uri);
/*< private >*/
- gpointer _reserved1;
gpointer _reserved2;
gpointer _reserved3;
gpointer _reserved4;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]