[Lazarus] A few hacky patches (resent)

Brad Campbell brad at wasp.net.au
Wed May 20 03:33:58 CEST 2009


Tom Verhoeff schrieb:

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

Thanks for your chart :-)
[...]
Do you want to add it to the wiki?

Unfortunately the actual order is more complicated, and more objects are 
involved, especially in drag-dock. I've already tried to create an graph 
with the called methods, but it doesn't scale nicely :-(


> The DragObject is optional.

It's not optional, but a default object is created unless one is 
provided by the application in OnDragStart. In Delphi the DragObject 
handles the input messages, what in Lazarus is the task of the 
DragManager. The Delphi approach is more flexible, but not very useful 
without access to the many protected TControl methods and properties.

> 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).

In Delphi the DragObject has to be created immediately, because it 
handles the further input (message loop). In Lazarus the creation could 
be postponed, until a not-immediate drag really starts.

> 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 visualization allows for many implementations, like dragging a 
connection from one component to another one, in a graph or flowchart 
construction or (electronic...) CAD application.

> The chain 7, 8, 9 can occur repeatedly; 9 indicates acceptability
> of a drop at this target via the Boolean var parameter Accepted.

OnDragOver can occur for enter, leave and move. Usually only the result 
of a dsDragMove is processed further, but in a manual drag operation 
only the outcome of dsDragLeave is the important one, invoked from 
DragStop prior to 11. IMO this convention is one more design flaw.

> 12 is called only if the immediately preceding OnDragOver of this target
> returned Accepted = True; i.e. Accepted is a precondition of 12.

When a dock manager is used, OnDockOver can be omitted. Otherwise 
Accepted is set to True before the call to the handler.

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

In drag-dock there can exist 4 possible outcomes: a valid drop (dock), a 
valid drop on no target (float), an invalid drop (cancel), and the abort 
of a not yet started drag. In addition the entire operation can be 
aborted from the OnUnDock handler - I wonder why in this case the drag 
did start at all :-(

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

DragObjects can be destroyed automatically, what is done for the default 
objects and the TDrag...ObjectEx classes. The other classes are designed 
for re-use, and should be created and destroyed only once for the 
lifetime of the application.

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

Of course :-)

Do you have already or want to implement some sample applications, for 
e.g. the demonstration of the OnDragMove visualization?

DoDi





More information about the Lazarus mailing list