Ignore:
Timestamp:
Sep 16, 2010, 1:52:48 PM (14 years ago)
Author:
george
Message:
  • Upraveno: Přepracováno na uchování seznamu ukotvovacích klientů horizontálně nebo vertikálně.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • DockManager/Lazarus/UCustomDockManager.pas

    r42 r43  
    77uses
    88  Classes, SysUtils, Controls, LCLType, LMessages, Graphics, StdCtrls,
    9   Buttons, ExtCtrls;
     9  Buttons, ExtCtrls, Contnrs, Forms;
    1010
    1111const
     
    1313
    1414type
    15 
    16   { TCustomDockManager }
    17 
    18   TCustomDockManager = class(TDockManager)
    19   private
    20     FDockSite: TWinControl;
    21     FDockPanel: TPanel;
     15  TDockDirection = (ddNone, ddHorizontal, ddVertical);
     16
     17  TCustomDockManager = class;
     18
     19  TConjoinDockForm = class(TForm)
     20
     21  end;
     22
     23  { TDockClientPanel }
     24
     25  TDockClientPanel = class(TPanel)
     26    OwnerDockManager: TCustomDockManager;
    2227    CloseButton: TSpeedButton;
    23     procedure DrawGrabber(Canvas: TCanvas; AControl: TControl);
    24     procedure CloseButtonClick(Sender: TObject);
     28    Control: TControl;
     29    Splitter: TSplitter;
     30    constructor Create(TheOwner: TComponent); override;
     31    destructor Destroy; override;
    2532    procedure DockPanelPaint(Sender: TObject);
    2633    procedure DockPanelMouseDown(Sender: TObject; Button: TMouseButton;
    2734      Shift: TShiftState; X, Y: Integer);
     35    procedure DrawGrabber(Canvas: TCanvas; AControl: TControl);
     36    procedure CloseButtonClick(Sender: TObject);
     37    procedure ResizeExecute(Sender: TObject);
     38  end;
     39
     40  { TCustomDockManager }
     41
     42  TCustomDockManager = class(TDockManager)
     43  private
     44    FDockDirection: TDockDirection;
     45    FDockSite: TWinControl;
     46    FDockPanels: TObjectList; // of TDockClientPanel
     47    function FindControlInPanels(Control: TControl): TDockClientPanel;
    2848  public
    2949    constructor Create(ADockSite: TWinControl); override;
     
    5474{ TCustomDockManager }
    5575
    56 procedure TCustomDockManager.DrawGrabber(Canvas: TCanvas; AControl: TControl);
    57 begin
    58   with Canvas do begin
    59     Brush.Color := clBtnFace;
    60     Pen.Color := clBlack;
    61     FillRect(0, 0, AControl.Width, GrabberSize);
    62     Rectangle(1, 1, AControl.Width - 1, GrabberSize - 1);
    63     TextOut(6, 2, AControl.Caption);
    64 
    65     CloseButton.Left := AControl.Width - CloseButton.Width - 2;
    66     CloseButton.Top := 2;
    67   end;
    68 end;
    69 
    70 procedure TCustomDockManager.CloseButtonClick(Sender: TObject);
     76function TCustomDockManager.FindControlInPanels(Control: TControl
     77  ): TDockClientPanel;
     78var
     79  I: Integer;
     80begin
     81  I := 0;
     82  while (I < FDockPanels.Count) and
     83    (TDockClientPanel(FDockPanels[I]).Control <> Control) do Inc(I);
     84  if I < FDockPanels.Count then Result := TDockClientPanel(FDockPanels[I])
     85    else Result := nil;
     86end;
     87
     88constructor TCustomDockManager.Create(ADockSite: TWinControl);
     89begin
     90  FDockSite := ADockSite;
     91  FDockPanels := TObjectList.Create;
     92  inherited Create(ADockSite);
     93end;
     94
     95destructor TCustomDockManager.Destroy;
     96begin
     97  FDockPanels.Free;
     98  inherited Destroy;
     99end;
     100
     101procedure TCustomDockManager.BeginUpdate;
     102begin
     103  inherited BeginUpdate;
     104end;
     105
     106procedure TCustomDockManager.EndUpdate;
     107begin
     108  inherited EndUpdate;
     109end;
     110
     111procedure TCustomDockManager.GetControlBounds(Control: TControl; out
     112  AControlBounds: TRect);
     113begin
     114end;
     115
     116function TCustomDockManager.GetDockEdge(ADockObject: TDragDockObject): boolean;
     117begin
     118  Result := inherited GetDockEdge(ADockObject);
     119end;
     120
     121procedure TCustomDockManager.InsertControl(ADockObject: TDragDockObject);
     122begin
     123  inherited InsertControl(ADockObject);
     124end;
     125
     126procedure TCustomDockManager.InsertControl(Control: TControl; InsertAt: TAlign;
     127  DropCtl: TControl);
     128var
     129  NewSplitter: TSplitter;
     130  NewPanel: TDockClientPanel;
     131  I: Integer;
     132begin
     133  if FDockSite.DockClientCount = 2 then begin
     134    if (InsertAt = alTop) or (InsertAt = alBottom) then
     135      FDockDirection := ddVertical
     136    else
     137    if (InsertAt = alLeft) or (InsertAt = alRight) then
     138      FDockDirection := ddHorizontal
     139    else FDockDirection := ddHorizontal;
     140  end;
     141  if FDockSite.DockClientCount > 1 then begin
     142    NewSplitter := TSplitter.Create(nil);
     143    NewSplitter.Parent := FDockSite;
     144    NewSplitter.Visible := True;
     145    NewSplitter.Color := clRed;
     146    with NewSplitter do
     147    if FDockDirection = ddVertical then begin
     148      Align := alTop;
     149      Top := FDockSite.Height;
     150    end else
     151    if FDockDirection = ddHorizontal then begin
     152      Align := alLeft;
     153      Left := FDockSite.Width;
     154    end;
     155
     156    with TDockClientPanel(FDockPanels.Last) do
     157    if FDockDirection = ddVertical then
     158      Align := alTop
     159    else
     160    if FDockDirection = ddHorizontal then
     161      Align := alLeft;
     162  end;
     163  NewPanel := TDockClientPanel.Create(nil);
     164  with NewPanel do begin
     165    Splitter := NewSplitter;
     166    Parent := FDockSite;
     167    OwnerDockManager := Self;
     168    Visible := True;
     169    Align := alClient;
     170  end;
     171  NewPanel.Control := Control;
     172  Control.Parent := NewPanel;
     173  FDockPanels.Add(NewPanel);
     174
     175  for I := 0 to FDockPanels.Count - 1 do begin
     176    TDockClientPanel(FDockPanels[I]).Height := FDockSite.Height div
     177      FDockSite.DockClientCount;
     178    TDockClientPanel(FDockPanels[I]).Width := FDockSite.Width div
     179      FDockSite.DockClientCount;
     180  end;
     181
     182//  FDockPanel.Invalidate;
     183  inherited;
     184end;
     185
     186procedure TCustomDockManager.LoadFromStream(Stream: TStream);
     187begin
     188end;
     189
     190procedure TCustomDockManager.PaintSite(DC: HDC);
     191var
     192  Canvas: TControlCanvas;
     193  Control: TControl;
     194  I: Integer;
     195  R: TRect;
     196begin
     197  for I := 0 to FDockPanels.Count - 1 do
     198    with TDockClientPanel(FDockPanels[I]) do begin
     199      Invalidate;
     200    end;
     201end;
     202
     203procedure TCustomDockManager.MessageHandler(Sender: TControl;
     204  var Message: TLMessage);
     205begin
     206  inherited MessageHandler(Sender, Message);
     207end;
     208
     209procedure TCustomDockManager.PositionDockRect(ADockObject: TDragDockObject);
     210begin
     211  inherited PositionDockRect(ADockObject);
     212end;
     213
     214procedure TCustomDockManager.PositionDockRect(Client, DropCtl: TControl;
     215  DropAlign: TAlign; var DockRect: TRect);
     216begin
     217  case DropAlign of
     218    alNone: begin
     219      DockRect := Rect(0, 0, FDockSite.ClientWidth, FDockSite.ClientHeight);
     220    end;
     221    alRight: begin
     222      DockRect := Rect(FDockSite.ClientWidth div 2, 0, FDockSite.ClientWidth, FDockSite.ClientHeight);
     223    end;
     224    alLeft: begin
     225      DockRect := Rect(0, 0, FDockSite.ClientWidth div 2, FDockSite.ClientHeight);
     226    end;
     227    alTop: begin
     228      DockRect := Rect(0, 0, FDockSite.ClientWidth, FDockSite.ClientHeight div 2);
     229    end;
     230    alBottom: begin
     231      DockRect := Rect(0, FDockSite.ClientHeight div 2, FDockSite.ClientWidth, FDockSite.ClientHeight);
     232    end;
     233  end;
     234  DockRect.TopLeft := FDockSite.ClientToScreen(DockRect.TopLeft);
     235  DockRect.BottomRight := FDockSite.ClientToScreen(DockRect.BottomRight);
     236end;
     237
     238procedure TCustomDockManager.RemoveControl(Control: TControl);
     239var
     240  ClientPanel: TDockClientPanel;
     241begin
     242  inherited;
     243  if Control.HostDockSite = Self.FDockSite then begin
     244    ClientPanel := FindControlInPanels(Control);
     245    //ClientPanel.Splitter.Free;
     246    FDockPanels.Remove(ClientPanel);
     247    if FDockSite.DockClientCount = 2 then FDockDirection := ddNone;
     248    //FDockSite.Invalidate;
     249  end;
     250end;
     251
     252procedure TCustomDockManager.ResetBounds(Force: Boolean);
    71253var
    72254  I: Integer;
     
    74256  R: TRect;
    75257begin
    76   for I := 0 to FDockSite.ControlCount - 1 do
    77     begin
    78       Control := FDockSite.Controls[I];
    79       if Control.Visible and (Control.HostDockSite = FDockSite) then
    80       begin
    81         Control.Hide;
    82       end;
    83     end;
    84   FDockPanel.Hide;
    85 end;
    86 
    87 procedure TCustomDockManager.DockPanelPaint(Sender: TObject);
    88 var
    89   I: Integer;
    90   Control: TControl;
    91   R: TRect;
    92 begin
    93   CloseButton.Visible := FDockSite.DockClientCount > 0;
    94   for I := 0 to FDockSite.DockClientCount - 1 do begin
    95     Control := FDockSite.DockClients[I];
    96     if Control.Visible and (Control.HostDockSite = FDockSite) then
    97     begin
    98       R := Control.BoundsRect;
    99       //Control.SetBounds(0, GrabberSize, FDockSite.Width - Control.Left,
    100       //  FDockSite.Height - Control.Top);
    101       //Canvas.FillRect(R);
    102       DrawGrabber(FDockPanel.Canvas, Control);
    103     end;
    104   end;
    105 end;
    106 
    107 procedure TCustomDockManager.DockPanelMouseDown(Sender: TObject;
    108   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    109 begin
    110   if (Button=mbLeft) and (FDockSite.DockClientCount > 0) then
    111     DragManager.DragStart(FDockSite.DockClients[0], False, 1);
    112 end;
    113 
    114 constructor TCustomDockManager.Create(ADockSite: TWinControl);
    115 begin
    116   FDockSite := ADockSite;
    117   FDockPanel := TPanel.Create(nil);
    118   with FDockPanel do begin
    119     Parent := ADockSite;
    120     Align := alClient;
    121     Visible := True;
    122     OnPaint := DockPanelPaint;
    123     OnMouseDown := DockPanelMouseDown();
    124     BevelInner := bvNone;
    125     BevelOuter := bvNone;
    126   end;
    127 
    128   CloseButton := TSpeedButton.Create(FDockPanel);
     258end;
     259
     260procedure TCustomDockManager.SaveToStream(Stream: TStream);
     261begin
     262end;
     263
     264procedure TCustomDockManager.SetReplacingControl(Control: TControl);
     265begin
     266  inherited SetReplacingControl(Control);
     267end;
     268
     269function TCustomDockManager.AutoFreeByControl: Boolean;
     270begin
     271  Result := inherited AutoFreeByControl;
     272end;
     273
     274{ TDockClientPanel }
     275
     276constructor TDockClientPanel.Create(TheOwner: TComponent);
     277begin
     278  inherited;
     279  CloseButton := TSpeedButton.Create(Self);
    129280  with CloseButton do begin
    130     Parent := FDockPanel;
     281    Parent := Self;
    131282    Caption := 'X';
    132283    Font.Size := 6;
     
    136287    OnClick := CloseButtonClick;
    137288  end;
    138   inherited Create(ADockSite);
    139 end;
    140 
    141 destructor TCustomDockManager.Destroy;
    142 begin
    143   FDockPanel.Free;
     289  OnPaint := DockPanelPaint;
     290  OnMouseDown := DockPanelMouseDown;
     291  OnResize := ResizeExecute;
     292  BevelInner := bvNone;
     293  BevelOuter := bvNone;
     294end;
     295
     296destructor TDockClientPanel.Destroy;
     297begin
    144298  inherited Destroy;
    145299end;
    146300
    147 procedure TCustomDockManager.BeginUpdate;
    148 begin
    149   inherited BeginUpdate;
    150 end;
    151 
    152 procedure TCustomDockManager.EndUpdate;
    153 begin
    154   inherited EndUpdate;
    155 end;
    156 
    157 procedure TCustomDockManager.GetControlBounds(Control: TControl; out
    158   AControlBounds: TRect);
    159 begin
    160 end;
    161 
    162 function TCustomDockManager.GetDockEdge(ADockObject: TDragDockObject): boolean;
    163 begin
    164   Result := inherited GetDockEdge(ADockObject);
    165 end;
    166 
    167 procedure TCustomDockManager.InsertControl(ADockObject: TDragDockObject);
    168 begin
    169   inherited InsertControl(ADockObject);
    170   FDockPanel.Repaint;
    171 end;
    172 
    173 procedure TCustomDockManager.InsertControl(Control: TControl; InsertAt: TAlign;
    174   DropCtl: TControl);
    175 begin
    176   inherited;
    177 end;
    178 
    179 procedure TCustomDockManager.LoadFromStream(Stream: TStream);
    180 begin
    181 end;
    182 
    183 procedure TCustomDockManager.PaintSite(DC: HDC);
    184 var
    185   Canvas: TControlCanvas;
    186   Control: TControl;
     301procedure TDockClientPanel.DrawGrabber(Canvas: TCanvas; AControl: TControl);
     302begin
     303  with Canvas do begin
     304    Brush.Color := clBtnFace;
     305    Pen.Color := clBlack;
     306    FillRect(0, 0, AControl.Width, GrabberSize);
     307
     308    if (AControl as TWinControl).Focused then
     309      Font.Style := Font.Style + [fsBold]
     310      else Font.Style := Font.Style - [fsBold];
     311    Rectangle(1, 1, AControl.Width - 1, GrabberSize - 1);
     312    TextOut(6, 2, AControl.Caption);
     313
     314    CloseButton.Left := AControl.Width - CloseButton.Width - 2;
     315    CloseButton.Top := 2;
     316  end;
     317end;
     318
     319procedure TDockClientPanel.CloseButtonClick(Sender: TObject);
     320begin
     321  Control.Hide;
     322end;
     323
     324procedure TDockClientPanel.ResizeExecute(Sender: TObject);
     325begin
     326  Control.Top := GrabberSize;
     327  Control.Left := 0;
     328  Control.Width := Width;
     329  Control.Height := Height - GrabberSize;
     330  //Control.SetBounds(0, GrabberSize, Width - Control.Left,
     331  //  Height - Control.Top);
     332end;
     333
     334procedure TDockClientPanel.DockPanelPaint(Sender: TObject);
     335var
    187336  I: Integer;
    188337  R: TRect;
    189338begin
    190   Canvas := TControlCanvas.Create;
    191   try
    192     //Canvas.Control := FDockSite;
    193     Canvas.Control := FDockPanel;
    194     Canvas.Lock;
    195     try
    196       Canvas.Handle := DC;
    197       try
    198         for I := 0 to FDockSite.ControlCount - 1 do
    199         begin
    200           Control := FDockSite.Controls[I];
    201           if Control.Visible and (Control.HostDockSite = FDockSite) then
    202           begin
    203             R := Control.BoundsRect;
    204             Control.SetBounds(0, GrabberSize, FDockSite.Width - Control.Left,
    205               FDockSite.Height - Control.Top);
    206             Canvas.FillRect(R);
    207             DrawGrabber(Canvas, Control);
    208           end;
    209         end;
    210       finally
    211         Canvas.Handle := 0;
    212       end;
    213     finally
    214       Canvas.Unlock;
    215     end;
    216   finally
    217     Canvas.Free;
    218   end;
    219   FDockPanel.Repaint;
    220 end;
    221 
    222 procedure TCustomDockManager.MessageHandler(Sender: TControl;
    223   var Message: TLMessage);
    224 begin
    225   inherited MessageHandler(Sender, Message);
    226 end;
    227 
    228 procedure TCustomDockManager.PositionDockRect(ADockObject: TDragDockObject);
    229 begin
    230   inherited PositionDockRect(ADockObject);
    231 end;
    232 
    233 procedure TCustomDockManager.PositionDockRect(Client, DropCtl: TControl;
    234   DropAlign: TAlign; var DockRect: TRect);
    235 begin
    236   DockRect := Rect(0, 0, FDockSite.ClientWidth, FDockSite.ClientHeight);
    237   DockRect.TopLeft := FDockSite.ClientToScreen(DockRect.TopLeft);
    238   DockRect.BottomRight := FDockSite.ClientToScreen(DockRect.BottomRight);
    239 end;
    240 
    241 procedure TCustomDockManager.RemoveControl(Control: TControl);
    242 begin
    243   inherited;
    244   //FDockPanel.Invalidate;
    245   FDockSite.Invalidate;
    246 end;
    247 
    248 procedure TCustomDockManager.ResetBounds(Force: Boolean);
    249 var
    250   I: Integer;
    251   Control: TControl;
    252   R: TRect;
    253 begin
    254   for I := 0 to FDockSite.ControlCount - 1 do
    255     begin
    256       Control := FDockSite.Controls[I];
    257       if Control.Visible and (Control.HostDockSite = FDockSite) then
    258       begin
    259         R := Control.BoundsRect;
    260         Control.SetBounds(0, GrabberSize, FDockSite.Width - Control.Left,
    261           FDockSite.Height - Control.Top);
    262       end;
    263     end;
    264 end;
    265 
    266 procedure TCustomDockManager.SaveToStream(Stream: TStream);
    267 begin
    268 end;
    269 
    270 procedure TCustomDockManager.SetReplacingControl(Control: TControl);
    271 begin
    272   inherited SetReplacingControl(Control);
    273 end;
    274 
    275 function TCustomDockManager.AutoFreeByControl: Boolean;
    276 begin
    277   Result := inherited AutoFreeByControl;
     339  R := Control.ClientRect;
     340  Canvas.FillRect(R);
     341  DrawGrabber(Canvas, Control);
     342end;
     343
     344procedure TDockClientPanel.DockPanelMouseDown(Sender: TObject;
     345  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
     346begin
     347  if (Button=mbLeft) then begin
     348    DragManager.DragStart(Control, False, 1);
     349  end;
    278350end;
    279351
Note: See TracChangeset for help on using the changeset viewer.