dockmanager example: cleanup, added and use uMiniRestore

git-svn-id: trunk@22544 -
This commit is contained in:
dodi 2009-11-12 10:11:03 +00:00
parent 6b0be3249d
commit d8b319efd5
13 changed files with 258 additions and 140 deletions

1
.gitattributes vendored
View File

@ -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.pas svneol=native#text/pascal
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/patches/FloatHostDockable.patch svneol=native#text/pascal
examples/dockmanager/patches/NewClients.patch svneol=native#text/pascal

View File

@ -14,7 +14,6 @@ uses
begin
Application.Initialize;
Application.CreateForm(TEditorSite, EditorSite);
Application.CreateForm(TViewWindow, ViewWindow);
Application.Run;
end.

View File

@ -1,5 +1,3 @@
{ This is an automatically generated lazarus resource file }
LazarusResources.Add('TViewWindow','FORMDATA',[
'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

View File

@ -1,4 +1,12 @@
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+}
@ -21,13 +29,13 @@ type
{ public declarations }
end;
var
ViewWindow: TViewWindow;
//var ViewWindow: TViewWindow; //useless
implementation
uses
LCLProc, fFloatingSite;
//LCLProc, //debugging only
fFloatingSite;
{ TViewWindow }
@ -35,18 +43,24 @@ 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);
Site.BoundsRect := self.BoundsRect;
//DebugLn('--- floating');
Site := TFloatingSite.Create(Application); //the new site
Site.BoundsRect := self.BoundsRect; //the new position and extension
ManualDock(Site);
end else
DebugLn('--- in ' + HostDockSite.Name);
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;

View File

@ -11,6 +11,7 @@ inherited EditorSite: TEditorSite
OnDeactivate = FormDeactivate
OnHide = FormHide
OnResize = FormResize
OnWindowStateChange = FormWindowStateChange
ShowInTaskBar = stAlways
inherited pnlLeft: TPanel
Height = 256

View File

