diff options
Diffstat (limited to 'examples/clock')
| -rw-r--r-- | examples/clock/Cargo.toml | 7 | ||||
| -rw-r--r-- | examples/clock/src/main.rs | 176 | 
2 files changed, 59 insertions, 124 deletions
diff --git a/examples/clock/Cargo.toml b/examples/clock/Cargo.toml index 308cbfbb..c6e32379 100644 --- a/examples/clock/Cargo.toml +++ b/examples/clock/Cargo.toml @@ -5,11 +5,6 @@ authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]  edition = "2018"  publish = false -[features] -canvas = [] -  [dependencies] -iced = { path = "../..", features = ["canvas", "async-std", "debug"] } -iced_native = { path = "../../native" } +iced = { path = "../..", features = ["canvas", "tokio", "debug"] }  chrono = "0.4" -async-std = { version = "1.0", features = ["unstable"] } diff --git a/examples/clock/src/main.rs b/examples/clock/src/main.rs index d8266f06..b317ac00 100644 --- a/examples/clock/src/main.rs +++ b/examples/clock/src/main.rs @@ -1,9 +1,10 @@  use iced::{ -    canvas, executor, Application, Canvas, Color, Command, Container, Element, -    Length, Point, Settings, Subscription, Vector, +    canvas::{self, Cache, Canvas, Cursor, Geometry, LineCap, Path, Stroke}, +    executor, time, Application, Color, Command, Container, Element, Length, +    Point, Rectangle, Settings, Subscription, Vector,  }; -pub fn main() { +pub fn main() -> iced::Result {      Clock::run(Settings {          antialiasing: true,          ..Settings::default() @@ -11,8 +12,8 @@ pub fn main() {  }  struct Clock { -    now: LocalTime, -    clock: canvas::layer::Cache<LocalTime>, +    now: chrono::DateTime<chrono::Local>, +    clock: Cache,  }  #[derive(Debug, Clone, Copy)] @@ -23,12 +24,13 @@ enum Message {  impl Application for Clock {      type Executor = executor::Default;      type Message = Message; +    type Flags = (); -    fn new() -> (Self, Command<Message>) { +    fn new(_flags: ()) -> (Self, Command<Message>) {          (              Clock { -                now: chrono::Local::now().into(), -                clock: canvas::layer::Cache::new(), +                now: chrono::Local::now(), +                clock: Default::default(),              },              Command::none(),          ) @@ -41,7 +43,7 @@ impl Application for Clock {      fn update(&mut self, message: Message) -> Command<Message> {          match message {              Message::Tick(local_time) => { -                let now = local_time.into(); +                let now = local_time;                  if now != self.now {                      self.now = now; @@ -54,140 +56,78 @@ impl Application for Clock {      }      fn subscription(&self) -> Subscription<Message> { -        time::every(std::time::Duration::from_millis(500)).map(Message::Tick) +        time::every(std::time::Duration::from_millis(500)) +            .map(|_| Message::Tick(chrono::Local::now()))      }      fn view(&mut self) -> Element<Message> { -        let canvas = Canvas::new() +        let canvas = Canvas::new(self)              .width(Length::Units(400)) -            .height(Length::Units(400)) -            .push(self.clock.with(&self.now)); +            .height(Length::Units(400));          Container::new(canvas)              .width(Length::Fill)              .height(Length::Fill) +            .padding(20)              .center_x()              .center_y()              .into()      }  } -#[derive(Debug, PartialEq, Eq)] -struct LocalTime { -    hour: u32, -    minute: u32, -    second: u32, -} - -impl From<chrono::DateTime<chrono::Local>> for LocalTime { -    fn from(date_time: chrono::DateTime<chrono::Local>) -> LocalTime { +impl canvas::Program<Message> for Clock { +    fn draw(&self, bounds: Rectangle, _cursor: Cursor) -> Vec<Geometry> {          use chrono::Timelike; -        LocalTime { -            hour: date_time.hour(), -            minute: date_time.minute(), -            second: date_time.second(), -        } -    } -} +        let clock = self.clock.draw(bounds.size(), |frame| { +            let center = frame.center(); +            let radius = frame.width().min(frame.height()) / 2.0; -impl canvas::Drawable for LocalTime { -    fn draw(&self, frame: &mut canvas::Frame) { -        let center = frame.center(); -        let radius = frame.width().min(frame.height()) / 2.0; -        let offset = Vector::new(center.x, center.y); - -        let clock = canvas::Path::new(|path| path.circle(center, radius)); - -        frame.fill( -            &clock, -            canvas::Fill::Color(Color::from_rgb8(0x12, 0x93, 0xD8)), -        ); - -        fn draw_hand( -            n: u32, -            total: u32, -            length: f32, -            offset: Vector, -            path: &mut canvas::path::Builder, -        ) { -            let turns = n as f32 / total as f32; -            let t = 2.0 * std::f32::consts::PI * (turns - 0.25); - -            let x = length * t.cos(); -            let y = length * t.sin(); - -            path.line_to(Point::new(x, y) + offset); -        } +            let background = Path::circle(center, radius); +            frame.fill(&background, Color::from_rgb8(0x12, 0x93, 0xD8)); -        let hour_and_minute_hands = canvas::Path::new(|path| { -            path.move_to(center); -            draw_hand(self.hour, 12, 0.5 * radius, offset, path); +            let short_hand = +                Path::line(Point::ORIGIN, Point::new(0.0, -0.5 * radius)); -            path.move_to(center); -            draw_hand(self.minute, 60, 0.8 * radius, offset, path) -        }); +            let long_hand = +                Path::line(Point::ORIGIN, Point::new(0.0, -0.8 * radius)); -        frame.stroke( -            &hour_and_minute_hands, -            canvas::Stroke { -                width: 6.0, +            let thin_stroke = Stroke { +                width: radius / 100.0,                  color: Color::WHITE, -                line_cap: canvas::LineCap::Round, -                ..canvas::Stroke::default() -            }, -        ); - -        let second_hand = canvas::Path::new(|path| { -            path.move_to(center); -            draw_hand(self.second, 60, 0.8 * radius, offset, path) +                line_cap: LineCap::Round, +                ..Stroke::default() +            }; + +            let wide_stroke = Stroke { +                width: thin_stroke.width * 3.0, +                ..thin_stroke +            }; + +            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.now.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.stroke( -            &second_hand, -            canvas::Stroke { -                width: 3.0, -                color: Color::WHITE, -                line_cap: canvas::LineCap::Round, -                ..canvas::Stroke::default() -            }, -        ); +        vec![clock]      }  } -mod time { -    use iced::futures; +fn hand_rotation(n: u32, total: u32) -> f32 { +    let turns = n as f32 / total as f32; -    pub fn every( -        duration: std::time::Duration, -    ) -> iced::Subscription<chrono::DateTime<chrono::Local>> { -        iced::Subscription::from_recipe(Every(duration)) -    } - -    struct Every(std::time::Duration); - -    impl<H, I> iced_native::subscription::Recipe<H, I> for Every -    where -        H: std::hash::Hasher, -    { -        type Output = chrono::DateTime<chrono::Local>; - -        fn hash(&self, state: &mut H) { -            use std::hash::Hash; - -            std::any::TypeId::of::<Self>().hash(state); -            self.0.hash(state); -        } - -        fn stream( -            self: Box<Self>, -            _input: futures::stream::BoxStream<'static, I>, -        ) -> futures::stream::BoxStream<'static, Self::Output> { -            use futures::stream::StreamExt; - -            async_std::stream::interval(self.0) -                .map(|_| chrono::Local::now()) -                .boxed() -        } -    } +    2.0 * std::f32::consts::PI * turns  }  | 
