#![deny(missing_docs)]
#![deny(missing_debug_implementations)]
#![deny(unused_results)]
#![forbid(unsafe_code)]
#![forbid(rust_2018_idioms)]
use dodrio::bumpalo;
use std::{cell::RefCell, rc::Rc};
mod bus;
mod clipboard;
mod element;
mod hasher;
pub mod css;
pub mod subscription;
pub mod widget;
pub use bus::Bus;
pub use clipboard::Clipboard;
pub use css::Css;
pub use dodrio;
pub use element::Element;
pub use hasher::Hasher;
pub use iced_core::{
keyboard, mouse, Align, Background, Color, Font, HorizontalAlignment,
Length, Point, Rectangle, Size, Vector, VerticalAlignment,
};
pub use iced_futures::{executor, futures, Command};
pub use subscription::Subscription;
#[doc(no_inline)]
pub use widget::*;
#[doc(no_inline)]
pub use executor::Executor;
pub trait Application {
type Executor: Executor;
type Message: Send;
type Flags;
fn new(flags: Self::Flags) -> (Self, Command<Self::Message>)
where
Self: Sized;
fn title(&self) -> String;
fn update(
&mut self,
message: Self::Message,
clipboard: &mut Clipboard,
) -> Command<Self::Message>;
fn view(&mut self) -> Element<'_, Self::Message>;
fn subscription(&self) -> Subscription<Self::Message> {
Subscription::none()
}
fn run(flags: Self::Flags)
where
Self: 'static + Sized,
{
use futures::stream::StreamExt;
let window = web_sys::window().unwrap();
let document = window.document().unwrap();
let body = document.body().unwrap();
let mut clipboard = Clipboard::new();
let (sender, receiver) =
iced_futures::futures::channel::mpsc::unbounded();
let mut runtime = iced_futures::Runtime::new(
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));
let instance = Instance {
application: application.clone(),
bus: Bus::new(sender),
};
let vdom = dodrio::Vdom::new(&body, instance);
let event_loop = receiver.for_each(move |message| {
let (command, subscription) = runtime.enter(|| {
let command =
application.borrow_mut().update(message, &mut clipboard);
let subscription = application.borrow().subscription();
(command, subscription)
});
let new_title = application.borrow().title();
runtime.spawn(command);
runtime.track(subscription);
if title != new_title {
document.set_title(&new_title);
title = new_title;
}
vdom.weak().schedule_render();
futures::future::ready(())
});
wasm_bindgen_futures::spawn_local(event_loop);
}
}
struct Instance<A: Application> {
application: Rc<RefCell<A>>,
bus: Bus<A::Message>,
}
impl<'a, A> dodrio::Render<'a> for Instance<A>
where
A: Application,
{
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(context.bump, &self.bus, &mut css);
div(context.bump)
.attr("style", "width: 100%; height: 100%")
.children(vec![css.node(context.bump), node])
.finish()
}
}