How to suppress output of SetVariableControl?
pmazzoni
I am building a control panel that includes a SetVariable control. Changing the value of this control triggers a procedure that moves the current selection in a table to the row indicated by the variable's new value:
Function moveCurrRow(sva) : setVariableControl
STRUCT WMSetVariableAction &sva
NVar gCurrEventRow
wave eventName
variable tableRows = numpnts(eventName)
if (gCurrEventRow >= tableRows)
gCurrEventRow -= 1
elseIf (gCurrEventRow < 0)
gCurrEventRow = 0
else
modifyTable /W=eventTable selection=(gCurrEventRow, 0, gCurrEventRow, 0, gCurrEventRow, 0)
endIf
End //MoveCurrRow
STRUCT WMSetVariableAction &sva
NVar gCurrEventRow
wave eventName
variable tableRows = numpnts(eventName)
if (gCurrEventRow >= tableRows)
gCurrEventRow -= 1
elseIf (gCurrEventRow < 0)
gCurrEventRow = 0
else
modifyTable /W=eventTable selection=(gCurrEventRow, 0, gCurrEventRow, 0, gCurrEventRow, 0)
endIf
End //MoveCurrRow
Every time I click on the control to increment or decrement the variable's value, I get the output below on the history window. How can I suppress this output?
STRUCT WMSetVariableAction
ctrlName[256]: currRowDisp
win[401]: eventMarking
winRect: STRUCT Rect
top: 0
left: 0
bottom: 800
right: 400
ctrlRect: STRUCT Rect
top: 140
left: 20
bottom: 154
right: 110
mouseLoc: STRUCT Point
v: 145
h: 108
eventCode: 9
eventMod: 1
userdata:
blockReentry: 0
isStr: 0
dval: 14
sval[2500]: 14
vName[1298]: gCurrEventRow
svWave: <null>
rowIndex: 0
rowLabel[256]:
colIndex: 0
colLabel[256]:
layerIndex: 0
layerLabel[256]:
chunkIndex: 0
chunkLabel[256]:
mousePart: 1
in fcn moveCurrRow: sva=
ctrlName[256]: currRowDisp
win[401]: eventMarking
winRect: STRUCT Rect
top: 0
left: 0
bottom: 800
right: 400
ctrlRect: STRUCT Rect
top: 140
left: 20
bottom: 154
right: 110
mouseLoc: STRUCT Point
v: 145
h: 108
eventCode: 9
eventMod: 1
userdata:
blockReentry: 0
isStr: 0
dval: 14
sval[2500]: 14
vName[1298]: gCurrEventRow
svWave: <null>
rowIndex: 0
rowLabel[256]:
colIndex: 0
colLabel[256]:
layerIndex: 0
layerLabel[256]:
chunkIndex: 0
chunkLabel[256]:
mousePart: 1
in fcn moveCurrRow: sva=
This is not the normal behavior of the SetVariable control, so I suppose the problematic behavior happens somewhere else in your code. Can you post a MWE (minimal working example), which compiles and shows the problematic behavior? Also, I see a few other issues with your setVariableControl function. For example, the function executes on all kinds of events such as just moving the mouse. I would restrict that to the relevant events (such as changing the value). Also, it is probably not a good idea in general to use global variables.
June 29, 2023 at 01:06 am - Permalink
"in fcn moveCurrRow: sva= "
You must have a function called "moveCurrRow" that is triggered when that code executes. Do you have a window hook on the table in question?
I guess gCurrEventRow is the global attached to the SetVariable that holds the value. That used to be the only way to use a SetVariable control, before the internal storage of the value was introduced, so it's natural that folks still use a global. These days, it is preferred to use the internal value rather than a global.
June 29, 2023 at 09:12 am - Permalink
Your GUI control procedure moveCurrRow should only execute the modifyTable code on a specific event. As it is right now the code is always executed even when moving the mouse over the control.
June 29, 2023 at 09:31 am - Permalink
Thank you everyone for your explanations. I now understand how to use the setvariablecontrol, i.e. using a switch...case statement based on the eventCode property. The control now works exactly as I had intended it to:
STRUCT WMSetVariableAction &sva
NVar gCurrEventRow
wave eventName
variable tableRows = numpnts(eventName)
switch (sva.eventCode)
case 1: // Mouse up
if (gCurrEventRow >= tableRows)
gCurrEventRow -= 1
beep
elseIf (gCurrEventRow < 0)
gCurrEventRow = 0
beep
else
modifyTable /W=eventTable selection=(gCurrEventRow, 0, gCurrEventRow, 0, gCurrEventRow, 0)
endIf
case 2: // Enter key
case 3: // Live update
Variable dval = sva.dval
String sval = sva.sval
break
case -1: // Control being killed
break
endswitch
return 0
End //MoveCurrRow
Regarding the suggested use of the internal value instead of a global, where can I find more information? Is it by any chance a new feature in Igor 9? I am still using Igor 8.
June 29, 2023 at 05:09 pm - Permalink
No problem. The feature of internal variables already exists for quite some years. Here is an excerpt of the manual:
I would also suggest to impose the limits of your table onto the SetVariable control itself instead of checking the limits in the control function (or does the size of the table change? You can of course also update the limits in this case):
SetVariable myTableCtrl ,value=_NUM:0 ,limits={0,numpnts(eventName),1}
Then your control function could be vastly simplified:
if (sva.eventCode == 1 || sva.eventCode == 2) // mouse up or enter
modifyTable/W=eventTable selection=(sva.dval, 0, sva.dval, 0, sva.dval, 0)
endif
return 0
End
June 29, 2023 at 07:13 pm - Permalink
In reply to No problem. The feature of… by chozo
That's a great idea. Thanks! Yes, the size of the table changes but I can update the setvariable's limits when this happens.
June 29, 2023 at 10:02 pm - Permalink