Skip to content

Commit

Permalink
fix(dragdrop): Fix reordering item at the bottom of the list has no e…
Browse files Browse the repository at this point in the history
…ffect (but still within LV bounds)
  • Loading branch information
dr1rrb committed Jan 10, 2022
1 parent b0fc2a7 commit 0eb888d
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ public partial class DragDrop_ListViewReorder_Automated : SampleControlUITestBas
[ActivePlatforms(Platform.Browser)] // TODO: support drag-and-drop testing on mobile https://github.com/unoplatform/Uno.UITest/issues/31
public void When_Reorder_To_Last() => Test_Reorder(3, 5);

[Test]
[AutoRetry]
[ActivePlatforms(Platform.Browser)] // TODO: support drag-and-drop testing on mobile https://github.com/unoplatform/Uno.UITest/issues/31
public void When_Reorder_To_Last_2() => Test_Reorder(3, 6 /* out of range */, expectedTo: 5);

[Test]
[AutoRetry]
[ActivePlatforms(Platform.Browser)] // TODO: support drag-and-drop testing on mobile https://github.com/unoplatform/Uno.UITest/issues/31
Expand All @@ -63,11 +68,6 @@ public partial class DragDrop_ListViewReorder_Automated : SampleControlUITestBas








[Test]
[AutoRetry]
[ActivePlatforms(Platform.Browser)] // TODO: support drag-and-drop testing on mobile https://github.com/unoplatform/Uno.UITest/issues/31
Expand Down Expand Up @@ -128,7 +128,7 @@ public partial class DragDrop_ListViewReorder_Automated : SampleControlUITestBas
[ActivePlatforms(Platform.Browser)] // TODO: support drag-and-drop testing on mobile https://github.com/unoplatform/Uno.UITest/issues/31
public void When_ReorderWithMultiSelectStartingFromASelectedItem_To_Last() => Test_ReorderMulti(2, 5, expectedTo: 4);

private void Test_Reorder(int from, int to)
private void Test_Reorder(int from, int to, int? expectedTo = null)
{
Run("UITests.Windows_UI_Xaml.DragAndDrop.DragDrop_ListView", skipInitialScreenshot: true);

Expand All @@ -141,12 +141,13 @@ private void Test_Reorder(int from, int to)
var x = sutBounds.X + 50;
var srcY = Item(sutBounds, from);
var dstY = Item(sutBounds, to);
var expectedY = expectedTo is null ? dstY : Item(sutBounds, expectedTo.Value);

_app.DragCoordinates(x, srcY, x, dstY);

var result = TakeScreenshot("Result", ignoreInSnapshotCompare: true);

ImageAssert.HasColorAt(result, x, dstY, _items[from], tolerance: 10);
ImageAssert.HasColorAt(result, x, expectedY, _items[from], tolerance: 10);
Assert.IsTrue(op.GetDependencyPropertyValue<string>("Text").Contains("Move"));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ internal class BorderLayerRenderer
_currentState = newState;
}

return newState.BoundsPath;
return newState.BoundsPath; // Will be null if not updated !!!
}

/// <summary>
Expand Down
35 changes: 18 additions & 17 deletions src/Uno.UI/UI/Xaml/Controls/ListViewBase/ListViewBase.DragDrop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -184,10 +184,7 @@ private static void OnItemContainerDragCompleted(UIElement sender, DropCompleted
}
}

private static void OnReorderDragUpdated(object sender, _DragEventArgs dragEventArgs) => OnReorderUpdated(sender, dragEventArgs, setVelocity: true);
private static void OnReorderDragLeave(object sender, _DragEventArgs dragEventArgs) => OnReorderUpdated(sender, dragEventArgs, setVelocity: false);

