Compare commits

...

25 commits
0.4.1 ... main

Author SHA1 Message Date
Stephen Seo d90c86c894 cargo update, bump version 2024-02-28 11:53:21 +09:00
Stephen Seo f42fadd403 Update README.md
Previously, the README referenced dependency structopt, which was
replaced with dependency clap.
2023-11-28 21:42:12 +09:00
Stephen Seo f2f58047a5 Version 0.4.8 2023-11-28 15:02:27 +09:00
Stephen Seo d457098f2a Fix use of deprecated object from bindgen 2023-11-28 15:02:09 +09:00
Stephen Seo d0beff5a98 Update build dependency bindgen 2023-11-28 15:00:26 +09:00
Stephen Seo 7a860e323a Update image and wgpu dependencies 2023-11-28 12:29:35 +09:00
Stephen Seo ef234f0ec0 Replace dependency structopt with clap 2023-11-28 12:20:49 +09:00
Stephen Seo 391949cde6 Version 0.4.7 2023-11-26 15:49:48 +09:00
Stephen Seo f66880f13d Update ggez dependency 2023-11-26 15:42:04 +09:00
Stephen Seo 83bb20c246 Remove no longer needed comment in Cargo.toml 2023-06-27 18:59:12 +09:00
Stephen Seo dd868969cc Version 0.4.6 with new version of ggez 2023-06-27 10:41:04 +09:00
Stephen Seo 1dc28d7b07 Update README.md 2023-02-27 15:55:31 +09:00
Stephen Seo f7ffa62e02 Update README.md 2023-02-27 15:49:05 +09:00
Stephen Seo bcea959381 Merge branch 'devel' 2023-02-27 15:39:48 +09:00
Stephen Seo aa6fb750e7 Refactor "no-password-fix"
Refactors the fix for the use case of when MPD requires no password.
2023-02-04 21:32:31 +09:00
Stephen Seo a1706913e6 Fix timer bg not updating
This commit fixes the bg mesh (slightly-transparent-black-bg for text)
not updating when the timer-text changes size.
2023-02-04 20:41:47 +09:00
Stephen Seo e28d20a5da
Update README.md 2023-02-04 19:59:04 +09:00
Stephen Seo 4653399fe9 Backport Fix: display not working when no password
Previous implementation only worked if MPD was accessed with a password.
This commit fixes no-password access of MPD.

Backported from `devel` branch.
2023-02-04 19:56:09 +09:00
Stephen Seo e0be69df81 Impl passing password via file 2023-01-31 16:19:55 +09:00
Stephen Seo 8643542b7a
Update README.md 2023-01-31 16:05:48 +09:00
Stephen Seo e9e57c9dff Update README.md 2023-01-31 16:02:02 +09:00
Stephen Seo d1590bee0a Update README.md 2023-01-31 15:59:19 +09:00
Stephen Seo 56f6784892 Fix where display doesn't work when no password
Previous implementation only worked if MPD was accessed with a password.
This commit fixes no-password access of MPD.
2023-01-31 15:57:56 +09:00
Stephen Seo a223d8b530
Update README.md 2023-01-29 16:57:54 +09:00
Stephen Seo fad82f6448
Update README.md 2023-01-29 16:55:20 +09:00
8 changed files with 1297 additions and 1306 deletions

2408
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
[package]
name = "mpd_info_screen"
version = "0.4.1"
version = "0.4.9"
edition = "2021"
description = "Displays info on currently playing music from an MPD daemon"
license = "MIT"
@ -10,16 +10,14 @@ resolver = "2"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
structopt = "0.3"
clap = { version = "4.4", features = ["derive"] }
image = "0.24"
#ggez = "0.8.1"
# Workaround for album art not drawing bug in ggez, use commit from "devel" branch:
ggez = { git = "https://github.com/ggez/ggez.git", rev = "f87f078346729737b4691b9618eab3f95d61c8ad" }
ggez = "0.9.3"
freetype = { version = "0.7", optional = true }
wgpu = "0.14"
wgpu = "0.16"
[build-dependencies]
bindgen = { version = "0.53", optional = true }
bindgen = { version = "0.69", optional = true }
[features]
unicode_support = ["dep:freetype", "dep:bindgen"]

