Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix drag starting immediately #18

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 70 additions & 49 deletions WPFSpark/FluidWrapPanel/FluidWrapPanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

/// <summary>
Expand All @@ -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();
}
}
});
}
}

/// <summary>
Expand Down Expand Up @@ -1205,7 +1225,7 @@ private bool TryFluidDrag(Point position, Point positionInParent)
/// <param name="positionInParent">Position where the user clicked w.r.t. the FluidWrapPanel (the parentFWPanel of the UIElement being dragged</param>
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!)
Expand All @@ -1226,6 +1246,7 @@ await Dispatcher.InvokeAsync(() =>
_lastDragElement = _dragElement;

_dragElement = null;
_isDragging = false;
_lastExchangedElement = null;

InvalidateVisual();
Expand Down