Shape drags only read the modifiers held at the press, so pressing Shift mid-drag (the usual way) didn't square a rectangle or keep a polygon's proportions, and Alt mid-drag didn't draw from the centre. They now follow the modifiers held at each pointer event, like the marquees. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
74c7980146
commit
1ae11a4bb1
|
|
@ -2293,7 +2293,7 @@ fn draw_drag_preview(app: &mut PhotocraftApp, painter: &egui::Painter, xf: &View
|
|||
trail.feed(&d.points, app.session.tools.brush.size);
|
||||
trail.draw(painter, doc_rect, xf.flip, col);
|
||||
}
|
||||
t if crate::vector_ui::is_shape_tool(t) => crate::vector_ui::draw_shape_preview(app, painter, xf, t, d.start, last, d.modifiers),
|
||||
t if crate::vector_ui::is_shape_tool(t) => crate::vector_ui::draw_shape_preview(app, painter, xf, t, d.start, last, d.live),
|
||||
Tool::RectMarquee | Tool::EllipseMarquee | Tool::ObjectSelection => {
|
||||
// Marching ants, visible on any pixels (#172).
|
||||
let (a, b) = marquee.unwrap_or((d.start, last));
|
||||
|
|
@ -2714,7 +2714,7 @@ pub(crate) fn finish_gesture(app: &mut PhotocraftApp, d: Drag) {
|
|||
}
|
||||
match d.tool {
|
||||
Tool::ObjectSelection => crate::retouch_ui::finish_object_selection(app, d.start, [end[0], end[1]], d.modifiers),
|
||||
t if crate::vector_ui::is_shape_tool(t) => crate::vector_ui::finish_shape(app, t, d.start, [end[0], end[1]], d.modifiers),
|
||||
t if crate::vector_ui::is_shape_tool(t) => crate::vector_ui::finish_shape(app, t, d.start, [end[0], end[1]], d.live),
|
||||
Tool::PathSelection => crate::vector_ui::path_selection_finish(app, d.start, [end[0], end[1]]),
|
||||
Tool::Type | Tool::VerticalType => crate::type_tool::pointer_up(app, d.start, [end[0], end[1]]),
|
||||
Tool::Brush | Tool::Pencil | Tool::Eraser => {
|
||||
|
|
|
|||
|
|
@ -938,6 +938,30 @@ mod tests {
|
|||
assert_eq!(app.session.active().unwrap().doc.layers.len(), 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shift_pressed_during_a_shape_drag_constrains_it() {
|
||||
// #668: ⇧ only counted when held at the press; Photoshop constrains when it is pressed
|
||||
// mid-drag (and stops when it is released).
|
||||
use crate::canvas::{ToolEvent, tool_event};
|
||||
for (tool, sides) in [(Tool::Polygon, 6), (Tool::Rectangle, 4), (Tool::EllipseShape, 0)] {
|
||||
let mut app = app();
|
||||
app.ui.tool = tool;
|
||||
app.ui.tool_options.polygon_sides = 6;
|
||||
let none = egui::Modifiers::NONE;
|
||||
tool_event(&mut app, ToolEvent::Down { x: 10.0, y: 10.0, pressure: 1.0 }, none);
|
||||
tool_event(&mut app, ToolEvent::Move { x: 40.0, y: 30.0, pressure: 1.0 }, none);
|
||||
tool_event(&mut app, ToolEvent::Move { x: 70.0, y: 40.0, pressure: 1.0 }, egui::Modifiers::SHIFT);
|
||||
tool_event(&mut app, ToolEvent::Up { x: 70.0, y: 40.0 }, egui::Modifiers::SHIFT);
|
||||
let st = app.session.active().unwrap();
|
||||
let l = st.doc.layer(st.active_layer.unwrap()).unwrap();
|
||||
assert!(matches!(l.content, LayerContent::Shape(_)), "{tool:?} ({sides} sides): a shape layer");
|
||||
let b = l.surface().unwrap().content_bounds();
|
||||
// The drag is 60 × 30; constrained, the shape's box is 60 × 60 (a hexagon is narrower
|
||||
// than its box, so the height tells).
|
||||
assert!(b.height().abs_diff(60) <= 1 && b.width() <= 61, "{tool:?}: ⇧ mid-drag keeps proportions: {b:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shape_preview_is_the_committed_path() {
|
||||
let mut app = app();
|
||||
|
|
|
|||
Loading…
Reference in New Issue