mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-12-11 16:21:02 +01:00
anchordocking: enlarge one shrink one
git-svn-id: trunk@25999 -
This commit is contained in:
parent
f7eabc0679
commit
397f83d77b
@ -239,7 +239,8 @@ type
|
||||
procedure Merge;
|
||||
function EnlargeSide(Side: TAnchorKind;
|
||||
OnlyCheckIfPossible: boolean): boolean;
|
||||
function EnlargeSideResizeTwoSplitters(Side, SideEnlarge: TAnchorKind;
|
||||
function EnlargeSideResizeTwoSplitters(ShrinkSplitterSide,
|
||||
EnlargeSpitterSide: TAnchorKind;
|
||||
OnlyCheckIfPossible: boolean): boolean;
|
||||
public
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
@ -387,6 +388,8 @@ var
|
||||
function dbgs(SiteType: TAnchorDockHostSiteType): string; overload;
|
||||
|
||||
procedure CopyAnchorBounds(Source, Target: TControl);
|
||||
procedure AnchorAndChangeBounds(AControl: TControl; Side: TAnchorKind;
|
||||
Target: TControl);
|
||||
function ControlsLeftTopOnScreen(AControl: TControl): TPoint;
|
||||
|
||||
implementation
|
||||
@ -419,6 +422,32 @@ begin
|
||||
Target.EnableAutoSizing;
|
||||
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;
|
||||
end;
|
||||
end else begin
|
||||
AControl.AnchorToNeighbour(Side,0,Target);
|
||||
case Side of
|
||||
akTop: AControl.Top:=Target.Top+Target.Height;
|
||||
akLeft: AControl.Left:=Target.Left+Target.Width;
|
||||
akRight: AControl.Width:=Target.Left-AControl.Width;
|
||||
akBottom: AControl.Height:=Target.Top-AControl.Height;
|
||||
end;
|
||||
end;
|
||||
AControl.BoundsRect:=NewBounds;
|
||||
end;
|
||||
|
||||
function ControlsLeftTopOnScreen(AControl: TControl): TPoint;
|
||||
begin
|
||||
if AControl.Parent<>nil then begin
|
||||
@ -2311,27 +2340,33 @@ begin
|
||||
// ToDo:
|
||||
end;
|
||||
|
||||
function TAnchorDockHostSite.EnlargeSideResizeTwoSplitters(Side,
|
||||
SideEnlarge: TAnchorKind; OnlyCheckIfPossible: boolean): boolean;
|
||||
{ Shrink one neighbor control, enlarge Control. Two splitters are resized.
|
||||
function TAnchorDockHostSite.EnlargeSideResizeTwoSplitters(ShrinkSplitterSide,
|
||||
EnlargeSpitterSide: TAnchorKind; OnlyCheckIfPossible: boolean): boolean;
|
||||
{ Shrink one neighbor control, enlarge Self. Two splitters are resized.
|
||||
|
||||
For example: ShrinkSplitterSide=akBottom, EnlargeSpitterSide=akLeft
|
||||
|
||||
|#| |# |#| |#
|
||||
|#| Self |# |#| |#
|
||||
--+#+--------+# --> --+#| Self |#
|
||||
==============# ===#| |#
|
||||
-------------+# --+#| |#
|
||||
A |# A|#| |#
|
||||
-------------+# --+#+--------+#
|
||||
================= ==================
|
||||
|
||||
|
||||
|
||||
|#| |# |#| |#
|
||||
|#| Control |# |#| |#
|
||||
--+#+---------+# --> --+#| Control |#
|
||||
===============# ===#| |#
|
||||
--------------+# --+#| |#
|
||||
A |# A|#| |#
|
||||
--------------+# --+#+---------+#
|
||||
================== ===================
|
||||
}
|
||||
var
|
||||
Splitter: TAnchorDockSplitter;
|
||||
EnlargeSplitter: TAnchorDockSplitter;
|
||||
SideShrink: TAnchorKind;
|
||||
ShrinkSplitter: TControl;
|
||||
i: Integer;
|
||||
Sibling: TControl;
|
||||
ParentSite: TAnchorDockHostSite;
|
||||
ShrinkSplitter: TAnchorDockSplitter;
|
||||
EnlargeSplitter: TAnchorDockSplitter;
|
||||
KeptSide: TAnchorKind;
|
||||
KeptAnchorControl: TControl;
|
||||
Sibling: TControl;
|
||||
ShrinkControl: TControl;
|
||||
i: Integer;
|
||||
begin
|
||||
Result:=false;
|
||||
if not (Parent is TAnchorDockHostSite) then exit;
|
||||
@ -2341,57 +2376,56 @@ begin
|
||||
ParentSite.DisableAutoSizing;
|
||||
end;
|
||||
try
|
||||
Splitter:=TAnchorDockSplitter(AnchorSide[Side].Control);
|
||||
if not (Splitter is TAnchorDockSplitter) then exit;
|
||||
// side has a splitter
|
||||
if (SideEnlarge<>ClockwiseAnchor[Side])
|
||||
and (SideEnlarge<>OppositeAnchor[ClockwiseAnchor[Side]]) then
|
||||
// check ShrinkSplitter
|
||||
ShrinkSplitter:=TAnchorDockSplitter(AnchorSide[ShrinkSplitterSide].Control);
|
||||
if not (ShrinkSplitter is TAnchorDockSplitter) then exit;
|
||||
// check if EnlargeSpitterSide is a neighbor ShrinkSplitterSide
|
||||
if (EnlargeSpitterSide<>ClockwiseAnchor[ShrinkSplitterSide])
|
||||
and (EnlargeSpitterSide<>OppositeAnchor[ClockwiseAnchor[ShrinkSplitterSide]]) then
|
||||
exit;
|
||||
// enlarge side is not a neighbor side
|
||||
EnlargeSplitter:=TAnchorDockSplitter(AnchorSide[SideEnlarge].Control);
|
||||
// check EnlargeSpitter
|
||||
EnlargeSplitter:=TAnchorDockSplitter(AnchorSide[EnlargeSpitterSide].Control);
|
||||
if not (EnlargeSplitter is TAnchorDockSplitter) then exit;
|
||||
// enlarge side has a splitter
|
||||
SideShrink:=OppositeAnchor[SideEnlarge];
|
||||
ShrinkSplitter:=AnchorSide[SideShrink].Control;
|
||||
if (ShrinkSplitter<>ParentSite)
|
||||
and (not (ShrinkSplitter is TAnchorDockSplitter)) then exit;
|
||||
// shrink side is anchored to a splitter or parent
|
||||
if Splitter.AnchorSide[SideShrink].Control<>ShrinkSplitter then exit;
|
||||
// Splitter stopps at ShrinkSplitter
|
||||
// check if KeptSide is anchored to a splitter or parent
|
||||
KeptSide:=OppositeAnchor[EnlargeSpitterSide];
|
||||
KeptAnchorControl:=AnchorSide[KeptSide].Control;
|
||||
if not ((KeptAnchorControl=ParentSite)
|
||||
or (KeptAnchorControl is TAnchorDockSplitter)) then exit;
|
||||
// check if ShrinkSplitter is anchored/stops at KeptAnchorControl
|
||||
if ShrinkSplitter.AnchorSide[KeptSide].Control<>KeptAnchorControl then exit;
|
||||
|
||||
if not OnlyCheckIfPossible then begin
|
||||
if ShrinkSplitter=ParentSite then begin
|
||||
EnlargeSplitter.AnchorParallel(Side,0,ParentSite);
|
||||
AnchorParallel(Side,0,ParentSite);
|
||||
end else begin
|
||||
EnlargeSplitter.AnchorSide[Side].Assign(ShrinkSplitter.AnchorSide[Side]);
|
||||
AnchorSide[Side].Assign(ShrinkSplitter.AnchorSide[Side]);
|
||||
// check if there is a control to shrink
|
||||
ShrinkControl:=nil;
|
||||
for i:=0 to ShrinkSplitter.AnchoredControlCount-1 do begin
|
||||
Sibling:=ShrinkSplitter.AnchoredControls[i];
|
||||
if (Sibling.AnchorSide[OppositeAnchor[ShrinkSplitterSide]].Control=ShrinkSplitter)
|
||||
and (Sibling.AnchorSide[KeptSide].Control=KeptAnchorControl) then begin
|
||||
ShrinkControl:=Sibling;
|
||||
break;
|
||||
end;
|
||||
Splitter.AnchorSide[SideShrink].Control:=EnlargeSplitter;
|
||||
end;
|
||||
if ShrinkControl=nil then exit;
|
||||
|
||||
for i:=0 to Parent.ControlCount-1 do begin
|
||||
Sibling:=Controls[i];
|
||||
if Sibling.AnchorSide[SideEnlarge].Control<>ShrinkSplitter then continue;
|
||||
// Sibling is on the shrinking side
|
||||
case Side of
|
||||
akTop: if Sibling.Top>Top then continue;
|
||||
akLeft: if Sibling.Left>Left then continue;
|
||||
akRight: if Sibling.Left<Left then continue;
|
||||
akBottom: if Sibling.Top<Top then continue;
|
||||
end;
|
||||
if OnlyCheckIfPossible then begin
|
||||
// check if the Sibling is big enough for shrinking
|
||||
case SideShrink of
|
||||
akTop: if Sibling.Top>=EnlargeSplitter.Top then exit;
|
||||
akLeft: if Sibling.Left>=EnlargeSplitter.Left then exit;
|
||||
akRight: if Sibling.Left+Sibling.Width<=EnlargeSplitter.Left+EnlargeSplitter.Width then exit;
|
||||
akBottom: if Sibling.Top+Sibling.Height<=EnlargeSplitter.Top+EnlargeSplitter.Height then exit;
|
||||
end;
|
||||
end else begin
|
||||
// shrink Sibling
|
||||
Sibling.AnchorSide[SideShrink].Control:=EnlargeSplitter;
|
||||
if OnlyCheckIfPossible then begin
|
||||
// check if ShrinkControl is large enough for shrinking
|
||||
case EnlargeSpitterSide of
|
||||
akTop: if ShrinkControl.Top>=EnlargeSplitter.Top then exit;
|
||||
akLeft: if ShrinkControl.Left>=EnlargeSplitter.Left then exit;
|
||||
akRight: if ShrinkControl.Left+ShrinkControl.Width
|
||||
<=EnlargeSplitter.Left+EnlargeSplitter.Width then exit;
|
||||
akBottom: if ShrinkControl.Top+ShrinkControl.Height
|
||||
<=EnlargeSplitter.Top+EnlargeSplitter.Height then exit;
|
||||
end;
|
||||
end else begin
|
||||
// do it
|
||||
// enlarge the EnlargeSplitter and Self
|
||||
AnchorAndChangeBounds(EnlargeSplitter,ShrinkSplitterSide,
|
||||
ShrinkControl.AnchorSide[ShrinkSplitterSide].Control);
|
||||
AnchorAndChangeBounds(Self,ShrinkSplitterSide,
|
||||
ShrinkControl.AnchorSide[ShrinkSplitterSide].Control);
|
||||
// shrink the ShrinkSplitter and ShrinkControl
|
||||
AnchorAndChangeBounds(ShrinkSplitter,KeptSide,EnlargeSplitter);
|
||||
AnchorAndChangeBounds(ShrinkControl,KeptSide,EnlargeSplitter);
|
||||
end;
|
||||
|
||||
finally
|
||||
|
||||
Loading…
Reference in New Issue
Block a user