1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
//! Interaction check for the enriched ROI manager panel
//! (`PlotWidget::show_roi_manager`), the rsplot port of silx
//! `RegionOfInterestTableWidget`. The panel renders one row per ROI — an
//! editable name, the geometry shown as a make-current selector, and a remove
//! button — plus the add / clear-all controls.
//!
//! This drives the panel through a headless egui_kittest harness and asserts,
//! via accesskit queries and a real click, that:
//! * the table renders a row for every ROI (the per-ROI geometry labels and
//! the column headers are present), and
//! * clicking a row's geometry selector makes that ROI the current one
//! (silx row selection → `sigCurrentRoiChanged`), routed through the
//! `set_current_roi` owner API.
//!
//! Mirrors `tests/scene_window_render.rs`' accesskit interaction harness. Needs
//! a GPU (real or software) for the render backend.
use std::cell::RefCell;
use std::rc::Rc;
use egui_kittest::Harness;
use egui_kittest::kittest::Queryable;
use egui_kittest::wgpu::{WgpuTestRenderer, create_render_state, default_wgpu_setup};
use rsplot::egui;
use rsplot::{PlotWidget, Roi};
const W: f32 = 360.0;
const H: f32 = 300.0;
/// The exact text the manager shows for a `Roi::Rect`, mirroring the private
/// `roi_description` Rect arm in `high_level.rs`. Used to query/click a specific
/// row's geometry selector by its accesskit label.
fn rect_desc(x: (f64, f64), y: (f64, f64)) -> String {
format!(
"Rect x=[{:.3}, {:.3}] y=[{:.3}, {:.3}]",
x.0, x.1, y.0, y.1
)
}
#[test]
fn roi_manager_table_renders_rows_and_click_makes_current() {
let rs = create_render_state(default_wgpu_setup());
rsplot::install(&rs);
// Two ROIs at distinct positions → distinct geometry labels, so each row's
// make-current selector is uniquely addressable by accesskit label.
let alpha = ((1.0, 2.0), (1.0, 2.0));
let beta = ((5.0, 6.0), (5.0, 6.0));
let mut plot = PlotWidget::new(&rs, 0);
let i_alpha = plot.add_roi(Roi::Rect {
x: alpha.0,
y: alpha.1,
});
plot.set_roi_name(i_alpha, "alpha");
let i_beta = plot.add_roi(Roi::Rect {
x: beta.0,
y: beta.1,
});
plot.set_roi_name(i_beta, "beta");
// No ROI is current until the user selects one.
assert_eq!(plot.current_roi(), None, "no ROI current before selection");
let app = Rc::new(RefCell::new(plot));
let app_ui = app.clone();
let renderer = WgpuTestRenderer::from_render_state(rs);
let mut harness = Harness::builder()
.with_size(egui::vec2(W, H))
.with_pixels_per_point(1.0)
.renderer(renderer)
.build_ui(move |ui| {
app_ui.borrow_mut().show_roi_manager(ui);
});
harness.step();
// The table rendered: column headers and a geometry row for each ROI.
assert!(
harness.query_by_label("Name").is_some(),
"the manager table must show its Name column header"
);
assert!(
harness.query_by_label("Region").is_some(),
"the manager table must show its Region column header"
);
assert!(
harness
.query_by_label(&rect_desc(alpha.0, alpha.1))
.is_some(),
"the table must render a row for the first ROI"
);
assert!(
harness.query_by_label(&rect_desc(beta.0, beta.1)).is_some(),
"the table must render a row for the second ROI"
);
// Click the second ROI's geometry selector → it becomes current.
harness.get_by_label(&rect_desc(beta.0, beta.1)).click();
harness.run();
assert_eq!(
app.borrow().current_roi(),
Some(i_beta),
"clicking a row's geometry selector must make that ROI current"
);
}