[gtk+/gtk-style-context: 490/540] Some tweaks for the GtkStyleContext migration guide



commit be986fe92a8293d65f288910b7639eed11d24997
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed Nov 24 01:01:31 2010 -0500

    Some tweaks for the GtkStyleContext migration guide

 docs/reference/gtk/migrating-GtkStyleContext.xml |  815 ++++++++++++----------
 1 files changed, 436 insertions(+), 379 deletions(-)
---
diff --git a/docs/reference/gtk/migrating-GtkStyleContext.xml b/docs/reference/gtk/migrating-GtkStyleContext.xml
index 886343d..b366e65 100644
--- a/docs/reference/gtk/migrating-GtkStyleContext.xml
+++ b/docs/reference/gtk/migrating-GtkStyleContext.xml
@@ -6,25 +6,26 @@
   <title>Migrating from GtkStyle to GtkStyleContext</title>
 
   <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
     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.
   </para>
 
   <refsect2 id="gtk-migrating-GtkStyleContext-themes">
     <title>Migrating themes</title>
 
     <para>
-      From GTK+ 3.0 on, theme engines must implement #GtkThemingEngine and be installed
-      in <literal>$(libdir)/gtk+-3.0/$(GTK_VERSION)/theming-engines</literal>, 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 <literal>$(sharedir)/themes/Clearlooks/gtk-3.0/gtk.css</literal>,
-      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 <filename>$libdir/gtk+-3.0/$GTK_VERSION/theming-engines</filename>,
+      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
+      <filename>$datadir/themes/Clearlooks/gtk-3.0/gtk.css</filename>,
+      with possible variants such as the dark theme being named
+      <filename>gtk-dark.css</filename> in the same directory.
     </para>
   </refsect2>
 
@@ -32,97 +33,112 @@
     <title>Migrating theme engines</title>
 
     <para>
-      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:
     </para>
 
     <orderedlist>
       <listitem>
-	All variations of <literal>gtk_paint_box()</literal>, <literal>gtk_paint_flat_box()</literal>,
-	<literal>gtk_paint_shadow()</literal>, <literal>gtk_paint_box_gap()</literal> and
-	<literal>gtk_paint_shadow_gap()</literal> 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.
       </listitem>
       <listitem>
-	<literal>gtk_paint_resize_grip()</literal> 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.
       </listitem>
       <listitem>
-	<literal>gtk_paint_spinner()</literal> 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.
       </listitem>
     </orderedlist>
 
     <para>
-      The available list of render methods is:
+      The list of available render methods is:
     </para>
 
     <simplelist>
-      <member>gtk_render_background(): Renders a widget/area background.</member>
       <member>
-	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_background(): Renders a widget/area background.
       </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.
+        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.
       </member>
       <member>
-	gtk_render_check() and gtk_render_option(): Respectively render checkboxes and
-	radiobuttons.
+        gtk_render_frame_gap(): Renders a frame border with a gap on one side.
       </member>
       <member>
-	gtk_render_arrow(): Renders an arrow pointing to a direction
+        gtk_render_layout(): Renders a #PangoLayout.
       </member>
       <member>
-	gtk_render_expander(): Renders an expander indicator, such as in #GtkExpander
+        gtk_render_handle(): Renders all kind of handles and resize grips,
+        depending on the style class.
       </member>
       <member>
-	gtk_render_focus(): Renders the indication that a widget has the keyboard focus
+        gtk_render_check(): Render checkboxes.
       </member>
       <member>
-	gtk_render_line(): Renders a line from one coordinate to another.
+        gtk_render_option(): Render radiobuttons.
       </member>
       <member>
-	gtk_render_slider(): Renders a slider indicator, such as in #GtkScale
+        gtk_render_arrow(): Renders an arrow pointing to a direction.
       </member>
       <member>
-	gtk_render_extension(): Renders and extension to an UI element, such as a
-	notebook tab.
+        gtk_render_expander(): Renders an expander indicator, such as in
+        #GtkExpander.
       </member>
       <member>
-	gtk_render_activity(): Renders an area displaying activity, be it a progressbar
-	or a spinner.
+        gtk_render_focus(): Renders the indication that a widget has the
+        keyboard focus.
       </member>
       <member>
