Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Nord, Dracula, Solarized and Gruvbox themes #2170

Merged
merged 8 commits into from
Feb 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `default` and `shift_step` methods for `slider` widgets. [#2100](https://github.com/iced-rs/iced/pull/2100)
- `Custom` variant to `command::Action`. [#2146](https://github.com/iced-rs/iced/pull/2146)
- Mouse movement events for `MouseArea`. [#2147](https://github.com/iced-rs/iced/pull/2147)
- Dracula, Nord, Solarized, and Gruvbox variants for `Theme`. [#2170](https://github.com/iced-rs/iced/pull/2170)

### Changed
- Enable WebGPU backend in `wgpu` by default instead of WebGL. [#2068](https://github.com/iced-rs/iced/pull/2068)
Expand Down Expand Up @@ -127,6 +128,7 @@ Many thanks to...
- @Tahinli
- @tarkah
- @tzemanovic
- @varbhat
- @william-shere

## [0.10.0] - 2023-07-28
Expand Down
18 changes: 9 additions & 9 deletions core/src/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,26 +179,26 @@ impl From<[f32; 4]> for Color {
#[macro_export]
macro_rules! color {
($r:expr, $g:expr, $b:expr) => {
$crate::Color::from_rgb8($r, $g, $b)
color!($r, $g, $b, 1.0)
};
($r:expr, $g:expr, $b:expr, $a:expr) => {
$crate::Color::from_rgba8($r, $g, $b, $a)
$crate::Color {
r: $r as f32 / 255.0,
g: $g as f32 / 255.0,
b: $b as f32 / 255.0,
a: $a,
}
};
($hex:expr) => {{
let hex = $hex as u32;
let r = (hex & 0xff0000) >> 16;
let g = (hex & 0xff00) >> 8;
let b = (hex & 0xff);

$crate::Color::from_rgb8(r as u8, g as u8, b as u8)
color!($hex, 1.0)
}};
($hex:expr, $a:expr) => {{
let hex = $hex as u32;
let r = (hex & 0xff0000) >> 16;
let g = (hex & 0xff00) >> 8;
let b = (hex & 0xff);

$crate::Color::from_rgba8(r as u8, g as u8, b as u8, $a)
color!(r, g, b, $a)
}};
}

Expand Down
61 changes: 16 additions & 45 deletions examples/styling/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use iced::theme::{self, Theme};
use iced::widget::{
button, checkbox, column, container, horizontal_rule, progress_bar, radio,
row, scrollable, slider, text, text_input, toggler, vertical_rule,
vertical_space,
button, checkbox, column, container, horizontal_rule, pick_list,
progress_bar, row, scrollable, slider, text, text_input, toggler,
vertical_rule, vertical_space,
};
use iced::{Alignment, Color, Element, Length, Sandbox, Settings};
use iced::{Alignment, Element, Length, Sandbox, Settings, Theme};

pub fn main() -> iced::Result {
Styling::run(Settings::default())
Expand All @@ -19,16 +18,9 @@ struct Styling {
toggler_value: bool,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
enum ThemeType {
Light,
Dark,
Custom,
}

#[derive(Debug, Clone)]
enum Message {
ThemeChanged(ThemeType),
ThemeChanged(Theme),
InputChanged(String),
ButtonPressed,
SliderChanged(f32),
Expand All @@ -50,20 +42,7 @@ impl Sandbox for Styling {
fn update(&mut self, message: Message) {
match message {
Message::ThemeChanged(theme) => {
self.theme = match theme {
ThemeType::Light => Theme::Light,
ThemeType::Dark => Theme::Dark,
ThemeType::Custom => Theme::custom(
String::from("Custom"),
theme::Palette {
background: Color::from_rgb(1.0, 0.9, 1.0),
text: Color::BLACK,
primary: Color::from_rgb(0.5, 0.5, 0.0),
success: Color::from_rgb(0.0, 1.0, 0.0),
danger: Color::from_rgb(1.0, 0.0, 0.0),
},
),
}
self.theme = theme;
}
Message::InputChanged(value) => self.input_value = value,
Message::ButtonPressed => {}
Expand All @@ -74,24 +53,16 @@ impl Sandbox for Styling {
}

fn view(&self) -> Element<Message> {
let choose_theme =
[ThemeType::Light, ThemeType::Dark, ThemeType::Custom]
.iter()
.fold(
column![text("Choose a theme:")].spacing(10),
|column, theme| {
column.push(radio(
format!("{theme:?}"),
*theme,
Some(match self.theme {
Theme::Light => ThemeType::Light,
Theme::Dark => ThemeType::Dark,
Theme::Custom { .. } => ThemeType::Custom,
}),
Message::ThemeChanged,
))
},
);
let choose_theme = column![
text("Theme:"),
pick_list(
Theme::ALL,
Some(self.theme.clone()),
Message::ThemeChanged
)
.width(Length::Fill),
]
.spacing(10);

let text_input = text_input("Type something...", &self.input_value)
.on_input(Message::InputChanged)
Expand Down
46 changes: 43 additions & 3 deletions style/src/theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use crate::core::{Background, Border, Color, Shadow, Vector};

use std::fmt;
use std::rc::Rc;
use std::sync::Arc;

/// A built-in theme.
#[derive(Debug, Clone, PartialEq, Default)]
Expand All @@ -34,13 +35,34 @@ pub enum Theme {
Light,
/// The built-in dark variant.
Dark,
/// The built-in Dracula variant.
Dracula,
/// The built-in Nord variant.
Nord,
/// The built-in Solarized Light variant.
SolarizedLight,
/// The built-in Solarized Dark variant.
SolarizedDark,
/// The built-in Gruvbox Light variant.
GruvboxLight,
/// The built-in Gruvbox Dark variant.
GruvboxDark,
/// A [`Theme`] that uses a [`Custom`] palette.
Custom(Box<Custom>),
Custom(Arc<Custom>),
}

impl Theme {
/// A list with all the defined themes.
pub const ALL: &'static [Self] = &[Self::Light, Self::Dark];
pub const ALL: &'static [Self] = &[
Self::Light,
Self::Dark,
Self::Dracula,
Self::Nord,
Self::SolarizedLight,
Self::SolarizedDark,
Self::GruvboxLight,
Self::GruvboxDark,
];

/// Creates a new custom [`Theme`] from the given [`Palette`].
pub fn custom(name: String, palette: Palette) -> Self {
Expand All @@ -54,14 +76,20 @@ impl Theme {
palette: Palette,
generate: impl FnOnce(Palette) -> palette::Extended,
) -> Self {
Self::Custom(Box::new(Custom::with_fn(name, palette, generate)))
Self::Custom(Arc::new(Custom::with_fn(name, palette, generate)))
}

/// Returns the [`Palette`] of the [`Theme`].
pub fn palette(&self) -> Palette {
match self {
Self::Light => Palette::LIGHT,
Self::Dark => Palette::DARK,
Self::Dracula => Palette::DRACULA,
Self::Nord => Palette::NORD,
Self::SolarizedLight => Palette::SOLARIZED_LIGHT,
Self::SolarizedDark => Palette::SOLARIZED_DARK,
Self::GruvboxLight => Palette::GRUVBOX_LIGHT,
Self::GruvboxDark => Palette::GRUVBOX_DARK,
Self::Custom(custom) => custom.palette,
}
}
Expand All @@ -71,6 +99,12 @@ impl Theme {
match self {
Self::Light => &palette::EXTENDED_LIGHT,
Self::Dark => &palette::EXTENDED_DARK,
Self::Dracula => &palette::EXTENDED_DRACULA,
Self::Nord => &palette::EXTENDED_NORD,
Self::SolarizedLight => &palette::EXTENDED_SOLARIZED_LIGHT,
Self::SolarizedDark => &palette::EXTENDED_SOLARIZED_DARK,
Self::GruvboxLight => &palette::EXTENDED_GRUVBOX_LIGHT,
Self::GruvboxDark => &palette::EXTENDED_GRUVBOX_DARK,
Self::Custom(custom) => &custom.extended,
}
}
Expand All @@ -81,6 +115,12 @@ impl fmt::Display for Theme {
match self {
Self::Light => write!(f, "Light"),
Self::Dark => write!(f, "Dark"),
Self::Dracula => write!(f, "Dracula"),
Self::Nord => write!(f, "Nord"),
Self::SolarizedLight => write!(f, "Solarized Light"),
Self::SolarizedDark => write!(f, "Solarized Dark"),
Self::GruvboxLight => write!(f, "Gruvbox Light"),
Self::GruvboxDark => write!(f, "Gruvbox Dark"),
Self::Custom(custom) => custom.fmt(f),
}
}
Expand Down
92 changes: 91 additions & 1 deletion style/src/theme/palette.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! Define the colors of a theme.
use iced_core::Color;
use crate::core::{color, Color};

use once_cell::sync::Lazy;
use palette::color_difference::Wcag21RelativeContrast;
Expand Down Expand Up @@ -67,6 +67,72 @@
0x3F as f32 / 255.0,
),
};

/// The built-in Dracula variant of a [`Palette`].
///
/// Source: https://draculatheme.com

Check warning on line 73 in style/src/theme/palette.rs

View workflow job for this annotation

GitHub Actions / all

this URL is not a hyperlink
pub const DRACULA: Self = Self {
background: color!(0x282A36), // BACKGROUND
text: color!(0xf8f8f2), // FOREGROUND
primary: color!(0xbd93f9), // PURPLE
success: color!(0x50fa7b), // GREEN
danger: color!(0xff5555), // RED
};

/// The built-in Nord variant of a [`Palette`].
///
/// Source: https://www.nordtheme.com/docs/colors-and-palettes

Check warning on line 84 in style/src/theme/palette.rs

View workflow job for this annotation

GitHub Actions / all

this URL is not a hyperlink
pub const NORD: Self = Self {
background: color!(0x2e3440), // nord0
text: color!(0xeceff4), // nord6
primary: color!(0x8fbcbb), // nord7
success: color!(0xa3be8c), // nord14
danger: color!(0xbf616a), // nord11
};

/// The built-in Solarized Light variant of a [`Palette`].
///
/// Source: https://ethanschoonover.com/solarized

Check warning on line 95 in style/src/theme/palette.rs

View workflow job for this annotation

GitHub Actions / all

this URL is not a hyperlink
pub const SOLARIZED_LIGHT: Self = Self {
background: color!(0xfdf6e3), // base3
text: color!(0x657b83), // base00
primary: color!(0x2aa198), // cyan
success: color!(0x859900), // green
danger: color!(0xdc322f), // red
};

/// The built-in Solarized Dark variant of a [`Palette`].
///
/// Source: https://ethanschoonover.com/solarized

Check warning on line 106 in style/src/theme/palette.rs

View workflow job for this annotation

GitHub Actions / all

this URL is not a hyperlink
pub const SOLARIZED_DARK: Self = Self {
background: color!(0x002b36), // base03
text: color!(0x839496), // base0
primary: color!(0x2aa198), // cyan
success: color!(0x859900), // green
danger: color!(0xdc322f), // red
};

/// The built-in Gruvbox Light variant of a [`Palette`].
///
/// Source: https://github.com/morhetz/gruvbox

Check warning on line 117 in style/src/theme/palette.rs

View workflow job for this annotation

GitHub Actions / all

this URL is not a hyperlink
pub const GRUVBOX_LIGHT: Self = Self {
background: color!(0xfbf1c7), // light BG_0
text: color!(0x282828), // light FG0_29
primary: color!(0x458588), // light BLUE_4
success: color!(0x98971a), // light GREEN_2
danger: color!(0xcc241d), // light RED_1
};

/// The built-in Gruvbox Dark variant of a [`Palette`].
///
/// Source: https://github.com/morhetz/gruvbox

Check warning on line 128 in style/src/theme/palette.rs

View workflow job for this annotation

GitHub Actions / all

this URL is not a hyperlink
pub const GRUVBOX_DARK: Self = Self {
background: color!(0x282828), // dark BG_0
text: color!(0xfbf1c7), // dark FG0_29
primary: color!(0x458588), // dark BLUE_4
success: color!(0x98971a), // dark GREEN_2
danger: color!(0xcc241d), // dark RED_1
};
}

/// An extended set of colors generated from a [`Palette`].
Expand Down Expand Up @@ -94,6 +160,30 @@
pub static EXTENDED_DARK: Lazy<Extended> =
Lazy::new(|| Extended::generate(Palette::DARK));

/// The built-in Dracula variant of an [`Extended`] palette.
pub static EXTENDED_DRACULA: Lazy<Extended> =
Lazy::new(|| Extended::generate(Palette::DRACULA));

/// The built-in Nord variant of an [`Extended`] palette.
pub static EXTENDED_NORD: Lazy<Extended> =
Lazy::new(|| Extended::generate(Palette::NORD));

/// The built-in Solarized Light variant of an [`Extended`] palette.
pub static EXTENDED_SOLARIZED_LIGHT: Lazy<Extended> =
Lazy::new(|| Extended::generate(Palette::SOLARIZED_LIGHT));

/// The built-in Solarized Dark variant of an [`Extended`] palette.
pub static EXTENDED_SOLARIZED_DARK: Lazy<Extended> =
Lazy::new(|| Extended::generate(Palette::SOLARIZED_DARK));

/// The built-in Gruvbox Light variant of an [`Extended`] palette.
pub static EXTENDED_GRUVBOX_LIGHT: Lazy<Extended> =
Lazy::new(|| Extended::generate(Palette::GRUVBOX_LIGHT));

/// The built-in Gruvbox Dark variant of an [`Extended`] palette.
pub static EXTENDED_GRUVBOX_DARK: Lazy<Extended> =
Lazy::new(|| Extended::generate(Palette::GRUVBOX_DARK));

impl Extended {
/// Generates an [`Extended`] palette from a simple [`Palette`].
pub fn generate(palette: Palette) -> Self {
Expand Down
Loading