diff options
author | 2022-07-09 02:28:52 +0200 | |
---|---|---|
committer | 2022-07-09 02:28:52 +0200 | |
commit | e053e25d2ccb17f7a162685a106a8bbd915a873f (patch) | |
tree | 5304f3ea2712e8889c7278ec5e57418f484d8f6c /winit/src | |
parent | 66eb6263003c1bbedd1fd14d6b12f172d20a6211 (diff) | |
parent | 7105db97a53d90adf429091298f31c90974d8f08 (diff) | |
download | iced-e053e25d2ccb17f7a162685a106a8bbd915a873f.tar.gz iced-e053e25d2ccb17f7a162685a106a8bbd915a873f.tar.bz2 iced-e053e25d2ccb17f7a162685a106a8bbd915a873f.zip |
Merge pull request #1362 from iced-rs/theming
Theming
Diffstat (limited to 'winit/src')
-rw-r--r-- | winit/src/application.rs | 60 | ||||
-rw-r--r-- | winit/src/application/state.rs | 49 |
2 files changed, 79 insertions, 30 deletions
diff --git a/winit/src/application.rs b/winit/src/application.rs index 90b03d56..9c7dd74e 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -6,9 +6,10 @@ pub use state::State; use crate::clipboard::{self, Clipboard}; use crate::conversion; use crate::mouse; +use crate::renderer; use crate::{ - Color, Command, Debug, Error, Executor, Mode, Proxy, Runtime, Settings, - Size, Subscription, + Command, Debug, Error, Executor, Mode, Proxy, Runtime, Settings, Size, + Subscription, }; use iced_futures::futures; @@ -18,6 +19,8 @@ use iced_graphics::window; use iced_native::program::Program; use iced_native::user_interface::{self, UserInterface}; +pub use iced_native::application::{Appearance, StyleSheet}; + use std::mem::ManuallyDrop; /// An interactive, native cross-platform application. @@ -31,7 +34,10 @@ use std::mem::ManuallyDrop; /// /// When using an [`Application`] with the `debug` feature enabled, a debug view /// can be toggled by pressing `F12`. -pub trait Application: Program { +pub trait Application: Program +where + <Self::Renderer as crate::Renderer>::Theme: StyleSheet, +{ /// The data needed to initialize your [`Application`]. type Flags; @@ -51,6 +57,16 @@ pub trait Application: Program { /// title of your application when necessary. fn title(&self) -> String; + /// Returns the current [`Theme`] of the [`Application`]. + fn theme(&self) -> <Self::Renderer as crate::Renderer>::Theme; + + /// Returns the [`Style`] variation of the [`Theme`]. + fn style( + &self, + ) -> <<Self::Renderer as crate::Renderer>::Theme as StyleSheet>::Style { + Default::default() + } + /// Returns the event `Subscription` for the current state of the /// application. /// @@ -74,13 +90,6 @@ pub trait Application: Program { Mode::Windowed } - /// Returns the background [`Color`] of the [`Application`]. - /// - /// By default, it returns [`Color::WHITE`]. - fn background_color(&self) -> Color { - Color::WHITE - } - /// Returns the scale factor of the [`Application`]. /// /// It can be used to dynamically control the size of the UI at runtime @@ -112,6 +121,7 @@ where A: Application + 'static, E: Executor + 'static, C: window::Compositor<Renderer = A::Renderer> + 'static, + <A::Renderer as crate::Renderer>::Theme: StyleSheet, { use futures::task; use futures::Future; @@ -247,6 +257,7 @@ async fn run_instance<A, E, C>( A: Application + 'static, E: Executor + 'static, C: window::Compositor<Renderer = A::Renderer> + 'static, + <A::Renderer as crate::Renderer>::Theme: StyleSheet, { use iced_futures::futures::stream::StreamExt; use winit::event; @@ -341,8 +352,14 @@ async fn run_instance<A, E, C>( } debug.draw_started(); - let new_mouse_interaction = - user_interface.draw(&mut renderer, state.cursor_position()); + let new_mouse_interaction = user_interface.draw( + &mut renderer, + state.theme(), + &renderer::Style { + text_color: state.text_color(), + }, + state.cursor_position(), + ); debug.draw_finished(); if new_mouse_interaction != mouse_interaction { @@ -389,8 +406,14 @@ async fn run_instance<A, E, C>( debug.layout_finished(); debug.draw_started(); - let new_mouse_interaction = user_interface - .draw(&mut renderer, state.cursor_position()); + let new_mouse_interaction = user_interface.draw( + &mut renderer, + state.theme(), + &renderer::Style { + text_color: state.text_color(), + }, + state.cursor_position(), + ); if new_mouse_interaction != mouse_interaction { window.set_cursor_icon(conversion::mouse_interaction( @@ -497,7 +520,10 @@ pub fn build_user_interface<'a, A: Application>( renderer: &mut A::Renderer, size: Size, debug: &mut Debug, -) -> UserInterface<'a, A::Message, A::Renderer> { +) -> UserInterface<'a, A::Message, A::Renderer> +where + <A::Renderer as crate::Renderer>::Theme: StyleSheet, +{ debug.view_started(); let view = application.view(); debug.view_finished(); @@ -520,7 +546,9 @@ pub fn update<A: Application, E: Executor>( messages: &mut Vec<A::Message>, window: &winit::window::Window, graphics_info: impl FnOnce() -> compositor::Information + Copy, -) { +) where + <A::Renderer as crate::Renderer>::Theme: StyleSheet, +{ for message in messages.drain(..) { debug.log_message(&message); diff --git a/winit/src/application/state.rs b/winit/src/application/state.rs index b54d3aed..6b843919 100644 --- a/winit/src/application/state.rs +++ b/winit/src/application/state.rs @@ -1,3 +1,4 @@ +use crate::application::{self, StyleSheet as _}; use crate::conversion; use crate::{Application, Color, Debug, Mode, Point, Size, Viewport}; @@ -6,26 +7,34 @@ use winit::event::{Touch, WindowEvent}; use winit::window::Window; /// The state of a windowed [`Application`]. -#[derive(Debug, Clone)] -pub struct State<A: Application> { +#[allow(missing_debug_implementations)] +pub struct State<A: Application> +where + <A::Renderer as crate::Renderer>::Theme: application::StyleSheet, +{ title: String, mode: Mode, - background_color: Color, scale_factor: f64, viewport: Viewport, viewport_version: usize, cursor_position: winit::dpi::PhysicalPosition<f64>, modifiers: winit::event::ModifiersState, + theme: <A::Renderer as crate::Renderer>::Theme, + appearance: application::Appearance, application: PhantomData<A>, } -impl<A: Application> State<A> { +impl<A: Application> State<A> +where + <A::Renderer as crate::Renderer>::Theme: application::StyleSheet, +{ /// Creates a new [`State`] for the provided [`Application`] and window. pub fn new(application: &A, window: &Window) -> Self { let title = application.title(); let mode = application.mode(); - let background_color = application.background_color(); let scale_factor = application.scale_factor(); + let theme = application.theme(); + let appearance = theme.appearance(application.style()); let viewport = { let physical_size = window.inner_size(); @@ -39,22 +48,18 @@ impl<A: Application> State<A> { Self { title, mode, - background_color, scale_factor, viewport, viewport_version: 0, // TODO: Encode cursor availability in the type-system cursor_position: winit::dpi::PhysicalPosition::new(-1.0, -1.0), modifiers: winit::event::ModifiersState::default(), + theme, + appearance, application: PhantomData, } } - /// Returns the current background [`Color`] of the [`State`]. - pub fn background_color(&self) -> Color { - self.background_color - } - /// Returns the current [`Viewport`] of the [`State`]. pub fn viewport(&self) -> &Viewport { &self.viewport @@ -95,6 +100,21 @@ impl<A: Application> State<A> { self.modifiers } + /// Returns the current theme of the [`State`]. + pub fn theme(&self) -> &<A::Renderer as crate::Renderer>::Theme { + &self.theme + } + + /// Returns the current background [`Color`] of the [`State`]. + pub fn background_color(&self) -> Color { + self.appearance.background_color + } + + /// Returns the current text [`Color`] of the [`State`]. + pub fn text_color(&self) -> Color { + self.appearance.text_color + } + /// Processes the provided window event and updates the [`State`] /// accordingly. pub fn update( @@ -187,9 +207,6 @@ impl<A: Application> State<A> { self.mode = new_mode; } - // Update background color - self.background_color = application.background_color(); - // Update scale factor let new_scale_factor = application.scale_factor(); @@ -203,5 +220,9 @@ impl<A: Application> State<A> { self.scale_factor = new_scale_factor; } + + // Update theme and appearance + self.theme = application.theme(); + self.appearance = self.theme.appearance(application.style()); } } |