Merge pull request #3100 from nrq6993-a11y/stream/vc-feat1-g1-warp-remember-defaults

G1: Effect Warp dialog remembers last confirmed style and sliders
This commit is contained in:
BFlat
2026-10-20 02:35:48 +07:00
committed by GitHub
4 changed files with 54 additions and 3 deletions
+13 -2
View File
@@ -90,6 +90,9 @@ pub fn open(app: &mut VectorcraftApp, p: &Value) -> Result<Value, String> {
return Ok(json!({ "pending": EXISTS }));
}
fields.extend(info.defaults.as_object().cloned().unwrap_or_default());
if super::warp_effect::is_warp(id) {
super::warp_effect::merge_remembered(&mut fields, app.last_warp.as_ref());
}
}
}
fields.insert("preview".into(), json!(true));
@@ -119,8 +122,12 @@ fn confirm_exists(app: &mut VectorcraftApp, d: &Dialog) -> Result<Value, String>
let target = fields.remove("__target").unwrap_or(Value::Null);
if d.bool("discard") {
fields.remove("__index");
let defaults = vectorcraft_effects::default_params(&d.str("__effect"));
let id = d.str("__effect");
let defaults = vectorcraft_effects::default_params(&id);
fields.extend(defaults.and_then(|v| v.as_object().cloned()).unwrap_or_default());
if super::warp_effect::is_warp(id.as_str()) {
super::warp_effect::merge_remembered(&mut fields, app.last_warp.as_ref());
}
} else {
let k = fields.get("__index").and_then(Value::as_u64).unwrap_or(0) as usize;
fields.extend(target_effects(app, &target).get(k).map(params_of).unwrap_or_default());
@@ -673,7 +680,11 @@ fn confirm(app: &mut VectorcraftApp, d: &Dialog) -> Result<Value, String> {
let r = form::commit_preview(app, cmd, p.clone())?;
// Last Effect repeats applied effects, not edits.
if cmd == "effect.apply" {
app.last_effect = Some((d.str("__effect"), p["params"].clone()));
let id = d.str("__effect");
app.last_effect = Some((id.clone(), p["params"].clone()));
if super::warp_effect::is_warp(id.as_str()) {
app.last_warp = Some(super::warp_effect::remembered_params(d));
}
}
Ok(r)
}
+19
View File
@@ -187,6 +187,25 @@ fn warp_options_existing_style_edit_keeps_stack_target_visibility_and_history()
}
}
/// A new Warp Options dialog opens on the sliders confirmed last time (#1760 follow-up).
#[test]
fn warp_dialog_remembers_last_confirmed_sliders() {
let (mut app, _) = app();
app.run("effect.dialog", json!({"effect": "warp.arc", "item": null})).unwrap();
let ctx = context();
settle(&mut app, &ctx);
set(&mut app, json!({"bend": -40.0, "horizontal": 12.0, "vertical": -8.0, "orientation": "vertical"}));
confirm(&mut app).unwrap();
app.run("effect.dialog", json!({"effect": "warp.flag", "item": null})).unwrap();
settle(&mut app, &ctx);
let d = app.ui.dialog.as_ref().unwrap();
assert_eq!(d.str("__effect"), "warp.flag");
assert_eq!(d.f64("bend", 0.0), -40.0);
assert_eq!(d.f64("horizontal", 0.0), 12.0);
assert_eq!(d.f64("vertical", 0.0), -8.0);
assert_eq!(d.str("orientation"), "vertical");
}
#[test]
fn warp_options_preview_toggle_and_ok_use_latest_values() {
let (mut app, id) = app();
+19 -1
View File
@@ -1,6 +1,6 @@
//! Effect > Warp controls. The style remains an effect ID; Envelope Warp has a different schema.
use egui::{Pos2, Rect, Stroke, vec2};
use serde_json::json;
use serde_json::{Map, Value, json};
use vectorcraft_effects::{WARP_STYLES, WarpStyle, warp_point};
use super::form;
@@ -8,10 +8,28 @@ use crate::state::Dialog;
use crate::theme::Tokens;
use crate::widgets;
const REMEMBERED: [&str; 4] = ["bend", "horizontal", "vertical", "orientation"];
pub(super) fn is_warp(id: &str) -> bool {
id.strip_prefix("warp.").and_then(WarpStyle::from_id).is_some()
}
/// Slider and orientation values to seed the next new Warp Options dialog.
pub(super) fn remembered_params(d: &Dialog) -> Value {
let kept = REMEMBERED.iter().filter_map(|k| Some((k.to_string(), d.fields.get(*k)?.clone())));
Value::Object(kept.collect())
}
/// Last confirmed warp settings over the catalog defaults for a new dialog.
pub(super) fn merge_remembered(fields: &mut Map<String, Value>, remembered: Option<&Value>) {
let Some(obj) = remembered.and_then(Value::as_object) else { return };
for key in REMEMBERED {
if let Some(v) = obj.get(key) {
fields.insert(key.into(), v.clone());
}
}
}
fn shown(label: &str) -> String {
tl!(label).trim_end_matches('…').to_string()
}
+3
View File
@@ -398,6 +398,8 @@ pub struct VectorcraftApp {
pub titlebar_inset: f32,
/// Last applied effect (Effect → Apply Last Effect).
pub last_effect: Option<(String, serde_json::Value)>,
/// Last confirmed Warp Options (bend, distortion, orientation) for the next new warp dialog.
pub last_warp: Option<serde_json::Value>,
/// Commands run through [`Self::run`] so far: the native menu bar reads its rows again when it
/// moves ([`native_menu::sync`]).
run_count: u64,
@@ -542,6 +544,7 @@ impl VectorcraftApp {
perf: Perf::default(),
titlebar_inset: 0.0,
last_effect: None,
last_warp: None,
run_count: 0,
clipboard_out: None,
clipboard_published: None,