mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-14 14:41:52 +00:00
Shape Builder, Live Paint Selection: hover highlights go when the pointer leaves the canvas
The Shape Builder had no hover_ended, so when the pointer left the canvas (for a panel, out of the window, under a menu or dialog), the region or stroke highlight and the Cursor Swatch Preview chips stayed where the pointer was last seen. A map of a large selection that arrived afterwards also highlighted the region under that old point again. When the hover ends, the tool now drops the highlight, the stroke a click would split and the preview, and forgets the point. The Live Paint Selection tool had the same gap: its face or edge highlight now goes too.
This commit is contained in:
@@ -676,6 +676,14 @@ impl Tool for ShapeBuilderTool {
|
||||
self.finish_edit(cx)
|
||||
}
|
||||
|
||||
/// The pointer hovers nothing for the tool: its highlight, the stroke a click would split and
|
||||
/// the cursor swatch preview go, and a map that arrives afterwards highlights nothing.
|
||||
fn hover_ended(&mut self, _cx: &ToolContext) {
|
||||
self.hover = None;
|
||||
self.stroke = None;
|
||||
self.at = None;
|
||||
}
|
||||
|
||||
fn poll(&mut self, cx: &ToolContext, wait: bool) -> Vec<Action> {
|
||||
let mut acts = self.poll_merge(cx, wait);
|
||||
if !acts.is_empty() || self.dragging {
|
||||
|
||||
@@ -700,6 +700,11 @@ impl Tool for LivePaintSelectionTool {
|
||||
vec![]
|
||||
}
|
||||
|
||||
/// The pointer hovers nothing for the tool: its highlight goes.
|
||||
fn hover_ended(&mut self, _cx: &ToolContext) {
|
||||
self.hover = LpHover::None;
|
||||
}
|
||||
|
||||
fn overlays(&self, cx: &ToolContext) -> Vec<Overlay> {
|
||||
if let Some(r) = self.drag.and_then(|d| d.marquee(cx)) {
|
||||
return vec![Overlay::Marquee(r)];
|
||||
|
||||
@@ -920,6 +920,43 @@ fn shape_builder_shift_drag_shows_no_scissors_or_stroke_highlight() {
|
||||
assert_eq!(t.cursor(&cx, Point::new(75.0, 75.0), shift), Cursor::ShapeBuilder);
|
||||
}
|
||||
|
||||
/// When the pointer leaves the canvas, the Shape Builder's region or stroke highlight and its
|
||||
/// cursor swatch preview go.
|
||||
#[test]
|
||||
fn shape_builder_hover_ended_drops_the_highlight_and_the_swatch_preview() {
|
||||
let (d, s) = corner_rects();
|
||||
let p = paint();
|
||||
let cx = cx(&d, &s, &p);
|
||||
let mut t = ShapeBuilderTool::default();
|
||||
for (key, v) in [("pickColorFrom", json!("swatches")), ("cursorSwatchPreview", json!(true)), ("clickStrokeSplitsPath", json!(true))] {
|
||||
t.set_option(key, &v);
|
||||
}
|
||||
// Over a region, then over a stroke a click would split.
|
||||
for (x, y) in [(25.0, 25.0), (-1.0, 25.0)] {
|
||||
t.pointer(&cx, &ev(PointerKind::Move, x, y));
|
||||
let ov = t.overlays(&cx);
|
||||
assert!(ov.iter().any(|o| matches!(o, Overlay::Swatch { .. })) && ov.iter().any(|o| matches!(o, Overlay::Path { .. })), "{ov:?}");
|
||||
t.hover_ended(&cx);
|
||||
assert!(t.overlays(&cx).is_empty());
|
||||
}
|
||||
}
|
||||
|
||||
/// A map of a large selection that arrives after the pointer leaves the canvas highlights nothing
|
||||
/// under the point where the pointer was last seen.
|
||||
#[test]
|
||||
fn shape_builder_map_arriving_after_hover_ended_highlights_nothing() {
|
||||
let (d, s) = square_row(40);
|
||||
let p = paint();
|
||||
let cx = ToolContext { revision: (1, 1), ..cx(&d, &s, &p) };
|
||||
let mut t = ShapeBuilderTool::default();
|
||||
t.pointer(&cx, &ev(PointerKind::Move, 15.0, 10.0));
|
||||
assert!(t.waiting() && t.hover.is_none(), "the map is built on another thread");
|
||||
t.hover_ended(&cx);
|
||||
t.poll(&cx, true);
|
||||
assert!(!t.waiting());
|
||||
assert!(t.hover.is_none() && t.overlays(&cx).is_empty(), "{:?}", t.hover);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shape_builder_stroke_options_round_trip_and_pick_the_side_under_the_pointer() {
|
||||
let (d, s) = corner_rects();
|
||||
@@ -1548,6 +1585,21 @@ fn live_paint_selection_hover_builds_no_map_of_the_selection() {
|
||||
assert!(!t.waiting());
|
||||
}
|
||||
|
||||
/// When the pointer leaves the canvas, the Live Paint Selection tool's highlight goes.
|
||||
#[test]
|
||||
fn live_paint_selection_hover_ended_drops_the_highlight() {
|
||||
let (d, ..) = live_group_doc();
|
||||
let s = Selection::default();
|
||||
let p = paint();
|
||||
let cx = cx(&d, &s, &p);
|
||||
let mut t = LivePaintSelectionTool::default();
|
||||
t.pointer(&cx, &ev(PointerKind::Move, 75.0, 25.0));
|
||||
let ov = t.overlays(&cx);
|
||||
assert!(ov.iter().any(|o| matches!(o, Overlay::Path { .. })), "{ov:?}");
|
||||
t.hover_ended(&cx);
|
||||
assert!(t.overlays(&cx).is_empty());
|
||||
}
|
||||
|
||||
/// A Live Paint Selection click pressed with `down`: the press does nothing, and the release does
|
||||
/// what is returned.
|
||||
fn lp_click(t: &mut LivePaintSelectionTool, cx: &ToolContext, down: PointerEvent) -> Vec<Action> {
|
||||
|
||||
Reference in New Issue
Block a user