use crate::theme::MacTheme;
use egui::{CornerRadius, Painter, Rect, Response, Stroke, StrokeKind, Ui, Vec2, Widget};
pub type ThumbnailDrawer<'a> = Box<dyn FnOnce(&Painter, Rect) + 'a>;
#[derive(Default)]
pub struct MacThumbnailCell<'a> {
selected: bool,
theme: Option<&'a MacTheme>,
size: Option<Vec2>,
corner_radius: Option<f32>,
border_width: Option<f32>,
drawer: Option<ThumbnailDrawer<'a>>,
}
impl<'a> MacThumbnailCell<'a> {
pub fn new() -> Self {
Self::default()
}
pub fn selected(mut self, selected: bool) -> Self {
self.selected = selected;
self
}
pub fn theme(mut self, theme: &'a MacTheme) -> Self {
self.theme = Some(theme);
self
}
pub fn size(mut self, size: Vec2) -> Self {
self.size = Some(size);
self
}
pub fn square(mut self, side: f32) -> Self {
self.size = Some(Vec2::splat(side));
self
}
pub fn corner_radius(mut self, radius: f32) -> Self {
self.corner_radius = Some(radius);
self
}
pub fn border_width(mut self, width: f32) -> Self {
self.border_width = Some(width);
self
}
pub fn custom_draw(mut self, drawer: impl FnOnce(&Painter, Rect) + 'a) -> Self {
self.drawer = Some(Box::new(drawer));
self
}
pub fn show(self, ui: &mut Ui) -> Response {
self.ui(ui)
}
pub fn paint_in_rect(self, painter: &Painter, rect: Rect, hovered: bool) {
let theme_cow = MacTheme::resolve(self.theme, painter.ctx());
let theme: &MacTheme = &theme_cow;
let metrics = theme.thumbnail();
let corner_radius = self
.corner_radius
.unwrap_or_else(|| metrics.corner_radius.points());
let border_width = self
.border_width
.unwrap_or_else(|| metrics.border_width.points());
let bg_color = if self.selected {
theme.selected_control()
} else if hovered {
theme.control()
} else {
theme.control_background()
};
let stroke_color = if self.selected {
theme.control_accent()
} else {
theme.separator()
};
let border_stroke = Stroke::new(border_width, stroke_color);
painter.rect(
rect,
CornerRadius::same(corner_radius as u8),
bg_color,
border_stroke,
StrokeKind::Inside,
);
if let Some(drawer) = self.drawer {
let inner_rect = rect.shrink(border_width);
drawer(painter, inner_rect);
}
}
}
impl<'a> Widget for MacThumbnailCell<'a> {
fn ui(self, ui: &mut Ui) -> Response {
let theme_cow = MacTheme::resolve(self.theme, ui.ctx());
let theme: &MacTheme = &theme_cow;
let metrics = theme.thumbnail();
let default_side = metrics.size.points();
let size = self.size.unwrap_or_else(|| Vec2::splat(default_side));
let (rect, response) = ui.allocate_exact_size(size, egui::Sense::click());
let painter = ui.painter_at(rect);
let hovered = response.hovered();
self.paint_in_rect(&painter, rect, hovered);
response
}
}