allow styling queue widget

This commit is contained in:
figsoda 2020-11-01 14:29:39 -05:00
parent 1aedeb45c3
commit 1de2d3a0f2
3 changed files with 118 additions and 100 deletions

View file

@ -6,26 +6,28 @@ Config(
Ratio(10, Textbox(Text("Album"))), Ratio(10, Textbox(Text("Album"))),
Ratio(1, Textbox(Text("Time"))), Ratio(1, Textbox(Text("Time"))),
])), ])),
Min(0, Queue( Min(0, Queue([
columns: [ Column(
Ratio(12, If(Selected, item: Ratio(12, QueueTitle),
Styled([Fg(Black), Bg(Indexed(117)), Bold], QueueTitle), style: [Fg(Indexed(117))],
Styled([Fg(Indexed(117))], QueueTitle), selected_style: [Fg(Black), Bg(Indexed(117)), Bold],
)), ),
Ratio(10, If(Selected, Column(
Styled([Fg(Black), Bg(Indexed(111)), Bold], QueueArtist), item: Ratio(10, QueueArtist),
Styled([Fg(Indexed(111))], QueueArtist), style: [Fg(Indexed(111))],
)), selected_style: [Fg(Black), Bg(Indexed(111)), Bold],
Ratio(10, If(Selected, ),
Styled([Fg(Black), Bg(Indexed(105)), Bold], QueueAlbum), Column(
Styled([Fg(Indexed(105))], QueueAlbum), item: Ratio(10, QueueAlbum),
)), style: [Fg(Indexed(105))],
Ratio(1, If(Selected, selected_style: [Fg(Black), Bg(Indexed(105)), Bold],
Styled([Fg(Black), Bg(Indexed(177)), Bold], QueueDuration), ),
Styled([Fg(Indexed(177))], QueueDuration), Column(
)), item: Ratio(1, QueueDuration),
], style: [Fg(Indexed(177))],
)), selected_style: [Fg(Black), Bg(Indexed(177)), Bold],
),
])),
Fixed(1, Textbox(If(Playing, Parts([ Fixed(1, Textbox(If(Playing, Parts([
Text("["), Text("["),
CurrentElapsed, CurrentElapsed,

View file

@ -30,7 +30,7 @@ pub enum Widget {
Rows(Vec<Constrained<Widget>>), Rows(Vec<Constrained<Widget>>),
Columns(Vec<Constrained<Widget>>), Columns(Vec<Constrained<Widget>>),
Textbox(Texts), Textbox(Texts),
Queue { columns: Vec<Constrained<Texts>> }, Queue(Vec<Column>),
} }
#[derive(Deserialize)] #[derive(Deserialize)]
@ -101,6 +101,15 @@ pub enum Condition {
Xor(Box<Condition>, Box<Condition>), Xor(Box<Condition>, Box<Condition>),
} }
#[derive(Deserialize)]
pub struct Column {
pub item: Constrained<Texts>,
#[serde(default)]
pub style: Vec<AddStyle>,
#[serde(default)]
pub selected_style: Vec<AddStyle>,
}
impl<'de> Deserialize<'de> for Texts { impl<'de> Deserialize<'de> for Texts {
fn deserialize<D>(de: D) -> Result<Self, D::Error> fn deserialize<D>(de: D) -> Result<Self, D::Error>
where where

View file

@ -8,7 +8,7 @@ use tui::{
}; };
use crate::{ use crate::{
config::{AddStyle, Condition, Constrained, Texts, Widget}, config::{AddStyle, Column, Condition, Constrained, Texts, Widget},
mpd::{Song, Status, Track}, mpd::{Song, Status, Track},
}; };
@ -109,13 +109,13 @@ pub fn render(
); );
frame.render_widget(Paragraph::new(Spans::from(spans)), size); frame.render_widget(Paragraph::new(Spans::from(spans)), size);
} }
Widget::Queue { columns } => { Widget::Queue(xs) => {
let len = columns.capacity(); let len = xs.capacity();
let mut ws = Vec::with_capacity(len); let mut ws = Vec::with_capacity(len);
let mut cs = Vec::with_capacity(len); let mut cs = Vec::with_capacity(len);
let denom = columns.iter().fold(0, |n, x| { let denom = xs.iter().fold(0, |n, Column { item, .. }| {
if let Constrained::Ratio(m, _) = x { if let Constrained::Ratio(m, _) = item {
n + m n + m
} else { } else {
n n
@ -128,17 +128,17 @@ pub fn render(
None None
}; };
for column in columns { for column in xs {
let len = queue.len(); let len = queue.len();
if len == 0 { if len == 0 {
continue; continue;
} }
let (xs, constraint) = match column { let (txts, constraint) = match &column.item {
Constrained::Fixed(n, w) => (w, Constraint::Length(*n)), Constrained::Fixed(n, txts) => (txts, Constraint::Length(*n)),
Constrained::Max(n, w) => (w, Constraint::Max(*n)), Constrained::Max(n, txts) => (txts, Constraint::Max(*n)),
Constrained::Min(n, w) => (w, Constraint::Min(*n)), Constrained::Min(n, txts) => (txts, Constraint::Min(*n)),
Constrained::Ratio(n, xs) => (xs, Constraint::Ratio(*n, denom)), Constrained::Ratio(n, txts) => (txts, Constraint::Ratio(*n, denom)),
}; };
let mut items = Vec::with_capacity(len); let mut items = Vec::with_capacity(len);
@ -146,7 +146,7 @@ pub fn render(
let mut spans = Vec::new(); let mut spans = Vec::new();
flatten( flatten(
&mut spans, &mut spans,
xs, txts,
status, status,
current_track, current_track,
Some(&queue[i]), Some(&queue[i]),
@ -155,7 +155,11 @@ pub fn render(
); );
items.push(ListItem::new(Spans::from(spans))); items.push(ListItem::new(Spans::from(spans)));
} }
ws.push(List::new(items)); ws.push(
List::new(items)
.style(patch_style(Style::default(), &column.style))
.highlight_style(patch_style(Style::default(), &column.selected_style)),
);
cs.push(constraint); cs.push(constraint);
} }
@ -272,71 +276,6 @@ fn flatten(
} }
} }
Texts::Styled(styles, box xs) => { Texts::Styled(styles, box xs) => {
let mut style = style;
for add_style in styles {
match add_style {
AddStyle::Fg(color) => {
style.fg = Some(*color);
}
AddStyle::Bg(color) => {
style.bg = Some(*color);
}
AddStyle::Bold => {
style = style.add_modifier(Modifier::BOLD);
}
AddStyle::NoBold => {
style = style.remove_modifier(Modifier::BOLD);
}
AddStyle::Dim => {
style = style.add_modifier(Modifier::DIM);
}
AddStyle::NoDim => {
style = style.remove_modifier(Modifier::DIM);
}
AddStyle::Italic => {
style = style.add_modifier(Modifier::ITALIC);
}
AddStyle::NoItalic => {
style = style.remove_modifier(Modifier::ITALIC);
}
AddStyle::Underlined => {
style = style.add_modifier(Modifier::UNDERLINED);
}
AddStyle::NoUnderlined => {
style = style.remove_modifier(Modifier::UNDERLINED);
}
AddStyle::SlowBlink => {
style = style.add_modifier(Modifier::SLOW_BLINK);
}
AddStyle::NoSlowBlink => {
style = style.remove_modifier(Modifier::SLOW_BLINK);
}
AddStyle::RapidBlink => {
style = style.add_modifier(Modifier::RAPID_BLINK);
}
AddStyle::NoRapidBlink => {
style = style.remove_modifier(Modifier::RAPID_BLINK);
}
AddStyle::Reversed => {
style = style.add_modifier(Modifier::REVERSED);
}
AddStyle::NoReversed => {
style = style.remove_modifier(Modifier::REVERSED);
}
AddStyle::Hidden => {
style = style.add_modifier(Modifier::HIDDEN);
}
AddStyle::NoHidden => {
style = style.remove_modifier(Modifier::HIDDEN);
}
AddStyle::CrossedOut => {
style = style.add_modifier(Modifier::CROSSED_OUT);
}
AddStyle::NoCrossedOut => {
style = style.remove_modifier(Modifier::CROSSED_OUT);
}
}
}
flatten( flatten(
spans, spans,
xs, xs,
@ -344,7 +283,7 @@ fn flatten(
current_track, current_track,
queue_track, queue_track,
selected, selected,
style, patch_style(style, styles),
); );
} }
Texts::Parts(xss) => { Texts::Parts(xss) => {
@ -390,6 +329,74 @@ fn flatten(
} }
} }
} }
fn patch_style(style: Style, styles: &Vec<AddStyle>) -> Style {
let mut style = style;
for add_style in styles {
match add_style {
AddStyle::Fg(color) => {
style.fg = Some(*color);
}
AddStyle::Bg(color) => {
style.bg = Some(*color);
}
AddStyle::Bold => {
style = style.add_modifier(Modifier::BOLD);
}
AddStyle::NoBold => {
style = style.remove_modifier(Modifier::BOLD);
}
AddStyle::Dim => {
style = style.add_modifier(Modifier::DIM);
}
AddStyle::NoDim => {
style = style.remove_modifier(Modifier::DIM);
}
AddStyle::Italic => {
style = style.add_modifier(Modifier::ITALIC);
}
AddStyle::NoItalic => {
style = style.remove_modifier(Modifier::ITALIC);
}
AddStyle::Underlined => {
style = style.add_modifier(Modifier::UNDERLINED);
}
AddStyle::NoUnderlined => {
style = style.remove_modifier(Modifier::UNDERLINED);
}
AddStyle::SlowBlink => {
style = style.add_modifier(Modifier::SLOW_BLINK);
}
AddStyle::NoSlowBlink => {
style = style.remove_modifier(Modifier::SLOW_BLINK);
}
AddStyle::RapidBlink => {
style = style.add_modifier(Modifier::RAPID_BLINK);
}
AddStyle::NoRapidBlink => {
style = style.remove_modifier(Modifier::RAPID_BLINK);
}
AddStyle::Reversed => {
style = style.add_modifier(Modifier::REVERSED);
}
AddStyle::NoReversed => {
style = style.remove_modifier(Modifier::REVERSED);
}
AddStyle::Hidden => {
style = style.add_modifier(Modifier::HIDDEN);
}
AddStyle::NoHidden => {
style = style.remove_modifier(Modifier::HIDDEN);
}
AddStyle::CrossedOut => {
style = style.add_modifier(Modifier::CROSSED_OUT);
}
AddStyle::NoCrossedOut => {
style = style.remove_modifier(Modifier::CROSSED_OUT);
}
}
}
style
}
fn eval_cond( fn eval_cond(
cond: &Condition, cond: &Condition,