summaryrefslogtreecommitdiffstats
path: root/web/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'web/src/lib.rs')
-rw-r--r--web/src/lib.rs90
1 files changed, 37 insertions, 53 deletions
diff --git a/web/src/lib.rs b/web/src/lib.rs
index 258ad9e7..58f6591d 100644
--- a/web/src/lib.rs
+++ b/web/src/lib.rs
@@ -1,7 +1,5 @@
//! A web runtime for Iced, targetting the DOM.
//!
-//! ![`iced_web` crate graph](https://github.com/hecrj/iced/blob/cae26cb7bc627f4a5b3bcf1cd023a0c552e8c65e/docs/graphs/web.png?raw=true)
-//!
//! `iced_web` takes [`iced_core`] and builds a WebAssembly runtime on top. It
//! achieves this by introducing a `Widget` trait that can be used to produce
//! VDOM nodes.
@@ -23,8 +21,8 @@
//!
//! ```bash
//! cd examples
-//! cargo build --example tour --target wasm32-unknown-unknown
-//! wasm-bindgen ../target/wasm32-unknown-unknown/debug/examples/tour.wasm --out-dir tour --web
+//! cargo build --package tour --target wasm32-unknown-unknown
+//! wasm-bindgen ../target/wasm32-unknown-unknown/debug/tour.wasm --out-dir tour --web
//! ```
//!
//! Then, we need to create an `.html` file to load our application:
@@ -34,6 +32,7 @@
//! <html>
//! <head>
//! <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+//! <meta name="viewport" content="width=device-width, initial-scale=1">
//! <title>Tour - Iced</title>
//! </head>
//! <body>
@@ -50,7 +49,7 @@
//!
//! [`wasm-pack`]: https://github.com/rustwasm/wasm-pack
//! [`wasm-bindgen`]: https://github.com/rustwasm/wasm-bindgen
-//! [`tour` example]: https://github.com/hecrj/iced/blob/master/examples/tour.rs
+//! [`tour` example]: https://github.com/hecrj/iced/tree/0.2/examples/tour
#![deny(missing_docs)]
#![deny(missing_debug_implementations)]
#![deny(unused_results)]
@@ -73,8 +72,8 @@ pub use dodrio;
pub use element::Element;
pub use hasher::Hasher;
pub use iced_core::{
- Align, Background, Color, Font, HorizontalAlignment, Length, Point, Size,
- Vector, VerticalAlignment,
+ keyboard, mouse, Align, Background, Color, Font, HorizontalAlignment,
+ Length, Point, Rectangle, Size, Vector, VerticalAlignment,
};
pub use iced_futures::{executor, futures, Command};
pub use subscription::Subscription;
@@ -94,30 +93,23 @@ pub use executor::Executor;
/// An [`Application`](trait.Application.html) can execute asynchronous actions
/// by returning a [`Command`](struct.Command.html) in some of its methods.
pub trait Application {
+ /// The [`Executor`] that will run commands and subscriptions.
+ type Executor: Executor;
+
/// The type of __messages__ your [`Application`] will produce.
- ///
- /// [`Application`]: trait.Application.html
type Message: Send;
- /// The [`Executor`] that will run commands and subscriptions.
- ///
- /// The [`executor::WasmBindgen`] can be a good choice for the Web.
- ///
- /// [`Executor`]: trait.Executor.html
- /// [`executor::Default`]: executor/struct.Default.html
- type Executor: Executor;
+ /// The data needed to initialize your [`Application`].
+ type Flags;
/// Initializes the [`Application`].
///
/// Here is where you should return the initial state of your app.
///
- /// Additionally, you can return a [`Command`](struct.Command.html) if you
- /// need to perform some async action in the background on startup. This is
- /// useful if you want to load state from a file, perform an initial HTTP
- /// request, etc.
- ///
- /// [`Application`]: trait.Application.html
- fn new() -> (Self, Command<Self::Message>)
+ /// Additionally, you can return a [`Command`] if you need to perform some
+ /// async action in the background on startup. This is useful if you want to
+ /// load state from a file, perform an initial HTTP request, etc.
+ fn new(flags: Self::Flags) -> (Self, Command<Self::Message>)
where
Self: Sized;
@@ -125,8 +117,6 @@ pub trait Application {
///
/// This title can be dynamic! The runtime will automatically update the
/// title of your application when necessary.
- ///
- /// [`Application`]: trait.Application.html
fn title(&self) -> String;
/// Handles a __message__ and updates the state of the [`Application`].
@@ -136,16 +126,11 @@ pub trait Application {
/// this method.
///
/// Any [`Command`] returned will be executed immediately in the background.
- ///
- /// [`Application`]: trait.Application.html
- /// [`Command`]: struct.Command.html
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.
- ///
- /// [`Application`]: trait.Application.html
fn view(&mut self) -> Element<'_, Self::Message>;
/// Returns the event [`Subscription`] for the current state of the
@@ -156,30 +141,21 @@ pub trait Application {
/// [`update`](#tymethod.update).
///
/// By default, this method returns an empty [`Subscription`].
- ///
- /// [`Subscription`]: struct.Subscription.html
fn subscription(&self) -> Subscription<Self::Message> {
Subscription::none()
}
/// Runs the [`Application`].
- ///
- /// [`Application`]: trait.Application.html
- fn run()
+ fn run(flags: Self::Flags)
where
Self: 'static + Sized,
{
use futures::stream::StreamExt;
- let (app, command) = Self::new();
-
let window = web_sys::window().unwrap();
let document = window.document().unwrap();
let body = document.body().unwrap();
- let mut title = app.title();
- document.set_title(&title);
-
let (sender, receiver) =
iced_futures::futures::channel::mpsc::unbounded();
@@ -187,6 +163,12 @@ pub trait Application {
Self::Executor::new().expect("Create executor"),
sender.clone(),
);
+
+ let (app, command) = runtime.enter(|| Self::new(flags));
+
+ let mut title = app.title();
+ document.set_title(&title);
+
runtime.spawn(command);
let application = Rc::new(RefCell::new(app));
@@ -199,8 +181,13 @@ pub trait Application {
let vdom = dodrio::Vdom::new(&body, instance);
let event_loop = receiver.for_each(move |message| {
- let command = application.borrow_mut().update(message);
- let subscription = application.borrow().subscription();
+ let (command, subscription) = runtime.enter(|| {
+ let command = application.borrow_mut().update(message);
+ let subscription = application.borrow().subscription();
+
+ (command, subscription)
+ });
+
let new_title = application.borrow().title();
runtime.spawn(command);
@@ -226,28 +213,25 @@ struct Instance<A: Application> {
bus: Bus<A::Message>,
}
-impl<A> dodrio::Render for Instance<A>
+impl<'a, A> dodrio::Render<'a> for Instance<A>
where
A: Application,
{
- fn render<'a, 'bump>(
- &'a self,
- bump: &'bump bumpalo::Bump,
- ) -> dodrio::Node<'bump>
- where
- 'a: 'bump,
- {
+ fn render(
+ &self,
+ context: &mut dodrio::RenderContext<'a>,
+ ) -> dodrio::Node<'a> {
use dodrio::builder::*;
let mut ui = self.application.borrow_mut();
let element = ui.view();
let mut css = Css::new();
- let node = element.widget.node(bump, &self.bus, &mut css);
+ let node = element.widget.node(context.bump, &self.bus, &mut css);
- div(bump)
+ div(context.bump)
.attr("style", "width: 100%; height: 100%")
- .children(vec![css.node(bump), node])
+ .children(vec![css.node(context.bump), node])
.finish()
}
}