On Sat, Apr 18, 2009 at 01:56:54AM +0200, Hans-Peter Diettrich wrote:
> I've started documentation about dragging, with the first part
> (drag-drop) here:
> <http://wiki.lazarus.freepascal.org/LCL_Drag_Drop>
It would be helpful to include a Message Sequence Chart or UML Sequence
Diagram, visualizing which objects and methods are involved in what order.
Something along the lines (this is for Delphi; view with monospaced font):
Main Drag (Optional) Drag
User Event Source Drag Target
(Mouse) Loop Control Object Control
= = = =
| | | |
1|--MouseDown--->| | |
| 2#--OnMouseDown->| |
| | 3# |
| 4#<-BeginDrag()--# |
| # # |
| | | |
| 5#--OnStartDrag->| |
| # 6#----Create---->= |
| | # | |
7|--MouseMove--->| | | |
| 8#-----------------------------------OnDragOver->|
| # | | 9#
| # | | #
| | | | |
10|---MouseUp---->| | | |
| 11#-----------------------------------OnDragDrop->|
| # | | 12#
| # | | #
| #---OnEndDrag-->| | |
| | 13#----Destroy--->= |
| | | |
The DragObject is optional. There could be multiple candidate targets.
The Main Event Loop determines which event to send to which object,
depending on the user action, the cursor location, and the current state
of the GUI.
4 somehow triggers 5 (there is a delay depending on the Boolean parameter
Immediate to BeginDrag).
6 determines the location of the MouseDown and may use this to decide on
what gets dragged (through GetCursorPos, ScreenToClient, MouseToCell).
It can call SetDragImage to visualize a thing being dragged.
The chain 7, 8, 9 can occur repeatedly; 9 indicates acceptability
of a drop at this target via the Boolean var parameter Accepted.
12 is called only if the immediately preceding OnDragOver of this target
returned Accepted = True; i.e. Accepted is a precondition of 12.
13 receives the parameter Target to know where the drop was accepted;
if Target = nil, then the drop was cancelled by the user
(MouseUp at an unacceptable location), and OnDragDrop was not performed;
if Target <> nil, then OnDragDrop was already performed at the Target.
The work associated with an actual drop is thus divided over the
OnDragDrop (for actions at the target) and OnEndDrag (for actions at
the source). Since a Drag Object needs to be destroyed, independent
of whether the drop was successful or canceled, it is best to call
Free (or Destroy) only in the OnEndDrag handler.
Only one drag can be active at any moment; it either ends in a drop or is
canceled.
There are various other things to be included, but this is the fundamental
part. (Maybe also see <http://www.delphi-central.com/drag.aspx> or
<http://www.podgoretsky.com/ftp/Docs/Delphi/D5/dg/controls.html>.)
I hope this is helpful.
Tom
--
E-MAIL: T.Verhoeff @ TUE.NL | Dept. of Math. & Comp. Science
PHONE: +31 40 247 41 25 | Technische Universiteit Eindhoven
FAX: +31 40 247 54 04 | PO Box 513, NL-5600 MB Eindhoven
http://www.win.tue.nl/~wstomv/ | The Netherlands
_______________________________________________
Lazarus mailing list
[email protected]
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus