IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

GTK+ avec C & C++ Discussion :

GTK+-2.24 et gtk_widget_modify_bg(): comment lutter contre le changement du climat informatique.


Sujet :

GTK+ avec C & C++

  1. #1
    Membre confirmé
    Profil pro
    Retraité
    Inscrit en
    Novembre 2009
    Messages
    330
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2009
    Messages : 330
    Points : 607
    Points
    607
    Par défaut GTK+-2.24 et gtk_widget_modify_bg(): comment lutter contre le changement du climat informatique.
    J'indique ceci pour faire gagner du temps à ceux que cela peut intéresser.

    Le but est de choisir des couleurs codées en dur en utilisant une palette, toujours la même depuis la plus haute antiquité et indépendantes du thème utilisé sur une machine donnée.
    Il serai en effet gênant de comparer deux courbes censés être de même couleur sans l'être vraiment.
    Avec ma vieille Debian-6, en utilisant gtk_widget_modify_bg(), j'affichais la palette:
    Nom : panneau_colore.jpg
Affichages : 929
Taille : 35,3 Ko
    mais avec des versions plus récentes, comme Mint-18, j'obtenais ceci:
    Nom : panneau_gris.jpg
Affichages : 740
Taille : 50,0 Ko

    Après avoir erré dans la doc de GTK sans succès, j'ai finalement trouvé la solution à mon problème ici:
    http://wxwidgets.10942.n7.nabble.com...n-td90794.html
    Il faut désactiver l'influence du thème sur les boutons avec ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    gtk_rc_parse_string(
                          "style \"our_button\" {\n"
                          // This disables any engines that may be setting button
                          // background images:
                          "   engine \"\" {}\n"
                          // This should disable any other theme settings for button
                          // background images:
                          "   bg_pixmap[NORMAL] = \"<none>\"\n"
                          "   bg_pixmap[ACTIVE] = \"<none>\"\n"
                          "   bg_pixmap[PRELIGHT] = \"<none>\"\n"
                          "   bg_pixmap[SELECTED] = \"<none>\"\n"
                          "   bg_pixmap[INSENSITIVE] = \"<none>\"\n"
                          "}\n"
                          "class \"GtkButton\" style : highest \"our_button\"\n"
                          );
    Plus de détails sont donnés sur le lien cité.

    Je pense que ce serai une bonne idée de rajouter cet exemple dans la doc de GTK qui ne traite que de GtkLabel sachant que la méthode préconisée dans ce cas (rajouter une EventBox) ne convient pas pour un bouton: seulement un mince cadre autour du bouton est changé de couleur.

  2. #2
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 296
    Points : 4 949
    Points
    4 949
    Billets dans le blog
    5
    Par défaut
    Une remarque sûrement stupide : ne pourrais-tu pas simplement connecter sur tes boutons un callback associé au signal «*draw*» pour changer le fond ?

  3. #3
    Membre confirmé
    Profil pro
    Retraité
    Inscrit en
    Novembre 2009
    Messages
    330
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2009
    Messages : 330
    Points : 607
    Points
    607
    Par défaut
    C'est plutôt que j'ai dû mal définir le problème: pour gtk_widget_modify_bg() on a
    Note that “no window” widgets (which have the GTK_NO_WINDOW flag set) draw on their parent container’s window and thus may not draw any background themselves. This is the case for e.g. GtkLabel.To modify the background of such widgets, you have to set the background color on their parent; if you want to set the background of a rectangular area around a label, try placing the label in a GtkEventBox widget and setting the background color on that.
    Apparemment, les GtkButton sont dans ce cas. Quand on les place dans une EventBox, c'est celle-ci qui est coloriée, mais le bouton recouvre presque entièrement cette boite et la couleur visible reste fixée en principe par le thème utilisé, alors que le GtkLabel ne change que la couleur des caractères qu'il trace, laissant transparaître la EventBox derrière. C'est pourquoi on est obligé de désactiver le thème pour les boutons.
    Le problème n'est donc pas d'appeler ou non un Callback.
    Remarque: le procédé utilisé désactive le thème pour tous les boutons.
    Remarque: comme je suis toujours en GTK+-2, c'est le signal "expose-event" (remplacé par "draw" dans GTK-3) qui pourrait être concerné.

    En fait, j'ai tout un tas de récriminations en stock concernant les changements forcés induits par l'évolution du paysage informatique. Par exemple pour ce qui est des thèmes, sur ma Debian-6 j'avais installé le thème Glossy avec pour les bordures de fenêtres Glider: ceux-ci ont disparus depuis et comme je n'ai pas envie de passer des heures à essayer d'en trouver un aussi beau, je me contente d'un aspect moins élégant.
    Plus sérieusement, j'aime bien le débogueur DDD mais, faute de maintenance, celui-ci n'a pas été adapté au nouveau format ELF et n'est donc plus opérationnel. J'oscille donc entre Nemiver, convivial mais pour lequel je n'ai pas trouvé comment envoyer directement une commande à GDB, et GUD, l'interface Emacs de GDB bien moins conviviale que DDD mais plus puissante que Nemiver.
    En définitive, je reviens souvent sous Debian-6 pour retrouver avec délice mes habitudes de dinosaure.

  4. #4
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 296
    Points : 4 949
    Points
    4 949
    Billets dans le blog
    5
    Par défaut
    Je me suis mis à chercher une petite solution pérenne à ton problème. Effectivement on n'accède pas à l'espace graphique d'un GtkButton. J'ai contourné le problème en insérant dans les GtkButton des GtkLabel. Pour eux il est possible de "bricoler" un peu leur affichage.

    Malheureusement je n'ai pas pu compiler pour Gtk+v2.0. Mais je pense que ca doit fonctionner aussi sous cette version. Voila le résultat obtenu :
    Nom : Capture d’écran_2018-01-27_12-05-35.png
