mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-12 13:50:06 +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.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
|
||||
|
@ -14,7 +14,6 @@ uses
|
||||
begin
|
||||
Application.Initialize;
|
||||
Application.CreateForm(TEditorSite, EditorSite);
|
||||
Application.CreateForm(TViewWindow, ViewWindow);
|
||||
Application.Run;
|
||||
end.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -11,6 +11,7 @@ inherited EditorSite: TEditorSite
|
||||
OnDeactivate = FormDeactivate
|
||||
OnHide = FormHide
|
||||
OnResize = FormResize
|
||||
OnWindowStateChange = FormWindowStateChange
|
||||
ShowInTaskBar = stAlways
|
||||
inherited pnlLeft: TPanel
|
||||
Height = 256
|
||||
|
@ -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
|
||||
]);
|
||||
|
@ -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}
|
||||
|
||||
|
@ -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">
|
||||
|
@ -7,7 +7,8 @@ unit EasyDockMgr;
|
||||
interface
|
||||
|
||||
uses
|
||||
EasyDockSite, fDockBook, fFloatingSite, fElasticSite, LazarusPackageIntf;
|
||||
EasyDockSite, fDockBook, fFloatingSite, fElasticSite, uMiniRestore,
|
||||
LazarusPackageIntf;
|
||||
|
||||
implementation
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
]);
|
||||
|
@ -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;
|
||||
|
||||
|
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