use ribir_core::prelude::*;
use crate::prelude::*;
class_names! {
RADIO_SELECTED,
RADIO_UNSELECTED,
RADIO,
RADIO_SELECTED_ICON,
RADIO_UNSELECTED_ICON
}
#[declare]
pub struct Radio {
#[declare(default)]
pub selected: bool,
#[declare(custom, default = Box::new(()) as Box<dyn Any>)]
pub value: Box<dyn Any>,
}
impl RadioDeclarer {
pub fn with_value<V: 'static>(&mut self, value: V) -> &mut Self {
self.value = Some(PipeValue::Value(Box::new(value)));
self
}
}
impl Radio {
fn radio_class_name(&self) -> ClassName {
if self.selected { RADIO_SELECTED } else { RADIO_UNSELECTED }
}
fn radio_icon_class_name(&self) -> ClassName {
if self.selected { RADIO_SELECTED_ICON } else { RADIO_UNSELECTED_ICON }
}
}
impl ComposeChild<'static> for Radio {
type Child = Option<PositionChild<TextValue>>;
fn compose_child(this: impl StateWriter<Value = Self>, child: Self::Child) -> Widget<'static> {
fat_obj! {
on_action: move |_| $write(this).selected = true,
@ {
let icon = @Icon {
class: class_list![
distinct_pipe!($read(this).radio_class_name()),
RADIO
],
@Void { class: distinct_pipe!($read(this).radio_icon_class_name()) }
};
icon_with_label(icon.into_widget(), child)
}
}
.into_widget()
}
}
#[cfg(test)]
mod tests {
use ribir_core::test_helper::*;
use ribir_dev_helper::*;
use super::*;
widget_image_tests!(
radio_widget,
WidgetTester::new(self::column! {
@Radio { selected: true }
@Radio {
selected: false,
@ { "Default label position." }
}
@Radio {
selected: true,
@Leading::new("Leading label position.")
}
@Radio {
selected: false,
@Trailing::new("Trailing label position.")
}
})
.with_wnd_size(Size::new(200., 256.))
.with_comparison(0.002)
);
}