zng_wgt_material_icons/
lib.rs1#![doc(html_favicon_url = "https://zng-ui.github.io/res/zng-logo-icon.png")]
2#![doc(html_logo_url = "https://zng-ui.github.io/res/zng-logo.png")]
3#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
18#![warn(unused_extern_crates)]
19#![warn(missing_docs)]
20
21zng_wgt::enable_widget_macros!();
22
23#[cfg(feature = "usage_recorder")]
24mod usage_recorder;
25
26#[cfg(all(
27 feature = "embedded",
28 any(feature = "outlined", feature = "filled", feature = "rounded", feature = "sharp")
29))]
30zng_env::on_process_start!(|_| {
31 zng_app::APP.on_init(zng_app::hn!(|args| {
32 if args.is_minimal {
33 return;
34 }
35
36 use zng_wgt::{ICONS, IconRequestArgs, prelude::UiNode, wgt_fn};
37 use zng_wgt_text::icon::{GlyphIcon, Icon};
38
39 #[cfg(feature = "usage_recorder")]
40 usage_recorder::on_init();
41
42 let sets = [
44 #[cfg(feature = "outlined")]
45 (outlined::FONT_NAME, outlined::FONT_BYTES),
46 #[cfg(feature = "filled")]
47 (filled::FONT_NAME, filled::FONT_BYTES),
48 #[cfg(feature = "rounded")]
49 (rounded::FONT_NAME, rounded::FONT_BYTES),
50 #[cfg(feature = "sharp")]
51 (sharp::FONT_NAME, sharp::FONT_BYTES),
52 ];
53 for (name, bytes) in sets {
54 let font = zng_ext_font::CustomFont::from_bytes(name, zng_ext_font::FontBytes::from_static(bytes), 0);
55 zng_ext_font::FONTS.register(font);
56 }
57
58 ICONS.register(wgt_fn!(|args: IconRequestArgs| {
60 if let Some(strong_key) = args.name().strip_prefix("material/") {
61 #[expect(clippy::type_complexity)]
62 let sets: &[(&str, fn(&str) -> Option<GlyphIcon>)] = &[
63 #[cfg(feature = "outlined")]
64 ("outlined/", outlined::get),
65 #[cfg(feature = "filled")]
66 ("filled/", filled::get),
67 #[cfg(feature = "rounded")]
68 ("rounded/", rounded::get),
69 #[cfg(feature = "sharp")]
70 ("sharp/", sharp::get),
71 ];
72 for (name, get) in sets {
73 if let Some(key) = strong_key.strip_prefix(name)
74 && let Some(ico) = get(key)
75 {
76 return Icon!(ico);
77 }
78 }
79 }
80
81 UiNode::nil()
82 }));
83
84 ICONS.register_fallback(wgt_fn!(|args: IconRequestArgs| {
85 let sets = [
86 #[cfg(feature = "outlined")]
87 outlined::get,
88 #[cfg(feature = "filled")]
89 filled::get,
90 #[cfg(feature = "rounded")]
91 rounded::get,
92 #[cfg(feature = "sharp")]
93 sharp::get,
94 ];
95 for get in sets {
96 if let Some(ico) = get(args.name()) {
97 return Icon!(ico);
98 }
99 }
100 UiNode::nil()
101 }));
102 }));
103});
104
105#[cfg(any(feature = "outlined", feature = "filled", feature = "rounded", feature = "sharp"))]
106macro_rules! getters {
107 ($FONT_NAME:ident, $MAP:ident) => {
108 pub fn get(key: &str) -> Option<GlyphIcon> {
110 let icon = GlyphIcon::new($FONT_NAME.clone(), *$MAP.get(key)?);
111 #[cfg(feature = "usage_recorder")]
112 USAGE.insert(key);
113 Some(icon)
114 }
115
116 #[cfg(feature = "usage_recorder")]
117 pub(crate) static USAGE: std::sync::LazyLock<crate::usage_recorder::UsageRecorder> = std::sync::LazyLock::new(Default::default);
118
119 pub fn req(key: &str) -> GlyphIcon {
127 match get(key) {
128 Some(g) => g,
129 None => {
130 tracing::error!("icon {key:?} not found in `outlined`");
131 GlyphIcon::new("", '\0')
132 }
133 }
134 }
135
136 pub fn all() -> impl ExactSizeIterator<Item = (&'static str, GlyphIcon)> {
138 $MAP.entries()
139 .map(|(key, val)| (*key, GlyphIcon::new($FONT_NAME.clone(), *val)))
140 }
141 };
142}
143
144#[doc = include_str!(concat!(env!("OUT_DIR"), "/generated.outlined.docs.txt"))]
161#[cfg(feature = "outlined")]
162pub mod outlined {
163 use zng_ext_font::FontName;
164 use zng_wgt_text::icon::GlyphIcon;
165
166 pub const FONT_NAME: FontName = FontName::from_static("Material Icons Outlined");
168
169 #[cfg(feature = "embedded")]
171 pub const FONT_BYTES: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/generated.outlined.ttf"));
172
173 include!(concat!(env!("OUT_DIR"), "/generated.outlined.map.rs"));
174 getters!(FONT_NAME, MAP);
175}
176
177#[doc = include_str!(concat!(env!("OUT_DIR"), "/generated.filled.docs.txt"))]
194#[cfg(feature = "filled")]
195pub mod filled {
196 use zng_ext_font::FontName;
197 use zng_wgt_text::icon::GlyphIcon;
198
199 pub const FONT_NAME: FontName = FontName::from_static("Material Icons");
201
202 #[cfg(feature = "embedded")]
204 pub const FONT_BYTES: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/generated.filled.ttf"));
205
206 include!(concat!(env!("OUT_DIR"), "/generated.filled.map.rs"));
207 getters!(FONT_NAME, MAP);
208}
209
210#[doc = include_str!(concat!(env!("OUT_DIR"), "/generated.rounded.docs.txt"))]
227#[cfg(feature = "rounded")]
228pub mod rounded {
229 use zng_ext_font::FontName;
230 use zng_wgt_text::icon::GlyphIcon;
231
232 pub const FONT_NAME: FontName = FontName::from_static("Material Icons Rounded");
234
235 #[cfg(feature = "embedded")]
237 pub const FONT_BYTES: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/generated.rounded.ttf"));
238
239 include!(concat!(env!("OUT_DIR"), "/generated.rounded.map.rs"));
240 getters!(FONT_NAME, MAP);
241}
242
243#[doc = include_str!(concat!(env!("OUT_DIR"), "/generated.sharp.docs.txt"))]
260#[cfg(feature = "sharp")]
261pub mod sharp {
262 use zng_ext_font::FontName;
263 use zng_wgt_text::icon::GlyphIcon;
264
265 pub const FONT_NAME: FontName = FontName::from_static("Material Icons Sharp");
267
268 #[cfg(feature = "embedded")]
270 pub const FONT_BYTES: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/generated.sharp.ttf"));
271
272 include!(concat!(env!("OUT_DIR"), "/generated.sharp.map.rs"));
273 getters!(FONT_NAME, MAP);
274}