Merge pull request #6273 from dotCooCoo/fix/tool-options-reload-keep-drag

Tools: setting another tool's option leaves a drag's options alone
This commit is contained in:
BFlat
2026-11-09 11:43:23 +08:00
committed by GitHub
2 changed files with 35 additions and 1 deletions
+22
View File
@@ -268,6 +268,28 @@ fn escape_on_a_shape_drag_saves_the_option_it_put_back() {
assert_eq!(s.prefs.corner_radius, radius);
}
/// Setting another tool's option during a polygon drag leaves the drag's options alone: Escape
/// still puts back the side count the arrow changed.
#[test]
fn escape_puts_back_the_sides_after_another_tool_s_option_is_set() {
use vectorcraft_tools::{Mods, PointerEvent, PointerKind, ToolKey};
let mut s = session();
let v = ViewInfo { smart_guides: false, ..Default::default() };
select(&mut s, "polygon");
s.pointer(&PointerEvent::new(PointerKind::Down, 100.0, 100.0), v).unwrap();
s.pointer(&PointerEvent::new(PointerKind::Drag, 200.0, 180.0), v).unwrap();
s.tool_key(ToolKey::Up, Mods::default(), v).unwrap();
// Saves every option, the one the arrow changed included.
s.set_tool_option("length", &json!(50));
let values = json!({"points": 9});
s.set_tool_options(Some("star"), values.as_object().unwrap());
assert_eq!(s.tool_options()["sides"], json!(7), "the drag keeps its side count");
s.tool_key(ToolKey::Escape, Mods::default(), v).unwrap();
assert_eq!(s.tool_options()["sides"], json!(6));
assert_eq!(s.prefs.tool_settings["polygon"]["sides"], json!(6));
assert_eq!(s.prefs.tool_settings["star"]["points"], json!(9));
}
/// The Fidelity an Alt smoothing drag uses on a selected path.
fn alt_smooth_fidelity(s: &mut Session) -> Option<f64> {
use vectorcraft_tools::{Action, Mods, PointerEvent, PointerKind};
+13 -1
View File
@@ -257,7 +257,15 @@ impl Session {
/// Give `t` the persistent options stored for it in `prefs`.
fn restore_tool_settings(prefs: &Prefs, t: &mut dyn Tool) {
Self::restore_stores(prefs, t, |_| true);
}
/// Give `t` the persistent options stored for it in `prefs`, from the stores `wanted` accepts.
fn restore_stores(prefs: &Prefs, t: &mut dyn Tool, wanted: impl Fn(&str) -> bool) {
for (store, keys) in settings::stores(t.id()) {
if !wanted(store) {
continue;
}
let Some(saved) = prefs.tool_settings.get(store) else { continue };
for k in keys {
if let Some(v) = saved.get(*k) {
@@ -267,6 +275,7 @@ impl Session {
}
// Alt switches the Pencil, Paintbrush or Blob Brush to Smooth, using Smooth Tool Options' Fidelity.
if matches!(t.id(), "pencil" | "paintbrush" | "blobBrush")
&& wanted("smooth")
&& let Some(v) = prefs.tool_settings.get("smooth").and_then(|s| s.get("fidelity"))
{
t.set_option("smoothFidelity", v);
@@ -907,7 +916,10 @@ impl Session {
}
Self::restore_tool_settings(&self.prefs, lender);
}
Self::restore_tool_settings(&self.prefs, self.tool.as_mut());
// Only the stores it shares with the tool set: the active tool's own options stay as they
// are, also in the middle of a drag that Escape can cancel.
let set = other.id();
Self::restore_stores(&self.prefs, self.tool.as_mut(), |store| settings::stores(set).any(|(s, _)| s == store));
}
out
}