From 5fefe9eec3fdda7e9e3df44e4d9a8de9ccf47124 Mon Sep 17 00:00:00 2001 From: JojiiOfficial Date: Sun, 13 Dec 2020 20:41:22 +0100 Subject: [PATCH] Add hjkl controls for AddToPlaylistMenu (#335) * Add hjkl controls for AddToPlaylistMenu * turn off autojump in contextmenu for vim bindings Co-authored-by: Henrik Friedrichsen --- src/commands.rs | 12 +++-- src/playlist.rs | 4 +- src/ui/contextmenu.rs | 105 +++++++++++++++++++++++++----------------- 3 files changed, 73 insertions(+), 48 deletions(-) diff --git a/src/commands.rs b/src/commands.rs index 09c3fb3..b232b60 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -2,9 +2,6 @@ use std::collections::HashMap; use std::sync::Arc; use std::time::Duration; -use crate::command::{ - parse, Command, GotoMode, JumpMode, MoveAmount, MoveMode, SeekDirection, ShiftMode, TargetMode, -}; use crate::config::Config; use crate::library::Library; use crate::queue::{Queue, RepeatSetting}; @@ -14,6 +11,13 @@ use crate::ui::contextmenu::ContextMenu; use crate::ui::help::HelpView; use crate::ui::layout::Layout; use crate::UserData; +use crate::{ + command::{ + parse, Command, GotoMode, JumpMode, MoveAmount, MoveMode, SeekDirection, ShiftMode, + TargetMode, + }, + ui::contextmenu::AddToPlaylistMenu, +}; use cursive::event::{Event, Key}; use cursive::traits::View; use cursive::Cursive; @@ -211,6 +215,8 @@ impl CommandManager { fn handle_callbacks(&self, s: &mut Cursive, cmd: &Command) -> Result, String> { let local = if let Some(mut contextmenu) = s.find_name::("contextmenu") { contextmenu.on_command(s, cmd)? + } else if let Some(mut add_track_menu) = s.find_name::("addtrackmenu") { + add_track_menu.on_command(s, cmd)? } else { let mut main = s .find_name::("main") diff --git a/src/playlist.rs b/src/playlist.rs index 81bf32a..ccb1bd5 100644 --- a/src/playlist.rs +++ b/src/playlist.rs @@ -19,7 +19,7 @@ pub struct Playlist { pub snapshot_id: String, pub num_tracks: usize, pub tracks: Option>, - pub collaborative: bool + pub collaborative: bool, } impl Playlist { @@ -143,7 +143,7 @@ impl From<&FullPlaylist> for Playlist { snapshot_id: list.snapshot_id.clone(), num_tracks: list.tracks.total as usize, tracks: None, - collaborative: list.collaborative + collaborative: list.collaborative, } } } diff --git a/src/ui/contextmenu.rs b/src/ui/contextmenu.rs index 1fa0cd4..f3bc26c 100644 --- a/src/ui/contextmenu.rs +++ b/src/ui/contextmenu.rs @@ -6,10 +6,10 @@ use cursive::Cursive; use crate::commands::CommandResult; use crate::library::Library; +use crate::playable::Playable; use crate::queue::Queue; use crate::track::Track; use crate::traits::{ListItem, ViewExt}; -use crate::playable::Playable; use crate::ui::layout::Layout; use crate::ui::modal::Modal; use crate::{ @@ -25,6 +25,10 @@ pub struct ContextMenu { dialog: Modal, } +pub struct AddToPlaylistMenu { + dialog: Modal, +} + enum ContextMenuAction { ShowItem(Box), ShareUrl(String), @@ -38,8 +42,8 @@ impl ContextMenu { library: Arc, spotify: Arc, track: Track, - ) -> Modal { - let mut list_select: SelectView = SelectView::new().autojump(); + ) -> NamedView { + let mut list_select: SelectView = SelectView::new(); let current_user_id = library.user_id.as_ref().unwrap(); for list in library.items().iter() { @@ -82,8 +86,12 @@ impl ContextMenu { .title("Add track to playlist") .dismiss_button("Cancel") .padding(Margins::lrtb(1, 1, 1, 0)) - .content(ScrollView::new(list_select)); - Modal::new(dialog) + .content(ScrollView::new(list_select.with_name("addplaylist_select"))); + + AddToPlaylistMenu { + dialog: Modal::new_ext(dialog), + } + .with_name("addtrackmenu") } fn track_already_added() -> Dialog { @@ -94,7 +102,7 @@ impl ContextMenu { } pub fn new(item: &dyn ListItem, queue: Arc, library: Arc) -> NamedView { - let mut content: SelectView = SelectView::new().autojump(); + let mut content: SelectView = SelectView::new(); if let Some(a) = item.artist() { content.add_item("Show artist", ContextMenuAction::ShowItem(Box::new(a))); } @@ -170,48 +178,59 @@ impl ContextMenu { } } +impl ViewExt for AddToPlaylistMenu { + fn on_command(&mut self, s: &mut Cursive, cmd: &Command) -> Result { + handle_move_command::(&mut self.dialog, s, cmd, "addplaylist_select") + } +} + impl ViewExt for ContextMenu { fn on_command(&mut self, s: &mut Cursive, cmd: &Command) -> Result { - match cmd { - Command::Back => { - s.pop_layer(); - Ok(CommandResult::Consumed(None)) - } - Command::Move(mode, amount) => self - .dialog - .call_on_name( - "contextmenu_select", - |select: &mut SelectView| { - let items = select.len(); - match mode { - MoveMode::Up => { - match amount { - MoveAmount::Extreme => select.set_selection(0), - MoveAmount::Integer(amount) => { - select.select_up(*amount as usize) - } - }; - Ok(CommandResult::Consumed(None)) - } - MoveMode::Down => { - match amount { - MoveAmount::Extreme => select.set_selection(items), - MoveAmount::Integer(amount) => { - select.select_down(*amount as usize) - } - }; - Ok(CommandResult::Consumed(None)) - } - _ => Ok(CommandResult::Consumed(None)), - } - }, - ) - .unwrap_or(Ok(CommandResult::Consumed(None))), - _ => Ok(CommandResult::Consumed(None)), - } + handle_move_command::(&mut self.dialog, s, cmd, "contextmenu_select") } } +fn handle_move_command( + sel: &mut Modal, + s: &mut Cursive, + cmd: &Command, + name: &str, +) -> Result { + match cmd { + Command::Back => { + s.pop_layer(); + Ok(CommandResult::Consumed(None)) + } + Command::Move(mode, amount) => sel + .call_on_name(name, |select: &mut SelectView| { + let items = select.len(); + match mode { + MoveMode::Up => { + match amount { + MoveAmount::Extreme => select.set_selection(0), + MoveAmount::Integer(amount) => select.select_up(*amount as usize), + }; + Ok(CommandResult::Consumed(None)) + } + MoveMode::Down => { + match amount { + MoveAmount::Extreme => select.set_selection(items), + MoveAmount::Integer(amount) => select.select_down(*amount as usize), + }; + Ok(CommandResult::Consumed(None)) + } + _ => Ok(CommandResult::Consumed(None)), + } + }) + .unwrap_or(Ok(CommandResult::Consumed(None))), + _ => Ok(CommandResult::Consumed(None)), + } +} + +impl ViewWrapper for AddToPlaylistMenu { + wrap_impl!(self.dialog: Modal); +} + impl ViewWrapper for ContextMenu { wrap_impl!(self.dialog: Modal); }