"Touchproof" (cap-only) MultiSlider code/hack for use as fad

Discuss Lemur and share techniques.
tdmusic
Newbie
Posts:13
Joined:28 Dec 2011 15:19
"Touchproof" (cap-only) MultiSlider code/hack for use as fad

Post by tdmusic » 29 Dec 2011 16:56

Hi all,

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>
To work with it, you can add as many as you like to your project, and then you also need to create a globally accessible script at the top level of the project tree (or somewhere where all the sliders can access it) called "touchproofSliderAction(msobj)" with the following content:

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);
}
I've done it this way so that the logic for the slider is kept in one place so e.g. if I find a bug, it can be corrected more easily. This seems like quite a good pattern (using get/set expression/attribute on a passed in object) for interfaces where complex logic is reused.

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

Post Reply