lingxia_platform/
banner_background.rs1use crate::traits::app_runtime::DesktopBannerBackground;
2
3impl DesktopBannerBackground {
4 pub fn parse(value: &str) -> Result<Self, String> {
5 let value = value.trim();
6 if value.is_empty() || value.eq_ignore_ascii_case("system") {
7 return Ok(Self::System);
8 }
9 if value.eq_ignore_ascii_case("light") {
10 return Ok(Self::Light);
11 }
12 if value.eq_ignore_ascii_case("dark") {
13 return Ok(Self::Dark);
14 }
15 parse_css_color(value)
16 .map(|(r, g, b, a)| Self::Color { r, g, b, a })
17 .ok_or_else(|| {
18 "banner background must be system, light, dark, or #RGB/#RRGGBB/#RRGGBBAA".into()
19 })
20 }
21
22 pub fn as_ffi(&self) -> String {
23 match self {
24 Self::System => String::new(),
25 Self::Light => "light".into(),
26 Self::Dark => "dark".into(),
27 Self::Color { r, g, b, a } if *a == 255 => format!("#{r:02x}{g:02x}{b:02x}"),
28 Self::Color { r, g, b, a } => format!("#{r:02x}{g:02x}{b:02x}{a:02x}"),
29 }
30 }
31
32 pub fn prefers_dark_content(&self) -> bool {
33 match self {
34 Self::Light => true,
35 Self::Dark | Self::System => false,
36 Self::Color { r, g, b, .. } => relative_luminance(*r, *g, *b) > 0.55,
37 }
38 }
39}
40
41fn parse_css_color(value: &str) -> Option<(u8, u8, u8, u8)> {
42 let hex = value.strip_prefix('#')?;
43 let digits = hex.as_bytes();
44 let nibble = |byte| match byte {
45 b'0'..=b'9' => Some(byte - b'0'),
46 b'a'..=b'f' => Some(byte - b'a' + 10),
47 b'A'..=b'F' => Some(byte - b'A' + 10),
48 _ => None,
49 };
50 let pair = |hi, lo| Some(nibble(hi)? * 16 + nibble(lo)?);
51 match digits {
52 [r, g, b] => Some((nibble(*r)? * 17, nibble(*g)? * 17, nibble(*b)? * 17, 255)),
53 [r1, r2, g1, g2, b1, b2] => Some((pair(*r1, *r2)?, pair(*g1, *g2)?, pair(*b1, *b2)?, 255)),
54 [r1, r2, g1, g2, b1, b2, a1, a2] => Some((
55 pair(*r1, *r2)?,
56 pair(*g1, *g2)?,
57 pair(*b1, *b2)?,
58 pair(*a1, *a2)?,
59 )),
60 _ => None,
61 }
62}
63
64fn relative_luminance(r: u8, g: u8, b: u8) -> f32 {
65 0.2126 * (r as f32 / 255.0) + 0.7152 * (g as f32 / 255.0) + 0.0722 * (b as f32 / 255.0)
66}