-----------------------------------------------------------------------
-- 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;