Compare commits
2 commits
f07641622e
...
b53b3d8362
Author | SHA1 | Date | |
---|---|---|---|
b53b3d8362 | |||
620d5803e6 |
9 changed files with 309 additions and 157 deletions
|
@ -110,8 +110,8 @@ template $AudreyUiPlayQueueSong: Box {
|
||||||
actions: move;
|
actions: move;
|
||||||
propagation-phase: capture;
|
propagation-phase: capture;
|
||||||
|
|
||||||
prepare => $on_drag_prepare ();
|
prepare => $on_drag_prepare () swapped;
|
||||||
drag-begin => $on_drag_begin ();
|
drag-begin => $on_drag_begin () swapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
DropTarget {
|
DropTarget {
|
||||||
|
@ -119,7 +119,7 @@ template $AudreyUiPlayQueueSong: Box {
|
||||||
formats: "AudreyUiPlayQueueSong";
|
formats: "AudreyUiPlayQueueSong";
|
||||||
preload: true;
|
preload: true;
|
||||||
|
|
||||||
drop => $on_drop ();
|
drop => $on_drop () swapped;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
mod song;
|
pub mod song;
|
||||||
pub use song::Song;
|
pub use song::Song;
|
||||||
|
|
||||||
mod state;
|
mod state;
|
||||||
pub use state::State;
|
pub use state::State;
|
||||||
|
|
||||||
mod ffi {
|
pub mod ffi {
|
||||||
use gtk::glib;
|
use gtk::glib;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -31,6 +31,15 @@ mod ffi {
|
||||||
pub fn audrey_playbin_get_duration(self_: *mut AudreyPlaybin) -> f64;
|
pub fn audrey_playbin_get_duration(self_: *mut AudreyPlaybin) -> f64;
|
||||||
pub fn audrey_playbin_get_mute(self_: *mut AudreyPlaybin) -> glib::ffi::gboolean;
|
pub fn audrey_playbin_get_mute(self_: *mut AudreyPlaybin) -> glib::ffi::gboolean;
|
||||||
pub fn audrey_playbin_set_mute(self_: *mut AudreyPlaybin, mute: glib::ffi::gboolean);
|
pub fn audrey_playbin_set_mute(self_: *mut AudreyPlaybin, mute: glib::ffi::gboolean);
|
||||||
|
pub fn audrey_playbin_get_play_queue_position(
|
||||||
|
self_: *mut AudreyPlaybin,
|
||||||
|
) -> std::ffi::c_uint;
|
||||||
|
pub fn audrey_playbin_move_track(
|
||||||
|
self_: *mut AudreyPlaybin,
|
||||||
|
from: std::ffi::c_uint,
|
||||||
|
to: std::ffi::c_uint,
|
||||||
|
);
|
||||||
|
pub fn audrey_playbin_remove_track(self_: *mut AudreyPlaybin, position: std::ffi::c_uint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,4 +104,16 @@ impl Playbin {
|
||||||
pub fn set_mute(&self, mute: bool) {
|
pub fn set_mute(&self, mute: bool) {
|
||||||
unsafe { ffi::audrey_playbin_set_mute(self.to_glib_none().0, mute.into_glib()) }
|
unsafe { ffi::audrey_playbin_set_mute(self.to_glib_none().0, mute.into_glib()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn play_queue_position(&self) -> u32 {
|
||||||
|
unsafe { ffi::audrey_playbin_get_play_queue_position(self.to_glib_none().0) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn move_track(&self, from: u32, to: u32) {
|
||||||
|
unsafe { ffi::audrey_playbin_move_track(self.to_glib_none().0, from, to) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_track(&self, position: u32) {
|
||||||
|
unsafe { ffi::audrey_playbin_remove_track(self.to_glib_none().0, position) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
mod ffi {
|
pub mod ffi {
|
||||||
use gtk::glib;
|
use gtk::glib;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct AudreyPlaybinSong {
|
pub struct AudreyPlaybinSong {
|
||||||
parent_instance: glib::gobject_ffi::GObject,
|
_data: [u8; 0],
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct AudreyPlaybinSongClass {
|
pub struct AudreyPlaybinSongClass {
|
||||||
parent_class: glib::gobject_ffi::GObjectClass,
|
_data: [u8; 0],
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
18
src/rust.h
18
src/rust.h
|
@ -1 +1,17 @@
|
||||||
typedef struct _AudreyUiPlaybar AudreyUiPlaybar;
|
#include <glib-object.h>
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
// ui::playbar
|
||||||
|
typedef void AudreyUiPlaybar;
|
||||||
|
|
||||||
|
// ui::play_queue::Song
|
||||||
|
typedef void AudreyUiPlayQueueSong;
|
||||||
|
#define AUDREY_UI_TYPE_PLAY_QUEUE_SONG (audrey_ui_play_queue_song_get_type ())
|
||||||
|
GType audrey_ui_play_queue_song_get_type(void);
|
||||||
|
AudreyUiPlayQueueSong *audrey_ui_play_queue_song_new(void *playbin);
|
||||||
|
void audrey_ui_play_queue_song_set_draggable(AudreyUiPlayQueueSong *self, gboolean draggable);
|
||||||
|
void audrey_ui_play_queue_song_set_show_position(AudreyUiPlayQueueSong *self, gboolean show_position);
|
||||||
|
void audrey_ui_play_queue_song_set_show_artist(AudreyUiPlayQueueSong *self, gboolean show_artist);
|
||||||
|
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_unbind(AudreyUiPlayQueueSong *self);
|
||||||
|
|
|
@ -9,4 +9,18 @@ namespace Audrey {
|
||||||
public int volume { get; set; }
|
public int volume { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class Ui.PlayQueueSong : Gtk.Box {
|
||||||
|
public bool draggable { get; set; }
|
||||||
|
public bool show_position { get; set; }
|
||||||
|
public bool show_artist { get; set; }
|
||||||
|
public bool show_cover { get; set; }
|
||||||
|
public bool current { get; set; }
|
||||||
|
public uint displayed_position { get; set; }
|
||||||
|
public PlaybinSong song { get; set; }
|
||||||
|
|
||||||
|
public PlayQueueSong (Playbin playbin);
|
||||||
|
public void bind (uint position, PlaybinSong song);
|
||||||
|
public void unbind ();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,3 +6,5 @@ pub use playbar::Playbar;
|
||||||
|
|
||||||
mod setup;
|
mod setup;
|
||||||
pub use setup::Setup;
|
pub use setup::Setup;
|
||||||
|
|
||||||
|
pub mod play_queue;
|
||||||
|
|
|
@ -1,116 +1,3 @@
|
||||||
// song widget+drag behavior taken from gnome music
|
|
||||||
|
|
||||||
[GtkTemplate (ui = "/eu/callcc/audrey/play_queue_song.ui")]
|
|
||||||
class Audrey.Ui.PlayQueueSong : Gtk.Box {
|
|
||||||
public bool draggable { get; set; default = false; }
|
|
||||||
public bool show_position { get; set; default = false; }
|
|
||||||
public bool show_artist { get; set; default = false; }
|
|
||||||
public bool show_cover { get; set; default = false; }
|
|
||||||
|
|
||||||
private bool _current = false;
|
|
||||||
public bool current {
|
|
||||||
get { return _current; }
|
|
||||||
set {
|
|
||||||
this._current = value;
|
|
||||||
if (value) {
|
|
||||||
this.add_css_class ("playing");
|
|
||||||
} else {
|
|
||||||
this.remove_css_class ("playing");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public uint displayed_position { get; set; }
|
|
||||||
public PlaybinSong song { get; set; }
|
|
||||||
|
|
||||||
private weak Playbin playbin;
|
|
||||||
public PlayQueueSong (Playbin playbin) {
|
|
||||||
this.playbin = playbin;
|
|
||||||
|
|
||||||
var action_group = new SimpleActionGroup ();
|
|
||||||
|
|
||||||
var remove = new SimpleAction ("remove", null);
|
|
||||||
remove.activate.connect (() => {
|
|
||||||
this.playbin.remove_track (this.displayed_position-1);
|
|
||||||
});
|
|
||||||
action_group.add_action (remove);
|
|
||||||
|
|
||||||
this.insert_action_group ("song", action_group);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ulong connection;
|
|
||||||
public void bind (uint position, PlaybinSong song) {
|
|
||||||
this.displayed_position = position+1;
|
|
||||||
this.song = song;
|
|
||||||
this.current = this.playbin.play_queue_position == position;
|
|
||||||
this.connection = this.playbin.notify["play-queue-position"].connect (() => {
|
|
||||||
this.current = this.playbin.play_queue_position == position;
|
|
||||||
});
|
|
||||||
|
|
||||||
song.need_cover_art ();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void unbind () {
|
|
||||||
this.playbin.disconnect (this.connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
[GtkCallback] private string format_duration (int duration) {
|
|
||||||
return "%02d:%02d".printf(duration/60, duration%60);
|
|
||||||
}
|
|
||||||
|
|
||||||
[GtkCallback] private string star_button_icon_name (DateTime? starred) {
|
|
||||||
return starred == null ? "non-starred" : "starred";
|
|
||||||
}
|
|
||||||
|
|
||||||
private double drag_x;
|
|
||||||
private double drag_y;
|
|
||||||
|
|
||||||
[GtkCallback] private Gdk.ContentProvider? on_drag_prepare (double x, double y) {
|
|
||||||
if (this.draggable) {
|
|
||||||
this.drag_x = x;
|
|
||||||
this.drag_y = y;
|
|
||||||
return new Gdk.ContentProvider.for_value (this);
|
|
||||||
}
|
|
||||||
else return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Gtk.ListBox? drag_widget;
|
|
||||||
|
|
||||||
[GtkCallback] private void on_drag_begin (Gtk.DragSource source, Gdk.Drag drag) {
|
|
||||||
this.drag_widget = new Gtk.ListBox ();
|
|
||||||
|
|
||||||
var drag_row = new PlayQueueSong (this.playbin);
|
|
||||||
drag_row.draggable = false;
|
|
||||||
drag_row.show_position = this.show_position;
|
|
||||||
drag_row.show_artist = this.show_artist;
|
|
||||||
drag_row.show_cover = this.show_cover;
|
|
||||||
drag_row.current = false;
|
|
||||||
drag_row.displayed_position = this.displayed_position;
|
|
||||||
drag_row.song = this.song;
|
|
||||||
drag_row.set_size_request (this.get_width (), this.get_height ());
|
|
||||||
|
|
||||||
var drag_row_real = new Gtk.ListBoxRow ();
|
|
||||||
drag_row_real.child = drag_row;
|
|
||||||
|
|
||||||
this.drag_widget.append (drag_row_real);
|
|
||||||
this.drag_widget.drag_highlight_row (drag_row_real);
|
|
||||||
|
|
||||||
var drag_icon = Gtk.DragIcon.get_for_drag (drag);
|
|
||||||
drag_icon.set("child", this.drag_widget);
|
|
||||||
drag.set_hotspot ((int) this.drag_x, (int) this.drag_y);
|
|
||||||
}
|
|
||||||
|
|
||||||
[GtkCallback] private bool on_drop (Value value, double x, double y) {
|
|
||||||
this.drag_widget = null;
|
|
||||||
this.drag_x = 0.0;
|
|
||||||
this.drag_y = 0.0;
|
|
||||||
|
|
||||||
var source = value as PlayQueueSong;
|
|
||||||
debug ("dropped %u on %u", source.displayed_position, this.displayed_position);
|
|
||||||
this.playbin.move_track (source.displayed_position-1, this.displayed_position-1);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[GtkTemplate (ui = "/eu/callcc/audrey/play_queue.ui")]
|
[GtkTemplate (ui = "/eu/callcc/audrey/play_queue.ui")]
|
||||||
public class Audrey.Ui.PlayQueue : Adw.Bin {
|
public class Audrey.Ui.PlayQueue : Adw.Bin {
|
||||||
private weak Playbin _playbin;
|
private weak Playbin _playbin;
|
||||||
|
|
|
@ -1,32 +1,35 @@
|
||||||
mod imp {
|
mod imp {
|
||||||
use std::cell::RefCell;
|
use glib::{subclass::InitializingObject, WeakRef};
|
||||||
//use crate::playbin;
|
use gtk::{gdk, gio, glib, prelude::*, subclass::prelude::*};
|
||||||
use gtk::{glib, prelude::*, subclass::prelude::*};
|
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")]
|
||||||
#[properties(wrapper_type = super::Song)]
|
#[properties(wrapper_type = super::Song)]
|
||||||
pub struct Song {
|
pub struct Song {
|
||||||
#[property(get, set, default = false)]
|
pub(super) playbin: RefCell<Option<WeakRef<crate::Playbin>>>,
|
||||||
draggable: RefCell<bool>,
|
|
||||||
#[property(get, set, default = false)]
|
|
||||||
show_position: RefCell<bool>,
|
|
||||||
#[property(get, set, default = false)]
|
|
||||||
show_artist: RefCell<bool>,
|
|
||||||
#[property(get, set, default = false)]
|
|
||||||
show_cover: RefCell<bool>,
|
|
||||||
#[property(get, set = Self::set_current, default = false)]
|
|
||||||
current: RefCell<bool>,
|
|
||||||
#[property(get, set)]
|
|
||||||
displayed_position: RefCell<u32>,
|
|
||||||
//#[property(get, set)]
|
|
||||||
//song: playbin::Song,
|
|
||||||
|
|
||||||
//playbin: playbin::Playbin,
|
#[property(set, get)]
|
||||||
connection: RefCell<u64>,
|
draggable: Cell<bool>,
|
||||||
drag_x: RefCell<f64>,
|
#[property(set, get)]
|
||||||
drag_y: RefCell<f64>,
|
show_position: Cell<bool>,
|
||||||
drag_widget: RefCell<Option<gtk::ListBox>>,
|
#[property(set, get)]
|
||||||
|
show_artist: Cell<bool>,
|
||||||
|
#[property(set, get)]
|
||||||
|
show_cover: Cell<bool>,
|
||||||
|
|
||||||
|
#[property(set = Self::set_current, get)]
|
||||||
|
current: Cell<bool>,
|
||||||
|
|
||||||
|
#[property(set, get)]
|
||||||
|
displayed_position: Cell<u32>,
|
||||||
|
#[property(get, set)]
|
||||||
|
song: RefCell<Option<crate::playbin::Song>>,
|
||||||
|
|
||||||
|
pub(super) connection: Cell<Option<glib::SignalHandlerId>>,
|
||||||
|
|
||||||
|
drag_pos: Cell<(i32, i32)>,
|
||||||
|
drag_widget: Cell<Option<gtk::ListBox>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
|
@ -34,10 +37,40 @@ mod imp {
|
||||||
const NAME: &'static str = "AudreyUiPlayQueueSong";
|
const NAME: &'static str = "AudreyUiPlayQueueSong";
|
||||||
type Type = super::Song;
|
type Type = super::Song;
|
||||||
type ParentType = gtk::Box;
|
type ParentType = gtk::Box;
|
||||||
|
|
||||||
|
fn class_init(klass: &mut Self::Class) {
|
||||||
|
klass.bind_template();
|
||||||
|
klass.bind_template_callbacks();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn instance_init(obj: &InitializingObject<Self>) {
|
||||||
|
obj.init_template();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::derived_properties]
|
#[glib::derived_properties]
|
||||||
impl ObjectImpl for Song {}
|
impl ObjectImpl for Song {
|
||||||
|
fn constructed(&self) {
|
||||||
|
self.parent_constructed();
|
||||||
|
|
||||||
|
let action_remove = gio::ActionEntry::builder("remove")
|
||||||
|
.activate(glib::clone!(
|
||||||
|
#[weak(rename_to = self_)]
|
||||||
|
self,
|
||||||
|
move |_, _, _| {
|
||||||
|
self_
|
||||||
|
.obj()
|
||||||
|
.playbin()
|
||||||
|
.remove_track(self_.obj().displayed_position() - 1)
|
||||||
|
}
|
||||||
|
))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let actions = gio::SimpleActionGroup::new();
|
||||||
|
actions.add_action_entries([action_remove]);
|
||||||
|
self.obj().insert_action_group("song", Some(&actions));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl WidgetImpl for Song {}
|
impl WidgetImpl for Song {}
|
||||||
|
|
||||||
|
@ -46,16 +79,93 @@ mod imp {
|
||||||
#[gtk::template_callbacks]
|
#[gtk::template_callbacks]
|
||||||
impl Song {
|
impl Song {
|
||||||
fn set_current(&self, value: bool) {
|
fn set_current(&self, value: bool) {
|
||||||
*self.current.borrow_mut() = value;
|
self.current.replace(value);
|
||||||
if value {
|
if value {
|
||||||
self.obj().add_css_class("playing");
|
self.obj().add_css_class("playing");
|
||||||
} else {
|
} else {
|
||||||
self.obj().remove_css_class("playing");
|
self.obj().remove_css_class("playing");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[template_callback]
|
||||||
|
fn format_duration(&self, duration: i64) -> String {
|
||||||
|
format!("{:02}:{:02}", duration / 60, duration % 60)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[template_callback]
|
||||||
|
fn star_button_icon_name(
|
||||||
|
&self, /* TODO , starred: Option<&glib::DateTime> */
|
||||||
|
) -> &'static str {
|
||||||
|
/* TODO
|
||||||
|
match starred {
|
||||||
|
None => "non-starred",
|
||||||
|
Some(_) => "starred",
|
||||||
|
} */
|
||||||
|
"non-starred"
|
||||||
|
}
|
||||||
|
|
||||||
|
// song widget+drag behavior taken from gnome music
|
||||||
|
|
||||||
|
#[template_callback]
|
||||||
|
fn on_drag_prepare(&self, x: f64, y: f64) -> Option<gdk::ContentProvider> {
|
||||||
|
if self.draggable.get() {
|
||||||
|
self.drag_pos.replace((x as i32, y as i32));
|
||||||
|
let value = self.obj().to_value();
|
||||||
|
Some(gdk::ContentProvider::for_value(&value))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[template_callback]
|
||||||
|
fn on_drag_begin(&self, drag: &gdk::Drag) {
|
||||||
|
let drag_widget = gtk::ListBox::new();
|
||||||
|
|
||||||
|
let drag_row = super::Song::new(self.obj().playbin());
|
||||||
|
drag_row.set_draggable(false);
|
||||||
|
drag_row.set_show_position(self.obj().show_position());
|
||||||
|
drag_row.set_show_artist(self.obj().show_artist());
|
||||||
|
drag_row.set_show_cover(self.obj().show_cover());
|
||||||
|
drag_row.set_current(self.obj().current());
|
||||||
|
drag_row.set_displayed_position(self.obj().displayed_position());
|
||||||
|
drag_row.set_song(self.obj().song().unwrap());
|
||||||
|
drag_row.set_size_request(self.obj().width(), self.obj().height());
|
||||||
|
|
||||||
|
let drag_row_real = gtk::ListBoxRow::new();
|
||||||
|
drag_row_real.set_child(Some(&drag_row));
|
||||||
|
|
||||||
|
drag_widget.append(&drag_row_real);
|
||||||
|
drag_widget.drag_highlight_row(&drag_row_real);
|
||||||
|
|
||||||
|
let drag_icon = gtk::DragIcon::for_drag(drag);
|
||||||
|
drag_icon.set_child(Some(&drag_widget));
|
||||||
|
let (drag_x, drag_y) = self.drag_pos.get();
|
||||||
|
drag.set_hotspot(drag_x, drag_y);
|
||||||
|
|
||||||
|
self.drag_widget.replace(Some(drag_widget));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[template_callback]
|
||||||
|
fn on_drop(&self, _value: glib::Value, _x: f64, _y: f64) -> bool {
|
||||||
|
/* FIXME: WrongValueType(ValueTypeMismatchError { actual: GValue, requested: AudreyUiPlayQueueSong })
|
||||||
|
let source: super::Song = value.get().unwrap();
|
||||||
|
|
||||||
|
source.imp().drag_widget.set(None);
|
||||||
|
|
||||||
|
self.obj().playbin().move_track(
|
||||||
|
source.displayed_position() - 1,
|
||||||
|
self.obj().displayed_position() - 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
true */
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use adw::prelude::*;
|
||||||
|
use adw::subclass::prelude::*;
|
||||||
|
use glib::Object;
|
||||||
use gtk::glib;
|
use gtk::glib;
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
|
@ -63,3 +173,116 @@ glib::wrapper! {
|
||||||
@extends gtk::Box, gtk::Widget,
|
@extends gtk::Box, gtk::Widget,
|
||||||
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Song {
|
||||||
|
pub fn new(playbin: crate::Playbin) -> Self {
|
||||||
|
let song: Self = Object::new();
|
||||||
|
song.imp().playbin.replace(Some(playbin.downgrade()));
|
||||||
|
song
|
||||||
|
}
|
||||||
|
|
||||||
|
fn playbin(&self) -> crate::Playbin {
|
||||||
|
let playbin = self.imp().playbin.borrow();
|
||||||
|
let playbin = playbin.as_ref().unwrap(); // weak
|
||||||
|
playbin.upgrade().unwrap().clone() // strong
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bind(&self, position: u32, song: &crate::playbin::Song) {
|
||||||
|
self.set_displayed_position(position + 1);
|
||||||
|
self.set_song(song);
|
||||||
|
self.set_current(self.playbin().play_queue_position() == position);
|
||||||
|
self.imp()
|
||||||
|
.connection
|
||||||
|
.replace(Some(self.playbin().connect_notify_local(
|
||||||
|
Some("play-queue-position"),
|
||||||
|
glib::clone!(
|
||||||
|
#[weak(rename_to = self_)]
|
||||||
|
self,
|
||||||
|
move |playbin: &crate::Playbin, _| {
|
||||||
|
self_.set_current(playbin.play_queue_position() == position)
|
||||||
|
}
|
||||||
|
),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unbind(&self) {
|
||||||
|
self.playbin()
|
||||||
|
.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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -191,14 +191,3 @@ glib::wrapper! {
|
||||||
@extends adw::Bin, gtk::Widget,
|
@extends adw::Bin, gtk::Widget,
|
||||||
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget;
|
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
mod ffi {
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue