diff --git a/examples/dockmanager/elasticsite/MakeSite.lpi b/examples/dockmanager/elasticsite/MakeSite.lpi
index e5a5e60138..2871cf13db 100644
--- a/examples/dockmanager/elasticsite/MakeSite.lpi
+++ b/examples/dockmanager/elasticsite/MakeSite.lpi
@@ -8,7 +8,7 @@
-
+
@@ -33,14 +33,14 @@
-
+
-
+
@@ -51,25 +51,29 @@
-
+
-
-
+
+
-
+
+
+
+
+
-
-
-
-
+
+
+
+
@@ -91,10 +95,10 @@
-
-
-
-
+
+
+
+
@@ -106,7 +110,7 @@
-
+
@@ -129,31 +133,26 @@
-
-
+
+
-
-
-
-
+
-
-
+
+
-
+
-
-
-
+
@@ -186,10 +185,10 @@
-
-
+
+
-
+
@@ -198,10 +197,10 @@
-
-
-
-
+
+
+
+
@@ -247,48 +246,38 @@
-
-
-
+
-
-
-
-
-
+
+
+
-
-
-
+
-
-
-
+
-
-
-
+
-
-
-
-
+
+
+
+
@@ -301,143 +290,177 @@
-
-
-
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
-
diff --git a/examples/dockmanager/package/easydocksite.pas b/examples/dockmanager/package/easydocksite.pas
index 666389528f..1e1b61ed45 100644
--- a/examples/dockmanager/package/easydocksite.pas
+++ b/examples/dockmanager/package/easydocksite.pas
@@ -72,6 +72,11 @@ uses
Forms,
ExtCtrls, //splitter
Controls,
+{$IFDEF PageFrame}
+ fPageFrame,
+{$ELSE}
+ fDockBook,
+{$ENDIF}
ComCtrls; //TPageControl
type
@@ -79,6 +84,12 @@ type
TEasyZone = class; //forward declaration
TEasySplitter = TCustomSplitter;
+{$IFDEF PageFrame}
+ TEasyBook = TPageFrame;
+{$ELSE}
+ TEasyBook = TEasyDockBook;
+{$ENDIF}
+
TEasyZonePart =
(
zpNowhere, // not in any zone
@@ -243,6 +254,9 @@ type
property HideSingleCaption: boolean read FHideSingleCaption write SetSingleCaption;
end;
+function NoteBookCreate(AOwner: TWinControl): TEasyBook; inline;
+procedure NoteBookAdd(ABook: TEasyBook; AItem: TControl); inline;
+
const
AlignNames: array[TAlign] of string = (
'alNone', 'alTop', 'alBottom', 'alLeft', 'alRight', 'alClient', 'alCustom'
@@ -269,11 +283,6 @@ implementation
uses
SysUtils, Types,
math,
-{$IFDEF PageFrame}
- fPageFrame,
-{$ELSE}
- fDockBook,
-{$ENDIF}
Themes, LResources,
LCLproc; //debugging
@@ -284,13 +293,6 @@ const
HeaderButtons = [zpCloseButton];
{$ENDIF}
-type
-{$IFDEF PageFrame}
- TEasyBook = TPageFrame;
-{$ELSE}
- TEasyBook = TEasyDockBook;
-{$ENDIF}
-
function NoteBookCreate(AOwner: TWinControl): TEasyBook; inline;
begin
Result := TEasyBook.Create(AOwner);
@@ -298,7 +300,6 @@ end;
procedure NoteBookAdd(ABook: TEasyBook; AItem: TControl); inline;
begin
- //AItem.ManualDock(ABook.pnlDock);
AItem.ManualDock(ABook);
end;
diff --git a/examples/dockmanager/package/fdockbook.lfm b/examples/dockmanager/package/fdockbook.lfm
index 2c0c073b59..44dc051e1e 100644
--- a/examples/dockmanager/package/fdockbook.lfm
+++ b/examples/dockmanager/package/fdockbook.lfm
@@ -8,6 +8,7 @@ object EasyDockBook: TEasyDockBook
ClientWidth = 400
DockSite = True
DragKind = dkDock
+ OnClose = FormClose
OnCreate = FormCreate
OnDockDrop = FormDockDrop
OnDockOver = FormDockOver
diff --git a/examples/dockmanager/package/fdockbook.lrs b/examples/dockmanager/package/fdockbook.lrs
index 5233aef49d..75f2de5fdd 100644
--- a/examples/dockmanager/package/fdockbook.lrs
+++ b/examples/dockmanager/package/fdockbook.lrs
@@ -3,10 +3,10 @@
LazarusResources.Add('TEasyDockBook','FORMDATA',[
'TPF0'#13'TEasyDockBook'#12'EasyDockBook'#4'Left'#3#7#1#6'Height'#3','#1#3'To'
+'p'#3#146#0#5'Width'#3#144#1#7'Caption'#6#12'EasyDockBook'#12'ClientHeight'#3
- +','#1#11'ClientWidth'#3#144#1#8'DockSite'#9#8'DragKind'#7#6'dkDock'#8'OnCrea'
- +'te'#7#10'FormCreate'#10'OnDockDrop'#7#12'FormDockDrop'#10'OnDockOver'#7#12
- +'FormDockOver'#13'OnGetSiteInfo'#7#15'FormGetSiteInfo'#8'OnUnDock'#7#10'Form'
- +'UnDock'#10'LCLVersion'#6#6'0.9.29'#7'Visible'#9#0#6'TPanel'#7'pnlDock'#4'Le'
- +'ft'#2#0#6'Height'#3','#1#3'Top'#2#0#5'Width'#3#144#1#5'Align'#7#8'alClient'
- +#8'TabOrder'#2#0#14'UseDockManager'#8#0#0#0
+ +','#1#11'ClientWidth'#3#144#1#8'DockSite'#9#8'DragKind'#7#6'dkDock'#7'OnClos'
+ +'e'#7#9'FormClose'#8'OnCreate'#7#10'FormCreate'#10'OnDockDrop'#7#12'FormDock'
+ +'Drop'#10'OnDockOver'#7#12'FormDockOver'#13'OnGetSiteInfo'#7#15'FormGetSiteI'
+ +'nfo'#8'OnUnDock'#7#10'FormUnDock'#10'LCLVersion'#6#6'0.9.29'#7'Visible'#9#0
+ +#6'TPanel'#7'pnlDock'#4'Left'#2#0#6'Height'#3','#1#3'Top'#2#0#5'Width'#3#144
+ +#1#5'Align'#7#8'alClient'#8'TabOrder'#2#0#14'UseDockManager'#8#0#0#0
]);
diff --git a/examples/dockmanager/package/fdockbook.pas b/examples/dockmanager/package/fdockbook.pas
index bd53e66880..75f4416d20 100644
--- a/examples/dockmanager/package/fdockbook.pas
+++ b/examples/dockmanager/package/fdockbook.pas
@@ -32,10 +32,12 @@ ToDo:
- Load/Store layout
+ Update parent on un/dock: Caption and DockHeaders!
-Problem:
+Problems:
Disallow undocking/floating of a NOT docked dockbook.
Fix: flag StayDocked.
+
+Clients are not properly undocked on close!?
*)
(* Applications
@@ -85,6 +87,7 @@ type
TEasyDockBook = class(TForm)
pnlDock: TPanel;
+ procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
procedure FormCreate(Sender: TObject);
procedure FormDockDrop(Sender: TObject; Source: TDragDockObject;
X, Y: Integer);
@@ -121,6 +124,37 @@ end;
{ TEasyDockBook }
+procedure TEasyDockBook.FormClose(Sender: TObject;
+ var CloseAction: TCloseAction);
+var
+ i: integer;
+ ctl: TControl;
+ //wc: TWinControl absolute ctl;
+ frm: TCustomForm absolute ctl;
+begin
+(* When an empty notebook is closed, it shall be freed.
+ Otherwise the clients must be handled (close forms)
+
+ This code is never reached???
+*)
+{$IFDEF new}
+ //BeginFormUpdate;
+ for i := DockClientCount - 1 downto 0 do begin
+ ctl := DockClients[i];
+ ctl.ManualDock(nil);
+ DebugLn('Undocked %s P=%p H=%p', [ctl.Name,
+ pointer(ctl.Parent), pointer(ctl.HostDockSite)]);
+ if ctl is TCustomForm then begin
+ //frm.Close;
+ end;
+ end;
+ //EndFormUpdate;
+{$ELSE}
+ //not required?
+{$ENDIF}
+ CloseAction := caFree;
+end;
+
procedure TEasyDockBook.FormCreate(Sender: TObject);
begin
Tabs := TTabs.Create(self);
diff --git a/examples/dockmanager/package/ffloatingsite.lfm b/examples/dockmanager/package/ffloatingsite.lfm
index 236e8ccf72..3b0fecf479 100644
--- a/examples/dockmanager/package/ffloatingsite.lfm
+++ b/examples/dockmanager/package/ffloatingsite.lfm
@@ -7,6 +7,7 @@ object FloatingSite: TFloatingSite
ClientHeight = 265
ClientWidth = 377
DockSite = True
+ OnClose = FormClose
OnDockDrop = FormDockDrop
OnUnDock = FormUnDock
UseDockManager = True
diff --git a/examples/dockmanager/package/ffloatingsite.lrs b/examples/dockmanager/package/ffloatingsite.lrs
index ccb9fc49d3..3d26fe2db3 100644
--- a/examples/dockmanager/package/ffloatingsite.lrs
+++ b/examples/dockmanager/package/ffloatingsite.lrs
@@ -3,20 +3,20 @@
LazarusResources.Add('TFloatingSite','FORMDATA',[
'TPF0'#13'TFloatingSite'#12'FloatingSite'#4'Left'#3#175#1#6'Height'#3#9#1#3'T'
+'op'#3#242#1#5'Width'#3'y'#1#7'Caption'#6#12'FloatingSite'#12'ClientHeight'#3
- +#9#1#11'ClientWidth'#3'y'#1#8'DockSite'#9#10'OnDockDrop'#7#12'FormDockDrop'#8
- +'OnUnDock'#7#10'FormUnDock'#14'UseDockManager'#9#10'LCLVersion'#6#6'0.9.29'#7
- +'Visible'#9#0#6'TImage'#6'Image1'#4'Left'#3'i'#1#6'Height'#2#16#3'Top'#2#0#5
- +'Width'#2#16#7'Anchors'#11#5'akTop'#7'akRight'#0#8'AutoSize'#9#12'Picture.Da'
- +'ta'#10'H'#1#0#0#5'TIcon>'#1#0#0#0#0#1#0#1#0#16#16#16#0#0#0#0#0'('#1#0#0#22#0
- +#0#0'('#0#0#0#16#0#0#0' '#0#0#0#1#0#4#0#0#0#0#0#192#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128#0#128#0#0#0#128#0#128#0
- +#128#128#0#0#128#128#128#0#192#192#192#0#0#0#255#0#0#255#0#0#0#255#255#0#255
- +#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+ +#9#1#11'ClientWidth'#3'y'#1#8'DockSite'#9#7'OnClose'#7#9'FormClose'#10'OnDoc'
+ +'kDrop'#7#12'FormDockDrop'#8'OnUnDock'#7#10'FormUnDock'#14'UseDockManager'#9
+ +#10'LCLVersion'#6#6'0.9.29'#7'Visible'#9#0#6'TImage'#6'Image1'#4'Left'#3'i'#1
+ +#6'Height'#2#16#3'Top'#2#0#5'Width'#2#16#7'Anchors'#11#5'akTop'#7'akRight'#0
+ +#8'AutoSize'#9#12'Picture.Data'#10'H'#1#0#0#5'TIcon>'#1#0#0#0#0#1#0#1#0#16#16
+ +#16#0#0#0#0#0'('#1#0#0#22#0#0#0'('#0#0#0#16#0#0#0' '#0#0#0#1#0#4#0#0#0#0#0
+ +#192#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128
+ +#128#0#128#0#0#0#128#0#128#0#128#128#0#0#128#128#128#0#192#192#192#0#0#0#255
+ +#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#0#0
+#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#153#0#0#0#0#0#0#153#153#153#0#0#0#0#0#153#153#153#0#0#0#0#9
- +#153#153#153#144#0#0#0#9#153#153#153#144#0#0#0#0#153#153#153#0#0#0#0#0#153
- +#153#153#0#0#0#0#0#0#153#0#0#0#0#0#0#0#0#0#0#127#255#0#0#191#255#0#0#223#255
- +#0#0#239#255#0#0#247#255#0#0#251#255#0#0#253#207#0#0#254#3#0#0#254#1#0#0#254
- +#1#0#0#252#0#0#0#252#0#0#0#254#1#0#0#254#1#0#0#255#3#0#0#255#207#0#0#7'Visib'
- +'le'#8#0#0#0
+ +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#153#0#0#0#0#0#0#153#153#153#0#0#0
+ +#0#0#153#153#153#0#0#0#0#9#153#153#153#144#0#0#0#9#153#153#153#144#0#0#0#0
+ +#153#153#153#0#0#0#0#0#153#153#153#0#0#0#0#0#0#153#0#0#0#0#0#0#0#0#0#0#127
+ +#255#0#0#191#255#0#0#223#255#0#0#239#255#0#0#247#255#0#0#251#255#0#0#253#207
+ +#0#0#254#3#0#0#254#1#0#0#254#1#0#0#252#0#0#0#252#0#0#0#254#1#0#0#254#1#0#0
+ +#255#3#0#0#255#207#0#0#7'Visible'#8#0#0#0
]);
diff --git a/examples/dockmanager/package/ffloatingsite.pas b/examples/dockmanager/package/ffloatingsite.pas
index df9150a2b6..dbb9fe9d3c 100644
--- a/examples/dockmanager/package/ffloatingsite.pas
+++ b/examples/dockmanager/package/ffloatingsite.pas
@@ -8,6 +8,10 @@ unit fFloatingSite;
- Disallow TControls to float (else nothing but trouble).
- For the IDE, floating client forms must wrap themselves into a new
host site, to allow for continued docking of other clients.
+
+Problems:
+As with DockBook, closing docked forms results in Exceptions :-(
+
*)
{$mode objfpc}{$H+}
@@ -21,6 +25,7 @@ uses
type
TFloatingSite = class(TForm)
Image1: TImage;
+ procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
procedure FormDockDrop(Sender: TObject; Source: TDragDockObject;
X, Y: Integer);
procedure FormUnDock(Sender: TObject; Client: TControl;
@@ -61,6 +66,44 @@ begin
Caption := s;
end;
+procedure TFloatingSite.FormClose(Sender: TObject;
+ var CloseAction: TCloseAction);
+var
+ i: integer;
+ ctl: TControl;
+ frm: TCustomForm absolute ctl;
+begin
+(* When an empty site is closed, it shall be freed.
+ Otherwise the clients must be handled (close forms).
+
+ Currently closing docked forms leads to exceptions :-(
+*)
+{$IFDEF new}
+ //BeginFormUpdate;
+ for i := DockClientCount - 1 downto 0 do begin
+ ctl := DockClients[i];
+ ctl.ManualDock(nil);
+ //Application.ReleaseComponent(ctl); --- Exception!
+ if ctl <> nil then begin
+ //verify that both Parent and HostDockSite are cleared
+ DebugLn('Undocked %s P=%p H=%p', [ctl.Name,
+ pointer(ctl.Parent), pointer(ctl.HostDockSite)]);
+ //DebugLn('P=%p H=%p', [ctl.Parent, ctl.HostDockSite]);
+ //DebugLn('%x', [self]);
+ end;
+ if ctl is TCustomForm then begin
+ //frm.Close; --- Exception!
+ //frm.Release; --- also Exception!
+ //frm.Hide;
+ end;
+ end;
+ //EndFormUpdate;
+{$ELSE}
+ //not required?
+{$ENDIF}
+ CloseAction := caFree;
+end;
+
procedure TFloatingSite.FormDockDrop(Sender: TObject; Source: TDragDockObject;
X, Y: Integer);
begin
diff --git a/examples/dockmanager/package/umakesite.pas b/examples/dockmanager/package/umakesite.pas
index a019a25a91..4b3f888392 100644
--- a/examples/dockmanager/package/umakesite.pas
+++ b/examples/dockmanager/package/umakesite.pas
@@ -4,7 +4,9 @@ unit uMakeSite;
Owners:
The DockMaster can own all floating forms, for easy enumeration.
The DockMaster can own all dock grips, for easy detection of the dockable forms.
+ Handle destruction how?
The owner of the dockable forms is responsible for creating or finding dockable forms?
+ The auto-created forms are/shall be owned by DockMaster.Owner?
Problems:
@@ -20,8 +22,9 @@ Default floating sites are owned by Application,
{$mode objfpc}{$H+}
-{$DEFINE ownSites} //floating sites owned by TDockMaster?
-{$DEFINE ownGrips} //docking grips owned by TDockMaster?
+{$DEFINE ownSites} //floating sites owned by DockMaster?
+{$DEFINE ownForms} //dockable forms owned by owner of DockMaster
+{$DEFINE ownGrips} //docking grips owned by DockMaster?
interface
@@ -55,11 +58,15 @@ type
procedure DockHandleMouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
procedure FormEndDock(Sender, Target: TObject; X, Y: Integer);
+ protected //utilities
+ function ReloadForm(const AName: string): TCustomForm; virtual;
function WrapDockable(Client: TControl): TFloatingSite;
+ private
+ LastSite: TFloatingSite;
public
- Factory: TComponent; //generic owner
+ Factory: TWinControl; //generic owner
procedure AddElasticSites(AForm: TCustomForm; Sides: sDockSides);
- function CreateDockable(const AName: string; fMultiInst: boolean; fWrap: boolean = True): TForm;
+ function CreateDockable(const AName: string; fMultiInst: boolean; fWrap: boolean = True): TCustomForm;
procedure DumpSites;
procedure LoadFromStream(Stream: TStream);
procedure SaveToStream(Stream: TStream);
@@ -117,7 +124,8 @@ begin
spl := TSplitter.Create(AForm);
spl.Parent := AForm;
spl.Align := side;
- spl.BorderStyle := bsSingle;
+ //spl.BorderStyle := bsSingle;
+ spl.Beveled := True;
//size components
pnl.Splitter := spl;
if side in [alLeft,alRight] then
@@ -135,81 +143,37 @@ begin
end;
function TDockMaster.CreateDockable(const AName: string;
- fMultiInst: boolean; fWrap: boolean): TForm;
+ fMultiInst: boolean; fWrap: boolean): TCustomForm;
var
- basename, instname: string;
- i, l, instno: integer;
- fc: TFormClass;
img: TImage;
r: TRect;
Site: TFloatingSite;
- ctl: TControl;
-const
- digits = ['0'..'9'];
+ Res: TWinControlAccess absolute Result;
begin
(* Create a dockable form, based on its name.
Used also to restore a layout.
+
+Options (to come or to be removed)
fMultiInst allows to auto-create new versions (if True),
otherwise an already existing instance is returned. (really returned?)
-
- The name is split into basename and instance number.
- A component of T is created (and named AName - automatic!).
*)
- if AName = '' then begin
- //test!
- Result := TForm.Create(self); //named Form1, Form2...
- end else begin
- //basename := AName;
- //find the instance number, if present
- instno := 0;
- l := Length(AName);
- i := l;
- while AName[i] in digits do begin
- dec(i);
- end;
- //i now is the position of the last non-digit in the name
- //extract the instance number
- basename := Copy(AName, 1, i);
- while i < l do begin
- inc(i);
- instno := instno * 10 + ord(AName[i])-ord('0');
- end;
- if instno = 0 then
- instno := 1; //default instance number for forms
- //lookup existing instance
- instname := basename + IntToStr(instno);
- {$IFDEF old}
- if false then
- TWinControlAccess(Site).ReloadDockedControl(instname, ctl);
- //Result := nil;
- for i := 0 to ComponentCount - 1 do begin
- Result := TForm(Components[i]);
- if Result.Name = instname then
- exit; //found it
- end;
- {$ELSE}
- //Factory.ReloadDockedControl
- {$ENDIF}
- if FindComponent(instname) <> nil then
- exit;
- //create new instance
- basename := 'T' + basename;
- fc := TFormClass(GetClass(basename)); //must be registered class name!
- if not assigned(fc) then
- exit;
- Result := fc.Create(self);
- if Result.Name <> AName then
- Result.Name := AName; //???
- end;
- if Result.DragKind <> dkDock then begin
+//get the form
+ Result := ReloadForm(AName);
+ if Result = nil then
+ exit;
+//check make dockable
+ if Res.DragKind <> dkDock then begin
//make it dockable
- Result.DragKind := dkDock;
- Result.OnEndDock := @FormEndDock; //float into default host site
+ Res.DragKind := dkDock;
+ Res.OnEndDock := @FormEndDock; //float into default host site
end;
+//wrap into floating site, if requested (not on restore Layout)
if fWrap then begin
//wrap into dock site
Site := WrapDockable(Result);
- //create a docking handle - should become a component?
+ end;
+//create a docking handle - should become a component?
+ if LastSite <> nil then begin //problem: find grabber picture!?
img := TImage.Create(Result); //we could own the img, and be notified when its parent becomes nil
img.Parent := Result;
img.Align := alNone;
@@ -218,12 +182,11 @@ begin
r.bottom := 16;
r.Left := r.Right - 16;
img.BoundsRect := r;
- img.Picture := Site.Image1.Picture;
+ img.Picture := LastSite.Image1.Picture;
img.OnMouseMove := @DockHandleMouseMove;
img.Visible := True;
end;
Result.Visible := True;
- //Result.OnEndDock();
end;
procedure TDockMaster.FormEndDock(Sender, Target: TObject; X, Y: Integer);
@@ -249,6 +212,7 @@ procedure TDockMaster.LoadFromStream(Stream: TStream);
var
ctl, pre: TControl;
site: TFloatingSite;
+ nb: TEasyBook;
procedure MakeForm;
begin
@@ -257,12 +221,33 @@ var
end;
begin
- //Test0;
+(* Restore a layout.
+- Create all ElasticSites (to come)
+- Create all floating sites
+- Reload all docked controls
+
+Notebooks?
+ In the simple case a notebook is created automatically, by docking a control
+ with align=alCustom.
+ In order to maintain proper docking we'll have to create and name the notebooks
+ before, then create and dock all their clients.
+ Ownership?
+ When notebooks are dockable, they cannot be owned by the DockSite!
+*)
+//Test0;
site := TFloatingSite.Create(self);
MakeForm; ctl.ManualDock(site, nil, alClient);
MakeForm; ctl.ManualDock(site, pre, alRight);
- MakeForm; ctl.ManualDock(site, pre, alBottom);
- //MakeForm; ctl.ManualDock(site, pre, alCustom);
+ if False then begin //simple case
+ MakeForm; ctl.ManualDock(site, pre, alBottom);
+ MakeForm; ctl.ManualDock(site, pre, alCustom);
+ end else begin
+ nb := NoteBookCreate(site); //name it...
+ nb.ManualDock(site, ctl, alBottom);
+ //MakeForm; NoteBookAdd(nb, ctl);
+ MakeForm; ctl.ManualDock(site, nb, alCustom);
+ MakeForm; ctl.ManualDock(site, nb, alCustom);
+ end;
end;
procedure TDockMaster.SaveToStream(Stream: TStream);
@@ -270,15 +255,82 @@ begin
end;
+function TDockMaster.ReloadForm(const AName: string): TCustomForm;
+var
+ basename, instname: string;
+ i, l, instno: integer;
+ fc: TFormClass;
+ fo: TComponent; //form owner
+ ctl: TControl;
+const
+ digits = ['0'..'9'];
+begin
+(* Get a form from the Factory, or search/create it.
+
+ The name is split into basename and instance number.
+ A component of T is created (and named AName - automatic!).
+*)
+ Result := nil;
+//check if Factory can provide the form
+ if assigned(Factory) then begin
+ TWinControlAccess(Factory).ReloadDockedControl(AName, ctl);
+ if ctl is TCustomForm then begin
+ Result := TCustomForm(ctl);
+ exit;
+ end; //else assume that we should do everything?
+ FreeAndNil(ctl);
+ end;
+//search/create ourselves
+{$IFDEF ownForms}
+ fo := Owner; //our owner also owns the forms
+{$ELSE}
+ fo := Self; //we own the forms
+{$ENDIF}
+ if AName = '' then begin
+ //test!
+ Result := TForm.Create(fo); //named Form1, Form2...
+ end else begin
+ //find the instance number, if present
+ instno := 0;
+ l := Length(AName);
+ i := l;
+ while AName[i] in digits do begin
+ dec(i);
+ end;
+ //i now is the position of the last non-digit in the name
+ //extract the instance number
+ basename := Copy(AName, 1, i);
+ while i < l do begin
+ inc(i);
+ instno := instno * 10 + ord(AName[i])-ord('0');
+ end;
+ if instno = 0 then
+ instno := 1; //default instance number for forms
+ //lookup existing instance
+ instname := basename + IntToStr(instno);
+ if fo.FindComponent(instname) <> nil then
+ exit;
+ //create new instance
+ basename := 'T' + basename;
+ fc := TFormClass(GetClass(basename)); //must be registered class name!
+ if not assigned(fc) then
+ exit;
+ Result := fc.Create(fo);
+ if Result.Name <> AName then
+ Result.Name := AName; //???
+ end;
+end;
+
function TDockMaster.WrapDockable(Client: TControl): TFloatingSite;
var
- Site: TForm absolute Result;
+ Site: TFloatingSite absolute Result;
begin
{$IFDEF ownSites}
Site := TFloatingSite.Create(Self); //the new site
{$ELSE}
Site := TFloatingSite.Create(Application); //the new site
{$ENDIF}
+ LastSite := Site;
Site.BoundsRect := Client.BoundsRect; //the new position and extension
Client.Align := alClient;
Client.Visible := True; //otherwise docking may be rejected
@@ -301,13 +353,6 @@ begin
end;
procedure TDockMaster.DumpSites;
-var
- i, j: integer;
- Site: TWinControl;
- ctl: TControl;
- cmp: TComponent;
- n, s: string;
- hds: boolean;
const
OrientString: array[TDockOrientation] of char = (
'N','H','V' {$IFDEF FPC} ,'P' {$ENDIF}
@@ -326,6 +371,56 @@ const
Result := '<' + ph.ClassName + '>';
end;
+ procedure DumpSite(ASite: TWinControl);
+ var
+ ctl: TControl;
+ wc: TWinControl absolute ctl;
+ n, s: string;
+ hds: boolean;
+ Site: TWinControl;
+ j: integer;
+ begin
+ ctl := ASite;
+ s := Format('Site=%s (%d,%d)[%d,%d]', [SiteName(ctl),
+ ctl.Left, ctl.Top, ctl.Width, ctl.Height]);
+ while ctl <> nil do begin
+ hds := ctl.HostDockSite <> nil;
+ if hds then begin
+ Site := ctl.HostDockSite;
+ if Site <> nil then
+ n := ' in ' + SiteName(Site) + '@' + OrientString[ctl.DockOrientation];
+ end else begin
+ Site := ctl.Parent;
+ if Site <> nil then
+ n := ' at ' + SiteName(Site) + '@' + AlignString[ctl.Align];
+ end;
+ if Site = nil then
+ break;
+ s := s + n;
+ ctl := Site;
+ end;
+ DebugLn(s);
+ //clients
+ Site := ASite;
+ for j := 0 to Site.DockClientCount - 1 do begin
+ ctl := site.DockClients[j];
+ s := OrientString[ctl.DockOrientation];
+ DebugLn(' %s.Client=%s@%s (%d,%d)[%d,%d]', [SiteName(ASite), SiteName(ctl), s,
+ ctl.Left, ctl.Top, ctl.Width, ctl.Height]);
+ //if ctl is TFloatingSite then
+ if (ctl is TWinControl) and wc.DockSite then
+ DumpSite(wc);
+ end;
+ end;
+
+var
+ i, j: integer;
+ //Site: TWinControl;
+ cmp: TComponent;
+ wc: TWinControl absolute cmp;
+ ctl: TControl absolute cmp;
+ n, s: string;
+ hds: boolean;
begin
(* Dump registered docking sites.
Elastic panels have no name.
@@ -340,6 +435,14 @@ begin
DebugLn('--- dump sites ---');
for i := 0 to ComponentCount - 1 do begin
cmp := Components[i];
+ {$IFnDEF old}
+ if (cmp is TWinControl) and wc.DockSite then
+ DumpSite(wc)
+ else if ctl is TControl then begin
+ DebugLn('Client=%s in %s (%d,%d)[%d,%d]', [SiteName(ctl), SiteName(ctl.HostDockSite),
+ ctl.Left, ctl.Top, ctl.Width, ctl.Height]);
+ end;
+ {$ELSE}
if cmp is TWinControl then begin
//path
Site := TWinControl(cmp);
@@ -380,6 +483,7 @@ begin
ctl.Left, ctl.Top, ctl.Width, ctl.Height]);
end;
end;
+ {$ENDIF}
end;
DebugLn('--- end dump ---');
end;