DragService.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  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.Input;
  15. using System.Windows;
  16. using System.Diagnostics;
  17. using Xceed.Wpf.AvalonDock.Layout;
  18. namespace Xceed.Wpf.AvalonDock.Controls
  19. {
  20. class DragService
  21. {
  22. DockingManager _manager;
  23. LayoutFloatingWindowControl _floatingWindow;
  24. public DragService(LayoutFloatingWindowControl floatingWindow)
  25. {
  26. _floatingWindow = floatingWindow;
  27. _manager = floatingWindow.Model.Root.Manager;
  28. GetOverlayWindowHosts();
  29. }
  30. List<IOverlayWindowHost> _overlayWindowHosts = new List<IOverlayWindowHost>();
  31. void GetOverlayWindowHosts()
  32. {
  33. _overlayWindowHosts.AddRange(_manager.GetFloatingWindowsByZOrder().OfType<LayoutAnchorableFloatingWindowControl>().Where(fw => fw != _floatingWindow && fw.IsVisible));
  34. _overlayWindowHosts.Add(_manager);
  35. }
  36. IOverlayWindowHost _currentHost;
  37. IOverlayWindow _currentWindow;
  38. List<IDropArea> _currentWindowAreas = new List<IDropArea>();
  39. IDropTarget _currentDropTarget;
  40. public void UpdateMouseLocation(Point dragPosition)
  41. {
  42. var floatingWindowModel = _floatingWindow.Model as LayoutFloatingWindow;
  43. var newHost = _overlayWindowHosts.FirstOrDefault(oh => oh.HitTest(dragPosition));
  44. if (_currentHost != null || _currentHost != newHost)
  45. {
  46. //is mouse still inside current overlay window host?
  47. if ((_currentHost != null && !_currentHost.HitTest(dragPosition)) ||
  48. _currentHost != newHost)
  49. {
  50. //esit drop target
  51. if (_currentDropTarget != null)
  52. _currentWindow.DragLeave(_currentDropTarget);
  53. _currentDropTarget = null;
  54. //exit area
  55. _currentWindowAreas.ForEach(a =>
  56. _currentWindow.DragLeave(a));
  57. _currentWindowAreas.Clear();
  58. //hide current overlay window
  59. if (_currentWindow != null)
  60. _currentWindow.DragLeave(_floatingWindow);
  61. if (_currentHost != null)
  62. _currentHost.HideOverlayWindow();
  63. _currentHost = null;
  64. }
  65. if (_currentHost != newHost)
  66. {
  67. _currentHost = newHost;
  68. _currentWindow = _currentHost.ShowOverlayWindow(_floatingWindow);
  69. _currentWindow.DragEnter(_floatingWindow);
  70. }
  71. }
  72. if (_currentHost == null)
  73. return;
  74. if (_currentDropTarget != null &&
  75. !_currentDropTarget.HitTest(dragPosition))
  76. {
  77. _currentWindow.DragLeave(_currentDropTarget);
  78. _currentDropTarget = null;
  79. }
  80. List<IDropArea> areasToRemove = new List<IDropArea>();
  81. _currentWindowAreas.ForEach(a =>
  82. {
  83. //is mouse still inside this area?
  84. if (!a.DetectionRect.Contains(dragPosition))
  85. {
  86. _currentWindow.DragLeave(a);
  87. areasToRemove.Add(a);
  88. }
  89. });
  90. areasToRemove.ForEach(a =>
  91. _currentWindowAreas.Remove(a));
  92. var areasToAdd =
  93. _currentHost.GetDropAreas(_floatingWindow).Where(cw => !_currentWindowAreas.Contains(cw) && cw.DetectionRect.Contains(dragPosition)).ToList();
  94. _currentWindowAreas.AddRange(areasToAdd);
  95. areasToAdd.ForEach(a =>
  96. _currentWindow.DragEnter(a));
  97. if (_currentDropTarget == null)
  98. {
  99. _currentWindowAreas.ForEach(wa =>
  100. {
  101. if (_currentDropTarget != null)
  102. return;
  103. _currentDropTarget = _currentWindow.GetTargets().FirstOrDefault(dt => dt.HitTest(dragPosition));
  104. if (_currentDropTarget != null)
  105. {
  106. _currentWindow.DragEnter(_currentDropTarget);
  107. return;
  108. }
  109. });
  110. }
  111. }
  112. public void Drop(Point dropLocation, out bool dropHandled)
  113. {
  114. dropHandled = false;
  115. UpdateMouseLocation(dropLocation);
  116. var floatingWindowModel = _floatingWindow.Model as LayoutFloatingWindow;
  117. var root = floatingWindowModel.Root;
  118. if (_currentHost != null)
  119. _currentHost.HideOverlayWindow();
  120. if (_currentDropTarget != null)
  121. {
  122. _currentWindow.DragDrop(_currentDropTarget);
  123. root.CollectGarbage();
  124. dropHandled = true;
  125. }
  126. _currentWindowAreas.ForEach(a => _currentWindow.DragLeave(a));
  127. if (_currentDropTarget != null)
  128. _currentWindow.DragLeave(_currentDropTarget);
  129. if (_currentWindow != null)
  130. _currentWindow.DragLeave(_floatingWindow);
  131. _currentWindow = null;
  132. _currentHost = null;
  133. }
  134. internal void Abort()
  135. {
  136. var floatingWindowModel = _floatingWindow.Model as LayoutFloatingWindow;
  137. _currentWindowAreas.ForEach(a => _currentWindow.DragLeave(a));
  138. if (_currentDropTarget != null)
  139. _currentWindow.DragLeave(_currentDropTarget);
  140. if (_currentWindow != null)
  141. _currentWindow.DragLeave(_floatingWindow);
  142. _currentWindow = null;
  143. if (_currentHost != null)
  144. _currentHost.HideOverlayWindow();
  145. _currentHost = null;
  146. }
  147. }
  148. }