Affichages : 776
Taille : 64,9 Ko

    Si ca t'intéresse je te livre le code version Gtk+3.0.

    [Edit]
    Au final ce n'est pas fonctionnel sous Gtk+2.0. Il faut bien utiliser un GtkEventBox pour contourner le problème...
    [/Edit]

  5. #5
    Membre confirmé
    Profil pro
    Retraité
    Inscrit en
    Novembre 2009
    Messages
    330
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2009
    Messages : 330
    Points : 607
    Points
    607
    Par défaut
    Il faut bien utiliser un GtkEventBox pour contourner le problème...
    En fait, sous GTK-2, il n'y a même pas besoin d'une EventBox: l'appel à gtk_rc_parse_string() qui désactive le thème suffit pour rétablir l'action de gtk_widget_modify_bg() sur tous les boutons...

    Merci pour ton offre pour le code GTK-3. Je n'en suis pas encore là: j'essaye d'adapter mon code pour me passer des fonctions de GDK-2 dépréciées dans 2.24, ce qui pose encore quelques problèmes, mais ton code peut toujours m'intéresser.

  6. #6
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 296
    Points : 4 949
    Points
    4 949
    Billets dans le blog
    5
    Par défaut
    Oups j’ai effacé le code source .

    Bon, ce n’est pas grave. Je vais l’ecrire à nouveau. Ça pourra toujours intéresser...

    Pour rebondir sur ton dernier post ce n’est pas un peu energivore de vouloir modifier ton code pour être à jour sur la v2.24 pour ensuite se dire de passer à la v3.0 ?

    Le passage à la v3.0 ne doit pas être bien compliqué je pense.

  7. #7
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 296
    Points : 4 949
    Points
    4 949
    Billets dans le blog
    5
    Par défaut
    Chose promise, chose due . Voila le code exemple en Gtk+3.0 pour colorer le label d'un bouton.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    #include <gtk/gtk.h>
     
    guchar colors[] = {255, 255, 255, 0, 0, 0, 252, 8, 10, 26, 254, 30,
    		   7, 2, 252, 254, 253, 6, 192, 210, 234, 227, 225, 226,
    		   150, 0, 226, 26, 235, 230, 240, 24, 254, 253, 166, 1,
    		   117, 29, 191, 108, 5, 76, 91, 230, 227, 0, 139, 6,
    		   166, 220, 244, 114, 97, 201, 81, 71, 140, 20, 21, 139,
    		   174, 254, 225, 162, 253, 222, 110, 205, 25, 75, 145, 121,
    		   254, 217, 14, 245, 201, 0, 192, 165, 26, 149, 128, 1,
    		   214, 214, 214, 171, 171, 171, 111, 111, 111, 89, 89, 89};
     
    gchar *text[] = {"white", "black", "red", "green",
    		 "blue", "yellow", "brown", "grey",
    		 "violet", "cyan", "magenta", "orange",
    		 "indigo", "maroon", "turquoise", "green4",
    		 "skyblue", "slateblue", "darkslateblue", "midnightblue",
    		 "aquamarine1", "aquamarine2", "aquamarine3", "aquamarine4",
    		 "gold1", "gold2", "gold3", "gold4",
    		 "grey80", "grey60", "grey40", "grey30"};
     
     
    gboolean
    callback_draw_background (GtkWidget *widget, cairo_t *cr, gpointer user_data)
    {
      /* count permet de récupérer la couleur correspondante dans le tableau colors[] */
      gint count = GPOINTER_TO_INT (user_data); /* Récupération du n° du bouton */
     
      /* Affectation de la couleur */
      cairo_set_source_rgb (cr, (gdouble)colors[count*3]/255, (gdouble)colors[count*3+1]/255, (gdouble)colors[count*3+2]/255);
     
      /* Récupération du rectangle graphique correspondant au GtkLabel */
      GtkAllocation allocation;
      gtk_widget_get_allocation (widget, &allocation);
     
      /* Création d'un chemin dans cairo puis remplissage de celui-ci */
      cairo_rectangle (cr, allocation.x, allocation.y, allocation.width, allocation.height);
      cairo_paint (cr);
     
      return FALSE;
    }
     
    gint
    main(gint argc, gchar **argv)
    {
      gtk_init(&argc, &argv);
     
      GtkWidget *Window = NULL;
      GtkWidget *grid = NULL;
      GtkWidget *button = NULL;
      GtkWidget *label = NULL;
      gint i, j;
      gint count = 0;
      gchar *compolabel = NULL;
     
      Window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
      g_signal_connect(G_OBJECT(Window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
     
      grid = gtk_grid_new ();
      gtk_container_add(GTK_CONTAINER(Window), grid);
     
      for (j=0; j < 8; j++)
        {
          for (i=0; i < 4; i++)
    	{
    	  /* Création du GtkLabel avec son texte approprié tiré du tableau text[] */
    	  compolabel = g_strdup_printf ("%d %s", count, text[i + j*4]);
    	  label = gtk_label_new (compolabel);
    	  g_free (compolabel);
     
    	  /* Création du bouton qui va recevoir le GtkLabel comme widget enfant */
    	  button = gtk_button_new ();
    	  gtk_container_add (GTK_CONTAINER (button), label);
    	  /* Connexion du signal draw au GtkLabel. C'est dans ce callback que le fond change de couleur. On transmet
               * en donnée utilisateur le n° du bouton. Ce nombre va nous permettre d'extraire la couleur correspondante. */
    	  g_signal_connect (G_OBJECT (label), "draw", G_CALLBACK(callback_draw_background), GINT_TO_POINTER(count));
     
    	  /* Insertion du bouton courant dans la grille */
    	  gtk_grid_attach (GTK_GRID (grid), button, i, j, 1, 1);
     
    	  count++;
    	}
        }
     
      gtk_widget_show_all(Window);
     
      gtk_main();
     
      return 0;
    }

  8. #8
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Points : 2 002
    Points
    2 002
    Par défaut
    En GTK+ 3, pourquoi ne pas directement utiliser un GtkColorButton ou GtkColorChooserDialog ? De plus l'analyse du code de GtkColorButton devrait permettre de voir comment colorier l'intérieur d'un boutton proprement: c'est exactement le comportement du widget.

    En GTK+ 2, GtkColorButton existait déjà, donc idem, il suffit d'analyser le code. Je pense que ça doit lancer une boîte de dialogue de sélection de couleur (un GtkColorSelectionDialog en GTK+ 2). Il faut alors personnaliser le sélecteur pour n'utiliser qu'une palette prédéfinie de couleurs.

    Bien sûr, je pars du principe que le nom de la couleur n'a pas une importance capitale, mais bon, toutes les couleurs n'ont pas un nom donc baser l'interface utilisateur sur un nom de couleur ne me parait pas forcément pertinent, même si on a accès qu'à une palette de couleurs. Le seul intérêt que je vois serait pour l'accessibilité (daltoniens, par exemple).

  9. #9
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Points : 2 002
    Points
    2 002
    Par défaut
    Citation Envoyé par gerald3d Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    guchar colors[] = {255, 255, 255, 0, 0, 0, 252, 8, 10, 26, 254, 30,
    		   7, 2, 252, 254, 253, 6, 192, 210, 234, 227, 225, 226,
    		   150, 0, 226, 26, 235, 230, 240, 24, 254, 253, 166, 1,
    		   117, 29, 191, 108, 5, 76, 91, 230, 227, 0, 139, 6,
    		   166, 220, 244, 114, 97, 201, 81, 71, 140, 20, 21, 139,
    		   174, 254, 225, 162, 253, 222, 110, 205, 25, 75, 145, 121,
    		   254, 217, 14, 245, 201, 0, 192, 165, 26, 149, 128, 1,
    		   214, 214, 214, 171, 171, 171, 111, 111, 111, 89, 89, 89};
     
    gchar *text[] = {"white", "black", "red", "green",
    		 "blue", "yellow", "brown", "grey",
    		 "violet", "cyan", "magenta", "orange",
    		 "indigo", "maroon", "turquoise", "green4",
    		 "skyblue", "slateblue", "darkslateblue", "midnightblue",
    		 "aquamarine1", "aquamarine2", "aquamarine3", "aquamarine4",
    		 "gold1", "gold2", "gold3", "gold4",
    		 "grey80", "grey60", "grey40", "grey30"};
    C'est un peu moche cette affaire :/. Si le but est d'associer une couleur à un nom, alors crée une structure qui représente cette association, c'est plus lisible.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    typedef struct _RGBColor
    {
        guint8 red;
        guint8 green;
        guint8 blue;
    } RGBColor;
     
    typedef struct _Palette
    {
        gchar *name;
        RGBColor color;
    } PaletteColor;
     
    static const PaletteColor palette[] = {
        { "white", { 255, 255, 255 } },
        { "black", { 0, 0, 0 } },
    ...
    };

    Ensuite à la connexion du signal on donne directement le pointeur vers la couleur en question plutôt qu'un indice de tableau.

    Cela permet ensuite de faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    PaletteColor *color = user_data;
    cairo_set_source_rgb (cr, color->red / 255.0, colors->green / 255.0, colors->blue / 255.0);
    Les 255.0 sont là pour forcer un calcul en flottant et pas en entier.

    Attention: code non testé

  10. #10
    Membre confirmé
    Profil pro
    Retraité
    Inscrit en
    Novembre 2009
    Messages
    330
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2009
    Messages : 330
    Points : 607
    Points
    607
    Par défaut
    Dans Grace et GraceGTK, les noms et les valeurs RGB des couleurs sont conformes à /etc/X11/rgb.txt et je trouve souhaitable que l'utilisateur ne les change pas: on ne parle pas ici d'effets artistiques mais de cohérence souhaité entre plusieurs publications scientifiques.

    Dans le langage de script de Grace(GTK), une couleur peut être désignée, soit par un numéro, soit par un nom. La palette de base est fixée dans un script de démarrage (templates/Default.agr) qui permet, si l'utilisateur le désire, de rajouter des couleurs à cette palette de base (et même de modifier celle-ci, mais c'est fortement déconseillé).
    La gestion de cette palette dans Grace n'est peut être pas optimale, mais elle existait bien avant moi et à le mérite d'être complètement autonome, donc je ne vois pas la nécessité d'en changer.
    C'est l'interface interactive qui peut poser problème et ma démarche, c'est de donner la priorité au langage et à sa compatibilité ascendante.

    L'utilisation des tableaux par Gerald est, je pense, une simple commodité de sa part, dans Grace, on trouve le type de structure dont tu parle:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    typedef struct {
        RGB rgb;
        char *cname;
        int ctype;
        int tstamp;
    } CMap_entry;
    P.S.: je n'ai pas vraiment compris l'utilité du tstamp, mais je ne me suis pas risqué à l'éliminer.
    Le ctype sert à distinguer les COLOR_MAIN des teintes intermédiaires engendrées pour l'anti-aliasing par l'interface Grace/T1Lib

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comment mieux lutter contre le travail dissimulé
    Par Invité dans le forum Développement
    Réponses: 0
    Dernier message: 29/01/2016, 21h03
  2. Comment lutter efficacement contre les virus ?
    Par Hinault Romaric dans le forum Actualités
    Réponses: 34
    Dernier message: 20/01/2014, 21h57
  3. Réponses: 161
    Dernier message: 30/04/2009, 08h27
  4. Comment lutter contre le plagiat ?
    Par boux2 dans le forum Juridique
    Réponses: 6
    Dernier message: 03/07/2007, 08h07
  5. [Myphpnews] Comment lutter contre le spam dans les commentaires ?
    Par fireworks dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 30
    Dernier message: 25/10/2006, 14h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo