egui_charts/ui_kit/buttons/
icon_button.rs1use super::{ButtonSize, ButtonVariant, finish};
6use crate::icons::Icon;
7use crate::theme::ThemeExt;
8use egui::{Rect, Response, Sense, Ui, Vec2};
9
10pub struct IconButton<'a> {
35 icon: &'a Icon,
36 size: ButtonSize,
37 tooltip: Option<String>,
38 selected: Option<bool>,
39 enabled: bool,
40 icon_scale: Option<f32>,
41}
42
43impl<'a> IconButton<'a> {
44 pub fn new(icon: &'a Icon) -> Self {
46 Self {
47 icon,
48 size: ButtonSize::MD,
49 tooltip: None,
50 selected: None,
51 enabled: true,
52 icon_scale: None,
53 }
54 }
55
56 #[must_use]
58 pub fn size(mut self, size: ButtonSize) -> Self {
59 self.size = size;
60 self
61 }
62
63 #[must_use]
65 pub fn tooltip(mut self, text: impl Into<String>) -> Self {
66 self.tooltip = Some(text.into());
67 self
68 }
69
70 #[must_use]
72 pub fn selected(mut self, selected: bool) -> Self {
73 self.selected = Some(selected);
74 self
75 }
76
77 #[must_use]
79 pub fn enabled(mut self, enabled: bool) -> Self {
80 self.enabled = enabled;
81 self
82 }
83
84 #[must_use]
88 pub fn icon_scale(mut self, scale: f32) -> Self {
89 self.icon_scale = Some(scale.clamp(0.1, 1.0));
90 self
91 }
92
93 pub fn show(self, ui: &mut Ui) -> Response {
95 if !self.enabled {
96 return ui.add_enabled(false, |ui: &mut Ui| {
98 Self {
99 enabled: true,
100 ..self
101 }
102 .show(ui)
103 });
104 }
105
106 let button_size = Vec2::splat(self.size.pixels());
107 let (rect, response) = ui.allocate_exact_size(button_size, Sense::click());
108 crate::styles::focus::draw_focus_ring(ui, &response, ui.active_theme().radius.sm);
109
110 if ui.is_rect_visible(rect) {
111 let hovered = response.hovered();
112 let pressed = response.is_pointer_button_down_on();
113 let variant = if self.selected == Some(true) {
114 ButtonVariant::Primary
115 } else {
116 ButtonVariant::Ghost
117 };
118 ui.painter().rect_filled(
119 rect,
120 ui.active_theme().radius.sm,
121 variant.bg_color(ui, hovered, pressed),
122 );
123
124 let icon_color = if self.selected == Some(true) {
125 variant.fg_color(ui)
126 } else {
127 ui.style().interact(&response).fg_stroke.color
128 };
129 let icon_size = Vec2::splat(self.size.icon_pixels(self.icon_scale));
130 self.icon
131 .as_image_tinted(icon_size, icon_color)
132 .paint_at(ui, Rect::from_center_size(rect.center(), icon_size));
133 }
134
135 let tooltip = self.tooltip.as_deref();
136 finish(
137 response,
138 self.selected,
139 tooltip.unwrap_or_default(),
140 tooltip,
141 )
142 }
143}