dockmanager example: updated Factory, owners, notebook docking

git-svn-id: trunk@22749 -
This commit is contained in:
dodi 2009-11-24 12:59:34 +00:00
parent 6e03051421
commit 7900c21415
9 changed files with 441 additions and 234 deletions

View File

@ -8,7 +8,7 @@
<TargetFileExt Value=".exe"/>
<Icon Value="0"/>
<UseXPManifest Value="True"/>
<ActiveEditorIndexAtStart Value="4"/>
<ActiveEditorIndexAtStart Value="3"/>
</General>
<VersionInfo>
<ProjectVersion Value=""/>
@ -33,14 +33,14 @@
<PackageName Value="LCL"/>
</Item2>
</RequiredPackages>
<Units Count="34">
<Units Count="40">
<Unit0>
<Filename Value="MakeSite.lpr"/>
<IsPartOfProject Value="True"/>
<UnitName Value="MakeSite"/>
<CursorPos X="51" Y="18"/>
<TopLine Value="1"/>
<UsageCount Value="80"/>
<UsageCount Value="87"/>
</Unit0>
<Unit1>
<Filename Value="fmastersite.pas"/>
@ -51,25 +51,29 @@
<CursorPos X="1" Y="51"/>
<TopLine Value="23"/>
<EditorIndex Value="0"/>
<UsageCount Value="80"/>
<UsageCount Value="87"/>
<Loaded Value="True"/>
</Unit1>
<Unit2>
<Filename Value="..\package\umakesite.pas"/>
<UnitName Value="uMakeSite"/>
<CursorPos X="1" Y="126"/>
<TopLine Value="105"/>
<CursorPos X="1" Y="247"/>
<TopLine Value="214"/>
<EditorIndex Value="3"/>
<UsageCount Value="74"/>
<UsageCount Value="77"/>
<Bookmarks Count="2">
<Item0 X="1" Y="165" ID="1"/>
<Item1 X="1" Y="275" ID="2"/>
</Bookmarks>
<Loaded Value="True"/>
</Unit2>
<Unit3>
<Filename Value="..\..\..\lcl\controls.pp"/>
<UnitName Value="Controls"/>
<CursorPos X="15" Y="1757"/>
<TopLine Value="1733"/>
<EditorIndex Value="7"/>
<UsageCount Value="39"/>
<CursorPos X="15" Y="1242"/>
<TopLine Value="1218"/>
<EditorIndex Value="9"/>
<UsageCount Value="42"/>
<Loaded Value="True"/>
</Unit3>
<Unit4>
@ -91,10 +95,10 @@
</Unit5>
<Unit6>
<Filename Value="..\..\..\..\..\lazarus\fpc\2.2.4\source\rtl\objpas\classes\classesh.inc"/>
<CursorPos X="14" Y="1556"/>
<TopLine Value="1533"/>
<EditorIndex Value="10"/>
<UsageCount Value="14"/>
<CursorPos X="3" Y="1458"/>
<TopLine Value="1468"/>
<EditorIndex Value="6"/>
<UsageCount Value="16"/>
<Loaded Value="True"/>
</Unit6>
<Unit7>
@ -106,7 +110,7 @@
<UnitName Value="fClientForm"/>
<CursorPos X="10" Y="38"/>
<TopLine Value="12"/>
<UsageCount Value="80"/>
<UsageCount Value="87"/>
</Unit7>
<Unit8>
<Filename Value="..\..\..\lcl\include\winapih.inc"/>
@ -129,31 +133,26 @@
<Unit11>
<Filename Value="..\package\easydocksite.pas"/>
<UnitName Value="EasyDockSite"/>
<CursorPos X="1" Y="364"/>
<TopLine Value="341"/>
<CursorPos X="3" Y="303"/>
<TopLine Value="301"/>
<EditorIndex Value="4"/>
<UsageCount Value="38"/>
<Bookmarks Count="1">
<Item0 X="3" Y="365" ID="2"/>
</Bookmarks>
<UsageCount Value="41"/>
<Loaded Value="True"/>
</Unit11>
<Unit12>
<Filename Value="..\..\..\lcl\forms.pp"/>
<UnitName Value="Forms"/>
<CursorPos X="17" Y="532"/>
<TopLine Value="509"/>
<CursorPos X="17" Y="647"/>
<TopLine Value="624"/>
<EditorIndex Value="1"/>
<UsageCount Value="34"/>
<UsageCount Value="37"/>
<Loaded Value="True"/>
</Unit12>
<Unit13>
<Filename Value="..\..\..\lcl\include\customform.inc"/>
<CursorPos X="17" Y="1593"/>
<TopLine Value="1571"/>
<EditorIndex Value="14"/>
<UsageCount Value="19"/>
<Loaded Value="True"/>
<UsageCount Value="20"/>
</Unit13>
<Unit14>
<Filename Value="..\..\..\..\..\lazarus\fpc\2.2.4\source\rtl\inc\objpash.inc"/>
@ -186,10 +185,10 @@
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="fFloatingSite"/>
<CursorPos X="9" Y="107"/>
<TopLine Value="64"/>
<CursorPos X="1" Y="14"/>
<TopLine Value="1"/>
<EditorIndex Value="2"/>
<UsageCount Value="36"/>
<UsageCount Value="39"/>
<Loaded Value="True"/>
</Unit18>
<Unit19>
@ -198,10 +197,10 @@
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="fDockBook"/>
<CursorPos X="1" Y="1"/>
<TopLine Value="1"/>
<EditorIndex Value="6"/>
<UsageCount Value="34"/>
<CursorPos X="1" Y="132"/>
<TopLine Value="121"/>
<EditorIndex Value="7"/>
<UsageCount Value="37"/>
<Loaded Value="True"/>
</Unit19>
<Unit20>
@ -247,48 +246,38 @@
<Filename Value="..\..\..\..\..\lazarus\fpc\2.2.4\source\rtl\objpas\classes\compon.inc"/>
<CursorPos X="3" Y="161"/>
<TopLine Value="158"/>
<EditorIndex Value="11"/>
<UsageCount Value="14"/>
<Loaded Value="True"/>
<UsageCount Value="15"/>
</Unit25>
<Unit26>
<Filename Value="..\..\..\lcl\include\control.inc"/>
<CursorPos X="3" Y="540"/>
<TopLine Value="525"/>
<EditorIndex Value="13"/>
<UsageCount Value="24"/>
<Loaded Value="True"/>
<CursorPos X="3" Y="3876"/>
<TopLine Value="3836"/>
<UsageCount Value="25"/>
</Unit26>
<Unit27>
<Filename Value="..\..\..\lcl\include\wincontrol.inc"/>
<CursorPos X="3" Y="6514"/>
<TopLine Value="6468"/>
<EditorIndex Value="9"/>
<UsageCount Value="24"/>
<Loaded Value="True"/>
<UsageCount Value="25"/>
</Unit27>
<Unit28>
<Filename Value="..\..\..\lcl\include\dragdock.inc"/>
<CursorPos X="10" Y="21"/>
<TopLine Value="1"/>
<EditorIndex Value="16"/>
<UsageCount Value="24"/>
<Loaded Value="True"/>
<UsageCount Value="25"/>
</Unit28>
<Unit29>
<Filename Value="..\..\..\lcl\include\dragmanager.inc"/>
<CursorPos X="1" Y="730"/>
<TopLine Value="687"/>
<EditorIndex Value="12"/>
<UsageCount Value="19"/>
<Loaded Value="True"/>
<UsageCount Value="20"/>
</Unit29>
<Unit30>
<Filename Value="..\..\..\lcl\include\application.inc"/>
<CursorPos X="1" Y="2074"/>
<TopLine Value="2051"/>
<EditorIndex Value="15"/>
<UsageCount Value="19"/>
<CursorPos X="1" Y="2076"/>
<TopLine Value="2053"/>
<EditorIndex Value="8"/>
<UsageCount Value="22"/>
<Loaded Value="True"/>
</Unit30>
<Unit31>
@ -301,143 +290,177 @@
<Filename Value="..\..\..\lcl\include\customcontrol.inc"/>
<CursorPos X="17" Y="113"/>
<TopLine Value="92"/>
<EditorIndex Value="8"/>
<UsageCount Value="10"/>
<Loaded Value="True"/>
<UsageCount Value="11"/>
</Unit32>
<Unit33>
<Filename Value="..\package\zoneheader.inc"/>
<CursorPos X="41" Y="168"/>
<TopLine Value="145"/>
<EditorIndex Value="5"/>
<UsageCount Value="10"/>
<Bookmarks Count="1">
<Item0 X="41" Y="168" ID="1"/>
</Bookmarks>
<UsageCount Value="13"/>
<Loaded Value="True"/>
</Unit33>
<Unit34>
<Filename Value="..\..\..\lcl\lclproc.pas"/>
<UnitName Value="LCLProc"/>
<CursorPos X="1" Y="2109"/>
<TopLine Value="2086"/>
<EditorIndex Value="10"/>
<UsageCount Value="12"/>
<Loaded Value="True"/>
</Unit34>
<Unit35>
<Filename Value="..\..\..\..\..\lazarus\fpc\2.2.4\source\rtl\objpas\sysutils\sysstrh.inc"/>
<CursorPos X="29" Y="123"/>
<TopLine Value="123"/>
<EditorIndex Value="11"/>
<UsageCount Value="12"/>
<Loaded Value="True"/>
</Unit35>
<Unit36>
<Filename Value="..\..\..\..\..\lazarus\fpc\2.2.4\source\rtl\objpas\sysutils\sysstr.inc"/>
<CursorPos X="11" Y="915"/>
<TopLine Value="914"/>
<EditorIndex Value="12"/>
<UsageCount Value="12"/>
<Loaded Value="True"/>
</Unit36>
<Unit37>
<Filename Value="..\..\..\..\..\lazarus\fpc\2.2.4\source\rtl\objpas\sysutils\sysformt.inc"/>
<CursorPos X="12" Y="115"/>
<TopLine Value="97"/>
<EditorIndex Value="13"/>
<UsageCount Value="12"/>
<Loaded Value="True"/>
</Unit37>
<Unit38>
<Filename Value="..\..\..\lcl\ldockctrl.pas"/>
<UnitName Value="LDockCtrl"/>
<CursorPos X="1" Y="40"/>
<TopLine Value="19"/>
<UsageCount Value="10"/>
</Unit38>
<Unit39>
<Filename Value="..\..\..\components\jcf2\Utils\Delay.pas"/>
<UnitName Value="Delay"/>
<CursorPos X="16" Y="62"/>
<TopLine Value="53"/>
<UsageCount Value="10"/>
</Unit39>
</Units>
<JumpHistory Count="30" HistoryIndex="29">
<JumpHistory Count="28" HistoryIndex="26">
<Position1>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="249" Column="23" TopLine="244"/>
<Filename Value="..\package\fdockbook.pas"/>
<Caret Line="143" Column="1" TopLine="119"/>
</Position1>
<Position2>
<Filename Value="..\package\ffloatingsite.pas"/>
<Caret Line="107" Column="9" TopLine="64"/>
<Filename Value="..\package\fdockbook.pas"/>
<Caret Line="144" Column="1" TopLine="120"/>
</Position2>
<Position3>
<Filename Value="..\package\easydocksite.pas"/>
<Caret Line="555" Column="29" TopLine="526"/>
<Filename Value="..\package\fdockbook.pas"/>
<Caret Line="145" Column="1" TopLine="121"/>
</Position3>
<Position4>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="65" Column="28" TopLine="38"/>
<Filename Value="..\package\fdockbook.pas"/>
<Caret Line="146" Column="1" TopLine="122"/>
</Position4>
<Position5>
<Filename Value="..\package\fdockbook.pas"/>
<Caret Line="143" Column="20" TopLine="124"/>
<Caret Line="147" Column="1" TopLine="123"/>
</Position5>
<Position6>
<Filename Value="fmastersite.pas"/>
<Caret Line="50" Column="17" TopLine="15"/>
<Filename Value="..\package\fdockbook.pas"/>
<Caret Line="148" Column="1" TopLine="124"/>
</Position6>
<Position7>
<Filename Value="fmastersite.pas"/>
<Caret Line="51" Column="17" TopLine="15"/>
<Filename Value="..\package\fdockbook.pas"/>
<Caret Line="143" Column="1" TopLine="119"/>
</Position7>
<Position8>
<Filename Value="fmastersite.pas"/>
<Caret Line="50" Column="17" TopLine="15"/>
<Filename Value="..\package\fdockbook.pas"/>
<Caret Line="151" Column="5" TopLine="119"/>
</Position8>
<Position9>
<Filename Value="fmastersite.pas"/>
<Caret Line="57" Column="17" TopLine="15"/>
<Filename Value="..\package\ffloatingsite.pas"/>
<Caret Line="88" Column="19" TopLine="58"/>
</Position9>
<Position10>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="253" Column="23" TopLine="232"/>
<Filename Value="..\package\ffloatingsite.pas"/>
<Caret Line="75" Column="1" TopLine="62"/>
</Position10>
<Position11>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="62" Column="96" TopLine="39"/>
<Caret Line="374" Column="68" TopLine="351"/>
</Position11>
<Position12>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="256" Column="18" TopLine="237"/>
<Caret Line="402" Column="7" TopLine="391"/>
</Position12>
<Position13>
<Filename Value="..\package\fdockbook.pas"/>
<Caret Line="90" Column="15" TopLine="66"/>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="267" Column="18" TopLine="259"/>
</Position13>
<Position14>
<Filename Value="..\package\fdockbook.pas"/>
<Caret Line="87" Column="12" TopLine="74"/>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="165" Column="10" TopLine="143"/>
</Position14>
<Position15>
<Filename Value="..\package\fdockbook.pas"/>
<Caret Line="98" Column="26" TopLine="74"/>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="164" Column="18" TopLine="143"/>
</Position15>
<Position16>
<Filename Value="..\package\fdockbook.pas"/>
<Caret Line="143" Column="30" TopLine="119"/>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="144" Column="52" TopLine="143"/>
</Position16>
<Position17>
<Filename Value="..\package\fdockbook.pas"/>
<Caret Line="275" Column="36" TopLine="251"/>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="62" Column="25" TopLine="44"/>
</Position17>
<Position18>
<Filename Value="..\package\fdockbook.pas"/>
<Caret Line="1" Column="1" TopLine="1"/>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="220" Column="20" TopLine="212"/>
</Position18>
<Position19>
<Filename Value="..\package\easydocksite.pas"/>
<Caret Line="565" Column="1" TopLine="598"/>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="268" Column="24" TopLine="243"/>
</Position19>
<Position20>
<Filename Value="..\package\easydocksite.pas"/>
<Caret Line="228" Column="14" TopLine="206"/>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="327" Column="1" TopLine="281"/>
</Position20>
<Position21>
<Filename Value="..\package\easydocksite.pas"/>
<Caret Line="363" Column="17" TopLine="339"/>
<Caret Line="558" Column="27" TopLine="521"/>
</Position21>
<Position22>
<Filename Value="..\package\easydocksite.pas"/>
<Caret Line="371" Column="1" TopLine="339"/>
<Caret Line="240" Column="1" TopLine="225"/>
</Position22>
<Position23>
<Filename Value="..\package\easydocksite.pas"/>
<Caret Line="380" Column="23" TopLine="339"/>
<Caret Line="278" Column="1" TopLine="254"/>
</Position23>
<Position24>
<Filename Value="..\package\easydocksite.pas"/>
<Caret Line="786" Column="40" TopLine="763"/>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="242" Column="19" TopLine="208"/>
</Position24>
<Position25>
<Filename Value="..\package\zoneheader.inc"/>
<Caret Line="168" Column="41" TopLine="143"/>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="265" Column="1" TopLine="219"/>
</Position25>
<Position26>
<Filename Value="..\package\easydocksite.pas"/>
<Caret Line="169" Column="7" TopLine="148"/>
<Caret Line="257" Column="25" TopLine="234"/>
</Position26>
<Position27>
<Filename Value="..\package\easydocksite.pas"/>
<Caret Line="228" Column="14" TopLine="205"/>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="247" Column="22" TopLine="213"/>
</Position27>
<Position28>
<Filename Value="..\package\zoneheader.inc"/>
<Caret Line="168" Column="43" TopLine="145"/>
<Filename Value="..\package\easydocksite.pas"/>
<Caret Line="303" Column="3" TopLine="301"/>
</Position28>
<Position29>
<Filename Value="fmastersite.pas"/>
<Caret Line="51" Column="1" TopLine="23"/>
</Position29>
<Position30>
<Filename Value="fmastersite.pas"/>
<Caret Line="52" Column="1" TopLine="23"/>
</Position30>
</JumpHistory>
</ProjectOptions>
<CompilerOptions>

View File

@ -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;

View File

@ -8,6 +8,7 @@ object EasyDockBook: TEasyDockBook
ClientWidth = 400
DockSite = True
DragKind = dkDock
OnClose = FormClose
OnCreate = FormCreate
OnDockDrop = FormDockDrop
OnDockOver = FormDockOver

View File

@ -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
]);

View File

@ -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);

View File

@ -7,6 +7,7 @@ object FloatingSite: TFloatingSite
ClientHeight = 265
ClientWidth = 377
DockSite = True
OnClose = FormClose
OnDockDrop = FormDockDrop
OnUnDock = FormUnDock
UseDockManager = True

View File

@ -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
]);

View File

@ -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

View File

@ -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<basename> 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<basename> 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;