[libdazzle] tree: track the drop node during DnD motion
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libdazzle] tree: track the drop node during DnD motion
- Date: Tue, 5 Dec 2017 10:22:57 +0000 (UTC)
commit add198486f4fc421a608993a87a862f945c69167
Author: Christian Hergert <chergert redhat com>
Date: Tue Dec 5 02:10:52 2017 -0800
tree: track the drop node during DnD motion
This allows us to keep track of where we are dropping things and
the position relative to the node for the drop. That can be used
when doing DnD operations that we'll pass off to the builders.
src/tree/dzl-tree-private.h | 2 +
src/tree/dzl-tree.c | 111 +++++++++++++++++++++++++++++++++++++++++--
2 files changed, 108 insertions(+), 5 deletions(-)
---
diff --git a/src/tree/dzl-tree-private.h b/src/tree/dzl-tree-private.h
index 956ab13..f7a5b4e 100644
--- a/src/tree/dzl-tree-private.h
+++ b/src/tree/dzl-tree-private.h
@@ -42,6 +42,8 @@ void _dzl_tree_insert_sorted (DzlTree
gpointer user_data);
void _dzl_tree_remove (DzlTree *self,
DzlTreeNode *node);
+DzlTreeNode *_dzl_tree_get_drop_node (DzlTree *self,
+ DzlTreeDropPosition *pos);
GPtrArray *_dzl_tree_get_builders (DzlTree *self);
gboolean _dzl_tree_get_iter (DzlTree *self,
DzlTreeNode *node,
diff --git a/src/tree/dzl-tree.c b/src/tree/dzl-tree.c
index a10a1a7..25f9e19 100644
--- a/src/tree/dzl-tree.c
+++ b/src/tree/dzl-tree.c
@@ -38,6 +38,8 @@ typedef struct
GdkRGBA dim_foreground;
guint show_icons : 1;
guint always_expand : 1;
+ GtkTreePath *last_drop_path;
+ GtkTreeViewDropPosition last_drop_pos;
} DzlTreePrivate;
typedef struct
@@ -860,6 +862,98 @@ dzl_tree_add_child (GtkBuildable *buildable,
dzl_tree_parent_buildable_iface->add_child (buildable, builder, child, type);
}
+static gboolean
+dzl_tree_drag_motion (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time_)
+{
+ DzlTree *self = (DzlTree *)widget;
+ DzlTreePrivate *priv = dzl_tree_get_instance_private (self);
+ gboolean ret;
+
+ g_assert (DZL_IS_TREE (self));
+ g_assert (GDK_IS_DRAG_CONTEXT (context));
+
+ ret = GTK_WIDGET_CLASS (dzl_tree_parent_class)->drag_motion (widget, context, x, y, time_);
+
+ /*
+ * Cache the current drop position so we can use it
+ * later to determine how to drop on a given node.
+ */
+ g_clear_pointer (&priv->last_drop_path, gtk_tree_path_free);
+ gtk_tree_view_get_drag_dest_row (GTK_TREE_VIEW (widget),
+ &priv->last_drop_path,
+ &priv->last_drop_pos);
+
+ return ret;
+}
+
+static void
+dzl_tree_drag_end (GtkWidget *widget,
+ GdkDragContext *context)
+{
+ DzlTree *self = (DzlTree *)widget;
+ DzlTreePrivate *priv = dzl_tree_get_instance_private (self);
+
+ g_assert (DZL_IS_TREE (self));
+ g_assert (GDK_IS_DRAG_CONTEXT (context));
+
+ priv->last_drop_pos = 0;
+ g_clear_pointer (&priv->last_drop_path, gtk_tree_path_free);
+
+ GTK_WIDGET_CLASS (dzl_tree_parent_class)->drag_end (widget, context);
+}
+
+DzlTreeNode *
+_dzl_tree_get_drop_node (DzlTree *self,
+ DzlTreeDropPosition *pos)
+{
+ DzlTreePrivate *priv = dzl_tree_get_instance_private (self);
+ g_autoptr(DzlTreeNode) node = NULL;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ g_return_val_if_fail (DZL_IS_TREE (self), NULL);
+
+ if (pos != NULL)
+ *pos = 0;
+
+ /* We can't do anything if we don't have a path */
+ if (priv->last_drop_path == NULL)
+ return NULL;
+
+ /* We don't have anything to do if path doesn't exist */
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (self));
+ if (!gtk_tree_model_get_iter (model, &iter, priv->last_drop_path))
+ return NULL;
+
+ gtk_tree_model_get (model, &iter, 0, &node, -1);
+ g_assert (DZL_IS_TREE_NODE (node));
+
+ switch (priv->last_drop_pos)
+ {
+ case GTK_TREE_VIEW_DROP_BEFORE:
+ *pos = DZL_TREE_DROP_BEFORE;
+ break;
+
+ case GTK_TREE_VIEW_DROP_AFTER:
+ *pos = DZL_TREE_DROP_AFTER;
+ break;
+
+ case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE:
+ case GTK_TREE_VIEW_DROP_INTO_OR_AFTER:
+ *pos = DZL_TREE_DROP_INTO;
+ break;
+
+ default:
+ break;
+ }
+
+ return g_steal_pointer (&node);
+}
+
static void
dzl_tree_style_updated (GtkWidget *widget)
{
@@ -881,16 +975,20 @@ dzl_tree_style_updated (GtkWidget *widget)
}
static void
-dzl_tree_finalize (GObject *object)
+dzl_tree_destroy (GtkWidget *widget)
{
- DzlTree *self = DZL_TREE (object);
+ DzlTree *self = (DzlTree *)widget;
DzlTreePrivate *priv = dzl_tree_get_instance_private (self);
- g_ptr_array_unref (priv->builders);
+ g_assert (DZL_IS_TREE (self));
+
+ g_clear_pointer (&priv->last_drop_path, gtk_tree_path_free);
+ g_clear_pointer (&priv->builders, g_ptr_array_unref);
g_clear_object (&priv->store);
g_clear_object (&priv->root);
+ g_clear_object (&priv->context_menu);
- G_OBJECT_CLASS (dzl_tree_parent_class)->finalize (object);
+ GTK_WIDGET_CLASS (dzl_tree_parent_class)->destroy (widget);
}
static void
@@ -980,14 +1078,17 @@ dzl_tree_class_init (DzlTreeClass *klass)
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GtkTreeViewClass *tree_view_class = GTK_TREE_VIEW_CLASS (klass);
- object_class->finalize = dzl_tree_finalize;
object_class->get_property = dzl_tree_get_property;
object_class->set_property = dzl_tree_set_property;
widget_class->popup_menu = dzl_tree_popup_menu;
widget_class->button_press_event = dzl_tree_button_press_event;
+ widget_class->destroy = dzl_tree_destroy;
widget_class->style_updated = dzl_tree_style_updated;
+ widget_class->drag_motion = dzl_tree_drag_motion;
+ widget_class->drag_end = dzl_tree_drag_end;
+
tree_view_class->row_activated = dzl_tree_row_activated;
tree_view_class->row_expanded = dzl_tree_row_expanded;
tree_view_class->row_collapsed = dzl_tree_row_collapsed;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]