scide: implement selectionLength for openDocument
[supercollider.git] / HelpSource / Classes / TabletView.schelp
blob451c519b6fe5ee3fd2804baed16b3a49a7c12bf0
1 CLASS:: TabletView
2 redirect:: implClass
3 summary:: A view responding to Wacom tablet
4 categories:: GUI>Views
5 related:: Classes/TabletSlider2D
7 DESCRIPTION::
9 An otherwise featureless view that receives extended wacom tablet data. It can also be used with a normal mouse but with less resolution.
11 note::
12 TabletView is not implemented in Qt GUI, and is only available in other GUI kits on Mac OS X.
14 To use it in SwingOSC, install the JNI library:
16 code:: $ cp JNITablet/build/libJNITablet.jnilib /Library/Java/Extensions/ ::
18 or make a symbolic link:
20 code:: $ ln -s <absolutePathToSwingOSC>/JNITablet/build/libJNITablet.jnilib /Library/Java/Extensions/ ::
23 strong::Drag-and-drop:: returns and accepts a Point, describing the current x and y value.
25 The default link::Classes/View#-action#action:: is triggered when dragging the mouse inside the view.
27 All the strong::mouse actions:: ( link::Classes/View#-action#action::, link::Classes/View#-mouseDownAction#mouseDownAction::, and link::Classes/View#-mouseUpAction#mouseUpAction:: ) receive the following arguments:
29 table::
31 ## view || the view
33 ## x || subpixel location in view
35 ## y || subpixel location in view
37 ## pressure || 0..1
39 ## tiltX || -1 (max. left) ... +1 (max. right)
41 ## tiltY || -1 (max. down) ... +1 (max. up)
43 ## deviceID || All tablet-pointer events generated in the period between the device entering and leaving tablet proximity have the same device ID. Therefore, when working with multiple tablets / mice, you can match actions by looking at the deviceID.
45 ## buttonNumber || 0 left, 1 right, 2 middle wheel click. see also buttonMask below.
47 ## clickCount || double click, triple click ... most relevant for the mouseDown, but still valid for the dragged and mouseUp
49 ## absoluteZ || the wheel on the side of some mice
51 ## rotation || in degrees. Used for example on the "4d mouse", and the "art marker". Note: on Mac OS X 10.4.11 using an Intuos3 tablet with Art Marker, the returned value must be multiplied by 1024 to actually obtain degrees (bug?).
55 These additional arguments are only delivered in SwingOSC:
57 table::
59 ## absoluteX || the absolute horizontal pen position on tablet (in tablet-native high-resolution)
61 ## absoluteY || the absolute vertical pen position on tablet (in tablet-native high-resolution)
63 ## buttonMask || a flag mask of all buttons on the pen / tablet. you can extract each button's state using a bitAnd: buttonMask.bitAnd( 1 << n ) where n = 0, 1, 2, ...
65 ## tanPressure || Tangential pressure is also known as barrel pressure.
69 note::
70 If using a mouse (even a wacom) rather than a pen, the x and y will be integer pixel values, rather than subpixel floats.  Wacom stylus devices have higher resolution than the screen.  Pressure will be 1 for mouse down, 0 for mouse up.
73 CLASSMETHODS::
75 PRIVATE:: key
77 INSTANCEMETHODS::
79 METHOD:: proximityAction
80     note:: Only in SwingOSC GUI ::
82     The action will be called with the following arguments:
84 table::
86 ## view || true to indicate that a pointing device is entering the proximity of its tablet and false when it is leaving it.
88 ## entering || true to indicate that a pointing device is entering the proximity of its tablet and false when it is leaving it.
90 ## deviceID || All tablet-pointer events generated in the period between the device entering and leaving tablet proximity have the same device ID. Therefore, when working with multiple tablets / mice, you can match actions by looking at the deviceID.
92 ## pointingDeviceTypes ||
93 0 NSUnknownPointingDevice
94 1 NSPenPointingDevice
95 2 NSCursorPointingDevice
96 3 NSEraserPointingDevice
98 ## systemTabletID || If multiple tablets are connected to the system, the system-tablet ID is incremented for each subsequent one. If there is only one tablet device, its system-tablet ID is zero.
100 ## pointingDeviceID || This index is significant for multimode (or Dual Tracking) tablets that support multiple concurrent pointing devices; the index is incremented for each pointing device that comes into proximity. Otherwise, zero is always returned.
102 ## tabletID || Returns the USB model identifier of the tablet device associated with the receiver.
104 ## uniqueID || Also known as tool ID, this is a unique number recorded in the chip inside every pointing device. The unique ID makes it possible to assign a specific pointing device to a specific tablet.
110 EXAMPLES::
112 SUBSECTION:: Basic use
114 code::
116 w = Window.new;
117 t = TabletView(w,Rect(40,40,300,300));
118 t.background = Color.white;
119 w.acceptsMouseOver = true;
120 w.front;
122 f = { arg what, x, y, pressure, tiltx, tilty, deviceID, buttonNumber, clickCount,
123     absoluteZ, rotation, absoluteX, absoluteY, buttonMask, tanPressure;
124     ("%: x %  y %  press %  tiltx %  tilty %  clicks %  absX %  absY %  absZ %  rota %  mask %\n")
125     .postf(
126         what, x.round( 0.01 ), y.round( 0.01 ), pressure.round( 0.01 ),
127         tiltx.round( 0.01 ), tilty.round( 0.01 ), clickCount, absoluteX, absoluteY, absoluteZ,
128         rotation.round( 0.01 ), buttonMask
129     );
132 t.mouseDownAction   = { arg view ... params; f.value( "down", *params )};
133 t.action            = { arg view ... params; f.value( "drag", *params )};
134 t.mouseUpAction     = { arg view ... params; f.value( "up  ", *params )};
135 t.mouseOverAction   = { arg view ... params; f.value( "over", *params )};
139 SUBSECTION:: A sound example
141 code::
142 s.boot
145 SynthDef("help-2DTabletSlider", {
146     arg freq = 440, int1 = 5, int2 = -5, ffreqInterval = 0, rq = 0.4, gate = 0.0;
147     var p,c,d,f;
148     c=LFNoise1.kr(0.1,0.45,0.55);
149     d=LFNoise1.kr(0.1,0.45,0.55);
150     f=LFNoise1.kr(0.1,2);
151     p=Pulse.ar([ freq * int1.midiratio + f , freq, freq * int2.midiratio - f],
152         [c,d,c], 0.2);
153     Out.ar(0,
154         RLPF.ar(Mix.ar(p),freq * ffreqInterval.midiratio,rq)
155             * EnvGen.kr(Env.adsr, gate, gate)
156     )
157 },[0.1,0.1,0.1,0.1,0.1,nil]).send(s);
161 var w, v,freq,int,synth;
162 synth = Synth("help-2DTabletSlider");
163 w = Window.new.front;
165 freq = ControlSpec(100,3000,\exp);
166 int = ControlSpec(-48,48,\linear,1);
168 v = TabletView(w,Rect(10,10,380,380));
169 v.background = Color.blue.alpha_(0.2);
170 v.action = { arg view,x,y,pressure,tiltx,tilty;
171     synth.set(
172         \int1, int.map(x),
173         \int2, int.map(y),
174         \ffreqInterval, int.map(pressure),
175         \gate, pressure.postln
176     );
179 v.mouseDownAction = { arg view,x,y,pressure;
180     synth.set(
181         \freq , rrand(30,80).midicps,
182         \gate, pressure.postln
183     )
185 v.mouseUpAction = { arg view,x,y,pressure;
186     synth.set( \gate, 0.postln )
191 SUBSECTION:: Detecting proximity
193 note:: Only in SwingOSC GUI ::
195 code::
197 w = JSCWindow.new;
198 t = JSCTabletView(w,Rect(40,40,300,300));
199 t.background = Color.white;
200 w.acceptsMouseOver = true;
201 w.front;
203 t.proximityAction = { arg view, entering, deviceID, pointingDeviceType,
204     systemTabletID, pointingDeviceID, tabletID, uniqueID;
206     var what = if( entering, "enter", "exit " );
207     ("%: deviceID %  pointingDeviceType %  systemTabletID % pointingDeviceID %  tabletID %  uniqueID %\n")
208     .postf(
209         what, deviceID, pointingDeviceType, systemTabletID,
210         pointingDeviceID, tabletID, uniqueID
211     );
216 SUBSECTION:: JSCTabletView is a also a user view
218 note:: Only in SwingOSC GUI ::
220 code::
222 var x = 150, y = 150, pressure = 0, tiltx = 0, tilty = 0, rota = 0, colr = Color.white;
224 w = JSCWindow.new;
225 t = JSCTabletView( w,Rect( 40, 40, 300, 300 ));
226 t.background = Color.white;
227 w.front;
229 f = { arg view, argX, argY, argPressure, argTiltX, argTiltY, deviceID, buttonNumber,
230             clickCount, absZ, argRota;
231     x = argX; y = argY; pressure = argPressure;
232     tiltx = argTiltX; tilty = argTiltY;
233     rota    = argRota * 1024; // * 1024 for Art Marker...
234     view.refresh;
236 t.drawFunc = { arg view;
237     JPen.fillColor = colr;
238     JPen.fillRect( view.bounds.moveTo( 0, 0 ));
239     JPen.translate( x, y );
240     JPen.width = pressure * 10 + 0.5;
241     JPen.rotate( rota * pi / 180 );
242     JPen.skew( tiltx, tilty );
243     JPen.strokeOval( Rect( -100, -100, 200, 200 ));
244     JPen.line( -100 @ 0, 100 @ 0 );
245     JPen.line( 0 @ -100, 0 @ 100 );
246     JPen.stroke;
249 t.mouseDownAction = f;
250 t.action = f;
251 t.mouseUpAction = f;
252 t.proximityAction = { arg view, entering, deviceID, pointingDeviceType;
253     colr = if( entering, { Color.hsv( pointingDeviceType / 4, 0.5, 1.0 )}, Color.white );
254     view.refresh;
259 Here's a variation: make the above example respond only to a particular pen tools. For this, you need a pen that fires proximity actions and you need to know the pen's uniqueID (see link::#-proximityAction::). For example, my Art Marker has ID 127926421:
261 code::
263 var filterUniqueID = 127926421; // put your own ID here
264 var filterDeviceID = -1;
265 var fProx, fAction;
266 fProx = t.proximityAction;
267 t.proximityAction = { arg view, entering, deviceID, pointingDeviceType,
268                         systemTabletID, pointingDeviceID, tabletID, uniqueID;
269     if( uniqueID == filterUniqueID, {
270         filterDeviceID = deviceID; // now t.action only reacts to events from this deviceID
271         fProx.value( view, entering, deviceID, pointingDeviceType );
272     });
274 fAction = t.action;
275 f = { arg view, x, y, pressure, tiltX, tiltY, deviceID, buttonNumber,
276             clickCount, absZ, rota;
277     if( deviceID == filterDeviceID, {
278         fAction.value( view, x, y, pressure, tiltX, tiltY, deviceID, buttonNumber,
279                 clickCount, absZ, rota );
280     });
282 t.mouseDownAction = f;
283 t.action = f;
284 t.mouseUpAction = f;
288 SUBSECTION:: An example using 'curcial' library
290 code::
292 Instr([\minimoog,\loose],{ arg freq=440,int1=5,int2 = -5,
293             ffreqInterval=0,rq=0.4,gate=0.0;
294     var p,c,d,f;
295     c=LFNoise1.kr(0.1,0.45,0.55);
296     d=LFNoise1.kr(0.1,0.45,0.55);
297     f=LFNoise1.kr(0.1,2);
298     p=Pulse.ar([ freq * int1.midiratio + f , freq, freq * int2.midiratio - f],
299             [c,d,c],0.2);
301     RLPF.ar(Mix.ar(p),freq * ffreqInterval.midiratio,rq)
302         * EnvGen.kr(Env.adsr, gate, Latch.kr(gate,gate))
304 },#[
305     nil,
306     [[-48,48,\linear,1]],
307     [[-48,48,\linear,1]],
308     [[-48,48,\linear,1]]
311 p = Patch.new([ 'minimoog', 'loose' ],[
312     nil,nil,nil,nil,nil,
313     KrNumberEditor(0.0,\gate) // override the default control
316 Sheet({ arg f;
317     var v,freq,int;
318     freq = ControlSpec(100,3000,\exp);
319     int = [-48,48,\linear,1].asSpec;
321     p.topGui(f);
322     v = TabletView(f,Rect(0,0,200,200));
323     v.background = Color.white;
324     v.action = { arg view,x,y,pressure,tiltx,tilty;
325         p.args.at(1).value_( int.map( x / 200 ) ).changed;
326         p.args.at(2).value_( int.map( y / 200 ) ).changed;
327         p.args.at(3).value_( int.map( pressure ) ).changed;
328     };
329     v.mouseDownAction = { arg view,x,y,pressure;
330         p.args.at(0).value_( rrand(30,80).midicps ).changed;
331         p.args.at(5).value_( pressure ).changed;
332     };
333     v.mouseUpAction = { arg view,x,y,pressure;
334         p.args.at(5).value_( 0.0 ).changed;
335     };