openpencil/crates/openpencil-shell-core/src/lib.rs
Kayshen-X bb321f115c feat(shell-core,shell-native): map Jian PointerEvent to ShellEvent (Step 1a Task 3)
Phase B Task 3 implementation per spec v19 §5.1 + §5.1.1 (FROZEN
2026-05-04):

shell-core:
- New `event` module declaring `ShellEvent` (6 variants per spec §5.1)
  + sub-types `PointerId / TouchId / TouchPhase / TouchForce /
    MouseButton / ElementState / ScrollDelta / Modifiers / KeyCode /
    WindowEventKind`. Pure OP types — no winit / Jian / GL — so the
  enum is wasm32-clean and visible on iOS / Android (spec §11.3).
- TouchForce::Calibrated mirrors winit::Force 1:1 (spec §11.3
  invariant) so Step 1f mobile mapper compiles without API break.
- Newtype id fields are `pub` so shell-native can construct them across
  crates (spec round 3 BLOCK-R3-4 fix).

shell-native:
- New `event` module (cfg-gated desktop only) housing
  `JianPointerMapper` — stateful diff over the per-PointerId
  `MouseButtons` snapshot. Diff runs on Down / Up / Move (spec round 3
  CONCERN-R3-1 fix); Hover / Move emits a trailing `PointerMove`.
- Touch branch maps Down/Move/Up/Cancel → Started/Moved/Ended/Cancelled;
  Touch Hover returns `Vec::new()` (touches never hover).
- Mouse / Pen / Stylus / Trackpad share the same diff branch.
- Degraded inputs (no button transition + no Move emission) return
  `Vec::new()` instead of synthesising a `ShellEvent::Other` variant
  (spec round 4 CONCERN-R4-1 fix; the enum stays at exactly 6 variants).

Tests:
- 15 new unit tests in shell-native/tests/event_mapping.rs covering
  the 4 Touch phases, mouse Hover, LEFT Down/Up pair, multi-button
  press/release during Move, Pen/Stylus/Trackpad routing, two
  degraded-empty paths, and modifiers propagation (CMD → meta).
- 3 new shape tests in shell-core/tests/event_shape.rs proving the
  6-variant invariant + TouchForce::Calibrated field shape +
  `pub`-field newtype constructibility.

Verified:
- `cargo test -p openpencil-shell-core -p openpencil-shell-native`
  green (36 tests total across both crates).
- `cargo check --target wasm32-unknown-unknown -p openpencil-shell-core`
  green; shell-web on wasm32 still compiles with the new module pulled
  through.
- `cargo check --target aarch64-apple-ios -p openpencil-shell-native`
  + `--target aarch64-linux-android -p openpencil-shell-native` both
  green (mapper cfg-gated out of mobile).
- `cargo metadata --filter-platform aarch64-linux-android` confirms
  jian-host-desktop / jian-skia not in the Android dep tree.
- §11.1 grep: 0 actual `use winit/skia_safe/glutin/...` items in
  shell-core (only doc-comment references).
- `cargo clippy --all-targets` clean; `cargo fmt --check` clean.
2026-05-05 21:48:00 +08:00

29 lines
1.4 KiB
Rust

//! OpenPencil shell core — platform-agnostic widget facade + RenderBackend trait.
//!
//! Per spec v19 §1.2 (FROZEN 2026-05-04): this crate must compile on
//! wasm32-unknown-unknown. winit / accesskit_winit / skia-safe live in
//! `openpencil-shell-native`; wasm-bindgen / web-sys / CanvasKit live in
//! `openpencil-shell-web`.
//!
//! v19 pivot — this crate is a thin Jian wrapper:
//! - the [`jian`] module re-exports `jian_core::render::{DrawOp, Paint, TextRun, …}`
//! + geometry/scene aliases for shell-native's internal translation (widget code never sees them).
//! - the [`render_backend`] module defines OP's own widget-facing facade
//! (`RenderBackend` trait + `Rect` / `Color` / `TextLayout`, spec §5.2).
//! - the [`event`] module declares OP's `ShellEvent` enum + sub-types
//! (spec §5.1). Widget code consumes these on every platform; the
//! desktop Jian/winit → ShellEvent mapper lives in
//! `openpencil-shell-native::event` (target-gated to desktop today;
//! Step 1f extends to mobile).
pub mod event;
pub mod jian;
pub mod render_backend;
// Re-export the primary API for upstream crates / widgets / tests.
pub use event::{
ElementState, KeyCode, Modifiers, MouseButton, PointerId, ScrollDelta, ShellEvent, TouchForce,
TouchId, TouchPhase, WindowEventKind,
};
pub use render_backend::{Color, Point2D, Rect, RenderBackend, TextLayout};