Some tweaks for the GtkStyleContext migration guide
This commit is contained in:
committed by
Carlos Garnacho
parent
0f98b15090
commit
091c882996
@ -6,25 +6,26 @@
|
|||||||
<title>Migrating from GtkStyle to GtkStyleContext</title>
|
<title>Migrating from GtkStyle to GtkStyleContext</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
In GTK+ 3.0, GTK+ was added GtkStyleContext to replace GtkStyle and
|
In GTK+ 3.0, #GtkStyleContext was added to replace #GtkStyle and
|
||||||
the theming infrastructure available in 2.x. GtkStyleContext is an
|
the theming infrastructure available in 2.x. GtkStyleContext is an
|
||||||
object similar in spirit to GtkStyle, as it contains theming information,
|
object similar in spirit to GtkStyle, as it contains theming information,
|
||||||
although in a more complete and tokenized fashion. Moving to #GtkStyleContext
|
although in a more complete and tokenized fashion. There are two aspects
|
||||||
is twofold, there is themes and theming engines on one
|
to switching to GtkStyleContext: porting themes and theme engines, and
|
||||||
side, and applications, widgets and libraries on the other.
|
porting applications, libraries and widgets.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<refsect2 id="gtk-migrating-GtkStyleContext-themes">
|
<refsect2 id="gtk-migrating-GtkStyleContext-themes">
|
||||||
<title>Migrating themes</title>
|
<title>Migrating themes</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
From GTK+ 3.0 on, theme engines must implement #GtkThemingEngine and be installed
|
From GTK+ 3.0 on, theme engines must implement #GtkThemingEngine and be
|
||||||
in <literal>$(libdir)/gtk+-3.0/$(GTK_VERSION)/theming-engines</literal>, and
|
installed in <filename>$libdir/gtk+-3.0/$GTK_VERSION/theming-engines</filename>,
|
||||||
the files containing style information must be written in the CSS format as
|
and the files containing style information must be written in the CSS-like
|
||||||
parsed by #GtkCssProvider. For a theme named "Clearlooks", the CSS file parsed
|
format that is understood by #GtkCssProvider. For a theme named
|
||||||
by default would be <literal>$(sharedir)/themes/Clearlooks/gtk-3.0/gtk.css</literal>,
|
"Clearlooks", the CSS file parsed by default is
|
||||||
with possible variants such as the dark theme being named as "gtk-dark.css" in
|
<filename>$datadir/themes/Clearlooks/gtk-3.0/gtk.css</filename>,
|
||||||
the same directory.
|
with possible variants such as the dark theme being named
|
||||||
|
<filename>gtk-dark.css</filename> in the same directory.
|
||||||
</para>
|
</para>
|
||||||
</refsect2>
|
</refsect2>
|
||||||
|
|
||||||
@ -32,97 +33,112 @@
|
|||||||
<title>Migrating theme engines</title>
|
<title>Migrating theme engines</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Migrating a #GtkStyle based engine to a #GtkThemingEngine based one should
|
Migrating a #GtkStyle based engine to a #GtkThemingEngine based one
|
||||||
be straightforward for most of the vmethods. Besides a cleanup in the available
|
should be straightforward for most of the vfuncs. Besides a cleanup
|
||||||
paint methods and a cleanup in the parameters passed (in favor of #GtkStyleContext
|
in the available paint methods and a simplification in the passed
|
||||||
containing all the information), the available render methods should resemble
|
arguments (in favor of #GtkStyleContext containing all the information),
|
||||||
those of #GtkStyle quite evidently, with some differences worth to point out:
|
the available render methods resemble those of #GtkStyle quite
|
||||||
|
evidently. Notable differences include:
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<orderedlist>
|
<orderedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
All variations of <literal>gtk_paint_box()</literal>, <literal>gtk_paint_flat_box()</literal>,
|
All variations of gtk_paint_box(), gtk_paint_flat_box(),
|
||||||
<literal>gtk_paint_shadow()</literal>, <literal>gtk_paint_box_gap()</literal> and
|
gtk_paint_shadow(), gtk_paint_box_gap() and gtk_paint_shadow_gap()
|
||||||
<literal>gtk_paint_shadow_gap()</literal> become replaced by gtk_render_background(),
|
are replaced by gtk_render_background(), gtk_render_frame() and
|
||||||
gtk_render_frame() and gtk_render_frame_gap(), where the first would render frameless
|
gtk_render_frame_gap(). The first function renders frameless
|
||||||
backgrounds and the last two would render all frame variants.
|
backgrounds and the last two render frames in various forms.
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<literal>gtk_paint_resize_grip()</literal> disappears in favor of gtk_render_handle()
|
gtk_paint_resize_grip() has been subsumed by gtk_render_handle()
|
||||||
with a #GTK_STYLE_CLASS_GRIP class set in the style context.
|
with a #GTK_STYLE_CLASS_GRIP class set in the style context.
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<literal>gtk_paint_spinner()</literal> disappears in favor of gtk_render_activity()
|
gtk_paint_spinner() disappears in favor of gtk_render_activity()
|
||||||
with a #GTK_STYLE_CLASS_SPINNER class set in the style context.
|
with a #GTK_STYLE_CLASS_SPINNER class set in the style context.
|
||||||
</listitem>
|
</listitem>
|
||||||
</orderedlist>
|
</orderedlist>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The available list of render methods is:
|
The list of available render methods is:
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<simplelist>
|
<simplelist>
|
||||||
<member>gtk_render_background(): Renders a widget/area background.</member>
|
|
||||||
<member>
|
<member>
|
||||||
gtk_render_frame(): Renders a frame border around the given rectangle. Usually
|
gtk_render_background(): Renders a widget/area background.
|
||||||
the detail of the border depends on the theme information, plus the current widget
|
|
||||||
state.
|
|
||||||
</member>
|
|
||||||
<member>gtk_render_layout(): Renders a #PangoLayout</member>
|
|
||||||
<member>gtk_render_frame_gap(): Renders a frame border with a gap on one side.</member>
|
|
||||||
<member>
|
|
||||||
gtk_render_handle(): Renders all kind of handles and resize grips,
|
|
||||||
usually depending the rendering on the CSS class.
|
|
||||||
</member>
|
</member>
|
||||||
<member>
|
<member>
|
||||||
gtk_render_check() and gtk_render_option(): Respectively render checkboxes and
|
gtk_render_frame(): Renders a frame border around the given rectangle.
|
||||||
radiobuttons.
|
Usually the detail of the border depends on the theme information,
|
||||||
|
plus the current widget state.
|
||||||
</member>
|
</member>
|
||||||
<member>
|
<member>
|
||||||
gtk_render_arrow(): Renders an arrow pointing to a direction
|
gtk_render_frame_gap(): Renders a frame border with a gap on one side.
|
||||||
</member>
|
</member>
|
||||||
<member>
|
<member>
|
||||||
gtk_render_expander(): Renders an expander indicator, such as in #GtkExpander
|
gtk_render_layout(): Renders a #PangoLayout.
|
||||||
</member>
|
</member>
|
||||||
<member>
|
<member>
|
||||||
gtk_render_focus(): Renders the indication that a widget has the keyboard focus
|
gtk_render_handle(): Renders all kind of handles and resize grips,
|
||||||
|
depending on the style class.
|
||||||
</member>
|
</member>
|
||||||
<member>
|
<member>
|
||||||
gtk_render_line(): Renders a line from one coordinate to another.
|
gtk_render_check(): Render checkboxes.
|
||||||
</member>
|
</member>
|
||||||
<member>
|
<member>
|
||||||
gtk_render_slider(): Renders a slider indicator, such as in #GtkScale
|
gtk_render_option(): Render radiobuttons.
|
||||||
</member>
|
</member>
|
||||||
<member>
|
<member>
|
||||||
gtk_render_extension(): Renders and extension to an UI element, such as a
|
gtk_render_arrow(): Renders an arrow pointing to a direction.
|
||||||
notebook tab.
|
|
||||||
</member>
|
</member>
|
||||||
<member>
|
<member>
|
||||||
gtk_render_activity(): Renders an area displaying activity, be it a progressbar
|
gtk_render_expander(): Renders an expander indicator, such as in
|
||||||
or a spinner.
|
#GtkExpander.
|
||||||
</member>
|
</member>
|
||||||
<member>
|
<member>
|
||||||
gtk_render_icon_pixbuf(): Renders an icon into a #GdkPixbuf.
|
gtk_render_focus(): Renders the indication that a widget has the
|
||||||
|
keyboard focus.
|
||||||
|
</member>
|
||||||
|
<member>
|
||||||
|
gtk_render_line(): Renders a line from one coordinate to another.
|
||||||
|
</member>
|
||||||
|
<member>
|
||||||
|
gtk_render_slider(): Renders a slider, such as in #GtkScale.
|
||||||
|
</member>
|
||||||
|
<member>
|
||||||
|
gtk_render_extension(): Renders an extension that protrudes from
|
||||||
|
a UI element, such as a notebook tab.
|
||||||
|
</member>
|
||||||
|
<member>
|
||||||
|
gtk_render_activity(): Renders an area displaying activity, be it
|
||||||
|
a progressbar or a spinner.
|
||||||
|
</member>
|
||||||
|
<member>
|
||||||
|
gtk_render_icon_pixbuf(): Renders an icon into a #GdkPixbuf.
|
||||||
</member>
|
</member>
|
||||||
</simplelist>
|
</simplelist>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
One of the main differences to #GtkStyle engines is that the rendered widget is
|
One of the main differences to #GtkStyle-based engines is that the
|
||||||
totally isolated from the theme engine, all style information is meant to be
|
rendered widget is totally isolated from the theme engine, all style
|
||||||
retrieved from the #GtkThemingEngine API, or from the #GtkWidgetPath obtained
|
information is meant to be retrieved from the #GtkThemingEngine API,
|
||||||
from gtk_theming_engine_get_path(), which fully represents the rendered widget's
|
or from the #GtkWidgetPath obtained from gtk_theming_engine_get_path(),
|
||||||
hierarchy from a styling point of view.
|
which fully represents the rendered widget's hierarchy from a styling
|
||||||
|
point of view.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The detail string available in the old engines is now essentially replaced by
|
The detail string available in #GtkStyle-based engines has been
|
||||||
widget regions and CSS classes and widget regions. Regions are a way for
|
replaced by widget regions and style classes. Regions are a way for
|
||||||
container/complex widgets to classify and add ordering hints to its children.
|
complex widgets to associate different styles with different areas,
|
||||||
CSS classes identify are a way to label some content being rendered, both regions
|
such as even and odd rows in a treeview. Style classes allow sharing
|
||||||
and classes can be identified both in CSS files and theming engines. There are
|
of style information between widgets, regardless of their type.
|
||||||
several predefined classes and regions such as %GTK_STYLE_CLASS_BUTTON or
|
Regions and style classes can be used in style sheets to associate
|
||||||
%GTK_STYLE_REGION_TAB in gtkstylecontext.h, although custom widgets may define
|
styles, and them engines can also access them. There are several
|
||||||
their own, which themes may attempt at handling.
|
predefined classes and regions such as %GTK_STYLE_CLASS_BUTTON or
|
||||||
|
%GTK_STYLE_REGION_TAB in <filename>gtkstylecontext.h</filename>,
|
||||||
|
although custom widgets may define their own, which themes may
|
||||||
|
attempt to handle.
|
||||||
</para>
|
</para>
|
||||||
</refsect2>
|
</refsect2>
|
||||||
|
|
||||||
@ -130,25 +146,33 @@
|
|||||||
<title>Extending the CSS parser</title>
|
<title>Extending the CSS parser</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
If there is a need for extending the default CSS parser, #GtkRCStyle has been
|
In #GtkStyle-based engines, #GtkRCStyle provided ways to extend the
|
||||||
replaced by gtk_theming_engine_register_property(), where the theming engine
|
gtkrc parser with engine-specific extensions. This has been replaced
|
||||||
may register new properties that map to a #GType, even if there is builtin
|
by gtk_theming_engine_register_property(), which lets a theme engine
|
||||||
support for most basic types, it is possible to hook a custom parser for the
|
register new properties with an arbitrary type. While there is built-in
|
||||||
property.
|
support for most basic types, it is possible to use a custom parser
|
||||||
|
for the property.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The installed properties depend on the #GtkThemeEngine::name property, so they
|
The installed properties depend on the #GtkThemeEngine::name property,
|
||||||
should be added in the <literal>constructed()</literal> handler. For example,
|
so they should be added in the <literal>constructed()</literal> vfunc.
|
||||||
if an engine with the name "Clearlooks" installs a "focus-color" property, the
|
For example, if an engine with the name "Clearlooks" installs a
|
||||||
property <literal>-Clearlooks-focus-color</literal> will be registered and
|
"focus-color" property with the type #GdkRGBA, the property
|
||||||
accepted in CSS.
|
<literal>-Clearlooks-focus-color</literal> will be registered and
|
||||||
|
accepted in CSS like this:
|
||||||
|
<informalexample><programlisting>
|
||||||
|
GtkEntry {
|
||||||
|
-Clearlooks-focus-color: rgba(255, 0, 0, 1.0);
|
||||||
|
}
|
||||||
|
</programlisting></informalexample>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Widget style properties also follow a similar syntax, with the widget type
|
Widget style properties also follow a similar syntax, with the widget
|
||||||
name used as a prefix, so for example the #GtkWidget:focus-line-width style property
|
type name used as a prefix. For example, the #GtkWidget:focus-line-width
|
||||||
could be modified in CSS as <literal>-GtkWidget-focus-line-width</literal>.
|
style property can be modified in CSS as
|
||||||
|
<literal>-GtkWidget-focus-line-width</literal>.
|
||||||
</para>
|
</para>
|
||||||
</refsect2>
|
</refsect2>
|
||||||
|
|
||||||
@ -156,91 +180,95 @@
|
|||||||
<title>Using the CSS file format</title>
|
<title>Using the CSS file format</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The difference in syntax between the RC and CSS file formats is evident, it
|
The syntax of RC and CSS files formats is obviously different.
|
||||||
actually seems shorter to highlight the similarities, although anyone familiar
|
The CSS-like syntax will hopefully be much more familiar to many
|
||||||
with CSS3 should get an idea soon of the new format, to make a more or less
|
people, lowering the barrier for custom theming.
|
||||||
comprehensive example, the following RC data:
|
</para>
|
||||||
|
<para>
|
||||||
|
Instead of going through the syntax differences one-by-one, we
|
||||||
|
will present a more or less comprehensive example and discuss
|
||||||
|
how it can be translated into CSS:
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<example>
|
<example>
|
||||||
<title>Sample RC code</title>
|
<title>Sample RC code</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
style "default" {
|
style "default" {
|
||||||
xthickness = 1
|
xthickness = 1
|
||||||
ythickness = 1
|
ythickness = 1
|
||||||
|
|
||||||
GtkButton::child-displacement-x = 1
|
GtkButton::child-displacement-x = 1
|
||||||
GtkButton::child-displacement-y = 1
|
GtkButton::child-displacement-y = 1
|
||||||
GtkCheckButton::indicator-size = 14
|
GtkCheckButton::indicator-size = 14
|
||||||
|
|
||||||
bg[NORMAL] = @bg_color
|
bg[NORMAL] = @bg_color
|
||||||
bg[PRELIGHT] = shade (1.02, @bg_color)
|
bg[PRELIGHT] = shade (1.02, @bg_color)
|
||||||
bg[SELECTED] = @selected_bg_color
|
bg[SELECTED] = @selected_bg_color
|
||||||
bg[INSENSITIVE] = @bg_color
|
bg[INSENSITIVE] = @bg_color
|
||||||
bg[ACTIVE] = shade (0.9, @bg_color)
|
bg[ACTIVE] = shade (0.9, @bg_color)
|
||||||
|
|
||||||
fg[NORMAL] = @fg_color
|
fg[NORMAL] = @fg_color
|
||||||
fg[PRELIGHT] = @fg_color
|
fg[PRELIGHT] = @fg_color
|
||||||
fg[SELECTED] = @selected_fg_color
|
fg[SELECTED] = @selected_fg_color
|
||||||
fg[INSENSITIVE] = darker (@bg_color)
|
fg[INSENSITIVE] = darker (@bg_color)
|
||||||
fg[ACTIVE] = @fg_color
|
fg[ACTIVE] = @fg_color
|
||||||
|
|
||||||
text[NORMAL] = @text_color
|
text[NORMAL] = @text_color
|
||||||
text[PRELIGHT] = @text_color
|
text[PRELIGHT] = @text_color
|
||||||
text[SELECTED] = @selected_fg_color
|
text[SELECTED] = @selected_fg_color
|
||||||
text[INSENSITIVE] = darker (@bg_color)
|
text[INSENSITIVE] = darker (@bg_color)
|
||||||
text[ACTIVE] = @selected_fg_color
|
text[ACTIVE] = @selected_fg_color
|
||||||
|
|
||||||
base[NORMAL] = @base_color
|
base[NORMAL] = @base_color
|
||||||
base[PRELIGHT] = shade (0.95, @bg_color)
|
base[PRELIGHT] = shade (0.95, @bg_color)
|
||||||
base[SELECTED] = @selected_bg_color
|
base[SELECTED] = @selected_bg_color
|
||||||
base[INSENSITIVE] = @bg_color
|
base[INSENSITIVE] = @bg_color
|
||||||
base[ACTIVE] = shade (0.9, @selected_bg_color)
|
base[ACTIVE] = shade (0.9, @selected_bg_color)
|
||||||
|
|
||||||
engine "clearlooks" {
|
engine "clearlooks" {
|
||||||
colorize_scrollbar = TRUE
|
colorize_scrollbar = TRUE
|
||||||
style = CLASSIC
|
style = CLASSIC
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
style "tooltips" {
|
style "tooltips" {
|
||||||
xthickness = 4
|
xthickness = 4
|
||||||
ythickness = 4
|
ythickness = 4
|
||||||
|
|
||||||
bg[NORMAL] = @tooltip_bg_color
|
bg[NORMAL] = @tooltip_bg_color
|
||||||
fg[NORMAL] = @tooltip_fg_color
|
fg[NORMAL] = @tooltip_fg_color
|
||||||
}
|
}
|
||||||
|
|
||||||
style "button" {
|
style "button" {
|
||||||
xthickness = 3
|
xthickness = 3
|
||||||
ythickness = 3
|
ythickness = 3
|
||||||
|
|
||||||
bg[NORMAL] = shade (1.04, @bg_color)
|
bg[NORMAL] = shade (1.04, @bg_color)
|
||||||
bg[PRELIGHT] = shade (1.06, @bg_color)
|
bg[PRELIGHT] = shade (1.06, @bg_color)
|
||||||
bg[ACTIVE] = shade (0.85, @bg_color)
|
bg[ACTIVE] = shade (0.85, @bg_color)
|
||||||
}
|
}
|
||||||
|
|
||||||
style "entry" {
|
style "entry" {
|
||||||
xthickness = 3
|
xthickness = 3
|
||||||
ythickness = 3
|
ythickness = 3
|
||||||
|
|
||||||
bg[SELECTED] = mix (0.4, @selected_bg_color, @base_color)
|
bg[SELECTED] = mix (0.4, @selected_bg_color, @base_color)
|
||||||
fg[SELECTED] = @text_color
|
fg[SELECTED] = @text_color
|
||||||
|
|
||||||
engine "clearlooks" {
|
engine "clearlooks" {
|
||||||
focus_color = shade (0.65, @selected_bg_color)
|
focus_color = shade (0.65, @selected_bg_color)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
style "other" {
|
style "other" {
|
||||||
bg[NORMAL] = #fff;
|
bg[NORMAL] = #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
class "GtkWidget" style "default"
|
class "GtkWidget" style "default"
|
||||||
class "GtkEntry" style "entry"
|
class "GtkEntry" style "entry"
|
||||||
widget_class "*<GtkButton>" style "button"
|
widget_class "*<GtkButton>" style "button"
|
||||||
widget "gtk-tooltip*" style "tooltips"
|
widget "gtk-tooltip*" style "tooltips"
|
||||||
widget_class "window-name.*.GtkButton" style "other"
|
widget_class "window-name.*.GtkButton" style "other"
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</example>
|
</example>
|
||||||
|
|
||||||
@ -251,86 +279,87 @@
|
|||||||
<example>
|
<example>
|
||||||
<title>CSS translation</title>
|
<title>CSS translation</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
* {
|
* {
|
||||||
padding: 1;
|
padding: 1;
|
||||||
-GtkButton-child-displacement-x: 1;
|
-GtkButton-child-displacement-x: 1;
|
||||||
-GtkButton-child-displacement-y: 1;
|
-GtkButton-child-displacement-y: 1;
|
||||||
-GtkCheckButton-indicator-size: 14;
|
-GtkCheckButton-indicator-size: 14;
|
||||||
|
|
||||||
background-color: @bg_color;
|
background-color: @bg_color;
|
||||||
color: @fg_color;
|
color: @fg_color;
|
||||||
|
|
||||||
-Clearlooks-colorize-scrollbar: true;
|
-Clearlooks-colorize-scrollbar: true;
|
||||||
-Clearlooks-style: classic;
|
-Clearlooks-style: classic;
|
||||||
}
|
}
|
||||||
|
|
||||||
*:hover {
|
*:hover {
|
||||||
background-color: shade (@bg_color, 1.02);
|
background-color: shade (@bg_color, 1.02);
|
||||||
}
|
}
|
||||||
|
|
||||||
*:selected {
|
*:selected {
|
||||||
background-color: @selected_bg_color;
|
background-color: @selected_bg_color;
|
||||||
color: @selected_fg_color;
|
color: @selected_fg_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
*:insensitive {
|
*:insensitive {
|
||||||
color: shade (@bg_color, 0.7);
|
color: shade (@bg_color, 0.7);
|
||||||
}
|
}
|
||||||
|
|
||||||
*:active {
|
*:active {
|
||||||
background-color: shade (@bg_color, 0.9);
|
background-color: shade (@bg_color, 0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
.tooltip {
|
.tooltip {
|
||||||
padding: 4;
|
padding: 4;
|
||||||
|
|
||||||
background-color: @tooltip_bg_color;
|
background-color: @tooltip_bg_color;
|
||||||
color: @tooltip_fg_color;
|
color: @tooltip_fg_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
padding: 3;
|
padding: 3;
|
||||||
background-color: shade (@bg_color, 1.04);
|
background-color: shade (@bg_color, 1.04);
|
||||||
}
|
}
|
||||||
|
|
||||||
.button:hover {
|
.button:hover {
|
||||||
background-color: shade (@bg_color, 1.06);
|
background-color: shade (@bg_color, 1.06);
|
||||||
}
|
}
|
||||||
|
|
||||||
.button:active {
|
.button:active {
|
||||||
background-color: shade (@bg_color, 0.85);
|
background-color: shade (@bg_color, 0.85);
|
||||||
}
|
}
|
||||||
|
|
||||||
.entry {
|
.entry {
|
||||||
padding: 3;
|
padding: 3;
|
||||||
|
|
||||||
background-color: @base_color;
|
background-color: @base_color;
|
||||||
color: @text_color;
|
color: @text_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.entry:selected {
|
.entry:selected {
|
||||||
background-color: mix (@selected_bg_color, @base_color, 0.4);
|
background-color: mix (@selected_bg_color, @base_color, 0.4);
|
||||||
-Clearlooks-focus-color: shade (0.65, @selected_bg_color)
|
-Clearlooks-focus-color: shade (0.65, @selected_bg_color)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The latter selector is an specification of the first,
|
/* The latter selector is an specification of the first,
|
||||||
since any widget may use the same classes or names */
|
since any widget may use the same classes or names */
|
||||||
#window-name .button,
|
#window-name .button,
|
||||||
GtkWindow#window-name GtkButton.button {
|
GtkWindow#window-name GtkButton.button {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</example>
|
</example>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
One notable difference is the reduction from fg/bg/text/base colors to only
|
One notable difference is the reduction from fg/bg/text/base colors
|
||||||
foreground/background, in exchange the widget is able to render its various
|
to only foreground/background, in exchange the widget is able to render
|
||||||
elements with different CSS classes, so they would be themed independently.
|
its various elements with different CSS classes, which can be themed
|
||||||
|
independently.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
It is worth mentioning that the new file format doesn't support custom
|
It is worth mentioning that the new file format does not support
|
||||||
keybindings nor stock icon mappings as the RC format did.
|
custom keybindings nor stock icon mappings as the RC format did.
|
||||||
</para>
|
</para>
|
||||||
</refsect2>
|
</refsect2>
|
||||||
|
|
||||||
@ -338,120 +367,140 @@
|
|||||||
<title>A checklist for widgets</title>
|
<title>A checklist for widgets</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
When porting your widgets to use #GtkStyleContext, this is usually
|
When porting your widgets to use #GtkStyleContext, this checklist
|
||||||
the checklist to follow:
|
might be useful.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<orderedlist>
|
<orderedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
Replace <literal>style_set()</literal> calls with <literal>style_updated()</literal>.
|
Replace <literal>style_set()</literal> calls with
|
||||||
|
<literal>style_updated()</literal>.
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Try to identify the role of what you're rendering with any number of classes, this will
|
Try to identify the role of what you're rendering with any number
|
||||||
replace the detail string, there is a predefined set of CSS classes. Note that complex
|
of classes. This will replace the detail string. There is a predefined
|
||||||
widgets will probably need rendering different elements with different applying CSS
|
set of CSS classes which you can reuse where appropriate. Doing so
|
||||||
classes in order to have them styled separatedly. This could result in code like
|
will give you theming 'for free', whereas custom classes will require
|
||||||
(simplified examples):
|
extra work in the theme. Note that complex widgets are likely to
|
||||||
</para>
|
need different styles when rendering different parts, and style
|
||||||
|
classes are one way to achieve this. This could result in code like
|
||||||
|
the following (simplified) examples:
|
||||||
|
</para>
|
||||||
|
|
||||||
<example>
|
<example>
|
||||||
<title>Setting a permanent CSS class</title>
|
<title>Setting a permanent CSS class</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
static void
|
static void
|
||||||
gtk_button_init (GtkButton *button)
|
gtk_button_init (GtkButton *button)
|
||||||
{
|
{
|
||||||
GtkStyleContext *context;
|
GtkStyleContext *context;
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
context = gtk_widget_get_style_context (GTK_WIDGET (button));
|
context = gtk_widget_get_style_context (GTK_WIDGET (button));
|
||||||
|
|
||||||
/* Set the "button" class */
|
/* Set the "button" class */
|
||||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_BUTTON);
|
gtk_style_context_add_class (context, GTK_STYLE_CLASS_BUTTON);
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</example>
|
</example>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Or
|
Or
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<example>
|
<example>
|
||||||
<title>Using dynamic CSS classes for different elements</title>
|
<title>Using dynamic CSS classes for different elements</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
static gboolean
|
static gboolean
|
||||||
gtk_spin_button_draw (GtkSpinButton *spin,
|
gtk_spin_button_draw (GtkSpinButton *spin,
|
||||||
cairo_t *cr)
|
cairo_t *cr)
|
||||||
{
|
{
|
||||||
GtkStyleContext *context;
|
GtkStyleContext *context;
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
context = gtk_widget_get_style_context (GTK_WIDGET (spin));
|
context = gtk_widget_get_style_context (GTK_WIDGET (spin));
|
||||||
|
|
||||||
gtk_style_context_save (context);
|
gtk_style_context_save (context);
|
||||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_ENTRY);
|
gtk_style_context_add_class (context, GTK_STYLE_CLASS_ENTRY);
|
||||||
|
|
||||||
/* Call to entry draw impl with "entry" class */
|
/* Call to entry draw impl with "entry" class */
|
||||||
parent_class->draw (spin, cr);
|
parent_class->draw (spin, cr);
|
||||||
|
|
||||||
gtk_style_context_restore (context);
|
gtk_style_context_restore (context);
|
||||||
gtk_style_context_save (context);
|
gtk_style_context_save (context);
|
||||||
|
|
||||||
/* Render up/down buttons with the "button" class */
|
/* Render up/down buttons with the "button" class */
|
||||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_BUTTON);
|
gtk_style_context_add_class (context, GTK_STYLE_CLASS_BUTTON);
|
||||||
draw_up_button (spin, cr);
|
draw_up_button (spin, cr);
|
||||||
draw_down_button (spin, cr);
|
draw_down_button (spin, cr);
|
||||||
|
|
||||||
gtk_style_context_restore (context);
|
gtk_style_context_restore (context);
|
||||||
|
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</example>
|
</example>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Note that #GtkStyleContext only provides fg/bg colors, so text/base is done through
|
Note that #GtkStyleContext only provides fg/bg colors, so text/base
|
||||||
distinctive theming of the different classes. For example, An entry would usually
|
is done through distinctive theming of the different classes. For
|
||||||
be black on white while a button would usually be black on light grey.
|
example, an entry would usually be black on white while a button
|
||||||
</para>
|
would usually be black on light grey.
|
||||||
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
Replace all <literal>gtk_paint_*()</literal> calls to use <literal>gtk_render_*()</literal>,
|
Replace all <literal>gtk_paint_*()</literal> calls with corresponding
|
||||||
the most distinctive changes are the use of #GtkStateFlags to represent the widget state and
|
<literal>gtk_render_*()</literal> calls. The most distinctive changes
|
||||||
the lack of #GtkShadowType. For gtk_render_check() and gtk_render_option(), the
|
are the use of #GtkStateFlags to represent the widget state and the
|
||||||
<literal>shadow_type</literal> parameter is replaced by the #GTK_STATE_FLAG_ACTIVE and
|
lack of #GtkShadowType. For gtk_render_check() and gtk_render_option(),
|
||||||
#GTK_STATE_FLAG_INCONSISTENT state flags. For things such as pressed/unpressed button states,
|
the @shadow_type parameter is replaced by the #GTK_STATE_FLAG_ACTIVE
|
||||||
#GTK_STATE_FLAG_ACTIVE is used, so the CSS may style normal/active states differently to render
|
and #GTK_STATE_FLAG_INCONSISTENT state flags. For things such as
|
||||||
outset/inset borders respectively.
|
pressed/unpressed button states, #GTK_STATE_FLAG_ACTIVE is used, and
|
||||||
|
the CSS may style normal/active states differently to render
|
||||||
|
outset/inset borders, respectively.
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
Replace all uses of xthickness/ythickness, #GtkStyleContext uses the CSS box model, so
|
The various <literal>gtk_widget_modify_*()</literal> functions to
|
||||||
there is the border-width/padding/margin properties to replace the different applications
|
override colors or fonts for individual widgets have been replaced
|
||||||
of X and Y thickness. Note that all of this is merely a guideline to use, which widgets
|
by similar <literal>gtk_widget_override_*()</literal> functions.
|
||||||
may choose to obey or not.
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
It is no longer necessary to call gtk_widget_style_attach(),
|
||||||
|
gtk_style_attach(), gtk_style_detach() or gtk_widget_ensure_style().
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
Replace all uses of xthickness/ythickness. #GtkStyleContext uses the
|
||||||
|
CSS box model, and there are border-width/padding/margin properties to
|
||||||
|
replace the different applications of X and Y thickness. Note that all
|
||||||
|
of this is merely a guideline. Widgets may choose to follow it or not.
|
||||||
</listitem>
|
</listitem>
|
||||||
</orderedlist>
|
</orderedlist>
|
||||||
</refsect2>
|
</refsect2>
|
||||||
|
|
||||||
<refsect2 id="gtk-migrating-GtkStyleContext-parsing">
|
<refsect2 id="gtk-migrating-GtkStyleContext-parsing">
|
||||||
<title>Parsing from custom resources</title>
|
<title>Parsing of custom resources</title>
|
||||||
<para>
|
<para>
|
||||||
As a consequence of the RC format going away, calling gtk_rc_parse() or gtk_rc_parse_string()
|
As a consequence of the RC format going away, calling gtk_rc_parse() or
|
||||||
won't be doing anything to the widget styling, the way to replace these calls is using the CSS
|
gtk_rc_parse_string() won't have any effect on a widgets appearance.
|
||||||
format, which is loaded through a #GtkCssProvider, and inserted as a style resource to an
|
The way to replace these calls is using a custom #GtkStyleProvider,
|
||||||
individual widget through gtk_style_context_add_provider() or to all widgets in a screen through
|
either for an individual widget through gtk_style_context_add_provider()
|
||||||
gtk_style_context_add_provider_for_screen().
|
or for all widgets on a screen through gtk_style_context_add_provider_for_screen().
|
||||||
|
Typically, the provider will be a #GtkCssProvider, which parse CSS
|
||||||
|
information from a file or from a string.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Notice that you can also get style information from custom resources by implementing a
|
Notice that you can also get style information from custom resources
|
||||||
#GtkStyleProvider, where it would be translated to something the widget understands. Although
|
by implementing the #GtkStyleProvider interface yourself. This is
|
||||||
this is an advanced feature that should be rarely used.
|
an advanced feature that should be rarely used.
|
||||||
</para>
|
</para>
|
||||||
</refsect2>
|
</refsect2>
|
||||||
|
|
||||||
@ -459,83 +508,91 @@
|
|||||||
<title>Bonus points</title>
|
<title>Bonus points</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
There are some features in #GtkStyleContext that weren't available in
|
There are some features in #GtkStyleContext that were not available in
|
||||||
#GtkStyle, or were made available over time for certain widgets through
|
#GtkStyle, or were made available over time for certain widgets through
|
||||||
extending the detail string in obscure ways. UI elements being rendered
|
extending the detail string in obscure ways. There is a lot more
|
||||||
may be provided now a lot more information, so going through this list
|
information available when rendering UI elements, and it is accessible
|
||||||
you'll ensure your widget is the perfect citizen in a fully themable UI
|
in more uniform, less hacky ways. By going through this list you'll
|
||||||
|
ensure your widget is a good citizen in a fully themable user interface.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<orderedlist>
|
<orderedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
If your widget renders a series of similar elements, such as tabs
|
If your widget renders a series of similar elements, such as tabs
|
||||||
in a #GtkNotebook or rows/column in a #GtkTreeView, consider adding
|
in a #GtkNotebook or rows/column in a #GtkTreeView, consider adding
|
||||||
regions through gtk_style_context_add_region(), these regions can be
|
regions through gtk_style_context_add_region(). These regions can be
|
||||||
referenced in CSS and the :nth-child pseudoclass may be used to match
|
referenced in CSS and the :nth-child pseudo-class may be used to match
|
||||||
the elements depending on the flags passed.
|
the elements depending on the flags passed.
|
||||||
|
|
||||||
<example>
|
<example>
|
||||||
<title>Theming widget regions</title>
|
<title>Theming widget regions</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
GtkNotebook tab {
|
GtkNotebook tab {
|
||||||
background-color: #f3329d;
|
background-color: #f3329d;
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkTreeView row::nth-child (even) {
|
GtkTreeView row::nth-child (even) {
|
||||||
background-color: #dddddd;
|
background-color: #dddddd;
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</example>
|
</example>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
If your container renders child widgets within different regions, make it implement
|
If your container renders child widgets within different regions,
|
||||||
<literal>GtkContainer::get_path_for_child()</literal>, This function lets containers
|
make it implement GtkContainer::get_path_for_child(). This function
|
||||||
assign special #GtkWidgetPath<!-- -->s to child widgets depending on its role/region,
|
lets containers assign a special #GtkWidgetPath to child widgets
|
||||||
this is necessary to extend the concept above throughout the widget hierarchy.
|
depending on their role/region. This is necessary to extend the
|
||||||
</para>
|
concept above throughout the widget hierarchy.
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
For example, a #GtkNotebook would modify the tab labels' #GtkWidgetPath so the
|
For example, a #GtkNotebook modifies the tab labels' #GtkWidgetPath
|
||||||
"tab" region is added, doing this so would allow the tab label to be themed through:
|
so the "tab" region is added. This makes it possible to theme tab
|
||||||
</para>
|
labels through:
|
||||||
|
</para>
|
||||||
|
|
||||||
<example>
|
<example>
|
||||||
<title>Theming a widget within a parent container region</title>
|
<title>Theming a widget within a parent container region</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
GtkNotebook tab GtkLabel {
|
GtkNotebook tab GtkLabel {
|
||||||
font: Sans 8;
|
font: Sans 8;
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</example>
|
</example>
|
||||||
|
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
If you intend several visual elements to look interconnected, make sure you specify
|
If you intend several visual elements to look interconnected,
|
||||||
rendered elements' connection areas through gtk_style_context_set_junction_sides()
|
make sure you specify rendered elements' connection areas with
|
||||||
|
gtk_style_context_set_junction_sides(). It is of course up to the
|
||||||
|
theme to make use of this information or not.
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
#GtkStyleContext supports implicit animations on state changes for the most simple
|
#GtkStyleContext supports implicit animations on state changes for
|
||||||
cases, widgets with one single animatable area, which are changed state through
|
the most simple case out-of-the-box: widgets with a single animatable
|
||||||
gtk_widget_set_state_flags() or gtk_widget_unset_state_flags(). These functions
|
area, whose state is changed with gtk_widget_set_state_flags() or
|
||||||
trigger the animations for the affected state flags.
|
gtk_widget_unset_state_flags(). These functions trigger animated
|
||||||
</para>
|
transitions for the affected state flags. Examples of widgets for
|
||||||
<para>
|
which this kind of animation may be sufficient are #GtkButton or
|
||||||
If your widget consists of more than a simple area (such as buttons or entries),
|
#GtkEntry.
|
||||||
and these different areas may be rendered with different states, make sure to
|
</para>
|
||||||
mark the rendered areas through gtk_style_context_push_animatable_region() and
|
<para>
|
||||||
gtk_style_context_pop_animatable_region().
|
If your widget consists of more than a simple area, and these areas
|
||||||
</para>
|
may be rendered with different states, make sure to mark the rendered
|
||||||
|
areas with gtk_style_context_push_animatable_region() and
|
||||||
|
gtk_style_context_pop_animatable_region().
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
gtk_style_context_notify_state_change() may be used to trigger a transition for
|
gtk_style_context_notify_state_change() may be used to trigger a
|
||||||
a given state, the region ID will determine the animatable region that becomes
|
transition for a given state. The region ID will determine the
|
||||||
affected by this transition.
|
animatable region that is affected by this transition.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</orderedlist>
|
</orderedlist>
|
||||||
</refsect2>
|
</refsect2>
|
||||||
|
|||||||
Reference in New Issue
Block a user