add initial help screen + keybinding -> command parsing
still needs some more work, i.e. to show commands in help instead of parsed data structures, but it's a start. fixes #117 fixes #121
This commit is contained in:
@@ -60,6 +60,7 @@ the `portaudio_backend` feature:
|
||||
These keybindings are hardcoded for now. In the future it may be desirable to
|
||||
have them configurable.
|
||||
|
||||
* `?` show help screen
|
||||
* Navigate through the screens using the F-keys:
|
||||
* `F1`: Queue
|
||||
* `c` clears the entire queue
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use command::{Command, GotoMode, MoveMode, SeekDirection, ShiftMode, TargetMode};
|
||||
use command::{parse, Command, GotoMode, MoveMode, SeekDirection, ShiftMode, TargetMode};
|
||||
use cursive::event::{Event, Key};
|
||||
use cursive::traits::View;
|
||||
use cursive::views::ViewRef;
|
||||
@@ -33,10 +33,18 @@ impl CommandManager {
|
||||
spotify: Arc<Spotify>,
|
||||
queue: Arc<Queue>,
|
||||
library: Arc<Library>,
|
||||
bindings: Option<HashMap<String, Command>>,
|
||||
bindings: Option<HashMap<String, String>>,
|
||||
) -> CommandManager {
|
||||
let mut kb = Self::default_keybindings();
|
||||
kb.extend(bindings.unwrap_or_default());
|
||||
|
||||
for (key, command) in bindings.unwrap_or_default() {
|
||||
if let Some(command) = parse(&command) {
|
||||
info!("Custom keybinding: {} -> {:?}", key, command);
|
||||
kb.insert(key, command);
|
||||
} else {
|
||||
error!("Invalid command for key {}: {}", key, command);
|
||||
}
|
||||
}
|
||||
|
||||
CommandManager {
|
||||
aliases: HashMap::new(),
|
||||
@@ -240,6 +248,7 @@ impl CommandManager {
|
||||
kb.insert("F1".into(), Command::Focus("queue".into()));
|
||||
kb.insert("F2".into(), Command::Focus("search".into()));
|
||||
kb.insert("F3".into(), Command::Focus("library".into()));
|
||||
kb.insert("?".into(), Command::Focus("help".into()));
|
||||
kb.insert("Backspace".into(), Command::Back);
|
||||
|
||||
kb.insert("o".into(), Command::Open(TargetMode::Selected));
|
||||
|
||||
@@ -10,7 +10,7 @@ pub const CLIENT_ID: &str = "d420a117a32841c2b3474932e49fb54b";
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, Default)]
|
||||
pub struct Config {
|
||||
pub keybindings: Option<HashMap<String, Command>>,
|
||||
pub keybindings: Option<HashMap<String, String>>,
|
||||
pub theme: Option<ConfigTheme>,
|
||||
pub use_nerdfont: Option<bool>,
|
||||
pub proxy: Option<String>,
|
||||
|
||||
@@ -214,6 +214,8 @@ fn main() {
|
||||
|
||||
let queueview = ui::queue::QueueView::new(queue.clone(), library.clone());
|
||||
|
||||
let helpview = ui::help::HelpView::new(cmd_manager.keybindings().clone());
|
||||
|
||||
let status = ui::statusbar::StatusBar::new(
|
||||
queue.clone(),
|
||||
library.clone(),
|
||||
@@ -223,7 +225,8 @@ fn main() {
|
||||
let mut layout = ui::layout::Layout::new(status, &event_manager, theme)
|
||||
.view("search", search.with_name("search"), "Search")
|
||||
.view("library", libraryview.with_name("library"), "Library")
|
||||
.view("queue", queueview, "Queue");
|
||||
.view("queue", queueview, "Queue")
|
||||
.view("help", helpview, "Help");
|
||||
|
||||
// initial view is library
|
||||
layout.set_view("library");
|
||||
|
||||
45
src/ui/help.rs
Normal file
45
src/ui/help.rs
Normal file
@@ -0,0 +1,45 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use cursive::theme::Effect;
|
||||
use cursive::utils::markup::StyledString;
|
||||
use cursive::view::ViewWrapper;
|
||||
use cursive::views::{ScrollView, TextView};
|
||||
|
||||
use command::Command;
|
||||
use config::config_path;
|
||||
use traits::ViewExt;
|
||||
|
||||
pub struct HelpView {
|
||||
view: ScrollView<TextView>,
|
||||
}
|
||||
|
||||
impl HelpView {
|
||||
pub fn new(bindings: HashMap<String, Command>) -> 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 = serde_json::to_string(&bindings[key]).unwrap_or_default();
|
||||
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<TextView>);
|
||||
}
|
||||
|
||||
impl ViewExt for HelpView {}
|
||||
@@ -1,6 +1,7 @@
|
||||
pub mod album;
|
||||
pub mod artist;
|
||||
pub mod contextmenu;
|
||||
pub mod help;
|
||||
pub mod layout;
|
||||
pub mod library;
|
||||
pub mod listview;
|
||||
|
||||
Reference in New Issue
Block a user