SCUserView user-definable view

superclass: SCView

SCUserView is a user-definable View intended mainly for use with Pen and drawHooks.

See also: SCWindow, Pen, Color, and String

keyDownAction_

Set the function which should be evaluated if the view is in focus and a key is pressed. This function will be passed four arguments: the View, the key pressed as a Char, modifier keys (shift, alt, etc.), and the unicode value. See SCView for more details.

(

// select the window, type something and watch the post window

w = SCWindow.new("select this window and type something");

c = SCUserView(w,w.view.bounds);

c.keyDownAction = { arg view,char,modifiers,unicode;

[char, modifiers, unicode].postln;

c.drawFunc = {|me|

char.asString.drawAtPoint(180@150, Font("Helvetica", 70), Color.blue(0.3, 0.5))

};

c.refresh;

};

w.front; c.focus;

)

drawFunc_

Set the function which should be evaluated if the view is refreshed. This happens every time the view or the whole window is refreshed (manually by calling SCView:refresh, SCWindow:refresh or e.g. by selecting the view or resizing the window).

(

var func;

func = {|me|

Pen.use{

// clipping into the boundingbox

Pen.moveTo((me.bounds.left)@(me.bounds.top));

Pen.lineTo(((me.bounds.left)@(me.bounds.top))

+ (me.bounds.width@0));

Pen.lineTo(((me.bounds.left)@(me.bounds.top))

+ (me.bounds.width@me.bounds.height));

Pen.lineTo(((me.bounds.left)@(me.bounds.top))

+ (0@me.bounds.height));

Pen.lineTo((me.bounds.left)@(me.bounds.top));

Pen.clip;

// draw background

Color.gray(0.5).set;

Pen.moveTo((me.bounds.left)@(me.bounds.top));

Pen.lineTo(((me.bounds.left)@(me.bounds.top))

+ (me.bounds.width@0));

Pen.lineTo(((me.bounds.left)@(me.bounds.top))

+ (me.bounds.width@me.bounds.height));

Pen.lineTo(((me.bounds.left)@(me.bounds.top))

+ (0@me.bounds.height));

Pen.lineTo((me.bounds.left)@(me.bounds.top));

Pen.fill;

Pen.translate(100, 100);

10.do{

Color.red(rrand(0.0, 1), rrand(0.0, 0.5)).set;

Pen.addArc((400.exprand(2))@(100.rand), rrand(10, 100), 2pi.rand, pi);

Pen.perform([\stroke, \fill].choose);

}

}

};

w = SCWindow.new("DrawFunc Examples").front;

w.view.background_(Color.white);

3.do{|i|

v = SCUserView(w, Rect(20+(i*120), 100, 100, 100));

v.drawFunc = func;

};

w.refresh;

)

relativeOrigin_

Set the Origin of Pen in the view's drawFunc relative to the SCUserView.

(

var func;

func = {|me|

Pen.use{

10.do{

Color.red(rrand(0.0, 1), rrand(0.0, 0.5)).set;

Pen.addArc((400.exprand(2))@(100.rand), rrand(10, 100), 2pi.rand, pi);

Pen.perform([\stroke, \fill].choose);

}

}

};

w = SCWindow.new("DrawFunc Examples").front;

w.view.background_(Color.white);

3.do{|i|

v = SCUserView(w, Rect(20+(i*120), 100, 100, 100))

.drawFunc_(func).relativeOrigin_(true);

};

w.refresh;

)

mousePosition

Get the relative position of the mouse cursor.

mouseDownAction_

Set the function which should be evaluated if the mouse is at the beginning of tracking (mouse-down). This function will be passed four arguments: theView, x coordinate, y coordinate, and keyboard modifiers.

mouseMoveAction_

Set the function which should be evaluated if the mouse is tracked. This function will be passed four arguments: theView, x coordinate, y coordinate, and keyboard modifiers.

mouseUpAction_

Set the function which should be evaluated if the mouse is at the end of tracking (mouse-up). This function will be passed four arguments: theView, x coordinate, y coordinate, and keyboard modifiers.

(

var drawFunc, beginTrackFunc, endTrackFunc, trackFunc, sat = 0, absX;

drawFunc = {|me|

Pen.use{

10.do{

Color.red(rrand(0.0, 1), rrand(0.0, 0.5)).set;

Pen.addArc((400.exprand(2))@(100.rand), rrand(10, 100), 2pi.rand, pi);

Pen.perform([\stroke, \fill].choose);

}

}

};

beginTrackFunc = {|me, x, y, mod|

absX = x;

postf("begin path: x=% realtive mousePosition:%\n",absX, me.mousePosition);

};

endTrackFunc = {|me, x, y, mod|

postf("end path: (absX-x)==% realtive mousePosition:%\n",(absX-x), me.mousePosition);

};

trackFunc = {|me, x, y, mod|

sat = ((absX-x)/100);

((me.mousePosition)/(me.bounds.width@me.bounds.height)).postln;

me.refresh;

};

w = SCWindow.new.front;

w.view.background_(Color.white);

3.do{|i|

v = SCUserView(w, Rect(20+(i*120), 100, 100, 100));

//v.background_(Color.white); // not affecting anything...

v.drawFunc = drawFunc;

v.mouseDownAction = beginTrackFunc;

v.mouseUpAction = endTrackFunc;

v.mouseMoveAction = trackFunc;

v.relativeOrigin = true;

};

w.refresh;

)

