use super::super::drag::{HANDLE, floor};
use super::super::{DESK, EASE, LINGER, SHUT, open_width};
use super::{ROW, panel, said, step, tick};
use crate::test_support::window::seated;
const Y: f32 = 450.0;
fn button(pos: egui::Pos2, pressed: bool) -> egui::Event {
egui::Event::PointerButton {
pos,
button: egui::PointerButton::Primary,
pressed,
modifiers: egui::Modifiers::NONE,
}
}
pub(super) fn drag(
ctx: &egui::Context,
model: &mut crate::ui::Model,
width: f32,
(time, beat): (f64, f64),
from: f32,
by: f32,
) -> egui::FullOutput {
let to = from + by;
let at = |x| egui::pos2(x, Y);
let frames = [
egui::Event::PointerMoved(at(from)),
button(at(from), true),
egui::Event::PointerMoved(at(to)),
egui::Event::PointerMoved(at(to)),
button(at(to), false),
];
let mut last = None;
for (i, event) in (0u8..).zip(frames) {
let now = f64::from(i).mul_add(beat, time);
last = Some(step(ctx, model, width, now, vec![event]));
}
last.expect("five frames")
}
fn opened(output: &egui::FullOutput) -> bool {
said(output).iter().any(|t| t == ROW)
}
pub(super) fn near(got: Option<f32>, want: f32) -> bool {
got.is_some_and(|got| (got - want).abs() < 0.01)
}
#[test]
fn a_collapsed_drag_sets_the_collapsed_width_and_leaves_the_expanded_one() {
let ctx = egui::Context::default();
let mut model = seated();
tick(&ctx, &mut model, 0.0, None);
let grip = egui::pos2(SHUT - HANDLE / 2.0, Y);
let hovered = step(
&ctx,
&mut model,
DESK,
0.5,
vec![egui::Event::PointerMoved(grip)],
);
assert!(!opened(&hovered), "the edge is not the bar");
assert_eq!(
hovered.platform_output.cursor_icon,
egui::CursorIcon::ResizeHorizontal
);
let released = drag(&ctx, &mut model, DESK, (1.0, 0.02), grip.x, 40.0);
assert!(!opened(&released), "shut through the drag");
assert!(
near(model.bar.dragged.shut, SHUT + 40.0),
"{:?}",
model.bar.dragged
);
assert_eq!(
model.bar.dragged.open, None,
"the expanded one is untouched"
);
assert_eq!(model.bar.drag, None, "put down on release");
let rest = tick(&ctx, &mut model, 2.0, None);
assert!(!opened(&rest));
assert!(
near(Some(panel(&ctx)), SHUT + 40.0),
"the glass shows the column"
);
let over = Some(egui::pos2(10.0, Y));
tick(&ctx, &mut model, 3.0, over);
tick(&ctx, &mut model, 3.0 + f64::from(EASE), over);
tick(&ctx, &mut model, 3.1 + f64::from(EASE), over);
assert!(
near(Some(panel(&ctx)), open_width(DESK)),
"the default, eased to"
);
}
#[test]
fn an_expanded_drag_sets_the_expanded_width_and_leaves_the_collapsed_one() {
let ctx = egui::Context::default();
let mut model = seated();
model.bar.pinned = true;
tick(&ctx, &mut model, 0.0, None);
let wide = open_width(DESK);
let released = drag(
&ctx,
&mut model,
DESK,
(1.0, 0.02),
wide - HANDLE / 2.0,
100.0,
);
assert!(opened(&released), "open through the drag");
assert!(
near(model.bar.dragged.open, wide + 100.0),
"{:?}",
model.bar.dragged
);
assert_eq!(
model.bar.dragged.shut, None,
"the collapsed one is untouched"
);
assert!(near(Some(panel(&ctx)), wide + 100.0));
model.bar.pinned = false;
model.bar.left_at = None;
tick(&ctx, &mut model, 2.0, None);
tick(&ctx, &mut model, 2.0 + f64::from(EASE), None);
tick(&ctx, &mut model, 2.1 + f64::from(EASE), None);
assert!(
near(Some(panel(&ctx)), SHUT),
"the default column, eased to"
);
}
#[test]
fn a_drag_writes_the_width_it_began_on_whatever_the_pointer_does() {
let ctx = egui::Context::default();
let mut model = seated();
let over = Some(egui::pos2(10.0, Y));
tick(&ctx, &mut model, 0.0, over);
tick(&ctx, &mut model, 0.2, over);
let wide = open_width(DESK);
let released = drag(
&ctx,
&mut model,
DESK,
(1.0, LINGER),
wide - HANDLE / 2.0,
-100.0,
);
assert!(
opened(&released),
"open through a drag longer than the linger"
);
assert!(
near(model.bar.dragged.open, wide - 100.0),
"{:?}",
model.bar.dragged
);
assert_eq!(model.bar.dragged.shut, None);
let away = Some(egui::pos2(900.0, Y));
assert!(
opened(&tick(&ctx, &mut model, 4.0f64.mul_add(LINGER, 1.1), away)),
"lingering from the release"
);
assert!(!opened(&tick(&ctx, &mut model, 20.0, away)), "lapsed");
let released = drag(
&ctx,
&mut model,
DESK,
(21.0, 0.02),
SHUT - HANDLE / 2.0,
-SHUT,
);
assert!(
!opened(&released),
"shut through a drag that crossed into the rows"
);
assert!(
near(model.bar.dragged.shut, floor(&ctx)),
"{:?}",
model.bar.dragged
);
assert!(near(model.bar.dragged.open, wide - 100.0), "untouched");
}