Skip to main content

teksilo_scene/
lib.rs

1// SPDX-License-Identifier: MPL-2.0
2// SPDX-FileCopyrightText: 2026 FernTech
3
4//! `teksilo-scene` — pannable / zoomable scene viewport for Teksilo.
5//!
6//! A sub-toolkit for **scene-based applications** — story corkboards,
7//! mind maps, node-graph editors, timeline views — where content is
8//! free-positioned at scene coordinates instead of placed by a layout
9//! algorithm. Two tiers of content coexist under one view transform:
10//!
11//! - **Heavyweight tier:** any `Widget` (Button, TextInput, Panel,
12//!   composite components) at a parent-relative position, fully
13//!   interactive and accessible, with full event / focus / animation /
14//!   a11y machinery intact.
15//! - **Lightweight tier:** [`SceneItem`]s (paths, rects, images,
16//!   custom paint) without arena overhead — for the "background
17//!   furniture" of a scene where thousands of items render cheaply.
18//!
19//! The crate is built on top of teksilo-core's per-node `set_transform`
20//! scope (which composes through hit-test, paint, and a11y) and the
21//! platform's pinch / scroll / animated-`Signal<f32>` infrastructure
22//! — so OS gestures, reduced-motion snapping, and the four-gate idle
23//! scheduler fall out for free.
24//!
25//! See [`docs/teksilo-scene.md`](https://github.com/ferntech-eu/teksilo/blob/main/docs/teksilo-scene.md)
26//! for the user-facing reference and
27//! [`docs/teksilo-scene-a11y.md`](https://github.com/ferntech-eu/teksilo/blob/main/docs/teksilo-scene-a11y.md)
28//! for the accessibility-shaping API.
29//!
30//! ## Quick start
31//!
32//! ```ignore
33//! use teksilo_scene::{ItemId, RectItem, Scene, SceneView};
34//! use teksilo_canvas::{Point, Rect};
35//!
36//! let mut scene = Scene::new();
37//! let _w: ItemId = scene.add_widget(
38//!     my_card_widget(),
39//!     Rect::new(0.0, 0.0, 200.0, 120.0),
40//! );
41//! scene.add_item(
42//!     RectItem::new(Rect::new(0.0, 0.0, 50.0, 50.0)).fill(teksilo_tokens::Color::RED),
43//!     Point::new(220.0, 0.0),
44//! );
45//! let view = SceneView::new(scene);
46//! tree.add(view);
47//! ```
48
49#![allow(clippy::type_complexity)]
50
51// Implementation modules are intentionally `pub(crate)`. The crate's
52// public surface is the re-export block below — every type or trait
53// an external consumer is meant to use is reachable as
54// `teksilo_scene::Foo` (never `teksilo_scene::flags::Foo` etc). Narrowing
55// here lets internal refactors land without ripple effects in
56// downstream apps. Adding a new external-facing type? Re-export it
57// rather than widening a module to `pub`.
58pub(crate) mod a11y;
59pub(crate) mod animation;
60pub(crate) mod cache;
61pub(crate) mod constrain;
62pub(crate) mod flags;
63pub(crate) mod index;
64pub(crate) mod item;
65pub(crate) mod item_handlers;
66pub(crate) mod items;
67pub(crate) mod journal;
68pub(crate) mod magnet;
69pub(crate) mod minimap;
70pub(crate) mod pick;
71pub(crate) mod salvage;
72pub(crate) mod scene;
73pub(crate) mod scene_card;
74pub(crate) mod scene_list_adapter;
75pub(crate) mod scene_model;
76pub(crate) mod scroll_view;
77pub(crate) mod selection;
78pub(crate) mod shape;
79pub(crate) mod state;
80pub(crate) mod transform;
81pub(crate) mod transform_session;
82pub(crate) mod view;
83
84pub use a11y::{
85    A11yCategory, A11yGroup, A11yGroupBuilder, A11yGroupId, A11yMode, A11yNode, A11yOffScreenMode,
86    A11yRelation,
87};
88pub use animation::{pulse_once, register_animated_item_signal};
89pub use cache::CacheMode;
90pub use constrain::{ChangeVerdict, ProposedChange};
91pub use flags::ItemFlags;
92pub use index::{GridHashIndex, SpatialIndex};
93pub use item::{AppearanceWrite, ItemId, SceneItem, SceneItemA11yContext, SceneItemPaintContext};
94pub use item_handlers::{DragMode, SceneItemHandlerSet, SceneTapEvent};
95pub use items::AccessSubtreeMode;
96pub use items::{GroupItem, ImageItem, PathItem, RectItem, TextAlign, TextItem};
97pub use journal::{
98    ChangeSource, HistoryMode, Salvage, SceneChange, SceneEdit, SceneTransactionRecord, TxnId,
99    TxnOutcome,
100};
101pub use magnet::{
102    Magnet, MagnetConnection, MagnetFeedback, MagnetId, MagnetMarker, MagnetRef, MagnetRole,
103    MagnetSnap, MagnetVerdict, MagnetVisualState, MagnetismConfig, MarkerVisibility,
104};
105pub use minimap::{MinimapReadout, SceneMinimap};
106pub use pick::{PaintKey, RANK_OVER, RANK_UNDER, RANK_WIDGET, claims_press, hit_testable};
107pub use salvage::{
108    ItemA11yDecorations, RemovedItem, ReplaceItemError, ReplaceRejected, RestoreError,
109};
110pub use scene::Scene;
111pub use scene::{
112    AppearanceChange, CascadeBudget, HandlerReplacement, ItemChange, ItemPayload, PanAxes,
113    Placement, SceneConstraints, SceneLayer, SizePolicy,
114};
115pub use scene_card::{CardMode, SceneCard};
116pub use scene_list_adapter::SceneListAdapter;
117pub use scene_model::{SceneModel, SceneTransaction, SceneWriteGuard, WeakSceneModel};
118pub use scroll_view::{SceneScrollView, ScrollBarMode, ScrollBarPolicy};
119pub use selection::{SceneSelection, SceneSelectionMode};
120pub use shape::{
121    HIT_BAND_SLACK, ItemSelectionMode, ItemShape, SHAPE_FLATTEN_TOLERANCE, SceneRegion,
122    ShapeGeometry,
123};
124pub use state::SceneViewState;
125pub use transform_session::{
126    DEFAULT_EDGE_PAN_PX, DEFAULT_EDGE_PAN_SPEED, DEFAULT_HANDLE_PX, DEFAULT_PADDING_PX,
127    LivePreview, ROTATE_OFFSET_PX, TransformChrome, TransformConfig, TransformDelta,
128    TransformFrame, TransformHandle, TransformHandleSet, TransformLabels, TransformOp,
129    TransformOutcome, TransformSession, TransformSource, TransformStep,
130};
131pub use view::paint_node::{WetLayer, WetNode};
132pub use view::{DEFAULT_RETENTION_MARGIN, DebugOverlay, FocusDirection, SceneView};