The drag message is the one initially sent out by the sender application. It must be assigned a what member of B_SIMPLE_DATA by you, the programmer. The message fields in the drag message can be split into those that are provided by you, and those that are filled in automatically by the system. Let's take a look at each of these.
- The following drag message fields will need to be filled in by your code. Detailed descriptions of these fields are found below.
- "be:types", "be:filetypes", and "be:type_descriptions": These fields indicates the formats the sender is willing to provide data in, and are filled in together.
- "be:actions": A list of actions the sender is willing to perform on its data, at the request of the receiver.
- "be:clip_name": A suggested name for the data being sent, which may be used at the option of the receiver. This field is optional.
- "be:originator", "be:originator_data": used to preserve context information across asynchronous message sendings.
- "be:data": This was used by the old [obsolete] drag'n'drop protocol, to contain the data being dragged. You don't need to use it with modern applications.
- "_drop_point_", "_drop_offset_": The values in these fields are set automatically by the system; do not set them yourself. They give information about where the drop took place on the screen.
Message Fields
- "be:types", "be:filetypes", and "be:type_descriptions" Fields
- The main purpose of negotiated drag'n'drop is to come up with an optimal compromise between the data formats the sender application can provide something in, and the data formats the receiver can accept that data in. Accordingly, the three most important message fields in the drag message are the "be:types" and "be:filetypes" fields; "be:type_descriptions" accompanies the "be:filetypes" field, so we'll describe it here also.. Each of these fields is filled with a list of string values.
- Values for these fields will typically be obtained from the Translation Kit, by asking the Translation Kit which data formats it can provide the dragged data in, and filling the fields in with the information returned by the calls to the Translation Kit. (For example, if appropriate translators are installed on the system, the Translation Kit might be able to translate a bitmap into any of JPEG, GIF, PNG, or TIFF images.)
- The specific meanings of these three fields are as follows:
- "be:types": each value in this field indicates a data format the sender is willing to provide its sent data in. This is a string value (a MIME string, actually), but you won't normally need to know what the string actually is, since you'll obtain it from the Translation Kit, or from a predefined constant. If "be:types" consists of a single element whose value is equal to that in the global variable B_FILE_MIME_TYPE, then the sender application is not willing to provide its data in a BMessage; the receiver must accept the data through a file, in one of the formats specified in the "be:filetypes" field of this message. If you want to indicate that your application is willing to send its data via either of a BMessage or a file, then add B_FILE_MIME_TYPE as the last element of "be:types", after all of the types which can be sent in a BMessage.
- "be:filetypes": similar "be:types", but a values in this field indicate formats in which the sender is willing to provide its data via a file. This can make a lot of sense; for example, if what the user is dragging around is a 30 megabyte video clip, you probably don't want to pass this in a BMessage. In most cases, "be:filetypes" will be identical to "be:types". If your application isn't willing to pass data via a file, then it doesn't matter what (if anything) you put into "be:filetypes". Important: See the section below in "Passing Data Via a File" for further notes on this, if you plan to make use of it.
- "be:type_descriptions": this is just a user-friendly description of the corresponding format in "be:filetypes". It may be displayed onscreen to the user when the user can choose between several different data formats during a file save operation. It is not used otherwise.
- The be:actions" Field
- In negotiated drag'n'drop, the sender and receiver negotiate not only the format of the sent data, but also the action performed on that data. Should the data be copied from the sender to the receiver, moved from the sender to the receiver, or something else? The first part of this "actions negotiation" takes place in the drag message via the "be:actions" field.
- "be:actions" contains a list of values (32-bit integers actually) which define the actions the sender is will to perform at the request of the receiver. No action will actually be carried out until and unless the receiver requests it. The possible action requests are given by the following constants:
- B_COPY_TARGET : the sender is willing to provide a copy of the dragged object.
- B_MOVE_TARGET : The sender is willing to move the target over to the receiver; if the receiver requests this, then after the sender sends a copy of the data, it will delete its own copy.
- B_LINK_TARGET : The sender is willing to provide a link to the target. [xxx what does this mean exactly? If the sender is the Tracker, I can understand it, but in Chris' document, B_LINK_TARGET is listed as a general action, not one that is Tracker-specific.]
- B_TRASH_TARGET : The sender is willing to delete its data without even sending it. This is useful if, for example, you want your user to be able to drag something from the application to the Tracker's wastebasket icon, and have the object removed from the application as a result.
- In addition to the above four "standard" actions, there are a few actions which can be carried out specifically when the Tracker is the sender application [xxx does the Tracker have to be the receiver as well? If so, should we even document these actions?]:
- B_COPY_SELECTION_TO : One or more elements (files, directories) are selected in a Tracker window; the Tracker is willing to copy these files to an entry_ref type destination, which will be supplied in a "refs" field in the negotiation message, should the receiver application choose this action.
- B_MOVE_SELECTION_TO : One or more elements (files, directories) are selected in a Tracker window; the Tracker is willing to move these files to an entry_ref type destination, which will be supplied in a "refs" field in the negotiation message, should the receiver application choose this action.
- [xxx Chris' document implies the Tracker can also make links due to a specific Tracker action, is there something like a B_LINK_SELECTION_TO?]
- The "be:clip_name" Field
- This is an easy one. If present (it doesn't have to be), it contains a string suggesting a name for the data which will be sent. This name may be used by the receiver; for example, if data is dragged onto the Tracker, the Tracker will try to use the value in "be:clip_name" as the basis for the name of the clipping file it creates from the data. However, the receiver is under no obligation to pay attention to "be:clip_name".
- "be:originator" and "be:originator_data" Fields
- Let's say you're a sender application, and you've asynchronously sent off a drag message. Then you receive a BMessage. Is it the reply to your original message? And if so, how do you access data about the original drag (such as where the mouse was clicked) you might need in order to complete the data message? Since the original drag message was sent asynchronously, your application went merrily on its way immediately after sending, and no longer remembers what the heck it dragged off before. What do you do? This is where "be:originator" and "be:originator_data" come in.
- "be:originator" should be filled in with something that identifies your application to itself; it doesn't really matter what. We'll see how this is used in a second...
- "be:originator_data" can be filled in with data about the drag that you'll need to use later on in the drag'n'drop negotiation. This could be something as simple as the mouse position, or it could be a much more complex piece of information about the context of the application at the time the drag was started. It's up to you, and of course, you don't have to use "be:orginator_data" at all.
- If you fill in "be:originator" and "be:originator_data" properly on all of your outgoing drag messages, then here is what your app can do when it receives a BMessage that may be a negotiation message responding to a previously sent (asynchronous) drag message:
- 1. Your app checks to ensure that the incoming message has the correct format for a negotiation message (we'll describe the format of negotiation messages in a bit). If it does, then go on...
- 2. Your app uses BMessage::IsReply() to check if the incoming message is a reply to a previous message.
- 3. If the incoming message is in fact a reply, your app uses BMessage::Previous() to obtain the original message; the message the incoming message was sent in reply to.
- 4. Now, your app can examine "be:originator" in the original message, to see if it recognizes that value as indicating a drag message sent out by itself. If it does, then the incoming BMessage is in fact a negotiation message in response to your original drag message; your app can extract necessary context data from "be:originator_data", and go on to construct and send the data message.
- The "be:data" Field
- This field was used in the original drag'n'drop protocol to carry the dragged data. It is not used in the negotiated drag'n'drop protocol.
- The "_drop_point_" Field
- This field contains a BPoint giving the screen coordinate of the mouse cursor, when the drag was ended (i.e. when the mouse button was released and the data dropped.) It's added automatically by the system--you don't create or add to it yourself.
- The "_drop_offset_" Field
- Whether you have your application display a bitmap or a rectangular outline during a drag, the dragged area occupies a rectangle. (Though it may not appear so to the user, since with a bitmap, sections of the bitmap can be transparent). "_drop_offset_" gives as a BPoint the distance from the top left point of the dragged area to the position of the mouse cursor within that dragged area. [xxx I think this is correct but just want to be sure.]It's added automatically by the system - you don't create or add to it yourself.
- Passing Data in a File
- Using a BMessage to pass a large amount of data from one application to another may not be desirable; at the extreme, you may not have enough memory to accommodate the entire BMessage. If you need to pass large amounts of data in a drag'n'drop operation, you may prefer to do so via a file.
- As far as passing data by a file goes, the sender application can indicate one of two things when sending the drag message to the receiver:
- The sender can offer to pass the data in a file, as well as via a BMessage. The receiver then has the option of accepting the data either through a BMessage, or through a file.
- The sender can state that it will only pass the data via a file. The receiver app, if it wants the data, had better agree.
- In both cases, the sender's ability to send data via a file is indicated by a value in the drag message's "be:types" field of B_FILE_MIME_TYPE. If B_FILE_MIME_TYPE is the first entry in the "be:types" field, than the sender will pass data only in a file, and anything else in "be:types" will be ignored. If there are entries in "be:types" before a value of B_FILE_MIME_TYPE, then those entries are types with which the sender is prepared to send data directly in the data message.
- If the sender has indicated, via the presence of a B_FILE_MIME_TYPE value in "be:types", that it is willing to pass data via a file, then the formats in which it can provide that file are listed in the "be:filetypes" field. If a value if B_FILE_MIME_TYPE is not present somewhere in the "be:types" field, then the sender is not able to pass data via a file, and any values in the "be:filetypes" field will be ignored.
Copyright 2005 by yellowTAB GmbH, Be Inc., Palm Source Inc. and their respective legal successors
All rights reserved.