From fff333f89ba99f32171641f0e8d78c9cdfe291b4 Mon Sep 17 00:00:00 2001 From: Songtronix Date: Mon, 23 Mar 2020 15:54:23 +0100 Subject: Add example for download with progress tracking --- examples/download_progress/src/main.rs | 116 +++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 examples/download_progress/src/main.rs (limited to 'examples/download_progress/src/main.rs') diff --git a/examples/download_progress/src/main.rs b/examples/download_progress/src/main.rs new file mode 100644 index 00000000..936144d5 --- /dev/null +++ b/examples/download_progress/src/main.rs @@ -0,0 +1,116 @@ +use iced::{ + button, executor, Align, Application, Button, Column, Command, Container, + Element, Length, ProgressBar, Settings, Subscription, Text, +}; + +mod downloader; + +pub fn main() { + Downloader::run(Settings::default()) +} + +#[derive(Debug, Default)] +struct Downloader { + // Whether to start the download or not. + enabled: bool, + // The current percentage of the download + current_progress: u64, + + btn_state: button::State, +} + +#[derive(Debug)] +pub enum Message { + DownloadUpdate(downloader::DownloadMessage), + Interaction(Interaction), +} + +// For explanation of why we use an Interaction enum see here: +// https://github.com/hecrj/iced/pull/155#issuecomment-573523405 +#[derive(Debug, Clone)] +pub enum Interaction { + // User pressed the button to start the download + StartDownload, +} + +impl Application for Downloader { + type Executor = executor::Default; + type Message = Message; + + fn new() -> (Downloader, Command) { + (Downloader::default(), Command::none()) + } + + fn title(&self) -> String { + String::from("Download Progress - Iced") + } + + fn update(&mut self, message: Message) -> Command { + match message { + Message::Interaction(action) => match action { + Interaction::StartDownload => { + self.enabled = true; + } + }, + Message::DownloadUpdate(update) => match update { + downloader::DownloadMessage::Downloading(percentage) => { + self.current_progress = percentage; + } + downloader::DownloadMessage::Done => { + self.current_progress = 100; + self.enabled = false; + } + _ => {} + }, + }; + + Command::none() + } + + fn subscription(&self) -> Subscription { + if self.enabled { + downloader::file("https://speed.hetzner.de/100MB.bin") + .map(Message::DownloadUpdate) + } else { + Subscription::none() + } + } + + fn view(&mut self) -> Element { + // Construct widgets + + let toggle_text = match self.enabled { + true => "Downloading...", + false => "Start the download!", + }; + + let toggle: Element = + Button::new(&mut self.btn_state, Text::new(toggle_text)) + .on_press(Interaction::StartDownload) + .into(); + + let progress_bar = + ProgressBar::new(0.0..=100.0, self.current_progress as f32); + + let progress_text = &match self.enabled { + true => format!("Downloading {}%", self.current_progress), + false => "Ready to rock!".into(), + }; + + // Construct layout + let content = Column::new() + .align_items(Align::Center) + .spacing(20) + .padding(20) + .push(Text::new(progress_text)) + .push(progress_bar) + .push(toggle.map(Message::Interaction)); + + Container::new(content) + .width(Length::Fill) + .height(Length::Fill) + .center_x() + .center_y() + .into() + } +} -- cgit From 30c7db3f25d12461f2dec493f92c3f3282bd264d Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 23 Mar 2020 20:34:16 +0100 Subject: Improve `download_progress` example - Use `reqwest` with `Response::chunk` to notify progress. - Turn example state into an enum --- examples/download_progress/src/main.rs | 129 ++++++++++++++++++--------------- 1 file changed, 69 insertions(+), 60 deletions(-) (limited to 'examples/download_progress/src/main.rs') diff --git a/examples/download_progress/src/main.rs b/examples/download_progress/src/main.rs index 936144d5..75e3bee0 100644 --- a/examples/download_progress/src/main.rs +++ b/examples/download_progress/src/main.rs @@ -6,60 +6,61 @@ use iced::{ mod downloader; pub fn main() { - Downloader::run(Settings::default()) -} - -#[derive(Debug, Default)] -struct Downloader { - // Whether to start the download or not. - enabled: bool, - // The current percentage of the download - current_progress: u64, - - btn_state: button::State, + Example::run(Settings::default()) } #[derive(Debug)] -pub enum Message { - DownloadUpdate(downloader::DownloadMessage), - Interaction(Interaction), +enum Example { + Idle { button: button::State }, + Downloading { progress: f32 }, + Finished { button: button::State }, } -// For explanation of why we use an Interaction enum see here: -// https://github.com/hecrj/iced/pull/155#issuecomment-573523405 #[derive(Debug, Clone)] -pub enum Interaction { - // User pressed the button to start the download - StartDownload, +pub enum Message { + DownloadProgressed(downloader::Progress), + Download, } -impl Application for Downloader { +impl Application for Example { type Executor = executor::Default; type Message = Message; - fn new() -> (Downloader, Command) { - (Downloader::default(), Command::none()) + fn new() -> (Example, Command) { + ( + Example::Idle { + button: button::State::new(), + }, + Command::none(), + ) } fn title(&self) -> String { - String::from("Download Progress - Iced") + String::from("Download progress - Iced") } fn update(&mut self, message: Message) -> Command { match message { - Message::Interaction(action) => match action { - Interaction::StartDownload => { - self.enabled = true; + Message::Download => match self { + Example::Idle { .. } | Example::Finished { .. } => { + *self = Example::Downloading { progress: 0.0 }; } + _ => {} }, - Message::DownloadUpdate(update) => match update { - downloader::DownloadMessage::Downloading(percentage) => { - self.current_progress = percentage; - } - downloader::DownloadMessage::Done => { - self.current_progress = 100; - self.enabled = false; - } + Message::DownloadProgressed(message) => match self { + Example::Downloading { progress } => match message { + downloader::Progress::Started => { + *progress = 0.0; + } + downloader::Progress::Advanced(percentage) => { + *progress = percentage; + } + downloader::Progress::Finished => { + *self = Example::Finished { + button: button::State::new(), + } + } + }, _ => {} }, }; @@ -68,43 +69,51 @@ impl Application for Downloader { } fn subscription(&self) -> Subscription { - if self.enabled { - downloader::file("https://speed.hetzner.de/100MB.bin") - .map(Message::DownloadUpdate) - } else { - Subscription::none() + match self { + Example::Downloading { .. } => { + downloader::file("https://speed.hetzner.de/100MB.bin") + .map(Message::DownloadProgressed) + } + _ => Subscription::none(), } } fn view(&mut self) -> Element { - // Construct widgets - - let toggle_text = match self.enabled { - true => "Downloading...", - false => "Start the download!", + let current_progress = match self { + Example::Idle { .. } => 0.0, + Example::Downloading { progress } => *progress, + Example::Finished { .. } => 100.0, }; - let toggle: Element = - Button::new(&mut self.btn_state, Text::new(toggle_text)) - .on_press(Interaction::StartDownload) - .into(); - - let progress_bar = - ProgressBar::new(0.0..=100.0, self.current_progress as f32); - - let progress_text = &match self.enabled { - true => format!("Downloading {}%", self.current_progress), - false => "Ready to rock!".into(), + let progress_bar = ProgressBar::new(0.0..=100.0, current_progress); + + let control: Element<_> = match self { + Example::Idle { button } => { + Button::new(button, Text::new("Start the download!")) + .on_press(Message::Download) + .into() + } + Example::Finished { button } => Column::new() + .spacing(10) + .align_items(Align::Center) + .push(Text::new("Download finished!")) + .push( + Button::new(button, Text::new("Start again")) + .on_press(Message::Download), + ) + .into(), + Example::Downloading { .. } => { + Text::new(format!("Downloading... {:.2}%", current_progress)) + .into() + } }; - // Construct layout let content = Column::new() + .spacing(10) + .padding(10) .align_items(Align::Center) - .spacing(20) - .padding(20) - .push(Text::new(progress_text)) .push(progress_bar) - .push(toggle.map(Message::Interaction)); + .push(control); Container::new(content) .width(Length::Fill) -- cgit From b92e1f957408e3254e5fe0da389808474de6c4a9 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 23 Mar 2020 20:37:30 +0100 Subject: Rename `downloader` module to `download` --- examples/download_progress/src/main.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'examples/download_progress/src/main.rs') diff --git a/examples/download_progress/src/main.rs b/examples/download_progress/src/main.rs index 75e3bee0..f3da3d7b 100644 --- a/examples/download_progress/src/main.rs +++ b/examples/download_progress/src/main.rs @@ -3,7 +3,7 @@ use iced::{ Element, Length, ProgressBar, Settings, Subscription, Text, }; -mod downloader; +mod download; pub fn main() { Example::run(Settings::default()) @@ -18,7 +18,7 @@ enum Example { #[derive(Debug, Clone)] pub enum Message { - DownloadProgressed(downloader::Progress), + DownloadProgressed(download::Progress), Download, } @@ -49,13 +49,13 @@ impl Application for Example { }, Message::DownloadProgressed(message) => match self { Example::Downloading { progress } => match message { - downloader::Progress::Started => { + download::Progress::Started => { *progress = 0.0; } - downloader::Progress::Advanced(percentage) => { + download::Progress::Advanced(percentage) => { *progress = percentage; } - downloader::Progress::Finished => { + download::Progress::Finished => { *self = Example::Finished { button: button::State::new(), } @@ -71,7 +71,7 @@ impl Application for Example { fn subscription(&self) -> Subscription { match self { Example::Downloading { .. } => { - downloader::file("https://speed.hetzner.de/100MB.bin") + download::file("https://speed.hetzner.de/100MB.bin") .map(Message::DownloadProgressed) } _ => Subscription::none(), -- cgit From 0d719bbdf336a022c073986e1e5a91cf632a270c Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 23 Mar 2020 20:43:55 +0100 Subject: Handle errors in `download_progress` example --- examples/download_progress/src/main.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'examples/download_progress/src/main.rs') diff --git a/examples/download_progress/src/main.rs b/examples/download_progress/src/main.rs index f3da3d7b..817a45ac 100644 --- a/examples/download_progress/src/main.rs +++ b/examples/download_progress/src/main.rs @@ -14,6 +14,7 @@ enum Example { Idle { button: button::State }, Downloading { progress: f32 }, Finished { button: button::State }, + Errored { button: button::State }, } #[derive(Debug, Clone)] @@ -60,6 +61,11 @@ impl Application for Example { button: button::State::new(), } } + download::Progress::Errored => { + *self = Example::Errored { + button: button::State::new(), + }; + } }, _ => {} }, @@ -83,6 +89,7 @@ impl Application for Example { Example::Idle { .. } => 0.0, Example::Downloading { progress } => *progress, Example::Finished { .. } => 100.0, + Example::Errored { .. } => 0.0, }; let progress_bar = ProgressBar::new(0.0..=100.0, current_progress); @@ -106,6 +113,15 @@ impl Application for Example { Text::new(format!("Downloading... {:.2}%", current_progress)) .into() } + Example::Errored { button } => Column::new() + .spacing(10) + .align_items(Align::Center) + .push(Text::new("Something went wrong :(")) + .push( + Button::new(button, Text::new("Try again")) + .on_press(Message::Download), + ) + .into(), }; let content = Column::new() -- cgit From 8e0dcd212d71ff334aa590ee3b565da7b8d24713 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 23 Mar 2020 21:08:03 +0100 Subject: Fix retry button on `download_progress` example --- examples/download_progress/src/main.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'examples/download_progress/src/main.rs') diff --git a/examples/download_progress/src/main.rs b/examples/download_progress/src/main.rs index 817a45ac..6c3094f7 100644 --- a/examples/download_progress/src/main.rs +++ b/examples/download_progress/src/main.rs @@ -19,8 +19,8 @@ enum Example { #[derive(Debug, Clone)] pub enum Message { - DownloadProgressed(download::Progress), Download, + DownloadProgressed(download::Progress), } impl Application for Example { @@ -43,7 +43,9 @@ impl Application for Example { fn update(&mut self, message: Message) -> Command { match message { Message::Download => match self { - Example::Idle { .. } | Example::Finished { .. } => { + Example::Idle { .. } + | Example::Finished { .. } + | Example::Errored { .. } => { *self = Example::Downloading { progress: 0.0 }; } _ => {} -- cgit