radio.rs

 1use std::sync::Arc;
 2
 3use crate::prelude::*;
 4
 5#[derive(IntoElement)]
 6pub struct RadioWithLabel {
 7    id: ElementId,
 8    label: Label,
 9    selected: bool,
10    on_click: Arc<dyn Fn(&bool, &mut Window, &mut App) + 'static>,
11}
12
13impl RadioWithLabel {
14    pub fn new(
15        id: impl Into<ElementId>,
16        label: Label,
17        selected: bool,
18        on_click: impl Fn(&bool, &mut Window, &mut App) + 'static,
19    ) -> Self {
20        Self {
21            id: id.into(),
22            label,
23            selected,
24            on_click: Arc::new(on_click),
25        }
26    }
27}
28
29impl RenderOnce for RadioWithLabel {
30    fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
31        let inner_diameter = rems_from_px(6.);
32        let outer_diameter = rems_from_px(16.);
33        let border_width = rems_from_px(1.);
34        h_flex()
35            .id(self.id)
36            .gap(DynamicSpacing::Base08.rems(cx))
37            .group("")
38            .child(
39                div()
40                    .size(outer_diameter)
41                    .rounded(outer_diameter / 2.)
42                    .border_color(cx.theme().colors().border)
43                    .border(border_width)
44                    .group_hover("", |el| el.bg(cx.theme().colors().element_hover))
45                    .when(self.selected, |el| {
46                        el.child(
47                            div()
48                                .m((outer_diameter - inner_diameter) / 2. - border_width)
49                                .size(inner_diameter)
50                                .rounded(inner_diameter / 2.)
51                                .bg(cx.theme().colors().icon_accent),
52                        )
53                    }),
54            )
55            .child(self.label)
56            .on_click(move |_event, window, cx| {
57                (self.on_click)(&true, window, cx);
58            })
59    }
60}