dockmanager example: added MiniIDE2 project

git-svn-id: trunk@25562 -
This commit is contained in:
dodi 2010-05-21 11:25:33 +00:00
parent 84dd68a5f0
commit db7ac79d9e
10 changed files with 1011 additions and 11 deletions

8
.gitattributes vendored
View File

@ -2905,6 +2905,14 @@ examples/dockmanager/ide_demo/feditbook.lfm 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.pas svneol=native#text/plain
examples/dockmanager/ide_demo2/MiniIDE2.lpi svneol=native#text/plain
examples/dockmanager/ide_demo2/MiniIDE2.lpr svneol=native#text/plain
examples/dockmanager/ide_demo2/fclientform2.lfm svneol=native#text/plain
examples/dockmanager/ide_demo2/fclientform2.pas svneol=native#text/pascal
examples/dockmanager/ide_demo2/feditbook2.lfm svneol=native#text/plain
examples/dockmanager/ide_demo2/feditbook2.pas svneol=native#text/pascal
examples/dockmanager/ide_demo2/fminiide2.lfm svneol=native#text/plain
examples/dockmanager/ide_demo2/fminiide2.pas 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/easydockmgr.lpk svneol=native#text/plain

View File

@ -1,10 +1,6 @@
The examples/dockmanager directory contains several projects,
provided by DoDi <DrDiettrich1@aol.com>
!!!BEWARE!!!
As long as new autosizing doesn't work properly,
you'll have to use -dOldAutoSize.
patches/
========
@ -23,11 +19,6 @@ easyedit/easyeditor
===================
demonstrates an multi-window editor with dockable pages (files).
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.
@ -41,11 +32,20 @@ ide_demo/MiniIDE
================
A Lazarus-like IDE with:
- dockable windows
- elastic docksites
- 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...
ide_demo2/MiniIDE2
==================
A Lazarus-like IDE with:
- dockable windows, including editor forms
- persistent layouts with special form handling
In contrast to MiniIDE this project only uses dockable forms,
floating in a hostsite that allows to dock multiple forms together.
An editor form only is one of such forms, special only in the save/reload of its content.
An elastic site is created only for the MainBar, to allow for monolithic (single-form) layouts.
toolbar/test1

View File

@ -0,0 +1,87 @@
<?xml version="1.0"?>
<CONFIG>
<ProjectOptions>
<PathDelim Value="\"/>
<Version Value="7"/>
<General>
<SessionStorage Value="InIDEConfig"/>
<MainUnit Value="0"/>
<AutoCreateForms Value="False"/>
<TargetFileExt Value=".exe"/>
<Title Value="MiniIDE2"/>
<UseXPManifest Value="True"/>
</General>
<VersionInfo>
<StringTable Comments="" CompanyName="" FileDescription="" FileVersion="0.0.0.0" InternalName="" LegalCopyright="" LegalTrademarks="" OriginalFilename="" ProductName="" ProductVersion=""/>
</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="4">
<Unit0>
<Filename Value="MiniIDE2.lpr"/>
<IsPartOfProject Value="True"/>
<UnitName Value="MiniIDE2"/>
</Unit0>
<Unit1>
<Filename Value="fminiide2.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="MainBar"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="fMiniIde2"/>
</Unit1>
<Unit2>
<Filename Value="feditbook2.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="EditBook"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="fEditBook2"/>
</Unit2>
<Unit3>
<Filename Value="fclientform2.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="ViewWindow"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="fClientForm2"/>
</Unit3>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="8"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="MiniIDE2"/>
</Target>
<SearchPaths>
<IncludeFiles Value="lib\i386-win32\"/>
<OtherUnitFiles Value="D:\SourceForge\lazarus\examples\dockmanager\easyedit\;D:\SourceForge\lazarus\examples\dockmanager\lib\i386-win32\;D:\SourceForge\lazarus\ideintf\units\i386-win32\;D:\SourceForge\lazarus\lcl\units\i386-win32\;D:\SourceForge\lazarus\lcl\units\i386-win32\win32\;D:\SourceForge\lazarus\packager\units\i386-win32\"/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Other>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
</CONFIG>

View File

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

View File

@ -0,0 +1,23 @@
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'
ParentColor = False
end
end

View File

@ -0,0 +1,68 @@
unit fClientForm2;
(* 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.
*)
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
StdCtrls, ExtCtrls;
type
TViewWindow = class(TForm)
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;
{$R *.lfm}
end.

View File

