The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.
=pod

=head1 NAME

IUP::Manual::08_DragAndDrop - Using Drag & Drop feature with IUP

=head1 IUP MANUAL

=over

=item * L<IUP::Manual::01_Introduction|IUP::Manual::01_Introduction>

=item * L<IUP::Manual::02_Elements|IUP::Manual::02_Elements>

=item * L<IUP::Manual::03_Attributes|IUP::Manual::03_Attributes>

=item * L<IUP::Manual::04_Callbacks|IUP::Manual::04_Callbacks>

=item * L<IUP::Manual::06_HandlingKeyboard|IUP::Manual::06_HandlingKeyboard>

=item * L<IUP::Manual::05_DialogLayout|IUP::Manual::05_DialogLayout>

=item * L<IUP::Manual::07_UsingImageLibrary|IUP::Manual::07_UsingImageLibrary>

=item * IUP::Manual::08_DragAndDrop E<nbsp>E<nbsp>E<nbsp>E<nbsp>E<nbsp> B<E<lt>E<lt>E<lt> this document>

=back

=head1 DRAG & DROP

Drag&Drop feature can used with L<IUP::Label>, L<IUP::Text>, L<IUP::List>, L<IUP::Tree>, L<IUP::Canvas> (+ all derived elements) and L<IUP::Dialog>.

The user starts a drag and drop transfer by pressing the mouse button
over the data (Windows and GTK: left button; Motif: middle button)
which is referred to as the drag source. The data can be dropped in any
location that has been registered as a drop target. The drop occurs
when the user releases the mouse button. This can be done inside a
control, from one control to another in the same dialog, in different
dialogs of the same application, or between different applications (the
other application does NOT need to be implemented with IUP).

In IUP, a drag and drop transfer can result in the data being moved or
copied. A B<copy> operation is enabled with the CTRL key pressed. A
B<move> operation is enabled with the SHIFT key pressed. A move
operation will be possible only if the attribute DRAGSOURCEMOVE is Yes.
When no key is pressed the default operation is B<copy> when
DRAGSOURCEMOVE=No and B<move> when DRAGSOURCEMOVE=Yes. The user can
cancel a drag at any time by pressing the ESCAPE key.

Steps to use the Drag & Drop support in an IUP application:

=head2 AT SOURCE:

=over

=item * Enable the element as source using the attribute DRAGSOURCE=YES;

=item * Define the data types supported by the element for the drag operation using the DRAGTYPES attribute;

=item * Register the required callbacks DRAGBEGIN_CB, DRAGDATASIZE_CB and DRAGDATA_CB for drag handling. DRAGEND_CB is the only optional drag callback, all other callbacks and attributes must be set.

=back

=head2 AT TARGET:

=over

=item * Enable the element as target using the attribute DROPTARGET=YES;

=item * Define the data types supported by the element for the drop using the DROPTYPES attribute;

=item * Register the required callback DROPDATA_CB for handling the data received. This callback and all the drop target attributes must be set too. DROPMOTION_CB is the only optional drop callback.

=back

=head2 ATTRIBUTES

=head3 Attributes at Drag Source

=over

=item B<DRAGSOURCE>

I<(non inheritable)>: Set up a control as a source for drag operations. Default: NO.

=item B<DRAGTYPES>

I<(non inheritable)>: A list of data types that are
supported by the source. Accepts a string with one or more names
separated by commas. See L<Notes|#Notes> bellow for a list of known
names. Must be set.

=item B<DRAGSOURCEMOVE>

I<(non inheritable)>: Enables the move action. Default: NO (only copy is enabled).

=back

=head3 Attributes at Drop Target

=over

=item B<DROPTARGET>

I<(non inheritable)>: Set up a control as a destination for drop operations. Default: NO.

=item B<DROPTYPES>

I<(non inheritable)>: A list of data types that are supported by the target.
Accepts a string with one or more names separated by commas. See L<|/Notes> bellow for a list of known names. Must beset.

=back

=head2 CALLBACKS

