summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2022-05-27 01:26:57 +0200
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2022-05-27 01:29:36 +0200
commit28d09bfff1dde55190986bab10d7aaeb0ceb49de (patch)
treedf38cec7242de571d94378cd736a05bc82a622c2
parentd988d813d77bc23147a179586206048e6cc42157 (diff)
downloadiced-28d09bfff1dde55190986bab10d7aaeb0ceb49de.tar.gz
iced-28d09bfff1dde55190986bab10d7aaeb0ceb49de.tar.bz2
iced-28d09bfff1dde55190986bab10d7aaeb0ceb49de.zip
Implement theme styling for `Radio`
-rw-r--r--examples/scrollable/src/main.rs15
-rw-r--r--examples/scrollable/src/style.rs40
-rw-r--r--examples/styling/src/main.rs51
-rw-r--r--native/src/widget/radio.rs39
-rw-r--r--pure/src/helpers.rs5
-rw-r--r--pure/src/widget/radio.rs9
-rw-r--r--src/pure/widget.rs6
-rw-r--r--src/widget.rs6
-rw-r--r--style/src/radio.rs42
-rw-r--r--style/src/theme.rs28
10 files changed, 85 insertions, 156 deletions
diff --git a/examples/scrollable/src/main.rs b/examples/scrollable/src/main.rs
index 8e027504..e49aa63b 100644
--- a/examples/scrollable/src/main.rs
+++ b/examples/scrollable/src/main.rs
@@ -69,15 +69,12 @@ impl Sandbox for ScrollableDemo {
let choose_theme = style::Theme::ALL.iter().fold(
Column::new().spacing(10).push(Text::new("Choose a theme:")),
|column, option| {
- column.push(
- Radio::new(
- *option,
- format!("{:?}", option),
- Some(*theme),
- Message::ThemeChanged,
- )
- .style(*theme),
- )
+ column.push(Radio::new(
+ *option,
+ format!("{:?}", option),
+ Some(*theme),
+ Message::ThemeChanged,
+ ))
},
);
diff --git a/examples/scrollable/src/style.rs b/examples/scrollable/src/style.rs
index 0ed38b00..0581a8c8 100644
--- a/examples/scrollable/src/style.rs
+++ b/examples/scrollable/src/style.rs
@@ -1,4 +1,4 @@
-use iced::{container, radio, rule, scrollable};
+use iced::{container, rule, scrollable};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Theme {
@@ -25,15 +25,6 @@ impl<'a> From<Theme> for Box<dyn container::StyleSheet + 'a> {
}
}
-impl<'a> From<Theme> for Box<dyn radio::StyleSheet + 'a> {
- fn from(theme: Theme) -> Self {
- match theme {
- Theme::Light => Default::default(),
- Theme::Dark => dark::Radio.into(),
- }
- }
-}
-
impl<'a> From<Theme> for Box<dyn scrollable::StyleSheet + 'a> {
fn from(theme: Theme) -> Self {
match theme {
@@ -53,7 +44,7 @@ impl From<Theme> for Box<dyn rule::StyleSheet> {
}
mod dark {
- use iced::{container, radio, rule, scrollable, Color};
+ use iced::{container, rule, scrollable, Color};
const BACKGROUND: Color = Color::from_rgb(
0x36 as f32 / 255.0,
@@ -73,12 +64,6 @@ mod dark {
0xE9 as f32 / 255.0,
);
- const ACTIVE: Color = Color::from_rgb(
- 0x72 as f32 / 255.0,
- 0x89 as f32 / 255.0,
- 0xDA as f32 / 255.0,
- );
-
const SCROLLBAR: Color = Color::from_rgb(
0x2E as f32 / 255.0,
0x33 as f32 / 255.0,
@@ -107,27 +92,6 @@ mod dark {
}
}
- pub struct Radio;
-
- impl radio::StyleSheet for Radio {
- fn active(&self) -> radio::Style {
- radio::Style {
- background: SURFACE.into(),
- dot_color: ACTIVE,
- border_width: 1.0,
- border_color: ACTIVE,
- text_color: None,
- }
- }
-
- fn hovered(&self) -> radio::Style {
- radio::Style {
- background: Color { a: 0.5, ..SURFACE }.into(),
- ..self.active()
- }
- }
- }
-
pub struct Scrollable;
impl scrollable::StyleSheet for Scrollable {
diff --git a/examples/styling/src/main.rs b/examples/styling/src/main.rs
index 82876cb4..27b3ead4 100644
--- a/examples/styling/src/main.rs
+++ b/examples/styling/src/main.rs
@@ -61,15 +61,12 @@ impl Sandbox for Styling {
let choose_theme = style::Theme::ALL.iter().fold(
Column::new().spacing(10).push(Text::new("Choose a theme:")),
|column, theme| {
- column.push(
- Radio::new(
- *theme,
- format!("{:?}", theme),
- Some(self.theme),
- Message::ThemeChanged,
- )
- .style(self.theme),
- )
+ column.push(Radio::new(
+ *theme,
+ format!("{:?}", theme),
+ Some(self.theme),
+ Message::ThemeChanged,
+ ))
},
);
@@ -158,7 +155,7 @@ impl Sandbox for Styling {
mod style {
use iced::{
- checkbox, container, progress_bar, radio, rule, scrollable, text_input,
+ checkbox, container, progress_bar, rule, scrollable, text_input,
toggler,
};
@@ -187,15 +184,6 @@ mod style {
}
}
- impl<'a> From<Theme> for Box<dyn radio::StyleSheet + 'a> {
- fn from(theme: Theme) -> Self {
- match theme {
- Theme::Light => Default::default(),
- Theme::Dark => dark::Radio.into(),
- }
- }
- }
-
impl<'a> From<Theme> for Box<dyn text_input::StyleSheet + 'a> {
fn from(theme: Theme) -> Self {
match theme {
@@ -252,8 +240,8 @@ mod style {
mod dark {
use iced::{
- checkbox, container, progress_bar, radio, rule, scrollable,
- text_input, toggler, Color,
+ checkbox, container, progress_bar, rule, scrollable, text_input,
+ toggler, Color,
};
const SURFACE: Color = Color::from_rgb(
@@ -292,27 +280,6 @@ mod style {
}
}
- pub struct Radio;
-
- impl radio::StyleSheet for Radio {
- fn active(&self) -> radio::Style {
- radio::Style {
- background: SURFACE.into(),
- dot_color: ACTIVE,
- border_width: 1.0,
- border_color: ACTIVE,
- text_color: None,
- }
- }
-
- fn hovered(&self) -> radio::Style {
- radio::Style {
- background: Color { a: 0.5, ..SURFACE }.into(),
- ..self.active()
- }
- }
- }
-
pub struct TextInput;
impl text_input::StyleSheet for TextInput {
diff --git a/native/src/widget/radio.rs b/native/src/widget/radio.rs
index 5d936eaf..de7e2735 100644
--- a/native/src/widget/radio.rs
+++ b/native/src/widget/radio.rs
@@ -12,14 +12,14 @@ use crate::{
Shell, Widget,
};
-pub use iced_style::radio::{Style, StyleSheet};
+pub use iced_style::radio::{Appearance, StyleSheet};
/// A circular button representing a choice.
///
/// # Example
/// ```
-/// # type Radio<'a, Message> =
-/// # iced_native::widget::Radio<'a, Message, iced_native::renderer::Null>;
+/// # type Radio<Message> =
+/// # iced_native::widget::Radio<Message, iced_native::renderer::Null>;
/// #
/// #[derive(Debug, Clone, Copy, PartialEq, Eq)]
/// pub enum Choice {
@@ -41,7 +41,11 @@ pub use iced_style::radio::{Style, StyleSheet};
///
/// ![Radio buttons drawn by `iced_wgpu`](https://github.com/iced-rs/iced/blob/7760618fb112074bc40b148944521f312152012a/docs/images/radio.png?raw=true)
#[allow(missing_debug_implementations)]
-pub struct Radio<'a, Message, Renderer: text::Renderer> {
+pub struct Radio<Message, Renderer>
+where
+ Renderer: text::Renderer,
+ Renderer::Theme: StyleSheet,
+{
is_selected: bool,
on_click: Message,
label: String,
@@ -50,12 +54,14 @@ pub struct Radio<'a, Message, Renderer: text::Renderer> {
spacing: u16,
text_size: Option<u16>,
font: Renderer::Font,
- style_sheet: Box<dyn StyleSheet + 'a>,
+ style: <Renderer::Theme as StyleSheet>::Style,
}
-impl<'a, Message, Renderer: text::Renderer> Radio<'a, Message, Renderer>
+impl<Message, Renderer> Radio<Message, Renderer>
where
Message: Clone,
+ Renderer: text::Renderer,
+ Renderer::Theme: StyleSheet,
{
/// The default size of a [`Radio`] button.
pub const DEFAULT_SIZE: u16 = 28;
@@ -90,7 +96,7 @@ where
spacing: Self::DEFAULT_SPACING, //15
text_size: None,
font: Default::default(),
- style_sheet: Default::default(),
+ style: Default::default(),
}
}
@@ -127,18 +133,18 @@ where
/// Sets the style of the [`Radio`] button.
pub fn style(
mut self,
- style_sheet: impl Into<Box<dyn StyleSheet + 'a>>,
+ style: impl Into<<Renderer::Theme as StyleSheet>::Style>,
) -> Self {
- self.style_sheet = style_sheet.into();
+ self.style = style.into();
self
}
}
-impl<'a, Message, Renderer> Widget<Message, Renderer>
- for Radio<'a, Message, Renderer>
+impl<Message, Renderer> Widget<Message, Renderer> for Radio<Message, Renderer>
where
Message: Clone,
Renderer: text::Renderer,
+ Renderer::Theme: StyleSheet,
{
fn width(&self) -> Length {
self.width
@@ -223,9 +229,9 @@ where
let mut children = layout.children();
let custom_style = if is_mouse_over {
- self.style_sheet.hovered()
+ theme.hovered(self.style)
} else {
- self.style_sheet.active()
+ theme.active(self.style)
};
{
@@ -281,15 +287,14 @@ where
}
}
-impl<'a, Message, Renderer> From<Radio<'a, Message, Renderer>>
+impl<'a, Message, Renderer> From<Radio<Message, Renderer>>
for Element<'a, Message, Renderer>
where
Message: 'a + Clone,
Renderer: 'a + text::Renderer,
+ Renderer::Theme: StyleSheet,
{
- fn from(
- radio: Radio<'a, Message, Renderer>,
- ) -> Element<'a, Message, Renderer> {
+ fn from(radio: Radio<Message, Renderer>) -> Element<'a, Message, Renderer> {
Element::new(radio)
}
}
diff --git a/pure/src/helpers.rs b/pure/src/helpers.rs
index d8741b09..159256ed 100644
--- a/pure/src/helpers.rs
+++ b/pure/src/helpers.rs
@@ -100,15 +100,16 @@ where
/// Creates a new [`Radio`].
///
/// [`Radio`]: widget::Radio
-pub fn radio<'a, Message, Renderer, V>(
+pub fn radio<Message, Renderer, V>(
label: impl Into<String>,
value: V,
selected: Option<V>,
on_click: impl FnOnce(V) -> Message,
-) -> widget::Radio<'a, Message, Renderer>
+) -> widget::Radio<Message, Renderer>
where
Message: Clone,
Renderer: iced_native::text::Renderer,
+ Renderer::Theme: widget::radio::StyleSheet,
V: Copy + Eq,
{
widget::Radio::new(value, label, selected, on_click)
diff --git a/pure/src/widget/radio.rs b/pure/src/widget/radio.rs
index c92c8dbc..9a8885e0 100644
--- a/pure/src/widget/radio.rs
+++ b/pure/src/widget/radio.rs
@@ -9,13 +9,13 @@ use iced_native::renderer;
use iced_native::text;
use iced_native::{Clipboard, Length, Point, Rectangle, Shell};
-pub use iced_native::widget::radio::{Radio, Style, StyleSheet};
+pub use iced_native::widget::radio::{Appearance, Radio, StyleSheet};
-impl<'a, Message, Renderer> Widget<Message, Renderer>
- for Radio<'a, Message, Renderer>
+impl<Message, Renderer> Widget<Message, Renderer> for Radio<Message, Renderer>
where
Message: Clone,
Renderer: text::Renderer,
+ Renderer::Theme: StyleSheet,
{
fn width(&self) -> Length {
<Self as iced_native::Widget<Message, Renderer>>::width(self)
@@ -96,10 +96,11 @@ where
}
impl<'a, Message, Renderer> Into<Element<'a, Message, Renderer>>
- for Radio<'a, Message, Renderer>
+ for Radio<Message, Renderer>
where
Message: 'a + Clone,
Renderer: text::Renderer + 'a,
+ Renderer::Theme: StyleSheet,
{
fn into(self) -> Element<'a, Message, Renderer> {
Element::new(self)
diff --git a/src/pure/widget.rs b/src/pure/widget.rs
index e91cf56a..04975c0d 100644
--- a/src/pure/widget.rs
+++ b/src/pure/widget.rs
@@ -90,11 +90,11 @@ pub mod pick_list {
pub mod radio {
//! Create choices using radio buttons.
- pub use iced_pure::widget::radio::{Style, StyleSheet};
+ pub use iced_pure::widget::radio::{Appearance, StyleSheet};
/// A circular button representing a choice.
- pub type Radio<'a, Message, Theme> =
- iced_pure::widget::Radio<'a, Message, crate::Renderer<Theme>>;
+ pub type Radio<Message, Theme> =
+ iced_pure::widget::Radio<Message, crate::Renderer<Theme>>;
}
pub mod scrollable {
diff --git a/src/widget.rs b/src/widget.rs
index 51a498b0..2f3600b6 100644
--- a/src/widget.rs
+++ b/src/widget.rs
@@ -106,11 +106,11 @@ pub mod pick_list {
pub mod radio {
//! Create choices using radio buttons.
- pub use iced_native::widget::radio::{Style, StyleSheet};
+ pub use iced_native::widget::radio::{Appearance, StyleSheet};
/// A circular button representing a choice.
- pub type Radio<'a, Message, Theme> =
- iced_native::widget::Radio<'a, Message, crate::Renderer<Theme>>;
+ pub type Radio<Message, Theme> =
+ iced_native::widget::Radio<Message, crate::Renderer<Theme>>;
}
pub mod scrollable {
diff --git a/style/src/radio.rs b/style/src/radio.rs
index dab76ad8..a4d4a83b 100644
--- a/style/src/radio.rs
+++ b/style/src/radio.rs
@@ -3,7 +3,7 @@ use iced_core::{Background, Color};
/// The appearance of a radio button.
#[derive(Debug, Clone, Copy)]
-pub struct Style {
+pub struct Appearance {
pub background: Background,
pub dot_color: Color,
pub border_width: f32,
@@ -13,43 +13,9 @@ pub struct Style {
/// A set of rules that dictate the style of a radio button.
pub trait StyleSheet {
- fn active(&self) -> Style;
+ type Style: Default + Copy;
- fn hovered(&self) -> Style;
-}
-
-struct Default;
-
-impl StyleSheet for Default {
- fn active(&self) -> Style {
- Style {
- background: Background::Color(Color::from_rgb(0.95, 0.95, 0.95)),
- dot_color: Color::from_rgb(0.3, 0.3, 0.3),
- border_width: 1.0,
- border_color: Color::from_rgb(0.6, 0.6, 0.6),
- text_color: None,
- }
- }
-
- fn hovered(&self) -> Style {
- Style {
- background: Background::Color(Color::from_rgb(0.90, 0.90, 0.90)),
- ..self.active()
- }
- }
-}
-
-impl<'a> std::default::Default for Box<dyn StyleSheet + 'a> {
- fn default() -> Self {
- Box::new(Default)
- }
-}
+ fn active(&self, style: Self::Style) -> Appearance;
-impl<'a, T> From<T> for Box<dyn StyleSheet + 'a>
-where
- T: StyleSheet + 'a,
-{
- fn from(style_sheet: T) -> Self {
- Box::new(style_sheet)
- }
+ fn hovered(&self, style: Self::Style) -> Appearance;
}
diff --git a/style/src/theme.rs b/style/src/theme.rs
index c9fae3c2..e3b151aa 100644
--- a/style/src/theme.rs
+++ b/style/src/theme.rs
@@ -4,6 +4,7 @@ pub use self::palette::Palette;
use crate::application;
use crate::button;
+use crate::radio;
use crate::slider;
use iced_core::{Background, Color};
@@ -165,3 +166,30 @@ impl slider::StyleSheet for Theme {
}
}
}
+
+impl radio::StyleSheet for Theme {
+ type Style = ();
+
+ fn active(&self, _style: Self::Style) -> radio::Appearance {
+ let palette = self.extended_palette();
+
+ radio::Appearance {
+ background: Color::TRANSPARENT.into(),
+ dot_color: palette.primary.strong.color.into(),
+ border_width: 1.0,
+ border_color: palette.primary.strong.color,
+ text_color: None,
+ }
+ }
+
+ fn hovered(&self, style: Self::Style) -> radio::Appearance {
+ let active = self.active(style);
+ let palette = self.extended_palette();
+
+ radio::Appearance {
+ dot_color: palette.primary.weak.text.into(),
+ background: palette.primary.weak.color.into(),
+ ..active
+ }
+ }
+}