Example
| Chapter 18. Drag and Drop |

## Example

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

Figure 18.1. Drag and Drop

Source Code

File: `dndwindow.h` (For use with gtkmm 3, not gtkmm 2)

    #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::DragContext>& context,
              Gtk::SelectionData& selection_data, guint info, guint time);
      void on_label_drop_drag_data_received(
              const Glib::RefPtr<Gdk::DragContext>& context, int x, int y,
              const Gtk::SelectionData& selection_data, guint info, guint time);

      //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 3, not gtkmm 2)

    #include "dndwindow.h"
    #include <gtkmm/application.h>

    int main (int argc, char *argv[])
    {
      auto app = Gtk::Application::create(argc, argv, "org.gtkmm.example");

      DnDWindow dndWindow;

      //Shows the window and returns when it is closed.
      return app->run(dndWindow);
    }

File: `dndwindow.cc` (For use with gtkmm 3, not gtkmm 2)

    #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);

      //Targets:
      std::vector<Gtk::TargetEntry> listTargets;
      listTargets.push_back( Gtk::TargetEntry("STRING") );
      listTargets.push_back( Gtk::TargetEntry("text/plain") );

      //Drag site:

      //Make m_Button_Drag a DnD drag source:
      m_Button_Drag.drag_source_set(listTargets);

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

      m_HBox.pack_start(m_Button_Drag);

      //Drop site:

      //Make m_Label_Drop a DnD drop destination:
      m_Label_Drop.drag_dest_set(listTargets);

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

      m_HBox.pack_start(m_Label_Drop);

      show_all();
    }

    DnDWindow::~DnDWindow()
    {
    }

    void DnDWindow::on_button_drag_data_get(
            const Glib::RefPtr<Gdk::DragContext>&,
            Gtk::SelectionData& selection_data, guint, guint)
    {
      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::DragContext>& context, int, int,
            const Gtk::SelectionData& selection_data, guint, guint time)
    {
      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;
      }

      context->drag_finish(false, false, time);
    }

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

DragContext |  | Chapter 19. The Clipboard