=head3 Callbacks at Drag Source (Must be set when DRAGSOURCE=Yes)

=over

=item  B<DRAGBEGIN_CB>

notifies source that drag started. It is called when the mouse starts a drag operation.

B<Callback handler prototype:>

 sub DRAGBEGIN_CB_handler {
   my ($self, $x, $y) = @_;
   #...
 }

B<$self:> identifier of the element that activated the event

B<$x, $y:> cursor position relative to the top-left corner of the element.

B<Returns:> If IUP_IGNORE is returned the drag is aborted.

=item B<DRAGDATASIZE_CB>

request for size of drag data from source. It is called when the data is dropped, before the B<DRAGDATA_CB> callback.

 sub DRAGDATASIZE_CB_handler {
   my ($self, $type) = @_;
   #...
 }

B<$self:> identifier of the element that activated the event

B<$type:> type of the data. It is one of the registered types in B<DRAGTYPES>.

B<Returns:> the size in bytes for the data. It will be used to allocate the buffer size for the data in transfer.

=item B<DRAGDATA_CB>

request for drag data from source. It is called when the data is dropped.

 sub DRAGDATA_CB_handler {
   my ($self, $type, $size) = @_;
   #...
   return IUP_DEFAULT, $data;
 }

B<$self:> identifier of the element that activated the event

B<$type:> type of the data. It is one of the registered types in B<DRAGTYPES>.

B<$size:> buffer size in bytes. The same value returned by B<DRAGDATASIZE_CB>

B<Returns:> 2 values - callback return value (e.g. IUP_DEFAULT) + C<$data> data to be dragged by receiving application (should have size C<$size>).

=item B<DRAGEND_CB>

notifies source that drag is done. The only drag
callback that is B<optional>. It is called after the data has been
dropped.

 sub DRAGEND_CB_handler {
   my ($self, $action) = @_;
   #...
 }

B<$self:> identifier of the element that activated the event

B<$action:> action performed by the operation (1 = move, 0 = copy, -1 = drag failed or aborted)

If action is 1 it is responsibility of the application to remove the data from source.

=back

=head3 Callback at Drop Target (Must be set when DROPTARGET=Yes)

=over

=item B<DROPDATA_CB>

source has sent target the requested data. It is called when the data is dropped. If both drag and drop would be in the same application it would be called after the B<DRAGDATA_CB> callback.

 sub DROPDATA_CB_handler {
   my ($self, $type, $data, $x, $y) = @_;
   #...
 }

B<$self:> identifier of the element that activated the event

B<$type:> type of the data. It is one of the registered types in B<DROPTYPES>.

B<$data:> content data received in the drop operation.

B<$x, $y:> cursor position relative to the top-left corner of the element.

=item B<DROPMOTION_CB>

notifies destination about drag pointer motion. The only drop callback that is B<optional>. It is called when the mouse moves over any valid drop site.

 sub DROPMOTION_CB_handler {
   my ($self, $x, $y, $status) = @_;
   #...
 }

B<$self:> identifier of the element that activated the event

B<$x, $y:> position in the canvas where the event has occurred, in pixels.

B<$status:> status of mouse buttons and certain keyboard keys at the moment the event was generated. The same macros used for L<BUTTON_CB|IUP::Manual::04_Callbacks/BUTTON_CB> can be used for this status.

=back

=head2 Notes

Drag and Drop support can be set independently. A control can have drop
without drag support and vice-versa.

Here are some common Drag&Drop types defined by existing applications:

=over

=item * "TEXT" used for regular text without formatting. Automatically translated to CF_TEXT in Windows.

=item * content MIME types, like "text/uri-list", "text/html", "image/png", "image/jpeg", "image/bmp" and "image/gif".

=item * "UTF8_STRING" in GTK and "UNICODETEXT" in Windows.

=item * "COMPOUND_TEXT" in GTK and "Rich Text Format" in Windows.

=item * "BITMAP" and "DIB" in Windows. Automatically translated to CF_BITMAP and CF_DIB.

=back

=cut