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

Reply via email to