From 2539042b71d70afd4d8f262783d441e768811ee9 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 28 Apr 2020 06:24:12 +0200 Subject: Remove `Drawable` and rename `State` to `Program` --- examples/bezier_tool/src/main.rs | 91 ++++++++++++---------- examples/clock/Cargo.toml | 3 - examples/clock/src/main.rs | 98 ++++++++++------------- examples/solar_system/Cargo.toml | 3 - examples/solar_system/src/main.rs | 158 +++++++++++++++----------------------- 5 files changed, 157 insertions(+), 196 deletions(-) (limited to 'examples') diff --git a/examples/bezier_tool/src/main.rs b/examples/bezier_tool/src/main.rs index 5473bc07..2112f662 100644 --- a/examples/bezier_tool/src/main.rs +++ b/examples/bezier_tool/src/main.rs @@ -69,10 +69,8 @@ impl Sandbox for Example { mod bezier { use iced::{ - canvas::{ - self, Canvas, Drawable, Event, Frame, Geometry, Path, Stroke, - }, - mouse, ButtonState, Element, Length, Point, Size, + canvas::{self, Canvas, Event, Frame, Geometry, Path, Stroke}, + mouse, ButtonState, Element, Length, Point, Rectangle, Size, }; #[derive(Default)] @@ -106,8 +104,10 @@ mod bezier { curves: &'a [Curve], } - impl<'a> canvas::State for Bezier<'a> { - fn update(&mut self, event: Event, _bounds: Size) -> Option { + impl<'a> canvas::Program for Bezier<'a> { + fn update(&mut self, event: Event, bounds: Size) -> Option { + let bounds = Rectangle::new(Point::ORIGIN, bounds); + match event { Event::Mouse(mouse_event) => match mouse_event { mouse::Event::CursorMoved { x, y } => { @@ -118,46 +118,55 @@ mod bezier { mouse::Event::Input { button: mouse::Button::Left, state: ButtonState::Pressed, - } => match self.state.pending { - None => { - self.state.pending = Some(Pending::One { - from: self.state.cursor_position, - }); - None - } - Some(Pending::One { from }) => { - self.state.pending = Some(Pending::Two { - from, - to: self.state.cursor_position, - }); - - None - } - Some(Pending::Two { from, to }) => { - self.state.pending = None; - - Some(Curve { - from, - to, - control: self.state.cursor_position, - }) + } if bounds.contains(self.state.cursor_position) => { + match self.state.pending { + None => { + self.state.pending = Some(Pending::One { + from: self.state.cursor_position, + }); + None + } + Some(Pending::One { from }) => { + self.state.pending = Some(Pending::Two { + from, + to: self.state.cursor_position, + }); + + None + } + Some(Pending::Two { from, to }) => { + self.state.pending = None; + + Some(Curve { + from, + to, + control: self.state.cursor_position, + }) + } } - }, + } _ => None, }, } } fn draw(&self, bounds: Size) -> Vec { - let curves = self.state.cache.draw(bounds, &self.curves); + let content = self.state.cache.draw(bounds, |frame: &mut Frame| { + Curve::draw_all(self.curves, frame); + + frame.stroke( + &Path::rectangle(Point::ORIGIN, frame.size()), + Stroke::default(), + ); + }); if let Some(pending) = &self.state.pending { let pending_curve = pending.draw(bounds, self.state.cursor_position); - vec![curves, pending_curve] + vec![content, pending_curve] } else { - vec![curves] + vec![content] } } } @@ -169,14 +178,16 @@ mod bezier { control: Point, } - impl Drawable for Curve { - fn draw(&self, frame: &mut Frame) { - let curve = Path::new(|p| { - p.move_to(self.from); - p.quadratic_curve_to(self.control, self.to); + impl Curve { + fn draw_all(curves: &[Curve], frame: &mut Frame) { + let curves = Path::new(|p| { + for curve in curves { + p.move_to(curve.from); + p.quadratic_curve_to(curve.control, curve.to); + } }); - frame.stroke(&curve, Stroke::default().with_width(2.0)); + frame.stroke(&curves, Stroke::default().with_width(2.0)); } } @@ -202,7 +213,7 @@ mod bezier { control: cursor_position, }; - curve.draw(&mut frame); + Curve::draw_all(&[curve], &mut frame); } }; diff --git a/examples/clock/Cargo.toml b/examples/clock/Cargo.toml index 308cbfbb..ab771405 100644 --- a/examples/clock/Cargo.toml +++ b/examples/clock/Cargo.toml @@ -5,9 +5,6 @@ authors = ["Héctor Ramón Jiménez "] edition = "2018" publish = false -[features] -canvas = [] - [dependencies] iced = { path = "../..", features = ["canvas", "async-std", "debug"] } iced_native = { path = "../../native" } diff --git a/examples/clock/src/main.rs b/examples/clock/src/main.rs index 8b3a92c7..c2beddef 100644 --- a/examples/clock/src/main.rs +++ b/examples/clock/src/main.rs @@ -1,6 +1,7 @@ use iced::{ - canvas, executor, Application, Canvas, Color, Command, Container, Element, - Length, Point, Settings, Subscription, Vector, + canvas::{self, Cache, Canvas, Geometry, LineCap, Path, Stroke}, + executor, Application, Color, Command, Container, Element, Length, Point, + Settings, Size, Subscription, Vector, }; pub fn main() { @@ -11,8 +12,8 @@ pub fn main() { } struct Clock { - now: LocalTime, - clock: canvas::Cache, + now: chrono::DateTime, + clock: Cache, } #[derive(Debug, Clone, Copy)] @@ -28,7 +29,7 @@ impl Application for Clock { fn new(_flags: ()) -> (Self, Command) { ( Clock { - now: chrono::Local::now().into(), + now: chrono::Local::now(), clock: Default::default(), }, Command::none(), @@ -59,7 +60,7 @@ impl Application for Clock { } fn view(&mut self) -> Element { - let canvas = Canvas::new(self.clock.with(&self.now)) + let canvas = Canvas::new(self) .width(Length::Units(400)) .height(Length::Units(400)); @@ -73,69 +74,54 @@ impl Application for Clock { } } -#[derive(Debug, PartialEq, Eq)] -struct LocalTime { - hour: u32, - minute: u32, - second: u32, -} - -impl From> for LocalTime { - fn from(date_time: chrono::DateTime) -> LocalTime { +impl canvas::Program for Clock { + fn draw(&self, bounds: Size) -> Vec { use chrono::Timelike; - LocalTime { - hour: date_time.hour(), - minute: date_time.minute(), - second: date_time.second(), - } - } -} - -impl canvas::Drawable for LocalTime { - fn draw(&self, frame: &mut canvas::Frame) { - use canvas::Path; + let clock = self.clock.draw(bounds, |frame| { + let center = frame.center(); + let radius = frame.width().min(frame.height()) / 2.0; - let center = frame.center(); - let radius = frame.width().min(frame.height()) / 2.0; + let background = Path::circle(center, radius); + frame.fill(&background, Color::from_rgb8(0x12, 0x93, 0xD8)); - let clock = Path::circle(center, radius); - frame.fill(&clock, Color::from_rgb8(0x12, 0x93, 0xD8)); + let short_hand = + Path::line(Point::ORIGIN, Point::new(0.0, -0.5 * radius)); - let short_hand = - Path::line(Point::ORIGIN, Point::new(0.0, -0.5 * radius)); + let long_hand = + Path::line(Point::ORIGIN, Point::new(0.0, -0.8 * radius)); - let long_hand = - Path::line(Point::ORIGIN, Point::new(0.0, -0.8 * radius)); + let thin_stroke = Stroke { + width: radius / 100.0, + color: Color::WHITE, + line_cap: LineCap::Round, + ..Stroke::default() + }; - let thin_stroke = canvas::Stroke { - width: radius / 100.0, - color: Color::WHITE, - line_cap: canvas::LineCap::Round, - ..canvas::Stroke::default() - }; + let wide_stroke = Stroke { + width: thin_stroke.width * 3.0, + ..thin_stroke + }; - let wide_stroke = canvas::Stroke { - width: thin_stroke.width * 3.0, - ..thin_stroke - }; + frame.translate(Vector::new(center.x, center.y)); - frame.translate(Vector::new(center.x, center.y)); + frame.with_save(|frame| { + frame.rotate(hand_rotation(self.now.hour(), 12)); + frame.stroke(&short_hand, wide_stroke); + }); - frame.with_save(|frame| { - frame.rotate(hand_rotation(self.hour, 12)); - frame.stroke(&short_hand, wide_stroke); - }); + frame.with_save(|frame| { + frame.rotate(hand_rotation(self.now.minute(), 60)); + frame.stroke(&long_hand, wide_stroke); + }); - frame.with_save(|frame| { - frame.rotate(hand_rotation(self.minute, 60)); - frame.stroke(&long_hand, wide_stroke); + frame.with_save(|frame| { + frame.rotate(hand_rotation(self.now.second(), 60)); + frame.stroke(&long_hand, thin_stroke); + }) }); - frame.with_save(|frame| { - frame.rotate(hand_rotation(self.second, 60)); - frame.stroke(&long_hand, thin_stroke); - }); + vec![clock] } } diff --git a/examples/solar_system/Cargo.toml b/examples/solar_system/Cargo.toml index c88cda50..0555aa96 100644 --- a/examples/solar_system/Cargo.toml +++ b/examples/solar_system/Cargo.toml @@ -5,9 +5,6 @@ authors = ["Héctor Ramón Jiménez "] edition = "2018" publish = false -[features] -canvas = [] - [dependencies] iced = { path = "../..", features = ["canvas", "async-std", "debug"] } iced_native = { path = "../../native" } diff --git a/examples/solar_system/src/main.rs b/examples/solar_system/src/main.rs index 9337c7b5..e2f107bd 100644 --- a/examples/solar_system/src/main.rs +++ b/examples/solar_system/src/main.rs @@ -81,6 +81,12 @@ struct State { } impl State { + const SUN_RADIUS: f32 = 70.0; + const ORBIT_RADIUS: f32 = 150.0; + const EARTH_RADIUS: f32 = 12.0; + const MOON_RADIUS: f32 = 4.0; + const MOON_DISTANCE: f32 = 28.0; + pub fn new() -> State { let now = Instant::now(); let (width, height) = window::Settings::default().size; @@ -95,17 +101,6 @@ impl State { } } - pub fn space(&self) -> Space<'_> { - Space { stars: &self.stars } - } - - pub fn system(&self) -> System { - System { - start: self.start, - now: self.now, - } - } - pub fn update(&mut self, now: Instant) { self.now = now; self.system_cache.clear(); @@ -136,106 +131,81 @@ impl State { } } -impl canvas::State for State { +impl canvas::Program for State { fn draw(&self, bounds: Size) -> Vec { - vec![ - self.space_cache.draw(bounds, self.space()), - self.system_cache.draw(bounds, self.system()), - ] - } -} + use canvas::{Path, Stroke}; + use std::f32::consts::PI; -#[derive(Debug)] -struct Space<'a> { - stars: &'a [(Point, f32)], -} + let background = self.space_cache.draw(bounds, |frame| { + let space = Path::rectangle(Point::new(0.0, 0.0), frame.size()); -impl canvas::Drawable for Space<'_> { - fn draw(&self, frame: &mut canvas::Frame) { - use canvas::Path; + let stars = Path::new(|path| { + for (p, size) in &self.stars { + path.rectangle(*p, Size::new(*size, *size)); + } + }); - let space = Path::rectangle(Point::new(0.0, 0.0), frame.size()); + frame.fill(&space, Color::BLACK); - let stars = Path::new(|path| { - for (p, size) in self.stars { - path.rectangle(*p, Size::new(*size, *size)); - } + frame.translate(frame.center() - Point::ORIGIN); + frame.fill(&stars, Color::WHITE); }); - frame.fill(&space, Color::BLACK); + let system = self.system_cache.draw(bounds, |frame| { + let center = frame.center(); - frame.translate(frame.center() - Point::ORIGIN); - frame.fill(&stars, Color::WHITE); - } -} + let sun = Path::circle(center, Self::SUN_RADIUS); + let orbit = Path::circle(center, Self::ORBIT_RADIUS); -#[derive(Debug)] -struct System { - start: Instant, - now: Instant, -} - -impl System { - const SUN_RADIUS: f32 = 70.0; - const ORBIT_RADIUS: f32 = 150.0; - const EARTH_RADIUS: f32 = 12.0; - const MOON_RADIUS: f32 = 4.0; - const MOON_DISTANCE: f32 = 28.0; -} - -impl canvas::Drawable for System { - fn draw(&self, frame: &mut canvas::Frame) { - use canvas::{Path, Stroke}; - use std::f32::consts::PI; - - let center = frame.center(); - - let sun = Path::circle(center, Self::SUN_RADIUS); - let orbit = Path::circle(center, Self::ORBIT_RADIUS); - - frame.fill(&sun, Color::from_rgb8(0xF9, 0xD7, 0x1C)); - frame.stroke( - &orbit, - Stroke { - width: 1.0, - color: Color::from_rgba8(0, 153, 255, 0.1), - ..Stroke::default() - }, - ); + frame.fill(&sun, Color::from_rgb8(0xF9, 0xD7, 0x1C)); + frame.stroke( + &orbit, + Stroke { + width: 1.0, + color: Color::from_rgba8(0, 153, 255, 0.1), + ..Stroke::default() + }, + ); - let elapsed = self.now - self.start; - let rotation = (2.0 * PI / 60.0) * elapsed.as_secs() as f32 - + (2.0 * PI / 60_000.0) * elapsed.subsec_millis() as f32; + let elapsed = self.now - self.start; + let rotation = (2.0 * PI / 60.0) * elapsed.as_secs() as f32 + + (2.0 * PI / 60_000.0) * elapsed.subsec_millis() as f32; - frame.with_save(|frame| { - frame.translate(Vector::new(center.x, center.y)); - frame.rotate(rotation); - frame.translate(Vector::new(Self::ORBIT_RADIUS, 0.0)); + frame.with_save(|frame| { + frame.translate(Vector::new(center.x, center.y)); + frame.rotate(rotation); + frame.translate(Vector::new(Self::ORBIT_RADIUS, 0.0)); + + let earth = Path::circle(Point::ORIGIN, Self::EARTH_RADIUS); + let shadow = Path::rectangle( + Point::new(0.0, -Self::EARTH_RADIUS), + Size::new( + Self::EARTH_RADIUS * 4.0, + Self::EARTH_RADIUS * 2.0, + ), + ); - let earth = Path::circle(Point::ORIGIN, Self::EARTH_RADIUS); - let shadow = Path::rectangle( - Point::new(0.0, -Self::EARTH_RADIUS), - Size::new(Self::EARTH_RADIUS * 4.0, Self::EARTH_RADIUS * 2.0), - ); + frame.fill(&earth, Color::from_rgb8(0x6B, 0x93, 0xD6)); - frame.fill(&earth, Color::from_rgb8(0x6B, 0x93, 0xD6)); + frame.with_save(|frame| { + frame.rotate(rotation * 10.0); + frame.translate(Vector::new(0.0, Self::MOON_DISTANCE)); - frame.with_save(|frame| { - frame.rotate(rotation * 10.0); - frame.translate(Vector::new(0.0, Self::MOON_DISTANCE)); + let moon = Path::circle(Point::ORIGIN, Self::MOON_RADIUS); + frame.fill(&moon, Color::WHITE); + }); - let moon = Path::circle(Point::ORIGIN, Self::MOON_RADIUS); - frame.fill(&moon, Color::WHITE); + frame.fill( + &shadow, + Color { + a: 0.7, + ..Color::BLACK + }, + ); }); - - frame.fill( - &shadow, - Color { - a: 0.7, - ..Color::BLACK - }, - ); }); + + vec![background, system] } } -- cgit