@ -1,40 +1,39 @@
{ This is an automatically generated lazarus resource file }
LazarusResources.Add('TEditorSite','FORMDATA',[
'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'
+'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
+#8'FormHide'#8'OnResize'#7#10'FormResize'#13'ShowInTaskBar'#7#8'stAlways'#0
+#241#6'TPanel'#7'pnlLeft'#6'Height'#3#0#1#0#0#241#9'TSplitter'#9'splitLeft'#6
+'Height'#3#0#1#0#0#241#6'TPanel'#8'pnlRight'#4'Left'#3#144#1#6'Height'#3#0#1
+#0#0#241#6'TPanel'#9'pnlBottom'#3'Top'#3#4#1#5'Width'#3#144#1#0#0#241#9'TSpl'
+'itter'#10'splitRight'#4'Left'#3#140#1#6'Height'#3#0#1#0#0#241#10'TStatusBar'
+#10'StatusBar1'#3'Top'#3#5#1#5'Width'#3#144#1#0#0#241#9'TSplitter'#11'splitB'
+'ottom'#3'Top'#3#0#1#5'Width'#3#144#1#0#0#242#2#7#9'TMainMenu'#9'MainMenu1'#4
+'left'#3#240#0#3'top'#2'0'#0#9'TMenuItem'#6'mnFile'#7'Caption'#6#5'&File'#0#9
+'TMenuItem'#6'mnOpen'#7'Caption'#6#5'&Open'#7'OnClick'#7#11'mnOpenClick'#0#0
+#9'TMenuItem'#9'MenuItem1'#7'Caption'#6#1'-'#0#0#9'TMenuItem'#6'mnExit'#7'Ca'
+'ption'#6#5'E&xit'#7'OnClick'#7#11'mnExitClick'#0#0#0#9'TMenuItem'#6'mnView'
+#7'Caption'#6#5'&View'#0#9'TMenuItem'#9'MenuItem2'#7'Caption'#6#16'Object In'
+'spector'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#9'MenuItem3'#7'Cap'
+'tion'#6#8'Messages'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#9'MenuI'
+'tem4'#7'Caption'#6#13'Code Explorer'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'T'
+'MenuItem'#9'MenuItem5'#7'Caption'#6#9'ToDo List'#7'OnClick'#7#13'ViewMenuCl'
+'ick'#0#0#9'TMenuItem'#9'MenuItem6'#7'Caption'#6#13'Debug windows'#0#9'TMenu'
+'Item'#9'MenuItem7'#7'Caption'#6#7'Watches'#7'OnClick'#7#13'ViewMenuClick'#0
+#0#9'TMenuItem'#9'MenuItem8'#7'Caption'#6#11'BreakPoints'#7'OnClick'#7#13'Vi'
+'ewMenuClick'#0#0#9'TMenuItem'#9'MenuItem9'#7'Caption'#6#15'Local Variables'
+#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#10'MenuItem10'#7'Caption'#6
+#9'Registers'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#10'MenuItem11'
+#7'Caption'#6#10'Call Stack'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'
+#10'MenuItem12'#7'Caption'#6#9'Assembler'#7'OnClick'#7#13'ViewMenuClick'#0#0
+#9'TMenuItem'#10'MenuItem13'#7'Caption'#6#12'Debug Output'#7'OnClick'#7#13'V'
+'iewMenuClick'#0#0#0#0#9'TMenuItem'#10'MenuItem14'#7'Caption'#6#8'&Windows'#0
+#9'TMenuItem'#12'mnWindowDump'#7'Caption'#6#5'&Dump'#7'OnClick'#7#17'mnWindo'
+'wDumpClick'#0#0#9'TMenuItem'#10'mnMinimize'#7'Caption'#6#12'Minimize all'#7
+'OnClick'#7#15'mnMinimizeClick'#0#0#9'TMenuItem'#9'mnRestore'#7'Caption'#6#11
+'Restore all'#7'OnClick'#7#14'mnRestoreClick'#0#0#0#0#242#2#8#11'TOpenDialog'
+#11'OpenDialog1'#6'Filter'#6#25'*.pas|*.pas|All Files|*.*'#4'left'#3'5'#1#3
+'top'#2'0'#0#0#0
+#8'FormHide'#8'OnResize'#7#10'FormResize'#19'OnWindowStateChange'#7#21'FormW'
+'indowStateChange'#13'ShowInTaskBar'#7#8'stAlways'#0#241#6'TPanel'#7'pnlLeft'
+#6'Height'#3#0#1#0#0#241#9'TSplitter'#9'splitLeft'#6'Height'#3#0#1#0#0#241#6
+'TPanel'#8'pnlRight'#4'Left'#3#144#1#6'Height'#3#0#1#0#0#241#6'TPanel'#9'pnl'
+'Bottom'#3'Top'#3#4#1#5'Width'#3#144#1#0#0#241#9'TSplitter'#10'splitRight'#4
+'Left'#3#140#1#6'Height'#3#0#1#0#0#241#10'TStatusBar'#10'StatusBar1'#3'Top'#3
+#5#1#5'Width'#3#144#1#0#0#241#9'TSplitter'#11'splitBottom'#3'Top'#3#0#1#5'Wi'
+'dth'#3#144#1#0#0#242#2#7#9'TMainMenu'#9'MainMenu1'#4'left'#3#240#0#3'top'#2
+'0'#0#9'TMenuItem'#6'mnFile'#7'Caption'#6#5'&File'#0#9'TMenuItem'#6'mnOpen'#7
+'Caption'#6#5'&Open'#7'OnClick'#7#11'mnOpenClick'#0#0#9'TMenuItem'#9'MenuIte'
+'m1'#7'Caption'#6#1'-'#0#0#9'TMenuItem'#6'mnExit'#7'Caption'#6#5'E&xit'#7'On'
+'Click'#7#11'mnExitClick'#0#0#0#9'TMenuItem'#6'mnView'#7'Caption'#6#5'&View'
+#0#9'TMenuItem'#9'MenuItem2'#7'Caption'#6#16'Object Inspector'#7'OnClick'#7
+#13'ViewMenuClick'#0#0#9'TMenuItem'#9'MenuItem3'#7'Caption'#6#8'Messages'#7
+'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#9'MenuItem4'#7'Caption'#6#13
+'Code Explorer'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#9'MenuItem5'
+#7'Caption'#6#9'ToDo List'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#9
+'MenuItem6'#7'Caption'#6#13'Debug windows'#0#9'TMenuItem'#9'MenuItem7'#7'Cap'
+'tion'#6#7'Watches'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#9'MenuIt'
+'em8'#7'Caption'#6#11'BreakPoints'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMen'
+'uItem'#9'MenuItem9'#7'Caption'#6#15'Local Variables'#7'OnClick'#7#13'ViewMe'
+'nuClick'#0#0#9'TMenuItem'#10'MenuItem10'#7'Caption'#6#9'Registers'#7'OnClic'
+'k'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#10'MenuItem11'#7'Caption'#6#10'Call'
+' Stack'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#10'MenuItem12'#7'Ca'
+'ption'#6#9'Assembler'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#10'Me'
+'nuItem13'#7'Caption'#6#12'Debug Output'#7'OnClick'#7#13'ViewMenuClick'#0#0#0
+#0#9'TMenuItem'#10'MenuItem14'#7'Caption'#6#8'&Windows'#0#9'TMenuItem'#12'mn'
+'WindowDump'#7'Caption'#6#5'&Dump'#7'OnClick'#7#17'mnWindowDumpClick'#0#0#9
+'TMenuItem'#10'mnMinimize'#7'Caption'#6#12'Minimize all'#7'OnClick'#7#15'mnM'
+'inimizeClick'#0#0#9'TMenuItem'#9'mnRestore'#7'Caption'#6#11'Restore all'#7
+'OnClick'#7#14'mnRestoreClick'#0#0#0#0#242#2#8#11'TOpenDialog'#11'OpenDialog'
+'1'#6'Filter'#6#25'*.pas|*.pas|All Files|*.*'#4'left'#3'5'#1#3'top'#2'0'#0#0
+#0
]);

