GUI¶
Intro ¶
Due modalità
- Monitor visivi - recuperare informazioni.
- Interfacce grafiche - interazione attraverso il mouse.
Meglio programmarle come processi indipendenti sia rispetto allo scheduling che all'audio in modo da poterle cancellare in qualsiasi momento.
Window ¶
Contenitore all'interno del quale posizionare tutti gli oggetti grafici che vogliamo visualizzare.
(
w = Window.new("CiaoCiao", // Nome che compare sulla barra in alto
Rect(0,0,300,110) // Posizione e size in pixels (sinistra, alto, larghezza, altezza)
);
w.front; // la fa comparire
w.alwaysOnTop_(true); // la fa sempre stare davanti alle altre finestre sullo schermo
w.onClose_( {w.free} ); // questo metodo esegue la funzione che è suo argomento quando chiudiamo la finestra dal pallino rosso
)
w.name_("urca"); // Cambiare il titolo
w.background_(Color.red); // Vedere l'help file di Color
w.alpha_(rand(1.0)); // Indice di trasparenza tra 0.0 e 1.0
Oggetti grafici ¶
Oggetti da posizionare nella window.
Assegnati a variabili per poter comunicare con loro in entrambe le direzioni.
Primi due argomenti comuni a tutti:
- istanza di Window dove posizionarli.
- istanza di Rect() che ne specifica la posizione.
(
w = Window.new("CiaoCiao", Rect(0,0,300,110));
w.front;
w.alwaysOnTop_(true);
w.onClose_({w.free;h.free;n.free;k.free;b.free;p.free;d.free;t.free;z.free});
h = Slider.new(w, Rect(5,5,50,100)); // Crea uno slider x = 0 = sinistra / y = 0 = alto (in pixels)
n = NumberBox.new(w, Rect(65,5, 50,20)); // Crea un number box
k = Knob.new(w, Rect(65,30, 75,75)); // Crea un knob
b = Button.new(w, Rect(120,5, 50,20)); // Crea un number box
p = PopUpMenu.new(w, Rect(175,5, 100,20)); // Crea un pop up menu
d = Slider2D.new(w, Rect(145,30, 75,75)); // Crea un interfaccia XY
t = StaticText.new(w, Rect(225,30, 75,75)); // Crea un testo
z = MultiSliderView.new(w,Rect(5,110, 290,75)); // Crea un multislider
)
Ogni oggetto può:
- inviare valori all'Interprete.
- ricevere valori dall'Interprete.
Questi valori possono poi essere inviati al Server attraverso i consueti metodi.

Recuperare valori ¶
Agendo col mouse sulla GUI $\rightarrow$ modifica dei valori.
Dobbiamo recuperarli nell'interprete $\rightarrow$ metodo .action()
(
w = Window.new("Slider", Rect.new(0,0,100,210));
h = Slider.new(w, Rect(25,5,50,200));
w.front;
w.alwaysOnTop_(true);
w.onClose_({w.free;h.free});
h.action_({h.value.postln}); // Recupera valore
)
Inviare il valore dall'interprete a un Synth (Server).
s.boot;
s.scope(1);
s.plotTree;
(
SynthDef(\slider, {arg amp=0;
var sig;
sig = SinOsc.ar * amp.lag; // Smoothing
Out.ar(0,sig)
}).add;
w = Window.new("Slider", Rect.new(0,0,60,210));
h = Slider.new(w, Rect(5,5,50,200));
w.front;
w.alwaysOnTop_(true);
w.onClose_({w.free;h.free;u.free});
h.action_({var val; // Assegna il valore a una variabile
val = h.value; // per poterlo riutilizzare nel codice
val.postln;
u.set(\amp, val) // Invia il valore al Server
});
)
u = Synth(\slider) // Crea il Synth
Inviare valori ¶
Per visualizzare nella GUI un valore inviato dall'interprete $\rightarrow$ metodo .value()
(
w = Window.new("Slider", Rect.new(0,0,100,210));
h = Slider.new(w, Rect(25,5,50,200));
w.front;
w.alwaysOnTop_(true);
w.onClose_({w.free;h.free});
)
h.value_(rand(1.0)); // Singolo valore
Se vogliamo inviare valori in modo dinamico ad esempio attraverso una Routine
- .play(AppClock).
- { }.defer
(
r = Routine.new({
inf.do({
h.value_(rand(1.0));
0.1.wait
})
}).reset.play(AppClock);
)
(
r = Routine.new({
inf.do({
{h.value_(rand(1.0))}.defer;
0.1.wait
})
}).reset.play;
)
r.stop;
Il metodo .value() invia solamente alla GUI
Se vogliamo impiegare una modalità di controllo mista (sia interazione che sequencing) $\rightarrow$ metodo .valueAction()
h.action_({h.value.postln}); // Recupera il valore
h.valueAction_(rand(1.0)); // Invia il valore
( // Sequencing
r = Routine.new({
inf.do({
{h.valueAction_(rand(1.0))}.defer;
0.1.wait
})
}).reset.play;
)
r.stop;
// Provare ad interagire con il mouse sullo Slider...
FlowLayout ¶
Utilità per posizionare GUI nella Windows.
// Oggetti diversi
(
w = Window.new("Multi", Rect.new(0,0,220,250));
w.addFlowLayout( 5@20, // Margini dalla Window x@y
5@5 ); // Spazio tra gli oggetti x@y
h = Slider.new(w, 50@100); // Specificare solo le dimensioni
n = Slider.new(w, 50@100);
d = Slider2D.new(w, 100@100);
p = PopUpMenu.new(w, 210@20);
z = MultiSliderView.new(w, 210@75);
w.front;
w.alwaysOnTop_(true);
w.onClose_({w.free;h.free;n.free;d.free;p.free;z.free});
)
// Copie multiple dello stesso oggetto
(
w = Window.new("Multi", Rect.new(0,0,220,220));
w.addFlowLayout( 20@20, // Margini dalla Window x@y
5@5 ); // Distanze tra gli oggetti x@y
16.do{Slider2D(w.view,40@40).background_(Color.rand)};
w.front;
w.alwaysOnTop_(true);
w.onClose_({w.free});
)
Ulteriori approfondimenti in questa Introduzione oppure consultando gli Help files dei singoli oggetti.
Interfacce per controllo ¶
Interfacce per segnali ¶
- SoundFileView
- EnvelopeView
- ScopeView
- FreqScopeView
- Esempio composto
s.boot;
s.meter;
s.plotTree;
s.freeAllBuffers;
(
f = Buffer.alloc(s,1024,1,bufnum:1); // Specifica il Buffer 1
w = Window.new("Oscilloscopio", Rect(0,0,410,415));
c = ScopeView.new(w, Rect(5,5,400,200));
g = FreqScopeView.new(w, Rect(5,210,400,200));
c.bufnum = f.bufnum;
c.server_(s);
c.start;
g.freqMode_(1);
g.dbRange_(90);
g.active_(true);
g.inBus_(0);
w.front;
w.alwaysOnTop_(true);
w.onClose_({f.free;w.free;c.free;d.free;e.free;g.kill});
SynthDef(\scoping, {arg bus=0, buffy=0;
ScopeOut2.ar(In.ar(bus,1), buffy) // Scrive nel Buffer
}).add;
SynthDef(\suono, {arg bus=0;
Out.ar(bus, Blip.ar(200,MouseX.kr(1,50)))
}).add;
)
(
d = Synth(\scoping, [\buffy, f.bufnum]);
e = Synth(\suono)
)