summaryrefslogtreecommitdiffstats
path: root/src/sandbox.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/sandbox.rs')
-rw-r--r--src/sandbox.rs171
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)
+ }
}