summaryrefslogtreecommitdiffstats
path: root/examples/download_progress/src/main.rs
blob: 936144d5b5af8f2649805761a4a0454ff1d557b4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
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<Message>) {
        (Downloader::default(), Command::none())
    }

    fn title(&self) -> String {
        String::from("Download Progress - Iced")
    }

    fn update(&mut self, message: Message) -> Command<Message> {
        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<Message> {
        if self.enabled {
            downloader::file("https://speed.hetzner.de/100MB.bin")
                .map(Message::DownloadUpdate)
        } else {
            Subscription::none()
        }
    }

    fn view(&mut self) -> Element<Message> {
        // Construct widgets

        let toggle_text = match self.enabled {
            true => "Downloading...",
            false => "Start the download!",
        };

        let toggle: Element<Interaction> =
            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()
    }
}