LayoutDocumentTabItem.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /*************************************************************************************
  2. Extended WPF Toolkit
  3. Copyright (C) 2007-2013 Xceed Software Inc.
  4. This program is provided to you under the terms of the Microsoft Public
  5. License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
  6. For more features, controls, and fast professional support,
  7. pick up the Plus Edition at http://xceed.com/wpf_toolkit
  8. Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
  9. ***********************************************************************************/
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Linq;
  13. using System.Text;
  14. using System.Windows;
  15. using System.Windows.Controls;
  16. using System.Windows.Input;
  17. using Xceed.Wpf.AvalonDock.Layout;
  18. using System.Diagnostics;
  19. using System.Windows.Media;
  20. namespace Xceed.Wpf.AvalonDock.Controls
  21. {
  22. public class LayoutDocumentTabItem : Control
  23. {
  24. static LayoutDocumentTabItem()
  25. {
  26. DefaultStyleKeyProperty.OverrideMetadata(typeof(LayoutDocumentTabItem), new FrameworkPropertyMetadata(typeof(LayoutDocumentTabItem)));
  27. }
  28. public LayoutDocumentTabItem()
  29. {
  30. }
  31. #region Model
  32. /// <summary>
  33. /// Model Dependency Property
  34. /// </summary>
  35. public static readonly DependencyProperty ModelProperty =
  36. DependencyProperty.Register("Model", typeof(LayoutContent), typeof(LayoutDocumentTabItem),
  37. new FrameworkPropertyMetadata((LayoutContent)null,
  38. new PropertyChangedCallback(OnModelChanged)));
  39. /// <summary>
  40. /// Gets or sets the Model property. This dependency property
  41. /// indicates the layout content model attached to the tab item.
  42. /// </summary>
  43. public LayoutContent Model
  44. {
  45. get { return (LayoutContent)GetValue(ModelProperty); }
  46. set { SetValue(ModelProperty, value); }
  47. }
  48. /// <summary>
  49. /// Handles changes to the Model property.
  50. /// </summary>
  51. private static void OnModelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  52. {
  53. ((LayoutDocumentTabItem)d).OnModelChanged(e);
  54. }
  55. /// <summary>
  56. /// Provides derived classes an opportunity to handle changes to the Model property.
  57. /// </summary>
  58. protected virtual void OnModelChanged(DependencyPropertyChangedEventArgs e)
  59. {
  60. if (Model != null)
  61. SetLayoutItem(Model.Root.Manager.GetLayoutItemFromModel(Model));
  62. else
  63. SetLayoutItem(null);
  64. //UpdateLogicalParent();
  65. }
  66. #endregion
  67. #region LayoutItem
  68. /// <summary>
  69. /// LayoutItem Read-Only Dependency Property
  70. /// </summary>
  71. private static readonly DependencyPropertyKey LayoutItemPropertyKey
  72. = DependencyProperty.RegisterReadOnly("LayoutItem", typeof(LayoutItem), typeof(LayoutDocumentTabItem),
  73. new FrameworkPropertyMetadata((LayoutItem)null));
  74. public static readonly DependencyProperty LayoutItemProperty
  75. = LayoutItemPropertyKey.DependencyProperty;
  76. /// <summary>
  77. /// Gets the LayoutItem property. This dependency property
  78. /// indicates the LayoutItem attached to this tag item.
  79. /// </summary>
  80. public LayoutItem LayoutItem
  81. {
  82. get { return (LayoutItem)GetValue(LayoutItemProperty); }
  83. }
  84. /// <summary>
  85. /// Provides a secure method for setting the LayoutItem property.
  86. /// This dependency property indicates the LayoutItem attached to this tag item.
  87. /// </summary>
  88. /// <param name="value">The new value for the property.</param>
  89. protected void SetLayoutItem(LayoutItem value)
  90. {
  91. SetValue(LayoutItemPropertyKey, value);
  92. }
  93. #endregion
  94. List<Rect> _otherTabsScreenArea = null;
  95. List<TabItem> _otherTabs = null;
  96. Rect _parentDocumentTabPanelScreenArea;
  97. DocumentPaneTabPanel _parentDocumentTabPanel;
  98. bool _isMouseDown = false;
  99. Point _mouseDownPoint;
  100. void UpdateDragDetails()
  101. {
  102. _parentDocumentTabPanel = this.FindLogicalAncestor<DocumentPaneTabPanel>();
  103. _parentDocumentTabPanelScreenArea = _parentDocumentTabPanel.GetScreenArea();
  104. _otherTabs = _parentDocumentTabPanel.Children.Cast<TabItem>().Where(ch =>
  105. ch.Visibility != System.Windows.Visibility.Collapsed).ToList();
  106. Rect currentTabScreenArea = this.FindLogicalAncestor<TabItem>().GetScreenArea();
  107. _otherTabsScreenArea = _otherTabs.Select(ti =>
  108. {
  109. var screenArea = ti.GetScreenArea();
  110. return new Rect(screenArea.Left, screenArea.Top, currentTabScreenArea.Width, screenArea.Height);
  111. }).ToList();
  112. }
  113. protected override void OnMouseLeftButtonDown(System.Windows.Input.MouseButtonEventArgs e)
  114. {
  115. base.OnMouseLeftButtonDown(e);
  116. Model.IsActive = true;
  117. if (e.ClickCount == 1)
  118. {
  119. _mouseDownPoint = e.GetPosition(this);
  120. _isMouseDown = true;
  121. }
  122. }
  123. protected override void OnMouseMove(System.Windows.Input.MouseEventArgs e)
  124. {
  125. base.OnMouseMove(e);
  126. if (_isMouseDown)
  127. {
  128. Point ptMouseMove = e.GetPosition(this);
  129. if (Math.Abs(ptMouseMove.X - _mouseDownPoint.X) > SystemParameters.MinimumHorizontalDragDistance ||
  130. Math.Abs(ptMouseMove.Y - _mouseDownPoint.Y) > SystemParameters.MinimumVerticalDragDistance)
  131. {
  132. UpdateDragDetails();
  133. CaptureMouse();
  134. _isMouseDown = false;
  135. }
  136. }
  137. if (IsMouseCaptured)
  138. {
  139. var mousePosInScreenCoord = this.PointToScreenDPI(e.GetPosition(this));
  140. if (!_parentDocumentTabPanelScreenArea.Contains(mousePosInScreenCoord))
  141. {
  142. ReleaseMouseCapture();
  143. var manager = Model.Root.Manager;
  144. manager.StartDraggingFloatingWindowForContent(Model);
  145. }
  146. else
  147. {
  148. int indexOfTabItemWithMouseOver = _otherTabsScreenArea.FindIndex(r => r.Contains(mousePosInScreenCoord));
  149. if (indexOfTabItemWithMouseOver >= 0)
  150. {
  151. var targetModel = _otherTabs[indexOfTabItemWithMouseOver].Content as LayoutContent;
  152. var container = Model.Parent as ILayoutContainer;
  153. var containerPane = Model.Parent as ILayoutPane;
  154. var childrenList = container.Children.ToList();
  155. containerPane.MoveChild(childrenList.IndexOf(Model), childrenList.IndexOf(targetModel));
  156. Model.IsActive = true;
  157. _parentDocumentTabPanel.UpdateLayout();
  158. UpdateDragDetails();
  159. }
  160. }
  161. }
  162. }
  163. protected override void OnMouseLeftButtonUp(System.Windows.Input.MouseButtonEventArgs e)
  164. {
  165. if (IsMouseCaptured)
  166. ReleaseMouseCapture();
  167. _isMouseDown = false;
  168. base.OnMouseLeftButtonUp(e);
  169. }
  170. protected override void OnMouseLeave(System.Windows.Input.MouseEventArgs e)
  171. {
  172. base.OnMouseLeave(e);
  173. _isMouseDown = false;
  174. }
  175. protected override void OnMouseEnter(MouseEventArgs e)
  176. {
  177. base.OnMouseEnter(e);
  178. _isMouseDown = false;
  179. }
  180. protected override void OnMouseDown(MouseButtonEventArgs e)
  181. {
  182. if (e.ChangedButton == MouseButton.Middle)
  183. {
  184. if (LayoutItem.CloseCommand.CanExecute(null))
  185. LayoutItem.CloseCommand.Execute(null);
  186. }
  187. base.OnMouseDown(e);
  188. }
  189. }
  190. }