lazarus/examples/dockmanager/ide_demo2/fminiide2.pas

334 lines
7.3 KiB
ObjectPascal

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, Forms, Controls, Dialogs, Menus, StdCtrls;
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.