Repository navigation
feat(ui): set time settings on a two-column minutes-and-seconds roller - #150
Merged
Merged
Conversation
The preset pickers could not reach most of the values their own fields hold. Average lap offered eleven choices stopping at 3:00 against a field validated to 59:59, so a circuit with a longer lap could not be configured at all; session and rest duration stopped at 60 minutes against a validated 24 hours. The lists could not simply be extended either, since kValueChoiceCapacity is twelve. Both columns are live at once. The vertical gesture acts on whichever column it starts over, so minutes and seconds are adjusted without a focus to switch between them. Columns wrap within themselves and never carry: a carry is unpredictable when the two are targeted independently, and a flick that rolls seconds several times round would otherwise drag minutes with it. A discrete swipe per step would have needed 59 gestures to cross a column, which is worse than the single press it replaces, so the screen tracks the pointer continuously and a flick coasts with exponential decay. That needed a continuous path through the input layer, which until now deliberately reduced touch to named actions. The discrete contract is untouched and everything else still uses it. Saving is a measured 1200 ms hold rather than LVGL's 400 ms long press. On the device that threshold committed a value 1.4 seconds after the screen opened, before anything had been rolled. The hold is cancelled if the finger wanders more than 14 px, and a bar fills as it counts, because a longer hold with no feedback reads as an unresponsive screen rather than a deliberate one. Cancelling is a horizontal swipe: down now drives the digits and can no longer mean back. Durations are stored in seconds, which needed a settings v5 and a migration, since 1439 minutes of seconds does not fit the uint16 they used to occupy. Everything before v5 held whole minutes, so migrating is exact. The log record mirrors those fields, so kLogFormatVersion goes to 2 as well and older logs are rejected by version rather than silently misread as very short sessions; that consumes the bump #137 was waiting for. Fifteen host tests cover the ranges, wrap without carry, drag accumulation, flick decay and settling, catching a coasting column, clamping to a field's floor on commit, the zero-means-unset coupling to lower display, and the hold threshold and its wander cancel. Verified on the panel across a 175-sample editing session: column targeting follows the touch, minutes wrapped 28 to 0 while seconds held at :05, and the session ended in exactly one deliberate save with no accidental commits. Closes #149 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
18 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #149.
The pickers could not reach their own fields' values
Not merely clumsy — incomplete. Every one of these stores and validates far more than
the picker offered:
average_lap_secondssession_durationrest_durationA circuit with a lap over three minutes could not be configured at all. The lists could not
just be extended either:
kValueChoiceCapacityis twelve.Interaction
Both columns live at once, the vertical gesture acting on whichever one it starts over, so
minutes and seconds need no focus switched between them. Columns wrap within themselves and
never carry — a carry is unpredictable when the two are targeted independently, and a
flick rolling seconds several times round would otherwise drag minutes with it.
Why the input layer had to grow
A discrete swipe per step needs up to 59 gestures to cross a column, which is worse than
the single press it replaces. So the screen tracks the pointer continuously and a flick
coasts with exponential decay.
InputActiondeliberately reduces touch to named actions anddiscards position;
attach_drag_inputadds a parallel continuous path. The discrete contractis untouched and every other screen still uses it.
Saving needed a longer hold, found on the device
Built against LVGL's
LV_EVENT_LONG_PRESSED— 400 ms — saving fired while the driver wasstill taking hold of the unit. Captured before the fix, with no drag samples at all first:
Now a measured 1200 ms hold, cancelled if the finger wanders more than 14 px, with a bar
filling as it counts — a longer hold without feedback would read as an unresponsive screen,
a worse defect than the one being fixed.
HoldToSaveis separate fromTimeRollerbecauseit concerns the finger rather than the value, and carries no LVGL so it is host-tested.
Cancelling is a horizontal swipe: down drives the digits and can no longer mean back.
Settings v5, and a log format bump
Durations are stored in seconds now, which the old
uint16cannot hold — 1439 minutes ofseconds is 86,399. They widen to
uint32with a v5 format and a migration; everythingbefore v5 held whole minutes, so migrating is exact. Tested against a real v4 blob.
The log record mirrors those fields, so
kLogFormatVersiongoes to 2 and older logs arerejected by version rather than silently misread as very short sessions. That consumes the
bump #137 was waiting for.
Verification
accumulation, flick decay and settling, catching a coasting column, commit clamping, the
zero-means-unset coupling, and the hold threshold and wander cancel
Column targeting follows the touch with no focus switch, and wrap-without-carry is visible
in real data — seconds hold at
:05while minutes roll28 -> 0 -> 5 -> 3. One deliberatesave, no accidental commits, no watchdog triggers. Probe removed and its absence confirmed on
the final image.
Also
.gitignorenow coverscore.*: a failing host test binary drops core dumps in therepository root, and seven of them were sitting there from this branch's own debugging.