Skip to content

Latest commit

 

History

History
141 lines (117 loc) · 6.81 KB

PROGRESS.md

File metadata and controls

141 lines (117 loc) · 6.81 KB

PROGRESS — Phase 2 (Session 2A): Vector System — Shape Objects

Last updated: 2026-09-22T18:00:00+08:00 Current task: none — session complete Completed tasks: 1, 2, 3, 4, 5, 6, 7, 8, 9 Current mode: A

Log

2026-09-22T18:00:00+08:00 — Tasks 8 and 9 complete (sample, docs, close-out)

  • Task 8: docs/samples/vector_demo.pxcproj (five kinds + move + edit + select); crates/core/tests/vector_demo.rs (command usage, determinism, edit/move load-bearing, FNV1a pin 17788156799176839111); CLI determinism render test.
  • Task 9: README (shape tools/shortcuts/vocabulary/sample), BACKLOG (5 session-2A deferrals), ROADMAP (session 2A complete, 2B/2C remain), ui-roadmap-mapping.md rows #6/#17 rationales refreshed, PLAN.md → COMPLETE.
  • Tests: full workspace 403 passed / 0 failed; build 0 warnings.
  • Files modified: as above.

2026-09-22T17:20:00+08:00 — Task 7 complete (GUI shape tools, selection, move)

  • Implemented: five Tool variants (ShapeRect/ShapeEllipse/ShapeLine/ ShapePolygon/ShapeArrow) with uppercase shortcuts; shape-tool drag on empty space commits shape.add+shape.select as one undo step, on an existing object it grabs and moves it (per-delta shape.move in one group); click selects via pixel-exact hit-test; Delete removes the selected shape; arrow-key nudge moves the selected shape over pixels; render.rs draws a selection outline; toolbar gained a "Vector shapes" group; Flickable/toolbar width grew to 2000px; test window widened to 2400px (the real app scrolls the toolbar).
  • Pivots (Mode A corrections): the toolbar's "Selection" group loop (i >= 10) started matching the new tools — narrowed to i == 10 || 11; toolbar width pinned at 1360px clipped the palette — raised with the Flickable.
  • Tests: 4 new GUI tests (per-tool add+select, click-select/drag-move, delete+nudge, shape-over-pixel nudge priority). 403 workspace tests.

2026-09-22T17:00:00+08:00 — Task 6 complete (CLI parity)

  • crates/cli/tests/automation.rs: shape scripts render byte-identically across runs and equal their raster-equivalent PNGs through the real binary.

2026-09-22T16:50:00+08:00 — Tasks 4 and 5 complete (vocabulary + engine)

  • Implemented: six command variants (ShapeAdd with optional id, ShapeEdit, ShapeMove, ShapeRemove, ShapeSelect, ShapeSelectClear); kind-based shape.add/edit parser/serializer with canonical text; registry entries (Category::Shape) — palette/autocomplete cover them for free; EngineState.selected_shape; apply arms with max+1 id assignment, duplicate/missing-id typed errors, remove-clears- selection; engine tests for AC5/AC6.
  • Parser VARIANT_COUNT 36 → 42; registry table + exhaustive match extended.

2026-09-22T16:20:00+08:00 — Tasks 1-3 complete (raster extraction, shape model, document integration)

  • Task 1: crates/core/src/raster.rs (new) — bresenham_points, ellipse_points, rect_points (extracted from the engine's RectDraw arm so shapes and the raster command share one implementation), regular_polygon/sin_cos_fixed, polygon_points, arrow_head_points, isqrt; engine + selection call through the module. Pure move: 376 tests unchanged.
  • Task 2: crates/core/src/shapes.rs (new) — Shape/ShapeGeometry (rect/ellipse/line/polygon/arrow), points/bounds/translate/covers, hit_test (topmost-first, pixel-exact), rasterize_shape, hash_bytes for content hashing. Tests pin byte-identity with the raster commands.
  • Task 3: Document gains shapes (render order, above the raster stack in composite() — GUI, CLI, and eyedropper all agree), add/remove/ shape_mut with DuplicateShapeId/NoSuchShape errors, content_hash covers shapes. Existing pinned sample hashes unchanged.
  • Tests: 387 passed / 0 failed. Build 0 warnings. Mode used: A.

2026-09-22T15:35:00+08:00 — Session start

  • Plan PLAN.md locked by maintainer. Session-1 PROGRESS.md archived to Plans/archive/PROGRESS-phase2-session1.md; session-1 work committed as d77810b.
  • Baseline: 376 tests pass, 0 warnings.
  • Dependencies: all confirmed in PLAN.md — no new crates required.

Current Blockers

None.

Backlog (out-of-scope items discovered during execution)

(empty)

Resumption

None — session complete. Next: Phase 2 session 2B (guides, snapping, grid & symmetry tools) or 2C (annotations), at the maintainer's call.


AUTOPILOT: Session complete.

Tasks completed: 9 / 9 Acceptance criteria: 10 / 10 passed Modes used: A (all tasks) Files modified: PLAN.md, PROGRESS.md, ROADMAP.md, BACKLOG.md, README.md, crates/core/src/{raster,shapes}.rs (new), crates/core/src/{lib,command,parser,registry,engine, document}.rs, crates/core/tests/vector_demo.rs (new), crates/cli/tests/automation.rs, crates/app/src/{controller,main,render}.rs, crates/app/ui/common/{home_toolbar}.slint, crates/app/ui/{linux,macos}/chrome.slint, docs/samples/vector_demo.pxcproj (new), docs/design/ui-roadmap-mapping.md Backlog items: 5 — see BACKLOG.md, Phase 2 session 2A deferrals Regressions found: none

2026-09-22T12:30:00+08:00 — Zoom readout feature (post-Phase 1.75 request)

  • The zoom percentage readout in both chrome trees is now a clickable ZoomPicker: type a custom zoom percentage (Enter or "Go" applies, clamped to the controller's 1x-32x bounds) with a suggestion list that filters by prefix while typing and shows everything until edited, so opening it never presents an empty box.
  • Suggestion ordering per the maintainer's spec, unit-tested in crates/app/src/zoom.rs: 3 most frequent, 2 most recent (skipping duplicates), 5 defaults where the first is configurable via Settings -> Basic -> "Zoom suggestions default", then 100/200/500/2000, duplicates skipped, list capped at 10.
  • Zoom usage (wheel, Fit, 1:1, custom entry, suggestion picks) is recorded into a persisted zoom_history (frequency + recency); writes are throttled to once per 2s and flushed on window close.
  • Three real bugs caught during the work, all documented in commits:
    1. main.slint silently failed to forward the new callbacks (an earlier scripted edit missed after Phase 2's additions) - the picker rendered but was inert. Found by isolating the chain: UI click -> callback -> Rust handler.
    2. The suggestion list looked empty on open because it filtered by the pre-filled current zoom; fixed with a "dirty" flag.
    3. A consecutive-duplicate dedup in record_zoom ate legitimate re-applies; frequency should count every use, so the dedup was removed.
  • 8 new tests (5 GUI, 3 zoom.rs units + settings round-trip). 416 tests pass, 0 warnings.