canary-rs/crates/sao-ui-rs/src/widgets/text.rs

92 lines
2.3 KiB
Rust
Raw Normal View History

2022-07-21 21:19:57 +00:00
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<TextLayout>,
2022-07-21 21:19:57 +00:00
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,
2022-07-21 21:19:57 +00:00
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);
2022-07-21 21:19:57 +00:00
}
if let Some(layout) = self.layout.as_ref() {
ctx.draw_text_layout(layout, self.offset, self.scale, self.color);
}
2022-07-21 21:19:57 +00:00
}
}