diff options
Diffstat (limited to 'src/sandbox.rs')
-rw-r--r-- | src/sandbox.rs | 171 |
1 files changed, 98 insertions, 73 deletions
diff --git a/src/sandbox.rs b/src/sandbox.rs index 2c0332ff..dbaa02f1 100644 --- a/src/sandbox.rs +++ b/src/sandbox.rs @@ -1,127 +1,143 @@ -use crate::{executor, Application, Command, Element, Settings, Subscription}; +use crate::{ + Application, Color, Command, Element, Error, Settings, Subscription, +}; /// A sandboxed [`Application`]. /// -/// A [`Sandbox`] is just an [`Application`] that cannot run any asynchronous -/// actions. +/// If you are a just getting started with the library, this trait offers a +/// simpler interface than [`Application`]. /// -/// If you do not need to leverage a [`Command`], you can use a [`Sandbox`] -/// instead of returning a [`Command::none`] everywhere. +/// 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. /// -/// [`Application`]: trait.Application.html -/// [`Sandbox`]: trait.Sandbox.html -/// [`Command`]: struct.Command.html -/// [`Command::none`]: struct.Command.html#method.none +/// Therefore, it is recommended to always start by implementing this trait and +/// upgrade only once necessary. /// -/// # Example -/// We can use a [`Sandbox`] to run the [`Counter` example we implemented -/// before](index.html#overview), instead of an [`Application`]. We just need -/// to remove the use of [`Command`]: +/// # Examples +/// [The repository has a bunch of examples] that use the [`Sandbox`] trait: /// -/// ```no_run -/// use iced::{button, Button, Column, Element, Sandbox, Settings, Text}; +/// - [`bezier_tool`], a Paint-like tool for drawing Bézier curves using +/// [`lyon`]. +/// - [`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! /// -/// pub fn main() { -/// Counter::run(Settings::default()) -/// } +/// [The repository has a bunch of examples]: https://github.com/hecrj/iced/tree/0.2/examples +/// [`bezier_tool`]: https://github.com/hecrj/iced/tree/0.2/examples/bezier_tool +/// [`counter`]: https://github.com/hecrj/iced/tree/0.2/examples/counter +/// [`custom_widget`]: https://github.com/hecrj/iced/tree/0.2/examples/custom_widget +/// [`geometry`]: https://github.com/hecrj/iced/tree/0.2/examples/geometry +/// [`pane_grid`]: https://github.com/hecrj/iced/tree/0.2/examples/pane_grid +/// [`progress_bar`]: https://github.com/hecrj/iced/tree/0.2/examples/progress_bar +/// [`styling`]: https://github.com/hecrj/iced/tree/0.2/examples/styling +/// [`svg`]: https://github.com/hecrj/iced/tree/0.2/examples/svg +/// [`tour`]: https://github.com/hecrj/iced/tree/0.2/examples/tour +/// [`lyon`]: https://github.com/nical/lyon +/// [the overview]: index.html#overview +/// [`iced_wgpu`]: https://github.com/hecrj/iced/tree/0.2/wgpu +/// [`Svg` widget]: crate::widget::Svg +/// [Ghostscript Tiger]: https://commons.wikimedia.org/wiki/File:Ghostscript_Tiger.svg /// -/// #[derive(Default)] -/// struct Counter { -/// value: i32, -/// increment_button: button::State, -/// decrement_button: button::State, -/// } +/// ## A simple "Hello, world!" +/// +/// If you just want to get started, here is a simple [`Sandbox`] that +/// says "Hello, world!": /// -/// #[derive(Debug, Clone, Copy)] -/// enum Message { -/// IncrementPressed, -/// DecrementPressed, +/// ```no_run +/// use iced::{Element, Sandbox, Settings, Text}; +/// +/// pub fn main() -> iced::Result { +/// Hello::run(Settings::default()) /// } /// -/// impl Sandbox for Counter { -/// type Message = Message; +/// struct Hello; +/// +/// impl Sandbox for Hello { +/// type Message = (); /// -/// fn new() -> Self { -/// Self::default() +/// fn new() -> Hello { +/// Hello /// } /// /// fn title(&self) -> String { -/// String::from("A simple counter") +/// String::from("A cool application") /// } /// -/// fn update(&mut self, message: Message) { -/// match message { -/// Message::IncrementPressed => { -/// self.value += 1; -/// } -/// Message::DecrementPressed => { -/// self.value -= 1; -/// } -/// } +/// fn update(&mut self, _message: Self::Message) { +/// // This application has no interactions /// } /// -/// fn view(&mut self) -> Element<Message> { -/// Column::new() -/// .push( -/// Button::new(&mut self.increment_button, Text::new("Increment")) -/// .on_press(Message::IncrementPressed), -/// ) -/// .push( -/// Text::new(self.value.to_string()).size(50), -/// ) -/// .push( -/// Button::new(&mut self.decrement_button, Text::new("Decrement")) -/// .on_press(Message::DecrementPressed), -/// ) -/// .into() +/// fn view(&mut self) -> Element<Self::Message> { +/// Text::new("Hello, world!").into() /// } /// } /// ``` pub trait Sandbox { /// The type of __messages__ your [`Sandbox`] will produce. - /// - /// [`Sandbox`]: trait.Sandbox.html type Message: std::fmt::Debug + Send; /// Initializes the [`Sandbox`]. /// /// Here is where you should return the initial state of your app. - /// - /// [`Sandbox`]: trait.Sandbox.html 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. - /// - /// [`Sandbox`]: trait.Sandbox.html 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. - /// - /// [`Sandbox`]: trait.Sandbox.html fn update(&mut self, message: Self::Message); /// Returns the widgets to display in the [`Sandbox`]. /// /// These widgets can produce __messages__ based on user interaction. - /// - /// [`Sandbox`]: trait.Sandbox.html fn view(&mut self) -> Element<'_, Self::Message>; + /// Returns the background color of the [`Sandbox`]. + /// + /// By default, it returns [`Color::WHITE`]. + fn background_color(&self) -> Color { + Color::WHITE + } + + /// 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`]. /// - /// This method will take control of the current thread and __will NOT - /// return__. + /// 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. - /// - /// [`Sandbox`]: trait.Sandbox.html - fn run(settings: Settings) + fn run(settings: Settings<()>) -> Result<(), Error> where Self: 'static + Sized, { @@ -133,10 +149,11 @@ impl<T> Application for T where T: Sandbox, { - type Executor = executor::Null; + type Executor = crate::runtime::executor::Null; + type Flags = (); type Message = T::Message; - fn new() -> (Self, Command<T::Message>) { + fn new(_flags: ()) -> (Self, Command<T::Message>) { (T::new(), Command::none()) } @@ -157,4 +174,12 @@ where fn view(&mut self) -> Element<'_, T::Message> { T::view(self) } + + fn background_color(&self) -> Color { + T::background_color(self) + } + + fn scale_factor(&self) -> f64 { + T::scale_factor(self) + } } |