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
#![allow(deprecated)]

use gtk::prelude::*;
use relm4::{
    gtk, Component, ComponentController, ComponentParts, ComponentSender, Controller, RelmApp,
    SimpleComponent,
};
use relm4_components::simple_combo_box::SimpleComboBox;

type ComboContent = &'static str;

const GREETINGS: &[&str] = &["Hello!", "Hallo!", "Salut!", "Siema!", "привет!", "你好!"];

#[derive(Debug)]
enum AppMsg {
    ComboChanged(usize),
}

struct App {
    combo: Controller<SimpleComboBox<ComboContent>>,
    idx: usize,
}

impl App {
    fn lang(&self) -> &str {
        // you can also use self.combo.model().variants[self.idx]
        self.combo
            .model()
            .get_active_elem()
            .expect("combo box should have an active element")
    }

    fn greeting(&self) -> &str {
        GREETINGS[self.idx]
    }

    fn label(&self) -> String {
        format!("Greeting in {}: {}", self.lang(), self.greeting())
    }
}

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

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

            gtk::Box {
                set_orientation: gtk::Orientation::Vertical,

                #[local_ref]
                combo -> gtk::ComboBoxText {},

                gtk::Label {
                    #[watch]
                    set_label: &model.label(),
                },
            }
        }
    }

    fn update(&mut self, msg: Self::Input, _: ComponentSender<Self>) {
        match msg {
            AppMsg::ComboChanged(idx) => self.idx = idx,
        }
    }

    fn init(
        _: Self::Init,
        root: Self::Root,
        sender: ComponentSender<Self>,
    ) -> ComponentParts<Self> {
        let default_idx = 0;

        let langs = vec![
            "English", "German", "French", "Polish", "Russian", "Chinese",
        ];

        let combo = SimpleComboBox::builder()
            .launch(SimpleComboBox {
                variants: langs,
                active_index: Some(default_idx),
            })
            .forward(sender.input_sender(), AppMsg::ComboChanged);

        let model = App {
            combo,
            idx: default_idx,
        };

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

        ComponentParts { model, widgets }
    }
}

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