Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    An unexpected dropout event is triggered before a drop event

    When dropping an element, a dropOut event is always triggered before the drop event.

    Here is a code sample that triggers it:



    VLayout layout = new VLayout();
    layout.setWidth100();
    layout.setHeight100();

    Button b = new Button("Drop me on the red canvas");
    b.setCanDrag(true);
    b.setCanDrop(true);
    layout.addMember(b);

    Canvas c = new Canvas();
    c.setCanAcceptDrop(true);
    c.setBackgroundColor("red");
    c.setWidth100();
    c.setHeight100();
    c.addDropHandler(new DropHandler() {

    @Override
    public void onDrop(DropEvent event) {
    GWT.log("drop");
    }
    });
    c.addDropOutHandler(new DropOutHandler() {

    @Override
    public void onDropOut(DropOutEvent event) {
    GWT.log("dropout");
    }
    });

    layout.addMember(c);
    layout.draw();


    This requires the application to do some extra checks to distinguish between a real drop out when the mouse actually leaves the drop target and a bad one that should be ignored.


    SmartGWT version: SNAPSHOT_v11.1d_2017-01-05
    Tested on Chrome 55.0.2883.87 and Firefox 50.1.0

    #2
    This is by design. DropOut tells you the drop interaction has completed, and is the right place to clean up things like temporary drop indicators.

    Generally, this leads to nice clean code, since you don't have to put cleanup code *both* in DropOut and in Drop.

    If you're having trouble, post about the specific actions involved in your drop interaction, where you don't understand where best to put the code.

    Comment


      #3
      This directly contradicts the documentation: "Executed when the dragged object is moved out of the rectangle of this drop target.".

      Moreover, there is a problem with this approach because there are sometimes false positives when we actually get outside the drop target very slowly. In one of my canvasses, I have the following code:

      @Override
      public void onDropOut(DropOutEvent event) {
      if (canvas.containsPoint(event.getX(), event.getY(), true)) {
      GWT.log("drop out for x,y="+event.getX()+","+event.getY()+" canvas="
      +canvas.getAbsoluteLeft()+","+canvas.getAbsoluteTop()+"-"
      +(canvas.getAbsoluteLeft() + canvas.getWidth())+","
      +(canvas.getAbsoluteTop() + canvas.getHeight()));
      }
      }

      I would expect this to never occur when I move the mouse out of the canvas before the drop is complete. However it happens sometimes:

      drop out for x,y=300,122 canvas=100,100-734,124

      This kind of false positive combined to this design decision makes it difficult to have a reliable implementation because I am now in a situation where I have to wait and see if a drop event comes in to confirm that the drop actually succeeded inside the drop target.

      Comment


        #4
        We'll clarify the docs, but this isn't a behavior that's changing. We've implemented thousands of drag and drop operations over the years, and it's clear to us that this is the most useful behavior for this event.

        On your other point, it seems like you're saying you received a dropOut with coordinates still within the Canvas. This could be a native browser bug (reporting wrong coordinates or sizes), or a subtlety of styling (browser mouseOuts will occur over a CSS margin, whereas for containsPoint(), we consider the margin as part of the bounds of a Canvas). We'd need a complete test case, version and browser information before we'd look further.

        In any case, we're not following how this creates a coding issue for you. You don't seem to be reporting an absence of a dropIn after seeing a dropOut like this, so there doesn't seem to be an issue with writing cleanup code in the usual way.

        If you want help with how to structure your code, again we really need to know what specific actions you're taking where you don't understand when to trigger the action. Please do not expect further replies if you again ignore this question and continue to argue in the abstract.

        Comment


          #5
          The issue is the following. When the mouse enters the drop target, I need to start some processing. This processing should be cancelled and the related resources cleaned up if the drop operation is abandoned by the user, but it should keep going if the drop completes successfully. As far as I understand, the drop event is my only reliable way to know that the drop is successful and it happens after a dropOut occurred. So, when the dropOut occurs, I don't know whether I should clean or not.

          Comment


            #6
            Unusual scenario, easy enough to solve: Drop fires fires synchronously after DropOut. Set a timer in DropOut with a 0ms delay. If Drop hasn't fired when the timer goes off, cancel the processing.

            Comment


              #7
              That's how I had solved the problem, but I wasn't sure about which delay would be safe. Nice to know that 0ms will do the trick. Thank you.

              Comment

              Working...
              X