Skip to main content

ferroui_controls/
window_transparency_level.rs

1use std::fmt;
2use std::ops::Deref;
3
4/// A transparency level a window can be asked to render with.
5///
6/// The set of levels is closed: values are obtained from the associated
7/// functions ([`none`](Self::none), [`transparent`](Self::transparent), ...).
8#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
9pub struct WindowTransparencyLevel {
10    value: &'static str,
11}
12
13impl WindowTransparencyLevel {
14    const fn new(value: &'static str) -> Self {
15        Self { value }
16    }
17
18    /// The window background is black where the client area is transparent.
19    pub const fn none() -> Self {
20        Self::new("None")
21    }
22
23    /// The window background is transparent.
24    pub const fn transparent() -> Self {
25        Self::new("Transparent")
26    }
27
28    /// The window background is a blur-behind where the client area is
29    /// transparent.
30    pub const fn blur() -> Self {
31        Self::new("Blur")
32    }
33
34    /// The window background is a blur-behind with a high blur radius. This
35    /// level may fall back to blur, if the platform doesn't support acrylic.
36    pub const fn acrylic_blur() -> Self {
37        Self::new("AcrylicBlur")
38    }
39
40    /// The window background is based on desktop wallpaper tint with a blur.
41    /// This will only work on Windows 11.
42    pub const fn mica() -> Self {
43        Self::new("Mica")
44    }
45}
46
47impl fmt::Display for WindowTransparencyLevel {
48    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49        f.write_str(self.value)
50    }
51}
52
53/// A read-only list of transparency levels, in order of preference.
54#[derive(Clone, Debug, Default, PartialEq, Eq)]
55pub struct WindowTransparencyLevelCollection {
56    list: Vec<WindowTransparencyLevel>,
57}
58
59impl WindowTransparencyLevelCollection {
60    /// Creates a collection from a list of levels.
61    pub fn new(list: impl Into<Vec<WindowTransparencyLevel>>) -> Self {
62        Self { list: list.into() }
63    }
64}
65
66impl Deref for WindowTransparencyLevelCollection {
67    type Target = [WindowTransparencyLevel];
68
69    fn deref(&self) -> &[WindowTransparencyLevel] {
70        &self.list
71    }
72}
73
74impl<'a> IntoIterator for &'a WindowTransparencyLevelCollection {
75    type Item = &'a WindowTransparencyLevel;
76    type IntoIter = std::slice::Iter<'a, WindowTransparencyLevel>;
77
78    fn into_iter(self) -> Self::IntoIter {
79        self.list.iter()
80    }
81}
82
83#[cfg(test)]
84mod tests {
85    use super::*;
86
87    #[test]
88    fn display_writes_the_level_name() {
89        assert_eq!(WindowTransparencyLevel::none().to_string(), "None");
90        assert_eq!(WindowTransparencyLevel::transparent().to_string(), "Transparent");
91        assert_eq!(WindowTransparencyLevel::blur().to_string(), "Blur");
92        assert_eq!(WindowTransparencyLevel::acrylic_blur().to_string(), "AcrylicBlur");
93        assert_eq!(WindowTransparencyLevel::mica().to_string(), "Mica");
94    }
95
96    #[test]
97    fn levels_compare_by_value() {
98        assert_eq!(WindowTransparencyLevel::blur(), WindowTransparencyLevel::blur());
99        assert_ne!(WindowTransparencyLevel::blur(), WindowTransparencyLevel::acrylic_blur());
100    }
101
102    #[test]
103    fn collection_exposes_its_items_in_order() {
104        let collection = WindowTransparencyLevelCollection::new([
105            WindowTransparencyLevel::mica(),
106            WindowTransparencyLevel::acrylic_blur(),
107        ]);
108        assert_eq!(collection.len(), 2);
109        assert_eq!(collection[0], WindowTransparencyLevel::mica());
110        assert_eq!(
111            collection.iter().map(ToString::to_string).collect::<Vec<_>>(),
112            ["Mica", "AcrylicBlur"]
113        );
114        assert!(WindowTransparencyLevelCollection::default().is_empty());
115    }
116}