Skip to content

Commit

Permalink
feat(widgets): 🎸 widget of radio button
Browse files Browse the repository at this point in the history
  • Loading branch information
wjian23 committed Nov 4, 2024
1 parent 9285517 commit a3de041
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Please only add new entries below the [Unreleased](#unreleased---releasedate) he

- **core**: Added the smooth widgets for transitioning the layout position and size. (#645 @M-Adoo)
- **widgets**: Added three widgets `FractionallyWidthBox`, `FractionallyHeightBox`, and `FractionallySizedBox` to enable fractional sizing of widgets. (#647 @M-Adoo)
- **widgets**: Add widget of radio button (#pr @wjian23)

### Fixed

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion themes/material/src/classes.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use ribir_core::prelude::Classes;

mod radio_cls;
mod scrollbar_cls;

pub fn initd_classes() -> Classes {
let mut classes = Classes::default();
scrollbar_cls::init(&mut classes);
radio_cls::init(&mut classes);
classes
}
64 changes: 64 additions & 0 deletions themes/material/src/classes/radio_cls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use ribir_core::prelude::*;
use ribir_widgets::prelude::*;

use crate::InteractiveLayer;

const TOTAL_SIZE: f32 = 40.;
const CONTAINER_SIZE: f32 = 20.;
const INDICATOR_SIZE: f32 = 10.;
const BORDER_SIZE: f32 = 2.;

pub(super) fn init(classes: &mut Classes) {
classes.insert(RADIO_SELECTED, |_w| {
fn_widget! {
@InteractiveLayer {
border_radii: Radius::all(TOTAL_SIZE / 2.),
color: Palette::of(ctx!()).primary(),
@Container {
size: Size::new(TOTAL_SIZE, TOTAL_SIZE),
cursor: CursorIcon::Pointer,
@Container {
h_align: HAlign::Center,
v_align: VAlign::Center,
size: Size::new(CONTAINER_SIZE, CONTAINER_SIZE),
border_radius: Radius::all(CONTAINER_SIZE / 2.),
border: Border::all(
BorderSide::new(BORDER_SIZE, Palette::of(ctx!()).primary().into())
),
@Container {
v_align: VAlign::Center,
h_align: HAlign::Center,
size: Size::new(INDICATOR_SIZE, INDICATOR_SIZE),
border_radius: Radius::all(INDICATOR_SIZE / 2.),
background: Palette::of(ctx!()).primary(),
}
}
}
}
}
.into_widget()
});

classes.insert(RADIO_UNSELECTED, |_w| {
fn_widget! {
@InteractiveLayer {
border_radii: Radius::all(TOTAL_SIZE / 2.),
color: Palette::of(ctx!()).primary(),
@Container {
cursor: CursorIcon::Pointer,
size: Size::new(TOTAL_SIZE, TOTAL_SIZE),
@Container {
h_align: HAlign::Center,
v_align: VAlign::Center,
size: Size::new(CONTAINER_SIZE, CONTAINER_SIZE),
border_radius: Radius::all(CONTAINER_SIZE / 2.),
border: Border::all(
BorderSide::new(BORDER_SIZE, Palette::of(ctx!()).on_surface_variant().into())
),
}
}
}
}
.into_widget()
});
}
5 changes: 3 additions & 2 deletions widgets/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub mod layout;
pub mod link;
pub mod lists;
pub mod path;
pub mod radio;
pub mod scrollbar;
pub mod tabs;
pub mod text;
Expand All @@ -19,7 +20,7 @@ pub mod transform_box;
pub mod prelude {
pub use super::{
avatar::*, buttons::*, checkbox::*, common_widget::*, divider::*, grid_view::*, icon::*,
input::*, label::*, layout::*, link::*, lists::*, path::*, scrollbar::*, tabs::*, text::*,
text_field::*, transform_box::*,
input::*, label::*, layout::*, link::*, lists::*, path::*, radio::*, scrollbar::*, tabs::*,
text::*, text_field::*, transform_box::*,
};
}
59 changes: 59 additions & 0 deletions widgets/src/radio.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use ribir_core::prelude::*;

class_names! {
#[doc = "Class name for the radio button when selected"]
RADIO_SELECTED,
#[doc = "Class name for the radio button when unselected"]
RADIO_UNSELECTED
}

#[derive(Declare)]
pub struct Radio {
pub checked: bool,
}

impl Compose for Radio {
fn compose(this: impl StateWriter<Value = Self>) -> Widget<'static> {
fn_widget! {
@ pipe!($this.checked).map(move |checked| {
fn_widget! {
let class = match checked {
true => RADIO_SELECTED,
false => RADIO_UNSELECTED,
};
@ Void { class: class }
}
})
}
.into_widget()
}
}

#[cfg(test)]
mod tests {
use ribir_core::test_helper::{Frame, MockMulti, WidgetTester};
use ribir_dev_helper::*;

use super::*;

fn radio_widget(_: &mut BuildCtx) -> Widget<'static> {
fn_widget! {
@MockMulti {
@Radio {
checked: false,
}
@Radio {
checked: true,
}
}
}
.into_widget()
}

widget_image_tests!(
radio_widget,
WidgetTester::new(radio_widget)
.with_wnd_size(Size::new(150., 80.))
.with_comparison(0.002)
);
}

0 comments on commit a3de041

Please sign in to comment.