QcPenPrinter: no need to allocate QPrintDialog on heap
[supercollider.git] / HelpSource / Classes / EZNumber.schelp
blobb40b4728deebecaedff9131de1e9c44402b53800
1 class:: EZNumber
2 summary:: Wrapper class for label and number box
3 categories:: GUI>EZ-GUI
4 related:: Classes/NumberBox
6 description::
7 EZNumber is wrapper class which creates an (optional) link::Classes/StaticText::, and a link::Classes/NumberBox::.
9 subsection:: Some Important Issues Regarding NumberBox
10 If the parent is code::nil::, then EZNumber will create its own window. See link::Classes/EZGui:: more options.
12 subsection:: Scrolling and Arrow Keys
13 EZNumber scrolls 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 code::minval:: and code::maxval:: values of the spec on creation of the view.  Unlike the step variable of a regular link::Classes/NumberBox::, code::controlSpec.step:: is also the smallest possible increment for the EZNumber. By default, the shift-key modifier will allow you to step by 100 x code::controlSpec.step::, while the ctrl-key will give you 10x code::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 code::numberView.alt_step:: to any value you like. Accordingly you can customize the other modifiers to fit your needs. See link::Classes/NumberBox::.
15 classmethods::
16 method:: new
18 argument:: parent
19 The parent view or window. If the parent is nil, then EZNumber 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.
21 argument:: bounds
22 An instance of link::Classes/Rect:: or link::Classes/Point::. Default value is code::160@20::.
24 argument:: label
25 The label. Default value is code::nil::. If code::nil::, then no link::Classes/StaticText:: is created.
27 argument:: controlSpec
28 The link::Classes/ControlSpec:: for scaling the value.
30 argument:: action
31 A link::Classes/Function:: called when the value changes. The function is passed the EZNumber instance as its argument.
33 argument:: initVal
34 The value to initialize the slider and number box with. If code::nil::, then it uses the link::Classes/ControlSpec::'s default value.
36 argument:: initAction
37 A link::Classes/Boolean:: indicating whether the action function should be called when setting the initial value. The default is code::false::.
39 argument:: labelWidth
40 Number of pixels width for the label. The  default is 60. In the code::\horz:: layout, if you specify the code::numberWidth::, then the code::labelWidth:: is ignored and is set to the code::bounds.width - unitWidth - numberWidth::.
42 argument:: numberWidth
43 Number of pixels width for the number box. The  default is 45. In \line2 layout, numberWidth defaults to the bounds.width minus the unitWidth.
45 argument:: unitWidth
46 Number of pixels width for the unit label. The default is 0.  If code::unitWidth:: is 0, then no code::unitLabel:: is created. In the code::\line2:: layout, if you specify the code::numberWidth::, then the code::unitWidth:: is ignored and is set to the code::bounds.width - unitWidth - numberWidth::.
48 argument:: labelHeight
49 Default is 20;
51 argument:: layout
52 code::\line2::, or code::\horz::. The default is code::\horz::; code::\line2:: is a two line version.
54 argument:: gap
55 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.
57 argument:: margin
58 A link::Classes/Point::. This will inset the bounds occupied  by the subviews of view.
60 discussion::
61 code::
63 w = Window.new.front;
64 g = EZNumber(w,        // parent
65              150@20,   // bounds
66              " test ", // label
67              \freq,    // controlSpec
68              { |ez| (ez.value.asString ++" is the value of " ++ ez).postln }, // action
69              330,      // initValue
70              true      // initAction
72 g.setColors(Color.grey,Color.white);
76 // Simplest version, no parent view, so a window is created
78         g = EZNumber(label:" test ", controlSpec: \amp.asSpec.step_(0.01) );
79         g.action_({ |ez| (ez.value.asString ++" is the value of " ++ ez).postln });
83 The contained views can be accessed via the EZNumber instance variables: code::labelView::, code::numberView::.
85 instancemethods::
87 method:: numberView
88 Returns the numberView
90 method:: action
91 A function to be evaluated when the value changes. Te first argument will be the EZNumber.
92 argument:: arg1
93 An instance of link::Classes/Function:: or link::Classes/FunctionList::. Default value is nil.
95 method:: value
96 The value of the slider
98 method:: round
99 Rounds the values in the number box.
100 argument:: arg1
102 method:: controlSpec
103 An instance of link::Classes/ControlSpec:: for scaling the values.
104 argument:: arg1
106 method:: value
107 Gets/sets the list/menu to the index at value. Does not perform the action.
108 argument:: val
109 An link::Classes/Integer::.
111 valueAction
112 Sets the value and performs the action at the index value and the global action.
113 argument:: val
114 An link::Classes/Integer::.
116 method:: doAction
117 Performs the action at the current index and the global action.
119 method:: set
120 Set the args after creation.
121 argument:: label
122 argument:: spec
123 argument:: argAction
124 argument:: initVal
125 argument:: initAction
127 method:: enabled
128 Sets/gets if the list is enabled.
129 argument:: bool
130 An instance of link::Classes/Boolean::. Default is code::true::.
133 subsection:: Changing Appearance
135 method:: setColors
136 argument:: stringBackground
137 An instance of link::Classes/Color::. The code::background:: of the label and unit views.
138 argument:: stringColor
139 An instance of link::Classes/Color::. The code::stringColor:: of the label and unit views.
140 argument:: numBackground
141 An instance of link::Classes/Color::. The code::background:: of the number view.
142 argument:: numStringColor
143 An instance of link::Classes/Color::. The code::stringColor:: of the number view.
144 argument:: numNormalColor
145 An instance of link::Classes/Color::. The code::normalColor:: of the number view.
146 argument:: numTypingColor
147 An instance of link::Classes/Color::. The code::typingColor:: of the number view.
148 argument:: background
149 An instance of link::Classes/Color::. The code::background:: of the enclosing view.
151 method:: font
152 Set the link::Classes/Font:: used by all the views.
153 argument:: font
154 An instance of link::Classes/Font::.
157 examples::
158 code::
159 // Simplest version
160 (               // basic use
161                 w=Window.new.front;
162                 g=EZNumber(w, 170@16," test  ", \freq,unitWidth:30, numberWidth:60,layout:\horz);
163                 g.setColors(Color.grey,Color.white);
167 // lots of numberviews on on view
169 w=Window.new.front;
170 w.view.decorator=FlowLayout(w.view.bounds);
171 w.view.decorator.gap=2@2;
173 40.do{
174                 g=EZNumber(w, 170@16," test  ", \freq,unitWidth:30, numberWidth:60,layout:\horz);
175                 g.setColors(Color.grey,Color.white, Color.grey(0.8));
180 // click these parentheses to see all features and layouts
183 m=nil;
184 m=2@2;          //comment for no margin
186 /////////////////
187 /// Layout \horz
189 (               // all features
190                 g=EZNumber(nil, 170@20," freq  ", \freq,unitWidth:30, numberWidth:60,layout:\horz,margin:m);
191                 g.setColors(Color.grey,Color.white,background: Color.grey(0.7));
192                 g.window.bounds = g.window.bounds.moveBy(-180,50);
195 (               // no unitView
196                 g=EZNumber(nil, 170@20," freq  ", \freq,unitWidth:0, numberWidth:60,layout:\horz,margin:m);
197                 g.setColors(Color.grey,Color.white,background: Color.grey(0.7));
198                 g.window.bounds = g.window.bounds.moveBy(-180, -20);
201 (               // no label, with unit. use window name as label
202                 g=EZNumber(nil, 120@20,nil, \freq,unitWidth:30, numberWidth:60,layout:\horz,margin:m);
203                 g.setColors(Color.grey,Color.white,background: Color.grey(0.7));
204                 g.window.bounds = g.window.bounds.moveBy(-180, -90);
205                 g.window.name="Freq";
209 (               // no units, no label; use window name as label;
210                 g=EZNumber(nil, 120@20, nil, \freq,unitWidth:0, numberWidth:60,layout:\horz,margin:m);
211                 g.setColors(Color.grey,Color.white,background: Color.grey(0.7));
212                 g.window.bounds = g.window.bounds.moveBy(-180, -160);
213                 g.window.name="Freq";
216 /////////////////
217 /// Layout \line2
219 (               // all features
220                 g=EZNumber(nil, 120@42," freq  ", \freq,unitWidth:30, numberWidth:60,layout:\line2,margin:m);
221                 g.setColors(Color.grey,Color.white,background: Color.grey(0.7));
222                 g.window.bounds = g.window.bounds.moveBy(100,50);
225 (               // no unitView, with label
226                 g=EZNumber(nil, 170@42," freq  ", \freq,unitWidth:0, numberWidth:60,layout:\line2,margin:m);
227                 g.setColors(Color.grey,Color.white,background: Color.grey(0.7));
228                 g.window.bounds = g.window.bounds.moveBy(100, -50);
230 (               // no unitView, no label; use window name as label
231                 g=EZNumber(nil, 170@20,nil, \freq,unitWidth:0, numberWidth:60,layout:\line2,margin:m);
232                 g.setColors(Color.grey,Color.white,background: Color.grey(0.7));
233                 g.window.bounds = g.window.bounds.moveBy(100,-150);
234                 g.window.name="Freq";
242 // Sound example
244 // start server
245 s.waitForBoot({
247         var w, startButton, noteControl, cutoffControl, resonControl;
248         var balanceControl, ampControl;
249         var node, cmdPeriodFunc;
251         // define a synth
252         SynthDef("window-test", { arg note = 36, fc = 1000, rq = 0.25, bal=0, amp=0.4, gate = 1;
253                         var x;
254                         x = Mix.fill(4, {
255                                 LFSaw.ar((note + {0.1.rand2}.dup).midicps, 0, 0.02)
256                         });
257                         x = RLPF.ar(x, fc, rq).softclip;
258                         x = RLPF.ar(x, fc, rq, amp).softclip;
259                         x = Balance2.ar(x[0], x[1], bal);
260                         x = x * EnvGen.kr(Env.cutoff, gate, doneAction: 2);
261                         Out.ar(0, x);
262                 }, [0.1, 0.1, 0.1, 0.1, 0.1, 0]
263         ).add;
267         // make the window
268         w = Window("another control panel", Rect(200, 400, 300, 180));
269         w.front; // make window visible and front window.
270         w.view.decorator = FlowLayout(w.view.bounds);
272         w.view.background = Color.rand;
274         // add a button to start and stop the sound.
275         startButton = Button(w, 75 @ 20);
276         startButton.states = [
277                 ["Start", Color.black, Color.green],
278                 ["Stop", Color.white, Color.red]
279         ];
280         startButton.action = {|view|
281                         if (view.value == 1) {
282                                 // start sound
283                                 node = Synth( "window-test", [
284                                         "note", noteControl.value,
285                                         "fc", cutoffControl.value,
286                                         "rq", resonControl.value,
287                                         "bal", balanceControl.value,
288                                         "amp", ampControl.value.dbamp ]);
289                         } {
290                                 // set gate to zero to cause envelope to release
291                                 node.release; node = nil;
292                         };
293         };
295         // create controls for all parameters
296         w.view.decorator.nextLine;
297         noteControl = EZNumber(w, 160 @ 20, "Note ", ControlSpec(24, 60, \lin, 1),
298                 {|ez| node.set( "note", ez.value )}, 36);
300         w.view.decorator.nextLine;
301         cutoffControl = EZNumber(w, 160 @ 20, "Cutoff ", ControlSpec(200, 5000, \exp),
302                 {|ez| node.set( "fc", ez.value )}, 1000);
304         w.view.decorator.nextLine;
305         resonControl = EZNumber(w, 160 @ 20, "Reson", ControlSpec(0.1, 0.7),
306                 {|ez| node.set( "rq", ez.value )}, 0.2);
308         w.view.decorator.nextLine;
309         balanceControl = EZNumber(w, 160 @ 20, "Balance ", \bipolar,
310                 {|ez| node.set( "bal", ez.value )}, 0);
312         w.view.decorator.nextLine;
313         ampControl = EZNumber(w, 160 @ 20, "Amp ", \db,
314                 {|ez| node.set( "amp", ez.value.dbamp )}, -6);
317         // set start button to zero upon a cmd-period
318         cmdPeriodFunc = { startButton.value = 0; };
319         CmdPeriod.add(cmdPeriodFunc);
321         // stop the sound when window closes and remove cmdPeriodFunc.
322         w.onClose = {
323                 node.free; node = nil;
324                 CmdPeriod.remove(cmdPeriodFunc);
325         };