diff options
author | 2019-09-04 11:09:57 +0200 | |
---|---|---|
committer | 2019-09-04 11:09:57 +0200 | |
commit | c583a2174d28878a6b1a31288e80b96fac62e799 (patch) | |
tree | 36c80d9a0565980d6bbee62c548c8db142555ba2 /examples | |
parent | 2c35103035e47485f2fb049f86b3c00feb4b99d2 (diff) | |
download | iced-c583a2174d28878a6b1a31288e80b96fac62e799.tar.gz iced-c583a2174d28878a6b1a31288e80b96fac62e799.tar.bz2 iced-c583a2174d28878a6b1a31288e80b96fac62e799.zip |
Improve tour example
Diffstat (limited to 'examples')
-rw-r--r-- | examples/ggez/main.rs | 21 | ||||
-rw-r--r-- | examples/ggez/renderer.rs | 26 | ||||
-rw-r--r-- | examples/ggez/renderer/button.rs | 1 | ||||
-rw-r--r-- | examples/ggez/renderer/debugger.rs | 30 | ||||
-rw-r--r-- | examples/ggez/renderer/image.rs | 51 | ||||
-rw-r--r-- | examples/ggez/renderer/text.rs | 17 | ||||
-rw-r--r-- | examples/ggez/tour.rs | 381 | ||||
-rw-r--r-- | examples/ggez/widget.rs | 3 | ||||
-rw-r--r-- | examples/resources/Roboto-LICENSE | 202 | ||||
-rw-r--r-- | examples/resources/Roboto-Regular.ttf | bin | 0 -> 171272 bytes | |||
-rw-r--r-- | examples/resources/ferris.png | bin | 0 -> 33061 bytes |
11 files changed, 546 insertions, 186 deletions
diff --git a/examples/ggez/main.rs b/examples/ggez/main.rs index 329bde81..0a6a2005 100644 --- a/examples/ggez/main.rs +++ b/examples/ggez/main.rs @@ -16,8 +16,8 @@ pub fn main() -> ggez::GameResult { let (context, event_loop) = { &mut ggez::ContextBuilder::new("iced", "ggez") .window_mode(ggez::conf::WindowMode { - width: 1280.0, - height: 1024.0, + width: 850.0, + height: 850.0, ..ggez::conf::WindowMode::default() }) .build()? @@ -39,6 +39,7 @@ pub fn main() -> ggez::GameResult { struct Game { spritesheet: graphics::Image, + font: graphics::Font, tour: Tour, events: Vec<iced::Event>, @@ -51,7 +52,8 @@ impl Game { Ok(Game { spritesheet: graphics::Image::new(context, "/ui.png").unwrap(), - tour: Tour::new(), + font: graphics::Font::new(context, "/Roboto-Regular.ttf").unwrap(), + tour: Tour::new(context), events: Vec::new(), cache: Some(iced::Cache::default()), @@ -126,7 +128,7 @@ impl event::EventHandler for Game { } fn draw(&mut self, context: &mut ggez::Context) -> ggez::GameResult { - graphics::clear(context, [0.3, 0.3, 0.6, 1.0].into()); + graphics::clear(context, graphics::WHITE); let screen = graphics::screen_coordinates(context); @@ -134,14 +136,17 @@ impl event::EventHandler for Game { let layout = self.tour.layout(); let content = Column::new() - .width(screen.w as u32) - .height(screen.h as u32) + .width(screen.w as u16) + .height(screen.h as u16) .align_items(iced::Align::Center) .justify_content(iced::Justify::Center) .push(layout); - let renderer = - &mut Renderer::new(context, self.spritesheet.clone()); + let renderer = &mut Renderer::new( + context, + self.spritesheet.clone(), + self.font, + ); let mut ui = iced::UserInterface::build( content, diff --git a/examples/ggez/renderer.rs b/examples/ggez/renderer.rs index ccf12aba..8746dd96 100644 --- a/examples/ggez/renderer.rs +++ b/examples/ggez/renderer.rs @@ -1,24 +1,38 @@ mod button; mod checkbox; +mod debugger; +mod image; mod radio; mod slider; mod text; -use ggez::graphics::{self, spritebatch::SpriteBatch, Image}; +use ggez::graphics::{ + self, spritebatch::SpriteBatch, Font, Image, MeshBuilder, +}; use ggez::Context; pub struct Renderer<'a> { pub context: &'a mut Context, pub sprites: SpriteBatch, pub spritesheet: Image, + pub font: Font, + font_size: f32, + debug_mesh: Option<MeshBuilder>, } impl Renderer<'_> { - pub fn new(context: &mut Context, spritesheet: Image) -> Renderer { + pub fn new( + context: &mut Context, + spritesheet: Image, + font: Font, + ) -> Renderer { Renderer { context, sprites: SpriteBatch::new(spritesheet.clone()), spritesheet, + font, + font_size: 20.0, + debug_mesh: None, } } @@ -37,5 +51,13 @@ impl Renderer<'_> { graphics::FilterMode::Linear, ) .expect("Draw text"); + + if let Some(debug_mesh) = self.debug_mesh.take() { + let mesh = + debug_mesh.build(self.context).expect("Build debug mesh"); + + graphics::draw(self.context, &mesh, graphics::DrawParam::default()) + .expect("Draw debug mesh"); + } } } diff --git a/examples/ggez/renderer/button.rs b/examples/ggez/renderer/button.rs index fc3ea7ca..486e07ed 100644 --- a/examples/ggez/renderer/button.rs +++ b/examples/ggez/renderer/button.rs @@ -104,6 +104,7 @@ impl button::Renderer for Renderer<'_> { let mut text = Text::new(TextFragment { text: String::from(label), + font: Some(self.font), scale: Some(Scale { x: 20.0, y: 20.0 }), ..Default::default() }); diff --git a/examples/ggez/renderer/debugger.rs b/examples/ggez/renderer/debugger.rs new file mode 100644 index 00000000..98124795 --- /dev/null +++ b/examples/ggez/renderer/debugger.rs @@ -0,0 +1,30 @@ +use super::Renderer; +use ggez::graphics::{Color, DrawMode, MeshBuilder, Rect}; + +impl iced::renderer::Debugger for Renderer<'_> { + type Color = Color; + + fn explain(&mut self, layout: &iced::Layout<'_>, color: Color) { + let bounds = layout.bounds(); + + let mut debug_mesh = + self.debug_mesh.take().unwrap_or(MeshBuilder::new()); + + debug_mesh.rectangle( + DrawMode::stroke(1.0), + Rect { + x: bounds.x, + y: bounds.y, + w: bounds.width, + h: bounds.height, + }, + color, + ); + + self.debug_mesh = Some(debug_mesh); + + for child in layout.children() { + self.explain(&child, color); + } + } +} diff --git a/examples/ggez/renderer/image.rs b/examples/ggez/renderer/image.rs new file mode 100644 index 00000000..c3ead5c9 --- /dev/null +++ b/examples/ggez/renderer/image.rs @@ -0,0 +1,51 @@ +use super::Renderer; + +use ggez::{graphics, nalgebra}; +use iced::image; + +impl image::Renderer<graphics::Image> for Renderer<'_> { + fn node( + &self, + style: iced::Style, + image: &graphics::Image, + width: Option<u16>, + height: Option<u16>, + _source: Option<iced::Rectangle<u16>>, + ) -> iced::Node { + let aspect_ratio = image.width() as f32 / image.height() as f32; + + let style = match (width, height) { + (Some(width), Some(height)) => style.width(width).height(height), + (Some(width), None) => style + .width(width) + .height((width as f32 / aspect_ratio).round() as u16), + (None, Some(height)) => style + .height(height) + .width((height as f32 * aspect_ratio).round() as u16), + (None, None) => style.width(image.width()).height(image.height()), + }; + + iced::Node::new(style) + } + + fn draw( + &mut self, + image: &graphics::Image, + bounds: iced::Rectangle, + _source: Option<iced::Rectangle<u16>>, + ) { + // 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, + graphics::DrawParam::new() + .dest(nalgebra::Point2::new(bounds.x, bounds.y)) + .scale(nalgebra::Vector2::new( + bounds.width / image.width() as f32, + bounds.height / image.height() as f32, + )), + ) + .expect("Draw image"); + } +} diff --git a/examples/ggez/renderer/text.rs b/examples/ggez/renderer/text.rs index a6f782fc..ecf1481e 100644 --- a/examples/ggez/renderer/text.rs +++ b/examples/ggez/renderer/text.rs @@ -6,7 +6,13 @@ use std::cell::RefCell; use std::f32; impl text::Renderer<Color> for Renderer<'_> { - fn node(&self, style: iced::Style, content: &str, size: f32) -> iced::Node { + fn node( + &self, + style: iced::Style, + content: &str, + size: Option<u16>, + ) -> iced::Node { + let font = self.font; let font_cache = graphics::font_cache(self.context); let content = String::from(content); @@ -17,6 +23,7 @@ impl text::Renderer<Color> for Renderer<'_> { // I noticed that the first measure is the one that matters in // practice. Here, we use a RefCell to store the cached measurement. let measure = RefCell::new(None); + let size = size.map(f32::from).unwrap_or(self.font_size); iced::Node::with_measure(style, move |bounds| { let mut measure = measure.borrow_mut(); @@ -35,6 +42,7 @@ impl text::Renderer<Color> for Renderer<'_> { let mut text = Text::new(TextFragment { text: content.clone(), + font: Some(font), scale: Some(Scale { x: size, y: size }), ..Default::default() }); @@ -71,13 +79,16 @@ impl text::Renderer<Color> for Renderer<'_> { &mut self, bounds: iced::Rectangle, content: &str, - size: f32, + size: Option<u16>, color: Option<Color>, horizontal_alignment: text::HorizontalAlignment, _vertical_alignment: text::VerticalAlignment, ) { + let size = size.map(f32::from).unwrap_or(self.font_size); + let mut text = Text::new(TextFragment { text: String::from(content), + font: Some(self.font), scale: Some(Scale { x: size, y: size }), ..Default::default() }); @@ -101,7 +112,7 @@ impl text::Renderer<Color> for Renderer<'_> { x: bounds.x, y: bounds.y, }, - color, + color.or(Some(graphics::BLACK)), ); } } diff --git a/examples/ggez/tour.rs b/examples/ggez/tour.rs index 19982aa4..c2126675 100644 --- a/examples/ggez/tour.rs +++ b/examples/ggez/tour.rs @@ -1,22 +1,26 @@ use super::widget::{ - button, slider, Button, Checkbox, Column, Element, Radio, Row, Slider, Text, + button, slider, Button, Checkbox, Column, Element, Image, Radio, Row, + Slider, Text, }; -use ggez::graphics::{Color, BLACK}; +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() -> Tour { + pub fn new(context: &mut Context) -> Tour { Tour { - steps: Steps::new(), + steps: Steps::new(context), back_button: button::State::new(), next_button: button::State::new(), + debug: false, } } @@ -29,7 +33,7 @@ impl Tour { self.steps.advance(); } Message::StepMessage(step_msg) => { - self.steps.update(step_msg); + self.steps.update(step_msg, &mut self.debug); } } } @@ -39,6 +43,7 @@ impl Tour { steps, back_button, next_button, + .. } = self; let mut controls = Row::new(); @@ -59,12 +64,18 @@ impl Tour { ); } - Column::new() + let element: Element<_> = Column::new() .max_width(500) .spacing(20) - .push(steps.layout().map(Message::StepMessage)) + .push(steps.layout(self.debug).map(Message::StepMessage)) .push(controls) - .into() + .into(); + + if self.debug { + element.explain(BLACK) + } else { + element + } } } @@ -81,44 +92,52 @@ struct Steps { } impl Steps { - fn new() -> Steps { + fn new(context: &mut Context) -> Steps { Steps { steps: vec![ Step::Welcome, - Step::Buttons { - primary: button::State::new(), - secondary: button::State::new(), - positive: button::State::new(), - }, - Step::Checkbox { is_checked: false }, - Step::Radio { selection: None }, 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::RowsAndColumns { - layout: Layout::Row, - spacing_slider: slider::State::new(), - spacing: 20, + 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) { - self.steps[self.current].update(msg); + fn update(&mut self, msg: StepMessage, debug: &mut bool) { + self.steps[self.current].update(msg, debug); } - fn layout(&mut self) -> Element<StepMessage> { - self.steps[self.current].layout() + fn layout(&mut self, debug: bool) -> Element<StepMessage> { + self.steps[self.current].layout(debug) } fn advance(&mut self) { @@ -145,52 +164,51 @@ impl Steps { enum Step { Welcome, - Buttons { - primary: button::State, - secondary: button::State, - positive: button::State, - }, - Checkbox { - is_checked: bool, - }, - Radio { - selection: Option<Language>, - }, 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, }, - RowsAndColumns { - layout: Layout, - spacing_slider: slider::State, - spacing: u16, + Radio { + selection: Option<Language>, }, + Image { + ferris: graphics::Image, + width: u16, + slider: slider::State, + }, + Debugger, End, } #[derive(Debug, Clone, Copy)] pub enum StepMessage { - CheckboxToggled(bool), - LanguageSelected(Language), SliderChanged(f32), - TextSizeChanged(f32), - TextColorChanged(Color), LayoutChanged(Layout), SpacingChanged(f32), + TextSizeChanged(f32), + TextColorChanged(Color), + LanguageSelected(Language), + ImageWidthChanged(f32), + DebugToggled(bool), } impl<'a> Step { - fn update(&mut self, msg: StepMessage) { + fn update(&mut self, msg: StepMessage, debug: &mut bool) { match msg { - StepMessage::CheckboxToggled(value) => { - if let Step::Checkbox { is_checked } = self { - *is_checked = value; + StepMessage::DebugToggled(value) => { + if let Step::Debugger = self { + *debug = value; } } StepMessage::LanguageSelected(language) => { @@ -223,31 +241,30 @@ impl<'a> Step { *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::Buttons { .. } => true, - Step::Checkbox { is_checked } => *is_checked, 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 layout(&mut self) -> Element<StepMessage> { + fn layout(&mut self, debug: bool) -> Element<StepMessage> { match self { Step::Welcome => Self::welcome().into(), - Step::Buttons { - primary, - secondary, - positive, - } => Self::buttons(primary, secondary, positive).into(), - Step::Checkbox { is_checked } => Self::checkbox(*is_checked).into(), Step::Radio { selection } => Self::radio(*selection).into(), Step::Slider { state, value } => Self::slider(state, *value).into(), Step::Text { @@ -256,6 +273,11 @@ 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::RowsAndColumns { layout, spacing_slider, @@ -263,6 +285,7 @@ impl<'a> Step { } => { Self::rows_and_columns(*layout, spacing_slider, *spacing).into() } + Step::Debugger => Self::debugger(debug).into(), Step::End => Self::end().into(), } } @@ -277,80 +300,26 @@ impl<'a> Step { fn welcome() -> Column<'a, StepMessage> { Self::container("Welcome!") .push(Text::new( - "This is a tour that introduces some of the features and \ - concepts related with UI development in Iced.", + "This a simple tour meant to showcase a bunch of widgets that \ + can be easily implemented on top of Iced.", )) .push(Text::new( - "You will need to interact with the UI in order to reach the \ - end!", - )) - } - - fn buttons( - primary: &'a mut button::State, - secondary: &'a mut button::State, - positive: &'a mut button::State, - ) -> Column<'a, StepMessage> { - Self::container("Button") - .push(Text::new("A button can fire actions when clicked.")) - .push(Text::new( - "As of now, there are 3 different types of buttons: \ - primary, secondary, and positive.", - )) - .push(Button::new(primary, "Primary")) - .push( - Button::new(secondary, "Secondary") - .class(button::Class::Secondary), - ) - .push( - Button::new(positive, "Positive") - .class(button::Class::Positive), - ) - .push(Text::new( - "Additional types will be added in the near future! Choose \ - each type smartly depending on the situation.", + "Iced is a renderer-agnostic GUI library for Rust focused on \ + simplicity and type-safety. It is heavily inspired by Elm.", )) - } - - fn checkbox(is_checked: bool) -> Column<'a, StepMessage> { - Self::container("Checkbox") .push(Text::new( - "A box that can be checked. Useful to build toggle controls.", - )) - .push(Checkbox::new( - is_checked, - "Show \"Next\" button", - StepMessage::CheckboxToggled, + "It was originally born as part of Coffee, an opinionated \ + 2D game engine for Rust.", )) .push(Text::new( - "A checkbox always has a label, and both the checkbox and its \ - label can be clicked to toggle it.", + "Iced does not provide a built-in renderer. This example runs \ + on a fairly simple renderer built on top of ggez, another \ + game library.", )) - } - - fn radio(selection: Option<Language>) -> Column<'a, StepMessage> { - let question = Column::new() - .padding(20) - .spacing(10) - .push(Text::new("Iced is written in...")) - .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. Like \ - a checkbox, it always has a label.", + "You will need to interact with the UI in order to reach the \ + end!", )) - .push(question) } fn slider( @@ -378,55 +347,6 @@ impl<'a> Step { ) } - 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 {} points", size)).size(size), - ) - .push(Slider::new( - size_slider, - 10.0..=50.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 rows_and_columns( layout: Layout, spacing_slider: &'a mut slider::State, @@ -463,7 +383,7 @@ impl<'a> Step { .spacing(10) .push(Slider::new( spacing_slider, - 0.0..=100.0, + 0.0..=80.0, spacing as f32, StepMessage::SpacingChanged, )) @@ -489,10 +409,127 @@ impl<'a> Step { .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 extended as more features are added.", + "This tour will be updated as more features are added.", )) .push(Text::new("Make sure to keep an eye on it!")) } diff --git a/examples/ggez/widget.rs b/examples/ggez/widget.rs index a5fcccc6..9a141c83 100644 --- a/examples/ggez/widget.rs +++ b/examples/ggez/widget.rs @@ -1,12 +1,13 @@ use super::Renderer; -use ggez::graphics::Color; +use ggez::graphics::{self, Color}; pub use iced::{button, slider, Button, 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 Column<'a, Message> = iced::Column<'a, Message, Renderer<'a>>; pub type Row<'a, Message> = iced::Row<'a, Message, Renderer<'a>>; diff --git a/examples/resources/Roboto-LICENSE b/examples/resources/Roboto-LICENSE new file mode 100644 index 00000000..75b52484 --- /dev/null +++ b/examples/resources/Roboto-LICENSE @@ -0,0 +1,202 @@ +
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/examples/resources/Roboto-Regular.ttf b/examples/resources/Roboto-Regular.ttf Binary files differnew file mode 100644 index 00000000..2b6392ff --- /dev/null +++ b/examples/resources/Roboto-Regular.ttf diff --git a/examples/resources/ferris.png b/examples/resources/ferris.png Binary files differnew file mode 100644 index 00000000..ebce1a14 --- /dev/null +++ b/examples/resources/ferris.png |