Skip to content

Commit

Permalink
remember position in previous menus (#48)
Browse files Browse the repository at this point in the history
  • Loading branch information
rmsthebest authored Nov 18, 2024
1 parent f95959c commit b6941fa
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 22 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed

### Changed
- Remember position when entering a sub-menu to restore state on exit.

### Removed

Expand Down
64 changes: 42 additions & 22 deletions src/tui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,6 @@ impl Repository {
self.path.pop();
}

fn count(&self) -> usize {
self.current_level().len()
}

fn current_level_desc(&self) -> Vec<(bool, String)> {
self.current_level()
.iter()
Expand Down Expand Up @@ -164,7 +160,7 @@ pub fn restore_terminal() -> AppResult<()> {
}

pub struct App {
state: ListState,
state: Vec<ListState>,
repository: Repository,
}

Expand All @@ -175,7 +171,35 @@ impl App {

Self {
repository,
state: initial_state,
state: vec![initial_state],
}
}
pub fn selected(&self) -> usize {
if let Some(current) = self.state.last() {
current.selected().unwrap_or_default()
} else {
0
}
}

pub fn select_next(&mut self) {
if let Some(current) = self.state.last_mut() {
current.select_next();
}
}
pub fn select_previous(&mut self) {
if let Some(current) = self.state.last_mut() {
current.select_previous();
}
}
pub fn enter_menu(&mut self) {
let mut new_state = ListState::default();
new_state.select(Some(0));
self.state.push(new_state);
}
pub fn exit_menu(&mut self) {
if self.state.len() > 1 {
self.state.pop();
}
}
}
Expand All @@ -194,31 +218,22 @@ impl App {
Char('s') => return Ok(Some(self.repository.selected.clone())),
Char('h') | Left => {
self.repository.up();
self.state.select(Some(0));
self.exit_menu();
}
Char('l') | Char(' ') | Right | Enter => {
let selected = self.state.selected().unwrap_or_default();
let selected = self.selected();
if self.repository.is_option(selected) {
self.repository.toggle_current(selected);
} else {
self.repository
.select(self.state.selected().unwrap_or_default());
self.state.select(Some(0));
self.repository.select(self.selected());
self.enter_menu();
}
}
Char('j') | Down => {
if self.state.selected().unwrap_or_default()
< self.repository.count() - 1
{
self.state
.select(Some(self.state.selected().unwrap_or_default() + 1));
}
self.select_next();
}
Char('k') | Up => {
if self.state.selected().unwrap_or_default() > 0 {
self.state
.select(Some(self.state.selected().unwrap_or_default() - 1));
}
self.select_previous();
}
_ => {}
}
Expand Down Expand Up @@ -314,7 +329,12 @@ impl App {
// We can now render the item list
// (look carefully, we are using StatefulWidget's render.)
// ratatui::widgets::StatefulWidget::render as stateful_render
StatefulWidget::render(items, inner_area, buf, &mut self.state);
if let Some(current_state) = self.state.last_mut() {
StatefulWidget::render(items, inner_area, buf, current_state);
} else {
ratatui::restore();
panic!("menu state not found!")
}
}

fn render_footer(&self, area: Rect, buf: &mut Buffer) {
Expand Down

0 comments on commit b6941fa

Please sign in to comment.