[Xfce4-commits] <design:master> Work on DnD, entirely experimental though.
Jannis Pohlmann
noreply at xfce.org
Sun Jun 5 01:40:01 CEST 2011
Updating branch refs/heads/master
to 883cf7f2623c63c28e237d8f4c9011760a9708c0 (commit)
from 6106a699ed82d7a1c8ab5de5ac1a42e711f3e5e2 (commit)
commit 883cf7f2623c63c28e237d8f4c9011760a9708c0
Author: Jannis Pohlmann <jannis at xfce.org>
Date: Sun Jun 5 01:36:51 2011 +0200
Work on DnD, entirely experimental though.
.../demo-code/custom-view/drag-source.vala | 27 +++
.../demo-code/custom-view/mockup.vala | 19 ++-
.../demo-code/custom-view/shortcut-row.vala | 11 +-
.../demo-code/custom-view/shortcuts-view.vala | 236 ++++++++++++++++++--
4 files changed, 271 insertions(+), 22 deletions(-)
diff --git a/thunar/shortcuts-pane/demo-code/custom-view/drag-source.vala b/thunar/shortcuts-pane/demo-code/custom-view/drag-source.vala
index baaa0cf..1d8a763 100644
--- a/thunar/shortcuts-pane/demo-code/custom-view/drag-source.vala
+++ b/thunar/shortcuts-pane/demo-code/custom-view/drag-source.vala
@@ -24,11 +24,38 @@ using Gtk;
class DragSource : EventBox {
+ public static enum DragInfo {
+ TEXT_URI_LIST
+ }
+
public string location { get; set; }
public DragSource (string location) {
this.location = location;
+ TargetEntry targets[1] = {
+ TargetEntry () {
+ target = "text/uri-list",
+ flags = 0,
+ info = DragInfo.TEXT_URI_LIST
+ }
+ };
+
+ drag_source_set (this, Gdk.ModifierType.BUTTON1_MASK, targets, Gdk.DragAction.COPY);
+
+ drag_begin.connect ((context) => {
+ debug ("drag begin");
+ });
+
+ drag_data_get.connect ((context, selection_data, info, time) => {
+ debug ("drag data get");
+ selection_data.set_uris (new string[] { location });
+ });
+
+ drag_end.connect ((context) => {
+ debug ("drag end");
+ });
+
var label = new Label (this.location);
add (label);
label.show ();
diff --git a/thunar/shortcuts-pane/demo-code/custom-view/mockup.vala b/thunar/shortcuts-pane/demo-code/custom-view/mockup.vala
index 77a7484..72adee5 100644
--- a/thunar/shortcuts-pane/demo-code/custom-view/mockup.vala
+++ b/thunar/shortcuts-pane/demo-code/custom-view/mockup.vala
@@ -55,12 +55,27 @@ int main (string[] args) {
viewport.add (view);
view.show ();
+ var drag_frame = new Frame (null);
+ drag_frame.set_label_align (0.5f, 0.5f);
+ box.pack_start (drag_frame, false, true, 0);
+ drag_frame.show ();
+
+ var drag_frame_label = new Label ("<b>Drag us</b>");
+ drag_frame_label.set_use_markup (true);
+ drag_frame.set_label_widget (drag_frame_label);
+ drag_frame_label.show ();
+
+ var drag_sources = new VBox (false, 6);
+ drag_sources.set_border_width (6);
+ drag_frame.add (drag_sources);
+ drag_sources.show ();
+
var local_file = new DragSource ("file:///home/jannis/foo.txt");
- box.pack_start (local_file, false, true, 0);
+ drag_sources.pack_start (local_file, false, true, 0);
local_file.show ();
var remote_uri = new DragSource ("sftp://xfce.org/home/jannis/bar.txt");
- box.pack_start (remote_uri, false, true, 0);
+ drag_sources.pack_start (remote_uri, false, true, 0);
remote_uri.show ();
window.show ();
diff --git a/thunar/shortcuts-pane/demo-code/custom-view/shortcut-row.vala b/thunar/shortcuts-pane/demo-code/custom-view/shortcut-row.vala
index 0ef1b6f..b6bad1a 100644
--- a/thunar/shortcuts-pane/demo-code/custom-view/shortcut-row.vala
+++ b/thunar/shortcuts-pane/demo-code/custom-view/shortcut-row.vala
@@ -26,13 +26,14 @@ public class ShortcutRow : EventBox {
public string title { get; set; }
public string icon_name { get; set; }
public bool connected { get; set; }
+ public bool is_drop_target { get; set; default = false; }
private Image disconnect_icon { get; set; }
private Image cancel_icon { get; set; }
private Button button { get; set; }
private Spinner spinner { get; set; }
- public ShortcutRow (string title, string icon_name, bool connected) {
+ public ShortcutRow (string? title, string? icon_name, bool connected) {
this.title = title;
this.icon_name = icon_name;
this.connected = connected;
@@ -49,6 +50,14 @@ public class ShortcutRow : EventBox {
align.add (box);
box.show ();
+ notify["is-drop-target"].connect (() => {
+ if (this.is_drop_target) {
+ drag_highlight (box);
+ } else {
+ drag_unhighlight (box);
+ }
+ });
+
var icon = new Image.from_icon_name (icon_name, IconSize.MENU);
box.pack_start (icon, false, true, 0);
icon.show ();
diff --git a/thunar/shortcuts-pane/demo-code/custom-view/shortcuts-view.vala b/thunar/shortcuts-pane/demo-code/custom-view/shortcuts-view.vala
index c934a2a..c1fc5e3 100644
--- a/thunar/shortcuts-pane/demo-code/custom-view/shortcuts-view.vala
+++ b/thunar/shortcuts-pane/demo-code/custom-view/shortcuts-view.vala
@@ -24,9 +24,11 @@ using Gtk;
public class Category : GLib.Object {
public string name { get; set; }
+ public bool supports_bookmarks { get; set; default = false; }
- public Category (string name) {
+ public Category (string name, bool supports_bookmarks) {
this.name = name;
+ this.supports_bookmarks = supports_bookmarks;
}
}
@@ -46,10 +48,50 @@ public class Shortcut : GLib.Object {
+public class CategoryExpander : Expander {
+ public Category category { get; set; }
+ public Container container { get; private set; }
+ public ShortcutRow? drop_indicator { get; private set; default = null; }
+
+ public CategoryExpander (Category category) {
+ this.category = category;
+
+ var markup = "<span size='medium' weight='bold' color='#353535'>%s</span>";
+ set_label (GLib.Markup.printf_escaped (markup, category.name));
+
+ set_border_width (0);
+ set_use_markup (true);
+ set_expanded (true);
+ set_spacing (0);
+
+ container = new VBox (false, 0);
+ add (container);
+ container.show ();
+ }
+
+ public void add_drop_indicator () {
+ drop_indicator = new ShortcutRow (null, null, false);
+ drop_indicator.set_no_show_all (true);
+ drop_indicator.set_visible (false);
+ container.add (drop_indicator);
+ }
+}
+
+
+
public class ShortcutsView : EventBox {
private Alignment alignment { get; set; }
private VBox box { get; set; }
- private unowned List<Expander> expanders { get; set; }
+ private unowned List<CategoryExpander> expanders { get; set; }
+
+ private bool drop_data_ready { get; set; default = false; }
+ private bool drop_occured { get; set; default = false; }
+ private TargetList drop_targets { get; set; default = null; }
+ private string[]? drop_uris { get; set; default = null; }
+
+ public static enum DragInfo {
+ TEXT_URI_LIST
+ }
public ShortcutsView () {
alignment = new Alignment (0.0f, 0.0f, 1.0f, 1.0f);
@@ -63,12 +105,12 @@ public class ShortcutsView : EventBox {
List<GLib.Object> shortcuts = new List<GLib.Object> ();
- shortcuts.append (new Category ("DEVICES"));
+ shortcuts.append (new Category ("DEVICES", false));
shortcuts.append (new Shortcut ("File System", "harddrive", false));
shortcuts.append (new Shortcut ("iPod", "multimedia-player", true));
shortcuts.append (new Shortcut ("Blank DVD+RW Disc", "media-optical-dvd", true));
- shortcuts.append (new Category ("PLACES"));
+ shortcuts.append (new Category ("PLACES", true));
shortcuts.append (new Shortcut ("jannis", "user-home", false));
shortcuts.append (new Shortcut ("Desktop", "user-desktop", false));
shortcuts.append (new Shortcut ("Trash", "user-trash", false));
@@ -76,39 +118,195 @@ public class ShortcutsView : EventBox {
shortcuts.append (new Shortcut ("Downloads", "folder", false));
shortcuts.append (new Shortcut ("Thesis", "folder", false));
- shortcuts.append (new Category ("NETWORK"));
+ shortcuts.append (new Category ("NETWORK", true));
shortcuts.append (new Shortcut ("sftp at xfce.org", "folder-remote", true));
shortcuts.append (new Shortcut ("ftp at gezeiten.org", "folder-remote", false));
- expanders = new List<Expander> ();
+ expanders = new List<CategoryExpander> ();
- Container? container = null;
+ CategoryExpander? expander = null;
foreach (var item in shortcuts) {
if (item is Category) {
Category category = (Category) item;
- var markup = "<span size='medium' weight='bold' color='#353535'>%s</span>";
-
- var expander = new Expander (GLib.Markup.printf_escaped (markup, category.name));
- expander.set_border_width (0);
- expander.set_use_markup (true);
- expander.set_expanded (true);
- expander.set_spacing (0);
+ expander = new CategoryExpander (category);
box.pack_start (expander, false, true, 0);
-
- container = new VBox (false, 0);
- expander.add (container);
- container.show ();
+ expander.show ();
expanders.append (expander);
} else {
Shortcut shortcut = (Shortcut) item;
var row = new ShortcutRow (shortcut.name, shortcut.icon_name, shortcut.connected);
- container.add (row);
+ expander.container.add (row);
row.show ();
}
}
+ foreach (var exp in expanders) {
+ if (exp.category.supports_bookmarks) {
+ exp.add_drop_indicator ();
+ }
+ }
+
show_all ();
+
+ /* create list of supported drop targets */
+ TargetEntry target_entries[1] = {
+ TargetEntry () {
+ target = "text/uri-list",
+ flags = 0,
+ info = DragInfo.TEXT_URI_LIST
+ }
+ };
+
+ /* remember this list for use in DnD handlers */
+ drop_targets = new TargetList (target_entries);
+
+ /* set the view as a drag destination for these targets */
+ drag_dest_set (this, 0, target_entries, Gdk.DragAction.COPY);
+ }
+
+ public bool find_category_for_file (GLib.File file,
+ out CategoryExpander? expander)
+ {
+ foreach (var exp in expanders) {
+ if (exp.category.name == "PLACES" && file.has_uri_scheme ("file")) {
+ expander = exp;
+ return true;
+ } else if (exp.category.name == "NETWORK" && file.has_uri_scheme ("sftp")) {
+ expander = exp;
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public override bool drag_motion (Gdk.DragContext context,
+ int x,
+ int y,
+ uint time) {
+ debug ("drag motion");
+
+ /* request drop data on demand */
+ if (!drop_data_ready) {
+ /* check if we can handle the drag data (only text/uri-list supported) */
+ var target = drag_dest_find_target (this, context, drop_targets);
+ if (target == Gdk.Atom.intern_static_string ("text/uri-list")) {
+ /* request drop data from the source */
+ drag_get_data (this, context, target, time);
+ }
+
+ /* we are not ready to drop yet */
+ Gdk.drag_status (context, 0, time);
+ } else {
+ /* create a file object for the URI */
+ var file = GLib.File.new_for_uri (drop_uris[0]);
+
+ /* find the correct category for it */
+ CategoryExpander? expander = null;
+ if (find_category_for_file (file, out expander)) {
+ if (expander.drop_indicator != null) {
+ expander.drop_indicator.is_drop_target = true;
+ expander.drop_indicator.set_visible (true);
+ }
+
+ /* we have drop data, now we can create the bookmark */
+ Gdk.drag_status (context, Gdk.DragAction.COPY, time);
+ } else {
+ /* we have an unsupported drop URI, cannot handle it */
+ Gdk.drag_status (context, 0, time);
+ }
+ }
+
+ return true;
+ }
+
+ public override void drag_leave (Gdk.DragContext context, uint time) {
+ debug ("drag leave, reset flags");
+
+ if (drop_data_ready) {
+ /* create a file object for the URI */
+ var file = GLib.File.new_for_uri (drop_uris[0]);
+
+ /* find the correct category for it */
+ CategoryExpander? expander = null;
+ if (find_category_for_file (file, out expander)) {
+ if (expander.drop_indicator != null) {
+ expander.drop_indicator.is_drop_target = false;
+ expander.drop_indicator.set_visible (false);
+ }
+ }
+ }
+
+ drop_data_ready = false;
+ drop_occured = false;
+ drop_uris = null;
+ }
+
+ public override bool drag_drop (Gdk.DragContext context,
+ int x,
+ int y,
+ uint time)
+ {
+ /* determine the DnD target and see if we can handle it */
+ var target = drag_dest_find_target (this, context, drop_targets);
+ if (target == Gdk.Atom.intern_static_string ("text/uri-list")) {
+ debug ("drag drop, supports target, perform drop");
+
+ /* set flag so that drag_data_received knows we are dropping for real */
+ drop_occured = true;
+
+ /* request data from drag source */
+ drag_get_data (this, context, target, time);
+
+ /* we will call drag_finish later */
+ return true;
+ } else {
+ debug ("drag drop, target unsupported, cancel drop");
+
+ /* cancel drop */
+ return false;
+ }
+ }
+
+ public override void drag_data_received (Gdk.DragContext context,
+ int x,
+ int y,
+ SelectionData selection_data,
+ uint info,
+ uint time)
+ {
+ debug ("drag data received");
+
+ string[] uris = selection_data.get_uris ();
+
+ if (!drop_data_ready) {
+ drop_uris = uris;
+ drop_data_ready = true;
+
+ if (uris != null) {
+ debug ("request from drag motion, have uris");
+ } else {
+ debug ("request from drag motion, don't have uris");
+ }
+ }
+
+ if (drop_occured) {
+ /* reset the drop state */
+ drop_occured = false;
+
+ if (drop_uris != null) {
+ debug ("have uris, create bookmark now");
+ } else {
+ debug ("don't have uris, abort drag-and-drop");
+ }
+
+ /* tell the drag source that we handled the drop */
+ drag_finish (context, drop_uris != null, false, time);
+
+ /* disable highlighting and release the drag data */
+ drag_leave (context, time);
+ }
}
}
More information about the Xfce4-commits
mailing list