summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2024-03-06 11:24:51 +0100
committerLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2024-03-06 11:24:51 +0100
commit40af65c3aa4a96281db8f642cfa1641479314d27 (patch)
tree6cd41fd0bd3804a185f94b1f7d79d42f0f0537b2
parenta43afc791e8f78b03d802f980a10f32dc932f0b2 (diff)
downloadiced-40af65c3aa4a96281db8f642cfa1641479314d27.tar.gz
iced-40af65c3aa4a96281db8f642cfa1641479314d27.tar.bz2
iced-40af65c3aa4a96281db8f642cfa1641479314d27.zip
Simplify theming for `Toggler` widget
-rw-r--r--style/src/lib.rs1
-rw-r--r--style/src/theme.rs70
-rw-r--r--style/src/toggler.rs35
-rw-r--r--widget/src/helpers.rs2
-rw-r--r--widget/src/toggler.rs131
5 files changed, 112 insertions, 127 deletions
diff --git a/style/src/lib.rs b/style/src/lib.rs
index 09a943aa..3e439f07 100644
--- a/style/src/lib.rs
+++ b/style/src/lib.rs
@@ -23,6 +23,5 @@ pub mod pick_list;
pub mod svg;
pub mod text_editor;
pub mod theme;
-pub mod toggler;
pub use theme::Theme;
diff --git a/style/src/theme.rs b/style/src/theme.rs
index a7a95ab0..993e3d68 100644
--- a/style/src/theme.rs
+++ b/style/src/theme.rs
@@ -10,7 +10,6 @@ use crate::pane_grid;
use crate::pick_list;
use crate::svg;
use crate::text_editor;
-use crate::toggler;
use crate::core::{Background, Border, Color};
@@ -378,75 +377,6 @@ impl pick_list::StyleSheet for Theme {
}
}
-/// The style of a toggler.
-#[derive(Default)]
-pub enum Toggler {
- /// The default style.
- #[default]
- Default,
- /// A custom style.
- Custom(Box<dyn toggler::StyleSheet<Style = Theme>>),
-}
-
-impl toggler::StyleSheet for Theme {
- type Style = Toggler;
-
- fn active(
- &self,
- style: &Self::Style,
- is_active: bool,
- ) -> toggler::Appearance {
- match style {
- Toggler::Default => {
- let palette = self.extended_palette();
-
- toggler::Appearance {
- background: if is_active {
- palette.primary.strong.color
- } else {
- palette.background.strong.color
- },
- background_border_width: 0.0,
- background_border_color: Color::TRANSPARENT,
- foreground: if is_active {
- palette.primary.strong.text
- } else {
- palette.background.base.color
- },
- foreground_border_width: 0.0,
- foreground_border_color: Color::TRANSPARENT,
- }
- }
- Toggler::Custom(custom) => custom.active(self, is_active),
- }
- }
-
- fn hovered(
- &self,
- style: &Self::Style,
- is_active: bool,
- ) -> toggler::Appearance {
- match style {
- Toggler::Default => {
- let palette = self.extended_palette();
-
- toggler::Appearance {
- foreground: if is_active {
- Color {
- a: 0.5,
- ..palette.primary.strong.text
- }
- } else {
- palette.background.weak.color
- },
- ..self.active(style, is_active)
- }
- }
- Toggler::Custom(custom) => custom.hovered(self, is_active),
- }
- }
-}
-
/// The style of a pane grid.
#[derive(Default)]
pub enum PaneGrid {
diff --git a/style/src/toggler.rs b/style/src/toggler.rs
deleted file mode 100644
index 731e87ce..00000000
--- a/style/src/toggler.rs
+++ /dev/null
@@ -1,35 +0,0 @@
-//! Change the appearance of a toggler.
-use iced_core::Color;
-
-/// The appearance of a toggler.
-#[derive(Debug, Clone, Copy)]
-pub struct Appearance {
- /// The background [`Color`] of the toggler.
- pub background: Color,
- /// The width of the background border of the toggler.
- pub background_border_width: f32,
- /// The [`Color`] of the background border of the toggler.
- pub background_border_color: Color,
- /// The foreground [`Color`] of the toggler.
- pub foreground: Color,
- /// The width of the foreground border of the toggler.
- pub foreground_border_width: f32,
- /// The [`Color`] of the foreground border of the toggler.
- pub foreground_border_color: Color,
-}
-
-/// A set of rules that dictate the style of a toggler.
-pub trait StyleSheet {
- /// The supported style of the [`StyleSheet`].
- type Style: Default;
-
- /// Returns the active [`Appearance`] of the toggler for the provided [`Style`].
- ///
- /// [`Style`]: Self::Style
- fn active(&self, style: &Self::Style, is_active: bool) -> Appearance;
-
- /// Returns the hovered [`Appearance`] of the toggler for the provided [`Style`].
- ///
- /// [`Style`]: Self::Style
- fn hovered(&self, style: &Self::Style, is_active: bool) -> Appearance;
-}
diff --git a/widget/src/helpers.rs b/widget/src/helpers.rs
index 33c9f300..8cb03691 100644
--- a/widget/src/helpers.rs
+++ b/widget/src/helpers.rs
@@ -196,7 +196,7 @@ pub fn toggler<'a, Message, Theme, Renderer>(
) -> Toggler<'a, Message, Theme, Renderer>
where
Renderer: core::text::Renderer,
- Theme: toggler::StyleSheet,
+ Theme: toggler::Style,
{
Toggler::new(label, is_checked, f)
}
diff --git a/widget/src/toggler.rs b/widget/src/toggler.rs
index 4e3925ba..1f19212d 100644
--- a/widget/src/toggler.rs
+++ b/widget/src/toggler.rs
@@ -9,11 +9,10 @@ use crate::core::touch;
use crate::core::widget;
use crate::core::widget::tree::{self, Tree};
use crate::core::{
- Border, Clipboard, Element, Event, Layout, Length, Pixels, Rectangle,
- Shell, Size, Widget,
+ Border, Clipboard, Color, Element, Event, Layout, Length, Pixels,
+ Rectangle, Shell, Size, Widget,
};
-
-pub use crate::style::toggler::{Appearance, StyleSheet};
+use crate::style::Theme;
/// A toggler widget.
///
@@ -38,7 +37,6 @@ pub struct Toggler<
Theme = crate::Theme,
Renderer = crate::Renderer,
> where
- Theme: StyleSheet,
Renderer: text::Renderer,
{
is_toggled: bool,
@@ -52,12 +50,11 @@ pub struct Toggler<
text_shaping: text::Shaping,
spacing: f32,
font: Option<Renderer::Font>,
- style: Theme::Style,
+ style: fn(&Theme, Status) -> Appearance,
}
impl<'a, Message, Theme, Renderer> Toggler<'a, Message, Theme, Renderer>
where
- Theme: StyleSheet,
Renderer: text::Renderer,
{
/// The default size of a [`Toggler`].
@@ -77,6 +74,7 @@ where
f: F,
) -> Self
where
+ Theme: Style,
F: 'a + Fn(bool) -> Message,
{
Toggler {
@@ -91,7 +89,7 @@ where
text_shaping: text::Shaping::Basic,
spacing: Self::DEFAULT_SIZE / 2.0,
font: None,
- style: Default::default(),
+ style: Theme::style(),
}
}
@@ -149,7 +147,7 @@ where
}
/// Sets the style of the [`Toggler`].
- pub fn style(mut self, style: impl Into<Theme::Style>) -> Self {
+ pub fn style(mut self, style: fn(&Theme, Status) -> Appearance) -> Self {
self.style = style.into();
self
}
@@ -158,7 +156,6 @@ where
impl<'a, Message, Theme, Renderer> Widget<Message, Theme, Renderer>
for Toggler<'a, Message, Theme, Renderer>
where
- Theme: StyleSheet + crate::text::StyleSheet,
Renderer: text::Renderer,
{
fn tag(&self) -> tree::Tag {
@@ -294,12 +291,18 @@ where
let bounds = toggler_layout.bounds();
let is_mouse_over = cursor.is_over(layout.bounds());
- let style = if is_mouse_over {
- theme.hovered(&self.style, self.is_toggled)
+ let status = if is_mouse_over {
+ Status::Hovered {
+ is_toggled: self.is_toggled,
+ }
} else {
- theme.active(&self.style, self.is_toggled)
+ Status::Active {
+ is_toggled: self.is_toggled,
+ }
};
+ let appearance = (self.style)(theme, status);
+
let border_radius = bounds.height / BORDER_RADIUS_RATIO;
let space = SPACE_RATIO * bounds.height;
@@ -315,12 +318,12 @@ where
bounds: toggler_background_bounds,
border: Border {
radius: border_radius.into(),
- width: style.background_border_width,
- color: style.background_border_color,
+ width: appearance.background_border_width,
+ color: appearance.background_border_color,
},
..renderer::Quad::default()
},
- style.background,
+ appearance.background,
);
let toggler_foreground_bounds = Rectangle {
@@ -340,12 +343,12 @@ where
bounds: toggler_foreground_bounds,
border: Border {
radius: border_radius.into(),
- width: style.foreground_border_width,
- color: style.foreground_border_color,
+ width: appearance.foreground_border_width,
+ color: appearance.foreground_border_color,
},
..renderer::Quad::default()
},
- style.foreground,
+ appearance.foreground,
);
}
}
@@ -354,7 +357,7 @@ impl<'a, Message, Theme, Renderer> From<Toggler<'a, Message, Theme, Renderer>>
for Element<'a, Message, Theme, Renderer>
where
Message: 'a,
- Theme: StyleSheet + crate::text::StyleSheet + 'a,
+ Theme: 'a,
Renderer: text::Renderer + 'a,
{
fn from(
@@ -363,3 +366,91 @@ where
Element::new(toggler)
}
}
+
+/// The possible status of a [`Toggler`].
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum Status {
+ /// The [`Toggler`] can be interacted with.
+ Active {
+ /// Indicates whether the [`Toggler`] is toggled.
+ is_toggled: bool,
+ },
+ /// The [`Toggler`] is being hovered.
+ Hovered {
+ /// Indicates whether the [`Toggler`] is toggled.
+ is_toggled: bool,
+ },
+}
+
+/// The appearance of a toggler.
+#[derive(Debug, Clone, Copy)]
+pub struct Appearance {
+ /// The background [`Color`] of the toggler.
+ pub background: Color,
+ /// The width of the background border of the toggler.
+ pub background_border_width: f32,
+ /// The [`Color`] of the background border of the toggler.
+ pub background_border_color: Color,
+ /// The foreground [`Color`] of the toggler.
+ pub foreground: Color,
+ /// The width of the foreground border of the toggler.
+ pub foreground_border_width: f32,
+ /// The [`Color`] of the foreground border of the toggler.
+ pub foreground_border_color: Color,
+}
+
+/// The definiton of the default style of a [`Toggler`].
+pub trait Style {
+ /// Returns the default style of a [`Toggler`].
+ fn style() -> fn(&Self, Status) -> Appearance;
+}
+
+impl Style for Theme {
+ fn style() -> fn(&Self, Status) -> Appearance {
+ default
+ }
+}
+
+/// The default style of a [`Toggler`].
+pub fn default(theme: &Theme, status: Status) -> Appearance {
+ let palette = theme.extended_palette();
+
+ let background = match status {
+ Status::Active { is_toggled } | Status::Hovered { is_toggled } => {
+ if is_toggled {
+ palette.primary.strong.color
+ } else {
+ palette.background.strong.color
+ }
+ }
+ };
+
+ let foreground = match status {
+ Status::Active { is_toggled } => {
+ if is_toggled {
+ palette.primary.strong.text
+ } else {
+ palette.background.base.color
+ }
+ }
+ Status::Hovered { is_toggled } => {
+ if is_toggled {
+ Color {
+ a: 0.5,
+ ..palette.primary.strong.text
+ }
+ } else {
+ palette.background.weak.color
+ }
+ }
+ };
+
+ Appearance {
+ background,
+ foreground,
+ foreground_border_width: 0.0,
+ foreground_border_color: Color::TRANSPARENT,
+ background_border_width: 0.0,
+ background_border_color: Color::TRANSPARENT,
+ }
+}