Paul Ishenin schrieb:
That's all, so far, but it took me many hours to distill all the
observed woes of the current [L]DockTree implementation into these few
principles.
Will you implement this principles also?
I've just implemented TDockTree.PositionDockRect (see appended diff).
Before testing with the docking example, remove the Form1.OnDockOver
handler, which replaces the DockRect again.
There is one problem with getting the dock zone extent, as you can see
in the comment on dzone.FBounds, which seems to be invalid for most
docking zones. The workaround with dzone.Top etc. works better, but it
excludes the zone header - behaves like DropCtl.Bounds. Using the
workaround makes the DockRect behave almost as in Delphi.
There exist more problems with the current implementation, apart from
the bugs in the dock zone management. One problem is inherited from the
Delphi interface IDockManager, which allows the docking manager to
modify the DockRect, but doesn't allow to also modify the DropAlign. It
wouldn't break compatibility to make DropAlign an "var" parameter in
PositionDockRect, like DockRect already is. Without this or a similar
patch it will be impossible to obtain values other than the
top/bottom/left/right alignment, as determined by the dragged control.
When the zone and alignment is only determined by the dragged control,
without a chance for adjustments by the dock manager, it will be almost
impossible to e.g. dock a control to the top or bottom of a horizontal
row of already docked controls.
Another problem is the determination of the DropCtl, which cannot work
properly when the mouse is over an dock header, not over a docked
control - then DropCtl is Nil. Then the dock manager has no idea about
the affected dock zone. Using the current mouse position and iterating
through the dock zones doesn't work just now, because the dock zones
currently do not have a valid Bounds rectangle (including the zone
header). This also may be one of the reason for further errors in the
handling of docked controls and docking zones.
The Delphi implementation reveals further problems, e.g. undocking a
control can result in undocking an entire dock zone with more than only
the intended control. A bug or a feature?
Now I wish everybody a Merry Christmas or, to be more political correct,
seasonal greetings :-)
DoDi
Index: D:/SourceForge/Lazarus/lcl/include/docktree.inc
===================================================================
--- D:/SourceForge/Lazarus/lcl/include/docktree.inc (revision 17889)
+++ D:/SourceForge/Lazarus/lcl/include/docktree.inc (working copy)
@@ -112,8 +112,33 @@
procedure TDockTree.PositionDockRect(AClient, DropCtl: TControl;
DropAlign: TAlign; var DockRect: TRect);
+var
+ dzone: TDockZone;
+ r: TRect;
begin
- // ToDo
+//determine drop zone
+ if DropCtl = nil then
+ dzone := RootZone
+ else
+ dzone := RootZone.FindZone(DropCtl);
+//get the zone extent.
+ r := dzone.FBounds; //todo: doesn't work
+//this works better, but doesn't include the zone header
+ //r := Rect(dzone.Left, dzone.Top, dzone.Width, dzone.Height);
+//shrink rect
+ case DropAlign of
+ alTop: r.Bottom := r.Bottom div 2;
+ alBottom: begin r.Bottom := r.Bottom div 2; inc(r.Top, r.Bottom); end;
+ alLeft: r.Right := r.Right div 2;
+ alRight: begin r.Right := r.Right div 2; inc(r.Left, r.Right); end;
+ end;
+//client to screen
+ r.TopLeft := DockSite.ClientToScreen(r.TopLeft);
+//width/height to right/bottom
+ inc(r.Bottom, r.Top);
+ inc(r.Right, r.Left);
+//store result
+ DockRect := r;
end;
procedure TDockTree.RemoveControl(AControl: TControl);
_______________________________________________
Lazarus mailing list
[email protected]
http://www.lazarus.freepascal.org/mailman/listinfo/lazarus