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!(|args| {
31 if args.yield_until_app() {
32 return;
33 }
34 zng_app::APP.on_init(zng_app::hn!(|_| {
35 use zng_wgt::{ICONS, IconRequestArgs, prelude::UiNode, wgt_fn};
36 use zng_wgt_text::icon::{GlyphIcon, Icon};
37
38 #[cfg(feature = "usage_recorder")]
39 usage_recorder::on_init();
40
41 let sets = [
43 #[cfg(feature = "outlined")]
44 (outlined::FONT_NAME, outlined::FONT_BYTES),
45 #[cfg(feature = "filled")]
46 (filled::FONT_NAME, filled::FONT_BYTES),
47 #[cfg(feature = "rounded")]
48 (rounded::FONT_NAME, rounded::FONT_BYTES),
49 #[cfg(feature = "sharp")]
50 (sharp::FONT_NAME, sharp::FONT_BYTES),
51 ];
52 for (name, bytes) in sets {
53 let font = zng_ext_font::CustomFont::from_bytes(name, zng_ext_font::FontBytes::from_static(bytes), 0);
54 zng_ext_font::FONTS.register(font);
55 }
56
57 ICONS.register(wgt_fn!(|args: IconRequestArgs| {
59 if let Some(strong_key) = args.name().strip_prefix("material/") {
60 #[expect(clippy::type_complexity)]
61 let sets: &[(&str, fn(&str) -> Option<GlyphIcon>)] = &[
62 #[cfg(feature = "outlined")]
63 ("outlined/", outlined::get),
64 #[cfg(feature = "filled")]
65 ("filled/", filled::get),
66 #[cfg(feature = "rounded")]
67 ("rounded/", rounded::get),
68 #[cfg(feature = "sharp")]
69 ("sharp/", sharp::get),
70 ];
71 for (name, get) in sets {
72 if let Some(key) = strong_key.strip_prefix(name)
73 && let Some(ico) = get(key)
74 {
75 return Icon!(ico);
76 }
77 }
78 }
79
80 UiNode::nil()
81 }));
82
83 ICONS.register_fallback(wgt_fn!(|args: IconRequestArgs| {
84 let sets = [
85 #[cfg(feature = "outlined")]
86 outlined::get,
87 #[cfg(feature = "filled")]
88 filled::get,
89 #[cfg(feature = "rounded")]
90 rounded::get,
91 #[cfg(feature = "sharp")]
92 sharp::get,
93 ];
94 for get in sets {
95 if let Some(ico) = get(args.name()) {
96 return Icon!(ico);
97 }
98 }
99 UiNode::nil()
100 }));
101 }));
102});
103
104#[cfg(any(feature = "outlined", feature = "filled", feature = "rounded", feature = "sharp"))]
105macro_rules! getters {
106 ($FONT_NAME:ident, $MAP:ident) => {
107 pub fn get(key: &str) -> Option<GlyphIcon> {
109 let icon = GlyphIcon::new($FONT_NAME.clone(), *$MAP.get(key)?);
110 #[cfg(feature = "usage_recorder")]
111 USAGE.insert(key);
112 Some(icon)
113 }
114
115 #[cfg(feature = "usage_recorder")]
116 pub(crate) static USAGE: std::sync::LazyLock<crate::usage_recorder::UsageRecorder> = std::sync::LazyLock::new(Default::default);
117
118 pub fn req(key: &str) -> GlyphIcon {
126 match get(key) {
127 Some(g) => g,
128 None => {
129 tracing::error!("icon {key:?} not found in `outlined`");
130 GlyphIcon::new("", '\0')
131 }
132 }
133 }
134
135 pub fn all() -> impl ExactSizeIterator<Item = (&'static str, GlyphIcon)> {
137 $MAP.entries()
138 .map(|(key, val)| (*key, GlyphIcon::new($FONT_NAME.clone(), *val)))
139 }
140 };
141}
142
143#[doc = include_str!(concat!(env!("OUT_DIR"), "/generated.outlined.docs.txt"))]
160#[cfg(feature = "outlined")]
161pub mod outlined {
162 use zng_ext_font::FontName;
163 use zng_wgt_text::icon::GlyphIcon;
164
165 pub const FONT_NAME: FontName = FontName::from_static("Material Icons Outlined");
167
168 #[cfg(feature = "embedded")]
170 pub const FONT_BYTES: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/generated.outlined.ttf"));
171
172 include!(concat!(env!("OUT_DIR"), "/generated.outlined.map.rs"));
173 getters!(FONT_NAME, MAP);
174}
175
176#[doc = include_str!(concat!(env!("OUT_DIR"), "/generated.filled.docs.txt"))]
193#[cfg(feature = "filled")]
194pub mod filled {
195 use zng_ext_font::FontName;
196 use zng_wgt_text::icon::GlyphIcon;
197
198 pub const FONT_NAME: FontName = FontName::from_static("Material Icons");
200
201 #[cfg(feature = "embedded")]
203 pub const FONT_BYTES: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/generated.filled.ttf"));
204
205 include!(concat!(env!("OUT_DIR"), "/generated.filled.map.rs"));
206 getters!(FONT_NAME, MAP);
207}
208
209#[doc = include_str!(concat!(env!("OUT_DIR"), "/generated.rounded.docs.txt"))]
226#[cfg(feature = "rounded")]
227pub mod rounded {
228 use zng_ext_font::FontName;
229 use zng_wgt_text::icon::GlyphIcon;
230
231 pub const FONT_NAME: FontName = FontName::from_static("Material Icons Rounded");
233
234 #[cfg(feature = "embedded")]
236 pub const FONT_BYTES: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/generated.rounded.ttf"));
237
238 include!(concat!(env!("OUT_DIR"), "/generated.rounded.map.rs"));
239 getters!(FONT_NAME, MAP);
240}
241
242#[doc = include_str!(concat!(env!("OUT_DIR"), "/generated.sharp.docs.txt"))]
259#[cfg(feature = "sharp")]
260pub mod sharp {
261 use zng_ext_font::FontName;
262 use zng_wgt_text::icon::GlyphIcon;
263
264 pub const FONT_NAME: FontName = FontName::from_static("Material Icons Sharp");
266
267 #[cfg(feature = "embedded")]
269 pub const FONT_BYTES: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/generated.sharp.ttf"));
270
271 include!(concat!(env!("OUT_DIR"), "/generated.sharp.map.rs"));
272 getters!(FONT_NAME, MAP);
273}