summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorAlbrecht Schlosser <albrechts.fltk@online.de>2017-09-08 15:02:04 +0000
committerAlbrecht Schlosser <albrechts.fltk@online.de>2017-09-08 15:02:04 +0000
commitae983b74f271c2466804b1a9ab071a4fc8b1b4d0 (patch)
tree1987bc534ee2e1ab32ca026267af7689a0c4d282 /examples
parent0bf5f9809a0c5c15cfc486e215f30a2a539e088e (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')
-rw-r--r--examples/howto-drag-and-drop.cxx84
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");