diff options
author | 2020-03-04 04:10:26 +0100 | |
---|---|---|
committer | 2020-03-04 04:10:26 +0100 | |
commit | 012b4adec7a87331b2d75f6bc5d2a0189dcd7ec5 (patch) | |
tree | ce668596d734fe9fe04e1fa40cb932cd3e1c1789 /examples/stopwatch | |
parent | 02091267bf38d4da5efab57e9b63504804b3a468 (diff) | |
download | iced-012b4adec7a87331b2d75f6bc5d2a0189dcd7ec5.tar.gz iced-012b4adec7a87331b2d75f6bc5d2a0189dcd7ec5.tar.bz2 iced-012b4adec7a87331b2d75f6bc5d2a0189dcd7ec5.zip |
Draft `Panes` widget and `panes` example
Diffstat (limited to 'examples/stopwatch')
-rw-r--r-- | examples/stopwatch/src/lib.rs | 204 | ||||
-rw-r--r-- | examples/stopwatch/src/main.rs | 204 |
2 files changed, 206 insertions, 202 deletions
diff --git a/examples/stopwatch/src/lib.rs b/examples/stopwatch/src/lib.rs new file mode 100644 index 00000000..0219470b --- /dev/null +++ b/examples/stopwatch/src/lib.rs @@ -0,0 +1,204 @@ +use iced::{ + button, Align, Application, Button, Column, Command, Container, Element, + HorizontalAlignment, Length, Row, Subscription, Text, +}; +use std::time::{Duration, Instant}; + +#[derive(Debug)] +pub struct Stopwatch { + duration: Duration, + state: State, + toggle: button::State, + reset: button::State, +} + +#[derive(Debug)] +enum State { + Idle, + Ticking { last_tick: Instant }, +} + +#[derive(Debug, Clone)] +pub enum Message { + Toggle, + Reset, + Tick(Instant), +} + +impl Application for Stopwatch { + type Executor = iced_futures::executor::AsyncStd; + type Message = Message; + + fn new() -> (Stopwatch, Command<Message>) { + ( + Stopwatch { + duration: Duration::default(), + state: State::Idle, + toggle: button::State::new(), + reset: button::State::new(), + }, + Command::none(), + ) + } + + fn title(&self) -> String { + String::from("Stopwatch - Iced") + } + + fn update(&mut self, message: Message) -> Command<Message> { + match message { + Message::Toggle => match self.state { + State::Idle => { + self.state = State::Ticking { + last_tick: Instant::now(), + }; + } + State::Ticking { .. } => { + self.state = State::Idle; + } + }, + Message::Tick(now) => match &mut self.state { + State::Ticking { last_tick } => { + self.duration += now - *last_tick; + *last_tick = now; + } + _ => {} + }, + Message::Reset => { + self.duration = Duration::default(); + } + } + + Command::none() + } + + fn subscription(&self) -> Subscription<Message> { + match self.state { + State::Idle => Subscription::none(), + State::Ticking { .. } => { + time::every(Duration::from_millis(10)).map(Message::Tick) + } + } + } + + fn view(&mut self) -> Element<Message> { + const MINUTE: u64 = 60; + const HOUR: u64 = 60 * MINUTE; + + let seconds = self.duration.as_secs(); + + let duration = Text::new(format!( + "{:0>2}:{:0>2}:{:0>2}.{:0>2}", + seconds / HOUR, + (seconds % HOUR) / MINUTE, + seconds % MINUTE, + self.duration.subsec_millis() / 10, + )) + .size(40); + + let button = |state, label, style| { + Button::new( + state, + Text::new(label) + .horizontal_alignment(HorizontalAlignment::Center), + ) + .min_width(80) + .padding(10) + .style(style) + }; + + let toggle_button = { + let (label, color) = match self.state { + State::Idle => ("Start", style::Button::Primary), + State::Ticking { .. } => ("Stop", style::Button::Destructive), + }; + + button(&mut self.toggle, label, color).on_press(Message::Toggle) + }; + + let reset_button = + button(&mut self.reset, "Reset", style::Button::Secondary) + .on_press(Message::Reset); + + let controls = Row::new() + .spacing(20) + .push(toggle_button) + .push(reset_button); + + let content = Column::new() + .align_items(Align::Center) + .spacing(20) + .push(duration) + .push(controls); + + Container::new(content) + .width(Length::Fill) + .height(Length::Fill) + .center_x() + .center_y() + .into() + } +} + +mod time { + use iced::futures; + + pub fn every( + duration: std::time::Duration, + ) -> iced::Subscription<std::time::Instant> { + 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 = std::time::Instant; + + 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(|_| std::time::Instant::now()) + .boxed() + } + } +} + +mod style { + use iced::{button, Background, Color, Vector}; + + pub enum Button { + Primary, + Secondary, + Destructive, + } + + impl button::StyleSheet for Button { + fn active(&self) -> button::Style { + button::Style { + background: Some(Background::Color(match self { + Button::Primary => Color::from_rgb(0.11, 0.42, 0.87), + Button::Secondary => Color::from_rgb(0.5, 0.5, 0.5), + Button::Destructive => Color::from_rgb(0.8, 0.2, 0.2), + })), + border_radius: 12, + shadow_offset: Vector::new(1.0, 1.0), + text_color: Color::WHITE, + ..button::Style::default() + } + } + } +} diff --git a/examples/stopwatch/src/main.rs b/examples/stopwatch/src/main.rs index d84c4817..adcdffe4 100644 --- a/examples/stopwatch/src/main.rs +++ b/examples/stopwatch/src/main.rs @@ -1,206 +1,6 @@ -use iced::{ - button, Align, Application, Button, Column, Command, Container, Element, - HorizontalAlignment, Length, Row, Settings, Subscription, Text, -}; -use std::time::{Duration, Instant}; +use iced::{Application, Settings}; +use stopwatch::Stopwatch; pub fn main() { Stopwatch::run(Settings::default()) } - -struct Stopwatch { - duration: Duration, - state: State, - toggle: button::State, - reset: button::State, -} - -enum State { - Idle, - Ticking { last_tick: Instant }, -} - -#[derive(Debug, Clone)] -enum Message { - Toggle, - Reset, - Tick(Instant), -} - -impl Application for Stopwatch { - type Executor = iced_futures::executor::AsyncStd; - type Message = Message; - - fn new() -> (Stopwatch, Command<Message>) { - ( - Stopwatch { - duration: Duration::default(), - state: State::Idle, - toggle: button::State::new(), - reset: button::State::new(), - }, - Command::none(), - ) - } - - fn title(&self) -> String { - String::from("Stopwatch - Iced") - } - - fn update(&mut self, message: Message) -> Command<Message> { - match message { - Message::Toggle => match self.state { - State::Idle => { - self.state = State::Ticking { - last_tick: Instant::now(), - }; - } - State::Ticking { .. } => { - self.state = State::Idle; - } - }, - Message::Tick(now) => match &mut self.state { - State::Ticking { last_tick } => { - self.duration += now - *last_tick; - *last_tick = now; - } - _ => {} - }, - Message::Reset => { - self.duration = Duration::default(); - } - } - - Command::none() - } - - fn subscription(&self) -> Subscription<Message> { - match self.state { - State::Idle => Subscription::none(), - State::Ticking { .. } => { - time::every(Duration::from_millis(10)).map(Message::Tick) - } - } - } - - fn view(&mut self) -> Element<Message> { - const MINUTE: u64 = 60; - const HOUR: u64 = 60 * MINUTE; - - let seconds = self.duration.as_secs(); - - let duration = Text::new(format!( - "{:0>2}:{:0>2}:{:0>2}.{:0>2}", - seconds / HOUR, - (seconds % HOUR) / MINUTE, - seconds % MINUTE, - self.duration.subsec_millis() / 10, - )) - .size(40); - - let button = |state, label, style| { - Button::new( - state, - Text::new(label) - .horizontal_alignment(HorizontalAlignment::Center), - ) - .min_width(80) - .padding(10) - .style(style) - }; - - let toggle_button = { - let (label, color) = match self.state { - State::Idle => ("Start", style::Button::Primary), - State::Ticking { .. } => ("Stop", style::Button::Destructive), - }; - - button(&mut self.toggle, label, color).on_press(Message::Toggle) - }; - - let reset_button = - button(&mut self.reset, "Reset", style::Button::Secondary) - .on_press(Message::Reset); - - let controls = Row::new() - .spacing(20) - .push(toggle_button) - .push(reset_button); - - let content = Column::new() - .align_items(Align::Center) - .spacing(20) - .push(duration) - .push(controls); - - Container::new(content) - .width(Length::Fill) - .height(Length::Fill) - .center_x() - .center_y() - .into() - } -} - -mod time { - use iced::futures; - - pub fn every( - duration: std::time::Duration, - ) -> iced::Subscription<std::time::Instant> { - 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 = std::time::Instant; - - 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(|_| std::time::Instant::now()) - .boxed() - } - } -} - -mod style { - use iced::{button, Background, Color, Vector}; - - pub enum Button { - Primary, - Secondary, - Destructive, - } - - impl button::StyleSheet for Button { - fn active(&self) -> button::Style { - button::Style { - background: Some(Background::Color(match self { - Button::Primary => Color::from_rgb(0.11, 0.42, 0.87), - Button::Secondary => Color::from_rgb(0.5, 0.5, 0.5), - Button::Destructive => Color::from_rgb(0.8, 0.2, 0.2), - })), - border_radius: 12, - shadow_offset: Vector::new(1.0, 1.0), - text_color: Color::WHITE, - ..button::Style::default() - } - } - } -} |