tui_realm_stdlib/components/
label.rs1use tuirealm::command::{Cmd, CmdResult};
2use tuirealm::component::Component;
3use tuirealm::props::{
4 AttrValue, Attribute, Color, HorizontalAlignment, Props, QueryResult, Style, TextModifiers,
5};
6use tuirealm::ratatui::Frame;
7use tuirealm::ratatui::layout::Rect;
8use tuirealm::ratatui::widgets::Paragraph;
9use tuirealm::state::State;
10
11use crate::prop_ext::CommonProps;
12
13#[derive(Default)]
18#[must_use]
19pub struct Label {
20 common: CommonProps,
21 props: Props,
22}
23
24impl Label {
25 pub fn foreground(mut self, fg: Color) -> Self {
27 self.attr(Attribute::Foreground, AttrValue::Color(fg));
28 self
29 }
30
31 pub fn background(mut self, bg: Color) -> Self {
33 self.attr(Attribute::Background, AttrValue::Color(bg));
34 self
35 }
36
37 pub fn modifiers(mut self, m: TextModifiers) -> Self {
39 self.attr(Attribute::TextProps, AttrValue::TextModifiers(m));
40 self
41 }
42
43 pub fn style(mut self, style: Style) -> Self {
47 self.attr(Attribute::Style, AttrValue::Style(style));
48 self
49 }
50
51 pub fn text<S: Into<String>>(mut self, t: S) -> Self {
53 self.attr(Attribute::Text, AttrValue::String(t.into()));
55 self
56 }
57
58 pub fn alignment_horizontal(mut self, alignment: HorizontalAlignment) -> Self {
60 self.attr(
61 Attribute::AlignmentHorizontal,
62 AttrValue::AlignmentHorizontal(alignment),
63 );
64 self
65 }
66}
67
68impl Component for Label {
69 fn view(&mut self, render: &mut Frame, area: Rect) {
70 if !self.common.display {
71 return;
72 }
73
74 let text = self
76 .props
77 .get(Attribute::Text)
78 .and_then(|v| v.as_string())
79 .map_or("", |v| v.as_str());
80 let alignment: HorizontalAlignment = self
81 .props
82 .get(Attribute::AlignmentHorizontal)
83 .and_then(AttrValue::as_alignment_horizontal)
84 .unwrap_or(HorizontalAlignment::Left);
85 render.render_widget(
86 Paragraph::new(text)
87 .style(self.common.style)
88 .alignment(alignment),
89 area,
90 );
91 }
92
93 fn query<'a>(&'a self, attr: Attribute) -> Option<QueryResult<'a>> {
94 if let Some(value) = self.common.get_for_query(attr) {
95 return Some(value);
96 }
97
98 self.props.get_for_query(attr)
99 }
100
101 fn attr(&mut self, attr: Attribute, value: AttrValue) {
102 if let Some(value) = self.common.set(attr, value) {
103 self.props.set(attr, value);
104 }
105 }
106
107 fn state(&self) -> State {
108 State::None
109 }
110
111 fn perform(&mut self, cmd: Cmd) -> CmdResult {
112 CmdResult::Invalid(cmd)
113 }
114}
115
116#[cfg(test)]
117mod tests {
118
119 use pretty_assertions::assert_eq;
120
121 use super::*;
122
123 #[test]
124 fn test_components_label() {
125 let component: Label = Label::default()
126 .alignment_horizontal(HorizontalAlignment::Center)
127 .background(Color::Red)
128 .foreground(Color::Yellow)
129 .modifiers(TextModifiers::BOLD)
130 .text("foobar");
131
132 assert_eq!(component.state(), State::None);
133 }
134
135 #[test]
136 fn test_various_text_inputs() {
137 let _ = Label::default().text("str");
138 let _ = Label::default().text(String::from("String"));
139 #[allow(clippy::needless_borrows_for_generic_args)]
141 let _ = Label::default().text(&String::from("&String"));
142 }
143}