1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License in the LICENSE-APACHE file or at:
//     https://www.apache.org/licenses/LICENSE-2.0

//! Wrapper adding a label

use crate::AccelLabel;
use kas::{event, layout, prelude::*};

impl_scope! {
    /// A wrapper widget with a label
    ///
    /// The label supports accelerator keys, which activate `self.inner` on
    /// usage.
    ///
    /// Mouse/touch input on the label sends events to the inner widget.
    #[autoimpl(Deref, DerefMut using self.inner)]
    #[derive(Clone, Default, Debug)]
    #[widget {
        layout = list(self.dir) 'row: [self.inner, non_navigable: self.label];
    }]
    pub struct WithLabel<W: Widget, D: Directional> {
        core: widget_core!(),
        dir: D,
        #[widget]
        inner: W,
        #[widget]
        label: AccelLabel,
    }

    impl Self
    where
        D: Default,
    {
        /// Construct from `inner` widget and `label`
        #[inline]
        pub fn new<T: Into<AccelString>>(inner: W, label: T) -> Self {
            Self::new_with_direction(D::default(), inner, label)
        }
    }

    impl Self {
        /// Construct from `direction`, `inner` widget and `label`
        #[inline]
        pub fn new_with_direction<T: Into<AccelString>>(direction: D, inner: W, label: T) -> Self {
            WithLabel {
                core: Default::default(),
                dir: direction,
                inner,
                label: AccelLabel::new(label.into()),
            }
        }

        /// Get the direction
        #[inline]
        pub fn direction(&self) -> Direction {
            self.dir.as_direction()
        }

        /// Take inner
        #[inline]
        pub fn take_inner(self) -> W {
            self.inner
        }

        /// Access layout storage
        ///
        /// The number of columns/rows is fixed at two: the `inner` widget, and
        /// the `label` (in this order, regardless of direction).
        #[inline]
        pub fn layout_storage(&mut self) -> &mut impl layout::RowStorage {
            &mut self.core.row
        }

        /// Get whether line-wrapping is enabled
        #[inline]
        pub fn wrap(&self) -> bool {
            self.label.wrap()
        }

        /// Enable/disable line wrapping
        ///
        /// By default this is enabled.
        #[inline]
        pub fn set_wrap(&mut self, wrap: bool) {
            self.label.set_wrap(wrap);
        }

        /// Enable/disable line wrapping (inline)
        #[inline]
        pub fn with_wrap(mut self, wrap: bool) -> Self {
            self.label.set_wrap(wrap);
            self
        }

        /// Set text
        ///
        /// Note: this must not be called before fonts have been initialised
        /// (usually done by the theme when the main loop starts).
        pub fn set_text<T: Into<AccelString>>(&mut self, text: T) -> TkAction {
            self.label.set_text(text.into())
        }

        /// Get the accelerator keys
        pub fn keys(&self) -> &[event::VirtualKeyCode] {
            self.label.keys()
        }
    }

    impl Layout for Self {
        fn find_id(&mut self, coord: Coord) -> Option<WidgetId> {
            self.rect().contains(coord).then(|| self.inner.id())
        }
    }

    impl Widget for Self {
        fn configure(&mut self, mgr: &mut ConfigMgr) {
            mgr.add_accel_keys(self.inner.id_ref(), self.keys());
        }
    }

    impl SetAccel for Self {
        #[inline]
        fn set_accel_string(&mut self, string: AccelString) -> TkAction {
            self.label.set_accel_string(string)
        }
    }
}