SmoothNumberBox

part of wslib



a Pen-based replacement for SCNumberBox, with extra styling options. 



SmoothNumberBox works the same way as a SCNumberBox but, as the name states, it looks smooth. SmoothNumberBox is a subclass of RoundNumberBox and shares all of its functionality. The difference is that SmoothNumberBox has no bevel by default. SmoothNumberBox was designed to be used alongside SmoothSlider and SmoothButton.


One of the extra features is the possibility to enter expressions into the box. These are automatically interpreted after hitting the enter key.


(

w = Window("SmoothNumberBox Example", Rect(100, 500, 400, 120)).front;

b = SmoothNumberBox(w, Rect(150, 10, 100, 20));

b.value = rrand(1,15);

b.action = {arg numb; numb.value.postln; };

f = { |keyStroke| {  

w.front; b.focus;

keyStroke.keyStroke; // enter a formula (through appleScript, part of wslib)

0.5.wait;

w.front; b.focus;

"\n".keyStroke; // press enter

}.r.play( AppClock );

};

)


f.( "1+1" ); // if this doesn't work, type these expressions in the SmoothNumberBox yourself

f.( "100*2" );

f.( "(5+1)**2" );


The behaviour can be customized using the interpretFunc and allowedChars variables. 

The default interpretFunc is:    { |string| string.interpret } 

The default allowedChars are:    "+-.eE*/()%"

Any typed char that is not in the allowedChars string will not show up in the box. The interpretFunc should usually return a Number, which is to be displayed in the numberbox. If the function returns nil the old value is kept. The interpretFunc allows for alternate interpretations of the entered data. For example it could detect unit types:


( // first run the example above

b.interpretFunc = { |string|

var ext;

ext = string.find( "dB" );

if( ext.notNil )

{ string[..ext-1].interpret  }

{ string.interpret.ampdb };

};

b.allowedChars = "+-.eE*/()% dB";

)


f.( "0.1" ); // regular values are now converted to dB's

f.( "0 dB" ); // trailing "dB" signs will be interpreted as straight dB's

f.( "-6 dB" );

f.( "0" );

f.( "1" );



The counterpart of this is the formatFunc. This is the function used to show the value in the numberbox. An example to add to the above would be the following:


// first run the examples above

b.formatFunc = { |value| value.round(0.001).asString + "dB"; };


Another feature of SmoothNumberBox is the charSelectIndex. This gives the ability to show a selection rectangle behind one of the characters displayed in the box. The example shows how this feature can be used:


(

w = Window("click a number and start dragging", Rect(100, 500, 400, 120)).front;

b = SmoothNumberBox(w, Rect(150, 10, 70, 20));

b.clipLo_(-999).clipHi_(1000).align_( \right );

b.formatFunc_({ |value|value.asStringWithFrac(4).preExtend(9, $  ); }); // fixed width string

c = [ 1000, 100, 10, 1, 0, 0.1, 0.01, 0.001, 0.0001 ]; // stepsizes


// mouse support

b.mouseDownAction = { |vw, x, y|

vw.charSelectIndex = vw.charIndexFromPoint( x@y, [4] );

vw.scroll_step = c[vw.charSelectIndex] ? 1;

vw.step = vw.scroll_step;

};


// arrow keys left/right to select char, up/down to change value

b.keyDownAction = { |vw, char, mod, unicode|

var res;

res = case { unicode == 16rF703 }

{ vw.charSelectIndex = (vw.charSelectIndex + 1).min(8); nil }

{ unicode == 16rF702 }

{ vw.charSelectIndex = (vw.charSelectIndex - 1).max(-1); nil }

{ true }

{ vw.defaultKeyDownAction( char, mod, unicode ); };

vw.step = c[vw.charSelectIndex] ? 1;

res;

};

)


Creation / Class Methods


*new (parent, bounds)

parent - The parent view.

bounds - An instance of Rect, or a Point indicating width@height.

(

w = Window("SmoothNumberBox Example", Rect(100, 500, 400, 120));

b = SmoothNumberBox(w, Rect(150, 10, 100, 20));

b.value = rrand(1,15);

b.action = {arg numb; numb.value.postln; };

w.front

)

Check the SCNumberBox helpfile for more examples and variable descriptions