From 797f804dc41165f1d28fa21af227f642298f39d9 Mon Sep 17 00:00:00 2001 From: mattias Date: Sat, 12 Jun 2010 21:34:12 +0000 Subject: [PATCH] anchordocking: enlarge with rotate splitter git-svn-id: trunk@26070 - --- examples/anchordocking/anchordocking.pas | 150 +++++++++++++++++++++-- lcl/lclproc.pas | 2 +- 2 files changed, 142 insertions(+), 10 deletions(-) diff --git a/examples/anchordocking/anchordocking.pas b/examples/anchordocking/anchordocking.pas index c54eace1b8..a90948c9f7 100644 --- a/examples/anchordocking/anchordocking.pas +++ b/examples/anchordocking/anchordocking.pas @@ -259,6 +259,8 @@ type function EnlargeSideResizeTwoSplitters(ShrinkSplitterSide, EnlargeSpitterSide: TAnchorKind; OnlyCheckIfPossible: boolean): boolean; + function EnlargeSideRotateSplitter(Side: TAnchorKind; + OnlyCheckIfPossible: boolean): boolean; procedure CreateBoundSplitter; procedure PositionBoundSplitter; public @@ -509,17 +511,14 @@ end; procedure AnchorAndChangeBounds(AControl: TControl; Side: TAnchorKind; Target: TControl); -var - NewBounds: TRect; begin - NewBounds:=AControl.BoundsRect; if Target=AControl.Parent then begin AControl.AnchorParallel(Side,0,Target); case Side of akTop: AControl.Top:=0; akLeft: AControl.Left:=0; akRight: AControl.Width:=AControl.Parent.ClientWidth-AControl.Left; - akBottom: AControl.Height:=AControl.Parent.ClientHeight-Acontrol.Top; + akBottom: AControl.Height:=AControl.Parent.ClientHeight-AControl.Top; end; end else begin AControl.AnchorToNeighbour(Side,0,Target); @@ -530,7 +529,6 @@ begin akBottom: AControl.Height:=Target.Top-AControl.Height; end; end; - AControl.BoundsRect:=NewBounds; end; function ControlsLeftTopOnScreen(AControl: TControl): TPoint; @@ -3051,12 +3049,13 @@ function TAnchorDockHostSite.EnlargeSide(Side: TAnchorKind; =================== =================== } begin - Result:=false; + Result:=true; if EnlargeSideResizeTwoSplitters(Side,ClockwiseAnchor[Side], - OnlyCheckIfPossible) then exit(true); + OnlyCheckIfPossible) then exit; if EnlargeSideResizeTwoSplitters(Side,OppositeAnchor[ClockwiseAnchor[Side]], - OnlyCheckIfPossible) then exit(true); - // ToDo: EnlargeBetween + OnlyCheckIfPossible) then exit; + if EnlargeSideRotateSplitter(Side,OnlyCheckIfPossible) then exit; + Result:=false; end; function TAnchorDockHostSite.EnlargeSideResizeTwoSplitters(ShrinkSplitterSide, @@ -3156,6 +3155,139 @@ begin Result:=true; end; +function TAnchorDockHostSite.EnlargeSideRotateSplitter(Side: TAnchorKind; + OnlyCheckIfPossible: boolean): boolean; +{ Shrink splitter at Side, enlarge both neighbor splitters, + rotate the splitter behind, enlarge Control, + shrink controls at rotate splitter + + |#| |#| |#| |#| + |#| Control |#| |#| |#| + --+#+---------+#+-- --> --+#| Control |#+-- + =================== ===#| |#=== + --------+#+-------- --+#| |#+-- + |#| B |#| |#|B + |#+-------- |#| |#+-- + A |#========= A|#| |#=== + |#+-------- |#| |#+-- + |#| C |#| |#|C + --------+#+-------- --+#+---------+#+-- + =================== =================== +} +var + Splitter: TAnchorDockSplitter; + CWSide: TAnchorKind; + CWSplitter: TAnchorDockSplitter; + CCWSide: TAnchorKind; + i: Integer; + Sibling: TControl; + BehindSide: TAnchorKind; + RotateSplitter: TAnchorDockSplitter; + CCWSplitter: TAnchorDockSplitter; +begin + Result:=false; + // check if there is a splitter at Side + Splitter:=TAnchorDockSplitter(AnchorSide[Side].Control); + if not (Splitter is TAnchorDockSplitter) then exit; + // check if there is a splitter at clockwise Side + CWSide:=ClockwiseAnchor[Side]; + CWSplitter:=TAnchorDockSplitter(AnchorSide[CWSide].Control); + if not (CWSplitter is TAnchorDockSplitter) then exit; + // check if there is a splitter at counter clockwise Side + CCWSide:=OppositeAnchor[CWSide]; + CCWSplitter:=TAnchorDockSplitter(AnchorSide[CCWSide].Control); + if not (CCWSplitter is TAnchorDockSplitter) then exit; + // check if neighbor splitters end at Splitter + if CWSplitter.AnchorSide[Side].Control<>Splitter then exit; + if CCWSplitter.AnchorSide[Side].Control<>Splitter then exit; + // find the rotate splitter behind Splitter + BehindSide:=OppositeAnchor[Side]; + RotateSplitter:=nil; + for i:=0 to Splitter.AnchoredControlCount-1 do begin + Sibling:=Splitter.AnchoredControls[i]; + if Sibling.AnchorSide[BehindSide].Control<>Splitter then continue; + if not (Sibling is TAnchorDockSplitter) then continue; + if Side in [akLeft,akRight] then begin + if Sibling.TopTop+Height then continue; + end else begin + if Sibling.LeftLeft+Width then continue; + end; + if RotateSplitter=nil then + RotateSplitter:=TAnchorDockSplitter(Sibling) + else + // there are multiple splitters behind + exit; + end; + // check that all siblings at RotateSplitter are large enough to shrink + for i:=0 to RotateSplitter.AnchoredControlCount-1 do begin + Sibling:=RotateSplitter.AnchoredControls[i]; + if Side in [akLeft,akRight] then begin + if (Sibling.Top>Top-DockMaster.SplitterWidth) + and (Sibling.Top+Sibling.HeightLeft-DockMaster.SplitterWidth) + and (Sibling.Left+Sibling.Width