@ -0,0 +1,13 @@
inherited EditBook: TEditBook
Left = 670
Top = 115
Caption = 'EditBook'
OnClose = FormClose
object StatusBar1: TStatusBar[0]
Left = 0
Height = 23
Top = 217
Width = 320
Panels = <>
end
end

View File

@ -0,0 +1,301 @@
unit fEditBook2;
(* 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???
{$DEFINE DockSite}
interface
uses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
ComCtrls, SynEdit, EasyDockSite, fDockBook;
type
(* SynEdits seem not to dock properly, so we make them part of a dockable form.
Docked SynEdits have 2 sets of scrollbars!?
*)
//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 (TEditPages).
It can have more components, here: a StatusBar.
Special layout save/restore methods, to handle opened files.
*)
{ TEditBook }
//TEditBook = class(TForm)
TEditBook = class(TCustomDockSite)
StatusBar1: TStatusBar;
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
protected
FEdit: TEditPages;
{$IFDEF new}
function GetFloatingDockSiteClass: TWinControlClass; override;
{$ENDIF}
public
constructor Create(TheOwner: TComponent); override;
function OpenFile(const AName: string): boolean; //virtual;
function AddFile(const AName: string): boolean; //virtual;
procedure LoadFromStream(strm: TStream); override;
procedure SaveToStream(strm: TStream); override;
property Pages: TEditPages read FEdit;
end;
function GetEditWindow(ctl: TControl): TEditBook;
const
EditBookID = CustomDockSiteID + 1;
var
MRUEdit: TEditPage; //Most Recently Used EditPage
implementation
uses
uMakeSite, fFloatingSite;
function GetEditWindow(ctl: TControl): TEditBook;
begin
while assigned(ctl) and not (ctl is TEditBook) do
ctl := ctl.Parent; //floathost?
Result := TEditBook(ctl);
assert(Result <> nil, 'not in EditBook');
end;
{ TEditBook }
{$IFDEF new}
function TEditBook.GetFloatingDockSiteClass: TWinControlClass;
begin
//Result:=inherited GetFloatingDockSiteClass;
Result := TFloatingSite;
end;
{$ENDIF}
procedure TEditBook.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
CloseAction := caFree;
end;
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;
end;
function TEditBook.AddFile(const AName: string): boolean;
var
i: integer;
ctl: TControl;
ep: TEditPage absolute ctl;
begin
for i := 0 to FEdit.DockClientCount - 1 do begin
ctl := FEdit.DockClients[i];
Result := ep.FileName = AName;
if Result then
exit; //activate this page???
end;
//file not found
Result := OpenFile(AName);
end;
function TEditBook.OpenFile(const AName: string): boolean;
var
se: TEditPage;
begin
se := TEditPage.Create(Owner);
se.LoadFile(AName);
se.ManualDock(FEdit);
end;
procedure TEditBook.LoadFromStream(strm: TStream);
var
i, n: byte;
fn: string;
begin
(* Merge list of files with already open files.
*)
//inherited LoadFromStream(strm);
i := strm.ReadByte;
assert(i = EditBookID, 'bad stream');
n := strm.ReadByte;
for i := 0 to n-1 do begin
fn := strm.ReadAnsiString;
AddFile(fn);
end;
end;
procedure TEditBook.SaveToStream(strm: TStream);
var
i, n: byte;
ctl: TControl;
ep: TEditPage absolute ctl;
begin
(* Stream list of open files.
*)
//inherited SaveToStream(strm);
strm.WriteByte(EditBookID);
n := FEdit.DockClientCount;
strm.WriteByte(n);
for i := 0 to n - 1 do begin
ctl := FEdit.DockClients[i];
strm.WriteAnsiString(ep.FileName);
end;
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);
frm := GetEditWindow(self);
if frm is TEditBook then begin
//frm.Close;
frm.Release;
exit;
end;
end;
inherited AfterUndock(tabidx);
end;
{$R *.lfm}
initialization
RegisterClass(TEditBook);
RegisterClass(TEditPage);
end.

View File

