xilem/view/
label.rs

1// Copyright 2024 the Xilem Authors
2// SPDX-License-Identifier: Apache-2.0
3
4use masonry::{widget::WidgetMut, ArcStr, WidgetPod};
5
6use crate::{Color, MasonryView, MessageResult, TextAlignment, ViewCx, ViewId};
7
8pub fn label(label: impl Into<ArcStr>) -> Label {
9    Label {
10        label: label.into(),
11        text_color: Color::WHITE,
12        alignment: TextAlignment::default(),
13        disabled: false,
14    }
15}
16
17pub struct Label {
18    label: ArcStr,
19    text_color: Color,
20    alignment: TextAlignment,
21    disabled: bool,
22    // TODO: add more attributes of `masonry::widget::Label`
23}
24
25impl Label {
26    pub fn color(mut self, color: Color) -> Self {
27        self.text_color = color;
28        self
29    }
30
31    pub fn alignment(mut self, alignment: TextAlignment) -> Self {
32        self.alignment = alignment;
33        self
34    }
35
36    pub fn disabled(mut self) -> Self {
37        self.disabled = true;
38        self
39    }
40}
41
42impl<State, Action> MasonryView<State, Action> for Label {
43    type Element = masonry::widget::Label;
44    type ViewState = ();
45
46    fn build(&self, _cx: &mut ViewCx) -> (WidgetPod<Self::Element>, Self::ViewState) {
47        let widget_pod = WidgetPod::new(
48            masonry::widget::Label::new(self.label.clone())
49                .with_text_brush(self.text_color)
50                .with_text_alignment(self.alignment),
51        );
52        (widget_pod, ())
53    }
54
55    fn rebuild(
56        &self,
57        _view_state: &mut Self::ViewState,
58        cx: &mut ViewCx,
59        prev: &Self,
60        mut element: WidgetMut<Self::Element>,
61    ) {
62        if prev.label != self.label {
63            element.set_text(self.label.clone());
64            cx.mark_changed();
65        }
66        // if prev.disabled != self.disabled {
67        //     element.set_disabled(self.disabled);
68        //     cx.mark_changed();
69        // }
70        if prev.text_color != self.text_color {
71            element.set_text_brush(self.text_color);
72            cx.mark_changed();
73        }
74        if prev.alignment != self.alignment {
75            element.set_alignment(self.alignment);
76            cx.mark_changed();
77        }
78    }
79
80    fn message(
81        &self,
82        _view_state: &mut Self::ViewState,
83        _id_path: &[ViewId],
84        message: Box<dyn std::any::Any>,
85        _app_state: &mut State,
86    ) -> crate::MessageResult<Action> {
87        tracing::error!("Message arrived in Label::message, but Label doesn't consume any messages, this is a bug");
88        MessageResult::Stale(message)
89    }
90}