View file

@ -12,6 +12,11 @@ A Rust program that displays info about the currently running MPD server.
The window shows albumart (may be embedded in the audio file, or is a "cover.jpg" in the same directory as the song file), a "time-remaining"
counter, and the filename currently being played
## Known Bugs ❗❗
Currently there are no known bugs. Please report any bugs you find to the
[issue tracker](https://github.com/Stephen-Seo/mpd_info_screen/issues).
## Unicode Support
By default, unicode characters will not display properly. Build the project with
@ -30,29 +35,39 @@ or through crates.io:
# Usage
mpd_info_screen 0.3.7
Displays info on currently playing music from an MPD daemon
USAGE:
mpd_info_screen [FLAGS] [OPTIONS] <host> [port]
Usage: mpd_info_screen [OPTIONS] <HOST> [PORT]
FLAGS:
--disable-show-album disable album display
--disable-show-artist disable artist display
--disable-show-filename disable filename display
--disable-show-title disable title display
--no-scale-fill don't scale-fill the album art to the window
--pprompt input password via prompt
-h, --help Prints help information
-V, --version Prints version information
Arguments:
<HOST>
[PORT] [default: 6600]
OPTIONS:
-l, --log-level <log-level> [default: Error] [possible values: Error, Warning, Debug, Verbose]
-p <password>
-t, --text-bg-opacity <text-bg-opacity> sets the opacity of the text background (0-255) [default: 190]
Options:
-p <PASSWORD>
ARGS:
<host>
<port> [default: 6600]
--disable-show-title
disable title display
--disable-show-artist
disable artist display
--disable-show-album
disable album display
--disable-show-filename
disable filename display
--pprompt
input password via prompt
--pfile <PASSWORD_FILE>
read password from file
--no-scale-fill
don't scale-fill the album art to the window
-l, --log-level <LOG_LEVEL>
[default: error] [possible values: error, warning, debug, verbose]
-t, --text-bg-opacity <TEXT_BG_OPACITY>
sets the opacity of the text background (0-255) [default: 190]
-h, --help
Print help
-V, --version
Print version
Note that presing the Escape key when the window is focused closes the program.
@ -81,8 +96,8 @@ MIT license.
Uses dependency [image](https://crates.io/crates/image) which is licensed under
MIT license.
Uses dependency [structopt](https://crates.io/crates/structopt) which is
licensed under Apache-2.0 or MIT licenses.
Uses dependency [clap](https://crates.io/crates/clap) which is licensed under
Apache-2.0 or MIT licenses.
## Unicode Support Dependencies

View file

@ -14,7 +14,7 @@ fn main() {
let bindings = bindgen::Builder::default()
.header("src/bindgen_wrapper.h")
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.generate()
.expect("Unable to generate bindings");

View file

@ -1,5 +1,5 @@
use std::fmt::Display;
use structopt::clap::arg_enum;
use clap::ValueEnum;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum LogState {
@ -9,14 +9,12 @@ pub enum LogState {
Verbose,
}
arg_enum! {
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum LogLevel {
Error,
Warning,
Debug,
Verbose,
}
#[derive(ValueEnum, Copy, Clone, Debug, PartialEq, Eq)]
pub enum LogLevel {
Error,
Warning,
Debug,
Verbose,
}
pub fn log<T>(msg: T, state: LogState, level: LogLevel)

View file

@ -213,11 +213,17 @@ pub struct MPDDisplay {
album_string_cache: String,
album_transform: Transform,
timer_text: Text,
timer_text_len: usize,
timer_transform: Transform,
timer_x: f32,
timer_y: f32,
timer: f64,
length: f64,
cached_filename_y: f32,
cached_album_y: f32,
cached_artist_y: f32,
cached_title_y: f32,
cached_timer_y: f32,
text_bg_mesh: Option<Mesh>,
hide_text: bool,
tried_album_art_in_dir: bool,
@ -247,11 +253,17 @@ impl MPDDisplay {
title_text: Text::default(),
title_transform: Transform::default(),
timer_text: Text::new("0"),
timer_text_len: 0,
timer_transform: Transform::default(),
timer_x: INIT_FONT_SIZE_X,
timer_y: INIT_FONT_SIZE_Y,
timer: 0.0,
length: 0.0,
cached_filename_y: 0.0f32,
cached_album_y: 0.0f32,
cached_artist_y: 0.0f32,
cached_title_y: 0.0f32,
cached_timer_y: 0.0f32,
text_bg_mesh: None,
hide_text: false,
tried_album_art_in_dir: false,
@ -459,12 +471,6 @@ impl MPDDisplay {
let mut offset_y: f32 = drawable_size.1;
let mut filename_y: f32 = 0.0;
let mut album_y: f32 = 0.0;
let mut artist_y: f32 = 0.0;
let mut title_y: f32 = 0.0;
let mut timer_y: f32 = 0.0;
let set_transform = |text: &mut Text,
transform: &mut Transform,
offset_y: &mut f32,
@ -551,7 +557,7 @@ impl MPDDisplay {
&mut self.filename_text,
&mut self.filename_transform,
&mut offset_y,
&mut filename_y,
&mut self.cached_filename_y,
true,
false,
false,
@ -571,7 +577,7 @@ impl MPDDisplay {
&mut self.album_text,
&mut self.album_transform,
&mut offset_y,
&mut album_y,
&mut self.cached_album_y,
true,
false,
true,
@ -585,7 +591,7 @@ impl MPDDisplay {
&mut self.artist_text,
&mut self.artist_transform,
&mut offset_y,
&mut artist_y,
&mut self.cached_artist_y,
true,
true,
false,
@ -605,7 +611,7 @@ impl MPDDisplay {
&mut self.title_text,
&mut self.title_transform,
&mut offset_y,
&mut title_y,
&mut self.cached_title_y,
true,
false,
false,
@ -624,7 +630,7 @@ impl MPDDisplay {
&mut self.timer_text,
&mut self.timer_transform,
&mut offset_y,
&mut timer_y,
&mut self.cached_timer_y,
false,
false,
false,
@ -632,6 +638,12 @@ impl MPDDisplay {
&mut self.timer_y,
);
self.update_bg_mesh(ctx)?;
Ok(())
}
fn update_bg_mesh(&mut self, ctx: &mut Context) -> GameResult<()> {
let filename_dimensions = self
.filename_text
.dimensions(ctx)
@ -659,7 +671,7 @@ impl MPDDisplay {
DrawMode::fill(),
Rect {
x: TEXT_X_OFFSET,
y: filename_y,
y: self.cached_filename_y,
w: filename_dimensions.w,
h: filename_dimensions.h,
},
@ -671,7 +683,7 @@ impl MPDDisplay {
DrawMode::fill(),
Rect {
x: TEXT_X_OFFSET,
y: album_y,
y: self.cached_album_y,
w: album_dimensions.w,
h: album_dimensions.h,
},
@ -683,7 +695,7 @@ impl MPDDisplay {
DrawMode::fill(),
Rect {
x: TEXT_X_OFFSET,
y: artist_y,
y: self.cached_artist_y,
w: artist_dimensions.w,
h: artist_dimensions.h,
},
@ -695,7 +707,7 @@ impl MPDDisplay {
DrawMode::fill(),
Rect {
x: TEXT_X_OFFSET,
y: title_y,
y: self.cached_title_y,
w: title_dimensions.w,
h: title_dimensions.h,
},
@ -709,7 +721,7 @@ impl MPDDisplay {
DrawMode::fill(),
Rect {
x: TEXT_X_OFFSET,
y: timer_y,
y: self.cached_timer_y,
w: timer_dimensions.w,
h: timer_dimensions.h,
},
@ -918,11 +930,16 @@ impl EventHandler for MPDDisplay {
let delta = ctx.time.delta();
self.timer += delta.as_secs_f64();
let timer_diff = seconds_to_time(self.length - self.timer);
let timer_diff_len = timer_diff.len();
self.timer_text = Text::new(timer_diff);
self.timer_text.set_scale(PxScale {
x: self.timer_x,
y: self.timer_y,
});
if timer_diff_len != self.timer_text_len {
self.timer_text_len = timer_diff_len;
self.update_bg_mesh(ctx)?;
}
Ok(())
}

View file

@ -9,46 +9,48 @@ use ggez::event::winit_event::{ElementState, KeyboardInput, ModifiersState};
use ggez::event::{self, ControlFlow, EventHandler};
use ggez::input::keyboard::{self, KeyInput};
use ggez::{ContextBuilder, GameError};
use std::fs::File;
use std::io::Read;
use std::net::Ipv4Addr;
use std::path::PathBuf;
use std::thread;
use std::time::{Duration, Instant};
use structopt::StructOpt;
use clap::Parser;
use debug_log::log;
#[derive(StructOpt, Debug, Clone)]
#[structopt(name = "mpd_info_screen")]
#[derive(Parser, Debug, Clone)]
#[command(author, version, about, long_about = None)]
pub struct Opt {
host: Ipv4Addr,
#[structopt(default_value = "6600")]
#[arg(default_value = "6600")]
port: u16,
#[structopt(short = "p")]
#[arg(short = 'p')]
password: Option<String>,
#[structopt(long = "disable-show-title", help = "disable title display")]
#[arg(long = "disable-show-title", help = "disable title display")]
disable_show_title: bool,
#[structopt(long = "disable-show-artist", help = "disable artist display")]
#[arg(long = "disable-show-artist", help = "disable artist display")]
disable_show_artist: bool,
#[structopt(long = "disable-show-album", help = "disable album display")]
#[arg(long = "disable-show-album", help = "disable album display")]
disable_show_album: bool,
#[structopt(long = "disable-show-filename", help = "disable filename display")]
#[arg(long = "disable-show-filename", help = "disable filename display")]
disable_show_filename: bool,
#[structopt(long = "pprompt", help = "input password via prompt")]
#[arg(long = "pprompt", help = "input password via prompt")]
enable_prompt_password: bool,
#[structopt(
#[arg(long = "pfile", help = "read password from file")]
password_file: Option<PathBuf>,
#[arg(
long = "no-scale-fill",
help = "don't scale-fill the album art to the window"
)]
do_not_fill_scale_album_art: bool,
#[structopt(
short = "l",
#[arg(
short = 'l',
long = "log-level",
possible_values = &debug_log::LogLevel::variants(),
default_value = "Error",
case_insensitive = true,
default_value = "error",
)]
log_level: debug_log::LogLevel,
#[structopt(
#[arg(
short,
long,
help = "sets the opacity of the text background (0-255)",
@ -58,9 +60,26 @@ pub struct Opt {
}
fn main() -> Result<(), String> {
let opt = Opt::from_args();
let mut opt = Opt::parse();
println!("Got host addr == {}, port == {}", opt.host, opt.port);
// Read password from file if exists, error otherwise.
if let Some(psswd_file_path) = opt.password_file.as_ref() {
let mut file = File::open(psswd_file_path).expect("pfile/password_file should exist");
let mut content: String = String::new();
file.read_to_string(&mut content)
.expect("Should be able to read from pfile/password_file");
if content.ends_with("\r\n") {
content.truncate(content.len() - 2);
} else if content.ends_with('\n') {
content.truncate(content.len() - 1);
}
opt.password = Some(content);
}
let (mut ctx, event_loop) = ContextBuilder::new("mpd_info_screen", "Stephen Seo")
.window_setup(WindowSetup {
title: "mpd info screen".into(),

View file

@ -250,6 +250,8 @@ impl MPDHandler {
)
.map_err(|_| String::from("Failed to get TCP connection (is MPD running?)"))?;
let password_is_empty = password.is_empty();
let s = MPDHandler {
state: Arc::new(RwLock::new(MPDHandlerState {
art_data: Vec::new(),
@ -266,7 +268,7 @@ impl MPDHandler {
password,
error_text: String::new(),
can_authenticate: true,
is_authenticated: false,
is_authenticated: password_is_empty,
can_get_album_art: true,
can_get_album_art_in_dir: true,
can_get_status: true,