12 gennaio 2007

Colori, colori, colori - un approfondimento

A voi, maniaci dei temi che siete lì fuori. Voi che non riuscite a tenere lo stesso aspetto grafico per più di una settimana (e a volte anche meno). Ascoltate.

Partiamo dall'alto, dallo strumento di preferenze Tema del centro di controllo di GNOME. Nella versione in corso di sviluppo, questo strumento è in grado di riconoscere sei colori simbolici:
  • fg_color
  • bg_color
  • text_color
  • base_color
  • selected_fg_color
  • selected_bg_color
Le prime due coppie corrispondono a ciò che di solito viene impostato come colori base del tema (sfondo e primo piano di widget semplici e sfondo e primo piano di widget "di testo" come le GtkEntry). La terza coppia indica i colori nello stato selezionato (per esempio quando evidenziate una voce di menù).

Cosa vuol dire riconoscere? Banalmente significa che se nella definizione del tema (file gtkrc) sono stati usati i nomi simbolici precedentemene elencati, se è in esecuzione il demone delle impostazioni di GNOME (gnome-settings-daemon) e se sono stati scelti dei colori personalizzati, allora all'atto della rappresentazione a schermo, il colore definito nel file gtkrc viene scartato in favore del colore scelto nei dettagli dello strumento di preferenze.

Dunque, per poter ricolorare un tema è necessario che il tema sia stato scritto sfruttando questi sei colori simbolici. Non c'è alcuna necessità per motore del tema di supportare alcuna particolare funzionalità. Tutto il lavoro è svolto dalle GTK+ e dalla definizione del tema, tramite semplice associazioni widget->stile->colore.

