Files
eng-pad/PROGRESS.md
Kyle Isom 85a210c001 Update docs for DC-1 testing, fix toolbar clipping
- Updated DESIGN.md: rendering strategy (no backing bitmap, screen-space
  grid, viewport clamping), added line snap and box tool documentation
- Updated PROGRESS.md: DC-1 testing results and fixes applied
- Updated CLAUDE.md: key conventions for rendering
- Fix toolbar overlap: use clipToBounds on canvas AndroidView to prevent
  it from drawing over the toolbar area

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 15:13:25 -07:00

148 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PROGRESS.md — eng-pad Implementation Progress
This file tracks completed work and decisions. Updated after every step.
See PROJECT_PLAN.md for the full step list.
## Completed
### Phase 0: Project Documents (2026-03-24)
- [x] 0.1: Created DESIGN.md — full technical design covering architecture,
data model, coordinate system, rendering, input handling, and source tree.
- [x] 0.2: Created PROJECT_PLAN.md — discrete steps grouped by phase with
checkboxes and file references.
- [x] 0.3: Created PROGRESS.md — this file.
- [x] 0.4: Updated CLAUDE.md — build commands, source tree, project doc
pointers.
### Phase 1: Project Skeleton + Data Layer (2026-03-24)
- [x] 1.1: Generated Android project — Gradle 8.14.2, AGP 8.10.1, Kotlin 2.1.20
- [x] 1.2: Version catalog with Compose BOM 2026.03.00, Room 2.8.4,
Navigation 2.9.7, Lifecycle 2.10.0
- [x] 1.3: Lint configured — warningsAsErrors, AGP version check suppressed
(AGP 9.x needs Gradle 9.x)
- [x] 1.4: Room entities: Notebook, Page, Stroke, PageSize enum
- [x] 1.5: Converters: FloatArray ↔ ByteArray (packed little-endian)
- [x] 1.6: DAOs: NotebookDao, PageDao, StrokeDao
- [x] 1.7: EngPadDatabase (Room, version 1)
- [x] 1.8: NotebookRepository, PageRepository
- [x] 1.9: Unit tests: StrokeBlobTest (6 tests), PageSizeTest (4 tests) — all pass
- Foojay resolver added for automatic JDK toolchain download
- compileSdk/targetSdk bumped to 36 (required by latest androidx dependencies)
### Phase 2: Notebook List Screen (2026-03-24)
- [x] 2.1: MainActivity with Compose NavHost (three routes: notebooks, pages, editor)
- [x] 2.2: NotebookListViewModel with StateFlow, create/delete operations
- [x] 2.3: NotebookListScreen — lazy list, create dialog (title + page size radio),
long-press delete with confirmation, empty state
- [x] 2.4: Auto-create page 1 in NotebookRepository.create()
- [x] 2.5: Navigation wired — tap notebook → pages stub, editor stub
- EngPadTheme: high-contrast light color scheme (black on white for e-ink)
### Phase 3: Canvas — Basic Drawing (2026-03-24)
- [x] 3.13.4: PadCanvasView — stylus input with historical points, Path/Paint
stroke rendering, direct path drawing (no backing bitmap), 60pt grid
drawn in screen space with pixel-snapped positions, Matrix coordinate
transform (canonical ↔ screen)
- [x] 3.5: CanvasState — tool enum (PEN_FINE, PEN_MEDIUM, ERASER, SELECT, BOX),
zoom/pan state, pen width constants (4.49pt, 5.91pt)
- [x] 3.6: EditorViewModel — loads strokes from Room, saves on completion
- [x] 3.7: EditorScreen + Toolbar — Compose wrapper with AndroidView,
FilterChip toolbar for pen size and eraser selection
- [x] 3.8: NavGraph updated — pages route auto-navigates to first page's editor,
page size passed through route params
- Used KTX Canvas extensions (withMatrix, withScale, createBitmap) per lint
- ClickableViewAccessibility suppressed on PadCanvasView (drawing view)
### Phase 4: Zoom and Pan (2026-03-24)
- [x] 4.1: ScaleGestureDetector with focal-point zoom (dynamic min4×)
- [x] 4.2: Finger drag for pan with multi-pointer tracking, pan clamped
so page always fills viewport
- [x] 4.3: Input routing by tool type already in place from Phase 3
- Zoom/pan state managed locally in PadCanvasView for responsiveness,
synced to ViewModel on gesture end
- Minimum zoom computed dynamically from page/view dimensions
### Phase 5: Eraser (2026-03-24)
- [x] 5.15.3: Stroke-level eraser with bounding box hit test (42pt radius),
processes historical touch points for thorough erasing, deletes from
view + Room DB
### Phase 6: Undo/Redo (2026-03-24)
- [x] 6.1: UndoableAction interface, AddStrokeAction, DeleteStrokeAction
- [x] 6.2: UndoManager with undo/redo stacks (depth 50), StateFlow for canUndo/canRedo
- [x] 6.3: EditorViewModel rewired — stroke add/delete go through UndoManager,
visual callbacks sync canvas view without full reload
- [x] 6.4: 9 unit tests for UndoManager (perform, undo, redo, depth limit, clear, no-ops)
- Toolbar now has undo/redo buttons with enabled state
### Phase 7: Selection — Move, Copy, Delete (2026-03-24)
- [x] 7.17.2: Rectangle selection with dashed rect and blue highlight
- [x] 7.3: Delete, drag-to-move, copy operations with toolbar buttons
- [x] 7.4: Full undo integration — DeleteMultipleStrokesAction, MoveStrokesAction,
CopyStrokesAction
- Drag existing selection to move, tap outside to deselect
### Phase 8: Multi-Page Navigation (2026-03-24)
- [x] 8.1: PageListScreen — adaptive grid of page cards with correct aspect ratio
- [x] 8.2: Add new page via FAB
- [x] 8.3: NavGraph refactored — pages route loads notebook metadata then shows
PageListScreen, tap page navigates to editor with page size
### Phase 9: PDF Export (2026-03-24)
- [x] 9.1: PdfExporter — creates PdfDocument, scales canonical 300 DPI coords
to 72 DPI PDF points (×0.24), renders strokes without grid
- [x] 9.2: Share via Intent.ACTION_SEND + FileProvider (configured in Phase 1)
- [x] 9.3: PDF button in editor toolbar, exports current page
### Phase 10: Polish (2026-03-24)
- [x] 10.1: High-contrast e-ink theme — expanded color scheme with proper
container, variant, and outline colors for readability
- [x] 10.2: Auto-save already in place since Phase 3 (strokes save on completion)
- [x] 10.3: Empty states and delete confirmations already in place from Phase 2
- [ ] 10.4: Performance profiling — requires on-device testing
### On-Device Testing — Daylight DC-1 (2026-03-24)
Tested on DC-1, identified and fixed rendering issues:
- **Grid**: original grid drawn in canonical space had uneven spacing due to
sub-pixel positioning when scaled. Fixed by drawing grid in screen space
with pixel-snapped line positions. Now uniform squares.
- **Stroke quality**: original backing bitmap at 1/4 resolution caused blurry
strokes. Fixed by removing backing bitmap entirely and drawing paths directly.
Anti-aliasing disabled on all paint for crisp e-ink lines.
- **Viewport**: dark gray background was visible around page edges. Fixed by
clamping pan to page edges, computing dynamic min zoom, and white background.
- **Box tool**: works correctly on device.
- **PDF export**: correctly elides grid — confirmed on device.
- **Line snap**: increased threshold to 60pt (~5mm) and switched to max-distance
tracking to handle EMR stylus hand tremor.
## Status
All implementation phases complete. Remaining work:
- Test on Supernote Manta
- Verify line snap behavior on device
- Performance profiling with heavily annotated pages
## Decisions & Deviations
- **Language**: Kotlin (chosen over Java for better Compose/coroutine support).
- **Storage**: Room/SQLite with packed float BLOBs for stroke points.
- **Palm rejection**: Hardware only (EMR digitizer handles it).
- **Pressure sensitivity**: None — two fixed pen sizes (0.38mm, 0.5mm).
- **Coordinate system**: 300 DPI canonical points (scaled to 72 DPI for PDF export).
- **UI framework**: Compose for chrome, custom View for canvas (Compose
Canvas lacks MotionEvent access needed for stylus input).