mirror of
https://github.com/Dummi26/musicdb.git
synced 2025-03-10 14:13:53 +01:00
add play/pause/stop button to status bar and idle display
This commit is contained in:
parent
3e86ba921e
commit
168f51a5fc
@ -31,11 +31,8 @@ font = ''
|
||||
status_bar = '''\t
|
||||
\s0.5;?\A#\c505050by \c593D6E\A##?\a#?\A# ##\c505050on \c264524\a##\c808080?%>Year=%# (%>Year=%)## | \d'''
|
||||
|
||||
idle_top = '\t'
|
||||
idle_top = '''\t \s0.5;\c505050(\d?%>Genre=%#, %>Genre=%##)
|
||||
?\A#\c505050by \c593D6E\A##?\a#?\A# ##\c505050on \c264524\a##\c808080?%>Year=%# (%>Year=%)##'''
|
||||
|
||||
idle_side1 = '''?\A#\c505050by \c593D6E\A##
|
||||
?\a#\c505050on \c264524\a##'''
|
||||
idle_side2 = '''
|
||||
\c505050\d
|
||||
%>Year=%
|
||||
%>Genre=% '''
|
||||
idle_side1 = ''
|
||||
idle_side2 = ''
|
||||
|
@ -8,6 +8,7 @@ use crate::{
|
||||
gui_anim::AnimationController,
|
||||
gui_base::Button,
|
||||
gui_playback::{get_right_x, image_display, CurrentInfo},
|
||||
gui_playpause::PlayPause,
|
||||
gui_text::{AdvancedLabel, Label},
|
||||
};
|
||||
|
||||
@ -20,6 +21,7 @@ pub struct IdleDisplay {
|
||||
c_top_label: AdvancedLabel,
|
||||
c_side1_label: AdvancedLabel,
|
||||
c_side2_label: AdvancedLabel,
|
||||
c_buttons: PlayPause,
|
||||
cover_aspect_ratio: AnimationController<f32>,
|
||||
artist_image_aspect_ratio: AnimationController<f32>,
|
||||
cover_left: f32,
|
||||
@ -33,6 +35,7 @@ pub struct IdleDisplay {
|
||||
|
||||
impl IdleDisplay {
|
||||
pub fn new(config: GuiElemCfg) -> Self {
|
||||
let cover_bottom = 0.79;
|
||||
Self {
|
||||
config,
|
||||
idle_mode: 0.0,
|
||||
@ -56,6 +59,7 @@ impl IdleDisplay {
|
||||
),
|
||||
c_side1_label: AdvancedLabel::new(GuiElemCfg::default(), Vec2::new(0.0, 0.5), vec![]),
|
||||
c_side2_label: AdvancedLabel::new(GuiElemCfg::default(), Vec2::new(0.0, 0.5), vec![]),
|
||||
c_buttons: PlayPause::new(GuiElemCfg::default()),
|
||||
cover_aspect_ratio: AnimationController::new(
|
||||
1.0,
|
||||
1.0,
|
||||
@ -76,7 +80,7 @@ impl IdleDisplay {
|
||||
),
|
||||
cover_left: 0.01,
|
||||
cover_top: 0.21,
|
||||
cover_bottom: 0.79,
|
||||
cover_bottom,
|
||||
artist_image_top: 0.5,
|
||||
artist_image_to_cover_margin: 0.01,
|
||||
}
|
||||
@ -91,6 +95,7 @@ impl GuiElem for IdleDisplay {
|
||||
self.c_top_label.elem_mut(),
|
||||
self.c_side1_label.elem_mut(),
|
||||
self.c_side2_label.elem_mut(),
|
||||
self.c_buttons.elem_mut(),
|
||||
]
|
||||
.into_iter(),
|
||||
)
|
||||
@ -256,6 +261,14 @@ impl GuiElem for IdleDisplay {
|
||||
);
|
||||
self.c_side2_label.config_mut().pos =
|
||||
Rectangle::from_tuples((left, ai_top), (max_right, bottom));
|
||||
// limit width of c_buttons
|
||||
let buttons_right_pos = 0.99;
|
||||
let buttons_width_max = info.pos.height() * 0.08 / 0.3 / info.pos.width();
|
||||
let buttons_width = buttons_width_max.min(0.2);
|
||||
self.c_buttons.config_mut().pos = Rectangle::from_tuples(
|
||||
(buttons_right_pos - buttons_width, 0.86),
|
||||
(buttons_right_pos, 0.94),
|
||||
);
|
||||
}
|
||||
}
|
||||
fn config(&self) -> &GuiElemCfg {
|
||||
|
207
musicdb-client/src/gui_playpause.rs
Normal file
207
musicdb-client/src/gui_playpause.rs
Normal file
@ -0,0 +1,207 @@
|
||||
use musicdb_lib::server::Command;
|
||||
use speedy2d::{color::Color, dimen::Vec2, shape::Rectangle, Graphics2D};
|
||||
|
||||
use crate::{
|
||||
gui::{DrawInfo, GuiAction, GuiElem, GuiElemCfg},
|
||||
gui_base::{Button, Panel},
|
||||
};
|
||||
|
||||
pub struct PlayPause {
|
||||
config: GuiElemCfg,
|
||||
to_zero: Button<[Panel<()>; 1]>,
|
||||
play_pause: Button<[PlayPauseDisplay; 1]>,
|
||||
to_end: Button<[NextSongShape; 1]>,
|
||||
}
|
||||
|
||||
impl PlayPause {
|
||||
pub fn new(config: GuiElemCfg) -> Self {
|
||||
Self {
|
||||
config,
|
||||
to_zero: Button::new(
|
||||
GuiElemCfg::at(Rectangle::from_tuples((0.0, 0.0), (0.3, 1.0))),
|
||||
|_| vec![GuiAction::SendToServer(Command::Stop)],
|
||||
[Panel::with_background(
|
||||
GuiElemCfg::at(Rectangle::from_tuples((0.2, 0.2), (0.8, 0.8))),
|
||||
(),
|
||||
Color::MAGENTA,
|
||||
)],
|
||||
),
|
||||
play_pause: Button::new(
|
||||
GuiElemCfg::at(Rectangle::from_tuples((0.35, 0.0), (0.65, 1.0))),
|
||||
|btn| {
|
||||
vec![GuiAction::SendToServer(if btn.children[0].is_playing {
|
||||
Command::Pause
|
||||
} else {
|
||||
Command::Resume
|
||||
})]
|
||||
},
|
||||
[PlayPauseDisplay::new(GuiElemCfg::at(
|
||||
Rectangle::from_tuples((0.2, 0.2), (0.8, 0.8)),
|
||||
))],
|
||||
),
|
||||
to_end: Button::new(
|
||||
GuiElemCfg::at(Rectangle::from_tuples((0.7, 0.0), (1.0, 1.0))),
|
||||
|_| vec![GuiAction::SendToServer(Command::NextSong)],
|
||||
[NextSongShape::new(GuiElemCfg::at(Rectangle::from_tuples(
|
||||
(0.2, 0.2),
|
||||
(0.8, 0.8),
|
||||
)))],
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct PlayPauseDisplay {
|
||||
config: GuiElemCfg,
|
||||
is_playing: bool,
|
||||
}
|
||||
impl PlayPauseDisplay {
|
||||
pub fn new(config: GuiElemCfg) -> Self {
|
||||
Self {
|
||||
config,
|
||||
is_playing: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl GuiElem for PlayPauseDisplay {
|
||||
fn draw(&mut self, info: &mut DrawInfo, g: &mut Graphics2D) {
|
||||
self.is_playing = info.database.playing;
|
||||
if info.database.playing {
|
||||
g.draw_rectangle(
|
||||
Rectangle::from_tuples(
|
||||
(
|
||||
info.pos.top_left().x + info.pos.width() * 0.2,
|
||||
info.pos.top_left().y,
|
||||
),
|
||||
(
|
||||
info.pos.top_left().x + info.pos.width() * 0.4,
|
||||
info.pos.bottom_right().y,
|
||||
),
|
||||
),
|
||||
Color::BLUE,
|
||||
);
|
||||
g.draw_rectangle(
|
||||
Rectangle::from_tuples(
|
||||
(
|
||||
info.pos.bottom_right().x - info.pos.width() * 0.4,
|
||||
info.pos.top_left().y,
|
||||
),
|
||||
(
|
||||
info.pos.bottom_right().x - info.pos.width() * 0.2,
|
||||
info.pos.bottom_right().y,
|
||||
),
|
||||
),
|
||||
Color::BLUE,
|
||||
);
|
||||
} else {
|
||||
g.draw_triangle(
|
||||
[
|
||||
*info.pos.top_left(),
|
||||
Vec2::new(
|
||||
info.pos.bottom_right().x,
|
||||
(info.pos.top_left().y + info.pos.bottom_right().y) / 2.0,
|
||||
),
|
||||
info.pos.bottom_left(),
|
||||
],
|
||||
Color::GREEN,
|
||||
);
|
||||
}
|
||||
}
|
||||
fn config(&self) -> &GuiElemCfg {
|
||||
&self.config
|
||||
}
|
||||
fn config_mut(&mut self) -> &mut GuiElemCfg {
|
||||
&mut self.config
|
||||
}
|
||||
fn children(&mut self) -> Box<dyn Iterator<Item = &mut dyn GuiElem> + '_> {
|
||||
Box::new([].into_iter())
|
||||
}
|
||||
fn any(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
fn any_mut(&mut self) -> &mut dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
fn elem(&self) -> &dyn GuiElem {
|
||||
self
|
||||
}
|
||||
fn elem_mut(&mut self) -> &mut dyn GuiElem {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
struct NextSongShape {
|
||||
config: GuiElemCfg,
|
||||
}
|
||||
impl NextSongShape {
|
||||
pub fn new(config: GuiElemCfg) -> Self {
|
||||
Self { config }
|
||||
}
|
||||
}
|
||||
impl GuiElem for NextSongShape {
|
||||
fn draw(&mut self, info: &mut DrawInfo, g: &mut Graphics2D) {
|
||||
let top = *info.pos.top_left();
|
||||
let bottom = info.pos.bottom_left();
|
||||
let right = Vec2::new(info.pos.bottom_right().x, (top.y + bottom.y) / 2.0);
|
||||
g.draw_triangle([top, right, bottom], Color::CYAN);
|
||||
let half_width = info.pos.width() * 0.04;
|
||||
let top_right = Vec2::new(info.pos.top_right().x - half_width, info.pos.top_left().y);
|
||||
let bottom_right = Vec2::new(
|
||||
info.pos.top_right().x - half_width,
|
||||
info.pos.bottom_right().y,
|
||||
);
|
||||
g.draw_line(top_right, bottom_right, 2.0 * half_width, Color::CYAN);
|
||||
}
|
||||
fn config(&self) -> &GuiElemCfg {
|
||||
&self.config
|
||||
}
|
||||
fn config_mut(&mut self) -> &mut GuiElemCfg {
|
||||
&mut self.config
|
||||
}
|
||||
fn children(&mut self) -> Box<dyn Iterator<Item = &mut dyn GuiElem> + '_> {
|
||||
Box::new([].into_iter())
|
||||
}
|
||||
fn any(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
fn any_mut(&mut self) -> &mut dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
fn elem(&self) -> &dyn GuiElem {
|
||||
self
|
||||
}
|
||||
fn elem_mut(&mut self) -> &mut dyn GuiElem {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl GuiElem for PlayPause {
|
||||
fn config(&self) -> &GuiElemCfg {
|
||||
&self.config
|
||||
}
|
||||
fn config_mut(&mut self) -> &mut GuiElemCfg {
|
||||
&mut self.config
|
||||
}
|
||||
fn children(&mut self) -> Box<dyn Iterator<Item = &mut dyn GuiElem> + '_> {
|
||||
Box::new(
|
||||
[
|
||||
self.to_zero.elem_mut(),
|
||||
self.play_pause.elem_mut(),
|
||||
self.to_end.elem_mut(),
|
||||
]
|
||||
.into_iter(),
|
||||
)
|
||||
}
|
||||
fn any(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
fn any_mut(&mut self) -> &mut dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
fn elem(&self) -> &dyn GuiElem {
|
||||
self
|
||||
}
|
||||
fn elem_mut(&mut self) -> &mut dyn GuiElem {
|
||||
self
|
||||
}
|
||||
}
|
@ -5,7 +5,9 @@ use speedy2d::{color::Color, dimen::Vec2, shape::Rectangle};
|
||||
use crate::{
|
||||
gui::{DrawInfo, GuiElem, GuiElemCfg},
|
||||
gui_anim::AnimationController,
|
||||
gui_base::Panel,
|
||||
gui_playback::{image_display, CurrentInfo},
|
||||
gui_playpause::PlayPause,
|
||||
gui_text::AdvancedLabel,
|
||||
};
|
||||
|
||||
@ -15,6 +17,7 @@ pub struct StatusBar {
|
||||
current_info: CurrentInfo,
|
||||
cover_aspect_ratio: AnimationController<f32>,
|
||||
c_song_label: AdvancedLabel,
|
||||
c_buttons: PlayPause,
|
||||
}
|
||||
|
||||
impl StatusBar {
|
||||
@ -33,13 +36,14 @@ impl StatusBar {
|
||||
Instant::now(),
|
||||
),
|
||||
c_song_label: AdvancedLabel::new(GuiElemCfg::default(), Vec2::new(0.0, 0.5), vec![]),
|
||||
c_buttons: PlayPause::new(GuiElemCfg::default()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl GuiElem for StatusBar {
|
||||
fn children(&mut self) -> Box<dyn Iterator<Item = &mut dyn GuiElem> + '_> {
|
||||
Box::new([self.c_song_label.elem_mut()].into_iter())
|
||||
Box::new([self.c_song_label.elem_mut(), self.c_buttons.elem_mut()].into_iter())
|
||||
}
|
||||
fn draw(&mut self, info: &mut DrawInfo, g: &mut speedy2d::Graphics2D) {
|
||||
self.current_info.update(info, g);
|
||||
@ -71,12 +75,20 @@ impl GuiElem for StatusBar {
|
||||
if let Some(h) = &info.helper {
|
||||
h.request_redraw();
|
||||
}
|
||||
// limit width of c_buttons
|
||||
let buttons_right_pos = 0.99;
|
||||
let buttons_width_max = info.pos.height() * 0.7 / 0.3 / info.pos.width();
|
||||
let buttons_width = buttons_width_max.min(0.2);
|
||||
self.c_buttons.config_mut().pos = Rectangle::from_tuples(
|
||||
(buttons_right_pos - buttons_width, 0.15),
|
||||
(buttons_right_pos, 0.85),
|
||||
);
|
||||
self.c_song_label.config_mut().pos = Rectangle::from_tuples(
|
||||
(
|
||||
self.cover_aspect_ratio.value * info.pos.height() / info.pos.width(),
|
||||
0.0,
|
||||
),
|
||||
(1.0, 1.0),
|
||||
(buttons_right_pos - buttons_width, 1.0),
|
||||
);
|
||||
}
|
||||
// draw cover
|
||||
|
@ -34,6 +34,8 @@ mod gui_notif;
|
||||
#[cfg(feature = "speedy2d")]
|
||||
mod gui_playback;
|
||||
#[cfg(feature = "speedy2d")]
|
||||
mod gui_playpause;
|
||||
#[cfg(feature = "speedy2d")]
|
||||
mod gui_queue;
|
||||
#[cfg(feature = "speedy2d")]
|
||||
mod gui_screen;
|
||||
|
Loading…
Reference in New Issue
Block a user