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
use gtk::prelude::{BoxExt, ButtonExt, GtkWindowExt, OrientableExt};
use relm4::{gtk, send, AppUpdate, Model, RelmApp, Sender, WidgetPlus, Widgets};
#[derive(Clone, Copy)]
enum Page {
Hello,
Intro,
Overview,
}
impl Page {
fn next(self) -> Self {
match self {
Page::Hello => Page::Intro,
Page::Intro => Page::Overview,
Page::Overview => Page::Overview,
}
}
fn previous(self) -> Self {
match self {
Page::Hello => Page::Hello,
Page::Intro => Page::Hello,
Page::Overview => Page::Intro,
}
}
}
struct AppModel {
page: Page,
}
enum AppMsg {
NextPage,
PreviousPage,
}
impl Model for AppModel {
type Msg = AppMsg;
type Widgets = AppWidgets;
type Components = ();
}
impl AppUpdate for AppModel {
fn update(&mut self, msg: AppMsg, _components: &(), _sender: Sender<AppMsg>) -> bool {
match msg {
AppMsg::NextPage => {
self.page = self.page.next();
}
AppMsg::PreviousPage => {
self.page = self.page.previous();
}
}
true
}
}
#[relm4::widget]
impl Widgets<AppModel, ()> for AppWidgets {
view! {
gtk::ApplicationWindow {
set_title: Some("Simple app"),
set_default_width: 300,
set_default_height: 100,
set_child = Some(>k::Box) {
set_orientation: gtk::Orientation::Vertical,
set_margin_all: 5,
set_spacing: 5,
append: stack = >k::Stack {
set_margin_all: 5,
set_transition_type: gtk::StackTransitionType::RotateLeft,
add_child: hello_label = >k::Label {
set_label: "Hello! Welcome to this application!",
},
add_child: intro_label = >k::Label {
set_label: "To get started click on \"Next page\".",
},
add_child: overview_label = >k::Label {
set_label: "* Insert overview here *",
},
},
append = >k::Button {
set_label: "Next page",
connect_clicked(sender) => move |_| {
send!(sender, AppMsg::NextPage);
},
},
append = >k::Button::with_label("Previous page") {
connect_clicked(sender) => move |_| {
send!(sender, AppMsg::PreviousPage);
},
},
},
}
}
fn pre_view() {
match model.page {
Page::Hello => self.stack.set_visible_child(&self.hello_label),
Page::Intro => self.stack.set_visible_child(&self.intro_label),
Page::Overview => self.stack.set_visible_child(&self.overview_label),
}
}
}
fn main() {
let model = AppModel { page: Page::Hello };
let app = RelmApp::new(model);
app.run();
}