mirror of
https://github.com/emilk/egui.git
synced 2026-08-29 21:00:03 -04:00
Combined example
This commit is contained in:
95
tests/egui_tests/tests/atom_wrap_overflow.rs
Normal file
95
tests/egui_tests/tests/atom_wrap_overflow.rs
Normal file
@@ -0,0 +1,95 @@
|
||||
//! Repro for a wrapping bug: a `grow`, wrapping nested [`AtomLayout`] placed next to a fixed-width
|
||||
//! sibling (think: the atom-layout demo's tag-filter sidebar + card gallery) wraps "too late" and
|
||||
//! overflows the container.
|
||||
//!
|
||||
//! The layout under test is a non-wrapping row of `[ fixed sidebar · grow wrapping gallery ]`,
|
||||
//! forced to the container width via `min_size`. We render it at a range of shrinking container
|
||||
//! widths and assert the laid-out width never exceeds the container.
|
||||
|
||||
use egui::{Atom, AtomExt as _, AtomLayout, Atoms, CornerRadius, Frame, Margin, Stroke, Vec2};
|
||||
use egui_kittest::Harness;
|
||||
use std::cell::Cell;
|
||||
|
||||
const SIDEBAR_WIDTH: f32 = 120.0;
|
||||
const GAP: f32 = 12.0;
|
||||
|
||||
fn chip_frame() -> Frame {
|
||||
Frame::new()
|
||||
.inner_margin(Margin::symmetric(6, 2))
|
||||
.corner_radius(CornerRadius::same(4))
|
||||
.stroke(Stroke::new(1.0, egui::Color32::GRAY))
|
||||
}
|
||||
|
||||
/// A single grow chip, like a tag button in the demo.
|
||||
fn chip(word: &str) -> Atom<'static> {
|
||||
Atom::layout(AtomLayout::new(word.to_owned()).frame(chip_frame())).atom_grow(true)
|
||||
}
|
||||
|
||||
/// `[ fixed sidebar · grow wrapping gallery of chips ]`, forced to `width` via `min_size`.
|
||||
fn root(width: f32) -> AtomLayout<'static> {
|
||||
let words = [
|
||||
"aurora",
|
||||
"night",
|
||||
"long-exposure",
|
||||
"iceland",
|
||||
"winter",
|
||||
"jungle",
|
||||
"macro",
|
||||
"wildlife",
|
||||
"humid",
|
||||
"sahara",
|
||||
"golden-hour",
|
||||
"minimal",
|
||||
];
|
||||
let mut chips = Atoms::default();
|
||||
for word in words {
|
||||
chips.push_right(chip(word));
|
||||
}
|
||||
let gallery = Atom::layout(AtomLayout::new(chips).wrap(true).gap(6.0)).atom_grow(true);
|
||||
|
||||
let sidebar =
|
||||
Atom::layout(AtomLayout::new("sidebar").frame(chip_frame())).atom_max_width(SIDEBAR_WIDTH);
|
||||
|
||||
AtomLayout::new((sidebar, gallery))
|
||||
.gap(GAP)
|
||||
.min_size(Vec2::new(width, 0.0))
|
||||
}
|
||||
|
||||
/// Render `root` at the given container width and return the laid-out (allocated) width.
|
||||
fn laid_out_width(width: f32) -> f32 {
|
||||
let measured = Cell::new(0.0_f32);
|
||||
let mut harness = Harness::builder()
|
||||
.with_size(Vec2::new(width, 600.0))
|
||||
.build_ui(|ui| {
|
||||
let avail = ui.available_width();
|
||||
let response = root(avail).show(ui);
|
||||
measured.set(response.response.rect.width());
|
||||
});
|
||||
harness.run();
|
||||
measured.get()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn atom_wrap_no_overflow_when_shrinking() {
|
||||
let mut failures = Vec::new();
|
||||
|
||||
// Shrink the container step by step.
|
||||
for width in (260..=820).rev().step_by(40) {
|
||||
let w = width as f32;
|
||||
let laid_out = laid_out_width(w);
|
||||
let overflow = laid_out - w;
|
||||
println!("container {w:6.1} -> laid out {laid_out:7.1} (overflow {overflow:+.1})");
|
||||
// Allow a pixel of rounding slack.
|
||||
if overflow > 1.0 {
|
||||
failures.push(format!(
|
||||
"container {w:.1}: laid out {laid_out:.1} (overflow {overflow:.1}px)"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
assert!(
|
||||
failures.is_empty(),
|
||||
"the wrapping layout overflowed its container:\n{}",
|
||||
failures.join("\n")
|
||||
);
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e43b410ab0a06b40da5ad9c7fd105d11201d44a3afd63fd213429cc39013c0d4
|
||||
oid sha256:d1aac2317afe29ae297b9082d236432327df4f5210b91b0d5694ae2deec765e1
|
||||
size 6964
|
||||
|
||||
Reference in New Issue
Block a user