2012-09-03 11 views
5

Sto cercando di creare un widget personalizzato in GTK 3. Ho notato problemi di disegno che appaiono solo con determinati temi GTK, mentre tutti gli altri temi funzionano alla grande. Ho ristretto il problema al codice che disegna lo sfondo chiamando gtk_render_background(). Per alcuni temi, lo sfondo viene reso in nero, anche se questo non è il colore di sfondo predefinito dei temi. Di seguito è una versione semplificata della mia funzione di disegno.Sfondo del widget GTK personalizzato viene reso nero fisso

static void gtk_databox_ruler_draw_ticks(GtkDataboxRuler *ruler) 
{ 
    GtkWidget *widget; 
    GtkStateFlags state; 
    cairo_t *cr; 
    GtkStyleContext *style_context; 
    gint width, height; 

    if (!gtk_widget_is_drawable(GTK_WIDGET(ruler))) { 
     return; 
    } 

    widget = GTK_WIDGET(ruler); 
    state = gtk_widget_get_state_flags(widget); 
    style_context = gtk_widget_get_style_context(widget); 

    gtk_style_context_save(style_context); 
    gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_DEFAULT); 
    gtk_style_context_set_state(style_context, state); 

    /* <test-code> */ 
    GdkRGBA test; 
    gtk_style_context_get_background_color(style_context, gtk_widget_get_state_flags(widget), &test); 
    /* </test-code> */ 

    width = gtk_widget_get_allocated_width(widget); 
    height = gtk_widget_get_allocated_height(widget); 

    cr = cairo_create(ruler->priv->backing_surface); 

    gtk_render_background(style_context, cr, 0, 0, width, height); 

    gtk_style_context_restore(style_context); 
    cairo_destroy(cr); 
} 

ho aggiunto un po 'di test-codice per interrogare il colore di sfondo e impostare un punto di interruzione in gdb:

Quando si utilizza Ambiance tema di Ubuntu:

(gdb) print test 
$1: test = {red = 0.94901960784313721, green = 0.94509803921568625, 
    blue = 0.94117647058823528, alpha = 1} 

Quando si utilizza highcontrast tema di Ubuntu:

(gdb) print test 
$1: test = {red = 0, green = 0, blue = 0, alpha = 0} 

Ora mi chiedo se uso il nuovo GtkStyleContext in modo errato, o se o il il tema è rotto. Come posso restringere la fonte del problema?

Mi piacerebbe anche che qualcuno possa indicarmi una buona introduzione a GtkStyleContext. La documentazione API ufficiale non è così utile per comprendere il concetto fondamentale.

+0

Non so dove si sta disegnando, ma si può solo disegnare un widget nel suo metodo virtuale di disegno: ci sono così tante cose nel codice che causano un comportamento imprevisto, che qualsiasi cosa potrebbe fare ciò – erick2red

+0

La funzione gtk_databox_ruler_draw_ticks' mostrata sopra è chiamata dalla funzione di disegno del widget ('GtkWidgetClass-> draw'). Puoi indicare cose nel codice sopra che devono essere corrette? – dasup

+0

Non so se ti aiuterà, ma potresti guardare [qui] (http://erick2red.github.com/blog/2012/08/21/making-you-own-widget/) – erick2red

risposta

4

Dopo oltre un anno, ho dovuto esaminare nuovamente questo problema perché si verifica anche quando si utilizza lo stile predefinito GTK3 (incorporato), vale a dire quando il mio programma viene utilizzato su un sistema che non ha temi ecc. installato.

Sembra che la fonte del problema sia che alcuni temi GTK definiscono un colore di sfondo per il "caso predefinito" e altri no.

Il GTK3 default theme:

… 
* { 
    color: @fg_color; 
    border-color: shade (@bg_color, 0.6); 
    padding: 2px; 
    -GtkWindow-resize-grip-width: 0; 
    -GtkWindow-resize-grip-height: 0; 
    -GtkWindow-decoration-button-layout: 'icon:minimize,maximize,close'; 
} 

GtkWindow, .button, .slider { 
    background-color: @bg_color; 
} 
… 

Il tema Adwaita:

… 
* { 
    /* inherit the color from parent by default */ 
    color: inherit; 
    background-color: @theme_bg_color; 
} 
… 

per ottenere la sfondo disegnato, ho semplicemente bisogno di selezionare una classe widget che ha un colore di sfondo definito in tutti (la maggior parte) temi. Io uso la classe Button per quello:

gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_BUTTON); 
2

Quale versione di Ubuntu e GTK3 stai usando?

Forse è necessario chiamare gtk_style_context_set_junction_sides().

Questa informazione potrebbe essere interessata anche da Benjamin Otte, uno degli sviluppatori di GTK. How GTK styling works, disponibile anche GTK+3 Styling.

+0

Sto usando Ubuntu 12.04, libgtk è nella versione 3.4.2-0ubuntu0. Ho aggiunto 'gtk_style_context_set_junction_sides 'con' GTK_JUNCTION_BOTTOM' impostato dopo 'gtk_style_context_add_class' ma ciò non ha risolto il problema. Grazie per il link, ma penso che si concentri maggiormente sul lato CSS mentre ho bisogno di maggiori informazioni su GtkStyl lato eContext (es. rendering, cosa fa salvare/ripristinare, come funzionano le classi). – dasup

1

parte del pescato qui può essere che sempre di più, non c'è necessariamente un singolo colore di sfondo più.

Per la documentazione di https://developer.gnome.org/gtk3/stable/GtkStyleContext.html#gtk-style-context-get-background-color:

". Questa funzione è molto meno utile di quanto sembri, e non dovrebbe essere utilizzato in codice appena scritto CSS non ha il concetto di 'colore di sfondo', come sfondo può essere un'immagine, o un gradiente, o qualsiasi altro motivo compresi i colori solidi."

+0

Grazie per aver segnalato questo! Si prega di notare che nel codice precedente, ho usato 'gtk_style_context_get_background_color' solo per scopi di test/debug. Il codice reale chiama 'gtk_render_background', che presumo riguardi tutti i tipi di definizioni di backround. Tuttavia, chiamando 'gtk_render_background' si ottiene un backround nero pieno con alcuni temi. – dasup