Re: GtkStyle arguments for GtkWidget




Tim Janik <timj@gtk.org> writes:

> hi all,
> 
> i'm about to implement editing facilities for a widget's GtkStyle in
> GLE. i first intended to implement special knowledge about styles in
> GLE, but come to think of it, it's actually much more usefull to export
> the style fields through the widget arguments (besides the obvious
> reduction of code duplication in interface builders and language bindings).

First - the whole subject of setting styles for widgets needs
some revision in light of themes.

The style of a widget should not be seen as something one
sets, but rather something that is constructed out of
a number of GtkRcStyles.

typedef enum {
  GTK_RC_FG   = 1 << 0,
  GTK_RC_BG   = 1 << 1,
  GTK_RC_TEXT = 1 << 2,
  GTK_RC_BASE = 1 << 3
} GtkRcFlags;

struct _GtkRcStyle
{
  char *name;
  char *font_name;
  char *fontset_name;
  char *bg_pixmap_name[5];

  GtkRcFlags color_flags[5];
  GdkColor   fg[5];
  GdkColor   bg[5];
  GdkColor   text[5];
  GdkColor   base[5];

  GtkThemeEngine *engine;
  gpointer        engine_data;

  /* Private */
  guint ref_count;
};

In contrast to GtkStyles, these can be composited, because
each field can be "undefined", rather than set.

Probably, the way this should work is that there would be
one RcStyle set as object data, which is more tightly
bound than all the styles set in the RC file. Then,
one would do (ignoring widget args stuff):

 GtkRcStyle *rc_style = gtk_rc_style_new();
 static GdkColor red = { 0, 0xffff, 0, 0 };

 rc_style->color_flags[GTK_STATE_NORMAL] = GTK_RC_FG;
 rc_style->fg[NORMAL] = red;

 gtk_widget_set_rc_style (widget, rc_style);
 gtk_rc_style_unref (rc_style);

So, the way that your proposed style_XX stuff would work
would be:

 - If there is no RC style for the widget, create it,
   and set the field.

 - Otherwise, modify the current RC style.

> currently, a GtkWidget only supports
> "GtkWidget::style" of type GtkStyle*
> if the style args get implemented as
> widget arguments, we will also get:
> "GtkWidget::style_fg::STATE" of type GtkColorValue
> "GtkWidget::style_bg::STATE" of type GtkColorValue
> "GtkWidget::style_light::STATE" of type GtkColorValue
> "GtkWidget::style_dark::STATE" of type GtkColorValue
> "GtkWidget::style_mid::STATE" of type GtkColorValue
> "GtkWidget::style_text::STATE" of type GtkColorValue
> "GtkWidget::style_base::STATE" of type GtkColorValue
> "GtkWidget::style_black" of type GtkColorValue
> "GtkWidget::style_white" of type GtkColorValue
> "GtkWidget::style_font" of type GtkFontName

There probably needs to be style_fontset as well as
style_font.

> STATE is an enum value from GtkStateType and thus may consist of
> { 0, 1, 2, 3, 4, GTK_STATE_NORMAL, GTK_STATE_ACTIVE, GTK_STATE_PRELIGHT,
>   GTK_STATE_SELECTED, GTK_STATE_INSENSITIVE, normal, active, prelight,
>   selected, insensitive }

> GtkColorValue is an new type derived from GTK_TYPE_UINT and will consist
> of #oobbggrr, where oo stands for the opacity (opacity isn't really used
> by the styles, but this would also be the correct type to be returned
> from GtkColorSelection).

As established in quite a few other places in the
GTK+ API, a color is represented as a GdkColor, and an
unallocated color as a GdkColor with the pixel field
ignored. I don't think we should deviate from that
here. 

The GdkColor structure has an usused 16 bits of padding,
so it would be possible to add opacity to it, or define
a GtkColor struct which was GdkColor + opacity.

> GtkFontName is a new type derived from GTK_TYPE_STRING (similar to
> GTK_TYPE_IDENTIFIER) describing the fontname.

I'm not really sure of the advantages of the aliasing here...
the inspiriation for GTK_TYPE_IDENTIFIER was that identifiers
could be distinguished from strings in RC file syntax.

> to get the STATE -> GtkStateType mapping working, GtkArgInfo will gain
> a new member GtkType name_parameter_type; indicating what the third
> part of an argument name may consist of (we need this anyways for
> the "GtkObject::*signal::" arguments which take a signal name as
> third parameter). the name_parameter_type can be queried through an
> extended query_args interface, e.g. gtk_object_query_args_extended or _full).

This sounds like a nice addition - it regularizes the signal::
syntax.

> besides the advantage that GUI builders would gain from the style args, this
> interface would also come in handy for language bindings and even C code,
> where one can then easily change a widgets appearance through
> 
> button =
>   gtk_widget_new (GTK_TYPE_ENTRY,
>                   "visible", TRUE,
>                   "style_fg::normal", 0xffff00 /* yellow */,
>                   "style_base::normal", 0xff00ff /* purple */,
>                   "style_fg::selected", 0x000000 /* black */,
>                   "style_base::normal", 0xffffff /* white */,
>                   "style_font", "-freefont-brushstroke-*-*-*-*-*-*-*-*-*-*-*-*",
>                   NULL);
> 
> without going through all the hassle of copying and attaching new styles
> (especially in language bindings).

[ This hassle probably would be much _less_ in a language binding - 
  with the RC stuff, it would probably look like, in Perl:

gtk_widget_new (GTK_TYPE_ENTRY,
        visible => TRUE,
        style => { fg => { normal => { 0, 0xffff, 0xffff, 0 },
                            selected => { 0, 0, 0, 0 } },
                   base => { normal => { 0, 0xffff, 0, 0xffff },
                             selected => { 0, 0xffff, 0xffff, 0xfff } },
                   font => "-freefont-brushstroke-*-*-*-*-*-*-*-*-*-*-*-*" })

 but anyways... ]

Regards,
                                        Owen



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