dockmanager example: added MiniIDE demo, updated layout persistence.

git-svn-id: trunk@23116 -
This commit is contained in:
dodi 2009-12-13 09:46:20 +00:00
parent d89894ca1e
commit 2e8aaf5beb
27 changed files with 6968 additions and 284 deletions

13
.gitattributes vendored
View File

@ -2805,6 +2805,19 @@ examples/dockmanager/elasticsite/feditorsite.lrs svneol=native#text/plain
examples/dockmanager/elasticsite/feditorsite.pas svneol=native#text/pascal examples/dockmanager/elasticsite/feditorsite.pas svneol=native#text/pascal
examples/dockmanager/elasticsite/fmastersite.lfm svneol=native#text/plain examples/dockmanager/elasticsite/fmastersite.lfm svneol=native#text/plain
examples/dockmanager/elasticsite/fmastersite.pas svneol=native#text/pascal examples/dockmanager/elasticsite/fmastersite.pas svneol=native#text/pascal
examples/dockmanager/ide_demo/MiniIDE.ico -text
examples/dockmanager/ide_demo/MiniIDE.lpi svneol=native#text/plain
examples/dockmanager/ide_demo/MiniIDE.lpr svneol=native#text/plain
examples/dockmanager/ide_demo/fclientform.lfm svneol=native#text/plain
examples/dockmanager/ide_demo/fclientform.lrs svneol=native#text/plain
examples/dockmanager/ide_demo/fclientform.pas svneol=native#text/plain
examples/dockmanager/ide_demo/feditbook.lfm svneol=native#text/plain
examples/dockmanager/ide_demo/feditbook.lrs svneol=native#text/plain
examples/dockmanager/ide_demo/feditbook.pas svneol=native#text/plain
examples/dockmanager/ide_demo/fminiide.lfm svneol=native#text/plain
examples/dockmanager/ide_demo/fminiide.lrs svneol=native#text/plain
examples/dockmanager/ide_demo/fminiide.pas svneol=native#text/plain
examples/dockmanager/ide_demo/miniide.lrs svneol=native#text/plain
examples/dockmanager/package/easy_dock_images.lrs svneol=native#text/pascal examples/dockmanager/package/easy_dock_images.lrs svneol=native#text/pascal
examples/dockmanager/package/easydocking.pas svneol=native#text/pascal examples/dockmanager/package/easydocking.pas svneol=native#text/pascal
examples/dockmanager/package/easydockmgr.lpk svneol=native#text/plain examples/dockmanager/package/easydockmgr.lpk svneol=native#text/plain

1
.gitignore vendored
View File

