1------------------------------------------------------------------------------
2--                  GtkAda - Ada95 binding for Gtk+/Gnome                   --
3--                                                                          --
4--                     Copyright (C) 2000-2015, AdaCore                     --
5--                                                                          --
6-- This library is free software;  you can redistribute it and/or modify it --
7-- under terms of the  GNU General Public License  as published by the Free --
8-- Software  Foundation;  either version 3,  or (at your  option) any later --
9-- version. This library is distributed in the hope that it will be useful, --
10-- but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN- --
11-- TABILITY or FITNESS FOR A PARTICULAR PURPOSE.                            --
12--                                                                          --
13-- As a special exception under Section 7 of GPL version 3, you are granted --
14-- additional permissions described in the GCC Runtime Library Exception,   --
15-- version 3.1, as published by the Free Software Foundation.               --
16--                                                                          --
17-- You should have received a copy of the GNU General Public License and    --
18-- a copy of the GCC Runtime Library Exception along with this program;     --
19-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
20-- <http://www.gnu.org/licenses/>.                                          --
21--                                                                          --
22------------------------------------------------------------------------------
23
24--  <description>
25--  Like all modern GUI toolkits, GtkAda has a full support for drag-and-drop
26--  operations. This is a mechanism for interactively transferring data between
27--  two widgets, either in the same application or in two different
28--  applications. The user clicks on a widget (called a "drag source"), and,
29--  while keeping the mouse button pressed, moves it to another widget, where
30--  the mouse button is released (this other widget is called a "drop site").
31--  As a result, and if both widgets can handle the same type of data, some
32--  data is either copied or moved to this new widget.
33--
34--  This is a very intuitive way, in some cases, to enhance the usability of
35--  your application, although you should carefully consider whether this
36--  should be used or not.
37--
38--  GtkAda supports several drag-and-drop protocols, so as to be able to
39--  communicate with the maximum number of applications. These protocols are
40--  Xdnd and Motif.
41--
42--  Below is a summary of what is needed to add drag-and-drop capabilities to
43--  your application. We highly recommend that you look at, and understand,
44--  the example in testgtk (create_dnd.adb), before using these features in
45--  your own application.
46--
47--  See also the package Gtk.Selection, that contains some lower subprograms
48--  and data types that are used when implementing drag-and-drop.
49--
50--  - Defining a widget as a possible drag source
51--
52--  You need to call Source_Set, specifying which mouse buttons can activate
53--  the drag, which types of data will be given, and which kind of action
54--  will be performed.
55--  You then need to connect to the signal "drag_data_get", that will be
56--  emitted when the user has dropped the item and GtkAda needs to find the
57--  data. You must call Selection_Data_Set in the handler to set the actual
58--  data.
59--  You can also connect the widget to "drag_data_delete", which will be
60--  called whenever the data set for the selection is no longer required and
61--  should be deleted. The signal will be emitted only if the drop site
62--  requests it, or if the selected action for the drag-and-drop operation
63--  was Action_Move. It will not be called automatically for an Action_Copy.
64--  Note that the callback might be called several times, if for instance this
65--  was an Action_Move, and the drop site requires explicitly to delete the
66--  data in its call to Finish.
67--
68--  - Defining a widget as a possible drop site
69--
70--  You need to call Dest_Set, specifying which types of Data are accepted
71--  by the widget, which actions are recognized, and whether you accept drops
72--  from external applications.
73--  You also need to connect to "drag_data_received", that will be emitted
74--  when the user has dropped some data on the widget. The handler should
75--  call Finish, to warn the source widget that the drag and drop operation
76--  is finished, and whether it was successful or not.
77--  </description>
78--  <c_version>2.16.6</c_version>
79--  <group>Inter-Process communication</group>
80--  <testgtk>create_dnd.adb</testgtk>
81
82with Gdk.Dnd;           use Gdk.Dnd;
83with Gdk.Drag_Contexts; use Gdk.Drag_Contexts;
84with Gdk.Event;
85with Gdk.Pixbuf;
86with Gdk.Types;
87
88with Gtk.Widget;
89with Gtk.Target_List; use Gtk.Target_List;
90
91package Gtk.Dnd is
92
93   -------------------
94   -- Dest_Defaults --
95   -------------------
96
97   type Dest_Defaults is new Integer;
98   --  Specify the various types of action that will be taken on behalf of the
99   --  user for a drag destination site.
100
101   Dest_No_Default        : constant Dest_Defaults;
102   --  No default behavior is provided for the drop site, this is your own
103   --  responsabily. You need to handler the "drag_drop" signal yourself.
104
105   Dest_Default_Motion    : constant Dest_Defaults;
106   --  If set for a widget, GtkAda, during a drag over this widget will check
107   --  if the drag matches this widget's list of possible targets and
108   --  actions. gdk_drag_status is called as appropriate.
109
110   Dest_Default_Highlight : constant Dest_Defaults;
111   --  If set for a widget, GtkAda will draw a highlight on this widget as
112   --  long as a drag is over this widget and the wiget drag format and action
113   --  is acceptable.
114
115   Dest_Default_Drop      : constant Dest_Defaults;
116   --  If set for a widget, when a drop occurs, GtkAda+ will check if the drag
117   --  matches this widget's list of possible targets and actions. If so,
118   --  GtkAda will call Get_Data on behalf of the widget. Whether or not
119   --  the drop is succesful, GtkAda will call Drag_Finish. If the
120   --  action was a move, then if the drag was succesful, then True will be
121   --  passed for the delete parameter to Finish.
122
123   Dest_Default_All       : constant Dest_Defaults;
124   --  If set, specifies that all default actions should be taken.
125
126   ------------------------------------------
127   -- Setting up a widget as a destination --
128   ------------------------------------------
129
130   procedure Dest_Set
131     (Widget  : access Gtk.Widget.Gtk_Widget_Record'Class;
132      Flags   : Dest_Defaults := Dest_No_Default;
133      Targets : Target_Entry_Array := Any_Target_Entry;
134      Actions : Drag_Action := Action_Any);
135   --  Set a widget as a potential drop destination.
136   --
137   --  Flags specifies what action GtkAda should take on behalf of a widget for
138   --  drops onto that widget. The Targets and Actions fields are used only
139   --  if Dest_Default_Motion or Dest_Default_Drop are given.
140   --
141   --  Targets indicates the drop types that Widget accepts. If no item from
142   --  Targets matches the list of targets emitted by the source (as set in
143   --  Source_Set), then the drop will be considered illegal and refused.
144   --
145   --  Actions is a bitmask of possible actions for a drop onto Widget. At
146   --  least of the actions must be in common with what was set for the source
147   --  in Source_Set, or the drop is considered illegal.
148
149   --  if Flags = Dest_No_Default, no default behavior is provided, and
150   --  Targets and Actions are simply ignored.
151
152   procedure Dest_Set_Proxy
153     (Widget          : access Gtk.Widget.Gtk_Widget_Record'Class;
154      Proxy_Window    : Gdk.Gdk_Window;
155      Protocol        : Drag_Protocol;
156      Use_Coordinates : Boolean);
157   --  Set this widget as a proxy for drops to another window.
158   --  All drag events on Widget will be forwarded to Proxy_Window.
159   --  Protocol is the drag protocol that Proxy_Window accepts. You can use
160   --  Gdk.Drag.Get_Protocol to determine this.
161   --  If Use_Coordinates is True, send the same coordinates to the destination
162   --  because it is an embedded subwindow.
163
164   procedure Dest_Unset
165     (Widget : access Gtk.Widget.Gtk_Widget_Record'Class);
166   --  Clear information about a drop destination set with Dest_Set. The
167   --  widget will no longer receive notification of drags.
168
169   procedure Dest_Set_Target_List
170     (Widget      : access Gtk.Widget.Gtk_Widget_Record'Class;
171      Target_List : Gtk.Target_List.Gtk_Target_List);
172   function Dest_Get_Target_List
173     (Widget : access Gtk.Widget.Gtk_Widget_Record'Class)
174      return Gtk.Target_List.Gtk_Target_List;
175   --  Sets the target types that this widget can accept from drag-and-drop.
176   --  The widget must first be made into a drag destination with
177   --  Dest_Set.
178
179   procedure Dest_Add_Image_Targets
180     (Widget : access Gtk.Widget.Gtk_Widget_Record'Class);
181   procedure Dest_Add_Text_Targets
182     (Widget : access Gtk.Widget.Gtk_Widget_Record'Class);
183   procedure Dest_Add_Uri_Targets
184     (Widget : access Gtk.Widget.Gtk_Widget_Record'Class);
185   --  Add the image/text/URI targets supported by Gtk_Selection to the target
186   --  list of the drag destination. The targets are added with Info = 0. If
187   --  you need another value, use Gtk.Selection.Target_List_Add_*_Targets, and
188   --  Dest_Set_Target_List
189
190   function Dest_Find_Target
191     (Widget      : access Gtk.Widget.Gtk_Widget_Record'Class;
192      Context     : Gdk.Drag_Contexts.Drag_Context;
193      Target_List : Gtk.Target_List.Gtk_Target_List) return Gdk.Types.Gdk_Atom;
194   --  Looks for a match between the targets set for context and the
195   --  Target_List, returning the first matching target, otherwise returning
196   --  GDK_NONE. Target_List should usually be the return value from
197   --  Dest_Get_Target_List, but some widgets may have different valid targets
198   --  for different parts of the widget; in that case, they will have to
199   --  implement a drag_motion handler that passes the correct target list to
200   --  this function.
201
202   function Dest_Get_Track_Motion
203     (Widget : access Gtk.Widget.Gtk_Widget_Record'Class)
204      return Boolean;
205   procedure Dest_Set_Track_Motion
206     (Widget       : access Gtk.Widget.Gtk_Widget_Record'Class;
207      Track_Motion : Boolean);
208   --  Control whether the widget emits drag-motion and drag-leave
209   --  events regardless of the targets and the Dest_Default_Motion
210   --  flag.
211   --
212   --  This may be used when a widget wants to do generic
213   --  actions regardless of the targets that the source offers.
214
215   -------------------------------------
216   -- Setting up a widget as a source --
217   -------------------------------------
218
219   procedure Source_Set
220     (Widget            : access Gtk.Widget.Gtk_Widget_Record'Class;
221      Start_Button_Mask : Gdk.Types.Gdk_Modifier_Type;
222      Targets           : Target_Entry_Array;
223      Actions           : Drag_Action);
224   --  Set up a widget so that GtkAda will start a drag operation when the
225   --  user clicks and drags on the widget. The widget must have a window.
226   --
227   --  Targets is the list of targets that the drag can provide. The first
228   --  possible target accepted by the drop site will be used. For instance,
229   --  if Targets contains "text/plain" and "text/url", and the drop site only
230   --  accepts "text/url", this will be the one used. However, if the drop site
231   --  also accepts "text/plain", the latter will be prefered.
232   --
233   --  Widget needs to be able to convert the data to any of the types in
234   --  Target, as any of them might be requested by the drop site.
235   --
236   --  Actions is a list of possible actions for drags from Widget. At least
237   --  one of the actions must be in common with the drop site for the
238   --  drag-and-drop operation to succeed.
239
240   procedure Source_Unset (Widget : access Gtk.Widget.Gtk_Widget_Record'Class);
241   --  Undo the effects of Source_Set
242
243   procedure Source_Set_Target_List
244     (Widget      : access Gtk.Widget.Gtk_Widget_Record'Class;
245      Target_List : Gtk.Target_List.Gtk_Target_List);
246   function Source_Get_Target_List
247     (Widget : access Gtk.Widget.Gtk_Widget_Record'Class)
248      return Gtk.Target_List.Gtk_Target_List;
249   --  Changes the target types that this widget offers for drag-and-drop. The
250   --  widget must first be made into a drag source with Source_Set.
251
252   procedure Source_Add_Image_Targets
253     (Widget : access Gtk.Widget.Gtk_Widget_Record'Class);
254   procedure Source_Add_Text_Targets
255     (Widget : access Gtk.Widget.Gtk_Widget_Record'Class);
256   procedure Source_Add_Uri_Targets
257     (Widget : access Gtk.Widget.Gtk_Widget_Record'Class);
258   --  Add the writable image/text/URI targets supported by Gtk_Selection to
259   --  the target list of the drag source. The targets are added with Info = 0.
260   --  If you need another value, use Gtk.Selection.Target_List_Add_*_Targets,
261   --  and Source_Set_Target_List
262   --  Widget: a #GtkWidget that's is a drag source
263
264   procedure Source_Set_Icon_Pixbuf
265     (Widget : access Gtk.Widget.Gtk_Widget_Record'Class;
266      Pixbuf : Gdk.Pixbuf.Gdk_Pixbuf);
267   procedure Source_Set_Icon_Stock
268     (Widget   : access Gtk.Widget.Gtk_Widget_Record'Class;
269      Stock_Id : String);
270   procedure Source_Set_Icon_Name
271     (Widget    : access Gtk.Widget.Gtk_Widget_Record'Class;
272      Icon_Name : String);
273   --  Set the icon that will be used for drags from a particular widget.
274   --  GtkAda retains a reference count for the arguments, and will release
275   --  them when they are no longer needed.
276
277   ---------------------------------
278   -- The drag-and-drop operation --
279   ---------------------------------
280
281   procedure Finish
282     (Context : Drag_Context;
283      Success : Boolean;
284      Del     : Boolean;
285      Time    : Guint32 := 0);
286   --  Inform the drag source that the drop is finished, and that the data of
287   --  the drag will no longer be required.
288   --  Success should indicate whether the drop was successful.
289   --  Del should be set to True if the source should delete the original
290   --  data (this should be True for a move).
291
292   procedure Get_Data
293     (Widget  : access Gtk.Widget.Gtk_Widget_Record'Class;
294      Context : Drag_Context;
295      Target  : Gdk.Types.Gdk_Atom;
296      Time    : Guint32 := 0);
297   --  Get the data associated with a drag. When the data is received or the
298   --  retrieval fails, GtkAda will emit a "drag_data_received"
299   --  signal. Failure of the retrieval is indicated by the length field of
300   --  the selection_data signal parameter being negative. However, when
301   --  Get_Data is called implicitely because the Drag_Default_Drop was set,
302   --  then the widget will not receive notification of failed drops.
303   --
304   --  Target is the target (form of the data) to retrieve.
305   --  Time is a timestamp to retrive the data, and will be given to
306   --  "drag_data_motion" or "drag_data_drop" signals.
307
308   function Get_Source_Widget
309     (Context : Drag_Context) return Gtk.Widget.Gtk_Widget;
310   --  Determine the source widget for a drag.
311   --  If the drag is occuring within a single application, this function
312   --  returns the source widget. Otherwise, it returns null.
313
314   procedure Highlight (Widget : access Gtk.Widget.Gtk_Widget_Record'Class);
315   --  Draw a highlight around a widget.
316
317   procedure Unhighlight (Widget : access Gtk.Widget.Gtk_Widget_Record'Class);
318   --  Remove a highlight set by Highlight.
319
320   function Drag_Begin
321     (Widget  : access Gtk.Widget.Gtk_Widget_Record'Class;
322      Targets : Gtk_Target_List;
323      Actions : Drag_Action;
324      Button  : Gint;
325      Event   : Gdk.Event.Gdk_Event) return Drag_Context;
326   --  Initiate a drag on the source side. The function only needs to be used
327   --  when the application is starting drags itself, and is not needed when
328   --  Source_Set is used.
329   --  Targets is the list of targets (data formats) in which the source can
330   --  provide the data.
331   --  Actions is a bitmask of the allowed drag actions for this drag.
332   --  Button is the button the user clicked to start the drag.
333   --  Event is the event that triggered the start of the drag.
334
335   function Check_Threshold
336     (Widget    : access Gtk.Widget.Gtk_Widget_Record'Class;
337      Start_X   : Gint;
338      Start_Y   : Gint;
339      Current_X : Gint;
340      Current_Y : Gint) return Boolean;
341   --  Checks to see if a mouse drag starting at (Start_X, Start_Y) and ending
342   --  at (Current_X, Current_Y) has passed the GTK drag threshhold, and thus
343   --  should trigger the beginning of a drag-and-drop operation.
344   --  Return True if the drag threshold has been passed.
345
346   -----------
347   -- Icons --
348   -----------
349
350   procedure Set_Icon_Widget
351     (Context : Drag_Context;
352      Widget  : access Gtk.Widget.Gtk_Widget_Record'Class;
353      Hot_X   : Gint;
354      Hot_Y   : Gint);
355   --  Change the icon for a drag.
356   --  GtkAda will not destroy the icon, so if you don't want it to persist,
357   --  you should connect to the "drag_end" signal and destroy it yourself.
358   --  Context is the reference to the current drag operation.
359   --  Widget is the toplevel window to use as an icon. (Hot_X, Hot_Y) is the
360   --  coordinates of the hot point (that will be just under the mouse) within
361   --  Widget.
362
363   procedure Set_Icon_Default (Context : Drag_Context);
364   --  Set the icon for a particular drag to the default icon.
365   --  This must be called with a context for the source side of a drag.
366
367   procedure Set_Icon_Pixbuf
368     (Context : Drag_Context;
369      Pixbuf  : Gdk.Pixbuf.Gdk_Pixbuf;
370      Hot_X   : Gint;
371      Hot_Y   : Gint);
372   --  Sets Pixbuf as the icon for a given drag.
373   --  Context: the context for a drag. (This must be called
374   --             with a  context for the source side of a drag)
375   --  Pixbuf: the Gdk_Pixbuf to use as the drag icon.
376   --  Hot_x: the X offset within the pixbuf of the hotspot.
377   --  Hot_y: the Y offset within the pixbuf of the hotspot.
378
379   procedure Set_Icon_Stock
380     (Context  : Drag_Context;
381      Stock_Id : String;
382      Hot_X    : Gint;
383      Hot_Y    : Gint);
384   --  Sets the icon for a given drag from a stock ID
385   --  Context: the context for a drag. (This must be called
386   --             with a  context for the source side of a drag)
387   --  Stock: the ID of the stock icon to use for the drag.
388   --  Hot_x: the X offset within the icon of the hotspot.
389   --  Hot_y: the Y offset within the icon of the hotspot.
390
391   procedure Set_Icon_Name
392     (Context   : Drag_Context;
393      Icon_Name : String;
394      Hot_X     : Gint;
395      Hot_Y     : Gint);
396   --  Sets the icon for a given drag from a named themed icon. See
397   --  the docs for Gtk_Icon_Theme for more details. Note that the
398   --  size of the icon depends on the icon theme (the icon is
399   --  loaded at the symbolic size GTK_ICON_SIZE_DND), thus
400   --  Hot_X and Hot_Y have to be used with care.
401
402   -------------
403   -- Signals --
404   -------------
405
406   --  <signals>
407   --  The following new signals are defined for the class
408   --  Gtk.Widget.Gtk_Widget to support drag-and-drop.
409   --  Please note that no default marshaller is provided in GtkAda for these
410   --  handlers, and that you will have to use the general form of callbacks
411   --  instead, getting the value of the parameters directly from the
412   --  Gtk_Args structure.
413   --
414   --  - "drag_begin"   (source side)
415   --    procedure Handler (Widget  : access Gtk_Widget_Record'Class;
416   --                       Context : Drag_Context);
417   --
418   --    A new drag-and-drop operation has just been started from Widget. This
419   --    callback can be used for instance to modify the visual aspect of the
420   --    widget, so as to give a visual clue as to what widget is the source.
421   --
422   --  - "drag_end"     (source side)
423   --    procedure Handler (Widget  : access Gtk_Widget_Record'Class;
424   --                       Context : Drag_Context);
425   --
426   --    The drag-and-drop operation that was started from the widget has been
427   --    completed, and the standard set of the widget can be restored.
428   --
429   --  - "drag_data_get"  (source side)
430   --    procedure Handler (Widget  : access Gtk_Widget_Record'Class;
431   --                       Context : Drag_Context;
432   --                       Data    : Selection_Data;
433   --                       Info    : Guint;
434   --                       Time    : Guint);
435   --
436   --    This should be connected to every drag source.
437   --    This is used to request the actual data to be transfered to the drop
438   --    site once the drop has been done.
439   --    Info is the type of the expected Data, and is in fact the third
440   --    field of the Target_Entry record, whose value you have define
441   --    yourself.
442   --    Data should be modified to include a pointer or a copy of the data,
443   --    through Selection_Data_Set.
444   --
445   --  - "drag_data_delete"  (source side)
446   --    procedure Handler (Widget  : access Gtk_Widget_Record'Class;
447   --                       Context : Drag_Context);
448   --
449   --    This handler is called whenever the drop site of a drag-and-drop
450   --    operation has decided that the data should be deleted, or
451   --    automaticallyif the selected action was Action_Move.
452   --    Widget is the drag source.
453   --
454   --  - "drag_leave"  (target side)
455   --    procedure Handler (Widget  : access Gtk_Widget_Record'Class;
456   --                       Context : Drag_Context;
457   --                       Time    : Guint);
458
459   --    Signal emitted whenever a drag-and-drop operation is being performed,
460   --    and the mouse has just left the area covered by a widget on the
461   --    screen. This can be used to restore the default visual aspect of the
462   --    widget. This is also emitted when the drop has been performed on the
463   --    widget.
464   --
465   --  - "drag_motion"  (target side)
466   --    function Handler (Widget  : access Gtk_Widget_Record'Class;
467   --                      Context : Drag_Context;
468   --                      X       : Gint;
469   --                      Y       : Gint;
470   --                      Time    : Guint)
471   --                     return Boolean;
472   --
473   --    This is called every time the user is doing a dnd operation, and
474   --    the mouse is currently over Widget (but not released yet).
475   --    This can be used to change the visual aspect of Widget to provide
476   --    visual clues to the user. The "opposite" signal is drag_leave.
477   --
478   --    The return value is ignored if Dest_Default_Motion was set when
479   --    Source_Set was called. This handler should return True if Widget
480   --    acknowledges that it is a possible drop site for the particular
481   --    targets provided by the drag source.
482   --
483   --  - "drag_drop"  (target side)
484   --    function Handler (Widget  : access Gtk_Widget_Record'Class;
485   --                      Context : Drag_Context;
486   --                      X       : Gint;
487   --                      Y       : Gint;
488   --                      Time    : Guint)
489   --                     return Boolean;
490   --
491   --    This is called whenever a drop is about to be performed on the widget.
492   --    Note that this is called even if no common target type has been found
493   --    between the drag source and the drop site. Thus, you will need to
494   --    analyze the result of Get_Targets (Context) to find the possible
495   --    targets.
496   --    The data is sent separately through the "drag_data_received" signal,
497   --    and might not even be available when "drag_drop" is emitted.
498   --    This signal is mostly used if you have chosen not to use any of the
499   --    default behavior when calling Dest_Set. Otherwise, everything is
500   --    already handled directly by GtkAda.
501   --
502   --    This handler should return True if Widget acknowledges that it is a
503   --    possible drop site for the particular targets provided by the drag
504   --    source.
505   --
506   --  - "drag_data_received"  (target_side)
507   --    procedure Handler (Widget  : access Gtk_Widget_Record'Class;
508   --                       Context : Drag_Context;
509   --                       X       : Gint;
510   --                       Y       : Gint;
511   --                       Data    : Selection_Data;
512   --                       Info    : Guint;
513   --                       Time    : Guint);
514   --
515   --    This signal should be connected to every drop site.
516   --    The handler is called every time some new data has been dropped onto
517   --    Widget. (X, Y) are the mouse coordinates, relative to the widget's
518   --    window, where the data was dropped. Info is the type of the data,
519   --    has set in the third field of the Target_Entry record, and Data
520   --    contains a pointer to the actual data.
521   --
522   --  </signals>
523
524private
525   Dest_No_Default        : constant Dest_Defaults := 0;
526   Dest_Default_Motion    : constant Dest_Defaults := 2 ** 0;
527   Dest_Default_Highlight : constant Dest_Defaults := 2 ** 1;
528   Dest_Default_Drop      : constant Dest_Defaults := 2 ** 2;
529   Dest_Default_All       : constant Dest_Defaults := 7;
530end Gtk.Dnd;
531