View File

@ -1,7 +1,7 @@
unit fEditorSite;
(* EditorSite by DoDi <DrDiettrich1@aol.com>
mimics an Delphi editor window, that allows to
- dock other windows to it
Mimics an Delphi editor window, that allows to dock other windows to it,
with several extensions:
- optionally enlarging the window
- detach a page into a new 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:
For simplicity an IDE main menu has been added to the main window,
that allows to create several project window dummies,
which can be docked to the editor window.
that allows to create several project (View) window dummies,
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
you can have multiple edit views within the editor window.
Mixed docking of editor pages and View windows (currently) is not blocked,
so that you can have multiple edit views within the editor window.
Secondary editor windows should have the same docking capabilities.
(not yet)
Known bugs:
- The IDE suspects dangling references - KEEP these references!
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+}
{$DEFINE clientform} //clients are forms?
{.$DEFINE stdfloat} //using standard floating host?
{$DEFINE minimize} //test application minimize/restore
interface
@ -66,6 +68,7 @@ type
procedure FormDeactivate(Sender: TObject);
procedure FormHide(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure FormWindowStateChange(Sender: TObject);
procedure mnMinimizeClick(Sender: TObject);
procedure mnRestoreClick(Sender: TObject);
procedure mnWindowDumpClick(Sender: TObject);
@ -87,6 +90,7 @@ implementation
uses
LCLProc,
uMiniRestore,
fClientForm,
fFloatingSite;
@ -102,30 +106,21 @@ begin
FEdit.Parent := self;
FEdit.Visible := True;
FEdit.DragMode := dmManual; //disallow undocking
//FEdit.pnlDock.DragMode := dmManual;
FAutoExpand := True;
end;
function TEditorSite.CreateDockable(const cap: string): TWinControl;
var
Site: TFloatingSite;
{$IFDEF clientform}
Client: TViewWindow;
{$ELSE}
Client: TWinControl;
{$ENDIF}
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.Label1.Caption := cap;
Client.Visible := True;
//Client.FloatingDockSiteClass := TFloatingSite;
{$ELSE}
Client := TPanel.Create(self);
Client.DragMode := dmAutomatic;
Client.DragKind := dkDock;
Client.Visible := True;
{$ENDIF}
//name it
Client.Caption := cap;
try
@ -133,19 +128,9 @@ begin
except
//here: simply ignore duplicate name
end;
{$IFDEF stdfloat}
Client.ManualDock(nil);
{$ELSE}
//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);
Client.ManualDock(Site, nil, alClient);
{$ENDIF}
{$ENDIF}
Result := Client;
end;
@ -158,11 +143,31 @@ begin
CreateDockable(item.Caption);
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);
begin
Close;
end;
// ----------- application window handling -------------
procedure TEditorSite.FormActivate(Sender: TObject);
begin
//DebugLn('--- Activate');
@ -175,13 +180,18 @@ end;
procedure TEditorSite.FormHide(Sender: TObject);
begin
DebugLn('--- FormHide'); //not when minimized manually (win32)
//DebugLn('--- FormHide'); //not when minimized manually (win32)
//mnMinimizeClick(Sender);
end;
procedure TEditorSite.FormResize(Sender: TObject);
begin
DebugLn('--- Resize');
//DebugLn('--- Resize');
end;
procedure TEditorSite.FormWindowStateChange(Sender: TObject);
begin
DoMiniRestore;
end;
procedure TEditorSite.mnMinimizeClick(Sender: TObject);
@ -189,6 +199,7 @@ var
i: integer;
f: TForm;
begin
{$IFDEF minimize}
for i := 0 to Screen.FormCount - 1 do begin
f := Screen.Forms[i];
//if f = self then f.WindowState := wsMinimized else
@ -197,18 +208,16 @@ begin
f.WindowState := wsMinimized;
end;
end;
{$ELSE}
{$ENDIF}
end;
procedure TEditorSite.mnRestoreClick(Sender: TObject);
begin
{$IFDEF minimize}
WindowState := wsNormal;
end;
procedure TEditorSite.mnOpenClick(Sender: TObject);
begin
if OpenDialog1.Execute then begin
OpenFile(OpenDialog1.FileName);
end;
{$ELSE}
{$ENDIF}
end;
procedure TEditorSite.mnWindowDumpClick(Sender: TObject);
@ -243,16 +252,6 @@ begin
DebugLn('---');
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
{$I feditorsite.lrs}

