summaryrefslogtreecommitdiffstats
path: root/src/process/help.rs
diff options
context:
space:
mode:
authorTim Oram <dev@mitmaro.ca>2020-08-04 23:59:29 -0230
committerTim Oram <dev@mitmaro.ca>2020-09-02 14:51:24 -0230
commit04c8b0e1c5f4a00c4613e83fe9308b5c33e72a1c (patch)
tree9953b41bfd4bbcb7e47667f59c4a9e39d0bedc53 /src/process/help.rs
parentc28186e99730f82bac3ada8d729825e285752371 (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.rs104
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)
+ }
+}