View Issue Details

IDProjectCategoryView StatusLast Update
0034347LazarusPackagespublic2019-01-28 06:32
ReporterAndrey Zubarev Assigned ToMichl  
PrioritynormalSeverityminorReproducibilityhave not tried
Status closedResolutionfixed 
Target Version2.2Fixed in Version2.1 (SVN) 
Summary0034347: AnchorDocking feature (new button: size reduction of the panel)
DescriptionSuch there is in many programs. When you mouse over the panel increases, when lose the mouse decreases.
Take a look at the attached screenshot of Delphi
TagsNo tags attached.
Fixed in Revision59681, 60099, 60233, 60234
LazTarget-
Widgetset
Attached Files

Relationships

related to 0034363 closedMichl AnchorDocking top level site with pages need header 
related to 0034508 closedMichl AnchorDocking, add an event allowing to draw a custom header 
related to 0034614 closedMichl AnchorDocking: Sites can be overlapped after minimize\unminimize 
related to 0034612 closedMichl AnchorDocking: AV on double loading layout with minimized sites 

Activities

Andrey Zubarev

2018-09-27 12:04

reporter  

button.png (65,548 bytes)   
button.png (65,548 bytes)   

Juha Manninen

2018-09-27 15:16

developer   ~0111054

What increases and decreases?

Andrey Zubarev

2018-09-28 07:16

reporter   ~0111059

Sorry for my English. See animated gif https://imgur.com/a/A5Zg7f8

Juha Manninen

2018-09-28 09:17

developer   ~0111060

Ok, I see. I don't know what is the right word for it. Minimize / normalize maybe.
The window overlaps other windows until you click the upper pin-button.

Andrey Zubarev

2018-10-30 11:48

reporter   ~0111677

Tried to do, in the first looming, looks so anchordocking_minimize_docksite1.patch
Problems:
-ugly minimize button
-minimize state not saved
-form resize not handled
-form undock not handled
-overlap show not implemented

Andrey Zubarev

2018-10-30 11:49

reporter  

anchordocking_minimize_docksite1.patch (12,637 bytes)   
Index: components/anchordocking/anchordocking.pas
===================================================================
--- components/anchordocking/anchordocking.pas	(revision 59377)
+++ components/anchordocking/anchordocking.pas	(working copy)
@@ -123,6 +123,14 @@
            PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
   end;
 
+  TAnchorDockMinimizeButton = class(TCustomSpeedButton)
+  protected
+    function GetDrawDetails: TThemedElementDetails; override;
+    procedure CalculatePreferredSize(var PreferredWidth,
+           PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
+  end;
+
+
   { TAnchorDockHeader
     The panel of a TAnchorDockHostSite containing the close button and the
     caption when the form is docked. The header can be shown at any of the four
@@ -133,9 +141,11 @@
   TAnchorDockHeader = class(TCustomPanel)
   private
     FCloseButton: TCustomSpeedButton;
+    FMinimizeButton: TCustomSpeedButton;
     FHeaderPosition: TADLHeaderPosition;
     fFocused:Boolean;
     procedure CloseButtonClick(Sender: TObject);
+    procedure MinimizeButtonClick(Sender: TObject);
     procedure HeaderPositionItemClick(Sender: TObject);
     procedure UndockButtonClick(Sender: TObject);
     procedure MergeButtonClick(Sender: TObject);
@@ -154,6 +164,7 @@
   public
     constructor Create(TheOwner: TComponent); override;
     property CloseButton: TCustomSpeedButton read FCloseButton;
+    property MinimizeButton: TCustomSpeedButton read FMinimizeButton;
     property HeaderPosition: TADLHeaderPosition read FHeaderPosition write SetHeaderPosition;
     property BevelOuter default bvNone;
   end;
@@ -263,6 +274,7 @@
     FSiteType: TAnchorDockHostSiteType;
     FBoundSplitter: TAnchorDockSplitter;
     fUpdateLayout: integer;
+    FMinimized: boolean;
     procedure SetHeaderSide(const AValue: TAnchorKind);
   protected
     procedure DoEnter; override;
@@ -319,6 +331,7 @@
     destructor Destroy; override;
     function CloseQuery: boolean; override;
     function CloseSite: boolean; virtual;
+    procedure MinimizeSite; virtual;
     procedure RemoveControl(AControl: TControl); override;
     procedure InsertControl(AControl: TControl; Index: integer); override;
     procedure GetSiteInfo(Client: TControl; var InfluenceRect: TRect;
@@ -2193,7 +2206,7 @@
       try
         SetupSite(Site,ANode,AParent);
         Site.FSiteType:=adhstPages;
-        Site.Header.Parent:=nil;
+        //Site.Header.Parent:=nil;
         if Site.Pages=nil then
           Site.CreatePages;
         for i:=0 to ANode.Count-1 do begin
@@ -3680,6 +3693,7 @@
     AControl:=TControl(Sender);
     if not (csDestroying in ComponentState) then begin
       if (not AControl.Visible)
+      and (not FMinimized)
       and (not ((AControl is TAnchorDockHeader)
                or (AControl is TAnchorDockSplitter)
                or (AControl is TAnchorDockHostSite)))
@@ -5165,6 +5179,59 @@
   Result:=Check(Self);
 end;
 
+function CheckOposite(Side:TAnchorKind;var AControl: TControl;out Splitter: TAnchorDockSplitter; out SplitterAnchorKind:TAnchorKind):boolean;
+begin
+  result:=GetDockSplitter(AControl,Side,Splitter);
+  if result then begin
+    if CountAnchoredControls(Splitter,OppositeAnchor[Side])=1 then begin
+      SplitterAnchorKind:=Side;
+      exit;
+    end;
+  end;
+  result:=false
+end;
+
+function FindNearestSpliter(AControl: TControl;out Splitter: TAnchorDockSplitter;out SplitterAnchorKind:TAnchorKind):boolean;
+begin
+  result:=CheckOposite(akTop,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akRight,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akBottom,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akLeft,AControl,Splitter,SplitterAnchorKind);
+end;
+
+procedure TAnchorDockHostSite.MinimizeSite;
+var
+  AControl: TControl;
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
+  SpliterPercentPosition:Single;
+begin
+  debugln(['TAnchorDockHostSite.MinimizeSite ',DbgSName(Self),' SiteType=',dbgs(SiteType)]);
+  AControl:=GetOneControl;
+  if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then
+    if Splitter.Enabled or FMinimized then begin
+      FMinimized:=not FMinimized;
+      AControl.Visible:=not AControl.Visible;
+      Splitter.Enabled:=AControl.Visible;
+      if FMinimized then begin
+        SpliterPercentPosition:=Splitter.FPercentPosition;
+        UpdateHeaderAlign;
+        case SplitterAnchorKind of
+          akTop: Splitter.MoveSplitter(Height-Header.Height);
+          akBottom: Splitter.MoveSplitter(Header.Height-Splitter.Top);
+          akLeft: Splitter.MoveSplitter(Header.Height-Splitter.Left);
+          akRight: Splitter.MoveSplitter(Width-Header.Height);
+        end;
+        Splitter.FPercentPosition:=SpliterPercentPosition;
+      end else begin
+        UpdateHeaderAlign;
+      end;
+    end;
+end;
+
 function TAnchorDockHostSite.CloseSite: boolean;
 var
   AControl: TControl;
@@ -5306,9 +5373,8 @@
     if Parent is TAnchorDockPage then
       TAnchorDockPage(Parent).UpdateDockCaption;
   end;
-
   // do not show close button for mainform
-  Header.CloseButton.Visible:=not IsParentOf(Application.MainForm);
+  Header.CloseButton.Visible:=(not IsParentOf(Application.MainForm))and(Pages=nil);
 end;
 
 procedure TAnchorDockHostSite.GetSiteInfo(Client: TControl;
@@ -5362,9 +5428,27 @@
 end;
 
 procedure TAnchorDockHostSite.UpdateHeaderAlign;
+const
+OppositeAlign: array[TAnchorKind] of TAlign = (
+  alBottom, // akTop,
+  alRight,  // akLeft,
+  alLeft,   // akRight,
+  alTop     // akBottom
+  );
+var
+  NeededHeaderPosition:TADLHeaderPosition;
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
 begin
   if Header=nil then exit;
-  case Header.HeaderPosition of
+  if FMinimized then begin
+    if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+      Header.Align:=OppositeAlign[SplitterAnchorKind];
+    end else
+      NeededHeaderPosition:=Header.HeaderPosition;
+  end else
+    NeededHeaderPosition:=Header.HeaderPosition;
+  case NeededHeaderPosition of
   adlhpAuto:
     if Header.Align in [alLeft,alRight] then begin
       if (ClientHeight>0)
@@ -5476,6 +5560,7 @@
 constructor TAnchorDockHostSite.CreateNew(AOwner: TComponent; Num: Integer);
 begin
   inherited CreateNew(AOwner,Num);
+  FMinimized:=false;
   Visible:=false;
   FHeaderSide:=akTop;
   FHeader:=DockMaster.HeaderClass.Create(Self);
@@ -5569,6 +5654,13 @@
   end;
 end;
 
+procedure TAnchorDockHeader.MinimizeButtonClick(Sender: TObject);
+begin
+  if Parent is TAnchorDockHostSite then begin
+    TAnchorDockHostSite(Parent).MinimizeSite;
+  end;
+end;
+
 procedure TAnchorDockHeader.HeaderPositionItemClick(Sender: TObject);
 var
   Item: TMenuItem;
@@ -5640,6 +5732,13 @@
       r.Right:=CloseButton.Left-1;
   end;
 
+  if MinimizeButton.IsControlVisible and (MinimizeButton.Parent=Self) then begin
+    if Align in [alLeft,alRight] then
+      r.Top:=MinimizeButton.Top+MinimizeButton.Height+1
+    else
+      r.Right:=MinimizeButton.Left-1;
+  end;
+
   // caption
   if Caption<>'' then begin
     if fFocused and DockMaster.HeaderHighlightFocused and NeedHighlightText then
@@ -5728,7 +5827,14 @@
     end else begin
       PreferredHeight:=Max(NeededHeight,PreferredHeight);
     end;
+  end else begin
+    NeededHeight:=CloseButton.Height;
+    if Align in [alLeft,alRight] then begin
+      PreferredWidth:=Max(NeededHeight,PreferredWidth);
+    end else begin
+      PreferredHeight:=Max(NeededHeight,PreferredHeight);
   end;
+  end;
 end;
 
 procedure TAnchorDockHeader.MouseDown(Button: TMouseButton; Shift: TShiftState;
@@ -5742,11 +5848,15 @@
 procedure TAnchorDockHeader.UpdateHeaderControls;
 begin
   if Align in [alLeft,alRight] then begin
-    if CloseButton<>nil then
+    if CloseButton<>nil then begin
+      MinimizeButton.Align:=alTop;
       CloseButton.Align:=alTop;
+    end;
   end else begin
-    if CloseButton<>nil then
+    if CloseButton<>nil then begin
+      MinimizeButton.Align:=alRight;
       CloseButton.Align:=alRight;
+    end;
   end;
   //debugln(['TAnchorDockHeader.UpdateHeaderControls ',dbgs(Align),' ',dbgs(CloseButton.Align)]);
 end;
@@ -5787,9 +5897,9 @@
 begin
   inherited Create(TheOwner);
   FHeaderPosition:=adlhpAuto;
-  FCloseButton:=TAnchorDockCloseButton.Create(Self);
   BevelOuter:=bvNone;
   BorderWidth:=0;
+  FCloseButton:=TAnchorDockCloseButton.Create(Self);
   with FCloseButton do begin
     Name:='CloseButton';
     Parent:=Self;
@@ -5799,6 +5909,16 @@
     OnClick:=@CloseButtonClick;
     AutoSize:=true;
   end;
+  FMinimizeButton:=TAnchorDockMinimizeButton.Create(Self);
+  with FMinimizeButton do begin
+    Name:='MinimizeButton';
+    Parent:=Self;
+    Flat:=true;
+    ShowHint:=true;
+    Hint:=adrsMinimize;
+    OnClick:=@MinimizeButtonClick;
+    AutoSize:=true;
+  end;
   Align:=alTop;
   AutoSize:=true;
   ShowHint:=true;
@@ -5844,6 +5964,44 @@
   end;
 end;
 
+{ TAnchorDockMinimizeButton }
+
+function TAnchorDockMinimizeButton.GetDrawDetails: TThemedElementDetails;
+
+function WindowPart: TThemedWindow;
+  begin
+    // no check states available
+    Result := twMDIMinButtonNormal;
+    if not IsEnabled then
+      Result := twMDIMinButtonDisabled
+    else
+    if FState in [bsDown, bsExclusive] then
+      Result := twMDIMinButtonPushed
+    else
+    if FState = bsHot then
+      Result := twMDIMinButtonHot
+    else
+      Result := twMDIMinButtonNormal;
+  end;
+
+begin
+  Result := ThemeServices.GetElementDetails(WindowPart);
+end;
+
+procedure TAnchorDockMinimizeButton.CalculatePreferredSize(var PreferredWidth,
+  PreferredHeight: integer; WithThemeSpace: Boolean);
+begin
+  with ThemeServices.GetDetailSize(ThemeServices.GetElementDetails(twMinButtonNormal)) do
+  begin
+    PreferredWidth:=cx;
+    PreferredHeight:=cy;
+    {$IF defined(LCLGtk2) or defined(Carbon)}
+    inc(PreferredWidth,2);
+    inc(PreferredHeight,2);
+    {$ENDIF}
+  end;
+end;
+
 { TAnchorDockManager }
 
 procedure TAnchorDockManager.SetPreferredSiteSizeAsSiteMinimum(
@@ -6506,31 +6664,33 @@
 var
   NewLeft, NewTop: Integer;
 begin
-  if ResizeAnchor in [akLeft,akRight] then
-  begin
-    if DockParentClientSize.cx> 0 then
+  if Enabled then begin
+    if ResizeAnchor in [akLeft,akRight] then
     begin
-      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
-        NewLeft := Round(FPercentPosition*Parent.ClientWidth)
-      else
-        NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
-      NewTop := Top;
-      SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
-    end;
-  end else
-  begin
-    if DockParentClientSize.cy> 0 then
+      if DockParentClientSize.cx> 0 then
+      begin
+        if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+          NewLeft := Round(FPercentPosition*Parent.ClientWidth)
+        else
+          NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
+        NewTop := Top;
+        SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      end;
+    end else
     begin
-      NewLeft := Left;
-      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
-        NewTop := Round(FPercentPosition*Parent.ClientHeight)
-      else
-        NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
-      SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      if DockParentClientSize.cy> 0 then
+      begin
+        NewLeft := Left;
+        if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+          NewTop := Round(FPercentPosition*Parent.ClientHeight)
+        else
+          NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+        SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      end;
     end;
+    if FPercentPosition < 0 then
+      UpdatePercentPosition;
   end;
-  if FPercentPosition < 0 then
-    UpdatePercentPosition;
 end;
 
 function TAnchorDockSplitter.SideAnchoredControlCount(Side: TAnchorKind): integer;
Index: components/anchordocking/anchordockstr.pas
===================================================================
--- components/anchordocking/anchordockstr.pas	(revision 59377)
+++ components/anchordocking/anchordockstr.pas	(working copy)
@@ -8,6 +8,7 @@
 
 resourcestring
   adrsClose = 'Close';
+  adrsMinimize = 'Minimize';
   adrsQuit = 'Quit %s';
   adrsTabPosition = 'Tab position';
   adrsMovePageRight = 'Move page right';

Juha Manninen

2018-10-30 22:34

developer   ~0111697

Andrey Zubarev, with all the problems you listed, do you feel the patch should be applied into trunk?
I have not tested it. I am not even the right person to test it thoroughly because I don't normally use AnchorDocking.
Others please test. What do you think?

Andrey Zubarev

2018-10-30 23:34

reporter   ~0111699

Of course add in trunk cannot be. I put it out for the test, and probably someone has an opinion on this, I would like to discuss.

New patch with:
-ugly minimize button
-minimize state not saved
-form undock not handled
-overlap show not implemented

Andrey Zubarev

2018-10-30 23:35

reporter  

anchordocking_minimize_docksite2.patch (15,240 bytes)   
Index: components/anchordocking/anchordocking.pas
===================================================================
--- components/anchordocking/anchordocking.pas	(revision 59377)
+++ components/anchordocking/anchordocking.pas	(working copy)
@@ -123,6 +123,14 @@
            PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
   end;
 
+  TAnchorDockMinimizeButton = class(TCustomSpeedButton)
+  protected
+    function GetDrawDetails: TThemedElementDetails; override;
+    procedure CalculatePreferredSize(var PreferredWidth,
+           PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
+  end;
+
+
   { TAnchorDockHeader
     The panel of a TAnchorDockHostSite containing the close button and the
     caption when the form is docked. The header can be shown at any of the four
@@ -133,9 +141,11 @@
   TAnchorDockHeader = class(TCustomPanel)
   private
     FCloseButton: TCustomSpeedButton;
+    FMinimizeButton: TCustomSpeedButton;
     FHeaderPosition: TADLHeaderPosition;
     fFocused:Boolean;
     procedure CloseButtonClick(Sender: TObject);
+    procedure MinimizeButtonClick(Sender: TObject);
     procedure HeaderPositionItemClick(Sender: TObject);
     procedure UndockButtonClick(Sender: TObject);
     procedure MergeButtonClick(Sender: TObject);
@@ -154,6 +164,7 @@
   public
     constructor Create(TheOwner: TComponent); override;
     property CloseButton: TCustomSpeedButton read FCloseButton;
+    property MinimizeButton: TCustomSpeedButton read FMinimizeButton;
     property HeaderPosition: TADLHeaderPosition read FHeaderPosition write SetHeaderPosition;
     property BevelOuter default bvNone;
   end;
@@ -263,6 +274,7 @@
     FSiteType: TAnchorDockHostSiteType;
     FBoundSplitter: TAnchorDockSplitter;
     fUpdateLayout: integer;
+    FMinimized: boolean;
     procedure SetHeaderSide(const AValue: TAnchorKind);
   protected
     procedure DoEnter; override;
@@ -319,6 +331,7 @@
     destructor Destroy; override;
     function CloseQuery: boolean; override;
     function CloseSite: boolean; virtual;
+    procedure MinimizeSite; virtual;
     procedure RemoveControl(AControl: TControl); override;
     procedure InsertControl(AControl: TControl; Index: integer); override;
     procedure GetSiteInfo(Client: TControl; var InfluenceRect: TRect;
@@ -970,6 +983,27 @@
   end;
 end;
 
+function CountAndReturnOnlyOneMinimizedAnchoredControls(Control: TControl; Side: TAnchorKind): TAnchorDockHostSite;
+var
+  i,Counter: Integer;
+  Neighbour: TControl;
+begin
+  Counter:=0;
+  for i:=0 to Control.AnchoredControlCount-1 do begin
+    Neighbour:=Control.AnchoredControls[i];
+    if Neighbour.Visible then
+    if Neighbour is TAnchorDockHostSite then
+    if (OppositeAnchor[Side] in Neighbour.Anchors)
+    and (Neighbour.AnchorSide[OppositeAnchor[Side]].Control=Control) then begin
+      inc(Counter);
+      result:=TAnchorDockHostSite(Neighbour);
+    end;
+  end;
+  if (Counter=1)and(result is TAnchorDockHostSite)and((result as TAnchorDockHostSite).FMinimized) then
+  else
+    result:=Nil;
+end;
+
 function NeighbourCanBeShrinked(EnlargeControl, Neighbour: TControl;
   Side: TAnchorKind): boolean;
 { returns true if Neighbour can be shrinked on the opposite side of Side
@@ -2193,7 +2227,7 @@
       try
         SetupSite(Site,ANode,AParent);
         Site.FSiteType:=adhstPages;
-        Site.Header.Parent:=nil;
+        //Site.Header.Parent:=nil;
         if Site.Pages=nil then
           Site.CreatePages;
         for i:=0 to ANode.Count-1 do begin
@@ -3680,6 +3714,7 @@
     AControl:=TControl(Sender);
     if not (csDestroying in ComponentState) then begin
       if (not AControl.Visible)
+      and (not FMinimized)
       and (not ((AControl is TAnchorDockHeader)
                or (AControl is TAnchorDockSplitter)
                or (AControl is TAnchorDockHostSite)))
@@ -5165,6 +5200,63 @@
   Result:=Check(Self);
 end;
 
+function CheckOposite(Side:TAnchorKind;var AControl: TControl;out Splitter: TAnchorDockSplitter; out SplitterAnchorKind:TAnchorKind):boolean;
+begin
+  result:=GetDockSplitter(AControl,Side,Splitter);
+  if result then begin
+    if CountAnchoredControls(Splitter,OppositeAnchor[Side])=1 then begin
+      SplitterAnchorKind:=Side;
+      exit;
+    end;
+  end;
+  result:=false
+end;
+
+function FindNearestSpliter(AControl: TControl;out Splitter: TAnchorDockSplitter;out SplitterAnchorKind:TAnchorKind):boolean;
+begin
+  result:=CheckOposite(akTop,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akRight,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akBottom,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akLeft,AControl,Splitter,SplitterAnchorKind);
+end;
+
+procedure TAnchorDockHostSite.MinimizeSite;
+var
+  AControl: TControl;
+  OpositeDockHostSite:TAnchorDockHostSite;
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
+  //SpliterPercentPosition:Single;
+begin
+  debugln(['TAnchorDockHostSite.MinimizeSite ',DbgSName(Self),' SiteType=',dbgs(SiteType)]);
+  AControl:=GetOneControl;
+  if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+    OpositeDockHostSite:=CountAndReturnOnlyOneMinimizedAnchoredControls(Splitter,SplitterAnchorKind);
+    if (Splitter.Enabled and (OpositeDockHostSite=nil)) or FMinimized then begin
+      FMinimized:=not FMinimized;
+      AControl.Visible:=not AControl.Visible;
+      Splitter.Enabled:=AControl.Visible;
+      UpdateHeaderAlign;
+      {if FMinimized then begin
+        SpliterPercentPosition:=Splitter.FPercentPosition;
+        UpdateHeaderAlign;
+        case SplitterAnchorKind of
+          akTop: Splitter.MoveSplitter(Height-Header.Height);
+          akBottom: Splitter.MoveSplitter(Header.Height-Splitter.Top);
+          akLeft: Splitter.MoveSplitter(Header.Height-Splitter.Left);
+          akRight: Splitter.MoveSplitter(Width-Header.Height);
+        end;
+        Splitter.FPercentPosition:=SpliterPercentPosition;
+      end else begin
+        UpdateHeaderAlign;
+      end;}
+    end;
+  end;
+end;
+
 function TAnchorDockHostSite.CloseSite: boolean;
 var
   AControl: TControl;
@@ -5306,9 +5398,8 @@
     if Parent is TAnchorDockPage then
       TAnchorDockPage(Parent).UpdateDockCaption;
   end;
-
   // do not show close button for mainform
-  Header.CloseButton.Visible:=not IsParentOf(Application.MainForm);
+  Header.CloseButton.Visible:=(not IsParentOf(Application.MainForm))and(Pages=nil);
 end;
 
 procedure TAnchorDockHostSite.GetSiteInfo(Client: TControl;
@@ -5362,9 +5453,27 @@
 end;
 
 procedure TAnchorDockHostSite.UpdateHeaderAlign;
+const
+OppositeAlign: array[TAnchorKind] of TAlign = (
+  alBottom, // akTop,
+  alRight,  // akLeft,
+  alLeft,   // akRight,
+  alTop     // akBottom
+  );
+var
+  NeededHeaderPosition:TADLHeaderPosition;
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
 begin
   if Header=nil then exit;
-  case Header.HeaderPosition of
+  if FMinimized then begin
+    if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+      Header.Align:=OppositeAlign[SplitterAnchorKind];
+    end else
+      NeededHeaderPosition:=Header.HeaderPosition;
+  end else
+    NeededHeaderPosition:=Header.HeaderPosition;
+  case NeededHeaderPosition of
   adlhpAuto:
     if Header.Align in [alLeft,alRight] then begin
       if (ClientHeight>0)
@@ -5476,6 +5585,7 @@
 constructor TAnchorDockHostSite.CreateNew(AOwner: TComponent; Num: Integer);
 begin
   inherited CreateNew(AOwner,Num);
+  FMinimized:=false;
   Visible:=false;
   FHeaderSide:=akTop;
   FHeader:=DockMaster.HeaderClass.Create(Self);
@@ -5569,6 +5679,13 @@
   end;
 end;
 
+procedure TAnchorDockHeader.MinimizeButtonClick(Sender: TObject);
+begin
+  if Parent is TAnchorDockHostSite then begin
+    TAnchorDockHostSite(Parent).MinimizeSite;
+  end;
+end;
+
 procedure TAnchorDockHeader.HeaderPositionItemClick(Sender: TObject);
 var
   Item: TMenuItem;
@@ -5640,6 +5757,13 @@
       r.Right:=CloseButton.Left-1;
   end;
 
+  if MinimizeButton.IsControlVisible and (MinimizeButton.Parent=Self) then begin
+    if Align in [alLeft,alRight] then
+      r.Top:=MinimizeButton.Top+MinimizeButton.Height+1
+    else
+      r.Right:=MinimizeButton.Left-1;
+  end;
+
   // caption
   if Caption<>'' then begin
     if fFocused and DockMaster.HeaderHighlightFocused and NeedHighlightText then
@@ -5728,7 +5852,14 @@
     end else begin
       PreferredHeight:=Max(NeededHeight,PreferredHeight);
     end;
+  end else begin
+    NeededHeight:=CloseButton.Height;
+    if Align in [alLeft,alRight] then begin
+      PreferredWidth:=Max(NeededHeight,PreferredWidth);
+    end else begin
+      PreferredHeight:=Max(NeededHeight,PreferredHeight);
   end;
+  end;
 end;
 
 procedure TAnchorDockHeader.MouseDown(Button: TMouseButton; Shift: TShiftState;
@@ -5742,11 +5873,15 @@
 procedure TAnchorDockHeader.UpdateHeaderControls;
 begin
   if Align in [alLeft,alRight] then begin
-    if CloseButton<>nil then
+    if CloseButton<>nil then begin
+      MinimizeButton.Align:=alTop;
       CloseButton.Align:=alTop;
+    end;
   end else begin
-    if CloseButton<>nil then
+    if CloseButton<>nil then begin
+      MinimizeButton.Align:=alRight;
       CloseButton.Align:=alRight;
+    end;
   end;
   //debugln(['TAnchorDockHeader.UpdateHeaderControls ',dbgs(Align),' ',dbgs(CloseButton.Align)]);
 end;
@@ -5787,9 +5922,9 @@
 begin
   inherited Create(TheOwner);
   FHeaderPosition:=adlhpAuto;
-  FCloseButton:=TAnchorDockCloseButton.Create(Self);
   BevelOuter:=bvNone;
   BorderWidth:=0;
+  FCloseButton:=TAnchorDockCloseButton.Create(Self);
   with FCloseButton do begin
     Name:='CloseButton';
     Parent:=Self;
@@ -5799,6 +5934,16 @@
     OnClick:=@CloseButtonClick;
     AutoSize:=true;
   end;
+  FMinimizeButton:=TAnchorDockMinimizeButton.Create(Self);
+  with FMinimizeButton do begin
+    Name:='MinimizeButton';
+    Parent:=Self;
+    Flat:=true;
+    ShowHint:=true;
+    Hint:=adrsMinimize;
+    OnClick:=@MinimizeButtonClick;
+    AutoSize:=true;
+  end;
   Align:=alTop;
   AutoSize:=true;
   ShowHint:=true;
@@ -5844,6 +5989,44 @@
   end;
 end;
 
+{ TAnchorDockMinimizeButton }
+
+function TAnchorDockMinimizeButton.GetDrawDetails: TThemedElementDetails;
+
+function WindowPart: TThemedWindow;
+  begin
+    // no check states available
+    Result := twMDIMinButtonNormal;
+    if not IsEnabled then
+      Result := twMDIMinButtonDisabled
+    else
+    if FState in [bsDown, bsExclusive] then
+      Result := twMDIMinButtonPushed
+    else
+    if FState = bsHot then
+      Result := twMDIMinButtonHot
+    else
+      Result := twMDIMinButtonNormal;
+  end;
+
+begin
+  Result := ThemeServices.GetElementDetails(WindowPart);
+end;
+
+procedure TAnchorDockMinimizeButton.CalculatePreferredSize(var PreferredWidth,
+  PreferredHeight: integer; WithThemeSpace: Boolean);
+begin
+  with ThemeServices.GetDetailSize(ThemeServices.GetElementDetails(twMinButtonNormal)) do
+  begin
+    PreferredWidth:=cx;
+    PreferredHeight:=cy;
+    {$IF defined(LCLGtk2) or defined(Carbon)}
+    inc(PreferredWidth,2);
+    inc(PreferredHeight,2);
+    {$ENDIF}
+  end;
+end;
+
 { TAnchorDockManager }
 
 procedure TAnchorDockManager.SetPreferredSiteSizeAsSiteMinimum(
@@ -6505,32 +6688,57 @@
 procedure TAnchorDockSplitter.SetBoundsPercentually;
 var
   NewLeft, NewTop: Integer;
+  AControl: TControl;
+  SplitterAnchorKind:TAnchorKind;
 begin
-  if ResizeAnchor in [akLeft,akRight] then
-  begin
-    if DockParentClientSize.cx> 0 then
+  if Enabled then begin
+    if ResizeAnchor in [akLeft,akRight] then
     begin
-      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
-        NewLeft := Round(FPercentPosition*Parent.ClientWidth)
-      else
-        NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
-      NewTop := Top;
-      SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      if DockParentClientSize.cx> 0 then
+      begin
+        if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+          NewLeft := Round(FPercentPosition*Parent.ClientWidth)
+        else
+          NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
+        NewTop := Top;
+        SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      end;
+    end else
+    begin
+      if DockParentClientSize.cy> 0 then
+      begin
+        NewLeft := Left;
+        if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+          NewTop := Round(FPercentPosition*Parent.ClientHeight)
+        else
+          NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+        SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      end;
     end;
-  end else
-  begin
-    if DockParentClientSize.cy> 0 then
-    begin
-      NewLeft := Left;
-      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
-        NewTop := Round(FPercentPosition*Parent.ClientHeight)
-      else
-        NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+    if FPercentPosition < 0 then
+      UpdatePercentPosition;
+  end else begin
+    SplitterAnchorKind:=akTop;
+    AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);
+    if AControl=nil then begin SplitterAnchorKind:=akRight;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+    if AControl=nil then begin SplitterAnchorKind:=akBottom;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+    if AControl=nil then begin SplitterAnchorKind:=akLeft;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+
+    if AControl is TAnchorDockHostSite then begin
+      (AControl as TAnchorDockHostSite).UpdateHeaderAlign;
+      NewTop := (AControl as TAnchorDockHostSite).Header.Left;
+      NewTop := (AControl as TAnchorDockHostSite).Header.Height;
+      NewLeft := left;
+      NewTop := top;
+      case SplitterAnchorKind of
+        akTop: NewTop := AControl.Top+(AControl as TAnchorDockHostSite).Header.Height;
+        akBottom: NewTop := AControl.Top+AControl.Height-(AControl as TAnchorDockHostSite).Header.Height-Height;
+        akLeft: NewLeft := AControl.Left+(AControl as TAnchorDockHostSite).Header.Width;
+        akRight: NewLeft := AControl.Left+AControl.Width-(AControl as TAnchorDockHostSite).Header.Width-Width;
+      end;
       SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
     end;
   end;
-  if FPercentPosition < 0 then
-    UpdatePercentPosition;
 end;
 
 function TAnchorDockSplitter.SideAnchoredControlCount(Side: TAnchorKind): integer;
Index: components/anchordocking/anchordockstr.pas
===================================================================
--- components/anchordocking/anchordockstr.pas	(revision 59377)
+++ components/anchordocking/anchordockstr.pas	(working copy)
@@ -8,6 +8,7 @@
 
 resourcestring
   adrsClose = 'Close';
+  adrsMinimize = 'Minimize';
   adrsQuit = 'Quit %s';
   adrsTabPosition = 'Tab position';
   adrsMovePageRight = 'Move page right';

Juha Manninen

2018-10-31 18:57

developer   ~0111710

> Of course add in trunk cannot be. I put it out for the test, and probably someone has an opinion on this, I would like to discuss.

:)
As you notice, it is difficult to get people to test a patch. Changes applied in trunk have a little better chance of being tested.

Andrey Zubarev

2018-10-31 19:10

reporter   ~0111711

First we need to add a setting and make it off by default. Currently it looks ugly and will scare ordinary users

Andrey Zubarev

2018-10-31 19:19

reporter   ~0111712

https://imgur.com/a/pscP56l

Andrey Zubarev

2018-10-31 22:36

reporter  

anchordocking_minimize_docksite3.patch (35,632 bytes)   
Index: components/anchordocking/anchordocking.pas
===================================================================
--- components/anchordocking/anchordocking.pas	(revision 59377)
+++ components/anchordocking/anchordocking.pas	(working copy)
@@ -123,6 +123,14 @@
            PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
   end;
 
+  TAnchorDockMinimizeButton = class(TCustomSpeedButton)
+  protected
+    function GetDrawDetails: TThemedElementDetails; override;
+    procedure CalculatePreferredSize(var PreferredWidth,
+           PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
+  end;
+
+
   { TAnchorDockHeader
     The panel of a TAnchorDockHostSite containing the close button and the
     caption when the form is docked. The header can be shown at any of the four
@@ -133,9 +141,11 @@
   TAnchorDockHeader = class(TCustomPanel)
   private
     FCloseButton: TCustomSpeedButton;
+    FMinimizeButton: TCustomSpeedButton;
     FHeaderPosition: TADLHeaderPosition;
     fFocused:Boolean;
     procedure CloseButtonClick(Sender: TObject);
+    procedure MinimizeButtonClick(Sender: TObject);
     procedure HeaderPositionItemClick(Sender: TObject);
     procedure UndockButtonClick(Sender: TObject);
     procedure MergeButtonClick(Sender: TObject);
@@ -154,6 +164,7 @@
   public
     constructor Create(TheOwner: TComponent); override;
     property CloseButton: TCustomSpeedButton read FCloseButton;
+    property MinimizeButton: TCustomSpeedButton read FMinimizeButton;
     property HeaderPosition: TADLHeaderPosition read FHeaderPosition write SetHeaderPosition;
     property BevelOuter default bvNone;
   end;
@@ -263,6 +274,7 @@
     FSiteType: TAnchorDockHostSiteType;
     FBoundSplitter: TAnchorDockSplitter;
     fUpdateLayout: integer;
+    FMinimized: boolean;
     procedure SetHeaderSide(const AValue: TAnchorKind);
   protected
     procedure DoEnter; override;
@@ -319,6 +331,7 @@
     destructor Destroy; override;
     function CloseQuery: boolean; override;
     function CloseSite: boolean; virtual;
+    procedure MinimizeSite; virtual;
     procedure RemoveControl(AControl: TControl); override;
     procedure InsertControl(AControl: TControl; Index: integer); override;
     procedure GetSiteInfo(Client: TControl; var InfluenceRect: TRect;
@@ -431,6 +444,7 @@
     FShowHeader: boolean;
     FShowHeaderCaption: boolean;
     FSplitterWidth: integer;
+    FDockSitecCanBeMinimized: boolean;
     procedure SetAllowDragging(AValue: boolean);
     procedure SetDockOutsideMargin(AValue: integer);
     procedure SetDockParentMargin(AValue: integer);
@@ -448,6 +462,7 @@
     procedure SetHeaderFlatten(AValue: boolean);
     procedure SetHeaderFilled(AValue: boolean);
     procedure SetHeaderHighlightFocused(AValue: boolean);
+    procedure SetDockSitecCanBeMinimized(AValue: boolean);
   public
     property DragTreshold: integer read FDragTreshold write SetDragTreshold;
     property DockOutsideMargin: integer read FDockOutsideMargin write SetDockOutsideMargin;
@@ -466,6 +481,7 @@
     property HeaderFlatten: boolean read FHeaderFlatten write SetHeaderFlatten;
     property HeaderFilled: boolean read FHeaderFilled write SetHeaderFilled;
     property HeaderHighlightFocused: boolean read FHeaderHighlightFocused write SetHeaderHighlightFocused;
+    property DockSitesCanBeMinimized: boolean read FDockSitecCanBeMinimized write SetDockSitecCanBeMinimized;
     procedure IncreaseChangeStamp; inline;
     property ChangeStamp: integer read FChangeStamp;
     procedure LoadFromConfig(Config: TConfigStorage); overload;
@@ -502,6 +518,7 @@
     FHeaderFlatten: boolean;
     FHeaderFilled: boolean;
     FHeaderHighlightFocused: boolean;
+    FDockSitesCanBeMinimized: boolean;
     FIdleConnected: Boolean;
     FManagerClass: TAnchorDockManagerClass;
     FOnCreateControl: TADCreateControlEvent;
@@ -561,6 +578,7 @@
     procedure SetHeaderFlatten(AValue: boolean);
     procedure SetHeaderFilled(AValue: boolean);
     procedure SetHeaderHighlightFocused(AValue: boolean);
+    procedure SetDockSitesCanBeMinimized(AValue: boolean);
 
     procedure SetShowMenuItemShowHeader(AValue: boolean);
     procedure SetupSite(Site: TWinControl; ANode: TAnchorDockLayoutTreeNode;
@@ -680,6 +698,7 @@
     property HeaderFlatten: boolean read FHeaderFlatten write SetHeaderFlatten default true;
     property HeaderFilled: boolean read FHeaderFilled write SetHeaderFilled default true;
     property HeaderHighlightFocused: boolean read FHeaderHighlightFocused write SetHeaderHighlightFocused default false;
+    property DockSitesCanBeMinimized: boolean read FDockSitesCanBeMinimized write SetDockSitesCanBeMinimized default false;
 
     property SplitterWidth: integer read FSplitterWidth write SetSplitterWidth default 4;
     property ScaleOnResize: boolean read FScaleOnResize write SetScaleOnResize default true; // scale children when resizing a site
@@ -970,6 +989,27 @@
   end;
 end;
 
+function CountAndReturnOnlyOneMinimizedAnchoredControls(Control: TControl; Side: TAnchorKind): TAnchorDockHostSite;
+var
+  i,Counter: Integer;
+  Neighbour: TControl;
+begin
+  Counter:=0;
+  for i:=0 to Control.AnchoredControlCount-1 do begin
+    Neighbour:=Control.AnchoredControls[i];
+    if Neighbour.Visible then
+    if Neighbour is TAnchorDockHostSite then
+    if (OppositeAnchor[Side] in Neighbour.Anchors)
+    and (Neighbour.AnchorSide[OppositeAnchor[Side]].Control=Control) then begin
+      inc(Counter);
+      result:=TAnchorDockHostSite(Neighbour);
+    end;
+  end;
+  if (Counter=1)and(result is TAnchorDockHostSite)and((result as TAnchorDockHostSite).FMinimized) then
+  else
+    result:=Nil;
+end;
+
 function NeighbourCanBeShrinked(EnlargeControl, Neighbour: TControl;
   Side: TAnchorKind): boolean;
 { returns true if Neighbour can be shrinked on the opposite side of Side
@@ -1361,6 +1401,13 @@
   IncreaseChangeStamp;
 end;
 
+procedure TAnchorDockSettings.SetDockSitecCanBeMinimized(AValue: boolean);
+begin
+  if FDockSitecCanBeMinimized=AValue then Exit;
+  FDockSitecCanBeMinimized:=AValue;
+  IncreaseChangeStamp;
+end;
+
 procedure TAnchorDockSettings.Assign(Source: TAnchorDockSettings);
 begin
   FAllowDragging := Source.FAllowDragging;
@@ -1381,6 +1428,7 @@
   FShowHeaderCaption := Source.FShowHeaderCaption;
   FSplitterWidth := Source.FSplitterWidth;
   FHeaderHighlightFocused:=Source.FHeaderHighlightFocused;
+  FDockSitecCanBeMinimized:=Source.FDockSitecCanBeMinimized;
 end;
 
 procedure TAnchorDockSettings.IncreaseChangeStamp;
@@ -1407,6 +1455,7 @@
   HeaderFlatten:=Config.GetValue('HeaderFlatten',true);
   HeaderFilled:=Config.GetValue('HeaderFilled',true);
   HeaderHighlightFocused:=Config.GetValue('HeaderHighlightFocused',False);
+  DockSitesCanBeMinimized:=Config.GetValue('DockSitecCanBeMinimized',False);
   Config.UndoAppendBasePath;
 end;
 
@@ -1429,6 +1478,7 @@
   Config.SetDeleteValue(Path+'HeaderFlatten',HeaderFlatten,true);
   Config.SetDeleteValue(Path+'HeaderFilled',HeaderFilled,true);
   Config.SetDeleteValue(Path+'HeaderHighlightFocused',HeaderHighlightFocused,False);
+  Config.SetDeleteValue(Path+'DockSitecCanBeMinimized',DockSitesCanBeMinimized,False);
 end;
 
 procedure TAnchorDockSettings.SaveToConfig(Config: TConfigStorage);
@@ -1450,6 +1500,7 @@
   Config.SetDeleteValue('HeaderFlatten',HeaderFlatten,true);
   Config.SetDeleteValue('HeaderFilled',HeaderFilled,true);
   Config.SetDeleteValue('HeaderHighlightFocused',HeaderHighlightFocused,False);
+  Config.SetDeleteValue('DockSitecCanBeMinimized',DockSitesCanBeMinimized,False);
   Config.UndoAppendBasePath;
 end;
 
@@ -1472,6 +1523,7 @@
       and (HeaderFlatten=Settings.HeaderFlatten)
       and (HeaderFilled=Settings.HeaderFilled)
       and (HeaderHighlightFocused=Settings.HeaderHighlightFocused)
+      and (DockSitesCanBeMinimized=Settings.DockSitesCanBeMinimized)
       ;
 end;
 
@@ -1494,6 +1546,7 @@
   HeaderFlatten:=Config.GetValue(Path+'HeaderFlatten',true);
   HeaderFilled:=Config.GetValue(Path+'HeaderFilled',true);
   HeaderHighlightFocused:=Config.GetValue(Path+'HeaderHighlightFocused',False);
+  DockSitesCanBeMinimized:=Config.GetValue(Path+'DockSitecCanBeMinimized',False);
 end;
 
 { TAnchorDockMaster }
@@ -2193,7 +2246,7 @@
       try
         SetupSite(Site,ANode,AParent);
         Site.FSiteType:=adhstPages;
-        Site.Header.Parent:=nil;
+        //Site.Header.Parent:=nil;
         if Site.Pages=nil then
           Site.CreatePages;
         for i:=0 to ANode.Count-1 do begin
@@ -2514,6 +2567,24 @@
   InvalidateHeaders;
 end;
 
+procedure TAnchorDockMaster.SetDockSitesCanBeMinimized(AValue: boolean);
+var
+  i:integer;
+  Site: TAnchorDockHostSite;
+begin
+  if FDockSitesCanBeMinimized=AValue then Exit;
+  FDockSitesCanBeMinimized:=AValue;
+  for i:=0 to ComponentCount-1 do begin
+    Site:=TAnchorDockHostSite(Components[i]);
+    if not (Site is TAnchorDockHostSite) then continue;
+    if (Site.Header<>nil) then begin
+      DisableControlAutoSizing(Site);
+      Site.UpdateHeaderShowing;
+    end;
+  end;
+  EnableAllAutoSizing;
+  OptionsChanged;
+end;
 procedure TAnchorDockMaster.SetScaleOnResize(AValue: boolean);
 begin
   if FScaleOnResize=AValue then Exit;
@@ -2698,6 +2769,7 @@
   FPageClass:=TAnchorDockPage;
   FRestoreLayouts:=TAnchorDockRestoreLayouts.Create;
   FHeaderHighlightFocused:=false;
+  FDockSitesCanBeMinimized:=false;
 end;
 
 destructor TAnchorDockMaster.Destroy;
@@ -3323,6 +3395,7 @@
   HeaderFlatten                    := Settings.HeaderFlatten;
   HeaderFilled                     := Settings.HeaderFilled;
   HeaderHighlightFocused           := Settings.HeaderHighlightFocused;
+  DockSitesCanBeMinimized          := Settings.DockSitesCanBeMinimized;
 end;
 
 procedure TAnchorDockMaster.SaveSettings(Settings: TAnchorDockSettings);
@@ -3343,6 +3416,7 @@
   Settings.HeaderFlatten:=HeaderFlatten;
   Settings.HeaderFilled:=HeaderFilled;
   Settings.HeaderHighlightFocused:=HeaderHighlightFocused;
+  Settings.DockSitesCanBeMinimized:=DockSitesCanBeMinimized;
 end;
 
 function TAnchorDockMaster.SettingsAreEqual(Settings: TAnchorDockSettings
@@ -3680,6 +3754,7 @@
     AControl:=TControl(Sender);
     if not (csDestroying in ComponentState) then begin
       if (not AControl.Visible)
+      and (not FMinimized)
       and (not ((AControl is TAnchorDockHeader)
                or (AControl is TAnchorDockSplitter)
                or (AControl is TAnchorDockHostSite)))
@@ -5165,6 +5240,64 @@
   Result:=Check(Self);
 end;
 
+function CheckOposite(Side:TAnchorKind;var AControl: TControl;out Splitter: TAnchorDockSplitter; out SplitterAnchorKind:TAnchorKind):boolean;
+begin
+  result:=GetDockSplitter(AControl,Side,Splitter);
+  if result then begin
+    if CountAnchoredControls(Splitter,OppositeAnchor[Side])=1 then begin
+      SplitterAnchorKind:=Side;
+      exit;
+    end;
+  end;
+  result:=false
+end;
+
+function FindNearestSpliter(AControl: TControl;out Splitter: TAnchorDockSplitter;out SplitterAnchorKind:TAnchorKind):boolean;
+begin
+  result:=CheckOposite(akTop,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akRight,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akBottom,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akLeft,AControl,Splitter,SplitterAnchorKind);
+end;
+
+procedure TAnchorDockHostSite.MinimizeSite;
+var
+  AControl: TControl;
+  OpositeDockHostSite:TAnchorDockHostSite;
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
+  //SpliterPercentPosition:Single;
+begin
+  debugln(['TAnchorDockHostSite.MinimizeSite ',DbgSName(Self),' SiteType=',dbgs(SiteType)]);
+  AControl:=GetOneControl;
+  if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+    OpositeDockHostSite:=CountAndReturnOnlyOneMinimizedAnchoredControls(Splitter,SplitterAnchorKind);
+    if (Splitter.Enabled and (OpositeDockHostSite=nil)) or FMinimized then begin
+      FMinimized:=not FMinimized;
+      AControl.Visible:=not AControl.Visible;
+      Splitter.Enabled:=AControl.Visible;
+      UpdateHeaderAlign;
+      Splitter.SetBoundsPercentually;
+      {if FMinimized then begin
+        SpliterPercentPosition:=Splitter.FPercentPosition;
+        UpdateHeaderAlign;
+        case SplitterAnchorKind of
+          akTop: Splitter.MoveSplitter(Height-Header.Height);
+          akBottom: Splitter.MoveSplitter(Header.Height-Splitter.Top);
+          akLeft: Splitter.MoveSplitter(Header.Height-Splitter.Left);
+          akRight: Splitter.MoveSplitter(Width-Header.Height);
+        end;
+        Splitter.FPercentPosition:=SpliterPercentPosition;
+      end else begin
+        UpdateHeaderAlign;
+      end;}
+    end;
+  end;
+end;
+
 function TAnchorDockHostSite.CloseSite: boolean;
 var
   AControl: TControl;
@@ -5306,9 +5439,8 @@
     if Parent is TAnchorDockPage then
       TAnchorDockPage(Parent).UpdateDockCaption;
   end;
-
   // do not show close button for mainform
-  Header.CloseButton.Visible:=not IsParentOf(Application.MainForm);
+  Header.CloseButton.Visible:=(not IsParentOf(Application.MainForm))and(Pages=nil);
 end;
 
 procedure TAnchorDockHostSite.GetSiteInfo(Client: TControl;
@@ -5362,9 +5494,27 @@
 end;
 
 procedure TAnchorDockHostSite.UpdateHeaderAlign;
+const
+OppositeAlign: array[TAnchorKind] of TAlign = (
+  alBottom, // akTop,
+  alRight,  // akLeft,
+  alLeft,   // akRight,
+  alTop     // akBottom
+  );
+var
+  NeededHeaderPosition:TADLHeaderPosition;
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
 begin
   if Header=nil then exit;
-  case Header.HeaderPosition of
+  if FMinimized then begin
+    if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+      Header.Align:=OppositeAlign[SplitterAnchorKind];
+    end else
+      NeededHeaderPosition:=Header.HeaderPosition;
+  end else
+    NeededHeaderPosition:=Header.HeaderPosition;
+  case NeededHeaderPosition of
   adlhpAuto:
     if Header.Align in [alLeft,alRight] then begin
       if (ClientHeight>0)
@@ -5390,8 +5540,10 @@
 procedure TAnchorDockHostSite.UpdateHeaderShowing;
 begin
   if Header=nil then exit;
-  if HeaderNeedsShowing then
-    Header.Parent:=Self
+  if HeaderNeedsShowing then begin
+    Header.Parent:=Self;
+    Header.MinimizeButton.Visible:=DockMaster.DockSitesCanBeMinimized;
+  end
   else
     Header.Parent:=nil;
 end;
@@ -5476,6 +5628,7 @@
 constructor TAnchorDockHostSite.CreateNew(AOwner: TComponent; Num: Integer);
 begin
   inherited CreateNew(AOwner,Num);
+  FMinimized:=false;
   Visible:=false;
   FHeaderSide:=akTop;
   FHeader:=DockMaster.HeaderClass.Create(Self);
@@ -5569,6 +5722,13 @@
   end;
 end;
 
+procedure TAnchorDockHeader.MinimizeButtonClick(Sender: TObject);
+begin
+  if Parent is TAnchorDockHostSite then begin
+    TAnchorDockHostSite(Parent).MinimizeSite;
+  end;
+end;
+
 procedure TAnchorDockHeader.HeaderPositionItemClick(Sender: TObject);
 var
   Item: TMenuItem;
@@ -5640,6 +5800,13 @@
       r.Right:=CloseButton.Left-1;
   end;
 
+  if MinimizeButton.IsControlVisible and (MinimizeButton.Parent=Self) then begin
+    if Align in [alLeft,alRight] then
+      r.Top:=MinimizeButton.Top+MinimizeButton.Height+1
+    else
+      r.Right:=MinimizeButton.Left-1;
+  end;
+
   // caption
   if Caption<>'' then begin
     if fFocused and DockMaster.HeaderHighlightFocused and NeedHighlightText then
@@ -5728,7 +5895,14 @@
     end else begin
       PreferredHeight:=Max(NeededHeight,PreferredHeight);
     end;
+  end else begin
+    NeededHeight:=CloseButton.Height;
+    if Align in [alLeft,alRight] then begin
+      PreferredWidth:=Max(NeededHeight,PreferredWidth);
+    end else begin
+      PreferredHeight:=Max(NeededHeight,PreferredHeight);
   end;
+  end;
 end;
 
 procedure TAnchorDockHeader.MouseDown(Button: TMouseButton; Shift: TShiftState;
@@ -5742,11 +5916,15 @@
 procedure TAnchorDockHeader.UpdateHeaderControls;
 begin
   if Align in [alLeft,alRight] then begin
-    if CloseButton<>nil then
+    if CloseButton<>nil then begin
+      MinimizeButton.Align:=alTop;
       CloseButton.Align:=alTop;
+    end;
   end else begin
-    if CloseButton<>nil then
+    if CloseButton<>nil then begin
+      MinimizeButton.Align:=alRight;
       CloseButton.Align:=alRight;
+    end;
   end;
   //debugln(['TAnchorDockHeader.UpdateHeaderControls ',dbgs(Align),' ',dbgs(CloseButton.Align)]);
 end;
@@ -5787,9 +5965,9 @@
 begin
   inherited Create(TheOwner);
   FHeaderPosition:=adlhpAuto;
-  FCloseButton:=TAnchorDockCloseButton.Create(Self);
   BevelOuter:=bvNone;
   BorderWidth:=0;
+  FCloseButton:=TAnchorDockCloseButton.Create(Self);
   with FCloseButton do begin
     Name:='CloseButton';
     Parent:=Self;
@@ -5799,6 +5977,16 @@
     OnClick:=@CloseButtonClick;
     AutoSize:=true;
   end;
+  FMinimizeButton:=TAnchorDockMinimizeButton.Create(Self);
+  with FMinimizeButton do begin
+    Name:='MinimizeButton';
+    Parent:=Self;
+    Flat:=true;
+    ShowHint:=true;
+    Hint:=adrsMinimize;
+    OnClick:=@MinimizeButtonClick;
+    AutoSize:=true;
+  end;
   Align:=alTop;
   AutoSize:=true;
   ShowHint:=true;
@@ -5844,6 +6032,44 @@
   end;
 end;
 
+{ TAnchorDockMinimizeButton }
+
+function TAnchorDockMinimizeButton.GetDrawDetails: TThemedElementDetails;
+
+function WindowPart: TThemedWindow;
+  begin
+    // no check states available
+    Result := twMDIMinButtonNormal;
+    if not IsEnabled then
+      Result := twMDIMinButtonDisabled
+    else
+    if FState in [bsDown, bsExclusive] then
+      Result := twMDIMinButtonPushed
+    else
+    if FState = bsHot then
+      Result := twMDIMinButtonHot
+    else
+      Result := twMDIMinButtonNormal;
+  end;
+
+begin
+  Result := ThemeServices.GetElementDetails(WindowPart);
+end;
+
+procedure TAnchorDockMinimizeButton.CalculatePreferredSize(var PreferredWidth,
+  PreferredHeight: integer; WithThemeSpace: Boolean);
+begin
+  with ThemeServices.GetDetailSize(ThemeServices.GetElementDetails(twMinButtonNormal)) do
+  begin
+    PreferredWidth:=cx;
+    PreferredHeight:=cy;
+    {$IF defined(LCLGtk2) or defined(Carbon)}
+    inc(PreferredWidth,2);
+    inc(PreferredHeight,2);
+    {$ENDIF}
+  end;
+end;
+
 { TAnchorDockManager }
 
 procedure TAnchorDockManager.SetPreferredSiteSizeAsSiteMinimum(
@@ -6505,32 +6731,58 @@
 procedure TAnchorDockSplitter.SetBoundsPercentually;
 var
   NewLeft, NewTop: Integer;
+  AControl: TControl;
+  SplitterAnchorKind:TAnchorKind;
 begin
-  if ResizeAnchor in [akLeft,akRight] then
-  begin
-    if DockParentClientSize.cx> 0 then
+  if Enabled then begin
+    if ResizeAnchor in [akLeft,akRight] then
     begin
-      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
-        NewLeft := Round(FPercentPosition*Parent.ClientWidth)
-      else
-        NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
-      NewTop := Top;
-      SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      if DockParentClientSize.cx> 0 then
+      begin
+        if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+          NewLeft := Round(FPercentPosition*Parent.ClientWidth)
+        else
+          NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
+        NewTop := Top;
+        SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      end;
+    end else
+    begin
+      if DockParentClientSize.cy> 0 then
+      begin
+        NewLeft := Left;
+        if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+          NewTop := Round(FPercentPosition*Parent.ClientHeight)
+        else
+          NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+        SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      end;
     end;
-  end else
-  begin
-    if DockParentClientSize.cy> 0 then
-    begin
-      NewLeft := Left;
-      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
-        NewTop := Round(FPercentPosition*Parent.ClientHeight)
-      else
-        NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+    if FPercentPosition < 0 then
+      UpdatePercentPosition;
+  end else begin
+    SplitterAnchorKind:=akTop;
+    AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);
+    if AControl=nil then begin SplitterAnchorKind:=akRight;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+    if AControl=nil then begin SplitterAnchorKind:=akBottom;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+    if AControl=nil then begin SplitterAnchorKind:=akLeft;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+
+    if AControl is TAnchorDockHostSite then begin
+      (AControl as TAnchorDockHostSite).UpdateHeaderAlign;
+      NewTop := (AControl as TAnchorDockHostSite).Header.Left;
+      NewTop := (AControl as TAnchorDockHostSite).Header.Height;
+      NewLeft := left;
+      NewTop := top;
+      (AControl as TAnchorDockHostSite).UpdateHeaderAlign;
+      case SplitterAnchorKind of
+        akTop: NewTop := AControl.Top+(AControl as TAnchorDockHostSite).Header.Height;
+        akBottom: NewTop := AControl.Top+AControl.Height-(AControl as TAnchorDockHostSite).Header.Height-Height;
+        akLeft: NewLeft := AControl.Left+(AControl as TAnchorDockHostSite).Header.Width;
+        akRight: NewLeft := AControl.Left+AControl.Width-(AControl as TAnchorDockHostSite).Header.Width-Width;
+      end;
       SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
     end;
   end;
-  if FPercentPosition < 0 then
-    UpdatePercentPosition;
 end;
 
 function TAnchorDockSplitter.SideAnchoredControlCount(Side: TAnchorKind): integer;
Index: components/anchordocking/anchordockoptionsdlg.lfm
===================================================================
--- components/anchordocking/anchordockoptionsdlg.lfm	(revision 59377)
+++ components/anchordocking/anchordockoptionsdlg.lfm	(working copy)
@@ -1,11 +1,13 @@
 object AnchorDockOptionsFrame: TAnchorDockOptionsFrame
   Left = 0
-  Height = 482
+  Height = 567
   Top = 0
-  Width = 416
-  ClientHeight = 482
-  ClientWidth = 416
+  Width = 490
+  ClientHeight = 567
+  ClientWidth = 490
+  DesignTimePPI = 113
   OnClick = FrameClick
+  ParentFont = False
   TabOrder = 0
   DesignLeft = 513
   DesignTop = 189
@@ -12,14 +14,15 @@
   object DragThresholdLabel: TLabel
     AnchorSideLeft.Control = Owner
     AnchorSideTop.Control = Owner
-    Left = 10
-    Height = 13
-    Top = 10
-    Width = 111
-    BorderSpacing.Left = 10
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 12
+    Width = 122
+    BorderSpacing.Left = 12
+    BorderSpacing.Top = 12
     Caption = 'DragThresholdLabel'
     ParentColor = False
+    ParentFont = False
   end
   object DragThresholdTrackBar: TTrackBar
     AnchorSideLeft.Control = DragThresholdLabel
@@ -27,15 +30,16 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = Owner
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 46
-    Top = 23
-    Width = 396
+    Left = 12
+    Height = 54
+    Top = 31
+    Width = 466
     Max = 20
     OnChange = DragThresholdTrackBarChange
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Right = 10
+    BorderSpacing.Right = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 1
@@ -46,12 +50,13 @@
     AnchorSideTop.Control = DragThresholdLabel
     AnchorSideTop.Side = asrCenter
     AnchorSideRight.Control = Owner
-    Left = 127
-    Height = 23
-    Top = 5
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 141
+    Height = 27
+    Top = 8
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 20
+    ParentFont = False
     TabOrder = 0
     Visible = False
   end
@@ -59,13 +64,14 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = DragThresholdTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 79
-    Width = 103
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 97
+    Width = 112
+    BorderSpacing.Top = 12
     Caption = 'SplitterWidthLabel'
     ParentColor = False
+    ParentFont = False
   end
   object SplitterWidthTrackBar: TTrackBar
     AnchorSideLeft.Control = DragThresholdTrackBar
@@ -73,14 +79,15 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 46
-    Top = 92
-    Width = 396
+    Left = 12
+    Height = 54
+    Top = 116
+    Width = 466
     Min = 1
     OnChange = SplitterWidthTrackBarChange
     Position = 1
     Anchors = [akTop, akLeft, akRight]
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 3
@@ -89,12 +96,13 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = SplitterWidthTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 24
-    Top = 142
-    Width = 160
-    BorderSpacing.Top = 4
+    Left = 12
+    Height = 23
+    Top = 175
+    Width = 169
+    BorderSpacing.Top = 5
     Caption = 'ScaleOnResizeCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 4
@@ -103,12 +111,13 @@
     AnchorSideLeft.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 24
-    Top = 166
-    Width = 149
+    Left = 12
+    Height = 23
+    Top = 198
+    Width = 160
     Caption = 'ShowHeaderCheckBox'
     OnChange = ShowHeaderCheckBoxChange
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 5
@@ -117,12 +126,13 @@
     AnchorSideLeft.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Control = ShowHeaderCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 190
-    Width = 191
-    BorderSpacing.Left = 15
+    Left = 30
+    Height = 23
+    Top = 221
+    Width = 208
+    BorderSpacing.Left = 18
     Caption = 'ShowHeaderCaptionCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 6
@@ -131,11 +141,12 @@
     AnchorSideLeft.Control = ShowHeaderCaptionCheckBox
     AnchorSideTop.Control = ShowHeaderCaptionCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 214
-    Width = 249
+    Left = 30
+    Height = 23
+    Top = 244
+    Width = 272
     Caption = 'HideHeaderCaptionForFloatingCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 7
@@ -147,15 +158,16 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = Owner
     AnchorSideRight.Side = asrBottom
-    Left = 122
+    Left = 136
     Height = 27
-    Top = 286
-    Width = 284
+    Top = 313
+    Width = 342
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 6
-    BorderSpacing.Right = 10
-    ItemHeight = 0
+    BorderSpacing.Left = 7
+    BorderSpacing.Right = 12
+    ItemHeight = 19
     OnDrawItem = HeaderStyleComboBoxDrawItem
+    ParentFont = False
     Style = csDropDownList
     TabOrder = 10
   end
@@ -163,23 +175,25 @@
     AnchorSideLeft.Control = ShowHeaderCheckBox
     AnchorSideTop.Control = HeaderStyleComboBox
     AnchorSideTop.Side = asrCenter
-    Left = 20
-    Height = 13
-    Top = 293
-    Width = 96
-    BorderSpacing.Left = 10
+    Left = 24
+    Height = 19
+    Top = 317
+    Width = 105
+    BorderSpacing.Left = 12
     Caption = 'HeaderStyleLabel'
     ParentColor = False
+    ParentFont = False
   end
   object FlattenHeadersCheckBox: TCheckBox
     AnchorSideLeft.Control = HideHeaderCaptionForFloatingCheckBox
     AnchorSideTop.Control = HideHeaderCaptionForFloatingCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 238
-    Width = 164
+    Left = 30
+    Height = 23
+    Top = 267
+    Width = 175
     Caption = 'FlattenHeadersCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 8
@@ -188,11 +202,12 @@
     AnchorSideLeft.Control = FlattenHeadersCheckBox
     AnchorSideTop.Control = FlattenHeadersCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 262
-    Width = 154
+    Left = 30
+    Height = 23
+    Top = 290
+    Width = 164
     Caption = 'FilledHeadersCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 9
@@ -201,11 +216,12 @@
     AnchorSideLeft.Control = FilledHeadersCheckBox
     AnchorSideTop.Control = HeaderStyleComboBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 313
-    Width = 175
+    Left = 30
+    Height = 23
+    Top = 340
+    Width = 189
     Caption = 'HighlightFocusedCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 11
@@ -215,13 +231,14 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = SplitterWidthLabel
     AnchorSideTop.Side = asrCenter
-    Left = 119
-    Height = 23
-    Top = 74
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 131
+    Height = 27
+    Top = 93
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 10
     MinValue = 1
+    ParentFont = False
     TabOrder = 2
     Value = 1
     Visible = False
@@ -228,15 +245,16 @@
   end
   object HeaderAlignTopLabel: TLabel
     AnchorSideLeft.Control = DragThresholdLabel
-    AnchorSideTop.Control = HighlightFocusedCheckBox
+    AnchorSideTop.Control = DockSitesCanBeMinimized
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 347
-    Width = 117
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 398
+    Width = 130
+    BorderSpacing.Top = 12
     Caption = 'HeaderAlignTopLabel'
     ParentColor = False
+    ParentFont = False
   end
   object HeaderAlignTopTrackBar: TTrackBar
     AnchorSideLeft.Control = Owner
@@ -244,10 +262,10 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 47
-    Top = 360
-    Width = 396
+    Left = 12
+    Height = 55
+    Top = 417
+    Width = 466
     Frequency = 10
     Max = 150
     OnChange = HeaderAlignTopTrackBarChange
@@ -254,7 +272,8 @@
     PageSize = 10
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 10
+    BorderSpacing.Left = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 13
@@ -264,12 +283,13 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = HeaderAlignTopLabel
     AnchorSideTop.Side = asrCenter
-    Left = 133
-    Height = 23
-    Top = 342
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 149
+    Height = 27
+    Top = 394
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 150
+    ParentFont = False
     TabOrder = 12
     Visible = False
   end
@@ -277,13 +297,14 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = HeaderAlignTopTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 417
-    Width = 120
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 484
+    Width = 130
+    BorderSpacing.Top = 12
     Caption = 'HeaderAlignLeftLabel'
     ParentColor = False
+    ParentFont = False
   end
   object HeaderAlignLeftTrackBar: TTrackBar
     AnchorSideLeft.Control = Owner
@@ -291,10 +312,10 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 47
-    Top = 430
-    Width = 396
+    Left = 12
+    Height = 55
+    Top = 503
+    Width = 466
     Frequency = 10
     Max = 200
     OnChange = HeaderAlignLeftTrackBarChange
@@ -301,7 +322,8 @@
     PageSize = 10
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 10
+    BorderSpacing.Left = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 15
@@ -311,13 +333,28 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = HeaderAlignLeftLabel
     AnchorSideTop.Side = asrCenter
-    Left = 136
-    Height = 23
-    Top = 412
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 149
+    Height = 27
+    Top = 480
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 200
+    ParentFont = False
     TabOrder = 14
     Visible = False
   end
+  object DockSitesCanBeMinimized: TCheckBox
+    AnchorSideLeft.Control = FilledHeadersCheckBox
+    AnchorSideTop.Control = HighlightFocusedCheckBox
+    AnchorSideTop.Side = asrBottom
+    Left = 30
+    Height = 23
+    Top = 363
+    Width = 185
+    Caption = 'DockSitesCanBeMinimized'
+    ParentFont = False
+    ParentShowHint = False
+    ShowHint = True
+    TabOrder = 16
+  end
 end
Index: components/anchordocking/anchordockoptionsdlg.pas
===================================================================
--- components/anchordocking/anchordockoptionsdlg.pas	(revision 59377)
+++ components/anchordocking/anchordockoptionsdlg.pas	(working copy)
@@ -37,6 +37,7 @@
     HeaderStyleLabel: TLabel;
     HideHeaderCaptionForFloatingCheckBox: TCheckBox;
     HighlightFocusedCheckBox: TCheckBox;
+    DockSitesCanBeMinimized: TCheckBox;
     ScaleOnResizeCheckBox: TCheckBox;
     ShowHeaderCaptionCheckBox: TCheckBox;
     ShowHeaderCheckBox: TCheckBox;
@@ -299,6 +300,7 @@
   HeaderStyleLabel.Enabled:=HasHeaders;
   HeaderStyleComboBox.Enabled:=HasHeaders;
   HighlightFocusedCheckBox.Enabled:=HasHeaders;
+  DockSitesCanBeMinimized.Enabled:=HasHeaders;
 end;
 
 constructor TAnchorDockOptionsFrame.Create(TheOwner: TComponent);
@@ -356,6 +358,7 @@
   TheSettings.HeaderFilled:=FilledHeadersCheckBox.Checked;
   TheSettings.HeaderStyle:=TADHeaderStyle(HeaderStyleComboBox.ItemIndex);
   TheSettings.HeaderHighlightFocused:=HighlightFocusedCheckBox.Checked;
+  TheSettings.DockSitesCanBeMinimized:=DockSitesCanBeMinimized.Checked;
 end;
 
 procedure TAnchorDockOptionsFrame.LoadFromSettings(
@@ -429,6 +432,10 @@
   HighlightFocusedCheckBox.Checked:=TheSettings.HeaderHighlightFocused;
   HighlightFocusedCheckBox.Caption:=adrsHighlightFocused;
   HighlightFocusedCheckBox.Hint:=adrsHighlightFocusedHint;
+
+  DockSitesCanBeMinimized.Checked:=TheSettings.DockSitesCanBeMinimized;
+  DockSitesCanBeMinimized.Caption:=adrsDockSitesCanBeMinimized;
+  DockSitesCanBeMinimized.Hint:=adrsDockSitesCanBeMinimizedHint;
 end;
 
 end.
Index: components/anchordocking/anchordockstr.pas
===================================================================
--- components/anchordocking/anchordockstr.pas	(revision 59377)
+++ components/anchordocking/anchordockstr.pas	(working copy)
@@ -8,6 +8,7 @@
 
 resourcestring
   adrsClose = 'Close';
+  adrsMinimize = 'Minimize';
   adrsQuit = 'Quit %s';
   adrsTabPosition = 'Tab position';
   adrsMovePageRight = 'Move page right';
@@ -82,6 +83,8 @@
   adrsFilledHeadersHint = 'Fill headers of docked controls';
   adrsHighlightFocused = 'Highlight focused';
   adrsHighlightFocusedHint = 'Highlight header of focused docked control';
+  adrsDockSitesCanBeMinimized = 'Dock sites can be minimized';
+  adrsDockSitesCanBeMinimizedHint = 'Dock sites can be minimized';
 
 implementation
 

Andrey Zubarev

2018-10-31 22:37

reporter   ~0111717

anchordocking_minimize_docksite3.patch can be applied for tests

Andrey Zubarev

2018-11-04 13:22

reporter  

anchordocking_minimize_docksite4.patch (39,872 bytes)   
Index: components/anchordocking/anchordocking.pas
===================================================================
--- components/anchordocking/anchordocking.pas	(revision 59428)
+++ components/anchordocking/anchordocking.pas	(working copy)
@@ -123,6 +123,14 @@
            PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
   end;
 
+  TAnchorDockMinimizeButton = class(TCustomSpeedButton)
+  protected
+    function GetDrawDetails: TThemedElementDetails; override;
+    procedure CalculatePreferredSize(var PreferredWidth,
+           PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
+  end;
+
+
   { TAnchorDockHeader
     The panel of a TAnchorDockHostSite containing the close button and the
     caption when the form is docked. The header can be shown at any of the four
@@ -133,9 +141,11 @@
   TAnchorDockHeader = class(TCustomPanel)
   private
     FCloseButton: TCustomSpeedButton;
+    FMinimizeButton: TCustomSpeedButton;
     FHeaderPosition: TADLHeaderPosition;
     fFocused:Boolean;
     procedure CloseButtonClick(Sender: TObject);
+    procedure MinimizeButtonClick(Sender: TObject);
     procedure HeaderPositionItemClick(Sender: TObject);
     procedure UndockButtonClick(Sender: TObject);
     procedure MergeButtonClick(Sender: TObject);
@@ -154,6 +164,7 @@
   public
     constructor Create(TheOwner: TComponent); override;
     property CloseButton: TCustomSpeedButton read FCloseButton;
+    property MinimizeButton: TCustomSpeedButton read FMinimizeButton;
     property HeaderPosition: TADLHeaderPosition read FHeaderPosition write SetHeaderPosition;
     property BevelOuter default bvNone;
   end;
@@ -262,7 +273,10 @@
     FPages: TAnchorDockPageControl;
     FSiteType: TAnchorDockHostSiteType;
     FBoundSplitter: TAnchorDockSplitter;
-    fUpdateLayout: integer;
+    fUpdateLayout: Integer;
+    FMinimized: Boolean;
+    fMinimization: Boolean;
+    FMinimizedControl: TControl;
     procedure SetHeaderSide(const AValue: TAnchorKind);
   protected
     procedure DoEnter; override;
@@ -319,6 +333,8 @@
     destructor Destroy; override;
     function CloseQuery: boolean; override;
     function CloseSite: boolean; virtual;
+    procedure MinimizeSite; virtual;
+    procedure AsyncMinimizeSite(Data: PtrInt);
     procedure RemoveControl(AControl: TControl); override;
     procedure InsertControl(AControl: TControl; Index: integer); override;
     procedure GetSiteInfo(Client: TControl; var InfluenceRect: TRect;
@@ -431,6 +447,7 @@
     FShowHeader: boolean;
     FShowHeaderCaption: boolean;
     FSplitterWidth: integer;
+    FDockSitecCanBeMinimized: boolean;
     procedure SetAllowDragging(AValue: boolean);
     procedure SetDockOutsideMargin(AValue: integer);
     procedure SetDockParentMargin(AValue: integer);
@@ -448,6 +465,7 @@
     procedure SetHeaderFlatten(AValue: boolean);
     procedure SetHeaderFilled(AValue: boolean);
     procedure SetHeaderHighlightFocused(AValue: boolean);
+    procedure SetDockSitecCanBeMinimized(AValue: boolean);
   public
     property DragTreshold: integer read FDragTreshold write SetDragTreshold;
     property DockOutsideMargin: integer read FDockOutsideMargin write SetDockOutsideMargin;
@@ -466,6 +484,7 @@
     property HeaderFlatten: boolean read FHeaderFlatten write SetHeaderFlatten;
     property HeaderFilled: boolean read FHeaderFilled write SetHeaderFilled;
     property HeaderHighlightFocused: boolean read FHeaderHighlightFocused write SetHeaderHighlightFocused;
+    property DockSitesCanBeMinimized: boolean read FDockSitecCanBeMinimized write SetDockSitecCanBeMinimized;
     procedure IncreaseChangeStamp; inline;
     property ChangeStamp: integer read FChangeStamp;
     procedure LoadFromConfig(Config: TConfigStorage); overload;
@@ -502,6 +521,7 @@
     FHeaderFlatten: boolean;
     FHeaderFilled: boolean;
     FHeaderHighlightFocused: boolean;
+    FDockSitesCanBeMinimized: boolean;
     FIdleConnected: Boolean;
     FManagerClass: TAnchorDockManagerClass;
     FOnCreateControl: TADCreateControlEvent;
@@ -561,6 +581,7 @@
     procedure SetHeaderFlatten(AValue: boolean);
     procedure SetHeaderFilled(AValue: boolean);
     procedure SetHeaderHighlightFocused(AValue: boolean);
+    procedure SetDockSitesCanBeMinimized(AValue: boolean);
 
     procedure SetShowMenuItemShowHeader(AValue: boolean);
     procedure SetupSite(Site: TWinControl; ANode: TAnchorDockLayoutTreeNode;
@@ -680,6 +701,7 @@
     property HeaderFlatten: boolean read FHeaderFlatten write SetHeaderFlatten default true;
     property HeaderFilled: boolean read FHeaderFilled write SetHeaderFilled default true;
     property HeaderHighlightFocused: boolean read FHeaderHighlightFocused write SetHeaderHighlightFocused default false;
+    property DockSitesCanBeMinimized: boolean read FDockSitesCanBeMinimized write SetDockSitesCanBeMinimized default false;
 
     property SplitterWidth: integer read FSplitterWidth write SetSplitterWidth default 4;
     property ScaleOnResize: boolean read FScaleOnResize write SetScaleOnResize default true; // scale children when resizing a site
@@ -970,6 +992,27 @@
   end;
 end;
 
+function CountAndReturnOnlyOneMinimizedAnchoredControls(Control: TControl; Side: TAnchorKind): TAnchorDockHostSite;
+var
+  i,Counter: Integer;
+  Neighbour: TControl;
+begin
+  Counter:=0;
+  for i:=0 to Control.AnchoredControlCount-1 do begin
+    Neighbour:=Control.AnchoredControls[i];
+    if Neighbour.Visible then
+    if Neighbour is TAnchorDockHostSite then
+    if (OppositeAnchor[Side] in Neighbour.Anchors)
+    and (Neighbour.AnchorSide[OppositeAnchor[Side]].Control=Control) then begin
+      inc(Counter);
+      result:=TAnchorDockHostSite(Neighbour);
+    end;
+  end;
+  if (Counter=1)and(result is TAnchorDockHostSite)and((result as TAnchorDockHostSite).FMinimized) then
+  else
+    result:=Nil;
+end;
+
 function NeighbourCanBeShrinked(EnlargeControl, Neighbour: TControl;
   Side: TAnchorKind): boolean;
 { returns true if Neighbour can be shrinked on the opposite side of Side
@@ -1361,6 +1404,13 @@
   IncreaseChangeStamp;
 end;
 
+procedure TAnchorDockSettings.SetDockSitecCanBeMinimized(AValue: boolean);
+begin
+  if FDockSitecCanBeMinimized=AValue then Exit;
+  FDockSitecCanBeMinimized:=AValue;
+  IncreaseChangeStamp;
+end;
+
 procedure TAnchorDockSettings.Assign(Source: TAnchorDockSettings);
 begin
   FAllowDragging := Source.FAllowDragging;
@@ -1381,6 +1431,7 @@
   FShowHeaderCaption := Source.FShowHeaderCaption;
   FSplitterWidth := Source.FSplitterWidth;
   FHeaderHighlightFocused:=Source.FHeaderHighlightFocused;
+  FDockSitecCanBeMinimized:=Source.FDockSitecCanBeMinimized;
 end;
 
 procedure TAnchorDockSettings.IncreaseChangeStamp;
@@ -1407,6 +1458,7 @@
   HeaderFlatten:=Config.GetValue('HeaderFlatten',true);
   HeaderFilled:=Config.GetValue('HeaderFilled',true);
   HeaderHighlightFocused:=Config.GetValue('HeaderHighlightFocused',False);
+  DockSitesCanBeMinimized:=Config.GetValue('DockSitecCanBeMinimized',False);
   Config.UndoAppendBasePath;
 end;
 
@@ -1429,6 +1481,7 @@
   Config.SetDeleteValue(Path+'HeaderFlatten',HeaderFlatten,true);
   Config.SetDeleteValue(Path+'HeaderFilled',HeaderFilled,true);
   Config.SetDeleteValue(Path+'HeaderHighlightFocused',HeaderHighlightFocused,False);
+  Config.SetDeleteValue(Path+'DockSitecCanBeMinimized',DockSitesCanBeMinimized,False);
 end;
 
 procedure TAnchorDockSettings.SaveToConfig(Config: TConfigStorage);
@@ -1450,6 +1503,7 @@
   Config.SetDeleteValue('HeaderFlatten',HeaderFlatten,true);
   Config.SetDeleteValue('HeaderFilled',HeaderFilled,true);
   Config.SetDeleteValue('HeaderHighlightFocused',HeaderHighlightFocused,False);
+  Config.SetDeleteValue('DockSitecCanBeMinimized',DockSitesCanBeMinimized,False);
   Config.UndoAppendBasePath;
 end;
 
@@ -1472,6 +1526,7 @@
       and (HeaderFlatten=Settings.HeaderFlatten)
       and (HeaderFilled=Settings.HeaderFilled)
       and (HeaderHighlightFocused=Settings.HeaderHighlightFocused)
+      and (DockSitesCanBeMinimized=Settings.DockSitesCanBeMinimized)
       ;
 end;
 
@@ -1494,6 +1549,7 @@
   HeaderFlatten:=Config.GetValue(Path+'HeaderFlatten',true);
   HeaderFilled:=Config.GetValue(Path+'HeaderFilled',true);
   HeaderHighlightFocused:=Config.GetValue(Path+'HeaderHighlightFocused',False);
+  DockSitesCanBeMinimized:=Config.GetValue(Path+'DockSitecCanBeMinimized',False);
 end;
 
 { TAnchorDockMaster }
@@ -2193,7 +2249,7 @@
       try
         SetupSite(Site,ANode,AParent);
         Site.FSiteType:=adhstPages;
-        Site.Header.Parent:=nil;
+        //Site.Header.Parent:=nil;
         if Site.Pages=nil then
           Site.CreatePages;
         for i:=0 to ANode.Count-1 do begin
@@ -2514,6 +2570,24 @@
   InvalidateHeaders;
 end;
 
+procedure TAnchorDockMaster.SetDockSitesCanBeMinimized(AValue: boolean);
+var
+  i:integer;
+  Site: TAnchorDockHostSite;
+begin
+  if FDockSitesCanBeMinimized=AValue then Exit;
+  FDockSitesCanBeMinimized:=AValue;
+  for i:=0 to ComponentCount-1 do begin
+    Site:=TAnchorDockHostSite(Components[i]);
+    if not (Site is TAnchorDockHostSite) then continue;
+    if (Site.Header<>nil) then begin
+      DisableControlAutoSizing(Site);
+      Site.UpdateHeaderShowing;
+    end;
+  end;
+  EnableAllAutoSizing;
+  OptionsChanged;
+end;
 procedure TAnchorDockMaster.SetScaleOnResize(AValue: boolean);
 begin
   if FScaleOnResize=AValue then Exit;
@@ -2698,14 +2772,13 @@
   FPageClass:=TAnchorDockPage;
   FRestoreLayouts:=TAnchorDockRestoreLayouts.Create;
   FHeaderHighlightFocused:=false;
+  FDockSitesCanBeMinimized:=false;
 end;
 
 destructor TAnchorDockMaster.Destroy;
 var
   AControl: TControl;
-  {$IFDEF VerboseAnchorDocking}
-  i: Integer;
-  {$ENDIF}
+  i, j: Integer;
 begin
   QueueSimplify:=false;
   FreeAndNil(FRestoreLayouts);
@@ -2727,6 +2800,12 @@
     debugln(['TAnchorDockMaster.Destroy ',i,'/',ComponentCount,' ',DbgSName(Components[i])]);
   end;
   {$ENDIF}
+  for i:=0 to ComponentCount-1 do begin
+    for j:=0 to ComponentCount-1 do begin
+      if i<>j then
+        TControl(Components[i]).RemoveAllHandlersOfObject(TControl(Components[j]));
+  end;
+  end;
   inherited Destroy;
 end;
 
@@ -3323,6 +3402,7 @@
   HeaderFlatten                    := Settings.HeaderFlatten;
   HeaderFilled                     := Settings.HeaderFilled;
   HeaderHighlightFocused           := Settings.HeaderHighlightFocused;
+  DockSitesCanBeMinimized          := Settings.DockSitesCanBeMinimized;
 end;
 
 procedure TAnchorDockMaster.SaveSettings(Settings: TAnchorDockSettings);
@@ -3343,6 +3423,7 @@
   Settings.HeaderFlatten:=HeaderFlatten;
   Settings.HeaderFilled:=HeaderFilled;
   Settings.HeaderHighlightFocused:=HeaderHighlightFocused;
+  Settings.DockSitesCanBeMinimized:=DockSitesCanBeMinimized;
 end;
 
 function TAnchorDockMaster.SettingsAreEqual(Settings: TAnchorDockSettings
@@ -3680,6 +3761,7 @@
     AControl:=TControl(Sender);
     if not (csDestroying in ComponentState) then begin
       if (not AControl.Visible)
+      and (not FMinimized)
       and (not ((AControl is TAnchorDockHeader)
                or (AControl is TAnchorDockSplitter)
                or (AControl is TAnchorDockHostSite)))
@@ -4119,6 +4201,8 @@
 end;
 
 procedure TAnchorDockHostSite.FreePages;
+var
+  i:Integer;
 begin
   FreeAndNil(FPages);
 end;
@@ -4233,6 +4317,14 @@
         akRight: NewBounds.Right:=AControl.Left+AControl.Width;
         akBottom: NewBounds.Bottom:=AControl.Top+AControl.Height;
         end;
+        if (sibling is TAnchorDockHostSite) then
+        if (sibling as TAnchorDockHostSite).FMinimized then begin
+          (sibling as TAnchorDockHostSite).FMinimized:=false;
+          (sibling as TAnchorDockHostSite).FMinimizedControl.Parent:=(sibling as TAnchorDockHostSite);
+          (sibling as TAnchorDockHostSite).FMinimizedControl.Visible:=True;
+          (sibling as TAnchorDockHostSite).FMinimizedControl:=nil;
+          (sibling as TAnchorDockHostSite).UpdateHeaderAlign;
+        end;
         Sibling.BoundsRect:=NewBounds;
       end;
     end;
@@ -4306,6 +4398,13 @@
       FSiteType:=adhstOneControl;
       OnlySiteLeft.Align:=alClient;
       Header.Parent:=Self;
+      if OnlySiteLeft.FMinimized then begin
+        OnlySiteLeft.FMinimized:=false;
+        OnlySiteLeft.FMinimizedControl.Parent:=OnlySiteLeft;
+        OnlySiteLeft.FMinimizedControl.Visible:=True;
+        OnlySiteLeft.FMinimizedControl:=nil;
+        UpdateHeaderAlign;
+      end;
       UpdateHeaderAlign;
 
       //debugln(['TAnchorDockHostSite.RemoveControlFromLayout.ConvertToOneControlType AFTER CONVERT "',Caption,'" to onecontrol OnlySiteLeft="',OnlySiteLeft.Caption,'"']);
@@ -4465,7 +4564,7 @@
     debugln(['TAnchorDockHostSite.Simplify ',DbgSName(Self),' ',DbgSName(AControl)]);
     if AControl is TAnchorDockHostSite then
       SimplifyOneControl
-    else if (AControl=nil) or (csDestroying in AControl.ComponentState) then
+    else if ((AControl=nil) or (csDestroying in AControl.ComponentState)) then
       DockMaster.NeedFree(Self);
   end;
 end;
@@ -4577,7 +4676,8 @@
     Result:=Controls[i];
     if Result.Owner<>Self then exit;
   end;
-  Result:=nil;
+  result:=FMinimizedControl;
+  //Result:=nil;
 end;
 
 function TAnchorDockHostSite.GetSiteCount: integer;
@@ -5165,6 +5265,71 @@
   Result:=Check(Self);
 end;
 
+function CheckOposite(Side:TAnchorKind;var AControl: TControl;out Splitter: TAnchorDockSplitter; out SplitterAnchorKind:TAnchorKind):boolean;
+begin
+  result:=GetDockSplitter(AControl,Side,Splitter);
+  if result then begin
+    if CountAnchoredControls(Splitter,OppositeAnchor[Side])=1 then begin
+      SplitterAnchorKind:=Side;
+      exit;
+    end;
+  end;
+  result:=false
+end;
+
+function FindNearestSpliter(AControl: TControl;out Splitter: TAnchorDockSplitter;out SplitterAnchorKind:TAnchorKind):boolean;
+begin
+  result:=CheckOposite(akTop,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akRight,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akBottom,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akLeft,AControl,Splitter,SplitterAnchorKind);
+end;
+
+procedure TAnchorDockHostSite.MinimizeSite;
+begin
+  Application.QueueAsyncCall(@AsyncMinimizeSite,0);
+  //AsyncMinimizeSite,0
+end;
+
+procedure TAnchorDockHostSite.AsyncMinimizeSite(Data: PtrInt);
+var
+  AControl: TControl;
+  OpositeDockHostSite:TAnchorDockHostSite;
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
+  //SpliterPercentPosition:Single;
+begin
+  fMinimization:=true;
+  debugln(['TAnchorDockHostSite.MinimizeSite ',DbgSName(Self),' SiteType=',dbgs(SiteType)]);
+  if FMinimized then
+    AControl:=FMinimizedControl
+  else
+    AControl:=GetOneControl;
+  if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+    OpositeDockHostSite:=CountAndReturnOnlyOneMinimizedAnchoredControls(Splitter,SplitterAnchorKind);
+    if (Splitter.Enabled and (OpositeDockHostSite=nil)) or FMinimized then begin
+      FMinimized:=not FMinimized;
+      if FMinimized then begin
+        FMinimizedControl:=AControl;
+        AControl.Visible:=False;
+        AControl.Parent:=nil;
+      end else begin
+        AControl.Parent:=self;
+        AControl.Visible:=True;
+        FMinimizedControl:=nil;
+      end;
+      Splitter.Enabled:=AControl.Visible;
+      UpdateHeaderAlign;
+      Splitter.SetBoundsPercentually;
+    end;
+  end;
+  fMinimization:=false;
+end;
+
+
 function TAnchorDockHostSite.CloseSite: boolean;
 var
   AControl: TControl;
@@ -5306,9 +5471,8 @@
     if Parent is TAnchorDockPage then
       TAnchorDockPage(Parent).UpdateDockCaption;
   end;
-
   // do not show close button for mainform
-  Header.CloseButton.Visible:=not IsParentOf(Application.MainForm);
+  Header.CloseButton.Visible:=(not IsParentOf(Application.MainForm))and(Pages=nil);
 end;
 
 procedure TAnchorDockHostSite.GetSiteInfo(Client: TControl;
@@ -5362,9 +5526,33 @@
 end;
 
 procedure TAnchorDockHostSite.UpdateHeaderAlign;
+const
+OppositeAlign: array[TAnchorKind] of TAlign = (
+  alBottom, // akTop,
+  alRight,  // akLeft,
+  alLeft,   // akRight,
+  alTop     // akBottom
+  );
+OppositeAnchorKindAlign: array[TAnchorKind] of TADLHeaderPosition = (
+  adlhpBottom, // akTop,
+  adlhpRight,  // akLeft,
+  adlhpLeft,   // akRight,
+  adlhpTop     // akBottom
+  );
+var
+  NeededHeaderPosition:TADLHeaderPosition;
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
 begin
   if Header=nil then exit;
-  case Header.HeaderPosition of
+  if FMinimized then begin
+    if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+      NeededHeaderPosition:=OppositeAnchorKindAlign[SplitterAnchorKind];
+    end else
+      NeededHeaderPosition:=Header.HeaderPosition;
+  end else
+    NeededHeaderPosition:=Header.HeaderPosition;
+  case NeededHeaderPosition of
   adlhpAuto:
     if Header.Align in [alLeft,alRight] then begin
       if (ClientHeight>0)
@@ -5390,8 +5578,11 @@
 procedure TAnchorDockHostSite.UpdateHeaderShowing;
 begin
   if Header=nil then exit;
-  if HeaderNeedsShowing then
-    Header.Parent:=Self
+  if HeaderNeedsShowing then begin
+    Header.Parent:=Self;
+    Header.MinimizeButton.Visible:=DockMaster.DockSitesCanBeMinimized;
+    Header.MinimizeButton.Parent:=Header;
+  end
   else
     Header.Parent:=nil;
 end;
@@ -5476,6 +5667,9 @@
 constructor TAnchorDockHostSite.CreateNew(AOwner: TComponent; Num: Integer);
 begin
   inherited CreateNew(AOwner,Num);
+  FMinimized:=false;
+  fMinimization:=false;
+  FMinimizedControl:=Nil;
   Visible:=false;
   FHeaderSide:=akTop;
   FHeader:=DockMaster.HeaderClass.Create(Self);
@@ -5490,13 +5684,13 @@
 end;
 
 destructor TAnchorDockHostSite.Destroy;
-//var i: Integer;
+var i: Integer;
 begin
-  //debugln(['TAnchorDockHostSite.Destroy ',DbgSName(Self),' Caption="',Caption,'" Self=',dbgs(Pointer(Self)),' ComponentCount=',ComponentCount,' ControlCount=',ControlCount]);
-  {for i:=0 to ComponentCount-1 do
+  debugln(['TAnchorDockHostSite.Destroy ',DbgSName(Self),' Caption="',Caption,'" Self=',dbgs(Pointer(Self)),' ComponentCount=',ComponentCount,' ControlCount=',ControlCount]);
+  for i:=0 to ComponentCount-1 do
     debugln(['TAnchorDockHostSite.Destroy Component ',i,'/',ComponentCount,' ',DbgSName(Components[i])]);
   for i:=0 to ControlCount-1 do
-    debugln(['TAnchorDockHostSite.Destroy Control ',i,'/',ControlCount,' ',DbgSName(Controls[i])]);}
+    debugln(['TAnchorDockHostSite.Destroy Control ',i,'/',ControlCount,' ',DbgSName(Controls[i])]);
   FreePages;
   inherited Destroy;
 end;
@@ -5569,6 +5763,13 @@
   end;
 end;
 
+procedure TAnchorDockHeader.MinimizeButtonClick(Sender: TObject);
+begin
+  if Parent is TAnchorDockHostSite then begin
+    TAnchorDockHostSite(Parent).MinimizeSite;
+  end;
+end;
+
 procedure TAnchorDockHeader.HeaderPositionItemClick(Sender: TObject);
 var
   Item: TMenuItem;
@@ -5640,6 +5841,13 @@
       r.Right:=CloseButton.Left-1;
   end;
 
+  if MinimizeButton.IsControlVisible and (MinimizeButton.Parent=Self) then begin
+    if Align in [alLeft,alRight] then
+      r.Top:=MinimizeButton.Top+MinimizeButton.Height+1
+    else
+      r.Right:=MinimizeButton.Left-1;
+  end;
+
   // caption
   if Caption<>'' then begin
     if fFocused and DockMaster.HeaderHighlightFocused and NeedHighlightText then
@@ -5728,7 +5936,14 @@
     end else begin
       PreferredHeight:=Max(NeededHeight,PreferredHeight);
     end;
+  end else begin
+    NeededHeight:=CloseButton.Height;
+    if Align in [alLeft,alRight] then begin
+      PreferredWidth:=Max(NeededHeight,PreferredWidth);
+    end else begin
+      PreferredHeight:=Max(NeededHeight,PreferredHeight);
   end;
+  end;
 end;
 
 procedure TAnchorDockHeader.MouseDown(Button: TMouseButton; Shift: TShiftState;
@@ -5742,11 +5957,15 @@
 procedure TAnchorDockHeader.UpdateHeaderControls;
 begin
   if Align in [alLeft,alRight] then begin
-    if CloseButton<>nil then
+    if CloseButton<>nil then begin
+      MinimizeButton.Align:=alTop;
       CloseButton.Align:=alTop;
+    end;
   end else begin
-    if CloseButton<>nil then
+    if CloseButton<>nil then begin
+      MinimizeButton.Align:=alRight;
       CloseButton.Align:=alRight;
+    end;
   end;
   //debugln(['TAnchorDockHeader.UpdateHeaderControls ',dbgs(Align),' ',dbgs(CloseButton.Align)]);
 end;
@@ -5787,9 +6006,9 @@
 begin
   inherited Create(TheOwner);
   FHeaderPosition:=adlhpAuto;
-  FCloseButton:=TAnchorDockCloseButton.Create(Self);
   BevelOuter:=bvNone;
   BorderWidth:=0;
+  FCloseButton:=TAnchorDockCloseButton.Create(Self);
   with FCloseButton do begin
     Name:='CloseButton';
     Parent:=Self;
@@ -5799,6 +6018,16 @@
     OnClick:=@CloseButtonClick;
     AutoSize:=true;
   end;
+  FMinimizeButton:=TAnchorDockMinimizeButton.Create(Self);
+  with FMinimizeButton do begin
+    Name:='MinimizeButton';
+    Parent:=Self;
+    Flat:=true;
+    ShowHint:=true;
+    Hint:=adrsMinimize;
+    OnClick:=@MinimizeButtonClick;
+    AutoSize:=true;
+  end;
   Align:=alTop;
   AutoSize:=true;
   ShowHint:=true;
@@ -5844,6 +6073,44 @@
   end;
 end;
 
+{ TAnchorDockMinimizeButton }
+
+function TAnchorDockMinimizeButton.GetDrawDetails: TThemedElementDetails;
+
+function WindowPart: TThemedWindow;
+  begin
+    // no check states available
+    Result := twMDIMinButtonNormal;
+    if not IsEnabled then
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonDisabled{$ELSE}twMDIMinButtonDisabled{$ENDIF}
+    else
+    if FState in [bsDown, bsExclusive] then
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonPushed{$ELSE}twMDIMinButtonPushed{$ENDIF}
+    else
+    if FState = bsHot then
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonHot{$ELSE}twMDIMinButtonHot{$ENDIF}
+    else
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonNormal{$ELSE}twMDIMinButtonNormal{$ENDIF};
+  end;
+
+begin
+  Result := ThemeServices.GetElementDetails(WindowPart);
+end;
+
+procedure TAnchorDockMinimizeButton.CalculatePreferredSize(var PreferredWidth,
+  PreferredHeight: integer; WithThemeSpace: Boolean);
+begin
+  with ThemeServices.GetDetailSize(ThemeServices.GetElementDetails({$IFDEF LCLGtk2}twMDIRestoreButtonNormal{$ELSE}twMinButtonNormal{$ENDIF})) do
+  begin
+    PreferredWidth:=cx;
+    PreferredHeight:=cy;
+    {$IF defined(LCLGtk2) or defined(Carbon)}
+    inc(PreferredWidth,2);
+    inc(PreferredHeight,2);
+    {$ENDIF}
+  end;
+end;
+
 { TAnchorDockManager }
 
 procedure TAnchorDockManager.SetPreferredSiteSizeAsSiteMinimum(
@@ -6505,32 +6772,58 @@
 procedure TAnchorDockSplitter.SetBoundsPercentually;
 var
   NewLeft, NewTop: Integer;
+  AControl: TControl;
+  SplitterAnchorKind:TAnchorKind;
 begin
-  if ResizeAnchor in [akLeft,akRight] then
-  begin
-    if DockParentClientSize.cx> 0 then
+  if Enabled then begin
+    if ResizeAnchor in [akLeft,akRight] then
     begin
-      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
-        NewLeft := Round(FPercentPosition*Parent.ClientWidth)
-      else
-        NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
-      NewTop := Top;
-      SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      if DockParentClientSize.cx> 0 then
+      begin
+        if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+          NewLeft := Round(FPercentPosition*Parent.ClientWidth)
+        else
+          NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
+        NewTop := Top;
+        SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      end;
+    end else
+    begin
+      if DockParentClientSize.cy> 0 then
+      begin
+        NewLeft := Left;
+        if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+          NewTop := Round(FPercentPosition*Parent.ClientHeight)
+        else
+          NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+        SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      end;
     end;
-  end else
-  begin
-    if DockParentClientSize.cy> 0 then
-    begin
-      NewLeft := Left;
-      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
-        NewTop := Round(FPercentPosition*Parent.ClientHeight)
-      else
-        NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+    if FPercentPosition < 0 then
+      UpdatePercentPosition;
+  end else begin
+    SplitterAnchorKind:=akTop;
+    AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);
+    if AControl=nil then begin SplitterAnchorKind:=akRight;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+    if AControl=nil then begin SplitterAnchorKind:=akBottom;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+    if AControl=nil then begin SplitterAnchorKind:=akLeft;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+
+    if AControl is TAnchorDockHostSite then begin
+      (AControl as TAnchorDockHostSite).UpdateHeaderAlign;
+      NewTop := (AControl as TAnchorDockHostSite).Header.Left;
+      NewTop := (AControl as TAnchorDockHostSite).Header.Height;
+      NewLeft := left;
+      NewTop := top;
+      (AControl as TAnchorDockHostSite).UpdateHeaderAlign;
+      case SplitterAnchorKind of
+        akTop: NewTop := AControl.Top+(AControl as TAnchorDockHostSite).Header.Height;
+        akBottom: NewTop := AControl.Top+AControl.Height-(AControl as TAnchorDockHostSite).Header.Height-Height;
+        akLeft: NewLeft := AControl.Left+(AControl as TAnchorDockHostSite).Header.Width;
+        akRight: NewLeft := AControl.Left+AControl.Width-(AControl as TAnchorDockHostSite).Header.Width-Width;
+      end;
       SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
     end;
   end;
-  if FPercentPosition < 0 then
-    UpdatePercentPosition;
 end;
 
 function TAnchorDockSplitter.SideAnchoredControlCount(Side: TAnchorKind): integer;
Index: components/anchordocking/anchordockoptionsdlg.lfm
===================================================================
--- components/anchordocking/anchordockoptionsdlg.lfm	(revision 59428)
+++ components/anchordocking/anchordockoptionsdlg.lfm	(working copy)
@@ -1,11 +1,13 @@
 object AnchorDockOptionsFrame: TAnchorDockOptionsFrame
   Left = 0
-  Height = 482
+  Height = 567
   Top = 0
-  Width = 416
-  ClientHeight = 482
-  ClientWidth = 416
+  Width = 490
+  ClientHeight = 567
+  ClientWidth = 490
+  DesignTimePPI = 113
   OnClick = FrameClick
+  ParentFont = False
   TabOrder = 0
   DesignLeft = 513
   DesignTop = 189
@@ -12,14 +14,15 @@
   object DragThresholdLabel: TLabel
     AnchorSideLeft.Control = Owner
     AnchorSideTop.Control = Owner
-    Left = 10
-    Height = 13
-    Top = 10
-    Width = 111
-    BorderSpacing.Left = 10
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 12
+    Width = 122
+    BorderSpacing.Left = 12
+    BorderSpacing.Top = 12
     Caption = 'DragThresholdLabel'
     ParentColor = False
+    ParentFont = False
   end
   object DragThresholdTrackBar: TTrackBar
     AnchorSideLeft.Control = DragThresholdLabel
@@ -27,15 +30,16 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = Owner
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 46
-    Top = 23
-    Width = 396
+    Left = 12
+    Height = 54
+    Top = 31
+    Width = 466
     Max = 20
     OnChange = DragThresholdTrackBarChange
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Right = 10
+    BorderSpacing.Right = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 1
@@ -46,12 +50,13 @@
     AnchorSideTop.Control = DragThresholdLabel
     AnchorSideTop.Side = asrCenter
     AnchorSideRight.Control = Owner
-    Left = 127
-    Height = 23
-    Top = 5
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 141
+    Height = 27
+    Top = 8
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 20
+    ParentFont = False
     TabOrder = 0
     Visible = False
   end
@@ -59,13 +64,14 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = DragThresholdTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 79
-    Width = 103
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 97
+    Width = 112
+    BorderSpacing.Top = 12
     Caption = 'SplitterWidthLabel'
     ParentColor = False
+    ParentFont = False
   end
   object SplitterWidthTrackBar: TTrackBar
     AnchorSideLeft.Control = DragThresholdTrackBar
@@ -73,14 +79,15 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 46
-    Top = 92
-    Width = 396
+    Left = 12
+    Height = 54
+    Top = 116
+    Width = 466
     Min = 1
     OnChange = SplitterWidthTrackBarChange
     Position = 1
     Anchors = [akTop, akLeft, akRight]
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 3
@@ -89,12 +96,13 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = SplitterWidthTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 24
-    Top = 142
-    Width = 160
-    BorderSpacing.Top = 4
+    Left = 12
+    Height = 23
+    Top = 175
+    Width = 169
+    BorderSpacing.Top = 5
     Caption = 'ScaleOnResizeCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 4
@@ -103,12 +111,13 @@
     AnchorSideLeft.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 24
-    Top = 166
-    Width = 149
+    Left = 12
+    Height = 23
+    Top = 198
+    Width = 160
     Caption = 'ShowHeaderCheckBox'
     OnChange = ShowHeaderCheckBoxChange
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 5
@@ -117,12 +126,13 @@
     AnchorSideLeft.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Control = ShowHeaderCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 190
-    Width = 191
-    BorderSpacing.Left = 15
+    Left = 30
+    Height = 23
+    Top = 221
+    Width = 208
+    BorderSpacing.Left = 18
     Caption = 'ShowHeaderCaptionCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 6
@@ -131,11 +141,12 @@
     AnchorSideLeft.Control = ShowHeaderCaptionCheckBox
     AnchorSideTop.Control = ShowHeaderCaptionCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 214
-    Width = 249
+    Left = 30
+    Height = 23
+    Top = 244
+    Width = 272
     Caption = 'HideHeaderCaptionForFloatingCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 7
@@ -147,15 +158,16 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = Owner
     AnchorSideRight.Side = asrBottom
-    Left = 122
+    Left = 136
     Height = 27
-    Top = 286
-    Width = 284
+    Top = 313
+    Width = 342
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 6
-    BorderSpacing.Right = 10
-    ItemHeight = 0
+    BorderSpacing.Left = 7
+    BorderSpacing.Right = 12
+    ItemHeight = 19
     OnDrawItem = HeaderStyleComboBoxDrawItem
+    ParentFont = False
     Style = csDropDownList
     TabOrder = 10
   end
@@ -163,23 +175,25 @@
     AnchorSideLeft.Control = ShowHeaderCheckBox
     AnchorSideTop.Control = HeaderStyleComboBox
     AnchorSideTop.Side = asrCenter
-    Left = 20
-    Height = 13
-    Top = 293
-    Width = 96
-    BorderSpacing.Left = 10
+    Left = 24
+    Height = 19
+    Top = 317
+    Width = 105
+    BorderSpacing.Left = 12
     Caption = 'HeaderStyleLabel'
     ParentColor = False
+    ParentFont = False
   end
   object FlattenHeadersCheckBox: TCheckBox
     AnchorSideLeft.Control = HideHeaderCaptionForFloatingCheckBox
     AnchorSideTop.Control = HideHeaderCaptionForFloatingCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 238
-    Width = 164
+    Left = 30
+    Height = 23
+    Top = 267
+    Width = 175
     Caption = 'FlattenHeadersCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 8
@@ -188,11 +202,12 @@
     AnchorSideLeft.Control = FlattenHeadersCheckBox
     AnchorSideTop.Control = FlattenHeadersCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 262
-    Width = 154
+    Left = 30
+    Height = 23
+    Top = 290
+    Width = 164
     Caption = 'FilledHeadersCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 9
@@ -201,11 +216,12 @@
     AnchorSideLeft.Control = FilledHeadersCheckBox
     AnchorSideTop.Control = HeaderStyleComboBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 313
-    Width = 175
+    Left = 30
+    Height = 23
+    Top = 340
+    Width = 189
     Caption = 'HighlightFocusedCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 11
@@ -215,13 +231,14 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = SplitterWidthLabel
     AnchorSideTop.Side = asrCenter
-    Left = 119
-    Height = 23
-    Top = 74
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 131
+    Height = 27
+    Top = 93
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 10
     MinValue = 1
+    ParentFont = False
     TabOrder = 2
     Value = 1
     Visible = False
@@ -228,15 +245,16 @@
   end
   object HeaderAlignTopLabel: TLabel
     AnchorSideLeft.Control = DragThresholdLabel
-    AnchorSideTop.Control = HighlightFocusedCheckBox
+    AnchorSideTop.Control = DockSitesCanBeMinimized
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 347
-    Width = 117
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 398
+    Width = 130
+    BorderSpacing.Top = 12
     Caption = 'HeaderAlignTopLabel'
     ParentColor = False
+    ParentFont = False
   end
   object HeaderAlignTopTrackBar: TTrackBar
     AnchorSideLeft.Control = Owner
@@ -244,10 +262,10 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 47
-    Top = 360
-    Width = 396
+    Left = 12
+    Height = 55
+    Top = 417
+    Width = 466
     Frequency = 10
     Max = 150
     OnChange = HeaderAlignTopTrackBarChange
@@ -254,7 +272,8 @@
     PageSize = 10
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 10
+    BorderSpacing.Left = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 13
@@ -264,12 +283,13 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = HeaderAlignTopLabel
     AnchorSideTop.Side = asrCenter
-    Left = 133
-    Height = 23
-    Top = 342
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 149
+    Height = 27
+    Top = 394
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 150
+    ParentFont = False
     TabOrder = 12
     Visible = False
   end
@@ -277,13 +297,14 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = HeaderAlignTopTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 417
-    Width = 120
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 484
+    Width = 130
+    BorderSpacing.Top = 12
     Caption = 'HeaderAlignLeftLabel'
     ParentColor = False
+    ParentFont = False
   end
   object HeaderAlignLeftTrackBar: TTrackBar
     AnchorSideLeft.Control = Owner
@@ -291,10 +312,10 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 47
-    Top = 430
-    Width = 396
+    Left = 12
+    Height = 55
+    Top = 503
+    Width = 466
     Frequency = 10
     Max = 200
     OnChange = HeaderAlignLeftTrackBarChange
@@ -301,7 +322,8 @@
     PageSize = 10
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 10
+    BorderSpacing.Left = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 15
@@ -311,13 +333,28 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = HeaderAlignLeftLabel
     AnchorSideTop.Side = asrCenter
-    Left = 136
-    Height = 23
-    Top = 412
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 149
+    Height = 27
+    Top = 480
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 200
+    ParentFont = False
     TabOrder = 14
     Visible = False
   end
+  object DockSitesCanBeMinimized: TCheckBox
+    AnchorSideLeft.Control = FilledHeadersCheckBox
+    AnchorSideTop.Control = HighlightFocusedCheckBox
+    AnchorSideTop.Side = asrBottom
+    Left = 30
+    Height = 23
+    Top = 363
+    Width = 185
+    Caption = 'DockSitesCanBeMinimized'
+    ParentFont = False
+    ParentShowHint = False
+    ShowHint = True
+    TabOrder = 16
+  end
 end
Index: components/anchordocking/anchordockoptionsdlg.pas
===================================================================
--- components/anchordocking/anchordockoptionsdlg.pas	(revision 59428)
+++ components/anchordocking/anchordockoptionsdlg.pas	(working copy)
@@ -37,6 +37,7 @@
     HeaderStyleLabel: TLabel;
     HideHeaderCaptionForFloatingCheckBox: TCheckBox;
     HighlightFocusedCheckBox: TCheckBox;
+    DockSitesCanBeMinimized: TCheckBox;
     ScaleOnResizeCheckBox: TCheckBox;
     ShowHeaderCaptionCheckBox: TCheckBox;
     ShowHeaderCheckBox: TCheckBox;
@@ -299,6 +300,7 @@
   HeaderStyleLabel.Enabled:=HasHeaders;
   HeaderStyleComboBox.Enabled:=HasHeaders;
   HighlightFocusedCheckBox.Enabled:=HasHeaders;
+  DockSitesCanBeMinimized.Enabled:=HasHeaders;
 end;
 
 constructor TAnchorDockOptionsFrame.Create(TheOwner: TComponent);
@@ -356,6 +358,7 @@
   TheSettings.HeaderFilled:=FilledHeadersCheckBox.Checked;
   TheSettings.HeaderStyle:=TADHeaderStyle(HeaderStyleComboBox.ItemIndex);
   TheSettings.HeaderHighlightFocused:=HighlightFocusedCheckBox.Checked;
+  TheSettings.DockSitesCanBeMinimized:=DockSitesCanBeMinimized.Checked;
 end;
 
 procedure TAnchorDockOptionsFrame.LoadFromSettings(
@@ -429,6 +432,10 @@
   HighlightFocusedCheckBox.Checked:=TheSettings.HeaderHighlightFocused;
   HighlightFocusedCheckBox.Caption:=adrsHighlightFocused;
   HighlightFocusedCheckBox.Hint:=adrsHighlightFocusedHint;
+
+  DockSitesCanBeMinimized.Checked:=TheSettings.DockSitesCanBeMinimized;
+  DockSitesCanBeMinimized.Caption:=adrsDockSitesCanBeMinimized;
+  DockSitesCanBeMinimized.Hint:=adrsDockSitesCanBeMinimizedHint;
 end;
 
 end.
Index: components/anchordocking/anchordockstr.pas
===================================================================
--- components/anchordocking/anchordockstr.pas	(revision 59428)
+++ components/anchordocking/anchordockstr.pas	(working copy)
@@ -8,6 +8,7 @@
 
 resourcestring
   adrsClose = 'Close';
+  adrsMinimize = 'Minimize';
   adrsQuit = 'Quit %s';
   adrsTabPosition = 'Tab position';
   adrsMovePageRight = 'Move page right';
@@ -82,6 +83,8 @@
   adrsFilledHeadersHint = 'Fill headers of docked controls';
   adrsHighlightFocused = 'Highlight focused';
   adrsHighlightFocusedHint = 'Highlight header of focused docked control';
+  adrsDockSitesCanBeMinimized = 'Dock sites can be minimized';
+  adrsDockSitesCanBeMinimizedHint = 'Dock sites can be minimized';
 
 implementation
 

Andrey Zubarev

2018-11-04 13:26

reporter   ~0111784

Please test anchordocking_minimize_docksite4.patch it work with gtk,win and qt
-ugly minimize button (for gtk2 i use twMDIRestoreButton instead twMDIMinButtonNormal)
-minimize state not saved
-overlap show not implemented

Andrey Zubarev

2018-11-06 07:16

reporter  

anchordocking_minimize_docksite5.patch (56,037 bytes)   
Index: components/anchordocking/anchordocking.pas
===================================================================
--- components/anchordocking/anchordocking.pas	(revision 59428)
+++ components/anchordocking/anchordocking.pas	(working copy)
@@ -92,9 +92,9 @@
 {$mode objfpc}{$H+}
 
 { $DEFINE VerboseAnchorDockRestore}
-{ $DEFINE VerboseADCustomSite}
-{ $DEFINE VerboseAnchorDockPages}
-{ $DEFINE VerboseAnchorDocking}
+{$DEFINE VerboseADCustomSite}
+{$DEFINE VerboseAnchorDockPages}
+{$DEFINE VerboseAnchorDocking}
 
 interface
 
@@ -123,6 +123,14 @@
            PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
   end;
 
+  TAnchorDockMinimizeButton = class(TCustomSpeedButton)
+  protected
+    function GetDrawDetails: TThemedElementDetails; override;
+    procedure CalculatePreferredSize(var PreferredWidth,
+           PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
+  end;
+
+
   { TAnchorDockHeader
     The panel of a TAnchorDockHostSite containing the close button and the
     caption when the form is docked. The header can be shown at any of the four
@@ -133,9 +141,11 @@
   TAnchorDockHeader = class(TCustomPanel)
   private
     FCloseButton: TCustomSpeedButton;
+    FMinimizeButton: TCustomSpeedButton;
     FHeaderPosition: TADLHeaderPosition;
     fFocused:Boolean;
     procedure CloseButtonClick(Sender: TObject);
+    procedure MinimizeButtonClick(Sender: TObject);
     procedure HeaderPositionItemClick(Sender: TObject);
     procedure UndockButtonClick(Sender: TObject);
     procedure MergeButtonClick(Sender: TObject);
@@ -154,6 +164,7 @@
   public
     constructor Create(TheOwner: TComponent); override;
     property CloseButton: TCustomSpeedButton read FCloseButton;
+    property MinimizeButton: TCustomSpeedButton read FMinimizeButton;
     property HeaderPosition: TADLHeaderPosition read FHeaderPosition write SetHeaderPosition;
     property BevelOuter default bvNone;
   end;
@@ -262,7 +273,10 @@
     FPages: TAnchorDockPageControl;
     FSiteType: TAnchorDockHostSiteType;
     FBoundSplitter: TAnchorDockSplitter;
-    fUpdateLayout: integer;
+    fUpdateLayout: Integer;
+    FMinimized: Boolean;
+    fMinimization: Boolean;
+    FMinimizedControl: TControl;
     procedure SetHeaderSide(const AValue: TAnchorKind);
   protected
     procedure DoEnter; override;
@@ -319,6 +333,8 @@
     destructor Destroy; override;
     function CloseQuery: boolean; override;
     function CloseSite: boolean; virtual;
+    procedure MinimizeSite; virtual;
+    procedure AsyncMinimizeSite(Data: PtrInt);
     procedure RemoveControl(AControl: TControl); override;
     procedure InsertControl(AControl: TControl; Index: integer); override;
     procedure GetSiteInfo(Client: TControl; var InfluenceRect: TRect;
@@ -431,6 +447,7 @@
     FShowHeader: boolean;
     FShowHeaderCaption: boolean;
     FSplitterWidth: integer;
+    FDockSitecCanBeMinimized: boolean;
     procedure SetAllowDragging(AValue: boolean);
     procedure SetDockOutsideMargin(AValue: integer);
     procedure SetDockParentMargin(AValue: integer);
@@ -448,6 +465,7 @@
     procedure SetHeaderFlatten(AValue: boolean);
     procedure SetHeaderFilled(AValue: boolean);
     procedure SetHeaderHighlightFocused(AValue: boolean);
+    procedure SetDockSitecCanBeMinimized(AValue: boolean);
   public
     property DragTreshold: integer read FDragTreshold write SetDragTreshold;
     property DockOutsideMargin: integer read FDockOutsideMargin write SetDockOutsideMargin;
@@ -466,6 +484,7 @@
     property HeaderFlatten: boolean read FHeaderFlatten write SetHeaderFlatten;
     property HeaderFilled: boolean read FHeaderFilled write SetHeaderFilled;
     property HeaderHighlightFocused: boolean read FHeaderHighlightFocused write SetHeaderHighlightFocused;
+    property DockSitesCanBeMinimized: boolean read FDockSitecCanBeMinimized write SetDockSitecCanBeMinimized;
     procedure IncreaseChangeStamp; inline;
     property ChangeStamp: integer read FChangeStamp;
     procedure LoadFromConfig(Config: TConfigStorage); overload;
@@ -502,6 +521,7 @@
     FHeaderFlatten: boolean;
     FHeaderFilled: boolean;
     FHeaderHighlightFocused: boolean;
+    FDockSitesCanBeMinimized: boolean;
     FIdleConnected: Boolean;
     FManagerClass: TAnchorDockManagerClass;
     FOnCreateControl: TADCreateControlEvent;
@@ -541,6 +561,8 @@
     function GetNodeSite(Node: TAnchorDockLayoutTreeNode): TAnchorDockHostSite;
     procedure MapTreeToControls(Tree: TAnchorDockLayoutTree);
     function RestoreLayout(Tree: TAnchorDockLayoutTree; Scale: boolean): boolean;
+    procedure SetMinimizedState(Tree: TAnchorDockLayoutTree);
+    procedure SetnodeMinimizedState(ANode: TAnchorDockLayoutTreeNode);
     procedure EnableAllAutoSizing;
     procedure ClearLayoutProperties(AControl: TControl; NewAlign: TAlign = alClient);
     procedure PopupMenuPopup(Sender: TObject);
@@ -561,6 +583,7 @@
     procedure SetHeaderFlatten(AValue: boolean);
     procedure SetHeaderFilled(AValue: boolean);
     procedure SetHeaderHighlightFocused(AValue: boolean);
+    procedure SetDockSitesCanBeMinimized(AValue: boolean);
 
     procedure SetShowMenuItemShowHeader(AValue: boolean);
     procedure SetupSite(Site: TWinControl; ANode: TAnchorDockLayoutTreeNode;
@@ -680,6 +703,7 @@
     property HeaderFlatten: boolean read FHeaderFlatten write SetHeaderFlatten default true;
     property HeaderFilled: boolean read FHeaderFilled write SetHeaderFilled default true;
     property HeaderHighlightFocused: boolean read FHeaderHighlightFocused write SetHeaderHighlightFocused default false;
+    property DockSitesCanBeMinimized: boolean read FDockSitesCanBeMinimized write SetDockSitesCanBeMinimized default false;
 
     property SplitterWidth: integer read FSplitterWidth write SetSplitterWidth default 4;
     property ScaleOnResize: boolean read FScaleOnResize write SetScaleOnResize default true; // scale children when resizing a site
@@ -970,6 +994,27 @@
   end;
 end;
 
+function CountAndReturnOnlyOneMinimizedAnchoredControls(Control: TControl; Side: TAnchorKind): TAnchorDockHostSite;
+var
+  i,Counter: Integer;
+  Neighbour: TControl;
+begin
+  Counter:=0;
+  for i:=0 to Control.AnchoredControlCount-1 do begin
+    Neighbour:=Control.AnchoredControls[i];
+    if Neighbour.Visible then
+    if Neighbour is TAnchorDockHostSite then
+    if (OppositeAnchor[Side] in Neighbour.Anchors)
+    and (Neighbour.AnchorSide[OppositeAnchor[Side]].Control=Control) then begin
+      inc(Counter);
+      result:=TAnchorDockHostSite(Neighbour);
+    end;
+  end;
+  if (Counter=1)and(result is TAnchorDockHostSite)and((result as TAnchorDockHostSite).FMinimized) then
+  else
+    result:=Nil;
+end;
+
 function NeighbourCanBeShrinked(EnlargeControl, Neighbour: TControl;
   Side: TAnchorKind): boolean;
 { returns true if Neighbour can be shrinked on the opposite side of Side
@@ -1361,6 +1406,13 @@
   IncreaseChangeStamp;
 end;
 
+procedure TAnchorDockSettings.SetDockSitecCanBeMinimized(AValue: boolean);
+begin
+  if FDockSitecCanBeMinimized=AValue then Exit;
+  FDockSitecCanBeMinimized:=AValue;
+  IncreaseChangeStamp;
+end;
+
 procedure TAnchorDockSettings.Assign(Source: TAnchorDockSettings);
 begin
   FAllowDragging := Source.FAllowDragging;
@@ -1381,6 +1433,7 @@
   FShowHeaderCaption := Source.FShowHeaderCaption;
   FSplitterWidth := Source.FSplitterWidth;
   FHeaderHighlightFocused:=Source.FHeaderHighlightFocused;
+  FDockSitecCanBeMinimized:=Source.FDockSitecCanBeMinimized;
 end;
 
 procedure TAnchorDockSettings.IncreaseChangeStamp;
@@ -1407,6 +1460,7 @@
   HeaderFlatten:=Config.GetValue('HeaderFlatten',true);
   HeaderFilled:=Config.GetValue('HeaderFilled',true);
   HeaderHighlightFocused:=Config.GetValue('HeaderHighlightFocused',False);
+  DockSitesCanBeMinimized:=Config.GetValue('DockSitecCanBeMinimized',False);
   Config.UndoAppendBasePath;
 end;
 
@@ -1429,6 +1483,7 @@
   Config.SetDeleteValue(Path+'HeaderFlatten',HeaderFlatten,true);
   Config.SetDeleteValue(Path+'HeaderFilled',HeaderFilled,true);
   Config.SetDeleteValue(Path+'HeaderHighlightFocused',HeaderHighlightFocused,False);
+  Config.SetDeleteValue(Path+'DockSitecCanBeMinimized',DockSitesCanBeMinimized,False);
 end;
 
 procedure TAnchorDockSettings.SaveToConfig(Config: TConfigStorage);
@@ -1450,6 +1505,7 @@
   Config.SetDeleteValue('HeaderFlatten',HeaderFlatten,true);
   Config.SetDeleteValue('HeaderFilled',HeaderFilled,true);
   Config.SetDeleteValue('HeaderHighlightFocused',HeaderHighlightFocused,False);
+  Config.SetDeleteValue('DockSitecCanBeMinimized',DockSitesCanBeMinimized,False);
   Config.UndoAppendBasePath;
 end;
 
@@ -1472,6 +1528,7 @@
       and (HeaderFlatten=Settings.HeaderFlatten)
       and (HeaderFilled=Settings.HeaderFilled)
       and (HeaderHighlightFocused=Settings.HeaderHighlightFocused)
+      and (DockSitesCanBeMinimized=Settings.DockSitesCanBeMinimized)
       ;
 end;
 
@@ -1494,6 +1551,7 @@
   HeaderFlatten:=Config.GetValue(Path+'HeaderFlatten',true);
   HeaderFilled:=Config.GetValue(Path+'HeaderFilled',true);
   HeaderHighlightFocused:=Config.GetValue(Path+'HeaderHighlightFocused',False);
+  DockSitesCanBeMinimized:=Config.GetValue(Path+'DockSitecCanBeMinimized',False);
 end;
 
 { TAnchorDockMaster }
@@ -2021,6 +2079,8 @@
     aHostSite:=TAnchorDockHostSite(Site);
     aHostSite.Header.HeaderPosition:=ANode.HeaderPosition;
     aHostSite.DockRestoreBounds:=NewBounds;
+    //aHostSite.FMinimized:=ANode.Minimized;
+    //we update aHostSite.FMinimized in TAnchorDockMaster.SetMinimizedState
     if (ANode.NodeType<>adltnPages) and (aHostSite.Pages<>nil) then
       aHostSite.FreePages;
   end;
@@ -2040,6 +2100,25 @@
   fTreeNameToDocker[Node.Name]:=Result;
 end;
 
+procedure TAnchorDockMaster.SetNodeMinimizedState(ANode: TAnchorDockLayoutTreeNode);
+var
+  HostSite:TAnchorDockHostSite;
+  i:integer;
+begin
+  HostSite:=GetNodeSite(ANode);
+  if Assigned(HostSite) then
+    if HostSite.FMinimized<>ANode.Minimized then
+      Application.QueueAsyncCall(@HostSite.AsyncMinimizeSite,0);
+      //HostSite.MinimizeSite;
+  for i:=0 to ANode.Count-1 do
+    SetnodeMinimizedState(ANode.Nodes[i]);
+end;
+
+procedure TAnchorDockMaster.SetMinimizedState(Tree: TAnchorDockLayoutTree);
+begin
+  SetnodeMinimizedState(Tree.Root);
+end;
+
 function TAnchorDockMaster.RestoreLayout(Tree: TAnchorDockLayoutTree;
   Scale: boolean): boolean;
 
@@ -2193,7 +2272,7 @@
       try
         SetupSite(Site,ANode,AParent);
         Site.FSiteType:=adhstPages;
-        Site.Header.Parent:=nil;
+        //Site.Header.Parent:=nil;
         if Site.Pages=nil then
           Site.CreatePages;
         for i:=0 to ANode.Count-1 do begin
@@ -2358,7 +2437,7 @@
       debugln(ControlNames.Text);
       {$ENDIF}
       // if some forms/controls could not be created the layout needs to be adapted
-      Tree.Root.Simplify(ControlNames);
+      Tree.Root.Simplify(ControlNames,false);
 
       // reuse existing sites to reduce flickering
       MapTreeToControls(Tree);
@@ -2368,6 +2447,7 @@
 
       // create sites, move controls
       RestoreLayout(Tree,Scale);
+      SetMinimizedState(Tree);
     finally
       EndUpdate;
     end;
@@ -2514,6 +2594,24 @@
   InvalidateHeaders;
 end;
 
+procedure TAnchorDockMaster.SetDockSitesCanBeMinimized(AValue: boolean);
+var
+  i:integer;
+  Site: TAnchorDockHostSite;
+begin
+  if FDockSitesCanBeMinimized=AValue then Exit;
+  FDockSitesCanBeMinimized:=AValue;
+  for i:=0 to ComponentCount-1 do begin
+    Site:=TAnchorDockHostSite(Components[i]);
+    if not (Site is TAnchorDockHostSite) then continue;
+    if (Site.Header<>nil) then begin
+      DisableControlAutoSizing(Site);
+      Site.UpdateHeaderShowing;
+    end;
+  end;
+  EnableAllAutoSizing;
+  OptionsChanged;
+end;
 procedure TAnchorDockMaster.SetScaleOnResize(AValue: boolean);
 begin
   if FScaleOnResize=AValue then Exit;
@@ -2698,14 +2796,13 @@
   FPageClass:=TAnchorDockPage;
   FRestoreLayouts:=TAnchorDockRestoreLayouts.Create;
   FHeaderHighlightFocused:=false;
+  FDockSitesCanBeMinimized:=false;
 end;
 
 destructor TAnchorDockMaster.Destroy;
 var
   AControl: TControl;
-  {$IFDEF VerboseAnchorDocking}
-  i: Integer;
-  {$ENDIF}
+  i, j: Integer;
 begin
   QueueSimplify:=false;
   FreeAndNil(FRestoreLayouts);
@@ -2727,6 +2824,12 @@
     debugln(['TAnchorDockMaster.Destroy ',i,'/',ComponentCount,' ',DbgSName(Components[i])]);
   end;
   {$ENDIF}
+  for i:=0 to ComponentCount-1 do begin
+    for j:=0 to ComponentCount-1 do begin
+      if i<>j then
+        TControl(Components[i]).RemoveAllHandlersOfObject(TControl(Components[j]));
+  end;
+  end;
   inherited Destroy;
 end;
 
@@ -3088,12 +3191,12 @@
   AFormOrDockPanel: TWinControl;
   VisibleControls: TStringList;
 
-  procedure SaveFormOrDockPanel(theFormOrDockPanel: TWinControl; SaveChildren: boolean);
+  procedure SaveFormOrDockPanel(theFormOrDockPanel: TWinControl; SaveChildren: boolean; AMinimized:boolean);
   begin
     // custom dock site
     LayoutNode:=LayoutTree.NewNode(LayoutTree.Root);
     LayoutNode.NodeType:=adltnCustomSite;
-    LayoutNode.Assign(theFormOrDockPanel,theFormOrDockPanel is TAnchorDockPanel);
+    LayoutNode.Assign(theFormOrDockPanel,theFormOrDockPanel is TAnchorDockPanel,AMinimized);
     // can have one normal dock site
     if SaveChildren then
     begin
@@ -3124,7 +3227,7 @@
       debugln(['TAnchorDockMaster.SaveMainLayoutToTree AForm=',DbgSName(AFormOrDockPanel)]);
       DebugWriteChildAnchors(AFormOrDockPanel,true,true);
       if AFormOrDockPanel is TAnchorDockPanel then begin
-        SaveFormOrDockPanel(GetParentFormOrDockPanel(AFormOrDockPanel),{false}true);
+        SaveFormOrDockPanel(GetParentFormOrDockPanel(AFormOrDockPanel),true,false);
         //LayoutNode:=LayoutTree.NewNode(LayoutTree.Root);
         //TAnchorDockPanel(AFormOrDockPanel).SaveLayout(LayoutTree,LayoutNode);
       end else if AFormOrDockPanel is TAnchorDockHostSite then begin
@@ -3132,12 +3235,12 @@
         LayoutNode:=LayoutTree.NewNode(LayoutTree.Root);
         Site.SaveLayout(LayoutTree,LayoutNode);
       end else if IsCustomSite(AFormOrDockPanel) then begin
-        SaveFormOrDockPanel(AFormOrDockPanel,true);
+        SaveFormOrDockPanel(AFormOrDockPanel,true,false);
       end else
         raise EAnchorDockLayoutError.Create('invalid root control for save: '+DbgSName(AControl));
     end;
     // remove invisible controls
-    LayoutTree.Root.Simplify(VisibleControls);
+    LayoutTree.Root.Simplify(VisibleControls,false);
   finally
     VisibleControls.Free;
     SavedSites.Free;
@@ -3157,7 +3260,7 @@
     (AControl as TAnchorDockPanel).SaveLayout(LayoutTree,LayoutTree.Root);
   end else if IsCustomSite(AControl) then begin
     LayoutTree.Root.NodeType:=adltnCustomSite;
-    LayoutTree.Root.Assign(AControl);
+    LayoutTree.Root.Assign(AControl,false,false);
     // can have one normal dock site
     Site:=TAnchorDockManager(AControl.DockManager).GetChildSite;
     if Site<>nil then begin
@@ -3252,7 +3355,7 @@
       debugln(ControlNames.Text);
       {$ENDIF}
       // if some forms/controls could not be created the layout needs to be adapted
-      Tree.Root.Simplify(ControlNames);
+      Tree.Root.Simplify(ControlNames,false);
 
       // reuse existing sites to reduce flickering
       MapTreeToControls(Tree);
@@ -3262,6 +3365,7 @@
 
       // create sites, move controls
       RestoreLayout(Tree,Scale);
+      SetMinimizedState(Tree);
     finally
       EndUpdate;
     end;
@@ -3323,6 +3427,7 @@
   HeaderFlatten                    := Settings.HeaderFlatten;
   HeaderFilled                     := Settings.HeaderFilled;
   HeaderHighlightFocused           := Settings.HeaderHighlightFocused;
+  DockSitesCanBeMinimized          := Settings.DockSitesCanBeMinimized;
 end;
 
 procedure TAnchorDockMaster.SaveSettings(Settings: TAnchorDockSettings);
@@ -3343,6 +3448,7 @@
   Settings.HeaderFlatten:=HeaderFlatten;
   Settings.HeaderFilled:=HeaderFilled;
   Settings.HeaderHighlightFocused:=HeaderHighlightFocused;
+  Settings.DockSitesCanBeMinimized:=DockSitesCanBeMinimized;
 end;
 
 function TAnchorDockMaster.SettingsAreEqual(Settings: TAnchorDockSettings
@@ -3680,6 +3786,7 @@
     AControl:=TControl(Sender);
     if not (csDestroying in ComponentState) then begin
       if (not AControl.Visible)
+      and (not FMinimized)
       and (not ((AControl is TAnchorDockHeader)
                or (AControl is TAnchorDockSplitter)
                or (AControl is TAnchorDockHostSite)))
@@ -4119,6 +4226,8 @@
 end;
 
 procedure TAnchorDockHostSite.FreePages;
+var
+  i:Integer;
 begin
   FreeAndNil(FPages);
 end;
@@ -4233,6 +4342,14 @@
         akRight: NewBounds.Right:=AControl.Left+AControl.Width;
         akBottom: NewBounds.Bottom:=AControl.Top+AControl.Height;
         end;
+        if (sibling is TAnchorDockHostSite) then
+        if (sibling as TAnchorDockHostSite).FMinimized then begin
+          (sibling as TAnchorDockHostSite).FMinimized:=false;
+          (sibling as TAnchorDockHostSite).FMinimizedControl.Parent:=(sibling as TAnchorDockHostSite);
+          (sibling as TAnchorDockHostSite).FMinimizedControl.Visible:=True;
+          (sibling as TAnchorDockHostSite).FMinimizedControl:=nil;
+          (sibling as TAnchorDockHostSite).UpdateHeaderAlign;
+        end;
         Sibling.BoundsRect:=NewBounds;
       end;
     end;
@@ -4306,6 +4423,13 @@
       FSiteType:=adhstOneControl;
       OnlySiteLeft.Align:=alClient;
       Header.Parent:=Self;
+      if OnlySiteLeft.FMinimized then begin
+        OnlySiteLeft.FMinimized:=false;
+        OnlySiteLeft.FMinimizedControl.Parent:=OnlySiteLeft;
+        OnlySiteLeft.FMinimizedControl.Visible:=True;
+        OnlySiteLeft.FMinimizedControl:=nil;
+        UpdateHeaderAlign;
+      end;
       UpdateHeaderAlign;
 
       //debugln(['TAnchorDockHostSite.RemoveControlFromLayout.ConvertToOneControlType AFTER CONVERT "',Caption,'" to onecontrol OnlySiteLeft="',OnlySiteLeft.Caption,'"']);
@@ -4465,7 +4589,7 @@
     debugln(['TAnchorDockHostSite.Simplify ',DbgSName(Self),' ',DbgSName(AControl)]);
     if AControl is TAnchorDockHostSite then
       SimplifyOneControl
-    else if (AControl=nil) or (csDestroying in AControl.ComponentState) then
+    else if ((AControl=nil) or (csDestroying in AControl.ComponentState)) then
       DockMaster.NeedFree(Self);
   end;
 end;
@@ -4577,7 +4701,8 @@
     Result:=Controls[i];
     if Result.Owner<>Self then exit;
   end;
-  Result:=nil;
+  result:=FMinimizedControl;
+  //Result:=nil;
 end;
 
 function TAnchorDockHostSite.GetSiteCount: integer;
@@ -5165,6 +5290,71 @@
   Result:=Check(Self);
 end;
 
+function CheckOposite(Side:TAnchorKind;var AControl: TControl;out Splitter: TAnchorDockSplitter; out SplitterAnchorKind:TAnchorKind):boolean;
+begin
+  result:=GetDockSplitter(AControl,Side,Splitter);
+  if result then begin
+    if CountAnchoredControls(Splitter,OppositeAnchor[Side])=1 then begin
+      SplitterAnchorKind:=Side;
+      exit;
+    end;
+  end;
+  result:=false
+end;
+
+function FindNearestSpliter(AControl: TControl;out Splitter: TAnchorDockSplitter;out SplitterAnchorKind:TAnchorKind):boolean;
+begin
+  result:=CheckOposite(akTop,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akRight,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akBottom,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akLeft,AControl,Splitter,SplitterAnchorKind);
+end;
+
+procedure TAnchorDockHostSite.MinimizeSite;
+begin
+  //Application.QueueAsyncCall(@AsyncMinimizeSite,0);
+  AsyncMinimizeSite(0);
+end;
+
+procedure TAnchorDockHostSite.AsyncMinimizeSite(Data: PtrInt);
+var
+  AControl: TControl;
+  OpositeDockHostSite:TAnchorDockHostSite;
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
+  //SpliterPercentPosition:Single;
+begin
+  fMinimization:=true;
+  debugln(['TAnchorDockHostSite.MinimizeSite ',DbgSName(Self),' SiteType=',dbgs(SiteType)]);
+  if FMinimized then
+    AControl:=FMinimizedControl
+  else
+    AControl:=GetOneControl;
+  if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+    OpositeDockHostSite:=CountAndReturnOnlyOneMinimizedAnchoredControls(Splitter,SplitterAnchorKind);
+    if (Splitter.Enabled and (OpositeDockHostSite=nil)) or FMinimized then begin
+      FMinimized:=not FMinimized;
+      if FMinimized then begin
+        FMinimizedControl:=AControl;
+        AControl.Visible:=False;
+        AControl.Parent:=nil;
+      end else begin
+        AControl.Parent:=self;
+        AControl.Visible:=True;
+        FMinimizedControl:=nil;
+      end;
+      Splitter.Enabled:=AControl.Visible;
+      UpdateHeaderAlign;
+      Splitter.SetBoundsPercentually;
+    end;
+  end;
+  fMinimization:=false;
+end;
+
+
 function TAnchorDockHostSite.CloseSite: boolean;
 var
   AControl: TControl;
@@ -5306,9 +5496,8 @@
     if Parent is TAnchorDockPage then
       TAnchorDockPage(Parent).UpdateDockCaption;
   end;
-
   // do not show close button for mainform
-  Header.CloseButton.Visible:=not IsParentOf(Application.MainForm);
+  Header.CloseButton.Visible:=(not IsParentOf(Application.MainForm))and(Pages=nil);
 end;
 
 procedure TAnchorDockHostSite.GetSiteInfo(Client: TControl;
@@ -5362,9 +5551,33 @@
 end;
 
 procedure TAnchorDockHostSite.UpdateHeaderAlign;
+const
+OppositeAlign: array[TAnchorKind] of TAlign = (
+  alBottom, // akTop,
+  alRight,  // akLeft,
+  alLeft,   // akRight,
+  alTop     // akBottom
+  );
+OppositeAnchorKindAlign: array[TAnchorKind] of TADLHeaderPosition = (
+  adlhpBottom, // akTop,
+  adlhpRight,  // akLeft,
+  adlhpLeft,   // akRight,
+  adlhpTop     // akBottom
+  );
+var
+  NeededHeaderPosition:TADLHeaderPosition;
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
 begin
   if Header=nil then exit;
-  case Header.HeaderPosition of
+  if FMinimized then begin
+    if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+      NeededHeaderPosition:=OppositeAnchorKindAlign[SplitterAnchorKind];
+    end else
+      NeededHeaderPosition:=Header.HeaderPosition;
+  end else
+    NeededHeaderPosition:=Header.HeaderPosition;
+  case NeededHeaderPosition of
   adlhpAuto:
     if Header.Align in [alLeft,alRight] then begin
       if (ClientHeight>0)
@@ -5390,8 +5603,11 @@
 procedure TAnchorDockHostSite.UpdateHeaderShowing;
 begin
   if Header=nil then exit;
-  if HeaderNeedsShowing then
-    Header.Parent:=Self
+  if HeaderNeedsShowing then begin
+    Header.Parent:=Self;
+    Header.MinimizeButton.Visible:=DockMaster.DockSitesCanBeMinimized;
+    Header.MinimizeButton.Parent:=Header;
+  end
   else
     Header.Parent:=nil;
 end;
@@ -5432,7 +5648,7 @@
   if (SiteType=adhstOneControl) and (OneControl<>nil)
   and (not (OneControl is TAnchorDockHostSite)) then begin
     LayoutNode.NodeType:=adltnControl;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,FMinimized);
     LayoutNode.Name:=OneControl.Name;
     LayoutNode.HeaderPosition:=Header.HeaderPosition;
   end else if (SiteType in [adhstLayout,adhstOneControl]) then begin
@@ -5450,7 +5666,7 @@
         Splitter.SaveLayout(ChildNode);
       end;
     end;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,FMinimized);
     LayoutNode.HeaderPosition:=Header.HeaderPosition;
   end else if SiteType=adhstPages then begin
     LayoutNode.NodeType:=adltnPages;
@@ -5461,7 +5677,7 @@
         Site.SaveLayout(LayoutTree,ChildNode);
       end;
     end;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,FMinimized);
     LayoutNode.HeaderPosition:=Header.HeaderPosition;
   end else
     LayoutNode.NodeType:=adltnNone;
@@ -5476,6 +5692,9 @@
 constructor TAnchorDockHostSite.CreateNew(AOwner: TComponent; Num: Integer);
 begin
   inherited CreateNew(AOwner,Num);
+  FMinimized:=false;
+  fMinimization:=false;
+  FMinimizedControl:=Nil;
   Visible:=false;
   FHeaderSide:=akTop;
   FHeader:=DockMaster.HeaderClass.Create(Self);
@@ -5490,13 +5709,13 @@
 end;
 
 destructor TAnchorDockHostSite.Destroy;
-//var i: Integer;
+var i: Integer;
 begin
-  //debugln(['TAnchorDockHostSite.Destroy ',DbgSName(Self),' Caption="',Caption,'" Self=',dbgs(Pointer(Self)),' ComponentCount=',ComponentCount,' ControlCount=',ControlCount]);
-  {for i:=0 to ComponentCount-1 do
+  debugln(['TAnchorDockHostSite.Destroy ',DbgSName(Self),' Caption="',Caption,'" Self=',dbgs(Pointer(Self)),' ComponentCount=',ComponentCount,' ControlCount=',ControlCount]);
+  for i:=0 to ComponentCount-1 do
     debugln(['TAnchorDockHostSite.Destroy Component ',i,'/',ComponentCount,' ',DbgSName(Components[i])]);
   for i:=0 to ControlCount-1 do
-    debugln(['TAnchorDockHostSite.Destroy Control ',i,'/',ControlCount,' ',DbgSName(Controls[i])]);}
+    debugln(['TAnchorDockHostSite.Destroy Control ',i,'/',ControlCount,' ',DbgSName(Controls[i])]);
   FreePages;
   inherited Destroy;
 end;
@@ -5569,6 +5788,13 @@
   end;
 end;
 
+procedure TAnchorDockHeader.MinimizeButtonClick(Sender: TObject);
+begin
+  if Parent is TAnchorDockHostSite then begin
+    TAnchorDockHostSite(Parent).MinimizeSite;
+  end;
+end;
+
 procedure TAnchorDockHeader.HeaderPositionItemClick(Sender: TObject);
 var
   Item: TMenuItem;
@@ -5640,6 +5866,13 @@
       r.Right:=CloseButton.Left-1;
   end;
 
+  if MinimizeButton.IsControlVisible and (MinimizeButton.Parent=Self) then begin
+    if Align in [alLeft,alRight] then
+      r.Top:=MinimizeButton.Top+MinimizeButton.Height+1
+    else
+      r.Right:=MinimizeButton.Left-1;
+  end;
+
   // caption
   if Caption<>'' then begin
     if fFocused and DockMaster.HeaderHighlightFocused and NeedHighlightText then
@@ -5728,7 +5961,14 @@
     end else begin
       PreferredHeight:=Max(NeededHeight,PreferredHeight);
     end;
+  end else begin
+    NeededHeight:=CloseButton.Height;
+    if Align in [alLeft,alRight] then begin
+      PreferredWidth:=Max(NeededHeight,PreferredWidth);
+    end else begin
+      PreferredHeight:=Max(NeededHeight,PreferredHeight);
   end;
+  end;
 end;
 
 procedure TAnchorDockHeader.MouseDown(Button: TMouseButton; Shift: TShiftState;
@@ -5742,11 +5982,15 @@
 procedure TAnchorDockHeader.UpdateHeaderControls;
 begin
   if Align in [alLeft,alRight] then begin
-    if CloseButton<>nil then
+    if CloseButton<>nil then begin
+      MinimizeButton.Align:=alTop;
       CloseButton.Align:=alTop;
+    end;
   end else begin
-    if CloseButton<>nil then
+    if CloseButton<>nil then begin
+      MinimizeButton.Align:=alRight;
       CloseButton.Align:=alRight;
+    end;
   end;
   //debugln(['TAnchorDockHeader.UpdateHeaderControls ',dbgs(Align),' ',dbgs(CloseButton.Align)]);
 end;
@@ -5787,9 +6031,9 @@
 begin
   inherited Create(TheOwner);
   FHeaderPosition:=adlhpAuto;
-  FCloseButton:=TAnchorDockCloseButton.Create(Self);
   BevelOuter:=bvNone;
   BorderWidth:=0;
+  FCloseButton:=TAnchorDockCloseButton.Create(Self);
   with FCloseButton do begin
     Name:='CloseButton';
     Parent:=Self;
@@ -5799,6 +6043,16 @@
     OnClick:=@CloseButtonClick;
     AutoSize:=true;
   end;
+  FMinimizeButton:=TAnchorDockMinimizeButton.Create(Self);
+  with FMinimizeButton do begin
+    Name:='MinimizeButton';
+    Parent:=Self;
+    Flat:=true;
+    ShowHint:=true;
+    Hint:=adrsMinimize;
+    OnClick:=@MinimizeButtonClick;
+    AutoSize:=true;
+  end;
   Align:=alTop;
   AutoSize:=true;
   ShowHint:=true;
@@ -5844,6 +6098,44 @@
   end;
 end;
 
+{ TAnchorDockMinimizeButton }
+
+function TAnchorDockMinimizeButton.GetDrawDetails: TThemedElementDetails;
+
+function WindowPart: TThemedWindow;
+  begin
+    // no check states available
+    Result := twMinButtonNormal;
+    if not IsEnabled then
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonDisabled{$ELSE}twMinButtonDisabled{$ENDIF}
+    else
+    if FState in [bsDown, bsExclusive] then
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonPushed{$ELSE}twMinButtonPushed{$ENDIF}
+    else
+    if FState = bsHot then
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonHot{$ELSE}twMinButtonHot{$ENDIF}
+    else
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonNormal{$ELSE}twMinButtonNormal{$ENDIF};
+  end;
+
+begin
+  Result := ThemeServices.GetElementDetails(WindowPart);
+end;
+
+procedure TAnchorDockMinimizeButton.CalculatePreferredSize(var PreferredWidth,
+  PreferredHeight: integer; WithThemeSpace: Boolean);
+begin
+  with ThemeServices.GetDetailSize(ThemeServices.GetElementDetails({$IFDEF LCLGtk2}twMDIRestoreButtonNormal{$ELSE}twMinButtonNormal{$ENDIF})) do
+  begin
+    PreferredWidth:=cx;
+    PreferredHeight:=cy;
+    {$IF defined(LCLGtk2) or defined(Carbon)}
+    inc(PreferredWidth,2);
+    inc(PreferredHeight,2);
+    {$ENDIF}
+  end;
+end;
+
 { TAnchorDockManager }
 
 procedure TAnchorDockManager.SetPreferredSiteSizeAsSiteMinimum(
@@ -6505,32 +6797,58 @@
 procedure TAnchorDockSplitter.SetBoundsPercentually;
 var
   NewLeft, NewTop: Integer;
+  AControl: TControl;
+  SplitterAnchorKind:TAnchorKind;
 begin
-  if ResizeAnchor in [akLeft,akRight] then
-  begin
-    if DockParentClientSize.cx> 0 then
+  if Enabled then begin
+    if ResizeAnchor in [akLeft,akRight] then
     begin
-      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
-        NewLeft := Round(FPercentPosition*Parent.ClientWidth)
-      else
-        NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
-      NewTop := Top;
-      SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      if DockParentClientSize.cx> 0 then
+      begin
+        if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+          NewLeft := Round(FPercentPosition*Parent.ClientWidth)
+        else
+          NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
+        NewTop := Top;
+        SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      end;
+    end else
+    begin
+      if DockParentClientSize.cy> 0 then
+      begin
+        NewLeft := Left;
+        if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+          NewTop := Round(FPercentPosition*Parent.ClientHeight)
+        else
+          NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+        SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      end;
     end;
-  end else
-  begin
-    if DockParentClientSize.cy> 0 then
-    begin
-      NewLeft := Left;
-      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
-        NewTop := Round(FPercentPosition*Parent.ClientHeight)
-      else
-        NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+    if FPercentPosition < 0 then
+      UpdatePercentPosition;
+  end else begin
+    SplitterAnchorKind:=akTop;
+    AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);
+    if AControl=nil then begin SplitterAnchorKind:=akRight;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+    if AControl=nil then begin SplitterAnchorKind:=akBottom;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+    if AControl=nil then begin SplitterAnchorKind:=akLeft;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+
+    if AControl is TAnchorDockHostSite then begin
+      (AControl as TAnchorDockHostSite).UpdateHeaderAlign;
+      NewTop := (AControl as TAnchorDockHostSite).Header.Left;
+      NewTop := (AControl as TAnchorDockHostSite).Header.Height;
+      NewLeft := left;
+      NewTop := top;
+      (AControl as TAnchorDockHostSite).UpdateHeaderAlign;
+      case SplitterAnchorKind of
+        akTop: NewTop := AControl.Top+(AControl as TAnchorDockHostSite).Header.Height;
+        akBottom: NewTop := AControl.Top+AControl.Height-(AControl as TAnchorDockHostSite).Header.Height-Height;
+        akLeft: NewLeft := AControl.Left+(AControl as TAnchorDockHostSite).Header.Width;
+        akRight: NewLeft := AControl.Left+AControl.Width-(AControl as TAnchorDockHostSite).Header.Width-Width;
+      end;
       SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
     end;
   end;
-  if FPercentPosition < 0 then
-    UpdatePercentPosition;
 end;
 
 function TAnchorDockSplitter.SideAnchoredControlCount(Side: TAnchorKind): integer;
@@ -6562,12 +6880,39 @@
 
 procedure TAnchorDockSplitter.SaveLayout(
   LayoutNode: TAnchorDockLayoutTreeNode);
+var
+  NewLeft, NewTop: Integer;
 begin
   if ResizeAnchor in [akLeft,akRight] then
     LayoutNode.NodeType:=adltnSplitterVertical
   else
     LayoutNode.NodeType:=adltnSplitterHorizontal;
-  LayoutNode.Assign(Self);
+  LayoutNode.Assign(Self,false,false);
+
+  if not Enabled then begin
+    if ResizeAnchor in [akLeft,akRight] then
+    begin
+      if DockParentClientSize.cx> 0 then
+      begin
+        if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+          NewLeft := Round(FPercentPosition*Parent.ClientWidth)
+        else
+          NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
+        NewTop := Top;
+      end;
+    end else
+    begin
+      if DockParentClientSize.cy> 0 then
+      begin
+        NewLeft := Left;
+        if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+          NewTop := Round(FPercentPosition*Parent.ClientHeight)
+        else
+          NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+      end;
+    end;
+    LayoutNode.BoundsRect:=Rect(NewLeft,NewTop,NewLeft+Width,NewTop+Height);
+  end
 end;
 
 function TAnchorDockSplitter.HasOnlyOneSibling(Side: TAnchorKind; MinPos,
Index: components/anchordocking/anchordockoptionsdlg.lfm
===================================================================
--- components/anchordocking/anchordockoptionsdlg.lfm	(revision 59428)
+++ components/anchordocking/anchordockoptionsdlg.lfm	(working copy)
@@ -1,11 +1,13 @@
 object AnchorDockOptionsFrame: TAnchorDockOptionsFrame
   Left = 0
-  Height = 482
+  Height = 567
   Top = 0
-  Width = 416
-  ClientHeight = 482
-  ClientWidth = 416
+  Width = 490
+  ClientHeight = 567
+  ClientWidth = 490
+  DesignTimePPI = 113
   OnClick = FrameClick
+  ParentFont = False
   TabOrder = 0
   DesignLeft = 513
   DesignTop = 189
@@ -12,14 +14,15 @@
   object DragThresholdLabel: TLabel
     AnchorSideLeft.Control = Owner
     AnchorSideTop.Control = Owner
-    Left = 10
-    Height = 13
-    Top = 10
-    Width = 111
-    BorderSpacing.Left = 10
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 12
+    Width = 122
+    BorderSpacing.Left = 12
+    BorderSpacing.Top = 12
     Caption = 'DragThresholdLabel'
     ParentColor = False
+    ParentFont = False
   end
   object DragThresholdTrackBar: TTrackBar
     AnchorSideLeft.Control = DragThresholdLabel
@@ -27,15 +30,16 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = Owner
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 46
-    Top = 23
-    Width = 396
+    Left = 12
+    Height = 54
+    Top = 31
+    Width = 466
     Max = 20
     OnChange = DragThresholdTrackBarChange
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Right = 10
+    BorderSpacing.Right = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 1
@@ -46,12 +50,13 @@
     AnchorSideTop.Control = DragThresholdLabel
     AnchorSideTop.Side = asrCenter
     AnchorSideRight.Control = Owner
-    Left = 127
-    Height = 23
-    Top = 5
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 141
+    Height = 27
+    Top = 8
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 20
+    ParentFont = False
     TabOrder = 0
     Visible = False
   end
@@ -59,13 +64,14 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = DragThresholdTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 79
-    Width = 103
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 97
+    Width = 112
+    BorderSpacing.Top = 12
     Caption = 'SplitterWidthLabel'
     ParentColor = False
+    ParentFont = False
   end
   object SplitterWidthTrackBar: TTrackBar
     AnchorSideLeft.Control = DragThresholdTrackBar
@@ -73,14 +79,15 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 46
-    Top = 92
-    Width = 396
+    Left = 12
+    Height = 54
+    Top = 116
+    Width = 466
     Min = 1
     OnChange = SplitterWidthTrackBarChange
     Position = 1
     Anchors = [akTop, akLeft, akRight]
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 3
@@ -89,12 +96,13 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = SplitterWidthTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 24
-    Top = 142
-    Width = 160
-    BorderSpacing.Top = 4
+    Left = 12
+    Height = 23
+    Top = 175
+    Width = 169
+    BorderSpacing.Top = 5
     Caption = 'ScaleOnResizeCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 4
@@ -103,12 +111,13 @@
     AnchorSideLeft.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 24
-    Top = 166
-    Width = 149
+    Left = 12
+    Height = 23
+    Top = 198
+    Width = 160
     Caption = 'ShowHeaderCheckBox'
     OnChange = ShowHeaderCheckBoxChange
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 5
@@ -117,12 +126,13 @@
     AnchorSideLeft.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Control = ShowHeaderCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 190
-    Width = 191
-    BorderSpacing.Left = 15
+    Left = 30
+    Height = 23
+    Top = 221
+    Width = 208
+    BorderSpacing.Left = 18
     Caption = 'ShowHeaderCaptionCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 6
@@ -131,11 +141,12 @@
     AnchorSideLeft.Control = ShowHeaderCaptionCheckBox
     AnchorSideTop.Control = ShowHeaderCaptionCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 214
-    Width = 249
+    Left = 30
+    Height = 23
+    Top = 244
+    Width = 272
     Caption = 'HideHeaderCaptionForFloatingCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 7
@@ -147,15 +158,16 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = Owner
     AnchorSideRight.Side = asrBottom
-    Left = 122
+    Left = 136
     Height = 27
-    Top = 286
-    Width = 284
+    Top = 313
+    Width = 342
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 6
-    BorderSpacing.Right = 10
-    ItemHeight = 0
+    BorderSpacing.Left = 7
+    BorderSpacing.Right = 12
+    ItemHeight = 19
     OnDrawItem = HeaderStyleComboBoxDrawItem
+    ParentFont = False
     Style = csDropDownList
     TabOrder = 10
   end
@@ -163,23 +175,25 @@
     AnchorSideLeft.Control = ShowHeaderCheckBox
     AnchorSideTop.Control = HeaderStyleComboBox
     AnchorSideTop.Side = asrCenter
-    Left = 20
-    Height = 13
-    Top = 293
-    Width = 96
-    BorderSpacing.Left = 10
+    Left = 24
+    Height = 19
+    Top = 317
+    Width = 105
+    BorderSpacing.Left = 12
     Caption = 'HeaderStyleLabel'
     ParentColor = False
+    ParentFont = False
   end
   object FlattenHeadersCheckBox: TCheckBox
     AnchorSideLeft.Control = HideHeaderCaptionForFloatingCheckBox
     AnchorSideTop.Control = HideHeaderCaptionForFloatingCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 238
-    Width = 164
+    Left = 30
+    Height = 23
+    Top = 267
+    Width = 175
     Caption = 'FlattenHeadersCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 8
@@ -188,11 +202,12 @@
     AnchorSideLeft.Control = FlattenHeadersCheckBox
     AnchorSideTop.Control = FlattenHeadersCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 262
-    Width = 154
+    Left = 30
+    Height = 23
+    Top = 290
+    Width = 164
     Caption = 'FilledHeadersCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 9
@@ -201,11 +216,12 @@
     AnchorSideLeft.Control = FilledHeadersCheckBox
     AnchorSideTop.Control = HeaderStyleComboBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 313
-    Width = 175
+    Left = 30
+    Height = 23
+    Top = 340
+    Width = 189
     Caption = 'HighlightFocusedCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 11
@@ -215,13 +231,14 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = SplitterWidthLabel
     AnchorSideTop.Side = asrCenter
-    Left = 119
-    Height = 23
-    Top = 74
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 131
+    Height = 27
+    Top = 93
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 10
     MinValue = 1
+    ParentFont = False
     TabOrder = 2
     Value = 1
     Visible = False
@@ -228,15 +245,16 @@
   end
   object HeaderAlignTopLabel: TLabel
     AnchorSideLeft.Control = DragThresholdLabel
-    AnchorSideTop.Control = HighlightFocusedCheckBox
+    AnchorSideTop.Control = DockSitesCanBeMinimized
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 347
-    Width = 117
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 398
+    Width = 130
+    BorderSpacing.Top = 12
     Caption = 'HeaderAlignTopLabel'
     ParentColor = False
+    ParentFont = False
   end
   object HeaderAlignTopTrackBar: TTrackBar
     AnchorSideLeft.Control = Owner
@@ -244,10 +262,10 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 47
-    Top = 360
-    Width = 396
+    Left = 12
+    Height = 55
+    Top = 417
+    Width = 466
     Frequency = 10
     Max = 150
     OnChange = HeaderAlignTopTrackBarChange
@@ -254,7 +272,8 @@
     PageSize = 10
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 10
+    BorderSpacing.Left = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 13
@@ -264,12 +283,13 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = HeaderAlignTopLabel
     AnchorSideTop.Side = asrCenter
-    Left = 133
-    Height = 23
-    Top = 342
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 149
+    Height = 27
+    Top = 394
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 150
+    ParentFont = False
     TabOrder = 12
     Visible = False
   end
@@ -277,13 +297,14 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = HeaderAlignTopTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 417
-    Width = 120
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 484
+    Width = 130
+    BorderSpacing.Top = 12
     Caption = 'HeaderAlignLeftLabel'
     ParentColor = False
+    ParentFont = False
   end
   object HeaderAlignLeftTrackBar: TTrackBar
     AnchorSideLeft.Control = Owner
@@ -291,10 +312,10 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 47
-    Top = 430
-    Width = 396
+    Left = 12
+    Height = 55
+    Top = 503
+    Width = 466
     Frequency = 10
     Max = 200
     OnChange = HeaderAlignLeftTrackBarChange
@@ -301,7 +322,8 @@
     PageSize = 10
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 10
+    BorderSpacing.Left = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 15
@@ -311,13 +333,28 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = HeaderAlignLeftLabel
     AnchorSideTop.Side = asrCenter
-    Left = 136
-    Height = 23
-    Top = 412
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 149
+    Height = 27
+    Top = 480
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 200
+    ParentFont = False
     TabOrder = 14
     Visible = False
   end
+  object DockSitesCanBeMinimized: TCheckBox
+    AnchorSideLeft.Control = FilledHeadersCheckBox
+    AnchorSideTop.Control = HighlightFocusedCheckBox
+    AnchorSideTop.Side = asrBottom
+    Left = 30
+    Height = 23
+    Top = 363
+    Width = 185
+    Caption = 'DockSitesCanBeMinimized'
+    ParentFont = False
+    ParentShowHint = False
+    ShowHint = True
+    TabOrder = 16
+  end
 end
Index: components/anchordocking/anchordockoptionsdlg.pas
===================================================================
--- components/anchordocking/anchordockoptionsdlg.pas	(revision 59428)
+++ components/anchordocking/anchordockoptionsdlg.pas	(working copy)
@@ -37,6 +37,7 @@
     HeaderStyleLabel: TLabel;
     HideHeaderCaptionForFloatingCheckBox: TCheckBox;
     HighlightFocusedCheckBox: TCheckBox;
+    DockSitesCanBeMinimized: TCheckBox;
     ScaleOnResizeCheckBox: TCheckBox;
     ShowHeaderCaptionCheckBox: TCheckBox;
     ShowHeaderCheckBox: TCheckBox;
@@ -299,6 +300,7 @@
   HeaderStyleLabel.Enabled:=HasHeaders;
   HeaderStyleComboBox.Enabled:=HasHeaders;
   HighlightFocusedCheckBox.Enabled:=HasHeaders;
+  DockSitesCanBeMinimized.Enabled:=HasHeaders;
 end;
 
 constructor TAnchorDockOptionsFrame.Create(TheOwner: TComponent);
@@ -356,6 +358,7 @@
   TheSettings.HeaderFilled:=FilledHeadersCheckBox.Checked;
   TheSettings.HeaderStyle:=TADHeaderStyle(HeaderStyleComboBox.ItemIndex);
   TheSettings.HeaderHighlightFocused:=HighlightFocusedCheckBox.Checked;
+  TheSettings.DockSitesCanBeMinimized:=DockSitesCanBeMinimized.Checked;
 end;
 
 procedure TAnchorDockOptionsFrame.LoadFromSettings(
@@ -429,6 +432,10 @@
   HighlightFocusedCheckBox.Checked:=TheSettings.HeaderHighlightFocused;
   HighlightFocusedCheckBox.Caption:=adrsHighlightFocused;
   HighlightFocusedCheckBox.Hint:=adrsHighlightFocusedHint;
+
+  DockSitesCanBeMinimized.Checked:=TheSettings.DockSitesCanBeMinimized;
+  DockSitesCanBeMinimized.Caption:=adrsDockSitesCanBeMinimized;
+  DockSitesCanBeMinimized.Hint:=adrsDockSitesCanBeMinimizedHint;
 end;
 
 end.
Index: components/anchordocking/anchordockpanel.pas
===================================================================
--- components/anchordocking/anchordockpanel.pas	(revision 59428)
+++ components/anchordocking/anchordockpanel.pas	(working copy)
@@ -55,7 +55,7 @@
   begin
 
     LayoutNode.NodeType:=adltnControl;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,false);
     LayoutNode.Name:={OneControl.}Name;
 
     TAnchorDockHostSite(OneControl).SaveLayout(LayoutTree,LayoutNode);
Index: components/anchordocking/anchordockstorage.pas
===================================================================
--- components/anchordocking/anchordockstorage.pas	(revision 59428)
+++ components/anchordocking/anchordockstorage.pas	(working copy)
@@ -64,6 +64,7 @@
     FTabPosition: TTabPosition;
     FWindowState: TWindowState;
     FControlLocation: TADLControlLocation;
+    FMinimized: Boolean;
     function GetAnchors(Site: TAnchorKind): string;
     function GetBottom: integer;
     function GetHeight: integer;
@@ -90,6 +91,7 @@
     procedure SetTop(const AValue: integer);
     procedure SetWidth(const AValue: integer);
     procedure SetWindowState(const AValue: TWindowState);
+    procedure SetMinimized(const AValue: boolean);
   public
     constructor Create;
     destructor Destroy; override;
@@ -96,7 +98,7 @@
     procedure Clear;
     function IsEqual(Node: TAnchorDockLayoutTreeNode): boolean;
     procedure Assign(Node: TAnchorDockLayoutTreeNode); overload;
-    procedure Assign(AControl: TControl; OverrideBoundsRect: Boolean=false); overload;
+    procedure Assign(AControl: TControl; OverrideBoundsRect: Boolean; AMinimized: Boolean); overload;
     procedure LoadFromConfig(Config: TConfigStorage); overload;
     procedure LoadFromConfig(Path: string; Config: TRttiXMLConfig); overload;
     procedure SaveToConfig(Config: TConfigStorage); overload;
@@ -106,7 +108,7 @@
     procedure CheckConsistency; virtual;
 
     // simplifying
-    procedure Simplify(ExistingNames: TStrings);
+    procedure Simplify(ExistingNames: TStrings; ParentMinimized:boolean);
     procedure DeleteNode(ChildNode: TAnchorDockLayoutTreeNode);
     function FindNodeBoundSplitter(ChildNode: TAnchorDockLayoutTreeNode;
                                    Side: TAnchorKind): TAnchorDockLayoutTreeNode;
@@ -135,6 +137,7 @@
     property Monitor: integer read FMonitor write SetMonitor;
     property HeaderPosition: TADLHeaderPosition read FHeaderPosition write SetHeaderPosition;
     property TabPosition: TTabPosition read FTabPosition write SetTabPosition;
+    property Minimized: Boolean read FMinimized write SetMinimized;
     function Count: integer;
     function IsSplitter: boolean;
     function IsRootWindow: boolean;
@@ -988,6 +991,13 @@
   IncreaseChangeStamp;
 end;
 
+procedure TAnchorDockLayoutTreeNode.SetMinimized(const AValue: boolean);
+begin
+  if FMinimized=AValue then exit;
+  FMinimized:=AValue;
+  IncreaseChangeStamp;
+end;
+
 procedure TAnchorDockLayoutTreeNode.SetTop(const AValue: integer);
 begin
   if Top=AValue then exit;
@@ -1084,6 +1094,7 @@
   BoundSplitterPos:=Node.BoundSplitterPos;
   WorkAreaRect:=Node.WorkAreaRect;
   Monitor:=Node.Monitor;
+  Minimized:=Node.Minimized;
   for a:=low(TAnchorKind) to high(TAnchorKind) do
     Anchors[a]:=Node.Anchors[a];
   while Count>Node.Count do Nodes[Count-1].Free;
@@ -1098,9 +1109,10 @@
   end;
 end;
 
-procedure TAnchorDockLayoutTreeNode.Assign(AControl: TControl; OverrideBoundsRect: Boolean=false);
+procedure TAnchorDockLayoutTreeNode.Assign(AControl: TControl; OverrideBoundsRect: Boolean; AMinimized: Boolean);
 var
   AnchorControl: TControl;
+  ParentForm:TCustomForm;
   a: TAnchorKind;
 begin
   Name:=AControl.Name;
@@ -1109,12 +1121,18 @@
   else
     BoundsRect:=AControl.BoundsRect;
   Align:=AControl.Align;
+  Minimized:=AMinimized;
   if (AControl.Parent=nil) and (AControl is TCustomForm) then begin
     WindowState:=TCustomForm(AControl).WindowState;
     Monitor:=TCustomForm(AControl).Monitor.MonitorNum;
     WorkAreaRect:=TCustomForm(AControl).Monitor.WorkareaRect;
-  end else
-    WindowState:=GetParentForm(AControl).WindowState;
+  end else begin
+    ParentForm:=GetParentForm(AControl);
+    if assigned(ParentForm) then
+      WindowState:=ParentForm.WindowState
+    else
+      WindowState:=wsNormal;
+  end;
   if AControl is TCustomTabControl then
     TabPosition:=TCustomTabControl(AControl).TabPosition
   else
@@ -1137,6 +1155,7 @@
   Clear;
   Name:=Config.GetValue('Name','');
   NodeType:=NameToADLTreeNodeType(Config.GetValue('Type',ADLTreeNodeTypeNames[adltnNone]));
+  Minimized:=Config.GetValue('Minimized',false);
   Left:=Config.GetValue('Bounds/Left',0);
   Top:=Config.GetValue('Bounds/Top',0);
   Width:=Config.GetValue('Bounds/Width',0);
@@ -1171,6 +1190,7 @@
   Clear;
   Name:=Config.GetValue(Path+'Name','');
   NodeType:=NameToADLTreeNodeType(Config.GetValue(Path+'Type',ADLTreeNodeTypeNames[adltnNone]));
+  Minimized:=Config.GetValue(Path+'Minimized',false);
   Left:=Config.GetValue(Path+'Bounds/Left',0);
   Top:=Config.GetValue(Path+'Bounds/Top',0);
   Width:=Config.GetValue(Path+'Bounds/Width',0);
@@ -1219,6 +1239,7 @@
                                           ADLHeaderPositionNames[adlhpAuto]);
   Config.SetDeleteValue('Header/TabPosition',ADLTabPostionNames[TabPosition],
                                              ADLTabPostionNames[tpTop]);
+  Config.SetDeleteValue('Minimized',Minimized,False);
   Config.SetDeleteValue('Monitor',Monitor,0);
   Config.SetDeleteValue('ChildCount',Count,0);
   for i:=1 to Count do begin
@@ -1252,6 +1273,7 @@
                                                ADLHeaderPositionNames[adlhpAuto]);
   Config.SetDeleteValue(Path+'Header/TabPosition',ADLTabPostionNames[TabPosition],
                                                   ADLTabPostionNames[tpTop]);
+  Config.SetDeleteValue(Path+'Minimized',Minimized,False);
   Config.SetDeleteValue(Path+'Monitor',Monitor,0);
   Config.SetDeleteValue(Path+'ChildCount',Count,0);
   for i:=1 to Count do
@@ -1397,7 +1419,7 @@
   end;
 end;
 
-procedure TAnchorDockLayoutTreeNode.Simplify(ExistingNames: TStrings);
+procedure TAnchorDockLayoutTreeNode.Simplify(ExistingNames: TStrings; ParentMinimized:boolean);
 { Simplification rules:
    1. Control nodes without existing name are deleted.
    2. Empty layouts and pages are deleted
@@ -1406,16 +1428,18 @@
 var
   i: Integer;
   ChildNode: TAnchorDockLayoutTreeNode;
+  NodeMinimized:boolean;
 begin
   // simplify children
   i:=Count-1;
   while i>=0 do begin
     ChildNode:=Nodes[i];
-    ChildNode.Simplify(ExistingNames);
+    NodeMinimized:=ParentMinimized or ChildNode.Minimized;
+    ChildNode.Simplify(ExistingNames,NodeMinimized);
 
     if (ChildNode.NodeType=adltnControl) then begin
       // leaf node => check if there is a control
-      if (ChildNode.Name='') or (ExistingNames.IndexOf(ChildNode.Name)<0) then
+      if (ChildNode.Name='') or ((ExistingNames.IndexOf(ChildNode.Name)<0) and (not NodeMinimized)) then
         DeleteNode(ChildNode);
     end else if ChildNode.IsSplitter then begin
       // splitter
@@ -1424,7 +1448,7 @@
         ChildNode[0].Free;
     end else if ChildNode.NodeType=adltnCustomSite then begin
       // custom dock site
-    end else if ChildNode.Count=0 then begin
+    end else if (ChildNode.Count=0)and(not NodeMinimized) then begin
       // inner node without child => delete
       DeleteNode(ChildNode);
     end else if (ChildNode.Count=1)
Index: components/anchordocking/anchordockstr.pas
===================================================================
--- components/anchordocking/anchordockstr.pas	(revision 59428)
+++ components/anchordocking/anchordockstr.pas	(working copy)
@@ -8,6 +8,7 @@
 
 resourcestring
   adrsClose = 'Close';
+  adrsMinimize = 'Minimize';
   adrsQuit = 'Quit %s';
   adrsTabPosition = 'Tab position';
   adrsMovePageRight = 'Move page right';
@@ -82,6 +83,8 @@
   adrsFilledHeadersHint = 'Fill headers of docked controls';
   adrsHighlightFocused = 'Highlight focused';
   adrsHighlightFocusedHint = 'Highlight header of focused docked control';
+  adrsDockSitesCanBeMinimized = 'Dock sites can be minimized';
+  adrsDockSitesCanBeMinimizedHint = 'Dock sites can be minimized';
 
 implementation
 
Index: components/anchordocking/design/anchordesktopoptions.pas
===================================================================
--- components/anchordocking/design/anchordesktopoptions.pas	(revision 59428)
+++ components/anchordocking/design/anchordesktopoptions.pas	(working copy)
@@ -272,7 +272,7 @@
         // custom dock site
         LayoutNode:=FTree.NewNode(FTree.Root);
         LayoutNode.NodeType:=adltnCustomSite;
-        LayoutNode.Assign(AForm);
+        LayoutNode.Assign(AForm,false,false);
         // can have one normal dock site
         Site:=TAnchorDockManager(AForm.DockManager).GetChildSite;
         if Site<>nil then begin
@@ -287,7 +287,7 @@
         raise EAnchorDockLayoutError.Create('invalid root control for save: '+DbgSName(AControl));
     end;
     // remove invisible controls
-    FTree.Root.Simplify(VisibleControls);
+    FTree.Root.Simplify(VisibleControls,false);
   finally
     VisibleControls.Free;
     SavedSites.Free;

Andrey Zubarev

2018-11-06 07:18

reporter   ~0111804

anchordocking_minimize_docksite5.patch - now minimized sites can be saved\restored. Please test

Andrey Zubarev

2018-11-07 11:26

reporter  

anchordocking_minimize_docksite6.patch (64,863 bytes)   
Index: components/anchordocking/anchordocking.pas
===================================================================
--- components/anchordocking/anchordocking.pas	(revision 59428)
+++ components/anchordocking/anchordocking.pas	(working copy)
@@ -92,9 +92,9 @@
 {$mode objfpc}{$H+}
 
 { $DEFINE VerboseAnchorDockRestore}
-{ $DEFINE VerboseADCustomSite}
-{ $DEFINE VerboseAnchorDockPages}
-{ $DEFINE VerboseAnchorDocking}
+{$DEFINE VerboseADCustomSite}
+{$DEFINE VerboseAnchorDockPages}
+{$DEFINE VerboseAnchorDocking}
 
 interface
 
@@ -109,6 +109,10 @@
 const ADAutoSizingReason = 'TAnchorDockMaster Delayed';
 {$ENDIF}
 
+const EmptyMouseTimeStartX=low(Integer);
+      MouseNoMoveDelta=5;
+      MouseNoMoveTime=500;
+
 type
   TAnchorDockHostSite = class;
 
@@ -123,6 +127,14 @@
            PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
   end;
 
+  TAnchorDockMinimizeButton = class(TCustomSpeedButton)
+  protected
+    function GetDrawDetails: TThemedElementDetails; override;
+    procedure CalculatePreferredSize(var PreferredWidth,
+           PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
+  end;
+
+
   { TAnchorDockHeader
     The panel of a TAnchorDockHostSite containing the close button and the
     caption when the form is docked. The header can be shown at any of the four
@@ -133,9 +145,12 @@
   TAnchorDockHeader = class(TCustomPanel)
   private
     FCloseButton: TCustomSpeedButton;
+    FMinimizeButton: TCustomSpeedButton;
     FHeaderPosition: TADLHeaderPosition;
     fFocused:Boolean;
+    FMouseTimeStartX,FMouseTimeStartY:Integer;
     procedure CloseButtonClick(Sender: TObject);
+    procedure MinimizeButtonClick(Sender: TObject);
     procedure HeaderPositionItemClick(Sender: TObject);
     procedure UndockButtonClick(Sender: TObject);
     procedure MergeButtonClick(Sender: TObject);
@@ -147,6 +162,11 @@
           PreferredHeight: integer; WithThemeSpace: Boolean); override;
     procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X,
              Y: Integer); override;
+    procedure MouseMove(Shift: TShiftState; X,Y: Integer); override;
+    procedure MouseLeave;  override;
+    procedure StartMouseNoMoveTimer(X, Y: Integer);
+    procedure StopMouseNoMoveTimer;
+    procedure DoMouseNoMoveTimer(Sender: TObject);
     procedure UpdateHeaderControls;
     procedure SetAlign(Value: TAlign); override;
     procedure DoOnShowHint(HintInfo: PHintInfo); override;
@@ -154,6 +174,7 @@
   public
     constructor Create(TheOwner: TComponent); override;
     property CloseButton: TCustomSpeedButton read FCloseButton;
+    property MinimizeButton: TCustomSpeedButton read FMinimizeButton;
     property HeaderPosition: TADLHeaderPosition read FHeaderPosition write SetHeaderPosition;
     property BevelOuter default bvNone;
   end;
@@ -190,6 +211,7 @@
     procedure SetBoundsKeepDockBounds(ALeft, ATop, AWidth, AHeight: integer); // movement for scaling keeps the DockBounds
     function SideAnchoredControlCount(Side: TAnchorKind): integer;
     function HasAnchoredControls: boolean;
+    function GetSpliterBoundsWithUnminimizedDockSites:TRect;
     procedure SaveLayout(LayoutNode: TAnchorDockLayoutTreeNode);
     function HasOnlyOneSibling(Side: TAnchorKind; MinPos, MaxPos: integer): TControl;
     property DockRestoreBounds: TRect read FDockRestoreBounds write FDockRestoreBounds;
@@ -241,6 +263,15 @@
   end;
   TAnchorDockPageControlClass = class of TAnchorDockPageControl;
 
+
+  TAnchorDockOverlappingForm = class(TCustomForm)
+  protected
+    procedure MouseLeave;  override;
+  public
+    AnchorDockHostSite:TAnchorDockHostSite;
+    constructor CreateNew(AOwner: TComponent; Num: Integer = 0); override;
+  end;
+
   { TAnchorDockHostSite
     This form is the dockhostsite for all controls.
     When docked together they build a tree structure with the docked controls
@@ -262,7 +293,11 @@
     FPages: TAnchorDockPageControl;
     FSiteType: TAnchorDockHostSiteType;
     FBoundSplitter: TAnchorDockSplitter;
-    fUpdateLayout: integer;
+    fUpdateLayout: Integer;
+    FMinimized: Boolean;
+    fMinimization: Boolean;
+    FMinimizedControl: TControl;
+    //OverlappingForm:TAnchorDockOverlappingForm;
     procedure SetHeaderSide(const AValue: TAnchorKind);
   protected
     procedure DoEnter; override;
@@ -319,6 +354,10 @@
     destructor Destroy; override;
     function CloseQuery: boolean; override;
     function CloseSite: boolean; virtual;
+    procedure MinimizeSite; virtual;
+    procedure AsyncMinimizeSite(Data: PtrInt);
+    procedure ShowMinimizedControl;
+    procedure HideMinimizedControl;
     procedure RemoveControl(AControl: TControl); override;
     procedure InsertControl(AControl: TControl; Index: integer); override;
     procedure GetSiteInfo(Client: TControl; var InfluenceRect: TRect;
@@ -431,6 +470,7 @@
     FShowHeader: boolean;
     FShowHeaderCaption: boolean;
     FSplitterWidth: integer;
+    FDockSitecCanBeMinimized: boolean;
     procedure SetAllowDragging(AValue: boolean);
     procedure SetDockOutsideMargin(AValue: integer);
     procedure SetDockParentMargin(AValue: integer);
@@ -448,6 +488,7 @@
     procedure SetHeaderFlatten(AValue: boolean);
     procedure SetHeaderFilled(AValue: boolean);
     procedure SetHeaderHighlightFocused(AValue: boolean);
+    procedure SetDockSitecCanBeMinimized(AValue: boolean);
   public
     property DragTreshold: integer read FDragTreshold write SetDragTreshold;
     property DockOutsideMargin: integer read FDockOutsideMargin write SetDockOutsideMargin;
@@ -466,6 +507,7 @@
     property HeaderFlatten: boolean read FHeaderFlatten write SetHeaderFlatten;
     property HeaderFilled: boolean read FHeaderFilled write SetHeaderFilled;
     property HeaderHighlightFocused: boolean read FHeaderHighlightFocused write SetHeaderHighlightFocused;
+    property DockSitesCanBeMinimized: boolean read FDockSitecCanBeMinimized write SetDockSitecCanBeMinimized;
     procedure IncreaseChangeStamp; inline;
     property ChangeStamp: integer read FChangeStamp;
     procedure LoadFromConfig(Config: TConfigStorage); overload;
@@ -502,6 +544,7 @@
     FHeaderFlatten: boolean;
     FHeaderFilled: boolean;
     FHeaderHighlightFocused: boolean;
+    FDockSitesCanBeMinimized: boolean;
     FIdleConnected: Boolean;
     FManagerClass: TAnchorDockManagerClass;
     FOnCreateControl: TADCreateControlEvent;
@@ -531,6 +574,7 @@
     fPopupMenu: TPopupMenu;
     // Used by RestoreLayout:
     WorkArea, SrcWorkArea: TRect;
+    FOverlappingForm:TAnchorDockOverlappingForm;
 
     function GetControls(Index: integer): TControl;
     function GetLocalizedHeaderHint: string;
@@ -541,6 +585,8 @@
     function GetNodeSite(Node: TAnchorDockLayoutTreeNode): TAnchorDockHostSite;
     procedure MapTreeToControls(Tree: TAnchorDockLayoutTree);
     function RestoreLayout(Tree: TAnchorDockLayoutTree; Scale: boolean): boolean;
+    procedure SetMinimizedState(Tree: TAnchorDockLayoutTree);
+    procedure SetnodeMinimizedState(ANode: TAnchorDockLayoutTreeNode);
     procedure EnableAllAutoSizing;
     procedure ClearLayoutProperties(AControl: TControl; NewAlign: TAlign = alClient);
     procedure PopupMenuPopup(Sender: TObject);
@@ -561,6 +607,7 @@
     procedure SetHeaderFlatten(AValue: boolean);
     procedure SetHeaderFilled(AValue: boolean);
     procedure SetHeaderHighlightFocused(AValue: boolean);
+    procedure SetDockSitesCanBeMinimized(AValue: boolean);
 
     procedure SetShowMenuItemShowHeader(AValue: boolean);
     procedure SetupSite(Site: TWinControl; ANode: TAnchorDockLayoutTreeNode;
@@ -586,6 +633,8 @@
     procedure OnIdle(Sender: TObject; var Done: Boolean);
     procedure AsyncSimplify({%H-}Data: PtrInt);
   public
+    procedure ShowOverlappingForm;
+    procedure HideOverlappingForm;
     constructor Create(AOwner: TComponent); override;
     destructor Destroy; override;
     function FullRestoreLayout(Tree: TAnchorDockLayoutTree; Scale: Boolean): Boolean;
@@ -680,6 +729,7 @@
     property HeaderFlatten: boolean read FHeaderFlatten write SetHeaderFlatten default true;
     property HeaderFilled: boolean read FHeaderFilled write SetHeaderFilled default true;
     property HeaderHighlightFocused: boolean read FHeaderHighlightFocused write SetHeaderHighlightFocused default false;
+    property DockSitesCanBeMinimized: boolean read FDockSitesCanBeMinimized write SetDockSitesCanBeMinimized default false;
 
     property SplitterWidth: integer read FSplitterWidth write SetSplitterWidth default 4;
     property ScaleOnResize: boolean read FScaleOnResize write SetScaleOnResize default true; // scale children when resizing a site
@@ -698,6 +748,7 @@
 
 var
   DockMaster: TAnchorDockMaster = nil;
+  MouseNoMoveTimer: TTimer = nil;
 
 const
   ADHeaderStyleNames: array[TADHeaderStyle] of string = (
@@ -970,6 +1021,27 @@
   end;
 end;
 
+function CountAndReturnOnlyOneMinimizedAnchoredControls(Control: TControl; Side: TAnchorKind): TAnchorDockHostSite;
+var
+  i,Counter: Integer;
+  Neighbour: TControl;
+begin
+  Counter:=0;
+  for i:=0 to Control.AnchoredControlCount-1 do begin
+    Neighbour:=Control.AnchoredControls[i];
+    if Neighbour.Visible then
+    if Neighbour is TAnchorDockHostSite then
+    if (OppositeAnchor[Side] in Neighbour.Anchors)
+    and (Neighbour.AnchorSide[OppositeAnchor[Side]].Control=Control) then begin
+      inc(Counter);
+      result:=TAnchorDockHostSite(Neighbour);
+    end;
+  end;
+  if (Counter=1)and(result is TAnchorDockHostSite)and((result as TAnchorDockHostSite).FMinimized) then
+  else
+    result:=Nil;
+end;
+
 function NeighbourCanBeShrinked(EnlargeControl, Neighbour: TControl;
   Side: TAnchorKind): boolean;
 { returns true if Neighbour can be shrinked on the opposite side of Side
@@ -1361,6 +1433,13 @@
   IncreaseChangeStamp;
 end;
 
+procedure TAnchorDockSettings.SetDockSitecCanBeMinimized(AValue: boolean);
+begin
+  if FDockSitecCanBeMinimized=AValue then Exit;
+  FDockSitecCanBeMinimized:=AValue;
+  IncreaseChangeStamp;
+end;
+
 procedure TAnchorDockSettings.Assign(Source: TAnchorDockSettings);
 begin
   FAllowDragging := Source.FAllowDragging;
@@ -1381,6 +1460,7 @@
   FShowHeaderCaption := Source.FShowHeaderCaption;
   FSplitterWidth := Source.FSplitterWidth;
   FHeaderHighlightFocused:=Source.FHeaderHighlightFocused;
+  FDockSitecCanBeMinimized:=Source.FDockSitecCanBeMinimized;
 end;
 
 procedure TAnchorDockSettings.IncreaseChangeStamp;
@@ -1407,6 +1487,7 @@
   HeaderFlatten:=Config.GetValue('HeaderFlatten',true);
   HeaderFilled:=Config.GetValue('HeaderFilled',true);
   HeaderHighlightFocused:=Config.GetValue('HeaderHighlightFocused',False);
+  DockSitesCanBeMinimized:=Config.GetValue('DockSitecCanBeMinimized',False);
   Config.UndoAppendBasePath;
 end;
 
@@ -1429,6 +1510,7 @@
   Config.SetDeleteValue(Path+'HeaderFlatten',HeaderFlatten,true);
   Config.SetDeleteValue(Path+'HeaderFilled',HeaderFilled,true);
   Config.SetDeleteValue(Path+'HeaderHighlightFocused',HeaderHighlightFocused,False);
+  Config.SetDeleteValue(Path+'DockSitecCanBeMinimized',DockSitesCanBeMinimized,False);
 end;
 
 procedure TAnchorDockSettings.SaveToConfig(Config: TConfigStorage);
@@ -1450,6 +1532,7 @@
   Config.SetDeleteValue('HeaderFlatten',HeaderFlatten,true);
   Config.SetDeleteValue('HeaderFilled',HeaderFilled,true);
   Config.SetDeleteValue('HeaderHighlightFocused',HeaderHighlightFocused,False);
+  Config.SetDeleteValue('DockSitecCanBeMinimized',DockSitesCanBeMinimized,False);
   Config.UndoAppendBasePath;
 end;
 
@@ -1472,6 +1555,7 @@
       and (HeaderFlatten=Settings.HeaderFlatten)
       and (HeaderFilled=Settings.HeaderFilled)
       and (HeaderHighlightFocused=Settings.HeaderHighlightFocused)
+      and (DockSitesCanBeMinimized=Settings.DockSitesCanBeMinimized)
       ;
 end;
 
@@ -1494,6 +1578,7 @@
   HeaderFlatten:=Config.GetValue(Path+'HeaderFlatten',true);
   HeaderFilled:=Config.GetValue(Path+'HeaderFilled',true);
   HeaderHighlightFocused:=Config.GetValue(Path+'HeaderHighlightFocused',False);
+  DockSitesCanBeMinimized:=Config.GetValue(Path+'DockSitecCanBeMinimized',False);
 end;
 
 { TAnchorDockMaster }
@@ -2021,6 +2106,8 @@
     aHostSite:=TAnchorDockHostSite(Site);
     aHostSite.Header.HeaderPosition:=ANode.HeaderPosition;
     aHostSite.DockRestoreBounds:=NewBounds;
+    //aHostSite.FMinimized:=ANode.Minimized;
+    //we update aHostSite.FMinimized in TAnchorDockMaster.SetMinimizedState
     if (ANode.NodeType<>adltnPages) and (aHostSite.Pages<>nil) then
       aHostSite.FreePages;
   end;
@@ -2040,6 +2127,25 @@
   fTreeNameToDocker[Node.Name]:=Result;
 end;
 
+procedure TAnchorDockMaster.SetNodeMinimizedState(ANode: TAnchorDockLayoutTreeNode);
+var
+  HostSite:TAnchorDockHostSite;
+  i:integer;
+begin
+  HostSite:=GetNodeSite(ANode);
+  if Assigned(HostSite) then
+    if HostSite.FMinimized<>ANode.Minimized then
+      Application.QueueAsyncCall(@HostSite.AsyncMinimizeSite,0);
+      //HostSite.MinimizeSite;
+  for i:=0 to ANode.Count-1 do
+    SetnodeMinimizedState(ANode.Nodes[i]);
+end;
+
+procedure TAnchorDockMaster.SetMinimizedState(Tree: TAnchorDockLayoutTree);
+begin
+  SetnodeMinimizedState(Tree.Root);
+end;
+
 function TAnchorDockMaster.RestoreLayout(Tree: TAnchorDockLayoutTree;
   Scale: boolean): boolean;
 
@@ -2193,7 +2299,7 @@
       try
         SetupSite(Site,ANode,AParent);
         Site.FSiteType:=adhstPages;
-        Site.Header.Parent:=nil;
+        //Site.Header.Parent:=nil;
         if Site.Pages=nil then
           Site.CreatePages;
         for i:=0 to ANode.Count-1 do begin
@@ -2358,7 +2464,7 @@
       debugln(ControlNames.Text);
       {$ENDIF}
       // if some forms/controls could not be created the layout needs to be adapted
-      Tree.Root.Simplify(ControlNames);
+      Tree.Root.Simplify(ControlNames,false);
 
       // reuse existing sites to reduce flickering
       MapTreeToControls(Tree);
@@ -2368,6 +2474,7 @@
 
       // create sites, move controls
       RestoreLayout(Tree,Scale);
+      SetMinimizedState(Tree);
     finally
       EndUpdate;
     end;
@@ -2423,10 +2530,22 @@
 end;
 
 procedure TAnchorDockMaster.OnIdle(Sender: TObject; var Done: Boolean);
+var
+  MousePos: TPoint;
+  Bounds:Trect;
 begin
   if Done then ;
-  IdleConnected:=false;
   Restoring:=false;
+  if FOverlappingForm=nil then
+    IdleConnected:=false
+  else begin
+    GetCursorPos(MousePos);
+    Bounds.TopLeft:=FOverlappingForm.ClientToScreen(point(0,0));
+    Bounds.BottomRight:=FOverlappingForm.ClientToScreen(point(FOverlappingForm.Width,FOverlappingForm.Height));
+    if not PtInRect(Bounds,MousePos) then begin
+      HideOverlappingForm;
+    end;
+  end;
 end;
 
 procedure TAnchorDockMaster.AsyncSimplify(Data: PtrInt);
@@ -2514,6 +2633,24 @@
   InvalidateHeaders;
 end;
 
+procedure TAnchorDockMaster.SetDockSitesCanBeMinimized(AValue: boolean);
+var
+  i:integer;
+  Site: TAnchorDockHostSite;
+begin
+  if FDockSitesCanBeMinimized=AValue then Exit;
+  FDockSitesCanBeMinimized:=AValue;
+  for i:=0 to ComponentCount-1 do begin
+    Site:=TAnchorDockHostSite(Components[i]);
+    if not (Site is TAnchorDockHostSite) then continue;
+    if (Site.Header<>nil) then begin
+      DisableControlAutoSizing(Site);
+      Site.UpdateHeaderShowing;
+    end;
+  end;
+  EnableAllAutoSizing;
+  OptionsChanged;
+end;
 procedure TAnchorDockMaster.SetScaleOnResize(AValue: boolean);
 begin
   if FScaleOnResize=AValue then Exit;
@@ -2668,6 +2805,19 @@
     EnableAllAutoSizing;
 end;
 
+procedure TAnchorDockMaster.ShowOverlappingForm;
+begin
+  FOverlappingForm.Show;
+  IdleConnected:=true;
+end;
+
+procedure TAnchorDockMaster.HideOverlappingForm;
+begin
+  FOverlappingForm.Hide;
+  FOverlappingForm.AnchorDockHostSite.HideMinimizedControl;
+  IdleConnected:=false;
+end;
+
 constructor TAnchorDockMaster.Create(AOwner: TComponent);
 begin
   inherited Create(AOwner);
@@ -2698,14 +2848,14 @@
   FPageClass:=TAnchorDockPage;
   FRestoreLayouts:=TAnchorDockRestoreLayouts.Create;
   FHeaderHighlightFocused:=false;
+  FDockSitesCanBeMinimized:=false;
+  FOverlappingForm:=nil;
 end;
 
 destructor TAnchorDockMaster.Destroy;
 var
   AControl: TControl;
-  {$IFDEF VerboseAnchorDocking}
-  i: Integer;
-  {$ENDIF}
+  i, j: Integer;
 begin
   QueueSimplify:=false;
   FreeAndNil(FRestoreLayouts);
@@ -2727,6 +2877,12 @@
     debugln(['TAnchorDockMaster.Destroy ',i,'/',ComponentCount,' ',DbgSName(Components[i])]);
   end;
   {$ENDIF}
+  for i:=0 to ComponentCount-1 do begin
+    for j:=0 to ComponentCount-1 do begin
+      if i<>j then
+        TControl(Components[i]).RemoveAllHandlersOfObject(TControl(Components[j]));
+  end;
+  end;
   inherited Destroy;
 end;
 
@@ -3018,7 +3174,8 @@
   i:=Screen.CustomFormCount-1;
   while i>=0 do begin
     AForm:=GetParentForm(Screen.CustomForms[i]);
-    AForm.Hide;
+    if Assigned(AForm)then
+      AForm.Hide;
     i:=Min(i,Screen.CustomFormCount)-1;
   end;
 
@@ -3062,8 +3219,11 @@
   end;
 end;
 
-function GetParentFormOrDockPanel(Control: TControl): TCustomForm;
+function GetParentFormOrDockPanel(Control: TControl; TopForm:Boolean=true): TCustomForm;
+var
+  oldControl: TControl;
 begin
+  oldControl:=Control;
   while (Control <> nil) and (Control.Parent <> nil) do
   begin
     if (Control is TAnchorDockPanel) then
@@ -3076,6 +3236,18 @@
     Result := TCustomForm(Control)
   else
     Result := nil;
+  if not TopForm then begin
+    if Control is TAnchorDockPanel then
+      exit;
+    Control:=oldControl;
+    while (Control <> nil) and (Control.Parent <> nil) do
+    begin
+      Control := Control.Parent;
+      if (Control is TCustomForm) then
+        Break;
+    end;
+    Result := TCustomForm(Control);
+  end;
 end;
 
 procedure TAnchorDockMaster.SaveMainLayoutToTree(LayoutTree: TAnchorDockLayoutTree);
@@ -3088,12 +3260,12 @@
   AFormOrDockPanel: TWinControl;
   VisibleControls: TStringList;
 
-  procedure SaveFormOrDockPanel(theFormOrDockPanel: TWinControl; SaveChildren: boolean);
+  procedure SaveFormOrDockPanel(theFormOrDockPanel: TWinControl; SaveChildren: boolean; AMinimized:boolean);
   begin
     // custom dock site
     LayoutNode:=LayoutTree.NewNode(LayoutTree.Root);
     LayoutNode.NodeType:=adltnCustomSite;
-    LayoutNode.Assign(theFormOrDockPanel,theFormOrDockPanel is TAnchorDockPanel);
+    LayoutNode.Assign(theFormOrDockPanel,theFormOrDockPanel is TAnchorDockPanel,AMinimized);
     // can have one normal dock site
     if SaveChildren then
     begin
@@ -3124,7 +3296,7 @@
       debugln(['TAnchorDockMaster.SaveMainLayoutToTree AForm=',DbgSName(AFormOrDockPanel)]);
       DebugWriteChildAnchors(AFormOrDockPanel,true,true);
       if AFormOrDockPanel is TAnchorDockPanel then begin
-        SaveFormOrDockPanel(GetParentFormOrDockPanel(AFormOrDockPanel),{false}true);
+        SaveFormOrDockPanel(GetParentFormOrDockPanel(AFormOrDockPanel),true,false);
         //LayoutNode:=LayoutTree.NewNode(LayoutTree.Root);
         //TAnchorDockPanel(AFormOrDockPanel).SaveLayout(LayoutTree,LayoutNode);
       end else if AFormOrDockPanel is TAnchorDockHostSite then begin
@@ -3132,12 +3304,12 @@
         LayoutNode:=LayoutTree.NewNode(LayoutTree.Root);
         Site.SaveLayout(LayoutTree,LayoutNode);
       end else if IsCustomSite(AFormOrDockPanel) then begin
-        SaveFormOrDockPanel(AFormOrDockPanel,true);
+        SaveFormOrDockPanel(AFormOrDockPanel,true,false);
       end else
         raise EAnchorDockLayoutError.Create('invalid root control for save: '+DbgSName(AControl));
     end;
     // remove invisible controls
-    LayoutTree.Root.Simplify(VisibleControls);
+    LayoutTree.Root.Simplify(VisibleControls,false);
   finally
     VisibleControls.Free;
     SavedSites.Free;
@@ -3157,7 +3329,7 @@
     (AControl as TAnchorDockPanel).SaveLayout(LayoutTree,LayoutTree.Root);
   end else if IsCustomSite(AControl) then begin
     LayoutTree.Root.NodeType:=adltnCustomSite;
-    LayoutTree.Root.Assign(AControl);
+    LayoutTree.Root.Assign(AControl,false,false);
     // can have one normal dock site
     Site:=TAnchorDockManager(AControl.DockManager).GetChildSite;
     if Site<>nil then begin
@@ -3252,7 +3424,7 @@
       debugln(ControlNames.Text);
       {$ENDIF}
       // if some forms/controls could not be created the layout needs to be adapted
-      Tree.Root.Simplify(ControlNames);
+      Tree.Root.Simplify(ControlNames,false);
 
       // reuse existing sites to reduce flickering
       MapTreeToControls(Tree);
@@ -3262,6 +3434,7 @@
 
       // create sites, move controls
       RestoreLayout(Tree,Scale);
+      SetMinimizedState(Tree);
     finally
       EndUpdate;
     end;
@@ -3323,6 +3496,7 @@
   HeaderFlatten                    := Settings.HeaderFlatten;
   HeaderFilled                     := Settings.HeaderFilled;
   HeaderHighlightFocused           := Settings.HeaderHighlightFocused;
+  DockSitesCanBeMinimized          := Settings.DockSitesCanBeMinimized;
 end;
 
 procedure TAnchorDockMaster.SaveSettings(Settings: TAnchorDockSettings);
@@ -3343,6 +3517,7 @@
   Settings.HeaderFlatten:=HeaderFlatten;
   Settings.HeaderFilled:=HeaderFilled;
   Settings.HeaderHighlightFocused:=HeaderHighlightFocused;
+  Settings.DockSitesCanBeMinimized:=DockSitesCanBeMinimized;
 end;
 
 function TAnchorDockMaster.SettingsAreEqual(Settings: TAnchorDockSettings
@@ -3680,6 +3855,7 @@
     AControl:=TControl(Sender);
     if not (csDestroying in ComponentState) then begin
       if (not AControl.Visible)
+      and (not FMinimized)
       and (not ((AControl is TAnchorDockHeader)
                or (AControl is TAnchorDockSplitter)
                or (AControl is TAnchorDockHostSite)))
@@ -4119,6 +4295,8 @@
 end;
 
 procedure TAnchorDockHostSite.FreePages;
+var
+  i:Integer;
 begin
   FreeAndNil(FPages);
 end;
@@ -4233,6 +4411,14 @@
         akRight: NewBounds.Right:=AControl.Left+AControl.Width;
         akBottom: NewBounds.Bottom:=AControl.Top+AControl.Height;
         end;
+        if (sibling is TAnchorDockHostSite) then
+        if (sibling as TAnchorDockHostSite).FMinimized then begin
+          (sibling as TAnchorDockHostSite).FMinimized:=false;
+          (sibling as TAnchorDockHostSite).FMinimizedControl.Parent:=(sibling as TAnchorDockHostSite);
+          (sibling as TAnchorDockHostSite).FMinimizedControl.Visible:=True;
+          (sibling as TAnchorDockHostSite).FMinimizedControl:=nil;
+          (sibling as TAnchorDockHostSite).UpdateHeaderAlign;
+        end;
         Sibling.BoundsRect:=NewBounds;
       end;
     end;
@@ -4306,6 +4492,13 @@
       FSiteType:=adhstOneControl;
       OnlySiteLeft.Align:=alClient;
       Header.Parent:=Self;
+      if OnlySiteLeft.FMinimized then begin
+        OnlySiteLeft.FMinimized:=false;
+        OnlySiteLeft.FMinimizedControl.Parent:=OnlySiteLeft;
+        OnlySiteLeft.FMinimizedControl.Visible:=True;
+        OnlySiteLeft.FMinimizedControl:=nil;
+        UpdateHeaderAlign;
+      end;
       UpdateHeaderAlign;
 
       //debugln(['TAnchorDockHostSite.RemoveControlFromLayout.ConvertToOneControlType AFTER CONVERT "',Caption,'" to onecontrol OnlySiteLeft="',OnlySiteLeft.Caption,'"']);
@@ -4465,7 +4658,7 @@
     debugln(['TAnchorDockHostSite.Simplify ',DbgSName(Self),' ',DbgSName(AControl)]);
     if AControl is TAnchorDockHostSite then
       SimplifyOneControl
-    else if (AControl=nil) or (csDestroying in AControl.ComponentState) then
+    else if ((AControl=nil) or (csDestroying in AControl.ComponentState)) then
       DockMaster.NeedFree(Self);
   end;
 end;
@@ -4577,7 +4770,8 @@
     Result:=Controls[i];
     if Result.Owner<>Self then exit;
   end;
-  Result:=nil;
+  result:=FMinimizedControl;
+  //Result:=nil;
 end;
 
 function TAnchorDockHostSite.GetSiteCount: integer;
@@ -5165,6 +5359,102 @@
   Result:=Check(Self);
 end;
 
+function CheckOposite(Side:TAnchorKind;var AControl: TControl;out Splitter: TAnchorDockSplitter; out SplitterAnchorKind:TAnchorKind):boolean;
+begin
+  result:=GetDockSplitter(AControl,Side,Splitter);
+  if result then begin
+    if CountAnchoredControls(Splitter,OppositeAnchor[Side])=1 then begin
+      SplitterAnchorKind:=Side;
+      exit;
+    end;
+  end;
+  result:=false
+end;
+
+function FindNearestSpliter(AControl: TControl;out Splitter: TAnchorDockSplitter;out SplitterAnchorKind:TAnchorKind):boolean;
+begin
+  result:=CheckOposite(akTop,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akRight,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akBottom,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akLeft,AControl,Splitter,SplitterAnchorKind);
+end;
+
+procedure TAnchorDockHostSite.MinimizeSite;
+begin
+  //Application.QueueAsyncCall(@AsyncMinimizeSite,0);
+  AsyncMinimizeSite(0);
+end;
+
+procedure TAnchorDockHostSite.AsyncMinimizeSite(Data: PtrInt);
+var
+  AControl: TControl;
+  OpositeDockHostSite:TAnchorDockHostSite;
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
+  //SpliterPercentPosition:Single;
+begin
+  fMinimization:=true;
+  debugln(['TAnchorDockHostSite.MinimizeSite ',DbgSName(Self),' SiteType=',dbgs(SiteType)]);
+  if FMinimized then
+    AControl:=FMinimizedControl
+  else
+    AControl:=GetOneControl;
+  if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+    OpositeDockHostSite:=CountAndReturnOnlyOneMinimizedAnchoredControls(Splitter,SplitterAnchorKind);
+    if (Splitter.Enabled and (OpositeDockHostSite=nil)) or FMinimized then begin
+      FMinimized:=not FMinimized;
+      if FMinimized then begin
+        FMinimizedControl:=AControl;
+        AControl.Visible:=False;
+        AControl.Parent:=nil;
+      end else begin
+        AControl.Parent:=self;
+        AControl.Visible:=True;
+        FMinimizedControl:=nil;
+      end;
+      Splitter.Enabled:=AControl.Visible;
+      UpdateHeaderAlign;
+      Splitter.SetBoundsPercentually;
+    end;
+  end;
+  fMinimization:=false;
+end;
+
+procedure TAnchorDockHostSite.ShowMinimizedControl;
+var
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
+  SpliterRect,OverlappingFormRect:TRect;
+begin
+  if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+    SpliterRect:=Splitter.GetSpliterBoundsWithUnminimizedDockSites;
+    OverlappingFormRect:=BoundsRect;
+    case SplitterAnchorKind of
+         akTop:OverlappingFormRect.Top:=SpliterRect.Bottom;
+        akLeft:OverlappingFormRect.Left:=SpliterRect.Right;
+       akRight:OverlappingFormRect.Right:=SpliterRect.Left;
+      akBottom:OverlappingFormRect.Bottom:=SpliterRect.Top;
+    end;
+    DockMaster.FOverlappingForm:=TAnchorDockOverlappingForm.CreateNew(self);
+    DockMaster.FOverlappingForm.BoundsRect:=OverlappingFormRect;
+    DockMaster.FOverlappingForm.Parent:=GetParentFormOrDockPanel(self,false);
+    DockMaster.FOverlappingForm.AnchorDockHostSite:=self;
+    FMinimizedControl.Parent:=DockMaster.FOverlappingForm;
+    FMinimizedControl.Show;
+    DockMaster.ShowOverlappingForm;
+  end;
+end;
+
+procedure TAnchorDockHostSite.HideMinimizedControl;
+begin
+   FMinimizedControl.Hide;
+   FMinimizedControl.Parent:=nil;
+   FreeAndNil(DockMaster.FOverlappingForm);
+end;
+
 function TAnchorDockHostSite.CloseSite: boolean;
 var
   AControl: TControl;
@@ -5306,9 +5596,8 @@
     if Parent is TAnchorDockPage then
       TAnchorDockPage(Parent).UpdateDockCaption;
   end;
-
   // do not show close button for mainform
-  Header.CloseButton.Visible:=not IsParentOf(Application.MainForm);
+  Header.CloseButton.Visible:=(not IsParentOf(Application.MainForm))and(Pages=nil);
 end;
 
 procedure TAnchorDockHostSite.GetSiteInfo(Client: TControl;
@@ -5362,9 +5651,33 @@
 end;
 
 procedure TAnchorDockHostSite.UpdateHeaderAlign;
+const
+OppositeAlign: array[TAnchorKind] of TAlign = (
+  alBottom, // akTop,
+  alRight,  // akLeft,
+  alLeft,   // akRight,
+  alTop     // akBottom
+  );
+OppositeAnchorKindAlign: array[TAnchorKind] of TADLHeaderPosition = (
+  adlhpBottom, // akTop,
+  adlhpRight,  // akLeft,
+  adlhpLeft,   // akRight,
+  adlhpTop     // akBottom
+  );
+var
+  NeededHeaderPosition:TADLHeaderPosition;
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
 begin
   if Header=nil then exit;
-  case Header.HeaderPosition of
+  if FMinimized then begin
+    if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+      NeededHeaderPosition:=OppositeAnchorKindAlign[SplitterAnchorKind];
+    end else
+      NeededHeaderPosition:=Header.HeaderPosition;
+  end else
+    NeededHeaderPosition:=Header.HeaderPosition;
+  case NeededHeaderPosition of
   adlhpAuto:
     if Header.Align in [alLeft,alRight] then begin
       if (ClientHeight>0)
@@ -5390,8 +5703,11 @@
 procedure TAnchorDockHostSite.UpdateHeaderShowing;
 begin
   if Header=nil then exit;
-  if HeaderNeedsShowing then
-    Header.Parent:=Self
+  if HeaderNeedsShowing then begin
+    Header.Parent:=Self;
+    Header.MinimizeButton.Visible:=DockMaster.DockSitesCanBeMinimized;
+    Header.MinimizeButton.Parent:=Header;
+  end
   else
     Header.Parent:=nil;
 end;
@@ -5432,7 +5748,7 @@
   if (SiteType=adhstOneControl) and (OneControl<>nil)
   and (not (OneControl is TAnchorDockHostSite)) then begin
     LayoutNode.NodeType:=adltnControl;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,FMinimized);
     LayoutNode.Name:=OneControl.Name;
     LayoutNode.HeaderPosition:=Header.HeaderPosition;
   end else if (SiteType in [adhstLayout,adhstOneControl]) then begin
@@ -5450,7 +5766,7 @@
         Splitter.SaveLayout(ChildNode);
       end;
     end;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,FMinimized);
     LayoutNode.HeaderPosition:=Header.HeaderPosition;
   end else if SiteType=adhstPages then begin
     LayoutNode.NodeType:=adltnPages;
@@ -5461,7 +5777,7 @@
         Site.SaveLayout(LayoutTree,ChildNode);
       end;
     end;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,FMinimized);
     LayoutNode.HeaderPosition:=Header.HeaderPosition;
   end else
     LayoutNode.NodeType:=adltnNone;
@@ -5476,6 +5792,9 @@
 constructor TAnchorDockHostSite.CreateNew(AOwner: TComponent; Num: Integer);
 begin
   inherited CreateNew(AOwner,Num);
+  FMinimized:=false;
+  fMinimization:=false;
+  FMinimizedControl:=Nil;
   Visible:=false;
   FHeaderSide:=akTop;
   FHeader:=DockMaster.HeaderClass.Create(Self);
@@ -5490,13 +5809,13 @@
 end;
 
 destructor TAnchorDockHostSite.Destroy;
-//var i: Integer;
+var i: Integer;
 begin
-  //debugln(['TAnchorDockHostSite.Destroy ',DbgSName(Self),' Caption="',Caption,'" Self=',dbgs(Pointer(Self)),' ComponentCount=',ComponentCount,' ControlCount=',ControlCount]);
-  {for i:=0 to ComponentCount-1 do
+  debugln(['TAnchorDockHostSite.Destroy ',DbgSName(Self),' Caption="',Caption,'" Self=',dbgs(Pointer(Self)),' ComponentCount=',ComponentCount,' ControlCount=',ControlCount]);
+  for i:=0 to ComponentCount-1 do
     debugln(['TAnchorDockHostSite.Destroy Component ',i,'/',ComponentCount,' ',DbgSName(Components[i])]);
   for i:=0 to ControlCount-1 do
-    debugln(['TAnchorDockHostSite.Destroy Control ',i,'/',ControlCount,' ',DbgSName(Controls[i])]);}
+    debugln(['TAnchorDockHostSite.Destroy Control ',i,'/',ControlCount,' ',DbgSName(Controls[i])]);
   FreePages;
   inherited Destroy;
 end;
@@ -5569,6 +5888,13 @@
   end;
 end;
 
+procedure TAnchorDockHeader.MinimizeButtonClick(Sender: TObject);
+begin
+  if Parent is TAnchorDockHostSite then begin
+    TAnchorDockHostSite(Parent).MinimizeSite;
+  end;
+end;
+
 procedure TAnchorDockHeader.HeaderPositionItemClick(Sender: TObject);
 var
   Item: TMenuItem;
@@ -5640,6 +5966,13 @@
       r.Right:=CloseButton.Left-1;
   end;
 
+  if MinimizeButton.IsControlVisible and (MinimizeButton.Parent=Self) then begin
+    if Align in [alLeft,alRight] then
+      r.Top:=MinimizeButton.Top+MinimizeButton.Height+1
+    else
+      r.Right:=MinimizeButton.Left-1;
+  end;
+
   // caption
   if Caption<>'' then begin
     if fFocused and DockMaster.HeaderHighlightFocused and NeedHighlightText then
@@ -5728,7 +6061,14 @@
     end else begin
       PreferredHeight:=Max(NeededHeight,PreferredHeight);
     end;
+  end else begin
+    NeededHeight:=CloseButton.Height;
+    if Align in [alLeft,alRight] then begin
+      PreferredWidth:=Max(NeededHeight,PreferredWidth);
+    end else begin
+      PreferredHeight:=Max(NeededHeight,PreferredHeight);
   end;
+  end;
 end;
 
 procedure TAnchorDockHeader.MouseDown(Button: TMouseButton; Shift: TShiftState;
@@ -5739,14 +6079,63 @@
     DragManager.DragStart(Parent,false,DockMaster.DragTreshold);
 end;
 
+procedure  TAnchorDockHeader.MouseMove(Shift: TShiftState; X,Y: Integer);
+begin
+  inherited MouseMove(Shift, X, Y);
+  if parent<>nil then
+    if parent is TAnchorDockHostSite then
+      if (parent as TAnchorDockHostSite).FMinimized then
+        if DockMaster.FOverlappingForm=nil then
+          if FMouseTimeStartX=EmptyMouseTimeStartX then
+            StartMouseNoMoveTimer(X, Y)
+          else begin
+            if (abs(FMouseTimeStartX-X)>MouseNoMoveDelta)or(abs(FMouseTimeStartY-Y)>MouseNoMoveDelta)then
+            StopMouseNoMoveTimer;
+          end;
+end;
+
+procedure TAnchorDockHeader.MouseLeave;
+begin
+  inherited;
+  StopMouseNoMoveTimer;
+end;
+
+procedure TAnchorDockHeader.StartMouseNoMoveTimer(X, Y: Integer);
+begin
+  if MouseNoMoveTimer.Enabled then MouseNoMoveTimer.Enabled:=false;
+  MouseNoMoveTimer.Interval:=MouseNoMoveTime;
+  MouseNoMoveTimer.OnTimer:=@DoMouseNoMoveTimer;
+  MouseNoMoveTimer.Enabled:=true;
+end;
+
+procedure TAnchorDockHeader.StopMouseNoMoveTimer;
+begin
+  FMouseTimeStartX:=EmptyMouseTimeStartX;
+  MouseNoMoveTimer.OnTimer:=nil;
+  MouseNoMoveTimer.Enabled:=false;
+end;
+
+procedure TAnchorDockHeader.DoMouseNoMoveTimer(Sender: TObject);
+begin
+  StopMouseNoMoveTimer;
+  if parent<>nil then
+    if parent is TAnchorDockHostSite then
+      if (parent as TAnchorDockHostSite).FMinimized then
+        (parent as TAnchorDockHostSite).ShowMinimizedControl;
+end;
+
 procedure TAnchorDockHeader.UpdateHeaderControls;
 begin
   if Align in [alLeft,alRight] then begin
-    if CloseButton<>nil then
+    if CloseButton<>nil then begin
+      MinimizeButton.Align:=alTop;
       CloseButton.Align:=alTop;
+    end;
   end else begin
-    if CloseButton<>nil then
+    if CloseButton<>nil then begin
+      MinimizeButton.Align:=alRight;
       CloseButton.Align:=alRight;
+    end;
   end;
   //debugln(['TAnchorDockHeader.UpdateHeaderControls ',dbgs(Align),' ',dbgs(CloseButton.Align)]);
 end;
@@ -5787,9 +6176,9 @@
 begin
   inherited Create(TheOwner);
   FHeaderPosition:=adlhpAuto;
-  FCloseButton:=TAnchorDockCloseButton.Create(Self);
   BevelOuter:=bvNone;
   BorderWidth:=0;
+  FCloseButton:=TAnchorDockCloseButton.Create(Self);
   with FCloseButton do begin
     Name:='CloseButton';
     Parent:=Self;
@@ -5799,11 +6188,22 @@
     OnClick:=@CloseButtonClick;
     AutoSize:=true;
   end;
+  FMinimizeButton:=TAnchorDockMinimizeButton.Create(Self);
+  with FMinimizeButton do begin
+    Name:='MinimizeButton';
+    Parent:=Self;
+    Flat:=true;
+    ShowHint:=true;
+    Hint:=adrsMinimize;
+    OnClick:=@MinimizeButtonClick;
+    AutoSize:=true;
+  end;
   Align:=alTop;
   AutoSize:=true;
   ShowHint:=true;
   PopupMenu:=DockMaster.GetPopupMenu;
   fFocused:=false;
+  FMouseTimeStartX:=EmptyMouseTimeStartX;
 end;
 
 { TAnchorDockCloseButton }
@@ -5844,6 +6244,44 @@
   end;
 end;
 
+{ TAnchorDockMinimizeButton }
+
+function TAnchorDockMinimizeButton.GetDrawDetails: TThemedElementDetails;
+
+function WindowPart: TThemedWindow;
+  begin
+    // no check states available
+    Result := twMinButtonNormal;
+    if not IsEnabled then
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonDisabled{$ELSE}twMinButtonDisabled{$ENDIF}
+    else
+    if FState in [bsDown, bsExclusive] then
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonPushed{$ELSE}twMinButtonPushed{$ENDIF}
+    else
+    if FState = bsHot then
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonHot{$ELSE}twMinButtonHot{$ENDIF}
+    else
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonNormal{$ELSE}twMinButtonNormal{$ENDIF};
+  end;
+
+begin
+  Result := ThemeServices.GetElementDetails(WindowPart);
+end;
+
+procedure TAnchorDockMinimizeButton.CalculatePreferredSize(var PreferredWidth,
+  PreferredHeight: integer; WithThemeSpace: Boolean);
+begin
+  with ThemeServices.GetDetailSize(ThemeServices.GetElementDetails({$IFDEF LCLGtk2}twMDIRestoreButtonNormal{$ELSE}twMinButtonNormal{$ENDIF})) do
+  begin
+    PreferredWidth:=cx;
+    PreferredHeight:=cy;
+    {$IF defined(LCLGtk2) or defined(Carbon)}
+    inc(PreferredWidth,2);
+    inc(PreferredHeight,2);
+    {$ENDIF}
+  end;
+end;
+
 { TAnchorDockManager }
 
 procedure TAnchorDockManager.SetPreferredSiteSizeAsSiteMinimum(
@@ -6505,32 +6943,58 @@
 procedure TAnchorDockSplitter.SetBoundsPercentually;
 var
   NewLeft, NewTop: Integer;
+  AControl: TControl;
+  SplitterAnchorKind:TAnchorKind;
 begin
-  if ResizeAnchor in [akLeft,akRight] then
-  begin
-    if DockParentClientSize.cx> 0 then
+  if Enabled then begin
+    if ResizeAnchor in [akLeft,akRight] then
     begin
-      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
-        NewLeft := Round(FPercentPosition*Parent.ClientWidth)
-      else
-        NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
-      NewTop := Top;
-      SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      if DockParentClientSize.cx> 0 then
+      begin
+        if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+          NewLeft := Round(FPercentPosition*Parent.ClientWidth)
+        else
+          NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
+        NewTop := Top;
+        SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      end;
+    end else
+    begin
+      if DockParentClientSize.cy> 0 then
+      begin
+        NewLeft := Left;
+        if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+          NewTop := Round(FPercentPosition*Parent.ClientHeight)
+        else
+          NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+        SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      end;
     end;
-  end else
-  begin
-    if DockParentClientSize.cy> 0 then
-    begin
-      NewLeft := Left;
-      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
-        NewTop := Round(FPercentPosition*Parent.ClientHeight)
-      else
-        NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+    if FPercentPosition < 0 then
+      UpdatePercentPosition;
+  end else begin
+    SplitterAnchorKind:=akTop;
+    AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);
+    if AControl=nil then begin SplitterAnchorKind:=akRight;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+    if AControl=nil then begin SplitterAnchorKind:=akBottom;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+    if AControl=nil then begin SplitterAnchorKind:=akLeft;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+
+    if AControl is TAnchorDockHostSite then begin
+      (AControl as TAnchorDockHostSite).UpdateHeaderAlign;
+      NewTop := (AControl as TAnchorDockHostSite).Header.Left;
+      NewTop := (AControl as TAnchorDockHostSite).Header.Height;
+      NewLeft := left;
+      NewTop := top;
+      (AControl as TAnchorDockHostSite).UpdateHeaderAlign;
+      case SplitterAnchorKind of
+        akTop: NewTop := AControl.Top+(AControl as TAnchorDockHostSite).Header.Height;
+        akBottom: NewTop := AControl.Top+AControl.Height-(AControl as TAnchorDockHostSite).Header.Height-Height;
+        akLeft: NewLeft := AControl.Left+(AControl as TAnchorDockHostSite).Header.Width;
+        akRight: NewLeft := AControl.Left+AControl.Width-(AControl as TAnchorDockHostSite).Header.Width-Width;
+      end;
       SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
     end;
   end;
-  if FPercentPosition < 0 then
-    UpdatePercentPosition;
 end;
 
 function TAnchorDockSplitter.SideAnchoredControlCount(Side: TAnchorKind): integer;
@@ -6560,14 +7024,47 @@
   end;
 end;
 
+function TAnchorDockSplitter.GetSpliterBoundsWithUnminimizedDockSites:TRect;
+var
+  NewLeft, NewTop: Integer;
+begin
+  if ResizeAnchor in [akLeft,akRight] then
+  begin
+    if DockParentClientSize.cx> 0 then
+    begin
+      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+        NewLeft := Round(FPercentPosition*Parent.ClientWidth)
+      else
+        NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
+      NewTop := Top;
+    end;
+  end else
+  begin
+    if DockParentClientSize.cy> 0 then
+    begin
+      NewLeft := Left;
+      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+        NewTop := Round(FPercentPosition*Parent.ClientHeight)
+      else
+        NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+    end;
+  end;
+  result:=Rect(NewLeft,NewTop,NewLeft+Width,NewTop+Height);
+end;
+
 procedure TAnchorDockSplitter.SaveLayout(
   LayoutNode: TAnchorDockLayoutTreeNode);
+var
+  NewLeft, NewTop: Integer;
 begin
   if ResizeAnchor in [akLeft,akRight] then
     LayoutNode.NodeType:=adltnSplitterVertical
   else
     LayoutNode.NodeType:=adltnSplitterHorizontal;
-  LayoutNode.Assign(Self);
+  LayoutNode.Assign(Self,false,false);
+  if not Enabled then begin
+    LayoutNode.BoundsRect:=GetSpliterBoundsWithUnminimizedDockSites;
+  end
 end;
 
 function TAnchorDockSplitter.HasOnlyOneSibling(Side: TAnchorKind; MinPos,
@@ -6782,6 +7279,20 @@
   PopupMenu:=DockMaster.GetPopupMenu;
 end;
 
+{ TAnchorDockOverlappingForm }
+
+constructor TAnchorDockOverlappingForm.CreateNew(AOwner: TComponent; Num: Integer = 0);
+begin
+  inherited;
+  BorderStyle:=bsNone;
+  AnchorDockHostSite:=nil;
+end;
+
+procedure TAnchorDockOverlappingForm.MouseLeave;
+begin
+  inherited;
+end;
+
 { TAnchorDockPage }
 
 procedure TAnchorDockPage.UpdateDockCaption(Exclude: TControl);
@@ -6835,9 +7346,11 @@
 
 initialization
   DockMaster:=TAnchorDockMaster.Create(nil);
+  MouseNoMoveTimer:=TTimer.Create(nil);
 
 finalization
   FreeAndNil(DockMaster);
+  FreeAndNil(MouseNoMoveTimer);
 
 end.
 
Index: components/anchordocking/anchordockoptionsdlg.lfm
===================================================================
--- components/anchordocking/anchordockoptionsdlg.lfm	(revision 59428)
+++ components/anchordocking/anchordockoptionsdlg.lfm	(working copy)
@@ -1,11 +1,13 @@
 object AnchorDockOptionsFrame: TAnchorDockOptionsFrame
   Left = 0
-  Height = 482
+  Height = 567
   Top = 0
-  Width = 416
-  ClientHeight = 482
-  ClientWidth = 416
+  Width = 490
+  ClientHeight = 567
+  ClientWidth = 490
+  DesignTimePPI = 113
   OnClick = FrameClick
+  ParentFont = False
   TabOrder = 0
   DesignLeft = 513
   DesignTop = 189
@@ -12,14 +14,15 @@
   object DragThresholdLabel: TLabel
     AnchorSideLeft.Control = Owner
     AnchorSideTop.Control = Owner
-    Left = 10
-    Height = 13
-    Top = 10
-    Width = 111
-    BorderSpacing.Left = 10
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 12
+    Width = 122
+    BorderSpacing.Left = 12
+    BorderSpacing.Top = 12
     Caption = 'DragThresholdLabel'
     ParentColor = False
+    ParentFont = False
   end
   object DragThresholdTrackBar: TTrackBar
     AnchorSideLeft.Control = DragThresholdLabel
@@ -27,15 +30,16 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = Owner
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 46
-    Top = 23
-    Width = 396
+    Left = 12
+    Height = 54
+    Top = 31
+    Width = 466
     Max = 20
     OnChange = DragThresholdTrackBarChange
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Right = 10
+    BorderSpacing.Right = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 1
@@ -46,12 +50,13 @@
     AnchorSideTop.Control = DragThresholdLabel
     AnchorSideTop.Side = asrCenter
     AnchorSideRight.Control = Owner
-    Left = 127
-    Height = 23
-    Top = 5
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 141
+    Height = 27
+    Top = 8
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 20
+    ParentFont = False
     TabOrder = 0
     Visible = False
   end
@@ -59,13 +64,14 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = DragThresholdTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 79
-    Width = 103
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 97
+    Width = 112
+    BorderSpacing.Top = 12
     Caption = 'SplitterWidthLabel'
     ParentColor = False
+    ParentFont = False
   end
   object SplitterWidthTrackBar: TTrackBar
     AnchorSideLeft.Control = DragThresholdTrackBar
@@ -73,14 +79,15 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 46
-    Top = 92
-    Width = 396
+    Left = 12
+    Height = 54
+    Top = 116
+    Width = 466
     Min = 1
     OnChange = SplitterWidthTrackBarChange
     Position = 1
     Anchors = [akTop, akLeft, akRight]
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 3
@@ -89,12 +96,13 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = SplitterWidthTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 24
-    Top = 142
-    Width = 160
-    BorderSpacing.Top = 4
+    Left = 12
+    Height = 23
+    Top = 175
+    Width = 169
+    BorderSpacing.Top = 5
     Caption = 'ScaleOnResizeCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 4
@@ -103,12 +111,13 @@
     AnchorSideLeft.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 24
-    Top = 166
-    Width = 149
+    Left = 12
+    Height = 23
+    Top = 198
+    Width = 160
     Caption = 'ShowHeaderCheckBox'
     OnChange = ShowHeaderCheckBoxChange
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 5
@@ -117,12 +126,13 @@
     AnchorSideLeft.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Control = ShowHeaderCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 190
-    Width = 191
-    BorderSpacing.Left = 15
+    Left = 30
+    Height = 23
+    Top = 221
+    Width = 208
+    BorderSpacing.Left = 18
     Caption = 'ShowHeaderCaptionCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 6
@@ -131,11 +141,12 @@
     AnchorSideLeft.Control = ShowHeaderCaptionCheckBox
     AnchorSideTop.Control = ShowHeaderCaptionCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 214
-    Width = 249
+    Left = 30
+    Height = 23
+    Top = 244
+    Width = 272
     Caption = 'HideHeaderCaptionForFloatingCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 7
@@ -147,15 +158,16 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = Owner
     AnchorSideRight.Side = asrBottom
-    Left = 122
+    Left = 136
     Height = 27
-    Top = 286
-    Width = 284
+    Top = 313
+    Width = 342
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 6
-    BorderSpacing.Right = 10
-    ItemHeight = 0
+    BorderSpacing.Left = 7
+    BorderSpacing.Right = 12
+    ItemHeight = 19
     OnDrawItem = HeaderStyleComboBoxDrawItem
+    ParentFont = False
     Style = csDropDownList
     TabOrder = 10
   end
@@ -163,23 +175,25 @@
     AnchorSideLeft.Control = ShowHeaderCheckBox
     AnchorSideTop.Control = HeaderStyleComboBox
     AnchorSideTop.Side = asrCenter
-    Left = 20
-    Height = 13
-    Top = 293
-    Width = 96
-    BorderSpacing.Left = 10
+    Left = 24
+    Height = 19
+    Top = 317
+    Width = 105
+    BorderSpacing.Left = 12
     Caption = 'HeaderStyleLabel'
     ParentColor = False
+    ParentFont = False
   end
   object FlattenHeadersCheckBox: TCheckBox
     AnchorSideLeft.Control = HideHeaderCaptionForFloatingCheckBox
     AnchorSideTop.Control = HideHeaderCaptionForFloatingCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 238
-    Width = 164
+    Left = 30
+    Height = 23
+    Top = 267
+    Width = 175
     Caption = 'FlattenHeadersCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 8
@@ -188,11 +202,12 @@
     AnchorSideLeft.Control = FlattenHeadersCheckBox
     AnchorSideTop.Control = FlattenHeadersCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 262
-    Width = 154
+    Left = 30
+    Height = 23
+    Top = 290
+    Width = 164
     Caption = 'FilledHeadersCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 9
@@ -201,11 +216,12 @@
     AnchorSideLeft.Control = FilledHeadersCheckBox
     AnchorSideTop.Control = HeaderStyleComboBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 313
-    Width = 175
+    Left = 30
+    Height = 23
+    Top = 340
+    Width = 189
     Caption = 'HighlightFocusedCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 11
@@ -215,13 +231,14 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = SplitterWidthLabel
     AnchorSideTop.Side = asrCenter
-    Left = 119
-    Height = 23
-    Top = 74
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 131
+    Height = 27
+    Top = 93
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 10
     MinValue = 1
+    ParentFont = False
     TabOrder = 2
     Value = 1
     Visible = False
@@ -228,15 +245,16 @@
   end
   object HeaderAlignTopLabel: TLabel
     AnchorSideLeft.Control = DragThresholdLabel
-    AnchorSideTop.Control = HighlightFocusedCheckBox
+    AnchorSideTop.Control = DockSitesCanBeMinimized
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 347
-    Width = 117
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 398
+    Width = 130
+    BorderSpacing.Top = 12
     Caption = 'HeaderAlignTopLabel'
     ParentColor = False
+    ParentFont = False
   end
   object HeaderAlignTopTrackBar: TTrackBar
     AnchorSideLeft.Control = Owner
@@ -244,10 +262,10 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 47
-    Top = 360
-    Width = 396
+    Left = 12
+    Height = 55
+    Top = 417
+    Width = 466
     Frequency = 10
     Max = 150
     OnChange = HeaderAlignTopTrackBarChange
@@ -254,7 +272,8 @@
     PageSize = 10
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 10
+    BorderSpacing.Left = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 13
@@ -264,12 +283,13 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = HeaderAlignTopLabel
     AnchorSideTop.Side = asrCenter
-    Left = 133
-    Height = 23
-    Top = 342
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 149
+    Height = 27
+    Top = 394
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 150
+    ParentFont = False
     TabOrder = 12
     Visible = False
   end
@@ -277,13 +297,14 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = HeaderAlignTopTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 417
-    Width = 120
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 484
+    Width = 130
+    BorderSpacing.Top = 12
     Caption = 'HeaderAlignLeftLabel'
     ParentColor = False
+    ParentFont = False
   end
   object HeaderAlignLeftTrackBar: TTrackBar
     AnchorSideLeft.Control = Owner
@@ -291,10 +312,10 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 47
-    Top = 430
-    Width = 396
+    Left = 12
+    Height = 55
+    Top = 503
+    Width = 466
     Frequency = 10
     Max = 200
     OnChange = HeaderAlignLeftTrackBarChange
@@ -301,7 +322,8 @@
     PageSize = 10
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 10
+    BorderSpacing.Left = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 15
@@ -311,13 +333,28 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = HeaderAlignLeftLabel
     AnchorSideTop.Side = asrCenter
-    Left = 136
-    Height = 23
-    Top = 412
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 149
+    Height = 27
+    Top = 480
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 200
+    ParentFont = False
     TabOrder = 14
     Visible = False
   end
+  object DockSitesCanBeMinimized: TCheckBox
+    AnchorSideLeft.Control = FilledHeadersCheckBox
+    AnchorSideTop.Control = HighlightFocusedCheckBox
+    AnchorSideTop.Side = asrBottom
+    Left = 30
+    Height = 23
+    Top = 363
+    Width = 185
+    Caption = 'DockSitesCanBeMinimized'
+    ParentFont = False
+    ParentShowHint = False
+    ShowHint = True
+    TabOrder = 16
+  end
 end
Index: components/anchordocking/anchordockoptionsdlg.pas
===================================================================
--- components/anchordocking/anchordockoptionsdlg.pas	(revision 59428)
+++ components/anchordocking/anchordockoptionsdlg.pas	(working copy)
@@ -37,6 +37,7 @@
     HeaderStyleLabel: TLabel;
     HideHeaderCaptionForFloatingCheckBox: TCheckBox;
     HighlightFocusedCheckBox: TCheckBox;
+    DockSitesCanBeMinimized: TCheckBox;
     ScaleOnResizeCheckBox: TCheckBox;
     ShowHeaderCaptionCheckBox: TCheckBox;
     ShowHeaderCheckBox: TCheckBox;
@@ -299,6 +300,7 @@
   HeaderStyleLabel.Enabled:=HasHeaders;
   HeaderStyleComboBox.Enabled:=HasHeaders;
   HighlightFocusedCheckBox.Enabled:=HasHeaders;
+  DockSitesCanBeMinimized.Enabled:=HasHeaders;
 end;
 
 constructor TAnchorDockOptionsFrame.Create(TheOwner: TComponent);
@@ -356,6 +358,7 @@
   TheSettings.HeaderFilled:=FilledHeadersCheckBox.Checked;
   TheSettings.HeaderStyle:=TADHeaderStyle(HeaderStyleComboBox.ItemIndex);
   TheSettings.HeaderHighlightFocused:=HighlightFocusedCheckBox.Checked;
+  TheSettings.DockSitesCanBeMinimized:=DockSitesCanBeMinimized.Checked;
 end;
 
 procedure TAnchorDockOptionsFrame.LoadFromSettings(
@@ -429,6 +432,10 @@
   HighlightFocusedCheckBox.Checked:=TheSettings.HeaderHighlightFocused;
   HighlightFocusedCheckBox.Caption:=adrsHighlightFocused;
   HighlightFocusedCheckBox.Hint:=adrsHighlightFocusedHint;
+
+  DockSitesCanBeMinimized.Checked:=TheSettings.DockSitesCanBeMinimized;
+  DockSitesCanBeMinimized.Caption:=adrsDockSitesCanBeMinimized;
+  DockSitesCanBeMinimized.Hint:=adrsDockSitesCanBeMinimizedHint;
 end;
 
 end.
Index: components/anchordocking/anchordockpanel.pas
===================================================================
--- components/anchordocking/anchordockpanel.pas	(revision 59428)
+++ components/anchordocking/anchordockpanel.pas	(working copy)
@@ -55,7 +55,7 @@
   begin
 
     LayoutNode.NodeType:=adltnControl;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,false);
     LayoutNode.Name:={OneControl.}Name;
 
     TAnchorDockHostSite(OneControl).SaveLayout(LayoutTree,LayoutNode);
Index: components/anchordocking/anchordockstorage.pas
===================================================================
--- components/anchordocking/anchordockstorage.pas	(revision 59428)
+++ components/anchordocking/anchordockstorage.pas	(working copy)
@@ -64,6 +64,7 @@
     FTabPosition: TTabPosition;
     FWindowState: TWindowState;
     FControlLocation: TADLControlLocation;
+    FMinimized: Boolean;
     function GetAnchors(Site: TAnchorKind): string;
     function GetBottom: integer;
     function GetHeight: integer;
@@ -90,6 +91,7 @@
     procedure SetTop(const AValue: integer);
     procedure SetWidth(const AValue: integer);
     procedure SetWindowState(const AValue: TWindowState);
+    procedure SetMinimized(const AValue: boolean);
   public
     constructor Create;
     destructor Destroy; override;
@@ -96,7 +98,7 @@
     procedure Clear;
     function IsEqual(Node: TAnchorDockLayoutTreeNode): boolean;
     procedure Assign(Node: TAnchorDockLayoutTreeNode); overload;
-    procedure Assign(AControl: TControl; OverrideBoundsRect: Boolean=false); overload;
+    procedure Assign(AControl: TControl; OverrideBoundsRect: Boolean; AMinimized: Boolean); overload;
     procedure LoadFromConfig(Config: TConfigStorage); overload;
     procedure LoadFromConfig(Path: string; Config: TRttiXMLConfig); overload;
     procedure SaveToConfig(Config: TConfigStorage); overload;
@@ -106,7 +108,7 @@
     procedure CheckConsistency; virtual;
 
     // simplifying
-    procedure Simplify(ExistingNames: TStrings);
+    procedure Simplify(ExistingNames: TStrings; ParentMinimized:boolean);
     procedure DeleteNode(ChildNode: TAnchorDockLayoutTreeNode);
     function FindNodeBoundSplitter(ChildNode: TAnchorDockLayoutTreeNode;
                                    Side: TAnchorKind): TAnchorDockLayoutTreeNode;
@@ -135,6 +137,7 @@
     property Monitor: integer read FMonitor write SetMonitor;
     property HeaderPosition: TADLHeaderPosition read FHeaderPosition write SetHeaderPosition;
     property TabPosition: TTabPosition read FTabPosition write SetTabPosition;
+    property Minimized: Boolean read FMinimized write SetMinimized;
     function Count: integer;
     function IsSplitter: boolean;
     function IsRootWindow: boolean;
@@ -988,6 +991,13 @@
   IncreaseChangeStamp;
 end;
 
+procedure TAnchorDockLayoutTreeNode.SetMinimized(const AValue: boolean);
+begin
+  if FMinimized=AValue then exit;
+  FMinimized:=AValue;
+  IncreaseChangeStamp;
+end;
+
 procedure TAnchorDockLayoutTreeNode.SetTop(const AValue: integer);
 begin
   if Top=AValue then exit;
@@ -1084,6 +1094,7 @@
   BoundSplitterPos:=Node.BoundSplitterPos;
   WorkAreaRect:=Node.WorkAreaRect;
   Monitor:=Node.Monitor;
+  Minimized:=Node.Minimized;
   for a:=low(TAnchorKind) to high(TAnchorKind) do
     Anchors[a]:=Node.Anchors[a];
   while Count>Node.Count do Nodes[Count-1].Free;
@@ -1098,9 +1109,10 @@
   end;
 end;
 
-procedure TAnchorDockLayoutTreeNode.Assign(AControl: TControl; OverrideBoundsRect: Boolean=false);
+procedure TAnchorDockLayoutTreeNode.Assign(AControl: TControl; OverrideBoundsRect: Boolean; AMinimized: Boolean);
 var
   AnchorControl: TControl;
+  ParentForm:TCustomForm;
   a: TAnchorKind;
 begin
   Name:=AControl.Name;
@@ -1109,12 +1121,18 @@
   else
     BoundsRect:=AControl.BoundsRect;
   Align:=AControl.Align;
+  Minimized:=AMinimized;
   if (AControl.Parent=nil) and (AControl is TCustomForm) then begin
     WindowState:=TCustomForm(AControl).WindowState;
     Monitor:=TCustomForm(AControl).Monitor.MonitorNum;
     WorkAreaRect:=TCustomForm(AControl).Monitor.WorkareaRect;
-  end else
-    WindowState:=GetParentForm(AControl).WindowState;
+  end else begin
+    ParentForm:=GetParentForm(AControl);
+    if assigned(ParentForm) then
+      WindowState:=ParentForm.WindowState
+    else
+      WindowState:=wsNormal;
+  end;
   if AControl is TCustomTabControl then
     TabPosition:=TCustomTabControl(AControl).TabPosition
   else
@@ -1137,6 +1155,7 @@
   Clear;
   Name:=Config.GetValue('Name','');
   NodeType:=NameToADLTreeNodeType(Config.GetValue('Type',ADLTreeNodeTypeNames[adltnNone]));
+  Minimized:=Config.GetValue('Minimized',false);
   Left:=Config.GetValue('Bounds/Left',0);
   Top:=Config.GetValue('Bounds/Top',0);
   Width:=Config.GetValue('Bounds/Width',0);
@@ -1171,6 +1190,7 @@
   Clear;
   Name:=Config.GetValue(Path+'Name','');
   NodeType:=NameToADLTreeNodeType(Config.GetValue(Path+'Type',ADLTreeNodeTypeNames[adltnNone]));
+  Minimized:=Config.GetValue(Path+'Minimized',false);
   Left:=Config.GetValue(Path+'Bounds/Left',0);
   Top:=Config.GetValue(Path+'Bounds/Top',0);
   Width:=Config.GetValue(Path+'Bounds/Width',0);
@@ -1219,6 +1239,7 @@
                                           ADLHeaderPositionNames[adlhpAuto]);
   Config.SetDeleteValue('Header/TabPosition',ADLTabPostionNames[TabPosition],
                                              ADLTabPostionNames[tpTop]);
+  Config.SetDeleteValue('Minimized',Minimized,False);
   Config.SetDeleteValue('Monitor',Monitor,0);
   Config.SetDeleteValue('ChildCount',Count,0);
   for i:=1 to Count do begin
@@ -1252,6 +1273,7 @@
                                                ADLHeaderPositionNames[adlhpAuto]);
   Config.SetDeleteValue(Path+'Header/TabPosition',ADLTabPostionNames[TabPosition],
                                                   ADLTabPostionNames[tpTop]);
+  Config.SetDeleteValue(Path+'Minimized',Minimized,False);
   Config.SetDeleteValue(Path+'Monitor',Monitor,0);
   Config.SetDeleteValue(Path+'ChildCount',Count,0);
   for i:=1 to Count do
@@ -1397,7 +1419,7 @@
   end;
 end;
 
-procedure TAnchorDockLayoutTreeNode.Simplify(ExistingNames: TStrings);
+procedure TAnchorDockLayoutTreeNode.Simplify(ExistingNames: TStrings; ParentMinimized:boolean);
 { Simplification rules:
    1. Control nodes without existing name are deleted.
    2. Empty layouts and pages are deleted
@@ -1406,16 +1428,18 @@
 var
   i: Integer;
   ChildNode: TAnchorDockLayoutTreeNode;
+  NodeMinimized:boolean;
 begin
   // simplify children
   i:=Count-1;
   while i>=0 do begin
     ChildNode:=Nodes[i];
-    ChildNode.Simplify(ExistingNames);
+    NodeMinimized:=ParentMinimized or ChildNode.Minimized;
+    ChildNode.Simplify(ExistingNames,NodeMinimized);
 
     if (ChildNode.NodeType=adltnControl) then begin
       // leaf node => check if there is a control
-      if (ChildNode.Name='') or (ExistingNames.IndexOf(ChildNode.Name)<0) then
+      if (ChildNode.Name='') or ((ExistingNames.IndexOf(ChildNode.Name)<0) and (not NodeMinimized)) then
         DeleteNode(ChildNode);
     end else if ChildNode.IsSplitter then begin
       // splitter
@@ -1424,7 +1448,7 @@
         ChildNode[0].Free;
     end else if ChildNode.NodeType=adltnCustomSite then begin
       // custom dock site
-    end else if ChildNode.Count=0 then begin
+    end else if (ChildNode.Count=0)and(not NodeMinimized) then begin
       // inner node without child => delete
       DeleteNode(ChildNode);
     end else if (ChildNode.Count=1)
Index: components/anchordocking/anchordockstr.pas
===================================================================
--- components/anchordocking/anchordockstr.pas	(revision 59428)
+++ components/anchordocking/anchordockstr.pas	(working copy)
@@ -8,6 +8,7 @@
 
 resourcestring
   adrsClose = 'Close';
+  adrsMinimize = 'Minimize';
   adrsQuit = 'Quit %s';
   adrsTabPosition = 'Tab position';
   adrsMovePageRight = 'Move page right';
@@ -82,6 +83,8 @@
   adrsFilledHeadersHint = 'Fill headers of docked controls';
   adrsHighlightFocused = 'Highlight focused';
   adrsHighlightFocusedHint = 'Highlight header of focused docked control';
+  adrsDockSitesCanBeMinimized = 'Dock sites can be minimized';
+  adrsDockSitesCanBeMinimizedHint = 'Dock sites can be minimized';
 
 implementation
 
Index: components/anchordocking/design/anchordesktopoptions.pas
===================================================================
--- components/anchordocking/design/anchordesktopoptions.pas	(revision 59428)
+++ components/anchordocking/design/anchordesktopoptions.pas	(working copy)
@@ -272,7 +272,7 @@
         // custom dock site
         LayoutNode:=FTree.NewNode(FTree.Root);
         LayoutNode.NodeType:=adltnCustomSite;
-        LayoutNode.Assign(AForm);
+        LayoutNode.Assign(AForm,false,false);
         // can have one normal dock site
         Site:=TAnchorDockManager(AForm.DockManager).GetChildSite;
         if Site<>nil then begin
@@ -287,7 +287,7 @@
         raise EAnchorDockLayoutError.Create('invalid root control for save: '+DbgSName(AControl));
     end;
     // remove invisible controls
-    FTree.Root.Simplify(VisibleControls);
+    FTree.Root.Simplify(VisibleControls,false);
   finally
     VisibleControls.Free;
     SavedSites.Free;

Andrey Zubarev

2018-11-07 11:30

reporter   ~0111824

Last edited: 2018-11-07 14:16

View 2 revisions

anchordocking_minimize_docksite6.patch
In the first approximation everything works. Please test!
-Need a timer, for not close overlapping form immediately after the loss of the mouse

Andrey Zubarev

2018-11-07 14:16

reporter  

anchordocking_minimize_docksite7.patch (67,286 bytes)   
Index: components/anchordocking/anchordocking.pas
===================================================================
--- components/anchordocking/anchordocking.pas	(revision 59428)
+++ components/anchordocking/anchordocking.pas	(working copy)
@@ -109,6 +109,11 @@
 const ADAutoSizingReason = 'TAnchorDockMaster Delayed';
 {$ENDIF}
 
+const EmptyMouseTimeStartX=low(Integer);
+      MouseNoMoveDelta=5;
+      MouseNoMoveTime=500;
+      HideOverlappingFormByMouseLoseTime=500;
+
 type
   TAnchorDockHostSite = class;
 
@@ -123,6 +128,14 @@
            PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
   end;
 
+  TAnchorDockMinimizeButton = class(TCustomSpeedButton)
+  protected
+    function GetDrawDetails: TThemedElementDetails; override;
+    procedure CalculatePreferredSize(var PreferredWidth,
+           PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
+  end;
+
+
   { TAnchorDockHeader
     The panel of a TAnchorDockHostSite containing the close button and the
     caption when the form is docked. The header can be shown at any of the four
@@ -133,9 +146,12 @@
   TAnchorDockHeader = class(TCustomPanel)
   private
     FCloseButton: TCustomSpeedButton;
+    FMinimizeButton: TCustomSpeedButton;
     FHeaderPosition: TADLHeaderPosition;
     fFocused:Boolean;
+    FMouseTimeStartX,FMouseTimeStartY:Integer;
     procedure CloseButtonClick(Sender: TObject);
+    procedure MinimizeButtonClick(Sender: TObject);
     procedure HeaderPositionItemClick(Sender: TObject);
     procedure UndockButtonClick(Sender: TObject);
     procedure MergeButtonClick(Sender: TObject);
@@ -147,6 +163,11 @@
           PreferredHeight: integer; WithThemeSpace: Boolean); override;
     procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X,
              Y: Integer); override;
+    procedure MouseMove(Shift: TShiftState; X,Y: Integer); override;
+    procedure MouseLeave;  override;
+    procedure StartMouseNoMoveTimer(X, Y: Integer);
+    procedure StopMouseNoMoveTimer;
+    procedure DoMouseNoMoveTimer(Sender: TObject);
     procedure UpdateHeaderControls;
     procedure SetAlign(Value: TAlign); override;
     procedure DoOnShowHint(HintInfo: PHintInfo); override;
@@ -154,6 +175,7 @@
   public
     constructor Create(TheOwner: TComponent); override;
     property CloseButton: TCustomSpeedButton read FCloseButton;
+    property MinimizeButton: TCustomSpeedButton read FMinimizeButton;
     property HeaderPosition: TADLHeaderPosition read FHeaderPosition write SetHeaderPosition;
     property BevelOuter default bvNone;
   end;
@@ -190,6 +212,7 @@
     procedure SetBoundsKeepDockBounds(ALeft, ATop, AWidth, AHeight: integer); // movement for scaling keeps the DockBounds
     function SideAnchoredControlCount(Side: TAnchorKind): integer;
     function HasAnchoredControls: boolean;
+    function GetSpliterBoundsWithUnminimizedDockSites:TRect;
     procedure SaveLayout(LayoutNode: TAnchorDockLayoutTreeNode);
     function HasOnlyOneSibling(Side: TAnchorKind; MinPos, MaxPos: integer): TControl;
     property DockRestoreBounds: TRect read FDockRestoreBounds write FDockRestoreBounds;
@@ -241,6 +264,15 @@
   end;
   TAnchorDockPageControlClass = class of TAnchorDockPageControl;
 
+
+  TAnchorDockOverlappingForm = class(TCustomForm)
+  protected
+    procedure MouseLeave;  override;
+  public
+    AnchorDockHostSite:TAnchorDockHostSite;
+    constructor CreateNew(AOwner: TComponent; Num: Integer = 0); override;
+  end;
+
   { TAnchorDockHostSite
     This form is the dockhostsite for all controls.
     When docked together they build a tree structure with the docked controls
@@ -262,7 +294,10 @@
     FPages: TAnchorDockPageControl;
     FSiteType: TAnchorDockHostSiteType;
     FBoundSplitter: TAnchorDockSplitter;
-    fUpdateLayout: integer;
+    fUpdateLayout: Integer;
+    FMinimized: Boolean;
+    fMinimization: Boolean;
+    FMinimizedControl: TControl;
     procedure SetHeaderSide(const AValue: TAnchorKind);
   protected
     procedure DoEnter; override;
@@ -319,6 +354,10 @@
     destructor Destroy; override;
     function CloseQuery: boolean; override;
     function CloseSite: boolean; virtual;
+    procedure MinimizeSite; virtual;
+    procedure AsyncMinimizeSite(Data: PtrInt);
+    procedure ShowMinimizedControl;
+    procedure HideMinimizedControl;
     procedure RemoveControl(AControl: TControl); override;
     procedure InsertControl(AControl: TControl; Index: integer); override;
     procedure GetSiteInfo(Client: TControl; var InfluenceRect: TRect;
@@ -431,6 +470,7 @@
     FShowHeader: boolean;
     FShowHeaderCaption: boolean;
     FSplitterWidth: integer;
+    FDockSitecCanBeMinimized: boolean;
     procedure SetAllowDragging(AValue: boolean);
     procedure SetDockOutsideMargin(AValue: integer);
     procedure SetDockParentMargin(AValue: integer);
@@ -448,6 +488,7 @@
     procedure SetHeaderFlatten(AValue: boolean);
     procedure SetHeaderFilled(AValue: boolean);
     procedure SetHeaderHighlightFocused(AValue: boolean);
+    procedure SetDockSitecCanBeMinimized(AValue: boolean);
   public
     property DragTreshold: integer read FDragTreshold write SetDragTreshold;
     property DockOutsideMargin: integer read FDockOutsideMargin write SetDockOutsideMargin;
@@ -466,6 +507,7 @@
     property HeaderFlatten: boolean read FHeaderFlatten write SetHeaderFlatten;
     property HeaderFilled: boolean read FHeaderFilled write SetHeaderFilled;
     property HeaderHighlightFocused: boolean read FHeaderHighlightFocused write SetHeaderHighlightFocused;
+    property DockSitesCanBeMinimized: boolean read FDockSitecCanBeMinimized write SetDockSitecCanBeMinimized;
     procedure IncreaseChangeStamp; inline;
     property ChangeStamp: integer read FChangeStamp;
     procedure LoadFromConfig(Config: TConfigStorage); overload;
@@ -502,6 +544,7 @@
     FHeaderFlatten: boolean;
     FHeaderFilled: boolean;
     FHeaderHighlightFocused: boolean;
+    FDockSitesCanBeMinimized: boolean;
     FIdleConnected: Boolean;
     FManagerClass: TAnchorDockManagerClass;
     FOnCreateControl: TADCreateControlEvent;
@@ -531,6 +574,7 @@
     fPopupMenu: TPopupMenu;
     // Used by RestoreLayout:
     WorkArea, SrcWorkArea: TRect;
+    FOverlappingForm:TAnchorDockOverlappingForm;
 
     function GetControls(Index: integer): TControl;
     function GetLocalizedHeaderHint: string;
@@ -541,6 +585,8 @@
     function GetNodeSite(Node: TAnchorDockLayoutTreeNode): TAnchorDockHostSite;
     procedure MapTreeToControls(Tree: TAnchorDockLayoutTree);
     function RestoreLayout(Tree: TAnchorDockLayoutTree; Scale: boolean): boolean;
+    procedure SetMinimizedState(Tree: TAnchorDockLayoutTree);
+    procedure SetnodeMinimizedState(ANode: TAnchorDockLayoutTreeNode);
     procedure EnableAllAutoSizing;
     procedure ClearLayoutProperties(AControl: TControl; NewAlign: TAlign = alClient);
     procedure PopupMenuPopup(Sender: TObject);
@@ -561,6 +607,7 @@
     procedure SetHeaderFlatten(AValue: boolean);
     procedure SetHeaderFilled(AValue: boolean);
     procedure SetHeaderHighlightFocused(AValue: boolean);
+    procedure SetDockSitesCanBeMinimized(AValue: boolean);
 
     procedure SetShowMenuItemShowHeader(AValue: boolean);
     procedure SetupSite(Site: TWinControl; ANode: TAnchorDockLayoutTreeNode;
@@ -584,8 +631,12 @@
     procedure SetHideHeaderCaptionFloatingControl(const AValue: boolean);
     procedure SetSplitterWidth(const AValue: integer);
     procedure OnIdle(Sender: TObject; var Done: Boolean);
+    procedure StartHideOverlappingTimer;
+    procedure StopHideOverlappingTimer;
     procedure AsyncSimplify({%H-}Data: PtrInt);
   public
+    procedure ShowOverlappingForm;
+    procedure HideOverlappingForm(Sender: TObject);
     constructor Create(AOwner: TComponent); override;
     destructor Destroy; override;
     function FullRestoreLayout(Tree: TAnchorDockLayoutTree; Scale: Boolean): Boolean;
@@ -680,6 +731,7 @@
     property HeaderFlatten: boolean read FHeaderFlatten write SetHeaderFlatten default true;
     property HeaderFilled: boolean read FHeaderFilled write SetHeaderFilled default true;
     property HeaderHighlightFocused: boolean read FHeaderHighlightFocused write SetHeaderHighlightFocused default false;
+    property DockSitesCanBeMinimized: boolean read FDockSitesCanBeMinimized write SetDockSitesCanBeMinimized default false;
 
     property SplitterWidth: integer read FSplitterWidth write SetSplitterWidth default 4;
     property ScaleOnResize: boolean read FScaleOnResize write SetScaleOnResize default true; // scale children when resizing a site
@@ -698,6 +750,7 @@
 
 var
   DockMaster: TAnchorDockMaster = nil;
+  DockTimer: TTimer = nil;
 
 const
   ADHeaderStyleNames: array[TADHeaderStyle] of string = (
@@ -970,6 +1023,27 @@
   end;
 end;
 
+function CountAndReturnOnlyOneMinimizedAnchoredControls(Control: TControl; Side: TAnchorKind): TAnchorDockHostSite;
+var
+  i,Counter: Integer;
+  Neighbour: TControl;
+begin
+  Counter:=0;
+  for i:=0 to Control.AnchoredControlCount-1 do begin
+    Neighbour:=Control.AnchoredControls[i];
+    if Neighbour.Visible then
+    if Neighbour is TAnchorDockHostSite then
+    if (OppositeAnchor[Side] in Neighbour.Anchors)
+    and (Neighbour.AnchorSide[OppositeAnchor[Side]].Control=Control) then begin
+      inc(Counter);
+      result:=TAnchorDockHostSite(Neighbour);
+    end;
+  end;
+  if (Counter=1)and(result is TAnchorDockHostSite)and((result as TAnchorDockHostSite).FMinimized) then
+  else
+    result:=Nil;
+end;
+
 function NeighbourCanBeShrinked(EnlargeControl, Neighbour: TControl;
   Side: TAnchorKind): boolean;
 { returns true if Neighbour can be shrinked on the opposite side of Side
@@ -1361,6 +1435,13 @@
   IncreaseChangeStamp;
 end;
 
+procedure TAnchorDockSettings.SetDockSitecCanBeMinimized(AValue: boolean);
+begin
+  if FDockSitecCanBeMinimized=AValue then Exit;
+  FDockSitecCanBeMinimized:=AValue;
+  IncreaseChangeStamp;
+end;
+
 procedure TAnchorDockSettings.Assign(Source: TAnchorDockSettings);
 begin
   FAllowDragging := Source.FAllowDragging;
@@ -1381,6 +1462,7 @@
   FShowHeaderCaption := Source.FShowHeaderCaption;
   FSplitterWidth := Source.FSplitterWidth;
   FHeaderHighlightFocused:=Source.FHeaderHighlightFocused;
+  FDockSitecCanBeMinimized:=Source.FDockSitecCanBeMinimized;
 end;
 
 procedure TAnchorDockSettings.IncreaseChangeStamp;
@@ -1407,6 +1489,7 @@
   HeaderFlatten:=Config.GetValue('HeaderFlatten',true);
   HeaderFilled:=Config.GetValue('HeaderFilled',true);
   HeaderHighlightFocused:=Config.GetValue('HeaderHighlightFocused',False);
+  DockSitesCanBeMinimized:=Config.GetValue('DockSitecCanBeMinimized',False);
   Config.UndoAppendBasePath;
 end;
 
@@ -1429,6 +1512,7 @@
   Config.SetDeleteValue(Path+'HeaderFlatten',HeaderFlatten,true);
   Config.SetDeleteValue(Path+'HeaderFilled',HeaderFilled,true);
   Config.SetDeleteValue(Path+'HeaderHighlightFocused',HeaderHighlightFocused,False);
+  Config.SetDeleteValue(Path+'DockSitecCanBeMinimized',DockSitesCanBeMinimized,False);
 end;
 
 procedure TAnchorDockSettings.SaveToConfig(Config: TConfigStorage);
@@ -1450,6 +1534,7 @@
   Config.SetDeleteValue('HeaderFlatten',HeaderFlatten,true);
   Config.SetDeleteValue('HeaderFilled',HeaderFilled,true);
   Config.SetDeleteValue('HeaderHighlightFocused',HeaderHighlightFocused,False);
+  Config.SetDeleteValue('DockSitecCanBeMinimized',DockSitesCanBeMinimized,False);
   Config.UndoAppendBasePath;
 end;
 
@@ -1472,6 +1557,7 @@
       and (HeaderFlatten=Settings.HeaderFlatten)
       and (HeaderFilled=Settings.HeaderFilled)
       and (HeaderHighlightFocused=Settings.HeaderHighlightFocused)
+      and (DockSitesCanBeMinimized=Settings.DockSitesCanBeMinimized)
       ;
 end;
 
@@ -1494,6 +1580,7 @@
   HeaderFlatten:=Config.GetValue(Path+'HeaderFlatten',true);
   HeaderFilled:=Config.GetValue(Path+'HeaderFilled',true);
   HeaderHighlightFocused:=Config.GetValue(Path+'HeaderHighlightFocused',False);
+  DockSitesCanBeMinimized:=Config.GetValue(Path+'DockSitecCanBeMinimized',False);
 end;
 
 { TAnchorDockMaster }
@@ -2021,6 +2108,8 @@
     aHostSite:=TAnchorDockHostSite(Site);
     aHostSite.Header.HeaderPosition:=ANode.HeaderPosition;
     aHostSite.DockRestoreBounds:=NewBounds;
+    //aHostSite.FMinimized:=ANode.Minimized;
+    //we update aHostSite.FMinimized in TAnchorDockMaster.SetMinimizedState
     if (ANode.NodeType<>adltnPages) and (aHostSite.Pages<>nil) then
       aHostSite.FreePages;
   end;
@@ -2040,6 +2129,25 @@
   fTreeNameToDocker[Node.Name]:=Result;
 end;
 
+procedure TAnchorDockMaster.SetNodeMinimizedState(ANode: TAnchorDockLayoutTreeNode);
+var
+  HostSite:TAnchorDockHostSite;
+  i:integer;
+begin
+  HostSite:=GetNodeSite(ANode);
+  if Assigned(HostSite) then
+    if HostSite.FMinimized<>ANode.Minimized then
+      Application.QueueAsyncCall(@HostSite.AsyncMinimizeSite,0);
+      //HostSite.MinimizeSite;
+  for i:=0 to ANode.Count-1 do
+    SetnodeMinimizedState(ANode.Nodes[i]);
+end;
+
+procedure TAnchorDockMaster.SetMinimizedState(Tree: TAnchorDockLayoutTree);
+begin
+  SetnodeMinimizedState(Tree.Root);
+end;
+
 function TAnchorDockMaster.RestoreLayout(Tree: TAnchorDockLayoutTree;
   Scale: boolean): boolean;
 
@@ -2193,7 +2301,7 @@
       try
         SetupSite(Site,ANode,AParent);
         Site.FSiteType:=adhstPages;
-        Site.Header.Parent:=nil;
+        //Site.Header.Parent:=nil;
         if Site.Pages=nil then
           Site.CreatePages;
         for i:=0 to ANode.Count-1 do begin
@@ -2358,7 +2466,7 @@
       debugln(ControlNames.Text);
       {$ENDIF}
       // if some forms/controls could not be created the layout needs to be adapted
-      Tree.Root.Simplify(ControlNames);
+      Tree.Root.Simplify(ControlNames,false);
 
       // reuse existing sites to reduce flickering
       MapTreeToControls(Tree);
@@ -2368,6 +2476,7 @@
 
       // create sites, move controls
       RestoreLayout(Tree,Scale);
+      SetMinimizedState(Tree);
     finally
       EndUpdate;
     end;
@@ -2422,11 +2531,40 @@
   OptionsChanged;
 end;
 
+procedure TAnchorDockMaster.StartHideOverlappingTimer;
+begin
+  if not DockTimer.Enabled then begin
+    DockTimer.Interval:=HideOverlappingFormByMouseLoseTime;
+    DockTimer.OnTimer:=@HideOverlappingForm;
+    DockTimer.Enabled:=true;
+  end;
+end;
+
+procedure TAnchorDockMaster.StopHideOverlappingTimer;
+begin
+  DockTimer.Enabled:=False;
+  DockTimer.Interval:=0;
+  DockTimer.OnTimer:=nil;
+end;
+
 procedure TAnchorDockMaster.OnIdle(Sender: TObject; var Done: Boolean);
+var
+  MousePos: TPoint;
+  Bounds:Trect;
 begin
   if Done then ;
-  IdleConnected:=false;
   Restoring:=false;
+  if FOverlappingForm=nil then
+    IdleConnected:=false
+  else begin
+    GetCursorPos(MousePos);
+    Bounds.TopLeft:=FOverlappingForm.ClientToScreen(point(0,0));
+    Bounds.BottomRight:=FOverlappingForm.ClientToScreen(point(FOverlappingForm.Width,FOverlappingForm.Height));
+    if not PtInRect(Bounds,MousePos) then
+      StartHideOverlappingTimer
+    else
+      StopHideOverlappingTimer;
+  end;
 end;
 
 procedure TAnchorDockMaster.AsyncSimplify(Data: PtrInt);
@@ -2514,6 +2652,24 @@
   InvalidateHeaders;
 end;
 
+procedure TAnchorDockMaster.SetDockSitesCanBeMinimized(AValue: boolean);
+var
+  i:integer;
+  Site: TAnchorDockHostSite;
+begin
+  if FDockSitesCanBeMinimized=AValue then Exit;
+  FDockSitesCanBeMinimized:=AValue;
+  for i:=0 to ComponentCount-1 do begin
+    Site:=TAnchorDockHostSite(Components[i]);
+    if not (Site is TAnchorDockHostSite) then continue;
+    if (Site.Header<>nil) then begin
+      DisableControlAutoSizing(Site);
+      Site.UpdateHeaderShowing;
+    end;
+  end;
+  EnableAllAutoSizing;
+  OptionsChanged;
+end;
 procedure TAnchorDockMaster.SetScaleOnResize(AValue: boolean);
 begin
   if FScaleOnResize=AValue then Exit;
@@ -2668,6 +2824,20 @@
     EnableAllAutoSizing;
 end;
 
+procedure TAnchorDockMaster.ShowOverlappingForm;
+begin
+  FOverlappingForm.Show;
+  IdleConnected:=true;
+end;
+
+procedure TAnchorDockMaster.HideOverlappingForm(Sender: TObject);
+begin
+  StopHideOverlappingTimer;
+  FOverlappingForm.Hide;
+  FOverlappingForm.AnchorDockHostSite.HideMinimizedControl;
+  IdleConnected:=false;
+end;
+
 constructor TAnchorDockMaster.Create(AOwner: TComponent);
 begin
   inherited Create(AOwner);
@@ -2698,14 +2868,14 @@
   FPageClass:=TAnchorDockPage;
   FRestoreLayouts:=TAnchorDockRestoreLayouts.Create;
   FHeaderHighlightFocused:=false;
+  FDockSitesCanBeMinimized:=false;
+  FOverlappingForm:=nil;
 end;
 
 destructor TAnchorDockMaster.Destroy;
 var
   AControl: TControl;
-  {$IFDEF VerboseAnchorDocking}
-  i: Integer;
-  {$ENDIF}
+  i, j: Integer;
 begin
   QueueSimplify:=false;
   FreeAndNil(FRestoreLayouts);
@@ -2727,6 +2897,12 @@
     debugln(['TAnchorDockMaster.Destroy ',i,'/',ComponentCount,' ',DbgSName(Components[i])]);
   end;
   {$ENDIF}
+  for i:=0 to ComponentCount-1 do begin
+    for j:=0 to ComponentCount-1 do begin
+      if i<>j then
+        TControl(Components[i]).RemoveAllHandlersOfObject(TControl(Components[j]));
+  end;
+  end;
   inherited Destroy;
 end;
 
@@ -3018,7 +3194,8 @@
   i:=Screen.CustomFormCount-1;
   while i>=0 do begin
     AForm:=GetParentForm(Screen.CustomForms[i]);
-    AForm.Hide;
+    if Assigned(AForm)then
+      AForm.Hide;
     i:=Min(i,Screen.CustomFormCount)-1;
   end;
 
@@ -3062,8 +3239,11 @@
   end;
 end;
 
-function GetParentFormOrDockPanel(Control: TControl): TCustomForm;
+function GetParentFormOrDockPanel(Control: TControl; TopForm:Boolean=true): TCustomForm;
+var
+  oldControl: TControl;
 begin
+  oldControl:=Control;
   while (Control <> nil) and (Control.Parent <> nil) do
   begin
     if (Control is TAnchorDockPanel) then
@@ -3076,6 +3256,18 @@
     Result := TCustomForm(Control)
   else
     Result := nil;
+  if not TopForm then begin
+    if Control is TAnchorDockPanel then
+      exit;
+    Control:=oldControl;
+    while (Control <> nil) and (Control.Parent <> nil) do
+    begin
+      Control := Control.Parent;
+      if (Control is TCustomForm) then
+        Break;
+    end;
+    Result := TCustomForm(Control);
+  end;
 end;
 
 procedure TAnchorDockMaster.SaveMainLayoutToTree(LayoutTree: TAnchorDockLayoutTree);
@@ -3088,12 +3280,12 @@
   AFormOrDockPanel: TWinControl;
   VisibleControls: TStringList;
 
-  procedure SaveFormOrDockPanel(theFormOrDockPanel: TWinControl; SaveChildren: boolean);
+  procedure SaveFormOrDockPanel(theFormOrDockPanel: TWinControl; SaveChildren: boolean; AMinimized:boolean);
   begin
     // custom dock site
     LayoutNode:=LayoutTree.NewNode(LayoutTree.Root);
     LayoutNode.NodeType:=adltnCustomSite;
-    LayoutNode.Assign(theFormOrDockPanel,theFormOrDockPanel is TAnchorDockPanel);
+    LayoutNode.Assign(theFormOrDockPanel,theFormOrDockPanel is TAnchorDockPanel,AMinimized);
     // can have one normal dock site
     if SaveChildren then
     begin
@@ -3124,7 +3316,7 @@
       debugln(['TAnchorDockMaster.SaveMainLayoutToTree AForm=',DbgSName(AFormOrDockPanel)]);
       DebugWriteChildAnchors(AFormOrDockPanel,true,true);
       if AFormOrDockPanel is TAnchorDockPanel then begin
-        SaveFormOrDockPanel(GetParentFormOrDockPanel(AFormOrDockPanel),{false}true);
+        SaveFormOrDockPanel(GetParentFormOrDockPanel(AFormOrDockPanel),true,false);
         //LayoutNode:=LayoutTree.NewNode(LayoutTree.Root);
         //TAnchorDockPanel(AFormOrDockPanel).SaveLayout(LayoutTree,LayoutNode);
       end else if AFormOrDockPanel is TAnchorDockHostSite then begin
@@ -3132,12 +3324,12 @@
         LayoutNode:=LayoutTree.NewNode(LayoutTree.Root);
         Site.SaveLayout(LayoutTree,LayoutNode);
       end else if IsCustomSite(AFormOrDockPanel) then begin
-        SaveFormOrDockPanel(AFormOrDockPanel,true);
+        SaveFormOrDockPanel(AFormOrDockPanel,true,false);
       end else
         raise EAnchorDockLayoutError.Create('invalid root control for save: '+DbgSName(AControl));
     end;
     // remove invisible controls
-    LayoutTree.Root.Simplify(VisibleControls);
+    LayoutTree.Root.Simplify(VisibleControls,false);
   finally
     VisibleControls.Free;
     SavedSites.Free;
@@ -3157,7 +3349,7 @@
     (AControl as TAnchorDockPanel).SaveLayout(LayoutTree,LayoutTree.Root);
   end else if IsCustomSite(AControl) then begin
     LayoutTree.Root.NodeType:=adltnCustomSite;
-    LayoutTree.Root.Assign(AControl);
+    LayoutTree.Root.Assign(AControl,false,false);
     // can have one normal dock site
     Site:=TAnchorDockManager(AControl.DockManager).GetChildSite;
     if Site<>nil then begin
@@ -3252,7 +3444,7 @@
       debugln(ControlNames.Text);
       {$ENDIF}
       // if some forms/controls could not be created the layout needs to be adapted
-      Tree.Root.Simplify(ControlNames);
+      Tree.Root.Simplify(ControlNames,false);
 
       // reuse existing sites to reduce flickering
       MapTreeToControls(Tree);
@@ -3262,6 +3454,7 @@
 
       // create sites, move controls
       RestoreLayout(Tree,Scale);
+      SetMinimizedState(Tree);
     finally
       EndUpdate;
     end;
@@ -3323,6 +3516,7 @@
   HeaderFlatten                    := Settings.HeaderFlatten;
   HeaderFilled                     := Settings.HeaderFilled;
   HeaderHighlightFocused           := Settings.HeaderHighlightFocused;
+  DockSitesCanBeMinimized          := Settings.DockSitesCanBeMinimized;
 end;
 
 procedure TAnchorDockMaster.SaveSettings(Settings: TAnchorDockSettings);
@@ -3343,6 +3537,7 @@
   Settings.HeaderFlatten:=HeaderFlatten;
   Settings.HeaderFilled:=HeaderFilled;
   Settings.HeaderHighlightFocused:=HeaderHighlightFocused;
+  Settings.DockSitesCanBeMinimized:=DockSitesCanBeMinimized;
 end;
 
 function TAnchorDockMaster.SettingsAreEqual(Settings: TAnchorDockSettings
@@ -3680,6 +3875,7 @@
     AControl:=TControl(Sender);
     if not (csDestroying in ComponentState) then begin
       if (not AControl.Visible)
+      and (not FMinimized)
       and (not ((AControl is TAnchorDockHeader)
                or (AControl is TAnchorDockSplitter)
                or (AControl is TAnchorDockHostSite)))
@@ -4119,6 +4315,8 @@
 end;
 
 procedure TAnchorDockHostSite.FreePages;
+var
+  i:Integer;
 begin
   FreeAndNil(FPages);
 end;
@@ -4233,6 +4431,14 @@
         akRight: NewBounds.Right:=AControl.Left+AControl.Width;
         akBottom: NewBounds.Bottom:=AControl.Top+AControl.Height;
         end;
+        if (sibling is TAnchorDockHostSite) then
+        if (sibling as TAnchorDockHostSite).FMinimized then begin
+          (sibling as TAnchorDockHostSite).FMinimized:=false;
+          (sibling as TAnchorDockHostSite).FMinimizedControl.Parent:=(sibling as TAnchorDockHostSite);
+          (sibling as TAnchorDockHostSite).FMinimizedControl.Visible:=True;
+          (sibling as TAnchorDockHostSite).FMinimizedControl:=nil;
+          (sibling as TAnchorDockHostSite).UpdateHeaderAlign;
+        end;
         Sibling.BoundsRect:=NewBounds;
       end;
     end;
@@ -4306,6 +4512,13 @@
       FSiteType:=adhstOneControl;
       OnlySiteLeft.Align:=alClient;
       Header.Parent:=Self;
+      if OnlySiteLeft.FMinimized then begin
+        OnlySiteLeft.FMinimized:=false;
+        OnlySiteLeft.FMinimizedControl.Parent:=OnlySiteLeft;
+        OnlySiteLeft.FMinimizedControl.Visible:=True;
+        OnlySiteLeft.FMinimizedControl:=nil;
+        UpdateHeaderAlign;
+      end;
       UpdateHeaderAlign;
 
       //debugln(['TAnchorDockHostSite.RemoveControlFromLayout.ConvertToOneControlType AFTER CONVERT "',Caption,'" to onecontrol OnlySiteLeft="',OnlySiteLeft.Caption,'"']);
@@ -4465,7 +4678,7 @@
     debugln(['TAnchorDockHostSite.Simplify ',DbgSName(Self),' ',DbgSName(AControl)]);
     if AControl is TAnchorDockHostSite then
       SimplifyOneControl
-    else if (AControl=nil) or (csDestroying in AControl.ComponentState) then
+    else if ((AControl=nil) or (csDestroying in AControl.ComponentState)) then
       DockMaster.NeedFree(Self);
   end;
 end;
@@ -4577,7 +4790,8 @@
     Result:=Controls[i];
     if Result.Owner<>Self then exit;
   end;
-  Result:=nil;
+  result:=FMinimizedControl;
+  //Result:=nil;
 end;
 
 function TAnchorDockHostSite.GetSiteCount: integer;
@@ -5165,6 +5379,105 @@
   Result:=Check(Self);
 end;
 
+function CheckOposite(Side:TAnchorKind;var AControl: TControl;out Splitter: TAnchorDockSplitter; out SplitterAnchorKind:TAnchorKind):boolean;
+begin
+  result:=GetDockSplitter(AControl,Side,Splitter);
+  if result then begin
+    if CountAnchoredControls(Splitter,OppositeAnchor[Side])=1 then begin
+      SplitterAnchorKind:=Side;
+      exit;
+    end;
+  end;
+  result:=false
+end;
+
+function FindNearestSpliter(AControl: TControl;out Splitter: TAnchorDockSplitter;out SplitterAnchorKind:TAnchorKind):boolean;
+begin
+  result:=CheckOposite(akTop,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akRight,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akBottom,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akLeft,AControl,Splitter,SplitterAnchorKind);
+end;
+
+procedure TAnchorDockHostSite.MinimizeSite;
+begin
+  //Application.QueueAsyncCall(@AsyncMinimizeSite,0);
+  AsyncMinimizeSite(0);
+end;
+
+procedure TAnchorDockHostSite.AsyncMinimizeSite(Data: PtrInt);
+var
+  AControl: TControl;
+  OpositeDockHostSite:TAnchorDockHostSite;
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
+  //SpliterPercentPosition:Single;
+begin
+  fMinimization:=true;
+  debugln(['TAnchorDockHostSite.MinimizeSite ',DbgSName(Self),' SiteType=',dbgs(SiteType)]);
+  if FMinimized then
+    AControl:=FMinimizedControl
+  else
+    AControl:=GetOneControl;
+  if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+    OpositeDockHostSite:=CountAndReturnOnlyOneMinimizedAnchoredControls(Splitter,SplitterAnchorKind);
+    if (Splitter.Enabled and (OpositeDockHostSite=nil)) or FMinimized then begin
+      FMinimized:=not FMinimized;
+      if FMinimized then begin
+        FMinimizedControl:=AControl;
+        AControl.Visible:=False;
+        AControl.Parent:=nil;
+      end else begin
+        AControl.Parent:=self;
+        AControl.Visible:=True;
+        FMinimizedControl:=nil;
+      end;
+      Splitter.Enabled:=AControl.Visible;
+      UpdateHeaderAlign;
+      Splitter.SetBoundsPercentually;
+    end;
+  end;
+  fMinimization:=false;
+end;
+
+procedure TAnchorDockHostSite.ShowMinimizedControl;
+var
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
+  SpliterRect,OverlappingFormRect:TRect;
+begin
+  if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+    SpliterRect:=Splitter.GetSpliterBoundsWithUnminimizedDockSites;
+    OverlappingFormRect:=BoundsRect;
+    case SplitterAnchorKind of
+         akTop:OverlappingFormRect.Top:=SpliterRect.Bottom;
+        akLeft:OverlappingFormRect.Left:=SpliterRect.Right;
+       akRight:OverlappingFormRect.Right:=SpliterRect.Left;
+      akBottom:OverlappingFormRect.Bottom:=SpliterRect.Top;
+    end;
+    DockMaster.FOverlappingForm:=TAnchorDockOverlappingForm.CreateNew(self);
+    DockMaster.FOverlappingForm.BoundsRect:=OverlappingFormRect;
+    DockMaster.FOverlappingForm.Parent:=GetParentFormOrDockPanel(self,false);
+    DockMaster.FOverlappingForm.AnchorDockHostSite:=self;
+    header.Parent:=DockMaster.FOverlappingForm;
+    FMinimizedControl.Parent:=DockMaster.FOverlappingForm;
+    FMinimizedControl.Show;
+    DockMaster.ShowOverlappingForm;
+  end;
+end;
+
+procedure TAnchorDockHostSite.HideMinimizedControl;
+begin
+   FMinimizedControl.Hide;
+   header.Parent:=self;
+   header.UpdateHeaderControls;
+   FMinimizedControl.Parent:=nil;
+   FreeAndNil(DockMaster.FOverlappingForm);
+end;
+
 function TAnchorDockHostSite.CloseSite: boolean;
 var
   AControl: TControl;
@@ -5306,9 +5619,8 @@
     if Parent is TAnchorDockPage then
       TAnchorDockPage(Parent).UpdateDockCaption;
   end;
-
   // do not show close button for mainform
-  Header.CloseButton.Visible:=not IsParentOf(Application.MainForm);
+  Header.CloseButton.Visible:=(not IsParentOf(Application.MainForm))and(Pages=nil);
 end;
 
 procedure TAnchorDockHostSite.GetSiteInfo(Client: TControl;
@@ -5362,9 +5674,33 @@
 end;
 
 procedure TAnchorDockHostSite.UpdateHeaderAlign;
+const
+OppositeAlign: array[TAnchorKind] of TAlign = (
+  alBottom, // akTop,
+  alRight,  // akLeft,
+  alLeft,   // akRight,
+  alTop     // akBottom
+  );
+OppositeAnchorKindAlign: array[TAnchorKind] of TADLHeaderPosition = (
+  adlhpBottom, // akTop,
+  adlhpRight,  // akLeft,
+  adlhpLeft,   // akRight,
+  adlhpTop     // akBottom
+  );
+var
+  NeededHeaderPosition:TADLHeaderPosition;
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
 begin
   if Header=nil then exit;
-  case Header.HeaderPosition of
+  if FMinimized then begin
+    if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+      NeededHeaderPosition:=OppositeAnchorKindAlign[SplitterAnchorKind];
+    end else
+      NeededHeaderPosition:=Header.HeaderPosition;
+  end else
+    NeededHeaderPosition:=Header.HeaderPosition;
+  case NeededHeaderPosition of
   adlhpAuto:
     if Header.Align in [alLeft,alRight] then begin
       if (ClientHeight>0)
@@ -5390,8 +5726,11 @@
 procedure TAnchorDockHostSite.UpdateHeaderShowing;
 begin
   if Header=nil then exit;
-  if HeaderNeedsShowing then
-    Header.Parent:=Self
+  if HeaderNeedsShowing then begin
+    Header.Parent:=Self;
+    Header.MinimizeButton.Visible:=DockMaster.DockSitesCanBeMinimized;
+    Header.MinimizeButton.Parent:=Header;
+  end
   else
     Header.Parent:=nil;
 end;
@@ -5432,7 +5771,7 @@
   if (SiteType=adhstOneControl) and (OneControl<>nil)
   and (not (OneControl is TAnchorDockHostSite)) then begin
     LayoutNode.NodeType:=adltnControl;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,FMinimized);
     LayoutNode.Name:=OneControl.Name;
     LayoutNode.HeaderPosition:=Header.HeaderPosition;
   end else if (SiteType in [adhstLayout,adhstOneControl]) then begin
@@ -5450,7 +5789,7 @@
         Splitter.SaveLayout(ChildNode);
       end;
     end;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,FMinimized);
     LayoutNode.HeaderPosition:=Header.HeaderPosition;
   end else if SiteType=adhstPages then begin
     LayoutNode.NodeType:=adltnPages;
@@ -5461,7 +5800,7 @@
         Site.SaveLayout(LayoutTree,ChildNode);
       end;
     end;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,FMinimized);
     LayoutNode.HeaderPosition:=Header.HeaderPosition;
   end else
     LayoutNode.NodeType:=adltnNone;
@@ -5476,6 +5815,9 @@
 constructor TAnchorDockHostSite.CreateNew(AOwner: TComponent; Num: Integer);
 begin
   inherited CreateNew(AOwner,Num);
+  FMinimized:=false;
+  fMinimization:=false;
+  FMinimizedControl:=Nil;
   Visible:=false;
   FHeaderSide:=akTop;
   FHeader:=DockMaster.HeaderClass.Create(Self);
@@ -5490,13 +5832,13 @@
 end;
 
 destructor TAnchorDockHostSite.Destroy;
-//var i: Integer;
+var i: Integer;
 begin
-  //debugln(['TAnchorDockHostSite.Destroy ',DbgSName(Self),' Caption="',Caption,'" Self=',dbgs(Pointer(Self)),' ComponentCount=',ComponentCount,' ControlCount=',ControlCount]);
-  {for i:=0 to ComponentCount-1 do
+  debugln(['TAnchorDockHostSite.Destroy ',DbgSName(Self),' Caption="',Caption,'" Self=',dbgs(Pointer(Self)),' ComponentCount=',ComponentCount,' ControlCount=',ControlCount]);
+  for i:=0 to ComponentCount-1 do
     debugln(['TAnchorDockHostSite.Destroy Component ',i,'/',ComponentCount,' ',DbgSName(Components[i])]);
   for i:=0 to ControlCount-1 do
-    debugln(['TAnchorDockHostSite.Destroy Control ',i,'/',ControlCount,' ',DbgSName(Controls[i])]);}
+    debugln(['TAnchorDockHostSite.Destroy Control ',i,'/',ControlCount,' ',DbgSName(Controls[i])]);
   FreePages;
   inherited Destroy;
 end;
@@ -5562,13 +5904,34 @@
 end;
 
 procedure TAnchorDockHeader.CloseButtonClick(Sender: TObject);
+var
+  HeaderParent:TAnchorDockHostSite;
 begin
-  if Parent is TAnchorDockHostSite then begin
-    DockMaster.RestoreLayouts.Add(DockMaster.CreateRestoreLayout(Parent),true);
-    TAnchorDockHostSite(Parent).CloseSite;
+  TWinControl(HeaderParent):=Parent;
+  if HeaderParent=TWinControl(DockMaster.FOverlappingForm) then begin
+    HeaderParent:=DockMaster.FOverlappingForm.AnchorDockHostSite;
+    HeaderParent.HideMinimizedControl;
   end;
+  if HeaderParent is TAnchorDockHostSite then begin
+    DockMaster.RestoreLayouts.Add(DockMaster.CreateRestoreLayout(HeaderParent),true);
+    HeaderParent.CloseSite;
+  end;
 end;
 
+procedure TAnchorDockHeader.MinimizeButtonClick(Sender: TObject);
+var
+  HeaderParent:TAnchorDockHostSite;
+begin
+  TWinControl(HeaderParent):=Parent;
+  if HeaderParent=TWinControl(DockMaster.FOverlappingForm) then begin
+    HeaderParent:=DockMaster.FOverlappingForm.AnchorDockHostSite;
+    HeaderParent.HideMinimizedControl;
+  end;
+  if HeaderParent is TAnchorDockHostSite then begin
+    HeaderParent.MinimizeSite;
+  end;
+end;
+
 procedure TAnchorDockHeader.HeaderPositionItemClick(Sender: TObject);
 var
   Item: TMenuItem;
@@ -5640,6 +6003,13 @@
       r.Right:=CloseButton.Left-1;
   end;
 
+  if MinimizeButton.IsControlVisible and (MinimizeButton.Parent=Self) then begin
+    if Align in [alLeft,alRight] then
+      r.Top:=MinimizeButton.Top+MinimizeButton.Height+1
+    else
+      r.Right:=MinimizeButton.Left-1;
+  end;
+
   // caption
   if Caption<>'' then begin
     if fFocused and DockMaster.HeaderHighlightFocused and NeedHighlightText then
@@ -5728,7 +6098,14 @@
     end else begin
       PreferredHeight:=Max(NeededHeight,PreferredHeight);
     end;
+  end else begin
+    NeededHeight:=CloseButton.Height;
+    if Align in [alLeft,alRight] then begin
+      PreferredWidth:=Max(NeededHeight,PreferredWidth);
+    end else begin
+      PreferredHeight:=Max(NeededHeight,PreferredHeight);
   end;
+  end;
 end;
 
 procedure TAnchorDockHeader.MouseDown(Button: TMouseButton; Shift: TShiftState;
@@ -5735,18 +6112,67 @@
   X, Y: Integer);
 begin
   inherited MouseDown(Button, Shift, X, Y);
-  if (Button=mbLeft) and DockMaster.AllowDragging then
+  if (Button=mbLeft) and (DockMaster.AllowDragging) and (DockMaster.FOverlappingForm=nil) then
     DragManager.DragStart(Parent,false,DockMaster.DragTreshold);
 end;
 
+procedure  TAnchorDockHeader.MouseMove(Shift: TShiftState; X,Y: Integer);
+begin
+  inherited MouseMove(Shift, X, Y);
+  if parent<>nil then
+    if parent is TAnchorDockHostSite then
+      if (parent as TAnchorDockHostSite).FMinimized then
+        if DockMaster.FOverlappingForm=nil then
+          if FMouseTimeStartX=EmptyMouseTimeStartX then
+            StartMouseNoMoveTimer(X, Y)
+          else begin
+            if (abs(FMouseTimeStartX-X)>MouseNoMoveDelta)or(abs(FMouseTimeStartY-Y)>MouseNoMoveDelta)then
+            StopMouseNoMoveTimer;
+          end;
+end;
+
+procedure TAnchorDockHeader.MouseLeave;
+begin
+  inherited;
+  StopMouseNoMoveTimer;
+end;
+
+procedure TAnchorDockHeader.StartMouseNoMoveTimer(X, Y: Integer);
+begin
+  if DockTimer.Enabled then DockTimer.Enabled:=false;
+  DockTimer.Interval:=MouseNoMoveTime;
+  DockTimer.OnTimer:=@DoMouseNoMoveTimer;
+  DockTimer.Enabled:=true;
+end;
+
+procedure TAnchorDockHeader.StopMouseNoMoveTimer;
+begin
+  FMouseTimeStartX:=EmptyMouseTimeStartX;
+  DockTimer.OnTimer:=nil;
+  DockTimer.Enabled:=false;
+end;
+
+procedure TAnchorDockHeader.DoMouseNoMoveTimer(Sender: TObject);
+begin
+  StopMouseNoMoveTimer;
+  if parent<>nil then
+    if parent is TAnchorDockHostSite then
+      if (parent as TAnchorDockHostSite).FMinimized then
+        (parent as TAnchorDockHostSite).ShowMinimizedControl;
+end;
+
 procedure TAnchorDockHeader.UpdateHeaderControls;
 begin
   if Align in [alLeft,alRight] then begin
-    if CloseButton<>nil then
+    if CloseButton<>nil then begin
+      MinimizeButton.Align:=alTop;
       CloseButton.Align:=alTop;
+    end;
   end else begin
-    if CloseButton<>nil then
+    if CloseButton<>nil then begin
+      MinimizeButton.Align:=alRight;
       CloseButton.Align:=alRight;
+    end;
   end;
   //debugln(['TAnchorDockHeader.UpdateHeaderControls ',dbgs(Align),' ',dbgs(CloseButton.Align)]);
 end;
@@ -5787,9 +6213,9 @@
 begin
   inherited Create(TheOwner);
   FHeaderPosition:=adlhpAuto;
-  FCloseButton:=TAnchorDockCloseButton.Create(Self);
   BevelOuter:=bvNone;
   BorderWidth:=0;
+  FCloseButton:=TAnchorDockCloseButton.Create(Self);
   with FCloseButton do begin
     Name:='CloseButton';
     Parent:=Self;
@@ -5799,11 +6225,22 @@
     OnClick:=@CloseButtonClick;
     AutoSize:=true;
   end;
+  FMinimizeButton:=TAnchorDockMinimizeButton.Create(Self);
+  with FMinimizeButton do begin
+    Name:='MinimizeButton';
+    Parent:=Self;
+    Flat:=true;
+    ShowHint:=true;
+    Hint:=adrsMinimize;
+    OnClick:=@MinimizeButtonClick;
+    AutoSize:=true;
+  end;
   Align:=alTop;
   AutoSize:=true;
   ShowHint:=true;
   PopupMenu:=DockMaster.GetPopupMenu;
   fFocused:=false;
+  FMouseTimeStartX:=EmptyMouseTimeStartX;
 end;
 
 { TAnchorDockCloseButton }
@@ -5844,6 +6281,44 @@
   end;
 end;
 
+{ TAnchorDockMinimizeButton }
+
+function TAnchorDockMinimizeButton.GetDrawDetails: TThemedElementDetails;
+
+function WindowPart: TThemedWindow;
+  begin
+    // no check states available
+    Result := twMinButtonNormal;
+    if not IsEnabled then
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonDisabled{$ELSE}twMinButtonDisabled{$ENDIF}
+    else
+    if FState in [bsDown, bsExclusive] then
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonPushed{$ELSE}twMinButtonPushed{$ENDIF}
+    else
+    if FState = bsHot then
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonHot{$ELSE}twMinButtonHot{$ENDIF}
+    else
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonNormal{$ELSE}twMinButtonNormal{$ENDIF};
+  end;
+
+begin
+  Result := ThemeServices.GetElementDetails(WindowPart);
+end;
+
+procedure TAnchorDockMinimizeButton.CalculatePreferredSize(var PreferredWidth,
+  PreferredHeight: integer; WithThemeSpace: Boolean);
+begin
+  with ThemeServices.GetDetailSize(ThemeServices.GetElementDetails({$IFDEF LCLGtk2}twMDIRestoreButtonNormal{$ELSE}twMinButtonNormal{$ENDIF})) do
+  begin
+    PreferredWidth:=cx;
+    PreferredHeight:=cy;
+    {$IF defined(LCLGtk2) or defined(Carbon)}
+    inc(PreferredWidth,2);
+    inc(PreferredHeight,2);
+    {$ENDIF}
+  end;
+end;
+
 { TAnchorDockManager }
 
 procedure TAnchorDockManager.SetPreferredSiteSizeAsSiteMinimum(
@@ -6213,6 +6688,9 @@
   ClientRectChanged:=(WidthDiff<>0) or (HeightDiff<>0);
   if ClientRectChanged or PreferredSiteSizeAsSiteMinimum then
     AlignChilds;
+  if ClientRectChanged then
+    if DockMaster.FOverlappingForm<>nil then
+      DockMaster.HideOverlappingForm(nil);
 end;
 
 procedure TAnchorDockManager.SaveToStream(Stream: TStream);
@@ -6505,32 +6983,58 @@
 procedure TAnchorDockSplitter.SetBoundsPercentually;
 var
   NewLeft, NewTop: Integer;
+  AControl: TControl;
+  SplitterAnchorKind:TAnchorKind;
 begin
-  if ResizeAnchor in [akLeft,akRight] then
-  begin
-    if DockParentClientSize.cx> 0 then
+  if Enabled then begin
+    if ResizeAnchor in [akLeft,akRight] then
     begin
-      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
-        NewLeft := Round(FPercentPosition*Parent.ClientWidth)
-      else
-        NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
-      NewTop := Top;
-      SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      if DockParentClientSize.cx> 0 then
+      begin
+        if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+          NewLeft := Round(FPercentPosition*Parent.ClientWidth)
+        else
+          NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
+        NewTop := Top;
+        SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      end;
+    end else
+    begin
+      if DockParentClientSize.cy> 0 then
+      begin
+        NewLeft := Left;
+        if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+          NewTop := Round(FPercentPosition*Parent.ClientHeight)
+        else
+          NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+        SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      end;
     end;
-  end else
-  begin
-    if DockParentClientSize.cy> 0 then
-    begin
-      NewLeft := Left;
-      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
-        NewTop := Round(FPercentPosition*Parent.ClientHeight)
-      else
-        NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+    if FPercentPosition < 0 then
+      UpdatePercentPosition;
+  end else begin
+    SplitterAnchorKind:=akTop;
+    AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);
+    if AControl=nil then begin SplitterAnchorKind:=akRight;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+    if AControl=nil then begin SplitterAnchorKind:=akBottom;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+    if AControl=nil then begin SplitterAnchorKind:=akLeft;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+
+    if AControl is TAnchorDockHostSite then begin
+      (AControl as TAnchorDockHostSite).UpdateHeaderAlign;
+      NewTop := (AControl as TAnchorDockHostSite).Header.Left;
+      NewTop := (AControl as TAnchorDockHostSite).Header.Height;
+      NewLeft := left;
+      NewTop := top;
+      (AControl as TAnchorDockHostSite).UpdateHeaderAlign;
+      case SplitterAnchorKind of
+        akTop: NewTop := AControl.Top+(AControl as TAnchorDockHostSite).Header.Height;
+        akBottom: NewTop := AControl.Top+AControl.Height-(AControl as TAnchorDockHostSite).Header.Height-Height;
+        akLeft: NewLeft := AControl.Left+(AControl as TAnchorDockHostSite).Header.Width;
+        akRight: NewLeft := AControl.Left+AControl.Width-(AControl as TAnchorDockHostSite).Header.Width-Width;
+      end;
       SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
     end;
   end;
-  if FPercentPosition < 0 then
-    UpdatePercentPosition;
 end;
 
 function TAnchorDockSplitter.SideAnchoredControlCount(Side: TAnchorKind): integer;
@@ -6560,14 +7064,47 @@
   end;
 end;
 
+function TAnchorDockSplitter.GetSpliterBoundsWithUnminimizedDockSites:TRect;
+var
+  NewLeft, NewTop: Integer;
+begin
+  if ResizeAnchor in [akLeft,akRight] then
+  begin
+    if DockParentClientSize.cx> 0 then
+    begin
+      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+        NewLeft := Round(FPercentPosition*Parent.ClientWidth)
+      else
+        NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
+      NewTop := Top;
+    end;
+  end else
+  begin
+    if DockParentClientSize.cy> 0 then
+    begin
+      NewLeft := Left;
+      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+        NewTop := Round(FPercentPosition*Parent.ClientHeight)
+      else
+        NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+    end;
+  end;
+  result:=Rect(NewLeft,NewTop,NewLeft+Width,NewTop+Height);
+end;
+
 procedure TAnchorDockSplitter.SaveLayout(
   LayoutNode: TAnchorDockLayoutTreeNode);
+var
+  NewLeft, NewTop: Integer;
 begin
   if ResizeAnchor in [akLeft,akRight] then
     LayoutNode.NodeType:=adltnSplitterVertical
   else
     LayoutNode.NodeType:=adltnSplitterHorizontal;
-  LayoutNode.Assign(Self);
+  LayoutNode.Assign(Self,false,false);
+  if not Enabled then begin
+    LayoutNode.BoundsRect:=GetSpliterBoundsWithUnminimizedDockSites;
+  end
 end;
 
 function TAnchorDockSplitter.HasOnlyOneSibling(Side: TAnchorKind; MinPos,
@@ -6645,7 +7182,7 @@
 begin
   inherited MouseDown(Button, Shift, X, Y);
   ATabIndex := IndexOfPageAt(X, Y);
-  if (Button = mbLeft) and DockMaster.AllowDragging and (ATabIndex >= 0) then
+  if (Button = mbLeft) and DockMaster.AllowDragging and (ATabIndex >= 0) and (DockMaster.FOverlappingForm=nil) then
   begin
     APage:=Page[ATabIndex];
     if (APage.ControlCount>0) and (APage.Controls[0] is TAnchorDockHostSite) then
@@ -6782,6 +7319,20 @@
   PopupMenu:=DockMaster.GetPopupMenu;
 end;
 
+{ TAnchorDockOverlappingForm }
+
+constructor TAnchorDockOverlappingForm.CreateNew(AOwner: TComponent; Num: Integer = 0);
+begin
+  inherited;
+  BorderStyle:=bsNone;
+  AnchorDockHostSite:=nil;
+end;
+
+procedure TAnchorDockOverlappingForm.MouseLeave;
+begin
+  inherited;
+end;
+
 { TAnchorDockPage }
 
 procedure TAnchorDockPage.UpdateDockCaption(Exclude: TControl);
@@ -6835,9 +7386,11 @@
 
 initialization
   DockMaster:=TAnchorDockMaster.Create(nil);
+  DockTimer:=TTimer.Create(nil);
 
 finalization
   FreeAndNil(DockMaster);
+  FreeAndNil(DockTimer);
 
 end.
 
Index: components/anchordocking/anchordockoptionsdlg.lfm
===================================================================
--- components/anchordocking/anchordockoptionsdlg.lfm	(revision 59428)
+++ components/anchordocking/anchordockoptionsdlg.lfm	(working copy)
@@ -1,11 +1,13 @@
 object AnchorDockOptionsFrame: TAnchorDockOptionsFrame
   Left = 0
-  Height = 482
+  Height = 567
   Top = 0
-  Width = 416
-  ClientHeight = 482
-  ClientWidth = 416
+  Width = 490
+  ClientHeight = 567
+  ClientWidth = 490
+  DesignTimePPI = 113
   OnClick = FrameClick
+  ParentFont = False
   TabOrder = 0
   DesignLeft = 513
   DesignTop = 189
@@ -12,14 +14,15 @@
   object DragThresholdLabel: TLabel
     AnchorSideLeft.Control = Owner
     AnchorSideTop.Control = Owner
-    Left = 10
-    Height = 13
-    Top = 10
-    Width = 111
-    BorderSpacing.Left = 10
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 12
+    Width = 122
+    BorderSpacing.Left = 12
+    BorderSpacing.Top = 12
     Caption = 'DragThresholdLabel'
     ParentColor = False
+    ParentFont = False
   end
   object DragThresholdTrackBar: TTrackBar
     AnchorSideLeft.Control = DragThresholdLabel
@@ -27,15 +30,16 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = Owner
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 46
-    Top = 23
-    Width = 396
+    Left = 12
+    Height = 54
+    Top = 31
+    Width = 466
     Max = 20
     OnChange = DragThresholdTrackBarChange
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Right = 10
+    BorderSpacing.Right = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 1
@@ -46,12 +50,13 @@
     AnchorSideTop.Control = DragThresholdLabel
     AnchorSideTop.Side = asrCenter
     AnchorSideRight.Control = Owner
-    Left = 127
-    Height = 23
-    Top = 5
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 141
+    Height = 27
+    Top = 8
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 20
+    ParentFont = False
     TabOrder = 0
     Visible = False
   end
@@ -59,13 +64,14 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = DragThresholdTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 79
-    Width = 103
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 97
+    Width = 112
+    BorderSpacing.Top = 12
     Caption = 'SplitterWidthLabel'
     ParentColor = False
+    ParentFont = False
   end
   object SplitterWidthTrackBar: TTrackBar
     AnchorSideLeft.Control = DragThresholdTrackBar
@@ -73,14 +79,15 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 46
-    Top = 92
-    Width = 396
+    Left = 12
+    Height = 54
+    Top = 116
+    Width = 466
     Min = 1
     OnChange = SplitterWidthTrackBarChange
     Position = 1
     Anchors = [akTop, akLeft, akRight]
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 3
@@ -89,12 +96,13 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = SplitterWidthTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 24
-    Top = 142
-    Width = 160
-    BorderSpacing.Top = 4
+    Left = 12
+    Height = 23
+    Top = 175
+    Width = 169
+    BorderSpacing.Top = 5
     Caption = 'ScaleOnResizeCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 4
@@ -103,12 +111,13 @@
     AnchorSideLeft.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 24
-    Top = 166
-    Width = 149
+    Left = 12
+    Height = 23
+    Top = 198
+    Width = 160
     Caption = 'ShowHeaderCheckBox'
     OnChange = ShowHeaderCheckBoxChange
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 5
@@ -117,12 +126,13 @@
     AnchorSideLeft.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Control = ShowHeaderCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 190
-    Width = 191
-    BorderSpacing.Left = 15
+    Left = 30
+    Height = 23
+    Top = 221
+    Width = 208
+    BorderSpacing.Left = 18
     Caption = 'ShowHeaderCaptionCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 6
@@ -131,11 +141,12 @@
     AnchorSideLeft.Control = ShowHeaderCaptionCheckBox
     AnchorSideTop.Control = ShowHeaderCaptionCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 214
-    Width = 249
+    Left = 30
+    Height = 23
+    Top = 244
+    Width = 272
     Caption = 'HideHeaderCaptionForFloatingCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 7
@@ -147,15 +158,16 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = Owner
     AnchorSideRight.Side = asrBottom
-    Left = 122
+    Left = 136
     Height = 27
-    Top = 286
-    Width = 284
+    Top = 313
+    Width = 342
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 6
-    BorderSpacing.Right = 10
-    ItemHeight = 0
+    BorderSpacing.Left = 7
+    BorderSpacing.Right = 12
+    ItemHeight = 19
     OnDrawItem = HeaderStyleComboBoxDrawItem
+    ParentFont = False
     Style = csDropDownList
     TabOrder = 10
   end
@@ -163,23 +175,25 @@
     AnchorSideLeft.Control = ShowHeaderCheckBox
     AnchorSideTop.Control = HeaderStyleComboBox
     AnchorSideTop.Side = asrCenter
-    Left = 20
-    Height = 13
-    Top = 293
-    Width = 96
-    BorderSpacing.Left = 10
+    Left = 24
+    Height = 19
+    Top = 317
+    Width = 105
+    BorderSpacing.Left = 12
     Caption = 'HeaderStyleLabel'
     ParentColor = False
+    ParentFont = False
   end
   object FlattenHeadersCheckBox: TCheckBox
     AnchorSideLeft.Control = HideHeaderCaptionForFloatingCheckBox
     AnchorSideTop.Control = HideHeaderCaptionForFloatingCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 238
-    Width = 164
+    Left = 30
+    Height = 23
+    Top = 267
+    Width = 175
     Caption = 'FlattenHeadersCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 8
@@ -188,11 +202,12 @@
     AnchorSideLeft.Control = FlattenHeadersCheckBox
     AnchorSideTop.Control = FlattenHeadersCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 262
-    Width = 154
+    Left = 30
+    Height = 23
+    Top = 290
+    Width = 164
     Caption = 'FilledHeadersCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 9
@@ -201,11 +216,12 @@
     AnchorSideLeft.Control = FilledHeadersCheckBox
     AnchorSideTop.Control = HeaderStyleComboBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 313
-    Width = 175
+    Left = 30
+    Height = 23
+    Top = 340
+    Width = 189
     Caption = 'HighlightFocusedCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 11
@@ -215,13 +231,14 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = SplitterWidthLabel
     AnchorSideTop.Side = asrCenter
-    Left = 119
-    Height = 23
-    Top = 74
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 131
+    Height = 27
+    Top = 93
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 10
     MinValue = 1
+    ParentFont = False
     TabOrder = 2
     Value = 1
     Visible = False
@@ -228,15 +245,16 @@
   end
   object HeaderAlignTopLabel: TLabel
     AnchorSideLeft.Control = DragThresholdLabel
-    AnchorSideTop.Control = HighlightFocusedCheckBox
+    AnchorSideTop.Control = DockSitesCanBeMinimized
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 347
-    Width = 117
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 398
+    Width = 130
+    BorderSpacing.Top = 12
     Caption = 'HeaderAlignTopLabel'
     ParentColor = False
+    ParentFont = False
   end
   object HeaderAlignTopTrackBar: TTrackBar
     AnchorSideLeft.Control = Owner
@@ -244,10 +262,10 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 47
-    Top = 360
-    Width = 396
+    Left = 12
+    Height = 55
+    Top = 417
+    Width = 466
     Frequency = 10
     Max = 150
     OnChange = HeaderAlignTopTrackBarChange
@@ -254,7 +272,8 @@
     PageSize = 10
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 10
+    BorderSpacing.Left = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 13
@@ -264,12 +283,13 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = HeaderAlignTopLabel
     AnchorSideTop.Side = asrCenter
-    Left = 133
-    Height = 23
-    Top = 342
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 149
+    Height = 27
+    Top = 394
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 150
+    ParentFont = False
     TabOrder = 12
     Visible = False
   end
@@ -277,13 +297,14 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = HeaderAlignTopTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 417
-    Width = 120
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 484
+    Width = 130
+    BorderSpacing.Top = 12
     Caption = 'HeaderAlignLeftLabel'
     ParentColor = False
+    ParentFont = False
   end
   object HeaderAlignLeftTrackBar: TTrackBar
     AnchorSideLeft.Control = Owner
@@ -291,10 +312,10 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 47
-    Top = 430
-    Width = 396
+    Left = 12
+    Height = 55
+    Top = 503
+    Width = 466
     Frequency = 10
     Max = 200
     OnChange = HeaderAlignLeftTrackBarChange
@@ -301,7 +322,8 @@
     PageSize = 10
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 10
+    BorderSpacing.Left = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 15
@@ -311,13 +333,28 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = HeaderAlignLeftLabel
     AnchorSideTop.Side = asrCenter
-    Left = 136
-    Height = 23
-    Top = 412
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 149
+    Height = 27
+    Top = 480
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 200
+    ParentFont = False
     TabOrder = 14
     Visible = False
   end
+  object DockSitesCanBeMinimized: TCheckBox
+    AnchorSideLeft.Control = FilledHeadersCheckBox
+    AnchorSideTop.Control = HighlightFocusedCheckBox
+    AnchorSideTop.Side = asrBottom
+    Left = 30
+    Height = 23
+    Top = 363
+    Width = 185
+    Caption = 'DockSitesCanBeMinimized'
+    ParentFont = False
+    ParentShowHint = False
+    ShowHint = True
+    TabOrder = 16
+  end
 end
Index: components/anchordocking/anchordockoptionsdlg.pas
===================================================================
--- components/anchordocking/anchordockoptionsdlg.pas	(revision 59428)
+++ components/anchordocking/anchordockoptionsdlg.pas	(working copy)
@@ -37,6 +37,7 @@
     HeaderStyleLabel: TLabel;
     HideHeaderCaptionForFloatingCheckBox: TCheckBox;
     HighlightFocusedCheckBox: TCheckBox;
+    DockSitesCanBeMinimized: TCheckBox;
     ScaleOnResizeCheckBox: TCheckBox;
     ShowHeaderCaptionCheckBox: TCheckBox;
     ShowHeaderCheckBox: TCheckBox;
@@ -299,6 +300,7 @@
   HeaderStyleLabel.Enabled:=HasHeaders;
   HeaderStyleComboBox.Enabled:=HasHeaders;
   HighlightFocusedCheckBox.Enabled:=HasHeaders;
+  DockSitesCanBeMinimized.Enabled:=HasHeaders;
 end;
 
 constructor TAnchorDockOptionsFrame.Create(TheOwner: TComponent);
@@ -356,6 +358,7 @@
   TheSettings.HeaderFilled:=FilledHeadersCheckBox.Checked;
   TheSettings.HeaderStyle:=TADHeaderStyle(HeaderStyleComboBox.ItemIndex);
   TheSettings.HeaderHighlightFocused:=HighlightFocusedCheckBox.Checked;
+  TheSettings.DockSitesCanBeMinimized:=DockSitesCanBeMinimized.Checked;
 end;
 
 procedure TAnchorDockOptionsFrame.LoadFromSettings(
@@ -429,6 +432,10 @@
   HighlightFocusedCheckBox.Checked:=TheSettings.HeaderHighlightFocused;
   HighlightFocusedCheckBox.Caption:=adrsHighlightFocused;
   HighlightFocusedCheckBox.Hint:=adrsHighlightFocusedHint;
+
+  DockSitesCanBeMinimized.Checked:=TheSettings.DockSitesCanBeMinimized;
+  DockSitesCanBeMinimized.Caption:=adrsDockSitesCanBeMinimized;
+  DockSitesCanBeMinimized.Hint:=adrsDockSitesCanBeMinimizedHint;
 end;
 
 end.
Index: components/anchordocking/anchordockpanel.pas
===================================================================
--- components/anchordocking/anchordockpanel.pas	(revision 59428)
+++ components/anchordocking/anchordockpanel.pas	(working copy)
@@ -55,7 +55,7 @@
   begin
 
     LayoutNode.NodeType:=adltnControl;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,false);
     LayoutNode.Name:={OneControl.}Name;
 
     TAnchorDockHostSite(OneControl).SaveLayout(LayoutTree,LayoutNode);
Index: components/anchordocking/anchordockstorage.pas
===================================================================
--- components/anchordocking/anchordockstorage.pas	(revision 59428)
+++ components/anchordocking/anchordockstorage.pas	(working copy)
@@ -64,6 +64,7 @@
     FTabPosition: TTabPosition;
     FWindowState: TWindowState;
     FControlLocation: TADLControlLocation;
+    FMinimized: Boolean;
     function GetAnchors(Site: TAnchorKind): string;
     function GetBottom: integer;
     function GetHeight: integer;
@@ -90,6 +91,7 @@
     procedure SetTop(const AValue: integer);
     procedure SetWidth(const AValue: integer);
     procedure SetWindowState(const AValue: TWindowState);
+    procedure SetMinimized(const AValue: boolean);
   public
     constructor Create;
     destructor Destroy; override;
@@ -96,7 +98,7 @@
     procedure Clear;
     function IsEqual(Node: TAnchorDockLayoutTreeNode): boolean;
     procedure Assign(Node: TAnchorDockLayoutTreeNode); overload;
-    procedure Assign(AControl: TControl; OverrideBoundsRect: Boolean=false); overload;
+    procedure Assign(AControl: TControl; OverrideBoundsRect: Boolean; AMinimized: Boolean); overload;
     procedure LoadFromConfig(Config: TConfigStorage); overload;
     procedure LoadFromConfig(Path: string; Config: TRttiXMLConfig); overload;
     procedure SaveToConfig(Config: TConfigStorage); overload;
@@ -106,7 +108,7 @@
     procedure CheckConsistency; virtual;
 
     // simplifying
-    procedure Simplify(ExistingNames: TStrings);
+    procedure Simplify(ExistingNames: TStrings; ParentMinimized:boolean);
     procedure DeleteNode(ChildNode: TAnchorDockLayoutTreeNode);
     function FindNodeBoundSplitter(ChildNode: TAnchorDockLayoutTreeNode;
                                    Side: TAnchorKind): TAnchorDockLayoutTreeNode;
@@ -135,6 +137,7 @@
     property Monitor: integer read FMonitor write SetMonitor;
     property HeaderPosition: TADLHeaderPosition read FHeaderPosition write SetHeaderPosition;
     property TabPosition: TTabPosition read FTabPosition write SetTabPosition;
+    property Minimized: Boolean read FMinimized write SetMinimized;
     function Count: integer;
     function IsSplitter: boolean;
     function IsRootWindow: boolean;
@@ -988,6 +991,13 @@
   IncreaseChangeStamp;
 end;
 
+procedure TAnchorDockLayoutTreeNode.SetMinimized(const AValue: boolean);
+begin
+  if FMinimized=AValue then exit;
+  FMinimized:=AValue;
+  IncreaseChangeStamp;
+end;
+
 procedure TAnchorDockLayoutTreeNode.SetTop(const AValue: integer);
 begin
   if Top=AValue then exit;
@@ -1084,6 +1094,7 @@
   BoundSplitterPos:=Node.BoundSplitterPos;
   WorkAreaRect:=Node.WorkAreaRect;
   Monitor:=Node.Monitor;
+  Minimized:=Node.Minimized;
   for a:=low(TAnchorKind) to high(TAnchorKind) do
     Anchors[a]:=Node.Anchors[a];
   while Count>Node.Count do Nodes[Count-1].Free;
@@ -1098,9 +1109,10 @@
   end;
 end;
 
-procedure TAnchorDockLayoutTreeNode.Assign(AControl: TControl; OverrideBoundsRect: Boolean=false);
+procedure TAnchorDockLayoutTreeNode.Assign(AControl: TControl; OverrideBoundsRect: Boolean; AMinimized: Boolean);
 var
   AnchorControl: TControl;
+  ParentForm:TCustomForm;
   a: TAnchorKind;
 begin
   Name:=AControl.Name;
@@ -1109,12 +1121,18 @@
   else
     BoundsRect:=AControl.BoundsRect;
   Align:=AControl.Align;
+  Minimized:=AMinimized;
   if (AControl.Parent=nil) and (AControl is TCustomForm) then begin
     WindowState:=TCustomForm(AControl).WindowState;
     Monitor:=TCustomForm(AControl).Monitor.MonitorNum;
     WorkAreaRect:=TCustomForm(AControl).Monitor.WorkareaRect;
-  end else
-    WindowState:=GetParentForm(AControl).WindowState;
+  end else begin
+    ParentForm:=GetParentForm(AControl);
+    if assigned(ParentForm) then
+      WindowState:=ParentForm.WindowState
+    else
+      WindowState:=wsNormal;
+  end;
   if AControl is TCustomTabControl then
     TabPosition:=TCustomTabControl(AControl).TabPosition
   else
@@ -1137,6 +1155,7 @@
   Clear;
   Name:=Config.GetValue('Name','');
   NodeType:=NameToADLTreeNodeType(Config.GetValue('Type',ADLTreeNodeTypeNames[adltnNone]));
+  Minimized:=Config.GetValue('Minimized',false);
   Left:=Config.GetValue('Bounds/Left',0);
   Top:=Config.GetValue('Bounds/Top',0);
   Width:=Config.GetValue('Bounds/Width',0);
@@ -1171,6 +1190,7 @@
   Clear;
   Name:=Config.GetValue(Path+'Name','');
   NodeType:=NameToADLTreeNodeType(Config.GetValue(Path+'Type',ADLTreeNodeTypeNames[adltnNone]));
+  Minimized:=Config.GetValue(Path+'Minimized',false);
   Left:=Config.GetValue(Path+'Bounds/Left',0);
   Top:=Config.GetValue(Path+'Bounds/Top',0);
   Width:=Config.GetValue(Path+'Bounds/Width',0);
@@ -1219,6 +1239,7 @@
                                           ADLHeaderPositionNames[adlhpAuto]);
   Config.SetDeleteValue('Header/TabPosition',ADLTabPostionNames[TabPosition],
                                              ADLTabPostionNames[tpTop]);
+  Config.SetDeleteValue('Minimized',Minimized,False);
   Config.SetDeleteValue('Monitor',Monitor,0);
   Config.SetDeleteValue('ChildCount',Count,0);
   for i:=1 to Count do begin
@@ -1252,6 +1273,7 @@
                                                ADLHeaderPositionNames[adlhpAuto]);
   Config.SetDeleteValue(Path+'Header/TabPosition',ADLTabPostionNames[TabPosition],
                                                   ADLTabPostionNames[tpTop]);
+  Config.SetDeleteValue(Path+'Minimized',Minimized,False);
   Config.SetDeleteValue(Path+'Monitor',Monitor,0);
   Config.SetDeleteValue(Path+'ChildCount',Count,0);
   for i:=1 to Count do
@@ -1397,7 +1419,7 @@
   end;
 end;
 
-procedure TAnchorDockLayoutTreeNode.Simplify(ExistingNames: TStrings);
+procedure TAnchorDockLayoutTreeNode.Simplify(ExistingNames: TStrings; ParentMinimized:boolean);
 { Simplification rules:
    1. Control nodes without existing name are deleted.
    2. Empty layouts and pages are deleted
@@ -1406,16 +1428,18 @@
 var
   i: Integer;
   ChildNode: TAnchorDockLayoutTreeNode;
+  NodeMinimized:boolean;
 begin
   // simplify children
   i:=Count-1;
   while i>=0 do begin
     ChildNode:=Nodes[i];
-    ChildNode.Simplify(ExistingNames);
+    NodeMinimized:=ParentMinimized or ChildNode.Minimized;
+    ChildNode.Simplify(ExistingNames,NodeMinimized);
 
     if (ChildNode.NodeType=adltnControl) then begin
       // leaf node => check if there is a control
-      if (ChildNode.Name='') or (ExistingNames.IndexOf(ChildNode.Name)<0) then
+      if (ChildNode.Name='') or ((ExistingNames.IndexOf(ChildNode.Name)<0) and (not NodeMinimized)) then
         DeleteNode(ChildNode);
     end else if ChildNode.IsSplitter then begin
       // splitter
@@ -1424,7 +1448,7 @@
         ChildNode[0].Free;
     end else if ChildNode.NodeType=adltnCustomSite then begin
       // custom dock site
-    end else if ChildNode.Count=0 then begin
+    end else if (ChildNode.Count=0)and(not NodeMinimized) then begin
       // inner node without child => delete
       DeleteNode(ChildNode);
     end else if (ChildNode.Count=1)
Index: components/anchordocking/anchordockstr.pas
===================================================================
--- components/anchordocking/anchordockstr.pas	(revision 59428)
+++ components/anchordocking/anchordockstr.pas	(working copy)
@@ -8,6 +8,7 @@
 
 resourcestring
   adrsClose = 'Close';
+  adrsMinimize = 'Minimize';
   adrsQuit = 'Quit %s';
   adrsTabPosition = 'Tab position';
   adrsMovePageRight = 'Move page right';
@@ -82,6 +83,8 @@
   adrsFilledHeadersHint = 'Fill headers of docked controls';
   adrsHighlightFocused = 'Highlight focused';
   adrsHighlightFocusedHint = 'Highlight header of focused docked control';
+  adrsDockSitesCanBeMinimized = 'Dock sites can be minimized';
+  adrsDockSitesCanBeMinimizedHint = 'Dock sites can be minimized';
 
 implementation
 
Index: components/anchordocking/design/anchordesktopoptions.pas
===================================================================
--- components/anchordocking/design/anchordesktopoptions.pas	(revision 59428)
+++ components/anchordocking/design/anchordesktopoptions.pas	(working copy)
@@ -272,7 +272,7 @@
         // custom dock site
         LayoutNode:=FTree.NewNode(FTree.Root);
         LayoutNode.NodeType:=adltnCustomSite;
-        LayoutNode.Assign(AForm);
+        LayoutNode.Assign(AForm,false,false);
         // can have one normal dock site
         Site:=TAnchorDockManager(AForm.DockManager).GetChildSite;
         if Site<>nil then begin
@@ -287,7 +287,7 @@
         raise EAnchorDockLayoutError.Create('invalid root control for save: '+DbgSName(AControl));
     end;
     // remove invisible controls
-    FTree.Root.Simplify(VisibleControls);
+    FTree.Root.Simplify(VisibleControls,false);
   finally
     VisibleControls.Free;
     SavedSites.Free;

Andrey Zubarev

2018-11-07 14:22

reporter   ~0111831

anchordocking_minimize_docksite7.patch
That's about what I wanted to do))

Problems:
-ugly minimize button;
-perhaps need add to settings MouseNoMoveDelta=5 MouseNoMoveTime=500 HideOverlappingFormByMouseLoseTime=500 consts;
-perhaps need add animation to show\hide overlaping window;
-perhaps need add small border to overlaping window;

Not tested in linux!
Please review and test!

Andrey Zubarev

2018-11-08 21:37

reporter   ~0111872

Demo https://imgur.com/a/q5owCHp

Andrey Zubarev

2018-11-11 00:19

reporter  

anchordocking_minimize_docksite8.patch (67,938 bytes)   
Index: components/anchordocking/anchordocking.pas
===================================================================
--- components/anchordocking/anchordocking.pas	(revision 59428)
+++ components/anchordocking/anchordocking.pas	(working copy)
@@ -109,6 +109,11 @@
 const ADAutoSizingReason = 'TAnchorDockMaster Delayed';
 {$ENDIF}
 
+const EmptyMouseTimeStartX=low(Integer);
+      MouseNoMoveDelta=5;
+      MouseNoMoveTime=500;
+      HideOverlappingFormByMouseLoseTime=500;
+
 type
   TAnchorDockHostSite = class;
 
@@ -123,6 +128,14 @@
            PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
   end;
 
+  TAnchorDockMinimizeButton = class(TCustomSpeedButton)
+  protected
+    function GetDrawDetails: TThemedElementDetails; override;
+    procedure CalculatePreferredSize(var PreferredWidth,
+           PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
+  end;
+
+
   { TAnchorDockHeader
     The panel of a TAnchorDockHostSite containing the close button and the
     caption when the form is docked. The header can be shown at any of the four
@@ -133,9 +146,12 @@
   TAnchorDockHeader = class(TCustomPanel)
   private
     FCloseButton: TCustomSpeedButton;
+    FMinimizeButton: TCustomSpeedButton;
     FHeaderPosition: TADLHeaderPosition;
     fFocused:Boolean;
+    FMouseTimeStartX,FMouseTimeStartY:Integer;
     procedure CloseButtonClick(Sender: TObject);
+    procedure MinimizeButtonClick(Sender: TObject);
     procedure HeaderPositionItemClick(Sender: TObject);
     procedure UndockButtonClick(Sender: TObject);
     procedure MergeButtonClick(Sender: TObject);
@@ -147,6 +163,11 @@
           PreferredHeight: integer; WithThemeSpace: Boolean); override;
     procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X,
              Y: Integer); override;
+    procedure MouseMove(Shift: TShiftState; X,Y: Integer); override;
+    procedure MouseLeave;  override;
+    procedure StartMouseNoMoveTimer(X, Y: Integer);
+    procedure StopMouseNoMoveTimer;
+    procedure DoMouseNoMoveTimer(Sender: TObject);
     procedure UpdateHeaderControls;
     procedure SetAlign(Value: TAlign); override;
     procedure DoOnShowHint(HintInfo: PHintInfo); override;
@@ -154,6 +175,7 @@
   public
     constructor Create(TheOwner: TComponent); override;
     property CloseButton: TCustomSpeedButton read FCloseButton;
+    property MinimizeButton: TCustomSpeedButton read FMinimizeButton;
     property HeaderPosition: TADLHeaderPosition read FHeaderPosition write SetHeaderPosition;
     property BevelOuter default bvNone;
   end;
@@ -190,6 +212,7 @@
     procedure SetBoundsKeepDockBounds(ALeft, ATop, AWidth, AHeight: integer); // movement for scaling keeps the DockBounds
     function SideAnchoredControlCount(Side: TAnchorKind): integer;
     function HasAnchoredControls: boolean;
+    function GetSpliterBoundsWithUnminimizedDockSites:TRect;
     procedure SaveLayout(LayoutNode: TAnchorDockLayoutTreeNode);
     function HasOnlyOneSibling(Side: TAnchorKind; MinPos, MaxPos: integer): TControl;
     property DockRestoreBounds: TRect read FDockRestoreBounds write FDockRestoreBounds;
@@ -241,6 +264,15 @@
   end;
   TAnchorDockPageControlClass = class of TAnchorDockPageControl;
 
+
+  TAnchorDockOverlappingForm = class(TCustomForm)
+  protected
+    procedure MouseLeave;  override;
+  public
+    AnchorDockHostSite:TAnchorDockHostSite;
+    constructor CreateNew(AOwner: TComponent; Num: Integer = 0); override;
+  end;
+
   { TAnchorDockHostSite
     This form is the dockhostsite for all controls.
     When docked together they build a tree structure with the docked controls
@@ -262,7 +294,10 @@
     FPages: TAnchorDockPageControl;
     FSiteType: TAnchorDockHostSiteType;
     FBoundSplitter: TAnchorDockSplitter;
-    fUpdateLayout: integer;
+    fUpdateLayout: Integer;
+    FMinimized: Boolean;
+    fMinimization: Boolean;
+    FMinimizedControl: TControl;
     procedure SetHeaderSide(const AValue: TAnchorKind);
   protected
     procedure DoEnter; override;
@@ -319,6 +354,10 @@
     destructor Destroy; override;
     function CloseQuery: boolean; override;
     function CloseSite: boolean; virtual;
+    procedure MinimizeSite; virtual;
+    procedure AsyncMinimizeSite(Data: PtrInt);
+    procedure ShowMinimizedControl;
+    procedure HideMinimizedControl;
     procedure RemoveControl(AControl: TControl); override;
     procedure InsertControl(AControl: TControl; Index: integer); override;
     procedure GetSiteInfo(Client: TControl; var InfluenceRect: TRect;
@@ -431,6 +470,7 @@
     FShowHeader: boolean;
     FShowHeaderCaption: boolean;
     FSplitterWidth: integer;
+    FDockSitecCanBeMinimized: boolean;
     procedure SetAllowDragging(AValue: boolean);
     procedure SetDockOutsideMargin(AValue: integer);
     procedure SetDockParentMargin(AValue: integer);
@@ -448,6 +488,7 @@
     procedure SetHeaderFlatten(AValue: boolean);
     procedure SetHeaderFilled(AValue: boolean);
     procedure SetHeaderHighlightFocused(AValue: boolean);
+    procedure SetDockSitecCanBeMinimized(AValue: boolean);
   public
     property DragTreshold: integer read FDragTreshold write SetDragTreshold;
     property DockOutsideMargin: integer read FDockOutsideMargin write SetDockOutsideMargin;
@@ -466,6 +507,7 @@
     property HeaderFlatten: boolean read FHeaderFlatten write SetHeaderFlatten;
     property HeaderFilled: boolean read FHeaderFilled write SetHeaderFilled;
     property HeaderHighlightFocused: boolean read FHeaderHighlightFocused write SetHeaderHighlightFocused;
+    property DockSitesCanBeMinimized: boolean read FDockSitecCanBeMinimized write SetDockSitecCanBeMinimized;
     procedure IncreaseChangeStamp; inline;
     property ChangeStamp: integer read FChangeStamp;
     procedure LoadFromConfig(Config: TConfigStorage); overload;
@@ -502,6 +544,7 @@
     FHeaderFlatten: boolean;
     FHeaderFilled: boolean;
     FHeaderHighlightFocused: boolean;
+    FDockSitesCanBeMinimized: boolean;
     FIdleConnected: Boolean;
     FManagerClass: TAnchorDockManagerClass;
     FOnCreateControl: TADCreateControlEvent;
@@ -531,6 +574,7 @@
     fPopupMenu: TPopupMenu;
     // Used by RestoreLayout:
     WorkArea, SrcWorkArea: TRect;
+    FOverlappingForm:TAnchorDockOverlappingForm;
 
     function GetControls(Index: integer): TControl;
     function GetLocalizedHeaderHint: string;
@@ -541,6 +585,8 @@
     function GetNodeSite(Node: TAnchorDockLayoutTreeNode): TAnchorDockHostSite;
     procedure MapTreeToControls(Tree: TAnchorDockLayoutTree);
     function RestoreLayout(Tree: TAnchorDockLayoutTree; Scale: boolean): boolean;
+    procedure SetMinimizedState(Tree: TAnchorDockLayoutTree);
+    procedure SetnodeMinimizedState(ANode: TAnchorDockLayoutTreeNode);
     procedure EnableAllAutoSizing;
     procedure ClearLayoutProperties(AControl: TControl; NewAlign: TAlign = alClient);
     procedure PopupMenuPopup(Sender: TObject);
@@ -561,6 +607,7 @@
     procedure SetHeaderFlatten(AValue: boolean);
     procedure SetHeaderFilled(AValue: boolean);
     procedure SetHeaderHighlightFocused(AValue: boolean);
+    procedure SetDockSitesCanBeMinimized(AValue: boolean);
 
     procedure SetShowMenuItemShowHeader(AValue: boolean);
     procedure SetupSite(Site: TWinControl; ANode: TAnchorDockLayoutTreeNode;
@@ -584,8 +631,12 @@
     procedure SetHideHeaderCaptionFloatingControl(const AValue: boolean);
     procedure SetSplitterWidth(const AValue: integer);
     procedure OnIdle(Sender: TObject; var Done: Boolean);
+    procedure StartHideOverlappingTimer;
+    procedure StopHideOverlappingTimer;
     procedure AsyncSimplify({%H-}Data: PtrInt);
   public
+    procedure ShowOverlappingForm;
+    procedure HideOverlappingForm(Sender: TObject);
     constructor Create(AOwner: TComponent); override;
     destructor Destroy; override;
     function FullRestoreLayout(Tree: TAnchorDockLayoutTree; Scale: Boolean): Boolean;
@@ -680,6 +731,7 @@
     property HeaderFlatten: boolean read FHeaderFlatten write SetHeaderFlatten default true;
     property HeaderFilled: boolean read FHeaderFilled write SetHeaderFilled default true;
     property HeaderHighlightFocused: boolean read FHeaderHighlightFocused write SetHeaderHighlightFocused default false;
+    property DockSitesCanBeMinimized: boolean read FDockSitesCanBeMinimized write SetDockSitesCanBeMinimized default false;
 
     property SplitterWidth: integer read FSplitterWidth write SetSplitterWidth default 4;
     property ScaleOnResize: boolean read FScaleOnResize write SetScaleOnResize default true; // scale children when resizing a site
@@ -698,6 +750,7 @@
 
 var
   DockMaster: TAnchorDockMaster = nil;
+  DockTimer: TTimer = nil;
 
 const
   ADHeaderStyleNames: array[TADHeaderStyle] of string = (
@@ -970,6 +1023,27 @@
   end;
 end;
 
+function CountAndReturnOnlyOneMinimizedAnchoredControls(Control: TControl; Side: TAnchorKind): TAnchorDockHostSite;
+var
+  i,Counter: Integer;
+  Neighbour: TControl;
+begin
+  Counter:=0;
+  for i:=0 to Control.AnchoredControlCount-1 do begin
+    Neighbour:=Control.AnchoredControls[i];
+    if Neighbour.Visible then
+    if Neighbour is TAnchorDockHostSite then
+    if (OppositeAnchor[Side] in Neighbour.Anchors)
+    and (Neighbour.AnchorSide[OppositeAnchor[Side]].Control=Control) then begin
+      inc(Counter);
+      result:=TAnchorDockHostSite(Neighbour);
+    end;
+  end;
+  if (Counter=1)and(result is TAnchorDockHostSite)and((result as TAnchorDockHostSite).FMinimized) then
+  else
+    result:=Nil;
+end;
+
 function NeighbourCanBeShrinked(EnlargeControl, Neighbour: TControl;
   Side: TAnchorKind): boolean;
 { returns true if Neighbour can be shrinked on the opposite side of Side
@@ -1361,6 +1435,13 @@
   IncreaseChangeStamp;
 end;
 
+procedure TAnchorDockSettings.SetDockSitecCanBeMinimized(AValue: boolean);
+begin
+  if FDockSitecCanBeMinimized=AValue then Exit;
+  FDockSitecCanBeMinimized:=AValue;
+  IncreaseChangeStamp;
+end;
+
 procedure TAnchorDockSettings.Assign(Source: TAnchorDockSettings);
 begin
   FAllowDragging := Source.FAllowDragging;
@@ -1381,6 +1462,7 @@
   FShowHeaderCaption := Source.FShowHeaderCaption;
   FSplitterWidth := Source.FSplitterWidth;
   FHeaderHighlightFocused:=Source.FHeaderHighlightFocused;
+  FDockSitecCanBeMinimized:=Source.FDockSitecCanBeMinimized;
 end;
 
 procedure TAnchorDockSettings.IncreaseChangeStamp;
@@ -1407,6 +1489,7 @@
   HeaderFlatten:=Config.GetValue('HeaderFlatten',true);
   HeaderFilled:=Config.GetValue('HeaderFilled',true);
   HeaderHighlightFocused:=Config.GetValue('HeaderHighlightFocused',False);
+  DockSitesCanBeMinimized:=Config.GetValue('DockSitecCanBeMinimized',False);
   Config.UndoAppendBasePath;
 end;
 
@@ -1429,6 +1512,7 @@
   Config.SetDeleteValue(Path+'HeaderFlatten',HeaderFlatten,true);
   Config.SetDeleteValue(Path+'HeaderFilled',HeaderFilled,true);
   Config.SetDeleteValue(Path+'HeaderHighlightFocused',HeaderHighlightFocused,False);
+  Config.SetDeleteValue(Path+'DockSitecCanBeMinimized',DockSitesCanBeMinimized,False);
 end;
 
 procedure TAnchorDockSettings.SaveToConfig(Config: TConfigStorage);
@@ -1450,6 +1534,7 @@
   Config.SetDeleteValue('HeaderFlatten',HeaderFlatten,true);
   Config.SetDeleteValue('HeaderFilled',HeaderFilled,true);
   Config.SetDeleteValue('HeaderHighlightFocused',HeaderHighlightFocused,False);
+  Config.SetDeleteValue('DockSitecCanBeMinimized',DockSitesCanBeMinimized,False);
   Config.UndoAppendBasePath;
 end;
 
@@ -1472,6 +1557,7 @@
       and (HeaderFlatten=Settings.HeaderFlatten)
       and (HeaderFilled=Settings.HeaderFilled)
       and (HeaderHighlightFocused=Settings.HeaderHighlightFocused)
+      and (DockSitesCanBeMinimized=Settings.DockSitesCanBeMinimized)
       ;
 end;
 
@@ -1494,6 +1580,7 @@
   HeaderFlatten:=Config.GetValue(Path+'HeaderFlatten',true);
   HeaderFilled:=Config.GetValue(Path+'HeaderFilled',true);
   HeaderHighlightFocused:=Config.GetValue(Path+'HeaderHighlightFocused',False);
+  DockSitesCanBeMinimized:=Config.GetValue(Path+'DockSitecCanBeMinimized',False);
 end;
 
 { TAnchorDockMaster }
@@ -2021,6 +2108,8 @@
     aHostSite:=TAnchorDockHostSite(Site);
     aHostSite.Header.HeaderPosition:=ANode.HeaderPosition;
     aHostSite.DockRestoreBounds:=NewBounds;
+    //aHostSite.FMinimized:=ANode.Minimized;
+    //we update aHostSite.FMinimized in TAnchorDockMaster.SetMinimizedState
     if (ANode.NodeType<>adltnPages) and (aHostSite.Pages<>nil) then
       aHostSite.FreePages;
   end;
@@ -2040,6 +2129,25 @@
   fTreeNameToDocker[Node.Name]:=Result;
 end;
 
+procedure TAnchorDockMaster.SetNodeMinimizedState(ANode: TAnchorDockLayoutTreeNode);
+var
+  HostSite:TAnchorDockHostSite;
+  i:integer;
+begin
+  HostSite:=GetNodeSite(ANode);
+  if Assigned(HostSite) then
+    if HostSite.FMinimized<>ANode.Minimized then
+      Application.QueueAsyncCall(@HostSite.AsyncMinimizeSite,0);
+      //HostSite.MinimizeSite;
+  for i:=0 to ANode.Count-1 do
+    SetnodeMinimizedState(ANode.Nodes[i]);
+end;
+
+procedure TAnchorDockMaster.SetMinimizedState(Tree: TAnchorDockLayoutTree);
+begin
+  SetnodeMinimizedState(Tree.Root);
+end;
+
 function TAnchorDockMaster.RestoreLayout(Tree: TAnchorDockLayoutTree;
   Scale: boolean): boolean;
 
@@ -2193,7 +2301,7 @@
       try
         SetupSite(Site,ANode,AParent);
         Site.FSiteType:=adhstPages;
-        Site.Header.Parent:=nil;
+        //Site.Header.Parent:=nil;
         if Site.Pages=nil then
           Site.CreatePages;
         for i:=0 to ANode.Count-1 do begin
@@ -2358,7 +2466,7 @@
       debugln(ControlNames.Text);
       {$ENDIF}
       // if some forms/controls could not be created the layout needs to be adapted
-      Tree.Root.Simplify(ControlNames);
+      Tree.Root.Simplify(ControlNames,false);
 
       // reuse existing sites to reduce flickering
       MapTreeToControls(Tree);
@@ -2368,6 +2476,7 @@
 
       // create sites, move controls
       RestoreLayout(Tree,Scale);
+      SetMinimizedState(Tree);
     finally
       EndUpdate;
     end;
@@ -2422,11 +2531,54 @@
   OptionsChanged;
 end;
 
+procedure TAnchorDockMaster.StartHideOverlappingTimer;
+begin
+  if not DockTimer.Enabled then begin
+    DockTimer.Interval:=HideOverlappingFormByMouseLoseTime;
+    DockTimer.OnTimer:=@HideOverlappingForm;
+    DockTimer.Enabled:=true;
+  end;
+end;
+
+procedure TAnchorDockMaster.StopHideOverlappingTimer;
+begin
+  DockTimer.Enabled:=False;
+  DockTimer.Interval:=0;
+  DockTimer.OnTimer:=nil;
+end;
+
+function IsParentControl(aParent, aControl: TControl): boolean;
+begin
+  while (aControl <> nil) and (aControl.Parent <> nil) do
+  begin
+    if (aControl=aParent) then
+      exit(true);
+    aControl := aControl.Parent;
+  end;
+  result:=aControl=aParent;
+end;
+
+
 procedure TAnchorDockMaster.OnIdle(Sender: TObject; var Done: Boolean);
+var
+  MousePos: TPoint;
+  Bounds:Trect;
 begin
   if Done then ;
-  IdleConnected:=false;
   Restoring:=false;
+  if FOverlappingForm=nil then
+    IdleConnected:=false
+  else begin
+    GetCursorPos(MousePos);
+    Bounds.TopLeft:=FOverlappingForm.ClientToScreen(point(0,0));
+    Bounds.BottomRight:=FOverlappingForm.ClientToScreen(point(FOverlappingForm.Width,FOverlappingForm.Height));
+    if not IsParentControl(FOverlappingForm, GetCaptureControl) then begin
+      if not PtInRect(Bounds,MousePos) then
+          StartHideOverlappingTimer
+        else
+          StopHideOverlappingTimer;
+    end;
+  end;
 end;
 
 procedure TAnchorDockMaster.AsyncSimplify(Data: PtrInt);
@@ -2514,6 +2666,24 @@
   InvalidateHeaders;
 end;
 
+procedure TAnchorDockMaster.SetDockSitesCanBeMinimized(AValue: boolean);
+var
+  i:integer;
+  Site: TAnchorDockHostSite;
+begin
+  if FDockSitesCanBeMinimized=AValue then Exit;
+  FDockSitesCanBeMinimized:=AValue;
+  for i:=0 to ComponentCount-1 do begin
+    Site:=TAnchorDockHostSite(Components[i]);
+    if not (Site is TAnchorDockHostSite) then continue;
+    if (Site.Header<>nil) then begin
+      DisableControlAutoSizing(Site);
+      Site.UpdateHeaderShowing;
+    end;
+  end;
+  EnableAllAutoSizing;
+  OptionsChanged;
+end;
 procedure TAnchorDockMaster.SetScaleOnResize(AValue: boolean);
 begin
   if FScaleOnResize=AValue then Exit;
@@ -2668,6 +2838,20 @@
     EnableAllAutoSizing;
 end;
 
+procedure TAnchorDockMaster.ShowOverlappingForm;
+begin
+  FOverlappingForm.Show;
+  IdleConnected:=true;
+end;
+
+procedure TAnchorDockMaster.HideOverlappingForm(Sender: TObject);
+begin
+  StopHideOverlappingTimer;
+  FOverlappingForm.Hide;
+  FOverlappingForm.AnchorDockHostSite.HideMinimizedControl;
+  IdleConnected:=false;
+end;
+
 constructor TAnchorDockMaster.Create(AOwner: TComponent);
 begin
   inherited Create(AOwner);
@@ -2698,14 +2882,14 @@
   FPageClass:=TAnchorDockPage;
   FRestoreLayouts:=TAnchorDockRestoreLayouts.Create;
   FHeaderHighlightFocused:=false;
+  FDockSitesCanBeMinimized:=false;
+  FOverlappingForm:=nil;
 end;
 
 destructor TAnchorDockMaster.Destroy;
 var
   AControl: TControl;
-  {$IFDEF VerboseAnchorDocking}
-  i: Integer;
-  {$ENDIF}
+  i, j: Integer;
 begin
   QueueSimplify:=false;
   FreeAndNil(FRestoreLayouts);
@@ -2727,6 +2911,12 @@
     debugln(['TAnchorDockMaster.Destroy ',i,'/',ComponentCount,' ',DbgSName(Components[i])]);
   end;
   {$ENDIF}
+  for i:=0 to ComponentCount-1 do begin
+    for j:=0 to ComponentCount-1 do begin
+      if i<>j then
+        TControl(Components[i]).RemoveAllHandlersOfObject(TControl(Components[j]));
+  end;
+  end;
   inherited Destroy;
 end;
 
@@ -3018,7 +3208,8 @@
   i:=Screen.CustomFormCount-1;
   while i>=0 do begin
     AForm:=GetParentForm(Screen.CustomForms[i]);
-    AForm.Hide;
+    if Assigned(AForm)then
+      AForm.Hide;
     i:=Min(i,Screen.CustomFormCount)-1;
   end;
 
@@ -3062,8 +3253,11 @@
   end;
 end;
 
-function GetParentFormOrDockPanel(Control: TControl): TCustomForm;
+function GetParentFormOrDockPanel(Control: TControl; TopForm:Boolean=true): TCustomForm;
+var
+  oldControl: TControl;
 begin
+  oldControl:=Control;
   while (Control <> nil) and (Control.Parent <> nil) do
   begin
     if (Control is TAnchorDockPanel) then
@@ -3076,6 +3270,18 @@
     Result := TCustomForm(Control)
   else
     Result := nil;
+  if not TopForm then begin
+    if Control is TAnchorDockPanel then
+      exit;
+    Control:=oldControl;
+    while (Control <> nil) and (Control.Parent <> nil) do
+    begin
+      Control := Control.Parent;
+      if (Control is TCustomForm) then
+        Break;
+    end;
+    Result := TCustomForm(Control);
+  end;
 end;
 
 procedure TAnchorDockMaster.SaveMainLayoutToTree(LayoutTree: TAnchorDockLayoutTree);
@@ -3088,12 +3294,12 @@
   AFormOrDockPanel: TWinControl;
   VisibleControls: TStringList;
 
-  procedure SaveFormOrDockPanel(theFormOrDockPanel: TWinControl; SaveChildren: boolean);
+  procedure SaveFormOrDockPanel(theFormOrDockPanel: TWinControl; SaveChildren: boolean; AMinimized:boolean);
   begin
     // custom dock site
     LayoutNode:=LayoutTree.NewNode(LayoutTree.Root);
     LayoutNode.NodeType:=adltnCustomSite;
-    LayoutNode.Assign(theFormOrDockPanel,theFormOrDockPanel is TAnchorDockPanel);
+    LayoutNode.Assign(theFormOrDockPanel,theFormOrDockPanel is TAnchorDockPanel,AMinimized);
     // can have one normal dock site
     if SaveChildren then
     begin
@@ -3124,7 +3330,7 @@
       debugln(['TAnchorDockMaster.SaveMainLayoutToTree AForm=',DbgSName(AFormOrDockPanel)]);
       DebugWriteChildAnchors(AFormOrDockPanel,true,true);
       if AFormOrDockPanel is TAnchorDockPanel then begin
-        SaveFormOrDockPanel(GetParentFormOrDockPanel(AFormOrDockPanel),{false}true);
+        SaveFormOrDockPanel(GetParentFormOrDockPanel(AFormOrDockPanel),true,false);
         //LayoutNode:=LayoutTree.NewNode(LayoutTree.Root);
         //TAnchorDockPanel(AFormOrDockPanel).SaveLayout(LayoutTree,LayoutNode);
       end else if AFormOrDockPanel is TAnchorDockHostSite then begin
@@ -3132,12 +3338,12 @@
         LayoutNode:=LayoutTree.NewNode(LayoutTree.Root);
         Site.SaveLayout(LayoutTree,LayoutNode);
       end else if IsCustomSite(AFormOrDockPanel) then begin
-        SaveFormOrDockPanel(AFormOrDockPanel,true);
+        SaveFormOrDockPanel(AFormOrDockPanel,true,false);
       end else
         raise EAnchorDockLayoutError.Create('invalid root control for save: '+DbgSName(AControl));
     end;
     // remove invisible controls
-    LayoutTree.Root.Simplify(VisibleControls);
+    LayoutTree.Root.Simplify(VisibleControls,false);
   finally
     VisibleControls.Free;
     SavedSites.Free;
@@ -3157,7 +3363,7 @@
     (AControl as TAnchorDockPanel).SaveLayout(LayoutTree,LayoutTree.Root);
   end else if IsCustomSite(AControl) then begin
     LayoutTree.Root.NodeType:=adltnCustomSite;
-    LayoutTree.Root.Assign(AControl);
+    LayoutTree.Root.Assign(AControl,false,false);
     // can have one normal dock site
     Site:=TAnchorDockManager(AControl.DockManager).GetChildSite;
     if Site<>nil then begin
@@ -3252,7 +3458,7 @@
       debugln(ControlNames.Text);
       {$ENDIF}
       // if some forms/controls could not be created the layout needs to be adapted
-      Tree.Root.Simplify(ControlNames);
+      Tree.Root.Simplify(ControlNames,false);
 
       // reuse existing sites to reduce flickering
       MapTreeToControls(Tree);
@@ -3262,6 +3468,7 @@
 
       // create sites, move controls
       RestoreLayout(Tree,Scale);
+      SetMinimizedState(Tree);
     finally
       EndUpdate;
     end;
@@ -3323,6 +3530,7 @@
   HeaderFlatten                    := Settings.HeaderFlatten;
   HeaderFilled                     := Settings.HeaderFilled;
   HeaderHighlightFocused           := Settings.HeaderHighlightFocused;
+  DockSitesCanBeMinimized          := Settings.DockSitesCanBeMinimized;
 end;
 
 procedure TAnchorDockMaster.SaveSettings(Settings: TAnchorDockSettings);
@@ -3343,6 +3551,7 @@
   Settings.HeaderFlatten:=HeaderFlatten;
   Settings.HeaderFilled:=HeaderFilled;
   Settings.HeaderHighlightFocused:=HeaderHighlightFocused;
+  Settings.DockSitesCanBeMinimized:=DockSitesCanBeMinimized;
 end;
 
 function TAnchorDockMaster.SettingsAreEqual(Settings: TAnchorDockSettings
@@ -3680,6 +3889,7 @@
     AControl:=TControl(Sender);
     if not (csDestroying in ComponentState) then begin
       if (not AControl.Visible)
+      and (not FMinimized)
       and (not ((AControl is TAnchorDockHeader)
                or (AControl is TAnchorDockSplitter)
                or (AControl is TAnchorDockHostSite)))
@@ -4119,6 +4329,8 @@
 end;
 
 procedure TAnchorDockHostSite.FreePages;
+var
+  i:Integer;
 begin
   FreeAndNil(FPages);
 end;
@@ -4233,6 +4445,14 @@
         akRight: NewBounds.Right:=AControl.Left+AControl.Width;
         akBottom: NewBounds.Bottom:=AControl.Top+AControl.Height;
         end;
+        if (sibling is TAnchorDockHostSite) then
+        if (sibling as TAnchorDockHostSite).FMinimized then begin
+          (sibling as TAnchorDockHostSite).FMinimized:=false;
+          (sibling as TAnchorDockHostSite).FMinimizedControl.Parent:=(sibling as TAnchorDockHostSite);
+          (sibling as TAnchorDockHostSite).FMinimizedControl.Visible:=True;
+          (sibling as TAnchorDockHostSite).FMinimizedControl:=nil;
+          (sibling as TAnchorDockHostSite).UpdateHeaderAlign;
+        end;
         Sibling.BoundsRect:=NewBounds;
       end;
     end;
@@ -4306,6 +4526,13 @@
       FSiteType:=adhstOneControl;
       OnlySiteLeft.Align:=alClient;
       Header.Parent:=Self;
+      if OnlySiteLeft.FMinimized then begin
+        OnlySiteLeft.FMinimized:=false;
+        OnlySiteLeft.FMinimizedControl.Parent:=OnlySiteLeft;
+        OnlySiteLeft.FMinimizedControl.Visible:=True;
+        OnlySiteLeft.FMinimizedControl:=nil;
+        UpdateHeaderAlign;
+      end;
       UpdateHeaderAlign;
 
       //debugln(['TAnchorDockHostSite.RemoveControlFromLayout.ConvertToOneControlType AFTER CONVERT "',Caption,'" to onecontrol OnlySiteLeft="',OnlySiteLeft.Caption,'"']);
@@ -4465,7 +4692,7 @@
     debugln(['TAnchorDockHostSite.Simplify ',DbgSName(Self),' ',DbgSName(AControl)]);
     if AControl is TAnchorDockHostSite then
       SimplifyOneControl
-    else if (AControl=nil) or (csDestroying in AControl.ComponentState) then
+    else if ((AControl=nil) or (csDestroying in AControl.ComponentState)) then
       DockMaster.NeedFree(Self);
   end;
 end;
@@ -4577,7 +4804,8 @@
     Result:=Controls[i];
     if Result.Owner<>Self then exit;
   end;
-  Result:=nil;
+  result:=FMinimizedControl;
+  //Result:=nil;
 end;
 
 function TAnchorDockHostSite.GetSiteCount: integer;
@@ -5165,6 +5393,105 @@
   Result:=Check(Self);
 end;
 
+function CheckOposite(Side:TAnchorKind;var AControl: TControl;out Splitter: TAnchorDockSplitter; out SplitterAnchorKind:TAnchorKind):boolean;
+begin
+  result:=GetDockSplitter(AControl,Side,Splitter);
+  if result then begin
+    if CountAnchoredControls(Splitter,OppositeAnchor[Side])=1 then begin
+      SplitterAnchorKind:=Side;
+      exit;
+    end;
+  end;
+  result:=false
+end;
+
+function FindNearestSpliter(AControl: TControl;out Splitter: TAnchorDockSplitter;out SplitterAnchorKind:TAnchorKind):boolean;
+begin
+  result:=CheckOposite(akTop,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akRight,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akBottom,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akLeft,AControl,Splitter,SplitterAnchorKind);
+end;
+
+procedure TAnchorDockHostSite.MinimizeSite;
+begin
+  //Application.QueueAsyncCall(@AsyncMinimizeSite,0);
+  AsyncMinimizeSite(0);
+end;
+
+procedure TAnchorDockHostSite.AsyncMinimizeSite(Data: PtrInt);
+var
+  AControl: TControl;
+  OpositeDockHostSite:TAnchorDockHostSite;
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
+  //SpliterPercentPosition:Single;
+begin
+  fMinimization:=true;
+  debugln(['TAnchorDockHostSite.MinimizeSite ',DbgSName(Self),' SiteType=',dbgs(SiteType)]);
+  if FMinimized then
+    AControl:=FMinimizedControl
+  else
+    AControl:=GetOneControl;
+  if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+    OpositeDockHostSite:=CountAndReturnOnlyOneMinimizedAnchoredControls(Splitter,SplitterAnchorKind);
+    if (Splitter.Enabled and (OpositeDockHostSite=nil)) or FMinimized then begin
+      FMinimized:=not FMinimized;
+      if FMinimized then begin
+        FMinimizedControl:=AControl;
+        AControl.Visible:=False;
+        AControl.Parent:=nil;
+      end else begin
+        AControl.Parent:=self;
+        AControl.Visible:=True;
+        FMinimizedControl:=nil;
+      end;
+      Splitter.Enabled:=AControl.Visible;
+      UpdateHeaderAlign;
+      Splitter.SetBoundsPercentually;
+    end;
+  end;
+  fMinimization:=false;
+end;
+
+procedure TAnchorDockHostSite.ShowMinimizedControl;
+var
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
+  SpliterRect,OverlappingFormRect:TRect;
+begin
+  if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+    SpliterRect:=Splitter.GetSpliterBoundsWithUnminimizedDockSites;
+    OverlappingFormRect:=BoundsRect;
+    case SplitterAnchorKind of
+         akTop:OverlappingFormRect.Top:=SpliterRect.Bottom;
+        akLeft:OverlappingFormRect.Left:=SpliterRect.Right;
+       akRight:OverlappingFormRect.Right:=SpliterRect.Left;
+      akBottom:OverlappingFormRect.Bottom:=SpliterRect.Top;
+    end;
+    DockMaster.FOverlappingForm:=TAnchorDockOverlappingForm.CreateNew(self);
+    DockMaster.FOverlappingForm.BoundsRect:=OverlappingFormRect;
+    DockMaster.FOverlappingForm.Parent:=GetParentFormOrDockPanel(self,false);
+    DockMaster.FOverlappingForm.AnchorDockHostSite:=self;
+    header.Parent:=DockMaster.FOverlappingForm;
+    FMinimizedControl.Parent:=DockMaster.FOverlappingForm;
+    FMinimizedControl.Show;
+    DockMaster.ShowOverlappingForm;
+  end;
+end;
+
+procedure TAnchorDockHostSite.HideMinimizedControl;
+begin
+   FMinimizedControl.Hide;
+   header.Parent:=self;
+   header.UpdateHeaderControls;
+   FMinimizedControl.Parent:=nil;
+   FreeAndNil(DockMaster.FOverlappingForm);
+end;
+
 function TAnchorDockHostSite.CloseSite: boolean;
 var
   AControl: TControl;
@@ -5306,9 +5633,8 @@
     if Parent is TAnchorDockPage then
       TAnchorDockPage(Parent).UpdateDockCaption;
   end;
-
   // do not show close button for mainform
-  Header.CloseButton.Visible:=not IsParentOf(Application.MainForm);
+  Header.CloseButton.Visible:=(not IsParentOf(Application.MainForm))and(Pages=nil);
 end;
 
 procedure TAnchorDockHostSite.GetSiteInfo(Client: TControl;
@@ -5362,9 +5688,33 @@
 end;
 
 procedure TAnchorDockHostSite.UpdateHeaderAlign;
+const
+OppositeAlign: array[TAnchorKind] of TAlign = (
+  alBottom, // akTop,
+  alRight,  // akLeft,
+  alLeft,   // akRight,
+  alTop     // akBottom
+  );
+OppositeAnchorKindAlign: array[TAnchorKind] of TADLHeaderPosition = (
+  adlhpBottom, // akTop,
+  adlhpRight,  // akLeft,
+  adlhpLeft,   // akRight,
+  adlhpTop     // akBottom
+  );
+var
+  NeededHeaderPosition:TADLHeaderPosition;
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
 begin
   if Header=nil then exit;
-  case Header.HeaderPosition of
+  if FMinimized then begin
+    if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+      NeededHeaderPosition:=OppositeAnchorKindAlign[SplitterAnchorKind];
+    end else
+      NeededHeaderPosition:=Header.HeaderPosition;
+  end else
+    NeededHeaderPosition:=Header.HeaderPosition;
+  case NeededHeaderPosition of
   adlhpAuto:
     if Header.Align in [alLeft,alRight] then begin
       if (ClientHeight>0)
@@ -5390,8 +5740,11 @@
 procedure TAnchorDockHostSite.UpdateHeaderShowing;
 begin
   if Header=nil then exit;
-  if HeaderNeedsShowing then
-    Header.Parent:=Self
+  if HeaderNeedsShowing then begin
+    Header.Parent:=Self;
+    Header.MinimizeButton.Visible:=DockMaster.DockSitesCanBeMinimized;
+    Header.MinimizeButton.Parent:=Header;
+  end
   else
     Header.Parent:=nil;
 end;
@@ -5432,7 +5785,7 @@
   if (SiteType=adhstOneControl) and (OneControl<>nil)
   and (not (OneControl is TAnchorDockHostSite)) then begin
     LayoutNode.NodeType:=adltnControl;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,FMinimized);
     LayoutNode.Name:=OneControl.Name;
     LayoutNode.HeaderPosition:=Header.HeaderPosition;
   end else if (SiteType in [adhstLayout,adhstOneControl]) then begin
@@ -5450,7 +5803,7 @@
         Splitter.SaveLayout(ChildNode);
       end;
     end;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,FMinimized);
     LayoutNode.HeaderPosition:=Header.HeaderPosition;
   end else if SiteType=adhstPages then begin
     LayoutNode.NodeType:=adltnPages;
@@ -5461,7 +5814,7 @@
         Site.SaveLayout(LayoutTree,ChildNode);
       end;
     end;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,FMinimized);
     LayoutNode.HeaderPosition:=Header.HeaderPosition;
   end else
     LayoutNode.NodeType:=adltnNone;
@@ -5476,6 +5829,9 @@
 constructor TAnchorDockHostSite.CreateNew(AOwner: TComponent; Num: Integer);
 begin
   inherited CreateNew(AOwner,Num);
+  FMinimized:=false;
+  fMinimization:=false;
+  FMinimizedControl:=Nil;
   Visible:=false;
   FHeaderSide:=akTop;
   FHeader:=DockMaster.HeaderClass.Create(Self);
@@ -5490,13 +5846,13 @@
 end;
 
 destructor TAnchorDockHostSite.Destroy;
-//var i: Integer;
+var i: Integer;
 begin
-  //debugln(['TAnchorDockHostSite.Destroy ',DbgSName(Self),' Caption="',Caption,'" Self=',dbgs(Pointer(Self)),' ComponentCount=',ComponentCount,' ControlCount=',ControlCount]);
-  {for i:=0 to ComponentCount-1 do
+  debugln(['TAnchorDockHostSite.Destroy ',DbgSName(Self),' Caption="',Caption,'" Self=',dbgs(Pointer(Self)),' ComponentCount=',ComponentCount,' ControlCount=',ControlCount]);
+  for i:=0 to ComponentCount-1 do
     debugln(['TAnchorDockHostSite.Destroy Component ',i,'/',ComponentCount,' ',DbgSName(Components[i])]);
   for i:=0 to ControlCount-1 do
-    debugln(['TAnchorDockHostSite.Destroy Control ',i,'/',ControlCount,' ',DbgSName(Controls[i])]);}
+    debugln(['TAnchorDockHostSite.Destroy Control ',i,'/',ControlCount,' ',DbgSName(Controls[i])]);
   FreePages;
   inherited Destroy;
 end;
@@ -5562,13 +5918,34 @@
 end;
 
 procedure TAnchorDockHeader.CloseButtonClick(Sender: TObject);
+var
+  HeaderParent:TAnchorDockHostSite;
 begin
-  if Parent is TAnchorDockHostSite then begin
-    DockMaster.RestoreLayouts.Add(DockMaster.CreateRestoreLayout(Parent),true);
-    TAnchorDockHostSite(Parent).CloseSite;
+  TWinControl(HeaderParent):=Parent;
+  if HeaderParent=TWinControl(DockMaster.FOverlappingForm) then begin
+    HeaderParent:=DockMaster.FOverlappingForm.AnchorDockHostSite;
+    HeaderParent.HideMinimizedControl;
   end;
+  if HeaderParent is TAnchorDockHostSite then begin
+    DockMaster.RestoreLayouts.Add(DockMaster.CreateRestoreLayout(HeaderParent),true);
+    HeaderParent.CloseSite;
+  end;
 end;
 
+procedure TAnchorDockHeader.MinimizeButtonClick(Sender: TObject);
+var
+  HeaderParent:TAnchorDockHostSite;
+begin
+  TWinControl(HeaderParent):=Parent;
+  if HeaderParent=TWinControl(DockMaster.FOverlappingForm) then begin
+    HeaderParent:=DockMaster.FOverlappingForm.AnchorDockHostSite;
+    HeaderParent.HideMinimizedControl;
+  end;
+  if HeaderParent is TAnchorDockHostSite then begin
+    HeaderParent.MinimizeSite;
+  end;
+end;
+
 procedure TAnchorDockHeader.HeaderPositionItemClick(Sender: TObject);
 var
   Item: TMenuItem;
@@ -5640,6 +6017,13 @@
       r.Right:=CloseButton.Left-1;
   end;
 
+  if MinimizeButton.IsControlVisible and (MinimizeButton.Parent=Self) then begin
+    if Align in [alLeft,alRight] then
+      r.Top:=MinimizeButton.Top+MinimizeButton.Height+1
+    else
+      r.Right:=MinimizeButton.Left-1;
+  end;
+
   // caption
   if Caption<>'' then begin
     if fFocused and DockMaster.HeaderHighlightFocused and NeedHighlightText then
@@ -5728,25 +6112,89 @@
     end else begin
       PreferredHeight:=Max(NeededHeight,PreferredHeight);
     end;
+  end else begin
+    NeededHeight:=CloseButton.Height;
+    if Align in [alLeft,alRight] then begin
+      PreferredWidth:=Max(NeededHeight,PreferredWidth);
+    end else begin
+      PreferredHeight:=Max(NeededHeight,PreferredHeight);
   end;
+  end;
 end;
 
 procedure TAnchorDockHeader.MouseDown(Button: TMouseButton; Shift: TShiftState;
   X, Y: Integer);
+var
+  SiteMinimized:Boolean;
 begin
   inherited MouseDown(Button, Shift, X, Y);
-  if (Button=mbLeft) and DockMaster.AllowDragging then
-    DragManager.DragStart(Parent,false,DockMaster.DragTreshold);
+  SiteMinimized:=False;
+  if Parent is TAnchorDockHostSite then
+    SiteMinimized:=(Parent as TAnchorDockHostSite).FMinimized;
+  if SiteMinimized then begin
+    DoMouseNoMoveTimer(nil);
+  end else
+    if (Button=mbLeft) and (DockMaster.AllowDragging) and (DockMaster.FOverlappingForm=nil) then
+      DragManager.DragStart(Parent,false,DockMaster.DragTreshold);
 end;
 
+procedure  TAnchorDockHeader.MouseMove(Shift: TShiftState; X,Y: Integer);
+begin
+  inherited MouseMove(Shift, X, Y);
+  if parent<>nil then
+    if parent is TAnchorDockHostSite then
+      if (parent as TAnchorDockHostSite).FMinimized then
+        if DockMaster.FOverlappingForm=nil then
+          if FMouseTimeStartX=EmptyMouseTimeStartX then
+            StartMouseNoMoveTimer(X, Y)
+          else begin
+            if (abs(FMouseTimeStartX-X)>MouseNoMoveDelta)or(abs(FMouseTimeStartY-Y)>MouseNoMoveDelta)then
+            StopMouseNoMoveTimer;
+          end;
+end;
+
+procedure TAnchorDockHeader.MouseLeave;
+begin
+  inherited;
+  StopMouseNoMoveTimer;
+end;
+
+procedure TAnchorDockHeader.StartMouseNoMoveTimer(X, Y: Integer);
+begin
+  if DockTimer.Enabled then DockTimer.Enabled:=false;
+  DockTimer.Interval:=MouseNoMoveTime;
+  DockTimer.OnTimer:=@DoMouseNoMoveTimer;
+  DockTimer.Enabled:=true;
+end;
+
+procedure TAnchorDockHeader.StopMouseNoMoveTimer;
+begin
+  FMouseTimeStartX:=EmptyMouseTimeStartX;
+  DockTimer.OnTimer:=nil;
+  DockTimer.Enabled:=false;
+end;
+
+procedure TAnchorDockHeader.DoMouseNoMoveTimer(Sender: TObject);
+begin
+  StopMouseNoMoveTimer;
+  if parent<>nil then
+    if parent is TAnchorDockHostSite then
+      if (parent as TAnchorDockHostSite).FMinimized then
+        (parent as TAnchorDockHostSite).ShowMinimizedControl;
+end;
+
 procedure TAnchorDockHeader.UpdateHeaderControls;
 begin
   if Align in [alLeft,alRight] then begin
-    if CloseButton<>nil then
+    if CloseButton<>nil then begin
+      MinimizeButton.Align:=alTop;
       CloseButton.Align:=alTop;
+    end;
   end else begin
-    if CloseButton<>nil then
+    if CloseButton<>nil then begin
+      MinimizeButton.Align:=alRight;
       CloseButton.Align:=alRight;
+    end;
   end;
   //debugln(['TAnchorDockHeader.UpdateHeaderControls ',dbgs(Align),' ',dbgs(CloseButton.Align)]);
 end;
@@ -5787,9 +6235,9 @@
 begin
   inherited Create(TheOwner);
   FHeaderPosition:=adlhpAuto;
-  FCloseButton:=TAnchorDockCloseButton.Create(Self);
   BevelOuter:=bvNone;
   BorderWidth:=0;
+  FCloseButton:=TAnchorDockCloseButton.Create(Self);
   with FCloseButton do begin
     Name:='CloseButton';
     Parent:=Self;
@@ -5799,11 +6247,22 @@
     OnClick:=@CloseButtonClick;
     AutoSize:=true;
   end;
+  FMinimizeButton:=TAnchorDockMinimizeButton.Create(Self);
+  with FMinimizeButton do begin
+    Name:='MinimizeButton';
+    Parent:=Self;
+    Flat:=true;
+    ShowHint:=true;
+    Hint:=adrsMinimize;
+    OnClick:=@MinimizeButtonClick;
+    AutoSize:=true;
+  end;
   Align:=alTop;
   AutoSize:=true;
   ShowHint:=true;
   PopupMenu:=DockMaster.GetPopupMenu;
   fFocused:=false;
+  FMouseTimeStartX:=EmptyMouseTimeStartX;
 end;
 
 { TAnchorDockCloseButton }
@@ -5844,6 +6303,44 @@
   end;
 end;
 
+{ TAnchorDockMinimizeButton }
+
+function TAnchorDockMinimizeButton.GetDrawDetails: TThemedElementDetails;
+
+function WindowPart: TThemedWindow;
+  begin
+    // no check states available
+    Result := twMinButtonNormal;
+    if not IsEnabled then
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonDisabled{$ELSE}twMinButtonDisabled{$ENDIF}
+    else
+    if FState in [bsDown, bsExclusive] then
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonPushed{$ELSE}twMinButtonPushed{$ENDIF}
+    else
+    if FState = bsHot then
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonHot{$ELSE}twMinButtonHot{$ENDIF}
+    else
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonNormal{$ELSE}twMinButtonNormal{$ENDIF};
+  end;
+
+begin
+  Result := ThemeServices.GetElementDetails(WindowPart);
+end;
+
+procedure TAnchorDockMinimizeButton.CalculatePreferredSize(var PreferredWidth,
+  PreferredHeight: integer; WithThemeSpace: Boolean);
+begin
+  with ThemeServices.GetDetailSize(ThemeServices.GetElementDetails({$IFDEF LCLGtk2}twMDIRestoreButtonNormal{$ELSE}twMinButtonNormal{$ENDIF})) do
+  begin
+    PreferredWidth:=cx;
+    PreferredHeight:=cy;
+    {$IF defined(LCLGtk2) or defined(Carbon)}
+    inc(PreferredWidth,2);
+    inc(PreferredHeight,2);
+    {$ENDIF}
+  end;
+end;
+
 { TAnchorDockManager }
 
 procedure TAnchorDockManager.SetPreferredSiteSizeAsSiteMinimum(
@@ -6213,6 +6710,9 @@
   ClientRectChanged:=(WidthDiff<>0) or (HeightDiff<>0);
   if ClientRectChanged or PreferredSiteSizeAsSiteMinimum then
     AlignChilds;
+  if ClientRectChanged then
+    if DockMaster.FOverlappingForm<>nil then
+      DockMaster.HideOverlappingForm(nil);
 end;
 
 procedure TAnchorDockManager.SaveToStream(Stream: TStream);
@@ -6505,32 +7005,58 @@
 procedure TAnchorDockSplitter.SetBoundsPercentually;
 var
   NewLeft, NewTop: Integer;
+  AControl: TControl;
+  SplitterAnchorKind:TAnchorKind;
 begin
-  if ResizeAnchor in [akLeft,akRight] then
-  begin
-    if DockParentClientSize.cx> 0 then
+  if Enabled then begin
+    if ResizeAnchor in [akLeft,akRight] then
     begin
-      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
-        NewLeft := Round(FPercentPosition*Parent.ClientWidth)
-      else
-        NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
-      NewTop := Top;
-      SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      if DockParentClientSize.cx> 0 then
+      begin
+        if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+          NewLeft := Round(FPercentPosition*Parent.ClientWidth)
+        else
+          NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
+        NewTop := Top;
+        SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      end;
+    end else
+    begin
+      if DockParentClientSize.cy> 0 then
+      begin
+        NewLeft := Left;
+        if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+          NewTop := Round(FPercentPosition*Parent.ClientHeight)
+        else
+          NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+        SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      end;
     end;
-  end else
-  begin
-    if DockParentClientSize.cy> 0 then
-    begin
-      NewLeft := Left;
-      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
-        NewTop := Round(FPercentPosition*Parent.ClientHeight)
-      else
-        NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+    if FPercentPosition < 0 then
+      UpdatePercentPosition;
+  end else begin
+    SplitterAnchorKind:=akTop;
+    AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);
+    if AControl=nil then begin SplitterAnchorKind:=akRight;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+    if AControl=nil then begin SplitterAnchorKind:=akBottom;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+    if AControl=nil then begin SplitterAnchorKind:=akLeft;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+
+    if AControl is TAnchorDockHostSite then begin
+      (AControl as TAnchorDockHostSite).UpdateHeaderAlign;
+      NewTop := (AControl as TAnchorDockHostSite).Header.Left;
+      NewTop := (AControl as TAnchorDockHostSite).Header.Height;
+      NewLeft := left;
+      NewTop := top;
+      (AControl as TAnchorDockHostSite).UpdateHeaderAlign;
+      case SplitterAnchorKind of
+        akTop: NewTop := AControl.Top+(AControl as TAnchorDockHostSite).Header.Height;
+        akBottom: NewTop := AControl.Top+AControl.Height-(AControl as TAnchorDockHostSite).Header.Height-Height;
+        akLeft: NewLeft := AControl.Left+(AControl as TAnchorDockHostSite).Header.Width;
+        akRight: NewLeft := AControl.Left+AControl.Width-(AControl as TAnchorDockHostSite).Header.Width-Width;
+      end;
       SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
     end;
   end;
-  if FPercentPosition < 0 then
-    UpdatePercentPosition;
 end;
 
 function TAnchorDockSplitter.SideAnchoredControlCount(Side: TAnchorKind): integer;
@@ -6560,14 +7086,47 @@
   end;
 end;
 
+function TAnchorDockSplitter.GetSpliterBoundsWithUnminimizedDockSites:TRect;
+var
+  NewLeft, NewTop: Integer;
+begin
+  if ResizeAnchor in [akLeft,akRight] then
+  begin
+    if DockParentClientSize.cx> 0 then
+    begin
+      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+        NewLeft := Round(FPercentPosition*Parent.ClientWidth)
+      else
+        NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
+      NewTop := Top;
+    end;
+  end else
+  begin
+    if DockParentClientSize.cy> 0 then
+    begin
+      NewLeft := Left;
+      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+        NewTop := Round(FPercentPosition*Parent.ClientHeight)
+      else
+        NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+    end;
+  end;
+  result:=Rect(NewLeft,NewTop,NewLeft+Width,NewTop+Height);
+end;
+
 procedure TAnchorDockSplitter.SaveLayout(
   LayoutNode: TAnchorDockLayoutTreeNode);
+var
+  NewLeft, NewTop: Integer;
 begin
   if ResizeAnchor in [akLeft,akRight] then
     LayoutNode.NodeType:=adltnSplitterVertical
   else
     LayoutNode.NodeType:=adltnSplitterHorizontal;
-  LayoutNode.Assign(Self);
+  LayoutNode.Assign(Self,false,false);
+  if not Enabled then begin
+    LayoutNode.BoundsRect:=GetSpliterBoundsWithUnminimizedDockSites;
+  end
 end;
 
 function TAnchorDockSplitter.HasOnlyOneSibling(Side: TAnchorKind; MinPos,
@@ -6645,7 +7204,7 @@
 begin
   inherited MouseDown(Button, Shift, X, Y);
   ATabIndex := IndexOfPageAt(X, Y);
-  if (Button = mbLeft) and DockMaster.AllowDragging and (ATabIndex >= 0) then
+  if (Button = mbLeft) and DockMaster.AllowDragging and (ATabIndex >= 0) and (DockMaster.FOverlappingForm=nil) then
   begin
     APage:=Page[ATabIndex];
     if (APage.ControlCount>0) and (APage.Controls[0] is TAnchorDockHostSite) then
@@ -6782,6 +7341,20 @@
   PopupMenu:=DockMaster.GetPopupMenu;
 end;
 
+{ TAnchorDockOverlappingForm }
+
+constructor TAnchorDockOverlappingForm.CreateNew(AOwner: TComponent; Num: Integer = 0);
+begin
+  inherited;
+  BorderStyle:=bsNone;
+  AnchorDockHostSite:=nil;
+end;
+
+procedure TAnchorDockOverlappingForm.MouseLeave;
+begin
+  inherited;
+end;
+
 { TAnchorDockPage }
 
 procedure TAnchorDockPage.UpdateDockCaption(Exclude: TControl);
@@ -6835,9 +7408,11 @@
 
 initialization
   DockMaster:=TAnchorDockMaster.Create(nil);
+  DockTimer:=TTimer.Create(nil);
 
 finalization
   FreeAndNil(DockMaster);
+  FreeAndNil(DockTimer);
 
 end.
 
Index: components/anchordocking/anchordockoptionsdlg.lfm
===================================================================
--- components/anchordocking/anchordockoptionsdlg.lfm	(revision 59428)
+++ components/anchordocking/anchordockoptionsdlg.lfm	(working copy)
@@ -1,11 +1,13 @@
 object AnchorDockOptionsFrame: TAnchorDockOptionsFrame
   Left = 0
-  Height = 482
+  Height = 567
   Top = 0
-  Width = 416
-  ClientHeight = 482
-  ClientWidth = 416
+  Width = 490
+  ClientHeight = 567
+  ClientWidth = 490
+  DesignTimePPI = 113
   OnClick = FrameClick
+  ParentFont = False
   TabOrder = 0
   DesignLeft = 513
   DesignTop = 189
@@ -12,14 +14,15 @@
   object DragThresholdLabel: TLabel
     AnchorSideLeft.Control = Owner
     AnchorSideTop.Control = Owner
-    Left = 10
-    Height = 13
-    Top = 10
-    Width = 111
-    BorderSpacing.Left = 10
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 12
+    Width = 122
+    BorderSpacing.Left = 12
+    BorderSpacing.Top = 12
     Caption = 'DragThresholdLabel'
     ParentColor = False
+    ParentFont = False
   end
   object DragThresholdTrackBar: TTrackBar
     AnchorSideLeft.Control = DragThresholdLabel
@@ -27,15 +30,16 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = Owner
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 46
-    Top = 23
-    Width = 396
+    Left = 12
+    Height = 54
+    Top = 31
+    Width = 466
     Max = 20
     OnChange = DragThresholdTrackBarChange
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Right = 10
+    BorderSpacing.Right = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 1
@@ -46,12 +50,13 @@
     AnchorSideTop.Control = DragThresholdLabel
     AnchorSideTop.Side = asrCenter
     AnchorSideRight.Control = Owner
-    Left = 127
-    Height = 23
-    Top = 5
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 141
+    Height = 27
+    Top = 8
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 20
+    ParentFont = False
     TabOrder = 0
     Visible = False
   end
@@ -59,13 +64,14 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = DragThresholdTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 79
-    Width = 103
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 97
+    Width = 112
+    BorderSpacing.Top = 12
     Caption = 'SplitterWidthLabel'
     ParentColor = False
+    ParentFont = False
   end
   object SplitterWidthTrackBar: TTrackBar
     AnchorSideLeft.Control = DragThresholdTrackBar
@@ -73,14 +79,15 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 46
-    Top = 92
-    Width = 396
+    Left = 12
+    Height = 54
+    Top = 116
+    Width = 466
     Min = 1
     OnChange = SplitterWidthTrackBarChange
     Position = 1
     Anchors = [akTop, akLeft, akRight]
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 3
@@ -89,12 +96,13 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = SplitterWidthTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 24
-    Top = 142
-    Width = 160
-    BorderSpacing.Top = 4
+    Left = 12
+    Height = 23
+    Top = 175
+    Width = 169
+    BorderSpacing.Top = 5
     Caption = 'ScaleOnResizeCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 4
@@ -103,12 +111,13 @@
     AnchorSideLeft.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 24
-    Top = 166
-    Width = 149
+    Left = 12
+    Height = 23
+    Top = 198
+    Width = 160
     Caption = 'ShowHeaderCheckBox'
     OnChange = ShowHeaderCheckBoxChange
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 5
@@ -117,12 +126,13 @@
     AnchorSideLeft.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Control = ShowHeaderCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 190
-    Width = 191
-    BorderSpacing.Left = 15
+    Left = 30
+    Height = 23
+    Top = 221
+    Width = 208
+    BorderSpacing.Left = 18
     Caption = 'ShowHeaderCaptionCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 6
@@ -131,11 +141,12 @@
     AnchorSideLeft.Control = ShowHeaderCaptionCheckBox
     AnchorSideTop.Control = ShowHeaderCaptionCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 214
-    Width = 249
+    Left = 30
+    Height = 23
+    Top = 244
+    Width = 272
     Caption = 'HideHeaderCaptionForFloatingCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 7
@@ -147,15 +158,16 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = Owner
     AnchorSideRight.Side = asrBottom
-    Left = 122
+    Left = 136
     Height = 27
-    Top = 286
-    Width = 284
+    Top = 313
+    Width = 342
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 6
-    BorderSpacing.Right = 10
-    ItemHeight = 0
+    BorderSpacing.Left = 7
+    BorderSpacing.Right = 12
+    ItemHeight = 19
     OnDrawItem = HeaderStyleComboBoxDrawItem
+    ParentFont = False
     Style = csDropDownList
     TabOrder = 10
   end
@@ -163,23 +175,25 @@
     AnchorSideLeft.Control = ShowHeaderCheckBox
     AnchorSideTop.Control = HeaderStyleComboBox
     AnchorSideTop.Side = asrCenter
-    Left = 20
-    Height = 13
-    Top = 293
-    Width = 96
-    BorderSpacing.Left = 10
+    Left = 24
+    Height = 19
+    Top = 317
+    Width = 105
+    BorderSpacing.Left = 12
     Caption = 'HeaderStyleLabel'
     ParentColor = False
+    ParentFont = False
   end
   object FlattenHeadersCheckBox: TCheckBox
     AnchorSideLeft.Control = HideHeaderCaptionForFloatingCheckBox
     AnchorSideTop.Control = HideHeaderCaptionForFloatingCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 238
-    Width = 164
+    Left = 30
+    Height = 23
+    Top = 267
+    Width = 175
     Caption = 'FlattenHeadersCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 8
@@ -188,11 +202,12 @@
     AnchorSideLeft.Control = FlattenHeadersCheckBox
     AnchorSideTop.Control = FlattenHeadersCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 262
-    Width = 154
+    Left = 30
+    Height = 23
+    Top = 290
+    Width = 164
     Caption = 'FilledHeadersCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 9
@@ -201,11 +216,12 @@
     AnchorSideLeft.Control = FilledHeadersCheckBox
     AnchorSideTop.Control = HeaderStyleComboBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 313
-    Width = 175
+    Left = 30
+    Height = 23
+    Top = 340
+    Width = 189
     Caption = 'HighlightFocusedCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 11
@@ -215,13 +231,14 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = SplitterWidthLabel
     AnchorSideTop.Side = asrCenter
-    Left = 119
-    Height = 23
-    Top = 74
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 131
+    Height = 27
+    Top = 93
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 10
     MinValue = 1
+    ParentFont = False
     TabOrder = 2
     Value = 1
     Visible = False
@@ -228,15 +245,16 @@
   end
   object HeaderAlignTopLabel: TLabel
     AnchorSideLeft.Control = DragThresholdLabel
-    AnchorSideTop.Control = HighlightFocusedCheckBox
+    AnchorSideTop.Control = DockSitesCanBeMinimized
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 347
-    Width = 117
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 398
+    Width = 130
+    BorderSpacing.Top = 12
     Caption = 'HeaderAlignTopLabel'
     ParentColor = False
+    ParentFont = False
   end
   object HeaderAlignTopTrackBar: TTrackBar
     AnchorSideLeft.Control = Owner
@@ -244,10 +262,10 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 47
-    Top = 360
-    Width = 396
+    Left = 12
+    Height = 55
+    Top = 417
+    Width = 466
     Frequency = 10
     Max = 150
     OnChange = HeaderAlignTopTrackBarChange
@@ -254,7 +272,8 @@
     PageSize = 10
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 10
+    BorderSpacing.Left = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 13
@@ -264,12 +283,13 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = HeaderAlignTopLabel
     AnchorSideTop.Side = asrCenter
-    Left = 133
-    Height = 23
-    Top = 342
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 149
+    Height = 27
+    Top = 394
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 150
+    ParentFont = False
     TabOrder = 12
     Visible = False
   end
@@ -277,13 +297,14 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = HeaderAlignTopTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 417
-    Width = 120
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 484
+    Width = 130
+    BorderSpacing.Top = 12
     Caption = 'HeaderAlignLeftLabel'
     ParentColor = False
+    ParentFont = False
   end
   object HeaderAlignLeftTrackBar: TTrackBar
     AnchorSideLeft.Control = Owner
@@ -291,10 +312,10 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 47
-    Top = 430
-    Width = 396
+    Left = 12
+    Height = 55
+    Top = 503
+    Width = 466
     Frequency = 10
     Max = 200
     OnChange = HeaderAlignLeftTrackBarChange
@@ -301,7 +322,8 @@
     PageSize = 10
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 10
+    BorderSpacing.Left = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 15
@@ -311,13 +333,28 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = HeaderAlignLeftLabel
     AnchorSideTop.Side = asrCenter
-    Left = 136
-    Height = 23
-    Top = 412
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 149
+    Height = 27
+    Top = 480
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 200
+    ParentFont = False
     TabOrder = 14
     Visible = False
   end
+  object DockSitesCanBeMinimized: TCheckBox
+    AnchorSideLeft.Control = FilledHeadersCheckBox
+    AnchorSideTop.Control = HighlightFocusedCheckBox
+    AnchorSideTop.Side = asrBottom
+    Left = 30
+    Height = 23
+    Top = 363
+    Width = 185
+    Caption = 'DockSitesCanBeMinimized'
+    ParentFont = False
+    ParentShowHint = False
+    ShowHint = True
+    TabOrder = 16
+  end
 end
Index: components/anchordocking/anchordockoptionsdlg.pas
===================================================================
--- components/anchordocking/anchordockoptionsdlg.pas	(revision 59428)
+++ components/anchordocking/anchordockoptionsdlg.pas	(working copy)
@@ -37,6 +37,7 @@
     HeaderStyleLabel: TLabel;
     HideHeaderCaptionForFloatingCheckBox: TCheckBox;
     HighlightFocusedCheckBox: TCheckBox;
+    DockSitesCanBeMinimized: TCheckBox;
     ScaleOnResizeCheckBox: TCheckBox;
     ShowHeaderCaptionCheckBox: TCheckBox;
     ShowHeaderCheckBox: TCheckBox;
@@ -299,6 +300,7 @@
   HeaderStyleLabel.Enabled:=HasHeaders;
   HeaderStyleComboBox.Enabled:=HasHeaders;
   HighlightFocusedCheckBox.Enabled:=HasHeaders;
+  DockSitesCanBeMinimized.Enabled:=HasHeaders;
 end;
 
 constructor TAnchorDockOptionsFrame.Create(TheOwner: TComponent);
@@ -356,6 +358,7 @@
   TheSettings.HeaderFilled:=FilledHeadersCheckBox.Checked;
   TheSettings.HeaderStyle:=TADHeaderStyle(HeaderStyleComboBox.ItemIndex);
   TheSettings.HeaderHighlightFocused:=HighlightFocusedCheckBox.Checked;
+  TheSettings.DockSitesCanBeMinimized:=DockSitesCanBeMinimized.Checked;
 end;
 
 procedure TAnchorDockOptionsFrame.LoadFromSettings(
@@ -429,6 +432,10 @@
   HighlightFocusedCheckBox.Checked:=TheSettings.HeaderHighlightFocused;
   HighlightFocusedCheckBox.Caption:=adrsHighlightFocused;
   HighlightFocusedCheckBox.Hint:=adrsHighlightFocusedHint;
+
+  DockSitesCanBeMinimized.Checked:=TheSettings.DockSitesCanBeMinimized;
+  DockSitesCanBeMinimized.Caption:=adrsDockSitesCanBeMinimized;
+  DockSitesCanBeMinimized.Hint:=adrsDockSitesCanBeMinimizedHint;
 end;
 
 end.
Index: components/anchordocking/anchordockpanel.pas
===================================================================
--- components/anchordocking/anchordockpanel.pas	(revision 59428)
+++ components/anchordocking/anchordockpanel.pas	(working copy)
@@ -55,7 +55,7 @@
   begin
 
     LayoutNode.NodeType:=adltnControl;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,false);
     LayoutNode.Name:={OneControl.}Name;
 
     TAnchorDockHostSite(OneControl).SaveLayout(LayoutTree,LayoutNode);
Index: components/anchordocking/anchordockstorage.pas
===================================================================
--- components/anchordocking/anchordockstorage.pas	(revision 59428)
+++ components/anchordocking/anchordockstorage.pas	(working copy)
@@ -64,6 +64,7 @@
     FTabPosition: TTabPosition;
     FWindowState: TWindowState;
     FControlLocation: TADLControlLocation;
+    FMinimized: Boolean;
     function GetAnchors(Site: TAnchorKind): string;
     function GetBottom: integer;
     function GetHeight: integer;
@@ -90,6 +91,7 @@
     procedure SetTop(const AValue: integer);
     procedure SetWidth(const AValue: integer);
     procedure SetWindowState(const AValue: TWindowState);
+    procedure SetMinimized(const AValue: boolean);
   public
     constructor Create;
     destructor Destroy; override;
@@ -96,7 +98,7 @@
     procedure Clear;
     function IsEqual(Node: TAnchorDockLayoutTreeNode): boolean;
     procedure Assign(Node: TAnchorDockLayoutTreeNode); overload;
-    procedure Assign(AControl: TControl; OverrideBoundsRect: Boolean=false); overload;
+    procedure Assign(AControl: TControl; OverrideBoundsRect: Boolean; AMinimized: Boolean); overload;
     procedure LoadFromConfig(Config: TConfigStorage); overload;
     procedure LoadFromConfig(Path: string; Config: TRttiXMLConfig); overload;
     procedure SaveToConfig(Config: TConfigStorage); overload;
@@ -106,7 +108,7 @@
     procedure CheckConsistency; virtual;
 
     // simplifying
-    procedure Simplify(ExistingNames: TStrings);
+    procedure Simplify(ExistingNames: TStrings; ParentMinimized:boolean);
     procedure DeleteNode(ChildNode: TAnchorDockLayoutTreeNode);
     function FindNodeBoundSplitter(ChildNode: TAnchorDockLayoutTreeNode;
                                    Side: TAnchorKind): TAnchorDockLayoutTreeNode;
@@ -135,6 +137,7 @@
     property Monitor: integer read FMonitor write SetMonitor;
     property HeaderPosition: TADLHeaderPosition read FHeaderPosition write SetHeaderPosition;
     property TabPosition: TTabPosition read FTabPosition write SetTabPosition;
+    property Minimized: Boolean read FMinimized write SetMinimized;
     function Count: integer;
     function IsSplitter: boolean;
     function IsRootWindow: boolean;
@@ -988,6 +991,13 @@
   IncreaseChangeStamp;
 end;
 
+procedure TAnchorDockLayoutTreeNode.SetMinimized(const AValue: boolean);
+begin
+  if FMinimized=AValue then exit;
+  FMinimized:=AValue;
+  IncreaseChangeStamp;
+end;
+
 procedure TAnchorDockLayoutTreeNode.SetTop(const AValue: integer);
 begin
   if Top=AValue then exit;
@@ -1084,6 +1094,7 @@
   BoundSplitterPos:=Node.BoundSplitterPos;
   WorkAreaRect:=Node.WorkAreaRect;
   Monitor:=Node.Monitor;
+  Minimized:=Node.Minimized;
   for a:=low(TAnchorKind) to high(TAnchorKind) do
     Anchors[a]:=Node.Anchors[a];
   while Count>Node.Count do Nodes[Count-1].Free;
@@ -1098,9 +1109,10 @@
   end;
 end;
 
-procedure TAnchorDockLayoutTreeNode.Assign(AControl: TControl; OverrideBoundsRect: Boolean=false);
+procedure TAnchorDockLayoutTreeNode.Assign(AControl: TControl; OverrideBoundsRect: Boolean; AMinimized: Boolean);
 var
   AnchorControl: TControl;
+  ParentForm:TCustomForm;
   a: TAnchorKind;
 begin
   Name:=AControl.Name;
@@ -1109,12 +1121,18 @@
   else
     BoundsRect:=AControl.BoundsRect;
   Align:=AControl.Align;
+  Minimized:=AMinimized;
   if (AControl.Parent=nil) and (AControl is TCustomForm) then begin
     WindowState:=TCustomForm(AControl).WindowState;
     Monitor:=TCustomForm(AControl).Monitor.MonitorNum;
     WorkAreaRect:=TCustomForm(AControl).Monitor.WorkareaRect;
-  end else
-    WindowState:=GetParentForm(AControl).WindowState;
+  end else begin
+    ParentForm:=GetParentForm(AControl);
+    if assigned(ParentForm) then
+      WindowState:=ParentForm.WindowState
+    else
+      WindowState:=wsNormal;
+  end;
   if AControl is TCustomTabControl then
     TabPosition:=TCustomTabControl(AControl).TabPosition
   else
@@ -1137,6 +1155,7 @@
   Clear;
   Name:=Config.GetValue('Name','');
   NodeType:=NameToADLTreeNodeType(Config.GetValue('Type',ADLTreeNodeTypeNames[adltnNone]));
+  Minimized:=Config.GetValue('Minimized',false);
   Left:=Config.GetValue('Bounds/Left',0);
   Top:=Config.GetValue('Bounds/Top',0);
   Width:=Config.GetValue('Bounds/Width',0);
@@ -1171,6 +1190,7 @@
   Clear;
   Name:=Config.GetValue(Path+'Name','');
   NodeType:=NameToADLTreeNodeType(Config.GetValue(Path+'Type',ADLTreeNodeTypeNames[adltnNone]));
+  Minimized:=Config.GetValue(Path+'Minimized',false);
   Left:=Config.GetValue(Path+'Bounds/Left',0);
   Top:=Config.GetValue(Path+'Bounds/Top',0);
   Width:=Config.GetValue(Path+'Bounds/Width',0);
@@ -1219,6 +1239,7 @@
                                           ADLHeaderPositionNames[adlhpAuto]);
   Config.SetDeleteValue('Header/TabPosition',ADLTabPostionNames[TabPosition],
                                              ADLTabPostionNames[tpTop]);
+  Config.SetDeleteValue('Minimized',Minimized,False);
   Config.SetDeleteValue('Monitor',Monitor,0);
   Config.SetDeleteValue('ChildCount',Count,0);
   for i:=1 to Count do begin
@@ -1252,6 +1273,7 @@
                                                ADLHeaderPositionNames[adlhpAuto]);
   Config.SetDeleteValue(Path+'Header/TabPosition',ADLTabPostionNames[TabPosition],
                                                   ADLTabPostionNames[tpTop]);
+  Config.SetDeleteValue(Path+'Minimized',Minimized,False);
   Config.SetDeleteValue(Path+'Monitor',Monitor,0);
   Config.SetDeleteValue(Path+'ChildCount',Count,0);
   for i:=1 to Count do
@@ -1397,7 +1419,7 @@
   end;
 end;
 
-procedure TAnchorDockLayoutTreeNode.Simplify(ExistingNames: TStrings);
+procedure TAnchorDockLayoutTreeNode.Simplify(ExistingNames: TStrings; ParentMinimized:boolean);
 { Simplification rules:
    1. Control nodes without existing name are deleted.
    2. Empty layouts and pages are deleted
@@ -1406,16 +1428,18 @@
 var
   i: Integer;
   ChildNode: TAnchorDockLayoutTreeNode;
+  NodeMinimized:boolean;
 begin
   // simplify children
   i:=Count-1;
   while i>=0 do begin
     ChildNode:=Nodes[i];
-    ChildNode.Simplify(ExistingNames);
+    NodeMinimized:=ParentMinimized or ChildNode.Minimized;
+    ChildNode.Simplify(ExistingNames,NodeMinimized);
 
     if (ChildNode.NodeType=adltnControl) then begin
       // leaf node => check if there is a control
-      if (ChildNode.Name='') or (ExistingNames.IndexOf(ChildNode.Name)<0) then
+      if (ChildNode.Name='') or ((ExistingNames.IndexOf(ChildNode.Name)<0) and (not NodeMinimized)) then
         DeleteNode(ChildNode);
     end else if ChildNode.IsSplitter then begin
       // splitter
@@ -1424,7 +1448,7 @@
         ChildNode[0].Free;
     end else if ChildNode.NodeType=adltnCustomSite then begin
       // custom dock site
-    end else if ChildNode.Count=0 then begin
+    end else if (ChildNode.Count=0)and(not NodeMinimized) then begin
       // inner node without child => delete
       DeleteNode(ChildNode);
     end else if (ChildNode.Count=1)
Index: components/anchordocking/anchordockstr.pas
===================================================================
--- components/anchordocking/anchordockstr.pas	(revision 59428)
+++ components/anchordocking/anchordockstr.pas	(working copy)
@@ -8,6 +8,7 @@
 
 resourcestring
   adrsClose = 'Close';
+  adrsMinimize = 'Minimize';
   adrsQuit = 'Quit %s';
   adrsTabPosition = 'Tab position';
   adrsMovePageRight = 'Move page right';
@@ -82,6 +83,8 @@
   adrsFilledHeadersHint = 'Fill headers of docked controls';
   adrsHighlightFocused = 'Highlight focused';
   adrsHighlightFocusedHint = 'Highlight header of focused docked control';
+  adrsDockSitesCanBeMinimized = 'Dock sites can be minimized';
+  adrsDockSitesCanBeMinimizedHint = 'Dock sites can be minimized';
 
 implementation
 
Index: components/anchordocking/design/anchordesktopoptions.pas
===================================================================
--- components/anchordocking/design/anchordesktopoptions.pas	(revision 59428)
+++ components/anchordocking/design/anchordesktopoptions.pas	(working copy)
@@ -272,7 +272,7 @@
         // custom dock site
         LayoutNode:=FTree.NewNode(FTree.Root);
         LayoutNode.NodeType:=adltnCustomSite;
-        LayoutNode.Assign(AForm);
+        LayoutNode.Assign(AForm,false,false);
         // can have one normal dock site
         Site:=TAnchorDockManager(AForm.DockManager).GetChildSite;
         if Site<>nil then begin
@@ -287,7 +287,7 @@
         raise EAnchorDockLayoutError.Create('invalid root control for save: '+DbgSName(AControl));
     end;
     // remove invisible controls
-    FTree.Root.Simplify(VisibleControls);
+    FTree.Root.Simplify(VisibleControls,false);
   finally
     VisibleControls.Free;
     SavedSites.Free;

Andrey Zubarev

2018-11-11 00:21

reporter   ~0111897

Last edited: 2018-11-11 00:23

View 2 revisions

anchordocking_minimize_docksite8.patch
- no hide overlaping window if mouse captured
- disable drag minimized headers

Works in linux, but not tested!
Please review and test!

Michl

2018-11-11 21:49

developer   ~0111912

Last edited: 2018-11-11 21:50

View 2 revisions

Thank you for your work!
I like this feature very much and I don't think, this has to be optional. However it is implemented, so it can be optional.
I tested Windows 7 (Classic and Aero theme), Linux Mint KDE GTK2, Linux Mint KDE Qt.


Now my list of issues/suggestions:

1. A little one. In the options, this option is not correct aligned, it overlap option "header align top".

2. The caption of a form isn't shown, when it is minimized.

3. If a docked form is minimized and "show headers" are unchecked, the space for the header is further blocked, but nothing (just the background) is shown there.

4. It would be nice, if a second click on a closed form will close the form again, so it is not necessary to move the mouse out the form.

5. If you try to dock a form on a minimized form, Lazarus is crashed.

6. If you try to dock a form before a minimized form, it is docked after the minimized form and the layout is destroyed (the splitter get lost, the maximize button doesn't react anymore).

7. The preview window need a border and/or at least a background (maybe a TPanel). On Qt the tabs of a page control are shown with alpha channel. Without a background, they are not readable.


Hope you can manage the issues?! I'm looking forward for a new patch.

Andrey Zubarev

2018-11-12 00:08

reporter  

anchordocking_minimize_docksite9.patch (72,496 bytes)   
Index: components/anchordocking/anchordocking.pas
===================================================================
--- components/anchordocking/anchordocking.pas	(revision 59428)
+++ components/anchordocking/anchordocking.pas	(working copy)
@@ -109,6 +109,11 @@
 const ADAutoSizingReason = 'TAnchorDockMaster Delayed';
 {$ENDIF}
 
+const EmptyMouseTimeStartX=low(Integer);
+      MouseNoMoveDelta=5;
+      MouseNoMoveTime=500;
+      HideOverlappingFormByMouseLoseTime=500;
+
 type
   TAnchorDockHostSite = class;
 
@@ -123,6 +128,14 @@
            PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
   end;
 
+  TAnchorDockMinimizeButton = class(TCustomSpeedButton)
+  protected
+    function GetDrawDetails: TThemedElementDetails; override;
+    procedure CalculatePreferredSize(var PreferredWidth,
+           PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
+  end;
+
+
   { TAnchorDockHeader
     The panel of a TAnchorDockHostSite containing the close button and the
     caption when the form is docked. The header can be shown at any of the four
@@ -133,9 +146,13 @@
   TAnchorDockHeader = class(TCustomPanel)
   private
     FCloseButton: TCustomSpeedButton;
+    FMinimizeButton: TCustomSpeedButton;
     FHeaderPosition: TADLHeaderPosition;
     fFocused:Boolean;
+    fUseTimer:Boolean;
+    FMouseTimeStartX,FMouseTimeStartY:Integer;
     procedure CloseButtonClick(Sender: TObject);
+    procedure MinimizeButtonClick(Sender: TObject);
     procedure HeaderPositionItemClick(Sender: TObject);
     procedure UndockButtonClick(Sender: TObject);
     procedure MergeButtonClick(Sender: TObject);
@@ -147,6 +164,11 @@
           PreferredHeight: integer; WithThemeSpace: Boolean); override;
     procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X,
              Y: Integer); override;
+    procedure MouseMove(Shift: TShiftState; X,Y: Integer); override;
+    procedure MouseLeave;  override;
+    procedure StartMouseNoMoveTimer(X, Y: Integer);
+    procedure StopMouseNoMoveTimer;
+    procedure DoMouseNoMoveTimer(Sender: TObject);
     procedure UpdateHeaderControls;
     procedure SetAlign(Value: TAlign); override;
     procedure DoOnShowHint(HintInfo: PHintInfo); override;
@@ -154,6 +176,7 @@
   public
     constructor Create(TheOwner: TComponent); override;
     property CloseButton: TCustomSpeedButton read FCloseButton;
+    property MinimizeButton: TCustomSpeedButton read FMinimizeButton;
     property HeaderPosition: TADLHeaderPosition read FHeaderPosition write SetHeaderPosition;
     property BevelOuter default bvNone;
   end;
@@ -190,6 +213,7 @@
     procedure SetBoundsKeepDockBounds(ALeft, ATop, AWidth, AHeight: integer); // movement for scaling keeps the DockBounds
     function SideAnchoredControlCount(Side: TAnchorKind): integer;
     function HasAnchoredControls: boolean;
+    function GetSpliterBoundsWithUnminimizedDockSites:TRect;
     procedure SaveLayout(LayoutNode: TAnchorDockLayoutTreeNode);
     function HasOnlyOneSibling(Side: TAnchorKind; MinPos, MaxPos: integer): TControl;
     property DockRestoreBounds: TRect read FDockRestoreBounds write FDockRestoreBounds;
@@ -241,6 +265,14 @@
   end;
   TAnchorDockPageControlClass = class of TAnchorDockPageControl;
 
+
+  TAnchorDockOverlappingForm = class(TCustomForm)
+  public
+    AnchorDockHostSite:TAnchorDockHostSite;
+    Panel:TPanel;
+    constructor CreateNew(AOwner: TComponent; Num: Integer = 0); override;
+  end;
+
   { TAnchorDockHostSite
     This form is the dockhostsite for all controls.
     When docked together they build a tree structure with the docked controls
@@ -262,7 +294,10 @@
     FPages: TAnchorDockPageControl;
     FSiteType: TAnchorDockHostSiteType;
     FBoundSplitter: TAnchorDockSplitter;
-    fUpdateLayout: integer;
+    fUpdateLayout: Integer;
+    FMinimized: Boolean;
+    fMinimization: Boolean;
+    FMinimizedControl: TControl;
     procedure SetHeaderSide(const AValue: TAnchorKind);
   protected
     procedure DoEnter; override;
@@ -319,6 +354,10 @@
     destructor Destroy; override;
     function CloseQuery: boolean; override;
     function CloseSite: boolean; virtual;
+    procedure MinimizeSite; virtual;
+    procedure AsyncMinimizeSite(Data: PtrInt);
+    procedure ShowMinimizedControl;
+    procedure HideMinimizedControl;
     procedure RemoveControl(AControl: TControl); override;
     procedure InsertControl(AControl: TControl; Index: integer); override;
     procedure GetSiteInfo(Client: TControl; var InfluenceRect: TRect;
@@ -329,6 +368,7 @@
     procedure UpdateDockCaption(Exclude: TControl = nil); override;
     procedure UpdateHeaderAlign;
     procedure UpdateHeaderShowing;
+    function CanBeMinimized(out Splitter: TAnchorDockSplitter; out SplitterAnchorKind:TAnchorKind):boolean;
     procedure BeginUpdateLayout;
     procedure EndUpdateLayout;
     function UpdatingLayout: boolean;
@@ -431,6 +471,7 @@
     FShowHeader: boolean;
     FShowHeaderCaption: boolean;
     FSplitterWidth: integer;
+    FDockSitecCanBeMinimized: boolean;
     procedure SetAllowDragging(AValue: boolean);
     procedure SetDockOutsideMargin(AValue: integer);
     procedure SetDockParentMargin(AValue: integer);
@@ -448,6 +489,7 @@
     procedure SetHeaderFlatten(AValue: boolean);
     procedure SetHeaderFilled(AValue: boolean);
     procedure SetHeaderHighlightFocused(AValue: boolean);
+    procedure SetDockSitecCanBeMinimized(AValue: boolean);
   public
     property DragTreshold: integer read FDragTreshold write SetDragTreshold;
     property DockOutsideMargin: integer read FDockOutsideMargin write SetDockOutsideMargin;
@@ -466,6 +508,7 @@
     property HeaderFlatten: boolean read FHeaderFlatten write SetHeaderFlatten;
     property HeaderFilled: boolean read FHeaderFilled write SetHeaderFilled;
     property HeaderHighlightFocused: boolean read FHeaderHighlightFocused write SetHeaderHighlightFocused;
+    property DockSitesCanBeMinimized: boolean read FDockSitecCanBeMinimized write SetDockSitecCanBeMinimized;
     procedure IncreaseChangeStamp; inline;
     property ChangeStamp: integer read FChangeStamp;
     procedure LoadFromConfig(Config: TConfigStorage); overload;
@@ -502,6 +545,7 @@
     FHeaderFlatten: boolean;
     FHeaderFilled: boolean;
     FHeaderHighlightFocused: boolean;
+    FDockSitesCanBeMinimized: boolean;
     FIdleConnected: Boolean;
     FManagerClass: TAnchorDockManagerClass;
     FOnCreateControl: TADCreateControlEvent;
@@ -531,6 +575,7 @@
     fPopupMenu: TPopupMenu;
     // Used by RestoreLayout:
     WorkArea, SrcWorkArea: TRect;
+    FOverlappingForm:TAnchorDockOverlappingForm;
 
     function GetControls(Index: integer): TControl;
     function GetLocalizedHeaderHint: string;
@@ -541,6 +586,9 @@
     function GetNodeSite(Node: TAnchorDockLayoutTreeNode): TAnchorDockHostSite;
     procedure MapTreeToControls(Tree: TAnchorDockLayoutTree);
     function RestoreLayout(Tree: TAnchorDockLayoutTree; Scale: boolean): boolean;
+    procedure SetMinimizedState(Tree: TAnchorDockLayoutTree);
+    procedure UpdateHeaders;
+    procedure SetnodeMinimizedState(ANode: TAnchorDockLayoutTreeNode);
     procedure EnableAllAutoSizing;
     procedure ClearLayoutProperties(AControl: TControl; NewAlign: TAlign = alClient);
     procedure PopupMenuPopup(Sender: TObject);
@@ -561,6 +609,7 @@
     procedure SetHeaderFlatten(AValue: boolean);
     procedure SetHeaderFilled(AValue: boolean);
     procedure SetHeaderHighlightFocused(AValue: boolean);
+    procedure SetDockSitesCanBeMinimized(AValue: boolean);
 
     procedure SetShowMenuItemShowHeader(AValue: boolean);
     procedure SetupSite(Site: TWinControl; ANode: TAnchorDockLayoutTreeNode;
@@ -584,8 +633,12 @@
     procedure SetHideHeaderCaptionFloatingControl(const AValue: boolean);
     procedure SetSplitterWidth(const AValue: integer);
     procedure OnIdle(Sender: TObject; var Done: Boolean);
+    procedure StartHideOverlappingTimer;
+    procedure StopHideOverlappingTimer;
     procedure AsyncSimplify({%H-}Data: PtrInt);
   public
+    procedure ShowOverlappingForm;
+    procedure HideOverlappingForm(Sender: TObject);
     constructor Create(AOwner: TComponent); override;
     destructor Destroy; override;
     function FullRestoreLayout(Tree: TAnchorDockLayoutTree; Scale: Boolean): Boolean;
@@ -680,6 +733,7 @@
     property HeaderFlatten: boolean read FHeaderFlatten write SetHeaderFlatten default true;
     property HeaderFilled: boolean read FHeaderFilled write SetHeaderFilled default true;
     property HeaderHighlightFocused: boolean read FHeaderHighlightFocused write SetHeaderHighlightFocused default false;
+    property DockSitesCanBeMinimized: boolean read FDockSitesCanBeMinimized write SetDockSitesCanBeMinimized default false;
 
     property SplitterWidth: integer read FSplitterWidth write SetSplitterWidth default 4;
     property ScaleOnResize: boolean read FScaleOnResize write SetScaleOnResize default true; // scale children when resizing a site
@@ -698,6 +752,7 @@
 
 var
   DockMaster: TAnchorDockMaster = nil;
+  DockTimer: TTimer = nil;
 
 const
   ADHeaderStyleNames: array[TADHeaderStyle] of string = (
@@ -970,6 +1025,27 @@
   end;
 end;
 
+function CountAndReturnOnlyOneMinimizedAnchoredControls(Control: TControl; Side: TAnchorKind): TAnchorDockHostSite;
+var
+  i,Counter: Integer;
+  Neighbour: TControl;
+begin
+  Counter:=0;
+  for i:=0 to Control.AnchoredControlCount-1 do begin
+    Neighbour:=Control.AnchoredControls[i];
+    if Neighbour.Visible then
+    if Neighbour is TAnchorDockHostSite then
+    if (OppositeAnchor[Side] in Neighbour.Anchors)
+    and (Neighbour.AnchorSide[OppositeAnchor[Side]].Control=Control) then begin
+      inc(Counter);
+      result:=TAnchorDockHostSite(Neighbour);
+    end;
+  end;
+  if (Counter=1)and(result is TAnchorDockHostSite)and((result as TAnchorDockHostSite).FMinimized) then
+  else
+    result:=Nil;
+end;
+
 function NeighbourCanBeShrinked(EnlargeControl, Neighbour: TControl;
   Side: TAnchorKind): boolean;
 { returns true if Neighbour can be shrinked on the opposite side of Side
@@ -1361,6 +1437,13 @@
   IncreaseChangeStamp;
 end;
 
+procedure TAnchorDockSettings.SetDockSitecCanBeMinimized(AValue: boolean);
+begin
+  if FDockSitecCanBeMinimized=AValue then Exit;
+  FDockSitecCanBeMinimized:=AValue;
+  IncreaseChangeStamp;
+end;
+
 procedure TAnchorDockSettings.Assign(Source: TAnchorDockSettings);
 begin
   FAllowDragging := Source.FAllowDragging;
@@ -1381,6 +1464,7 @@
   FShowHeaderCaption := Source.FShowHeaderCaption;
   FSplitterWidth := Source.FSplitterWidth;
   FHeaderHighlightFocused:=Source.FHeaderHighlightFocused;
+  FDockSitecCanBeMinimized:=Source.FDockSitecCanBeMinimized;
 end;
 
 procedure TAnchorDockSettings.IncreaseChangeStamp;
@@ -1407,6 +1491,7 @@
   HeaderFlatten:=Config.GetValue('HeaderFlatten',true);
   HeaderFilled:=Config.GetValue('HeaderFilled',true);
   HeaderHighlightFocused:=Config.GetValue('HeaderHighlightFocused',False);
+  DockSitesCanBeMinimized:=Config.GetValue('DockSitecCanBeMinimized',False);
   Config.UndoAppendBasePath;
 end;
 
@@ -1429,6 +1514,7 @@
   Config.SetDeleteValue(Path+'HeaderFlatten',HeaderFlatten,true);
   Config.SetDeleteValue(Path+'HeaderFilled',HeaderFilled,true);
   Config.SetDeleteValue(Path+'HeaderHighlightFocused',HeaderHighlightFocused,False);
+  Config.SetDeleteValue(Path+'DockSitecCanBeMinimized',DockSitesCanBeMinimized,False);
 end;
 
 procedure TAnchorDockSettings.SaveToConfig(Config: TConfigStorage);
@@ -1450,6 +1536,7 @@
   Config.SetDeleteValue('HeaderFlatten',HeaderFlatten,true);
   Config.SetDeleteValue('HeaderFilled',HeaderFilled,true);
   Config.SetDeleteValue('HeaderHighlightFocused',HeaderHighlightFocused,False);
+  Config.SetDeleteValue('DockSitecCanBeMinimized',DockSitesCanBeMinimized,False);
   Config.UndoAppendBasePath;
 end;
 
@@ -1472,6 +1559,7 @@
       and (HeaderFlatten=Settings.HeaderFlatten)
       and (HeaderFilled=Settings.HeaderFilled)
       and (HeaderHighlightFocused=Settings.HeaderHighlightFocused)
+      and (DockSitesCanBeMinimized=Settings.DockSitesCanBeMinimized)
       ;
 end;
 
@@ -1494,6 +1582,7 @@
   HeaderFlatten:=Config.GetValue(Path+'HeaderFlatten',true);
   HeaderFilled:=Config.GetValue(Path+'HeaderFilled',true);
   HeaderHighlightFocused:=Config.GetValue(Path+'HeaderHighlightFocused',False);
+  DockSitesCanBeMinimized:=Config.GetValue(Path+'DockSitecCanBeMinimized',False);
 end;
 
 { TAnchorDockMaster }
@@ -2021,6 +2110,8 @@
     aHostSite:=TAnchorDockHostSite(Site);
     aHostSite.Header.HeaderPosition:=ANode.HeaderPosition;
     aHostSite.DockRestoreBounds:=NewBounds;
+    //aHostSite.FMinimized:=ANode.Minimized;
+    //we update aHostSite.FMinimized in TAnchorDockMaster.SetMinimizedState
     if (ANode.NodeType<>adltnPages) and (aHostSite.Pages<>nil) then
       aHostSite.FreePages;
   end;
@@ -2040,6 +2131,25 @@
   fTreeNameToDocker[Node.Name]:=Result;
 end;
 
+procedure TAnchorDockMaster.SetNodeMinimizedState(ANode: TAnchorDockLayoutTreeNode);
+var
+  HostSite:TAnchorDockHostSite;
+  i:integer;
+begin
+  HostSite:=GetNodeSite(ANode);
+  if Assigned(HostSite) then
+    if HostSite.FMinimized<>ANode.Minimized then
+      Application.QueueAsyncCall(@HostSite.AsyncMinimizeSite,0);
+      //HostSite.MinimizeSite;
+  for i:=0 to ANode.Count-1 do
+    SetnodeMinimizedState(ANode.Nodes[i]);
+end;
+
+procedure TAnchorDockMaster.SetMinimizedState(Tree: TAnchorDockLayoutTree);
+begin
+  SetnodeMinimizedState(Tree.Root);
+end;
+
 function TAnchorDockMaster.RestoreLayout(Tree: TAnchorDockLayoutTree;
   Scale: boolean): boolean;
 
@@ -2193,7 +2303,7 @@
       try
         SetupSite(Site,ANode,AParent);
         Site.FSiteType:=adhstPages;
-        Site.Header.Parent:=nil;
+        //Site.Header.Parent:=nil;
         if Site.Pages=nil then
           Site.CreatePages;
         for i:=0 to ANode.Count-1 do begin
@@ -2358,7 +2468,7 @@
       debugln(ControlNames.Text);
       {$ENDIF}
       // if some forms/controls could not be created the layout needs to be adapted
-      Tree.Root.Simplify(ControlNames);
+      Tree.Root.Simplify(ControlNames,false);
 
       // reuse existing sites to reduce flickering
       MapTreeToControls(Tree);
@@ -2368,6 +2478,7 @@
 
       // create sites, move controls
       RestoreLayout(Tree,Scale);
+      SetMinimizedState(Tree);
     finally
       EndUpdate;
     end;
@@ -2422,11 +2533,54 @@
   OptionsChanged;
 end;
 
+procedure TAnchorDockMaster.StartHideOverlappingTimer;
+begin
+  if not DockTimer.Enabled then begin
+    DockTimer.Interval:=HideOverlappingFormByMouseLoseTime;
+    DockTimer.OnTimer:=@HideOverlappingForm;
+    DockTimer.Enabled:=true;
+  end;
+end;
+
+procedure TAnchorDockMaster.StopHideOverlappingTimer;
+begin
+  DockTimer.Enabled:=False;
+  DockTimer.Interval:=0;
+  DockTimer.OnTimer:=nil;
+end;
+
+function IsParentControl(aParent, aControl: TControl): boolean;
+begin
+  while (aControl <> nil) and (aControl.Parent <> nil) do
+  begin
+    if (aControl=aParent) then
+      exit(true);
+    aControl := aControl.Parent;
+  end;
+  result:=aControl=aParent;
+end;
+
+
 procedure TAnchorDockMaster.OnIdle(Sender: TObject; var Done: Boolean);
+var
+  MousePos: TPoint;
+  Bounds:Trect;
 begin
   if Done then ;
-  IdleConnected:=false;
   Restoring:=false;
+  if FOverlappingForm=nil then
+    IdleConnected:=false
+  else begin
+    GetCursorPos(MousePos);
+    Bounds.TopLeft:=FOverlappingForm.ClientToScreen(point(0,0));
+    Bounds.BottomRight:=FOverlappingForm.ClientToScreen(point(FOverlappingForm.Width,FOverlappingForm.Height));
+    if not IsParentControl(FOverlappingForm, GetCaptureControl) then begin
+      if not PtInRect(Bounds,MousePos) then
+          StartHideOverlappingTimer
+        else
+          StopHideOverlappingTimer;
+    end;
+  end;
 end;
 
 procedure TAnchorDockMaster.AsyncSimplify(Data: PtrInt);
@@ -2514,6 +2668,24 @@
   InvalidateHeaders;
 end;
 
+procedure TAnchorDockMaster.SetDockSitesCanBeMinimized(AValue: boolean);
+var
+  i:integer;
+  Site: TAnchorDockHostSite;
+begin
+  if FDockSitesCanBeMinimized=AValue then Exit;
+  FDockSitesCanBeMinimized:=AValue;
+  for i:=0 to ComponentCount-1 do begin
+    Site:=TAnchorDockHostSite(Components[i]);
+    if not (Site is TAnchorDockHostSite) then continue;
+    if (Site.Header<>nil) then begin
+      DisableControlAutoSizing(Site);
+      Site.UpdateHeaderShowing;
+    end;
+  end;
+  EnableAllAutoSizing;
+  OptionsChanged;
+end;
 procedure TAnchorDockMaster.SetScaleOnResize(AValue: boolean);
 begin
   if FScaleOnResize=AValue then Exit;
@@ -2598,6 +2770,9 @@
     if (Site.Header<>nil) then begin
       DisableControlAutoSizing(Site);
       Site.UpdateHeaderShowing;
+      if Site.fminimized then
+        if not AValue then
+          site.MinimizeSite;
     end;
   end;
   EnableAllAutoSizing;
@@ -2668,6 +2843,20 @@
     EnableAllAutoSizing;
 end;
 
+procedure TAnchorDockMaster.ShowOverlappingForm;
+begin
+  FOverlappingForm.Show;
+  IdleConnected:=true;
+end;
+
+procedure TAnchorDockMaster.HideOverlappingForm(Sender: TObject);
+begin
+  StopHideOverlappingTimer;
+  FOverlappingForm.Hide;
+  FOverlappingForm.AnchorDockHostSite.HideMinimizedControl;
+  IdleConnected:=false;
+end;
+
 constructor TAnchorDockMaster.Create(AOwner: TComponent);
 begin
   inherited Create(AOwner);
@@ -2698,14 +2887,14 @@
   FPageClass:=TAnchorDockPage;
   FRestoreLayouts:=TAnchorDockRestoreLayouts.Create;
   FHeaderHighlightFocused:=false;
+  FDockSitesCanBeMinimized:=false;
+  FOverlappingForm:=nil;
 end;
 
 destructor TAnchorDockMaster.Destroy;
 var
   AControl: TControl;
-  {$IFDEF VerboseAnchorDocking}
-  i: Integer;
-  {$ENDIF}
+  i, j: Integer;
 begin
   QueueSimplify:=false;
   FreeAndNil(FRestoreLayouts);
@@ -2727,6 +2916,12 @@
     debugln(['TAnchorDockMaster.Destroy ',i,'/',ComponentCount,' ',DbgSName(Components[i])]);
   end;
   {$ENDIF}
+  for i:=0 to ComponentCount-1 do begin
+    for j:=0 to ComponentCount-1 do begin
+      if i<>j then
+        TControl(Components[i]).RemoveAllHandlersOfObject(TControl(Components[j]));
+  end;
+  end;
   inherited Destroy;
 end;
 
@@ -3018,7 +3213,8 @@
   i:=Screen.CustomFormCount-1;
   while i>=0 do begin
     AForm:=GetParentForm(Screen.CustomForms[i]);
-    AForm.Hide;
+    if Assigned(AForm)then
+      AForm.Hide;
     i:=Min(i,Screen.CustomFormCount)-1;
   end;
 
@@ -3062,8 +3258,11 @@
   end;
 end;
 
-function GetParentFormOrDockPanel(Control: TControl): TCustomForm;
+function GetParentFormOrDockPanel(Control: TControl; TopForm:Boolean=true): TCustomForm;
+var
+  oldControl: TControl;
 begin
+  oldControl:=Control;
   while (Control <> nil) and (Control.Parent <> nil) do
   begin
     if (Control is TAnchorDockPanel) then
@@ -3076,6 +3275,18 @@
     Result := TCustomForm(Control)
   else
     Result := nil;
+  if not TopForm then begin
+    if Control is TAnchorDockPanel then
+      exit;
+    Control:=oldControl;
+    while (Control <> nil) and (Control.Parent <> nil) do
+    begin
+      Control := Control.Parent;
+      if (Control is TCustomForm) then
+        Break;
+    end;
+    Result := TCustomForm(Control);
+  end;
 end;
 
 procedure TAnchorDockMaster.SaveMainLayoutToTree(LayoutTree: TAnchorDockLayoutTree);
@@ -3088,12 +3299,12 @@
   AFormOrDockPanel: TWinControl;
   VisibleControls: TStringList;
 
-  procedure SaveFormOrDockPanel(theFormOrDockPanel: TWinControl; SaveChildren: boolean);
+  procedure SaveFormOrDockPanel(theFormOrDockPanel: TWinControl; SaveChildren: boolean; AMinimized:boolean);
   begin
     // custom dock site
     LayoutNode:=LayoutTree.NewNode(LayoutTree.Root);
     LayoutNode.NodeType:=adltnCustomSite;
-    LayoutNode.Assign(theFormOrDockPanel,theFormOrDockPanel is TAnchorDockPanel);
+    LayoutNode.Assign(theFormOrDockPanel,theFormOrDockPanel is TAnchorDockPanel,AMinimized);
     // can have one normal dock site
     if SaveChildren then
     begin
@@ -3124,7 +3335,7 @@
       debugln(['TAnchorDockMaster.SaveMainLayoutToTree AForm=',DbgSName(AFormOrDockPanel)]);
       DebugWriteChildAnchors(AFormOrDockPanel,true,true);
       if AFormOrDockPanel is TAnchorDockPanel then begin
-        SaveFormOrDockPanel(GetParentFormOrDockPanel(AFormOrDockPanel),{false}true);
+        SaveFormOrDockPanel(GetParentFormOrDockPanel(AFormOrDockPanel),true,false);
         //LayoutNode:=LayoutTree.NewNode(LayoutTree.Root);
         //TAnchorDockPanel(AFormOrDockPanel).SaveLayout(LayoutTree,LayoutNode);
       end else if AFormOrDockPanel is TAnchorDockHostSite then begin
@@ -3132,12 +3343,12 @@
         LayoutNode:=LayoutTree.NewNode(LayoutTree.Root);
         Site.SaveLayout(LayoutTree,LayoutNode);
       end else if IsCustomSite(AFormOrDockPanel) then begin
-        SaveFormOrDockPanel(AFormOrDockPanel,true);
+        SaveFormOrDockPanel(AFormOrDockPanel,true,false);
       end else
         raise EAnchorDockLayoutError.Create('invalid root control for save: '+DbgSName(AControl));
     end;
     // remove invisible controls
-    LayoutTree.Root.Simplify(VisibleControls);
+    LayoutTree.Root.Simplify(VisibleControls,false);
   finally
     VisibleControls.Free;
     SavedSites.Free;
@@ -3157,7 +3368,7 @@
     (AControl as TAnchorDockPanel).SaveLayout(LayoutTree,LayoutTree.Root);
   end else if IsCustomSite(AControl) then begin
     LayoutTree.Root.NodeType:=adltnCustomSite;
-    LayoutTree.Root.Assign(AControl);
+    LayoutTree.Root.Assign(AControl,false,false);
     // can have one normal dock site
     Site:=TAnchorDockManager(AControl.DockManager).GetChildSite;
     if Site<>nil then begin
@@ -3252,7 +3463,7 @@
       debugln(ControlNames.Text);
       {$ENDIF}
       // if some forms/controls could not be created the layout needs to be adapted
-      Tree.Root.Simplify(ControlNames);
+      Tree.Root.Simplify(ControlNames,false);
 
       // reuse existing sites to reduce flickering
       MapTreeToControls(Tree);
@@ -3262,6 +3473,7 @@
 
       // create sites, move controls
       RestoreLayout(Tree,Scale);
+      SetMinimizedState(Tree);
     finally
       EndUpdate;
     end;
@@ -3323,6 +3535,7 @@
   HeaderFlatten                    := Settings.HeaderFlatten;
   HeaderFilled                     := Settings.HeaderFilled;
   HeaderHighlightFocused           := Settings.HeaderHighlightFocused;
+  DockSitesCanBeMinimized          := Settings.DockSitesCanBeMinimized;
 end;
 
 procedure TAnchorDockMaster.SaveSettings(Settings: TAnchorDockSettings);
@@ -3343,6 +3556,7 @@
   Settings.HeaderFlatten:=HeaderFlatten;
   Settings.HeaderFilled:=HeaderFilled;
   Settings.HeaderHighlightFocused:=HeaderHighlightFocused;
+  Settings.DockSitesCanBeMinimized:=DockSitesCanBeMinimized;
 end;
 
 function TAnchorDockMaster.SettingsAreEqual(Settings: TAnchorDockSettings
@@ -3664,6 +3878,24 @@
   LUIncreaseChangeStamp64(FOptionsChangeStamp);
 end;
 
+procedure TAnchorDockMaster.UpdateHeaders;
+var
+  i: Integer;
+  AControl: TControl;
+  AHostSite: TAnchorDockHostSite;
+begin
+    for i:=0 to ControlCount-1 do begin
+      AControl:=Controls[i];
+      if not DockedControlIsVisible(AControl) then continue;
+      while Assigned(AControl) do
+      begin
+        if AControl is TAnchorDockHostSite then
+          TAnchorDockHostSite(AControl).UpdateHeaderShowing;
+        AControl:=AControl.parent;
+      end;
+    end;
+end;
+
 { TAnchorDockHostSite }
 
 procedure TAnchorDockHostSite.SetHeaderSide(const AValue: TAnchorKind);
@@ -3680,6 +3912,7 @@
     AControl:=TControl(Sender);
     if not (csDestroying in ComponentState) then begin
       if (not AControl.Visible)
+      and (not FMinimized)
       and (not ((AControl is TAnchorDockHeader)
                or (AControl is TAnchorDockSplitter)
                or (AControl is TAnchorDockHostSite)))
@@ -4119,6 +4352,8 @@
 end;
 
 procedure TAnchorDockHostSite.FreePages;
+var
+  i:Integer;
 begin
   FreeAndNil(FPages);
 end;
@@ -4233,6 +4468,14 @@
         akRight: NewBounds.Right:=AControl.Left+AControl.Width;
         akBottom: NewBounds.Bottom:=AControl.Top+AControl.Height;
         end;
+        if (sibling is TAnchorDockHostSite) then
+        if (sibling as TAnchorDockHostSite).FMinimized then begin
+          (sibling as TAnchorDockHostSite).FMinimized:=false;
+          (sibling as TAnchorDockHostSite).FMinimizedControl.Parent:=(sibling as TAnchorDockHostSite);
+          (sibling as TAnchorDockHostSite).FMinimizedControl.Visible:=True;
+          (sibling as TAnchorDockHostSite).FMinimizedControl:=nil;
+          (sibling as TAnchorDockHostSite).UpdateHeaderAlign;
+        end;
         Sibling.BoundsRect:=NewBounds;
       end;
     end;
@@ -4306,6 +4549,13 @@
       FSiteType:=adhstOneControl;
       OnlySiteLeft.Align:=alClient;
       Header.Parent:=Self;
+      if OnlySiteLeft.FMinimized then begin
+        OnlySiteLeft.FMinimized:=false;
+        OnlySiteLeft.FMinimizedControl.Parent:=OnlySiteLeft;
+        OnlySiteLeft.FMinimizedControl.Visible:=True;
+        OnlySiteLeft.FMinimizedControl:=nil;
+        UpdateHeaderAlign;
+      end;
       UpdateHeaderAlign;
 
       //debugln(['TAnchorDockHostSite.RemoveControlFromLayout.ConvertToOneControlType AFTER CONVERT "',Caption,'" to onecontrol OnlySiteLeft="',OnlySiteLeft.Caption,'"']);
@@ -4465,7 +4715,7 @@
     debugln(['TAnchorDockHostSite.Simplify ',DbgSName(Self),' ',DbgSName(AControl)]);
     if AControl is TAnchorDockHostSite then
       SimplifyOneControl
-    else if (AControl=nil) or (csDestroying in AControl.ComponentState) then
+    else if ((AControl=nil) or (csDestroying in AControl.ComponentState)) then
       DockMaster.NeedFree(Self);
   end;
 end;
@@ -4577,7 +4827,8 @@
     Result:=Controls[i];
     if Result.Owner<>Self then exit;
   end;
-  Result:=nil;
+  result:=FMinimizedControl;
+  //Result:=nil;
 end;
 
 function TAnchorDockHostSite.GetSiteCount: integer;
@@ -5165,6 +5416,117 @@
   Result:=Check(Self);
 end;
 
+function CheckOposite(Side:TAnchorKind;var AControl: TControl;out Splitter: TAnchorDockSplitter; out SplitterAnchorKind:TAnchorKind):boolean;
+begin
+  result:=GetDockSplitter(AControl,Side,Splitter);
+  if result then begin
+    if CountAnchoredControls(Splitter,OppositeAnchor[Side])=1 then begin
+      SplitterAnchorKind:=Side;
+      exit;
+    end;
+  end;
+  result:=false
+end;
+
+function FindNearestSpliter(AControl: TControl;out Splitter: TAnchorDockSplitter;out SplitterAnchorKind:TAnchorKind):boolean;
+begin
+  result:=CheckOposite(akTop,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akRight,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akBottom,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akLeft,AControl,Splitter,SplitterAnchorKind);
+end;
+
+function TAnchorDockHostSite.CanBeMinimized(out Splitter: TAnchorDockSplitter;
+                                            out SplitterAnchorKind:TAnchorKind):boolean;
+var
+  AControl: TControl;
+  OpositeDockHostSite:TAnchorDockHostSite;
+begin
+  result:=false;
+  if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+    OpositeDockHostSite:=CountAndReturnOnlyOneMinimizedAnchoredControls(Splitter,SplitterAnchorKind);
+    if (Splitter.Enabled and (OpositeDockHostSite=nil)) then
+      result:=true;
+  end
+end;
+
+procedure TAnchorDockHostSite.MinimizeSite;
+begin
+  //Application.QueueAsyncCall(@AsyncMinimizeSite,0);
+  AsyncMinimizeSite(0);
+end;
+
+procedure TAnchorDockHostSite.AsyncMinimizeSite(Data: PtrInt);
+var
+  AControl: TControl;
+  OpositeDockHostSite:TAnchorDockHostSite;
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
+  //SpliterPercentPosition:Single;
+begin
+  fMinimization:=true;
+  debugln(['TAnchorDockHostSite.MinimizeSite ',DbgSName(Self),' SiteType=',dbgs(SiteType)]);
+  if FMinimized then
+    AControl:=FMinimizedControl
+  else
+    AControl:=GetOneControl;
+  if CanBeMinimized(Splitter,SplitterAnchorKind) or FMinimized then begin
+    FMinimized:=not FMinimized;
+    if FMinimized then begin
+      FMinimizedControl:=AControl;
+      AControl.Visible:=False;
+      AControl.Parent:=nil;
+    end else begin
+      AControl.Parent:=self;
+      AControl.Visible:=True;
+      FMinimizedControl:=nil;
+    end;
+    Splitter.Enabled:=AControl.Visible;
+    UpdateHeaderAlign;
+    dockmaster.UpdateHeaders;
+    Splitter.SetBoundsPercentually;
+  end;
+  fMinimization:=false;
+end;
+
+procedure TAnchorDockHostSite.ShowMinimizedControl;
+var
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
+  SpliterRect,OverlappingFormRect:TRect;
+begin
+  if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+    SpliterRect:=Splitter.GetSpliterBoundsWithUnminimizedDockSites;
+    OverlappingFormRect:=BoundsRect;
+    case SplitterAnchorKind of
+         akTop:OverlappingFormRect.Top:=SpliterRect.Bottom;
+        akLeft:OverlappingFormRect.Left:=SpliterRect.Right;
+       akRight:OverlappingFormRect.Right:=SpliterRect.Left;
+      akBottom:OverlappingFormRect.Bottom:=SpliterRect.Top;
+    end;
+    DockMaster.FOverlappingForm:=TAnchorDockOverlappingForm.CreateNew(self);
+    DockMaster.FOverlappingForm.BoundsRect:=OverlappingFormRect;
+    DockMaster.FOverlappingForm.Parent:=GetParentFormOrDockPanel(self,false);
+    DockMaster.FOverlappingForm.AnchorDockHostSite:=self;
+    header.Parent:=DockMaster.FOverlappingForm;
+    FMinimizedControl.Parent:=DockMaster.FOverlappingForm.Panel;
+    FMinimizedControl.Show;
+    DockMaster.ShowOverlappingForm;
+  end;
+end;
+
+procedure TAnchorDockHostSite.HideMinimizedControl;
+begin
+   FMinimizedControl.Hide;
+   header.Parent:=self;
+   header.UpdateHeaderControls;
+   FMinimizedControl.Parent:=nil;
+   FreeAndNil(DockMaster.FOverlappingForm);
+end;
+
 function TAnchorDockHostSite.CloseSite: boolean;
 var
   AControl: TControl;
@@ -5281,21 +5643,24 @@
 begin
   if csDestroying in ComponentState then exit;
   NewCaption:='';
-  for i:=0 to ControlCount-1 do begin
-    Child:=Controls[i];
-    if Child=Exclude then continue;
-    if (Child.HostDockSite=Self) or (Child is TAnchorDockHostSite)
-    or (Child is TAnchorDockPageControl) then begin
-      if NewCaption<>'' then
-        NewCaption:=NewCaption+',';
-      NewCaption:=NewCaption+Child.Caption;
+  if FMinimized then
+    NewCaption:=FMinimizedControl.Caption
+  else
+    for i:=0 to ControlCount-1 do begin
+      Child:=Controls[i];
+      if Child=Exclude then continue;
+      if (Child.HostDockSite=Self) or (Child is TAnchorDockHostSite)
+      or (Child is TAnchorDockPageControl) then begin
+        if NewCaption<>'' then
+          NewCaption:=NewCaption+',';
+        NewCaption:=NewCaption+Child.Caption;
+      end;
     end;
-  end;
   OldCaption:=Caption;
   Caption:=NewCaption;
   //debugln(['TAnchorDockHostSite.UpdateDockCaption Caption="',Caption,'" NewCaption="',NewCaption,'" HasParent=',Parent<>nil,' ',DbgSName(Header)]);
-  if ((Parent=nil) and DockMaster.HideHeaderCaptionFloatingControl)
-  or (not DockMaster.ShowHeaderCaption) then
+  if {((Parent=nil) and DockMaster.HideHeaderCaptionFloatingControl)
+  or (not DockMaster.ShowHeaderCaption)}false then
     Header.Caption:=''
   else
     Header.Caption:=Caption;
@@ -5306,9 +5671,8 @@
     if Parent is TAnchorDockPage then
       TAnchorDockPage(Parent).UpdateDockCaption;
   end;
-
   // do not show close button for mainform
-  Header.CloseButton.Visible:=not IsParentOf(Application.MainForm);
+  Header.CloseButton.Visible:=(not IsParentOf(Application.MainForm));
 end;
 
 procedure TAnchorDockHostSite.GetSiteInfo(Client: TControl;
@@ -5339,7 +5703,8 @@
   end;
 
   CanDock:=(Client is TAnchorDockHostSite)
-           and not DockMaster.AutoFreedIfControlIsRemoved(Self,Client);
+           and not DockMaster.AutoFreedIfControlIsRemoved(Self,Client)
+           and not FMinimized;
   //debugln(['TAnchorDockHostSite.GetSiteInfo ',DbgSName(Self),' ',dbgs(BoundsRect),' ',Caption,' CanDock=',CanDock,' PtIn=',PtInRect(InfluenceRect,MousePos)]);
 
   if Assigned(OnGetSiteInfo) then
@@ -5362,9 +5727,33 @@
 end;
 
 procedure TAnchorDockHostSite.UpdateHeaderAlign;
+const
+OppositeAlign: array[TAnchorKind] of TAlign = (
+  alBottom, // akTop,
+  alRight,  // akLeft,
+  alLeft,   // akRight,
+  alTop     // akBottom
+  );
+OppositeAnchorKindAlign: array[TAnchorKind] of TADLHeaderPosition = (
+  adlhpBottom, // akTop,
+  adlhpRight,  // akLeft,
+  adlhpLeft,   // akRight,
+  adlhpTop     // akBottom
+  );
+var
+  NeededHeaderPosition:TADLHeaderPosition;
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
 begin
   if Header=nil then exit;
-  case Header.HeaderPosition of
+  if FMinimized then begin
+    if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+      NeededHeaderPosition:=OppositeAnchorKindAlign[SplitterAnchorKind];
+    end else
+      NeededHeaderPosition:=Header.HeaderPosition;
+  end else
+    NeededHeaderPosition:=Header.HeaderPosition;
+  case NeededHeaderPosition of
   adlhpAuto:
     if Header.Align in [alLeft,alRight] then begin
       if (ClientHeight>0)
@@ -5388,10 +5777,16 @@
 end;
 
 procedure TAnchorDockHostSite.UpdateHeaderShowing;
+var
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
 begin
   if Header=nil then exit;
-  if HeaderNeedsShowing then
-    Header.Parent:=Self
+  if HeaderNeedsShowing then begin
+    Header.Parent:=Self;
+    Header.MinimizeButton.Visible:=(DockMaster.DockSitesCanBeMinimized and CanBeMinimized(Splitter,SplitterAnchorKind))or FMinimized;
+    Header.MinimizeButton.Parent:=Header;
+  end
   else
     Header.Parent:=nil;
 end;
@@ -5432,7 +5827,7 @@
   if (SiteType=adhstOneControl) and (OneControl<>nil)
   and (not (OneControl is TAnchorDockHostSite)) then begin
     LayoutNode.NodeType:=adltnControl;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,FMinimized);
     LayoutNode.Name:=OneControl.Name;
     LayoutNode.HeaderPosition:=Header.HeaderPosition;
   end else if (SiteType in [adhstLayout,adhstOneControl]) then begin
@@ -5450,7 +5845,7 @@
         Splitter.SaveLayout(ChildNode);
       end;
     end;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,FMinimized);
     LayoutNode.HeaderPosition:=Header.HeaderPosition;
   end else if SiteType=adhstPages then begin
     LayoutNode.NodeType:=adltnPages;
@@ -5461,7 +5856,7 @@
         Site.SaveLayout(LayoutTree,ChildNode);
       end;
     end;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,FMinimized);
     LayoutNode.HeaderPosition:=Header.HeaderPosition;
   end else
     LayoutNode.NodeType:=adltnNone;
@@ -5476,6 +5871,9 @@
 constructor TAnchorDockHostSite.CreateNew(AOwner: TComponent; Num: Integer);
 begin
   inherited CreateNew(AOwner,Num);
+  FMinimized:=false;
+  fMinimization:=false;
+  FMinimizedControl:=Nil;
   Visible:=false;
   FHeaderSide:=akTop;
   FHeader:=DockMaster.HeaderClass.Create(Self);
@@ -5490,13 +5888,13 @@
 end;
 
 destructor TAnchorDockHostSite.Destroy;
-//var i: Integer;
+var i: Integer;
 begin
-  //debugln(['TAnchorDockHostSite.Destroy ',DbgSName(Self),' Caption="',Caption,'" Self=',dbgs(Pointer(Self)),' ComponentCount=',ComponentCount,' ControlCount=',ControlCount]);
-  {for i:=0 to ComponentCount-1 do
+  debugln(['TAnchorDockHostSite.Destroy ',DbgSName(Self),' Caption="',Caption,'" Self=',dbgs(Pointer(Self)),' ComponentCount=',ComponentCount,' ControlCount=',ControlCount]);
+  for i:=0 to ComponentCount-1 do
     debugln(['TAnchorDockHostSite.Destroy Component ',i,'/',ComponentCount,' ',DbgSName(Components[i])]);
   for i:=0 to ControlCount-1 do
-    debugln(['TAnchorDockHostSite.Destroy Control ',i,'/',ControlCount,' ',DbgSName(Controls[i])]);}
+    debugln(['TAnchorDockHostSite.Destroy Control ',i,'/',ControlCount,' ',DbgSName(Controls[i])]);
   FreePages;
   inherited Destroy;
 end;
@@ -5562,13 +5960,34 @@
 end;
 
 procedure TAnchorDockHeader.CloseButtonClick(Sender: TObject);
+var
+  HeaderParent:TAnchorDockHostSite;
 begin
-  if Parent is TAnchorDockHostSite then begin
-    DockMaster.RestoreLayouts.Add(DockMaster.CreateRestoreLayout(Parent),true);
-    TAnchorDockHostSite(Parent).CloseSite;
+  TWinControl(HeaderParent):=Parent;
+  if HeaderParent=TWinControl(DockMaster.FOverlappingForm) then begin
+    HeaderParent:=DockMaster.FOverlappingForm.AnchorDockHostSite;
+    HeaderParent.HideMinimizedControl;
   end;
+  if HeaderParent is TAnchorDockHostSite then begin
+    DockMaster.RestoreLayouts.Add(DockMaster.CreateRestoreLayout(HeaderParent),true);
+    HeaderParent.CloseSite;
+  end;
 end;
 
+procedure TAnchorDockHeader.MinimizeButtonClick(Sender: TObject);
+var
+  HeaderParent:TAnchorDockHostSite;
+begin
+  TWinControl(HeaderParent):=Parent;
+  if HeaderParent=TWinControl(DockMaster.FOverlappingForm) then begin
+    HeaderParent:=DockMaster.FOverlappingForm.AnchorDockHostSite;
+    HeaderParent.HideMinimizedControl;
+  end;
+  if HeaderParent is TAnchorDockHostSite then begin
+    HeaderParent.MinimizeSite;
+  end;
+end;
+
 procedure TAnchorDockHeader.HeaderPositionItemClick(Sender: TObject);
 var
   Item: TMenuItem;
@@ -5640,6 +6059,13 @@
       r.Right:=CloseButton.Left-1;
   end;
 
+  if MinimizeButton.IsControlVisible and (MinimizeButton.Parent=Self) then begin
+    if Align in [alLeft,alRight] then
+      r.Top:=MinimizeButton.Top+MinimizeButton.Height+1
+    else
+      r.Right:=MinimizeButton.Left-1;
+  end;
+
   // caption
   if Caption<>'' then begin
     if fFocused and DockMaster.HeaderHighlightFocused and NeedHighlightText then
@@ -5728,25 +6154,102 @@
     end else begin
       PreferredHeight:=Max(NeededHeight,PreferredHeight);
     end;
+  end else begin
+    NeededHeight:=CloseButton.Height;
+    if Align in [alLeft,alRight] then begin
+      PreferredWidth:=Max(NeededHeight,PreferredWidth);
+    end else begin
+      PreferredHeight:=Max(NeededHeight,PreferredHeight);
   end;
+  end;
 end;
 
 procedure TAnchorDockHeader.MouseDown(Button: TMouseButton; Shift: TShiftState;
   X, Y: Integer);
+var
+  SiteMinimized:Boolean;
 begin
   inherited MouseDown(Button, Shift, X, Y);
-  if (Button=mbLeft) and DockMaster.AllowDragging then
-    DragManager.DragStart(Parent,false,DockMaster.DragTreshold);
+  SiteMinimized:=False;
+  fUseTimer:=false;
+  StopMouseNoMoveTimer;
+  if Parent is TAnchorDockHostSite then
+    SiteMinimized:=(Parent as TAnchorDockHostSite).FMinimized;
+  if SiteMinimized then begin
+    DoMouseNoMoveTimer(nil);
+  end else
+    begin
+      if parent<>nil then
+        if DockMaster.FOverlappingForm<>nil then
+          //if parent=DockMaster.FOverlappingForm.Panel then
+            DockMaster.HideOverlappingForm(nil);
+      if (Button=mbLeft) and (DockMaster.AllowDragging) and (DockMaster.FOverlappingForm=nil) then
+        DragManager.DragStart(Parent,false,DockMaster.DragTreshold);
+    end;
 end;
 
+procedure  TAnchorDockHeader.MouseMove(Shift: TShiftState; X,Y: Integer);
+begin
+  inherited MouseMove(Shift, X, Y);
+  if parent<>nil then
+    if parent is TAnchorDockHostSite then
+      if (parent as TAnchorDockHostSite).FMinimized then
+        if DockMaster.FOverlappingForm=nil then
+          if FMouseTimeStartX=EmptyMouseTimeStartX then
+            StartMouseNoMoveTimer(X, Y)
+          else begin
+            if (abs(FMouseTimeStartX-X)>MouseNoMoveDelta)or(abs(FMouseTimeStartY-Y)>MouseNoMoveDelta)then
+            StopMouseNoMoveTimer;
+          end;
+  if (parent is TAnchorDockHostSite)and(DockMaster.FOverlappingForm=nil)then
+    fUseTimer:=true;
+end;
+
+procedure TAnchorDockHeader.MouseLeave;
+begin
+  inherited;
+  StopMouseNoMoveTimer;
+end;
+
+procedure TAnchorDockHeader.StartMouseNoMoveTimer(X, Y: Integer);
+begin
+  if fUseTimer then begin
+    if DockTimer.Enabled then DockTimer.Enabled:=false;
+    DockTimer.Interval:=MouseNoMoveTime;
+    DockTimer.OnTimer:=@DoMouseNoMoveTimer;
+    DockTimer.Enabled:=true;
+  end;
+end;
+
+procedure TAnchorDockHeader.StopMouseNoMoveTimer;
+begin
+  FMouseTimeStartX:=EmptyMouseTimeStartX;
+  DockTimer.OnTimer:=nil;
+  DockTimer.Enabled:=false;
+end;
+
+procedure TAnchorDockHeader.DoMouseNoMoveTimer(Sender: TObject);
+begin
+  StopMouseNoMoveTimer;
+  //if fUseTimer then
+    if parent<>nil then
+      if parent is TAnchorDockHostSite then
+        if (parent as TAnchorDockHostSite).FMinimized then
+          (parent as TAnchorDockHostSite).ShowMinimizedControl;
+end;
+
 procedure TAnchorDockHeader.UpdateHeaderControls;
 begin
   if Align in [alLeft,alRight] then begin
-    if CloseButton<>nil then
+    if CloseButton<>nil then begin
+      MinimizeButton.Align:=alTop;
       CloseButton.Align:=alTop;
+    end;
   end else begin
-    if CloseButton<>nil then
+    if CloseButton<>nil then begin
+      MinimizeButton.Align:=alRight;
       CloseButton.Align:=alRight;
+    end;
   end;
   //debugln(['TAnchorDockHeader.UpdateHeaderControls ',dbgs(Align),' ',dbgs(CloseButton.Align)]);
 end;
@@ -5787,9 +6290,9 @@
 begin
   inherited Create(TheOwner);
   FHeaderPosition:=adlhpAuto;
-  FCloseButton:=TAnchorDockCloseButton.Create(Self);
   BevelOuter:=bvNone;
   BorderWidth:=0;
+  FCloseButton:=TAnchorDockCloseButton.Create(Self);
   with FCloseButton do begin
     Name:='CloseButton';
     Parent:=Self;
@@ -5799,11 +6302,23 @@
     OnClick:=@CloseButtonClick;
     AutoSize:=true;
   end;
+  FMinimizeButton:=TAnchorDockMinimizeButton.Create(Self);
+  with FMinimizeButton do begin
+    Name:='MinimizeButton';
+    Parent:=Self;
+    Flat:=true;
+    ShowHint:=true;
+    Hint:=adrsMinimize;
+    OnClick:=@MinimizeButtonClick;
+    AutoSize:=true;
+  end;
   Align:=alTop;
   AutoSize:=true;
   ShowHint:=true;
   PopupMenu:=DockMaster.GetPopupMenu;
   fFocused:=false;
+  FMouseTimeStartX:=EmptyMouseTimeStartX;
+  fUseTimer:=true;
 end;
 
 { TAnchorDockCloseButton }
@@ -5844,6 +6359,44 @@
   end;
 end;
 
+{ TAnchorDockMinimizeButton }
+
+function TAnchorDockMinimizeButton.GetDrawDetails: TThemedElementDetails;
+
+function WindowPart: TThemedWindow;
+  begin
+    // no check states available
+    Result := twMinButtonNormal;
+    if not IsEnabled then
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonDisabled{$ELSE}twMinButtonDisabled{$ENDIF}
+    else
+    if FState in [bsDown, bsExclusive] then
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonPushed{$ELSE}twMinButtonPushed{$ENDIF}
+    else
+    if FState = bsHot then
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonHot{$ELSE}twMinButtonHot{$ENDIF}
+    else
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonNormal{$ELSE}twMinButtonNormal{$ENDIF};
+  end;
+
+begin
+  Result := ThemeServices.GetElementDetails(WindowPart);
+end;
+
+procedure TAnchorDockMinimizeButton.CalculatePreferredSize(var PreferredWidth,
+  PreferredHeight: integer; WithThemeSpace: Boolean);
+begin
+  with ThemeServices.GetDetailSize(ThemeServices.GetElementDetails({$IFDEF LCLGtk2}twMDIRestoreButtonNormal{$ELSE}twMinButtonNormal{$ENDIF})) do
+  begin
+    PreferredWidth:=cx;
+    PreferredHeight:=cy;
+    {$IF defined(LCLGtk2) or defined(Carbon)}
+    inc(PreferredWidth,2);
+    inc(PreferredHeight,2);
+    {$ENDIF}
+  end;
+end;
+
 { TAnchorDockManager }
 
 procedure TAnchorDockManager.SetPreferredSiteSizeAsSiteMinimum(
@@ -6213,6 +6766,9 @@
   ClientRectChanged:=(WidthDiff<>0) or (HeightDiff<>0);
   if ClientRectChanged or PreferredSiteSizeAsSiteMinimum then
     AlignChilds;
+  if ClientRectChanged then
+    if DockMaster.FOverlappingForm<>nil then
+      DockMaster.HideOverlappingForm(nil);
 end;
 
 procedure TAnchorDockManager.SaveToStream(Stream: TStream);
@@ -6505,32 +7061,58 @@
 procedure TAnchorDockSplitter.SetBoundsPercentually;
 var
   NewLeft, NewTop: Integer;
+  AControl: TControl;
+  SplitterAnchorKind:TAnchorKind;
 begin
-  if ResizeAnchor in [akLeft,akRight] then
-  begin
-    if DockParentClientSize.cx> 0 then
+  if Enabled then begin
+    if ResizeAnchor in [akLeft,akRight] then
     begin
-      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
-        NewLeft := Round(FPercentPosition*Parent.ClientWidth)
-      else
-        NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
-      NewTop := Top;
-      SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      if DockParentClientSize.cx> 0 then
+      begin
+        if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+          NewLeft := Round(FPercentPosition*Parent.ClientWidth)
+        else
+          NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
+        NewTop := Top;
+        SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      end;
+    end else
+    begin
+      if DockParentClientSize.cy> 0 then
+      begin
+        NewLeft := Left;
+        if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+          NewTop := Round(FPercentPosition*Parent.ClientHeight)
+        else
+          NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+        SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      end;
     end;
-  end else
-  begin
-    if DockParentClientSize.cy> 0 then
-    begin
-      NewLeft := Left;
-      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
-        NewTop := Round(FPercentPosition*Parent.ClientHeight)
-      else
-        NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+    if FPercentPosition < 0 then
+      UpdatePercentPosition;
+  end else begin
+    SplitterAnchorKind:=akTop;
+    AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);
+    if AControl=nil then begin SplitterAnchorKind:=akRight;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+    if AControl=nil then begin SplitterAnchorKind:=akBottom;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+    if AControl=nil then begin SplitterAnchorKind:=akLeft;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+
+    if AControl is TAnchorDockHostSite then begin
+      (AControl as TAnchorDockHostSite).UpdateHeaderAlign;
+      NewTop := (AControl as TAnchorDockHostSite).Header.Left;
+      NewTop := (AControl as TAnchorDockHostSite).Header.Height;
+      NewLeft := left;
+      NewTop := top;
+      (AControl as TAnchorDockHostSite).UpdateHeaderAlign;
+      case SplitterAnchorKind of
+        akTop: NewTop := AControl.Top+(AControl as TAnchorDockHostSite).Header.Height;
+        akBottom: NewTop := AControl.Top+AControl.Height-(AControl as TAnchorDockHostSite).Header.Height-Height;
+        akLeft: NewLeft := AControl.Left+(AControl as TAnchorDockHostSite).Header.Width;
+        akRight: NewLeft := AControl.Left+AControl.Width-(AControl as TAnchorDockHostSite).Header.Width-Width;
+      end;
       SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
     end;
   end;
-  if FPercentPosition < 0 then
-    UpdatePercentPosition;
 end;
 
 function TAnchorDockSplitter.SideAnchoredControlCount(Side: TAnchorKind): integer;
@@ -6560,14 +7142,47 @@
   end;
 end;
 
+function TAnchorDockSplitter.GetSpliterBoundsWithUnminimizedDockSites:TRect;
+var
+  NewLeft, NewTop: Integer;
+begin
+  if ResizeAnchor in [akLeft,akRight] then
+  begin
+    if DockParentClientSize.cx> 0 then
+    begin
+      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+        NewLeft := Round(FPercentPosition*Parent.ClientWidth)
+      else
+        NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
+      NewTop := Top;
+    end;
+  end else
+  begin
+    if DockParentClientSize.cy> 0 then
+    begin
+      NewLeft := Left;
+      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+        NewTop := Round(FPercentPosition*Parent.ClientHeight)
+      else
+        NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+    end;
+  end;
+  result:=Rect(NewLeft,NewTop,NewLeft+Width,NewTop+Height);
+end;
+
 procedure TAnchorDockSplitter.SaveLayout(
   LayoutNode: TAnchorDockLayoutTreeNode);
+var
+  NewLeft, NewTop: Integer;
 begin
   if ResizeAnchor in [akLeft,akRight] then
     LayoutNode.NodeType:=adltnSplitterVertical
   else
     LayoutNode.NodeType:=adltnSplitterHorizontal;
-  LayoutNode.Assign(Self);
+  LayoutNode.Assign(Self,false,false);
+  if not Enabled then begin
+    LayoutNode.BoundsRect:=GetSpliterBoundsWithUnminimizedDockSites;
+  end
 end;
 
 function TAnchorDockSplitter.HasOnlyOneSibling(Side: TAnchorKind; MinPos,
@@ -6645,7 +7260,7 @@
 begin
   inherited MouseDown(Button, Shift, X, Y);
   ATabIndex := IndexOfPageAt(X, Y);
-  if (Button = mbLeft) and DockMaster.AllowDragging and (ATabIndex >= 0) then
+  if (Button = mbLeft) and DockMaster.AllowDragging and (ATabIndex >= 0) and (DockMaster.FOverlappingForm=nil) then
   begin
     APage:=Page[ATabIndex];
     if (APage.ControlCount>0) and (APage.Controls[0] is TAnchorDockHostSite) then
@@ -6782,6 +7397,20 @@
   PopupMenu:=DockMaster.GetPopupMenu;
 end;
 
+{ TAnchorDockOverlappingForm }
+
+constructor TAnchorDockOverlappingForm.CreateNew(AOwner: TComponent; Num: Integer = 0);
+begin
+  inherited;
+  BorderStyle:=bsNone;
+  AnchorDockHostSite:=nil;
+  Panel:=TPanel.Create(self);
+  Panel.BorderStyle:=bsSingle;
+  Panel.Align:=alClient;
+  Panel.Parent:=self;
+  Panel.Visible:=true;
+end;
+
 { TAnchorDockPage }
 
 procedure TAnchorDockPage.UpdateDockCaption(Exclude: TControl);
@@ -6835,9 +7464,11 @@
 
 initialization
   DockMaster:=TAnchorDockMaster.Create(nil);
+  DockTimer:=TTimer.Create(nil);
 
 finalization
   FreeAndNil(DockMaster);
+  FreeAndNil(DockTimer);
 
 end.
 
Index: components/anchordocking/anchordockoptionsdlg.lfm
===================================================================
--- components/anchordocking/anchordockoptionsdlg.lfm	(revision 59428)
+++ components/anchordocking/anchordockoptionsdlg.lfm	(working copy)
@@ -1,11 +1,13 @@
 object AnchorDockOptionsFrame: TAnchorDockOptionsFrame
   Left = 0
-  Height = 482
+  Height = 567
   Top = 0
-  Width = 416
-  ClientHeight = 482
-  ClientWidth = 416
+  Width = 490
+  ClientHeight = 567
+  ClientWidth = 490
+  DesignTimePPI = 113
   OnClick = FrameClick
+  ParentFont = False
   TabOrder = 0
   DesignLeft = 513
   DesignTop = 189
@@ -12,14 +14,15 @@
   object DragThresholdLabel: TLabel
     AnchorSideLeft.Control = Owner
     AnchorSideTop.Control = Owner
-    Left = 10
-    Height = 13
-    Top = 10
-    Width = 111
-    BorderSpacing.Left = 10
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 12
+    Width = 122
+    BorderSpacing.Left = 12
+    BorderSpacing.Top = 12
     Caption = 'DragThresholdLabel'
     ParentColor = False
+    ParentFont = False
   end
   object DragThresholdTrackBar: TTrackBar
     AnchorSideLeft.Control = DragThresholdLabel
@@ -27,15 +30,16 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = Owner
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 46
-    Top = 23
-    Width = 396
+    Left = 12
+    Height = 54
+    Top = 31
+    Width = 466
     Max = 20
     OnChange = DragThresholdTrackBarChange
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Right = 10
+    BorderSpacing.Right = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 1
@@ -46,12 +50,13 @@
     AnchorSideTop.Control = DragThresholdLabel
     AnchorSideTop.Side = asrCenter
     AnchorSideRight.Control = Owner
-    Left = 127
-    Height = 23
-    Top = 5
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 141
+    Height = 27
+    Top = 8
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 20
+    ParentFont = False
     TabOrder = 0
     Visible = False
   end
@@ -59,13 +64,14 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = DragThresholdTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 79
-    Width = 103
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 97
+    Width = 112
+    BorderSpacing.Top = 12
     Caption = 'SplitterWidthLabel'
     ParentColor = False
+    ParentFont = False
   end
   object SplitterWidthTrackBar: TTrackBar
     AnchorSideLeft.Control = DragThresholdTrackBar
@@ -73,14 +79,15 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 46
-    Top = 92
-    Width = 396
+    Left = 12
+    Height = 54
+    Top = 116
+    Width = 466
     Min = 1
     OnChange = SplitterWidthTrackBarChange
     Position = 1
     Anchors = [akTop, akLeft, akRight]
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 3
@@ -89,12 +96,13 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = SplitterWidthTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 24
-    Top = 142
-    Width = 160
-    BorderSpacing.Top = 4
+    Left = 12
+    Height = 23
+    Top = 175
+    Width = 169
+    BorderSpacing.Top = 5
     Caption = 'ScaleOnResizeCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 4
@@ -103,12 +111,13 @@
     AnchorSideLeft.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 24
-    Top = 166
-    Width = 149
+    Left = 12
+    Height = 23
+    Top = 198
+    Width = 160
     Caption = 'ShowHeaderCheckBox'
     OnChange = ShowHeaderCheckBoxChange
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 5
@@ -117,12 +126,13 @@
     AnchorSideLeft.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Control = ShowHeaderCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 190
-    Width = 191
-    BorderSpacing.Left = 15
+    Left = 30
+    Height = 23
+    Top = 221
+    Width = 208
+    BorderSpacing.Left = 18
     Caption = 'ShowHeaderCaptionCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 6
@@ -131,11 +141,12 @@
     AnchorSideLeft.Control = ShowHeaderCaptionCheckBox
     AnchorSideTop.Control = ShowHeaderCaptionCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 214
-    Width = 249
+    Left = 30
+    Height = 23
+    Top = 244
+    Width = 272
     Caption = 'HideHeaderCaptionForFloatingCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 7
@@ -147,15 +158,16 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = Owner
     AnchorSideRight.Side = asrBottom
-    Left = 122
+    Left = 136
     Height = 27
-    Top = 286
-    Width = 284
+    Top = 313
+    Width = 342
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 6
-    BorderSpacing.Right = 10
-    ItemHeight = 0
+    BorderSpacing.Left = 7
+    BorderSpacing.Right = 12
+    ItemHeight = 19
     OnDrawItem = HeaderStyleComboBoxDrawItem
+    ParentFont = False
     Style = csDropDownList
     TabOrder = 10
   end
@@ -163,23 +175,25 @@
     AnchorSideLeft.Control = ShowHeaderCheckBox
     AnchorSideTop.Control = HeaderStyleComboBox
     AnchorSideTop.Side = asrCenter
-    Left = 20
-    Height = 13
-    Top = 293
-    Width = 96
-    BorderSpacing.Left = 10
+    Left = 24
+    Height = 19
+    Top = 317
+    Width = 105
+    BorderSpacing.Left = 12
     Caption = 'HeaderStyleLabel'
     ParentColor = False
+    ParentFont = False
   end
   object FlattenHeadersCheckBox: TCheckBox
     AnchorSideLeft.Control = HideHeaderCaptionForFloatingCheckBox
     AnchorSideTop.Control = HideHeaderCaptionForFloatingCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 238
-    Width = 164
+    Left = 30
+    Height = 23
+    Top = 267
+    Width = 175
     Caption = 'FlattenHeadersCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 8
@@ -188,11 +202,12 @@
     AnchorSideLeft.Control = FlattenHeadersCheckBox
     AnchorSideTop.Control = FlattenHeadersCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 262
-    Width = 154
+    Left = 30
+    Height = 23
+    Top = 290
+    Width = 164
     Caption = 'FilledHeadersCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 9
@@ -201,11 +216,12 @@
     AnchorSideLeft.Control = FilledHeadersCheckBox
     AnchorSideTop.Control = HeaderStyleComboBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 313
-    Width = 175
+    Left = 30
+    Height = 23
+    Top = 340
+    Width = 189
     Caption = 'HighlightFocusedCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 11
@@ -215,13 +231,14 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = SplitterWidthLabel
     AnchorSideTop.Side = asrCenter
-    Left = 119
-    Height = 23
-    Top = 74
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 131
+    Height = 27
+    Top = 93
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 10
     MinValue = 1
+    ParentFont = False
     TabOrder = 2
     Value = 1
     Visible = False
@@ -228,15 +245,16 @@
   end
   object HeaderAlignTopLabel: TLabel
     AnchorSideLeft.Control = DragThresholdLabel
-    AnchorSideTop.Control = HighlightFocusedCheckBox
+    AnchorSideTop.Control = DockSitesCanBeMinimized
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 347
-    Width = 117
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 398
+    Width = 130
+    BorderSpacing.Top = 12
     Caption = 'HeaderAlignTopLabel'
     ParentColor = False
+    ParentFont = False
   end
   object HeaderAlignTopTrackBar: TTrackBar
     AnchorSideLeft.Control = Owner
@@ -244,10 +262,10 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 47
-    Top = 360
-    Width = 396
+    Left = 12
+    Height = 55
+    Top = 417
+    Width = 466
     Frequency = 10
     Max = 150
     OnChange = HeaderAlignTopTrackBarChange
@@ -254,7 +272,8 @@
     PageSize = 10
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 10
+    BorderSpacing.Left = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 13
@@ -264,12 +283,13 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = HeaderAlignTopLabel
     AnchorSideTop.Side = asrCenter
-    Left = 133
-    Height = 23
-    Top = 342
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 149
+    Height = 27
+    Top = 394
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 150
+    ParentFont = False
     TabOrder = 12
     Visible = False
   end
@@ -277,13 +297,14 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = HeaderAlignTopTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 417
-    Width = 120
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 484
+    Width = 130
+    BorderSpacing.Top = 12
     Caption = 'HeaderAlignLeftLabel'
     ParentColor = False
+    ParentFont = False
   end
   object HeaderAlignLeftTrackBar: TTrackBar
     AnchorSideLeft.Control = Owner
@@ -291,10 +312,10 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 47
-    Top = 430
-    Width = 396
+    Left = 12
+    Height = 55
+    Top = 503
+    Width = 466
     Frequency = 10
     Max = 200
     OnChange = HeaderAlignLeftTrackBarChange
@@ -301,7 +322,8 @@
     PageSize = 10
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 10
+    BorderSpacing.Left = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 15
@@ -311,13 +333,28 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = HeaderAlignLeftLabel
     AnchorSideTop.Side = asrCenter
-    Left = 136
-    Height = 23
-    Top = 412
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 149
+    Height = 27
+    Top = 480
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 200
+    ParentFont = False
     TabOrder = 14
     Visible = False
   end
+  object DockSitesCanBeMinimized: TCheckBox
+    AnchorSideLeft.Control = FilledHeadersCheckBox
+    AnchorSideTop.Control = HighlightFocusedCheckBox
+    AnchorSideTop.Side = asrBottom
+    Left = 30
+    Height = 23
+    Top = 363
+    Width = 185
+    Caption = 'DockSitesCanBeMinimized'
+    ParentFont = False
+    ParentShowHint = False
+    ShowHint = True
+    TabOrder = 16
+  end
 end
Index: components/anchordocking/anchordockoptionsdlg.pas
===================================================================
--- components/anchordocking/anchordockoptionsdlg.pas	(revision 59428)
+++ components/anchordocking/anchordockoptionsdlg.pas	(working copy)
@@ -37,6 +37,7 @@
     HeaderStyleLabel: TLabel;
     HideHeaderCaptionForFloatingCheckBox: TCheckBox;
     HighlightFocusedCheckBox: TCheckBox;
+    DockSitesCanBeMinimized: TCheckBox;
     ScaleOnResizeCheckBox: TCheckBox;
     ShowHeaderCaptionCheckBox: TCheckBox;
     ShowHeaderCheckBox: TCheckBox;
@@ -202,7 +203,7 @@
 
       HeaderAlignTopSpinEdit.Visible:=true;
       HeaderAlignTopTrackBar.Visible:=false;
-      HeaderAlignTopSpinEdit.AnchorToNeighbour(akTop,6,HighlightFocusedCheckBox);
+      HeaderAlignTopSpinEdit.AnchorToNeighbour(akTop,6,DockSitesCanBeMinimized);
       HeaderAlignTopLabel.AnchorVerticalCenterTo(HeaderAlignTopSpinEdit);
       UpdateHeaderAlignTopLabel;
 
@@ -299,6 +300,7 @@
   HeaderStyleLabel.Enabled:=HasHeaders;
   HeaderStyleComboBox.Enabled:=HasHeaders;
   HighlightFocusedCheckBox.Enabled:=HasHeaders;
+  DockSitesCanBeMinimized.Enabled:=HasHeaders;
 end;
 
 constructor TAnchorDockOptionsFrame.Create(TheOwner: TComponent);
@@ -356,6 +358,7 @@
   TheSettings.HeaderFilled:=FilledHeadersCheckBox.Checked;
   TheSettings.HeaderStyle:=TADHeaderStyle(HeaderStyleComboBox.ItemIndex);
   TheSettings.HeaderHighlightFocused:=HighlightFocusedCheckBox.Checked;
+  TheSettings.DockSitesCanBeMinimized:=DockSitesCanBeMinimized.Checked;
 end;
 
 procedure TAnchorDockOptionsFrame.LoadFromSettings(
@@ -429,6 +432,10 @@
   HighlightFocusedCheckBox.Checked:=TheSettings.HeaderHighlightFocused;
   HighlightFocusedCheckBox.Caption:=adrsHighlightFocused;
   HighlightFocusedCheckBox.Hint:=adrsHighlightFocusedHint;
+
+  DockSitesCanBeMinimized.Checked:=TheSettings.DockSitesCanBeMinimized;
+  DockSitesCanBeMinimized.Caption:=adrsDockSitesCanBeMinimized;
+  DockSitesCanBeMinimized.Hint:=adrsDockSitesCanBeMinimizedHint;
 end;
 
 end.
Index: components/anchordocking/anchordockpanel.pas
===================================================================
--- components/anchordocking/anchordockpanel.pas	(revision 59428)
+++ components/anchordocking/anchordockpanel.pas	(working copy)
@@ -55,7 +55,7 @@
   begin
 
     LayoutNode.NodeType:=adltnControl;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,false);
     LayoutNode.Name:={OneControl.}Name;
 
     TAnchorDockHostSite(OneControl).SaveLayout(LayoutTree,LayoutNode);
Index: components/anchordocking/anchordockstorage.pas
===================================================================
--- components/anchordocking/anchordockstorage.pas	(revision 59428)
+++ components/anchordocking/anchordockstorage.pas	(working copy)
@@ -64,6 +64,7 @@
     FTabPosition: TTabPosition;
     FWindowState: TWindowState;
     FControlLocation: TADLControlLocation;
+    FMinimized: Boolean;
     function GetAnchors(Site: TAnchorKind): string;
     function GetBottom: integer;
     function GetHeight: integer;
@@ -90,6 +91,7 @@
     procedure SetTop(const AValue: integer);
     procedure SetWidth(const AValue: integer);
     procedure SetWindowState(const AValue: TWindowState);
+    procedure SetMinimized(const AValue: boolean);
   public
     constructor Create;
     destructor Destroy; override;
@@ -96,7 +98,7 @@
     procedure Clear;
     function IsEqual(Node: TAnchorDockLayoutTreeNode): boolean;
     procedure Assign(Node: TAnchorDockLayoutTreeNode); overload;
-    procedure Assign(AControl: TControl; OverrideBoundsRect: Boolean=false); overload;
+    procedure Assign(AControl: TControl; OverrideBoundsRect: Boolean; AMinimized: Boolean); overload;
     procedure LoadFromConfig(Config: TConfigStorage); overload;
     procedure LoadFromConfig(Path: string; Config: TRttiXMLConfig); overload;
     procedure SaveToConfig(Config: TConfigStorage); overload;
@@ -106,7 +108,7 @@
     procedure CheckConsistency; virtual;
 
     // simplifying
-    procedure Simplify(ExistingNames: TStrings);
+    procedure Simplify(ExistingNames: TStrings; ParentMinimized:boolean);
     procedure DeleteNode(ChildNode: TAnchorDockLayoutTreeNode);
     function FindNodeBoundSplitter(ChildNode: TAnchorDockLayoutTreeNode;
                                    Side: TAnchorKind): TAnchorDockLayoutTreeNode;
@@ -135,6 +137,7 @@
     property Monitor: integer read FMonitor write SetMonitor;
     property HeaderPosition: TADLHeaderPosition read FHeaderPosition write SetHeaderPosition;
     property TabPosition: TTabPosition read FTabPosition write SetTabPosition;
+    property Minimized: Boolean read FMinimized write SetMinimized;
     function Count: integer;
     function IsSplitter: boolean;
     function IsRootWindow: boolean;
@@ -988,6 +991,13 @@
   IncreaseChangeStamp;
 end;
 
+procedure TAnchorDockLayoutTreeNode.SetMinimized(const AValue: boolean);
+begin
+  if FMinimized=AValue then exit;
+  FMinimized:=AValue;
+  IncreaseChangeStamp;
+end;
+
 procedure TAnchorDockLayoutTreeNode.SetTop(const AValue: integer);
 begin
   if Top=AValue then exit;
@@ -1084,6 +1094,7 @@
   BoundSplitterPos:=Node.BoundSplitterPos;
   WorkAreaRect:=Node.WorkAreaRect;
   Monitor:=Node.Monitor;
+  Minimized:=Node.Minimized;
   for a:=low(TAnchorKind) to high(TAnchorKind) do
     Anchors[a]:=Node.Anchors[a];
   while Count>Node.Count do Nodes[Count-1].Free;
@@ -1098,9 +1109,10 @@
   end;
 end;
 
-procedure TAnchorDockLayoutTreeNode.Assign(AControl: TControl; OverrideBoundsRect: Boolean=false);
+procedure TAnchorDockLayoutTreeNode.Assign(AControl: TControl; OverrideBoundsRect: Boolean; AMinimized: Boolean);
 var
   AnchorControl: TControl;
+  ParentForm:TCustomForm;
   a: TAnchorKind;
 begin
   Name:=AControl.Name;
@@ -1109,12 +1121,18 @@
   else
     BoundsRect:=AControl.BoundsRect;
   Align:=AControl.Align;
+  Minimized:=AMinimized;
   if (AControl.Parent=nil) and (AControl is TCustomForm) then begin
     WindowState:=TCustomForm(AControl).WindowState;
     Monitor:=TCustomForm(AControl).Monitor.MonitorNum;
     WorkAreaRect:=TCustomForm(AControl).Monitor.WorkareaRect;
-  end else
-    WindowState:=GetParentForm(AControl).WindowState;
+  end else begin
+    ParentForm:=GetParentForm(AControl);
+    if assigned(ParentForm) then
+      WindowState:=ParentForm.WindowState
+    else
+      WindowState:=wsNormal;
+  end;
   if AControl is TCustomTabControl then
     TabPosition:=TCustomTabControl(AControl).TabPosition
   else
@@ -1137,6 +1155,7 @@
   Clear;
   Name:=Config.GetValue('Name','');
   NodeType:=NameToADLTreeNodeType(Config.GetValue('Type',ADLTreeNodeTypeNames[adltnNone]));
+  Minimized:=Config.GetValue('Minimized',false);
   Left:=Config.GetValue('Bounds/Left',0);
   Top:=Config.GetValue('Bounds/Top',0);
   Width:=Config.GetValue('Bounds/Width',0);
@@ -1171,6 +1190,7 @@
   Clear;
   Name:=Config.GetValue(Path+'Name','');
   NodeType:=NameToADLTreeNodeType(Config.GetValue(Path+'Type',ADLTreeNodeTypeNames[adltnNone]));
+  Minimized:=Config.GetValue(Path+'Minimized',false);
   Left:=Config.GetValue(Path+'Bounds/Left',0);
   Top:=Config.GetValue(Path+'Bounds/Top',0);
   Width:=Config.GetValue(Path+'Bounds/Width',0);
@@ -1219,6 +1239,7 @@
                                           ADLHeaderPositionNames[adlhpAuto]);
   Config.SetDeleteValue('Header/TabPosition',ADLTabPostionNames[TabPosition],
                                              ADLTabPostionNames[tpTop]);
+  Config.SetDeleteValue('Minimized',Minimized,False);
   Config.SetDeleteValue('Monitor',Monitor,0);
   Config.SetDeleteValue('ChildCount',Count,0);
   for i:=1 to Count do begin
@@ -1252,6 +1273,7 @@
                                                ADLHeaderPositionNames[adlhpAuto]);
   Config.SetDeleteValue(Path+'Header/TabPosition',ADLTabPostionNames[TabPosition],
                                                   ADLTabPostionNames[tpTop]);
+  Config.SetDeleteValue(Path+'Minimized',Minimized,False);
   Config.SetDeleteValue(Path+'Monitor',Monitor,0);
   Config.SetDeleteValue(Path+'ChildCount',Count,0);
   for i:=1 to Count do
@@ -1397,7 +1419,7 @@
   end;
 end;
 
-procedure TAnchorDockLayoutTreeNode.Simplify(ExistingNames: TStrings);
+procedure TAnchorDockLayoutTreeNode.Simplify(ExistingNames: TStrings; ParentMinimized:boolean);
 { Simplification rules:
    1. Control nodes without existing name are deleted.
    2. Empty layouts and pages are deleted
@@ -1406,16 +1428,18 @@
 var
   i: Integer;
   ChildNode: TAnchorDockLayoutTreeNode;
+  NodeMinimized:boolean;
 begin
   // simplify children
   i:=Count-1;
   while i>=0 do begin
     ChildNode:=Nodes[i];
-    ChildNode.Simplify(ExistingNames);
+    NodeMinimized:=ParentMinimized or ChildNode.Minimized;
+    ChildNode.Simplify(ExistingNames,NodeMinimized);
 
     if (ChildNode.NodeType=adltnControl) then begin
       // leaf node => check if there is a control
-      if (ChildNode.Name='') or (ExistingNames.IndexOf(ChildNode.Name)<0) then
+      if (ChildNode.Name='') or ((ExistingNames.IndexOf(ChildNode.Name)<0) and (not NodeMinimized)) then
         DeleteNode(ChildNode);
     end else if ChildNode.IsSplitter then begin
       // splitter
@@ -1424,7 +1448,7 @@
         ChildNode[0].Free;
     end else if ChildNode.NodeType=adltnCustomSite then begin
       // custom dock site
-    end else if ChildNode.Count=0 then begin
+    end else if (ChildNode.Count=0)and(not NodeMinimized) then begin
       // inner node without child => delete
       DeleteNode(ChildNode);
     end else if (ChildNode.Count=1)
Index: components/anchordocking/anchordockstr.pas
===================================================================
--- components/anchordocking/anchordockstr.pas	(revision 59428)
+++ components/anchordocking/anchordockstr.pas	(working copy)
@@ -8,6 +8,7 @@
 
 resourcestring
   adrsClose = 'Close';
+  adrsMinimize = 'Minimize';
   adrsQuit = 'Quit %s';
   adrsTabPosition = 'Tab position';
   adrsMovePageRight = 'Move page right';
@@ -82,6 +83,8 @@
   adrsFilledHeadersHint = 'Fill headers of docked controls';
   adrsHighlightFocused = 'Highlight focused';
   adrsHighlightFocusedHint = 'Highlight header of focused docked control';
+  adrsDockSitesCanBeMinimized = 'Dock sites can be minimized';
+  adrsDockSitesCanBeMinimizedHint = 'Dock sites can be minimized';
 
 implementation
 
Index: components/anchordocking/design/anchordesktopoptions.pas
===================================================================
--- components/anchordocking/design/anchordesktopoptions.pas	(revision 59428)
+++ components/anchordocking/design/anchordesktopoptions.pas	(working copy)
@@ -272,7 +272,7 @@
         // custom dock site
         LayoutNode:=FTree.NewNode(FTree.Root);
         LayoutNode.NodeType:=adltnCustomSite;
-        LayoutNode.Assign(AForm);
+        LayoutNode.Assign(AForm,false,false);
         // can have one normal dock site
         Site:=TAnchorDockManager(AForm.DockManager).GetChildSite;
         if Site<>nil then begin
@@ -287,7 +287,7 @@
         raise EAnchorDockLayoutError.Create('invalid root control for save: '+DbgSName(AControl));
     end;
     // remove invisible controls
-    FTree.Root.Simplify(VisibleControls);
+    FTree.Root.Simplify(VisibleControls,false);
   finally
     VisibleControls.Free;
     SavedSites.Free;

Andrey Zubarev

2018-11-12 00:12

reporter   ~0111917

anchordocking_minimize_docksite9.patch

1,2,3,4,5,7 - fixed, please test
6 - please give layout for components\anchordocking\minide\ example, and screenshot how to do for crash

Michl

2018-11-12 21:01

developer  

test.xml (1,379 bytes)   
<?xml version="1.0" encoding="utf-8"?>
<CONFIG>
  <MainConfig>
    <Nodes ChildCount="2">
      <Item1 Name="MainIDE" Type="CustomSite" ChildCount="1">
        <Bounds Top="50" Left="100" Width="600" Height="434">
          <WorkArea>
            <Rect Right="1920" Bottom="1036"/>
          </WorkArea>
        </Bounds>
        <Item1 Name="AnchorDockSite3" Type="Layout" ChildCount="3">
          <Bounds Top="60" Width="600" Height="350" SplitterPos="55"/>
          <Anchors Align="Bottom"/>
          <Item1 Name="ObjectInspector" Type="Control">
            <Bounds Width="296" Height="350"/>
            <Anchors Right="AnchorDockSplitter2"/>
          </Item1>
          <Item2 Name="AnchorDockSplitter2" Type="SplitterVertical">
            <Bounds Left="296" Width="4" Height="350"/>
          </Item2>
          <Item3 Name="SourceEditor1" Type="Control">
            <Bounds Left="300" Width="300" Height="350"/>
            <Anchors Left="AnchorDockSplitter2"/>
          </Item3>
        </Item1>
      </Item1>
      <Item2 Name="Messages" Type="Control">
        <Bounds Top="548" Left="208" Width="350" Height="100">
          <WorkArea>
            <Rect Right="1920" Bottom="1036"/>
          </WorkArea>
        </Bounds>
      </Item2>
    </Nodes>
  </MainConfig>
  <Settings DockSitecCanBeMinimized="True"/>
</CONFIG>
test.xml (1,379 bytes)   

Michl

2018-11-12 21:12

developer  

test.png (2,968 bytes)   
test.png (2,968 bytes)   

Michl

2018-11-12 21:14

developer   ~0111942

Last edited: 2018-11-12 21:31

View 3 revisions

1. For issue 6, see test.xml:
- after loading of layout, minimize Source Editor 1
- dock messages after (right) of minimized Source Editor 1
- Splitter between Object Inspector and Source Editor 1 get lost

2. If you do this, there you can see a new bug. The minimize button of Object Inspector is lost. This always happens, when a form is docked to a new place.

3. The size of the minimize button and therefore the size of the header is wrong calculated. It is nearly the double size. See test.png: Left: wrong size (Source Editor 1); Right: correct size (Messages)

4. In MiniIDE:
- load layout test.xml
- dock Messages right of Source Editor 1
- minimize Source Editor 1
- maximize Source Editor 1
- minimize Messages
- maximize Messages
- see the minimize button and close button changed (see test2.png)

Michl

2018-11-12 21:25

developer  

Test2.png (2,820 bytes)   
Test2.png (2,820 bytes)   

Andrey Zubarev

2018-11-12 23:11

reporter   ~0111945

1 - maybe unminimize all sites if user start drag site?

Michl

2018-11-13 07:21

developer   ~0111946

Imagine as user, you have some minimized sites left, right and on the bottom. Now you dock a site on the right and all your minimized sites are unminimized. For user it would be annyoing when his layout is changed this way. If it is possible, I wouldn't do it.

Andrey Zubarev

2018-11-14 21:16

reporter  

anchordocking_minimize_docksite10.patch (77,237 bytes)   
Index: components/anchordocking/anchordocking.pas
===================================================================
--- components/anchordocking/anchordocking.pas	(revision 59428)
+++ components/anchordocking/anchordocking.pas	(working copy)
@@ -109,6 +109,12 @@
 const ADAutoSizingReason = 'TAnchorDockMaster Delayed';
 {$ENDIF}
 
+const EmptyMouseTimeStartX=low(Integer);
+      MouseNoMoveDelta=5;
+      MouseNoMoveTime=500;
+      HideOverlappingFormByMouseLoseTime=500;
+      ButtonBorderSpacingAround=4;
+
 type
   TAnchorDockHostSite = class;
 
@@ -123,6 +129,14 @@
            PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
   end;
 
+  TAnchorDockMinimizeButton = class(TCustomSpeedButton)
+  protected
+    function GetDrawDetails: TThemedElementDetails; override;
+    procedure CalculatePreferredSize(var PreferredWidth,
+           PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
+  end;
+
+
   { TAnchorDockHeader
     The panel of a TAnchorDockHostSite containing the close button and the
     caption when the form is docked. The header can be shown at any of the four
@@ -133,9 +147,13 @@
   TAnchorDockHeader = class(TCustomPanel)
   private
     FCloseButton: TCustomSpeedButton;
+    FMinimizeButton: TCustomSpeedButton;
     FHeaderPosition: TADLHeaderPosition;
     fFocused:Boolean;
+    fUseTimer:Boolean;
+    FMouseTimeStartX,FMouseTimeStartY:Integer;
     procedure CloseButtonClick(Sender: TObject);
+    procedure MinimizeButtonClick(Sender: TObject);
     procedure HeaderPositionItemClick(Sender: TObject);
     procedure UndockButtonClick(Sender: TObject);
     procedure MergeButtonClick(Sender: TObject);
@@ -147,6 +165,11 @@
           PreferredHeight: integer; WithThemeSpace: Boolean); override;
     procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X,
              Y: Integer); override;
+    procedure MouseMove(Shift: TShiftState; X,Y: Integer); override;
+    procedure MouseLeave;  override;
+    procedure StartMouseNoMoveTimer(X, Y: Integer);
+    procedure StopMouseNoMoveTimer;
+    procedure DoMouseNoMoveTimer(Sender: TObject);
     procedure UpdateHeaderControls;
     procedure SetAlign(Value: TAlign); override;
     procedure DoOnShowHint(HintInfo: PHintInfo); override;
@@ -154,6 +177,7 @@
   public
     constructor Create(TheOwner: TComponent); override;
     property CloseButton: TCustomSpeedButton read FCloseButton;
+    property MinimizeButton: TCustomSpeedButton read FMinimizeButton;
     property HeaderPosition: TADLHeaderPosition read FHeaderPosition write SetHeaderPosition;
     property BevelOuter default bvNone;
   end;
@@ -190,6 +214,7 @@
     procedure SetBoundsKeepDockBounds(ALeft, ATop, AWidth, AHeight: integer); // movement for scaling keeps the DockBounds
     function SideAnchoredControlCount(Side: TAnchorKind): integer;
     function HasAnchoredControls: boolean;
+    function GetSpliterBoundsWithUnminimizedDockSites:TRect;
     procedure SaveLayout(LayoutNode: TAnchorDockLayoutTreeNode);
     function HasOnlyOneSibling(Side: TAnchorKind; MinPos, MaxPos: integer): TControl;
     property DockRestoreBounds: TRect read FDockRestoreBounds write FDockRestoreBounds;
@@ -241,6 +266,14 @@
   end;
   TAnchorDockPageControlClass = class of TAnchorDockPageControl;
 
+
+  TAnchorDockOverlappingForm = class(TCustomForm)
+  public
+    AnchorDockHostSite:TAnchorDockHostSite;
+    Panel:TPanel;
+    constructor CreateNew(AOwner: TComponent; Num: Integer = 0); override;
+  end;
+
   { TAnchorDockHostSite
     This form is the dockhostsite for all controls.
     When docked together they build a tree structure with the docked controls
@@ -262,7 +295,10 @@
     FPages: TAnchorDockPageControl;
     FSiteType: TAnchorDockHostSiteType;
     FBoundSplitter: TAnchorDockSplitter;
-    fUpdateLayout: integer;
+    fUpdateLayout: Integer;
+    FMinimized: Boolean;
+    fMinimization: Boolean;
+    FMinimizedControl: TControl;
     procedure SetHeaderSide(const AValue: TAnchorKind);
   protected
     procedure DoEnter; override;
@@ -319,6 +355,10 @@
     destructor Destroy; override;
     function CloseQuery: boolean; override;
     function CloseSite: boolean; virtual;
+    procedure MinimizeSite; virtual;
+    procedure AsyncMinimizeSite(Data: PtrInt);
+    procedure ShowMinimizedControl;
+    procedure HideMinimizedControl;
     procedure RemoveControl(AControl: TControl); override;
     procedure InsertControl(AControl: TControl; Index: integer); override;
     procedure GetSiteInfo(Client: TControl; var InfluenceRect: TRect;
@@ -329,6 +369,7 @@
     procedure UpdateDockCaption(Exclude: TControl = nil); override;
     procedure UpdateHeaderAlign;
     procedure UpdateHeaderShowing;
+    function CanBeMinimized(out Splitter: TAnchorDockSplitter; out SplitterAnchorKind:TAnchorKind):boolean;
     procedure BeginUpdateLayout;
     procedure EndUpdateLayout;
     function UpdatingLayout: boolean;
@@ -431,6 +472,7 @@
     FShowHeader: boolean;
     FShowHeaderCaption: boolean;
     FSplitterWidth: integer;
+    FDockSitecCanBeMinimized: boolean;
     procedure SetAllowDragging(AValue: boolean);
     procedure SetDockOutsideMargin(AValue: integer);
     procedure SetDockParentMargin(AValue: integer);
@@ -448,6 +490,7 @@
     procedure SetHeaderFlatten(AValue: boolean);
     procedure SetHeaderFilled(AValue: boolean);
     procedure SetHeaderHighlightFocused(AValue: boolean);
+    procedure SetDockSitecCanBeMinimized(AValue: boolean);
   public
     property DragTreshold: integer read FDragTreshold write SetDragTreshold;
     property DockOutsideMargin: integer read FDockOutsideMargin write SetDockOutsideMargin;
@@ -466,6 +509,7 @@
     property HeaderFlatten: boolean read FHeaderFlatten write SetHeaderFlatten;
     property HeaderFilled: boolean read FHeaderFilled write SetHeaderFilled;
     property HeaderHighlightFocused: boolean read FHeaderHighlightFocused write SetHeaderHighlightFocused;
+    property DockSitesCanBeMinimized: boolean read FDockSitecCanBeMinimized write SetDockSitecCanBeMinimized;
     procedure IncreaseChangeStamp; inline;
     property ChangeStamp: integer read FChangeStamp;
     procedure LoadFromConfig(Config: TConfigStorage); overload;
@@ -502,6 +546,7 @@
     FHeaderFlatten: boolean;
     FHeaderFilled: boolean;
     FHeaderHighlightFocused: boolean;
+    FDockSitesCanBeMinimized: boolean;
     FIdleConnected: Boolean;
     FManagerClass: TAnchorDockManagerClass;
     FOnCreateControl: TADCreateControlEvent;
@@ -531,6 +576,7 @@
     fPopupMenu: TPopupMenu;
     // Used by RestoreLayout:
     WorkArea, SrcWorkArea: TRect;
+    FOverlappingForm:TAnchorDockOverlappingForm;
 
     function GetControls(Index: integer): TControl;
     function GetLocalizedHeaderHint: string;
@@ -541,6 +587,9 @@
     function GetNodeSite(Node: TAnchorDockLayoutTreeNode): TAnchorDockHostSite;
     procedure MapTreeToControls(Tree: TAnchorDockLayoutTree);
     function RestoreLayout(Tree: TAnchorDockLayoutTree; Scale: boolean): boolean;
+    procedure SetMinimizedState(Tree: TAnchorDockLayoutTree);
+    procedure UpdateHeaders;
+    procedure SetnodeMinimizedState(ANode: TAnchorDockLayoutTreeNode);
     procedure EnableAllAutoSizing;
     procedure ClearLayoutProperties(AControl: TControl; NewAlign: TAlign = alClient);
     procedure PopupMenuPopup(Sender: TObject);
@@ -561,6 +610,7 @@
     procedure SetHeaderFlatten(AValue: boolean);
     procedure SetHeaderFilled(AValue: boolean);
     procedure SetHeaderHighlightFocused(AValue: boolean);
+    procedure SetDockSitesCanBeMinimized(AValue: boolean);
 
     procedure SetShowMenuItemShowHeader(AValue: boolean);
     procedure SetupSite(Site: TWinControl; ANode: TAnchorDockLayoutTreeNode;
@@ -584,8 +634,12 @@
     procedure SetHideHeaderCaptionFloatingControl(const AValue: boolean);
     procedure SetSplitterWidth(const AValue: integer);
     procedure OnIdle(Sender: TObject; var Done: Boolean);
+    procedure StartHideOverlappingTimer;
+    procedure StopHideOverlappingTimer;
     procedure AsyncSimplify({%H-}Data: PtrInt);
   public
+    procedure ShowOverlappingForm;
+    procedure HideOverlappingForm(Sender: TObject);
     constructor Create(AOwner: TComponent); override;
     destructor Destroy; override;
     function FullRestoreLayout(Tree: TAnchorDockLayoutTree; Scale: Boolean): Boolean;
@@ -680,6 +734,7 @@
     property HeaderFlatten: boolean read FHeaderFlatten write SetHeaderFlatten default true;
     property HeaderFilled: boolean read FHeaderFilled write SetHeaderFilled default true;
     property HeaderHighlightFocused: boolean read FHeaderHighlightFocused write SetHeaderHighlightFocused default false;
+    property DockSitesCanBeMinimized: boolean read FDockSitesCanBeMinimized write SetDockSitesCanBeMinimized default false;
 
     property SplitterWidth: integer read FSplitterWidth write SetSplitterWidth default 4;
     property ScaleOnResize: boolean read FScaleOnResize write SetScaleOnResize default true; // scale children when resizing a site
@@ -698,8 +753,14 @@
 
 var
   DockMaster: TAnchorDockMaster = nil;
+  DockTimer: TTimer = nil;
 
+  PreferredButtonWidth:integer=-1;
+  PreferredButtonHeight:integer=-1;
+
+
 const
+  HardcodedButtonSize:integer=13;
   ADHeaderStyleNames: array[TADHeaderStyle] of string = (
     'Frame3D',
     'Line',
@@ -970,6 +1031,27 @@
   end;
 end;
 
+function CountAndReturnOnlyOneMinimizedAnchoredControls(Control: TControl; Side: TAnchorKind): TAnchorDockHostSite;
+var
+  i,Counter: Integer;
+  Neighbour: TControl;
+begin
+  Counter:=0;
+  for i:=0 to Control.AnchoredControlCount-1 do begin
+    Neighbour:=Control.AnchoredControls[i];
+    if Neighbour.Visible then
+    if Neighbour is TAnchorDockHostSite then
+    if (OppositeAnchor[Side] in Neighbour.Anchors)
+    and (Neighbour.AnchorSide[OppositeAnchor[Side]].Control=Control) then begin
+      inc(Counter);
+      result:=TAnchorDockHostSite(Neighbour);
+    end;
+  end;
+  if (Counter=1)and(result is TAnchorDockHostSite)and((result as TAnchorDockHostSite).FMinimized) then
+  else
+    result:=Nil;
+end;
+
 function NeighbourCanBeShrinked(EnlargeControl, Neighbour: TControl;
   Side: TAnchorKind): boolean;
 { returns true if Neighbour can be shrinked on the opposite side of Side
@@ -1361,6 +1443,13 @@
   IncreaseChangeStamp;
 end;
 
+procedure TAnchorDockSettings.SetDockSitecCanBeMinimized(AValue: boolean);
+begin
+  if FDockSitecCanBeMinimized=AValue then Exit;
+  FDockSitecCanBeMinimized:=AValue;
+  IncreaseChangeStamp;
+end;
+
 procedure TAnchorDockSettings.Assign(Source: TAnchorDockSettings);
 begin
   FAllowDragging := Source.FAllowDragging;
@@ -1381,6 +1470,7 @@
   FShowHeaderCaption := Source.FShowHeaderCaption;
   FSplitterWidth := Source.FSplitterWidth;
   FHeaderHighlightFocused:=Source.FHeaderHighlightFocused;
+  FDockSitecCanBeMinimized:=Source.FDockSitecCanBeMinimized;
 end;
 
 procedure TAnchorDockSettings.IncreaseChangeStamp;
@@ -1407,6 +1497,7 @@
   HeaderFlatten:=Config.GetValue('HeaderFlatten',true);
   HeaderFilled:=Config.GetValue('HeaderFilled',true);
   HeaderHighlightFocused:=Config.GetValue('HeaderHighlightFocused',False);
+  DockSitesCanBeMinimized:=Config.GetValue('DockSitecCanBeMinimized',False);
   Config.UndoAppendBasePath;
 end;
 
@@ -1429,6 +1520,7 @@
   Config.SetDeleteValue(Path+'HeaderFlatten',HeaderFlatten,true);
   Config.SetDeleteValue(Path+'HeaderFilled',HeaderFilled,true);
   Config.SetDeleteValue(Path+'HeaderHighlightFocused',HeaderHighlightFocused,False);
+  Config.SetDeleteValue(Path+'DockSitecCanBeMinimized',DockSitesCanBeMinimized,False);
 end;
 
 procedure TAnchorDockSettings.SaveToConfig(Config: TConfigStorage);
@@ -1450,6 +1542,7 @@
   Config.SetDeleteValue('HeaderFlatten',HeaderFlatten,true);
   Config.SetDeleteValue('HeaderFilled',HeaderFilled,true);
   Config.SetDeleteValue('HeaderHighlightFocused',HeaderHighlightFocused,False);
+  Config.SetDeleteValue('DockSitecCanBeMinimized',DockSitesCanBeMinimized,False);
   Config.UndoAppendBasePath;
 end;
 
@@ -1472,6 +1565,7 @@
       and (HeaderFlatten=Settings.HeaderFlatten)
       and (HeaderFilled=Settings.HeaderFilled)
       and (HeaderHighlightFocused=Settings.HeaderHighlightFocused)
+      and (DockSitesCanBeMinimized=Settings.DockSitesCanBeMinimized)
       ;
 end;
 
@@ -1494,6 +1588,7 @@
   HeaderFlatten:=Config.GetValue(Path+'HeaderFlatten',true);
   HeaderFilled:=Config.GetValue(Path+'HeaderFilled',true);
   HeaderHighlightFocused:=Config.GetValue(Path+'HeaderHighlightFocused',False);
+  DockSitesCanBeMinimized:=Config.GetValue(Path+'DockSitecCanBeMinimized',False);
 end;
 
 { TAnchorDockMaster }
@@ -2021,6 +2116,8 @@
     aHostSite:=TAnchorDockHostSite(Site);
     aHostSite.Header.HeaderPosition:=ANode.HeaderPosition;
     aHostSite.DockRestoreBounds:=NewBounds;
+    //aHostSite.FMinimized:=ANode.Minimized;
+    //we update aHostSite.FMinimized in TAnchorDockMaster.SetMinimizedState
     if (ANode.NodeType<>adltnPages) and (aHostSite.Pages<>nil) then
       aHostSite.FreePages;
   end;
@@ -2040,6 +2137,25 @@
   fTreeNameToDocker[Node.Name]:=Result;
 end;
 
+procedure TAnchorDockMaster.SetNodeMinimizedState(ANode: TAnchorDockLayoutTreeNode);
+var
+  HostSite:TAnchorDockHostSite;
+  i:integer;
+begin
+  HostSite:=GetNodeSite(ANode);
+  if Assigned(HostSite) then
+    if HostSite.FMinimized<>ANode.Minimized then
+      Application.QueueAsyncCall(@HostSite.AsyncMinimizeSite,0);
+      //HostSite.MinimizeSite;
+  for i:=0 to ANode.Count-1 do
+    SetnodeMinimizedState(ANode.Nodes[i]);
+end;
+
+procedure TAnchorDockMaster.SetMinimizedState(Tree: TAnchorDockLayoutTree);
+begin
+  SetnodeMinimizedState(Tree.Root);
+end;
+
 function TAnchorDockMaster.RestoreLayout(Tree: TAnchorDockLayoutTree;
   Scale: boolean): boolean;
 
@@ -2193,7 +2309,7 @@
       try
         SetupSite(Site,ANode,AParent);
         Site.FSiteType:=adhstPages;
-        Site.Header.Parent:=nil;
+        //Site.Header.Parent:=nil;
         if Site.Pages=nil then
           Site.CreatePages;
         for i:=0 to ANode.Count-1 do begin
@@ -2358,7 +2474,7 @@
       debugln(ControlNames.Text);
       {$ENDIF}
       // if some forms/controls could not be created the layout needs to be adapted
-      Tree.Root.Simplify(ControlNames);
+      Tree.Root.Simplify(ControlNames,false);
 
       // reuse existing sites to reduce flickering
       MapTreeToControls(Tree);
@@ -2368,6 +2484,7 @@
 
       // create sites, move controls
       RestoreLayout(Tree,Scale);
+      SetMinimizedState(Tree);
     finally
       EndUpdate;
     end;
@@ -2422,11 +2539,54 @@
   OptionsChanged;
 end;
 
+procedure TAnchorDockMaster.StartHideOverlappingTimer;
+begin
+  if not DockTimer.Enabled then begin
+    DockTimer.Interval:=HideOverlappingFormByMouseLoseTime;
+    DockTimer.OnTimer:=@HideOverlappingForm;
+    DockTimer.Enabled:=true;
+  end;
+end;
+
+procedure TAnchorDockMaster.StopHideOverlappingTimer;
+begin
+  DockTimer.Enabled:=False;
+  DockTimer.Interval:=0;
+  DockTimer.OnTimer:=nil;
+end;
+
+function IsParentControl(aParent, aControl: TControl): boolean;
+begin
+  while (aControl <> nil) and (aControl.Parent <> nil) do
+  begin
+    if (aControl=aParent) then
+      exit(true);
+    aControl := aControl.Parent;
+  end;
+  result:=aControl=aParent;
+end;
+
+
 procedure TAnchorDockMaster.OnIdle(Sender: TObject; var Done: Boolean);
+var
+  MousePos: TPoint;
+  Bounds:Trect;
 begin
   if Done then ;
-  IdleConnected:=false;
   Restoring:=false;
+  if FOverlappingForm=nil then
+    IdleConnected:=false
+  else begin
+    GetCursorPos(MousePos);
+    Bounds.TopLeft:=FOverlappingForm.ClientToScreen(point(0,0));
+    Bounds.BottomRight:=FOverlappingForm.ClientToScreen(point(FOverlappingForm.Width,FOverlappingForm.Height));
+    if not IsParentControl(FOverlappingForm, GetCaptureControl) then begin
+      if not PtInRect(Bounds,MousePos) then
+          StartHideOverlappingTimer
+        else
+          StopHideOverlappingTimer;
+    end;
+  end;
 end;
 
 procedure TAnchorDockMaster.AsyncSimplify(Data: PtrInt);
@@ -2514,6 +2674,18 @@
   InvalidateHeaders;
 end;
 
+procedure TAnchorDockMaster.SetDockSitesCanBeMinimized(AValue: boolean);
+var
+  i:integer;
+  Site: TAnchorDockHostSite;
+begin
+  if FDockSitesCanBeMinimized=AValue then Exit;
+  FDockSitesCanBeMinimized:=AValue;
+  UpdateHeaders;
+  InvalidateHeaders;
+  EnableAllAutoSizing;
+  OptionsChanged;
+end;
 procedure TAnchorDockMaster.SetScaleOnResize(AValue: boolean);
 begin
   if FScaleOnResize=AValue then Exit;
@@ -2598,6 +2770,9 @@
     if (Site.Header<>nil) then begin
       DisableControlAutoSizing(Site);
       Site.UpdateHeaderShowing;
+      if Site.fminimized then
+        if not AValue then
+          site.MinimizeSite;
     end;
   end;
   EnableAllAutoSizing;
@@ -2668,6 +2843,20 @@
     EnableAllAutoSizing;
 end;
 
+procedure TAnchorDockMaster.ShowOverlappingForm;
+begin
+  FOverlappingForm.Show;
+  IdleConnected:=true;
+end;
+
+procedure TAnchorDockMaster.HideOverlappingForm(Sender: TObject);
+begin
+  StopHideOverlappingTimer;
+  FOverlappingForm.Hide;
+  FOverlappingForm.AnchorDockHostSite.HideMinimizedControl;
+  IdleConnected:=false;
+end;
+
 constructor TAnchorDockMaster.Create(AOwner: TComponent);
 begin
   inherited Create(AOwner);
@@ -2698,14 +2887,14 @@
   FPageClass:=TAnchorDockPage;
   FRestoreLayouts:=TAnchorDockRestoreLayouts.Create;
   FHeaderHighlightFocused:=false;
+  FDockSitesCanBeMinimized:=false;
+  FOverlappingForm:=nil;
 end;
 
 destructor TAnchorDockMaster.Destroy;
 var
   AControl: TControl;
-  {$IFDEF VerboseAnchorDocking}
-  i: Integer;
-  {$ENDIF}
+  i, j: Integer;
 begin
   QueueSimplify:=false;
   FreeAndNil(FRestoreLayouts);
@@ -2727,6 +2916,12 @@
     debugln(['TAnchorDockMaster.Destroy ',i,'/',ComponentCount,' ',DbgSName(Components[i])]);
   end;
   {$ENDIF}
+  for i:=0 to ComponentCount-1 do begin
+    for j:=0 to ComponentCount-1 do begin
+      if i<>j then
+        TControl(Components[i]).RemoveAllHandlersOfObject(TControl(Components[j]));
+  end;
+  end;
   inherited Destroy;
 end;
 
@@ -2914,6 +3109,7 @@
       raise Exception.Create('TAnchorDockMaster.MakeDockable '+Format(
         adrsNotSupportedHasParent, [DbgSName(AControl), DbgSName(AControl)]));
     end;
+    site.UpdateHeaderShowing;
     if (Site<>nil) and Show then
       MakeVisible(Site,BringToFront);
   finally
@@ -3018,7 +3214,8 @@
   i:=Screen.CustomFormCount-1;
   while i>=0 do begin
     AForm:=GetParentForm(Screen.CustomForms[i]);
-    AForm.Hide;
+    if Assigned(AForm)then
+      AForm.Hide;
     i:=Min(i,Screen.CustomFormCount)-1;
   end;
 
@@ -3062,8 +3259,11 @@
   end;
 end;
 
-function GetParentFormOrDockPanel(Control: TControl): TCustomForm;
+function GetParentFormOrDockPanel(Control: TControl; TopForm:Boolean=true): TCustomForm;
+var
+  oldControl: TControl;
 begin
+  oldControl:=Control;
   while (Control <> nil) and (Control.Parent <> nil) do
   begin
     if (Control is TAnchorDockPanel) then
@@ -3076,6 +3276,18 @@
     Result := TCustomForm(Control)
   else
     Result := nil;
+  if not TopForm then begin
+    if Control is TAnchorDockPanel then
+      exit;
+    Control:=oldControl;
+    while (Control <> nil) and (Control.Parent <> nil) do
+    begin
+      Control := Control.Parent;
+      if (Control is TCustomForm) then
+        Break;
+    end;
+    Result := TCustomForm(Control);
+  end;
 end;
 
 procedure TAnchorDockMaster.SaveMainLayoutToTree(LayoutTree: TAnchorDockLayoutTree);
@@ -3088,12 +3300,12 @@
   AFormOrDockPanel: TWinControl;
   VisibleControls: TStringList;
 
-  procedure SaveFormOrDockPanel(theFormOrDockPanel: TWinControl; SaveChildren: boolean);
+  procedure SaveFormOrDockPanel(theFormOrDockPanel: TWinControl; SaveChildren: boolean; AMinimized:boolean);
   begin
     // custom dock site
     LayoutNode:=LayoutTree.NewNode(LayoutTree.Root);
     LayoutNode.NodeType:=adltnCustomSite;
-    LayoutNode.Assign(theFormOrDockPanel,theFormOrDockPanel is TAnchorDockPanel);
+    LayoutNode.Assign(theFormOrDockPanel,theFormOrDockPanel is TAnchorDockPanel,AMinimized);
     // can have one normal dock site
     if SaveChildren then
     begin
@@ -3124,7 +3336,7 @@
       debugln(['TAnchorDockMaster.SaveMainLayoutToTree AForm=',DbgSName(AFormOrDockPanel)]);
       DebugWriteChildAnchors(AFormOrDockPanel,true,true);
       if AFormOrDockPanel is TAnchorDockPanel then begin
-        SaveFormOrDockPanel(GetParentFormOrDockPanel(AFormOrDockPanel),{false}true);
+        SaveFormOrDockPanel(GetParentFormOrDockPanel(AFormOrDockPanel),true,false);
         //LayoutNode:=LayoutTree.NewNode(LayoutTree.Root);
         //TAnchorDockPanel(AFormOrDockPanel).SaveLayout(LayoutTree,LayoutNode);
       end else if AFormOrDockPanel is TAnchorDockHostSite then begin
@@ -3132,12 +3344,12 @@
         LayoutNode:=LayoutTree.NewNode(LayoutTree.Root);
         Site.SaveLayout(LayoutTree,LayoutNode);
       end else if IsCustomSite(AFormOrDockPanel) then begin
-        SaveFormOrDockPanel(AFormOrDockPanel,true);
+        SaveFormOrDockPanel(AFormOrDockPanel,true,false);
       end else
         raise EAnchorDockLayoutError.Create('invalid root control for save: '+DbgSName(AControl));
     end;
     // remove invisible controls
-    LayoutTree.Root.Simplify(VisibleControls);
+    LayoutTree.Root.Simplify(VisibleControls,false);
   finally
     VisibleControls.Free;
     SavedSites.Free;
@@ -3157,7 +3369,7 @@
     (AControl as TAnchorDockPanel).SaveLayout(LayoutTree,LayoutTree.Root);
   end else if IsCustomSite(AControl) then begin
     LayoutTree.Root.NodeType:=adltnCustomSite;
-    LayoutTree.Root.Assign(AControl);
+    LayoutTree.Root.Assign(AControl,false,false);
     // can have one normal dock site
     Site:=TAnchorDockManager(AControl.DockManager).GetChildSite;
     if Site<>nil then begin
@@ -3252,7 +3464,7 @@
       debugln(ControlNames.Text);
       {$ENDIF}
       // if some forms/controls could not be created the layout needs to be adapted
-      Tree.Root.Simplify(ControlNames);
+      Tree.Root.Simplify(ControlNames,false);
 
       // reuse existing sites to reduce flickering
       MapTreeToControls(Tree);
@@ -3262,6 +3474,7 @@
 
       // create sites, move controls
       RestoreLayout(Tree,Scale);
+      SetMinimizedState(Tree);
     finally
       EndUpdate;
     end;
@@ -3323,6 +3536,7 @@
   HeaderFlatten                    := Settings.HeaderFlatten;
   HeaderFilled                     := Settings.HeaderFilled;
   HeaderHighlightFocused           := Settings.HeaderHighlightFocused;
+  DockSitesCanBeMinimized          := Settings.DockSitesCanBeMinimized;
 end;
 
 procedure TAnchorDockMaster.SaveSettings(Settings: TAnchorDockSettings);
@@ -3343,6 +3557,7 @@
   Settings.HeaderFlatten:=HeaderFlatten;
   Settings.HeaderFilled:=HeaderFilled;
   Settings.HeaderHighlightFocused:=HeaderHighlightFocused;
+  Settings.DockSitesCanBeMinimized:=DockSitesCanBeMinimized;
 end;
 
 function TAnchorDockMaster.SettingsAreEqual(Settings: TAnchorDockSettings
@@ -3436,8 +3651,11 @@
   if fUpdateCount<=0 then
     RaiseGDBException('');
   dec(fUpdateCount);
-  if fUpdateCount=0 then
+  if fUpdateCount=0 then begin
     SimplifyPendingLayouts;
+    UpdateHeaders;
+    InvalidateHeaders;
+  end;
 end;
 
 function TAnchorDockMaster.IsReleasing(AControl: TControl): Boolean;
@@ -3664,6 +3882,24 @@
   LUIncreaseChangeStamp64(FOptionsChangeStamp);
 end;
 
+procedure TAnchorDockMaster.UpdateHeaders;
+var
+  i: Integer;
+  AControl: TControl;
+  AHostSite: TAnchorDockHostSite;
+begin
+    for i:=0 to ControlCount-1 do begin
+      AControl:=Controls[i];
+      if not DockedControlIsVisible(AControl) then continue;
+      while Assigned(AControl) do
+      begin
+        if AControl is TAnchorDockHostSite then
+          TAnchorDockHostSite(AControl).UpdateHeaderShowing;
+        AControl:=AControl.parent;
+      end;
+    end;
+end;
+
 { TAnchorDockHostSite }
 
 procedure TAnchorDockHostSite.SetHeaderSide(const AValue: TAnchorKind);
@@ -3680,6 +3916,7 @@
     AControl:=TControl(Sender);
     if not (csDestroying in ComponentState) then begin
       if (not AControl.Visible)
+      and (not FMinimized)
       and (not ((AControl is TAnchorDockHeader)
                or (AControl is TAnchorDockSplitter)
                or (AControl is TAnchorDockHostSite)))
@@ -4119,6 +4356,8 @@
 end;
 
 procedure TAnchorDockHostSite.FreePages;
+var
+  i:Integer;
 begin
   FreeAndNil(FPages);
 end;
@@ -4233,6 +4472,14 @@
         akRight: NewBounds.Right:=AControl.Left+AControl.Width;
         akBottom: NewBounds.Bottom:=AControl.Top+AControl.Height;
         end;
+        if (sibling is TAnchorDockHostSite) then
+        if (sibling as TAnchorDockHostSite).FMinimized then begin
+          (sibling as TAnchorDockHostSite).FMinimized:=false;
+          (sibling as TAnchorDockHostSite).FMinimizedControl.Parent:=(sibling as TAnchorDockHostSite);
+          (sibling as TAnchorDockHostSite).FMinimizedControl.Visible:=True;
+          (sibling as TAnchorDockHostSite).FMinimizedControl:=nil;
+          (sibling as TAnchorDockHostSite).UpdateHeaderAlign;
+        end;
         Sibling.BoundsRect:=NewBounds;
       end;
     end;
@@ -4306,6 +4553,13 @@
       FSiteType:=adhstOneControl;
       OnlySiteLeft.Align:=alClient;
       Header.Parent:=Self;
+      if OnlySiteLeft.FMinimized then begin
+        OnlySiteLeft.FMinimized:=false;
+        OnlySiteLeft.FMinimizedControl.Parent:=OnlySiteLeft;
+        OnlySiteLeft.FMinimizedControl.Visible:=True;
+        OnlySiteLeft.FMinimizedControl:=nil;
+        UpdateHeaderAlign;
+      end;
       UpdateHeaderAlign;
 
       //debugln(['TAnchorDockHostSite.RemoveControlFromLayout.ConvertToOneControlType AFTER CONVERT "',Caption,'" to onecontrol OnlySiteLeft="',OnlySiteLeft.Caption,'"']);
@@ -4465,7 +4719,7 @@
     debugln(['TAnchorDockHostSite.Simplify ',DbgSName(Self),' ',DbgSName(AControl)]);
     if AControl is TAnchorDockHostSite then
       SimplifyOneControl
-    else if (AControl=nil) or (csDestroying in AControl.ComponentState) then
+    else if ((AControl=nil) or (csDestroying in AControl.ComponentState)) then
       DockMaster.NeedFree(Self);
   end;
 end;
@@ -4577,7 +4831,8 @@
     Result:=Controls[i];
     if Result.Owner<>Self then exit;
   end;
-  Result:=nil;
+  result:=FMinimizedControl;
+  //Result:=nil;
 end;
 
 function TAnchorDockHostSite.GetSiteCount: integer;
@@ -5165,6 +5420,119 @@
   Result:=Check(Self);
 end;
 
+function CheckOposite(Side:TAnchorKind;var AControl: TControl;out Splitter: TAnchorDockSplitter; out SplitterAnchorKind:TAnchorKind):boolean;
+begin
+  result:=GetDockSplitter(AControl,Side,Splitter);
+  if result then begin
+    if CountAnchoredControls(Splitter,OppositeAnchor[Side])=1 then begin
+      SplitterAnchorKind:=Side;
+      exit;
+    end;
+  end;
+  result:=false
+end;
+
+function FindNearestSpliter(AControl: TControl;out Splitter: TAnchorDockSplitter;out SplitterAnchorKind:TAnchorKind):boolean;
+begin
+  result:=CheckOposite(akTop,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akRight,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akBottom,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akLeft,AControl,Splitter,SplitterAnchorKind);
+end;
+
+function TAnchorDockHostSite.CanBeMinimized(out Splitter: TAnchorDockSplitter;
+                                            out SplitterAnchorKind:TAnchorKind):boolean;
+var
+  AControl: TControl;
+  OpositeDockHostSite:TAnchorDockHostSite;
+begin
+  result:=false;
+  if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+    OpositeDockHostSite:=CountAndReturnOnlyOneMinimizedAnchoredControls(Splitter,SplitterAnchorKind);
+    if (Splitter.Enabled and (OpositeDockHostSite=nil)) then
+      result:=true;
+  end
+end;
+
+procedure TAnchorDockHostSite.MinimizeSite;
+begin
+  //Application.QueueAsyncCall(@AsyncMinimizeSite,0);
+  AsyncMinimizeSite(0);
+end;
+
+procedure TAnchorDockHostSite.AsyncMinimizeSite(Data: PtrInt);
+var
+  AControl: TControl;
+  //OpositeDockHostSite:TAnchorDockHostSite;
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
+  //SpliterPercentPosition:Single;
+begin
+  fMinimization:=true;
+  debugln(['TAnchorDockHostSite.MinimizeSite ',DbgSName(Self),' SiteType=',dbgs(SiteType)]);
+  if FMinimized then
+    AControl:=FMinimizedControl
+  else
+    AControl:=GetOneControl;
+  if CanBeMinimized(Splitter,SplitterAnchorKind) or FMinimized then begin
+    FMinimized:=not FMinimized;
+    if FMinimized then begin
+      FMinimizedControl:=AControl;
+      AControl.Visible:=False;
+      AControl.Parent:=nil;
+      //self.DoDockOver(); OnDockOver;
+    end else begin
+      AControl.Parent:=self;
+      AControl.Visible:=True;
+      FMinimizedControl:=nil;
+    end;
+    Splitter.Enabled:=AControl.Visible;
+    UpdateHeaderAlign;
+    dockmaster.UpdateHeaders;
+    dockmaster.InvalidateHeaders;
+    Splitter.SetBoundsPercentually;
+  end;
+  fMinimization:=false;
+end;
+
+procedure TAnchorDockHostSite.ShowMinimizedControl;
+var
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
+  SpliterRect,OverlappingFormRect:TRect;
+begin
+  if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+    SpliterRect:=Splitter.GetSpliterBoundsWithUnminimizedDockSites;
+    OverlappingFormRect:=BoundsRect;
+    case SplitterAnchorKind of
+         akTop:OverlappingFormRect.Top:=SpliterRect.Bottom;
+        akLeft:OverlappingFormRect.Left:=SpliterRect.Right;
+       akRight:OverlappingFormRect.Right:=SpliterRect.Left;
+      akBottom:OverlappingFormRect.Bottom:=SpliterRect.Top;
+    end;
+    DockMaster.FOverlappingForm:=TAnchorDockOverlappingForm.CreateNew(self);
+    DockMaster.FOverlappingForm.BoundsRect:=OverlappingFormRect;
+    DockMaster.FOverlappingForm.Parent:=GetParentFormOrDockPanel(self,false);
+    DockMaster.FOverlappingForm.AnchorDockHostSite:=self;
+    header.Parent:=DockMaster.FOverlappingForm;
+    FMinimizedControl.Parent:=DockMaster.FOverlappingForm.Panel;
+    FMinimizedControl.Show;
+    DockMaster.ShowOverlappingForm;
+  end;
+end;
+
+procedure TAnchorDockHostSite.HideMinimizedControl;
+begin
+   FMinimizedControl.Hide;
+   header.Parent:=self;
+   header.UpdateHeaderControls;
+   FMinimizedControl.Parent:=nil;
+   FreeAndNil(DockMaster.FOverlappingForm);
+end;
+
 function TAnchorDockHostSite.CloseSite: boolean;
 var
   AControl: TControl;
@@ -5281,21 +5649,24 @@
 begin
   if csDestroying in ComponentState then exit;
   NewCaption:='';
-  for i:=0 to ControlCount-1 do begin
-    Child:=Controls[i];
-    if Child=Exclude then continue;
-    if (Child.HostDockSite=Self) or (Child is TAnchorDockHostSite)
-    or (Child is TAnchorDockPageControl) then begin
-      if NewCaption<>'' then
-        NewCaption:=NewCaption+',';
-      NewCaption:=NewCaption+Child.Caption;
+  if FMinimized then
+    NewCaption:=FMinimizedControl.Caption
+  else
+    for i:=0 to ControlCount-1 do begin
+      Child:=Controls[i];
+      if Child=Exclude then continue;
+      if (Child.HostDockSite=Self) or (Child is TAnchorDockHostSite)
+      or (Child is TAnchorDockPageControl) then begin
+        if NewCaption<>'' then
+          NewCaption:=NewCaption+',';
+        NewCaption:=NewCaption+Child.Caption;
+      end;
     end;
-  end;
   OldCaption:=Caption;
   Caption:=NewCaption;
   //debugln(['TAnchorDockHostSite.UpdateDockCaption Caption="',Caption,'" NewCaption="',NewCaption,'" HasParent=',Parent<>nil,' ',DbgSName(Header)]);
-  if ((Parent=nil) and DockMaster.HideHeaderCaptionFloatingControl)
-  or (not DockMaster.ShowHeaderCaption) then
+  if {((Parent=nil) and DockMaster.HideHeaderCaptionFloatingControl)
+  or (not DockMaster.ShowHeaderCaption)}false then
     Header.Caption:=''
   else
     Header.Caption:=Caption;
@@ -5306,9 +5677,8 @@
     if Parent is TAnchorDockPage then
       TAnchorDockPage(Parent).UpdateDockCaption;
   end;
-
   // do not show close button for mainform
-  Header.CloseButton.Visible:=not IsParentOf(Application.MainForm);
+  Header.CloseButton.Visible:=(not IsParentOf(Application.MainForm));
 end;
 
 procedure TAnchorDockHostSite.GetSiteInfo(Client: TControl;
@@ -5339,7 +5709,8 @@
   end;
 
   CanDock:=(Client is TAnchorDockHostSite)
-           and not DockMaster.AutoFreedIfControlIsRemoved(Self,Client);
+           and not DockMaster.AutoFreedIfControlIsRemoved(Self,Client)
+           and not FMinimized;
   //debugln(['TAnchorDockHostSite.GetSiteInfo ',DbgSName(Self),' ',dbgs(BoundsRect),' ',Caption,' CanDock=',CanDock,' PtIn=',PtInRect(InfluenceRect,MousePos)]);
 
   if Assigned(OnGetSiteInfo) then
@@ -5362,9 +5733,33 @@
 end;
 
 procedure TAnchorDockHostSite.UpdateHeaderAlign;
+const
+OppositeAlign: array[TAnchorKind] of TAlign = (
+  alBottom, // akTop,
+  alRight,  // akLeft,
+  alLeft,   // akRight,
+  alTop     // akBottom
+  );
+OppositeAnchorKindAlign: array[TAnchorKind] of TADLHeaderPosition = (
+  adlhpBottom, // akTop,
+  adlhpRight,  // akLeft,
+  adlhpLeft,   // akRight,
+  adlhpTop     // akBottom
+  );
+var
+  NeededHeaderPosition:TADLHeaderPosition;
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
 begin
   if Header=nil then exit;
-  case Header.HeaderPosition of
+  if FMinimized then begin
+    if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+      NeededHeaderPosition:=OppositeAnchorKindAlign[SplitterAnchorKind];
+    end else
+      NeededHeaderPosition:=Header.HeaderPosition;
+  end else
+    NeededHeaderPosition:=Header.HeaderPosition;
+  case NeededHeaderPosition of
   adlhpAuto:
     if Header.Align in [alLeft,alRight] then begin
       if (ClientHeight>0)
@@ -5388,10 +5783,16 @@
 end;
 
 procedure TAnchorDockHostSite.UpdateHeaderShowing;
+var
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
 begin
   if Header=nil then exit;
-  if HeaderNeedsShowing then
-    Header.Parent:=Self
+  if HeaderNeedsShowing then begin
+    Header.Parent:=Self;
+    Header.MinimizeButton.Visible:=(DockMaster.DockSitesCanBeMinimized and CanBeMinimized(Splitter,SplitterAnchorKind))or FMinimized;
+    Header.MinimizeButton.Parent:=Header;
+  end
   else
     Header.Parent:=nil;
 end;
@@ -5432,7 +5833,7 @@
   if (SiteType=adhstOneControl) and (OneControl<>nil)
   and (not (OneControl is TAnchorDockHostSite)) then begin
     LayoutNode.NodeType:=adltnControl;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,FMinimized);
     LayoutNode.Name:=OneControl.Name;
     LayoutNode.HeaderPosition:=Header.HeaderPosition;
   end else if (SiteType in [adhstLayout,adhstOneControl]) then begin
@@ -5450,7 +5851,7 @@
         Splitter.SaveLayout(ChildNode);
       end;
     end;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,FMinimized);
     LayoutNode.HeaderPosition:=Header.HeaderPosition;
   end else if SiteType=adhstPages then begin
     LayoutNode.NodeType:=adltnPages;
@@ -5461,7 +5862,7 @@
         Site.SaveLayout(LayoutTree,ChildNode);
       end;
     end;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,FMinimized);
     LayoutNode.HeaderPosition:=Header.HeaderPosition;
   end else
     LayoutNode.NodeType:=adltnNone;
@@ -5476,6 +5877,9 @@
 constructor TAnchorDockHostSite.CreateNew(AOwner: TComponent; Num: Integer);
 begin
   inherited CreateNew(AOwner,Num);
+  FMinimized:=false;
+  fMinimization:=false;
+  FMinimizedControl:=Nil;
   Visible:=false;
   FHeaderSide:=akTop;
   FHeader:=DockMaster.HeaderClass.Create(Self);
@@ -5490,13 +5894,13 @@
 end;
 
 destructor TAnchorDockHostSite.Destroy;
-//var i: Integer;
+var i: Integer;
 begin
-  //debugln(['TAnchorDockHostSite.Destroy ',DbgSName(Self),' Caption="',Caption,'" Self=',dbgs(Pointer(Self)),' ComponentCount=',ComponentCount,' ControlCount=',ControlCount]);
-  {for i:=0 to ComponentCount-1 do
+  debugln(['TAnchorDockHostSite.Destroy ',DbgSName(Self),' Caption="',Caption,'" Self=',dbgs(Pointer(Self)),' ComponentCount=',ComponentCount,' ControlCount=',ControlCount]);
+  for i:=0 to ComponentCount-1 do
     debugln(['TAnchorDockHostSite.Destroy Component ',i,'/',ComponentCount,' ',DbgSName(Components[i])]);
   for i:=0 to ControlCount-1 do
-    debugln(['TAnchorDockHostSite.Destroy Control ',i,'/',ControlCount,' ',DbgSName(Controls[i])]);}
+    debugln(['TAnchorDockHostSite.Destroy Control ',i,'/',ControlCount,' ',DbgSName(Controls[i])]);
   FreePages;
   inherited Destroy;
 end;
@@ -5562,13 +5966,34 @@
 end;
 
 procedure TAnchorDockHeader.CloseButtonClick(Sender: TObject);
+var
+  HeaderParent:TAnchorDockHostSite;
 begin
-  if Parent is TAnchorDockHostSite then begin
-    DockMaster.RestoreLayouts.Add(DockMaster.CreateRestoreLayout(Parent),true);
-    TAnchorDockHostSite(Parent).CloseSite;
+  TWinControl(HeaderParent):=Parent;
+  if HeaderParent=TWinControl(DockMaster.FOverlappingForm) then begin
+    HeaderParent:=DockMaster.FOverlappingForm.AnchorDockHostSite;
+    HeaderParent.HideMinimizedControl;
   end;
+  if HeaderParent is TAnchorDockHostSite then begin
+    DockMaster.RestoreLayouts.Add(DockMaster.CreateRestoreLayout(HeaderParent),true);
+    HeaderParent.CloseSite;
+  end;
 end;
 
+procedure TAnchorDockHeader.MinimizeButtonClick(Sender: TObject);
+var
+  HeaderParent:TAnchorDockHostSite;
+begin
+  TWinControl(HeaderParent):=Parent;
+  if HeaderParent=TWinControl(DockMaster.FOverlappingForm) then begin
+    HeaderParent:=DockMaster.FOverlappingForm.AnchorDockHostSite;
+    HeaderParent.HideMinimizedControl;
+  end;
+  if HeaderParent is TAnchorDockHostSite then begin
+    HeaderParent.MinimizeSite;
+  end;
+end;
+
 procedure TAnchorDockHeader.HeaderPositionItemClick(Sender: TObject);
 var
   Item: TMenuItem;
@@ -5635,11 +6060,18 @@
 
   if CloseButton.IsControlVisible and (CloseButton.Parent=Self) then begin
     if Align in [alLeft,alRight] then
-      r.Top:=CloseButton.Top+CloseButton.Height+1
+      r.Top:=CloseButton.Top+CloseButton.Height+ButtonBorderSpacingAround
     else
-      r.Right:=CloseButton.Left-1;
+      r.Right:=CloseButton.Left-ButtonBorderSpacingAround;
   end;
 
+  if MinimizeButton.IsControlVisible and (MinimizeButton.Parent=Self) then begin
+    if Align in [alLeft,alRight] then
+      r.Top:=MinimizeButton.Top+MinimizeButton.Height+ButtonBorderSpacingAround
+    else
+      r.Right:=MinimizeButton.Left-ButtonBorderSpacingAround;
+  end;
+
   // caption
   if Caption<>'' then begin
     if fFocused and DockMaster.HeaderHighlightFocused and NeedHighlightText then
@@ -5728,26 +6160,127 @@
     end else begin
       PreferredHeight:=Max(NeededHeight,PreferredHeight);
     end;
+  end else begin
+    NeededHeight:=CloseButton.Height;
+    if Align in [alLeft,alRight] then begin
+      PreferredWidth:=Max(NeededHeight,PreferredWidth);
+    end else begin
+      PreferredHeight:=Max(NeededHeight,PreferredHeight);
   end;
+  end;
 end;
 
 procedure TAnchorDockHeader.MouseDown(Button: TMouseButton; Shift: TShiftState;
   X, Y: Integer);
+var
+  SiteMinimized:Boolean;
 begin
   inherited MouseDown(Button, Shift, X, Y);
-  if (Button=mbLeft) and DockMaster.AllowDragging then
-    DragManager.DragStart(Parent,false,DockMaster.DragTreshold);
+  SiteMinimized:=False;
+  fUseTimer:=false;
+  StopMouseNoMoveTimer;
+  if Parent is TAnchorDockHostSite then
+    SiteMinimized:=(Parent as TAnchorDockHostSite).FMinimized;
+  if SiteMinimized then begin
+    DoMouseNoMoveTimer(nil);
+  end else
+    begin
+      if parent<>nil then
+        if DockMaster.FOverlappingForm<>nil then
+          //if parent=DockMaster.FOverlappingForm.Panel then
+            DockMaster.HideOverlappingForm(nil);
+      if (Button=mbLeft) and (DockMaster.AllowDragging) and (DockMaster.FOverlappingForm=nil) then
+        DragManager.DragStart(Parent,false,DockMaster.DragTreshold);
+    end;
 end;
 
+procedure  TAnchorDockHeader.MouseMove(Shift: TShiftState; X,Y: Integer);
+begin
+  inherited MouseMove(Shift, X, Y);
+  if parent<>nil then
+    if parent is TAnchorDockHostSite then
+      if (parent as TAnchorDockHostSite).FMinimized then
+        if DockMaster.FOverlappingForm=nil then
+          if FMouseTimeStartX=EmptyMouseTimeStartX then
+            StartMouseNoMoveTimer(X, Y)
+          else begin
+            if (abs(FMouseTimeStartX-X)>MouseNoMoveDelta)or(abs(FMouseTimeStartY-Y)>MouseNoMoveDelta)then
+            StopMouseNoMoveTimer;
+          end;
+  if (parent is TAnchorDockHostSite)and(DockMaster.FOverlappingForm=nil)then
+    fUseTimer:=true;
+end;
+
+procedure TAnchorDockHeader.MouseLeave;
+begin
+  inherited;
+  StopMouseNoMoveTimer;
+end;
+
+procedure TAnchorDockHeader.StartMouseNoMoveTimer(X, Y: Integer);
+begin
+  if fUseTimer then begin
+    if DockTimer.Enabled then DockTimer.Enabled:=false;
+    DockTimer.Interval:=MouseNoMoveTime;
+    DockTimer.OnTimer:=@DoMouseNoMoveTimer;
+    DockTimer.Enabled:=true;
+  end;
+end;
+
+procedure TAnchorDockHeader.StopMouseNoMoveTimer;
+begin
+  FMouseTimeStartX:=EmptyMouseTimeStartX;
+  DockTimer.OnTimer:=nil;
+  DockTimer.Enabled:=false;
+end;
+
+procedure TAnchorDockHeader.DoMouseNoMoveTimer(Sender: TObject);
+begin
+  StopMouseNoMoveTimer;
+  //if fUseTimer then
+    if parent<>nil then
+      if parent is TAnchorDockHostSite then
+        if (parent as TAnchorDockHostSite).FMinimized then
+          (parent as TAnchorDockHostSite).ShowMinimizedControl;
+end;
+
 procedure TAnchorDockHeader.UpdateHeaderControls;
 begin
   if Align in [alLeft,alRight] then begin
-    if CloseButton<>nil then
-      CloseButton.Align:=alTop;
+    if CloseButton<>nil then begin
+      //MinimizeButton.Align:=alTop;
+      //CloseButton.Align:=alTop;
+      CloseButton.AnchorSide[akRight].Side := asrCenter;
+      CloseButton.AnchorSide[akRight].Control := self;
+      CloseButton.AnchorSide[akTop].Side := asrTop;
+      CloseButton.AnchorSide[akTop].Control := self;
+      CloseButton.Anchors := CloseButton.Anchors + [akTop] + [akRight];
+
+      MinimizeButton.AnchorSide[akRight].Side := asrCenter;
+      MinimizeButton.AnchorSide[akRight].Control := CloseButton;
+      MinimizeButton.AnchorSide[akTop].Side := asrBottom;
+      MinimizeButton.AnchorSide[akTop].Control := CloseButton;
+      MinimizeButton.Anchors := MinimizeButton.Anchors + [akTop] + [akRight];
+    end;
   end else begin
-    if CloseButton<>nil then
-      CloseButton.Align:=alRight;
+    if CloseButton<>nil then begin
+      //MinimizeButton.Align:=alRight;
+      //CloseButton.Align:=alRight;
+      CloseButton.AnchorSide[akRight].Side := asrRight;
+      CloseButton.AnchorSide[akRight].Control := self;
+      CloseButton.AnchorSide[akTop].Side := asrCenter;
+      CloseButton.AnchorSide[akTop].Control := self;
+      CloseButton.Anchors := CloseButton.Anchors - [akLeft] + [akRight];
+
+      MinimizeButton.AnchorSide[akRight].Side := asrLeft;
+      MinimizeButton.AnchorSide[akRight].Control := CloseButton;
+      MinimizeButton.AnchorSide[akTop].Side := asrCenter;
+      MinimizeButton.AnchorSide[akTop].Control := CloseButton;
+      MinimizeButton.Anchors := MinimizeButton.Anchors - [akLeft] + [akRight];
+    end;
   end;
+  CloseButton.BorderSpacing.Around:=ButtonBorderSpacingAround;
+  MinimizeButton.BorderSpacing.Around:=ButtonBorderSpacingAround;
   //debugln(['TAnchorDockHeader.UpdateHeaderControls ',dbgs(Align),' ',dbgs(CloseButton.Align)]);
 end;
 
@@ -5787,9 +6320,9 @@
 begin
   inherited Create(TheOwner);
   FHeaderPosition:=adlhpAuto;
-  FCloseButton:=TAnchorDockCloseButton.Create(Self);
   BevelOuter:=bvNone;
   BorderWidth:=0;
+  FCloseButton:=TAnchorDockCloseButton.Create(Self);
   with FCloseButton do begin
     Name:='CloseButton';
     Parent:=Self;
@@ -5799,11 +6332,23 @@
     OnClick:=@CloseButtonClick;
     AutoSize:=true;
   end;
+  FMinimizeButton:=TAnchorDockMinimizeButton.Create(Self);
+  with FMinimizeButton do begin
+    Name:='MinimizeButton';
+    Parent:=Self;
+    Flat:=true;
+    ShowHint:=true;
+    Hint:=adrsMinimize;
+    OnClick:=@MinimizeButtonClick;
+    AutoSize:=true;
+  end;
   Align:=alTop;
   AutoSize:=true;
   ShowHint:=true;
   PopupMenu:=DockMaster.GetPopupMenu;
   fFocused:=false;
+  FMouseTimeStartX:=EmptyMouseTimeStartX;
+  fUseTimer:=true;
 end;
 
 { TAnchorDockCloseButton }
@@ -5830,6 +6375,31 @@
   Result := ThemeServices.GetElementDetails(WindowPart);
 end;
 
+procedure SizeCorrector(var current,recomend:integer);
+begin
+  if recomend<0 then begin
+    if current>0 then
+      recomend:=current
+    else
+      current:=HardcodedButtonSize;
+  end else begin
+      if current>recomend then
+        current:=recomend
+      else begin
+        if current>0 then
+         recomend:=current
+        else
+         current:=recomend;
+      end;
+  end;
+end;
+
+procedure ButtonSizeCorrector(var w,h:integer);
+begin
+  SizeCorrector(w,PreferredButtonWidth);
+  SizeCorrector(h,PreferredButtonHeight);
+end;
+
 procedure TAnchorDockCloseButton.CalculatePreferredSize(var PreferredWidth,
   PreferredHeight: integer; WithThemeSpace: Boolean);
 begin
@@ -5837,6 +6407,7 @@
   begin
     PreferredWidth:=cx;
     PreferredHeight:=cy;
+    ButtonSizeCorrector(PreferredWidth,PreferredHeight);
     {$IF defined(LCLGtk2) or defined(Carbon)}
     inc(PreferredWidth,2);
     inc(PreferredHeight,2);
@@ -5844,6 +6415,45 @@
   end;
 end;
 
+{ TAnchorDockMinimizeButton }
+
+function TAnchorDockMinimizeButton.GetDrawDetails: TThemedElementDetails;
+
+function WindowPart: TThemedWindow;
+  begin
+    // no check states available
+    Result := twMinButtonNormal;
+    if not IsEnabled then
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonDisabled{$ELSE}twMinButtonDisabled{$ENDIF}
+    else
+    if FState in [bsDown, bsExclusive] then
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonPushed{$ELSE}twMinButtonPushed{$ENDIF}
+    else
+    if FState = bsHot then
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonHot{$ELSE}twMinButtonHot{$ENDIF}
+    else
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonNormal{$ELSE}twMinButtonNormal{$ENDIF};
+  end;
+
+begin
+  Result := ThemeServices.GetElementDetails(WindowPart);
+end;
+
+procedure TAnchorDockMinimizeButton.CalculatePreferredSize(var PreferredWidth,
+  PreferredHeight: integer; WithThemeSpace: Boolean);
+begin
+  with ThemeServices.GetDetailSize(ThemeServices.GetElementDetails({$IFDEF LCLGtk2}twMDIRestoreButtonNormal{$ELSE}twMinButtonNormal{$ENDIF})) do
+  begin
+    PreferredWidth:=cx;
+    PreferredHeight:=cy;
+    ButtonSizeCorrector(PreferredWidth,PreferredHeight);
+    {$IF defined(LCLGtk2) or defined(Carbon)}
+    inc(PreferredWidth,2);
+    inc(PreferredHeight,2);
+    {$ENDIF}
+  end;
+end;
+
 { TAnchorDockManager }
 
 procedure TAnchorDockManager.SetPreferredSiteSizeAsSiteMinimum(
@@ -6213,6 +6823,9 @@
   ClientRectChanged:=(WidthDiff<>0) or (HeightDiff<>0);
   if ClientRectChanged or PreferredSiteSizeAsSiteMinimum then
     AlignChilds;
+  if ClientRectChanged then
+    if DockMaster.FOverlappingForm<>nil then
+      DockMaster.HideOverlappingForm(nil);
 end;
 
 procedure TAnchorDockManager.SaveToStream(Stream: TStream);
@@ -6234,6 +6847,27 @@
     BestDistance:=CurDistance;
   end;
 
+  procedure UnMinimizeSitesAt;
+  var
+    i:integer;
+    Site: TAnchorDockHostSite;
+    ARect:trect;
+  begin
+    for i:=0 to DockMaster.ComponentCount-1 do begin
+      Site:=TAnchorDockHostSite(DockMaster.Components[i]);
+      if not (Site is TAnchorDockHostSite) then continue;
+      if not Site.Showing then continue;
+      if not Site.Enabled then continue;
+      if not Site.IsVisible then continue;
+      ARect.TopLeft:=Site.ClientToScreen(point(0,0));
+      ARect.BottomRight:=Site.ClientToScreen(point(Site.Width,Site.Height));
+      InflateRect(ARect,DockMaster.DragTreshold+10,DockMaster.DragTreshold+10);
+      if PtInRect(ARect, ADockObject.DragPos) then
+      if Site.FMinimized then
+        Application.QueueAsyncCall(@Site.AsyncMinimizeSite,0);
+    end;
+  end;
+
 var
   p: TPoint;
   LastTabRect: TRect;
@@ -6245,6 +6879,8 @@
     exit(false);
   end;
 
+  UnMinimizeSitesAt;
+
   p:=Site.ScreenToClient(ADockObject.DragPos);
   //debugln(['TAnchorDockManager.GetDockEdge ',dbgs(p),' ',dbgs(Site.BoundsRect),' ',DbgSName(Site)]);
   if (DockSite<>nil) and (DockSite.Pages<>nil) then begin
@@ -6505,32 +7141,58 @@
 procedure TAnchorDockSplitter.SetBoundsPercentually;
 var
   NewLeft, NewTop: Integer;
+  AControl: TControl;
+  SplitterAnchorKind:TAnchorKind;
 begin
-  if ResizeAnchor in [akLeft,akRight] then
-  begin
-    if DockParentClientSize.cx> 0 then
+  if Enabled then begin
+    if ResizeAnchor in [akLeft,akRight] then
     begin
-      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
-        NewLeft := Round(FPercentPosition*Parent.ClientWidth)
-      else
-        NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
-      NewTop := Top;
-      SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      if DockParentClientSize.cx> 0 then
+      begin
+        if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+          NewLeft := Round(FPercentPosition*Parent.ClientWidth)
+        else
+          NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
+        NewTop := Top;
+        SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      end;
+    end else
+    begin
+      if DockParentClientSize.cy> 0 then
+      begin
+        NewLeft := Left;
+        if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+          NewTop := Round(FPercentPosition*Parent.ClientHeight)
+        else
+          NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+        SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      end;
     end;
-  end else
-  begin
-    if DockParentClientSize.cy> 0 then
-    begin
-      NewLeft := Left;
-      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
-        NewTop := Round(FPercentPosition*Parent.ClientHeight)
-      else
-        NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+    if FPercentPosition < 0 then
+      UpdatePercentPosition;
+  end else begin
+    SplitterAnchorKind:=akTop;
+    AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);
+    if AControl=nil then begin SplitterAnchorKind:=akRight;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+    if AControl=nil then begin SplitterAnchorKind:=akBottom;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+    if AControl=nil then begin SplitterAnchorKind:=akLeft;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+
+    if AControl is TAnchorDockHostSite then begin
+      (AControl as TAnchorDockHostSite).UpdateHeaderAlign;
+      NewTop := (AControl as TAnchorDockHostSite).Header.Left;
+      NewTop := (AControl as TAnchorDockHostSite).Header.Height;
+      NewLeft := left;
+      NewTop := top;
+      (AControl as TAnchorDockHostSite).UpdateHeaderAlign;
+      case SplitterAnchorKind of
+        akTop: NewTop := AControl.Top+(AControl as TAnchorDockHostSite).Header.Height;
+        akBottom: NewTop := AControl.Top+AControl.Height-(AControl as TAnchorDockHostSite).Header.Height-Height;
+        akLeft: NewLeft := AControl.Left+(AControl as TAnchorDockHostSite).Header.Width;
+        akRight: NewLeft := AControl.Left+AControl.Width-(AControl as TAnchorDockHostSite).Header.Width-Width;
+      end;
       SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
     end;
   end;
-  if FPercentPosition < 0 then
-    UpdatePercentPosition;
 end;
 
 function TAnchorDockSplitter.SideAnchoredControlCount(Side: TAnchorKind): integer;
@@ -6560,14 +7222,47 @@
   end;
 end;
 
+function TAnchorDockSplitter.GetSpliterBoundsWithUnminimizedDockSites:TRect;
+var
+  NewLeft, NewTop: Integer;
+begin
+  if ResizeAnchor in [akLeft,akRight] then
+  begin
+    if DockParentClientSize.cx> 0 then
+    begin
+      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+        NewLeft := Round(FPercentPosition*Parent.ClientWidth)
+      else
+        NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
+      NewTop := Top;
+    end;
+  end else
+  begin
+    if DockParentClientSize.cy> 0 then
+    begin
+      NewLeft := Left;
+      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+        NewTop := Round(FPercentPosition*Parent.ClientHeight)
+      else
+        NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+    end;
+  end;
+  result:=Rect(NewLeft,NewTop,NewLeft+Width,NewTop+Height);
+end;
+
 procedure TAnchorDockSplitter.SaveLayout(
   LayoutNode: TAnchorDockLayoutTreeNode);
+var
+  NewLeft, NewTop: Integer;
 begin
   if ResizeAnchor in [akLeft,akRight] then
     LayoutNode.NodeType:=adltnSplitterVertical
   else
     LayoutNode.NodeType:=adltnSplitterHorizontal;
-  LayoutNode.Assign(Self);
+  LayoutNode.Assign(Self,false,false);
+  if not Enabled then begin
+    LayoutNode.BoundsRect:=GetSpliterBoundsWithUnminimizedDockSites;
+  end
 end;
 
 function TAnchorDockSplitter.HasOnlyOneSibling(Side: TAnchorKind; MinPos,
@@ -6645,7 +7340,7 @@
 begin
   inherited MouseDown(Button, Shift, X, Y);
   ATabIndex := IndexOfPageAt(X, Y);
-  if (Button = mbLeft) and DockMaster.AllowDragging and (ATabIndex >= 0) then
+  if (Button = mbLeft) and DockMaster.AllowDragging and (ATabIndex >= 0) and (DockMaster.FOverlappingForm=nil) then
   begin
     APage:=Page[ATabIndex];
     if (APage.ControlCount>0) and (APage.Controls[0] is TAnchorDockHostSite) then
@@ -6782,6 +7477,20 @@
   PopupMenu:=DockMaster.GetPopupMenu;
 end;
 
+{ TAnchorDockOverlappingForm }
+
+constructor TAnchorDockOverlappingForm.CreateNew(AOwner: TComponent; Num: Integer = 0);
+begin
+  inherited;
+  BorderStyle:=bsNone;
+  AnchorDockHostSite:=nil;
+  Panel:=TPanel.Create(self);
+  Panel.BorderStyle:=bsSingle;
+  Panel.Align:=alClient;
+  Panel.Parent:=self;
+  Panel.Visible:=true;
+end;
+
 { TAnchorDockPage }
 
 procedure TAnchorDockPage.UpdateDockCaption(Exclude: TControl);
@@ -6835,9 +7544,11 @@
 
 initialization
   DockMaster:=TAnchorDockMaster.Create(nil);
+  DockTimer:=TTimer.Create(nil);
 
 finalization
   FreeAndNil(DockMaster);
+  FreeAndNil(DockTimer);
 
 end.
 
Index: components/anchordocking/anchordockoptionsdlg.lfm
===================================================================
--- components/anchordocking/anchordockoptionsdlg.lfm	(revision 59428)
+++ components/anchordocking/anchordockoptionsdlg.lfm	(working copy)
@@ -1,11 +1,13 @@
 object AnchorDockOptionsFrame: TAnchorDockOptionsFrame
   Left = 0
-  Height = 482
+  Height = 567
   Top = 0
-  Width = 416
-  ClientHeight = 482
-  ClientWidth = 416
+  Width = 490
+  ClientHeight = 567
+  ClientWidth = 490
+  DesignTimePPI = 113
   OnClick = FrameClick
+  ParentFont = False
   TabOrder = 0
   DesignLeft = 513
   DesignTop = 189
@@ -12,14 +14,15 @@
   object DragThresholdLabel: TLabel
     AnchorSideLeft.Control = Owner
     AnchorSideTop.Control = Owner
-    Left = 10
-    Height = 13
-    Top = 10
-    Width = 111
-    BorderSpacing.Left = 10
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 12
+    Width = 122
+    BorderSpacing.Left = 12
+    BorderSpacing.Top = 12
     Caption = 'DragThresholdLabel'
     ParentColor = False
+    ParentFont = False
   end
   object DragThresholdTrackBar: TTrackBar
     AnchorSideLeft.Control = DragThresholdLabel
@@ -27,15 +30,16 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = Owner
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 46
-    Top = 23
-    Width = 396
+    Left = 12
+    Height = 54
+    Top = 31
+    Width = 466
     Max = 20
     OnChange = DragThresholdTrackBarChange
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Right = 10
+    BorderSpacing.Right = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 1
@@ -46,12 +50,13 @@
     AnchorSideTop.Control = DragThresholdLabel
     AnchorSideTop.Side = asrCenter
     AnchorSideRight.Control = Owner
-    Left = 127
-    Height = 23
-    Top = 5
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 141
+    Height = 27
+    Top = 8
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 20
+    ParentFont = False
     TabOrder = 0
     Visible = False
   end
@@ -59,13 +64,14 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = DragThresholdTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 79
-    Width = 103
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 97
+    Width = 112
+    BorderSpacing.Top = 12
     Caption = 'SplitterWidthLabel'
     ParentColor = False
+    ParentFont = False
   end
   object SplitterWidthTrackBar: TTrackBar
     AnchorSideLeft.Control = DragThresholdTrackBar
@@ -73,14 +79,15 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 46
-    Top = 92
-    Width = 396
+    Left = 12
+    Height = 54
+    Top = 116
+    Width = 466
     Min = 1
     OnChange = SplitterWidthTrackBarChange
     Position = 1
     Anchors = [akTop, akLeft, akRight]
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 3
@@ -89,12 +96,13 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = SplitterWidthTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 24
-    Top = 142
-    Width = 160
-    BorderSpacing.Top = 4
+    Left = 12
+    Height = 23
+    Top = 175
+    Width = 169
+    BorderSpacing.Top = 5
     Caption = 'ScaleOnResizeCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 4
@@ -103,12 +111,13 @@
     AnchorSideLeft.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 24
-    Top = 166
-    Width = 149
+    Left = 12
+    Height = 23
+    Top = 198
+    Width = 160
     Caption = 'ShowHeaderCheckBox'
     OnChange = ShowHeaderCheckBoxChange
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 5
@@ -117,12 +126,13 @@
     AnchorSideLeft.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Control = ShowHeaderCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 190
-    Width = 191
-    BorderSpacing.Left = 15
+    Left = 30
+    Height = 23
+    Top = 221
+    Width = 208
+    BorderSpacing.Left = 18
     Caption = 'ShowHeaderCaptionCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 6
@@ -131,11 +141,12 @@
     AnchorSideLeft.Control = ShowHeaderCaptionCheckBox
     AnchorSideTop.Control = ShowHeaderCaptionCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 214
-    Width = 249
+    Left = 30
+    Height = 23
+    Top = 244
+    Width = 272
     Caption = 'HideHeaderCaptionForFloatingCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 7
@@ -147,15 +158,16 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = Owner
     AnchorSideRight.Side = asrBottom
-    Left = 122
+    Left = 136
     Height = 27
-    Top = 286
-    Width = 284
+    Top = 313
+    Width = 342
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 6
-    BorderSpacing.Right = 10
-    ItemHeight = 0
+    BorderSpacing.Left = 7
+    BorderSpacing.Right = 12
+    ItemHeight = 19
     OnDrawItem = HeaderStyleComboBoxDrawItem
+    ParentFont = False
     Style = csDropDownList
     TabOrder = 10
   end
@@ -163,23 +175,25 @@
     AnchorSideLeft.Control = ShowHeaderCheckBox
     AnchorSideTop.Control = HeaderStyleComboBox
     AnchorSideTop.Side = asrCenter
-    Left = 20
-    Height = 13
-    Top = 293
-    Width = 96
-    BorderSpacing.Left = 10
+    Left = 24
+    Height = 19
+    Top = 317
+    Width = 105
+    BorderSpacing.Left = 12
     Caption = 'HeaderStyleLabel'
     ParentColor = False
+    ParentFont = False
   end
   object FlattenHeadersCheckBox: TCheckBox
     AnchorSideLeft.Control = HideHeaderCaptionForFloatingCheckBox
     AnchorSideTop.Control = HideHeaderCaptionForFloatingCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 238
-    Width = 164
+    Left = 30
+    Height = 23
+    Top = 267
+    Width = 175
     Caption = 'FlattenHeadersCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 8
@@ -188,11 +202,12 @@
     AnchorSideLeft.Control = FlattenHeadersCheckBox
     AnchorSideTop.Control = FlattenHeadersCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 262
-    Width = 154
+    Left = 30
+    Height = 23
+    Top = 290
+    Width = 164
     Caption = 'FilledHeadersCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 9
@@ -201,11 +216,12 @@
     AnchorSideLeft.Control = FilledHeadersCheckBox
     AnchorSideTop.Control = HeaderStyleComboBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 313
-    Width = 175
+    Left = 30
+    Height = 23
+    Top = 340
+    Width = 189
     Caption = 'HighlightFocusedCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 11
@@ -215,13 +231,14 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = SplitterWidthLabel
     AnchorSideTop.Side = asrCenter
-    Left = 119
-    Height = 23
-    Top = 74
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 131
+    Height = 27
+    Top = 93
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 10
     MinValue = 1
+    ParentFont = False
     TabOrder = 2
     Value = 1
     Visible = False
@@ -228,15 +245,16 @@
   end
   object HeaderAlignTopLabel: TLabel
     AnchorSideLeft.Control = DragThresholdLabel
-    AnchorSideTop.Control = HighlightFocusedCheckBox
+    AnchorSideTop.Control = DockSitesCanBeMinimized
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 347
-    Width = 117
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 398
+    Width = 130
+    BorderSpacing.Top = 12
     Caption = 'HeaderAlignTopLabel'
     ParentColor = False
+    ParentFont = False
   end
   object HeaderAlignTopTrackBar: TTrackBar
     AnchorSideLeft.Control = Owner
@@ -244,10 +262,10 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 47
-    Top = 360
-    Width = 396
+    Left = 12
+    Height = 55
+    Top = 417
+    Width = 466
     Frequency = 10
     Max = 150
     OnChange = HeaderAlignTopTrackBarChange
@@ -254,7 +272,8 @@
     PageSize = 10
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 10
+    BorderSpacing.Left = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 13
@@ -264,12 +283,13 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = HeaderAlignTopLabel
     AnchorSideTop.Side = asrCenter
-    Left = 133
-    Height = 23
-    Top = 342
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 149
+    Height = 27
+    Top = 394
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 150
+    ParentFont = False
     TabOrder = 12
     Visible = False
   end
@@ -277,13 +297,14 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = HeaderAlignTopTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 417
-    Width = 120
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 484
+    Width = 130
+    BorderSpacing.Top = 12
     Caption = 'HeaderAlignLeftLabel'
     ParentColor = False
+    ParentFont = False
   end
   object HeaderAlignLeftTrackBar: TTrackBar
     AnchorSideLeft.Control = Owner
@@ -291,10 +312,10 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 47
-    Top = 430
-    Width = 396
+    Left = 12
+    Height = 55
+    Top = 503
+    Width = 466
     Frequency = 10
     Max = 200
     OnChange = HeaderAlignLeftTrackBarChange
@@ -301,7 +322,8 @@
     PageSize = 10
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 10
+    BorderSpacing.Left = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 15
@@ -311,13 +333,28 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = HeaderAlignLeftLabel
     AnchorSideTop.Side = asrCenter
-    Left = 136
-    Height = 23
-    Top = 412
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 149
+    Height = 27
+    Top = 480
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 200
+    ParentFont = False
     TabOrder = 14
     Visible = False
   end
+  object DockSitesCanBeMinimized: TCheckBox
+    AnchorSideLeft.Control = FilledHeadersCheckBox
+    AnchorSideTop.Control = HighlightFocusedCheckBox
+    AnchorSideTop.Side = asrBottom
+    Left = 30
+    Height = 23
+    Top = 363
+    Width = 185
+    Caption = 'DockSitesCanBeMinimized'
+    ParentFont = False
+    ParentShowHint = False
+    ShowHint = True
+    TabOrder = 16
+  end
 end
Index: components/anchordocking/anchordockoptionsdlg.pas
===================================================================
--- components/anchordocking/anchordockoptionsdlg.pas	(revision 59428)
+++ components/anchordocking/anchordockoptionsdlg.pas	(working copy)
@@ -37,6 +37,7 @@
     HeaderStyleLabel: TLabel;
     HideHeaderCaptionForFloatingCheckBox: TCheckBox;
     HighlightFocusedCheckBox: TCheckBox;
+    DockSitesCanBeMinimized: TCheckBox;
     ScaleOnResizeCheckBox: TCheckBox;
     ShowHeaderCaptionCheckBox: TCheckBox;
     ShowHeaderCheckBox: TCheckBox;
@@ -202,7 +203,7 @@
 
       HeaderAlignTopSpinEdit.Visible:=true;
       HeaderAlignTopTrackBar.Visible:=false;
-      HeaderAlignTopSpinEdit.AnchorToNeighbour(akTop,6,HighlightFocusedCheckBox);
+      HeaderAlignTopSpinEdit.AnchorToNeighbour(akTop,6,DockSitesCanBeMinimized);
       HeaderAlignTopLabel.AnchorVerticalCenterTo(HeaderAlignTopSpinEdit);
       UpdateHeaderAlignTopLabel;
 
@@ -299,6 +300,7 @@
   HeaderStyleLabel.Enabled:=HasHeaders;
   HeaderStyleComboBox.Enabled:=HasHeaders;
   HighlightFocusedCheckBox.Enabled:=HasHeaders;
+  DockSitesCanBeMinimized.Enabled:=HasHeaders;
 end;
 
 constructor TAnchorDockOptionsFrame.Create(TheOwner: TComponent);
@@ -356,6 +358,7 @@
   TheSettings.HeaderFilled:=FilledHeadersCheckBox.Checked;
   TheSettings.HeaderStyle:=TADHeaderStyle(HeaderStyleComboBox.ItemIndex);
   TheSettings.HeaderHighlightFocused:=HighlightFocusedCheckBox.Checked;
+  TheSettings.DockSitesCanBeMinimized:=DockSitesCanBeMinimized.Checked;
 end;
 
 procedure TAnchorDockOptionsFrame.LoadFromSettings(
@@ -429,6 +432,10 @@
   HighlightFocusedCheckBox.Checked:=TheSettings.HeaderHighlightFocused;
   HighlightFocusedCheckBox.Caption:=adrsHighlightFocused;
   HighlightFocusedCheckBox.Hint:=adrsHighlightFocusedHint;
+
+  DockSitesCanBeMinimized.Checked:=TheSettings.DockSitesCanBeMinimized;
+  DockSitesCanBeMinimized.Caption:=adrsDockSitesCanBeMinimized;
+  DockSitesCanBeMinimized.Hint:=adrsDockSitesCanBeMinimizedHint;
 end;
 
 end.
Index: components/anchordocking/anchordockpanel.pas
===================================================================
--- components/anchordocking/anchordockpanel.pas	(revision 59428)
+++ components/anchordocking/anchordockpanel.pas	(working copy)
@@ -55,7 +55,7 @@
   begin
 
     LayoutNode.NodeType:=adltnControl;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,false);
     LayoutNode.Name:={OneControl.}Name;
 
     TAnchorDockHostSite(OneControl).SaveLayout(LayoutTree,LayoutNode);
Index: components/anchordocking/anchordockstorage.pas
===================================================================
--- components/anchordocking/anchordockstorage.pas	(revision 59428)
+++ components/anchordocking/anchordockstorage.pas	(working copy)
@@ -64,6 +64,7 @@
     FTabPosition: TTabPosition;
     FWindowState: TWindowState;
     FControlLocation: TADLControlLocation;
+    FMinimized: Boolean;
     function GetAnchors(Site: TAnchorKind): string;
     function GetBottom: integer;
     function GetHeight: integer;
@@ -90,6 +91,7 @@
     procedure SetTop(const AValue: integer);
     procedure SetWidth(const AValue: integer);
     procedure SetWindowState(const AValue: TWindowState);
+    procedure SetMinimized(const AValue: boolean);
   public
     constructor Create;
     destructor Destroy; override;
@@ -96,7 +98,7 @@
     procedure Clear;
     function IsEqual(Node: TAnchorDockLayoutTreeNode): boolean;
     procedure Assign(Node: TAnchorDockLayoutTreeNode); overload;
-    procedure Assign(AControl: TControl; OverrideBoundsRect: Boolean=false); overload;
+    procedure Assign(AControl: TControl; OverrideBoundsRect: Boolean; AMinimized: Boolean); overload;
     procedure LoadFromConfig(Config: TConfigStorage); overload;
     procedure LoadFromConfig(Path: string; Config: TRttiXMLConfig); overload;
     procedure SaveToConfig(Config: TConfigStorage); overload;
@@ -106,7 +108,7 @@
     procedure CheckConsistency; virtual;
 
     // simplifying
-    procedure Simplify(ExistingNames: TStrings);
+    procedure Simplify(ExistingNames: TStrings; ParentMinimized:boolean);
     procedure DeleteNode(ChildNode: TAnchorDockLayoutTreeNode);
     function FindNodeBoundSplitter(ChildNode: TAnchorDockLayoutTreeNode;
                                    Side: TAnchorKind): TAnchorDockLayoutTreeNode;
@@ -135,6 +137,7 @@
     property Monitor: integer read FMonitor write SetMonitor;
     property HeaderPosition: TADLHeaderPosition read FHeaderPosition write SetHeaderPosition;
     property TabPosition: TTabPosition read FTabPosition write SetTabPosition;
+    property Minimized: Boolean read FMinimized write SetMinimized;
     function Count: integer;
     function IsSplitter: boolean;
     function IsRootWindow: boolean;
@@ -988,6 +991,13 @@
   IncreaseChangeStamp;
 end;
 
+procedure TAnchorDockLayoutTreeNode.SetMinimized(const AValue: boolean);
+begin
+  if FMinimized=AValue then exit;
+  FMinimized:=AValue;
+  IncreaseChangeStamp;
+end;
+
 procedure TAnchorDockLayoutTreeNode.SetTop(const AValue: integer);
 begin
   if Top=AValue then exit;
@@ -1084,6 +1094,7 @@
   BoundSplitterPos:=Node.BoundSplitterPos;
   WorkAreaRect:=Node.WorkAreaRect;
   Monitor:=Node.Monitor;
+  Minimized:=Node.Minimized;
   for a:=low(TAnchorKind) to high(TAnchorKind) do
     Anchors[a]:=Node.Anchors[a];
   while Count>Node.Count do Nodes[Count-1].Free;
@@ -1098,9 +1109,10 @@
   end;
 end;
 
-procedure TAnchorDockLayoutTreeNode.Assign(AControl: TControl; OverrideBoundsRect: Boolean=false);
+procedure TAnchorDockLayoutTreeNode.Assign(AControl: TControl; OverrideBoundsRect: Boolean; AMinimized: Boolean);
 var
   AnchorControl: TControl;
+  ParentForm:TCustomForm;
   a: TAnchorKind;
 begin
   Name:=AControl.Name;
@@ -1109,12 +1121,18 @@
   else
     BoundsRect:=AControl.BoundsRect;
   Align:=AControl.Align;
+  Minimized:=AMinimized;
   if (AControl.Parent=nil) and (AControl is TCustomForm) then begin
     WindowState:=TCustomForm(AControl).WindowState;
     Monitor:=TCustomForm(AControl).Monitor.MonitorNum;
     WorkAreaRect:=TCustomForm(AControl).Monitor.WorkareaRect;
-  end else
-    WindowState:=GetParentForm(AControl).WindowState;
+  end else begin
+    ParentForm:=GetParentForm(AControl);
+    if assigned(ParentForm) then
+      WindowState:=ParentForm.WindowState
+    else
+      WindowState:=wsNormal;
+  end;
   if AControl is TCustomTabControl then
     TabPosition:=TCustomTabControl(AControl).TabPosition
   else
@@ -1137,6 +1155,7 @@
   Clear;
   Name:=Config.GetValue('Name','');
   NodeType:=NameToADLTreeNodeType(Config.GetValue('Type',ADLTreeNodeTypeNames[adltnNone]));
+  Minimized:=Config.GetValue('Minimized',false);
   Left:=Config.GetValue('Bounds/Left',0);
   Top:=Config.GetValue('Bounds/Top',0);
   Width:=Config.GetValue('Bounds/Width',0);
@@ -1171,6 +1190,7 @@
   Clear;
   Name:=Config.GetValue(Path+'Name','');
   NodeType:=NameToADLTreeNodeType(Config.GetValue(Path+'Type',ADLTreeNodeTypeNames[adltnNone]));
+  Minimized:=Config.GetValue(Path+'Minimized',false);
   Left:=Config.GetValue(Path+'Bounds/Left',0);
   Top:=Config.GetValue(Path+'Bounds/Top',0);
   Width:=Config.GetValue(Path+'Bounds/Width',0);
@@ -1219,6 +1239,7 @@
                                           ADLHeaderPositionNames[adlhpAuto]);
   Config.SetDeleteValue('Header/TabPosition',ADLTabPostionNames[TabPosition],
                                              ADLTabPostionNames[tpTop]);
+  Config.SetDeleteValue('Minimized',Minimized,False);
   Config.SetDeleteValue('Monitor',Monitor,0);
   Config.SetDeleteValue('ChildCount',Count,0);
   for i:=1 to Count do begin
@@ -1252,6 +1273,7 @@
                                                ADLHeaderPositionNames[adlhpAuto]);
   Config.SetDeleteValue(Path+'Header/TabPosition',ADLTabPostionNames[TabPosition],
                                                   ADLTabPostionNames[tpTop]);
+  Config.SetDeleteValue(Path+'Minimized',Minimized,False);
   Config.SetDeleteValue(Path+'Monitor',Monitor,0);
   Config.SetDeleteValue(Path+'ChildCount',Count,0);
   for i:=1 to Count do
@@ -1397,7 +1419,7 @@
   end;
 end;
 
-procedure TAnchorDockLayoutTreeNode.Simplify(ExistingNames: TStrings);
+procedure TAnchorDockLayoutTreeNode.Simplify(ExistingNames: TStrings; ParentMinimized:boolean);
 { Simplification rules:
    1. Control nodes without existing name are deleted.
    2. Empty layouts and pages are deleted
@@ -1406,16 +1428,18 @@
 var
   i: Integer;
   ChildNode: TAnchorDockLayoutTreeNode;
+  NodeMinimized:boolean;
 begin
   // simplify children
   i:=Count-1;
   while i>=0 do begin
     ChildNode:=Nodes[i];
-    ChildNode.Simplify(ExistingNames);
+    NodeMinimized:=ParentMinimized or ChildNode.Minimized;
+    ChildNode.Simplify(ExistingNames,NodeMinimized);
 
     if (ChildNode.NodeType=adltnControl) then begin
       // leaf node => check if there is a control
-      if (ChildNode.Name='') or (ExistingNames.IndexOf(ChildNode.Name)<0) then
+      if (ChildNode.Name='') or ((ExistingNames.IndexOf(ChildNode.Name)<0) and (not NodeMinimized)) then
         DeleteNode(ChildNode);
     end else if ChildNode.IsSplitter then begin
       // splitter
@@ -1424,7 +1448,7 @@
         ChildNode[0].Free;
     end else if ChildNode.NodeType=adltnCustomSite then begin
       // custom dock site
-    end else if ChildNode.Count=0 then begin
+    end else if (ChildNode.Count=0)and(not NodeMinimized) then begin
       // inner node without child => delete
       DeleteNode(ChildNode);
     end else if (ChildNode.Count=1)
Index: components/anchordocking/anchordockstr.pas
===================================================================
--- components/anchordocking/anchordockstr.pas	(revision 59428)
+++ components/anchordocking/anchordockstr.pas	(working copy)
@@ -8,6 +8,7 @@
 
 resourcestring
   adrsClose = 'Close';
+  adrsMinimize = 'Minimize';
   adrsQuit = 'Quit %s';
   adrsTabPosition = 'Tab position';
   adrsMovePageRight = 'Move page right';
@@ -82,6 +83,8 @@
   adrsFilledHeadersHint = 'Fill headers of docked controls';
   adrsHighlightFocused = 'Highlight focused';
   adrsHighlightFocusedHint = 'Highlight header of focused docked control';
+  adrsDockSitesCanBeMinimized = 'Dock sites can be minimized';
+  adrsDockSitesCanBeMinimizedHint = 'Dock sites can be minimized';
 
 implementation
 
Index: components/anchordocking/design/anchordesktopoptions.pas
===================================================================
--- components/anchordocking/design/anchordesktopoptions.pas	(revision 59428)
+++ components/anchordocking/design/anchordesktopoptions.pas	(working copy)
@@ -272,7 +272,7 @@
         // custom dock site
         LayoutNode:=FTree.NewNode(FTree.Root);
         LayoutNode.NodeType:=adltnCustomSite;
-        LayoutNode.Assign(AForm);
+        LayoutNode.Assign(AForm,false,false);
         // can have one normal dock site
         Site:=TAnchorDockManager(AForm.DockManager).GetChildSite;
         if Site<>nil then begin
@@ -287,7 +287,7 @@
         raise EAnchorDockLayoutError.Create('invalid root control for save: '+DbgSName(AControl));
     end;
     // remove invisible controls
-    FTree.Root.Simplify(VisibleControls);
+    FTree.Root.Simplify(VisibleControls,false);
   finally
     VisibleControls.Free;
     SavedSites.Free;

Andrey Zubarev

2018-11-14 21:21

reporter   ~0111977

See anchordocking_minimize_docksite10.patch

1. I unminimize sites which came the mouse, it's not a very good solution, but so far I haven't been able to do better
2,3,4 Fixed

Michl

2018-11-14 22:26

developer  

Test3.png (1,219 bytes)   
Test3.png (1,219 bytes)   

Michl

2018-11-14 22:44

developer   ~0111981

Last edited: 2018-11-14 22:53

View 3 revisions

Thank you! A lot is working, but I found some things:

1. See picture Test3.png. It seems, the space for the buttons is correct but the buttons itself is half the size.

2.
- load layout test.xml (don't maximize MiniIDE)
- minimize Source Editor 1
- move Messages right of minimized Source Editor 1, but don't dock it
- move Messages out of MiniIDE and release mouse
--> Messages is further activated as docking site, with no mouse pressed
- pressing ESC, Messages is moved to coordinates 0, 0

3.
- load layout test2.xml
- minimize Messages
- move Project Inspector on Messages
--> Project Inspector is docked right from Messages without releasing of mouse

4. (do the same steps as in 3.)
- load layout test2.xml
- minimize Messages
- move Project Inspector on Messages
- move Project Inspector back to FPDoc Editor
--> Messages has no minimize button anymore

Michl

2018-11-14 22:48

developer  

test2.xml (2,636 bytes)   
<?xml version="1.0" encoding="utf-8"?>
<CONFIG>
  <MainConfig>
    <Nodes ChildCount="1">
      <Item1 Name="MainIDE" Type="CustomSite" ChildCount="1" WindowState="Maximized">
        <Bounds Top="-4" Left="-4" Width="1920" Height="1012">
          <WorkArea>
            <Rect Right="1920" Bottom="1036"/>
          </WorkArea>
        </Bounds>
        <Item1 Name="AnchorDockSite3" Type="Layout" ChildCount="7" WindowState="Maximized">
          <Bounds Top="80" Width="1920" Height="908" SplitterPos="75"/>
          <Anchors Align="Bottom"/>
          <Item1 Name="ObjectInspector" Type="Control" WindowState="Maximized">
            <Bounds Width="644" Height="908"/>
            <Anchors Right="AnchorDockSplitter2"/>
          </Item1>
          <Item2 Name="AnchorDockSplitter2" Type="SplitterVertical" WindowState="Maximized">
            <Bounds Left="644" Width="4" Height="908"/>
          </Item2>
          <Item3 Name="SourceEditor1" Type="Control" WindowState="Maximized">
            <Bounds Left="648" Width="779" Height="638"/>
            <Anchors Left="AnchorDockSplitter2" Right="AnchorDockSplitter4" Bottom="AnchorDockSplitter3"/>
          </Item3>
          <Item4 Name="AnchorDockSplitter3" Type="SplitterHorizontal" WindowState="Maximized">
            <Bounds Top="638" Left="648" Width="779" Height="4"/>
            <Anchors Left="AnchorDockSplitter2" Right="AnchorDockSplitter4"/>
          </Item4>
          <Item5 Name="AnchorDockSite4" Type="Pages" ChildCount="2" WindowState="Maximized">
            <Bounds Top="642" Left="648" Width="779" Height="266"/>
            <Anchors Top="AnchorDockSplitter3" Left="AnchorDockSplitter2" Right="AnchorDockSplitter4"/>
            <Item1 Name="FPDocEditor" Type="Control" WindowState="Maximized">
              <Bounds Width="320" Height="240"/>
              <Anchors Align="Client"/>
            </Item1>
            <Item2 Name="ProjectInspector" Type="Control" WindowState="Maximized">
              <Bounds Width="762" Height="240"/>
              <Anchors Align="Client"/>
            </Item2>
          </Item5>
          <Item6 Name="AnchorDockSplitter4" Type="SplitterVertical" WindowState="Maximized">
            <Bounds Left="1427" Width="4" Height="908"/>
          </Item6>
          <Item7 Name="Messages" Type="Control" WindowState="Maximized">
            <Bounds Left="1431" Width="489" Height="908"/>
            <Anchors Left="AnchorDockSplitter4"/>
          </Item7>
        </Item1>
      </Item1>
    </Nodes>
  </MainConfig>
  <Settings DockSitecCanBeMinimized="True"/>
</CONFIG>
test2.xml (2,636 bytes)   

Andrey Zubarev

2018-11-15 13:48

reporter   ~0111984

1. Themes.GetDetailSize without aero return 11,11 for twSmallClose (13,13 with aero). Therefore the screenshot is correct. I refused buttons.align and buttons became square.

2. This is separate DragManager issue

3. Yes, I will fix it soon

4. Because mouse capture changed
>>1. I unminimize sites which came the mouse, it's not a very good solution, but so far I haven't been able to do better
I will look for another solution

Andrey Zubarev

2018-11-18 19:09

reporter  

anchordocking_minimize_docksite11.patch (78,809 bytes)   
Index: components/anchordocking/anchordocking.pas
===================================================================
--- components/anchordocking/anchordocking.pas	(revision 59428)
+++ components/anchordocking/anchordocking.pas	(working copy)
@@ -109,6 +109,31 @@
 const ADAutoSizingReason = 'TAnchorDockMaster Delayed';
 {$ENDIF}
 
+const EmptyMouseTimeStartX=low(Integer);
+      MouseNoMoveDelta=5;
+      MouseNoMoveTime=500;
+      HideOverlappingFormByMouseLoseTime=500;
+      ButtonBorderSpacingAround=4;
+      OppositeAnchorKind2Align: array[TAnchorKind] of TAlign = (
+        alBottom, // akTop,
+        alRight,  // akLeft,
+        alLeft,   // akRight,
+        alTop     // akBottom
+        );
+      {AnchorKind2Align: array[TAnchorKind] of TAlign = (
+        alTop,  // akTop,
+        alLeft, // akLeft,
+        alRight,// akRight,
+        alBottom// akBottom
+        );}
+      OppositeAnchorKind2TADLHeaderPosition: array[TAnchorKind] of TADLHeaderPosition = (
+        adlhpBottom, // akTop,
+        adlhpRight,  // akLeft,
+        adlhpLeft,   // akRight,
+        adlhpTop     // akBottom
+        );
+
+
 type
   TAnchorDockHostSite = class;
 
@@ -123,6 +148,14 @@
            PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
   end;
 
+  TAnchorDockMinimizeButton = class(TCustomSpeedButton)
+  protected
+    function GetDrawDetails: TThemedElementDetails; override;
+    procedure CalculatePreferredSize(var PreferredWidth,
+           PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
+  end;
+
+
   { TAnchorDockHeader
     The panel of a TAnchorDockHostSite containing the close button and the
     caption when the form is docked. The header can be shown at any of the four
@@ -133,9 +166,13 @@
   TAnchorDockHeader = class(TCustomPanel)
   private
     FCloseButton: TCustomSpeedButton;
+    FMinimizeButton: TCustomSpeedButton;
     FHeaderPosition: TADLHeaderPosition;
     fFocused:Boolean;
+    fUseTimer:Boolean;
+    FMouseTimeStartX,FMouseTimeStartY:Integer;
     procedure CloseButtonClick(Sender: TObject);
+    procedure MinimizeButtonClick(Sender: TObject);
     procedure HeaderPositionItemClick(Sender: TObject);
     procedure UndockButtonClick(Sender: TObject);
     procedure MergeButtonClick(Sender: TObject);
@@ -147,6 +184,11 @@
           PreferredHeight: integer; WithThemeSpace: Boolean); override;
     procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X,
              Y: Integer); override;
+    procedure MouseMove(Shift: TShiftState; X,Y: Integer); override;
+    procedure MouseLeave;  override;
+    procedure StartMouseNoMoveTimer(X, Y: Integer);
+    procedure StopMouseNoMoveTimer;
+    procedure DoMouseNoMoveTimer(Sender: TObject);
     procedure UpdateHeaderControls;
     procedure SetAlign(Value: TAlign); override;
     procedure DoOnShowHint(HintInfo: PHintInfo); override;
@@ -154,6 +196,7 @@
   public
     constructor Create(TheOwner: TComponent); override;
     property CloseButton: TCustomSpeedButton read FCloseButton;
+    property MinimizeButton: TCustomSpeedButton read FMinimizeButton;
     property HeaderPosition: TADLHeaderPosition read FHeaderPosition write SetHeaderPosition;
     property BevelOuter default bvNone;
   end;
@@ -190,6 +233,7 @@
     procedure SetBoundsKeepDockBounds(ALeft, ATop, AWidth, AHeight: integer); // movement for scaling keeps the DockBounds
     function SideAnchoredControlCount(Side: TAnchorKind): integer;
     function HasAnchoredControls: boolean;
+    function GetSpliterBoundsWithUnminimizedDockSites:TRect;
     procedure SaveLayout(LayoutNode: TAnchorDockLayoutTreeNode);
     function HasOnlyOneSibling(Side: TAnchorKind; MinPos, MaxPos: integer): TControl;
     property DockRestoreBounds: TRect read FDockRestoreBounds write FDockRestoreBounds;
@@ -241,6 +285,14 @@
   end;
   TAnchorDockPageControlClass = class of TAnchorDockPageControl;
 
+
+  TAnchorDockOverlappingForm = class(TCustomForm)
+  public
+    AnchorDockHostSite:TAnchorDockHostSite;
+    Panel:TPanel;
+    constructor CreateNew(AOwner: TComponent; Num: Integer = 0); override;
+  end;
+
   { TAnchorDockHostSite
     This form is the dockhostsite for all controls.
     When docked together they build a tree structure with the docked controls
@@ -262,7 +314,10 @@
     FPages: TAnchorDockPageControl;
     FSiteType: TAnchorDockHostSiteType;
     FBoundSplitter: TAnchorDockSplitter;
-    fUpdateLayout: integer;
+    fUpdateLayout: Integer;
+    FMinimized: Boolean;
+    fMinimization: Boolean;
+    FMinimizedControl: TControl;
     procedure SetHeaderSide(const AValue: TAnchorKind);
   protected
     procedure DoEnter; override;
@@ -319,6 +374,10 @@
     destructor Destroy; override;
     function CloseQuery: boolean; override;
     function CloseSite: boolean; virtual;
+    procedure MinimizeSite; virtual;
+    procedure AsyncMinimizeSite(Data: PtrInt);
+    procedure ShowMinimizedControl;
+    procedure HideMinimizedControl;
     procedure RemoveControl(AControl: TControl); override;
     procedure InsertControl(AControl: TControl; Index: integer); override;
     procedure GetSiteInfo(Client: TControl; var InfluenceRect: TRect;
@@ -329,6 +388,7 @@
     procedure UpdateDockCaption(Exclude: TControl = nil); override;
     procedure UpdateHeaderAlign;
     procedure UpdateHeaderShowing;
+    function CanBeMinimized(out Splitter: TAnchorDockSplitter; out SplitterAnchorKind:TAnchorKind):boolean;
     procedure BeginUpdateLayout;
     procedure EndUpdateLayout;
     function UpdatingLayout: boolean;
@@ -337,6 +397,7 @@
     procedure SaveLayout(LayoutTree: TAnchorDockLayoutTree;
                          LayoutNode: TAnchorDockLayoutTreeNode);
     property DockRestoreBounds: TRect read FDockRestoreBounds write FDockRestoreBounds;
+    function GetDockEdge(const MousePos: TPoint): TAlign; override;
 
     property HeaderSide: TAnchorKind read FHeaderSide write SetHeaderSide;
     property Header: TAnchorDockHeader read FHeader;
@@ -431,6 +492,7 @@
     FShowHeader: boolean;
     FShowHeaderCaption: boolean;
     FSplitterWidth: integer;
+    FDockSitecCanBeMinimized: boolean;
     procedure SetAllowDragging(AValue: boolean);
     procedure SetDockOutsideMargin(AValue: integer);
     procedure SetDockParentMargin(AValue: integer);
@@ -448,6 +510,7 @@
     procedure SetHeaderFlatten(AValue: boolean);
     procedure SetHeaderFilled(AValue: boolean);
     procedure SetHeaderHighlightFocused(AValue: boolean);
+    procedure SetDockSitecCanBeMinimized(AValue: boolean);
   public
     property DragTreshold: integer read FDragTreshold write SetDragTreshold;
     property DockOutsideMargin: integer read FDockOutsideMargin write SetDockOutsideMargin;
@@ -466,6 +529,7 @@
     property HeaderFlatten: boolean read FHeaderFlatten write SetHeaderFlatten;
     property HeaderFilled: boolean read FHeaderFilled write SetHeaderFilled;
     property HeaderHighlightFocused: boolean read FHeaderHighlightFocused write SetHeaderHighlightFocused;
+    property DockSitesCanBeMinimized: boolean read FDockSitecCanBeMinimized write SetDockSitecCanBeMinimized;
     procedure IncreaseChangeStamp; inline;
     property ChangeStamp: integer read FChangeStamp;
     procedure LoadFromConfig(Config: TConfigStorage); overload;
@@ -502,6 +566,7 @@
     FHeaderFlatten: boolean;
     FHeaderFilled: boolean;
     FHeaderHighlightFocused: boolean;
+    FDockSitesCanBeMinimized: boolean;
     FIdleConnected: Boolean;
     FManagerClass: TAnchorDockManagerClass;
     FOnCreateControl: TADCreateControlEvent;
@@ -531,6 +596,7 @@
     fPopupMenu: TPopupMenu;
     // Used by RestoreLayout:
     WorkArea, SrcWorkArea: TRect;
+    FOverlappingForm:TAnchorDockOverlappingForm;
 
     function GetControls(Index: integer): TControl;
     function GetLocalizedHeaderHint: string;
@@ -541,6 +607,9 @@
     function GetNodeSite(Node: TAnchorDockLayoutTreeNode): TAnchorDockHostSite;
     procedure MapTreeToControls(Tree: TAnchorDockLayoutTree);
     function RestoreLayout(Tree: TAnchorDockLayoutTree; Scale: boolean): boolean;
+    procedure SetMinimizedState(Tree: TAnchorDockLayoutTree);
+    procedure UpdateHeaders;
+    procedure SetnodeMinimizedState(ANode: TAnchorDockLayoutTreeNode);
     procedure EnableAllAutoSizing;
     procedure ClearLayoutProperties(AControl: TControl; NewAlign: TAlign = alClient);
     procedure PopupMenuPopup(Sender: TObject);
@@ -561,6 +630,7 @@
     procedure SetHeaderFlatten(AValue: boolean);
     procedure SetHeaderFilled(AValue: boolean);
     procedure SetHeaderHighlightFocused(AValue: boolean);
+    procedure SetDockSitesCanBeMinimized(AValue: boolean);
 
     procedure SetShowMenuItemShowHeader(AValue: boolean);
     procedure SetupSite(Site: TWinControl; ANode: TAnchorDockLayoutTreeNode;
@@ -584,8 +654,12 @@
     procedure SetHideHeaderCaptionFloatingControl(const AValue: boolean);
     procedure SetSplitterWidth(const AValue: integer);
     procedure OnIdle(Sender: TObject; var Done: Boolean);
+    procedure StartHideOverlappingTimer;
+    procedure StopHideOverlappingTimer;
     procedure AsyncSimplify({%H-}Data: PtrInt);
   public
+    procedure ShowOverlappingForm;
+    procedure HideOverlappingForm(Sender: TObject);
     constructor Create(AOwner: TComponent); override;
     destructor Destroy; override;
     function FullRestoreLayout(Tree: TAnchorDockLayoutTree; Scale: Boolean): Boolean;
@@ -680,6 +754,7 @@
     property HeaderFlatten: boolean read FHeaderFlatten write SetHeaderFlatten default true;
     property HeaderFilled: boolean read FHeaderFilled write SetHeaderFilled default true;
     property HeaderHighlightFocused: boolean read FHeaderHighlightFocused write SetHeaderHighlightFocused default false;
+    property DockSitesCanBeMinimized: boolean read FDockSitesCanBeMinimized write SetDockSitesCanBeMinimized default false;
 
     property SplitterWidth: integer read FSplitterWidth write SetSplitterWidth default 4;
     property ScaleOnResize: boolean read FScaleOnResize write SetScaleOnResize default true; // scale children when resizing a site
@@ -698,8 +773,14 @@
 
 var
   DockMaster: TAnchorDockMaster = nil;
+  DockTimer: TTimer = nil;
 
+  PreferredButtonWidth:integer=-1;
+  PreferredButtonHeight:integer=-1;
+
+
 const
+  HardcodedButtonSize:integer=13;
   ADHeaderStyleNames: array[TADHeaderStyle] of string = (
     'Frame3D',
     'Line',
@@ -970,6 +1051,27 @@
   end;
 end;
 
+function CountAndReturnOnlyOneMinimizedAnchoredControls(Control: TControl; Side: TAnchorKind): TAnchorDockHostSite;
+var
+  i,Counter: Integer;
+  Neighbour: TControl;
+begin
+  Counter:=0;
+  for i:=0 to Control.AnchoredControlCount-1 do begin
+    Neighbour:=Control.AnchoredControls[i];
+    if Neighbour.Visible then
+    if Neighbour is TAnchorDockHostSite then
+    if (OppositeAnchor[Side] in Neighbour.Anchors)
+    and (Neighbour.AnchorSide[OppositeAnchor[Side]].Control=Control) then begin
+      inc(Counter);
+      result:=TAnchorDockHostSite(Neighbour);
+    end;
+  end;
+  if (Counter=1)and(result is TAnchorDockHostSite)and((result as TAnchorDockHostSite).FMinimized) then
+  else
+    result:=Nil;
+end;
+
 function NeighbourCanBeShrinked(EnlargeControl, Neighbour: TControl;
   Side: TAnchorKind): boolean;
 { returns true if Neighbour can be shrinked on the opposite side of Side
@@ -1361,6 +1463,13 @@
   IncreaseChangeStamp;
 end;
 
+procedure TAnchorDockSettings.SetDockSitecCanBeMinimized(AValue: boolean);
+begin
+  if FDockSitecCanBeMinimized=AValue then Exit;
+  FDockSitecCanBeMinimized:=AValue;
+  IncreaseChangeStamp;
+end;
+
 procedure TAnchorDockSettings.Assign(Source: TAnchorDockSettings);
 begin
   FAllowDragging := Source.FAllowDragging;
@@ -1381,6 +1490,7 @@
   FShowHeaderCaption := Source.FShowHeaderCaption;
   FSplitterWidth := Source.FSplitterWidth;
   FHeaderHighlightFocused:=Source.FHeaderHighlightFocused;
+  FDockSitecCanBeMinimized:=Source.FDockSitecCanBeMinimized;
 end;
 
 procedure TAnchorDockSettings.IncreaseChangeStamp;
@@ -1407,6 +1517,7 @@
   HeaderFlatten:=Config.GetValue('HeaderFlatten',true);
   HeaderFilled:=Config.GetValue('HeaderFilled',true);
   HeaderHighlightFocused:=Config.GetValue('HeaderHighlightFocused',False);
+  DockSitesCanBeMinimized:=Config.GetValue('DockSitecCanBeMinimized',False);
   Config.UndoAppendBasePath;
 end;
 
@@ -1429,6 +1540,7 @@
   Config.SetDeleteValue(Path+'HeaderFlatten',HeaderFlatten,true);
   Config.SetDeleteValue(Path+'HeaderFilled',HeaderFilled,true);
   Config.SetDeleteValue(Path+'HeaderHighlightFocused',HeaderHighlightFocused,False);
+  Config.SetDeleteValue(Path+'DockSitecCanBeMinimized',DockSitesCanBeMinimized,False);
 end;
 
 procedure TAnchorDockSettings.SaveToConfig(Config: TConfigStorage);
@@ -1450,6 +1562,7 @@
   Config.SetDeleteValue('HeaderFlatten',HeaderFlatten,true);
   Config.SetDeleteValue('HeaderFilled',HeaderFilled,true);
   Config.SetDeleteValue('HeaderHighlightFocused',HeaderHighlightFocused,False);
+  Config.SetDeleteValue('DockSitecCanBeMinimized',DockSitesCanBeMinimized,False);
   Config.UndoAppendBasePath;
 end;
 
@@ -1472,6 +1585,7 @@
       and (HeaderFlatten=Settings.HeaderFlatten)
       and (HeaderFilled=Settings.HeaderFilled)
       and (HeaderHighlightFocused=Settings.HeaderHighlightFocused)
+      and (DockSitesCanBeMinimized=Settings.DockSitesCanBeMinimized)
       ;
 end;
 
@@ -1494,6 +1608,7 @@
   HeaderFlatten:=Config.GetValue(Path+'HeaderFlatten',true);
   HeaderFilled:=Config.GetValue(Path+'HeaderFilled',true);
   HeaderHighlightFocused:=Config.GetValue(Path+'HeaderHighlightFocused',False);
+  DockSitesCanBeMinimized:=Config.GetValue(Path+'DockSitecCanBeMinimized',False);
 end;
 
 { TAnchorDockMaster }
@@ -2021,6 +2136,8 @@
     aHostSite:=TAnchorDockHostSite(Site);
     aHostSite.Header.HeaderPosition:=ANode.HeaderPosition;
     aHostSite.DockRestoreBounds:=NewBounds;
+    //aHostSite.FMinimized:=ANode.Minimized;
+    //we update aHostSite.FMinimized in TAnchorDockMaster.SetMinimizedState
     if (ANode.NodeType<>adltnPages) and (aHostSite.Pages<>nil) then
       aHostSite.FreePages;
   end;
@@ -2040,6 +2157,25 @@
   fTreeNameToDocker[Node.Name]:=Result;
 end;
 
+procedure TAnchorDockMaster.SetNodeMinimizedState(ANode: TAnchorDockLayoutTreeNode);
+var
+  HostSite:TAnchorDockHostSite;
+  i:integer;
+begin
+  HostSite:=GetNodeSite(ANode);
+  if Assigned(HostSite) then
+    if HostSite.FMinimized<>ANode.Minimized then
+      Application.QueueAsyncCall(@HostSite.AsyncMinimizeSite,0);
+      //HostSite.MinimizeSite;
+  for i:=0 to ANode.Count-1 do
+    SetnodeMinimizedState(ANode.Nodes[i]);
+end;
+
+procedure TAnchorDockMaster.SetMinimizedState(Tree: TAnchorDockLayoutTree);
+begin
+  SetnodeMinimizedState(Tree.Root);
+end;
+
 function TAnchorDockMaster.RestoreLayout(Tree: TAnchorDockLayoutTree;
   Scale: boolean): boolean;
 
@@ -2193,7 +2329,7 @@
       try
         SetupSite(Site,ANode,AParent);
         Site.FSiteType:=adhstPages;
-        Site.Header.Parent:=nil;
+        //Site.Header.Parent:=nil;
         if Site.Pages=nil then
           Site.CreatePages;
         for i:=0 to ANode.Count-1 do begin
@@ -2358,7 +2494,7 @@
       debugln(ControlNames.Text);
       {$ENDIF}
       // if some forms/controls could not be created the layout needs to be adapted
-      Tree.Root.Simplify(ControlNames);
+      Tree.Root.Simplify(ControlNames,false);
 
       // reuse existing sites to reduce flickering
       MapTreeToControls(Tree);
@@ -2368,6 +2504,7 @@
 
       // create sites, move controls
       RestoreLayout(Tree,Scale);
+      SetMinimizedState(Tree);
     finally
       EndUpdate;
     end;
@@ -2422,11 +2559,54 @@
   OptionsChanged;
 end;
 
+procedure TAnchorDockMaster.StartHideOverlappingTimer;
+begin
+  if not DockTimer.Enabled then begin
+    DockTimer.Interval:=HideOverlappingFormByMouseLoseTime;
+    DockTimer.OnTimer:=@HideOverlappingForm;
+    DockTimer.Enabled:=true;
+  end;
+end;
+
+procedure TAnchorDockMaster.StopHideOverlappingTimer;
+begin
+  DockTimer.Enabled:=False;
+  DockTimer.Interval:=0;
+  DockTimer.OnTimer:=nil;
+end;
+
+function IsParentControl(aParent, aControl: TControl): boolean;
+begin
+  while (aControl <> nil) and (aControl.Parent <> nil) do
+  begin
+    if (aControl=aParent) then
+      exit(true);
+    aControl := aControl.Parent;
+  end;
+  result:=aControl=aParent;
+end;
+
+
 procedure TAnchorDockMaster.OnIdle(Sender: TObject; var Done: Boolean);
+var
+  MousePos: TPoint;
+  Bounds:Trect;
 begin
   if Done then ;
-  IdleConnected:=false;
   Restoring:=false;
+  if FOverlappingForm=nil then
+    IdleConnected:=false
+  else begin
+    GetCursorPos(MousePos);
+    Bounds.TopLeft:=FOverlappingForm.ClientToScreen(point(0,0));
+    Bounds.BottomRight:=FOverlappingForm.ClientToScreen(point(FOverlappingForm.Width,FOverlappingForm.Height));
+    if not IsParentControl(FOverlappingForm, GetCaptureControl) then begin
+      if not PtInRect(Bounds,MousePos) then
+          StartHideOverlappingTimer
+        else
+          StopHideOverlappingTimer;
+    end;
+  end;
 end;
 
 procedure TAnchorDockMaster.AsyncSimplify(Data: PtrInt);
@@ -2514,6 +2694,18 @@
   InvalidateHeaders;
 end;
 
+procedure TAnchorDockMaster.SetDockSitesCanBeMinimized(AValue: boolean);
+var
+  i:integer;
+  Site: TAnchorDockHostSite;
+begin
+  if FDockSitesCanBeMinimized=AValue then Exit;
+  FDockSitesCanBeMinimized:=AValue;
+  UpdateHeaders;
+  InvalidateHeaders;
+  EnableAllAutoSizing;
+  OptionsChanged;
+end;
 procedure TAnchorDockMaster.SetScaleOnResize(AValue: boolean);
 begin
   if FScaleOnResize=AValue then Exit;
@@ -2598,6 +2790,9 @@
     if (Site.Header<>nil) then begin
       DisableControlAutoSizing(Site);
       Site.UpdateHeaderShowing;
+      if Site.fminimized then
+        if not AValue then
+          site.MinimizeSite;
     end;
   end;
   EnableAllAutoSizing;
@@ -2668,6 +2863,20 @@
     EnableAllAutoSizing;
 end;
 
+procedure TAnchorDockMaster.ShowOverlappingForm;
+begin
+  FOverlappingForm.Show;
+  IdleConnected:=true;
+end;
+
+procedure TAnchorDockMaster.HideOverlappingForm(Sender: TObject);
+begin
+  StopHideOverlappingTimer;
+  FOverlappingForm.Hide;
+  FOverlappingForm.AnchorDockHostSite.HideMinimizedControl;
+  IdleConnected:=false;
+end;
+
 constructor TAnchorDockMaster.Create(AOwner: TComponent);
 begin
   inherited Create(AOwner);
@@ -2698,14 +2907,14 @@
   FPageClass:=TAnchorDockPage;
   FRestoreLayouts:=TAnchorDockRestoreLayouts.Create;
   FHeaderHighlightFocused:=false;
+  FDockSitesCanBeMinimized:=false;
+  FOverlappingForm:=nil;
 end;
 
 destructor TAnchorDockMaster.Destroy;
 var
   AControl: TControl;
-  {$IFDEF VerboseAnchorDocking}
-  i: Integer;
-  {$ENDIF}
+  i, j: Integer;
 begin
   QueueSimplify:=false;
   FreeAndNil(FRestoreLayouts);
@@ -2727,6 +2936,12 @@
     debugln(['TAnchorDockMaster.Destroy ',i,'/',ComponentCount,' ',DbgSName(Components[i])]);
   end;
   {$ENDIF}
+  for i:=0 to ComponentCount-1 do begin
+    for j:=0 to ComponentCount-1 do begin
+      if i<>j then
+        TControl(Components[i]).RemoveAllHandlersOfObject(TControl(Components[j]));
+  end;
+  end;
   inherited Destroy;
 end;
 
@@ -2914,6 +3129,7 @@
       raise Exception.Create('TAnchorDockMaster.MakeDockable '+Format(
         adrsNotSupportedHasParent, [DbgSName(AControl), DbgSName(AControl)]));
     end;
+    site.UpdateHeaderShowing;
     if (Site<>nil) and Show then
       MakeVisible(Site,BringToFront);
   finally
@@ -3018,7 +3234,8 @@
   i:=Screen.CustomFormCount-1;
   while i>=0 do begin
     AForm:=GetParentForm(Screen.CustomForms[i]);
-    AForm.Hide;
+    if Assigned(AForm)then
+      AForm.Hide;
     i:=Min(i,Screen.CustomFormCount)-1;
   end;
 
@@ -3062,8 +3279,11 @@
   end;
 end;
 
-function GetParentFormOrDockPanel(Control: TControl): TCustomForm;
+function GetParentFormOrDockPanel(Control: TControl; TopForm:Boolean=true): TCustomForm;
+var
+  oldControl: TControl;
 begin
+  oldControl:=Control;
   while (Control <> nil) and (Control.Parent <> nil) do
   begin
     if (Control is TAnchorDockPanel) then
@@ -3076,6 +3296,18 @@
     Result := TCustomForm(Control)
   else
     Result := nil;
+  if not TopForm then begin
+    if Control is TAnchorDockPanel then
+      exit;
+    Control:=oldControl;
+    while (Control <> nil) and (Control.Parent <> nil) do
+    begin
+      Control := Control.Parent;
+      if (Control is TCustomForm) then
+        Break;
+    end;
+    Result := TCustomForm(Control);
+  end;
 end;
 
 procedure TAnchorDockMaster.SaveMainLayoutToTree(LayoutTree: TAnchorDockLayoutTree);
@@ -3088,12 +3320,12 @@
   AFormOrDockPanel: TWinControl;
   VisibleControls: TStringList;
 
-  procedure SaveFormOrDockPanel(theFormOrDockPanel: TWinControl; SaveChildren: boolean);
+  procedure SaveFormOrDockPanel(theFormOrDockPanel: TWinControl; SaveChildren: boolean; AMinimized:boolean);
   begin
     // custom dock site
     LayoutNode:=LayoutTree.NewNode(LayoutTree.Root);
     LayoutNode.NodeType:=adltnCustomSite;
-    LayoutNode.Assign(theFormOrDockPanel,theFormOrDockPanel is TAnchorDockPanel);
+    LayoutNode.Assign(theFormOrDockPanel,theFormOrDockPanel is TAnchorDockPanel,AMinimized);
     // can have one normal dock site
     if SaveChildren then
     begin
@@ -3124,7 +3356,7 @@
       debugln(['TAnchorDockMaster.SaveMainLayoutToTree AForm=',DbgSName(AFormOrDockPanel)]);
       DebugWriteChildAnchors(AFormOrDockPanel,true,true);
       if AFormOrDockPanel is TAnchorDockPanel then begin
-        SaveFormOrDockPanel(GetParentFormOrDockPanel(AFormOrDockPanel),{false}true);
+        SaveFormOrDockPanel(GetParentFormOrDockPanel(AFormOrDockPanel),true,false);
         //LayoutNode:=LayoutTree.NewNode(LayoutTree.Root);
         //TAnchorDockPanel(AFormOrDockPanel).SaveLayout(LayoutTree,LayoutNode);
       end else if AFormOrDockPanel is TAnchorDockHostSite then begin
@@ -3132,12 +3364,12 @@
         LayoutNode:=LayoutTree.NewNode(LayoutTree.Root);
         Site.SaveLayout(LayoutTree,LayoutNode);
       end else if IsCustomSite(AFormOrDockPanel) then begin
-        SaveFormOrDockPanel(AFormOrDockPanel,true);
+        SaveFormOrDockPanel(AFormOrDockPanel,true,false);
       end else
         raise EAnchorDockLayoutError.Create('invalid root control for save: '+DbgSName(AControl));
     end;
     // remove invisible controls
-    LayoutTree.Root.Simplify(VisibleControls);
+    LayoutTree.Root.Simplify(VisibleControls,false);
   finally
     VisibleControls.Free;
     SavedSites.Free;
@@ -3157,7 +3389,7 @@
     (AControl as TAnchorDockPanel).SaveLayout(LayoutTree,LayoutTree.Root);
   end else if IsCustomSite(AControl) then begin
     LayoutTree.Root.NodeType:=adltnCustomSite;
-    LayoutTree.Root.Assign(AControl);
+    LayoutTree.Root.Assign(AControl,false,false);
     // can have one normal dock site
     Site:=TAnchorDockManager(AControl.DockManager).GetChildSite;
     if Site<>nil then begin
@@ -3252,7 +3484,7 @@
       debugln(ControlNames.Text);
       {$ENDIF}
       // if some forms/controls could not be created the layout needs to be adapted
-      Tree.Root.Simplify(ControlNames);
+      Tree.Root.Simplify(ControlNames,false);
 
       // reuse existing sites to reduce flickering
       MapTreeToControls(Tree);
@@ -3262,6 +3494,7 @@
 
       // create sites, move controls
       RestoreLayout(Tree,Scale);
+      SetMinimizedState(Tree);
     finally
       EndUpdate;
     end;
@@ -3323,6 +3556,7 @@
   HeaderFlatten                    := Settings.HeaderFlatten;
   HeaderFilled                     := Settings.HeaderFilled;
   HeaderHighlightFocused           := Settings.HeaderHighlightFocused;
+  DockSitesCanBeMinimized          := Settings.DockSitesCanBeMinimized;
 end;
 
 procedure TAnchorDockMaster.SaveSettings(Settings: TAnchorDockSettings);
@@ -3343,6 +3577,7 @@
   Settings.HeaderFlatten:=HeaderFlatten;
   Settings.HeaderFilled:=HeaderFilled;
   Settings.HeaderHighlightFocused:=HeaderHighlightFocused;
+  Settings.DockSitesCanBeMinimized:=DockSitesCanBeMinimized;
 end;
 
 function TAnchorDockMaster.SettingsAreEqual(Settings: TAnchorDockSettings
@@ -3436,8 +3671,11 @@
   if fUpdateCount<=0 then
     RaiseGDBException('');
   dec(fUpdateCount);
-  if fUpdateCount=0 then
+  if fUpdateCount=0 then begin
     SimplifyPendingLayouts;
+    UpdateHeaders;
+    InvalidateHeaders;
+  end;
 end;
 
 function TAnchorDockMaster.IsReleasing(AControl: TControl): Boolean;
@@ -3664,6 +3902,24 @@
   LUIncreaseChangeStamp64(FOptionsChangeStamp);
 end;
 
+procedure TAnchorDockMaster.UpdateHeaders;
+var
+  i: Integer;
+  AControl: TControl;
+  AHostSite: TAnchorDockHostSite;
+begin
+    for i:=0 to ControlCount-1 do begin
+      AControl:=Controls[i];
+      if not DockedControlIsVisible(AControl) then continue;
+      while Assigned(AControl) do
+      begin
+        if AControl is TAnchorDockHostSite then
+          TAnchorDockHostSite(AControl).UpdateHeaderShowing;
+        AControl:=AControl.parent;
+      end;
+    end;
+end;
+
 { TAnchorDockHostSite }
 
 procedure TAnchorDockHostSite.SetHeaderSide(const AValue: TAnchorKind);
@@ -3680,6 +3936,7 @@
     AControl:=TControl(Sender);
     if not (csDestroying in ComponentState) then begin
       if (not AControl.Visible)
+      and (not FMinimized)
       and (not ((AControl is TAnchorDockHeader)
                or (AControl is TAnchorDockSplitter)
                or (AControl is TAnchorDockHostSite)))
@@ -4119,6 +4376,8 @@
 end;
 
 procedure TAnchorDockHostSite.FreePages;
+var
+  i:Integer;
 begin
   FreeAndNil(FPages);
 end;
@@ -4233,6 +4492,14 @@
         akRight: NewBounds.Right:=AControl.Left+AControl.Width;
         akBottom: NewBounds.Bottom:=AControl.Top+AControl.Height;
         end;
+        if (sibling is TAnchorDockHostSite) then
+        if (sibling as TAnchorDockHostSite).FMinimized then begin
+          (sibling as TAnchorDockHostSite).FMinimized:=false;
+          (sibling as TAnchorDockHostSite).FMinimizedControl.Parent:=(sibling as TAnchorDockHostSite);
+          (sibling as TAnchorDockHostSite).FMinimizedControl.Visible:=True;
+          (sibling as TAnchorDockHostSite).FMinimizedControl:=nil;
+          (sibling as TAnchorDockHostSite).UpdateHeaderAlign;
+        end;
         Sibling.BoundsRect:=NewBounds;
       end;
     end;
@@ -4306,6 +4573,13 @@
       FSiteType:=adhstOneControl;
       OnlySiteLeft.Align:=alClient;
       Header.Parent:=Self;
+      if OnlySiteLeft.FMinimized then begin
+        OnlySiteLeft.FMinimized:=false;
+        OnlySiteLeft.FMinimizedControl.Parent:=OnlySiteLeft;
+        OnlySiteLeft.FMinimizedControl.Visible:=True;
+        OnlySiteLeft.FMinimizedControl:=nil;
+        UpdateHeaderAlign;
+      end;
       UpdateHeaderAlign;
 
       //debugln(['TAnchorDockHostSite.RemoveControlFromLayout.ConvertToOneControlType AFTER CONVERT "',Caption,'" to onecontrol OnlySiteLeft="',OnlySiteLeft.Caption,'"']);
@@ -4465,7 +4739,7 @@
     debugln(['TAnchorDockHostSite.Simplify ',DbgSName(Self),' ',DbgSName(AControl)]);
     if AControl is TAnchorDockHostSite then
       SimplifyOneControl
-    else if (AControl=nil) or (csDestroying in AControl.ComponentState) then
+    else if ((AControl=nil) or (csDestroying in AControl.ComponentState)) then
       DockMaster.NeedFree(Self);
   end;
 end;
@@ -4577,7 +4851,8 @@
     Result:=Controls[i];
     if Result.Owner<>Self then exit;
   end;
-  Result:=nil;
+  result:=FMinimizedControl;
+  //Result:=nil;
 end;
 
 function TAnchorDockHostSite.GetSiteCount: integer;
@@ -5165,6 +5440,119 @@
   Result:=Check(Self);
 end;
 
+function CheckOposite(Side:TAnchorKind;var AControl: TControl;out Splitter: TAnchorDockSplitter; out SplitterAnchorKind:TAnchorKind):boolean;
+begin
+  result:=GetDockSplitter(AControl,Side,Splitter);
+  if result then begin
+    if CountAnchoredControls(Splitter,OppositeAnchor[Side])=1 then begin
+      SplitterAnchorKind:=Side;
+      exit;
+    end;
+  end;
+  result:=false
+end;
+
+function FindNearestSpliter(AControl: TControl;out Splitter: TAnchorDockSplitter;out SplitterAnchorKind:TAnchorKind):boolean;
+begin
+  result:=CheckOposite(akTop,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akRight,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akBottom,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akLeft,AControl,Splitter,SplitterAnchorKind);
+end;
+
+function TAnchorDockHostSite.CanBeMinimized(out Splitter: TAnchorDockSplitter;
+                                            out SplitterAnchorKind:TAnchorKind):boolean;
+var
+  AControl: TControl;
+  OpositeDockHostSite:TAnchorDockHostSite;
+begin
+  result:=false;
+  if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+    OpositeDockHostSite:=CountAndReturnOnlyOneMinimizedAnchoredControls(Splitter,SplitterAnchorKind);
+    if (Splitter.Enabled and (OpositeDockHostSite=nil)) then
+      result:=true;
+  end
+end;
+
+procedure TAnchorDockHostSite.MinimizeSite;
+begin
+  //Application.QueueAsyncCall(@AsyncMinimizeSite,0);
+  AsyncMinimizeSite(0);
+end;
+
+procedure TAnchorDockHostSite.AsyncMinimizeSite(Data: PtrInt);
+var
+  AControl: TControl;
+  //OpositeDockHostSite:TAnchorDockHostSite;
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
+  //SpliterPercentPosition:Single;
+begin
+  fMinimization:=true;
+  debugln(['TAnchorDockHostSite.MinimizeSite ',DbgSName(Self),' SiteType=',dbgs(SiteType)]);
+  if FMinimized then
+    AControl:=FMinimizedControl
+  else
+    AControl:=GetOneControl;
+  if CanBeMinimized(Splitter,SplitterAnchorKind) or FMinimized then begin
+    FMinimized:=not FMinimized;
+    if FMinimized then begin
+      FMinimizedControl:=AControl;
+      AControl.Visible:=False;
+      AControl.Parent:=nil;
+      //self.DoDockOver(); OnDockOver;
+    end else begin
+      AControl.Parent:=self;
+      AControl.Visible:=True;
+      FMinimizedControl:=nil;
+    end;
+    Splitter.Enabled:=AControl.Visible;
+    UpdateHeaderAlign;
+    dockmaster.UpdateHeaders;
+    dockmaster.InvalidateHeaders;
+    Splitter.SetBoundsPercentually;
+  end;
+  fMinimization:=false;
+end;
+
+procedure TAnchorDockHostSite.ShowMinimizedControl;
+var
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
+  SpliterRect,OverlappingFormRect:TRect;
+begin
+  if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+    SpliterRect:=Splitter.GetSpliterBoundsWithUnminimizedDockSites;
+    OverlappingFormRect:=BoundsRect;
+    case SplitterAnchorKind of
+         akTop:OverlappingFormRect.Top:=SpliterRect.Bottom;
+        akLeft:OverlappingFormRect.Left:=SpliterRect.Right;
+       akRight:OverlappingFormRect.Right:=SpliterRect.Left;
+      akBottom:OverlappingFormRect.Bottom:=SpliterRect.Top;
+    end;
+    DockMaster.FOverlappingForm:=TAnchorDockOverlappingForm.CreateNew(self);
+    DockMaster.FOverlappingForm.BoundsRect:=OverlappingFormRect;
+    DockMaster.FOverlappingForm.Parent:=GetParentFormOrDockPanel(self,false);
+    DockMaster.FOverlappingForm.AnchorDockHostSite:=self;
+    header.Parent:=DockMaster.FOverlappingForm;
+    FMinimizedControl.Parent:=DockMaster.FOverlappingForm.Panel;
+    FMinimizedControl.Show;
+    DockMaster.ShowOverlappingForm;
+  end;
+end;
+
+procedure TAnchorDockHostSite.HideMinimizedControl;
+begin
+   FMinimizedControl.Hide;
+   header.Parent:=self;
+   header.UpdateHeaderControls;
+   FMinimizedControl.Parent:=nil;
+   FreeAndNil(DockMaster.FOverlappingForm);
+end;
+
 function TAnchorDockHostSite.CloseSite: boolean;
 var
   AControl: TControl;
@@ -5281,21 +5669,24 @@
 begin
   if csDestroying in ComponentState then exit;
   NewCaption:='';
-  for i:=0 to ControlCount-1 do begin
-    Child:=Controls[i];
-    if Child=Exclude then continue;
-    if (Child.HostDockSite=Self) or (Child is TAnchorDockHostSite)
-    or (Child is TAnchorDockPageControl) then begin
-      if NewCaption<>'' then
-        NewCaption:=NewCaption+',';
-      NewCaption:=NewCaption+Child.Caption;
+  if FMinimized then
+    NewCaption:=FMinimizedControl.Caption
+  else
+    for i:=0 to ControlCount-1 do begin
+      Child:=Controls[i];
+      if Child=Exclude then continue;
+      if (Child.HostDockSite=Self) or (Child is TAnchorDockHostSite)
+      or (Child is TAnchorDockPageControl) then begin
+        if NewCaption<>'' then
+          NewCaption:=NewCaption+',';
+        NewCaption:=NewCaption+Child.Caption;
+      end;
     end;
-  end;
   OldCaption:=Caption;
   Caption:=NewCaption;
   //debugln(['TAnchorDockHostSite.UpdateDockCaption Caption="',Caption,'" NewCaption="',NewCaption,'" HasParent=',Parent<>nil,' ',DbgSName(Header)]);
-  if ((Parent=nil) and DockMaster.HideHeaderCaptionFloatingControl)
-  or (not DockMaster.ShowHeaderCaption) then
+  if {((Parent=nil) and DockMaster.HideHeaderCaptionFloatingControl)
+  or (not DockMaster.ShowHeaderCaption)}false then
     Header.Caption:=''
   else
     Header.Caption:=Caption;
@@ -5306,9 +5697,8 @@
     if Parent is TAnchorDockPage then
       TAnchorDockPage(Parent).UpdateDockCaption;
   end;
-
   // do not show close button for mainform
-  Header.CloseButton.Visible:=not IsParentOf(Application.MainForm);
+  Header.CloseButton.Visible:=(not IsParentOf(Application.MainForm));
 end;
 
 procedure TAnchorDockHostSite.GetSiteInfo(Client: TControl;
@@ -5339,7 +5729,8 @@
   end;
 
   CanDock:=(Client is TAnchorDockHostSite)
-           and not DockMaster.AutoFreedIfControlIsRemoved(Self,Client);
+           and not DockMaster.AutoFreedIfControlIsRemoved(Self,Client)
+           and not FMinimized;
   //debugln(['TAnchorDockHostSite.GetSiteInfo ',DbgSName(Self),' ',dbgs(BoundsRect),' ',Caption,' CanDock=',CanDock,' PtIn=',PtInRect(InfluenceRect,MousePos)]);
 
   if Assigned(OnGetSiteInfo) then
@@ -5362,9 +5753,20 @@
 end;
 
 procedure TAnchorDockHostSite.UpdateHeaderAlign;
+var
+  NeededHeaderPosition:TADLHeaderPosition;
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
 begin
   if Header=nil then exit;
-  case Header.HeaderPosition of
+  if FMinimized then begin
+    if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+      NeededHeaderPosition:=OppositeAnchorKind2TADLHeaderPosition[SplitterAnchorKind];
+    end else
+      NeededHeaderPosition:=Header.HeaderPosition;
+  end else
+    NeededHeaderPosition:=Header.HeaderPosition;
+  case NeededHeaderPosition of
   adlhpAuto:
     if Header.Align in [alLeft,alRight] then begin
       if (ClientHeight>0)
@@ -5388,10 +5790,16 @@
 end;
 
 procedure TAnchorDockHostSite.UpdateHeaderShowing;
+var
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
 begin
   if Header=nil then exit;
-  if HeaderNeedsShowing then
-    Header.Parent:=Self
+  if HeaderNeedsShowing then begin
+    Header.Parent:=Self;
+    Header.MinimizeButton.Visible:=(DockMaster.DockSitesCanBeMinimized and CanBeMinimized(Splitter,SplitterAnchorKind))or FMinimized;
+    Header.MinimizeButton.Parent:=Header;
+  end
   else
     Header.Parent:=nil;
 end;
@@ -5415,6 +5823,31 @@
   Result:=(fUpdateLayout>0) or (csDestroying in ComponentState);
 end;
 
+function AcceptAlign(Site:TAnchorDockHostSite; AlignCandidate:TAlign):TAlign;
+var
+  i:integer;
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
+  MinimizedSiteAlign:TAlign;
+begin
+  for i:=0 to Site.ControlCount-1 do
+    if Site.Controls[i] is TAnchorDockHostSite then
+      if (Site.Controls[i] as TAnchorDockHostSite).FMinimized then begin
+        if FindNearestSpliter(Site.Controls[i] as TAnchorDockHostSite,Splitter,SplitterAnchorKind) then begin
+          MinimizedSiteAlign:=OppositeAnchorKind2Align[SplitterAnchorKind];
+          if AlignCandidate=MinimizedSiteAlign then
+            exit(alNone);
+        end
+      end;
+  result:=AlignCandidate;
+end;
+
+function TAnchorDockHostSite.GetDockEdge(const MousePos: TPoint): TAlign;
+begin
+  result:=inherited;
+  result:=AcceptAlign(self,result);
+end;
+
 procedure TAnchorDockHostSite.SaveLayout(
   LayoutTree: TAnchorDockLayoutTree; LayoutNode: TAnchorDockLayoutTreeNode);
 var
@@ -5432,7 +5865,7 @@
   if (SiteType=adhstOneControl) and (OneControl<>nil)
   and (not (OneControl is TAnchorDockHostSite)) then begin
     LayoutNode.NodeType:=adltnControl;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,FMinimized);
     LayoutNode.Name:=OneControl.Name;
     LayoutNode.HeaderPosition:=Header.HeaderPosition;
   end else if (SiteType in [adhstLayout,adhstOneControl]) then begin
@@ -5450,7 +5883,7 @@
         Splitter.SaveLayout(ChildNode);
       end;
     end;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,FMinimized);
     LayoutNode.HeaderPosition:=Header.HeaderPosition;
   end else if SiteType=adhstPages then begin
     LayoutNode.NodeType:=adltnPages;
@@ -5461,7 +5894,7 @@
         Site.SaveLayout(LayoutTree,ChildNode);
       end;
     end;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,FMinimized);
     LayoutNode.HeaderPosition:=Header.HeaderPosition;
   end else
     LayoutNode.NodeType:=adltnNone;
@@ -5476,6 +5909,9 @@
 constructor TAnchorDockHostSite.CreateNew(AOwner: TComponent; Num: Integer);
 begin
   inherited CreateNew(AOwner,Num);
+  FMinimized:=false;
+  fMinimization:=false;
+  FMinimizedControl:=Nil;
   Visible:=false;
   FHeaderSide:=akTop;
   FHeader:=DockMaster.HeaderClass.Create(Self);
@@ -5490,13 +5926,13 @@
 end;
 
 destructor TAnchorDockHostSite.Destroy;
-//var i: Integer;
+var i: Integer;
 begin
-  //debugln(['TAnchorDockHostSite.Destroy ',DbgSName(Self),' Caption="',Caption,'" Self=',dbgs(Pointer(Self)),' ComponentCount=',ComponentCount,' ControlCount=',ControlCount]);
-  {for i:=0 to ComponentCount-1 do
+  debugln(['TAnchorDockHostSite.Destroy ',DbgSName(Self),' Caption="',Caption,'" Self=',dbgs(Pointer(Self)),' ComponentCount=',ComponentCount,' ControlCount=',ControlCount]);
+  for i:=0 to ComponentCount-1 do
     debugln(['TAnchorDockHostSite.Destroy Component ',i,'/',ComponentCount,' ',DbgSName(Components[i])]);
   for i:=0 to ControlCount-1 do
-    debugln(['TAnchorDockHostSite.Destroy Control ',i,'/',ControlCount,' ',DbgSName(Controls[i])]);}
+    debugln(['TAnchorDockHostSite.Destroy Control ',i,'/',ControlCount,' ',DbgSName(Controls[i])]);
   FreePages;
   inherited Destroy;
 end;
@@ -5562,13 +5998,34 @@
 end;
 
 procedure TAnchorDockHeader.CloseButtonClick(Sender: TObject);
+var
+  HeaderParent:TAnchorDockHostSite;
 begin
-  if Parent is TAnchorDockHostSite then begin
-    DockMaster.RestoreLayouts.Add(DockMaster.CreateRestoreLayout(Parent),true);
-    TAnchorDockHostSite(Parent).CloseSite;
+  TWinControl(HeaderParent):=Parent;
+  if HeaderParent=TWinControl(DockMaster.FOverlappingForm) then begin
+    HeaderParent:=DockMaster.FOverlappingForm.AnchorDockHostSite;
+    HeaderParent.HideMinimizedControl;
   end;
+  if HeaderParent is TAnchorDockHostSite then begin
+    DockMaster.RestoreLayouts.Add(DockMaster.CreateRestoreLayout(HeaderParent),true);
+    HeaderParent.CloseSite;
+  end;
 end;
 
+procedure TAnchorDockHeader.MinimizeButtonClick(Sender: TObject);
+var
+  HeaderParent:TAnchorDockHostSite;
+begin
+  TWinControl(HeaderParent):=Parent;
+  if HeaderParent=TWinControl(DockMaster.FOverlappingForm) then begin
+    HeaderParent:=DockMaster.FOverlappingForm.AnchorDockHostSite;
+    HeaderParent.HideMinimizedControl;
+  end;
+  if HeaderParent is TAnchorDockHostSite then begin
+    HeaderParent.MinimizeSite;
+  end;
+end;
+
 procedure TAnchorDockHeader.HeaderPositionItemClick(Sender: TObject);
 var
   Item: TMenuItem;
@@ -5635,11 +6092,18 @@
 
   if CloseButton.IsControlVisible and (CloseButton.Parent=Self) then begin
     if Align in [alLeft,alRight] then
-      r.Top:=CloseButton.Top+CloseButton.Height+1
+      r.Top:=CloseButton.Top+CloseButton.Height+ButtonBorderSpacingAround
     else
-      r.Right:=CloseButton.Left-1;
+      r.Right:=CloseButton.Left-ButtonBorderSpacingAround;
   end;
 
+  if MinimizeButton.IsControlVisible and (MinimizeButton.Parent=Self) then begin
+    if Align in [alLeft,alRight] then
+      r.Top:=MinimizeButton.Top+MinimizeButton.Height+ButtonBorderSpacingAround
+    else
+      r.Right:=MinimizeButton.Left-ButtonBorderSpacingAround;
+  end;
+
   // caption
   if Caption<>'' then begin
     if fFocused and DockMaster.HeaderHighlightFocused and NeedHighlightText then
@@ -5728,26 +6192,127 @@
     end else begin
       PreferredHeight:=Max(NeededHeight,PreferredHeight);
     end;
+  end else begin
+    NeededHeight:=CloseButton.Height;
+    if Align in [alLeft,alRight] then begin
+      PreferredWidth:=Max(NeededHeight,PreferredWidth);
+    end else begin
+      PreferredHeight:=Max(NeededHeight,PreferredHeight);
   end;
+  end;
 end;
 
 procedure TAnchorDockHeader.MouseDown(Button: TMouseButton; Shift: TShiftState;
   X, Y: Integer);
+var
+  SiteMinimized:Boolean;
 begin
   inherited MouseDown(Button, Shift, X, Y);
-  if (Button=mbLeft) and DockMaster.AllowDragging then
-    DragManager.DragStart(Parent,false,DockMaster.DragTreshold);
+  SiteMinimized:=False;
+  fUseTimer:=false;
+  StopMouseNoMoveTimer;
+  if Parent is TAnchorDockHostSite then
+    SiteMinimized:=(Parent as TAnchorDockHostSite).FMinimized;
+  if SiteMinimized then begin
+    DoMouseNoMoveTimer(nil);
+  end else
+    begin
+      if parent<>nil then
+        if DockMaster.FOverlappingForm<>nil then
+          //if parent=DockMaster.FOverlappingForm.Panel then
+            DockMaster.HideOverlappingForm(nil);
+      if (Button=mbLeft) and (DockMaster.AllowDragging) and (DockMaster.FOverlappingForm=nil) then
+        DragManager.DragStart(Parent,false,DockMaster.DragTreshold);
+    end;
 end;
 
+procedure  TAnchorDockHeader.MouseMove(Shift: TShiftState; X,Y: Integer);
+begin
+  inherited MouseMove(Shift, X, Y);
+  if parent<>nil then
+    if parent is TAnchorDockHostSite then
+      if (parent as TAnchorDockHostSite).FMinimized then
+        if DockMaster.FOverlappingForm=nil then
+          if FMouseTimeStartX=EmptyMouseTimeStartX then
+            StartMouseNoMoveTimer(X, Y)
+          else begin
+            if (abs(FMouseTimeStartX-X)>MouseNoMoveDelta)or(abs(FMouseTimeStartY-Y)>MouseNoMoveDelta)then
+            StopMouseNoMoveTimer;
+          end;
+  if (parent is TAnchorDockHostSite)and(DockMaster.FOverlappingForm=nil)then
+    fUseTimer:=true;
+end;
+
+procedure TAnchorDockHeader.MouseLeave;
+begin
+  inherited;
+  StopMouseNoMoveTimer;
+end;
+
+procedure TAnchorDockHeader.StartMouseNoMoveTimer(X, Y: Integer);
+begin
+  if fUseTimer then begin
+    if DockTimer.Enabled then DockTimer.Enabled:=false;
+    DockTimer.Interval:=MouseNoMoveTime;
+    DockTimer.OnTimer:=@DoMouseNoMoveTimer;
+    DockTimer.Enabled:=true;
+  end;
+end;
+
+procedure TAnchorDockHeader.StopMouseNoMoveTimer;
+begin
+  FMouseTimeStartX:=EmptyMouseTimeStartX;
+  DockTimer.OnTimer:=nil;
+  DockTimer.Enabled:=false;
+end;
+
+procedure TAnchorDockHeader.DoMouseNoMoveTimer(Sender: TObject);
+begin
+  StopMouseNoMoveTimer;
+  //if fUseTimer then
+    if parent<>nil then
+      if parent is TAnchorDockHostSite then
+        if (parent as TAnchorDockHostSite).FMinimized then
+          (parent as TAnchorDockHostSite).ShowMinimizedControl;
+end;
+
 procedure TAnchorDockHeader.UpdateHeaderControls;
 begin
   if Align in [alLeft,alRight] then begin
-    if CloseButton<>nil then
-      CloseButton.Align:=alTop;
+    if CloseButton<>nil then begin
+      //MinimizeButton.Align:=alTop;
+      //CloseButton.Align:=alTop;
+      CloseButton.AnchorSide[akRight].Side := asrCenter;
+      CloseButton.AnchorSide[akRight].Control := self;
+      CloseButton.AnchorSide[akTop].Side := asrTop;
+      CloseButton.AnchorSide[akTop].Control := self;
+      CloseButton.Anchors := CloseButton.Anchors + [akTop] + [akRight];
+
+      MinimizeButton.AnchorSide[akRight].Side := asrCenter;
+      MinimizeButton.AnchorSide[akRight].Control := CloseButton;
+      MinimizeButton.AnchorSide[akTop].Side := asrBottom;
+      MinimizeButton.AnchorSide[akTop].Control := CloseButton;
+      MinimizeButton.Anchors := MinimizeButton.Anchors + [akTop] + [akRight];
+    end;
   end else begin
-    if CloseButton<>nil then
-      CloseButton.Align:=alRight;
+    if CloseButton<>nil then begin
+      //MinimizeButton.Align:=alRight;
+      //CloseButton.Align:=alRight;
+      CloseButton.AnchorSide[akRight].Side := asrRight;
+      CloseButton.AnchorSide[akRight].Control := self;
+      CloseButton.AnchorSide[akTop].Side := asrCenter;
+      CloseButton.AnchorSide[akTop].Control := self;
+      CloseButton.Anchors := CloseButton.Anchors - [akLeft] + [akRight];
+
+      MinimizeButton.AnchorSide[akRight].Side := asrLeft;
+      MinimizeButton.AnchorSide[akRight].Control := CloseButton;
+      MinimizeButton.AnchorSide[akTop].Side := asrCenter;
+      MinimizeButton.AnchorSide[akTop].Control := CloseButton;
+      MinimizeButton.Anchors := MinimizeButton.Anchors - [akLeft] + [akRight];
+    end;
   end;
+  CloseButton.BorderSpacing.Around:=ButtonBorderSpacingAround;
+  MinimizeButton.BorderSpacing.Around:=ButtonBorderSpacingAround;
   //debugln(['TAnchorDockHeader.UpdateHeaderControls ',dbgs(Align),' ',dbgs(CloseButton.Align)]);
 end;
 
@@ -5787,9 +6352,9 @@
 begin
   inherited Create(TheOwner);
   FHeaderPosition:=adlhpAuto;
-  FCloseButton:=TAnchorDockCloseButton.Create(Self);
   BevelOuter:=bvNone;
   BorderWidth:=0;
+  FCloseButton:=TAnchorDockCloseButton.Create(Self);
   with FCloseButton do begin
     Name:='CloseButton';
     Parent:=Self;
@@ -5799,11 +6364,23 @@
     OnClick:=@CloseButtonClick;
     AutoSize:=true;
   end;
+  FMinimizeButton:=TAnchorDockMinimizeButton.Create(Self);
+  with FMinimizeButton do begin
+    Name:='MinimizeButton';
+    Parent:=Self;
+    Flat:=true;
+    ShowHint:=true;
+    Hint:=adrsMinimize;
+    OnClick:=@MinimizeButtonClick;
+    AutoSize:=true;
+  end;
   Align:=alTop;
   AutoSize:=true;
   ShowHint:=true;
   PopupMenu:=DockMaster.GetPopupMenu;
   fFocused:=false;
+  FMouseTimeStartX:=EmptyMouseTimeStartX;
+  fUseTimer:=true;
 end;
 
 { TAnchorDockCloseButton }
@@ -5830,6 +6407,31 @@
   Result := ThemeServices.GetElementDetails(WindowPart);
 end;
 
+procedure SizeCorrector(var current,recomend:integer);
+begin
+  if recomend<0 then begin
+    if current>0 then
+      recomend:=current
+    else
+      current:=HardcodedButtonSize;
+  end else begin
+      if current>recomend then
+        current:=recomend
+      else begin
+        if current>0 then
+         recomend:=current
+        else
+         current:=recomend;
+      end;
+  end;
+end;
+
+procedure ButtonSizeCorrector(var w,h:integer);
+begin
+  SizeCorrector(w,PreferredButtonWidth);
+  SizeCorrector(h,PreferredButtonHeight);
+end;
+
 procedure TAnchorDockCloseButton.CalculatePreferredSize(var PreferredWidth,
   PreferredHeight: integer; WithThemeSpace: Boolean);
 begin
@@ -5837,6 +6439,7 @@
   begin
     PreferredWidth:=cx;
     PreferredHeight:=cy;
+    ButtonSizeCorrector(PreferredWidth,PreferredHeight);
     {$IF defined(LCLGtk2) or defined(Carbon)}
     inc(PreferredWidth,2);
     inc(PreferredHeight,2);
@@ -5844,6 +6447,45 @@
   end;
 end;
 
+{ TAnchorDockMinimizeButton }
+
+function TAnchorDockMinimizeButton.GetDrawDetails: TThemedElementDetails;
+
+function WindowPart: TThemedWindow;
+  begin
+    // no check states available
+    Result := twMinButtonNormal;
+    if not IsEnabled then
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonDisabled{$ELSE}twMinButtonDisabled{$ENDIF}
+    else
+    if FState in [bsDown, bsExclusive] then
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonPushed{$ELSE}twMinButtonPushed{$ENDIF}
+    else
+    if FState = bsHot then
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonHot{$ELSE}twMinButtonHot{$ENDIF}
+    else
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonNormal{$ELSE}twMinButtonNormal{$ENDIF};
+  end;
+
+begin
+  Result := ThemeServices.GetElementDetails(WindowPart);
+end;
+
+procedure TAnchorDockMinimizeButton.CalculatePreferredSize(var PreferredWidth,
+  PreferredHeight: integer; WithThemeSpace: Boolean);
+begin
+  with ThemeServices.GetDetailSize(ThemeServices.GetElementDetails({$IFDEF LCLGtk2}twMDIRestoreButtonNormal{$ELSE}twMinButtonNormal{$ENDIF})) do
+  begin
+    PreferredWidth:=cx;
+    PreferredHeight:=cy;
+    ButtonSizeCorrector(PreferredWidth,PreferredHeight);
+    {$IF defined(LCLGtk2) or defined(Carbon)}
+    inc(PreferredWidth,2);
+    inc(PreferredHeight,2);
+    {$ENDIF}
+  end;
+end;
+
 { TAnchorDockManager }
 
 procedure TAnchorDockManager.SetPreferredSiteSizeAsSiteMinimum(
@@ -6213,6 +6855,9 @@
   ClientRectChanged:=(WidthDiff<>0) or (HeightDiff<>0);
   if ClientRectChanged or PreferredSiteSizeAsSiteMinimum then
     AlignChilds;
+  if ClientRectChanged then
+    if DockMaster.FOverlappingForm<>nil then
+      DockMaster.HideOverlappingForm(nil);
 end;
 
 procedure TAnchorDockManager.SaveToStream(Stream: TStream);
@@ -6287,6 +6932,11 @@
       ADockObject.DropOnControl:=Site
     else
       ADockObject.DropOnControl:=nil;
+    if Site is TAnchorDockHostSite then begin
+      ADockObject.DropAlign:=AcceptAlign(Site as TAnchorDockHostSite,ADockObject.DropAlign);
+      if ADockObject.DropAlign=alNone then
+        exit(false);
+    end;
   end;
   //debugln(['TAnchorDockManager.GetDockEdge ADockObject.DropAlign=',dbgs(ADockObject.DropAlign),' DropOnControl=',DbgSName(ADockObject.DropOnControl)]);
   Result:=true;
@@ -6505,32 +7155,58 @@
 procedure TAnchorDockSplitter.SetBoundsPercentually;
 var
   NewLeft, NewTop: Integer;
+  AControl: TControl;
+  SplitterAnchorKind:TAnchorKind;
 begin
-  if ResizeAnchor in [akLeft,akRight] then
-  begin
-    if DockParentClientSize.cx> 0 then
+  if Enabled then begin
+    if ResizeAnchor in [akLeft,akRight] then
     begin
-      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
-        NewLeft := Round(FPercentPosition*Parent.ClientWidth)
-      else
-        NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
-      NewTop := Top;
-      SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      if DockParentClientSize.cx> 0 then
+      begin
+        if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+          NewLeft := Round(FPercentPosition*Parent.ClientWidth)
+        else
+          NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
+        NewTop := Top;
+        SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      end;
+    end else
+    begin
+      if DockParentClientSize.cy> 0 then
+      begin
+        NewLeft := Left;
+        if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+          NewTop := Round(FPercentPosition*Parent.ClientHeight)
+        else
+          NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+        SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      end;
     end;
-  end else
-  begin
-    if DockParentClientSize.cy> 0 then
-    begin
-      NewLeft := Left;
-      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
-        NewTop := Round(FPercentPosition*Parent.ClientHeight)
-      else
-        NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+    if FPercentPosition < 0 then
+      UpdatePercentPosition;
+  end else begin
+    SplitterAnchorKind:=akTop;
+    AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);
+    if AControl=nil then begin SplitterAnchorKind:=akRight;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+    if AControl=nil then begin SplitterAnchorKind:=akBottom;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+    if AControl=nil then begin SplitterAnchorKind:=akLeft;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+
+    if AControl is TAnchorDockHostSite then begin
+      (AControl as TAnchorDockHostSite).UpdateHeaderAlign;
+      NewTop := (AControl as TAnchorDockHostSite).Header.Left;
+      NewTop := (AControl as TAnchorDockHostSite).Header.Height;
+      NewLeft := left;
+      NewTop := top;
+      (AControl as TAnchorDockHostSite).UpdateHeaderAlign;
+      case SplitterAnchorKind of
+        akTop: NewTop := AControl.Top+(AControl as TAnchorDockHostSite).Header.Height;
+        akBottom: NewTop := AControl.Top+AControl.Height-(AControl as TAnchorDockHostSite).Header.Height-Height;
+        akLeft: NewLeft := AControl.Left+(AControl as TAnchorDockHostSite).Header.Width;
+        akRight: NewLeft := AControl.Left+AControl.Width-(AControl as TAnchorDockHostSite).Header.Width-Width;
+      end;
       SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
     end;
   end;
-  if FPercentPosition < 0 then
-    UpdatePercentPosition;
 end;
 
 function TAnchorDockSplitter.SideAnchoredControlCount(Side: TAnchorKind): integer;
@@ -6560,14 +7236,47 @@
   end;
 end;
 
+function TAnchorDockSplitter.GetSpliterBoundsWithUnminimizedDockSites:TRect;
+var
+  NewLeft, NewTop: Integer;
+begin
+  if ResizeAnchor in [akLeft,akRight] then
+  begin
+    if DockParentClientSize.cx> 0 then
+    begin
+      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+        NewLeft := Round(FPercentPosition*Parent.ClientWidth)
+      else
+        NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
+      NewTop := Top;
+    end;
+  end else
+  begin
+    if DockParentClientSize.cy> 0 then
+    begin
+      NewLeft := Left;
+      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+        NewTop := Round(FPercentPosition*Parent.ClientHeight)
+      else
+        NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+    end;
+  end;
+  result:=Rect(NewLeft,NewTop,NewLeft+Width,NewTop+Height);
+end;
+
 procedure TAnchorDockSplitter.SaveLayout(
   LayoutNode: TAnchorDockLayoutTreeNode);
+var
+  NewLeft, NewTop: Integer;
 begin
   if ResizeAnchor in [akLeft,akRight] then
     LayoutNode.NodeType:=adltnSplitterVertical
   else
     LayoutNode.NodeType:=adltnSplitterHorizontal;
-  LayoutNode.Assign(Self);
+  LayoutNode.Assign(Self,false,false);
+  if not Enabled then begin
+    LayoutNode.BoundsRect:=GetSpliterBoundsWithUnminimizedDockSites;
+  end
 end;
 
 function TAnchorDockSplitter.HasOnlyOneSibling(Side: TAnchorKind; MinPos,
@@ -6645,7 +7354,7 @@
 begin
   inherited MouseDown(Button, Shift, X, Y);
   ATabIndex := IndexOfPageAt(X, Y);
-  if (Button = mbLeft) and DockMaster.AllowDragging and (ATabIndex >= 0) then
+  if (Button = mbLeft) and DockMaster.AllowDragging and (ATabIndex >= 0) and (DockMaster.FOverlappingForm=nil) then
   begin
     APage:=Page[ATabIndex];
     if (APage.ControlCount>0) and (APage.Controls[0] is TAnchorDockHostSite) then
@@ -6782,6 +7491,20 @@
   PopupMenu:=DockMaster.GetPopupMenu;
 end;
 
+{ TAnchorDockOverlappingForm }
+
+constructor TAnchorDockOverlappingForm.CreateNew(AOwner: TComponent; Num: Integer = 0);
+begin
+  inherited;
+  BorderStyle:=bsNone;
+  AnchorDockHostSite:=nil;
+  Panel:=TPanel.Create(self);
+  Panel.BorderStyle:=bsSingle;
+  Panel.Align:=alClient;
+  Panel.Parent:=self;
+  Panel.Visible:=true;
+end;
+
 { TAnchorDockPage }
 
 procedure TAnchorDockPage.UpdateDockCaption(Exclude: TControl);
@@ -6835,9 +7558,11 @@
 
 initialization
   DockMaster:=TAnchorDockMaster.Create(nil);
+  DockTimer:=TTimer.Create(nil);
 
 finalization
   FreeAndNil(DockMaster);
+  FreeAndNil(DockTimer);
 
 end.
 
Index: components/anchordocking/anchordockoptionsdlg.lfm
===================================================================
--- components/anchordocking/anchordockoptionsdlg.lfm	(revision 59428)
+++ components/anchordocking/anchordockoptionsdlg.lfm	(working copy)
@@ -1,11 +1,13 @@
 object AnchorDockOptionsFrame: TAnchorDockOptionsFrame
   Left = 0
-  Height = 482
+  Height = 567
   Top = 0
-  Width = 416
-  ClientHeight = 482
-  ClientWidth = 416
+  Width = 490
+  ClientHeight = 567
+  ClientWidth = 490
+  DesignTimePPI = 113
   OnClick = FrameClick
+  ParentFont = False
   TabOrder = 0
   DesignLeft = 513
   DesignTop = 189
@@ -12,14 +14,15 @@
   object DragThresholdLabel: TLabel
     AnchorSideLeft.Control = Owner
     AnchorSideTop.Control = Owner
-    Left = 10
-    Height = 13
-    Top = 10
-    Width = 111
-    BorderSpacing.Left = 10
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 12
+    Width = 122
+    BorderSpacing.Left = 12
+    BorderSpacing.Top = 12
     Caption = 'DragThresholdLabel'
     ParentColor = False
+    ParentFont = False
   end
   object DragThresholdTrackBar: TTrackBar
     AnchorSideLeft.Control = DragThresholdLabel
@@ -27,15 +30,16 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = Owner
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 46
-    Top = 23
-    Width = 396
+    Left = 12
+    Height = 54
+    Top = 31
+    Width = 466
     Max = 20
     OnChange = DragThresholdTrackBarChange
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Right = 10
+    BorderSpacing.Right = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 1
@@ -46,12 +50,13 @@
     AnchorSideTop.Control = DragThresholdLabel
     AnchorSideTop.Side = asrCenter
     AnchorSideRight.Control = Owner
-    Left = 127
-    Height = 23
-    Top = 5
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 141
+    Height = 27
+    Top = 8
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 20
+    ParentFont = False
     TabOrder = 0
     Visible = False
   end
@@ -59,13 +64,14 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = DragThresholdTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 79
-    Width = 103
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 97
+    Width = 112
+    BorderSpacing.Top = 12
     Caption = 'SplitterWidthLabel'
     ParentColor = False
+    ParentFont = False
   end
   object SplitterWidthTrackBar: TTrackBar
     AnchorSideLeft.Control = DragThresholdTrackBar
@@ -73,14 +79,15 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 46
-    Top = 92
-    Width = 396
+    Left = 12
+    Height = 54
+    Top = 116
+    Width = 466
     Min = 1
     OnChange = SplitterWidthTrackBarChange
     Position = 1
     Anchors = [akTop, akLeft, akRight]
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 3
@@ -89,12 +96,13 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = SplitterWidthTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 24
-    Top = 142
-    Width = 160
-    BorderSpacing.Top = 4
+    Left = 12
+    Height = 23
+    Top = 175
+    Width = 169
+    BorderSpacing.Top = 5
     Caption = 'ScaleOnResizeCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 4
@@ -103,12 +111,13 @@
     AnchorSideLeft.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 24
-    Top = 166
-    Width = 149
+    Left = 12
+    Height = 23
+    Top = 198
+    Width = 160
     Caption = 'ShowHeaderCheckBox'
     OnChange = ShowHeaderCheckBoxChange
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 5
@@ -117,12 +126,13 @@
     AnchorSideLeft.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Control = ShowHeaderCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 190
-    Width = 191
-    BorderSpacing.Left = 15
+    Left = 30
+    Height = 23
+    Top = 221
+    Width = 208
+    BorderSpacing.Left = 18
     Caption = 'ShowHeaderCaptionCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 6
@@ -131,11 +141,12 @@
     AnchorSideLeft.Control = ShowHeaderCaptionCheckBox
     AnchorSideTop.Control = ShowHeaderCaptionCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 214
-    Width = 249
+    Left = 30
+    Height = 23
+    Top = 244
+    Width = 272
     Caption = 'HideHeaderCaptionForFloatingCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 7
@@ -147,15 +158,16 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = Owner
     AnchorSideRight.Side = asrBottom
-    Left = 122
+    Left = 136
     Height = 27
-    Top = 286
-    Width = 284
+    Top = 313
+    Width = 342
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 6
-    BorderSpacing.Right = 10
-    ItemHeight = 0
+    BorderSpacing.Left = 7
+    BorderSpacing.Right = 12
+    ItemHeight = 19
     OnDrawItem = HeaderStyleComboBoxDrawItem
+    ParentFont = False
     Style = csDropDownList
     TabOrder = 10
   end
@@ -163,23 +175,25 @@
     AnchorSideLeft.Control = ShowHeaderCheckBox
     AnchorSideTop.Control = HeaderStyleComboBox
     AnchorSideTop.Side = asrCenter
-    Left = 20
-    Height = 13
-    Top = 293
-    Width = 96
-    BorderSpacing.Left = 10
+    Left = 24
+    Height = 19
+    Top = 317
+    Width = 105
+    BorderSpacing.Left = 12
     Caption = 'HeaderStyleLabel'
     ParentColor = False
+    ParentFont = False
   end
   object FlattenHeadersCheckBox: TCheckBox
     AnchorSideLeft.Control = HideHeaderCaptionForFloatingCheckBox
     AnchorSideTop.Control = HideHeaderCaptionForFloatingCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 238
-    Width = 164
+    Left = 30
+    Height = 23
+    Top = 267
+    Width = 175
     Caption = 'FlattenHeadersCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 8
@@ -188,11 +202,12 @@
     AnchorSideLeft.Control = FlattenHeadersCheckBox
     AnchorSideTop.Control = FlattenHeadersCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 262
-    Width = 154
+    Left = 30
+    Height = 23
+    Top = 290
+    Width = 164
     Caption = 'FilledHeadersCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 9
@@ -201,11 +216,12 @@
     AnchorSideLeft.Control = FilledHeadersCheckBox
     AnchorSideTop.Control = HeaderStyleComboBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 313
-    Width = 175
+    Left = 30
+    Height = 23
+    Top = 340
+    Width = 189
     Caption = 'HighlightFocusedCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 11
@@ -215,13 +231,14 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = SplitterWidthLabel
     AnchorSideTop.Side = asrCenter
-    Left = 119
-    Height = 23
-    Top = 74
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 131
+    Height = 27
+    Top = 93
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 10
     MinValue = 1
+    ParentFont = False
     TabOrder = 2
     Value = 1
     Visible = False
@@ -228,15 +245,16 @@
   end
   object HeaderAlignTopLabel: TLabel
     AnchorSideLeft.Control = DragThresholdLabel
-    AnchorSideTop.Control = HighlightFocusedCheckBox
+    AnchorSideTop.Control = DockSitesCanBeMinimized
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 347
-    Width = 117
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 398
+    Width = 130
+    BorderSpacing.Top = 12
     Caption = 'HeaderAlignTopLabel'
     ParentColor = False
+    ParentFont = False
   end
   object HeaderAlignTopTrackBar: TTrackBar
     AnchorSideLeft.Control = Owner
@@ -244,10 +262,10 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 47
-    Top = 360
-    Width = 396
+    Left = 12
+    Height = 55
+    Top = 417
+    Width = 466
     Frequency = 10
     Max = 150
     OnChange = HeaderAlignTopTrackBarChange
@@ -254,7 +272,8 @@
     PageSize = 10
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 10
+    BorderSpacing.Left = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 13
@@ -264,12 +283,13 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = HeaderAlignTopLabel
     AnchorSideTop.Side = asrCenter
-    Left = 133
-    Height = 23
-    Top = 342
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 149
+    Height = 27
+    Top = 394
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 150
+    ParentFont = False
     TabOrder = 12
     Visible = False
   end
@@ -277,13 +297,14 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = HeaderAlignTopTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 417
-    Width = 120
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 484
+    Width = 130
+    BorderSpacing.Top = 12
     Caption = 'HeaderAlignLeftLabel'
     ParentColor = False
+    ParentFont = False
   end
   object HeaderAlignLeftTrackBar: TTrackBar
     AnchorSideLeft.Control = Owner
@@ -291,10 +312,10 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 47
-    Top = 430
-    Width = 396
+    Left = 12
+    Height = 55
+    Top = 503
+    Width = 466
     Frequency = 10
     Max = 200
     OnChange = HeaderAlignLeftTrackBarChange
@@ -301,7 +322,8 @@
     PageSize = 10
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 10
+    BorderSpacing.Left = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 15
@@ -311,13 +333,28 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = HeaderAlignLeftLabel
     AnchorSideTop.Side = asrCenter
-    Left = 136
-    Height = 23
-    Top = 412
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 149
+    Height = 27
+    Top = 480
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 200
+    ParentFont = False
     TabOrder = 14
     Visible = False
   end
+  object DockSitesCanBeMinimized: TCheckBox
+    AnchorSideLeft.Control = FilledHeadersCheckBox
+    AnchorSideTop.Control = HighlightFocusedCheckBox
+    AnchorSideTop.Side = asrBottom
+    Left = 30
+    Height = 23
+    Top = 363
+    Width = 185
+    Caption = 'DockSitesCanBeMinimized'
+    ParentFont = False
+    ParentShowHint = False
+    ShowHint = True
+    TabOrder = 16
+  end
 end
Index: components/anchordocking/anchordockoptionsdlg.pas
===================================================================
--- components/anchordocking/anchordockoptionsdlg.pas	(revision 59428)
+++ components/anchordocking/anchordockoptionsdlg.pas	(working copy)
@@ -37,6 +37,7 @@
     HeaderStyleLabel: TLabel;
     HideHeaderCaptionForFloatingCheckBox: TCheckBox;
     HighlightFocusedCheckBox: TCheckBox;
+    DockSitesCanBeMinimized: TCheckBox;
     ScaleOnResizeCheckBox: TCheckBox;
     ShowHeaderCaptionCheckBox: TCheckBox;
     ShowHeaderCheckBox: TCheckBox;
@@ -202,7 +203,7 @@
 
       HeaderAlignTopSpinEdit.Visible:=true;
       HeaderAlignTopTrackBar.Visible:=false;
-      HeaderAlignTopSpinEdit.AnchorToNeighbour(akTop,6,HighlightFocusedCheckBox);
+      HeaderAlignTopSpinEdit.AnchorToNeighbour(akTop,6,DockSitesCanBeMinimized);
       HeaderAlignTopLabel.AnchorVerticalCenterTo(HeaderAlignTopSpinEdit);
       UpdateHeaderAlignTopLabel;
 
@@ -299,6 +300,7 @@
   HeaderStyleLabel.Enabled:=HasHeaders;
   HeaderStyleComboBox.Enabled:=HasHeaders;
   HighlightFocusedCheckBox.Enabled:=HasHeaders;
+  DockSitesCanBeMinimized.Enabled:=HasHeaders;
 end;
 
 constructor TAnchorDockOptionsFrame.Create(TheOwner: TComponent);
@@ -356,6 +358,7 @@
   TheSettings.HeaderFilled:=FilledHeadersCheckBox.Checked;
   TheSettings.HeaderStyle:=TADHeaderStyle(HeaderStyleComboBox.ItemIndex);
   TheSettings.HeaderHighlightFocused:=HighlightFocusedCheckBox.Checked;
+  TheSettings.DockSitesCanBeMinimized:=DockSitesCanBeMinimized.Checked;
 end;
 
 procedure TAnchorDockOptionsFrame.LoadFromSettings(
@@ -429,6 +432,10 @@
   HighlightFocusedCheckBox.Checked:=TheSettings.HeaderHighlightFocused;
   HighlightFocusedCheckBox.Caption:=adrsHighlightFocused;
   HighlightFocusedCheckBox.Hint:=adrsHighlightFocusedHint;
+
+  DockSitesCanBeMinimized.Checked:=TheSettings.DockSitesCanBeMinimized;
+  DockSitesCanBeMinimized.Caption:=adrsDockSitesCanBeMinimized;
+  DockSitesCanBeMinimized.Hint:=adrsDockSitesCanBeMinimizedHint;
 end;
 
 end.
Index: components/anchordocking/anchordockpanel.pas
===================================================================
--- components/anchordocking/anchordockpanel.pas	(revision 59428)
+++ components/anchordocking/anchordockpanel.pas	(working copy)
@@ -55,7 +55,7 @@
   begin
 
     LayoutNode.NodeType:=adltnControl;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,false);
     LayoutNode.Name:={OneControl.}Name;
 
     TAnchorDockHostSite(OneControl).SaveLayout(LayoutTree,LayoutNode);
Index: components/anchordocking/anchordockstorage.pas
===================================================================
--- components/anchordocking/anchordockstorage.pas	(revision 59428)
+++ components/anchordocking/anchordockstorage.pas	(working copy)
@@ -64,6 +64,7 @@
     FTabPosition: TTabPosition;
     FWindowState: TWindowState;
     FControlLocation: TADLControlLocation;
+    FMinimized: Boolean;
     function GetAnchors(Site: TAnchorKind): string;
     function GetBottom: integer;
     function GetHeight: integer;
@@ -90,6 +91,7 @@
     procedure SetTop(const AValue: integer);
     procedure SetWidth(const AValue: integer);
     procedure SetWindowState(const AValue: TWindowState);
+    procedure SetMinimized(const AValue: boolean);
   public
     constructor Create;
     destructor Destroy; override;
@@ -96,7 +98,7 @@
     procedure Clear;
     function IsEqual(Node: TAnchorDockLayoutTreeNode): boolean;
     procedure Assign(Node: TAnchorDockLayoutTreeNode); overload;
-    procedure Assign(AControl: TControl; OverrideBoundsRect: Boolean=false); overload;
+    procedure Assign(AControl: TControl; OverrideBoundsRect: Boolean; AMinimized: Boolean); overload;
     procedure LoadFromConfig(Config: TConfigStorage); overload;
     procedure LoadFromConfig(Path: string; Config: TRttiXMLConfig); overload;
     procedure SaveToConfig(Config: TConfigStorage); overload;
@@ -106,7 +108,7 @@
     procedure CheckConsistency; virtual;
 
     // simplifying
-    procedure Simplify(ExistingNames: TStrings);
+    procedure Simplify(ExistingNames: TStrings; ParentMinimized:boolean);
     procedure DeleteNode(ChildNode: TAnchorDockLayoutTreeNode);
     function FindNodeBoundSplitter(ChildNode: TAnchorDockLayoutTreeNode;
                                    Side: TAnchorKind): TAnchorDockLayoutTreeNode;
@@ -135,6 +137,7 @@
     property Monitor: integer read FMonitor write SetMonitor;
     property HeaderPosition: TADLHeaderPosition read FHeaderPosition write SetHeaderPosition;
     property TabPosition: TTabPosition read FTabPosition write SetTabPosition;
+    property Minimized: Boolean read FMinimized write SetMinimized;
     function Count: integer;
     function IsSplitter: boolean;
     function IsRootWindow: boolean;
@@ -988,6 +991,13 @@
   IncreaseChangeStamp;
 end;
 
+procedure TAnchorDockLayoutTreeNode.SetMinimized(const AValue: boolean);
+begin
+  if FMinimized=AValue then exit;
+  FMinimized:=AValue;
+  IncreaseChangeStamp;
+end;
+
 procedure TAnchorDockLayoutTreeNode.SetTop(const AValue: integer);
 begin
   if Top=AValue then exit;
@@ -1084,6 +1094,7 @@
   BoundSplitterPos:=Node.BoundSplitterPos;
   WorkAreaRect:=Node.WorkAreaRect;
   Monitor:=Node.Monitor;
+  Minimized:=Node.Minimized;
   for a:=low(TAnchorKind) to high(TAnchorKind) do
     Anchors[a]:=Node.Anchors[a];
   while Count>Node.Count do Nodes[Count-1].Free;
@@ -1098,9 +1109,10 @@
   end;
 end;
 
-procedure TAnchorDockLayoutTreeNode.Assign(AControl: TControl; OverrideBoundsRect: Boolean=false);
+procedure TAnchorDockLayoutTreeNode.Assign(AControl: TControl; OverrideBoundsRect: Boolean; AMinimized: Boolean);
 var
   AnchorControl: TControl;
+  ParentForm:TCustomForm;
   a: TAnchorKind;
 begin
   Name:=AControl.Name;
@@ -1109,12 +1121,18 @@
   else
     BoundsRect:=AControl.BoundsRect;
   Align:=AControl.Align;
+  Minimized:=AMinimized;
   if (AControl.Parent=nil) and (AControl is TCustomForm) then begin
     WindowState:=TCustomForm(AControl).WindowState;
     Monitor:=TCustomForm(AControl).Monitor.MonitorNum;
     WorkAreaRect:=TCustomForm(AControl).Monitor.WorkareaRect;
-  end else
-    WindowState:=GetParentForm(AControl).WindowState;
+  end else begin
+    ParentForm:=GetParentForm(AControl);
+    if assigned(ParentForm) then
+      WindowState:=ParentForm.WindowState
+    else
+      WindowState:=wsNormal;
+  end;
   if AControl is TCustomTabControl then
     TabPosition:=TCustomTabControl(AControl).TabPosition
   else
@@ -1137,6 +1155,7 @@
   Clear;
   Name:=Config.GetValue('Name','');
   NodeType:=NameToADLTreeNodeType(Config.GetValue('Type',ADLTreeNodeTypeNames[adltnNone]));
+  Minimized:=Config.GetValue('Minimized',false);
   Left:=Config.GetValue('Bounds/Left',0);
   Top:=Config.GetValue('Bounds/Top',0);
   Width:=Config.GetValue('Bounds/Width',0);
@@ -1171,6 +1190,7 @@
   Clear;
   Name:=Config.GetValue(Path+'Name','');
   NodeType:=NameToADLTreeNodeType(Config.GetValue(Path+'Type',ADLTreeNodeTypeNames[adltnNone]));
+  Minimized:=Config.GetValue(Path+'Minimized',false);
   Left:=Config.GetValue(Path+'Bounds/Left',0);
   Top:=Config.GetValue(Path+'Bounds/Top',0);
   Width:=Config.GetValue(Path+'Bounds/Width',0);
@@ -1219,6 +1239,7 @@
                                           ADLHeaderPositionNames[adlhpAuto]);
   Config.SetDeleteValue('Header/TabPosition',ADLTabPostionNames[TabPosition],
                                              ADLTabPostionNames[tpTop]);
+  Config.SetDeleteValue('Minimized',Minimized,False);
   Config.SetDeleteValue('Monitor',Monitor,0);
   Config.SetDeleteValue('ChildCount',Count,0);
   for i:=1 to Count do begin
@@ -1252,6 +1273,7 @@
                                                ADLHeaderPositionNames[adlhpAuto]);
   Config.SetDeleteValue(Path+'Header/TabPosition',ADLTabPostionNames[TabPosition],
                                                   ADLTabPostionNames[tpTop]);
+  Config.SetDeleteValue(Path+'Minimized',Minimized,False);
   Config.SetDeleteValue(Path+'Monitor',Monitor,0);
   Config.SetDeleteValue(Path+'ChildCount',Count,0);
   for i:=1 to Count do
@@ -1397,7 +1419,7 @@
   end;
 end;
 
-procedure TAnchorDockLayoutTreeNode.Simplify(ExistingNames: TStrings);
+procedure TAnchorDockLayoutTreeNode.Simplify(ExistingNames: TStrings; ParentMinimized:boolean);
 { Simplification rules:
    1. Control nodes without existing name are deleted.
    2. Empty layouts and pages are deleted
@@ -1406,16 +1428,18 @@
 var
   i: Integer;
   ChildNode: TAnchorDockLayoutTreeNode;
+  NodeMinimized:boolean;
 begin
   // simplify children
   i:=Count-1;
   while i>=0 do begin
     ChildNode:=Nodes[i];
-    ChildNode.Simplify(ExistingNames);
+    NodeMinimized:=ParentMinimized or ChildNode.Minimized;
+    ChildNode.Simplify(ExistingNames,NodeMinimized);
 
     if (ChildNode.NodeType=adltnControl) then begin
       // leaf node => check if there is a control
-      if (ChildNode.Name='') or (ExistingNames.IndexOf(ChildNode.Name)<0) then
+      if (ChildNode.Name='') or ((ExistingNames.IndexOf(ChildNode.Name)<0) and (not NodeMinimized)) then
         DeleteNode(ChildNode);
     end else if ChildNode.IsSplitter then begin
       // splitter
@@ -1424,7 +1448,7 @@
         ChildNode[0].Free;
     end else if ChildNode.NodeType=adltnCustomSite then begin
       // custom dock site
-    end else if ChildNode.Count=0 then begin
+    end else if (ChildNode.Count=0)and(not NodeMinimized) then begin
       // inner node without child => delete
       DeleteNode(ChildNode);
     end else if (ChildNode.Count=1)
Index: components/anchordocking/anchordockstr.pas
===================================================================
--- components/anchordocking/anchordockstr.pas	(revision 59428)
+++ components/anchordocking/anchordockstr.pas	(working copy)
@@ -8,6 +8,7 @@
 
 resourcestring
   adrsClose = 'Close';
+  adrsMinimize = 'Minimize';
   adrsQuit = 'Quit %s';
   adrsTabPosition = 'Tab position';
   adrsMovePageRight = 'Move page right';
@@ -82,6 +83,8 @@
   adrsFilledHeadersHint = 'Fill headers of docked controls';
   adrsHighlightFocused = 'Highlight focused';
   adrsHighlightFocusedHint = 'Highlight header of focused docked control';
+  adrsDockSitesCanBeMinimized = 'Dock sites can be minimized';
+  adrsDockSitesCanBeMinimizedHint = 'Dock sites can be minimized';
 
 implementation
 
Index: components/anchordocking/design/anchordesktopoptions.pas
===================================================================
--- components/anchordocking/design/anchordesktopoptions.pas	(revision 59428)
+++ components/anchordocking/design/anchordesktopoptions.pas	(working copy)
@@ -272,7 +272,7 @@
         // custom dock site
         LayoutNode:=FTree.NewNode(FTree.Root);
         LayoutNode.NodeType:=adltnCustomSite;
-        LayoutNode.Assign(AForm);
+        LayoutNode.Assign(AForm,false,false);
         // can have one normal dock site
         Site:=TAnchorDockManager(AForm.DockManager).GetChildSite;
         if Site<>nil then begin
@@ -287,7 +287,7 @@
         raise EAnchorDockLayoutError.Create('invalid root control for save: '+DbgSName(AControl));
     end;
     // remove invisible controls
-    FTree.Root.Simplify(VisibleControls);
+    FTree.Root.Simplify(VisibleControls,false);
   finally
     VisibleControls.Free;
     SavedSites.Free;
Index: lcl/include/dragmanager.inc
===================================================================
--- lcl/include/dragmanager.inc	(revision 59428)
+++ lcl/include/dragmanager.inc	(working copy)
@@ -484,6 +484,8 @@
         else
           DropAlign := DropOnControl.GetDockEdge(DropOnControl.ScreenToClient(APosition));
       end;
+      if DropAlign=alNone then
+        ATarget:=nil;
     end;
 
   if ATarget <> FDockObject.DragTarget then

Andrey Zubarev

2018-11-18 19:12

reporter   ~0112050

anchordocking_minimize_docksite11.patch
Dock to minimized sites disabled. But it need smal changes to lcl - dragmanager.inc

Michl

2018-11-27 09:34

developer  

test3.xml (2,232 bytes)   
<?xml version="1.0" encoding="utf-8"?>
<CONFIG>
  <MainConfig>
    <Nodes ChildCount="1">
      <Item1 Name="MainIDE" Type="CustomSite" ChildCount="1">
        <Bounds Top="50" Left="100" Width="722" Height="502">
          <WorkArea>
            <Rect Right="1920" Bottom="1036"/>
          </WorkArea>
        </Bounds>
        <Item1 Name="AnchorDockSite6" Type="Layout" ChildCount="9">
          <Bounds Top="58" Width="722" Height="420" SplitterPos="53"/>
          <Anchors Align="Bottom"/>
          <Item1 Name="ObjectInspector" Type="Control">
            <Bounds Width="177" Height="420"/>
            <Anchors Right="AnchorDockSplitter2"/>
          </Item1>
          <Item2 Name="AnchorDockSplitter2" Type="SplitterVertical">
            <Bounds Left="177" Width="4" Height="420"/>
          </Item2>
          <Item3 Name="SourceEditor1" Type="Control">
            <Bounds Left="181" Width="160" Height="420"/>
            <Anchors Left="AnchorDockSplitter2" Right="AnchorDockSplitter4"/>
          </Item3>
          <Item4 Name="FPDocEditor" Type="Control">
            <Bounds Left="632" Width="90" Height="420"/>
            <Anchors Left="AnchorDockSplitter3"/>
          </Item4>
          <Item5 Name="AnchorDockSplitter4" Type="SplitterVertical">
            <Bounds Left="341" Width="4" Height="420"/>
          </Item5>
          <Item6 Name="Messages" Type="Control" Minimized="True">
            <Bounds Left="345" Width="15" Height="420"/>
            <Anchors Left="AnchorDockSplitter4" Right="AnchorDockSplitter5"/>
          </Item6>
          <Item7 Name="AnchorDockSplitter5" Type="SplitterVertical">
            <Bounds Left="522" Width="4" Height="420"/>
          </Item7>
          <Item8 Name="ProjectInspector" Type="Control">
            <Bounds Left="364" Width="264" Height="420"/>
            <Anchors Left="AnchorDockSplitter5" Right="AnchorDockSplitter3"/>
          </Item8>
          <Item9 Name="AnchorDockSplitter3" Type="SplitterVertical">
            <Bounds Left="628" Width="4" Height="420"/>
          </Item9>
        </Item1>
      </Item1>
    </Nodes>
  </MainConfig>
  <Settings DockSitecCanBeMinimized="True"/>
</CONFIG>
test3.xml (2,232 bytes)   

Michl

2018-11-27 09:50

developer   ~0112225

Sorry for the delay, currently I have very low spare time and I want test the issue before I commit the patch.

Please load test3.xml. There are two issues.

1. The minimize button of Source Editor 1 is missing. This is maybe per design but if someone will use this feature, he might minimize more then one site at one place.

2.Minimize Project Inspector, then you have some space. Maybe thatswhile you don't show the minimize button?!

I get a Range Error in Lazarus-IDE with Qt, maybe because of 2. ?!

A further minor issue I see. The background of the form caption in Qt is further transparent for the popup.

Andrey Zubarev

2018-11-27 11:48

reporter   ~0112229

Last edited: 2018-11-27 11:50

View 2 revisions

1.2. Yes, it by design. Project Inspector also should not have a minimize button. if the adjacent window is minimized, this window should not have a minimize button

I'll fix it soon. too there were of free time problems

>>I get a Range Error in Lazarus-IDE with Qt, maybe because of 2. ?!
I have not encountered this.

>>A further minor issue I see. The background of the form caption in Qt is further transparent for the popup.
there is still an incorrect getting of popup window borders if it popup on paged site. I think it's a qt issue.

Andrey Zubarev

2018-11-27 20:15

reporter  

anchordocking_minimize_docksite12.patch (78,825 bytes)   
Index: components/anchordocking/anchordocking.pas
===================================================================
--- components/anchordocking/anchordocking.pas	(revision 59428)
+++ components/anchordocking/anchordocking.pas	(working copy)
@@ -109,6 +109,37 @@
 const ADAutoSizingReason = 'TAnchorDockMaster Delayed';
 {$ENDIF}
 
+const EmptyMouseTimeStartX=low(Integer);
+      MouseNoMoveDelta=5;
+      MouseNoMoveTime=500;
+      HideOverlappingFormByMouseLoseTime=500;
+      ButtonBorderSpacingAround=4;
+      OppositeAnchorKind2Align: array[TAnchorKind] of TAlign = (
+        alBottom, // akTop,
+        alRight,  // akLeft,
+        alLeft,   // akRight,
+        alTop     // akBottom
+        );
+      OppositeAnchorKind: array[TAnchorKind] of TAnchorKind = (
+        akBottom, // akTop,
+        akRight,  // akLeft,
+        akLeft,   // akRight,
+        akTop     // akBottom
+        );
+      {AnchorKind2Align: array[TAnchorKind] of TAlign = (
+        alTop,  // akTop,
+        alLeft, // akLeft,
+        alRight,// akRight,
+        alBottom// akBottom
+        );}
+      OppositeAnchorKind2TADLHeaderPosition: array[TAnchorKind] of TADLHeaderPosition = (
+        adlhpBottom, // akTop,
+        adlhpRight,  // akLeft,
+        adlhpLeft,   // akRight,
+        adlhpTop     // akBottom
+        );
+
+
 type
   TAnchorDockHostSite = class;
 
@@ -123,6 +154,14 @@
            PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
   end;
 
+  TAnchorDockMinimizeButton = class(TCustomSpeedButton)
+  protected
+    function GetDrawDetails: TThemedElementDetails; override;
+    procedure CalculatePreferredSize(var PreferredWidth,
+           PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); override;
+  end;
+
+
   { TAnchorDockHeader
     The panel of a TAnchorDockHostSite containing the close button and the
     caption when the form is docked. The header can be shown at any of the four
@@ -133,9 +172,13 @@
   TAnchorDockHeader = class(TCustomPanel)
   private
     FCloseButton: TCustomSpeedButton;
+    FMinimizeButton: TCustomSpeedButton;
     FHeaderPosition: TADLHeaderPosition;
     fFocused:Boolean;
+    fUseTimer:Boolean;
+    FMouseTimeStartX,FMouseTimeStartY:Integer;
     procedure CloseButtonClick(Sender: TObject);
+    procedure MinimizeButtonClick(Sender: TObject);
     procedure HeaderPositionItemClick(Sender: TObject);
     procedure UndockButtonClick(Sender: TObject);
     procedure MergeButtonClick(Sender: TObject);
@@ -147,6 +190,11 @@
           PreferredHeight: integer; WithThemeSpace: Boolean); override;
     procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X,
              Y: Integer); override;
+    procedure MouseMove(Shift: TShiftState; X,Y: Integer); override;
+    procedure MouseLeave;  override;
+    procedure StartMouseNoMoveTimer(X, Y: Integer);
+    procedure StopMouseNoMoveTimer;
+    procedure DoMouseNoMoveTimer(Sender: TObject);
     procedure UpdateHeaderControls;
     procedure SetAlign(Value: TAlign); override;
     procedure DoOnShowHint(HintInfo: PHintInfo); override;
@@ -154,6 +202,7 @@
   public
     constructor Create(TheOwner: TComponent); override;
     property CloseButton: TCustomSpeedButton read FCloseButton;
+    property MinimizeButton: TCustomSpeedButton read FMinimizeButton;
     property HeaderPosition: TADLHeaderPosition read FHeaderPosition write SetHeaderPosition;
     property BevelOuter default bvNone;
   end;
@@ -190,6 +239,7 @@
     procedure SetBoundsKeepDockBounds(ALeft, ATop, AWidth, AHeight: integer); // movement for scaling keeps the DockBounds
     function SideAnchoredControlCount(Side: TAnchorKind): integer;
     function HasAnchoredControls: boolean;
+    function GetSpliterBoundsWithUnminimizedDockSites:TRect;
     procedure SaveLayout(LayoutNode: TAnchorDockLayoutTreeNode);
     function HasOnlyOneSibling(Side: TAnchorKind; MinPos, MaxPos: integer): TControl;
     property DockRestoreBounds: TRect read FDockRestoreBounds write FDockRestoreBounds;
@@ -241,6 +291,14 @@
   end;
   TAnchorDockPageControlClass = class of TAnchorDockPageControl;
 
+
+  TAnchorDockOverlappingForm = class(TCustomForm)
+  public
+    AnchorDockHostSite:TAnchorDockHostSite;
+    Panel:TPanel;
+    constructor CreateNew(AOwner: TComponent; Num: Integer = 0); override;
+  end;
+
   { TAnchorDockHostSite
     This form is the dockhostsite for all controls.
     When docked together they build a tree structure with the docked controls
@@ -262,7 +320,10 @@
     FPages: TAnchorDockPageControl;
     FSiteType: TAnchorDockHostSiteType;
     FBoundSplitter: TAnchorDockSplitter;
-    fUpdateLayout: integer;
+    fUpdateLayout: Integer;
+    FMinimized: Boolean;
+    fMinimization: Boolean;
+    FMinimizedControl: TControl;
     procedure SetHeaderSide(const AValue: TAnchorKind);
   protected
     procedure DoEnter; override;
@@ -319,6 +380,10 @@
     destructor Destroy; override;
     function CloseQuery: boolean; override;
     function CloseSite: boolean; virtual;
+    procedure MinimizeSite; virtual;
+    procedure AsyncMinimizeSite(Data: PtrInt);
+    procedure ShowMinimizedControl;
+    procedure HideMinimizedControl;
     procedure RemoveControl(AControl: TControl); override;
     procedure InsertControl(AControl: TControl; Index: integer); override;
     procedure GetSiteInfo(Client: TControl; var InfluenceRect: TRect;
@@ -329,6 +394,7 @@
     procedure UpdateDockCaption(Exclude: TControl = nil); override;
     procedure UpdateHeaderAlign;
     procedure UpdateHeaderShowing;
+    function CanBeMinimized(out Splitter: TAnchorDockSplitter; out SplitterAnchorKind:TAnchorKind):boolean;
     procedure BeginUpdateLayout;
     procedure EndUpdateLayout;
     function UpdatingLayout: boolean;
@@ -337,6 +403,7 @@
     procedure SaveLayout(LayoutTree: TAnchorDockLayoutTree;
                          LayoutNode: TAnchorDockLayoutTreeNode);
     property DockRestoreBounds: TRect read FDockRestoreBounds write FDockRestoreBounds;
+    function GetDockEdge(const MousePos: TPoint): TAlign; override;
 
     property HeaderSide: TAnchorKind read FHeaderSide write SetHeaderSide;
     property Header: TAnchorDockHeader read FHeader;
@@ -431,6 +498,7 @@
     FShowHeader: boolean;
     FShowHeaderCaption: boolean;
     FSplitterWidth: integer;
+    FDockSitecCanBeMinimized: boolean;
     procedure SetAllowDragging(AValue: boolean);
     procedure SetDockOutsideMargin(AValue: integer);
     procedure SetDockParentMargin(AValue: integer);
@@ -448,6 +516,7 @@
     procedure SetHeaderFlatten(AValue: boolean);
     procedure SetHeaderFilled(AValue: boolean);
     procedure SetHeaderHighlightFocused(AValue: boolean);
+    procedure SetDockSitecCanBeMinimized(AValue: boolean);
   public
     property DragTreshold: integer read FDragTreshold write SetDragTreshold;
     property DockOutsideMargin: integer read FDockOutsideMargin write SetDockOutsideMargin;
@@ -466,6 +535,7 @@
     property HeaderFlatten: boolean read FHeaderFlatten write SetHeaderFlatten;
     property HeaderFilled: boolean read FHeaderFilled write SetHeaderFilled;
     property HeaderHighlightFocused: boolean read FHeaderHighlightFocused write SetHeaderHighlightFocused;
+    property DockSitesCanBeMinimized: boolean read FDockSitecCanBeMinimized write SetDockSitecCanBeMinimized;
     procedure IncreaseChangeStamp; inline;
     property ChangeStamp: integer read FChangeStamp;
     procedure LoadFromConfig(Config: TConfigStorage); overload;
@@ -502,6 +572,7 @@
     FHeaderFlatten: boolean;
     FHeaderFilled: boolean;
     FHeaderHighlightFocused: boolean;
+    FDockSitesCanBeMinimized: boolean;
     FIdleConnected: Boolean;
     FManagerClass: TAnchorDockManagerClass;
     FOnCreateControl: TADCreateControlEvent;
@@ -531,6 +602,7 @@
     fPopupMenu: TPopupMenu;
     // Used by RestoreLayout:
     WorkArea, SrcWorkArea: TRect;
+    FOverlappingForm:TAnchorDockOverlappingForm;
 
     function GetControls(Index: integer): TControl;
     function GetLocalizedHeaderHint: string;
@@ -541,6 +613,9 @@
     function GetNodeSite(Node: TAnchorDockLayoutTreeNode): TAnchorDockHostSite;
     procedure MapTreeToControls(Tree: TAnchorDockLayoutTree);
     function RestoreLayout(Tree: TAnchorDockLayoutTree; Scale: boolean): boolean;
+    procedure SetMinimizedState(Tree: TAnchorDockLayoutTree);
+    procedure UpdateHeaders;
+    procedure SetnodeMinimizedState(ANode: TAnchorDockLayoutTreeNode);
     procedure EnableAllAutoSizing;
     procedure ClearLayoutProperties(AControl: TControl; NewAlign: TAlign = alClient);
     procedure PopupMenuPopup(Sender: TObject);
@@ -561,6 +636,7 @@
     procedure SetHeaderFlatten(AValue: boolean);
     procedure SetHeaderFilled(AValue: boolean);
     procedure SetHeaderHighlightFocused(AValue: boolean);
+    procedure SetDockSitesCanBeMinimized(AValue: boolean);
 
     procedure SetShowMenuItemShowHeader(AValue: boolean);
     procedure SetupSite(Site: TWinControl; ANode: TAnchorDockLayoutTreeNode;
@@ -584,8 +660,12 @@
     procedure SetHideHeaderCaptionFloatingControl(const AValue: boolean);
     procedure SetSplitterWidth(const AValue: integer);
     procedure OnIdle(Sender: TObject; var Done: Boolean);
+    procedure StartHideOverlappingTimer;
+    procedure StopHideOverlappingTimer;
     procedure AsyncSimplify({%H-}Data: PtrInt);
   public
+    procedure ShowOverlappingForm;
+    procedure HideOverlappingForm(Sender: TObject);
     constructor Create(AOwner: TComponent); override;
     destructor Destroy; override;
     function FullRestoreLayout(Tree: TAnchorDockLayoutTree; Scale: Boolean): Boolean;
@@ -680,6 +760,7 @@
     property HeaderFlatten: boolean read FHeaderFlatten write SetHeaderFlatten default true;
     property HeaderFilled: boolean read FHeaderFilled write SetHeaderFilled default true;
     property HeaderHighlightFocused: boolean read FHeaderHighlightFocused write SetHeaderHighlightFocused default false;
+    property DockSitesCanBeMinimized: boolean read FDockSitesCanBeMinimized write SetDockSitesCanBeMinimized default false;
 
     property SplitterWidth: integer read FSplitterWidth write SetSplitterWidth default 4;
     property ScaleOnResize: boolean read FScaleOnResize write SetScaleOnResize default true; // scale children when resizing a site
@@ -698,8 +779,14 @@
 
 var
   DockMaster: TAnchorDockMaster = nil;
+  DockTimer: TTimer = nil;
 
+  PreferredButtonWidth:integer=-1;
+  PreferredButtonHeight:integer=-1;
+
+
 const
+  HardcodedButtonSize:integer=13;
   ADHeaderStyleNames: array[TADHeaderStyle] of string = (
     'Frame3D',
     'Line',
@@ -970,6 +1057,27 @@
   end;
 end;
 
+function CountAndReturnOnlyOneMinimizedAnchoredControls(Control: TControl; Side: TAnchorKind): TAnchorDockHostSite;
+var
+  i,Counter: Integer;
+  Neighbour: TControl;
+begin
+  Counter:=0;
+  for i:=0 to Control.AnchoredControlCount-1 do begin
+    Neighbour:=Control.AnchoredControls[i];
+    if Neighbour.Visible then
+    if Neighbour is TAnchorDockHostSite then
+    if (OppositeAnchor[Side] in Neighbour.Anchors)
+    and (Neighbour.AnchorSide[OppositeAnchor[Side]].Control=Control) then begin
+      inc(Counter);
+      result:=TAnchorDockHostSite(Neighbour);
+    end;
+  end;
+  if (Counter=1)and(result is TAnchorDockHostSite)and((result as TAnchorDockHostSite).FMinimized) then
+  else
+    result:=Nil;
+end;
+
 function NeighbourCanBeShrinked(EnlargeControl, Neighbour: TControl;
   Side: TAnchorKind): boolean;
 { returns true if Neighbour can be shrinked on the opposite side of Side
@@ -1361,6 +1469,13 @@
   IncreaseChangeStamp;
 end;
 
+procedure TAnchorDockSettings.SetDockSitecCanBeMinimized(AValue: boolean);
+begin
+  if FDockSitecCanBeMinimized=AValue then Exit;
+  FDockSitecCanBeMinimized:=AValue;
+  IncreaseChangeStamp;
+end;
+
 procedure TAnchorDockSettings.Assign(Source: TAnchorDockSettings);
 begin
   FAllowDragging := Source.FAllowDragging;
@@ -1381,6 +1496,7 @@
   FShowHeaderCaption := Source.FShowHeaderCaption;
   FSplitterWidth := Source.FSplitterWidth;
   FHeaderHighlightFocused:=Source.FHeaderHighlightFocused;
+  FDockSitecCanBeMinimized:=Source.FDockSitecCanBeMinimized;
 end;
 
 procedure TAnchorDockSettings.IncreaseChangeStamp;
@@ -1407,6 +1523,7 @@
   HeaderFlatten:=Config.GetValue('HeaderFlatten',true);
   HeaderFilled:=Config.GetValue('HeaderFilled',true);
   HeaderHighlightFocused:=Config.GetValue('HeaderHighlightFocused',False);
+  DockSitesCanBeMinimized:=Config.GetValue('DockSitecCanBeMinimized',False);
   Config.UndoAppendBasePath;
 end;
 
@@ -1429,6 +1546,7 @@
   Config.SetDeleteValue(Path+'HeaderFlatten',HeaderFlatten,true);
   Config.SetDeleteValue(Path+'HeaderFilled',HeaderFilled,true);
   Config.SetDeleteValue(Path+'HeaderHighlightFocused',HeaderHighlightFocused,False);
+  Config.SetDeleteValue(Path+'DockSitecCanBeMinimized',DockSitesCanBeMinimized,False);
 end;
 
 procedure TAnchorDockSettings.SaveToConfig(Config: TConfigStorage);
@@ -1450,6 +1568,7 @@
   Config.SetDeleteValue('HeaderFlatten',HeaderFlatten,true);
   Config.SetDeleteValue('HeaderFilled',HeaderFilled,true);
   Config.SetDeleteValue('HeaderHighlightFocused',HeaderHighlightFocused,False);
+  Config.SetDeleteValue('DockSitecCanBeMinimized',DockSitesCanBeMinimized,False);
   Config.UndoAppendBasePath;
 end;
 
@@ -1472,6 +1591,7 @@
       and (HeaderFlatten=Settings.HeaderFlatten)
       and (HeaderFilled=Settings.HeaderFilled)
       and (HeaderHighlightFocused=Settings.HeaderHighlightFocused)
+      and (DockSitesCanBeMinimized=Settings.DockSitesCanBeMinimized)
       ;
 end;
 
@@ -1494,6 +1614,7 @@
   HeaderFlatten:=Config.GetValue(Path+'HeaderFlatten',true);
   HeaderFilled:=Config.GetValue(Path+'HeaderFilled',true);
   HeaderHighlightFocused:=Config.GetValue(Path+'HeaderHighlightFocused',False);
+  DockSitesCanBeMinimized:=Config.GetValue(Path+'DockSitecCanBeMinimized',False);
 end;
 
 { TAnchorDockMaster }
@@ -2021,6 +2142,8 @@
     aHostSite:=TAnchorDockHostSite(Site);
     aHostSite.Header.HeaderPosition:=ANode.HeaderPosition;
     aHostSite.DockRestoreBounds:=NewBounds;
+    //aHostSite.FMinimized:=ANode.Minimized;
+    //we update aHostSite.FMinimized in TAnchorDockMaster.SetMinimizedState
     if (ANode.NodeType<>adltnPages) and (aHostSite.Pages<>nil) then
       aHostSite.FreePages;
   end;
@@ -2040,6 +2163,25 @@
   fTreeNameToDocker[Node.Name]:=Result;
 end;
 
+procedure TAnchorDockMaster.SetNodeMinimizedState(ANode: TAnchorDockLayoutTreeNode);
+var
+  HostSite:TAnchorDockHostSite;
+  i:integer;
+begin
+  HostSite:=GetNodeSite(ANode);
+  if Assigned(HostSite) then
+    if HostSite.FMinimized<>ANode.Minimized then
+      Application.QueueAsyncCall(@HostSite.AsyncMinimizeSite,0);
+      //HostSite.MinimizeSite;
+  for i:=0 to ANode.Count-1 do
+    SetnodeMinimizedState(ANode.Nodes[i]);
+end;
+
+procedure TAnchorDockMaster.SetMinimizedState(Tree: TAnchorDockLayoutTree);
+begin
+  SetnodeMinimizedState(Tree.Root);
+end;
+
 function TAnchorDockMaster.RestoreLayout(Tree: TAnchorDockLayoutTree;
   Scale: boolean): boolean;
 
@@ -2193,7 +2335,7 @@
       try
         SetupSite(Site,ANode,AParent);
         Site.FSiteType:=adhstPages;
-        Site.Header.Parent:=nil;
+        //Site.Header.Parent:=nil;
         if Site.Pages=nil then
           Site.CreatePages;
         for i:=0 to ANode.Count-1 do begin
@@ -2358,7 +2500,7 @@
       debugln(ControlNames.Text);
       {$ENDIF}
       // if some forms/controls could not be created the layout needs to be adapted
-      Tree.Root.Simplify(ControlNames);
+      Tree.Root.Simplify(ControlNames,false);
 
       // reuse existing sites to reduce flickering
       MapTreeToControls(Tree);
@@ -2368,6 +2510,7 @@
 
       // create sites, move controls
       RestoreLayout(Tree,Scale);
+      SetMinimizedState(Tree);
     finally
       EndUpdate;
     end;
@@ -2422,11 +2565,54 @@
   OptionsChanged;
 end;
 
+procedure TAnchorDockMaster.StartHideOverlappingTimer;
+begin
+  if not DockTimer.Enabled then begin
+    DockTimer.Interval:=HideOverlappingFormByMouseLoseTime;
+    DockTimer.OnTimer:=@HideOverlappingForm;
+    DockTimer.Enabled:=true;
+  end;
+end;
+
+procedure TAnchorDockMaster.StopHideOverlappingTimer;
+begin
+  DockTimer.Enabled:=False;
+  DockTimer.Interval:=0;
+  DockTimer.OnTimer:=nil;
+end;
+
+function IsParentControl(aParent, aControl: TControl): boolean;
+begin
+  while (aControl <> nil) and (aControl.Parent <> nil) do
+  begin
+    if (aControl=aParent) then
+      exit(true);
+    aControl := aControl.Parent;
+  end;
+  result:=aControl=aParent;
+end;
+
+
 procedure TAnchorDockMaster.OnIdle(Sender: TObject; var Done: Boolean);
+var
+  MousePos: TPoint;
+  Bounds:Trect;
 begin
   if Done then ;
-  IdleConnected:=false;
   Restoring:=false;
+  if FOverlappingForm=nil then
+    IdleConnected:=false
+  else begin
+    GetCursorPos(MousePos);
+    Bounds.TopLeft:=FOverlappingForm.ClientToScreen(point(0,0));
+    Bounds.BottomRight:=FOverlappingForm.ClientToScreen(point(FOverlappingForm.Width,FOverlappingForm.Height));
+    if not IsParentControl(FOverlappingForm, GetCaptureControl) then begin
+      if not PtInRect(Bounds,MousePos) then
+          StartHideOverlappingTimer
+        else
+          StopHideOverlappingTimer;
+    end;
+  end;
 end;
 
 procedure TAnchorDockMaster.AsyncSimplify(Data: PtrInt);
@@ -2514,6 +2700,18 @@
   InvalidateHeaders;
 end;
 
+procedure TAnchorDockMaster.SetDockSitesCanBeMinimized(AValue: boolean);
+var
+  i:integer;
+  Site: TAnchorDockHostSite;
+begin
+  if FDockSitesCanBeMinimized=AValue then Exit;
+  FDockSitesCanBeMinimized:=AValue;
+  UpdateHeaders;
+  InvalidateHeaders;
+  EnableAllAutoSizing;
+  OptionsChanged;
+end;
 procedure TAnchorDockMaster.SetScaleOnResize(AValue: boolean);
 begin
   if FScaleOnResize=AValue then Exit;
@@ -2598,6 +2796,9 @@
     if (Site.Header<>nil) then begin
       DisableControlAutoSizing(Site);
       Site.UpdateHeaderShowing;
+      if Site.fminimized then
+        if not AValue then
+          site.MinimizeSite;
     end;
   end;
   EnableAllAutoSizing;
@@ -2668,6 +2869,20 @@
     EnableAllAutoSizing;
 end;
 
+procedure TAnchorDockMaster.ShowOverlappingForm;
+begin
+  FOverlappingForm.Show;
+  IdleConnected:=true;
+end;
+
+procedure TAnchorDockMaster.HideOverlappingForm(Sender: TObject);
+begin
+  StopHideOverlappingTimer;
+  FOverlappingForm.Hide;
+  FOverlappingForm.AnchorDockHostSite.HideMinimizedControl;
+  IdleConnected:=false;
+end;
+
 constructor TAnchorDockMaster.Create(AOwner: TComponent);
 begin
   inherited Create(AOwner);
@@ -2698,14 +2913,14 @@
   FPageClass:=TAnchorDockPage;
   FRestoreLayouts:=TAnchorDockRestoreLayouts.Create;
   FHeaderHighlightFocused:=false;
+  FDockSitesCanBeMinimized:=false;
+  FOverlappingForm:=nil;
 end;
 
 destructor TAnchorDockMaster.Destroy;
 var
   AControl: TControl;
-  {$IFDEF VerboseAnchorDocking}
-  i: Integer;
-  {$ENDIF}
+  i, j: Integer;
 begin
   QueueSimplify:=false;
   FreeAndNil(FRestoreLayouts);
@@ -2727,6 +2942,12 @@
     debugln(['TAnchorDockMaster.Destroy ',i,'/',ComponentCount,' ',DbgSName(Components[i])]);
   end;
   {$ENDIF}
+  for i:=0 to ComponentCount-1 do begin
+    for j:=0 to ComponentCount-1 do begin
+      if i<>j then
+        TControl(Components[i]).RemoveAllHandlersOfObject(TControl(Components[j]));
+  end;
+  end;
   inherited Destroy;
 end;
 
@@ -2914,6 +3135,7 @@
       raise Exception.Create('TAnchorDockMaster.MakeDockable '+Format(
         adrsNotSupportedHasParent, [DbgSName(AControl), DbgSName(AControl)]));
     end;
+    site.UpdateHeaderShowing;
     if (Site<>nil) and Show then
       MakeVisible(Site,BringToFront);
   finally
@@ -3018,7 +3240,8 @@
   i:=Screen.CustomFormCount-1;
   while i>=0 do begin
     AForm:=GetParentForm(Screen.CustomForms[i]);
-    AForm.Hide;
+    if Assigned(AForm)then
+      AForm.Hide;
     i:=Min(i,Screen.CustomFormCount)-1;
   end;
 
@@ -3062,8 +3285,11 @@
   end;
 end;
 
-function GetParentFormOrDockPanel(Control: TControl): TCustomForm;
+function GetParentFormOrDockPanel(Control: TControl; TopForm:Boolean=true): TCustomForm;
+var
+  oldControl: TControl;
 begin
+  oldControl:=Control;
   while (Control <> nil) and (Control.Parent <> nil) do
   begin
     if (Control is TAnchorDockPanel) then
@@ -3076,6 +3302,18 @@
     Result := TCustomForm(Control)
   else
     Result := nil;
+  if not TopForm then begin
+    if Control is TAnchorDockPanel then
+      exit;
+    Control:=oldControl;
+    while (Control <> nil) and (Control.Parent <> nil) do
+    begin
+      Control := Control.Parent;
+      if (Control is TCustomForm) then
+        Break;
+    end;
+    Result := TCustomForm(Control);
+  end;
 end;
 
 procedure TAnchorDockMaster.SaveMainLayoutToTree(LayoutTree: TAnchorDockLayoutTree);
@@ -3088,12 +3326,12 @@
   AFormOrDockPanel: TWinControl;
   VisibleControls: TStringList;
 
-  procedure SaveFormOrDockPanel(theFormOrDockPanel: TWinControl; SaveChildren: boolean);
+  procedure SaveFormOrDockPanel(theFormOrDockPanel: TWinControl; SaveChildren: boolean; AMinimized:boolean);
   begin
     // custom dock site
     LayoutNode:=LayoutTree.NewNode(LayoutTree.Root);
     LayoutNode.NodeType:=adltnCustomSite;
-    LayoutNode.Assign(theFormOrDockPanel,theFormOrDockPanel is TAnchorDockPanel);
+    LayoutNode.Assign(theFormOrDockPanel,theFormOrDockPanel is TAnchorDockPanel,AMinimized);
     // can have one normal dock site
     if SaveChildren then
     begin
@@ -3124,7 +3362,7 @@
       debugln(['TAnchorDockMaster.SaveMainLayoutToTree AForm=',DbgSName(AFormOrDockPanel)]);
       DebugWriteChildAnchors(AFormOrDockPanel,true,true);
       if AFormOrDockPanel is TAnchorDockPanel then begin
-        SaveFormOrDockPanel(GetParentFormOrDockPanel(AFormOrDockPanel),{false}true);
+        SaveFormOrDockPanel(GetParentFormOrDockPanel(AFormOrDockPanel),true,false);
         //LayoutNode:=LayoutTree.NewNode(LayoutTree.Root);
         //TAnchorDockPanel(AFormOrDockPanel).SaveLayout(LayoutTree,LayoutNode);
       end else if AFormOrDockPanel is TAnchorDockHostSite then begin
@@ -3132,12 +3370,12 @@
         LayoutNode:=LayoutTree.NewNode(LayoutTree.Root);
         Site.SaveLayout(LayoutTree,LayoutNode);
       end else if IsCustomSite(AFormOrDockPanel) then begin
-        SaveFormOrDockPanel(AFormOrDockPanel,true);
+        SaveFormOrDockPanel(AFormOrDockPanel,true,false);
       end else
         raise EAnchorDockLayoutError.Create('invalid root control for save: '+DbgSName(AControl));
     end;
     // remove invisible controls
-    LayoutTree.Root.Simplify(VisibleControls);
+    LayoutTree.Root.Simplify(VisibleControls,false);
   finally
     VisibleControls.Free;
     SavedSites.Free;
@@ -3157,7 +3395,7 @@
     (AControl as TAnchorDockPanel).SaveLayout(LayoutTree,LayoutTree.Root);
   end else if IsCustomSite(AControl) then begin
     LayoutTree.Root.NodeType:=adltnCustomSite;
-    LayoutTree.Root.Assign(AControl);
+    LayoutTree.Root.Assign(AControl,false,false);
     // can have one normal dock site
     Site:=TAnchorDockManager(AControl.DockManager).GetChildSite;
     if Site<>nil then begin
@@ -3252,7 +3490,7 @@
       debugln(ControlNames.Text);
       {$ENDIF}
       // if some forms/controls could not be created the layout needs to be adapted
-      Tree.Root.Simplify(ControlNames);
+      Tree.Root.Simplify(ControlNames,false);
 
       // reuse existing sites to reduce flickering
       MapTreeToControls(Tree);
@@ -3262,6 +3500,7 @@
 
       // create sites, move controls
       RestoreLayout(Tree,Scale);
+      SetMinimizedState(Tree);
     finally
       EndUpdate;
     end;
@@ -3323,6 +3562,7 @@
   HeaderFlatten                    := Settings.HeaderFlatten;
   HeaderFilled                     := Settings.HeaderFilled;
   HeaderHighlightFocused           := Settings.HeaderHighlightFocused;
+  DockSitesCanBeMinimized          := Settings.DockSitesCanBeMinimized;
 end;
 
 procedure TAnchorDockMaster.SaveSettings(Settings: TAnchorDockSettings);
@@ -3343,6 +3583,7 @@
   Settings.HeaderFlatten:=HeaderFlatten;
   Settings.HeaderFilled:=HeaderFilled;
   Settings.HeaderHighlightFocused:=HeaderHighlightFocused;
+  Settings.DockSitesCanBeMinimized:=DockSitesCanBeMinimized;
 end;
 
 function TAnchorDockMaster.SettingsAreEqual(Settings: TAnchorDockSettings
@@ -3436,8 +3677,11 @@
   if fUpdateCount<=0 then
     RaiseGDBException('');
   dec(fUpdateCount);
-  if fUpdateCount=0 then
+  if fUpdateCount=0 then begin
     SimplifyPendingLayouts;
+    UpdateHeaders;
+    InvalidateHeaders;
+  end;
 end;
 
 function TAnchorDockMaster.IsReleasing(AControl: TControl): Boolean;
@@ -3664,6 +3908,24 @@
   LUIncreaseChangeStamp64(FOptionsChangeStamp);
 end;
 
+procedure TAnchorDockMaster.UpdateHeaders;
+var
+  i: Integer;
+  AControl: TControl;
+  AHostSite: TAnchorDockHostSite;
+begin
+    for i:=0 to ControlCount-1 do begin
+      AControl:=Controls[i];
+      if not DockedControlIsVisible(AControl) then continue;
+      while Assigned(AControl) do
+      begin
+        if AControl is TAnchorDockHostSite then
+          TAnchorDockHostSite(AControl).UpdateHeaderShowing;
+        AControl:=AControl.parent;
+      end;
+    end;
+end;
+
 { TAnchorDockHostSite }
 
 procedure TAnchorDockHostSite.SetHeaderSide(const AValue: TAnchorKind);
@@ -3680,6 +3942,7 @@
     AControl:=TControl(Sender);
     if not (csDestroying in ComponentState) then begin
       if (not AControl.Visible)
+      and (not FMinimized)
       and (not ((AControl is TAnchorDockHeader)
                or (AControl is TAnchorDockSplitter)
                or (AControl is TAnchorDockHostSite)))
@@ -4119,6 +4382,8 @@
 end;
 
 procedure TAnchorDockHostSite.FreePages;
+var
+  i:Integer;
 begin
   FreeAndNil(FPages);
 end;
@@ -4233,6 +4498,14 @@
         akRight: NewBounds.Right:=AControl.Left+AControl.Width;
         akBottom: NewBounds.Bottom:=AControl.Top+AControl.Height;
         end;
+        if (sibling is TAnchorDockHostSite) then
+        if (sibling as TAnchorDockHostSite).FMinimized then begin
+          (sibling as TAnchorDockHostSite).FMinimized:=false;
+          (sibling as TAnchorDockHostSite).FMinimizedControl.Parent:=(sibling as TAnchorDockHostSite);
+          (sibling as TAnchorDockHostSite).FMinimizedControl.Visible:=True;
+          (sibling as TAnchorDockHostSite).FMinimizedControl:=nil;
+          (sibling as TAnchorDockHostSite).UpdateHeaderAlign;
+        end;
         Sibling.BoundsRect:=NewBounds;
       end;
     end;
@@ -4306,6 +4579,13 @@
       FSiteType:=adhstOneControl;
       OnlySiteLeft.Align:=alClient;
       Header.Parent:=Self;
+      if OnlySiteLeft.FMinimized then begin
+        OnlySiteLeft.FMinimized:=false;
+        OnlySiteLeft.FMinimizedControl.Parent:=OnlySiteLeft;
+        OnlySiteLeft.FMinimizedControl.Visible:=True;
+        OnlySiteLeft.FMinimizedControl:=nil;
+        UpdateHeaderAlign;
+      end;
       UpdateHeaderAlign;
 
       //debugln(['TAnchorDockHostSite.RemoveControlFromLayout.ConvertToOneControlType AFTER CONVERT "',Caption,'" to onecontrol OnlySiteLeft="',OnlySiteLeft.Caption,'"']);
@@ -4465,7 +4745,7 @@
     debugln(['TAnchorDockHostSite.Simplify ',DbgSName(Self),' ',DbgSName(AControl)]);
     if AControl is TAnchorDockHostSite then
       SimplifyOneControl
-    else if (AControl=nil) or (csDestroying in AControl.ComponentState) then
+    else if ((AControl=nil) or (csDestroying in AControl.ComponentState)) then
       DockMaster.NeedFree(Self);
   end;
 end;
@@ -4577,7 +4857,8 @@
     Result:=Controls[i];
     if Result.Owner<>Self then exit;
   end;
-  Result:=nil;
+  result:=FMinimizedControl;
+  //Result:=nil;
 end;
 
 function TAnchorDockHostSite.GetSiteCount: integer;
@@ -5165,6 +5446,125 @@
   Result:=Check(Self);
 end;
 
+function CheckOposite(Side:TAnchorKind;AControl: TControl;out Splitter: TAnchorDockSplitter; out SplitterAnchorKind:TAnchorKind):boolean;
+begin
+  result:=GetDockSplitter(AControl,Side,Splitter);
+  if result then begin
+    if CountAnchoredControls(Splitter,OppositeAnchor[Side])=1 then begin
+      SplitterAnchorKind:=Side;
+      exit;
+    end;
+  end;
+  result:=false
+end;
+
+function FindNearestSpliter(AControl: TControl;out Splitter: TAnchorDockSplitter;out SplitterAnchorKind:TAnchorKind):boolean;
+begin
+  result:=CheckOposite(akTop,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akRight,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akBottom,AControl,Splitter,SplitterAnchorKind);
+  if result then exit;
+  result:=CheckOposite(akLeft,AControl,Splitter,SplitterAnchorKind);
+end;
+
+function TAnchorDockHostSite.CanBeMinimized(out Splitter: TAnchorDockSplitter;
+                                            out SplitterAnchorKind:TAnchorKind):boolean;
+var
+  //AControl: TControl;
+  OpositeDockHostSite:TAnchorDockHostSite;
+  OpositeSplitter: TAnchorDockSplitter;
+begin
+  result:=false;
+  if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+    OpositeDockHostSite:=CountAndReturnOnlyOneMinimizedAnchoredControls(Splitter,SplitterAnchorKind);
+    if (Splitter.Enabled and (OpositeDockHostSite=nil)) then begin
+      result:=true;
+      if CheckOposite(OppositeAnchorKind[SplitterAnchorKind],self,OpositeSplitter,SplitterAnchorKind) then
+      if Assigned(OpositeSplitter) then
+      if not OpositeSplitter.Enabled then
+        result:=false;
+    end;
+  end;
+end;
+
+procedure TAnchorDockHostSite.MinimizeSite;
+begin
+  //Application.QueueAsyncCall(@AsyncMinimizeSite,0);
+  AsyncMinimizeSite(0);
+end;
+
+procedure TAnchorDockHostSite.AsyncMinimizeSite(Data: PtrInt);
+var
+  AControl: TControl;
+  //OpositeDockHostSite:TAnchorDockHostSite;
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
+  //SpliterPercentPosition:Single;
+begin
+  fMinimization:=true;
+  debugln(['TAnchorDockHostSite.MinimizeSite ',DbgSName(Self),' SiteType=',dbgs(SiteType)]);
+  if FMinimized then
+    AControl:=FMinimizedControl
+  else
+    AControl:=GetOneControl;
+  if CanBeMinimized(Splitter,SplitterAnchorKind) or FMinimized then begin
+    FMinimized:=not FMinimized;
+    if FMinimized then begin
+      FMinimizedControl:=AControl;
+      AControl.Visible:=False;
+      AControl.Parent:=nil;
+      //self.DoDockOver(); OnDockOver;
+    end else begin
+      AControl.Parent:=self;
+      AControl.Visible:=True;
+      FMinimizedControl:=nil;
+    end;
+    Splitter.Enabled:=AControl.Visible;
+    UpdateHeaderAlign;
+    dockmaster.UpdateHeaders;
+    dockmaster.InvalidateHeaders;
+    Splitter.SetBoundsPercentually;
+  end;
+  fMinimization:=false;
+end;
+
+procedure TAnchorDockHostSite.ShowMinimizedControl;
+var
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
+  SpliterRect,OverlappingFormRect:TRect;
+begin
+  if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+    SpliterRect:=Splitter.GetSpliterBoundsWithUnminimizedDockSites;
+    OverlappingFormRect:=BoundsRect;
+    case SplitterAnchorKind of
+         akTop:OverlappingFormRect.Top:=SpliterRect.Bottom;
+        akLeft:OverlappingFormRect.Left:=SpliterRect.Right;
+       akRight:OverlappingFormRect.Right:=SpliterRect.Left;
+      akBottom:OverlappingFormRect.Bottom:=SpliterRect.Top;
+    end;
+    DockMaster.FOverlappingForm:=TAnchorDockOverlappingForm.CreateNew(self);
+    DockMaster.FOverlappingForm.BoundsRect:=OverlappingFormRect;
+    DockMaster.FOverlappingForm.Parent:=GetParentFormOrDockPanel(self,false);
+    DockMaster.FOverlappingForm.AnchorDockHostSite:=self;
+    header.Parent:=DockMaster.FOverlappingForm;
+    FMinimizedControl.Parent:=DockMaster.FOverlappingForm.Panel;
+    FMinimizedControl.Show;
+    DockMaster.ShowOverlappingForm;
+  end;
+end;
+
+procedure TAnchorDockHostSite.HideMinimizedControl;
+begin
+   FMinimizedControl.Hide;
+   header.Parent:=self;
+   header.UpdateHeaderControls;
+   FMinimizedControl.Parent:=nil;
+   FreeAndNil(DockMaster.FOverlappingForm);
+end;
+
 function TAnchorDockHostSite.CloseSite: boolean;
 var
   AControl: TControl;
@@ -5281,21 +5681,24 @@
 begin
   if csDestroying in ComponentState then exit;
   NewCaption:='';
-  for i:=0 to ControlCount-1 do begin
-    Child:=Controls[i];
-    if Child=Exclude then continue;
-    if (Child.HostDockSite=Self) or (Child is TAnchorDockHostSite)
-    or (Child is TAnchorDockPageControl) then begin
-      if NewCaption<>'' then
-        NewCaption:=NewCaption+',';
-      NewCaption:=NewCaption+Child.Caption;
+  if FMinimized then
+    NewCaption:=FMinimizedControl.Caption
+  else
+    for i:=0 to ControlCount-1 do begin
+      Child:=Controls[i];
+      if Child=Exclude then continue;
+      if (Child.HostDockSite=Self) or (Child is TAnchorDockHostSite)
+      or (Child is TAnchorDockPageControl) then begin
+        if NewCaption<>'' then
+          NewCaption:=NewCaption+',';
+        NewCaption:=NewCaption+Child.Caption;
+      end;
     end;
-  end;
   OldCaption:=Caption;
   Caption:=NewCaption;
   //debugln(['TAnchorDockHostSite.UpdateDockCaption Caption="',Caption,'" NewCaption="',NewCaption,'" HasParent=',Parent<>nil,' ',DbgSName(Header)]);
-  if ((Parent=nil) and DockMaster.HideHeaderCaptionFloatingControl)
-  or (not DockMaster.ShowHeaderCaption) then
+  if {((Parent=nil) and DockMaster.HideHeaderCaptionFloatingControl)
+  or (not DockMaster.ShowHeaderCaption)}false then
     Header.Caption:=''
   else
     Header.Caption:=Caption;
@@ -5306,9 +5709,8 @@
     if Parent is TAnchorDockPage then
       TAnchorDockPage(Parent).UpdateDockCaption;
   end;
-
   // do not show close button for mainform
-  Header.CloseButton.Visible:=not IsParentOf(Application.MainForm);
+  Header.CloseButton.Visible:=(not IsParentOf(Application.MainForm));
 end;
 
 procedure TAnchorDockHostSite.GetSiteInfo(Client: TControl;
@@ -5339,7 +5741,8 @@
   end;
 
   CanDock:=(Client is TAnchorDockHostSite)
-           and not DockMaster.AutoFreedIfControlIsRemoved(Self,Client);
+           and not DockMaster.AutoFreedIfControlIsRemoved(Self,Client)
+           and not FMinimized;
   //debugln(['TAnchorDockHostSite.GetSiteInfo ',DbgSName(Self),' ',dbgs(BoundsRect),' ',Caption,' CanDock=',CanDock,' PtIn=',PtInRect(InfluenceRect,MousePos)]);
 
   if Assigned(OnGetSiteInfo) then
@@ -5362,9 +5765,20 @@
 end;
 
 procedure TAnchorDockHostSite.UpdateHeaderAlign;
+var
+  NeededHeaderPosition:TADLHeaderPosition;
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
 begin
   if Header=nil then exit;
-  case Header.HeaderPosition of
+  if FMinimized then begin
+    if FindNearestSpliter(self,Splitter,SplitterAnchorKind) then begin
+      NeededHeaderPosition:=OppositeAnchorKind2TADLHeaderPosition[SplitterAnchorKind];
+    end else
+      NeededHeaderPosition:=Header.HeaderPosition;
+  end else
+    NeededHeaderPosition:=Header.HeaderPosition;
+  case NeededHeaderPosition of
   adlhpAuto:
     if Header.Align in [alLeft,alRight] then begin
       if (ClientHeight>0)
@@ -5388,10 +5802,16 @@
 end;
 
 procedure TAnchorDockHostSite.UpdateHeaderShowing;
+var
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
 begin
   if Header=nil then exit;
-  if HeaderNeedsShowing then
-    Header.Parent:=Self
+  if HeaderNeedsShowing then begin
+    Header.Parent:=Self;
+    Header.MinimizeButton.Visible:=(DockMaster.DockSitesCanBeMinimized and CanBeMinimized(Splitter,SplitterAnchorKind))or FMinimized;
+    Header.MinimizeButton.Parent:=Header;
+  end
   else
     Header.Parent:=nil;
 end;
@@ -5415,6 +5835,31 @@
   Result:=(fUpdateLayout>0) or (csDestroying in ComponentState);
 end;
 
+function AcceptAlign(Site:TAnchorDockHostSite; AlignCandidate:TAlign):TAlign;
+var
+  i:integer;
+  Splitter: TAnchorDockSplitter;
+  SplitterAnchorKind:TAnchorKind;
+  MinimizedSiteAlign:TAlign;
+begin
+  for i:=0 to Site.ControlCount-1 do
+    if Site.Controls[i] is TAnchorDockHostSite then
+      if (Site.Controls[i] as TAnchorDockHostSite).FMinimized then begin
+        if FindNearestSpliter(Site.Controls[i] as TAnchorDockHostSite,Splitter,SplitterAnchorKind) then begin
+          MinimizedSiteAlign:=OppositeAnchorKind2Align[SplitterAnchorKind];
+          if AlignCandidate=MinimizedSiteAlign then
+            exit(alNone);
+        end
+      end;
+  result:=AlignCandidate;
+end;
+
+function TAnchorDockHostSite.GetDockEdge(const MousePos: TPoint): TAlign;
+begin
+  result:=inherited;
+  result:=AcceptAlign(self,result);
+end;
+
 procedure TAnchorDockHostSite.SaveLayout(
   LayoutTree: TAnchorDockLayoutTree; LayoutNode: TAnchorDockLayoutTreeNode);
 var
@@ -5432,7 +5877,7 @@
   if (SiteType=adhstOneControl) and (OneControl<>nil)
   and (not (OneControl is TAnchorDockHostSite)) then begin
     LayoutNode.NodeType:=adltnControl;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,FMinimized);
     LayoutNode.Name:=OneControl.Name;
     LayoutNode.HeaderPosition:=Header.HeaderPosition;
   end else if (SiteType in [adhstLayout,adhstOneControl]) then begin
@@ -5450,7 +5895,7 @@
         Splitter.SaveLayout(ChildNode);
       end;
     end;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,FMinimized);
     LayoutNode.HeaderPosition:=Header.HeaderPosition;
   end else if SiteType=adhstPages then begin
     LayoutNode.NodeType:=adltnPages;
@@ -5461,7 +5906,7 @@
         Site.SaveLayout(LayoutTree,ChildNode);
       end;
     end;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,FMinimized);
     LayoutNode.HeaderPosition:=Header.HeaderPosition;
   end else
     LayoutNode.NodeType:=adltnNone;
@@ -5476,6 +5921,9 @@
 constructor TAnchorDockHostSite.CreateNew(AOwner: TComponent; Num: Integer);
 begin
   inherited CreateNew(AOwner,Num);
+  FMinimized:=false;
+  fMinimization:=false;
+  FMinimizedControl:=Nil;
   Visible:=false;
   FHeaderSide:=akTop;
   FHeader:=DockMaster.HeaderClass.Create(Self);
@@ -5490,13 +5938,13 @@
 end;
 
 destructor TAnchorDockHostSite.Destroy;
-//var i: Integer;
+var i: Integer;
 begin
-  //debugln(['TAnchorDockHostSite.Destroy ',DbgSName(Self),' Caption="',Caption,'" Self=',dbgs(Pointer(Self)),' ComponentCount=',ComponentCount,' ControlCount=',ControlCount]);
-  {for i:=0 to ComponentCount-1 do
+  debugln(['TAnchorDockHostSite.Destroy ',DbgSName(Self),' Caption="',Caption,'" Self=',dbgs(Pointer(Self)),' ComponentCount=',ComponentCount,' ControlCount=',ControlCount]);
+  for i:=0 to ComponentCount-1 do
     debugln(['TAnchorDockHostSite.Destroy Component ',i,'/',ComponentCount,' ',DbgSName(Components[i])]);
   for i:=0 to ControlCount-1 do
-    debugln(['TAnchorDockHostSite.Destroy Control ',i,'/',ControlCount,' ',DbgSName(Controls[i])]);}
+    debugln(['TAnchorDockHostSite.Destroy Control ',i,'/',ControlCount,' ',DbgSName(Controls[i])]);
   FreePages;
   inherited Destroy;
 end;
@@ -5562,13 +6010,34 @@
 end;
 
 procedure TAnchorDockHeader.CloseButtonClick(Sender: TObject);
+var
+  HeaderParent:TAnchorDockHostSite;
 begin
-  if Parent is TAnchorDockHostSite then begin
-    DockMaster.RestoreLayouts.Add(DockMaster.CreateRestoreLayout(Parent),true);
-    TAnchorDockHostSite(Parent).CloseSite;
+  TWinControl(HeaderParent):=Parent;
+  if HeaderParent=TWinControl(DockMaster.FOverlappingForm) then begin
+    HeaderParent:=DockMaster.FOverlappingForm.AnchorDockHostSite;
+    HeaderParent.HideMinimizedControl;
   end;
+  if HeaderParent is TAnchorDockHostSite then begin
+    DockMaster.RestoreLayouts.Add(DockMaster.CreateRestoreLayout(HeaderParent),true);
+    HeaderParent.CloseSite;
+  end;
 end;
 
+procedure TAnchorDockHeader.MinimizeButtonClick(Sender: TObject);
+var
+  HeaderParent:TAnchorDockHostSite;
+begin
+  TWinControl(HeaderParent):=Parent;
+  if HeaderParent=TWinControl(DockMaster.FOverlappingForm) then begin
+    HeaderParent:=DockMaster.FOverlappingForm.AnchorDockHostSite;
+    HeaderParent.HideMinimizedControl;
+  end;
+  if HeaderParent is TAnchorDockHostSite then begin
+    HeaderParent.MinimizeSite;
+  end;
+end;
+
 procedure TAnchorDockHeader.HeaderPositionItemClick(Sender: TObject);
 var
   Item: TMenuItem;
@@ -5635,11 +6104,18 @@
 
   if CloseButton.IsControlVisible and (CloseButton.Parent=Self) then begin
     if Align in [alLeft,alRight] then
-      r.Top:=CloseButton.Top+CloseButton.Height+1
+      r.Top:=CloseButton.Top+CloseButton.Height+ButtonBorderSpacingAround
     else
-      r.Right:=CloseButton.Left-1;
+      r.Right:=CloseButton.Left-ButtonBorderSpacingAround;
   end;
 
+  if MinimizeButton.IsControlVisible and (MinimizeButton.Parent=Self) then begin
+    if Align in [alLeft,alRight] then
+      r.Top:=MinimizeButton.Top+MinimizeButton.Height+ButtonBorderSpacingAround
+    else
+      r.Right:=MinimizeButton.Left-ButtonBorderSpacingAround;
+  end;
+
   // caption
   if Caption<>'' then begin
     if fFocused and DockMaster.HeaderHighlightFocused and NeedHighlightText then
@@ -5728,26 +6204,127 @@
     end else begin
       PreferredHeight:=Max(NeededHeight,PreferredHeight);
     end;
+  end else begin
+    NeededHeight:=CloseButton.Height;
+    if Align in [alLeft,alRight] then begin
+      PreferredWidth:=Max(NeededHeight,PreferredWidth);
+    end else begin
+      PreferredHeight:=Max(NeededHeight,PreferredHeight);
   end;
+  end;
 end;
 
 procedure TAnchorDockHeader.MouseDown(Button: TMouseButton; Shift: TShiftState;
   X, Y: Integer);
+var
+  SiteMinimized:Boolean;
 begin
   inherited MouseDown(Button, Shift, X, Y);
-  if (Button=mbLeft) and DockMaster.AllowDragging then
-    DragManager.DragStart(Parent,false,DockMaster.DragTreshold);
+  SiteMinimized:=False;
+  fUseTimer:=false;
+  StopMouseNoMoveTimer;
+  if Parent is TAnchorDockHostSite then
+    SiteMinimized:=(Parent as TAnchorDockHostSite).FMinimized;
+  if SiteMinimized then begin
+    DoMouseNoMoveTimer(nil);
+  end else
+    begin
+      if parent<>nil then
+        if DockMaster.FOverlappingForm<>nil then
+          //if parent=DockMaster.FOverlappingForm.Panel then
+            DockMaster.HideOverlappingForm(nil);
+      if (Button=mbLeft) and (DockMaster.AllowDragging) and (DockMaster.FOverlappingForm=nil) then
+        DragManager.DragStart(Parent,false,DockMaster.DragTreshold);
+    end;
 end;
 
+procedure  TAnchorDockHeader.MouseMove(Shift: TShiftState; X,Y: Integer);
+begin
+  inherited MouseMove(Shift, X, Y);
+  if parent<>nil then
+    if parent is TAnchorDockHostSite then
+      if (parent as TAnchorDockHostSite).FMinimized then
+        if DockMaster.FOverlappingForm=nil then
+          if FMouseTimeStartX=EmptyMouseTimeStartX then
+            StartMouseNoMoveTimer(X, Y)
+          else begin
+            if (abs(FMouseTimeStartX-X)>MouseNoMoveDelta)or(abs(FMouseTimeStartY-Y)>MouseNoMoveDelta)then
+            StopMouseNoMoveTimer;
+          end;
+  if (parent is TAnchorDockHostSite)and(DockMaster.FOverlappingForm=nil)then
+    fUseTimer:=true;
+end;
+
+procedure TAnchorDockHeader.MouseLeave;
+begin
+  inherited;
+  StopMouseNoMoveTimer;
+end;
+
+procedure TAnchorDockHeader.StartMouseNoMoveTimer(X, Y: Integer);
+begin
+  if fUseTimer then begin
+    if DockTimer.Enabled then DockTimer.Enabled:=false;
+    DockTimer.Interval:=MouseNoMoveTime;
+    DockTimer.OnTimer:=@DoMouseNoMoveTimer;
+    DockTimer.Enabled:=true;
+  end;
+end;
+
+procedure TAnchorDockHeader.StopMouseNoMoveTimer;
+begin
+  FMouseTimeStartX:=EmptyMouseTimeStartX;
+  DockTimer.OnTimer:=nil;
+  DockTimer.Enabled:=false;
+end;
+
+procedure TAnchorDockHeader.DoMouseNoMoveTimer(Sender: TObject);
+begin
+  StopMouseNoMoveTimer;
+  //if fUseTimer then
+    if parent<>nil then
+      if parent is TAnchorDockHostSite then
+        if (parent as TAnchorDockHostSite).FMinimized then
+          (parent as TAnchorDockHostSite).ShowMinimizedControl;
+end;
+
 procedure TAnchorDockHeader.UpdateHeaderControls;
 begin
   if Align in [alLeft,alRight] then begin
-    if CloseButton<>nil then
-      CloseButton.Align:=alTop;
+    if CloseButton<>nil then begin
+      //MinimizeButton.Align:=alTop;
+      //CloseButton.Align:=alTop;
+      CloseButton.AnchorSide[akRight].Side := asrCenter;
+      CloseButton.AnchorSide[akRight].Control := self;
+      CloseButton.AnchorSide[akTop].Side := asrTop;
+      CloseButton.AnchorSide[akTop].Control := self;
+      CloseButton.Anchors := CloseButton.Anchors + [akTop] + [akRight];
+
+      MinimizeButton.AnchorSide[akRight].Side := asrCenter;
+      MinimizeButton.AnchorSide[akRight].Control := CloseButton;
+      MinimizeButton.AnchorSide[akTop].Side := asrBottom;
+      MinimizeButton.AnchorSide[akTop].Control := CloseButton;
+      MinimizeButton.Anchors := MinimizeButton.Anchors + [akTop] + [akRight];
+    end;
   end else begin
-    if CloseButton<>nil then
-      CloseButton.Align:=alRight;
+    if CloseButton<>nil then begin
+      //MinimizeButton.Align:=alRight;
+      //CloseButton.Align:=alRight;
+      CloseButton.AnchorSide[akRight].Side := asrRight;
+      CloseButton.AnchorSide[akRight].Control := self;
+      CloseButton.AnchorSide[akTop].Side := asrCenter;
+      CloseButton.AnchorSide[akTop].Control := self;
+      CloseButton.Anchors := CloseButton.Anchors - [akLeft] + [akRight];
+
+      MinimizeButton.AnchorSide[akRight].Side := asrLeft;
+      MinimizeButton.AnchorSide[akRight].Control := CloseButton;
+      MinimizeButton.AnchorSide[akTop].Side := asrCenter;
+      MinimizeButton.AnchorSide[akTop].Control := CloseButton;
+      MinimizeButton.Anchors := MinimizeButton.Anchors - [akLeft] + [akRight];
+    end;
   end;
+  CloseButton.BorderSpacing.Around:=ButtonBorderSpacingAround;
+  MinimizeButton.BorderSpacing.Around:=ButtonBorderSpacingAround;
   //debugln(['TAnchorDockHeader.UpdateHeaderControls ',dbgs(Align),' ',dbgs(CloseButton.Align)]);
 end;
 
@@ -5787,9 +6364,9 @@
 begin
   inherited Create(TheOwner);
   FHeaderPosition:=adlhpAuto;
-  FCloseButton:=TAnchorDockCloseButton.Create(Self);
   BevelOuter:=bvNone;
   BorderWidth:=0;
+  FCloseButton:=TAnchorDockCloseButton.Create(Self);
   with FCloseButton do begin
     Name:='CloseButton';
     Parent:=Self;
@@ -5799,11 +6376,23 @@
     OnClick:=@CloseButtonClick;
     AutoSize:=true;
   end;
+  FMinimizeButton:=TAnchorDockMinimizeButton.Create(Self);
+  with FMinimizeButton do begin
+    Name:='MinimizeButton';
+    Parent:=Self;
+    Flat:=true;
+    ShowHint:=true;
+    Hint:=adrsMinimize;
+    OnClick:=@MinimizeButtonClick;
+    AutoSize:=true;
+  end;
   Align:=alTop;
   AutoSize:=true;
   ShowHint:=true;
   PopupMenu:=DockMaster.GetPopupMenu;
   fFocused:=false;
+  FMouseTimeStartX:=EmptyMouseTimeStartX;
+  fUseTimer:=true;
 end;
 
 { TAnchorDockCloseButton }
@@ -5830,6 +6419,31 @@
   Result := ThemeServices.GetElementDetails(WindowPart);
 end;
 
+procedure SizeCorrector(var current,recomend:integer);
+begin
+  if recomend<0 then begin
+    if current>0 then
+      recomend:=current
+    else
+      current:=HardcodedButtonSize;
+  end else begin
+      if current>recomend then
+        current:=recomend
+      else begin
+        if current>0 then
+         recomend:=current
+        else
+         current:=recomend;
+      end;
+  end;
+end;
+
+procedure ButtonSizeCorrector(var w,h:integer);
+begin
+  SizeCorrector(w,PreferredButtonWidth);
+  SizeCorrector(h,PreferredButtonHeight);
+end;
+
 procedure TAnchorDockCloseButton.CalculatePreferredSize(var PreferredWidth,
   PreferredHeight: integer; WithThemeSpace: Boolean);
 begin
@@ -5837,6 +6451,7 @@
   begin
     PreferredWidth:=cx;
     PreferredHeight:=cy;
+    ButtonSizeCorrector(PreferredWidth,PreferredHeight);
     {$IF defined(LCLGtk2) or defined(Carbon)}
     inc(PreferredWidth,2);
     inc(PreferredHeight,2);
@@ -5844,6 +6459,45 @@
   end;
 end;
 
+{ TAnchorDockMinimizeButton }
+
+function TAnchorDockMinimizeButton.GetDrawDetails: TThemedElementDetails;
+
+function WindowPart: TThemedWindow;
+  begin
+    // no check states available
+    Result := twMinButtonNormal;
+    if not IsEnabled then
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonDisabled{$ELSE}twMinButtonDisabled{$ENDIF}
+    else
+    if FState in [bsDown, bsExclusive] then
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonPushed{$ELSE}twMinButtonPushed{$ENDIF}
+    else
+    if FState = bsHot then
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonHot{$ELSE}twMinButtonHot{$ENDIF}
+    else
+      Result := {$IFDEF LCLGtk2}twMDIRestoreButtonNormal{$ELSE}twMinButtonNormal{$ENDIF};
+  end;
+
+begin
+  Result := ThemeServices.GetElementDetails(WindowPart);
+end;
+
+procedure TAnchorDockMinimizeButton.CalculatePreferredSize(var PreferredWidth,
+  PreferredHeight: integer; WithThemeSpace: Boolean);
+begin
+  with ThemeServices.GetDetailSize(ThemeServices.GetElementDetails({$IFDEF LCLGtk2}twMDIRestoreButtonNormal{$ELSE}twMinButtonNormal{$ENDIF})) do
+  begin
+    PreferredWidth:=cx;
+    PreferredHeight:=cy;
+    ButtonSizeCorrector(PreferredWidth,PreferredHeight);
+    {$IF defined(LCLGtk2) or defined(Carbon)}
+    inc(PreferredWidth,2);
+    inc(PreferredHeight,2);
+    {$ENDIF}
+  end;
+end;
+
 { TAnchorDockManager }
 
 procedure TAnchorDockManager.SetPreferredSiteSizeAsSiteMinimum(
@@ -6213,6 +6867,9 @@
   ClientRectChanged:=(WidthDiff<>0) or (HeightDiff<>0);
   if ClientRectChanged or PreferredSiteSizeAsSiteMinimum then
     AlignChilds;
+  if ClientRectChanged then
+    if DockMaster.FOverlappingForm<>nil then
+      DockMaster.HideOverlappingForm(nil);
 end;
 
 procedure TAnchorDockManager.SaveToStream(Stream: TStream);
@@ -6287,6 +6944,11 @@
       ADockObject.DropOnControl:=Site
     else
       ADockObject.DropOnControl:=nil;
+    if Site is TAnchorDockHostSite then begin
+      ADockObject.DropAlign:=AcceptAlign(Site as TAnchorDockHostSite,ADockObject.DropAlign);
+      if ADockObject.DropAlign=alNone then
+        exit(false);
+    end;
   end;
   //debugln(['TAnchorDockManager.GetDockEdge ADockObject.DropAlign=',dbgs(ADockObject.DropAlign),' DropOnControl=',DbgSName(ADockObject.DropOnControl)]);
   Result:=true;
@@ -6505,32 +7167,58 @@
 procedure TAnchorDockSplitter.SetBoundsPercentually;
 var
   NewLeft, NewTop: Integer;
+  AControl: TControl;
+  SplitterAnchorKind:TAnchorKind;
 begin
-  if ResizeAnchor in [akLeft,akRight] then
-  begin
-    if DockParentClientSize.cx> 0 then
+  if Enabled then begin
+    if ResizeAnchor in [akLeft,akRight] then
     begin
-      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
-        NewLeft := Round(FPercentPosition*Parent.ClientWidth)
-      else
-        NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
-      NewTop := Top;
-      SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      if DockParentClientSize.cx> 0 then
+      begin
+        if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+          NewLeft := Round(FPercentPosition*Parent.ClientWidth)
+        else
+          NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
+        NewTop := Top;
+        SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      end;
+    end else
+    begin
+      if DockParentClientSize.cy> 0 then
+      begin
+        NewLeft := Left;
+        if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+          NewTop := Round(FPercentPosition*Parent.ClientHeight)
+        else
+          NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+        SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
+      end;
     end;
-  end else
-  begin
-    if DockParentClientSize.cy> 0 then
-    begin
-      NewLeft := Left;
-      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
-        NewTop := Round(FPercentPosition*Parent.ClientHeight)
-      else
-        NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+    if FPercentPosition < 0 then
+      UpdatePercentPosition;
+  end else begin
+    SplitterAnchorKind:=akTop;
+    AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);
+    if AControl=nil then begin SplitterAnchorKind:=akRight;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+    if AControl=nil then begin SplitterAnchorKind:=akBottom;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+    if AControl=nil then begin SplitterAnchorKind:=akLeft;AControl:=CountAndReturnOnlyOneMinimizedAnchoredControls(self,SplitterAnchorKind);end;
+
+    if AControl is TAnchorDockHostSite then begin
+      (AControl as TAnchorDockHostSite).UpdateHeaderAlign;
+      NewTop := (AControl as TAnchorDockHostSite).Header.Left;
+      NewTop := (AControl as TAnchorDockHostSite).Header.Height;
+      NewLeft := left;
+      NewTop := top;
+      (AControl as TAnchorDockHostSite).UpdateHeaderAlign;
+      case SplitterAnchorKind of
+        akTop: NewTop := AControl.Top+(AControl as TAnchorDockHostSite).Header.Height;
+        akBottom: NewTop := AControl.Top+AControl.Height-(AControl as TAnchorDockHostSite).Header.Height-Height;
+        akLeft: NewLeft := AControl.Left+(AControl as TAnchorDockHostSite).Header.Width;
+        akRight: NewLeft := AControl.Left+AControl.Width-(AControl as TAnchorDockHostSite).Header.Width-Width;
+      end;
       SetBoundsKeepDockBounds(NewLeft,NewTop,Width,Height);
     end;
   end;
-  if FPercentPosition < 0 then
-    UpdatePercentPosition;
 end;
 
 function TAnchorDockSplitter.SideAnchoredControlCount(Side: TAnchorKind): integer;
@@ -6560,14 +7248,47 @@
   end;
 end;
 
+function TAnchorDockSplitter.GetSpliterBoundsWithUnminimizedDockSites:TRect;
+var
+  NewLeft, NewTop: Integer;
+begin
+  if ResizeAnchor in [akLeft,akRight] then
+  begin
+    if DockParentClientSize.cx> 0 then
+    begin
+      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+        NewLeft := Round(FPercentPosition*Parent.ClientWidth)
+      else
+        NewLeft := (DockBounds.Left*Parent.ClientWidth) div DockParentClientSize.cx;
+      NewTop := Top;
+    end;
+  end else
+  begin
+    if DockParentClientSize.cy> 0 then
+    begin
+      NewLeft := Left;
+      if (FPercentPosition > 0) or SameValue(FPercentPosition, 0) then
+        NewTop := Round(FPercentPosition*Parent.ClientHeight)
+      else
+        NewTop := (DockBounds.Top*Parent.ClientHeight) div DockParentClientSize.cy;
+    end;
+  end;
+  result:=Rect(NewLeft,NewTop,NewLeft+Width,NewTop+Height);
+end;
+
 procedure TAnchorDockSplitter.SaveLayout(
   LayoutNode: TAnchorDockLayoutTreeNode);
+var
+  NewLeft, NewTop: Integer;
 begin
   if ResizeAnchor in [akLeft,akRight] then
     LayoutNode.NodeType:=adltnSplitterVertical
   else
     LayoutNode.NodeType:=adltnSplitterHorizontal;
-  LayoutNode.Assign(Self);
+  LayoutNode.Assign(Self,false,false);
+  if not Enabled then begin
+    LayoutNode.BoundsRect:=GetSpliterBoundsWithUnminimizedDockSites;
+  end
 end;
 
 function TAnchorDockSplitter.HasOnlyOneSibling(Side: TAnchorKind; MinPos,
@@ -6645,7 +7366,7 @@
 begin
   inherited MouseDown(Button, Shift, X, Y);
   ATabIndex := IndexOfPageAt(X, Y);
-  if (Button = mbLeft) and DockMaster.AllowDragging and (ATabIndex >= 0) then
+  if (Button = mbLeft) and DockMaster.AllowDragging and (ATabIndex >= 0) and (DockMaster.FOverlappingForm=nil) then
   begin
     APage:=Page[ATabIndex];
     if (APage.ControlCount>0) and (APage.Controls[0] is TAnchorDockHostSite) then
@@ -6782,6 +7503,20 @@
   PopupMenu:=DockMaster.GetPopupMenu;
 end;
 
+{ TAnchorDockOverlappingForm }
+
+constructor TAnchorDockOverlappingForm.CreateNew(AOwner: TComponent; Num: Integer = 0);
+begin
+  inherited;
+  BorderStyle:=bsNone;
+  AnchorDockHostSite:=nil;
+  Panel:=TPanel.Create(self);
+  Panel.BorderStyle:=bsSingle;
+  Panel.Align:=alClient;
+  Panel.Parent:=self;
+  Panel.Visible:=true;
+end;
+
 { TAnchorDockPage }
 
 procedure TAnchorDockPage.UpdateDockCaption(Exclude: TControl);
@@ -6835,9 +7570,11 @@
 
 initialization
   DockMaster:=TAnchorDockMaster.Create(nil);
+  DockTimer:=TTimer.Create(nil);
 
 finalization
   FreeAndNil(DockMaster);
+  FreeAndNil(DockTimer);
 
 end.
 
Index: components/anchordocking/anchordockoptionsdlg.lfm
===================================================================
--- components/anchordocking/anchordockoptionsdlg.lfm	(revision 59428)
+++ components/anchordocking/anchordockoptionsdlg.lfm	(working copy)
@@ -1,11 +1,13 @@
 object AnchorDockOptionsFrame: TAnchorDockOptionsFrame
   Left = 0
-  Height = 482
+  Height = 567
   Top = 0
-  Width = 416
-  ClientHeight = 482
-  ClientWidth = 416
+  Width = 490
+  ClientHeight = 567
+  ClientWidth = 490
+  DesignTimePPI = 113
   OnClick = FrameClick
+  ParentFont = False
   TabOrder = 0
   DesignLeft = 513
   DesignTop = 189
@@ -12,14 +14,15 @@
   object DragThresholdLabel: TLabel
     AnchorSideLeft.Control = Owner
     AnchorSideTop.Control = Owner
-    Left = 10
-    Height = 13
-    Top = 10
-    Width = 111
-    BorderSpacing.Left = 10
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 12
+    Width = 122
+    BorderSpacing.Left = 12
+    BorderSpacing.Top = 12
     Caption = 'DragThresholdLabel'
     ParentColor = False
+    ParentFont = False
   end
   object DragThresholdTrackBar: TTrackBar
     AnchorSideLeft.Control = DragThresholdLabel
@@ -27,15 +30,16 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = Owner
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 46
-    Top = 23
-    Width = 396
+    Left = 12
+    Height = 54
+    Top = 31
+    Width = 466
     Max = 20
     OnChange = DragThresholdTrackBarChange
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Right = 10
+    BorderSpacing.Right = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 1
@@ -46,12 +50,13 @@
     AnchorSideTop.Control = DragThresholdLabel
     AnchorSideTop.Side = asrCenter
     AnchorSideRight.Control = Owner
-    Left = 127
-    Height = 23
-    Top = 5
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 141
+    Height = 27
+    Top = 8
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 20
+    ParentFont = False
     TabOrder = 0
     Visible = False
   end
@@ -59,13 +64,14 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = DragThresholdTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 79
-    Width = 103
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 97
+    Width = 112
+    BorderSpacing.Top = 12
     Caption = 'SplitterWidthLabel'
     ParentColor = False
+    ParentFont = False
   end
   object SplitterWidthTrackBar: TTrackBar
     AnchorSideLeft.Control = DragThresholdTrackBar
@@ -73,14 +79,15 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 46
-    Top = 92
-    Width = 396
+    Left = 12
+    Height = 54
+    Top = 116
+    Width = 466
     Min = 1
     OnChange = SplitterWidthTrackBarChange
     Position = 1
     Anchors = [akTop, akLeft, akRight]
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 3
@@ -89,12 +96,13 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = SplitterWidthTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 24
-    Top = 142
-    Width = 160
-    BorderSpacing.Top = 4
+    Left = 12
+    Height = 23
+    Top = 175
+    Width = 169
+    BorderSpacing.Top = 5
     Caption = 'ScaleOnResizeCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 4
@@ -103,12 +111,13 @@
     AnchorSideLeft.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 24
-    Top = 166
-    Width = 149
+    Left = 12
+    Height = 23
+    Top = 198
+    Width = 160
     Caption = 'ShowHeaderCheckBox'
     OnChange = ShowHeaderCheckBoxChange
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 5
@@ -117,12 +126,13 @@
     AnchorSideLeft.Control = ScaleOnResizeCheckBox
     AnchorSideTop.Control = ShowHeaderCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 190
-    Width = 191
-    BorderSpacing.Left = 15
+    Left = 30
+    Height = 23
+    Top = 221
+    Width = 208
+    BorderSpacing.Left = 18
     Caption = 'ShowHeaderCaptionCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 6
@@ -131,11 +141,12 @@
     AnchorSideLeft.Control = ShowHeaderCaptionCheckBox
     AnchorSideTop.Control = ShowHeaderCaptionCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 214
-    Width = 249
+    Left = 30
+    Height = 23
+    Top = 244
+    Width = 272
     Caption = 'HideHeaderCaptionForFloatingCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 7
@@ -147,15 +158,16 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = Owner
     AnchorSideRight.Side = asrBottom
-    Left = 122
+    Left = 136
     Height = 27
-    Top = 286
-    Width = 284
+    Top = 313
+    Width = 342
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 6
-    BorderSpacing.Right = 10
-    ItemHeight = 0
+    BorderSpacing.Left = 7
+    BorderSpacing.Right = 12
+    ItemHeight = 19
     OnDrawItem = HeaderStyleComboBoxDrawItem
+    ParentFont = False
     Style = csDropDownList
     TabOrder = 10
   end
@@ -163,23 +175,25 @@
     AnchorSideLeft.Control = ShowHeaderCheckBox
     AnchorSideTop.Control = HeaderStyleComboBox
     AnchorSideTop.Side = asrCenter
-    Left = 20
-    Height = 13
-    Top = 293
-    Width = 96
-    BorderSpacing.Left = 10
+    Left = 24
+    Height = 19
+    Top = 317
+    Width = 105
+    BorderSpacing.Left = 12
     Caption = 'HeaderStyleLabel'
     ParentColor = False
+    ParentFont = False
   end
   object FlattenHeadersCheckBox: TCheckBox
     AnchorSideLeft.Control = HideHeaderCaptionForFloatingCheckBox
     AnchorSideTop.Control = HideHeaderCaptionForFloatingCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 238
-    Width = 164
+    Left = 30
+    Height = 23
+    Top = 267
+    Width = 175
     Caption = 'FlattenHeadersCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 8
@@ -188,11 +202,12 @@
     AnchorSideLeft.Control = FlattenHeadersCheckBox
     AnchorSideTop.Control = FlattenHeadersCheckBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 262
-    Width = 154
+    Left = 30
+    Height = 23
+    Top = 290
+    Width = 164
     Caption = 'FilledHeadersCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 9
@@ -201,11 +216,12 @@
     AnchorSideLeft.Control = FilledHeadersCheckBox
     AnchorSideTop.Control = HeaderStyleComboBox
     AnchorSideTop.Side = asrBottom
-    Left = 25
-    Height = 24
-    Top = 313
-    Width = 175
+    Left = 30
+    Height = 23
+    Top = 340
+    Width = 189
     Caption = 'HighlightFocusedCheckBox'
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 11
@@ -215,13 +231,14 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = SplitterWidthLabel
     AnchorSideTop.Side = asrCenter
-    Left = 119
-    Height = 23
-    Top = 74
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 131
+    Height = 27
+    Top = 93
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 10
     MinValue = 1
+    ParentFont = False
     TabOrder = 2
     Value = 1
     Visible = False
@@ -228,15 +245,16 @@
   end
   object HeaderAlignTopLabel: TLabel
     AnchorSideLeft.Control = DragThresholdLabel
-    AnchorSideTop.Control = HighlightFocusedCheckBox
+    AnchorSideTop.Control = DockSitesCanBeMinimized
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 347
-    Width = 117
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 398
+    Width = 130
+    BorderSpacing.Top = 12
     Caption = 'HeaderAlignTopLabel'
     ParentColor = False
+    ParentFont = False
   end
   object HeaderAlignTopTrackBar: TTrackBar
     AnchorSideLeft.Control = Owner
@@ -244,10 +262,10 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 47
-    Top = 360
-    Width = 396
+    Left = 12
+    Height = 55
+    Top = 417
+    Width = 466
     Frequency = 10
     Max = 150
     OnChange = HeaderAlignTopTrackBarChange
@@ -254,7 +272,8 @@
     PageSize = 10
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 10
+    BorderSpacing.Left = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 13
@@ -264,12 +283,13 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = HeaderAlignTopLabel
     AnchorSideTop.Side = asrCenter
-    Left = 133
-    Height = 23
-    Top = 342
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 149
+    Height = 27
+    Top = 394
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 150
+    ParentFont = False
     TabOrder = 12
     Visible = False
   end
@@ -277,13 +297,14 @@
     AnchorSideLeft.Control = DragThresholdLabel
     AnchorSideTop.Control = HeaderAlignTopTrackBar
     AnchorSideTop.Side = asrBottom
-    Left = 10
-    Height = 13
-    Top = 417
-    Width = 120
-    BorderSpacing.Top = 10
+    Left = 12
+    Height = 19
+    Top = 484
+    Width = 130
+    BorderSpacing.Top = 12
     Caption = 'HeaderAlignLeftLabel'
     ParentColor = False
+    ParentFont = False
   end
   object HeaderAlignLeftTrackBar: TTrackBar
     AnchorSideLeft.Control = Owner
@@ -291,10 +312,10 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = DragThresholdTrackBar
     AnchorSideRight.Side = asrBottom
-    Left = 10
-    Height = 47
-    Top = 430
-    Width = 396
+    Left = 12
+    Height = 55
+    Top = 503
+    Width = 466
     Frequency = 10
     Max = 200
     OnChange = HeaderAlignLeftTrackBarChange
@@ -301,7 +322,8 @@
     PageSize = 10
     Position = 0
     Anchors = [akTop, akLeft, akRight]
-    BorderSpacing.Left = 10
+    BorderSpacing.Left = 12
+    ParentFont = False
     ParentShowHint = False
     ShowHint = True
     TabOrder = 15
@@ -311,13 +333,28 @@
     AnchorSideLeft.Side = asrBottom
     AnchorSideTop.Control = HeaderAlignLeftLabel
     AnchorSideTop.Side = asrCenter
-    Left = 136
-    Height = 23
-    Top = 412
-    Width = 50
-    BorderSpacing.Left = 6
+    Left = 149
+    Height = 27
+    Top = 480
+    Width = 59
+    BorderSpacing.Left = 7
     MaxValue = 200
+    ParentFont = False
     TabOrder = 14
     Visible = False
   end
+  object DockSitesCanBeMinimized: TCheckBox
+    AnchorSideLeft.Control = FilledHeadersCheckBox
+    AnchorSideTop.Control = HighlightFocusedCheckBox
+    AnchorSideTop.Side = asrBottom
+    Left = 30
+    Height = 23
+    Top = 363
+    Width = 185
+    Caption = 'DockSitesCanBeMinimized'
+    ParentFont = False
+    ParentShowHint = False
+    ShowHint = True
+    TabOrder = 16
+  end
 end
Index: components/anchordocking/anchordockoptionsdlg.pas
===================================================================
--- components/anchordocking/anchordockoptionsdlg.pas	(revision 59428)
+++ components/anchordocking/anchordockoptionsdlg.pas	(working copy)
@@ -37,6 +37,7 @@
     HeaderStyleLabel: TLabel;
     HideHeaderCaptionForFloatingCheckBox: TCheckBox;
     HighlightFocusedCheckBox: TCheckBox;
+    DockSitesCanBeMinimized: TCheckBox;
     ScaleOnResizeCheckBox: TCheckBox;
     ShowHeaderCaptionCheckBox: TCheckBox;
     ShowHeaderCheckBox: TCheckBox;
@@ -202,7 +203,7 @@
 
       HeaderAlignTopSpinEdit.Visible:=true;
       HeaderAlignTopTrackBar.Visible:=false;
-      HeaderAlignTopSpinEdit.AnchorToNeighbour(akTop,6,HighlightFocusedCheckBox);
+      HeaderAlignTopSpinEdit.AnchorToNeighbour(akTop,6,DockSitesCanBeMinimized);
       HeaderAlignTopLabel.AnchorVerticalCenterTo(HeaderAlignTopSpinEdit);
       UpdateHeaderAlignTopLabel;
 
@@ -299,6 +300,7 @@
   HeaderStyleLabel.Enabled:=HasHeaders;
   HeaderStyleComboBox.Enabled:=HasHeaders;
   HighlightFocusedCheckBox.Enabled:=HasHeaders;
+  DockSitesCanBeMinimized.Enabled:=HasHeaders;
 end;
 
 constructor TAnchorDockOptionsFrame.Create(TheOwner: TComponent);
@@ -356,6 +358,7 @@
   TheSettings.HeaderFilled:=FilledHeadersCheckBox.Checked;
   TheSettings.HeaderStyle:=TADHeaderStyle(HeaderStyleComboBox.ItemIndex);
   TheSettings.HeaderHighlightFocused:=HighlightFocusedCheckBox.Checked;
+  TheSettings.DockSitesCanBeMinimized:=DockSitesCanBeMinimized.Checked;
 end;
 
 procedure TAnchorDockOptionsFrame.LoadFromSettings(
@@ -429,6 +432,10 @@
   HighlightFocusedCheckBox.Checked:=TheSettings.HeaderHighlightFocused;
   HighlightFocusedCheckBox.Caption:=adrsHighlightFocused;
   HighlightFocusedCheckBox.Hint:=adrsHighlightFocusedHint;
+
+  DockSitesCanBeMinimized.Checked:=TheSettings.DockSitesCanBeMinimized;
+  DockSitesCanBeMinimized.Caption:=adrsDockSitesCanBeMinimized;
+  DockSitesCanBeMinimized.Hint:=adrsDockSitesCanBeMinimizedHint;
 end;
 
 end.
Index: components/anchordocking/anchordockpanel.pas
===================================================================
--- components/anchordocking/anchordockpanel.pas	(revision 59428)
+++ components/anchordocking/anchordockpanel.pas	(working copy)
@@ -55,7 +55,7 @@
   begin
 
     LayoutNode.NodeType:=adltnControl;
-    LayoutNode.Assign(Self);
+    LayoutNode.Assign(Self,false,false);
     LayoutNode.Name:={OneControl.}Name;
 
     TAnchorDockHostSite(OneControl).SaveLayout(LayoutTree,LayoutNode);
Index: components/anchordocking/anchordockstorage.pas
===================================================================
--- components/anchordocking/anchordockstorage.pas	(revision 59428)
+++ components/anchordocking/anchordockstorage.pas	(working copy)
@@ -64,6 +64,7 @@
     FTabPosition: TTabPosition;
     FWindowState: TWindowState;
     FControlLocation: TADLControlLocation;
+    FMinimized: Boolean;
     function GetAnchors(Site: TAnchorKind): string;
     function GetBottom: integer;
     function GetHeight: integer;
@@ -90,6 +91,7 @@
     procedure SetTop(const AValue: integer);
     procedure SetWidth(const AValue: integer);
     procedure SetWindowState(const AValue: TWindowState);
+    procedure SetMinimized(const AValue: boolean);
   public
     constructor Create;
     destructor Destroy; override;
@@ -96,7 +98,7 @@
     procedure Clear;
     function IsEqual(Node: TAnchorDockLayoutTreeNode): boolean;
     procedure Assign(Node: TAnchorDockLayoutTreeNode); overload;
-    procedure Assign(AControl: TControl; OverrideBoundsRect: Boolean=false); overload;
+    procedure Assign(AControl: TControl; OverrideBoundsRect: Boolean; AMinimized: Boolean); overload;
     procedure LoadFromConfig(Config: TConfigStorage); overload;
     procedure LoadFromConfig(Path: string; Config: TRttiXMLConfig); overload;
     procedure SaveToConfig(Config: TConfigStorage); overload;
@@ -106,7 +108,7 @@
     procedure CheckConsistency; virtual;
 
     // simplifying
-    procedure Simplify(ExistingNames: TStrings);
+    procedure Simplify(ExistingNames: TStrings; ParentMinimized:boolean);
     procedure DeleteNode(ChildNode: TAnchorDockLayoutTreeNode);
     function FindNodeBoundSplitter(ChildNode: TAnchorDockLayoutTreeNode;
                                    Side: TAnchorKind): TAnchorDockLayoutTreeNode;
@@ -135,6 +137,7 @@
     property Monitor: integer read FMonitor write SetMonitor;
     property HeaderPosition: TADLHeaderPosition read FHeaderPosition write SetHeaderPosition;
     property TabPosition: TTabPosition read FTabPosition write SetTabPosition;
+    property Minimized: Boolean read FMinimized write SetMinimized;
     function Count: integer;
     function IsSplitter: boolean;
     function IsRootWindow: boolean;
@@ -988,6 +991,13 @@
   IncreaseChangeStamp;
 end;
 
+procedure TAnchorDockLayoutTreeNode.SetMinimized(const AValue: boolean);
+begin
+  if FMinimized=AValue then exit;
+  FMinimized:=AValue;
+  IncreaseChangeStamp;
+end;
+
 procedure TAnchorDockLayoutTreeNode.SetTop(const AValue: integer);
 begin
   if Top=AValue then exit;
@@ -1084,6 +1094,7 @@
   BoundSplitterPos:=Node.BoundSplitterPos;
   WorkAreaRect:=Node.WorkAreaRect;
   Monitor:=Node.Monitor;
+  Minimized:=Node.Minimized;
   for a:=low(TAnchorKind) to high(TAnchorKind) do
     Anchors[a]:=Node.Anchors[a];
   while Count>Node.Count do Nodes[Count-1].Free;
@@ -1098,9 +1109,10 @@
   end;
 end;
 
-procedure TAnchorDockLayoutTreeNode.Assign(AControl: TControl; OverrideBoundsRect: Boolean=false);
+procedure TAnchorDockLayoutTreeNode.Assign(AControl: TControl; OverrideBoundsRect: Boolean; AMinimized: Boolean);
 var
   AnchorControl: TControl;
+  ParentForm:TCustomForm;
   a: TAnchorKind;
 begin
   Name:=AControl.Name;
@@ -1109,12 +1121,18 @@
   else
     BoundsRect:=AControl.BoundsRect;
   Align:=AControl.Align;
+  Minimized:=AMinimized;
   if (AControl.Parent=nil) and (AControl is TCustomForm) then begin
     WindowState:=TCustomForm(AControl).WindowState;
     Monitor:=TCustomForm(AControl).Monitor.MonitorNum;
     WorkAreaRect:=TCustomForm(AControl).Monitor.WorkareaRect;
-  end else
-    WindowState:=GetParentForm(AControl).WindowState;
+  end else begin
+    ParentForm:=GetParentForm(AControl);
+    if assigned(ParentForm) then
+      WindowState:=ParentForm.WindowState
+    else
+      WindowState:=wsNormal;
+  end;
   if AControl is TCustomTabControl then
     TabPosition:=TCustomTabControl(AControl).TabPosition
   else
@@ -1137,6 +1155,7 @@
   Clear;
   Name:=Config.GetValue('Name','');
   NodeType:=NameToADLTreeNodeType(Config.GetValue('Type',ADLTreeNodeTypeNames[adltnNone]));
+  Minimized:=Config.GetValue('Minimized',false);
   Left:=Config.GetValue('Bounds/Left',0);
   Top:=Config.GetValue('Bounds/Top',0);
   Width:=Config.GetValue('Bounds/Width',0);
@@ -1171,6 +1190,7 @@
   Clear;
   Name:=Config.GetValue(Path+'Name','');
   NodeType:=NameToADLTreeNodeType(Config.GetValue(Path+'Type',ADLTreeNodeTypeNames[adltnNone]));
+  Minimized:=Config.GetValue(Path+'Minimized',false);
   Left:=Config.GetValue(Path+'Bounds/Left',0);
   Top:=Config.GetValue(Path+'Bounds/Top',0);
   Width:=Config.GetValue(Path+'Bounds/Width',0);
@@ -1219,6 +1239,7 @@
                                           ADLHeaderPositionNames[adlhpAuto]);
   Config.SetDeleteValue('Header/TabPosition',ADLTabPostionNames[TabPosition],
                                              ADLTabPostionNames[tpTop]);
+  Config.SetDeleteValue('Minimized',Minimized,False);
   Config.SetDeleteValue('Monitor',Monitor,0);
   Config.SetDeleteValue('ChildCount',Count,0);
   for i:=1 to Count do begin
@@ -1252,6 +1273,7 @@
                                                ADLHeaderPositionNames[adlhpAuto]);
   Config.SetDeleteValue(Path+'Header/TabPosition',ADLTabPostionNames[TabPosition],
                                                   ADLTabPostionNames[tpTop]);
+  Config.SetDeleteValue(Path+'Minimized',Minimized,False);
   Config.SetDeleteValue(Path+'Monitor',Monitor,0);
   Config.SetDeleteValue(Path+'ChildCount',Count,0);
   for i:=1 to Count do
@@ -1397,7 +1419,7 @@
   end;
 end;
 
-procedure TAnchorDockLayoutTreeNode.Simplify(ExistingNames: TStrings);
+procedure TAnchorDockLayoutTreeNode.Simplify(ExistingNames: TStrings; ParentMinimized:boolean);
 { Simplification rules:
    1. Control nodes without existing name are deleted.
    2. Empty layouts and pages are deleted
@@ -1406,16 +1428,18 @@
 var
   i: Integer;
   ChildNode: TAnchorDockLayoutTreeNode;
+  NodeMinimized:boolean;
 begin
   // simplify children
   i:=Count-1;
   while i>=0 do begin
     ChildNode:=Nodes[i];
-    ChildNode.Simplify(ExistingNames);
+    NodeMinimized:=ParentMinimized or ChildNode.Minimized;
+    ChildNode.Simplify(ExistingNames,NodeMinimized);
 
     if (ChildNode.NodeType=adltnControl) then begin
       // leaf node => check if there is a control
-      if (ChildNode.Name='') or (ExistingNames.IndexOf(ChildNode.Name)<0) then
+      if (ChildNode.Name='') or ((ExistingNames.IndexOf(ChildNode.Name)<0) and (not NodeMinimized)) then
         DeleteNode(ChildNode);
     end else if ChildNode.IsSplitter then begin
       // splitter
@@ -1424,7 +1448,7 @@
         ChildNode[0].Free;
     end else if ChildNode.NodeType=adltnCustomSite then begin
       // custom dock site
-    end else if ChildNode.Count=0 then begin
+    end else if (ChildNode.Count=0)and(not NodeMinimized) then begin
       // inner node without child => delete
       DeleteNode(ChildNode);
     end else if (ChildNode.Count=1)
Index: components/anchordocking/anchordockstr.pas
===================================================================
--- components/anchordocking/anchordockstr.pas	(revision 59428)
+++ components/anchordocking/anchordockstr.pas	(working copy)
@@ -8,6 +8,7 @@
 
 resourcestring
   adrsClose = 'Close';
+  adrsMinimize = 'Minimize';
   adrsQuit = 'Quit %s';
   adrsTabPosition = 'Tab position';
   adrsMovePageRight = 'Move page right';
@@ -82,6 +83,8 @@
   adrsFilledHeadersHint = 'Fill headers of docked controls';
   adrsHighlightFocused = 'Highlight focused';
   adrsHighlightFocusedHint = 'Highlight header of focused docked control';
+  adrsDockSitesCanBeMinimized = 'Dock sites can be minimized';
+  adrsDockSitesCanBeMinimizedHint = 'Dock sites can be minimized';
 
 implementation
 
Index: components/anchordocking/design/anchordesktopoptions.pas
===================================================================
--- components/anchordocking/design/anchordesktopoptions.pas	(revision 59428)
+++ components/anchordocking/design/anchordesktopoptions.pas	(working copy)
@@ -272,7 +272,7 @@
         // custom dock site
         LayoutNode:=FTree.NewNode(FTree.Root);
         LayoutNode.NodeType:=adltnCustomSite;
-        LayoutNode.Assign(AForm);
+        LayoutNode.Assign(AForm,false,false);
         // can have one normal dock site
         Site:=TAnchorDockManager(AForm.DockManager).GetChildSite;
         if Site<>nil then begin
@@ -287,7 +287,7 @@
         raise EAnchorDockLayoutError.Create('invalid root control for save: '+DbgSName(AControl));
     end;
     // remove invisible controls
-    FTree.Root.Simplify(VisibleControls);
+    FTree.Root.Simplify(VisibleControls,false);
   finally
     VisibleControls.Free;
     SavedSites.Free;

Andrey Zubarev

2018-11-27 20:25

reporter   ~0112235

anchordocking_minimize_docksite12.patch

Last 1,2 issues fixed:
>>Project Inspector also should not have a minimize button.
>>if the adjacent window is minimized, this window should not have a minimize button

Now I see a few small problems, and two big ones:
1) Bugs with double loading layout with minimized sites
2) Problem with unminimize site after dock a window nearby. When free space became less than the original width unminimized site

I will solve it, but please add the current patch. I'm already bad at navigating my changes, it makes it difficult to work

Michl

2018-11-27 21:35

developer   ~0112237

I commited the patch with minor formatting changes. Thank you!

Michl

2018-11-27 21:52

developer   ~0112238

I've seen, you are not listed in the contributors list. You have posted a lot of patches for bugs and features. I'll add you to that list. Is Andrey Zubarev your correct name and can I add you to the list?

Andrey Zubarev

2018-11-27 22:24

reporter   ~0112239

Yes, Andrey Zubarev my correct name. You can add. Thanks!

Michl

2018-11-27 23:09

developer   ~0112240

Done. I hope of more good patches from you ;)

Andrey Zubarev

2018-11-28 11:17

reporter   ~0112244

Thanks!

Andrey Zubarev

2019-01-17 20:51

reporter   ~0113452

Found small bug. If load layout for visible=false forms minimize button not show.
To fix need modify DockedControlIsVisible function. Modifed function:

function DockedControlIsVisible(Control: TControl): boolean;
begin
  while Control<>nil do begin
    if (not Control.IsControlVisible)
    and (not (Control is TAnchorDockPage))//exclude pages
    and (Control.parent<>nil )then //exclude top level forms
      exit(false);
    Control:=Control.Parent;
  end;
  Result:=true;
end;

Unfortunately I can not give the patch, I have accumulated too many changes

Michl

2019-01-17 23:46

developer   ~0113456

Applied. Thank you!

Andrey Zubarev

2019-01-18 07:46

reporter   ~0113458

Thanks!

Michl

2019-01-27 17:58

developer   ~0113675

> Found small bug. If load layout for visible=false forms minimize button not show.
> To fix need modify DockedControlIsVisible function. Modifed function:

As I can't see the problem, can you please add a layout for this bug?! I reverted the last patch in revision 60233. With it, a closed site was wrongly reopened after loading layout.

Andrey Zubarev

2019-01-27 20:07

reporter   ~0113677

The problem occurs if you load layout on starting program, before show mainform. Try attached layout.xml with minidewithdockpanel example, it will be loaded before the form is shown, in Application.Createform, And minimize button not shown, although he enabled in attached layout.xml

Andrey Zubarev

2019-01-27 20:07

reporter  

layout.xml (1,060 bytes)   
<?xml version="1.0" encoding="utf-8"?>
<CONFIG>
  <MainConfig>
    <Nodes ChildCount="1">
      <Item1 Name="AnchorDockPanel1" Type="CustomSite" ChildCount="1">
        <Bounds Top="43" Left="45" Width="568" Height="418"/>
        <Anchors Align="Client"/>
        <Item1 Name="AnchorDockSite3" Type="Layout" ChildCount="3">
          <Bounds Top="1" Left="1" Width="524" Height="325"/>
          <Anchors Align="Client"/>
          <Item1 Name="SourceEditor1" Type="Control">
            <Bounds Width="524" Height="171"/>
            <Anchors Bottom="AnchorDockSplitter1"/>
          </Item1>
          <Item2 Name="AnchorDockSplitter1" Type="SplitterHorizontal">
            <Bounds Top="171" Width="524" Height="4"/>
          </Item2>
          <Item3 Name="DebugOutput" Type="Control">
            <Bounds Top="175" Width="524" Height="150"/>
            <Anchors Top="AnchorDockSplitter1"/>
          </Item3>
        </Item1>
      </Item1>
    </Nodes>
  </MainConfig>
  <Settings DockSitesCanBeMinimized="True"/>
</CONFIG>
layout.xml (1,060 bytes)   

Michl

2019-01-27 23:24

developer   ~0113682

I removed the check DockedControlIsVisible in UpdateHeaders. At least your patch does the same.

This is IMHO not the best solution. Maybe a loading (and simelar) state for DockMaster could be inserted, whith it, there were a chance to detect this special case to call UpdateHeaderShowing. For now, I'll not insert such a new state property.

Andrey Zubarev

2019-01-28 06:32

reporter   ~0113684

Thanks!

Issue History

Date Modified Username Field Change
2018-09-27 12:04 Andrey Zubarev New Issue
2018-09-27 12:04 Andrey Zubarev File Added: button.png
2018-09-27 15:16 Juha Manninen Note Added: 0111054
2018-09-28 07:16 Andrey Zubarev Note Added: 0111059
2018-09-28 09:17 Juha Manninen Note Added: 0111060
2018-10-19 18:41 Juha Manninen Relationship added related to 0034363
2018-10-30 11:48 Andrey Zubarev Note Added: 0111677
2018-10-30 11:49 Andrey Zubarev File Added: anchordocking_minimize_docksite1.patch
2018-10-30 22:34 Juha Manninen Note Added: 0111697
2018-10-30 23:34 Andrey Zubarev Note Added: 0111699
2018-10-30 23:35 Andrey Zubarev File Added: anchordocking_minimize_docksite2.patch
2018-10-31 18:57 Juha Manninen Note Added: 0111710
2018-10-31 19:10 Andrey Zubarev Note Added: 0111711
2018-10-31 19:19 Andrey Zubarev Note Added: 0111712
2018-10-31 21:00 Michl Assigned To => Michl
2018-10-31 21:00 Michl Status new => assigned
2018-10-31 21:04 Michl LazTarget => -
2018-10-31 21:04 Michl Summary AnchorDocing feature (new button: size reduction of the panel) => AnchorDocking feature (new button: size reduction of the panel)
2018-10-31 22:36 Andrey Zubarev File Added: anchordocking_minimize_docksite3.patch
2018-10-31 22:37 Andrey Zubarev Note Added: 0111717
2018-11-04 13:22 Andrey Zubarev File Added: anchordocking_minimize_docksite4.patch
2018-11-04 13:26 Andrey Zubarev Note Added: 0111784
2018-11-06 07:16 Andrey Zubarev File Added: anchordocking_minimize_docksite5.patch
2018-11-06 07:18 Andrey Zubarev Note Added: 0111804
2018-11-07 11:26 Andrey Zubarev File Added: anchordocking_minimize_docksite6.patch
2018-11-07 11:30 Andrey Zubarev Note Added: 0111824
2018-11-07 14:16 Andrey Zubarev File Added: anchordocking_minimize_docksite7.patch
2018-11-07 14:16 Andrey Zubarev Note Edited: 0111824 View Revisions
2018-11-07 14:22 Andrey Zubarev Note Added: 0111831
2018-11-08 21:37 Andrey Zubarev Note Added: 0111872
2018-11-11 00:19 Andrey Zubarev File Added: anchordocking_minimize_docksite8.patch
2018-11-11 00:21 Andrey Zubarev Note Added: 0111897
2018-11-11 00:23 Andrey Zubarev Note Edited: 0111897 View Revisions
2018-11-11 21:49 Michl Note Added: 0111912
2018-11-11 21:50 Michl Note Edited: 0111912 View Revisions
2018-11-12 00:08 Andrey Zubarev File Added: anchordocking_minimize_docksite9.patch
2018-11-12 00:12 Andrey Zubarev Note Added: 0111917
2018-11-12 21:01 Michl File Added: test.xml
2018-11-12 21:12 Michl File Added: test.png
2018-11-12 21:14 Michl Note Added: 0111942
2018-11-12 21:25 Michl File Added: Test2.png
2018-11-12 21:30 Michl Note Edited: 0111942 View Revisions
2018-11-12 21:31 Michl Note Edited: 0111942 View Revisions
2018-11-12 23:11 Andrey Zubarev Note Added: 0111945
2018-11-13 07:21 Michl Note Added: 0111946
2018-11-14 21:16 Andrey Zubarev File Added: anchordocking_minimize_docksite10.patch
2018-11-14 21:21 Andrey Zubarev Note Added: 0111977
2018-11-14 22:26 Michl File Added: Test3.png
2018-11-14 22:44 Michl Note Added: 0111981
2018-11-14 22:44 Michl Note Edited: 0111981 View Revisions
2018-11-14 22:48 Michl File Added: test2.xml
2018-11-14 22:53 Michl Note Edited: 0111981 View Revisions
2018-11-15 13:48 Andrey Zubarev Note Added: 0111984
2018-11-18 19:09 Andrey Zubarev File Added: anchordocking_minimize_docksite11.patch
2018-11-18 19:12 Andrey Zubarev Note Added: 0112050
2018-11-25 15:31 Juha Manninen Relationship added related to 0034508
2018-11-27 09:34 Michl File Added: test3.xml
2018-11-27 09:50 Michl Note Added: 0112225
2018-11-27 11:48 Andrey Zubarev Note Added: 0112229
2018-11-27 11:50 Andrey Zubarev Note Edited: 0112229 View Revisions
2018-11-27 20:15 Andrey Zubarev File Added: anchordocking_minimize_docksite12.patch
2018-11-27 20:25 Andrey Zubarev Note Added: 0112235
2018-11-27 21:35 Michl Fixed in Revision => 59681
2018-11-27 21:35 Michl Note Added: 0112237
2018-11-27 21:35 Michl Status assigned => resolved
2018-11-27 21:35 Michl Fixed in Version => 2.1 (SVN)
2018-11-27 21:35 Michl Resolution open => fixed
2018-11-27 21:35 Michl Target Version => 2.2
2018-11-27 21:52 Michl Note Added: 0112238
2018-11-27 21:52 Michl Status resolved => feedback
2018-11-27 22:24 Andrey Zubarev Note Added: 0112239
2018-11-27 22:24 Andrey Zubarev Status feedback => assigned
2018-11-27 23:09 Michl Note Added: 0112240
2018-11-27 23:09 Michl Status assigned => resolved
2018-11-28 11:17 Andrey Zubarev Note Added: 0112244
2018-11-28 11:17 Andrey Zubarev Status resolved => closed
2018-12-12 22:09 Michl Relationship added related to 0034614
2018-12-12 22:10 Michl Relationship added related to 0034612
2019-01-17 20:51 Andrey Zubarev Note Added: 0113452
2019-01-17 20:51 Andrey Zubarev Status closed => assigned
2019-01-17 20:51 Andrey Zubarev Resolution fixed => reopened
2019-01-17 23:46 Michl Fixed in Revision 59681 => 59681, 60099
2019-01-17 23:46 Michl Note Added: 0113456
2019-01-17 23:46 Michl Status assigned => resolved
2019-01-17 23:46 Michl Resolution reopened => fixed
2019-01-18 07:46 Andrey Zubarev Note Added: 0113458
2019-01-18 07:46 Andrey Zubarev Status resolved => closed
2019-01-27 17:54 Michl Status closed => assigned
2019-01-27 17:54 Michl Resolution fixed => reopened
2019-01-27 17:58 Michl Note Added: 0113675
2019-01-27 17:58 Michl Status assigned => feedback
2019-01-27 20:07 Andrey Zubarev Note Added: 0113677
2019-01-27 20:07 Andrey Zubarev Status feedback => assigned
2019-01-27 20:07 Andrey Zubarev File Added: layout.xml
2019-01-27 23:24 Michl Fixed in Revision 59681, 60099 => 59681, 60099, 60233, 60234
2019-01-27 23:24 Michl Note Added: 0113682
2019-01-27 23:24 Michl Status assigned => resolved
2019-01-27 23:24 Michl Resolution reopened => fixed
2019-01-28 06:32 Andrey Zubarev Note Added: 0113684
2019-01-28 06:32 Andrey Zubarev Status resolved => closed