mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-22 13:39:30 +02:00
dockmanager example: added MiniIDE2 project
git-svn-id: trunk@25562 -
This commit is contained in:
parent
84dd68a5f0
commit
db7ac79d9e
8
.gitattributes
vendored
8
.gitattributes
vendored
@ -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
|
||||
|
@ -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
|
||||
|
87
examples/dockmanager/ide_demo2/MiniIDE2.lpi
Normal file
87
examples/dockmanager/ide_demo2/MiniIDE2.lpi
Normal 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>
|
21
examples/dockmanager/ide_demo2/MiniIDE2.lpr
Normal file
21
examples/dockmanager/ide_demo2/MiniIDE2.lpr
Normal 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.
|
||||
|
23
examples/dockmanager/ide_demo2/fclientform2.lfm
Normal file
23
examples/dockmanager/ide_demo2/fclientform2.lfm
Normal 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
|
68
examples/dockmanager/ide_demo2/fclientform2.pas
Normal file
68
examples/dockmanager/ide_demo2/fclientform2.pas
Normal 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.
|
||||
|
13
examples/dockmanager/ide_demo2/feditbook2.lfm
Normal file
13
examples/dockmanager/ide_demo2/feditbook2.lfm
Normal 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
|
301
examples/dockmanager/ide_demo2/feditbook2.pas
Normal file
301
examples/dockmanager/ide_demo2/feditbook2.pas
Normal 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.
|
||||
|
145
examples/dockmanager/ide_demo2/fminiide2.lfm
Normal file
145
examples/dockmanager/ide_demo2/fminiide2.lfm
Normal 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
|
334
examples/dockmanager/ide_demo2/fminiide2.pas
Normal file
334
examples/dockmanager/ide_demo2/fminiide2.pas
Normal 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.
|
||||
|
Loading…
Reference in New Issue
Block a user