Merge pull request #1166 from storytold/fix/1152-offset-path-memory

#1152: Offset Path opens on the values it was last applied with
This commit is contained in:
BFlat
2026-10-11 17:16:28 +07:00
committed by GitHub
5 changed files with 35 additions and 5 deletions
+1 -1
View File
File diff suppressed because one or more lines are too long
+8 -1
View File
@@ -40,5 +40,12 @@ fn body(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool {
fn confirm(app: &mut VectorcraftApp, d: &Dialog) -> Result<Value, String> {
let (id, params) = command(d);
if d.kind == "offsetPath" { form::commit_preview(app, id, params) } else { run_and_close(app, id, params) }
if d.kind != "offsetPath" {
return run_and_close(app, id, params);
}
let r = form::commit_preview(app, id, params)?;
// The fields as the dialog held them, so they show as typed when it opens again.
let kept = ["offset", "joins", "miterLimit"].into_iter().filter_map(|k| Some((k.to_string(), d.fields.get(k)?.clone())));
app.ui.offset_path = Value::Object(kept.collect());
Ok(r)
}
+16
View File
@@ -201,3 +201,19 @@ fn offset_path_previews() {
cancel(&mut app);
assert_eq!(count(&app), 1, "rolled back");
}
/// Offset Path opens on the values it was last confirmed with (#1152).
#[test]
fn offset_path_remembers_its_last_values() {
let mut app = app_with_selection();
app.run("select.all", json!({})).unwrap();
crate::menus::invoke(&mut app, "object.path.offsetPath", json!({}));
let d = app.ui.dialog.as_mut().unwrap();
d.fields.insert("offset".into(), json!(-4.5));
d.fields.insert("joins".into(), json!("round"));
confirm(&mut app).unwrap();
assert!(app.ui.dialog.is_none());
crate::menus::invoke(&mut app, "object.path.offsetPath", json!({}));
let d = app.ui.dialog.as_ref().unwrap();
assert_eq!((d.f64("offset", 0.0), d.str("joins"), d.f64("miterLimit", 0.0)), (-4.5, "round".to_string(), 4.0));
}
+5 -3
View File
@@ -1331,7 +1331,7 @@ pub fn run_ui_command(app: &mut VectorcraftApp, id: &str, p: &Value) -> Option<R
"ui.spotColors" => crate::dialogs::spot_colors::open(app),
"ui.menuDialog" => match s("command").as_deref() {
Some(c) if crate::dialogs::envelope::opens(c) => crate::dialogs::envelope::open(app, c),
c => match c.and_then(menu_dialog) {
c => match c.and_then(|c| menu_dialog(app, c)) {
Some((kind, fields)) => {
app.ui.dialog = Some(crate::state::Dialog::new(kind, fields));
Ok(Value::Null)
@@ -2976,7 +2976,7 @@ fn queried_dialog(id: &str) -> Option<(&'static str, &'static [&'static str])> {
}
/// The dialog (kind, fields) the menu item of command `id` opens, as the reference app's does.
fn menu_dialog(id: &str) -> Option<(&'static str, Value)> {
fn menu_dialog(app: &VectorcraftApp, id: &str) -> Option<(&'static str, Value)> {
Some(match id {
"object.move" => ("move", json!({"dx": "0 pt", "dy": "0 pt"})),
"object.rotate" => ("rotate", json!({"angle": 0})),
@@ -2985,6 +2985,8 @@ fn menu_dialog(id: &str) -> Option<(&'static str, Value)> {
"object.reflect" => ("reflect", json!({"axis": "vertical"})),
"object.shear" => ("shear", json!({"angle": 0, "axis": "horizontal"})),
"path.average" => ("average", json!({"axis": "both"})),
// Offset Path opens on the values it was last confirmed with.
"object.path.offsetPath" if app.ui.offset_path.is_object() => ("offsetPath", app.ui.offset_path.clone()),
"object.path.offsetPath" => ("offsetPath", json!({"offset": "10 pt", "joins": "miter", "miterLimit": 4})),
"object.path.simplify" => ("simplify", json!({"tolerance": "1 pt"})),
"object.path.splitIntoGrid" => ("splitIntoGrid", json!({"rows": 2, "columns": 2, "gutter": "12 pt"})),
@@ -3041,7 +3043,7 @@ pub fn invoke(app: &mut VectorcraftApp, id: &str, p: Value) {
if waits_for_ime(app, id) {
return;
}
if let Some((kind, fields)) = menu_dialog(id)
if let Some((kind, fields)) = menu_dialog(app, id)
&& p.as_object().is_none_or(|o| o.is_empty())
{
app.ui.dialog = Some(crate::state::Dialog::new(kind, fields));
+5
View File
@@ -388,6 +388,10 @@ pub struct UiState {
/// The EPS Options chosen last (`document.exportEps` options; null: never used).
#[serde(default)]
pub eps_options: Value,
/// The Offset Path fields confirmed last (offset, joins, miterLimit; null: never used): its
/// dialog opens on them (#1152).
#[serde(default)]
pub offset_path: Value,
/// The DXF Import Options chosen last (fit, scaleLineweights, center, mergeLayers; null:
/// never used).
#[serde(default)]
@@ -639,6 +643,7 @@ impl Default for UiState {
dialog_search: None,
dxf_options: Value::Null,
eps_options: Value::Null,
offset_path: Value::Null,
dxf_import: Value::Null,
home: None,
layers_panel: Default::default(),