mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-18 11:39:09 +02:00
fixed fpc 2.1.1 compilation, docking: implemented shrinking to get space for docked control
git-svn-id: trunk@9718 -
This commit is contained in:
parent
be5b78fb47
commit
ac5ae3b17e
@ -192,7 +192,6 @@ type
|
|||||||
procedure DoEnableChange; virtual;
|
procedure DoEnableChange; virtual;
|
||||||
procedure DoHit(const ACount: Integer; var AContinue: Boolean); virtual;
|
procedure DoHit(const ACount: Integer; var AContinue: Boolean); virtual;
|
||||||
procedure SetHitCount(const AValue: Integer);
|
procedure SetHitCount(const AValue: Integer);
|
||||||
procedure SetLocation(const ASource: String; const ALine: Integer); virtual;
|
|
||||||
procedure SetValid(const AValue: TValidState);
|
procedure SetValid(const AValue: TValidState);
|
||||||
|
|
||||||
protected
|
protected
|
||||||
@ -210,6 +209,7 @@ type
|
|||||||
procedure SetInitialEnabled(const AValue: Boolean); virtual;
|
procedure SetInitialEnabled(const AValue: Boolean); virtual;
|
||||||
public
|
public
|
||||||
constructor Create(ACollection: TCollection); override;
|
constructor Create(ACollection: TCollection); override;
|
||||||
|
procedure SetLocation(const ASource: String; const ALine: Integer); virtual;// PublicProtectedFix ide/debugmanager.pas(867,32) Error: identifier idents no member "SetLocation"
|
||||||
property Enabled: Boolean read GetEnabled write SetEnabled;
|
property Enabled: Boolean read GetEnabled write SetEnabled;
|
||||||
property Expression: String read GetExpression write SetExpression;
|
property Expression: String read GetExpression write SetExpression;
|
||||||
property HitCount: Integer read GetHitCount;
|
property HitCount: Integer read GetHitCount;
|
||||||
|
@ -94,6 +94,7 @@ begin
|
|||||||
DockingManager.WriteDebugReport;
|
DockingManager.WriteDebugReport;
|
||||||
|
|
||||||
Form2:=CreateNewForm;
|
Form2:=CreateNewForm;
|
||||||
|
DebugLn(['TMainForm.FormCreate =============================================================']);
|
||||||
Form3:=CreateNewForm;
|
Form3:=CreateNewForm;
|
||||||
|
|
||||||
if not UseConfig then begin
|
if not UseConfig then begin
|
||||||
|
@ -85,7 +85,7 @@ uses
|
|||||||
// help manager
|
// help manager
|
||||||
IDEContextHelpEdit, HelpManager,
|
IDEContextHelpEdit, HelpManager,
|
||||||
// designer
|
// designer
|
||||||
ComponentPalette, ComponentReg, ObjInspExt,
|
JITForm, ComponentPalette, ComponentReg, ObjInspExt,
|
||||||
Designer, FormEditor, CustomFormEditor,
|
Designer, FormEditor, CustomFormEditor,
|
||||||
ControlSelection, AnchorEditor,
|
ControlSelection, AnchorEditor,
|
||||||
{$DEFINE UseNewMenuEditor}
|
{$DEFINE UseNewMenuEditor}
|
||||||
@ -2153,8 +2153,7 @@ end;
|
|||||||
|
|
||||||
Procedure TMainIDE.SetDesigning(AComponent: TComponent; Value: Boolean);
|
Procedure TMainIDE.SetDesigning(AComponent: TComponent; Value: Boolean);
|
||||||
Begin
|
Begin
|
||||||
AComponent.SetDesigning(Value);
|
SetComponentDesignMode(AComponent,Value);
|
||||||
//TODO: Remove widgetset from this code
|
|
||||||
if Value then WidgetSet.SetDesigning(AComponent);
|
if Value then WidgetSet.SetDesigning(AComponent);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -1499,7 +1499,7 @@ end;
|
|||||||
|
|
||||||
function TPointerToPointerTree.FindNode(const Key: Pointer): TAvgLvlTreeNode;
|
function TPointerToPointerTree.FindNode(const Key: Pointer): TAvgLvlTreeNode;
|
||||||
begin
|
begin
|
||||||
Result:=FItems.FindKey(@Key,@ComparePointerWithPtrToPtrItem)
|
Result:=FItems.FindKey(Key,@ComparePointerWithPtrToPtrItem)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TPointerToPointerTree.GetNode(Node: TAvgLvlTreeNode; out Key,
|
function TPointerToPointerTree.GetNode(Node: TAvgLvlTreeNode; out Key,
|
||||||
|
@ -1123,6 +1123,7 @@ type
|
|||||||
procedure AnchorToCompanion(Side: TAnchorKind; Space: integer;
|
procedure AnchorToCompanion(Side: TAnchorKind; Space: integer;
|
||||||
Sibling: TControl;
|
Sibling: TControl;
|
||||||
FreeCompositeSide: boolean = true);
|
FreeCompositeSide: boolean = true);
|
||||||
|
procedure AnchorSame(Side: TAnchorKind; Sibling: TControl);
|
||||||
function AnchoredControlCount: integer;
|
function AnchoredControlCount: integer;
|
||||||
property AnchoredControls[Index: integer]: TControl read GetAnchoredControls;
|
property AnchoredControls[Index: integer]: TControl read GetAnchoredControls;
|
||||||
procedure SetBounds(aLeft, aTop, aWidth, aHeight: integer); virtual;
|
procedure SetBounds(aLeft, aTop, aWidth, aHeight: integer); virtual;
|
||||||
|
@ -3690,6 +3690,15 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TControl.AnchorSame(Side: TAnchorKind; Sibling: TControl);
|
||||||
|
begin
|
||||||
|
if Side in Sibling.Anchors then
|
||||||
|
Anchors:=Anchors+[Side]
|
||||||
|
else
|
||||||
|
Anchors:=Anchors-[Side];
|
||||||
|
AnchorSide[Side].Assign(Sibling.AnchorSide[Side]);
|
||||||
|
end;
|
||||||
|
|
||||||
function TControl.AnchoredControlCount: integer;
|
function TControl.AnchoredControlCount: integer;
|
||||||
begin
|
begin
|
||||||
if fAnchoredControls=nil then
|
if fAnchoredControls=nil then
|
||||||
|
@ -27,8 +27,8 @@
|
|||||||
|
|
||||||
{ $DEFINE CHECK_POSITION}
|
{ $DEFINE CHECK_POSITION}
|
||||||
{$IFDEF CHECK_POSITION}
|
{$IFDEF CHECK_POSITION}
|
||||||
const CheckPostionClassName = 'TButton';
|
const CheckPostionClassName = 'TButtonX';
|
||||||
const CheckPostionName = 'WhereRadioGroup';
|
const CheckPostionName = 'MainForm';
|
||||||
|
|
||||||
function CheckPosition(AControl: TControl): boolean;
|
function CheckPosition(AControl: TControl): boolean;
|
||||||
begin
|
begin
|
||||||
@ -1316,7 +1316,7 @@ var
|
|||||||
{$IFDEF CHECK_POSITION}
|
{$IFDEF CHECK_POSITION}
|
||||||
//if csDesigning in ComponentState then
|
//if csDesigning in ComponentState then
|
||||||
if CheckPosition(Control) then
|
if CheckPosition(Control) then
|
||||||
with Control do
|
with Control do begin
|
||||||
DebugLn('[TWinControl.AlignControls.DoPosition] After Anchoring',
|
DebugLn('[TWinControl.AlignControls.DoPosition] After Anchoring',
|
||||||
' ',Name,':',ClassName,
|
' ',Name,':',ClassName,
|
||||||
' Align=',AlignNames[AAlign],
|
' Align=',AlignNames[AAlign],
|
||||||
@ -1324,6 +1324,8 @@ var
|
|||||||
' Old=',DbgS(Left,Top,Width,Height),
|
' Old=',DbgS(Left,Top,Width,Height),
|
||||||
' New=',DbgS(NewLeft,NewTop,NewWidth,NewHeight),
|
' New=',DbgS(NewLeft,NewTop,NewWidth,NewHeight),
|
||||||
'');
|
'');
|
||||||
|
DebugLn(['DoPosition akRight=',akRight in CurAnchors,' ',GetAnchorSidePosition(akRight,NewRight)]);
|
||||||
|
end;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1648,14 +1650,14 @@ begin
|
|||||||
RemainingBorderSpace:=Rect(0,0,0,0);
|
RemainingBorderSpace:=Rect(0,0,0,0);
|
||||||
// adjust RemainingClientRect by ChildSizing properties
|
// adjust RemainingClientRect by ChildSizing properties
|
||||||
AdjustBorderSpace(RemainingClientRect,RemainingBorderSpace,
|
AdjustBorderSpace(RemainingClientRect,RemainingBorderSpace,
|
||||||
ChildSizing.LeftRightSpacing,ChildSizing.TopBottomSpacing,
|
ChildSizing.LeftRightSpacing,ChildSizing.TopBottomSpacing,
|
||||||
ChildSizing.LeftRightSpacing,ChildSizing.TopBottomSpacing);
|
ChildSizing.LeftRightSpacing,ChildSizing.TopBottomSpacing);
|
||||||
//DebugLn('[TWinControl.AlignControls] ',Name,':',Classname,' ',Left,',',Top,',',Width,',',Height,' ClientRect=',RemainingClientRect.Left,',',RemainingClientRect.Top,',',RemainingClientRect.Right,',',RemainingClientRect.Bottom);
|
//DebugLn('[TWinControl.AlignControls] ',Name,':',Classname,' ',Left,',',Top,',',Width,',',Height,' ClientRect=',RemainingClientRect.Left,',',RemainingClientRect.Top,',',RemainingClientRect.Right,',',RemainingClientRect.Bottom);
|
||||||
AlignList := TFPList.Create;
|
AlignList := TFPList.Create;
|
||||||
try
|
try
|
||||||
// Auto aligning/anchoring can be very interdependent.
|
// Auto aligning/anchoring can be very interdependent.
|
||||||
// In worst case the n-2 depends on the n-1, the n-3 depends on n-2
|
// In worst case the n-2 depends on the n-1, the n-3 depends on n-2
|
||||||
// and so forth. This is allowed, so do up to n steps.
|
// and so forth. This is allowed, so do up to n loop step.
|
||||||
// Do not more, to avoid endless loops, if there are circle
|
// Do not more, to avoid endless loops, if there are circle
|
||||||
// dependencies.
|
// dependencies.
|
||||||
for i:=0 to ControlCount-1 do begin
|
for i:=0 to ControlCount-1 do begin
|
||||||
|
@ -750,7 +750,7 @@ var
|
|||||||
begin
|
begin
|
||||||
i:=Count;
|
i:=Count;
|
||||||
while NextDownIndex(i) do
|
while NextDownIndex(i) do
|
||||||
TNotifyEvent(Items[i])(Self);
|
TNotifyEvent(Items[i])(Sender);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
|
@ -37,8 +37,8 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, Math, SysUtils, TypInfo, LCLProc, Controls, Forms, Menus,
|
Classes, Math, SysUtils, TypInfo, LCLProc, Controls, Forms, Menus,
|
||||||
LCLStrConsts, AvgLvlTree, StringHashList, LazConfigStorage, LDockCtrlEdit,
|
LCLStrConsts, AvgLvlTree, StringHashList, ExtCtrls, LazConfigStorage,
|
||||||
LDockTree;
|
LDockCtrlEdit, LDockTree;
|
||||||
|
|
||||||
type
|
type
|
||||||
TNonDockConfigNames = (
|
TNonDockConfigNames = (
|
||||||
@ -226,6 +226,8 @@ type
|
|||||||
Side: TAnchorKind): boolean;
|
Side: TAnchorKind): boolean;
|
||||||
procedure FixControlBounds(Layout: TLazDockConfigNode;
|
procedure FixControlBounds(Layout: TLazDockConfigNode;
|
||||||
AddedControl: TControl);
|
AddedControl: TControl);
|
||||||
|
procedure ShrinkNeighbourhood(Layout: TLazDockConfigNode;
|
||||||
|
AControl: TControl);
|
||||||
public
|
public
|
||||||
constructor Create(TheOwner: TComponent); override;
|
constructor Create(TheOwner: TComponent); override;
|
||||||
procedure ShowDockingEditor; virtual;
|
procedure ShowDockingEditor; virtual;
|
||||||
@ -439,7 +441,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;
|
//DumpStack;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCustomLazControlDocker.CreateFormAndDockWithSplitter(
|
function TCustomLazControlDocker.CreateFormAndDockWithSplitter(
|
||||||
@ -460,54 +462,98 @@ var
|
|||||||
SplitterNode: TLazDockConfigNode;
|
SplitterNode: TLazDockConfigNode;
|
||||||
NeighbourNode: TLazDockConfigNode;
|
NeighbourNode: TLazDockConfigNode;
|
||||||
NeighbourControl: TControl;
|
NeighbourControl: TControl;
|
||||||
NewParent: TLazDockForm;
|
NewParent: TWinControl;
|
||||||
Splitter: TLazDockSplitter;
|
Splitter: TLazDockSplitter;
|
||||||
a: TAnchorKind;
|
a: TAnchorKind;
|
||||||
|
NewParentCreated: Boolean;
|
||||||
|
SplitterSize: LongInt;
|
||||||
begin
|
begin
|
||||||
Result:=false;
|
Result:=false;
|
||||||
|
DebugLn(['TCustomLazControlDocker.CreateFormAndDockWithSplitter DockerName="',DockerName,'"']);
|
||||||
SelfNode:=Layout.FindByName(DockerName,true);
|
SelfNode:=Layout.FindByName(DockerName,true);
|
||||||
SplitterNode:=Layout.FindByName(SelfNode.Sides[Side]);
|
SplitterNode:=Layout.FindByName(SelfNode.Sides[Side]);
|
||||||
NeighbourNode:=Layout.FindByName(SplitterNode.Sides[Side]);
|
NeighbourNode:=SplitterNode.FindNeighbour(OppositeAnchor[Side],true);
|
||||||
NeighbourControl:=Manager.FindControlByDockerName(NeighbourNode.Name);
|
NeighbourControl:=Manager.FindControlByDockerName(NeighbourNode.Name);
|
||||||
|
|
||||||
if NeighbourControl.Parent=nil then begin
|
if NeighbourControl.Parent=nil then begin
|
||||||
// create a new TLazDockForm and put both controls into it
|
// NeighbourControl is a standalone control (e.g. an undocked form)
|
||||||
|
// => create a new TLazDockForm and put both controls into it
|
||||||
NewParent:=TLazDockForm.Create(nil);
|
NewParent:=TLazDockForm.Create(nil);
|
||||||
NewParent.DisableAlign;
|
NewParentCreated:=true;
|
||||||
try
|
end else begin
|
||||||
// move Control and Neighbour to the new parent
|
// NeighbourControl is docked
|
||||||
|
NewParent:=NeighbourControl.Parent;
|
||||||
|
NewParentCreated:=false;
|
||||||
|
end;
|
||||||
|
|
||||||
|
NewParent.DisableAlign;
|
||||||
|
try
|
||||||
|
// create a splitter
|
||||||
|
Splitter:=TLazDockSplitter.Create(nil);
|
||||||
|
Splitter.Align:=alNone;
|
||||||
|
Splitter.Beveled:=true;
|
||||||
|
Splitter.ResizeAnchor:=Side;
|
||||||
|
Splitter.Parent:=NewParent;
|
||||||
|
if Side in [akLeft,akRight] then
|
||||||
|
SplitterSize:=Manager.Manager.GetSplitterWidth(Splitter)
|
||||||
|
else
|
||||||
|
SplitterSize:=Manager.Manager.GetSplitterHeight(Splitter);
|
||||||
|
if Side in [akLeft,akRight] then
|
||||||
|
Splitter.Width:=SplitterSize
|
||||||
|
else
|
||||||
|
Splitter.Height:=SplitterSize;
|
||||||
|
DebugLn(['TCustomLazControlDocker.CreateFormAndDockWithSplitter Splitter=',DbgSName(Splitter),' ',dbgs(Splitter.BoundsRect)]);
|
||||||
|
|
||||||
|
if NewParentCreated then begin
|
||||||
|
// resize NewParent to bounds of NeighbourControl
|
||||||
|
NewParent.BoundsRect:=NeighbourControl.BoundsRect;
|
||||||
NeighbourControl.Parent:=NewParent;
|
NeighbourControl.Parent:=NewParent;
|
||||||
Control.Parent:=NewParent;
|
end;
|
||||||
|
DebugLn(['TCustomLazControlDocker.CreateFormAndDockWithSplitter NewParent=',DbgSName(NewParent),' ',dbgs(NewParent.BoundsRect)]);
|
||||||
|
DebugLn(['TCustomLazControlDocker.CreateFormAndDockWithSplitter NeighbourControl=',DbgSName(NeighbourControl),' ',dbgs(NeighbourControl.BoundsRect)]);
|
||||||
|
|
||||||
// create a splitter
|
// move Control to the new parent
|
||||||
Splitter:=TLazDockSplitter.Create(nil);
|
Control.Parent:=NewParent;
|
||||||
Splitter.Align:=alNone;
|
Control.BoundsRect:=SelfNode.Bounds;
|
||||||
Splitter.Beveled:=true;
|
DebugLn(['TCustomLazControlDocker.CreateFormAndDockWithSplitter Control=',DbgSName(Control),' ',dbgs(Control.BoundsRect)]);
|
||||||
Splitter.ResizeAnchor:=Side;
|
|
||||||
Splitter.Parent:=NewParent;
|
|
||||||
|
|
||||||
|
if NewParentCreated then begin
|
||||||
for a:=Low(TAnchorKind) to High(TAnchorKind) do begin
|
for a:=Low(TAnchorKind) to High(TAnchorKind) do begin
|
||||||
// anchor Neighbour
|
|
||||||
if a=OppositeAnchor[Side] then
|
|
||||||
NeighbourControl.AnchorParallel(a,0,Splitter)
|
|
||||||
else
|
|
||||||
NeighbourControl.AnchorParallel(a,0,NewParent);
|
|
||||||
// anchor Control
|
// anchor Control
|
||||||
if a=Side then
|
if a=Side then
|
||||||
Control.AnchorParallel(a,0,Splitter)
|
Control.AnchorToNeighbour(a,0,Splitter)
|
||||||
else
|
else
|
||||||
Control.AnchorParallel(a,0,NewParent);
|
Control.AnchorParallel(a,0,NewParent);
|
||||||
// anchor Splitter
|
// anchor Splitter
|
||||||
if (Side in [akLeft,akRight]) <> (a in [akLeft,akRight]) then
|
if (Side in [akLeft,akRight]) <> (a in [akLeft,akRight]) then
|
||||||
Splitter.AnchorParallel(a,0,NewParent);
|
Splitter.AnchorParallel(a,0,NewParent);
|
||||||
|
// anchor Neighbour
|
||||||
|
if a=OppositeAnchor[Side] then
|
||||||
|
NeighbourControl.AnchorToNeighbour(a,0,Splitter)
|
||||||
|
else
|
||||||
|
NeighbourControl.AnchorParallel(a,0,NewParent);
|
||||||
end;
|
end;
|
||||||
|
end else begin
|
||||||
FixControlBounds(Layout,Control);
|
for a:=Low(TAnchorKind) to High(TAnchorKind) do begin
|
||||||
|
// anchor Control
|
||||||
finally
|
if a=Side then
|
||||||
NewParent.EnableAlign;
|
Control.AnchorToNeighbour(a,0,Splitter)
|
||||||
|
else
|
||||||
|
Control.AnchorSame(a,NeighbourControl);
|
||||||
|
// anchor Splitter
|
||||||
|
if (Side in [akLeft,akRight]) <> (a in [akLeft,akRight]) then
|
||||||
|
Splitter.AnchorSame(a,NeighbourControl);
|
||||||
|
end;
|
||||||
|
// anchor Neighbour
|
||||||
|
NeighbourControl.AnchorToNeighbour(OppositeAnchor[Side],0,Splitter);
|
||||||
end;
|
end;
|
||||||
end else begin
|
|
||||||
|
|
||||||
|
ShrinkNeighbourhood(Layout,Control);
|
||||||
|
FixControlBounds(Layout,Control);
|
||||||
|
|
||||||
|
finally
|
||||||
|
NewParent.EnableAlign;
|
||||||
|
NewParent.Visible:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Result:=true;
|
Result:=true;
|
||||||
@ -568,6 +614,8 @@ var
|
|||||||
Result^.Node:=
|
Result^.Node:=
|
||||||
Layout.FindByName(Manager.GetControlConfigName(AControl),true);
|
Layout.FindByName(Manager.GetControlConfigName(AControl),true);
|
||||||
ControlToInfo[AControl]:=Result;
|
ControlToInfo[AControl]:=Result;
|
||||||
|
if ControlToInfo[AControl]<>Result then
|
||||||
|
RaiseGDBException('');
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -579,6 +627,7 @@ var
|
|||||||
begin
|
begin
|
||||||
if Neighbour=nil then exit;
|
if Neighbour=nil then exit;
|
||||||
if Neighbour.Parent<>AControl.Parent then exit;
|
if Neighbour.Parent<>AControl.Parent then exit;
|
||||||
|
//DebugLn(['Left Improve AControl=',DbgSName(AControl),' Neighbour=',DbgSName(Neighbour)]);
|
||||||
Info^.MinLeft:=Max(Info^.MinLeft,
|
Info^.MinLeft:=Max(Info^.MinLeft,
|
||||||
CalculateMinimumLeft(Neighbour)+Neighbour.Width);
|
CalculateMinimumLeft(Neighbour)+Neighbour.Width);
|
||||||
end;
|
end;
|
||||||
@ -589,8 +638,9 @@ var
|
|||||||
begin
|
begin
|
||||||
Info:=GetInfo(AControl);
|
Info:=GetInfo(AControl);
|
||||||
if not Info^.MinLeftValid then begin
|
if not Info^.MinLeftValid then begin
|
||||||
|
//DebugLn(['CalculateMinimumLeft ',DbgSName(AControl)]);
|
||||||
if Info^.MinLeftCalculating then
|
if Info^.MinLeftCalculating then
|
||||||
raise Exception.Create('anchor circle');
|
raise Exception.Create('anchor circle (left)');
|
||||||
Info^.MinLeftCalculating:=true;
|
Info^.MinLeftCalculating:=true;
|
||||||
|
|
||||||
Info^.MinLeft:=0;
|
Info^.MinLeft:=0;
|
||||||
@ -599,14 +649,16 @@ var
|
|||||||
if AControl.Parent<>nil then begin
|
if AControl.Parent<>nil then begin
|
||||||
for i:=0 to AControl.Parent.ControlCount-1 do begin
|
for i:=0 to AControl.Parent.ControlCount-1 do begin
|
||||||
Sibling:=AControl.Parent.Controls[i];
|
Sibling:=AControl.Parent.Controls[i];
|
||||||
|
if Sibling=AControl then continue;
|
||||||
if (akRight in Sibling.Anchors)
|
if (akRight in Sibling.Anchors)
|
||||||
and (Sibling.AnchorSide[akRight].Control=AControl) then
|
and (Sibling.AnchorSide[akRight].Control=AControl) then
|
||||||
Improve(Sibling.AnchorSide[akRight].Control);
|
Improve(Sibling);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Info^.MinLeftCalculating:=true;
|
Info^.MinLeftCalculating:=false;
|
||||||
Info^.MinLeftValid:=true;
|
Info^.MinLeftValid:=true;
|
||||||
|
//DebugLn(['CalculateMinimumLeft END ',DbgSName(AControl),' ',GetInfo(AControl)^.MinLeftValid]);
|
||||||
end;
|
end;
|
||||||
Result:=Info^.MinLeft;
|
Result:=Info^.MinLeft;
|
||||||
end;
|
end;
|
||||||
@ -630,7 +682,7 @@ var
|
|||||||
Info:=GetInfo(AControl);
|
Info:=GetInfo(AControl);
|
||||||
if not Info^.MinTopValid then begin
|
if not Info^.MinTopValid then begin
|
||||||
if Info^.MinTopCalculating then
|
if Info^.MinTopCalculating then
|
||||||
raise Exception.Create('anchor circle');
|
raise Exception.Create('anchor circle (top)');
|
||||||
Info^.MinTopCalculating:=true;
|
Info^.MinTopCalculating:=true;
|
||||||
|
|
||||||
Info^.MinTop:=0;
|
Info^.MinTop:=0;
|
||||||
@ -639,13 +691,14 @@ var
|
|||||||
if AControl.Parent<>nil then begin
|
if AControl.Parent<>nil then begin
|
||||||
for i:=0 to AControl.Parent.ControlCount-1 do begin
|
for i:=0 to AControl.Parent.ControlCount-1 do begin
|
||||||
Sibling:=AControl.Parent.Controls[i];
|
Sibling:=AControl.Parent.Controls[i];
|
||||||
|
if Sibling=AControl then continue;
|
||||||
if (akBottom in Sibling.Anchors)
|
if (akBottom in Sibling.Anchors)
|
||||||
and (Sibling.AnchorSide[akBottom].Control=AControl) then
|
and (Sibling.AnchorSide[akBottom].Control=AControl) then
|
||||||
Improve(Sibling.AnchorSide[akBottom].Control);
|
Improve(Sibling);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Info^.MinTopCalculating:=true;
|
Info^.MinTopCalculating:=false;
|
||||||
Info^.MinTopValid:=true;
|
Info^.MinTopValid:=true;
|
||||||
end;
|
end;
|
||||||
Result:=Info^.MinTop;
|
Result:=Info^.MinTop;
|
||||||
@ -653,50 +706,53 @@ var
|
|||||||
|
|
||||||
function CalculateClientSize(AControl: TControl): TPoint;
|
function CalculateClientSize(AControl: TControl): TPoint;
|
||||||
var
|
var
|
||||||
Info: PControlInfo;
|
|
||||||
AWinControl: TWinControl;
|
AWinControl: TWinControl;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
ChildControl: TControl;
|
ChildControl: TControl;
|
||||||
begin
|
begin
|
||||||
Info:=GetInfo(AControl);
|
Result:=Point(0,0);
|
||||||
if not Info^.MinClientSizeValid then begin
|
if AControl is TWinControl then begin
|
||||||
Info^.MinClientSizeValid:=true;
|
AWinControl:=TWinControl(AControl);
|
||||||
Info^.MinClientSize:=Point(0,0);
|
for i:=0 to AWinControl.ControlCount-1 do begin
|
||||||
if AControl is TWinControl then begin
|
ChildControl:=AWinControl.Controls[i];
|
||||||
AWinControl:=TWinControl(AControl);
|
Result.X:=Max(Result.X,CalculateMinimumLeft(ChildControl)
|
||||||
for i:=0 to AWinControl.ControlCount-1 do begin
|
+ChildControl.Width);
|
||||||
ChildControl:=AWinControl.Controls[i];
|
Result.Y:=Max(Result.Y,CalculateMinimumTop(ChildControl)
|
||||||
Info^.MinClientSize.X:=Max(Info^.MinClientSize.X,
|
+ChildControl.Height);
|
||||||
CalculateMinimumLeft(ChildControl));
|
|
||||||
Info^.MinClientSize.Y:=Max(Info^.MinClientSize.Y,
|
|
||||||
CalculateMinimumTop(ChildControl));
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
Result:=Info^.MinClientSize;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure ApplyBounds;
|
procedure ApplyBounds(ParentClientWidth, ParentClientHeight: Integer);
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
Sibling: TControl;
|
Sibling: TControl;
|
||||||
Info: PControlInfo;
|
Info: PControlInfo;
|
||||||
NewRect: TRect;
|
NewRect: TRect;
|
||||||
OldRect: TRect;
|
OldRect: TRect;
|
||||||
|
SideControl: TControl;
|
||||||
begin
|
begin
|
||||||
for i:=0 to AddedControl.Parent.ControlCount-1 do begin
|
for i:=0 to AddedControl.Parent.ControlCount-1 do begin
|
||||||
Sibling:=AddedControl.Parent.Controls[i];
|
Sibling:=AddedControl.Parent.Controls[i];
|
||||||
Info:=GetInfo(Sibling);
|
Info:=GetInfo(Sibling);
|
||||||
NewRect.Left:=Info^.MinLeft;
|
NewRect.Left:=Info^.MinLeft;
|
||||||
NewRect.Right:=NewRect.Left+Sibling.Width;
|
NewRect.Right:=NewRect.Left+Sibling.Width;
|
||||||
if (akRight in Sibling.Anchors)
|
SideControl:=Sibling.AnchorSide[akRight].Control;
|
||||||
and (Sibling.AnchorSide[akRight].Control<>nil) then
|
if (akRight in Sibling.Anchors) and (SideControl<>nil) then begin
|
||||||
NewRect.Right:=CalculateMinimumLeft(Sibling.AnchorSide[akRight].Control);
|
if SideControl=AddedControl.Parent then
|
||||||
|
NewRect.Right:=ParentClientWidth
|
||||||
|
else if SideControl.Parent=AddedControl.Parent then
|
||||||
|
NewRect.Right:=CalculateMinimumLeft(SideControl);
|
||||||
|
end;
|
||||||
NewRect.Top:=Info^.MinTop;
|
NewRect.Top:=Info^.MinTop;
|
||||||
NewRect.Bottom:=NewRect.Top+Sibling.Height;
|
NewRect.Bottom:=NewRect.Top+Sibling.Height;
|
||||||
if (akBottom in Sibling.Anchors)
|
SideControl:=Sibling.AnchorSide[akBottom].Control;
|
||||||
and (Sibling.AnchorSide[akBottom].Control<>nil) then
|
if (akBottom in Sibling.Anchors) and (SideControl<>nil) then begin
|
||||||
NewRect.Bottom:=CalculateMinimumTop(Sibling.AnchorSide[akBottom].Control);
|
if SideControl=AddedControl.Parent then
|
||||||
|
NewRect.Bottom:=ParentClientHeight
|
||||||
|
else if SideControl.Parent=AddedControl.Parent then
|
||||||
|
NewRect.Bottom:=CalculateMinimumTop(SideControl);
|
||||||
|
end;
|
||||||
OldRect:=Sibling.BoundsRect;
|
OldRect:=Sibling.BoundsRect;
|
||||||
if not CompareRect(@OldRect,@NewRect) then begin
|
if not CompareRect(@OldRect,@NewRect) then begin
|
||||||
DebugLn(['ApplyBounds Sibling=',DbgSName(Sibling),' NewRect=',dbgs(NewRect)]);
|
DebugLn(['ApplyBounds Sibling=',DbgSName(Sibling),' NewRect=',dbgs(NewRect)]);
|
||||||
@ -713,6 +769,10 @@ var
|
|||||||
begin
|
begin
|
||||||
DebugLn(['TCustomLazControlDocker.FixControlBounds ',DbgSName(AddedControl)]);
|
DebugLn(['TCustomLazControlDocker.FixControlBounds ',DbgSName(AddedControl)]);
|
||||||
CurParent:=AddedControl.Parent;
|
CurParent:=AddedControl.Parent;
|
||||||
|
if CurParent=nil then begin
|
||||||
|
DebugLn(['TCustomLazControlDocker.FixControlBounds WARNING: no parent']);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
CurParent.DisableAlign;
|
CurParent.DisableAlign;
|
||||||
try
|
try
|
||||||
InitInfos;
|
InitInfos;
|
||||||
@ -722,7 +782,9 @@ begin
|
|||||||
DiffHeight:=ParentSize.Y-CurParent.ClientHeight;
|
DiffHeight:=ParentSize.Y-CurParent.ClientHeight;
|
||||||
if (DiffWidth<>0) or (DiffHeight<>0) then begin
|
if (DiffWidth<>0) or (DiffHeight<>0) then begin
|
||||||
// parent needs resizing
|
// parent needs resizing
|
||||||
CurParent.Parent.DisableAlign;
|
DebugLn(['TCustomLazControlDocker.FixControlBounds Parent=',DbgSName(AddedControl.Parent),' needs resizing to ',dbgs(ParentSize)]);
|
||||||
|
if CurParent.Parent<>nil then
|
||||||
|
CurParent.Parent.DisableAlign;
|
||||||
try
|
try
|
||||||
CurParent.ClientWidth:=ParentSize.X;
|
CurParent.ClientWidth:=ParentSize.X;
|
||||||
CurParent.ClientHeight:=ParentSize.Y;
|
CurParent.ClientHeight:=ParentSize.Y;
|
||||||
@ -737,16 +799,112 @@ begin
|
|||||||
DebugLn(['TCustomLazControlDocker.FixControlBounds TODO move parent ',DbgSName(CurParent)]);
|
DebugLn(['TCustomLazControlDocker.FixControlBounds TODO move parent ',DbgSName(CurParent)]);
|
||||||
end;
|
end;
|
||||||
finally
|
finally
|
||||||
CurParent.Parent.EnableAlign;
|
if CurParent.Parent<>nil then
|
||||||
|
CurParent.Parent.EnableAlign;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
ApplyBounds;
|
ApplyBounds(ParentSize.X,ParentSize.Y);
|
||||||
finally
|
finally
|
||||||
FreeInfos;
|
FreeInfos;
|
||||||
CurParent.EnableAlign;
|
CurParent.EnableAlign;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCustomLazControlDocker.ShrinkNeighbourhood(
|
||||||
|
Layout: TLazDockConfigNode; AControl: TControl);
|
||||||
|
{ shrink neighbour controls according to Layout
|
||||||
|
A neighbour is the first control left or top of AControl, that can be shrinked
|
||||||
|
and is only anchored to AControl.
|
||||||
|
}
|
||||||
|
function CountAnchoredControls(CurControl: TControl; Side: TAnchorKind
|
||||||
|
): Integer;
|
||||||
|
{ return the number of siblings, that are anchored on Side of CurControl
|
||||||
|
For example: if Side=akLeft it will return the number of controls, which
|
||||||
|
right side is anchored to the left of CurControl }
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
Neighbour: TControl;
|
||||||
|
begin
|
||||||
|
Result:=0;
|
||||||
|
for i:=0 to CurControl.Parent.ControlCount-1 do begin
|
||||||
|
Neighbour:=CurControl.Parent.Controls[i];
|
||||||
|
if Neighbour=CurControl then continue;
|
||||||
|
if (OppositeAnchor[Side] in Neighbour.Anchors)
|
||||||
|
and (Neighbour.AnchorSide[OppositeAnchor[Side]].Control=CurControl) then
|
||||||
|
inc(Result);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure ShrinkControl(CurControl: TControl; Side: TAnchorKind); forward;
|
||||||
|
|
||||||
|
procedure ShrinkNeighboursOnSide(CurControl: TControl; Side: TAnchorKind);
|
||||||
|
// shrink all controls, that are anchored on Side of CurControl
|
||||||
|
var
|
||||||
|
Neighbour: TControl;
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
DebugLn(['ShrinkNeighboursOnSide START ',DbgSName(CurControl),' ',AnchorNames[Side]]);
|
||||||
|
if Side in CurControl.Anchors then begin
|
||||||
|
Neighbour:=CurControl.AnchorSide[Side].Control;
|
||||||
|
DebugLn(['ShrinkNeighboursOnSide Neighbour=',DbgSName(Neighbour)]);
|
||||||
|
ShrinkControl(Neighbour,Side);
|
||||||
|
end;
|
||||||
|
for i:=0 to CurControl.Parent.ControlCount-1 do begin
|
||||||
|
Neighbour:=CurControl.Parent.Controls[i];
|
||||||
|
if (OppositeAnchor[Side] in Neighbour.Anchors)
|
||||||
|
and (Neighbour.AnchorSide[OppositeAnchor[Side]].Control=CurControl)
|
||||||
|
then
|
||||||
|
ShrinkControl(Neighbour,Side);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure ShrinkControl(CurControl: TControl; Side: TAnchorKind);
|
||||||
|
var
|
||||||
|
NodeName: String;
|
||||||
|
Node: TLazDockConfigNode;
|
||||||
|
CurBounds: TRect;
|
||||||
|
begin
|
||||||
|
DebugLn(['ShrinkControl START ',DbgSName(CurControl),' Side=',AnchorNames[Side]]);
|
||||||
|
if (CurControl=nil) or (CurControl=AControl)
|
||||||
|
or (CurControl.Parent<>AControl.Parent) then
|
||||||
|
exit;
|
||||||
|
if CountAnchoredControls(CurControl,OppositeAnchor[Side])>1 then begin
|
||||||
|
// CurControl is not only anchored at AControl
|
||||||
|
// do not shrink it
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
if CurControl is TCustomSplitter then begin
|
||||||
|
// a splitter can not be shrinked
|
||||||
|
// => try to shrink the controls on the other side of the splitter
|
||||||
|
ShrinkNeighboursOnSide(CurControl,Side);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
// shrink accoring to Layout
|
||||||
|
NodeName:=Manager.GetControlConfigName(CurControl);
|
||||||
|
if NodeName='' then exit;
|
||||||
|
Node:=Layout.FindByName(NodeName,true);
|
||||||
|
if Node=nil then exit;
|
||||||
|
CurBounds:=Node.Bounds;
|
||||||
|
DebugLn(['ShrinkControl ',DbgSName(CurControl),' Side=',AnchorNames[Side],' LayoutBounds=',dbgs(CurBounds)]);
|
||||||
|
if Side in [akLeft,akRight] then
|
||||||
|
CurControl.Width:=Min(CurControl.Width,CurBounds.Right-CurBounds.Left)
|
||||||
|
else
|
||||||
|
CurControl.Height:=Min(CurControl.Height,CurBounds.Bottom-CurBounds.Top);
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
a: TAnchorKind;
|
||||||
|
begin
|
||||||
|
DebugLn(['TCustomLazControlDocker.ShrinkNeighbourhood AControl=',DbgSName(AControl)]);
|
||||||
|
AControl.Parent.DisableAlign;
|
||||||
|
try
|
||||||
|
for a:=Low(TAnchorKind) to High(TAnchorKind) do
|
||||||
|
ShrinkNeighboursOnSide(AControl,a);
|
||||||
|
finally
|
||||||
|
AControl.Parent.EnableAlign;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function TCustomLazControlDocker.GetControlName(AControl: TControl): string;
|
function TCustomLazControlDocker.GetControlName(AControl: TControl): string;
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
@ -1101,39 +1259,6 @@ var
|
|||||||
Result:=Manager.FindControlByDockerName(ADockerName);
|
Result:=Manager.FindControlByDockerName(ADockerName);
|
||||||
end;
|
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).
|
|
||||||
}
|
|
||||||
var
|
|
||||||
SplitterNode: TLazDockConfigNode;
|
|
||||||
NeighbourNode: TLazDockConfigNode;
|
|
||||||
NeighbourControl: TControl;
|
|
||||||
begin
|
|
||||||
// TODO
|
|
||||||
SplitterNode:=FindNode(SelfNode.Sides[Side]);
|
|
||||||
NeighbourNode:=SplitterNode.FindNeighbour(OppositeAnchor[Side],true);
|
|
||||||
NeighbourControl:=FindControl(NeighbourNode.Name);
|
|
||||||
if NeighbourControl=nil then RaiseGDBException('inconsistency');
|
|
||||||
if NeighbourNode.Parent=nil then begin
|
|
||||||
// Neighbour is a standalone control
|
|
||||||
// => combine Neighbour and Self onto a dummy form
|
|
||||||
Result:=CreateFormAndDockWithSplitter(Layout,Side);
|
|
||||||
exit;
|
|
||||||
end else begin
|
|
||||||
|
|
||||||
end;
|
|
||||||
Result:=false;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function DockWithSpiralSpltter: boolean;
|
function DockWithSpiralSpltter: boolean;
|
||||||
begin
|
begin
|
||||||
// TODO
|
// TODO
|
||||||
@ -1153,7 +1278,7 @@ var
|
|||||||
and (SideNode.TheType in [ldcntSplitterLeftRight,ldcntSplitterUpDown])
|
and (SideNode.TheType in [ldcntSplitterLeftRight,ldcntSplitterUpDown])
|
||||||
then begin
|
then begin
|
||||||
if SideNode.IsTheOnlyNeighbour(SelfNode,a)
|
if SideNode.IsTheOnlyNeighbour(SelfNode,a)
|
||||||
and DockWithOwnSplitter(a) then
|
and CreateFormAndDockWithSplitter(Layout,a) then
|
||||||
exit(true);
|
exit(true);
|
||||||
inc(SplitterCount);
|
inc(SplitterCount);
|
||||||
if (SplitterCount=4) and DockWithSpiralSpltter then
|
if (SplitterCount=4) and DockWithSpiralSpltter then
|
||||||
@ -1493,6 +1618,7 @@ function TCustomLazDockingManager.CreateLayout(const DockerName: string;
|
|||||||
// create a usable config
|
// create a usable config
|
||||||
// This means: search a config, create a copy
|
// This means: search a config, create a copy
|
||||||
// and remove all nodes without visible controls.
|
// and remove all nodes without visible controls.
|
||||||
|
{$DEFINE VerboseAnchorDockCreateLayout}
|
||||||
var
|
var
|
||||||
Root: TLazDockConfigNode;
|
Root: TLazDockConfigNode;
|
||||||
CurDockControl: TControl;
|
CurDockControl: TControl;
|
||||||
@ -1683,7 +1809,7 @@ var
|
|||||||
a: TAnchorKind;
|
a: TAnchorKind;
|
||||||
OldFormNode: TLazDockConfigNode;
|
OldFormNode: TLazDockConfigNode;
|
||||||
begin
|
begin
|
||||||
DebugLn(['SimplifyOneChildForm ',dbgs(FormNode)]);
|
//DebugLn(['SimplifyOneChildForm ',dbgs(FormNode)]);
|
||||||
if FormNode<>Root then RaiseGDBException('');
|
if FormNode<>Root then RaiseGDBException('');
|
||||||
if FormNode.ChildCount<>1 then RaiseGDBException('');
|
if FormNode.ChildCount<>1 then RaiseGDBException('');
|
||||||
FormBounds:=FormNode.Bounds;
|
FormBounds:=FormNode.Bounds;
|
||||||
@ -1716,7 +1842,9 @@ var
|
|||||||
Child: TLazDockConfigNode;
|
Child: TLazDockConfigNode;
|
||||||
begin
|
begin
|
||||||
if Node=nil then exit;
|
if Node=nil then exit;
|
||||||
|
{$IFDEF VerboseAnchorDockCreateLayout}
|
||||||
DebugLn(['RemoveEmptyNodes ',Node.Name,' Node.ChildCount=',Node.ChildCount]);
|
DebugLn(['RemoveEmptyNodes ',Node.Name,' Node.ChildCount=',Node.ChildCount]);
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
// remove unneeded childs
|
// remove unneeded childs
|
||||||
i:=Node.ChildCount-1;
|
i:=Node.ChildCount-1;
|
||||||
@ -1734,25 +1862,33 @@ var
|
|||||||
// 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) then begin
|
if (Docker=nil) then begin
|
||||||
|
{$IFDEF VerboseAnchorDockCreateLayout}
|
||||||
DebugLn(['RemoveEmptyNodes delete unknown node: ',dbgs(Node)]);
|
DebugLn(['RemoveEmptyNodes delete unknown node: ',dbgs(Node)]);
|
||||||
|
{$ENDIF}
|
||||||
DeleteNode(Node);
|
DeleteNode(Node);
|
||||||
end
|
end
|
||||||
else if not ControlIsVisible(Docker.Control) then begin
|
else if not ControlIsVisible(Docker.Control) then begin
|
||||||
|
{$IFDEF VerboseAnchorDockCreateLayout}
|
||||||
DebugLn(['RemoveEmptyNodes delete invisible node: ',dbgs(Node)]);
|
DebugLn(['RemoveEmptyNodes delete invisible node: ',dbgs(Node)]);
|
||||||
|
{$ENDIF}
|
||||||
DeleteNode(Node);
|
DeleteNode(Node);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
ldcntPage:
|
ldcntPage:
|
||||||
// these are auto created parent node. 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
|
||||||
|
{$IFDEF VerboseAnchorDockCreateLayout}
|
||||||
DebugLn(['RemoveEmptyNodes delete node without childs: ',dbgs(Node)]);
|
DebugLn(['RemoveEmptyNodes delete node without childs: ',dbgs(Node)]);
|
||||||
|
{$ENDIF}
|
||||||
DeleteNode(Node);
|
DeleteNode(Node);
|
||||||
end;
|
end;
|
||||||
ldcntForm:
|
ldcntForm:
|
||||||
// these are auto created parent node. If they have 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 they have only one child: delete node and move childs up
|
||||||
if Node.ChildCount=0 then begin
|
if Node.ChildCount=0 then begin
|
||||||
|
{$IFDEF VerboseAnchorDockCreateLayout}
|
||||||
DebugLn(['RemoveEmptyNodes delete node without childs: ',dbgs(Node)]);
|
DebugLn(['RemoveEmptyNodes delete node without childs: ',dbgs(Node)]);
|
||||||
|
{$ENDIF}
|
||||||
DeleteNode(Node);
|
DeleteNode(Node);
|
||||||
end else if Node.ChildCount=1 then begin
|
end else if Node.ChildCount=1 then begin
|
||||||
// Only one child left
|
// Only one child left
|
||||||
@ -1762,7 +1898,9 @@ var
|
|||||||
// these are auto created parent node. If they have 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 child up
|
// if they have only one child: delete node and move child up
|
||||||
if Node.ChildCount=0 then begin
|
if Node.ChildCount=0 then begin
|
||||||
|
{$IFDEF VerboseAnchorDockCreateLayout}
|
||||||
DebugLn(['RemoveEmptyNodes delete node without childs: ',dbgs(Node)]);
|
DebugLn(['RemoveEmptyNodes delete node without childs: ',dbgs(Node)]);
|
||||||
|
{$ENDIF}
|
||||||
DeleteNode(Node);
|
DeleteNode(Node);
|
||||||
end else if Node.ChildCount=1 then begin
|
end else if Node.ChildCount=1 then begin
|
||||||
// Only one child left
|
// Only one child left
|
||||||
@ -1920,15 +2058,23 @@ begin
|
|||||||
Root:=nil;
|
Root:=nil;
|
||||||
|
|
||||||
Config:=GetConfigWithDockerName(DockerName);
|
Config:=GetConfigWithDockerName(DockerName);
|
||||||
|
|
||||||
DebugLn(['TCustomLazDockingManager.CreateLayout DockerName="',DockerName,'"']);
|
DebugLn(['TCustomLazDockingManager.CreateLayout DockerName="',DockerName,'"']);
|
||||||
config.WriteDebugReport;
|
config.WriteDebugReport;
|
||||||
if (Config=nil) or (Config.Root=nil) then exit;
|
|
||||||
|
if (Config=nil) or (Config.Root=nil) then begin
|
||||||
|
DebugLn(['TCustomLazDockingManager.CreateLayout DockerName="',DockerName,'" No control']);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
CurControl:=FindControlByDockerName(DockerName);
|
CurControl:=FindControlByDockerName(DockerName);
|
||||||
DebugLn(['TCustomLazDockingManager.CreateLayout CurControl=',DbgSName(CurControl)]);
|
if not ControlIsVisible(CurControl) then begin
|
||||||
if not ControlIsVisible(CurControl) then exit;
|
DebugLn(['TCustomLazDockingManager.CreateLayout DockerName="',DockerName,'" CurControl=',DbgSName(CurControl),' control not visible']);
|
||||||
DebugLn(['TCustomLazDockingManager.CreateLayout CurControl is treated as visible']);
|
exit;
|
||||||
if (not ConfigIsCompatible(Config.Root,ExceptionOnError)) then exit;
|
end;
|
||||||
DebugLn(['TCustomLazDockingManager.CreateLayout Config is compatible']);
|
if (not ConfigIsCompatible(Config.Root,ExceptionOnError)) then begin
|
||||||
|
DebugLn(['TCustomLazDockingManager.CreateLayout DockerName="',DockerName,'" CurControl=',DbgSName(CurControl),' config is not compatible']);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
// create a copy of the config
|
// create a copy of the config
|
||||||
Root:=TLazDockConfigNode.Create(nil);
|
Root:=TLazDockConfigNode.Create(nil);
|
||||||
@ -1937,12 +2083,10 @@ 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']);
|
DebugLn(['TCustomLazDockingManager.CreateLayout Not all Controls are on the same Form. Using only one 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;
|
||||||
@ -1952,10 +2096,12 @@ begin
|
|||||||
CurDockControl:=CurDockControl.GetTopParent;
|
CurDockControl:=CurDockControl.GetTopParent;
|
||||||
// remove nodes of other dock forms
|
// remove nodes of other dock forms
|
||||||
RemoveEmptyNodes(Root);
|
RemoveEmptyNodes(Root);
|
||||||
DebugLn(['TCustomLazDockingManager.CreateLayout After removing nodes of other dock forms:']);
|
//DebugLn(['TCustomLazDockingManager.CreateLayout After removing nodes of other dock forms:']);
|
||||||
Root.WriteDebugReport;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
DebugLn(['TCustomLazDockingManager.CreateLayout After removing unneeded nodes:']);
|
||||||
|
Root.WriteDebugReport;
|
||||||
|
|
||||||
Result:=Root;
|
Result:=Root;
|
||||||
Root:=nil;
|
Root:=nil;
|
||||||
finally
|
finally
|
||||||
|
@ -97,6 +97,8 @@ begin
|
|||||||
DockGroupBox.Caption:='Dock to control';
|
DockGroupBox.Caption:='Dock to control';
|
||||||
DockControlLabel.Caption:='To control';
|
DockControlLabel.Caption:='To control';
|
||||||
|
|
||||||
|
CancelButton.Caption:='Cancel';
|
||||||
|
|
||||||
UpdateButtonEnabled;
|
UpdateButtonEnabled;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user