Skip to content

Add pebble/colors module with named GColor8 constants#1587

Open
WalkerFrederick wants to merge 1 commit intoModdable-OpenSource:publicfrom
WalkerFrederick:add-pebble-colors-module
Open

Add pebble/colors module with named GColor8 constants#1587
WalkerFrederick wants to merge 1 commit intoModdable-OpenSource:publicfrom
WalkerFrederick:add-pebble-colors-module

Conversation

@WalkerFrederick
Copy link
Copy Markdown

Summary

Expose all 64 Pebble GColor8 named color constants (plus clear) as a preloaded JavaScript module at "pebble/colors"

proposed usage:
import { cobaltBlue, chromeYellow, white } from "pebble/colors";

Each constant is the GColor8 ARGB8 byte value matching the C SDK definitions, usable directly with Poco rendering methods.

Motivation

render.makeColor(r, g, b) can produce unexpected results for Pebble developers because the 2-bit-per-channel display silently snaps values to the nearest of 64 palette colors, with no indication that the rendered color differs from what was requested.

Named constant

No silent snapping — you're choosing directly from the actual palette, so what you write is exactly what renders
Discoverable — autocomplete shows all 64 available colors
Consistent with the C SDK — C developers already have GColorCobaltBlue, GColorChromeYellow, etc. This brings the JS SDK to parity

Details

Each export is the GColor8 ARGB8 byte value (e.g. cobaltBlue = 0xC6), matching the C SDK's GColorCobaltBlueARGB8 Values
The module is preloaded into ROM, so it has zero heap cost at runtime
Names use camelCase following JS conventions (C SDK uses PascalCase GColorCobaltBlue)

Expose all 64 Pebble GColor8 named color constants (plus clear) as a
preloaded JavaScript module at "pebble/colors", allowing developers to
use named imports instead of raw hex values:

  import { cobaltBlue, chromeYellow, white } from "pebble/colors";

Each constant is the GColor8 ARGB8 byte value matching the C SDK
definitions, usable directly with Poco rendering methods.

The module is preloaded into ROM for zero heap cost at runtime.
@phoddie
Copy link
Copy Markdown
Collaborator

phoddie commented Apr 5, 2026

Hey, thanks for the PR!

I like your idea. With just 64 colors, using RGB triples can be awkward to select unique colors.

The approach you propose works with Poco, but it won't work with Piu. Piu does have its own list of name strings. That allows developers to write new Skin({ fill: "white" }) . We could amend that list to include the Pebble colors.

But, the following would still give unexpected results because Piu interprets numbers passed as colors as 32-bit ARGB values (returned by global rgb(), hsla(), and rgba() functions). It would be challenging to explain to developers why this doesn't render as white.

import { white } from "pebble/colors";

let sampleColumn = new Column(null, {
	top: 0, bottom: 0, left: 0, right: 0,
	skin: new Skin({ fill: white }), style: sampleStyle,

There's probably a good solution to this. Any ideas? I'll think on it some too.

@WalkerFrederick
Copy link
Copy Markdown
Author

Good point on Piu

What if the module exported 32-bit RRGGBBAA values instead of GColor8 bytes? Same format rgb() returns, so Piu would just work:

export const cobaltBlue = 0x0055AAFF;
export const white      = 0xFFFFFFFF;

Then on the Poco side, check if the value is above 0xFF, convert from 32-bit to GColor8 by shifting each channel down to 2 bits. All 64 palette colors are exact multiples of 85 so the conversion is lossless. Old code passing raw GColor8 bytes still works since anything ≤ 0xFF gets treated as GColor8 like before.

32-bit opaque black is 0x000000FF = 255, which collides with GColor8 white (0xFF). It's the only collision. Could work around it by exporting black as 0x000001FF — B=1 instead of B=0. Both land in the same 0–63 bucket on the 2-bit display so it's still black.

only downside being that it then might be weird if someone were to manually use 0x000000FF with poco.

otherwise i will have to think on it...

Thanks

@phoddie
Copy link
Copy Markdown
Collaborator

phoddie commented Apr 6, 2026

A magic number is a clever hack, but a little fragile. If we only had an extra bit.

I was thinking about this today. Piu already supports named colors, so extending that list is natural. Poco does not support named colors. Maybe adding that to Poco is the right solution? it could be be render.makeColor("cobaltBlue"). That isn't quite as elegant as your import but it stays within the Poco API style. It could probably share the string to color mapping table with Piu.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants