« Programmation GTK/Pixmaps » : différence entre les versions

Contenu supprimé Contenu ajouté
Tavernierbot (discussion | contributions)
STyx (discussion | contributions)
m wikifié
Ligne 1 :
Les '''pixmaps''' sont des structures de données contenant des images. Celles-ci peuvent être utilisées à différents endroits, mais le plus souvent comme icônes dans le bureau X Window. Un ''bitmap'' est un ''pixmap'' de 2 couleurs.
 
Pour utiliser des pixmaps avec GTK, on doit d'abord construire une structure <code>GdkPixmap</code> en utilisant les fonctions de la couche GDK. Les pixmaps peuvent soit être créés à partir de données en memoire, ou à partir de données lues dans un fichier. Nous utiliserons chacun des appels pour créer un pixmap.
 
GdkPixmap *gdk_bitmap_create_from_data( GdkWindow *window,
gchar *data,
gint width,
gint height );
 
Cette fonction sert à créer un pixmap mono-plan (2 couleurs) à partir de données en mémoire. Chaque bit de la donnée data. width et height sont exprimés en pixels. Le pointeur vers un <code>GdkWindow</code> pointe sur la fenêtre courante car les ressources d'un pixmap n'ont de signification que dans le contexte de l'écran où il doit s'afficher.
 
GdkPixmap* gdk_pixmap_create_from_data( GdkWindow *window,
gchar *data,
gint width,
Ligne 18 :
GdkColor *bg );
 
Cette fonction est utilisée pour créer un pixmap d'une profondeur donnée (nombre de couleurs) à partir de la donnée spécifiée pas data. <code>fg</code> et <code>bg</code> sont les couleurs à utiliser pour l'avant et l'arrière-plan.
 
GdkPixmap* gdk_pixmap_create_from_xpm( GdkWindow *window,
GdkBitmap **mask,
GdkColor *transparent_color,
const gchar *filename );
 
Le format XPM est une représentation des pixmaps reconnue par le système X Window. Il est largement utilisé et de nombreux utilitaires pour créer des fichiers d'images à ce format sont disponibles. Le fichier <code>filename</code> doit contenir une image dans ce format qui sera chargée dans la structure pixmap. Le masque <code>mask</code> indique quels sont les bits opaques du pixmap. Tous les autres bits sont colorisés en utilisant la couleur spécifiée par <code>transparent_color</code>. Un exemple d'utilisation est présenté ci-dessous.
 
GdkPixmap* gdk_pixmap_create_from_xpm_d (GdkWindow *window,
GdkBitmap **mask,
GdkColor *transparent_color,
gchar **data);
 
De petites images peuvent être intégrées dans un programme sous la forme de données <code>data</code> au format XPM. Un pixmap est créé en utilisant ces données au lieu de les lire dans un fichier. Un exemple de telles données est&nbsp;:
 
/* XPM */
static const char * xpm_data[] = {
"16 16 3 1",
" c None",
". c #000000000000",
"X c #FFFFFFFFFFFF",
" ",
" ...... ",
" .XXX.X. ",
" .XXX.XX. ",
" .XXX.XXX. ",
" .XXX..... ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" ......... ",
" ",
" "};
 
void gdk_pixmap_destroy( GdkPixmap *pixmap );
 
Lorsqu'on a utilisé un pixmap et que l'on en a plus besoin tout de suite, il est préférable de libérer la ressource en utilisant un appel à <code>gdk_pixmap_destroy</code>. Les pixmaps doivent être considérées comme une ressource précieuse.
 
Quand le pixmap est créé, on peut l'afficher comme un widget GTK. On doit créer un widget pixmap qui contiendra le pixmap GDK. Ceci est réalisé de la façon suivante&nbsp;:
 
GtkWidget* gtk_pixmap_new( GdkPixmap *pixmap,
GdkBitmap *mask );
 
Les autres fonctions pour les widgets pixmap sont&nbsp;:
 
guint gtk_pixmap_get_type( void );
void gtk_pixmap_set( GtkPixmap *pixmap,
GdkPixmap *val,
GdkBitmap *mask);
void gtk_pixmap_get( GtkPixmap *pixmap,
GdkPixmap **val,
GdkBitmap **mask);
 
