mirror of
https://github.com/storytold/photocraft.git
synced 2026-11-12 21:23:02 +00:00
Clone Stamp: a press without a source point shows the reference's alert
The Clone Stamp set a status-bar line when no source point was defined. It now opens the
reference application's alert at the press ("Could not use the clone stamp tool because the
area to clone has not been defined (Alt-click to define a source point)."), once while it is up,
and starts no drag. The Healing Brush keeps its status line.
This commit is contained in:
1 parent
d0299c4179
commit
ddf039917a
3 files changed
+37
-13
No files matched your search
@@ -525,7 +525,12 @@ pub(super) fn tool_event_with_view(app: &mut PhotocraftApp, ev: ToolEvent, mods:
|
||||
if !sets_source && press_refused(app, tool) {
|
||||
return;
|
||||
}
|
||||
if !sets_source && (crate::rasterize_prompt::intercept(app, tool, x, y, pressure) || refuse_group(app, tool)) {
|
||||
// The Clone Stamp's no-source alert opens at the press, after any rasterize prompt.
|
||||
if !sets_source
|
||||
&& (crate::rasterize_prompt::intercept(app, tool, x, y, pressure)
|
||||
|| refuse_group(app, tool)
|
||||
|| crate::retouch_ui::clone_stamp_without_source(app, tool))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// ⌘ with a selection tool is the Move tool for the drag: outside the selection (or
|
||||
|
||||
@@ -198,6 +198,21 @@ pub(crate) fn stroke_seed(points: &[[f64; 3]]) -> u64 {
|
||||
photocraft_engine::paint::rng::seed_from_bytes(first.as_bytes())
|
||||
}
|
||||
|
||||
/// A Clone Stamp press with no source point yet: the reference application's alert, opened at
|
||||
/// the press (#12609) and once while it is up. Returns whether it refused the stroke.
|
||||
pub(crate) fn clone_stamp_without_source(app: &mut PhotocraftApp, tool: Tool) -> bool {
|
||||
if tool != Tool::CloneStamp || clone_params(app).is_some() {
|
||||
return false;
|
||||
}
|
||||
let message = if cfg!(target_os = "macos") {
|
||||
tl!("Could not use the clone stamp tool because the area to clone has not been defined (Option-click to define a source point).")
|
||||
} else {
|
||||
tl!("Could not use the clone stamp tool because the area to clone has not been defined (Alt-click to define a source point).")
|
||||
};
|
||||
open_alert_once(app, message);
|
||||
true
|
||||
}
|
||||
|
||||
/// Finish a stroke with a retouching tool. Returns false if `tool` isn't one.
|
||||
pub fn finish_stroke(app: &mut PhotocraftApp, tool: Tool, points: &[[f64; 3]], mods: egui::Modifiers, line: bool) -> bool {
|
||||
finish_stroke_with(app, tool, points, mods, line, None)
|
||||
@@ -224,6 +239,9 @@ pub(crate) fn finish_stroke_with(app: &mut PhotocraftApp, tool: Tool, points: &[
|
||||
return true;
|
||||
}
|
||||
let Some(p) = clone_params(app) else {
|
||||
if clone_stamp_without_source(app, tool) {
|
||||
return true;
|
||||
}
|
||||
// Option-click on the Mac, Alt-click on Windows.
|
||||
app.ui.status = if cfg!(target_os = "macos") {
|
||||
tl!("Option-click to define a source point to clone from")
|
||||
@@ -783,7 +801,8 @@ fn cam_amount_slider(ui: &mut egui::Ui, name: &str, value: &mut f32, lo: f32, hi
|
||||
});
|
||||
}
|
||||
|
||||
fn open_cam_range_alert(app: &mut PhotocraftApp, message: &str) {
|
||||
/// Opens the alert with `message` (English, translated here) unless it is already up.
|
||||
fn open_alert_once(app: &mut PhotocraftApp, message: &str) {
|
||||
let message = tl!(message).to_owned();
|
||||
let shown =
|
||||
app.ui.dialogs.iter().any(|d| d.kind == crate::state::DialogKind::Error && d.fields.get("message").and_then(|m| m.as_str()) == Some(message.as_str()));
|
||||
@@ -807,11 +826,11 @@ fn content_aware_move_bar(app: &mut PhotocraftApp, ui: &mut egui::Ui) {
|
||||
}
|
||||
opt(ui, tl!("Structure:"));
|
||||
if cam_integer_popup(ui, "cam-structure", "Structure", &mut app.ui.tool_options.cam_structure, 1.0, 7.0, STRUCTURE_TIP) {
|
||||
open_cam_range_alert(app, STRUCTURE_RANGE_ALERT);
|
||||
open_alert_once(app, STRUCTURE_RANGE_ALERT);
|
||||
}
|
||||
opt(ui, tl!("Color:"));
|
||||
if cam_integer_popup(ui, "cam-color", "Color", &mut app.ui.tool_options.cam_color, 0.0, 10.0, COLOR_TIP) {
|
||||
open_cam_range_alert(app, COLOR_RANGE_ALERT);
|
||||
open_alert_once(app, COLOR_RANGE_ALERT);
|
||||
}
|
||||
crate::widgets::checkbox(ui, &mut app.ui.tool_options.sample_all.content_aware_move, tl!("Sample All Layers"))
|
||||
.on_hover_text(tl!("Enable to remix all layers"));
|
||||
|
||||
@@ -225,15 +225,15 @@ fn paint_bucket_mode_reaches_the_fill() {
|
||||
|
||||
#[test]
|
||||
fn clone_without_a_source_names_the_platform_modifier() {
|
||||
// Option-click on the Mac, Alt-click elsewhere (#251).
|
||||
for tool in [Tool::CloneStamp, Tool::Healing] {
|
||||
let mut app = app();
|
||||
app.ui.tool = tool;
|
||||
assert!(finish_stroke(&mut app, tool, &[[10.0, 30.0, 1.0], [50.0, 30.0, 1.0]], egui::Modifiers::NONE, false));
|
||||
assert!(app.ui.status_error, "{tool:?}");
|
||||
let want = if cfg!(target_os = "macos") { "Option-click" } else { "Alt-click" };
|
||||
assert!(app.ui.status.starts_with(want), "{tool:?}: {}", app.ui.status);
|
||||
}
|
||||
// Option-click on the Mac, Alt-click elsewhere (#251). The Clone Stamp says it in an alert
|
||||
// (#12609, clone_stamp_no_source_alert_tests.rs).
|
||||
let tool = Tool::Healing;
|
||||
let mut app = app();
|
||||
app.ui.tool = tool;
|
||||
assert!(finish_stroke(&mut app, tool, &[[10.0, 30.0, 1.0], [50.0, 30.0, 1.0]], egui::Modifiers::NONE, false));
|
||||
assert!(app.ui.status_error);
|
||||
let want = if cfg!(target_os = "macos") { "Option-click" } else { "Alt-click" };
|
||||
assert!(app.ui.status.starts_with(want), "{}", app.ui.status);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in new issue
Block a user