Files
vectorcraft/crates/engine/src/interaction.rs
T
dotCooCoo a17acb852f Selection: Show Bounding Box While Moving and Drawing shows the box during moves and shape drawing
The new General preference Show Bounding Box While Moving and Drawing
(`boundingBoxWhileMovingAndDrawing`, off by default) keeps the bounding
box and its handles visible during two kinds of drag, with View › Show
Bounding Box on. While a drag moves the selection (a Selection tool
move, an Alt-drag copy, or a shape tool's move by the center point),
the box is drawn where the drag has moved the selection. The box is
measured once when the drag starts and offset by each step's move.
While the Rectangle, Rounded Rectangle, Ellipse, Polygon and Star tools
draw a shape, the box is drawn around the shape. A rotation and a
widget drag still hide the box until the release. The Line Segment
tool, the Pen, the Pencil and the Paintbrush draw no box.

With the preference off, the box hides during a move (#737, for #712)
and while a shape is drawn (#5839), as before. A Selection tool move
with Real-time Drawing off still moves the box with the pointer, and a
shape tool's move by the center point hides it in both modes.

With Real-time Drawing off, the box of a shape being drawn is measured
from the pending preview, in the color of the layer the shape goes on.
A shape being drawn shows no box until a preview step has succeeded,
so a failed preview does not show the box of the selection from before
the drag. The preference's label has a row in every catalog.

Session::deferred_move() is replaced by Session::move_drag_box(), which
returns the moved box, and Session::deferred_transform_box() now also
returns the layer color of the box.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-12 08:28:21 -08:00

103 lines
5.5 KiB
Rust

use super::{Affine, Arc, Document, NodeId, Selection, Value};
/// An in-progress drag: the snapshot the previews are applied to.
#[derive(Clone, Debug)]
pub struct Interaction {
pub label: String,
pub doc: Arc<Document>,
/// The selection the previews start from (shared, so a preview frame copies nothing).
pub selection: Arc<Selection>,
pub preview: Option<(String, Value)>,
/// A replaced or canceled preview restores these new-art paints from before the interaction.
pub(crate) paint: vectorcraft_tools::PaintDefaults,
/// An accepted batch preview uses these final paints after changing the document color mode.
pub(crate) preview_paint: Option<vectorcraft_tools::PaintDefaults>,
/// Conversion of new-art paints waits until a color-mode preview is accepted.
pub(crate) deferred_color_mode: Option<crate::cmd::colormgmt::DeferredColorMode>,
pub(crate) color_mode_paints: Option<(vectorcraft_tools::PaintDefaults, vectorcraft_tools::PaintDefaults)>,
/// Per-document state restored on cancel (current layer, highlighted Layers panel rows,
/// isolation).
pub active_layer: Option<NodeId>,
pub layer_rows: Vec<NodeId>,
pub variables_highlight: Option<String>,
pub isolation: Option<NodeId>,
/// The perspective transform the previews make (`perspective.transform` params): Transform
/// Again repeats it once the drag is committed.
pub perspective_again: Option<Value>,
/// A transform or a perspective edit with `copy` keeps the copies it made of the snapshot here
/// ([`PreviewCopies`]).
pub(crate) copies: Option<Arc<PreviewCopies>>,
/// The bounding box of `selection` in `doc`, measured once for a move drag
/// ([`crate::Session::move_drag_box`]): each step offsets it by the drag's move.
pub(crate) move_box: std::sync::OnceLock<Option<vectorcraft_doc::OrientedBox>>,
}
/// What Object → Transform → Transform Again (⌘D) repeats ([`SessionState::last_transform`]).
#[derive(Clone, Debug, PartialEq)]
pub enum LastTransform {
/// The last transform command's matrix, and the options Transform Again passes with it.
Matrix(Affine, Value),
/// The last Transform Each's parameters: each object transforms about its own bounds, so the
/// repeat runs the command on the selection of the moment rather than one matrix.
Each(Value),
}
/// This holds the copies that a transform or a perspective edit with `copy` made of an
/// interaction's snapshot ([`cmd::object::apply_transform`]; `persp_edit` and `plane_move` in
/// `cmd::distortcmds`). A later transform or perspective edit with `copy` of the same objects,
/// while the document is still that snapshot, starts from `doc` and transforms only the copies.
#[derive(Debug)]
pub(crate) struct PreviewCopies {
/// The copies were made from this snapshot.
pub(crate) from: Arc<Document>,
/// The transform or perspective edit copied these objects.
pub(crate) roots: Vec<NodeId>,
/// This is `from` with the copies added, untransformed.
pub(crate) doc: Arc<Document>,
/// This is the selection after copying, with the copies selected.
pub(crate) selection: Selection,
/// These are the copies' ids, in the order of `roots`.
pub(crate) ids: Vec<NodeId>,
}
/// An open undo group ([`Session::begin_undo_group`]): the edits made in it are one undo step.
#[derive(Clone, Debug)]
pub struct UndoGroup {
/// The new-art paints from before the group's first command.
pub(crate) paint: vectorcraft_tools::PaintDefaults,
/// The document before the group's first edit, as the undo step that edit recorded keeps it.
pub(crate) first: Option<Arc<Document>>,
/// The numbers of the journal entries made in the group's document while it was open: a canceled
/// group drops them. An entry that changed the active document has the index of the document it
/// left active, and a canceled group turns it into that change.
pub(crate) journal: Vec<(usize, Option<usize>)>,
/// For each `command.batch` entry in `journal`, the steps of its `commands` that belong to the
/// group (by number), each with the index of the document it left active when it changed the
/// active document: a canceled group drops those steps and keeps the batch's other ones.
pub(crate) steps: Vec<BatchSteps>,
/// The undo step's name; else the first edit's.
pub(crate) label: Option<String>,
}
/// A `command.batch` journal entry's number and the steps of it that belong to an undo group, each
/// with the index of the document it left active when it changed the active document
/// ([`UndoGroup::steps`]).
pub(crate) type BatchSteps = (usize, Vec<(usize, Option<usize>)>);
/// One undo step begun with [`Session::begin_undo_scope`], which [`Session::end_undo_scope`] ends.
#[derive(Clone, Debug)]
pub struct UndoScope {
/// The document ([`DocState::uid`]).
pub(crate) uid: u64,
/// The journal's length when the scope began.
pub(crate) journal: usize,
/// When the document's undo group was open already: the document, its selection and the document
/// that the group's undo step keeps, as they were when the scope began; `None` when the scope
/// opened the group.
pub(crate) joined: Option<(Arc<Document>, Selection, Option<Arc<Document>>)>,
/// The new-art colors and the group's color-mode history metadata at the scope's start.
/// Only used when cancelling a joined scope that converted those colors.
pub(crate) paint: vectorcraft_tools::PaintDefaults,
pub(crate) color_mode_paints: Option<(vectorcraft_tools::PaintDefaults, vectorcraft_tools::PaintDefaults)>,
}