Keep the selection when smart selection finds nothing (#2235)
* Keep the selection when smart selection finds nothing Select Subject and Object Selection run heuristics that often miss on busy photos. In Replace mode an empty result cleared the selection, so the Select Subject button looked dead and even destroyed existing work. apply() now preserves the selection and reports changed:false in every mode. The UI also answers visibly instead of staying silent: empty smart-selection results set an info status suggesting what to try next, and a click with Object Selection falls back to a Quick Selection dab at the brush size instead of doing nothing. * Translate the smart-selection status messages; drop needless borrows (clippy) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Brandon Thomas <echelon@gmail.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
5e481cde02
commit
39c97c9be0
|
|
@ -60,8 +60,12 @@ pub(crate) fn with_doc_sampler<R>(doc: &Document, layer: Option<LayerId>, all_la
|
|||
}
|
||||
|
||||
/// Stores `region` combined with the current selection by `m` as one history step.
|
||||
/// Finding nothing never destroys work: the selection (and history) is left alone and the
|
||||
/// caller gets `changed: false`, whatever the mode. (Select Subject and Object Selection run
|
||||
/// heuristics that often find nothing on busy photos; clearing the selection then looks like
|
||||
/// a dead button.)
|
||||
fn apply(s: &mut Session, label: &str, region: Option<Region>, m: SelectionMode) -> Result<Value> {
|
||||
if region.is_none() && matches!(m, SelectionMode::Add | SelectionMode::Subtract) {
|
||||
if region.is_none() {
|
||||
// Nothing found: leave the selection (and history) alone.
|
||||
let selected = s.active().ok_or(EngineError::NoDocument)?.doc.selection.is_some();
|
||||
return Ok(json!({ "selected": selected, "changed": false }));
|
||||
|
|
@ -388,6 +392,27 @@ mod tests {
|
|||
assert!(cov(&s, 10, 10) >= 0.5 && cov(&s, 100, 50) < 0.5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_result_keeps_the_selection_in_every_mode() {
|
||||
// Finding nothing must never wipe the selection, whatever the mode: Select Subject
|
||||
// and Object Selection run heuristics that often miss on busy photos, and a missed
|
||||
// Quick Selection dab must not destroy the work either.
|
||||
for m in ["add", "subtract", "replace"] {
|
||||
let mut s = two_regions(8);
|
||||
s.execute("select.all", json!({})).unwrap();
|
||||
let r = s.execute("select.quick", json!({"points": [[-5000, -5000]], "size": 8, "mode": m})).unwrap();
|
||||
assert_eq!(r["changed"], false, "mode {m}");
|
||||
assert_eq!(r["selected"], true, "mode {m}");
|
||||
assert!(cov(&s, 10, 50) >= 0.99, "mode {m}: Select All survived an empty result");
|
||||
}
|
||||
// Select Subject on a flat field finds nothing and keeps the selection too.
|
||||
let mut s = session_with(140, 100, 8, |_, _| [0.5, 0.5, 0.5]);
|
||||
s.execute("select.all", json!({})).unwrap();
|
||||
let r = s.execute("select.subject", json!({})).unwrap();
|
||||
assert_eq!(r["changed"], false);
|
||||
assert!(cov(&s, 10, 10) >= 0.99);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn object_selection_disc() {
|
||||
for depth in [8, 16, 32] {
|
||||
|
|
|
|||
|
|
@ -2356,3 +2356,7 @@ fontWeight Italic Kurzíva
|
|||
XOR XOR
|
||||
Color Burn (Paint.NET) Ztmavit barvy (Paint.NET)
|
||||
Color Dodge (Paint.NET) Zesvětlit barvy (Paint.NET)
|
||||
No subject found — try Object Selection or the Lasso Nebyl nalezen žádný objekt — zkuste Výběr objektu nebo Laso
|
||||
Quick Selection found nothing there Rychlý výběr zde nic nenašel
|
||||
Object Selection found nothing there — try a tighter rectangle Výběr objektu zde nic nenašel — zkuste těsnější obdélník
|
||||
No subject found — try a rectangle around the object Nebyl nalezen žádný objekt — zkuste obdélník kolem objektu
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
|
|
@ -2395,3 +2395,7 @@ fontWeight Italic Kursiv
|
|||
XOR XOR
|
||||
Color Burn (Paint.NET) Farbig nachbelichten (Paint.NET)
|
||||
Color Dodge (Paint.NET) Farbig abwedeln (Paint.NET)
|
||||
No subject found — try Object Selection or the Lasso Kein Motiv gefunden — versuchen Sie das Objektauswahlwerkzeug oder das Lasso
|
||||
Quick Selection found nothing there Die Schnellauswahl hat dort nichts gefunden
|
||||
Object Selection found nothing there — try a tighter rectangle Die Objektauswahl hat dort nichts gefunden — versuchen Sie ein engeres Rechteck
|
||||
No subject found — try a rectangle around the object Kein Motiv gefunden — versuchen Sie ein Rechteck um das Objekt
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
|
|
@ -3467,3 +3467,7 @@ fontWeight Thin Πολύ λεπτά
|
|||
XOR XOR
|
||||
Color Burn (Paint.NET) Κάψιμο χρώματος (Paint.NET)
|
||||
Color Dodge (Paint.NET) Φωτισμός χρώματος (Paint.NET)
|
||||
No subject found — try Object Selection or the Lasso Δεν βρέθηκε θέμα — δοκιμάστε την Επιλογή αντικειμένου ή το Λάσο
|
||||
Quick Selection found nothing there Η Γρήγορη επιλογή δεν βρήκε τίποτα εκεί
|
||||
Object Selection found nothing there — try a tighter rectangle Η Επιλογή αντικειμένου δεν βρήκε τίποτα εκεί — δοκιμάστε ένα πιο στενό ορθογώνιο
|
||||
No subject found — try a rectangle around the object Δεν βρέθηκε θέμα — δοκιμάστε ένα ορθογώνιο γύρω από το αντικείμενο
|
||||
|
|
|
|||
|
Can't render this file because it has a wrong number of fields in line 5.
|
|
|
@ -2424,3 +2424,7 @@ fontWeight Italic Cursiva
|
|||
XOR XOR
|
||||
Color Burn (Paint.NET) Sobreexponer color (Paint.NET)
|
||||
Color Dodge (Paint.NET) Aclarar color (Paint.NET)
|
||||
No subject found — try Object Selection or the Lasso No se encontró ningún sujeto — pruebe Selección de objeto o el Lazo
|
||||
Quick Selection found nothing there Selección rápida no encontró nada ahí
|
||||
Object Selection found nothing there — try a tighter rectangle Selección de objeto no encontró nada ahí — pruebe un rectángulo más ajustado
|
||||
No subject found — try a rectangle around the object No se encontró ningún sujeto — pruebe un rectángulo alrededor del objeto
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 4 and column 47.
|
|
|
@ -2777,3 +2777,7 @@ fontWeight Italic Italique
|
|||
XOR XOR
|
||||
Color Burn (Paint.NET) Densité couleur + (Paint.NET)
|
||||
Color Dodge (Paint.NET) Densité couleur − (Paint.NET)
|
||||
No subject found — try Object Selection or the Lasso Aucun sujet trouvé — essayez la Sélection d'objet ou le Lasso
|
||||
Quick Selection found nothing there La Sélection rapide n'a rien trouvé à cet endroit
|
||||
Object Selection found nothing there — try a tighter rectangle La Sélection d'objet n'a rien trouvé à cet endroit — essayez un rectangle plus serré
|
||||
No subject found — try a rectangle around the object Aucun sujet trouvé — essayez un rectangle autour de l'objet
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
|
|
@ -2764,3 +2764,7 @@ fontWeight Italic Miring
|
|||
XOR XOR
|
||||
Color Burn (Paint.NET) Color Burn (Paint.NET)
|
||||
Color Dodge (Paint.NET) Color Dodge (Paint.NET)
|
||||
No subject found — try Object Selection or the Lasso Subjek tidak ditemukan — coba Seleksi Objek atau Laso
|
||||
Quick Selection found nothing there Seleksi Cepat tidak menemukan apa pun di sana
|
||||
Object Selection found nothing there — try a tighter rectangle Seleksi Objek tidak menemukan apa pun di sana — coba persegi panjang yang lebih rapat
|
||||
No subject found — try a rectangle around the object Subjek tidak ditemukan — coba persegi panjang di sekitar objek
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 4 and column 47.
|
|
|
@ -2426,3 +2426,7 @@ fontWeight Italic Corsivo
|
|||
XOR XOR
|
||||
Color Burn (Paint.NET) Colore brucia (Paint.NET)
|
||||
Color Dodge (Paint.NET) Colore scherma (Paint.NET)
|
||||
No subject found — try Object Selection or the Lasso Nessun soggetto trovato — prova Selezione oggetto o il Lazo
|
||||
Quick Selection found nothing there Selezione rapida non ha trovato nulla lì
|
||||
Object Selection found nothing there — try a tighter rectangle Selezione oggetto non ha trovato nulla lì — prova un rettangolo più stretto
|
||||
No subject found — try a rectangle around the object Nessun soggetto trovato — prova un rettangolo attorno all'oggetto
|
||||
|
|
|
|||
|
Can't render this file because it has a wrong number of fields in line 14.
|
|
|
@ -3380,3 +3380,7 @@ fontWeight Italic 斜体
|
|||
XOR XOR
|
||||
Color Burn (Paint.NET) 焼き込みカラー (Paint.NET)
|
||||
Color Dodge (Paint.NET) 覆い焼きカラー (Paint.NET)
|
||||
No subject found — try Object Selection or the Lasso 被写体が見つかりません — オブジェクト選択ツールまたはなげなわツールを試してください
|
||||
Quick Selection found nothing there クイック選択ではそこに何も見つかりませんでした
|
||||
Object Selection found nothing there — try a tighter rectangle オブジェクト選択ではそこに何も見つかりませんでした — より狭い長方形で試してください
|
||||
No subject found — try a rectangle around the object 被写体が見つかりません — オブジェクトを囲む長方形を試してください
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
|
|
@ -2935,3 +2935,7 @@ fontWeight Italic 기울임
|
|||
XOR XOR
|
||||
Color Burn (Paint.NET) 색상 번 (Paint.NET)
|
||||
Color Dodge (Paint.NET) 색상 닷지 (Paint.NET)
|
||||
No subject found — try Object Selection or the Lasso 피사체를 찾을 수 없습니다 — 개체 선택 또는 올가미를 사용해 보세요
|
||||
Quick Selection found nothing there 빠른 선택으로 해당 위치에서 아무것도 찾지 못했습니다
|
||||
Object Selection found nothing there — try a tighter rectangle 개체 선택으로 해당 위치에서 아무것도 찾지 못했습니다 — 더 좁은 사각형을 사용해 보세요
|
||||
No subject found — try a rectangle around the object 피사체를 찾을 수 없습니다 — 개체 주위에 사각형을 그려 보세요
|
||||
|
|
|
|||
|
Can't render this file because it has a wrong number of fields in line 10.
|
|
|
@ -3539,3 +3539,7 @@ cameraRaw Whites Witten
|
|||
Color Dodge (Paint.NET) Kleur tegenhouden (Paint.NET)
|
||||
Pro Medium Pro Medium
|
||||
Studio Light Studio Light
|
||||
No subject found — try Object Selection or the Lasso Geen onderwerp gevonden — probeer Objectselectie of de Lasso
|
||||
Quick Selection found nothing there Snelle selectie heeft daar niets gevonden
|
||||
Object Selection found nothing there — try a tighter rectangle Objectselectie heeft daar niets gevonden — probeer een krappere rechthoek
|
||||
No subject found — try a rectangle around the object Geen onderwerp gevonden — probeer een rechthoek rond het object
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 8 and column 34.
|
|
|
@ -3379,3 +3379,7 @@ cameraRaw Roughness Chropowatość
|
|||
XOR XOR
|
||||
Color Burn (Paint.NET) Wypalanie koloru (Paint.NET)
|
||||
Color Dodge (Paint.NET) Rozjaśnianie koloru (Paint.NET)
|
||||
No subject found — try Object Selection or the Lasso Nie znaleziono obiektu — spróbuj Zaznaczania obiektu lub Lassa
|
||||
Quick Selection found nothing there Szybkie zaznaczanie nic tam nie znalazło
|
||||
Object Selection found nothing there — try a tighter rectangle Zaznaczanie obiektu nic tam nie znalazło — spróbuj ciaśniejszego prostokąta
|
||||
No subject found — try a rectangle around the object Nie znaleziono obiektu — spróbuj prostokąta wokół obiektu
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
|
|
@ -2785,3 +2785,7 @@ fontWeight Italic Itálico
|
|||
XOR XOR
|
||||
Color Burn (Paint.NET) Superexposição de cores (Paint.NET)
|
||||
Color Dodge (Paint.NET) Subexposição de cores (Paint.NET)
|
||||
No subject found — try Object Selection or the Lasso Nenhum assunto encontrado — tente Seleção de objeto ou o Laço
|
||||
Quick Selection found nothing there A Seleção rápida não encontrou nada ali
|
||||
Object Selection found nothing there — try a tighter rectangle A Seleção de objeto não encontrou nada ali — tente um retângulo mais justo
|
||||
No subject found — try a rectangle around the object Nenhum assunto encontrado — tente um retângulo ao redor do objeto
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
|
|
@ -2631,3 +2631,7 @@ fontWeight Italic Курсив
|
|||
XOR XOR
|
||||
Color Burn (Paint.NET) Затемнение основы (Paint.NET)
|
||||
Color Dodge (Paint.NET) Осветление основы (Paint.NET)
|
||||
No subject found — try Object Selection or the Lasso Объект не найден — попробуйте «Выделение объектов» или «Лассо»
|
||||
Quick Selection found nothing there Быстрое выделение ничего здесь не нашло
|
||||
Object Selection found nothing there — try a tighter rectangle Выделение объектов ничего здесь не нашло — попробуйте более узкий прямоугольник
|
||||
No subject found — try a rectangle around the object Объект не найден — попробуйте прямоугольник вокруг объекта
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
|
|
@ -3466,3 +3466,7 @@ cameraRaw Masking Маскування
|
|||
Color Dodge (Paint.NET) Освітлення основи (Paint.NET)
|
||||
Pro Medium Pro Medium
|
||||
Studio Light Studio Light
|
||||
No subject found — try Object Selection or the Lasso Об'єкт не знайдено — спробуйте «Виділення об'єктів» або «Ласо»
|
||||
Quick Selection found nothing there Швидке виділення нічого тут не знайшло
|
||||
Object Selection found nothing there — try a tighter rectangle Виділення об'єктів нічого тут не знайшло — спробуйте вужчий прямокутник
|
||||
No subject found — try a rectangle around the object Об'єкт не знайдено — спробуйте прямокутник навколо об'єкта
|
||||
|
|
|
|||
|
Can't render this file because it has a wrong number of fields in line 12.
|
|
|
@ -2364,3 +2364,7 @@ fontWeight Italic 斜体
|
|||
XOR XOR
|
||||
Color Burn (Paint.NET) 颜色加深 (Paint.NET)
|
||||
Color Dodge (Paint.NET) 颜色减淡 (Paint.NET)
|
||||
No subject found — try Object Selection or the Lasso 未找到主体 — 请尝试对象选择工具或套索工具
|
||||
Quick Selection found nothing there 快速选择在该处未找到任何内容
|
||||
Object Selection found nothing there — try a tighter rectangle 对象选择在该处未找到任何内容 — 请尝试更紧凑的矩形
|
||||
No subject found — try a rectangle around the object 未找到主体 — 请尝试在对象周围绘制矩形
|
||||
|
|
|
|||
|
Can't render this file because it has a wrong number of fields in line 14.
|
|
|
@ -2333,3 +2333,7 @@ fontWeight Italic 斜體
|
|||
XOR XOR
|
||||
Color Burn (Paint.NET) 加深顏色 (Paint.NET)
|
||||
Color Dodge (Paint.NET) 加亮顏色 (Paint.NET)
|
||||
No subject found — try Object Selection or the Lasso 找不到主體 — 請嘗試物件選取工具或套索工具
|
||||
Quick Selection found nothing there 快速選取在該處找不到任何內容
|
||||
Object Selection found nothing there — try a tighter rectangle 物件選取在該處找不到任何內容 — 請嘗試更緊密的矩形
|
||||
No subject found — try a rectangle around the object 找不到主體 — 請嘗試在物件周圍繪製矩形
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
|
|
@ -1009,7 +1009,8 @@ pub fn options_bar(app: &mut PhotocraftApp, ui: &mut egui::Ui) {
|
|||
widgets::checkbox(ui, &mut app.ui.tool_options.sample_all_layers, tl!("Sample All Layers"));
|
||||
widgets::vline(ui, 22.0);
|
||||
if widgets::secondary_button(ui, tl!("Select Subject"), 0.0).clicked() {
|
||||
let _ = app.run("select.subject", json!({}));
|
||||
let r = app.run("select.subject", json!({}));
|
||||
crate::retouch_ui::report_smart_result(app, r, tl!("No subject found — try Object Selection or the Lasso"));
|
||||
}
|
||||
if widgets::secondary_button(ui, tl!("Select and Mask…"), 0.0).clicked() {
|
||||
let _ = crate::menus::invoke(app, ui.ctx(), "select.selectAndMask", json!({}));
|
||||
|
|
|
|||
|
|
@ -103,8 +103,9 @@ pub fn finish_stroke(app: &mut PhotocraftApp, tool: Tool, points: &[[f64; 3]], m
|
|||
let size = app.session.tools.brush.size;
|
||||
let mode = if mods.alt { "subtract" } else { "add" };
|
||||
let xy: Vec<[f64; 2]> = points.iter().map(|q| [q[0], q[1]]).collect();
|
||||
let _ = app
|
||||
.run("select.quick", json!({"points": xy, "size": size, "mode": mode, "enhanceEdge": o.enhance_edge, "sampleAllLayers": o.sample_all_layers}));
|
||||
let (sample_all, enhance) = (o.sample_all_layers, o.enhance_edge);
|
||||
let r = app.run("select.quick", json!({"points": xy, "size": size, "mode": mode, "enhanceEdge": enhance, "sampleAllLayers": sample_all}));
|
||||
report_smart_result(app, r, tl!("Quick Selection found nothing there"));
|
||||
return true;
|
||||
}
|
||||
_ => return false,
|
||||
|
|
@ -203,11 +204,19 @@ pub fn finish_content_aware_move(app: &mut PhotocraftApp, start: [f64; 2], end:
|
|||
}
|
||||
}
|
||||
|
||||
/// Object Selection: the dragged rectangle.
|
||||
/// Object Selection: the dragged rectangle. A click (or a sub-2 px nudge) cannot be a
|
||||
/// rectangle: like Photoshop's click-to-select, it falls back to a Quick Selection dab at
|
||||
/// the brush size instead of looking dead (⌥ subtracts, otherwise it adds). Larger drags
|
||||
/// run the rectangle GrabCut (⌥ subtracts, ⇧ adds, otherwise replaces).
|
||||
pub fn finish_object_selection(app: &mut PhotocraftApp, start: [f64; 2], end: [f64; 2], mods: egui::Modifiers) {
|
||||
let (x, y) = (start[0].min(end[0]), start[1].min(end[1]));
|
||||
let (w, h) = ((end[0] - start[0]).abs(), (end[1] - start[1]).abs());
|
||||
let sample_all = app.ui.tool_options.sample_all_layers;
|
||||
if w < 2.0 || h < 2.0 {
|
||||
let size = app.session.tools.brush.size;
|
||||
let mode = if mods.alt { "subtract" } else { "add" };
|
||||
let r = app.run("select.quick", json!({"points": [[end[0], end[1]]], "size": size, "mode": mode, "sampleAllLayers": sample_all}));
|
||||
report_smart_result(app, r, tl!("Quick Selection found nothing there"));
|
||||
return;
|
||||
}
|
||||
let mode = if mods.alt {
|
||||
|
|
@ -217,10 +226,19 @@ pub fn finish_object_selection(app: &mut PhotocraftApp, start: [f64; 2], end: [f
|
|||
} else {
|
||||
"replace"
|
||||
};
|
||||
let _ = app.run(
|
||||
"select.object",
|
||||
json!({"rect": [x.round(), y.round(), w.round(), h.round()], "mode": mode, "sampleAllLayers": app.ui.tool_options.sample_all_layers}),
|
||||
);
|
||||
let r = app.run("select.object", json!({"rect": [x.round(), y.round(), w.round(), h.round()], "mode": mode, "sampleAllLayers": sample_all}));
|
||||
report_smart_result(app, r, tl!("Object Selection found nothing there — try a tighter rectangle"));
|
||||
}
|
||||
|
||||
/// Reports a smart-selection command result in the status bar. Engine errors are already
|
||||
/// reported by [`PhotocraftApp::run`], but an empty result (`changed: false`) is a silent
|
||||
/// success that looks like a dead button (Select Subject finding nothing on a busy photo,
|
||||
/// Object Selection missing its rectangle). `empty_msg` says what to try next.
|
||||
pub fn report_smart_result(app: &mut PhotocraftApp, res: Result<Value, String>, empty_msg: &str) {
|
||||
if matches!(res, Ok(ref v) if v.get("changed").and_then(Value::as_bool) == Some(false)) {
|
||||
app.ui.status = empty_msg.into();
|
||||
app.ui.status_error = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// ⌥-click with Clone Stamp / Healing Brush sets the source.
|
||||
|
|
@ -356,7 +374,8 @@ pub fn options_bar(app: &mut PhotocraftApp, ui: &mut egui::Ui, tool: Tool) -> bo
|
|||
opt(ui, &crate::i18n::fmt(tl!("{key} to subtract"), &[("key", &crate::shortcuts::pretty("Alt"))]));
|
||||
crate::widgets::vline(ui, 22.0);
|
||||
if crate::widgets::secondary_button(ui, tl!("Select Subject"), 0.0).clicked() {
|
||||
let _ = app.run("select.subject", json!({}));
|
||||
let r = app.run("select.subject", json!({}));
|
||||
report_smart_result(app, r, tl!("No subject found — try Object Selection or the Lasso"));
|
||||
}
|
||||
}
|
||||
Tool::ObjectSelection => {
|
||||
|
|
@ -364,7 +383,8 @@ pub fn options_bar(app: &mut PhotocraftApp, ui: &mut egui::Ui, tool: Tool) -> bo
|
|||
opt(ui, tl!("Drag a rectangle around the object"));
|
||||
crate::widgets::vline(ui, 22.0);
|
||||
if crate::widgets::secondary_button(ui, tl!("Select Subject"), 0.0).clicked() {
|
||||
let _ = app.run("select.subject", json!({}));
|
||||
let r = app.run("select.subject", json!({}));
|
||||
report_smart_result(app, r, tl!("No subject found — try a rectangle around the object"));
|
||||
}
|
||||
}
|
||||
Tool::RedEye => {
|
||||
|
|
@ -511,6 +531,44 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn object_selection_click_falls_back_to_quick_selection() {
|
||||
// A click cannot be a rectangle: it selects at the cursor instead of looking dead.
|
||||
let mut app = app();
|
||||
app.ui.tool = Tool::ObjectSelection;
|
||||
let m = egui::Modifiers::NONE;
|
||||
tool_event(&mut app, ToolEvent::Down { x: 50.0, y: 30.0, pressure: 1.0 }, m);
|
||||
tool_event(&mut app, ToolEvent::Up { x: 50.0, y: 30.0 }, m);
|
||||
assert!(!app.ui.status_error, "{}", app.ui.status);
|
||||
assert_eq!(app.session.journal.last().map(|(id, _)| id.as_str()), Some("select.quick"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn object_selection_rect_runs_object_selection_and_reports() {
|
||||
let mut app = app();
|
||||
app.run("paint.pencil", json!({"points": [[20, 10], [20, 50]], "size": 8, "color": "#ff0000"})).unwrap();
|
||||
app.ui.tool = Tool::ObjectSelection;
|
||||
let m = egui::Modifiers::NONE;
|
||||
tool_event(&mut app, ToolEvent::Down { x: 5.0, y: 5.0, pressure: 1.0 }, m);
|
||||
tool_event(&mut app, ToolEvent::Move { x: 60.0, y: 55.0, pressure: 1.0 }, m);
|
||||
tool_event(&mut app, ToolEvent::Up { x: 60.0, y: 55.0 }, m);
|
||||
assert!(!app.ui.status_error, "{}", app.ui.status);
|
||||
assert_eq!(app.session.journal.last().map(|(id, _)| id.as_str()), Some("select.object"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_smart_result_is_reported_without_error() {
|
||||
// An empty smart selection (Select Subject missing on a busy photo) is an info, not
|
||||
// an error and not silence: the button must visibly answer.
|
||||
let mut app = app();
|
||||
report_smart_result(&mut app, Ok(json!({"selected": false, "changed": false})), "nothing there");
|
||||
assert_eq!(app.ui.status.as_str(), "nothing there");
|
||||
assert!(!app.ui.status_error);
|
||||
app.ui.status.clear();
|
||||
report_smart_result(&mut app, Ok(json!({"selected": true, "changed": true})), "nothing there");
|
||||
assert!(app.ui.status.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mixer_brush_is_selectable_and_paints_only_inside_the_selection_via_control() {
|
||||
use crate::control::{ControlRequest, Outcome, handle};
|
||||
|
|
|
|||
Loading…
Reference in New Issue