tui: inpainting canvas overlay (keyboard-driven mask editor) #23

Closed
opened 2026-04-11 13:03:12 +00:00 by charles · 0 comments
Owner

User story

As a user in inpaint mode, I want a full-screen canvas to draw a mask over the init image using the keyboard, so that I can inpaint regions without leaving the terminal.

Acceptance criteria

Canvas overlay

  • Full-screen overlay pushed from Generate screen in inpaint mode
  • Init image drawn via the image renderer (Kitty preferred)
  • A mask layer (GrayImage) sized to the init image is maintained alongside

Keyboard editing

  • h/j/k/l moves cursor by one pixel (or brush-radius step); arrow keys duplicate
  • Space paints a circular stamp at the cursor; held paint (autorepeat) supported
  • x erases under the cursor; c clears the whole mask
  • [ / ] decreases/increases brush radius (1–128)
  • Brush cursor visually indicated via a ratatui overlay rectangle or a half-block cursor sprite layered on the image
  • Enter confirms and returns to Generate with the mask exported as an 8-bit grayscale PNG (white = inpaint region)
  • Esc cancels without modifying Generate state

Integration

  • Exported mask path stored on the Generate screen's inpaint state and passed to the backend on submit
  • Redraws are debounced to avoid flooding the terminal when painting continuously

Tests

  • Unit test: painting at (x, y) with radius r produces the expected circle fill
  • Unit test: confirm returns a PNG whose non-zero pixel count matches expectations

Out of scope

  • The inpainting generation itself (handled by plugin backend)
  • Mouse-driven drawing (keyboard-only per spec)

References

  • Spec §4.1.2 "Inpainting"
## User story As a user in inpaint mode, I want a full-screen canvas to draw a mask over the init image using the keyboard, so that I can inpaint regions without leaving the terminal. ## Acceptance criteria ### Canvas overlay - [ ] Full-screen overlay pushed from Generate screen in inpaint mode - [ ] Init image drawn via the image renderer (Kitty preferred) - [ ] A mask layer (`GrayImage`) sized to the init image is maintained alongside ### Keyboard editing - [ ] `h`/`j`/`k`/`l` moves cursor by one pixel (or brush-radius step); arrow keys duplicate - [ ] `Space` paints a circular stamp at the cursor; held paint (autorepeat) supported - [ ] `x` erases under the cursor; `c` clears the whole mask - [ ] `[` / `]` decreases/increases brush radius (1–128) - [ ] Brush cursor visually indicated via a ratatui overlay rectangle or a half-block cursor sprite layered on the image - [ ] `Enter` confirms and returns to Generate with the mask exported as an 8-bit grayscale PNG (white = inpaint region) - [ ] `Esc` cancels without modifying Generate state ### Integration - [ ] Exported mask path stored on the Generate screen's inpaint state and passed to the backend on submit - [ ] Redraws are debounced to avoid flooding the terminal when painting continuously ### Tests - [ ] Unit test: painting at `(x, y)` with radius `r` produces the expected circle fill - [ ] Unit test: confirm returns a PNG whose non-zero pixel count matches expectations ## Out of scope - The inpainting generation itself (handled by plugin backend) - Mouse-driven drawing (keyboard-only per spec) ## References - Spec §4.1.2 "Inpainting"
charles added this to the loom-tui v0.1.0 milestone 2026-04-11 13:03:12 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/loom#23
No description provided.