egui/widgets/
radio_button.rs1use crate::*;
2
3#[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
23pub struct RadioButton {
24 checked: bool,
25 text: WidgetText,
26}
27
28impl RadioButton {
29 pub fn new(checked: bool, text: impl Into<WidgetText>) -> Self {
30 Self {
31 checked,
32 text: text.into(),
33 }
34 }
35}
36
37impl Widget for RadioButton {
38 fn ui(self, ui: &mut Ui) -> Response {
39 let Self { checked, text } = self;
40
41 let spacing = &ui.spacing();
42 let icon_width = spacing.icon_width;
43 let icon_spacing = spacing.icon_spacing;
44
45 let (galley, mut desired_size) = if text.is_empty() {
46 (None, vec2(icon_width, 0.0))
47 } else {
48 let total_extra = vec2(icon_width + icon_spacing, 0.0);
49
50 let wrap_width = ui.available_width() - total_extra.x;
51 let text = text.into_galley(ui, None, wrap_width, TextStyle::Button);
52
53 let mut desired_size = total_extra + text.size();
54 desired_size = desired_size.at_least(spacing.interact_size);
55
56 (Some(text), desired_size)
57 };
58
59 desired_size = desired_size.at_least(Vec2::splat(spacing.interact_size.y));
60 desired_size.y = desired_size.y.max(icon_width);
61 let (rect, response) = ui.allocate_exact_size(desired_size, Sense::click());
62
63 response.widget_info(|| {
64 WidgetInfo::selected(
65 WidgetType::RadioButton,
66 ui.is_enabled(),
67 checked,
68 galley.as_ref().map_or("", |x| x.text()),
69 )
70 });
71
72 if ui.is_rect_visible(rect) {
73 let visuals = ui.style().interact(&response);
75
76 let (small_icon_rect, big_icon_rect) = ui.spacing().icon_rectangles(rect);
77
78 let painter = ui.painter();
79
80 painter.add(epaint::CircleShape {
81 center: big_icon_rect.center(),
82 radius: big_icon_rect.width() / 2.0 + visuals.expansion,
83 fill: visuals.bg_fill,
84 stroke: visuals.bg_stroke,
85 });
86
87 if checked {
88 painter.add(epaint::CircleShape {
89 center: small_icon_rect.center(),
90 radius: small_icon_rect.width() / 3.0,
91 fill: visuals.fg_stroke.color, stroke: Default::default(),
94 });
95 }
96
97 if let Some(galley) = galley {
98 let text_pos = pos2(
99 rect.min.x + icon_width + icon_spacing,
100 rect.center().y - 0.5 * galley.size().y,
101 );
102 ui.painter().galley(text_pos, galley, visuals.text_color());
103 }
104 }
105
106 response
107 }
108}