Monday, February 8, 2010

More Flexible Docking

The Delphi docking model happens to implement (by accident?) a feature, which I'd call top-level docking. When no DropOn control is found by the stupid DragManager/TControl methods, the dropped control is docked into the root zone of the docktree. This can happen on e.g. an drop onto an zone header, for which only the DockManager can determine the associated control, or on an drop outside the target DockSite, but within its InfluenceRect.

I've already tried to implement docking relative to dockzones, instead of relative to already docked controls, but didn't follow this approach further. The idea was to take into account the distance of the drop position, relative to the center of a dockzone. From this approach only the notebook-docking has survived, forced on an drop near the center of an already docked control. A similar override could be made for positions close to the boundary of a docked control, but I couldn't find a simple implementation with obvious DockRect feedback.

Now the idea comes up again, with drop positions near the boundaries of an entire DockSite. The existing code only allows for extending the root (or any other) zone only in its established horizontal/vertical orientation (isogonal), and this behaviour now should be extended to orthogonal docking at least for the root zone.

Let's take the case of DropOnControl=Nil to force an drop into the root zone. This condition must be checked at least twice, once in GetDockEdge and later in InsertControl. In both methods a search for the closest already docked control must be skipped, when the drop position is out of (or close to) the boundaries of the DockSite. In InsertControl another check may be required, to distinguish an drop into an empty DockSite from an drop into the root zone of an already populated DockSite. Everything were much easier to implement if the dragged control would not try to determine the DropOnControl and DockRect itself, without any knowledge about the DockManager's dockzones :-(