diff --git a/core/Cargo.toml b/core/Cargo.toml index 2360e822..6e1f5ffb 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -23,6 +23,10 @@ xxhash-rust.workspace = true palette.workspace = true palette.optional = true +serde.workspace = true +serde.optional = true +serde.features = ["derive"] + [target.'cfg(windows)'.dependencies] raw-window-handle.workspace = true diff --git a/core/src/color.rs b/core/src/color.rs index b8db322f..a9a0aa55 100644 --- a/core/src/color.rs +++ b/core/src/color.rs @@ -3,6 +3,7 @@ use palette::rgb::{Srgb, Srgba}; /// A color in the `sRGB` color space. #[derive(Debug, Clone, Copy, PartialEq, Default)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Color { /// Red component, 0.0 - 1.0 pub r: f32, diff --git a/core/src/lib.rs b/core/src/lib.rs index 002336ee..e46e8726 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -9,11 +9,12 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" )] -#![forbid(unsafe_code, rust_2018_idioms)] +#![forbid(unsafe_code)] #![deny( missing_debug_implementations, missing_docs, unused_results, + rust_2018_idioms, rustdoc::broken_intra_doc_links )] pub mod alignment; diff --git a/debug/Cargo.toml b/debug/Cargo.toml index 77cabf6a..5f63fb90 100644 --- a/debug/Cargo.toml +++ b/debug/Cargo.toml @@ -11,10 +11,11 @@ categories.workspace = true keywords.workspace = true [features] -enable = ["iced_sentinel", "once_cell"] +enable = ["dep:iced_sentinel", "dep:once_cell"] [dependencies] iced_core.workspace = true +iced_style.workspace = true iced_sentinel.workspace = true iced_sentinel.optional = true diff --git a/debug/src/lib.rs b/debug/src/lib.rs index c02540ec..7bab52e9 100644 --- a/debug/src/lib.rs +++ b/debug/src/lib.rs @@ -1,4 +1,7 @@ pub use iced_core as core; +pub use iced_style as style; + +use crate::style::theme; pub use internal::Timer; @@ -6,6 +9,10 @@ pub fn open_axe() {} pub fn log_message(_message: &impl std::fmt::Debug) {} +pub fn theme_changed(palette: theme::Palette) { + internal::theme_changed(palette); +} + pub fn boot_time() -> Timer { internal::boot_time() } @@ -41,6 +48,7 @@ pub fn time(name: impl AsRef) -> Timer { #[cfg(feature = "enable")] mod internal { use crate::core::time::Instant; + use crate::style::theme; use iced_sentinel::client::{self, Client}; use iced_sentinel::timing::{self, Timing}; @@ -48,6 +56,10 @@ mod internal { use once_cell::sync::Lazy; use std::sync::{Mutex, MutexGuard}; + pub fn theme_changed(palette: theme::Palette) { + lock().sentinel.report_theme_change(palette); + } + pub fn boot_time() -> Timer { timer(timing::Stage::Boot) } @@ -120,6 +132,10 @@ mod internal { #[cfg(not(feature = "enable"))] mod internal { + use crate::style::theme; + + pub fn theme_changed(_palette: theme::Palette) {} + pub fn boot_time() -> Timer { Timer } diff --git a/sentinel/Cargo.toml b/sentinel/Cargo.toml index efb36659..c34c5048 100644 --- a/sentinel/Cargo.toml +++ b/sentinel/Cargo.toml @@ -12,6 +12,10 @@ keywords.workspace = true [dependencies] iced_core.workspace = true + +iced_style.workspace = true +iced_style.features = ["serde"] + serde_json.workspace = true futures.workspace = true log.workspace = true diff --git a/sentinel/src/client.rs b/sentinel/src/client.rs index ad1feb5d..5792dc85 100644 --- a/sentinel/src/client.rs +++ b/sentinel/src/client.rs @@ -1,3 +1,4 @@ +use crate::style::theme; use crate::{Input, Timing, SOCKET_ADDRESS}; use tokio::io::{self, AsyncWriteExt}; @@ -11,6 +12,10 @@ pub struct Client { } impl Client { + pub fn report_theme_change(&mut self, palette: theme::Palette) { + let _ = self.sender.try_send(Input::ThemeChanged(palette)); + } + pub fn report_timing(&mut self, timing: Timing) { let _ = self.sender.try_send(Input::TimingMeasured(timing)); } diff --git a/sentinel/src/lib.rs b/sentinel/src/lib.rs index 3d13c53d..c645ea49 100644 --- a/sentinel/src/lib.rs +++ b/sentinel/src/lib.rs @@ -1,8 +1,10 @@ pub use iced_core as core; +pub use iced_style as style; pub mod client; pub mod timing; +use crate::style::theme; use crate::timing::Timing; use futures::future; @@ -18,6 +20,7 @@ pub const SOCKET_ADDRESS: &str = "127.0.0.1:9167"; pub enum Input { Connected(Version), TimingMeasured(Timing), + ThemeChanged(theme::Palette), } #[derive(Debug, Clone)] @@ -25,6 +28,7 @@ pub enum Event { Connected(Version), Disconnected, TimingMeasured(Timing), + ThemeChanged(theme::Palette), } pub fn run() -> impl Stream { @@ -87,6 +91,9 @@ async fn receive( Input::TimingMeasured(timing) => { Event::TimingMeasured(timing) } + Input::ThemeChanged(palette) => { + Event::ThemeChanged(palette) + } }, )) } diff --git a/style/Cargo.toml b/style/Cargo.toml index 3f00e787..9f28c670 100644 --- a/style/Cargo.toml +++ b/style/Cargo.toml @@ -10,9 +10,16 @@ homepage.workspace = true categories.workspace = true keywords.workspace = true +[features] +serde = ["dep:serde", "iced_core/serde"] + [dependencies] iced_core.workspace = true iced_core.features = ["palette"] palette.workspace = true once_cell.workspace = true + +serde.workspace = true +serde.optional = true +serde.features = ["derive"] diff --git a/style/src/application.rs b/style/src/application.rs index e9a1f4ff..db9a673a 100644 --- a/style/src/application.rs +++ b/style/src/application.rs @@ -1,5 +1,6 @@ //! Change the appearance of an application. -use iced_core::Color; +use crate::core::Color; +use crate::theme; /// A set of rules that dictate the style of an application. pub trait StyleSheet { @@ -10,6 +11,17 @@ pub trait StyleSheet { /// /// [`Style`]: Self::Style fn appearance(&self, style: &Self::Style) -> Appearance; + + /// Returns the [`theme::Palette`] of the application, if any. + /// + /// This may be used by other parts of the `iced` runtime to + /// try to match the style of your application. + /// + /// For instance, the Iced Axe uses this [`theme::Palette`] to + /// automatically style itself using your application's colors. + fn palette(&self) -> Option { + None + } } /// The appearance of an application. diff --git a/style/src/lib.rs b/style/src/lib.rs index 3c2865eb..67fcad52 100644 --- a/style/src/lib.rs +++ b/style/src/lib.rs @@ -7,11 +7,12 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" )] -#![forbid(unsafe_code, rust_2018_idioms)] +#![forbid(unsafe_code)] #![deny( unused_results, missing_docs, unused_results, + rust_2018_idioms, rustdoc::broken_intra_doc_links )] pub use iced_core as core; diff --git a/style/src/theme/palette.rs b/style/src/theme/palette.rs index 15a964cd..74a8253a 100644 --- a/style/src/theme/palette.rs +++ b/style/src/theme/palette.rs @@ -8,6 +8,7 @@ use palette::{FromColor, Hsl, Mix}; /// A color palette. #[derive(Debug, Clone, Copy, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Palette { /// The background [`Color`] of the [`Palette`]. pub background: Color, diff --git a/winit/src/application/state.rs b/winit/src/application/state.rs index 14c4507f..b70d8dc2 100644 --- a/winit/src/application/state.rs +++ b/winit/src/application/state.rs @@ -2,6 +2,7 @@ use crate::application::{self, StyleSheet as _}; use crate::conversion; use crate::core::mouse; use crate::core::{Color, Size}; +use crate::debug; use crate::graphics::Viewport; use crate::Application; @@ -37,6 +38,8 @@ where let theme = application.theme(); let appearance = theme.appearance(&application.style()); + let _ = theme.palette().map(debug::theme_changed); + let viewport = { let physical_size = window.inner_size(); @@ -211,5 +214,7 @@ where // Update theme and appearance self.theme = application.theme(); self.appearance = self.theme.appearance(&application.style()); + + let _ = self.theme.palette().map(debug::theme_changed); } }