lcl: docking - reposition children after the dock layout change

git-svn-id: trunk@17860 -
This commit is contained in:
paul 2008-12-19 07:16:03 +00:00
parent 3ba102a25f
commit 0206260c62
3 changed files with 195 additions and 87 deletions

View File

@ -1893,6 +1893,7 @@ type
FOrientation: TDockOrientation;
FNextSibling: TDockZone;
FPrevSibling: TDockZone;
FBounds: TRect;
protected
function GetHeight: Integer; virtual;
function GetLeft: Integer; virtual;
@ -1902,6 +1903,12 @@ type
function GetVisible: Boolean; virtual;
function GetVisibleChildCount: Integer; virtual;
function GetWidth: Integer; virtual;
procedure SetLimitBegin(const AValue: Integer); virtual;
procedure SetLimitSize(const AValue: Integer); virtual;
procedure SetHeight(const AValue: Integer); virtual;
procedure SetLeft(const AValue: Integer); virtual;
procedure SetTop(const AValue: Integer); virtual;
procedure SetWidth(const AValue: Integer); virtual;
public
constructor Create(TheTree: TDockTree; TheChildControl: TControl);
function FindZone(AControl: TControl): TDockZone;
@ -1919,17 +1926,17 @@ type
property ChildControl: TControl read FChildControl;
property ChildCount: Integer read FChildCount;
property FirstChild: TDockZone read FFirstChildZone;
property Height: Integer read GetHeight;
property Left: Integer read GetLeft;
property LimitBegin: Integer read GetLimitBegin; // returns Left or Top
property LimitSize: Integer read GetLimitSize; // returns Width or Height
property Height: Integer read GetHeight write SetHeight;
property Left: Integer read GetLeft write SetLeft;
property LimitBegin: Integer read GetLimitBegin write SetLimitBegin; // returns Left or Top
property LimitSize: Integer read GetLimitSize write SetLimitSize; // returns Width or Height
property Orientation: TDockOrientation read FOrientation write FOrientation;
property Parent: TDockZone read FParentZone;
property Top: Integer read GetTop;
property Top: Integer read GetTop write SetTop;
property Tree: TDockTree read FTree;
property Visible: Boolean read GetVisible;
property VisibleChildCount: Integer read GetVisibleChildCount;
property Width: Integer read GetWidth;
property Width: Integer read GetWidth write SetWidth;
property NextSibling: TDockZone read FNextSibling;
property PrevSibling: TDockZone read FPrevSibling;
end;

View File

