----------------------------------------------------------------------- -- GtkAda - Ada95 binding for Gtk+/Gnome -- -- -- -- Copyright (C) 2000-2010 AdaCore -- -- -- -- This library is free software; you can redistribute it and/or -- -- modify it under the terms of the GNU General Public -- -- License as published by the Free Software Foundation; either -- -- version 2 of the License, or (at your option) any later version. -- -- -- -- This library is distributed in the hope that it will be useful, -- -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- -- General Public License for more details. -- -- -- -- You should have received a copy of the GNU General Public -- -- License along with this library; if not, write to the -- -- Free Software Foundation, Inc., 59 Temple Place - Suite 330, -- -- Boston, MA 02111-1307, USA. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ----------------------------------------------------------------------- -- -- Like all modern GUI toolkits, GtkAda has a full support for drag-and-drop -- operations. This is a mechanism for interactively transferring data between -- two widgets, either in the same application or in two different -- applications. The user clicks on a widget (called a "drag source"), and, -- while keeping the mouse button pressed, moves it to another widget, where -- the mouse button is released (this other widget is called a "drop site"). -- As a result, and if both widgets can handle the same type of data, some -- data is either copied or moved to this new widget. -- -- This is a very intuitive way, in some cases, to enhance the usability of -- your application, although you should carefully consider whether this -- should be used or not. -- -- GtkAda supports several drag-and-drop protocols, so as to be able to -- communicate with the maximum number of applications. These protocols are -- Xdnd and Motif. -- -- Below is a summary of what is needed to add drag-and-drop capabilities to -- your application. We highly recommend that you look at, and understand, -- the example in testgtk (create_dnd.adb), before using these features in -- your own application. -- -- See also the package Gtk.Selection, that contains some lower subprograms -- and data types that are used when implementing drag-and-drop. -- -- - Defining a widget as a possible drag source -- -- You need to call Source_Set, specifying which mouse buttons can activate -- the drag, which types of data will be given, and which kind of action -- will be performed. -- You then need to connect to the signal "drag_data_get", that will be -- emitted when the user has dropped the item and GtkAda needs to find the -- data. You must call Selection_Data_Set in the handler to set the actual -- data. -- You can also connect the widget to "drag_data_delete", which will be -- called whenever the data set for the selection is no longer required and -- should be deleted. The signal will be emitted only if the drop site -- requests it, or if the selected action for the drag-and-drop operation -- was Action_Move. It will not be called automatically for an Action_Copy. -- Note that the callback might be called several times, if for instance this -- was an Action_Move, and the drop site requires explicitly to delete the -- data in its call to Finish. -- -- - Defining a widget as a possible drop site -- -- You need to call Dest_Set, specifying which types of Data are accepted -- by the widget, which actions are recognized, and whether you accept drops -- from external applications. -- You also need to connect to "drag_data_received", that will be emitted -- when the user has dropped some data on the widget. The handler should -- call Finish, to warn the source widget that the drag and drop operation -- is finished, and whether it was successful or not. -- -- 2.16.6 -- Inter-Process communication -- create_dnd.adb with Gdk.Bitmap; with Gdk.Color; with Gdk.Dnd; use Gdk.Dnd; with Gdk.Event; with Gdk.Pixmap; with Gdk.Pixbuf; with Gdk.Types; with Gdk.Window; with Gtk.Widget; with Gtk.Selection; use Gtk.Selection; package Gtk.Dnd is ------------------- -- Dest_Defaults -- ------------------- type Dest_Defaults is new Integer; -- Specify the various types of action that will be taken on behalf of the -- user for a drag destination site. Dest_No_Default : constant Dest_Defaults; -- No default behavior is provided for the drop site, this is your own -- responsabily. You need to handler the "drag_drop" signal yourself. Dest_Default_Motion : constant Dest_Defaults; -- If set for a widget, GtkAda, during a drag over this widget will check -- if the drag matches this widget's list of possible targets and -- actions. gdk_drag_status is called as appropriate. Dest_Default_Highlight : constant Dest_Defaults; -- If set for a widget, GtkAda will draw a highlight on this widget as -- long as a drag is over this widget and the wiget drag format and action -- is acceptable. Dest_Default_Drop : constant Dest_Defaults; -- If set for a widget, when a drop occurs, GtkAda+ will check if the drag -- matches this widget's list of possible targets and actions. If so, -- GtkAda will call Get_Data on behalf of the widget. Whether or not -- the drop is succesful, GtkAda will call Drag_Finish. If the -- action was a move, then if the drag was succesful, then True will be -- passed for the delete parameter to Finish. Dest_Default_All : constant Dest_Defaults; -- If set, specifies that all default actions should be taken. ------------------------------------------ -- Setting up a widget as a destination -- ------------------------------------------ procedure Dest_Set (Widget : access Gtk.Widget.Gtk_Widget_Record'Class; Flags : Dest_Defaults := Dest_No_Default; Targets : Target_Entry_Array := Any_Target_Entry; Actions : Drag_Action := Action_Any); -- Set a widget as a potential drop destination. -- -- Flags specifies what action GtkAda should take on behalf of a widget for -- drops onto that widget. The Targets and Actions fields are used only -- if Dest_Default_Motion or Dest_Default_Drop are given. -- -- Targets indicates the drop types that Widget accepts. If no item from -- Targets matches the list of targets emitted by the source (as set in -- Source_Set), then the drop will be considered illegal and refused. -- -- Actions is a bitmask of possible actions for a drop onto Widget. At -- least of the actions must be in common with what was set for the source -- in Source_Set, or the drop is considered illegal. -- if Flags = Dest_No_Default, no default behavior is provided, and -- Targets and Actions are simply ignored. procedure Dest_Set_Proxy (Widget : access Gtk.Widget.Gtk_Widget_Record'Class; Proxy_Window : Gdk.Window.Gdk_Window; Protocol : Drag_Protocol; Use_Coordinates : Boolean); -- Set this widget as a proxy for drops to another window. -- All drag events on Widget will be forwarded to Proxy_Window. -- Protocol is the drag protocol that Proxy_Window accepts. You can use -- Gdk.Drag.Get_Protocol to determine this. -- If Use_Coordinates is True, send the same coordinates to the destination -- because it is an embedded subwindow. procedure Dest_Unset (Widget : access Gtk.Widget.Gtk_Widget_Record'Class); -- Clear information about a drop destination set with Dest_Set. The -- widget will no longer receive notification of drags. procedure Dest_Set_Target_List (Widget : access Gtk.Widget.Gtk_Widget_Record'Class; Target_List : Gtk.Selection.Target_List); function Dest_Get_Target_List (Widget : access Gtk.Widget.Gtk_Widget_Record'Class) return Target_List; -- Sets the target types that this widget can accept from drag-and-drop. -- The widget must first be made into a drag destination with -- Dest_Set. procedure Dest_Add_Image_Targets (Widget : access Gtk.Widget.Gtk_Widget_Record'Class); procedure Dest_Add_Text_Targets (Widget : access Gtk.Widget.Gtk_Widget_Record'Class); procedure Dest_Add_Uri_Targets (Widget : access Gtk.Widget.Gtk_Widget_Record'Class); -- Add the image/text/URI targets supported by Gtk_Selection to the target -- list of the drag destination. The targets are added with Info = 0. If -- you need another value, use Gtk.Selection.Target_List_Add_*_Targets, and -- Dest_Set_Target_List function Dest_Find_Target (Widget : access Gtk.Widget.Gtk_Widget_Record'Class; Context : Gdk.Dnd.Drag_Context; Target_List : Gtk.Selection.Target_List) return Gdk.Types.Gdk_Atom; -- Looks for a match between the targets set for context and the -- Target_List, returning the first matching target, otherwise returning -- GDK_NONE. Target_List should usually be the return value from -- Dest_Get_Target_List, but some widgets may have different valid targets -- for different parts of the widget; in that case, they will have to -- implement a drag_motion handler that passes the correct target list to -- this function. function Dest_Get_Track_Motion (Widget : access Gtk.Widget.Gtk_Widget_Record'Class) return Boolean; procedure Dest_Set_Track_Motion (Widget : access Gtk.Widget.Gtk_Widget_Record'Class; Track_Motion : Boolean); -- Control whether the widget emits drag-motion and drag-leave -- events regardless of the targets and the Dest_Default_Motion -- flag. -- -- This may be used when a widget wants to do generic -- actions regardless of the targets that the source offers. ------------------------------------- -- Setting up a widget as a source -- ------------------------------------- procedure Source_Set (Widget : access Gtk.Widget.Gtk_Widget_Record'Class; Start_Button_Mask : Gdk.Types.Gdk_Modifier_Type; Targets : Target_Entry_Array; Actions : Drag_Action); -- Set up a widget so that GtkAda will start a drag operation when the -- user clicks and drags on the widget. The widget must have a window. -- -- Targets is the list of targets that the drag can provide. The first -- possible target accepted by the drop site will be used. For instance, -- if Targets contains "text/plain" and "text/url", and the drop site only -- accepts "text/url", this will be the one used. However, if the drop site -- also accepts "text/plain", the latter will be prefered. -- -- Widget needs to be able to convert the data to any of the types in -- Target, as any of them might be requested by the drop site. -- -- Actions is a list of possible actions for drags from Widget. At least -- one of the actions must be in common with the drop site for the -- drag-and-drop operation to succeed. procedure Source_Unset (Widget : access Gtk.Widget.Gtk_Widget_Record'Class); -- Undo the effects of Source_Set procedure Source_Set_Target_List (Widget : access Gtk.Widget.Gtk_Widget_Record'Class; Target_List : Gtk.Selection.Target_List); function Source_Get_Target_List (Widget : access Gtk.Widget.Gtk_Widget_Record'Class) return Target_List; -- Changes the target types that this widget offers for drag-and-drop. The -- widget must first be made into a drag source with Source_Set. procedure Source_Add_Image_Targets (Widget : access Gtk.Widget.Gtk_Widget_Record'Class); procedure Source_Add_Text_Targets (Widget : access Gtk.Widget.Gtk_Widget_Record'Class); procedure Source_Add_Uri_Targets (Widget : access Gtk.Widget.Gtk_Widget_Record'Class); -- Add the writable image/text/URI targets supported by Gtk_Selection to -- the target list of the drag source. The targets are added with Info = 0. -- If you need another value, use Gtk.Selection.Target_List_Add_*_Targets, -- and Source_Set_Target_List -- Widget: a #GtkWidget that's is a drag source procedure Source_Set_Icon (Widget : access Gtk.Widget.Gtk_Widget_Record'Class; Colormap : Gdk.Color.Gdk_Colormap; Pixmap : Gdk.Pixmap.Gdk_Pixmap; Mask : Gdk.Bitmap.Gdk_Bitmap); procedure Source_Set_Icon_Pixbuf (Widget : access Gtk.Widget.Gtk_Widget_Record'Class; Pixbuf : Gdk.Pixbuf.Gdk_Pixbuf); procedure Source_Set_Icon_Stock (Widget : access Gtk.Widget.Gtk_Widget_Record'Class; Stock_Id : String); procedure Source_Set_Icon_Name (Widget : access Gtk.Widget.Gtk_Widget_Record'Class; Icon_Name : String); -- Set the icon that will be used for drags from a particular widget. -- GtkAda retains a reference count for the arguments, and will release -- them when they are no longer needed. --------------------------------- -- The drag-and-drop operation -- --------------------------------- procedure Finish (Context : Drag_Context; Success : Boolean; Del : Boolean; Time : Guint32 := 0); -- Inform the drag source that the drop is finished, and that the data of -- the drag will no longer be required. -- Success should indicate whether the drop was successful. -- Del should be set to True if the source should delete the original -- data (this should be True for a move). procedure Get_Data (Widget : access Gtk.Widget.Gtk_Widget_Record'Class; Context : Drag_Context; Target : Gdk.Types.Gdk_Atom; Time : Guint32 := 0); -- Get the data associated with a drag. When the data is received or the -- retrieval fails, GtkAda will emit a "drag_data_received" -- signal. Failure of the retrieval is indicated by the length field of -- the selection_data signal parameter being negative. However, when -- Get_Data is called implicitely because the Drag_Default_Drop was set, -- then the widget will not receive notification of failed drops. -- -- Target is the target (form of the data) to retrieve. -- Time is a timestamp to retrive the data, and will be given to -- "drag_data_motion" or "drag_data_drop" signals. function Get_Source_Widget (Context : Drag_Context) return Gtk.Widget.Gtk_Widget; -- Determine the source widget for a drag. -- If the drag is occuring within a single application, this function -- returns the source widget. Otherwise, it returns null. procedure Highlight (Widget : access Gtk.Widget.Gtk_Widget_Record'Class); -- Draw a highlight around a widget. procedure Unhighlight (Widget : access Gtk.Widget.Gtk_Widget_Record'Class); -- Remove a highlight set by Highlight. function Drag_Begin (Widget : access Gtk.Widget.Gtk_Widget_Record'Class; Targets : Target_List; Actions : Drag_Action; Button : Gint; Event : Gdk.Event.Gdk_Event) return Drag_Context; -- Initiate a drag on the source side. The function only needs to be used -- when the application is starting drags itself, and is not needed when -- Source_Set is used. -- Targets is the list of targets (data formats) in which the source can -- provide the data. -- Actions is a bitmask of the allowed drag actions for this drag. -- Button is the button the user clicked to start the drag. -- Event is the event that triggered the start of the drag. function Check_Threshold (Widget : access Gtk.Widget.Gtk_Widget_Record'Class; Start_X : Gint; Start_Y : Gint; Current_X : Gint; Current_Y : Gint) return Boolean; -- Checks to see if a mouse drag starting at (Start_X, Start_Y) and ending -- at (Current_X, Current_Y) has passed the GTK drag threshhold, and thus -- should trigger the beginning of a drag-and-drop operation. -- Return True if the drag threshold has been passed. ----------- -- Icons -- ----------- procedure Set_Icon_Widget (Context : Drag_Context; Widget : access Gtk.Widget.Gtk_Widget_Record'Class; Hot_X : Gint; Hot_Y : Gint); -- Change the icon for a drag. -- GtkAda will not destroy the icon, so if you don't want it to persist, -- you should connect to the "drag_end" signal and destroy it yourself. -- Context is the reference to the current drag operation. -- Widget is the toplevel window to use as an icon. (Hot_X, Hot_Y) is the -- coordinates of the hot point (that will be just under the mouse) within -- Widget. procedure Set_Icon_Pixmap (Context : Drag_Context; Colormap : Gdk.Color.Gdk_Colormap; Pixmap : Gdk.Pixmap.Gdk_Pixmap; Mask : Gdk.Bitmap.Gdk_Bitmap; Hot_X : Gint; Hot_Y : Gint); -- Sets a given pixmap as the icon for a given drag. GtkAda retains a -- reference count for the arguments, and will release them when they are -- no longer needed. -- (Hot_X, Hot_Y) is the coordinates of the hotspot within Pixmap. procedure Set_Icon_Default (Context : Drag_Context); -- Set the icon for a particular drag to the default icon. -- This must be called with a context for the source side of a drag. procedure Set_Icon_Pixbuf (Context : Drag_Context; Pixbuf : Gdk.Pixbuf.Gdk_Pixbuf; Hot_X : Gint; Hot_Y : Gint); -- Sets Pixbuf as the icon for a given drag. -- Context: the context for a drag. (This must be called -- with a context for the source side of a drag) -- Pixbuf: the Gdk_Pixbuf to use as the drag icon. -- Hot_x: the X offset within the pixbuf of the hotspot. -- Hot_y: the Y offset within the pixbuf of the hotspot. procedure Set_Icon_Stock (Context : Drag_Context; Stock_Id : String; Hot_X : Gint; Hot_Y : Gint); -- Sets the icon for a given drag from a stock ID -- Context: the context for a drag. (This must be called -- with a context for the source side of a drag) -- Stock: the ID of the stock icon to use for the drag. -- Hot_x: the X offset within the icon of the hotspot. -- Hot_y: the Y offset within the icon of the hotspot. procedure Set_Icon_Name (Context : Drag_Context; Icon_Name : String; Hot_X : Gint; Hot_Y : Gint); -- Sets the icon for a given drag from a named themed icon. See -- the docs for Gtk_Icon_Theme for more details. Note that the -- size of the icon depends on the icon theme (the icon is -- loaded at the symbolic size GTK_ICON_SIZE_DND), thus -- Hot_X and Hot_Y have to be used with care. ----------------- -- Obsolescent -- ----------------- -- All subprograms below are now obsolescent in gtk+. They might be removed -- from future versions of gtk+ (and therefore GtkAda). -- To find out whether your code uses any of these, we recommend compiling -- with the -gnatwj switch -- procedure Set_Default_Icon (Colormap : Gdk.Color.Gdk_Colormap; Pixmap : Gdk.Pixmap.Gdk_Pixmap; Mask : Gdk.Bitmap.Gdk_Bitmap; Hot_X : Gint; Hot_Y : Gint); pragma Obsolescent; -- Set_Default_Icon -- Change the default drag icon. GtkAda retains a reference count for the -- arguments, and will release them when they are no longer needed. -- This procedure is deprecated. -- ------------- -- Signals -- ------------- -- -- The following new signals are defined for the class -- Gtk.Widget.Gtk_Widget to support drag-and-drop. -- Please note that no default marshaller is provided in GtkAda for these -- handlers, and that you will have to use the general form of callbacks -- instead, getting the value of the parameters directly from the -- Gtk_Args structure. -- -- - "drag_begin" (source side) -- procedure Handler (Widget : access Gtk_Widget_Record'Class; -- Context : Drag_Context); -- -- A new drag-and-drop operation has just been started from Widget. This -- callback can be used for instance to modify the visual aspect of the -- widget, so as to give a visual clue as to what widget is the source. -- -- - "drag_end" (source side) -- procedure Handler (Widget : access Gtk_Widget_Record'Class; -- Context : Drag_Context); -- -- The drag-and-drop operation that was started from the widget has been -- completed, and the standard set of the widget can be restored. -- -- - "drag_data_get" (source side) -- procedure Handler (Widget : access Gtk_Widget_Record'Class; -- Context : Drag_Context; -- Data : Selection_Data; -- Info : Guint; -- Time : Guint); -- -- This should be connected to every drag source. -- This is used to request the actual data to be transfered to the drop -- site once the drop has been done. -- Info is the type of the expected Data, and is in fact the third -- field of the Target_Entry record, whose value you have define -- yourself. -- Data should be modified to include a pointer or a copy of the data, -- through Selection_Data_Set. -- -- - "drag_data_delete" (source side) -- procedure Handler (Widget : access Gtk_Widget_Record'Class; -- Context : Drag_Context); -- -- This handler is called whenever the drop site of a drag-and-drop -- operation has decided that the data should be deleted, or -- automaticallyif the selected action was Action_Move. -- Widget is the drag source. -- -- - "drag_leave" (target side) -- procedure Handler (Widget : access Gtk_Widget_Record'Class; -- Context : Drag_Context; -- Time : Guint); -- Signal emitted whenever a drag-and-drop operation is being performed, -- and the mouse has just left the area covered by a widget on the -- screen. This can be used to restore the default visual aspect of the -- widget. This is also emitted when the drop has been performed on the -- widget. -- -- - "drag_motion" (target side) -- function Handler (Widget : access Gtk_Widget_Record'Class; -- Context : Drag_Context; -- X : Gint; -- Y : Gint; -- Time : Guint) -- return Boolean; -- -- This is called every time the user is doing a dnd operation, and -- the mouse is currently over Widget (but not released yet). -- This can be used to change the visual aspect of Widget to provide -- visual clues to the user. The "opposite" signal is drag_leave. -- -- The return value is ignored if Dest_Default_Motion was set when -- Source_Set was called. This handler should return True if Widget -- acknowledges that it is a possible drop site for the particular -- targets provided by the drag source. -- -- - "drag_drop" (target side) -- function Handler (Widget : access Gtk_Widget_Record'Class; -- Context : Drag_Context; -- X : Gint; -- Y : Gint; -- Time : Guint) -- return Boolean; -- -- This is called whenever a drop is about to be performed on the widget. -- Note that this is called even if no common target type has been found -- between the drag source and the drop site. Thus, you will need to -- analyze the result of Get_Targets (Context) to find the possible -- targets. -- The data is sent separately through the "drag_data_received" signal, -- and might not even be available when "drag_drop" is emitted. -- This signal is mostly used if you have chosen not to use any of the -- default behavior when calling Dest_Set. Otherwise, everything is -- already handled directly by GtkAda. -- -- This handler should return True if Widget acknowledges that it is a -- possible drop site for the particular targets provided by the drag -- source. -- -- - "drag_data_received" (target_side) -- procedure Handler (Widget : access Gtk_Widget_Record'Class; -- Context : Drag_Context; -- X : Gint; -- Y : Gint; -- Data : Selection_Data; -- Info : Guint; -- Time : Guint); -- -- This signal should be connected to every drop site. -- The handler is called every time some new data has been dropped onto -- Widget. (X, Y) are the mouse coordinates, relative to the widget's -- window, where the data was dropped. Info is the type of the data, -- has set in the third field of the Target_Entry record, and Data -- contains a pointer to the actual data. -- -- private Dest_No_Default : constant Dest_Defaults := 0; Dest_Default_Motion : constant Dest_Defaults := 2 ** 0; Dest_Default_Highlight : constant Dest_Defaults := 2 ** 1; Dest_Default_Drop : constant Dest_Defaults := 2 ** 2; Dest_Default_All : constant Dest_Defaults := 7; pragma Import (C, Set_Icon_Pixmap, "gtk_drag_set_icon_pixmap"); pragma Import (C, Set_Icon_Default, "gtk_drag_set_icon_default"); pragma Import (C, Set_Default_Icon, "gtk_drag_set_default_icon"); end Gtk.Dnd;