wip translated ui playbar class
This commit is contained in:
parent
b94d41542f
commit
6f3b3537ad
9 changed files with 264 additions and 22 deletions
|
@ -28,6 +28,8 @@ extern "C" {}
|
||||||
fn main() -> glib::ExitCode {
|
fn main() -> glib::ExitCode {
|
||||||
gio::resources_register_include!("audrey.gresource").expect("could not register resources");
|
gio::resources_register_include!("audrey.gresource").expect("could not register resources");
|
||||||
|
|
||||||
|
ui::Playbar::ensure_type();
|
||||||
|
|
||||||
gtk::disable_setlocale();
|
gtk::disable_setlocale();
|
||||||
bindtextdomain("audrey", meson_config::LOCALEDIR).expect("failed to bind text domain");
|
bindtextdomain("audrey", meson_config::LOCALEDIR).expect("failed to bind text domain");
|
||||||
bind_textdomain_codeset("audrey", "UTF-8").expect("failed to bind textdomaincodeset");
|
bind_textdomain_codeset("audrey", "UTF-8").expect("failed to bind textdomaincodeset");
|
||||||
|
|
|
@ -5,7 +5,7 @@ audrey_sources = [
|
||||||
'playbin.vala',
|
'playbin.vala',
|
||||||
'subsonic.vala',
|
'subsonic.vala',
|
||||||
'ui/play_queue.vala',
|
'ui/play_queue.vala',
|
||||||
'ui/playbar.vala',
|
'ui/playbar.vapi',
|
||||||
'ui/setup.vala',
|
'ui/setup.vala',
|
||||||
'ui/window.vala',
|
'ui/window.vala',
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
mod song;
|
mod song;
|
||||||
pub use song::Song;
|
pub use song::Song;
|
||||||
|
|
||||||
|
mod state;
|
||||||
|
pub use state::State;
|
||||||
|
|
||||||
mod ffi {
|
mod ffi {
|
||||||
use gtk::glib;
|
use gtk::glib;
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,15 @@ mod ffi {
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn audrey_playbin_song_get_type() -> glib::ffi::GType;
|
pub fn audrey_playbin_song_get_type() -> glib::ffi::GType;
|
||||||
|
pub fn audrey_playbin_song_get_title(
|
||||||
|
self_: *mut AudreyPlaybinSong,
|
||||||
|
) -> *const std::ffi::c_char;
|
||||||
|
pub fn audrey_playbin_song_get_artist(
|
||||||
|
self_: *mut AudreyPlaybinSong,
|
||||||
|
) -> *const std::ffi::c_char;
|
||||||
|
pub fn audrey_playbin_song_get_album(
|
||||||
|
self_: *mut AudreyPlaybinSong,
|
||||||
|
) -> *const std::ffi::c_char;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,3 +34,35 @@ glib::wrapper! {
|
||||||
type_ => || ffi::audrey_playbin_song_get_type(),
|
type_ => || ffi::audrey_playbin_song_get_type(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Song {
|
||||||
|
pub fn get_title(&self) -> std::borrow::Cow<'_, str> {
|
||||||
|
use glib::translate::ToGlibPtr;
|
||||||
|
|
||||||
|
// TODO: memory management....
|
||||||
|
String::from_utf8_lossy(unsafe {
|
||||||
|
std::ffi::CStr::from_ptr(ffi::audrey_playbin_song_get_title(self.to_glib_none().0))
|
||||||
|
.to_bytes()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_artist(&self) -> std::borrow::Cow<'_, str> {
|
||||||
|
use glib::translate::ToGlibPtr;
|
||||||
|
|
||||||
|
// TODO: memory management....
|
||||||
|
String::from_utf8_lossy(unsafe {
|
||||||
|
std::ffi::CStr::from_ptr(ffi::audrey_playbin_song_get_artist(self.to_glib_none().0))
|
||||||
|
.to_bytes()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_album(&self) -> std::borrow::Cow<'_, str> {
|
||||||
|
use glib::translate::ToGlibPtr;
|
||||||
|
|
||||||
|
// TODO: memory management....
|
||||||
|
String::from_utf8_lossy(unsafe {
|
||||||
|
std::ffi::CStr::from_ptr(ffi::audrey_playbin_song_get_album(self.to_glib_none().0))
|
||||||
|
.to_bytes()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
38
src/playbin/state.rs
Normal file
38
src/playbin/state.rs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
mod ffi {
|
||||||
|
use gtk::glib;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
pub fn audrey_playbin_state_get_type() -> glib::ffi::GType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
use gtk::glib;
|
||||||
|
use glib::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||||
|
pub enum State {
|
||||||
|
Stopped,
|
||||||
|
Paused,
|
||||||
|
Playing,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<'a> glib::value::FromValue<'a> for State {
|
||||||
|
type Checker = glib::value::GenericValueTypeChecker<Self>;
|
||||||
|
|
||||||
|
unsafe fn from_value(value: &'a glib::Value) -> Self {
|
||||||
|
use glib::translate::ToGlibPtr;
|
||||||
|
|
||||||
|
match glib::gobject_ffi::g_value_get_enum(value.to_glib_none().0) {
|
||||||
|
0 => Self::Stopped,
|
||||||
|
1 => Self::Paused,
|
||||||
|
2 => Self::Playing,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StaticType for State {
|
||||||
|
fn static_type() -> glib::Type {
|
||||||
|
unsafe { glib::translate::from_glib(ffi::audrey_playbin_state_get_type()) }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
mod ffi {
|
mod ffi {
|
||||||
use std::ffi::*;
|
|
||||||
use gtk::glib;
|
use gtk::glib;
|
||||||
|
use std::ffi::*;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
|
@ -19,7 +19,8 @@ mod ffi {
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn audrey_subsonic_song_copy(ptr: *const AudreySubsonicSong) -> *mut AudreySubsonicSong;
|
pub fn audrey_subsonic_song_copy(ptr: *const AudreySubsonicSong)
|
||||||
|
-> *mut AudreySubsonicSong;
|
||||||
pub fn audrey_subsonic_song_free(ptr: *mut AudreySubsonicSong);
|
pub fn audrey_subsonic_song_free(ptr: *mut AudreySubsonicSong);
|
||||||
pub fn audrey_subsonic_song_get_type() -> glib::ffi::GType;
|
pub fn audrey_subsonic_song_get_type() -> glib::ffi::GType;
|
||||||
}
|
}
|
||||||
|
|
1
src/ui/playbar.h
Normal file
1
src/ui/playbar.h
Normal file
|
@ -0,0 +1 @@
|
||||||
|
typedef struct _AudreyUiPlaybar AudreyUiPlaybar;
|
|
@ -1,29 +1,178 @@
|
||||||
mod ffi {
|
mod imp {
|
||||||
use gtk::glib;
|
use adw::prelude::*;
|
||||||
|
use adw::subclass::prelude::*;
|
||||||
|
use glib::subclass::InitializingObject;
|
||||||
|
use gtk::{gdk, glib};
|
||||||
|
use std::cell::{Cell, RefCell};
|
||||||
|
|
||||||
#[repr(C)]
|
#[derive(glib::Properties, gtk::CompositeTemplate, Default)]
|
||||||
pub struct AudreyUiPlaybar {
|
#[properties(wrapper_type = super::Playbar)]
|
||||||
parent_instance: adw::ffi::AdwBin,
|
#[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>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[glib::object_subclass]
|
||||||
pub struct AudreyUiPlaybarClass {
|
impl ObjectSubclass for Playbar {
|
||||||
parent_class: adw::ffi::AdwBinClass,
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
#[glib::derived_properties]
|
||||||
pub fn audrey_ui_playbar_get_type() -> glib::ffi::GType;
|
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!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use gtk::glib;
|
use gtk::glib;
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct Playbar(Object<ffi::AudreyUiPlaybar, ffi::AudreyUiPlaybarClass>)
|
pub struct Playbar(ObjectSubclass<imp::Playbar>)
|
||||||
@extends adw::Bin, gtk::Widget,
|
@extends adw::Bin, gtk::Widget,
|
||||||
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget;
|
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget;
|
||||||
|
}
|
||||||
|
|
||||||
match fn {
|
mod ffi {
|
||||||
type_ => || ffi::audrey_ui_playbar_get_type(),
|
use glib::translate::IntoGlib;
|
||||||
|
use gtk::glib;
|
||||||
|
use gtk::prelude::*;
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn audrey_ui_playbar_get_type() -> glib::ffi::GType {
|
||||||
|
super::Playbar::static_type().into_glib()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,21 @@
|
||||||
[GtkTemplate (ui = "/eu/callcc/audrey/playbar.ui")]
|
// [GtkTemplate (ui = "/eu/callcc/audrey/playbar.ui")]
|
||||||
class Audrey.Ui.Playbar : Adw.Bin {
|
[CCode (cheader_filename = "ui/playbar.h")]
|
||||||
public PlaybinSong? song { get; set; }
|
public class Audrey.Ui.Playbar : Adw.Bin {
|
||||||
|
public PlaybinSong? song {
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
public Gdk.Paintable? playing_cover_art { get; set; }
|
public Gdk.Paintable? playing_cover_art { get; set; }
|
||||||
public weak Playbin playbin { get; set; }
|
public weak Playbin playbin { get; set; }
|
||||||
public bool show_cover_art { get; set; default = true; }
|
public bool show_cover_art { get; set; /*default = true;*/ }
|
||||||
|
|
||||||
public int volume {
|
public int volume { get; set; }
|
||||||
|
/*{
|
||||||
get { return playbin == null ? 100 : playbin.volume; }
|
get { return playbin == null ? 100 : playbin.volume; }
|
||||||
set { playbin.volume = value; }
|
set { playbin.volume = value; }
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
/*
|
||||||
[GtkCallback] private string format_timestamp (double s) {
|
[GtkCallback] private string format_timestamp (double s) {
|
||||||
return "%02d:%02d".printf (((int) s)/60, ((int) s)%60);
|
return "%02d:%02d".printf (((int) s)/60, ((int) s)%60);
|
||||||
}
|
}
|
||||||
|
@ -90,4 +96,5 @@ class Audrey.Ui.Playbar : Adw.Bin {
|
||||||
~Playbar () {
|
~Playbar () {
|
||||||
debug ("destroying playbar widget");
|
debug ("destroying playbar widget");
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
Loading…
Reference in a new issue