@ -18,105 +18,155 @@
*****************************************************************************
}
function TDockZone.GetHeight: Integer;
//var
//Zone: TDockZone;
//R: TRect;
procedure TDockZone.SetLimitBegin(const AValue: Integer);
// sets the left/top coord of zone.
begin
case FOrientation of
doHorizontal: Top := AValue;
doVertical: Left := AValue;
else
raise Exception.Create('TDockZone.SetLimitBegin');
end;
end;
procedure TDockZone.SetLimitSize(const AValue: Integer);
// sets the zone width/height.
begin
case FOrientation of
doHorizontal: Height := AValue;
doVertical: Width := AValue;
else
raise Exception.Create('TDockZone.SetLimitSize');
end;
end;
procedure TDockZone.SetHeight(const AValue: Integer);
begin
if not Visible then
Result:=0
else if (FChildControl<>nil) then
Result:=FChildControl.Height
else if FParentZone<>nil then
Result:=FParentZone.Height
else
Result:=0;
Exit;
{if (Self = FTree.FTopZone)
or ((FParentZone = FTree.FTopZone)
and (FChildControl <> nil) and (FTree.FTopZone.VisibleChildCount = 1))
then begin
R := FTree.FDockSite.ClientRect;
FTree.FDockSite.AdjustClientRect(R);
Result := R.Bottom - R.Top;
end
else begin
Zone := Self;
while Zone.FParentZone<>nil do begin
if Zone.FParentZone.FOrientation = doHorizontal then begin
Result := Zone.ZoneLimit - Zone.LimitBegin;
Exit;
end else
Zone := Zone.FParentZone;
end;
if FTree.FTopZone.FOrientation = doHorizontal then
Result := FTree.FTopXYLimit
if (FChildControl <> nil) then
FChildControl.Height := AValue
else
FBounds.Bottom := AValue;
end;
procedure TDockZone.SetLeft(const AValue: Integer);
begin
if not Visible then
Exit;
if (FChildControl <> nil) then
FChildControl.Left := AValue
else
FBounds.Left := AValue;
end;
procedure TDockZone.SetTop(const AValue: Integer);
begin
if not Visible then
Exit;
if (FChildControl <> nil) then
FChildControl.Top := AValue
else
FBounds.Top := AValue;
end;
procedure TDockZone.SetWidth(const AValue: Integer);
begin
if not Visible then
Exit;
if (FChildControl <> nil) then
FChildControl.Width := AValue
else
FBounds.Right := AValue;
end;
function TDockZone.GetHeight: Integer;
begin
if not Visible then
Result := 0
else
if (FChildControl <> nil) then
begin
if FTree.RootZone = Self then
Result := FChildControl.ClientHeight
else
Result := FTree.FTopZone.ZoneLimit;
end;}
Result := FChildControl.Height
end
else
begin
if FParentZone.Orientation = doHorizontal then
Result := FBounds.Bottom
else
Result := FParentZone.Height;
end;
end;
function TDockZone.GetLeft: Integer;
//var
//Zone: TDockZone;
//R: TRect;
begin
Result:=0;
{Zone := Self;
while Zone.FParentZone<>nil do begin
if (Zone.FParentZone.FOrientation = doVertical)
and (Zone.FPrevSibling <> nil) then begin
Result := Zone.FPrevSibling.ZoneLimit;
Exit;
end else
Zone := Zone.FParentZone;
if not Visible then
Result := 0
else
if (FChildControl <> nil) then
begin
if FTree.RootZone = Self then
Result := 0
else
Result := FChildControl.Left
end
else
begin
if FParentZone.Orientation = doVertical then
Result := FBounds.Left
else
Result := FParentZone.Left;
end;
R := FTree.FDockSite.ClientRect;
FTree.FDockSite.AdjustClientRect(R);
Result:=R.Left;}
end;
function TDockZone.GetLimitBegin: Integer;
// returns the zone limit.
// returns the left/top coord of zone.
begin
if FOrientation = doHorizontal then
Result := Top
else if FOrientation = doVertical then
Result := Left
case FOrientation of
doHorizontal: Result := Top;
doVertical: Result := Left;
else
raise Exception.Create('TDockZone.GetLimitBegin');
end;
end;
function TDockZone.GetLimitSize: Integer;
// returns the zone size.
// returns the zone width/height.
begin
if FOrientation = doHorizontal then
Result := Height
else if FOrientation = doVertical then
Result := Width
case FOrientation of
doHorizontal: Result := Height;
doVertical: Result := Width;
else
raise Exception.Create('TDockZone.GetLimitSize');
end;
end;
function TDockZone.GetTop: Integer;
//var
//Zone: TDockZone;
//R: TRect;
begin
Result:=0
{Zone := Self;
while Zone.FParentZone<>nil do begin
if (Zone.FParentZone.FOrientation = doHorizontal)
and (Zone.FPrevSibling <> nil) then begin
Result := Zone.FPrevSibling.ZoneLimit;
Exit;
end else
Zone := Zone.FParentZone;
if not Visible then
Exit(0);
if (FChildControl <> nil) then
begin
if FTree.RootZone = Self then
Result := 0
else
Result := FChildControl.Top
end
else
begin
if FParentZone.Orientation = doHorizontal then
Result := FBounds.Top
else
Result := FParentZone.Top;
end;
R := FTree.FDockSite.ClientRect;
FTree.FDockSite.AdjustClientRect(R);
Result:=R.Top;}
end;
function TDockZone.GetVisible: Boolean;
@ -143,13 +193,22 @@ end;
function TDockZone.GetWidth: Integer;
begin
if not Visible then
Result:=0
else if (FChildControl<>nil) then
Result:=FChildControl.Width
else if FParentZone<>nil then
Result:=FParentZone.Width
Exit(0);
if (FChildControl <> nil) then
begin
if FTree.RootZone = Self then
Result := FChildControl.ClientWidth
else
Result := FChildControl.Width
end
else
Result:=0;
begin
if FParentZone.Orientation = doVertical then
Result := FBounds.Right
else
Result := FParentZone.Width;
end;
end;
function TDockZone.GetNextVisibleZone: TDockZone;
@ -161,8 +220,9 @@ end;
constructor TDockZone.Create(TheTree: TDockTree; TheChildControl: TControl);
begin
FTree:=TheTree;
FChildControl:=TheChildControl;
FTree := TheTree;
FChildControl := TheChildControl;
FBounds := Rect(0, 0, 0, 0);
end;
function TDockZone.FindZone(AControl: TControl): TDockZone;

View File

@ -81,6 +81,7 @@ type
procedure AdjustDockRect(AControl: TControl; var ARect: TRect); override;
procedure AnchorDockLayout(Zone: TLazDockZone);
procedure CreateDockLayoutHelperControls(Zone: TLazDockZone);
procedure ResetSizes(Zone: TLazDockZone);
procedure BreakAnchors(Zone: TDockZone);
procedure PaintDockFrame(ACanvas: TCanvas; AControl: TControl;
const ARect: TRect); override;
@ -992,6 +993,45 @@ begin
CreateDockLayoutHelperControls(Zone.NextSibling as TLazDockZone);
end;
procedure TLazDockTree.ResetSizes(Zone: TLazDockZone);
var
NewSize, NewPos: Integer;
Child: TLazDockZone;
begin
if Zone = nil then
Exit;
// split available size between children
if (Zone.Orientation in [doHorizontal, doVertical]) and
(Zone.VisibleChildCount > 0) then
begin
NewSize := Zone.LimitSize div Zone.VisibleChildCount;
NewPos := Zone.LimitBegin;
Child := Zone.FirstChild as TLazDockZone;
while Child <> nil do
begin
if Child.Visible then
begin
case Zone.Orientation of
doHorizontal:
begin
Child.Top := NewPos;
Child.Height := NewSize;
end;
doVertical:
begin
Child.Left := NewPos;
Child.Width := NewSize;
end;
end;
ResetSizes(Child);
inc(NewPos, NewSize);
end;
Child := Child.NextSibling as TLazDockZone;
end;
end;
end;
procedure TLazDockTree.AdjustDockRect(AControl: TControl; var ARect: TRect);
begin
// offset one of the borders of control rect in order to get space for frame
@ -1305,6 +1345,7 @@ begin
try
BreakAnchors(Zone);
CreateDockLayoutHelperControls(Zone);
ResetSizes(Zone);
AnchorDockLayout(Zone);
finally
if DockSite <> nil then