mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-14 10:19:22 +02:00
lcl: Patch for docking: InsertControl (from Hans-Peter Diettrich, mantis #0012909)
git-svn-id: trunk@18094 -
This commit is contained in:
parent
968747c675
commit
c92465fa27
@ -1916,6 +1916,7 @@ type
|
|||||||
function GetNextVisibleZone: TDockZone;
|
function GetNextVisibleZone: TDockZone;
|
||||||
function NextVisible: TDockZone;
|
function NextVisible: TDockZone;
|
||||||
function PrevVisible: TDockZone;
|
function PrevVisible: TDockZone;
|
||||||
|
procedure AddSibling(NewZone: TDockZone; InsertAt: TAlign);
|
||||||
procedure AddAsFirstChild(NewChildZone: TDockZone);
|
procedure AddAsFirstChild(NewChildZone: TDockZone);
|
||||||
procedure AddAsLastChild(NewChildZone: TDockZone);
|
procedure AddAsLastChild(NewChildZone: TDockZone);
|
||||||
procedure ReplaceChild(OldChild, NewChild: TDockZone);
|
procedure ReplaceChild(OldChild, NewChild: TDockZone);
|
||||||
@ -2050,7 +2051,6 @@ type
|
|||||||
procedure DeleteZone(Zone: TDockZone);
|
procedure DeleteZone(Zone: TDockZone);
|
||||||
procedure SetDockSite(const AValue: TWinControl);
|
procedure SetDockSite(const AValue: TWinControl);
|
||||||
protected
|
protected
|
||||||
procedure AdjustDockRect(AControl: TControl; var ARect: TRect); virtual;
|
|
||||||
function HitTest(const MousePos: TPoint; var HTFlag: Integer): TControl; virtual;
|
function HitTest(const MousePos: TPoint; var HTFlag: Integer): TControl; virtual;
|
||||||
procedure PaintDockFrame(ACanvas: TCanvas; AControl: TControl;
|
procedure PaintDockFrame(ACanvas: TCanvas; AControl: TControl;
|
||||||
const ARect: TRect); virtual;
|
const ARect: TRect); virtual;
|
||||||
@ -2061,6 +2061,7 @@ type
|
|||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
procedure BeginUpdate; override;
|
procedure BeginUpdate; override;
|
||||||
procedure EndUpdate; override;
|
procedure EndUpdate; override;
|
||||||
|
procedure AdjustDockRect(AControl: TControl; var ARect: TRect); virtual;
|
||||||
procedure GetControlBounds(AControl: TControl;
|
procedure GetControlBounds(AControl: TControl;
|
||||||
out ControlBounds: TRect); override;
|
out ControlBounds: TRect); override;
|
||||||
procedure InsertControl(AControl: TControl; InsertAt: TAlign;
|
procedure InsertControl(AControl: TControl; InsertAt: TAlign;
|
||||||
|
@ -118,14 +118,19 @@ var
|
|||||||
begin
|
begin
|
||||||
//determine drop zone
|
//determine drop zone
|
||||||
if DropCtl = nil then
|
if DropCtl = nil then
|
||||||
DropZone := RootZone
|
begin
|
||||||
|
DropZone := RootZone;
|
||||||
|
R := DockSite.ClientRect;
|
||||||
|
end
|
||||||
else
|
else
|
||||||
|
begin
|
||||||
DropZone := RootZone.FindZone(DropCtl);
|
DropZone := RootZone.FindZone(DropCtl);
|
||||||
|
if DropZone = nil then
|
||||||
//get the zone extent.
|
DropZone := RootZone;
|
||||||
//r := dzone.FBounds; //todo: doesn't work
|
//get the zone extent.
|
||||||
with DropZone do
|
with DropZone do
|
||||||
R := Rect(Left, Top, Width, Height);
|
R := Rect(Left, Top, Width, Height);
|
||||||
|
end;
|
||||||
|
|
||||||
// if there are no zones then use the whole rect
|
// if there are no zones then use the whole rect
|
||||||
// else split drop zone
|
// else split drop zone
|
||||||
|
@ -290,6 +290,29 @@ begin
|
|||||||
inc(FChildCount);
|
inc(FChildCount);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TDockZone.AddSibling(NewZone: TDockZone; InsertAt: TAlign);
|
||||||
|
var
|
||||||
|
LinkAfter: TDockZone;
|
||||||
|
begin
|
||||||
|
case InsertAt of
|
||||||
|
alLeft, alTop: LinkAfter := FPrevSibling;
|
||||||
|
alRight, alBottom: LinkAfter := Self;
|
||||||
|
else
|
||||||
|
raise Exception.Create('TDockZone.AddSibling: unhandled insertion');
|
||||||
|
end;
|
||||||
|
if LinkAfter = nil then
|
||||||
|
Parent.AddAsFirstChild(NewZone)
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
NewZone.FPrevSibling := LinkAfter;
|
||||||
|
NewZone.FNextSibling := LinkAfter.NextSibling;
|
||||||
|
NewZone.FParentZone := Parent;
|
||||||
|
if LinkAfter.NextSibling <> nil then
|
||||||
|
LinkAfter.NextSibling.FPrevSibling := NewZone;
|
||||||
|
LinkAfter.FNextSibling := NewZone;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TDockZone.ReplaceChild(OldChild, NewChild: TDockZone);
|
procedure TDockZone.ReplaceChild(OldChild, NewChild: TDockZone);
|
||||||
begin
|
begin
|
||||||
NewChild.FParentZone := Self;
|
NewChild.FParentZone := Self;
|
||||||
|
@ -33,7 +33,7 @@ uses
|
|||||||
Math, Types, Classes, SysUtils, LCLProc, LCLType, LCLStrConsts,
|
Math, Types, Classes, SysUtils, LCLProc, LCLType, LCLStrConsts,
|
||||||
Graphics, Controls, ExtCtrls, Forms, Menus, Themes, LCLIntf,
|
Graphics, Controls, ExtCtrls, Forms, Menus, Themes, LCLIntf,
|
||||||
LMessages, LResources, typinfo;
|
LMessages, LResources, typinfo;
|
||||||
|
|
||||||
type
|
type
|
||||||
TLazDockPages = class;
|
TLazDockPages = class;
|
||||||
TLazDockPage = class;
|
TLazDockPage = class;
|
||||||
@ -67,9 +67,9 @@ type
|
|||||||
dhiRestore,
|
dhiRestore,
|
||||||
dhiClose
|
dhiClose
|
||||||
);
|
);
|
||||||
|
|
||||||
TDockHeaderImages = array[TDockHeaderImageKind] of TCustomBitmap;
|
TDockHeaderImages = array[TDockHeaderImageKind] of TCustomBitmap;
|
||||||
|
|
||||||
{ TLazDockTree }
|
{ TLazDockTree }
|
||||||
|
|
||||||
TLazDockTree = class(TDockTree)
|
TLazDockTree = class(TDockTree)
|
||||||
@ -105,7 +105,7 @@ type
|
|||||||
public
|
public
|
||||||
property AutoFreeDockSite: boolean read FAutoFreeDockSite write FAutoFreeDockSite;
|
property AutoFreeDockSite: boolean read FAutoFreeDockSite write FAutoFreeDockSite;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TLazDockHeaderPart =
|
TLazDockHeaderPart =
|
||||||
(
|
(
|
||||||
ldhpAll, // total header rect
|
ldhpAll, // total header rect
|
||||||
@ -122,7 +122,7 @@ type
|
|||||||
TCustomAnchoredDockManager does not use TLazDockZone and allows arbitrary
|
TCustomAnchoredDockManager does not use TLazDockZone and allows arbitrary
|
||||||
layouts.
|
layouts.
|
||||||
}
|
}
|
||||||
|
|
||||||
TLazDockForm = class(TCustomForm)
|
TLazDockForm = class(TCustomForm)
|
||||||
private
|
private
|
||||||
FMainControl: TControl;
|
FMainControl: TControl;
|
||||||
@ -153,8 +153,8 @@ type
|
|||||||
function GetTitleOrientation(Control: TControl): TDockOrientation;
|
function GetTitleOrientation(Control: TControl): TDockOrientation;
|
||||||
property MainControl: TControl read FMainControl write SetMainControl;// used for the default caption
|
property MainControl: TControl read FMainControl write SetMainControl;// used for the default caption
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TLazDockPage
|
{ TLazDockPage
|
||||||
Pretty the same as a TLazDockForm but as page of a TLazDockPages }
|
Pretty the same as a TLazDockForm but as page of a TLazDockPages }
|
||||||
|
|
||||||
@ -186,18 +186,18 @@ type
|
|||||||
write SetActiveNotebookPageComponent;
|
write SetActiveNotebookPageComponent;
|
||||||
property Pages;
|
property Pages;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TLazDockSplitter }
|
{ TLazDockSplitter }
|
||||||
|
|
||||||
TLazDockSplitter = class(TCustomSplitter)
|
TLazDockSplitter = class(TCustomSplitter)
|
||||||
public
|
public
|
||||||
constructor Create(AOwner: TComponent); override;
|
constructor Create(AOwner: TComponent); override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
TCustomAnchoredDockManager = class;
|
TCustomAnchoredDockManager = class;
|
||||||
|
|
||||||
{ TLazDockOwnerComponent
|
{ TLazDockOwnerComponent
|
||||||
A TComponent owning all automatically created controls of a
|
A TComponent owning all automatically created controls of a
|
||||||
TCustomAnchoredDockManager, like TLazDockForm }
|
TCustomAnchoredDockManager, like TLazDockForm }
|
||||||
@ -208,11 +208,11 @@ type
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
{ TCustomAnchoredDockManager
|
{ TCustomAnchoredDockManager
|
||||||
This class implements an LCL TDockManager via anchoring.
|
This class implements an LCL TDockManager via anchoring.
|
||||||
It implements the docking, undocking, enlarging, shrinking.
|
It implements the docking, undocking, enlarging, shrinking.
|
||||||
|
|
||||||
The TCustomLazDockingManager component in LDockCtrl uses this
|
The TCustomLazDockingManager component in LDockCtrl uses this
|
||||||
docking manager and extends it by layouts that can be stored/restored. }
|
docking manager and extends it by layouts that can be stored/restored. }
|
||||||
|
|
||||||
@ -271,8 +271,8 @@ type
|
|||||||
// here.
|
// here.
|
||||||
function CreateForm: TLazDockForm;
|
function CreateForm: TLazDockForm;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
const
|
const
|
||||||
DockAlignOrientations: array[TAlign] of TDockOrientation =
|
DockAlignOrientations: array[TAlign] of TDockOrientation =
|
||||||
(
|
(
|
||||||
@ -322,7 +322,7 @@ type
|
|||||||
TDockHeader = class
|
TDockHeader = class
|
||||||
class procedure CreateDockHeaderImages(out Images: TDockHeaderImages);
|
class procedure CreateDockHeaderImages(out Images: TDockHeaderImages);
|
||||||
class procedure DestroyDockHeaderImages(var Images: TDockHeaderImages);
|
class procedure DestroyDockHeaderImages(var Images: TDockHeaderImages);
|
||||||
|
|
||||||
class function GetRectOfPart(AHeaderRect: TRect; AOrientation: TDockOrientation; APart: TLazDockHeaderPart): TRect;
|
class function GetRectOfPart(AHeaderRect: TRect; AOrientation: TDockOrientation; APart: TLazDockHeaderPart): TRect;
|
||||||
class function FindPart(AHeaderRect: TRect; APoint: TPoint; AOrientation: TDockOrientation): TLazDockHeaderPart;
|
class function FindPart(AHeaderRect: TRect; APoint: TPoint; AOrientation: TDockOrientation): TLazDockHeaderPart;
|
||||||
class procedure Draw(ACanvas: TCanvas; ACaption: String; DockBtnImages: TDockHeaderImages; AOrientation: TDockOrientation; const ARect: TRect; const MousePos: TPoint);
|
class procedure Draw(ACanvas: TCanvas; ACaption: String; DockBtnImages: TDockHeaderImages; AOrientation: TDockOrientation; const ARect: TRect; const MousePos: TPoint);
|
||||||
@ -430,7 +430,7 @@ class procedure TDockHeader.Draw(ACanvas: TCanvas; ACaption: String; DockBtnImag
|
|||||||
dy := (ARect.Bottom - ARect.Top - ABitmap.Height) div 2;
|
dy := (ARect.Bottom - ARect.Top - ABitmap.Height) div 2;
|
||||||
ACanvas.Draw(ARect.Left + dx, ARect.Top + dy, ABitmap);
|
ACanvas.Draw(ARect.Left + dx, ARect.Top + dy, ABitmap);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
BtnRect: TRect;
|
BtnRect: TRect;
|
||||||
DrawRect: TRect;
|
DrawRect: TRect;
|
||||||
@ -445,7 +445,7 @@ begin
|
|||||||
ACanvas.Brush.Color := clBtnShadow;
|
ACanvas.Brush.Color := clBtnShadow;
|
||||||
ACanvas.FrameRect(DrawRect);
|
ACanvas.FrameRect(DrawRect);
|
||||||
InflateRect(DrawRect, -1, -1);
|
InflateRect(DrawRect, -1, -1);
|
||||||
|
|
||||||
IsMouseDown := (GetKeyState(VK_LBUTTON) and $80) <> 0;
|
IsMouseDown := (GetKeyState(VK_LBUTTON) and $80) <> 0;
|
||||||
|
|
||||||
// draw close button
|
// draw close button
|
||||||
@ -459,7 +459,7 @@ begin
|
|||||||
|
|
||||||
// draw caption
|
// draw caption
|
||||||
DrawRect := GetRectOfPart(ARect, AOrientation, ldhpCaption);
|
DrawRect := GetRectOfPart(ARect, AOrientation, ldhpCaption);
|
||||||
|
|
||||||
OldMode := SetBkMode(ACanvas.Handle, TRANSPARENT);
|
OldMode := SetBkMode(ACanvas.Handle, TRANSPARENT);
|
||||||
|
|
||||||
case AOrientation of
|
case AOrientation of
|
||||||
@ -588,11 +588,11 @@ function ControlIsAnchoredIndirectly(StartControl: TControl; Side: TAnchorKind;
|
|||||||
DestControl: TControl): boolean;
|
DestControl: TControl): boolean;
|
||||||
{ true if there is an Anchor way from StartControl to DestControl over Side.
|
{ true if there is an Anchor way from StartControl to DestControl over Side.
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
+-+|+-+
|
+-+|+-+
|
||||||
|A|||B|
|
|A|||B|
|
||||||
+-+|+-+
|
+-+|+-+
|
||||||
|
|
||||||
A is akLeft to B.
|
A is akLeft to B.
|
||||||
B is akRight to A.
|
B is akRight to A.
|
||||||
The splitter is akLeft to B.
|
The splitter is akLeft to B.
|
||||||
@ -602,7 +602,7 @@ function ControlIsAnchoredIndirectly(StartControl: TControl; Side: TAnchorKind;
|
|||||||
var
|
var
|
||||||
Checked: array of Boolean;
|
Checked: array of Boolean;
|
||||||
Parent: TWinControl;
|
Parent: TWinControl;
|
||||||
|
|
||||||
function Check(ControlIndex: integer): boolean;
|
function Check(ControlIndex: integer): boolean;
|
||||||
var
|
var
|
||||||
AControl: TControl;
|
AControl: TControl;
|
||||||
@ -614,7 +614,7 @@ var
|
|||||||
Checked[ControlIndex]:=true;
|
Checked[ControlIndex]:=true;
|
||||||
AControl:=Parent.Controls[ControlIndex];
|
AControl:=Parent.Controls[ControlIndex];
|
||||||
if AControl=DestControl then exit(true);
|
if AControl=DestControl then exit(true);
|
||||||
|
|
||||||
if (Side in AControl.Anchors) then begin
|
if (Side in AControl.Anchors) then begin
|
||||||
SideControl:=AControl.AnchorSide[Side].Control;
|
SideControl:=AControl.AnchorSide[Side].Control;
|
||||||
if (SideControl<>nil) and Check(Parent.GetControlIndex(SideControl)) then
|
if (SideControl<>nil) and Check(Parent.GetControlIndex(SideControl)) then
|
||||||
@ -631,7 +631,7 @@ var
|
|||||||
end;
|
end;
|
||||||
Result:=false;
|
Result:=false;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
@ -659,19 +659,19 @@ function GetEnclosingControlRect(ControlList: TFPlist; out
|
|||||||
ARect: TAnchorControlsRect): boolean;
|
ARect: TAnchorControlsRect): boolean;
|
||||||
{ ARect will be the minimum TAnchorControlsRect around the controls in the list
|
{ ARect will be the minimum TAnchorControlsRect around the controls in the list
|
||||||
returns true, if there is such a TAnchorControlsRect.
|
returns true, if there is such a TAnchorControlsRect.
|
||||||
|
|
||||||
The controls in ARect will either be the Parent or a TLazDockSplitter
|
The controls in ARect will either be the Parent or a TLazDockSplitter
|
||||||
}
|
}
|
||||||
var
|
var
|
||||||
Parent: TWinControl;
|
Parent: TWinControl;
|
||||||
|
|
||||||
function ControlIsValidAnchor(Control: TControl; Side: TAnchorKind): boolean;
|
function ControlIsValidAnchor(Control: TControl; Side: TAnchorKind): boolean;
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
Result:=false;
|
Result:=false;
|
||||||
if (Control=ARect[Side]) then exit(true);// this allows Parent at the beginning
|
if (Control=ARect[Side]) then exit(true);// this allows Parent at the beginning
|
||||||
|
|
||||||
if not (Control is TLazDockSplitter) then
|
if not (Control is TLazDockSplitter) then
|
||||||
exit;// not a splitter
|
exit;// not a splitter
|
||||||
if (TLazDockSplitter(Control).ResizeAnchor in [akLeft,akRight])
|
if (TLazDockSplitter(Control).ResizeAnchor in [akLeft,akRight])
|
||||||
@ -690,7 +690,7 @@ var
|
|||||||
end;
|
end;
|
||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
TopIndex: Integer;
|
TopIndex: Integer;
|
||||||
TopControl: TControl;
|
TopControl: TControl;
|
||||||
@ -712,7 +712,7 @@ begin
|
|||||||
if Parent=nil then exit;
|
if Parent=nil then exit;
|
||||||
for i:=0 to ControlList.Count-1 do
|
for i:=0 to ControlList.Count-1 do
|
||||||
if TControl(ControlList[i]).Parent<>Parent then exit;
|
if TControl(ControlList[i]).Parent<>Parent then exit;
|
||||||
|
|
||||||
// set the default rect: the Parent
|
// set the default rect: the Parent
|
||||||
Result:=true;
|
Result:=true;
|
||||||
for a:=Low(TAnchorKind) to High(TAnchorKind) do
|
for a:=Low(TAnchorKind) to High(TAnchorKind) do
|
||||||
@ -731,21 +731,21 @@ begin
|
|||||||
for TopIndex:=0 to Candidates.Count-1 do begin
|
for TopIndex:=0 to Candidates.Count-1 do begin
|
||||||
TopControl:=TControl(Candidates[TopIndex]);
|
TopControl:=TControl(Candidates[TopIndex]);
|
||||||
if not ControlIsValidAnchor(TopControl,akTop) then continue;
|
if not ControlIsValidAnchor(TopControl,akTop) then continue;
|
||||||
|
|
||||||
for RightIndex:=0 to Candidates.Count-1 do begin
|
for RightIndex:=0 to Candidates.Count-1 do begin
|
||||||
RightControl:=TControl(Candidates[RightIndex]);
|
RightControl:=TControl(Candidates[RightIndex]);
|
||||||
if (TopControl.AnchorSide[akRight].Control<>RightControl)
|
if (TopControl.AnchorSide[akRight].Control<>RightControl)
|
||||||
and (RightControl.AnchorSide[akTop].Control<>TopControl) then
|
and (RightControl.AnchorSide[akTop].Control<>TopControl) then
|
||||||
continue; // not touching / not a corner
|
continue; // not touching / not a corner
|
||||||
if not ControlIsValidAnchor(RightControl,akRight) then continue;
|
if not ControlIsValidAnchor(RightControl,akRight) then continue;
|
||||||
|
|
||||||
for BottomIndex:=0 to Candidates.Count-1 do begin
|
for BottomIndex:=0 to Candidates.Count-1 do begin
|
||||||
BottomControl:=TControl(Candidates[BottomIndex]);
|
BottomControl:=TControl(Candidates[BottomIndex]);
|
||||||
if (RightControl.AnchorSide[akBottom].Control<>BottomControl)
|
if (RightControl.AnchorSide[akBottom].Control<>BottomControl)
|
||||||
and (BottomControl.AnchorSide[akRight].Control<>RightControl) then
|
and (BottomControl.AnchorSide[akRight].Control<>RightControl) then
|
||||||
continue; // not touching / not a corner
|
continue; // not touching / not a corner
|
||||||
if not ControlIsValidAnchor(BottomControl,akBottom) then continue;
|
if not ControlIsValidAnchor(BottomControl,akBottom) then continue;
|
||||||
|
|
||||||
for LeftIndex:=0 to Candidates.Count-1 do begin
|
for LeftIndex:=0 to Candidates.Count-1 do begin
|
||||||
LeftControl:=TControl(Candidates[LeftIndex]);
|
LeftControl:=TControl(Candidates[LeftIndex]);
|
||||||
if (BottomControl.AnchorSide[akLeft].Control<>LeftControl)
|
if (BottomControl.AnchorSide[akLeft].Control<>LeftControl)
|
||||||
@ -765,7 +765,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Candidates.Free;
|
Candidates.Free;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -773,7 +773,7 @@ function GetEnclosedControls(const ARect: TAnchorControlsRect): TFPList;
|
|||||||
{ return a list of all controls bounded by the anchors in ARect }
|
{ return a list of all controls bounded by the anchors in ARect }
|
||||||
var
|
var
|
||||||
Parent: TWinControl;
|
Parent: TWinControl;
|
||||||
|
|
||||||
procedure Fill(AControl: TControl);
|
procedure Fill(AControl: TControl);
|
||||||
var
|
var
|
||||||
a: TAnchorKind;
|
a: TAnchorKind;
|
||||||
@ -784,10 +784,10 @@ var
|
|||||||
if AControl=Parent then exit;// do not add Parent
|
if AControl=Parent then exit;// do not add Parent
|
||||||
for a:=Low(TAnchorKind) to High(TAnchorKind) do
|
for a:=Low(TAnchorKind) to High(TAnchorKind) do
|
||||||
if ARect[a]=AControl then exit;// do not add boundary
|
if ARect[a]=AControl then exit;// do not add boundary
|
||||||
|
|
||||||
if Result.IndexOf(AControl)>=0 then exit;// already added
|
if Result.IndexOf(AControl)>=0 then exit;// already added
|
||||||
Result.Add(AControl);
|
Result.Add(AControl);
|
||||||
|
|
||||||
for a:=Low(TAnchorKind) to High(TAnchorKind) do
|
for a:=Low(TAnchorKind) to High(TAnchorKind) do
|
||||||
Fill(AControl.AnchorSide[a].Control);
|
Fill(AControl.AnchorSide[a].Control);
|
||||||
for i:=0 to Parent.ControlCount-1 do begin
|
for i:=0 to Parent.ControlCount-1 do begin
|
||||||
@ -797,7 +797,7 @@ var
|
|||||||
Fill(SideControl);
|
Fill(SideControl);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
AControl: TControl;
|
AControl: TControl;
|
||||||
@ -810,7 +810,7 @@ begin
|
|||||||
Parent:=TWinControl(ARect[akLeft])
|
Parent:=TWinControl(ARect[akLeft])
|
||||||
else
|
else
|
||||||
Parent:=ARect[akLeft].Parent;
|
Parent:=ARect[akLeft].Parent;
|
||||||
|
|
||||||
// find the left, top most control
|
// find the left, top most control
|
||||||
for i:=0 to Parent.ControlCount-1 do begin
|
for i:=0 to Parent.ControlCount-1 do begin
|
||||||
AControl:=Parent.Controls[i];
|
AControl:=Parent.Controls[i];
|
||||||
@ -821,7 +821,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
if Result.Count=0 then exit;
|
if Result.Count=0 then exit;
|
||||||
|
|
||||||
// use flood fill to find the rest
|
// use flood fill to find the rest
|
||||||
Fill(LeftTopControl);
|
Fill(LeftTopControl);
|
||||||
end;
|
end;
|
||||||
@ -1169,12 +1169,12 @@ procedure TLazDockTree.InsertControl(AControl: TControl; InsertAt: TAlign;
|
|||||||
It creates a new TDockZone for AControl and inserts it as a new leaf.
|
It creates a new TDockZone for AControl and inserts it as a new leaf.
|
||||||
It automatically changes the tree, so that the parent of the new TDockZone
|
It automatically changes the tree, so that the parent of the new TDockZone
|
||||||
will have the Orientation for InsertAt.
|
will have the Orientation for InsertAt.
|
||||||
|
|
||||||
Example 1:
|
Example 1:
|
||||||
|
|
||||||
A newly created TLazDockTree has only a DockSite (TLazDockForm) and a single
|
A newly created TLazDockTree has only a DockSite (TLazDockForm) and a single
|
||||||
TDockZone - the RootZone, which has as ChildControl the DockSite.
|
TDockZone - the RootZone, which has as ChildControl the DockSite.
|
||||||
|
|
||||||
Visual:
|
Visual:
|
||||||
+-DockSite--+
|
+-DockSite--+
|
||||||
| |
|
| |
|
||||||
@ -1241,11 +1241,11 @@ begin
|
|||||||
|
|
||||||
// undock
|
// undock
|
||||||
UndockControlForDocking(AControl);
|
UndockControlForDocking(AControl);
|
||||||
|
|
||||||
// dock
|
// dock
|
||||||
// create a new zone for AControl
|
// create a new zone for AControl
|
||||||
NewZone := DockZoneClass.Create(Self,AControl) as TLazDockZone;
|
NewZone := DockZoneClass.Create(Self,AControl) as TLazDockZone;
|
||||||
|
|
||||||
// insert new zone into tree
|
// insert new zone into tree
|
||||||
if (DropZone = RootZone) and (RootZone.FirstChild = nil) then
|
if (DropZone = RootZone) and (RootZone.FirstChild = nil) then
|
||||||
begin
|
begin
|
||||||
@ -1263,7 +1263,7 @@ begin
|
|||||||
|
|
||||||
AControl.BoundsRect := NewBounds;
|
AControl.BoundsRect := NewBounds;
|
||||||
AControl.Parent := DockSite;
|
AControl.Parent := DockSite;
|
||||||
|
|
||||||
if AControl.Visible then
|
if AControl.Visible then
|
||||||
DockSite.Visible := True;
|
DockSite.Visible := True;
|
||||||
end else
|
end else
|
||||||
@ -1282,7 +1282,7 @@ begin
|
|||||||
else
|
else
|
||||||
DropZone := DropZone.GetLastChild;
|
DropZone := DropZone.GetLastChild;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// insert a new Parent Zone if needed
|
// insert a new Parent Zone if needed
|
||||||
NeedNewParentZone := True;
|
NeedNewParentZone := True;
|
||||||
if (DropZone.Parent <> nil) then
|
if (DropZone.Parent <> nil) then
|
||||||
@ -1302,7 +1302,7 @@ begin
|
|||||||
OldParentZone.ReplaceChild(DropZone, NewParentZone);
|
OldParentZone.ReplaceChild(DropZone, NewParentZone);
|
||||||
NewParentZone.AddAsFirstChild(DropZone);
|
NewParentZone.AddAsFirstChild(DropZone);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if DropZone.Parent = nil then
|
if DropZone.Parent = nil then
|
||||||
RaiseGDBException('TLazDockTree.InsertControl Inconsistency DropZone.Parent=nil');
|
RaiseGDBException('TLazDockTree.InsertControl Inconsistency DropZone.Parent=nil');
|
||||||
// adjust Orientation in tree
|
// adjust Orientation in tree
|
||||||
@ -1318,17 +1318,15 @@ begin
|
|||||||
RaiseGDBException('TLazDockTree.InsertControl Inconsistency DropZone.Orientation<>NewOrientation');
|
RaiseGDBException('TLazDockTree.InsertControl Inconsistency DropZone.Orientation<>NewOrientation');
|
||||||
|
|
||||||
// insert new node
|
// insert new node
|
||||||
if InsertAt in [alLeft, alTop] then
|
//DoDi: should insert relative to dropzone, not at begin/end of the parent zone
|
||||||
DropZone.Parent.AddAsFirstChild(NewZone)
|
DropZone.AddSibling(NewZone, InsertAt);
|
||||||
else
|
|
||||||
DropZone.Parent.AddAsLastChild(NewZone);
|
|
||||||
|
|
||||||
// add AControl to DockSite
|
// add AControl to DockSite
|
||||||
PrepareControlForResize(AControl);
|
PrepareControlForResize(AControl);
|
||||||
AControl.DockOrientation := NewOrientation;
|
AControl.DockOrientation := NewOrientation;
|
||||||
AControl.Parent := NewZone.GetParentControl;
|
AControl.Parent := NewZone.GetParentControl;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Build dock layout (anchors, splitters, pages)
|
// Build dock layout (anchors, splitters, pages)
|
||||||
if NewZone.Parent <> nil then
|
if NewZone.Parent <> nil then
|
||||||
BuildDockLayout(NewZone.Parent as TLazDockZone)
|
BuildDockLayout(NewZone.Parent as TLazDockZone)
|
||||||
@ -1397,7 +1395,7 @@ procedure TLazDockTree.FindBorderControls(Zone: TLazDockZone; Side: TAnchorKind;
|
|||||||
begin
|
begin
|
||||||
if List=nil then List:=TFPList.Create;
|
if List=nil then List:=TFPList.Create;
|
||||||
if Zone=nil then exit;
|
if Zone=nil then exit;
|
||||||
|
|
||||||
if (Zone.Splitter<>nil) and (Zone.Parent<>nil)
|
if (Zone.Splitter<>nil) and (Zone.Parent<>nil)
|
||||||
and (Zone.Orientation=doVertical) then begin
|
and (Zone.Orientation=doVertical) then begin
|
||||||
// this splitter is leftmost, topmost, bottommost
|
// this splitter is leftmost, topmost, bottommost
|
||||||
@ -1574,7 +1572,7 @@ procedure TLazDockTree.MouseMessage(var Message: TLMessage);
|
|||||||
InvalidateRect(DockSite.Handle, @NewMouseState.Rect, False);
|
InvalidateRect(DockSite.Handle, @NewMouseState.Rect, False);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function FindControlAndPart(MouseMsg: TLMMouse; out ARect: TRect; out APart: TLazDockHeaderPart): TControl;
|
function FindControlAndPart(MouseMsg: TLMMouse; out ARect: TRect; out APart: TLazDockHeaderPart): TControl;
|
||||||
var
|
var
|
||||||
i: integer;
|
i: integer;
|
||||||
@ -1610,7 +1608,7 @@ procedure TLazDockTree.MouseMessage(var Message: TLMessage);
|
|||||||
end;
|
end;
|
||||||
Result := nil;
|
Result := nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
ARect: TRect;
|
ARect: TRect;
|
||||||
Part: TLazDockHeaderPart;
|
Part: TLazDockHeaderPart;
|
||||||
@ -1854,19 +1852,19 @@ procedure TCustomAnchoredDockManager.CombineSpiralSplitterPair(Splitter1,
|
|||||||
|------
|
|------
|
||||||
| D
|
| D
|
||||||
}
|
}
|
||||||
|
|
||||||
procedure MoveAnchorSide(AControl: TControl; Side: TAnchorKind);
|
procedure MoveAnchorSide(AControl: TControl; Side: TAnchorKind);
|
||||||
begin
|
begin
|
||||||
if AControl.AnchorSide[Side].Control=Splitter2 then
|
if AControl.AnchorSide[Side].Control=Splitter2 then
|
||||||
AControl.AnchorSide[Side].Control:=Splitter1;
|
AControl.AnchorSide[Side].Control:=Splitter1;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure EnlargeSplitter(Side: TAnchorKind);
|
procedure EnlargeSplitter(Side: TAnchorKind);
|
||||||
begin
|
begin
|
||||||
if GetAnchorDepth(Splitter1,Side)>GetAnchorDepth(Splitter2,Side) then
|
if GetAnchorDepth(Splitter1,Side)>GetAnchorDepth(Splitter2,Side) then
|
||||||
Splitter1.AnchorSide[Side].Assign(Splitter2.AnchorSide[Side]);
|
Splitter1.AnchorSide[Side].Assign(Splitter2.AnchorSide[Side]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
LeftRightSplitter: boolean;
|
LeftRightSplitter: boolean;
|
||||||
ParentControl: TWinControl;
|
ParentControl: TWinControl;
|
||||||
@ -1900,7 +1898,7 @@ begin
|
|||||||
MoveAnchorSide(CurControl,akBottom);
|
MoveAnchorSide(CurControl,akBottom);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// enlarge Splitter1
|
// enlarge Splitter1
|
||||||
if LeftRightSplitter then begin
|
if LeftRightSplitter then begin
|
||||||
// enlarge Splitter1 to top and bottom
|
// enlarge Splitter1 to top and bottom
|
||||||
@ -1911,7 +1909,7 @@ begin
|
|||||||
EnlargeSplitter(akLeft);
|
EnlargeSplitter(akLeft);
|
||||||
EnlargeSplitter(akRight);
|
EnlargeSplitter(akRight);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// delete Splitter2
|
// delete Splitter2
|
||||||
Splitter2.Free;
|
Splitter2.Free;
|
||||||
finally
|
finally
|
||||||
@ -2100,7 +2098,7 @@ begin
|
|||||||
|
|
||||||
DropCtlAnchor:=MainAlignAnchor[InsertAt];
|
DropCtlAnchor:=MainAlignAnchor[InsertAt];
|
||||||
ControlAnchor:=OppositeAnchor[DropCtlAnchor];
|
ControlAnchor:=OppositeAnchor[DropCtlAnchor];
|
||||||
|
|
||||||
DropCtlTitlePos:=GetPreferredTitlePosition(DropCtl.ClientWidth,
|
DropCtlTitlePos:=GetPreferredTitlePosition(DropCtl.ClientWidth,
|
||||||
DropCtl.ClientHeight);
|
DropCtl.ClientHeight);
|
||||||
|
|
||||||
@ -2146,7 +2144,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if not ParentDisabledAlign then
|
if not ParentDisabledAlign then
|
||||||
begin
|
begin
|
||||||
DropCtl.Parent.DisableAlign;
|
DropCtl.Parent.DisableAlign;
|
||||||
ParentDisabledAlign := True;
|
ParentDisabledAlign := True;
|
||||||
@ -2234,7 +2232,7 @@ begin
|
|||||||
|
|
||||||
// position DropCtl
|
// position DropCtl
|
||||||
DropCtl.AnchorToNeighbour(DropCtlAnchor,0,Splitter);
|
DropCtl.AnchorToNeighbour(DropCtlAnchor,0,Splitter);
|
||||||
|
|
||||||
// set titles
|
// set titles
|
||||||
UpdateTitlePosition(DropCtl);
|
UpdateTitlePosition(DropCtl);
|
||||||
UpdateTitlePosition(Control);
|
UpdateTitlePosition(Control);
|
||||||
@ -2309,7 +2307,7 @@ end;
|
|||||||
|
|
||||||
Removes a control from a docking form.
|
Removes a control from a docking form.
|
||||||
It breaks all anchors and cleans up.
|
It breaks all anchors and cleans up.
|
||||||
|
|
||||||
The created gap will be tried to fill up.
|
The created gap will be tried to fill up.
|
||||||
It removes TLazDockSplitter, TLazDockPage and TLazDockPages if they are no
|
It removes TLazDockSplitter, TLazDockPage and TLazDockPages if they are no
|
||||||
longer needed.
|
longer needed.
|
||||||
@ -2342,7 +2340,7 @@ procedure TCustomAnchoredDockManager.UndockControl(Control: TControl; Float: boo
|
|||||||
|
|
||||||
|
|
||||||
2. Four spiral splitters:
|
2. Four spiral splitters:
|
||||||
|
|
||||||
Before:
|
Before:
|
||||||
|
|
|
|
||||||
A |
|
A |
|
||||||
@ -2354,7 +2352,7 @@ procedure TCustomAnchoredDockManager.UndockControl(Control: TControl; Float: boo
|
|||||||
| D
|
| D
|
||||||
|
|
||||||
The left and right splitter will be combined to one.
|
The left and right splitter will be combined to one.
|
||||||
|
|
||||||
After:
|
After:
|
||||||
|
|
|
|
||||||
A |
|
A |
|
||||||
@ -2369,12 +2367,12 @@ procedure TCustomAnchoredDockManager.UndockControl(Control: TControl; Float: boo
|
|||||||
3. No TLazDockSplitter. Control is the only child of a TLazDockPage
|
3. No TLazDockSplitter. Control is the only child of a TLazDockPage
|
||||||
In this case the page will be deleted.
|
In this case the page will be deleted.
|
||||||
If the TLazDockPages has no childs left, it is recursively undocked.
|
If the TLazDockPages has no childs left, it is recursively undocked.
|
||||||
|
|
||||||
4. No TLazDockSplitter, Control is the only child of a TLazDockForm.
|
4. No TLazDockSplitter, Control is the only child of a TLazDockForm.
|
||||||
The TLazDockForm is deleted and the Control is floated.
|
The TLazDockForm is deleted and the Control is floated.
|
||||||
This normally means: A form will simply be placed on the desktop, other
|
This normally means: A form will simply be placed on the desktop, other
|
||||||
controls will be docked into their DockSite.
|
controls will be docked into their DockSite.
|
||||||
|
|
||||||
5. Otherwise: this control was not docked.
|
5. Otherwise: this control was not docked.
|
||||||
}
|
}
|
||||||
var
|
var
|
||||||
@ -2416,7 +2414,7 @@ var
|
|||||||
ParentControl:=nil;
|
ParentControl:=nil;
|
||||||
DebugLn(['DoFinallyForParent EnableAlign for ',DbgSName(OldParentControl),' Control=',DbgSName(Control),' OldParentControl.ControlCount=',OldParentControl.ControlCount]);
|
DebugLn(['DoFinallyForParent EnableAlign for ',DbgSName(OldParentControl),' Control=',DbgSName(Control),' OldParentControl.ControlCount=',OldParentControl.ControlCount]);
|
||||||
OldParentControl.EnableAlign;
|
OldParentControl.EnableAlign;
|
||||||
|
|
||||||
// check if the remaining is a TLazDockForm with only one child
|
// check if the remaining is a TLazDockForm with only one child
|
||||||
if (OldParentControl is TLazDockForm)
|
if (OldParentControl is TLazDockForm)
|
||||||
and (OldParentControl.ControlCount=1) then
|
and (OldParentControl.ControlCount=1) then
|
||||||
@ -2435,7 +2433,7 @@ var
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
OldParentPage: TLazDockPage;
|
OldParentPage: TLazDockPage;
|
||||||
OldParentForm: TLazDockForm;
|
OldParentForm: TLazDockForm;
|
||||||
@ -2445,7 +2443,7 @@ begin
|
|||||||
// already undocked
|
// already undocked
|
||||||
RaiseGDBException('TCustomAnchoredDockManager.UndockControl Control.Parent=nil');
|
RaiseGDBException('TCustomAnchoredDockManager.UndockControl Control.Parent=nil');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
ParentControl:=Control.Parent;
|
ParentControl:=Control.Parent;
|
||||||
ParentControl.DisableAlign;
|
ParentControl.DisableAlign;
|
||||||
try
|
try
|
||||||
@ -2515,7 +2513,7 @@ begin
|
|||||||
Done:=true;
|
Done:=true;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if not Done then begin
|
if not Done then begin
|
||||||
// check if Control is the only child of a TLazDockForm
|
// check if Control is the only child of a TLazDockForm
|
||||||
if (ParentControl.ControlCount=1)
|
if (ParentControl.ControlCount=1)
|
||||||
@ -2526,11 +2524,11 @@ begin
|
|||||||
Done:=true;
|
Done:=true;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if not Done then begin
|
if not Done then begin
|
||||||
// otherwise: keep
|
// otherwise: keep
|
||||||
end;
|
end;
|
||||||
|
|
||||||
finally
|
finally
|
||||||
DoFinallyForParent;
|
DoFinallyForParent;
|
||||||
end;
|
end;
|
||||||
@ -2593,14 +2591,14 @@ var
|
|||||||
ParentDisabledAlign: Boolean;
|
ParentDisabledAlign: Boolean;
|
||||||
EnlargeSplitter: TLazDockSplitter;
|
EnlargeSplitter: TLazDockSplitter;
|
||||||
RotateSplitter: TLazDockSplitter;
|
RotateSplitter: TLazDockSplitter;
|
||||||
|
|
||||||
procedure ParentDisableAlign;
|
procedure ParentDisableAlign;
|
||||||
begin
|
begin
|
||||||
if ParentDisabledAlign then exit;
|
if ParentDisabledAlign then exit;
|
||||||
ParentDisabledAlign:=true;
|
ParentDisabledAlign:=true;
|
||||||
Parent.DisableAlign;
|
Parent.DisableAlign;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Result:=false;
|
Result:=false;
|
||||||
if Control=nil then exit;
|
if Control=nil then exit;
|
||||||
@ -2615,7 +2613,7 @@ begin
|
|||||||
if not GetLazDockSplitterOrParent(Control,Side3,Side3Anchor) then exit;
|
if not GetLazDockSplitterOrParent(Control,Side3,Side3Anchor) then exit;
|
||||||
Parent:=Control.Parent;
|
Parent:=Control.Parent;
|
||||||
if (Side2Anchor=Parent) and (Side3Anchor=Parent) then exit;
|
if (Side2Anchor=Parent) and (Side3Anchor=Parent) then exit;
|
||||||
|
|
||||||
// search controls anchored to the MainSplitter on the other side
|
// search controls anchored to the MainSplitter on the other side
|
||||||
Neighbour:=nil;
|
Neighbour:=nil;
|
||||||
for i:=0 to Parent.ControlCount-1 do begin
|
for i:=0 to Parent.ControlCount-1 do begin
|
||||||
@ -2652,7 +2650,7 @@ begin
|
|||||||
if Sibling.Top>Control.Top+Control.Height then continue;
|
if Sibling.Top>Control.Top+Control.Height then continue;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if Neighbour=nil then
|
if Neighbour=nil then
|
||||||
Neighbour:=Sibling
|
Neighbour:=Sibling
|
||||||
else if Sibling is TLazDockSplitter then begin
|
else if Sibling is TLazDockSplitter then begin
|
||||||
@ -2667,7 +2665,7 @@ begin
|
|||||||
|
|
||||||
if Neighbour=nil then exit; // no neighbour found
|
if Neighbour=nil then exit; // no neighbour found
|
||||||
DebugLn(['TCustomAnchoredDockManager.EnlargeControl Neighbour=',DbgSName(Neighbour)]);
|
DebugLn(['TCustomAnchoredDockManager.EnlargeControl Neighbour=',DbgSName(Neighbour)]);
|
||||||
|
|
||||||
ParentDisabledAlign:=false;
|
ParentDisabledAlign:=false;
|
||||||
try
|
try
|
||||||
if Neighbour is TLazDockSplitter then begin
|
if Neighbour is TLazDockSplitter then begin
|
||||||
@ -2760,7 +2758,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
UpdateTitlePosition(Control);
|
UpdateTitlePosition(Control);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end else begin
|
end else begin
|
||||||
// shrink a neighbour control
|
// shrink a neighbour control
|
||||||
DebugLn(['TCustomAnchoredDockManager.EnlargeControl Shrink one control: Neighbour=',DbgSName(Neighbour)]);
|
DebugLn(['TCustomAnchoredDockManager.EnlargeControl Shrink one control: Neighbour=',DbgSName(Neighbour)]);
|
||||||
@ -2777,7 +2775,7 @@ begin
|
|||||||
------------------- }
|
------------------- }
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// check if the Neighbour can be shrinked
|
// check if the Neighbour can be shrinked
|
||||||
if NeighbourCanBeShrinked(Control,Neighbour,Side2) then begin
|
if NeighbourCanBeShrinked(Control,Neighbour,Side2) then begin
|
||||||
ShrinkSide:=Side2;
|
ShrinkSide:=Side2;
|
||||||
@ -2787,7 +2785,7 @@ begin
|
|||||||
// Neighbour can not be shrinked
|
// Neighbour can not be shrinked
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ EnlargeSplitter
|
{ EnlargeSplitter
|
||||||
^
|
^
|
||||||
|
Loading…
Reference in New Issue
Block a user