diff options
| author | 2019-09-19 15:01:12 +0200 | |
|---|---|---|
| committer | 2019-09-19 15:01:12 +0200 | |
| commit | f9de39ddaa3020a9585b1648afb0ead45dfd7aa9 (patch) | |
| tree | 04289787e353b4b059354d22ce53f2b79464431c | |
| parent | dd093c79d7da84675be648c7df2ebfc85b5039f2 (diff) | |
| download | iced-f9de39ddaa3020a9585b1648afb0ead45dfd7aa9.tar.gz iced-f9de39ddaa3020a9585b1648afb0ead45dfd7aa9.tar.bz2 iced-f9de39ddaa3020a9585b1648afb0ead45dfd7aa9.zip | |
Unify `web` and `ggez` tour examples :tada:
| -rw-r--r-- | .github/workflows/integration.yml | 2 | ||||
| -rw-r--r-- | Cargo.toml | 7 | ||||
| -rw-r--r-- | examples/tour/Cargo.toml | 29 | ||||
| -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) | 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 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.rs | 5 | ||||
| -rw-r--r-- | examples/tour/tour.rs | 578 | ||||
| -rw-r--r-- | src/color.rs (renamed from web/src/color.rs) | 3 | ||||
| -rw-r--r-- | src/element.rs | 9 | ||||
| -rw-r--r-- | src/lib.rs | 2 | ||||
| -rw-r--r-- | src/user_interface.rs | 10 | ||||
| -rw-r--r-- | src/widget.rs | 2 | ||||
| -rw-r--r-- | src/widget/button.rs | 2 | ||||
| -rw-r--r-- | src/widget/checkbox.rs | 2 | ||||
| -rw-r--r-- | src/widget/column.rs | 2 | ||||
| -rw-r--r-- | src/widget/image.rs | 4 | ||||
| -rw-r--r-- | src/widget/radio.rs | 2 | ||||
| -rw-r--r-- | src/widget/row.rs | 2 | ||||
| -rw-r--r-- | src/widget/slider.rs | 2 | ||||
| -rw-r--r-- | src/widget/text.rs | 2 | ||||
| -rw-r--r-- | web/examples/tour/Cargo.toml | 17 | ||||
| l--------- | web/examples/tour/resources/ferris.png | 1 | ||||
| -rw-r--r-- | web/src/lib.rs | 4 | 
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 @@ -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.ttfBinary files differ index 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.pngBinary files differ index 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.pngBinary files differ index 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/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)      } @@ -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 { | 
