Here is a very crude first implementation (code at the bottom):

(note that the updated version is called as `dragDropList[Dynamic@l)
Some notes:
- The black box serves both as insertion marker and as spacer to move the other items out of the way - obviously, it will need some better styling
- I'm not sure what the best size for the insertion point is - one option is to make it the same size as the item being moved (not sure how to do that though)
- As you can see, there is no smooth animation - not sure whether this one is feasible with any kind of acceptable performance
- The insertion bar is the item currently being moved - this makes re-insertion very easy, since we just have to change the displayed content back. Also, we never have to add stuff to the list, just reorder it
- The insertion bar is moved every time the cursor is over another item
- As can be seen, there is some flickering in the order of the items at some points - this is caused by the fact that reordering the items can sometimes bring another item below the cursor (instead of the insertion bar), causing repeated reordering
- The state of the control lives in several variables:
list: The list of items, in their current order
iList: The list of indices, in the same order as list
indices: The current positions of the elements (given in the original order)
dragged: The index of the currently dragged item, or None
curPos: The current position of the insertion bar
cursor: The cursor to show (includes the moved item)
BeginPackage["dragDropList`"];
dragDropList;
Begin["`Private`"];
dragDropList[Dynamic@var_, items_] :=
Panel@DynamicModule[
{
set = (var = #) &,
rawItems = items,
list,
iList,
indices = Range@Length@items,
dragged = None,
curPos,
cursor = "Arrow",
defCursor =
Graphics[{Arrowheads[0.7], Arrow[{{0, 0}, {-.5, 1}}]},
ImageSize -> 16, PlotRange -> {{-1, 0}, {0, 2}}]
},
set@rawItems;
iList = indices;
list = MapIndexed[
EventHandler[
Dynamic@If[
dragged === #2,
Graphics[Rectangle[{0, 0}, {1, 1}], AspectRatio -> Full,
ImageSize -> {100, 30}],
#
],
{
"MouseDown" :> (
dragged = #2;
curPos = indices[[dragged]];
FrontEndExecute[
FrontEnd`SetMouseAppearance[
cursor = Overlay[{#, defCursor}, Alignment -> Center]]]
),
"MouseEntered" :> (
If[curPos =!= indices[[#2]] && dragged =!= None,
With[
{newPos = indices[[#2]]},
{iList, list} =
Transpose[({t, d} \[Function]
Insert[d, First@t, newPos]) @@
TakeDrop[Transpose@{iList, list}, {curPos}]];
indices = Ordering@iList;
set@rawItems[[iList]];
curPos = newPos
]
]
)
}
] & @@ {#, #2[[1]]} &,
rawItems
];
Deploy@EventHandler[
Pane[
Dynamic@Column@list,
{Automatic, Automatic},
Scrollbars -> Automatic
],
{
"MouseUp" :> (
dragged = None;
FrontEndExecute[
FrontEnd`SetMouseAppearance[cursor = "Arrow"]]
),
"MouseEntered" :> FrontEndExecute[FrontEnd`SetMouseAppearance[]],
"MouseExited" :>
FrontEndExecute[FrontEnd`SetMouseAppearance[cursor]]
},
PassEventsDown -> True
]
]
End[];
EndPackage[];
Dynamic@list
dragDropList[Dynamic@list,Panel/@Table[RandomWord[],10]]
Graphicsenvironment where I could easily manage and find out what things overlapped, but it'll be harder to do in a more general one. In particular getting thumbnail moves with the mouse which is doable using a hack involving the underpinnings ofMouseAppearance, but which would probably be annoying. What's your main use case for this? – b3m2a1 Jan 13 '20 at 22:59