mercoledì 28 novembre 2012

Programmare con Clutter (versione 1.12.2): creare un'applicazione. Tutorial parte 1


Clutter è un libreria grafica open source che serve principalmente a creare interfacce grafiche basate su OpenGL ed in grado di sfruttare l'accelerazione della GPU. Con Clutter possiamo creare interfacce animate e gestire gli eventi di input dell'utente.
La libreria è multi piattaforma (X11, Darwin e Win32), è scritta in C ed offre anche la possibilità di utilizzarla attraverso altri linguaggi di programmazione.

Questo tutorial ha lo scopo di illustrare degli esempi pratici per imparare a sviluppare programmi con Clutter aggiornato all'ultima versione, la 1.12.2.
Mi sono avvicinato a questa libreria da poco tempo per creare una piccola applicazione per bambini, ed è stato difficile trovare su internet dei tutorial aggiornati all'ultima versione.
Visto che ci sono molte classi e funzioni deprecate dalle precedenti versioni, ecco una guida che va a colmare questa lacuna!

Per questo tutorial utilizzerò il linguaggio C (visto che sembra non sia ancora pronto il binding in C++) .

Prepariamo gli strumenti necessari per iniziare

Queste istruzioni si riferiscono ad Ubuntu (sto utilizzando la 12.10), per la preparazione degli strumenti di sviluppo su altri sistemi vi consiglio di consultare la documentazione sul sito ufficiale.

Il primo passo per iniziare a programmare e' installare gli strumenti di sviluppo sulla nostra macchina. Aprite Ubuntu Software Center, cliccate sul campo di ricerca in alto a destra e digitate “anjuta”, quindi selezionate Anjuta e cliccate su “Installa”.

Anjuta e' un ambiente di sviluppo integrato, cioè un software che aiuta i programmatori nello sviluppo del codice. In particolare e' rivolto allo sviluppo di applicazioni in ambiente GNOME.

Adesso vi serve la libreria Clutter, pulite il campo di ricerca di Ubuntu Software Center e digitate “libclutter dev”. Selezionate “OpenGL based interactive canvas library (development files)”, il nome del pacchetto è “libclutter-1.0-dev”, quindi cliccate su “ulteriori informazioni”. Quindi spuntate il componente aggiuntivo “OpenGL based interactive canvas library (documentation)“ e cliccate su Installa.

Ultimo strumento fondamentale è DevHelp, che vi permetterà di consultare la guida di riferimento di Clutter, cercate “devhelp” su Ubuntu Software Center ed installatelo, ora siete pronti all'azione.

Creiamo un nuovo progetto

Faremo un semplice programma che inizialmente si limita a creare una finestra con lo sfondo di colore nero e rappresentarla sullo schermo. Successivamente aggiungeremo altri elementi.

  • Iniziamo con lanciare Anjuta e selezionare Nuovo – Progetto nel menu File o sulla barra degli strumenti.
  • Quando compare la finestra di selezione del tipo di progetto, selezionate C e quindi Generico, quindi cliccate su continua.
  • Nella schermata successiva date un nome al progetto, ad esempio clutter_tutorial, quindi se volete il vostro nome ed indirizzo email. Il numero di versione non e' importante, andiamo avanti.
  • Nel campo destinazione cliccate sul tasto apri e selezionate la posizione dove mettere il progetto. Vi consiglio di creare una nuova cartella.
  • Spuntate l'opzione “Configura pacchetti esterni”, le altre opzioni le lasciamo con i valori di default, clicchiamo su continua.
  • Nella schermata che visualizza la lista dei pacchetti spuntiamo il pacchetto clutter-1.0 e clicchiamo su Continua, quindi su Applica.

Modifichiamo il file main.c

Apriamo il file main.c e aggiungiamo dopo #include<stdio.h>
#include <stdlib.h>
#include <clutter/clutter.h>

Cancelliamo le righe all'interno della funzione main() e sostituiamole con queste:

int main (int argc, char *argv[])
{
    ClutterInitError error = clutter_init(&argc, &argv);

    ClutterColor stage_color = { 0, 0, 0, 255 };

    ClutterActor *stage = clutter_stage_new();
    clutter_actor_set_size(stage, 512, 512);
    clutter_actor_set_background_color(stage, &stage_color);
    clutter_actor_show(stage);

    clutter_main();
    return error;
}

Adesso proviamo a compilare e guardiamo il nostro programma in azione.

clutter_tutorial crea una finestra nera sullo schermo

