egui_macview/controls/
button_cell.rs1use crate::theme::MacTheme;
7use egui::{Color32, CornerRadius, Response, Stroke, StrokeKind, Ui, Vec2, Widget};
8
9pub struct MacButtonCell<'a> {
30 text: &'a str,
31 selected: bool,
32 theme: Option<&'a MacTheme>,
33 width: Option<f32>,
34 height: Option<f32>,
35 corner_radius: Option<f32>,
36}
37
38impl<'a> MacButtonCell<'a> {
39 pub fn new(text: &'a str) -> Self {
41 Self {
42 text,
43 selected: false,
44 theme: None,
45 width: None,
46 height: None,
47 corner_radius: None,
48 }
49 }
50
51 pub fn theme(mut self, theme: &'a MacTheme) -> Self {
53 self.theme = Some(theme);
54 self
55 }
56
57 pub fn selected(mut self, selected: bool) -> Self {
59 self.selected = selected;
60 self
61 }
62
63 pub fn width(mut self, width: f32) -> Self {
65 self.width = Some(width);
66 self
67 }
68
69 pub fn height(mut self, height: f32) -> Self {
71 self.height = Some(height);
72 self
73 }
74
75 pub fn corner_radius(mut self, r: f32) -> Self {
77 self.corner_radius = Some(r);
78 self
79 }
80}
81
82impl<'a> Widget for MacButtonCell<'a> {
83 fn ui(self, ui: &mut Ui) -> Response {
84 let fallback_theme;
85 let theme = match self.theme {
86 Some(t) => t,
87 None => {
88 fallback_theme = MacTheme::default();
89 &fallback_theme
90 }
91 };
92
93 let metrics = &theme.button().regular;
94 let height = self.height.unwrap_or_else(|| metrics.height.points());
95 let corner_radius = self
96 .corner_radius
97 .unwrap_or_else(|| metrics.corner_radius.points());
98 let padding_h = metrics
99 .padding_horizontal
100 .as_ref()
101 .map(|d| d.points())
102 .unwrap_or_else(|| metrics.font_size.points());
103
104 let font_id = egui::FontId::proportional(metrics.font_size.points());
105 let text_layout =
106 ui.painter()
107 .layout_no_wrap(self.text.to_owned(), font_id.clone(), Color32::WHITE);
108 let desired_width = self
109 .width
110 .unwrap_or_else(|| text_layout.size().x + padding_h * 2.0);
111
112 let (rect, response) =
113 ui.allocate_exact_size(Vec2::new(desired_width, height), egui::Sense::click());
114
115 let painter = ui.painter_at(rect);
116
117 let bg_color = if self.selected {
119 theme.selected_control()
120 } else if response.is_pointer_button_down_on() {
121 theme.selected_control_inactive()
122 } else if response.hovered() {
123 theme.control()
124 } else {
125 theme.control_background()
126 };
127
128 let border_stroke = Stroke::new(metrics.border_width.points(), theme.separator());
129
130 painter.rect(
131 rect,
132 CornerRadius::same(corner_radius as u8),
133 bg_color,
134 border_stroke,
135 StrokeKind::Inside,
136 );
137
138 let bg_style = theme.background_style(bg_color);
139 let text_color = bg_style.primary_text_color(theme);
140
141 painter.text(
142 rect.center(),
143 egui::Align2::CENTER_CENTER,
144 self.text,
145 font_id,
146 text_color,
147 );
148
149 response
150 }
151}