1use eframe::egui::{self, Color32, Response, Sense, Ui, Vec2, Widget};
2
3pub struct MaterialIcon {
4 name: String,
5 size: f32,
6 color: Option<Color32>,
7 filled: bool,
8}
9
10impl MaterialIcon {
11 pub fn new(name: impl Into<String>) -> Self {
12 Self {
13 name: name.into(),
14 size: 24.0,
15 color: None,
16 filled: false,
17 }
18 }
19
20 pub fn size(mut self, size: f32) -> Self {
21 self.size = size;
22 self
23 }
24
25 pub fn color(mut self, color: Color32) -> Self {
26 self.color = Some(color);
27 self
28 }
29
30 pub fn filled(mut self, filled: bool) -> Self {
31 self.filled = filled;
32 self
33 }
34}
35
36impl Widget for MaterialIcon {
37 fn ui(self, ui: &mut Ui) -> Response {
38 let desired_size = Vec2::splat(self.size);
39 let (rect, response) = ui.allocate_exact_size(desired_size, Sense::hover());
40
41 let icon_color = self
42 .color
43 .unwrap_or_else(|| Color32::from_gray(if ui.visuals().dark_mode { 230 } else { 30 }));
44
45 ui.painter().text(
47 rect.center(),
48 egui::Align2::CENTER_CENTER,
49 &self.name,
50 egui::FontId::proportional(self.size),
51 icon_color,
52 );
53
54 response
55 }
56}
57
58pub fn icon(name: impl Into<String>) -> MaterialIcon {
59 MaterialIcon::new(name)
60}