mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-13 09:49:22 +02:00
dockmanager example: cleanup, added and use uMiniRestore
git-svn-id: trunk@22544 -
This commit is contained in:
parent
6b0be3249d
commit
d8b319efd5
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -2797,6 +2797,7 @@ examples/dockmanager/package/ffloatingsite.lfm svneol=native#text/plain
|
|||||||
examples/dockmanager/package/ffloatingsite.lrs svneol=native#text/plain
|
examples/dockmanager/package/ffloatingsite.lrs svneol=native#text/plain
|
||||||
examples/dockmanager/package/ffloatingsite.pas svneol=native#text/pascal
|
examples/dockmanager/package/ffloatingsite.pas svneol=native#text/pascal
|
||||||
examples/dockmanager/package/pen.ico -text
|
examples/dockmanager/package/pen.ico -text
|
||||||
|
examples/dockmanager/package/uminirestore.pas svneol=native#text/pascal
|
||||||
examples/dockmanager/package/zoneheader.inc svneol=native#text/pascal
|
examples/dockmanager/package/zoneheader.inc svneol=native#text/pascal
|
||||||
examples/dockmanager/patches/FloatHostDockable.patch svneol=native#text/pascal
|
examples/dockmanager/patches/FloatHostDockable.patch svneol=native#text/pascal
|
||||||
examples/dockmanager/patches/NewClients.patch svneol=native#text/pascal
|
examples/dockmanager/patches/NewClients.patch svneol=native#text/pascal
|
||||||
|
@ -14,7 +14,6 @@ uses
|
|||||||
begin
|
begin
|
||||||
Application.Initialize;
|
Application.Initialize;
|
||||||
Application.CreateForm(TEditorSite, EditorSite);
|
Application.CreateForm(TEditorSite, EditorSite);
|
||||||
Application.CreateForm(TViewWindow, ViewWindow);
|
|
||||||
Application.Run;
|
Application.Run;
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
{ This is an automatically generated lazarus resource file }
|
|
||||||
|
|
||||||
LazarusResources.Add('TViewWindow','FORMDATA',[
|
LazarusResources.Add('TViewWindow','FORMDATA',[
|
||||||
'TPF0'#11'TViewWindow'#10'ViewWindow'#4'Left'#3'A'#1#6'Height'#3','#1#3'Top'#3
|
'TPF0'#11'TViewWindow'#10'ViewWindow'#4'Left'#3'A'#1#6'Height'#3','#1#3'Top'#3
|
||||||
+'L'#1#5'Width'#3#144#1#7'Caption'#6#10'ViewWindow'#12'ClientHeight'#3','#1#11
|
+'L'#1#5'Width'#3#144#1#7'Caption'#6#10'ViewWindow'#12'ClientHeight'#3','#1#11
|
||||||
|
@ -1,4 +1,12 @@
|
|||||||
unit fClientForm;
|
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+}
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
@ -21,13 +29,13 @@ type
|
|||||||
{ public declarations }
|
{ public declarations }
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
//var ViewWindow: TViewWindow; //useless
|
||||||
ViewWindow: TViewWindow;
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
LCLProc, fFloatingSite;
|
//LCLProc, //debugging only
|
||||||
|
fFloatingSite;
|
||||||
|
|
||||||
{ TViewWindow }
|
{ TViewWindow }
|
||||||
|
|
||||||
@ -35,18 +43,24 @@ procedure TViewWindow.FormEndDock(Sender, Target: TObject; X, Y: Integer);
|
|||||||
var
|
var
|
||||||
Site: TFloatingSite;
|
Site: TFloatingSite;
|
||||||
begin
|
begin
|
||||||
|
(* When we become floating, dock immediately into a new floating host docksite.
|
||||||
|
*)
|
||||||
if HostDockSite = nil then begin
|
if HostDockSite = nil then begin
|
||||||
DebugLn('--- floating');
|
//DebugLn('--- floating');
|
||||||
Site := TFloatingSite.Create(Application);
|
Site := TFloatingSite.Create(Application); //the new site
|
||||||
Site.BoundsRect := self.BoundsRect;
|
Site.BoundsRect := self.BoundsRect; //the new position and extension
|
||||||
ManualDock(Site);
|
ManualDock(Site);
|
||||||
end else
|
end else begin
|
||||||
DebugLn('--- in ' + HostDockSite.Name);
|
//DebugLn('--- in ' + HostDockSite.Name);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TViewWindow.Image1MouseMove(Sender: TObject; Shift: TShiftState;
|
procedure TViewWindow.Image1MouseMove(Sender: TObject; Shift: TShiftState;
|
||||||
X, Y: Integer);
|
X, Y: Integer);
|
||||||
begin
|
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
|
if ssLeft in Shift then begin
|
||||||
BeginDrag(False);
|
BeginDrag(False);
|
||||||
end;
|
end;
|
||||||
|
@ -11,6 +11,7 @@ inherited EditorSite: TEditorSite
|
|||||||
OnDeactivate = FormDeactivate
|
OnDeactivate = FormDeactivate
|
||||||
OnHide = FormHide
|
OnHide = FormHide
|
||||||
OnResize = FormResize
|
OnResize = FormResize
|
||||||
|
OnWindowStateChange = FormWindowStateChange
|
||||||
ShowInTaskBar = stAlways
|
ShowInTaskBar = stAlways
|
||||||
inherited pnlLeft: TPanel
|
inherited pnlLeft: TPanel
|
||||||
Height = 256
|
Height = 256
|
||||||
|
@ -1,40 +1,39 @@
|
|||||||
{ This is an automatically generated lazarus resource file }
|
|
||||||
|
|
||||||
LazarusResources.Add('TEditorSite','FORMDATA',[
|
LazarusResources.Add('TEditorSite','FORMDATA',[
|
||||||
'TPF0'#241#11'TEditorSite'#10'EditorSite'#4'Left'#3'b'#1#6'Height'#3','#1#5'W'
|
'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'
|
+'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'
|
+'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
|
+'nCreate'#7#10'FormCreate'#12'OnDeactivate'#7#14'FormDeactivate'#6'OnHide'#7
|
||||||
+#8'FormHide'#8'OnResize'#7#10'FormResize'#13'ShowInTaskBar'#7#8'stAlways'#0
|
+#8'FormHide'#8'OnResize'#7#10'FormResize'#19'OnWindowStateChange'#7#21'FormW'
|
||||||
+#241#6'TPanel'#7'pnlLeft'#6'Height'#3#0#1#0#0#241#9'TSplitter'#9'splitLeft'#6
|
+'indowStateChange'#13'ShowInTaskBar'#7#8'stAlways'#0#241#6'TPanel'#7'pnlLeft'
|
||||||
+'Height'#3#0#1#0#0#241#6'TPanel'#8'pnlRight'#4'Left'#3#144#1#6'Height'#3#0#1
|
+#6'Height'#3#0#1#0#0#241#9'TSplitter'#9'splitLeft'#6'Height'#3#0#1#0#0#241#6
|
||||||
+#0#0#241#6'TPanel'#9'pnlBottom'#3'Top'#3#4#1#5'Width'#3#144#1#0#0#241#9'TSpl'
|
+'TPanel'#8'pnlRight'#4'Left'#3#144#1#6'Height'#3#0#1#0#0#241#6'TPanel'#9'pnl'
|
||||||
+'itter'#10'splitRight'#4'Left'#3#140#1#6'Height'#3#0#1#0#0#241#10'TStatusBar'
|
+'Bottom'#3'Top'#3#4#1#5'Width'#3#144#1#0#0#241#9'TSplitter'#10'splitRight'#4
|
||||||
+#10'StatusBar1'#3'Top'#3#5#1#5'Width'#3#144#1#0#0#241#9'TSplitter'#11'splitB'
|
+'Left'#3#140#1#6'Height'#3#0#1#0#0#241#10'TStatusBar'#10'StatusBar1'#3'Top'#3
|
||||||
+'ottom'#3'Top'#3#0#1#5'Width'#3#144#1#0#0#242#2#7#9'TMainMenu'#9'MainMenu1'#4
|
+#5#1#5'Width'#3#144#1#0#0#241#9'TSplitter'#11'splitBottom'#3'Top'#3#0#1#5'Wi'
|
||||||
+'left'#3#240#0#3'top'#2'0'#0#9'TMenuItem'#6'mnFile'#7'Caption'#6#5'&File'#0#9
|
+'dth'#3#144#1#0#0#242#2#7#9'TMainMenu'#9'MainMenu1'#4'left'#3#240#0#3'top'#2
|
||||||
+'TMenuItem'#6'mnOpen'#7'Caption'#6#5'&Open'#7'OnClick'#7#11'mnOpenClick'#0#0
|
+'0'#0#9'TMenuItem'#6'mnFile'#7'Caption'#6#5'&File'#0#9'TMenuItem'#6'mnOpen'#7
|
||||||
+#9'TMenuItem'#9'MenuItem1'#7'Caption'#6#1'-'#0#0#9'TMenuItem'#6'mnExit'#7'Ca'
|
+'Caption'#6#5'&Open'#7'OnClick'#7#11'mnOpenClick'#0#0#9'TMenuItem'#9'MenuIte'
|
||||||
+'ption'#6#5'E&xit'#7'OnClick'#7#11'mnExitClick'#0#0#0#9'TMenuItem'#6'mnView'
|
+'m1'#7'Caption'#6#1'-'#0#0#9'TMenuItem'#6'mnExit'#7'Caption'#6#5'E&xit'#7'On'
|
||||||
+#7'Caption'#6#5'&View'#0#9'TMenuItem'#9'MenuItem2'#7'Caption'#6#16'Object In'
|
+'Click'#7#11'mnExitClick'#0#0#0#9'TMenuItem'#6'mnView'#7'Caption'#6#5'&View'
|
||||||
+'spector'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#9'MenuItem3'#7'Cap'
|
+#0#9'TMenuItem'#9'MenuItem2'#7'Caption'#6#16'Object Inspector'#7'OnClick'#7
|
||||||
+'tion'#6#8'Messages'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#9'MenuI'
|
+#13'ViewMenuClick'#0#0#9'TMenuItem'#9'MenuItem3'#7'Caption'#6#8'Messages'#7
|
||||||
+'tem4'#7'Caption'#6#13'Code Explorer'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'T'
|
+'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#9'MenuItem4'#7'Caption'#6#13
|
||||||
+'MenuItem'#9'MenuItem5'#7'Caption'#6#9'ToDo List'#7'OnClick'#7#13'ViewMenuCl'
|
+'Code Explorer'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#9'MenuItem5'
|
||||||
+'ick'#0#0#9'TMenuItem'#9'MenuItem6'#7'Caption'#6#13'Debug windows'#0#9'TMenu'
|
+#7'Caption'#6#9'ToDo List'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#9
|
||||||
+'Item'#9'MenuItem7'#7'Caption'#6#7'Watches'#7'OnClick'#7#13'ViewMenuClick'#0
|
+'MenuItem6'#7'Caption'#6#13'Debug windows'#0#9'TMenuItem'#9'MenuItem7'#7'Cap'
|
||||||
+#0#9'TMenuItem'#9'MenuItem8'#7'Caption'#6#11'BreakPoints'#7'OnClick'#7#13'Vi'
|
+'tion'#6#7'Watches'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#9'MenuIt'
|
||||||
+'ewMenuClick'#0#0#9'TMenuItem'#9'MenuItem9'#7'Caption'#6#15'Local Variables'
|
+'em8'#7'Caption'#6#11'BreakPoints'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMen'
|
||||||
+#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#10'MenuItem10'#7'Caption'#6
|
+'uItem'#9'MenuItem9'#7'Caption'#6#15'Local Variables'#7'OnClick'#7#13'ViewMe'
|
||||||
+#9'Registers'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#10'MenuItem11'
|
+'nuClick'#0#0#9'TMenuItem'#10'MenuItem10'#7'Caption'#6#9'Registers'#7'OnClic'
|
||||||
+#7'Caption'#6#10'Call Stack'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'
|
+'k'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#10'MenuItem11'#7'Caption'#6#10'Call'
|
||||||
+#10'MenuItem12'#7'Caption'#6#9'Assembler'#7'OnClick'#7#13'ViewMenuClick'#0#0
|
+' Stack'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#10'MenuItem12'#7'Ca'
|
||||||
+#9'TMenuItem'#10'MenuItem13'#7'Caption'#6#12'Debug Output'#7'OnClick'#7#13'V'
|
+'ption'#6#9'Assembler'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#10'Me'
|
||||||
+'iewMenuClick'#0#0#0#0#9'TMenuItem'#10'MenuItem14'#7'Caption'#6#8'&Windows'#0
|
+'nuItem13'#7'Caption'#6#12'Debug Output'#7'OnClick'#7#13'ViewMenuClick'#0#0#0
|
||||||
+#9'TMenuItem'#12'mnWindowDump'#7'Caption'#6#5'&Dump'#7'OnClick'#7#17'mnWindo'
|
+#0#9'TMenuItem'#10'MenuItem14'#7'Caption'#6#8'&Windows'#0#9'TMenuItem'#12'mn'
|
||||||
+'wDumpClick'#0#0#9'TMenuItem'#10'mnMinimize'#7'Caption'#6#12'Minimize all'#7
|
+'WindowDump'#7'Caption'#6#5'&Dump'#7'OnClick'#7#17'mnWindowDumpClick'#0#0#9
|
||||||
+'OnClick'#7#15'mnMinimizeClick'#0#0#9'TMenuItem'#9'mnRestore'#7'Caption'#6#11
|
+'TMenuItem'#10'mnMinimize'#7'Caption'#6#12'Minimize all'#7'OnClick'#7#15'mnM'
|
||||||
+'Restore all'#7'OnClick'#7#14'mnRestoreClick'#0#0#0#0#242#2#8#11'TOpenDialog'
|
+'inimizeClick'#0#0#9'TMenuItem'#9'mnRestore'#7'Caption'#6#11'Restore all'#7
|
||||||
+#11'OpenDialog1'#6'Filter'#6#25'*.pas|*.pas|All Files|*.*'#4'left'#3'5'#1#3
|
+'OnClick'#7#14'mnRestoreClick'#0#0#0#0#242#2#8#11'TOpenDialog'#11'OpenDialog'
|
||||||
+'top'#2'0'#0#0#0
|
+'1'#6'Filter'#6#25'*.pas|*.pas|All Files|*.*'#4'left'#3'5'#1#3'top'#2'0'#0#0
|
||||||
|
+#0
|
||||||
]);
|
]);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
unit fEditorSite;
|
unit fEditorSite;
|
||||||
(* EditorSite by DoDi <DrDiettrich1@aol.com>
|
(* EditorSite by DoDi <DrDiettrich1@aol.com>
|
||||||
mimics an Delphi editor window, that allows to
|
Mimics an Delphi editor window, that allows to dock other windows to it,
|
||||||
- dock other windows to it
|
with several extensions:
|
||||||
- optionally enlarging the window
|
- optionally enlarging the window
|
||||||
- detach a page into a new editor window
|
- detach a page into a new editor window
|
||||||
- move a page into a different editor window
|
- move a page into a different editor window
|
||||||
@ -10,24 +10,26 @@ mimics an Delphi editor window, that allows to
|
|||||||
Some quirks should be handled properly in a true IDE implementation:
|
Some quirks should be handled properly in a true IDE implementation:
|
||||||
|
|
||||||
For simplicity an IDE main menu has been added to the main window,
|
For simplicity an IDE main menu has been added to the main window,
|
||||||
that allows to create several project window dummies,
|
that allows to create several project (View) window dummies,
|
||||||
which can be docked to the editor window.
|
which can be docked to each other, or to the editor window.
|
||||||
|
|
||||||
Mixed docking of editor pages and View windows is not blocked, so that
|
Mixed docking of editor pages and View windows (currently) is not blocked,
|
||||||
you can have multiple edit views within the editor window.
|
so that you can have multiple edit views within the editor window.
|
||||||
|
|
||||||
Secondary editor windows should have the same docking capabilities.
|
Secondary editor windows should have the same docking capabilities.
|
||||||
|
(not yet)
|
||||||
|
|
||||||
Known bugs:
|
Known bugs:
|
||||||
- The IDE suspects dangling references - KEEP these references!
|
- The IDE suspects dangling references - KEEP these references!
|
||||||
Please report if you know how to fix this issue.
|
Please report if you know how to fix this issue.
|
||||||
|
|
||||||
|
+ Problems with non-form project windows.
|
||||||
|
Since the IDE windows are all forms, we only handle this case now.
|
||||||
*)
|
*)
|
||||||
|
|
||||||
{$mode objfpc}{$H+}
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
{$DEFINE clientform} //clients are forms?
|
{$DEFINE minimize} //test application minimize/restore
|
||||||
{.$DEFINE stdfloat} //using standard floating host?
|
|
||||||
|
|
||||||
interface
|
interface
|
||||||
|
|
||||||
@ -66,6 +68,7 @@ type
|
|||||||
procedure FormDeactivate(Sender: TObject);
|
procedure FormDeactivate(Sender: TObject);
|
||||||
procedure FormHide(Sender: TObject);
|
procedure FormHide(Sender: TObject);
|
||||||
procedure FormResize(Sender: TObject);
|
procedure FormResize(Sender: TObject);
|
||||||
|
procedure FormWindowStateChange(Sender: TObject);
|
||||||
procedure mnMinimizeClick(Sender: TObject);
|
procedure mnMinimizeClick(Sender: TObject);
|
||||||
procedure mnRestoreClick(Sender: TObject);
|
procedure mnRestoreClick(Sender: TObject);
|
||||||
procedure mnWindowDumpClick(Sender: TObject);
|
procedure mnWindowDumpClick(Sender: TObject);
|
||||||
@ -87,6 +90,7 @@ implementation
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
LCLProc,
|
LCLProc,
|
||||||
|
uMiniRestore,
|
||||||
fClientForm,
|
fClientForm,
|
||||||
fFloatingSite;
|
fFloatingSite;
|
||||||
|
|
||||||
@ -102,30 +106,21 @@ begin
|
|||||||
FEdit.Parent := self;
|
FEdit.Parent := self;
|
||||||
FEdit.Visible := True;
|
FEdit.Visible := True;
|
||||||
FEdit.DragMode := dmManual; //disallow undocking
|
FEdit.DragMode := dmManual; //disallow undocking
|
||||||
//FEdit.pnlDock.DragMode := dmManual;
|
|
||||||
FAutoExpand := True;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TEditorSite.CreateDockable(const cap: string): TWinControl;
|
function TEditorSite.CreateDockable(const cap: string): TWinControl;
|
||||||
var
|
var
|
||||||
Site: TFloatingSite;
|
Site: TFloatingSite;
|
||||||
{$IFDEF clientform}
|
|
||||||
Client: TViewWindow;
|
Client: TViewWindow;
|
||||||
{$ELSE}
|
|
||||||
Client: TWinControl;
|
|
||||||
{$ENDIF}
|
|
||||||
begin
|
begin
|
||||||
{$IFDEF clientform}
|
(* 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(Application);
|
Client := TViewWindow.Create(Application);
|
||||||
Client.Label1.Caption := cap;
|
Client.Label1.Caption := cap;
|
||||||
Client.Visible := True;
|
Client.Visible := True;
|
||||||
//Client.FloatingDockSiteClass := TFloatingSite;
|
|
||||||
{$ELSE}
|
|
||||||
Client := TPanel.Create(self);
|
|
||||||
Client.DragMode := dmAutomatic;
|
|
||||||
Client.DragKind := dkDock;
|
|
||||||
Client.Visible := True;
|
|
||||||
{$ENDIF}
|
|
||||||
//name it
|
//name it
|
||||||
Client.Caption := cap;
|
Client.Caption := cap;
|
||||||
try
|
try
|
||||||
@ -133,19 +128,9 @@ begin
|
|||||||
except
|
except
|
||||||
//here: simply ignore duplicate name
|
//here: simply ignore duplicate name
|
||||||
end;
|
end;
|
||||||
{$IFDEF stdfloat}
|
|
||||||
Client.ManualDock(nil);
|
|
||||||
{$ELSE}
|
|
||||||
//Client.FloatingDockSiteClass := TFloatingSite;
|
//Client.FloatingDockSiteClass := TFloatingSite;
|
||||||
{$IFDEF old}
|
|
||||||
//ManualFloat doesn't work as expected :-(
|
|
||||||
//Client.Align := alClient; //required for proper docking
|
|
||||||
Client.ManualFloat(Rect(200,200, 400,400));
|
|
||||||
{$ELSE}
|
|
||||||
Site := TFloatingSite.Create(Application);
|
Site := TFloatingSite.Create(Application);
|
||||||
Client.ManualDock(Site, nil, alClient);
|
Client.ManualDock(Site, nil, alClient);
|
||||||
{$ENDIF}
|
|
||||||
{$ENDIF}
|
|
||||||
Result := Client;
|
Result := Client;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -158,11 +143,31 @@ begin
|
|||||||
CreateDockable(item.Caption);
|
CreateDockable(item.Caption);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TEditorSite.OpenFile(const FileName: string): TObject;
|
||||||
|
begin
|
||||||
|
//todo: load the file
|
||||||
|
CurEdit := TEditPage.Create(self);
|
||||||
|
CurEdit.LoadFile(FileName);
|
||||||
|
CurEdit.ManualDock(FEdit);
|
||||||
|
//make it visible
|
||||||
|
Result := CurEdit; //or what?
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TEditorSite.mnOpenClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
if OpenDialog1.Execute then begin
|
||||||
|
OpenFile(OpenDialog1.FileName);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TEditorSite.mnExitClick(Sender: TObject);
|
procedure TEditorSite.mnExitClick(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
Close;
|
Close;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
// ----------- application window handling -------------
|
||||||
|
|
||||||
procedure TEditorSite.FormActivate(Sender: TObject);
|
procedure TEditorSite.FormActivate(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
//DebugLn('--- Activate');
|
//DebugLn('--- Activate');
|
||||||
@ -175,13 +180,18 @@ end;
|
|||||||
|
|
||||||
procedure TEditorSite.FormHide(Sender: TObject);
|
procedure TEditorSite.FormHide(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
DebugLn('--- FormHide'); //not when minimized manually (win32)
|
//DebugLn('--- FormHide'); //not when minimized manually (win32)
|
||||||
//mnMinimizeClick(Sender);
|
//mnMinimizeClick(Sender);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TEditorSite.FormResize(Sender: TObject);
|
procedure TEditorSite.FormResize(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
DebugLn('--- Resize');
|
//DebugLn('--- Resize');
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TEditorSite.FormWindowStateChange(Sender: TObject);
|
||||||
|
begin
|
||||||
|
DoMiniRestore;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TEditorSite.mnMinimizeClick(Sender: TObject);
|
procedure TEditorSite.mnMinimizeClick(Sender: TObject);
|
||||||
@ -189,6 +199,7 @@ var
|
|||||||
i: integer;
|
i: integer;
|
||||||
f: TForm;
|
f: TForm;
|
||||||
begin
|
begin
|
||||||
|
{$IFDEF minimize}
|
||||||
for i := 0 to Screen.FormCount - 1 do begin
|
for i := 0 to Screen.FormCount - 1 do begin
|
||||||
f := Screen.Forms[i];
|
f := Screen.Forms[i];
|
||||||
//if f = self then f.WindowState := wsMinimized else
|
//if f = self then f.WindowState := wsMinimized else
|
||||||
@ -197,18 +208,16 @@ begin
|
|||||||
f.WindowState := wsMinimized;
|
f.WindowState := wsMinimized;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
{$ELSE}
|
||||||
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TEditorSite.mnRestoreClick(Sender: TObject);
|
procedure TEditorSite.mnRestoreClick(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
|
{$IFDEF minimize}
|
||||||
WindowState := wsNormal;
|
WindowState := wsNormal;
|
||||||
end;
|
{$ELSE}
|
||||||
|
{$ENDIF}
|
||||||
procedure TEditorSite.mnOpenClick(Sender: TObject);
|
|
||||||
begin
|
|
||||||
if OpenDialog1.Execute then begin
|
|
||||||
OpenFile(OpenDialog1.FileName);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TEditorSite.mnWindowDumpClick(Sender: TObject);
|
procedure TEditorSite.mnWindowDumpClick(Sender: TObject);
|
||||||
@ -243,16 +252,6 @@ begin
|
|||||||
DebugLn('---');
|
DebugLn('---');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TEditorSite.OpenFile(const FileName: string): TObject;
|
|
||||||
begin
|
|
||||||
//todo: load the file
|
|
||||||
CurEdit := TEditPage.Create(self);
|
|
||||||
CurEdit.LoadFile(FileName);
|
|
||||||
CurEdit.ManualDock(FEdit);
|
|
||||||
//make it visible
|
|
||||||
Result := CurEdit; //or what?
|
|
||||||
end;
|
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
{$I feditorsite.lrs}
|
{$I feditorsite.lrs}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
<Description Value="EasyDocking Manager and Notebook"/>
|
<Description Value="EasyDocking Manager and Notebook"/>
|
||||||
<License Value="LGPL"/>
|
<License Value="LGPL"/>
|
||||||
<Version Major="1"/>
|
<Version Major="1"/>
|
||||||
<Files Count="8">
|
<Files Count="9">
|
||||||
<Item1>
|
<Item1>
|
||||||
<Filename Value="easydocksite.pas"/>
|
<Filename Value="easydocksite.pas"/>
|
||||||
<UnitName Value="EasyDockSite"/>
|
<UnitName Value="EasyDockSite"/>
|
||||||
@ -51,6 +51,10 @@
|
|||||||
<HasRegisterProc Value="True"/>
|
<HasRegisterProc Value="True"/>
|
||||||
<UnitName Value="fElasticSite"/>
|
<UnitName Value="fElasticSite"/>
|
||||||
</Item8>
|
</Item8>
|
||||||
|
<Item9>
|
||||||
|
<Filename Value="uminirestore.pas"/>
|
||||||
|
<UnitName Value="uMiniRestore"/>
|
||||||
|
</Item9>
|
||||||
</Files>
|
</Files>
|
||||||
<Type Value="RunAndDesignTime"/>
|
<Type Value="RunAndDesignTime"/>
|
||||||
<RequiredPkgs Count="2">
|
<RequiredPkgs Count="2">
|
||||||
|
@ -7,7 +7,8 @@ unit EasyDockMgr;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
EasyDockSite, fDockBook, fFloatingSite, fElasticSite, LazarusPackageIntf;
|
EasyDockSite, fDockBook, fFloatingSite, fElasticSite, uMiniRestore,
|
||||||
|
LazarusPackageIntf;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
@ -6,9 +6,7 @@ object FloatingSite: TFloatingSite
|
|||||||
Caption = 'FloatingSite'
|
Caption = 'FloatingSite'
|
||||||
DockSite = True
|
DockSite = True
|
||||||
OnDockDrop = FormDockDrop
|
OnDockDrop = FormDockDrop
|
||||||
OnDockOver = FormDockOver
|
|
||||||
OnUnDock = FormUnDock
|
OnUnDock = FormUnDock
|
||||||
ShowInTaskBar = stNever
|
|
||||||
UseDockManager = True
|
UseDockManager = True
|
||||||
LCLVersion = '0.9.29'
|
LCLVersion = '0.9.29'
|
||||||
Visible = True
|
Visible = True
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
LazarusResources.Add('TFloatingSite','FORMDATA',[
|
LazarusResources.Add('TFloatingSite','FORMDATA',[
|
||||||
'TPF0'#13'TFloatingSite'#12'FloatingSite'#4'Left'#3#175#1#6'Height'#3#9#1#3'T'
|
'TPF0'#13'TFloatingSite'#12'FloatingSite'#4'Left'#3#175#1#6'Height'#3#9#1#3'T'
|
||||||
+'op'#3#242#1#5'Width'#3'y'#1#7'Caption'#6#12'FloatingSite'#8'DockSite'#9#10
|
+'op'#3#242#1#5'Width'#3'y'#1#7'Caption'#6#12'FloatingSite'#8'DockSite'#9#10
|
||||||
+'OnDockDrop'#7#12'FormDockDrop'#10'OnDockOver'#7#12'FormDockOver'#8'OnUnDock'
|
+'OnDockDrop'#7#12'FormDockDrop'#8'OnUnDock'#7#10'FormUnDock'#14'UseDockManag'
|
||||||
+#7#10'FormUnDock'#13'ShowInTaskBar'#7#7'stNever'#14'UseDockManager'#9#10'LCL'
|
+'er'#9#10'LCLVersion'#6#6'0.9.29'#7'Visible'#9#0#0
|
||||||
+'Version'#6#6'0.9.29'#7'Visible'#9#0#0
|
|
||||||
]);
|
]);
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
unit fFloatingSite;
|
unit fFloatingSite;
|
||||||
(* Floating dock host.
|
(* Floating dock host.
|
||||||
|
Host one or more docked clients.
|
||||||
|
To distinguish multiple clients, use the form header style (named caption).
|
||||||
|
Destroy the site on the last undock.
|
||||||
|
|
||||||
ToDo:
|
Handle flaws of the Delphi docking model (improper undock).
|
||||||
- show summary caption
|
- Disallow TControls to float (else nothing but trouble).
|
||||||
|
- For the IDE, floating client forms must wrap themselves into a new
|
||||||
|
host site, to allow for continued docking of other clients.
|
||||||
*)
|
*)
|
||||||
|
|
||||||
{$mode objfpc}{$H+}
|
{$mode objfpc}{$H+}
|
||||||
@ -16,8 +21,6 @@ type
|
|||||||
TFloatingSite = class(TForm)
|
TFloatingSite = class(TForm)
|
||||||
procedure FormDockDrop(Sender: TObject; Source: TDragDockObject;
|
procedure FormDockDrop(Sender: TObject; Source: TDragDockObject;
|
||||||
X, Y: Integer);
|
X, Y: Integer);
|
||||||
procedure FormDockOver(Sender: TObject; Source: TDragDockObject;
|
|
||||||
X, Y: Integer; State: TDragState; var Accept: Boolean);
|
|
||||||
procedure FormUnDock(Sender: TObject; Client: TControl;
|
procedure FormUnDock(Sender: TObject; Client: TControl;
|
||||||
NewTarget: TWinControl; var Allow: Boolean);
|
NewTarget: TWinControl; var Allow: Boolean);
|
||||||
private
|
private
|
||||||
@ -34,8 +37,8 @@ var
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
EasyDockSite,
|
LCLproc, //debugging only
|
||||||
LCLproc;
|
EasyDockSite; //our DockManager
|
||||||
|
|
||||||
{ TFloatingSite }
|
{ TFloatingSite }
|
||||||
|
|
||||||
@ -45,6 +48,9 @@ var
|
|||||||
s: string;
|
s: string;
|
||||||
ctl: TControl;
|
ctl: TControl;
|
||||||
begin
|
begin
|
||||||
|
(* Show the combined captions of all clients.
|
||||||
|
Exclude client to be undocked.
|
||||||
|
*)
|
||||||
s := '';
|
s := '';
|
||||||
for i := 0 to DockClientCount - 1 do begin
|
for i := 0 to DockClientCount - 1 do begin
|
||||||
ctl := DockClients[i];
|
ctl := DockClients[i];
|
||||||
@ -52,63 +58,54 @@ begin
|
|||||||
s := s + GetDockCaption(ctl) + ', ';
|
s := s + GetDockCaption(ctl) + ', ';
|
||||||
end;
|
end;
|
||||||
SetLength(s, Length(s) - 2); //strip trailing ", "
|
SetLength(s, Length(s) - 2); //strip trailing ", "
|
||||||
Caption := s; //GetDockCaption(self);
|
Caption := s;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TFloatingSite.FormDockDrop(Sender: TObject; Source: TDragDockObject;
|
procedure TFloatingSite.FormDockDrop(Sender: TObject; Source: TDragDockObject;
|
||||||
X, Y: Integer);
|
X, Y: Integer);
|
||||||
begin
|
begin
|
||||||
|
(* Update the caption.
|
||||||
|
*)
|
||||||
AdjustCaption(nil);
|
AdjustCaption(nil);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TFloatingSite.FormDockOver(Sender: TObject; Source: TDragDockObject;
|
|
||||||
X, Y: Integer; State: TDragState; var Accept: Boolean);
|
|
||||||
begin
|
|
||||||
//DebugLn('DockOver');
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TFloatingSite.FormUnDock(Sender: TObject; Client: TControl;
|
procedure TFloatingSite.FormUnDock(Sender: TObject; Client: TControl;
|
||||||
NewTarget: TWinControl; var Allow: Boolean);
|
NewTarget: TWinControl; var Allow: Boolean);
|
||||||
begin
|
begin
|
||||||
(* Check for undock last client:
|
(* Check for undock last client, if allowed kill empty docksite.
|
||||||
- disallow to Nil (move window?)
|
|
||||||
- if allowed, kill empty docksite.
|
|
||||||
Refresh caption after undock.
|
Refresh caption after undock.
|
||||||
|
|
||||||
Shit: in both cases the docking management does the opposite of what it should do :-(
|
Shit: in both cases the docking management does the opposite of what it should do :-(
|
||||||
|
|
||||||
When the last control is dragged away, it's hosted in a *new* site.
|
When the last control is dragged away, it's hosted in a *new* site.
|
||||||
When a second control is dragged away, the entire site is moved.
|
When a second control is dragged away, the entire site is moved.
|
||||||
|
|
||||||
|
Fix: disallow TControls to become floating.
|
||||||
*)
|
*)
|
||||||
|
//try to distinguish between TControl and TWinControl (TCustomForm?)
|
||||||
|
Allow := (NewTarget <> nil) or (Client is TWinControl); //seems to be safe
|
||||||
|
if not Allow then
|
||||||
|
exit; //all done
|
||||||
|
|
||||||
if DockClientCount <= 1 then begin
|
if DockClientCount <= 1 then begin
|
||||||
if NewTarget = nil then begin
|
Release; //destroy empty site
|
||||||
//Allow := False; //deny
|
|
||||||
Allow := True; //move form - where???
|
|
||||||
Release;
|
|
||||||
end else
|
|
||||||
Release;
|
|
||||||
end else begin
|
end else begin
|
||||||
//allow float - action required?
|
AdjustCaption(Client); //update caption, excluding removed client
|
||||||
(* strange behaviour: client is undocked, but stays in the site.
|
DockManager.ResetBounds(True); //required with gtk2!?
|
||||||
The site is moved to the drop location.
|
|
||||||
*)
|
|
||||||
//Allow := NewTarget <> nil; //simply disallow undock to floating state (for now)
|
|
||||||
Allow := True; //bug!!!
|
|
||||||
//DragManager. - not helpful - where is the DockObject???
|
|
||||||
end;
|
|
||||||
if Allow then begin
|
|
||||||
AdjustCaption(Client);
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TFloatingSite.Loaded;
|
procedure TFloatingSite.Loaded;
|
||||||
begin
|
begin
|
||||||
|
(* select and configure the docking manager.
|
||||||
|
*)
|
||||||
inherited Loaded;
|
inherited Loaded;
|
||||||
if DockManager = nil then
|
if DockManager = nil then
|
||||||
DockManager := TEasyTree.Create(self);
|
DockManager := TEasyTree.Create(self);
|
||||||
if DockManager is TEasyTree then begin
|
if DockManager is TEasyTree then begin
|
||||||
TEasyTree(DockManager).HideSingleCaption := True;
|
//adjust as desired (order required!?)
|
||||||
TEasyTree(DockManager).SetStyle(hsForm);
|
TEasyTree(DockManager).HideSingleCaption := True; //only show headers for multiple clients
|
||||||
|
TEasyTree(DockManager).SetStyle(hsForm); //show client name in the header
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
108
examples/dockmanager/package/uminirestore.pas
Normal file
108
examples/dockmanager/package/uminirestore.pas
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
unit uMiniRestore;
|
||||||
|
(* Attempt to fix taskbar issues, related to application minimize/restore.
|
||||||
|
|
||||||
|
Symptoms
|
||||||
|
--------
|
||||||
|
On Linux/KDE all forms are listed in the taskbar, while only the main form
|
||||||
|
should be found there. This makes the restauration of an entire application
|
||||||
|
almost impossible, because all forms must be restored manually! :-(
|
||||||
|
|
||||||
|
The Application.OnMinimize/Restore handlers are never invoked, because the
|
||||||
|
according methods in TApplication are never invoked.
|
||||||
|
|
||||||
|
Usage
|
||||||
|
-----
|
||||||
|
In your MainForm.OnWindowStateChange call DoMiniRestore,
|
||||||
|
or set the handler to DummyInstance.MiniRestore.
|
||||||
|
|
||||||
|
Approach
|
||||||
|
--------
|
||||||
|
This workaround hides all forms when the main form is minimized, and
|
||||||
|
restores them when the main form is restored. [Note: hide, not minimize!]
|
||||||
|
(a single click on the taskbar entry of the application is sufficient :-)
|
||||||
|
|
||||||
|
This feature is enabled on the first minimize of the main form, and eventually
|
||||||
|
should be disabled when the main form is closed, to prevent side effects.
|
||||||
|
|
||||||
|
Currently the auto-hidden windows are only hidden (Visbible=False).
|
||||||
|
A combination with other properties could be used, to distinguish these from
|
||||||
|
intentionally hidden windows.
|
||||||
|
|
||||||
|
Screen.ActiveForm seems to reflect the focused form in OnWindowStateChange
|
||||||
|
of the main form. This form is remembered and focused after a restore.
|
||||||
|
*)
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Forms;
|
||||||
|
|
||||||
|
type
|
||||||
|
TMiniRestore = class
|
||||||
|
class procedure MiniRestore(Sender: TObject);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure DoMiniRestore;
|
||||||
|
|
||||||
|
var
|
||||||
|
DummyInstance: TMiniRestore;//never instantiated
|
||||||
|
EnableMinRestore: boolean; //eventually clear this before application shutdown
|
||||||
|
OldFocus: TCustomForm; //the focused form on minimize
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
class procedure TMiniRestore.MiniRestore(Sender: TObject);
|
||||||
|
begin
|
||||||
|
DoMiniRestore;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure DoMiniRestore;
|
||||||
|
var
|
||||||
|
i: integer;
|
||||||
|
f, mf: TCustomForm;
|
||||||
|
ws: TWindowState;
|
||||||
|
begin
|
||||||
|
(* Depending on the state of the main form, hide or restore all application forms.
|
||||||
|
*)
|
||||||
|
//check enabled and action
|
||||||
|
mf := Application.MainForm;
|
||||||
|
ws := mf.WindowState;
|
||||||
|
case ws of
|
||||||
|
wsMaximized: exit; //do nothing
|
||||||
|
wsMinimized:
|
||||||
|
begin
|
||||||
|
EnableMinRestore := True; //do minimize, allow for restore
|
||||||
|
OldFocus := Screen.ActiveCustomForm; //save focus window
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if not EnableMinRestore then
|
||||||
|
exit; //disabled
|
||||||
|
end;
|
||||||
|
//for all forms...
|
||||||
|
for i := 0 to Screen.CustomFormCount - 1 do begin
|
||||||
|
f := Screen.CustomForms[i];
|
||||||
|
case ws of
|
||||||
|
wsNormal:
|
||||||
|
if (f <> mf) and (f.WindowState = wsNormal)
|
||||||
|
and (f.ShowInTaskBar = stDefault)
|
||||||
|
and not f.Visible then begin
|
||||||
|
//f.WindowState := wsNormal;
|
||||||
|
f.Show;
|
||||||
|
end;
|
||||||
|
wsMinimized:
|
||||||
|
if (f <> mf) and (f.WindowState = wsNormal) and f.Visible then begin
|
||||||
|
//f.WindowState := wsMinimized;
|
||||||
|
//f.ShowInTaskBar := stDefault;
|
||||||
|
f.Hide;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
//set the focus
|
||||||
|
if (ws = wsNormal) and assigned(OldFocus) then
|
||||||
|
OldFocus.SetFocus;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user