Drag'n'drop between apps

AmigaOS users can make feature requests in this forum.
User avatar
gonegahgah
Posts: 43
Joined: Fri May 31, 2013 4:22 pm

Re: Drag'n'drop between apps

Post by gonegahgah »

nbache wrote:MUI does seem to provide D&D between windows. At least I know that in YAM I can drag a mail from the Inbox list to the attachment tab of a write window in order to attach the mail.
Cool, thanks Niels.
I was looking at the MUI demos and poorly guessing from that.
I imagine the drop zones are tightly tied to matching drag zones in MUI?

Speaking of MUI. I registered it at http://www.sasg.com/mui/ and paid the US$25.
I didn't receive anything. No unlock key; no email response?
Should I just ask PayPal to cancel my payment or is there something else I can do to receive my key? Anyone know?
chris
Posts: 552
Joined: Sat Jun 18, 2011 11:05 am
Contact:

Re: Drag'n'drop between apps

Post by chris »

gonegahgah wrote:If it is only receivers you can get around creating a file.
Instead you could create a virtual file and provide all the file handling routines so the reader could read your virtual file like they would a real one.
Incidentally, datatypes.library does this exact thing - if a program provides a memory pointer to create a datatypes object out of, when the datatype subclass receives it it looks exactly like a file, and is read using the DOS functions.
Unfortunately that creates a bit of duplication because an app has to consider that its draggable content may be taken to either a new style app or a legacy app.
So it has to both create a file and provide an object interface.
That's because there is no way to know in advance where the user is going to drag the content.
It shouldn't need to, as any object creation could create the file itself, probably on demand if it is determined that it is needed.

The application could flag that a particular drag isn't suitable for legacy applications - eg. spreadsheet cells.
Hmm, interesting. I implemented this in NetSurf for various things, and it works between windows. The easy one to test is dragging something from the hotlist or history windows into the main browser window, but you can also drag text selections between browser windows.
Well done. As I guessed correctly, and as you've now shown, it is possible for an app to set up its own drag'n'drop between its own windows.
The next ideal direction is to make this possible across apps as well.
That's a good point, actually. A URL dragged from one web browser hotlist should be able to be dropped into the window of a different web browser. That's something else which isn't truly "file compatible".
User avatar
nbache
Beta Tester
Beta Tester
Posts: 1506
Joined: Mon Dec 20, 2010 7:25 pm
Location: Copenhagen, Denmark
Contact:

Re: Drag'n'drop between apps

Post by nbache »

gonegahgah wrote:I imagine the drop zones are tightly tied to matching drag zones in MUI?
Sorry, no idea. I don't know anything about how it's implemented and have almost no MUI programming experience at all. But at least there is some standard D&D support in MUI itself (i.e. it's not all implemented in YAM's own code), because the MUI prefs program has a tab page devoted to the behaviour of D&D.
Speaking of MUI. I registered it at http://www.sasg.com/mui/ and paid the US$25.
I didn't receive anything. No unlock key; no email response?
Should I just ask PayPal to cancel my payment or is there something else I can do to receive my key? Anyone know?
I think I have heard that people still do receive responses once in a while, but with very long waiting times. But that was several years ago, so it might have dried out completely. Anybody with more recent info?

Best regards,

Niels
User avatar
gonegahgah
Posts: 43
Joined: Fri May 31, 2013 4:22 pm

Re: Drag'n'drop between apps

Post by gonegahgah »

nbache wrote:
gonegahgah wrote:I imagine the drop zones are tightly tied to matching drag zones in MUI?
Sorry, no idea. I don't know anything about how it's implemented and have almost no MUI programming experience at all. But at least there is some standard D&D support in MUI itself (i.e. it's not all implemented in YAM's own code), because the MUI prefs program has a tab page devoted to the behaviour of D&D.
Out of curiosity I checked the DragDrop.c source code at http://aminet.net/package/dev/mui/mui38dev.

