I have a project where using a data grid form really simplifies things, however, it’s critical that the user can re-order the list in arbitrary way. To do this I needed to add drag and drop to the data grid.
First I wrote rolled my own:
There two main limitations with this code are that it will only work for a data grid form (not table) and only if the cache controls property is true.
local sDragImage,sControlIndexMap,sOriginalIndexes on dragStart local tControl,tItem set the dragData["private"] to "dgDragIndex"&&the dgHilitedIndex of me put the dgDataControlOfIndex[the dgHilitedIndex of me] of me into tControl lock screen import snapshot from tControl put the long id of the last image into sDragImage set the visible of sDragImage to false set the dragImage to the short id of sDragImage put the dgIndexes of me into sOriginalIndexes delete variable sControlIndexMap repeat for each item tItem in the dgIndexes of me put tItem into sControlIndexMap[the dgDataControlOfIndex[tItem] of me] end repeat set the allowableDragActions to "move" pass dragStart end dragStart on dragMove pX,pY local tDragIndex,tNewIndexes,tOverIndex if word 1 of the dragData["private"] = "dgDragIndex" then unlock screen lock cursor -- refresh bug workaround on setting the dgIndexes the dragAction seems to get set to none put word 2 of the dragData["private"] into tDragIndex set the dragAction to "move" if pY > the bottom of me-20 then if item 2 of the dgVisibleLines of me < the dgNumberOfLines of me or the scroll of me is not the dgFormattedHeight of me then set the dgVscroll of me to min(the dgVscroll of me + 20, the dgFormattedHeight of me) end if else if pY < the top of me+20 then if item 1 of the dgVisibleLines of me > 1 or the scroll of me is not 0 then set the dgVscroll of me to max(the dgVscroll of me - 20,0) end if end if repeat with X=1 to the number of groups of group "dgList" of me if the visible of group X of group "dgList" and the short name of the owner of group X of group "dgList" is "dgList" then if (pY >= the top of group X of group "dgList" of me) and (pY < (the top of group X of group "dgList" of me+(the bottom of group X of group "dgList" of me-the top of group X of group "dgList" of me) div 2)) then -- place above index put sControlIndexMap[the long id of group X of group "dgList" of me] into tOverIndex --put "over"&&tOverIndex if tDragIndex = tOverIndex then put sOriginalIndexes into tNewIndexes else put sOriginalIndexes into tNewIndexes delete item itemOffset(tDragIndex,tNewIndexes) of tNewIndexes put tDragIndex&"," before item itemOffset(tOverIndex,tNewIndexes) of tNewIndexes end if set the dgIndexes of me to tNewIndexes put tNewIndexes into sOriginalIndexes else if (pY <= the bottom of group X of group "dgList" of me) and (pY > (the top of group X of group "dgList" of me+(the bottom of group X of group "dgList" of me-the top of group X of group "dgList" of me) div 2)) then -- place below index put sControlIndexMap[the long id of group X of group "dgList" of me] into tOverIndex --put "over"&&tOverIndex if tDragIndex = tOverIndex then put sOriginalIndexes into tNewIndexes else put sOriginalIndexes into tNewIndexes delete item itemOffset(tDragIndex,tNewIndexes) of tNewIndexes put ","&tDragIndex after item itemOffset(tOverIndex,tNewIndexes) of tNewIndexes end if set the dgIndexes of me to tNewIndexes put tNewIndexes into sOriginalIndexes end if end if end repeat end if pass dragMove end dragMove on dragEnd -- clean up if sDragImage <> "" then delete sDragImage put "" into sDragImage end if pass dragEnd end dragEnd
Then I had a poke around the data grid behavior script and found undocumented support for drag and drop. So here’s the new script that does not have the limitations of the above and is obviously far less verbose:
on dragStart local tIndex if (the dgHeader of the target is empty) then put the dgIndex of the dgDataControl of the target into tIndex set the dgDragImageIndex of me to tIndex set the dragData["private"] to empty set the dgTrackDragReorder[tIndex] of me to true end if end dragStart on DragReorderDrop pOriginatingIndex, pStartLine, pDroppedOnLine if (pStartLine is not pDroppedOnLine) then SetLineOfIndex pOriginatingIndex, pDroppedOnLine send "RefreshList" to me in 0 secs end if end DragReorderDrop on dragMove set the dragaction to "move" end dragMove

