mirror of
https://github.com/danbulant/despot
synced 2026-07-05 19:10:57 +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,
|
DynamicComponent, FamilyOwned, FontFamilyList, Weight,
|
||||||
},
|
},
|
||||||
widget::MakeWidget,
|
widget::MakeWidget,
|
||||||
|
widgets::{button::ButtonKind, Button},
|
||||||
Cushy,
|
Cushy,
|
||||||
};
|
};
|
||||||
|
|
||||||
static FONT: OnceLock<LoadedFont> = OnceLock::new();
|
static FONT: OnceLock<LoadedFont> = OnceLock::new();
|
||||||
|
|
||||||
pub fn load_fonts(/*cushy: &Cushy*/) -> FontCollection {
|
pub fn load_fonts() -> FontCollection {
|
||||||
let fonts = FontCollection::default();
|
let fonts = FontCollection::default();
|
||||||
let font_data = include_bytes!("../fonts/MaterialIcons-Regular.ttf").to_vec();
|
|
||||||
dbg!(font_data.len());
|
|
||||||
let font = fonts.push_unloadable(
|
let font = fonts.push_unloadable(
|
||||||
// include_bytes!("../fonts/MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].ttf").into(),
|
include_bytes!("../fonts/MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].ttf").into(),
|
||||||
font_data,
|
|
||||||
);
|
);
|
||||||
// /home/dan/projects/despot/fonts/MaterialIcons-Regular.ttf
|
|
||||||
println!("loaded");
|
|
||||||
FONT.set(font).map_err(|_| ()).unwrap();
|
FONT.set(font).map_err(|_| ()).unwrap();
|
||||||
fonts
|
fonts
|
||||||
}
|
}
|
||||||
|
|
@ -30,11 +26,8 @@ fn font_component() -> DynamicComponent {
|
||||||
DynamicComponent::new({
|
DynamicComponent::new({
|
||||||
move |context| {
|
move |context| {
|
||||||
let font = &FONT.get().unwrap();
|
let font = &FONT.get().unwrap();
|
||||||
// dbg!(font);
|
|
||||||
let faces = context.loaded_font_faces(font);
|
let faces = context.loaded_font_faces(font);
|
||||||
dbg!(&faces);
|
|
||||||
let face = faces.first()?;
|
let face = faces.first()?;
|
||||||
dbg!(&face);
|
|
||||||
Some(cushy::styles::Component::custom(FontFamilyList::from(
|
Some(cushy::styles::Component::custom(FontFamilyList::from(
|
||||||
vec![FamilyOwned::Name(face.families[0].0.clone())],
|
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())
|
.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: &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 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::units::Lp;
|
||||||
use cushy::figures::Size;
|
use cushy::figures::{Size, Zero};
|
||||||
use cushy::kludgine::Color;
|
use cushy::kludgine::Color;
|
||||||
use cushy::styles::{CornerRadii, Dimension, DimensionRange};
|
use cushy::styles::{CornerRadii, Dimension, DimensionRange};
|
||||||
use cushy::widgets::image::ImageCornerRadius;
|
use cushy::widgets::image::ImageCornerRadius;
|
||||||
|
|
@ -56,6 +56,7 @@ pub fn playlists_widget(
|
||||||
list
|
list
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
.gutter(Dimension::ZERO)
|
||||||
.vertical_scroll()
|
.vertical_scroll()
|
||||||
.size(Size {
|
.size(Size {
|
||||||
width: Dimension::Lp(Lp::points(200)).into(),
|
width: Dimension::Lp(Lp::points(200)).into(),
|
||||||
|
|
@ -97,7 +98,6 @@ where
|
||||||
.on_click(callback)
|
.on_click(callback)
|
||||||
.with(&ButtonBackground, background)
|
.with(&ButtonBackground, background)
|
||||||
.with(&ButtonHoverBackground, background_hover)
|
.with(&ButtonHoverBackground, background_hover)
|
||||||
.pad()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `background` and `background_hover` colors for a library entry.
|
/// 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());
|
let track = tracks.map_each(move |tracks| tracks.get(&index).cloned());
|
||||||
index
|
index
|
||||||
.to_string()
|
.to_string()
|
||||||
|
.align_right()
|
||||||
.size(Size {
|
.size(Size {
|
||||||
width: Dimension::Lp(Lp::points(40)).into(),
|
width: Dimension::Lp(Lp::points(20)).into(),
|
||||||
height: DimensionRange::default(),
|
height: DimensionRange::default(),
|
||||||
})
|
})
|
||||||
.fit_horizontally()
|
|
||||||
.and({
|
.and({
|
||||||
get_or_create_track_image(&track_images, index, |index| {
|
get_or_create_track_image(&track_images, index, |index| {
|
||||||
Image::new_empty()
|
Image::new_empty()
|
||||||
|
|
@ -213,6 +213,7 @@ impl LikedSongsPage {
|
||||||
format_delta(track.track.duration)
|
format_delta(track.track.duration)
|
||||||
.into_label()
|
.into_label()
|
||||||
.overflow(LabelOverflow::Clip)
|
.overflow(LabelOverflow::Clip)
|
||||||
|
.align_right()
|
||||||
.make_widget()
|
.make_widget()
|
||||||
})
|
})
|
||||||
.unwrap_or(Space::primary().make_widget())
|
.unwrap_or(Space::primary().make_widget())
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,17 @@ use cushy::{
|
||||||
styles::{Dimension, DimensionRange},
|
styles::{Dimension, DimensionRange},
|
||||||
value::{Dynamic, Source},
|
value::{Dynamic, Source},
|
||||||
widget::MakeWidget,
|
widget::MakeWidget,
|
||||||
widgets::{image::ImageCornerRadius, Button, Image, Label, Slider},
|
widgets::{
|
||||||
|
image::ImageCornerRadius,
|
||||||
|
label::{Displayable, LabelOverflow},
|
||||||
|
Button, Image, Label, Slider,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use librespot_metadata::audio::UniqueFields;
|
use librespot_metadata::audio::UniqueFields;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
icons::{icon, SKIP_PREVIOUS},
|
icons::{icon, iconbtn, IntoIcon, PAUSE, PLAY, REPEAT, SHUFFLE, SKIP_NEXT, SKIP_PREVIOUS},
|
||||||
player::{DynamicPlayer, PlayerState},
|
player::{DynamicPlayer, PlayerState},
|
||||||
widgets::image::ImageExt,
|
widgets::image::ImageExt,
|
||||||
};
|
};
|
||||||
|
|
@ -32,7 +36,9 @@ fn meta(player: DynamicPlayer) -> impl MakeWidget {
|
||||||
.flatten()
|
.flatten()
|
||||||
}))
|
}))
|
||||||
.with(&ImageCornerRadius, Dimension::Lp(Lp::points(4)))
|
.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(
|
.and(
|
||||||
player
|
player
|
||||||
.track
|
.track
|
||||||
|
|
@ -43,23 +49,30 @@ fn meta(player: DynamicPlayer) -> impl MakeWidget {
|
||||||
track
|
track
|
||||||
.name
|
.name
|
||||||
.clone()
|
.clone()
|
||||||
.and(match &track.unique_fields {
|
.into_label()
|
||||||
UniqueFields::Track {
|
.overflow(LabelOverflow::Clip)
|
||||||
artists,
|
.and(
|
||||||
album,
|
match &track.unique_fields {
|
||||||
album_artists,
|
UniqueFields::Track {
|
||||||
popularity,
|
artists,
|
||||||
number,
|
album,
|
||||||
disc_number,
|
album_artists,
|
||||||
} => {
|
popularity,
|
||||||
artists.iter().map(|artist| artist.name.clone()).join(", ")
|
number,
|
||||||
|
disc_number,
|
||||||
|
} => artists
|
||||||
|
.iter()
|
||||||
|
.map(|artist| artist.name.clone())
|
||||||
|
.join(", "),
|
||||||
|
UniqueFields::Episode {
|
||||||
|
description,
|
||||||
|
publish_time,
|
||||||
|
show_name,
|
||||||
|
} => show_name.clone(),
|
||||||
}
|
}
|
||||||
UniqueFields::Episode {
|
.into_label()
|
||||||
description,
|
.overflow(LabelOverflow::Clip),
|
||||||
publish_time,
|
)
|
||||||
show_name,
|
|
||||||
} => show_name.clone(),
|
|
||||||
})
|
|
||||||
.into_rows()
|
.into_rows()
|
||||||
.make_widget()
|
.make_widget()
|
||||||
})
|
})
|
||||||
|
|
@ -78,20 +91,19 @@ fn meta(player: DynamicPlayer) -> impl MakeWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn controls(player: DynamicPlayer) -> impl MakeWidget {
|
fn controls(player: DynamicPlayer) -> impl MakeWidget {
|
||||||
icon("shuffle")
|
iconbtn(SHUFFLE)
|
||||||
.into_button()
|
.and(iconbtn(SKIP_PREVIOUS))
|
||||||
.and(icon(SKIP_PREVIOUS).into_button())
|
|
||||||
.and(player.state.map_each({
|
.and(player.state.map_each({
|
||||||
let player = player.clone();
|
let player = player.clone();
|
||||||
move |state| {
|
move |state| {
|
||||||
let player = player.clone();
|
let player = player.clone();
|
||||||
let state = state.clone();
|
let state = state.clone();
|
||||||
match &state {
|
match &state {
|
||||||
PlayerState::Playing => "pause",
|
PlayerState::Playing => PAUSE,
|
||||||
PlayerState::Paused { .. } => "play",
|
PlayerState::Paused { .. } => PLAY,
|
||||||
_ => "play",
|
_ => PLAY,
|
||||||
}
|
}
|
||||||
.into_button()
|
.into_iconbtn()
|
||||||
.on_click(move |_| match state {
|
.on_click(move |_| match state {
|
||||||
PlayerState::Playing => {
|
PlayerState::Playing => {
|
||||||
player.player.pause();
|
player.player.pause();
|
||||||
|
|
@ -103,8 +115,8 @@ fn controls(player: DynamicPlayer) -> impl MakeWidget {
|
||||||
.make_widget()
|
.make_widget()
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.and("skip".into_button())
|
.and(iconbtn(SKIP_NEXT))
|
||||||
.and("repeat".into_button())
|
.and(iconbtn(REPEAT))
|
||||||
.into_columns()
|
.into_columns()
|
||||||
.centered()
|
.centered()
|
||||||
.and(time(player))
|
.and(time(player))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue