diff options
author | 2019-09-19 15:01:12 +0200 | |
---|---|---|
committer | 2019-09-19 15:01:12 +0200 | |
commit | f9de39ddaa3020a9585b1648afb0ead45dfd7aa9 (patch) | |
tree | 04289787e353b4b059354d22ce53f2b79464431c /examples | |
parent | dd093c79d7da84675be648c7df2ebfc85b5039f2 (diff) | |
download | iced-f9de39ddaa3020a9585b1648afb0ead45dfd7aa9.tar.gz iced-f9de39ddaa3020a9585b1648afb0ead45dfd7aa9.tar.bz2 iced-f9de39ddaa3020a9585b1648afb0ead45dfd7aa9.zip |
Unify `web` and `ggez` tour examples :tada:
Diffstat (limited to 'examples')
-rw-r--r-- | examples/tour/Cargo.toml | 29 | ||||
-rw-r--r-- | examples/tour/index.html | 13 | ||||
-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) | bin | 171272 -> 171272 bytes | |||
-rw-r--r-- | examples/tour/resources/ferris.png (renamed from examples/resources/ferris.png) | bin | 33061 -> 33061 bytes | |||
-rw-r--r-- | examples/tour/resources/ui.png (renamed from examples/resources/ui.png) | bin | 16691 -> 16691 bytes | |||
-rw-r--r-- | examples/tour/src/iced_ggez.rs | 6 | ||||
-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.rs | 11 | ||||
-rw-r--r-- | examples/tour/src/tour.rs (renamed from examples/tour/tour.rs) | 47 | ||||
-rw-r--r-- | examples/tour/src/web.rs | 33 | ||||
-rw-r--r-- | examples/tour/src/widget.rs | 5 |
21 files changed, 194 insertions, 69 deletions
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/examples/tour/index.html b/examples/tour/index.html new file mode 100644 index 00000000..b17ac4a2 --- /dev/null +++ b/examples/tour/index.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> + <head> + <meta http-equiv="Content-type" content="text/html; charset=utf-8"/> + <title>Tour - Iced</title> + </head> + <body> + <script type="module"> + 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 Binary files differindex 2b6392ff..2b6392ff 100644 --- a/examples/resources/Roboto-Regular.ttf +++ b/examples/tour/resources/Roboto-Regular.ttf diff --git a/examples/resources/ferris.png b/examples/tour/resources/ferris.png Binary files differindex ebce1a14..ebce1a14 100644 --- a/examples/resources/ferris.png +++ b/examples/tour/resources/ferris.png diff --git a/examples/resources/ui.png b/examples/tour/resources/ui.png Binary files differindex 4fd3beb3..4fd3beb3 100644 --- a/examples/resources/ui.png +++ b/examples/tour/resources/ui.png 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/examples/tour/tour.rs b/examples/tour/src/tour.rs index d0be99b0..4bd7c8a3 100644 --- a/examples/tour/tour.rs +++ b/examples/tour/src/tour.rs @@ -1,12 +1,8 @@ -use super::widget::{ - button, slider, Button, Checkbox, Column, Element, Image, Radio, Row, - Slider, Text, +use crate::widget::{ + 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, @@ -313,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 \ @@ -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/examples/tour/src/web.rs b/examples/tour/src/web.rs new file mode 100644 index 00000000..a0a3060f --- /dev/null +++ b/examples/tour/src/web.rs @@ -0,0 +1,33 @@ +use futures::Future; +use iced_web::UserInterface; +use wasm_bindgen::prelude::*; + +use crate::tour::{self, 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, + ) -> Option<Box<dyn Future<Output = tour::Message>>> { + self.update(message); + + None + } + + fn view(&mut self) -> iced_web::Element<tour::Message> { + self.view() + } +} 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::*; |