use egui::{Color32, Vec2, vec2};
use egui_styled::prelude::*;
fn make_checkerboard(ctx: &egui::Context) -> egui::TextureHandle {
let size = [32, 32];
let mut pixels = vec![Color32::TRANSPARENT; 32 * 32];
for y in 0..32usize {
for x in 0..32usize {
pixels[y * 32 + x] = if (x / 8 + y / 8) % 2 == 0 {
Color32::from_rgb(255, 140, 0)
} else {
Color32::WHITE
};
}
}
ctx.load_texture(
"checkerboard",
egui::ColorImage::new(size, pixels),
egui::TextureOptions::NEAREST,
)
}
fn images_ui(ui: &mut egui::Ui, handle: &egui::TextureHandle) {
let sized = egui::load::SizedTexture::from_handle(handle);
let src = || egui::ImageSource::Texture(sized);
ui.heading("egui_styled - Images");
ui.add_space(16.0);
ui.label("StyledImage - exact size, themed border + corner radius:");
ui.add_space(8.0);
Styled::image(src())
.size(Vec2::splat(64.0))
.corner_radius(12.0)
.border(2.0, Color32::WHITE)
.show(ui);
ui.add_space(16.0);
ui.label("StyledImage - drop shadow:");
ui.add_space(8.0);
Styled::image(src())
.size(Vec2::splat(64.0))
.corner_radius(8.0)
.shadow_filled(vec2(4.0, 4.0), Color32::from_black_alpha(120))
.show(ui);
ui.add_space(16.0);
ui.label("StyledImage - hover tint (hover me):");
ui.add_space(8.0);
Styled::image(src())
.size(Vec2::splat(64.0))
.corner_radius(8.0)
.border(1.0, Color32::from_gray(100))
.hover_tint(Color32::from_rgba_unmultiplied(100, 160, 255, 200))
.id("hover_tint_demo")
.show(ui);
ui.add_space(16.0);
ui.label("StyledImage - circle clip (corner_radius = half size):");
ui.add_space(8.0);
Styled::image(src())
.size(Vec2::splat(64.0))
.corner_radius(32.0)
.border(2.0, Color32::from_gray(160))
.show(ui);
ui.add_space(32.0);
ui.label("background_image on Styled::frame - stretch fill, rounded corners:");
ui.add_space(8.0);
Styled::frame()
.background_image(src())
.corner_radius(16.0)
.padding(24.0)
.show(ui, |ui| {
ui.label(
egui::RichText::new("Text over a textured background")
.color(Color32::WHITE)
.strong(),
);
ui.add_space(8.0);
Styled::button("Button inside textured frame")
.bg(Color32::from_black_alpha(160))
.hover_bg(Color32::from_black_alpha(210))
.text_color(Color32::WHITE)
.corner_radius(6.0)
.show(ui);
});
ui.add_space(16.0);
ui.label("background_image + tint + bg fill (solid fallback while loading):");
ui.add_space(8.0);
Styled::frame()
.bg(Color32::from_rgb(40, 40, 60))
.background_image(src())
.background_image_tint(Color32::from_rgba_unmultiplied(255, 255, 255, 180))
.corner_radius(12.0)
.border(1.0, Color32::from_gray(80))
.padding(20.0)
.show(ui, |ui| {
ui.label(
egui::RichText::new("Semi-transparent texture over a solid fill")
.color(Color32::WHITE),
);
});
ui.add_space(16.0);
ui.label("background_image - Cover fit (crop, not stretch) on a wide frame:");
ui.add_space(8.0);
Styled::frame()
.full_width()
.background_image(src())
.background_image_fit(BackgroundImageFit::Cover)
.corner_radius(8.0)
.min_height(80.0)
.padding(16.0)
.show(ui, |ui| {
ui.label(
egui::RichText::new("Wide frame, Cover fit preserves aspect ratio")
.color(Color32::WHITE),
);
});
}
struct ImagesApp {
handle: Option<egui::TextureHandle>,
}
impl eframe::App for ImagesApp {
fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) {
let handle = self
.handle
.get_or_insert_with(|| make_checkerboard(ui.ctx()))
.clone();
images_ui(ui, &handle);
}
}
fn main() -> eframe::Result<()> {
eframe::run_native(
"egui_styled images",
eframe::NativeOptions {
viewport: egui::ViewportBuilder::default().with_inner_size([640.0, 700.0]),
..Default::default()
},
Box::new(|_cc| Ok(Box::new(ImagesApp { handle: None }))),
)
}