From d0f79d2779d00752eef78cd98b6904cd888d59e3 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sat, 23 Nov 2019 20:23:38 +0100 Subject: Make `tour` work with `iced_web` again :tada: - Implements `TextInput`, `Scrollable`, and `Container` - Adds basic style generation --- web/src/lib.rs | 51 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 7 deletions(-) (limited to 'web/src/lib.rs') diff --git a/web/src/lib.rs b/web/src/lib.rs index 77a963ba..ac7f570c 100644 --- a/web/src/lib.rs +++ b/web/src/lib.rs @@ -61,15 +61,18 @@ use std::cell::RefCell; mod bus; mod element; + +pub mod style; pub mod widget; pub use bus::Bus; pub use dodrio; pub use element::Element; pub use iced_core::{ - Align, Background, Color, Font, HorizontalAlignment, Length, + Align, Background, Color, Command, Font, HorizontalAlignment, Length, VerticalAlignment, }; +pub use style::Style; pub use widget::*; /// An interactive web application. @@ -86,6 +89,28 @@ pub trait Application { /// [`Application`]: trait.Application.html type Message; + /// 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) + where + Self: Sized; + + /// Returns the current title of the [`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`]. /// /// This is where you define your __update logic__. All the __messages__, @@ -96,7 +121,7 @@ pub trait Application { /// /// [`Application`]: trait.Application.html /// [`Command`]: struct.Command.html - fn update(&mut self, message: Self::Message); + fn update(&mut self, message: Self::Message) -> Command; /// Returns the widgets to display in the [`Application`]. /// @@ -108,16 +133,19 @@ pub trait Application { /// Runs the [`Application`]. /// /// [`Application`]: trait.Application.html - fn run(self) + fn run() where Self: 'static + Sized, { - let app = Instance::new(self); + // TODO: Spawn command + let (app, _command) = Self::new(); + + let instance = Instance::new(app); let window = web_sys::window().unwrap(); let document = window.document().unwrap(); let body = document.body().unwrap(); - let vdom = dodrio::Vdom::new(&body, app); + let vdom = dodrio::Vdom::new(&body, instance); vdom.forget(); } @@ -135,7 +163,8 @@ impl Instance { } fn update(&mut self, message: Message) { - self.ui.borrow_mut().update(message); + // TODO: Spawn command + let _command = self.ui.borrow_mut().update(message); } } @@ -150,9 +179,17 @@ where where 'a: 'bump, { + use dodrio::builder::*; + let mut ui = self.ui.borrow_mut(); let element = ui.view(); + let mut style_sheet = style::Sheet::new(); + + let node = element.widget.node(bump, &Bus::new(), &mut style_sheet); - element.widget.node(bump, &Bus::new()) + div(bump) + .attr("style", "width: 100%; height: 100%") + .children(vec![style_sheet.node(bump), node]) + .finish() } } -- cgit From 9f3abe920271996cc4a9c533ad5e0e75e3d18a3d Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 24 Nov 2019 11:25:14 +0100 Subject: Spawn `Command` futures in `iced_web` --- web/src/lib.rs | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) (limited to 'web/src/lib.rs') diff --git a/web/src/lib.rs b/web/src/lib.rs index ac7f570c..dd401c31 100644 --- a/web/src/lib.rs +++ b/web/src/lib.rs @@ -57,7 +57,7 @@ #![deny(unsafe_code)] #![deny(rust_2018_idioms)] use dodrio::bumpalo; -use std::cell::RefCell; +use std::{cell::RefCell, rc::Rc}; mod bus; mod element; @@ -87,7 +87,7 @@ pub trait Application { /// The type of __messages__ your [`Application`] will produce. /// /// [`Application`]: trait.Application.html - type Message; + type Message: Clone; /// Initializes the [`Application`]. /// @@ -137,10 +137,10 @@ pub trait Application { where Self: 'static + Sized, { - // TODO: Spawn command - let (app, _command) = Self::new(); + let (app, command) = Self::new(); + let mut instance = Instance::new(app); - let instance = Instance::new(app); + instance.spawn(command); let window = web_sys::window().unwrap(); let document = window.document().unwrap(); @@ -151,26 +151,42 @@ pub trait Application { } } +#[derive(Clone)] struct Instance { - ui: RefCell>>, + ui: Rc>>>, } -impl Instance { +impl Instance +where + Message: 'static + Clone, +{ fn new(ui: impl Application + 'static) -> Self { Self { - ui: RefCell::new(Box::new(ui)), + ui: Rc::new(RefCell::new(Box::new(ui))), } } fn update(&mut self, message: Message) { - // TODO: Spawn command - let _command = self.ui.borrow_mut().update(message); + let command = self.ui.borrow_mut().update(message); + + self.spawn(command); + } + + fn spawn(&mut self, command: Command) { + use futures::FutureExt; + + for future in command.futures() { + let mut instance = self.clone(); + let future = future.map(move |message| instance.update(message)); + + wasm_bindgen_futures::spawn_local(future); + } } } impl dodrio::Render for Instance where - Message: 'static, + Message: 'static + Clone, { fn render<'a, 'bump>( &'a self, -- cgit From 2b2a0f12c75032453fbefd2491d3ef51ff0ba88e Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 24 Nov 2019 11:33:50 +0100 Subject: Update document title properly in `iced_web` --- web/src/lib.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'web/src/lib.rs') diff --git a/web/src/lib.rs b/web/src/lib.rs index dd401c31..8239ffc9 100644 --- a/web/src/lib.rs +++ b/web/src/lib.rs @@ -143,7 +143,10 @@ pub trait Application { instance.spawn(command); let window = web_sys::window().unwrap(); + let document = window.document().unwrap(); + document.set_title(&instance.title); + let body = document.body().unwrap(); let vdom = dodrio::Vdom::new(&body, instance); @@ -153,6 +156,7 @@ pub trait Application { #[derive(Clone)] struct Instance { + title: String, ui: Rc>>>, } @@ -162,14 +166,25 @@ where { fn new(ui: impl Application + 'static) -> Self { Self { + title: ui.title(), ui: Rc::new(RefCell::new(Box::new(ui))), } } fn update(&mut self, message: Message) { let command = self.ui.borrow_mut().update(message); + let title = self.ui.borrow().title(); self.spawn(command); + + let window = web_sys::window().unwrap(); + let document = window.document().unwrap(); + + if self.title != title { + document.set_title(&title); + + self.title = title; + } } fn spawn(&mut self, command: Command) { -- cgit