-	gtk_render_icon_pixbuf(): Renders an icon into a #GdkPixbuf.
+        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>
     </simplelist>
 
     <para>
-      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.
     </para>
 
     <para>
-      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 <filename>gtkstylecontext.h</filename>,
+      although custom widgets may define their own, which themes may
+      attempt to handle.
     </para>
   </refsect2>
 
@@ -130,25 +146,33 @@
     <title>Extending the CSS parser</title>
 
     <para>
-      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.
     </para>
 
     <para>
-      The installed properties depend on the #GtkThemeEngine::name property, so they
-      should be added in the <literal>constructed()</literal> handler. For example,
-      if an engine with the name "Clearlooks" installs a "focus-color" property, the
-      property <literal>-Clearlooks-focus-color</literal> will be registered and
-      accepted in CSS.
+      The installed properties depend on the #GtkThemeEngine::name property,
+      so they should be added in the <literal>constructed()</literal> vfunc.
+      For example, if an engine with the name "Clearlooks" installs a
+      "focus-color" property with the type #GdkRGBA, the property
+      <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>
-      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 <literal>-GtkWidget-focus-line-width</literal>.
+      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
+      <literal>-GtkWidget-focus-line-width</literal>.
     </para>
   </refsect2>
 
@@ -156,91 +180,95 @@
     <title>Using the CSS file format</title>
 
     <para>
-      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.
+    </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>
 
     <example>
       <title>Sample RC code</title>
       <programlisting>
-	style "default" {
-		xthickness = 1
-		ythickness = 1
-
-		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)
-
-		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
-
-		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
-		}
-	}
-
-	style "tooltips" {
-		xthickness = 4
-		ythickness = 4
-
-		bg[NORMAL]        = @tooltip_bg_color
-		fg[NORMAL]        = @tooltip_fg_color
-	}
-
-	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)
-	}
-
-	style "entry" {
-		xthickness = 3
-		ythickness = 3
-
-		bg[SELECTED] = mix (0.4, @selected_bg_color, @base_color)
-		fg[SELECTED] = @text_color
-
-		engine "clearlooks" {
-			focus_color = shade (0.65, @selected_bg_color)
-		}
-	}
-
-	style "other" {
-		bg[NORMAL] = &num;fff;
-	}
-
-	class "GtkWidget" style "default"
-	class "GtkEntry" style "entry"
-	widget_class "*&lt;GtkButton&gt;" style "button"
-	widget "gtk-tooltip*" style "tooltips"
-	widget_class "window-name.*.GtkButton" style "other"
+        style "default" {
+                xthickness = 1
+                ythickness = 1
+
+                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)
+
+                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
+
+                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
+                }
+        }
+
+        style "tooltips" {
+                xthickness = 4
+                ythickness = 4
+
+                bg[NORMAL]        = @tooltip_bg_color
+                fg[NORMAL]        = @tooltip_fg_color
+        }
+
+        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)
+        }
+
+        style "entry" {
+                xthickness = 3
+                ythickness = 3
+
+                bg[SELECTED] = mix (0.4, @selected_bg_color, @base_color)
+                fg[SELECTED] = @text_color
+
+                engine "clearlooks" {
+                        focus_color = shade (0.65, @selected_bg_color)
+                }
+        }
+
+        style "other" {
+                bg[NORMAL] = &num;fff;
+        }
+
+        class "GtkWidget" style "default"
+        class "GtkEntry" style "entry"
+        widget_class "*&lt;GtkButton&gt;" style "button"
+        widget "gtk-tooltip*" style "tooltips"
+        widget_class "window-name.*.GtkButton" style "other"
       </programlisting>
     </example>
 
@@ -251,86 +279,87 @@
     <example>
       <title>CSS translation</title>
       <programlisting>
