liftof_tui/tabs/
tab_settings.rs

1use ratatui::prelude::*;
2
3use ratatui::widgets::{
4//    Axis,
5    Block,
6    BorderType,
7//    GraphType,
8//    Dataset,
9//    Chart,
10    Borders,
11//    Cell,
12    List,
13    ListState,
14    ListItem,
15    //ListDirection,
16//    ListState,
17    Paragraph,
18//    Row,
19//    Table,
20//    Tabs,
21};
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  // Color::Blue was nice for background
124  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