Per il momento il programma è molto grezzo, non possiamo fare molto oltre a vedere questa finestra nera sul nostro schermo. Dopo aver chiuso la finestra possiamo vedere che il programma rimane in esecuzione e siamo costretti a fermarlo da Anjuta, selezionando la voce “Ferma programma” dal menu Esegui.
Adesso analizziamo insieme il codice:

  • clutter_init() inizializza la libreria. Prima di qualsiasi chiamata di funzione bisogna inizializzare Clutter con questa istruzione. Come vedete riceve i parametri della funzione main(), infatti può ricevere dall'invocazione da riga di comando dei parametri. Il valore di ritorno è costituito da eventuali errori durante l'inizializzazione.
  • ClutterColor è la struttura che definisce il colore e viene inizializzata con i valori di rosso, verde, blu e di opacità, con valori che vanno da zero a 255. Nel nostro caso sono 3 zeri per ottenere il nero e 255 per avere un colore pieno senza trasparenze.

Prima di andare avanti bisogna fermarci per un po di teoria riguardante Clutter.
La classe ClutterActor è la base fondamentale di tutta libreria, ogni oggetto grafico rappresentato sullo schermo è un attore che si muove su un palcoscenico (stage). Lo stesso stage è comunque un'istanza della classe ClutterActor. Per prima cosa viene creato un palcoscenico, quindi vengono creati gli attori e vengono aggiunti al palcoscenico per diventare visibili.

  • clutter_stage_new() crea il palcoscenico, stage è il puntatore al nostro palcoscenico;
  • clutter_actor_set_size() definisce la larghezza e l'altezza di un attore, in questo caso viene utilizzato per definire le dimensioni del nostro palcoscenico, infatti nei parametri viene passato stage e le dimensioni di 512 di larghezza per 512 di altezza;
  • clutter_actor_set_background_color() definisce il colore di sfondo di un attore, nel nostro caso assegniamo il colore nero che avevamo definito in stage_color, al nostro palcoscenico stage;
  • clutter_actor_show() rende visibile l'attore, noi rendiamo visibile il nostro stage;
  • clutter_main() passa il controllo al main loop, cioè attende il verificarsi degli eventi, che possono essere ad esempio delle azioni da parte dell'utente;

Ora facciamo in modo che quando chiudiamo la finestra il programma si arresti, basta aggiungere questa riga dopo clutter_actor_show(stage);

g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);

Questa funzione collega il segnale “destroy”, che viene lanciato da stage quando viene distrutto, con la chiamata alla funzione clutter_main_quit() che interrompe il main loop del programma. Ora, quando chiuderemo la finestra, stage verrà distrutto e lancerà il segnale “destroy”, quindi verrà chiamata la funzione clutter_main_quit() che terminerà il programma.
Compilate e provate a lanciare il programma e quindi a chiudere la finestra.

clutter_tutorial esce con codice d'errore 1 che corrisponde a CLUTTER_INIT_SUCCESS, cioè nessun errore.


E' arrivato il momento di aggiungere un attore sul nostro palcoscenico, aggiungiamo le seguenti righe dopo clutter_actor_set_background_color(stage, &stage_color);

ClutterColor actor_color = { 0, 255, 0, 128 };
ClutterActor *rect = clutter_actor_new();
clutter_actor_set_background_color(rect, &actor_color);
clutter_actor_set_size(rect, 100, 100);
clutter_actor_set_position(rect, 100, 100);
clutter_actor_add_child(stage, rect);

Analizziamo il codice che abbiamo aggiunto:
  • prima di tutto inizializziamo actor_color con un colore verde intenso;
  • clutter_actor_new() crea un nuovo attore, rect è il puntatore al nostro attore;
  • clutter_actor_set_background_color() è la stessa funzione che abbiamo usato per definire il colore del palcoscenico, adesso passiamo rect, che è il nostro attore e l'indirizzo del colore che abbiamo definito in actor_color;
  • anche clutter_actor_set_size() è lo stesso che abbiamo utilizzato prima, questa volta definiamo le dimensioni del nostro attore;
  • clutter_actor_set_position() definisce la posizione dell'attore sul palcoscenico, le coordinate sono rispettivamente la posizione sull'asse x seguita da quella sull'asse y. Le origini degli assi sono poste sull'angolo in alto a sinistra della finestra.
  • Ora che l'attore è pronto per andare sulla scena lo aggiungiamo al palcoscenico con la funzione clutter_actor_add_child(). Nel momento in cui l'attore viene aggiunto al palcoscenico questo diventa visibile.

Provate a compilare ed avviare il programma, ora vedrete un bel quadrato verde all'interno della nostra finestra nera.

un attore verde è sulla scena!
Il programma completo dovrebbe avere questo aspetto:


