Difference between revisions of "Docking"

From Free Pascal wiki
Jump to navigationJump to search
 
(11 intermediate revisions by 8 users not shown)
Line 1: Line 1:
 
==Overview==
 
==Overview==
Docking allows to combine several windows (forms) into one window and to split them. The central instance to control how a form is docked to another is the '''docking manager'''. For exmaple the Delphi docking manager uses the Align property to combine forms. This limits the allowed docking layouts, but at least it has a rudimentary save/restore mechanism. The free Delphi package ''DockPanel'' uses the Align property, hidden panels and TPageControls to allow nested layouts and even page docking. The TLazDockingManager uses the LCL Anchor properties, TPageControl and TSplitters, it allows nesting, page docking, autosize and has a sophisticated save/restore mechanism (see [[Anchor Docking]]).
+
There exist two different flavors of docking. The Delphi compatible DragDock model is based on dedicated target controls (DockSites), into which other controls or forms can be docked by dragging them with the mouse. The Lazarus specific AnchorDocking model allows to glue forms together by other means.
 +
 
 +
Docked forms or controls can be undocked again, of course, and a constructed layout can be stored for later restauration, like the IDE window layout.
 +
 
 +
===Docking Managers===
 +
 
 +
The central instance to determine how a control is docked to others is the '''docking manager'''. For example the Delphi default docking manager (TDockTree) allows to insert a dropped control relative to an already docked control. User supplied docking managers can implement other docking models and layouts, e.g. for constructing forms and dialogs, flowcharts, motherboards, electrical circuits, city plans or other diagrams. Every such docking manager provides visual feedback to the user, signaling how a dragged control will be placed into the managed DockSite. The free Delphi package ''DockPanel'' uses the Align property, hidden panels and TPageControls to allow nested layouts and even page docking. In the Lazarus sources there are two docking implementations
 +
 
 +
*[[Anchor Docking]]
 +
*[[EasyDockingManager]]
  
 
===Not only forms===
 
