FLTK logo

Re: [fltk.general] Re: Updating program to 1.4.x

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 All Forums  |  Back to fltk.general  ]
 
Previous Message ]New Message | Reply ]Next Message ]

Re: Re: Updating program to 1.4.x Manolo May 25, 2021  
 
I see that the macOS version of the D-n-D code sends an FL_RELEASE event right after the initial FL_DRAG event,
while the Windows versions sends it after the end of the D-n-D operation. That part of the code is unchanged
between 1.3 and 1.4. Some more analysis is required to determine whether this FL_RELEASE event is wrong
or not. In the meantime, I suggest you modify a bit your handle() function as in the attached code to have it process
the FL_RELEASE event only after the end of a D-n-D operation. With this change, the test program is correct
both under macOS and Windows.

--
You received this message because you are subscribed to the Google Groups "fltk.general" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fltkgeneral+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/fltkgeneral/1e40350a-243c-4bc9-8b02-41d1d0ddcd4bn%40googlegroups.com.
#include <stdio.h>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Button.H>
#include <FL/fl_ask.H> // fl_message()
#include <FL/names.h>

// SIMPLE SENDER CLASS
class Sender : public Fl_Button {
  bool drag_was_completed;
public:
  // Ctor
  Sender(int x,int y,int w,int h, const char *label = 0) : Fl_Button(x,y,w,h,label) {
    drag_was_completed = false;
  }

  // Sender event handler
  int handle(int event) {
//fprintf(stderr, "%s\n", fl_eventnames[event]);
    int ret = Fl_Button::handle(event);
    switch ( event ) {
      case FL_DRAG: {             // do 'copy/dnd' when someone clicks on box
        const char *msg = "It works!";
        Fl::copy(msg,strlen(msg),0);
        drag_was_completed = false;
        Fl::dnd();
        ret = 1;
        break;
      }
      case FL_RELEASE: {
        if( Fl::event_inside( this ) && drag_was_completed) {
          fl_choice("You Pushed the Button!", "Ok", 0, 0);
          ret = 1;
        }
        drag_was_completed = false;
        break;
      }
      case FL_DND_LEAVE:
      case FL_DND_RELEASE:
        drag_was_completed = true;
        break;
    }
    return(ret);
  }
};
// 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 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
        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");
  Sender a(0,0,100,100, "Drag or Push");
  win_a.end();
  win_a.show();
  // Create receiver window and widget
  Fl_Window win_b(400,0,200,100,"Receiver");
  Receiver b(100,0,100,100);
  win_b.end();
  win_b.show();
  return(Fl::run());
}
 
 
Direct Link to Message ]
 
     
Previous Message ]New Message | Reply ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.