The primary line is: if(msg->obj == (Object *) muiUserData(obj))

The muiUserData() is not important in this line. You could check for any object.
This approach is actually quite flexible.
It is up to the programmer to decide how they will decide on which sender objects to listen to.
So you probably could set up a standard interface for querying foreign objects using MUI.

In the above the destination is asked, by 'msg', if they are interested when the drag '->obj' is over them and they can reply MUIV_DragQuery_Accept if it is an object they know.
Very nice. I would still like to allow for advance warning though but being able to show recognition when a drag item is over them is very good.
And being able to do so for different source objects is flexible, as it should be, but it doesn't look like anyone has coded automatic foreign object handling using MUI.
It should be possible to, I think, with the flexibility provided? So I can't say that foreign drag'n'drop couldn't be done with MUI.

You would need to write new receiver and sender objects. Existing ones couldn't handle foreign objects.
User avatar
gonegahgah
Posts: 43
Joined: Fri May 31, 2013 4:22 pm

Re: Drag'n'drop between apps

Post by gonegahgah »

chris wrote:Incidentally, datatypes.library does this exact thing - if a program provides a memory pointer to create a datatypes object out of, when the datatype subclass receives it it looks exactly like a file...
I'm not 100% conversant with datatypes but looking at http://wiki.amigaos.net/index.php/Datatypes_Library I don't think that it would work in the context we are speaking about.
Reading the web page, the subclass gets this file pointer from the major type; which is exactly what you have said in your quote.

ie. "The first step that a [sub]class has to perform in order to convert the source data, is to get a handle on the data. This is obtained by passing the DTA_Handle tag to the super-class using the OM_GET method."
"If the source Type is DTF_IFF, then DTA_Handle points to a struct IFFHandle that is already initialized and opened for reading, otherwise the handle points to a BPTR file handle."

It is only a file pointer for the purposes of writing a subclass so the subclass can read from the file of a type that it knows how to translate. The apps are still expected to deal with datatypes through objects; not this file pointer.
The datatype idea is so that an app doesn't have to recognise a file format and instead just use datatypes to create the general type of data in memory. The data must then be obtained or interacted with via an object.
So this doesn't really work as a virtual file system for our purposes.
chris wrote:
Unfortunately that creates a bit of duplication because an app has to consider that its draggable content may be taken to either a new style app or a legacy app.
So it has to both create a file and provide an object interface.
That's because there is no way to know in advance where the user is going to drag the content.
It shouldn't need to, as any object creation could create the file itself, probably on demand if it is determined that it is needed.
Let's look at the mechanism of getting dropped objects. It is by set up and message receipt.

First we: AddAppWindow(id, userdata, window, msgport, taglist)

This adds the window you specify to Workbench's list of app windows. Workbench will then send a message to 'msgport' if a workbench icon(s) is dropped into our window.
The app receives a list of WBArg structures for each icon in the message.

So to provide dropping files into legacy receiver apps, from newly written senders apps, Workbench needs to be modified in one of three ways:
1. Workbench has to move icons that are submitted from sources other than its own windows, or
2. Workbench provides access to its app window list and icon list (which is not likely), or
3. Modify WhichWorkbenchObject() to also return pointers to app windows (not sure if this is possible due to window closing issues).

With (1) Workbench could be modified to not require the app to provide the file until it has found a drop window or zone. You would probably need to pass your handleinput messages to Workbench?
With (2) control would be turned over to you so you would have to determine if the pointer is dropped over an app window. I assume some sort of locking would be necessary which may be messy.
With (3) this would be the simplest but perhaps can't be done for reasons of window unpredictability; similar to (2). Otherwise you could send your own AppMessages to these Window app message ports.

