Skip to main content

egui_material3/
icon.rs

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        // Render icon character from MaterialSymbolsOutlined font
46        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}