pushrod_widgets/system_widgets/
text_widget.rs

1// Pushrod Widgets
2// Text Widget
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16use sdl2::render::{Canvas, Texture};
17use sdl2::video::Window;
18
19use crate::caches::TextureCache;
20use crate::primitives::draw_base;
21use crate::properties::{
22    WidgetProperties, PROPERTY_TEXT_JUSTIFICATION, TEXT_JUSTIFY_CENTER, TEXT_JUSTIFY_LEFT,
23    TEXT_JUSTIFY_RIGHT,
24};
25use crate::texture_store::TextureStore;
26use crate::widget::Widget;
27use sdl2::rect::Rect;
28
29/// Text Widget.
30#[derive(Default)]
31pub struct TextWidget {
32    texture_store: TextureStore,
33    properties: WidgetProperties,
34}
35
36/// Implementation for drawing a `TextWidget`, with the `Widget` trait objects applied.
37impl Widget for TextWidget {
38    widget_default_impl!("TextWidget");
39
40    /// This is the draw implementation of the `TextWidget`.  It uses the following properties:
41    ///
42    /// - PROPERTY_MAIN_COLOR: the `Color` of the body of the `Widget`
43    /// - PROPERTY_BORDER_WIDTH: the width of the border to draw
44    /// - PROPERTY_BORDER_COLOR: the `Color` of the border.
45    /// - PROPERTY_FONT_COLOR: the color of the font
46    /// - PROPERTY_FONT_NAME: full or relative path to the font file to use to render the text
47    /// - PROPERTY_FONT_SIZE: the size in points of the font
48    /// - PROPERTY_FONT_STYLE: the `FontStyle` to apply to the font
49    /// - PROPERTY_TEXT_JUSTIFICATION: The `TEXT_JUSTIFY_*` constant to use to position the text inside the `Widget`
50    /// - PROPERTY_TEXT: `String` containing the text to display
51    fn draw(&mut self, c: &mut Canvas<Window>, t: &mut TextureCache) -> Option<&Texture> {
52        // ONLY update the texture if the `BaseWidget` shows that it's been invalidated.
53        if self.invalidated() {
54            let bounds = self.properties.get_bounds();
55            let (font_texture, width, height) = t.render_text(c, &mut self.properties, None);
56            let text_justification = self.properties.get_value(PROPERTY_TEXT_JUSTIFICATION);
57            let texture_y = 0;
58            let widget_w = bounds.0;
59            let texture_x: i32 = match text_justification {
60                TEXT_JUSTIFY_LEFT => 0,
61                TEXT_JUSTIFY_CENTER => (widget_w - width) as i32 / 2,
62                TEXT_JUSTIFY_RIGHT => (widget_w - width) as i32,
63                _ => 0,
64            };
65
66            self.texture_store
67                .create_or_resize_texture(c, bounds.0, bounds.1);
68
69            let cloned_properties = self.properties.clone();
70
71            c.with_texture_canvas(self.texture_store.get_mut_ref(), |texture| {
72                draw_base(texture, &cloned_properties, None);
73
74                texture
75                    .copy(
76                        &font_texture,
77                        None,
78                        Rect::new(texture_x, texture_y, width, height),
79                    )
80                    .unwrap();
81            })
82            .unwrap();
83        }
84
85        self.texture_store.get_optional_ref()
86    }
87}