radio.rs

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