liftof_tui/tabs/
tab_settings.rs1use ratatui::prelude::*;
2
3use ratatui::widgets::{
4Block,
6 BorderType,
7Borders,
11List,
13 ListState,
14 ListItem,
15 Paragraph,
18};
22
23use tui_popup::Popup;
24
25use crate::colors::{
26 ColorTheme,
27 ColorSet,
28 COLORSETOMILU,
29 COLORSETBW,
30 COLORSETDUNE,
31 COLORSETLD,
32 COLORSETNIUHI,
33 COLORSETMATRIX,
34 COLORSETSTARFIELD,
35 COLORSETGAPS,
36 COLORSETPRINCESSPEACH
37};
38
39
40#[derive(Debug, Clone)]
41pub struct SettingsTab<'a> {
42 pub theme : ColorTheme,
43 pub colortheme_popup : bool,
44 pub ctl_state : ListState,
45 pub ctl_items : Vec::<ListItem<'a>>,
46 pub ctl_active : bool,
47}
48
49impl SettingsTab<'_> {
50 pub fn new(theme : ColorTheme) -> SettingsTab<'static> {
51 let ct_list_items = vec![ListItem::new(Line::from("Black&White")),
52 ListItem::new(Line::from("StarField")),
53 ListItem::new(Line::from("Omiliu")),
54 ListItem::new(Line::from("GAPS")),
55 ListItem::new(Line::from("Niuhi")),
56 ListItem::new(Line::from("Dune")),
57 ListItem::new(Line::from("LowerDecks")),
58 ListItem::new(Line::from("Matrix")),
59 ListItem::new(Line::from("PrincessPeach")),
60 ];
61 SettingsTab {
62 theme,
63 colortheme_popup : false,
64 ctl_state : ListState::default(),
65 ctl_items : ct_list_items,
66 ctl_active : false,
67 }
68 }
69
70 pub fn next_ct(&mut self) {
71 let i = match self.ctl_state.selected() {
72 Some(i) => {
73 if i >= self.ctl_items.len() - 1 {
74 0
75 } else {
76 i + 1
77 }
78 }
79 None => 0,
80 };
81 self.ctl_state.select(Some(i));
82 }
83
84 pub fn previous_ct(&mut self) {
85 let i = match self.ctl_state.selected() {
86 Some(i) => {
87 if i == 0 {
88 self.ctl_items.len() - 1
89 } else {
90 i - 1
91 }
92 }
93 None => 0,
94 };
95 self.ctl_state.select(Some(i));
96 }
97
98 pub fn unselect_ctl(&mut self) {
99 self.ctl_state.select(None);
100 }
101
102 pub fn get_colorset(&self) -> Option<ColorSet> {
103 let cs = match self.ctl_state.selected() {
104 Some(i) => {
105 match i {
106 0 => Some(COLORSETBW),
107 1 => Some(COLORSETSTARFIELD),
108 2 => Some(COLORSETOMILU),
109 3 => Some(COLORSETGAPS),
110 4 => Some(COLORSETNIUHI),
111 5 => Some(COLORSETDUNE),
112 6 => Some(COLORSETLD),
113 7 => Some(COLORSETMATRIX),
114 8 => Some(COLORSETPRINCESSPEACH),
115 _ => None,
116 }
117 }
118 None => None,
119 };
120 cs
121 }
122
123 pub fn render(&mut self, main_window : &Rect, frame : &mut Frame) {
125 let main_rows = Layout::default()
126 .direction(Direction::Horizontal)
127 .constraints(
128 [Constraint::Percentage(50), Constraint::Percentage(50)].as_ref(),
129 )
130 .split(*main_window);
131
132 let cols_row0 = Layout::default()
133 .direction(Direction::Vertical)
134 .constraints(
135 [Constraint::Percentage(50),
136 Constraint::Percentage(50),
137 ].as_ref()
138 )
139 .split(main_rows[0]);
140
141 let cols_row1 = Layout::default()
142 .direction(Direction::Vertical)
143 .constraints(
144 [Constraint::Percentage(50),
145 Constraint::Percentage(50),
146 ].as_ref()
147 )
148 .split(main_rows[1]);
149
150 let rows_cols_row1 = Layout::default()
151 .direction(Direction::Horizontal)
152 .constraints(
153 [Constraint::Percentage(50),
154 Constraint::Percentage(50)
155 ].as_ref()
156 )
157 .split(cols_row1[1]);
158
159 let par_title_string = String::from("Apply Color Theme");
160 let (first, rest) = par_title_string.split_at(1);
161 let par_title = Line::from(vec![
162 Span::styled(
163 first,
164 Style::default()
165 .fg(self.theme.hc)
166 .add_modifier(Modifier::UNDERLINED)
167 .add_modifier(Modifier::BOLD),
168 ),
169 Span::styled(rest, self.theme.style()),
170 ]);
171
172 let rbs = Block::default()
173 .borders(Borders::ALL)
174 .style(self.theme.style())
175 .title(par_title)
176 .border_type(BorderType::Plain);
177
178 let color_theme_list = List::new(self.ctl_items.clone()).block(rbs)
179 .highlight_style(self.theme.highlight().add_modifier(Modifier::BOLD))
180 .highlight_symbol(">>")
181 .repeat_highlight_symbol(true);
182 match self.ctl_state.selected() {
183 None => self.ctl_state.select(Some(1)),
184 Some(_) => (),
185 }
186 let content = "Settings (WIP)";
187 let main_view = Paragraph::new(content)
188 .style(self.theme.style())
189 .alignment(Alignment::Center)
190 .block(
191 Block::default()
192 .borders(Borders::NONE)
193 );
194
195 let par_refresh_string = String::from("Refresh rate");
196 let (first, rest) = par_refresh_string.split_at(1);
197 let par_refresh_title = Line::from(vec![
198 Span::styled(
199 first,
200 Style::default()
201 .fg(self.theme.hc)
202 .add_modifier(Modifier::UNDERLINED)
203 .add_modifier(Modifier::BOLD),
204 ),
205 Span::styled(rest, self.theme.style()),
206 ]);
207
208 let refresh_view = Paragraph::new(content)
209 .style(self.theme.style())
210 .alignment(Alignment::Center)
211 .block(
212 Block::default()
213 .title(par_refresh_title)
214 .borders(Borders::ALL)
215 .border_type(BorderType::Rounded),
216 );
217
218 let par_wf_fixed_y_title = String::from("Fix Waveform y-scale");
219 let wf_fixed_y_view = Paragraph::new(content)
220 .style(self.theme.style())
221 .alignment(Alignment::Center)
222 .block(
223 Block::default()
224 .title(par_wf_fixed_y_title)
225 .borders(Borders::ALL)
226 .border_type(BorderType::Rounded),
227 );
228
229 frame.render_widget(main_view, cols_row0[0]);
230 frame.render_stateful_widget(color_theme_list, cols_row1[0], &mut self.ctl_state );
231 frame.render_widget(refresh_view, rows_cols_row1[0]);
232 frame.render_widget(wf_fixed_y_view, rows_cols_row1[1]);
233 if self.colortheme_popup {
234 let popup = Popup::new("Any key to continue!")
235 .title("New color theme selected!")
236 .style(self.theme.style());
237 frame.render_widget(&popup, frame.area());
238 }
239 }
240}
241
242