Idle pill: the note no longer sits against the rim (the elided words took the whole width); words only where they fit, and they fade before the carousel makes the island too narrow for them

This commit is contained in:
server2
2026-10-19 11:41:45 +02:00
parent 7cb2368b23
commit 756f38be4e
+35 -10
View File
@@ -388,7 +388,8 @@ pub fn pill_face(monitor: &str, small: f32) -> Rectangle {
let h = c::pill::height(); let h = c::pill::height();
let player = shown(&media, island.selected.as_deref()); let player = shown(&media, island.selected.as_deref());
let width = mix(c::pill::width(), small_width_for(player.is_some(), &art.path), small); let small_w = small_width_for(player.is_some(), &art.path);
let width = mix(c::pill::width(), small_w, small);
let live = player.is_some() && focused_monitor().as_deref().is_none_or(|name| name == monitor); let live = player.is_some() && focused_monitor().as_deref().is_none_or(|name| name == monitor);
let spectrum = live.then(Spectrum::read); let spectrum = live.then(Spectrum::read);
@@ -398,21 +399,27 @@ pub fn pill_face(monitor: &str, small: f32) -> Rectangle {
amane::request_frame(); amane::request_frame();
} }
let face = if small < 0.5 { /*
* the pill's face fades out, then the small one in: they swap halfway, or with nothing
* playing as soon as the shape gets too narrow for the words, so these never vanish while seen
*/
let turn = if player.is_some() { 0.5 } else { ((c::pill::width() - idle_room()) / (c::pill::width() - small_w).max(1.0)).clamp(0.05, 0.5) };
let face = if small < turn {
let big = match player { let big = match player {
Some(player) => compact(player, playing(player, &island), &art.path, levels, width), Some(player) => compact(player, playing(player, &island), &art.path, levels, width),
None => idle_face(width), None => idle_face(width),
}; };
veiled(big, width, h, h / 2.0, 1.0 - 2.0 * small, &colors) veiled(big, width, h, h / 2.0, 1.0 - small / turn, &colors)
} else { } else {
let little: Box<dyn Widget> = match player { let little: Box<dyn Widget> = match player {
Some(_) if !art.path.is_empty() => Box::new(cover(&art.path, h - 10.0, 1.5, false)), Some(_) if !art.path.is_empty() => Box::new(cover(&art.path, h - 10.0, 1.5, false)),
Some(player) => Box::new(pill_levels(playing(player, &island), levels)), Some(player) => Box::new(pill_levels(playing(player, &island), levels)),
None => Box::new(icon(Glyph::Note, 15.0, theme::now().accent)), None => Box::new(icon(Glyph::Note, IDLE_NOTE, theme::now().accent)),
}; };
veiled(Rectangle::new().width(width).height(h).align_child(Center, Center).child(Stack::new(vec![little])), width, h, h / 2.0, 2.0 * small - 1.0, &colors) veiled(Rectangle::new().width(width).height(h).align_child(Center, Center).child(Stack::new(vec![little])), width, h, h / 2.0, (small - turn) / (1.0 - turn), &colors)
}; };
surface::shell(width, h, h / 2.0, &colors, 0.0, face) surface::shell(width, h, h / 2.0, &colors, 0.0, face)
@@ -668,12 +675,30 @@ fn idle(colors: &[Color; 3]) -> Rectangle {
surface::shell(c::pill::width(), c::pill::height(), c::pill::height() / 2.0, colors, 0.0, idle_face(c::pill::width())) surface::shell(c::pill::width(), c::pill::height(), c::pill::height() / 2.0, colors, 0.0, idle_face(c::pill::width()))
} }
/*
* a note and "Nothing playing", centred. the words only where they fit with half the
* pill's height to spare at each end, else the note alone: an elided text takes the whole
* width, which put the note against the rim, and a pill narrower than the words did too
*/
fn idle_face(width: f32) -> Rectangle { fn idle_face(width: f32) -> Rectangle {
Rectangle::new() let note = icon(Glyph::Note, IDLE_NOTE, theme::now().accent);
.width(width) let row = if idle_room() <= width { Row::new(children![note, idle_words()]) } else { Row::new(children![note]) };
.height(c::pill::height())
.align_child(Center, Center) Rectangle::new().width(width).height(c::pill::height()).align_child(Center, Center).child(row.gap(8.0).align(Center))
.child(Row::new(children![icon(Glyph::Note, 15.0, theme::now().accent), Text::new("Nothing playing").size(text::body()).color(theme::now().dim).elide()]).gap(8.0).align(Center)) }
const IDLE_NOTE: f32 = 15.0;
fn idle_words() -> Text {
Text::new("Nothing playing").size(text::body()).color(theme::now().dim)
}
// the width the note and the words need, with half the pill's height to spare at each end
fn idle_room() -> f32 {
match idle_words().width() {
amane::Size::Fixed(words) => IDLE_NOTE + 8.0 + words + c::pill::height(),
amane::Size::Parent => f32::MAX,
}
} }
// the pill, `width` wide: cover, title, the player's live levels // the pill, `width` wide: cover, title, the player's live levels