mirror of
https://github.com/danbulant/despot
synced 2026-06-18 22:11:03 +00:00
improves styles, fixed font loading
This commit is contained in:
parent
394fcf01e8
commit
3f0dde272c
5 changed files with 259 additions and 257 deletions
393
Cargo.lock
generated
393
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
46
src/icons.rs
46
src/icons.rs
|
|
@ -7,21 +7,17 @@ use cushy::{
|
|||
DynamicComponent, FamilyOwned, FontFamilyList, Weight,
|
||||
},
|
||||
widget::MakeWidget,
|
||||
widgets::{button::ButtonKind, Button},
|
||||
Cushy,
|
||||
};
|
||||
|
||||
static FONT: OnceLock<LoadedFont> = OnceLock::new();
|
||||
|
||||
pub fn load_fonts(/*cushy: &Cushy*/) -> FontCollection {
|
||||
pub fn load_fonts() -> FontCollection {
|
||||
let fonts = FontCollection::default();
|
||||
let font_data = include_bytes!("../fonts/MaterialIcons-Regular.ttf").to_vec();
|
||||
dbg!(font_data.len());
|
||||
let font = fonts.push_unloadable(
|
||||
// include_bytes!("../fonts/MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].ttf").into(),
|
||||
font_data,
|
||||
include_bytes!("../fonts/MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].ttf").into(),
|
||||
);
|
||||
// /home/dan/projects/despot/fonts/MaterialIcons-Regular.ttf
|
||||
println!("loaded");
|
||||
FONT.set(font).map_err(|_| ()).unwrap();
|
||||
fonts
|
||||
}
|
||||
|
|
@ -30,11 +26,8 @@ fn font_component() -> DynamicComponent {
|
|||
DynamicComponent::new({
|
||||
move |context| {
|
||||
let font = &FONT.get().unwrap();
|
||||
// dbg!(font);
|
||||
let faces = context.loaded_font_faces(font);
|
||||
dbg!(&faces);
|
||||
let face = faces.first()?;
|
||||
dbg!(&face);
|
||||
Some(cushy::styles::Component::custom(FontFamilyList::from(
|
||||
vec![FamilyOwned::Name(face.families[0].0.clone())],
|
||||
)))
|
||||
|
|
@ -61,5 +54,38 @@ pub fn icon(str: &str) -> impl MakeWidget {
|
|||
.with_dynamic(&FontWeight, FONT_WEIGHT_COMPONENT.clone())
|
||||
}
|
||||
|
||||
pub fn iconbtn(str: &str) -> Button {
|
||||
icon(str).into_button().kind(ButtonKind::Transparent)
|
||||
}
|
||||
|
||||
pub trait IntoIcon {
|
||||
fn into_icon(self) -> impl MakeWidget;
|
||||
fn into_iconbtn(self) -> Button
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.into_icon().into_button().kind(ButtonKind::Transparent)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIcon for &str {
|
||||
fn into_icon(self) -> impl MakeWidget {
|
||||
icon(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub const PLAY: &str = "\u{e037}";
|
||||
pub const PAUSE: &str = "\u{e034}";
|
||||
pub const REPEAT: &str = "\u{e040}";
|
||||
pub const REPEAT_ON: &str = "\u{e9d6}";
|
||||
pub const REPEAT_ONE: &str = "\u{e041}";
|
||||
pub const REPEAT_ONE_ON: &str = "\u{e9d7}";
|
||||
pub const SHUFFLE: &str = "\u{e043}";
|
||||
pub const SHUFFLE_ON: &str = "\u{e9e1}";
|
||||
pub const SKIP_NEXT: &str = "\u{e044}";
|
||||
pub const SKIP_PREVIOUS: &str = "\u{e045}";
|
||||
pub const QUEUE_MUSIC: &str = "\u{e03d}";
|
||||
pub const EXPLICIT: &str = "\u{e01e}";
|
||||
pub const ALBUM: &str = "\u{e019}";
|
||||
pub const LYRICS: &str = "\u{ec0b}";
|
||||
pub const MUSIC_CAST: &str = "\u{eb1a}";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use cushy::figures::units::Lp;
|
||||
use cushy::figures::Size;
|
||||
use cushy::figures::{Size, Zero};
|
||||
use cushy::kludgine::Color;
|
||||
use cushy::styles::{CornerRadii, Dimension, DimensionRange};
|
||||
use cushy::widgets::image::ImageCornerRadius;
|
||||
|
|
@ -56,6 +56,7 @@ pub fn playlists_widget(
|
|||
list
|
||||
}),
|
||||
)
|
||||
.gutter(Dimension::ZERO)
|
||||
.vertical_scroll()
|
||||
.size(Size {
|
||||
width: Dimension::Lp(Lp::points(200)).into(),
|
||||
|
|
@ -97,7 +98,6 @@ where
|
|||
.on_click(callback)
|
||||
.with(&ButtonBackground, background)
|
||||
.with(&ButtonHoverBackground, background_hover)
|
||||
.pad()
|
||||
}
|
||||
|
||||
/// Returns `background` and `background_hover` colors for a library entry.
|
||||
|
|
|
|||
|
|
@ -119,11 +119,11 @@ impl LikedSongsPage {
|
|||
let track = tracks.map_each(move |tracks| tracks.get(&index).cloned());
|
||||
index
|
||||
.to_string()
|
||||
.align_right()
|
||||
.size(Size {
|
||||
width: Dimension::Lp(Lp::points(40)).into(),
|
||||
width: Dimension::Lp(Lp::points(20)).into(),
|
||||
height: DimensionRange::default(),
|
||||
})
|
||||
.fit_horizontally()
|
||||
.and({
|
||||
get_or_create_track_image(&track_images, index, |index| {
|
||||
Image::new_empty()
|
||||
|
|
@ -213,6 +213,7 @@ impl LikedSongsPage {
|
|||
format_delta(track.track.duration)
|
||||
.into_label()
|
||||
.overflow(LabelOverflow::Clip)
|
||||
.align_right()
|
||||
.make_widget()
|
||||
})
|
||||
.unwrap_or(Space::primary().make_widget())
|
||||
|
|
|
|||
|
|
@ -5,13 +5,17 @@ use cushy::{
|
|||
styles::{Dimension, DimensionRange},
|
||||
value::{Dynamic, Source},
|
||||
widget::MakeWidget,
|
||||
widgets::{image::ImageCornerRadius, Button, Image, Label, Slider},
|
||||
widgets::{
|
||||
image::ImageCornerRadius,
|
||||
label::{Displayable, LabelOverflow},
|
||||
Button, Image, Label, Slider,
|
||||
},
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use librespot_metadata::audio::UniqueFields;
|
||||
|
||||
use crate::{
|
||||
icons::{icon, SKIP_PREVIOUS},
|
||||
icons::{icon, iconbtn, IntoIcon, PAUSE, PLAY, REPEAT, SHUFFLE, SKIP_NEXT, SKIP_PREVIOUS},
|
||||
player::{DynamicPlayer, PlayerState},
|
||||
widgets::image::ImageExt,
|
||||
};
|
||||
|
|
@ -32,7 +36,9 @@ fn meta(player: DynamicPlayer) -> impl MakeWidget {
|
|||
.flatten()
|
||||
}))
|
||||
.with(&ImageCornerRadius, Dimension::Lp(Lp::points(4)))
|
||||
.size(Size::squared(Dimension::Lp(Lp::inches_f(1.))))
|
||||
.size(Size::squared(Dimension::Lp(Lp::inches_f(0.8))))
|
||||
.pad()
|
||||
.align_left()
|
||||
.and(
|
||||
player
|
||||
.track
|
||||
|
|
@ -43,23 +49,30 @@ fn meta(player: DynamicPlayer) -> impl MakeWidget {
|
|||
track
|
||||
.name
|
||||
.clone()
|
||||
.and(match &track.unique_fields {
|
||||
UniqueFields::Track {
|
||||
artists,
|
||||
album,
|
||||
album_artists,
|
||||
popularity,
|
||||
number,
|
||||
disc_number,
|
||||
} => {
|
||||
artists.iter().map(|artist| artist.name.clone()).join(", ")
|
||||
.into_label()
|
||||
.overflow(LabelOverflow::Clip)
|
||||
.and(
|
||||
match &track.unique_fields {
|
||||
UniqueFields::Track {
|
||||
artists,
|
||||
album,
|
||||
album_artists,
|
||||
popularity,
|
||||
number,
|
||||
disc_number,
|
||||
} => artists
|
||||
.iter()
|
||||
.map(|artist| artist.name.clone())
|
||||
.join(", "),
|
||||
UniqueFields::Episode {
|
||||
description,
|
||||
publish_time,
|
||||
show_name,
|
||||
} => show_name.clone(),
|
||||
}
|
||||
UniqueFields::Episode {
|
||||
description,
|
||||
publish_time,
|
||||
show_name,
|
||||
} => show_name.clone(),
|
||||
})
|
||||
.into_label()
|
||||
.overflow(LabelOverflow::Clip),
|
||||
)
|
||||
.into_rows()
|
||||
.make_widget()
|
||||
})
|
||||
|
|
@ -78,20 +91,19 @@ fn meta(player: DynamicPlayer) -> impl MakeWidget {
|
|||
}
|
||||
|
||||
fn controls(player: DynamicPlayer) -> impl MakeWidget {
|
||||
icon("shuffle")
|
||||
.into_button()
|
||||
.and(icon(SKIP_PREVIOUS).into_button())
|
||||
iconbtn(SHUFFLE)
|
||||
.and(iconbtn(SKIP_PREVIOUS))
|
||||
.and(player.state.map_each({
|
||||
let player = player.clone();
|
||||
move |state| {
|
||||
let player = player.clone();
|
||||
let state = state.clone();
|
||||
match &state {
|
||||
PlayerState::Playing => "pause",
|
||||
PlayerState::Paused { .. } => "play",
|
||||
_ => "play",
|
||||
PlayerState::Playing => PAUSE,
|
||||
PlayerState::Paused { .. } => PLAY,
|
||||
_ => PLAY,
|
||||
}
|
||||
.into_button()
|
||||
.into_iconbtn()
|
||||
.on_click(move |_| match state {
|
||||
PlayerState::Playing => {
|
||||
player.player.pause();
|
||||
|
|
@ -103,8 +115,8 @@ fn controls(player: DynamicPlayer) -> impl MakeWidget {
|
|||
.make_widget()
|
||||
}
|
||||
}))
|
||||
.and("skip".into_button())
|
||||
.and("repeat".into_button())
|
||||
.and(iconbtn(SKIP_NEXT))
|
||||
.and(iconbtn(REPEAT))
|
||||
.into_columns()
|
||||
.centered()
|
||||
.and(time(player))
|
||||
|
|
|
|||
Loading…
Reference in a new issue