From 55d5dcd9f71ca369a08ab2fb0729118898ba9ed3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20Korczy=C5=84ski?= Date: Fri, 19 Nov 2021 11:34:02 +0000 Subject: [PATCH] [UX] Added Drag and Drop utils --- .../Utils/DragDrop/DropUtilsTest.cs | 218 ++++++++++++++++++ .../WDE.Common/Utils/DragDrop/DropUtils.cs | 59 +++++ 2 files changed, 277 insertions(+) create mode 100644 WDE.Common.Test/Utils/DragDrop/DropUtilsTest.cs create mode 100644 WoWDatabaseEditor.Common/WDE.Common/Utils/DragDrop/DropUtils.cs diff --git a/WDE.Common.Test/Utils/DragDrop/DropUtilsTest.cs b/WDE.Common.Test/Utils/DragDrop/DropUtilsTest.cs new file mode 100644 index 000000000..86786bd31 --- /dev/null +++ b/WDE.Common.Test/Utils/DragDrop/DropUtilsTest.cs @@ -0,0 +1,218 @@ +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using WDE.Common.Utils.DragDrop; + +namespace WDE.Common.Test.Utils.DragDrop +{ + public class DropUtilsTest + { + private List l = null!; + + [SetUp] + public void Setup() + { + l = new List() { 1, 2, 3, 4, 5 }; + } + + private void PerformTest(int dropIndex, int[] expected, params int[] itemsToDrop) + { + var drop = new DropUtils(l, itemsToDrop.ToList(), dropIndex); + drop.DoDrop(l); + CollectionAssert.AreEqual(expected, l); + drop.Undo(l); + CollectionAssert.AreEqual(new int[]{ 1, 2, 3, 4, 5 }, l); + drop.DoDrop(l); + CollectionAssert.AreEqual(expected, l); + } + + [Test] + public void TestMove1To0() => PerformTest(0, new []{1, 2, 3, 4, 5}, 1); + + [Test] + public void TestMove1To1() => PerformTest(1, new []{1, 2, 3, 4, 5}, 1); + + [Test] + public void TestMove1To2() => PerformTest(2, new []{2, 1, 3, 4, 5}, 1); + + [Test] + public void TestMove1To3() => PerformTest(3, new []{2, 3, 1, 4, 5}, 1); + + [Test] + public void TestMove1To4() => PerformTest(4, new []{2, 3, 4, 1, 5}, 1); + + [Test] + public void TestMove1To5() => PerformTest(5, new []{2, 3, 4, 5, 1}, 1); + + [Test] + public void TestMove2To0() => PerformTest(0, new []{2, 1, 3, 4, 5}, 2); + + [Test] + public void TestMove2To1() => PerformTest(1, new []{1, 2, 3, 4, 5}, 2); + + [Test] + public void TestMove2To2() => PerformTest(2, new []{1, 2, 3, 4, 5}, 2); + + [Test] + public void TestMove2To3() => PerformTest(3, new []{1, 3, 2, 4, 5}, 2); + + [Test] + public void TestMove2To4() => PerformTest(4, new []{1, 3, 4, 2, 5}, 2); + + [Test] + public void TestMove2To5() => PerformTest(5, new []{1, 3, 4, 5, 2}, 2); + + [Test] + public void TestMove5To0() => PerformTest(0, new []{5, 1, 2, 3, 4}, 5); + + [Test] + public void TestMove5To1() => PerformTest(1, new []{1, 5, 2, 3, 4}, 5); + + [Test] + public void TestMove5To2() => PerformTest(2, new []{1, 2, 5, 3, 4}, 5); + + [Test] + public void TestMove5To3() => PerformTest(3, new []{1, 2, 3, 5, 4}, 5); + + [Test] + public void TestMove5To4() => PerformTest(4, new []{1, 2, 3, 4, 5}, 5); + + [Test] + public void TestMove5To5() => PerformTest(5, new []{1, 2, 3, 4, 5}, 5); + + + [Test] + public void TestMove12To0() => PerformTest(0, new []{1, 2, 3, 4, 5}, 1, 2); + + [Test] + public void TestMove12To1() => PerformTest(1, new []{1, 2, 3, 4, 5}, 1, 2); + + [Test] + public void TestMove12To2() => PerformTest(2, new []{1, 2, 3, 4, 5}, 1, 2); + + [Test] + public void TestMove12To3() => PerformTest(3, new []{3, 1, 2, 4, 5}, 1, 2); + + [Test] + public void TestMove12To4() => PerformTest(4, new []{3, 4, 1, 2, 5}, 1, 2); + + [Test] + public void TestMove12To5() => PerformTest(5, new []{3, 4, 5, 1, 2}, 1, 2); + + + [Test] + public void TestMove45To0() => PerformTest(0, new []{4, 5, 1, 2, 3}, 4, 5); + + [Test] + public void TestMove45To1() => PerformTest(1, new []{1, 4, 5, 2, 3}, 4, 5); + + [Test] + public void TestMove45To2() => PerformTest(2, new []{1, 2, 4, 5, 3}, 4, 5); + + [Test] + public void TestMove45To3() => PerformTest(3, new []{1, 2, 3, 4, 5}, 4, 5); + + [Test] + public void TestMove45To4() => PerformTest(4, new []{1, 2, 3, 4, 5}, 4, 5); + + [Test] + public void TestMove45To5() => PerformTest(5, new []{1, 2, 3, 4, 5}, 4, 5); + + + [Test] + public void TestMove15To0() => PerformTest(0, new []{1, 5, 2, 3, 4}, 1, 5); + + [Test] + public void TestMove15To1() => PerformTest(1, new []{1, 5, 2, 3, 4}, 1, 5); + + [Test] + public void TestMove15To2() => PerformTest(2, new []{2, 1, 5, 3, 4}, 1, 5); + + [Test] + public void TestMove15To3() => PerformTest(3, new []{2, 3, 1, 5, 4}, 1, 5); + + [Test] + public void TestMove15To4() => PerformTest(4, new []{2, 3, 4, 1, 5}, 1, 5); + + [Test] + public void TestMove15To5() => PerformTest(5, new []{2, 3, 4, 1, 5}, 1, 5); + + + + + [Test] + public void TestMove123To0() => PerformTest(0, new []{1, 2, 3, 4, 5}, 1, 2, 3); + + [Test] + public void TestMove123To1() => PerformTest(1, new []{1, 2, 3, 4, 5}, 1, 2, 3); + + [Test] + public void TestMove123To2() => PerformTest(2, new []{1, 2, 3, 4, 5}, 1, 2, 3); + + [Test] + public void TestMove123To3() => PerformTest(3, new []{1, 2, 3, 4, 5}, 1, 2, 3); + + [Test] + public void TestMove123To4() => PerformTest(4, new []{4, 1, 2, 3, 5}, 1, 2, 3); + + [Test] + public void TestMove123To5() => PerformTest(5, new []{4, 5, 1, 2, 3}, 1, 2, 3); + + + + [Test] + public void TestMove124To0() => PerformTest(0, new []{1, 2, 4, 3, 5}, 1, 2, 4); + [Test] + public void TestMove124To1() => PerformTest(1, new []{1, 2, 4, 3, 5}, 1, 2, 4); + [Test] + public void TestMove124To2() => PerformTest(2, new []{1, 2, 4, 3, 5}, 1, 2, 4); + [Test] + public void TestMove124To3() => PerformTest(3, new []{3, 1, 2, 4, 5}, 1, 2, 4); + [Test] + public void TestMove124To4() => PerformTest(4, new []{3, 1, 2, 4, 5}, 1, 2, 4); + [Test] + public void TestMove124To5() => PerformTest(5, new []{3, 5, 1, 2, 4}, 1, 2, 4); + + + [Test] + public void TestMove125To0() => PerformTest(0, new []{1, 2, 5, 3, 4}, 1, 2, 5); + [Test] + public void TestMove125To1() => PerformTest(1, new []{1, 2, 5, 3, 4}, 1, 2, 5); + [Test] + public void TestMove125To2() => PerformTest(2, new []{1, 2, 5, 3, 4}, 1, 2, 5); + [Test] + public void TestMove125To3() => PerformTest(3, new []{3, 1, 2, 5, 4}, 1, 2, 5); + [Test] + public void TestMove125To4() => PerformTest(4, new []{3, 4, 1, 2, 5}, 1, 2, 5); + [Test] + public void TestMove125To5() => PerformTest(5, new []{3, 4, 1, 2, 5}, 1, 2, 5); + + + [Test] + public void TestMove1234To0() => PerformTest(0, new []{1, 2, 3, 4, 5}, 1, 2, 3, 4); + [Test] + public void TestMove1234To1() => PerformTest(1, new []{1, 2, 3, 4, 5}, 1, 2, 3, 4); + [Test] + public void TestMove1234To2() => PerformTest(2, new []{1, 2, 3, 4, 5}, 1, 2, 3, 4); + [Test] + public void TestMove1234To3() => PerformTest(3, new []{1, 2, 3, 4, 5}, 1, 2, 3, 4); + [Test] + public void TestMove1234To4() => PerformTest(4, new []{1, 2, 3, 4, 5}, 1, 2, 3, 4); + [Test] + public void TestMove1234To5() => PerformTest(5, new []{5, 1, 2, 3, 4}, 1, 2, 3, 4); + + + [Test] + public void TestMove12345To0() => PerformTest(0, new []{1, 2, 3, 4, 5}, 1, 2, 3, 4, 5); + [Test] + public void TestMove12345To1() => PerformTest(1, new []{1, 2, 3, 4, 5}, 1, 2, 3, 4, 5); + [Test] + public void TestMove12345To2() => PerformTest(2, new []{1, 2, 3, 4, 5}, 1, 2, 3, 4, 5); + [Test] + public void TestMove12345To3() => PerformTest(3, new []{1, 2, 3, 4, 5}, 1, 2, 3, 4, 5); + [Test] + public void TestMove12345To4() => PerformTest(4, new []{1, 2, 3, 4, 5}, 1, 2, 3, 4, 5); + [Test] + public void TestMove12345To5() => PerformTest(5, new []{1, 2, 3, 4, 5}, 1, 2, 3, 4, 5); + } +} \ No newline at end of file diff --git a/WoWDatabaseEditor.Common/WDE.Common/Utils/DragDrop/DropUtils.cs b/WoWDatabaseEditor.Common/WDE.Common/Utils/DragDrop/DropUtils.cs new file mode 100644 index 000000000..143ed387d --- /dev/null +++ b/WoWDatabaseEditor.Common/WDE.Common/Utils/DragDrop/DropUtils.cs @@ -0,0 +1,59 @@ +using System.Collections.Generic; +using System.Diagnostics; + +namespace WDE.Common.Utils.DragDrop +{ + public class DropUtils + { + private readonly IReadOnlyList originalList; + private readonly IList itemsToDrop; + private readonly int dropIndex; + private readonly int realDropIndex; + private readonly List<(T, int)> itemAndIndices = new(); + + public DropUtils(IReadOnlyList originalList, IList itemsToDrop, int dropIndex) + { + this.originalList = originalList; + this.itemsToDrop = itemsToDrop; + this.dropIndex = dropIndex; + + realDropIndex = dropIndex; + foreach (var item in itemsToDrop) + { + var index = originalList.IndexOf(item); + if (index < dropIndex) + realDropIndex--; + itemAndIndices.Add((item, index)); + } + + itemAndIndices.Sort((a, b) => a.Item2.CompareTo(b.Item2)); + } + + public void DoDrop(IList list) + { + foreach (var item in itemsToDrop) + { + list.Remove(item); + } + + for (int i = 0; i < itemsToDrop.Count; i++) + { + list.Insert(realDropIndex + i, itemsToDrop[i]); + } + } + + public void Undo(IList list) + { + for (int i = 0; i < itemsToDrop.Count; ++i) + { + Debug.Assert(EqualityComparer.Default.Equals(itemsToDrop[i], list[dropIndex])); + list.RemoveAt(realDropIndex); + } + + foreach (var pair in itemAndIndices) + { + list.Insert(pair.Item2, pair.Item1); + } + } + } +} \ No newline at end of file