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滑杆进行声音合成的的小样
(
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)
)
