mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-11-26 10:47:31 +01:00
fixed compilation under fpc 2.1.1
git-svn-id: trunk@9694 -
This commit is contained in:
parent
85de8ce1f8
commit
43b02b83ea
@ -92,8 +92,6 @@ begin
|
|||||||
ControlDocker1.Manager:=DockingManager;
|
ControlDocker1.Manager:=DockingManager;
|
||||||
|
|
||||||
DockingManager.WriteDebugReport;
|
DockingManager.WriteDebugReport;
|
||||||
DockingManager.CreateLayout(ControlDocker1.DockerName,Self,true);
|
|
||||||
Halt;
|
|
||||||
|
|
||||||
Form2:=CreateNewForm;
|
Form2:=CreateNewForm;
|
||||||
Form3:=CreateNewForm;
|
Form3:=CreateNewForm;
|
||||||
@ -104,9 +102,8 @@ begin
|
|||||||
DockingManager.Manager.InsertControl(Form3,alBottom,Self);
|
DockingManager.Manager.InsertControl(Form3,alBottom,Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
DockingManager.WriteDebugReport;
|
//DockingManager.WriteDebugReport;
|
||||||
|
//ControlDocker1.GetLayoutFromControl;
|
||||||
ControlDocker1.GetLayoutFromControl;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMainForm.FormDestroy(Sender: TObject);
|
procedure TMainForm.FormDestroy(Sender: TObject);
|
||||||
|
|||||||
@ -20,11 +20,10 @@ unit newfield;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, DBConst, LCLIntf, Graphics, Controls, Forms, Dialogs,
|
Classes, Math, SysUtils, DBConst, LCLIntf, Graphics, Controls, Forms, Dialogs,
|
||||||
ExtCtrls, StdCtrls, Buttons, DB, LResources, ComponentEditors,
|
ExtCtrls, StdCtrls, Buttons, DB, LResources, ComponentEditors,
|
||||||
PropEdits, TypInfo;
|
PropEdits, TypInfo;
|
||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
{ TNewFieldFrm }
|
{ TNewFieldFrm }
|
||||||
|
|||||||
@ -416,11 +416,12 @@ begin
|
|||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
DebugLn(['TCustomLazControlDocker.ControlVisibleChanging Sender=',DbgSName(Sender)]);
|
DebugLn(['TCustomLazControlDocker.ControlVisibleChanging Sender=',DbgSName(Sender)]);
|
||||||
|
DumpStack;
|
||||||
if Control.Visible then begin
|
if Control.Visible then begin
|
||||||
// control will be hidden -> the layout will change
|
// control will be hidden -> the layout will change
|
||||||
// save the layout for later restore
|
// save the layout for later restore
|
||||||
SaveLayout;
|
SaveLayout;
|
||||||
end else begin
|
end else if ([csDestroying,csDesigning,csLoading]*ComponentState=[]) then begin
|
||||||
// the control will become visible -> dock it to restore the last layout
|
// the control will become visible -> dock it to restore the last layout
|
||||||
RestoreLayout;
|
RestoreLayout;
|
||||||
end;
|
end;
|
||||||
@ -429,6 +430,7 @@ end;
|
|||||||
procedure TCustomLazControlDocker.ControlVisibleChanged(Sender: TObject);
|
procedure TCustomLazControlDocker.ControlVisibleChanged(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
DebugLn(['TCustomLazControlDocker.ControlVisibleChanged Sender=',DbgSName(Sender)]);
|
DebugLn(['TCustomLazControlDocker.ControlVisibleChanged Sender=',DbgSName(Sender)]);
|
||||||
|
DumpStack;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCustomLazControlDocker.GetControlName(AControl: TControl): string;
|
function TCustomLazControlDocker.GetControlName(AControl: TControl): string;
|
||||||
@ -768,60 +770,95 @@ procedure TCustomLazControlDocker.RestoreLayout;
|
|||||||
|+---+#+-----------------+|
|
|+---+#+-----------------+|
|
||||||
+-------------------------+
|
+-------------------------+
|
||||||
}
|
}
|
||||||
type
|
|
||||||
TSiblingDistance = (
|
|
||||||
sdUnknown,
|
|
||||||
sdThreeSides, // sibling shares 3 sides
|
|
||||||
sdOneSide, // sibling shares 1 side
|
|
||||||
sdSplitterThreeSides,// splitter, then sibling shares 3 sides
|
|
||||||
sdSplitterOneSide // splitter, then sibling shares 1 side
|
|
||||||
);
|
|
||||||
var
|
var
|
||||||
Layout: TLazDockerConfig;
|
Layout: TLazDockConfigNode;
|
||||||
SelfNode: TLazDockConfigNode;
|
SelfNode: TLazDockConfigNode;
|
||||||
|
|
||||||
procedure RaiseLayoutInconsistency(Node: TLazDockConfigNode);
|
function FindNode(const ANodeName: string): TLazDockConfigNode;
|
||||||
begin
|
begin
|
||||||
raise Exception.Create('TCustomLazControlDocker.RestoreLayout'
|
if ANodeName='' then
|
||||||
+' DockerName="'+DockerName+'"'
|
Result:=nil
|
||||||
+' Control='+DbgSName(Control)
|
|
||||||
+' Node='+Node.Name);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure FindSibling(Node: TLazDockConfigNode; Side: TAnchorKind;
|
|
||||||
out Sibling: TControl; out SiblingNode: TLazDockConfigNode;
|
|
||||||
out Distance: TSiblingDistance);
|
|
||||||
// find the nearest visible sibling control at Side
|
|
||||||
var
|
|
||||||
SiblingName: string;
|
|
||||||
begin
|
|
||||||
Sibling:=nil;
|
|
||||||
SiblingNode:=nil;
|
|
||||||
Distance:=sdUnknown;
|
|
||||||
if Node=nil then exit;
|
|
||||||
SiblingName:=Node.Sides[Side];
|
|
||||||
if SiblingName<>'' then begin
|
|
||||||
SiblingNode:=Layout.Root.FindByName(SiblingName,true);
|
|
||||||
if SiblingNode=nil then
|
|
||||||
RaiseLayoutInconsistency(Node);
|
|
||||||
case SiblingNode.TheType of
|
|
||||||
ldcntSplitterLeftRight,ldcntSplitterUpDown:
|
|
||||||
begin
|
|
||||||
FindSibling(SiblingNode,Side,Sibling,SiblingNode,Distance);
|
|
||||||
if Distance=sdOneSide then
|
|
||||||
Distance:=sdSplitterOneSide;
|
|
||||||
if Distance=sdThreeSides then
|
|
||||||
Distance:=sdSplitterThreeSides;
|
|
||||||
if Distance=sdSplitterThreeSides then begin
|
|
||||||
|
|
||||||
end;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
else
|
else
|
||||||
exit;
|
Result:=Layout.FindByName(ANodeName,true,true);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function FindNodeUsingSplitter(Splitter: TLazDockConfigNode;
|
||||||
|
SiblingSide: TAnchorKind; NilIfAmbiguous: boolean): TLazDockConfigNode;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
ParentNode: TLazDockConfigNode;
|
||||||
|
Child: TLazDockConfigNode;
|
||||||
|
begin
|
||||||
|
Result:=nil;
|
||||||
|
ParentNode:=Splitter.Parent;
|
||||||
|
for i:=0 to ParentNode.ChildCount-1 do begin
|
||||||
|
Child:=ParentNode.Childs[i];
|
||||||
|
if CompareText(Child.Sides[SiblingSide],Splitter.Name)=0 then begin
|
||||||
|
if Result=nil then
|
||||||
|
Result:=Child
|
||||||
|
else if NilIfAmbiguous then
|
||||||
|
exit(nil);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function SplitterIsOnlyUsedByNodeAtSide(Splitter, Node: TLazDockConfigNode;
|
||||||
|
SiblingSide: TAnchorKind): boolean;
|
||||||
|
{ check if one side of the Splitter is only used by Node.
|
||||||
|
For example: If only Node.Sides[SiblingSide]=Splitter.Name
|
||||||
|
---------+
|
||||||
|
--+#+---+|
|
||||||
|
B |#| A ||
|
||||||
|
--+#+---+|
|
||||||
|
---------+}
|
||||||
|
begin
|
||||||
|
Result:=FindNodeUsingSplitter(Splitter,SiblingSide,true)<>nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function DockWithOwnSplitter(Side: TAnchorKind): boolean;
|
||||||
|
{ Add a splitter to Side and dock to it. For example:
|
||||||
|
--------+ -----------+
|
||||||
|
---+| ----+#+---+|
|
||||||
|
B | -> B |#| A ||
|
||||||
|
---+| ----+#+---+|
|
||||||
|
--------+ -----------+
|
||||||
|
If B has no parent, a TLazDockForm is created.
|
||||||
|
|
||||||
|
To get space for A, either B is shrinked and/or the parent of B is enlarged
|
||||||
|
(including the grand parents of B).
|
||||||
|
}
|
||||||
|
begin
|
||||||
// TODO
|
// TODO
|
||||||
|
Result:=false;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function DockWithSpiralSpltter: boolean;
|
||||||
|
begin
|
||||||
|
// TODO
|
||||||
|
Result:=false;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function SplitterDocking: boolean;
|
||||||
|
var
|
||||||
|
a: TAnchorKind;
|
||||||
|
SplitterCount: Integer;
|
||||||
|
SideNode: TLazDockConfigNode;
|
||||||
|
begin
|
||||||
|
SplitterCount:=0;
|
||||||
|
for a:=Low(TAnchorKind) to High(TAnchorKind) do begin
|
||||||
|
SideNode:=FindNode(SelfNode.Sides[a]);
|
||||||
|
if (SideNode<>nil)
|
||||||
|
and (SideNode.TheType in [ldcntSplitterLeftRight,ldcntSplitterUpDown])
|
||||||
|
then begin
|
||||||
|
if SplitterIsOnlyUsedByNodeAtSide(SideNode,SelfNode,a)
|
||||||
|
and DockWithOwnSplitter(a) then
|
||||||
|
exit(true);
|
||||||
|
inc(SplitterCount);
|
||||||
|
if (SplitterCount=4) and DockWithSpiralSpltter then
|
||||||
|
exit(true);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
Result:=false;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
@ -829,10 +866,11 @@ var
|
|||||||
begin
|
begin
|
||||||
DebugLn(['TCustomLazControlDocker.RestoreLayout A ',DockerName,' Control=',DbgSName(Control)]);
|
DebugLn(['TCustomLazControlDocker.RestoreLayout A ',DockerName,' Control=',DbgSName(Control)]);
|
||||||
if (Manager=nil) or (Control=nil) then exit;
|
if (Manager=nil) or (Control=nil) then exit;
|
||||||
Layout:=Manager.GetConfigWithDockerName(DockerName);
|
Layout:=Manager.CreateLayout(DockerName,Control,false);
|
||||||
if (Layout=nil) or (Layout.Root=nil) then exit;
|
if (Layout=nil) then exit;
|
||||||
SelfNode:=Layout.Root.FindByName(DockerName,true);
|
try
|
||||||
DebugLn(['TCustomLazControlDocker.RestoreLayout ',SelfNode<>nil,' DockerName=',DockerName,' ',Manager.Configs[0].DockerName]);
|
SelfNode:=Layout.FindByName(DockerName,true);
|
||||||
|
DebugLn(['TCustomLazControlDocker.RestoreLayout ',SelfNode<>nil,' DockerName=',DockerName]);
|
||||||
if (SelfNode=nil) or (SelfNode.TheType<>ldcntControl) then exit;
|
if (SelfNode=nil) or (SelfNode.TheType<>ldcntControl) then exit;
|
||||||
|
|
||||||
if SelfNode.Parent<>nil then begin
|
if SelfNode.Parent<>nil then begin
|
||||||
@ -846,8 +884,8 @@ begin
|
|||||||
ldcntControl,ldcntForm:
|
ldcntControl,ldcntForm:
|
||||||
begin
|
begin
|
||||||
// this control was docked on a form as child
|
// this control was docked on a form as child
|
||||||
DebugLn(['TCustomLazControlDocker.RestoreLayout TODO restore splitter']);
|
DebugLn(['TCustomLazControlDocker.RestoreLayout restore splitter']);
|
||||||
//FindSibling(SelfNode,akLeft,LeftSibling,LeftSiblingDistance);
|
if SplitterDocking then exit;
|
||||||
end;
|
end;
|
||||||
else
|
else
|
||||||
exit;
|
exit;
|
||||||
@ -860,6 +898,9 @@ begin
|
|||||||
Control.SetBoundsKeepBase(NewBounds.Left,NewBounds.Top,
|
Control.SetBoundsKeepBase(NewBounds.Left,NewBounds.Top,
|
||||||
NewBounds.Right-NewBounds.Left,
|
NewBounds.Right-NewBounds.Left,
|
||||||
NewBounds.Bottom-NewBounds.Top);
|
NewBounds.Bottom-NewBounds.Top);
|
||||||
|
finally
|
||||||
|
Layout.Free;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TCustomLazControlDocker.Create(TheOwner: TComponent);
|
constructor TCustomLazControlDocker.Create(TheOwner: TComponent);
|
||||||
@ -1076,18 +1117,18 @@ var
|
|||||||
begin
|
begin
|
||||||
// merge the configs
|
// merge the configs
|
||||||
NewConfigCount:=Config.GetValue(Path+'Configs/Count',0);
|
NewConfigCount:=Config.GetValue(Path+'Configs/Count',0);
|
||||||
DebugLn(['TCustomLazDockingManager.LoadFromConfig NewConfigCount=',NewConfigCount]);
|
//DebugLn(['TCustomLazDockingManager.LoadFromConfig NewConfigCount=',NewConfigCount]);
|
||||||
for i:=0 to NewConfigCount-1 do begin
|
for i:=0 to NewConfigCount-1 do begin
|
||||||
SubPath:=Path+'Config'+IntToStr(i)+'/';
|
SubPath:=Path+'Config'+IntToStr(i)+'/';
|
||||||
NewDockerName:=Config.GetValue(SubPath+'DockerName/Value','');
|
NewDockerName:=Config.GetValue(SubPath+'DockerName/Value','');
|
||||||
if NewDockerName='' then continue;
|
if NewDockerName='' then continue;
|
||||||
NewRootName:=Config.GetValue(SubPath+'Name/Value','');
|
NewRootName:=Config.GetValue(SubPath+'Name/Value','');
|
||||||
if NewRootName='' then continue;
|
if NewRootName='' then continue;
|
||||||
DebugLn(['TCustomLazDockingManager.LoadFromConfig NewDockerName=',NewDockerName,' NewRootName=',NewRootName]);
|
//DebugLn(['TCustomLazDockingManager.LoadFromConfig NewDockerName=',NewDockerName,' NewRootName=',NewRootName]);
|
||||||
NewRoot:=TLazDockConfigNode.Create(nil,NewRootName);
|
NewRoot:=TLazDockConfigNode.Create(nil,NewRootName);
|
||||||
NewRoot.LoadFromConfig(Config,SubPath);
|
NewRoot.LoadFromConfig(Config,SubPath);
|
||||||
AddOrReplaceConfig(NewDockerName,NewRoot);
|
AddOrReplaceConfig(NewDockerName,NewRoot);
|
||||||
NewRoot.WriteDebugReport;
|
//NewRoot.WriteDebugReport;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1196,18 +1237,18 @@ var
|
|||||||
SiblingSide: TAnchorKind): boolean;
|
SiblingSide: TAnchorKind): boolean;
|
||||||
{ check if one side of the Splitter is only used by Node.
|
{ check if one side of the Splitter is only used by Node.
|
||||||
For example: If only Node.Sides[SiblingSide]=Splitter.Name
|
For example: If only Node.Sides[SiblingSide]=Splitter.Name
|
||||||
---------+ --------+
|
---------+
|
||||||
--+#+---+| ---+|
|
--+#+---+|
|
||||||
B |#| A || -> B ||
|
B |#| A ||
|
||||||
--+#+---+| ---+|
|
--+#+---+|
|
||||||
---------+ --------+}
|
---------+}
|
||||||
begin
|
begin
|
||||||
Result:=FindNodeUsingSplitter(Splitter,SiblingSide,true)<>nil;
|
Result:=FindNodeUsingSplitter(Splitter,SiblingSide,true)<>nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure DeleteNode(var DeletingNode: TLazDockConfigNode);
|
procedure DeleteNode(var DeletingNode: TLazDockConfigNode);
|
||||||
|
|
||||||
function IsOwnSideSplitter(Side: TAnchorKind;
|
function DeleteOwnSideSplitter(Side: TAnchorKind;
|
||||||
var SplitterNode: TLazDockConfigNode): boolean;
|
var SplitterNode: TLazDockConfigNode): boolean;
|
||||||
{ check if DeletingNode has a splitter to Side, and this node is the only
|
{ check if DeletingNode has a splitter to Side, and this node is the only
|
||||||
node anchored to the splitter at this side.
|
node anchored to the splitter at this side.
|
||||||
@ -1227,8 +1268,8 @@ var
|
|||||||
begin
|
begin
|
||||||
Result:=false;
|
Result:=false;
|
||||||
// check if this is the only node using this Side of the splitter
|
// check if this is the only node using this Side of the splitter
|
||||||
if not SplitterIsOnlyUsedByNodeAtSide(SplitterNode,DeletingNode,
|
if not SplitterIsOnlyUsedByNodeAtSide(SplitterNode,DeletingNode,Side) then
|
||||||
Side) then exit;
|
exit;
|
||||||
|
|
||||||
// All nodes, that uses the splitter from the other side will now be
|
// All nodes, that uses the splitter from the other side will now be
|
||||||
// anchored to the other side of DeletingNode
|
// anchored to the other side of DeletingNode
|
||||||
@ -1289,16 +1330,12 @@ var
|
|||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure RaiseUnknownCase;
|
|
||||||
begin
|
|
||||||
raise Exception.Create('TCustomLazDockingManager.CreateLayout invalid Config');
|
|
||||||
end;
|
|
||||||
|
|
||||||
var
|
var
|
||||||
a: TAnchorKind;
|
a: TAnchorKind;
|
||||||
SiblingNode: TLazDockConfigNode;
|
SiblingNode: TLazDockConfigNode;
|
||||||
SplitterCount: Integer;
|
SplitterCount: Integer;// number of shared splitters
|
||||||
begin
|
begin
|
||||||
|
DebugLn(['DeleteNode ',DeletingNode.Name]);
|
||||||
SplitterCount:=0;
|
SplitterCount:=0;
|
||||||
for a:=Low(TAnchorKind) to High(TAnchorKind) do begin
|
for a:=Low(TAnchorKind) to High(TAnchorKind) do begin
|
||||||
SiblingNode:=FindNode(DeletingNode.Sides[a]);
|
SiblingNode:=FindNode(DeletingNode.Sides[a]);
|
||||||
@ -1306,18 +1343,18 @@ var
|
|||||||
and (SiblingNode.TheType in [ldcntSplitterLeftRight,ldcntSplitterUpDown])
|
and (SiblingNode.TheType in [ldcntSplitterLeftRight,ldcntSplitterUpDown])
|
||||||
then begin
|
then begin
|
||||||
// there is a splitter
|
// there is a splitter
|
||||||
if IsOwnSideSplitter(a,SiblingNode) then break;
|
if DeleteOwnSideSplitter(a,SiblingNode) then begin
|
||||||
inc(SplitterCount);
|
// splitter deleted
|
||||||
end;
|
break;
|
||||||
end;
|
|
||||||
if SplitterCount=0 then begin
|
|
||||||
// no splitter -> simply delete the node
|
|
||||||
end else if SplitterCount=4 then begin
|
|
||||||
// this is a spiral splitter node
|
|
||||||
UnbindSpiralNode;
|
|
||||||
end else begin
|
end else begin
|
||||||
// this should never be reached
|
inc(SplitterCount);// not own => shared
|
||||||
RaiseUnknownCase;
|
if SplitterCount=4 then begin
|
||||||
|
// this is a spiral splitter node -> merge two splitters
|
||||||
|
UnbindSpiralNode;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
FreeAndNil(DeletingNode);
|
FreeAndNil(DeletingNode);
|
||||||
end;
|
end;
|
||||||
@ -1361,6 +1398,44 @@ var
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
FreeAndNil(PagesNode);
|
FreeAndNil(PagesNode);
|
||||||
|
//debugln(Root.DebugLayoutAsString);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure SimplifyOneChildForm(var FormNode: TLazDockConfigNode);
|
||||||
|
{ FormNode has only one child left.
|
||||||
|
Remove Form node and replace root with child
|
||||||
|
}
|
||||||
|
var
|
||||||
|
FormBounds: TRect;
|
||||||
|
OffsetX: LongInt;
|
||||||
|
OffsetY: LongInt;
|
||||||
|
Child: TLazDockConfigNode;
|
||||||
|
ChildBounds: TRect;
|
||||||
|
a: TAnchorKind;
|
||||||
|
OldFormNode: TLazDockConfigNode;
|
||||||
|
begin
|
||||||
|
DebugLn(['SimplifyOneChildForm ',dbgs(FormNode)]);
|
||||||
|
if FormNode<>Root then RaiseGDBException('');
|
||||||
|
if FormNode.ChildCount<>1 then RaiseGDBException('');
|
||||||
|
FormBounds:=FormNode.Bounds;
|
||||||
|
OffsetX:=FormBounds.Left;
|
||||||
|
OffsetY:=FormBounds.Top;
|
||||||
|
Child:=FormNode.Childs[0];
|
||||||
|
// changes parent of child
|
||||||
|
Child.Parent:=FormNode.Parent;
|
||||||
|
// move child to place where FormNode was
|
||||||
|
ChildBounds:=Child.Bounds;
|
||||||
|
OffsetRect(ChildBounds,OffsetX,OffsetY);
|
||||||
|
Child.Bounds:=ChildBounds;
|
||||||
|
// change anchors of child
|
||||||
|
for a:=Low(TAnchorKind) to High(TAnchorKind) do begin
|
||||||
|
if CompareText(Child.Sides[a],FormNode.Name)=0 then
|
||||||
|
Child.Sides[a]:=FormNode.Sides[a];
|
||||||
|
end;
|
||||||
|
OldFormNode:=FormNode;
|
||||||
|
FormNode:=Child;
|
||||||
|
OldFormNode.Free;
|
||||||
|
//Root.WriteDebugReport;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure RemoveEmptyNodes(var Node: TLazDockConfigNode);
|
procedure RemoveEmptyNodes(var Node: TLazDockConfigNode);
|
||||||
@ -1389,24 +1464,39 @@ var
|
|||||||
Docker:=FindDockerByName(Node.Name);
|
Docker:=FindDockerByName(Node.Name);
|
||||||
// if the associated control does not exist or is not visible,
|
// if the associated control does not exist or is not visible,
|
||||||
// then delete the node
|
// then delete the node
|
||||||
if (Docker=nil) or not ControlIsVisible(Docker.Control) then begin
|
if (Docker=nil) then begin
|
||||||
DebugLn(['RemoveEmptyNodes delete unknown or invisible node: ',dbgs(Node)]);
|
DebugLn(['RemoveEmptyNodes delete unknown node: ',dbgs(Node)]);
|
||||||
|
DeleteNode(Node);
|
||||||
|
end
|
||||||
|
else if not ControlIsVisible(Docker.Control) then begin
|
||||||
|
DebugLn(['RemoveEmptyNodes delete invisible node: ',dbgs(Node)]);
|
||||||
DeleteNode(Node);
|
DeleteNode(Node);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
ldcntForm,ldcntPage:
|
ldcntPage:
|
||||||
// these are auto created parent nodes. If they have no childs: delete
|
// these are auto created parent node. If they have no childs: delete
|
||||||
if Node.ChildCount=0 then begin
|
if Node.ChildCount=0 then begin
|
||||||
DebugLn(['RemoveEmptyNodes delete node without childs: ',dbgs(Node)]);
|
DebugLn(['RemoveEmptyNodes delete node without childs: ',dbgs(Node)]);
|
||||||
DeleteNode(Node);
|
DeleteNode(Node);
|
||||||
end;
|
end;
|
||||||
ldcntPages:
|
ldcntForm:
|
||||||
// this is an auto created parent node. If it has no childs: delete
|
// these are auto created parent node. If they have no childs: delete
|
||||||
|
// if they have only one child: delete node and move childs up
|
||||||
if Node.ChildCount=0 then begin
|
if Node.ChildCount=0 then begin
|
||||||
DebugLn(['RemoveEmptyNodes delete node without childs: ',dbgs(Node)]);
|
DebugLn(['RemoveEmptyNodes delete node without childs: ',dbgs(Node)]);
|
||||||
DeleteNode(Node);
|
DeleteNode(Node);
|
||||||
end else if Node.ChildCount=1 then begin
|
end else if Node.ChildCount=1 then begin
|
||||||
// Only one page left
|
// Only one child left
|
||||||
|
SimplifyOneChildForm(Node);
|
||||||
|
end;
|
||||||
|
ldcntPages:
|
||||||
|
// these are auto created parent node. If they have no childs: delete
|
||||||
|
// if they have only one child: delete node and move child up
|
||||||
|
if Node.ChildCount=0 then begin
|
||||||
|
DebugLn(['RemoveEmptyNodes delete node without childs: ',dbgs(Node)]);
|
||||||
|
DeleteNode(Node);
|
||||||
|
end else if Node.ChildCount=1 then begin
|
||||||
|
// Only one child left
|
||||||
SimplifyOnePageNode(Node);
|
SimplifyOnePageNode(Node);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -1426,12 +1516,14 @@ var
|
|||||||
if (CurForm<>nil) then begin
|
if (CurForm<>nil) then begin
|
||||||
while CurForm.Parent<>nil do
|
while CurForm.Parent<>nil do
|
||||||
CurForm:=CurForm.Parent;
|
CurForm:=CurForm.Parent;
|
||||||
|
if CurForm<>VisibleControl then begin
|
||||||
if RootForm=nil then
|
if RootForm=nil then
|
||||||
RootForm:=CurForm
|
RootForm:=CurForm
|
||||||
else if RootForm<>CurForm then
|
else if RootForm<>CurForm then
|
||||||
exit(false);
|
exit(false);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
end;
|
||||||
// check childs
|
// check childs
|
||||||
for i:=0 to Node.ChildCount-1 do
|
for i:=0 to Node.ChildCount-1 do
|
||||||
if not Check(Node.Childs[i]) then exit(false);
|
if not Check(Node.Childs[i]) then exit(false);
|
||||||
@ -1577,20 +1669,23 @@ begin
|
|||||||
|
|
||||||
// clean up by removing all invisible, unknown and empty nodes
|
// clean up by removing all invisible, unknown and empty nodes
|
||||||
RemoveEmptyNodes(Root);
|
RemoveEmptyNodes(Root);
|
||||||
|
DebugLn(['TCustomLazDockingManager.CreateLayout After removing unneeded nodes:']);
|
||||||
|
Root.WriteDebugReport;
|
||||||
|
|
||||||
// check if all used controls are on the same dock form
|
// check if all used controls are on the same dock form
|
||||||
if not AllControlsAreOnSameForm then begin
|
if not AllControlsAreOnSameForm then begin
|
||||||
|
DebugLn(['TCustomLazDockingManager.CreateLayout not all Controls are on the same Form']);
|
||||||
// the used controls are distributed on different dock forms
|
// the used controls are distributed on different dock forms
|
||||||
// => choose one dock form and remove the nodes of the others
|
// => choose one dock form and remove the nodes of the others
|
||||||
NearestControlNode:=FindNearestControlNode;
|
NearestControlNode:=FindNearestControlNode;
|
||||||
if NearestControlNode<>nil then begin
|
if NearestControlNode=nil then RaiseGDBException('');
|
||||||
CurDockControl:=FindControlByDockerName(NearestControlNode.Name);
|
CurDockControl:=FindControlByDockerName(NearestControlNode.Name);
|
||||||
if CurDockControl<>nil then begin
|
if CurDockControl=nil then RaiseGDBException('');
|
||||||
CurDockControl:=CurDockControl.GetTopParent;
|
CurDockControl:=CurDockControl.GetTopParent;
|
||||||
// remove nodes of other dock forms
|
// remove nodes of other dock forms
|
||||||
RemoveEmptyNodes(Root);
|
RemoveEmptyNodes(Root);
|
||||||
end;
|
DebugLn(['TCustomLazDockingManager.CreateLayout After removing nodes of other dock forms:']);
|
||||||
end;
|
Root.WriteDebugReport;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Result:=Root;
|
Result:=Root;
|
||||||
@ -1705,6 +1800,26 @@ function TCustomLazDockingManager.ConfigIsCompatible(
|
|||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function CheckUniqueCorner(Side1, Side2: TAnchorKind): boolean;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
Child: TLazDockConfigNode;
|
||||||
|
begin
|
||||||
|
Result:=true;
|
||||||
|
if Node.Parent=nil then exit;
|
||||||
|
if Node.Sides[Side1]='' then exit;
|
||||||
|
if Node.Sides[Side2]='' then exit;
|
||||||
|
for i:=0 to Node.Parent.ChildCount-1 do begin
|
||||||
|
Child:=Node.Parent.Childs[i];
|
||||||
|
if Child=Node then continue;
|
||||||
|
if (CompareText(Node.Sides[Side1],Child.Sides[Side1])=0)
|
||||||
|
and (CompareText(Node.Sides[Side2],Child.Sides[Side2])=0) then begin
|
||||||
|
Error('overlapping nodes');
|
||||||
|
exit(false);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
a: TAnchorKind;
|
a: TAnchorKind;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
@ -1790,6 +1905,11 @@ function TCustomLazDockingManager.ConfigIsCompatible(
|
|||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if not CheckUniqueCorner(akLeft,akTop) then exit;
|
||||||
|
if not CheckUniqueCorner(akLeft,akBottom) then exit;
|
||||||
|
if not CheckUniqueCorner(akRight,akTop) then exit;
|
||||||
|
if not CheckUniqueCorner(akRight,akBottom) then exit;
|
||||||
|
|
||||||
// check childs
|
// check childs
|
||||||
for i:=0 to Node.ChildCount-1 do
|
for i:=0 to Node.ChildCount-1 do
|
||||||
if not CheckNode(Node.Childs[i]) then exit;
|
if not CheckNode(Node.Childs[i]) then exit;
|
||||||
@ -1928,7 +2048,6 @@ begin
|
|||||||
SrcChild:=Src.Childs[i];
|
SrcChild:=Src.Childs[i];
|
||||||
NewChild:=TLazDockConfigNode.Create(Self);
|
NewChild:=TLazDockConfigNode.Create(Self);
|
||||||
NewChild.Assign(SrcChild);
|
NewChild.Assign(SrcChild);
|
||||||
FChilds.Add(NewChild);
|
|
||||||
end;
|
end;
|
||||||
end else
|
end else
|
||||||
inherited Assign(Source);
|
inherited Assign(Source);
|
||||||
@ -2075,6 +2194,7 @@ begin
|
|||||||
DebugLn('TLazDockConfigNode.WriteDebugReport Root=',dbgs(Self));
|
DebugLn('TLazDockConfigNode.WriteDebugReport Root=',dbgs(Self));
|
||||||
WriteNode(' ',Self);
|
WriteNode(' ',Self);
|
||||||
DebugLn(DebugLayoutAsString);
|
DebugLn(DebugLayoutAsString);
|
||||||
|
DumpStack;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TLazDockConfigNode.DebugLayoutAsString: string;
|
function TLazDockConfigNode.DebugLayoutAsString: string;
|
||||||
@ -2118,17 +2238,17 @@ var
|
|||||||
Result:=PNodeInfo(NodeInfos[Node]);
|
Result:=PNodeInfo(NodeInfos[Node]);
|
||||||
if Result=nil then begin
|
if Result=nil then begin
|
||||||
New(Result);
|
New(Result);
|
||||||
FillChar(Result^,SizeOf(Result),0);
|
FillChar(Result^,SizeOf(TNodeInfo),0);
|
||||||
NodeInfos[Node]:=Result;
|
NodeInfos[Node]:=Result;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure w(x,y: Integer; const s: string; MaxY: Integer = 0);
|
procedure w(x,y: Integer; const s: string; MaxX: Integer = 0);
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
for i:=1 to length(s) do begin
|
for i:=1 to length(s) do begin
|
||||||
if (MaxY>0) and (y>MaxY) then exit;
|
if (MaxX>0) and (x+i>MaxX) then exit;
|
||||||
Result[LogCols*(y-1) + x + i-1]:=s[i];
|
Result[LogCols*(y-1) + x + i-1]:=s[i];
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -2200,6 +2320,7 @@ var
|
|||||||
NeighbourLength: LongInt;
|
NeighbourLength: LongInt;
|
||||||
begin
|
begin
|
||||||
if Neighbour=nil then exit;
|
if Neighbour=nil then exit;
|
||||||
|
if Neighbour.Parent<>Node.Parent then exit;
|
||||||
NeighbourPos:=GetMinPos(Neighbour,Side);
|
NeighbourPos:=GetMinPos(Neighbour,Side);
|
||||||
NeighbourSize:=GetMinSize(Neighbour);
|
NeighbourSize:=GetMinSize(Neighbour);
|
||||||
if Side=akLeft then
|
if Side=akLeft then
|
||||||
@ -2215,6 +2336,7 @@ var
|
|||||||
begin
|
begin
|
||||||
if MinPosCalculating then begin
|
if MinPosCalculating then begin
|
||||||
DebugLn(['DebugLayoutAsString.GetMinPos.Compute WARNING: anchor circle detected']);
|
DebugLn(['DebugLayoutAsString.GetMinPos.Compute WARNING: anchor circle detected']);
|
||||||
|
DumpStack;
|
||||||
exit(1);
|
exit(1);
|
||||||
end;
|
end;
|
||||||
if (not MinPosValid) then begin
|
if (not MinPosValid) then begin
|
||||||
@ -2240,6 +2362,7 @@ var
|
|||||||
Info: PNodeInfo;
|
Info: PNodeInfo;
|
||||||
begin
|
begin
|
||||||
Info:=GetNodeInfo(Node);
|
Info:=GetNodeInfo(Node);
|
||||||
|
//DebugLn(['GetMinPos ',Node.Name,' ',AnchorNames[Side],' ',Info^.MinLeftCalculating]);
|
||||||
if Side=akLeft then
|
if Side=akLeft then
|
||||||
Result:=Compute(Info^.MinLeftValid,Info^.MinLeftCalculating,Info^.MinLeft)
|
Result:=Compute(Info^.MinLeftValid,Info^.MinLeftCalculating,Info^.MinLeft)
|
||||||
else
|
else
|
||||||
@ -2254,6 +2377,7 @@ var
|
|||||||
Child: TLazDockConfigNode;
|
Child: TLazDockConfigNode;
|
||||||
ChildSize: TPoint;
|
ChildSize: TPoint;
|
||||||
begin
|
begin
|
||||||
|
//DebugLn(['GetChildsMinSize ',Node.name]);
|
||||||
Result:=Point(0,0);
|
Result:=Point(0,0);
|
||||||
if Node.TheType=ldcntPages then begin
|
if Node.TheType=ldcntPages then begin
|
||||||
// maximum size of all pages
|
// maximum size of all pages
|
||||||
@ -2278,6 +2402,7 @@ var
|
|||||||
ChildMinSize: TPoint;
|
ChildMinSize: TPoint;
|
||||||
Info: PNodeInfo;
|
Info: PNodeInfo;
|
||||||
begin
|
begin
|
||||||
|
//DebugLn(['GetMinSize ',Node.name]);
|
||||||
Info:=GetNodeInfo(Node);
|
Info:=GetNodeInfo(Node);
|
||||||
if Info^.MinSizeValid then begin
|
if Info^.MinSizeValid then begin
|
||||||
Result:=Info^.MinSize;
|
Result:=Info^.MinSize;
|
||||||
@ -2285,6 +2410,7 @@ var
|
|||||||
end;
|
end;
|
||||||
if Info^.MinSizeCalculating then begin
|
if Info^.MinSizeCalculating then begin
|
||||||
DebugLn(['DebugLayoutAsString.GetMinSize WARNING: anchor circle detected']);
|
DebugLn(['DebugLayoutAsString.GetMinSize WARNING: anchor circle detected']);
|
||||||
|
DumpStack;
|
||||||
Result:=Point(1,1);
|
Result:=Point(1,1);
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
@ -2301,9 +2427,9 @@ var
|
|||||||
Result.X:=Max(Result.X,ChildMinSize.X+2);
|
Result.X:=Max(Result.X,ChildMinSize.X+2);
|
||||||
Result.Y:=Max(Result.Y,ChildMinSize.Y+2);
|
Result.Y:=Max(Result.Y,ChildMinSize.Y+2);
|
||||||
end;
|
end;
|
||||||
Info^.MinSizeCalculating:=false;
|
|
||||||
Info^.MinSize:=Result;
|
Info^.MinSize:=Result;
|
||||||
Info^.MinSizeValid:=true;
|
Info^.MinSizeValid:=true;
|
||||||
|
Info^.MinSizeCalculating:=false;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure DrawNode(Node: TLazDockConfigNode; ARect: TRect);
|
procedure DrawNode(Node: TLazDockConfigNode; ARect: TRect);
|
||||||
@ -2311,20 +2437,23 @@ var
|
|||||||
i: Integer;
|
i: Integer;
|
||||||
Child: TLazDockConfigNode;
|
Child: TLazDockConfigNode;
|
||||||
ChildSize: TPoint;
|
ChildSize: TPoint;
|
||||||
ChildPos: TPoint;
|
|
||||||
ChildRect: TRect;
|
ChildRect: TRect;
|
||||||
begin
|
begin
|
||||||
|
//DebugLn(['DrawNode Node=',Node.Name,' ARect=',dbgs(ARect)]);
|
||||||
wrectangle(ARect);
|
wrectangle(ARect);
|
||||||
w(ARect.Left+1,ARect.Top,Node.Name,ARect.Right);
|
w(ARect.Left+1,ARect.Top,Node.Name,ARect.Right);
|
||||||
|
|
||||||
for i := 0 to Node.ChildCount-1 do begin
|
for i := 0 to Node.ChildCount-1 do begin
|
||||||
Child:=Node.Childs[i];
|
Child:=Node.Childs[i];
|
||||||
|
ChildRect.Left:=ARect.Left+1+GetMinPos(Child,akLeft);
|
||||||
|
ChildRect.Top:=ARect.Top+1+GetMinPos(Child,akTop);
|
||||||
ChildSize:=GetMinSize(Child);
|
ChildSize:=GetMinSize(Child);
|
||||||
ChildPos:=Point(GetMinPos(Child,akLeft),GetMinPos(Child,akTop));
|
|
||||||
ChildRect.Left:=ARect.Left+1+ChildPos.X;
|
|
||||||
ChildRect.Top:=ARect.Top+1+ChildPos.Y;
|
|
||||||
ChildRect.Right:=ChildRect.Left+ChildSize.X-1;
|
ChildRect.Right:=ChildRect.Left+ChildSize.X-1;
|
||||||
ChildRect.Bottom:=ChildRect.Top+ChildSize.Y-1;
|
ChildRect.Bottom:=ChildRect.Top+ChildSize.Y-1;
|
||||||
|
if CompareText(Child.Sides[akRight],Node.Name)=0 then
|
||||||
|
ChildRect.Right:=ARect.Right-1;
|
||||||
|
if CompareText(Child.Sides[akBottom],Node.Name)=0 then
|
||||||
|
ChildRect.Bottom:=ARect.Bottom-1;
|
||||||
DrawNode(Child,ChildRect);
|
DrawNode(Child,ChildRect);
|
||||||
if Node.TheType=ldcntPages then begin
|
if Node.TheType=ldcntPages then begin
|
||||||
// paint only one page
|
// paint only one page
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user