veloren_voxygen/ui/widgets/
outlined_text.rs

1use conrod_core::{
2    Color, FontSize, Positionable, Sizeable, Widget, WidgetCommon, builder_methods, text,
3    widget::{self, Text},
4    widget_ids,
5};
6
7#[derive(Clone, WidgetCommon)]
8pub struct OutlinedText<'a> {
9    #[conrod(common_builder)]
10    common: widget::CommonBuilder,
11
12    text: &'a str,
13    text_style: widget::text::Style,
14    outline_color: Option<Color>,
15    outline_width: f64,
16}
17
18widget_ids! {
19    struct Ids{
20        base,
21        outline1,
22        outline2,
23        outline3,
24        outline4,
25    }
26}
27
28pub struct State {
29    ids: Ids,
30}
31
32impl<'a> OutlinedText<'a> {
33    builder_methods! {
34        pub color {text_style.color = Some(Color)}
35        pub outline_color {outline_color = Some(Color)}
36
37        pub font_size {text_style.font_size = Some(FontSize)}
38        pub outline_width {outline_width = f64}
39    }
40
41    pub fn new(text: &'a str) -> Self {
42        Self {
43            common: widget::CommonBuilder::default(),
44            text,
45
46            text_style: widget::text::Style::default(),
47            outline_color: None,
48            outline_width: 0.0,
49        }
50    }
51
52    #[must_use]
53    pub fn font_id(mut self, font_id: text::font::Id) -> Self {
54        self.text_style.font_id = Some(Some(font_id));
55        self
56    }
57}
58
59impl Widget for OutlinedText<'_> {
60    type Event = ();
61    type State = State;
62    type Style = ();
63
64    fn init_state(&self, id_gen: widget::id::Generator) -> Self::State {
65        State {
66            ids: Ids::new(id_gen),
67        }
68    }
69
70    fn style(&self) -> Self::Style {}
71
72    fn update(self, args: widget::UpdateArgs<Self>) -> Self::Event {
73        let widget::UpdateArgs {
74            id,
75            state,
76            ui,
77            rect,
78            ..
79        } = args;
80
81        let mut outline_style = self.text_style;
82        outline_style.color = self.outline_color;
83
84        let shift = self.outline_width;
85        Text::new(self.text)
86            .with_style(self.text_style)
87            .xy(rect.xy())
88            .wh(rect.dim())
89            .parent(id)
90            .depth(-1.0)
91            .set(state.ids.base, ui);
92
93        Text::new(self.text)
94            .with_style(outline_style)
95            .x_y_relative_to(state.ids.base, shift, shift)
96            .wh_of(state.ids.base)
97            .set(state.ids.outline1, ui);
98
99        Text::new(self.text)
100            .with_style(outline_style)
101            .x_y_relative_to(state.ids.base, -shift, shift)
102            .wh_of(state.ids.base)
103            .set(state.ids.outline2, ui);
104
105        Text::new(self.text)
106            .with_style(outline_style)
107            .x_y_relative_to(state.ids.base, shift, -shift)
108            .wh_of(state.ids.base)
109            .set(state.ids.outline3, ui);
110
111        Text::new(self.text)
112            .with_style(outline_style)
113            .x_y_relative_to(state.ids.base, -shift, -shift)
114            .wh_of(state.ids.base)
115            .set(state.ids.outline4, ui);
116    }
117}