I've created a "touchproof" multi slider which can be used as a single fader - essentially, this works in the same way as the fader with "cap only" mode, but I've found the multislider is useful sometimes as it can be made smaller than the fader, it can be made bipolar and its minimal design can help reduce visual clutter. I've not implemented anything to do with more than 1 slider within the MultiSlider as I'm not currently using this in my project.
The idea is that if you touch the slider near to its current value, you can move it freely, but if you touch it a position outside of a "tolerance" zone, the touch is rejected and the slider stays at its previous value (after a brief flicker ).
Here's the jzlib (not cleaned up as I've pulled it out of a project but should be good enough to work with):
Code: Select all
<JZML>
<WINDOW class="MultiSlider" text="MultiSlider15" x="0" y="0" width="66" height="247" id="21" state="1" group="0" font="tahoma,10,0" send="1" osc_target="-2" midi_target="0" kbmouse_target="-2" bipolar="1" capture="1" color="1787903" gradient="1" grid="0" grid_steps="1" horizontal="0" label="0" multicolor="0" nbr="1" physic="0">
<PARAM name="x=" value="0.500000" send="17" osc_target="0" osc_trigger="1" osc_message="/EQFX/MultiSlider15/x" midi_target="-1" midi_trigger="1" midi_message="0xB5,0xB5,6,6" midi_scale="0,16383" osc_scale="0.000000,1.000000" kbmouse_target="-1" kbmouse_trigger="1" kbmouse_message="0,0,0" kbmouse_scale="0,1,0,1"/>
<VARIABLE name="tension=0.2" send="0" osc_target="0" osc_trigger="1" osc_message="/EQFX/MultiSlider15/tension" midi_target="-1" midi_trigger="1" midi_message="0x90,0x90,0,0" midi_scale="0,16383" kbmouse_target="-1" kbmouse_trigger="1" kbmouse_message="0,0,0" kbmouse_scale="0,1,0,1"/>
<VARIABLE name="friction=0.9" send="0" osc_target="0" osc_trigger="1" osc_message="/EQFX/MultiSlider15/friction" midi_target="-1" midi_trigger="1" midi_message="0x90,0x90,0,0" midi_scale="0,16383" kbmouse_target="-1" kbmouse_trigger="1" kbmouse_message="0,0,0" kbmouse_scale="0,1,0,1"/>
<VARIABLE name="height=0.5" send="0" osc_target="0" osc_trigger="1" osc_message="/EQFX/MultiSlider15/height" midi_target="-1" midi_trigger="1" midi_message="0x90,0x90,0,0" midi_scale="0,16383" kbmouse_target="-1" kbmouse_trigger="1" kbmouse_message="0,0,0" kbmouse_scale="0,1,0,1"/>
<VARIABLE name="light=0" send="0" osc_target="0" osc_trigger="1" osc_message="/EQFX/MultiSlider15/light" midi_target="-1" midi_trigger="1" midi_message="0x90,0x90,0,0" midi_scale="0,16383" kbmouse_target="-1" kbmouse_trigger="1" kbmouse_message="0,0,0" kbmouse_scale="0,1,0,1"/>
<VARIABLE name="outputX=0.5" send="17" osc_target="0" osc_trigger="1" osc_message="/EQFX/MultiSlider15/outputX" midi_target="0" midi_trigger="1" midi_message="0xB5,0xB5,6,6" midi_scale="0,16383" kbmouse_target="-1" kbmouse_trigger="1" kbmouse_message="0,0,0" kbmouse_scale="0,1,0,1"/>
<VARIABLE name="prevX={-1, -1}" send="1" osc_target="0" osc_trigger="1" osc_message="/EQFX/MultiSlider15/prevX" midi_target="-1" midi_trigger="1" midi_message="0x95,0x96,0,0" midi_scale="0,16383" kbmouse_target="-1" kbmouse_trigger="1" kbmouse_message="-1,0,0" kbmouse_scale="0,1,0,1"/>
<SCRIPT name="action()" script="touchproofSliderAction(getobject());" trigger_script="x" trigger_type="0" trigger="1" osc_message="/EQFX/MultiSlider15/action" midi_message="0x90,0x90,0,0" midi_target="-1" flag="1"/>
<SCRIPT name="updatePrevX()" script="prevX[1] = prevX[0];
prevX[0] = x;" trigger_script="" trigger_type="1" trigger="1" osc_message="/EQFX/MultiSlider15/updatePrevX" midi_message="0x90,0x90,0,0" midi_target="-1" flag="1"/>
</WINDOW>
</JZML>
touchproofSliderAction(msobj):
Code: Select all
decl tolerance = 0.2;
if(getexpression(msObj, 'tolerance')) {
tolerance = getexpression(msObj, 'tolerance');
}
decl prevX = getexpression(msObj, 'prevX');
decl x = getexpression(msObj, 'x');
decl outputX = getexpression(msObj, 'outputX');
// If we are moving the fader, or the touch is within the tolerance zone, accept the touch
// otherwise reject it
if((prevX[0] != prevX[1]) || (x <= outputX + tolerance && x >= outputX - tolerance)) {
setexpression(msObj, 'outputX', x);
} else {
setexpression(msObj, 'x', outputX);
}
To set the MIDI target for the slider, you need to change the MIDI mapping for the "outputX" expression, rather than "x" - this is so we only send out a value when we want to, rather than sending out whatever value you touch.
The global tolerance can be adjusted in the script above (currently 0.2), or overridden on a per-slider basis by creating an expression called "tolerance" within the MultiSlider object and giving it a value (so e.g. a tolerance of 0.1 would mean you have to touch within 10% of the original value or your touch will be rejected).
Hope this is useful to some people… it's been useful for me in figuring out ways to override the default behaviour of objects and how to hack some relatively complex/OO-style code out of the limited scripting language… I've got lots more ideas for the future
One other thing - could anyone from Liine comment on memory/CPU usage within the app? Is doing things like this (passing objects around, updating vectors on frame etc.) multiple times per-project potentially going to be problematic on the iPad or is there plenty of headroom?
Cheers,
Tom