From a6f3eb034de7fa41fdf64b6cc499bbfdd2106622 Mon Sep 17 00:00:00 2001 From: Tobias Clasen Date: Tue, 26 Nov 2024 09:40:57 +0000 Subject: [PATCH] feat: allow variable width * Added the feature described in issue #44 * Update components.rs with a comment --- src/main.rs | 4 ++++ src/player/ui.rs | 29 +++++++++++++++++------------ src/player/ui/components.rs | 9 ++++++++- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/main.rs b/src/main.rs index 92aab0d..a2cc896 100644 --- a/src/main.rs +++ b/src/main.rs @@ -67,6 +67,10 @@ struct Args { #[clap(long, short)] debug: bool, + /// The width of the player + #[clap(long, short)] + width: Option, + /// This is either a path, or a name of a file in the data directory (eg. ~/.local/share/lowfi). #[clap(long, short, alias = "list", short_alias = 'l')] tracks: Option, diff --git a/src/player/ui.rs b/src/player/ui.rs index a084a60..8711320 100644 --- a/src/player/ui.rs +++ b/src/player/ui.rs @@ -27,8 +27,8 @@ use super::{Messages, Player}; mod components; mod input; -/// The total width of the UI. -const WIDTH: usize = 27; +/// The default total width of the UI. +const DEFAULT_WIDTH: usize = 27; /// Self explanitory. const FPS: usize = 12; @@ -66,12 +66,12 @@ pub struct Window { impl Window { /// Initializes a new [Window]. - pub fn new() -> Self { + pub fn new(width: usize) -> Self { Self { borders: [ - format!("┌{}┐\r\n", "─".repeat(WIDTH + 2)), + format!("┌{}┐\r\n", "─".repeat(width + 2)), // This one doesn't have a leading \r\n to avoid extra space under the window. - format!("└{}┘", "─".repeat(WIDTH + 2)), + format!("└{}┘", "─".repeat(width + 2)), ], out: stdout(), } @@ -119,8 +119,9 @@ impl Window { /// The code for the terminal interface itself. /// /// * `minimalist` - All this does is hide the bottom control bar. -async fn interface(player: Arc, minimalist: bool) -> eyre::Result<()> { - let mut window = Window::new(); +/// * `width` - The width of player +async fn interface(player: Arc, minimalist: bool, width: usize) -> eyre::Result<()> { + let mut window = Window::new(width); loop { // Load `current` once so that it doesn't have to be loaded over and over @@ -128,15 +129,15 @@ async fn interface(player: Arc, minimalist: bool) -> eyre::Result<()> { let current = player.current.load(); let current = current.as_ref(); - let action = components::action(&player, current, WIDTH); + let action = components::action(&player, current, width); let volume = player.sink.volume(); let percentage = format!("{}%", (volume * 100.0).round().abs()); let timer = VOLUME_TIMER.load(Ordering::Relaxed); let middle = match timer { - 0 => components::progress_bar(&player, current, WIDTH - 16), - _ => components::audio_bar(volume, &percentage, WIDTH - 17), + 0 => components::progress_bar(&player, current, width - 16), + _ => components::audio_bar(volume, &percentage, width - 17), }; if timer > 0 && timer <= AUDIO_BAR_DURATION { @@ -147,7 +148,7 @@ async fn interface(player: Arc, minimalist: bool) -> eyre::Result<()> { VOLUME_TIMER.store(0, Ordering::Relaxed); } - let controls = components::controls(WIDTH); + let controls = components::controls(width); let menu = if minimalist { vec![action, middle] @@ -236,7 +237,11 @@ impl Drop for Environment { /// previous terminal history. pub async fn start(player: Arc, sender: Sender, args: Args) -> eyre::Result<()> { let environment = Environment::ready(args.alternate)?; - let interface = task::spawn(interface(Arc::clone(&player), args.minimalist)); + let interface = task::spawn(interface( + Arc::clone(&player), + args.minimalist, + args.width.unwrap_or(DEFAULT_WIDTH).max(21), + )); input::listen(sender.clone()).await?; interface.abort(); diff --git a/src/player/ui/components.rs b/src/player/ui/components.rs index 015cc16..ecfb77a 100644 --- a/src/player/ui/components.rs +++ b/src/player/ui/components.rs @@ -116,5 +116,12 @@ pub fn controls(width: usize) -> String { let len: usize = controls.concat().iter().map(|x| x.len()).sum(); let controls = controls.map(|x| format!("{}{}", x[0].bold(), x[1])); - controls.join(&" ".repeat((width - len) / (controls.len() - 1))) + let mut controls = controls.join(&" ".repeat((width - len) / (controls.len() - 1))); + // This is needed because changing the above line + // only works for when the width is even + controls.push_str(match width % 2 { + 0 => " ", + _ => "", + }); + controls }