iced_optional_element_shim/lib.rs
1use iced::{advanced::{layout, mouse, renderer, widget::Tree, Layout, Widget}, Element, Length, Rectangle, Renderer, Size, Theme};
2
3/// Works to convert `Option<T>` to `Element<'a, Message, Theme, Renderer>`
4///
5/// iced versions after 0.13.1 have a `From` impl so they don't need this.
6///
7/// Usage:
8///
9/// use iced_optional_element_shim::to_elem;
10///
11/// fn view(&self) -> Element<'a, Message> {
12/// column!(
13/// text("Example header"),
14///
15/// if true {
16/// to_elem(Some(text("this element will display")))
17/// } else {
18/// to_elem::<Message, iced::widget::Text>(None)
19/// },
20///
21/// if false {
22/// to_elem(Some(text("this element will not display")))
23/// } else {
24/// to_elem::<Message, iced::widget::Text>(None)
25/// },
26///
27/// text("footer"),
28/// )
29/// }
30///
31pub fn to_elem<'a, Message, T: Into<Element<'a, Message, Theme, Renderer>>>(element: Option<T>) -> Element<'a, Message, Theme, Renderer> {
32 struct Void;
33
34 impl<Message, Theme, Renderer> Widget<Message, Theme, Renderer> for Void
35 where Renderer: iced::advanced::Renderer
36 {
37 fn size(&self) -> Size<Length> {
38 Size {
39 width: Length::Fixed(0.0),
40 height: Length::Fixed(0.0),
41 }
42 }
43
44 fn layout(
45 &self,
46 _tree: &mut Tree,
47 _renderer: &Renderer,
48 _limits: &layout::Limits,
49 ) -> layout::Node {
50 layout::Node::new(Size::ZERO)
51 }
52
53 fn draw(
54 &self,
55 _tree: &Tree,
56 _renderer: &mut Renderer,
57 _theme: &Theme,
58 _style: &renderer::Style,
59 _layout: Layout<'_>,
60 _cursor: mouse::Cursor,
61 _viewport: &Rectangle,
62 ) {
63 }
64 }
65
66 element.map(T::into).unwrap_or_else(|| Element::new(Void))
67}
68
69// #[cfg(test)]
70// mod tests {
71// use super::*;
72
73// #[test]
74// fn it_works() {
75// let result = add(2, 2);
76// assert_eq!(result, 4);
77// }
78// }