1use iced::{
24 Alignment::{self, Center},
25 Element,
26 widget::{center, column, container, row, rule, svg::Handle, text},
27};
28
29use crate::{
30 Message,
31 ferrix::Ferrix,
32 fl,
33 icons::ERROR_ICON,
34 widgets::{header_text, link_button},
35};
36
37mod battery;
38mod cpu;
39mod cpu_freq;
40mod dashboard;
41mod distro;
42mod dmi;
43mod drm;
44mod env;
45mod export;
46mod groups;
47mod kernel;
48mod ram;
49mod settings;
50mod soft;
51mod storage;
52mod sysmon;
53mod system;
54mod systemd;
55mod users;
56mod vulnerabilities;
57
58pub use sysmon::*;
59
60#[derive(Debug, Clone, Copy, Default, Eq, PartialEq)]
61pub enum Page {
62 #[default]
66 Dashboard,
67 Processors,
68 CPUFrequency,
69 CPUVulnerabilities,
70 SystemMonitor,
71 Memory,
72 FileSystems,
73 DMI,
74 Battery,
75 Screen,
76
77 Distro,
81 SystemMisc,
82 Users,
83 Groups,
84 SystemManager,
85 Software,
86 Environment,
87 Sensors,
88
89 Kernel,
93 KModules,
94 Development,
95
96 Settings,
100 About,
101 Export,
102 Todo,
103}
104
105impl From<&str> for Page {
106 fn from(value: &str) -> Self {
107 match value {
108 "dash" | "dashboard" => Self::Dashboard,
109 "sysmon" | "monitor" | "system" | "system-monitor" => Self::SystemMonitor,
110 "proc" | "cpu" | "processors" => Self::Processors,
111 "cpu-frequency" | "cpufreq" => Self::CPUFrequency,
112 "cpu-vuln" | "vulnerabilities" => Self::CPUVulnerabilities,
113 "memory" | "mem" | "ram" => Self::Memory,
114 "storage" => Self::FileSystems,
115 "dmi" => Self::DMI,
116 "battery" | "bat" => Self::Battery,
117 "edid" | "screen" => Self::Screen,
118 "distro" => Self::Distro,
119 "users" => Self::Users,
120 "groups" => Self::Groups,
121 "misc" => Self::SystemMisc,
122 "systemd" => Self::SystemManager,
123 "software" | "soft" | "pkg" | "pkgs" => Self::Software,
124 "env" => Self::Environment,
125 "sensors" => Self::Sensors,
126 "kernel" | "linux" => Self::Kernel,
127 "kmods" | "mod" | "modules" => Self::KModules,
128 "dev" => Self::Development,
129 "settings" => Self::Settings,
130 "about" | "version" | "--version" | "-V" | "-v" => {
131 println!("FSM (Ferrix System Monitor) v{}", env!("CARGO_PKG_VERSION"));
132
133 eprintln!(" *** If you are from Russia, you can send me a donation:");
134 eprintln!(" 2202 2062 5233 5406\n Thank you!");
135
136 Self::About
137 }
138 "export" => Self::Export,
139 _ => {
140 eprintln!("ERROR: Unknown page name: \"{value}\"!\n");
141 eprintln!(" *** If you are from Russia, you can send me a donation:");
142 eprintln!(" 2202 2062 5233 5406\n Thank you!");
143
144 Self::default()
145 }
146 }
147 }
148}
149
150impl<'a> Page {
151 pub fn title(&'a self) -> iced::widget::Column<'a, Message> {
152 header_text(self.title_str())
153 }
154
155 pub fn title_str(&self) -> String {
156 match self {
157 Self::Dashboard => fl!("page-dashboard"),
158 Self::Processors => fl!("page-procs"),
159 Self::CPUFrequency => fl!("page-cpufreq"),
160 Self::CPUVulnerabilities => fl!("page-vuln"),
161 Self::SystemMonitor => fl!("page-sysmon"),
162 Self::Memory => fl!("page-memory"),
163 Self::FileSystems => fl!("page-fsystems"),
164 Self::DMI => fl!("page-dmi"),
165 Self::Battery => fl!("page-battery"),
166 Self::Screen => fl!("page-screen"),
167 Self::Distro => fl!("page-distro"),
168 Self::Users => fl!("page-users"),
169 Self::Groups => fl!("page-groups"),
170 Self::SystemManager => fl!("page-sysmgr"),
171 Self::Software => fl!("page-software"),
172 Self::Environment => fl!("page-env"),
173 Self::Sensors => fl!("page-sensors"),
174 Self::Kernel => fl!("page-kernel"),
175 Self::KModules => fl!("page-kmods"),
176 Self::Development => fl!("page-dev"),
177 Self::SystemMisc => fl!("page-sysmisc"),
178 Self::Settings => fl!("page-settings"),
179 Self::About => fl!("page-about"),
180 Self::Export => fl!("page-export"),
181 Self::Todo => fl!("page-todo"),
182 }
183 }
184
185 pub fn page(&'a self, state: &'a Ferrix) -> Element<'a, Message> {
186 let page = match self {
187 Self::Dashboard => dashboard::dashboard(&state.data).into(),
188 Self::SystemMonitor => sysmon::usage_charts_page(
189 &state.data,
190 &state.data.curr_proc_stat,
191 &state.data.prev_proc_stat,
192 )
193 .into(), Self::Processors => cpu::proc_page(&state.data.proc_data).into(),
196 Self::CPUFrequency => cpu_freq::cpu_freq_page(&state.data.cpu_freq).into(),
197 Self::CPUVulnerabilities => {
198 vulnerabilities::vulnerabilities_page(&state.data.cpu_vulnerabilities).into()
199 }
200 Self::Memory => ram::ram_page(&state.data.ram_data, &state.data.swap_data).into(),
201 Self::FileSystems => storage::storage_page(&state.data.storages).into(),
202 Self::DMI => dmi::dmi_page(&state.data.dmi_data).into(),
203 Self::Battery => battery::bat_page(&state.data.bat_data).into(),
204 Self::Screen => drm::drm_page(&state.data.drm_data).into(),
205 Self::Distro => distro::distro_page(&state.data.osrel_data).into(),
206 Self::Kernel => kernel::kernel_page(&state.data.kernel_data).into(),
207 Self::KModules => kernel::kmods_page(&state.data.kmods_data).into(),
208 Self::SystemMisc => system::system_page(&state.data.system).into(),
209 Self::Users => users::users_page(&state.data.users_list).into(),
210 Self::Groups => groups::groups_page(&state.data.groups_list).into(),
211 Self::SystemManager => systemd::services_page(&state.data.sysd_services_list).into(),
212 Self::Software => soft::soft_page(&state.data.installed_pkgs_list).into(),
213 Self::Environment => env::env_page(&state.data.system).into(),
214 Self::Settings => settings::settings_page(&state).into(),
215 Self::Export => export::export_page().into(),
216 Self::About => self.about_page().into(),
217 _ => self.todo_page(),
218 };
219
220 column![self.title(), page,].spacing(5).into()
221 }
222
223 fn todo_page(&self) -> Element<'a, Message> {
224 container(center(
225 text(fl!("page-todo-msg")).size(16).style(text::secondary),
226 ))
227 .into()
228 }
229
230 fn about_page(&'a self) -> container::Container<'a, Message> {
231 let img = iced::widget::svg("/usr/share/Ferrix/com.mskrasnov.Ferrix.svg")
232 .width(128)
233 .height(128);
234 let header = row![
235 img,
236 column![
237 text(fl!("about-hdr")).size(24),
238 text(format!(
239 "{}: {}, {}: {}",
240 fl!("about-ferrix"),
241 env!("CARGO_PKG_VERSION"),
242 fl!("about-flib"),
243 ferrix_lib::FX_LIB_VERSION,
244 ))
245 .size(14),
246 ]
247 .spacing(5),
248 ]
249 .align_y(Center)
250 .spacing(5);
251
252 let about_info = row![
253 column![
254 text(fl!("about-author-hdr")).style(text::secondary),
255 text(fl!("about-feedback-hdr")).style(text::secondary),
256 text(fl!("about-source-hdr")).style(text::secondary),
257 text("crates.io:").style(text::secondary),
258 text(fl!("about-blog")).style(text::secondary),
259 ]
260 .align_x(Alignment::End)
261 .spacing(3),
262 column![
263 row![
264 text(fl!("about-author")),
265 link_button("(GitHub)", "https://github.com/mskrasnov"),
266 ]
267 .spacing(5),
268 link_button("mskrasnov07 at ya dot ru", "mailto:mskrasnov07@ya.ru"),
269 link_button("GitHub", "https://github.com/mskrasnov/Ferrix"),
270 row![
271 link_button("ferrix-app", "https://crates.io/crates/ferrix-app"),
272 text(", "),
273 link_button("ferrix-lib", "https://crates.io/crates/ferrix-lib"),
274 ],
275 link_button("mskrasnov", "https://boosty.to/mskrasnov"),
276 ]
277 .spacing(3),
278 ]
279 .spacing(5);
280
281 let donate = column![
282 text(fl!("about-donate")),
283 link_button(fl!("about-donate-lbl"), "https://boosty.to/mskrasnov"),
284 ]
285 .spacing(5);
286
287 let contents = column![
288 column![header, rule::horizontal(1)].spacing(2),
289 about_info,
290 row![
291 text(fl!("about-support")).style(text::warning).size(16),
292 rule::horizontal(1)
293 ]
294 .align_y(Center)
295 .spacing(5),
296 donate,
297 ]
298 .spacing(5);
299
300 container(contents)
301 }
302}
303
304fn loading_page<'a>() -> container::Container<'a, Message> {
305 container(center(
306 text(fl!("ldr-page-tooltip"))
307 .style(text::secondary)
308 .size(14),
309 ))
310}
311
312fn error_page<'a>(etext: &'a str) -> container::Container<'a, Message> {
313 container(center(
314 column![
315 row![
316 iced::widget::svg(Handle::from_memory(ERROR_ICON))
317 .width(20)
318 .height(20),
319 text(fl!("err-page-tooltip")).size(20),
320 ]
321 .align_y(Center)
322 .spacing(5),
323 text(etext).style(text::secondary).size(14),
324 ]
325 .align_x(Center)
326 .spacing(5),
327 ))
328}