summaryrefslogtreecommitdiff
path: root/src/list.rs
diff options
context:
space:
mode:
authormo8it <mo8it@proton.me>2024-08-25 20:31:08 +0200
committermo8it <mo8it@proton.me>2024-08-25 20:31:08 +0200
commit360605e2840d7b8876afac6df5178c068484cd57 (patch)
treee453cf5ab30f40e976ce16ee373a2b0fb2f88283 /src/list.rs
parent47976caa69e24ea9ee5d38918a0abea89ff10983 (diff)
parent64772544fad6788fd3fce5db3f357dba6f2d8d23 (diff)
Merge branch 'rm-ratatui'
Diffstat (limited to 'src/list.rs')
-rw-r--r--src/list.rs147
1 files changed, 75 insertions, 72 deletions
diff --git a/src/list.rs b/src/list.rs
index 6ff6959..a8e5225 100644
--- a/src/list.rs
+++ b/src/list.rs
@@ -1,95 +1,96 @@
use anyhow::{Context, Result};
-use ratatui::{
- backend::CrosstermBackend,
- crossterm::{
- event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, KeyEventKind},
- terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
- QueueableCommand,
+use crossterm::{
+ cursor,
+ event::{
+ self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, KeyEventKind, MouseEventKind,
},
- Terminal,
+ terminal::{
+ disable_raw_mode, enable_raw_mode, DisableLineWrap, EnableLineWrap, EnterAlternateScreen,
+ LeaveAlternateScreen,
+ },
+ QueueableCommand,
};
use std::io::{self, StdoutLock, Write};
use crate::app_state::AppState;
-use self::state::{Filter, UiState};
+use self::state::{Filter, ListState};
mod state;
fn handle_list(app_state: &mut AppState, stdout: &mut StdoutLock) -> Result<()> {
- let mut terminal = Terminal::new(CrosstermBackend::new(stdout))?;
- terminal.clear()?;
-
- let mut ui_state = UiState::new(app_state);
-
- 'outer: loop {
- terminal.try_draw(|frame| ui_state.draw(frame).map_err(io::Error::other))?;
-
- let key = loop {
- match event::read().context("Failed to read terminal event")? {
- Event::Key(key) => match key.kind {
- KeyEventKind::Press | KeyEventKind::Repeat => break key,
- KeyEventKind::Release => (),
- },
- // Redraw
- Event::Resize(_, _) => continue 'outer,
- // Ignore
- Event::FocusGained | Event::FocusLost | Event::Mouse(_) | Event::Paste(_) => (),
- }
- };
-
- ui_state.message.clear();
-
- match key.code {
- KeyCode::Char('q') => break,
- KeyCode::Down | KeyCode::Char('j') => ui_state.select_next(),
- KeyCode::Up | KeyCode::Char('k') => ui_state.select_previous(),
- KeyCode::Home | KeyCode::Char('g') => ui_state.select_first(),
- KeyCode::End | KeyCode::Char('G') => ui_state.select_last(),
- KeyCode::Char('d') => {
- let message = if ui_state.filter == Filter::Done {
- ui_state.filter = Filter::None;
- "Disabled filter DONE"
- } else {
- ui_state.filter = Filter::Done;
- "Enabled filter DONE │ Press d again to disable the filter"
- };
-
- ui_state = ui_state.with_updated_rows();
- ui_state.message.push_str(message);
+ let mut list_state = ListState::new(app_state, stdout)?;
+
+ loop {
+ match event::read().context("Failed to read terminal event")? {
+ Event::Key(key) => {
+ match key.kind {
+ KeyEventKind::Release => continue,
+ KeyEventKind::Press | KeyEventKind::Repeat => (),
+ }
+
+ list_state.message.clear();
+
+ match key.code {
+ KeyCode::Char('q') => return Ok(()),
+ KeyCode::Down | KeyCode::Char('j') => list_state.select_next(),
+ KeyCode::Up | KeyCode::Char('k') => list_state.select_previous(),
+ KeyCode::Home | KeyCode::Char('g') => list_state.select_first(),
+ KeyCode::End | KeyCode::Char('G') => list_state.select_last(),
+ KeyCode::Char('d') => {
+ if list_state.filter() == Filter::Done {
+ list_state.set_filter(Filter::None);
+ list_state.message.push_str("Disabled filter DONE");
+ } else {
+ list_state.set_filter(Filter::Done);
+ list_state.message.push_str(
+ "Enabled filter DONE │ Press d again to disable the filter",
+ );
+ }
+ }
+ KeyCode::Char('p') => {
+ let message = if list_state.filter() == Filter::Pending {
+ list_state.set_filter(Filter::None);
+ "Disabled filter PENDING"
+ } else {
+ list_state.set_filter(Filter::Pending);
+ "Enabled filter PENDING │ Press p again to disable the filter"
+ };
+
+ list_state.message.push_str(message);
+ }
+ KeyCode::Char('r') => list_state.reset_selected()?,
+ KeyCode::Char('c') => {
+ if list_state.selected_to_current_exercise()? {
+ return Ok(());
+ }
+ }
+ // Redraw to remove the message.
+ KeyCode::Esc => (),
+ _ => continue,
+ }
}
- KeyCode::Char('p') => {
- let message = if ui_state.filter == Filter::Pending {
- ui_state.filter = Filter::None;
- "Disabled filter PENDING"
- } else {
- ui_state.filter = Filter::Pending;
- "Enabled filter PENDING │ Press p again to disable the filter"
- };
-
- ui_state = ui_state.with_updated_rows();
- ui_state.message.push_str(message);
- }
- KeyCode::Char('r') => {
- ui_state = ui_state.with_reset_selected()?;
- }
- KeyCode::Char('c') => {
- ui_state.selected_to_current_exercise()?;
- break;
- }
- _ => (),
+ Event::Mouse(event) => match event.kind {
+ MouseEventKind::ScrollDown => list_state.select_next(),
+ MouseEventKind::ScrollUp => list_state.select_previous(),
+ _ => continue,
+ },
+ Event::Resize(width, height) => list_state.set_term_size(width, height),
+ // Ignore
+ Event::FocusGained | Event::FocusLost => continue,
}
- }
- Ok(())
+ list_state.draw(stdout)?;
+ }
}
pub fn list(app_state: &mut AppState) -> Result<()> {
let mut stdout = io::stdout().lock();
stdout
.queue(EnterAlternateScreen)?
- .queue(EnableMouseCapture)?
- .flush()?;
+ .queue(cursor::Hide)?
+ .queue(DisableLineWrap)?
+ .queue(EnableMouseCapture)?;
enable_raw_mode()?;
let res = handle_list(app_state, &mut stdout);
@@ -97,6 +98,8 @@ pub fn list(app_state: &mut AppState) -> Result<()> {
// Restore the terminal even if we got an error.
stdout
.queue(LeaveAlternateScreen)?
+ .queue(cursor::Show)?
+ .queue(EnableLineWrap)?
.queue(DisableMouseCapture)?
.flush()?;
disable_raw_mode()?;