feat: allow variable width

* Added the feature described in issue #44

* Update components.rs with a comment
This commit is contained in:
Tobias Clasen 2024-11-26 09:40:57 +00:00 committed by GitHub
parent 5f0f78f0e6
commit a6f3eb034d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 29 additions and 13 deletions

View File

@ -67,6 +67,10 @@ struct Args {
#[clap(long, short)]
debug: bool,
/// The width of the player
#[clap(long, short)]
width: Option<usize>,
/// 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<String>,

View File

@ -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<Player>, minimalist: bool) -> eyre::Result<()> {
let mut window = Window::new();
/// * `width` - The width of player
async fn interface(player: Arc<Player>, 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<Player>, 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<Player>, 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<Player>, sender: Sender<Messages>, 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();

View File

@ -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
}