fix(format): a slider commits only a move to another shown value

changed() also fires when the slider rounds the value it shows, on focus too. Compare the rounded
values, so keyboard and accessibility edits commit without focus and rounding does not.
This commit is contained in:
Harrison Booth
2026-10-27 19:31:36 -05:00
parent 90ce7dcb9b
commit d989389441
+6 -4
View File
@@ -477,16 +477,18 @@ fn fx_slider(
} else {
ui.data_mut(|d| d.remove::<f64>(sid));
}
// `changed()` also fires when the slider only rounds the value it shows (55.000000000000007 to 55,
// or 0.5 to 1 on focus, which re-added a reflection the pane had just cleared): only a move to
// another shown value is an edit. Accessibility and keyboard edits are such moves too.
let shown_changed = r.changed() && v.round() != value.round();
// A slider that only had focus when another control took it (the Reflection "None" button)
// must not commit its stale value: only an edit the user made is committed on losing focus.
let edited_id = sid.with("edited");
if r.changed() {
if shown_changed {
ui.data_mut(|d| d.insert_temp(edited_id, true));
}
let edited = ui.data_mut(|d| d.get_temp::<bool>(edited_id)).unwrap_or(false);
// `changed()` alone also fires when the slider only rounds the shown value (55.000000000000007 to 55),
// which re-added a reflection the pane had just cleared; a keyboard edit has focus.
if r.drag_stopped() || (r.lost_focus() && edited) || (r.changed() && !r.dragged() && r.has_focus()) {
if r.drag_stopped() || (r.lost_focus() && edited) || (shown_changed && !r.dragged()) {
ui.data_mut(|d| {
d.remove::<f64>(sid);
d.remove::<bool>(edited_id);