SuperCollider:图形化用户界面

SC3的图形化用户界面类

Server.default=s=Server.local;

SC3的GUI类包括量程(Range)和2D滑杆,拖放工具,下拉列表,多滑杆和其它很多很多,,

同时按下shift+cmd+N (Mac机)看看可选的GUI小工具。

GD_ToolboxWindow()	// 展示GUI建设的第三方类

在这份教程中,SwingOSC用户(这包括了使用PsyCollider的任何人)将需要在以下所有GUI代码前加上J,或使用另一个可替代文件(5.2b GUI与SwingOSC)

SwingOSC.default.boot;

做一个窗口

// Rect定义初始的萤幕位置和窗口大小
// screenx,screeny, windowwidth, windowheight是其引数
// 原点(0,0)为萤幕左下角
(
var w;

w=SCWindow("My Window", Rect(100,500,200,200));
// 一个200*200的窗口出现在萤幕坐标点(100, 500)

w.front; // 这行代码显示窗口
)

注意,萤幕的原点坐标(0,0)在萤幕左下角,相对的,窗口坐标点(100,500)也在窗口左下角。


我们为我们的窗口加入控制,定义它们使用的参数。我们在窗口内再次使用一个Rect新建一个控制器,并决定它在窗口内的位置和大小。

(
var w, slid;

w=SCWindow("My Window", Rect(100,500,200,200));
//一个200*200的窗口出现在萤幕坐标点(100, 500)

slid=SCSlider(w,Rect(10,10,150,40)); //一个基础的滑杆对象 

// 这是收回(callback)——任何时候当你移动滑杆,这个函数都将被调用
slid.action_({slid.value.postln;});

w.front;
)

注意滑杆默认的范围是0.0~1.0。


对此来说,ControlSpec是一个很有帮助的UGen,它可以将默认的范围转变到任何想要的范围。

(
var w, slid, cs;

w=SCWindow("My Window", Rect(100,500,200,200));
//一个200*200的窗口出现在萤幕坐标点(100, 500)

slid=SCSlider(w,Rect(10,10,150,40));

//引数为最小值、最大值、warp(映射函数)、递增量和起始值
cs= ControlSpec(20, 20000, 'exp', 10, 1000); 

slid.action_({cs.map(slid.value).postln;}); //map to the desired range

w.front;
)

2d slide
2d slide

运用2D滑杆进行声音合成的的小样

(
SynthDef(\filterme,
{arg freq=1000, rq=0.5;
Out.ar(0,
Pan2.ar(
BPF.ar(Impulse.ar(LFNoise0.kr(15,500,1000),0.1, WhiteNoise.ar(2)),freq,rq)
))
}).load(s)
)

(
var w, slid2d, syn;

w=SCWindow("My Window", Rect(100,300,200,200));
slid2d= SC2DSlider(w,Rect(5,5,175,175));

syn=Synth(\filterme);

slid2d.action_({
[slid2d.x, slid2d.y].postln;
// 我在这做自己的映射,而不是使用ControlSpec
syn.set(\freq,100+(10000*slid2d.y),\rq,0.01+(0.09*slid2d.x));
});

w.front;

w.onClose={syn.free;};
)

更进一步的探索:
要尝试拖放和其它UI工具,可以打开SC范例文件夹内的GUI examples文件夹查阅。


(
// 创建一个含一些数字盒的GUI窗口
// 你可以在按下cmd键的同时鼠标左键
// 拖动一个数字到另一个数字上以替换后者的值
var w, n, f, s;
w = SCWindow("number box test", Rect(128, 64, 260, 80));
w.view.decorator = f = FlowLayout(w.view.bounds);

n = SCNumberBox(w, Rect(0,0,80,24));
n.value = 123;

n = SCNumberBox(w, Rect(0,0,80,24));
n.value = 456;

n = SCDragBoth(w, Rect(0,0,80,24));
n.object = 789;

f.nextLine;

s = SCSlider(w, Rect(0,0,240,24));

w.front;
)

同样的,还有其它一些有趣的GUI对象的帮助文档:

赞许一下——很多更有趣的GUI对象是由Jan Trutzschler引入SuperCollider的。
[SCMultiSliderView]
[SCEnvelopeView]