Nota: sì, il sistema di gestione dei temi delle GTK+ è abbastanza complicato e si divide tra motori dei temi (theme engine - contengono il codice per il tracciamento delle forme) e file di definizione (gtkrc - contengono una serie coppie proprietà=valore per i widget dell'interfaccia, widget per widget o gruppo per gruppo). Cercherò di non entrare troppo in dettaglio.

A questo punto dovrebbe però essere sorto un dubbio: come è possibile scrivere una definizione di tema esteticamente gradevole usando solo 6 colori? Sfruttando una proprietà delle GTK+ 2.10 che permettono di creare un nuovo colore variando un colore esistente, tramite le espressioni mix(fattore, colore1, colore2) e shade(fattore, colore). Sono anche disponibili darker(colore) e lighter(colore) che altro non sono che shade con fattore preimpostato.

Per ogni ulteriore informazione o approfondimento, consultate la spiegazione sui file di risorsa delle GTK+.

Passiamo ad un esempio pratico: scriviamo un semplice file gtkrc per un tema ricolorabile.

Ogni tema presenta almeno una sezione in cui si definisce uno stile
style "default"
{
fg[NORMAL] = @fg_color
fg[PRELIGHT] = @fg_color
fg[SELECTED] = @selected_fg_color
fg[ACTIVE] = @fg_color
fg[INSENSITIVE] = darker (@bg_color)

bg[NORMAL] = @bg_colo
bg[PRELIGHT] = shade (1.02, @bg_color)
bg[SELECTED] = @selected_bg_color
bg[INSENSITIVE] = @bg_color
bg[ACTIVE] = shade (0.9, @bg_color)

base[NORMAL] = @base_color
base[PRELIGHT] = shade (0.95, @bg_color)
base[ACTIVE] = shade (0.9, @selected_bg_color)
base[SELECTED] = @selected_bg_color
base[INSENSITIVE] = @bg_color

text[NORMAL] = @text_color
text[PRELIGHT] = @text_color
text[ACTIVE] = @selected_fg_color
text[SELECTED] = @selected_fg_color
text[INSENSITIVE] = darker (@bg_color)

engine "clearlooks"
{
menubarstyle = 2
animation = TRUE
radius = 4.5
style = GLOSSY
}
}
Ho volontariamente omesso ogni definizione di proprietà dei singoli widget (cose come GtkScrollbar::min_slider_length = 20 per definire la dimensione minima del cursore delle barre di scorrimento): sebbene non siano essenziali per questa discussione, influiscono fortemente nell'aspetto grafico finale di un tema, andando a modificare le dimensioni e le spaziature dei vari componenti.

Sono solo presenti, nella definizione di questo stile, le definizioni dei colori da usare (di nuovo, consultate la pagina linkata prima per capire il significato delle varie opzioni) usando colori nominali riconosciuto dallo strumento di preferenze Tema e espressioni di modifica fornite da GTK+ (2.10 e successive) e la definizione del motore di tema da usare con le opzioni riconosciute da questo.

Uno stile deve poi essere applicato a un widget o a un gruppo di widget. Visto che stiamo facendo una prova, lo applichiamo indifferentemente a tutti i widget. Alla definizione dello stile facciamo quindi seguire:
class "GtkWidget" style "default"
Leggi: applica lo stile "default" a quei widget la cui classe è GtkWidget (ossia tutti).

Cosa manca? La definizione dei colori da usare. È vero che ho usato i colori simbolici, ma è pur vero che debbo dare una associazione iniziale tra colore simbolico e colore reale da usare se l'utente non sta usando colori propri. Per cui, prima delle due predecentei definizioni, dovrei inserire qualcosa come:
gtk_color_scheme = "fg_color:#000000\nbg_color:#E2E2E2\nbase_color:#ffffff\ntext_color
:#000000\nselected_bg_color:#3063B1\nselected_fg_color:#ffffff"
Sostituite, nel leggere, a \n il carattere "a capo" e vi sarà semplicissimo riconoscere 6 definizioni di colori.

A questo punto scrivete il tutto nel giusto ordine in un file di testo, salvatelo col nome gtkrc, mettetelo in una cartella dal nome gtk-2.0, mettete la cartella in un'altra cartella dal nome che più vi piace (GlossyDumb), comprimete il tutto come file tar.gz e cambiate l'estensione in gtp: ecco preparato un tema, pietoso in verità, che sfrutta le nuove caratteristiche di GTK+ 2.10 e GNOME 2.18. Giusto per farmi ridere dietro, lo potete scaricare qui.

Diciamo che, scegliendo gli stessi colori, il tema Glossy appare così:


Un approfondimento

A chi mi chiedeva quanto lavoro di porting del codice fosse stato effettuato, rispondo zero! Tutto il lavoro per sfruttare la possibilità di ricolorare i temi è praticamente limitato ai file gtkrc. Mi pare che al momento solo il tema Crux (tra quelli forniti con gnome-theme) non stia usando i sei colori simbolici riconosciuti.

Ad esempio, il citato location widget di Nautilus è solo un widget come gli altri e come tale può essere gestito nei file gtkrc, specificando uno stile e applicandolo a quel tipo di widget:
style "nautilus-location" {
bg[NORMAL] = mix (0.5, "red", @bg_color)
}
widget "*.nautilus-extra-view-widget" style:highest "nautilus-location"
Non ho idea di cosa possa venire fuori miscelando metà rosso puro ("red" == #FF0000) e metà colore simbolico al momento in uso per lo sfondo, però il punto è che la gestione è demandata alla definizione, non all'applicazione.

Conclusioni

Sarà interessante vedere quanti temi di terze parti faranno uso di questa caratteristica e con quele inerzia. L'uso di nomi e la presenza delle espressioni, se ben applicati, più forzare il creatore di tema a concentrarsi più sui rapporti di proporzione tra i vari elementi ([xy]tickness!!) che sul colore: visto che posso cambiarlo, il colore diventa secondario nel giudizio su un tema, le scelte su come disegnare i singoli widget no.

Allo stesso tempo c'è da considerare che, allo stato attuale, la personalizzazione dei colori è stata pensata e implementata, per l'appunto, come personalizzazione. Non è possibile definire uno schema di colori e distribuire solo lo schema. Ciò potrebbe cambiare in futuro, ma la funzionalità dipenderebbe sempre da quanti temi saranno in grado di gestire la personalizzazione dei colori.

3 commenti:

Anonimo ha detto...

scusa, ma perchè scrivi come Petrarca?

elwood ha detto...

Ecco finalmente un pò di luce anzi di colore!Ma per avere una guida più approfondita su come creare un tema gtk?ci si deve affidare al materiale che si trova su gnome-look?

canvas giclee ha detto...

Great post, thanks a lot for sharing!