Example
| Chapter 17. Drag and Drop |

## Example

Here is a very simple example, demonstrating a drag and drop `Copy` operation:

Figure 17.1. Drag and Drop

Source Code

File: `dndwindow.h` (For use with gtkmm 4)

    #ifndef GTKMM_EXAMPLE_DNDWINDOW_H
    #define GTKMM_EXAMPLE_DNDWINDOW_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:
      void on_button_drag_data_get(
              const Glib::RefPtr<Gdk::Drag>& drag,
              Gtk::SelectionData& selection_data);
      void on_label_drop_drag_data_received(
              const Glib::RefPtr<Gdk::Drop>& drop,
              const Gtk::SelectionData& selection_data);

      //Member widgets:
      Gtk::Box m_HBox;
      Gtk::Button m_Button_Drag;
      Gtk::Label m_Label_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 <iostream>

    DnDWindow::DnDWindow()
    : m_Button_Drag("Drag Here\n"),
      m_Label_Drop("Drop here\n")
    {
      set_title("DnD example");

      add(m_HBox);

      //Drag site:

      //Make m_Button_Drag a DnD drag source:
      m_Button_Drag.drag_source_set(Glib::RefPtr<Gdk::ContentFormats>());
      m_Button_Drag.drag_source_add_text_targets();

      //Connect signals:
      m_Button_Drag.signal_drag_data_get().connect(sigc::mem_fun(*this,
                  &DnDWindow::on_button_drag_data_get));

      m_HBox.add(m_Button_Drag);
      m_Button_Drag.set_expand(true);

      //Drop site:

      //Make m_Label_Drop a DnD drop destination:
      // Don't do this: m_Label_Drop.drag_dest_set({}).
      // It would call the wrong overload of drag_dest_set() with the wrong
      // default values of flags and actions (wrong in this simple example).
      m_Label_Drop.drag_dest_set(Glib::RefPtr<Gdk::ContentFormats>());
      m_Label_Drop.drag_dest_add_text_targets();

      //Connect signals:
      m_Label_Drop.signal_drag_data_received().connect(sigc::mem_fun(*this,
                  &DnDWindow::on_label_drop_drag_data_received) );

      m_HBox.add(m_Label_Drop);
      m_Label_Drop.set_expand(true);
    }

    DnDWindow::~DnDWindow()
    {
    }

    void DnDWindow::on_button_drag_data_get(
            const Glib::RefPtr<Gdk::Drag>&,
            Gtk::SelectionData& selection_data)
    {
      selection_data.set(selection_data.get_target(), 8 /* 8 bits format */,
              (const guchar*)"I'm Data!",
              9 /* the length of I'm Data! in bytes */);
    }

    void DnDWindow::on_label_drop_drag_data_received(
            const Glib::RefPtr<Gdk::Drop>& drop,
            const Gtk::SelectionData& selection_data)
    {
      const int length = selection_data.get_length();
      if((length >= 0) && (selection_data.get_format() == 8))
      {
        std::cout << "Received \"" << selection_data.get_data_as_string()
            << "\" in label " << std::endl;
      }

      drop->failed();
    }

There is a more complex example in examples/others/dnd.

Signals |  | Chapter 18. The Clipboard