cosmic/
ext.rs

1// Copyright 2022 System76 <info@system76.com>
2// SPDX-License-Identifier: MPL-2.0
3
4use iced::Color;
5use iced_core::Widget;
6
7pub trait ElementExt {
8    #[must_use]
9    fn debug(self, debug: bool) -> Self;
10}
11
12impl<Message: 'static> ElementExt for crate::Element<'_, Message> {
13    fn debug(self, debug: bool) -> Self {
14        if debug {
15            self.explain(Color::WHITE)
16        } else {
17            self
18        }
19    }
20}
21
22/// Additional methods for the [`Column`] and [`Row`] widgets.
23pub trait CollectionWidget<'a, Message: 'a>:
24    Widget<Message, crate::Theme, crate::Renderer>
25where
26    Self: Sized,
27{
28    /// Moves all the elements of `other` into `self`, leaving `other` empty.
29    #[must_use]
30    fn append<E>(self, other: &mut Vec<E>) -> Self
31    where
32        E: Into<crate::Element<'a, Message>>;
33
34    /// Appends all elements in an iterator to the widget.
35    #[must_use]
36    fn extend<E>(mut self, iterator: impl Iterator<Item = E>) -> Self
37    where
38        E: Into<crate::Element<'a, Message>>,
39    {
40        for item in iterator {
41            self = self.push(item.into());
42        }
43
44        self
45    }
46
47    /// Pushes an element into the widget.
48    #[must_use]
49    fn push(self, element: impl Into<crate::Element<'a, Message>>) -> Self;
50
51    /// Conditionally pushes an element to the widget.
52    #[must_use]
53    fn push_maybe(self, element: Option<impl Into<crate::Element<'a, Message>>>) -> Self {
54        if let Some(element) = element {
55            self.push(element.into())
56        } else {
57            self
58        }
59    }
60}
61
62impl<'a, Message: 'a> CollectionWidget<'a, Message> for crate::widget::Column<'a, Message> {
63    fn append<E>(self, other: &mut Vec<E>) -> Self
64    where
65        E: Into<crate::Element<'a, Message>>,
66    {
67        self.extend(other.drain(..).map(Into::into))
68    }
69
70    fn push(self, element: impl Into<crate::Element<'a, Message>>) -> Self {
71        self.push(element)
72    }
73}
74
75impl<'a, Message: 'a> CollectionWidget<'a, Message> for crate::widget::Row<'a, Message> {
76    fn append<E>(self, other: &mut Vec<E>) -> Self
77    where
78        E: Into<crate::Element<'a, Message>>,
79    {
80        self.extend(other.drain(..).map(Into::into))
81    }
82
83    fn push(self, element: impl Into<crate::Element<'a, Message>>) -> Self {
84        self.push(element)
85    }
86}
87
88pub trait ColorExt {
89    /// Combines color with background to create appearance of transparency.
90    #[must_use]
91    fn blend_alpha(self, background: Self, alpha: f32) -> Self;
92}
93
94impl ColorExt for iced::Color {
95    fn blend_alpha(self, background: Self, alpha: f32) -> Self {
96        Self {
97            a: 1.0,
98            r: (self.r - background.r).mul_add(alpha, background.r),
99            g: (self.g - background.g).mul_add(alpha, background.g),
100            b: (self.b - background.b).mul_add(alpha, background.b),
101        }
102    }
103}