llimphi_widget_empty/
lib.rs1#![forbid(unsafe_code)]
10
11use llimphi_ui::llimphi_layout::taffy::{
12 prelude::{length, percent, FlexDirection, Size, Style},
13 AlignItems, JustifyContent,
14};
15use llimphi_ui::llimphi_raster::peniko::Color;
16use llimphi_ui::llimphi_text::Alignment;
17use llimphi_ui::View;
18use llimphi_icons::{icon_view, Icon};
19use llimphi_theme::{alpha, Theme};
20
21#[derive(Debug, Clone, Copy)]
24pub struct EmptyPalette {
25 pub fg_icon: Color,
26 pub fg_title: Color,
27 pub fg_desc: Color,
28}
29
30impl EmptyPalette {
31 pub fn from_theme(t: &Theme) -> Self {
32 Self {
33 fg_icon: with_alpha8(t.fg_muted, alpha::HINT),
34 fg_title: t.fg_muted,
35 fg_desc: with_alpha8(t.fg_muted, alpha::DISABLED),
36 }
37 }
38}
39
40fn with_alpha8(c: Color, a: u8) -> Color {
41 let [r, g, b, _] = c.components;
42 use llimphi_ui::llimphi_raster::peniko::color::AlphaColor;
43 AlphaColor::new([r, g, b, a as f32 / 255.0])
44}
45
46pub fn empty_view<Msg: Clone + 'static>(
57 icon: Icon,
58 title: impl Into<String>,
59 description: Option<&str>,
60 palette: &EmptyPalette,
61) -> View<Msg> {
62 let icon_cell = View::new(Style {
63 size: Size {
64 width: length(72.0_f32),
65 height: length(72.0_f32),
66 },
67 flex_shrink: 0.0,
68 ..Default::default()
69 })
70 .children(vec![icon_view(icon, palette.fg_icon, 1.4)]);
71
72 let title_view = View::new(Style {
73 size: Size {
74 width: percent(1.0_f32),
75 height: length(28.0_f32),
76 },
77 flex_shrink: 0.0,
78 ..Default::default()
79 })
80 .text_aligned(title.into(), 15.5, palette.fg_title, Alignment::Center);
81
82 let mut children = vec![icon_cell, title_view];
83 if let Some(desc) = description {
84 children.push(
85 View::new(Style {
86 size: Size {
87 width: length(360.0_f32),
88 height: length(40.0_f32),
89 },
90 flex_shrink: 0.0,
91 ..Default::default()
92 })
93 .text_aligned(desc.to_string(), 12.0, palette.fg_desc, Alignment::Center),
94 );
95 }
96
97 View::new(Style {
98 flex_direction: FlexDirection::Column,
99 size: Size {
100 width: percent(1.0_f32),
101 height: percent(1.0_f32),
102 },
103 align_items: Some(AlignItems::Center),
104 justify_content: Some(JustifyContent::Center),
105 gap: Size {
106 width: length(0.0_f32),
107 height: length(14.0_f32),
108 },
109 ..Default::default()
110 })
111 .children(children)
112}