summaryrefslogtreecommitdiffstats
path: root/winit/src
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón <hector0193@gmail.com>2022-07-09 02:28:52 +0200
committerLibravatar GitHub <noreply@github.com>2022-07-09 02:28:52 +0200
commite053e25d2ccb17f7a162685a106a8bbd915a873f (patch)
tree5304f3ea2712e8889c7278ec5e57418f484d8f6c /winit/src
parent66eb6263003c1bbedd1fd14d6b12f172d20a6211 (diff)
parent7105db97a53d90adf429091298f31c90974d8f08 (diff)
downloadiced-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.rs60
-rw-r--r--winit/src/application/state.rs49
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());
}
}