Re: changing a widget's background




andrew@cogent.ca writes:

> On Apr 26,  4:14pm, Ramiro Estrugo wrote:
> } Subject: [gtk-list] changing a widget's background
> } what is the correct way to do this ?
> } 
> } ive experimented with chaning the w->window and hacking the style with
> } little success.
> } 
> } all i want to do is change the background.
> 
> Lots of people ask this.  It actually is a lot harder than it needs to
> be.  We have hacked a function to simplify matters somewhat.  It takes
> a color ID (foreground, etc.) and a widget state (normal, prelight,
> etc.), as well as a 24-bit packed RGB color, where 0xff0000 would be
> red and 0x0000ff would be blue.  Returns 1 on success, 0 on failure.
> I suggest that this function be added to the GTK+ API if there is
> nothing similar that I have overlooked.

The problem with this approach (gtk_widget_get_style(), gtk_style_copy())
is that it won't reflect changes in the style that occur dynamically.

The better way to do this is with gtk_widget_modify_style().

A quick example of using would be:

===
GtkRcStyle *rc_style = gtk_rc_style_new();

rc_style->color_flags[GTK_STATE_NORMAL] |= GTK_RC_FG;
rc_style->fg[GTK_STATE_NORMAL].red = 0xffff;
rc_style->fg[GTK_STATE_NORMAL].green = 0;
rc_style->fg[GTK_STATE_NORMAL].blue = 0;

gtk_widget_modify_style (widget, rc_style);
===

A function similar to your original one, would look something
like:

void
gtk_widget_set_color (GtkWidget *widget, GtkRcFlags color, GtkStateType state,
                      GdkColor *color)
{
  GtkRcStyle *rc_style;

  g_return_if_fail (widget != NULL);
  g_return_if_fail (GTK_IS_WIDGET (widget));
  g_return_if_fail (color != NULL);

  rc_style  = gtk_object_get_data (GTK_OBJECT (widget), "modify-style");

  if (!rc_style)
    {
      rc_style = gtk_rc_style_new ();
      gtk_widget_modify_style (widget, rc_style);
      gtk_object_set_data (GTK_OBJECT (widget), "modify-style", rc_style);
    }

  switch (color) {
  case GTK_RC_FG:
    rc_style->flags[state] |= GTK_RC_FG;
    rc_style->fg[state] = *color;
    break;
  case GTK_RC_BG:
    rc_style->flags[state] |= GTK_RC_FG;
    rc_style->fg[state] = *color;
    break;
  case GTK_RC_TEXT:
    rc_style->flags[state] |= GTK_RC_TEXT;
    rc_style->fg[state] = *color;
    break;
  case GTK_RC_BASE:
    rc_style->flags[state] |= GTK_RC_BASE;
    rc_style->fg[state] = *color;
    break;
  default:  
    g_warning ("gtk_widget_set_color: Unknown state color flag %d\n", color);
  }  
}
 
Some convenience functions (not exactly like this) probably
would have been added to 1.2, but modify_style() was
added fairly late, so there wasn't enough time to figure
out exactly what was the right way of doing it.

(Actually, gtk_widget_modify_style has some issues that
 probably need to be addressed in 1.4:

 - It assumes the reference count of its argument, instead
   of adding to it

 - It doesn't trigger a "style_set" signal if the widget has a
   style already
)

To get back to the original question of changing the background...
It does depend on what kind of widget you are dealing
with.

For a drawing area, for example, the simplest way is simply
going to be:

 gtk_widget_realize (darea);
 gdk_window_set_background (darea->window, &color);

This will generally apply to any widget that you are painting
yourself. (For a layout it would should be
GTK_LAYOUT(layout)->bin->window)

For widgets that GTK+ is drawing, you need to take one of
the other approaches. 


[ Standard disclaimer: changing the color scheme (or fonts) of your
widgets is generally a bad idea, except in unusual circumstances.

 - You are overriding the user's preferences, and possibly ending
   up with an illegible result.

 - It's just bad graphics design to have a bunch of different fonts
   and colors.
]

Regards,
                                        Owen



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]