diff --git a/src/Tools/psxreadmap/src/lib.rs b/src/Tools/psxreadmap/src/lib.rs index 055517d5..c4f1737e 100644 --- a/src/Tools/psxreadmap/src/lib.rs +++ b/src/Tools/psxreadmap/src/lib.rs @@ -7,7 +7,7 @@ use ratatui::{ layout::{Alignment, Constraint, Direction, Layout, Rect}, style::{Color, Modifier, Style}, text::{Line, Span}, - widgets::{Block, Borders, BorderType, Gauge, Paragraph, Tabs} + widgets::{Block, Borders, BorderType, Gauge, List, ListItem, ListState, Paragraph, Tabs} }; pub type EventReceiver = std::sync::mpsc::Receiver>; @@ -51,21 +51,76 @@ impl MenuSelection { } } +pub struct ListSelection { + pub selection: Option +} + +impl ListSelection { + fn change_value(&mut self, max: usize, f: fn(usize)->usize) { + if let Some(cur_selection) = self.selection { + self.selection = Some(f(cur_selection)%max); + } + } + + pub fn increment(&mut self, max: usize) { + fn add_one(value: usize) -> usize { + value + 1 + } + self.change_value(max, add_one) + } + + pub fn decrement(&mut self, max: usize) { + fn sub_one(value: usize) -> usize { + value - 1 + } + self.change_value(max, sub_one) + } + + pub fn activate(&mut self) { + self.selection = Some(0); + } + + pub fn deactivate(&mut self) { + self.selection = None; + } + + pub fn is_active(&self) -> bool { + self.selection.is_some() + } +} + +impl Default for ListSelection { + fn default() -> Self { + Self{selection: None} + } +} + pub struct ConsoleUI { - rx: EventReceiver, - terminal: Terminal, - cur_size: Rect, - main_chunks: Vec, - stats_chunks: Vec, - menu_selection: MenuSelection, + rx: EventReceiver, + terminal: Terminal, + cur_size: Rect, + main_chunks: Vec, + stats_chunks: Vec, + menu_selection: MenuSelection, + content_selection: ListSelection, } impl ConsoleUI { pub fn new(rx: EventReceiver, terminal: Terminal) -> ConsoleUI { - ConsoleUI{rx, terminal, cur_size: Rect::default(), main_chunks: Vec::default(), stats_chunks: Vec::default(), menu_selection: MenuSelection::Stats} + ConsoleUI{rx, terminal, cur_size: Rect::default(), main_chunks: Vec::default(), stats_chunks: Vec::default(), menu_selection: MenuSelection::Stats, content_selection: ListSelection::default()} } - pub fn update(&mut self) -> Result { + pub fn update(&mut self, data: &ConsoleUIData) -> Result { + if data.list.len() > 0 { + if !self.content_selection.is_active() { + self.content_selection.activate(); + } + } + + else { + self.content_selection.deactivate(); + } + match self.rx.recv()? { Event::Input(event) => { match event.code { @@ -82,6 +137,26 @@ impl ConsoleUI { self.menu_selection = self.menu_selection.next(); Ok(UIState::Render) }, + KeyCode::Down => { + if matches!(self.menu_selection, MenuSelection::Stats) { + self.content_selection.increment(data.list.len()); + Ok(UIState::Render) + } + + else { + Ok(UIState::Alive) + } + }, + KeyCode::Up => { + if matches!(self.menu_selection, MenuSelection::Stats) { + self.content_selection.decrement(data.list.len()); + Ok(UIState::Render) + } + + else { + Ok(UIState::Alive) + } + }, KeyCode::Enter => { if matches!(self.menu_selection, MenuSelection::Quit) { Ok(UIState::Terminated) @@ -106,7 +181,7 @@ impl ConsoleUI { } } - pub fn render(&mut self, data: &ConsoleUIData) -> Result<(), Error> { + pub fn render(&mut self, data: &mut ConsoleUIData) -> Result<(), Error> { self.terminal.draw(|frame| { Self::update_sub_frames(&mut self.main_chunks, &mut self.stats_chunks, &mut self.cur_size, frame.size()); @@ -114,7 +189,7 @@ impl ConsoleUI { frame.render_widget(Self::create_menu(&self.menu_selection), self.main_chunks[1]); match self.menu_selection { MenuSelection::Stats => { - Self::render_stats(frame, &self.stats_chunks, data); + Self::render_stats(frame, &self.stats_chunks, &self.content_selection, data); }, MenuSelection::Quit => { frame.render_widget(Self::create_exit_message(), self.main_chunks[2]); @@ -180,18 +255,27 @@ impl ConsoleUI { ) } - fn render_stats(frame: &mut ConsoleFrame, frames: &Vec, data: &ConsoleUIData) { - let content_text = Paragraph::new("") - .style(Style::default().fg(Color::White)) - .alignment(Alignment::Center) - .block(Block::default() - .borders(Borders::ALL) - .style(Style::default().fg(Color::White)) - .border_type(BorderType::Plain) - ); - let mem_gauge = Self::create_overall_mem_gauge(data.highest_adr); + fn render_stats(frame: &mut ConsoleFrame, frames: &Vec, content_selection: &ListSelection, data: &mut ConsoleUIData) { + let content_list = List::new({ + let mut vec = Vec::new(); - frame.render_widget(content_text, frames[0]); + for item in &data.list { + vec.push(ListItem::new(item.as_str())) + } + vec + }).style(Style::default().fg(Color::White)) + .block(Block::default() + .borders(Borders::ALL) + .style(Style::default().fg(Color::White)) + .border_type(BorderType::Plain) + ) + .highlight_style(Style::default().bg(Color::Yellow)); + let mem_gauge = Self::create_overall_mem_gauge(data.highest_adr); + let mut list_state = ListState::default(); + + list_state.select(content_selection.selection); + + frame.render_stateful_widget(content_list, frames[0], &mut list_state); frame.render_widget(mem_gauge, frames[1]); } @@ -221,7 +305,8 @@ impl ConsoleUI { #[derive(Default)] pub struct ConsoleUIData { - highest_adr: u64 + highest_adr: u64, + list: Vec } impl ConsoleUIData { @@ -245,6 +330,16 @@ impl ConsoleUIData { } self.highest_adr = get_last_section_end_adr(memory_map); + self.list = vec![ + String::from("Schwimmflugel 0"), + String::from("Schwimmflugel 1"), + String::from("Schwimmflugel 2"), + String::from("Schwimmflugel 3"), + String::from("Schwimmflugel 4"), + String::from("Schwimmflugel 5"), + String::from("Schwimmflugel 6"), + String::from("Schwimmflugel 7"), + ]; Ok(()) } } diff --git a/src/Tools/psxreadmap/src/main.rs b/src/Tools/psxreadmap/src/main.rs index 519b1e8a..069dd6d6 100644 --- a/src/Tools/psxreadmap/src/main.rs +++ b/src/Tools/psxreadmap/src/main.rs @@ -34,13 +34,13 @@ fn run_main(cmd: CommandLine) -> Result<(), Error> { let memory_map = load_memory_map(cmd.use_wsl, cmd.input)?; dump_memory_map(cmd.output, &memory_map)?; let rx = start_event_loop(); let terminal = setup_console()?; - let ui_data = ConsoleUIData::new(&memory_map)?; + let mut ui_data = ConsoleUIData::new(&memory_map)?; let mut console_ui = ConsoleUI::new(rx, terminal); loop { - match console_ui.update()? { + match console_ui.update(&ui_data)? { UIState::Alive => (), - UIState::Render => {console_ui.render(&ui_data)?;} + UIState::Render => {console_ui.render(&mut ui_data)?;} UIState::Terminated => break } }