openpencil/crates/openpencil-shell-native
Kayshen-X a036463c93 feat(themes): axis chip click cycles to the next theme value
VariablesPanel chips were previously click-swallowing placeholders.
This commit adds the actual axis-cycle behavior — clicking the
"mode: dark" chip flips it to "mode: light", then "mode: sepia",
wrapping back to "mode: light". The TS app has the equivalent
behavior via its theme dropdown; the Rust shell now offers the
one-click chip flip as the simpler entry point.

`crates/openpencil-shell-core/src/document/variables.rs`:
  - `VariableTable::cycle_active_axis_value(axis) -> bool`:
      1. Returns false (no-op) when `axis` isn't in `themes` or
         its values list is empty.
      2. When the axis isn't in `active_theme`, seeds it with the
         first value.
      3. When current value matches an entry, advances to the
         next (wrapping past the last).
      4. When current value is unrecognized (axis options
         changed since file loaded), falls back to the first.

`crates/openpencil-shell-native/src/widget_host/property_dispatch.rs`:
  - `dispatch_variables_panel_press` `AxisChip(idx)` branch now
    looks up the axis name by position in `active_theme` (BTreeMap
    iteration is stable + matches the chip walk order in
    VariablesPanel::paint), commits any pending property focus,
    captures an undo snapshot, calls `cycle_active_axis_value`,
    and pushes the snapshot onto history when the cycle actually
    moved (return true). Snapshot+restore covers var_table per
    the prior history fix (99d602a3), so undo round-trips the
    theme cycle the same way it does variable color edits.

Tests (5 added, 300 shell-core total):
  - `cycle_active_axis_seeds_first_value_when_absent` — axis in
    `themes` but not in `active_theme` → cycle plants the first
    value.
  - `cycle_active_axis_advances_to_next_value` — three-value
    walk through light → dark → sepia → light (wrap).
  - `cycle_active_axis_returns_false_for_unknown_axis` — no-op +
    false.
  - `cycle_active_axis_returns_false_for_empty_values` — defined
    in themes but with empty values list → no-op + false.
  - `cycle_active_axis_falls_back_to_first_when_current_unknown`
    — graceful degradation when active_theme has a stale value
    (axis options changed since file load).

The variable edit chain now covers BOTH primary surfaces:
  - Row click on a Color-kind variable → ColorPicker → set_color_hex
  - Axis chip click → cycle_active_axis_value
Both push undo entries that restore through the var_table-aware
snapshot.
2026-05-14 19:39:37 +08:00
..
examples refactor(shell): promote inspector_window to openpencil-desktop binary crate 2026-05-10 19:50:10 +08:00
notes feat(shell-native): Step 1a Task 4 — basic_window demo + acceptance + Phase C Gate 2026-05-05 22:39:00 +08:00
src feat(themes): axis chip click cycles to the next theme value 2026-05-14 19:39:37 +08:00
tests refactor(shell-native): finish v19.4 cleanup — drop orphan event/ + stale test 2026-05-08 22:03:34 +08:00
Cargo.toml docs(shell-native): correct stale Cargo.toml comment about Invariant 2 2026-05-10 10:17:10 +08:00