Using egui, I'm trying to lay out some images in a grid.
I have included some sample code below. There are two things I fail to understand about its behaviour.
-
On each row of the grid, the image size grows from one column to the next, starting off with a tiny size until it reaches the maximum width of the containing
group
:
-
If the image is rotated (uncomment the line containing
rotate
in the sample code) then the pre-rotation dimensions and position of the image are taken into account when placing the image into the containinggroup
, consequently the image protrudes[1] beyond thegroup
's boundary:
Can you shed any light on why this is happening, and how I can prevent it from happening?
Here is the code:
// The code I'm struggling with
impl MyImage {
pub fn show(&self, ui: &mut Ui) {
let uri = format!("file://{}", self.path.to_string_lossy());
ui.vertical_centered(|ui| {
ui.group(|ui| {
ui.set_width(50.0);
ui.add(
Image::from_uri(&uri)
.show_loading_spinner(true) // Seems to be ignored
//.shrink_to_fit()
//.rotate(-std::f32::consts::TAU / 4.0, [0.5, 0.5].into())
);
ui.label(&self.label);
})
});
}
}
impl eframe::App for MyApp {
fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
Grid::new("image grid").show(ui, |ui| {
for (n, image) in self.images.iter().enumerate() {
image.show(ui);
if n % 6 == 5 {
ui.end_row();
}
}
});
});
}
}
// Remaining code needed for it compile and run
use std::{
env::args,
path::{Path, PathBuf},
};
use egui::{Grid, Image, Ui};
fn main() {
let mut args = args();
let _executable = args.next();
let path = args.next().unwrap();
let options = eframe::NativeOptions {
viewport: egui::ViewportBuilder::default().with_inner_size([320.0, 240.0]),
..Default::default()
};
eframe::run_native(
"My egui App",
options,
Box::new(|cc| {
egui_extras::install_image_loaders(&cc.egui_ctx);
Ok(Box::<MyApp>::new(MyApp::new(path)))
}),
).unwrap();
}
struct MyApp {
images: Vec<MyImage>,
}
struct MyImage {
path: PathBuf,
label: String,
}
impl MyApp {
fn new(path: impl AsRef<Path>) -> Self {
Self {
// Fake multiple images by repeating the same one
images: (0..10)
.map(|n| MyImage {
path: path.as_ref().into(),
label: format!("Image {n}"),
})
.collect()
}
}
}
rotate around a point away from the centre of the image, such as
[0.0, 0.0]
to make it more obvious ↩︎