feat: add a lot of stuff, don't remember what exactly it did lol
cargo devel CI / cargo CI (push) Failing after 1m4s Details

This commit is contained in:
Christoph J. Scherr 2024-08-24 01:24:39 +02:00
parent 6bee508bf3
commit e068450b6b
13 changed files with 190 additions and 54 deletions

View File

@ -7,7 +7,9 @@ use libpt::log::{debug, info};
use crate::error::Error; use crate::error::Error;
use crate::store::Store; use crate::store::Store;
use self::ui::details::Details;
use self::ui::entry::{Entry, Kind}; use self::ui::entry::{Entry, Kind};
use self::ui::mainpanel::MainPanel;
pub mod ui; pub mod ui;
@ -29,6 +31,9 @@ pub struct Player {
#[clap(skip)] #[clap(skip)]
store: Option<Store>, store: Option<Store>,
#[clap(skip)]
active_main_panel: MainPanel,
} }
impl Player { impl Player {
@ -65,6 +70,8 @@ impl Player {
..Default::default() ..Default::default()
}; };
debug!("main panel on start: {:#?}", app.active_main_panel);
info!("Player ready to start UI"); info!("Player ready to start UI");
Ok(app) Ok(app)
} }
@ -74,6 +81,17 @@ impl Player {
fn set_category(&mut self, kind: Kind) { fn set_category(&mut self, kind: Kind) {
self.kind = kind; self.kind = kind;
match self.kind {
Kind::Album | Kind::Playlist => {
self.set_active_main_panel(MainPanel::Details(Default::default()))
}
Kind::Genre | Kind::Artist | Kind::Overview => {
self.set_active_main_panel(MainPanel::Overview(Default::default()))
}
Kind::Song => {
unreachable!()
}
}
} }
fn category(&self) -> Kind { fn category(&self) -> Kind {
@ -86,6 +104,7 @@ impl Player {
fn entries(&self) -> Vec<Entry> { fn entries(&self) -> Vec<Entry> {
match self.category() { match self.category() {
Kind::Overview => self.store().albums(),
Kind::Album => self.store().albums(), Kind::Album => self.store().albums(),
Kind::Song => self.store().songs(), Kind::Song => self.store().songs(),
Kind::Playlist => self.store().playlists(), Kind::Playlist => self.store().playlists(),

58
src/player/ui/details.rs Normal file
View File

@ -0,0 +1,58 @@
use egui::text::LayoutJob;
use egui::{Color32, FontFamily, FontId, Label, TextFormat};
use super::Entry;
#[derive(Clone, Default, PartialEq)]
pub struct Details {
parent: Entry,
frame: egui::Frame,
}
impl Details {
pub fn new(parent: Entry) -> Self {
let frame = egui::Frame::none();
Self {
parent: parent.to_owned(),
frame,
}
}
pub(crate) fn ui(&self, ui: &mut egui::Ui, ctx: &egui::Context, player: &mut super::Player) {
ui.label("todo");
}
}
impl egui::Widget for Details {
fn ui(self, ui: &mut egui::Ui) -> egui::Response {
ui.vertical_centered(|ui| {
let r = ui.add(
egui::Image::new(self.parent.img())
.rounding(5.0)
.bg_fill(Color32::DARK_GRAY)
.shrink_to_fit()
.maintain_aspect_ratio(true),
);
let mut job = LayoutJob::default();
job.append(
&self.parent.title,
0.0,
TextFormat {
font_id: FontId::new(14.0, FontFamily::Proportional),
..Default::default()
},
);
r.union(ui.add(Label::new(job)));
r.union(ui.label(&self.parent.subtitle));
})
.response
}
}
impl std::fmt::Debug for Details {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Details")
.field("parent", &self.parent)
.finish()
}
}

View File

@ -9,9 +9,10 @@ pub enum Kind {
Song, Song,
Artist, Artist,
Genre, Genre,
Overview,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct Entry { pub struct Entry {
pub kind: Kind, pub kind: Kind,
pub title: String, pub title: String,
@ -54,6 +55,7 @@ impl std::fmt::Display for Kind {
"{}", "{}",
match self { match self {
Self::Song => "Song", Self::Song => "Song",
Self::Overview => "Overview",
Self::Genre => "Genre", Self::Genre => "Genre",
Self::Album => "Album", Self::Album => "Album",
Self::Playlist => "Playlist", Self::Playlist => "Playlist",

View File

@ -0,0 +1,26 @@
use egui_extras::{Column, TableBuilder};
use super::details::Details;
use super::overview::Overview;
use super::Player;
#[derive(Clone, PartialEq, Debug)]
pub enum MainPanel {
Details(Details),
Overview(Overview),
}
impl MainPanel {
pub(crate) fn ui(&self, ui: &mut egui::Ui, ctx: &egui::Context, player: &mut Player) {
match self {
Self::Overview(ov) => ov.ui(ui, ctx, player),
Self::Details(dt) => dt.ui(ui, ctx, player),
}
}
}
impl Default for MainPanel {
fn default() -> Self {
Self::Overview(Overview::default())
}
}

View File

@ -3,11 +3,12 @@ use egui_extras::{Column, TableBuilder};
use libpt::log::{error, trace, warn}; use libpt::log::{error, trace, warn};
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
pub mod details;
pub mod entry; pub mod entry;
pub mod mainpanel;
pub mod overview;
pub mod showbox; pub mod showbox;
use self::showbox::ShowBox;
use super::*; use super::*;
const ICON_RAW: &[u8; 36525] = include_bytes!("../../../assets/img/icon-512.jpg"); const ICON_RAW: &[u8; 36525] = include_bytes!("../../../assets/img/icon-512.jpg");
@ -102,36 +103,16 @@ impl Player {
} }
fn main_panel(&mut self, ui: &mut egui::Ui, ctx: &egui::Context) { fn main_panel(&mut self, ui: &mut egui::Ui, ctx: &egui::Context) {
let mut tb = TableBuilder::new(ui); let bind = self.active_main_panel.clone();
bind.ui(ui, ctx, self)
let entries_per_line: usize = ctx.screen_rect().width() as usize / 256;
for _ in 0..entries_per_line {
tb = tb.column(Column::remainder());
}
tb.body(|mut body| {
for line in self.entries().chunks(entries_per_line) {
body.row(240.0, |mut row| {
for e in line {
row.col(|ui| {
let shobo = ui.add(ShowBox::new(e));
let shobo = shobo.interact(Sense::click());
if shobo.clicked() {
debug!("showbox \"{:#?}\" was clicked", shobo);
warn!("clicking for showbox not defined yet");
self.open(e);
}
});
}
});
}
});
} }
fn meta_panel(&mut self, ui: &mut egui::Ui, ctx: &egui::Context) { fn meta_panel(&mut self, ui: &mut egui::Ui, ctx: &egui::Context) {
ui.horizontal_centered(|ui| { ui.horizontal_centered(|ui| {
for category in Kind::iter() { for category in Kind::iter() {
if category == Kind::Song {
continue; // no category for songs, that's just clicked and then played
}
let sl = ui.selectable_label(self.category() == category, category.to_string()); let sl = ui.selectable_label(self.category() == category, category.to_string());
if sl.clicked() { if sl.clicked() {
self.set_category(category); self.set_category(category);
@ -156,6 +137,10 @@ impl Player {
height: icon_height, height: icon_height,
} }
} }
pub fn set_active_main_panel(&mut self, mp: MainPanel) {
self.active_main_panel = mp;
}
} }
impl eframe::App for Player { impl eframe::App for Player {

47
src/player/ui/overview.rs Normal file
View File

@ -0,0 +1,47 @@
use egui::Sense;
use egui_extras::{Column, TableBuilder};
use libpt::log::{debug, warn};
use super::showbox::ShowBox;
use super::Player;
#[derive(Clone, Default, PartialEq)]
pub struct Overview {
frame: egui::Frame,
}
impl Overview {
pub fn ui(&self, ui: &mut egui::Ui, ctx: &egui::Context, player: &mut Player) {
let mut tb = TableBuilder::new(ui);
let entries_per_line: usize = ctx.screen_rect().width() as usize / 256;
for _ in 0..entries_per_line {
tb = tb.column(Column::remainder());
}
tb.body(|mut body| {
for line in player.entries().chunks(entries_per_line) {
body.row(240.0, |mut row| {
for e in line {
row.col(|ui| {
let shobo = ui.add(ShowBox::new(e));
let shobo = shobo.interact(Sense::click());
if shobo.clicked() {
debug!("showbox \"{:#?}\" was clicked", shobo);
warn!("clicking for showbox not defined yet");
player.open(e);
}
});
}
});
}
});
}
}
impl std::fmt::Debug for Overview {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Overview").finish()
}
}

View File

@ -20,31 +20,27 @@ impl ShowBox {
impl egui::Widget for ShowBox { impl egui::Widget for ShowBox {
fn ui(self, ui: &mut egui::Ui) -> egui::Response { fn ui(self, ui: &mut egui::Ui) -> egui::Response {
egui::Frame::none() ui.vertical_centered(|ui| {
// .fill(Color32::DARK_GRAY) let r = ui.add(
.show(ui, |ui| { egui::Image::new(self.entry.img())
ui.vertical_centered(|ui| { .rounding(5.0)
let r = ui.add( .bg_fill(Color32::DARK_GRAY)
egui::Image::new(self.entry.img()) .shrink_to_fit()
.rounding(5.0) .maintain_aspect_ratio(true),
.bg_fill(Color32::DARK_GRAY) );
.shrink_to_fit() let mut job = LayoutJob::default();
.maintain_aspect_ratio(true), job.append(
); &self.entry.title,
let mut job = LayoutJob::default(); 0.0,
job.append( TextFormat {
&self.entry.title, font_id: FontId::new(14.0, FontFamily::Proportional),
0.0, ..Default::default()
TextFormat { },
font_id: FontId::new(14.0, FontFamily::Proportional), );
..Default::default() r.union(ui.add(Label::new(job)));
}, r.union(ui.label(&self.entry.subtitle));
); })
r.union(ui.add(Label::new(job))); .response
r.union(ui.label(&self.entry.subtitle));
})
})
.response
} }
} }

0
src/store/album.rs Normal file
View File

0
src/store/artist.rs Normal file
View File

0
src/store/genre.rs Normal file
View File

View File

@ -98,7 +98,7 @@ impl Store {
} else { } else {
let e = Error::NoProjDir; let e = Error::NoProjDir;
error!("{}", e); error!("{}", e);
std::process::exit(1); Err(e)
} }
} }
} }

1
src/store/playlist.rs Normal file
View File

@ -0,0 +1 @@
pub struct Playlist;

2
src/store/song.rs Normal file
View File

@ -0,0 +1,2 @@
#[derive(Clone, Debug, Hash)]
pub struct Song {}