source: DockManagement/UDockManagement.pas

Last change on this file was 6, checked in by chronos, 12 years ago
  • Added: Some basic functionality for conjoined form support.
File size: 30.1 KB
Line 
1unit UDockManagement;
2
3interface
4
5uses
6 Forms, Classes, Types, Windows, Messages, SysUtils, Variants, Graphics,
7 Controls, Dialogs, Menus, StdCtrls, ExtCtrls, ComCtrls, XPMan, Grids,
8 FindFile, Math, Tabs, DockTabSet, ToolWin, ImgList, ActnList, URegistry,
9 Generics.Collections;
10
11const
12 RegistryRootKey = HKEY_CURRENT_USER;
13 UseConjoinForm: Boolean = True;
14 UseTabbedDock: Boolean = True;
15
16type
17 TDockFormInitState = class
18 DockSite: string;
19 Width: Integer;
20 Height: Integer;
21 Form: TForm;
22 Visible: Boolean;
23 end;
24
25 TDockPanelAction = (dpaUndock, dpaDock, dpaClose, dpaShow);
26
27 TDDockForm = class(TForm)
28 protected
29 procedure DoClose(var Action: TCloseAction); override;
30 procedure DoShow; override;
31 procedure DockDrop(Source: TDragDockObject; X, Y: Integer); override;
32 procedure DoDockOver(Source: TDragDockObject; X, Y: Integer;
33 State: TDragState; var Accept: Boolean); override;
34 public
35 constructor Create(AOwner: TComponent); override;
36 end;
37
38 TDDockPanel = class(TPanel)
39 procedure DoDockOver(Source: TDragDockObject; X, Y: Integer;
40 State: TDragState; var Accept: Boolean); override;
41 procedure DockDrop(Source: TDragDockObject; X, Y: Integer); override;
42 function DoUnDock(NewTarget: TWinControl; Client: TControl): Boolean; override;
43 end;
44
45 TDDockTabSet = class(TDockTabSet)
46 procedure DockDrop(Source: TDragDockObject; X, Y: Integer); override;
47 private
48 procedure TabRemoved(Sender: TObject);
49 property OnTabRemoved;
50 public
51 constructor Create(AOwner: TComponent); override;
52 end;
53
54 TDBaseDockPanel = class(TPanel)
55 PanelCenter: TDDockPanel;
56 PanelLeft: TDDockPanel;
57 PanelTop: TDDockPanel;
58 PanelRight: TDDockPanel;
59 PanelBottom: TDDockPanel;
60 DockTabSetLeft: TDDockTabSet;
61 DockTabSetTop: TDDockTabSet;
62 DockTabSetRight: TDDockTabSet;
63 DockTabSetBottom: TDDockTabSet;
64 SplitterLeft: TSplitter;
65 SplitterTop: TSplitter;
66 SplitterRight: TSplitter;
67 SplitterBottom: TSplitter;
68 public
69 DockPanelWidth: Integer;
70 procedure DockPanelCloseForm(Source: TForm; Panel: TPanel; Action: TDockPanelAction);
71 constructor Create(AOwner: TComponent); override;
72 end;
73
74 TDDockManager = class
75 BaseDockPanel: TDBaseDockPanel;
76 RegistryKey: string;
77 DockFormInitStateList: TObjectList<TDockFormInitState>;
78 Owner: TComponent;
79 procedure SaveToRegistry;
80 procedure LoadFromRegistry;
81 procedure RegisterDockForm(AForm: TForm; InitWidth, InitHeight: Integer; InitDockSite: string; InitVisible: Boolean);
82 constructor Create(AOwner: TComponent);
83 destructor Destroy; override;
84 end;
85
86 TDConjoinPanel = class(TDDockPanel)
87 protected
88 function DoUnDock(NewTarget: TWinControl; Client: TControl): Boolean; override;
89 end;
90
91 TDConjoinForm = class(TCustomForm)
92 Panel: TDConjoinPanel;
93 constructor Create(AOwner: TComponent); override;
94 constructor CreateNew(AOwner: TComponent; Dummy: Integer = 0); override;
95 end;
96
97 TDTabForm = class(TCustomForm)
98 Panel: TPanel;
99 TabSet: TDockTabSet;
100 constructor CreateNew(AOwner: TComponent; Dummy: Integer = 0); override;
101 end;
102
103
104implementation
105
106uses Registry;
107
108function GetDockRect(X, Y, Width, Height: Integer; Align: TAlign): TRect;
109const
110 Border = 0.1;
111 FrameWidth = 30;
112var
113 CenterRectagle: TRect;
114begin
115 CenterRectagle := Rect(Round(Width * Border), Round(Height * Border),
116 Width - Round(Width * Border), Height - Round(Height * Border));
117
118 if (Height > 0) and (Width > 0) then begin
119 if (X > CenterRectagle.Left) and (Y > CenterRectagle.Top) and
120 (X < CenterRectagle.Right) and (Y < CenterRectagle.Bottom) then begin
121 Result.TopLeft := CenterRectagle.TopLeft;
122 Result.BottomRight := CenterRectagle.BottomRight;
123 end else
124 if (X < CenterRectagle.Left) and (Round(Y * (Width / Height)) > X) and
125 (Round(Y * (Width / Height)) < (Width - X)) then begin
126 Result.TopLeft := Point(0, 0);
127 Result.BottomRight := Point(Width div 2, Height);
128 end else
129 if (Y < CenterRectagle.Top) and (Round(X * (Height / Width)) > Y) and
130 (Round(X * (Height / Width)) < (Height - Y)) then begin
131 Result.TopLeft := Point(0, 0);
132 Result.BottomRight := Point(Width, Height div 2);
133 end else
134 if (X > CenterRectagle.Right) and (Round(Y * (Width / Height)) > (Width - X)) and
135 (Round(Y * (Width / Height)) < X) then begin
136 Result.TopLeft := Point(Width div 2, 0);
137 Result.BottomRight := Point(Width, Height);
138 end else
139 if (Y > CenterRectagle.Bottom) and (Round(X * (Height / Width)) > (Height - Y)) and
140 (Round(X * (Height / Width)) < Y) then begin
141 Result.TopLeft := Point(0, Height div 2);
142 Result.BottomRight := Point(Width, Height);
143 end else
144 Accept := False;
145 end;
146
147 case Align of
148 alLeft: if Width < FrameWidth then begin
149 Result.TopLeft := Point(0, 0);
150 Result.BottomRight := Point(FrameWidth, Height);
151 end;
152 alTop: if Height < FrameWidth then begin
153 Result.TopLeft := Point(0, 0);
154 Result.BottomRight := Point(Width, FrameWidth);
155 end;
156 alRight: if Width < FrameWidth then begin
157 Result.TopLeft := Point(-FrameWidth, 0);
158 Result.BottomRight := Point(Width, Height);
159 end;
160 alBottom: if Height < FrameWidth then begin
161 Result.TopLeft := Point(0, -FrameWidth);
162 Result.BottomRight := Point(Width, Height);
163 end;
164 end;
165end;
166
167{ TDDockManager }
168
169procedure TDDockManager.RegisterDockForm(AForm: TForm; InitWidth, InitHeight: Integer; InitDockSite: string; InitVisible: Boolean);
170begin
171 with DockFormInitStateList[DockFormInitStateList.Add(TDockFormInitState.Create)] do begin
172 DockSite := InitDockSite;
173 Visible := InitVisible;
174 Width := InitWidth;
175 Height := InitHeight;
176 Form := AForm;
177 Owner.InsertComponent(Form);
178 end;
179end;
180
181procedure TDDockManager.SaveToRegistry;
182var
183 I: Integer;
184 DockData: TMemoryStream;
185 Buffer: array of Byte;
186begin
187 with TRegistryEx.Create do
188 try
189 RootKey := RegistryRootKey;
190 for I := 0 to DockFormInitStateList.Count - 1 do
191 with TDockFormInitState(DockFormInitStateList[I]).Form do begin
192 OpenKey(RegistryKey + '\Dock\' + Name, True);
193 WriteBool('Visible', Visible);
194 WriteInteger('LRDockWidth', LRDockWidth);
195 WriteInteger('TBDockHeight', TBDockHeight);
196 WriteInteger('UndockWidth', UndockWidth);
197 WriteInteger('UndockHeight', UndockHeight);
198 WriteInteger('Width', Width);
199 WriteInteger('Height', Height);
200 WriteInteger('Top', Top);
201 WriteInteger('Left', Left);
202 WriteInteger('Orientation', Integer(DockOrientation));
203 WriteBool('Docked', not Floating);
204 if not Floating then WriteString('TargetDockSite', HostDockSite.Name);
205 WriteInteger('Align', Integer(alLeft));
206 end;
207 OpenKey(RegistryKey + '\Dock', True);
208 if BaseDockPanel.PanelTop.Height = 0 then WriteInteger('PanelTopHeight', BaseDockPanel.PanelTop.Tag)
209 else WriteInteger('PanelTopHeight', BaseDockPanel.PanelTop.Height);
210 if BaseDockPanel.PanelLeft.Width = 0 then WriteInteger('PanelLeftWidth', BaseDockPanel.PanelLeft.Tag)
211 else WriteInteger('PanelLeftWidth', BaseDockPanel.PanelLeft.Width);
212 if BaseDockPanel.PanelRight.Width = 0 then WriteInteger('PanelRightWidth', BaseDockPanel.PanelRight.Tag)
213 else WriteInteger('PanelRightWidth', BaseDockPanel.PanelRight.Width);
214 if BaseDockPanel.PanelBottom.Height = 0 then WriteInteger('PanelBottomHeight', BaseDockPanel.PanelBottom.Tag)
215 else WriteInteger('PanelBottomHeight', BaseDockPanel.PanelBottom.Height);
216
217 with BaseDockPanel do begin
218 DockData := TMemoryStream.Create;
219 PanelTop.DockManager.SaveToStream(DockData);
220 SetLength(Buffer, DockData.Size);
221 DockData.Position := 0;
222 DockData.Read(Buffer[0], Length(Buffer));
223 WriteBinaryData('PanelTopDockZone', Buffer[0], Length(Buffer));
224
225 DockData.Clear;
226 PanelLeft.DockManager.SaveToStream(DockData);
227 SetLength(Buffer, DockData.Size);
228 DockData.Position := 0;
229 DockData.Read(Buffer[0], Length(Buffer));
230 WriteBinaryData('PanelLeftDockZone', Buffer[0], Length(Buffer));
231
232 DockData.Clear;
233 Panelright.DockManager.SaveToStream(DockData);
234 SetLength(Buffer, DockData.Size);
235 DockData.Position := 0;
236 DockData.Read(Buffer[0], Length(Buffer));
237 WriteBinaryData('PanelRightDockZone', Buffer[0], Length(Buffer));
238
239 DockData.Clear;
240 PanelBottom.DockManager.SaveToStream(DockData);
241 SetLength(Buffer, DockData.Size);
242 DockData.Position := 0;
243 DockData.Read(Buffer[0], Length(Buffer));
244 WriteBinaryData('PanelBottomDockZone', Buffer[0], Length(Buffer));
245
246 DockData.Clear;
247 PanelCenter.DockManager.SaveToStream(DockData);
248 SetLength(Buffer, DockData.Size);
249 DockData.Position := 0;
250 DockData.Read(Buffer[0], Length(Buffer));
251 WriteBinaryData('PanelCenterDockZone', Buffer[0], Length(Buffer));
252
253 DockData.Free;
254 end;
255 finally
256 Free;
257 end;
258end;
259
260constructor TDDockManager.Create(AOwner: TComponent);
261begin
262 DockFormInitStateList := TObjectList<TDockFormInitState>.Create;
263 Owner := AOwner;
264end;
265
266destructor TDDockManager.Destroy;
267var
268 I: Integer;
269begin
270 inherited;
271 DockFormInitStateList.Free;
272end;
273
274procedure TDDockManager.LoadFromRegistry;
275const
276 ReadBufferSize = 100000;
277var
278 I: Integer;
279 DockData: TMemoryStream;
280 Buffer: array of Byte;
281begin
282 with TRegistryEx.Create do
283 try
284 RootKey := RegistryRootKey;
285 OpenKey(RegistryKey + '\Dock', True);
286
287 with BaseDockPanel do begin
288 PanelTop.Tag := ReadIntegerWithDefault('PanelTopHeight', PanelTop.Tag);
289 if PanelTop.Tag > Height then PanelTop.Tag := Height div 2;
290 if PanelTop.Tag = 0 then PanelTop.Tag := 10;
291
292 PanelLeft.Tag := ReadIntegerWithDefault('PanelLeftWidth', PanelLeft.Tag);
293 if PanelLeft.Tag > Width then PanelLeft.Tag := Width div 2;
294 if PanelLeft.Tag = 0 then PanelLeft.Tag := 10;
295
296 PanelRight.Tag := ReadIntegerWithDefault('PanelRightWidth', PanelRight.Tag);
297 if PanelRight.Tag > Width then PanelRight.Tag := Width div 2;
298 if PanelRight.Tag = 0 then PanelRight.Tag := 10;
299
300 PanelBottom.Tag := ReadIntegerWithDefault('PanelBottomHeight', PanelBottom.Tag);
301 if PanelBottom.Tag > Height then PanelBottom.Tag := Height div 2;
302 if PanelBottom.Tag = 0 then PanelBottom.Tag := 10;
303 end;
304
305 for I := 0 to DockFormInitStateList.Count - 1 do
306 with TDockFormInitState(DockFormInitStateList[I]) do begin
307 OpenKey(RegistryKey + '\Dock\' + Form.Name, True);
308 Form.DockOrientation := TDockOrientation(ReadIntegerWithDefault('Orientation', 0));
309 Form.TBDockHeight := ReadIntegerWithDefault('TBDockHeight', Height);
310 Form.LRDockWidth := ReadIntegerWithDefault('LRDockWidth', Width);
311 Form.UndockHeight := ReadIntegerWithDefault('UndockHeight', Height);
312 Form.UndockWidth := ReadIntegerWithDefault('UndockWidth', Width);
313 Form.Width := ReadIntegerWithDefault('Width', Width);
314 Form.Height := ReadIntegerWithDefault('Height', Height);
315 Form.Top := ReadIntegerWithDefault('Top', (Screen.Width - Width) div 2);
316 Form.Left := ReadIntegerWithDefault('Left', (Screen.Width - Width) div 2);
317 if ReadBoolWithDefault('Docked', True) then begin
318 if ReadStringWithDefault('TargetDockSite', DockSite) = 'DockTabSetLeft' then begin
319 Visible := True;
320 Form.Visible := True;
321 BaseDockPanel.DockTabSetLeft.Visible := True;
322 Form.ManualDock(BaseDockPanel.DockTabSetLeft, Form, TAlign(ReadIntegerWithDefault('Align', 0)));
323 end;
324 if ReadStringWithDefault('TargetDockSite', DockSite) = 'DockTabSetTop' then begin
325 Visible := True;
326 Form.Visible := True;
327 BaseDockPanel.DockTabSetTop.Visible := True;
328 Form.ManualDock(BaseDockPanel.DockTabSetTop, Form, TAlign(ReadIntegerWithDefault('Align', 0)));
329 end;
330 if ReadStringWithDefault('TargetDockSite', DockSite) = 'DockTabSetRight' then begin
331 Visible := True;
332 Form.Visible := True;
333 BaseDockPanel.DockTabSetRight.Visible := True;
334 Form.ManualDock(BaseDockPanel.DockTabSetRight, Form, TAlign(ReadIntegerWithDefault('Align', 0)));
335 end;
336 if ReadStringWithDefault('TargetDockSite', DockSite) = 'DockTabSetBottom' then begin
337 Visible := True;
338 Form.Visible := True;
339 BaseDockPanel.DockTabSetBottom.Visible := True;
340 Form.ManualDock(BaseDockPanel.DockTabSetBottom, Form, TAlign(ReadIntegerWithDefault('Align', 0)));
341 end;
342 if ReadStringWithDefault('TargetDockSite', DockSite) = 'PanelTop' then begin
343 OpenKey(RegistryKey + '\Dock', True);
344 if not ValueExists('PanelTopDockZone') then Form.ManualDock(BaseDockPanel.PanelTop, Form, TAlign(ReadIntegerWithDefault('Align', 0)));
345 OpenKey(RegistryKey + '\Dock\' + Form.Name, True);
346 Form.Visible := ReadBoolWithDefault('Visible', Visible);
347 end;
348 if ReadStringWithDefault('TargetDockSite', DockSite) = 'PanelLeft' then begin
349 OpenKey(RegistryKey + '\Dock', True);
350 if not ValueExists('PanelLeftDockZone') then Form.ManualDock(BaseDockPanel.PanelLeft, Form, TAlign(ReadIntegerWithDefault('Align', 0)));
351 OpenKey(RegistryKey + '\Dock\' + Form.Name, True);
352 Form.Visible := ReadBoolWithDefault('Visible', Visible);
353 end;
354 if ReadStringWithDefault('TargetDockSite', DockSite) = 'PanelRight' then begin
355 OpenKey(RegistryKey + '\Dock', True);
356 if not ValueExists('PanelRightDockZone') then Form.ManualDock(BaseDockPanel.PanelRight, Form, TAlign(ReadIntegerWithDefault('Align', 0)));
357 OpenKey(RegistryKey + '\Dock\' + Form.Name, True);
358 Form.Visible := ReadBoolWithDefault('Visible', Visible);
359 end;
360 if ReadStringWithDefault('TargetDockSite', DockSite) = 'PanelBottom' then begin
361 OpenKey(RegistryKey + '\Dock', True);
362 if not ValueExists('PanelBottomDockZone') then Form.ManualDock(BaseDockPanel.PanelBottom, Form, TAlign(ReadIntegerWithDefault('Align', 0)));
363 OpenKey(RegistryKey + '\Dock\' + Form.Name, True);
364 Form.Visible := ReadBoolWithDefault('Visible', Visible);
365 end;
366 if ReadStringWithDefault('TargetDockSite', DockSite) = 'PanelCenter' then begin
367 OpenKey(RegistryKey + '\Dock', True);
368 if not ValueExists('PanelCenterDockZone') then Form.ManualDock(BaseDockPanel.PanelCenter, Form, TAlign(ReadIntegerWithDefault('Align', 0)));
369 OpenKey(RegistryKey + '\Dock\' + Form.Name, True);
370 Form.Visible := ReadBoolWithDefault('Visible', Visible);
371 end;
372 end;
373 end;
374
375 OpenKey(RegistryKey + '\Dock', True);
376 with BaseDockPanel do begin
377 DockData := TMemoryStream.Create;
378 if ValueExists('PanelTopDockZone') then begin
379 SetLength(Buffer, GetDataSize('PanelTopDockZone'));
380 if Length(Buffer) > 0 then begin
381 SetLength(Buffer, ReadBinaryData('PanelTopDockZone', Buffer[0], Length(Buffer)));
382 DockData.Clear;
383 DockData.Write(Buffer[0], Length(Buffer));
384 DockData.Position := 0;
385 PanelTop.DockManager.LoadFromStream(DockData);
386 end;
387 end;
388 if ValueExists('PanelLeftDockZone') then begin
389 SetLength(Buffer, GetDataSize('PanelLeftDockZone'));
390 if Length(Buffer) > 0 then begin
391 SetLength(Buffer, ReadBinaryData('PanelLeftDockZone', Buffer[0], Length(Buffer)));
392 DockData.Clear;
393 DockData.Write(Buffer[0], Length(Buffer));
394 DockData.Position := 0;
395 PanelLeft.DockManager.LoadFromStream(DockData);
396 end;
397 end;
398 if ValueExists('PanelRightDockZone') then begin
399 SetLength(Buffer, GetDataSize('PanelRightDockZone'));
400 if Length(Buffer) > 0 then begin
401 SetLength(Buffer, ReadBinaryData('PanelRightDockZone', Buffer[0], Length(Buffer)));
402 DockData.Clear;
403 DockData.Write(Buffer[0], Length(Buffer));
404 DockData.Position := 0;
405 PanelRight.DockManager.LoadFromStream(DockData);
406 end;
407 end;
408 if ValueExists('PanelBottomDockZone') then begin
409 SetLength(Buffer, GetDataSize('PanelBottomDockZone'));
410 if Length(Buffer) > 0 then begin
411 SetLength(Buffer, ReadBinaryData('PanelBottomDockZone', Buffer[0], Length(Buffer)));
412 DockData.Clear;
413 DockData.Write(Buffer[0], Length(Buffer));
414 DockData.Position := 0;
415 PanelBottom.DockManager.LoadFromStream(DockData);
416 end;
417 end;
418 if ValueExists('PanelCenterDockZone') then begin
419 SetLength(Buffer, GetDataSize('PanelCenterDockZone'));
420 if Length(Buffer) > 0 then begin
421 SetLength(Buffer, ReadBinaryData('PanelCenterDockZone', Buffer[0], Length(Buffer)));
422 DockData.Clear;
423 DockData.Write(Buffer[0], Length(Buffer));
424 DockData.Position := 0;
425 PanelCenter.DockManager.LoadFromStream(DockData);
426 end;
427 end;
428 DockData.Free;
429 end;
430
431 finally
432 Free;
433 end;
434end;
435
436
437{ TDDockForm }
438
439constructor TDDockForm.Create(AOwner: TComponent);
440begin
441 inherited;
442 if UseConjoinForm then begin
443 DockSite := True;
444 UseDockManager := True;
445 end;
446 DragKind := dkDock;
447 DragMode := dmAutomatic;
448end;
449
450procedure TDBaseDockPanel.DockPanelCloseForm(Source: TForm; Panel: TPanel;
451 Action: TDockPanelAction);
452var
453 I: Integer;
454 VisibleDockClientCount: Integer;
455begin
456 if not Assigned(Panel) then Exit;
457
458 VisibleDockClientCount := 0;
459 for I := 0 to Panel.DockClientCount - 1 do
460 if Panel.DockClients[I].Visible then Inc(VisibleDockClientCount);
461
462 if ((Action = dpaClose) and (VisibleDockClientCount = 0)) or
463 ((Action = dpaUndock) and (VisibleDockClientCount = 1)) then
464 begin
465 if Panel = PanelLeft then begin
466 PanelLeft.Tag := PanelLeft.Width;
467 PanelLeft.Width := DockPanelWidth;
468 SplitterLeft.Visible := False;
469 end else
470 if Panel = PanelRight then begin
471 PanelRight.Tag := PanelRight.Width;
472 PanelRight.Width := DockPanelWidth;
473 SplitterRight.Visible := False;
474 end;
475 if Panel = PanelTop then begin
476 PanelTop.Tag := PanelTop.Height;
477 PanelTop.Height := DockPanelWidth;
478 SplitterTop.Visible := False;
479 end;
480 if Panel = PanelBottom then begin
481 PanelBottom.Tag := PanelBottom.Height;
482 PanelBottom.Height := DockPanelWidth;
483 SplitterBottom.Visible := False;
484 end;
485 end else
486 if Assigned(Source) then begin
487 if Panel = PanelLeft then begin
488 if PanelLeft.Width <= DockPanelWidth then
489 PanelLeft.Width := PanelLeft.Tag;
490 SplitterLeft.Visible := True;
491 SplitterLeft.Left := 0;
492 PanelLeft.Left := 0;
493 DockTabSetLeft.Left := 0;
494 end else
495 if Panel = PanelRight then begin
496 if PanelRight.Width <= DockPanelWidth then begin
497 PanelRight.Width := PanelRight.Tag;
498 PanelRight.Left := Width - PanelRight.Width;
499 end;
500 SplitterRight.Visible := True;
501 SplitterRight.Left := Width;
502 PanelRight.Left := Width;
503 DockTabSetRight.Left := Width;
504 end else
505 if Panel = PanelTop then begin
506 if PanelTop.Height <= DockPanelWidth then
507 PanelTop.Height := PanelTop.Tag;
508 SplitterTop.Visible := True;
509 SplitterTop.Top := 0;
510 PanelTop.Top := 0;
511 DockTabSetTop.Top := 0;
512 end;
513 if Panel = PanelBottom then begin
514 if PanelBottom.Height <= DockPanelWidth then
515 PanelBottom.Height := PanelBottom.Tag;
516 SplitterBottom.Visible := True;
517 SplitterBottom.Top := Height;
518 PanelBottom.Top := Height;
519 DockTabSetBottom.Top := Height;
520 end;
521 end;
522end;
523
524procedure TDDockForm.DockDrop(Source: TDragDockObject; X, Y: Integer);
525var
526 NewConjoin: TDConjoinForm;
527begin
528 inherited;
529 if not UseConjoinForm then Exit;
530 NewConjoin := TDConjoinForm.CreateNew(nil);
531 NewConjoin.Show;
532 NewConjoin.Caption := 'Conjoin';
533 Source.Control.ManualDock(NewConjoin.Panel, nil, alTop);
534 Self.ManualDock(NewConjoin.Panel, nil, alTop);
535// if Parent is TDBaseDockPanel then
536// with TDBaseDockPanel(Parent) do
537// DockPanelCloseForm(nil, Self, dpaDock);
538end;
539
540procedure TDDockForm.DoClose(var Action: TCloseAction);
541begin
542 inherited;
543 if Parent is TDDockPanel then
544 with TDDockPanel(Parent) do
545 if Parent is TDBaseDockPanel then
546 with TDBaseDockPanel(Parent) do
547 DockPanelCloseForm(Self, TDDockPanel(Self.Parent), dpaClose);
548end;
549
550procedure TDDockForm.DoDockOver(Source: TDragDockObject; X, Y: Integer;
551 State: TDragState; var Accept: Boolean);
552const
553 Border = 0.1;
554 FrameWidth = 30;
555var
556 DockRectangle: TRect;
557 CenterRectagle: TRect;
558begin
559 inherited;
560 if not UseConjoinForm then Exit;
561 Accept := Source.Control is TDDockForm;
562 if Accept then
563 begin
564 CenterRectagle := Rect(Round(Width * Border), Round(Height * Border),
565 Width - Round(Width * Border), Height - Round(Height * Border));
566
567 if (Height > 0) and (Width > 0) then begin
568 if (X > CenterRectagle.Left) and (Y > CenterRectagle.Top) and
569 (X < CenterRectagle.Right) and (Y < CenterRectagle.Bottom) then begin
570 DockRectangle.TopLeft := ClientToScreen(CenterRectagle.TopLeft);
571 DockRectangle.BottomRight := ClientToScreen(CenterRectagle.BottomRight);
572 end else
573 if (X < CenterRectagle.Left) and (Round(Y * (Width / Height)) > X) and
574 (Round(Y * (Width / Height)) < (Width - X)) then begin
575 DockRectangle.TopLeft := ClientToScreen(Point(0, 0));
576 DockRectangle.BottomRight := ClientToScreen(Point(Width div 2, Height));
577 end else
578 if (Y < CenterRectagle.Top) and (Round(X * (Height / Width)) > Y) and
579 (Round(X * (Height / Width)) < (Height - Y)) then begin
580 DockRectangle.TopLeft := ClientToScreen(Point(0, 0));
581 DockRectangle.BottomRight := ClientToScreen(Point(Width, Height div 2));
582 end else
583 if (X > CenterRectagle.Right) and (Round(Y * (Width / Height)) > (Width - X)) and
584 (Round(Y * (Width / Height)) < X) then begin
585 DockRectangle.TopLeft := ClientToScreen(Point(Width div 2, 0));
586 DockRectangle.BottomRight := ClientToScreen(Point(Width, Height));
587 end else
588 if (Y > CenterRectagle.Bottom) and (Round(X * (Height / Width)) > (Height - Y)) and
589 (Round(X * (Height / Width)) < Y) then begin
590 DockRectangle.TopLeft := ClientToScreen(Point(0, Height div 2));
591 DockRectangle.BottomRight := ClientToScreen(Point(Width, Height));
592 end else
593 Accept := False;
594 end;
595
596 case Align of
597 alLeft: if Width < FrameWidth then begin
598 DockRectangle.TopLeft := ClientToScreen(Point(0, 0));
599 DockRectangle.BottomRight := ClientToScreen(Point(FrameWidth, Height));
600 end;
601 alTop: if Height < FrameWidth then begin
602 DockRectangle.TopLeft := ClientToScreen(Point(0, 0));
603 DockRectangle.BottomRight := ClientToScreen(Point(Width, FrameWidth));
604 end;
605 alRight: if Width < FrameWidth then begin
606 DockRectangle.TopLeft := ClientToScreen(Point(-FrameWidth, 0));
607 DockRectangle.BottomRight := ClientToScreen(Point(Width, Height));
608 end;
609 alBottom: if Height < FrameWidth then begin
610 DockRectangle.TopLeft := ClientToScreen(Point(0, -FrameWidth));
611 DockRectangle.BottomRight := ClientToScreen(Point(Width, Height));
612 end;
613 end;
614 Source.DockRect := DockRectangle;
615 end;
616end;
617
618procedure TDDockForm.DoShow;
619begin
620 inherited;
621 if Parent is TDDockPanel then
622 with TDDockPanel(Parent) do
623 if Parent is TDBaseDockPanel then
624 with TDBaseDockPanel(Parent) do
625 DockPanelCloseForm(Self, TDDockPanel(Self.Parent), dpaShow);
626end;
627
628procedure TDDockPanel.DockDrop(Source: TDragDockObject; X, Y: Integer);
629begin
630 inherited;
631 if Parent is TDBaseDockPanel then
632 with TDBaseDockPanel(Parent) do
633 DockPanelCloseForm(nil, Self, dpaDock);
634end;
635
636procedure TDDockPanel.DoDockOver(Source: TDragDockObject; X, Y: Integer;
637 State: TDragState; var Accept: Boolean);
638begin
639 inherited;
640 Accept := Source.Control is TDDockForm;
641 if Accept then
642 begin
643 Source.DockRect := GetDockRect(X, Y, Width, Height);
644 Source.DockRect.TopLeft := ClientToScreen(Source.DockRect.TopLeft);
645 Source.DockRect.BottomRight := ClientToScreen(Source.DockRect.BottomRight);
646 end;
647end;
648
649function TDDockPanel.DoUnDock(NewTarget: TWinControl;
650 Client: TControl): Boolean;
651begin
652 Result := inherited DoUnDock(NewTarget, Client);
653 if Parent is TDBaseDockPanel then
654 with TDBaseDockPanel(Parent) do
655 DockPanelCloseForm(nil, Self, dpaUnDock);
656end;
657
658{ TDDockTabSet }
659
660constructor TDDockTabSet.Create(AOwner: TComponent);
661begin
662 inherited;
663 OnTabRemoved := TabRemoved;
664end;
665
666procedure TDDockTabSet.DockDrop(Source: TDragDockObject; X, Y: Integer);
667begin
668 inherited;
669 Visible := True;
670end;
671
672procedure TDDockTabSet.TabRemoved(Sender: TObject);
673begin
674 inherited;
675 Visible := Tabs.Count > 0;
676end;
677
678{ TDBaseDockPanel }
679
680constructor TDBaseDockPanel.Create(AOwner: TComponent);
681begin
682 inherited;
683
684 PanelCenter := TDDockPanel.Create(Owner);
685 with PanelCenter do begin
686 Align := alClient;
687 AutoSize := True;
688 DockSite := True;
689 Parent := Self;
690 Name := 'PanelCenter';
691 Caption := '';
692 end;
693
694 PanelLeft := TDDockPanel.Create(Owner);
695 with PanelLeft do begin
696 DockSite := True;
697 Align := alLeft;
698 Parent := Self;
699 Name := 'PanelLeft';
700 Caption := '';
701 Width := 0;
702 end;
703 DockTabSetLeft := TDDockTabSet.Create(Owner);
704 with DockTabSetLeft do begin
705 Align := alLeft;
706 Style := tsModernTabs;
707 TabPosition := tpLeft;
708 DestinationDockSite := PanelLeft;
709 Visible := False;
710 DockSite := False;
711 ShrinkToFit := True;
712 Parent := Self;
713 Name := 'DockTabSetLeft';
714 Caption := '';
715 Width := 24;
716 end;
717 PanelLeft.Left := DockTabSetLeft.Width;
718 SplitterLeft := TSplitter.Create(Owner);
719 with SplitterLeft do begin
720 Align := alLeft;
721 Parent := Self;
722 Name := 'SplitterLeft';
723 Visible := False;
724 end;
725
726 PanelRight := TDDockPanel.Create(Owner);
727 with PanelRight do begin
728 DockSite := True;
729 Align := alRight;
730 Parent := Self;
731 Name := 'PanelRight';
732 Caption := '';
733 Width := 0;
734 end;
735 DockTabSetRight := TDDockTabSet.Create(Owner);
736 with DockTabSetRight do begin
737 Align := alRight;
738 Style := tsModernTabs;
739 TabPosition := tpRight;
740 DestinationDockSite := PanelRight;
741 Visible := False;
742 DockSite := False;
743 ShrinkToFit := True;
744 Parent := Self;
745 Name := 'DockTabSetRight';
746 Caption := '';
747 Width := 24;
748 end;
749 SplitterRight := TSplitter.Create(Owner);
750 with SplitterRight do begin
751 Align := alRight;
752 Parent := Self;
753 Visible := False;
754 Name := 'SplitterRight';
755 end;
756
757 PanelTop := TDDockPanel.Create(Owner);
758 with PanelTop do begin
759 DockSite := True;
760 Align := alTop;
761 Parent := Self;
762 Name := 'PanelTop';
763 Caption := '';
764 Height := 0;
765 end;
766 DockTabSetTop := TDDockTabSet.Create(Owner);
767 with DockTabSetTop do begin
768 Align := alTop;
769 Style := tsModernTabs;
770 TabPosition := tpTop;
771 DestinationDockSite := PanelTop;
772 Visible := False;
773 DockSite := False;
774 ShrinkToFit := True;
775 Parent := Self;
776 Name := 'DockTabSetTop';
777 Caption := '';
778 Height := 24;
779 end;
780 PanelTop.Top := DockTabSetTop.Height;
781 SplitterTop := TSplitter.Create(Owner);
782 with SplitterTop do begin
783 Align := alTop;
784 Parent := Self;
785 Name := 'SplitterTop';
786 Visible := False;
787 end;
788
789 PanelBottom := TDDockPanel.Create(Owner);
790 with PanelBottom do begin
791 DockSite := True;
792 Parent := Self;
793 Name := 'PanelBottom';
794 Caption := '';
795 Height := 0;
796 Align := alBottom;
797 end;
798 DockTabSetBottom := TDDockTabSet.Create(Owner);
799 with DockTabSetBottom do begin
800 Style := tsModernTabs;
801 TabPosition := tpBottom;
802 DestinationDockSite := PanelBottom;
803 Visible := False;
804 DockSite := False;
805 ShrinkToFit := True;
806 Parent := Self;
807 Name := 'DockTabSetBottom';
808 Caption := '';
809 Align := alBottom;
810 Height := 24;
811 end;
812 SplitterBottom := TSplitter.Create(Owner);
813 with SplitterBottom do begin
814 Name := 'SplitterBottom';
815 Parent := Self;
816 Visible := False;
817 Align := alBottom;
818 end;
819end;
820
821{ TDConjoinForm }
822
823constructor TDConjoinForm.Create(AOwner: TComponent);
824begin
825 inherited;
826end;
827
828constructor TDConjoinForm.CreateNew(AOwner: TComponent; Dummy: Integer);
829begin
830 inherited;
831 Panel := TDConjoinPanel.Create(Self);
832 Panel.Align := alClient;
833 Panel.BevelOuter := bvNone;
834 Panel.BevelInner := bvNone;
835 Panel.Caption := '';
836 Panel.Parent := Self;
837 Panel.Visible := True;
838 Panel.DockSite := True;
839 Panel.UseDockManager := True;
840 //Panel.DragKind := dkDock;
841 //Panel.DragMode := dmAutomatic;
842 DragMode := dmAutomatic;
843 DragKind := dkDock;
844end;
845
846{ TDConjoinPanel }
847
848function TDConjoinPanel.DoUnDock(NewTarget: TWinControl;
849 Client: TControl): Boolean;
850var
851 VisibleDockClientCount: Integer;
852 I: Integer;
853begin
854 inherited;
855
856 VisibleDockClientCount := 0;
857 for I := 0 to DockClientCount - 1 do
858 if DockClients[I].Visible then Inc(VisibleDockClientCount);
859
860 if VisibleDockClientCount <= 2 then begin
861 Parent.Free;
862 end;
863end;
864
865{ TDTabForm }
866
867constructor TDTabForm.CreateNew(AOwner: TComponent; Dummy: Integer);
868begin
869 inherited;
870 Panel := TDConjoinPanel.Create(Self);
871 Panel.Align := alClient;
872 Panel.BevelOuter := bvNone;
873 Panel.BevelInner := bvNone;
874 Panel.Caption := '';
875 Panel.Parent := Self;
876 Panel.Visible := True;
877 Panel.DockSite := True;
878 Panel.UseDockManager := True;
879 //Panel.DragKind := dkDock;
880 //Panel.DragMode := dmAutomatic;
881 DragMode := dmAutomatic;
882 DragKind := dkDock;
883 TabSet := TDockTabSet.Create(Self);
884 TabSet.Parent := Self;
885 TabSet.Align := alBottom;
886 TabSet.Visible := True;
887end;
888
889end.
Note: See TracBrowser for help on using the repository browser.