feat(theme): themes as files (theme crate: toml subset + ints, contrast check, wire); whimsy dark + light; display reads themes/, serves THEME/THEME_NAME, init SET_THEME -> THEME_CHANGED to all windows, bar themed; k-ui follows; settings appearance; init keeps choice in sealed users/<id>/settings/, reapplies at sign-in + display restart
This commit is contained in:
73
crates/theme/src/wire.rs
Normal file
73
crates/theme/src/wire.rs
Normal file
@@ -0,0 +1,73 @@
|
||||
//! A theme in message words, as the display hands it to a window
|
||||
//! (`types::display::window::THEME`). Its name stays behind.
|
||||
|
||||
use crate::{Rgba, Theme};
|
||||
|
||||
pub const WORDS: usize = types::display::window::THEME_WORDS;
|
||||
|
||||
fn colours(t: &Theme) -> [Rgba; 12] {
|
||||
[
|
||||
t.background,
|
||||
t.surface,
|
||||
t.surface_raised,
|
||||
t.accent,
|
||||
t.on_accent,
|
||||
t.text_primary,
|
||||
t.text_secondary,
|
||||
t.destructive,
|
||||
t.on_destructive,
|
||||
t.focus,
|
||||
t.orbs[0],
|
||||
t.orbs[1],
|
||||
]
|
||||
}
|
||||
|
||||
pub fn encode(t: &Theme) -> [usize; WORDS] {
|
||||
let c = colours(t);
|
||||
let mut w = [0usize; WORDS];
|
||||
for i in 0..6 {
|
||||
w[i] = c[2 * i].to_rgb() as usize | (c[2 * i + 1].to_rgb() as usize) << 32;
|
||||
}
|
||||
w[6] = t.corner_radius as usize
|
||||
| (t.spacing_base as usize) << 8
|
||||
| (t.blur_radius as usize) << 16
|
||||
| (t.panel_opacity as usize) << 24
|
||||
| (t.highlight as usize) << 32
|
||||
| (t.duration_fast as usize) << 40;
|
||||
w[7] = t.duration_normal as usize
|
||||
| (t.spring_stiffness as usize) << 16
|
||||
| (t.spring_damping as usize & 0xff) << 32
|
||||
| (t.orbs[2].to_rgb() as usize & 0xff_ffff) << 40;
|
||||
w
|
||||
}
|
||||
|
||||
pub fn decode(w: [usize; WORDS]) -> Theme {
|
||||
let c = |i: usize| Rgba::rgb((w[i / 2] >> (32 * (i % 2))) as u32 & 0xff_ffff);
|
||||
let byte = |word: usize, at: u32| (w[word] >> at) as u8;
|
||||
let half = |word: usize, at: u32| (w[word] >> at) as u16;
|
||||
Theme {
|
||||
name: [0; crate::NAME_BYTES],
|
||||
name_len: 0,
|
||||
background: c(0),
|
||||
surface: c(1),
|
||||
surface_raised: c(2),
|
||||
accent: c(3),
|
||||
on_accent: c(4),
|
||||
text_primary: c(5),
|
||||
text_secondary: c(6),
|
||||
destructive: c(7),
|
||||
on_destructive: c(8),
|
||||
focus: c(9),
|
||||
orbs: [c(10), c(11), Rgba::rgb((w[7] >> 40) as u32 & 0xff_ffff)],
|
||||
corner_radius: byte(6, 0) as f32,
|
||||
spacing_base: byte(6, 8) as f32,
|
||||
blur_radius: byte(6, 16),
|
||||
panel_opacity: byte(6, 24),
|
||||
highlight: byte(6, 32),
|
||||
duration_fast: half(6, 40),
|
||||
duration_normal: half(7, 0),
|
||||
spring_stiffness: half(7, 16),
|
||||
// At most 200 (see `parse`): a byte.
|
||||
spring_damping: byte(7, 32) as u16,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user