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

Reply via email to