/MyPanel/MyPanel/DockPanel.cs

# · C# · 2492 lines · 2100 code · 344 blank · 48 comment · 514 complexity · 4088d2ca0cda05e1884e4ea464a167cb MD5 · raw file

Large files are truncated click here to view the full file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Drawing;
  5. using System.Data;
  6. using System.Text;
  7. using System.Windows.Forms;
  8. using System.Drawing.Drawing2D;
  9. using System.Drawing.Text;
  10. namespace Guoyongrong.WinFormsUI.Docking
  11. {
  12. public partial class DockPanel : Panel, IDockDragProcessor, ISplitterDragProcessor
  13. {
  14. #region Propery
  15. public DockContent[] DocumentsToArray()
  16. {
  17. int count = DocumentsCount;
  18. DockContent[] documents = new DockContent[count];
  19. int i = 0;
  20. foreach (DockContent content in Documents)
  21. {
  22. documents[i] = content;
  23. i++;
  24. }
  25. return documents;
  26. }
  27. public IEnumerable<DockContent> Documents
  28. {
  29. get
  30. {
  31. foreach (DockContent content in DockContents)
  32. {
  33. if (content.DockState == DockState.Document)
  34. yield return content;
  35. }
  36. }
  37. }
  38. public int DocumentsCount
  39. {
  40. get
  41. {
  42. int count = 0;
  43. foreach (DockContent content in Documents)
  44. count++;
  45. return count;
  46. }
  47. }
  48. private DockPage m_ActivePage = null;
  49. [Browsable(false)]
  50. public DockPage ActivePage
  51. {
  52. get { return m_ActivePage; }
  53. set
  54. {
  55. if (m_ActivePage == value || value == null || value.DockState == DockState.Document)
  56. {
  57. return;
  58. }
  59. if (m_ActivePage != null)
  60. m_ActivePage.IsActivated = false;
  61. m_ActivePage = value;
  62. if (m_ActivePage != null)
  63. m_ActivePage.IsActivated = true;
  64. }
  65. }
  66. private DockContent m_ActiveDocument = null;
  67. [Browsable(false)]
  68. public DockContent ActiveDocument
  69. {
  70. get { return m_ActiveDocument; }
  71. set
  72. {
  73. if (m_ActiveDocument == value || value == null || value.DockState != DockState.Document)
  74. {
  75. return;
  76. }
  77. m_ActiveDocument = value;
  78. }
  79. }
  80. private DockPage m_ActiveDocumentPage = null;
  81. [Browsable(false)]
  82. public DockPage ActiveDocumentPage
  83. {
  84. get { return m_ActiveDocumentPage; }
  85. set
  86. {
  87. if (m_ActiveDocumentPage == value || value == null || value.DockState != DockState.Document)
  88. {
  89. return;
  90. }
  91. if (m_ActiveDocumentPage != null)
  92. m_ActiveDocumentPage.IsActivated = false;
  93. m_ActiveDocumentPage = value;
  94. if (m_ActiveDocumentPage != null)
  95. m_ActiveDocumentPage.IsActivated = true;
  96. }
  97. }
  98. #endregion
  99. #region Collections
  100. private DockPageCollection m_pages = new DockPageCollection();
  101. [Browsable(false)]
  102. internal DockPageCollection DockPages
  103. {
  104. get { return m_pages; }
  105. }
  106. private DockContentCollection m_contents = new DockContentCollection();
  107. [Browsable(false)]
  108. internal DockContentCollection DockContents
  109. {
  110. get { return m_contents; }
  111. }
  112. private FloatWindowCollection m_floatWindows;
  113. [Browsable(false)]
  114. internal FloatWindowCollection FloatWindows
  115. {
  116. get { return m_floatWindows; }
  117. }
  118. private DockWindowCollection m_dockWindows;
  119. [Browsable(false)]
  120. internal DockWindowCollection DockWindows
  121. {
  122. get
  123. {
  124. return m_dockWindows;
  125. }
  126. }
  127. #endregion
  128. #region ISplitterDragProcessor
  129. private SplitterDragHandler m_splitterDragHandler = null;
  130. private SplitterDragHandler GetSplitterDragHandler()
  131. {
  132. if (m_splitterDragHandler == null)
  133. m_splitterDragHandler = new SplitterDragHandler(this);
  134. return m_splitterDragHandler;
  135. }
  136. public void SplitterMove(IDragSource DragSource, Rectangle rectSplitter)
  137. {
  138. GetSplitterDragHandler().BeginDrag(DragSource, rectSplitter);
  139. }
  140. public void BeginDrag(IDragSource DragSource, Rectangle rectSplitter)
  141. {
  142. #region DockPageSplitter
  143. if (DragSource is DockPageSplitter) //DockPageSplitter
  144. {
  145. DockPageSplitter splitter = DragSource as DockPageSplitter;
  146. DockPage DockPane = splitter.DockPane;
  147. }
  148. #endregion
  149. #region SplitterBase
  150. else if (DragSource is SplitterBase) //SplitterBase
  151. {
  152. SplitterBase splitter = DragSource as SplitterBase;
  153. if (splitter.Parent is DockWindow) //DockWindow
  154. {
  155. DockWindow window = splitter.Parent as DockWindow;
  156. }
  157. else if (splitter.Parent is AutoHideWindow)//AutoHideWindow
  158. {
  159. AutoHideWindow window = splitter.Parent as AutoHideWindow;
  160. window.FlagDragging = true;
  161. }
  162. }
  163. #endregion
  164. }
  165. public void EndDrag(IDragSource DragSource)
  166. {
  167. #region DockPageSplitter
  168. if (DragSource is DockPageSplitter) //DockPageSplitter
  169. {
  170. DockPageSplitter splitter = DragSource as DockPageSplitter;
  171. DockPage DockPane = splitter.DockPane;
  172. }
  173. #endregion
  174. #region SplitterBase
  175. else if (DragSource is SplitterBase) //SplitterBase
  176. {
  177. SplitterBase splitter = DragSource as SplitterBase;
  178. if (splitter.Parent is DockWindow) //DockWindow
  179. {
  180. DockWindow window = splitter.Parent as DockWindow;
  181. }
  182. else if (splitter.Parent is AutoHideWindow)//AutoHideWindow
  183. {
  184. AutoHideWindow window = splitter.Parent as AutoHideWindow;
  185. window.FlagDragging = false;
  186. }
  187. }
  188. #endregion
  189. }
  190. public bool IsVertical(IDragSource DragSource)
  191. {
  192. #region DockPageSplitter
  193. if (DragSource is DockPageSplitter) //DockPageSplitter
  194. {
  195. DockPageSplitter splitter = DragSource as DockPageSplitter;
  196. DockPage DockPane = splitter.DockPane;
  197. NestedDockingStatus status = DockPane.NestedDockingStatus;
  198. return (status.DisplayingAlignment == DockAlignment.Left ||
  199. status.DisplayingAlignment == DockAlignment.Right);
  200. }
  201. #endregion
  202. #region DockWindow
  203. else if (DragSource is DockWindow) //DockWindow
  204. {
  205. DockWindow window = DragSource as DockWindow;
  206. return (window.DockState == DockState.DockLeft || window.DockState == DockState.DockRight);
  207. }
  208. #endregion
  209. #region AutoHideWindow
  210. else if (DragSource is AutoHideWindow)//AutoHideWindow
  211. {
  212. AutoHideWindow window = DragSource as AutoHideWindow;
  213. return (window.DockState == DockState.DockLeftAutoHide || window.DockState == DockState.DockRightAutoHide);
  214. }
  215. #endregion
  216. return false;
  217. }
  218. public Rectangle DragLimitBounds(IDragSource DragSource)
  219. {
  220. #region DockPageSplitter
  221. if (DragSource is DockPageSplitter) //DockPageSplitter
  222. {
  223. DockPageSplitter splitter = DragSource as DockPageSplitter;
  224. DockPage DockPane = splitter.DockPane;
  225. NestedDockingStatus status = DockPane.NestedDockingStatus;
  226. Rectangle rectLimit = splitter.Parent.RectangleToScreen(status.LogicalBounds);
  227. if (this.IsVertical(DragSource))
  228. {
  229. rectLimit.X += MeasurePane.MinSize;
  230. rectLimit.Width -= 2 * MeasurePane.MinSize;
  231. }
  232. else
  233. {
  234. rectLimit.Y += MeasurePane.MinSize;
  235. rectLimit.Height -= 2 * MeasurePane.MinSize;
  236. }
  237. return rectLimit;
  238. }
  239. #endregion
  240. #region DockWindow
  241. else if (DragSource is DockWindow) //DockWindow
  242. {
  243. DockWindow window = DragSource as DockWindow;
  244. Rectangle rectLimit = this.DockArea;
  245. Point location;
  246. if ((Control.ModifierKeys & Keys.Shift) == 0)
  247. location = window.Location;
  248. else
  249. location = this.DockArea.Location;
  250. if (this.IsVertical(DragSource))
  251. {
  252. rectLimit.X += MeasurePane.MinSize;
  253. rectLimit.Width -= 2 * MeasurePane.MinSize;
  254. rectLimit.Y = location.Y;
  255. if ((Control.ModifierKeys & Keys.Shift) == 0)
  256. rectLimit.Height = window.Height;
  257. }
  258. else
  259. {
  260. rectLimit.Y += MeasurePane.MinSize;
  261. rectLimit.Height -= 2 * MeasurePane.MinSize;
  262. rectLimit.X = location.X;
  263. if ((Control.ModifierKeys & Keys.Shift) == 0)
  264. rectLimit.Width = window.Width;
  265. }
  266. return this.RectangleToScreen(rectLimit);
  267. }
  268. #endregion
  269. #region AutoHideWindow
  270. else if (DragSource is AutoHideWindow)//AutoHideWindow
  271. {
  272. AutoHideWindow window = DragSource as AutoHideWindow;
  273. Rectangle rectLimit = this.DockArea;
  274. if (this.IsVertical(DragSource))
  275. {
  276. rectLimit.X += MeasurePane.MinSize;
  277. rectLimit.Width -= 2 * MeasurePane.MinSize;
  278. }
  279. else
  280. {
  281. rectLimit.Y += MeasurePane.MinSize;
  282. rectLimit.Height -= 2 * MeasurePane.MinSize;
  283. }
  284. return this.RectangleToScreen(rectLimit);
  285. }
  286. #endregion
  287. return Rectangle.Empty;
  288. }
  289. public void MoveSplitter(IDragSource DragSource, int offset)
  290. {
  291. #region DockPageSplitter
  292. if (DragSource is DockPageSplitter) //DockPageSplitter
  293. {
  294. DockPageSplitter splitter = DragSource as DockPageSplitter;
  295. DockPage DockPane = splitter.DockPane;
  296. NestedDockingStatus status = DockPane.NestedDockingStatus;
  297. double proportion = status.Proportion;
  298. if (status.LogicalBounds.Width <= 0 || status.LogicalBounds.Height <= 0)
  299. return;
  300. else if (status.DisplayingAlignment == DockAlignment.Left)
  301. proportion += ((double)offset) / (double)status.LogicalBounds.Width;
  302. else if (status.DisplayingAlignment == DockAlignment.Right)
  303. proportion -= ((double)offset) / (double)status.LogicalBounds.Width;
  304. else if (status.DisplayingAlignment == DockAlignment.Top)
  305. proportion += ((double)offset) / (double)status.LogicalBounds.Height;
  306. else
  307. proportion -= ((double)offset) / (double)status.LogicalBounds.Height;
  308. //DockPane.SetNestedDockingProportion(proportion);
  309. status.SetStatus(
  310. status.Container,
  311. status.PreviousPane,
  312. status.Alignment, proportion);
  313. if (DockPane.DockControl != null)
  314. ((Control)DockPane.DockControl).PerformLayout();
  315. }
  316. #endregion
  317. #region DockWindow
  318. else if (DragSource is DockWindow) //DockWindow
  319. {
  320. DockWindow window = DragSource as DockWindow;
  321. if ((Control.ModifierKeys & Keys.Shift) != 0)
  322. window.SendToBack();
  323. Rectangle rectDockArea = this.DockArea;
  324. if (window.DockState == DockState.DockLeft && rectDockArea.Width > 0)
  325. {
  326. if (this.DockLeftPortion > 1)
  327. this.DockLeftPortion = window.Width + offset;
  328. else
  329. this.DockLeftPortion += ((double)offset) / (double)rectDockArea.Width;
  330. }
  331. else if (window.DockState == DockState.DockRight && rectDockArea.Width > 0)
  332. {
  333. if (this.DockRightPortion > 1)
  334. this.DockRightPortion = window.Width - offset;
  335. else
  336. this.DockRightPortion -= ((double)offset) / (double)rectDockArea.Width;
  337. }
  338. else if (window.DockState == DockState.DockBottom && rectDockArea.Height > 0)
  339. {
  340. if (this.DockBottomPortion > 1)
  341. this.DockBottomPortion = window.Height - offset;
  342. else
  343. this.DockBottomPortion -= ((double)offset) / (double)rectDockArea.Height;
  344. }
  345. else if (window.DockState == DockState.DockTop && rectDockArea.Height > 0)
  346. {
  347. if (this.DockTopPortion > 1)
  348. this.DockTopPortion = window.Height + offset;
  349. else
  350. this.DockTopPortion += ((double)offset) / (double)rectDockArea.Height;
  351. }
  352. }
  353. #endregion
  354. #region AutoHideWindow
  355. else if (DragSource is AutoHideWindow)//AutoHideWindow
  356. {
  357. AutoHideWindow window = DragSource as AutoHideWindow;
  358. Rectangle rectDockArea = this.DockArea;
  359. DockContent content = window.ActiveContent;
  360. if (window.DockState == DockState.DockLeftAutoHide && rectDockArea.Width > 0)
  361. {
  362. if (content.AutoHidePortion < 1)
  363. content.AutoHidePortion += ((double)offset) / (double)rectDockArea.Width;
  364. else
  365. content.AutoHidePortion = Width + offset;
  366. }
  367. else if (window.DockState == DockState.DockRightAutoHide && rectDockArea.Width > 0)
  368. {
  369. if (content.AutoHidePortion < 1)
  370. content.AutoHidePortion -= ((double)offset) / (double)rectDockArea.Width;
  371. else
  372. content.AutoHidePortion = Width - offset;
  373. }
  374. else if (window.DockState == DockState.DockBottomAutoHide && rectDockArea.Height > 0)
  375. {
  376. if (content.AutoHidePortion < 1)
  377. content.AutoHidePortion -= ((double)offset) / (double)rectDockArea.Height;
  378. else
  379. content.AutoHidePortion = Height - offset;
  380. }
  381. else if (window.DockState == DockState.DockTopAutoHide && rectDockArea.Height > 0)
  382. {
  383. if (content.AutoHidePortion < 1)
  384. content.AutoHidePortion += ((double)offset) / (double)rectDockArea.Height;
  385. else
  386. content.AutoHidePortion = Height + offset;
  387. }
  388. }
  389. #endregion
  390. }
  391. #endregion
  392. #region IDockDragProcessor
  393. private bool IsDockStateValid(DockContent content, DockState dockState)
  394. {
  395. if (dockState == DockState.Document &&
  396. this.DocumentStyle == DocumentStyle.SystemMdi)
  397. return false;
  398. else
  399. return DockHelper.IsDockStateValid(dockState, content.DockAreas);
  400. }
  401. public bool IsDockStateValid(IDragSource DragSource, DockState dockState)
  402. {
  403. #region DockContent
  404. if (DragSource is DockContent) //DockContent
  405. {
  406. DockContent content = DragSource as DockContent;
  407. return IsDockStateValid(content, dockState);
  408. }
  409. #endregion
  410. #region DockPage
  411. else if (DragSource is DockPage) //DockPage
  412. {
  413. DockPage page = DragSource as DockPage;
  414. foreach (DockContent content in page.DockContents)
  415. if (!IsDockStateValid(content,dockState))
  416. return false;
  417. return true;
  418. }
  419. #endregion
  420. #region DockWindow
  421. else if (DragSource is DockWindow) //DockWindow
  422. {
  423. DockWindow window = DragSource as DockWindow;
  424. return true;
  425. }
  426. #endregion
  427. #region FloatWindow
  428. else if (DragSource is FloatWindow) // FloatWindow
  429. {
  430. FloatWindow window = DragSource as FloatWindow;
  431. foreach (DockPage pane in window.NestedPanes)
  432. foreach (DockContent content in pane.DockContents)
  433. if (!DockHelper.IsDockStateValid(dockState, content.DockAreas))
  434. return false;
  435. return true;
  436. }
  437. #endregion
  438. #region Other
  439. else
  440. {
  441. return false;
  442. }
  443. #endregion
  444. }
  445. public bool CanDockTo(IDragSource DragSource, DockPage pane)
  446. {
  447. #region DockContent
  448. if (DragSource is DockContent) //DockContent
  449. {
  450. DockContent content = DragSource as DockContent;
  451. if (!IsDockStateValid(DragSource, pane.DockState))
  452. return false;
  453. if (content.DockPage == pane && pane.DisplayingContents.Count == 1)
  454. return false;
  455. return true;
  456. }
  457. #endregion
  458. #region DockPage
  459. else if (DragSource is DockPage) //DockPage
  460. {
  461. DockPage page = DragSource as DockPage;
  462. if (!IsDockStateValid(DragSource,pane.DockState))
  463. return false;
  464. if (pane == page)
  465. return false;
  466. return true;
  467. }
  468. #endregion
  469. #region FloatWindow
  470. else if (DragSource is FloatWindow) // FloatWindow
  471. {
  472. FloatWindow window = DragSource as FloatWindow;
  473. if (!IsDockStateValid(DragSource,pane.DockState))
  474. return false;
  475. if (pane.DockControl == window)
  476. return false;
  477. return true;
  478. }
  479. #endregion
  480. return false;
  481. }
  482. public void TestDrop(IDragSource TestDropSource, IDragSource dragSource, DockOutlineBase dockOutline)
  483. {
  484. #region DockPage
  485. if (TestDropSource is DockPage) //DockPage
  486. {
  487. DockPage page = TestDropSource as DockPage;
  488. if (!this.CanDockTo(dragSource, page))
  489. return;
  490. Point ptMouse = Control.MousePosition;
  491. HitTestResult hitTestResult = page.GetHitTest(ptMouse);
  492. if (hitTestResult.HitArea == HitTestArea.Caption)
  493. dockOutline.Show(page, -1);
  494. else if (hitTestResult.HitArea == HitTestArea.TabStrip && hitTestResult.Index != -1)
  495. dockOutline.Show(page, hitTestResult.Index);
  496. }
  497. #endregion
  498. #region FloatWindow
  499. else if (TestDropSource is FloatWindow) // FloatWindow
  500. {
  501. FloatWindow window = TestDropSource as FloatWindow;
  502. if (window.VisibleNestedPanes.Count == 1)
  503. {
  504. DockPage pane = window.VisibleNestedPanes[0];
  505. if (!this.CanDockTo(dragSource,pane))
  506. return;
  507. Point ptMouse = Control.MousePosition;
  508. uint lParam = Win32Helper.MakeLong(ptMouse.X, ptMouse.Y);
  509. if (NativeMethods.SendMessage(Handle, (int)Win32.Msgs.WM_NCHITTEST, 0, lParam) == (uint)Win32.HitTest.HTCAPTION)
  510. dockOutline.Show(window.VisibleNestedPanes[0], -1);
  511. }
  512. }
  513. #endregion
  514. }
  515. public Rectangle BeginDrag(IDragSource DragSource, Point ptMouse)
  516. {
  517. #region DockContent
  518. if (DragSource is DockContent) //DockContent
  519. {
  520. DockContent content = DragSource as DockContent;
  521. Size size;
  522. DockPage floatPane = null;
  523. FloatWindow fw = this.FloatWindows.CreateOrGetFloatWindow();
  524. if (content.DockState == DockState.Float || floatPane == null || fw.NestedPanes.Count != 1)
  525. size = this.DefaultFloatWindowSize;
  526. else
  527. size = fw.Size;
  528. Point location;
  529. DockPage Pane = content.DockPage;
  530. Rectangle rectPane = Pane.ClientRectangle;
  531. if (content.DockState == DockState.Document)
  532. {
  533. if (this.DocumentTabStripLocation == DocumentTabStripLocation.Bottom)
  534. location = new Point(rectPane.Left, rectPane.Bottom - size.Height);
  535. else
  536. location = new Point(rectPane.Left, rectPane.Top);
  537. }
  538. else
  539. {
  540. location = new Point(rectPane.Left, rectPane.Bottom);
  541. location.Y -= size.Height;
  542. }
  543. location = Pane.PointToScreen(location);
  544. if (ptMouse.X > location.X + size.Width)
  545. location.X += ptMouse.X - (location.X + size.Width) + Measures.SplitterSize;
  546. return new Rectangle(location, size);
  547. }
  548. #endregion
  549. #region DockPage
  550. else if (DragSource is DockPage) //DockPage
  551. {
  552. DockPage page = DragSource as DockPage;
  553. Point location = PointToScreen(new Point(0, 0));
  554. Size size;
  555. DockPage floatPane = null;
  556. FloatWindow fw = this.FloatWindows.CreateOrGetFloatWindow();
  557. if (page.DockState == DockState.Float || floatPane == null || fw.NestedPanes.Count != 1)
  558. size = this.DefaultFloatWindowSize;
  559. else
  560. size = fw.Size;
  561. if (ptMouse.X > location.X + size.Width)
  562. location.X += ptMouse.X - (location.X + size.Width) + Measures.SplitterSize;
  563. return new Rectangle(location, size);
  564. }
  565. #endregion
  566. #region FloatWindow
  567. else if (DragSource is FloatWindow) // FloatWindow
  568. {
  569. FloatWindow window = DragSource as FloatWindow;
  570. return window.Bounds;
  571. }
  572. #endregion
  573. return Rectangle.Empty;
  574. }
  575. public void FloatAt(IDragSource DragSource, Rectangle floatWindowBounds)
  576. {
  577. #region DockContent FloatAt
  578. if (DragSource is DockContent)
  579. {
  580. DockContent dragContent = DragSource as DockContent;
  581. DockPage page = processShow(dragContent, DockState.Float, null, DockAlignment.Unknown, 0.5, -1, floatWindowBounds, true);
  582. }
  583. #endregion
  584. #region DockPage FloatAt
  585. else if (DragSource is DockPage)
  586. {
  587. DockPage dragPage = DragSource as DockPage;
  588. DockPage page = processShow(dragPage, DockState.Float, null, DockAlignment.Unknown, 0.5, -1, floatWindowBounds, true);
  589. }
  590. #endregion
  591. #region FloatWindow FloatAt
  592. else if (DragSource is FloatWindow)
  593. {
  594. FloatWindow dragFloatWindow = DragSource as FloatWindow;
  595. dragFloatWindow.Bounds = floatWindowBounds;
  596. }
  597. #endregion
  598. }
  599. private void doDock(DockContent dragContent, DockState stateTo, DockPage pane, DockStyle dockStyle, int contentIndex)
  600. {
  601. DockPage dragPage = dragContent.DockPage;
  602. //dragPage's DockContents more than 1
  603. if (dragPage.DockContents.Count < 1)
  604. {
  605. throw new Exception("Error in DockContents count");
  606. }
  607. DockPage page = processShow(dragContent, stateTo, pane, DockHelper.GetDockAlignment(dockStyle), 0.5, contentIndex, Rectangle.Empty, true);
  608. }
  609. private void doDock(DockPage dragPage, DockState stateTo, DockPage pane, DockStyle dockStyle, int contentIndex)
  610. {
  611. //dragPage's DockContents less than 1
  612. if (dragPage.DisplayingContents.Count < 1)
  613. {
  614. throw new Exception("Error in DockContents count");
  615. }
  616. DockPage page = processShow(dragPage, stateTo, pane, DockHelper.GetDockAlignment(dockStyle), 0.5, contentIndex, Rectangle.Empty, true);
  617. }
  618. public void DockTo(IDragSource DragSource, DockPage pane, DockStyle dockStyle, int contentIndex)
  619. {
  620. #region DockContent DockTo
  621. if (DragSource is DockContent)
  622. {
  623. DockContent dragContent = DragSource as DockContent;
  624. #region DockTo(DockPage pane, DockStyle dockStyle, int contentIndex)
  625. DockState stateTo = pane.DockState;
  626. doDock(dragContent, stateTo, pane, dockStyle, contentIndex);
  627. #endregion
  628. }
  629. #endregion
  630. #region DockPage DockTo
  631. else if (DragSource is DockPage)
  632. {
  633. DockPage dragPage = DragSource as DockPage;
  634. #region DockTo(DockPage pane, DockStyle dockStyle, int contentIndex)
  635. DockState stateTo = pane.DockState;
  636. doDock(dragPage, stateTo, pane, dockStyle, contentIndex);
  637. #endregion
  638. }
  639. #endregion
  640. #region FloatWindow DockTo
  641. else if (DragSource is FloatWindow)
  642. {
  643. FloatWindow dragFloatWindow = DragSource as FloatWindow;
  644. #region DockTo(DockPage pane, DockStyle dockStyle, int contentIndex)
  645. DockState stateTo = pane.DockState;
  646. if (dockStyle == DockStyle.Fill)
  647. {
  648. for (int i = 0; i < dragFloatWindow.NestedPanes.Count; i++)
  649. {
  650. DockPage paneFrom = dragFloatWindow.NestedPanes[i];
  651. this.processShow(paneFrom, stateTo, pane, DockAlignment.Fill, 0.5, contentIndex, Rectangle.Empty, true);
  652. }
  653. }
  654. else
  655. {
  656. DockAlignment alignment = DockHelper.GetDockAlignment(dockStyle);
  657. MergeNestedPanes(dragFloatWindow.VisibleNestedPanes, pane.DockControl, pane, alignment, 0.5, contentIndex);
  658. }
  659. #endregion
  660. }
  661. #endregion
  662. }
  663. public void DockTo(IDragSource DragSource, DockPanel panel, DockStyle dockStyle)
  664. {
  665. #region DockContent DockTo
  666. if (DragSource is DockContent)
  667. {
  668. DockContent dragContent = DragSource as DockContent;
  669. #region DockTo(DockPanel panel, DockStyle dockStyle)
  670. DockState stateTo = DockHelper.GetDockState(dockStyle);
  671. DockPage dragPage = dragContent.DockPage;
  672. DockPage pane = this.DockWindows[stateTo].NestedPanes.GetDefaultPreviousPane(dragContent.DockContext.PrevPanelPage);
  673. doDock(dragContent, stateTo, pane, dockStyle, -1);
  674. #endregion
  675. }
  676. #endregion
  677. #region DockPage DockTo
  678. else if (DragSource is DockPage)
  679. {
  680. DockPage dragPage = DragSource as DockPage;
  681. #region DockTo(DockPanel panel, DockStyle dockStyle)
  682. DockState stateFrom = dragPage.DockState;
  683. DockState stateTo = DockHelper.GetDockState(dockStyle);
  684. DockPage pane = this.DockWindows[stateTo].NestedPanes.GetDefaultPreviousPane(dragPage);
  685. doDock(dragPage, stateTo, pane, dockStyle, -1);
  686. #endregion
  687. }
  688. #endregion
  689. #region FloatWindow DockTo
  690. else if (DragSource is FloatWindow)
  691. {
  692. FloatWindow dragFloatWindow = DragSource as FloatWindow;
  693. #region DockTo(DockPanel panel, DockStyle dockStyle)
  694. //only one situation
  695. DockState state = DockHelper.GetDockState(dockStyle);
  696. NestedPageCollection nestedPanesTo = this.DockWindows[state].NestedPanes;
  697. DockPage prevPane = null;
  698. for (int i = nestedPanesTo.Count - 1; i >= 0; i--)
  699. if (nestedPanesTo[i] != dragFloatWindow.VisibleNestedPanes[0] && nestedPanesTo[i].IsAutoHide)
  700. prevPane = nestedPanesTo[i];
  701. MergeNestedPanes(dragFloatWindow.VisibleNestedPanes, nestedPanesTo.Container, prevPane, DockAlignment.Left, 0.5, -1);
  702. #endregion
  703. }
  704. #endregion
  705. }
  706. private DockDragHandler m_dockDragHandler = null;
  707. private DockDragHandler GetDockDragHandler()
  708. {
  709. if (m_dockDragHandler == null)
  710. m_dockDragHandler = new DockDragHandler(this);
  711. return m_dockDragHandler;
  712. }
  713. internal void BeginDrag(IDragSource dragSource)
  714. {
  715. Console.WriteLine("DockPanel:BeginDrag");
  716. GetDockDragHandler().BeginDrag(dragSource);
  717. }
  718. #endregion
  719. #region AutoHideWindow
  720. private AutoHideWindow m_autoHideWindow;
  721. private AutoHideWindow AutoHideWindow
  722. {
  723. get { return m_autoHideWindow; }
  724. }
  725. internal Control AutoHideControl
  726. {
  727. get { return m_autoHideWindow; }
  728. }
  729. internal void RefreshActiveAutoHideContent()
  730. {
  731. AutoHideWindow.RefreshActiveContent();
  732. }
  733. internal Rectangle AutoHideWindowRectangle
  734. {
  735. get
  736. {
  737. DockState state = AutoHideWindow.DockState;
  738. Rectangle rectDockArea = DockArea;
  739. if (ActiveAutoHideContent == null)
  740. return Rectangle.Empty;
  741. if (Parent == null)
  742. return Rectangle.Empty;
  743. Rectangle rect = Rectangle.Empty;
  744. double autoHideSize = ActiveAutoHideContent.AutoHidePortion;
  745. if (state == DockState.DockLeftAutoHide)
  746. {
  747. if (autoHideSize < 1)
  748. autoHideSize = rectDockArea.Width * autoHideSize;
  749. if (autoHideSize > rectDockArea.Width - MeasurePane.MinSize)
  750. autoHideSize = rectDockArea.Width - MeasurePane.MinSize;
  751. rect.X = rectDockArea.X;
  752. rect.Y = rectDockArea.Y;
  753. rect.Width = (int)autoHideSize;
  754. rect.Height = rectDockArea.Height;
  755. }
  756. else if (state == DockState.DockRightAutoHide)
  757. {
  758. if (autoHideSize < 1)
  759. autoHideSize = rectDockArea.Width * autoHideSize;
  760. if (autoHideSize > rectDockArea.Width - MeasurePane.MinSize)
  761. autoHideSize = rectDockArea.Width - MeasurePane.MinSize;
  762. rect.X = rectDockArea.X + rectDockArea.Width - (int)autoHideSize;
  763. rect.Y = rectDockArea.Y;
  764. rect.Width = (int)autoHideSize;
  765. rect.Height = rectDockArea.Height;
  766. }
  767. else if (state == DockState.DockTopAutoHide)
  768. {
  769. if (autoHideSize < 1)
  770. autoHideSize = rectDockArea.Height * autoHideSize;
  771. if (autoHideSize > rectDockArea.Height - MeasurePane.MinSize)
  772. autoHideSize = rectDockArea.Height - MeasurePane.MinSize;
  773. rect.X = rectDockArea.X;
  774. rect.Y = rectDockArea.Y;
  775. rect.Width = rectDockArea.Width;
  776. rect.Height = (int)autoHideSize;
  777. }
  778. else if (state == DockState.DockBottomAutoHide)
  779. {
  780. if (autoHideSize < 1)
  781. autoHideSize = rectDockArea.Height * autoHideSize;
  782. if (autoHideSize > rectDockArea.Height - MeasurePane.MinSize)
  783. autoHideSize = rectDockArea.Height - MeasurePane.MinSize;
  784. rect.X = rectDockArea.X;
  785. rect.Y = rectDockArea.Y + rectDockArea.Height - (int)autoHideSize;
  786. rect.Width = rectDockArea.Width;
  787. rect.Height = (int)autoHideSize;
  788. }
  789. return rect;
  790. }
  791. }
  792. internal Rectangle GetAutoHideWindowBounds(Rectangle rectAutoHideWindow)
  793. {
  794. if (DocumentStyle == DocumentStyle.SystemMdi ||
  795. DocumentStyle == DocumentStyle.DockingMdi)
  796. return (Parent == null) ? Rectangle.Empty : Parent.RectangleToClient(RectangleToScreen(rectAutoHideWindow));
  797. else
  798. return rectAutoHideWindow;
  799. }
  800. internal void RefreshAutoHideStrip()
  801. {
  802. AutoHideStripWindow.RefreshChanges();
  803. }
  804. internal Rectangle GetTabStripRectangle(DockState dockState)
  805. {
  806. return AutoHideStripWindow.GetTabStripRectangle(dockState);
  807. }
  808. [Browsable(false)]
  809. public DockContent ActiveAutoHideContent
  810. {
  811. get { return AutoHideWindow.ActiveContent; }
  812. set { AutoHideWindow.ActiveContent = value; }
  813. }
  814. #endregion
  815. #region AutoHideStripWindow
  816. private AutoHideStripBase m_autoHideStripWindow = null;
  817. internal AutoHideStripBase AutoHideStripWindow
  818. {
  819. get
  820. {
  821. return m_autoHideStripWindow;
  822. }
  823. }
  824. #endregion
  825. private DockPanelHandler m_DockPanelHandler = null;
  826. internal DockPanelHandler DockPanelHandler
  827. {
  828. get
  829. {
  830. return m_DockPanelHandler;
  831. }
  832. }
  833. public DockPanel()
  834. {
  835. SetStyle(
  836. ControlStyles.ResizeRedraw |
  837. ControlStyles.UserPaint |
  838. ControlStyles.AllPaintingInWmPaint |
  839. ControlStyles.OptimizedDoubleBuffer, true);
  840. m_DockPanelHandler = new DockPanelHandler(this);
  841. DockPanelHandler.DockContentRemoved += new DockContentEventHandler(DockPanelHandler_DockContentRemoved);
  842. DockPanelHandler.DockContentAdded += new DockContentEventHandler(DockPanelHandler_DockContentAdded);
  843. DockPanelHandler.DockPageRemoved += new DockPageEventHandler(DockPanelHandler_DockPageRemoved);
  844. DockPanelHandler.DockPageAdded += new DockPageEventHandler(DockPanelHandler_DockPageAdded);
  845. InitializeComponent();
  846. SuspendLayout();
  847. m_autoHideWindow = new AutoHideWindow(this);
  848. m_autoHideWindow.Visible = false;
  849. m_autoHideWindow.Splitter.SplitterMove += new EventHandler(AutoHideWindowSplitter_SplitterMove);
  850. SetAutoHideWindowParent();
  851. m_autoHideStripWindow = new AutoHideStripWindow();
  852. m_autoHideStripWindow.RemoveAll();
  853. m_autoHideStripWindow.ActiveContentChanged += new DockContentEventHandler(m_autoHideStripWindow_ActiveContentChanged);
  854. Controls.Add(m_autoHideStripWindow);
  855. this.m_floatWindows = new FloatWindowCollection();
  856. this.m_floatWindows.FloatWindowRemoved += new FloatWindowEventHandler(m_floatWindows_FloatWindowRemoved);
  857. this.m_floatWindows.FloatWindowAdded += new FloatWindowEventHandler(m_floatWindows_FloatWindowAdded);
  858. this.m_dockWindows = new DockWindowCollection();
  859. this.m_dockWindows.DockWindowRemoved += new DockWindowEventHandler(m_dockWindows_DockWindowRemoved);
  860. this.m_dockWindows.DockWindowAdded += new DockWindowEventHandler(m_dockWindows_DockWindowAdded);
  861. this.Controls.AddRange(new Control[]{
  862. DockWindows[DockState.Document],
  863. DockWindows[DockState.DockLeft],
  864. DockWindows[DockState.DockRight],
  865. DockWindows[DockState.DockTop],
  866. DockWindows[DockState.DockBottom]
  867. });
  868. m_dummyControl = new DummyControl();
  869. m_dummyControl.Bounds = new Rectangle(0, 0, 1, 1);
  870. Controls.Add(m_dummyControl);
  871. ResumeLayout();
  872. }
  873. #region AutoHideStripWindow Events
  874. void m_autoHideStripWindow_ActiveContentChanged(object sender, DockContentEventArgs e)
  875. {
  876. DockContent content = e.Content;
  877. if (content != null && this.ActiveAutoHideContent != content)
  878. this.ActiveAutoHideContent = content;
  879. }
  880. #endregion
  881. #region AutoHideWindow & Splitter Events
  882. void AutoHideWindowSplitter_SplitterMove(object sender, EventArgs e)
  883. {
  884. SplitterBase m_splitter = sender as SplitterBase;
  885. AutoHideWindow window = m_splitter.Parent as AutoHideWindow;
  886. if (window == null)
  887. return;
  888. this.SplitterMove(window, window.RectangleToScreen(m_splitter.Bounds));
  889. }
  890. #endregion
  891. #region DockWindow & Splitter Events
  892. void m_dockWindows_DockWindowRemoved(object sender, DockWindowEventArgs e)
  893. {
  894. }
  895. void m_dockWindows_DockWindowAdded(object sender, DockWindowEventArgs e)
  896. {
  897. DockWindow window = e.DockWindow;
  898. window.Splitter.SplitterMove += new EventHandler(DockWindowSplitter_SplitterMove);
  899. }
  900. void DockWindowSplitter_SplitterMove(object sender, EventArgs e)
  901. {
  902. SplitterBase m_splitter = sender as SplitterBase;
  903. DockWindow window = m_splitter.Parent as DockWindow;
  904. if (window == null)
  905. return;
  906. this.SplitterMove(window, window.RectangleToScreen(m_splitter.Bounds));
  907. }
  908. #endregion
  909. #region FloatWindow Events
  910. void m_floatWindows_FloatWindowRemoved(object sender, FloatWindowEventArgs e)
  911. {
  912. }
  913. void m_floatWindows_FloatWindowAdded(object sender, FloatWindowEventArgs e)
  914. {
  915. FloatWindow fw = e.FloatWindow;
  916. fw.Visible = false;
  917. fw.Owner = this.FindForm();
  918. fw.StartPosition = FormStartPosition.WindowsDefaultLocation;
  919. fw.Size = this.DefaultFloatWindowSize;
  920. fw.CaptionClick += new EventHandler(fw_CaptionClick);
  921. fw.CaptionDoubleClick += new EventHandler(fw_CaptionDoubleClick);
  922. fw.FormCloseClick += new EventHandler(fw_FormCloseClick);
  923. }
  924. void fw_FormCloseClick(object sender, EventArgs e)
  925. {
  926. FloatWindow fw = sender as FloatWindow;
  927. for (int i = fw.NestedPanes.Count - 1; i >= 0; i--)
  928. {
  929. DockPage page = fw.NestedPanes[i];
  930. DockContentCollection contents = page.DockContents;
  931. for (int j = contents.Count - 1; j >= 0; j--)
  932. {
  933. DockContent content = contents[j];
  934. if (content.DockState != DockState.Float)
  935. continue;
  936. this.DockPanelHandler.CloseContent(content);
  937. }
  938. }
  939. }
  940. void fw_CaptionDoubleClick(object sender, EventArgs e)
  941. {
  942. FloatWindow fw = sender as FloatWindow;
  943. this.SuspendLayout(true);
  944. // Restore to panel
  945. foreach (DockPage pane in fw.NestedPanes)
  946. {
  947. if (pane.DockState != DockState.Float)
  948. continue;
  949. DockPanelHandler.RestoreToPanel(pane);
  950. }
  951. this.DoRefresh();
  952. this.ResumeLayout(true, true);
  953. }
  954. void fw_CaptionClick(object sender, EventArgs e)
  955. {
  956. FloatWindow fw = sender as FloatWindow;
  957. if (this.AllowEndUserDocking && fw.AllowEndUserDocking)
  958. {
  959. this.BeginDrag(fw);
  960. }
  961. }
  962. #endregion
  963. #region DockContent Events
  964. void DockPanelHandler_DockContentRemoved(object sender, DockContentEventArgs e)
  965. {
  966. DockContent content = e.Content;
  967. DockContents.Remove(content);
  968. }
  969. void DockPanelHandler_DockContentAdded(object sender, DockContentEventArgs e)
  970. {
  971. DockContent content = e.Content;
  972. content.AutoHidePortionChanged += new DockContentEventHandler(content_AutoHidePortionChanged);
  973. content.CloseButtonEnableChanged += new DockContentEventHandler(content_CloseButtonEnableChanged);
  974. DockContents.Add(content);
  975. }
  976. void content_CloseButtonEnableChanged(object sender, DockContentEventArgs e)
  977. {
  978. DockContent content = e.Content;
  979. DockPage page = content.DockPage;
  980. if (page != null)
  981. {
  982. if (page.ActiveContent == content)
  983. {
  984. page.RefreshChanges();
  985. }
  986. }
  987. }
  988. void content_AutoHidePortionChanged(object sender, DockContentEventArgs e)
  989. {
  990. DockContent content = e.Content;
  991. if (this.ActiveAutoHideContent == content)
  992. this.PerformLayout();
  993. }
  994. #endregion
  995. #region DockPage Events
  996. void DockPanelHandler_DockPageRemoved(object sender, DockPageEventArgs e)
  997. {
  998. DockPage page = e.DockPage;
  999. this.DockPages.Remove(page);
  1000. }
  1001. void DockPanelHandler_DockPageAdded(object sender, DockPageEventArgs e)
  1002. {
  1003. DockPage page = e.DockPage;
  1004. this.DockPages.Add(page);
  1005. page.ActiveContentChanged += new DockContentChangedEventHandler(page_ActiveContentChanged);
  1006. page.DockPageCaptionControl.DockButton.Click += new EventHandler(page_DockButton_Click);
  1007. page.DockPageCaptionControl.CloseButton.Click += new EventHandler(m_captionControl_CloseButtonClick);
  1008. page.DockPageCaptionControl.MouseDown += new MouseEventHandler(m_captionControl_MouseDown);
  1009. page.DockPageCaptionControl.DockContentClicked += new DockContentEventHandler(m_captionControl_DockContentClicked);
  1010. page.DockPageCaptionControl.DockContentDoubleClicked += new DockContentEventHandler(m_captionControl_DockContentDoubleClicked);
  1011. page.DockPageStripControl.MouseDown += new MouseEventHandler(m_tabStripControl_MouseDown);
  1012. page.DockPageStripControl.CloseButton.Click += new EventHandler(m_tabStripControl_CloseButtonClick);
  1013. page.DockPageStripControl.DockContentClicked += new DockContentEventHandler(m_tabStripControl_DockContentClicked);
  1014. page.DockPageStripControl.DockContentDoubleClicked += new DockContentEventHandler(m_tabStripControl_DockContentDoubleClicked);
  1015. page.Splitter.SplitterMove += new EventHandler(DockPageSplitter_SplitterMove);
  1016. }
  1017. void page_ActiveContentChanged(object sender, DockContentChangedEventArgs e)
  1018. {
  1019. DockContent newContent = e.NewContent;
  1020. DockContent oldContent = e.OldContent;
  1021. if (newContent != null)
  1022. {
  1023. if (newContent.DockPage != null)
  1024. {
  1025. if (newContent.DockPage.DockControl != null)
  1026. {
  1027. FloatWindow fw = newContent.DockPage.DockControl as FloatWindow;
  1028. if (fw != null)
  1029. {
  1030. fw.SetText();
  1031. }
  1032. }
  1033. }
  1034. }
  1035. }
  1036. #region DockPage Splitter Events
  1037. void DockPageSplitter_SplitterMove(object sender, EventArgs e)
  1038. {
  1039. SplitterBase m_splitter = sender as SplitterBase;
  1040. Control page = m_splitter.Parent as Control;
  1041. if (page == null)
  1042. return;
  1043. this.SplitterMove(m_splitter as IDragSource, page.RectangleToScreen(m_splitter.Bounds));
  1044. }
  1045. #endregion
  1046. #region DockButton Events
  1047. void page_DockButton_Click(object sender, EventArgs e)
  1048. {
  1049. DockPageCaptionBase caption = (sender as Control).Parent as DockPageCaptionBase;
  1050. DockPage pane = caption.Parent as DockPage;
  1051. DockState state = DockHelper.ToggleAutoHideState(pane.DockState);
  1052. this.SuspendLayout(true);
  1053. if (DockHelper.IsDockStateAutoHide(state))
  1054. {
  1055. pane.DockState = state;
  1056. this.ActiveAutoHideContent = pane.ActiveContent;
  1057. this.ActiveAutoHideContent = null;
  1058. }
  1059. else
  1060. {
  1061. this.DockWindows[pane.DockState].AddDockPage(pane);
  1062. }
  1063. this.ResumeLayout(true,true);
  1064. this.DoRefresh();
  1065. }
  1066. private void DoRefresh()
  1067. {
  1068. this.RefreshActiveAutoHideContent();
  1069. this.RefreshAutoHideStrip();
  1070. this.PerformLayout();
  1071. this.Invalidate(true);
  1072. }
  1073. #endregion
  1074. #region DockPageStripControl Events
  1075. void m_tabStripControl_MouseDown(object sender, MouseEventArgs e)
  1076. {
  1077. Control c = sender as Control;
  1078. DockPage page = c.Parent as DockPage;
  1079. ActivePage = page;
  1080. ActiveDocumentPage = page;
  1081. }
  1082. void m_tabStripControl_DockContentClicked(object sender, DockContentEventArgs e)
  1083. {
  1084. DockContent content = e.Content;
  1085. if (content == null) return;
  1086. ActiveDocument = content;
  1087. DockPage page = content.DockPage;
  1088. if (this.AllowEndUserDocking &&
  1089. page.AllowDockDragAndDrop &&
  1090. content != null &&
  1091. content.AllowEndUserDocking)
  1092. {
  1093. BeginDrag(content);
  1094. }
  1095. }
  1096. void m_tabStripControl_DockContentDoubleClicked(object sender, DockContentEventArgs e)
  1097. {
  1098. DockContent content = e.Content;
  1099. if (content == null) return;
  1100. DockState stateTo = DockState.Unknown;
  1101. DockPage page = null;
  1102. if (content.IsFloat)
  1103. {
  1104. page = content.DockContext.PrevPanelPage;
  1105. if (page == null)
  1106. {
  1107. stateTo = content.DefaultDockState;
  1108. }
  1109. }
  1110. else
  1111. {
  1112. page = content.DockContext.PrevFloatPage;
  1113. stateTo = DockState.Float;
  1114. }
  1115. if (page != null)
  1116. {
  1117. page.AddDockContent(content);
  1118. FloatWindow fw = page.DockControl as FloatWindow;
  1119. fw.Visible = true;
  1120. }