Repository navigation
fix(ui): reserve popup header space for controls #955
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -2917,6 +2917,53 @@ fn dynamic_text_is_a_menu_of_values_that_starts_the_text() { | |||||
| assert_eq!(h.state().ui.dynamic_text, None); | ||||||
| } | ||||||
|
|
||||||
| #[test] | ||||||
| fn popup_titles_leave_room_for_controls() { | ||||||
| use egui::accesskit::Role; | ||||||
|
|
||||||
| for title in ["Oak".to_string(), "HIDDEN INTERSECTION Tab Sign (Oversized) ".repeat(4), "長い地物名".repeat(30)] { | ||||||
| for count in [1, 2] { | ||||||
| let mut h = harness(); | ||||||
| h.ctx.set_missing_glyph_policy(egui::MissingGlyphPolicy::Tofu); | ||||||
| let features: Vec<_> = (0..count) | ||||||
| .map(|_| json!({"type": "Feature", "properties": {"name": title}, "geometry": {"type": "Point", "coordinates": [0, 0]}})) | ||||||
| .collect(); | ||||||
| h.state_mut() | ||||||
| .run( | ||||||
| "layer.addDataText", | ||||||
| json!({ | ||||||
| "fileName": "popup.geojson", | ||||||
| "name": "A layer with a name much longer than the popup header can hold", | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The layer name is set to a long string here, but the test never asserts on it. Only the feature title is checked against the close, previous and next buttons. The PR description says layer names are bounded too, so this is a coverage gap. Consider also finding the layer label (
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Both labels use the same bounded column, and the rendered long-layer case was inspected. Keeping the regression focused on title overlap and control interactions. (reviewed at 5e660e8) |
||||||
| "text": json!({"type": "FeatureCollection", "features": features}).to_string() | ||||||
| }), | ||||||
| ) | ||||||
| .unwrap(); | ||||||
| h.state_mut().run("map.zoomToExtent", json!({"extent": [-5, -4, 5, 4]})).unwrap(); | ||||||
| h.ctx.data_mut(|d| d.insert_temp(egui::Id::unique("identify_popup_limit"), egui::vec2(240.0, 360.0))); | ||||||
| h.state_mut().run("ui.identify", json!({"lon": 0, "lat": 0})).unwrap(); | ||||||
| h.run_steps(6); | ||||||
|
|
||||||
| let title_rect = h.query_all_by_label(&title).map(|n| n.rect()).min_by(|a, b| a.min.y.total_cmp(&b.min.y)).unwrap(); | ||||||
|
coderabbitai[bot] marked this conversation as resolved.
|
||||||
| let close = h.get_by_role_and_label(Role::Button, "×").rect(); | ||||||
| assert!(close.max.x <= title_rect.min.x - 12.0 + 240.0, "close must stay inside the popup"); | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bound is looser than it claims. The popup's right edge is
Suggested change
Confidence: medium.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This assertion intentionally checks outer popup containment; exact right padding is not its contract. Separate assertions check title/control separation. (reviewed at 5e660e8) |
||||||
| assert!(title_rect.max.x < close.min.x, "title must leave room for close"); | ||||||
| if count > 1 { | ||||||
| let previous = h.get_by_role_and_label(Role::Button, "‹").rect(); | ||||||
| assert!(title_rect.max.x < previous.min.x, "title must leave room for all navigation controls"); | ||||||
| h.get_by_role_and_label(Role::Button, "›").click(); | ||||||
| h.run_steps(3); | ||||||
| assert_eq!(h.state().map.popup.as_ref().unwrap().index, 1); | ||||||
| h.get_by_role_and_label(Role::Button, "‹").click(); | ||||||
| h.run_steps(3); | ||||||
| assert_eq!(h.state().map.popup.as_ref().unwrap().index, 0); | ||||||
| } | ||||||
| h.get_by_role_and_label(Role::Button, "×").click(); | ||||||
| h.run_steps(3); | ||||||
| assert!(h.state().map.popup.is_none(), "close must remain clickable"); | ||||||
| } | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| #[test] | ||||||
| fn the_popup_closes_when_its_feature_is_deleted() { | ||||||
| let mut h = harness(); | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possible visual regression: header controls are now top-aligned. Before, the controls sat in a
ui.horizontal(centre cross-axis), so × / zoom / ‹ › were vertically centred against the two-line title block. Nowright_to_left(Align::Min)pins them to the top. Other header rows in this crate useright_to_left(Align::Center)(e.g.panes.rs:612,chrome.rs:342), which suggests centring is the house style. Please compare the "after" screenshot against the old placement. If the controls moved,egui::Align::Centeris the likely fix, though it's worth checking that egui centres controls laid out before the title block. Confidence: medium (I could not render it).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Compared the attached before/after renders: controls remain aligned with the first title line. The previous inner control layout also used
Align::Min; retaining the current layout. (reviewed at 5e660e8)