diff options
author | Tim Oram <dev@mitmaro.ca> | 2020-08-04 23:59:29 -0230 |
---|---|---|
committer | Tim Oram <dev@mitmaro.ca> | 2020-09-02 14:51:24 -0230 |
commit | 04c8b0e1c5f4a00c4613e83fe9308b5c33e72a1c (patch) | |
tree | 9953b41bfd4bbcb7e47667f59c4a9e39d0bedc53 /src/process/help.rs | |
parent | c28186e99730f82bac3ada8d729825e285752371 (diff) |
Refactor help to not be a process module
The help process module always needed to have knowledge of the different
modules in the project, which was very awkward. This updates the help
system to be part of the process module and moves the help data into the
modules. This also allowed the removal of the visual boolean on the List
state, that was only used when rendering the help module.
Diffstat (limited to 'src/process/help.rs')
-rw-r--r-- | src/process/help.rs | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/src/process/help.rs b/src/process/help.rs new file mode 100644 index 0000000..127d512 --- /dev/null +++ b/src/process/help.rs @@ -0,0 +1,104 @@ +use crate::display::display_color::DisplayColor; +use crate::input::input_handler::{InputHandler, InputMode}; +use crate::input::Input; +use crate::process::handle_input_result::HandleInputResult; +use crate::view::line_segment::LineSegment; +use crate::view::view_data::ViewData; +use crate::view::view_line::ViewLine; +use crate::view::View; +use unicode_segmentation::UnicodeSegmentation; + +pub struct Help { + view_data: ViewData, +} + +fn get_max_help_key_length(lines: &[(&str, &str)]) -> usize { + let mut max_length = 0; + for (key, _) in lines { + let len = UnicodeSegmentation::graphemes(*key, true).count(); + if len > max_length { + max_length = len; + } + } + max_length +} + +impl Help { + pub fn new_from_keybindings_descriptions(keybindings: &[(&str, &str)]) -> Self { + let mut view_data = ViewData::new(); + view_data.set_show_title(true); + + let max_key_length = get_max_help_key_length(keybindings); + + view_data.push_leading_line( + ViewLine::new_pinned(vec![LineSegment::new_with_color_and_style( + format!(" {0:width$} Action", "Key", width = max_key_length).as_str(), + DisplayColor::Normal, + false, + true, + false, + )]) + .set_padding_color_and_style(DisplayColor::Normal, false, true, false), + ); + + for line in keybindings { + view_data.push_line(ViewLine::new_with_pinned_segments( + vec![ + LineSegment::new_with_color( + format!(" {0:width$}", line.0, width = max_key_length).as_str(), + DisplayColor::IndicatorColor, + ), + LineSegment::new_with_color_and_style("|", DisplayColor::Normal, true, false, false), + LineSegment::new(line.1), + ], + 2, + )); + } + + view_data.push_trailing_line(ViewLine::new_pinned(vec![LineSegment::new_with_color( + "Any key to close", + DisplayColor::IndicatorColor, + )])); + + Self { view_data } + } + + pub fn new_from_view_data(keybindings: Option<&[(&str, &str)]>, view_data: Option<ViewData>) -> Self { + if let Some(k) = keybindings { + Self::new_from_keybindings_descriptions(k) + } + else if let Some(view_data) = view_data { + Self { view_data } + } + else { + let mut view_data = ViewData::new(); + view_data.set_content(ViewLine::new(vec![LineSegment::new("Help not available")])); + Self { view_data } + } + } + + pub fn get_view_data(&mut self, view: &View<'_>) -> &ViewData { + let (view_width, view_height) = view.get_view_size(); + self.view_data.set_view_size(view_width, view_height); + self.view_data.rebuild(); + &self.view_data + } + + pub fn handle_input(&mut self, input_handler: &InputHandler<'_>, view: &View<'_>) -> HandleInputResult { + let input = input_handler.get_input(InputMode::Default); + match input { + Input::MoveCursorLeft => self.view_data.scroll_left(), + Input::MoveCursorRight => self.view_data.scroll_right(), + Input::MoveCursorDown => self.view_data.scroll_down(), + Input::MoveCursorUp => self.view_data.scroll_up(), + Input::MoveCursorPageDown => self.view_data.page_down(), + Input::MoveCursorPageUp => self.view_data.page_up(), + Input::Resize => { + let (view_width, view_height) = view.get_view_size(); + self.view_data.set_view_size(view_width, view_height); + }, + _ => return HandleInputResult::new(Input::Help), + } + HandleInputResult::new(input) + } +} |