[gtk+/wip/csoriano/bookmarks: 18/23] gtkplacessidebar: add API for show drop hints
- From: Carlos Soriano Sánchez <csoriano src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/csoriano/bookmarks: 18/23] gtkplacessidebar: add API for show drop hints
- Date: Thu, 7 May 2015 14:54:07 +0000 (UTC)
commit 020beba0ed90105b900343808857e3099dcfa025
Author: Carlos Soriano <csoriano gnome org>
Date: Sat Apr 11 17:35:23 2015 +0200
gtkplacessidebar: add API for show drop hints
It is convenient to allow applications to show all the drop
targets at once. This improves the user experience with drag
an drop.
The new API allows the application to set the gtkplacessidebar
in a mode where invalid drop targets are insensitive and it
adds a "new bookmark" row. This mode is intended to be set
when the application is aware of a dnd operation and needs to
be stopped kwhen the application is aware that dnd operation
was cancelled or ended in a different part than gtkplacesisdebar.
https://bugzilla.gnome.org/show_bug.cgi?id=747793
docs/reference/gtk/gtk3-sections.txt | 2 +
gtk/gtkplacessidebar.c | 125 ++++++++++++++++++++++++++++------
gtk/gtkplacessidebar.h | 5 ++
3 files changed, 110 insertions(+), 22 deletions(-)
---
diff --git a/docs/reference/gtk/gtk3-sections.txt b/docs/reference/gtk/gtk3-sections.txt
index 8f15a3a..cabbbf3 100644
--- a/docs/reference/gtk/gtk3-sections.txt
+++ b/docs/reference/gtk/gtk3-sections.txt
@@ -2648,6 +2648,8 @@ gtk_places_sidebar_get_local_only
gtk_places_sidebar_set_local_only
gtk_places_sidebar_get_show_enter_location
gtk_places_sidebar_set_show_enter_location
+gtk_places_sidebar_drop_hints_start
+gtk_places_sidebar_drop_hints_stop
<SUBSECTION Standard>
GTK_PLACES_SIDEBAR
GTK_IS_PLACES_SIDEBAR
diff --git a/gtk/gtkplacessidebar.c b/gtk/gtkplacessidebar.c
index eaed6d5..75be75d 100644
--- a/gtk/gtkplacessidebar.c
+++ b/gtk/gtkplacessidebar.c
@@ -121,8 +121,9 @@
typedef enum {
DROP_STATE_NORMAL,
DROP_STATE_NEW_BOOKMARK_FADING_IN,
+ DROP_STATE_NEW_BOOKMARK_FADING_OUT,
DROP_STATE_NEW_BOOKMARK_ARMED,
- DROP_STATE_NEW_BOOKMARK_FADING_OUT
+ DROP_STATE_NEW_BOOKMARK_ARMED_PERMANENT,
} DropState;
struct _GtkPlacesSidebar {
@@ -152,6 +153,7 @@ struct _GtkPlacesSidebar {
/* DND */
GList *drag_list; /* list of GFile */
gint drag_data_info;
+ gboolean dragging_over;
/* volume mounting - delayed open process */
GtkPlacesOpenFlags go_to_after_mount_open_flags;
@@ -1690,15 +1692,21 @@ show_new_bookmark_row (GtkPlacesSidebar *sidebar,
-1);
}
- sidebar->drop_state = DROP_STATE_NEW_BOOKMARK_ARMED;
+ /* If the state is permanent, don't change it. Is the application that
+ * controls this */
+ if (sidebar->drop_state != DROP_STATE_NEW_BOOKMARK_ARMED_PERMANENT)
+ sidebar->drop_state = DROP_STATE_NEW_BOOKMARK_ARMED;
/* Highlight the new bookmark row */
- drop_target_index = gtk_tree_path_get_indices (path)[0];
- if (drop_target_index == bookmarks_index)
+ if (path != NULL)
{
- new_bookmark_path = gtk_tree_path_new_from_indices (bookmarks_index, -1);
- gtk_tree_view_set_drag_dest_row (sidebar->tree_view, new_bookmark_path,
GTK_TREE_VIEW_DROP_INTO_OR_AFTER);
- gtk_tree_path_free (new_bookmark_path);
+ drop_target_index = gtk_tree_path_get_indices (path)[0];
+ if (drop_target_index == bookmarks_index)
+ {
+ new_bookmark_path = gtk_tree_path_new_from_indices (bookmarks_index, -1);
+ gtk_tree_view_set_drag_dest_row (sidebar->tree_view, new_bookmark_path,
GTK_TREE_VIEW_DROP_INTO_OR_AFTER);
+ gtk_tree_path_free (new_bookmark_path);
+ }
}
}
@@ -1736,6 +1744,8 @@ drag_motion_callback (GtkTreeView *tree_view,
gboolean drop_as_bookmarks;
gchar *drop_target_uri = NULL;
+ sidebar->dragging_over = TRUE;
+
action = 0;
drop_as_bookmarks = FALSE;
path = NULL;
@@ -1825,17 +1835,40 @@ drag_motion_callback (GtkTreeView *tree_view,
return TRUE;
}
-static gboolean
-drag_leave_timeout_cb (gpointer data)
+static void
+on_drag_end (GtkPlacesSidebar *sidebar)
{
- GtkPlacesSidebar *sidebar = GTK_PLACES_SIDEBAR (data);
+ g_return_if_fail (GTK_IS_PLACES_SIDEBAR (sidebar));
free_drag_data (sidebar);
- stop_drop_feedback (sidebar);
+ /* we could call finalize when disposing the widget */
+ if (sidebar->tree_view != NULL)
+ stop_drop_feedback (sidebar);
remove_drop_bookmark_feedback_row (sidebar);
+ if (sidebar->drag_leave_timeout_id)
+ g_source_remove (sidebar->drag_leave_timeout_id);
+
sidebar->drag_leave_timeout_id = 0;
- return FALSE;
+ sidebar->drop_state = DROP_STATE_NORMAL;
+ sidebar->dragging_over = FALSE;
+}
+
+static gboolean
+drag_leave_timeout_cb (gpointer data)
+{
+ GtkPlacesSidebar *sidebar = GTK_PLACES_SIDEBAR (data);
+
+ if (sidebar->drop_state != DROP_STATE_NEW_BOOKMARK_ARMED_PERMANENT)
+ {
+ on_drag_end (sidebar);
+ return FALSE;
+ }
+ else
+ {
+ sidebar->dragging_over = FALSE;
+ return TRUE;
+ }
}
static void
@@ -1844,6 +1877,8 @@ drag_leave_callback (GtkTreeView *tree_view,
guint time,
GtkPlacesSidebar *sidebar)
{
+ sidebar->dragging_over = FALSE;
+
if (sidebar->drag_leave_timeout_id)
g_source_remove (sidebar->drag_leave_timeout_id);
@@ -2082,9 +2117,8 @@ drag_data_received_callback (GtkWidget *widget,
out:
sidebar->drop_occured = FALSE;
- free_drag_data (sidebar);
- remove_drop_bookmark_feedback_row (sidebar);
gtk_drag_finish (context, success, FALSE, time);
+ on_drag_end (sidebar);
gtk_tree_path_free (tree_path);
}
@@ -4398,15 +4432,9 @@ gtk_places_sidebar_dispose (GObject *object)
sidebar->cancellable = NULL;
}
- sidebar->tree_view = NULL;
+ on_drag_end (sidebar);
- if (sidebar->drag_leave_timeout_id)
- {
- g_source_remove (sidebar->drag_leave_timeout_id);
- sidebar->drag_leave_timeout_id = 0;
- }
-
- free_drag_data (sidebar);
+ sidebar->tree_view = NULL;
if (sidebar->bookmarks_manager != NULL)
{
@@ -5337,3 +5365,56 @@ gtk_places_sidebar_get_nth_bookmark (GtkPlacesSidebar *sidebar,
return file;
}
+
+/**
+ * gtk_places_sidebar_drop_hints_start:
+ * @sidebar: a places sidebar
+ *
+ * Make the GtkPlacesSidebar show drop hints, so it can show the available drop
+ * targets and a "new bookmark" row. This improves the drag and drop
+ * experience of the user and allow applications to show at once the available
+ * drop targets.
+ * This needs to be called when the application is aware of a drag, and
+ * gtk_places_sidebar_hide_drop_hints needs to be called when the drag
+ * has been finished.
+ *
+ * Since: 3.18
+ */
+void
+gtk_places_sidebar_drop_hints_start (GtkPlacesSidebar *sidebar)
+{
+ show_new_bookmark_row (sidebar, NULL);
+ sidebar->drop_state = DROP_STATE_NEW_BOOKMARK_ARMED_PERMANENT;
+}
+
+/**
+ * gtk_places_sidebar_drop_hints_stop:
+ * @sidebar: a places sidebar
+ *
+ * Stop the hints that started with gtk_places_sidebar_drop_hints_start.
+ * It's not needed to take care of the drag if it finish in GtkPlacesSidebar, so
+ * it's not needed to conect to their signals to call gtk_places_sidebar_drop_hints_stop
+ * manually, just call it when the drag ends on some other widget on your application.
+ *
+ * Since: 3.18
+ */
+void
+gtk_places_sidebar_drop_hints_stop (GtkPlacesSidebar *sidebar)
+{
+ if (sidebar->drop_state == DROP_STATE_NEW_BOOKMARK_ARMED_PERMANENT ||
+ sidebar->drop_state == DROP_STATE_NEW_BOOKMARK_ARMED)
+ {
+ if (!sidebar->dragging_over)
+ {
+ on_drag_end (sidebar);
+ }
+ else
+ {
+ /* In case this is called while we are dragging we need to mark the
+ * drop state as no permanent so the leave timeout can do its job.
+ * This will only happen in applications that call this in a wrong
+ * time */
+ sidebar->drop_state = DROP_STATE_NEW_BOOKMARK_ARMED;
+ }
+ }
+}
diff --git a/gtk/gtkplacessidebar.h b/gtk/gtkplacessidebar.h
index f703cf8..759fbcf 100644
--- a/gtk/gtkplacessidebar.h
+++ b/gtk/gtkplacessidebar.h
@@ -131,6 +131,11 @@ GSList * gtk_places_sidebar_list_shortcuts (GtkPlacesSideb
GDK_AVAILABLE_IN_3_10
GFile * gtk_places_sidebar_get_nth_bookmark (GtkPlacesSidebar *sidebar,
gint n);
+GDK_AVAILABLE_IN_3_18
+void gtk_places_sidebar_drop_hints_start (GtkPlacesSidebar *sidebar);
+
+GDK_AVAILABLE_IN_3_18
+void gtk_places_sidebar_drop_hints_stop (GtkPlacesSidebar *sidebar);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]