kas_widgets/adapt/with_label.rs
1// Licensed under the Apache License, Version 2.0 (the "License");
2// you may not use this file except in compliance with the License.
3// You may obtain a copy of the License in the LICENSE-APACHE file or at:
4// https://www.apache.org/licenses/LICENSE-2.0
5
6//! Wrapper adding a label
7
8use crate::AccessLabel;
9use kas::{layout, prelude::*};
10
11impl_scope! {
12 /// A wrapper widget with a label
13 ///
14 /// The label supports access keys, which activate `self.inner` on
15 /// usage.
16 ///
17 /// Mouse/touch input on the label sends events to the inner widget.
18 #[autoimpl(Deref, DerefMut using self.inner)]
19 #[derive(Clone, Default)]
20 #[widget {
21 Data = W::Data;
22 layout = list! 'row (self.dir, [self.inner, non_navigable!(self.label)]);
23 }]
24 pub struct WithLabel<W: Widget, D: Directional = Direction> {
25 core: widget_core!(),
26 dir: D,
27 #[widget]
28 inner: W,
29 #[widget(&())]
30 label: AccessLabel,
31 }
32
33 impl Self {
34 /// Construct a wrapper around `inner` placing a `label` in the given `direction`
35 pub fn new<T: Into<AccessString>>(inner: W, label: T) -> Self where D: Default {
36 Self::new_dir(inner, D::default(), label)
37 }
38 }
39 impl<W: Widget> WithLabel<W, kas::dir::Left> {
40 /// Construct from `inner` widget and `label`
41 pub fn left<T: Into<AccessString>>(inner: W, label: T) -> Self {
42 Self::new(inner, label)
43 }
44 }
45 impl<W: Widget> WithLabel<W, kas::dir::Right> {
46 /// Construct from `inner` widget and `label`
47 pub fn right<T: Into<AccessString>>(inner: W, label: T) -> Self {
48 Self::new(inner, label)
49 }
50 }
51
52 impl Self {
53 /// Construct a wrapper around `inner` placing a `label` in the given `direction`
54 #[inline]
55 pub fn new_dir<T: Into<AccessString>>(inner: W, direction: D, label: T) -> Self {
56 WithLabel {
57 core: Default::default(),
58 dir: direction,
59 inner,
60 label: AccessLabel::new(label.into()),
61 }
62 }
63
64 /// Get the direction
65 #[inline]
66 pub fn direction(&self) -> Direction {
67 self.dir.as_direction()
68 }
69
70 /// Take inner
71 #[inline]
72 pub fn take_inner(self) -> W {
73 self.inner
74 }
75
76 /// Access layout storage
77 ///
78 /// The number of columns/rows is fixed at two: the `inner` widget, and
79 /// the `label` (in this order, regardless of direction).
80 #[inline]
81 pub fn layout_storage(&mut self) -> &mut impl layout::RowStorage {
82 &mut self.core.row
83 }
84
85 /// Get whether line-wrapping is enabled
86 #[inline]
87 pub fn wrap(&self) -> bool {
88 self.label.wrap()
89 }
90
91 /// Enable/disable line wrapping
92 ///
93 /// By default this is enabled.
94 #[inline]
95 pub fn set_wrap(&mut self, wrap: bool) {
96 self.label.set_wrap(wrap);
97 }
98
99 /// Enable/disable line wrapping (inline)
100 #[inline]
101 pub fn with_wrap(mut self, wrap: bool) -> Self {
102 self.label.set_wrap(wrap);
103 self
104 }
105
106 /// Set text
107 ///
108 /// Note: this must not be called before fonts have been initialised
109 /// (usually done by the theme when the main loop starts).
110 pub fn set_text<T: Into<AccessString>>(&mut self, text: T) -> Action {
111 self.label.set_text(text.into())
112 }
113 }
114
115 impl Layout for Self {
116 fn find_id(&mut self, coord: Coord) -> Option<Id> {
117 self.rect().contains(coord).then(|| self.inner.id())
118 }
119 }
120}