1use 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 }
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 }
170 }
171}