kas_core/
hidden.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//! Hidden extras
7//!
8//! It turns out that some widgets are needed in kas-core. This module is
9//! hidden by default and direct usage (outside of kas crates) is
10//! not supported (i.e. **changes are not considered breaking**).
11
12use crate::classes::HasStr;
13use crate::event::{ConfigCx, Event, EventCx, IsUsed};
14use crate::geom::{Coord, Offset, Rect};
15use crate::layout::{Align, AlignHints, AxisInfo, SizeRules};
16use crate::theme::{DrawCx, SizeCx, Text, TextClass};
17use crate::{Events, Id, Layout, NavAdvance, Node, Widget};
18use kas_macros::{autoimpl, impl_scope};
19
20impl_scope! {
21    /// A simple text label
22    ///
23    /// Vertical alignment defaults to centred, horizontal
24    /// alignment depends on the script direction if not specified.
25    /// Line-wrapping is enabled.
26    #[derive(Clone, Debug, Default)]
27    #[widget {
28        Data = ();
29    }]
30    pub struct StrLabel {
31        core: widget_core!(),
32        text: Text<&'static str>,
33    }
34
35    impl Self {
36        /// Construct from `text`
37        #[inline]
38        pub fn new(text: &'static str) -> Self {
39            StrLabel {
40                core: Default::default(),
41                text: Text::new(text, TextClass::Label(false)),
42            }
43        }
44    }
45
46    impl Layout for Self {
47        #[inline]
48        fn size_rules(&mut self, sizer: SizeCx, axis: AxisInfo) -> SizeRules {
49            sizer.text_rules(&mut self.text, axis)
50        }
51
52        fn set_rect(&mut self, cx: &mut ConfigCx, rect: Rect, hints: AlignHints) {
53            self.core.rect = rect;
54            let align = hints.complete(Align::Default, Align::Center);
55            cx.text_set_size(&mut self.text, rect.size, align);
56        }
57
58        fn draw(&mut self, mut draw: DrawCx) {
59            draw.text(self.rect(), &self.text);
60        }
61    }
62
63    impl Events for Self {
64        fn configure(&mut self, cx: &mut ConfigCx) {
65            cx.text_configure(&mut self.text);
66        }
67    }
68
69    impl HasStr for Self {
70        fn get_str(&self) -> &str {
71            self.text.as_str()
72        }
73    }
74}
75
76impl_scope! {
77    /// Map any input data to `()`
78    #[autoimpl(Deref, DerefMut using self.inner)]
79    #[autoimpl(class_traits using self.inner where W: trait)]
80    #[derive(Clone, Default)]
81    pub struct MapAny<A, W: Widget<Data = ()>> {
82        _a: std::marker::PhantomData<A>,
83        pub inner: W,
84    }
85
86    impl Self {
87        /// Construct
88        pub fn new(inner: W) -> Self {
89            MapAny {
90                _a: std::marker::PhantomData,
91                inner,
92            }
93        }
94    }
95
96    // We don't use #[widget] here. This is not supported outside of Kas!
97    impl Layout for Self {
98        #[inline]
99        fn as_layout(&self) -> &dyn Layout {
100            self
101        }
102
103        #[inline]
104        fn id_ref(&self) -> &Id {
105            self.inner.id_ref()
106        }
107
108        #[inline]
109        fn rect(&self) -> Rect {
110            self.inner.rect()
111        }
112
113        #[inline]
114        fn widget_name(&self) -> &'static str {
115            "MapAny"
116        }
117
118        #[inline]
119        fn num_children(&self) -> usize {
120            self.inner.num_children()
121        }
122        #[inline]
123        fn get_child(&self, index: usize) -> Option<&dyn Layout> {
124            self.inner.get_child(index)
125        }
126
127        #[inline]
128        fn find_child_index(&self, id: &Id) -> Option<usize> {
129            self.inner.find_child_index(id)
130        }
131
132        #[inline]
133        fn size_rules(&mut self, sizer: SizeCx, axis: AxisInfo) -> SizeRules {
134            self.inner.size_rules(sizer, axis)
135        }
136
137        #[inline]
138        fn set_rect(&mut self, cx: &mut ConfigCx, rect: Rect, hints: AlignHints) {
139            self.inner.set_rect(cx, rect, hints);
140        }
141
142        #[inline]
143        fn nav_next(&self, reverse: bool, from: Option<usize>) -> Option<usize> {
144            self.inner.nav_next(reverse, from)
145        }
146
147        #[inline]
148        fn translation(&self) -> Offset {
149            self.inner.translation()
150        }
151
152        #[inline]
153        fn find_id(&mut self, coord: Coord) -> Option<Id> {
154            self.inner.find_id(coord)
155        }
156
157        #[inline]
158        fn draw(&mut self, draw: DrawCx) {
159            self.inner.draw(draw);
160        }
161    }
162
163    impl Widget for Self {
164        type Data = A;
165
166        fn as_node<'a>(&'a mut self, _: &'a A) -> Node<'a> {
167            self.inner.as_node(&())
168        }
169
170        #[inline]
171        fn for_child_node(
172            &mut self,
173            _: &A,
174            index: usize,
175            closure: Box<dyn FnOnce(Node<'_>) + '_>,
176        ) {
177            self.inner.for_child_node(&(), index, closure)
178        }
179
180        fn _configure(&mut self, cx: &mut ConfigCx, _: &A, id: Id) {
181            self.inner._configure(cx, &(), id);
182        }
183
184        fn _update(&mut self, cx: &mut ConfigCx, _: &A) {
185            self.inner._update(cx, &());
186        }
187
188        fn _send(&mut self, cx: &mut EventCx, _: &A, id: Id, event: Event) -> IsUsed {
189            self.inner._send(cx, &(), id, event)
190        }
191
192        fn _replay(&mut self, cx: &mut EventCx, _: &A, id: Id) {
193            self.inner._replay(cx, &(), id);
194        }
195
196        fn _nav_next(
197            &mut self,
198            cx: &mut ConfigCx,
199            _: &A,
200            focus: Option<&Id>,
201            advance: NavAdvance,
202        ) -> Option<Id> {
203            self.inner._nav_next(cx, &(), focus, advance)
204        }
205    }
206}