mirror of
https://github.com/storytold/figcraft.git
synced 2026-10-28 20:36:55 -06:00
refactor(engine): simplify canvas and board handlers
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
use super::derived::{ends_now, place_route, route};
|
||||
use super::edit::set_label;
|
||||
use super::items::add;
|
||||
use super::*;
|
||||
use super::{
|
||||
BoardItem, Connector, Document, End, LINE, LINE_WEIGHT, NodeId, NodeKind, Paint, Point, Result, Session, Side, StrokeCap, StrokeJoin, Value,
|
||||
VectorNetwork, bad, cap_of, get, id_of, json, num, req_targets, require, routing_of, string,
|
||||
};
|
||||
|
||||
/// One connector end from the params: a layer on this page, or a point.
|
||||
fn end_param(cmd: &str, s: &Session, p: &Value, key: &str, side_key: &str) -> Result<End> {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
use super::edit::set_font_size;
|
||||
use super::items::{owner_of_text, shape_padding, sticky_font_size, text_of};
|
||||
use super::*;
|
||||
use super::{
|
||||
Affine, BTreeSet, BezPath, BoardItem, Connector, Document, End, NodeId, NodeKind, PathEl, Point, Rect, Routing, Shape, Side, Vec2, VectorNetwork,
|
||||
is_board,
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
// Derived data (the normalize pass).
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
use super::connectors::connector_of;
|
||||
use super::derived::ends_now;
|
||||
use super::items::{add, add_text, shape_padding, text_of};
|
||||
use super::*;
|
||||
use super::{
|
||||
Affine, AutoLayout, BTreeMap, BoardItem, BoardShape, Color, Connector, DocError, Document, End, INK, NodeId, NodeKind, Paint, Result, Routing,
|
||||
Session, Sizing, StrokeCap, TextAlignH, TextAutoResize, TextData, Value, VectorNetwork, bad, cap_of, color_param, json, line_shade, num,
|
||||
req_string, req_targets, require, routing_of, shape_of, string,
|
||||
};
|
||||
|
||||
/// The label of connector `id`, if it has one.
|
||||
pub fn label_of(doc: &Document, id: NodeId) -> Option<NodeId> {
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
use super::*;
|
||||
use super::{
|
||||
AUTHOR_INK, Affine, AutoLayout, BlendMode, BoardItem, BoardShape, Color, Constraints, CrossAlign, Document, Effect, EffectKind, EngineError,
|
||||
HConstraint, HIGHLIGHTER, INK, LayoutMode, MARKER, MainAlign, Node, NodeId, NodeKind, Paint, Result, SHAPE, STAMP_SIZE, STICKY, STICKY_GAP,
|
||||
STICKY_PAD, Session, Shadow, Sizing, StrokeAlign, StrokeCap, StrokeJoin, TextAlignH, TextAutoResize, TextData, VConstraint, Value, VectorNetwork,
|
||||
author, bad, boolean, color_param, get, id, id_of, json, line_shade, num, num_or, parent_of, req_num, require, shape_of, stamp_of, string,
|
||||
textedit,
|
||||
};
|
||||
|
||||
/// A new layer at the top of `parent`, at `at` in it, made by `f`.
|
||||
pub(super) fn add(
|
||||
|
||||
@@ -2,7 +2,10 @@ use super::connectors::{end_json, other_end};
|
||||
use super::derived::ends_now;
|
||||
use super::edit::label_of;
|
||||
use super::items::edit_text;
|
||||
use super::*;
|
||||
use super::{
|
||||
BoardItem, Document, ERASER_PX, End, EngineError, Gesture, NodeId, Point, PointerEvent, Result, SHAPE, STICKY, Session, Side, ToolId, id_of,
|
||||
is_board, json,
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
// The board tools.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! Where something dropped at a page point lands: the frame under the point (or the page) and, in
|
||||
//! an auto layout frame, the child slot by pointer position plus the insertion line to draw.
|
||||
|
||||
use figcraft_doc::*;
|
||||
use figcraft_doc::{Document, LayoutMode, NodeId, NodeKind};
|
||||
use figcraft_geom::Point;
|
||||
use serde::Serialize;
|
||||
|
||||
|
||||
@@ -21,14 +21,14 @@
|
||||
use std::collections::BTreeSet;
|
||||
use std::sync::Arc;
|
||||
|
||||
use figcraft_doc::*;
|
||||
use figcraft_doc::{Corners, Document, Node, NodeId, NodeKind, StrokeProps, VectorNetwork, WindingRule};
|
||||
use figcraft_geom::kurbo::PathEl;
|
||||
use figcraft_geom::{Affine, BezPath, Point, Rect, Shape};
|
||||
use serde_json::{Value, json};
|
||||
|
||||
use crate::cmd::CommandSpec;
|
||||
use crate::cmd::edit::{roots, z_sorted};
|
||||
use crate::params::*;
|
||||
use crate::params::{f64_of, get, string, targets};
|
||||
use crate::tools::{Cursor, Gesture, PointerEvent, PointerKind, ToolId};
|
||||
use crate::{EngineError, Result, Session, bad, spec};
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ use std::collections::BTreeMap;
|
||||
|
||||
use figcraft_color::{ImageScaleMode, PaintKind};
|
||||
use figcraft_doc::geometry::select_target;
|
||||
use figcraft_doc::*;
|
||||
use figcraft_doc::{Document, LayoutMode, Node, NodeId, NodeKind, Sizing, StrokeAlign, StrokeCap, TextAutoResize, TextData, TextPath, VectorNetwork};
|
||||
use figcraft_geom::{Affine, Point, Rect, Vec2};
|
||||
use serde::Serialize;
|
||||
use serde_json::json;
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
use super::handles::{PATH_REACH_PX, label_at, locked_in, path_candidates, readable_text_fills};
|
||||
use super::*;
|
||||
use super::{
|
||||
Affine, Document, Gesture, Node, NodeId, NodeKind, Point, PointerEvent, Rect, Result, Session, Sizing, TextAutoResize, TextData, TextPath,
|
||||
ToolId, frame_at, json, select_target, textedit, within_slop,
|
||||
};
|
||||
|
||||
impl Session {
|
||||
/// Handle a double-click gesture: finish a pen path, rename or click labels/widgets,
|
||||
|
||||
@@ -2,7 +2,11 @@ use super::handles::{
|
||||
SNAP_PX, handle_at, in_quad, label_at, locked_in, on_corner_square, paints_below, resized_box, scale_factor, selection_box, selection_frame,
|
||||
shape_hint,
|
||||
};
|
||||
use super::*;
|
||||
use super::{
|
||||
Affine, ArcHandle, ArcHint, Cursor, Document, Gesture, Guide, Handle, ImageScaleMode, LayoutMode, NodeId, NodeKind, PaintKind, Point,
|
||||
PointerEvent, Rect, ResizeStart, Result, ScaleHint, Session, Sizing, Targets, TextAutoResize, ToolId, Vec2, move_world, roots, select_target,
|
||||
textedit, within_slop,
|
||||
};
|
||||
|
||||
impl Session {
|
||||
pub(super) fn move_down(&mut self, ev: &PointerEvent) -> Result<()> {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
use super::handles::SNAP_PX;
|
||||
use super::pen::take_enclosed;
|
||||
use super::*;
|
||||
use super::{
|
||||
Affine, Cursor, Gesture, Node, NodeId, NodeKind, Point, PointerEvent, Rect, Result, Session, StrokeCap, Targets, ToolId, Vec2, frame_at, textedit,
|
||||
};
|
||||
|
||||
impl Session {
|
||||
pub(super) fn draw_down(&mut self, ev: &PointerEvent) -> Result<()> {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use super::*;
|
||||
use super::{Affine, BTreeMap, Cursor, Document, Handle, NodeId, NodeKind, Point, ShapeHandle, ShapeHint, roots};
|
||||
|
||||
/// The frame whose name label (see [`ToolState::labels`]) is under `p` on `page`: the topmost
|
||||
/// one drawn, if it can be selected (still there, on the page, visible and unlocked).
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use super::*;
|
||||
use super::{Document, Gesture, Node, NodeId, Overlay, Point, PointerEvent, PointerKind, Result, Session, ShapeHandle, ToolId, json, textedit};
|
||||
|
||||
impl Session {
|
||||
/// Keys the current mode handles before menu shortcuts (vector edit mode's tools and point
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
use super::handles::{PENCIL_STROKE, selected_end_at};
|
||||
use super::*;
|
||||
use super::{
|
||||
Affine, Document, Gesture, Guide, Node, NodeId, NodeKind, PenPath, Point, PointerEvent, Result, Session, StrokeAlign, ToolId, Vec2,
|
||||
VectorNetwork, at_45_degrees, frame_at, json, pen_handles,
|
||||
};
|
||||
|
||||
/// Pen pressure along drawn samples as width profile points `[t, scale]`: `t` by length, at most
|
||||
/// 32 points, medium pressure (0.5) at the stroke weight, from a tenth to twice it. `None` when no
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
use super::handles::{handle_at, label_at, locked_in, on_corner_square, resize_cursor, selected_end_at};
|
||||
use super::*;
|
||||
use super::{
|
||||
Cursor, Document, Gesture, NodeId, NodeKind, Overlay, PenCursor, Point, PointerEvent, PointerKind, Rect, Result, Session, ToolId, at_45_degrees,
|
||||
frame_at, json, select_target,
|
||||
};
|
||||
|
||||
impl Session {
|
||||
/// The pointer left the canvas: what hovering there showed goes (the distances Alt or Dev Mode
|
||||
|
||||
@@ -24,14 +24,14 @@ mod width_sides_tests;
|
||||
#[cfg(test)]
|
||||
mod width_tests;
|
||||
|
||||
use figcraft_doc::*;
|
||||
use figcraft_doc::{Corners, Document, HandleMirroring, NodeId, NodeKind, StrokeAlign, StrokeCap, StrokeJoin, VectorNetwork, Vertex, WindingRule};
|
||||
use figcraft_geom::{Affine, Point, Rect, Vec2};
|
||||
use serde::Serialize;
|
||||
use serde_json::{Value, json};
|
||||
|
||||
use crate::cmd::CommandSpec;
|
||||
use crate::cmd::props::enum_of;
|
||||
use crate::params::*;
|
||||
use crate::params::{boolean, f64_of, get, id, num, num_or, req_num, string, targets};
|
||||
use crate::{EngineError, Result, Session, bad, spec};
|
||||
|
||||
pub(crate) use pointer::VGesture;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//! deleting, cutting and joining. Pure functions on a [`VectorNetwork`]; the session wrappers in
|
||||
//! `vectoredit.rs` re-fit the node afterwards.
|
||||
|
||||
use figcraft_doc::*;
|
||||
use figcraft_doc::{HandleMirroring, Region, Segment, VectorNetwork, Vertex, WindingRule};
|
||||
use figcraft_geom::kurbo::{CubicBez, ParamCurve, ParamCurveNearest};
|
||||
use figcraft_geom::{Affine, Point, Vec2};
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use figcraft_doc::*;
|
||||
use figcraft_doc::{Document, HandleMirroring, NodeId, NodeKind, VectorNetwork, Vertex};
|
||||
use figcraft_geom::{Affine, Point, Rect, Vec2};
|
||||
|
||||
use super::point_snap;
|
||||
@@ -510,20 +510,25 @@ impl Session {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Another edited layer under the press (or, with the paint bucket, whose area it is in).
|
||||
fn pressed_layer(doc: &Document, ve: &VectorEdit, ev: &PointerEvent, tol: f64) -> Option<NodeId> {
|
||||
match hit_any(doc, ve, ev.p(), tol) {
|
||||
Some((id, _)) => Some(id),
|
||||
None if ve.tool == VTool::Paint => {
|
||||
let inside = |id: NodeId| network(doc, id).is_some_and(|n| n.face_at(doc.world_transform(id).inverse() * ev.p()).is_some());
|
||||
(!inside(ve.id)).then(|| ve.others.iter().map(|o| o.id).find(|id| inside(*id))).flatten()
|
||||
}
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns false when the click left edit mode (the caller then runs the normal tool).
|
||||
fn vector_down(&mut self, ve: &VectorEdit, ev: &PointerEvent) -> Result<bool> {
|
||||
let doc = self.doc()?.clone();
|
||||
let tol = 6.0 / ev.zoom.max(1e-6);
|
||||
// A press on another edited layer's point, handle or segment (or, with the paint bucket,
|
||||
// area) makes it the active layer; a pen drawing a path keeps to its own layer.
|
||||
let other = match hit_any(&doc, ve, ev.p(), tol) {
|
||||
Some((id, _)) => Some(id),
|
||||
None if ve.tool == VTool::Paint => {
|
||||
let inside = |id: NodeId| network(&doc, id).is_some_and(|n| n.face_at(doc.world_transform(id).inverse() * ev.p()).is_some());
|
||||
(!inside(ve.id)).then(|| ve.others.iter().map(|o| o.id).find(|id| inside(*id))).flatten()
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
let other = Self::pressed_layer(&doc, ve, ev, tol);
|
||||
let switched;
|
||||
let ve = match other {
|
||||
Some(id) if id != ve.id && !(ve.tool == VTool::Pen && ve.anchor.is_some()) => {
|
||||
|
||||
@@ -11,7 +11,7 @@ use serde_json::{Value, json};
|
||||
|
||||
use super::{VHit, VTool, VectorEdit, default_points, edit, editing, indices, network, ops, selected_points, selection_position};
|
||||
use crate::cmd::CommandSpec;
|
||||
use crate::params::*;
|
||||
use crate::params::{boolean, f64_of, get, num, num_or, req_num};
|
||||
use crate::tools::{Handle, handle_at_corners};
|
||||
use crate::{Result, Session, bad, spec};
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
//! The points live in the stroke's [`WidthProfile`] and apply to every subpath (positions are
|
||||
//! fractions of each subpath's length).
|
||||
|
||||
use figcraft_doc::*;
|
||||
use figcraft_doc::{Document, NodeId, WidthProfile, WidthSide};
|
||||
use figcraft_geom::{Point, Vec2};
|
||||
use figcraft_pathops::width::{Polyline, nearest, polylines};
|
||||
use serde::Serialize;
|
||||
@@ -18,7 +18,7 @@ use serde_json::{Value, json};
|
||||
|
||||
use super::{editing, set_state};
|
||||
use crate::cmd::CommandSpec;
|
||||
use crate::params::*;
|
||||
use crate::params::{get, num, req_index, req_num, string};
|
||||
use crate::tools::{Gesture, PointerEvent};
|
||||
use crate::{Result, Session, bad, spec};
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ use serde_json::{Value, json};
|
||||
use super::*;
|
||||
use crate::EngineError;
|
||||
use crate::tools::{PointerEvent, PointerKind};
|
||||
use figcraft_doc::{ExportFormat, WidthSide};
|
||||
|
||||
fn ex(s: &mut Session, c: &str, p: Value) -> Value {
|
||||
s.execute(c, &p).unwrap_or_else(|e| panic!("{c}: {e}"))
|
||||
|
||||
@@ -6,6 +6,7 @@ use serde_json::{Value, json};
|
||||
use super::*;
|
||||
use crate::EngineError;
|
||||
use crate::tools::{PointerEvent, PointerKind};
|
||||
use figcraft_doc::{ExportFormat, WidthPreset, WidthProfile, WidthSide};
|
||||
|
||||
fn ex(s: &mut Session, c: &str, p: Value) -> Value {
|
||||
s.execute(c, &p).unwrap_or_else(|e| panic!("{c}: {e}"))
|
||||
|
||||
Reference in New Issue
Block a user