484 lines
14 KiB
Text
484 lines
14 KiB
Text
|
#lang scribble/manual
|
||
|
@(require (for-label racket))
|
||
|
|
||
|
@title{EZRanger}
|
||
|
A wrapper class for a label, a rangeslider, and numberboxes@section{categories}
|
||
|
GUI>EZ-GUI
|
||
|
@section{related}
|
||
|
Classes/EZGui, Classes/StaticText, Classes/Slider, Classes/NumberBox
|
||
|
|
||
|
@section{description}
|
||
|
|
||
|
EZRanger is wrapper class which creates an (optional) link::Classes/StaticText::, and a link::Classes/Slider:: plus a link::Classes/NumberBox::. If the parent is
|
||
|
@racketblock[nil::, then EZRanger will create its own window. See link::Classes/EZGui:: more options.
|
||
|
|
||
|
]
|
||
|
@section{subsection}
|
||
|
Scrolling and Arrow Keys
|
||
|
EZRanger's number boxs scroll by default, using the step size of the link::Classes/ControlSpec::. If the controlSpec's step is set to 0, or is not set, then the the stepping and scrolling will be guessed according to the
|
||
|
@racketblock[minval:: and ]
|
||
|
|
||
|
@racketblock[maxval:: values of the spec on creation of the view. Unlike the step variable of a regular link::Classes/NumberBox::, ]
|
||
|
|
||
|
@racketblock[controlSpec.step:: is also the smallest possible increment for the link::Classes/NumberBox::s. By default, the shift-key modifier will allow you to step by 100x ]
|
||
|
|
||
|
@racketblock[controlSpec.step::, while the ctrl-key will give you 10x ]
|
||
|
|
||
|
@racketblock[controlSpec.step::. Since the alt-key would give you 0.1 of the minimum step, it is disabled by default, but you can change that by setting ]
|
||
|
|
||
|
@racketblock[numberView.alt_step:: to any value you like. Accordingly you can customize the other modifiers to fit your needs. See link::Classes/NumberBox:: and link::Classes/Slider::. This also effects the arrow keys for the slider.
|
||
|
|
||
|
]
|
||
|
@section{classmethods}
|
||
|
|
||
|
|
||
|
@section{method}
|
||
|
new
|
||
|
|
||
|
@section{argument}
|
||
|
parent
|
||
|
The parent view or window. If the parent is nil, then EZRanger will create its own link::Classes/Window::, and place it conveniently on the screen if the bounds are a link::Classes/Point::. If the bounds are a link::Classes/Rect::, then the link::Classes/Rect:: determines the window bounds.
|
||
|
|
||
|
@section{argument}
|
||
|
bounds
|
||
|
An instance of link::Classes/Rect:: or link::Classes/Point::. Default value is
|
||
|
@racketblock[160@20::.
|
||
|
|
||
|
]
|
||
|
@section{argument}
|
||
|
label
|
||
|
The label. Default value is
|
||
|
@racketblock[nil::. If ]
|
||
|
|
||
|
@racketblock[nil::, then no link::Classes/StaticText:: is created.
|
||
|
|
||
|
]
|
||
|
@section{argument}
|
||
|
controlSpec
|
||
|
The link::Classes/ControlSpec:: for scaling the value.
|
||
|
|
||
|
@section{argument}
|
||
|
action
|
||
|
A link::Classes/Function:: called when the value changes. The function is passed the EZRanger instance as its argument.
|
||
|
|
||
|
@section{argument}
|
||
|
initVal
|
||
|
An instance of link::Classes/Array::
|
||
|
@racketblock[[lo, hi]::. If ]
|
||
|
|
||
|
@racketblock[nil::, then it uses the link::Classes/ControlSpec::'s default value.
|
||
|
|
||
|
]
|
||
|
@section{argument}
|
||
|
initAction
|
||
|
A link::Classes/Boolean:: indicating whether the action function should be called when setting the initial value. The default is
|
||
|
@racketblock[false::.
|
||
|
|
||
|
]
|
||
|
@section{argument}
|
||
|
labelWidth
|
||
|
Number of pixels width for the label. default is 60.
|
||
|
|
||
|
@section{argument}
|
||
|
numberWidth
|
||
|
Number of pixels width for the number box. default is 45.
|
||
|
|
||
|
@section{argument}
|
||
|
unitWidth
|
||
|
Number of pixels width for the unit label. The default is 0. If 0, then no
|
||
|
@racketblock[unitLabel:: is created.
|
||
|
|
||
|
]
|
||
|
@section{argument}
|
||
|
labelHeight
|
||
|
The default is 20;
|
||
|
|
||
|
@section{argument}
|
||
|
layout
|
||
|
|
||
|
@racketblock[\vert::, ]
|
||
|
|
||
|
@racketblock[\line2::, or ]
|
||
|
|
||
|
@racketblock[\horz::. The default is ]
|
||
|
|
||
|
@racketblock[\horz::.
|
||
|
|
||
|
]
|
||
|
@section{argument}
|
||
|
gap
|
||
|
A link::Classes/Point::. By default, the view tries to get its parent's gap, otherwise it defaults to
|
||
|
@racketblock[2@2::. Setting it overrides these.
|
||
|
|
||
|
]
|
||
|
@section{argument}
|
||
|
margin
|
||
|
A link::Classes/Point::. This will inset the bounds occupied by the subviews of view.
|
||
|
|
||
|
@section{discussion}
|
||
|
|
||
|
|
||
|
@racketblock[
|
||
|
(
|
||
|
w = Window.new.front;
|
||
|
g = EZRanger(w, 400@16," test ", \freq, { |v| v.value.postln }, [50,2000], unitWidth:30)
|
||
|
)
|
||
|
|
||
|
// Simplest version, no parent view, so a window is created
|
||
|
(
|
||
|
EZRanger(nil, 400@16," test ", \freq, { |v| v.value.postln }, [50,2000])
|
||
|
)
|
||
|
::
|
||
|
The contained views can be accessed via the EZRanger instance variables: ]
|
||
|
|
||
|
@racketblock[rangeSlider::, ]
|
||
|
|
||
|
@racketblock[hiBox::, ]
|
||
|
|
||
|
@racketblock[loBox::, ]
|
||
|
|
||
|
@racketblock[unitView::, ]
|
||
|
|
||
|
@racketblock[labelView::.
|
||
|
|
||
|
]
|
||
|
@section{instancemethods}
|
||
|
|
||
|
|
||
|
@section{subsection}
|
||
|
Accessing Instance and Class Variables
|
||
|
|
||
|
@section{method}
|
||
|
unitView
|
||
|
The units label. Only appears if
|
||
|
@racketblock[unitWidth:: was set to > 0.
|
||
|
|
||
|
]
|
||
|
@section{method}
|
||
|
controlSpec
|
||
|
An instance of ControlSpec for scaling the values.
|
||
|
|
||
|
@section{method}
|
||
|
loBox
|
||
|
The
|
||
|
@racketblock[lo:: value link::Classes/NumberBox::.
|
||
|
|
||
|
]
|
||
|
@section{method}
|
||
|
action
|
||
|
Set/get a link::Classes/Function:: or link::Classes/Function@section{List}
|
||
|
to be evaluated when the value changes. The first argument will be the EZRanger.
|
||
|
|
||
|
@section{method}
|
||
|
rangeSlider
|
||
|
The link::Classes/RangeSlider:: link::Classes/View::
|
||
|
|
||
|
@section{method}
|
||
|
lo
|
||
|
Set/get the low value.
|
||
|
|
||
|
@section{method}
|
||
|
hi
|
||
|
Set/get the high value
|
||
|
|
||
|
@section{method}
|
||
|
hiBox
|
||
|
The hi value link::Classes/NumberBox::.
|
||
|
|
||
|
@section{method}
|
||
|
round
|
||
|
Rounds the values in the number boxes.
|
||
|
|
||
|
@section{subsection}
|
||
|
Doing Some Task (optional)
|
||
|
|
||
|
@section{method}
|
||
|
doAction
|
||
|
Performs the action at the current index and the global action.
|
||
|
|
||
|
@section{method}
|
||
|
value
|
||
|
Gets/sets the
|
||
|
@racketblock[lo:: and ]
|
||
|
|
||
|
@racketblock[hi:: values.
|
||
|
]
|
||
|
@section{argument}
|
||
|
vals
|
||
|
An instance of link::Classes/Array::
|
||
|
@racketblock[ [lo, hi] ::.
|
||
|
|
||
|
]
|
||
|
@section{method}
|
||
|
valueAction
|
||
|
Sets the value and performs the action at the index value and the global action.
|
||
|
@section{argument}
|
||
|
vals
|
||
|
An instance of link::Classes/Array::
|
||
|
@racketblock[ [lo, hi] ::.
|
||
|
|
||
|
]
|
||
|
@section{subsection}
|
||
|
Changing Appearance
|
||
|
|
||
|
@section{method}
|
||
|
setColors
|
||
|
@section{argument}
|
||
|
stringBackground
|
||
|
An instance of link::Classes/Color::. The
|
||
|
@racketblock[background:: of the label and unit views.
|
||
|
]
|
||
|
@section{argument}
|
||
|
stringColor
|
||
|
An instance of link::Classes/Color::. The
|
||
|
@racketblock[stringColor:: of the label and unit views.
|
||
|
]
|
||
|
@section{argument}
|
||
|
sliderColor
|
||
|
An instance of link::Classes/Color::. The slider
|
||
|
@racketblock[background::.
|
||
|
]
|
||
|
@section{argument}
|
||
|
numBackground
|
||
|
An instance of link::Classes/Color::. The
|
||
|
@racketblock[background:: of the number view.
|
||
|
]
|
||
|
@section{argument}
|
||
|
numStringColor
|
||
|
An instance of link::Classes/Color::. The
|
||
|
@racketblock[stringColor:: of the number view.
|
||
|
]
|
||
|
@section{argument}
|
||
|
numNormalColor
|
||
|
An instance of link::Classes/Color::. The
|
||
|
@racketblock[normalColor:: of the number view.
|
||
|
]
|
||
|
@section{argument}
|
||
|
numTypingColor
|
||
|
An instance of link::Classes/Color::. The
|
||
|
@racketblock[typingColor:: of the number view.
|
||
|
]
|
||
|
@section{argument}
|
||
|
knobColor
|
||
|
An instance of link::Classes/Color::. The
|
||
|
@racketblock[knobColor:: of the slider view.
|
||
|
]
|
||
|
@section{argument}
|
||
|
background
|
||
|
An instance of link::Classes/Color::. The
|
||
|
@racketblock[background:: of the enclosing view.
|
||
|
|
||
|
]
|
||
|
@section{method}
|
||
|
font
|
||
|
Set the Font used by all the views.
|
||
|
@section{argument}
|
||
|
font
|
||
|
An instance of link::Classes/Font::.
|
||
|
|
||
|
|
||
|
@section{examples}
|
||
|
|
||
|
|
||
|
@racketblock[
|
||
|
( // basic use
|
||
|
w=Window.new.front;
|
||
|
g=EZRanger(w, 400@16," test ", \freq,{|v| v.value.postln},[50,2000],unitWidth:30);
|
||
|
g.setColors(Color.grey,Color.white, Color.grey(0.7),Color.grey, Color.white, Color.yellow);
|
||
|
);
|
||
|
|
||
|
// lots of range sliders on a view
|
||
|
(
|
||
|
w=Window.new.front;
|
||
|
w.view.decorator=FlowLayout(w.view.bounds);
|
||
|
w.view.decorator.gap=1@1;
|
||
|
|
||
|
20.do{
|
||
|
g=EZRanger(w, 400@16," test ", \freq,{|v| v.value.postln},[50.rand,50+20000.rand],unitWidth:30)
|
||
|
.setColors(Color.grey,Color.white, Color.grey(0.7),Color.grey,Color.white, Color.white, Color.yellow)
|
||
|
.font_(Font("Helvetica",11));
|
||
|
|
||
|
};
|
||
|
);
|
||
|
|
||
|
Window.closeAll
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////
|
||
|
////////// click these parentheses to see all features and layouts
|
||
|
(
|
||
|
|
||
|
m=nil;
|
||
|
m=2@2; // comment for no margin
|
||
|
|
||
|
|
||
|
/////////////////
|
||
|
/// Layout \horz
|
||
|
|
||
|
( // all features, small font
|
||
|
g=EZRanger(nil, 400@16," freq ", \freq,
|
||
|
initVal:[100.rand,200+2000.rand],unitWidth:30, numberWidth:60,layout:\horz, margin:2@2);
|
||
|
g.setColors(Color.grey,Color.white, Color.grey(0.7),
|
||
|
Color.grey, Color.white, Color.yellow, background:Color.grey(0.7),
|
||
|
knobColor: HiliteGradient(Color.grey, Color.white));
|
||
|
g.window.bounds = g.window.bounds.moveBy(-180,50);
|
||
|
g.font_(Font("Helvetica",10));
|
||
|
);
|
||
|
|
||
|
( // no unitView
|
||
|
g=EZRanger(nil, 400@16," freq ", \freq,initVal:[100.rand,200+2000.rand],
|
||
|
unitWidth:0, numberWidth:60,layout:\horz, margin:2@2);
|
||
|
g.setColors(Color.grey,Color.white, Color.grey(0.7),
|
||
|
Color.grey, Color.white, Color.yellow, background:Color.grey(0.7),
|
||
|
knobColor: HiliteGradient(Color.grey, Color.white));
|
||
|
g.window.bounds = g.window.bounds.moveBy(-180, -20);
|
||
|
g.font_(Font("Helvetica",10));
|
||
|
);
|
||
|
( // no label, so use window name as label
|
||
|
g=EZRanger(nil, 400@16, nil, \freq,initVal:[100.rand,200+2000.rand],
|
||
|
unitWidth:0, numberWidth:60,layout:\horz, margin:2@2);
|
||
|
g.setColors(Color.grey,Color.white, Color.grey(0.7),
|
||
|
Color.grey, Color.white, Color.yellow, background:Color.grey(0.7),
|
||
|
knobColor: HiliteGradient(Color.grey, Color.white));
|
||
|
g.window.bounds = g.window.bounds.moveBy(-180, -90);
|
||
|
g.window.name="Freq";
|
||
|
g.font_(Font("Helvetica",10));
|
||
|
);
|
||
|
|
||
|
/////////////////
|
||
|
/// Layout \line2
|
||
|
|
||
|
( // all features
|
||
|
g=EZRanger(nil, 300@42," freq ", \freq,initVal:[100.rand,200+2000.rand],
|
||
|
unitWidth:30, numberWidth:60,layout:\line2, margin:2@2);
|
||
|
g.setColors(Color.grey,Color.white, Color.grey(0.7),
|
||
|
Color.grey, Color.white, Color.yellow, background:Color.grey(0.7),
|
||
|
knobColor: HiliteGradient(Color.grey, Color.white));
|
||
|
g.window.bounds = g.window.bounds.moveBy(-180,-160);
|
||
|
);
|
||
|
|
||
|
( // no unitView, with label
|
||
|
g=EZRanger(nil, 300@42," freq ", \freq,initVal:[100.rand,200+2000.rand],
|
||
|
unitWidth:0, numberWidth:60,layout:\line2, margin:2@2);
|
||
|
g.setColors(Color.grey,Color.white, Color.grey(0.7),
|
||
|
Color.grey, Color.white, Color.yellow, background:Color.grey(0.7),
|
||
|
knobColor: HiliteGradient(Color.grey, Color.white));
|
||
|
g.window.bounds = g.window.bounds.moveBy(-180,-260);
|
||
|
);
|
||
|
|
||
|
( // no label
|
||
|
g=EZRanger(nil, 300@42,nil, \freq, initVal:[100.rand,200+2000.rand],
|
||
|
unitWidth:30, numberWidth:60,layout:\line2, margin:2@2);
|
||
|
g.setColors(Color.grey,Color.white, Color.grey(0.7),
|
||
|
Color.grey, Color.white, Color.yellow, background:Color.grey(0.7),
|
||
|
knobColor: HiliteGradient(Color.grey, Color.white));
|
||
|
g.window.bounds = g.window.bounds.moveBy(-180,-360);
|
||
|
g.window.name="Freq";
|
||
|
);
|
||
|
|
||
|
( // no label, so use window name as label
|
||
|
g=EZRanger(nil, 150@42,nil, \freq,initVal:[100.rand,200+2000.rand],
|
||
|
unitWidth:0, numberWidth:60,layout:\line2, margin:2@2);
|
||
|
g.setColors(Color.grey,Color.white, Color.grey(0.7),
|
||
|
Color.grey, Color.white, Color.yellow, background:Color.grey(0.7),
|
||
|
knobColor: HiliteGradient(Color.grey, Color.white));
|
||
|
g.window.bounds = g.window.bounds.moveBy(-180,-460);
|
||
|
g.window.name="Freq";
|
||
|
);
|
||
|
|
||
|
/////////////////
|
||
|
/// Layout \vert
|
||
|
|
||
|
( // all features, small font
|
||
|
g=EZRanger(nil, 45@300," Vol ", \db.asSpec.step_(0.01),initVal:[-3-15.rand,-2.rand],
|
||
|
unitWidth:30, numberWidth:60,layout:\vert, margin:2@2);
|
||
|
g.setColors(Color.grey,Color.white, Color.grey(0.7),
|
||
|
Color.grey, Color.white, Color.yellow, background:Color.grey(0.7),
|
||
|
knobColor: HiliteGradient(Color.grey, Color.white,\h));
|
||
|
g.window.bounds = g.window.bounds.moveBy(250,50);
|
||
|
g.font_(Font("Helvetica",9));
|
||
|
);
|
||
|
( // no label, small font
|
||
|
g=EZRanger(nil, 45@300, nil, \db.asSpec.step_(0.01),initVal:[-3-15.rand,-2.rand],
|
||
|
unitWidth:30, numberWidth:60,layout:\vert, margin:2@2);
|
||
|
g.setColors(Color.grey,Color.white, Color.grey(0.7),
|
||
|
Color.grey, Color.white, Color.yellow, background:Color.grey(0.7),
|
||
|
knobColor: HiliteGradient(Color.grey, Color.white,\h));
|
||
|
g.window.bounds = g.window.bounds.moveBy(310,50);
|
||
|
g.font_(Font("Helvetica",9));
|
||
|
);
|
||
|
( // no Units small font
|
||
|
g=EZRanger(nil, 45@300, " Vol", \db.asSpec.step_(0.01),initVal:[-3-15.rand,-2.rand],
|
||
|
unitWidth:0, numberWidth:60,layout:\vert, margin:2@2);
|
||
|
g.setColors(Color.grey,Color.white, Color.grey(0.7),
|
||
|
Color.grey, Color.white, Color.yellow, background:Color.grey(0.7),
|
||
|
knobColor: HiliteGradient(Color.grey, Color.white,\h));
|
||
|
g.window.bounds = g.window.bounds.moveBy(370,50);
|
||
|
g.font_(Font("Helvetica",9));
|
||
|
);
|
||
|
( // no unitView, no units small font
|
||
|
g=EZRanger(nil, 45@300, nil, \db.asSpec.step_(0.01),initVal:[-3-15.rand,-2.rand],
|
||
|
unitWidth:0, numberWidth:60,layout:\vert, margin:2@2);
|
||
|
g.setColors(Color.grey,Color.white, Color.grey(0.7),
|
||
|
Color.grey, Color.white, Color.yellow, background:Color.grey(0.7),
|
||
|
knobColor: HiliteGradient(Color.grey, Color.white,\h));
|
||
|
g.window.bounds = g.window.bounds.moveBy(430,50);
|
||
|
g.font_(Font("Helvetica",9));
|
||
|
);
|
||
|
|
||
|
)
|
||
|
|
||
|
/////////////////
|
||
|
|
||
|
////Sound Example
|
||
|
|
||
|
|
||
|
( // example to explore a synthesis idea:
|
||
|
p = ProxySpace.push(s.boot);
|
||
|
|
||
|
q = q ? ();
|
||
|
q.freqRange = [200, 2000];
|
||
|
q.ampRange = [0.1, 1];
|
||
|
q.ringRange = [0.1, 10];
|
||
|
q.numRange = [3, 30];
|
||
|
|
||
|
q.soundfunc = { |dens=5|
|
||
|
Splay.ar(
|
||
|
Array.fill(exprand(q.numRange[0], q.numRange[1]).asInteger, {
|
||
|
Ringz.ar(
|
||
|
Dust.ar(dens),
|
||
|
exprand(q.freqRange[0], q.freqRange[1]),
|
||
|
exprand(q.ringRange[0], q.ringRange[1]),
|
||
|
exprand(q.ampRange[0], q.ampRange[1])
|
||
|
)
|
||
|
})
|
||
|
).distort
|
||
|
};
|
||
|
)
|
||
|
~plong.play;
|
||
|
|
||
|
~plong.fadeTime = 3;
|
||
|
~plong = q[\soundfunc];
|
||
|
|
||
|
(
|
||
|
w = Window("cow herd").front;
|
||
|
w.view.decorator_(FlowLayout(w.bounds.copy.moveTo(0, 0)));
|
||
|
|
||
|
Spec.add(\ring, [0.03, 30, \exp]);
|
||
|
Spec.add(\num, [3, 30, \exp, 1]);
|
||
|
|
||
|
EZRanger(w, 390@20, "numRange", \num, { |sl| q.numRange = sl.value; }, labelWidth: 65)
|
||
|
.round_(1);
|
||
|
|
||
|
EZRanger(w, 390@20, "freqRange", \freq, { |sl| q.freqRange = sl.value; }, q.freqRange, labelWidth: 65)
|
||
|
.round_(0.1);
|
||
|
EZRanger(w, 390@20, "ringRange", \ring, { |sl| q.ringRange = sl.value; }, q.ringRange, labelWidth: 65)
|
||
|
.round_(0.0001);
|
||
|
EZRanger(w, 390@20, "ampRange", \amp, { |sl| q.ampRange = sl.value; }, q.ampRange, labelWidth: 65)
|
||
|
.round_(0.0001);
|
||
|
Button(w, 190@20).states_([[\newSound]]).action_({~plong = q[\soundfunc] });
|
||
|
)
|
||
|
::
|
||
|
]
|
||
|
|
||
|
|