Egui: laying out rotated images

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.

  1. 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:

  2. 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 containing group, consequently the image protrudes[1] beyond the group'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()
        }
    }
}

  1. rotate around a point away from the centre of the image, such as [0.0, 0.0] to make it more obvious ↩︎

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.