But with (1) the app would have to madly create a file when a destination were indicated so that Workbench could deliver this virtual file to the legacy receiver. This might bog down Workbench/the input process/something...
So, it would make more sense to create the virtual file before you begin moving it, or in a separate creation thread while the virtual icons are moved.
Any which way a virtual file needs to be created (unless it's an attachment as it already exists; but an image needs to be converted to a file first). At some stage the legacy receiver needs a file path(s).
If icons are being dragged and the file isn't created in time then Workbench will still probably be held up so that the app window doesn't disappear and cause an invalid message to be sent to a non-existent window.
Maybe it could be done or maybe it is just too messy.

I think it would possibly be the only simple solution to generate a virtual file(s) first and ask a modified Workbench to deliver these. ie. AppDeliverVirtualFile()
You would also need to do this either in parallel to a second process for newly written receivers or AppDeliverVirtualFile() would also have to report back if the drop is over a new style receiver that aren't app windows.
You would still have to notify the relevant translators that you are carrying something they can translate - for the new style receivers. Hmmm, sounds like a bit to do...

Addendum:
Again, it may be possible to actually create a class that returns a virtual file of some sort. Probably a worthwhile exercise in itself.
Also, you would probably want to bring Workbench into the game for new style receivers - so that they can receive files too - so maybe(?) these could be cross-incorporated.
chris wrote:The application could flag that a particular drag isn't suitable for legacy applications - eg. spreadsheet cells.
I still tend to think it is probably overall just easier to drag it from the source app into RAM: and then drag it from RAM: into the destination app.

We have to have some changes to the system first to even explore adding this feature for legacy receiver apps.
And sender apps have to be modified to adopt some new system for the whole point of this post to be workable.
I don't think it would be worthwhile to rewrite the existing system purely for the sake of copying files from new senders to legacy receivers.
It's only really worthwhile to write something new if you are adding something that can't presently be done by some means and that is desirable; I feel.
You're suggestion for legacy apps is certainly worthwhile in itself, but it can already presently be done; albeit by a two step process.
chris wrote:A URL dragged from one web browser hotlist should be able to be dropped into the window of a different web browser. That's something else which isn't truly "file compatible".
True.
chris wrote:Incidentally, datatypes.library does this exact thing...
Speaking of datatypes.library it may be worthwhile supporting it as one channel for drag'n'drop.
The major problem I have with it is that you don't get any options on the final product of this solution.
A picture is presented as a complete picture to your app. What if you want to use, as an example, progressive loading?

I would tend towards a different approach. It would be a full 180° on how things seem to be presently done.
That is the app end utilises its own chosen datatypes rather than needing the overly generalised datatype ones we presently have.
I think that that will give us a lot more flexibility.
chris
Posts: 552
Joined: Sat Jun 18, 2011 11:05 am
Contact:

Re: Drag'n'drop between apps

Post by chris »

gonegahgah wrote:It is only a file pointer for the purposes of writing a subclass so the subclass can read from the file of a type that it knows how to translate. The apps are still expected to deal with datatypes through objects; not this file pointer.
The datatype idea is so that an app doesn't have to recognise a file format and instead just use datatypes to create the general type of data in memory. The data must then be obtained or interacted with via an object.
So this doesn't really work as a virtual file system for our purposes.
It was just an example of where this sort of thing was already being used. However I think AppMessages need a file path rather than a BPTR so it probably isn't relevant anyway.
We have to have some changes to the system first to even explore adding this feature for legacy receiver apps.
And sender apps have to be modified to adopt some new system for the whole point of this post to be workable.
I don't think it would be worthwhile to rewrite the existing system purely for the sake of copying files from new senders to legacy receivers.
It's only really worthwhile to write something new if you are adding something that can't presently be done by some means and that is desirable; I feel.
Yes, agreed - get it working for new apps first, then if it is possible to make it send through the existing AppMessages do that later.
Speaking of datatypes.library it may be worthwhile supporting it as one channel for drag'n'drop.
Yes - a DataTypes object could be passed through, as long as the receiver acknowledges receipt, as it would then be responsible for disposing of it later.
The major problem I have with it is that you don't get any options on the final product of this solution.
A picture is presented as a complete picture to your app. What if you want to use, as an example, progressive loading?
If it's a DTObject then it has already been decoded and is in memory, so progressive loading isn't an issue. Progressive decoding might be for extremely large images. DataTypes does have some limited ability for this but I'm not sure if it is functional.
I would tend towards a different approach. It would be a full 180° on how things seem to be presently done.
That is the app end utilises its own chosen datatypes rather than needing the overly generalised datatype ones we presently have.
I think that that will give us a lot more flexibility.
I don't get what you mean?
User avatar
gonegahgah
Posts: 43
Joined: Fri May 31, 2013 4:22 pm

Re: Drag'n'drop between apps

Post by gonegahgah »

chris wrote:If it's a DTObject then it has already been decoded and is in memory, so progressive loading isn't an issue. Progressive decoding might be for extremely large images. DataTypes does have some limited ability for this but I'm not sure if it is functional.
That was one example. Others might be: obtaining only a portion of a picture, obtaining a single frame as an image from a video...
I don't get what you mean?
I would use something more along the lines of: app <--> formclass <--> fileclass <--> "file" rather than app <--> datatype <--> "file".
The app should be able to chose its own form of data that it uses; not the datatype.
It also would allow an easier broadening of the types of data supported.
chris
Posts: 552
Joined: Sat Jun 18, 2011 11:05 am
Contact:

Re: Drag'n'drop between apps

Post by chris »

gonegahgah wrote:I would use something more along the lines of: app <--> formclass <--> fileclass <--> "file" rather than app <--> datatype <--> "file".
The app should be able to chose its own form of data that it uses; not the datatype.
It also would allow an easier broadening of the types of data supported.
I think that should be possible anyway with DataTypes - it already supports base types of IFF, binary and text. A custom format could just be a DataTypes binary class object (hmm... but the receiver still needs to know what format it is in, I'm sure there must be some way this can be done within the DataTypes framework though - probably a new tag on the superclass for specifying a custom file type)
User avatar
gonegahgah
Posts: 43
Joined: Fri May 31, 2013 4:22 pm

Re: Drag'n'drop between apps

Post by gonegahgah »

chris wrote:I think that should be possible anyway with DataTypes - it already supports base types of IFF, binary and text. A custom format could just be a DataTypes binary class object (hmm... but the receiver still needs to know what format it is in, I'm sure there must be some way this can be done within the DataTypes framework though - probably a new tag on the superclass for specifying a custom file type)
As you were referring to as you wrote this, I'm introducing the idea of the destination format. I feel this should have varieties itself and be separated from the source format.

As an example say you have a document app that's wants to limit itself to Rich Text Format features (just to use something we know) and you have a document in WordWorth format that you want to load into it.
You will lose some features of course but if you use a text based datatype you lose even more of WordWorth's features.

So why don't we just write an rtf based datatype. This creates a few things:
- How will datatype store rtf in memory when the datatype loads it?
- How do you differentiate the datatype that loads Wordworth to text from the datatype that loads Wordworth to rtf?

In this example it would be better to create forms/rtf.form and files/ww.file classes.
The later knows how to read a ww.file for all its features. The former stores only the rtf information.

The greater flexibility this provides is that it can then use other combinations like WordPerfect (wp.file) to rtf.form, or even Wordworth (ww.file) to text.form.
Also, it is not limited to provided forms. You can roll your own private forms to get greater control over the data in memory.

How would you do that with datatypes?
chris
Posts: 552
Joined: Sat Jun 18, 2011 11:05 am
Contact:

Re: Drag'n'drop between apps

Post by chris »

gonegahgah wrote:How would you do that with datatypes?
If you're loading files than the application can use its usual file loader - if it doesn't normally use DataTypes for that, it shouldn't need to here.

For forms and other esoteric drags, then I agree DataTypes are probably not the right thing to use. Perhaps it could pass a BOOPSI object - such as a spreadsheet.gadget object, or a sub-class of such with only the relevant data in it?
Post Reply