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