diff options
author | 2019-09-15 18:53:13 +0200 | |
---|---|---|
committer | 2019-09-15 18:53:13 +0200 | |
commit | 655978f480c32bc696f0d5fe2fff834bfbf238ea (patch) | |
tree | ee9af0e0e802c7f85004fd28d3854dbb8bfcb4f5 /web | |
parent | 8834772fa70850559f7bd82cc8432394e3fd9db7 (diff) | |
download | iced-655978f480c32bc696f0d5fe2fff834bfbf238ea.tar.gz iced-655978f480c32bc696f0d5fe2fff834bfbf238ea.tar.bz2 iced-655978f480c32bc696f0d5fe2fff834bfbf238ea.zip |
Draft nodes for missing widgets
Diffstat (limited to 'web')
-rw-r--r-- | web/Cargo.toml | 5 | ||||
-rw-r--r-- | web/examples/tour/index.html | 2 | ||||
l--------- | web/examples/tour/resources/ferris.png | 1 | ||||
-rw-r--r-- | web/examples/tour/src/tour.rs | 4 | ||||
-rw-r--r-- | web/src/widget.rs | 6 | ||||
-rw-r--r-- | web/src/widget/button.rs | 4 | ||||
-rw-r--r-- | web/src/widget/checkbox.rs | 39 | ||||
-rw-r--r-- | web/src/widget/column.rs | 5 | ||||
-rw-r--r-- | web/src/widget/image.rs | 25 | ||||
-rw-r--r-- | web/src/widget/radio.rs | 40 | ||||
-rw-r--r-- | web/src/widget/row.rs | 5 | ||||
-rw-r--r-- | web/src/widget/slider.rs | 55 |
12 files changed, 167 insertions, 24 deletions
diff --git a/web/Cargo.toml b/web/Cargo.toml index 6d8c37b1..0ab89570 100644 --- a/web/Cargo.toml +++ b/web/Cargo.toml @@ -18,6 +18,7 @@ maintenance = { status = "actively-developed" } iced = { version = "0.1.0-alpha", path = ".." } dodrio = "0.1.0" futures = "0.1" +wasm-bindgen = "0.2.50" [dependencies.web-sys] version = "0.3.27" @@ -25,4 +26,8 @@ features = [ "console", "Document", "HtmlElement", + "HtmlInputElement", + "Event", + "EventTarget", + "InputEvent", ] diff --git a/web/examples/tour/index.html b/web/examples/tour/index.html index a639a6cb..527cc54c 100644 --- a/web/examples/tour/index.html +++ b/web/examples/tour/index.html @@ -2,7 +2,7 @@ <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"/> - <title>Tour - Iced Web</title> + <title>Web Tour - Iced</title> </head> <body> <script type="module"> diff --git a/web/examples/tour/resources/ferris.png b/web/examples/tour/resources/ferris.png new file mode 120000 index 00000000..9c4fb51c --- /dev/null +++ b/web/examples/tour/resources/ferris.png @@ -0,0 +1 @@ +../../../../examples/resources/ferris.png
\ No newline at end of file diff --git a/web/examples/tour/src/tour.rs b/web/examples/tour/src/tour.rs index 6c24622e..9a60e092 100644 --- a/web/examples/tour/src/tour.rs +++ b/web/examples/tour/src/tour.rs @@ -295,8 +295,8 @@ impl<'a> Step { )) .push(Text::new( "Iced does not provide a built-in renderer. This example runs \ - on a fairly simple renderer built on top of ggez, another \ - game library.", + on WebAssembly using dodrio, an experimental VDOM library \ + for Rust.", )) .push(Text::new( "You will need to interact with the UI in order to reach the \ diff --git a/web/src/widget.rs b/web/src/widget.rs index 7af592e1..67ca8e81 100644 --- a/web/src/widget.rs +++ b/web/src/widget.rs @@ -25,9 +25,5 @@ pub trait Widget<Message> { &self, bump: &'b bumpalo::Bump, _bus: &Bus<Message>, - ) -> dodrio::Node<'b> { - use dodrio::builder::*; - - div(bump).children(vec![text("WIP")]).finish() - } + ) -> dodrio::Node<'b>; } diff --git a/web/src/widget/button.rs b/web/src/widget/button.rs index 8ccda107..63c0262a 100644 --- a/web/src/widget/button.rs +++ b/web/src/widget/button.rs @@ -1,8 +1,8 @@ use crate::{Bus, Element, Widget}; -use dodrio::bumpalo; - pub use iced::button::{Class, State}; +use dodrio::bumpalo; + pub type Button<'a, Message> = iced::Button<'a, Message>; impl<'a, Message> Widget<Message> for Button<'a, Message> diff --git a/web/src/widget/checkbox.rs b/web/src/widget/checkbox.rs index a231d801..e3c61ca7 100644 --- a/web/src/widget/checkbox.rs +++ b/web/src/widget/checkbox.rs @@ -1,12 +1,45 @@ -use crate::{Color, Element, Widget}; +use crate::{Bus, Color, Element, Widget}; + +use dodrio::bumpalo; pub type Checkbox<Message> = iced::Checkbox<Color, Message>; -impl<Message> Widget<Message> for Checkbox<Message> {} +impl<Message> Widget<Message> for Checkbox<Message> +where + Message: 'static + Copy, +{ + fn node<'b>( + &self, + bump: &'b bumpalo::Bump, + bus: &Bus<Message>, + ) -> dodrio::Node<'b> { + use dodrio::builder::*; + + let checkbox_label = bumpalo::format!(in bump, "{}", self.label); + + let event_bus = bus.clone(); + let msg = (self.on_toggle)(!self.is_checked); + + label(bump) + .children(vec![ + input(bump) + .attr("type", "checkbox") + .bool_attr("checked", self.is_checked) + .on("click", move |root, vdom, _event| { + event_bus.publish(msg, root); + + vdom.schedule_render(); + }) + .finish(), + text(checkbox_label.into_bump_str()), + ]) + .finish() + } +} impl<'a, Message> From<Checkbox<Message>> for Element<'a, Message> where - Message: 'static, + Message: 'static + Copy, { fn from(checkbox: Checkbox<Message>) -> Element<'a, Message> { Element::new(checkbox) diff --git a/web/src/widget/column.rs b/web/src/widget/column.rs index b3131f5e..a2b8232e 100644 --- a/web/src/widget/column.rs +++ b/web/src/widget/column.rs @@ -52,7 +52,10 @@ impl<'a, Message> Widget<Message> for Column<'a, Message> { .map(|element| element.widget.node(bump, publish)) .collect(); - div(bump).children(children).finish() + div(bump) + .attr("style", "display: flex; flex-direction: column") + .children(children) + .finish() } } diff --git a/web/src/widget/image.rs b/web/src/widget/image.rs index ac144fd8..a882faff 100644 --- a/web/src/widget/image.rs +++ b/web/src/widget/image.rs @@ -1,8 +1,29 @@ -use crate::{Element, Widget}; +use crate::{Bus, Element, Widget}; + +use dodrio::bumpalo; pub type Image<'a> = iced::Image<&'a str>; -impl<'a, Message> Widget<Message> for Image<'a> {} +impl<'a, Message> Widget<Message> for Image<'a> { + fn node<'b>( + &self, + bump: &'b bumpalo::Bump, + _bus: &Bus<Message>, + ) -> dodrio::Node<'b> { + use dodrio::builder::*; + + let src = bumpalo::format!(in bump, "{}", self.image); + + let mut image = img(bump).attr("src", src.into_bump_str()); + + if let Some(width) = self.width { + let width = bumpalo::format!(in bump, "{}", width); + image = image.attr("width", width.into_bump_str()); + } + + image.finish() + } +} impl<'a, Message> From<Image<'a>> for Element<'a, Message> { fn from(image: Image<'a>) -> Element<'a, Message> { diff --git a/web/src/widget/radio.rs b/web/src/widget/radio.rs index 0c28b46f..df08a977 100644 --- a/web/src/widget/radio.rs +++ b/web/src/widget/radio.rs @@ -1,12 +1,46 @@ -use crate::{Color, Element, Widget}; +use crate::{Bus, Color, Element, Widget}; + +use dodrio::bumpalo; pub type Radio<Message> = iced::Radio<Color, Message>; -impl<Message> Widget<Message> for Radio<Message> {} +impl<Message> Widget<Message> for Radio<Message> +where + Message: 'static + Copy, +{ + fn node<'b>( + &self, + bump: &'b bumpalo::Bump, + bus: &Bus<Message>, + ) -> dodrio::Node<'b> { + use dodrio::builder::*; + + let radio_label = bumpalo::format!(in bump, "{}", self.label); + + let event_bus = bus.clone(); + let on_click = self.on_click; + + label(bump) + .attr("style", "display: block") + .children(vec![ + input(bump) + .attr("type", "radio") + .bool_attr("checked", self.is_selected) + .on("click", move |root, vdom, _event| { + event_bus.publish(on_click, root); + + vdom.schedule_render(); + }) + .finish(), + text(radio_label.into_bump_str()), + ]) + .finish() + } +} impl<'a, Message> From<Radio<Message>> for Element<'a, Message> where - Message: 'static, + Message: 'static + Copy, { fn from(radio: Radio<Message>) -> Element<'a, Message> { Element::new(radio) diff --git a/web/src/widget/row.rs b/web/src/widget/row.rs index 40fc68e3..71532245 100644 --- a/web/src/widget/row.rs +++ b/web/src/widget/row.rs @@ -40,7 +40,10 @@ impl<'a, Message> Widget<Message> for Row<'a, Message> { .map(|element| element.widget.node(bump, publish)) .collect(); - div(bump).children(children).finish() + div(bump) + .attr("style", "display: flex; flex-direction: row") + .children(children) + .finish() } } diff --git a/web/src/widget/slider.rs b/web/src/widget/slider.rs index 9c83befb..31bfcbf3 100644 --- a/web/src/widget/slider.rs +++ b/web/src/widget/slider.rs @@ -1,14 +1,61 @@ -use crate::{Element, Widget}; +use crate::{Bus, Element, Widget}; -pub use iced::slider::State; +use dodrio::bumpalo; pub type Slider<'a, Message> = iced::Slider<'a, Message>; -impl<'a, Message> Widget<Message> for Slider<'a, Message> {} +pub use iced::slider::State; + +impl<'a, Message> Widget<Message> for Slider<'a, Message> +where + Message: 'static + Copy, +{ + fn node<'b>( + &self, + bump: &'b bumpalo::Bump, + bus: &Bus<Message>, + ) -> dodrio::Node<'b> { + use dodrio::builder::*; + use wasm_bindgen::JsCast; + + let (start, end) = self.range.clone().into_inner(); + + let min = bumpalo::format!(in bump, "{}", start); + let max = bumpalo::format!(in bump, "{}", end); + let value = bumpalo::format!(in bump, "{}", self.value); + + let on_change = self.on_change.clone(); + let event_bus = bus.clone(); + + // TODO: Make `step` configurable + label(bump) + .children(vec![input(bump) + .attr("type", "range") + .attr("step", "0.01") + .attr("min", min.into_bump_str()) + .attr("max", max.into_bump_str()) + .attr("value", value.into_bump_str()) + .on("input", move |root, vdom, event| { + let slider = match event.target().and_then(|t| { + t.dyn_into::<web_sys::HtmlInputElement>().ok() + }) { + None => return, + Some(slider) => slider, + }; + + if let Ok(value) = slider.value().parse::<f32>() { + event_bus.publish(on_change(value), root); + vdom.schedule_render(); + } + }) + .finish()]) + .finish() + } +} impl<'a, Message> From<Slider<'a, Message>> for Element<'a, Message> where - Message: 'static, + Message: 'static + Copy, { fn from(slider: Slider<'a, Message>) -> Element<'a, Message> { Element::new(slider) |