diff --git a/src/app.rs b/src/app.rs index c1a5c969..b0965c1c 100644 --- a/src/app.rs +++ b/src/app.rs @@ -996,6 +996,49 @@ impl App { } } + pub fn scroll_half_page_up(&mut self) { + if self.help_dialog_state.is_showing_help { + let current = &mut self.help_dialog_state.scroll_state.current_scroll_index; + let amount = self.help_dialog_state.height / 2; + + *current = current.saturating_sub(amount); + } else if self.current_widget.widget_type.is_widget_table() { + if let (Some((_tlc_x, tlc_y)), Some((_brc_x, brc_y))) = ( + &self.current_widget.top_left_corner, + &self.current_widget.bottom_right_corner, + ) { + let border_offset = if self.is_drawing_border() { 1 } else { 0 }; + let header_offset = self.header_offset(&self.current_widget); + let height = brc_y - tlc_y - 2 * border_offset - header_offset; + self.change_position_count(-(height as i64) / 2); + } + } + } + + pub fn scroll_half_page_down(&mut self) { + if self.help_dialog_state.is_showing_help { + let current = &mut self.help_dialog_state.scroll_state.current_scroll_index; + let amount = self.help_dialog_state.height / 2; + + *current = (*current + amount).min( + self.help_dialog_state + .scroll_state + .max_scroll_index + .saturating_sub(1), + ); + } else if self.current_widget.widget_type.is_widget_table() { + if let (Some((_tlc_x, tlc_y)), Some((_brc_x, brc_y))) = ( + &self.current_widget.top_left_corner, + &self.current_widget.bottom_right_corner, + ) { + let border_offset = if self.is_drawing_border() { 1 } else { 0 }; + let header_offset = self.header_offset(&self.current_widget); + let height = brc_y - tlc_y - 2 * border_offset - header_offset; + self.change_position_count(height as i64 / 2); + } + } + } + pub fn skip_cursor_beginning(&mut self) { if !self.ignore_normal_keybinds() { if let BottomWidgetType::ProcSearch = self.current_widget.widget_type { diff --git a/src/app/states.rs b/src/app/states.rs index 4687d822..2ca18c0b 100644 --- a/src/app/states.rs +++ b/src/app/states.rs @@ -67,6 +67,7 @@ pub struct AppDeleteDialogState { pub struct AppHelpDialogState { pub is_showing_help: bool, + pub height: u16, pub scroll_state: ParagraphScrollState, pub index_shortcuts: Vec, } @@ -75,6 +76,7 @@ impl Default for AppHelpDialogState { fn default() -> Self { AppHelpDialogState { is_showing_help: false, + height: 0, scroll_state: ParagraphScrollState::default(), index_shortcuts: vec![0; constants::HELP_TEXT.len()], } diff --git a/src/canvas/dialogs/help_dialog.rs b/src/canvas/dialogs/help_dialog.rs index 494da366..df76d52d 100644 --- a/src/canvas/dialogs/help_dialog.rs +++ b/src/canvas/dialogs/help_dialog.rs @@ -1,3 +1,5 @@ +use std::cmp::max; + use unicode_width::UnicodeWidthStr; use crate::{app::App, canvas::Painter, constants}; @@ -30,12 +32,20 @@ impl Painter { ), ]); + let block = Block::default() + .title(help_title) + .style(self.colours.border_style) + .borders(Borders::ALL) + .border_style(self.colours.border_style); + if app_state.should_get_widget_bounds() { + app_state.help_dialog_state.height = block.inner(draw_loc).height; + // We must also recalculate how many lines are wrapping to properly get scrolling to work on // small terminal sizes... oh joy. let mut overflow_buffer = 0; - let paragraph_width = std::cmp::max(draw_loc.width.saturating_sub(2), 1); + let paragraph_width = max(draw_loc.width.saturating_sub(2), 1); let mut prev_section_len = 0; constants::HELP_TEXT @@ -92,13 +102,7 @@ impl Painter { f.render_widget( Paragraph::new(self.styled_help_text.clone()) - .block( - Block::default() - .title(help_title) - .style(self.colours.border_style) - .borders(Borders::ALL) - .border_style(self.colours.border_style), - ) + .block(block) .style(self.colours.text_style) .alignment(Alignment::Left) .wrap(Wrap { trim: true }) diff --git a/src/constants.rs b/src/constants.rs index 9ac719b3..f77c1864 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -226,7 +226,7 @@ pub const HELP_CONTENTS_TEXT: [&str; 8] = [ // TODO [Help]: Search in help? // TODO [Help]: Move to using tables for easier formatting? -pub const GENERAL_HELP_TEXT: [&str; 31] = [ +pub const GENERAL_HELP_TEXT: [&str; 32] = [ "1 - General", "q, Ctrl-c Quit", "Esc Close dialog windows, search, widgets, or exit expanded mode", @@ -256,6 +256,7 @@ pub const GENERAL_HELP_TEXT: [&str; 31] = [ "- Zoom out on chart (increase time range)", "= Reset zoom", "PgUp, PgDown Scroll up/down a table by a page", + "Ctrl-u, Ctrl-d Scroll up/down a table by half a page", "Mouse scroll Scroll through the tables or zoom in/out of charts by scrolling up/down", "Mouse click Selects the clicked widget, table entry, dialog option, or tab", ]; diff --git a/src/lib.rs b/src/lib.rs index c7bdfb6c..4c5c099b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -166,9 +166,11 @@ pub fn handle_key_event_or_break( } KeyCode::Char('a') => app.skip_cursor_beginning(), KeyCode::Char('e') => app.skip_cursor_end(), - KeyCode::Char('u') => app.clear_search(), + KeyCode::Char('u') if app.is_in_search_widget() => app.clear_search(), KeyCode::Char('w') => app.clear_previous_word(), KeyCode::Char('h') => app.on_backspace(), + KeyCode::Char('d') => app.scroll_half_page_down(), + KeyCode::Char('u') => app.scroll_half_page_up(), // KeyCode::Char('j') => {}, // Move down // KeyCode::Char('k') => {}, // Move up // KeyCode::Char('h') => {}, // Move right