Preear Symbol list
This commit is contained in:
parent
ae1221de81
commit
f24d993e82
|
@ -1,13 +1,13 @@
|
||||||
mod readmap_helper;
|
mod readmap_helper;
|
||||||
use crossterm::event::{KeyCode, KeyEvent};
|
use crossterm::event::{KeyCode, KeyEvent};
|
||||||
use readmap::types::MemoryMap;
|
use readmap::types::{MemoryMap, Symbol};
|
||||||
use std::{convert::From, path::PathBuf};
|
use std::{convert::From, path::PathBuf};
|
||||||
use tool_helper::Error;
|
use tool_helper::Error;
|
||||||
use ratatui::{
|
use ratatui::{
|
||||||
layout::{Alignment, Constraint, Direction, Layout, Rect},
|
layout::{Alignment, Constraint, Direction, Layout, Rect},
|
||||||
style::{Color, Modifier, Style},
|
style::{Color, Modifier, Style},
|
||||||
text::{Line, Span},
|
text::{Line, Span},
|
||||||
widgets::{Block, Borders, BorderType, Gauge, List, ListItem, ListState, Paragraph, Tabs}
|
widgets::{Block, Borders, BorderType, Gauge, List, ListItem, ListState, Paragraph, Tabs, block::Title}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub type EventReceiver = std::sync::mpsc::Receiver<Event<crossterm::event::KeyEvent>>;
|
pub type EventReceiver = std::sync::mpsc::Receiver<Event<crossterm::event::KeyEvent>>;
|
||||||
|
@ -136,7 +136,7 @@ impl<T:ID + Copy> DualSelection<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn switch_section_to(&mut self, section_mode: T) {
|
fn switch_mode_to(&mut self, section_mode: T) {
|
||||||
self.mode = section_mode;
|
self.mode = section_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,12 +148,16 @@ impl<T:ID + Copy> DualSelection<T> {
|
||||||
self.id[section_mode.get_id()]
|
self.id[section_mode.get_id()]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_current_selection(&self) -> ListState {
|
fn get_selection_state_for(&self, section_mode: T) -> ListState {
|
||||||
let mut state = ListState::default();
|
let mut state = ListState::default();
|
||||||
|
|
||||||
state.select(Some(self.get_selection_for(self.mode)));
|
state.select(Some(self.get_selection_for(section_mode)));
|
||||||
state
|
state
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_current_selection_state(&self) -> ListState {
|
||||||
|
self.get_selection_state_for(self.mode)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:ID + Default> Default for DualSelection<T> {
|
impl<T:ID + Default> Default for DualSelection<T> {
|
||||||
|
@ -181,7 +185,7 @@ impl ConsoleUI {
|
||||||
ConsoleUI{data: ConsoleUIData::default(), rx, terminal, console_size: Rect::default(), menu_selection: MenuSelection::Stats, section_selection: DualSelection::default(), list_section_selection: DualSelection::default()}
|
ConsoleUI{data: ConsoleUIData::default(), rx, terminal, console_size: Rect::default(), menu_selection: MenuSelection::Stats, section_selection: DualSelection::default(), list_section_selection: DualSelection::default()}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_data(&mut self, memory_map: &MemoryMap) -> Result<(), Error> {
|
pub fn update_data(&mut self, memory_map: MemoryMap) -> Result<(), Error> {
|
||||||
self.data = ConsoleUIData::from(memory_map)?;
|
self.data = ConsoleUIData::from(memory_map)?;
|
||||||
self.section_selection = DualSelection::default();
|
self.section_selection = DualSelection::default();
|
||||||
self.list_section_selection = DualSelection::default();
|
self.list_section_selection = DualSelection::default();
|
||||||
|
@ -311,11 +315,11 @@ impl ConsoleUI {
|
||||||
return Some(UIState::Render);
|
return Some(UIState::Render);
|
||||||
},
|
},
|
||||||
KeyCode::Char('a') => {
|
KeyCode::Char('a') => {
|
||||||
self.section_selection.switch_section_to(SectionMode::UpperSection);
|
self.section_selection.switch_mode_to(SectionMode::UpperSection);
|
||||||
return Some(UIState::Render);
|
return Some(UIState::Render);
|
||||||
},
|
},
|
||||||
KeyCode::Char('s') => {
|
KeyCode::Char('s') => {
|
||||||
self.section_selection.switch_section_to(SectionMode::LowerSection);
|
self.section_selection.switch_mode_to(SectionMode::LowerSection);
|
||||||
return Some(UIState::Render);
|
return Some(UIState::Render);
|
||||||
},
|
},
|
||||||
_ => None
|
_ => None
|
||||||
|
@ -333,6 +337,14 @@ impl ConsoleUI {
|
||||||
self.list_section_selection.decrement(length);
|
self.list_section_selection.decrement(length);
|
||||||
return Some(UIState::Render);
|
return Some(UIState::Render);
|
||||||
},
|
},
|
||||||
|
KeyCode::Enter => {
|
||||||
|
self.list_section_selection.switch_mode_to(ListSectionMode::Section);
|
||||||
|
return Some(UIState::Render);
|
||||||
|
}
|
||||||
|
KeyCode::Esc => {
|
||||||
|
self.list_section_selection.switch_mode_to(ListSectionMode::TopSection);
|
||||||
|
return Some(UIState::Render);
|
||||||
|
}
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -354,17 +366,13 @@ impl ConsoleUI {
|
||||||
let content_list = List::new(data.section_info.iter().map(|section| {
|
let content_list = List::new(data.section_info.iter().map(|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(Block::default()
|
.block(Self::create_default_border(""))
|
||||||
.borders(Borders::ALL)
|
|
||||||
.style(Style::default().fg(Color::White))
|
|
||||||
.border_type(BorderType::Plain)
|
|
||||||
)
|
|
||||||
.highlight_style(Style::default().bg(HIGHLIGHT_COLOR[section_selection.get_section_mode_id()]));
|
.highlight_style(Style::default().bg(HIGHLIGHT_COLOR[section_selection.get_section_mode_id()]));
|
||||||
|
|
||||||
let first_mem_gauge = Self::create_mem_gauge_from(&data.section_info[section_selection.get_selection_for(SectionMode::UpperSection)], "a", HIGHLIGHT_COLOR[0]);
|
let first_mem_gauge = Self::create_mem_gauge_from(&data.section_info[section_selection.get_selection_for(SectionMode::UpperSection)], "a", HIGHLIGHT_COLOR[0]);
|
||||||
let second_mem_gauge = Self::create_mem_gauge_from(&data.section_info[section_selection.get_selection_for(SectionMode::LowerSection)], "s", HIGHLIGHT_COLOR[1]);
|
let second_mem_gauge = Self::create_mem_gauge_from(&data.section_info[section_selection.get_selection_for(SectionMode::LowerSection)], "s", HIGHLIGHT_COLOR[1]);
|
||||||
|
|
||||||
frame.render_stateful_widget(content_list, layout[0], &mut section_selection.get_current_selection());
|
frame.render_stateful_widget(content_list, layout[0], &mut section_selection.get_current_selection_state());
|
||||||
frame.render_widget(first_mem_gauge, layout[1]);
|
frame.render_widget(first_mem_gauge, layout[1]);
|
||||||
frame.render_widget(second_mem_gauge, layout[2]);
|
frame.render_widget(second_mem_gauge, layout[2]);
|
||||||
}
|
}
|
||||||
|
@ -382,45 +390,68 @@ impl ConsoleUI {
|
||||||
]).split(layout[0]))
|
]).split(layout[0]))
|
||||||
};
|
};
|
||||||
|
|
||||||
let section_list = List::new(data.section_info.iter().skip(1).map(|section| {
|
let section_list = List::new(data.section_info.iter().skip(1).map(
|
||||||
|
|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(Block::default()
|
.block(Self::create_default_border("Section"))
|
||||||
.borders(Borders::ALL)
|
|
||||||
.style(Style::default().fg(Color::White))
|
|
||||||
.border_type(BorderType::Plain)
|
|
||||||
.title("Section")
|
|
||||||
)
|
|
||||||
.highlight_style(Style::default().bg(Color::White));
|
.highlight_style(Style::default().bg(Color::White));
|
||||||
|
|
||||||
let top_section = &data.section_info[section_selection.get_selection_for(ListSectionMode::TopSection) + 1];
|
let current_selection = section_selection.get_selection_for(ListSectionMode::TopSection);
|
||||||
|
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)
|
||||||
.block(Block::default()
|
.block(Self::create_default_border("Information"));
|
||||||
.borders(Borders::ALL)
|
|
||||||
.style(Style::default().fg(Color::White))
|
|
||||||
.border_type(BorderType::Plain).title("Information")
|
|
||||||
);
|
|
||||||
|
|
||||||
frame.render_widget(info_text, info_layout);
|
frame.render_widget(info_text, info_layout);
|
||||||
frame.render_stateful_widget(section_list, list_layout[0], &mut section_selection.get_current_selection());
|
frame.render_stateful_widget(section_list, list_layout[0], &mut section_selection.get_selection_state_for(ListSectionMode::TopSection));
|
||||||
//frame.render_widget(text, list_layout[1]);
|
|
||||||
|
if matches!(section_selection.mode, ListSectionMode::TopSection) {
|
||||||
|
let text = Paragraph::new("Press \"ENTER\" to display")
|
||||||
|
.style(Style::default().fg(Color::White))
|
||||||
|
.alignment(Alignment::Center)
|
||||||
|
.block(Self::create_default_border("Symbols"));
|
||||||
|
|
||||||
|
frame.render_widget(text, list_layout[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
let text = Paragraph::new("Press \"ESC\" to leave")
|
||||||
|
.style(Style::default().fg(Color::White))
|
||||||
|
.alignment(Alignment::Center)
|
||||||
|
.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))
|
||||||
|
.block(Self::create_default_border("Section"))
|
||||||
|
.highlight_style(Style::default().bg(Color::White));*/
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_quit(frame: &mut ConsoleFrame, layout: Rect) {
|
fn render_quit(frame: &mut ConsoleFrame, layout: Rect) {
|
||||||
let text = Paragraph::new("Press \"ENTER\" to exit")
|
let text = Paragraph::new("Press \"ENTER\" to exit")
|
||||||
.style(Style::default().fg(Color::White))
|
.style(Style::default().fg(Color::White))
|
||||||
.alignment(Alignment::Center)
|
.alignment(Alignment::Center)
|
||||||
.block(Block::default()
|
.block(Self::create_default_border("QUIT"));
|
||||||
.borders(Borders::ALL)
|
|
||||||
.style(Style::default().fg(Color::White))
|
|
||||||
.border_type(BorderType::Plain).title("QUIT")
|
|
||||||
);
|
|
||||||
|
|
||||||
frame.render_widget(text, layout);
|
frame.render_widget(text, layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn create_default_border<'a, T: Into<Title<'a>>>(title: T) -> Block<'a> {
|
||||||
|
Block::default()
|
||||||
|
.borders(Borders::ALL)
|
||||||
|
.style(Style::default().fg(Color::White))
|
||||||
|
.border_type(BorderType::Plain)
|
||||||
|
.title(title)
|
||||||
|
}
|
||||||
|
|
||||||
fn create_mem_gauge_from<'a>(section_info: &SectionInfo, string: &'a str, color: Color) -> Gauge<'a> {
|
fn create_mem_gauge_from<'a>(section_info: &SectionInfo, string: &'a str, color: Color) -> Gauge<'a> {
|
||||||
const PERCISION:usize = 5;
|
const PERCISION:usize = 5;
|
||||||
const FLOAT_DISPLAY_LIMIT:f64 = {
|
const FLOAT_DISPLAY_LIMIT:f64 = {
|
||||||
|
@ -465,7 +496,7 @@ impl ConsoleUIData {
|
||||||
pub const RAM_BASE_ADDRESS:u64 = 0x80000000;
|
pub const RAM_BASE_ADDRESS:u64 = 0x80000000;
|
||||||
pub const RAM_SIZE:usize = 2*1024*1024;
|
pub const RAM_SIZE:usize = 2*1024*1024;
|
||||||
|
|
||||||
pub fn from(memory_map: &MemoryMap) -> Result<Self, Error> {
|
pub fn from(memory_map: MemoryMap) -> Result<Self, Error> {
|
||||||
fn get_last_section_end_adr(memory_map: &MemoryMap) -> u64 {
|
fn get_last_section_end_adr(memory_map: &MemoryMap) -> u64 {
|
||||||
if let Some(section) = memory_map.sections.last() {
|
if let Some(section) = memory_map.sections.last() {
|
||||||
return section.adr + section.size as u64;
|
return section.adr + section.size as u64;
|
||||||
|
@ -474,19 +505,21 @@ impl ConsoleUIData {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut new_self = ConsoleUIData::default();
|
let mut new_self = ConsoleUIData::default();
|
||||||
let highest_adr = get_last_section_end_adr(memory_map);
|
let highest_adr = get_last_section_end_adr(&memory_map);
|
||||||
let program_size = (highest_adr - Self::RAM_BASE_ADDRESS) as usize;
|
let program_size = (highest_adr - Self::RAM_BASE_ADDRESS) as usize;
|
||||||
|
|
||||||
new_self.section_info.push(SectionInfo{
|
new_self.section_info.push(SectionInfo{
|
||||||
name: String::from("<overall usage>"),
|
name: String::from("<overall usage>"),
|
||||||
|
symbols: memory_map.global,
|
||||||
start_adr: Self::RAM_BASE_ADDRESS,
|
start_adr: Self::RAM_BASE_ADDRESS,
|
||||||
size: program_size,
|
size: program_size,
|
||||||
max_size: Self::RAM_SIZE
|
max_size: Self::RAM_SIZE
|
||||||
});
|
});
|
||||||
|
|
||||||
for section in &memory_map.sections {
|
for section in memory_map.sections {
|
||||||
new_self.section_info.push(SectionInfo{
|
new_self.section_info.push(SectionInfo{
|
||||||
name: section.name.clone(),
|
name: section.name,
|
||||||
|
symbols: section.symbols,
|
||||||
start_adr: section.adr,
|
start_adr: section.adr,
|
||||||
size: section.size,
|
size: section.size,
|
||||||
max_size: program_size
|
max_size: program_size
|
||||||
|
@ -500,6 +533,7 @@ impl ConsoleUIData {
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct SectionInfo {
|
struct SectionInfo {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
pub symbols: Vec<Symbol>,
|
||||||
pub start_adr: u64,
|
pub start_adr: u64,
|
||||||
pub size: usize,
|
pub size: usize,
|
||||||
pub max_size: usize,
|
pub max_size: usize,
|
||||||
|
|
|
@ -36,7 +36,7 @@ fn run_main(cmd: CommandLine) -> Result<(), Error> {
|
||||||
let terminal = setup_console()?;
|
let terminal = setup_console()?;
|
||||||
let mut console_ui = ConsoleUI::new(rx, terminal);
|
let mut console_ui = ConsoleUI::new(rx, terminal);
|
||||||
|
|
||||||
console_ui.update_data(&memory_map)?;
|
console_ui.update_data(memory_map)?;
|
||||||
loop {
|
loop {
|
||||||
match console_ui.update()? {
|
match console_ui.update()? {
|
||||||
UIState::Alive => (),
|
UIState::Alive => (),
|
||||||
|
|
Loading…
Reference in New Issue