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/fmastersite.lfm svneol=native#text/plain
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/easydocking.pas svneol=native#text/pascal
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/units
examples/designerbaseclass/units
examples/dockmanager/ide_demo/MiniIDE.rc
examples/dropfiles/units[!!-~]*.bak
examples/easter/*.bak
examples/easter/units

View File

@ -23,18 +23,27 @@ elasticsite/project1
demonstrates elastic dock sites, which become visible only after a control
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
=============
mainly demonstrates TToolBar/TToolButton related problems.
(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
Left = 413
Top = 306
Left = 670
Top = 115
Caption = 'EditBook'
OnActivate = FormActivate
OnClose = FormClose

View File

@ -11,15 +11,22 @@ unit fEditBook;
{$mode objfpc}{$H+}
{ 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
uses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
SynEdit,
fDockBook;
type
TEditPage = class(TSynEdit)
public
FileName: string;
procedure LoadFile(const AName: string);
end;
TEditBook = class(TEasyDockBook)
procedure FormActivate(Sender: TObject);
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
@ -28,7 +35,8 @@ type
protected
NRUEdit: TEditBook; //Next Recently Used EditBook
public
{ public declarations }
constructor Create(TheOwner: TComponent); override;
function OpenFile(const AName: string): boolean;
end;
var
@ -36,8 +44,17 @@ var
implementation
uses
uMakeSite;
{ TEditBook }
constructor TEditBook.Create(TheOwner: TComponent);
begin
inherited Create(TheOwner);
DockMaster.AddElasticSites(self, [alLeft, alRight, alBottom]);
end;
procedure TEditBook.FormActivate(Sender: TObject);
var
prev: TEditBook;
@ -78,6 +95,23 @@ begin
{$ENDIF}
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
{$I feditbook.lrs}

View File

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

View File

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

View File

@ -36,7 +36,9 @@ interface
uses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
ExtCtrls, ComCtrls, Menus,
fElasticSite, fEditBook, fEditForm;
//fElasticSite,
fEditBook,
fEditForm;
type
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"/>
<PathDelim Value="\"/>
<SearchPaths>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
<UnitOutputDirectory Value="..\lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Other>
<CompilerPath Value="$(CompPath)"/>

View File

@ -72,14 +72,12 @@ uses
Forms,
ExtCtrls, //splitter
Controls,
fDockBook,
ComCtrls; //TPageControl
type
TEasyTree = class; //forward declaration
TEasyZone = class; //forward declaration
TEasySplitter = TCustomSplitter;
TEasyBook = class(TEasyDockBook);
TEasyZonePart =
(
@ -170,6 +168,23 @@ type
property Top: integer read GetTop;
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 = class(TDockManager)
@ -201,18 +216,11 @@ type
FSiteRect: TRect; //to detect changed site extent
procedure UpdateTree;
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
//procedure ControlVisibilityChanged(Control: TControl; Visible: Boolean); override;
function ZoneFromPoint(SitePos: TPoint): TEasyZone;
function ReloadDockedControl(const AName: string): TControl; virtual;
function SaveDockedControl(Control: TControl): string; virtual;
protected //added
function FindControlZone(zone: TEasyZone; Control: TControl): TEasyZone;
procedure RemoveZone(Zone: TEasyZone);
@ -249,8 +257,33 @@ type
property HideSingleCaption: boolean read FHideSingleCaption write SetSingleCaption;
end;
function NoteBookCreate(AOwner: TWinControl): TEasyBook; inline;
procedure NoteBookAdd(ABook: TEasyBook; AItem: TControl); inline;
(* Application loader - a single method for consistency.
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
AlignNames: array[TAlign] of string = (
@ -269,7 +302,9 @@ const
'zpCloseButton' // header close button
);
var //debug only
//var AppDockBookClass: TDockBookClass;
var //debug only, these are valid only until drop
DropOn: TControl;
DockObj: TDragDockObject;
@ -279,6 +314,7 @@ uses
SysUtils, Types,
math,
Themes, LResources,
fDockBook,
LCLproc; //debugging
type
@ -292,33 +328,67 @@ const
HeaderButtons = [zpCloseButton];
{$ENDIF}
function NoteBookCreate(AOwner: TWinControl): TEasyBook; inline;
function NoteBookCreate(AOwner: TWinControl): TCustomDockSite;
begin
Result := TEasyBook.Create(AOwner);
(* Create default dockbook type.
*)
{
if assigned(AppDockBookClass) then
Result := AppDockBookClass.Create(AOwner)
else
}
Result := TEasyDockBook.Create(AOwner);
end;
procedure NoteBookAdd(ABook: TEasyBook; AItem: TControl); inline;
procedure NoteBookAdd(ABook: TCustomDockSite; AItem: TControl);
begin
AItem.ManualDock(ABook);
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
function {TCustomFormEditor.}CreateUniqueComponentName(const AClassName: string;
OwnerComponent: TComponent): string;
var
i, j: integer;
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;
if (OwnerComponent=nil) or (Result='') then exit;
i:=1;
while true do begin
j:=OwnerComponent.ComponentCount-1;
Result:=AClassName;
//strip leading 'T'
if (length(Result)>1) and (Result[1]='T') then
Result:=RightStr(Result,length(Result)-1);
//if trailing digit, append '_'
if Result[length(Result)] in ['0'..'9'] then
Result:=Result+'_';
Result:=Result+IntToStr(i);
//append instance number
j:=OwnerComponent.ComponentCount-1;
while (j>=0)
and (CompareText(Result,OwnerComponent.Components[j].Name)<>0) do
dec(j);
@ -477,7 +547,7 @@ procedure TEasyTree.InsertControl(Control: TControl; InsertAt: TAlign;
var
DropZone, OldZone, NewZone, OldParent, NewParent: TEasyZone;
r: TRect;
NoteBook: TEasyBook;
NoteBook: TCustomDockSite;
(* special cases:
1) first child in top zone - no 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.
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
//dock into book
if (FTopZone.FirstChild <> nil) then begin
//root zone is not empty
if (DropCtl is TEasyBook) then begin
NoteBook := DropCtl as TEasyBook;
if (DropCtl is TCustomDockSite) then begin
NoteBook := TCustomDockSite(DropCtl);
end else begin
//create new book
NoteBook := NoteBookCreate(FDockSite);
{$IFDEF replace}
NoteBook.ReplaceDockedControl(DropZone.ChildControl, NoteBook, nil, alCustom);
{$ELSE}
NoteBook.ManualDock(nil, nil);
NoteBook.ManualDock(nil, nil); //float it - purpose???
//hack: manually dock the notebook
FReplacingControl := NoteBook; //ignore insert (see above)
NoteBook.ManualDock(FDockSite); //move into DockClients[]
@ -640,7 +712,7 @@ begin
end;
//set control orientation
DropZone.AddSibling(NewZone, InsertAt);
//clear eventually moved zone
//clear eventually moved zone, when redocking within this site
if OldZone <> nil then begin
RemoveZone(OldZone); //must NOT modify moved control!
OldZone.Free;
@ -955,85 +1027,12 @@ type
BottomRight: TPoint;
Level: byte;
Orientation: TDockOrientation;
//Width, Height: word;
NameLen: integer; //+chars
NameLen: integer; //+chars, can be a complete notebook description
end;
var
ZoneRec: RZone;
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);
@ -1063,7 +1062,8 @@ procedure TEasyTree.LoadFromStream(Stream: TStream);
*)
for i := FDockSite.DockClientCount - 1 downto 0 do begin
ctl := FDockSite.DockClients[i];
ctl.ManualDock(nil);
ctl.Visible := True;
ctl.ManualDock(nil); //restore undocked position and extent
end;
end;
@ -1087,7 +1087,7 @@ procedure TEasyTree.LoadFromStream(Stream: TStream);
if NewCtl = nil then begin
//debug: create some control
NewCtl := TPanel.Create(DockSite);
NewCtl.Name := ZoneName;
TryRename(NewCtl, ZoneName);
end;
if NewCtl <> nil then begin
NewCtl.Visible := True;
@ -1103,10 +1103,8 @@ procedure TEasyTree.LoadFromStream(Stream: TStream);
dec(PrevLvl);
end;
if NewLvl = PrevLvl then //add sibling
//PrevZone.AddSibling(NewZone, alRight)
PrevZone.Parent.InsertAfter(PrevZone, NewZone)
else begin //NewLvl > PrevLvl - make child
//InZone.InsertAfter(PrevZone, NewZone);
PrevZone.InsertAfter(nil, NewZone);
PrevLvl := NewLvl;
end;
@ -1121,14 +1119,81 @@ begin
if GetRec > 0 then begin
FTopZone.BR := ZoneRec.BottomRight;
FTopZone.Orientation := ZoneRec.Orientation;
//if GetRec = 2 then MakeZone(FTopZone, 1);
MakeZones;
end;
//finish?
//remove all leafs without a child control?
//refresh the site
ResetBounds(True);
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);
var
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.
Apply ToolButtonAutoSizeAlign.patch to improve the appearance and behaviour
of the toolbar buttons.
of the toolbar buttons. (new version will use TToggleBox)
ToDo:
- 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)
Close docked forms on notebook destruction.
*)
(* Applications
@ -63,17 +52,14 @@ HostDockSite.UpdateDockCaption (provide composed dock caption)
{$mode objfpc}{$H+}
{$IFDEF WIN32}
{$DEFINE undockFix} //seems to be required for win32 widgetset
{$ELSE}
//no problems on Linux/gtk2
{$ENDIF}
{.$DEFINE undockFix}
{$DEFINE closeFix}
interface
uses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
ComCtrls, ExtCtrls, StdCtrls;
ComCtrls, ExtCtrls, StdCtrls, EasyDockSite;
type
TTabButton = class(TToolButton)
@ -94,7 +80,7 @@ type
{ TEasyDockBook }
TEasyDockBook = class(TForm)
TEasyDockBook = class(TCustomDockSite)
pnlDock: TPanel;
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
procedure FormCreate(Sender: TObject);
@ -107,18 +93,21 @@ type
procedure FormUnDock(Sender: TObject; Client: TControl;
NewTarget: TWinControl; var Allow: Boolean);
procedure ToolButton1Click(Sender: TObject);
private
protected
Tabs: TTabs;
CurTab: TTabButton;
protected
function GetDefaultDockCaption: string; override;
function GetControlTab(AControl: TControl): TTabButton;
procedure AfterUndock(tabidx: integer); virtual;
procedure LoadNames(const str: string); override;
function SaveNames: string; override;
public
StayDocked: boolean;
{$IFDEF undockFix}
destructor Destroy; override;
{$ENDIF}
{$IFDEF closeFix}
destructor Destroy; override;
{$IFDEF new}
procedure SetDockCaption(const AName: string);
{$ELSE}
{$ENDIF}
end;
@ -128,10 +117,6 @@ implementation
uses
fFloatingSite,
{$IFDEF WIN32}
Windows, //PostMessage
{$ELSE}
{$ENDIF}
LCLProc; //debug only
procedure Register;
@ -141,6 +126,7 @@ end;
{ TEasyDockBook }
{$IFDEF undockFix}
destructor TEasyDockBook.Destroy;
var
i: integer;
@ -157,7 +143,6 @@ begin
end of the application.
Fix: check ctl.ComponentState for csDestroying.
*)
{$IFDEF undockFix}
for i := DockClientCount - 1 downto 0 do begin
ctl := DockClients[i];
if not (csDestroying in ctl.ComponentState) then
@ -165,10 +150,37 @@ begin
DebugLn('Undocked %s P=%p H=%p', [ctl.Name,
pointer(ctl.Parent), pointer(ctl.HostDockSite)]);
end;
{$ELSE}
{$ENDIF}
inherited Destroy;
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;
var CloseAction: TCloseAction);
@ -180,24 +192,7 @@ var
begin
(* When an empty notebook is closed, it shall be freed.
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))]);
CloseAction := caFree;
end;
@ -234,13 +229,7 @@ begin
//unmanaged dock site requires an OnDockOver handler.
Accept := True; //this is the default, can be omitted
//make DockRect reflect the docking area
with Source do begin
ARect := pnlDock.ClientRect;
ARect.TopLeft := pnlDock.ClientToScreen(ARect.TopLeft);
inc(ARect.Bottom, ARect.Top);
inc(ARect.Right, ARect.Left);
DockRect := ARect;
end;
Source.DockRect := ScreenRect(pnlDock);
end;
procedure TEasyDockBook.FormGetSiteInfo(Sender: TObject; DockClient: TControl;
@ -248,6 +237,7 @@ procedure TEasyDockBook.FormGetSiteInfo(Sender: TObject; DockClient: TControl;
begin
//override TCustomForm behaviour!
CanDock := True;
InfluenceRect := ScreenRect(pnlDock);
end;
procedure TEasyDockBook.FormUnDock(Sender: TObject; Client: TControl;
@ -272,6 +262,24 @@ begin
Tabs.ButtonList.Delete(i);
Application.ReleaseComponent(btn);
//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}
//if not StayDocked and (Tabs.ButtonCount = 1) then begin
if False then begin
@ -291,27 +299,31 @@ begin
end else
{$ELSE}
//above code doesn't work :-(
//retry: explicit replace by last client, undock(?) and release
{$ENDIF}
if Tabs.ButtonCount > 0 then begin
//tab moved?
if CurTab = nil then begin //current button removed
//find next tab to show
if i >= Tabs.ButtonCount then
i := Pred(Tabs.ButtonCount); // dec(i);
if tabidx >= Tabs.ButtonCount then
tabidx := Pred(Tabs.ButtonCount); // dec(i);
//activate new tab
CurTab := Tabs.Buttons[i] as TTabButton;
CurTab := Tabs.Buttons[tabidx] as TTabButton;
CurTab.Down := True;
CurTab.Click;
end;
Caption := GetDefaultDockCaption;
end else if not StayDocked then begin
//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
//we are floating
Release;
exit;
end else if (HostDockSite <> nil) then begin //may be cleared already???
ManualDock(nil); //undock before closing
//DoUnDock(nil, nil);
//Dock(nil);
Release;
exit;
end;
Release;
end;
//update the host dock site and its DockManager
if HostDockSite <> nil then begin
@ -319,6 +331,8 @@ begin
TFloatingSite(HostDockSite).UpdateCaption(nil);
if HostDockSite.DockManager <> nil then
HostDockSite.Invalidate;
end else if Parent <> nil then begin
//notify - how?
end;
end;
@ -351,8 +365,7 @@ begin
end;
end;
{$IFDEF new}
procedure TEasyDockBook.SetDockCaption(const AName: string);
procedure TEasyDockBook.LoadNames(const str: string);
var
lst: TStringList;
i: integer;
@ -360,20 +373,40 @@ var
ctl: TControl;
begin
(* 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.CommaText := AName;
for i := 0 to lst.Count - 1 do begin
lst.CommaText := str;
//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];
ReloadDockedControl(s, ctl);
ReloadDockedControl(s, ctl); //handle everything in s!
if ctl <> nil then begin
ctl.Name := s;
ctl.ManualDock(self, nil, alCustom);
//ctl.Name := s;
ctl.ManualDock(pnlDock, nil, alCustom);
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);
var
@ -419,8 +452,8 @@ begin
end else
}
//both immediate and delayed drag start seem to work
Control.BeginDrag(False); //delayed docking
//Control.BeginDrag(True); //immediate drag
//Control.BeginDrag(False); //delayed docking
Control.BeginDrag(True); //immediate drag
end;
end;
end;

View File

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

View File

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

View File

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