#include <stdio.h>
#include <stdlib.h>
#include <clutter/clutter.h> 
int main(int argc, char *argv[])
{
    ClutterInitError error = clutter_init(&argc, &argv);
    ClutterColor stage_color = { 0, 0, 0, 255 };
    ClutterActor *stage = clutter_stage_new();
    clutter_actor_set_size(stage, 512, 512);
    clutter_actor_set_background_color(stage, &stage_color);
    ClutterColor actor_color = { 0, 255, 0, 128 }; 
    ClutterActor *rect = clutter_actor_new();
    clutter_actor_set_background_color(rect, &actor_color);
    clutter_actor_set_size(rect, 100, 100);
    clutter_actor_set_position(rect, 100, 100);
    clutter_actor_add_child(stage, rect);
    clutter_actor_show(stage);
    g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); 
    clutter_main();
    return error;
}

Qui si conclude la prima parte del nostro tutorial, mi rendo conto che abbiamo visto poco fino a questo momento, ma ci siamo fatti un'idea della semplicità di utilizzo di Clutter.

Per ulteriori informazioni riguardanti la sintassi delle funzioni vi consiglio di consultare la guida di riferimento utilizzando DevHelp o sul sito.

Se avete dubbi, domande o suggerimenti vi invito a lasciare dei commenti, a presto!

venerdì 16 novembre 2012

Cambia il target di Maxtrix.nix


Dopo qualche mese di pausa torno a scrivere suggerimenti e guide sperando di potervi essere d'aiuto. Forse avete notato che è cambiata l'intestazione del blog ed è scomparso qualsiasi riferimento ad OS X ed al mondo Apple in generale.
Purtroppo l'ultimo MacBook in mio possesso è andato in pensione, risaliva al lontano 2007 ( informaticamente parlando è una data lontana! ) e comunque non mi sarebbe stato possibile rimanere aggiornato con l'ultima versione di OS X.
Ormai da qualche anno utilizzo come sistema operativo principale Ubuntu e quindi ho dovuto ristringere il target al solo mondo GNU/Linux.
Spero di riuscire ad attirare la curiosità anche di quanti non utilizzano abitualmente una distribuzione GNU/Linux.


Rinominare una serie di file con un unico comando dal Terminale


A chi non è mai capitato di dover rinominare una lunga serie di file, come ad esempio una collezione di foto? Farlo con l'interfaccia grafica di un qualsiasi file manager è una procedura lunga e noiosa, costringendo l'utente a dover cliccare su ogni file per rinominarlo a mano!
Con il comando rename possiamo rinominare una serie di file in un colpo solo.
La sintassi di questo comando è la seguente:

rename [espressione regolare] files

La sintassi dell'espressione regolare è quella di Perl, in sintesi ha questa forma:

s / caratteri da sostituire / nuovi caratteri /

Per quanto riguarda files, possiamo utilizzare delle wildcard per selezionare i file da modificare.
Vediamo alcuni esempi per chiarire:

rename s/.jpeg/.jpg/ *.jpeg

*.jpeg informa rename che deve prendere tutti i file che terminano con .jpeg, quindi l'espressione regolare s/.jpeg/.jpg/ sostituisce ogni occorrenza della stringa .jpeg con la stringa .jpg.
Quindi se abbiamo i file

a.jpg
b.jpeg
c.jpg
d.jpeg

rename modificherà rispettivamente

b.jpeg in b.jpg
d.jpeg in d.jpg.

La sintassi delle espressioni regolari, seppur inizialmente può apparire piuttosto complessa, è uno strumento potente e versatile. Tramite l'uso di metacaratteri possiamo ottenere delle espressioni più complesse, vediamone alcuni:

^    inizio della stringa
$    fine della stringa
*    nessuna o più ripetizioni
+    una o più ripetizioni
{}   numero esatto della ripetizione

Vediamo degli esempi pratici:

rename s/^/foto/ *.jpg

Aggiunge la stringa foto davanti al nome di tutti i file che terminano con .jpg, ad esempio
01.jpg diventerà foto01.jpg.

rename s/$/foto/ *.jpg

Aggiunge la stringa foto alla fine del nome di tutti i file che terminano con .jpg, ad esempio
01.jpg diventerà 01foto.jpg.

rename s/ae*/e/ *

Tutte le occorrenze di una 'a' che sia seguita da nessuna o più 'e', verranno sostituite con e.

rename s/ae+/e/ *

Tutte le occorrenze di una 'a' che sia seguita da una o più 'e', verranno sostituite con e.

rename s/a{3}/a/ *

Tutte le occorrenze di 'aaa' verranno sostituite con 'a'.

Per ulteriori informazioni sulla sintassi di rename potete consultare le istruzioni con il solito
man rename

Mentre per la sintassi delle espressioni regolari in Perl vi segnalo questa pagina.