From 9b831e817f18ffe7bcde4aabaf653ebd5f02e9e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Gonz=C3=A1lez?= Date: Tue, 15 Nov 2022 00:08:51 +0100 Subject: [PATCH] Fix drag starting immediately --- WPFSpark/FluidWrapPanel/FluidWrapPanel.cs | 119 +++++++++++++--------- 1 file changed, 70 insertions(+), 49 deletions(-) diff --git a/WPFSpark/FluidWrapPanel/FluidWrapPanel.cs b/WPFSpark/FluidWrapPanel/FluidWrapPanel.cs index 6e19a33..3797230 100644 --- a/WPFSpark/FluidWrapPanel/FluidWrapPanel.cs +++ b/WPFSpark/FluidWrapPanel/FluidWrapPanel.cs @@ -34,6 +34,7 @@ using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; +using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; @@ -113,6 +114,7 @@ internal bool Contains(long row, long col) private Point _dragStartPoint; private UIElement _dragElement; private UIElement _lastDragElement; + private bool _isDragging; private bool _isOptimized; private Size _panelSize; private int _cellsPerLine; @@ -945,19 +947,12 @@ internal async Task BeginFluidDragAsync(UIElement child, Point position) if ((child == null) || (!IsComposing)) return; - // Call the event handler core on the Dispatcher. (Improves efficiency!) - await Dispatcher.InvokeAsync(() => - { - child.Opacity = DragOpacity; - child.SetValue(ZIndexProperty, ZIndexDrag); - // Capture further mouse events - child.CaptureMouse(); - _dragElement = child; - _lastDragElement = null; - - // Since we are scaling the dragElement by DragScale, the clickPoint also shifts - _dragStartPoint = new Point(position.X * DragScale, position.Y * DragScale); - }); + _dragStartPoint = position; + _dragElement = child; + _lastDragElement = null; + _isDragging = false; + + await Task.CompletedTask; } /// @@ -971,52 +966,77 @@ internal async Task FluidDragAsync(UIElement child, Point position, Point positi if ((child == null) || (!IsComposing) || (_dragElement == null)) return; - // Call the event handler core on the Dispatcher. (Improves efficiency!) - await Dispatcher.InvokeAsync(() => + if (!_isDragging) { - _dragElement.RenderTransform = CreateTransform(positionInParent.X - _dragStartPoint.X, - positionInParent.Y - _dragStartPoint.Y, - DragScale, - DragScale); + Vector diff = _dragStartPoint - position; - // Are all the children are of unit cell size? - if (_isOptimized) + if (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance || + Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance) { - // Get the index of the dragElement - var dragCellIndex = FluidItems.IndexOf(_dragElement); + // Call the event handler core on the Dispatcher. (Improves efficiency!) + await Dispatcher.InvokeAsync( () => + { + child.Opacity = DragOpacity; + child.SetValue(ZIndexProperty, ZIndexDrag); + // Capture further mouse events + child.CaptureMouse(); + + // Since we are scaling the dragElement by DragScale, the clickPoint also shifts + _dragStartPoint = new Point(position.X * DragScale, position.Y * DragScale); + _isDragging = true; + } ); + } + } - // Get the index in the fluidElements list corresponding to the current mouse location - var index = GetIndexFromPoint(positionInParent); + if (_isDragging) + { + // Call the event handler core on the Dispatcher. (Improves efficiency!) + await Dispatcher.InvokeAsync(() => + { + _dragElement.RenderTransform = CreateTransform(positionInParent.X - _dragStartPoint.X, + positionInParent.Y - _dragStartPoint.Y, + DragScale, + DragScale); - // If no valid cell index is obtained (happens when the dragElement is dragged outside - // the FluidWrapPanel), add the child to the end of the fluidElements list. - if ((index == -1) || (index >= FluidItems.Count)) + // Are all the children are of unit cell size? + if (_isOptimized) { - index = FluidItems.Count - 1; - } + // Get the index of the dragElement + var dragCellIndex = FluidItems.IndexOf(_dragElement); - // If both indices are same no need to process further - if (index == dragCellIndex) - return; + // Get the index in the fluidElements list corresponding to the current mouse location + var index = GetIndexFromPoint(positionInParent); - // Move the dragElement to the new index - FluidItems.RemoveAt(dragCellIndex); - FluidItems.Insert(index, _dragElement); + // If no valid cell index is obtained (happens when the dragElement is dragged outside + // the FluidWrapPanel), add the child to the end of the fluidElements list. + if ((index == -1) || (index >= FluidItems.Count)) + { + index = FluidItems.Count - 1; + } - // Refresh the FluidWrapPanel - InvalidateVisual(); - } - // Children are not having unit cell size - else - { - // Refresh the FluidWrapPanel only if the dragElement - // can be successfully placed in the new location - if (TryFluidDrag(position, positionInParent)) - { + // If both indices are same no need to process further + if (index == dragCellIndex) + return; + + // Move the dragElement to the new index + FluidItems.RemoveAt(dragCellIndex); + FluidItems.Insert(index, _dragElement); + + // Refresh the FluidWrapPanel InvalidateVisual(); } - } - }); + // Children are not having unit cell size + else + { + // Refresh the FluidWrapPanel only if the dragElement + // can be successfully placed in the new location + if (TryFluidDrag(position, positionInParent)) + { + InvalidateVisual(); + } + } + }); + } } /// @@ -1205,7 +1225,7 @@ private bool TryFluidDrag(Point position, Point positionInParent) /// Position where the user clicked w.r.t. the FluidWrapPanel (the parentFWPanel of the UIElement being dragged internal async Task EndFluidDragAsync(UIElement child, Point position, Point positionInParent) { - if ((child == null) || (!IsComposing) || (_dragElement == null)) + if ((child == null) || (!IsComposing) || (_dragElement == null) || (!_isDragging)) return; // Call the event handler core on the Dispatcher. (Improves efficiency!) @@ -1226,6 +1246,7 @@ await Dispatcher.InvokeAsync(() => _lastDragElement = _dragElement; _dragElement = null; + _isDragging = false; _lastExchangedElement = null; InvalidateVisual();