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;