Merge pull request #1519 from iced-rs/customizable-theme

Built-in `Theme` customization
This commit is contained in:
Héctor Ramón 2022-11-09 18:24:14 +01:00 committed by GitHub
commit af6f7945a9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 583 additions and 327 deletions

View file

@ -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> {

View file

@ -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 =

View file

@ -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

View file

@ -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)
};
{

View file

@ -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());

View file

@ -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)
}

View file

@ -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,

View file

@ -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);
}

View file

@ -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),
};

View file

@ -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,

View file

@ -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 {

View file

@ -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)
};
{

View file

@ -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)

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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;

View file

@ -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,

View file

@ -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)]

View file

@ -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 {

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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.

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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.

View file

@ -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)
}
}

View file

@ -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;
}

View file

@ -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)
}
}

File diff suppressed because it is too large Load diff

View file

@ -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;
}

View file

@ -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());
}
}