Paint: fix stuck pen, add Move/Draw/Erase modes and canvas persistence - #238
Merged
Conversation
Fixes #14 The pen appeared stuck because a long Ok press toggled a hidden isDrawing flag with no visual indication, and while it was set every short Ok press force-repainted the cell it had just toggled, so the pen could never be lifted or a dot erased. - Replace the hidden flag with three modes cycled by a long Ok press: Move, Draw, Erase; the XOR cursor shape shows the active mode (small dot / full cell / hollow frame), so an accidental long press is visible and one short press away from recovery - Short Ok toggles the cell in Move mode and lifts the pen or eraser in Draw/Erase modes - Arrows now react to press, long and repeat events, so holding a key keeps moving (and draws or erases a line with the pen down); strokes mark both the cell left and the cell entered - Save the canvas on exit (temp file + sync + rename so a failed write cannot destroy the previous save) and restore it on start; a failed save shows a storage error dialog instead of silently losing the drawing - Tear down the viewport before saving so a hanging SD write cannot freeze the GUI thread on a full event queue - Fix uninitialized PaintData, missing mutex use in the event loop, RECORD_NOTIFICATION closed without being opened, an event-queue leak on the mutex failure path and dead code in the clear handler - Add CHANGELOG.md backfilled from repo history; bump to 1.4 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Review/simplify follow-up. The hand-rolled save/load reimplemented lib/toolbox/saved_struct, the established persistence helper used by sibling apps (ir_intervalometer, air_arkanoid). Route through it: - saved_struct_save/saved_struct_load replace the manual open, read, write, close and size-check plumbing; they embed a magic, version and checksum, so the 4-byte magic constant and the 0/1 byte-normalization loop are gone (the checksum rejects a corrupt payload wholesale). - Keep the deliberate crash-safety: save to the temp file then rename it over the real save, so a failed write cannot destroy the previous canvas. Still memset the board to an empty canvas on any load failure. No behavior change: save on exit, restore on start, reject foreign or corrupt files (now checksum-backed), show the storage error dialog when the save cannot be written. Net -18 lines. Builds clean under ufbt (API 88.0), ufbt format applied. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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 #14
The bug
Pressing Ok together with a direction key easily turns into an accidental long Ok press, which toggled a hidden
isDrawingflag with zero visual indication. While it was set, every short Ok press toggled the cell and then immediately force-repainted it, so short presses could neither lift the pen nor erase anything - the pen looked permanently stuck.The fix
Implements the mode switch the issue author asked for, keeping "push to paint":
Save/load (also requested in #14)
The canvas is saved on exit to
/ext/apps_data/paint/canvas.bin(magic header + board) and restored on the next start. Hardened per review: written to a temp file with sync + rename so a failed write cannot destroy the previous save; a failed save shows the standard storage error dialog instead of silently losing the drawing; a corrupt or foreign file is rejected and loaded bytes are normalized to valid booleans.Cleanups
PaintDatawas never initialized aftermallocRECORD_NOTIFICATIONwas closed without ever being openedAdds
CHANGELOG.mdbackfilled from repo history (1.0 initial, 1.1-1.3 catalog bumps), bumpsfap_versionto 1.4. Builds clean under standalone ufbt (API 88.0),ufbt formatapplied. Reviewed with the code/comments/silent-failure agents and the simplifier pass.🤖 Generated with Claude Code