3. * Piccola parentesi prima di parlare dei pixbuf :
Magari non avete ancora provato a
documentarmi sulle gtk su altre fonti ma se
l’avete fatto sicuramente avrete notato che
alcune funzioni iniziano per gtk_ e altre per
gdk_
Questo è perché esistono 2 livelli di astrazione,
le gdk son la parte che gestisce i dati, le gtk
quella che li mostra a video.
Se volete salvarvi 10 o 20 immagini in memoria
usate le gdk, se le volete mostrare, magari una
alla volta usate le gtk
4. * I Pixbuf altro non sono che contenitori di
immagini, hanno molte funzioni per la
manipolazione di immagini, reggono quasi tutti
i tipi di immagini (png,jpg,bmp,gif,etc..)
* Facendo parte della libreria gdk (e non gtk) per
dichiararli hanno un loro tipo e non si usa
GtkWidget.
GdkPixbuf *esempio;
5. * Il Pixbuf può essere creato essenzialmente in 2
modi :
1. Creando un pixbuf vuoto :
Immagine = gdk_pixbuf_new(GDK_COLORSPACE_RGB,TRUE,8,
Larghezza,Altezza);
I primi 3 parametri son standard, gli ultimi 2 son le
dimensioni del pixbuf
2. Caricando un’immagine :
Immagine =
gdk_pixbuf_new_from_file("Nome_file.png",&error);
Per semplicità e possibile mettere NULL al posto di
error, se si usa error, se l’immagine non viene
caricata troveremmo in error->code e in error-
>message informazioni sull’errore (GdkError *error)
6. * Tra le funzioni più utili che possiamo trovare con
i pixbuf c’è
gdk_pixbuf_copy_area(PixbufProvenienza,left,top,larghez
za,altezza,PixbufDestinazione,top,left);
Questa funzione copia un pezzo di immagine dalla prima
immagine (parametro 1), il pezzo copiato inizia alle
coordinate left,top (2° e 3°) ed è grande
larghezza,altezza (4° e 5°).
Questo pezzo lo andiamo a incollare nella seconda
immagine (parametro 6) alle coordinate top,left (7° e
8°)
L’utilità di questa funzione è quella di permetterci di
creare set di immagini, in questo modo possiamo
caricare una solo immagine e poi spezzettarla in più
PixBuf (o in una matrice o vettore di pixbuf)
7. * Continuare a parlare dei pixbuf poteva diventare
fuorviante cosi ho esposte solo le funzioni più utili per il
momento.
* Per approfondire :
* http://developer.gnome.org/gdk-pixbuf/stable/
9. * Per poter mostrare le immagini a schermo possiamo
avvalerci delle GtkImage.
Fanno parte della libreria principale quindi son sempre dei
widget (come ogni componente visuale che vedremmo in
queste slide).
Per crearle abbiamo :
* image = gtk_image_new();
Crea una nuova immagine vuota;
* image = gtk_image_new_from_file("nomefile.png");
Crea una nuova immagine caricandola da un file;
* image = gtk_image_new_from_pixbuf(nomepixbuf);
Crea una nuova immagine caricandola da pixbuf
10. * Possiamo cambiare il contenuto di un’immagine in
qualunque momento avvalendoci delle funzioni :
* gtk_image_set_from_file(image,"nomefile.png");
Carica il contenuto del file nell’immagine
* gtk_image_set_from_pixbuf(image,nomepixbuf);
Carica il contenuto del pixbuf nell’immagine
12. * In questo esempio vogliamo creare il famoso gioco forza 4.
Verifichiamo cosa ci serve :
1. Saper creare un programma con le gtk
2. Saper gestire il click del mouse (dobbiamo sapere dove
clicka l’utente)
3. Saper caricare le immagini del gettone rosso e giallo
4. Saper creare nuove immagini e farle cadere
13. * Bene la prima parte sappiamo farla, l’abbiamo vista nella
prima lezione.
* Quindi scriviamo questo codice :
#include <gtk/gtk.h>
int main(int argc,char *argv[]) {
GtkWidget *win;
//Inizializzo le GTK
gtk_init (&argc, &argv);
//Creo la finestra
win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
//Imposto che quando la finestra viene chiusa deve
chiudersi il programma
g_signal_connect(GTK_OBJECT(win), "destroy", G_CALLBACK
( gtk_main_quit ), NULL);
//Imposto le dimensioni della finestra
gtk_widget_set_size_request (win,640,480);
//Mostro la finestra e tutto il suo contenuto
gtk_widget_show_all(win);
//Avvio il loop principale delle GTK
}
gtk_main ();
return 0; *
14. * Per la seconda dobbiamo riuscire a recepire il click del
mouse..
static gboolean mouse_click(GtkWidget
*widget,GdkEventButton *event,gpointer user_data) {
return TRUE;
}
int main(int argc,char *argv[]) {
…
win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
//Predispongo la finestra per ricevere i click del
mouse
gtk_widget_set_events(GTK_WIDGET(win),
gtk_widget_get_events(win) | GDK_BUTTON_PRESS_MASK);
//Chiedo di essere avvertito quando viene premuto un
tasto del mouse
g_signal_connect(GTK_OBJECT(win), "button-press-event",
G_CALLBACK ( mouse_click ), NULL);
*
15. * Ora dobbiamo caricare i 2 gettoni e l’immagine di
sfondo
GdkPixbuf *rosso,*giallo,*griglia;
int main(int argc,char *argv[]) {
rosso =
gdk_pixbuf_new_from_file("rosso.png",NULL);
giallo =
gdk_pixbuf_new_from_file("giallo.png",NULL);
griglia =
gdk_pixbuf_new_from_file("griglia.png",NULL);
*
16. * Se vogliamo vedere le immagini cadere dobbiamo
poterle creare dove vogliamo, per questo motivo
metto un fixed nella finestra
GtkFixed *contenitore;
int main(int argc,char *argv[]) {
…
//Creo il fixed
contenitore = gtk_fixed_new();
//Lo metto nella finestra
gtk_container_add(GTK_CONTAINER(win),contenitore)
;
*
17. * Ora che abbiamo il fixed possiamo passare a creare
le immagini, però dobbiamo sapere dove devono
finire quindi ci serve una matrice che contenga il
campo, e un intero che indichi di chi è il turno
int campo[15][20] ,turno=0; //640x480 con imms da
32x32
int main(int argc,char *argv[]) {
int i=0,j;
…
//inizializzo la matrice
for (;i<15;i++)
for (j=0;j<20;j++)
campo[i][j] = 0;
*
18. * Tutto è fatto nella funzione che riceve il click del mouse possiamo creare le immagini e
metterle al loro posto
static gboolean mouse_click(GtkWidget *widget,GdkEventButton *event,gpointer user_data) {
//Divido le coordinate per 32 in modo da averle secondo la base della matrice
int i,x = trunc(event->x/32);
//Creo un'immagine (alternando il colore in base al turno)
GdkImage *imm = gtk_image_new_from_pixbuf((turno)?rosso:giallo);
//Controllo che la colonna non sia piena
if (!campo[0][x]) {
//Scorro la colonna dal basso all'alto
for (i=14;i>=0;i--)
if (!campo[i][x]) break; //Esco quando trovo un punto libero
//Incremento il turno
turno = (turno+1)%2;
//Setto che la cella ora è piena
campo[i][x] = turno+1;
//Metto il gettone li
gtk_fixed_put(GTK_FIXED(contenitore),imm,x*32,i*32);
//Mostro l'immagine altrimenti non si vedrà
gtk_widget_show(imm);
}
*
return TRUE;
}