mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 17:56:50 -06:00
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:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user