cleverInsertionIndexFor method
this will behave more in line with user intent, if a user drags an item to its neighbor, this will always place it beyond its neighbor, while midwayInsertionIndex will sometimes place it back where it was to begin with and produce no action. Returns false if it's still going to have no effect anyway (eg if there's no room for a movement).
Implementation
(bool, int) cleverInsertionIndexFor(int currentIndex, int listLength) {
// if it's moving to before or after the current index, that would be a no op
if (index != currentIndex) {
int insertingAt;
// if the item being pointed at is either of those directly adjacent to the current index, the especially prefer to place it before or after those on the other side, not on the same side (which would be a no-op)
if (index == currentIndex + 1) {
insertingAt = currentIndex + 2; // after itself, after the next one.
} else if (index == currentIndex - 1) {
insertingAt = currentIndex - 1;
} else {
insertingAt = midwayInsertionIndex();
}
// make sure it hasn't been nudged out of all valid insertion points, if so, then there is no valid insertion point other than the original location, so no movement
return (insertingAt <= listLength && insertingAt >= 0, insertingAt);
} else {
return (false, midwayInsertionIndex());
}
}