Draft first-class Theme support

RFC: https://github.com/iced-rs/rfcs/pull/6
This commit is contained in:
Héctor Ramón Jiménez 2022-05-14 01:47:55 +02:00
parent 5de337f214
commit 664251f3f5
No known key found for this signature in database
GPG key ID: 140CC052C94F138E
113 changed files with 767 additions and 878 deletions

View file

@ -21,6 +21,9 @@ pub trait Application: Sized {
/// The type of __messages__ your [`Application`] will produce.
type Message: std::fmt::Debug + Send;
/// The theme of your [`Application`].
type Theme: Default;
/// The data needed to initialize your [`Application`].
type Flags;
@ -51,6 +54,16 @@ pub trait Application: Sized {
/// Any [`Command`] returned will be executed immediately in the background.
fn update(&mut self, message: Self::Message) -> Command<Self::Message>;
/// Returns the widgets to display in the [`Application`].
///
/// These widgets can produce __messages__ based on user interaction.
fn view(&self) -> pure::Element<'_, Self::Message, Self::Theme>;
/// Returns the current [`Theme`] of the [`Application`].
fn theme(&self) -> Self::Theme {
Self::Theme::default()
}
/// Returns the event [`Subscription`] for the current state of the
/// application.
///
@ -63,11 +76,6 @@ pub trait Application: Sized {
Subscription::none()
}
/// Returns the widgets to display in the [`Application`].
///
/// These widgets can produce __messages__ based on user interaction.
fn view(&self) -> pure::Element<'_, Self::Message>;
/// Returns the current [`Application`] mode.
///
/// The runtime will automatically transition your application if a new mode
@ -137,6 +145,7 @@ where
type Executor = A::Executor;
type Message = A::Message;
type Flags = A::Flags;
type Theme = A::Theme;
fn new(flags: Self::Flags) -> (Self, Command<Self::Message>) {
let (application, command) = A::new(flags);
@ -162,12 +171,16 @@ where
A::subscription(&self.application)
}
fn view(&mut self) -> crate::Element<'_, Self::Message> {
fn view(&mut self) -> crate::Element<'_, Self::Message, Self::Theme> {
let content = A::view(&self.application);
Pure::new(&mut self.state, content).into()
}
fn theme(&self) -> Self::Theme {
A::theme(&self.application)
}
fn mode(&self) -> window::Mode {
A::mode(&self.application)
}

View file

@ -1,5 +1,5 @@
use crate::pure;
use crate::{Color, Command, Error, Settings, Subscription};
use crate::{Color, Command, Error, Settings, Subscription, Theme};
/// A pure version of [`Sandbox`].
///
@ -34,6 +34,16 @@ pub trait Sandbox {
/// These widgets can produce __messages__ based on user interaction.
fn view(&self) -> pure::Element<'_, Self::Message>;
/// Returns the current [`Theme`] of the [`Sandbox`].
///
/// If you want to use your own custom theme type, you will have to use an
/// [`Application`].
///
/// By default, it returns [`Theme::default`].
fn theme(&self) -> Theme {
Theme::default()
}
/// Returns the background color of the [`Sandbox`].
///
/// By default, it returns [`Color::WHITE`].
@ -82,6 +92,7 @@ where
type Executor = iced_futures::backend::null::Executor;
type Flags = ();
type Message = T::Message;
type Theme = Theme;
fn new(_flags: ()) -> (Self, Command<T::Message>) {
(T::new(), Command::none())
@ -97,14 +108,18 @@ where
Command::none()
}
fn subscription(&self) -> Subscription<T::Message> {
Subscription::none()
}
fn view(&self) -> pure::Element<'_, T::Message> {
T::view(self)
}
fn theme(&self) -> Self::Theme {
T::theme(self)
}
fn subscription(&self) -> Subscription<T::Message> {
Subscription::none()
}
fn background_color(&self) -> Color {
T::background_color(self)
}

View file

@ -1,23 +1,24 @@
//! Pure versions of the widgets.
/// A container that distributes its contents vertically.
pub type Column<'a, Message> =
iced_pure::widget::Column<'a, Message, crate::Renderer>;
pub type Column<'a, Message, Theme = crate::Theme> =
iced_pure::widget::Column<'a, Message, crate::Renderer<Theme>>;
/// A container that distributes its contents horizontally.
pub type Row<'a, Message> =
iced_pure::widget::Row<'a, Message, crate::Renderer>;
pub type Row<'a, Message, Theme = crate::Theme> =
iced_pure::widget::Row<'a, Message, crate::Renderer<Theme>>;
/// A paragraph of text.
pub type Text = iced_pure::widget::Text<crate::Renderer>;
pub type Text<Theme = crate::Theme> =
iced_pure::widget::Text<crate::Renderer<Theme>>;
pub mod button {
//! Allow your users to perform actions by pressing a button.
pub use iced_pure::widget::button::{Style, StyleSheet};
/// A widget that produces a message when clicked.
pub type Button<'a, Message> =
iced_pure::widget::Button<'a, Message, crate::Renderer>;
pub type Button<'a, Message, Theme = crate::Theme> =
iced_pure::widget::Button<'a, Message, crate::Renderer<Theme>>;
}
pub mod checkbox {
@ -25,8 +26,8 @@ pub mod checkbox {
pub use iced_pure::widget::checkbox::{Style, StyleSheet};
/// A box that can be checked.
pub type Checkbox<'a, Message> =
iced_native::widget::Checkbox<'a, Message, crate::Renderer>;
pub type Checkbox<'a, Message, Theme> =
iced_native::widget::Checkbox<'a, Message, crate::Renderer<Theme>>;
}
pub mod container {
@ -34,8 +35,8 @@ pub mod container {
pub use iced_pure::widget::container::{Style, StyleSheet};
/// An element decorating some content.
pub type Container<'a, Message> =
iced_pure::widget::Container<'a, Message, crate::Renderer>;
pub type Container<'a, Message, Theme = crate::Theme> =
iced_pure::widget::Container<'a, Message, crate::Renderer<Theme>>;
}
pub mod pane_grid {
@ -57,16 +58,24 @@ pub mod pane_grid {
/// to completely fill the space available.
///
/// [![Pane grid - Iced](https://thumbs.gfycat.com/MixedFlatJellyfish-small.gif)](https://gfycat.com/mixedflatjellyfish)
pub type PaneGrid<'a, Message> =
iced_pure::widget::PaneGrid<'a, Message, crate::Renderer>;
pub type PaneGrid<'a, Message, Theme> =
iced_pure::widget::PaneGrid<'a, Message, crate::Renderer<Theme>>;
/// The content of a [`Pane`].
pub type Content<'a, Message> =
iced_pure::widget::pane_grid::Content<'a, Message, crate::Renderer>;
pub type Content<'a, Message, Theme> =
iced_pure::widget::pane_grid::Content<
'a,
Message,
crate::Renderer<Theme>,
>;
/// The title bar of a [`Pane`].
pub type TitleBar<'a, Message> =
iced_pure::widget::pane_grid::TitleBar<'a, Message, crate::Renderer>;
pub type TitleBar<'a, Message, Theme> =
iced_pure::widget::pane_grid::TitleBar<
'a,
Message,
crate::Renderer<Theme>,
>;
}
pub mod pick_list {
@ -75,8 +84,8 @@ pub mod pick_list {
pub use iced_pure::widget::pick_list::{Style, StyleSheet};
/// A widget allowing the selection of a single value from a list of options.
pub type PickList<'a, T, Message> =
iced_pure::widget::PickList<'a, T, Message, crate::Renderer>;
pub type PickList<'a, T, Message, Theme> =
iced_pure::widget::PickList<'a, T, Message, crate::Renderer<Theme>>;
}
pub mod radio {
@ -84,8 +93,8 @@ pub mod radio {
pub use iced_pure::widget::radio::{Style, StyleSheet};
/// A circular button representing a choice.
pub type Radio<'a, Message> =
iced_pure::widget::Radio<'a, Message, crate::Renderer>;
pub type Radio<'a, Message, Theme> =
iced_pure::widget::Radio<'a, Message, crate::Renderer<Theme>>;
}
pub mod scrollable {
@ -94,8 +103,8 @@ pub mod scrollable {
/// A widget that can vertically display an infinite amount of content
/// with a scrollbar.
pub type Scrollable<'a, Message> =
iced_pure::widget::Scrollable<'a, Message, crate::Renderer>;
pub type Scrollable<'a, Message, Theme> =
iced_pure::widget::Scrollable<'a, Message, crate::Renderer<Theme>>;
}
pub mod toggler {
@ -103,8 +112,8 @@ pub mod toggler {
pub use iced_pure::widget::toggler::{Style, StyleSheet};
/// A toggler widget.
pub type Toggler<'a, Message> =
iced_pure::widget::Toggler<'a, Message, crate::Renderer>;
pub type Toggler<'a, Message, Theme> =
iced_pure::widget::Toggler<'a, Message, crate::Renderer<Theme>>;
}
pub mod text_input {
@ -114,8 +123,8 @@ pub mod text_input {
pub use iced_pure::widget::text_input::{Style, StyleSheet};
/// A field that can be filled with text.
pub type TextInput<'a, Message> =
iced_pure::widget::TextInput<'a, Message, Renderer>;
pub type TextInput<'a, Message, Theme> =
iced_pure::widget::TextInput<'a, Message, Renderer<Theme>>;
}
pub mod tooltip {
@ -123,8 +132,8 @@ pub mod tooltip {
pub use iced_pure::widget::tooltip::Position;
/// A widget allowing the selection of a single value from a list of options.
pub type Tooltip<'a, Message> =
iced_pure::widget::Tooltip<'a, Message, crate::Renderer>;
pub type Tooltip<'a, Message, Theme> =
iced_pure::widget::Tooltip<'a, Message, crate::Renderer<Theme>>;
}
pub use iced_pure::widget::progress_bar;