mirror of
https://github.com/storytold/deckcraft.git
synced 2026-10-24 10:37:03 -06:00
Preferences: Interface size applies when the slider is let go (#767)
Dragging the Interface size slider set the interface scale on every frame, which grew or shrank the slider under the pointer and ran it to one of its ends. Keep the value pending in the dialog while the pointer holds the slider and apply it on release; keyboard changes still apply at once.
This commit is contained in:
@@ -2109,9 +2109,21 @@ fn body(app: &mut SlideApp, ui: &mut Ui, d: &mut Dialog) -> bool {
|
||||
if ui.checkbox(&mut dark, "Dark appearance").changed() {
|
||||
let _ = app.run("view.dark", json!({"on": dark}));
|
||||
}
|
||||
let mut scale = app.ui.ui_scale;
|
||||
if ui.add(egui::Slider::new(&mut scale, 0.75..=1.75).text("Interface size")).changed() {
|
||||
app.ui.ui_scale = scale;
|
||||
// While the pointer holds the slider its value only waits in the dialog: applying it
|
||||
// would rescale the slider under the pointer and run it to an end (#767). It applies
|
||||
// on release, and at once from the keyboard.
|
||||
let pending = d.fields.get("uiScale").and_then(|v| v.parse::<f32>().ok());
|
||||
let mut scale = pending.unwrap_or(app.ui.ui_scale);
|
||||
let r = ui.add(egui::Slider::new(&mut scale, 0.75..=1.75).text("Interface size"));
|
||||
if r.is_pointer_button_down_on() {
|
||||
if r.changed() || pending.is_some() {
|
||||
d.fields.insert("uiScale".into(), scale.to_string());
|
||||
}
|
||||
} else {
|
||||
if r.changed() || pending.is_some() {
|
||||
app.ui.ui_scale = scale;
|
||||
}
|
||||
d.fields.remove("uiScale");
|
||||
}
|
||||
ui.label(egui::RichText::new("Editing").font(theme::bold(13.0)));
|
||||
ui.checkbox(&mut app.session.prefs.smart_guides, "Show smart guides");
|
||||
|
||||
@@ -3253,4 +3253,38 @@ mod tests {
|
||||
flick(&mut harness, egui::vec2(-24.0, 0.0));
|
||||
assert_eq!(harness.state().show.as_ref().map(|s| s.state.slide), Some(0));
|
||||
}
|
||||
|
||||
/// Preferences › Interface size (#767): dragging the slider leaves the interface size alone
|
||||
/// until the pointer lets go, so the slider doesn't grow under the pointer mid-drag.
|
||||
#[test]
|
||||
fn interface_size_applies_when_the_slider_is_let_go() {
|
||||
let mut harness = egui_kittest::Harness::builder().with_size(egui::vec2(1200.0, 800.0)).build_ui_state(
|
||||
|ui, app: &mut SlideApp| {
|
||||
app.logic(ui.ctx());
|
||||
app.ui(ui);
|
||||
},
|
||||
SlideApp::new(Session::with_new(), Services::default()),
|
||||
);
|
||||
harness.run_steps(2);
|
||||
harness.state_mut().run("app.preferences", json!({})).unwrap();
|
||||
harness.run_steps(4);
|
||||
let before = harness.state().ui.ui_scale;
|
||||
let rect =
|
||||
harness.query_all_by_role_and_label(egui::accesskit::Role::Slider, "Interface size").next().expect("the Interface size slider").rect();
|
||||
let (from, to) = (rect.left_center() + egui::vec2(4.0, 0.0), rect.right_center() - egui::vec2(4.0, 0.0));
|
||||
harness.hover_at(from);
|
||||
harness.run_steps(1);
|
||||
harness.drag_at(from);
|
||||
harness.run_steps(1);
|
||||
for k in 1..=8 {
|
||||
harness.hover_at(from.lerp(to, k as f32 / 8.0));
|
||||
harness.run_steps(1);
|
||||
}
|
||||
assert_eq!(harness.state().ui.ui_scale, before, "nothing rescales while the slider is held");
|
||||
harness.drop_at(to);
|
||||
harness.run_steps(2);
|
||||
let after = harness.state().ui.ui_scale;
|
||||
assert!(after > before + 0.3, "letting go applies the size dragged to: {before} -> {after}");
|
||||
assert!(harness.state().dialog.is_some(), "Preferences stays open");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user