Include a header file required for build on mac 10.4
[supercollider.git] / Help / GUI / GUI-Overview.html
blob32bab25427d3774fb1deca4e5f8370d3decab742
1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2 <html>
3 <head>
4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5 <meta http-equiv="Content-Style-Type" content="text/css">
6 <title></title>
7 <meta name="Generator" content="Cocoa HTML Writer">
8 <meta name="CocoaVersion" content="1038.25">
9 <style type="text/css">
10 p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Helvetica}
11 p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; min-height: 12.0px}
12 p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; color: #0000ee}
13 p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px}
14 p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}
15 p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Helvetica}
16 p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Helvetica; min-height: 17.0px}
17 p.p8 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #bf0000}
18 p.p9 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px}
19 p.p10 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #bf0000; min-height: 14.0px}
20 p.p11 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #bf0000}
21 p.p12 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco}
22 p.p13 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #606060}
23 p.p14 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #0000bf}
24 p.p15 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Helvetica; min-height: 11.0px}
25 p.p16 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco; min-height: 12.0px}
26 p.p17 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco}
27 p.p18 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #0000bf}
28 span.s1 {color: #000000}
29 span.s2 {text-decoration: underline}
30 span.s3 {color: #0000bf}
31 span.s4 {text-decoration: underline ; color: #001bec}
32 span.s5 {color: #606060}
33 span.s6 {font: 10.0px Monaco; color: #bf0000}
34 span.s7 {color: #bf0000}
35 span.s8 {text-decoration: underline ; color: #0000ee}
36 span.s9 {color: #007300}
37 span.s10 {font: 12.0px Helvetica}
38 span.s11 {font: 10.0px Monaco; color: #0000bf}
39 span.s12 {font: 10.0px Monaco}
40 span.Apple-tab-span {white-space:pre}
41 </style>
42 </head>
43 <body>
44 <p class="p1"><b>GUI Overview and Introduction</b></p>
45 <p class="p2"><br></p>
46 <p class="p3"><span class="s1">See also: <a href="GUI-Classes.html"><span class="s2">GUI-Classes</span></a>, <a href="GUI-Tools/GUI.html"><span class="s2">GUI</span></a></span><span class="s3">, <a href="GUI-Tools/ViewRedirect.html"><span class="s4">ViewRedirect</span></a>.</span></p>
47 <p class="p4"><br></p>
48 <p class="p5">SuperCollider provides for using different gui kits, and also provides syntax for transparently writing kit and platform independent code. Two main classes control this mechnanism: the gui factory abstraction class, <a href="GUI-Tools/GUI.html"><span class="s3">GUI</span></a>, and the subclasses of <a href="GUI-Tools/ViewRedirect.html"><span class="s3">ViewRedirect</span></a>, which transparently uses the <a href="GUI-Tools/GUI.html"><span class="s3">GUI</span></a> class to redirect to the kit-specific gui class.</p>
49 <p class="p4"><br></p>
50 <p class="p5">For a table of all gui classes and their equivalents, see <a href="GUI-Classes.html"><span class="s3">GUI-Classes</span></a><span class="s3">.</span></p>
51 <p class="p5">For information on switching gui kits, see the documentation for <a href="GUI-Tools/GUI.html"><span class="s3">GUI</span></a>.</p>
52 <p class="p4"><br></p>
53 <p class="p6"><b>Basic usage: Kits and Syntax</b></p>
54 <p class="p7"><br></p>
55 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span>w=</span><span class="s3">Window</span><span class="s1">(</span><span class="s5">"Test Window"</span><span class="s1">).front; </span>// Window is a subclass of ViewRedirect</p>
56 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span>w.postln </span>// w now contains the class appropriate to the gui kit</p>
57 <p class="p7"><br></p>
58 <p class="p5">Kit-dependant gui classes have a prefix. For example, to make a window, the CocoaGUI kit uses <a href="Cocoa-GUI/SCWindow.html"><span class="s3">SCWindow</span></a><span class="s3">,</span> or the swing kit uses <a href="SC://JSCWindow.html"><span class="s3">JSCWindow</span></a>. It is generally discouraged to use the kit-dependant classes directly. Instead, you simply use the subclasses of <a href="GUI-Tools/ViewRedirect.html"><span class="s3">ViewRedirect</span></a><span class="s3">. </span>In most cases this involves simply using the class base name without any prefix, like in the example above. Behind the scenes, the above technique actually automatically redirects to the appropriate GUI class method. For a table of all gui classes and their kit-dependent equivalents, see <a href="GUI-Classes.html"><span class="s3">GUI-Classes</span></a><span class="s3">.</span></p>
59 <p class="p4"><br></p>
60 <p class="p5">Depending on the curent GUI.scheme the example above is equivalent to writing, for example:</p>
61 <p class="p4"><br></p>
62 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span></span><span class="s3">SCWindow</span><span class="s1">(</span><span class="s5">"Test Window"</span><span class="s1">).front; </span>// cocoa version</p>
63 <p class="p9"><span class="Apple-tab-span"> </span></p>
64 <p class="p5"><span class="s6"><span class="Apple-tab-span"> </span></span>or</p>
65 <p class="p10"><span class="Apple-tab-span"> </span></p>
66 <p class="p11"><span class="s1"><span class="Apple-tab-span"> </span></span><span class="s3">JSCWindow</span><span class="s1">(</span><span class="s5">"Test Window"</span><span class="s1">).front; </span>// swing version</p>
67 <p class="p4"><br></p>
68 <p class="p6"><b>Basic Usage: Windows, Containers and Decorators</b></p>
69 <p class="p7"><br></p>
70 <p class="p12">(</p>
71 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span></span>// Window returns the window class for the current kit</p>
72 <p class="p12"><span class="Apple-tab-span"> </span>w = <span class="s3">Window</span>( <span class="s5">"my name is..."</span>, <span class="s3">Rect</span>( 128, 64, 340, 360 ));</p>
73 <p class="p2"><br></p>
74 <p class="p12"><span class="Apple-tab-span"> </span>w.view.decorator = <span class="s3">FlowLayout</span>( w.view.bounds ); <span class="s7">// comment this out for no decorator</span></p>
75 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span></span>// w.addFlowLayout // you can use this instead of the above line for brevity.</p>
76 <p class="p2"><span class="Apple-tab-span"> </span></p>
77 <p class="p12"><span class="Apple-tab-span"> </span>w.view.background = <span class="s3">Color</span>( 0.6, 0.8, 0.8 );</p>
78 <p class="p2"><br></p>
79 <p class="p12"><span class="Apple-tab-span"> </span>32.do({ <span class="s3">arg</span> i;</p>
80 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>// Here Button returns the button class for the current kit</p>
81 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>b = <span class="s3">Button</span>( w, <span class="s3">Rect</span>( rrand( 20, 300 ), rrand( 20, 300 ), 75, 24 ));</p>
82 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>b.states = [[ <span class="s5">"Start "</span> ++ i, <span class="s3">Color</span>.black, <span class="s3">Color</span>.rand ],</p>
83 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>[ <span class="s5">"Stop "</span> ++ i, <span class="s3">Color</span>.white, <span class="s3">Color</span>.red ]];</p>
84 <p class="p12"><span class="Apple-tab-span"> </span>});</p>
85 <p class="p2"><br></p>
86 <p class="p12"><span class="Apple-tab-span"> </span>w.front;</p>
87 <p class="p12">)</p>
88 <p class="p2"><br></p>
89 <p class="p8"><span class="s1">w.postln </span>//prints the window instance for the current gui kit</p>
90 <p class="p8"><span class="s1">b.postln </span>//prints the button instance for the current gui kit</p>
91 <p class="p7"><br></p>
92 <p class="p5">In the above example, first a <a href="Main-GUI/Window.html"><span class="s3">Window</span></a> was created. A <a href="Main-GUI/Window.html"><span class="s3">Window</span></a> automatically has its own top level container, which is a subclass of <a href="Main-GUI/CompositeView.html"><span class="s3">CompositeView</span></a>. A <a href="Main-GUI/CompositeView.html"><span class="s3">CompositeView</span></a> can have a <b>decorator</b>, which automatically places the contents in a predetermined order. In this case it is a <a href="GUI-Tools/FlowLayout.html"><span class="s3">FlowLayout</span></a>, which is the only one that currently exists. This is optional however. Try commenting out the decorator in the example above.</p>
93 <p class="p4"><br></p>
94 <p class="p5"><span class="s8"><a href="Main-GUI/Window.html">Window</a></span> and <a href="Main-GUI/CompositeView.html"><span class="s3">CompositeView</span></a> both have addFlowLayout utility methods which assign an instance of FlowLayout to their view decorators and return the decorator.</p>
95 <p class="p7"><br></p>
96 <p class="p5">Most gui objects are subclasses of <a href="Main-GUI/View.html"><span class="s3">View</span></a>. All subclasses of View are created with the same beginning arguments, <b>parent </b>and <b>bounds</b>, for example, <a href="Main-GUI/Slider.html"><span class="s3">Slider</span></a>(<b>parent</b>, <b>bounds</b>).</p>
97 <p class="p4"><br></p>
98 <p class="p5">The <b>parent</b> is a container view of some kind, and the <b>bounds</b> are an instance of <a href="../Geometry/Rect.html"><span class="s3">Rect</span></a> or a <a href="../Geometry/Point.html"><span class="s3">Point</span></a> (for width and height only). Using a Point is convenient if you are using a decorator for the postioning.</p>
99 <p class="p7"><br></p>
100 <p class="p12"><span class="Apple-tab-span"> </span>(</p>
101 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span>w=</span><span class="s3">Window</span><span class="s1">.new.front;<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>// Use Rect for precise placement in a CompositeView</p>
102 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span></span><span class="s3">Slider</span><span class="s1">(w, </span><span class="s3">Rect</span><span class="s1"> (50,50,250,20)); <span class="Apple-tab-span"> </span></span>// Slider is actually placed in w.view, which is a top view.</p>
103 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span></span><span class="s3">Slider</span><span class="s1">(w.view, </span><span class="s3">Rect</span><span class="s1"> (50,100,250,20)) </span>// So this is equivalent when Window is used as a parent</p>
104 <p class="p12"><span class="Apple-tab-span"> </span>)</p>
105 <p class="p7"><br></p>
106 <p class="p5">You can easily nest containers, decorators and views to make complex layouts, and you can use colors to visually separate them:</p>
107 <p class="p4"><span class="Apple-tab-span"> </span></p>
108 <p class="p12"><span class="Apple-tab-span"> </span>(</p>
109 <p class="p12"><span class="Apple-tab-span"> </span>w=<span class="s3">Window</span>.new.front;</p>
110 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span>w.view.decorator = </span><span class="s3">FlowLayout</span><span class="s1">(w.view.bounds); </span>// notice that FlowView refers to w.view, not w</p>
111 <p class="p2"><span class="Apple-tab-span"> </span></p>
112 <p class="p12"><span class="Apple-tab-span"> </span>v=<span class="s3">CompositeView</span>(w, <span class="s3">Rect</span>(5,5,190,390));</p>
113 <p class="p12"><span class="Apple-tab-span"> </span>v.background = <span class="s3">Color</span>.rand; <span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s7">// set the color</span></p>
114 <p class="p12"><span class="Apple-tab-span"> </span>v.decorator = <span class="s3">FlowLayout</span>(v.bounds);</p>
115 <p class="p2"><span class="Apple-tab-span"> </span></p>
116 <p class="p12"><span class="Apple-tab-span"> </span>y=<span class="s3">CompositeView</span>(w, <span class="s3">Rect</span>(205,5,190,390));</p>
117 <p class="p12"><span class="Apple-tab-span"> </span>y.background = <span class="s3">Color</span>.rand;<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s7">// set the color</span></p>
118 <p class="p12"><span class="Apple-tab-span"> </span>y.decorator = <span class="s3">FlowLayout</span>(y.bounds);</p>
119 <p class="p2"><span class="Apple-tab-span"> </span></p>
120 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span>14.do{ </span><span class="s3">Slider</span><span class="s1">(v, 180@20).background_(v.background) };</span>// Points used, since the layout is handled by a decorator.</p>
121 <p class="p2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
122 <p class="p12"><span class="Apple-tab-span"> </span>18.do{ <span class="s3">Slider2D</span>(y,58@58).background_(<span class="s3">Color</span>.rand); };</p>
123 <p class="p2"><span class="Apple-tab-span"> </span></p>
124 <p class="p12"><span class="Apple-tab-span"> </span>)</p>
125 <p class="p9"><span class="Apple-tab-span"> </span></p>
126 <p class="p6"><b>Container Coordinates</b></p>
127 <p class="p7"><br></p>
128 <p class="p5">Container and User views use <b>relative</b> bounds coordinates, which are measured from the parent <b>view's</b> top left corner.</p>
129 <p class="p4"><br></p>
130 <p class="p12"><span class="Apple-tab-span"> </span>( <span class="Apple-converted-space"> </span></p>
131 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span>w=</span><span class="s3">Window</span><span class="s1">.new.front;<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>// Use Rect for precise placement in a CompositeView</p>
132 <p class="p12"><span class="Apple-tab-span"> </span>v=<span class="s3">CompositeView</span>(w, <span class="s3">Rect</span>(50,50,300,300));</p>
133 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span>v.background_(</span><span class="s3">Color</span><span class="s1">.grey);<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>// give the subview a visible color</p>
134 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span></span><span class="s3">Slider</span><span class="s1">(v, </span><span class="s3">Rect</span><span class="s1"> (50,50,220,20)) <span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>// so this is equivalent when Window is used as a parent</p>
135 <p class="p12"><span class="Apple-tab-span"> </span>)</p>
136 <p class="p7"><br></p>
137 <p class="p4"><br></p>
138 <p class="p6"><b>Window Coordinates</b></p>
139 <p class="p4"><br></p>
140 <p class="p5">For a <a href="Main-GUI/Window.html"><span class="s3">Window</span></a>, the bounds coordinates are measured from the <b>bottom</b> left of the screen.</p>
141 <p class="p5">The bounds.rect differs from that of views, and is the following: Rect(left, <b>bottom</b>, width,height). Typically, you will call Window.screenBounds to place a window precisely independently of the screen size you are working on.</p>
142 <p class="p4"><br></p>
143 <p class="p12"><span class="Apple-tab-span"> </span>(</p>
144 <p class="p13"><span class="s1"><span class="Apple-tab-span"> </span>w=</span><span class="s3">Window</span><span class="s1">.new(</span>"A Precisely Placed Window"<span class="s1">,</span></p>
145 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">Rect</span>(100, <span class="s3">Window</span>.screenBounds.height-300, 300, 200 )</p>
146 <p class="p2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
147 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>).front;</p>
148 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span>) </span>//since the window is 200 high and the bottom is at screenBounds.height-300, the top is 100 from the screen top</p>
149 <p class="p9"><br></p>
150 <p class="p6"><b>Resizing</b></p>
151 <p class="p4"><br></p>
152 <p class="p5">Views can resize or stretch according to nine differents states, according to the instance variable <b>resize</b>. For documentation and examples see <a href="GUI-Tools/resize.html"><span class="s3">resize</span></a>.</p>
153 <p class="p4"><br></p>
154 <p class="p9"><br></p>
155 <p class="p6"><b>Actions: Performing Things with a GUI Widget</b></p>
156 <p class="p7"><br></p>
157 <p class="p5">Gui widgets typically have an <b>action</b>, which is a <a href="../Core/Kernel/Function.html"><span class="s3">Function</span></a> or <a href="../Core/Kernel/FunctionList.html"><span class="s3">FunctionList</span></a> to be evaluated when the user interacts with the widget.</p>
158 <p class="p5">You can set the <b>action</b>, or use <b>addAction</b>, or <b>removeAction</b> to determine how a widget interacts with your code.</p>
159 <p class="p2"><span class="Apple-tab-span"> </span></p>
160 <p class="p12"><span class="Apple-tab-span"> </span>(</p>
161 <p class="p13"><span class="s1"><span class="Apple-tab-span"> </span>w = </span><span class="s3">Window</span><span class="s1"> (</span>"A Slider"<span class="s1">);</span></p>
162 <p class="p12"><span class="Apple-tab-span"> </span>a = <span class="s3">Slider</span> (w, <span class="s3">Rect</span>(40, 10, 300, 30));</p>
163 <p class="p12"><span class="Apple-tab-span"> </span>a.action={ <span class="s3">|sl|</span> sl.value.postln }; <span class="s7">// set the action of the slider</span></p>
164 <p class="p12"><span class="Apple-tab-span"> </span>w.front</p>
165 <p class="p12"><span class="Apple-tab-span"> </span>);</p>
166 <p class="p2"><span class="Apple-tab-span"> </span></p>
167 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span></span>// now incrementally add some more actions to the slider</p>
168 <p class="p12"><span class="Apple-tab-span"> </span>a.addAction({ <span class="s3">|sl|</span> w.view.background = <span class="s3">Color</span>.green(sl.value) });</p>
169 <p class="p12"><span class="Apple-tab-span"> </span>a.addAction({ <span class="s3">|sl|</span> sl.background = <span class="s3">Color</span>.red(1 - sl.value) });</p>
170 <p class="p2"><span class="Apple-tab-span"> </span></p>
171 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span></span>// adding and removing an action:</p>
172 <p class="p13"><span class="s1"><span class="Apple-tab-span"> </span>f = { </span><span class="s3">|sl|</span><span class="s1"> </span>"--------*******-------"<span class="s1">.postln; };</span></p>
173 <p class="p12"><span class="Apple-tab-span"> </span>a.addAction(f);</p>
174 <p class="p12"><span class="Apple-tab-span"> </span>a.removeAction(f);</p>
175 <p class="p2"><span class="Apple-tab-span"> </span></p>
176 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span></span>// or remove all, of course</p>
177 <p class="p12"><span class="Apple-tab-span"> </span>a.action = <span class="s3">nil</span>;</p>
178 <p class="p9"><br></p>
179 <p class="p6"><b>GUI Timing: System Clock and App Clock</b></p>
180 <p class="p9"><br></p>
181 <p class="p3"><span class="s1">See: <a href="../Scheduling/AppClock.html"><span class="s2">AppClock</span></a>, <a href="../Scheduling/TempoClock.html"><span class="s2">TempoClock</span></a>, <a href="../Scheduling/SystemClock.html"><span class="s2">SystemClock</span></a></span></p>
182 <p class="p4"><br></p>
183 <p class="p5">Calls to the gui system from from the lang must be made from the AppClock, since the <a href="../Scheduling/SystemClock.html"><span class="s3">SystemClock</span></a> is reserved for high priority sound related tasks. If you want to control a gui with a Routine or Task, then you must either use the <a href="../Scheduling/AppClock.html"><span class="s3">AppClock</span></a> to play them, or use the <b>defer</b> mechanism, which schedules a Function in the <a href="../Scheduling/AppClock.html"><span class="s3">AppClock</span></a>:</p>
184 <p class="p4"><span class="Apple-tab-span"> </span></p>
185 <p class="p12"><span class="Apple-tab-span"> </span>(</p>
186 <p class="p12"><span class="Apple-tab-span"> </span>w=<span class="s3">Window</span>.new.front;</p>
187 <p class="p14"><span class="s1"><span class="Apple-tab-span"> </span></span>Routine<span class="s1">{</span></p>
188 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>20.do{</p>
189 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.bounds=<span class="s3">Rect</span>(200.rand, 200+200.rand, 300,300);</p>
190 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>0.1.wait;</p>
191 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>};</p>
192 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.close;</p>
193 <p class="p12"><span class="Apple-tab-span"> </span>}.play(<span class="s3">AppClock</span>)</p>
194 <p class="p12"><span class="Apple-tab-span"> </span>)</p>
195 <p class="p9"><span class="Apple-tab-span"> </span></p>
196 <p class="p5">The same thing using the <b>defer</b> mechanism and a <a href="../Scheduling/SystemClock.html"><span class="s3">SystemClock</span></a>:</p>
197 <p class="p4"><span class="Apple-tab-span"> </span></p>
198 <p class="p12"><span class="Apple-tab-span"> </span>(</p>
199 <p class="p12"><span class="Apple-tab-span"> </span>w=<span class="s3">Window</span>.new.front;</p>
200 <p class="p14"><span class="s1"><span class="Apple-tab-span"> </span></span>Routine<span class="s1">{</span></p>
201 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>20.do{</p>
202 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>{w.bounds=<span class="s3">Rect</span>(200.rand, 200+200.rand, 300,300) }.defer; <span class="s7">// you must defer this</span></p>
203 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>0.1.wait;</p>
204 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>};</p>
205 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>{w.close}.defer; </span>// you must defer this</p>
206 <p class="p14"><span class="s1"><span class="Apple-tab-span"> </span>}.play(</span>SystemClock<span class="s1">)</span></p>
207 <p class="p12"><span class="Apple-tab-span"> </span>)</p>
208 <p class="p15"><br></p>
209 <p class="p5">In reality, <b>defer</b> simply schedules a <a href="../Core/Kernel/Routine.html"><span class="s3">Routine</span></a> in an <a href="../Scheduling/AppClock.html"><span class="s3">AppClock</span></a>.</p>
210 <p class="p7"><br></p>
211 <p class="p6"><b>Asynchronous GUI Techniques: Communicating with the Sound Server</b></p>
212 <p class="p7"><br></p>
213 <p class="p5">Sending values from a gui object to the sound server is basically the same as sending from the lang. Gui widgets typically have an <b>action</b>, which is a <a href="../Core/Kernel/Function.html"><span class="s3">Function</span></a> or <a href="../Core/Kernel/FunctionList.html"><span class="s3">FunctionList</span></a> to be evaluated when the user interacts with the widget.</p>
214 <p class="p4"><br></p>
215 <p class="p8">// use arrow keys to change frequency</p>
216 <p class="p16"><br></p>
217 <p class="p12"><span class="Apple-tab-span"> </span>(<span class="Apple-tab-span"> </span></p>
218 <p class="p12"><span class="Apple-tab-span"> </span>s.waitForBoot({</p>
219 <p class="p2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
220 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>n={<span class="s3">arg</span> freq=220;</p>
221 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">var</span> out;</p>
222 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>out=<span class="s3">SinOsc</span>.ar(freq,0,0.2);</p>
223 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>8.do{out = <span class="s3">AllpassN</span>.ar(out, 0.2,0.02+0.20.rand,8)};</p>
224 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>out;</p>
225 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>}.play;</p>
226 <p class="p2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
227 <p class="p13"><span class="s1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w = </span><span class="s3">Window</span><span class="s1">(</span>"Use arrow keys to change the frequency by steps"<span class="s1">, </span><span class="s3">Rect</span><span class="s1">(100, 500, 500, 120));</span></p>
228 <p class="p2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
229 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>b = <span class="Apple-tab-span"> </span><span class="s3">NumberBox</span>(w, <span class="s3">Rect</span>(200, 10, 100, 20));</p>
230 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>b.value = 220;</p>
231 <p class="p2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
232 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>b.action = {</span><span class="s3">arg</span><span class="s1"> numb; n.set(</span><span class="s9">\freq</span><span class="s1">, numb.value); }; </span>// set the action here to change the frequency.</p>
233 <p class="p2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
234 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>b.addAction ( {w.view.background = <span class="s3">Color</span>.rand}); <span class="s7">// add another action here.</span></p>
235 <p class="p2"><br></p>
236 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>b.step=55; </span>//make the step a fraction of the freq</p>
237 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>b.focus;</p>
238 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.front;</p>
239 <p class="p2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
240 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">CmdPeriod</span>.doOnce({w.close});</p>
241 <p class="p2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
242 <p class="p12"><span class="Apple-tab-span"> </span>});</p>
243 <p class="p12"><span class="Apple-tab-span"> </span>)</p>
244 <p class="p4"><br></p>
245 <p class="p5">Recieving values, however is asynchronous, and requires either using an OSCresponderNode, or polling values.</p>
246 <p class="p5">In this example a Routine polls values:</p>
247 <p class="p4"><br></p>
248 <p class="p12"><span class="Apple-tab-span"> </span>(</p>
249 <p class="p2"><span class="Apple-tab-span"> </span></p>
250 <p class="p12"><span class="Apple-tab-span"> </span>w = <span class="s3">Window</span>(<span class="s5">"Frequency Monitor"</span>, <span class="s3">Rect</span>(200, <span class="s3">Window</span>.screenBounds.height-200,300,150)).front;</p>
251 <p class="p12"><span class="Apple-tab-span"> </span>w.view.background_(<span class="s3">Color</span>.grey(0.9));</p>
252 <p class="p2"><span class="Apple-tab-span"> </span></p>
253 <p class="p12"><span class="Apple-tab-span"> </span>a = <span class="s3">StaticText</span>(w, <span class="s3">Rect</span>(45, 10, 200, 20)).background_(<span class="s3">Color</span>.rand);</p>
254 <p class="p2"><span class="Apple-tab-span"> </span></p>
255 <p class="p13"><span class="s1"><span class="Apple-tab-span"> </span>a.string = </span>"Current Frequency"<span class="s1">;</span></p>
256 <p class="p2"><span class="Apple-tab-span"> </span></p>
257 <p class="p12"><span class="Apple-tab-span"> </span><span class="s3">Button</span>.new(w, <span class="s3">Rect</span>(45, 70, 200, 20)).states_([[<span class="s5">"close"</span>,<span class="s3">Color</span>.black,<span class="s3">Color</span>.rand]]).action_({w.close});</p>
258 <p class="p2"><span class="Apple-tab-span"> </span></p>
259 <p class="p12"><span class="Apple-tab-span"> </span>s.waitForBoot({</p>
260 <p class="p2"><span class="Apple-tab-span"> </span></p>
261 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>b=<span class="s3">Bus</span>.new(<span class="s9">\control</span>,0,1);</p>
262 <p class="p2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
263 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>q=<span class="s3">SynthDef</span>(<span class="s9">\Docs_FreqMonitor</span>, {<span class="s3">var</span> freq,snd;</p>
264 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>freq=<span class="s3">LFNoise0</span>.ar(2, 400, 650);</p>
265 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>snd=<span class="s3">SinOsc</span>.ar(freq,0,0.2);</p>
266 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">Out</span>.ar(0,snd);</p>
267 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span><span class="s3">Out</span><span class="s1">.kr(b.index,freq); </span>// output the frequency to a control bus</p>
268 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>}).play;</p>
269 <p class="p2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
270 <p class="p14"><span class="s1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>r= </span>Routine<span class="s1">{</span></p>
271 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>{<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>// Set the value of the StaticText to the value in the control bus.</p>
272 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>// Setting GUI values is asynchronous, so you must use .defer in the system clock.</p>
273 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>// Also you must check if the window is still open, since Routine will continue for at least</p>
274 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>// one step after you close the window.</p>
275 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>b.get( {<span class="s3">arg</span> v; {w.isClosed.not.if{ a.string= <span class="s5">" Current Frequency: "</span>++v.round(0.01)}; }.defer} );</p>
276 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>// b.get sends query to the server, and waits for a response before it sets the StaticText.</p>
277 <p class="p2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
278 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>0.01.wait;</p>
279 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>}.loop</p>
280 <p class="p2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
281 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>}.play</p>
282 <p class="p12"><span class="Apple-tab-span"> </span>});</p>
283 <p class="p2"><span class="Apple-tab-span"> </span></p>
284 <p class="p12"><span class="Apple-tab-span"> </span><span class="s3">CmdPeriod</span>.doOnce({w.close});</p>
285 <p class="p12"><span class="Apple-tab-span"> </span>w.onClose={r.stop; q.free; b.free }; <span class="s7">//clean up if the window closes</span></p>
286 <p class="p2"><span class="Apple-tab-span"> </span></p>
287 <p class="p12"><span class="Apple-tab-span"> </span>)</p>
288 <p class="p2"><br></p>
289 <p class="p5">Here an OSCreponder changes a gui. See <a href="../Control/OSCresponderNode.html"><span class="s3">OSCresponderNode</span></a> for more examples. It is important here that the action of the responder is defered.</p>
290 <p class="p4"><br></p>
291 <p class="p2"><br></p>
292 <p class="p12"><span class="Apple-tab-span"> </span>(</p>
293 <p class="p12"><span class="Apple-tab-span"> </span>s.waitForBoot({</p>
294 <p class="p2"><span class="Apple-tab-span"> </span></p>
295 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w=<span class="s3">Window</span>.new.front;</p>
296 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.view.background_(<span class="s3">Color</span>.blue(0.3));</p>
297 <p class="p2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
298 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>x={<span class="Apple-tab-span"> </span><span class="s3">var</span> d,arr,out;</p>
299 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>d = </span><span class="s3">Dust</span><span class="s1">.kr(2,0.2);<span class="Apple-tab-span"> </span></span>// generate triggers for SendTrig and for DynKlank</p>
300 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span><span class="s3">SendTrig</span><span class="s1">.kr(d, 0, 0.9); </span>// send message to lang</p>
301 <p class="p2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
302 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>arr=<span class="s3">Array</span>.fill(4, {<span class="s3">TRand</span>.kr(50+500.rand,1200+1200.rand,d)});</p>
303 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>out=<span class="s3">DynKlank</span>.ar(`[arr, <span class="s3">nil</span>, [1, 1, 1, 1]], <span class="s3">K2A</span>.ar(d)*0.1);</p>
304 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">Limiter</span>.ar(out,0.5)</p>
305 <p class="p2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
306 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>}.play;</p>
307 <p class="p2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
308 <p class="p2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
309 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>// register to receive this message</p>
310 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>a = <span class="s3">OSCresponderNode</span>(s.addr, <span class="s9">'/tr'</span>,</p>
311 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>{ {w.refresh}.defer }).add; <span class="s7">// you must use defer here</span></p>
312 <p class="p2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
313 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.drawHook = {<span class="s3">|me|</span></p>
314 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">Pen</span>.use{</p>
315 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>90.do{</p>
316 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">Pen</span>.strokeColor=<span class="s3">Color</span>.rand.alpha_(rrand(0.1,0.9));</p>
317 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">Pen</span>.addArc(400.rand@400.rand, rrand(10, 100), 2pi.rand, pi);</p>
318 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">Pen</span>.stroke;</p>
319 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>};</p>
320 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>}</p>
321 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>};</p>
322 <p class="p2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
323 <p class="p2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
324 <p class="p2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
325 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span><span class="s3">CmdPeriod</span><span class="s1">.doOnce({w.close}); </span>//close window when sound is stopped</p>
326 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.onClose=({a.remove; x.free;});<span class="s7">// clean up</span></p>
327 <p class="p2"><span class="Apple-tab-span"> </span></p>
328 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>});</p>
329 <p class="p12"><span class="s10"><span class="Apple-tab-span"> </span></span>)</p>
330 <p class="p7"><br></p>
331 <p class="p6"><b>Custom GUI: designing your own widgets using UserView</b></p>
332 <p class="p7"><br></p>
333 <p class="p5">UserView is generally speaking a view in which you can draw, and for which you can define mouse, key, and drag and drop actions. For documentation on all of these, see the <a href="Main-GUI/UserView.html"><span class="s3">UserView</span></a>, <a href="Main-GUI/View.html"><span class="s3">View</span></a>, and <a href="Main-GUI/Pen.html"><span class="s3">Pen</span></a> help files. The example below, however, will demonstrate a basic example of these techniques for designing a widget. The steps you need to take are the following:</p>
334 <p class="p5">(<b>1) Create a User View (2) define a draw function (3) define an action (4) define mouse actions (5) define key actions (6) define drag and drop actions</b>. You can omit steps which you don't want.</p>
335 <p class="p4"><br></p>
336 <p class="p5">Caution, subclassing differs in many points from the example below. For a subclassing template and a quick tutorial on how to write a custom widget as a SCUserView subclass, see <a href="Cocoa-GUI/SCUserViewSubclassing/SCUserView-Subclassing.html"><span class="s3">SCUserView-Subclassing</span></a>.<span class="Apple-tab-span"> </span></p>
337 <p class="p4"><br></p>
338 <p class="p12"><span class="Apple-tab-span"> </span>(</p>
339 <p class="p12"><span class="Apple-tab-span"> </span><span class="s3">var</span> value = 0.5;</p>
340 <p class="p12"><span class="Apple-tab-span"> </span>w = <span class="s3">Window</span>.new.front;</p>
341 <p class="p2"><span class="Apple-tab-span"> </span></p>
342 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span></span>// (1) create a user view</p>
343 <p class="p12"><span class="Apple-tab-span"> </span>v = <span class="s3">UserView</span>(w,<span class="s3">Rect</span>(50,50,200,20));</p>
344 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span></span>// (2) define a drawing function for Pen</p>
345 <p class="p2"><span class="Apple-tab-span"> </span></p>
346 <p class="p12"><span class="Apple-tab-span"> </span>v.drawFunc = {</p>
347 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>// Draw the fill</p>
348 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">Pen</span>.fillColor = <span class="s3">Color</span>.grey;</p>
349 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">Pen</span>.addRect(<span class="s3">Rect</span>(0,0, v.bounds.width*value,v.bounds.height));</p>
350 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">Pen</span>.fill;</p>
351 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>// Draw the triangle</p>
352 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">Pen</span>.fillColor = <span class="s3">Color</span>.red;</p>
353 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">Pen</span>.moveTo(((v.bounds.width*value)-5) @ v.bounds.height);</p>
354 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">Pen</span>.lineTo(((v.bounds.width*value)+5) @ v.bounds.height);</p>
355 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">Pen</span>.lineTo(((v.bounds.width*value)) @ (v.bounds.height/2));</p>
356 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">Pen</span>.lineTo(((v.bounds.width*value)-5) @ v.bounds.height);</p>
357 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">Pen</span>.fill;</p>
358 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>// Draw the frame</p>
359 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">Pen</span>.strokeColor = <span class="s3">Color</span>.black;</p>
360 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">Pen</span>.addRect(<span class="s3">Rect</span>(0,0, v.bounds.width,v.bounds.height));</p>
361 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">Pen</span>.stroke;</p>
362 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>};</p>
363 <p class="p2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
364 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span></span>// (3) set an action to the user view<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
365 <p class="p12"><span class="Apple-tab-span"> </span>v.action = {value.postln; v.refresh};</p>
366 <p class="p2"><span class="Apple-tab-span"> </span></p>
367 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span></span>// (4) define mouse actions</p>
368 <p class="p12"><span class="Apple-tab-span"> </span>v.mouseDownAction = {<span class="s3">arg</span> view, x = 0.5,y, m;</p>
369 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>//m.postln;</p>
370 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>([256, 0].includes(m)).if{ <span class="s7">// restrict to no modifier</span></p>
371 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>value = (x).linlin(0,v.bounds.width,0,1); v.doAction};</p>
372 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>};</p>
373 <p class="p2"><span class="Apple-tab-span"> </span></p>
374 <p class="p12"><span class="Apple-tab-span"> </span>v.mouseMoveAction = v.mouseDownAction;</p>
375 <p class="p2"><span class="Apple-tab-span"> </span></p>
376 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span></span>// (5) (optional) define key actions</p>
377 <p class="p12"><span class="Apple-tab-span"> </span>v.keyDownAction = { <span class="s3">arg</span> view, char, modifiers, unicode,keycode;</p>
378 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>if (unicode == 16rF700, { value = (value+0.1).clip(0,1) });</p>
379 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>if (unicode == 16rF703, { value = (value+0.1).clip(0,1) });</p>
380 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>if (unicode == 16rF701, { value = (value-0.1).clip(0,1) });</p>
381 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>if (unicode == 16rF702, { value = (value-0.1).clip(0,1) });</p>
382 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>v.doAction;</p>
383 <p class="p12"><span class="Apple-tab-span"> </span>};</p>
384 <p class="p2"><span class="Apple-tab-span"> </span></p>
385 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span></span>// (6) (optional) define drag and drop</p>
386 <p class="p12"><span class="Apple-tab-span"> </span>v.beginDragAction = {value}; <span class="s7">// what to drag</span></p>
387 <p class="p12"><span class="Apple-tab-span"> </span>v.canReceiveDragHandler = {<span class="s3">View</span>.currentDrag.isNumber}; <span class="s7">// what to receive</span></p>
388 <p class="p12"><span class="Apple-tab-span"> </span>v.receiveDragHandler = {value = <span class="s3">View</span>.currentDrag; v.doAction }; <span class="s7">// what to do on receiving</span></p>
389 <p class="p2"><span class="Apple-tab-span"> </span></p>
390 <p class="p2"><span class="Apple-tab-span"> </span></p>
391 <p class="p8"><span class="s1"><span class="Apple-tab-span"> </span></span>// just for testing drag and drop</p>
392 <p class="p12"><span class="Apple-tab-span"> </span><span class="s3">Slider</span>(w,<span class="s3">Rect</span>(50,100,200,20));</p>
393 <p class="p2"><span class="Apple-tab-span"> </span></p>
394 <p class="p13"><span class="s1"><span class="Apple-tab-span"> </span></span><span class="s3">StaticText</span><span class="s1">(w,</span><span class="s3">Rect</span><span class="s1">(50,150,350,50)).string_(</span>"To Test Drag and Drop,\nHold down Cmd (Ctl) Key"<span class="s1">);</span></p>
395 <p class="p2"><span class="Apple-tab-span"> </span></p>
396 <p class="p12"><span class="Apple-tab-span"> </span>)</p>
397 <p class="p2"><br></p>
398 <p class="p6"><b>Automatic GUI</b></p>
399 <p class="p7"><br></p>
400 <p class="p5">You can get a quick simple automatic interface for a <a href="../ServerArchitecture/Synth.html"><span class="s3">Synth</span></a> with <a href="../ServerArchitecture/SynthDesc.html"><span class="s3">SynthDesc</span></a> : makeWindow.</p>
401 <p class="p4"><br></p>
402 <p class="p12"><span class="Apple-tab-span"> </span>(</p>
403 <p class="p12"><span class="Apple-tab-span"> </span>s.waitForBoot({</p>
404 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">SynthDef</span>(<span class="s5">"test"</span>, { <span class="s3">arg</span> out, freq=330, amp=0.6;</p>
405 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">Out</span>.ar(out, <span class="s3">SinOsc</span>.ar(freq,0,amp))</p>
406 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>}).add;</p>
407 <p class="p2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
408 <p class="p2"><span class="Apple-tab-span"> </span></p>
409 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">SynthDescLib</span>.global.at(<span class="s9">\test</span>).makeWindow;</p>
410 <p class="p12"><span class="Apple-tab-span"> </span>});</p>
411 <p class="p12"><span class="Apple-tab-span"> </span>)</p>
412 <p class="p2"><br></p>
413 <p class="p2"><br></p>
414 <p class="p6"><b>Helper Methods in GUI</b></p>
415 <p class="p7"><br></p>
416 <p class="p5"><b>*stringBounds( string, font )</b></p>
417 <p class="p4"><br></p>
418 <p class="p5">Returns a Rect object describing the bounds occupied by the given string if it was painted using the given font. Note that this method is asynchronous in SwingOSC, hence it is advised to use it inside a Routine.(not necessary on CocoaGUI). Example:</p>
419 <p class="p4"><br></p>
420 <p class="p12"><span class="Apple-tab-span"> </span>(</p>
421 <p class="p12"><span class="Apple-tab-span"> </span>{</p>
422 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">var</span> text = <span class="s5">"Test"</span>, bounds, font, fonts, rect = <span class="s3">Rect</span>.new, total = <span class="s3">Rect</span>.new;</p>
423 <p class="p2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
424 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>fonts = <span class="s3">Font</span>.availableFonts;</p>
425 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w = <span class="s3">Window</span>.new( <span class="s5">"String Bounds"</span>, resizable: <span class="s3">false</span> );</p>
426 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.view.background = <span class="s3">Color</span>.blue;</p>
427 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>10.do({</p>
428 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>font<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>= <span class="s3">Font</span>( fonts.choose, exprand( 6, 36 ));</p>
429 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>bounds<span class="Apple-tab-span"> </span>= <span class="s3">GUI</span>.stringBounds( text, font );</p>
430 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>rect.set( rect.right, rect.bottom, bounds.width + 4, bounds.height + 2 );</p>
431 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">StaticText</span>.new( w, rect )</p>
432 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>.font_( font ).align_( <span class="s9">\center</span> ).string_( text ).background_( <span class="s3">Color</span>.white );</p>
433 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>total<span class="Apple-tab-span"> </span>= total.union( rect );</p>
434 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>});</p>
435 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.bounds = total.moveTo( 200, 200 );</p>
436 <p class="p12"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.front;</p>
437 <p class="p12"><span class="Apple-tab-span"> </span>}.fork( <span class="s3">AppClock</span> );</p>
438 <p class="p12"><span class="Apple-tab-span"> </span>)</p>
439 <p class="p4"><br></p>
440 <p class="p6"><b>Browsers and Inspectors</b></p>
441 <p class="p4"><br></p>
442 <p class="p5">These classes use the current GUI kit implementation as returned by <span class="s11">GUI</span><span class="s12">.current</span> . You usually do not instantiate them directly, but use one of the "Plus-GUI" methods described in the next paragraph.</p>
443 <p class="p4"><br></p>
444 <p class="p5">ObjectInspector</p>
445 <p class="p5">StringInspector</p>
446 <p class="p5">ClassInspector</p>
447 <p class="p5">FunctionDefInspector</p>
448 <p class="p5">MethodInspector</p>
449 <p class="p5">SlotInspector</p>
450 <p class="p5">FrameInspector</p>
451 <p class="p4"><br></p>
452 <p class="p5">ClassBrowser</p>
453 <p class="p4"><br></p>
454 <p class="p7"><br></p>
455 <p class="p5">"Plus-GUI" methods are methods added to other classes such as <a href="../Collections/String.html"><span class="s3">String</span></a> or <a href="../ServerArchitecture/Server.html"><span class="s3">Server</span></a> that provide GUI functionality for those classes. These methods use the current GUI kit implementation as returned by <span class="s11">GUI</span><span class="s12">.current</span> .</p>
456 <p class="p4"><br></p>
457 <p class="p17">.inspect</p>
458 <p class="p5"><span class="Apple-tab-span"> </span>Examples for Inspectors:</p>
459 <p class="p17"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">Server</span>.default.inspect;</p>
460 <p class="p17"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">Server</span>.inspect;</p>
461 <p class="p4"><br></p>
462 <p class="p18">.browse</p>
463 <p class="p5"><span class="Apple-tab-span"> </span>Examples for Browsers:</p>
464 <p class="p11"><span class="s1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span><span class="s3">UGen</span><span class="s1">.browse;<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>// ClassBrowser</p>
465 <p class="p17"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">SynthDescLib</span>( <span class="s7">\myLib</span> ).read.browse;</p>
466 <p class="p4"><br></p>
467 <p class="p18">.makeWindow</p>
468 <p class="p5"><span class="Apple-tab-span"> </span>Examples for Server:</p>
469 <p class="p17"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>if( s.window.notNil, {s.window.close});</p>
470 <p class="p17"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>s.makeWindow;</p>
471 <p class="p17"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>s.scope;</p>
472 <p class="p4"><br></p>
473 <p class="p18">.plot</p>
474 <p class="p5"><span class="Apple-tab-span"> </span>Examples for Plotting:</p>
475 <p class="p3"><span class="s1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>see <a href="../Collections/ArrayedCollection.html"><span class="s2">ArrayedCollection</span></a>, <a href="../ServerArchitecture/Buffer.html"><span class="s2">Buffer</span></a>, <a href="../Control/Env.html"><span class="s2">Env</span></a>, <a href="../Core/Kernel/Function.html"><span class="s2">Function</span></a>, <a href="../Collections/Signal.html"><span class="s2">Signal</span></a>, <a href="../Files/SoundFile.html"><span class="s2">SoundFile</span></a>, <a href="../Collections/Wavetable.html"><span class="s2">Wavetable</span></a></span></p>
476 <p class="p4"><br></p>
477 <p class="p18">.scope</p>
478 <p class="p5"><span class="Apple-tab-span"> </span>Examples for Scoping</p>
479 <p class="p3"><span class="s1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>see <a href="../ServerArchitecture/Bus.html"><span class="s2">Bus</span></a>, <a href="../Core/Kernel/Function.html"><span class="s2">Function</span></a>, <a href="../ServerArchitecture/Server.html"><span class="s2">Server</span></a>, <a href="../UGens/UGen.html"><span class="s2">UGen</span></a></span><span class="s3">, <a href="Main-GUI/ScopeView.html"><span class="s4">ScopeView</span></a>, <a href="Main-GUI/Stethoscope.html"><span class="s4">Stethoscope</span></a></span></p>
480 <p class="p4"><br></p>
481 <p class="p7"><br></p>
482 </body>
483 </html>