diff options
| author | Albrecht Schlosser <albrechts.fltk@online.de> | 2017-09-08 15:02:04 +0000 |
|---|---|---|
| committer | Albrecht Schlosser <albrechts.fltk@online.de> | 2017-09-08 15:02:04 +0000 |
| commit | ae983b74f271c2466804b1a9ab071a4fc8b1b4d0 (patch) | |
| tree | 1987bc534ee2e1ab32ca026267af7689a0c4d282 /examples/howto-drag-and-drop.cxx | |
| parent | 0bf5f9809a0c5c15cfc486e215f30a2a539e088e (diff) | |
Enhance howto-drag-and-drop example program.
Refer to discussion if fltk.general, thread "Drag and drop issue"
in August September 2017.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12432 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'examples/howto-drag-and-drop.cxx')
| -rw-r--r-- | examples/howto-drag-and-drop.cxx | 84 |
1 files changed, 74 insertions, 10 deletions
diff --git a/examples/howto-drag-and-drop.cxx b/examples/howto-drag-and-drop.cxx index 5b1c1f4f7..98829c39c 100644 --- a/examples/howto-drag-and-drop.cxx +++ b/examples/howto-drag-and-drop.cxx @@ -1,14 +1,17 @@ // // "$Id$" // -// A simple demo of drag+drop with FLTK. -// Originally from erco's cheat sheet, permission by author. -// Inspired by Michael Sephton's original example posted on fltk.general. +// A simple demo of 'drag and drop' with FLTK. +// Originally from erco's cheat sheet, permission by author. +// Inspired by Michael Sephton's original example posted on fltk.general. // -// When you run the program, just drag the red square over -// to the green square to show a 'drag and drop' sequence. +// When you run the program, just drag the red square over +// to the green square to show a 'drag and drop' sequence. // -// Copyright 1998-2010 by Bill Spitzak and others. +// You can also drag and drop text from another application over +// to the green square to show a 'drag and drop' sequence. +// +// Copyright 1998-2017 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -25,6 +28,7 @@ #include <FL/Fl.H> #include <FL/Fl_Window.H> #include <FL/Fl_Box.H> +#include <FL/fl_ask.H> // fl_message() // SIMPLE SENDER CLASS class Sender : public Fl_Box { @@ -52,29 +56,89 @@ public: }; // SIMPLE RECEIVER CLASS class Receiver : public Fl_Box { + int dnd_inside; + char *dnd_text; public: // Ctor Receiver(int x,int y,int w,int h) : Fl_Box(x,y,w,h) { box(FL_FLAT_BOX); color(10); label("..to\nhere"); + dnd_inside = 0; + dnd_text = 0; } // Receiver event handler int handle(int event) { int ret = Fl_Box::handle(event); + int len; switch ( event ) { - case FL_DND_ENTER: // return(1) for these events to 'accept' dnd - case FL_DND_DRAG: - case FL_DND_RELEASE: + case FL_DND_ENTER: // return(1) for this event to 'accept' dnd + label("ENTER"); // visible only if you stop the mouse at the widget's border + fprintf(stderr, "FL_DND_ENTER\n"); + dnd_inside = 1; // status: inside the widget, accept drop + ret = 1; + break; + case FL_DND_DRAG: // return(1) for this event to 'accept' dnd + label("drop\nhere"); + fprintf(stderr, "FL_DND_DRAG\n"); ret = 1; break; + case FL_DND_RELEASE: // return(1) for this event to 'accept' the payload (drop) + fprintf(stderr, "FL_DND_RELEASE\n"); + if (dnd_inside) { + ret = 1; // return(1) and expect FL_PASTE event to follow + label("RELEASE"); + } else { + ret = 0; // return(0) to reject the DND payload (drop) + label("DND\nREJECTED!"); + } + break; case FL_PASTE: // handle actual drop (paste) operation - label(Fl::event_text()); + fprintf(stderr, "FL_PASTE\n"); + copy_label(Fl::event_text()); fprintf(stderr, "Pasted '%s'\n", Fl::event_text()); + + // Don't pop up dialog windows in FL_DND_* or FL_PASTE event handling + // resulting from DND operations. This may hang or even crash the + // application on *some* platforms. Use a short timer to delay the + // message display after the event processing is completed. + + delete[] dnd_text; // don't leak (just in case) + dnd_text = 0; + + len = Fl::event_length(); + if (len && Fl::event_text()) { + dnd_text = new char[len + 1]; + memcpy(dnd_text, Fl::event_text(), len); + dnd_text[len] = '\0'; + Fl::add_timeout(0.001, timer_cb, this); // delay message popup + } ret = 1; break; + case FL_DND_LEAVE: // not strictly necessary to return(1) for this event + label("..to\nhere"); // reset label + fprintf(stderr, "FL_DND_LEAVE\n"); + dnd_inside = 0; // status: mouse is outside, don't accept drop + ret = 1; // return(1) anyway.. + break; } return(ret); } + + // static timer callback + static void timer_cb(void *data) { + Receiver *r = (Receiver *)data; + r->dnd_cb(); + } + + // dnd (FL_PASTE) popup method + void dnd_cb() { + if (dnd_text) { + fl_message("%s", dnd_text); + delete[] dnd_text; + dnd_text = 0; + } + } }; + int main(int argc, char **argv) { // Create sender window and widget Fl_Window win_a(0,0,200,100,"Sender"); |
