use egui::{FontId, Label, Response, RichText, Shape, Stroke, TextWrapMode, Ui, WidgetText};
use crate::{
impl_style_builders,
style::shared_style::{SharedStyle, paint_shadows, render_scoped},
};
pub struct StyledLabel {
text: WidgetText,
bold: bool,
italics: bool,
wrap_mode: Option<TextWrapMode>,
font: Option<FontId>,
style: SharedStyle,
}
impl StyledLabel {
pub fn new(text: impl Into<WidgetText>) -> Self {
Self {
text: text.into(),
bold: false,
italics: false,
wrap_mode: None,
font: None,
style: SharedStyle::default(),
}
}
pub fn bold(mut self) -> Self {
self.bold = true;
self
}
pub fn italics(mut self) -> Self {
self.italics = true;
self
}
pub fn wrap_mode(mut self, mode: TextWrapMode) -> Self {
self.wrap_mode = Some(mode);
self
}
pub fn extend(self) -> Self {
self.wrap_mode(TextWrapMode::Extend)
}
pub fn truncate(self) -> Self {
self.wrap_mode(TextWrapMode::Truncate)
}
pub fn wrap(self) -> Self {
self.wrap_mode(TextWrapMode::Wrap)
}
pub fn font(mut self, font: FontId) -> Self {
self.font = Some(font);
self
}
pub fn show(self, ui: &mut Ui) -> Response {
let visible = self.style.visible != Some(false);
let mut rich = match self.text {
WidgetText::RichText(rt) => (*rt).clone(),
other => RichText::new(other.text().to_string()),
};
if let Some(color) = self.style.text_color {
rich = rich.color(color);
}
if let Some(font) = self.font.clone() {
rich = rich.font(font);
} else if let Some(size) = self.style.font_size {
rich = rich.size(size);
}
if self.bold {
rich = rich.strong();
}
if self.italics {
rich = rich.italics();
}
let mut label = Label::new(rich);
if let Some(mode) = self.wrap_mode {
label = label.wrap_mode(mode);
}
let visuals = ui.visuals().clone();
let wv = &visuals.widgets.inactive;
let bg = self.style.bg.unwrap_or(egui::Color32::TRANSPARENT);
let border = self.style.border.unwrap_or(Stroke::NONE);
let corner_radius = self.style.corner_radius.unwrap_or(wv.corner_radius);
let padding = self.style.padding.unwrap_or_default();
let margin = self.style.margin.unwrap_or_default();
let response = render_scoped(ui, visible, |ui| {
let shadow_idx = ui.painter().add(Shape::Noop);
let response = egui::Frame::new()
.fill(bg)
.stroke(border)
.corner_radius(corner_radius)
.inner_margin(padding)
.outer_margin(margin)
.show(ui, |ui| {
if self.style.full_width {
ui.set_min_width(ui.available_width());
}
if let Some(min_w) = self.style.min_width {
ui.set_min_width(min_w);
}
if let Some(min_h) = self.style.min_height {
ui.set_min_height(min_h);
}
ui.add(label)
})
.inner;
paint_shadows(
ui,
shadow_idx,
response.rect,
corner_radius,
&self.style.shadows,
);
response
});
if let Some(icon) = self.style.cursor_icon
&& response.hovered()
{
ui.ctx().set_cursor_icon(icon);
}
response
}
}
impl_style_builders!(StyledLabel);