Drag and drop questions

I have a DesktopContainer and an instance thereof in my app. The DesktopContainer has an HTMLViewer and a TextArea within it. I want to be able to drag/drop images onto the HTMLViewer and have it display them; it already has everything required for this to work, as indeed it does if I put the DropObject event on the TextaArea and the AcceptFileDrop in the TextArea’s Opening event. Then I can drop image files on the TextArea and my code makes them appear in the HTMLViewer. But any user would find this odd and expect to be able to drop the files anwhere within the container.

The difficulty is that an HTMLViewer doesn’t have any drag events. So I’ve put a canvas on top of the other controls in the Container, which appears to intercept the dropped files satisfactorily, but not, fortunately, keystrokes destined for the HTMLViewer.

However this would seem to be a work-around more than anything. So:

  1. Are there any downisides to using a canvas in this way
  2. Why can’t I put the DropObject event and AcceptFileDrop on the DesktopContainer?

I’m using Catalina, 2023r1.1, and all API2.

I can’t find DragEnter, DragEnter and DragExit in the docs. But I can add the events to a HtmlViewer.

Sorry - my mistake. It doesn’t have the DropObject event (it does have the others).

You are correct. But this is really weird. The 3 drag events and methods like AcceptFileDrop/AcceptPictureDrop suggest that drag and drop should work. Does DropObject work for the Window or Container of the HtmlViewer?

Edit: found this in the docs:

DropObject Event:

If obj.PictureAvailable Then
  Me.Backdrop = obj.Picture
End If

It looks like an oversight that DropObject is missing.

By oversight, do you mean that Xojo forgot to implement it, or forgot to document it (and the others, in the case of docs)?

DropObject is not listed as an option when you select “Add Event Handler …” to the HTMLViewer. I can add it to the Container of the HTMLViewer, but it does not fire. Or, as I mentioned in my OP, I can add it to TextArea in the Container, where it fires and the dropped images are treated as I expect. Likewise the Canvas.

Hmm, I’ll see whether I can AddHandler it.

Humph. Well, I can AddHandler it and get the syntax right, and the compiler is happy. This is in the Opening event handler for the HTMLViewer:

AddHandler me.DropObject, AddressOf myDropper

where myDropper is a method on the Container. I also removed the Canvas. But I get this RuntimeException:

Attempting to add a handler for an event that was already handled.

Already handled? Really? Where?

I ran in to this some years ago. DropObject does not exist for HTMLViewers, and – if I remember correctly – this was intentional. I had to write some Javascript to intercept the drop using the page body’s drag events (dragenter, dragover, dragleave, and drop). I then used executeInXojo to pass the data back.

@William_Yu could provide some more insight.

EDIT: Found the relevant cases: 20417 and 23411.

Thank you for the information. But there is no reason given why these have been removed.

I can’t answer that. That’s why I tagged William.

Thank you.

Thanks for that. Then ideally the drag events shouldn’t be offered and I shouldn’t be able to apparently add a handler for DropObject.

So I’m back to the canvas unless there’s a better alternative.

The cases say they were removed. Looks like they crept back in at some point. Javascript is probably the best solution currently if dealing with file drops.

Or a Canvas - via drag and drop - that embed the image reference and pass html code using HTMLViewer1.LoadPage(htmlcode,f)

Everything needed is already there in the HTMLViewer. All I have to do, having validated the file as existing, not a folder, and being an image, is to pass a URL for the file into the HTMLViewer, done via ExecuteJavaScriptSync.

I would still like to have Canvas approach validated by someone as the way to go, before I definitively include it in my next build.

As long as you don’t see side effects, why not? I haven’t tried it myself, so it’s your call to make as you implement.

I’m going home and will test my suggestion. I give the results tomorrow.
I am sure at 99.99% it will works.

IIRC, the WebView inside the viewer captures the drag and drop events and it would require a lot of work to prevent. Once that was done, there would be no way to allow users to have the events go through JavaScript if they wanted to. For instance, if the content being shown within the viewer supported drag and drop, that wouldn’t work at all.

Works nicely n macOS (as far as I can tell) but did require adding a MouseDown for the Canvas,so that, if clicked, the focus is passed to to the underlying HTMLViewer.

Unfortunately a Canvas under Windows is not transparent so it can’t work there. I did try setting the Canvas to be not Visible, but sadly this has much the same effect as setting it not Enabled; the DropFile event does not fire.