1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
use crate::{
    math::Vec2,
    ui::{ElementState, Layout, Ui, UiContent},
};

use std::borrow::Cow;

pub struct Label<'a> {
    position: Option<Vec2>,
    _multiline: Option<f32>,
    size: Option<Vec2>,
    label: Cow<'a, str>,
}

impl<'a> Label<'a> {
    pub fn new<S>(label: S) -> Label<'a>
    where
        S: Into<Cow<'a, str>>,
    {
        Label {
            position: None,
            _multiline: None,
            size: None,
            label: label.into(),
        }
    }

    pub fn multiline(self, line_height: f32) -> Self {
        Label {
            _multiline: Some(line_height),
            ..self
        }
    }

    pub fn position<P: Into<Option<Vec2>>>(self, position: P) -> Self {
        let position = position.into();

        Label { position, ..self }
    }

    pub fn size(self, size: Vec2) -> Self {
        Label {
            size: Some(size),
            ..self
        }
    }

    pub fn ui(self, ui: &mut Ui) {
        let context = ui.get_active_window_context();

        let size = self.size.unwrap_or_else(|| {
            context.window.painter.content_with_margins_size(
                &context.style.label_style,
                &UiContent::Label(self.label.clone()),
            )
        });

        let pos = context
            .window
            .cursor
            .fit(size, self.position.map_or(Layout::Vertical, Layout::Free));

        context.window.painter.draw_element_content(
            &context.style.label_style,
            pos,
            size,
            &UiContent::Label(self.label),
            ElementState {
                focused: context.focused,
                hovered: false,
                clicked: false,
                selected: false,
            },
        );
    }
}

impl Ui {
    pub fn label<P: Into<Option<Vec2>>>(&mut self, position: P, label: &str) {
        Label::new(label).position(position).ui(self)
    }

    pub fn calc_size(&mut self, label: &str) -> Vec2 {
        let context = self.get_active_window_context();

        context
            .window
            .painter
            .content_with_margins_size(&context.style.label_style, &UiContent::Label(label.into()))
    }
}