Keep activation borders above message label backplates
This commit is contained in:
@@ -118,6 +118,99 @@ fn scene(f: &Fixture) -> Scene {
|
||||
fn bar(scene: &Scene, call: Id) -> &Segment {
|
||||
scene.activations.iter().find(|a| a.call == call).unwrap()
|
||||
}
|
||||
|
||||
fn long_labels(f: &mut Fixture) {
|
||||
for occurrence in [f.call, f.inner, f.inner_reply, f.reply] {
|
||||
f.project.elements.get_mut(&occurrence).unwrap().name =
|
||||
"Pressure verification with a descriptive operation label".into();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn activation_shoulders_under_label_backplates_select_their_call() {
|
||||
for layer in [Layer::Oa, Layer::Sa] {
|
||||
let mut f = fixture(layer, true);
|
||||
long_labels(&mut f);
|
||||
let scene = scene(&f);
|
||||
let outer = bar(&scene, f.call);
|
||||
for occurrence in [f.inner, f.inner_reply, f.reply] {
|
||||
let message = line(&scene, occurrence);
|
||||
let shoulder = Point::new(outer.rect.x + 1., message.label_at.y + 11.);
|
||||
assert!(outer.rect.contains(shoulder));
|
||||
assert!(Rectangle::new(message.label_at, Size::new(225., 22.)).contains(shoulder));
|
||||
assert!(message.label.chars().count() > 32);
|
||||
assert!(message.points.windows(2).all(|p| {
|
||||
crate::diagram::distance_to_segment(shoulder, p[0], p[1]) > 8. / scene.scale
|
||||
}));
|
||||
assert_eq!(scene.hit(shoulder), Some(f.call));
|
||||
assert_eq!(
|
||||
scene.hit(message.label_at + iced::Vector::new(4., 4.)),
|
||||
Some(occurrence),
|
||||
"Label text outside activations remains selectable"
|
||||
);
|
||||
}
|
||||
for occurrence in [f.call, f.inner, f.inner_reply, f.reply] {
|
||||
let message = line(&scene, occurrence);
|
||||
for endpoint in [message.points[0], *message.points.last().unwrap()] {
|
||||
assert_eq!(scene.hit(endpoint), Some(occurrence));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn long_message_backplates_do_not_erase_selected_activation_border_pixels() {
|
||||
use iced::advanced::renderer::Headless;
|
||||
use iced_runtime::user_interface::{Cache, UserInterface};
|
||||
|
||||
let mut mounted = crate::behavior::canvas_workspace::tests::Mounted::unshown().await;
|
||||
let mut f = fixture(Layer::Oa, true);
|
||||
long_labels(&mut f);
|
||||
let mut scene = scene(&f);
|
||||
scene.selected = f.call;
|
||||
let border_x = bar(&scene, f.call).rect.x;
|
||||
let label_spans: Vec<_> = [f.inner, f.inner_reply, f.reply]
|
||||
.into_iter()
|
||||
.map(|id| {
|
||||
let message = line(&scene, id);
|
||||
assert!(
|
||||
Rectangle::new(message.label_at, Size::new(225., 22.))
|
||||
.contains(Point::new(border_x, message.label_at.y + 11.))
|
||||
);
|
||||
(message.label_at.y + 3.) as usize..(message.label_at.y + 20.) as usize
|
||||
})
|
||||
.collect();
|
||||
let dimensions = Size::new(800., 700.);
|
||||
let content: Element<'_, Message> = canvas::Canvas::new(scene)
|
||||
.width(dimensions.width)
|
||||
.height(dimensions.height)
|
||||
.into();
|
||||
let mut ui = UserInterface::build(content, dimensions, Cache::new(), &mut mounted.renderer);
|
||||
ui.draw(
|
||||
&mut mounted.renderer,
|
||||
&style::theme(),
|
||||
&iced::advanced::renderer::Style {
|
||||
text_color: style::INK,
|
||||
},
|
||||
mouse::Cursor::Unavailable,
|
||||
);
|
||||
let pixels = Headless::screenshot(&mut mounted.renderer, Size::new(800, 700), 1., Color::WHITE);
|
||||
let expected = [style::TEAL.r, style::TEAL.g, style::TEAL.b].map(|v| v * 255.);
|
||||
for span in label_spans {
|
||||
for y in span {
|
||||
assert!(
|
||||
((border_x as usize - 2)..=(border_x as usize + 2)).any(|x| {
|
||||
let offset = (y * 800 + x) * 4;
|
||||
pixels[offset..offset + 3]
|
||||
.iter()
|
||||
.zip(expected)
|
||||
.all(|(actual, target)| (*actual as f32 - target).abs() < 30.)
|
||||
}),
|
||||
"Selected activation border was erased at y={y}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
fn line(scene: &Scene, occurrence: Id) -> &super::super::Line {
|
||||
scene.lines.iter().find(|a| a.id == occurrence).unwrap()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user