Skip to content
This is the documentation for xc 0.66. The current documentation describes the newest version.

UXColor

UXColor is an RGBA colour with four channels, 0..255, using integers throughout. Like the rest of the toolkit’s arithmetic, this makes every backend produce identical pixels.

#use <UXKit> // or #import "UXColor.xc"
UXColor* brand = UXColor.fromHex($3050A0); // rgb(48,80,160)
UXColor* red = UXColor.red();
UXColor* ghost = brand.withAlpha(96);

Every operation returns a new colour; none mutates the receiver. A colour you pass to a view cannot be changed underneath it by another holder, and you can derive colours without defensive copies:

UXColor* ghost = brand.withAlpha(96);
// brand is still rgb(48,80,160) a=255

Channels are clamped on construction, so arithmetic that overshoots saturates instead of wrapping: lightened on an almost-white colour gives white, not black.

rgb · rgba · fromHex · fromHexA · toHex · hsb · toHSB · blend · lightened · darkened · withAlpha · luminance · isDark · isEqualTo · named colours

static UXColor* rgb(i32 r, i32 g, i32 b)

Opaque colour from three channels. Values outside 0..255 are clamped.

static UXColor* rgba(i32 r, i32 g, i32 b, i32 a)

With alpha. a is 255 for opaque, 0 for invisible.

static UXColor* fromHex(u32 hex) // 0xRRGGBB, opaque
UXColor* brand = UXColor.fromHex($3050A0);
static UXColor* fromHexA(u32 hex) // 0xAARRGGBB

Alpha is in the high byte, the order a packed colour word usually arrives in.

u32 toHex(void) // 0xRRGGBB

Drops alpha. To keep alpha across a round trip, hold the colour rather than its hex.

static UXColor* hsb(i32 h, i32 s, i32 v) // h 0..359, s/v 0..255

Hue wraps instead of clamping, so hsb(370, …) is hsb(10, …) and negative hues work. This suits rotating a hue by arithmetic.

void toHSB(i32* h, i32* s, i32* v)

Uses out-parameters, because three values come back:

i32 h = 0; i32 s = 0; i32 v = 0;
brand.toHSB(&h, &s, &v); // h=223 s=178 v=160

The round trip is exact for the values it can represent: UXColor.hsb(223, 178, 160) gives back rgb(48,80,160).

UXColor* blend(UXColor* other, i32 t) // t 0..255

Linear interpolation, including alpha. t = 0 is the receiver unchanged, t = 255 is other, 128 is halfway.

UXColor* lightened(i32 amt)

A blend toward white (a tint). lightened(64) on rgb(48,80,160) gives rgb(99,123,183).

UXColor* darkened(i32 amt)

A blend toward black (a shade).

Use these to build a widget’s pressed and disabled states from one colour instead of storing three: base, base.darkened(40), base.lightened(90).

UXColor* withAlpha(i32 alpha)

The same colour at a different opacity, as a copy. See Overview.

i32 luminance(void) // 0..255

Perceptual brightness with Rec. 601 weights (77r + 150g + 29b). Green counts for roughly twice red and five times blue, matching human vision. A plain average would rate pure blue and pure green equally bright, which they are not.

bool isDark(void) // luminance < 128

Luminance exists for choosing readable text over a background:

UXColor* ink = background.isDark() ? UXColor.white() : UXColor.black();

Unlike a palette of hand-picked pairs, this line keeps working when the background comes from a theme, a file, or a user.

bool isEqualTo(UXColor* o)

Channel-wise equality, including alpha; null is false.

UXColor.black() UXColor.white() UXColor.gray()
UXColor.red() UXColor.green() UXColor.blue()

Constructed fresh on each call, so they are never shared and are safe to derive from.

For colours with a meaning rather than a value, such as “window background” or “selected text”, use UXColorList, a named palette that a theme can replace as a whole.

#import <Stdio.xc>
#import "UXColor.xc"
void main(void) {
UXColor* brand = UXColor.fromHex($3050A0); // rgb(48,80,160)
brand.lightened(64); // rgb(99,123,183)
brand.darkened(64); // rgb(35,59,119)
brand.blend(UXColor.red(), 128); // rgb(151,39,79)
UXColor* ghost = brand.withAlpha(96); // a=96
// brand is unchanged: a=255
i32 h = 0; i32 s = 0; i32 v = 0;
brand.toHSB(&h, &s, &v); // 223, 178, 160
UXColor.hsb(h, s, v); // back to rgb(48,80,160)
// Readable text over any background.
UXColor* ink = brand.isDark() ? UXColor.white() : UXColor.black();
Stdio.printf("brand luminance %d -> %s text\n", brand.luminance(),
brand.isDark() ? (u8*)"white" : (u8*)"black"); // 79 -> white
}

The full program is website/site/examples/uxkit/colour.xc. The doc-examples gate compiles it, and the values above are what it prints.

  • A plain class (not an Object subclass)