Files
eng-pad/CLAUDE.md
Kyle Isom 6e5c500786 Update project docs to reflect current state after post-Phase 10 polish
- PROGRESS.md: remove stale known issues (all fixed), add post-Phase 10
  feature polish section covering toolbar redesign, 4 pen sizes, line/box/move
  tools, edge swipe nav, page reorder, notebook rename, filter/sort, JPG
  export, clipboard ops, startup state restoration, and DB migrations
- PROJECT_PLAN.md: add Phase 11 (Server Sync Integration) and Phase 12
  (Notebook Backup/Export) with step breakdowns
- DESIGN.md: add Tools table, sync architecture section, backup/export design,
  JPG export, stroke styles, startup state restoration, edge swipe nav; update
  rendering strategy (3-layer compositing), source tree, schema, and pen sizes
- CLAUDE.md: update build commands, architecture, source tree, and key
  conventions to match current codebase

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

6.7 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

eng-pad is an Android note-taking app built around notebooks with an EMR pen as the primary input method. Target devices are the Supernote Manta (Android 11) and Daylight DC-1 (Android 13). Minimum API level is Android 11 (API 30).

Build Commands

make all                 # lint -> test -> build
make build               # Compile debug + release APKs
make test                # Run unit tests
make lint                # Run Android Lint
make clean               # Clean build artifacts
make apk                 # Build release APK
make run                 # Build, install, and launch on emulator (starts emulator if needed)
make devrun              # Build, install, and launch on connected USB device
make run AVD=Medium_Phone_API_36.0  # Use a specific AVD

# Run a single test class:
make test-one CLASS=net.metacircular.engpad.data.StrokeBlobTest

# Direct Gradle commands:
./gradlew build          # Compile + test + lint
./gradlew test           # Unit tests only
./gradlew lint           # Android Lint only

Architecture

  • Kotlin + Jetpack Compose for UI chrome (screens, toolbar, dialogs)
  • Custom View (PadCanvasView) for the drawing canvas — Compose Canvas lacks MotionEvent access needed for stylus input
  • Room (SQLite) for persistence — notebooks, pages, strokes (schema version 3)
  • SharedPreferences for startup state restoration (last notebook, page list flag)
  • Single Activity with Compose Navigation (three routes: notebook list -> page list -> editor)
  • Coordinate system: 300 DPI canonical points. Regular page = 2550x3300pt, large = 3300x5100pt. Scaled to 72 DPI (x0.24) for PDF export.
  • Input dispatch: TOOL_TYPE_STYLUS -> draw/erase/select/move, TOOL_TYPE_FINGER -> zoom/pan/edge swipe

Project Documents

  • DESIGN.md — Full technical design (architecture, data model, rendering, tools, source tree)
  • PROJECT_PLAN.md — All implementation steps with checkboxes. Check off steps as completed.
  • PROGRESS.md — What's been done, what's in progress, decisions made. Update after every step.

Keep PROJECT_PLAN.md and PROGRESS.md in sync. When a step is completed, check it off in PROJECT_PLAN.md and log it in PROGRESS.md. When files are added, update the source tree in both DESIGN.md and this file.

Source Tree

eng-pad/
├── app/
│   ├── build.gradle.kts                              -- Module build config
│   └── src/
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── kotlin/net/metacircular/engpad/
│       │   │   ├── EngPadApp.kt                      -- Application class, SharedPreferences
│       │   │   ├── MainActivity.kt                   -- Single activity, Compose NavHost
│       │   │   ├── data/
│       │   │   │   ├── db/                           -- Room database (v3), DAOs, converters
│       │   │   │   ├── model/                        -- Entities: Notebook, Page, Stroke, PageSize
│       │   │   │   └── repository/                   -- NotebookRepository, PageRepository
│       │   │   ├── ui/
│       │   │   │   ├── navigation/NavGraph.kt        -- Routes, auto-restore last notebook
│       │   │   │   ├── notebooks/                    -- Library: list, filter, sort, rename + ViewModel
│       │   │   │   ├── pages/                        -- Page grid, drag-to-reorder + ViewModel
│       │   │   │   ├── editor/                       -- PadCanvasView, EditorScreen, ViewModel, Toolbar
│       │   │   │   ├── export/PdfExporter.kt         -- PDF + JPG generation + sharing
│       │   │   │   └── theme/Theme.kt                -- Material3 high-contrast e-ink theme
│       │   │   └── undo/                             -- UndoManager, UndoableAction, StrokeActions, SelectionActions
│       │   └── res/
│       │       ├── values/                           -- strings.xml, themes.xml
│       │       ├── drawable/                         -- Launcher icons
│       │       ├── mipmap-anydpi/                    -- Adaptive icon
│       │       └── xml/file_provider_paths.xml       -- FileProvider config
│       └── test/                                     -- Unit tests (StrokeBlobTest, PageSizeTest, UndoManagerTest)
├── build.gradle.kts                                  -- Root build config
├── settings.gradle.kts                               -- Project settings (foojay JDK resolver)
├── gradle.properties
├── gradle/libs.versions.toml                         -- Version catalog
├── Makefile                                          -- Build targets (build, test, lint, run, devrun, apk)
├── CLAUDE.md                                         -- This file
├── README.md
├── DESIGN.md                                         -- Technical design
├── PROJECT_PLAN.md                                   -- Implementation steps
└── PROGRESS.md                                       -- Completion tracking

Key Conventions

  • Stroke points are packed as little-endian float BLOBs: [x0,y0,x1,y1,...]
  • All coordinates are in canonical space (300 DPI). Screen transform via Matrix.
  • Grid drawn in screen space with pixel-snapped positions (not canonical space) for uniform squares. Cached in a grid bitmap, redrawn only on zoom/pan/resize.
  • 4 pen sizes: 0.38mm (4.49pt), 0.5mm (5.91pt), 0.6mm (7.09pt), 0.7mm (8.27pt) at 300 DPI.
  • Single PEN tool with long-press for size selection; remembers last size.
  • Line styles stored in stroke style DB column: plain, dashed, arrow, double_arrow.
  • LINE tool with long-press for style selection; BOX tool for rectangles.
  • MOVE tool for tap-and-drag stroke relocation.
  • Anti-aliasing disabled on all paint objects for crisp e-ink rendering.
  • Screen-resolution backing bitmap with incremental stroke addition (no full redraw on each new stroke).
  • Viewport: page always fills screen, pan clamped to edges, dynamic min zoom.
  • Edge swipe navigation: finger swipe from screen edge -> previous/next page.
  • Line snap: hold pen still 1.5s to snap to straight line (60pt movement threshold).
  • Hardware palm rejection only (EMR digitizer).
  • Startup state restoration via SharedPreferences (last notebook ID, page list flag).
  • Notebook lastPageId tracks resume position per-notebook.
  • Clipboard: cut/copy/paste with toolbar buttons shown contextually.
  • Export: PDF (multi-page, 72 DPI) and JPG (single page, 300 DPI) via share intents.