Here is a very simple example, demonstrating a drag and drop Copy
operation:
File: dndwindow.h
(For use with gtkmm 4)
#ifndef GTKMM_EXAMPLE_DNDWINDOW_H #define GTKMM_EXAMPLE_DNDWINDOW_H #include <gdkmm/drop.h> #include <gtkmm/box.h> #include <gtkmm/label.h> #include <gtkmm/window.h> #include <gtkmm/button.h> class DnDWindow : public Gtk::Window { public: DnDWindow(); virtual ~DnDWindow(); protected: //Signal handlers and callbacks: void on_label_drag_get_data(Glib::ValueBase& value); bool on_button_drop_drag_drop(const Glib::RefPtr<Gdk::Drop>& drop, int x, int y); void on_button_drop_got_data(Glib::RefPtr<Gio::AsyncResult>& result, const Glib::RefPtr<Gdk::Drop>& drop); //Member widgets: Gtk::Box m_HBox; Gtk::Label m_Label_Drag; Gtk::Button m_Button_Drop; }; #endif // GTKMM_EXAMPLE_DNDWINDOW_H
File: main.cc
(For use with gtkmm 4)
#include "dndwindow.h" #include <gtkmm/application.h> int main (int argc, char *argv[]) { auto app = Gtk::Application::create("org.gtkmm.example"); DnDWindow dndWindow; //Shows the window and returns when it is closed. return app->run(dndWindow, argc, argv); }
File: dndwindow.cc
(For use with gtkmm 4)
#include "dndwindow.h" #include <gdkmm/contentformats.h> #include <gdkmm/contentprovider.h> #include <gtkmm/dragsource.h> #include <gtkmm/droptarget.h> #include <iostream> DnDWindow::DnDWindow() : m_Label_Drag("Drag Here\n"), m_Button_Drop("Drop here\n") { set_title("DnD example"); add(m_HBox); //Drag site: //Make m_Label_Drag a DnD drag source: const GType ustring_type = Glib::Value<Glib::ustring>::value_type(); auto source = Gtk::DragSource::create(); auto content = Gdk::ContentProvider::create(ustring_type, sigc::mem_fun(*this, &DnDWindow::on_label_drag_get_data)); source->set_content(content); m_Label_Drag.add_controller(source); m_HBox.add(m_Label_Drag); m_Label_Drag.set_expand(true); //Drop site: //Make m_Button_Drop a DnD drop destination: auto formats = Gdk::ContentFormats::create(ustring_type); auto target = Gtk::DropTarget::create(formats, Gdk::DragAction::COPY); target->signal_drag_drop().connect( sigc::mem_fun(*this, &DnDWindow::on_button_drop_drag_drop), false); m_Button_Drop.add_controller(target); m_HBox.add(m_Button_Drop); m_Button_Drop.set_expand(true); } DnDWindow::~DnDWindow() { } // In this simple example where just a small amount of data is copied, // it would be reasonable to store the data in the ContentProvider. // Then this callback routine would be unnecessary. void DnDWindow::on_label_drag_get_data(Glib::ValueBase& value) { Glib::Value<Glib::ustring> ustring_value; ustring_value.init(value.gobj()); ustring_value.set("I'm Data!"); value = ustring_value; } bool DnDWindow::on_button_drop_drag_drop(const Glib::RefPtr<Gdk::Drop>& drop, int, int) { drop->read_text_async(sigc::bind(sigc::mem_fun(*this, &DnDWindow::on_button_drop_got_data), drop)); return true; } void DnDWindow::on_button_drop_got_data(Glib::RefPtr<Gio::AsyncResult>& result, const Glib::RefPtr<Gdk::Drop>& drop) { try { const Glib::ustring dropped_string = drop->read_text_finish(result); std::cout << "Received \"" << dropped_string << "\" in button " << std::endl; drop->finish(Gdk::DragAction::COPY); } catch (const std::exception& ex) { std::cout << "Drop failed: " << ex.what() << std::endl; drop->failed(); } }
There is a more complex example in examples/others/dnd.