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}