View File

@ -17,7 +17,7 @@
<Description Value="EasyDocking Manager and Notebook"/>
<License Value="LGPL"/>
<Version Major="1"/>
<Files Count="8">
<Files Count="9">
<Item1>
<Filename Value="easydocksite.pas"/>
<UnitName Value="EasyDockSite"/>
@ -51,6 +51,10 @@
<HasRegisterProc Value="True"/>
<UnitName Value="fElasticSite"/>
</Item8>
<Item9>
<Filename Value="uminirestore.pas"/>
<UnitName Value="uMiniRestore"/>
</Item9>
</Files>
<Type Value="RunAndDesignTime"/>
<RequiredPkgs Count="2">

View File

@ -7,7 +7,8 @@ unit EasyDockMgr;
interface
uses
EasyDockSite, fDockBook, fFloatingSite, fElasticSite, LazarusPackageIntf;
EasyDockSite, fDockBook, fFloatingSite, fElasticSite, uMiniRestore,
LazarusPackageIntf;
implementation

View File

@ -6,9 +6,7 @@ object FloatingSite: TFloatingSite
Caption = 'FloatingSite'
DockSite = True
OnDockDrop = FormDockDrop
OnDockOver = FormDockOver
OnUnDock = FormUnDock
ShowInTaskBar = stNever
UseDockManager = True
LCLVersion = '0.9.29'
Visible = True

