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
use gtk::prelude::*;
use relm4::{
    gtk, Component, ComponentController, ComponentParts, ComponentSender, Controller, RelmApp,
    SimpleComponent,
};
use relm4_components::web_image::{WebImage, WebImageMsg};

const IMAGES: &[&str] = &[
    "https://raw.githubusercontent.com/Relm4/Relm4/main/assets/Relm_logo_with_text.png",
    "https://raw.githubusercontent.com/Relm4/Relm4/main/assets/Relm_logo.png",
    "https://raw.githubusercontent.com/gtk-rs/gtk-rs.github.io/master/logo/gtk-rs.ico",
    "https://avatars.githubusercontent.com/u/5430905",
];

#[derive(Debug)]
enum AppMsg {
    Next,
    Unload,
}

struct App {
    image: Controller<WebImage>,
    idx: usize,
}

#[relm4::component]
impl SimpleComponent for App {
    type Init = ();
    type Input = AppMsg;
    type Output = ();

    view! {
        gtk::ApplicationWindow {
            set_default_size: (300, 300),

            #[wrap(Some)]
            set_titlebar = &gtk::HeaderBar {
                pack_start = &gtk::Button {
                    set_label: "Next image",
                    connect_clicked => AppMsg::Next,
                },
                pack_start = &gtk::Button {
                    set_label: "Unload image",
                    connect_clicked => AppMsg::Unload,
                }
            },

            gtk::Box {
                #[local_ref]
                image -> gtk::Box {}
            }
        }
    }

    fn update(&mut self, msg: Self::Input, _: ComponentSender<Self>) {
        match msg {
            AppMsg::Next => {
                self.idx = (self.idx + 1) % IMAGES.len();
                self.image
                    .emit(WebImageMsg::LoadImage(IMAGES[self.idx].to_owned()));
            }
            AppMsg::Unload => self.image.emit(WebImageMsg::Unload),
        }
    }

    fn init(
        _: Self::Init,
        root: &Self::Root,
        sender: ComponentSender<Self>,
    ) -> ComponentParts<Self> {
        let image = WebImage::builder().launch(IMAGES[0].to_owned()).detach();
        let model = App { image, idx: 0 };

        let image = model.image.widget();
        let widgets = view_output!();

        ComponentParts { model, widgets }
    }
}

fn main() {
    let app = RelmApp::new("relm4.example.open_button");
    app.run::<App>(());
}