Added high-level orientation as to what "pick and drop" means, and added reference to its use in EiffelStudio. Also various refinements and grammar corrections. Also clarification on what object to call 'set_pick_and_drop_mode', 'set_drag_and_drop_mode', etc. on. Also added a working code example of how to use set_accept_cursor and set_deny_cursor.

Author:vwheeler
Date:2014-04-29T22:20:43.000000Z


git-svn-id: https://svn.eiffel.com/eiffel-org/trunk@1351 abb3cda0-5349-4a8f-a601-0c33ac3a8c38
This commit is contained in:
vwheeler
2014-04-29 22:20:43 +00:00
parent 3f6dfe5196
commit 5d5dddd8fc

View File

@@ -1,15 +1,24 @@
[[Property:title|EiffelVision Pick and Drop]]
[[Property:weight|0]]
[[Property:uuid|309203de-6536-fe26-4f73-cb1f4a450e6f]]
Pick and drop is a mechanism which allows data to be transported from a '''source''' object to a '''target'''. Any EiffelVision 2 object inheriting [[ref:libraries/vision2/reference/ev_pick_and_dropable_chart|EV_PICK_AND_DROPABLE]] can be used to transport or receive data.
Pick-and-Drop is a unique user-interface action that permits a user to request an action be performed on a specified object. It is a more-ergonomic alternative to the typical drag-and-drop or "select-and-click" user operations found in most modern graphical user interfaces. Users of EiffelStudio have come to value Pick-and-Drop as both intuitive, and easier on the wrist and fingers with long-term use.
==A simple pick and drop example==
Pick-and-Drop uses the metaphor of '''pebbles and holes'''. The typical method of doing a pick-and-drop is that the end user selects the object to receive an action with a single click-and-release of the right mouse button. At that point, the mouse arrow turns into a "pebble" connected to the "point of picking" via a visible "band". This "pebble" is often an icon representing the type of object that was "picked". The "pebble" may then be dropped into any compatible "hole" (drop target—a widget configured to accept "pebbles" of this type). Such "receiving" widgets are often tool-bar buttons, but can be any widget that inherits from EV_PICK_AND_DROPABLE and is properly configured. The user then can either "drop the pebble into the hole" with a second click-and-release of the right mouse button (on the receiving object), or may cancel the operation by single-clicking the left mouse button.
Two necessary components for a pick and drop transport are a '''source''' and a '''target''', both of which must conform to [[ref:libraries/vision2/reference/ev_pick_and_dropable_chart|EV_PICK_AND_DROPABLE]]. The data that is to be transported is known as a '''pebble'''.
{{note|See [[uuid:a3789781-153b-7f4d-bb94-4bdf8923fb56|Retargeting Through Pick-and-Drop]] to see how EiffelStudio uses the Pick-and-Drop user interface.<br><br>}}
Because the Pick-and-Drop operation has been so popular, classes have been added to the EiffelVision 2 library to make implementing this user interface very easy.
From a technical viewpoint, Pick-and-Drop is a mechanism which allows data to be transported from a '''source''' object to a '''target'''. Any EiffelVision 2 object inheriting from [[ref:libraries/vision2/reference/ev_pick_and_dropable_chart|EV_PICK_AND_DROPABLE]] can be used to transport or receive data.
==A Simple Pick-and-Drop Example==
The two necessary components for a Pick-and-Drop operation are a '''source''' and a '''target''', both of which must [[uuid:b8c10baa-4f50-adfe-a6f8-9cb56a8f1917#Conformance|conform]] to [[ref:libraries/vision2/reference/ev_pick_and_dropable_chart|EV_PICK_AND_DROPABLE]]. The data that is to be transported is known as a '''pebble'''.
The following steps need to be undertaken to set up a simple pick and drop:
* Set the '''source''' by calling set_pebble.
* Set one or more '''targets''' by adding a function to their drop_actions. The arguments of the function must match the type of the '''pebble''' to be transported for the '''source''' otherwise the transport will not be permitted.
* Set one or more '''targets''' by adding an [[ET: Agents|agent]] to their <eiffel>drop_actions</eiffel> list. To make the '''target''' accept that type of '''pebble''', the arguments of the [[ET: Agents|agent]] must match the type of the '''pebble''' to be transported for the '''source'''. Otherwise the transport will not be permitted.
A simple example of this is demonstrated here:
<code>
@@ -17,22 +26,54 @@ A simple example of this is demonstrated here:
button2.drop_actions.extend (agent print (?))
</code>
As print takes an argument of type [[ref:/libraries/base/reference/string_8_chart|STRING_8]], button2 becomes a valid target for the pebble contained in button1. Right clicking the mouse pointer over the '''source''' will start the transport, and right clicking with the mouse pointer over a valid '''target''' will end the transport. The transport can be canceled anytime with a simple left click, just as you would do in EiffelStudio.
Because <eiffel>print</eiffel> takes an argument of type [[ref:/libraries/base/reference/string_8_chart|STRING_8]], button2 becomes a valid drop-target for the pebble contained by button1. Right clicking the mouse pointer over the '''source''' will start the transport, and right clicking with the mouse pointer over a valid '''target''' will complete the transport. The transport can be canceled anytime with a simple left click, just as you would do in EiffelStudio.
{{note|When a transport completes, the '''pebble''' that was transported is passed as an argument to all features in the '''targets''' drop_actions whose argument type matches the '''pebble'''. }}
{{note|When a transport completes, the '''pebble''' that was transported is passed as an argument to all features in the '''targets''' drop_actions whose argument type matches the '''pebble'''. <br><br>}}
==Three different modes of transport==
==Three Different Modes of Transport==
There are three different modes of transport available for pick and drop. They are listed below with details of their use:
* Pick and Drop mode. <br/>
:This is the default mode for pick and drop, but can be set with <eiffel>set_pick_and_drop_mode</eiffel>. Right clicking on a '''source''' starts the transport and right clicking on a valid '''target''' completes the transport. During execution, a band is drawn from the screen position where the pick started to the current mouse position. Pressing the left mouse button or the escape key during execution will end the transport.
::This is the default mode for pick and drop, but can be set by calling <eiffel>set_pick_and_drop_mode</eiffel> on the '''source''' object. Right clicking on a '''source''' starts the transport and right clicking on a valid '''target''' completes the transport. During execution, a band is drawn from the screen position where the pick started to the current mouse position. Pressing the left mouse button or the escape key during execution will end the transport.
* Drag and drop mode <br/>
:This mode can be set with <eiffel>set_drag_and_drop_mode</eiffel>. Left clicking on a '''source''' starts the transport and releasing the left mouse button over a valid '''target''' completes the transport. During execution, a band is drawn from the screen position where the pick started to the current mouse position. Releasing the left mouse button or pressing the escape key during execution will end the transport.
::This mode can be set by calling <eiffel>set_drag_and_drop_mode</eiffel> on the '''source''' object. Left clicking on a '''source''' starts the transport and releasing the left mouse button over a valid '''target''' completes the transport. During execution, a band is drawn from the screen position where the pick started to the current mouse position. Releasing the left mouse button or pressing the escape key during execution will end the transport.
* Target menu mode <br/>
:This mode can be set with <eiffel>set_target_menu_mode</eiffel>. Right clicking on a '''source''' brings up a menu of all the valid drop '''targets''' in the system. Selecting one of these targets completes the transport.
::This mode can be set by calling <eiffel>set_target_menu_mode</eiffel> on the '''source''' object. Right clicking on a '''source''' brings up a menu of all the valid drop '''targets''' in the system. Selecting one of these targets completes the transport.
==Accept and deny cursors==
==Accept and Deny Cursors==
When <eiffel>mode_is_pick_and_drop</eiffel> or <eiffel>mode_is_drag_and_drop</eiffel> then the shape of the mouse cursor changes to reflect whether the current GUI component below the mouse accepts the pebble or not. Calling <eiffel>set_accept_cursor</eiffel> or <eiffel>set_deny_cursor</eiffel> on the '''source''' object allows you to customize the Accept- and Deny-Cursor respectively—used to represent a valid or invalid '''target''' respectively while the mouse pointer (pebble) is being moved around. The default Accept-Cursor is the standard mouse pointer. The default Deny-Cursor is a red circle with a diagonal line across it: the universal "not permitted" symbol.
Example:
<code>
add_some_widgets
-- Add some widgets with a Pick-and-Drop example into `main_window'.
local
my_hbox: EV_HORIZONTAL_BOX
my_button1: EV_BUTTON
my_button2: EV_BUTTON
bullseye_pix_buffer: EV_PIXEL_BUFFER
bullseye_ptr_style: EV_POINTER_STYLE
do
create my_hbox
create my_button1.make_with_text ("Button1")
create my_button2.make_with_text ("Button2")
my_hbox.extend (my_button1)
my_hbox.extend (my_button2)
my_hbox.extend (create {EV_BUTTON}.make_with_text ("Button3"))
main_window.extend (my_hbox)
my_button2.set_pebble ("A Pick-and-Drop has occurred.")
my_button1.drop_actions.extend (agent my_button1.set_text (?))
my_button1.drop_actions.extend (agent io.put_string (?))
create bullseye_pix_buffer.make_with_size (32, 32)
bullseye_pix_buffer.set_with_named_file ("BULLSEYE.png")
create bullseye_ptr_style.make_with_pixel_buffer (bullseye_pix_buffer, 32, 32)
my_button2.set_accept_cursor (bullseye_ptr_style)
end
</code>
When <eiffel>mode_is_pick_and_drop</eiffel> or <eiffel>mode_is_drag_and_drop</eiffel> then the shape of the mouse cursor changes to reflect whether the current GUI component below the mouse accepts the pebble or not. Calling <eiffel>set_accept_cursor</eiffel> allows you to customize this cursor used to represent a valid '''target''' while calling <eiffel>set_deny_cursor</eiffel> allows you to customize the cursor used for non valid '''targets'''.