-	* {
-	  padding: 1;
-	  -GtkButton-child-displacement-x: 1;
-	  -GtkButton-child-displacement-y: 1;
-	  -GtkCheckButton-indicator-size: 14;
-
-	  background-color: @bg_color;
-	  color: @fg_color;
-
-	  -Clearlooks-colorize-scrollbar: true;
-	  -Clearlooks-style: classic;
-	}
-
-	*:hover {
-	  background-color: shade (@bg_color, 1.02);
-	}
-
-	*:selected {
-	  background-color: @selected_bg_color;
-	  color: @selected_fg_color;
-	}
-
-	*:insensitive {
-	  color: shade (@bg_color, 0.7);
-	}
-
-	*:active {
-	  background-color: shade (@bg_color, 0.9);
-	}
-
-	.tooltip {
-	  padding: 4;
-
-	  background-color: @tooltip_bg_color;
-	  color: @tooltip_fg_color;
-	}
-
-	.button {
-	  padding: 3;
-	  background-color: shade (@bg_color, 1.04);
-	}
-
-	.button:hover {
-	  background-color: shade (@bg_color, 1.06);
-	}
-
-	.button:active {
-	  background-color: shade (@bg_color, 0.85);
-	}
-
-	.entry {
-	  padding: 3;
-
-	  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)
-	}
-
-	/* The latter selector is an specification of the first,
-	   since any widget may use the same classes or names */
-	&num;window-name .button,
-	GtkWindow&num;window-name GtkButton.button {
-	  background-color: &num;fff;
-	}
+        * {
+          padding: 1;
+          -GtkButton-child-displacement-x: 1;
+          -GtkButton-child-displacement-y: 1;
+          -GtkCheckButton-indicator-size: 14;
+
+          background-color: @bg_color;
+          color: @fg_color;
+
+          -Clearlooks-colorize-scrollbar: true;
+          -Clearlooks-style: classic;
+        }
+
+        *:hover {
+          background-color: shade (@bg_color, 1.02);
+        }
+
+        *:selected {
+          background-color: @selected_bg_color;
+          color: @selected_fg_color;
+        }
+
+        *:insensitive {
+          color: shade (@bg_color, 0.7);
+        }
+
+        *:active {
+          background-color: shade (@bg_color, 0.9);
+        }
+
+        .tooltip {
+          padding: 4;
+
+          background-color: @tooltip_bg_color;
+          color: @tooltip_fg_color;
+        }
+
+        .button {
+          padding: 3;
+          background-color: shade (@bg_color, 1.04);
+        }
+
+        .button:hover {
+          background-color: shade (@bg_color, 1.06);
+        }
+
+        .button:active {
+          background-color: shade (@bg_color, 0.85);
+        }
+
+        .entry {
+          padding: 3;
+
+          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)
+        }
+
+        /* The latter selector is an specification of the first,
+           since any widget may use the same classes or names */
+        &num;window-name .button,
+        GtkWindow&num;window-name GtkButton.button {
+          background-color: &num;fff;
+        }
       </programlisting>
     </example>
 
     <para>
-      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.
     </para>
 
     <para>
-      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.
     </para>
   </refsect2>
 
@@ -338,120 +367,140 @@
     <title>A checklist for widgets</title>
 
     <para>
-      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.
     </para>
 
     <orderedlist>
       <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>
+        <para>
+          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:
+        </para>
+
+        <example>
+          <title>Setting a permanent CSS class</title>
+          <programlisting>
+            static void
+            gtk_button_init (GtkButton *button)
+            {
+              GtkStyleContext *context;
+
+              ...
+
+              context = gtk_widget_get_style_context (GTK_WIDGET (button));
+
+              /* Set the "button" class */
+              gtk_style_context_add_class (context, GTK_STYLE_CLASS_BUTTON);
+            }
+          </programlisting>
+        </example>
+
+        <para>
+          Or
+        </para>
+
+        <example>
+          <title>Using dynamic CSS classes for different elements</title>
+          <programlisting>
+            static gboolean
+            gtk_spin_button_draw (GtkSpinButton *spin,
+                                  cairo_t       *cr)
+            {
+              GtkStyleContext *context;
+
+              ...
+
+              context = gtk_widget_get_style_context (GTK_WIDGET (spin));
+
+              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);
+
+              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);
+
+              gtk_style_context_restore (context);
+
+              ...
+            }
+          </programlisting>
+        </example>
+
+        <para>
+          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.
+        </para>
+      </listitem>
+
+      <listitem>
+        Replace all <literal>gtk_paint_*()</literal> calls with corresponding
+        <literal>gtk_render_*()</literal> 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.
       </listitem>
 
       <listitem>
