2024-10-30 11:45:50 +00:00
|
|
|
mod imp {
|
|
|
|
use adw::prelude::*;
|
|
|
|
use adw::subclass::prelude::*;
|
|
|
|
use glib::subclass::InitializingObject;
|
|
|
|
use gtk::{gdk, glib};
|
|
|
|
use std::cell::{Cell, RefCell};
|
2024-10-30 10:42:03 +00:00
|
|
|
|
2024-10-30 11:45:50 +00:00
|
|
|
#[derive(glib::Properties, gtk::CompositeTemplate, Default)]
|
|
|
|
#[properties(wrapper_type = super::Playbar)]
|
|
|
|
#[template(resource = "/eu/callcc/audrey/playbar.ui")]
|
|
|
|
pub struct Playbar {
|
|
|
|
#[property(get, set)]
|
|
|
|
song: RefCell<Option<crate::playbin::Song>>,
|
|
|
|
#[property(get, set)]
|
|
|
|
playing_cover_art: RefCell<Option<gdk::Paintable>>,
|
|
|
|
#[property(get, set)]
|
|
|
|
playbin: RefCell<Option<crate::Playbin>>, // TODO: weak
|
|
|
|
#[property(get, set, default = true)]
|
|
|
|
show_cover_art: Cell<bool>,
|
|
|
|
|
|
|
|
#[property(get, set)]
|
|
|
|
volume: Cell<i32>,
|
2024-10-30 10:42:03 +00:00
|
|
|
}
|
|
|
|
|
2024-10-30 11:45:50 +00:00
|
|
|
#[glib::object_subclass]
|
|
|
|
impl ObjectSubclass for Playbar {
|
|
|
|
const NAME: &'static str = "AudreyUiPlaybar";
|
|
|
|
type Type = super::Playbar;
|
|
|
|
type ParentType = adw::Bin;
|
|
|
|
|
|
|
|
fn class_init(klass: &mut Self::Class) {
|
|
|
|
klass.bind_template();
|
|
|
|
klass.bind_template_callbacks();
|
|
|
|
}
|
|
|
|
|
|
|
|
fn instance_init(obj: &InitializingObject<Self>) {
|
|
|
|
obj.init_template();
|
|
|
|
}
|
2024-10-30 10:42:03 +00:00
|
|
|
}
|
|
|
|
|
2024-10-30 11:45:50 +00:00
|
|
|
#[glib::derived_properties]
|
|
|
|
impl ObjectImpl for Playbar {}
|
|
|
|
|
|
|
|
impl WidgetImpl for Playbar {}
|
|
|
|
|
|
|
|
impl BinImpl for Playbar {}
|
|
|
|
|
|
|
|
#[gtk::template_callbacks]
|
|
|
|
impl Playbar {
|
|
|
|
#[template_callback]
|
|
|
|
fn song_title(&self, song: Option<&crate::playbin::Song>) -> String {
|
|
|
|
match song {
|
|
|
|
None => "".to_owned(),
|
|
|
|
Some(song) => song.get_title().to_string(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[template_callback]
|
|
|
|
fn song_artist(&self, song: Option<&crate::playbin::Song>) -> String {
|
|
|
|
match song {
|
|
|
|
None => "".to_owned(),
|
|
|
|
Some(song) => song.get_artist().to_string(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[template_callback]
|
|
|
|
fn song_album(&self, song: Option<&crate::playbin::Song>) -> String {
|
|
|
|
match song {
|
|
|
|
None => "".to_owned(),
|
|
|
|
Some(song) => song.get_album().to_string(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[template_callback]
|
|
|
|
fn format_timestamp(&self, s: f64) -> String {
|
|
|
|
format!("{:02}:{:02}", (s as i64) / 64, (s as i64) % 60)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[template_callback]
|
|
|
|
fn playbin_active(&self, state: crate::playbin::State) -> bool {
|
|
|
|
state != crate::playbin::State::Stopped
|
|
|
|
}
|
|
|
|
|
|
|
|
#[template_callback]
|
|
|
|
fn can_press_play(&self, state: crate::playbin::State, n_items: u32) -> bool {
|
|
|
|
!(state == crate::playbin::State::Stopped && n_items == 0)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[template_callback]
|
|
|
|
fn play_pause_icon_name(&self, state: crate::playbin::State) -> &'static str {
|
|
|
|
match state {
|
|
|
|
crate::playbin::State::Playing => "media-playback-pause",
|
|
|
|
_ => "media-playback-start",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[template_callback]
|
|
|
|
fn mute_button_icon_name(&self, mute: bool) -> &'static str {
|
|
|
|
if mute { "audio-volume-muted" } else { "audio-volume-high" }
|
|
|
|
}
|
|
|
|
|
|
|
|
#[template_callback]
|
|
|
|
fn on_play_position_seek(&self, _range: >k::Range, _scroll_type: gtk::ScrollType, _value: f64) -> bool {
|
|
|
|
/*
|
|
|
|
if (range.adjustment.lower < range.adjustment.upper) {
|
|
|
|
this.playbin.seek ((int64) value);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
*/
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[template_callback]
|
|
|
|
fn on_skip_forward_clicked(&self) {
|
|
|
|
// this.playbin.go_to_next_track ();
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[template_callback]
|
|
|
|
fn on_skip_backward_clicked(&self) {
|
|
|
|
// this.playbin.go_to_prev_track ();
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[template_callback]
|
|
|
|
fn seek_backward(&self) {
|
|
|
|
// 10 seconds
|
|
|
|
// double new_position = playbin.position - 10.0;
|
|
|
|
// if (new_position < 0.0) new_position = 0.0;
|
|
|
|
// this.playbin.seek (new_position);
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[template_callback]
|
|
|
|
fn seek_forward(&self) {
|
|
|
|
// 10 seconds
|
|
|
|
// double new_position = playbin.position + 10.0;
|
|
|
|
// if (new_position > this.playbin.duration) new_position = this.playbin.duration;
|
|
|
|
// this.playbin.seek (new_position);
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[template_callback]
|
|
|
|
fn on_play_pause_clicked(&self) {
|
|
|
|
// if (this.playbin.state == PlaybinState.PLAYING) {
|
|
|
|
// this.playbin.pause();
|
|
|
|
// } else {
|
|
|
|
// this.playbin.play();
|
|
|
|
// }
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[template_callback]
|
|
|
|
fn on_mute_toggle(&self) {
|
|
|
|
//this.playbin.mute = !this.playbin.mute;
|
|
|
|
todo!()
|
|
|
|
}
|
2024-10-30 10:42:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
use gtk::glib;
|
|
|
|
|
|
|
|
glib::wrapper! {
|
2024-10-30 11:45:50 +00:00
|
|
|
pub struct Playbar(ObjectSubclass<imp::Playbar>)
|
2024-10-30 10:42:03 +00:00
|
|
|
@extends adw::Bin, gtk::Widget,
|
|
|
|
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget;
|
2024-10-30 11:45:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
mod ffi {
|
|
|
|
use glib::translate::IntoGlib;
|
|
|
|
use gtk::glib;
|
|
|
|
use gtk::prelude::*;
|
2024-10-30 10:42:03 +00:00
|
|
|
|
2024-10-30 11:45:50 +00:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "C" fn audrey_ui_playbar_get_type() -> glib::ffi::GType {
|
|
|
|
super::Playbar::static_type().into_glib()
|
2024-10-30 10:42:03 +00:00
|
|
|
}
|
|
|
|
}
|