use libflorescence::prelude::*;
use iced::{
advanced::widget::text,
border, color,
theme::{self, palette},
widget::{
button, container,
scrollable::{self, Rail},
text_editor,
},
window, Background, Border, Color,
};
const DARK_BLUE: Color = color!(0x010032);
const TEAL: Color = color!(0x3b8588);
const MAGENTA: Color = color!(0xe933f6);
const TURQOISE: Color = color!(0x75fad1);
// TODO not sure if I'll use this?
const PALETTE: theme::Palette = theme::Palette {
background: DARK_BLUE,
text: scale_rgb(TEAL, 1.),
primary: TURQOISE,
success: TURQOISE,
warning: MAGENTA,
danger: MAGENTA,
};
#[derive(Debug, Default)]
pub struct Theme;
#[derive(Debug, Clone, Copy)]
pub enum Button {
Normal,
Selected,
}
pub fn theme<S>(_state: &S, _window_id: window::Id) -> Theme {
Theme
}
impl theme::Base for Theme {
fn base(&self) -> theme::Style {
theme::Style {
background_color: PALETTE.background,
text_color: PALETTE.text,
}
}
fn palette(&self) -> Option<theme::Palette> {
Some(PALETTE)
}
}
impl button::Catalog for Theme {
type Class<'a> = Button;
fn default<'a>() -> Self::Class<'a> {
Button::Normal
}
fn style(
&self,
class: &Self::Class<'_>,
status: button::Status,
) -> button::Style {
let primary = palette::Primary::generate(
PALETTE.primary,
PALETTE.background,
PALETTE.text,
);
let base = button::Style {
background: Some(Background::Color(primary.base.color)),
text_color: primary.base.text,
border: border::rounded(2),
..button::Style::default()
};
let base = match status {
button::Status::Active | button::Status::Pressed => base,
button::Status::Hovered => button::Style {
background: Some(Background::Color(primary.strong.color)),
..base
},
button::Status::Disabled => button::Style {
background: base
.background
.map(|background| background.scale_alpha(0.5)),
text_color: base.text_color.scale_alpha(0.5),
..base
},
};
match class {
Button::Normal => button::Style {
border: Border {
color: Color::TRANSPARENT,
width: 1.0,
..default()
},
..base
},
Button::Selected => button::Style {
background: Some(Background::Color(MAGENTA)),
border: Border {
color: Color::WHITE,
width: 1.0,
..default()
},
..base
},
}
}
}
impl container::Catalog for Theme {
type Class<'a> = ();
fn default<'a>() -> Self::Class<'a> {
()
}
fn style(&self, class: &Self::Class<'_>) -> container::Style {
container::Style::default()
}
}
impl scrollable::Catalog for Theme {
type Class<'a> = ();
fn default<'a>() -> Self::Class<'a> {
()
}
fn style(
&self,
class: &Self::Class<'_>,
status: scrollable::Status,
) -> scrollable::Style {
let background =
palette::Background::new(PALETTE.background, PALETTE.text);
// TODO not same as default
let scrollbar = Rail {
background: Some(background.weak.color.into()),
border: border::rounded(2),
scroller: scrollable::Scroller {
color: background.strong.color,
border: border::rounded(2),
},
};
scrollable::Style {
container: container::Style::default(),
vertical_rail: scrollbar,
horizontal_rail: scrollbar,
gap: None,
}
}
}
impl text::Catalog for Theme {
type Class<'a> = ();
fn default<'a>() -> Self::Class<'a> {
()
}
fn style(&self, item: &Self::Class<'_>) -> text::Style {
text::Style { color: None }
}
}
impl text_editor::Catalog for Theme {
type Class<'a> = ();
fn default<'a>() -> Self::Class<'a> {
()
}
fn style(
&self,
class: &Self::Class<'_>,
status: text_editor::Status,
) -> text_editor::Style {
// TODO not same as default
let background =
palette::Background::new(PALETTE.background, PALETTE.text);
let primary = palette::Primary::generate(
PALETTE.primary,
PALETTE.background,
PALETTE.text,
);
let active = text_editor::Style {
background: Background::Color(background.base.color),
border: Border {
radius: 2.0.into(),
width: 1.0,
color: background.strong.color,
},
icon: background.weak.text,
placeholder: background.strong.color,
value: background.base.text,
selection: primary.weak.color,
};
active
}
}
// pub fn theme<S>(_state: &S, _window_id: window::Id) -> Theme {
// let text = scale_rgb(TEAL, 2.);
// Theme::custom(
// "Inflorescence".to_string(),
// theme::Palette {
// background: DARK_BLUE,
// text,
// primary: MAGENTA,
// success: TURQOISE,
// warning: MAGENTA,
// danger: MAGENTA,
// },
// )
// }
const fn scale_rgb(color: Color, scale: f32) -> Color {
let Color { r, g, b, a } = color;
Color {
r: r * scale,
g: g * scale,
b: b * scale,
a,
}
}