还有一些媒体预览对象
[SCSoundFileView]

(
w = SCWindow.new("soundfile test", Rect(200, 200, 800, 400));
a = SCSoundFileView.new(w, Rect(20,20, 700, 60));

f = SoundFile.new;
f.openRead("sounds/a11wlk01.wav");

a.soundfile_(f);
a.read(0, f.numFrames);

a.gridOn_(false);

w.front;
)

[SCMovieView]

(
z = SCWindow.new.front;
z.view.decorator = FlowLayout(z.view.bounds);

a=SCMovieView(z,Rect(0,0, 300,300));

//you need to put a path to a video file on your hard drive
a.path_("/Volumes/data/video/icmc/klippav-duck_cutup.mov")
)

a.stepForward

Pen类可作为一个萤幕绘制工具

(
var w, h = 400, v = 400, seed = Date.seed, run = true;
w = SCWindow("subdiv", Rect(400, 200, h, v));
w.view.background = Color.rand;
w.onClose = { run = false };
w.front;
w.drawHook = { var done, nextx, nexty, yellowness, penwidth;

nextx=0;
nexty=0;
yellowness=rrand(0.0,1.0);

penwidth=rrand(0.5,1.5);

//done=0;
	Pen.use {

		200.do({arg i;
		var lastx,lasty;
		lastx=nextx;
		lasty=nexty;

		nextx=nextx+rrand(1,20);
		nexty=nexty+rrand(1,40);

		if(nextx>=h, {nextx=nextx%h});
		if(nexty>=v, {nexty=nexty%v});

		penwidth=(penwidth+(0.2.rand2))%8.0;

		Pen.width= penwidth;

		yellowness= (yellowness+(0.1.rand2))%2.0;

		Color.yellow(yellowness).set;

		Pen.beginPath;
		Pen.line(Point(lastx,lasty),Point(nextx,nexty));
		Pen.rotate(rand(i%40));
		Pen.line(Point(lastx,lasty),Point(nextx,nexty));
		Pen.rotate(rand(i%40));
		Pen.line(Point(lastx,lasty),Point(nextx,nexty));
		Pen.rotate(rand(i%40));
		Pen.line(Point(lastx,lasty),Point(nextx,nexty));
			Pen.stroke;

		//Pen.fillRect(Rect(h.rand,v.rand,rrand(1,50),rrand(1,50)))

		});
	};

};

//{ while { run } { w.refresh; 3.wait; } }.fork(AppClock)

)

你同样可以用它来进行文字处理….

