makepad_widgets/
label.rs

1use {
2    crate::{
3        makepad_derive_widget::*,
4        makepad_draw::*,
5        widget::*
6    }
7};
8
9live_design!{
10    link widgets;
11    use link::theme::*;
12    
13    pub LabelBase = {{Label}} {}
14    pub Label = <LabelBase> {
15        width: Fit, height: Fit,
16        padding: <THEME_MSPACE_1> {}
17        draw_text: {
18            color: (THEME_COLOR_LABEL_OUTER),
19            text_style: <THEME_FONT_REGULAR> {
20                line_spacing: (THEME_FONT_WDGT_LINE_SPACING),
21            },
22            wrap: Word
23        }
24    }
25
26    pub Labelbold = <Label> {
27        draw_text: {
28            text_style: <THEME_FONT_BOLD> {
29                font_size: (THEME_FONT_SIZE_P)
30            }
31        }
32    }
33
34    pub LabelGradientX = <Label> {
35        width: Fit, height: Fit,
36        draw_text: {
37            uniform color_1: #f00,
38            uniform color_2: #ff0
39
40            fn get_color(self) ->vec4{
41                return mix(self.color_1, self.color_2, self.pos.y)
42            }
43        }
44    }
45    
46    pub LabelGradientY = <LabelGradientX> {
47        draw_text: {
48            fn get_color(self) ->vec4{
49                return mix(self.color_1, self.color_2, self.pos.x)
50            }
51        }
52    }
53    
54    pub TextBox = <Label> {
55        width: Fill, height: Fit,
56        padding: { left: 0., right: 0., top: (THEME_SPACE_1), bottom: 0. }
57        draw_text: {
58            text_style: <THEME_FONT_REGULAR> {
59                line_spacing: (THEME_FONT_LONGFORM_LINE_SPACING),
60                font_size: (THEME_FONT_SIZE_P)
61            }
62            color: (THEME_COLOR_TEXT)
63        }
64        text: "TextBox"
65    }
66
67    pub H1 = <Label> {
68        width: Fill,
69        padding: 0.
70        draw_text: {
71            wrap: Word
72            text_style: <THEME_FONT_BOLD> {
73                line_spacing: (THEME_FONT_HL_LINE_SPACING),
74                font_size: (THEME_FONT_SIZE_1)
75            }
76            color: (THEME_COLOR_TEXT_HL)
77        }
78        text: "H1"
79    }
80    
81    pub H1italic = <H1> {
82        draw_text: {
83            text_style: <THEME_FONT_BOLD_ITALIC> {
84                line_spacing: (THEME_FONT_HL_LINE_SPACING),
85                font_size: (THEME_FONT_SIZE_1)
86            }
87        }
88        text: "H1 italic"
89    }
90    
91    pub H2 = <H1> {
92        draw_text: {
93            text_style: <THEME_FONT_BOLD> {
94                line_spacing: (THEME_FONT_HL_LINE_SPACING),
95                font_size: (THEME_FONT_SIZE_2)
96            }
97        }
98        text: "H2"
99    }
100    
101    pub H2italic = <H1> {
102        draw_text: {
103            text_style: <THEME_FONT_BOLD_ITALIC> {
104                line_spacing: (THEME_FONT_HL_LINE_SPACING),
105                font_size: (THEME_FONT_SIZE_2)
106            }
107        }
108        text: "H2 italic"
109    }
110    
111    pub H3 = <H1> {
112        draw_text: {
113            text_style: <THEME_FONT_BOLD> {
114                line_spacing: (THEME_FONT_HL_LINE_SPACING),
115                font_size: (THEME_FONT_SIZE_3)
116            }
117        }
118        text: "H3"
119    }
120    
121    pub H3italic = <H1> {
122        draw_text: {
123            text_style: <THEME_FONT_BOLD_ITALIC> {
124                line_spacing: (THEME_FONT_HL_LINE_SPACING),
125                font_size: (THEME_FONT_SIZE_3)
126            }
127        }
128        text: "H3 italic"
129    }
130    
131    pub H4 = <H1> {
132        draw_text: {
133            text_style: <THEME_FONT_BOLD> {
134                line_spacing: (THEME_FONT_HL_LINE_SPACING),
135                font_size: (THEME_FONT_SIZE_4)
136            }
137        }
138        text: "H4"
139    }
140    
141    pub H4italic = <H1> {
142        draw_text: {
143            text_style: <THEME_FONT_BOLD_ITALIC> {
144                line_spacing: (THEME_FONT_HL_LINE_SPACING),
145                font_size: (THEME_FONT_SIZE_4)
146            }
147        }
148        text: "H4 italic"
149    }
150 
151    pub P = <TextBox> {
152        text: "Paragraph"
153    }
154    
155    pub Pbold = <TextBox> {
156        draw_text: {
157            text_style: <THEME_FONT_BOLD> {
158                font_size: (THEME_FONT_SIZE_P)
159            }
160        }
161        text: "Paragraph"
162    }
163    
164    pub Pitalic = <TextBox> {
165        draw_text: {
166            text_style: <THEME_FONT_ITALIC> {
167                font_size: (THEME_FONT_SIZE_P)
168            }
169        }
170        text: "Paragraph"
171    }
172    
173    pub Pbolditalic = <TextBox> {
174        draw_text: {
175            text_style: <THEME_FONT_BOLD_ITALIC> {
176                font_size: (THEME_FONT_SIZE_P)
177            }
178        }
179        text: "Paragraph"
180    }
181
182    pub IconSet = <Label> {
183        width: Fit,
184        draw_text: {
185            text_style: <THEME_FONT_ICONS> {
186                line_spacing: (THEME_FONT_WDGT_LINE_SPACING),
187                font_size: 100.
188            }
189            color: (THEME_COLOR_TEXT)
190        }
191        text: "Car"
192    }
193
194    
195}
196
197#[derive(Clone, Debug, DefaultNone)]
198pub enum LabelAction {
199    HoverIn(Rect),
200    HoverOut,
201    None
202}
203
204
205#[derive(Live, LiveHook, Widget)]
206pub struct Label {
207    #[redraw] #[live] draw_text: DrawText,
208    
209    #[walk] walk: Walk,
210    #[live] align: Align,
211    #[live(Flow::RightWrap)] flow: Flow,
212    #[live] padding: Padding,
213    
214    #[rust] area: Area,
215    //margin: Margin,
216    #[live] text: ArcStringMut,
217
218    // Indicates if this label responds to hover events
219    // It is not turned on by default because it will consume finger events
220    // and prevent other widgets from receiving them, if it is not considered with care
221    // The primary use case for this kind of emitted actions is for tooltips displaying
222    #[live(false)] hover_actions_enabled: bool
223} 
224
225impl Widget for Label {
226
227    fn draw_walk(&mut self, cx: &mut Cx2d, _scope: &mut Scope, walk:Walk)->DrawStep{
228        let walk = walk.with_add_padding(self.padding);
229        cx.begin_turtle(walk, Layout{
230            flow: self.flow,
231            ..Default::default()
232        });
233        // here we need to check if the text is empty, if so we need to set it to a space
234        // or the text draw will not work(seems like lazy drawtext bug)
235        let _ = self.text.as_ref().is_empty().then(|| {
236            let _ = self.set_text(cx, " ");
237        });
238        self.draw_text.draw_walk(cx, walk, self.align, self.text.as_ref());
239        cx.end_turtle_with_area(&mut self.area);
240        DrawStep::done()
241    }
242    
243    fn text(&self)->String{
244        self.text.as_ref().to_string()
245    }
246    
247    fn set_text(&mut self, cx:&mut Cx, v:&str){
248        self.text.as_mut_empty().push_str(v);
249        self.redraw(cx);
250    }
251
252    fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) {
253        let uid = self.widget_uid();
254                
255        match event.hit_designer(cx, self.area){
256            HitDesigner::DesignerPick(_e)=>{
257                cx.widget_action(uid, &scope.path, WidgetDesignAction::PickedBody)
258            }
259            _=>()
260        }
261        
262        if self.hover_actions_enabled {
263            
264            match event.hits_with_capture_overload(cx, self.area, true) {
265                Hit::FingerHoverIn(fh) => {
266                    cx.widget_action(uid, &scope.path, LabelAction::HoverIn(fh.rect));
267                }
268                Hit::FingerHoverOut(_) => {
269                    cx.widget_action(uid, &scope.path, LabelAction::HoverOut);
270                },
271                _ => ()
272            }
273        }
274    }
275}
276
277impl LabelRef {
278    pub fn hover_in(&self, actions:&Actions)->Option<Rect>{
279        if let Some(item) = actions.find_widget_action(self.widget_uid()) {
280            match item.cast(){
281                LabelAction::HoverIn(rect) => Some(rect),
282                _=> None
283            }
284        } else {
285            None
286        }
287    }
288
289    pub fn hover_out(&self, actions:&Actions)->bool{
290        if let Some(item) = actions.find_widget_action(self.widget_uid()) {
291            match item.cast(){
292                LabelAction::HoverOut => true,
293                _=> false
294            }
295        } else {
296            false
297        }
298    }
299    
300    pub fn set_text_with<F:FnOnce(&mut String)>(&self, f:F) {
301        if let Some(mut inner) = self.borrow_mut(){
302            f(inner.text.as_mut())
303        }
304    }
305}