Skip to main content

launcher/widgets/
tile.rs

1use eframe::egui;
2
3/// A generic tile widget for galleries
4pub fn gallery_tile(
5    ui: &mut egui::Ui,
6    rect_size: f32,
7    aspect_ratio: f32,
8    name: &str,
9    extra_ui: impl FnOnce(&mut egui::Ui),
10    texture: Option<&egui::TextureHandle>,
11) -> egui::Response {
12    // Total height includes image area, controls (24px), and spacing
13    let image_height = rect_size / aspect_ratio;
14    let total_height = image_height + 40.0;
15
16    let (rect, response) =
17        ui.allocate_exact_size(egui::vec2(rect_size, total_height), egui::Sense::click());
18
19    let visuals = ui.style().interact(&response);
20
21    // Draw tile background
22    ui.painter().rect_filled(
23        rect,
24        4.0,
25        if response.hovered() {
26            ui.visuals().widgets.hovered.bg_fill
27        } else {
28            ui.visuals().faint_bg_color
29        },
30    );
31
32    ui.painter()
33        .rect_stroke(rect, 4.0, visuals.bg_stroke, egui::StrokeKind::Inside);
34
35    // Define content area for the image
36    let image_rect = egui::Rect::from_min_size(
37        rect.min + egui::vec2(4.0, 4.0),
38        egui::vec2(rect_size - 8.0, image_height - 4.0),
39    );
40
41    if let Some(texture) = texture {
42        ui.painter().image(
43            texture.id(),
44            image_rect,
45            egui::Rect::from_min_max(egui::pos2(0.0, 0.0), egui::pos2(1.0, 1.0)),
46            egui::Color32::WHITE,
47        );
48    } else {
49        ui.painter()
50            .rect_filled(image_rect, 2.0, ui.visuals().widgets.inactive.bg_fill);
51        ui.painter().text(
52            image_rect.center(),
53            egui::Align2::CENTER_CENTER,
54            "No Image",
55            egui::FontId::proportional(12.0),
56            ui.visuals().widgets.inactive.text_color(),
57        );
58    }
59
60    // Controls area
61    let controls_rect = egui::Rect::from_min_size(
62        egui::pos2(rect.min.x + 8.0, rect.min.y + image_height + 8.0),
63        egui::vec2(rect_size - 16.0, 24.0),
64    );
65
66    let mut ui_child = ui.new_child(egui::UiBuilder::new().max_rect(controls_rect));
67    ui_child.horizontal(|ui| {
68        ui.label(egui::RichText::new(name).size(12.0));
69        extra_ui(ui);
70    });
71
72    response
73}