The knobs join a layout::seeded seed, so a changed starting value, option list or range starts every setting over, and a renamed knob no longer fails. new() refuses no knobs, twin names and a number outside its range. Controls are keyed by knob name. The test presses keys without a refresh, so only a notify redraws, and walks the switch twice, the slider twice and a pick the owner takes away.
134 lines
3.7 KiB
Rust
134 lines
3.7 KiB
Rust
use gpui::{
|
|
AnyElement, Context, FocusHandle, InteractiveElement, IntoElement, KeyUpEvent, Keystroke,
|
|
ParentElement, Render, Styled, TestAppContext, VisualTestContext, Window, div, px,
|
|
};
|
|
|
|
use std::cell::Cell;
|
|
|
|
use super::{Knob, Playground};
|
|
use crate::{
|
|
forms,
|
|
primitives::{FocusNext, FocusPrev, FocusScope},
|
|
theme::Theme,
|
|
};
|
|
|
|
struct Stage {
|
|
root: FocusHandle,
|
|
}
|
|
|
|
impl Render for Stage {
|
|
fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
|
|
FocusScope::new(&self.root)
|
|
.root()
|
|
.size_full()
|
|
.child(div().w(px(600.0)).child(playground()))
|
|
}
|
|
}
|
|
|
|
thread_local! {
|
|
static LARGE: Cell<bool> = const { Cell::new(true) };
|
|
}
|
|
|
|
fn playground() -> AnyElement {
|
|
Playground::new(
|
|
"playground",
|
|
[
|
|
Knob::Toggle("disabled".into(), false),
|
|
Knob::Choice(
|
|
"size".into(),
|
|
["Sm", "Md", "Lg"][..2 + usize::from(LARGE.get())]
|
|
.iter()
|
|
.map(|size| (*size).into())
|
|
.collect(),
|
|
1,
|
|
),
|
|
Knob::Number("share".into(), 0.5, (0.0, 1.0), 0.25),
|
|
],
|
|
|settings, _, _| {
|
|
let shown = format!(
|
|
"preview-{}-{}-{:.2}",
|
|
settings.on("disabled"),
|
|
settings.picked("size"),
|
|
settings.number("share")
|
|
);
|
|
div().debug_selector(|| shown).into_any_element()
|
|
},
|
|
)
|
|
.into_any_element()
|
|
}
|
|
|
|
fn settle(cx: &mut VisualTestContext) {
|
|
for _ in 0..3 {
|
|
cx.run_until_parked();
|
|
cx.update(|window, _| window.refresh());
|
|
}
|
|
cx.run_until_parked();
|
|
}
|
|
|
|
/// Presses a key with no refresh of its own, so only what notifies redraws.
|
|
fn press(key: &str, cx: &mut VisualTestContext) {
|
|
cx.simulate_keystrokes(key);
|
|
cx.run_until_parked();
|
|
cx.simulate_event(KeyUpEvent {
|
|
keystroke: Keystroke::parse(key).expect("a key"),
|
|
});
|
|
cx.run_until_parked();
|
|
}
|
|
|
|
/// Each knob's edit redraws the preview with the new settings.
|
|
#[gpui::test]
|
|
fn knobs_redraw_the_preview(cx: &mut TestAppContext) {
|
|
cx.update(|cx| {
|
|
Theme::init(cx);
|
|
forms::bind_keys(cx);
|
|
cx.bind_keys([
|
|
gpui::KeyBinding::new("tab", FocusNext, None),
|
|
gpui::KeyBinding::new("shift-tab", FocusPrev, None),
|
|
]);
|
|
});
|
|
let (view, cx) = cx.add_window_view(|_, cx| Stage {
|
|
root: cx.focus_handle(),
|
|
});
|
|
let root = view.read_with(cx, |stage, _| stage.root.clone());
|
|
cx.update(|window, _| window.focus(&root));
|
|
settle(cx);
|
|
let shown =
|
|
|selector: &'static str, cx: &mut VisualTestContext| cx.debug_bounds(selector).is_some();
|
|
assert!(shown("preview-false-Md-0.50", cx));
|
|
press("tab", cx);
|
|
press("space", cx);
|
|
assert!(shown("preview-true-Md-0.50", cx), "the switch turned");
|
|
press("tab", cx);
|
|
for key in ["down", "down", "enter"] {
|
|
press(key, cx);
|
|
}
|
|
assert!(shown("preview-true-Lg-0.50", cx), "the choice moved");
|
|
press("tab", cx);
|
|
press("right", cx);
|
|
press("right", cx);
|
|
assert!(
|
|
shown("preview-true-Lg-1.00", cx),
|
|
"the number stepped twice"
|
|
);
|
|
assert!(
|
|
shown("knob-readout-share-1.00", cx),
|
|
"its readout in the step's places"
|
|
);
|
|
press("shift-tab", cx);
|
|
press("shift-tab", cx);
|
|
press("space", cx);
|
|
assert!(
|
|
shown("preview-false-Lg-1.00", cx),
|
|
"the switch showed its own setting, so a second press turned it back"
|
|
);
|
|
LARGE.set(false);
|
|
settle(cx);
|
|
press("tab", cx);
|
|
press("tab", cx);
|
|
press("right", cx);
|
|
assert!(
|
|
shown("preview-false-Md-0.75", cx),
|
|
"the owner took away the picked size, so every setting started over"
|
|
);
|
|
}
|