use std::sync::Arc;
use egui::{
epaint::{RectShape, TextShape},
vec2, Color32, CornerRadius, FontSelection, Pos2, Rect, Vec2,
};
use crate::{Header, TitleHeader};
pub(crate) struct PreparedHeader {
content: HeaderContent,
size: Vec2,
}
impl PreparedHeader {
pub(crate) fn size(&self) -> Vec2 {
self.size
}
pub(crate) fn has_content(&self) -> bool {
!matches!(self.content, HeaderContent::None)
}
}
enum HeaderContent {
None,
Title(TitleHeaderContent),
}
struct TitleHeaderContent {
title: Arc<egui::Galley>,
padding: egui::Margin,
background: Color32,
}
pub(crate) fn prepare(ui: &egui::Ui, header: Header, body_color: Color32) -> PreparedHeader {
match header {
Header::None => PreparedHeader {
content: HeaderContent::None,
size: Vec2::ZERO,
},
Header::Title(TitleHeader {
text,
background_color: background,
}) => {
let padding = egui::Margin::same(5);
let background = if background == Color32::PLACEHOLDER {
body_color
} else {
background
};
let title = text.into_galley(ui, None, f32::INFINITY, FontSelection::Default);
let size = padding.sum() + title.rect.size();
PreparedHeader {
content: HeaderContent::Title(TitleHeaderContent {
title,
padding,
background,
}),
size,
}
}
}
}
impl PreparedHeader {
pub(in crate::editor) fn show(
self,
ui: &egui::Ui,
pos: Pos2,
node_size: Vec2,
corner_radius: CornerRadius,
) {
let Self { content, size } = self;
match content {
HeaderContent::None => {}
HeaderContent::Title(TitleHeaderContent {
title,
padding,
background,
}) => {
let rect = Rect::from_min_size(pos, vec2(node_size.x, size.y));
ui.painter()
.add(RectShape::filled(rect, corner_radius, background));
ui.painter().add(TextShape::new(
pos + padding.left_top(),
title,
ui.visuals().text_color(),
));
}
}
}
}