mod palette;
pub use self::palette::Palette;
use crate::application;
use crate::button;
use crate::radio;
use crate::slider;
use iced_core::{Background, Color};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Theme {
Light,
Dark,
}
impl Theme {
pub fn palette(self) -> Palette {
match self {
Self::Light => Palette::LIGHT,
Self::Dark => Palette::DARK,
}
}
fn extended_palette(&self) -> &palette::Extended {
match self {
Self::Light => &palette::EXTENDED_LIGHT,
Self::Dark => &palette::EXTENDED_DARK,
}
}
}
impl Default for Theme {
fn default() -> Self {
Self::Light
}
}
impl application::StyleSheet for Theme {
fn background_color(&self) -> Color {
let palette = self.extended_palette();
palette.background.base.color
}
fn text_color(&self) -> Color {
let palette = self.extended_palette();
palette.background.base.text
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Button {
Primary,
Secondary,
Positive,
Destructive,
Text,
}
impl Default for Button {
fn default() -> Self {
Self::Primary
}
}
impl button::StyleSheet for Theme {
type Style = Button;
fn active(&self, style: Self::Style) -> button::Appearance {
let palette = self.extended_palette();
let appearance = button::Appearance {
border_radius: 2.0,
..button::Appearance::default()
};
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
},
}
}
fn hovered(&self, style: Self::Style) -> button::Appearance {
let active = self.active(style);
let palette = self.extended_palette();
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::Appearance {
background: background.map(Background::from),
..active
}
}
}
impl slider::StyleSheet for Theme {
type Style = ();
fn active(&self, _style: Self::Style) -> slider::Appearance {
let palette = self.extended_palette();
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
},
}
}
fn hovered(&self, style: Self::Style) -> slider::Appearance {
let active = self.active(style);
let palette = self.extended_palette();
slider::Appearance {
handle: slider::Handle {
color: palette.primary.weak.color,
..active.handle
},
..active
}
}
fn dragging(&self, style: Self::Style) -> slider::Appearance {
let active = self.active(style);
let palette = self.extended_palette();
slider::Appearance {
handle: slider::Handle {
color: palette.primary.base.color,
..active.handle
},
..active
}
}
}
impl radio::StyleSheet for Theme {
type Style = ();
fn active(&self, _style: Self::Style) -> radio::Appearance {
let palette = self.extended_palette();
radio::Appearance {
background: Color::TRANSPARENT.into(),
dot_color: palette.primary.strong.color.into(),
border_width: 1.0,
border_color: palette.primary.strong.color,
text_color: None,
}
}
fn hovered(&self, style: Self::Style) -> radio::Appearance {
let active = self.active(style);
let palette = self.extended_palette();
radio::Appearance {
dot_color: palette.primary.weak.text.into(),
background: palette.primary.weak.color.into(),
..active
}
}
}