diff --git a/README.md b/README.md index 43fd2cb0b..5bfc8a75f 100644 --- a/README.md +++ b/README.md @@ -330,6 +330,7 @@ Note: \ - mandatory arg; [BAR] - optional arg | `playpause`
Aliases: `pause`, `toggleplay`, `toggleplayback` | Toggle playback. | | `stop` | Stop playback. | | `seek` [`+`\|`-`]\ | Seek to the specified position, or seek relative to current position by prepending `+`/`-`.
\* TIME is anything accepted by [parse_duration](https://docs.rs/parse_duration/latest/parse_duration/)
\* Default unit is `ms` for backward compatibility. | +| `move` \ \ | Scroll the current view `up`/`down`/`left`/`right` with integer step sizes, or `pageup`/`pagedown`/`pageleft`/`pageright` with float step sizes. | `repeat` [REPEAT_MODE]
Alias: `loop` | Set repeat mode. Omit argument to step through the available modes.
\* Valid values for REPEAT_MODE: `list` (aliases: `playlist`, `queue`), `track` (aliases: `once`, `single`), `none` (alias: `off`) | | `shuffle` [`on`\|`off`] | Enable or disable shuffle. Omit argument to toggle. | | `previous` | Play the previous track. | diff --git a/src/command.rs b/src/command.rs index eec0ef2af..64c70a960 100644 --- a/src/command.rs +++ b/src/command.rs @@ -33,6 +33,7 @@ pub enum MoveMode { #[strum(serialize_all = "lowercase")] pub enum MoveAmount { Integer(i32), + Float(f32), Extreme, } @@ -186,6 +187,7 @@ impl fmt::Display for Command { (MoveMode::Down, MoveAmount::Extreme) => vec!["bottom".to_string()], (MoveMode::Left, MoveAmount::Extreme) => vec!["leftmost".to_string()], (MoveMode::Right, MoveAmount::Extreme) => vec!["rightmost".to_string()], + (mode, MoveAmount::Float(amount)) => vec![mode.to_string(), amount.to_string()], (mode, MoveAmount::Integer(amount)) => vec![mode.to_string(), amount.to_string()], }, Command::Shift(mode, amount) => vec![mode.to_string(), amount.unwrap_or(1).to_string()], @@ -562,10 +564,10 @@ pub fn parse(input: &str) -> Result, CommandParseError> { use MoveMode::*; match move_mode_raw { "playing" => Ok(Playing), - "top" | "up" => Ok(Up), - "bottom" | "down" => Ok(Down), - "leftmost" | "left" => Ok(Left), - "rightmost" | "right" => Ok(Right), + "top" | "pageup" | "up" => Ok(Up), + "bottom" | "pagedown" | "down" => Ok(Down), + "leftmost" | "pageleft" | "left" => Ok(Left), + "rightmost" | "pageright" | "right" => Ok(Right), _ => Err(BadEnumArg { arg: move_mode_raw.into(), accept: vec![ @@ -574,6 +576,10 @@ pub fn parse(input: &str) -> Result, CommandParseError> { "bottom".into(), "leftmost".into(), "rightmost".into(), + "pageup".into(), + "pagedown".into(), + "pageleft".into(), + "pageright".into(), "up".into(), "down".into(), "left".into(), @@ -585,6 +591,19 @@ pub fn parse(input: &str) -> Result, CommandParseError> { let move_amount = match move_mode_raw { "playing" => Ok(MoveAmount::default()), "top" | "bottom" | "leftmost" | "rightmost" => Ok(MoveAmount::Extreme), + "pageup" | "pagedown" | "pageleft" | "pageright" => { + let amount = match args.get(1) { + Some(&amount_raw) => amount_raw + .parse::() + .map(MoveAmount::Float) + .map_err(|err| ArgParseError { + arg: amount_raw.into(), + err: err.to_string(), + })?, + None => MoveAmount::default(), + }; + Ok(amount) + } "up" | "down" | "left" | "right" => { let amount = match args.get(1) { Some(&amount_raw) => amount_raw diff --git a/src/ext_traits.rs b/src/ext_traits.rs index 175d1d712..e417d9a7b 100644 --- a/src/ext_traits.rs +++ b/src/ext_traits.rs @@ -1,4 +1,5 @@ use cursive::views::ViewRef; +use cursive::{View, XY}; use crate::command::{Command, MoveAmount, MoveMode}; use crate::commands::CommandResult; @@ -37,6 +38,10 @@ impl SelectViewExt for cursive::views::SelectView { MoveMode::Up => { match amount { MoveAmount::Extreme => self.set_selection(0), + MoveAmount::Float(scale) => { + let amount = (*self).required_size(XY::default()).y as f32 * scale; + self.select_up(amount as usize) + } MoveAmount::Integer(amount) => self.select_up(*amount as usize), }; Ok(CommandResult::Consumed(None)) @@ -44,6 +49,10 @@ impl SelectViewExt for cursive::views::SelectView { MoveMode::Down => { match amount { MoveAmount::Extreme => self.set_selection(items), + MoveAmount::Float(scale) => { + let amount = (*self).required_size(XY::default()).y as f32 * scale; + self.select_down(amount as usize) + } MoveAmount::Integer(amount) => self.select_down(*amount as usize), }; Ok(CommandResult::Consumed(None)) diff --git a/src/ui/help.rs b/src/ui/help.rs index c8d51b3ad..c6015d9f6 100644 --- a/src/ui/help.rs +++ b/src/ui/help.rs @@ -70,6 +70,11 @@ impl ViewExt for HelpView { MoveAmount::Extreme => { self.view.scroll_to_top(); } + MoveAmount::Float(scale) => { + let amount = (viewport.height() as f32) * scale; + scroller + .scroll_to_y(viewport.top().saturating_sub(amount as usize)); + } MoveAmount::Integer(amount) => scroller .scroll_to_y(viewport.top().saturating_sub(*amount as usize)), }; @@ -80,6 +85,11 @@ impl ViewExt for HelpView { MoveAmount::Extreme => { self.view.scroll_to_bottom(); } + MoveAmount::Float(scale) => { + let amount = (viewport.height() as f32) * scale; + scroller + .scroll_to_y(viewport.bottom().saturating_add(amount as usize)); + } MoveAmount::Integer(amount) => scroller .scroll_to_y(viewport.bottom().saturating_add(*amount as usize)), }; diff --git a/src/ui/listview.rs b/src/ui/listview.rs index 437ac3197..304790d25 100644 --- a/src/ui/listview.rs +++ b/src/ui/listview.rs @@ -542,6 +542,10 @@ impl ViewExt for ListView { if self.selected > 0 { match amount { MoveAmount::Extreme => self.move_focus_to(0), + MoveAmount::Float(scale) => { + let amount = (self.last_size.y as f32) * scale; + self.move_focus(-(amount as i32)) + } MoveAmount::Integer(amount) => self.move_focus(-(*amount)), } } @@ -551,6 +555,10 @@ impl ViewExt for ListView { if self.selected < last_idx { match amount { MoveAmount::Extreme => self.move_focus_to(last_idx), + MoveAmount::Float(scale) => { + let amount = (self.last_size.y as f32) * scale; + self.move_focus(amount as i32) + } MoveAmount::Integer(amount) => self.move_focus(*amount), } } diff --git a/src/ui/tabview.rs b/src/ui/tabview.rs index 7661228f4..14313086f 100644 --- a/src/ui/tabview.rs +++ b/src/ui/tabview.rs @@ -144,6 +144,7 @@ impl ViewExt for TabView { match amount { MoveAmount::Extreme => self.move_focus_to(0), MoveAmount::Integer(amount) => self.move_focus(-(*amount)), + _ => (), } return Ok(CommandResult::Consumed(None)); } @@ -151,6 +152,7 @@ impl ViewExt for TabView { match amount { MoveAmount::Extreme => self.move_focus_to(last_idx), MoveAmount::Integer(amount) => self.move_focus(*amount), + _ => (), } return Ok(CommandResult::Consumed(None)); }