M8: reuse application field lifecycle for selection opacity

This commit is contained in:
Carbocode committed 2026-11-05 09:59:05 +01:00
1 parent d68a140755
commit 0b68405d85
2 files changed
+10 -10

No files matched your search

+7 -1
View File
@@ -89,12 +89,18 @@ impl FigApp {
/// Apply a field edit through any command: `params` builds the command's params from the value.
pub fn field_run(&mut self, edit: Option<FieldEdit>, cmd: &str, params: impl Fn(f64) -> Value) {
self.field_run_named(edit, "Edit", cmd, params);
}
/// Apply a field edit with a specific undo label for scrubs; commit only on release.
/// Typed edits use `run`; scrub errors are discarded as in `field_run`.
pub(crate) fn field_run_named(&mut self, edit: Option<FieldEdit>, label: &str, cmd: &str, params: impl Fn(f64) -> Value) {
match edit {
Some(FieldEdit::Set(v)) => {
self.run(cmd, params(v));
}
Some(FieldEdit::Scrub(v, done)) => {
let _ = self.session.begin_interaction("Edit");
let _ = self.session.begin_interaction(label);
let _ = self.session.execute(cmd, &params(v));
if done {
let _ = self.session.commit_interaction();
@@ -157,15 +157,7 @@ pub fn section(app: &mut FigApp, ui: &mut Ui, doc: &Arc<Document>, ids: &[NodeId
d.remove::<OpacityScrub>(scrub_key);
}
});
if scrub {
let _ = app.session.begin_interaction("Opacity");
let _ = app.session.execute("selection.setPaint", &json!({"targets": group.targets, "paint": paint}));
if done {
let _ = app.session.commit_interaction();
}
} else {
app.run("selection.setPaint", json!({"targets": group.targets, "paint": paint}));
}
app.field_run_named(Some(edit), "Opacity", "selection.setPaint", |_| json!({"targets": group.targets, "paint": paint}));
}
widgets::tight_end(ui, |ui| {
if linked_name.is_some() {
@@ -469,6 +461,7 @@ mod tests {
for dx in [-10.0, -20.0, -30.0] {
p.frame(vec![Event::PointerMoved(start + vec2(dx, 0.0))]);
}
assert!(p.app.session.ds().unwrap().interaction.is_some(), "the scrub commits only on release");
assert!(p.frame(vec![]).iter().any(|(text, _)| text == "70%"), "the live opacity stays visible while scrubbing");
p.frame(vec![Event::PointerButton {
pos: start - vec2(30.0, 0.0),
@@ -478,6 +471,7 @@ mod tests {
}]);
assert!(p.app.session.ds().unwrap().interaction.is_none());
assert_eq!(p.app.session.doc().unwrap().node(a).unwrap().fills[0].opacity, 0.7);
assert_eq!(p.app.session.undo_labels(1), ["Opacity"], "the shared helper preserves the scrub's undo label");
p.app.run("edit.undo", json!({}));
assert_eq!(p.app.session.doc().unwrap().node(a).unwrap().fills[0].opacity, 1.0);
assert_eq!(p.app.session.selection().len(), 2);