===Not only forms===
The VCL (Delphi's pendant to the LCL) docking is not limited to forms. It can dock and undock any TWinControl. A form is automatically created and the control is put onto it. What type of form is created is defined by the function GetFloatingDockSiteClass. When a control is undocked the LCL automatically creates this class and add the control as child.
+
 
 +
Docking is not limited to forms in the LCL. It can dock and undock any control. When a non-windowed control is undocked, a form is automatically created and the control is put onto it. What type of form is created is defined by the function GetFloatingDockSiteClass. When a control is undocked the LCL automatically creates this class and add the control as child.
  
 
===Splitters===
 
===Splitters===
Some docking managers automatically add splitters between the docked forms so the user can still resize the forms. This is done by TLazDockingManager.
+
 
 +
Some docking managers automatically add splitters between the docked controls so the user can still resize the controls. The LCL provides TSplitter with some extended features like anchors, that Delphi does not have. This allows for very flexible layouts without hidden panels.
  
 
===Drag and Drop===
 
===Drag and Drop===
Some docking managers allows to dock forms via drag and drop. This is not yet implemented in the LCL and especially not every widgetset provides the same support. So even if it starts working on one platform it is not enough for the IDE. The IDE docking must be usable without drag and drop. The TLazDockingManager provides a popup menu item which leads to a dialog to setup the docking. Eventually drag and drop docking will be supported by the LCL.
+
 
 +
Some docking managers allows to dock forms via drag and drop. The dragging is implemented in the LCL and the docking managers can control the details. Some platforms like MS Windows sends drag events when dragging the title bar, others like Linux do not. Therefore docking managers under Linux require to add drag areas to each dockable form. These drag areas are often called ''dock headers''. Dragging can start automatically via the DragKind and DragMode properties or manually via the DragManager.DragStart method.
  
 
===Save/Restore===
 
===Save/Restore===
Some docking managers allows to save the current layout and restore it later. Some docking manager have a static restore. Static means it works only for a specific set of forms or the restore needs a specific creation order of the forms. For example imagine three forms docked together:
+
 
 +
Some docking managers allow to save the current layout and restore it later. How this is done is totally up to the docking packages. The LCL provides no framework for save/restore layouts of multiple forms.
 +
 
 +
Most docking packages have methods to save/restore the whole window layout of an application. That means they save all opened forms, their bounds and nested states and can restore that. Some have also a dynamic restore.
 +
For example imagine three forms docked together:
  
 
<pre>
 
<pre>
Line 23: Line 39:
 
</pre>
 
</pre>
  
Now imagine the application is restarted and only Form1 and Form2 have been created at start. The layout is restored somehow. For example by expanding Form2's height. Then Form3 is created. Some docking managers will not automatically dock the third form - the user has to redo the layout. Or they will dock Form3, but with a different size or at a different place. Some applications define a strict ruleset how to dock forms, which makes save/restore easy. The TLazDockingManager uses a dynamic restore and tries to restore the docking layout every time a form is shown. So if you create the 3 forms in any order they will be restored to the same layout. Many applications can live with a static restore. The IDE has lots of special windows - some are provided by design time packages, some are only created when needed (e.g. debugger, h2pas).
+
Now imagine the application is restarted and only Form1 and Form2 have been created at start. The layout is restored somehow. For example by expanding Form2's height, and requesting an instance of Form3. When no such instance is supplied immediately, it may or may not be docked into its previous place, when created later.
  
 
===Usage===
 
===Usage===
 +
 
Some docking managers can only dock special form descendants, so to make a form dockable it must descend from such a class or must be put onto one.
 
Some docking managers can only dock special form descendants, so to make a form dockable it must descend from such a class or must be put onto one.
 +
Because under Linux you must add a drag area, both existing dock managers wrap the dockable controls into docksites and add a drag area.
  
The TLazDockingManager only requires, that the programmer drops a TLazControlDocker onto the form, give an unique name and connect it to a TLazDockingManager. This way even existing forms do not need to change and can be easily extended to allow docking.
+
===See also===
You can create an arbitrary number of dock groups to forbid that some forms should never be docked together. But normally you use only one instance of TLazDockingManager for the whole application. This does ''not'' mean you have only one main docking window. There is no main docking window. The user can dock Form1 to Form2 and Form3 to Form4.
 
 
 
===Glossary===
 
 
 
;DockSite : A TWinControl with the boolean property DockSite set to True. A DockSite can accept DockClients.
 
;managed DockSite : A docksite with an installed dockmanager (DockManager<>nil, UseDockManager=True).
 
;docked : Controls appearing in a DockSite, in contrast to Floating or residing in an "ordinary" container control.
 
;DockClient : A docked control. In contrast to other controls, its position and size is controlled by the dockmanager of the docksite.
 
;target site : The docksite where the dragged control actually can or will be docked (when dropped).
 
;DockRect : A visible rectangle, that reflects the (intended) position and size of the dragged control after it is dropped.
 
;DockHeader : Visible elements, appearing near a docked control. They are added by the dockmanager, e.g. as a replacement for the invisible title bar of a docked form.
 
;floating : A dockable control in its own window on the screen, not docked into a docksite.
 
;floating site : A helper window, containing a dockable control that is not a window itself.
 
;FloatHost : TControl.FloatHostSite indicates the logical parent (floating site) of a docked control.
 
;ConJoinDockHost sites : Special docksites (application specific)
 
;wrapping a control into a floating site : When a dockable control cannot float for itself, a temporary floating site is created, into which the control is docked (wrapped). When the control is docked later, the floating site is destroyed.
 
  
===Links===
+
* [[Anchor Docking]]
 +
* [[Build custom dock manager]] - Tutorial
 +
* [[EasyDockingManager]]
 +
* [[DockedFormEditor]] - IDE implementation for form docked next to source
 +
* [[MultiDoc]] - replacement for standard MDI interface
 +
* [[Manual Docker]] - this Lazarus-IDE extension allows Messages window to dock to the source editor
  
*TLazDockingManager is described here [[Anchor Docking]]
+
[[Category:Docking]]
*Simulate MDI with [[MultiDoc]]
+
[[Category:Forms]]
 +
[[Category:Layout]]

Latest revision as of 19:26, 14 February 2021

Overview

There exist two different flavors of docking. The Delphi compatible DragDock model is based on dedicated target controls (DockSites), into which other controls or forms can be docked by dragging them with the mouse. The Lazarus specific AnchorDocking model allows to glue forms together by other means.

Docked forms or controls can be undocked again, of course, and a constructed layout can be stored for later restauration, like the IDE window layout.

Docking Managers

The central instance to determine how a control is docked to others is the docking manager. For example the Delphi default docking manager (TDockTree) allows to insert a dropped control relative to an already docked control. User supplied docking managers can implement other docking models and layouts, e.g. for constructing forms and dialogs, flowcharts, motherboards, electrical circuits, city plans or other diagrams. Every such docking manager provides visual feedback to the user, signaling how a dragged control will be placed into the managed DockSite. The free Delphi package DockPanel uses the Align property, hidden panels and TPageControls to allow nested layouts and even page docking. In the Lazarus sources there are two docking implementations

Not only forms

Docking is not limited to forms in the LCL. It can dock and undock any control. When a non-windowed control is undocked, a form is automatically created and the control is put onto it. What type of form is created is defined by the function GetFloatingDockSiteClass. When a control is undocked the LCL automatically creates this class and add the control as child.

Splitters

Some docking managers automatically add splitters between the docked controls so the user can still resize the controls. The LCL provides TSplitter with some extended features like anchors, that Delphi does not have. This allows for very flexible layouts without hidden panels.

Drag and Drop

Some docking managers allows to dock forms via drag and drop. The dragging is implemented in the LCL and the docking managers can control the details. Some platforms like MS Windows sends drag events when dragging the title bar, others like Linux do not. Therefore docking managers under Linux require to add drag areas to each dockable form. These drag areas are often called dock headers. Dragging can start automatically via the DragKind and DragMode properties or manually via the DragManager.DragStart method.

Save/Restore

Some docking managers allow to save the current layout and restore it later. How this is done is totally up to the docking packages. The LCL provides no framework for save/restore layouts of multiple forms.

Most docking packages have methods to save/restore the whole window layout of an application. That means they save all opened forms, their bounds and nested states and can restore that. Some have also a dynamic restore. For example imagine three forms docked together:

+-----++-----+
|Form1||Form2|
|     |+-----+
|     |+-----+
|     ||Form3|
+-----++-----+

Now imagine the application is restarted and only Form1 and Form2 have been created at start. The layout is restored somehow. For example by expanding Form2's height, and requesting an instance of Form3. When no such instance is supplied immediately, it may or may not be docked into its previous place, when created later.

Usage

Some docking managers can only dock special form descendants, so to make a form dockable it must descend from such a class or must be put onto one. Because under Linux you must add a drag area, both existing dock managers wrap the dockable controls into docksites and add a drag area.

See also