Sign in Join
Wiki copytemporary

Anchor Docking: what changed

Revision 5 to 6. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
1-About docking in general see [[Docking]].
1+About docking in general see [[Docking]].
22
33## Overview
44
5-Docking allows you to combine forms, or to treat controls as forms. You use the mouse to drag and dock forms together or undock (split) them. The basic dragging, docking and undocking functionality is provided by the LCL. But you need a docking manager to add splitters and grab zones, and to save and restore layouts.
5+Docking allows you to combine forms, or to treat controls as forms. You use the mouse to drag and dock forms together or undock (split) them. The basic dragging, docking and undocking functionality is provided by the LCL. But you need a docking manager to add splitters and grab zones, and to save and restore layouts.
66
7-Anchor docking has been implemented since version 0.9.29 in the package *anchordocking.lpk* for use in your own Lazarus applications, and *AnchorDockingDsgn.lpk* if you wish to make the Lazarus IDE windows dockable. It is easy to use, and provides many features and options not available in earlier docking packages.
7+Anchor docking has been implemented since version 0.9.29 in the package _anchordocking.lpk_ for use in your own Lazarus applications, and _AnchorDockingDsgn.lpk_ if you wish to make the Lazarus IDE windows dockable. It is easy to use, and provides many features and options not available in earlier docking packages.
88
9-You will find a code example at: components/anchordocking/miniide/miniide1.lpi
9+You will find a code example at: components/anchordocking/miniide/miniide1.lpi
1010
11-This means that the earlier TLazDockingManager and unit LDockCtrl are obsolete and now deprecated.
11+This means that the earlier TLazDockingManager and unit LDockCtrl are obsolete and now deprecated.
1212
1313### Features
1414
15-- **Drag and dock**: Headers are added that can be dragged to dock controls with the mouse. Preview rectangles will show where and how a control is docked.
16-- **Any layout**: By using the LCL's anchors almost any layout is possible. You can dock to left, right, top, bottom, inside or outside or as page like in a TPageControl. You can enlarge docked controls via the popup menu. No need to undock your whole layout.
17-- **What you see is how it is structured**: There are no hidden panels to align controls in rows and columns. Anchor docking makes sure forms do not overlap.
18-- **Splitters** are automatically inserted between docked forms to allow resizing.
19-- **Page docking**. Forms can be docked not only left/right/above/below, but in pages too. A TPageControl is automatically created for native look and feel. A page can contain arbitrary docked forms too, including paged docked forms, allowing nested pages and layouts. When a page is undocked the pagecontrol is automatically removed. You can drag and drop the tabs or use the popup menu to move pages.
20-- **Easy use**: With one line of code you can make a form or control dockable. Just give them unique names.
21-- Not only forms, but any **TWinControl** can be made dockable.
22-- Can **save/load layouts**. The layout information is stored for each dockable control and old layout files will still work even when the application gets more dockable controls or some are removed. The information is stored in the abstract class LCL TConfigStorage. So you can use for example TXMLConfigStorage to store layouts in xml files or you can write your own storage to store it wherever you want.
23-- Each docked form is put into a docksite providing an optional **header**. The header shows the caption of the docked form and contains a close button. You can *drag the header* to drag the form and undock it or to dock it at another position. The header can be at any of the four sides and moves by default automatically to the smaller side to save space. You can customize this. The header shows a customizable hint allowing to read long captions.
24-- When a docksite is resized the *child sites are automatically scaled*. You can turn this off.
25-- **Preserve size of forms**. For instance when docking a form to a left side of a site the width of the docked form is kept. The same for the other sides and the same for undocking.
26-- **Flickerless**: The restore tries to reuse existing sites and splitters to reduce creation and flickering of forms and to preserve the Z order of forms. This allows to quickly switch between layouts.
27-- **Header popup menu**:
28- - lock/unlock (disable dragging)
29- - header position (auto, left, top, right, bottom), this is saved/restored with the layout
30- - merge (for example after moving a dock page into a layout)
31- - undock (needed if no place to undock on screen)
32- - enlarge side to left, top, right, bottom
33- - close
34- - options
35-- **Page popup menu**:
36- - lock/unlock (disable dragging)
37- - undock (needed if no place to undock on screen)
38- - tab position for pagecontrol (top,bottom, left, right), this is saved/restored with the layout
39- - move page to the left, right, leftmost, rightmost
40- - close
41- - options
42-- Forms can be made dock sites. Then they can dock at one side. But they can not be docked itself.
43-- close button automatically saves a layout
44-- Powerful functions to alter the layout. You can use D&D to move a form and you can undock and dock in one move. There are functions to enlarge forms and shrinking others. These functions are available via the header popup menu as well. See below.
45-- There is an IDE package which makes the Lazarus IDE dockable. It is called anchordockingdsgn.lpk. Make sure you only install one docking package. Do not install the easydockmgr at the same time!
15+ * **Drag and dock** : Headers are added that can be dragged to dock controls with the mouse. Preview rectangles will show where and how a control is docked.
16+ * **Any layout** : By using the LCL's anchors almost any layout is possible. You can dock to left, right, top, bottom, inside or outside or as page like in a TPageControl. You can enlarge docked controls via the popup menu. No need to undock your whole layout.
17+ * **What you see is how it is structured** : There are no hidden panels to align controls in rows and columns. Anchor docking makes sure forms do not overlap.
18+ * **Splitters** are automatically inserted between docked forms to allow resizing.
19+ * **Page docking**. Forms can be docked not only left/right/above/below, but in pages too. A TPageControl is automatically created for native look and feel. A page can contain arbitrary docked forms too, including paged docked forms, allowing nested pages and layouts. When a page is undocked the pagecontrol is automatically removed. You can drag and drop the tabs or use the popup menu to move pages.
20+ * **Easy use** : With one line of code you can make a form or control dockable. Just give them unique names.
21+ * Not only forms, but any **TWinControl** can be made dockable.
22+ * Can **save/load layouts**. The layout information is stored for each dockable control and old layout files will still work even when the application gets more dockable controls or some are removed. The information is stored in the abstract class LCL TConfigStorage. So you can use for example TXMLConfigStorage to store layouts in xml files or you can write your own storage to store it wherever you want.
23+ * Each docked form is put into a docksite providing an optional **header**. The header shows the caption of the docked form and contains a close button. You can _drag the header_ to drag the form and undock it or to dock it at another position. The header can be at any of the four sides and moves by default automatically to the smaller side to save space. You can customize this. The header shows a customizable hint allowing to read long captions.
24+ * When a docksite is resized the _child sites are automatically scaled_. You can turn this off.
25+ * **Preserve size of forms**. For instance when docking a form to a left side of a site the width of the docked form is kept. The same for the other sides and the same for undocking.
26+ * **Flickerless** : The restore tries to reuse existing sites and splitters to reduce creation and flickering of forms and to preserve the Z order of forms. This allows to quickly switch between layouts.
27+ * **Header popup menu** :
28+ * lock/unlock (disable dragging)
29+ * header position (auto, left, top, right, bottom), this is saved/restored with the layout
30+ * merge (for example after moving a dock page into a layout)
31+ * undock (needed if no place to undock on screen)
32+ * enlarge side to left, top, right, bottom
33+ * close
34+ * options
35+ * **Page popup menu** :
36+ * lock/unlock (disable dragging)
37+ * undock (needed if no place to undock on screen)
38+ * tab position for pagecontrol (top,bottom, left, right), this is saved/restored with the layout
39+ * move page to the left, right, leftmost, rightmost
40+ * close
41+ * options
42+ * Forms can be made dock sites. Then they can dock at one side. But they can not be docked itself.
43+ * close button automatically saves a layout
44+ * Powerful functions to alter the layout. You can use D&D to move a form and you can undock and dock in one move. There are functions to enlarge forms and shrinking others. These functions are available via the header popup menu as well. See below.
45+ * There is an IDE package which makes the Lazarus IDE dockable. It is called anchordockingdsgn.lpk. Make sure you only install one docking package. Do not install the easydockmgr at the same time!
4646
4747### ToDos
4848
49-- Design time package: Add all layout files to menu
50-- simple way to make forms dockable at designtime (that means without writing any code)
51-- minimize button and Hide
52-- on show again: restore a default layout
53-- close button for pages
54-- Implement automatic menu merging in the LCL (when two forms with main menus are docked).
49+ * Design time package: Add all layout files to menu
50+ * simple way to make forms dockable at designtime (that means without writing any code)
51+ * minimize button and Hide
52+ * on show again: restore a default layout
53+ * close button for pages
54+ * Implement automatic menu merging in the LCL (when two forms with main menus are docked).
5555
56-## Usage I. (Add docking support to the Lazarus IDE)
56+##
5757
58-If you don't like the default "separate windows" look of the Lazarus IDE and prefer a single window (e.g., like RAD Studio™), you can install a package called **[[AnchorDockingDsgn]]** (lazarus/components/anchordocking/design/anchordockingdsgn.lpk). This package makes the IDE windows dockable.
58+Usage I. (Add docking support to the Lazarus IDE)
5959
60+If you don't like the default "separate windows" look of the Lazarus IDE and prefer a single window (e.g., like RAD Studio™), you can install a package called **[[AnchorDockingDsgn]]** (lazarus/components/anchordocking/design/anchordockingdsgn.lpk). This package makes the IDE windows dockable.
61+
6062### Important to macOS users
6163
62-Before Lazarus 3.0, there are many bugs related to docking.
64+Before Lazarus 3.0, there are many bugs related to docking.
6365
64-If "anchordockingdsgn" has been installed before Lazarus 3.0, the wrong configuration may be saved and needs to be reset first.
66+If "anchordockingdsgn" has been installed before Lazarus 3.0, the wrong configuration may be saved and needs to be reset first.
6567
66-The configuration is saved in environmentoptions.xml, which usually located in ~/.lazarus
68+The configuration is saved in environmentoptions.xml, which usually located in ~/.lazarus
6769
68-Close the IDE, locate environmentoptions.xml, delete the content between \<AnchorDocking\> and \</AnchorDocking\>, and the initial setting of anchordockingdsgn will be automatically set when the IDE is started again.
70+Close the IDE, locate environmentoptions.xml, delete the content between <AnchorDocking> and </AnchorDocking>, and the initial setting of anchordockingdsgn will be automatically set when the IDE is started again.
6971
7072### Installation
7173
72-Uninstall any other docking managers (e.g., easydockmgrdsgn). From the Lazarus menu bar pick "Package" - "Install/Uninstall Packages" and install the "anchordockingdsgn" package.
73-
74-After you have successfully installed the package and restarted the IDE, the IDE starts with a default docked layout like shown below. Note that AnchorDocking headers and splitters have been added to all dockable windows of the IDE. In case the headers don't get visible, see the section "Options" below on how to enable/disable them.
74+Uninstall any other docking managers (e.g., easydockmgrdsgn). From the Lazarus menu bar pick "Package" - "Install/Uninstall Packages" and install the "anchordockingdsgn" package.
7575
76-![](/wiki-images/a/ac/2021-12-02_10_21_07-Debian_10.8_Buster_-_VMware_Workstation.png)
76+After you have successfully installed the package and restarted the IDE, the IDE starts with a default docked layout like shown below. Note that AnchorDocking headers and splitters have been added to all dockable windows of the IDE. In case the headers don't get visible, see the section "Options" below on how to enable/disable them.
7777
78-You can change the layout by grabbing a dockable window by the Anchordocking header and drag and dock it anywhere else, or resize docked windows via splitters added to the window borders. You can right-click on the headers too for other options, for example, to change the look of the headers, as shown farther down below.
78+[![2021-12-02 10 21 07-Debian 10.8 Buster - VMware Workstation.png](/wiki-images/a/ac/2021-12-02_10_21_07-Debian_10.8_Buster_-_VMware_Workstation.png)](</File:2021-12-02_10_21_07-Debian_10.8_Buster_-_VMware_Workstation.png>)
7979
80-You can save the layout via the menu item **Tools / Save window layout as default**. This saves to ~/.lazarus/anchordocklayout.xml and restores it when the IDE starts up.
80+You can change the layout by grabbing a dockable window by the Anchordocking header and drag and dock it anywhere else, or resize docked windows via splitters added to the window borders. You can right-click on the headers too for other options, for example, to change the look of the headers, as shown farther down below.
8181
82-You can also save the layout to a file and load them later.
82+You can save the layout via the menu item **Tools / Save window layout as default**. This saves to ~/.lazarus/anchordocklayout.xml and restores it when the IDE starts up.
8383
84-Since Lazarus 1.1 you can pass a command line parameter
84+You can also save the layout to a file and load them later.
8585
86-```text
86+Since Lazarus 1.1 you can pass a command line parameter
87+```
8788./lazarus --anchordocklayout=<filename>
8889```
8990
90-The look (like the headers) can be further tweaked by right-clicking on them.
91+The look (like the headers) can be further tweaked by right-clicking on them.
9192
92-![](/wiki-images/8/8a/Docking_headers.gif)
93+[![docking headers.gif](/wiki-images/6/6f/docking_headers.gif)](</File:docking_headers.gif>)
9394
9495### Options
9596
96-After the successful installation of the AnchorDockingDsgn package, an additional configuration menu is added to the Lazarus options dialog ("Tools" - "Options" - "Environment")
97+After the successful installation of the AnchorDockingDsgn package, an additional configuration menu is added to the Lazarus options dialog ("Tools" - "Options" - "Environment")
9798
98-![](/wiki-images/3/3a/Anchordocking_options.png)
99+[![anchordocking options.png](/wiki-images/5/57/anchordocking_options.png)](</File:anchordocking_options.png>)
99100
100101#### Scale on resize
101102
102-When resizing a window, all docked forms inside are scaled by the same percentage.
103+When resizing a window, all docked forms inside are scaled by the same percentage.
103104
104105#### Show headers
105106
106-To dock/undock a window, you need to enable this option.
107+To dock/undock a window, you need to enable this option.
107108
108109#### Flatten headers
109110
110-No 3d frame in headers.
111+No 3d frame in headers.
111112
112113#### Header align top/left
113114
114-Headers are automatically put at top or left depending on these two values:
115+Headers are automatically put at top or left depending on these two values:
115116
116-- Move header to top, when (width/height)*100\<=HeaderAlignTop, default 80
117-- Move header to left, when (width/height)*100\>=HeaderAlignLeft, default 120
118-- Otherwise keep the header at the current position.
117+ * Move header to top, when (width/height)*100<=HeaderAlignTop, default 80
118+ * Move header to left, when (width/height)*100>=HeaderAlignLeft, default 120
119+ * Otherwise keep the header at the current position.
119120
120-Which means the header is by default put at the smaller side of a docked control. When the control is resized, the header switches to the smaller side.
121+Which means the header is by default put at the smaller side of a docked control. When the control is resized, the header switches to the smaller side.
121122
122123#### Allow dock sites to be minimized
123124
124-A extra minimize button is added, so a site can be minimized. Then sites next to it get more space. If needed, the minimized site then can easy be opened.
125+A extra minimize button is added, so a site can be minimized. Then sites next to it get more space. If needed, the minimized site then can easy be opened.
125126
126127#### Multine Tabs
127128
128-Feature added in Lazarus 2.2. If a OS support multiline tabs (like Windows), if there are no many tabs, they are shown in multiple lines.
129+Feature added in Lazarus 2.2. If a OS support multiline tabs (like Windows), if there are no many tabs, they are shown in multiple lines.
129130
130131#### Floating windows on top
131132
132-Feature added in Lazarus 2.2. If there are undocked windows shown, show these on top of main window. In a own application, there can be set DockMaster.MainDockForm, then all floating windows are shown on top of it. If MainDockForm is not set, Application.MainForm is used.
133+Feature added in Lazarus 2.2. If there are undocked windows shown, show these on top of main window. In a own application, there can be set DockMaster.MainDockForm, then all floating windows are shown on top of it. If MainDockForm is not set, Application.MainForm is used.
133134
134135## Usage II. (Add docking support to your own applications)
135136
136137### Quick start
137138
138-Add the package **AnchorDocking** to the required packages in the project inspector.
139-
140-Then add the unit **AnchorDocking** to the uses section of your main unit (the unit with your main form).
139+Add the package **AnchorDocking** to the required packages in the project inspector.
141140
142-Add to the FormCreate of your main form:
141+Then add the unit **AnchorDocking** to the uses section of your main unit (the unit with your main form).
143142
144-``` pascal
145- DockMaster.MakeDockSite(Self,[akBottom],admrpChild);
143+Add to the FormCreate of your main form:
146144```
147-
148-For the other dockable forms replace all calls of *Show* and *ShowOnTop* with
149-
150-``` pascal
151- DockMaster.MakeDockable(Form1,true,true);
145+DockMaster.MakeDockSite(Self,[akBottom],admrpChild);
152146```
153147
154-For the other dockable forms replace all calls of *Visible:=true* with
148+For the other dockable forms replace all calls of _Show_ and _ShowOnTop_ with
149+```
150+DockMaster.MakeDockable(Form1,true,true);
151+```
155152
156-``` pascal
157- DockMaster.MakeDockable(Form1,true);
153+For the other dockable forms replace all calls of _Visible:=true_ with
158154```
155+DockMaster.MakeDockable(Form1,true);
156+```
159157
160-Remove or comment all *Hide*, *Visible:=false*, *WindowState:=* calls.
158+Remove or comment all _Hide_ , _Visible:=false_ , _WindowState:=_ calls.
161159
162160### Prerequisites
163161
164-- Your project must use the package *AnchorDocking*.
165-- All dockable forms must be shown with MakeDockable or MakeDockSite. Do not use *Show*, *BringToFront*, *ShowOnTop*, *Visible:=true*. Of course you can have some non dockable forms, like hints or splashscreens.
166-- All dockable forms must be free resizable, that means no constraints, no BorderStyle bsDialog.
167-- No other docking system. AnchorDocking is incompatible with EasyDockMgr.
162+ * Your project must use the package _AnchorDocking_.
163+ * All dockable forms must be shown with MakeDockable or MakeDockSite. Do not use _Show_ , _BringToFront_ , _ShowOnTop_ , _Visible:=true_. Of course you can have some non dockable forms, like hints or splashscreens.
164+ * All dockable forms must be free resizable, that means no constraints, no BorderStyle bsDialog.
165+ * No other docking system. AnchorDocking is incompatible with EasyDockMgr.
168166
169167### Making forms dockable
170168
171-There are two ways to make a form dockable. You can use **DockMaster.MakeDockable** to wrap a form into a dock site. Then your form can dock and be docked completely free. You will use that for the biggest part of your forms, except for the MainForm, because this is only supported for the MainForm on gtk2 and qt. The second way is to use **DockMaster.MakeDockSite**. The form can dock other sites, but can not be docked itself. You might want to use *MakeDockSite* for the *MainForm*. For most other forms you probably want to use this:
172-
173-``` pascal
169+There are two ways to make a form dockable. You can use **DockMaster.MakeDockable** to wrap a form into a dock site. Then your form can dock and be docked completely free. You will use that for the biggest part of your forms, except for the MainForm, because this is only supported for the MainForm on gtk2 and qt. The second way is to use **DockMaster.MakeDockSite**. The form can dock other sites, but can not be docked itself. You might want to use _MakeDockSite_ for the _MainForm_. For most other forms you probably want to use this:
170+```
174171// shows YourForm
175-// if not already done, wrap the form into a dock site
176-DockMaster.MakeDockable(YourForm);
172+ // if not already done, wrap the form into a dock site
173+ DockMaster.MakeDockable(YourForm);
177174```
178175
179-Here are some examples how a form looks like that was made dockable with **DockMaster.MakeDockable**:
176+Here are some examples how a form looks like that was made dockable with **DockMaster.MakeDockable** :
180177
181-![](/wiki-images/b/bc/Docksite1.png) ![](/wiki-images/c/c6/Docksite2.png)
178+[![Docksite1.png](/wiki-images/b/bc/Docksite1.png)](</File:Docksite1.png>) [![Docksite2.png](/wiki-images/c/c6/Docksite2.png)](</File:Docksite2.png>)
182179
183-The header position is normally done automatically and the user can with a right click put it to any of the four sides.
180+The header position is normally done automatically and the user can with a right click put it to any of the four sides.
184181
185182### Example: miniide1
186183
187-The example can be found in *lazarus/components/anchordocking/miniide/miniide1.lpi*. It has a *mainform* in unit *unit1.pas* with a main menu which works as a docksite and several forms that are dockable.
184+The example can be found in _lazarus/components/anchordocking/miniide/miniide1.lpi_. It has a _mainform_ in unit _unit1.pas_ with a main menu which works as a docksite and several forms that are dockable.
188185
189-![](/wiki-images/a/a5/Anchordocking_miniide1.png)
186+[![Anchordocking miniide1.png](/wiki-images/a/a5/Anchordocking_miniide1.png)](</File:Anchordocking_miniide1.png>)
190187
191188### Making the main form a dock site
192189
193-In the TMainIDE.FormCreate the main form **MainIDE** is turned into a docksite:
194-
195-``` pascal
190+In the TMainIDE.FormCreate the main form **MainIDE** is turned into a docksite:
191+```
196192DockMaster.MakeDockSite(Self,[akBottom],admrpChild);
197193```
198194
199-The parameter *\[akBottom\]* allows to dock other sites at the bottom of MainIDE. The parameter *admrpChild* tells the DockMaster that when the MainIDE is enlarged the extra space is distributed to the docked sites.
195+The parameter _[akBottom]_ allows to dock other sites at the bottom of MainIDE. The parameter _admrpChild_ tells the DockMaster that when the MainIDE is enlarged the extra space is distributed to the docked sites.
200196
201-When the user docks a site to the bottom of MainIDE the site is put onto MainIDE (Site.Parent:=MainIDE) with Site.Align=alBottom. The other controls on MainIDE must be compatible to this. MainIDE for example has a BtnPanel with Align=alLeft and a TNoteBook with Align=alClient. See [[Autosize / Layout|here]] how Align works.
197+When the user docks a site to the bottom of MainIDE the site is put onto MainIDE (Site.Parent:=MainIDE) with Site.Align=alBottom. The other controls on MainIDE must be compatible to this. MainIDE for example has a BtnPanel with Align=alLeft and a TNoteBook with Align=alClient. See [[Autosize / Layout|here]] how Align works.
202198
203-The DockMaster adds automatically a splitter:
199+The DockMaster adds automatically a splitter:
204200
205-![](/wiki-images/c/ca/Anchordocking_miniide_dockedse1.png)
201+[![Anchordocking miniide dockedse1.png](/wiki-images/c/ca/Anchordocking_miniide_dockedse1.png)](</File:Anchordocking_miniide_dockedse1.png>)
206202
207-As soon as a dockable form is docked its caption is shown in the dock header.
203+As soon as a dockable form is docked its caption is shown in the dock header.
208204
209205#### Requirements for a custom dock site
210206
211-As long as nothing is docked into a custom dock site, your form can do everything as a normal form. But when a site is docked to it, some properties and methods need special care:
207+As long as nothing is docked into a custom dock site, your form can do everything as a normal form. But when a site is docked to it, some properties and methods need special care:
212208
213-- AutoSize=true may result in an endless loop. Disable it or override DoAutoSize/CalculatePreferredSize and take special care.
214-- Constraints: The DockMaster clears the maximum Constraints and will restore them on undock.
215-- Child controls anchored to the aligned site may overlap. See [[Autosize / Layout|here]] how Align works.
216-- ChildSizing: The spacing properties like LeftRightSpacing, TopBottomSpacing may interfere with the docking layout.
209+ * AutoSize=true may result in an endless loop. Disable it or override DoAutoSize/CalculatePreferredSize and take special care.
210+ * Constraints: The DockMaster clears the maximum Constraints and will restore them on undock.
211+ * Child controls anchored to the aligned site may overlap. See [[Autosize / Layout|here]] how Align works.
212+ * ChildSizing: The spacing properties like LeftRightSpacing, TopBottomSpacing may interfere with the docking layout.
217213
218214### Procedure to create all other forms by name
219215
220-The MainIDE sets the **DockMaster.OnCreateControl** event, to enable the DockMaster to create forms by name. This is needed to restore layouts.
221-
222-``` pascal
216+The MainIDE sets the **DockMaster.OnCreateControl** event, to enable the DockMaster to create forms by name. This is needed to restore layouts.
217+```
223218DockMaster.OnCreateControl:=@DockMasterCreateControl;
224219```
225-
226-``` pascal
220+```
227221procedure TMainIDE.DockMasterCreateControl(Sender: TObject; aName: string; var
228- AControl: TControl; DoDisableAutoSizing: boolean);
229-
230- procedure CreateForm(Caption: string; NewBounds: TRect);
231- begin
232- AControl:=CreateSimpleForm(aName,Caption,NewBounds,DoDisableAutoSizing);
233- end;
234-
235-begin
236- // first check if the form already exists
237- // the LCL Screen has a list of all existing forms.
238- // Note: Remember that the LCL allows as form names only standard
239- // pascal identifiers and compares them case insensitive
240- AControl:=Screen.FindForm(aName);
241- if AControl<>nil then begin
242- // if it already exists, just disable autosizing if requested
243- if DoDisableAutoSizing then
244- AControl.DisableAutoSizing;
245- exit;
246- end;
247- // if the form does not yet exist, create it
248- if aName='CodeExplorer' then
249- CreateForm('Code Explorer',Bounds(700,230,100,250))
250- ...
251- else if aName='DebugOutput' then
252- CreateForm('Debug Output',Bounds(400,400,350,150));
253-end;
222+ AControl: TControl; DoDisableAutoSizing: boolean);
223+
224+ procedure CreateForm(Caption: string; NewBounds: TRect);
225+ begin
226+ AControl:=CreateSimpleForm(aName,Caption,NewBounds,DoDisableAutoSizing);
227+ end;
228+
229+ begin
230+ // first check if the form already exists
231+ // the LCL Screen has a list of all existing forms.
232+ // Note: Remember that the LCL allows as form names only standard
233+ // pascal identifiers and compares them case insensitive
234+ AControl:=Screen.FindForm(aName);
235+ if AControl<>nil then begin
236+ // if it already exists, just disable autosizing if requested
237+ if DoDisableAutoSizing then
238+ AControl.DisableAutoSizing;
239+ exit;
240+ end;
241+ // if the form does not yet exist, create it
242+ if aName='CodeExplorer' then
243+ CreateForm('Code Explorer',Bounds(700,230,100,250))
244+ ...
245+ else if aName='DebugOutput' then
246+ CreateForm('Debug Output',Bounds(400,400,350,150));
247+ end;
254248```
255249
256-Creating a form can be as simple as this:
257-
258-``` pascal
250+Creating a form can be as simple as this:
251+```
259252MyForm:=TMyForm.Create(Self);
260-if DoDisableAutoSizing then
261- MyForm.DisableAutoSizing;
253+ if DoDisableAutoSizing then
254+ MyForm.DisableAutoSizing;
262255```
263256
264-But of course you can put there all kind of initialization code.
265-
266-The *DisableAutoSizing* reduces flickering. Make sure your forms **Visible** property is set to **false**.
257+But of course you can put there all kind of initialization code.
267258
268-Remember to call **DisableAutoSizing** for the form if the parameter **DoDisableAutoSizing** is set to *true*, because *Disable-* and *EnableAutosizing* calls must be balanced. If you miss the *DisableAutosizing*, the LCL will raise an exception later:
259+The _DisableAutoSizing_ reduces flickering. Make sure your forms **Visible** property is set to **false**.
269260
270-```text
261+Remember to call **DisableAutoSizing** for the form if the parameter **DoDisableAutoSizing** is set to _true_ , because _Disable-_ and _EnableAutosizing_ calls must be balanced. If you miss the _DisableAutosizing_ , the LCL will raise an exception later:
262+```
271263TControl.EnableAutoSizing SourceEditor1:TSimpleForm: missing DisableAutoSizing
272264```
273265
274-![](/wiki-images/8/8e/MissingDisableAutoSizing.png)
266+[![MissingDisableAutoSizing.png](/wiki-images/8/8e/MissingDisableAutoSizing.png)](</File:MissingDisableAutoSizing.png>)
275267
276-If you call **DisableAutoSizing** too much, your forms will not appear and/or not resize properly as the LCL is waiting for the *EnableAutoSizing* call that never comes.
268+If you call **DisableAutoSizing** too much, your forms will not appear and/or not resize properly as the LCL is waiting for the _EnableAutoSizing_ call that never comes.
277269
278270### Showing forms
279271
280-When a form should be shown, you have probably used something like *'MyForm.Show*. Instead you should now use
281-
282-``` pascal
272+When a form should be shown, you have probably used something like '_MyForm.Show_. Instead you should now use
273+```
283274DockMaster.MakeDockable(MyForm);
284275```
285276
286-This will wrap MyForm in a dock site and show it. It is clever enough to figure out if the form is already wrapped in a dock site.
287-
288-If you set the **DockMaster.OnCreateControl** event you can use this:
277+This will wrap MyForm in a dock site and show it. It is clever enough to figure out if the form is already wrapped in a dock site.
289278
290-``` pascal
279+If you set the **DockMaster.OnCreateControl** event you can use this:
280+```
291281DockMaster.ShowControl('MyForm',true);
292282```
293283
294284### Docking manually, via code
295285
296-Use the procedure **DockMaster.ManualDock** to dock a site to or into another.
297-
298-``` pascal
286+Use the procedure **DockMaster.ManualDock** to dock a site to or into another.
287+```
299288procedure ManualDock(SrcSite, TargetSite: TAnchorDockHostSite; Align: TAlign; TargetControl: TControl = nil);
300289```
301290
302-- **SrcSite** is the site to be docked. If SrcSite was docked it will be undocked first.
303-- **TargetSite** is the site where SrcSite will be docked into or docked as neighbor.
304-- **TargetControl** specifies if docking as neighbor (=nil), as inside neighbor (=TargetSide) or in front of a page (=a TAnchorDockPage).
291+ * **SrcSite** is the site to be docked. If SrcSite was docked it will be undocked first.
292+ * **TargetSite** is the site where SrcSite will be docked into or docked as neighbor.
293+ * **TargetControl** specifies if docking as neighbor (=nil), as inside neighbor (=TargetSide) or in front of a page (=a TAnchorDockPage).
305294
306-### Undocking manually, via code
295+
307296
308-Use the procedure **DockMaster.ManualFloat** to undock a site from its neighbors and create a flotaing top level form. The embedded control stays embedded into a TAnchorDockHostSite.
297+### Undocking manually, via code
309298
310-``` pascal
299+Use the procedure **DockMaster.ManualFloat** to undock a site from its neighbors and create a flotaing top level form. The embedded control stays embedded into a TAnchorDockHostSite.
300+```
311301procedure ManualFloat(AControl: TControl);
312302```
313303
314-You can give as parameter a TAnchorDockHostSite or a control embedded into a TAnchorDockHostSite (for example a form made dockable with MakeDockable). The site will be put at the same screen location.
304+You can give as parameter a TAnchorDockHostSite or a control embedded into a TAnchorDockHostSite (for example a form made dockable with MakeDockable). The site will be put at the same screen location.
315305
316306### Save layout
317307
318-The DockMaster allows to save the current layout to a TConfigStorage. The miniide example uses the xml version:
319-
320-``` pascal
308+The DockMaster allows to save the current layout to a TConfigStorage. The miniide example uses the xml version:
309+```
321310procedure TMainIDE.SaveLayout(Filename: string);
322-var
323- XMLConfig: TXMLConfigStorage;
324-begin
325- try
326- // create a new xml config file
327- XMLConfig:=TXMLConfigStorage.Create(Filename,false);
328- try
329- // save the current layout of all forms
330- DockMaster.SaveLayoutToConfig(XMLConfig);
331- XMLConfig.WriteToDisk;
332- finally
333- XMLConfig.Free;
334- end;
335- except
336- on E: Exception do begin
337- MessageDlg('Error',
338- 'Error saving layout to file '+Filename+':'#13+E.Message,mtError,
339- [mbCancel],0);
311+ var
312+ XMLConfig: TXMLConfigStorage;
313+ begin
314+ try
315+ // create a new xml config file
316+ XMLConfig:=TXMLConfigStorage.Create(Filename,false);
317+ try
318+ // save the current layout of all forms
319+ DockMaster.SaveLayoutToConfig(XMLConfig);
320+ XMLConfig.WriteToDisk;
321+ finally
322+ XMLConfig.Free;
323+ end;
324+ except
325+ on E: Exception do begin
326+ MessageDlg('Error',
327+ 'Error saving layout to file '+Filename+':'#13+E.Message,mtError,
328+ [mbCancel],0);
329+ end;
330+ end;
340331 end;
341- end;
342-end;
343332```
344333
345334### Load layout
346-
347-``` pascal
335+```
348336procedure TMainIDE.LoadLayout(Filename: string);
349-var
350- XMLConfig: TXMLConfigStorage;
351-begin
352- try
353- // load the xml config file
354- XMLConfig:=TXMLConfigStorage.Create(Filename,True);
355- try
356- // restore the layout
357- // this will close unneeded forms and call OnCreateControl for all needed
358- DockMaster.LoadLayoutFromConfig(XMLConfig);
359- finally
360- XMLConfig.Free;
361- end;
362- except
363- on E: Exception do begin
364- MessageDlg('Error',
365- 'Error loading layout from file '+Filename+':'#13+E.Message,mtError,
366- [mbCancel],0);
337+ var
338+ XMLConfig: TXMLConfigStorage;
339+ begin
340+ try
341+ // load the xml config file
342+ XMLConfig:=TXMLConfigStorage.Create(Filename,True);
343+ try
344+ // restore the layout
345+ // this will close unneeded forms and call OnCreateControl for all needed
346+ DockMaster.LoadLayoutFromConfig(XMLConfig);
347+ finally
348+ XMLConfig.Free;
349+ end;
350+ except
351+ on E: Exception do begin
352+ MessageDlg('Error',
353+ 'Error loading layout from file '+Filename+':'#13+E.Message,mtError,
354+ [mbCancel],0);
355+ end;
356+ end;
367357 end;
368- end;
369-end;
370358```
371359
372360### Enlarge/Shrink
373361
374-The anchor docking manager can enlarge/shrink docked neighbors. This is done via the popup menu of the dock header or in code with the function **DockMaster.ManualEnlarge**:
375-
376-``` pascal
362+The anchor docking manager can enlarge/shrink docked neighbors. This is done via the popup menu of the dock header or in code with the function **DockMaster.ManualEnlarge** :
363+```
377364function ManualEnlarge(Site: TAnchorDockHostSite; Side: TAnchorKind; OnlyCheckIfPossible: boolean): boolean;
378365```
379366
380-Site is a child site, Side the side of Site to expand. If you only want to test if enlarge is possible set OnlyCheckIfPossible to true.
367+Site is a child site, Side the side of Site to expand. If you only want to test if enlarge is possible set OnlyCheckIfPossible to true.
381368
382369### Enlarge one, shrink another
383370
384-Shrink neighbor *Object Inspector*, enlarge *Messages*: Right click on the header of *Messages* and click on **Enlarge right side**. Two splitters are resized.
371+Shrink neighbor _Object Inspector_ , enlarge _Messages_ : Right click on the header of _Messages_ and click on **Enlarge right side**. Two splitters are resized.
385372
386-![](/wiki-images/1/15/Anchordocking_before_enlarge1.png) enlarging *Messages* to the right side: ![](/wiki-images/f/f8/Anchordocking_after_enlarge1.png)
373+[![Anchordocking before enlarge1.png](/wiki-images/1/15/Anchordocking_before_enlarge1.png)](</File:Anchordocking_before_enlarge1.png>) enlarging _Messages_ to the right side: [![Anchordocking after enlarge1.png](/wiki-images/f/f8/Anchordocking_after_enlarge1.png)](</File:Anchordocking_after_enlarge1.png>)
387374
388375### Enlarge one, shrink many
389376
390-Shrink splitter at one side, enlarge both neighbor splitters, rotate the splitter behind, enlarge Control, shrink controls at rotate splitter. Right click on header of *Source Editor 1* then click on **Enlarge bottom side**.
377+Shrink splitter at one side, enlarge both neighbor splitters, rotate the splitter behind, enlarge Control, shrink controls at rotate splitter. Right click on header of _Source Editor 1_ then click on **Enlarge bottom side**.
391378
392-![](/wiki-images/c/cb/Anchordocking_before_enlarge2.png) becomes ![](/wiki-images/4/42/Anchordocking_after_enlarge2.png)
379+[![Anchordocking before enlarge2.png](/wiki-images/c/cb/Anchordocking_before_enlarge2.png)](</File:Anchordocking_before_enlarge2.png>) becomes [![Anchordocking after enlarge2.png](/wiki-images/4/42/Anchordocking_after_enlarge2.png)](</File:Anchordocking_after_enlarge2.png>)
393380
394381### General docking options
395382
396-The AnchorDocking package provides a dialog to setup some of the properties of the DockMaster. The dialog is in the unit AnchorDockOptionsDlg and you can use it simply:
397-
398-``` pascal
383+The AnchorDocking package provides a dialog to setup some of the properties of the DockMaster. The dialog is in the unit AnchorDockOptionsDlg and you can use it simply:
384+```
399385uses ... AnchorDockOptionsDlg;
400-...
401-procedure TMainIDE.FormCreate(Sender: TObject);
402-...
403-begin
404- ...
405- DockMaster.OnShowOptions:=@ShowAnchorDockOptions;
406- ...
407-end;
386+ ...
387+ procedure TMainIDE.FormCreate(Sender: TObject);
388+ ...
389+ begin
390+ ...
391+ DockMaster.OnShowOptions:=@ShowAnchorDockOptions;
392+ ...
393+ end;
408394```
409395
410-This will add a new menu item to the popup menus of the dock headers and pages called *Docking options*.
396+This will add a new menu item to the popup menus of the dock headers and pages called _Docking options_.
411397
412398## Why use Anchors instead of Align?
413399
414-Anchors allow to create any possible rectangular layout. Align is limited. Align with Panels can theoretically create a lot of layouts, but still not all. And some operations like enlarge/shrink are more complicated using Align/Panels than using Anchors. Align works good for a few forms, but the more forms are docked, the more the disadvantages of Align become visible.
400+Anchors allow to create any possible rectangular layout. Align is limited. Align with Panels can theoretically create a lot of layouts, but still not all. And some operations like enlarge/shrink are more complicated using Align/Panels than using Anchors. Align works good for a few forms, but the more forms are docked, the more the disadvantages of Align become visible.
415401
416402### Layouts that can be created with Align
417403
418-Align can only create the following layouts:
404+Align can only create the following layouts:
419405
420-![](/wiki-images/1/13/Anchordocking_align_layout1.png)
406+[![Anchordocking align layout1.png](/wiki-images/1/13/Anchordocking_align_layout1.png)](</File:Anchordocking_align_layout1.png>)
421407
422-The alTop controls are always at the top, filling the whole horizontal width. That's because the LCL first aligns all controls with alTop, then all alBottom, then alLeft, then alRight and finally alClient.
408+The alTop controls are always at the top, filling the whole horizontal width. That's because the LCL first aligns all controls with alTop, then all alBottom, then alLeft, then alRight and finally alClient.
423409
424410### Layouts that can be created with Align and Panels
425411
426-It is possible to nest Align layouts by using hidden panels. Then any layout that can be recursively splitted in halves can be created. Then you can create for example:
412+It is possible to nest Align layouts by using hidden panels. Then any layout that can be recursively splitted in halves can be created. Then you can create for example:
427413
428-![](/wiki-images/0/0e/Anchordocking_align_panels_layout1.png)
414+[![Anchordocking align panels layout1.png](/wiki-images/0/0e/Anchordocking_align_panels_layout1.png)](</File:Anchordocking_align_panels_layout1.png>)
429415
430-This requires only one hidden panel.
416+This requires only one hidden panel.
431417
432418### Changing Layouts
433419
434-Now the user wants to enlarge the *FPDocEditor* horizontally (and shrink *CodeExplorer*). With the *AnchorDocking* you can simply right click on the *FPDocEditor* header and click **Enlarge right side**.
420+Now the user wants to enlarge the _FPDocEditor_ horizontally (and shrink _CodeExplorer_). With the _AnchorDocking_ you can simply right click on the _FPDocEditor_ header and click **Enlarge right side**.
435421
436-![](/wiki-images/8/88/Anchordocking_align_panels_layout2.png)
422+[![Anchordocking align panels layout2.png](/wiki-images/8/88/Anchordocking_align_panels_layout2.png)](</File:Anchordocking_align_panels_layout2.png>)
437423
438-Other docking engines need at least 2 panels. One for *SrcEditor*,*Messages*,*FPDocEdit*,*CodeExpl* and one for *SrcEdit* and *Messages*. Most docking layouters do not even provide a simple way to change the layout in this way. An algorithm to allow this layout change, must analyze the whole structure as if there were no panels and must reparent a lot of things. Basically the algorithm must do the same as the anchor docking algorithm, but with the extra work of translating the layout into Align plus hidden panels.
424+Other docking engines need at least 2 panels. One for _SrcEditor_ ,_Messages_ ,_FPDocEdit_ ,_CodeExpl_ and one for _SrcEdit_ and _Messages_. Most docking layouters do not even provide a simple way to change the layout in this way. An algorithm to allow this layout change, must analyze the whole structure as if there were no panels and must reparent a lot of things. Basically the algorithm must do the same as the anchor docking algorithm, but with the extra work of translating the layout into Align plus hidden panels.
439425
440426### Layouts that are impossible with Align and Panels
441427
442-Now the user wants to enlarge *SourceEditor1* horizontally (and shrink *ObjectInspector*):
428+Now the user wants to enlarge _SourceEditor1_ horizontally (and shrink _ObjectInspector_):
443429
444-![](/wiki-images/e/e9/Anchordocking_impossible_with_align_panels1.png)
430+[![Anchordocking impossible with align panels1.png](/wiki-images/e/e9/Anchordocking_impossible_with_align_panels1.png)](</File:Anchordocking_impossible_with_align_panels1.png>)
445431
446-This layout is impossible with Align and panels, because you can not cut it in two halves. The same with
432+This layout is impossible with Align and panels, because you can not cut it in two halves. The same with
447433
448-![](/wiki-images/1/1e/Anchordocking_impossible_with_align_panels2.png)
434+[![Anchordocking impossible with align panels2.png](/wiki-images/1/1e/Anchordocking_impossible_with_align_panels2.png)](</File:Anchordocking_impossible_with_align_panels2.png>)
449435
450436### Conclusion
451437
452-Align with hidden panels allows you to easily create a simple docking manager that works well for a few forms, but it will always limit the user. Align is useful for row and column layouts, not for tables. Anchor docking works even for complex forms.
438+Align with hidden panels allows you to easily create a simple docking manager that works well for a few forms, but it will always limit the user. Align is useful for row and column layouts, not for tables. Anchor docking works even for complex forms.
453439
454440## Old/deprecated anchor docking
455441
456442### Create a TLazDockingManager
457-
458-``` pascal
459- DockingManager:=TLazDockingManager.Create(Self);
460443```
444+DockingManager:=TLazDockingManager.Create(Self);
445+```
461446
462-The Self as parameter is only used as Owner. That means, when the mainform is freed, the DockingManager is freed too. You can use *nil* and free the DockingManager yourself.
447+The Self as parameter is only used as Owner. That means, when the mainform is freed, the DockingManager is freed too. You can use _nil_ and free the DockingManager yourself.
463448
464449### Optional: Loading a configuration
465450
466-You can load the user configuration from disk.
467-
468-``` pascal
469- Config:=TXMLConfigStorage.Create('config.xml',true);
470- DockingManager.LoadFromConfig(Config);
471- Config.Free;
451+You can load the user configuration from disk.
472452```
453+Config:=TXMLConfigStorage.Create('config.xml',true);
454+ DockingManager.LoadFromConfig(Config);
455+ Config.Free;
456+```
473457
474-This loads the file *config.xml*. The config can be created by the SaveToConfig function. See below.
458+This loads the file _config.xml_. The config can be created by the SaveToConfig function. See below.
475459
476460### Make a form/control dockable
477461
478-Create a TLazControlDocker for each form/control that should be dockable
479-
480-``` pascal
481- ControlDocker1:=TLazControlDocker.Create(Self);
482- ControlDocker1.Name:='DockerForm1';
483- ControlDocker1.Manager:=DockingManager;
462+Create a TLazControlDocker for each form/control that should be dockable
484463```
464+ControlDocker1:=TLazControlDocker.Create(Self);
465+ ControlDocker1.Name:='DockerForm1';
466+ ControlDocker1.Manager:=DockingManager;
467+```
485468
486469### Optional: Saving the user configuration to disk
487470
488-When the program is closed you can save the user configuration to disk
489-
490-``` pascal
491- Config:=TXMLConfigStorage.Create('config.xml',true);
492- DockingManager.SaveToConfig(Config);
493- Config.WriteToDisk;
494- Config.Free;
471+When the program is closed you can save the user configuration to disk
495472```
473+Config:=TXMLConfigStorage.Create('config.xml',true);
474+ DockingManager.SaveToConfig(Config);
475+ Config.WriteToDisk;
476+ Config.Free;
477+```
496478
497479## See also
498480
499-- [[AnchorDockingDsgn]] AnchorDocking in the Lazarus IDE
500-- [[Anchor Docking Step by step example|Anchor Docking: A Step by step example]]
501-- [[Docking]] in general
502-- [[EasyDockingManager]] - an alternative docking implementation with a simpler layout engine and fewer options.
481+ * [[AnchorDockingDsgn]] AnchorDocking in the Lazarus IDE
482+ * [[Anchor Docking Step by step example|Anchor Docking: A Step by step example]]
483+ * [[Docking]] in general
484+ * [[EasyDockingManager]] \- an alternative docking implementation with a simpler layout engine and fewer options.
503485
504486---
505-*From the Free Pascal wiki, page "Anchor Docking", as it stood on 2024-01-27 after a change by Rich2014, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
506-Category: Docking
507-Category: Lazarus IDE plugins
487+*From the Free Pascal wiki, page "Anchor Docking", as the Internet Archive kept it on 2025-12-19, last changed on 2025-09-02. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history