EZSmoothSlider wrapper class for label, SmoothSlider, SmoothNumberBox
part of wslib
Inherits from: Object : EZGui : EZSlider
EZSmoothSlider is wrapper class which creates an (optional) StaticText, and a SmoothSlider plus a SmoothNumberBox. If the parent is nil, then EZSmoothSlider will create its own window. EZSmoothSlider behaves in the same way as EZSlider.
(
w = Window.new.front;
w.addFlowLayout;
z = EZSmoothSlider( w, // parent
390@20, // bounds
" test ", // label
\freq, // controlSpec
{|ez| (ez.value.asString ++" is the value of " ++ ez).postln} // action
);
z.setColors(Color.grey,Color.white)
);
// Simplest version, no parent view, so a window is created
(
z=EZSmoothSlider(label:" test ");
z.action_({|ez| (ez.value.asString ++" is the value of " ++ ez).postln});
);
(
w = Window().front;
w.addFlowLayout;
9.do({ |i|
EZSmoothSlider( w, 40@390, (i+1).digit2roman, layout: \vert )
.labelView.align_( \center );
});
)
Examples (converted from EZSlider)
( // basic use
w=Window.new.front;
g=EZSmoothSlider(w, 400@16," test ", \freq,unitWidth:30, numberWidth:60,layout:\horz);
g.setColors(Color.grey,Color.white);
);
g.view.enabled=false
// lots of sliders on on view
(
w=Window.new.front;
w.view.decorator=FlowLayout(w.view.bounds);
w.view.decorator.gap=2@2;
20.do{
EZSmoothSlider(w, 392@16," Freq ", \freq,unitWidth:30,initVal:6000.rand, numberWidth:60,layout:\horz)
.setColors(Color.grey,Color.white)
.font_(Font("Helvetica",11));
};
);
Window.closeAll // use this to close all the windows
/////////////////////////////////////////////////////////////////
////////// click these parentheses to see all features and layouts
(
m=nil;
//m=2@2; // uncomment this for margin
/////////////////
/// Layout \horz
( // all features, small font
g=EZSmoothSlider(nil, 400@14," freq ", \freq,unitWidth:30, numberWidth:60,layout:\horz, margin: m);
g.setColors(Color.grey,Color.white, Color.grey(0.7),Color.grey,
Color.white, Color.yellow);
g.window.bounds = g.window.bounds.moveBy(-180,50);
g.font_(Font("Helvetica",10));
);
( // no unitView
g=EZSmoothSlider(nil, 400@16," freq ", \freq,unitWidth:0, numberWidth:60,layout:\horz, margin: m);
g.setColors(Color.grey,Color.white, Color.grey(0.7),Color.grey,
Color.white, Color.yellow);
g.window.bounds = g.window.bounds.moveBy(-180, -20);
);
( // no label, so use window name as label
g=EZSmoothSlider(nil, 400@16, nil, \freq,unitWidth:0, numberWidth:60,layout:\horz, margin: m);
g.setColors(Color.grey,Color.white, Color.grey(0.7),Color.grey,
Color.white, Color.yellow);
g.window.bounds = g.window.bounds.moveBy(-180, -90);
g.window.name="Freq";
);
/////////////////
/// Layout \line2
( // all features
g=EZSmoothSlider(nil, 300@42," freq ", \freq,unitWidth:30, numberWidth:60,layout:\line2, margin: m);
g.setColors(Color.grey,Color.white, Color.grey(0.7),Color.grey,
Color.white, Color.yellow);
g.window.bounds = g.window.bounds.moveBy(-180,-160);
);
( // no unitView, with label
g=EZSmoothSlider(nil, 300@42," freq ", \freq,unitWidth:0, numberWidth:60,layout:\line2, margin: m);
g.setColors(Color.grey,Color.white, Color.grey(0.7),Color.grey,
Color.white, Color.yellow);
g.window.bounds = g.window.bounds.moveBy(-180,-260);
);
( // no label
g=EZSmoothSlider(nil, 300@42,nil, \freq, unitWidth:30, numberWidth:60,layout:\line2, margin: m);
g.setColors(Color.grey,Color.white, Color.grey(0.7),Color.grey,
Color.white, Color.yellow);
g.window.bounds = g.window.bounds.moveBy(-180,-360);
g.window.name="Freq";
);
( // no lablel, so use window name as label
g=EZSmoothSlider(nil, 150@42,nil, \freq,unitWidth:0, numberWidth:60,layout:\line2, margin: m);
g.setColors(Color.grey,Color.white, Color.grey(0.7),Color.grey,
Color.white, Color.yellow);
g.window.bounds = g.window.bounds.moveBy(-180,-460);
g.window.name="Freq";
);
/////////////////
/// Layout \vert
( // all features, small font
g=EZSmoothSlider(nil, 45@300," Vol ", \db.asSpec.step_(0.01),unitWidth:30, numberWidth:60,layout:\vert, margin: m);
g.setColors(Color.grey,Color.white, Color.grey(0.7),Color.grey,
Color.white, Color.yellow);
g.window.bounds = g.window.bounds.moveBy(250,50);
g.font_(Font("Helvetica",10));
);
( // no label, small font
g=EZSmoothSlider(nil, 45@300, nil, \db.asSpec.step_(0.01),unitWidth:30, numberWidth:60,layout:\vert, margin: m);
g.setColors(Color.grey,Color.white, Color.grey(0.7),Color.grey,
Color.white, Color.yellow);
g.window.bounds = g.window.bounds.moveBy(310,50);
g.font_(Font("Helvetica",10));
);
( // no Units small font
g=EZSmoothSlider(nil, 45@300, " Vol", \db.asSpec.step_(0.01),unitWidth:0, numberWidth:60,layout:\vert, margin: m);
g.setColors(Color.grey,Color.white, Color.grey(0.7),Color.grey,
Color.white, Color.yellow);
g.window.bounds = g.window.bounds.moveBy(370,50);
g.font_(Font("Helvetica",10));
);
( // no unitView, no Units small font
g=EZSmoothSlider(nil, 45@300, nil, \db.asSpec.step_(0.01),unitWidth:0, numberWidth:60,layout:\vert, margin: m);
g.setColors(Color.grey,Color.white, Color.grey(0.7),Color.grey,
Color.white, Color.yellow);
g.window.bounds = g.window.bounds.moveBy(430,50);
g.font_(Font("Helvetica",10));
);
)
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
// Sound example
(
// start server
s.waitForBoot({
var w, startButton, noteControl, cutoffControl, resonControl;
var balanceControl, ampControl;
var node, cmdPeriodFunc;
// define a synth
SynthDef("window-test", { arg note = 36, fc = 1000, rq = 0.25, bal=0, amp=0.4, gate = 1;
var x;
x = Mix.fill(4, {
LFSaw.ar((note + {0.1.rand2}.dup).midicps, 0, 0.02)
});
x = RLPF.ar(x, fc, rq).softclip;
x = RLPF.ar(x, fc, rq, amp).softclip;
x = Balance2.ar(x[0], x[1], bal);
x = x * EnvGen.kr(Env.cutoff, gate, doneAction: 2);
Out.ar(0, x);
}, [0.1, 0.1, 0.1, 0.1, 0.1, 0]
).load(s);
// make the window
w = Window("another control panel", Rect(20, 400, 440, 180));
w.front; // make window visible and front window.
w.view.decorator = FlowLayout(w.view.bounds);
w.view.decorator.gap=4@4;
// add a button to start and stop the sound.
startButton = SmoothButton(w, 75 @ 20);
startButton.states = [
["Start", Color.black, Color.green(0.7)],
["Stop", Color.white, Color.red(0.7)]
];
startButton.action = {|view|
if (view.value == 1) {
// start sound
node = Synth( "window-test", [
"note", noteControl.value,
"fc", cutoffControl.value,
"rq", resonControl.value,
"bal", balanceControl.value,
"amp", ampControl.value.dbamp ]);
} {
// set gate to zero to cause envelope to release
node.release; node = nil;
};
};
// create controls for all parameters
w.view.decorator.nextLine;
noteControl = EZSmoothSlider(w, 430 @ 20, "Note ", ControlSpec(24, 60, \lin, 1, 36, \note),
{|ez| node.set( "note", ez.value )}, unitWidth:30)
.setColors(Color.grey,Color.white, Color.grey(0.7),Color.grey, Color.white, Color.yellow);
w.view.decorator.nextLine;
cutoffControl = EZSmoothSlider(w, 430 @ 20, "Cutoff ", ControlSpec(200, 5000, \exp,0.01,1000,\Hz),
{|ez| node.set( "fc", ez.value )}, unitWidth:30)
.setColors(Color.grey,Color.white, Color.grey(0.7),Color.grey, Color.white, Color.yellow);
w.view.decorator.nextLine;
resonControl = EZSmoothSlider(w, 430 @ 20, "Reson ", ControlSpec(0.1, 0.7,\lin,0.001,0.2,\rq),
{|ez| node.set( "rq", ez.value )}, unitWidth:30)
.setColors(Color.grey,Color.white, Color.grey(0.7),Color.grey, Color.white, Color.yellow);
w.view.decorator.nextLine;
balanceControl = EZSmoothSlider(w, 430 @ 20, "Balance ", \bipolar,
{|ez| node.set( "bal", ez.value )}, unitWidth:30)
.setColors(Color.grey,Color.white, Color.grey(0.7),Color.grey, Color.white, Color.yellow);
w.view.decorator.nextLine;
ampControl = EZSmoothSlider(w, 430 @ 20, "Amp ", \db,
{|ez| node.set( "amp", ez.value.dbamp )}, -6, unitWidth:30)
.setColors(Color.grey,Color.white, Color.grey(0.7),Color.grey, Color.white, Color.yellow);
// set start button to zero upon a cmd-period
cmdPeriodFunc = { startButton.value = 0; };
CmdPeriod.add(cmdPeriodFunc);
// stop the sound when window closes and remove cmdPeriodFunc.
w.onClose = {
node.free; node = nil;
CmdPeriod.remove(cmdPeriodFunc);
};
});
)
// a variant of the above example so one can
// add new parameters and more views are created automatically
(
// start server
s.waitForBoot({
var w, startButton, sliders;
var node, cmdPeriodFunc;
var params, specs;
// define a synth
SynthDef("window-test", { arg note = 36, fc = 1000, rq = 0.25, bal = 0, amp=0.4, width=0, gate = 1;
var x;
x = Mix.fill(4, {
VarSaw.ar((note + {0.1.rand2}.dup).midicps, 0, width, 0.02)
});
x = RLPF.ar(x, fc, rq).softclip;
x = RLPF.ar(x, fc, rq, amp).softclip;
x = Balance2.ar(x[0], x[1], bal);
x = x * EnvGen.kr(Env.cutoff, gate, 5, doneAction: 2);
Out.ar(0, x);
}, [0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0]
).load(s);
params = ["note", "fc", "rq", "bal", "amp", "width"];
specs = [
ControlSpec(24, 60, \lin, 1, 36, \note),
ControlSpec(200, 5000, \exp,0.01,1000,\Hz),
ControlSpec(0.1, 0.7,\lin,0.001,0.2,\rq),
ControlSpec(-1, 1, \lin, 0, 0, \pan),
ControlSpec(0.0001, 2, \exp, 0, 0.3, \vol), // db spec acts weird, so use self made one
ControlSpec(0, 1, \lin, 0, 0.3, \width),
];
// make the window
w = Window("another control panel", Rect(20, 400, 440, 180));
w.front; // make window visible and front window.
w.view.decorator = FlowLayout(w.view.bounds);
w.view.decorator.gap=4@4;
// add a button to start and stop the sound.
startButton = SmoothButton(w, 75 @ 20);
startButton.states = [
["Start", Color.black, Color.green(0.7)],
["Stop", Color.white, Color.red(0.7)]
];
startButton.action = {|view|
var args;
if (view.value == 1) {
// start sound
params.do { |param, i|
args = args.add(param);
args = args.add(sliders[i].value)
};
node = Synth("window-test", args.postcs);
} {
// set gate to zero to cause envelope to release
node.release; node = nil;
};
};
// create controls for all parameters
w.view.decorator.nextLine;
sliders = params.collect { |param, i|
EZSmoothSlider(w, 430 @ 20, param, specs[i], {|ez| node.set( param, ez.value )})
.setColors(Color.grey,Color.white, Color.grey(0.7),Color.grey, Color.white, Color.yellow);
};
// set start button to zero upon a cmd-period
cmdPeriodFunc = { startButton.value = 0; };
CmdPeriod.add(cmdPeriodFunc);
// stop the sound when window closes and remove cmdPeriodFunc.
w.onClose = {
node.free; node = nil;
CmdPeriod.remove(cmdPeriodFunc);
};
})
)