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;
|
||||
propagation-phase: capture;
|
||||
|
||||
prepare => $on_drag_prepare ();
|
||||
drag-begin => $on_drag_begin ();
|
||||
prepare => $on_drag_prepare () swapped;
|
||||
drag-begin => $on_drag_begin () swapped;
|
||||
}
|
||||
|
||||
DropTarget {
|
||||
|
@ -119,7 +119,7 @@ template $AudreyUiPlayQueueSong: Box {
|
|||
formats: "AudreyUiPlayQueueSong";
|
||||
preload: true;
|
||||
|
||||
drop => $on_drop ();
|
||||
drop => $on_drop () swapped;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
mod song;
|
||||
pub mod song;
|
||||
pub use song::Song;
|
||||
|
||||
mod state;
|
||||
pub use state::State;
|
||||
|
||||
mod ffi {
|
||||
pub mod ffi {
|
||||
use gtk::glib;
|
||||
|
||||
#[repr(C)]
|
||||
|
@ -31,6 +31,15 @@ mod ffi {
|
|||
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_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) {
|
||||
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;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct AudreyPlaybinSong {
|
||||
parent_instance: glib::gobject_ffi::GObject,
|
||||
_data: [u8; 0],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct AudreyPlaybinSongClass {
|
||||
parent_class: glib::gobject_ffi::GObjectClass,
|
||||
_data: [u8; 0],
|
||||
}
|
||||
|
||||
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 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;
|
||||
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")]
|
||||
public class Audrey.Ui.PlayQueue : Adw.Bin {
|
||||
private weak Playbin _playbin;
|
||||
|
|
|
@ -1,32 +1,35 @@
|
|||
mod imp {
|
||||
use std::cell::RefCell;
|
||||
//use crate::playbin;
|
||||
use gtk::{glib, prelude::*, subclass::prelude::*};
|
||||
use glib::{subclass::InitializingObject, WeakRef};
|
||||
use gtk::{gdk, gio, glib, prelude::*, subclass::prelude::*};
|
||||
use std::cell::{Cell, RefCell};
|
||||
|
||||
#[derive(gtk::CompositeTemplate, glib::Properties, Default)]
|
||||
#[template(resource = "/eu/callcc/audrey/play_queue_song.ui")]
|
||||
#[properties(wrapper_type = super::Song)]
|
||||
pub struct Song {
|
||||
#[property(get, set, default = false)]
|
||||
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,
|
||||
pub(super) playbin: RefCell<Option<WeakRef<crate::Playbin>>>,
|
||||
|
||||
//playbin: playbin::Playbin,
|
||||
connection: RefCell<u64>,
|
||||
drag_x: RefCell<f64>,
|
||||
drag_y: RefCell<f64>,
|
||||
drag_widget: RefCell<Option<gtk::ListBox>>,
|
||||
#[property(set, get)]
|
||||
draggable: Cell<bool>,
|
||||
#[property(set, get)]
|
||||
show_position: Cell<bool>,
|
||||
#[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]
|
||||
|
@ -34,10 +37,40 @@ mod imp {
|
|||
const NAME: &'static str = "AudreyUiPlayQueueSong";
|
||||
type Type = super::Song;
|
||||
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]
|
||||
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 {}
|
||||
|
||||
|
@ -46,16 +79,93 @@ mod imp {
|
|||
#[gtk::template_callbacks]
|
||||
impl Song {
|
||||
fn set_current(&self, value: bool) {
|
||||
*self.current.borrow_mut() = value;
|
||||
self.current.replace(value);
|
||||
if value {
|
||||
self.obj().add_css_class("playing");
|
||||
} else {
|
||||
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;
|
||||
|
||||
glib::wrapper! {
|
||||
|
@ -63,3 +173,116 @@ glib::wrapper! {
|
|||
@extends gtk::Box, gtk::Widget,
|
||||
@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,
|
||||
@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