linux: shared memory interface - link with librt
[supercollider.git] / HelpSource / Classes / EZKnob.schelp
blobf694485b4c1875d63a395aab172c931ace0ff235
1 class:: EZKnob
2 summary:: Wrapper class for label, knob, number box
3 categories:: GUI>EZ-GUI
4 related:: Classes/Knob, Classes/NumberBox, Classes/StaticText, Classes/CompositeView, Classes/EZGui
6 description::
7 EZKnob is wrapper class which creates an (optional) link::Classes/StaticText::, and a link::Classes/Knob:: plus a link::Classes/NumberBox::. If the parent is nil, then EZKnob will create its own window. See link::Classes/EZGui:: more options.
9 subsection:: Some Important Issues Regarding NumberBox
11 warning::
12 EZKnob replaces the EZKnob Quark, which is now called EZKnobOld.  It is encouraged to update your code. The two classes have different creation methods and approaches, particularly concerning the strong::dimensions:: (now strong::bounds::). To make the conversion process easier,  EZKnobOld has an instance method called convert which will post the equivallent creation code for the new EZKnob.
15 note::
16 Bounds: Make certain to choose bounds that are large enough to encompass the knob, the number box, and the label (if you use one), otherwise you may get confusing results. See the examples below.
19 classmethods::
21 method:: new
23 argument:: parent
24 The parent view or window. If the parent is nil, then EZKnob 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.
26 argument:: bounds
27 An instance of link::Classes/Rect:: or link::Classes/Point::. Default value is code::160@20::.  Make certain to choose bounds that are large enough to encompass the knob, the number box, and the label (if you use one), otherwise you may get confusing results. See the examples below.
29 argument:: label
30 The label. Default value is nil. If nil, then no link::Classes/StaticText:: is created.
32 argument:: controlSpec
33 The link::Classes/ControlSpec:: for scaling the value.  If the code::minVal + maxVal:: of the spec is 0, then code::centered:: will be set to true automatically.
35 argument:: action
36 A link::Classes/Function:: called when the value changes. The function is passed the EZKnob instance as its argument.
38 argument:: initVal
39 The value to initialize the knob and number box with. If nil, then it uses the link::Classes/ControlSpec::'s default value.
41 argument:: initAction
42 A link::Classes/Boolean:: indicating whether the action function should be called when setting the initial value. The default is false.
44 argument:: labelWidth
45 Number of pixels width for the label. default is 60. This is only valid for the code::\horz:: layout.
47 argument:: knobSize
48 An instance of link::Classes/Point::.  It will adjust itself to maximize the space use of code::width/height::. By default, it uses the maximum availabel height, and adjusts the withd accordingly.
50 argument:: unitWidth
51 Number of pixels width for the unit label. Default is 0. If 0, then no unitLabel is created.
53 argument:: labelHeight
54 Default is 20.
56 argument:: layout
57 code::\vert::, code::vert2::,  code::\line2::, or code::\horz::. default is code::\vert::.
59 argument:: gap
60 A link::Classes/Point::. By default, the view tries to get its parent's gap, otherwise it defaults to code::2@2::. Setting it overrides these.
62 argument:: margin
63 A link::Classes/Point::. This will inset the bounds occupied  by the subviews of view.
65 discussion::
66 code::
68 w=Window.new.front;
69 g = EZKnob( w,        // parent
70             50@90,    // bounds
71             " test ", // label
72             \freq,    // controlSpec
73             { |ez| (ez.value.asString ++" is the value of " ++ ez).postln } // action
75 g.setColors(Color.grey, Color.white)
78 // Simplest version, no parent view, so a window is created
80         g = EZKnob(label:" test ");
81         g.action_({ |ez| (ez.value.asString ++" is the value of " ++ ez).postln });
84 The contained views can be accessed via the EZKnob instance variables: code::labelView::, code::knobView::, code::numberView::.
87 instancemethods::
89 subsection:: Accessing Instance Variables
91 method:: numberView
92 Returns:: the code::numberView::
94 method:: knobView
95 Returns:: the code::knobView::
97 method:: labelView
98 Set/get the code::labelView::
100 method:: action
101 A function to be evaluated when the value changes. Te first argument will be the EZKnob.
102 argument:: arg1
103 An instance of link::Classes/Function:: or link::Classes/FunctionList::. Default value is code::nil::.
105 method:: value
106 The value of the knob
108 method:: centered
109 Sets/gets whether the knob is in centered mode. See link::Classes/Knob::.
110 argument:: bool
112 method:: round
113 Rounds the values in the number box.
114 argument:: arg1
116 method:: controlSpec
117 An instance of link::Classes/ControlSpec:: for scaling the values.
118 argument:: arg1
120 method:: value
121 Gets/sets the list/menu to the index at value. Does not perform the action.
122 argument:: val
123 An link::Classes/Integer::.
125 method:: doAction
126 Performs the action at the current index and the global action.
128 method:: set
129 Set the args after creation. You can only set the label if it was not nil from the beginning.
130 argument:: label
131 argument:: spec
132 argument:: argAction
133 argument:: initVal
134 argument:: initAction
136 method:: visible
137 Sets/gets if the component views are visible.
138 argument:: bool
139 An instance of link::Classes/Boolean::. Default is code::true::.
141 subsection:: Changing Appearance
143 method:: setColors
144 argument:: stringBackground
145 An instance of link::Classes/Color::. The code::background:: of the label and unit views.
146 argument:: stringColor
147 An instance of link::Classes/Color::. The code::stringColor:: of the label and unit views.
148 argument:: numBackground
149 An instance of link::Classes/Color::. The code::numColor:: of the number view.
150 argument:: numStringColor
151 An instance of link::Classes/Color::. The code::stringColor:: of the number view.
152 argument:: numNormalColor
153 An instance of link::Classes/Color::. The code::normalColor:: of the number view.
154 argument:: numTypingColor
155 An instance of link::Classes/Color::. The code::typingColor:: of the number view.
156 argument:: knobColor
157 An instance of link::Classes/Color::. The code::knobColor:: of the knob view.
158 argument:: background
159 An instance of link::Classes/Color::. The code::background:: of the enclosing view.
161 method:: font
162 Set the Font used by all the views.
163 argument:: font
164 An instance of link::Classes/Font::.
166 examples::
168 code::
169 (       // basic use
170         w=Window.new.front;
171         g=EZKnob(w, 50@90," test  ", \freq,{|a| a.value.postln});
172         g.setColors(Color.grey,Color.white);
176 // lots of knobs on on view
178 w=Window.new.front;
179 w.view.decorator=FlowLayout(w.view.bounds);
180 w.view.decorator.gap=2@2;
182 20.do{
183         EZKnob(w, 180@24," Freq ", \freq,unitWidth:30,initVal:6000.rand,layout:\horz)
184         .setColors(Color.grey,Color.white)
185         .font_(Font("Helvetica",11));
190 Window.closeAll  // use this to close all the windows
192 /////////////////////////////////////////////////////////////////
193 ////////// click these parentheses to see all features and layouts
196 m=nil;
197 m=2@2;          // comment this for no margin
199 /////////////////
200 /// Layout \line2
202 (               // all features, small font
203                 g=EZKnob(nil, 128@40," freq  ", \freq,unitWidth:20,layout:\line2, margin: m);
204                 g.setColors(Color.grey,Color.white,Color.grey,
205                         Color.white, Color.yellow,nil,nil, Color.grey(0.7));
206                 g.window.bounds = g.window.bounds.moveBy(-180,50);
207                 g.font_(Font("Helvetica",10));
210 (               // no unitView
211                 g=EZKnob(nil, 118@40," freq  ", \freq,unitWidth:0,layout:\line2, margin: m);
212                 g.setColors(Color.grey,Color.white,Color.grey,
213                         Color.white, Color.yellow,nil,nil, Color.grey(0.7));
214                 g.window.bounds = g.window.bounds.moveBy(-180, -40);
216 (               // no label, so use window name as label
217                 g=EZKnob(nil, 118@30, nil, \freq,labelWidth:100, unitWidth:20,layout:\line2, margin: m);
218                 g.setColors(Color.grey,Color.white,Color.grey,
219                         Color.white, Color.yellow,nil,nil, Color.grey(0.7));
220                 g.window.bounds = g.window.bounds.moveBy(-180, -130);
221                 g.window.name="Freq";
224 /////////////////
225 /// Layout \horz
228 (               // all features
229                 g=EZKnob(nil, 200@28," freq  ", \freq,unitWidth:30,layout:\horz, margin: m);
230                 g.setColors(Color.grey,Color.white,Color.grey,
231                         Color.white, Color.yellow,nil,nil, Color.grey(0.7));
232                 g.window.bounds = g.window.bounds.moveBy(0,50);
235 (               // no unitView
236                 g=EZKnob(nil, 160@28," freq  ", \freq,layout:\horz, margin: m);
237                 g.setColors(Color.grey,Color.white,Color.grey,
238                         Color.white, Color.yellow,nil,nil, Color.grey(0.7));
239                 g.window.bounds = g.window.bounds.moveBy(0, -30);
241 (               // no label, so use window name as label
242                 g=EZKnob(nil, 120@28, nil, \freq ,layout:\horz, margin: m);
243                 g.setColors(Color.grey,Color.white,Color.grey,
244                         Color.white, Color.yellow,nil,nil, Color.grey(0.7));
245                 g.window.bounds = g.window.bounds.moveBy(0, -110);
246                 g.window.name="Freq";
251 /////////////////
252 /// Layout \vert
254 (               // all features
255                 g=EZKnob(nil, 82@82," freq  ", \freq,unitWidth:18,layout:\vert, margin: m);
256                 g.setColors(Color.grey,Color.white,Color.grey,
257                         Color.white, Color.yellow,nil,nil, Color.grey(0.7));
258                 g.font_(Font("Helvetica", 10));
259                 g.window.bounds = g.window.bounds.moveBy(220,50);
262 (               // no unitView, with label
263                 g=EZKnob(nil, 70@90," freq  ", \freq,unitWidth:0,layout:\vert, margin: m);
264                 g.setColors(Color.grey,Color.white,Color.grey,
265                         Color.white, Color.yellow,nil,nil, Color.grey(0.7));
266                 g.window.bounds = g.window.bounds.moveBy(220,-90);
269 (               // no label
270                 g=EZKnob(nil, 120@60,nil, \freq, unitWidth:30,layout:\vert, margin: m);
271                 g.setColors(Color.grey,Color.white,Color.grey,
272                         Color.white, Color.yellow,nil,nil, Color.grey(0.7));
273                 g.window.bounds = g.window.bounds.moveBy(220,-230);
274                 g.window.name="Freq";
277 (               // no lablel, so use window name as label
278                 g=EZKnob(nil, 120@60,nil, \freq,unitWidth:0,layout:\vert, margin: m);
279                 g.setColors(Color.grey,Color.white,Color.grey,
280                         Color.white, Color.yellow,nil,nil, Color.grey(0.7));
281                 g.window.bounds = g.window.bounds.moveBy(220,-340);
282                 g.window.name="Freq";
286 /////////////////
287 /// Layout \vert2
289 (               // all features
290                 g=EZKnob(nil, 82@82," freq  ", \freq,unitWidth:18,layout:\vert2, margin: m);
291                 g.setColors(Color.grey,Color.white,Color.grey,
292                         Color.white, Color.yellow,nil,nil, Color.grey(0.7));
293                 g.font_(Font("Helvetica", 10));
294                 g.window.bounds = g.window.bounds.moveBy(350,50);
297 (               // no unitView, with label
298                 g=EZKnob(nil, 70@90," freq  ", \freq,unitWidth:0,layout:\vert2, margin: m);
299                 g.setColors(Color.grey,Color.white,Color.grey,
300                         Color.white, Color.yellow,nil,nil, Color.grey(0.7));
301                 g.window.bounds = g.window.bounds.moveBy(350,-90);
304 (               // no label
305                 g=EZKnob(nil, 120@60,nil, \freq, unitWidth:30,layout:\vert2, margin: m);
306                 g.setColors(Color.grey,Color.white,Color.grey,
307                         Color.white, Color.yellow,nil,nil, Color.grey(0.7));
308                 g.window.bounds = g.window.bounds.moveBy(350,-230);
309                 g.window.name="Freq";
312 (               // no lablel, so use window name as label
313                 g=EZKnob(nil, 120@60,nil, \freq,unitWidth:0,layout:\vert2, margin: m);
314                 g.setColors(Color.grey,Color.white,Color.grey,
315                         Color.white, Color.yellow,nil,nil, Color.grey(0.7));
316                 g.window.bounds = g.window.bounds.moveBy(350,-340);
317                 g.window.name="Freq";
326 ///////////////////////////////////////////////////////////////
327 ///////////////////////////////////////////////////////////////
330 // Sound example
332 // start server
333 s.waitForBoot({
335 var w, startButton, noteControl, cutoffControl, resonControl;
336 var balanceControl, ampControl;
337 var node, cmdPeriodFunc;
339 // define a synth
340 SynthDef("window-test", { arg note = 36, fc = 1000, rq = 0.25, bal=0, amp=0.4, gate = 1;
341                 var x;
342                 x = Mix.fill(4, {
343                         LFSaw.ar((note + {0.1.rand2}.dup).midicps, 0, 0.02)
344                 });
345                 x = RLPF.ar(x, fc, rq).softclip;
346                 x = RLPF.ar(x, fc, rq, amp).softclip;
347                 x = Balance2.ar(x[0], x[1], bal);
348                 x = x * EnvGen.kr(Env.cutoff, gate, doneAction: 2);
349                 Out.ar(0, x);
350         }, [0.1, 0.1, 0.1, 0.1, 0.1, 0]
351 ).add;
356 // make the window
357 w = Window("another control panel", Rect(20, 400, 230, 250));
358 w.front; // make window visible and front window.
359 w.view.decorator = FlowLayout(w.view.bounds);
360 w.view.decorator.gap=2@2;
362 // add a button to start and stop the sound.
363 startButton = Button(w, 75 @ 20);
364 startButton.states = [
365         ["Start", Color.black, Color.green(0.7)],
366         ["Stop", Color.white, Color.red(0.7)]
368 startButton.action = {|view|
369                 if (view.value == 1) {
370                         // start sound
371                         node = Synth( "window-test", [
372                                 "note", noteControl.value,
373                                 "fc", cutoffControl.value,
374                                 "rq", resonControl.value,
375                                 "bal", balanceControl.value,
376                                 "amp", ampControl.value.dbamp ]);
377                 } {
378                         // set gate to zero to cause envelope to release
379                         node.release; node = nil;
380                 };
383 // create controls for all parameters
384 w.view.decorator.nextLine;
385 noteControl = EZKnob(w, 220 @ 32, "Note ", ControlSpec(24, 60, \lin, 1, 36, \note),
386         {|ez| node.set( "note", ez.value )}, unitWidth:30,layout:\horz)
387                 .setColors(Color.grey,Color.white, Color.grey(0.7),Color.grey, Color.white, Color.yellow);
389 w.view.decorator.nextLine;
390 cutoffControl = EZKnob(w, 220 @ 32, "Cutoff ", ControlSpec(200, 5000, \exp,0.01,1000,\Hz),
391         {|ez| node.set( "fc", ez.value )}, unitWidth:30,layout:\horz)
392                 .setColors(Color.grey,Color.white, Color.grey(0.7),Color.grey, Color.white, Color.yellow);
394 w.view.decorator.nextLine;
395 resonControl = EZKnob(w, 220 @ 32, "Reson ", ControlSpec(0.1, 0.7,\lin,0.001,0.2,\rq),
396         {|ez| node.set( "rq", ez.value )}, unitWidth:30,layout:\horz)
397                 .setColors(Color.grey,Color.white, Color.grey(0.7),Color.grey, Color.white, Color.yellow);
399 w.view.decorator.nextLine;
400 balanceControl = EZKnob(w, 220 @ 32, "Balance ", \bipolar,
401         {|ez| node.set( "bal", ez.value )},  unitWidth:30,layout:\horz)
402                 .setColors(Color.grey,Color.white, Color.grey(0.7),Color.grey, Color.white, Color.yellow);
404 w.view.decorator.nextLine;
405 ampControl = EZKnob(w, 220 @ 32, "Amp ", \db,
406         {|ez| node.set( "amp", ez.value.dbamp )}, -6, unitWidth:30,layout:\horz)
407                 .setColors(Color.grey,Color.white, Color.grey(0.7),Color.grey, Color.white, Color.yellow);
410 // set start button to zero upon a cmd-period
411 cmdPeriodFunc = { startButton.value = 0; };
412 CmdPeriod.add(cmdPeriodFunc);
414 // stop the sound when window closes and remove cmdPeriodFunc.
415 w.onClose = {
416         node.free; node = nil;
417         CmdPeriod.remove(cmdPeriodFunc);
423 //////////////////////////////
424 // more examples
425 // these mimick the original  EZKnob layout and colors
428 w = Window("EZKnob", Rect(380,400,300,180)).front;
429 w.view.decorator = FlowLayout(w.view.bounds);
430 k = EZKnob(w, 42 @ 74, "Knob", action: { arg knb; knb.value.postln; }, margin:2@2, labelHeight:16);
431 k.view.background_(Color.grey.alpha_(0.4));
433 k.centered_(true)
434 k.value=0.5;
435 k.visible_(false)
436 k.visible_(true)
438 k.enabled_(false)
439 k.value = 0.1
440 k.enabled
441 k.enabled_(true)
442 k.value = 0.25
445 w = Window("EZKnob", Rect(380,400,300,180)).front;
446 w.view.decorator = FlowLayout(w.view.bounds, gap: 1@1);
447 StaticText(w, (42 * 4 + 3) @ 16).string_("EZKnob Cluster").background_(Color.blue(0.1,0.1));
448 w.view.decorator.nextLine;
449 a = [
450                 EZKnob(w, 42 @ 74, "knob 1", margin:2@2, labelHeight:16),
451                 EZKnob(w, 42 @ 74, "knob 2", controlSpec: \freq, margin:2@2, labelHeight:16),
452                 EZKnob(w, 42 @ 74, "knob 3", controlSpec: \pan, margin:2@2, labelHeight:16).round_(0.001),
453                 EZKnob(w, 42 @ 74, "knob 4", controlSpec: \rq, margin:2@2, labelHeight:16)
454         ];
455 a.do{arg a;a.view.background_(Color.grey.alpha_(0.4))};
457 // a now holds the array of knobs
459 a[0].value
460 a[3].value_(0.5)
461 a.collect(_.value );