use std::collections::HashMap; use cursive::theme::Effect; use cursive::utils::markup::StyledString; use cursive::view::ViewWrapper; use cursive::views::{ScrollView, TextView}; use cursive::Cursive; use crate::command::{Command, MoveAmount, MoveMode}; use crate::commands::CommandResult; use crate::config::config_path; use crate::traits::ViewExt; use cursive::view::scroll::Scroller; pub struct HelpView { view: ScrollView, } impl HelpView { pub fn new(bindings: HashMap) -> HelpView { let mut text = StyledString::styled("Keybindings\n\n", Effect::Bold); let note = format!( "Custom bindings can be set in {} within the [keybindings] section.\n\n", config_path("config.toml").to_str().unwrap_or_default() ); text.append(StyledString::styled(note, Effect::Italic)); let mut keys: Vec<&String> = bindings.keys().collect(); keys.sort(); for key in keys { let command = &bindings[key]; let binding = format!("{} -> {}\n", key, command); text.append(binding); } HelpView { view: ScrollView::new(TextView::new(text)), } } } impl ViewWrapper for HelpView { wrap_impl!(self.view: ScrollView); } impl ViewExt for HelpView { fn title(&self) -> String { "Help".to_string() } fn on_command(&mut self, _s: &mut Cursive, cmd: &Command) -> Result { match cmd { Command::Help => Ok(CommandResult::Consumed(None)), Command::Move(mode, amount) => { let scroller = self.view.get_scroller_mut(); let viewport = scroller.content_viewport(); match mode { MoveMode::Up => { match amount { MoveAmount::Extreme => { self.view.scroll_to_top(); } MoveAmount::Integer(amount) => scroller .scroll_to_y(viewport.top().saturating_sub(*amount as usize)), }; Ok(CommandResult::Consumed(None)) } MoveMode::Down => { match amount { MoveAmount::Extreme => { self.view.scroll_to_bottom(); } MoveAmount::Integer(amount) => scroller .scroll_to_y(viewport.bottom().saturating_add(*amount as usize)), }; Ok(CommandResult::Consumed(None)) } _ => Ok(CommandResult::Consumed(None)), } } _ => Ok(CommandResult::Ignored), } } }