summaryrefslogtreecommitdiffstats
path: root/native/src/widget/radio.rs
diff options
context:
space:
mode:
Diffstat (limited to 'native/src/widget/radio.rs')
-rw-r--r--native/src/widget/radio.rs122
1 files changed, 84 insertions, 38 deletions
diff --git a/native/src/widget/radio.rs b/native/src/widget/radio.rs
index 46983db3..3a1dd386 100644
--- a/native/src/widget/radio.rs
+++ b/native/src/widget/radio.rs
@@ -1,9 +1,13 @@
//! Create choices using radio buttons.
+use crate::event::{self, Event};
+use crate::layout;
+use crate::mouse;
+use crate::row;
+use crate::text;
+use crate::touch::{self, Touch};
use crate::{
- input::{mouse, touch, ButtonState, Touch},
- layout, row, text, Align, Clipboard, Element, Event, Font, Hasher,
- HorizontalAlignment, Layout, Length, Point, Rectangle, Row, Text,
- VerticalAlignment, Widget,
+ Align, Clipboard, Element, Hasher, HorizontalAlignment, Layout, Length,
+ Point, Rectangle, Row, Text, VerticalAlignment, Widget,
};
use std::hash::Hash;
@@ -35,14 +39,22 @@ use std::hash::Hash;
///
/// ![Radio buttons drawn by `iced_wgpu`](https://github.com/hecrj/iced/blob/7760618fb112074bc40b148944521f312152012a/docs/images/radio.png?raw=true)
#[allow(missing_debug_implementations)]
-pub struct Radio<Message, Renderer: self::Renderer> {
+pub struct Radio<Message, Renderer: self::Renderer + text::Renderer> {
is_selected: bool,
on_click: Message,
label: String,
+ width: Length,
+ size: u16,
+ spacing: u16,
+ text_size: Option<u16>,
style: Renderer::Style,
}
-impl<Message, Renderer: self::Renderer> Radio<Message, Renderer> {
+impl<Message, Renderer: self::Renderer + text::Renderer>
+ Radio<Message, Renderer>
+where
+ Message: Clone,
+{
/// Creates a new [`Radio`] button.
///
/// It expects:
@@ -51,9 +63,12 @@ impl<Message, Renderer: self::Renderer> Radio<Message, Renderer> {
/// * the current selected value
/// * a function that will be called when the [`Radio`] is selected. It
/// receives the value of the radio and must produce a `Message`.
- ///
- /// [`Radio`]: struct.Radio.html
- pub fn new<F, V>(value: V, label: &str, selected: Option<V>, f: F) -> Self
+ pub fn new<F, V>(
+ value: V,
+ label: impl Into<String>,
+ selected: Option<V>,
+ f: F,
+ ) -> Self
where
V: Eq + Copy,
F: 'static + Fn(V) -> Message,
@@ -61,14 +76,40 @@ impl<Message, Renderer: self::Renderer> Radio<Message, Renderer> {
Radio {
is_selected: Some(value) == selected,
on_click: f(value),
- label: String::from(label),
+ label: label.into(),
+ width: Length::Shrink,
+ size: <Renderer as self::Renderer>::DEFAULT_SIZE,
+ spacing: Renderer::DEFAULT_SPACING, //15
+ text_size: None,
style: Renderer::Style::default(),
}
}
+ /// Sets the size of the [`Radio`] button.
+ pub fn size(mut self, size: u16) -> Self {
+ self.size = size;
+ self
+ }
+
+ /// Sets the width of the [`Radio`] button.
+ pub fn width(mut self, width: Length) -> Self {
+ self.width = width;
+ self
+ }
+
+ /// Sets the spacing between the [`Radio`] button and the text.
+ pub fn spacing(mut self, spacing: u16) -> Self {
+ self.spacing = spacing;
+ self
+ }
+
+ /// Sets the text size of the [`Radio`] button.
+ pub fn text_size(mut self, text_size: u16) -> Self {
+ self.text_size = Some(text_size);
+ self
+ }
+
/// Sets the style of the [`Radio`] button.
- ///
- /// [`Radio`]: struct.Radio.html
pub fn style(mut self, style: impl Into<Renderer::Style>) -> Self {
self.style = style.into();
self
@@ -77,11 +118,11 @@ impl<Message, Renderer: self::Renderer> Radio<Message, Renderer> {
impl<Message, Renderer> Widget<Message, Renderer> for Radio<Message, Renderer>
where
- Renderer: self::Renderer + text::Renderer + row::Renderer,
Message: Clone,
+ Renderer: self::Renderer + text::Renderer + row::Renderer,
{
fn width(&self) -> Length {
- Length::Fill
+ self.width
}
fn height(&self) -> Length {
@@ -93,18 +134,20 @@ where
renderer: &Renderer,
limits: &layout::Limits,
) -> layout::Node {
- let size = self::Renderer::default_size(renderer);
-
Row::<(), Renderer>::new()
- .width(Length::Fill)
- .spacing(15)
+ .width(self.width)
+ .spacing(self.spacing)
.align_items(Align::Center)
.push(
Row::new()
- .width(Length::Units(size as u16))
- .height(Length::Units(size as u16)),
+ .width(Length::Units(self.size))
+ .height(Length::Units(self.size)),
+ )
+ .push(
+ Text::new(&self.label)
+ .width(self.width)
+ .size(self.text_size.unwrap_or(renderer.default_size())),
)
- .push(Text::new(&self.label))
.layout(renderer, limits)
}
@@ -116,22 +159,23 @@ where
messages: &mut Vec<Message>,
_renderer: &Renderer,
_clipboard: Option<&dyn Clipboard>,
- ) {
+ ) -> event::Status {
match event {
- Event::Mouse(mouse::Event::Input {
- button: mouse::Button::Left,
- state: ButtonState::Pressed,
- })
+ Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
| Event::Touch(Touch {
phase: touch::Phase::Started,
..
}) => {
if layout.bounds().contains(cursor_position) {
messages.push(self.on_click.clone());
+
+ return event::Status::Captured;
}
}
_ => {}
}
+
+ event::Status::Ignored
}
fn draw(
@@ -140,6 +184,7 @@ where
defaults: &Renderer::Defaults,
layout: Layout<'_>,
cursor_position: Point,
+ _viewport: &Rectangle,
) -> Renderer::Output {
let bounds = layout.bounds();
let mut children = layout.children();
@@ -153,8 +198,8 @@ where
defaults,
label_layout.bounds(),
&self.label,
- <Renderer as text::Renderer>::DEFAULT_SIZE,
- Font::Default,
+ self.text_size.unwrap_or(renderer.default_size()),
+ Default::default(),
None,
HorizontalAlignment::Left,
VerticalAlignment::Center,
@@ -173,6 +218,9 @@ where
}
fn hash_layout(&self, state: &mut Hasher) {
+ struct Marker;
+ std::any::TypeId::of::<Marker>().hash(state);
+
self.label.hash(state);
}
}
@@ -182,16 +230,16 @@ where
/// Your [renderer] will need to implement this trait before being
/// able to use a [`Radio`] button in your user interface.
///
-/// [`Radio`]: struct.Radio.html
-/// [renderer]: ../../renderer/index.html
+/// [renderer]: crate::renderer
pub trait Renderer: crate::Renderer {
/// The style supported by this renderer.
type Style: Default;
- /// Returns the default size of a [`Radio`] button.
- ///
- /// [`Radio`]: struct.Radio.html
- fn default_size(&self) -> u32;
+ /// The default size of a [`Radio`] button.
+ const DEFAULT_SIZE: u16;
+
+ /// The default spacing of a [`Radio`] button.
+ const DEFAULT_SPACING: u16;
/// Draws a [`Radio`] button.
///
@@ -200,8 +248,6 @@ pub trait Renderer: crate::Renderer {
/// * whether the [`Radio`] is selected or not
/// * whether the mouse is over the [`Radio`] or not
/// * the drawn label of the [`Radio`]
- ///
- /// [`Radio`]: struct.Radio.html
fn draw(
&mut self,
bounds: Rectangle,
@@ -215,8 +261,8 @@ pub trait Renderer: crate::Renderer {
impl<'a, Message, Renderer> From<Radio<Message, Renderer>>
for Element<'a, Message, Renderer>
where
- Renderer: 'static + self::Renderer + row::Renderer + text::Renderer,
- Message: 'static + Clone,
+ Message: 'a + Clone,
+ Renderer: 'a + self::Renderer + row::Renderer + text::Renderer,
{
fn from(radio: Radio<Message, Renderer>) -> Element<'a, Message, Renderer> {
Element::new(radio)