summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/integration.yml2
-rw-r--r--Cargo.toml7
-rw-r--r--examples/tour/Cargo.toml29
-rw-r--r--examples/tour/index.html (renamed from web/examples/tour/index.html)6
-rw-r--r--examples/tour/resources/Roboto-LICENSE (renamed from examples/resources/Roboto-LICENSE)0
-rw-r--r--examples/tour/resources/Roboto-Regular.ttf (renamed from examples/resources/Roboto-Regular.ttf)bin171272 -> 171272 bytes
-rw-r--r--examples/tour/resources/ferris.png (renamed from examples/resources/ferris.png)bin33061 -> 33061 bytes
-rw-r--r--examples/tour/resources/ui.png (renamed from examples/resources/ui.png)bin16691 -> 16691 bytes
-rw-r--r--examples/tour/src/iced_ggez.rs6
-rw-r--r--examples/tour/src/iced_ggez/main.rs (renamed from examples/tour/main.rs)28
-rw-r--r--examples/tour/src/iced_ggez/renderer.rs (renamed from examples/tour/renderer.rs)20
-rw-r--r--examples/tour/src/iced_ggez/renderer/button.rs (renamed from examples/tour/renderer/button.rs)0
-rw-r--r--examples/tour/src/iced_ggez/renderer/checkbox.rs (renamed from examples/tour/renderer/checkbox.rs)0
-rw-r--r--examples/tour/src/iced_ggez/renderer/debugger.rs (renamed from examples/tour/renderer/debugger.rs)10
-rw-r--r--examples/tour/src/iced_ggez/renderer/image.rs (renamed from examples/tour/renderer/image.rs)45
-rw-r--r--examples/tour/src/iced_ggez/renderer/radio.rs (renamed from examples/tour/renderer/radio.rs)0
-rw-r--r--examples/tour/src/iced_ggez/renderer/slider.rs (renamed from examples/tour/renderer/slider.rs)0
-rw-r--r--examples/tour/src/iced_ggez/renderer/text.rs (renamed from examples/tour/renderer/text.rs)10
-rw-r--r--examples/tour/src/iced_ggez/widget.rs (renamed from examples/tour/widget.rs)6
-rw-r--r--examples/tour/src/lib.rs11
-rw-r--r--examples/tour/src/tour.rs (renamed from web/examples/tour/src/tour.rs)2
-rw-r--r--examples/tour/src/web.rs (renamed from web/examples/tour/src/lib.rs)4
-rw-r--r--examples/tour/src/widget.rs5
-rw-r--r--examples/tour/tour.rs578
-rw-r--r--src/color.rs (renamed from web/src/color.rs)3
-rw-r--r--src/element.rs9
-rw-r--r--src/lib.rs2
-rw-r--r--src/user_interface.rs10
-rw-r--r--src/widget.rs2
-rw-r--r--src/widget/button.rs2
-rw-r--r--src/widget/checkbox.rs2
-rw-r--r--src/widget/column.rs2
-rw-r--r--src/widget/image.rs4
-rw-r--r--src/widget/radio.rs2
-rw-r--r--src/widget/row.rs2
-rw-r--r--src/widget/slider.rs2
-rw-r--r--src/widget/text.rs2
-rw-r--r--web/examples/tour/Cargo.toml17
l---------web/examples/tour/resources/ferris.png1
-rw-r--r--web/src/lib.rs4
40 files changed, 166 insertions, 669 deletions
diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml
index f574e930..884a4e9e 100644
--- a/.github/workflows/integration.yml
+++ b/.github/workflows/integration.yml
@@ -18,4 +18,4 @@ jobs:
sudo apt-get install -y libasound2-dev libudev-dev
- uses: actions/checkout@master
- name: Run tests
- run: cargo test --verbose --all-features
+ run: cargo test --verbose --all --all-features
diff --git a/Cargo.toml b/Cargo.toml
index 07a4e9ac..51c7305a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -24,13 +24,8 @@ twox-hash = "1.5"
# Enable to obtain conversion traits
winit = { version = "0.20.0-alpha3", optional = true }
-[dev-dependencies]
-# A personal `ggez` fork that introduces a `FontCache` type to measure text
-# efficiently and fixes HiDPI issues.
-ggez = { version = "0.5", git = "https://github.com/hecrj/ggez.git" }
-
[workspace]
members = [
"web",
- "web/examples/tour",
+ "examples/tour",
]
diff --git a/examples/tour/Cargo.toml b/examples/tour/Cargo.toml
new file mode 100644
index 00000000..08d108d9
--- /dev/null
+++ b/examples/tour/Cargo.toml
@@ -0,0 +1,29 @@
+[package]
+name = "iced_tour"
+version = "0.0.0"
+authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]
+description = "Tour example for Iced"
+license = "MIT"
+repository = "https://github.com/hecrj/iced"
+edition = "2018"
+publish = false
+
+[[bin]]
+name = "ggez"
+path = "src/iced_ggez/main.rs"
+
+[dependencies]
+futures-preview = "=0.3.0-alpha.18"
+
+[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
+iced = { path = "../.." }
+# A personal `ggez` fork that introduces a `FontCache` type to measure text
+# efficiently and fixes HiDPI issues.
+ggez = { version = "0.5", git = "https://github.com/hecrj/ggez.git" }
+
+[target.'cfg(target_arch = "wasm32")'.dependencies]
+iced_web = { path = "../../web" }
+wasm-bindgen = "0.2.50"
+log = "0.4"
+console_error_panic_hook = "0.1.6"
+console_log = "0.1.2"
diff --git a/web/examples/tour/index.html b/examples/tour/index.html
index 527cc54c..b17ac4a2 100644
--- a/web/examples/tour/index.html
+++ b/examples/tour/index.html
@@ -2,12 +2,12 @@
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
- <title>Web Tour - Iced</title>
+ <title>Tour - Iced</title>
</head>
<body>
<script type="module">
- import init from "./pkg/iced_web_tour.js";
- init("./pkg/iced_web_tour_bg.wasm");
+ import init from "./pkg/iced_tour.js";
+ init("./pkg/iced_tour_bg.wasm");
</script>
</body>
</html>
diff --git a/examples/resources/Roboto-LICENSE b/examples/tour/resources/Roboto-LICENSE
index 75b52484..75b52484 100644
--- a/examples/resources/Roboto-LICENSE
+++ b/examples/tour/resources/Roboto-LICENSE
diff --git a/examples/resources/Roboto-Regular.ttf b/examples/tour/resources/Roboto-Regular.ttf
index 2b6392ff..2b6392ff 100644
--- a/examples/resources/Roboto-Regular.ttf
+++ b/examples/tour/resources/Roboto-Regular.ttf
Binary files differ
diff --git a/examples/resources/ferris.png b/examples/tour/resources/ferris.png
index ebce1a14..ebce1a14 100644
--- a/examples/resources/ferris.png
+++ b/examples/tour/resources/ferris.png
Binary files differ
diff --git a/examples/resources/ui.png b/examples/tour/resources/ui.png
index 4fd3beb3..4fd3beb3 100644
--- a/examples/resources/ui.png
+++ b/examples/tour/resources/ui.png
Binary files differ
diff --git a/examples/tour/src/iced_ggez.rs b/examples/tour/src/iced_ggez.rs
new file mode 100644
index 00000000..4a9c0ef4
--- /dev/null
+++ b/examples/tour/src/iced_ggez.rs
@@ -0,0 +1,6 @@
+mod renderer;
+mod widget;
+
+pub use renderer::Cache as ImageCache;
+pub use renderer::Renderer;
+pub use widget::*;
diff --git a/examples/tour/main.rs b/examples/tour/src/iced_ggez/main.rs
index 571bc2e2..a8cf09e5 100644
--- a/examples/tour/main.rs
+++ b/examples/tour/src/iced_ggez/main.rs
@@ -1,10 +1,4 @@
-mod renderer;
-mod tour;
-mod widget;
-
-use renderer::Renderer;
-use tour::Tour;
-use widget::Column;
+use iced_tour::{iced_ggez, Tour};
use ggez;
use ggez::event;
@@ -26,10 +20,7 @@ pub fn main() -> ggez::GameResult {
filesystem::mount(
context,
- std::path::Path::new(&format!(
- "{}/examples/resources",
- env!("CARGO_MANIFEST_DIR")
- )),
+ std::path::Path::new(env!("CARGO_MANIFEST_DIR")),
true,
);
@@ -41,6 +32,7 @@ pub fn main() -> ggez::GameResult {
struct Game {
spritesheet: graphics::Image,
font: graphics::Font,
+ images: iced_ggez::ImageCache,
tour: Tour,
events: Vec<iced::Event>,
@@ -52,9 +44,12 @@ impl Game {
graphics::set_default_filter(context, graphics::FilterMode::Nearest);
Ok(Game {
- spritesheet: graphics::Image::new(context, "/ui.png").unwrap(),
- font: graphics::Font::new(context, "/Roboto-Regular.ttf").unwrap(),
- tour: Tour::new(context),
+ spritesheet: graphics::Image::new(context, "/resources/ui.png")
+ .unwrap(),
+ font: graphics::Font::new(context, "/resources/Roboto-Regular.ttf")
+ .unwrap(),
+ images: iced_ggez::ImageCache::new(),
+ tour: Tour::new(),
events: Vec::new(),
cache: Some(iced::Cache::default()),
@@ -136,7 +131,7 @@ impl event::EventHandler for Game {
let (messages, cursor) = {
let view = self.tour.view();
- let content = Column::new()
+ let content = iced_ggez::Column::new()
.width(screen.w as u16)
.height(screen.h as u16)
.padding(20)
@@ -144,8 +139,9 @@ impl event::EventHandler for Game {
.justify_content(iced::Justify::Center)
.push(view);
- let renderer = &mut Renderer::new(
+ let renderer = &mut iced_ggez::Renderer::new(
context,
+ &mut self.images,
self.spritesheet.clone(),
self.font,
);
diff --git a/examples/tour/renderer.rs b/examples/tour/src/iced_ggez/renderer.rs
index 8746dd96..e3181eaa 100644
--- a/examples/tour/renderer.rs
+++ b/examples/tour/src/iced_ggez/renderer.rs
@@ -11,8 +11,11 @@ use ggez::graphics::{
};
use ggez::Context;
+pub use image::Cache;
+
pub struct Renderer<'a> {
pub context: &'a mut Context,
+ pub images: &'a mut image::Cache,
pub sprites: SpriteBatch,
pub spritesheet: Image,
pub font: Font,
@@ -20,14 +23,16 @@ pub struct Renderer<'a> {
debug_mesh: Option<MeshBuilder>,
}
-impl Renderer<'_> {
+impl<'a> Renderer<'a> {
pub fn new(
- context: &mut Context,
+ context: &'a mut Context,
+ images: &'a mut image::Cache,
spritesheet: Image,
font: Font,
- ) -> Renderer {
+ ) -> Renderer<'a> {
Renderer {
context,
+ images,
sprites: SpriteBatch::new(spritesheet.clone()),
spritesheet,
font,
@@ -61,3 +66,12 @@ impl Renderer<'_> {
}
}
}
+
+pub fn into_color(color: iced::Color) -> graphics::Color {
+ graphics::Color {
+ r: color.r,
+ g: color.g,
+ b: color.b,
+ a: color.a,
+ }
+}
diff --git a/examples/tour/renderer/button.rs b/examples/tour/src/iced_ggez/renderer/button.rs
index 486e07ed..486e07ed 100644
--- a/examples/tour/renderer/button.rs
+++ b/examples/tour/src/iced_ggez/renderer/button.rs
diff --git a/examples/tour/renderer/checkbox.rs b/examples/tour/src/iced_ggez/renderer/checkbox.rs
index 20a91be5..20a91be5 100644
--- a/examples/tour/renderer/checkbox.rs
+++ b/examples/tour/src/iced_ggez/renderer/checkbox.rs
diff --git a/examples/tour/renderer/debugger.rs b/examples/tour/src/iced_ggez/renderer/debugger.rs
index 98124795..c6727881 100644
--- a/examples/tour/renderer/debugger.rs
+++ b/examples/tour/src/iced_ggez/renderer/debugger.rs
@@ -1,10 +1,10 @@
-use super::Renderer;
-use ggez::graphics::{Color, DrawMode, MeshBuilder, Rect};
+use super::{into_color, Renderer};
+use ggez::graphics::{DrawMode, MeshBuilder, Rect};
impl iced::renderer::Debugger for Renderer<'_> {
- type Color = Color;
+ type Color = iced::Color;
- fn explain(&mut self, layout: &iced::Layout<'_>, color: Color) {
+ fn explain(&mut self, layout: &iced::Layout<'_>, color: iced::Color) {
let bounds = layout.bounds();
let mut debug_mesh =
@@ -18,7 +18,7 @@ impl iced::renderer::Debugger for Renderer<'_> {
w: bounds.width,
h: bounds.height,
},
- color,
+ into_color(color),
);
self.debug_mesh = Some(debug_mesh);
diff --git a/examples/tour/renderer/image.rs b/examples/tour/src/iced_ggez/renderer/image.rs
index c3ead5c9..17c6a56e 100644
--- a/examples/tour/renderer/image.rs
+++ b/examples/tour/src/iced_ggez/renderer/image.rs
@@ -3,15 +3,48 @@ use super::Renderer;
use ggez::{graphics, nalgebra};
use iced::image;
-impl image::Renderer<graphics::Image> for Renderer<'_> {
+pub struct Cache {
+ images: std::collections::HashMap<String, graphics::Image>,
+}
+
+impl Cache {
+ pub fn new() -> Self {
+ Self {
+ images: std::collections::HashMap::new(),
+ }
+ }
+
+ fn get<'a>(
+ &mut self,
+ name: &'a str,
+ context: &mut ggez::Context,
+ ) -> graphics::Image {
+ if let Some(image) = self.images.get(name) {
+ return image.clone();
+ }
+
+ let mut image = graphics::Image::new(context, &format!("/{}", name))
+ .expect("Load ferris image");
+
+ image.set_filter(graphics::FilterMode::Linear);
+
+ self.images.insert(name.to_string(), image.clone());
+
+ image
+ }
+}
+
+impl<'a> image::Renderer<&'a str> for Renderer<'_> {
fn node(
- &self,
+ &mut self,
style: iced::Style,
- image: &graphics::Image,
+ name: &&'a str,
width: Option<u16>,
height: Option<u16>,
_source: Option<iced::Rectangle<u16>>,
) -> iced::Node {
+ let image = self.images.get(name, self.context);
+
let aspect_ratio = image.width() as f32 / image.height() as f32;
let style = match (width, height) {
@@ -30,15 +63,17 @@ impl image::Renderer<graphics::Image> for Renderer<'_> {
fn draw(
&mut self,
- image: &graphics::Image,
+ name: &&'a str,
bounds: iced::Rectangle,
_source: Option<iced::Rectangle<u16>>,
) {
+ let image = self.images.get(name, self.context);
+
// We should probably use batches to draw images efficiently and keep
// draw side-effect free, but this is good enough for the example.
graphics::draw(
self.context,
- image,
+ &image,
graphics::DrawParam::new()
.dest(nalgebra::Point2::new(bounds.x, bounds.y))
.scale(nalgebra::Vector2::new(
diff --git a/examples/tour/renderer/radio.rs b/examples/tour/src/iced_ggez/renderer/radio.rs
index 0f7815d6..0f7815d6 100644
--- a/examples/tour/renderer/radio.rs
+++ b/examples/tour/src/iced_ggez/renderer/radio.rs
diff --git a/examples/tour/renderer/slider.rs b/examples/tour/src/iced_ggez/renderer/slider.rs
index 146cee18..146cee18 100644
--- a/examples/tour/renderer/slider.rs
+++ b/examples/tour/src/iced_ggez/renderer/slider.rs
diff --git a/examples/tour/renderer/text.rs b/examples/tour/src/iced_ggez/renderer/text.rs
index ecf1481e..b5010639 100644
--- a/examples/tour/renderer/text.rs
+++ b/examples/tour/src/iced_ggez/renderer/text.rs
@@ -1,11 +1,11 @@
-use super::Renderer;
-use ggez::graphics::{self, mint, Align, Color, Scale, Text, TextFragment};
+use super::{into_color, Renderer};
+use ggez::graphics::{self, mint, Align, Scale, Text, TextFragment};
use iced::text;
use std::cell::RefCell;
use std::f32;
-impl text::Renderer<Color> for Renderer<'_> {
+impl text::Renderer<iced::Color> for Renderer<'_> {
fn node(
&self,
style: iced::Style,
@@ -80,7 +80,7 @@ impl text::Renderer<Color> for Renderer<'_> {
bounds: iced::Rectangle,
content: &str,
size: Option<u16>,
- color: Option<Color>,
+ color: Option<iced::Color>,
horizontal_alignment: text::HorizontalAlignment,
_vertical_alignment: text::VerticalAlignment,
) {
@@ -112,7 +112,7 @@ impl text::Renderer<Color> for Renderer<'_> {
x: bounds.x,
y: bounds.y,
},
- color.or(Some(graphics::BLACK)),
+ color.or(Some(iced::Color::BLACK)).map(into_color),
);
}
}
diff --git a/examples/tour/widget.rs b/examples/tour/src/iced_ggez/widget.rs
index 9a141c83..a365daca 100644
--- a/examples/tour/widget.rs
+++ b/examples/tour/src/iced_ggez/widget.rs
@@ -1,13 +1,11 @@
use super::Renderer;
-use ggez::graphics::{self, Color};
-
-pub use iced::{button, slider, Button, Slider};
+pub use iced::{button, slider, text, Align, Button, Color, Slider};
pub type Text = iced::Text<Color>;
pub type Checkbox<Message> = iced::Checkbox<Color, Message>;
pub type Radio<Message> = iced::Radio<Color, Message>;
-pub type Image = iced::Image<graphics::Image>;
+pub type Image<'a> = iced::Image<&'a str>;
pub type Column<'a, Message> = iced::Column<'a, Message, Renderer<'a>>;
pub type Row<'a, Message> = iced::Row<'a, Message, Renderer<'a>>;
diff --git a/examples/tour/src/lib.rs b/examples/tour/src/lib.rs
new file mode 100644
index 00000000..eb41fcd9
--- /dev/null
+++ b/examples/tour/src/lib.rs
@@ -0,0 +1,11 @@
+pub mod tour;
+
+pub use tour::{Message, Tour};
+
+mod widget;
+
+#[cfg(target_arch = "wasm32")]
+mod web;
+
+#[cfg(not(target_arch = "wasm32"))]
+pub mod iced_ggez;
diff --git a/web/examples/tour/src/tour.rs b/examples/tour/src/tour.rs
index 9a60e092..4bd7c8a3 100644
--- a/web/examples/tour/src/tour.rs
+++ b/examples/tour/src/tour.rs
@@ -1,4 +1,4 @@
-use iced_web::{
+use crate::widget::{
button, slider, text::HorizontalAlignment, Align, Button, Checkbox, Color,
Column, Element, Image, Radio, Row, Slider, Text,
};
diff --git a/web/examples/tour/src/lib.rs b/examples/tour/src/web.rs
index dbf04df8..a0a3060f 100644
--- a/web/examples/tour/src/lib.rs
+++ b/examples/tour/src/web.rs
@@ -2,9 +2,7 @@ use futures::Future;
use iced_web::UserInterface;
use wasm_bindgen::prelude::*;
-mod tour;
-
-use tour::Tour;
+use crate::tour::{self, Tour};
#[wasm_bindgen(start)]
pub fn run() {
diff --git a/examples/tour/src/widget.rs b/examples/tour/src/widget.rs
new file mode 100644
index 00000000..9c2c4d5b
--- /dev/null
+++ b/examples/tour/src/widget.rs
@@ -0,0 +1,5 @@
+#[cfg(target_arch = "wasm32")]
+pub use iced_web::*;
+
+#[cfg(not(target_arch = "wasm32"))]
+pub use crate::iced_ggez::*;
diff --git a/examples/tour/tour.rs b/examples/tour/tour.rs
deleted file mode 100644
index d0be99b0..00000000
--- a/examples/tour/tour.rs
+++ /dev/null
@@ -1,578 +0,0 @@
-use super::widget::{
- button, slider, Button, Checkbox, 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,
- next_button: button::State,
- debug: bool,
-}
-
-impl Tour {
- pub fn new(context: &mut Context) -> Tour {
- Tour {
- steps: Steps::new(context),
- back_button: button::State::new(),
- next_button: button::State::new(),
- debug: false,
- }
- }
-
- pub fn update(&mut self, event: Message) {
- match event {
- Message::BackPressed => {
- self.steps.go_back();
- }
- Message::NextPressed => {
- self.steps.advance();
- }
- Message::StepMessage(step_msg) => {
- self.steps.update(step_msg, &mut self.debug);
- }
- }
- }
-
- pub fn view(&mut self) -> Element<Message> {
- let Tour {
- steps,
- back_button,
- next_button,
- ..
- } = self;
-
- let mut controls = Row::new();
-
- if steps.has_previous() {
- controls = controls.push(
- Button::new(back_button, "Back")
- .on_press(Message::BackPressed)
- .class(button::Class::Secondary),
- );
- }
-
- controls = controls.push(Column::new());
-
- if steps.can_continue() {
- controls = controls.push(
- Button::new(next_button, "Next").on_press(Message::NextPressed),
- );
- }
-
- let element: Element<_> = Column::new()
- .max_width(500)
- .spacing(20)
- .push(steps.view(self.debug).map(Message::StepMessage))
- .push(controls)
- .into();
-
- if self.debug {
- element.explain(BLACK)
- } else {
- element
- }
- }
-}
-
-#[derive(Debug, Clone, Copy)]
-pub enum Message {
- BackPressed,
- NextPressed,
- StepMessage(StepMessage),
-}
-
-struct Steps {
- steps: Vec<Step>,
- current: usize,
-}
-
-impl Steps {
- fn new(context: &mut Context) -> Steps {
- Steps {
- steps: vec![
- Step::Welcome,
- Step::Slider {
- state: slider::State::new(),
- value: 50,
- },
- Step::RowsAndColumns {
- layout: Layout::Row,
- spacing_slider: slider::State::new(),
- spacing: 20,
- },
- Step::Text {
- size_slider: slider::State::new(),
- size: 30,
- color_sliders: [slider::State::new(); 3],
- 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(),
- },
- Step::Debugger,
- Step::End,
- ],
- current: 0,
- }
- }
-
- fn update(&mut self, msg: StepMessage, debug: &mut bool) {
- self.steps[self.current].update(msg, debug);
- }
-
- fn view(&mut self, debug: bool) -> Element<StepMessage> {
- self.steps[self.current].view(debug)
- }
-
- fn advance(&mut self) {
- if self.can_continue() {
- self.current += 1;
- }
- }
-
- fn go_back(&mut self) {
- if self.has_previous() {
- self.current -= 1;
- }
- }
-
- fn has_previous(&self) -> bool {
- self.current > 0
- }
-
- fn can_continue(&self) -> bool {
- self.current + 1 < self.steps.len()
- && self.steps[self.current].can_continue()
- }
-}
-
-enum Step {
- Welcome,
- Slider {
- state: slider::State,
- value: u16,
- },
- RowsAndColumns {
- layout: Layout,
- spacing_slider: slider::State,
- spacing: u16,
- },
- Text {
- size_slider: slider::State,
- size: u16,
- color_sliders: [slider::State; 3],
- color: Color,
- },
- Radio {
- selection: Option<Language>,
- },
- Image {
- ferris: graphics::Image,
- width: u16,
- slider: slider::State,
- },
- Debugger,
- End,
-}
-
-#[derive(Debug, Clone, Copy)]
-pub enum StepMessage {
- SliderChanged(f32),
- LayoutChanged(Layout),
- SpacingChanged(f32),
- TextSizeChanged(f32),
- TextColorChanged(Color),
- LanguageSelected(Language),
- ImageWidthChanged(f32),
- DebugToggled(bool),
-}
-
-impl<'a> Step {
- fn update(&mut self, msg: StepMessage, debug: &mut bool) {
- match msg {
- StepMessage::DebugToggled(value) => {
- if let Step::Debugger = self {
- *debug = value;
- }
- }
- StepMessage::LanguageSelected(language) => {
- if let Step::Radio { selection } = self {
- *selection = Some(language);
- }
- }
- StepMessage::SliderChanged(new_value) => {
- if let Step::Slider { value, .. } = self {
- *value = new_value.round() as u16;
- }
- }
- StepMessage::TextSizeChanged(new_size) => {
- if let Step::Text { size, .. } = self {
- *size = new_size.round() as u16;
- }
- }
- StepMessage::TextColorChanged(new_color) => {
- if let Step::Text { color, .. } = self {
- *color = new_color;
- }
- }
- StepMessage::LayoutChanged(new_layout) => {
- if let Step::RowsAndColumns { layout, .. } = self {
- *layout = new_layout;
- }
- }
- StepMessage::SpacingChanged(new_spacing) => {
- if let Step::RowsAndColumns { spacing, .. } = self {
- *spacing = new_spacing.round() as u16;
- }
- }
- StepMessage::ImageWidthChanged(new_width) => {
- if let Step::Image { width, .. } = self {
- *width = new_width.round() as u16;
- }
- }
- };
- }
-
- fn can_continue(&self) -> bool {
- match self {
- Step::Welcome => true,
- Step::Radio { selection } => *selection == Some(Language::Rust),
- Step::Slider { .. } => true,
- Step::Text { .. } => true,
- Step::Image { .. } => true,
- Step::RowsAndColumns { .. } => true,
- Step::Debugger => true,
- Step::End => false,
- }
- }
-
- fn view(&mut self, debug: bool) -> Element<StepMessage> {
- match self {
- Step::Welcome => Self::welcome().into(),
- Step::Radio { selection } => Self::radio(*selection).into(),
- Step::Slider { state, value } => Self::slider(state, *value).into(),
- Step::Text {
- size_slider,
- size,
- 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::RowsAndColumns {
- layout,
- spacing_slider,
- spacing,
- } => {
- Self::rows_and_columns(*layout, spacing_slider, *spacing).into()
- }
- Step::Debugger => Self::debugger(debug).into(),
- Step::End => Self::end().into(),
- }
- }
-
- fn container(title: &str) -> Column<'a, StepMessage> {
- Column::new()
- .spacing(20)
- .align_items(Align::Stretch)
- .push(Text::new(title).size(50))
- }
-
- fn welcome() -> Column<'a, StepMessage> {
- Self::container("Welcome!")
- .push(Text::new(
- "This a simple tour meant to showcase a bunch of widgets that \
- can be easily implemented on top of Iced.",
- ))
- .push(Text::new(
- "Iced is a renderer-agnostic GUI library for Rust focused on \
- simplicity and type-safety. It is heavily inspired by Elm.",
- ))
- .push(Text::new(
- "It was originally born as part of Coffee, an opinionated \
- 2D game engine for Rust.",
- ))
- .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.",
- ))
- .push(Text::new(
- "You will need to interact with the UI in order to reach the \
- end!",
- ))
- }
-
- fn slider(
- state: &'a mut slider::State,
- value: u16,
- ) -> Column<'a, StepMessage> {
- Self::container("Slider")
- .push(Text::new(
- "A slider allows you to smoothly select a value from a range \
- of values.",
- ))
- .push(Text::new(
- "The following slider lets you choose an integer from \
- 0 to 100:",
- ))
- .push(Slider::new(
- state,
- 0.0..=100.0,
- value as f32,
- StepMessage::SliderChanged,
- ))
- .push(
- Text::new(&value.to_string())
- .horizontal_alignment(HorizontalAlignment::Center),
- )
- }
-
- fn rows_and_columns(
- layout: Layout,
- spacing_slider: &'a mut slider::State,
- spacing: u16,
- ) -> Column<'a, StepMessage> {
- let row_radio = Radio::new(
- Layout::Row,
- "Row",
- Some(layout),
- StepMessage::LayoutChanged,
- );
-
- let column_radio = Radio::new(
- Layout::Column,
- "Column",
- Some(layout),
- StepMessage::LayoutChanged,
- );
-
- let layout_section: Element<_> = match layout {
- Layout::Row => Row::new()
- .spacing(spacing)
- .push(row_radio)
- .push(column_radio)
- .into(),
- Layout::Column => Column::new()
- .spacing(spacing)
- .push(row_radio)
- .push(column_radio)
- .into(),
- };
-
- let spacing_section = Column::new()
- .spacing(10)
- .push(Slider::new(
- spacing_slider,
- 0.0..=80.0,
- spacing as f32,
- StepMessage::SpacingChanged,
- ))
- .push(
- Text::new(&format!("{} px", spacing))
- .horizontal_alignment(HorizontalAlignment::Center),
- );
-
- Self::container("Rows and columns")
- .spacing(spacing)
- .push(Text::new(
- "Iced uses a layout model based on flexbox to position UI \
- elements.",
- ))
- .push(Text::new(
- "Rows and columns can be used to distribute content \
- horizontally or vertically, respectively.",
- ))
- .push(layout_section)
- .push(Text::new(
- "You can also easily change the spacing between elements:",
- ))
- .push(spacing_section)
- }
-
- fn text(
- size_slider: &'a mut slider::State,
- size: u16,
- color_sliders: &'a mut [slider::State; 3],
- color: Color,
- ) -> Column<'a, StepMessage> {
- let size_section = Column::new()
- .padding(20)
- .spacing(20)
- .push(Text::new("You can change its size:"))
- .push(
- Text::new(&format!("This text is {} pixels", size)).size(size),
- )
- .push(Slider::new(
- size_slider,
- 10.0..=70.0,
- size as f32,
- StepMessage::TextSizeChanged,
- ));
-
- let [red, green, blue] = color_sliders;
- let color_section = Column::new()
- .padding(20)
- .spacing(20)
- .push(Text::new("And its color:"))
- .push(Text::new(&format!("{:?}", color)).color(color))
- .push(
- Row::new()
- .spacing(10)
- .push(Slider::new(red, 0.0..=1.0, color.r, move |r| {
- StepMessage::TextColorChanged(Color { r, ..color })
- }))
- .push(Slider::new(green, 0.0..=1.0, color.g, move |g| {
- StepMessage::TextColorChanged(Color { g, ..color })
- }))
- .push(Slider::new(blue, 0.0..=1.0, color.b, move |b| {
- StepMessage::TextColorChanged(Color { b, ..color })
- })),
- );
-
- Self::container("Text")
- .push(Text::new(
- "Text is probably the most essential widget for your UI. \
- It will try to adapt to the dimensions of its container.",
- ))
- .push(size_section)
- .push(color_section)
- }
-
- fn radio(selection: Option<Language>) -> Column<'a, StepMessage> {
- let question = Column::new()
- .padding(20)
- .spacing(10)
- .push(Text::new("Iced is written in...").size(24))
- .push(Language::all().iter().cloned().fold(
- Column::new().padding(10).spacing(20),
- |choices, language| {
- choices.push(Radio::new(
- language,
- language.into(),
- selection,
- StepMessage::LanguageSelected,
- ))
- },
- ));
-
- Self::container("Radio button")
- .push(Text::new(
- "A radio button is normally used to represent a choice... \
- Surprise test!",
- ))
- .push(question)
- .push(Text::new(
- "Iced works very well with iterators! The list above is \
- basically created by folding a column over the different \
- choices, creating a radio button for each one of them!",
- ))
- }
-
- 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(Slider::new(
- slider,
- 100.0..=500.0,
- width as f32,
- StepMessage::ImageWidthChanged,
- ))
- .push(
- Text::new(&format!("Width: {} px", width.to_string()))
- .horizontal_alignment(HorizontalAlignment::Center),
- )
- }
-
- fn debugger(debug: bool) -> Column<'a, StepMessage> {
- Self::container("Debugger")
- .push(Text::new(
- "You can ask Iced to visually explain the layouting of the \
- different elements comprising your UI!",
- ))
- .push(Text::new(
- "Give it a shot! Check the following checkbox to be able to \
- see element boundaries.",
- ))
- .push(Checkbox::new(
- debug,
- "Explain layout",
- StepMessage::DebugToggled,
- ))
- .push(Text::new("Feel free to go back and take a look."))
- }
-
- fn end() -> Column<'a, StepMessage> {
- Self::container("You reached the end!")
- .push(Text::new(
- "This tour will be updated as more features are added.",
- ))
- .push(Text::new("Make sure to keep an eye on it!"))
- }
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub enum Language {
- Rust,
- Elm,
- Ruby,
- Haskell,
- C,
- Other,
-}
-
-impl Language {
- fn all() -> [Language; 6] {
- [
- Language::C,
- Language::Elm,
- Language::Ruby,
- Language::Haskell,
- Language::Rust,
- Language::Other,
- ]
- }
-}
-
-impl From<Language> for &str {
- fn from(language: Language) -> &'static str {
- match language {
- Language::Rust => "Rust",
- Language::Elm => "Elm",
- Language::Ruby => "Ruby",
- Language::Haskell => "Haskell",
- Language::C => "C",
- Language::Other => "Other",
- }
- }
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub enum Layout {
- Row,
- Column,
-}
diff --git a/web/src/color.rs b/src/color.rs
index 2624c3c9..5cc3a084 100644
--- a/web/src/color.rs
+++ b/src/color.rs
@@ -1,4 +1,6 @@
+/// A color in the sRGB color space.
#[derive(Debug, Clone, Copy, PartialEq)]
+#[allow(missing_docs)]
pub struct Color {
pub r: f32,
pub g: f32,
@@ -7,6 +9,7 @@ pub struct Color {
}
impl Color {
+ /// The black color.
pub const BLACK: Color = Color {
r: 0.0,
g: 0.0,
diff --git a/src/element.rs b/src/element.rs
index 70d06f42..c13bf4a0 100644
--- a/src/element.rs
+++ b/src/element.rs
@@ -223,7 +223,10 @@ impl<'a, Message, Renderer> Element<'a, Message, Renderer> {
}
}
- pub(crate) fn compute_layout(&self, renderer: &Renderer) -> result::Layout {
+ pub(crate) fn compute_layout(
+ &self,
+ renderer: &mut Renderer,
+ ) -> result::Layout {
let node = self.widget.node(renderer);
node.0.compute_layout(geometry::Size::undefined()).unwrap()
@@ -264,7 +267,7 @@ impl<'a, A, B, Renderer> Widget<B, Renderer> for Map<'a, A, B, Renderer>
where
A: Copy,
{
- fn node(&self, renderer: &Renderer) -> Node {
+ fn node(&self, renderer: &mut Renderer) -> Node {
self.widget.node(renderer)
}
@@ -337,7 +340,7 @@ impl<'a, Message, Renderer> Widget<Message, Renderer>
where
Renderer: renderer::Debugger,
{
- fn node(&self, renderer: &Renderer) -> Node {
+ fn node(&self, renderer: &mut Renderer) -> Node {
self.element.widget.node(renderer)
}
diff --git a/src/lib.rs b/src/lib.rs
index c1c18b41..56eee559 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -200,6 +200,7 @@ pub mod input;
pub mod renderer;
pub mod widget;
+mod color;
mod element;
mod event;
mod hasher;
@@ -215,6 +216,7 @@ mod vector;
#[doc(no_inline)]
pub use stretch::{geometry::Size, number::Number};
+pub use color::Color;
pub use element::Element;
pub use event::Event;
pub use hasher::Hasher;
diff --git a/src/user_interface.rs b/src/user_interface.rs
index 2c7cbf82..6a69f81a 100644
--- a/src/user_interface.rs
+++ b/src/user_interface.rs
@@ -69,7 +69,7 @@ impl<'a, Message, Renderer> UserInterface<'a, Message, Renderer> {
/// let user_interface = UserInterface::build(
/// counter.view(),
/// cache,
- /// &renderer,
+ /// &mut renderer,
/// );
///
/// // Update and draw the user interface here...
@@ -82,7 +82,7 @@ impl<'a, Message, Renderer> UserInterface<'a, Message, Renderer> {
pub fn build<E: Into<Element<'a, Message, Renderer>>>(
root: E,
cache: Cache,
- renderer: &Renderer,
+ renderer: &mut Renderer,
) -> Self {
let root = root.into();
@@ -153,7 +153,7 @@ impl<'a, Message, Renderer> UserInterface<'a, Message, Renderer> {
/// let mut user_interface = UserInterface::build(
/// counter.view(),
/// cache,
- /// &renderer,
+ /// &mut renderer,
/// );
///
/// // Update the user interface
@@ -236,7 +236,7 @@ impl<'a, Message, Renderer> UserInterface<'a, Message, Renderer> {
/// let mut user_interface = UserInterface::build(
/// counter.view(),
/// cache,
- /// &renderer,
+ /// &mut renderer,
/// );
///
/// let messages = user_interface.update(events.drain(..));
@@ -302,7 +302,7 @@ impl Cache {
Cache {
hash: hasher.finish(),
- layout: root.compute_layout(&()),
+ layout: root.compute_layout(&mut ()),
cursor_position: Point::new(0.0, 0.0),
}
}
diff --git a/src/widget.rs b/src/widget.rs
index 30606934..45451f47 100644
--- a/src/widget.rs
+++ b/src/widget.rs
@@ -59,7 +59,7 @@ pub trait Widget<Message, Renderer>: std::fmt::Debug {
/// [`Node`]: ../struct.Node.html
/// [`Widget`]: trait.Widget.html
/// [`Layout`]: ../struct.Layout.html
- fn node(&self, renderer: &Renderer) -> Node;
+ fn node(&self, renderer: &mut Renderer) -> Node;
/// Draws the [`Widget`] using the associated `Renderer`.
///
diff --git a/src/widget/button.rs b/src/widget/button.rs
index 6f5d9908..d2ea70e4 100644
--- a/src/widget/button.rs
+++ b/src/widget/button.rs
@@ -133,7 +133,7 @@ where
Renderer: self::Renderer,
Message: Copy + std::fmt::Debug,
{
- fn node(&self, _renderer: &Renderer) -> Node {
+ fn node(&self, _renderer: &mut Renderer) -> Node {
Node::new(self.style.height(50))
}
diff --git a/src/widget/checkbox.rs b/src/widget/checkbox.rs
index 4ae167ad..6c13252d 100644
--- a/src/widget/checkbox.rs
+++ b/src/widget/checkbox.rs
@@ -98,7 +98,7 @@ where
Color: 'static + Copy + std::fmt::Debug,
Renderer: self::Renderer + text::Renderer<Color>,
{
- fn node(&self, renderer: &Renderer) -> Node {
+ fn node(&self, renderer: &mut Renderer) -> Node {
Row::<(), Renderer>::new()
.spacing(15)
.align_items(Align::Center)
diff --git a/src/widget/column.rs b/src/widget/column.rs
index ff754e98..831f5b8f 100644
--- a/src/widget/column.rs
+++ b/src/widget/column.rs
@@ -136,7 +136,7 @@ impl<'a, Message, Renderer> Column<'a, Message, Renderer> {
impl<'a, Message, Renderer> Widget<Message, Renderer>
for Column<'a, Message, Renderer>
{
- fn node(&self, renderer: &Renderer) -> Node {
+ fn node(&self, renderer: &mut Renderer) -> Node {
let mut children: Vec<Node> = self
.children
.iter()
diff --git a/src/widget/image.rs b/src/widget/image.rs
index 8c869ab8..1601234e 100644
--- a/src/widget/image.rs
+++ b/src/widget/image.rs
@@ -99,7 +99,7 @@ where
Renderer: self::Renderer<I>,
I: Clone,
{
- fn node(&self, renderer: &Renderer) -> Node {
+ fn node(&self, renderer: &mut Renderer) -> Node {
renderer.node(
self.style,
&self.image,
@@ -144,7 +144,7 @@ pub trait Renderer<I> {
/// [`Style`]: ../../struct.Style.html
/// [`Image`]: struct.Image.html
fn node(
- &self,
+ &mut self,
style: Style,
image: &I,
width: Option<u16>,
diff --git a/src/widget/radio.rs b/src/widget/radio.rs
index 27c0ff17..ba082ef5 100644
--- a/src/widget/radio.rs
+++ b/src/widget/radio.rs
@@ -111,7 +111,7 @@ where
Renderer: self::Renderer + text::Renderer<Color>,
Message: Copy + std::fmt::Debug,
{
- fn node(&self, renderer: &Renderer) -> Node {
+ fn node(&self, renderer: &mut Renderer) -> Node {
Row::<(), Renderer>::new()
.spacing(15)
.align_items(Align::Center)
diff --git a/src/widget/row.rs b/src/widget/row.rs
index 959528dc..181020e3 100644
--- a/src/widget/row.rs
+++ b/src/widget/row.rs
@@ -133,7 +133,7 @@ impl<'a, Message, Renderer> Row<'a, Message, Renderer> {
impl<'a, Message, Renderer> Widget<Message, Renderer>
for Row<'a, Message, Renderer>
{
- fn node(&self, renderer: &Renderer) -> Node {
+ fn node(&self, renderer: &mut Renderer) -> Node {
let mut children: Vec<Node> = self
.children
.iter()
diff --git a/src/widget/slider.rs b/src/widget/slider.rs
index 8a0cea01..fb6db8c9 100644
--- a/src/widget/slider.rs
+++ b/src/widget/slider.rs
@@ -107,7 +107,7 @@ impl<'a, Message, Renderer> Widget<Message, Renderer> for Slider<'a, Message>
where
Renderer: self::Renderer,
{
- fn node(&self, _renderer: &Renderer) -> Node {
+ fn node(&self, _renderer: &mut Renderer) -> Node {
Node::new(self.style.height(25))
}
diff --git a/src/widget/text.rs b/src/widget/text.rs
index b529cfd2..457a6814 100644
--- a/src/widget/text.rs
+++ b/src/widget/text.rs
@@ -113,7 +113,7 @@ where
Color: Copy + std::fmt::Debug,
Renderer: self::Renderer<Color>,
{
- fn node(&self, renderer: &Renderer) -> Node {
+ fn node(&self, renderer: &mut Renderer) -> Node {
renderer.node(self.style, &self.content, self.size)
}
diff --git a/web/examples/tour/Cargo.toml b/web/examples/tour/Cargo.toml
deleted file mode 100644
index 65a860e2..00000000
--- a/web/examples/tour/Cargo.toml
+++ /dev/null
@@ -1,17 +0,0 @@
-[package]
-name = "iced_web_tour"
-version = "0.0.0"
-authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]
-edition = "2018"
-publish = false
-
-[lib]
-crate-type = ["cdylib"]
-
-[dependencies]
-iced_web = { path = "../.." }
-wasm-bindgen = "0.2.50"
-futures-preview = "=0.3.0-alpha.18"
-log = "0.4"
-console_error_panic_hook = "0.1.6"
-console_log = "0.1.2"
diff --git a/web/examples/tour/resources/ferris.png b/web/examples/tour/resources/ferris.png
deleted file mode 120000
index 9c4fb51c..00000000
--- a/web/examples/tour/resources/ferris.png
+++ /dev/null
@@ -1 +0,0 @@
-../../../../examples/resources/ferris.png \ No newline at end of file
diff --git a/web/src/lib.rs b/web/src/lib.rs
index 5a0dd6f2..a6dc2b79 100644
--- a/web/src/lib.rs
+++ b/web/src/lib.rs
@@ -3,14 +3,12 @@ use futures::Future;
use std::cell::RefCell;
mod bus;
-mod color;
mod element;
mod widget;
pub use bus::Bus;
-pub use color::Color;
pub use element::Element;
-pub use iced::Align;
+pub use iced::{Align, Color};
pub use widget::*;
pub trait UserInterface {