Drag & drop listbox reordering
pb
This reordering function does not draw any neat visual cues (such as a thick line between items) to indicate the destination of the drag. Instead, the selected (darkened) row moves with the mouse while you depress the button.
Function OpenDragNDropExample()
Make/O/T/N=4 root:testList = {"item 1", "item 2", "item 3", "item 4"}
Make/O/N=4 root:testSel
DoWindow/K Panel_DragNDrop
Execute/Q "Panel_DragNDrop()"
End
Window Panel_DragNDrop() : Panel
PauseUpdate; Silent 1 // building window...
NewPanel /W=(350,125,650,325) as "Drag List Items Example"
ListBox list0,pos={1,2},size={298,197},proc=ListBoxProc_DragNDropLB
ListBox list0,listWave=root:testList,selWave=root:testSel,mode= 1,selRow= 1
EndMacro
Function ListBoxProc_DragNDropLB(lba) : ListBoxControl
STRUCT WMListboxAction &lba
Variable row = lba.row
Variable col = lba.col
WAVE/T/Z listWave = lba.listWave
WAVE/Z selWave = lba.selWave
switch( lba.eventCode )
case -1: // control being killed
break
case 1: // mouse down
Variable/G V_MouseDownRow = row
break
case 2: // mouse up
if(row != V_MouseDownRow) // dragged?
NVAR V_MouseDownRow
String item = listWave[V_MouseDownRow]
DeletePoints V_MouseDownRow, 1, listWave // do swap
InsertPoints row, 1, listWave
listWave[row] = item
endif
KillVariables V_MouseDownRow // cleanup variable
break
case 3: // double click
break
case 4: // cell selection
case 5: // cell selection plus shift key
break
case 6: // begin edit
break
case 7: // finish edit
break
endswitch
return 0
End
Make/O/T/N=4 root:testList = {"item 1", "item 2", "item 3", "item 4"}
Make/O/N=4 root:testSel
DoWindow/K Panel_DragNDrop
Execute/Q "Panel_DragNDrop()"
End
Window Panel_DragNDrop() : Panel
PauseUpdate; Silent 1 // building window...
NewPanel /W=(350,125,650,325) as "Drag List Items Example"
ListBox list0,pos={1,2},size={298,197},proc=ListBoxProc_DragNDropLB
ListBox list0,listWave=root:testList,selWave=root:testSel,mode= 1,selRow= 1
EndMacro
Function ListBoxProc_DragNDropLB(lba) : ListBoxControl
STRUCT WMListboxAction &lba
Variable row = lba.row
Variable col = lba.col
WAVE/T/Z listWave = lba.listWave
WAVE/Z selWave = lba.selWave
switch( lba.eventCode )
case -1: // control being killed
break
case 1: // mouse down
Variable/G V_MouseDownRow = row
break
case 2: // mouse up
if(row != V_MouseDownRow) // dragged?
NVAR V_MouseDownRow
String item = listWave[V_MouseDownRow]
DeletePoints V_MouseDownRow, 1, listWave // do swap
InsertPoints row, 1, listWave
listWave[row] = item
endif
KillVariables V_MouseDownRow // cleanup variable
break
case 3: // double click
break
case 4: // cell selection
case 5: // cell selection plus shift key
break
case 6: // begin edit
break
case 7: // finish edit
break
endswitch
return 0
End
Forum
Support
Gallery
Igor Pro 9
Learn More
Igor XOP Toolkit
Learn More
Igor NIDAQ Tools MX
Learn More
to
above.
January 30, 2010 at 03:05 pm - Permalink
January 30, 2010 at 04:36 pm - Permalink
I've figured out that one can tell if ctrl or cmd is pressed using getkeystate(0), but how does one test if the delete button or c,v,x buttons are being held down at the same time. They don't get reported in the event procedure and they don't appear in the cells.
January 30, 2010 at 11:48 pm - Permalink
January 31, 2010 at 11:27 am - Permalink
Actually, you guys have given me the idea that if you could properly code a nice, fancy window hook function, then you could have a sort of wrapper to convert a listbox to a drag-n-drop listbox (similar to how the WaveSelectorWidget has a function that transforms a button, popup, or listbox into the properly-functioning widget). Imagine something like MakeListboxDragNDrop(listboxName). It could set a hook that listens on mouse and keyboard events and uses ControlInfo to get necessary internal info, such as the selection. Then the user doesn't have to code all this stuff into a ListBoxProc on a listbox-by-listbox basis. It could also support various types of behavior (e.g., multi-row drag), based on the mode of the listbox.
This rapidly becomes quite complex, though, and illustrates why it'd be better if Igor could add drag-n-drop features in a later version. Not to knock WM at all, but I think I remember that LabView has a pretty nice drag-n-drop option on its listboxes (but maybe not with multi-row drag). I'm just sayin'... ;)
P.S. - @aclight, I like your idea to use the control's user data to store the starting row. I'm a geek for slick little tricks like that.
January 31, 2010 at 01:38 pm - Permalink
popupcontextual
menu with those options on it. However, I don't like using the mouse to do all those editing things, I would prefer to use the keyboard. Still having a way is better than having no way at all.January 31, 2010 at 11:37 pm - Permalink
I can pretty much promise you that in Igor x there will be the ability to have pretty drag and drop list boxes. The question is what the value of x is. :)
February 1, 2010 at 03:55 pm - Permalink
IgorMenuHook
, which might be appropriate for what you're trying to do. Here's the first sentence from the documentation: "IgorMenuHook is a user-defined function that Igor calls just before and just after menu selection (whether by mouse or keyboard)." I think you can trap "copy" and "paste" events with this.February 2, 2010 at 01:07 pm - Permalink