Skip to main content

ferrix_app/
settings.rs

1/* settings.rs
2 *
3 * Copyright 2025-2026 Michail Krasnov <mskrasnov07@ya.ru>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17 *
18 * SPDX-License-Identifier: GPL-3.0-or-later
19 */
20
21use anyhow::Result;
22use iced::{Theme, color};
23use serde::{Deserialize, Serialize};
24use std::{collections::HashMap, fmt::Display, fs, path::Path};
25
26use crate::{fl, styles::CPU_CHARTS_COLORS};
27
28#[derive(Debug, Clone, Deserialize, Serialize)]
29pub struct FXSettings {
30    pub update_period: u8,
31    pub charts_update_period_nsecs: u8,
32    pub style: Style,
33    pub chart_line_thickness: ChartLineThickness,
34    pub chart_colors: ChartColors,
35}
36
37impl FXSettings {
38    pub fn read<P: AsRef<Path>>(pth: P) -> Result<Self> {
39        let contents = fs::read_to_string(pth)?;
40        let data = toml::from_str(&contents)?;
41        Ok(data)
42    }
43
44    pub fn write<'a, P: AsRef<Path>>(&'a self, pth: P) -> Result<()> {
45        let contents = toml::to_string(&self)?;
46        fs::write(pth, contents)?;
47        Ok(())
48    }
49}
50
51impl Default for FXSettings {
52    fn default() -> Self {
53        Self {
54            update_period: 1,
55            charts_update_period_nsecs: 5,
56            style: Style::default(),
57            chart_line_thickness: ChartLineThickness::default(),
58            chart_colors: ChartColors::default(),
59        }
60    }
61}
62
63#[derive(Debug, Clone, Copy, Deserialize, Serialize, Default, PartialEq)]
64pub enum Style {
65    Light,
66    #[default]
67    Dark,
68}
69
70impl Style {
71    pub const ALL: &[Self] = &[Self::Light, Self::Dark];
72
73    pub fn to_theme(&self) -> Theme {
74        match self {
75            Self::Light => {
76                let mut palette = Theme::GruvboxLight.palette();
77                palette.success = color!(0x98971a);
78                palette.danger = color!(0xaf3a03);
79                palette.warning = color!(0xb57614);
80                palette.primary = color!(0xd79921);
81                palette.background = color!(0xebdbb2);
82
83                Theme::custom("Ferrix Light Theme", palette)
84            }
85            Self::Dark => {
86                let mut palette = Theme::GruvboxDark.palette();
87                palette.success = color!(0x98971a);
88                palette.danger = color!(0xfb4934);
89                palette.warning = color!(0xfabd2f);
90                palette.primary = color!(0xfabd2f);
91
92                Theme::custom("Ferrix Dark Theme", palette)
93            }
94        }
95    }
96}
97
98impl Display for Style {
99    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
100        write!(
101            f,
102            "{}",
103            match self {
104                Self::Light => fl!("style-light"),
105                Self::Dark => fl!("style-dark"),
106            }
107        )
108    }
109}
110
111#[derive(Debug, Clone, Copy, Eq, PartialEq, Default, Deserialize, Serialize)]
112pub enum ChartLineThickness {
113    #[default]
114    OnePixel,
115    TwoPixel,
116}
117
118impl ChartLineThickness {
119    pub const ALL: &[Self] = &[Self::OnePixel, Self::TwoPixel];
120
121    pub fn to_u32(&self) -> u32 {
122        match self {
123            Self::OnePixel => 1,
124            Self::TwoPixel => 2,
125        }
126    }
127}
128
129impl Display for ChartLineThickness {
130    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
131        write!(
132            f,
133            "{}",
134            match self {
135                Self::OnePixel => fl!("lthick-one"),
136                Self::TwoPixel => fl!("lthick-two"),
137            }
138        )
139    }
140}
141
142#[derive(Debug, Clone, Serialize, Deserialize)]
143pub struct ChartColors {
144    pub colors: HashMap<String, (u8, u8, u8)>,
145    // pub default_colors: Vec<(u8, u8, u8)>,
146}
147
148impl Default for ChartColors {
149    fn default() -> Self {
150        Self {
151            colors: {
152                let mut colors = HashMap::new();
153                let mut i = 0;
154                for color in CPU_CHARTS_COLORS {
155                    let c = color.into_rgba8();
156                    let c = (c[0], c[1], c[2]);
157                    colors.insert(format!("CPU #{i}"), c);
158                    i += 1;
159                }
160                colors
161            },
162            // default_colors: CPU_CHARTS_COLORS
163            //     .iter()
164            //     .map(|c| {
165            //         let c = c.into_rgba8();
166            //         (c[0], c[1], c[2])
167            //     })
168            //     .collect(),
169        }
170    }
171}