mirror of
https://github.com/storytold/photocraft.git
synced 2026-10-14 19:26:51 -04:00
Selection tools: ⌥ with nothing selected draws a new selection
With #1106's engine change, subtract or intersect with no selection selects nothing. The UI turned ⌥ (and ⇧⌥) into subtract (intersect) even with nothing selected, so ⌥-dragging a marquee or lasso on a clean canvas would select nothing; in Photoshop ⌥ then only draws the marquee from its centre. A modifier-made subtract or intersect is now a new selection when nothing is selected; an options-bar Subtract or Intersect is kept, and the cursor badge follows. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01UHgFEHEsefoQoBParH47JA
This commit is contained in:
3 files changed
+36
-1
No files matched your search
@@ -2928,7 +2928,7 @@ pub fn extra_windows(app: &mut PhotocraftApp, ctx: &egui::Context) {
|
||||
/// Selection mode from the options bar, overridden by modifier keys (⇧ add, ⌥ subtract, ⇧⌥ intersect).
|
||||
/// The cursor badge announces the same mode (`tool_feedback`).
|
||||
pub(crate) fn selection_mode(app: &PhotocraftApp, m: egui::Modifiers) -> &'static str {
|
||||
crate::tool_feedback::selection_mode(Tool::Lasso, app.ui.selection_mode, m)
|
||||
crate::tool_feedback::document_selection_mode(app, Tool::Lasso, m)
|
||||
}
|
||||
|
||||
/// A polygonal lasso click adds a vertex; clicking near the first vertex closes the polygon. The
|
||||
|
||||
@@ -303,3 +303,25 @@ fn cmd_alt_drag_floats_a_copy() {
|
||||
assert!(alpha(&d, 12, 20) == 1.0, "the original stays");
|
||||
assert!(alpha(&d, 50, 20) == 1.0, "the copy dropped 25 px right");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn alt_with_nothing_selected_draws_a_new_selection() {
|
||||
// #1106: with no selection, ⌥ has nothing to subtract from, so a marquee drawn with it held
|
||||
// still selects (Photoshop: ⌥ then only draws from the centre). With a selection it subtracts.
|
||||
let mut h = harness(Tool::RectMarquee);
|
||||
mods(&mut h, Modifiers::ALT);
|
||||
press_at(&mut h, 100.0, 100.0, Modifiers::ALT);
|
||||
move_to(&mut h, 140.0, 130.0);
|
||||
release_at(&mut h, 140.0, 130.0, Modifiers::ALT);
|
||||
mods(&mut h, Modifiers::NONE);
|
||||
assert!(h.state().session.active().unwrap().doc.selection.as_ref().is_some_and(|s| !s.content_bounds().is_empty()), "a selection was made");
|
||||
// Now ⌥ subtracts from it.
|
||||
let before = selection(&h);
|
||||
mods(&mut h, Modifiers::ALT);
|
||||
press_at(&mut h, 0.0, 0.0, Modifiers::ALT);
|
||||
move_to(&mut h, 400.0, 400.0);
|
||||
release_at(&mut h, 400.0, 400.0, Modifiers::ALT);
|
||||
mods(&mut h, Modifiers::NONE);
|
||||
let after = h.state().session.active().unwrap().doc.selection.as_ref().map(|s| s.content_bounds());
|
||||
assert!(after.is_none_or(|r| r.is_empty() || r != before), "⌥ subtracted: {before:?} -> {after:?}");
|
||||
}
|
||||
@@ -82,6 +82,19 @@ pub fn selection_mode(tool: Tool, bar: u8, m: egui::Modifiers) -> &'static str {
|
||||
}
|
||||
}
|
||||
|
||||
/// [`selection_mode`] for the active document: with nothing selected, ⌥ (or ⇧⌥) has nothing to
|
||||
/// subtract from or intersect with, so it draws a new selection, as in Photoshop (where ⌥ then
|
||||
/// only draws a marquee from its centre). An options-bar Subtract or Intersect is kept (#1106).
|
||||
pub fn document_selection_mode(app: &PhotocraftApp, tool: Tool, m: egui::Modifiers) -> &'static str {
|
||||
let mode = selection_mode(tool, app.ui.selection_mode, m);
|
||||
let selected = app.session.active().and_then(|st| st.doc.selection.as_ref()).is_some_and(|s| !s.content_bounds().is_empty());
|
||||
if m.alt && !selected && matches!(mode, "subtract" | "intersect") && selection_mode(tool, app.ui.selection_mode, egui::Modifiers::NONE) == "replace" {
|
||||
"replace"
|
||||
} else {
|
||||
mode
|
||||
}
|
||||
}
|
||||
|
||||
/// The badge the cursor of `tool` shows with modifiers `m` (None for non-selection tools or New).
|
||||
pub fn badge(app: &PhotocraftApp, tool: Tool, m: egui::Modifiers) -> Option<Badge> {
|
||||
if !is_selection_tool(tool) {
|
||||
|
||||
Reference in new issue
Block a user