diff options
| author | 2022-07-08 20:07:33 +0200 | |
|---|---|---|
| committer | 2022-07-08 20:07:33 +0200 | |
| commit | bb07d017e8c8e43ac74f66bf649643bebdc5f71d (patch) | |
| tree | 6e780f78ef4eae7dbe590a82ceef11e47289d953 | |
| parent | fa55dff61db47197a961152285c6a6abfab0b217 (diff) | |
| download | iced-bb07d017e8c8e43ac74f66bf649643bebdc5f71d.tar.gz iced-bb07d017e8c8e43ac74f66bf649643bebdc5f71d.tar.bz2 iced-bb07d017e8c8e43ac74f66bf649643bebdc5f71d.zip  | |
Add `Style` variant support to `application::StyleSheet`
Diffstat (limited to '')
| -rw-r--r-- | examples/integration_opengl/src/main.rs | 6 | ||||
| -rw-r--r-- | examples/integration_wgpu/src/main.rs | 6 | ||||
| -rw-r--r-- | examples/solar_system/src/main.rs | 11 | ||||
| -rw-r--r-- | glutin/src/application.rs | 15 | ||||
| -rw-r--r-- | native/src/program/state.rs | 6 | ||||
| -rw-r--r-- | native/src/user_interface.rs | 16 | ||||
| -rw-r--r-- | src/application.rs | 16 | ||||
| -rw-r--r-- | style/src/application.rs | 10 | ||||
| -rw-r--r-- | style/src/theme.rs | 26 | ||||
| -rw-r--r-- | winit/src/application.rs | 39 | ||||
| -rw-r--r-- | winit/src/application/state.rs | 40 | 
11 files changed, 148 insertions, 43 deletions
diff --git a/examples/integration_opengl/src/main.rs b/examples/integration_opengl/src/main.rs index cd46e9fd..1a78a493 100644 --- a/examples/integration_opengl/src/main.rs +++ b/examples/integration_opengl/src/main.rs @@ -12,7 +12,8 @@ use iced_glow::glow;  use iced_glow::{Backend, Renderer, Settings, Viewport};  use iced_glutin::conversion;  use iced_glutin::glutin; -use iced_glutin::{program, Clipboard, Debug, Size}; +use iced_glutin::renderer; +use iced_glutin::{program, Clipboard, Color, Debug, Size};  pub fn main() {      env_logger::init(); @@ -126,6 +127,9 @@ pub fn main() {                          ),                          &mut renderer,                          &iced_glow::Theme::Dark, +                        &renderer::Style { +                            text_color: Color::WHITE, +                        },                          &mut clipboard,                          &mut debug,                      ); diff --git a/examples/integration_wgpu/src/main.rs b/examples/integration_wgpu/src/main.rs index 1108b55d..3d27a0f0 100644 --- a/examples/integration_wgpu/src/main.rs +++ b/examples/integration_wgpu/src/main.rs @@ -5,7 +5,10 @@ use controls::Controls;  use scene::Scene;  use iced_wgpu::{wgpu, Backend, Renderer, Settings, Viewport}; -use iced_winit::{conversion, futures, program, winit, Clipboard, Debug, Size}; +use iced_winit::{ +    conversion, futures, program, renderer, winit, Clipboard, Color, Debug, +    Size, +};  use winit::{      dpi::PhysicalPosition, @@ -189,6 +192,7 @@ pub fn main() {                          ),                          &mut renderer,                          &iced_wgpu::Theme::Dark, +                        &renderer::Style { text_color: Color::WHITE },                          &mut clipboard,                          &mut debug,                      ); diff --git a/examples/solar_system/src/main.rs b/examples/solar_system/src/main.rs index 7e0e06b0..cee9a02f 100644 --- a/examples/solar_system/src/main.rs +++ b/examples/solar_system/src/main.rs @@ -6,13 +6,15 @@  //! Inspired by the example found in the MDN docs[1].  //!  //! [1]: https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Basic_animations#An_animated_solar_system +use iced::application;  use iced::canvas::{self, Cursor, Path, Stroke};  use iced::executor; +use iced::theme::{self, Theme};  use iced::time;  use iced::window;  use iced::{      Application, Canvas, Color, Command, Element, Length, Point, Rectangle, -    Settings, Size, Subscription, Theme, Vector, +    Settings, Size, Subscription, Vector,  };  use std::time::Instant; @@ -77,6 +79,13 @@ impl Application for SolarSystem {      fn theme(&self) -> Theme {          Theme::Dark      } + +    fn style(&self) -> theme::Application { +        theme::Application::Custom(|_theme| application::Appearance { +            background_color: Color::BLACK, +            text_color: Color::WHITE, +        }) +    }  }  #[derive(Debug)] diff --git a/glutin/src/application.rs b/glutin/src/application.rs index a222036a..dddf0067 100644 --- a/glutin/src/application.rs +++ b/glutin/src/application.rs @@ -10,6 +10,7 @@ use iced_winit::application;  use iced_winit::conversion;  use iced_winit::futures;  use iced_winit::futures::channel::mpsc; +use iced_winit::renderer;  use iced_winit::user_interface;  use iced_winit::{Clipboard, Debug, Proxy, Settings}; @@ -212,7 +213,6 @@ async fn run_instance<A, E, C>(      let mut state = application::State::new(&application, context.window());      let mut viewport_version = state.viewport_version(); -    let mut theme = application.theme();      let mut user_interface =          ManuallyDrop::new(application::build_user_interface( @@ -278,7 +278,6 @@ async fn run_instance<A, E, C>(                      let should_exit = application.should_exit(); -                    theme = application.theme();                      user_interface =                          ManuallyDrop::new(application::build_user_interface(                              &mut application, @@ -296,7 +295,10 @@ async fn run_instance<A, E, C>(                  debug.draw_started();                  let new_mouse_interaction = user_interface.draw(                      &mut renderer, -                    &theme, +                    state.theme(), +                    &renderer::Style { +                        text_color: state.text_color(), +                    },                      state.cursor_position(),                  );                  debug.draw_finished(); @@ -352,7 +354,10 @@ async fn run_instance<A, E, C>(                      debug.draw_started();                      let new_mouse_interaction = user_interface.draw(                          &mut renderer, -                        &theme, +                        state.theme(), +                        &renderer::Style { +                            text_color: state.text_color(), +                        },                          state.cursor_position(),                      );                      debug.draw_finished(); @@ -380,7 +385,7 @@ async fn run_instance<A, E, C>(                  compositor.present(                      &mut renderer,                      state.viewport(), -                    theme.background_color(), +                    state.background_color(),                      &debug.overlay(),                  ); diff --git a/native/src/program/state.rs b/native/src/program/state.rs index c881a64f..7ec2a04f 100644 --- a/native/src/program/state.rs +++ b/native/src/program/state.rs @@ -1,5 +1,6 @@  use crate::application;  use crate::mouse; +use crate::renderer;  use crate::user_interface::{self, UserInterface};  use crate::{Clipboard, Command, Debug, Event, Point, Program, Size}; @@ -89,6 +90,7 @@ where          cursor_position: Point,          renderer: &mut P::Renderer,          theme: &<P::Renderer as crate::Renderer>::Theme, +        style: &renderer::Style,          clipboard: &mut dyn Clipboard,          debug: &mut Debug,      ) -> Option<Command<P::Message>> { @@ -118,7 +120,7 @@ where          if messages.is_empty() {              debug.draw_started();              self.mouse_interaction = -                user_interface.draw(renderer, theme, cursor_position); +                user_interface.draw(renderer, theme, style, cursor_position);              debug.draw_finished();              self.cache = Some(user_interface.into_cache()); @@ -150,7 +152,7 @@ where              debug.draw_started();              self.mouse_interaction = -                user_interface.draw(renderer, theme, cursor_position); +                user_interface.draw(renderer, theme, style, cursor_position);              debug.draw_finished();              self.cache = Some(user_interface.into_cache()); diff --git a/native/src/user_interface.rs b/native/src/user_interface.rs index d682a880..97a004e7 100644 --- a/native/src/user_interface.rs +++ b/native/src/user_interface.rs @@ -303,8 +303,10 @@ where      /// [completing the last example](#example-1):      ///      /// ```no_run -    /// use iced_native::{clipboard, Size, Point, Theme}; +    /// use iced_native::clipboard; +    /// use iced_native::renderer;      /// use iced_native::user_interface::{self, UserInterface}; +    /// use iced_native::{Size, Point, Theme};      /// use iced_wgpu::Renderer;      ///      /// # mod iced_wgpu { @@ -351,7 +353,7 @@ where      ///     );      ///      ///     // Draw the user interface -    ///     let mouse_cursor = user_interface.draw(&mut renderer, &Theme::default(), cursor_position); +    ///     let mouse_cursor = user_interface.draw(&mut renderer, &Theme::default(), &renderer::Style::default(), cursor_position);      ///      ///     cache = user_interface.into_cache();      /// @@ -367,6 +369,7 @@ where          &mut self,          renderer: &mut Renderer,          theme: &Renderer::Theme, +        style: &renderer::Style,          cursor_position: Point,      ) -> mouse::Interaction {          // TODO: Move to shell level (?) @@ -399,12 +402,7 @@ where          self.root.widget.draw(              renderer,              theme, -            &renderer::Style { -                text_color: { -                    use application::StyleSheet; -                    theme.text_color() -                }, -            }, +            style,              Layout::new(&self.base),              base_cursor,              &viewport, @@ -446,7 +444,7 @@ where                          overlay.draw(                              renderer,                              theme, -                            &renderer::Style::default(), +                            style,                              Layout::new(layout),                              cursor_position,                          ); diff --git a/src/application.rs b/src/application.rs index b7c8cf9f..d4297eea 100644 --- a/src/application.rs +++ b/src/application.rs @@ -1,7 +1,7 @@  use crate::window;  use crate::{Command, Element, Executor, Settings, Subscription}; -pub use iced_native::application::StyleSheet; +pub use iced_native::application::{Appearance, StyleSheet};  /// An interactive cross-platform application.  /// @@ -141,10 +141,20 @@ pub trait Application: Sized {      fn view(&mut self) -> Element<'_, Self::Message, Self::Theme>;      /// Returns the current [`Theme`] of the [`Application`]. +    /// +    /// [`Theme`]: Self::Theme      fn theme(&self) -> Self::Theme {          Self::Theme::default()      } +    /// Returns the current [`Style`] of the [`Theme`]. +    /// +    /// [`Style`]: <Self::Theme as StyleSheet>::Style +    /// [`Theme`]: Self::Theme +    fn style(&self) -> <Self::Theme as StyleSheet>::Style { +        <Self::Theme as StyleSheet>::Style::default() +    } +      /// Returns the event [`Subscription`] for the current state of the      /// application.      /// @@ -260,6 +270,10 @@ where          self.0.theme()      } +    fn style(&self) -> <A::Theme as StyleSheet>::Style { +        self.0.style() +    } +      fn mode(&self) -> iced_winit::Mode {          match self.0.mode() {              window::Mode::Windowed => iced_winit::Mode::Windowed, diff --git a/style/src/application.rs b/style/src/application.rs index 4aa950fb..d48c6a34 100644 --- a/style/src/application.rs +++ b/style/src/application.rs @@ -1,7 +1,13 @@  use iced_core::Color;  pub trait StyleSheet { -    fn background_color(&self) -> Color; +    type Style: Default + Copy; -    fn text_color(&self) -> Color; +    fn appearance(&self, style: Self::Style) -> Appearance; +} + +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct Appearance { +    pub background_color: Color, +    pub text_color: Color,  } diff --git a/style/src/theme.rs b/style/src/theme.rs index 0bae671e..70b32edf 100644 --- a/style/src/theme.rs +++ b/style/src/theme.rs @@ -48,17 +48,31 @@ impl Default for Theme {      }  } -impl application::StyleSheet for Theme { -    fn background_color(&self) -> Color { -        let palette = self.extended_palette(); +#[derive(Debug, Clone, Copy)] +pub enum Application { +    Default, +    Custom(fn(Theme) -> application::Appearance), +} -        palette.background.base.color +impl Default for Application { +    fn default() -> Self { +        Self::Default      } +} -    fn text_color(&self) -> Color { +impl application::StyleSheet for Theme { +    type Style = Application; + +    fn appearance(&self, style: Self::Style) -> application::Appearance {          let palette = self.extended_palette(); -        palette.background.base.text +        match style { +            Application::Default => application::Appearance { +                background_color: palette.background.base.color, +                text_color: palette.background.base.text, +            }, +            Application::Custom(f) => f(*self), +        }      }  } diff --git a/winit/src/application.rs b/winit/src/application.rs index c7905c60..9c7dd74e 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -6,6 +6,7 @@ pub use state::State;  use crate::clipboard::{self, Clipboard};  use crate::conversion;  use crate::mouse; +use crate::renderer;  use crate::{      Command, Debug, Error, Executor, Mode, Proxy, Runtime, Settings, Size,      Subscription, @@ -18,7 +19,7 @@ use iced_graphics::window;  use iced_native::program::Program;  use iced_native::user_interface::{self, UserInterface}; -pub use iced_native::application::StyleSheet; +pub use iced_native::application::{Appearance, StyleSheet};  use std::mem::ManuallyDrop; @@ -33,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; @@ -54,7 +58,14 @@ pub trait Application: Program {      fn title(&self) -> String;      /// Returns the current [`Theme`] of the [`Application`]. -    fn theme(&self) -> <Self::Renderer as iced_native::Renderer>::Theme; +    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. @@ -110,7 +121,7 @@ where      A: Application + 'static,      E: Executor + 'static,      C: window::Compositor<Renderer = A::Renderer> + 'static, -    <A::Renderer as iced_native::Renderer>::Theme: StyleSheet, +    <A::Renderer as crate::Renderer>::Theme: StyleSheet,  {      use futures::task;      use futures::Future; @@ -246,7 +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 iced_native::Renderer>::Theme: StyleSheet, +    <A::Renderer as crate::Renderer>::Theme: StyleSheet,  {      use iced_futures::futures::stream::StreamExt;      use winit::event; @@ -255,7 +266,6 @@ async fn run_instance<A, E, C>(      let mut state = State::new(&application, &window);      let mut viewport_version = state.viewport_version(); -    let mut theme = application.theme();      let physical_size = state.physical_size(); @@ -328,7 +338,6 @@ async fn run_instance<A, E, C>(                      let should_exit = application.should_exit(); -                    theme = application.theme();                      user_interface = ManuallyDrop::new(build_user_interface(                          &mut application,                          cache, @@ -345,7 +354,10 @@ async fn run_instance<A, E, C>(                  debug.draw_started();                  let new_mouse_interaction = user_interface.draw(                      &mut renderer, -                    &theme, +                    state.theme(), +                    &renderer::Style { +                        text_color: state.text_color(), +                    },                      state.cursor_position(),                  );                  debug.draw_finished(); @@ -396,7 +408,10 @@ async fn run_instance<A, E, C>(                      debug.draw_started();                      let new_mouse_interaction = user_interface.draw(                          &mut renderer, -                        &theme, +                        state.theme(), +                        &renderer::Style { +                            text_color: state.text_color(), +                        },                          state.cursor_position(),                      ); @@ -422,7 +437,7 @@ async fn run_instance<A, E, C>(                      &mut renderer,                      &mut surface,                      state.viewport(), -                    theme.background_color(), +                    state.background_color(),                      &debug.overlay(),                  ) {                      Ok(()) => { @@ -531,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 34a9b10e..6b843919 100644 --- a/winit/src/application/state.rs +++ b/winit/src/application/state.rs @@ -1,13 +1,17 @@ +use crate::application::{self, StyleSheet as _};  use crate::conversion; -use crate::{Application, Debug, Mode, Point, Size, Viewport}; +use crate::{Application, Color, Debug, Mode, Point, Size, Viewport};  use std::marker::PhantomData;  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,      scale_factor: f64, @@ -15,15 +19,22 @@ pub struct State<A: Application> {      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 scale_factor = application.scale_factor(); +        let theme = application.theme(); +        let appearance = theme.appearance(application.style());          let viewport = {              let physical_size = window.inner_size(); @@ -43,6 +54,8 @@ impl<A: Application> State<A> {              // 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,          }      } @@ -87,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( @@ -192,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());      }  }  | 
