summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2022-11-09 04:05:31 +0100
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2022-11-09 04:05:31 +0100
commit18fb74f20092b2703a90afdb01f39754445998da (patch)
treef178b11be114717059c36248c45f8a005dbe5a38
parent8102f96f12e6cb22dd2a23accea2c70490c8c532 (diff)
downloadiced-18fb74f20092b2703a90afdb01f39754445998da.tar.gz
iced-18fb74f20092b2703a90afdb01f39754445998da.tar.bz2
iced-18fb74f20092b2703a90afdb01f39754445998da.zip
Introduce `Custom` variants for every style in the built-in `Theme`
-rw-r--r--examples/solar_system/src/main.rs12
-rw-r--r--native/src/overlay/menu.rs6
-rw-r--r--native/src/widget/button.rs4
-rw-r--r--native/src/widget/checkbox.rs4
-rw-r--r--native/src/widget/container.rs2
-rw-r--r--native/src/widget/helpers.rs9
-rw-r--r--native/src/widget/pane_grid.rs4
-rw-r--r--native/src/widget/pane_grid/content.rs2
-rw-r--r--native/src/widget/pane_grid/title_bar.rs2
-rw-r--r--native/src/widget/pick_list.rs36
-rw-r--r--native/src/widget/progress_bar.rs2
-rw-r--r--native/src/widget/radio.rs4
-rw-r--r--native/src/widget/rule.rs2
-rw-r--r--native/src/widget/scrollable.rs4
-rw-r--r--native/src/widget/slider.rs10
-rw-r--r--native/src/widget/text_input.rs6
-rw-r--r--native/src/widget/toggler.rs4
-rw-r--r--native/src/widget/tooltip.rs4
-rw-r--r--style/src/application.rs4
-rw-r--r--style/src/button.rs10
-rw-r--r--style/src/checkbox.rs6
-rw-r--r--style/src/container.rs4
-rw-r--r--style/src/menu.rs4
-rw-r--r--style/src/pane_grid.rs6
-rw-r--r--style/src/pick_list.rs15
-rw-r--r--style/src/progress_bar.rs4
-rw-r--r--style/src/radio.rs6
-rw-r--r--style/src/rule.rs4
-rw-r--r--style/src/scrollable.rs8
-rw-r--r--style/src/slider.rs8
-rw-r--r--style/src/text_input.rs14
-rw-r--r--style/src/theme.rs642
-rw-r--r--style/src/toggler.rs6
-rw-r--r--winit/src/application/state.rs4
34 files changed, 576 insertions, 286 deletions
diff --git a/examples/solar_system/src/main.rs b/examples/solar_system/src/main.rs
index 56787a99..9e303576 100644
--- a/examples/solar_system/src/main.rs
+++ b/examples/solar_system/src/main.rs
@@ -79,10 +79,14 @@ impl Application for SolarSystem {
}
fn style(&self) -> theme::Application {
- theme::Application::Custom(|_theme| application::Appearance {
- background_color: Color::BLACK,
- text_color: Color::WHITE,
- })
+ fn dark_background(_theme: &Theme) -> application::Appearance {
+ application::Appearance {
+ background_color: Color::BLACK,
+ text_color: Color::WHITE,
+ }
+ }
+
+ theme::Application::from(dark_background as fn(&Theme) -> _)
}
fn subscription(&self) -> Subscription<Message> {
diff --git a/native/src/overlay/menu.rs b/native/src/overlay/menu.rs
index 08135872..3b55eba1 100644
--- a/native/src/overlay/menu.rs
+++ b/native/src/overlay/menu.rs
@@ -178,7 +178,7 @@ where
font,
text_size,
padding,
- style,
+ style: style.clone(),
}));
state.tree.diff(&container as &dyn Widget<_, _>);
@@ -288,7 +288,7 @@ where
layout: Layout<'_>,
cursor_position: Point,
) {
- let appearance = theme.appearance(self.style);
+ let appearance = theme.appearance(&self.style);
let bounds = layout.bounds();
renderer.fill_quad(
@@ -460,7 +460,7 @@ where
_cursor_position: Point,
viewport: &Rectangle,
) {
- let appearance = theme.appearance(self.style);
+ let appearance = theme.appearance(&self.style);
let bounds = layout.bounds();
let text_size =
diff --git a/native/src/widget/button.rs b/native/src/widget/button.rs
index 1582188b..fa5da24b 100644
--- a/native/src/widget/button.rs
+++ b/native/src/widget/button.rs
@@ -231,7 +231,7 @@ where
cursor_position,
self.on_press.is_some(),
theme,
- self.style,
+ &self.style,
|| tree.state.downcast_ref::<State>(),
);
@@ -361,7 +361,7 @@ pub fn draw<'a, Renderer: crate::Renderer>(
style_sheet: &dyn StyleSheet<
Style = <Renderer::Theme as StyleSheet>::Style,
>,
- style: <Renderer::Theme as StyleSheet>::Style,
+ style: &<Renderer::Theme as StyleSheet>::Style,
state: impl FnOnce() -> &'a State,
) -> Appearance
where
diff --git a/native/src/widget/checkbox.rs b/native/src/widget/checkbox.rs
index dc3c0bd0..77d639a9 100644
--- a/native/src/widget/checkbox.rs
+++ b/native/src/widget/checkbox.rs
@@ -224,9 +224,9 @@ where
let mut children = layout.children();
let custom_style = if is_mouse_over {
- theme.hovered(self.style, self.is_checked)
+ theme.hovered(&self.style, self.is_checked)
} else {
- theme.active(self.style, self.is_checked)
+ theme.active(&self.style, self.is_checked)
};
{
diff --git a/native/src/widget/container.rs b/native/src/widget/container.rs
index 10a80b58..16537c50 100644
--- a/native/src/widget/container.rs
+++ b/native/src/widget/container.rs
@@ -228,7 +228,7 @@ where
cursor_position: Point,
viewport: &Rectangle,
) {
- let style = theme.appearance(self.style);
+ let style = theme.appearance(&self.style);
draw_background(renderer, &style, layout.bounds());
diff --git a/native/src/widget/helpers.rs b/native/src/widget/helpers.rs
index 79751878..fe6fb815 100644
--- a/native/src/widget/helpers.rs
+++ b/native/src/widget/helpers.rs
@@ -1,4 +1,5 @@
//! Helper functions to create pure widgets.
+use crate::overlay;
use crate::widget;
use crate::{Element, Length};
@@ -84,6 +85,7 @@ pub fn button<'a, Message, Renderer>(
where
Renderer: crate::Renderer,
Renderer::Theme: widget::button::StyleSheet,
+ <Renderer::Theme as widget::button::StyleSheet>::Style: Default,
{
widget::Button::new(content)
}
@@ -208,7 +210,12 @@ where
T: ToString + Eq + 'static,
[T]: ToOwned<Owned = Vec<T>>,
Renderer: crate::text::Renderer,
- Renderer::Theme: widget::pick_list::StyleSheet,
+ Renderer::Theme: widget::pick_list::StyleSheet
+ + widget::scrollable::StyleSheet
+ + overlay::menu::StyleSheet
+ + widget::container::StyleSheet,
+ <Renderer::Theme as overlay::menu::StyleSheet>::Style:
+ From<<Renderer::Theme as widget::pick_list::StyleSheet>::Style>,
{
widget::PickList::new(options, selected, on_selected)
}
diff --git a/native/src/widget/pane_grid.rs b/native/src/widget/pane_grid.rs
index fd771f8b..ff902aa7 100644
--- a/native/src/widget/pane_grid.rs
+++ b/native/src/widget/pane_grid.rs
@@ -401,7 +401,7 @@ where
viewport,
self.spacing,
self.on_resize.as_ref().map(|(leeway, _)| *leeway),
- self.style,
+ &self.style,
self.contents
.iter()
.zip(&tree.children)
@@ -727,7 +727,7 @@ pub fn draw<Renderer, T>(
viewport: &Rectangle,
spacing: u16,
resize_leeway: Option<u16>,
- style: <Renderer::Theme as StyleSheet>::Style,
+ style: &<Renderer::Theme as StyleSheet>::Style,
contents: impl Iterator<Item = (Pane, T)>,
draw_pane: impl Fn(
T,
diff --git a/native/src/widget/pane_grid/content.rs b/native/src/widget/pane_grid/content.rs
index c236d820..405dc0b2 100644
--- a/native/src/widget/pane_grid/content.rs
+++ b/native/src/widget/pane_grid/content.rs
@@ -103,7 +103,7 @@ where
let bounds = layout.bounds();
{
- let style = theme.appearance(self.style);
+ let style = theme.appearance(&self.style);
container::draw_background(renderer, &style, bounds);
}
diff --git a/native/src/widget/pane_grid/title_bar.rs b/native/src/widget/pane_grid/title_bar.rs
index eb85f924..783a14c3 100644
--- a/native/src/widget/pane_grid/title_bar.rs
+++ b/native/src/widget/pane_grid/title_bar.rs
@@ -129,7 +129,7 @@ where
use container::StyleSheet;
let bounds = layout.bounds();
- let style = theme.appearance(self.style);
+ let style = theme.appearance(&self.style);
let inherited_style = renderer::Style {
text_color: style.text_color.unwrap_or(inherited_style.text_color),
};
diff --git a/native/src/widget/pick_list.rs b/native/src/widget/pick_list.rs
index 896f5b35..a6459cd6 100644
--- a/native/src/widget/pick_list.rs
+++ b/native/src/widget/pick_list.rs
@@ -9,6 +9,8 @@ use crate::overlay::menu::{self, Menu};
use crate::renderer;
use crate::text::{self, Text};
use crate::touch;
+use crate::widget::container;
+use crate::widget::scrollable;
use crate::widget::tree::{self, Tree};
use crate::{
Clipboard, Element, Layout, Length, Padding, Point, Rectangle, Shell, Size,
@@ -42,7 +44,12 @@ where
T: ToString + Eq,
[T]: ToOwned<Owned = Vec<T>>,
Renderer: text::Renderer,
- Renderer::Theme: StyleSheet,
+ Renderer::Theme: StyleSheet
+ + scrollable::StyleSheet
+ + menu::StyleSheet
+ + container::StyleSheet,
+ <Renderer::Theme as menu::StyleSheet>::Style:
+ From<<Renderer::Theme as StyleSheet>::Style>,
{
/// The default padding of a [`PickList`].
pub const DEFAULT_PADDING: Padding = Padding::new(5);
@@ -114,7 +121,12 @@ where
[T]: ToOwned<Owned = Vec<T>>,
Message: 'a,
Renderer: text::Renderer + 'a,
- Renderer::Theme: StyleSheet,
+ Renderer::Theme: StyleSheet
+ + scrollable::StyleSheet
+ + menu::StyleSheet
+ + container::StyleSheet,
+ <Renderer::Theme as menu::StyleSheet>::Style:
+ From<<Renderer::Theme as StyleSheet>::Style>,
{
fn tag(&self) -> tree::Tag {
tree::Tag::of::<State<T>>()
@@ -202,7 +214,7 @@ where
&self.font,
self.placeholder.as_deref(),
self.selected.as_ref(),
- self.style,
+ &self.style,
)
}
@@ -221,7 +233,7 @@ where
self.text_size,
self.font.clone(),
&self.options,
- self.style,
+ self.style.clone(),
)
}
}
@@ -233,7 +245,12 @@ where
[T]: ToOwned<Owned = Vec<T>>,
Message: 'a,
Renderer: text::Renderer + 'a,
- Renderer::Theme: StyleSheet,
+ Renderer::Theme: StyleSheet
+ + scrollable::StyleSheet
+ + menu::StyleSheet
+ + container::StyleSheet,
+ <Renderer::Theme as menu::StyleSheet>::Style:
+ From<<Renderer::Theme as StyleSheet>::Style>,
{
fn from(pick_list: PickList<'a, T, Message, Renderer>) -> Self {
Self::new(pick_list)
@@ -456,7 +473,12 @@ where
T: Clone + ToString,
Message: 'a,
Renderer: text::Renderer + 'a,
- Renderer::Theme: StyleSheet,
+ Renderer::Theme: StyleSheet
+ + scrollable::StyleSheet
+ + menu::StyleSheet
+ + container::StyleSheet,
+ <Renderer::Theme as menu::StyleSheet>::Style:
+ From<<Renderer::Theme as StyleSheet>::Style>,
{
if state.is_open {
let bounds = layout.bounds();
@@ -493,7 +515,7 @@ pub fn draw<T, Renderer>(
font: &Renderer::Font,
placeholder: Option<&str>,
selected: Option<&T>,
- style: <Renderer::Theme as StyleSheet>::Style,
+ style: &<Renderer::Theme as StyleSheet>::Style,
) where
Renderer: text::Renderer,
Renderer::Theme: StyleSheet,
diff --git a/native/src/widget/progress_bar.rs b/native/src/widget/progress_bar.rs
index 8a945433..b053d959 100644
--- a/native/src/widget/progress_bar.rs
+++ b/native/src/widget/progress_bar.rs
@@ -124,7 +124,7 @@ where
/ (range_end - range_start)
};
- let style = theme.appearance(self.style);
+ let style = theme.appearance(&self.style);
renderer.fill_quad(
renderer::Quad {
diff --git a/native/src/widget/radio.rs b/native/src/widget/radio.rs
index cb83f745..743689c7 100644
--- a/native/src/widget/radio.rs
+++ b/native/src/widget/radio.rs
@@ -230,9 +230,9 @@ where
let mut children = layout.children();
let custom_style = if is_mouse_over {
- theme.hovered(self.style, self.is_selected)
+ theme.hovered(&self.style, self.is_selected)
} else {
- theme.active(self.style, self.is_selected)
+ theme.active(&self.style, self.is_selected)
};
{
diff --git a/native/src/widget/rule.rs b/native/src/widget/rule.rs
index 56f8c80d..e44d8d99 100644
--- a/native/src/widget/rule.rs
+++ b/native/src/widget/rule.rs
@@ -88,7 +88,7 @@ where
_viewport: &Rectangle,
) {
let bounds = layout.bounds();
- let style = theme.style(self.style);
+ let style = theme.appearance(&self.style);
let bounds = if self.is_horizontal {
let line_y = (bounds.y + (bounds.height / 2.0)
diff --git a/native/src/widget/scrollable.rs b/native/src/widget/scrollable.rs
index 4ebb07a0..b257cbe5 100644
--- a/native/src/widget/scrollable.rs
+++ b/native/src/widget/scrollable.rs
@@ -233,7 +233,7 @@ where
self.scrollbar_width,
self.scrollbar_margin,
self.scroller_width,
- self.style,
+ &self.style,
|renderer, layout, cursor_position, viewport| {
self.content.as_widget().draw(
&tree.children[0],
@@ -627,7 +627,7 @@ pub fn draw<Renderer>(
scrollbar_width: u16,
scrollbar_margin: u16,
scroller_width: u16,
- style: <Renderer::Theme as StyleSheet>::Style,
+ style: &<Renderer::Theme as StyleSheet>::Style,
draw_content: impl FnOnce(&mut Renderer, Layout<'_>, Point, &Rectangle),
) where
Renderer: crate::Renderer,
diff --git a/native/src/widget/slider.rs b/native/src/widget/slider.rs
index 585d9c35..92ed72e9 100644
--- a/native/src/widget/slider.rs
+++ b/native/src/widget/slider.rs
@@ -222,7 +222,7 @@ where
self.value,
&self.range,
theme,
- self.style,
+ &self.style,
)
}
@@ -353,7 +353,7 @@ pub fn draw<T, R>(
value: T,
range: &RangeInclusive<T>,
style_sheet: &dyn StyleSheet<Style = <R::Theme as StyleSheet>::Style>,
- style: <R::Theme as StyleSheet>::Style,
+ style: &<R::Theme as StyleSheet>::Style,
) where
T: Into<f64> + Copy,
R: crate::Renderer,
@@ -363,11 +363,11 @@ pub fn draw<T, R>(
let is_mouse_over = bounds.contains(cursor_position);
let style = if state.is_dragging {
- style_sheet.dragging(style)
+ style_sheet.dragging(&style)
} else if is_mouse_over {
- style_sheet.hovered(style)
+ style_sheet.hovered(&style)
} else {
- style_sheet.active(style)
+ style_sheet.active(&style)
};
let rail_y = bounds.y + (bounds.height / 2.0).round();
diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs
index 25a8690e..22eff7f1 100644
--- a/native/src/widget/text_input.rs
+++ b/native/src/widget/text_input.rs
@@ -188,7 +188,7 @@ where
self.size,
&self.font,
self.is_secure,
- self.style,
+ &self.style,
)
}
}
@@ -284,7 +284,7 @@ where
self.size,
&self.font,
self.is_secure,
- self.style,
+ &self.style,
)
}
@@ -746,7 +746,7 @@ pub fn draw<Renderer>(
size: Option<u16>,
font: &Renderer::Font,
is_secure: bool,
- style: <Renderer::Theme as StyleSheet>::Style,
+ style: &<Renderer::Theme as StyleSheet>::Style,
) where
Renderer: text::Renderer,
Renderer::Theme: StyleSheet,
diff --git a/native/src/widget/toggler.rs b/native/src/widget/toggler.rs
index 7893f78c..99a56ea8 100644
--- a/native/src/widget/toggler.rs
+++ b/native/src/widget/toggler.rs
@@ -260,9 +260,9 @@ where
let is_mouse_over = bounds.contains(cursor_position);
let style = if is_mouse_over {
- theme.hovered(self.style, self.is_active)
+ theme.hovered(&self.style, self.is_active)
} else {
- theme.active(self.style, self.is_active)
+ theme.active(&self.style, self.is_active)
};
let border_radius = bounds.height as f32 / BORDER_RADIUS_RATIO;
diff --git a/native/src/widget/tooltip.rs b/native/src/widget/tooltip.rs
index 674f2ba6..9347a886 100644
--- a/native/src/widget/tooltip.rs
+++ b/native/src/widget/tooltip.rs
@@ -201,7 +201,7 @@ where
self.gap,
self.padding,
self.snap_within_viewport,
- self.style,
+ &self.style,
|renderer, limits| {
Widget::<(), Renderer>::layout(tooltip, renderer, limits)
},
@@ -275,7 +275,7 @@ pub fn draw<Renderer>(
gap: u16,
padding: u16,
snap_within_viewport: bool,
- style: <Renderer::Theme as container::StyleSheet>::Style,
+ style: &<Renderer::Theme as container::StyleSheet>::Style,
layout_text: impl FnOnce(&Renderer, &layout::Limits) -> layout::Node,
draw_text: impl FnOnce(
&mut Renderer,
diff --git a/style/src/application.rs b/style/src/application.rs
index d48c6a34..a7f8d11f 100644
--- a/style/src/application.rs
+++ b/style/src/application.rs
@@ -1,9 +1,9 @@
use iced_core::Color;
pub trait StyleSheet {
- type Style: Default + Copy;
+ type Style: Default;
- fn appearance(&self, style: Self::Style) -> Appearance;
+ fn appearance(&self, style: &Self::Style) -> Appearance;
}
#[derive(Debug, Clone, Copy, PartialEq)]
diff --git a/style/src/button.rs b/style/src/button.rs
index c63a6b71..858a9ab2 100644
--- a/style/src/button.rs
+++ b/style/src/button.rs
@@ -27,11 +27,11 @@ impl std::default::Default for Appearance {
/// A set of rules that dictate the style of a button.
pub trait StyleSheet {
- type Style: Default + Copy;
+ type Style: Default;
- fn active(&self, style: Self::Style) -> Appearance;
+ fn active(&self, style: &Self::Style) -> Appearance;
- fn hovered(&self, style: Self::Style) -> Appearance {
+ fn hovered(&self, style: &Self::Style) -> Appearance {
let active = self.active(style);
Appearance {
@@ -40,14 +40,14 @@ pub trait StyleSheet {
}
}
- fn pressed(&self, style: Self::Style) -> Appearance {
+ fn pressed(&self, style: &Self::Style) -> Appearance {
Appearance {
shadow_offset: Vector::default(),
..self.active(style)
}
}
- fn disabled(&self, style: Self::Style) -> Appearance {
+ fn disabled(&self, style: &Self::Style) -> Appearance {
let active = self.active(style);
Appearance {
diff --git a/style/src/checkbox.rs b/style/src/checkbox.rs
index ba54b0a2..a8b4a11d 100644
--- a/style/src/checkbox.rs
+++ b/style/src/checkbox.rs
@@ -14,9 +14,9 @@ pub struct Appearance {
/// A set of rules that dictate the style of a checkbox.
pub trait StyleSheet {
- type Style: Default + Copy;
+ type Style: Default;
- fn active(&self, style: Self::Style, is_checked: bool) -> Appearance;
+ fn active(&self, style: &Self::Style, is_checked: bool) -> Appearance;
- fn hovered(&self, style: Self::Style, is_checked: bool) -> Appearance;
+ fn hovered(&self, style: &Self::Style, is_checked: bool) -> Appearance;
}
diff --git a/style/src/container.rs b/style/src/container.rs
index 184310fa..53c59589 100644
--- a/style/src/container.rs
+++ b/style/src/container.rs
@@ -25,8 +25,8 @@ impl std::default::Default for Appearance {
/// A set of rules that dictate the [`Appearance`] of a container.
pub trait StyleSheet {
- type Style: Default + Copy;
+ type Style: Default;
/// Produces the [`Appearance`] of a container.
- fn appearance(&self, style: Self::Style) -> Appearance;
+ fn appearance(&self, style: &Self::Style) -> Appearance;
}
diff --git a/style/src/menu.rs b/style/src/menu.rs
index 6ef3e2a2..409831a9 100644
--- a/style/src/menu.rs
+++ b/style/src/menu.rs
@@ -13,7 +13,7 @@ pub struct Appearance {
}
pub trait StyleSheet {
- type Style: Default + Copy;
+ type Style: Default + Clone;
- fn appearance(&self, style: Self::Style) -> Appearance;
+ fn appearance(&self, style: &Self::Style) -> Appearance;
}
diff --git a/style/src/pane_grid.rs b/style/src/pane_grid.rs
index 5bae353f..be541434 100644
--- a/style/src/pane_grid.rs
+++ b/style/src/pane_grid.rs
@@ -4,13 +4,13 @@ use iced_core::Color;
/// A set of rules that dictate the style of a container.
pub trait StyleSheet {
- type Style: Default + Copy;
+ type Style: Default;
/// The [`Line`] to draw when a split is picked.
- fn picked_split(&self, style: Self::Style) -> Option<Line>;
+ fn picked_split(&self, style: &Self::Style) -> Option<Line>;
/// The [`Line`] to draw when a split is hovered.
- fn hovered_split(&self, style: Self::Style) -> Option<Line>;
+ fn hovered_split(&self, style: &Self::Style) -> Option<Line>;
}
/// A line.
diff --git a/style/src/pick_list.rs b/style/src/pick_list.rs
index 2bafe932..a09772d7 100644
--- a/style/src/pick_list.rs
+++ b/style/src/pick_list.rs
@@ -1,9 +1,5 @@
use iced_core::{Background, Color};
-use crate::container;
-use crate::menu;
-use crate::scrollable;
-
/// The appearance of a pick list.
#[derive(Debug, Clone, Copy)]
pub struct Appearance {
@@ -17,13 +13,10 @@ pub struct Appearance {
}
/// A set of rules that dictate the style of a container.
-pub trait StyleSheet:
- container::StyleSheet + menu::StyleSheet + scrollable::StyleSheet
-{
- type Style: Default + Copy + Into<<Self as menu::StyleSheet>::Style>;
+pub trait StyleSheet {
+ type Style: Default + Clone;
- fn active(&self, style: <Self as StyleSheet>::Style) -> Appearance;
+ fn active(&self, style: &<Self as StyleSheet>::Style) -> Appearance;
- /// Produces the style of a container.
- fn hovered(&self, style: <Self as StyleSheet>::Style) -> Appearance;
+ fn hovered(&self, style: &<Self as StyleSheet>::Style) -> Appearance;
}
diff --git a/style/src/progress_bar.rs b/style/src/progress_bar.rs
index 768e7c9c..506d634f 100644
--- a/style/src/progress_bar.rs
+++ b/style/src/progress_bar.rs
@@ -11,7 +11,7 @@ pub struct Appearance {
/// A set of rules that dictate the style of a progress bar.
pub trait StyleSheet {
- type Style: Default + Copy;
+ type Style: Default;
- fn appearance(&self, style: Self::Style) -> Appearance;
+ fn appearance(&self, style: &Self::Style) -> Appearance;
}
diff --git a/style/src/radio.rs b/style/src/radio.rs
index d14ea33e..370d483e 100644
--- a/style/src/radio.rs
+++ b/style/src/radio.rs
@@ -13,9 +13,9 @@ pub struct Appearance {
/// A set of rules that dictate the style of a radio button.
pub trait StyleSheet {
- type Style: Default + Copy;
+ type Style: Default;
- fn active(&self, style: Self::Style, is_selected: bool) -> Appearance;
+ fn active(&self, style: &Self::Style, is_selected: bool) -> Appearance;
- fn hovered(&self, style: Self::Style, is_selected: bool) -> Appearance;
+ fn hovered(&self, style: &Self::Style, is_selected: bool) -> Appearance;
}
diff --git a/style/src/rule.rs b/style/src/rule.rs
index af334912..bcad655c 100644
--- a/style/src/rule.rs
+++ b/style/src/rule.rs
@@ -16,10 +16,10 @@ pub struct Appearance {
/// A set of rules that dictate the style of a rule.
pub trait StyleSheet {
- type Style: Default + Copy;
+ type Style: Default;
/// Produces the style of a rule.
- fn style(&self, style: Self::Style) -> Appearance;
+ fn appearance(&self, style: &Self::Style) -> Appearance;
}
/// The fill mode of a rule.
diff --git a/style/src/scrollable.rs b/style/src/scrollable.rs
index 8da7409c..4352930c 100644
--- a/style/src/scrollable.rs
+++ b/style/src/scrollable.rs
@@ -22,16 +22,16 @@ pub struct Scroller {
/// A set of rules that dictate the style of a scrollable.
pub trait StyleSheet {
- type Style: Default + Copy;
+ type Style: Default;
/// Produces the style of an active scrollbar.
- fn active(&self, style: Self::Style) -> Scrollbar;
+ fn active(&self, style: &Self::Style) -> Scrollbar;
/// Produces the style of an hovered scrollbar.
- fn hovered(&self, style: Self::Style) -> Scrollbar;
+ fn hovered(&self, style: &Self::Style) -> Scrollbar;
/// Produces the style of a scrollbar that is being dragged.
- fn dragging(&self, style: Self::Style) -> Scrollbar {
+ fn dragging(&self, style: &Self::Style) -> Scrollbar {
self.hovered(style)
}
}
diff --git a/style/src/slider.rs b/style/src/slider.rs
index 0ff0449b..73ee097b 100644
--- a/style/src/slider.rs
+++ b/style/src/slider.rs
@@ -26,14 +26,14 @@ pub enum HandleShape {
/// A set of rules that dictate the style of a slider.
pub trait StyleSheet {
- type Style: Default + Copy;
+ type Style: Default;
/// Produces the style of an active slider.
- fn active(&self, style: Self::Style) -> Appearance;
+ fn active(&self, style: &Self::Style) -> Appearance;
/// Produces the style of an hovered slider.
- fn hovered(&self, style: Self::Style) -> Appearance;
+ fn hovered(&self, style: &Self::Style) -> Appearance;
/// Produces the style of a slider that is being dragged.
- fn dragging(&self, style: Self::Style) -> Appearance;
+ fn dragging(&self, style: &Self::Style) -> Appearance;
}
diff --git a/style/src/text_input.rs b/style/src/text_input.rs
index af86617b..1be9ccea 100644
--- a/style/src/text_input.rs
+++ b/style/src/text_input.rs
@@ -12,22 +12,22 @@ pub struct Appearance {
/// A set of rules that dictate the style of a text input.
pub trait StyleSheet {
- type Style: Default + Copy;
+ type Style: Default;
/// Produces the style of an active text input.
- fn active(&self, style: Self::Style) -> Appearance;
+ fn active(&self, style: &Self::Style) -> Appearance;
/// Produces the style of a focused text input.
- fn focused(&self, style: Self::Style) -> Appearance;
+ fn focused(&self, style: &Self::Style) -> Appearance;
- fn placeholder_color(&self, style: Self::Style) -> Color;
+ fn placeholder_color(&self, style: &Self::Style) -> Color;
- fn value_color(&self, style: Self::Style) -> Color;
+ fn value_color(&self, style: &Self::Style) -> Color;
- fn selection_color(&self, style: Self::Style) -> Color;
+ fn selection_color(&self, style: &Self::Style) -> Color;
/// Produces the style of an hovered text input.
- fn hovered(&self, style: Self::Style) -> Appearance {
+ fn hovered(&self, style: &Self::Style) -> Appearance {
self.focused(style)
}
}
diff --git a/style/src/theme.rs b/style/src/theme.rs
index a253e990..a5a78ab1 100644
--- a/style/src/theme.rs
+++ b/style/src/theme.rs
@@ -19,7 +19,9 @@ use crate::text;
use crate::text_input;
use crate::toggler;
-use iced_core::{Background, Color};
+use iced_core::{Background, Color, Vector};
+
+use std::rc::Rc;
#[derive(Debug, Clone, PartialEq)]
pub enum Theme {
@@ -71,10 +73,9 @@ impl Custom {
}
}
-#[derive(Debug, Clone, Copy)]
pub enum Application {
Default,
- Custom(fn(Theme) -> application::Appearance),
+ Custom(Box<dyn application::StyleSheet<Style = Theme>>),
}
impl Default for Application {
@@ -86,7 +87,7 @@ impl Default for Application {
impl application::StyleSheet for Theme {
type Style = Application;
- fn appearance(&self, style: Self::Style) -> application::Appearance {
+ fn appearance(&self, style: &Self::Style) -> application::Appearance {
let palette = self.extended_palette();
match style {
@@ -94,21 +95,35 @@ impl application::StyleSheet for Theme {
background_color: palette.background.base.color,
text_color: palette.background.base.text,
},
- Application::Custom(f) => f(self.clone()),
+ Application::Custom(custom) => custom.appearance(self),
}
}
}
+impl application::StyleSheet for fn(&Theme) -> application::Appearance {
+ type Style = Theme;
+
+ fn appearance(&self, style: &Self::Style) -> application::Appearance {
+ (self)(style)
+ }
+}
+
+impl From<fn(&Theme) -> application::Appearance> for Application {
+ fn from(f: fn(&Theme) -> application::Appearance) -> Self {
+ Self::Custom(Box::new(f))
+ }
+}
+
/*
* Button
*/
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Button {
Primary,
Secondary,
Positive,
Destructive,
Text,
+ Custom(Box<dyn button::StyleSheet<Style = Theme>>),
}
impl Default for Button {
@@ -120,7 +135,7 @@ impl Default for Button {
impl button::StyleSheet for Theme {
type Style = Button;
- fn active(&self, style: Self::Style) -> button::Appearance {
+ fn active(&self, style: &Self::Style) -> button::Appearance {
let palette = self.extended_palette();
let appearance = button::Appearance {
@@ -143,19 +158,25 @@ impl button::StyleSheet for Theme {
text_color: palette.background.base.text,
..appearance
},
+ Button::Custom(custom) => custom.active(self),
}
}
- fn hovered(&self, style: Self::Style) -> button::Appearance {
- let active = self.active(style);
+ fn hovered(&self, style: &Self::Style) -> button::Appearance {
let palette = self.extended_palette();
+ if let Button::Custom(custom) = style {
+ return custom.hovered(self);
+ }
+
+ let active = self.active(style);
+
let background = match style {
Button::Primary => Some(palette.primary.base.color),
Button::Secondary => Some(palette.background.strong.color),
Button::Positive => Some(palette.success.strong.color),
Button::Destructive => Some(palette.danger.strong.color),
- Button::Text => None,
+ Button::Text | Button::Custom(_) => None,
};
button::Appearance {
@@ -163,17 +184,51 @@ impl button::StyleSheet for Theme {
..active
}
}
+
+ fn pressed(&self, style: &Self::Style) -> button::Appearance {
+ if let Button::Custom(custom) = style {
+ return custom.pressed(self);
+ }
+
+ button::Appearance {
+ shadow_offset: Vector::default(),
+ ..self.active(style)
+ }
+ }
+
+ fn disabled(&self, style: &Self::Style) -> button::Appearance {
+ if let Button::Custom(custom) = style {
+ return custom.disabled(self);
+ }
+
+ let active = self.active(style);
+
+ button::Appearance {
+ shadow_offset: Vector::default(),
+ background: active.background.map(|background| match background {
+ Background::Color(color) => Background::Color(Color {
+ a: color.a * 0.5,
+ ..color
+ }),
+ }),
+ text_color: Color {
+ a: active.text_color.a * 0.5,
+ ..active.text_color
+ },
+ ..active
+ }
+ }
}
/*
* Checkbox
*/
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Checkbox {
Primary,
Secondary,
Success,
Danger,
+ Custom(Box<dyn checkbox::StyleSheet<Style = Theme>>),
}
impl Default for Checkbox {
@@ -187,7 +242,7 @@ impl checkbox::StyleSheet for Theme {
fn active(
&self,
- style: Self::Style,
+ style: &Self::Style,
is_checked: bool,
) -> checkbox::Appearance {
let palette = self.extended_palette();
@@ -217,12 +272,13 @@ impl checkbox::StyleSheet for Theme {
palette.danger.base,
is_checked,
),
+ Checkbox::Custom(custom) => custom.active(self, is_checked),
}
}
fn hovered(
&self,
- style: Self::Style,
+ style: &Self::Style,
is_checked: bool,
) -> checkbox::Appearance {
let palette = self.extended_palette();
@@ -252,6 +308,7 @@ impl checkbox::StyleSheet for Theme {
palette.danger.base,
is_checked,
),
+ Checkbox::Custom(custom) => custom.hovered(self, is_checked),
}
}
}
@@ -279,11 +336,10 @@ fn checkbox_appearance(
/*
* Container
*/
-#[derive(Clone, Copy)]
pub enum Container {
Transparent,
Box,
- Custom(fn(&Theme) -> container::Appearance),
+ Custom(Box<dyn container::StyleSheet<Style = Theme>>),
}
impl Default for Container {
@@ -294,14 +350,14 @@ impl Default for Container {
impl From<fn(&Theme) -> container::Appearance> for Container {
fn from(f: fn(&Theme) -> container::Appearance) -> Self {
- Self::Custom(f)
+ Self::Custom(Box::new(f))
}
}
impl container::StyleSheet for Theme {
type Style = Container;
- fn appearance(&self, style: Self::Style) -> container::Appearance {
+ fn appearance(&self, style: &Self::Style) -> container::Appearance {
match style {
Container::Transparent => Default::default(),
Container::Box => {
@@ -315,63 +371,96 @@ impl container::StyleSheet for Theme {
border_color: Color::TRANSPARENT,
}
}
- Container::Custom(f) => f(self),
+ Container::Custom(custom) => custom.appearance(self),
}
}
}
+impl container::StyleSheet for fn(&Theme) -> container::Appearance {
+ type Style = Theme;
+
+ fn appearance(&self, style: &Self::Style) -> container::Appearance {
+ (self)(style)
+ }
+}
+
/*
* Slider
*/
-impl slider::StyleSheet for Theme {
- type Style = ();
+#[derive(Default)]
+pub enum Slider {
+ #[default]
+ Default,
+ Custom(Box<dyn slider::StyleSheet<Style = Theme>>),
+}
- fn active(&self, _style: Self::Style) -> slider::Appearance {
- let palette = self.extended_palette();
+impl slider::StyleSheet for Theme {
+ type Style = Slider;
- let handle = slider::Handle {
- shape: slider::HandleShape::Rectangle {
- width: 8,
- border_radius: 4.0,
- },
- color: Color::WHITE,
- border_color: Color::WHITE,
- border_width: 1.0,
- };
+ fn active(&self, style: &Self::Style) -> slider::Appearance {
+ match style {
+ Slider::Default => {
+ let palette = self.extended_palette();
- slider::Appearance {
- rail_colors: (palette.primary.base.color, Color::TRANSPARENT),
- handle: slider::Handle {
- color: palette.background.base.color,
- border_color: palette.primary.base.color,
- ..handle
- },
+ let handle = slider::Handle {
+ shape: slider::HandleShape::Rectangle {
+ width: 8,
+ border_radius: 4.0,
+ },
+ color: Color::WHITE,
+ border_color: Color::WHITE,
+ border_width: 1.0,
+ };
+
+ slider::Appearance {
+ rail_colors: (
+ palette.primary.base.color,
+ Color::TRANSPARENT,
+ ),
+ handle: slider::Handle {
+ color: palette.background.base.color,
+ border_color: palette.primary.base.color,
+ ..handle
+ },
+ }
+ }
+ Slider::Custom(custom) => custom.active(self),
}
}
- fn hovered(&self, style: Self::Style) -> slider::Appearance {
- let active = self.active(style);
- let palette = self.extended_palette();
+ fn hovered(&self, style: &Self::Style) -> slider::Appearance {
+ match style {
+ Slider::Default => {
+ let active = self.active(style);
+ let palette = self.extended_palette();
- slider::Appearance {
- handle: slider::Handle {
- color: palette.primary.weak.color,
- ..active.handle
- },
- ..active
+ slider::Appearance {
+ handle: slider::Handle {
+ color: palette.primary.weak.color,
+ ..active.handle
+ },
+ ..active
+ }
+ }
+ Slider::Custom(custom) => custom.hovered(self),
}
}
- fn dragging(&self, style: Self::Style) -> slider::Appearance {
- let active = self.active(style);
- let palette = self.extended_palette();
+ fn dragging(&self, style: &Self::Style) -> slider::Appearance {
+ match style {
+ Slider::Default => {
+ let active = self.active(style);
+ let palette = self.extended_palette();
- slider::Appearance {
- handle: slider::Handle {
- color: palette.primary.base.color,
- ..active.handle
- },
- ..active
+ slider::Appearance {
+ handle: slider::Handle {
+ color: palette.primary.base.color,
+ ..active.handle
+ },
+ ..active
+ }
+ }
+ Slider::Custom(custom) => custom.dragging(self),
}
}
}
@@ -379,20 +468,41 @@ impl slider::StyleSheet for Theme {
/*
* Menu
*/
+#[derive(Clone, Default)]
+pub enum Menu {
+ #[default]
+ Default,
+ Custom(Rc<dyn menu::StyleSheet<Style = Theme>>),
+}
+
impl menu::StyleSheet for Theme {
- type Style = ();
+ type Style = Menu;
- fn appearance(&self, _style: Self::Style) -> menu::Appearance {
- let palette = self.extended_palette();
+ fn appearance(&self, style: &Self::Style) -> menu::Appearance {
+ match style {
+ Menu::Default => {
+ let palette = self.extended_palette();
- menu::Appearance {
- text_color: palette.background.weak.text,
- background: palette.background.weak.color.into(),
- border_width: 1.0,
- border_radius: 0.0,
- border_color: palette.background.strong.color,
- selected_text_color: palette.primary.strong.text,
- selected_background: palette.primary.strong.color.into(),
+ menu::Appearance {
+ text_color: palette.background.weak.text,
+ background: palette.background.weak.color.into(),
+ border_width: 1.0,
+ border_radius: 0.0,
+ border_color: palette.background.strong.color,
+ selected_text_color: palette.primary.strong.text,
+ selected_background: palette.primary.strong.color.into(),
+ }
+ }
+ Menu::Custom(custom) => custom.appearance(self),
+ }
+ }
+}
+
+impl From<PickList> for Menu {
+ fn from(pick_list: PickList) -> Self {
+ match pick_list {
+ PickList::Default => Self::Default,
+ PickList::Custom(_, menu) => Self::Custom(menu),
}
}
}
@@ -400,34 +510,54 @@ impl menu::StyleSheet for Theme {
/*
* Pick List
*/
+#[derive(Clone, Default)]
+pub enum PickList {
+ #[default]
+ Default,
+ Custom(
+ Rc<dyn pick_list::StyleSheet<Style = Theme>>,
+ Rc<dyn menu::StyleSheet<Style = Theme>>,
+ ),
+}
+
impl pick_list::StyleSheet for Theme {
- type Style = ();
+ type Style = PickList;
- fn active(&self, _style: ()) -> pick_list::Appearance {
- let palette = self.extended_palette();
+ fn active(&self, style: &Self::Style) -> pick_list::Appearance {
+ match style {
+ PickList::Default => {
+ let palette = self.extended_palette();
- pick_list::Appearance {
- text_color: palette.background.weak.text,
- background: palette.background.weak.color.into(),
- placeholder_color: palette.background.strong.color,
- border_radius: 2.0,
- border_width: 1.0,
- border_color: palette.background.strong.color,
- icon_size: 0.7,
+ pick_list::Appearance {
+ text_color: palette.background.weak.text,
+ background: palette.background.weak.color.into(),
+ placeholder_color: palette.background.strong.color,
+ border_radius: 2.0,
+ border_width: 1.0,
+ border_color: palette.background.strong.color,
+ icon_size: 0.7,
+ }
+ }
+ PickList::Custom(custom, _) => custom.active(self),
}
}
- fn hovered(&self, _style: ()) -> pick_list::Appearance {
- let palette = self.extended_palette();
+ fn hovered(&self, style: &Self::Style) -> pick_list::Appearance {
+ match style {
+ PickList::Default => {
+ let palette = self.extended_palette();
- pick_list::Appearance {
- text_color: palette.background.weak.text,
- background: palette.background.weak.color.into(),
- placeholder_color: palette.background.strong.color,
- border_radius: 2.0,
- border_width: 1.0,
- border_color: palette.primary.strong.color,
- icon_size: 0.7,
+ pick_list::Appearance {
+ text_color: palette.background.weak.text,
+ background: palette.background.weak.color.into(),
+ placeholder_color: palette.background.strong.color,
+ border_radius: 2.0,
+ border_width: 1.0,
+ border_color: palette.primary.strong.color,
+ icon_size: 0.7,
+ }
+ }
+ PickList::Custom(custom, _) => custom.active(self),
}
}
}
@@ -435,37 +565,54 @@ impl pick_list::StyleSheet for Theme {
/*
* Radio
*/
+#[derive(Default)]
+pub enum Radio {
+ #[default]
+ Default,
+ Custom(Box<dyn radio::StyleSheet<Style = Theme>>),
+}
+
impl radio::StyleSheet for Theme {
- type Style = ();
+ type Style = Radio;
fn active(
&self,
- _style: Self::Style,
- _is_selected: bool,
+ style: &Self::Style,
+ is_selected: bool,
) -> radio::Appearance {
- let palette = self.extended_palette();
+ match style {
+ Radio::Default => {
+ let palette = self.extended_palette();
- radio::Appearance {
- background: Color::TRANSPARENT.into(),
- dot_color: palette.primary.strong.color,
- border_width: 1.0,
- border_color: palette.primary.strong.color,
- text_color: None,
+ radio::Appearance {
+ background: Color::TRANSPARENT.into(),
+ dot_color: palette.primary.strong.color,
+ border_width: 1.0,
+ border_color: palette.primary.strong.color,
+ text_color: None,
+ }
+ }
+ Radio::Custom(custom) => custom.active(self, is_selected),
}
}
fn hovered(
&self,
- style: Self::Style,
+ style: &Self::Style,
is_selected: bool,
) -> radio::Appearance {
- let active = self.active(style, is_selected);
- let palette = self.extended_palette();
+ match style {
+ Radio::Default => {
+ let active = self.active(style, is_selected);
+ let palette = self.extended_palette();
- radio::Appearance {
- dot_color: palette.primary.strong.color,
- background: palette.primary.weak.color.into(),
- ..active
+ radio::Appearance {
+ dot_color: palette.primary.strong.color,
+ background: palette.primary.weak.color.into(),
+ ..active
+ }
+ }
+ Radio::Custom(custom) => custom.hovered(self, is_selected),
}
}
}
@@ -473,49 +620,66 @@ impl radio::StyleSheet for Theme {
/*
* Toggler
*/
+#[derive(Default)]
+pub enum Toggler {
+ #[default]
+ Default,
+ Custom(Box<dyn toggler::StyleSheet<Style = Theme>>),
+}
+
impl toggler::StyleSheet for Theme {
- type Style = ();
+ type Style = Toggler;
fn active(
&self,
- _style: Self::Style,
+ style: &Self::Style,
is_active: bool,
) -> toggler::Appearance {
- let palette = self.extended_palette();
+ 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: None,
- foreground: if is_active {
- palette.primary.strong.text
- } else {
- palette.background.base.color
- },
- foreground_border: None,
+ toggler::Appearance {
+ background: if is_active {
+ palette.primary.strong.color
+ } else {
+ palette.background.strong.color
+ },
+ background_border: None,
+ foreground: if is_active {
+ palette.primary.strong.text
+ } else {
+ palette.background.base.color
+ },
+ foreground_border: None,
+ }
+ }
+ Toggler::Custom(custom) => custom.active(self, is_active),
}
}
fn hovered(
&self,
- style: Self::Style,
+ style: &Self::Style,
is_active: bool,
) -> toggler::Appearance {
- let palette = self.extended_palette();
+ match style {
+ Toggler::Default => {
+ let palette = self.extended_palette();
- toggler::Appearance {
- foreground: if is_active {
- Color {
- a: 0.5,
- ..palette.primary.strong.text
+ toggler::Appearance {
+ foreground: if is_active {
+ Color {
+ a: 0.5,
+ ..palette.primary.strong.text
+ }
+ } else {
+ palette.background.weak.color
+ },
+ ..self.active(style, is_active)
}
- } else {
- palette.background.weak.color
- },
- ..self.active(style, is_active)
+ }
+ Toggler::Custom(custom) => custom.hovered(self, is_active),
}
}
}
@@ -523,37 +687,53 @@ impl toggler::StyleSheet for Theme {
/*
* Pane Grid
*/
+#[derive(Default)]
+pub enum PaneGrid {
+ #[default]
+ Default,
+ Custom(Box<dyn pane_grid::StyleSheet<Style = Theme>>),
+}
+
impl pane_grid::StyleSheet for Theme {
- type Style = ();
+ type Style = PaneGrid;
- fn picked_split(&self, _style: Self::Style) -> Option<pane_grid::Line> {
- let palette = self.extended_palette();
+ fn picked_split(&self, style: &Self::Style) -> Option<pane_grid::Line> {
+ match style {
+ PaneGrid::Default => {
+ let palette = self.extended_palette();
- Some(pane_grid::Line {
- color: palette.primary.strong.color,
- width: 2.0,
- })
+ Some(pane_grid::Line {
+ color: palette.primary.strong.color,
+ width: 2.0,
+ })
+ }
+ PaneGrid::Custom(custom) => custom.picked_split(self),
+ }
}
- fn hovered_split(&self, _style: Self::Style) -> Option<pane_grid::Line> {
- let palette = self.extended_palette();
+ fn hovered_split(&self, style: &Self::Style) -> Option<pane_grid::Line> {
+ match style {
+ PaneGrid::Default => {
+ let palette = self.extended_palette();
- Some(pane_grid::Line {
- color: palette.primary.base.color,
- width: 2.0,
- })
+ Some(pane_grid::Line {
+ color: palette.primary.base.color,
+ width: 2.0,
+ })
+ }
+ PaneGrid::Custom(custom) => custom.hovered_split(self),
+ }
}
}
/*
* Progress Bar
*/
-#[derive(Clone, Copy)]
pub enum ProgressBar {
Primary,
Success,
Danger,
- Custom(fn(&Theme) -> progress_bar::Appearance),
+ Custom(Box<dyn progress_bar::StyleSheet<Style = Theme>>),
}
impl Default for ProgressBar {
@@ -562,10 +742,20 @@ impl Default for ProgressBar {
}
}
+impl From<fn(&Theme) -> progress_bar::Appearance> for ProgressBar {
+ fn from(f: fn(&Theme) -> progress_bar::Appearance) -> Self {
+ Self::Custom(Box::new(f))
+ }
+}
+
impl progress_bar::StyleSheet for Theme {
type Style = ProgressBar;
- fn appearance(&self, style: Self::Style) -> progress_bar::Appearance {
+ fn appearance(&self, style: &Self::Style) -> progress_bar::Appearance {
+ if let ProgressBar::Custom(custom) = style {
+ return custom.appearance(self);
+ }
+
let palette = self.extended_palette();
let from_palette = |bar: Color| progress_bar::Appearance {
@@ -578,18 +768,25 @@ impl progress_bar::StyleSheet for Theme {
ProgressBar::Primary => from_palette(palette.primary.base.color),
ProgressBar::Success => from_palette(palette.success.base.color),
ProgressBar::Danger => from_palette(palette.danger.base.color),
- ProgressBar::Custom(f) => f(self),
+ ProgressBar::Custom(custom) => custom.appearance(self),
}
}
}
+impl progress_bar::StyleSheet for fn(&Theme) -> progress_bar::Appearance {
+ type Style = Theme;
+
+ fn appearance(&self, style: &Self::Style) -> progress_bar::Appearance {
+ (self)(style)
+ }
+}
+
/*
* Rule
*/
-#[derive(Clone, Copy)]
pub enum Rule {
Default,
- Custom(fn(&Theme) -> rule::Appearance),
+ Custom(Box<dyn rule::StyleSheet<Style = Theme>>),
}
impl Default for Rule {
@@ -598,10 +795,16 @@ impl Default for Rule {
}
}
+impl From<fn(&Theme) -> rule::Appearance> for Rule {
+ fn from(f: fn(&Theme) -> rule::Appearance) -> Self {
+ Self::Custom(Box::new(f))
+ }
+}
+
impl rule::StyleSheet for Theme {
type Style = Rule;
- fn style(&self, style: Self::Style) -> rule::Appearance {
+ fn appearance(&self, style: &Self::Style) -> rule::Appearance {
let palette = self.extended_palette();
match style {
@@ -611,48 +814,80 @@ impl rule::StyleSheet for Theme {
radius: 0.0,
fill_mode: rule::FillMode::Full,
},
- Rule::Custom(f) => f(self),
+ Rule::Custom(custom) => custom.appearance(self),
}
}
}
+impl rule::StyleSheet for fn(&Theme) -> rule::Appearance {
+ type Style = Theme;
+
+ fn appearance(&self, style: &Self::Style) -> rule::Appearance {
+ (self)(style)
+ }
+}
+
/*
* Scrollable
*/
+#[derive(Default)]
+pub enum Scrollable {
+ #[default]
+ Default,
+ Custom(Box<dyn scrollable::StyleSheet<Style = Theme>>),
+}
+
impl scrollable::StyleSheet for Theme {
- type Style = ();
+ type Style = Scrollable;
- fn active(&self, _style: Self::Style) -> scrollable::Scrollbar {
- let palette = self.extended_palette();
+ fn active(&self, style: &Self::Style) -> scrollable::Scrollbar {
+ match style {
+ Scrollable::Default => {
+ let palette = self.extended_palette();
- scrollable::Scrollbar {
- background: palette.background.weak.color.into(),
- border_radius: 2.0,
- border_width: 0.0,
- border_color: Color::TRANSPARENT,
- scroller: scrollable::Scroller {
- color: palette.background.strong.color,
- border_radius: 2.0,
- border_width: 0.0,
- border_color: Color::TRANSPARENT,
- },
+ scrollable::Scrollbar {
+ background: palette.background.weak.color.into(),
+ border_radius: 2.0,
+ border_width: 0.0,
+ border_color: Color::TRANSPARENT,
+ scroller: scrollable::Scroller {
+ color: palette.background.strong.color,
+ border_radius: 2.0,
+ border_width: 0.0,
+ border_color: Color::TRANSPARENT,
+ },
+ }
+ }
+ Scrollable::Custom(custom) => custom.active(self),
}
}
- fn hovered(&self, _style: Self::Style) -> scrollable::Scrollbar {
- let palette = self.extended_palette();
+ fn hovered(&self, style: &Self::Style) -> scrollable::Scrollbar {
+ match style {
+ Scrollable::Default => {
+ let palette = self.extended_palette();
- scrollable::Scrollbar {
- background: palette.background.weak.color.into(),
- border_radius: 2.0,
- border_width: 0.0,
- border_color: Color::TRANSPARENT,
- scroller: scrollable::Scroller {
- color: palette.primary.strong.color,
- border_radius: 2.0,
- border_width: 0.0,
- border_color: Color::TRANSPARENT,
- },
+ scrollable::Scrollbar {
+ background: palette.background.weak.color.into(),
+ border_radius: 2.0,
+ border_width: 0.0,
+ border_color: Color::TRANSPARENT,
+ scroller: scrollable::Scroller {
+ color: palette.primary.strong.color,
+ border_radius: 2.0,
+ border_width: 0.0,
+ border_color: Color::TRANSPARENT,
+ },
+ }
+ }
+ Scrollable::Custom(custom) => custom.hovered(self),
+ }
+ }
+
+ fn dragging(&self, style: &Self::Style) -> scrollable::Scrollbar {
+ match style {
+ Scrollable::Default => self.hovered(style),
+ Scrollable::Custom(custom) => custom.dragging(self),
}
}
}
@@ -664,7 +899,6 @@ impl scrollable::StyleSheet for Theme {
pub enum Text {
Default,
Color(Color),
- Custom(fn(&Theme) -> text::Appearance),
}
impl Default for Text {
@@ -686,7 +920,6 @@ impl text::StyleSheet for Theme {
match style {
Text::Default => Default::default(),
Text::Color(c) => text::Appearance { color: Some(c) },
- Text::Custom(f) => f(self),
}
}
}
@@ -694,10 +927,21 @@ impl text::StyleSheet for Theme {
/*
* Text Input
*/
+#[derive(Default)]
+pub enum TextInput {
+ #[default]
+ Default,
+ Custom(Box<dyn text_input::StyleSheet<Style = Theme>>),
+}
+
impl text_input::StyleSheet for Theme {
- type Style = ();
+ type Style = TextInput;
+
+ fn active(&self, style: &Self::Style) -> text_input::Appearance {
+ if let TextInput::Custom(custom) = style {
+ return custom.active(self);
+ }
- fn active(&self, _style: Self::Style) -> text_input::Appearance {
let palette = self.extended_palette();
text_input::Appearance {
@@ -708,7 +952,11 @@ impl text_input::StyleSheet for Theme {
}
}
- fn hovered(&self, _style: Self::Style) -> text_input::Appearance {
+ fn hovered(&self, style: &Self::Style) -> text_input::Appearance {
+ if let TextInput::Custom(custom) = style {
+ return custom.hovered(self);
+ }
+
let palette = self.extended_palette();
text_input::Appearance {
@@ -719,7 +967,11 @@ impl text_input::StyleSheet for Theme {
}
}
- fn focused(&self, _style: Self::Style) -> text_input::Appearance {
+ fn focused(&self, style: &Self::Style) -> text_input::Appearance {
+ if let TextInput::Custom(custom) = style {
+ return custom.focused(self);
+ }
+
let palette = self.extended_palette();
text_input::Appearance {
@@ -730,19 +982,31 @@ impl text_input::StyleSheet for Theme {
}
}
- fn placeholder_color(&self, _style: Self::Style) -> Color {
+ fn placeholder_color(&self, style: &Self::Style) -> Color {
+ if let TextInput::Custom(custom) = style {
+ return custom.placeholder_color(self);
+ }
+
let palette = self.extended_palette();
palette.background.strong.color
}
- fn value_color(&self, _style: Self::Style) -> Color {
+ fn value_color(&self, style: &Self::Style) -> Color {
+ if let TextInput::Custom(custom) = style {
+ return custom.value_color(self);
+ }
+
let palette = self.extended_palette();
palette.background.base.text
}
- fn selection_color(&self, _style: Self::Style) -> Color {
+ fn selection_color(&self, style: &Self::Style) -> Color {
+ if let TextInput::Custom(custom) = style {
+ return custom.selection_color(self);
+ }
+
let palette = self.extended_palette();
palette.primary.weak.color
diff --git a/style/src/toggler.rs b/style/src/toggler.rs
index 0acf8e97..fcc7e45b 100644
--- a/style/src/toggler.rs
+++ b/style/src/toggler.rs
@@ -12,9 +12,9 @@ pub struct Appearance {
/// A set of rules that dictate the style of a toggler.
pub trait StyleSheet {
- type Style: Default + Copy;
+ type Style: Default;
- fn active(&self, style: Self::Style, is_active: bool) -> Appearance;
+ fn active(&self, style: &Self::Style, is_active: bool) -> Appearance;
- fn hovered(&self, style: Self::Style, is_active: bool) -> Appearance;
+ fn hovered(&self, style: &Self::Style, is_active: bool) -> Appearance;
}
diff --git a/winit/src/application/state.rs b/winit/src/application/state.rs
index 9c539548..8d6a1df1 100644
--- a/winit/src/application/state.rs
+++ b/winit/src/application/state.rs
@@ -32,7 +32,7 @@ where
let title = application.title();
let scale_factor = application.scale_factor();
let theme = application.theme();
- let appearance = theme.appearance(application.style());
+ let appearance = theme.appearance(&application.style());
let viewport = {
let physical_size = window.inner_size();
@@ -210,6 +210,6 @@ where
// Update theme and appearance
self.theme = application.theme();
- self.appearance = self.theme.appearance(application.style());
+ self.appearance = self.theme.appearance(&application.style());
}
}