From 812cb0bdad2d538ad58b9e36d2cafc4bbbb8bb6e Mon Sep 17 00:00:00 2001 From: dodi Date: Thu, 8 Apr 2010 10:15:30 +0000 Subject: [PATCH] dockmanager example: introduce docking into non-empty root zone git-svn-id: trunk@24495 - --- examples/dockmanager/easytree/easydocking.lpi | 2 +- examples/dockmanager/easytree/fmain.pas | 8 +- examples/dockmanager/easytree/ftree.pas | 1 - examples/dockmanager/elasticsite/MakeSite.lpi | 2 +- examples/dockmanager/elasticsite/SiteTest.lpi | 2 +- .../dockmanager/elasticsite/feditorsite.lfm | 26 --- .../dockmanager/elasticsite/feditorsite.lrs | 59 +++-- .../dockmanager/elasticsite/feditorsite.pas | 3 +- examples/dockmanager/ide_demo/MiniIDE.lpi | 4 +- examples/dockmanager/ide_demo/fclientform.lfm | 2 - examples/dockmanager/ide_demo/fclientform.lrs | 30 +-- examples/dockmanager/package/easydockmgr.lpk | 1 + examples/dockmanager/package/easydocksite.pas | 204 +++++++++++++++--- examples/dockmanager/package/zoneheader.inc | 4 +- 14 files changed, 230 insertions(+), 118 deletions(-) diff --git a/examples/dockmanager/easytree/easydocking.lpi b/examples/dockmanager/easytree/easydocking.lpi index 4a7edf6c29..9387fb30df 100644 --- a/examples/dockmanager/easytree/easydocking.lpi +++ b/examples/dockmanager/easytree/easydocking.lpi @@ -14,7 +14,7 @@ </General> <VersionInfo> - <ProjectVersion Value=""/> + <StringTable Comments="" CompanyName="" FileDescription="" FileVersion="0.0.0.0" InternalName="" LegalCopyright="" LegalTrademarks="" OriginalFilename="" ProductName="" ProductVersion=""/> </VersionInfo> <PublishOptions> <Version Value="2"/> diff --git a/examples/dockmanager/easytree/fmain.pas b/examples/dockmanager/easytree/fmain.pas index 8af16fb5ee..91da7cd5c5 100644 --- a/examples/dockmanager/easytree/fmain.pas +++ b/examples/dockmanager/easytree/fmain.pas @@ -238,7 +238,9 @@ begin if Source.DragTarget = nil then sb.SimpleText := '<drop nowhere>' else begin - DropOn := Source.DragTarget; + DropOn := Source.DropOnControl; + if DropOn = nil then + DropOn := Source.DragTarget; r := Source.DockRect; s := Format('drop onto %s[%d,%d - %d,%d] %s', [ DropOn.Name, r.Top, r.Left, r.Bottom, r.Right, AlignNames[Source.DropAlign]]); @@ -269,9 +271,11 @@ procedure TEasyDockMain.buDumpClick(Sender: TObject); var s: TStringStream; begin + if not (Docker.DockManager is TEasyTree) then + exit; s := TStringStream.Create(''); try - Docker.DockManager.SaveToStream(s); + TEasyTree(Docker.DockManager).DumpToStream(s); DumpBox.Memo1.Text := s.DataString; finally s.Free; diff --git a/examples/dockmanager/easytree/ftree.pas b/examples/dockmanager/easytree/ftree.pas index 53dc45a9e7..18d27254ad 100644 --- a/examples/dockmanager/easytree/ftree.pas +++ b/examples/dockmanager/easytree/ftree.pas @@ -25,7 +25,6 @@ implementation initialization {$i fTree.lrs} - {$i fTree.lrs} end. diff --git a/examples/dockmanager/elasticsite/MakeSite.lpi b/examples/dockmanager/elasticsite/MakeSite.lpi index 483023dd57..4493be44a7 100644 --- a/examples/dockmanager/elasticsite/MakeSite.lpi +++ b/examples/dockmanager/elasticsite/MakeSite.lpi @@ -13,7 +13,7 @@ <UseXPManifest Value="True"/> </General> <VersionInfo> - <ProjectVersion Value=""/> + <StringTable Comments="" CompanyName="" FileDescription="" FileVersion="0.0.0.0" InternalName="" LegalCopyright="" LegalTrademarks="" OriginalFilename="" ProductName="" ProductVersion=""/> </VersionInfo> <PublishOptions> <Version Value="2"/> diff --git a/examples/dockmanager/elasticsite/SiteTest.lpi b/examples/dockmanager/elasticsite/SiteTest.lpi index 02cf218a57..926a7a0df7 100644 --- a/examples/dockmanager/elasticsite/SiteTest.lpi +++ b/examples/dockmanager/elasticsite/SiteTest.lpi @@ -11,7 +11,7 @@ <UseXPManifest Value="True"/> </General> <VersionInfo> - <ProjectVersion Value=""/> + <StringTable Comments="" CompanyName="" FileDescription="" FileVersion="0.0.0.0" InternalName="" LegalCopyright="" LegalTrademarks="" OriginalFilename="" ProductName="" ProductVersion=""/> </VersionInfo> <PublishOptions> <Version Value="2"/> diff --git a/examples/dockmanager/elasticsite/feditorsite.lfm b/examples/dockmanager/elasticsite/feditorsite.lfm index f437941c84..1a1dd6f3b8 100644 --- a/examples/dockmanager/elasticsite/feditorsite.lfm +++ b/examples/dockmanager/elasticsite/feditorsite.lfm @@ -13,32 +13,6 @@ inherited EditorSite: TEditorSite OnHide = FormHide OnResize = FormResize OnWindowStateChange = FormWindowStateChange - inherited pnlLeft: TPanel - Height = 256 - end - inherited splitLeft: TSplitter - Height = 256 - end - inherited pnlRight: TPanel - Left = 400 - Height = 256 - end - inherited pnlBottom: TPanel - Top = 260 - Width = 400 - end - inherited splitRight: TSplitter - Left = 396 - Height = 256 - end - inherited StatusBar1: TStatusBar - Top = 261 - Width = 400 - end - inherited splitBottom: TSplitter - Top = 256 - Width = 400 - end object MainMenu1: TMainMenu[7] left = 240 top = 48 diff --git a/examples/dockmanager/elasticsite/feditorsite.lrs b/examples/dockmanager/elasticsite/feditorsite.lrs index 096406b9a8..f8c7321bf6 100644 --- a/examples/dockmanager/elasticsite/feditorsite.lrs +++ b/examples/dockmanager/elasticsite/feditorsite.lrs @@ -1,40 +1,33 @@ -{ 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#3'T' +'op'#3#156#0#5'Width'#3#144#1#7'Caption'#6#10'EditorSite'#12'ClientHeight'#3 +#25#1#11'ClientWidth'#3#144#1#4'Menu'#7#9'MainMenu1'#10'OnActivate'#7#12'For' +'mActivate'#8'OnCreate'#7#10'FormCreate'#12'OnDeactivate'#7#14'FormDeactivat' +'e'#6'OnHide'#7#8'FormHide'#8'OnResize'#7#10'FormResize'#19'OnWindowStateCha' - +'nge'#7#21'FormWindowStateChange'#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'pnlRi' - +'ght'#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'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'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'&Op' - +'en'#7'OnClick'#7#11'mnOpenClick'#0#0#9'TMenuItem'#9'MenuItem1'#7'Caption'#6 - +#1'-'#0#0#9'TMenuItem'#6'mnExit'#7'Caption'#6#5'E&xit'#7'OnClick'#7#11'mnExi' - +'tClick'#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'View' - +'MenuClick'#0#0#9'TMenuItem'#9'MenuItem4'#7'Caption'#6#13'Code Explorer'#7'O' - +'nClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#9'MenuItem5'#7'Caption'#6#9'To' - +'Do List'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#9'MenuItem6'#7'Cap' - +'tion'#6#13'Debug windows'#0#9'TMenuItem'#9'MenuItem7'#7'Caption'#6#7'Watche' - +'s'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#9'MenuItem8'#7'Caption'#6 - +#11'BreakPoints'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#9'MenuItem9' - +#7'Caption'#6#15'Local Variables'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenu' - +'Item'#10'MenuItem10'#7'Caption'#6#9'Registers'#7'OnClick'#7#13'ViewMenuClic' - +'k'#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'ViewMenuClick'#0#0#0#0#9'TMenuItem'#10'Men' - +'uItem14'#7'Caption'#6#8'&Windows'#0#9'TMenuItem'#12'mnWindowDump'#7'Caption' - +#6#5'&Dump'#7'OnClick'#7#17'mnWindowDumpClick'#0#0#9'TMenuItem'#10'mnMinimiz' - +'e'#7'Caption'#6#12'Minimize all'#7'OnClick'#7#15'mnMinimizeClick'#0#0#9'TMe' - +'nuItem'#9'mnRestore'#7'Caption'#6#11'Restore all'#7'OnClick'#7#14'mnRestore' - +'Click'#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 + +'nge'#7#21'FormWindowStateChange'#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'TMen' + +'uItem'#6'mnOpen'#7'Caption'#6#5'&Open'#7'OnClick'#7#11'mnOpenClick'#0#0#9'T' + +'MenuItem'#9'MenuItem1'#7'Caption'#6#1'-'#0#0#9'TMenuItem'#6'mnExit'#7'Capti' + +'on'#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 Insp' + +'ector'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#9'MenuItem3'#7'Capti' + +'on'#6#8'Messages'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMenuItem'#9'MenuIte' + +'m4'#7'Caption'#6#13'Code Explorer'#7'OnClick'#7#13'ViewMenuClick'#0#0#9'TMe' + +'nuItem'#9'MenuItem5'#7'Caption'#6#9'ToDo List'#7'OnClick'#7#13'ViewMenuClic' + +'k'#0#0#9'TMenuItem'#9'MenuItem6'#7'Caption'#6#13'Debug windows'#0#9'TMenuIt' + +'em'#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'View' + +'MenuClick'#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'Vie' + +'wMenuClick'#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'mnWindowD' + +'umpClick'#0#0#9'TMenuItem'#10'mnMinimize'#7'Caption'#6#12'Minimize all'#7'O' + +'nClick'#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 ]); diff --git a/examples/dockmanager/elasticsite/feditorsite.pas b/examples/dockmanager/elasticsite/feditorsite.pas index a3b5bc948a..432193d3c3 100644 --- a/examples/dockmanager/elasticsite/feditorsite.pas +++ b/examples/dockmanager/elasticsite/feditorsite.pas @@ -41,7 +41,8 @@ uses fEditForm; type - TEditorSite = class(TDockingSite) + //TEditorSite = class(TDockingSite) + TEditorSite = class(TForm) MenuItem10: TMenuItem; MenuItem11: TMenuItem; MenuItem12: TMenuItem; diff --git a/examples/dockmanager/ide_demo/MiniIDE.lpi b/examples/dockmanager/ide_demo/MiniIDE.lpi index 17da273c3c..acf38f50de 100644 --- a/examples/dockmanager/ide_demo/MiniIDE.lpi +++ b/examples/dockmanager/ide_demo/MiniIDE.lpi @@ -8,11 +8,11 @@ <MainUnit Value="0"/> <AutoCreateForms Value="False"/> <TargetFileExt Value=".exe"/> - <Icon Value="0"/> <UseXPManifest Value="True"/> + <Icon Value="0"/> </General> <VersionInfo> - <ProjectVersion Value=""/> + <StringTable Comments="" CompanyName="" FileDescription="" FileVersion="0.0.0.0" InternalName="" LegalCopyright="" LegalTrademarks="" OriginalFilename="" ProductName="" ProductVersion=""/> </VersionInfo> <PublishOptions> <Version Value="2"/> diff --git a/examples/dockmanager/ide_demo/fclientform.lfm b/examples/dockmanager/ide_demo/fclientform.lfm index 746ec0a4a0..98afba0bf1 100644 --- a/examples/dockmanager/ide_demo/fclientform.lfm +++ b/examples/dockmanager/ide_demo/fclientform.lfm @@ -18,8 +18,6 @@ object ViewWindow: TViewWindow Width = 142 AutoSize = False Caption = 'Label1' - DragKind = dkDock - DragMode = dmAutomatic ParentColor = False end object Image1: TImage diff --git a/examples/dockmanager/ide_demo/fclientform.lrs b/examples/dockmanager/ide_demo/fclientform.lrs index 573e06a544..3ce00d5271 100644 --- a/examples/dockmanager/ide_demo/fclientform.lrs +++ b/examples/dockmanager/ide_demo/fclientform.lrs @@ -1,22 +1,24 @@ +{ This is an automatically generated lazarus resource file } + LazarusResources.Add('TViewWindow','FORMDATA',[ 'TPF0'#11'TViewWindow'#10'ViewWindow'#4'Left'#3'q'#1#6'Height'#3','#1#3'Top'#3 +'q'#1#5'Width'#3#144#1#7'Caption'#6#10'ViewWindow'#12'ClientHeight'#3','#1#11 +'ClientWidth'#3#144#1#8'DragKind'#7#6'dkDock'#8'DragMode'#7#11'dmAutomatic'#9 +'OnEndDock'#7#11'FormEndDock'#10'LCLVersion'#6#6'0.9.29'#7'Visible'#9#0#6'TL' +'abel'#6'Label1'#4'Left'#2#16#6'Height'#2#14#3'Top'#2#8#5'Width'#3#142#0#8'A' - +'utoSize'#8#7'Caption'#6#6'Label1'#8'DragKind'#7#6'dkDock'#8'DragMode'#7#11 - +'dmAutomatic'#11'ParentColor'#8#0#0#6'TImage'#6'Image1'#4'Left'#3#128#1#6'He' - +'ight'#2#16#3'Top'#2#0#5'Width'#2#16#7'Anchors'#11#5'akTop'#7'akRight'#0#8'A' - +'utoSize'#9#11'OnMouseMove'#7#15'Image1MouseMove'#12'Picture.Data'#10'H'#1#0 - +#0#5'TIcon>'#1#0#0#0#0#1#0#1#0#16#16#16#0#0#0#0#0'('#1#0#0#22#0#0#0'('#0#0#0 - +#16#0#0#0' '#0#0#0#1#0#4#0#0#0#0#0#192#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128#0#128#0#0#0#128#0#128#0#128#128#0#0 - +#128#128#128#0#192#192#192#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0 - +#255#0#255#255#0#0#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 + +'utoSize'#8#7'Caption'#6#6'Label1'#11'ParentColor'#8#0#0#6'TImage'#6'Image1' + +#4'Left'#3#128#1#6'Height'#2#16#3'Top'#2#0#5'Width'#2#16#7'Anchors'#11#5'akT' + +'op'#7'akRight'#0#8'AutoSize'#9#11'OnMouseMove'#7#15'Image1MouseMove'#12'Pic' + +'ture.Data'#10'H'#1#0#0#5'TIcon>'#1#0#0#0#0#1#0#1#0#16#16#16#0#0#0#0#0'('#1#0 + +#0#22#0#0#0'('#0#0#0#16#0#0#0' '#0#0#0#1#0#4#0#0#0#0#0#192#0#0#0#0#0#0#0#0#0 + +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0#128#0#0#0#128#128#0#128#0#0#0#128#0 + +#128#0#128#128#0#0#128#128#128#0#192#192#192#0#0#0#255#0#0#255#0#0#0#255#255 + +#0#255#0#0#0#255#0#255#0#255#255#0#0#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#153#0#0#0#0#0#0#153#153#153#0#0#0#0#0#153#153#153#0#0#0#0#9#153#153#153 - +#144#0#0#0#9#153#153#153#144#0#0#0#0#153#153#153#0#0#0#0#0#153#153#153#0#0#0 - +#0#0#0#153#0#0#0#0#0#0#0#0#0#0#127#255#0#0#191#255#0#0#223#255#0#0#239#255#0 - +#0#247#255#0#0#251#255#0#0#253#207#0#0#254#3#0#0#254#1#0#0#254#1#0#0#252#0#0 - +#0#252#0#0#0#254#1#0#0#254#1#0#0#255#3#0#0#255#207#0#0#0#0#0 + +#0#0#0#0#0#0#0#0#0#0#153#0#0#0#0#0#0#153#153#153#0#0#0#0#0#153#153#153#0#0#0 + +#0#9#153#153#153#144#0#0#0#9#153#153#153#144#0#0#0#0#153#153#153#0#0#0#0#0 + +#153#153#153#0#0#0#0#0#0#153#0#0#0#0#0#0#0#0#0#0#127#255#0#0#191#255#0#0#223 + +#255#0#0#239#255#0#0#247#255#0#0#251#255#0#0#253#207#0#0#254#3#0#0#254#1#0#0 + +#254#1#0#0#252#0#0#0#252#0#0#0#254#1#0#0#254#1#0#0#255#3#0#0#255#207#0#0#0#0 + +#0 ]); diff --git a/examples/dockmanager/package/easydockmgr.lpk b/examples/dockmanager/package/easydockmgr.lpk index 087b02446b..6ae04c4e85 100644 --- a/examples/dockmanager/package/easydockmgr.lpk +++ b/examples/dockmanager/package/easydockmgr.lpk @@ -47,6 +47,7 @@ <UnitName Value="uMakeSite"/> </Item7> </Files> + <LazDoc Paths="..\docs\"/> <Type Value="RunAndDesignTime"/> <RequiredPkgs Count="2"> <Item1> diff --git a/examples/dockmanager/package/easydocksite.pas b/examples/dockmanager/package/easydocksite.pas index d79e686280..a34dec7e51 100644 --- a/examples/dockmanager/package/easydocksite.pas +++ b/examples/dockmanager/package/easydocksite.pas @@ -53,6 +53,7 @@ LCL TODO: {$mode objfpc}{$H+} +{$DEFINE RootDock} //allow docking into the root zone? //{$DEFINE newSplitter} //exclude splitter from remaining zone {.$DEFINE handle_existing} //dock controls existing in the dock site? {.$DEFINE splitter_color} //use colored splitter, for debugging? @@ -105,14 +106,12 @@ type TEasyDockHeader = class public - //HeaderSize: integer; //state last drawn MouseZone: TEasyZone; MouseDown: boolean; MousePart: TEasyZonePart; PartRect: TRect; public - //Style: TEasyHeaderStyle; constructor Create; function GetRectOfPart(ARect: TRect; AOrientation: TDockOrientation; APart: TEasyZonePart; HasSplitter: boolean; AStyle: TEasyHeaderStyle): TRect; virtual; function FindPart(AZone: TEasyZone; MousePos: TPoint; fButtonDown: boolean): TEasyZonePart; @@ -186,6 +185,7 @@ type constructor Create(ADockSite: TWinControl); override; class function DetectAlign(ZoneRect: TRect; MousePos: TPoint): TAlign; function GetDockEdge(ADockObject: TDragDockObject): boolean; override; + procedure PositionDockRect(ADockObject: TDragDockObject); override; procedure PositionDockRect(Client, DropCtl: TControl; DropAlign: TAlign; var DockRect: TRect); override; procedure SetReplacingControl(Control: TControl); override; //unused @@ -575,10 +575,17 @@ begin end; end; +const + OrthoOrientation: array[TDockOrientation] of TDockOrientation = ( + //doNoOrient, doHorizontal, doVertical, doPages + doNoOrient, doVertical, doHorizontal, doPages + ); + procedure TEasyTree.InsertControl(Control: TControl; InsertAt: TAlign; DropCtl: TControl); var DropZone, OldZone, NewZone, OldParent, NewParent: TEasyZone; + OldOrientation, NewOrientation: TDockOrientation; r: TRect; NoteBook: TCustomDockSite; (* special cases: @@ -633,17 +640,18 @@ begin exit; //nothing changed end; - if Control.Name = '' then //name it - for header caption - Control.Name := CreateUniqueComponentName(Control.ClassName, Control.Owner); - if DropCtl = nil then begin - DropCtl := FDockSite; //the dock site - DropZone := FTopZone.FirstChild; + //top level docking! + //DropCtl := FDockSite; //the dock site + DropZone := FTopZone; // FTopZone.FirstChild; end else begin DropZone := FindControlZone(FTopZone, DropCtl); if DropZone = nil then exit; //not here!? end; + if Control.Name = '' then //name it - for header caption + Control.Name := CreateUniqueComponentName(Control.ClassName, Control.Owner); + (* alCustom means: drop into notebook. Valid only when dropped onto an existing control, not into empty dock site. Create notebook, if required (put both controls into new notebook). @@ -695,10 +703,13 @@ begin NewZone := TEasyZone.Create(self); NewZone.ChildControl := Control as TControl; Control.Align := alNone; + if Control is TCustomForm then + TCustomForm(Control).BorderStyle := bsNone; //special case: in root zone (empty dock site) if FTopZone.FirstChild = nil then begin + //insert first, without orientation FTopZone.InsertAfter(nil, NewZone); NewZone.SetBounds(FDockSite.ClientRect); end else begin @@ -708,43 +719,78 @@ begin r := DropZone.GetBounds; //for later adjustment //get requested orientation, adjust align case InsertAt of - alTop, alBottom: Control.DockOrientation := doVertical; - alLeft, alRight: Control.DockOrientation := doHorizontal; + alTop, alBottom: NewOrientation := doVertical; + alLeft, alRight: NewOrientation := doHorizontal; else //unhandled or unspecific - if DropCtl.DockOrientation = doNoOrient then - DropCtl.DockOrientation := doHorizontal; //assume - Control.DockOrientation := DropCtl.DockOrientation; + { TODO : DropCtl=nil - if docked into root zone } + if (DropCtl = nil) or (DropCtl.DockOrientation = doNoOrient) then begin + NewOrientation := DropZone.Orientation; + end else + NewOrientation := DropCtl.DockOrientation; + if NewOrientation = doNoOrient then + NewOrientation := doHorizontal; //assume something //fix alignment - if Control.DockOrientation = doVertical then + if NewOrientation = doVertical then InsertAt := alBottom else InsertAt := alRight; end; + Control.DockOrientation := NewOrientation; +{ +//check topzone now must have an orientation + if FTopZone.Orientation = doNoOrient then begin + FTopZone.Orientation := NewOrientation; + FTopZone.FirstChild.ChildControl.DockOrientation := NewOrientation; + end; +} (* Now Control.DockOrientation is the insert orientation, DropCtl.DockOrientation is the zone orientation, InsertAt is one of alLeft/Right/Top/Bottom *) //check orientation - control orientation cannot be doNone! - OldParent := DropZone.Parent; - (* One special case remains: top zone without orientation - *) - if (OldParent.Orientation = doNoOrient) then begin - assert(OldParent = FTopZone, '???'); - FTopZone.Orientation := Control.DockOrientation; //easy + OldParent := DropZone.Parent; //nil if docked into root zone! + if OldParent = nil then begin + //dock into rootzone - may have no orientation + OldOrientation := FTopZone.Orientation; // OrthoOrientation[FTopZone.Orientation]; + end else + OldOrientation := OldParent.Orientation;; + if (OldOrientation = doNoOrient) then begin + //second insert into root zone - fix zone and control orientation! + //assert(OldParent = FTopZone, '???'); + OldOrientation := NewOrientation; // Control.DockOrientation; //easy + FTopZone.Orientation := NewOrientation; + FTopZone.FirstChild.ChildControl.DockOrientation := NewOrientation; end; //iso or orthogonal insert? - if (OldParent.Orientation <> Control.DockOrientation) then begin + if (OldOrientation <> NewOrientation) then begin //need intermediate zone NewParent := TEasyZone.Create(self); - NewParent.Orientation := Control.DockOrientation; + NewParent.Orientation := NewOrientation; NewParent.BR := r.BottomRight; - OldParent.ReplaceChild(DropZone, NewParent); //unlink DropZone + if OldParent <> nil then + OldParent.ReplaceChild(DropZone, NewParent) //unlink DropZone + else begin + //DropZone is FTopZone + FTopZone := NewParent; + { TODO : what more is required??? } + end; //orthogonal orientation NewParent.InsertAfter(nil, DropZone); end; - //set control orientation + //set control orientation - !rootzone? + if DropZone = FTopZone then begin + //dropzone must have a parent + DropZone := DropZone.FirstChild; + case InsertAt of + //alLeft, alTop: + alBottom, alRight: + while DropZone.NextSibling <> nil do + DropZone := DropZone.NextSibling; + end; + end; DropZone.AddSibling(NewZone, InsertAt); + //if FTopZone.Orientation = doNoOrient then FTopZone.Orientation := Control.DockOrientation; //clear eventually moved zone, when redocking within this site if OldZone <> nil then begin RemoveZone(OldZone); //must NOT modify moved control! @@ -762,6 +808,9 @@ var begin (* New DockManager interface, called instead of the old version. Determine exact target (zone) and DropAlign. + + For top-level docking: check mouse IN site! + Signal results: Prevent docking by setting DropOnControl=Control (prevent changes when dropped). DragTarget=nil means: become floating. @@ -770,6 +819,7 @@ Signal results: *) { TODO -cdocking : why is this method not called for a docksite with 1 client? If exactly the client is moved over it? +-> by design of GetDockTarget in DockPerformer! } //debug only DockObj := ADockObject; @@ -777,9 +827,13 @@ Signal results: //determine the zone containing the DragTargetPos with ADockObject do begin //mouse position within dock site - DragTargetPos := DragTarget.ScreenToClient(DragPos); + //DragTargetPos := DragTarget.ScreenToClient(DragPos); //find zone, handle empty site for elastic panels - if DockSite.DockClientCount = 0 then + if (DockSite.DockClientCount = 0) + {$IFDEF RootDock} + or (not PtInRect(DockRect, DragPos)) + {$ENDIF} + then zone := FTopZone else zone := ZoneFromPoint(DragTargetPos); @@ -788,8 +842,12 @@ Signal results: DropAlign := alNone; //prevent drop (below) end else begin ADockRect := zone.GetBounds; //include header - DropOnControl := zone.ChildControl; - DropAlign := DetectAlign(ADockRect, DragTargetPos); + DropOnControl := zone.ChildControl; //correct hit in header, not in control + if DockSite.DockClientCount = 0 then + DropAlign := alClient //always span empty site + else + DropAlign := DetectAlign(ADockRect, DragTargetPos); + {$IFnDEF RootDock} if DropOnControl = nil then begin {$IFDEF singleTab} if SingleTab and (DropAlign = alCustom) then begin @@ -798,6 +856,9 @@ Signal results: {$ENDIF} DropAlign := alClient; //first element in entire site end; //else //determine the alignment within the zone. + {$ELSE} + //allow for top-level docking + {$ENDIF} //to screen coords ADockRect.TopLeft := FDockSite.ClientToScreen(ADockRect.TopLeft); ADockRect.BottomRight := FDockSite.ClientToScreen(ADockRect.BottomRight); @@ -1336,7 +1397,7 @@ begin affected := p; until zone.FirstChild <> nil; (* cases: - zone without parent (top) - exit + zone without parent (top) - check orientation, exit zone with 0 children - excluded before zone with 1 child (ch), child is leaf -> looses orientation, move up @@ -1350,7 +1411,7 @@ begin //more than 1 child - check next level end else if ch.FirstChild = nil then begin //contains control, move up - ch.ChildControl.DockOrientation := zone.Parent.Orientation; + ch.ChildControl.DockOrientation := p.Orientation; p.ReplaceChild(zone, ch); //move control up zone.Free; affected := p; @@ -1371,7 +1432,37 @@ begin zone.PositionControl; zone := Zone.NextSibling; end; +{ +//root zone may loose orientation! + if affected = FTopZone then begin + if affected.FirstChild.NextSibling = nil then begin + FTopZone.Orientation := doNoOrient; + FTopZone.FirstChild.ChildControl.DockOrientation := doNoOrient; <--- non-leaf!? + end; + end; + } end; +{$IFDEF new} + while FTopZone.FirstChild <> nil do begin + Zone := FTopZone.FirstChild; + if Zone.NextSibling <> nil then + break; + //move zone up + FTopZone.FFirstChild := nil; + zone.Parent := nil; + FTopZone.Free; + FTopZone := zone; + end; +{$ELSE} +{$ENDIF} + if FTopZone.FirstChild = nil then + FTopZone.Orientation := doNoOrient + else if FTopZone.FirstChild.NextSibling = nil then begin + FTopZone.Orientation := doNoOrient; + FTopZone.FirstChild.ChildControl.DockOrientation := doNoOrient; + //bug: not leaf??? + end; + //update zone, here simply the whole dock site FSplitter.Hide; DockSite.Invalidate; @@ -1557,6 +1648,7 @@ begin end; //parent orientation? (if in rootzone) //if parent.Orientation = doNoOrient then + if Parent <> nil then Parent.Orientation := NewOrientation; if ChildControl <> nil then ChildControl.DockOrientation := NewOrientation; @@ -1761,7 +1853,7 @@ const alLeft, alLeft, alTop, alTop, alRight, alBottom, alBottom, alLeft, alLeft ); begin -(* Determine alignment from the location of the mouse within ZoneRect. +(* Determine alignment from the position of the mouse within ZoneRect. ZoneRect in screen TLBR coordinates, MousePos in screen coordinates. *) //center and extent of dock zone @@ -1779,8 +1871,8 @@ begin //zone := zInnermost; dir := alCustom; //pages end else begin - phi := arctan2(dy, dx); - zphi := trunc(radtodeg(phi)) div 45; + phi := arctan2(dy, dx); //zero at East (right), increasing clockwise + zphi := trunc(radtodeg(phi)) div 45; //both EN and ES are zero dir := cDir[zphi]; end; end else @@ -1806,7 +1898,11 @@ begin Usage: Only to prevent calls to the target control, in case of extended InfluenceRect. *) +//test + exit(false); + if false then Result:=inherited GetDockEdge(ADockObject); +{$IFDEF old} //ADockObject.DockRect Result := DockSite.DockClientCount = 0; //do nothing if docked clients exist! if Result then begin @@ -1826,7 +1922,16 @@ begin ADockObject.DockRect := r; Result := CanDock; end; - //Result := True; +{$ELSE} + DebugLn('DropOnControl ', DbgS(ADockObject.DropOnControl)); + ADockObject.DropAlign := DetectAlign(ADockObject.DockRect, ADockObject.DragPos); + Result := True; + DebugLn('dockedge x(%d-%d) y(%d-%d) %s', [ + ADockObject.DockRect.Left, ADockObject.DockRect.Right, + ADockObject.DockRect.Top, ADockObject.DockRect.Bottom, + AlignNames[ADockObject.DropAlign] + ]); +{$ENDIF} end; procedure TEasyDockManager.PositionDockRect(Client, DropCtl: TControl; @@ -1836,10 +1941,16 @@ var begin (* DockRect is initialized to the screen rect of the dock site by TControl, or to the zone rect by TEasyTree. + + DropCtl=Nil means: dock into the root zone. *) + //if False then inherited PositionDockRect(Client, DropCtl, DropAlign, DockRect); +{$IFDEF old} if (DropCtl = nil) {$IFDEF singleTab} and not SingleTab {$ENDIF} then //if (DropCtl = nil) then exit; //entire dock site +{$ELSE} +{$ENDIF} case DropAlign of //alClient: as is @@ -1859,6 +1970,33 @@ begin end; end; +procedure TEasyDockManager.PositionDockRect(ADockObject: TDragDockObject); +var + r: TRect; +begin +(* Something is wrong here? +ADockObject: + DockRect is the site rect, to be replaced by the target control/zone rect. +*) + +//test + exit; + + if false then inherited PositionDockRect(ADockObject); + with ADockObject do begin; + //check target + if DropOnControl <> nil then begin + //init control rect + r.TopLeft := DropOnControl.ClientOrigin; + r.Bottom := r.Top + DropOnControl.Height; + r.Right := r.Left + DropOnControl.Width; + end else begin + r := DockRect; + end; + DetectAlign(r, DragPos); + end; +end; + procedure TEasyDockManager.SetReplacingControl(Control: TControl); begin //nop diff --git a/examples/dockmanager/package/zoneheader.inc b/examples/dockmanager/package/zoneheader.inc index 3924c9dbe6..7e0352fd6c 100644 --- a/examples/dockmanager/package/zoneheader.inc +++ b/examples/dockmanager/package/zoneheader.inc @@ -31,9 +31,11 @@ var ImageKind: TDockHeaderImageKind; begin //called from unit finalization only! - // this code can result in crashes, due to missing handles + // this code can result in crashes, due to missing handles! +{ for ImageKind := Low(TDockHeaderImageKind) to High(TDockHeaderImageKind) do FreeAndNil(DockBtnImages[ImageKind]); +} end;