Skip to content

Commit

Permalink
tui: Add widget selection with arrow keys
Browse files Browse the repository at this point in the history
  • Loading branch information
David Isaksson committed Jan 5, 2024
1 parent 06822e4 commit ab730e3
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 16 deletions.
51 changes: 38 additions & 13 deletions src/emulator/tui/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use crate::{
},
};

use super::ui::AppWidget;

#[derive(Debug, Default, Clone)]
pub struct StateValue<T> {
value: T,
Expand Down Expand Up @@ -93,6 +95,8 @@ pub struct App {
/// State of the CPU
state: EmulationState,

pub selected_widget: AppWidget,

/// If the app should quit
should_quit: bool,
}
Expand All @@ -119,6 +123,7 @@ impl App {
program: program.to_vec(),
program_start,
disassembled_program: disassembly,
selected_widget: AppWidget::Disassembly,
..Default::default()
};

Expand Down Expand Up @@ -190,31 +195,51 @@ impl App {
}

pub fn scroll_up(&mut self) {
if self.disassembly_widget_scroll > 0 {
self.disassembly_widget_scroll -= 1;
match self.selected_widget {
AppWidget::Disassembly => {
if self.disassembly_widget_scroll > 0 {
self.disassembly_widget_scroll -= 1;
}
}
_ => {}
}
}

pub fn scroll_up_page(&mut self) {
if self.disassembly_widget_scroll > self.disassembly_frame_height {
self.disassembly_widget_scroll -= self.disassembly_frame_height;
} else {
self.disassembly_widget_scroll = 0;
match self.selected_widget {
AppWidget::Disassembly => {
if self.disassembly_widget_scroll > self.disassembly_frame_height {
self.disassembly_widget_scroll -= self.disassembly_frame_height;
} else {
self.disassembly_widget_scroll = 0;
}
}
_ => {}
}
}

pub fn scroll_down(&mut self) {
if self.disassembly_widget_scroll < self.disassembled_program.len() - 1 {
self.disassembly_widget_scroll += 1;
match self.selected_widget {
AppWidget::Disassembly => {
if self.disassembly_widget_scroll < self.disassembled_program.len() - 1 {
self.disassembly_widget_scroll += 1;
}
}
_ => {}
}
}

pub fn scroll_down_page(&mut self) {
let max = self.disassembled_program.len() - 1;
if self.disassembly_widget_scroll < max - self.disassembly_frame_height {
self.disassembly_widget_scroll += self.disassembly_frame_height;
} else {
self.disassembly_widget_scroll = max;
match self.selected_widget {
AppWidget::Disassembly => {
let max = self.disassembled_program.len() - 1;
if self.disassembly_widget_scroll < max - self.disassembly_frame_height {
self.disassembly_widget_scroll += self.disassembly_frame_height;
} else {
self.disassembly_widget_scroll = max;
}
}
_ => {}
}
}
}
66 changes: 63 additions & 3 deletions src/emulator/tui/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,63 @@ use crate::emulator::cpu::STACK_PAGE;

use super::app::{App, StateValue};

#[derive(Debug, Default, Copy, Clone, PartialEq)]
pub enum AppWidget {
Registers,
Stack,
#[default]
Disassembly,
}

impl AppWidget {
pub fn next(&self) -> AppWidget {
match self {
AppWidget::Registers => AppWidget::Stack,
AppWidget::Stack => AppWidget::Disassembly,
AppWidget::Disassembly => AppWidget::Disassembly, // Don't wrap
}
}

pub fn prev(&self) -> AppWidget {
match self {
AppWidget::Registers => AppWidget::Registers, // Don't wrap
AppWidget::Stack => AppWidget::Registers,
AppWidget::Disassembly => AppWidget::Stack,
}
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_widget_cycle() {
let mut w = AppWidget::default();
assert_eq!(w, AppWidget::Disassembly);
w = w.next();
assert_eq!(w, AppWidget::Disassembly);
w = w.prev();
assert_eq!(w, AppWidget::Stack);
w = w.prev();
assert_eq!(w, AppWidget::Registers);
w = w.prev();
assert_eq!(w, AppWidget::Registers);
w = w.next();
assert_eq!(w, AppWidget::Stack);
}
}

fn is_selected_style(selected: AppWidget, current_widget: AppWidget) -> Style {
if selected == current_widget {
Style::default().fg(Color::Yellow)
} else {
Style::default()
.fg(Color::Yellow)
.add_modifier(Modifier::DIM)
}
}

fn style_state_text<T: PartialEq>(state: &StateValue<T>) -> Style {
if state.has_changed() {
Style::default().light_yellow().bold()
Expand Down Expand Up @@ -92,7 +149,7 @@ fn render_registers_widget(app: &mut App, frame: &mut Frame, layout: Rect) {
.borders(Borders::ALL)
.border_type(BorderType::Rounded),
)
.style(Style::default().fg(Color::Yellow))
.style(is_selected_style(app.selected_widget, AppWidget::Registers))
.alignment(Alignment::Left),
layout,
);
Expand All @@ -117,7 +174,7 @@ fn render_stack_widget(app: &mut App, frame: &mut Frame, layout: Rect) {
.title("Stack")
.borders(Borders::ALL)
.border_type(BorderType::Rounded)
.style(Style::default().fg(Color::Yellow)),
.style(is_selected_style(app.selected_widget, AppWidget::Stack)),
),
layout,
);
Expand Down Expand Up @@ -151,7 +208,10 @@ fn render_disassembly_widget(app: &mut App, frame: &mut Frame, layout: Rect) {
.title("Disassembly")
.borders(Borders::ALL)
.border_type(BorderType::Rounded)
.style(Style::default().fg(Color::Yellow)),
.style(is_selected_style(
app.selected_widget,
AppWidget::Disassembly,
)),
),
layout,
);
Expand Down
6 changes: 6 additions & 0 deletions src/emulator/tui/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ pub fn update(app: &mut App, key_event: KeyEvent) {
KeyCode::Down => app.scroll_down(),
KeyCode::PageUp => app.scroll_up_page(),
KeyCode::PageDown => app.scroll_down_page(),
KeyCode::Left => {
app.selected_widget = app.selected_widget.prev();
}
KeyCode::Right => {
app.selected_widget = app.selected_widget.next();
}
_ => {}
};
}

0 comments on commit ab730e3

Please sign in to comment.