ltk/
chassis.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
//! Scaffolding shared by full-screen ambient surfaces (greeter, lock screen,
//! kiosk): theme bring-up, branding/wallpaper loading and the wallpaper-backed
//! view stack. Thin convenience over [`theme`](crate::theme) and
//! [`WallpaperBundle`](crate::WallpaperBundle) — every app that paints a
//! wallpaper behind centred content repeats this otherwise.

use std::sync::Arc;

use crate::{ Color, Element, ImageData, ThemeMode, WallpaperBundle };

/// Find, install and activate the `default` theme document in `mode`. Returns
/// the failure message instead of exiting; the caller decides how to abort.
pub fn set_default_theme( mode: ThemeMode ) -> Result<(), String>
{
	let doc = crate::ThemeDocument::find( "default" ).map_err( |e| format!( "{e}" ) )?;
	crate::set_active_document( doc );
	crate::set_active_mode( mode );
	Ok( () )
}

/// Decode the active theme's horizontal logo to RGBA, `size` px on the longer
/// edge. `None` if the theme ships no logo or the SVG fails to rasterise.
pub fn theme_logo_rgba( size: u32 ) -> Option<ImageData>
{
	let path  = crate::theme_logo_horizontal()?;
	let bytes = std::fs::read( &path ).ok()?;
	crate::decode_svg_bytes( &bytes, size )
}

/// Load a symbolic theme icon to RGBA, tinted with `tint`. `None` if missing.
pub fn theme_icon_tinted( name: &str, size: u32, tint: Color ) -> Option<ImageData>
{
	let ( rgba, w, h ) = crate::theme_icon_rgba( name, size )?;
	Some( ( Arc::new( crate::tint_symbolic( &rgba, tint ) ), w, h ) )
}

/// The active theme's branding image `name` (e.g. `"wallpaper"`,
/// `"lockscreen"`) as a [`WallpaperBundle`], falling back to a solid fill of
/// the palette background when the theme ships none.
pub fn branding_bundle_or_solid( name: &str ) -> WallpaperBundle
{
	let path = crate::theme_branding_image( name, 0, 0 );
	let bg   = crate::theme_palette().bg;
	WallpaperBundle::from_path_or_solid(
		path.as_deref(),
		( bg.r * 255.0 ) as u8,
		( bg.g * 255.0 ) as u8,
		( bg.b * 255.0 ) as u8,
	)
}

/// Convenience for [`branding_bundle_or_solid`] with `"wallpaper"`.
pub fn wallpaper_bundle_or_solid() -> WallpaperBundle
{
	branding_bundle_or_solid( "wallpaper" )
}

/// Stack `content` over `wallpaper` resolved for the given surface size.
pub fn backdrop<M: Clone>( content: Element<M>, wallpaper: &WallpaperBundle, w: u32, h: u32 ) -> Element<M>
{
	let ( rgba, iw, ih ) = wallpaper.for_size( w, h );
	crate::stack::<M>()
		.push( crate::img_widget( rgba, iw, ih ) )
		.push( content )
		.into()
}