📄 gtk_tut_it-12.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><HTML><HEAD> <META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.9"> <TITLE>GTK Tutorial: Widget non documentati</TITLE> <LINK HREF="gtk_tut_it-13.html" REL=next> <LINK HREF="gtk_tut_it-11.html" REL=previous> <LINK HREF="gtk_tut_it.html#toc12" REL=contents></HEAD><BODY BGCOLOR="#FFFFFF"><A HREF="gtk_tut_it-13.html">Avanti</A><A HREF="gtk_tut_it-11.html">Indietro</A><A HREF="gtk_tut_it.html#toc12">Indice</A><HR NOSHADE><H2><A NAME="s12">12. Widget non documentati</A></H2><P>Per questi sarebbe utile il contributo degli autori! :) Prendete inconsiderazione la possibilità di contribuire al nostro tutorial.<P>Se dovete usare uno di questi widget non documentati, vi suggeriamocaldamente di dare un'occhiata ai loro rispettivi file header nella distribuzione di GTK. I nomi delle funzioni di GTK sono molto descrittivi.Non appena si capisce come funzionano le cose, non è difficile dedurre il modo d'uso di un widget semplicemente guardando ladichiarazione di funzione associata ad esso. Aggiungendo a questo qualchespunto tratto dal codice di altri non dovrebbero esserci problemi.<P>Quando avrete raggiunto una comprensione globale di tutte le funzionidi un widget non documentato, considerate la possibilità di scrivereun tutorial su di esso, in modo che altri possano beneficiare delvostro lavoro.<P><H2><A NAME="ss12.1">12.1 Controlli di intervallo (Range Controls)</A></H2><H2><A NAME="ss12.2">12.2 Anteprime</A></H2><P>Le anteprime servono a un certo numero di cose in GIMP/GTK. La piùimportante è questa: a risoluzioni molto alte le immagini possonofacilmente occupare diverse decine di megabyte di memoria; ogni operazionesu immagini così grosse può richiedere molto tempo. Se per lascelta di una data modifica vi occorrono 5-10 tentativi (cioè 10-20passi, poiché è necessario ripristinare l'originale se si è commesso un errore), possono volerci letteralmente delle ore perfare quella giusta - se non si rimane a corto di memoria prima! Coloro chehanno passato ore in camera oscura conoscono la sensazione. In questi casile anteprime sono utilissime!<P>Ma la seccatura dell'attesa non è l'unico caso. Spesso è utileconfrontare la versione precedente con la successiva affiancandole, o almenoalternandole. Se si sta lavorando con grandi immagini e ritardi di una decinadi secondi un confronto efficace è quantomeno difficile da fare.Per immagini di 30 mega (4 pollici per 6 pollici, 600 punti per pollice, 24 bit)tale confronto risulta impraticabile per la maggior parte degli utenti. Inquesto caso le anteprime sono di grande aiuto! <P>Ma c'è di più. Con le anteprime è possibile scrivereplug-in per ottenere addirittura anteprime di anteprime (per esempio, lasimulazione del pacchetto di filtri). Questi plug-in possono cosìfornire un certo numero di anticipazioni di quel che si otterrebbe applicandocerte opzioni. Un simile approccio funziona come una tavolozza di anteprime,ed è molto efficace per piccoli cambiamenti! <P>Non è finita. Per alcuni plug-in può essere necessario unintervento umano in tempo reale specifico per ogni immagine. Nel plug-in SuperNova, ad esempio, vengono chieste le coordinate del centro dellafutura supernova. Il modo più semplice per fare questo èsenza dubbio quello di mostrare un'anteprima all'utente chiedendogli diselezionare interattivamente il centro.<P>Infine, un paio di applicazioni tipiche. Le anteprime possono essere usateanche quando non si sta lavorando con grandi immagini. Per esempio, sono utili quando si stanno calcolando dei pattern complicati (date un'occhiataal venerabile plug in ``Diffraction'' e a molti altri!). Altro esempio:date un'occhiata al plug-in di rotazione della mappa dei colori (in allestimento).Le anteprime possono anche essere usate per visualizzare in un plug-inpiccoli logo o, addirittura, l'immagine dell'Autore!<P>Quando non usare le anteprime<P>Le anteprime non vanno usate per grafici, disegni ecc., poiché per queste cose GDK è molto più veloce. Le anteprime vanno usatesolo per immagini derivate da un'elaborazione!<P>Le anteprime possono essere inserite dappertutto. In un vbox, in un hbox,in una tabella, in un bottone, ecc. Sicuramente però hanno il lorolook migliore se bordate con delle cornici (frame). Le anteprime non hannobordi propri e appaiono piatte senza (naturalmente, se quel che si vuoleè proprio un aspetto piatto...). I bordi possono essere creati condelle cornici.<P>[Image][Image]<P>Le anteprime sono per molti aspetti simili agli altri widget in GTK (contutto ciò che questo implica), con l'eccezione di avere unacaratteristica in più: è necessario che siano riempite conqualche tipo di immagine! Inizialmente parleremo solo dell'aspetto GTK delle anteprime e successivamente discuteremo di come riempirle.<P>Semplicemente:<P><BLOCKQUOTE><CODE><PRE> /* Crea un widget di anteprima, inizializzane le dimensioni e visualizzalo */GtkWidget *preview;preview=gtk_preview_new(GTK_PREVIEW_COLOR) /* Alternativamente: GTK_PREVIEW_GRAYSCALE);*/gtk_preview_size (GTK_PREVIEW (preview), WIDTH, HEIGHT);gtk_widget_show(preview);my_preview_rendering_function(preview);</PRE></CODE></BLOCKQUOTE><P>Come già detto, le anteprime hanno un buon aspetto dentro le cornici,quindi:<P><BLOCKQUOTE><CODE><PRE>GtkWidget *create_a_preview(int Width, int Height, int Colorfulness){ GtkWidget *preview; GtkWidget *frame; frame = gtk_frame_new(NULL); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); gtk_container_border_width (GTK_CONTAINER(frame),0); gtk_widget_show(frame); preview=gtk_preview_new (Colorfulness?GTK_PREVIEW_COLOR :GTK_PREVIEW_GRAYSCALE); gtk_preview_size (GTK_PREVIEW (preview), Width, Height); gtk_container_add(GTK_CONTAINER(frame),preview); gtk_widget_show(preview); my_preview_rendering_function(preview); return frame;}</PRE></CODE></BLOCKQUOTE><P>Questa è una semplice anteprima. Questa funzione restituisce la cornice``madre'', in modo che sia possibile metterla in qualche altro posto nella vostrainterfaccia. Naturalmente è possibile passare alla routine la cornicemadre come parametro. In molte situazioni, comunque, il contenuto di un'anteprimaviene aggiornato continuamente dall'applicazione; in questi casi potreste preferire passare alla funzione ``create_a_preview()'' un puntatore all'anteprima, ottenendone così il controllo dopo.<P>Un'avvertimento più importante che potrebbe un giorno risparmiarvi tanto tempo perso: a volte è preferibile etichettare le anteprime;ad esempio, è possibile etichettare l'anteprima contenente l'immagine originale come ``Originale'' e quella contenente l'immagine modificata come ``Modificata''. Potrebbe capitarvi di impacchettare in un vbox l'anteprimainsieme con l'etichetta associata. L'insidia inattesa sta nel fatto che sel'etichetta è più ampia dell'anteprima (cosa che puòaccadere per una varietà di motivi da voi non prevedibili, come ilfatto che la dimensione dell'anteprima viene decisa dinamicamente, o ladimensione del font), la cornice si espande e non risulta piùperfettamente aderente all'anteprima. Questo stesso problema probabilmentepuò verificarsi anche in altre situazioni.<P>[Image]<P>La soluzione è quella di mettere l'anteprima e l'etichetta in unatabella 2x1 e di legarle insieme chiamando la funzione gtk_table_attach coni seguenti parametri (questa è una delle varianti possibili,naturalmente; l'importante è che non ci sia GTK_FILL nella secondagtk_table_attach):<P><BLOCKQUOTE><CODE><PRE>gtk_table_attach(GTK_TABLE(table),label,0,1,0,1, 0, GTK_EXPAND|GTK_FILL, 0,0);gtk_table_attach(GTK_TABLE(table),frame,0,1,1,2, GTK_EXPAND, GTK_EXPAND, 0,0);</PRE></CODE></BLOCKQUOTE><P>Ed ecco il risultato:<P>[Image]<P>Altri suggerimenti<P>La maniera più semplice per rendere cliccabile un'anteprima è quella di metterla dentro un bottone. Questo ha anche l'effetto di aggiungere un bel bordo attorno all'anteprima, il che rende superfluo metterla in una cornice.<P>Questo è tutto per quel che riguarda GTK.<P><P>Completare un'anteprima<P>Per impratichirci con le basi del completamento delle anteprime, creiamoil seguente disegno (trovato per tentativi):<P>[Image]<P><BLOCKQUOTE><CODE><PRE>voidmy_preview_rendering_function(GtkWidget *preview){#define SIZE 100#define HALF (SIZE/2) guchar *row=(guchar *) malloc(3*SIZE); /* 3 bits per dot */ gint i, j; /* Coordinates */ double r, alpha, x, y; if (preview==NULL) return; /* Di solito aggiungo questo per */ /* evitare piantamenti stupidi. */ /* Probabilmente bisognerebbe */ /* assicurarsi che tutto sia stato*/ /* inizializzato con successo */ for (j=0; j < ABS(cos(2*alpha)) ) { /* Siamo dentro la sagoma? */ /* glib.h contiene ABS(x). */ row[i*3+0] = sqrt(1-r)*255; /* Definisce il Rosso */ row[i*3+1] = 128; /* Definisce il Verde */ row[i*3+2] = 224; /* Definisce il Blu */ } /* "+0" è per allineamento */ else { row[i*3+0] = r*255; row[i*3+1] = ABS(sin((float)i/SIZE*2*PI))*255; row[i*3+2] = ABS(sin((float)j/SIZE*2*PI))*255; } } gtk_preview_draw_row( GTK_PREVIEW(preview),row,0,j,SIZE); /* Inserisce "row" in "preview" a partire del punto avente */ /* coordinate (0,j) prima colonna, j-esima riga, per SIZE */ /* pixel verso destra */ } free(row); /* libera un po' di memoria */ gtk_widget_draw(preview,NULL); /* indovina cosa fa questo? */ gdk_flush(); /* e questo? */}</PRE></CODE></BLOCKQUOTE>Coloro che non usano GIMP probabilmente hanno già visto abbastanzaper fare molte cose. Per gli utenti GIMP c'è ancora qualcosa daaggiungere.<P>Anteprima dell'immagine<P>Probabilmente è opportuno tenere pronta una versione ridotta dell'immagine,grande quanto basta per riempire l'anteprima. Questo può essere fattoselezionando un pixel ogni n, dove n è il rapporto tra la dimensionedell'immagine e la dimensione dell'anteprima. Tutte le operazioni successive(compreso il riempimento dell'anteprima) sono fatte solo sul ridotto numerodi pixel selezionati. Di seguito è riportata un'implementazione dellariduzione dell'immagine (si tenga presente che ho preso solo lezioni basilari di C!).<P><P>(ATTENZIONE: CODICE NON VERIFICATO!!!)<P><BLOCKQUOTE><CODE><PRE>typedef struct { gint width; gint height; gint bbp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -