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