use iced::widget::button::{self, Status, Style as ButtonStyle};
use iced::widget::container;
use iced::widget::text_input::{self, Style as TextInputStyle};
use iced::{Background, Border, Color, Shadow, Theme, Vector, border};
pub struct Typography;
impl Typography {
pub const TITLE_LARGE: f32 = 24.0;
pub const ICON_LARGE: f32 = 20.0;
pub const TITLE: f32 = 18.0;
pub const HEADING: f32 = 16.0;
pub const BODY: f32 = 14.0;
pub const SMALL: f32 = 13.0;
pub const CAPTION: f32 = 12.0;
}
pub struct Spacing;
impl Spacing {
pub const XS: f32 = 2.0;
pub const SM: f32 = 4.0;
pub const BUTTON_V: f32 = 6.0;
pub const MD: f32 = 8.0;
pub const LG: f32 = 12.0;
pub const XL: f32 = 16.0;
pub const XXL: f32 = 20.0;
pub const XXXL: f32 = 24.0;
}
pub struct Layout;
impl Layout {
pub const WINDOW_WIDTH: f32 = 800.0;
pub const WINDOW_HEIGHT: f32 = 565.0;
pub const EDITOR_WIDTH: f32 = 700.0;
pub const EDITOR_HEIGHT: f32 = 500.0;
}
pub struct BorderRadius;
impl BorderRadius {
pub const STANDARD: f32 = 6.0;
pub const LARGE: f32 = 8.0;
}
pub struct ColorPalette;
impl ColorPalette {
pub const BACKGROUND_PRIMARY: Color = Color::from_rgb(0.12, 0.12, 0.15); pub const BACKGROUND_SECONDARY: Color = Color::from_rgb(0.15, 0.15, 0.18); pub const BACKGROUND_TERTIARY: Color = Color::from_rgb(0.18, 0.18, 0.22);
pub const ACCENT_PRIMARY: Color = Color::from_rgb(0.27, 0.58, 0.92); pub const ACCENT_SECONDARY: Color = Color::from_rgb(0.20, 0.47, 0.82); pub const ACCENT_TERTIARY: Color = Color::from_rgb(0.15, 0.35, 0.65);
pub const TEXT_PRIMARY: Color = Color::from_rgb(0.95, 0.95, 0.95); pub const TEXT_SECONDARY: Color = Color::from_rgb(0.75, 0.75, 0.75); pub const TEXT_MUTED: Color = Color::from_rgb(0.55, 0.55, 0.55);
pub const SUCCESS: Color = Color::from_rgb(0.2, 0.8, 0.4); pub const WARNING: Color = Color::from_rgb(0.9, 0.7, 0.2); pub const ERROR: Color = Color::from_rgb(0.8, 0.3, 0.3);
pub const DANGER_HOVER: Color = Color::from_rgb(0.9, 0.2, 0.2);
pub const DANGER_BORDER: Color = Color::from_rgb(0.7, 0.2, 0.2);
pub const DANGER_BORDER_HOVER: Color = Color::from_rgb(0.6, 0.15, 0.15);
pub const BACKDROP_OVERLAY: Color = Color::from_rgba(0.0, 0.0, 0.0, 0.6);
pub const BORDER_LIGHT: Color = Color::from_rgb(0.35, 0.35, 0.35); pub const BORDER_DARK: Color = Color::from_rgb(0.25, 0.25, 0.25); }
pub struct CustomButtonStyles;
impl CustomButtonStyles {
pub fn primary() -> button::Style {
button::Style {
background: Some(Background::Color(ColorPalette::ACCENT_PRIMARY)),
text_color: ColorPalette::TEXT_PRIMARY,
border: Border {
color: ColorPalette::ACCENT_SECONDARY,
width: 1.0,
radius: border::Radius::from(BorderRadius::STANDARD),
},
shadow: Shadow {
color: Color::TRANSPARENT,
offset: Vector::new(0.0, 2.0),
blur_radius: 4.0,
},
snap: false,
}
}
pub fn primary_hovered() -> button::Style {
button::Style {
background: Some(Background::Color(ColorPalette::ACCENT_SECONDARY)),
text_color: ColorPalette::TEXT_PRIMARY,
border: Border {
color: ColorPalette::ACCENT_TERTIARY,
width: 1.0,
radius: border::Radius::from(BorderRadius::STANDARD),
},
shadow: Shadow {
color: Color::from_rgba(0.27, 0.58, 0.92, 0.3),
offset: Vector::new(0.0, 3.0),
blur_radius: 8.0,
},
snap: false,
}
}
pub fn primary_pressed() -> button::Style {
button::Style {
background: Some(Background::Color(ColorPalette::ACCENT_TERTIARY)),
text_color: ColorPalette::TEXT_PRIMARY,
border: Border {
color: ColorPalette::ACCENT_TERTIARY,
width: 1.0,
radius: border::Radius::from(BorderRadius::STANDARD),
},
shadow: Shadow {
color: Color::TRANSPARENT,
offset: Vector::new(0.0, 1.0),
blur_radius: 2.0,
},
snap: false,
}
}
pub fn secondary() -> button::Style {
button::Style {
background: Some(Background::Color(ColorPalette::BACKGROUND_TERTIARY)),
text_color: ColorPalette::TEXT_PRIMARY,
border: Border {
color: ColorPalette::BORDER_LIGHT,
width: 1.0,
radius: border::Radius::from(BorderRadius::STANDARD),
},
shadow: Shadow {
color: Color::TRANSPARENT,
offset: Vector::new(0.0, 1.0),
blur_radius: 2.0,
},
snap: false,
}
}
pub fn secondary_hovered() -> button::Style {
button::Style {
background: Some(Background::Color(ColorPalette::ACCENT_PRIMARY)),
text_color: ColorPalette::TEXT_PRIMARY,
border: Border {
color: ColorPalette::ACCENT_SECONDARY,
width: 1.0,
radius: border::Radius::from(BorderRadius::STANDARD),
},
shadow: Shadow {
color: Color::from_rgba(0.27, 0.58, 0.92, 0.2),
offset: Vector::new(0.0, 2.0),
blur_radius: 4.0,
},
snap: false,
}
}
pub fn secondary_pressed() -> button::Style {
button::Style {
background: Some(Background::Color(ColorPalette::ACCENT_SECONDARY)),
text_color: ColorPalette::TEXT_PRIMARY,
border: Border {
color: ColorPalette::ACCENT_TERTIARY,
width: 1.0,
radius: border::Radius::from(BorderRadius::STANDARD),
},
shadow: Shadow {
color: Color::TRANSPARENT,
offset: Vector::new(0.0, 1.0),
blur_radius: 2.0,
},
snap: false,
}
}
pub fn selected() -> button::Style {
button::Style {
background: Some(Background::Color(ColorPalette::ACCENT_PRIMARY)),
text_color: ColorPalette::TEXT_PRIMARY,
border: Border {
color: ColorPalette::ACCENT_SECONDARY,
width: 2.0,
radius: border::Radius::from(BorderRadius::STANDARD),
},
shadow: Shadow {
color: Color::from_rgba(0.27, 0.58, 0.92, 0.4),
offset: Vector::new(0.0, 2.0),
blur_radius: 6.0,
},
snap: false,
}
}
pub fn danger() -> button::Style {
button::Style {
background: Some(Background::Color(ColorPalette::ERROR)),
text_color: ColorPalette::TEXT_PRIMARY,
border: Border {
color: ColorPalette::DANGER_BORDER,
width: 1.0,
radius: border::Radius::from(BorderRadius::STANDARD),
},
shadow: Shadow {
color: Color::TRANSPARENT,
offset: Vector::new(0.0, 2.0),
blur_radius: 4.0,
},
snap: false,
}
}
pub fn danger_hovered() -> button::Style {
button::Style {
background: Some(Background::Color(ColorPalette::DANGER_HOVER)),
text_color: ColorPalette::TEXT_PRIMARY,
border: Border {
color: ColorPalette::DANGER_BORDER_HOVER,
width: 1.0,
radius: border::Radius::from(BorderRadius::STANDARD),
},
shadow: Shadow {
color: Color::from_rgba(0.8, 0.3, 0.3, 0.3),
offset: Vector::new(0.0, 3.0),
blur_radius: 8.0,
},
snap: false,
}
}
pub fn disabled() -> button::Style {
button::Style {
background: Some(Background::Color(ColorPalette::BACKGROUND_SECONDARY)),
text_color: ColorPalette::TEXT_MUTED,
border: Border {
color: ColorPalette::BORDER_DARK,
width: 1.0,
radius: border::Radius::from(BorderRadius::STANDARD),
},
shadow: Shadow {
color: Color::TRANSPARENT,
offset: Vector::new(0.0, 0.0),
blur_radius: 0.0,
},
snap: false,
}
}
}
pub struct CustomContainerStyles;
impl CustomContainerStyles {
pub fn panel() -> container::Style {
container::Style {
background: Some(Background::Color(ColorPalette::BACKGROUND_SECONDARY)),
border: Border {
color: ColorPalette::BORDER_LIGHT,
width: 1.0,
radius: border::Radius::from(BorderRadius::LARGE),
},
shadow: Shadow {
color: Color::from_rgba(0.0, 0.0, 0.0, 0.3),
offset: Vector::new(0.0, 4.0),
blur_radius: 12.0,
},
text_color: Some(ColorPalette::TEXT_PRIMARY),
snap: false,
}
}
pub fn status_section() -> container::Style {
container::Style {
background: Some(Background::Color(ColorPalette::BACKGROUND_TERTIARY)),
border: Border {
color: ColorPalette::BORDER_LIGHT,
width: 1.0,
radius: border::Radius::from(BorderRadius::STANDARD),
},
shadow: Shadow {
color: Color::from_rgba(0.0, 0.0, 0.0, 0.2),
offset: Vector::new(0.0, 2.0),
blur_radius: 6.0,
},
text_color: Some(ColorPalette::TEXT_PRIMARY),
snap: false,
}
}
pub fn status_connected() -> container::Style {
container::Style {
background: Some(Background::Color(ColorPalette::BACKGROUND_TERTIARY)),
border: Border {
color: ColorPalette::SUCCESS,
width: 2.0,
radius: border::Radius::from(BorderRadius::STANDARD),
},
shadow: Shadow {
color: Color::from_rgba(0.2, 0.8, 0.4, 0.2),
offset: Vector::new(0.0, 2.0),
blur_radius: 8.0,
},
text_color: Some(ColorPalette::TEXT_PRIMARY),
snap: false,
}
}
pub fn status_error() -> container::Style {
container::Style {
background: Some(Background::Color(ColorPalette::BACKGROUND_TERTIARY)),
border: Border {
color: ColorPalette::ERROR,
width: 2.0,
radius: border::Radius::from(BorderRadius::STANDARD),
},
shadow: Shadow {
color: Color::from_rgba(0.8, 0.3, 0.3, 0.2),
offset: Vector::new(0.0, 2.0),
blur_radius: 8.0,
},
text_color: Some(ColorPalette::TEXT_PRIMARY),
snap: false,
}
}
}
pub struct CustomTextInputStyle;
impl CustomTextInputStyle {
pub fn base() -> text_input::Style {
text_input::Style {
background: Background::Color(ColorPalette::BACKGROUND_TERTIARY),
border: Border {
color: ColorPalette::BORDER_LIGHT,
width: 1.0,
radius: border::Radius::from(BorderRadius::STANDARD),
},
icon: ColorPalette::TEXT_SECONDARY,
placeholder: ColorPalette::TEXT_MUTED,
value: ColorPalette::TEXT_PRIMARY,
selection: ColorPalette::ACCENT_SECONDARY,
}
}
pub fn focused() -> text_input::Style {
text_input::Style {
background: Background::Color(ColorPalette::BACKGROUND_TERTIARY),
border: Border {
color: ColorPalette::ACCENT_PRIMARY,
width: 2.0,
radius: border::Radius::from(BorderRadius::STANDARD),
},
icon: ColorPalette::ACCENT_PRIMARY,
placeholder: ColorPalette::TEXT_MUTED,
value: ColorPalette::TEXT_PRIMARY,
selection: ColorPalette::ACCENT_SECONDARY,
}
}
}
impl CustomButtonStyles {
pub fn primary_fn() -> impl Fn(&Theme, Status) -> ButtonStyle {
|_theme, status| match status {
Status::Active => Self::primary(),
Status::Hovered => Self::primary_hovered(),
Status::Pressed => Self::primary_pressed(),
Status::Disabled => Self::disabled(),
}
}
pub fn secondary_fn() -> impl Fn(&Theme, Status) -> ButtonStyle {
|_theme, status| match status {
Status::Active => Self::secondary(),
Status::Hovered => Self::secondary_hovered(),
Status::Pressed => Self::secondary_pressed(),
Status::Disabled => Self::disabled(),
}
}
pub fn selected_fn() -> impl Fn(&Theme, Status) -> ButtonStyle {
|_theme, _status| Self::selected()
}
pub fn danger_fn() -> impl Fn(&Theme, Status) -> ButtonStyle {
|_theme, status| match status {
Status::Active | Status::Pressed => Self::danger(),
Status::Hovered => Self::danger_hovered(),
Status::Disabled => Self::disabled(),
}
}
}
impl CustomTextInputStyle {
pub fn default_fn() -> impl Fn(&Theme, text_input::Status) -> TextInputStyle {
|_theme, status| match status {
text_input::Status::Active
| text_input::Status::Hovered
| text_input::Status::Disabled => Self::base(),
text_input::Status::Focused { .. } => Self::focused(),
}
}
}