Support different sized lists

This commit is contained in:
Jaby Blubb 2023-08-20 16:21:42 +02:00
parent 311e2156d9
commit c49644e5b0
1 changed files with 91 additions and 79 deletions

View File

@ -102,50 +102,49 @@ impl Default for ListSectionMode {
struct DualSelection<T:ID> { struct DualSelection<T:ID> {
mode: T, mode: T,
id: [usize; 2] idx: [i64; 2]
} }
impl<T:ID + Copy> DualSelection<T> { impl<T:ID + Copy> DualSelection<T> {
fn increment(&mut self, max: usize) { fn increment(&mut self) {
let cur_id = &mut self.id[self.mode.get_id()]; self.idx[self.mode.get_id()] += 1;
let new_selection = *cur_id + 1;
*cur_id = {
if new_selection >= max {
0
}
else {
new_selection
}
}
} }
fn decrement(&mut self, max: usize) { fn decrement(&mut self) {
let cur_id = &mut self.id[self.mode.get_id()%2]; self.idx[self.mode.get_id()] -= 1;
let new_selection = *cur_id - 1; }
*cur_id = { fn normalize_with(&mut self, max: i64) {
if new_selection >= max { let mut cur_idx = self.idx[self.mode.get_id()];
max - 1
}
else { while cur_idx < 0 {
new_selection cur_idx += max;
}
} }
if cur_idx >= max {
cur_idx %= max;
}
self.idx[self.mode.get_id()] = cur_idx;
} }
fn switch_mode_to(&mut self, section_mode: T) { fn switch_mode_to(&mut self, section_mode: T) {
self.mode = section_mode; self.mode = section_mode;
} }
fn reset_mode_to(&mut self, section_mode: T) {
let cur_id = &mut self.idx[self.mode.get_id()%2];
*cur_id = 0;
self.switch_mode_to(section_mode)
}
fn get_section_mode_id(&self) -> usize { fn get_section_mode_id(&self) -> usize {
self.mode.get_id() self.mode.get_id()
} }
fn get_selection_for(&self, section_mode: T) -> usize { fn get_selection_for(&self, section_mode: T) -> usize {
self.id[section_mode.get_id()] self.idx[section_mode.get_id()] as usize
} }
fn get_selection_state_for(&self, section_mode: T) -> ListState { fn get_selection_state_for(&self, section_mode: T) -> ListState {
@ -162,7 +161,7 @@ impl<T:ID + Copy> DualSelection<T> {
impl<T:ID + Default> Default for DualSelection<T> { impl<T:ID + Default> Default for DualSelection<T> {
fn default() -> Self { fn default() -> Self {
Self{mode: T::default(), id: [0, 0]} Self{mode: T::default(), idx: [0, 0]}
} }
} }
@ -305,48 +304,64 @@ impl ConsoleUI {
} }
fn update_stats(&mut self, key: KeyEvent) -> Option<UIState> { fn update_stats(&mut self, key: KeyEvent) -> Option<UIState> {
match key.code { let result = {
KeyCode::Down => { match key.code {
self.section_selection.increment(self.data.section_info.len()); KeyCode::Down => {
return Some(UIState::Render); self.section_selection.increment();
}, Some(UIState::Render)
KeyCode::Up => { },
self.section_selection.decrement(self.data.section_info.len()); KeyCode::Up => {
return Some(UIState::Render); self.section_selection.decrement();
}, Some(UIState::Render)
KeyCode::Char('a') => { },
self.section_selection.switch_mode_to(SectionMode::UpperSection); KeyCode::Char('a') => {
return Some(UIState::Render); self.section_selection.switch_mode_to(SectionMode::UpperSection);
}, Some(UIState::Render)
KeyCode::Char('s') => { },
self.section_selection.switch_mode_to(SectionMode::LowerSection); KeyCode::Char('s') => {
return Some(UIState::Render); self.section_selection.switch_mode_to(SectionMode::LowerSection);
}, Some(UIState::Render)
_ => None },
} _ => None
}
};
self.section_selection.normalize_with(self.data.section_info.len() as i64);
result
} }
fn update_list(&mut self, key: KeyEvent) -> Option<UIState> { fn update_list(&mut self, key: KeyEvent) -> Option<UIState> {
let length = self.data.section_info.len() - 1; let result = {
match key.code { match key.code {
KeyCode::Down => { KeyCode::Down => {
self.list_section_selection.increment(length); self.list_section_selection.increment();
return Some(UIState::Render); Some(UIState::Render)
}, },
KeyCode::Up => { KeyCode::Up => {
self.list_section_selection.decrement(length); self.list_section_selection.decrement();
return Some(UIState::Render); Some(UIState::Render)
}, },
KeyCode::Enter => { KeyCode::Enter => {
self.list_section_selection.switch_mode_to(ListSectionMode::Section); self.list_section_selection.switch_mode_to(ListSectionMode::Section);
return Some(UIState::Render); Some(UIState::Render)
}
KeyCode::Esc => {
self.list_section_selection.reset_mode_to(ListSectionMode::TopSection);
Some(UIState::Render)
}
_ => None
} }
KeyCode::Esc => { };
self.list_section_selection.switch_mode_to(ListSectionMode::TopSection);
return Some(UIState::Render); if matches!(self.list_section_selection.mode, ListSectionMode::TopSection) {
} self.list_section_selection.normalize_with(self.data.section_info.len() as i64);
_ => None
} }
else {
let length = Self::get_selected_top_section(&self.list_section_selection, &self.data).symbols.len();
self.list_section_selection.normalize_with(length as i64);
}
result
} }
fn update_quit(&mut self, key: KeyEvent) -> Option<UIState> { fn update_quit(&mut self, key: KeyEvent) -> Option<UIState> {
@ -390,15 +405,14 @@ impl ConsoleUI {
]).split(layout[0])) ]).split(layout[0]))
}; };
let section_list = List::new(data.section_info.iter().skip(1).map( let section_list = List::new(data.section_info.iter().map(
|section| { |section| {
ListItem::new(section.name.clone()) ListItem::new(section.name.clone())
}).collect::<Vec<_>>()).style(Style::default().fg(Color::White)) }).collect::<Vec<_>>()).style(Style::default().fg(Color::White))
.block(Self::create_default_border("Section")) .block(Self::create_default_border("Section"))
.highlight_style(Style::default().bg(Color::White)); .highlight_style(Style::default().bg(Color::White));
let current_selection = section_selection.get_selection_for(ListSectionMode::TopSection); let top_section = Self::get_selected_top_section(section_selection, data);
let top_section = &data.section_info[current_selection + 1];
let info_text = Paragraph::new(format!("Name: {}\nAdr: 0x{:X} - 0x{:X}\nSize: {} Bytes", top_section.name, top_section.start_adr, top_section.get_end_adr(), top_section.size)) let info_text = Paragraph::new(format!("Name: {}\nAdr: 0x{:X} - 0x{:X}\nSize: {} Bytes", top_section.name, top_section.start_adr, top_section.get_end_adr(), top_section.size))
.style(Style::default().fg(Color::White)) .style(Style::default().fg(Color::White))
.alignment(Alignment::Left) .alignment(Alignment::Left)
@ -417,21 +431,14 @@ impl ConsoleUI {
} }
else { else {
let text = Paragraph::new("Press \"ESC\" to leave") let symbol_list = List::new(top_section.symbols.iter().map(
.style(Style::default().fg(Color::White)) |symbol| {
.alignment(Alignment::Center) ListItem::new(symbol.name.clone())
.block(Self::create_default_border(format!("Symbols in {}", top_section.name)));
frame.render_widget(text, list_layout[1]);
/*let symbol_list = List::new(data.section_info.iter().skip(1).map(
|section| {
ListItem::new(section.name.clone())
}).collect::<Vec<_>>()).style(Style::default().fg(Color::White)) }).collect::<Vec<_>>()).style(Style::default().fg(Color::White))
.block(Self::create_default_border("Section")) .block(Self::create_default_border(format!("Symbols in {}", top_section.name)))
.highlight_style(Style::default().bg(Color::White));*/ .highlight_style(Style::default().bg(Color::White));
frame.render_stateful_widget(symbol_list, list_layout[1], &mut section_selection.get_selection_state_for(ListSectionMode::Section));
} }
} }
@ -485,6 +492,11 @@ impl ConsoleUI {
} }
}) })
} }
fn get_selected_top_section<'a>(section_selection: &DualSelection<ListSectionMode>, data: &'a ConsoleUIData) -> &'a SectionInfo {
let current_selection = section_selection.get_selection_for(ListSectionMode::TopSection);
&data.section_info[current_selection]
}
} }
#[derive(Default)] #[derive(Default)]