@ -0,0 +1,145 @@
object MainBar: TMainBar
Left = 4
Height = 66
Top = 129
Width = 517
Caption = 'MainBar'
ClientHeight = 46
ClientWidth = 517
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 buDump: TButton
Left = 408
Height = 25
Top = 3
Width = 81
Caption = 'Dump'
OnClick = buDumpClick
TabOrder = 3
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'
OnClick = mnWindowDumpClick
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,334 @@
unit fMiniIde2;
(* 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 }
TMainBar = class(TForm)
buSave: TButton;
buRestore: TButton;
buDump: 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 buDumpClick(Sender: TObject);
procedure buRestoreClick(Sender: TObject);
procedure buSaveClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure mnExitClick(Sender: TObject);
procedure mnOpenClick(Sender: TObject);
procedure mnWindowDumpClick(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
LCLProc,
EasyDockSite,
uMakeSite, fEditBook2, fClientForm2;
{ 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.mnWindowDumpClick(Sender: TObject);
procedure DumpOwner(fo: TComponent);
var
i: integer;
cmp: TComponent;
begin
for i := 0 to fo.ComponentCount - 1 do begin
cmp := fo.Components[i];
//if cmp.Name <> '' then
begin
DebugLn(cmp.Name, ': ', cmp.ClassName);
end;
end;
end;
procedure DumpForms;
var
i: integer;
cmp: TComponent;
begin
DebugLn('- Forms');
for i := 0 to Screen.FormCount - 1 do begin
cmp := Screen.Forms[i];
//if cmp.Name <> '' then
begin
DebugLn(cmp.Name, ': ', cmp.ClassName);
end;
end;
end;
begin
//debug only
DebugLn('--- Screen');
DumpOwner(Screen);
DumpForms;
{
DebugLn('--- Owner');
DumpOwner(DockMaster.Owner);
}
DebugLn('--- end dump');
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
{$IFDEF old}
//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);
{$ELSE}
frm := GetEditWindow(MRUEdit);
{$ENDIF}
end;
if frm = nil then begin
frm := TEditBook.Create(Application);
//frm.ManualDock(nil);
DockLoader.MakeDockable(frm, true, 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.buDumpClick(Sender: TObject);
begin
DockMaster.DumpSites;
end;
procedure TMainBar.buSaveClick(Sender: TObject);
var
strm: TFileStream;
begin
(* Save layout.
This should inlude ALL forms, not only the dockable ones!
*)
if dlgLayout.Execute then begin
strm := TFileStream.Create(dlgLayout.FileName, fmCreate);
try
//save non-dockable forms
//save dockable forms and sites
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
Client: TViewWindow;
n: string;
begin
(* 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.
Should use: DockMaster.CreateDockable(TViewWindow) - RegisterClass!
*)
//lookup existing (assume single instance forms)
n := StringReplace(cap, ' ', '', [rfReplaceAll]);
Result := Screen.FindForm(n);
if Result = nil then begin
//create the form
Client := TViewWindow.Create(Self);
Client.Label1.Caption := cap;
//name it
Client.Caption := cap;
TryRename(Client, n);
DockMaster.MakeDockable(Client, fWrap, True);
Client.Visible := True;
Result := Client;
end else begin
//activate the existing form
Result.Show; //might be invisible
Result.SetFocus;
end;
end;
(* Special load/store cases:
ViewWindow: @<caption>
EditForm/Book: special load/save
EditPage?
*)
function TMainBar.OnReloadControl(const CtrlName: string;
ASite: TWinControl): TControl;
var
i: integer;
lst: TStringList;
s: string;
eb: TEditBook absolute Result;
ss: TStringStream;
begin
(* Handle special cases:
ViewWindow
EditBook
*)
if CtrlName[1] = '@' then begin
s := copy(CtrlName, 2, Length(CtrlName));
Result := CreateDockable(s, False);
//if Result <> nil then Result.Visible := True; //edit forms without pages are hidden?
end else if ord(CtrlName[1]) = EditBookID then begin
eb := TEditBook.Create(Application);
ss := TStringStream.Create(CtrlName);
try
eb.LoadFromStream(ss);
finally
ss.Free;
end;
end else
Result := nil; //for now
end;
function TMainBar.OnSaveControl(ACtrl: TControl): string;
var
i: integer;
ep: TEditPage;
ss: TStringStream;
begin
(* handle special cases:
ViewWindow
EditBook
*)
if ACtrl is TViewWindow then begin
Result := '@' + ACtrl.Caption
end else if ACtrl is TEditBook then begin
ss := TStringStream.Create('');
try
TEditBook(ACtrl).SaveToStream(ss);
Result := ss.DataString;
finally
ss.Free;
end;
//Result := ',' + TWinControl(ACtrl).GetDockCaption(ACtrl);
end else
Result := ''; //unhandled
//Result := ACtrl.HostDockSite.GetDockCaption(ACtrl);
end;
{$R *.lfm}
end.