musicus/src/player.rs

123 lines
3.2 KiB
Rust
Raw Normal View History

2023-10-25 17:45:32 +02:00
use crate::playlist_item::PlaylistItem;
use gtk::{gio, glib, glib::Properties, prelude::*, subclass::prelude::*};
use std::cell::{Cell, OnceCell};
2023-09-29 21:18:28 +02:00
mod imp {
use super::*;
#[derive(Properties, Debug, Default)]
#[properties(wrapper_type = super::MusicusPlayer)]
pub struct MusicusPlayer {
#[property(get, set)]
pub active: Cell<bool>,
#[property(get, set)]
pub playing: Cell<bool>,
2023-10-25 17:45:32 +02:00
#[property(get, construct_only)]
pub playlist: OnceCell<gio::ListStore>,
2023-10-26 11:48:42 +02:00
#[property(get, set = Self::set_current_index)]
2023-10-25 17:45:32 +02:00
pub current_index: Cell<u32>,
2023-11-03 16:22:58 +01:00
#[property(get, set)]
pub current_time: Cell<u32>,
#[property(get, set)]
pub remaining_time: Cell<u32>,
#[property(get, set = Self::set_position)]
pub position: Cell<f64>,
2023-09-29 21:18:28 +02:00
}
2023-10-26 11:48:42 +02:00
impl MusicusPlayer {
pub fn set_current_index(&self, index: u32) {
let playlist = self.playlist.get().unwrap();
2023-10-27 12:32:40 +02:00
2023-10-26 11:48:42 +02:00
if let Some(item) = playlist.item(self.current_index.get()) {
2023-10-27 12:32:40 +02:00
item.downcast::<PlaylistItem>()
.unwrap()
.set_is_playing(false);
2023-10-26 11:48:42 +02:00
}
self.current_index.set(index);
2023-10-27 12:32:40 +02:00
2023-10-26 11:48:42 +02:00
if let Some(item) = playlist.item(index) {
2023-10-27 12:32:40 +02:00
item.downcast::<PlaylistItem>()
.unwrap()
.set_is_playing(true);
2023-10-26 11:48:42 +02:00
}
}
2023-11-03 16:22:58 +01:00
pub fn set_position(&self, position: f64) {
self.position.set(position);
}
2023-10-26 11:48:42 +02:00
}
2023-09-29 21:18:28 +02:00
#[glib::object_subclass]
impl ObjectSubclass for MusicusPlayer {
const NAME: &'static str = "MusicusPlayer";
type Type = super::MusicusPlayer;
}
#[glib::derived_properties]
impl ObjectImpl for MusicusPlayer {}
}
glib::wrapper! {
pub struct MusicusPlayer(ObjectSubclass<imp::MusicusPlayer>);
}
impl MusicusPlayer {
pub fn new() -> Self {
2023-10-25 17:45:32 +02:00
glib::Object::builder()
.property("active", false)
.property("playing", false)
.property("playlist", gio::ListStore::new::<PlaylistItem>())
.property("current-index", 0u32)
2023-11-03 16:22:58 +01:00
.property("current-time", 0u32)
.property("remaining-time", 10000u32)
.property("position", 0.0)
2023-10-25 17:45:32 +02:00
.build()
2023-09-29 21:18:28 +02:00
}
2023-10-25 17:45:32 +02:00
pub fn append(&self, tracks: Vec<PlaylistItem>) {
let playlist = self.playlist();
2023-10-27 12:32:40 +02:00
2023-10-25 17:45:32 +02:00
for track in tracks {
playlist.append(&track);
2023-09-29 21:18:28 +02:00
}
2023-10-25 17:45:32 +02:00
self.set_active(true);
}
pub fn play(&self) {
self.set_playing(true)
2023-09-29 21:18:28 +02:00
}
pub fn pause(&self) {
2023-10-25 17:45:32 +02:00
self.set_playing(false)
2023-09-29 21:18:28 +02:00
}
2023-10-27 12:32:40 +02:00
pub fn current_item(&self) -> Option<PlaylistItem> {
let imp = self.imp();
imp.playlist
.get()
.unwrap()
.item(imp.current_index.get())
.and_downcast::<PlaylistItem>()
}
2023-11-03 16:22:58 +01:00
pub fn next(&self) {
if self.current_index() < self.playlist().n_items() - 1 {
self.set_current_index(self.current_index() + 1);
}
}
pub fn previous(&self) {
if self.current_index() > 0 {
self.set_current_index(self.current_index() - 1);
}
}
2023-09-29 21:18:28 +02:00
}
impl Default for MusicusPlayer {
fn default() -> Self {
Self::new()
}
}