-	<para>
-	  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):
-	</para>
-
-	<example>
-	  <title>Setting a permanent CSS class</title>
-	  <programlisting>
-	    static void
-	    gtk_button_init (GtkButton *button)
-	    {
-	      GtkStyleContext *context;
-
-	      ...
-
-	      context = gtk_widget_get_style_context (GTK_WIDGET (button));
-
-	      /* Set the "button" class */
-	      gtk_style_context_add_class (context, GTK_STYLE_CLASS_BUTTON);
-	    }
-	  </programlisting>
-	</example>
-
-	<para>
-	  Or
-	</para>
-
-	<example>
-	  <title>Using dynamic CSS classes for different elements</title>
-	  <programlisting>
-	    static gboolean
-	    gtk_spin_button_draw (GtkSpinButton *spin,
-	                          cairo_t       *cr)
-	    {
-	      GtkStyleContext *context;
-
-	      ...
-
-	      context = gtk_widget_get_style_context (GTK_WIDGET (spin));
-
-	      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);
-
-	      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);
-
-	      gtk_style_context_restore (context);
-
-	      ...
-	    }
-	  </programlisting>
-	</example>
-
-	<para>
-	  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.
-	</para>
+        The various <literal>gtk_widget_modify_*()</literal> functions to
+        override colors or fonts for individual widgets have been replaced
+        by similar <literal>gtk_widget_override_*()</literal> functions.
       </listitem>
 
       <listitem>
-	Replace all <literal>gtk_paint_*()</literal> calls to use <literal>gtk_render_*()</literal>,
-	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
-	<literal>shadow_type</literal> 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.
+        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, 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.
+        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>
     </orderedlist>
   </refsect2>
 
   <refsect2 id="gtk-migrating-GtkStyleContext-parsing">
-    <title>Parsing from custom resources</title>
+    <title>Parsing of custom resources</title>
     <para>
-      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.
     </para>
 
     <para>
-      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.
     </para>
   </refsect2>
 
@@ -459,83 +508,91 @@
     <title>Bonus points</title>
 
     <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
-      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.
     </para>
 
     <orderedlist>
       <listitem>
-	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.
-
-	<example>
-	  <title>Theming widget regions</title>
-	  <programlisting>
-	    GtkNotebook tab {
-	      background-color: &num;f3329d;
-	    }
-
-	    GtkTreeView row::nth-child (even) {
-	      background-color: &num;dddddd;
-	    }
-	  </programlisting>
-	</example>
+        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.
+
+        <example>
+          <title>Theming widget regions</title>
+          <programlisting>
+            GtkNotebook tab {
+              background-color: &num;f3329d;
+            }
+
+            GtkTreeView row::nth-child (even) {
+              background-color: &num;dddddd;
+            }
+          </programlisting>
+        </example>
       </listitem>
 
       <listitem>
-	<para>
-	  If your container renders child widgets within different regions, make it implement
-	  <literal>GtkContainer::get_path_for_child()</literal>, This function lets containers
-	  assign special #GtkWidgetPath<!-- -->s to child widgets depending on its role/region,
-	  this is necessary to extend the concept above throughout the widget hierarchy.
-	</para>
-
-	<para>
-	  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:
-	</para>
-
-	<example>
-	  <title>Theming a widget within a parent container region</title>
-	  <programlisting>
-	    GtkNotebook tab GtkLabel {
-	      font: Sans 8;
-	    }
-	  </programlisting>
-	</example>
+        <para>
+          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.
+        </para>
+
+        <para>
+          For example, a #GtkNotebook modifies the tab labels' #GtkWidgetPath
+          so the "tab" region is added. This makes it possible to theme tab
+          labels through:
+        </para>
+
+        <example>
+          <title>Theming a widget within a parent container region</title>
+          <programlisting>
+            GtkNotebook tab GtkLabel {
+              font: Sans 8;
+            }
+          </programlisting>
+        </example>
 
       </listitem>
 
       <listitem>
-	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.
       </listitem>
 
       <listitem>
-	<para>
-	  #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.
-	</para>
-	<para>
-	  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().
-	</para>
-
-	<para>
-	  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.
-	</para>
+        <para>
+          #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.
+        </para>
+        <para>
+          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().
+        </para>
+
+        <para>
+          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.
+        </para>
       </listitem>
     </orderedlist>
   </refsect2>



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