summaryrefslogtreecommitdiffstats
path: root/web
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2019-09-15 18:53:13 +0200
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2019-09-15 18:53:13 +0200
commit655978f480c32bc696f0d5fe2fff834bfbf238ea (patch)
treeee9af0e0e802c7f85004fd28d3854dbb8bfcb4f5 /web
parent8834772fa70850559f7bd82cc8432394e3fd9db7 (diff)
downloadiced-655978f480c32bc696f0d5fe2fff834bfbf238ea.tar.gz
iced-655978f480c32bc696f0d5fe2fff834bfbf238ea.tar.bz2
iced-655978f480c32bc696f0d5fe2fff834bfbf238ea.zip
Draft nodes for missing widgets
Diffstat (limited to 'web')
-rw-r--r--web/Cargo.toml5
-rw-r--r--web/examples/tour/index.html2
l---------web/examples/tour/resources/ferris.png1
-rw-r--r--web/examples/tour/src/tour.rs4
-rw-r--r--web/src/widget.rs6
-rw-r--r--web/src/widget/button.rs4
-rw-r--r--web/src/widget/checkbox.rs39
-rw-r--r--web/src/widget/column.rs5
-rw-r--r--web/src/widget/image.rs25
-rw-r--r--web/src/widget/radio.rs40
-rw-r--r--web/src/widget/row.rs5
-rw-r--r--web/src/widget/slider.rs55
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)