// draw on the view

(

var w, txt, tmppoints, all;

tmppoints = [];

w = SCWindow("draw on me", Rect(128, 64, 340, 360));

v = SCUserView(w,w.view.bounds)

.mouseMoveAction_({|v,x,y|

[x,y].postln;

tmppoints = tmppoints.add(v.mousePosition);

v.refresh;

})

.mouseUpAction_({|v,x,y|

all = all.add(tmppoints.copy);

tmppoints = [];

v.refresh;

})

.drawFunc_{|me|

Pen.use {

Color.white.set;

Pen.fillRect(me.bounds.moveTo(0,0));

Pen.width = 1;

Color.black.set;

Pen.beginPath;

tmppoints.do{ |p, i|

if(i == 0){

Pen.moveTo(p);

}{

Pen.lineTo(p);

}

};

all.do{|points|

points.do{|p, i|

if(i == 0){

Pen.moveTo(p);

}{

Pen.lineTo(p);

}

};

};

Pen.stroke;

};

};

v.relativeOrigin = true;

w.front;

)

clearOnRefresh_

Set the behaviour for refreshing the view. If this flag is true (the default) the view will be cleared before each refresh call, otherwise It will draw in top of it. On OSX this functionality is only available for the version >= 10.4 and with the flag relativeOrigin set to true.

(

var width = 640, height = 480, w, theta = 0, drawFunc, gui;

gui = GUI.get( \cocoa );

w = gui.window.new( "clearOnRefresh = true", Rect( 128, 64, width, height ), false );

drawFunc = { arg view;

var x = 20 * sin( theta ), y = 42 * cos( theta );

gui.pen.addRect( view.bounds.moveTo( 0, 0 ));

gui.pen.clip;

theta = theta + 0.01;

gui.pen.fillColor_( Color.red( 0.2, 0.1 ));

gui.pen.fillRect( Rect( 0, 0, width, height ));

gui.pen.strokeColor_( Color.white );

gui.pen.translate( width * 0.5, height * 0.5 );

6.do { arg i;

gui.pen.rotate( theta * (1 - (i / 6)) );

gui.pen.scale( 0.7 + (i * 0.4), 0.4 + (i * 0.5) );

gui.pen.strokeOval( Rect.aboutPoint( Point( x, y ), 60, 40 ));

};

};

x = gui.userView.new( w, Rect( 10, 10, width - 20, height - 20 ))

.canFocus_( false )

.drawFunc_( drawFunc )

.clearOnRefresh_( false )

.relativeOrigin_( true );

w.front;

Routine({ while({ x.isClosed.not }, { x.refresh; (1/25).wait })}).play( AppClock );

)

(

var width= 640, height= 480, w, theta= 0, drawFunc;

w= GUI.window.new("trail test3", Rect(128, 64, width, height), false);

drawFunc= {|v|

var x= 20*sin(theta), y= 42*cos(theta);

theta= theta+0.01;

GUI.pen.fillColor_(Color.red(0.2, 0.1));

GUI.pen.fillRect(Rect(0, 0, width, height));

GUI.pen.strokeColor_(Color.white);

GUI.pen.push;

GUI.pen.translate(width*0.5, height*0.5);

6.do{|i|

GUI.pen.rotate(theta*(1-(i/6)));

GUI.pen.scale(0.7+(i*0.4), 0.4+(i*0.5));

GUI.pen.strokeOval(Rect.aboutPoint(Point(x, y), 60, 40))

};

GUI.pen.pop;

};

GUI.userView.new(w, Rect(10, 10, width-20, height-20)).drawFunc_(drawFunc).relativeOrigin_(true);

w.front;

Routine({inf.do{|i| w.refresh; (1/25).wait}}).play(AppClock);

)

prevent redrawing:

(

var func, views;

func = {|me|

Pen.use{

10.do{

Color.red(rrand(0.0, 1), rrand(0.0, 0.5)).set;

Pen.addArc((400.exprand(2))@(100.rand), rrand(10, 100), 2pi.rand, pi);

Pen.perform([\stroke, \fill].choose);

}

}

};

w = SCWindow.new("DrawFunc Examples").front;

w.view.background_(Color.white);

views = {|i|

v = SCUserView(w, Rect(20+(i*120), 100, 100, 100)).relativeOrigin_(true);

v.drawFunc = func;

} ! 3;

w.refresh;

{views.do{|v| v.clearOnRefresh_(false);v.drawFunc = nil}}.defer(0.4);

)