mirror of
https://codeberg.org/icewind/logsmash.git
synced 2026-06-03 18:14:11 +02:00
mouse scroll
This commit is contained in:
parent
78475c1e72
commit
ff4d270d02
3 changed files with 38 additions and 21 deletions
|
|
@ -10,7 +10,7 @@ use crate::ui::single_match::grouped_lines;
|
||||||
use crate::ui::state::{
|
use crate::ui::state::{
|
||||||
ErrorState, LogState, LogsState, MatchListState, MatchState, UiEvent, UiPage, UiState,
|
ErrorState, LogState, LogsState, MatchListState, MatchState, UiEvent, UiPage, UiState,
|
||||||
};
|
};
|
||||||
use ratatui::crossterm::event::{Event, KeyCode, KeyModifiers};
|
use ratatui::crossterm::event::{DisableMouseCapture, EnableMouseCapture, Event, KeyCode, KeyModifiers, MouseEventKind};
|
||||||
use ratatui::crossterm::terminal::{
|
use ratatui::crossterm::terminal::{
|
||||||
disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen,
|
disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen,
|
||||||
};
|
};
|
||||||
|
|
@ -19,6 +19,7 @@ use ratatui::prelude::*;
|
||||||
use ratatui::Terminal;
|
use ratatui::Terminal;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::stdout;
|
use std::io::stdout;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
mod error_list;
|
mod error_list;
|
||||||
mod footer;
|
mod footer;
|
||||||
|
|
@ -34,6 +35,7 @@ mod table;
|
||||||
pub fn run_ui(app: App) -> Result<(), UiError> {
|
pub fn run_ui(app: App) -> Result<(), UiError> {
|
||||||
enable_raw_mode()?;
|
enable_raw_mode()?;
|
||||||
stdout().execute(EnterAlternateScreen)?;
|
stdout().execute(EnterAlternateScreen)?;
|
||||||
|
stdout().execute(EnableMouseCapture)?;
|
||||||
let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?;
|
let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?;
|
||||||
terminal.clear().ok();
|
terminal.clear().ok();
|
||||||
|
|
||||||
|
|
@ -51,14 +53,15 @@ pub fn run_ui(app: App) -> Result<(), UiError> {
|
||||||
}
|
}
|
||||||
|
|
||||||
disable_raw_mode()?;
|
disable_raw_mode()?;
|
||||||
|
stdout().execute(DisableMouseCapture)?;
|
||||||
stdout().execute(LeaveAlternateScreen)?;
|
stdout().execute(LeaveAlternateScreen)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_events(page: UiPage) -> io::Result<Option<UiEvent>> {
|
fn handle_events(page: UiPage) -> io::Result<Option<UiEvent>> {
|
||||||
if event::poll(std::time::Duration::from_millis(50))? {
|
if event::poll(Duration::from_millis(50))? {
|
||||||
if let Event::Key(key) = event::read()? {
|
match event::read()? {
|
||||||
if key.kind == event::KeyEventKind::Press {
|
Event::Key(key) if key.kind == event::KeyEventKind::Press=> {
|
||||||
return Ok(match key.code {
|
return Ok(match key.code {
|
||||||
KeyCode::Char('c') if key.modifiers == KeyModifiers::CONTROL => {
|
KeyCode::Char('c') if key.modifiers == KeyModifiers::CONTROL => {
|
||||||
Some(UiEvent::Quit)
|
Some(UiEvent::Quit)
|
||||||
|
|
@ -67,28 +70,38 @@ fn handle_events(page: UiPage) -> io::Result<Option<UiEvent>> {
|
||||||
KeyCode::Esc => Some(UiEvent::Back),
|
KeyCode::Esc => Some(UiEvent::Back),
|
||||||
KeyCode::Char('e') if page == UiPage::MatchList => Some(UiEvent::Errors),
|
KeyCode::Char('e') if page == UiPage::MatchList => Some(UiEvent::Errors),
|
||||||
KeyCode::Left if page != UiPage::MatchList => Some(UiEvent::Back),
|
KeyCode::Left if page != UiPage::MatchList => Some(UiEvent::Back),
|
||||||
KeyCode::Down => Some(UiEvent::Down(1)),
|
KeyCode::Down => Some(UiEvent::Down(1, true)),
|
||||||
KeyCode::Up => Some(UiEvent::Up(1)),
|
KeyCode::Up => Some(UiEvent::Up(1, true)),
|
||||||
KeyCode::PageDown => Some(UiEvent::Down(10)),
|
KeyCode::PageDown => Some(UiEvent::Down(10, false)),
|
||||||
KeyCode::PageUp => Some(UiEvent::Up(10)),
|
KeyCode::PageUp => Some(UiEvent::Up(10, false)),
|
||||||
KeyCode::End => Some(UiEvent::Down(usize::MAX)),
|
KeyCode::End => Some(UiEvent::Down(usize::MAX, false)),
|
||||||
KeyCode::Home => Some(UiEvent::Up(usize::MAX)),
|
KeyCode::Home => Some(UiEvent::Up(usize::MAX, false)),
|
||||||
KeyCode::Enter | KeyCode::Right => Some(UiEvent::Select),
|
KeyCode::Enter | KeyCode::Right => Some(UiEvent::Select),
|
||||||
KeyCode::Char('c') => Some(UiEvent::Copy),
|
KeyCode::Char('c') => Some(UiEvent::Copy),
|
||||||
_ => None,
|
_ => None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Event::Mouse(mouse) => {
|
||||||
|
return Ok(match mouse.kind {
|
||||||
|
MouseEventKind::ScrollUp => Some(UiEvent::Up(1, false)),
|
||||||
|
MouseEventKind::ScrollDown => Some(UiEvent::Down(1, false)),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const UI_HEADER_SIZE: u16 = 5;
|
||||||
|
|
||||||
fn ui(frame: &mut Frame, app: &App, state: &mut UiState) {
|
fn ui(frame: &mut Frame, app: &App, state: &mut UiState) {
|
||||||
let page = state.page();
|
let page = state.page();
|
||||||
let layout = Layout::default()
|
let layout = Layout::default()
|
||||||
.direction(Direction::Vertical)
|
.direction(Direction::Vertical)
|
||||||
.constraints(vec![
|
.constraints(vec![
|
||||||
Constraint::Min(5),
|
Constraint::Length(UI_HEADER_SIZE),
|
||||||
Constraint::Percentage(100),
|
Constraint::Percentage(100),
|
||||||
Constraint::Length(1),
|
Constraint::Length(1),
|
||||||
])
|
])
|
||||||
|
|
|
||||||
|
|
@ -132,15 +132,15 @@ impl<'a> UiState<'a> {
|
||||||
(UiState::Quit, _) => (true, UiState::Quit),
|
(UiState::Quit, _) => (true, UiState::Quit),
|
||||||
(_, UiEvent::Quit) => (true, UiState::Quit),
|
(_, UiEvent::Quit) => (true, UiState::Quit),
|
||||||
(UiState::MatchList(_), UiEvent::Back) => (true, UiState::Quit),
|
(UiState::MatchList(_), UiEvent::Back) => (true, UiState::Quit),
|
||||||
(mut state, UiEvent::Down(step)) => {
|
(mut state, UiEvent::Down(step, rollover)) => {
|
||||||
if let Some(table_state) = state.table_state() {
|
if let Some(table_state) = state.table_state() {
|
||||||
table_state.down(step);
|
table_state.down(step, rollover);
|
||||||
}
|
}
|
||||||
(true, state)
|
(true, state)
|
||||||
}
|
}
|
||||||
(mut state, UiEvent::Up(step)) => {
|
(mut state, UiEvent::Up(step, rollover)) => {
|
||||||
if let Some(table_state) = state.table_state() {
|
if let Some(table_state) = state.table_state() {
|
||||||
table_state.up(step);
|
table_state.up(step, rollover);
|
||||||
}
|
}
|
||||||
(true, state)
|
(true, state)
|
||||||
}
|
}
|
||||||
|
|
@ -254,8 +254,8 @@ impl<'a> UiState<'a> {
|
||||||
pub enum UiEvent {
|
pub enum UiEvent {
|
||||||
Quit,
|
Quit,
|
||||||
Back,
|
Back,
|
||||||
Up(usize),
|
Up(usize, bool),
|
||||||
Down(usize),
|
Down(usize, bool),
|
||||||
Errors,
|
Errors,
|
||||||
Select,
|
Select,
|
||||||
Copy,
|
Copy,
|
||||||
|
|
|
||||||
|
|
@ -60,10 +60,14 @@ impl ScrollbarTableState {
|
||||||
self.table.selected().unwrap_or_default()
|
self.table.selected().unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn up(&mut self, step: usize) -> usize {
|
pub fn offset(&self) -> usize {
|
||||||
|
self.table.offset()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn up(&mut self, step: usize, rollover: bool) -> usize {
|
||||||
let current = self.table.selected().unwrap_or(0);
|
let current = self.table.selected().unwrap_or(0);
|
||||||
let after = if step > current {
|
let after = if step > current {
|
||||||
if step == 1 {
|
if rollover {
|
||||||
self.count - 1
|
self.count - 1
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
|
|
@ -76,10 +80,10 @@ impl ScrollbarTableState {
|
||||||
after
|
after
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn down(&mut self, step: usize) -> usize {
|
pub fn down(&mut self, step: usize, rollover: bool) -> usize {
|
||||||
let current = self.table.selected().unwrap_or(0);
|
let current = self.table.selected().unwrap_or(0);
|
||||||
let after = if step >= self.count - current {
|
let after = if step >= self.count - current {
|
||||||
if step == 1 {
|
if rollover {
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
self.count - 1
|
self.count - 1
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue