This would be for any widget types other than widgets with preset/static values (such as checkbox/button/combobox/etc). I’m mostly considering this for “slider” widgets, but I honestly didn’t consider all options yet.
snapback() would be a way to tell cabbage that when mouse input ceases on a widget, it should return to the widget’s default value. This behavior essentially mimics the common “pitchwheel” style behavior, but still allows for an arbitrary (non-center/assymetric) value to return to via the default set in the widget’s range().
For example, this widget should return to 50 when released: range(0,100,50), snapback(1)
And this widget should return to 0: range(0,100,0), snapback(1)
I used a commercial plugin that uses a widget in this fashion, and it seemed particularly useful in their specific use case… It had essentially an rslider snapped to 0, any negative values would pull an LPF down from 20k or the ceiling, and positive values pull a HPF up from 20hz or the floor… releasing the knob returns it to 0, aka no filtering).
That’s great, thanks! It will definitely work for what I had in mind.
But csound code has no idea about the widget’s default value, which I do think would be really useful. It would also require different instruments (or at least calls with different p4s etc) to allow widgets that snap to different values. I just think it’d just be much simpler for end users if being added to large projects, imported widget groups, etc etc… Maybe I’m just big on feature creep
But yes, it’s by no means a priority since it’s pretty easy to workaround, and in my particular case it will probably be a straightforward use of it.
For portability and flexibility I turned this into a pair of UDOs that outputs either k or a rate values, and added an optional “hold” channel that can be used to turn off snapping on the fly. This can be used in place of a channel read to get a value, for example: opcode SnapBack,k,iS iDefaultValue,SChanName xin kMouseDown chnget "MOUSE_DOWN_LEFT" kHold chnget strcat(SChanName,"hold") kValue init iDefaultValue if kMouseDown == 1 || kHold == 1 then kValue = chnget:k(SChanName) else chnset k(iDefaultValue), SChanName kValue = iDefaultValue endif xout kValue endop opcode SnapBack,a,iS iDefaultValue,SChanName xin kMouseDown chnget "MOUSE_DOWN_LEFT" kHold chnget strcat(SChanName,"hold") aValue init iDefaultValue if kMouseDown == 1 || kHold == 1 then aValue = chnget:a(SChanName) else chnset k(iDefaultValue), SChanName aValue = iDefaultValue endif xout aValue endop instr 1 kFlex SnapBack 0, "flex" printk2 kFlex endin
That will read the channel “flex” into a krate value named kFlex, snapping back to 0. Setting “flexhold” to 1 (via another widget or otherwise) would stop the snap back behavior.
I was already considering port and how to integrate is as “optional”… I’m using this to control freq of two filters, as described before… and an immediate snap that large can create some distortions with certain filters. I’ll probably take a crack at that next.