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(all(
24 feature = "usage_recorder",
25 any(feature = "outlined", feature = "filled", feature = "rounded", feature = "sharp")
26))]
27mod usage_recorder;
28
29#[cfg(all(
30 feature = "embedded",
31 any(feature = "outlined", feature = "filled", feature = "rounded", feature = "sharp")
32))]
33zng_env::on_process_start!(|_| {
34 zng_app::APP.on_init(zng_app::hn!(|args| {
35 if args.is_minimal {
36 return;
37 }
38
39 use zng_wgt::{ICONS, IconRequestArgs, prelude::UiNode, wgt_fn};
40 use zng_wgt_text::icon::{GlyphIcon, Icon};
41
42 #[cfg(feature = "usage_recorder")]
43 usage_recorder::on_init();
44
45 let sets = [
47 #[cfg(feature = "outlined")]
48 (outlined::FONT_NAME, outlined::FONT_BYTES),
49 #[cfg(feature = "filled")]
50 (filled::FONT_NAME, filled::FONT_BYTES),
51 #[cfg(feature = "rounded")]
52 (rounded::FONT_NAME, rounded::FONT_BYTES),
53 #[cfg(feature = "sharp")]
54 (sharp::FONT_NAME, sharp::FONT_BYTES),
55 ];
56 for (name, bytes) in sets {
57 let font = zng_ext_font::CustomFont::from_bytes(name, zng_ext_font::FontBytes::from_static(bytes), 0);
58 zng_ext_font::FONTS.register(font);
59 }
60
61 ICONS.register(wgt_fn!(|args: IconRequestArgs| {
63 if let Some(strong_key) = args.name().strip_prefix("material/") {
64 #[expect(clippy::type_complexity)]
65 let sets: &[(&str, fn(&str) -> Option<GlyphIcon>)] = &[
66 #[cfg(feature = "outlined")]
67 ("outlined/", outlined::get),
68 #[cfg(feature = "filled")]
69 ("filled/", filled::get),
70 #[cfg(feature = "rounded")]
71 ("rounded/", rounded::get),
72 #[cfg(feature = "sharp")]
73 ("sharp/", sharp::get),
74 ];
75 for (name, get) in sets {
76 if let Some(key) = strong_key.strip_prefix(name)
77 && let Some(ico) = get(key)
78 {
79 return Icon!(ico);
80 }
81 }
82 }
83
84 UiNode::nil()
85 }));
86
87 ICONS.register_fallback(wgt_fn!(|args: IconRequestArgs| {
88 let sets = [
89 #[cfg(feature = "outlined")]
90 outlined::get,
91 #[cfg(feature = "filled")]
92 filled::get,
93 #[cfg(feature = "rounded")]
94 rounded::get,
95 #[cfg(feature = "sharp")]
96 sharp::get,
97 ];
98 for get in sets {
99 if let Some(ico) = get(args.name()) {
100 return Icon!(ico);
101 }
102 }
103 UiNode::nil()
104 }));
105 }));
106});
107
108#[cfg(any(feature = "outlined", feature = "filled", feature = "rounded", feature = "sharp"))]
109macro_rules! getters {
110 ($FONT_NAME:ident, $MAP:ident) => {
111 pub fn get(key: &str) -> Option<GlyphIcon> {
113 let icon = GlyphIcon::new($FONT_NAME.clone(), *$MAP.get(key)?);
114 #[cfg(feature = "usage_recorder")]
115 USAGE.insert(key);
116 Some(icon)
117 }
118
119 #[cfg(feature = "usage_recorder")]
120 pub(crate) static USAGE: std::sync::LazyLock<crate::usage_recorder::UsageRecorder> = std::sync::LazyLock::new(Default::default);
121
122 pub fn req(key: &str) -> GlyphIcon {
130 match get(key) {
131 Some(g) => g,
132 None => {
133 tracing::error!("icon {key:?} not found in `outlined`");
134 GlyphIcon::new("", '\0')
135 }
136 }
137 }
138
139 pub fn all() -> impl ExactSizeIterator<Item = (&'static str, GlyphIcon)> {
141 $MAP.entries()
142 .map(|(key, val)| (*key, GlyphIcon::new($FONT_NAME.clone(), *val)))
143 }
144 };
145}
146
147#[doc = include_str!(concat!(env!("OUT_DIR"), "/generated.outlined.docs.txt"))]
164#[cfg(feature = "outlined")]
165pub mod outlined {
166 use zng_ext_font::FontName;
167 use zng_wgt_text::icon::GlyphIcon;
168
169 pub const FONT_NAME: FontName = FontName::from_static("Material Icons Outlined");
171
172 #[cfg(feature = "embedded")]
174 pub const FONT_BYTES: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/generated.outlined.ttf"));
175
176 include!(concat!(env!("OUT_DIR"), "/generated.outlined.map.rs"));
177 getters!(FONT_NAME, MAP);
178}
179
180#[doc = include_str!(concat!(env!("OUT_DIR"), "/generated.filled.docs.txt"))]
197#[cfg(feature = "filled")]
198pub mod filled {
199 use zng_ext_font::FontName;
200 use zng_wgt_text::icon::GlyphIcon;
201
202 pub const FONT_NAME: FontName = FontName::from_static("Material Icons");
204
205 #[cfg(feature = "embedded")]
207 pub const FONT_BYTES: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/generated.filled.ttf"));
208
209 include!(concat!(env!("OUT_DIR"), "/generated.filled.map.rs"));
210 getters!(FONT_NAME, MAP);
211}
212
213#[doc = include_str!(concat!(env!("OUT_DIR"), "/generated.rounded.docs.txt"))]
230#[cfg(feature = "rounded")]
231pub mod rounded {
232 use zng_ext_font::FontName;
233 use zng_wgt_text::icon::GlyphIcon;
234
235 pub const FONT_NAME: FontName = FontName::from_static("Material Icons Rounded");
237
238 #[cfg(feature = "embedded")]
240 pub const FONT_BYTES: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/generated.rounded.ttf"));
241
242 include!(concat!(env!("OUT_DIR"), "/generated.rounded.map.rs"));
243 getters!(FONT_NAME, MAP);
244}
245
246#[doc = include_str!(concat!(env!("OUT_DIR"), "/generated.sharp.docs.txt"))]
263#[cfg(feature = "sharp")]
264pub mod sharp {
265 use zng_ext_font::FontName;
266 use zng_wgt_text::icon::GlyphIcon;
267
268 pub const FONT_NAME: FontName = FontName::from_static("Material Icons Sharp");
270
271 #[cfg(feature = "embedded")]
273 pub const FONT_BYTES: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/generated.sharp.ttf"));
274
275 include!(concat!(env!("OUT_DIR"), "/generated.sharp.map.rs"));
276 getters!(FONT_NAME, MAP);
277}