mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-02 14:16:56 -06:00
Add-ons: Path Precision Tools — Corner Tool and Slide Anchor
Path Precision Tools gains two tools, kept out of the toolbars (All Tools drawer and Object › Plug-ins › Path Precision Tools, no shortcuts): - Corner Tool (cornerTool): editable corners on any path through the existing Live Corners. Hover shows an eligible anchor, a click cuts a corner with the tool's radius and kind, a drag sizes it (Shift: whole values), a corner's marker selects it and loads its values, resizes it and removes it at 0 or on a double-click; a corner never grows past what fits; an Alt-marquee cuts every eligible anchor inside. - Corners section in the Anchor Inspector: radius, kind, selected count, Apply to Selected Anchors. - Slide Anchor Along Path (slideAnchor): a drag runs an anchor along its curve, the neighbouring segments refitted by the keep-shape kernel; Shift snaps where the tangent is a multiple of 45° from the constrain angle. - Commands addon.pathtools.cornerSet, cornerRemove and slideAnchor, one undo step each, params validated and covered by the command sweep. - Cursor stand-ins, catalog rows in every language, docs and tests.
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
use vectorcraft_doc::AnchorRef;
|
||||
use vectorcraft_geom::PathData;
|
||||
|
||||
use super::spans::Span;
|
||||
use super::{
|
||||
BTreeSet, CornerKind, EngineError, LiveCorners, LiveShape, NodeId, NodeKind, Result, Session, Value, bad, check_numbers, check_switches,
|
||||
@@ -249,17 +252,29 @@ pub(super) fn set_live_shape(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
Some(k) => k.clone(),
|
||||
None => c.picked(partial.as_deref()),
|
||||
};
|
||||
let (selected, layout) = (partial.as_deref().map(|a| c.corners_of(a)), c.sources().to_vec());
|
||||
set_corners(path, live, &picked, radius, kind);
|
||||
// Direct-Selected corners stay selected as they gain or lose anchors.
|
||||
if let (Some(anchors), Some(selected)) = (partial, selected)
|
||||
&& let Some(c) = LiveCorners::new(path, live.as_deref())
|
||||
&& c.sources() != layout
|
||||
{
|
||||
*anchors = c.anchors_of(&selected);
|
||||
}
|
||||
recut(path, live, partial, &picked, radius, kind);
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
ok()
|
||||
}
|
||||
|
||||
/// [`set_corners`] with the Direct-Selected corners (`partial`, the path's selected anchors)
|
||||
/// staying selected as they gain or lose anchors.
|
||||
pub(in crate::cmd) fn recut(
|
||||
path: &mut PathData,
|
||||
live: &mut Option<Box<LiveShape>>,
|
||||
partial: Option<&mut BTreeSet<AnchorRef>>,
|
||||
picked: &BTreeSet<usize>,
|
||||
radius: Option<f64>,
|
||||
kind: Option<CornerKind>,
|
||||
) {
|
||||
let before = LiveCorners::new(path, live.as_deref()).map(|c| (partial.as_deref().map(|a| c.corners_of(a)), c.sources().to_vec()));
|
||||
set_corners(path, live, picked, radius, kind);
|
||||
if let (Some(anchors), Some((Some(selected), layout))) = (partial, before)
|
||||
&& let Some(c) = LiveCorners::new(path, live.as_deref())
|
||||
&& c.sources() != layout
|
||||
{
|
||||
*anchors = c.anchors_of(&selected);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user