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