summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSam Tay <sam.chong.tay@gmail.com>2020-06-28 18:04:54 -0700
committerSam Tay <sam.chong.tay@gmail.com>2020-06-28 18:07:46 -0700
commit8b5c16b8a09f8f778036ebd2a0329243ad0edd77 (patch)
treecbf98631d88143c205c14c278fbb01b8d6c82b96 /src
parentf23602053eb04b31a715f3cc6acb471acced11c1 (diff)
Add a key-bindings help popup
Diffstat (limited to 'src')
-rw-r--r--src/tui/app.rs44
-rw-r--r--src/tui/views.rs1
2 files changed, 43 insertions, 2 deletions
diff --git a/src/tui/app.rs b/src/tui/app.rs
index 06ac090..023955f 100644
--- a/src/tui/app.rs
+++ b/src/tui/app.rs
@@ -1,7 +1,9 @@
use cursive::event::Event;
use cursive::theme::{BaseColor, Color, Effect, Style};
+use cursive::traits::{Nameable, Scrollable};
use cursive::utils::markup::StyledString;
use cursive::utils::span::SpannedString;
+use cursive::views::{Dialog, TextView};
use cursive::Cursive;
use cursive::XY;
use std::collections::HashMap;
@@ -17,6 +19,8 @@ use crate::config;
use crate::error::Result;
use crate::stackexchange::{Answer, Question};
+pub const NAME_HELP_VIEW: &str = "help_view";
+
pub fn run(qs: Vec<Question<Markdown>>) -> Result<()> {
let mut siv = cursive::default();
siv.load_theme_file(config::theme_file_name()?).unwrap(); // TODO dont unwrap
@@ -61,8 +65,16 @@ pub fn run(qs: Vec<Question<Markdown>>) -> Result<()> {
if let Some(cb) = cb {
cb(&mut siv)
}
- cursive::logger::init();
- siv.add_global_callback('?', cursive::Cursive::toggle_debug_console);
+
+ // Help / View keymappings
+ siv.add_global_callback('?', |s| {
+ if let Some(pos) = s.screen_mut().find_layer_from_name(NAME_HELP_VIEW) {
+ s.screen_mut().remove_layer(pos);
+ } else {
+ s.add_layer(help());
+ }
+ });
+ // Reload theme
siv.add_global_callback(Event::CtrlChar('r'), |s| {
s.load_theme_file(config::theme_file_name().unwrap())
.unwrap()
@@ -127,5 +139,33 @@ fn pretty_score(score: i32) -> StyledString {
)
}
+// This would be a good usecase for brining in termimad tables
+// TODO dont parse this at runtime, just hardcode it
+pub fn help() -> Dialog {
+ let bindings = r###"
+## Panes
+**Tab**: Focus next pane
+**Space**: Cycle layout (4 Pane, 2 Pane, FullScreen)
+
+## Scroll
+**h,j,k,l**: ←,↓,↑,→
+**Ctrl<b>, Ctrl<u>**: ↑ x 10
+**Ctrl<f>, Ctrl<d>**: ↓ x 10
+**gg**: Scroll To Top
+**G**: Scroll To Bottom
+
+## Misc
+**ZZ, Ctrl<c>**: Exit
+**?**: Toggle this help menu
+"###;
+ Dialog::around(
+ TextView::new(markdown::parse(bindings))
+ .scrollable()
+ .with_name(NAME_HELP_VIEW),
+ )
+ .dismiss_button("Close")
+ .title("Help")
+}
+
// TODO see cursive/examples/src/bin/select_test.rs for how to test the interface!
// maybe see if we can conditionally run when --nocapture is passed?
diff --git a/src/tui/views.rs b/src/tui/views.rs
index 2e2fc4d..3dc12a8 100644
--- a/src/tui/views.rs
+++ b/src/tui/views.rs
@@ -20,6 +20,7 @@ pub const NAME_QUESTION_VIEW: &str = "question_view";
pub const NAME_ANSWER_VIEW: &str = "answer_view";
pub const NAME_FULL_LAYOUT: &str = "full_layout";
+// TODO this seems pointless; probably should be removed
pub enum Name {
QuestionList,
AnswerList,