use egui::containers::panel::PanelState;
use super::super::{policy, render};
use crate::paint_probe::frame::Window;
use crate::test_support::window::seated;
use crate::ui::{Model, theme};
const WIDE: (f32, f32) = (1440.0, 900.0);
fn panel(window: &Window, name: &str, model: &mut Model) -> egui::Rect {
let mut rect = egui::Rect::ZERO;
for _ in 0..2 {
window.frame(Vec::new(), |ctx| {
render(ctx, model);
rect =
PanelState::load(ctx, egui::Id::new(name)).map_or(egui::Rect::ZERO, |at| at.rect);
});
}
rect
}
fn button(pos: egui::Pos2, pressed: bool) -> egui::Event {
egui::Event::PointerButton {
pos,
button: egui::PointerButton::Primary,
pressed,
modifiers: egui::Modifiers::NONE,
}
}
fn drag(window: &Window, from: egui::Pos2, to: egui::Pos2, mut body: impl FnMut(&egui::Context)) {
window.frame(vec![egui::Event::PointerMoved(from)], &mut body);
window.frame(vec![button(from, true)], &mut body);
for _ in 0..2 {
window.frame(vec![egui::Event::PointerMoved(to)], &mut body);
}
window.frame(vec![button(to, false)], &mut body);
}
#[test]
fn a_pane_dragged_wider_than_its_rows_does_not_snap_back_to_them() {
let mut model = seated();
let window = Window::sized(WIDE.0, WIDE.1);
let edge = panel(&window, "engines", &mut model).right();
let at = egui::pos2(edge, 400.0);
drag(&window, at, egui::pos2(520.0, 400.0), |ctx| {
render(ctx, &mut model);
});
assert!(
model
.dragged
.list
.is_some_and(|width| (width - 520.0).abs() < 1.0),
"the seat holds what the operator dragged: {:?}",
model.dragged.list
);
for pass in 0..3 {
let held = panel(&window, "engines", &mut model).width();
assert!(
(held - 520.0).abs() < 1.0,
"pass {pass}: the pane snapped back to {held}"
);
}
}
#[test]
fn a_narrower_window_clamps_the_drag_and_never_overwrites_it() {
let mut model = seated();
let mut window = Window::sized(WIDE.0, WIDE.1);
let edge = panel(&window, "engines", &mut model).right();
drag(
&window,
egui::pos2(edge, 400.0),
egui::pos2(520.0, 400.0),
|ctx| render(ctx, &mut model),
);
window.resize(900.0, 900.0);
let squeezed = panel(&window, "engines", &mut model).width();
assert!(squeezed < 520.0, "the narrow window shows {squeezed}");
assert_eq!(
model.dragged.list.map(f32::round),
Some(520.0),
"and the seat still holds the drag"
);
window.resize(WIDE.0, WIDE.1);
let back = panel(&window, "engines", &mut model).width();
assert!((back - 520.0).abs() < 1.0, "it came back to {back}");
}
#[test]
fn an_edge_nobody_dragged_still_follows_the_policy_when_the_window_moves() {
let mut model = seated();
let mut window = Window::sized(800.0, 600.0);
panel(&window, "engines", &mut model);
window.resize(WIDE.0, WIDE.1);
let held = panel(&window, "engines", &mut model).width();
assert_eq!(model.dragged.list, None, "nobody dragged anything");
assert!(
(held - policy::widths(WIDE.0)).abs() < 1.0,
"{held} against the policy's {}",
policy::widths(WIDE.0)
);
}
#[test]
fn the_composers_top_edge_sets_the_rows_and_both_directions_work() {
let mut model = seated();
let window = Window::sized(WIDE.0, WIDE.1);
let edge = panel(&window, "composer", &mut model);
drag(
&window,
egui::pos2(edge.center().x, edge.top()),
egui::pos2(edge.center().x, edge.top() - 80.0),
|ctx| render(ctx, &mut model),
);
let taller = model.dragged.rows.expect("the seat holds the drag");
assert!(taller > theme::COMPOSER_ROWS, "{taller} rows is not taller");
let edge = panel(&window, "composer", &mut model);
drag(
&window,
egui::pos2(edge.center().x, edge.top()),
egui::pos2(edge.center().x, edge.top() + 200.0),
|ctx| render(ctx, &mut model),
);
let shorter = model.dragged.rows.expect("the seat holds the drag");
assert!(
shorter < taller,
"{shorter} rows is not shorter than {taller}"
);
}
#[test]
fn the_narrow_shape_has_no_edge_and_reads_no_drag() {
let mut model = Model {
dragged: crate::ui::Dragged {
list: Some(600.0),
..crate::ui::Dragged::default()
},
..seated()
};
let window = Window::sized(400.0, 800.0);
assert_eq!(
panel(&window, "engines", &mut model),
egui::Rect::ZERO,
"there is no list panel at all"
);
assert_eq!(model.dragged.list, Some(600.0), "and nothing wrote to it");
}