use super::*; #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum HorizontalAlignment { Left, Center, Right, } pub struct LabelText { pub font: Font, pub text: String, } pub struct Label { text: LabelText, alignment: HorizontalAlignment, scale: f32, color: Color, left: f32, right: f32, baseline: f32, center_y: bool, dirty: bool, layout: Option, bounds: Rect, offset: Vec2, } impl Label { pub fn new( text: LabelText, alignment: HorizontalAlignment, scale: f32, color: Color, left: f32, right: f32, baseline: f32, center_y: bool, ) -> Self { Self { text, alignment, scale, color, left, right, baseline, center_y, dirty: true, layout: None, bounds: Rect::from_xy_size(Vec2::ZERO, Vec2::ZERO), offset: Vec2::ZERO, } } } impl Widget for Label { fn draw(&mut self, ctx: &DrawContext) { if self.dirty { let layout = TextLayout::new(&self.text.font, &self.text.text); let bounds = Rect::from(layout.get_bounds()).scale(self.scale); self.bounds = bounds; let xoff = match self.alignment { HorizontalAlignment::Left => self.left - bounds.bl.x, HorizontalAlignment::Right => self.right - bounds.tr.x, HorizontalAlignment::Center => { let available = self.right - self.left; let halfway = available / 2.0 + self.left; let width = bounds.tr.x - bounds.bl.x; let left = halfway - width / 2.0; left - bounds.bl.x } }; let yoff = if self.center_y { (bounds.bl.y - bounds.tr.y) / 2.0 - bounds.bl.y } else { 0.0 }; self.offset = Vec2::new(xoff, yoff + self.baseline); self.dirty = false; self.layout = Some(layout); } if let Some(layout) = self.layout.as_ref() { ctx.draw_text_layout(layout, self.offset, self.scale, self.color); } } }