<code>gtk_pixmap_set</code> sert à changer le pixmap pris en charge par le widget. val est le pixmap créé par le GDK.
 
Voici un exemple illustrant l'utilisation d'un pixmap dans un bouton&nbsp;:
 
#include <gtk/gtk.h>
/* données XPM d'une icône "Ouvrir fichier" */
static const char * xpm_data[] = {
"16 16 3 1",
" c None",
". c #000000000000",
"X c #FFFFFFFFFFFF",
" ",
" ...... ",
" .XXX.X. ",
" .XXX.XX. ",
" .XXX.XXX. ",
" .XXX..... ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" ......... ",
" ",
" "};
 
/* Termine l'application lorsqu'elle est appelée
 
* via le signal "delete_event" */
/* données XPM d'une icône "Ouvrir fichier" */
static const char * xpm_data[] = {
void close_application( GtkWidget *widget, GdkEvent *event, gpointer *data )
"16 16 3 1",
{
" c None",
". c #000000000000",
"X c #FFFFFFFFFFFF",
" ",
" ...... ",
" .XXX.X. ",
" .XXX.XX. ",
" .XXX.XXX. ",
" .XXX..... ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" ......... ",
" ",
" "};
 
 
/* Termine l'application lorsqu'elle est appelée
* via le signal "delete_event" */
 
void close_application( GtkWidget *widget, GdkEvent *event, gpointer *data )
{
gtk_main_quit();
}
 
/* Invoquée lorsque le bouton est cliqué. Affiche simplement
* un message. */
 
void button_clicked( GtkWidget *widget, gpointer *data )
/* Invoquée lorsque le bouton est cliqué. Affiche simplement
{
* un message. */
 
void button_clicked( GtkWidget *widget, gpointer *data )
{
printf( "bouton cliqué\n" );
}
 
int main( int argc, char *argv[] )
 
{
int main( int argc, char *argv[] )
{
/* GtkWidget est le type pour déclarer les widgets */
 
GtkWidget *window, *pixmapwid, *button;
GdkPixmap *pixmap;
GdkBitmap *mask;
GtkStyle *style;
/* Crée la fenêtre principale et attache le signal "delete_event" pour
* terminer l'application */
 
gtk_init( &argc, &argv );
window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
Ligne 143 ⟶ 139 :
gtk_container_border_width( GTK_CONTAINER (window), 10 );
gtk_widget_show( window );
 
/* Utilisation de GDK pour créer le pixmap */
 
style = gtk_widget_get_style( window );
pixmap = gdk_pixmap_create_from_xpm_d( window->window, &mask,
&style->bg[GTK_STATE_NORMAL],
(gchar **)xpm_data );
 
/* Création d'un widget pixmap GTK pour contenir le pixmap GDK */
 
pixmapwid = gtk_pixmap_new( pixmap, mask );
gtk_widget_show( pixmapwid );
 
/* Création d'un bouton pour contenir le widget pixmap */
 
button = gtk_button_new();
gtk_container_add( GTK_CONTAINER(button), pixmapwid );
gtk_container_add( GTK_CONTAINER(window), button );
gtk_widget_show( button );
 
gtk_signal_connect( GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(button_clicked), NULL );
 
/* Affichage de la fenêtre */
gtk_main ();
return 0;
}
 
Pour charger un fichier à partir d'un fichier XPM appelé <code>icon0.xpm</code> se trouvant dans le répertoire courant, on aurait créé le pixmap ainsi&nbsp;:
 
/* Charge un pixmap à partir d'un fichier */
 
pixmap = gdk_pixmap_create_from_xpm( window->window, &mask,
&style->bg[GTK_STATE_NORMAL],
Ligne 183 ⟶ 179 :
gtk_container_add( GTK_CONTAINER(window), pixmapwid );
 
;Utilisation des formes:
 
Un désavantage de l'utilisation des pixmaps est que l'objet affiché est toujours rectangulaire, quelle que soit l'image. On voudrait pouvoir créer des bureaux et des applications avec des icônes ayant des formes plus naturelles. Par exemple, pour une interface de jeu, on aimerait avoir des boutons ronds à pousser. Pour faire cela, on doit utiliser des fenêtres avec des formes.
Ligne 189 ⟶ 185 :
Une fenêtre avec forme est simplement un pixmap dont les pixels du fond sont transparents. Ainsi, lorsque l'image d'arrière-plan est multicolore, on ne la cache pas avec le bord de notre icône. L'exemple suivant affiche une image de brouette sur le bureau.
 
#include <gtk/gtk.h>
/* XPM */
static char * WheelbarrowFull_xpm[] = {
"48 48 64 1",
" c None",
". c #DF7DCF3CC71B",
"X c #965875D669A6",
"o c #71C671C671C6",
"O c #A699A289A699",
"+ c #965892489658",
"@ c #8E38410330C2",
"# c #D75C7DF769A6",
"$ c #F7DECF3CC71B",
"% c #96588A288E38",
"& c #A69992489E79",
"* c #8E3886178E38",
"= c #104008200820",
"- c #596510401040",
"; c #C71B30C230C2",
": c #C71B9A699658",
"> c #618561856185",
", c #20811C712081",
"< c #104000000000",
"1 c #861720812081",
"2 c #DF7D4D344103",
"3 c #79E769A671C6",
"4 c #861782078617",
"5 c #41033CF34103",
"6 c #000000000000",
"7 c #49241C711040",
"8 c #492445144924",
"9 c #082008200820",
"0 c #69A618611861",
"q c #B6DA71C65144",
"w c #410330C238E3",
"e c #CF3CBAEAB6DA",
"r c #71C6451430C2",
"t c #EFBEDB6CD75C",
"y c #28A208200820",
"u c #186110401040",
"i c #596528A21861",
"p c #71C661855965",
"a c #A69996589658",
"s c #30C228A230C2",
"d c #BEFBA289AEBA",
"f c #596545145144",
"g c #30C230C230C2",
"h c #8E3882078617",
"j c #208118612081",
"k c #38E30C300820",
"l c #30C2208128A2",
"z c #38E328A238E3",
"x c #514438E34924",
"c c #618555555965",
"v c #30C2208130C2",
"b c #38E328A230C2",
"n c #28A228A228A2",
"m c #41032CB228A2",
"M c #104010401040",
"N c #492438E34103",
"B c #28A2208128A2",
"V c #A699596538E3",
"C c #30C21C711040",
"Z c #30C218611040",
"A c #965865955965",
"S c #618534D32081",
"D c #38E31C711040",
"F c #082000000820",
" ",
" .XoO ",
" +@#$%o& ",
" *=-;#::o+ ",
" >,<12#:34 ",
" 45671#:X3 ",
" +89<02qwo ",
"e* >,67;ro ",
"ty> 459@>+&& ",
"$2u+ ><ipas8* ",
"%$;=* *3:.Xa.dfg> ",
"Oh$;ya *3d.a8j,Xe.d3g8+ ",
" Oh$;ka *3d$a8lz,,xxc:.e3g54 ",
" Oh$;kO *pd$%svbzz,sxxxxfX..&wn> ",
" Oh$@mO *3dthwlsslszjzxxxxxxx3:td8M4 ",
" Oh$@g& *3d$XNlvvvlllm,mNwxxxxxxxfa.:,B* ",
" Oh$@,Od.czlllllzlmmqV@V#V@fxxxxxxxf:%j5& ",
" Oh$1hd5lllslllCCZrV#r#:#2AxxxxxxxxxcdwM* ",
" OXq6c.%8vvvllZZiqqApA:mq:Xxcpcxxxxxfdc9* ",
" 2r<6gde3bllZZrVi7S@SV77A::qApxxxxxxfdcM ",
" :,q-6MN.dfmZZrrSS:#riirDSAX@Af5xxxxxfevo",
" +A26jguXtAZZZC7iDiCCrVVii7Cmmmxxxxxx%3g",
" *#16jszN..3DZZZZrCVSA2rZrV7Dmmwxxxx&en",
" p2yFvzssXe:fCZZCiiD7iiZDiDSSZwwxx8e*>",
" OA1<jzxwwc:$d%NDZZZZCCCZCCZZCmxxfd.B ",
" 3206Bwxxszx%et.eaAp77m77mmmf3&eeeg* ",
" @26MvzxNzvlbwfpdettttttttttt.c,n& ",
" *;16=lsNwwNwgsvslbwwvccc3pcfu<o ",
" p;<69BvwwsszslllbBlllllllu<5+ ",
" OS0y6FBlvvvzvzss,u=Blllj=54 ",
" c1-699Blvlllllu7k96MMMg4 ",
" *10y8n6FjvllllB<166668 ",
" S-kg+>666<M<996-y6n<8* ",
" p71=4 m69996kD8Z-66698&& ",
" &i0ycm6n4 ogk17,0<6666g ",
" N-k-<> >=01-kuu666> ",
" ,6ky& &46-10ul,66, ",
" Ou0<> o66y<ulw<66& ",
" *kk5 >66By7=xu664 ",
" <<M4 466lj<Mxu66o ",
" *>> +66uv,zN666* ",
" 566,xxj669 ",
" 4666FF666> ",
" >966666M ",
" oM6668+ ",
" *4 ",
" ",
" "};
 
/* Termine l'application lorsqu'elle est appelée
/* XPM */
* (via le signal "delete_event"). */
static char * WheelbarrowFull_xpm[] = {
"48 48 64 1",
void close_application( GtkWidget *widget, GdkEvent *event, gpointer *data )
" c None",
{
". c #DF7DCF3CC71B",
"X c #965875D669A6",
"o c #71C671C671C6",
"O c #A699A289A699",
"+ c #965892489658",
"@ c #8E38410330C2",
"# c #D75C7DF769A6",
"$ c #F7DECF3CC71B",
"% c #96588A288E38",
"& c #A69992489E79",
"* c #8E3886178E38",
"= c #104008200820",
"- c #596510401040",
"; c #C71B30C230C2",
": c #C71B9A699658",
"> c #618561856185",
", c #20811C712081",
"< c #104000000000",
"1 c #861720812081",
"2 c #DF7D4D344103",
"3 c #79E769A671C6",
"4 c #861782078617",
"5 c #41033CF34103",
"6 c #000000000000",
"7 c #49241C711040",
"8 c #492445144924",
"9 c #082008200820",
"0 c #69A618611861",
"q c #B6DA71C65144",
"w c #410330C238E3",
"e c #CF3CBAEAB6DA",
"r c #71C6451430C2",
"t c #EFBEDB6CD75C",
"y c #28A208200820",
"u c #186110401040",
"i c #596528A21861",
"p c #71C661855965",
"a c #A69996589658",
"s c #30C228A230C2",
"d c #BEFBA289AEBA",
"f c #596545145144",
"g c #30C230C230C2",
"h c #8E3882078617",
"j c #208118612081",
"k c #38E30C300820",
"l c #30C2208128A2",
"z c #38E328A238E3",
"x c #514438E34924",
"c c #618555555965",
"v c #30C2208130C2",
"b c #38E328A230C2",
"n c #28A228A228A2",
"m c #41032CB228A2",
"M c #104010401040",
"N c #492438E34103",
"B c #28A2208128A2",
"V c #A699596538E3",
"C c #30C21C711040",
"Z c #30C218611040",
"A c #965865955965",
"S c #618534D32081",
"D c #38E31C711040",
"F c #082000000820",
" ",
" .XoO ",
" +@#$%o& ",
" *=-;#::o+ ",
" >,<12#:34 ",
" 45671#:X3 ",
" +89<02qwo ",
"e* >,67;ro ",
"ty> 459@>+&& ",
"$2u+ ><ipas8* ",
"%$;=* *3:.Xa.dfg> ",
"Oh$;ya *3d.a8j,Xe.d3g8+ ",
" Oh$;ka *3d$a8lz,,xxc:.e3g54 ",
" Oh$;kO *pd$%svbzz,sxxxxfX..&wn> ",
" Oh$@mO *3dthwlsslszjzxxxxxxx3:td8M4 ",
" Oh$@g& *3d$XNlvvvlllm,mNwxxxxxxxfa.:,B* ",
" Oh$@,Od.czlllllzlmmqV@V#V@fxxxxxxxf:%j5& ",
" Oh$1hd5lllslllCCZrV#r#:#2AxxxxxxxxxcdwM* ",
" OXq6c.%8vvvllZZiqqApA:mq:Xxcpcxxxxxfdc9* ",
" 2r<6gde3bllZZrVi7S@SV77A::qApxxxxxxfdcM ",
" :,q-6MN.dfmZZrrSS:#riirDSAX@Af5xxxxxfevo",
" +A26jguXtAZZZC7iDiCCrVVii7Cmmmxxxxxx%3g",
" *#16jszN..3DZZZZrCVSA2rZrV7Dmmwxxxx&en",
" p2yFvzssXe:fCZZCiiD7iiZDiDSSZwwxx8e*>",
" OA1<jzxwwc:$d%NDZZZZCCCZCCZZCmxxfd.B ",
" 3206Bwxxszx%et.eaAp77m77mmmf3&eeeg* ",
" @26MvzxNzvlbwfpdettttttttttt.c,n& ",
" *;16=lsNwwNwgsvslbwwvccc3pcfu<o ",
" p;<69BvwwsszslllbBlllllllu<5+ ",
" OS0y6FBlvvvzvzss,u=Blllj=54 ",
" c1-699Blvlllllu7k96MMMg4 ",
" *10y8n6FjvllllB<166668 ",
" S-kg+>666<M<996-y6n<8* ",
" p71=4 m69996kD8Z-66698&& ",
" &i0ycm6n4 ogk17,0<6666g ",
" N-k-<> >=01-kuu666> ",
" ,6ky& &46-10ul,66, ",
" Ou0<> o66y<ulw<66& ",
" *kk5 >66By7=xu664 ",
" <<M4 466lj<Mxu66o ",
" *>> +66uv,zN666* ",
" 566,xxj669 ",
" 4666FF666> ",
" >966666M ",
" oM6668+ ",
" *4 ",
" ",
" "};
 
 
/* Termine l'application lorsqu'elle est appelée
* (via le signal "delete_event"). */
 
void close_application( GtkWidget *widget, GdkEvent *event, gpointer *data )
{
gtk_main_quit();
}
 
 
int main (int argc, char *argv[])
{
GtkWidget *window, *pixmap, *fixed;
GdkPixmap *gdk_pixmap;
Ligne 328 ⟶ 322 :
* pour terminer l'application. On notera que la fenêtre principale
* n'a pas de barre de titre car nous la faisons surgir. */
 
gtk_init (&argc, &argv);
window = gtk_window_new( GTK_WINDOW_POPUP );
Ligne 334 ⟶ 328 :
GTK_SIGNAL_FUNC (close_application), NULL);
gtk_widget_show (window);
 
/* Création du pixmap et du widget pixmap */
 
style = gtk_widget_get_default_style();
gc = style->black_gc;
Ligne 344 ⟶ 338 :
pixmap = gtk_pixmap_new( gdk_pixmap, mask );
gtk_widget_show( pixmap );
 
/* Pour afficher le pixmap, on utilise un widget fixe pour placer
* le pixmap */
 
fixed = gtk_fixed_new();
gtk_widget_set_usize( fixed, 200, 200 );
Ligne 353 ⟶ 347 :
gtk_container_add( GTK_CONTAINER(window), fixed );
gtk_widget_show( fixed );
 
/* On masque tout sauf l'image elle-même */
 
gtk_widget_shape_combine_mask( window, mask, 0, 0 );
/* Affichage de la fenêtre */
 
gtk_widget_set_uposition( window, 20, 400 );
gtk_widget_show( window );
Ligne 365 ⟶ 359 :
return 0;
}
 
Pour rendre l'image de la brouette sensible aux clics, on peut lui attacher le signal "button_press_event" pour lui faire faire quelque chose. Les quelques lignes suivantes font que l'image sera sensible à un clic souris qui provoquera l'arrêt de l'application.
 
gtk_widget_set_events( window,
gtk_widget_get_events( window ) |
GDK_BUTTON_PRESS_MASK );
 
gtk_signal_connect( GTK_OBJECT(window), "button_press_event",
GTK_SIGNAL_FUNC(close_application), NULL );