private static void OnReorderUpdated(object sender, _DragEventArgs dragEventArgs, bool setVelocity)
private static void OnReorderDragUpdated(object sender, _DragEventArgs dragEventArgs)
{
var that = sender as ListView;
var src = dragEventArgs.DataView.FindRawData(ReorderOwnerFormatId) as ListView;
Expand All @@ -213,17 +210,25 @@ private static void OnReorderUpdated(object sender, _DragEventArgs dragEventArgs
var position = dragEventArgs.GetPosition(that);
that.UpdateReordering(position, container, item);

if (setVelocity)
{
// See what our edge scrolling action should be...
var panVelocity = that.ComputeEdgeScrollVelocity(position);
// And request it.
that.SetPendingAutoPanVelocity(panVelocity);
}
else
// See what our edge scrolling action should be...
var panVelocity = that.ComputeEdgeScrollVelocity(position);
// And request it.
that.SetPendingAutoPanVelocity(panVelocity);
}

private static void OnReorderDragLeave(object sender, _DragEventArgs dragEventArgs)
{
var that = sender as ListView;
var src = dragEventArgs.DataView.FindRawData(ReorderOwnerFormatId) as ListView;
if (that is null || src != that)
{
that.SetPendingAutoPanVelocity(PanVelocity.Stationary);
dragEventArgs.Log().Warn("Invalid reorder event.");

return;
}

that.CleanupReordering();
that.SetPendingAutoPanVelocity(PanVelocity.Stationary);
}

private static void OnReorderCompleted(object sender, _DragEventArgs dragEventArgs)
Expand Down Expand Up @@ -363,11 +368,7 @@ private void UpdateReordering(Point location, FrameworkElement draggedContainer,
=> VirtualizingPanel?.GetLayouter().CompleteReorderingItem(draggedContainer, draggedItem);

private void CleanupReordering()
#if __ANDROID__
=> VirtualizingPanel?.GetLayouter().CleanupReordering();
#else
{ }
#endif

#region Helpers
private static bool IsObservableCollection(object src)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ abstract partial class VirtualizingPanelLayout
internal void UpdateReorderingItem(Point location, FrameworkElement element, object item) { }

internal Uno.UI.IndexPath? CompleteReorderingItem(FrameworkElement element, object item) => null;

internal void CleanupReordering() { }
}
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -1487,13 +1487,18 @@ internal void UpdateReorderingItem(Point location, FrameworkElement element, obj
}

internal Uno.UI.IndexPath? CompleteReorderingItem(FrameworkElement element, object item)
{
var dropTarget = _reorderingDropTarget?.ToIndexPath();
CleanupReordering();
return dropTarget;
}

internal void CleanupReordering()
{
_reorderingState = null;
ResetReorderedLayoutAttributes();
var dropTarget = _reorderingDropTarget?.ToIndexPath();
_reorderingDropTarget = null;
InvalidateLayout();
return dropTarget;
}

/// <summary>
Expand All @@ -1506,13 +1511,25 @@ private void UpdateLayoutForReordering()
if (_reorderingState is { } reorderingState && reorderingState.LayoutAttributes is { } draggedAttributes)
{
var dropTargetAttributes = GetLayoutAttributesUnderPoint(reorderingState.Location);
if (dropTargetAttributes is null)
{
// If we have a reorderingState, it means that the pointer is still over the LV.
// But if we didn't found any item under the pointer it means that it's after the last item,
// so we should consider that the item is going to be placed after the last item.
dropTargetAttributes = _itemLayoutInfos
.Values
.SelectMany(dict => dict.Values)
.OrderBy(attr => GetExtentStart(attr.Frame))
.LastOrDefault();
}

if (dropTargetAttributes == draggedAttributes)
{
// The item being dragged is currently under the point, no need to shift any items
dropTargetAttributes = null;
}
_reorderingDropTarget = dropTargetAttributes?.IndexPath;
if (dropTargetAttributes != null)
if (dropTargetAttributes is not null)
{
var preDragDraggedFrame = draggedAttributes.Frame;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1062,6 +1062,13 @@ internal void UpdateReorderingItem(Point location, FrameworkElement element, obj
LightRefresh();
}

internal void CleanupReordering()
{
_pendingReorder = null;

LightRefresh();
}

internal Uno.UI.IndexPath? CompleteReorderingItem(FrameworkElement element, object item)
{
var updatedIndex = default(Uno.UI.IndexPath?);
Expand Down

0 comments on commit 0eb888d

Please sign in to comment.