GUI parte III
SCPopUpMenu(parent, bounds)
Un menu desplegable para la SCWindow
parent = Ventana en la que queremos que se muestre el menu.
bounds = posición y dimensiones del menu mediante la clase Rect.
El primer método que hay que aprender para SCPopUpMenu es
.items. Al usar este metodo asignamos un array y sus elementos
serán los mismos para el menu y en el mismo orden.Se pueden
poner variables como elementos del array. Observen que si un
elemento el array es un número tiene que estar manejado como
símbolo o como string. Los siguientes métodos son
útiles para convertir números en símbolos o
strings y viceversa.
asString = convierte un número en un string.
12.asString
asSymbol = convierte el número en un símbolo
5.asSymbol
3.2.asSymbol
asInteger = convierte un string en un núero entero.
También elimina la parte decimal de un número racional.
"23".asInteger;
56.123.asInteger
Para convertir un
símbolo en un número lo hacemos así:
\45.asString.asInteger
asFloat = convierte un string en un número racional o de punto
flotante o con decimales.
"1.01".asFloat
Ejemplo 1
(
var panel, menu, elementoX=23, elementoY="hola";
panel=SCWindow("menu", Rect(200,200,400,200)).front;
menu=SCPopUpMenu(panel, Rect(100,50,200,100));
menu.items=[\elemento1, \elemento2, "una jirafa", \yo, 47.asSymbol,
elementoX.asString, "25", elementoY]
)
En el ejemplo 1.5 añadimos el método .action y lo
igualamos a una función usando llaves {}. Creamos un argumento
con el nombre que queramos. Usaremos aqui el nombre "indice". Este
argumento tomara el valor del índice del elemento del
menú que esté seleccionado. Podemos imprimir este valor
con el método .value.postln. Después, utilizando el
objeto switch podemos evaluar el argumento indice.value y asignar
acciones para cada elemento del menú. Aqui hacemos que la
ventana cambie de color.
Ejemplo 1.5
(
d=SCWindow(\halo, Rect(100,100,400,400)).front;
e=SCPopUpMenu(d, Rect(20,20,100,100));
e.items=[\red,\green,\blue];
d.view.background=Color(1,0,0);
e.action={|indice|
indice.value.postln;
switch(indice.value, 0, {d.view.background=Color(1,0,0)},
1,{d.view.background=Color(0,1,0)},
2,{d.view.background=Color(0,0,1)}
)
};
)
El ejemplo 2 es el mismo principio de evaluar el argumento del menu y
mediante un switch asignar acciones. Ahora ponemos dos acciones para
cada elemento del menú que son cambiar el color del menú
y disparar un Synth.
Ejemplo 2
(
var panel, menu, elementoX=23, elementoY="hola", notas, t;
(
SynthDef(\oriundo, {|a=100,b=500,c=1500,d=1150, t1=0.1,t2=0.4,t3=1.5,
amp=1, wrap=1|
var envFreq, sig, dur, env;
envFreq=EnvGen.kr(Env([a,b,c,d], [t1,t2,t3]));
sig=Pulse.ar(envFreq, 0.5).wrap2(wrap);
dur=t1+t2+t3;
env=EnvGen.kr(Env([0,1,1,0],[0,dur,0]),doneAction:2);
Out.ar(0, sig*env*amp);
}).send(s);
);
//Synth(\oriundo)
panel=SCWindow("menu", Rect(200,200,400,200)).front;
menu=SCPopUpMenu(panel, Rect(100,50,200,100));
menu.items=[\elemento1, \elemento2, "una jirafa", \yo, 47.asSymbol,
elementoX.asString, "25", elementoY];
menu.action={|indice|
indice.value.postln;
i=indice.value+1;
notas=[0,2,4,5,6,7,8,11].midiratio*67.midicps;
t=[0.1,0.2];
switch(indice.value, 0,{
Synth(\oriundo, [\a, notas.choose, \b, notas.choose, \c, notas.choose,
\d, notas.choose,
\t1, t.choose, \t2, t.choose, \t3, t.choose, \wrap, 1/16]);
menu.background=Color(1,0,0)
},
1,{
Synth(\oriundo, [\a, notas.choose, \b, notas.choose, \c, notas.choose,
\d, notas.choose,
\t1, t.choose, \t2, t.choose, \t3, t.choose, \wrap, 1/16]);
menu.background=Color(0,1,0)
},
2,{
Synth(\oriundo, [\a, notas.choose, \b, notas.choose, \c, notas.choose,
\d, notas.choose,
\t1, t.choose, \t2, t.choose, \t3, t.choose, \wrap, 1/16]);
menu.background=Color(0,0,1)
},
3,{
Synth(\oriundo, [\a, notas.choose, \b, notas.choose, \c, notas.choose,
\d, notas.choose,
\t1, t.choose, \t2, t.choose, \t3, t.choose, \wrap, 1/16]);
menu.background=Color(1,1,0)
},
4,{
Synth(\oriundo, [\a, notas.choose, \b, notas.choose, \c, notas.choose,
\d, notas.choose,
\t1, t.choose, \t2, t.choose, \t3, t.choose, \wrap, 1/16]);
menu.background=Color(1,0,1)
},
5,{
Synth(\oriundo, [\a, notas.choose, \b, notas.choose, \c, notas.choose,
\d, notas.choose,
\t1, t.choose, \t2, t.choose, \t3, t.choose, \wrap, 1/16]);
menu.background=Color(0,1,1)
},
6,{
Synth(\oriundo, [\a, notas.choose, \b, notas.choose, \c, notas.choose,
\d, notas.choose,
\t1, t.choose, \t2, t.choose, \t3, t.choose, \wrap, 1/16]);
menu.background=Color(1,1,1)
},
7,{
Synth(\oriundo, [\a, notas.choose, \b, notas.choose, \c, notas.choose,
\d, notas.choose,
\t1, t.choose, \t2, t.choose, \t3, t.choose, \wrap, 1/16]);
menu.background=Color(0,0,0)
}
);
}
)
Los métodos relacionados con el valor del menú tienen
funciones similares pero con diferencias importantes:
.value
regresa el índice seleccionado actualmente
.value_(indice)
programáticamente selecciona un elemento del
menú.
.valueAction_(indice)
programáticamente selecciona un elemento del
menú y ejecuta la acción.
.view.keyDownAction
Es una función que puede reconocer las teclas de la computadora
al ser presionadas dando información sobre diferentes
códigos relacionados a ella y permite ejecutar una
acción. Por default keyDownAction contiene 5 argumentos:
view = La instancia de SCView que recibe.
char=El caracter presionado. Posiblemente no se pueda imprimir. Los
caracteres compuestos como "é" pasan como
dos caracteres: primero
el acento "´" como espacio en blanco " " y luego la "e".
modifiers = información en bits sobre combinaciones de teclas.
Implica lógica binaria.
unicode = El código ASCII del caracter. American Standard Code
for Information Interchange
keycode = El código que la computadora asigna a las teclas como
hardware. Varía entre cada computadora.
El ejemplo que ofrecen los tutoriales de SuperCollider esta en el help
de SCView.
Ejemplo 3
(
var panel;
panel=SCWindow("teclea y ve", Rect(400,200,300,500)).front;
panel.view.keyDownAction={|view, char, modifiers, unicode, keycode|
[view, char, modifiers, unicode, keycode].postln;
};
)
El ejemplo 3 muestra la manera de asignar el método
.keyDownAction a un SCWindow.view y la manera de escribir los
argumentos. En el ejemplo 4 cambiamos los nombres de los argumentos.
Notese que keyDownAction reconoce sus argumentos por la
posición, no por el nombre. Asi a = view, b = char, c =
modifiers, d = unicode y no hay un argumento que represente a keycode
por que no lo queremos usar en esta ocasión. En este ejemplo
estamos pidiendo a la función que imprima los agumentos b y d
que corresponden al caracter y a su código ASCII. Además
disparamos un Saw que tiene como frecuencia el valor del código
ASCII correspondiente a la tecla que estemos apretando. El Saw
está multiplicado por un Line que hace las veces de envolvente y
como Line tiene el argumento doneAction nos sirve para apagar el synth.
Ejemplo 4
(
var ventana;
ventana=SCWindow("hola",Rect(300,300,350,500)).front;
ventana.view.keyDownAction={|a,b,c,d|
[b,d].postln;
{Saw.ar(d)*Line.kr(0,1,1,doneAction:2)}.play}
)
En el Ejemplo 5 aplicamos la estructura del switch para asignar
acciones a las diferentes teclas. Comúnmente usaremos solo el
argumento unicode con el código ASCII en el proceso de
selección. Observen como el argumento unicode tiene la capacidad
de diferencíar entre tecleo sencillo y las combinaciones de
teclas como con el shift para las mayúsculas.
Ejemplo 5
(
var panel, comentario;
(
SynthDef(\oblicuo, {|freq=300, dur=1, mod=13, prof=50|
var sig, env;
sig=LFTri.ar(LFTri.kr(mod, 0, freq, prof));
env=EnvGen.kr(Env.perc(0.01,dur),doneAction:2);
Out.ar(0,sig*env);
}).send(s);
);
//Synth(\oblicuo)
panel=SCWindow("teclea y ve", Rect(400,200,500,200)).front;
panel.view.keyDownAction={|view, char, modifiers, unicode, keycode|
[view, char, modifiers, unicode, keycode].postln;
switch(unicode.value, 97,{Synth(\oblicuo)}, // a minúscula
65,{Synth(\oblicuo, [\mod, 20, \freq, 300, \prof, 150])}, // A
mayúscula con shift
98,{Synth(\oblicuo, [\mod, 5, \freq, 1300, \prof, 500])}, // b
minúscula
66,{Synth(\oblicuo, [\mod, 9, \freq, 234, \prof, 150])} //
B mayúscula con shift
)
};
comentario=SCStaticText(panel, Rect(10,0,490,200));
comentario.font=Font("Arial", 150);
comentario.string="a A b B";
)