use iced::{container, radio, rule, scrollable}; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Theme { Light, Dark, } impl Theme { pub const ALL: [Theme; 2] = [Theme::Light, Theme::Dark]; } impl Default for Theme { fn default() -> Theme { Theme::Light } } impl<'a> From for Box { fn from(theme: Theme) -> Self { match theme { Theme::Light => Default::default(), Theme::Dark => dark::Container.into(), } } } impl<'a> From for Box { fn from(theme: Theme) -> Self { match theme { Theme::Light => Default::default(), Theme::Dark => dark::Radio.into(), } } } impl<'a> From for Box { fn from(theme: Theme) -> Self { match theme { Theme::Light => Default::default(), Theme::Dark => dark::Scrollable.into(), } } } impl From for Box { fn from(theme: Theme) -> Self { match theme { Theme::Light => Default::default(), Theme::Dark => dark::Rule.into(), } } } mod dark { use iced::{container, radio, rule, scrollable, Color}; const BACKGROUND: Color = Color::from_rgb( 0x36 as f32 / 255.0, 0x39 as f32 / 255.0, 0x3F as f32 / 255.0, ); const SURFACE: Color = Color::from_rgb( 0x40 as f32 / 255.0, 0x44 as f32 / 255.0, 0x4B as f32 / 255.0, ); const ACCENT: Color = Color::from_rgb( 0x6F as f32 / 255.0, 0xFF as f32 / 255.0, 0xE9 as f32 / 255.0, ); const ACTIVE: Color = Color::from_rgb( 0x72 as f32 / 255.0, 0x89 as f32 / 255.0, 0xDA as f32 / 255.0, ); const SCROLLBAR: Color = Color::from_rgb( 0x2E as f32 / 255.0, 0x33 as f32 / 255.0, 0x38 as f32 / 255.0, ); const SCROLLER: Color = Color::from_rgb( 0x20 as f32 / 255.0, 0x22 as f32 / 255.0, 0x25 as f32 / 255.0, ); pub struct Container; impl container::StyleSheet for Container { fn style(&self) -> container::Style { container::Style { background: Color { a: 0.99, ..BACKGROUND } .into(), text_color: Color::WHITE.into(), ..container::Style::default() } } } pub struct Radio; impl radio::StyleSheet for Radio { fn active(&self) -> radio::Style { radio::Style { background: SURFACE.into(), dot_color: ACTIVE, border_width: 1.0, border_color: ACTIVE, text_color: None, } } fn hovered(&self) -> radio::Style { radio::Style { background: Color { a: 0.5, ..SURFACE }.into(), ..self.active() } } } pub struct Scrollable; impl scrollable::StyleSheet for Scrollable { fn active(&self) -> scrollable::Scrollbar { scrollable::Scrollbar { background: Color { a: 0.8, ..SCROLLBAR } .into(), border_radius: 2.0, border_width: 0.0, border_color: Color::TRANSPARENT, scroller: scrollable::Scroller { color: Color { a: 0.7, ..SCROLLER }, border_radius: 2.0, border_width: 0.0, border_color: Color::TRANSPARENT, }, } } fn hovered(&self) -> scrollable::Scrollbar { let active = self.active(); scrollable::Scrollbar { background: SCROLLBAR.into(), scroller: scrollable::Scroller { color: SCROLLER, ..active.scroller }, ..active } } fn dragging(&self) -> scrollable::Scrollbar { let hovered = self.hovered(); scrollable::Scrollbar { scroller: scrollable::Scroller { color: ACCENT, ..hovered.scroller }, ..hovered } } } pub struct Rule; impl rule::StyleSheet for Rule { fn style(&self) -> rule::Style { rule::Style { color: SURFACE, width: 2, radius: 1.0, fill_mode: rule::FillMode::Percent(30.0), } } } }