diff --git a/src/config.rs b/src/config.rs index 795ca54..1af105d 100644 --- a/src/config.rs +++ b/src/config.rs @@ -6,40 +6,27 @@ use tui::style::Color; use std::{ fmt::{self, Formatter}, - net::{IpAddr, Ipv4Addr, SocketAddr}, + net::SocketAddr, }; +use crate::defaults; + #[derive(Deserialize)] pub struct Config { - #[serde(default = "address_default")] + #[serde(default = "defaults::address")] pub address: SocketAddr, #[serde(default)] pub cycle: bool, - #[serde(default = "jump_lines_default")] + #[serde(default = "defaults::jump_lines")] pub jump_lines: usize, - #[serde(default = "seek_secs_default")] + #[serde(default = "defaults::seek_secs")] pub seek_secs: f64, - #[serde(default = "ups_default")] + #[serde(default = "defaults::ups")] pub ups: f64, + #[serde(default = "defaults::layout")] pub layout: Widget, } -fn address_default() -> SocketAddr { - SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 6600) -} - -fn jump_lines_default() -> usize { - 24 -} - -fn seek_secs_default() -> f64 { - 5.0 -} - -fn ups_default() -> f64 { - 1.0 -} - #[derive(Deserialize)] pub enum Widget { Rows(Vec>), diff --git a/src/defaults.rs b/src/defaults.rs new file mode 100644 index 0000000..5f7b9e7 --- /dev/null +++ b/src/defaults.rs @@ -0,0 +1,219 @@ +use tui::style::Color; + +use std::net::{IpAddr, Ipv4Addr, SocketAddr}; + +use crate::config::{AddStyle, Column, Condition, Config, Constrained, Texts, Widget}; + +pub fn config() -> Config { + Config { + cycle: false, + address: address(), + jump_lines: jump_lines(), + seek_secs: seek_secs(), + ups: ups(), + layout: layout(), + } +} + +pub fn address() -> SocketAddr { + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 6600) +} + +pub fn jump_lines() -> usize { + 24 +} + +pub fn seek_secs() -> f64 { + 5.0 +} + +pub fn ups() -> f64 { + 1.0 +} + +pub fn layout() -> Widget { + Widget::Rows(vec![ + Constrained::Fixed( + 1, + Widget::Columns(vec![ + Constrained::Ratio( + 12, + Widget::Textbox(Texts::Styled( + vec![AddStyle::Fg(Color::Indexed(122)), AddStyle::Bold], + Box::new(Texts::Text(String::from("Title"))), + )), + ), + Constrained::Ratio( + 10, + Widget::Textbox(Texts::Styled( + vec![AddStyle::Fg(Color::Indexed(158)), AddStyle::Bold], + Box::new(Texts::Text(String::from("Artist"))), + )), + ), + Constrained::Ratio( + 10, + Widget::Textbox(Texts::Styled( + vec![AddStyle::Fg(Color::Indexed(194)), AddStyle::Bold], + Box::new(Texts::Text(String::from("Album"))), + )), + ), + Constrained::Ratio( + 1, + Widget::Textbox(Texts::Styled( + vec![AddStyle::Fg(Color::Indexed(230)), AddStyle::Bold], + Box::new(Texts::Text(String::from("Time"))), + )), + ), + ]), + ), + Constrained::Min( + 0, + Widget::Queue(vec![ + Column { + item: Constrained::Ratio(12, Texts::QueueTitle), + style: vec![AddStyle::Fg(Color::Indexed(75))], + selected_style: vec![ + AddStyle::Fg(Color::Black), + AddStyle::Bg(Color::Indexed(75)), + AddStyle::Bold, + ], + }, + Column { + item: Constrained::Ratio(10, Texts::QueueArtist), + style: vec![AddStyle::Fg(Color::Indexed(111))], + selected_style: vec![ + AddStyle::Fg(Color::Black), + AddStyle::Bg(Color::Indexed(111)), + AddStyle::Bold, + ], + }, + Column { + item: Constrained::Ratio(10, Texts::QueueAlbum), + style: vec![AddStyle::Fg(Color::Indexed(147))], + selected_style: vec![ + AddStyle::Fg(Color::Black), + AddStyle::Bg(Color::Indexed(147)), + AddStyle::Bold, + ], + }, + Column { + item: Constrained::Ratio(1, Texts::QueueDuration), + style: vec![AddStyle::Fg(Color::Indexed(183))], + selected_style: vec![ + AddStyle::Fg(Color::Black), + AddStyle::Bg(Color::Indexed(183)), + AddStyle::Bold, + ], + }, + ]), + ), + Constrained::Fixed( + 1, + Widget::Columns(vec![ + Constrained::Min( + 0, + Widget::Textbox(Texts::If( + Condition::Not(Box::new(Condition::Stopped)), + Box::new(Texts::Styled( + vec![AddStyle::Bold], + Box::new(Texts::Parts(vec![ + Texts::Styled( + vec![AddStyle::Fg(Color::Indexed(113))], + Box::new(Texts::Parts(vec![ + Texts::If( + Condition::Playing, + Box::new(Texts::Text(String::from("[playing: "))), + Some(Box::new(Texts::Text(String::from("[paused: ")))), + ), + Texts::CurrentElapsed, + Texts::Text(String::from("/")), + Texts::CurrentDuration, + Texts::Text(String::from("] ")), + ])), + ), + Texts::If( + Condition::TitleExist, + Box::new(Texts::Parts(vec![ + Texts::Styled( + vec![AddStyle::Fg(Color::Indexed(149))], + Box::new(Texts::CurrentTitle), + ), + Texts::If( + Condition::ArtistExist, + Box::new(Texts::Parts(vec![ + Texts::Styled( + vec![AddStyle::Fg(Color::Indexed(216))], + Box::new(Texts::Text(String::from(" ◆ "))), + ), + Texts::Styled( + vec![AddStyle::Fg(Color::Indexed(185))], + Box::new(Texts::CurrentArtist), + ), + Texts::If( + Condition::AlbumExist, + Box::new(Texts::Parts(vec![ + Texts::Styled( + vec![AddStyle::Fg(Color::Indexed(216))], + Box::new(Texts::Text(String::from( + " ◆ ", + ))), + ), + Texts::Styled( + vec![AddStyle::Fg(Color::Indexed(221))], + Box::new(Texts::CurrentAlbum), + ), + ])), + None, + ), + ])), + None, + ), + ])), + Some(Box::new(Texts::Styled( + vec![AddStyle::Fg(Color::Indexed(185))], + Box::new(Texts::CurrentFile), + ))), + ), + ])), + )), + None, + )), + ), + Constrained::Fixed( + 12, + Widget::TextboxR(Texts::Styled( + vec![AddStyle::Fg(Color::Indexed(81))], + Box::new(Texts::Parts(vec![ + Texts::Text(String::from("[")), + Texts::If( + Condition::Repeat, + Box::new(Texts::Text(String::from("@"))), + None, + ), + Texts::If( + Condition::Random, + Box::new(Texts::Text(String::from("#"))), + None, + ), + Texts::If( + Condition::Single, + Box::new(Texts::Text(String::from("^"))), + Some(Box::new(Texts::If( + Condition::Oneshot, + Box::new(Texts::Text(String::from("!"))), + None, + ))), + ), + Texts::If( + Condition::Consume, + Box::new(Texts::Text(String::from("*"))), + None, + ), + Texts::Text(String::from("]")), + ])), + )), + ), + ]), + ), + ]) +} diff --git a/src/main.rs b/src/main.rs index 04bb944..813a7ab 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,11 +2,12 @@ #![forbid(unsafe_code)] mod config; +mod defaults; mod fail; mod layout; mod mpd; -use anyhow::{bail, Context, Error, Result}; +use anyhow::{Context, Error, Result}; use crossterm::{ event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, KeyEvent, MouseEvent}, execute, @@ -118,10 +119,15 @@ async fn run() -> Result<()> { let mut xs = xs; xs.push("mmtc"); xs.push("mmtc.ron"); - ron::from_str(&fs::read_to_string(&xs).with_context(fail::read(xs.display()))?) - .with_context(fail::parse_cfg(xs.display()))? + + if xs.is_file() { + ron::from_str(&fs::read_to_string(&xs).with_context(fail::read(xs.display()))?) + .with_context(fail::parse_cfg(xs.display()))? + } else { + defaults::config() + } } else { - bail!("Failed to find the config directory, please specify a config file"); + defaults::config() }; let addr = if let Some(addr) = opts.address {