Settings: a dragged UI Scale applies on release (#2582)

Dragging an integer setting applied every step, so UI Scale resized the
interface under the pointer mid-drag. A dragged value now shows in its
field and applies when the button is released (a typed one already
waited for Enter).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
bflatastic
2026-10-30 07:53:12 +07:00
co-authored by Claude Opus 5.5
parent e6f2cce7d5
commit 1158022585
2 changed files with 39 additions and 4 deletions
+9 -4
View File
@@ -117,15 +117,20 @@ fn page_ui(app: &mut EffectcraftApp, ui: &mut egui::Ui, page: &Page, cur: &Value
ui.add_sized(vec2(label_w, 18.0), egui::Label::new(format!("{}:", tr(label))).truncate());
let r = match kind {
Kind::Int(lo, hi, unit) => {
let mut x = v.as_i64().unwrap_or(0);
// A typed number applies once entered: typing 85 into UI Scale
// doesn't resize the interface to 75 % at its first digit.
// A dragged value applies on release, and a typed one once
// entered: UI Scale doesn't resize the interface under the
// pointer mid-drag (#2582) or at a typed number's first digit.
let held = egui::Id::unique(("settings-drag", key));
let mut x = ui.data(|d| d.get_temp::<i64>(held)).unwrap_or_else(|| v.as_i64().unwrap_or(0));
let drag = egui::DragValue::new(&mut x).range(lo..=hi).speed(0.25).update_while_editing(false);
let r = ui.add(crate::widgets::drag_value(drag));
if !unit.is_empty() {
ui.label(RichText::new(tr(unit)).color(t.text_dim));
}
if r.changed() {
if r.dragged() {
ui.data_mut(|d| d.insert_temp(held, x));
} else if r.changed() || r.drag_stopped() {
ui.data_mut(|d| d.remove::<i64>(held));
acts.push(Act::Set(key.into(), json!(x)));
}
r
+30
View File
@@ -664,3 +664,33 @@ fn transition_presets_apply_from_effects_and_presets() {
assert_eq!(fx.name, "Radial Wipe");
assert_eq!(fx.prop("completion").unwrap().keys.len(), 2);
}
/// #2582: dragging Settings' UI Scale doesn't resize the interface under the pointer; the value
/// applies once the button is released.
#[test]
fn ui_scale_applies_when_the_drag_ends() {
let mut h = harness();
open_settings(&mut h);
let e = h.state().auto.find("settings.appearance.uiScale").expect("the UI Scale field");
let from = pos2(e.rect[0] + e.rect[2] / 2.0, e.rect[1] + e.rect[3] / 2.0);
h.input_mut().events.push(Event::PointerMoved(from));
h.input_mut().events.push(Event::PointerButton { pos: from, button: egui::PointerButton::Primary, pressed: true, modifiers: Default::default() });
h.step();
for k in 1..=8 {
h.input_mut().events.push(Event::PointerMoved(from + egui::vec2(10.0 * k as f32, 0.0)));
h.step();
assert_eq!(scale(&h), (100, 1.0), "nothing applies mid-drag");
}
h.input_mut().events.push(Event::PointerButton {
pos: from + egui::vec2(80.0, 0.0),
button: egui::PointerButton::Primary,
pressed: false,
modifiers: Default::default(),
});
h.run_steps(4);
let (pct, zoom) = scale(&h);
assert!(pct > 100 && (zoom - pct as f32 / 100.0).abs() < 1e-6, "applied on release: {pct} {zoom}");
click(&mut h, "settings.cancel");
h.run_steps(2);
assert_eq!(scale(&h), (100, 1.0));
}