mirror of
https://github.com/storytold/designcraft.git
synced 2026-11-14 22:35:26 +00:00
Object style dialog: a refused OK keeps it open with the reason; Czech terms as the catalog's
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6f40546167
commit
b8e229a5cc
3 files changed
+54
-7
No files matched your search
@@ -3576,7 +3576,16 @@ pub fn confirm(app: &mut DesignApp) -> Result<Value, String> {
|
||||
}
|
||||
"alert" => Ok(Value::Null),
|
||||
crate::effects_dialog::ID => crate::effects_dialog::confirm(app, &d),
|
||||
crate::object_style_dialog::ID => crate::object_style_dialog::confirm(app, &d),
|
||||
crate::object_style_dialog::ID => {
|
||||
let r = crate::object_style_dialog::confirm(app, &d);
|
||||
if let Err(e) = &r {
|
||||
// Keep the dialog and its edits open with the reason (an empty or taken name).
|
||||
let mut d = d.clone();
|
||||
d.fields.insert("status".into(), json!(e));
|
||||
app.ui.dialog = Some(d);
|
||||
}
|
||||
r
|
||||
}
|
||||
"findChange" => {
|
||||
let result = if d.b("objectMode") { Ok(Value::Null) } else { app.run("find.change", find_change_params(&d)) };
|
||||
// Confirmation consumes retained bounds before closing, even on an error.
|
||||
|
||||
@@ -32,14 +32,14 @@ pub(super) const TABLE: &[(&str, &str)] = &[
|
||||
("Copy", "Kopírovat"),
|
||||
("Paste", "Vložit"),
|
||||
("New Object Style", "Nový styl objektu"),
|
||||
("Object Style Options", "Volby stylu objektu"),
|
||||
("Object Style Options…", "Volby stylu objektu…"),
|
||||
("Object Style Options", "Možnosti stylu objektu"),
|
||||
("Object Style Options…", "Možnosti stylu objektu…"),
|
||||
("Basic Attributes", "Základní atributy"),
|
||||
("Stroke & Corner Options", "Volby tahu a rohů"),
|
||||
("Stroke & Corner Options", "Možnosti tahu a rohů"),
|
||||
("Effects for:", "Efekty pro:"),
|
||||
("Apply Style to Selection", "Použít styl na výběr"),
|
||||
("Create New Style", "Vytvořit nový styl"),
|
||||
("Clear Overrides", "Vymazat změny"),
|
||||
("Clear Overrides", "Zrušit přepsání"),
|
||||
("Shape:", "Tvar:"),
|
||||
("(no attributes)", "(žádné atributy)"),
|
||||
("Enter a style name.", "Zadejte název stylu."),
|
||||
|
||||
@@ -99,8 +99,13 @@ pub fn confirm(app: &mut DesignApp, d: &Dialog) -> Result<Value, String> {
|
||||
p.insert("fromSelection".into(), json!(false));
|
||||
let r = app.run("style.object.create", Value::Object(p)).map_err(|e| e.to_string())?;
|
||||
let made = r["name"].as_str().unwrap_or(&name).to_string();
|
||||
if d.b("apply") && app.session.active().is_some_and(|st| !st.selection.items.is_empty()) {
|
||||
app.run("style.object.apply", json!({"name": made})).map_err(|e| e.to_string())?;
|
||||
// The style exists now, so OK again mustn't make a second one: a refused apply (locked
|
||||
// objects) goes to the status line and the dialog closes.
|
||||
if d.b("apply")
|
||||
&& app.session.active().is_some_and(|st| !st.selection.items.is_empty())
|
||||
&& let Err(e) = app.run("style.object.apply", json!({"name": made}))
|
||||
{
|
||||
app.status(e.to_string());
|
||||
}
|
||||
Ok(r)
|
||||
} else {
|
||||
@@ -324,6 +329,11 @@ pub fn show(app: &mut DesignApp, ui: &mut egui::Ui, d: &mut Dialog) {
|
||||
d.fields.insert("name".into(), json!(name));
|
||||
}
|
||||
});
|
||||
// Why OK was refused (an empty or taken name), until the next try.
|
||||
let status = d.s("status");
|
||||
if !status.is_empty() {
|
||||
crate::rtl::label(ui, egui::RichText::new(status).color(crate::theme::Tokens::get(ui.ctx()).text_strong));
|
||||
}
|
||||
ui.add_space(8.0);
|
||||
let page = d.fields.get("page").and_then(Value::as_str).unwrap_or("general").to_string();
|
||||
ui.horizontal_top(|ui| {
|
||||
@@ -464,4 +474,32 @@ mod tests {
|
||||
assert!(doc(&app).styles.object_style(name).unwrap().fill.is_none(), "Fill unchecked: no longer in the style");
|
||||
assert!(doc(&app).styles.object_style(name).unwrap().effects.as_ref().unwrap().drop_shadow.on, "effects kept");
|
||||
}
|
||||
|
||||
/// A refused OK (an empty name, a name another style has) keeps the dialog and its edits,
|
||||
/// with the reason shown.
|
||||
#[test]
|
||||
fn a_refused_ok_keeps_the_dialog_open_with_the_reason() {
|
||||
let (mut app, _) = app_with_frame();
|
||||
let ctx = egui::Context::default();
|
||||
crate::theme::install_fonts(&ctx, "en");
|
||||
app.run("style.object.create", json!({"name": "Taken", "fromSelection": false})).unwrap();
|
||||
app.run("style.object.create", json!({"name": "Mine", "fromSelection": false})).unwrap();
|
||||
open_new(&mut app);
|
||||
if let Some(d) = app.ui.dialog.as_mut() {
|
||||
d.fields.insert("name".into(), json!(" "));
|
||||
set(d, &["stroke", "weight"], json!(7.0));
|
||||
}
|
||||
assert!(crate::dialogs::confirm(&mut app).is_err());
|
||||
let d = app.ui.dialog.as_ref().expect("still open");
|
||||
assert_eq!(d.s("status"), "Enter a style name.");
|
||||
assert_eq!(get(d, &["stroke", "weight"]), &json!(7.0), "the edits are kept");
|
||||
assert!(frame(&mut app, &ctx).iter().any(|t| t.trim() == "Enter a style name."));
|
||||
open_edit(&mut app, "Mine");
|
||||
if let Some(d) = app.ui.dialog.as_mut() {
|
||||
d.fields.insert("name".into(), json!("Taken"));
|
||||
}
|
||||
let e = crate::dialogs::confirm(&mut app).unwrap_err();
|
||||
assert!(e.contains("already named"), "{e}");
|
||||
assert!(app.ui.dialog.as_ref().is_some_and(|d| d.s("status") == e));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user