In my attempt to understand the drag/dock implementation of Lazarus, I 
came across some general questions. Is there a developer who is familiar 
with the current implementation of these things?

1. Model
--------
IMO a separation into drag/dock execution and dock site layout manager 
is suggested.

The drag/dock part only has to deal with the implementation of the 
graphical user feedback, based on the dock source properties DragMode 
and DragKind. It interacts with a drag/dock target at the current mouse 
position, to adjust the drag image appropriately. Depending on DragKind, 
the target should have UseDockManager=True or react on DockOver for 
dkDock, or it should react on DragOver for dkDrag. The search for a 
possible target continues into the parents of the control, until an 
accepting target is found, or the parent is Nil. This part of drag/dock 
execution IMO should be feasable for every platform, somehow. For 
testing purposes or on poorly equipped platforms it would be sufficient 
to change the drag image (or mouse pointer) according to the response of 
the target control.

The layout manager(s) are responsible for inserting and removing 
components, and can be shared with the layout managers of the form 
designers, and the handling of client/container size changes at runtime. 
Java-style and other layout managers could be added freely. The 
anchordocking sample demonstrates an layout manager with no docking 
capabilities (yet).

Dock-aware layout managers provide additional means to determine the 
parameters for visual feedback and a later DockDrop action. They also 
are responsible for starting an undock action at runtime, or for a 
rearrangement of components at design time.

2. Platform support
-------------------
I don't know what features are provided by the currently supported 
platforms, and nobody can know the features of future platforms. That's 
why I would restrict the expected support for drag/drop operations to 
very few features:

2.1 Determination of the component at the mouse position.
This feature should be available on every platform, since the system 
itself must know which target window has to be notified of mouse events.
Using this feature should allow to easily fill the white spots in the 
current determination of the dock site.

2.2 Mouse capture
Every platform should support kind of mouse capture, i.e. sending 
messages to a dedicated capture window, instead of informing the window 
under the mouse position. Information about active capturing and 
dragging should be stored in a dedicated place (Application object?), so 
that it can canceld easily and properly, whenever required. I dunno 
about the synchronization between the IDE and a debugger and debugged 
application, but I assume that there exists according communication, 
which should allow to properly cancel unrecoverable actions.

2.3 Visual feedback
Every platform should at least support mouse pointer shapes, for visual 
feedback about the actual target of a drag action. This primitive kind 
of feedback also requires no special management of temporary images on 
the screen, or in design state. More elaborated feedback can be added 
for platforms with better support for dragging operations (drag images 
etc.). Question is: how to deal with platform specific features in the LCL?
Another kind of standard support could use the hint-window mechanism, 
and drag around such a temporary window. Then the target of a dock 
operation only had to supply the dock zone (RECT), so that the dragged 
window can be properly resized and repositioned. This solution is really 
useful only with transparent windows, which do not hide the possible 
dock targets, both from the sight of the user, nor from the sight of the 
system in the determination of the drag target. Perhaps not a good idea?

3. Dock zones
-------------
IMO the current integration of drag/dock support bloats the TWinControl 
class too much. Much could be moved into the DockManager, except for the 
event handlers, UseDockManager and the DockManager itself. Even the 
information about the undocked size of docked components could be stored 
in the dock manager. While the data bloat may be acceptable, the code 
bloat hinders a proper (re-)design of the buggy or still missing parts 
of the drag/dock code.

3.1 Dock sites
IMO dock sites could be implemented in dedicated container controls, 
which react on docking events at all. These controls also can implement 
support for floating themselves, e.g. as detachable frames or toolbars. 
Delphi compatibility will not be affected, but a choice of ready-to-use 
docking components can simplify the design of new Lazarus applications.

3.2 Dockable components
IMO the docking of simple components is useful only at design time, when 
components are dropped from the toolbar onto a form. Docking at runtime 
can be restricted to forms and other floatable components, like toolbars 
or frames. Undocking of docked components requires that the structure of 
the docked components stays intact, i.e. forms or frames must be 
undocked in their original composition and framing. This forbids 
unpacking the components of a form, when the form is docked. When a form 
or frame instead is docked entirely, including a (small) title bar as in 
Delphi, every docked item can be restored exactly into it's previous 
appearance and behaviour, what currently simply is impossible.


3.3 Determination of the docking position.
I'll not go into details here, it's mostly a matter of implementation of 
the an docking manager. The default (tree) docking manager 
implementation lacks many docking features which can hardly be added, or 
even be made work, without a deep redesign of all related classes and 
other data types.

Therefore I'd suggest a separation of any but the abstract TDockManager 
from the Controls unit, eliminating the need for a rebuild of the IDE 
after every change to the Controls unit. It also will show up the 
undocumented dependencies between controls, messages, and the code that 
implements the details of dragging and docking. I'm willing to perform 
that separation myself, if no official developer is willing to do so - 
but I'm not willing to spend much time when afterwards the new structure 
doesn't become part of the trunk.

DoDi

_______________________________________________
Lazarus mailing list
[email protected]
http://www.lazarus.freepascal.org/mailman/listinfo/lazarus

Reply via email to