(
var linetext, drawletter;
var w, h = 800, v = 60, seed = Date.seed, run = true;
var time, name, sourcestring;
var yellowness, penwidth;

//name=[\s,\u,\p,\e,\r,\c,\o,\l,\l,\i,\d,\e,\r];

//sourcestring= "any lower case text";

sourcestring= "welcome to supercollider";

name=Array.fill(sourcestring.size,{arg i; sourcestring[i].asSymbol});

time=0;

linetext= (
'a':[[[0,1],[0.5,0]],[[0.5,0],[1,1]],[[0.25,0.5],[0.75,0.5]]],
'b':[[[0,1],[0,0]],[[0,1],[1,1]],[[0,0],[1,0]],[[0,0.5],[0.75,0.5]],[[0.75,0.5],[1,0.75]],[[0.75,0.5],[1,0.25]],[[1,0.75],[1,1]],[[1,0.25],[1,0]]],
'c':[[[0,1],[0,0]],[[0,0],[1,0]],[[0,1],[1,1]]],
'd':[[[0,1],[0,0]],[[0,0],[0.75,0]],[[0,1],[0.75,1]],[[0.75,1],[1,0.75]],[[0.75,0],[1,0.25]],[[1,0.25],[1,0.75]]],
'e':[[[0,0],[0,1]],[[0,0],[1,0]],[[0,1],[1,1]],[[0,0.5],[1,0.5]]],
'f':[[[0,0],[0,1]],[[0,0],[1,0]],[[0,0.5],[1,0.5]]],
'g':[[[0,1],[0,0]],[[0,0],[1,0]],[[0,1],[1,1]],[[1,1],[1,0.5]],[[0.5,0.5],[1,0.5]]],
'h':[[[0,1],[0,0]],[[0,0.5],[1,0.5]],[[1,1],[1,0]]],
'i':[[[0,0],[1,0]],[[0.5,0],[0.5,1]],[[0,1],[1,1]]],
'j':[[[0,0],[1,0]],[[0.5,0],[0.5,1]],[[0,1],[0.5,1]]],
'k':[[[0,1],[0,0]],[[0,0.5],[1,1]],[[0,0.5],[1,0]]],
'l':[[[0,1],[0,0]],[[0,1],[1,1]]],
'm':[[[0,1],[0,0]],[[0,0],[0.5,0.5]],[[0.5,0.5],[1,0]],[[1,0],[1,1]]],
'n':[[[0,1],[0,0]],[[0,0],[1,1]],[[1,1],[1,0]]],
'o':[[[0,1],[0,0]],[[0,0],[1,0]],[[0,1],[1,1]],[[1,0],[1,1]]],
'p':[[[0,0],[0,1]],[[0,0],[1,0]],[[0,0.5],[1,0.5]],[[1,0],[1,0.5]]],
'q':[[[0,0],[0,0.75]],[[0,0],[0.75,0]],[[0,0.75],[0.75,0.75]],[[0.75,0],[0.75,0.75]],[[0.5,0.5],[1,1]]],
'r':[[[0,0],[0,1]],[[0,0],[1,0]],[[0,0.5],[1,0.5]],[[1,0],[1,0.5]],[[0,0.5],[1,1]]],
's':[[[0,0],[0,0.5]],[[0,0],[1,0]],[[0,1],[1,1]],[[0,0.5],[1,0.5]],[[1,0.5],[1,1]]],
't':[[[0,0],[1,0]],[[0.5,0],[0.5,1]]],
'u':[[[0,1],[0,0]],[[0,1],[1,1]],[[1,0],[1,1]]],
'v':[[[0,0],[0.5,1]],[[0.5,1],[1,0]]],
'w':[[[0,0],[0.25,1]],[[0.25,1],[0.5,0.5]],[[0.5,0.5],[0.75,1]],[[0.75,1],[1,0]]],
'x':[[[0,0],[1,1]],[[0,1],[1,0]]],
'y':[[[0,0],[0.5,0.5]],[[0.5,0.5],[1,0]],[[0.5,0.5],[0.5,1]]],
'z':[[[0,1],[1,0]],[[0,0],[1,0]],[[0,1],[1,1]]],
(" ".asSymbol):[[[0,1],[1,1]],[[0,0.8],[0,1]],[[1,0.8],[1,1]]]
);

w = SCWindow("welcome", Rect(40, 500, h, v));
w.view.background = Color.blue(0.5);
w.onClose = { run = false };
w.front;

drawletter={arg which, startx, starty, xscale=100, yscale,prop=1.0;
var data;

yscale= yscale ? xscale;

data= linetext[which];

prop=(round((data.size)*prop).asInteger).max(1);

prop.do({arg i;
var val=data[i];

Pen.beginPath;
Pen.line(Point(startx+(xscale*val[0][0]),starty+(yscale*val[0][1])),Point(startx+(xscale*val[1][0]),starty+(yscale*val[1][1])));
Pen.stroke;

});

};

yellowness=rrand(0.7,0.9);

penwidth=rrand(2,3);

w.drawHook = {

	Pen.use {var xoscil, xsizoscil,yoscil, todraw, usedtime;

		Pen.width= penwidth;
		Color.yellow(yellowness).set;

		usedtime=time.min(1.0);

		todraw=(round((name.size)*usedtime).asInteger).max(1);

		todraw.do({arg j;

		xoscil= sin(2*pi*time+(j*pi*0.13))*140/(1+(10*time));

		yoscil= sin(2*pi*time+(j*pi*0.03))*200/(1+(200*time));

		xsizoscil= time*5+5;
				drawletter.value(name[j],50+(25*j)+(xoscil),10+yoscil,xsizoscil,xsizoscil,usedtime);

		});
	};
};

{ while { time<2.0 } { 

w.refresh;
time=(time+0.025); // %2.0;
0.05.wait; } }.fork(AppClock)
)
Be Sociable, Share!

发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.