Compare commits
2 commits
118b2d6f7e
...
0320e12206
Author | SHA1 | Date | |
---|---|---|---|
0320e12206 | |||
efbe32ed22 |
10 changed files with 100 additions and 160 deletions
|
@ -28,16 +28,16 @@ template $AudreyUiPlayQueue: Adw.Bin {
|
||||||
show-separators: true;
|
show-separators: true;
|
||||||
single-click-activate: true;
|
single-click-activate: true;
|
||||||
|
|
||||||
activate => $on_row_activated ();
|
activate => $on_row_activated () swapped;
|
||||||
|
|
||||||
model: NoSelection {
|
model: NoSelection {
|
||||||
model: bind template.playbin as <$AudreyPlaybin>.play_queue;
|
model: bind template.playbin as <$AudreyPlaybin>.play_queue;
|
||||||
};
|
};
|
||||||
|
|
||||||
factory: SignalListItemFactory {
|
factory: SignalListItemFactory {
|
||||||
setup => $on_song_list_setup ();
|
setup => $on_song_list_setup () swapped;
|
||||||
bind => $on_song_list_bind ();
|
bind => $on_song_list_bind () swapped;
|
||||||
unbind => $on_song_list_unbind ();
|
unbind => $on_song_list_unbind () swapped;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
6
src/ffi.rs
Normal file
6
src/ffi.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#![allow(dead_code)]
|
||||||
|
#![allow(non_camel_case_types)]
|
||||||
|
#![allow(non_snake_case)]
|
||||||
|
#![allow(non_upper_case_globals)]
|
||||||
|
|
||||||
|
include!(concat!(env!("OUT_DIR"), "/audrey_ffi.rs"));
|
|
@ -29,6 +29,7 @@ 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();
|
ui::Playbar::ensure_type();
|
||||||
|
ui::PlayQueue::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");
|
||||||
|
|
|
@ -5,7 +5,6 @@ audrey_sources = [
|
||||||
'playbin.vala',
|
'playbin.vala',
|
||||||
'rust.vapi',
|
'rust.vapi',
|
||||||
'subsonic.vala',
|
'subsonic.vala',
|
||||||
'ui/play_queue.vala',
|
|
||||||
'ui/setup.vala',
|
'ui/setup.vala',
|
||||||
'ui/window.vala',
|
'ui/window.vala',
|
||||||
]
|
]
|
||||||
|
|
|
@ -40,6 +40,7 @@ pub mod ffi {
|
||||||
to: std::ffi::c_uint,
|
to: std::ffi::c_uint,
|
||||||
);
|
);
|
||||||
pub fn audrey_playbin_remove_track(self_: *mut AudreyPlaybin, position: std::ffi::c_uint);
|
pub fn audrey_playbin_remove_track(self_: *mut AudreyPlaybin, position: std::ffi::c_uint);
|
||||||
|
pub fn audrey_playbin_select_track(self_: *mut AudreyPlaybin, position: std::ffi::c_uint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,4 +117,8 @@ impl Playbin {
|
||||||
pub fn remove_track(&self, position: u32) {
|
pub fn remove_track(&self, position: u32) {
|
||||||
unsafe { ffi::audrey_playbin_remove_track(self.to_glib_none().0, position) }
|
unsafe { ffi::audrey_playbin_remove_track(self.to_glib_none().0, position) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn select_track(&self, position: u32) {
|
||||||
|
unsafe { ffi::audrey_playbin_select_track(self.to_glib_none().0, position) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,3 +15,6 @@ void audrey_ui_play_queue_song_set_show_artist(AudreyUiPlayQueueSong *self, gboo
|
||||||
void audrey_ui_play_queue_song_set_show_cover(AudreyUiPlayQueueSong *self, gboolean show_cover);
|
void audrey_ui_play_queue_song_set_show_cover(AudreyUiPlayQueueSong *self, gboolean show_cover);
|
||||||
void audrey_ui_play_queue_song_bind(AudreyUiPlayQueueSong *self, guint position, void *song);
|
void audrey_ui_play_queue_song_bind(AudreyUiPlayQueueSong *self, guint position, void *song);
|
||||||
void audrey_ui_play_queue_song_unbind(AudreyUiPlayQueueSong *self);
|
void audrey_ui_play_queue_song_unbind(AudreyUiPlayQueueSong *self);
|
||||||
|
|
||||||
|
// ui::PlayQueue
|
||||||
|
typedef void AudreyUiPlayQueue;
|
||||||
|
|
|
@ -23,4 +23,9 @@ namespace Audrey {
|
||||||
public void unbind ();
|
public void unbind ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class Ui.PlayQueue : Adw.Bin {
|
||||||
|
public Playbin playbin { get; set; }
|
||||||
|
public bool can_clear_all { get; }
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +1,92 @@
|
||||||
pub mod song;
|
pub mod song;
|
||||||
pub use song::Song;
|
pub use song::Song;
|
||||||
|
|
||||||
mod ffi {
|
mod imp {
|
||||||
use gtk::glib;
|
use adw::{glib, prelude::*, subclass::prelude::*};
|
||||||
|
use glib::{subclass::InitializingObject, WeakRef};
|
||||||
|
|
||||||
#[repr(C)]
|
#[derive(gtk::CompositeTemplate, glib::Properties, Default)]
|
||||||
pub struct AudreyUiPlayQueue {
|
#[template(resource = "/eu/callcc/audrey/play_queue.ui")]
|
||||||
_data: [u8; 0],
|
#[properties(wrapper_type = super::PlayQueue)]
|
||||||
|
pub struct PlayQueue {
|
||||||
|
#[property(get, set)]
|
||||||
|
playbin: WeakRef<crate::Playbin>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[glib::object_subclass]
|
||||||
pub struct AudreyUiPlayQueueClass {
|
impl ObjectSubclass for PlayQueue {
|
||||||
_data: [u8; 0],
|
const NAME: &'static str = "AudreyUiPlayQueue";
|
||||||
|
type Type = super::PlayQueue;
|
||||||
|
type ParentType = adw::Bin;
|
||||||
|
|
||||||
|
fn class_init(klass: &mut Self::Class) {
|
||||||
|
klass.bind_template();
|
||||||
|
klass.bind_template_callbacks();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
fn instance_init(obj: &InitializingObject<Self>) {
|
||||||
pub fn audrey_ui_play_queue_get_type() -> glib::ffi::GType;
|
obj.init_template();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[glib::derived_properties]
|
||||||
|
impl ObjectImpl for PlayQueue {}
|
||||||
|
|
||||||
|
impl WidgetImpl for PlayQueue {}
|
||||||
|
|
||||||
|
impl BinImpl for PlayQueue {}
|
||||||
|
|
||||||
|
#[gtk::template_callbacks]
|
||||||
|
impl PlayQueue {
|
||||||
|
#[template_callback]
|
||||||
|
fn visible_child_name(&self, n_items: u32) -> &'static str {
|
||||||
|
if n_items > 0 {
|
||||||
|
"not-empty"
|
||||||
|
} else {
|
||||||
|
"empty"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[template_callback]
|
||||||
|
fn on_song_list_setup(&self, item: >k::ListItem, _factory: >k::SignalListItemFactory) {
|
||||||
|
let child = super::Song::new(&self.playbin.upgrade().unwrap());
|
||||||
|
|
||||||
|
child.set_draggable(true);
|
||||||
|
child.set_show_position(true);
|
||||||
|
child.set_show_artist(true);
|
||||||
|
child.set_show_cover(true);
|
||||||
|
|
||||||
|
item.set_child(Some(&child));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[template_callback]
|
||||||
|
fn on_song_list_bind(&self, item: >k::ListItem, _factory: >k::SignalListItemFactory) {
|
||||||
|
let child = item.child().and_downcast::<super::Song>().unwrap();
|
||||||
|
|
||||||
|
child.bind(
|
||||||
|
item.position(),
|
||||||
|
item.item().unwrap().downcast_ref::<crate::playbin::Song>().unwrap(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[template_callback]
|
||||||
|
fn on_song_list_unbind(&self, item: >k::ListItem, _factory: >k::SignalListItemFactory) {
|
||||||
|
let child = item.child().and_downcast::<super::Song>().unwrap();
|
||||||
|
|
||||||
|
child.unbind();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[template_callback]
|
||||||
|
fn on_row_activated(&self, position: u32) {
|
||||||
|
self.obj().playbin().unwrap().select_track(position);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use gtk::glib;
|
use gtk::glib;
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct PlayQueue(Object<ffi::AudreyUiPlayQueue, ffi::AudreyUiPlayQueueClass>)
|
pub struct PlayQueue(ObjectSubclass<imp::PlayQueue>)
|
||||||
@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 {
|
|
||||||
type_ => || ffi::audrey_ui_play_queue_get_type(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
/*
|
|
||||||
[GtkTemplate (ui = "/eu/callcc/audrey/play_queue.ui")]
|
|
||||||
public class Audrey.Ui.PlayQueue : Adw.Bin {
|
|
||||||
private weak Playbin _playbin;
|
|
||||||
public Playbin playbin {
|
|
||||||
get { return _playbin; }
|
|
||||||
set {
|
|
||||||
assert (_playbin == null); // only set once
|
|
||||||
_playbin = value;
|
|
||||||
|
|
||||||
_playbin.play_queue.items_changed.connect (this.on_store_items_changed);
|
|
||||||
this.can_clear_all = _playbin.play_queue.get_n_items () > 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool can_clear_all { get; private set; }
|
|
||||||
|
|
||||||
/*[GtkCallback] private void on_clear () {
|
|
||||||
this.playbin.clear ();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
private void on_store_items_changed (GLib.ListModel store, uint position, uint removed, uint added) {
|
|
||||||
this.can_clear_all = store.get_n_items () > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
[GtkCallback] private void on_song_list_setup (Gtk.SignalListItemFactory factory, Object object) {
|
|
||||||
var item = object as Gtk.ListItem;
|
|
||||||
var child = new PlayQueueSong (this.playbin);
|
|
||||||
|
|
||||||
child.draggable = true;
|
|
||||||
child.show_position = true;
|
|
||||||
child.show_artist = true;
|
|
||||||
child.show_cover = true;
|
|
||||||
|
|
||||||
item.child = child;
|
|
||||||
}
|
|
||||||
|
|
||||||
[GtkCallback] private void on_song_list_bind (Gtk.SignalListItemFactory factory, Object object) {
|
|
||||||
var item = object as Gtk.ListItem;
|
|
||||||
var child = item.child as PlayQueueSong;
|
|
||||||
|
|
||||||
child.bind (item.position, item.item as PlaybinSong);
|
|
||||||
}
|
|
||||||
|
|
||||||
[GtkCallback] private void on_song_list_unbind (Gtk.SignalListItemFactory factory, Object object) {
|
|
||||||
var item = object as Gtk.ListItem;
|
|
||||||
var child = item.child as PlayQueueSong;
|
|
||||||
|
|
||||||
child.unbind ();
|
|
||||||
}
|
|
||||||
|
|
||||||
[GtkCallback] private void on_row_activated (uint position) {
|
|
||||||
playbin.select_track (position);
|
|
||||||
}
|
|
||||||
|
|
||||||
[GtkCallback] private string visible_child_name (uint n_items) {
|
|
||||||
return n_items > 0 ? "not-empty" : "empty";
|
|
||||||
}
|
|
||||||
|
|
||||||
~PlayQueue () {
|
|
||||||
debug ("destroying play queue widget");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +1,7 @@
|
||||||
mod imp {
|
mod imp {
|
||||||
use glib::{subclass::InitializingObject, WeakRef};
|
use glib::{subclass::InitializingObject, WeakRef};
|
||||||
use gtk::{gdk, gio, glib, prelude::*, subclass::prelude::*};
|
use gtk::{gdk, gio, glib, prelude::*, subclass::prelude::*};
|
||||||
use std::cell::{RefCell, Cell};
|
use std::cell::{Cell, RefCell};
|
||||||
|
|
||||||
#[derive(gtk::CompositeTemplate, glib::Properties, Default)]
|
#[derive(gtk::CompositeTemplate, glib::Properties, Default)]
|
||||||
#[template(resource = "/eu/callcc/audrey/play_queue_song.ui")]
|
#[template(resource = "/eu/callcc/audrey/play_queue_song.ui")]
|
||||||
|
@ -208,79 +208,3 @@ impl Song {
|
||||||
.disconnect(self.imp().connection.take().unwrap());
|
.disconnect(self.imp().connection.take().unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod ffi {
|
|
||||||
use adw::prelude::*;
|
|
||||||
use glib::ffi::{gboolean, GType};
|
|
||||||
use glib::subclass::basic::InstanceStruct;
|
|
||||||
use glib::translate::{from_glib, from_glib_none, IntoGlib, IntoGlibPtr};
|
|
||||||
use gtk::glib;
|
|
||||||
use std::ffi::c_uint;
|
|
||||||
|
|
||||||
type AudreyUiPlayQueueSong = InstanceStruct<super::imp::Song>;
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
extern "C" fn audrey_ui_play_queue_song_get_type() -> GType {
|
|
||||||
super::Song::static_type().into_glib()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
extern "C" fn audrey_ui_play_queue_song_new(
|
|
||||||
playbin: *mut crate::playbin::ffi::AudreyPlaybin,
|
|
||||||
) -> *mut AudreyUiPlayQueueSong {
|
|
||||||
unsafe { super::Song::new(&from_glib_none(playbin)).into_glib_ptr() }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
extern "C" fn audrey_ui_play_queue_song_set_draggable(
|
|
||||||
self_: *mut AudreyUiPlayQueueSong,
|
|
||||||
draggable: gboolean,
|
|
||||||
) {
|
|
||||||
let self_: super::Song = unsafe { from_glib_none(self_) };
|
|
||||||
self_.set_draggable(unsafe { from_glib::<_, bool>(draggable) });
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
extern "C" fn audrey_ui_play_queue_song_set_show_position(
|
|
||||||
self_: *mut AudreyUiPlayQueueSong,
|
|
||||||
show_position: gboolean,
|
|
||||||
) {
|
|
||||||
let self_: super::Song = unsafe { from_glib_none(self_) };
|
|
||||||
self_.set_show_position(unsafe { from_glib::<_, bool>(show_position) });
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
extern "C" fn audrey_ui_play_queue_song_set_show_artist(
|
|
||||||
self_: *mut AudreyUiPlayQueueSong,
|
|
||||||
show_artist: gboolean,
|
|
||||||
) {
|
|
||||||
let self_: super::Song = unsafe { from_glib_none(self_) };
|
|
||||||
self_.set_show_artist(unsafe { from_glib::<_, bool>(show_artist) });
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
extern "C" fn audrey_ui_play_queue_song_set_show_cover(
|
|
||||||
self_: *mut AudreyUiPlayQueueSong,
|
|
||||||
show_cover: gboolean,
|
|
||||||
) {
|
|
||||||
let self_: super::Song = unsafe { from_glib_none(self_) };
|
|
||||||
self_.set_show_cover(unsafe { from_glib::<_, bool>(show_cover) });
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
extern "C" fn audrey_ui_play_queue_song_bind(
|
|
||||||
self_: *mut AudreyUiPlayQueueSong,
|
|
||||||
position: c_uint,
|
|
||||||
song: *mut crate::playbin::song::ffi::AudreyPlaybinSong,
|
|
||||||
) {
|
|
||||||
let self_: super::Song = unsafe { from_glib_none(self_) };
|
|
||||||
let song: crate::playbin::Song = unsafe { from_glib_none(song) };
|
|
||||||
self_.bind(position, &song);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
extern "C" fn audrey_ui_play_queue_song_unbind(self_: *mut AudreyUiPlayQueueSong) {
|
|
||||||
let self_: super::Song = unsafe { from_glib_none(self_) };
|
|
||||||
self_.unbind();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue