Settings, took care of warnings
This commit is contained in:
parent
14ee1e69bc
commit
a060161c64
|
@ -1,3 +1,8 @@
|
|||
[target.aarch64-unknown-linux-gnu]
|
||||
linker="aarch64-linux-gnu-gcc"
|
||||
|
||||
[env]
|
||||
XMPD_MANIFEST_PATH="./manifest.json"
|
||||
XMPD_SETTINGS_PATH="./settings.toml"
|
||||
XMPD_CACHE_PATH="./cache"
|
||||
|
||||
|
|
87
Cargo.lock
generated
87
Cargo.lock
generated
|
@ -1032,6 +1032,27 @@ dependencies = [
|
|||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "5.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
|
||||
dependencies = [
|
||||
"dirs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"option-ext",
|
||||
"redox_users",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dispatch"
|
||||
version = "0.2.0"
|
||||
|
@ -2406,6 +2427,12 @@ version = "1.20.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
|
||||
|
||||
[[package]]
|
||||
name = "option-ext"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
||||
|
||||
[[package]]
|
||||
name = "orbclient"
|
||||
version = "0.3.48"
|
||||
|
@ -2687,6 +2714,17 @@ dependencies = [
|
|||
"bitflags 2.6.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"libredox",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.11.1"
|
||||
|
@ -2920,6 +2958,15 @@ dependencies = [
|
|||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.10.6"
|
||||
|
@ -3255,11 +3302,26 @@ dependencies = [
|
|||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_edit 0.22.22",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
|
@ -3279,6 +3341,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"winnow 0.6.20",
|
||||
]
|
||||
|
@ -4322,19 +4386,13 @@ dependencies = [
|
|||
"anyhow",
|
||||
"camino",
|
||||
"clap",
|
||||
"dirs",
|
||||
"env_logger",
|
||||
"log",
|
||||
"xmpd-cli",
|
||||
"xmpd-gui",
|
||||
"xmpd-manifest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xmpd-derive"
|
||||
version = "2.0.0"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"xmpd-settings",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4354,8 +4412,8 @@ dependencies = [
|
|||
"log",
|
||||
"tokio",
|
||||
"uuid",
|
||||
"xmpd-derive",
|
||||
"xmpd-manifest",
|
||||
"xmpd-settings",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4369,6 +4427,17 @@ dependencies = [
|
|||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xmpd-settings"
|
||||
version = "2.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"egui 0.27.2",
|
||||
"lazy_static",
|
||||
"serde",
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zbus"
|
||||
version = "3.15.2"
|
||||
|
|
|
@ -4,7 +4,9 @@ members=[
|
|||
"xmpd-core",
|
||||
"xmpd-manifest",
|
||||
"xmpd-gui",
|
||||
"xmpd-cli", "xmpd-dl", "xmpd-derive",
|
||||
#"xmpd-cli",
|
||||
"xmpd-dl",
|
||||
"xmpd-settings",
|
||||
# "xmpd-tui"
|
||||
]
|
||||
|
||||
|
@ -25,7 +27,7 @@ bitflags = { version = "2.6.0", features = ["serde"] }
|
|||
camino = "1.1.6"
|
||||
clap = { version = "4.5.4", features = ["derive"] }
|
||||
eframe = "0.27.2"
|
||||
egui = { version = "0.27.2", features = ["color-hex"] }
|
||||
egui = { version = "0.27.2", features = ["color-hex", "serde"] }
|
||||
egui_extras = { version = "0.27.2", features = ["all_loaders"] }
|
||||
env_logger = "0.11.3"
|
||||
futures = "0.3.30"
|
||||
|
@ -44,4 +46,5 @@ tokio = { version = "1.37.0", features = ["macros", "rt-multi-thread", "process"
|
|||
url = { version = "2.5.0", features = ["serde"] }
|
||||
uuid = { version = "1.11.0", features = ["serde", "v4"] }
|
||||
windows = { version = "0.56.0", features = ["Win32_Foundation", "Win32_Storage_FileSystem", "Win32_System_Console"] }
|
||||
zip-extensions = "0.6.2"
|
||||
zip-extensions = "0.6.20"
|
||||
dirs="5.0.1"
|
||||
|
|
|
@ -21,11 +21,13 @@ name="xmpd"
|
|||
path="src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
xmpd-cli={ path="../xmpd-cli" }
|
||||
xmpd-gui={ path="../xmpd-gui" }
|
||||
xmpd-manifest={ path="../xmpd-manifest" }
|
||||
xmpd-cli.path="../xmpd-cli"
|
||||
xmpd-gui.path="../xmpd-gui"
|
||||
xmpd-manifest.path="../xmpd-manifest"
|
||||
xmpd-settings.path = "../xmpd-settings"
|
||||
clap.workspace=true
|
||||
camino.workspace = true
|
||||
anyhow.workspace = true
|
||||
log.workspace = true
|
||||
env_logger.workspace = true
|
||||
dirs.workspace = true
|
||||
|
|
|
@ -1,18 +1,75 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::{path::PathBuf, str::FromStr};
|
||||
|
||||
|
||||
#[derive(Debug, clap::Parser)]
|
||||
pub struct CliArgs {
|
||||
/// Manifest path
|
||||
#[arg(long, short)]
|
||||
manifest: Option<camino::Utf8PathBuf>,
|
||||
#[arg(long, short, default_value_t=get_default_manifest_path())]
|
||||
manifest: camino::Utf8PathBuf,
|
||||
/// settings file path
|
||||
#[arg(long, short, default_value_t=get_default_settings_path())]
|
||||
settings: camino::Utf8PathBuf,
|
||||
/// Cache dir path
|
||||
#[arg(long, short, default_value_t=get_default_cache_path())]
|
||||
cache: camino::Utf8PathBuf,
|
||||
/// Debug mode
|
||||
#[arg(long, short)]
|
||||
pub debug: bool,
|
||||
}
|
||||
|
||||
impl CliArgs {
|
||||
pub fn manifest_path(&self) -> Option<PathBuf> {
|
||||
Some(self.manifest.clone()?.into_std_path_buf())
|
||||
pub fn manifest_path(&self) -> PathBuf {
|
||||
self.manifest.clone().into_std_path_buf()
|
||||
}
|
||||
pub fn settings_path(&self) -> PathBuf {
|
||||
self.settings.clone().into_std_path_buf()
|
||||
}
|
||||
pub fn cache_path(&self) -> PathBuf {
|
||||
self.cache.clone().into_std_path_buf()
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(irrefutable_let_patterns)] // Broken?
|
||||
fn get_default_settings_path() -> camino::Utf8PathBuf {
|
||||
if let Ok(p) = std::env::var("XMPD_SETTINGS_PATH") {
|
||||
if let Ok(p) = camino::Utf8PathBuf::from_str(&p) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(mut p) = dirs::config_dir() {
|
||||
p.push("xmpd");
|
||||
p.push("config.toml");
|
||||
return camino::Utf8PathBuf::from_path_buf(p).expect("Invalid os path");
|
||||
}
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
#[allow(irrefutable_let_patterns)] // Broken?
|
||||
fn get_default_manifest_path() -> camino::Utf8PathBuf {
|
||||
if let Ok(p) = std::env::var("XMPD_MANIFEST_PATH") {
|
||||
if let Ok(p) = camino::Utf8PathBuf::from_str(&p) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
if let Some(mut p) = dirs::config_dir() {
|
||||
p.push("xmpd");
|
||||
p.push("manifest.json");
|
||||
return camino::Utf8PathBuf::from_path_buf(p).expect("Invalid os path");
|
||||
}
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
#[allow(irrefutable_let_patterns)] // Broken?
|
||||
fn get_default_cache_path() -> camino::Utf8PathBuf {
|
||||
if let Ok(p) = std::env::var("XMPD_CACHE_PATH") {
|
||||
if let Ok(p) = camino::Utf8PathBuf::from_str(&p) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
if let Some(mut p) = dirs::cache_dir() {
|
||||
p.push("xmpd");
|
||||
return camino::Utf8PathBuf::from_path_buf(p).expect("Invalid os path");
|
||||
}
|
||||
unreachable!()
|
||||
}
|
||||
|
|
|
@ -8,10 +8,11 @@ pub fn init(cliargs: &CliArgs) {
|
|||
let level = if cliargs.debug { LevelFilter::Debug } else { LevelFilter::Info };
|
||||
env_logger::builder()
|
||||
.format_timestamp(None)
|
||||
.filter(Some("xmpd_core"), level)
|
||||
.filter(Some("xmpd"), level)
|
||||
.filter(Some("xmpd_cli"), level)
|
||||
.filter(Some("xmpd_gui"), level)
|
||||
.filter(Some("xmpd_manifest"), level)
|
||||
.filter(Some("xmpd_config"), level)
|
||||
.filter(Some("xmpd_dl"), level)
|
||||
.init();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
|
||||
use clap::Parser;
|
||||
|
||||
mod cli;
|
||||
|
@ -10,12 +8,8 @@ type Result<T> = anyhow::Result<T>;
|
|||
fn main() -> Result<()> {
|
||||
let cliargs = cli::CliArgs::parse();
|
||||
logger::init(&cliargs);
|
||||
let manifest_path;
|
||||
if let Some(mp) = cliargs.manifest_path() {
|
||||
manifest_path = mp;
|
||||
} else {
|
||||
manifest_path = PathBuf::from("manifest.json");
|
||||
};
|
||||
xmpd_gui::start(manifest_path)?;
|
||||
log::debug!("Cli: {cliargs:?}");
|
||||
xmpd_settings::Settings::get()?.load(Some(cliargs.settings_path()))?;
|
||||
xmpd_gui::start(cliargs.manifest_path())?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
use proc_macro::TokenStream;
|
||||
|
||||
#[macro_use]
|
||||
extern crate quote;
|
||||
#[macro_use]
|
||||
extern crate syn;
|
||||
extern crate proc_macro;
|
||||
|
||||
|
||||
#[proc_macro_derive(UiComponent)]
|
||||
pub fn ui_comp_impl(input: TokenStream) -> TokenStream {
|
||||
let ast: syn::DeriveInput = syn::parse(input).unwrap();
|
||||
|
||||
let name = &ast.ident;
|
||||
let vis = &ast.vis;
|
||||
let attr = &ast.attrs;
|
||||
let data = &ast.data;
|
||||
let generics = &ast.generics;
|
||||
|
||||
let gen = quote! {
|
||||
impl xmp
|
||||
|
||||
};
|
||||
|
||||
gen.into()
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
|
@ -19,7 +19,7 @@ bench = false
|
|||
|
||||
[dependencies]
|
||||
xmpd-manifest.path = "../xmpd-manifest"
|
||||
xmpd-derive.path = "../xmpd-derive"
|
||||
xmpd-settings.path = "../xmpd-settings"
|
||||
egui.workspace = true
|
||||
eframe.workspace = true
|
||||
tokio.workspace = true
|
||||
|
|
|
@ -43,12 +43,13 @@ impl CompUi for LeftNav {
|
|||
}
|
||||
|
||||
fn add_playlist_tab(ui: &mut egui::Ui, pid: &Option<uuid::Uuid>, title: &str, author: Option<&str>, song_count: usize, width: f32) {
|
||||
let theme = handle_error_ui!(xmpd_settings::Settings::get()).theme.clone();
|
||||
let wdg_rect = ui.horizontal(|ui| {
|
||||
ui.set_width(width);
|
||||
ui.add_space(5.0);
|
||||
ui.add(
|
||||
egui::Image::new(crate::data::NOTE_ICON)
|
||||
.tint(crate::data::C_ACCENT)
|
||||
.tint(theme.accent_color)
|
||||
.fit_to_exact_size(egui::Vec2::new(32.0, 32.0))
|
||||
);
|
||||
ui.vertical(|ui| {
|
||||
|
@ -57,7 +58,7 @@ fn add_playlist_tab(ui: &mut egui::Ui, pid: &Option<uuid::Uuid>, title: &str, au
|
|||
ui.label(
|
||||
RichText::new(title)
|
||||
.size(10.0)
|
||||
.color(crate::data::C_ACCENT)
|
||||
.color(theme.accent_color)
|
||||
);
|
||||
} else {
|
||||
ui.label(
|
||||
|
@ -69,13 +70,13 @@ fn add_playlist_tab(ui: &mut egui::Ui, pid: &Option<uuid::Uuid>, title: &str, au
|
|||
if let Some(author) = author {
|
||||
ui.monospace(
|
||||
RichText::new(format!("By {author}"))
|
||||
.color(crate::data::C_TEXT_DIM)
|
||||
.color(theme.dim_text_color)
|
||||
.size(8.0)
|
||||
);
|
||||
}
|
||||
ui.monospace(
|
||||
RichText::new(format!("{song_count} songs"))
|
||||
.color(crate::data::C_TEXT_DIM)
|
||||
.color(theme.dim_text_color)
|
||||
.size(8.0)
|
||||
);
|
||||
});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::sync::{MutexGuard, PoisonError};
|
||||
use std::sync::MutexGuard;
|
||||
|
||||
use crate::GuiState;
|
||||
|
||||
|
|
|
@ -13,7 +13,8 @@ component_register!(Player);
|
|||
|
||||
|
||||
impl CompUi for Player {
|
||||
fn draw(ui: &mut egui::Ui, state: &mut crate::GuiState) -> crate::Result<()> {
|
||||
fn draw(ui: &mut egui::Ui, _: &mut crate::GuiState) -> crate::Result<()> {
|
||||
let theme = xmpd_settings::Settings::get()?.theme.clone();
|
||||
let avail = ui.available_size();
|
||||
ui.vertical_centered_justified(|ui| {
|
||||
ui.add_space(3.0);
|
||||
|
@ -25,7 +26,7 @@ impl CompUi for Player {
|
|||
.show_value(false);
|
||||
ui.style_mut().spacing.slider_width = avail.x * 0.90;
|
||||
let s = Stroke {
|
||||
color: crate::data::C_ACCENT,
|
||||
color: theme.accent_color,
|
||||
width: 2.0
|
||||
};
|
||||
ui.style_mut().visuals.widgets.inactive.fg_stroke = s;
|
||||
|
@ -45,15 +46,15 @@ impl CompUi for Player {
|
|||
|
||||
|
||||
let prev = egui::Image::new(crate::data::PREV_ICON)
|
||||
.tint(crate::data::C_ACCENT)
|
||||
.tint(theme.accent_color)
|
||||
.sense(Sense::click())
|
||||
.max_size(Vec2::new(16.0, 16.0));
|
||||
let pp = egui::Image::new(pp)
|
||||
.tint(crate::data::C_ACCENT)
|
||||
.tint(theme.accent_color)
|
||||
.sense(Sense::click())
|
||||
.max_size(Vec2::new(16.0, 16.0));
|
||||
let next = egui::Image::new(crate::data::NEXT_ICON)
|
||||
.tint(crate::data::C_ACCENT)
|
||||
.tint(theme.accent_color)
|
||||
.sense(Sense::click())
|
||||
.max_size(Vec2::new(16.0, 16.0));
|
||||
if ui.add(prev).clicked() {}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use egui::{Color32, RichText, Vec2};
|
||||
use egui::{RichText, Vec2};
|
||||
use song_list_nav::SearchType;
|
||||
use xmpd_manifest::{query::QueryType, song::Song, store::BaseStore};
|
||||
use xmpd_manifest::{song::Song, store::BaseStore};
|
||||
use super::{CompGetter, CompUi};
|
||||
|
||||
pub mod song_list_nav;
|
||||
|
@ -79,23 +79,23 @@ impl CompUi for SongList {
|
|||
}
|
||||
|
||||
fn display_song_tab(ui: &mut egui::Ui, sid: &uuid::Uuid, song: &Song) {
|
||||
|
||||
let theme = handle_error_ui!(xmpd_settings::Settings::get()).theme.clone();
|
||||
let rct = ui.horizontal(|ui| {
|
||||
ui.add(
|
||||
egui::Image::new(crate::data::NOTE_ICON)
|
||||
.tint(crate::data::C_ACCENT)
|
||||
.tint(theme.accent_color)
|
||||
.fit_to_exact_size(Vec2::new(32.0, 32.0))
|
||||
);
|
||||
ui.vertical(|ui| {
|
||||
let selected_song_id = {handle_error_ui!(SongList::get()).selected_song_id};
|
||||
if selected_song_id == *sid {
|
||||
ui.label(RichText::new(song.name()).color(crate::data::C_ACCENT));
|
||||
ui.label(RichText::new(song.name()).color(theme.accent_color));
|
||||
} else {
|
||||
ui.label(song.name());
|
||||
};
|
||||
ui.monospace(
|
||||
RichText::new(format!("By {}", song.author()))
|
||||
.color(crate::data::C_TEXT_DIM)
|
||||
.color(theme.dim_text_color)
|
||||
.size(10.0)
|
||||
);
|
||||
});
|
||||
|
|
|
@ -16,10 +16,11 @@ component_register!(SongListNav);
|
|||
|
||||
impl CompUi for SongListNav {
|
||||
fn draw(ui: &mut egui::Ui, _: &mut crate::GuiState) -> crate::Result<()> {
|
||||
let theme = xmpd_settings::Settings::get()?.theme.clone();
|
||||
ui.horizontal(|ui| {
|
||||
let search_icon = egui::Image::new(crate::data::SEARCH_ICON)
|
||||
.fit_to_exact_size(egui::Vec2::new(16.0, 16.0))
|
||||
.tint(crate::data::C_ACCENT);
|
||||
.tint(theme.accent_color);
|
||||
ui.add(search_icon);
|
||||
{
|
||||
ui.text_edit_singleline(&mut handle_error_ui!(SongListNav::get()).text);
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
use super::CompUi;
|
||||
|
||||
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct TopNav;
|
||||
|
||||
component_register!(TopNav);
|
||||
|
||||
impl CompUi for TopNav {
|
||||
fn draw(ui: &mut egui::Ui, state: &mut crate::GuiState) -> crate::Result<()> {
|
||||
ui.add_space(3.0);
|
||||
|
@ -14,7 +10,15 @@ impl CompUi for TopNav {
|
|||
ui.add_space(3.0);
|
||||
egui::menu::bar(ui, |ui| {
|
||||
ui.menu_button("File", |ui| {
|
||||
// TBD
|
||||
if ui.button("Settings").clicked() {
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
ui.menu_button("Manifest", |ui| {
|
||||
if ui.button("Save").clicked() {
|
||||
handle_error_ui!(state.manifest.save());
|
||||
}
|
||||
});
|
||||
ui.menu_button("Help", |ui| {
|
||||
if ui.button("Source").clicked() {
|
||||
|
@ -22,12 +26,7 @@ impl CompUi for TopNav {
|
|||
}
|
||||
|
||||
});
|
||||
ui.menu_button("Manifest", |ui| {
|
||||
if ui.button("Save").clicked() {
|
||||
handle_error_ui!(state.manifest.save());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -1,18 +1,8 @@
|
|||
// pub const APP_ICON: egui::ImageSource = egui::include_image!("../../assets/app_icon.png");
|
||||
pub const APP_ICON_BYTES: &[u8] = include_bytes!("../../assets/app_icon.png");
|
||||
// pub const APP_ICON_BYTES: &[u8] = include_bytes!("../../assets/app_icon.png");
|
||||
pub const NOTE_ICON: egui::ImageSource = egui::include_image!("../../assets/note.svg");
|
||||
pub const SEARCH_ICON: egui::ImageSource = egui::include_image!("../../assets/search.svg");
|
||||
pub const PREV_ICON: egui::ImageSource = egui::include_image!("../../assets/prev.svg");
|
||||
pub const NEXT_ICON: egui::ImageSource = egui::include_image!("../../assets/next.svg");
|
||||
pub const PLAY_ICON: egui::ImageSource = egui::include_image!("../../assets/play.svg");
|
||||
pub const PAUSE_ICON: egui::ImageSource = egui::include_image!("../../assets/pause.svg");
|
||||
|
||||
|
||||
// TODO: Replace this with config for theming
|
||||
// pub const C_ACCENT: egui::Color32 = egui::Color32::from_rgb(51, 51, 119);
|
||||
pub const C_ACCENT: egui::Color32 = egui::Color32::from_rgb(5, 102, 146); // #0566F6
|
||||
pub const C_PRIM_BG: egui::Color32 = egui::Color32::from_rgb(31, 34, 40); // #1F2228
|
||||
pub const C_SEC_BG: egui::Color32 = egui::Color32::from_rgb(47, 53, 61); // #2f353d
|
||||
pub const C_TEXT: egui::Color32 = egui::Color32::from_rgb(223, 223, 223); // #dfdfdf
|
||||
pub const C_TEXT_DIM: egui::Color32 = egui::Color32::from_rgb(175, 175, 175 ); // #afafaf
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#![feature(async_closure)]
|
||||
|
||||
use std::{path::{Path, PathBuf}, time::Duration};
|
||||
use egui::TextStyle;
|
||||
use windows::WindowId;
|
||||
use xmpd_manifest::{store::JsonStore, Manifest};
|
||||
|
||||
#[macro_use]
|
||||
|
@ -20,21 +18,21 @@ type Result<T> = anyhow::Result<T>;
|
|||
pub fn start(manifest_path: PathBuf) -> Result<()> {
|
||||
let options = eframe::NativeOptions::default();
|
||||
let mut state = GuiState::new(&manifest_path)?;
|
||||
|
||||
let theme = xmpd_settings::Settings::get()?.theme.clone();
|
||||
let res = eframe::run_simple_native(W_NAME, options, move |ctx, _frame| {
|
||||
egui_extras::install_image_loaders(ctx);
|
||||
state.windows.clone().draw_all(ctx, &mut state);
|
||||
egui::CentralPanel::default()
|
||||
.frame(
|
||||
egui::Frame::none()
|
||||
.fill(data::C_PRIM_BG)
|
||||
.fill(theme.primary_bg_color)
|
||||
.stroke(egui::Stroke::new(
|
||||
1.0,
|
||||
data::C_SEC_BG,
|
||||
theme.secondary_bg_color,
|
||||
)),
|
||||
)
|
||||
.show(ctx, |ui| {
|
||||
ui.style_mut().visuals.override_text_color = Some(crate::data::C_TEXT);
|
||||
ui.style_mut().visuals.override_text_color = Some(theme.text_color);
|
||||
main_window::draw(ui, &mut state)
|
||||
});
|
||||
ctx.request_repaint_after(Duration::from_millis(500));
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
use egui::ViewportId;
|
||||
use xmpd_manifest::store::JsonStore;
|
||||
|
||||
use crate::{components::{CompGetter, CompUi}, GuiState};
|
||||
|
||||
|
||||
use crate::{components::CompUi, GuiState};
|
||||
|
||||
pub fn draw(ui: &mut egui::Ui, state: &mut GuiState) -> crate::Result<()> {
|
||||
// The central panel the region left after adding TopPanel's and SidePanel's
|
||||
// ui.heading(format!("Songs ({})", self.manifest.get_song_count()));
|
||||
let theme = xmpd_settings::Settings::get()?.theme.clone();
|
||||
let avail = ui.available_size();
|
||||
ui.vertical(|ui| {
|
||||
handle_error_ui!(crate::components::top_nav::TopNav::draw(ui, state));
|
||||
crate::utils::super_separator(ui, crate::data::C_ACCENT, avail.x, 2.0);
|
||||
crate::utils::super_separator(ui, theme.accent_color, avail.x, 2.0);
|
||||
let avail = ui.available_size();
|
||||
let main_height = avail.y * 0.91;
|
||||
|
||||
|
@ -35,15 +31,15 @@ pub fn draw(ui: &mut egui::Ui, state: &mut GuiState) -> crate::Result<()> {
|
|||
egui::TopBottomPanel::new(egui::panel::TopBottomSide::Bottom, "player")
|
||||
.frame(
|
||||
egui::Frame::none()
|
||||
.fill(crate::data::C_PRIM_BG)
|
||||
.fill(theme.primary_bg_color)
|
||||
.stroke(egui::Stroke::new(
|
||||
1.0,
|
||||
crate::data::C_SEC_BG,
|
||||
theme.secondary_bg_color,
|
||||
)),
|
||||
)
|
||||
.show(ui.ctx(), |ui| {
|
||||
|
||||
ui.style_mut().visuals.override_text_color = Some(crate::data::C_TEXT);
|
||||
ui.style_mut().visuals.override_text_color = Some(theme.accent_color);
|
||||
handle_error_ui!(crate::components::player::Player::draw(ui, state));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
pub fn super_separator(ui: &mut egui::Ui, color: egui::Color32, width: f32, height: f32) {
|
||||
egui::Frame::none()
|
||||
.fill(color)
|
||||
// .stroke(egui::Stroke { color: crate::data::C_ACCENT, width: 1.0 })
|
||||
.show(ui, |ui| {
|
||||
ui.set_width(width);
|
||||
ui.set_height(height);
|
||||
|
|
|
@ -7,7 +7,7 @@ pub struct ErrorW {
|
|||
}
|
||||
|
||||
impl Window for ErrorW {
|
||||
fn draw(&self, ui: &mut egui::Ui, state: &mut crate::GuiState) -> crate::Result<()> {
|
||||
fn draw(&self, ui: &mut egui::Ui, _: &mut crate::GuiState) -> crate::Result<()> {
|
||||
ui.label("Hello from other window!");
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use std::{collections::{HashMap, HashSet}, ops::Deref, sync::{Arc, Mutex}};
|
||||
use std::{collections::{HashMap, HashSet}, sync::{Arc, Mutex}};
|
||||
use egui::{ViewportBuilder, ViewportId};
|
||||
use crate::GuiState;
|
||||
|
||||
mod error;
|
||||
mod settings;
|
||||
|
||||
lazy_static::lazy_static!(
|
||||
static ref WINDOWS: Arc<Mutex<HashMap<WindowId, Box<dyn Window>>>> = Arc::new(Mutex::new(HashMap::new()));
|
||||
|
@ -16,6 +17,7 @@ pub trait Window: std::fmt::Debug + Send {
|
|||
|
||||
#[derive(Debug, Clone, Hash, PartialEq, PartialOrd, Ord, Eq)]
|
||||
pub enum WindowId {
|
||||
Settings,
|
||||
Error
|
||||
}
|
||||
|
||||
|
@ -49,7 +51,6 @@ impl Windows {
|
|||
if self.is_open(&win_id) {
|
||||
ctx.show_viewport_immediate(vp_id.clone(), builder.clone(), |ctx, _vp_class| {
|
||||
ctx.input(|inp| {
|
||||
// println!("CLose requested: {}",inp.viewport().close_requested() );
|
||||
self.toggle(win_id, !inp.viewport().close_requested());
|
||||
});
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
|
|
14
xmpd-gui/src/windows/settings.rs
Normal file
14
xmpd-gui/src/windows/settings.rs
Normal file
|
@ -0,0 +1,14 @@
|
|||
use super::Window;
|
||||
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SettingsW {
|
||||
|
||||
}
|
||||
|
||||
|
||||
impl Window for SettingsW {
|
||||
fn draw(&self, ui: &mut egui::Ui, _: &mut crate::GuiState) -> crate::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -1,15 +1,14 @@
|
|||
[package]
|
||||
name = "xmpd-derive"
|
||||
name = "xmpd-settings"
|
||||
edition = "2021"
|
||||
version.workspace = true
|
||||
repository.workspace = true
|
||||
license.workspace = true
|
||||
authors.workspace = true
|
||||
|
||||
[lib]
|
||||
proc-macro=true
|
||||
|
||||
[dependencies]
|
||||
quote = "1.0.37"
|
||||
syn = "2.0.87"
|
||||
# xmpd-gui.path = "../xmpd-gui"
|
||||
anyhow.workspace = true
|
||||
egui.workspace = true
|
||||
lazy_static.workspace = true
|
||||
serde.workspace = true
|
||||
toml = "0.8.19"
|
49
xmpd-settings/src/lib.rs
Normal file
49
xmpd-settings/src/lib.rs
Normal file
|
@ -0,0 +1,49 @@
|
|||
use std::{path::PathBuf, sync::{Arc, Mutex, MutexGuard}};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use theme::Theme;
|
||||
|
||||
mod theme;
|
||||
|
||||
lazy_static::lazy_static!(
|
||||
static ref SETTINGS: Arc<Mutex<Settings>> = Arc::new(Mutex::new(Settings::default()));
|
||||
);
|
||||
|
||||
pub type Result<T> = anyhow::Result<T>;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
pub struct Settings {
|
||||
#[serde(skip)]
|
||||
settings_path: PathBuf,
|
||||
pub theme: Theme,
|
||||
}
|
||||
|
||||
impl Settings {
|
||||
pub fn get() -> crate::Result<MutexGuard<'static, Self>> {
|
||||
match SETTINGS.lock() {
|
||||
Ok(l) => Ok(l),
|
||||
Err(e) => Err(anyhow::anyhow!(format!("{e:?}"))),
|
||||
}
|
||||
}
|
||||
pub fn load(&mut self, path: Option<PathBuf>) -> Result<()> {
|
||||
let path = path.unwrap_or(self.settings_path.clone());
|
||||
if !path.exists() {
|
||||
std::fs::write(&path, "[theme]")?;
|
||||
self.save(Some(path.clone()))?;
|
||||
}
|
||||
let data = std::fs::read_to_string(&path)?;
|
||||
let data: Self = toml::from_str(&data)?;
|
||||
*self = data;
|
||||
self.settings_path = path;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn save(&mut self, path: Option<PathBuf>) -> Result<()> {
|
||||
let path = path.unwrap_or(self.settings_path.clone());
|
||||
let data = toml::to_string_pretty(&self)?;
|
||||
std::fs::write(&path, data)?;
|
||||
self.settings_path = path;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
47
xmpd-settings/src/theme.rs
Normal file
47
xmpd-settings/src/theme.rs
Normal file
|
@ -0,0 +1,47 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Theme {
|
||||
#[serde(default="Theme::default_accent_color")]
|
||||
pub accent_color: egui::Color32,
|
||||
#[serde(default="Theme::default_primary_bg_color")]
|
||||
pub primary_bg_color: egui::Color32,
|
||||
#[serde(default="Theme::default_secondary_bg_color")]
|
||||
pub secondary_bg_color: egui::Color32,
|
||||
#[serde(default="Theme::default_text_color")]
|
||||
pub text_color: egui::Color32,
|
||||
#[serde(default="Theme::default_dim_text_color")]
|
||||
pub dim_text_color: egui::Color32,
|
||||
}
|
||||
|
||||
impl Default for Theme {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
accent_color: Self::default_accent_color(),
|
||||
primary_bg_color: Self::default_primary_bg_color(),
|
||||
secondary_bg_color: Self::default_secondary_bg_color(),
|
||||
text_color: Self::default_text_color(),
|
||||
dim_text_color: Self::default_dim_text_color(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Theme {
|
||||
fn default_accent_color() -> egui::Color32 {
|
||||
egui::Color32::from_rgb(5, 102, 146) // #0566F6
|
||||
}
|
||||
fn default_primary_bg_color() -> egui::Color32 {
|
||||
egui::Color32::from_rgb(31, 34, 40) // #1F2228
|
||||
}
|
||||
fn default_secondary_bg_color() -> egui::Color32 {
|
||||
egui::Color32::from_rgb(47, 53, 61) // #2f353d
|
||||
}
|
||||
fn default_text_color() -> egui::Color32 {
|
||||
egui::Color32::from_rgb(223, 223, 223) // #dfdfdf
|
||||
}
|
||||
fn default_dim_text_color() -> egui::Color32 {
|
||||
egui::Color32::from_rgb(175, 175, 175 ) // #afafaf
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user