mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-09 01:28:22 +00:00
address review: same distance test in width profile lower bound; preview the whole drag when a symbolism tool deactivates
This commit is contained in:
committed by
bflatastic
parent
13b0bbe639
commit
fc83e5c5b9
@@ -90,7 +90,8 @@ impl WidthProfile {
|
||||
/// discontinuous point (two points at `t`, within `1e-7`).
|
||||
pub fn around(&self, t: f64) -> ((f64, f64), (f64, f64)) {
|
||||
let p = &self.points;
|
||||
let i = p.partition_point(|q| q.0 < t - 1e-7);
|
||||
// The same distance test below, so a point exactly 1e-7 before `t` is never skipped by rounding.
|
||||
let i = p.partition_point(|q| q.0 < t && (q.0 - t).abs() > 1e-7);
|
||||
if let Some(first) = p.get(i).filter(|q| (q.0 - t).abs() <= 1e-7) {
|
||||
let j = i + p[i..].partition_point(|q| q.0 - first.0 <= 1e-9) - 1;
|
||||
if j > i {
|
||||
@@ -353,5 +354,8 @@ mod tests {
|
||||
// Many points at one position are one step, found without a pass over them all.
|
||||
let many = WidthProfile { points: (0..1000).map(|i| (0.5, i as f64, i as f64)).collect() };
|
||||
assert_eq!(many.around(0.5), ((0.0, 0.0), (999.0, 999.0)));
|
||||
// 0.4999999 == 0.5 - 1e-7, yet its distance from 0.5 rounds above 1e-7: it is not part of the step.
|
||||
let near = WidthProfile { points: vec![(0.4999999, 2.0, 2.0), (0.5, 1.0, 1.0), (0.5, 0.5, 0.25)] };
|
||||
assert_eq!(near.around(0.5), ((1.0, 1.0), (0.5, 0.25)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,6 +117,19 @@ impl SymbolismTool {
|
||||
}
|
||||
}
|
||||
|
||||
impl SymbolismTool {
|
||||
/// Ends the drag: what is committed is the last preview, so the whole drag is shown first.
|
||||
fn finish(&mut self, cx: &ToolContext) -> Vec<Action> {
|
||||
self.active = false;
|
||||
let stale = (self.previewed != self.points.len()).then(|| {
|
||||
let (c, v) = self.command(cx);
|
||||
Action::Preview(c, v)
|
||||
});
|
||||
self.points.clear();
|
||||
stale.into_iter().chain([Action::Commit]).collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl Tool for SymbolismTool {
|
||||
fn id(&self) -> &'static str {
|
||||
self.id
|
||||
@@ -151,16 +164,7 @@ impl Tool for SymbolismTool {
|
||||
let (c, v) = self.command(cx);
|
||||
vec![Action::Preview(c, v)]
|
||||
}
|
||||
PointerKind::Up if self.active => {
|
||||
self.active = false;
|
||||
// What is committed is the last preview: show the whole drag first.
|
||||
let stale = (self.previewed != self.points.len()).then(|| {
|
||||
let (c, v) = self.command(cx);
|
||||
Action::Preview(c, v)
|
||||
});
|
||||
self.points.clear();
|
||||
stale.into_iter().chain([Action::Commit]).collect()
|
||||
}
|
||||
PointerKind::Up if self.active => self.finish(cx),
|
||||
_ => vec![],
|
||||
}
|
||||
}
|
||||
@@ -182,11 +186,9 @@ impl Tool for SymbolismTool {
|
||||
}
|
||||
vec![]
|
||||
}
|
||||
fn deactivate(&mut self, _cx: &ToolContext) -> Vec<Action> {
|
||||
fn deactivate(&mut self, cx: &ToolContext) -> Vec<Action> {
|
||||
if self.active {
|
||||
self.active = false;
|
||||
self.points.clear();
|
||||
return vec![Action::Commit];
|
||||
return self.finish(cx);
|
||||
}
|
||||
vec![]
|
||||
}
|
||||
@@ -335,6 +337,23 @@ mod tests {
|
||||
assert_eq!(up.last(), Some(&Action::Commit));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn switching_tools_mid_drag_previews_the_whole_drag_before_committing() {
|
||||
let (d, _) = doc_with_rect();
|
||||
let (s, p) = (Selection::default(), paint());
|
||||
let cx = cx(&d, &s, &p);
|
||||
let mut t = SymbolismTool::new("symbolShifter");
|
||||
t.pointer(&cx, &PointerEvent::new(PointerKind::Down, 0.0, 0.0));
|
||||
let n = 7 * crate::PREVIEW_ALL_UNTIL + 1; // not a point that previews
|
||||
for i in 1..n {
|
||||
t.pointer(&cx, &PointerEvent::new(PointerKind::Drag, 50.0 * i as f64, 0.0));
|
||||
}
|
||||
let a = t.deactivate(&cx);
|
||||
assert!(matches!(a.first(), Some(Action::Preview(_, v)) if v["points"].as_array().unwrap().len() == n), "{a:?}");
|
||||
assert_eq!(a.last(), Some(&Action::Commit));
|
||||
assert!(!t.busy());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn adjust_tools_map_to_symbol_adjust() {
|
||||
let (d, _) = doc_with_rect();
|
||||
|
||||
Reference in New Issue
Block a user