mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-21 05:01:50 +02:00
anchordocking: restore custom dock site
git-svn-id: trunk@26034 -
This commit is contained in:
parent
7e1ac4fe1a
commit
f987a5217d
@ -350,6 +350,8 @@ type
|
|||||||
property Controls[Index: integer]: TControl read GetControls;
|
property Controls[Index: integer]: TControl read GetControls;
|
||||||
function IndexOfControl(const aName: string): integer;
|
function IndexOfControl(const aName: string): integer;
|
||||||
function FindControl(const aName: string): TControl;
|
function FindControl(const aName: string): TControl;
|
||||||
|
function IsSite(AControl: TControl): boolean;
|
||||||
|
function IsCustomSite(AControl: TControl): boolean;
|
||||||
|
|
||||||
// show / make a control dockable
|
// show / make a control dockable
|
||||||
procedure MakeDockable(AControl: TControl; Show: boolean = true;
|
procedure MakeDockable(AControl: TControl; Show: boolean = true;
|
||||||
@ -501,8 +503,7 @@ begin
|
|||||||
i:=ControlCount-1;
|
i:=ControlCount-1;
|
||||||
while i>=0 do begin
|
while i>=0 do begin
|
||||||
AControl:=Controls[i];
|
AControl:=Controls[i];
|
||||||
if (AControl.HostDockSite is TAnchorDockHostSite)
|
if GetParentForm(AControl).IsVisible
|
||||||
and GetParentForm(AControl).IsVisible
|
|
||||||
and (Tree.Root.FindChildNode(AControl.Name,true)=nil)
|
and (Tree.Root.FindChildNode(AControl.Name,true)=nil)
|
||||||
and (Application.MainForm<>AControl) then begin
|
and (Application.MainForm<>AControl) then begin
|
||||||
// AControl is currently on a visible site, but not in the Tree
|
// AControl is currently on a visible site, but not in the Tree
|
||||||
@ -563,7 +564,7 @@ procedure TAnchorDockMaster.MapTreeToControls(Tree: TAnchorDockLayoutTree;
|
|||||||
TreeNameToDocker: TADNameToControl);
|
TreeNameToDocker: TADNameToControl);
|
||||||
|
|
||||||
procedure MapHostDockSites(Node: TAnchorDockLayoutTreeNode);
|
procedure MapHostDockSites(Node: TAnchorDockLayoutTreeNode);
|
||||||
// map in TreeNameToDocker each control name to its HostDockSite
|
// map in TreeNameToDocker each control name to its HostDockSite or custom dock site
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
AControl: TControl;
|
AControl: TControl;
|
||||||
@ -573,9 +574,16 @@ procedure TAnchorDockMaster.MapTreeToControls(Tree: TAnchorDockLayoutTree;
|
|||||||
AControl:=FindControl(Node.Name);
|
AControl:=FindControl(Node.Name);
|
||||||
if (AControl<>nil) and (AControl.HostDockSite is TAnchorDockHostSite) then
|
if (AControl<>nil) and (AControl.HostDockSite is TAnchorDockHostSite) then
|
||||||
TreeNameToDocker[Node.Name]:=AControl.HostDockSite;
|
TreeNameToDocker[Node.Name]:=AControl.HostDockSite;
|
||||||
end else
|
// ignore kids
|
||||||
for i:=0 to Node.Count-1 do
|
exit;
|
||||||
MapHostDockSites(Node[i]); // recursive
|
end;
|
||||||
|
if (Node.NodeType=adltnCustomSite) then begin
|
||||||
|
AControl:=FindControl(Node.Name);
|
||||||
|
if IsCustomSite(AControl) then
|
||||||
|
TreeNameToDocker[Node.Name]:=AControl;
|
||||||
|
end;
|
||||||
|
for i:=0 to Node.Count-1 do
|
||||||
|
MapHostDockSites(Node[i]); // recursive
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure MapTopLevelSites(Node: TAnchorDockLayoutTreeNode);
|
procedure MapTopLevelSites(Node: TAnchorDockLayoutTreeNode);
|
||||||
@ -587,12 +595,12 @@ procedure TAnchorDockMaster.MapTreeToControls(Tree: TAnchorDockLayoutTree;
|
|||||||
// flickering.
|
// flickering.
|
||||||
|
|
||||||
function FindMappedControl(ChildNode: TAnchorDockLayoutTreeNode
|
function FindMappedControl(ChildNode: TAnchorDockLayoutTreeNode
|
||||||
): TAnchorDockHostSite;
|
): TCustomForm;
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
if ChildNode.NodeType=adltnControl then
|
if ChildNode.NodeType in [adltnControl,adltnCustomSite] then
|
||||||
Result:=TAnchorDockHostSite(TreeNameToDocker[ChildNode.Name])
|
Result:=TCustomForm(TreeNameToDocker[ChildNode.Name])
|
||||||
else
|
else
|
||||||
for i:=0 to ChildNode.Count-1 do begin
|
for i:=0 to ChildNode.Count-1 do begin
|
||||||
Result:=FindMappedControl(ChildNode[i]); // search recursive
|
Result:=FindMappedControl(ChildNode[i]); // search recursive
|
||||||
@ -603,18 +611,18 @@ procedure TAnchorDockMaster.MapTreeToControls(Tree: TAnchorDockLayoutTree;
|
|||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
RootSite: TCustomForm;
|
RootSite: TCustomForm;
|
||||||
Site: TAnchorDockHostSite;
|
Site: TCustomForm;
|
||||||
begin
|
begin
|
||||||
if Node.IsSplitter then exit;
|
if Node.IsSplitter then exit;
|
||||||
if Node.IsRootWindow then begin
|
if Node.IsRootWindow then begin
|
||||||
if Node.Name='' then exit;
|
if Node.Name='' then exit;
|
||||||
if Node.NodeType=adltnControl then exit;
|
if Node.NodeType=adltnControl then exit;
|
||||||
// not is a complex site
|
// Node is a complex site
|
||||||
if TreeNameToDocker[Node.Name]<>nil then exit;
|
if TreeNameToDocker[Node.Name]<>nil then exit;
|
||||||
// and not yet mapped to a site
|
// and not yet mapped to a site
|
||||||
Site:=FindMappedControl(Node);
|
Site:=FindMappedControl(Node);
|
||||||
if Site=nil then exit;
|
if Site=nil then exit;
|
||||||
// and there is sub node mapped to a site
|
// and there is sub node mapped to a site (anchor or custom)
|
||||||
RootSite:=GetParentForm(Site);
|
RootSite:=GetParentForm(Site);
|
||||||
if not (RootSite is TAnchorDockHostSite) then exit;
|
if not (RootSite is TAnchorDockHostSite) then exit;
|
||||||
// and the mapped site has a root site
|
// and the mapped site has a root site
|
||||||
@ -707,13 +715,14 @@ end;
|
|||||||
function TAnchorDockMaster.RestoreLayout(Tree: TAnchorDockLayoutTree;
|
function TAnchorDockMaster.RestoreLayout(Tree: TAnchorDockLayoutTree;
|
||||||
TreeNameToDocker: TADNameToControl): boolean;
|
TreeNameToDocker: TADNameToControl): boolean;
|
||||||
|
|
||||||
procedure SetupSite(Site: TAnchorDockHostSite;
|
procedure SetupSite(Site: TCustomForm;
|
||||||
Node: TAnchorDockLayoutTreeNode; Parent: TWinControl);
|
Node: TAnchorDockLayoutTreeNode; Parent: TWinControl);
|
||||||
begin
|
begin
|
||||||
Site.BoundsRect:=Node.BoundsRect;
|
Site.BoundsRect:=Node.BoundsRect;
|
||||||
Site.Visible:=true;
|
Site.Visible:=true;
|
||||||
Site.Parent:=Parent;
|
Site.Parent:=Parent;
|
||||||
Site.Header.HeaderPosition:=Node.HeaderPosition;
|
if Site is TAnchorDockHostSite then
|
||||||
|
TAnchorDockHostSite(Site).Header.HeaderPosition:=Node.HeaderPosition;
|
||||||
if Parent=nil then begin
|
if Parent=nil then begin
|
||||||
Site.WindowState:=Node.WindowState;
|
Site.WindowState:=Node.WindowState;
|
||||||
if (Node.Monitor>=0) and (Node.Monitor<Screen.MonitorCount) then
|
if (Node.Monitor>=0) and (Node.Monitor<Screen.MonitorCount) then
|
||||||
@ -753,6 +762,21 @@ function TAnchorDockMaster.RestoreLayout(Tree: TAnchorDockLayoutTree;
|
|||||||
AControl.Visible:=true;
|
AControl.Visible:=true;
|
||||||
SetupSite(Site,Node,Parent);
|
SetupSite(Site,Node,Parent);
|
||||||
Result:=Site;
|
Result:=Site;
|
||||||
|
end else if Node.NodeType=adltnCustomSite then begin
|
||||||
|
// restore custom dock site
|
||||||
|
// the control was already created
|
||||||
|
// => position it
|
||||||
|
AControl:=FindControl(Node.Name);
|
||||||
|
if AControl=nil then begin
|
||||||
|
debugln(['TAnchorDockMaster.RestoreLayout.Restore WARNING: can not find control ',Node.Name]);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
if not IsCustomSite(AControl) then begin
|
||||||
|
debugln(['TAnchorDockMaster.RestoreLayout.Restore WARNING: ',Node.Name,' is not a custom dock site ',DbgSName(AControl)]);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
SetupSite(TCustomForm(AControl),Node,nil);
|
||||||
|
Result:=AControl;
|
||||||
end else if Node.IsSplitter then begin
|
end else if Node.IsSplitter then begin
|
||||||
// restore splitter
|
// restore splitter
|
||||||
Splitter:=TAnchorDockSplitter(TreeNameToDocker[Node.Name]);
|
Splitter:=TAnchorDockSplitter(TreeNameToDocker[Node.Name]);
|
||||||
@ -962,6 +986,18 @@ begin
|
|||||||
Result:=nil;
|
Result:=nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TAnchorDockMaster.IsSite(AControl: TControl): boolean;
|
||||||
|
begin
|
||||||
|
Result:=(AControl is TAnchorDockHostSite) or IsCustomSite(AControl);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TAnchorDockMaster.IsCustomSite(AControl: TControl): boolean;
|
||||||
|
begin
|
||||||
|
Result:=(AControl is TCustomForm) // also checks for nil
|
||||||
|
and (AControl.Parent=nil)
|
||||||
|
and (TCustomForm(AControl).DockManager is TAnchorDockManager);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TAnchorDockMaster.MakeDockable(AControl: TControl; Show: boolean;
|
procedure TAnchorDockMaster.MakeDockable(AControl: TControl; Show: boolean;
|
||||||
BringToFront: boolean; AddDockHeader: boolean);
|
BringToFront: boolean; AddDockHeader: boolean);
|
||||||
var
|
var
|
||||||
@ -1032,6 +1068,10 @@ begin
|
|||||||
raise Exception.Create('TAnchorDockMaster.MakeDockSite Parent='+DbgSName(AForm.Parent));
|
raise Exception.Create('TAnchorDockMaster.MakeDockSite Parent='+DbgSName(AForm.Parent));
|
||||||
AForm.DisableAutoSizing;
|
AForm.DisableAutoSizing;
|
||||||
try
|
try
|
||||||
|
if FControls.IndexOf(AForm)<0 then begin
|
||||||
|
FControls.Add(AForm);
|
||||||
|
AForm.FreeNotification(Self);
|
||||||
|
end;
|
||||||
AManager:=TAnchorDockManager.Create(AForm);
|
AManager:=TAnchorDockManager.Create(AForm);
|
||||||
AManager.DockableSites:=Sites;
|
AManager.DockableSites:=Sites;
|
||||||
AForm.DockManager:=AManager;
|
AForm.DockManager:=AManager;
|
||||||
@ -1110,8 +1150,7 @@ begin
|
|||||||
Site:=TAnchorDockHostSite(AForm);
|
Site:=TAnchorDockHostSite(AForm);
|
||||||
LayoutNode:=LayoutTree.NewNode(LayoutTree.Root);
|
LayoutNode:=LayoutTree.NewNode(LayoutTree.Root);
|
||||||
Site.SaveLayout(LayoutTree,LayoutNode);
|
Site.SaveLayout(LayoutTree,LayoutNode);
|
||||||
end else if (AForm.DockManager is TAnchorDockManager)
|
end else if IsCustomSite(AForm) then begin
|
||||||
and (AForm.Parent=nil) then begin
|
|
||||||
// custom dock site
|
// custom dock site
|
||||||
LayoutNode:=LayoutTree.NewNode(LayoutTree.Root);
|
LayoutNode:=LayoutTree.NewNode(LayoutTree.Root);
|
||||||
LayoutNode.NodeType:=adltnCustomSite;
|
LayoutNode.NodeType:=adltnCustomSite;
|
||||||
@ -1615,8 +1654,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
BoundsRect:=NewBounds;
|
BoundsRect:=NewBounds;
|
||||||
BoundsIncreased:=true;
|
BoundsIncreased:=true;
|
||||||
end else if (Parent.DockManager is TAnchorDockManager)
|
end else if DockMaster.IsCustomSite(Parent) then begin
|
||||||
and (Parent.Parent=nil) then begin
|
|
||||||
// Parent is a custom docksite
|
// Parent is a custom docksite
|
||||||
// => expand Self and Parent
|
// => expand Self and Parent
|
||||||
// expand Parent (the custom docksite)
|
// expand Parent (the custom docksite)
|
||||||
@ -1953,11 +1991,9 @@ procedure TAnchorDockHostSite.RemoveControlFromLayout(AControl: TControl);
|
|||||||
p:=ClientOrigin;
|
p:=ClientOrigin;
|
||||||
OffsetRect(NewBounds,p.x,p.y);
|
OffsetRect(NewBounds,p.x,p.y);
|
||||||
BoundsRect:=NewBounds;
|
BoundsRect:=NewBounds;
|
||||||
end else if ((not (Parent is TAnchorDockHostSite))
|
end else if DockMaster.IsCustomSite(Parent) then begin
|
||||||
and (Parent.DockManager is TAnchorDockManager)
|
// parent is a custom dock site
|
||||||
and (Parent.Parent=nil))
|
// shrink this site and the parent
|
||||||
then begin
|
|
||||||
// shrink this site and the parent (which is a custom dock site)
|
|
||||||
NewParentBounds:=Parent.BoundsRect;
|
NewParentBounds:=Parent.BoundsRect;
|
||||||
case Align of
|
case Align of
|
||||||
alTop:
|
alTop:
|
||||||
@ -2748,11 +2784,7 @@ var
|
|||||||
begin
|
begin
|
||||||
GetWindowRect(Handle, InfluenceRect);
|
GetWindowRect(Handle, InfluenceRect);
|
||||||
|
|
||||||
if (Parent=nil)
|
if (Parent=nil) or DockMaster.IsCustomSite(Parent) then begin
|
||||||
or ((not (Parent is TAnchorDockHostSite))
|
|
||||||
and (Parent.DockManager is TAnchorDockManager)
|
|
||||||
and (Parent.Parent=nil))
|
|
||||||
then begin
|
|
||||||
// allow docking outside => enlarge margins
|
// allow docking outside => enlarge margins
|
||||||
ADockMargin:=DockMaster.DockOutsideMargin;
|
ADockMargin:=DockMaster.DockOutsideMargin;
|
||||||
InfluenceRect.Left := InfluenceRect.Left-ADockMargin;
|
InfluenceRect.Left := InfluenceRect.Left-ADockMargin;
|
||||||
|
@ -1078,6 +1078,13 @@ var
|
|||||||
Side: TAnchorKind;
|
Side: TAnchorKind;
|
||||||
Sibling: TAnchorDockLayoutTreeNode;
|
Sibling: TAnchorDockLayoutTreeNode;
|
||||||
begin
|
begin
|
||||||
|
// check parent
|
||||||
|
if (NodeType=adltnNone) and (Parent<>nil) then
|
||||||
|
raise EAnchorDockLayoutError.Create('invalid parent');
|
||||||
|
if (NodeType=adltnCustomSite) and (Parent.NodeType<>adltnNone) then
|
||||||
|
raise EAnchorDockLayoutError.Create('invalid parent');
|
||||||
|
|
||||||
|
// check sides
|
||||||
for Side:=low(TAnchorKind) to high(TAnchorKind) do begin
|
for Side:=low(TAnchorKind) to high(TAnchorKind) do begin
|
||||||
if Anchors[Side]<>'' then begin
|
if Anchors[Side]<>'' then begin
|
||||||
// anchor must be a sibling
|
// anchor must be a sibling
|
||||||
@ -1116,6 +1123,7 @@ begin
|
|||||||
dbgs(Side), '"', Anchors[Side], '"']));
|
dbgs(Side), '"', Anchors[Side], '"']));
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// only the root node, pages, layouts and customsite can have children
|
// only the root node, pages, layouts and customsite can have children
|
||||||
if (Parent<>nil) and (Count>0)
|
if (Parent<>nil) and (Count>0)
|
||||||
and (not (NodeType in [adltnLayout,adltnPages,adltnCustomSite]))
|
and (not (NodeType in [adltnLayout,adltnPages,adltnCustomSite]))
|
||||||
@ -1123,9 +1131,11 @@ begin
|
|||||||
raise EAnchorDockLayoutError.Create(
|
raise EAnchorDockLayoutError.Create(
|
||||||
Format(adrsNoChildrenAllowedForNodeType, ['"', Name, '"',
|
Format(adrsNoChildrenAllowedForNodeType, ['"', Name, '"',
|
||||||
ADLTreeNodeTypeNames[NodeType]]));
|
ADLTreeNodeTypeNames[NodeType]]));
|
||||||
if (NodeType=adltnCustomSite) and (Count>1) then
|
if (NodeType=adltnCustomSite) then begin
|
||||||
raise EAnchorDockLayoutError.Create(Format(
|
if (Count>1) then
|
||||||
adrsCustomDockSiteCanHaveOnlyOneSite, ['"', Name, '"']));
|
raise EAnchorDockLayoutError.Create(Format(
|
||||||
|
adrsCustomDockSiteCanHaveOnlyOneSite, ['"', Name, '"']));
|
||||||
|
end;
|
||||||
|
|
||||||
// check grandchild
|
// check grandchild
|
||||||
for i:=0 to Count-1 do begin
|
for i:=0 to Count-1 do begin
|
||||||
@ -1372,7 +1382,7 @@ end;
|
|||||||
|
|
||||||
function TAnchorDockLayoutTreeNode.IsRootWindow: boolean;
|
function TAnchorDockLayoutTreeNode.IsRootWindow: boolean;
|
||||||
begin
|
begin
|
||||||
Result:=(NodeType in [adltnLayout,adltnPages,adltnControl])
|
Result:=(NodeType in [adltnLayout,adltnPages,adltnControl,adltnCustomSite])
|
||||||
and ((Parent=nil) or (Parent.NodeType in [adltnNone]));
|
and ((Parent=nil) or (Parent.NodeType in [adltnNone]));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@ uses
|
|||||||
begin
|
begin
|
||||||
Application.Initialize;
|
Application.Initialize;
|
||||||
Application.CreateForm(TMainIDE, MainIDE);
|
Application.CreateForm(TMainIDE, MainIDE);
|
||||||
DockMaster.MakeDockSite(MainIDE,[akBottom]);
|
|
||||||
Application.Run;
|
Application.Run;
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -112,6 +112,7 @@ begin
|
|||||||
SaveLayoutToolButton.Hint:='Save Layout to layout.xml';
|
SaveLayoutToolButton.Hint:='Save Layout to layout.xml';
|
||||||
LoadLayoutToolButton.Hint:='Load layout from layout.xml';
|
LoadLayoutToolButton.Hint:='Load layout from layout.xml';
|
||||||
|
|
||||||
|
DockMaster.MakeDockSite(Self,[akBottom]);
|
||||||
DockMaster.OnCreateControl:=@DockMasterCreateControl;
|
DockMaster.OnCreateControl:=@DockMasterCreateControl;
|
||||||
|
|
||||||
SetBounds(100,50,600,80);
|
SetBounds(100,50,600,80);
|
||||||
|
Loading…
Reference in New Issue
Block a user