Author: spitzak
Date: 2007-07-23 13:12:39 -0700 (Mon, 23 Jul 2007)
New Revision: 5934
Log:
Drag & Drop was completly broken on OSX. Also added a new "dnd" test program
and fixed a few bugs found with that as well.
Added:
trunk/test/dnd.cxx
Modified:
trunk/OpenGL/Fl_Gl_Choice.cxx
trunk/fltk/Browser.h
trunk/src/Group.cxx
trunk/src/Widget.cxx
trunk/src/message.cxx
trunk/src/osx/run.cxx
trunk/src/x11/dnd.cxx
Modified: trunk/OpenGL/Fl_Gl_Choice.cxx
===================================================================
--- trunk/OpenGL/Fl_Gl_Choice.cxx 2007-07-19 18:48:15 UTC (rev 5933)
+++ trunk/OpenGL/Fl_Gl_Choice.cxx 2007-07-23 20:12:39 UTC (rev 5934)
@@ -306,17 +306,15 @@
}
void fltk::no_gl_context() {
- if (fl_current_glcontext != first_context) {
#if USE_X11
- if (first_context) glXMakeCurrent(xdisplay, message_window, first_context);
+ glXMakeCurrent(xdisplay, 0, 0);
#elif defined(_WIN32)
- wglMakeCurrent(getDC(), first_context);
+ wglMakeCurrent(0, 0);
#elif defined(__APPLE__)
- // warning: the Quartz version should probably use Core GL (CGL) instead
of AGL
- aglSetCurrentContext(first_context);
+ // warning: the Quartz version should probably use Core GL (CGL) instead of
AGL
+ if (fl_current_glcontext) aglSetCurrentContext(0);
#endif
- fl_current_glcontext = first_context;
- }
+ fl_current_glcontext = 0;
cached_window = 0;
}
Modified: trunk/fltk/Browser.h
===================================================================
--- trunk/fltk/Browser.h 2007-07-19 18:48:15 UTC (rev 5933)
+++ trunk/fltk/Browser.h 2007-07-23 20:12:39 UTC (rev 5934)
@@ -40,10 +40,10 @@
enum { //<! values for type()
IS_MULTI = 1,
- NORMAL = GROUP_TYPE, //!< means single selection can be achieved by user
+ NORMAL = GROUP_TYPE, //!< means single selection can be achieved by user
MULTI = GROUP_TYPE+1 //!< means multiple selection can be achieved by
user
};
- enum { /// value for selected_column
+ enum { // value for selected_column
NO_COLUMN_SELECTED = -1 //!< means that no column has been selected by user
};
@@ -159,7 +159,7 @@
void display_lines(bool display);
int load(const char *filename);
-
+
int multi() const {return type()&IS_MULTI;}
const Symbol* leaf_symbol() const {return leaf_symbol_;}
@@ -168,7 +168,7 @@
void group_symbol(const Symbol* s) {group_symbol_ = s;}
protected:
- void handle_callback(int doit); /// defines how cb are handled in the browser
+ void handle_callback(int doit); // defines how cb are handled in the browser
private:
bool displaylines_;
Modified: trunk/src/Group.cxx
===================================================================
--- trunk/src/Group.cxx 2007-07-19 18:48:15 UTC (rev 5933)
+++ trunk/src/Group.cxx 2007-07-23 20:12:39 UTC (rev 5934)
@@ -346,6 +346,7 @@
case RELEASE:
case LEAVE:
case DND_LEAVE:
+ case DND_RELEASE:
// Ignore these. We handle them if the belowmouse of pushed widget
// has been set to this. Subclasses may do something with these.
// Definately do not pass them to child widgets!
Modified: trunk/src/Widget.cxx
===================================================================
--- trunk/src/Widget.cxx 2007-07-19 18:48:15 UTC (rev 5933)
+++ trunk/src/Widget.cxx 2007-07-23 20:12:39 UTC (rev 5934)
@@ -671,12 +671,14 @@
redraw_highlight();
// fall through to MOVE:
case MOVE:
- // Setting belowmouse directly is not needed by most widgets, as
- // send() will do it if this returns true. However if this widget
- // has children and one of them is the belowmouse, send will not
- // change it, so I have to call this here.
+ // This calls belowmouse() directly do this works as the fallback
+ // for Group::handle(), and also so it somewhat works if called
+ // directly rather than from send():
fltk::belowmouse(this);
return true;
+ case DND_DRAG:
+ fltk::belowmouse(this);
+ return false;
case LEAVE:
redraw_highlight();
return true;
@@ -735,14 +737,12 @@
// figure out correct type of event:
event = (contains(fltk::belowmouse())) ? MOVE : ENTER;
ret = handle(event);
- if (ret) {
- // If return value is true then this is the belowmouse widget,
- // set it, but only if handle() did not set it to some child:
- if (!contains(fltk::belowmouse())) fltk::belowmouse(this);
- }
+ // Set belowmouse only if handle() did not set it to some child:
+ if (!contains(fltk::belowmouse())) fltk::belowmouse(this);
break;
case LEAVE:
+ case DND_LEAVE:
clear_flag(HIGHLIGHT);
ret = handle(event);
break;
@@ -755,11 +755,8 @@
event = (contains(fltk::belowmouse())) ? DND_DRAG : DND_ENTER;
// see if it wants the event:
ret = handle(event);
- if (ret) {
- // If return value is true then this is the belowmouse widget,
- // set it, but only if handle() did not set it to some child:
- if (!contains(fltk::belowmouse())) fltk::belowmouse(this);
- }
+ // Set belowmouse only if handle() did not set it to some child:
+ if (!contains(fltk::belowmouse())) fltk::belowmouse(this);
break;
case PUSH:
Modified: trunk/src/message.cxx
===================================================================
--- trunk/src/message.cxx 2007-07-19 18:48:15 UTC (rev 5933)
+++ trunk/src/message.cxx 2007-07-23 20:12:39 UTC (rev 5934)
@@ -124,13 +124,13 @@
window.resize_align(ALIGN_TOP|ALIGN_RIGHT);
// w->size_range(window.w(), window.h(), 0, window.h());
- char buffer[1024];
+ char buffer[2048];
if (!strcmp(fmt,"%s")) {
message.label(va_arg(ap, const char*));
} else if (!strchr(fmt, '%')) {
message.label(fmt);
} else {
- vsnprintf(buffer, 1024, fmt, ap);
+ vsnprintf(buffer, 2048, fmt, ap);
message.label(buffer);
}
@@ -229,7 +229,7 @@
Same as fltk::message() except for the "!" symbol.
*/
void fltk::alert(const char *fmt, ...) {
- if (fltk::beep_on_dialog()) (fltk::beep(fltk::BEEP_ERROR));
+ if (fltk::beep_on_dialog()) (fltk::beep(fltk::BEEP_ERROR));
va_list ap;
va_start(ap, fmt);
innards("!", 0, 0, fmt, ap, ok, 0, 0);
Modified: trunk/src/osx/run.cxx
===================================================================
--- trunk/src/osx/run.cxx 2007-07-19 18:48:15 UTC (rev 5933)
+++ trunk/src/osx/run.cxx 2007-07-23 20:12:39 UTC (rev 5934)
@@ -45,6 +45,7 @@
#include <fltk/ItemGroup.h>
#include <fltk/Style.h>
#include <fltk/utf.h>
+#include <fltk/Cursor.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
@@ -232,8 +233,6 @@
// on every event to stop it.
static void *select_thread_proc(void *userdata)
{
- EventQueueRef eventqueue = (EventQueueRef)userdata;
-
while (1) {
if (run_select(1e20, true, true)) {
// wake up the main thread with a message:
@@ -1226,12 +1225,24 @@
////////////////////////////////////////////////////////////////
-Window *dnd_target_window = 0;
#include <fltk/draw.h>
+
+static void show_drag(bool v, Widget* target, DragReference dragRef) {
+ if (v) {
+ target->cursor(CURSOR_HAND);
+ //ShowDragHilite( dragRef );
+ } else {
+ target->cursor(CURSOR_DEFAULT);
+ //HideDragHilight( dragRef );
+ }
+ fltk::flush(); // make any fltk drawing get done
+}
+
/*
* Drag'n'drop tracking handler
*/
-//+++ verify port to FLTK2
+static DragReference current_drag;
+
static pascal OSErr dndTrackingHandler( DragTrackingMessage msg, WindowPtr w,
void *userData, DragReference dragRef )
{
Window *target = (Window*)userData;
@@ -1247,13 +1258,8 @@
e_y_root = py = mp.v;
e_x = px - target->x();
e_y = py - target->y();
- dnd_target_window = target;
-#if 0
- if ( handle( DND_ENTER, target ) )
- cursor( CURSOR_HAND ); //ShowDragHilite( ); // modify the mouse cursor?!
- else
- cursor( CURSOR_DEFAULT ); //HideDragHilite( dragRef );
-#endif
+ show_drag( handle( DND_ENTER, target ), target, dragRef);
+ current_drag = dragRef;
return noErr;
case kDragTrackingInWindow:
GetDragMouse( dragRef, &mp, 0 );
@@ -1263,22 +1269,12 @@
e_y_root = py = mp.v;
e_x = px - target->x();
e_y = py - target->y();
- dnd_target_window = target;
-#if 0
- if ( handle( DND_DRAG, target ) )
- cursor( CURSOR_HAND ); //ShowDragHilite( ); // modify the mouse cursor?!
- else
- cursor( CURSOR_DEFAULT ); //HideDragHilite( dragRef );
-#endif
+ show_drag ( handle( DND_DRAG, target ), target, dragRef);
return noErr;
- break;
case kDragTrackingLeaveWindow:
- // HideDragHilite()
- // cursor( CURSOR_DEFAULT ); //HideDragHilite( dragRef );
- if ( dnd_target_window )
- {
- handle( DND_LEAVE, dnd_target_window );
- dnd_target_window = 0;
+ if (current_drag) { // ignore if release was done
+ handle( DND_LEAVE, target );
+ show_drag( false, target, dragRef );
}
return noErr;
}
@@ -1295,15 +1291,20 @@
Point mp;
OSErr ret;
- Window *target = dnd_target_window = (Window*)userData;
+ Window *target = (Window*)userData;
GetDragMouse( dragRef, &mp, 0 );
e_x_root = mp.h;
e_y_root = mp.v;
e_x = e_x_root - target->x();
e_y = e_y_root - target->y();
- if ( !handle( DND_RELEASE, target ) )
+
+ ret = handle( DND_RELEASE, target );
+ Widget* droptarget = belowmouse();
+ show_drag( false, target, dragRef );
+ current_drag = 0;
+ if (!ret || !droptarget)
return userCanceledErr;
-
+
// get the ASCII text
UInt16 i, nItem;
ItemReference itemRef;
@@ -1358,10 +1359,9 @@
dst[-1] = 0;
// if ( e_text[e_length-1]==0 ) e_length--; // modify, if trailing 0 is part
of string
e_length = dst - e_text - 1;
- target->handle(PASTE);
+ droptarget->handle(PASTE);
free(buffer);
- dnd_target_window = 0L;
return noErr;
}
Modified: trunk/src/x11/dnd.cxx
===================================================================
--- trunk/src/x11/dnd.cxx 2007-07-19 18:48:15 UTC (rev 5933)
+++ trunk/src/x11/dnd.cxx 2007-07-23 20:12:39 UTC (rev 5934)
@@ -135,7 +135,7 @@
drop_ok = true;
moved = true;
- while (pushed()) {
+ while (event_state(ANY_BUTTON)) {
// figure out what window we are pointing at:
XWindow new_window = 0; int new_version = 0;
Added: trunk/test/dnd.cxx
===================================================================
--- trunk/test/dnd.cxx (rev 0)
+++ trunk/test/dnd.cxx 2007-07-23 20:12:39 UTC (rev 5934)
@@ -0,0 +1,83 @@
+#include <fltk/run.h>
+#include <fltk/Window.h>
+#include <fltk/events.h>
+#include <fltk/string.h>
+#include <fltk/MultiLineOutput.h>
+#include <stdio.h>
+
+using namespace fltk;
+
+Widget* bluewidget = 0;
+Widget* greenwidget = 0;
+MultiLineOutput* output = 0;
+
+class DNDTarget : public Widget {
+public:
+ int handle(int event) {
+ switch (event) {
+ case PUSH:
+ //printf("%s : starting dnd()\n", label());
+ if (greenwidget) {
+ greenwidget->color(0); greenwidget->redraw(); greenwidget = 0;
+ }
+ bluewidget = this; color(12); redraw();
+ fltk::copy(label(), strlen(label()));
+ fltk::dnd();
+ bluewidget = 0;
+ if (this != greenwidget) {color(0); redraw();}
+ return true;
+ case DND_ENTER:
+ if (greenwidget) {
+ greenwidget->color(0); greenwidget->redraw(); greenwidget = 0;
+ }
+ //printf("%s : DND_ENTER\n", label());
+ color(RED); redraw();
+ return 1;
+ case DND_DRAG:
+ // bug? You must implement this and return 1 or drop will not happen
+ return 1;
+ case DND_LEAVE:
+ //printf("%s : DND_LEAVE\n", label());
+ color(this==bluewidget ? 12 : 0); redraw();
+ return 1;
+ case DND_RELEASE:
+ //printf("%s : DND_RELEASE\n", label());
+ color(10); redraw(); // this should never be seen as paste replaces it!
+ return 1;
+ case PASTE:
+ //printf("%s : PASTE '%s'\n", label(), fltk::event_text());
+ greenwidget = this; color(GREEN); redraw();
+ ::output->text(fltk::event_text());
+ return 1;
+ default:
+ return Widget::handle(event);
+ }
+ }
+
+ DNDTarget(int x, int y, int w, int h, const char* l) :
+ Widget(x,y,w,h) { copy_label(l); }
+};
+
+#define SIZE 30
+#define BORDER 10
+#define NUM 5
+
+int main(int argc, char** argv) {
+ Window window(NUM*(SIZE+BORDER)+BORDER,
+ NUM*(SIZE+BORDER)+BORDER+50+2*BORDER);
+ window.begin();
+ for (int y = 0; y < NUM; y++) {
+ for (int x = 0; x < NUM; x++) {
+ char buf[100];
+ sprintf(buf, "%d", x+NUM*y+1);
+ new DNDTarget(BORDER+x*(SIZE+BORDER), BORDER+y*(SIZE+BORDER),
+ SIZE, SIZE, buf);
+ }
+ }
+ output = new MultiLineOutput(BORDER, 2*BORDER+NUM*(SIZE+BORDER),
+ NUM*(SIZE+BORDER)-BORDER, 50,
+ "Last paste:");
+ output->align(fltk::ALIGN_TOP|fltk::ALIGN_LEFT);
+ window.show(argc, argv);
+ return fltk::run();
+}
_______________________________________________
fltk-commit mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-commit