Round display support (gabbro): round template variants and arc status #62

Open
opened 2026-08-31 18:06:56 +02:00 by robert · 0 comments
robert commented 2026-08-31 18:06:56 +02:00 (Migrated from git.butzei.de)

Goal

Make the Pebble Round 2 a device the app was designed for rather than tolerated on. 260x260 round, but a circle of that size inscribes only about 184x184 - so a screen with more total pixels than emery has less usable area for grids.

Acceptance criteria

  • HERO1 centred with ~170 px digits - the template that suits a circle best
  • HERO2 hero centred, the two cells inset to the chord width at their vertical position
  • QUAD inset to the inscribed square, cells about 92x92
  • GRID6 falls back to QUAD on gabbro, as it does on basalt
  • Status becomes an arc along the top bezel using graphics_draw_arc() and gpoint_from_polar(), with glyphs placed radially - a straight strip has almost no width on a circle
  • NAV centred turn arrow with arc-aligned text
  • MAP round-native: a heading-up centred map, which suits a circle better than a rectangle
  • Variants selected with PBL_ROUND / PBL_IF_ROUND_ELSE(), never with runtime screen-size checks
  • No hard-coded coordinates anywhere - everything derived from layer_get_bounds()
  • gbitmap_get_data_row_info() used wherever the framebuffer is touched directly; rows are shorter near the top and bottom of a round display
  • text_layer_enable_screen_text_flow_and_paging() enabled for text that can overflow, so it follows the curve rather than clipping
  • Every page verified in the gabbro emulator and, where hardware allows, on device

Files

  • watchapp/src/c/page_render.c
  • watchapp/src/c/status_bar.c

Notes

Rectangular layouts do NOT auto-adapt to round - the SDK's automatic scaling is chalk to gabbro, which is round to round. See docs/DESIGN.md section 3 and docs/DECISIONS.md D24.

Update — 2026-09-01: moved to Phase 1b, and the DPI figure was wrong

Moved to Phase 1b — Generalise the display (D32). Round support is not cancelled; it is better
designed after a few real rides on the rectangle than before the first one, and it was landing before
#4 had confirmed the transport the whole architecture depends on.

Correction: the Round 2 is ~200 DPI, not 283. 260 px across a 1.3″ diagonal is about 200 — the
same density as the Time 2 (200 × 228 over 1.5″ ≈ 202 DPI). See the D24 correction.

  • A digit specified in pixels is the same physical size on both watches, so no per-device type
    scale is needed — but gabbro text cannot be smaller in pixels either, because the density it
    was credited with is not there
  • Digit sizes come from the procedural renderer (D33), so the round variants need no extra font
    resources
  • QUAD's emphasised slot 1 (D29) works within the inscribed square
  • Template geometry covered by the host-side tests in #68 — "no slot exceeds its bounds on
    emery, gabbro or basalt" as an assertion rather than a look in the emulator
## Goal Make the Pebble Round 2 a device the app was designed for rather than tolerated on. 260x260 round, but a circle of that size inscribes only about 184x184 - so a screen with more total pixels than emery has less usable area for grids. ## Acceptance criteria - [ ] `HERO1` centred with ~170 px digits - the template that suits a circle best - [ ] `HERO2` hero centred, the two cells inset to the chord width at their vertical position - [ ] `QUAD` inset to the inscribed square, cells about 92x92 - [ ] **`GRID6` falls back to `QUAD` on `gabbro`**, as it does on `basalt` - [ ] **Status becomes an arc** along the top bezel using `graphics_draw_arc()` and `gpoint_from_polar()`, with glyphs placed radially - a straight strip has almost no width on a circle - [ ] `NAV` centred turn arrow with arc-aligned text - [ ] `MAP` round-native: a heading-up centred map, which suits a circle better than a rectangle - [ ] Variants selected with `PBL_ROUND` / `PBL_IF_ROUND_ELSE()`, never with runtime screen-size checks - [ ] **No hard-coded coordinates anywhere** - everything derived from `layer_get_bounds()` - [ ] `gbitmap_get_data_row_info()` used wherever the framebuffer is touched directly; rows are shorter near the top and bottom of a round display - [ ] `text_layer_enable_screen_text_flow_and_paging()` enabled for text that can overflow, so it follows the curve rather than clipping - [ ] Every page verified in the `gabbro` emulator and, where hardware allows, on device ## Files - `watchapp/src/c/page_render.c` - `watchapp/src/c/status_bar.c` ## Notes Rectangular layouts do NOT auto-adapt to round - the SDK's automatic scaling is chalk to gabbro, which is round to round. See docs/DESIGN.md section 3 and docs/DECISIONS.md D24. ## Update — 2026-09-01: moved to Phase 1b, and the DPI figure was wrong Moved to **Phase 1b — Generalise the display** (D32). Round support is not cancelled; it is better designed after a few real rides on the rectangle than before the first one, and it was landing before #4 had confirmed the transport the whole architecture depends on. **Correction: the Round 2 is ~200 DPI, not 283.** 260 px across a 1.3″ diagonal is about 200 — the same density as the Time 2 (200 × 228 over 1.5″ ≈ 202 DPI). See the D24 correction. - [ ] A digit specified in pixels is the **same physical size on both watches**, so no per-device type scale is needed — but `gabbro` text cannot be smaller in pixels either, because the density it was credited with is not there - [ ] Digit sizes come from the procedural renderer (D33), so the round variants need no extra font resources - [ ] `QUAD`'s emphasised slot 1 (D29) works within the inscribed square - [ ] Template geometry covered by the host-side tests in #68 — "no slot exceeds its bounds on `emery`, `gabbro` or `basalt`" as an assertion rather than a look in the emulator
Sign in to join this conversation.
No description provided.