mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-09 10:47:27 +00:00
Gradient: a dropped or canceled point drag keeps the point selected
A drag that takes a selected freeform gradient point out of the object previews its removal, which deselects it. A dropped press now selects again the point that was selected once the tool took the press, and Escape reselects a point dragged out and back inside the object.
This commit is contained in:
@@ -206,6 +206,9 @@ pub struct Session {
|
||||
/// The id and persistent options of the tool when the press under way began, which a dropped
|
||||
/// press puts back ([`Session::drop_tool_press`]).
|
||||
pub(crate) press_options: Option<(String, serde_json::Map<String, serde_json::Value>)>,
|
||||
/// The freeform gradient point selected once the tool took the press under way, which a
|
||||
/// dropped press selects again ([`Session::drop_tool_press`]).
|
||||
pub(crate) press_point: Option<Option<(usize, cmd::gradient::StopOwner)>>,
|
||||
/// A guide being dragged out of a ruler ([`Session::ruler_guide`]).
|
||||
pub(crate) ruler_guide: Option<vectorcraft_tools::rulerguide::NewGuide>,
|
||||
/// Which selected type overflows its frame, for the ports every tool but the Type tools shows.
|
||||
|
||||
@@ -93,6 +93,7 @@ impl Session {
|
||||
plane_widget_press: false,
|
||||
pointer_held: false,
|
||||
press_options: None,
|
||||
press_point: None,
|
||||
ruler_guide: None,
|
||||
port_marks: Default::default(),
|
||||
font_search: None,
|
||||
|
||||
@@ -331,3 +331,29 @@ fn type_objects_keep_points_in_text_space() {
|
||||
assert!(close(f.points[i].at, Point::new(90.0, 150.0)), "back in document coordinates: {:?}", f.points[i].at);
|
||||
assert_eq!(f.points[i].color, Color::rgb(1.0, 0.0, 1.0));
|
||||
}
|
||||
|
||||
/// A dropped press (a long touch, a canceled touch) of the Gradient tool that dragged a selected
|
||||
/// point out of the object, and out and back in, keeps the point and its selection.
|
||||
#[test]
|
||||
fn a_dropped_drag_of_a_point_keeps_it_selected() {
|
||||
use vectorcraft_tools::{PointerEvent, PointerKind};
|
||||
let (mut s, id) = freeform_rect();
|
||||
let v = ViewInfo::default();
|
||||
s.select_tool("gradient", v).unwrap();
|
||||
let count = points(&s, id).points.len();
|
||||
assert!(count > 1, "a point can be dragged out");
|
||||
let at = s.proxy_freeform(false).unwrap().0.points[0].at;
|
||||
for back in [false, true] {
|
||||
run(&mut s, "paint.freeform.selectPoint", json!({"index": 0}));
|
||||
s.pointer(&PointerEvent::new(PointerKind::Down, at.x, at.y), v).unwrap();
|
||||
s.pointer(&PointerEvent::new(PointerKind::Drag, 400.0, 400.0), v).unwrap();
|
||||
assert_eq!(s.selected_freeform_point(), None, "the removal the drag previews deselects the point");
|
||||
if back {
|
||||
s.pointer(&PointerEvent::new(PointerKind::Drag, at.x + 5.0, at.y + 5.0), v).unwrap();
|
||||
}
|
||||
s.drop_tool_press(v).unwrap();
|
||||
assert!(!s.tool_busy(), "the tool is at rest");
|
||||
assert_eq!(points(&s, id).points.len(), count, "back inside: {back}");
|
||||
assert_eq!(s.selected_freeform_point(), Some(0), "back inside: {back}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,16 +366,22 @@ impl Session {
|
||||
/// Escape, as during a drag, for most tools), and a release returns the tool to rest. Of what
|
||||
/// the tool asks for along the way, only a cancel and a notify run, so a marquee selects
|
||||
/// nothing and a click opens no size dialog. The tool gets back the persistent options it had
|
||||
/// when the press began, and none of the press's changes to them are stored.
|
||||
/// when the press began, and none of the press's changes to them are stored. The freeform
|
||||
/// gradient point selected once the tool took the press is selected again.
|
||||
pub fn drop_tool_press(&mut self, view: ViewInfo) -> Result<()> {
|
||||
// Nothing to roll back without a document; the tool still drops the press and gets the release.
|
||||
let _ = self.cancel_interaction();
|
||||
let before = self.press_options.take();
|
||||
let point = self.press_point.take();
|
||||
let mut acts = self.with_tool_cx(view, |t, cx| t.drop_press(cx));
|
||||
acts.retain(|a| matches!(a, Action::Cancel | Action::Notify(_)));
|
||||
let dropped = self.take_tool_panic().and_then(|()| self.apply_actions(acts));
|
||||
let up = PointerEvent { kind: PointerKind::Up, pos: Point::ZERO, mods: Mods::default(), backquote: false, pressure: 1.0, pen: None };
|
||||
let r = dropped.and(self.pointer_event(&up, view, false));
|
||||
// A drag out of the object previews the point's removal, which deselects it.
|
||||
if let Some(p) = point {
|
||||
self.freeform_point = p;
|
||||
}
|
||||
if let Some((id, opts)) = before
|
||||
&& id == self.tool.id()
|
||||
{
|
||||
@@ -428,6 +434,11 @@ impl Session {
|
||||
}
|
||||
self.apply_actions(acts)
|
||||
});
|
||||
match ev.kind {
|
||||
PointerKind::Down => self.press_point = Some(self.freeform_point),
|
||||
PointerKind::Up => self.press_point = None,
|
||||
_ => {}
|
||||
}
|
||||
if ev.kind == PointerKind::Up {
|
||||
self.give_back_tool(view)?;
|
||||
}
|
||||
|
||||
@@ -274,10 +274,11 @@ pub(super) fn release(cx: &ToolContext, a: Option<&Annotator>, g: Gesture, lines
|
||||
}
|
||||
}
|
||||
|
||||
/// Escape during a drag: the point a drag-out deselected is selected again.
|
||||
/// Escape during a drag: the point a drag-out deselected is selected again, also when the drag
|
||||
/// came back inside the object.
|
||||
pub(super) fn cancel(g: &Gesture) -> Vec<Action> {
|
||||
match g.grab {
|
||||
Grab::Point(i) if g.out => vec![Action::Cancel, select(Some(i))],
|
||||
Grab::Point(i) if g.left => vec![Action::Cancel, select(Some(i))],
|
||||
_ => vec![Action::Cancel],
|
||||
}
|
||||
}
|
||||
@@ -499,6 +500,11 @@ mod tests {
|
||||
t.pointer(&cx, &ev(PointerKind::Down, 120.0, 120.0));
|
||||
t.pointer(&cx, &ev(PointerKind::Drag, 60.0, 60.0));
|
||||
assert_eq!(t.key(&cx, ToolKey::Escape, Default::default()), vec![Action::Cancel, select(Some(0))]);
|
||||
// Also after the drag came back inside.
|
||||
t.pointer(&cx, &ev(PointerKind::Down, 120.0, 120.0));
|
||||
t.pointer(&cx, &ev(PointerKind::Drag, 60.0, 60.0));
|
||||
t.pointer(&cx, &ev(PointerKind::Drag, 110.0, 110.0));
|
||||
assert_eq!(t.key(&cx, ToolKey::Escape, Default::default()), vec![Action::Cancel, select(Some(0))]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user