Ignore:
Timestamp:
May 4, 2012, 12:27:25 PM (12 years ago)
Author:
chronos
Message:
  • Fixed: Regions size update on Control visible state change.
  • Added: Support for custom center region selection. Surrounding regions are aligned to edges and keep size on docksite resize.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • Docking/CoolDocking/Managers/UCDManagerRegions.pas

    r355 r359  
    1515
    1616  TCDManagerRegionsItem = class(TCDManagerItem)
     17  private
     18  public
    1719    PanelHeader: TCDPanelHeader;
    1820    Splitter: TSplitter;
    19     Align: TAlign;
    2021    procedure VisibleChange(Sender: TObject); override;
    2122    procedure Paint(Sender: TObject); override;
     23    procedure PanelResize(Sender: TObject);
    2224    constructor Create;
    2325    destructor Destroy; override;
    2426    procedure SetControl(const AValue: TWinControl); override;
     27    procedure SetCenter;
    2528  end;
    2629
     
    3033  private
    3134    FDockItems: TObjectList; // TList<TCDManagerRegionsItem>
     35    FLastVisibleItemsCount: Integer;
    3236    function GetHeaderPos: THeaderPos; override;
    3337    procedure SetHeaderPos(const AValue: THeaderPos); override;
    3438    function GetDirection(InsertAt: TAlign): TCDDirection;
     39    procedure ResizePanels;
     40    procedure ClearItemsAlignment;
     41    procedure UpdateItemsAlignment;
     42    function PanelsVisible: Integer;
     43  protected
     44    FDockDirection: TCDDirection;
    3545  public
    36     FDockDirection: TCDDirection;
    3746    //Panels: TObjectList; // TObjectList<TCDStyleRegionsPanel>
    3847    function FindControlInPanels(Control: TControl): TCDManagerItem; override;
     
    5968{ TCDManagerRegionsItem }
    6069
     70procedure TCDManagerRegionsItem.SetCenter;
     71begin
     72  TCDManagerRegions(Manager).ClearItemsAlignment;
     73  PanelHeader.Align := alClient;
     74  Manager.Update;
     75end;
     76
    6177procedure TCDManagerRegionsItem.VisibleChange(Sender: TObject);
    6278begin
     
    6682    //  TCDManagerRegionsItem(DockItems[DockItems.IndexOf(FindControlInPanels(TControl(Sender)))]).HideType := dhtPermanent;
    6783    //end;
     84    PanelHeader.Visible := Control.Visible;
    6885    Update;
    6986
     
    91108end;
    92109
     110procedure TCDManagerRegionsItem.PanelResize(Sender: TObject);
     111begin
     112  TCDManagerRegions(Manager).ResizePanels;
     113end;
     114
    93115constructor TCDManagerRegionsItem.Create;
    94116begin
     
    97119  PanelHeader.Header.OnMouseDown := DockPanelMouseDown;
    98120  PanelHeader.Header.Icon.OnMouseDown := DockPanelMouseDown;
     121  PanelHeader.OnResize := PanelResize;
    99122
    100123  Splitter := TSplitter.Create(nil);
     
    113136  Splitter.Parent := nil;
    114137  Splitter.Free;
    115   Control.Parent := nil;
     138  if Assigned(Control) then Control.Parent := nil;
    116139  inherited Destroy;
    117140end;
     
    153176end;
    154177
     178procedure TCDManagerRegions.ResizePanels;
     179var
     180  I: Integer;
     181  CenterPanelSize: TPoint;
     182  Zoom: Real;
     183const
     184  MinSize = 30;
     185begin
     186  I := 0;
     187  while (I < DockItems.Count) and
     188    (TCDManagerRegionsItem(DockItems[I]).PanelHeader.Align <> alClient) do
     189      Inc(I);
     190  if I < DockItems.Count then begin
     191    CenterPanelSize.X := TCDManagerRegionsItem(DockItems[I]).PanelHeader.Width;
     192    CenterPanelSize.Y := TCDManagerRegionsItem(DockItems[I]).PanelHeader.Height;
     193  end else Exit;
     194  if (CenterPanelSize.X < MinSize) and (FDockDirection = ddHorizontal) then begin
     195    Zoom := CenterPanelSize.X / MinSize;
     196    for I := 0 to DockItems.Count - 1 do
     197      with TCDManagerRegionsItem(DockItems[I]).PanelHeader do
     198        if Align <> alClient then Width := Round(Width * Zoom);
     199  end;
     200  if (CenterPanelSize.Y < MinSize) and (FDockDirection = ddVertical) then begin
     201    Zoom := CenterPanelSize.Y / MinSize;
     202    for I := 0 to DockItems.Count - 1 do
     203      with TCDManagerRegionsItem(DockItems[I]).PanelHeader do
     204        if Align <> alClient then Height := Round(Height * Zoom);
     205  end;
     206end;
     207
     208procedure TCDManagerRegions.ClearItemsAlignment;
     209var
     210  I: Integer;
     211begin
     212  for I := 0 to FDockItems.Count - 1 do
     213  with TCDManagerRegionsItem(FDockItems[I]) do begin
     214    PanelHeader.Align := alNone;
     215    Splitter.Align := alNone;
     216  end;
     217end;
     218
     219procedure TCDManagerRegions.UpdateItemsAlignment;
     220var
     221  I: Integer;
     222  ClientPanelIndex: Integer;
     223begin
     224  // Find alClient panel item index
     225  I := 0;
     226  while (I < FDockItems.Count) and
     227    (TCDManagerRegionsItem(FDockItems[I]).PanelHeader.Align <> alClient) do Inc(I);
     228  if I < FDockItems.Count then ClientPanelIndex := I
     229    else ClientPanelIndex := FDockItems.Count div 2;
     230
     231  // Normalize alignment
     232  for I := 0 to FDockItems.Count - 1 do
     233  with TCDManagerRegionsItem(FDockItems[I]) do begin
     234    if FDockDirection = ddHorizontal then begin
     235      if I < ClientPanelIndex then PanelHeader.Align := alLeft
     236        else if I = ClientPanelIndex then PanelHeader.Align := alClient
     237        else if I > ClientPanelIndex then PanelHeader.Align := alRight;
     238    end;
     239    if FDockDirection = ddVertical then begin
     240      if I < ClientPanelIndex then PanelHeader.Align := alTop
     241        else if I = ClientPanelIndex then PanelHeader.Align := alClient
     242        else if I > ClientPanelIndex then PanelHeader.Align := alBottom;
     243    end;
     244  end;
     245end;
     246
     247function TCDManagerRegions.PanelsVisible: Integer;
     248var
     249  I: Integer;
     250begin
     251  Result := 0;
     252  for I := 0 to FDockItems.Count - 1 do
     253  with TCDManagerRegionsItem(FDockItems[I]) do begin
     254    if PanelHeader.Visible then Inc(Result);
     255  end;
     256end;
     257
    155258function TCDManagerRegions.FindControlInPanels(Control: TControl
    156259  ): TCDManagerItem;
     
    172275  NewItem := TCDManagerRegionsItem.Create;
    173276  with NewItem do begin
     277    PanelHeader.DockItem := NewItem;
    174278    PanelHeader.Parent := Self.DockSite;
    175279    Manager := Self;
     
    184288
    185289  NewItem.PanelHeader.Parent := DockSite;
    186 
    187   if DockItems.Count = 0 then NewItem.Align := alClient
    188     else NewItem.Align := InsertAt;
    189290
    190291  NewItem.Control := TWinControl(Control);
     
    302403var
    303404  I: Integer;
    304   SplitterLeft: Integer;
    305   SplitterTop: Integer;
    306   BaseAlign: TAlign;
     405  PositionLeft: Integer;
     406  PositionTop: Integer;
    307407  VisibleControlsCount: Integer;
     408const
     409  MinSize = 30;
    308410begin
    309411  inherited;
    310412  if FUpdateCount = 0 then begin
    311413  DebugLog('TCDManagerRegions.UpdateClientSize');
    312   VisibleControlsCount := DockSite.VisibleDockClientCount;
     414  VisibleControlsCount := PanelsVisible;
    313415  if DockSite is TForm then begin
    314     DockSiteVisible := VisibleControlsCount > 0;
     416    //DockSiteVisible := VisibleControlsCount > 0;
    315417  end;
    316418  if VisibleControlsCount = 0 then VisibleControlsCount := 1;
    317419
     420  PositionLeft := 0;
     421  PositionTop := 0;
     422  UpdateItemsAlignment;
    318423  for I := 0 to DockItems.Count - 1 do
    319424  with TCDManagerRegionsItem(DockItems[I]) do
    320425  begin
    321     PanelHeader.Left := SplitterLeft;
    322     PanelHeader.Top := SplitterTop;
    323     PanelHeader.Height := Self.DockSite.Height div
    324       VisibleControlsCount;
    325     PanelHeader.Width := Self.DockSite.Width div
    326       VisibleControlsCount;
     426    PanelHeader.Left := PositionLeft;
     427    PanelHeader.Top := PositionTop;
     428    if (FLastVisibleItemsCount <> VisibleControlsCount) then begin
     429      PanelHeader.Height := Self.DockSite.Height div
     430        VisibleControlsCount;
     431      PanelHeader.Width := Self.DockSite.Width div
     432        VisibleControlsCount;
     433    end;
     434    if PanelHeader.Height < MinSize then PanelHeader.Height := MinSize;
     435    if PanelHeader.Width < MinSize then PanelHeader.Width := MinSize;
     436
    327437    if Assigned(TWinControl(Control).DockManager) then
    328438      PanelHeader.Header.Visible := TCDManager(TWinControl(Control).DockManager).HeaderVisible;
    329439    PanelHeader.Visible := Control.Visible;
    330440    Paint(Self);
    331     if FDockDirection = ddHorizontal then
    332       BaseAlign := alLeft else BaseAlign := alTop;
    333 
    334     if I < Trunc((DockItems.Count - 1) / 2) then BaseAlign := BaseAlign
    335         else if I = Trunc((DockItems.Count - 1) / 2) then BaseAlign := alClient
    336         else if I > Trunc((DockItems.Count - 1) / 2) then begin
    337           if BaseAlign = alTop then BaseAlign := alBottom
    338           else if BaseAlign = alLeft then BaseAlign := alRight;
    339         end;
    340     PanelHeader.Align := BaseAlign;
    341 
    342     Splitter.Align := BaseAlign;
    343     SplitterLeft := PanelHeader.Left;
    344     SplitterTop := PanelHeader.Top;
    345     Splitter.Left := SplitterLeft;
    346     Splitter.Top := SplitterTop;
     441
     442    //PositionLeft := PanelHeader.Left;
     443    //PositionTop := PanelHeader.Top;
     444    if PanelHeader.Align = alLeft then Splitter.Left := PositionLeft + PanelHeader.Width + 1;
     445    if PanelHeader.Align = alRight then Splitter.Left := PositionLeft - 1;
     446    if PanelHeader.Align = alTop then Splitter.Top := PositionTop + PanelHeader.Height + 1;
     447    if PanelHeader.Align = alBottom then Splitter.Top := PositionTop - 1;
     448    Splitter.Align := PanelHeader.Align;
    347449    Splitter.Parent := Self.DockSite;
    348     Splitter.Visible := I <> (Trunc(DockItems.Count - 1) / 2);
    349     Inc(SplitterLeft, Splitter.Width);
    350     Inc(SplitterTop, Splitter.Height);
     450    Splitter.Visible := PanelHeader.Visible and (PanelHeader.Align <> alClient);
     451    Splitter.Width := 3;
     452    Splitter.Height := 3;
     453    Inc(PositionLeft, Splitter.Width + PanelHeader.Width);
     454    Inc(PositionTop, Splitter.Height + PanelHeader.Height);
    351455
    352456    Paint(Self);
    353     PanelHeader.Align := BaseAlign;
    354   end;
     457    //PanelHeader.Align := BaseAlign;
     458  end;
     459    FLastVisibleItemsCount := VisibleControlsCount;
    355460  end;
    356461end;
     
    362467  inherited;
    363468  //if DockSite.Visible <> AValue then
     469  if DockItems.Count > 0 then
    364470  try
    365471    BeginUpdate;
Note: See TracChangeset for help on using the changeset viewer.