Remove Sandbox trait 🎉
This commit is contained in:
parent
9152904af1
commit
846d76cd3f
13 changed files with 169 additions and 240 deletions
|
|
@ -10,7 +10,7 @@ pub fn main() -> iced::Result {
|
|||
iced::application("Arc - Iced", Arc::update, Arc::view)
|
||||
.subscription(Arc::subscription)
|
||||
.theme(|_| Theme::Dark)
|
||||
.antialiased()
|
||||
.antialiasing(true)
|
||||
.run()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use iced::{Alignment, Element, Length};
|
|||
|
||||
pub fn main() -> iced::Result {
|
||||
iced::application("Bezier Tool - Iced", Example::update, Example::view)
|
||||
.antialiased()
|
||||
.antialiasing(true)
|
||||
.run()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ pub fn main() -> iced::Result {
|
|||
iced::application("Clock - Iced", Clock::update, Clock::view)
|
||||
.subscription(Clock::subscription)
|
||||
.theme(Clock::theme)
|
||||
.antialiased()
|
||||
.antialiasing(true)
|
||||
.run()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ pub fn main() -> iced::Result {
|
|||
)
|
||||
.theme(ColorPalette::theme)
|
||||
.default_font(Font::MONOSPACE)
|
||||
.antialiased()
|
||||
.antialiasing(true)
|
||||
.run()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use iced::{Alignment, Command, Element, Length, Subscription};
|
|||
pub fn main() -> iced::Result {
|
||||
iced::application("Events - Iced", Events::update, Events::view)
|
||||
.subscription(Events::subscription)
|
||||
.ignore_close_request()
|
||||
.exit_on_close_request(false)
|
||||
.run()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,22 +1,17 @@
|
|||
use iced::application;
|
||||
use iced::gradient;
|
||||
use iced::widget::{
|
||||
checkbox, column, container, horizontal_space, row, slider, text,
|
||||
};
|
||||
use iced::{gradient, window};
|
||||
use iced::{
|
||||
Alignment, Color, Element, Length, Radians, Sandbox, Settings, Theme,
|
||||
};
|
||||
use iced::{Alignment, Color, Element, Length, Radians, Theme};
|
||||
|
||||
pub fn main() -> iced::Result {
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
Gradient::run(Settings {
|
||||
window: window::Settings {
|
||||
transparent: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
})
|
||||
iced::application("Gradient - Iced", Gradient::update, Gradient::view)
|
||||
.style(Gradient::style)
|
||||
.transparent(true)
|
||||
.run()
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
|
|
@ -35,9 +30,7 @@ enum Message {
|
|||
TransparentToggled(bool),
|
||||
}
|
||||
|
||||
impl Sandbox for Gradient {
|
||||
type Message = Message;
|
||||
|
||||
impl Gradient {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
start: Color::WHITE,
|
||||
|
|
@ -47,10 +40,6 @@ impl Sandbox for Gradient {
|
|||
}
|
||||
}
|
||||
|
||||
fn title(&self) -> String {
|
||||
String::from("Gradient")
|
||||
}
|
||||
|
||||
fn update(&mut self, message: Message) {
|
||||
match message {
|
||||
Message::StartChanged(color) => self.start = color,
|
||||
|
|
@ -118,6 +107,12 @@ impl Sandbox for Gradient {
|
|||
}
|
||||
}
|
||||
|
||||
impl Default for Gradient {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
fn color_picker(label: &str, color: Color) -> Element<'_, Color> {
|
||||
row![
|
||||
text(label).width(64),
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ pub fn main() -> iced::Result {
|
|||
LoadingSpinners::update,
|
||||
LoadingSpinners::view,
|
||||
)
|
||||
.antialiased()
|
||||
.antialiasing(true)
|
||||
.run()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ pub fn main() -> iced::Result {
|
|||
tracing_subscriber::fmt::init();
|
||||
|
||||
iced::application("Multitouch - Iced", Multitouch::update, Multitouch::view)
|
||||
.antialiased()
|
||||
.antialiasing(true)
|
||||
.centered()
|
||||
.run()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ fn main() -> iced::Result {
|
|||
SierpinskiEmulator::update,
|
||||
SierpinskiEmulator::view,
|
||||
)
|
||||
.antialiased()
|
||||
.antialiasing(true)
|
||||
.run()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ pub fn main() -> iced::Result {
|
|||
VectorialText::view,
|
||||
)
|
||||
.theme(|_| Theme::Dark)
|
||||
.antialiased()
|
||||
.antialiasing(true)
|
||||
.run()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -172,7 +172,6 @@ pub use iced_futures::futures;
|
|||
pub use iced_highlighter as highlighter;
|
||||
|
||||
mod error;
|
||||
mod sandbox;
|
||||
|
||||
pub mod application;
|
||||
pub mod program;
|
||||
|
|
@ -311,7 +310,6 @@ pub use executor::Executor;
|
|||
pub use font::Font;
|
||||
pub use program::Program;
|
||||
pub use renderer::Renderer;
|
||||
pub use sandbox::Sandbox;
|
||||
pub use settings::Settings;
|
||||
pub use subscription::Subscription;
|
||||
|
||||
|
|
|
|||
159
src/program.rs
159
src/program.rs
|
|
@ -194,12 +194,16 @@ impl<P: Definition> Program<P> {
|
|||
self.program.view(&self.state)
|
||||
}
|
||||
|
||||
fn subscription(&self) -> Subscription<Self::Message> {
|
||||
self.program.subscription(&self.state)
|
||||
}
|
||||
|
||||
fn theme(&self) -> Self::Theme {
|
||||
self.program.theme(&self.state)
|
||||
}
|
||||
|
||||
fn subscription(&self) -> Subscription<Self::Message> {
|
||||
self.program.subscription(&self.state)
|
||||
fn style(&self, theme: &Self::Theme) -> application::Appearance {
|
||||
self.program.style(&self.state, theme)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -221,11 +225,11 @@ impl<P: Definition> Program<P> {
|
|||
Self { settings, ..self }
|
||||
}
|
||||
|
||||
/// Toggles the [`Settings::antialiasing`] to `true` for the [`Program`].
|
||||
pub fn antialiased(self) -> Self {
|
||||
/// Sets the [`Settings::antialiasing`] of the [`Program`].
|
||||
pub fn antialiasing(self, antialiasing: bool) -> Self {
|
||||
Self {
|
||||
settings: Settings {
|
||||
antialiasing: true,
|
||||
antialiasing,
|
||||
..self.settings
|
||||
},
|
||||
..self
|
||||
|
|
@ -263,12 +267,26 @@ impl<P: Definition> Program<P> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Sets the [`window::Settings::exit_on_close_request`] to `false` in the [`Program`].
|
||||
pub fn ignore_close_request(self) -> Self {
|
||||
/// Sets the [`window::Settings::exit_on_close_request`] of the [`Program`].
|
||||
pub fn exit_on_close_request(self, exit_on_close_request: bool) -> Self {
|
||||
Self {
|
||||
settings: Settings {
|
||||
window: window::Settings {
|
||||
exit_on_close_request: false,
|
||||
exit_on_close_request,
|
||||
..self.settings.window
|
||||
},
|
||||
..self.settings
|
||||
},
|
||||
..self
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the [`window::Settings::transparent`] of the [`Program`].
|
||||
pub fn transparent(self, transparent: bool) -> Self {
|
||||
Self {
|
||||
settings: Settings {
|
||||
window: window::Settings {
|
||||
transparent,
|
||||
..self.settings.window
|
||||
},
|
||||
..self.settings
|
||||
|
|
@ -328,6 +346,19 @@ impl<P: Definition> Program<P> {
|
|||
settings: self.settings,
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the style logic of the [`Program`].
|
||||
pub fn style(
|
||||
self,
|
||||
f: impl Fn(&P::State, &P::Theme) -> application::Appearance,
|
||||
) -> Program<
|
||||
impl Definition<State = P::State, Message = P::Message, Theme = P::Theme>,
|
||||
> {
|
||||
Program {
|
||||
raw: with_style(self.raw, f),
|
||||
settings: self.settings,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The internal definition of a [`Program`].
|
||||
|
|
@ -377,6 +408,14 @@ pub trait Definition: Sized {
|
|||
fn theme(&self, _state: &Self::State) -> Self::Theme {
|
||||
Self::Theme::default()
|
||||
}
|
||||
|
||||
fn style(
|
||||
&self,
|
||||
_state: &Self::State,
|
||||
theme: &Self::Theme,
|
||||
) -> application::Appearance {
|
||||
application::DefaultStyle::default_style(theme)
|
||||
}
|
||||
}
|
||||
|
||||
fn with_title<P: Definition>(
|
||||
|
|
@ -431,6 +470,14 @@ fn with_title<P: Definition>(
|
|||
) -> Subscription<Self::Message> {
|
||||
self.program.subscription(state)
|
||||
}
|
||||
|
||||
fn style(
|
||||
&self,
|
||||
state: &Self::State,
|
||||
theme: &Self::Theme,
|
||||
) -> application::Appearance {
|
||||
self.program.style(state, theme)
|
||||
}
|
||||
}
|
||||
|
||||
WithTitle { program, title }
|
||||
|
|
@ -479,16 +526,24 @@ fn with_load<P: Definition>(
|
|||
self.program.title(state)
|
||||
}
|
||||
|
||||
fn theme(&self, state: &Self::State) -> Self::Theme {
|
||||
self.program.theme(state)
|
||||
}
|
||||
|
||||
fn subscription(
|
||||
&self,
|
||||
state: &Self::State,
|
||||
) -> Subscription<Self::Message> {
|
||||
self.program.subscription(state)
|
||||
}
|
||||
|
||||
fn theme(&self, state: &Self::State) -> Self::Theme {
|
||||
self.program.theme(state)
|
||||
}
|
||||
|
||||
fn style(
|
||||
&self,
|
||||
state: &Self::State,
|
||||
theme: &Self::Theme,
|
||||
) -> application::Appearance {
|
||||
self.program.style(state, theme)
|
||||
}
|
||||
}
|
||||
|
||||
WithLoad { program, load: f }
|
||||
|
|
@ -545,6 +600,14 @@ fn with_subscription<P: Definition>(
|
|||
fn theme(&self, state: &Self::State) -> Self::Theme {
|
||||
self.program.theme(state)
|
||||
}
|
||||
|
||||
fn style(
|
||||
&self,
|
||||
state: &Self::State,
|
||||
theme: &Self::Theme,
|
||||
) -> application::Appearance {
|
||||
self.program.style(state, theme)
|
||||
}
|
||||
}
|
||||
|
||||
WithSubscription {
|
||||
|
|
@ -604,11 +667,83 @@ fn with_theme<P: Definition>(
|
|||
) -> Subscription<Self::Message> {
|
||||
self.program.subscription(state)
|
||||
}
|
||||
|
||||
fn style(
|
||||
&self,
|
||||
state: &Self::State,
|
||||
theme: &Self::Theme,
|
||||
) -> application::Appearance {
|
||||
self.program.style(state, theme)
|
||||
}
|
||||
}
|
||||
|
||||
WithTheme { program, theme: f }
|
||||
}
|
||||
|
||||
fn with_style<P: Definition>(
|
||||
program: P,
|
||||
f: impl Fn(&P::State, &P::Theme) -> application::Appearance,
|
||||
) -> impl Definition<State = P::State, Message = P::Message, Theme = P::Theme> {
|
||||
struct WithStyle<P, F> {
|
||||
program: P,
|
||||
style: F,
|
||||
}
|
||||
|
||||
impl<P: Definition, F> Definition for WithStyle<P, F>
|
||||
where
|
||||
F: Fn(&P::State, &P::Theme) -> application::Appearance,
|
||||
{
|
||||
type State = P::State;
|
||||
type Message = P::Message;
|
||||
type Theme = P::Theme;
|
||||
type Executor = P::Executor;
|
||||
|
||||
fn style(
|
||||
&self,
|
||||
state: &Self::State,
|
||||
theme: &Self::Theme,
|
||||
) -> application::Appearance {
|
||||
(self.style)(state, theme)
|
||||
}
|
||||
|
||||
fn build(&self) -> (Self::State, Command<Self::Message>) {
|
||||
self.program.build()
|
||||
}
|
||||
|
||||
fn title(&self, state: &Self::State) -> String {
|
||||
self.program.title(state)
|
||||
}
|
||||
|
||||
fn update(
|
||||
&self,
|
||||
state: &mut Self::State,
|
||||
message: Self::Message,
|
||||
) -> Command<Self::Message> {
|
||||
self.program.update(state, message)
|
||||
}
|
||||
|
||||
fn view<'a>(
|
||||
&self,
|
||||
state: &'a Self::State,
|
||||
) -> Element<'a, Self::Message, Self::Theme> {
|
||||
self.program.view(state)
|
||||
}
|
||||
|
||||
fn subscription(
|
||||
&self,
|
||||
state: &Self::State,
|
||||
) -> Subscription<Self::Message> {
|
||||
self.program.subscription(state)
|
||||
}
|
||||
|
||||
fn theme(&self, state: &Self::State) -> Self::Theme {
|
||||
self.program.theme(state)
|
||||
}
|
||||
}
|
||||
|
||||
WithStyle { program, style: f }
|
||||
}
|
||||
|
||||
/// The title logic of some [`Program`].
|
||||
///
|
||||
/// This trait is implemented both for `&static str` and
|
||||
|
|
|
|||
199
src/sandbox.rs
199
src/sandbox.rs
|
|
@ -1,199 +0,0 @@
|
|||
use crate::application::{self, Application};
|
||||
use crate::{Command, Element, Error, Settings, Subscription, Theme};
|
||||
|
||||
/// A sandboxed [`Application`].
|
||||
///
|
||||
/// If you are a just getting started with the library, this trait offers a
|
||||
/// simpler interface than [`Application`].
|
||||
///
|
||||
/// Unlike an [`Application`], a [`Sandbox`] cannot run any asynchronous
|
||||
/// actions or be initialized with some external flags. However, both traits
|
||||
/// are very similar and upgrading from a [`Sandbox`] is very straightforward.
|
||||
///
|
||||
/// Therefore, it is recommended to always start by implementing this trait and
|
||||
/// upgrade only once necessary.
|
||||
///
|
||||
/// # Examples
|
||||
/// [The repository has a bunch of examples] that use the [`Sandbox`] trait:
|
||||
///
|
||||
/// - [`bezier_tool`], a Paint-like tool for drawing Bézier curves using the
|
||||
/// [`Canvas widget`].
|
||||
/// - [`counter`], the classic counter example explained in [the overview].
|
||||
/// - [`custom_widget`], a demonstration of how to build a custom widget that
|
||||
/// draws a circle.
|
||||
/// - [`geometry`], a custom widget showcasing how to draw geometry with the
|
||||
/// `Mesh2D` primitive in [`iced_wgpu`].
|
||||
/// - [`pane_grid`], a grid of panes that can be split, resized, and
|
||||
/// reorganized.
|
||||
/// - [`progress_bar`], a simple progress bar that can be filled by using a
|
||||
/// slider.
|
||||
/// - [`styling`], an example showcasing custom styling with a light and dark
|
||||
/// theme.
|
||||
/// - [`svg`], an application that renders the [Ghostscript Tiger] by leveraging
|
||||
/// the [`Svg` widget].
|
||||
/// - [`tour`], a simple UI tour that can run both on native platforms and the
|
||||
/// web!
|
||||
///
|
||||
/// [The repository has a bunch of examples]: https://github.com/iced-rs/iced/tree/0.12/examples
|
||||
/// [`bezier_tool`]: https://github.com/iced-rs/iced/tree/0.12/examples/bezier_tool
|
||||
/// [`counter`]: https://github.com/iced-rs/iced/tree/0.12/examples/counter
|
||||
/// [`custom_widget`]: https://github.com/iced-rs/iced/tree/0.12/examples/custom_widget
|
||||
/// [`geometry`]: https://github.com/iced-rs/iced/tree/0.12/examples/geometry
|
||||
/// [`pane_grid`]: https://github.com/iced-rs/iced/tree/0.12/examples/pane_grid
|
||||
/// [`progress_bar`]: https://github.com/iced-rs/iced/tree/0.12/examples/progress_bar
|
||||
/// [`styling`]: https://github.com/iced-rs/iced/tree/0.12/examples/styling
|
||||
/// [`svg`]: https://github.com/iced-rs/iced/tree/0.12/examples/svg
|
||||
/// [`tour`]: https://github.com/iced-rs/iced/tree/0.12/examples/tour
|
||||
/// [`Canvas widget`]: crate::widget::Canvas
|
||||
/// [the overview]: index.html#overview
|
||||
/// [`iced_wgpu`]: https://github.com/iced-rs/iced/tree/0.12/wgpu
|
||||
/// [`Svg` widget]: crate::widget::Svg
|
||||
/// [Ghostscript Tiger]: https://commons.wikimedia.org/wiki/File:Ghostscript_Tiger.svg
|
||||
///
|
||||
/// ## A simple "Hello, world!"
|
||||
///
|
||||
/// If you just want to get started, here is a simple [`Sandbox`] that
|
||||
/// says "Hello, world!":
|
||||
///
|
||||
/// ```no_run
|
||||
/// use iced::{Element, Sandbox, Settings};
|
||||
///
|
||||
/// pub fn main() -> iced::Result {
|
||||
/// Hello::run(Settings::default())
|
||||
/// }
|
||||
///
|
||||
/// struct Hello;
|
||||
///
|
||||
/// impl Sandbox for Hello {
|
||||
/// type Message = ();
|
||||
///
|
||||
/// fn new() -> Hello {
|
||||
/// Hello
|
||||
/// }
|
||||
///
|
||||
/// fn title(&self) -> String {
|
||||
/// String::from("A cool application")
|
||||
/// }
|
||||
///
|
||||
/// fn update(&mut self, _message: Self::Message) {
|
||||
/// // This application has no interactions
|
||||
/// }
|
||||
///
|
||||
/// fn view(&self) -> Element<Self::Message> {
|
||||
/// "Hello, world!".into()
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
pub trait Sandbox {
|
||||
/// The type of __messages__ your [`Sandbox`] will produce.
|
||||
type Message: std::fmt::Debug + Send;
|
||||
|
||||
/// Initializes the [`Sandbox`].
|
||||
///
|
||||
/// Here is where you should return the initial state of your app.
|
||||
fn new() -> Self;
|
||||
|
||||
/// Returns the current title of the [`Sandbox`].
|
||||
///
|
||||
/// This title can be dynamic! The runtime will automatically update the
|
||||
/// title of your application when necessary.
|
||||
fn title(&self) -> String;
|
||||
|
||||
/// Handles a __message__ and updates the state of the [`Sandbox`].
|
||||
///
|
||||
/// This is where you define your __update logic__. All the __messages__,
|
||||
/// produced by user interactions, will be handled by this method.
|
||||
fn update(&mut self, message: Self::Message);
|
||||
|
||||
/// Returns the widgets to display in the [`Sandbox`].
|
||||
///
|
||||
/// These widgets can produce __messages__ based on user interaction.
|
||||
fn view(&self) -> 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 current [`application::Appearance`].
|
||||
fn style(&self, theme: &Theme) -> application::Appearance {
|
||||
use application::DefaultStyle;
|
||||
|
||||
theme.default_style()
|
||||
}
|
||||
|
||||
/// Returns the scale factor of the [`Sandbox`].
|
||||
///
|
||||
/// It can be used to dynamically control the size of the UI at runtime
|
||||
/// (i.e. zooming).
|
||||
///
|
||||
/// For instance, a scale factor of `2.0` will make widgets twice as big,
|
||||
/// while a scale factor of `0.5` will shrink them to half their size.
|
||||
///
|
||||
/// By default, it returns `1.0`.
|
||||
fn scale_factor(&self) -> f64 {
|
||||
1.0
|
||||
}
|
||||
|
||||
/// Runs the [`Sandbox`].
|
||||
///
|
||||
/// On native platforms, this method will take control of the current thread
|
||||
/// and __will NOT return__.
|
||||
///
|
||||
/// It should probably be that last thing you call in your `main` function.
|
||||
fn run(settings: Settings<()>) -> Result<(), Error>
|
||||
where
|
||||
Self: 'static + Sized,
|
||||
{
|
||||
<Self as Application>::run(settings)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Application for T
|
||||
where
|
||||
T: Sandbox,
|
||||
{
|
||||
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())
|
||||
}
|
||||
|
||||
fn title(&self) -> String {
|
||||
T::title(self)
|
||||
}
|
||||
|
||||
fn update(&mut self, message: T::Message) -> Command<T::Message> {
|
||||
T::update(self, message);
|
||||
|
||||
Command::none()
|
||||
}
|
||||
|
||||
fn view(&self) -> Element<'_, T::Message> {
|
||||
T::view(self)
|
||||
}
|
||||
|
||||
fn theme(&self) -> Self::Theme {
|
||||
T::theme(self)
|
||||
}
|
||||
|
||||
fn style(&self, theme: &Theme) -> application::Appearance {
|
||||
T::style(self, theme)
|
||||
}
|
||||
|
||||
fn subscription(&self) -> Subscription<T::Message> {
|
||||
Subscription::none()
|
||||
}
|
||||
|
||||
fn scale_factor(&self) -> f64 {
|
||||
T::scale_factor(self)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue