Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / HelpSource / Classes / EnvelopeView.schelp
blobe96a393f567b84df09bcde5e07e671b3275f4feb
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 You can also define nodes with arrays of x and y values using link::#-value::, and the connections using link::#-connect::.
15 SUBSECTION:: Appearance
17 In strong::Qt GUI::, the view supports two strong::display styles::: the default one draws nodes as small dots, with labels next to them, while another style draws nodes as rounded rectangles with labels drawn inside. See link::#-style::.
19 A strong::label:: for each of the nodes can be set using link::#-strings:: and link::#-setString::.
21 SUBSECTION:: Interaction
23 Nodes can be selected and moved using mouse. Shift-clicking a node will add it to the selection.
25 You can also move selected nodes and change selection using keyboard. In strong::Qt::, pressing the arrow keys will move selected nodes (as long as link::#-step:: is larger than 0). Pressing the left or right arrow keys while holding down Alt will select previous or next node, and holding down Shift will extend selection to the left or to the right. Other GUI kits may differ.
27 In strong::Qt::, 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::.
29 In strong::Qt::, 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.
31 Node selection can also be changed programmatically using link::#-index::, link::#-selectIndex::, and link::#-deselectIndex::. The link::#-index#current:: node can be moved programmatically using link::#-x:: and link::#-y::.
33 INSTANCEMETHODS::
35 SUBSECTION:: Data
37 METHOD:: setEnv
38         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).
40         Any nodes existent prior to calling this method will be removed.
42         argument::
43                 An Env.
46 METHOD:: value
47         code::value:: retrieves the node positions, returning an array in the format of the Argument below. code::value_(anArray):: Sets the positions of the nodes, creating them if not existent.
49         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.
51         argument::
52                 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, ... ]] ::
54 METHOD:: valueAction
55         Sets link::#-value:: to the argument and triggers the link::#-action::.
57 METHOD:: x
58         The horizontal position of the emphasis::current:: node.
60         argument::
61                 A Float between 0 and 1.
63 METHOD:: y
64         The vertical position of the emphasis::current:: node.
66         argument::
67                 A Float between 0 and 1.
69 METHOD:: currentvalue
70         Synonym for link::#-y::.
72 METHOD:: curves
73         The shapes of connections between nodes. See below for the valid objects that describe a shape.
75         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.
77         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::.
79         argument::
80                 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.
82 METHOD:: strings
83         The labels of the nodes.
85         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).
86         ::
88         argument::
89                 An Array of Strings.
91 METHOD:: setString
92         Sets the label of the node at the given index.
94         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).::
96         argument::
97                 A String.
99 METHOD:: setFillColor
100         Sets the color used to draw the inside of the node at the given index.
102         argument:: index
103                 An Integer.
104         argument:: color
105                 A Color.
107 METHOD:: setThumbWidth
108         Sets the width of the node at the given index.
110     NOTE:: For compatibility with existing code, this will set the link::#-style:: to strong::'rects'::. ::
112         argument:: index
113                 An Integer.
114         argument:: width
115                 An Integer.
117 METHOD:: setThumbHeight
118         Sets the height of the node at the given index.
120     NOTE:: For compatibility with existing code, this will set the link::#-style:: to strong::'rects'::. ::
122         argument:: index
123                 An Integer.
124         argument:: height
125                 An Integer.
127 METHOD:: setThumbSize
128         Sets both width and height of the node at the given index to code::size::.
130         argument:: index
131                 An Integer.
132         argument:: size
133                 An Integer.
136 METHOD:: connect
137         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.
139         argument:: index
140                 An Integer - the index of the node to become one end of all the new connections.
141         argument:: connections
142                 An Array of Integers - indexes of nodes, each to become the second end to a new connection created.
146 SUBSECTION:: Appearance
148 METHOD:: style
149     NOTE:: Only available in Qt GUI ::
151     One of the following drawing styles:
153     list::
155     ## strong::'dots':: - nodes are drawn as small dots within a larger circle indicating the area of mouse sensitivity. Labels are drawn next to the dots (see link::#-setString::). This style always draws nodes with emphasis::equal width and height::, and will use the smaller of the node's sizes, if different (it never draws ellipses).
157     ## strong::'rects':: - nodes are drawn as rounded rectangles. Labels are drawn within the bounds of the rectangles.
158     ::
160     NOTE:: For compatibility with existing code, calling any of link::#-thumbWidth::, link::#-thumbHeight::, link::#-setThumbWidth::, or link::#-setThumbHeight:: will automatically switch style to strong::'rects'::. You can still set a different style afterwards.
161     ::
163     argument::
164         One of the symbols: code::\dots:: or code::\rects::. Alternatively, an integer 0 or 1, for each style respectively.
166     returns:: An integer 0 or 1.
168 METHOD:: drawLines
169         Whether to draw the connections between the nodes.
171         argument::
172                 A Boolean.
174 METHOD:: drawRects
175         Whether to draw the nodes
177         argument::
178                 A Boolean.
181 METHOD:: gridOn
182         Whether to draw the grid.
184         argument::
185                 A Boolean.
187 METHOD:: grid
188         The resolution of the grid.
190         argument::
191                 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.
193 METHOD:: thumbWidth
194     Sets the width of all nodes.
196     NOTE:: For compatibility with existing code, this will set the link::#-style:: to strong::'rects'::. ::
198         argument::
199                 An Integer.
201 METHOD:: thumbHeight
202     Sets the height of all nodes.
204     NOTE:: For compatibility with existing code, this will set the link::#-style:: to strong::'rects'::. ::
206         argument::
207                 An Integer.
209 METHOD:: thumbSize
210         Sets both link::#-thumbWidth:: and link::#-thumbHeight:: to the argument.
212 METHOD:: strokeColor
213         The color used to draw the connections and the node labels.
215         argument::
216                 A Color.
218 METHOD:: fillColor
219         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.
221         argument::
222                 A Color.
224 METHOD:: selectionColor
225         The color of a node when it is selected.
227         argument::
228                 A Color.
231 METHOD:: gridColor
232         The color of the grid.
234         argument::
235                 A Color.
237 METHOD:: colors
238         Sets the link::#-strokeColor:: and the link::#-fillColor:: to the arguments, respectively.
242 SUBSECTION:: Interaction
244 METHOD:: index
245         The index of the emphasis::current:: node, i.e. the node affected by link::#-x:: and link::#-y:: methods.
247     In strong::Qt::, this is the selected node with lowest index, or -1 if no selection.
249     In strong::Cocoa::, this is the last node selected, or -1 if no selection.
251     In strong::SwingOSC::, this is the last node clicked, regardless of selection.
253         argument::
254                 An Integer.
256 METHOD:: lastIndex
257     The last node selected, regardless of the current state of selection.
260 METHOD:: selectIndex
261         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.
263         argument::
264                 An Integer.
266 METHOD:: deselectIndex
267         Deselects the node at given index.
269         note:: Not available in strong:: Cocoa GUI ::. ::
271         argument::
272                 An Integer.
274 METHOD:: editable
275         Whether any node is editable.
277         argument::
278                 A Boolean.
280 METHOD:: setEditable
281         Sets whether the node at given index is editable. Regardless of this, no node will be editable unless link::#-editable:: is code::true::.
283         argument:: index
284                 An Integer.
286         argument:: flag
287                 A Boolean.
289 METHOD:: step
290         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.
292         argument::
293                 A Float.
295 METHOD:: keepHorizontalOrder
296         note:: Only available in strong::Qt GUI:: ::
298         Whether the position of nodes on the horizontal axis shall be restricted by their immediate neighbours (in order of their index).
300         Setting this to code::true:: will immediately modify the positions of existing nodes to match the order.
302         argument::
303                 A Boolean.
305 METHOD:: elasticSelection
306         note:: Only available in strong::Qt GUI:: ::
308         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).
310         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.
312         argument::
313                 A Boolean.
316 SUBSECTION:: Actions
318 METHOD:: action
319         The action object evaluated whenever the user moves a node.
321 METHOD:: metaAction
322         The action object evaluated whenever the user moves a node while the Ctrl key is pressed.
324 METHOD:: defaultKeyDownAction
326     Implements the default behavior on key presses.
328     In Qt, the default behavior is defined in the C++ implementation of the view instead of this method. See link::Classes/View#Key and mouse event propagation:: for explanation of how to override the behavior.
333 SUBSECTION:: Drag and drop
335 METHOD:: defaultGetDrag
336         returns::
337                 The link::#-value::.
339 METHOD:: defaultCanReceiveDrag
340         returns::
341                 True for any drag data, but the data should be in the same format as link::#-value::.
343 METHOD:: defaultReceiveDrag
344         If the drag data is of the acceptable form (see link::#-defaultCanReceiveDrag:: above), sets link::#-value:: using that data.
348 EXAMPLES::
350 Use as envelope view
351 code::
353 // use shift-click to keep a node selected
354 w = Window("envelope", Rect(150 , Window.screenBounds.height - 250, 250, 100)).front;
355 w.view.decorator = FlowLayout(w.view.bounds);
357 b = EnvelopeView(w, Rect(0, 0, 230, 80))
358         .drawLines_(true)
359         .selectionColor_(Color.red)
360         .drawRects_(true)
361         .resize_(5)
362         .step_(0.05)
363         .action_({arg b; [b.index, b.value].postln})
364         .thumbSize_(5)
365         .value_([[0.0, 0.1, 0.5, 1.0],[0.1,1.0,0.8,0.0]]);
366 w.front;
369 // show grid
370 b.gridOn_(true);
372 // show Env
373 b.setEnv(Env.asr(0.5,1, 0.2));
375 // make the first point unmoveable
377 b.setEditable(0,false);
381 Use shift click to select/unselect the points
382 code::
384 w = Window("envelope", Rect(150 , Window.screenBounds.height - 250, 400, 150)).front;
385 w.view.decorator = FlowLayout(w.view.bounds);
387 b = EnvelopeView(w, Rect(0, 0, 350, 100))
388         .thumbSize_(5)
389         .drawLines_(true)
390         .fillColor_(Color.green)
391         .selectionColor_(Color.red)
392         .drawRects_(true)
393         .value_([(0.0, 0.1 .. 1.0), (0.0, 0.1 .. 1.0)])
394         .setEditable(0,false);
398 r = Routine({
399         var j = 0;
400         20.do({ arg i;
401                 b.selectIndex((b.size - 1).rand.abs);
402                 0.1.wait;
403                 b.x_(1.0.rand.abs);
404                 b.y_(1.0.rand.abs);
405         });
406         b.selectIndex(-1);
408 AppClock.play(r);
412 Show boxes with a string in it:
413 code::
415 a = Window("text-boxes", Rect(200 , 450, 450, 450));
416 a.view.decorator = FlowLayout(a.view.bounds);
418 b = EnvelopeView(a, Rect(0, 0, 440, 440))
419         .thumbWidth_(60.0)
420         .thumbHeight_(15.0)
421         .drawLines_(true)
422         .drawRects_(true)
423         .selectionColor_(Color.red)
424         .value_([[0.1, 0.4, 0.5, 0.3], [0.1, 0.2, 0.9, 0.7]]);
425 4.do({arg i;
426         b.setString(i, ["this", "is", "so much", "fun"].at(i));
427         b.setFillColor(i,[Color.yellow, Color.white, Color.green].choose);
429 a.front;
433 b.connect(3, [2.0,0.0,1.0]); // the text objects can be connected
434 b.connect(0,[2.0,3.0,1.0]);