[gthumb: 8/9] fixed dragging from the tree view



commit 85496b581b119407bc844b971d9b7fe51fb982f0
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Tue Apr 27 21:20:20 2010 +0200

    fixed dragging from the tree view

 gthumb/gth-browser.c     |   11 ++--
 gthumb/gth-folder-tree.c |  173 +++++++++++++++++++++++++++++++++++++++++++---
 gthumb/gth-folder-tree.h |   86 ++++++++++++-----------
 3 files changed, 213 insertions(+), 57 deletions(-)
---
diff --git a/gthumb/gth-browser.c b/gthumb/gth-browser.c
index 552fde8..8cf4dd6 100644
--- a/gthumb/gth-browser.c
+++ b/gthumb/gth-browser.c
@@ -3725,12 +3725,11 @@ _gth_browser_construct (GthBrowser *browser)
 						      targets,
 						      n_targets,
 						      GDK_ACTION_MOVE | GDK_ACTION_COPY);
-		gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (browser->priv->folder_tree),
-							GDK_BUTTON1_MASK,
-							targets,
-							n_targets,
-							GDK_ACTION_MOVE | GDK_ACTION_COPY);
-
+		gth_folder_tree_enable_drag_source (GTH_FOLDER_TREE (browser->priv->folder_tree),
+						    GDK_BUTTON1_MASK,
+						    targets,
+						    n_targets,
+						    GDK_ACTION_MOVE | GDK_ACTION_COPY);
 		g_signal_connect (browser->priv->folder_tree,
 	                          "drag-data-received",
 	                          G_CALLBACK (folder_tree_drag_data_received),
diff --git a/gthumb/gth-folder-tree.c b/gthumb/gth-folder-tree.c
index 3135af4..9b40cc4 100644
--- a/gthumb/gth-folder-tree.c
+++ b/gthumb/gth-folder-tree.c
@@ -74,11 +74,23 @@ enum {
 
 struct _GthFolderTreePrivate
 {
-	GFile           *root;
-	GtkTreeStore    *tree_store;
-	GthIconCache    *icon_cache;
-	GtkCellRenderer *text_renderer;
-	GtkTreePath     *hover_path;
+	GFile            *root;
+	GtkTreeStore     *tree_store;
+	GthIconCache     *icon_cache;
+	GtkCellRenderer  *text_renderer;
+	GtkTreePath      *hover_path;
+
+	/* drag-and-drop */
+
+	gboolean         drag_source_enabled;
+	GdkModifierType  drag_start_button_mask;
+	GtkTargetList   *drag_target_list;
+	GdkDragAction    drag_actions;
+
+	gboolean         dragging : 1;        /* Whether the user is dragging items. */
+	gboolean         drag_started : 1;    /* Whether the drag has started. */
+	int              drag_start_x;        /* The position where the drag started. */
+	int              drag_start_y;
 };
 
 
@@ -94,6 +106,10 @@ gth_folder_tree_finalize (GObject *object)
 	folder_tree = GTH_FOLDER_TREE (object);
 
 	if (folder_tree->priv != NULL) {
+		if (folder_tree->priv->drag_target_list != NULL) {
+			gtk_target_list_unref (folder_tree->priv->drag_target_list);
+			folder_tree->priv->drag_target_list = NULL;
+		}
 		if (folder_tree->priv->root != NULL)
 			g_object_unref (folder_tree->priv->root);
 		gth_icon_cache_free (folder_tree->priv->icon_cache);
@@ -108,13 +124,17 @@ gth_folder_tree_finalize (GObject *object)
 static void
 gth_folder_tree_class_init (GthFolderTreeClass *class)
 {
-	GObjectClass *object_class;
+	GObjectClass   *object_class;
+	GtkWidgetClass *widget_class;
 
 	parent_class = g_type_class_peek_parent (class);
-	object_class = (GObjectClass*) class;
 
+	object_class = (GObjectClass*) class;
 	object_class->finalize = gth_folder_tree_finalize;
 
+	widget_class = (GtkWidgetClass*) class;
+	widget_class->drag_begin = NULL;
+
 	gth_folder_tree_signals[FOLDER_POPUP] =
 		g_signal_new ("folder_popup",
 			      G_TYPE_FROM_CLASS (class),
@@ -405,6 +425,19 @@ button_press_cb (GtkWidget      *widget,
 		int               expander_size;
 		int               horizontal_separator;
 
+		/* This can be the start of a dragging action. */
+
+		if (! (event->state & GDK_CONTROL_MASK)
+		    && ! (event->state & GDK_SHIFT_MASK)
+		    && folder_tree->priv->drag_source_enabled)
+		{
+			folder_tree->priv->dragging = TRUE;
+			folder_tree->priv->drag_start_x = event->x;
+			folder_tree->priv->drag_start_y = event->y;
+		}
+
+		/**/
+
 		if (! gtk_tree_view_column_cell_get_position (column,
 							      folder_tree->priv->text_renderer,
 							      &start_pos,
@@ -447,6 +480,87 @@ button_press_cb (GtkWidget      *widget,
 }
 
 
+static gboolean
+motion_notify_event_cb (GtkWidget      *widget,
+			GdkEventButton *event,
+			gpointer        user_data)
+{
+	GthFolderTree *folder_tree = user_data;
+
+	if (! folder_tree->priv->drag_source_enabled)
+		return FALSE;
+
+	if (folder_tree->priv->dragging) {
+		if (! folder_tree->priv->drag_started
+		    && gtk_drag_check_threshold (widget,
+					         folder_tree->priv->drag_start_x,
+					         folder_tree->priv->drag_start_y,
+						 event->x,
+						 event->y))
+		{
+			GtkTreePath    *path = NULL;
+			GdkDragContext *context;
+			int             cell_x;
+			int             cell_y;
+			GdkPixmap      *dnd_icon;
+
+			if (! gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (folder_tree),
+							     event->x,
+							     event->y,
+							     &path,
+							     NULL,
+							     &cell_x,
+							     &cell_y))
+			{
+				return FALSE;
+			}
+
+			gtk_tree_view_set_cursor (GTK_TREE_VIEW (folder_tree), path, NULL, FALSE);
+			folder_tree->priv->drag_started = TRUE;
+
+			/**/
+
+			context = gtk_drag_begin (widget,
+						  folder_tree->priv->drag_target_list,
+						  folder_tree->priv->drag_actions,
+						  1,
+						  (GdkEvent *) event);
+
+			dnd_icon = gtk_tree_view_create_row_drag_icon (GTK_TREE_VIEW (folder_tree), path);
+			gtk_drag_set_icon_pixmap (context,
+						  gdk_drawable_get_colormap (dnd_icon),
+						  dnd_icon,
+						  NULL,
+						  cell_x,
+						  cell_y);
+
+			g_object_unref (dnd_icon);
+			gtk_tree_path_free (path);
+		}
+
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+
+static gboolean
+button_release_event_cb (GtkWidget      *widget,
+			 GdkEventButton *event,
+			 gpointer        user_data)
+{
+	GthFolderTree *folder_tree = user_data;
+
+	if (folder_tree->priv->dragging) {
+		folder_tree->priv->dragging = FALSE;
+		folder_tree->priv->drag_started = FALSE;
+	}
+
+	return FALSE;
+}
+
+
 static void
 load_uri (GthFolderTree *folder_tree,
 	  EntryType      entry_type,
@@ -817,15 +931,23 @@ gth_folder_tree_construct (GthFolderTree *folder_tree)
 
 	/**/
 
-	g_signal_connect (G_OBJECT (folder_tree),
-			  "button_press_event",
+	g_signal_connect (folder_tree,
+			  "button-press-event",
 			  G_CALLBACK (button_press_cb),
 			  folder_tree);
-	g_signal_connect (G_OBJECT (folder_tree),
+	g_signal_connect (folder_tree,
+			  "motion-notify-event",
+			  G_CALLBACK (motion_notify_event_cb),
+			  folder_tree);
+	g_signal_connect (folder_tree,
+			  "button-release-event",
+			  G_CALLBACK (button_release_event_cb),
+			  folder_tree);
+	g_signal_connect (folder_tree,
 			  "row-activated",
 			  G_CALLBACK (row_activated_cb),
 			  folder_tree);
-	g_signal_connect (G_OBJECT (folder_tree),
+	g_signal_connect (folder_tree,
 			  "row-expanded",
 			  G_CALLBACK (row_expanded_cb),
 			  folder_tree);
@@ -836,6 +958,10 @@ static void
 gth_folder_tree_init (GthFolderTree *folder_tree)
 {
 	folder_tree->priv = g_new0 (GthFolderTreePrivate, 1);
+	folder_tree->priv->drag_source_enabled = FALSE;
+	folder_tree->priv->dragging = FALSE;
+	folder_tree->priv->drag_started = FALSE;
+	folder_tree->priv->drag_target_list = NULL;
 	gth_folder_tree_construct (folder_tree);
 }
 
@@ -1518,3 +1644,28 @@ gth_folder_tree_get_selected_or_parent (GthFolderTree *folder_tree)
 
 	return file_data;
 }
+
+
+void
+gth_folder_tree_enable_drag_source (GthFolderTree        *self,
+				    GdkModifierType       start_button_mask,
+				    const GtkTargetEntry *targets,
+				    int                   n_targets,
+				    GdkDragAction         actions)
+{
+	if (self->priv->drag_target_list != NULL)
+		gtk_target_list_unref (self->priv->drag_target_list);
+
+	self->priv->drag_source_enabled = TRUE;
+	self->priv->drag_start_button_mask = start_button_mask;
+	self->priv->drag_target_list = gtk_target_list_new (targets, n_targets);
+	self->priv->drag_actions = actions;
+}
+
+
+void
+gth_folder_tree_unset_drag_source (GthFolderTree *self)
+{
+	self->priv->drag_source_enabled = FALSE;
+}
+
diff --git a/gthumb/gth-folder-tree.h b/gthumb/gth-folder-tree.h
index 6263725..f90e058 100644
--- a/gthumb/gth-folder-tree.h
+++ b/gthumb/gth-folder-tree.h
@@ -65,47 +65,53 @@ struct _GthFolderTreeClass {
 			       const char    *new_name);
 };
 
-GType         gth_folder_tree_get_type         (void);
-GtkWidget *   gth_folder_tree_new              (const char      *uri);
-void          gth_folder_tree_set_list         (GthFolderTree   *folder_tree,
-						GFile           *root,
-						GList           *files,
-						gboolean         open_parent);
-void          gth_folder_tree_set_children     (GthFolderTree   *folder_tree,
-						GFile           *parent,
-						GList           *files /* GthFileData */);
-void          gth_folder_tree_loading_children (GthFolderTree   *folder_tree,
-						GFile           *parent);
-void          gth_folder_tree_add_children     (GthFolderTree   *folder_tree,
-						GFile           *parent,
-						GList           *files /* GthFileData */);
-void          gth_folder_tree_update_children  (GthFolderTree   *folder_tree,
-						GFile           *parent,
-						GList           *files /* GthFileData */);
-void          gth_folder_tree_update_child     (GthFolderTree   *folder_tree,
-						GFile           *file,
-						GthFileData     *file_data);
-void          gth_folder_tree_delete_children  (GthFolderTree   *folder_tree,
-						GFile           *parent,
-						GList           *files /* GFile */);
-void          gth_folder_tree_start_editing    (GthFolderTree   *folder_tree,
-						GFile           *file);
-GtkTreePath * gth_folder_tree_get_path         (GthFolderTree   *folder_tree,
-						GFile           *file);
-gboolean      gth_folder_tree_is_loaded        (GthFolderTree   *folder_tree,
-						GtkTreePath     *path);
-void          gth_folder_tree_reset_loaded     (GthFolderTree   *folder_tree);
-void          gth_folder_tree_expand_row       (GthFolderTree   *folder_tree,
-						GtkTreePath     *path,
-						gboolean         open_all);
-void          gth_folder_tree_select_path      (GthFolderTree   *folder_tree,
-						GtkTreePath     *path);
-GFile *       gth_folder_tree_get_root         (GthFolderTree   *folder_tree);
-GthFileData * gth_folder_tree_get_file         (GthFolderTree   *folder_tree,
-						GtkTreePath     *path);
-GthFileData * gth_folder_tree_get_selected     (GthFolderTree   *folder_tree);
+GType         gth_folder_tree_get_type           (void);
+GtkWidget *   gth_folder_tree_new                (const char           *uri);
+void          gth_folder_tree_set_list           (GthFolderTree        *folder_tree,
+						  GFile                *root,
+						  GList                *files,
+						  gboolean              open_parent);
+void          gth_folder_tree_set_children       (GthFolderTree        *folder_tree,
+						  GFile                *parent,
+						  GList                *files /* GthFileData */);
+void          gth_folder_tree_loading_children   (GthFolderTree        *folder_tree,
+						  GFile                *parent);
+void          gth_folder_tree_add_children       (GthFolderTree        *folder_tree,
+						  GFile                *parent,
+						  GList                *files /* GthFileData */);
+void          gth_folder_tree_update_children    (GthFolderTree        *folder_tree,
+						  GFile                *parent,
+						  GList                *files /* GthFileData */);
+void          gth_folder_tree_update_child       (GthFolderTree        *folder_tree,
+						  GFile                *file,
+						  GthFileData          *file_data);
+void          gth_folder_tree_delete_children    (GthFolderTree        *folder_tree,
+						  GFile                *parent,
+						  GList                *files /* GFile */);
+void          gth_folder_tree_start_editing      (GthFolderTree        *folder_tree,
+						  GFile                *file);
+GtkTreePath * gth_folder_tree_get_path           (GthFolderTree        *folder_tree,
+						  GFile                *file);
+gboolean      gth_folder_tree_is_loaded          (GthFolderTree        *folder_tree,
+						  GtkTreePath          *path);
+void          gth_folder_tree_reset_loaded       (GthFolderTree        *folder_tree);
+void          gth_folder_tree_expand_row         (GthFolderTree        *folder_tree,
+						  GtkTreePath          *path,
+						  gboolean              open_all);
+void          gth_folder_tree_select_path        (GthFolderTree        *folder_tree,
+						  GtkTreePath          *path);
+GFile *       gth_folder_tree_get_root           (GthFolderTree        *folder_tree);
+GthFileData * gth_folder_tree_get_file           (GthFolderTree        *folder_tree,
+						  GtkTreePath          *path);
+GthFileData * gth_folder_tree_get_selected       (GthFolderTree        *folder_tree);
 GthFileData * gth_folder_tree_get_selected_or_parent
-					       (GthFolderTree   *folder_tree);
+					         (GthFolderTree        *folder_tree);
+void          gth_folder_tree_enable_drag_source (GthFolderTree        *self,
+						  GdkModifierType       start_button_mask,
+						  const GtkTargetEntry *targets,
+						  int                   n_targets,
+						  GdkDragAction         actions);
+void          gth_folder_tree_unset_drag_source  (GthFolderTree        *self);
 
 G_END_DECLS
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]