iced-yoda/style/src/theme.rs

1345 lines
37 KiB
Rust
Raw Normal View History

2022-11-10 01:10:28 +01:00
//! Use the built-in theme and styles.
2022-06-04 03:04:43 +02:00
pub mod palette;
2022-05-21 17:33:31 -04:00
pub use palette::Palette;
2022-05-21 17:33:31 -04:00
use crate::application;
use crate::button;
2022-06-04 03:26:53 +02:00
use crate::checkbox;
use crate::container;
use crate::core::widget::text;
use crate::menu;
2022-06-01 01:44:59 +02:00
use crate::pane_grid;
use crate::pick_list;
use crate::progress_bar;
2022-05-27 01:26:57 +02:00
use crate::radio;
2022-06-01 01:56:46 +02:00
use crate::rule;
use crate::scrollable;
2022-05-26 00:40:27 +02:00
use crate::slider;
2022-11-16 17:42:41 +01:00
use crate::svg;
use crate::text_editor;
use crate::text_input;
use crate::toggler;
use crate::core::{Background, Border, Color, Shadow, Vector};
use std::fmt;
use std::rc::Rc;
2022-11-10 01:10:28 +01:00
/// A built-in theme.
#[derive(Debug, Clone, PartialEq, Default)]
pub enum Theme {
2022-11-10 01:10:28 +01:00
/// The built-in light variant.
#[default]
Light,
2022-11-10 01:10:28 +01:00
/// The built-in dark variant.
Dark,
2022-11-10 01:10:28 +01:00
/// A [`Theme`] that uses a [`Custom`] palette.
2022-11-03 03:27:55 +01:00
Custom(Box<Custom>),
}
2022-05-21 17:33:31 -04:00
impl Theme {
/// A list with all the defined themes.
pub const ALL: &'static [Self] = &[Self::Light, Self::Dark];
2022-11-10 01:10:28 +01:00
/// Creates a new custom [`Theme`] from the given [`Palette`].
pub fn custom(name: String, palette: Palette) -> Self {
Self::custom_with_fn(name, palette, palette::Extended::generate)
}
/// Creates a new custom [`Theme`] from the given [`Palette`], with
/// a custom generator of a [`palette::Extended`].
pub fn custom_with_fn(
name: String,
palette: Palette,
generate: impl FnOnce(Palette) -> palette::Extended,
) -> Self {
Self::Custom(Box::new(Custom::with_fn(name, palette, generate)))
2022-11-03 03:21:26 +01:00
}
2022-11-10 01:10:28 +01:00
/// Returns the [`Palette`] of the [`Theme`].
2022-11-03 03:27:55 +01:00
pub fn palette(&self) -> Palette {
2022-05-21 17:33:31 -04:00
match self {
Self::Light => Palette::LIGHT,
Self::Dark => Palette::DARK,
2022-11-03 03:21:26 +01:00
Self::Custom(custom) => custom.palette,
2022-05-21 17:33:31 -04:00
}
}
2022-11-10 01:10:28 +01:00
/// Returns the [`palette::Extended`] of the [`Theme`].
2022-06-04 03:04:43 +02:00
pub fn extended_palette(&self) -> &palette::Extended {
2022-05-21 17:33:31 -04:00
match self {
Self::Light => &palette::EXTENDED_LIGHT,
Self::Dark => &palette::EXTENDED_DARK,
2022-11-03 03:21:26 +01:00
Self::Custom(custom) => &custom.extended,
2022-05-21 17:33:31 -04:00
}
}
}
impl fmt::Display for Theme {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Light => write!(f, "Light"),
Self::Dark => write!(f, "Dark"),
Self::Custom(custom) => custom.fmt(f),
}
}
}
2022-11-10 01:10:28 +01:00
/// A [`Theme`] with a customized [`Palette`].
#[derive(Debug, Clone, PartialEq)]
2022-11-03 03:21:26 +01:00
pub struct Custom {
name: String,
2022-11-03 03:21:26 +01:00
palette: Palette,
extended: palette::Extended,
2022-11-03 03:21:26 +01:00
}
impl Custom {
2022-11-10 01:10:28 +01:00
/// Creates a [`Custom`] theme from the given [`Palette`].
pub fn new(name: String, palette: Palette) -> Self {
Self::with_fn(name, palette, palette::Extended::generate)
}
/// Creates a [`Custom`] theme from the given [`Palette`] with
/// a custom generator of a [`palette::Extended`].
pub fn with_fn(
name: String,
palette: Palette,
generate: impl FnOnce(Palette) -> palette::Extended,
) -> Self {
2022-11-03 03:21:26 +01:00
Self {
name,
2022-11-03 03:21:26 +01:00
palette,
extended: generate(palette),
2022-11-03 03:21:26 +01:00
}
}
}
impl fmt::Display for Custom {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.name)
}
}
2022-11-10 01:10:28 +01:00
/// The style of an application.
#[derive(Default)]
pub enum Application {
2022-11-10 01:10:28 +01:00
/// The default style.
#[default]
Default,
2022-11-10 01:10:28 +01:00
/// A custom style.
Custom(Box<dyn application::StyleSheet<Style = Theme>>),
}
impl application::StyleSheet for Theme {
type Style = Application;
fn appearance(&self, style: &Self::Style) -> application::Appearance {
let palette = self.extended_palette();
match style {
Application::Default => application::Appearance {
background_color: palette.background.base.color,
text_color: palette.background.base.text,
},
Application::Custom(custom) => custom.appearance(self),
}
}
}
Support conversion from Fn trait to custom theme ...instead of just from function pointers. I'm making this change not because I actually want to pass a closure, but to make passing a single fixed function work. This commit also simplifies the scrollable example slightly, and without the other half of this change that simplified example fails to compile with: ``` error[E0277]: the trait bound `iced::theme::ProgressBar: From<for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}>` is not satisfied --> examples/scrollable/src/main.rs:292:28 | 292 | .style(progress_bar_custom_style) | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}>` is not implemented for `iced::theme::ProgressBar` | | | required by a bound introduced by this call | = help: the trait `From<for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance>` is implemented for `iced::theme::ProgressBar` = note: required for `for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}` to implement `Into<iced::theme::ProgressBar>` note: required by a bound in `iced::widget::ProgressBar::<Renderer>::style` --> /home/marienz/src/iced/widget/src/progress_bar.rs:77:21 | 77 | style: impl Into<<Renderer::Theme as StyleSheet>::Style>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ProgressBar::<Renderer>::style` ``` This happens because `progress_bar_custom_style` by itself is a function item, which is typically coerced to a function pointer when one is needed, but not in this case. It is possible to work around this on the caller's side, but especially since the compiler diagnostic for this is a bit rough (see https://github.com/rust-lang/rust/issues/100116) let's try to make it work out of the box.
2023-05-21 23:41:26 +10:00
impl<T: Fn(&Theme) -> application::Appearance> application::StyleSheet for T {
type Style = Theme;
fn appearance(&self, style: &Self::Style) -> application::Appearance {
(self)(style)
}
}
Support conversion from Fn trait to custom theme ...instead of just from function pointers. I'm making this change not because I actually want to pass a closure, but to make passing a single fixed function work. This commit also simplifies the scrollable example slightly, and without the other half of this change that simplified example fails to compile with: ``` error[E0277]: the trait bound `iced::theme::ProgressBar: From<for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}>` is not satisfied --> examples/scrollable/src/main.rs:292:28 | 292 | .style(progress_bar_custom_style) | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}>` is not implemented for `iced::theme::ProgressBar` | | | required by a bound introduced by this call | = help: the trait `From<for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance>` is implemented for `iced::theme::ProgressBar` = note: required for `for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}` to implement `Into<iced::theme::ProgressBar>` note: required by a bound in `iced::widget::ProgressBar::<Renderer>::style` --> /home/marienz/src/iced/widget/src/progress_bar.rs:77:21 | 77 | style: impl Into<<Renderer::Theme as StyleSheet>::Style>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ProgressBar::<Renderer>::style` ``` This happens because `progress_bar_custom_style` by itself is a function item, which is typically coerced to a function pointer when one is needed, but not in this case. It is possible to work around this on the caller's side, but especially since the compiler diagnostic for this is a bit rough (see https://github.com/rust-lang/rust/issues/100116) let's try to make it work out of the box.
2023-05-21 23:41:26 +10:00
impl<T: Fn(&Theme) -> application::Appearance + 'static> From<T>
for Application
{
fn from(f: T) -> Self {
Self::Custom(Box::new(f))
}
}
2022-11-10 01:10:28 +01:00
/// The style of a button.
#[derive(Default)]
pub enum Button {
2022-11-10 01:10:28 +01:00
/// The primary style.
#[default]
Primary,
2022-11-10 01:10:28 +01:00
/// The secondary style.
Secondary,
2022-11-10 01:10:28 +01:00
/// The positive style.
Positive,
2022-11-10 01:10:28 +01:00
/// The destructive style.
Destructive,
2022-11-10 01:10:28 +01:00
/// The text style.
///
/// Useful for links!
Text,
2022-11-10 01:10:28 +01:00
/// A custom style.
Custom(Box<dyn button::StyleSheet<Style = Theme>>),
}
impl Button {
/// Creates a custom [`Button`] style variant.
pub fn custom(
style_sheet: impl button::StyleSheet<Style = Theme> + 'static,
) -> Self {
Self::Custom(Box::new(style_sheet))
}
}
impl button::StyleSheet for Theme {
type Style = Button;
fn active(&self, style: &Self::Style) -> button::Appearance {
2022-05-21 17:33:31 -04:00
let palette = self.extended_palette();
let appearance = button::Appearance {
border: Border::with_radius(2),
..button::Appearance::default()
2022-05-21 17:33:31 -04:00
};
let from_pair = |pair: palette::Pair| button::Appearance {
background: Some(pair.color.into()),
text_color: pair.text,
..appearance
};
match style {
Button::Primary => from_pair(palette.primary.strong),
Button::Secondary => from_pair(palette.secondary.base),
Button::Positive => from_pair(palette.success.base),
Button::Destructive => from_pair(palette.danger.base),
Button::Text => button::Appearance {
text_color: palette.background.base.text,
..appearance
2022-05-21 17:33:31 -04:00
},
Button::Custom(custom) => custom.active(self),
2022-05-21 17:33:31 -04:00
}
}
fn hovered(&self, style: &Self::Style) -> button::Appearance {
2022-05-21 17:33:31 -04:00
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 | Button::Custom(_) => None,
2022-05-21 17:33:31 -04:00
};
button::Appearance {
2022-05-21 17:33:31 -04:00
background: background.map(Background::from),
..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
}),
Background::Gradient(gradient) => {
Background::Gradient(gradient.mul_alpha(0.5))
}
}),
text_color: Color {
a: active.text_color.a * 0.5,
..active.text_color
},
..active
}
}
}
2022-05-26 00:40:27 +02:00
2022-11-10 01:10:28 +01:00
/// The style of a checkbox.
#[derive(Default)]
2022-06-04 03:26:53 +02:00
pub enum Checkbox {
2022-11-10 01:10:28 +01:00
/// The primary style.
#[default]
2022-06-04 03:26:53 +02:00
Primary,
2022-11-10 01:10:28 +01:00
/// The secondary style.
2022-06-04 03:26:53 +02:00
Secondary,
2022-11-10 01:10:28 +01:00
/// The success style.
2022-06-04 03:26:53 +02:00
Success,
2022-11-10 01:10:28 +01:00
/// The danger style.
2022-06-04 03:26:53 +02:00
Danger,
2022-11-10 01:10:28 +01:00
/// A custom style.
Custom(Box<dyn checkbox::StyleSheet<Style = Theme>>),
2022-06-04 03:26:53 +02:00
}
impl checkbox::StyleSheet for Theme {
type Style = Checkbox;
fn active(
&self,
style: &Self::Style,
2022-06-04 03:26:53 +02:00
is_checked: bool,
) -> checkbox::Appearance {
let palette = self.extended_palette();
match style {
Checkbox::Primary => checkbox_appearance(
palette.primary.strong.text,
palette.background.base,
2022-06-04 03:26:53 +02:00
palette.primary.strong,
is_checked,
),
Checkbox::Secondary => checkbox_appearance(
palette.background.base.text,
palette.background.base,
2022-06-04 03:26:53 +02:00
palette.background.base,
is_checked,
),
Checkbox::Success => checkbox_appearance(
palette.success.base.text,
palette.background.base,
2022-06-04 03:26:53 +02:00
palette.success.base,
is_checked,
),
Checkbox::Danger => checkbox_appearance(
palette.danger.base.text,
palette.background.base,
2022-06-04 03:26:53 +02:00
palette.danger.base,
is_checked,
),
Checkbox::Custom(custom) => custom.active(self, is_checked),
2022-06-04 03:26:53 +02:00
}
}
fn hovered(
&self,
style: &Self::Style,
2022-06-04 03:26:53 +02:00
is_checked: bool,
) -> checkbox::Appearance {
let palette = self.extended_palette();
match style {
Checkbox::Primary => checkbox_appearance(
palette.primary.strong.text,
palette.background.weak,
palette.primary.base,
2022-06-04 03:26:53 +02:00
is_checked,
),
Checkbox::Secondary => checkbox_appearance(
palette.background.base.text,
palette.background.weak,
palette.background.base,
2022-06-04 03:26:53 +02:00
is_checked,
),
Checkbox::Success => checkbox_appearance(
palette.success.base.text,
palette.background.weak,
palette.success.base,
2022-06-04 03:26:53 +02:00
is_checked,
),
Checkbox::Danger => checkbox_appearance(
palette.danger.base.text,
palette.background.weak,
palette.danger.base,
2022-06-04 03:26:53 +02:00
is_checked,
),
Checkbox::Custom(custom) => custom.hovered(self, is_checked),
2022-06-04 03:26:53 +02:00
}
}
}
fn checkbox_appearance(
icon_color: Color,
2022-06-04 03:26:53 +02:00
base: palette::Pair,
accent: palette::Pair,
is_checked: bool,
) -> checkbox::Appearance {
checkbox::Appearance {
background: Background::Color(if is_checked {
accent.color
} else {
base.color
}),
icon_color,
border: Border {
radius: 2.0.into(),
width: 1.0,
color: accent.color,
},
2022-06-04 03:26:53 +02:00
text_color: None,
}
}
2022-11-10 01:10:28 +01:00
/// The style of a container.
#[derive(Default)]
pub enum Container {
2022-11-10 01:10:28 +01:00
/// No style.
#[default]
Transparent,
2022-11-10 01:10:28 +01:00
/// A simple box.
Box,
2022-11-10 01:10:28 +01:00
/// A custom style.
Custom(Box<dyn container::StyleSheet<Style = Theme>>),
}
2024-01-10 02:58:40 +01:00
impl From<container::Appearance> for Container {
fn from(appearance: container::Appearance) -> Self {
Self::Custom(Box::new(move |_: &_| appearance))
}
}
Support conversion from Fn trait to custom theme ...instead of just from function pointers. I'm making this change not because I actually want to pass a closure, but to make passing a single fixed function work. This commit also simplifies the scrollable example slightly, and without the other half of this change that simplified example fails to compile with: ``` error[E0277]: the trait bound `iced::theme::ProgressBar: From<for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}>` is not satisfied --> examples/scrollable/src/main.rs:292:28 | 292 | .style(progress_bar_custom_style) | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}>` is not implemented for `iced::theme::ProgressBar` | | | required by a bound introduced by this call | = help: the trait `From<for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance>` is implemented for `iced::theme::ProgressBar` = note: required for `for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}` to implement `Into<iced::theme::ProgressBar>` note: required by a bound in `iced::widget::ProgressBar::<Renderer>::style` --> /home/marienz/src/iced/widget/src/progress_bar.rs:77:21 | 77 | style: impl Into<<Renderer::Theme as StyleSheet>::Style>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ProgressBar::<Renderer>::style` ``` This happens because `progress_bar_custom_style` by itself is a function item, which is typically coerced to a function pointer when one is needed, but not in this case. It is possible to work around this on the caller's side, but especially since the compiler diagnostic for this is a bit rough (see https://github.com/rust-lang/rust/issues/100116) let's try to make it work out of the box.
2023-05-21 23:41:26 +10:00
impl<T: Fn(&Theme) -> container::Appearance + 'static> From<T> for Container {
fn from(f: T) -> Self {
Self::Custom(Box::new(f))
}
}
impl container::StyleSheet for Theme {
type Style = Container;
fn appearance(&self, style: &Self::Style) -> container::Appearance {
match style {
2023-09-20 04:51:08 +02:00
Container::Transparent => container::Appearance::default(),
Container::Box => {
let palette = self.extended_palette();
container::Appearance {
text_color: None,
background: Some(palette.background.weak.color.into()),
border: Border::with_radius(2),
shadow: Shadow::default(),
}
}
Container::Custom(custom) => custom.appearance(self),
}
}
}
Support conversion from Fn trait to custom theme ...instead of just from function pointers. I'm making this change not because I actually want to pass a closure, but to make passing a single fixed function work. This commit also simplifies the scrollable example slightly, and without the other half of this change that simplified example fails to compile with: ``` error[E0277]: the trait bound `iced::theme::ProgressBar: From<for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}>` is not satisfied --> examples/scrollable/src/main.rs:292:28 | 292 | .style(progress_bar_custom_style) | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}>` is not implemented for `iced::theme::ProgressBar` | | | required by a bound introduced by this call | = help: the trait `From<for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance>` is implemented for `iced::theme::ProgressBar` = note: required for `for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}` to implement `Into<iced::theme::ProgressBar>` note: required by a bound in `iced::widget::ProgressBar::<Renderer>::style` --> /home/marienz/src/iced/widget/src/progress_bar.rs:77:21 | 77 | style: impl Into<<Renderer::Theme as StyleSheet>::Style>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ProgressBar::<Renderer>::style` ``` This happens because `progress_bar_custom_style` by itself is a function item, which is typically coerced to a function pointer when one is needed, but not in this case. It is possible to work around this on the caller's side, but especially since the compiler diagnostic for this is a bit rough (see https://github.com/rust-lang/rust/issues/100116) let's try to make it work out of the box.
2023-05-21 23:41:26 +10:00
impl<T: Fn(&Theme) -> container::Appearance> container::StyleSheet for T {
type Style = Theme;
fn appearance(&self, style: &Self::Style) -> container::Appearance {
(self)(style)
}
}
2022-11-10 01:10:28 +01:00
/// The style of a slider.
#[derive(Default)]
pub enum Slider {
2022-11-10 01:10:28 +01:00
/// The default style.
#[default]
Default,
2022-11-10 01:10:28 +01:00
/// A custom style.
Custom(Box<dyn slider::StyleSheet<Style = Theme>>),
}
2022-05-26 00:40:27 +02:00
impl slider::StyleSheet for Theme {
type Style = Slider;
2022-05-26 00:40:27 +02:00
fn active(&self, style: &Self::Style) -> slider::Appearance {
match style {
Slider::Default => {
let palette = self.extended_palette();
2022-05-26 00:40:27 +02:00
let handle = slider::Handle {
shape: slider::HandleShape::Rectangle {
width: 8,
border_radius: 4.0.into(),
},
color: Color::WHITE,
border_color: Color::WHITE,
border_width: 1.0,
};
slider::Appearance {
rail: slider::Rail {
colors: (
palette.primary.base.color,
2023-06-01 10:46:33 +02:00
palette.secondary.base.color,
),
width: 4.0,
border_radius: 2.0.into(),
},
handle: slider::Handle {
color: palette.background.base.color,
border_color: palette.primary.base.color,
..handle
},
}
}
Slider::Custom(custom) => custom.active(self),
2022-05-26 00:40:27 +02:00
}
}
fn hovered(&self, style: &Self::Style) -> slider::Appearance {
match style {
Slider::Default => {
let active = self.active(style);
let palette = self.extended_palette();
2022-05-26 00:40:27 +02:00
slider::Appearance {
handle: slider::Handle {
color: palette.primary.weak.color,
..active.handle
},
..active
}
}
Slider::Custom(custom) => custom.hovered(self),
2022-05-26 00:40:27 +02:00
}
}
fn dragging(&self, style: &Self::Style) -> slider::Appearance {
match style {
Slider::Default => {
let active = self.active(style);
let palette = self.extended_palette();
2022-05-26 00:40:27 +02:00
slider::Appearance {
handle: slider::Handle {
color: palette.primary.base.color,
..active.handle
},
..active
}
}
Slider::Custom(custom) => custom.dragging(self),
2022-05-26 00:40:27 +02:00
}
}
}
2022-05-27 01:26:57 +02:00
2022-11-10 01:10:28 +01:00
/// The style of a menu.
#[derive(Clone, Default)]
pub enum Menu {
2022-11-10 01:10:28 +01:00
/// The default style.
#[default]
Default,
2022-11-10 01:10:28 +01:00
/// A custom style.
Custom(Rc<dyn menu::StyleSheet<Style = Theme>>),
}
impl menu::StyleSheet for Theme {
type Style = Menu;
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: Border {
width: 1.0,
radius: 0.0.into(),
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),
}
}
}
2022-11-10 01:10:28 +01:00
/// The style of a pick list.
#[derive(Clone, Default)]
pub enum PickList {
2022-11-10 01:10:28 +01:00
/// The default style.
#[default]
Default,
2022-11-10 01:10:28 +01:00
/// A custom style.
Custom(
Rc<dyn pick_list::StyleSheet<Style = Theme>>,
Rc<dyn menu::StyleSheet<Style = Theme>>,
),
}
impl pick_list::StyleSheet for Theme {
type Style = PickList;
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,
handle_color: palette.background.weak.text,
border: Border {
radius: 2.0.into(),
width: 1.0,
color: palette.background.strong.color,
},
}
}
PickList::Custom(custom, _) => custom.active(self),
}
}
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,
handle_color: palette.background.weak.text,
border: Border {
radius: 2.0.into(),
width: 1.0,
color: palette.primary.strong.color,
},
}
}
2022-12-02 16:37:55 +01:00
PickList::Custom(custom, _) => custom.hovered(self),
}
}
}
2022-11-10 01:10:28 +01:00
/// The style of a radio button.
#[derive(Default)]
pub enum Radio {
2022-11-10 01:10:28 +01:00
/// The default style.
#[default]
Default,
2022-11-10 01:10:28 +01:00
/// A custom style.
Custom(Box<dyn radio::StyleSheet<Style = Theme>>),
}
2022-05-27 01:26:57 +02:00
impl radio::StyleSheet for Theme {
type Style = Radio;
2022-05-27 01:26:57 +02:00
fn active(
&self,
style: &Self::Style,
is_selected: bool,
) -> radio::Appearance {
match style {
Radio::Default => {
let palette = self.extended_palette();
2022-05-27 01:26:57 +02:00
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),
2022-05-27 01:26:57 +02:00
}
}
fn hovered(
&self,
style: &Self::Style,
is_selected: bool,
) -> radio::Appearance {
match style {
Radio::Default => {
let active = self.active(style, is_selected);
let palette = self.extended_palette();
2022-05-27 01:26:57 +02:00
radio::Appearance {
dot_color: palette.primary.strong.color,
background: palette.primary.weak.color.into(),
..active
}
}
Radio::Custom(custom) => custom.hovered(self, is_selected),
2022-05-27 01:26:57 +02:00
}
}
}
2022-11-10 01:10:28 +01:00
/// The style of a toggler.
#[derive(Default)]
pub enum Toggler {
2022-11-10 01:10:28 +01:00
/// The default style.
#[default]
Default,
2022-11-10 01:10:28 +01:00
/// 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: 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,
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),
}
}
}
2022-06-01 01:44:59 +02:00
2022-11-10 01:10:28 +01:00
/// The style of a pane grid.
#[derive(Default)]
pub enum PaneGrid {
2022-11-10 01:10:28 +01:00
/// The default style.
#[default]
Default,
2022-11-10 01:10:28 +01:00
/// A custom style.
Custom(Box<dyn pane_grid::StyleSheet<Style = Theme>>),
}
2022-06-01 01:44:59 +02:00
impl pane_grid::StyleSheet for Theme {
type Style = PaneGrid;
2022-06-01 01:44:59 +02:00
fn hovered_region(&self, style: &Self::Style) -> pane_grid::Appearance {
match style {
PaneGrid::Default => {
let palette = self.extended_palette();
pane_grid::Appearance {
background: Background::Color(Color {
a: 0.5,
..palette.primary.base.color
}),
border: Border {
width: 2.0,
color: palette.primary.strong.color,
radius: 0.0.into(),
},
}
}
PaneGrid::Custom(custom) => custom.hovered_region(self),
}
}
fn picked_split(&self, style: &Self::Style) -> Option<pane_grid::Line> {
match style {
PaneGrid::Default => {
let palette = self.extended_palette();
2022-06-01 01:44:59 +02:00
Some(pane_grid::Line {
color: palette.primary.strong.color,
width: 2.0,
})
}
PaneGrid::Custom(custom) => custom.picked_split(self),
}
2022-06-01 01:44:59 +02:00
}
fn hovered_split(&self, style: &Self::Style) -> Option<pane_grid::Line> {
match style {
PaneGrid::Default => {
let palette = self.extended_palette();
2022-06-01 01:44:59 +02:00
Some(pane_grid::Line {
color: palette.primary.base.color,
width: 2.0,
})
}
PaneGrid::Custom(custom) => custom.hovered_split(self),
}
2022-06-01 01:44:59 +02:00
}
}
2022-06-01 01:56:46 +02:00
2022-11-10 01:10:28 +01:00
/// The style of a progress bar.
#[derive(Default)]
pub enum ProgressBar {
2022-11-10 01:10:28 +01:00
/// The primary style.
#[default]
Primary,
2022-11-10 01:10:28 +01:00
/// The success style.
Success,
2022-11-10 01:10:28 +01:00
/// The danger style.
Danger,
2022-11-10 01:10:28 +01:00
/// A custom style.
Custom(Box<dyn progress_bar::StyleSheet<Style = Theme>>),
}
Support conversion from Fn trait to custom theme ...instead of just from function pointers. I'm making this change not because I actually want to pass a closure, but to make passing a single fixed function work. This commit also simplifies the scrollable example slightly, and without the other half of this change that simplified example fails to compile with: ``` error[E0277]: the trait bound `iced::theme::ProgressBar: From<for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}>` is not satisfied --> examples/scrollable/src/main.rs:292:28 | 292 | .style(progress_bar_custom_style) | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}>` is not implemented for `iced::theme::ProgressBar` | | | required by a bound introduced by this call | = help: the trait `From<for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance>` is implemented for `iced::theme::ProgressBar` = note: required for `for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}` to implement `Into<iced::theme::ProgressBar>` note: required by a bound in `iced::widget::ProgressBar::<Renderer>::style` --> /home/marienz/src/iced/widget/src/progress_bar.rs:77:21 | 77 | style: impl Into<<Renderer::Theme as StyleSheet>::Style>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ProgressBar::<Renderer>::style` ``` This happens because `progress_bar_custom_style` by itself is a function item, which is typically coerced to a function pointer when one is needed, but not in this case. It is possible to work around this on the caller's side, but especially since the compiler diagnostic for this is a bit rough (see https://github.com/rust-lang/rust/issues/100116) let's try to make it work out of the box.
2023-05-21 23:41:26 +10:00
impl<T: Fn(&Theme) -> progress_bar::Appearance + 'static> From<T>
for ProgressBar
{
fn from(f: T) -> Self {
Self::Custom(Box::new(f))
}
}
impl progress_bar::StyleSheet for Theme {
type Style = ProgressBar;
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 {
background: palette.background.strong.color.into(),
bar: bar.into(),
border_radius: 2.0.into(),
};
match style {
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(custom) => custom.appearance(self),
}
}
}
Support conversion from Fn trait to custom theme ...instead of just from function pointers. I'm making this change not because I actually want to pass a closure, but to make passing a single fixed function work. This commit also simplifies the scrollable example slightly, and without the other half of this change that simplified example fails to compile with: ``` error[E0277]: the trait bound `iced::theme::ProgressBar: From<for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}>` is not satisfied --> examples/scrollable/src/main.rs:292:28 | 292 | .style(progress_bar_custom_style) | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}>` is not implemented for `iced::theme::ProgressBar` | | | required by a bound introduced by this call | = help: the trait `From<for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance>` is implemented for `iced::theme::ProgressBar` = note: required for `for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}` to implement `Into<iced::theme::ProgressBar>` note: required by a bound in `iced::widget::ProgressBar::<Renderer>::style` --> /home/marienz/src/iced/widget/src/progress_bar.rs:77:21 | 77 | style: impl Into<<Renderer::Theme as StyleSheet>::Style>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ProgressBar::<Renderer>::style` ``` This happens because `progress_bar_custom_style` by itself is a function item, which is typically coerced to a function pointer when one is needed, but not in this case. It is possible to work around this on the caller's side, but especially since the compiler diagnostic for this is a bit rough (see https://github.com/rust-lang/rust/issues/100116) let's try to make it work out of the box.
2023-05-21 23:41:26 +10:00
impl<T: Fn(&Theme) -> progress_bar::Appearance> progress_bar::StyleSheet for T {
type Style = Theme;
fn appearance(&self, style: &Self::Style) -> progress_bar::Appearance {
(self)(style)
}
}
2022-11-10 01:10:28 +01:00
/// The style of a rule.
#[derive(Default)]
pub enum Rule {
2022-11-10 01:10:28 +01:00
/// The default style.
#[default]
Default,
2022-11-10 01:10:28 +01:00
/// A custom style.
Custom(Box<dyn rule::StyleSheet<Style = Theme>>),
}
Support conversion from Fn trait to custom theme ...instead of just from function pointers. I'm making this change not because I actually want to pass a closure, but to make passing a single fixed function work. This commit also simplifies the scrollable example slightly, and without the other half of this change that simplified example fails to compile with: ``` error[E0277]: the trait bound `iced::theme::ProgressBar: From<for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}>` is not satisfied --> examples/scrollable/src/main.rs:292:28 | 292 | .style(progress_bar_custom_style) | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}>` is not implemented for `iced::theme::ProgressBar` | | | required by a bound introduced by this call | = help: the trait `From<for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance>` is implemented for `iced::theme::ProgressBar` = note: required for `for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}` to implement `Into<iced::theme::ProgressBar>` note: required by a bound in `iced::widget::ProgressBar::<Renderer>::style` --> /home/marienz/src/iced/widget/src/progress_bar.rs:77:21 | 77 | style: impl Into<<Renderer::Theme as StyleSheet>::Style>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ProgressBar::<Renderer>::style` ``` This happens because `progress_bar_custom_style` by itself is a function item, which is typically coerced to a function pointer when one is needed, but not in this case. It is possible to work around this on the caller's side, but especially since the compiler diagnostic for this is a bit rough (see https://github.com/rust-lang/rust/issues/100116) let's try to make it work out of the box.
2023-05-21 23:41:26 +10:00
impl<T: Fn(&Theme) -> rule::Appearance + 'static> From<T> for Rule {
fn from(f: T) -> Self {
Self::Custom(Box::new(f))
}
}
2022-06-01 01:56:46 +02:00
impl rule::StyleSheet for Theme {
type Style = Rule;
2022-06-01 01:56:46 +02:00
fn appearance(&self, style: &Self::Style) -> rule::Appearance {
2022-06-01 01:56:46 +02:00
let palette = self.extended_palette();
match style {
Rule::Default => rule::Appearance {
color: palette.background.strong.color,
width: 1,
radius: 0.0.into(),
fill_mode: rule::FillMode::Full,
},
Rule::Custom(custom) => custom.appearance(self),
2022-06-01 01:56:46 +02:00
}
}
}
Support conversion from Fn trait to custom theme ...instead of just from function pointers. I'm making this change not because I actually want to pass a closure, but to make passing a single fixed function work. This commit also simplifies the scrollable example slightly, and without the other half of this change that simplified example fails to compile with: ``` error[E0277]: the trait bound `iced::theme::ProgressBar: From<for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}>` is not satisfied --> examples/scrollable/src/main.rs:292:28 | 292 | .style(progress_bar_custom_style) | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}>` is not implemented for `iced::theme::ProgressBar` | | | required by a bound introduced by this call | = help: the trait `From<for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance>` is implemented for `iced::theme::ProgressBar` = note: required for `for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}` to implement `Into<iced::theme::ProgressBar>` note: required by a bound in `iced::widget::ProgressBar::<Renderer>::style` --> /home/marienz/src/iced/widget/src/progress_bar.rs:77:21 | 77 | style: impl Into<<Renderer::Theme as StyleSheet>::Style>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ProgressBar::<Renderer>::style` ``` This happens because `progress_bar_custom_style` by itself is a function item, which is typically coerced to a function pointer when one is needed, but not in this case. It is possible to work around this on the caller's side, but especially since the compiler diagnostic for this is a bit rough (see https://github.com/rust-lang/rust/issues/100116) let's try to make it work out of the box.
2023-05-21 23:41:26 +10:00
impl<T: Fn(&Theme) -> rule::Appearance> rule::StyleSheet for T {
type Style = Theme;
fn appearance(&self, style: &Self::Style) -> rule::Appearance {
(self)(style)
}
}
/**
2022-12-06 04:44:37 +01:00
* Svg
*/
#[derive(Default)]
pub enum Svg {
/// No filtering to the rendered SVG.
#[default]
Default,
/// A custom style.
Custom(Box<dyn svg::StyleSheet<Style = Theme>>),
}
impl Svg {
/// Creates a custom [`Svg`] style.
pub fn custom_fn(f: fn(&Theme) -> svg::Appearance) -> Self {
Self::Custom(Box::new(f))
}
}
impl svg::StyleSheet for Theme {
type Style = Svg;
fn appearance(&self, style: &Self::Style) -> svg::Appearance {
match style {
2023-09-20 04:51:08 +02:00
Svg::Default => svg::Appearance::default(),
Svg::Custom(custom) => custom.appearance(self),
}
}
2023-12-12 14:02:15 +05:00
fn hovered(&self, style: &Self::Style) -> svg::Appearance {
self.appearance(style)
}
}
impl svg::StyleSheet for fn(&Theme) -> svg::Appearance {
type Style = Theme;
fn appearance(&self, style: &Self::Style) -> svg::Appearance {
(self)(style)
}
2023-12-12 14:02:15 +05:00
fn hovered(&self, style: &Self::Style) -> svg::Appearance {
self.appearance(style)
}
}
2022-11-10 01:10:28 +01:00
/// The style of a scrollable.
#[derive(Default)]
pub enum Scrollable {
2022-11-10 01:10:28 +01:00
/// The default style.
#[default]
Default,
2022-11-10 01:10:28 +01:00
/// A custom style.
Custom(Box<dyn scrollable::StyleSheet<Style = Theme>>),
}
impl Scrollable {
/// Creates a custom [`Scrollable`] theme.
pub fn custom<T: scrollable::StyleSheet<Style = Theme> + 'static>(
style: T,
) -> Self {
Self::Custom(Box::new(style))
}
}
impl scrollable::StyleSheet for Theme {
type Style = Scrollable;
fn active(&self, style: &Self::Style) -> scrollable::Scrollbar {
match style {
Scrollable::Default => {
let palette = self.extended_palette();
scrollable::Scrollbar {
background: Some(palette.background.weak.color.into()),
border: Border::with_radius(2),
scroller: scrollable::Scroller {
color: palette.background.strong.color,
border: Border::with_radius(2),
},
}
}
Scrollable::Custom(custom) => custom.active(self),
}
}
fn hovered(
&self,
style: &Self::Style,
is_mouse_over_scrollbar: bool,
) -> scrollable::Scrollbar {
match style {
Scrollable::Default => {
if is_mouse_over_scrollbar {
let palette = self.extended_palette();
scrollable::Scrollbar {
background: Some(palette.background.weak.color.into()),
border: Border::with_radius(2),
scroller: scrollable::Scroller {
color: palette.primary.strong.color,
border: Border::with_radius(2),
},
}
} else {
self.active(style)
}
}
Scrollable::Custom(custom) => {
custom.hovered(self, is_mouse_over_scrollbar)
}
}
}
fn dragging(&self, style: &Self::Style) -> scrollable::Scrollbar {
match style {
Scrollable::Default => self.hovered(style, true),
Scrollable::Custom(custom) => custom.dragging(self),
}
}
fn active_horizontal(&self, style: &Self::Style) -> scrollable::Scrollbar {
match style {
Scrollable::Default => self.active(style),
Scrollable::Custom(custom) => custom.active_horizontal(self),
}
}
fn hovered_horizontal(
&self,
style: &Self::Style,
is_mouse_over_scrollbar: bool,
) -> scrollable::Scrollbar {
match style {
Scrollable::Default => self.hovered(style, is_mouse_over_scrollbar),
Scrollable::Custom(custom) => {
custom.hovered_horizontal(self, is_mouse_over_scrollbar)
}
}
}
fn dragging_horizontal(
&self,
style: &Self::Style,
) -> scrollable::Scrollbar {
match style {
Scrollable::Default => self.hovered_horizontal(style, true),
Scrollable::Custom(custom) => custom.dragging_horizontal(self),
}
}
}
2022-11-10 01:10:28 +01:00
/// The style of text.
#[derive(Clone, Copy, Default)]
pub enum Text {
2022-11-10 01:10:28 +01:00
/// The default style.
#[default]
Default,
2022-11-10 01:10:28 +01:00
/// Colored text.
Color(Color),
}
impl From<Color> for Text {
fn from(color: Color) -> Self {
Text::Color(color)
}
}
impl text::StyleSheet for Theme {
type Style = Text;
fn appearance(&self, style: Self::Style) -> text::Appearance {
match style {
2023-09-20 04:51:08 +02:00
Text::Default => text::Appearance::default(),
Text::Color(c) => text::Appearance { color: Some(c) },
}
}
}
2022-11-10 01:10:28 +01:00
/// The style of a text input.
#[derive(Default)]
pub enum TextInput {
2022-11-10 01:10:28 +01:00
/// The default style.
#[default]
Default,
2022-11-10 01:10:28 +01:00
/// A custom style.
Custom(Box<dyn text_input::StyleSheet<Style = Theme>>),
}
impl text_input::StyleSheet for Theme {
type Style = TextInput;
fn active(&self, style: &Self::Style) -> text_input::Appearance {
if let TextInput::Custom(custom) = style {
return custom.active(self);
}
let palette = self.extended_palette();
text_input::Appearance {
background: palette.background.base.color.into(),
border: Border {
radius: 2.0.into(),
width: 1.0,
color: palette.background.strong.color,
},
icon_color: palette.background.weak.text,
}
}
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 {
background: palette.background.base.color.into(),
border: Border {
radius: 2.0.into(),
width: 1.0,
color: palette.background.base.text,
},
icon_color: palette.background.weak.text,
}
}
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 {
background: palette.background.base.color.into(),
border: Border {
radius: 2.0.into(),
width: 1.0,
color: palette.primary.strong.color,
},
icon_color: palette.background.weak.text,
}
}
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 {
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 {
if let TextInput::Custom(custom) = style {
return custom.selection_color(self);
}
let palette = self.extended_palette();
palette.primary.weak.color
}
fn disabled(&self, style: &Self::Style) -> text_input::Appearance {
if let TextInput::Custom(custom) = style {
return custom.disabled(self);
}
let palette = self.extended_palette();
text_input::Appearance {
background: palette.background.weak.color.into(),
border: Border {
radius: 2.0.into(),
width: 1.0,
color: palette.background.strong.color,
},
icon_color: palette.background.strong.color,
}
}
fn disabled_color(&self, style: &Self::Style) -> Color {
if let TextInput::Custom(custom) = style {
return custom.disabled_color(self);
}
self.placeholder_color(style)
}
}
/// The style of a text input.
#[derive(Default)]
pub enum TextEditor {
/// The default style.
#[default]
Default,
/// A custom style.
Custom(Box<dyn text_editor::StyleSheet<Style = Theme>>),
}
impl text_editor::StyleSheet for Theme {
type Style = TextEditor;
fn active(&self, style: &Self::Style) -> text_editor::Appearance {
if let TextEditor::Custom(custom) = style {
return custom.active(self);
}
let palette = self.extended_palette();
text_editor::Appearance {
background: palette.background.base.color.into(),
border: Border {
radius: 2.0.into(),
width: 1.0,
color: palette.background.strong.color,
},
}
}
fn hovered(&self, style: &Self::Style) -> text_editor::Appearance {
if let TextEditor::Custom(custom) = style {
return custom.hovered(self);
}
let palette = self.extended_palette();
text_editor::Appearance {
background: palette.background.base.color.into(),
border: Border {
radius: 2.0.into(),
width: 1.0,
color: palette.background.base.text,
},
}
}
fn focused(&self, style: &Self::Style) -> text_editor::Appearance {
if let TextEditor::Custom(custom) = style {
return custom.focused(self);
}
let palette = self.extended_palette();
text_editor::Appearance {
background: palette.background.base.color.into(),
border: Border {
radius: 2.0.into(),
width: 1.0,
color: palette.primary.strong.color,
},
}
}
fn placeholder_color(&self, style: &Self::Style) -> Color {
if let TextEditor::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 {
if let TextEditor::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 {
if let TextEditor::Custom(custom) = style {
return custom.selection_color(self);
}
let palette = self.extended_palette();
palette.primary.weak.color
}
fn disabled(&self, style: &Self::Style) -> text_editor::Appearance {
if let TextEditor::Custom(custom) = style {
return custom.disabled(self);
}
let palette = self.extended_palette();
text_editor::Appearance {
background: palette.background.weak.color.into(),
border: Border {
radius: 2.0.into(),
width: 1.0,
color: palette.background.strong.color,
},
}
}
fn disabled_color(&self, style: &Self::Style) -> Color {
if let TextEditor::Custom(custom) = style {
return custom.disabled_color(self);
}
self.placeholder_color(style)
}
}