zng_wgt_material_icons/
lib.rs
1#![doc(html_favicon_url = "https://raw.githubusercontent.com/zng-ui/zng/main/examples/image/res/zng-logo-icon.png")]
2#![doc(html_logo_url = "https://raw.githubusercontent.com/zng-ui/zng/main/examples/image/res/zng-logo.png")]
3#![doc = include_str!(concat!("../", std::env!("CARGO_PKG_README")))]
19#![warn(unused_extern_crates)]
20#![warn(missing_docs)]
21
22zng_wgt::enable_widget_macros!();
23
24pub struct MaterialIconsManager;
30impl MaterialIconsManager {
31 #[cfg(all(
32 feature = "embedded",
33 any(feature = "outlined", feature = "filled", feature = "rounded", feature = "sharp")
34 ))]
35 fn register_fonts(&self) {
36 let sets = [
37 #[cfg(feature = "outlined")]
38 (outlined::FONT_NAME, outlined::FONT_BYTES),
39 #[cfg(feature = "filled")]
40 (filled::FONT_NAME, filled::FONT_BYTES),
41 #[cfg(feature = "rounded")]
42 (rounded::FONT_NAME, rounded::FONT_BYTES),
43 #[cfg(feature = "sharp")]
44 (sharp::FONT_NAME, sharp::FONT_BYTES),
45 ];
46
47 for (name, bytes) in sets {
48 let font = zng_ext_font::CustomFont::from_bytes(name, zng_ext_font::FontDataRef::from_static(bytes), 0);
49 zng_ext_font::FONTS.register(font);
50 }
51 }
52}
53#[cfg(feature = "embedded")]
54impl zng_app::AppExtension for MaterialIconsManager {
55 #[cfg(any(feature = "outlined", feature = "filled", feature = "rounded", feature = "sharp"))]
56 fn init(&mut self) {
57 use zng_app::widget::node::{NilUiNode, UiNode as _};
58 use zng_wgt::{ICONS, IconRequestArgs, wgt_fn};
59 use zng_wgt_text::icon::{GlyphIcon, Icon};
60
61 self.register_fonts();
62
63 ICONS.register(wgt_fn!(|args: IconRequestArgs| {
64 if let Some(strong_key) = args.name().strip_prefix("material/") {
65 #[expect(clippy::type_complexity)]
66 let sets: &[(&str, fn(&str) -> Option<GlyphIcon>)] = &[
67 #[cfg(feature = "outlined")]
68 ("outlined/", outlined::get),
69 #[cfg(feature = "filled")]
70 ("filled/", filled::get),
71 #[cfg(feature = "rounded")]
72 ("rounded/", rounded::get),
73 #[cfg(feature = "sharp")]
74 ("sharp/", sharp::get),
75 ];
76 for (name, get) in sets {
77 if let Some(key) = strong_key.strip_prefix(name) {
78 if let Some(ico) = get(key) {
79 return Icon!(ico).boxed();
80 }
81 }
82 }
83 }
84
85 NilUiNode.boxed()
86 }));
87
88 ICONS.register_fallback(wgt_fn!(|args: IconRequestArgs| {
89 let sets = [
90 #[cfg(feature = "outlined")]
91 outlined::get,
92 #[cfg(feature = "filled")]
93 filled::get,
94 #[cfg(feature = "rounded")]
95 rounded::get,
96 #[cfg(feature = "sharp")]
97 sharp::get,
98 ];
99 for get in sets {
100 if let Some(ico) = get(args.name()) {
101 return Icon!(ico).boxed();
102 }
103 }
104 NilUiNode.boxed()
105 }));
106 }
107}
108
109#[cfg(any(feature = "outlined", feature = "filled", feature = "rounded", feature = "sharp"))]
110macro_rules! getters {
111 ($FONT_NAME:ident, $MAP:ident) => {
112 pub fn get(key: &str) -> Option<GlyphIcon> {
114 Some(GlyphIcon::new($FONT_NAME.clone(), *$MAP.get(key)?))
115 }
116
117 pub fn req(key: &str) -> GlyphIcon {
125 match get(key) {
126 Some(g) => g,
127 None => {
128 tracing::error!("icon {key:?} not found in `outlined`");
129 GlyphIcon::new("", '\0')
130 }
131 }
132 }
133
134 pub fn all() -> impl ExactSizeIterator<Item = (&'static str, GlyphIcon)> {
136 $MAP.entries()
137 .map(|(key, val)| (*key, GlyphIcon::new($FONT_NAME.clone(), *val)))
138 }
139 };
140}
141
142#[doc = include_str!(concat!(env!("OUT_DIR"), "/generated.outlined.docs.txt"))]
159#[cfg(feature = "outlined")]
160pub mod outlined {
161 use zng_ext_font::FontName;
162 use zng_wgt_text::icon::GlyphIcon;
163
164 pub const FONT_NAME: FontName = FontName::from_static("Material Icons Outlined");
166
167 #[cfg(feature = "embedded")]
169 pub const FONT_BYTES: &[u8] = include_bytes!("../fonts/MaterialIconsOutlined-Regular.otf");
170
171 include!(concat!(env!("OUT_DIR"), "/generated.outlined.map.rs"));
172 getters!(FONT_NAME, MAP);
173}
174
175#[doc = include_str!(concat!(env!("OUT_DIR"), "/generated.filled.docs.txt"))]
192#[cfg(feature = "filled")]
193pub mod filled {
194 use zng_ext_font::FontName;
195 use zng_wgt_text::icon::GlyphIcon;
196
197 pub const FONT_NAME: FontName = FontName::from_static("Material Icons");
199
200 #[cfg(feature = "embedded")]
202 pub const FONT_BYTES: &[u8] = include_bytes!("../fonts/MaterialIcons-Regular.ttf");
203
204 include!(concat!(env!("OUT_DIR"), "/generated.filled.map.rs"));
205 getters!(FONT_NAME, MAP);
206}
207
208#[doc = include_str!(concat!(env!("OUT_DIR"), "/generated.rounded.docs.txt"))]
225#[cfg(feature = "rounded")]
226pub mod rounded {
227 use zng_ext_font::FontName;
228 use zng_wgt_text::icon::GlyphIcon;
229
230 pub const FONT_NAME: FontName = FontName::from_static("Material Icons Rounded");
232
233 #[cfg(feature = "embedded")]
235 pub const FONT_BYTES: &[u8] = include_bytes!("../fonts/MaterialIconsRound-Regular.otf");
236
237 include!(concat!(env!("OUT_DIR"), "/generated.rounded.map.rs"));
238 getters!(FONT_NAME, MAP);
239}
240
241#[doc = include_str!(concat!(env!("OUT_DIR"), "/generated.sharp.docs.txt"))]
258#[cfg(feature = "sharp")]
259pub mod sharp {
260 use zng_ext_font::FontName;
261 use zng_wgt_text::icon::GlyphIcon;
262
263 pub const FONT_NAME: FontName = FontName::from_static("Material Icons Sharp");
265
266 #[cfg(feature = "embedded")]
268 pub const FONT_BYTES: &[u8] = include_bytes!("../fonts/MaterialIconsSharp-Regular.otf");
269
270 include!(concat!(env!("OUT_DIR"), "/generated.sharp.map.rs"));
271 getters!(FONT_NAME, MAP);
272}