diff options
author | 2019-11-24 11:34:30 +0100 | |
---|---|---|
committer | 2019-11-24 11:34:30 +0100 | |
commit | 149fd2aa1fa86858c7c1dcec8fd844caa78cec94 (patch) | |
tree | a199cf8d2caaf6aa60e48e93d6dd0688969d43b0 /src/sandbox.rs | |
parent | 9712b319bb7a32848001b96bd84977430f14b623 (diff) | |
parent | 47196c9007d12d3b3e0036ffabe3bf6d14ff4523 (diff) | |
download | iced-149fd2aa1fa86858c7c1dcec8fd844caa78cec94.tar.gz iced-149fd2aa1fa86858c7c1dcec8fd844caa78cec94.tar.bz2 iced-149fd2aa1fa86858c7c1dcec8fd844caa78cec94.zip |
Merge pull request #65 from hecrj/improvement/docs
Documentation
Diffstat (limited to 'src/sandbox.rs')
-rw-r--r-- | src/sandbox.rs | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/src/sandbox.rs b/src/sandbox.rs new file mode 100644 index 00000000..698578f4 --- /dev/null +++ b/src/sandbox.rs @@ -0,0 +1,155 @@ +use crate::{Application, Command, Element}; + +/// A sandboxed [`Application`]. +/// +/// A [`Sandbox`] is just an [`Application`] that cannot run any asynchronous +/// actions. +/// +/// If you do not need to leverage a [`Command`], you can use a [`Sandbox`] +/// instead of returning a [`Command::none`] everywhere. +/// +/// [`Application`]: trait.Application.html +/// [`Sandbox`]: trait.Sandbox.html +/// [`Command`]: struct.Command.html +/// [`Command::none`]: struct.Command.html#method.none +/// +/// # 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`]: +/// +/// ```no_run +/// use iced::{button, Button, Column, Element, Sandbox, Text}; +/// +/// pub fn main() { +/// Counter::run() +/// } +/// +/// #[derive(Default)] +/// struct Counter { +/// value: i32, +/// increment_button: button::State, +/// decrement_button: button::State, +/// } +/// +/// #[derive(Debug, Clone, Copy)] +/// enum Message { +/// IncrementPressed, +/// DecrementPressed, +/// } +/// +/// impl Sandbox for Counter { +/// type Message = Message; +/// +/// fn new() -> Self { +/// Self::default() +/// } +/// +/// fn title(&self) -> String { +/// String::from("A simple counter") +/// } +/// +/// fn update(&mut self, message: Message) { +/// match message { +/// Message::IncrementPressed => { +/// self.value += 1; +/// } +/// Message::DecrementPressed => { +/// self.value -= 1; +/// } +/// } +/// } +/// +/// 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() +/// } +/// } +/// ``` +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>; + + /// Runs the [`Sandbox`]. + /// + /// 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() + where + Self: 'static + Sized, + { + <Self as Application>::run() + } +} + +impl<T> Application for T +where + T: Sandbox, +{ + type Message = T::Message; + + fn new() -> (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(&mut self) -> Element<'_, T::Message> { + T::view(self) + } +} |