class library: SynthDef - lazy implementation of removeUGen
[supercollider.git] / HelpSource / Classes / EnvelopeView.schelp
blobfd1ffdd13968204f0d5aaaa7441d24f17ff58801
1 class:: EnvelopeView
2 redirect:: implClass
3 summary:: A configurable view with nodes and connections
4 categories:: GUI>Views
5 related:: Classes/MultiSliderView, Classes/SCEnvelopeEdit
7 DESCRIPTION::
9 A view which can graphically display nodes at x/y coordinates, connection lines, cross-connections, node markers, and labels. All of the values for these are stored in arrays. While this view is typically used to make editable envelopes interfaces, it can be used to draw very complex interconnection graphs as well.
11 You can make the view display an link::Classes/Env:: using link::#-setEnv::. Note however that the view will work on a copy of the data of the Env object, therefore moving the nodes through the view will have no effect on the Env.
13 Multiple nodes can be selected and moved using mouse or keyboard. See link::#-defaultKeyDownAction:: for details.
15 The last selected node is considered to be the current, and can be moved programmatically using link::#-x:: and link::#-y::. It is also possible to change the selection and switch the current node programmatically using link::#-selectIndex::, link::#-deselectIndex:: and link::#-index::, as well as move the current node .
17 In strong::Qt GUI::, link::#-keepHorizontalOrder:: allows you to enforce the order of nodes in horizontal direction to match their index order. In that case, node movement to the left and to the right will be restricted by the positions of their immediate neighbours. This is especially useful when EnvelopeView is used to display an link::Classes/Env::.
19 In strong::Qt GUI::, link::#-elasticSelection:: determines whether moving multiple nodes will be blocked altogether if any of the nodes meet an obstacle (the view bounds or a neighbour node), or only those individual nodes will be blocked.
21 note:: The variable link::#-step:: must be explicitly set to allow moving nodes using keyboard. ::
25 INSTANCEMETHODS::
27 SUBSECTION:: Data
29 METHOD:: setEnv
30         Sets an link::Classes/Env:: to be displayed by the view. The view will extract data from the Env object to display (times, values and curve types).
32         Any nodes existent prior to calling this method will be removed.
34         argument::
35                 An Env.
38 METHOD:: value
39         Sets the positions of the nodes, creating them if not existent.
41         If there were already existent nodes and their amount is different than the amount of x/y pairs in the argument, nodes will be added or removed (in order of creation reversed) until the amounts match, and then the new values will be applied.
43         argument::
44                 An Array containing two other Arrays, of which one contains the horizontal and the other the vertical position of the new nodes. The values must be between 0 and 1. For example: code:: [[ x1, x2, x3, ... ], [ y1, y2, y3, ... ]] ::
46 METHOD:: valueAction
47         Sets link::#-value:: to the argument and triggers the link::#-action::.
49 METHOD:: x
50         The horizontal position of the emphasis::current:: node.
52         argument::
53                 A Float between 0 and 1.
55 METHOD:: y
56         The vertical position of the emphasis::current:: node.
58         argument::
59                 A Float between 0 and 1.
61 METHOD:: currentvalue
62         Synonym for link::#-y::.
64 METHOD:: curves
65         The shapes of connections between nodes. See below for the valid objects that describe a shape.
67         If a single shape is given, it will be applied to all the existing nodes. If an Array of shapes is given, each of its elements will be applied to an existing node, in order of index.
69         A connection curve shape applied to a node will determine the shape of the connections originating at that node. If no connections have been created using link::#-connect::, the origin node of a connection is the one with lower index. If there are such connections however, their origin is the node that was passed as the first argument to link::#-connect::.
71         argument::
72                 The valid objects to describe a shape are listed in link::Classes/Env#*new::. The argument can be either a single, or an Array of those values.
74 METHOD:: strings
75         The labels of the nodes.
77         note:: In order for the labels to be visible, you might need to ensure that the link::#-strokeColor:: contrasts the link::#-fillColor:: (depending on how the view draws the nodes and the labels).
78         ::
80         argument::
81                 An Array of Strings.
83 METHOD:: setString
84         Sets the label of the node at the given index.
86         note:: In order for the label to be visible, you might need to ensure that the link::#-strokeColor:: contrasts the link::#-fillColor:: (depending on how the view draws the nodes and the labels).
88         argument::
89                 A String.
91 METHOD:: setFillColor
92         Sets the color used to draw the inside of the node at the given index.
94         argument:: index
95                 An Integer.
96         argument:: color
97                 A Color.
99 METHOD:: setThumbWidth
100         Sets the width of the node at the given index.
102         argument:: index
103                 An Integer.
104         argument:: width
105                 An Integer.
107 METHOD:: setThumbHeight
108         Sets the height of the node at the given index.
110         argument:: index
111                 An Integer.
112         argument:: height
113                 An Integer.
115 METHOD:: setThumbSize
116         Sets both width and height of the node at the given index to code::size::.
118         argument:: index
119                 An Integer.
120         argument:: size
121                 An Integer.
124 METHOD:: connect
125         Removes any connections created when the link::#-value:: was set, and then creates new ones from the node at index given in the first argument to each of the nodes at indexes given in the second argument.
127         argument:: index
128                 An Integer - the index of the node to become one end of all the new connections.
129         argument:: connections
130                 An Array of Integers - indexes of nodes, each to become the second end to a new connection created.
134 SUBSECTION:: Appearance
136 METHOD:: drawLines
137         Whether to draw the connections between the nodes.
139         argument::
140                 A Boolean.
142 METHOD:: drawRects
143         Whether to draw the nodes
145         argument::
146                 A Boolean.
149 METHOD:: gridOn
150         Whether to draw the grid.
152         argument::
153                 A Boolean.
155 METHOD:: grid
156         The resolution of the grid.
158         argument::
159                 A Point of which x and y correspond to grid spacing on the horizontal and the vertical axis, respectively. If one of the two is 0, the grid on that axis will not be drawn.
161 METHOD:: thumbWidth
162         The default width of the nodes. If the width of a specific node has been set using link::#-setThumbWidth::, it will take precedence.
164         argument::
165                 An Integer.
167 METHOD:: thumbHeight
168         The default height of the nodes. If the height of a specific node has been set using link::#-setThumbHeight::, it will take precedence.
170         argument::
171                 An Integer.
173 METHOD:: thumbSize
174         Sets both link::#-thumbWidth:: and link::#-thumbHeight:: to the argument.
176 METHOD:: strokeColor
177         The color used to draw the connections and the node labels.
179         argument::
180                 A Color.
182 METHOD:: fillColor
183         The default color used to draw the nodes. If the color of a specific node has been set using link::#-setFillColor::, it will take precedence.
185         argument::
186                 A Color.
188 METHOD:: selectionColor
189         The color of a node when it is selected.
191         argument::
192                 A Color.
195 METHOD:: gridColor
196         The color of the grid.
198         argument::
199                 A Color.
201 METHOD:: colors
202         Sets the link::#-strokeColor:: and the link::#-fillColor:: to the arguments, respectively.
206 SUBSECTION:: Interaction
208 METHOD:: index
209         The index of the emphasis::current:: node.
211         argument::
212                 An Integer.
214 METHOD:: lastIndex
215         Synonym for link::#-index::.
218 METHOD:: selectIndex
219         Selects the node at given index and makes it the current one, i.e. link::#-currentvalue:: will relate to that node. As a special case, if the argument is -1 all nodes will be deselected.
221         argument::
222                 An Integer.
224 METHOD:: deselectIndex
225         Deselects the node at given index.
227         note:: Not available in strong:: Cocoa GUI ::. ::
229         argument::
230                 An Integer.
232 METHOD:: editable
233         Whether any node is editable.
235         argument::
236                 A Boolean.
238 METHOD:: setEditable
239         Sets whether the node at given index is editable. Regardless of this, no node will be editable unless link::#-editable:: is code::true::.
241         argument:: index
242                 An Integer.
244         argument:: flag
245                 A Boolean.
247 METHOD:: step
248         Makes the nodes snap (i.e. quantized) to the nearest multiple of the argument. Unless this is larger than 0, nodes will not be movable using keyboard.
250         argument::
251                 A Float.
253 METHOD:: keepHorizontalOrder
254         note:: Only available in strong::Qt GUI:: ::
256         Whether the position of nodes on the horizontal axis shall be restricted by their immediate neighbours (in order of their index).
258         Setting this to code::true:: will immediately modify the positions of existing nodes to match the order.
260         argument::
261                 A Boolean.
263 METHOD:: elasticSelection
264         note:: Only available in strong::Qt GUI:: ::
266         Whether the relative positions of nodes within the selection can change when the selection is moved using mouse or keyboard, in order to adapt to obstacles (the view bounds or, in case link::#-keepHorizontalOrder:: is code::true::, a neighbour node).
268         If this is code::false::, movement of multiple nodes will be blocked altogether when an obstacles is met, otherwise only the individual nodes will be blocked at their obstacles.
270         argument::
271                 A Boolean.
274 SUBSECTION:: Actions
276 METHOD:: action
277         The action object evaluated whenever the user moves a node.
279 METHOD:: metaAction
280         The action object evaluated whenever the user moves a node while the Ctrl key is pressed.
282 METHOD:: defaultKeyDownAction
284         Implements the default effects of key presses as follows:
286         table::
287         ## strong::Key::           || strong::Effect::
288         ## Shift/Alt + right arrow || increment x by step
289         ## Shift/Alt + left arrow  || decrement x by step
290         ## right arrow             || select next node
291         ## left arrow              || select previous node
292         ## up arrow                || increment y by step
293         ## down arrow              || decrement y by step
294         ::
296         note:: strong:: Differences between GUI kits ::
298                 strong::Cocoa:: uses the Shift modifier to move nodes horizontally, while strong::SwingOSC:: uses Alt for the same purpose. strong::Qt:: however will only move nodes at all if Alt is pressed, and holding down Shift will select each node at the current index, as it is changed.
300                 In strong::Qt::, the default effects of key presses are defined in the view implementation instead of in this method. If you want to override them, you need to return code::true:: from this method, or from link::Classes/View#-keyDownAction::. See link::Classes/View#key_actions#Key actions:: for explanation.
302         ::
307 SUBSECTION:: Drag and drop
309 METHOD:: defaultGetDrag
310         returns::
311                 The link::#-value::.
313 METHOD:: defaultCanReceiveDrag
314         returns::
315                 True for any drag data, but the data should be in the same format as link::#-value::.
317 METHOD:: defaultReceiveDrag
318         If the drag data is of the acceptable form (see link::#-defaultCanReceiveDrag:: above), sets link::#-value:: using that data.
322 EXAMPLES::
324 Use as envelope view
325 code::
327 // use shift-click to keep a node selected
328 w = Window("envelope", Rect(150 , Window.screenBounds.height - 250, 250, 100)).front;
329 w.view.decorator = FlowLayout(w.view.bounds);
331 b = EnvelopeView(w, Rect(0, 0, 230, 80))
332         .drawLines_(true)
333         .selectionColor_(Color.red)
334         .drawRects_(true)
335         .resize_(5)
336         .step_(0.05)
337         .action_({arg b; [b.index, b.value].postln})
338         .thumbSize_(5)
339         .value_([[0.0, 0.1, 0.5, 1.0],[0.1,1.0,0.8,0.0]]);
340 w.front;
343 // show grid
344 b.gridOn_(true);
346 // show Env
347 b.setEnv(Env.asr(0.5,1, 0.2));
349 // make the first point unmoveable
351 b.setEditable(0,false);
355 Use shift click to select/unselect the points
356 code::
358 w = Window("envelope", Rect(150 , Window.screenBounds.height - 250, 400, 150)).front;
359 w.view.decorator = FlowLayout(w.view.bounds);
361 b = EnvelopeView(w, Rect(0, 0, 350, 100))
362         .thumbSize_(5)
363         .drawLines_(true)
364         .fillColor_(Color.green)
365         .selectionColor_(Color.red)
366         .drawRects_(true)
367         .value_([(0.0, 0.1 .. 1.0), (0.0, 0.1 .. 1.0)])
368         .setEditable(0,false);
372 r = Routine({
373         var j = 0;
374         20.do({ arg i;
375                 b.selectIndex((b.size - 1).rand.abs);
376                 0.1.wait;
377                 b.x_(1.0.rand.abs);
378                 b.y_(1.0.rand.abs);
379         });
380         b.selectIndex(-1);
382 AppClock.play(r);
386 Show boxes with a string in it:
387 code::
389 a = Window("text-boxes", Rect(200 , 450, 450, 450));
390 a.view.decorator = FlowLayout(a.view.bounds);
392 b = EnvelopeView(a, Rect(0, 0, 440, 440))
393         .thumbWidth_(60.0)
394         .thumbHeight_(15.0)
395         .drawLines_(true)
396         .drawRects_(true)
397         .selectionColor_(Color.red)
398         .value_([[0.1, 0.4, 0.5, 0.3], [0.1, 0.2, 0.9, 0.7]]);
399 4.do({arg i;
400         b.setString(i, ["this", "is", "so much", "fun"].at(i));
401         b.setFillColor(i,[Color.yellow, Color.white, Color.green].choose);
403 a.front;
407 b.connect(3, [2.0,0.0,1.0]); // the text objects can be connected
408 b.connect(0,[2.0,3.0,1.0]);