Brushes: Pattern Brush Options keeps Original after a swatch is chosen

This commit is contained in:
dotCooCoo
2026-11-02 12:04:13 +07:00
committed by bflatastic
parent 8a5ea9488e
commit 6045f100cd
2 changed files with 24 additions and 6 deletions
@@ -68,10 +68,10 @@ fn pattern_choice(d: &Dialog, choice: &str) -> Option<String> {
(!reserved && pattern_names(d).iter().any(|candidate| candidate == name)).then(|| name.to_string())
}
/// Whether tile `field`'s menu offers Original: the tile the dialog opened with, kept available after
/// a swatch is chosen so the tile can go back to it.
pub(super) fn original_available(d: &Dialog, field: &str) -> bool {
let choice = d.str(&tile_key(field));
let drawn = if field.ends_with("corner") { corner_art_field(d.fields.get("__def"), field) } else { Some(field) };
drawn.is_some() && pattern_choice(d, &choice).is_none()
!field.ends_with("corner") || corner_art_field(d.fields.get("__def"), field).is_some()
}
pub(super) fn reconcile_pattern_choices(f: &mut Map<String, Value>) {
@@ -541,8 +541,7 @@ fn pattern_body(ui: &mut egui::Ui, d: &mut Dialog) {
radios(ui, d, "fit", &fits);
}
/// Built-in corner choices. Original is disabled when the slot has no retained art or a listed
/// swatch was selected.
/// Built-in corner choices. Original is disabled when the corner opened with no art to draw.
fn corner_choices() -> [(&'static str, &'static str); 6] {
[
(CornerSource::None.id(), tl!("None")),
@@ -529,13 +529,32 @@ fn pattern_tile_menus_use_document_patterns_and_side_none_keeps_dialog_open() {
assert_eq!(ids.get(1).map(String::as_str), Some("original"));
}
}
// Original stays available after a swatch is chosen, and restores the tile the dialog opened with.
let d = app.ui.dialog.as_mut().unwrap();
crate::dialogs::brush_art_options::choose_corner(d, "sideTile", "Wide");
assert!(crate::dialogs::brush_art_options::original_available(d, "side"));
crate::dialogs::brush_art_options::choose_corner(d, "sideTile", "original");
let restored = crate::dialogs::brush_art_options::edited_def(d);
assert_eq!((&restored["side"], &restored["side_frame"]), (&before["side"], &before["side_frame"]));
super::super::confirm(&mut app).unwrap();
let kept = app.run("brush.get", json!({"name":"Diamonds"})).unwrap();
assert_eq!((&kept["side"], &kept["side_frame"]), (&before["side"], &before["side_frame"]));
app.run("ui.brushOptions", json!({"name":"Diamonds"})).unwrap();
let d = app.ui.dialog.as_mut().unwrap();
crate::dialogs::brush_art_options::choose_corner(d, "sideTile", "Wide");
assert!(!crate::dialogs::brush_art_options::original_available(d, "side"));
let preview = crate::dialogs::brush_art_options::edited_def(d);
assert_eq!(preview["side_frame"], json!(Rect::new(0.0, 0.0, 10.0, 4.0)));
assert_ne!(preview["side"], before["side"]);
super::super::confirm(&mut app).unwrap();
// A tile that opens on a swatch can also go back to the art it opened with.
let opened = app.run("brush.get", json!({"name":"Diamonds"})).unwrap();
app.run("ui.brushOptions", json!({"name":"Diamonds"})).unwrap();
let d = app.ui.dialog.as_mut().unwrap();
assert_eq!(d.str("sideTile"), "pattern:Wide");
assert!(crate::dialogs::brush_art_options::original_available(d, "side"));
crate::dialogs::brush_art_options::choose_corner(d, "sideTile", "original");
assert_eq!(crate::dialogs::brush_art_options::edited_def(d)["side"], opened["side"]);
super::super::cancel(&mut app);
app.session
.edit("Delete pattern", |doc, _| {
doc.patterns.clear();