3 summary:: A rotary controller view
5 related:: Classes/Slider, Classes/Slider2D
9 Knob displays a value from 0.0 to 1.0 in rotary fashon, and allows to control it with either circular or linear mouse motion.
11 It also displays the deviation of the value from either 0.0 or 0.5, which you can choose using link::#-centered::.
13 To switch between the mouse interaction modes, use link::#-mode::.
15 The amount by which the value changes at interaction can be fine-tuned using link::#-step::, link::#-keystep::, link::#-shift_scale::, link::#-ctrl_scale::, and link::#-alt_scale::
23 The default link::#-mode:: for newly created Knobs.
36 A Number in the range of 0.0 to 1.0.
40 Sets the value and triggeres link::#-action::.
43 Increments the value by link::#-keystep:: multiplied by the argument.
49 Decrements the value by link::#-keystep:: multiplied by the argument.
55 SUBSECTION:: Interaction
59 The way value is controlled with respect to mouse movement after clicking on the view:
61 ## code::\round:: - value follows circular movement
62 ## code::\horiz:: - value follows linear movement in horizontal direction
63 ## code::\vert:: - value follows linear movement in vertical direction
66 Defaults to code::\round::.
69 One of the symbols listed above.
73 The amount by which the value is incremented/decremented when pressing a relevant key.
82 The amount by which the value is incremented/decremented using the mouse in 'horizontal' and 'vertical' link::#-mode#modes::.
88 The factor by which link::#-step:: or link::#-keystep:: is multiplied when used at mouse or keyboard interaction while the Shift key is pressed.
94 The factor by which link::#-step:: or link::#-keystep:: is multiplied when used at mouse or keyboard interaction while the Ctrl key is pressed.
100 The factor by which link::#-step:: or link::#-keystep:: is multiplied when used at mouse or keyboard interaction while the Alt key is pressed.
107 SUBSECTION:: Appearance
111 Whether the deviation of value will be displayed in relation to 0.0 or 0.5 (e.g. as in a panning controller);
118 The colors used by the Knob to draw the following elements:
121 ## the main Knob color
122 ## the value indicator
123 ## the deviation indicator
124 ## the background of the deviation indicator
128 An Array of four Colors in the order listed above.
134 The action object evaluated whenever the user interacts with the Knob using the mouse or the keyboard.
136 METHOD:: defaultKeyDownAction
138 Implements the default effects of key presses as follows:
141 ## strong::Key:: || strong::Effect::
142 ## r || valueAction_(1.0.rand)
143 ## n || valueAction_(0)
144 ## x || valueAction_(1)
145 ## c || valueAction_(0.5)
148 ## up arrow || increment
149 ## down arrow || decrement
150 ## right arrow || increment
151 ## left arrow || decrement
154 See also: link::#-keystep::, link::#-shift_scale::, link::#-ctrl_scale::, link::#-alt_scale::.
156 SUBSECTION:: Drag and drop
158 METHOD:: defaultGetDrag
162 METHOD:: defaultCanReceiveDrag
164 True if the current drag data is a Number.
166 METHOD:: defaultReceiveDrag
167 Sets link::#-valueAction:: to the current drag data.
172 subsection:: Basic Example
176 var window, size = 32; // try different sizes - from 15 to 200 or more!
177 window = Window.new("Knob", Rect(640,630,270,70)).front;
178 k = Knob.new(window, Rect(20, 10, size, size));
179 k.action_({|v,x,y,m| postf("action func called: %\n", v.value); });
180 //k.color[1] = Color.gray(alpha:0);
185 k.valueAction = 0.125
190 k.mode = \round; // default
202 subsection:: Centered Mode
204 Center mode is useful for pan or eq gain control etc.
209 window = Window.new("Pan Knob", Rect(640,630,270,70)).front;
210 k = Knob.new(window, Rect(20,10,36,36));
211 k.action_({|v,x,y,m| \pan.asSpec.map(v.value).postln; })
214 .value_(\pan.asSpec.unmap(0)); // 0.5
215 //k.color[1] = Color.gray(alpha:0);
225 link::#-step:: only affects the 'horiz' and 'vert' modes:
229 var window, midispec;
230 midispec = [0,127,'linear',1].asSpec;
231 window = Window.new("step Knob", Rect(640,630,270,70)).front;
232 k = Knob.new(window, Rect(20,10,32,32));
233 k.action_({|v,x,y,m| midispec.map(v.value).postln; })
234 .value_(midispec.unmap(0));
240 k.step = 10/127 // step by 10
247 subsection:: mouseOverAction
252 w = Window.new("Knobs", Rect(250,500,270,70));
253 w.acceptsMouseOver=true; // must be true in parent window!
254 w.view.decorator = FlowLayout(w.view.bounds);
255 h = StaticText(w, 150 @ 20);
256 w.view.decorator.nextLine;
260 knob = Knob.new(w, size @ size)
261 .action_({|v,x,y,m| h.string = "val: " ++ v.value.asString; })
262 .mouseOverAction_({|v,x,y| h.string = "val: " ++ v.value.asString; });
272 subsection:: Drag and Drop
276 var w, txt, size = 36;
277 w = Window.new("Knobs", Rect(400,400,250,100)).front;
278 w.acceptsMouseOver=true;
279 w.view.decorator = FlowLayout(w.view.bounds).gap_(10 @ 10).margin_(10 @10);
280 txt = StaticText(w, 200 @ 14);
281 w.view.decorator.nextLine;
283 k = Knob(w, size @ size);
284 k.action = {arg v,x,y; v.value.postln; txt.string_("value: " ++ v.value); };
285 k.mouseOverAction = {|v| txt.string_("value: " ++ v.value); };
287 j = Knob(w, size @ size);
288 j.action = {arg v,x,y; j.value.postln; txt.string_("value: " ++ v.value); };
289 j.mouseOverAction = { txt.string_("value: " ++ j.value); };
291 n = NumberBox(w, 100 @ 20);
292 //n.setProperty(\boxColor,Color.grey(alpha:0.0));
296 // customize drag and drop methods
297 k.canReceiveDragHandler
298 k.canReceiveDragHandler = false; // don't accept drops
300 k.canReceiveDragHandler = { View.currentDrag.isFloat }; // accept only if drag is float
302 k.receiveDragHandler = { ("value dropped in: " ++ View.currentDrag).postln }
304 k.receiveDragHandler = { k.valueAction = View.currentDrag.clip(0.0, 1.0); }
306 k.beginDragAction = { ("drag out -> " ++ k.value).postln; }
308 k.beginDragAction = { k.value.asFloat; }