summaryrefslogtreecommitdiffstats
path: root/web
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2019-09-14 20:54:50 +0200
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2019-09-14 20:54:50 +0200
commit27ac85a9d98474904c422a891e54888376dec00a (patch)
treee268525f5bdb3e9631ba1156aaa6b02561dd03d4 /web
parenta97401aed2a173260a4abfdb65a77975ce6c0f01 (diff)
downloadiced-27ac85a9d98474904c422a891e54888376dec00a.tar.gz
iced-27ac85a9d98474904c422a891e54888376dec00a.tar.bz2
iced-27ac85a9d98474904c422a891e54888376dec00a.zip
Draft web runtime and widgets
Diffstat (limited to 'web')
-rw-r--r--web/Cargo.toml1
-rw-r--r--web/examples/tour/Cargo.toml1
-rw-r--r--web/examples/tour/src/lib.rs27
-rw-r--r--web/examples/tour/src/tour.rs43
-rw-r--r--web/src/color.rs16
-rw-r--r--web/src/element.rs47
-rw-r--r--web/src/lib.rs27
-rw-r--r--web/src/widget.rs20
-rw-r--r--web/src/widget/button.rs16
-rw-r--r--web/src/widget/checkbox.rs14
-rw-r--r--web/src/widget/column.rs48
-rw-r--r--web/src/widget/image.rs11
-rw-r--r--web/src/widget/radio.rs14
-rw-r--r--web/src/widget/row.rs36
-rw-r--r--web/src/widget/slider.rs16
-rw-r--r--web/src/widget/text.rs13
16 files changed, 321 insertions, 29 deletions
diff --git a/web/Cargo.toml b/web/Cargo.toml
index acc5f18b..6d8c37b1 100644
--- a/web/Cargo.toml
+++ b/web/Cargo.toml
@@ -17,6 +17,7 @@ maintenance = { status = "actively-developed" }
[dependencies]
iced = { version = "0.1.0-alpha", path = ".." }
dodrio = "0.1.0"
+futures = "0.1"
[dependencies.web-sys]
version = "0.3.27"
diff --git a/web/examples/tour/Cargo.toml b/web/examples/tour/Cargo.toml
index 15f38fa7..c2db46ec 100644
--- a/web/examples/tour/Cargo.toml
+++ b/web/examples/tour/Cargo.toml
@@ -11,6 +11,7 @@ crate-type = ["cdylib"]
[dependencies]
iced_web = { path = "../.." }
wasm-bindgen = "0.2.50"
+futures = "0.1"
log = "0.4"
console_error_panic_hook = "0.1.6"
console_log = "0.1.2"
diff --git a/web/examples/tour/src/lib.rs b/web/examples/tour/src/lib.rs
index e747a193..30855e8b 100644
--- a/web/examples/tour/src/lib.rs
+++ b/web/examples/tour/src/lib.rs
@@ -1,8 +1,35 @@
+use futures::{future, Future};
+use iced_web::UserInterface;
use wasm_bindgen::prelude::*;
+mod tour;
+
+use tour::Tour;
+
#[wasm_bindgen(start)]
pub fn run() {
console_error_panic_hook::set_once();
console_log::init_with_level(log::Level::Trace)
.expect("Initialize logging");
+
+ let tour = Tour::new();
+
+ tour.run();
+}
+
+impl iced_web::UserInterface for Tour {
+ type Message = tour::Message;
+
+ fn update(
+ &mut self,
+ message: tour::Message,
+ ) -> Box<dyn Future<Item = tour::Message, Error = ()>> {
+ self.update(message);
+
+ Box::new(future::err(()))
+ }
+
+ fn view(&mut self) -> iced_web::Element<tour::Message> {
+ self.view()
+ }
}
diff --git a/web/examples/tour/src/tour.rs b/web/examples/tour/src/tour.rs
index d0be99b0..6c24622e 100644
--- a/web/examples/tour/src/tour.rs
+++ b/web/examples/tour/src/tour.rs
@@ -1,12 +1,8 @@
-use super::widget::{
- button, slider, Button, Checkbox, Column, Element, Image, Radio, Row,
- Slider, Text,
+use iced_web::{
+ button, slider, text::HorizontalAlignment, Align, Button, Checkbox, Color,
+ Column, Element, Image, Radio, Row, Slider, Text,
};
-use ggez::graphics::{self, Color, FilterMode, BLACK};
-use ggez::Context;
-use iced::{text::HorizontalAlignment, Align};
-
pub struct Tour {
steps: Steps,
back_button: button::State,
@@ -15,9 +11,9 @@ pub struct Tour {
}
impl Tour {
- pub fn new(context: &mut Context) -> Tour {
+ pub fn new() -> Tour {
Tour {
- steps: Steps::new(context),
+ steps: Steps::new(),
back_button: button::State::new(),
next_button: button::State::new(),
debug: false,
@@ -72,7 +68,7 @@ impl Tour {
.into();
if self.debug {
- element.explain(BLACK)
+ element.explain(Color::BLACK)
} else {
element
}
@@ -92,7 +88,7 @@ struct Steps {
}
impl Steps {
- fn new(context: &mut Context) -> Steps {
+ fn new() -> Steps {
Steps {
steps: vec![
Step::Welcome,
@@ -109,19 +105,10 @@ impl Steps {
size_slider: slider::State::new(),
size: 30,
color_sliders: [slider::State::new(); 3],
- color: BLACK,
+ color: Color::BLACK,
},
Step::Radio { selection: None },
Step::Image {
- ferris: {
- let mut image =
- graphics::Image::new(context, "/ferris.png")
- .expect("Load ferris image");
-
- image.set_filter(FilterMode::Linear);
-
- image
- },
width: 300,
slider: slider::State::new(),
},
@@ -183,7 +170,6 @@ enum Step {
selection: Option<Language>,
},
Image {
- ferris: graphics::Image,
width: u16,
slider: slider::State,
},
@@ -273,11 +259,7 @@ impl<'a> Step {
color_sliders,
color,
} => Self::text(size_slider, *size, color_sliders, *color).into(),
- Step::Image {
- ferris,
- width,
- slider,
- } => Self::image(ferris.clone(), *width, slider).into(),
+ Step::Image { width, slider } => Self::image(*width, slider).into(),
Step::RowsAndColumns {
layout,
spacing_slider,
@@ -489,13 +471,16 @@ impl<'a> Step {
}
fn image(
- ferris: graphics::Image,
width: u16,
slider: &'a mut slider::State,
) -> Column<'a, StepMessage> {
Self::container("Image")
.push(Text::new("An image that tries to keep its aspect ratio."))
- .push(Image::new(ferris).width(width).align_self(Align::Center))
+ .push(
+ Image::new("resources/ferris.png")
+ .width(width)
+ .align_self(Align::Center),
+ )
.push(Slider::new(
slider,
100.0..=500.0,
diff --git a/web/src/color.rs b/web/src/color.rs
new file mode 100644
index 00000000..2624c3c9
--- /dev/null
+++ b/web/src/color.rs
@@ -0,0 +1,16 @@
+#[derive(Debug, Clone, Copy, PartialEq)]
+pub struct Color {
+ pub r: f32,
+ pub g: f32,
+ pub b: f32,
+ pub a: f32,
+}
+
+impl Color {
+ pub const BLACK: Color = Color {
+ r: 0.0,
+ g: 0.0,
+ b: 0.0,
+ a: 1.0,
+ };
+}
diff --git a/web/src/element.rs b/web/src/element.rs
new file mode 100644
index 00000000..c0c9ce5d
--- /dev/null
+++ b/web/src/element.rs
@@ -0,0 +1,47 @@
+use crate::{Color, Widget};
+
+pub struct Element<'a, Message> {
+ pub(crate) widget: Box<dyn Widget<Message> + 'a>,
+}
+
+impl<'a, Message> Element<'a, Message> {
+ pub fn new(widget: impl Widget<Message> + 'a) -> Self {
+ Self {
+ widget: Box::new(widget),
+ }
+ }
+
+ pub fn explain(self, color: Color) -> Element<'a, Message> {
+ self
+ }
+
+ pub fn map<F, B>(self, f: F) -> Element<'a, B>
+ where
+ Message: 'static,
+ B: 'static,
+ F: 'static + Fn(Message) -> B,
+ {
+ Element {
+ widget: Box::new(Map::new(self.widget, f)),
+ }
+ }
+}
+
+struct Map<'a, A, B> {
+ widget: Box<dyn Widget<A> + 'a>,
+ mapper: Box<dyn Fn(A) -> B>,
+}
+
+impl<'a, A, B> Map<'a, A, B> {
+ pub fn new<F>(widget: Box<dyn Widget<A> + 'a>, mapper: F) -> Map<'a, A, B>
+ where
+ F: 'static + Fn(A) -> B,
+ {
+ Map {
+ widget,
+ mapper: Box::new(mapper),
+ }
+ }
+}
+
+impl<'a, A, B> Widget<B> for Map<'a, A, B> {}
diff --git a/web/src/lib.rs b/web/src/lib.rs
index 8b137891..187e8ad9 100644
--- a/web/src/lib.rs
+++ b/web/src/lib.rs
@@ -1 +1,28 @@
+use futures::Future;
+mod color;
+mod element;
+mod widget;
+
+pub use color::Color;
+pub use element::Element;
+pub use iced::Align;
+pub use widget::*;
+
+pub trait UserInterface {
+ type Message;
+
+ fn update(
+ &mut self,
+ message: Self::Message,
+ ) -> Box<dyn Future<Item = Self::Message, Error = ()>>;
+
+ fn view(&mut self) -> Element<Self::Message>;
+
+ fn run(mut self)
+ where
+ Self: Sized,
+ {
+ let element = self.view();
+ }
+}
diff --git a/web/src/widget.rs b/web/src/widget.rs
new file mode 100644
index 00000000..5cb89a60
--- /dev/null
+++ b/web/src/widget.rs
@@ -0,0 +1,20 @@
+pub mod button;
+pub mod slider;
+pub mod text;
+
+mod checkbox;
+mod column;
+mod image;
+mod radio;
+mod row;
+
+pub use button::Button;
+pub use checkbox::Checkbox;
+pub use column::Column;
+pub use image::Image;
+pub use radio::Radio;
+pub use row::Row;
+pub use slider::Slider;
+pub use text::Text;
+
+pub trait Widget<Message> {}
diff --git a/web/src/widget/button.rs b/web/src/widget/button.rs
new file mode 100644
index 00000000..1f117d82
--- /dev/null
+++ b/web/src/widget/button.rs
@@ -0,0 +1,16 @@
+use crate::{Element, Widget};
+
+pub use iced::button::{Class, State};
+
+pub type Button<'a, Message> = iced::Button<'a, Message>;
+
+impl<'a, Message> Widget<Message> for Button<'a, Message> {}
+
+impl<'a, Message> From<Button<'a, Message>> for Element<'a, Message>
+where
+ Message: 'static,
+{
+ fn from(button: Button<'a, Message>) -> Element<'a, Message> {
+ Element::new(button)
+ }
+}
diff --git a/web/src/widget/checkbox.rs b/web/src/widget/checkbox.rs
new file mode 100644
index 00000000..a231d801
--- /dev/null
+++ b/web/src/widget/checkbox.rs
@@ -0,0 +1,14 @@
+use crate::{Color, Element, Widget};
+
+pub type Checkbox<Message> = iced::Checkbox<Color, Message>;
+
+impl<Message> Widget<Message> for Checkbox<Message> {}
+
+impl<'a, Message> From<Checkbox<Message>> for Element<'a, Message>
+where
+ Message: 'static,
+{
+ 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
new file mode 100644
index 00000000..84068ce6
--- /dev/null
+++ b/web/src/widget/column.rs
@@ -0,0 +1,48 @@
+use crate::{Align, Element, Widget};
+
+pub struct Column<'a, Message> {
+ children: Vec<Element<'a, Message>>,
+}
+
+impl<'a, Message> Column<'a, Message> {
+ pub fn new() -> Self {
+ Self {
+ children: Vec::new(),
+ }
+ }
+
+ pub fn spacing(self, _spacing: u16) -> Self {
+ self
+ }
+
+ pub fn padding(self, _padding: u16) -> Self {
+ self
+ }
+
+ pub fn max_width(self, _max_width: u16) -> Self {
+ self
+ }
+
+ pub fn align_items(self, _align: Align) -> Self {
+ self
+ }
+
+ pub fn push<E>(mut self, element: E) -> Self
+ where
+ E: Into<Element<'a, Message>>,
+ {
+ self.children.push(element.into());
+ self
+ }
+}
+
+impl<'a, Message> Widget<Message> for Column<'a, Message> {}
+
+impl<'a, Message> From<Column<'a, Message>> for Element<'a, Message>
+where
+ Message: 'static,
+{
+ fn from(column: Column<'a, Message>) -> Element<'a, Message> {
+ Element::new(column)
+ }
+}
diff --git a/web/src/widget/image.rs b/web/src/widget/image.rs
new file mode 100644
index 00000000..ac144fd8
--- /dev/null
+++ b/web/src/widget/image.rs
@@ -0,0 +1,11 @@
+use crate::{Element, Widget};
+
+pub type Image<'a> = iced::Image<&'a str>;
+
+impl<'a, Message> Widget<Message> for Image<'a> {}
+
+impl<'a, Message> From<Image<'a>> for Element<'a, Message> {
+ fn from(image: Image<'a>) -> Element<'a, Message> {
+ Element::new(image)
+ }
+}
diff --git a/web/src/widget/radio.rs b/web/src/widget/radio.rs
new file mode 100644
index 00000000..0c28b46f
--- /dev/null
+++ b/web/src/widget/radio.rs
@@ -0,0 +1,14 @@
+use crate::{Color, Element, Widget};
+
+pub type Radio<Message> = iced::Radio<Color, Message>;
+
+impl<Message> Widget<Message> for Radio<Message> {}
+
+impl<'a, Message> From<Radio<Message>> for Element<'a, Message>
+where
+ Message: 'static,
+{
+ 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
new file mode 100644
index 00000000..fc474ec3
--- /dev/null
+++ b/web/src/widget/row.rs
@@ -0,0 +1,36 @@
+use crate::{Element, Widget};
+
+pub struct Row<'a, Message> {
+ children: Vec<Element<'a, Message>>,
+}
+
+impl<'a, Message> Row<'a, Message> {
+ pub fn new() -> Self {
+ Self {
+ children: Vec::new(),
+ }
+ }
+
+ pub fn spacing(self, _spacing: u16) -> Self {
+ self
+ }
+
+ pub fn push<E>(mut self, element: E) -> Self
+ where
+ E: Into<Element<'a, Message>>,
+ {
+ self.children.push(element.into());
+ self
+ }
+}
+
+impl<'a, Message> Widget<Message> for Row<'a, Message> {}
+
+impl<'a, Message> From<Row<'a, Message>> for Element<'a, Message>
+where
+ Message: 'static,
+{
+ fn from(column: Row<'a, Message>) -> Element<'a, Message> {
+ Element::new(column)
+ }
+}
diff --git a/web/src/widget/slider.rs b/web/src/widget/slider.rs
new file mode 100644
index 00000000..9c83befb
--- /dev/null
+++ b/web/src/widget/slider.rs
@@ -0,0 +1,16 @@
+use crate::{Element, Widget};
+
+pub use iced::slider::State;
+
+pub type Slider<'a, Message> = iced::Slider<'a, Message>;
+
+impl<'a, Message> Widget<Message> for Slider<'a, Message> {}
+
+impl<'a, Message> From<Slider<'a, Message>> for Element<'a, Message>
+where
+ Message: 'static,
+{
+ fn from(slider: Slider<'a, Message>) -> Element<'a, Message> {
+ Element::new(slider)
+ }
+}
diff --git a/web/src/widget/text.rs b/web/src/widget/text.rs
new file mode 100644
index 00000000..0c1f75b6
--- /dev/null
+++ b/web/src/widget/text.rs
@@ -0,0 +1,13 @@
+use crate::{Color, Element, Widget};
+
+pub use iced::text::HorizontalAlignment;
+
+pub type Text = iced::Text<Color>;
+
+impl<'a, Message> Widget<Message> for Text {}
+
+impl<'a, Message> From<Text> for Element<'a, Message> {
+ fn from(text: Text) -> Element<'a, Message> {
+ Element::new(text)
+ }
+}