View File

@ -3,7 +3,6 @@
LazarusResources.Add('TFloatingSite','FORMDATA',[
'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
+'OnDockDrop'#7#12'FormDockDrop'#10'OnDockOver'#7#12'FormDockOver'#8'OnUnDock'
+#7#10'FormUnDock'#13'ShowInTaskBar'#7#7'stNever'#14'UseDockManager'#9#10'LCL'
+'Version'#6#6'0.9.29'#7'Visible'#9#0#0
+'OnDockDrop'#7#12'FormDockDrop'#8'OnUnDock'#7#10'FormUnDock'#14'UseDockManag'
+'er'#9#10'LCLVersion'#6#6'0.9.29'#7'Visible'#9#0#0
]);

View File

@ -1,8 +1,13 @@
unit fFloatingSite;
(* 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:
- show summary caption
Handle flaws of the Delphi docking model (improper undock).
- 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+}
@ -16,8 +21,6 @@ type
TFloatingSite = class(TForm)
procedure FormDockDrop(Sender: TObject; Source: TDragDockObject;
X, Y: Integer);
procedure FormDockOver(Sender: TObject; Source: TDragDockObject;
X, Y: Integer; State: TDragState; var Accept: Boolean);
procedure FormUnDock(Sender: TObject; Client: TControl;
NewTarget: TWinControl; var Allow: Boolean);
private
@ -34,8 +37,8 @@ var
implementation
uses
EasyDockSite,
LCLproc;
LCLproc, //debugging only
EasyDockSite; //our DockManager
{ TFloatingSite }
@ -45,6 +48,9 @@ var
s: string;
ctl: TControl;
begin
(* Show the combined captions of all clients.
Exclude client to be undocked.
*)
s := '';
for i := 0 to DockClientCount - 1 do begin
ctl := DockClients[i];
@ -52,63 +58,54 @@ begin
s := s + GetDockCaption(ctl) + ', ';
end;
SetLength(s, Length(s) - 2); //strip trailing ", "
Caption := s; //GetDockCaption(self);
Caption := s;
end;
procedure TFloatingSite.FormDockDrop(Sender: TObject; Source: TDragDockObject;
X, Y: Integer);
begin
(* Update the caption.
*)
AdjustCaption(nil);
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;
NewTarget: TWinControl; var Allow: Boolean);
begin
(* Check for undock last client:
- disallow to Nil (move window?)
- if allowed, kill empty docksite.
(* Check for undock last client, if allowed kill empty docksite.
Refresh caption after undock.
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 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 NewTarget = nil then begin
//Allow := False; //deny
Allow := True; //move form - where???
Release;
end else
Release;
Release; //destroy empty site
end else begin
//allow float - action required?
(* strange behaviour: client is undocked, but stays in the site.
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);
AdjustCaption(Client); //update caption, excluding removed client
DockManager.ResetBounds(True); //required with gtk2!?
end;
end;
procedure TFloatingSite.Loaded;
begin
(* select and configure the docking manager.
*)
inherited Loaded;
if DockManager = nil then
DockManager := TEasyTree.Create(self);
if DockManager is TEasyTree then begin
TEasyTree(DockManager).HideSingleCaption := True;
TEasyTree(DockManager).SetStyle(hsForm);
//adjust as desired (order required!?)
TEasyTree(DockManager).HideSingleCaption := True; //only show headers for multiple clients
TEasyTree(DockManager).SetStyle(hsForm); //show client name in the header
end;
end;

View 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.