How can I set a GTK+ 3 widget in Vala as a drag and drop target for external items? More specifically, I'd like to allow a user to drag movie files from a file manager into my application, so that I can get the dropped file's name, or if the user drags a directory, the filenames of the directory contents.
It is explained here:
https://laptrinhx.com/vala-9-drag-drop-3521859046/
using Gtk;
public class MainWindow : Gtk.Window
{
private Box vboxMain;
private ScrolledWindow swFiles;
private TreeView tvFiles;
private TreeViewColumn colName;
private const Gtk.TargetEntry[] targets = {
{"text/uri-list",0,0}
};
public static int main (string[] args)
{
Gtk.init(ref args);
var window = new MainWindow ();
window.show_all ();
Gtk.main();
return 0;
}
public MainWindow ()
{
this.title = "Drag files on this window";
this.window_position = WindowPosition.CENTER;
this.destroy.connect (Gtk.main_quit);
set_default_size (550, 400);
//vboxMain
vboxMain = new Box (Orientation.VERTICAL, 6);
vboxMain.margin = 6;
add (vboxMain);
//tvFiles
tvFiles = new TreeView();
//swFiles
swFiles = new ScrolledWindow(tvFiles.get_hadjustment (), tvFiles.get_vadjustment ());
swFiles.set_shadow_type (ShadowType.ETCHED_IN);
swFiles.set_size_request (550, 400);
swFiles.add(tvFiles);
vboxMain.add(swFiles);
//colName
colName = new TreeViewColumn();
colName.title ="File";
colName.expand = true;
CellRendererText cellName = new CellRendererText ();
colName.pack_start (cellName, false);
colName.set_attributes(cellName, "text", 0);
tvFiles.append_column(colName);
//inputStore
Gtk.ListStore store = new Gtk.ListStore (1, typeof (string));
tvFiles.model = store;
//connect drag drop handlers
Gtk.drag_dest_set (this,Gtk.DestDefaults.ALL, targets, Gdk.DragAction.COPY);
this.drag_data_received.connect(this.on_drag_data_received);
}
private void on_drag_data_received (Gdk.DragContext drag_context, int x, int y,
Gtk.SelectionData data, uint info, uint time)
{
//loop through list of URIs
foreach(string uri in data.get_uris ()){
string file = uri.replace("file://","").replace("file:/","");
file = Uri.unescape_string (file);
//add file to tree view
add_file (file);
}
Gtk.drag_finish (drag_context, true, false, time);
}
private void add_file(string file)
{
TreeIter iter;
Gtk.ListStore store = (Gtk.ListStore) tvFiles.model;
store.append (out iter);
store.set (iter, 0, file);
}
}
Build with valac dnd.vala --pkg gtk+-3.0