Gradient colors

Color gradients are allowed only for colors that are used as background colors of widgets. A background color gradient is a color that that transitions across its widget.

LibCXXW's gradient colors are directly implemented using the RENDER extension's CreateLinearGradient and CreateRadialGradient requests. LibCXXW forms the RENDER request by translating and computing its values from a virtualized representation; from virtual coordinates. The following is a brief summary of the XML format that forms each request, and a brief description, see the RENDER specification for more information.

<color id="bgcolor" type="linear_gradient">
  <x1>0</x1>
  <y1>0</y1>
  <x2>0</x2>
  <y2>1</y2>

  <gradient>
    <value>0</value>
    <color>gray</color>
  </gradient>
  <gradient>
    <value>1</value>
    <color>silver</color>
  </gradient>
  <gradient>
    <value>2</value>
    <color>white</color>
  </gradient>
</color>

<!-- ... -->

<layout type="grid" id="main-window-grid">

  <background_color>
    <color>bgcolor</color>
  </background_color>

  <!-- ... -->
</layout>

Gradient colors contain two or more gradients. values are non-negative integers, one of the values must be 0, and all values must be unique. The highest value sets the gradient's range, and each gradient specifies a color that references another plain color.

A linear_gradient type defines a gradient with a linear color transition to each color across a range of 0 to the maximum value. This is the same as setting x::w::color_arg from an x::w::linear_gradient. The above example creates a gradient that starts with the gray color, becomes a silver color at exactly the midpoint, and reaches the white color at the end. Using values of 0, 3, 4 results in a linear gradient that transitions to the 3 color at about 75% of the way from the starting to the ending color value.

The gradient colors transition over virtual coordinates of (x1, y1) through (x2, y2). The coordinate (0, 0) is the upper-left corner of the widget. (1, 1) is the bottom-right corner. Specifying x1, y1, x2, and y2 is optional; and they default to (0, 0) and (1, 1); by default, a linear gradient transition from the upper-left corner to the bottom-right corner.

<color id="bgcolor" type="linear_gradient">
  <widthmm>10</widthmm>
  <heightmm>10</heightmm>

  <!-- .... -->

</color>

The virtual gradient range of (0, 0) to (1, 1) gets automatically scaled to the widget's size, so that (0, 0) is always the top-left corner, and (1, 1) is always the widget's bottom-right corner. Specifying widthmm, heightmm sets a fixed width or height, specified in millimeters, that gets used to compute the virtual gradient positions, instead of automatically adjusting them to the widget's actual size. This example creates a gradient for a size of 10x10 millimeters; (0, 0) is still the top-left corner and (1, 1) is 10 millimeters below and to the right of it. If the widget is larger, the additional space gets filled with the closest color from the computed gradient; a smaller widget results in a clipped gradient.

A negative widthmm or heightmm value anchors the gradient coordinates to the opposite border. A widthmm and heightmm of -10 results in a 10x10 millimeter gradient that's anchored at the widget's bottom-right corner.

<color  id="bgcolor" type="radial_gradient">
  <inner_x>.5</inner_x>
  <inner_y>.5</inner_y>
  <outer_x>.5</outer_x>
  <outer_y>.5</outer_y>
  <inner_radius>0</inner_radius>
  <outer_radius>.5</outer_radius>
  <inner_radius_axis>shortest</inner_radius_axis>
  <outer_radius_axis>longest</outer_radius_axis>

  <gradient>
    <value>0</value>
    <color>gray</color>
  </gradient>
  <gradient>
    <value>1</value>
    <color>white</color>
  </gradient>
</color>

A radial_gradient type also defines a gradient from a values of 0 to the maximum value. The radial gradiant also gets defined in a virtual coordinate range (0, 0) to (1, 1), and also based on two coordinates in the range, which are specified as (inner_x, inner_y) and (outer_x, outer_y).

inner_radius defines a circle whose center is (inner_x, inner_y) and outer_radius defines a circle whose center is (outer_x, outer_y). The actual radius value of 1 is defined by inner_radius_axis and outer_radius_axis, respectively. This is the same as setting x::w::color_arg from an x::w::radial_gradient.

The above example shows the default values for all these settings, if not specified.

The inner circle must be contained entirely within the outer circle. The color value of 0 forms the area inside the inner circle, and the color gradient transition accordingly, to the maximum color value that forms the area outside the outer circle.

Optional widthmm and heightmm values work the same way for radial gradient as they do for linear gradients.