@ -238,6 +238,7 @@ examples/designerbaseclass/example/units
examples/designerbaseclass/lib/*.bak examples/designerbaseclass/lib/*.bak
examples/designerbaseclass/lib/units examples/designerbaseclass/lib/units
examples/designerbaseclass/units examples/designerbaseclass/units
examples/dockmanager/ide_demo/MiniIDE.rc
examples/dropfiles/units[!!-~]*.bak examples/dropfiles/units[!!-~]*.bak
examples/easter/*.bak examples/easter/*.bak
examples/easter/units examples/easter/units

View File

@ -23,18 +23,27 @@ elasticsite/project1
demonstrates elastic dock sites, which become visible only after a control demonstrates elastic dock sites, which become visible only after a control
has been docked into them. has been docked into them.
elasticsite/SiteTest
====================
demonstrates elastic panels and dockable forms.
elasticsite/MakeSite
====================
demonstrates persistent layouts, using default features.
For special forms see ide_demo/MiniIDE
ide_demo/MiniIDE
================
A Lazarus-like IDE with:
- dockable windows
- multiple editor forms
- persistent layouts with special form handling
Loading a layout should not affect files in the editors, because these are project specific. This can result in empty editor windows, for now.
More features to come...
toolbar/test1 toolbar/test1
============= =============
mainly demonstrates TToolBar/TToolButton related problems. mainly demonstrates TToolBar/TToolButton related problems.
(see provided patches) (see provided patches)
-------
In prepraration:
ide_demo
========
A Lazarus-like IDE, with dockable windows.
Shall demonstrate the use of dockable windows, multi-page editor,
elastic dock sites, flexible component palette (old/new Delphi style).
Also shall allow to store/reload a layout.

View File

@ -1,6 +1,6 @@
inherited EditBook: TEditBook inherited EditBook: TEditBook
Left = 413 Left = 670
Top = 306 Top = 115
Caption = 'EditBook' Caption = 'EditBook'
OnActivate = FormActivate OnActivate = FormActivate
OnClose = FormClose OnClose = FormClose

View File

@ -11,15 +11,22 @@ unit fEditBook;
{$mode objfpc}{$H+} {$mode objfpc}{$H+}
{ TODO : figure out what's wrong with the mru list - with multiple windows } { TODO : figure out what's wrong with the mru list - with multiple windows }
{.$DEFINE mru} //problems with MRU list??? {$DEFINE mru} //problems with MRU list???
interface interface
uses uses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
SynEdit,
fDockBook; fDockBook;
type type
TEditPage = class(TSynEdit)
public
FileName: string;
procedure LoadFile(const AName: string);
end;
TEditBook = class(TEasyDockBook) TEditBook = class(TEasyDockBook)
procedure FormActivate(Sender: TObject); procedure FormActivate(Sender: TObject);
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction); procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
@ -28,7 +35,8 @@ type
protected protected
NRUEdit: TEditBook; //Next Recently Used EditBook NRUEdit: TEditBook; //Next Recently Used EditBook
public public
{ public declarations } constructor Create(TheOwner: TComponent); override;
function OpenFile(const AName: string): boolean;
end; end;
var var
@ -36,8 +44,17 @@ var
implementation implementation
uses
uMakeSite;
{ TEditBook } { TEditBook }
constructor TEditBook.Create(TheOwner: TComponent);
begin
inherited Create(TheOwner);
DockMaster.AddElasticSites(self, [alLeft, alRight, alBottom]);
end;
procedure TEditBook.FormActivate(Sender: TObject); procedure TEditBook.FormActivate(Sender: TObject);
var var
prev: TEditBook; prev: TEditBook;
@ -78,6 +95,23 @@ begin
{$ENDIF} {$ENDIF}
end; end;
function TEditBook.OpenFile(const AName: string): boolean;
var
se: TEditPage;
begin
se := TEditPage.Create(Owner);
se.ManualDock(self);
se.LoadFile(AName);
end;
{ TEditPage }
procedure TEditPage.LoadFile(const AName: string);
begin
FileName := AName;
Lines.LoadFromFile(AName);
end;
initialization initialization
{$I feditbook.lrs} {$I feditbook.lrs}

View File

@ -1,6 +1,7 @@
inherited EditorSite: TEditorSite inherited EditorSite: TEditorSite
Left = 354 Left = 354
Height = 300 Height = 300
Top = 156
Width = 400 Width = 400
Caption = 'EditorSite' Caption = 'EditorSite'
ClientHeight = 281 ClientHeight = 281

View File

@ -1,40 +1,40 @@
{ This is an automatically generated lazarus resource file } { This is an automatically generated lazarus resource file }
LazarusResources.Add('TEditorSite','FORMDATA',[ LazarusResources.Add('TEditorSite','FORMDATA',[
'TPF0'#241#11'TEditorSite'#10'EditorSite'#4'Left'#3'b'#1#6'Height'#3','#1#5'W' 'TPF0'#241#11'TEditorSite'#10'EditorSite'#4'Left'#3'b'#1#6'Height'#3','#1#3'T'
+'idth'#3#144#1#7'Caption'#6#10'EditorSite'#12'ClientHeight'#3#25#1#11'Client' +'op'#3#156#0#5'Width'#3#144#1#7'Caption'#6#10'EditorSite'#12'ClientHeight'#3
+'Width'#3#144#1#4'Menu'#7#9'MainMenu1'#10'OnActivate'#7#12'FormActivate'#8'O' +#25#1#11'ClientWidth'#3#144#1#4'Menu'#7#9'MainMenu1'#10'OnActivate'#7#12'For'
+'nCreate'#7#10'FormCreate'#12'OnDeactivate'#7#14'FormDeactivate'#6'OnHide'#7 +'mActivate'#8'OnCreate'#7#10'FormCreate'#12'OnDeactivate'#7#14'FormDeactivat'
+#8'FormHide'#8'OnResize'#7#10'FormResize'#19'OnWindowStateChange'#7#21'FormW' +'e'#6'OnHide'#7#8'FormHide'#8'OnResize'#7#10'FormResize'#19'OnWindowStateCha'
+'indowStateChange'#0#241#6'TPanel'#7'pnlLeft'#6'Height'#3#0#1#0#0#241#9'TSpl' +'nge'#7#21'FormWindowStateChange'#0#241#6'TPanel'#7'pnlLeft'#6'Height'#3#0#1
+'itter'#9'splitLeft'#6'Height'#3#0#1#0#0#241#6'TPanel'#8'pnlRight'#4'Left'#3 +#0#0#241#9'TSplitter'#9'splitLeft'#6'Height'#3#0#1#0#0#241#6'TPanel'#8'pnlRi'
+#144#1#6'Height'#3#0#1#0#0#241#6'TPanel'#9'pnlBottom'#3'Top'#3#4#1#5'Width'#3 +'ght'#4'Left'#3#144#1#6'Height'#3#0#1#0#0#241#6'TPanel'#9'pnlBottom'#3'Top'#3
+#144#1#0#0#241#9'TSplitter'#10'splitRight'#4'Left'#3#140#1#6'Height'#3#0#1#0 +#4#1#5'Width'#3#144#1#0#0#241#9'TSplitter'#10'splitRight'#4'Left'#3#140#1#6
+#0#241#10'TStatusBar'#10'StatusBar1'#3'Top'#3#5#1#5'Width'#3#144#1#0#0#241#9 +'Height'#3#0#1#0#0#241#10'TStatusBar'#10'StatusBar1'#3'Top'#3#5#1#5'Width'#3
+'TSplitter'#11'splitBottom'#3'Top'#3#0#1#5'Width'#3#144#1#0#0#242#2#7#9'TMai' +#144#1#0#0#241#9'TSplitter'#11'splitBottom'#3'Top'#3#0#1#5'Width'#3#144#1#0#0
+'nMenu'#9'MainMenu1'#4'left'#3#240#0#3'top'#2'0'#0#9'TMenuItem'#6'mnFile'#7 +#242#2#7#9'TMainMenu'#9'MainMenu1'#4'left'#3#240#0#3'top'#2'0'#0#9'TMenuItem'
+'Caption'#6#5'&File'#0#9'TMenuItem'#6'mnOpen'#7'Caption'#6#5'&Open'#7'OnClic' +#6'mnFile'#7'Caption'#6#5'&File'#0#9'TMenuItem'#6'mnOpen'#7'Caption'#6#5'&Op'
+'k'#7#11'mnOpenClick'#0#0#9'TMenuItem'#9'MenuItem1'#7'Caption'#6#1'-'#0#0#9 +'en'#7'OnClick'#7#11'mnOpenClick'#0#0#9'TMenuItem'#9'MenuItem1'#7'Caption'#6
+'TMenuItem'#6'mnExit'#7'Caption'#6#5'E&xit'#7'OnClick'#7#11'mnExitClick'#0#0 +#1'-'#0#0#9'TMenuItem'#6'mnExit'#7'Caption'#6#5'E&xit'#7'OnClick'#7#11'mnExi'
+#0#9'TMenuItem'#6'mnView'#7'Caption'#6#5'&View'#0#9'TMenuItem'#9'MenuItem2'#7 +'tClick'#0#0#0#9'TMenuItem'#6'mnView'#7'Caption'#6#5'&View'#0#9'TMenuItem'#9
+'Caption'#6#16'Object Inspector'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuI' +'MenuItem2'#7'Caption'#6#16'Object Inspector'#7'OnClick'#7#13'ViewMenuClick'
+'tem'#9'MenuItem3'#7'Caption'#6#8'Messages'#7'OnClick'#7#13'ViewMenuClick'#0 +#0#0#9'TMenuItem'#9'MenuItem3'#7'Caption'#6#8'Messages'#7'OnClick'#7#13'View'
+#0#9'TMenuItem'#9'MenuItem4'#7'Caption'#6#13'Code Explorer'#7'OnClick'#7#13 +'MenuClick'#0#0#9'TMenuItem'#9'MenuItem4'#7'Caption'#6#13'Code Explorer'#7'O'
+'ViewMenuClick'#0#0#9'TMenuItem'#9'MenuItem5'#7'Caption'#6#9'ToDo List'#7'On' +'nClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#9'MenuItem5'#7'Caption'#6#9'To'
+'Click'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#9'MenuItem6'#7'Caption'#6#13'De' +'Do List'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#9'MenuItem6'#7'Cap'
+'bug windows'#0#9'TMenuItem'#9'MenuItem7'#7'Caption'#6#7'Watches'#7'OnClick' +'tion'#6#13'Debug windows'#0#9'TMenuItem'#9'MenuItem7'#7'Caption'#6#7'Watche'
+#7#13'ViewMenuClick'#0#0#9'TMenuItem'#9'MenuItem8'#7'Caption'#6#11'BreakPoin' +'s'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#9'MenuItem8'#7'Caption'#6
+'ts'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#9'MenuItem9'#7'Caption' +#11'BreakPoints'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#9'MenuItem9'
+#6#15'Local Variables'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#10'Me' +#7'Caption'#6#15'Local Variables'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenu'
+'nuItem10'#7'Caption'#6#9'Registers'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TM' +'Item'#10'MenuItem10'#7'Caption'#6#9'Registers'#7'OnClick'#7#13'ViewMenuClic'
+'enuItem'#10'MenuItem11'#7'Caption'#6#10'Call Stack'#7'OnClick'#7#13'ViewMen' +'k'#0#0#9'TMenuItem'#10'MenuItem11'#7'Caption'#6#10'Call Stack'#7'OnClick'#7
+'uClick'#0#0#9'TMenuItem'#10'MenuItem12'#7'Caption'#6#9'Assembler'#7'OnClick' +#13'ViewMenuClick'#0#0#9'TMenuItem'#10'MenuItem12'#7'Caption'#6#9'Assembler'
+#7#13'ViewMenuClick'#0#0#9'TMenuItem'#10'MenuItem13'#7'Caption'#6#12'Debug O' +#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#10'MenuItem13'#7'Caption'#6
+'utput'#7'OnClick'#7#13'ViewMenuClick'#0#0#0#0#9'TMenuItem'#10'MenuItem14'#7 +#12'Debug Output'#7'OnClick'#7#13'ViewMenuClick'#0#0#0#0#9'TMenuItem'#10'Men'
+'Caption'#6#8'&Windows'#0#9'TMenuItem'#12'mnWindowDump'#7'Caption'#6#5'&Dump' +'uItem14'#7'Caption'#6#8'&Windows'#0#9'TMenuItem'#12'mnWindowDump'#7'Caption'
+#7'OnClick'#7#17'mnWindowDumpClick'#0#0#9'TMenuItem'#10'mnMinimize'#7'Captio' +#6#5'&Dump'#7'OnClick'#7#17'mnWindowDumpClick'#0#0#9'TMenuItem'#10'mnMinimiz'
+'n'#6#12'Minimize all'#7'OnClick'#7#15'mnMinimizeClick'#0#0#9'TMenuItem'#9'm' +'e'#7'Caption'#6#12'Minimize all'#7'OnClick'#7#15'mnMinimizeClick'#0#0#9'TMe'
+'nRestore'#7'Caption'#6#11'Restore all'#7'OnClick'#7#14'mnRestoreClick'#0#0#0 +'nuItem'#9'mnRestore'#7'Caption'#6#11'Restore all'#7'OnClick'#7#14'mnRestore'
+#0#242#2#8#11'TOpenDialog'#11'OpenDialog1'#6'Filter'#6#25'*.pas|*.pas|All Fi' +'Click'#0#0#0#0#242#2#8#11'TOpenDialog'#11'OpenDialog1'#6'Filter'#6#25'*.pas'
+'les|*.*'#4'left'#3'5'#1#3'top'#2'0'#0#0#0 +'|*.pas|All Files|*.*'#4'left'#3'5'#1#3'top'#2'0'#0#0#0
]); ]);

View File

@ -36,7 +36,9 @@ interface
uses uses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
ExtCtrls, ComCtrls, Menus, ExtCtrls, ComCtrls, Menus,
fElasticSite, fEditBook, fEditForm; //fElasticSite,
fEditBook,
fEditForm;
type type
TEditorSite = class(TDockingSite) TEditorSite = class(TDockingSite)

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

View File

@ -0,0 +1,430 @@
<?xml version="1.0"?>
<CONFIG>
<ProjectOptions>
<PathDelim Value="\"/>
<Version Value="7"/>
<General>
<MainUnit Value="0"/>
<AutoCreateForms Value="False"/>
<TargetFileExt Value=".exe"/>
<Icon Value="0"/>
<UseXPManifest Value="True"/>
<ActiveEditorIndexAtStart Value="3"/>
</General>
<VersionInfo>
<ProjectVersion Value=""/>
</VersionInfo>
<PublishOptions>
<Version Value="2"/>
<IgnoreBinaries Value="False"/>
<IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
<ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
</PublishOptions>
<RunParams>
<local>
<FormatVersion Value="1"/>
<LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
</local>
</RunParams>
<RequiredPackages Count="3">
<Item1>
<PackageName Value="SynEdit"/>
</Item1>
<Item2>
<PackageName Value="EasyDockMgr"/>
</Item2>
<Item3>
<PackageName Value="LCL"/>
</Item3>
</RequiredPackages>
<Units Count="26">
<Unit0>
<Filename Value="MiniIDE.lpr"/>
<IsPartOfProject Value="True"/>
<UnitName Value="MiniIDE"/>
<UsageCount Value="66"/>
</Unit0>
<Unit1>
<Filename Value="fminiide.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="MainBar"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="fMiniIde"/>
<CursorPos X="1" Y="124"/>
<TopLine Value="106"/>
<EditorIndex Value="0"/>
<UsageCount Value="66"/>
<Loaded Value="True"/>
</Unit1>
<Unit2>
<Filename Value="feditorsite.pas"/>
<ComponentName Value="EditorSite"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="fEditorSite"/>
<CursorPos X="3" Y="40"/>
<TopLine Value="44"/>
<UsageCount Value="32"/>
</Unit2>
<Unit3>
<Filename Value="feditbook.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="EditBook"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="fEditBook"/>
<CursorPos X="3" Y="75"/>
<TopLine Value="75"/>
<EditorIndex Value="6"/>
<UsageCount Value="62"/>
<Loaded Value="True"/>
</Unit3>
<Unit4>
<Filename Value="..\..\..\lcl\forms.pp"/>
<UnitName Value="Forms"/>
<CursorPos X="3" Y="737"/>
<TopLine Value="715"/>
<EditorIndex Value="10"/>
<UsageCount Value="24"/>
<Loaded Value="True"/>
</Unit4>
<Unit5>
<Filename Value="..\package\fdockbook.pas"/>
<ComponentName Value="EasyDockBook"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="fDockBook"/>
<CursorPos X="4" Y="375"/>
<TopLine Value="365"/>
<EditorIndex Value="9"/>
<UsageCount Value="35"/>
<Bookmarks Count="1">
<Item0 X="5" Y="406" ID="1"/>
</Bookmarks>
<Loaded Value="True"/>
</Unit5>
<Unit6>
<Filename Value="..\..\..\components\synedit\synedit.pp"/>
<UnitName Value="SynEdit"/>
<CursorPos X="1" Y="734"/>
<TopLine Value="710"/>
<UsageCount Value="18"/>
</Unit6>
<Unit7>
<Filename Value="fclientform.pas"/>
<IsPartOfProject Value="True"/>
<HasResources Value="True"/>
<UnitName Value="fclientform"/>
<UsageCount Value="65"/>
</Unit7>
<Unit8>
<Filename Value="..\package\umakesite.pas"/>
<UnitName Value="uMakeSite"/>
<CursorPos X="1" Y="592"/>
<TopLine Value="576"/>
<EditorIndex Value="3"/>
<UsageCount Value="34"/>
<Loaded Value="True"/>
</Unit8>
<Unit9>
<Filename Value="..\..\..\lcl\controls.pp"/>
<UnitName Value="Controls"/>
<CursorPos X="15" Y="1789"/>
<TopLine Value="1767"/>
<EditorIndex Value="1"/>
<UsageCount Value="32"/>
<Loaded Value="True"/>
</Unit9>
<Unit10>
<Filename Value="fbookframe.pas"/>
<ComponentName Value="DockBook"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Frame"/>
<UnitName Value="fBookFrame"/>
<CursorPos X="26" Y="19"/>
<TopLine Value="1"/>
<UsageCount Value="26"/>
</Unit10>
<Unit11>
<Filename Value="..\package\felasticsite.pas"/>
<ComponentName Value="DockingSite"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="fElasticSite"/>
<CursorPos X="3" Y="48"/>
<TopLine Value="41"/>
<EditorIndex Value="7"/>
<UsageCount Value="31"/>
<Loaded Value="True"/>
</Unit11>
<Unit12>
<Filename Value="..\..\..\lcl\include\control.inc"/>
<CursorPos X="6" Y="2699"/>
<TopLine Value="2661"/>
<EditorIndex Value="2"/>
<UsageCount Value="29"/>
<Loaded Value="True"/>
</Unit12>
<Unit13>
<Filename Value="..\package\easydockmgr.pas"/>
<UnitName Value="EasyDockMgr"/>
<CursorPos X="1" Y="1"/>
<TopLine Value="1"/>
<UsageCount Value="14"/>
</Unit13>
<Unit14>
<Filename Value="..\package\easydocking.pas"/>
<UnitName Value="EasyDocking"/>
<CursorPos X="1" Y="1"/>
<TopLine Value="1"/>
<UsageCount Value="14"/>
</Unit14>
<Unit15>
<Filename Value="..\package\easydocksite.pas"/>
<ComponentName Value="CustomDockSite"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="EasyDockSite"/>
<CursorPos X="1" Y="1128"/>
<TopLine Value="1106"/>
<EditorIndex Value="11"/>
<UsageCount Value="31"/>
<Loaded Value="True"/>
</Unit15>
<Unit16>
<Filename Value="..\..\..\lcl\include\wincontrol.inc"/>
<CursorPos X="3" Y="5235"/>
<TopLine Value="5228"/>
<UsageCount Value="14"/>
</Unit16>
<Unit17>
<Filename Value="..\..\..\lcl\include\dragmanager.inc"/>
<CursorPos X="1" Y="516"/>
<TopLine Value="494"/>
<UsageCount Value="10"/>
</Unit17>
<Unit18>
<Filename Value="..\..\..\lcl\include\dragobject.inc"/>
<CursorPos X="1" Y="112"/>
<TopLine Value="90"/>
<UsageCount Value="10"/>
</Unit18>
<Unit19>
<Filename Value="..\..\..\..\..\lazarus\fpc\2.2.4\source\rtl\objpas\classes\classesh.inc"/>
<CursorPos X="14" Y="1556"/>
<TopLine Value="1534"/>
<EditorIndex Value="4"/>
<UsageCount Value="10"/>
<Loaded Value="True"/>
</Unit19>
<Unit20>
<Filename Value="..\..\..\..\..\lazarus\fpc\2.2.4\source\rtl\objpas\classes\streams.inc"/>
<CursorPos X="3" Y="448"/>
<TopLine Value="445"/>
<UsageCount Value="9"/>
</Unit20>
<Unit21>
<Filename Value="..\..\..\lcl\lclmessageglue.pas"/>
<UnitName Value="LCLMessageGlue"/>
<CursorPos X="1" Y="109"/>
<TopLine Value="87"/>
<EditorIndex Value="12"/>
<UsageCount Value="23"/>
<Loaded Value="True"/>
</Unit21>
<Unit22>
<Filename Value="..\package\ffloatingsite.pas"/>
<ComponentName Value="FloatingSite"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="fFloatingSite"/>
<CursorPos X="3" Y="58"/>
<TopLine Value="36"/>
<EditorIndex Value="5"/>
<UsageCount Value="25"/>
<Loaded Value="True"/>
</Unit22>
<Unit23>
<Filename Value="..\..\..\lcl\include\customform.inc"/>
<CursorPos X="16" Y="2476"/>
<TopLine Value="2467"/>
<UsageCount Value="9"/>
</Unit23>
<Unit24>
<Filename Value="..\..\..\lcl\lresources.pp"/>
<UnitName Value="LResources"/>
<CursorPos X="27" Y="756"/>
<TopLine Value="753"/>
<UsageCount Value="9"/>
</Unit24>
<Unit25>
<Filename Value="..\..\..\..\..\lazarus\fpc\2.2.4\source\rtl\objpas\classes\reader.inc"/>
<CursorPos X="21" Y="1241"/>
<TopLine Value="1239"/>
<EditorIndex Value="8"/>
<UsageCount Value="22"/>
<Loaded Value="True"/>
</Unit25>
</Units>
<JumpHistory Count="30" HistoryIndex="28">
<Position1>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="426" Column="1" TopLine="404"/>
</Position1>
<Position2>
<Filename Value="..\..\..\lcl\lclmessageglue.pas"/>
<Caret Line="109" Column="1" TopLine="87"/>
</Position2>
<Position3>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="426" Column="1" TopLine="404"/>
</Position3>
<Position4>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="427" Column="1" TopLine="405"/>
</Position4>
<Position5>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="428" Column="1" TopLine="406"/>
</Position5>
<Position6>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="429" Column="1" TopLine="407"/>
</Position6>
<Position7>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="430" Column="1" TopLine="408"/>
</Position7>
<Position8>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="431" Column="1" TopLine="409"/>
</Position8>
<Position9>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="435" Column="1" TopLine="413"/>
</Position9>
<Position10>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="463" Column="1" TopLine="441"/>
</Position10>
<Position11>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="467" Column="1" TopLine="445"/>
</Position11>
<Position12>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="469" Column="1" TopLine="447"/>
</Position12>
<Position13>
<Filename Value="..\package\easydocksite.pas"/>
<Caret Line="1117" Column="1" TopLine="1095"/>
</Position13>
<Position14>
<Filename Value="..\package\easydocksite.pas"/>
<Caret Line="1063" Column="1" TopLine="1041"/>
</Position14>
<Position15>
<Filename Value="..\package\easydocksite.pas"/>
<Caret Line="1068" Column="1" TopLine="1046"/>
</Position15>
<Position16>
<Filename Value="..\package\easydocksite.pas"/>
<Caret Line="1119" Column="1" TopLine="1097"/>
</Position16>
<Position17>
<Filename Value="..\package\easydocksite.pas"/>
<Caret Line="1120" Column="1" TopLine="1098"/>
</Position17>
<Position18>
<Filename Value="..\package\easydocksite.pas"/>
<Caret Line="1121" Column="1" TopLine="1099"/>
</Position18>
<Position19>
<Filename Value="..\package\easydocksite.pas"/>
<Caret Line="1122" Column="1" TopLine="1070"/>
</Position19>
<Position20>
<Filename Value="..\package\easydocksite.pas"/>
<Caret Line="1127" Column="1" TopLine="1105"/>
</Position20>
<Position21>
<Filename Value="..\package\easydocksite.pas"/>
<Caret Line="1128" Column="1" TopLine="1106"/>
</Position21>
<Position22>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="454" Column="1" TopLine="432"/>
</Position22>
<Position23>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="460" Column="1" TopLine="438"/>
</Position23>
<Position24>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="426" Column="1" TopLine="404"/>
</Position24>
<Position25>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="427" Column="1" TopLine="405"/>
</Position25>
<Position26>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="428" Column="1" TopLine="406"/>
</Position26>
<Position27>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="424" Column="22" TopLine="422"/>
</Position27>
<Position28>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="593" Column="12" TopLine="571"/>
</Position28>
<Position29>
<Filename Value="..\package\umakesite.pas"/>
<Caret Line="591" Column="18" TopLine="569"/>
</Position29>
<Position30>
<Filename Value="..\..\..\..\..\lazarus\fpc\2.2.4\source\rtl\objpas\classes\classesh.inc"/>
<Caret Line="1556" Column="14" TopLine="1534"/>
</Position30>
</JumpHistory>
</ProjectOptions>
<CompilerOptions>
<Version Value="8"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="MiniIDE"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)\"/>
<OtherUnitFiles Value="..\easyedit\;..\..\..\components\synedit\"/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Other>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
<Debugging>
<BreakPoints Count="1">
<Item1>
<Source Value="fminiide.pas"/>
<Line Value="223"/>
</Item1>
</BreakPoints>
<Exceptions Count="4">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
<Item4>
<Name Value="EComponentError"/>
</Item4>
</Exceptions>
</Debugging>
</CONFIG>

View File

@ -0,0 +1,21 @@
program MiniIDE;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Interfaces, // this includes the LCL widgetset
Forms, LResources, fminiide, EasyDockMgr, fclientform, fEditBook
{ you can add units after this };
{$IFDEF WINDOWS}{$R MiniIDE.rc}{$ENDIF}
begin
{$I MiniIDE.lrs}
Application.Initialize;
Application.CreateForm(TMainBar, MainBar);
Application.Run;
end.

View File

@ -0,0 +1,47 @@
object ViewWindow: TViewWindow
Left = 369
Height = 300
Top = 369
Width = 400
Caption = 'ViewWindow'
ClientHeight = 300
ClientWidth = 400
DragKind = dkDock
DragMode = dmAutomatic
OnEndDock = FormEndDock
LCLVersion = '0.9.29'
Visible = True
object Label1: TLabel
Left = 16
Height = 14
Top = 8
Width = 142
AutoSize = False
Caption = 'Label1'
DragKind = dkDock
DragMode = dmAutomatic
ParentColor = False
end
object Image1: TImage
Left = 384
Height = 16
Top = 0
Width = 16
Anchors = [akTop, akRight]
AutoSize = True
OnMouseMove = Image1MouseMove
Picture.Data = {
055449636F6E3E01000000000100010010101000000000002801000016000000
2800000010000000200000000100040000000000C00000000000000000000000
0000000000000000000000000000800000800000008080008000000080008000
8080000080808000C0C0C0000000FF0000FF000000FFFF00FF000000FF00FF00
FFFF0000FFFFFF00000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000990000000000009999990000000000999999000000000999999990
0000000999999990000000009999990000000000999999000000000000990000
00000000000000007FFF0000BFFF0000DFFF0000EFFF0000F7FF0000FBFF0000
FDCF0000FE030000FE010000FE010000FC000000FC000000FE010000FE010000
FF030000FFCF0000
}
end
end

View File

@ -0,0 +1,22 @@
LazarusResources.Add('TViewWindow','FORMDATA',[
'TPF0'#11'TViewWindow'#10'ViewWindow'#4'Left'#3'q'#1#6'Height'#3','#1#3'Top'#3
+'q'#1#5'Width'#3#144#1#7'Caption'#6#10'ViewWindow'#12'ClientHeight'#3','#1#11
+'ClientWidth'#3#144#1#8'DragKind'#7#6'dkDock'#8'DragMode'#7#11'dmAutomatic'#9
+'OnEndDock'#7#11'FormEndDock'#10'LCLVersion'#6#6'0.9.29'#7'Visible'#9#0#6'TL'
+'abel'#6'Label1'#4'Left'#2#16#6'Height'#2#14#3'Top'#2#8#5'Width'#3#142#0#8'A'
+'utoSize'#8#7'Caption'#6#6'Label1'#8'DragKind'#7#6'dkDock'#8'DragMode'#7#11
+'dmAutomatic'#11'ParentColor'#8#0#0#6'TImage'#6'Image1'#4'Left'#3#128#1#6'He'
+'ight'#2#16#3'Top'#2#0#5'Width'#2#16#7'Anchors'#11#5'akTop'#7'akRight'#0#8'A'
+'utoSize'#9#11'OnMouseMove'#7#15'Image1MouseMove'#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#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#0#0#0
]);

View File

@ -0,0 +1,73 @@
unit fClientForm;
(* A form for easy docking into multi-client floating sites.
When the form becomes floating, it docks itself into a new floating dockhost
site, that can accept further clients.
Since not all window managers allow to dock forms,
docking is allowed only from a dedicated (pin) icon.
*)
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
StdCtrls, ExtCtrls;
type
TViewWindow = class(TForm)
Image1: TImage;
Label1: TLabel;
procedure FormEndDock(Sender, Target: TObject; X, Y: Integer);
procedure Image1MouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
private
{ private declarations }
public
{ public declarations }
end;
//var ViewWindow: TViewWindow; //useless
implementation
uses
//LCLProc, //debugging only
fFloatingSite;
{ TViewWindow }
procedure TViewWindow.FormEndDock(Sender, Target: TObject; X, Y: Integer);
var
Site: TFloatingSite;
begin
(* When we become floating, dock immediately into a new floating host docksite.
*)
if HostDockSite = nil then begin
//DebugLn('--- floating');
Site := TFloatingSite.Create(Application); //the new site
Site.BoundsRect := self.BoundsRect; //the new position and extension
ManualDock(Site);
end else begin
//DebugLn('--- in ' + HostDockSite.Name);
end;
end;
procedure TViewWindow.Image1MouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
begin
(* The mouse is moved over our docking gadget.
When the left button is pressed, start dragging (for docking).
*)
if ssLeft in Shift then begin
BeginDrag(False);
end;
end;
initialization
{$I fclientform.lrs}
end.

View File

@ -0,0 +1,8 @@
object EditBook: TEditBook
Left = 670
Height = 240
Top = 115
Width = 320
Caption = 'EditBook'
LCLVersion = '0.9.29'
end

View File

@ -0,0 +1,6 @@
{ This is an automatically generated lazarus resource file }
LazarusResources.Add('TEditBook','FORMDATA',[
'TPF0'#9'TEditBook'#8'EditBook'#4'Left'#3#158#2#6'Height'#3#240#0#3'Top'#2's'
+#5'Width'#3'@'#1#7'Caption'#6#8'EditBook'#10'LCLVersion'#6#6'0.9.29'#0#0
]);

View File

@ -0,0 +1,221 @@
unit fEditBook;
(* Take2: embed a DockBook, add elastic sites.
Maintain a chain of active (editor) pages.
Whenever a page is activated, move it in front of the chain.
Destroy (and dequeue) all pages when the form is destroyed.
The queue head is stored in the global variable MRUEdit.
SynEdit seems not to be properly dockable - use intermediate form instead.
*)
{$mode objfpc}{$H+}
{ TODO : figure out what's wrong with the mru list - with multiple windows }
{$DEFINE mru} //problems with MRU list???
interface
uses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
SynEdit, EasyDockSite,
fDockBook;
type
//TEditPage = class(TSynEdit)
TEditPage = class(TCustomForm)
protected
FEdit: TSynEdit;
NRUEdit: TEditPage; //Next Recently Used EditPage
procedure DoFloatMsg(ADockSource: TDragDockObject); override;//CM_FLOAT
function GetDefaultDockCaption: string; override;
function GetPrev: TEditPage;
procedure SetFocus; override;
public
FileName: string;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure LoadFile(const AName: string);
end;
(* EditPages is a notebook with special notification of its parent.
*)
TEditPages = class(TEasyDockBook)
protected
procedure AfterUndock(tabidx: integer); override;
end;
(* An EditBook wraps a DockBook.
AsString is implemented for save/load the entire form.
Reloading files has to be done separately, not as part of a layout?
*)
{$IFDEF new}
TEditBook = class(TCustomDockSite)
protected
FEdit: TEditPages;
procedure LoadNames(const str: string); override;
function SaveNames: string; override;
//procedure OpenFiles(TheFiles: string);
public
constructor Create(TheOwner: TComponent); override;
function OpenFile(const AName: string): boolean; //virtual;
//property Files: string read SaveNames write LoadNames;
property AsString;
end;
{$ELSE}
TEditBook = class(TForm)
protected
FEdit: TEditPages;
public
constructor Create(TheOwner: TComponent); override;
function OpenFile(const AName: string): boolean; //virtual;
end;
{$ENDIF}
var
MRUEdit: TEditPage; //Most Recently Used EditPage
implementation
uses
uMakeSite;
{ TEditBook }
constructor TEditBook.Create(TheOwner: TComponent);
begin
inherited Create(TheOwner);
FEdit := TEditPages.Create(self);
FEdit.BorderStyle := bsNone;
FEdit.Parent := self;
FEdit.Align := alClient;
FEdit.Visible := True;
FEdit.DragMode := dmManual; //disallow undocking
FEdit.StayDocked := True;
DockMaster.AddElasticSites(self, [alLeft, alRight, alBottom]);
end;
function TEditBook.OpenFile(const AName: string): boolean;
var
se: TEditPage;
begin
se := TEditPage.Create(Owner);
se.LoadFile(AName);
se.ManualDock(FEdit);
end;
{ TEditPage }
constructor TEditPage.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
//FloatingDockSiteClass := TEditBook; //also created if NOT floating?
DragKind := dkDock;
DragMode := dmAutomatic; //most probably doesn't work
FEdit := TSynEdit.Create(self);
FEdit.Parent := self;
FEdit.Align := alClient;
//update chain
NRUEdit := MRUEdit;
MRUEdit := self;
//SetFocus;
end;
destructor TEditPage.Destroy;
var
prev: TEditPage;
begin
//update chain
if MRUEdit = self then
MRUEdit := NRUEdit
else begin
prev := GetPrev;
if prev <> nil then
prev.NRUEdit := NRUEdit; //okay
//else not in chain???
end;
inherited Destroy;
end;
procedure TEditPage.DoFloatMsg(ADockSource: TDragDockObject);
var
FloatHost: TEditBook;
begin
//wrap into TEditBook
if False then inherited DoFloatMsg(ADockSource); //for reference purpose only
//parent still is the OLD parent!
//if Parent <> nil then exit; //really do nothing? (if normal child)
FloatHost := TEditBook.Create(Application); // CreateFloatingDockSite(ADockSource.DockRect);
FloatHost.BoundsRect := ADockSource.DockRect;
FloatHost.Visible := True;
FloatHost.Caption := FloatHost.GetDockCaption(Self);
ADockSource.DragTarget := FloatHost.FEdit; // FloatHost;
ADockSource.DropOnControl := nil; // FloatHost.FEdit;
ADockSource.DropAlign := alCustom;
end;
function TEditPage.GetDefaultDockCaption: string;
begin
Result := ExtractFileName(FileName);
if Result = '' then
Result := inherited GetDefaultDockCaption;
end;
function TEditPage.GetPrev: TEditPage;
begin
//get preceding edit page in MRU chain
if MRUEdit = self then
exit(nil);
//not head
Result := MRUEdit;
while (Result <> nil) and (Result.NRUEdit <> self) do
Result := Result.NRUEdit;
//now result can be nil if we are not chained at all!
end;
procedure TEditPage.LoadFile(const AName: string);
begin
FileName := AName;
FEdit.Lines.LoadFromFile(AName);
Caption := ExtractFileName(AName);
end;
procedure TEditPage.SetFocus;
var
prev: TEditPage;
begin
//repair
//FloatingDockSiteClass := TEditBook; //not used???
//update chain
if MRUEdit <> self then begin
prev := GetPrev;
prev.NRUEdit := NRUEdit; //deQ
NRUEdit := MRUEdit;
MRUEdit := self;
end;
inherited SetFocus;
end;
{ TEditPages }
procedure TEditPages.AfterUndock(tabidx: integer);
var
frm: TCustomForm;
begin
//if last client undocked - close
if Tabs.ButtonCount = 0 then begin
frm := GetParentForm(self);
if frm is TEditBook then begin
frm.Close;
exit;
end;
end;
inherited AfterUndock(tabidx);
end;
initialization
{$I feditbook.lrs}
RegisterClass(TEditBook);
RegisterClass(TEditPage);
end.

View File

@ -0,0 +1,135 @@
object MainBar: TMainBar
Left = 248
Height = 66
Top = 113
Width = 400
Caption = 'MainBar'
ClientHeight = 47
ClientWidth = 400
Menu = MainMenu1
OnCreate = FormCreate
LCLVersion = '0.9.29'
object cbLayouts: TComboBox
Left = 88
Height = 21
Top = 0
Width = 144
ItemHeight = 13
Style = csDropDownList
TabOrder = 0
end
object Label1: TLabel
Left = 8
Height = 14
Top = 0
Width = 34
Caption = 'Layout'
ParentColor = False
end
object buRestore: TButton
Left = 304
Height = 25
Top = 1
Width = 91
Caption = 'Restore'
OnClick = buRestoreClick
TabOrder = 1
end
object buSave: TButton
Left = 240
Height = 25
Top = 1
Width = 59
Caption = 'Save'
OnClick = buSaveClick
TabOrder = 2
end
object MainMenu1: TMainMenu
left = 96
object mnFile: TMenuItem
Caption = '&File'
object mnOpen: TMenuItem
Caption = '&Open'
OnClick = mnOpenClick
end
object MenuItem1: TMenuItem
Caption = '-'
end
object mnExit: TMenuItem
Caption = 'E&xit'
OnClick = mnExitClick
end
end
object mnView: TMenuItem
Caption = '&View'
object MenuItem2: TMenuItem
Caption = 'Object Inspector'
OnClick = ViewMenuClick
end
object MenuItem3: TMenuItem
Caption = 'Messages'
OnClick = ViewMenuClick
end
object MenuItem4: TMenuItem
Caption = 'Code Explorer'
OnClick = ViewMenuClick
end
object MenuItem5: TMenuItem
Caption = 'ToDo List'
OnClick = ViewMenuClick
end
object MenuItem6: TMenuItem
Caption = 'Debug windows'
object MenuItem7: TMenuItem
Caption = 'Watches'
OnClick = ViewMenuClick
end
object MenuItem8: TMenuItem
Caption = 'BreakPoints'
OnClick = ViewMenuClick
end
object MenuItem9: TMenuItem
Caption = 'Local Variables'
OnClick = ViewMenuClick
end
object MenuItem10: TMenuItem
Caption = 'Registers'
OnClick = ViewMenuClick
end
object MenuItem11: TMenuItem
Caption = 'Call Stack'
OnClick = ViewMenuClick
end
object MenuItem12: TMenuItem
Caption = 'Assembler'
OnClick = ViewMenuClick
end
object MenuItem13: TMenuItem
Caption = 'Debug Output'
OnClick = ViewMenuClick
end
end
end
object MenuItem14: TMenuItem
Caption = '&Windows'
object mnWindowDump: TMenuItem
Caption = '&Dump'
end
object mnMinimize: TMenuItem
Caption = 'Minimize all'
end
object mnRestore: TMenuItem
Caption = 'Restore all'
end
end
end
object OpenDialog1: TOpenDialog
Filter = '*.pas|*.pas|All Files|*.*'
left = 184
end
object dlgLayout: TSaveDialog
DefaultExt = '.lyt'
Filter = 'Layouts|*.lyt'
left = 144
end
end

View File

@ -0,0 +1,39 @@
{ This is an automatically generated lazarus resource file }
LazarusResources.Add('TMainBar','FORMDATA',[
'TPF0'#8'TMainBar'#7'MainBar'#4'Left'#3#248#0#6'Height'#2'B'#3'Top'#2'q'#5'Wi'
+'dth'#3#144#1#7'Caption'#6#7'MainBar'#12'ClientHeight'#2'/'#11'ClientWidth'#3
+#144#1#4'Menu'#7#9'MainMenu1'#8'OnCreate'#7#10'FormCreate'#10'LCLVersion'#6#6
+'0.9.29'#0#9'TComboBox'#9'cbLayouts'#4'Left'#2'X'#6'Height'#2#21#3'Top'#2#0#5
+'Width'#3#144#0#10'ItemHeight'#2#13#5'Style'#7#14'csDropDownList'#8'TabOrder'
+#2#0#0#0#6'TLabel'#6'Label1'#4'Left'#2#8#6'Height'#2#14#3'Top'#2#0#5'Width'#2
+'"'#7'Caption'#6#6'Layout'#11'ParentColor'#8#0#0#7'TButton'#9'buRestore'#4'L'
+'eft'#3'0'#1#6'Height'#2#25#3'Top'#2#1#5'Width'#2'['#7'Caption'#6#7'Restore'
+#7'OnClick'#7#14'buRestoreClick'#8'TabOrder'#2#1#0#0#7'TButton'#6'buSave'#4
+'Left'#3#240#0#6'Height'#2#25#3'Top'#2#1#5'Width'#2';'#7'Caption'#6#4'Save'#7
+'OnClick'#7#11'buSaveClick'#8'TabOrder'#2#2#0#0#9'TMainMenu'#9'MainMenu1'#4
+'left'#2'`'#0#9'TMenuItem'#6'mnFile'#7'Caption'#6#5'&File'#0#9'TMenuItem'#6
+'mnOpen'#7'Caption'#6#5'&Open'#7'OnClick'#7#11'mnOpenClick'#0#0#9'TMenuItem'
+#9'MenuItem1'#7'Caption'#6#1'-'#0#0#9'TMenuItem'#6'mnExit'#7'Caption'#6#5'E&'
+'xit'#7'OnClick'#7#11'mnExitClick'#0#0#0#9'TMenuItem'#6'mnView'#7'Caption'#6
+#5'&View'#0#9'TMenuItem'#9'MenuItem2'#7'Caption'#6#16'Object Inspector'#7'On'
+'Click'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#9'MenuItem3'#7'Caption'#6#8'Mes'
+'sages'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#9'MenuItem4'#7'Capti'
+'on'#6#13'Code Explorer'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#9'M'
+'enuItem5'#7'Caption'#6#9'ToDo List'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TM'
+'enuItem'#9'MenuItem6'#7'Caption'#6#13'Debug windows'#0#9'TMenuItem'#9'MenuI'
+'tem7'#7'Caption'#6#7'Watches'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuIte'
+'m'#9'MenuItem8'#7'Caption'#6#11'BreakPoints'#7'OnClick'#7#13'ViewMenuClick'
+#0#0#9'TMenuItem'#9'MenuItem9'#7'Caption'#6#15'Local Variables'#7'OnClick'#7
+#13'ViewMenuClick'#0#0#9'TMenuItem'#10'MenuItem10'#7'Caption'#6#9'Registers'
+#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#10'MenuItem11'#7'Caption'#6
+#10'Call Stack'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#10'MenuItem1'
+'2'#7'Caption'#6#9'Assembler'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'
+#10'MenuItem13'#7'Caption'#6#12'Debug Output'#7'OnClick'#7#13'ViewMenuClick'
+#0#0#0#0#9'TMenuItem'#10'MenuItem14'#7'Caption'#6#8'&Windows'#0#9'TMenuItem'
+#12'mnWindowDump'#7'Caption'#6#5'&Dump'#0#0#9'TMenuItem'#10'mnMinimize'#7'Ca'
+'ption'#6#12'Minimize all'#0#0#9'TMenuItem'#9'mnRestore'#7'Caption'#6#11'Res'
+'tore all'#0#0#0#0#11'TOpenDialog'#11'OpenDialog1'#6'Filter'#6#25'*.pas|*.pa'
+'s|All Files|*.*'#4'left'#3#184#0#0#0#11'TSaveDialog'#9'dlgLayout'#10'Defaul'
+'tExt'#6#4'.lyt'#6'Filter'#6#13'Layouts|*.lyt'#4'left'#3#144#0#0#0#0
]);

View File

@ -0,0 +1,254 @@
unit fMiniIde;
(* IDE main bar (rudimentary)
Problems:
View window names are not derived from class name.
EditBooks are not managed sites(?)
*)
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
Menus, StdCtrls, SynEdit;
type
TMainBar = class(TForm)
buSave: TButton;
buRestore: TButton;
cbLayouts: TComboBox;
Label1: TLabel;
MainMenu1: TMainMenu;
MenuItem1: TMenuItem;
MenuItem10: TMenuItem;
MenuItem11: TMenuItem;
MenuItem12: TMenuItem;
MenuItem13: TMenuItem;
MenuItem14: TMenuItem;
MenuItem2: TMenuItem;
MenuItem3: TMenuItem;
MenuItem4: TMenuItem;
MenuItem5: TMenuItem;
MenuItem6: TMenuItem;
MenuItem7: TMenuItem;
MenuItem8: TMenuItem;
MenuItem9: TMenuItem;
mnExit: TMenuItem;
mnFile: TMenuItem;
mnMinimize: TMenuItem;
mnOpen: TMenuItem;
mnRestore: TMenuItem;
mnView: TMenuItem;
mnWindowDump: TMenuItem;
OpenDialog1: TOpenDialog;
dlgLayout: TSaveDialog;
procedure buRestoreClick(Sender: TObject);
procedure buSaveClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure mnExitClick(Sender: TObject);
procedure mnOpenClick(Sender: TObject);
procedure ViewMenuClick(Sender: TObject);
private
procedure GetLayouts;
procedure OpenFile(const AName: string);
private //DockMaster callbacks
function OnReloadControl(const CtrlName: string; ASite: TWinControl): TControl;
function OnSaveControl(ACtrl: TControl): string;
public
function CreateDockable(const cap: string; fWrap: boolean = True): TWinControl;
end;
var
MainBar: TMainBar;
implementation
uses
uMakeSite, fEditBook, fClientForm;
{ TMainBar }
procedure TMainBar.FormCreate(Sender: TObject);
begin
TDockMaster.Create(self);
DockMaster.OnSave := @OnSaveControl;
DockMaster.OnRestore := @OnReloadControl;
DockMaster.AddElasticSites(self, [alBottom]);
GetLayouts;
end;
procedure TMainBar.GetLayouts;
var
sr: TSearchRec;
begin
if FindFirst('*.lyt', faAnyFile, sr) = 0 then begin
repeat
cbLayouts.Items.Add(sr.Name);
until FindNext(sr) <> 0;
FindClose(sr);
end;
end;
procedure TMainBar.mnExitClick(Sender: TObject);
begin
Close;
end;
procedure TMainBar.mnOpenClick(Sender: TObject);
begin
if OpenDialog1.Execute then begin
OpenFile(OpenDialog1.FileName);
end;
end;
procedure TMainBar.OpenFile(const AName: string);
var
frm: TEditBook;
ctl: TControl;
begin
(* Translate into layout Reload format
*)
//get editor form
frm := nil;
if MRUEdit <> nil then begin
//use parent of last edit page
ctl := MRUEdit.Parent;
while ctl.Parent <> nil do
ctl := ctl.Parent;
if ctl is TEditBook then
frm := TEditBook(ctl);
end;
if frm = nil then begin
frm := TEditBook.Create(Application);
frm.Visible := True;
end;
frm.OpenFile(AName);
end;
procedure TMainBar.ViewMenuClick(Sender: TObject);
var
item: TMenuItem absolute Sender;
begin
(* Create a dummy window from the menu item name.
*)
CreateDockable(item.Caption);
end;
procedure TMainBar.buRestoreClick(Sender: TObject);
var
i: integer;
s: string;
f: TFileStream;
begin
i := cbLayouts.ItemIndex;
if i < 0 then begin
beep;
exit;
end;
s := cbLayouts.Items[i];
f := TFileStream.Create(s, fmOpenRead);
try
DockMaster.LoadFromStream(f);
finally
f.Free;
end;
end;
procedure TMainBar.buSaveClick(Sender: TObject);
var
strm: TFileStream;
begin
if dlgLayout.Execute then begin
strm := TFileStream.Create(dlgLayout.FileName, fmCreate);
try
DockMaster.SaveToStream(strm);
finally
strm.Free;
end;
cbLayouts.AddItem(dlgLayout.FileName, nil); //Extract?
end;
end;
function TMainBar.CreateDockable(const cap: string; fWrap: boolean): TWinControl;
var
//Site: TFloatingSite;
Client: TViewWindow;
begin
(* Translate into layout Reload format:
<name>%t=<type>[%f=<editfile>]
*)
(* Create a client form, and dock it into a floating dock host site.
We must force docking here, later the client will dock itself into
a float host site, when it becomes floating.
*)
//create the form
Client := TViewWindow.Create(Self);
Client.Label1.Caption := cap;
Client.Visible := True;
//name it
Client.Caption := cap;
try
Client.Name := StringReplace(cap, ' ', '', [rfReplaceAll]);
except
//here: simply ignore duplicate name
end;
DockMaster.MakeDockable(Client, fWrap);
Result := Client;
end;
(* Special load/store cases:
ViewWindow: @<caption>
EditForm/Book: EditBook:f1,f2...
EditPage?
*)
function TMainBar.OnReloadControl(const CtrlName: string;
ASite: TWinControl): TControl;
var
i: integer;
lst: TStringList;
s: string;
eb: TEditBook absolute Result;
begin
(* Format
Since commas are used for notebook docking, we have to choose other delimiters.
<name>%t=<type>[%f=<editfile>]
Default type is 'T'<name><instNo>, default instNo is 1?
*)
if CtrlName[1] = '@' then
Result := CreateDockable(copy(CtrlName, 2, Length(CtrlName)), False)
else if CtrlName[1] = ',' then begin
eb := TEditBook.Create(Application);
lst := TStringList.Create;
try
lst.CommaText := CtrlName;
for i := 1 to lst.Count - 1 do begin
s := lst[i];
eb.OpenFile(s);
end;
finally
lst.Free;
end;
end else
Result := nil; //for now
end;
function TMainBar.OnSaveControl(ACtrl: TControl): string;
var
i: integer;
ep: TEditPage;
begin
if ACtrl is TViewWindow then begin
Result := '@' + ACtrl.Caption;
end else if ACtrl is TEditBook then begin
Result := ',' + TWinControl(ACtrl).GetDockCaption(ACtrl);
end else
Result := ACtrl.HostDockSite.GetDockCaption(ACtrl);
end;
initialization
{$I fminiide.lrs}
end.

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@
<Version Value="8"/> <Version Value="8"/>
<PathDelim Value="\"/> <PathDelim Value="\"/>
<SearchPaths> <SearchPaths>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> <UnitOutputDirectory Value="..\lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths> </SearchPaths>
<Other> <Other>
<CompilerPath Value="$(CompPath)"/> <CompilerPath Value="$(CompPath)"/>

View File

@ -72,14 +72,12 @@ uses
Forms, Forms,
ExtCtrls, //splitter ExtCtrls, //splitter
Controls, Controls,
fDockBook,
ComCtrls; //TPageControl ComCtrls; //TPageControl
type type
TEasyTree = class; //forward declaration TEasyTree = class; //forward declaration
TEasyZone = class; //forward declaration TEasyZone = class; //forward declaration
TEasySplitter = TCustomSplitter; TEasySplitter = TCustomSplitter;
TEasyBook = class(TEasyDockBook);
TEasyZonePart = TEasyZonePart =
( (
@ -170,6 +168,23 @@ type
property Top: integer read GetTop; property Top: integer read GetTop;
end; end;
(* General DockSite, also Notebook dock site.
All restorable application forms should inherit from this class,
regardless of docking capabilities.
*)
TCustomDockSite = class(TForm)
protected
//function GetDefaultDockCaption: string; override;
procedure LoadNames(const str: string); virtual; abstract;
function SaveNames: string; virtual; abstract;
public
StayDocked: boolean;
property AsString: string read SaveNames write LoadNames;
end;
TDockSiteClass = class of TCustomDockSite;
(* TEasyDockManager implements some of the abstract methods of TDockManager. (* TEasyDockManager implements some of the abstract methods of TDockManager.
*) *)
TEasyDockManager = class(TDockManager) TEasyDockManager = class(TDockManager)
@ -201,18 +216,11 @@ type
FSiteRect: TRect; //to detect changed site extent FSiteRect: TRect; //to detect changed site extent
procedure UpdateTree; procedure UpdateTree;
protected protected
{$IFDEF old}
procedure BeginUpdate; override;
procedure EndUpdate; override;
procedure PositionDockRect(Client, DropCtl: TControl; DropAlign: TAlign;
var DockRect: TRect); override;
{$ELSE}
//in base class
{$ENDIF}
//extended interface //extended interface
//procedure ControlVisibilityChanged(Control: TControl; Visible: Boolean); override; //procedure ControlVisibilityChanged(Control: TControl; Visible: Boolean); override;
function ZoneFromPoint(SitePos: TPoint): TEasyZone; function ZoneFromPoint(SitePos: TPoint): TEasyZone;
function ReloadDockedControl(const AName: string): TControl; virtual; function ReloadDockedControl(const AName: string): TControl; virtual;
function SaveDockedControl(Control: TControl): string; virtual;
protected //added protected //added
function FindControlZone(zone: TEasyZone; Control: TControl): TEasyZone; function FindControlZone(zone: TEasyZone; Control: TControl): TEasyZone;
procedure RemoveZone(Zone: TEasyZone); procedure RemoveZone(Zone: TEasyZone);
@ -249,8 +257,33 @@ type
property HideSingleCaption: boolean read FHideSingleCaption write SetSingleCaption; property HideSingleCaption: boolean read FHideSingleCaption write SetSingleCaption;
end; end;
function NoteBookCreate(AOwner: TWinControl): TEasyBook; inline; (* Application loader - a single method for consistency.
procedure NoteBookAdd(ABook: TEasyBook; AItem: TControl); inline; The method has several tasks, depending on
fLoad,fSite:
F,F: save Ctrl description in AName.
T,F: provide Ctrl for Site from AName.
F,T: save Site description in AName.
T,T: provide Site and its container Ctrl from AName.
The DockManager only deals with dock clients, i.e. fSite is always False.
The DockMaster manages sites, i.e. fSite is True.
When a site is to be created, notebook sites can have a different docksite
control. Here Ctrl is the outer control, containing Site.
*)
//application loader link
type
TAppLoadStore = function(fLoad, fSite: boolean;
var Site: TWinControl; var Ctrl: TControl; var AName: string): boolean of object;
var
AppLoadStore: TAppLoadStore;
//handy function for DockRect initialization
function ScreenRect(ACtrl: TControl): TRect;
//primarily for DockManager internal use
function NoteBookCreate(AOwner: TWinControl): TCustomDockSite;
procedure NoteBookAdd(ABook: TCustomDockSite; AItem: TControl); //to be removed
function TryRename(AComp: TComponent; const NewName: string): boolean;
const const
AlignNames: array[TAlign] of string = ( AlignNames: array[TAlign] of string = (
@ -269,7 +302,9 @@ const
'zpCloseButton' // header close button 'zpCloseButton' // header close button
); );
var //debug only //var AppDockBookClass: TDockBookClass;
var //debug only, these are valid only until drop
DropOn: TControl; DropOn: TControl;
DockObj: TDragDockObject; DockObj: TDragDockObject;
@ -279,6 +314,7 @@ uses
SysUtils, Types, SysUtils, Types,
math, math,
Themes, LResources, Themes, LResources,
fDockBook,
LCLproc; //debugging LCLproc; //debugging
type type
@ -292,33 +328,67 @@ const
HeaderButtons = [zpCloseButton]; HeaderButtons = [zpCloseButton];
{$ENDIF} {$ENDIF}
function NoteBookCreate(AOwner: TWinControl): TEasyBook; inline; function NoteBookCreate(AOwner: TWinControl): TCustomDockSite;
begin begin
Result := TEasyBook.Create(AOwner); (* Create default dockbook type.
*)
{
if assigned(AppDockBookClass) then
Result := AppDockBookClass.Create(AOwner)
else
}
Result := TEasyDockBook.Create(AOwner);
end; end;
procedure NoteBookAdd(ABook: TEasyBook; AItem: TControl); inline; procedure NoteBookAdd(ABook: TCustomDockSite; AItem: TControl);
begin begin
AItem.ManualDock(ABook); AItem.ManualDock(ABook);
end; end;
function TryRename(AComp: TComponent; const NewName: string): boolean;
begin
(* catch errors in renaming a component
*)
try
AComp.Name := NewName;
Result := True;
except
Result := False;
end;
end;
function ScreenRect(ACtrl: TControl): TRect;
begin
Result.TopLeft := ACtrl.ControlOrigin; //screen coords
Result.Right := Result.Left + ACtrl.Width;
Result.Bottom := Result.Top + ACtrl.Height;
end;
//from CustomFormEditor.pp //from CustomFormEditor.pp
function {TCustomFormEditor.}CreateUniqueComponentName(const AClassName: string; function {TCustomFormEditor.}CreateUniqueComponentName(const AClassName: string;
OwnerComponent: TComponent): string; OwnerComponent: TComponent): string;
var var
i, j: integer; i, j: integer;
begin begin
(* Add instance number until unique.
<T><basename> ==> <basename><_><number>
The classname can be reconstructed by prefixing 'T' (typically)
and stripping trailing digits and (optionally) '_'.
*)
Result:=AClassName; Result:=AClassName;
if (OwnerComponent=nil) or (Result='') then exit; if (OwnerComponent=nil) or (Result='') then exit;
i:=1; i:=1;
while true do begin while true do begin
j:=OwnerComponent.ComponentCount-1;
Result:=AClassName; Result:=AClassName;
//strip leading 'T'
if (length(Result)>1) and (Result[1]='T') then if (length(Result)>1) and (Result[1]='T') then
Result:=RightStr(Result,length(Result)-1); Result:=RightStr(Result,length(Result)-1);
//if trailing digit, append '_'
if Result[length(Result)] in ['0'..'9'] then if Result[length(Result)] in ['0'..'9'] then
Result:=Result+'_'; Result:=Result+'_';
Result:=Result+IntToStr(i); Result:=Result+IntToStr(i);
//append instance number
j:=OwnerComponent.ComponentCount-1;
while (j>=0) while (j>=0)
and (CompareText(Result,OwnerComponent.Components[j].Name)<>0) do and (CompareText(Result,OwnerComponent.Components[j].Name)<>0) do
dec(j); dec(j);
@ -477,7 +547,7 @@ procedure TEasyTree.InsertControl(Control: TControl; InsertAt: TAlign;
var var
DropZone, OldZone, NewZone, OldParent, NewParent: TEasyZone; DropZone, OldZone, NewZone, OldParent, NewParent: TEasyZone;
r: TRect; r: TRect;
NoteBook: TEasyBook; NoteBook: TCustomDockSite;
(* special cases: (* special cases:
1) first child in top zone - no orientation 1) first child in top zone - no orientation
2) second child in top zone - determines orientation 2) second child in top zone - determines orientation
@ -545,21 +615,23 @@ begin
Valid only when dropped onto an existing control, not into empty dock site. Valid only when dropped onto an existing control, not into empty dock site.
Create notebook, if required (put both controls into new notebook). Create notebook, if required (put both controls into new notebook).
Try: create notebook already for first dropped control. Try: create notebook already for first dropped control (ifdef singleTab).
Use custom handler? Per Site or per application?
*) *)
if (InsertAt = alCustom) then begin if (InsertAt = alCustom) then begin
//dock into book //dock into book
if (FTopZone.FirstChild <> nil) then begin if (FTopZone.FirstChild <> nil) then begin
//root zone is not empty //root zone is not empty
if (DropCtl is TEasyBook) then begin if (DropCtl is TCustomDockSite) then begin
NoteBook := DropCtl as TEasyBook; NoteBook := TCustomDockSite(DropCtl);
end else begin end else begin
//create new book //create new book
NoteBook := NoteBookCreate(FDockSite); NoteBook := NoteBookCreate(FDockSite);
{$IFDEF replace} {$IFDEF replace}
NoteBook.ReplaceDockedControl(DropZone.ChildControl, NoteBook, nil, alCustom); NoteBook.ReplaceDockedControl(DropZone.ChildControl, NoteBook, nil, alCustom);
{$ELSE} {$ELSE}
NoteBook.ManualDock(nil, nil); NoteBook.ManualDock(nil, nil); //float it - purpose???
//hack: manually dock the notebook //hack: manually dock the notebook
FReplacingControl := NoteBook; //ignore insert (see above) FReplacingControl := NoteBook; //ignore insert (see above)
NoteBook.ManualDock(FDockSite); //move into DockClients[] NoteBook.ManualDock(FDockSite); //move into DockClients[]
@ -640,7 +712,7 @@ begin
end; end;
//set control orientation //set control orientation
DropZone.AddSibling(NewZone, InsertAt); DropZone.AddSibling(NewZone, InsertAt);
//clear eventually moved zone //clear eventually moved zone, when redocking within this site
if OldZone <> nil then begin if OldZone <> nil then begin
RemoveZone(OldZone); //must NOT modify moved control! RemoveZone(OldZone); //must NOT modify moved control!
OldZone.Free; OldZone.Free;
@ -955,85 +1027,12 @@ type
BottomRight: TPoint; BottomRight: TPoint;
Level: byte; Level: byte;
Orientation: TDockOrientation; Orientation: TDockOrientation;
//Width, Height: word; NameLen: integer; //+chars, can be a complete notebook description
NameLen: integer; //+chars
end; end;
var var
ZoneRec: RZone; ZoneRec: RZone;
ZoneName: string; ZoneName: string;
const
BookZoneName: string = '*';
procedure TEasyTree.SaveToStream(Stream: TStream);
procedure DoSaveZone(Zone: TEasyZone; Level: byte);
var
child: TControl;
begin
//fill ZoneRec
ZoneRec.Level := Level;
ZoneRec.Orientation := Zone.Orientation;
ZoneRec.BottomRight := Zone.BR;
child := Zone.ChildControl;
if child = nil then
ZoneName := ''
{$IFDEF new}
else if child is TEasyDockBook then begin
ZoneName := BookZoneName;
ZoneName := TEasyDockBook(child).GetDockCaption(child)
//ZoneName := TWinControlAccess(child).GetDockCaption(child); // BookZoneName
end
{$ELSE}
{$ENDIF}
else begin
//ZoneName := child.Name;
ZoneName := DockSite.GetDockCaption(child); //default to child.Name
end;
ZoneRec.NameLen := Length(ZoneName);
//write descriptor
Stream.Write(ZoneRec, sizeof(ZoneRec));
if ZoneRec.NameLen > 0 then
Stream.Write(ZoneName[1], ZoneRec.NameLen);
{ TODO -oDoDi : WritePages of notebook }
// recurse into first child
if Zone.FirstChild <> nil then
DoSaveZone(Zone.FirstChild, Level + 1); //all children of Level
// recurse into next sibling
if Zone.NextSibling <> nil then
DoSaveZone(Zone.NextSibling, Level); //all siblings of Level
end;
begin
// write top zone data
//Stream.Write(FTopXYLimit, SizeOf(FTopXYLimit));
//WriteLimits(FTopZone);
// write all zones from tree
DoSaveZone(FTopZone, 1);
//write end marker (dummy record of level 0)
ZoneRec.Level := 0;
ZoneRec.NameLen := 0;
Stream.Write(ZoneRec, sizeof(ZoneRec));
end;
function TEasyTree.ReloadDockedControl(const AName: string): TControl;
{$IFDEF new}
var
nb: TEasyBook;
begin
if Pos(',', AName) > 0 then begin
nb := NoteBookCreate(FDockSite);
nb.SetDockCaption(AName);
Result := nb;
end else begin
TWinControlAccess(DockSite).ReloadDockedControl(ZoneName???, Result);
end;
{$ELSE}
begin
Result:=nil;
TWinControlAccess(DockSite).ReloadDockedControl(AName, Result);
end;
{$ENDIF}
procedure TEasyTree.LoadFromStream(Stream: TStream); procedure TEasyTree.LoadFromStream(Stream: TStream);
@ -1063,7 +1062,8 @@ procedure TEasyTree.LoadFromStream(Stream: TStream);
*) *)
for i := FDockSite.DockClientCount - 1 downto 0 do begin for i := FDockSite.DockClientCount - 1 downto 0 do begin
ctl := FDockSite.DockClients[i]; ctl := FDockSite.DockClients[i];
ctl.ManualDock(nil); ctl.Visible := True;
ctl.ManualDock(nil); //restore undocked position and extent
end; end;
end; end;
@ -1087,7 +1087,7 @@ procedure TEasyTree.LoadFromStream(Stream: TStream);
if NewCtl = nil then begin if NewCtl = nil then begin
//debug: create some control //debug: create some control
NewCtl := TPanel.Create(DockSite); NewCtl := TPanel.Create(DockSite);
NewCtl.Name := ZoneName; TryRename(NewCtl, ZoneName);
end; end;
if NewCtl <> nil then begin if NewCtl <> nil then begin
NewCtl.Visible := True; NewCtl.Visible := True;
@ -1103,10 +1103,8 @@ procedure TEasyTree.LoadFromStream(Stream: TStream);
dec(PrevLvl); dec(PrevLvl);
end; end;
if NewLvl = PrevLvl then //add sibling if NewLvl = PrevLvl then //add sibling
//PrevZone.AddSibling(NewZone, alRight)
PrevZone.Parent.InsertAfter(PrevZone, NewZone) PrevZone.Parent.InsertAfter(PrevZone, NewZone)
else begin //NewLvl > PrevLvl - make child else begin //NewLvl > PrevLvl - make child
//InZone.InsertAfter(PrevZone, NewZone);
PrevZone.InsertAfter(nil, NewZone); PrevZone.InsertAfter(nil, NewZone);
PrevLvl := NewLvl; PrevLvl := NewLvl;
end; end;
@ -1121,14 +1119,81 @@ begin
if GetRec > 0 then begin if GetRec > 0 then begin
FTopZone.BR := ZoneRec.BottomRight; FTopZone.BR := ZoneRec.BottomRight;
FTopZone.Orientation := ZoneRec.Orientation; FTopZone.Orientation := ZoneRec.Orientation;
//if GetRec = 2 then MakeZone(FTopZone, 1);
MakeZones; MakeZones;
end; end;
//finish? //finish?
//remove all leafs without a child control? //remove all leafs without a child control?
//refresh the site
ResetBounds(True); ResetBounds(True);
end; end;
function TEasyTree.ReloadDockedControl(const AName: string): TControl;
var
n: string;
begin
Result:=nil;
n := AName;
if assigned(AppLoadStore)
and AppLoadStore(True, False, DockSite, Result, n) then begin
//all done
end else
TWinControlAccess(DockSite).ReloadDockedControl(AName, Result);
end;
function TEasyTree.SaveDockedControl(Control: TControl): string;
begin
(* Create string descriptor for docked control.
Override in sync with ReloadDockedControl!
*)
if Assigned(AppLoadStore)
and AppLoadStore(False, False, FDockSite, Control, Result) then begin
//all done
end else if Control is TCustomDockSite then
Result := TCustomDockSite(Control).AsString
else begin
//Result := Control.Name; //Delphi default
Result := FDockSite.GetDockCaption(Control); //defaults to child.Name
//notebooks will return comma separated name list
end;
end;
procedure TEasyTree.SaveToStream(Stream: TStream);
procedure DoSaveZone(Zone: TEasyZone; Level: byte);
var
child: TControl;
begin
//fill ZoneRec
ZoneRec.Level := Level;
ZoneRec.Orientation := Zone.Orientation;
ZoneRec.BottomRight := Zone.BR;
child := Zone.ChildControl;
if child = nil then
ZoneName := ''
else
ZoneName := SaveDockedControl(child);
ZoneRec.NameLen := Length(ZoneName);
//write descriptor
Stream.Write(ZoneRec, sizeof(ZoneRec));
if ZoneRec.NameLen > 0 then
Stream.Write(ZoneName[1], ZoneRec.NameLen);
// recurse into first child
if Zone.FirstChild <> nil then
DoSaveZone(Zone.FirstChild, Level + 1); //all children of Level
// recurse into next sibling
if Zone.NextSibling <> nil then
DoSaveZone(Zone.NextSibling, Level); //all siblings of Level
end;
begin
// write all zones from tree
DoSaveZone(FTopZone, 1);
//write end marker (dummy record of level 0)
ZoneRec.Level := 0;
ZoneRec.NameLen := 0;
Stream.Write(ZoneRec, sizeof(ZoneRec));
end;
procedure TEasyTree.DumpToStream(Stream: TStream); procedure TEasyTree.DumpToStream(Stream: TStream);
var var
r: TRect; r: TRect;

View File

@ -25,20 +25,9 @@ normally react on mouse buttons (borders...). E.g. a SynEdit has to be wrapped
into a form, before it can be dragged and docked by dragging the form. into a form, before it can be dragged and docked by dragging the form.
Apply ToolButtonAutoSizeAlign.patch to improve the appearance and behaviour Apply ToolButtonAutoSizeAlign.patch to improve the appearance and behaviour
of the toolbar buttons. of the toolbar buttons. (new version will use TToggleBox)
ToDo: Close docked forms on notebook destruction.
- Check use of ToggleBox instead of TToolButton
- Load/Store layout
+ Update parent on un/dock: Caption and DockHeaders!
Problems:
Disallow undocking/floating of a NOT docked dockbook.
Fix: flag StayDocked.
Clients are not properly undocked on close!?
(see undockFix)
*) *)
(* Applications (* Applications
@ -63,17 +52,14 @@ HostDockSite.UpdateDockCaption (provide composed dock caption)
{$mode objfpc}{$H+} {$mode objfpc}{$H+}
{$IFDEF WIN32} {.$DEFINE undockFix}
{$DEFINE undockFix} //seems to be required for win32 widgetset {$DEFINE closeFix}
{$ELSE}
//no problems on Linux/gtk2
{$ENDIF}
interface interface
uses uses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
ComCtrls, ExtCtrls, StdCtrls; ComCtrls, ExtCtrls, StdCtrls, EasyDockSite;
type type
TTabButton = class(TToolButton) TTabButton = class(TToolButton)
@ -94,7 +80,7 @@ type
{ TEasyDockBook } { TEasyDockBook }
TEasyDockBook = class(TForm) TEasyDockBook = class(TCustomDockSite)
pnlDock: TPanel; pnlDock: TPanel;
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction); procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
procedure FormCreate(Sender: TObject); procedure FormCreate(Sender: TObject);
@ -107,18 +93,21 @@ type
procedure FormUnDock(Sender: TObject; Client: TControl; procedure FormUnDock(Sender: TObject; Client: TControl;
NewTarget: TWinControl; var Allow: Boolean); NewTarget: TWinControl; var Allow: Boolean);
procedure ToolButton1Click(Sender: TObject); procedure ToolButton1Click(Sender: TObject);
private protected
Tabs: TTabs; Tabs: TTabs;
CurTab: TTabButton; CurTab: TTabButton;
protected protected
function GetDefaultDockCaption: string; override; function GetDefaultDockCaption: string; override;
function GetControlTab(AControl: TControl): TTabButton; function GetControlTab(AControl: TControl): TTabButton;
procedure AfterUndock(tabidx: integer); virtual;
procedure LoadNames(const str: string); override;
function SaveNames: string; override;
public public
StayDocked: boolean; {$IFDEF undockFix}
destructor Destroy; override;
{$ENDIF}
{$IFDEF closeFix}
destructor Destroy; override; destructor Destroy; override;
{$IFDEF new}
procedure SetDockCaption(const AName: string);
{$ELSE}
{$ENDIF} {$ENDIF}
end; end;
@ -128,10 +117,6 @@ implementation
uses uses
fFloatingSite, fFloatingSite,
{$IFDEF WIN32}
Windows, //PostMessage
{$ELSE}
{$ENDIF}
LCLProc; //debug only LCLProc; //debug only
procedure Register; procedure Register;
@ -141,6 +126,7 @@ end;
{ TEasyDockBook } { TEasyDockBook }
{$IFDEF undockFix}
destructor TEasyDockBook.Destroy; destructor TEasyDockBook.Destroy;
var var
i: integer; i: integer;
@ -157,7 +143,6 @@ begin
end of the application. end of the application.
Fix: check ctl.ComponentState for csDestroying. Fix: check ctl.ComponentState for csDestroying.
*) *)
{$IFDEF undockFix}
for i := DockClientCount - 1 downto 0 do begin for i := DockClientCount - 1 downto 0 do begin
ctl := DockClients[i]; ctl := DockClients[i];
if not (csDestroying in ctl.ComponentState) then if not (csDestroying in ctl.ComponentState) then
@ -165,10 +150,37 @@ begin
DebugLn('Undocked %s P=%p H=%p', [ctl.Name, DebugLn('Undocked %s P=%p H=%p', [ctl.Name,
pointer(ctl.Parent), pointer(ctl.HostDockSite)]); pointer(ctl.Parent), pointer(ctl.HostDockSite)]);
end; end;
{$ELSE}
{$ENDIF}
inherited Destroy; inherited Destroy;
end; end;
{$ELSE}
//LCL updated accordingly?
{$ENDIF}
{$IFDEF closeFix}
destructor TEasyDockBook.Destroy;
var
i: integer;
ctl: TControl;
frm: TCustomForm absolute ctl;
begin
(* Close docked forms, make all docked controls visible - or hidden?
*)
for i := DockClientCount - 1 downto 0 do begin
ctl := DockClients[i];
if not (csDestroying in ctl.ComponentState) then begin
ctl.Visible := True; //make hidden notebook pages visible
if ctl is TCustomForm then
if frm.CloseQuery then
frm.Close
else
ctl.Visible := True; //make hidden notebook pages visible
end;
end;
inherited Destroy;
end;
{$ELSE}
//pure option
{$ENDIF}
procedure TEasyDockBook.FormClose(Sender: TObject; procedure TEasyDockBook.FormClose(Sender: TObject;
var CloseAction: TCloseAction); var CloseAction: TCloseAction);
@ -180,24 +192,7 @@ var
begin begin
(* When an empty notebook is closed, it shall be freed. (* When an empty notebook is closed, it shall be freed.
Otherwise the clients must be handled (close forms) Otherwise the clients must be handled (close forms)
This code is never reached when we are docked
*) *)
{$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}
DebugLn(['TEasyDockBook.FormClose ',DbgSName(Self),' ',dbgs(Pointer(Self))]); DebugLn(['TEasyDockBook.FormClose ',DbgSName(Self),' ',dbgs(Pointer(Self))]);
CloseAction := caFree; CloseAction := caFree;
end; end;
@ -234,13 +229,7 @@ begin
//unmanaged dock site requires an OnDockOver handler. //unmanaged dock site requires an OnDockOver handler.
Accept := True; //this is the default, can be omitted Accept := True; //this is the default, can be omitted
//make DockRect reflect the docking area //make DockRect reflect the docking area
with Source do begin Source.DockRect := ScreenRect(pnlDock);
ARect := pnlDock.ClientRect;
ARect.TopLeft := pnlDock.ClientToScreen(ARect.TopLeft);
inc(ARect.Bottom, ARect.Top);
inc(ARect.Right, ARect.Left);
DockRect := ARect;
end;
end; end;
procedure TEasyDockBook.FormGetSiteInfo(Sender: TObject; DockClient: TControl; procedure TEasyDockBook.FormGetSiteInfo(Sender: TObject; DockClient: TControl;
@ -248,6 +237,7 @@ procedure TEasyDockBook.FormGetSiteInfo(Sender: TObject; DockClient: TControl;
begin begin
//override TCustomForm behaviour! //override TCustomForm behaviour!
CanDock := True; CanDock := True;
InfluenceRect := ScreenRect(pnlDock);
end; end;
procedure TEasyDockBook.FormUnDock(Sender: TObject; Client: TControl; procedure TEasyDockBook.FormUnDock(Sender: TObject; Client: TControl;
@ -272,6 +262,24 @@ begin
Tabs.ButtonList.Delete(i); Tabs.ButtonList.Delete(i);
Application.ReleaseComponent(btn); Application.ReleaseComponent(btn);
//special handle remove of current and last tab //special handle remove of current and last tab
AfterUndock(i);
end;
procedure TEasyDockBook.AfterUndock(tabidx: integer);
begin
(* A client has undocked, we have various options:
If 1 client remains, replace ourselves by this client (if docked)
Opt: hide Tabs.
If 0 clients remain, free ourselves (if docked or floating)
Finally update Parent (DockCaption if docked, if destroying self)
We can be either:
docked - HDS<>nil, HDS<>floating site
floating - HDS=Parent=floating site (which exactly? having no kids except us?)
child - HDS=nil, Parent<>nil.
*)
{$IFDEF new} {$IFDEF new}
//if not StayDocked and (Tabs.ButtonCount = 1) then begin //if not StayDocked and (Tabs.ButtonCount = 1) then begin
if False then begin if False then begin
@ -291,27 +299,31 @@ begin
end else end else
{$ELSE} {$ELSE}
//above code doesn't work :-( //above code doesn't work :-(
//retry: explicit replace by last client, undock(?) and release
{$ENDIF} {$ENDIF}
if Tabs.ButtonCount > 0 then begin if Tabs.ButtonCount > 0 then begin
//tab moved? //tab moved?
if CurTab = nil then begin //current button removed if CurTab = nil then begin //current button removed
//find next tab to show //find next tab to show
if i >= Tabs.ButtonCount then if tabidx >= Tabs.ButtonCount then
i := Pred(Tabs.ButtonCount); // dec(i); tabidx := Pred(Tabs.ButtonCount); // dec(i);
//activate new tab //activate new tab
CurTab := Tabs.Buttons[i] as TTabButton; CurTab := Tabs.Buttons[tabidx] as TTabButton;
CurTab.Down := True; CurTab.Down := True;
CurTab.Click; CurTab.Click;
end; end;
Caption := GetDefaultDockCaption; Caption := GetDefaultDockCaption;
end else if not StayDocked then begin end else if not StayDocked then begin
//last tab removed - close ONLY if we are docked or floating //last tab removed - close ONLY if we are docked or floating
if (HostDockSite <> nil) then begin //may be cleared already??? if (Parent = nil) then begin
ManualDock(nil); //undock before closing //we are floating
//DoUnDock(nil, nil);
//Dock(nil);
end;
Release; Release;
exit;
end else if (HostDockSite <> nil) then begin //may be cleared already???
ManualDock(nil); //undock before closing
Release;
exit;
end;
end; end;
//update the host dock site and its DockManager //update the host dock site and its DockManager
if HostDockSite <> nil then begin if HostDockSite <> nil then begin
@ -319,6 +331,8 @@ begin
TFloatingSite(HostDockSite).UpdateCaption(nil); TFloatingSite(HostDockSite).UpdateCaption(nil);
if HostDockSite.DockManager <> nil then if HostDockSite.DockManager <> nil then
HostDockSite.Invalidate; HostDockSite.Invalidate;
end else if Parent <> nil then begin
//notify - how?
end; end;
end; end;
@ -351,8 +365,7 @@ begin
end; end;
end; end;
{$IFDEF new} procedure TEasyDockBook.LoadNames(const str: string);
procedure TEasyDockBook.SetDockCaption(const AName: string);
var var
lst: TStringList; lst: TStringList;
i: integer; i: integer;
@ -360,20 +373,40 @@ var
ctl: TControl; ctl: TControl;
begin begin
(* This is a suggestion for handling arguments in ReloadDockedControl. (* This is a suggestion for handling arguments in ReloadDockedControl.
Skip lst[0], it contains our ClassName and (optional) Name
','<ClassName> ['='<Name>]
*) *)
lst := TStringList.Create; lst := TStringList.Create;
lst.CommaText := AName; lst.CommaText := str;
for i := 0 to lst.Count - 1 do begin //s := lst.Names[0];
s := lst.ValueFromIndex[0];
if s <> '' then
TryRename(self, s);
for i := i to lst.Count - 1 do begin
s := lst.Strings[i]; s := lst.Strings[i];
ReloadDockedControl(s, ctl); ReloadDockedControl(s, ctl); //handle everything in s!
if ctl <> nil then begin if ctl <> nil then begin
ctl.Name := s; //ctl.Name := s;
ctl.ManualDock(self, nil, alCustom); ctl.ManualDock(pnlDock, nil, alCustom);
end; end;
end; end;
end; end;
{$ELSE}
{$ENDIF} function TEasyDockBook.SaveNames: string;
var
i: integer;
ctl: TControl;
begin
(* Entry[0] is <ClassName> ['='<Name>]
else <Name> (with ClassName = 'T'<Name>)
*)
//Result := '*' + Name + '=' + ClassName; //really?
Result := ClassName + '=' + Name;
for i := 0 to pnlDock.DockClientCount - 1 do begin
ctl := pnlDock.DockClients[i];
Result := Result + ',' + ctl.Name;
end;
end;
procedure TEasyDockBook.ToolButton1Click(Sender: TObject); procedure TEasyDockBook.ToolButton1Click(Sender: TObject);
var var
@ -419,8 +452,8 @@ begin
end else end else
} }
//both immediate and delayed drag start seem to work //both immediate and delayed drag start seem to work
Control.BeginDrag(False); //delayed docking //Control.BeginDrag(False); //delayed docking
//Control.BeginDrag(True); //immediate drag Control.BeginDrag(True); //immediate drag
end; end;
end; end;
end; end;

View File

@ -1,7 +1,7 @@
object DockingSite: TDockingSite object DockingSite: TDockingSite
Left = 444 Left = 509
Height = 163 Height = 163
Top = 156 Top = 268
Width = 255 Width = 255
AutoSize = True AutoSize = True
Caption = 'Dock Site' Caption = 'Dock Site'

View File

@ -1,11 +1,11 @@
{ This is an automatically generated lazarus resource file } { This is an automatically generated lazarus resource file }
LazarusResources.Add('TDockingSite','FORMDATA',[ LazarusResources.Add('TDockingSite','FORMDATA',[
'TPF0'#12'TDockingSite'#11'DockingSite'#4'Left'#3#188#1#6'Height'#3#163#0#3'T' 'TPF0'#12'TDockingSite'#11'DockingSite'#4'Left'#3#253#1#6'Height'#3#163#0#3'T'
+'op'#3#156#0#5'Width'#3#255#0#8'AutoSize'#9#7'Caption'#6#9'Dock Site'#12'Cli' +'op'#3#12#1#5'Width'#3#255#0#8'AutoSize'#9#7'Caption'#6#9'Dock Site'#12'Clie'
+'entHeight'#3#163#0#11'ClientWidth'#3#255#0#10'LCLVersion'#6#6'0.9.29'#7'Vis' +'ntHeight'#3#163#0#11'ClientWidth'#3#255#0#10'LCLVersion'#6#6'0.9.29'#7'Visi'
+'ible'#9#0#6'TPanel'#7'pnlLeft'#4'Left'#2#0#6'Height'#3#138#0#3'Top'#2#0#5'W' +'ble'#9#0#6'TPanel'#7'pnlLeft'#4'Left'#2#0#6'Height'#3#138#0#3'Top'#2#0#5'Wi'
+'idth'#2#0#5'Align'#7#6'alLeft'#7'Caption'#6#7'pnlLeft'#5'Color'#7#7'clWhite' +'dth'#2#0#5'Align'#7#6'alLeft'#7'Caption'#6#7'pnlLeft'#5'Color'#7#7'clWhite'
+#8'DockSite'#9#11'ParentColor'#8#8'TabOrder'#2#0#10'OnDockDrop'#7#15'pnlLeft' +#8'DockSite'#9#11'ParentColor'#8#8'TabOrder'#2#0#10'OnDockDrop'#7#15'pnlLeft'
+'DockDrop'#10'OnDockOver'#7#15'pnlLeftDockOver'#13'OnGetSiteInfo'#7#18'pnlLe' +'DockDrop'#10'OnDockOver'#7#15'pnlLeftDockOver'#13'OnGetSiteInfo'#7#18'pnlLe'
+'ftGetSiteInfo'#8'OnUnDock'#7#13'pnlLeftUnDock'#0#0#9'TSplitter'#9'splitLeft' +'ftGetSiteInfo'#8'OnUnDock'#7#13'pnlLeftUnDock'#0#0#9'TSplitter'#9'splitLeft'

View File

@ -52,9 +52,14 @@ type
public public
end; end;
(* DockManager derived from EasyTree.
Added handling of notebooks.
*)
TAppDockManager = class(TEasyTree) TAppDockManager = class(TEasyTree)
protected protected
function ReloadDockedControl(const AName: string): TControl; override; function ReloadDockedControl(const AName: string): TControl; override;
//function SaveDockedControl(Control: TControl; Site: TWinControl): string; override;
function SaveDockedControl(Control: TControl): string; override;
end; end;
(* The owner of all docksites (* The owner of all docksites
@ -89,13 +94,12 @@ type
//persistence //persistence
procedure LoadFromStream(Stream: TStream); procedure LoadFromStream(Stream: TStream);
procedure SaveToStream(Stream: TStream); procedure SaveToStream(Stream: TStream);
function ReloadDockedControl(const AName: string; Site: TWinControl): TControl; function ReloadDockedControl(const AName: string; Site: TWinControl): TControl; virtual;
function SaveDockedControl(ACtrl: TControl; Site: TWinControl): string; virtual;
property OnSave: TOnSaveControl read FOnSave write FOnSave; property OnSave: TOnSaveControl read FOnSave write FOnSave;
property OnRestore: TOnReloadControl read FOnRestore write FOnRestore; property OnRestore: TOnReloadControl read FOnRestore write FOnRestore;
end; end;
function TryRename(AComp: TComponent; const NewName: string): boolean;
var var
DockMaster: TDockMaster; //for access by docksites on Reload... DockMaster: TDockMaster; //for access by docksites on Reload...
@ -111,22 +115,14 @@ type
TControlAccess = class(TControl) TControlAccess = class(TControl)
end; end;
{
const //what characters are acceptable, for unique names? const //what characters are acceptable, for unique names?
PanelNames: array[TAlign] of string = ( PanelNames: array[TAlign] of string = (
'', '', //alNone, alTop, '', '', //alNone, alTop,
'_Elastic_Bottom_', '_Elastic_Left_', '_Elastic_Right_', '_Elastic_Bottom_', '_Elastic_Left_', '_Elastic_Right_',
'', '' //alClient, alCustom '', '' //alClient, alCustom
); );
}
function TryRename(AComp: TComponent; const NewName: string): boolean;
begin
Result := True; //assume done
try
AComp.Name := NewName;
except
Result := False;
end;
end;
{ TDockMaster } { TDockMaster }
@ -183,7 +179,6 @@ begin
if pnl = nil then begin if pnl = nil then begin
//create the components //create the components
pnl := TDockPanel.Create(po); //owned by? pnl := TDockPanel.Create(po); //owned by?
LastPanel := pnl; //for reload layout
TryRename(pnl, pnlName); TryRename(pnl, pnlName);
pnl.Caption := ''; pnl.Caption := '';
pnl.Parent := AForm; pnl.Parent := AForm;
@ -217,6 +212,7 @@ begin
ElasticSites.Add(pnl); ElasticSites.Add(pnl);
{$ENDIF} {$ENDIF}
end; end;
LastPanel := pnl; //for reload layout
end; end;
end; end;
end; end;
@ -225,7 +221,7 @@ end;
function TDockMaster.CreateDockable(const AName: string; function TDockMaster.CreateDockable(const AName: string;
fMultiInst: boolean; fWrap: boolean): TWinControl; fMultiInst: boolean; fWrap: boolean): TWinControl;
var var
nb: TEasyBook; nb: TCustomDockSite;
begin begin
(* Create a dockable form, based on its name. (* Create a dockable form, based on its name.
Used also to restore a layout. Used also to restore a layout.
@ -268,10 +264,12 @@ begin
//create a docking handle - should become a component? //create a docking handle - should become a component?
img := TImage.Create(AForm); //we could own the img, and be notified when its parent becomes nil img := TImage.Create(AForm); //we could own the img, and be notified when its parent becomes nil
img.Align := alNone; img.Align := alNone;
//if not ForIDE then if ForIDE then
begin //prevent problems with the following code! try //begin //prevent problems with the following code!
img.AnchorParallel(akRight,0,Result); img.AnchorParallel(akRight,0,Result);
img.AnchorParallel(akTop,0,Result); img.AnchorParallel(akTop,0,Result);
except
DebugLn('error AnchorParallel');
end; end;
img.Anchors:=[akRight,akTop]; img.Anchors:=[akRight,akTop];
img.Cursor := crHandPoint; img.Cursor := crHandPoint;
@ -304,19 +302,21 @@ function TDockMaster.ReloadDockedControl(const AName: string;
var var
i: integer; i: integer;
lst: TStringList; lst: TStringList;
nb: TEasyBook absolute Result; nb: TCustomDockSite absolute Result;
s: string; s: string;
ctl: TControl; ctl: TControl;
begin begin
(* Reload docked controls - forms or NoteBook (* Reload docked control(s) - forms or NoteBook
Called from AppDockManager on ReloadDockedControl. Called from AppDockManager on ReloadDockedControl.
NoteBook identified by comma separated names in AName. NoteBook identified by comma separated names in AName.
FileEditor identified by dot in name? (not here)
Call OnRestore before or after notebook handling?
*) *)
if Pos(',', AName) > 0 then begin if Pos(',', AName) > 1 then begin
//restore NoteBook //restore NoteBook
nb := NoteBookCreate(Site); nb := NoteBookCreate(Site); //!!!which notebook class???
{$IFDEF old}
lst := TStringList.Create; lst := TStringList.Create;
try try
lst.CommaText := AName; lst.CommaText := AName;
@ -334,6 +334,9 @@ begin
finally finally
lst.Free; lst.Free;
end; end;
{$ELSE}
nb.AsString := AName;
{$ENDIF}
end else begin end else begin
//restore control (form?) //restore control (form?)
Result := nil; Result := nil;
@ -344,6 +347,15 @@ begin
end; end;
end; end;
function TDockMaster.SaveDockedControl(ACtrl: TControl;
Site: TWinControl): string;
begin
if Assigned(FOnSave) then
Result := FOnSave(ACtrl);
if Result = '' then
Result := Site.GetDockCaption(ACtrl);
end;
procedure TDockMaster.FormEndDock(Sender, Target: TObject; X, Y: Integer); procedure TDockMaster.FormEndDock(Sender, Target: TObject; X, Y: Integer);
var var
ctl: TControl; ctl: TControl;
@ -425,7 +437,7 @@ var
begin begin
(* Restore a layout. (* Restore a layout.
- Create all floating sites - Create all floating sites
- Create all ElasticSites - Create all ElasticSites - should exist???
- Reload all docked controls - Reload all docked controls
Notebooks? Notebooks?
@ -445,20 +457,7 @@ Notebooks?
site.BoundsRect := SiteRec.Bounds; site.BoundsRect := SiteRec.Bounds;
end else begin end else begin
//hosted panel - find parent form //hosted panel - find parent form
{$IFDEF old}
if Factory = nil then
hcomp := Screen.FindForm(SiteName)
else begin
hcomp := Factory.FindComponent(SiteName);
//hcomp := Factory.ReloadDockedControl(SiteName); - reload form!?
end;
if (hcomp = nil) or not (hcomp is TWinControl) then
host := TForm.Create(Application);
AddElasticSites(host, [SiteRec.Align]);
site := LastPanel;
{$ELSE}
site := MakePanel(SiteName, SiteRec.Align); site := MakePanel(SiteName, SiteRec.Align);
{$ENDIF}
end; end;
//debug //debug
if site = nil then begin if site = nil then begin
@ -528,7 +527,8 @@ end;
function TDockMaster.ReloadForm(const AName: string; fMultiInst: boolean): TWinControl; function TDockMaster.ReloadForm(const AName: string; fMultiInst: boolean): TWinControl;
var var
basename, instname: string; //instname: string
basename: string;
fc: TWinControlClass; fc: TWinControlClass;
fo: TComponent; //form owner fo: TComponent; //form owner
ctl: TControl; ctl: TControl;
@ -541,14 +541,20 @@ const
i, l, instno: integer; i, l, instno: integer;
begin begin
//find the instance number, if present //find the instance number, if present
instno := 0;
l := Length(AName); l := Length(AName);
i := l; i := l;
while AName[i] in digits do while AName[i] in digits do
dec(i); dec(i);
//i now is the position of the last non-digit in the name //i now is the position of the last non-digit in the name
//extract the instance number (*extract the instance number
TReader.ReadRootComponent appends "_nnn"
*)
{$IFDEF old}
if AName[i] = '_' then //handle name_inst
basename := Copy(AName, 1, i-1)
else
basename := Copy(AName, 1, i); basename := Copy(AName, 1, i);
instno := 0;
while i < l do begin while i < l do begin
inc(i); inc(i);
instno := instno * 10 + ord(AName[i])-ord('0'); instno := instno * 10 + ord(AName[i])-ord('0');
@ -558,6 +564,14 @@ const
instno := 1; //default instance number for forms instno := 1; //default instance number for forms
//lookup existing instance //lookup existing instance
instname := basename + IntToStr(instno); instname := basename + IntToStr(instno);
{$ELSE}
if AName[i] = '_' then begin
//assume this is a multi-instance name
basename := 'T' + Copy(AName, 1, i-1);
//instname := AName;
end else
basename := 'T' + AName;
{$ENDIF}
end; end;
begin begin
@ -573,6 +587,10 @@ begin
Result := Screen.FindForm(AName); Result := Screen.FindForm(AName);
if Result <> nil then if Result <> nil then
exit; //found it exit; //found it
//also search in our Owner
cmp := Owner.FindComponent(AName);
if (Result <> nil) and (Result is TWinControl) then
exit;
end; end;
//check if Factory can provide the form //check if Factory can provide the form
if assigned(Factory) then begin if assigned(Factory) then begin
@ -589,6 +607,7 @@ begin
Result := TForm.Create(fo); //named Form1, Form2... - not now??? Result := TForm.Create(fo); //named Form1, Form2... - not now???
end else begin end else begin
//create new instance //create new instance
{$IFDEF old}
if fMultiInst then if fMultiInst then
SplitName SplitName
else else
@ -599,8 +618,14 @@ begin
//assert(assigned(fc), 'class not registered: ' + basename); //assert(assigned(fc), 'class not registered: ' + basename);
if fMultiInst and not assigned(fc) then if fMultiInst and not assigned(fc) then
fc := TWinControlClass(GetClass('T' + AName)); //retry with non-splitted name fc := TWinControlClass(GetClass('T' + AName)); //retry with non-splitted name
if not assigned(fc) then {$ELSE}
SplitName;
fc := TWinControlClass(GetClass(basename));
{$ENDIF}
if not assigned(fc) then begin
DebugLn(basename , ' is not a registered class');
exit(nil); //bad form name exit(nil); //bad form name
end;
Result := fc.Create(fo); Result := fc.Create(fo);
if Result.Name <> AName then if Result.Name <> AName then
TryRename(Result, AName); TryRename(Result, AName);
@ -971,21 +996,29 @@ function TAppDockManager.ReloadDockedControl(const AName: string): TControl;
begin begin
(* Special connect to DockManager, and restore NoteBooks. (* Special connect to DockManager, and restore NoteBooks.
*) *)
if False then if False then Result:=inherited ReloadDockedControl(AName); //asking DockSite (very bad idea)
Result:=inherited ReloadDockedControl(AName); //asking DockSite (very bad idea)
if assigned(DockMaster) then begin if assigned(DockMaster) then begin
//Result := DockMaster.CreateDockable(AName, FDockSite, True, False);
//Result := DockMaster.CreateDockable(AName, True, False);
Result := DockMaster.ReloadDockedControl(AName, FDockSite); Result := DockMaster.ReloadDockedControl(AName, FDockSite);
end else begin //application default - search Application or Screen? end else begin //application default - search Application or Screen?
//Owner.FindComponent(AControlName) as TControl;
//Result := Application.FindComponent(AName) as TControl;
Result := Screen.FindForm(AName); Result := Screen.FindForm(AName);
//if Result = nil then Result := 'T' + AName //if Result = nil then Result := 'T' + AName
{ TODO -cdocking : load form by name, or create from typename } { TODO -cdocking : load form by name, or create from typename }
end; end;
if Result <> nil then if Result <> nil then
DebugLn('Reloaded %s.%s', [Result.Owner.Name, Result.Name]); DebugLn('Reloaded %s.%s', [Result.Owner.Name, Result.Name])
else
DebugLn('NOT reloaded: ', AName, ' ------------------');
end;
function TAppDockManager.SaveDockedControl(Control: TControl //; Site: TWinControl
): string;
begin
if assigned(DockMaster) then
Result := DockMaster.SaveDockedControl(Control, FDockSite)
else
//Result:=inherited SaveDockedControl(Control, FDockSite);
Result:=inherited SaveDockedControl(Control);
DebugLn('Saved as ', Result);
end; end;
initialization initialization