fum-player 1.3.1

A tui-based mpris music client.
use ratatui::{buffer::Buffer, layout::{Constraint, Layout, Rect}, style::Stylize, widgets::{Block, Paragraph, Widget, Wrap}};

use crate::{get_color, state::FumState};

use super::{Direction, FumWidget, SliderSource};

struct Volume {
    volume_bar: String,
    empty_bar: String,
    volume_area: Rect,
    empty_area: Rect
}

pub fn render(widget: &FumWidget, area: Rect, buf: &mut Buffer, state: &mut FumState) {
    if let FumWidget::Volume { id, direction, volume: vol_opt, empty: empt_opt, .. } = widget {
        let (vol_bg, vol_fg) = get_color!(&vol_opt.bg, &vol_opt.fg, &state.parent_bg, &state.parent_fg);
        let (empt_bg, empt_fg) = get_color!(&empt_opt.bg, &empt_opt.fg, &state.parent_bg, &state.parent_fg);

        let progress_char = vol_opt.char.to_string();
        let empty_char = empt_opt.char.to_string();

        state.sliders.insert(
            id.to_string(),
            (area.clone(), direction.clone(), SliderSource::Volume)
        );

        let Volume {
            volume_bar,
            empty_bar,
            volume_area,
            empty_area
        } = match direction {
            Direction::Horizontal => {
                let filled = (state.meta.volume * area.width as f64).round();
                let empty = area.width.saturating_sub(filled as u16);

                let volume_bar = progress_char.repeat(filled as usize);
                let empty_bar = empty_char.repeat(empty as usize);

                let [volume_area, empty_area] = Layout::horizontal([
                    Constraint::Length(filled as u16),
                    Constraint::Length(empty as u16)
                ]).areas(area);

                Volume {
                    volume_bar,
                    empty_bar,
                    volume_area,
                    empty_area
                }
            },
            Direction::Vertical => {
                let filled = (state.meta.volume * area.height as f64).round();
                let empty = area.height.saturating_sub(filled as u16);

                let volume_bar = progress_char.repeat(filled as usize);
                let empty_bar = empty_char.repeat(empty as usize);

                let [empty_area, volume_area] = Layout::vertical([
                    Constraint::Length(empty as u16),
                    Constraint::Length(filled as u16)
                ]).areas(area);

                Volume {
                    volume_bar,
                    empty_bar,
                    volume_area,
                    empty_area
                }
            }
        };

        // Render volume filled bg
        Block::new()
            .bg(*vol_bg)
            .render(volume_area, buf);

        // Render volume filled
        Paragraph::new(volume_bar)
            .wrap(Wrap::default())
            .fg(*vol_fg)
            .render(volume_area, buf);

        // Render empty bg
        Block::new()
            .bg(*empt_bg)
            .render(empty_area, buf);

        // Render empty
        Paragraph::new(empty_bar)
            .wrap(Wrap::default())
            .fg(*empt_fg)
            .render(empty_area, buf);
    }
}