Implement theme styling for Radio
This commit is contained in:
parent
d988d813d7
commit
28d09bfff1
10 changed files with 86 additions and 157 deletions
|
|
@ -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,
|
||||
))
|
||||
},
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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};
|
|||
///
|
||||
/// 
|
||||
#[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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
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 active(&self, style: Self::Style) -> Appearance;
|
||||
|
||||
fn hovered(&self, style: Self::Style) -> Appearance;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue