This commit is contained in:
Erica Z 2024-10-29 15:46:33 +01:00
parent 4193fb72c2
commit 1f289ecf1e
18 changed files with 137 additions and 53 deletions

View file

@ -1,11 +1,11 @@
using Gtk 4.0; using Gtk 4.0;
using Adw 1; using Adw 1;
template $UiPlayQueue: Adw.Bin { template $AudreyUiPlayQueue: Adw.Bin {
name: "play-queue"; name: "play-queue";
child: Stack { child: Stack {
visible-child-name: bind $visible_child_name (template.playbin as <$Playbin>.play-queue-length) as <string>; visible-child-name: bind $visible_child_name (template.playbin as <$AudreyPlaybin>.play-queue-length) as <string>;
StackPage { StackPage {
name: "empty"; name: "empty";
@ -31,7 +31,7 @@ template $UiPlayQueue: Adw.Bin {
activate => $on_row_activated (); activate => $on_row_activated ();
model: NoSelection { model: NoSelection {
model: bind template.playbin as <$Playbin>.play_queue; model: bind template.playbin as <$AudreyPlaybin>.play_queue;
}; };
factory: SignalListItemFactory { factory: SignalListItemFactory {

View file

@ -1,6 +1,6 @@
using Gtk 4.0; using Gtk 4.0;
template $UiPlayQueueSong: Box { template $AudreyUiPlayQueueSong: Box {
height-request: 48; height-request: 48;
spacing: 12; spacing: 12;
margin-start: 6; margin-start: 6;
@ -35,7 +35,7 @@ template $UiPlayQueueSong: Box {
margin-top: 1; margin-top: 1;
margin-bottom: 1; margin-bottom: 1;
pixel-size: 50; pixel-size: 50;
paintable: bind template.song as <$PlaybinSong>.thumbnail; paintable: bind template.song as <$AudreyPlaybinSong>.thumbnail;
} }
Box title_box { Box title_box {
@ -58,7 +58,7 @@ template $UiPlayQueueSong: Box {
max-width-chars: 90; max-width-chars: 90;
justify: fill; justify: fill;
label: bind template.song as <$PlaybinSong>.title; label: bind template.song as <$AudreyPlaybinSong>.title;
} }
Label { Label {
@ -71,7 +71,7 @@ template $UiPlayQueueSong: Box {
max-width-chars: 90; max-width-chars: 90;
justify: fill; justify: fill;
label: bind template.song as <$PlaybinSong>.artist; label: bind template.song as <$AudreyPlaybinSong>.artist;
} }
} }
} }
@ -83,12 +83,12 @@ template $UiPlayQueueSong: Box {
single-line-mode: true; single-line-mode: true;
styles [ "numeric", "dim-label" ] styles [ "numeric", "dim-label" ]
label: bind $format_duration (template.song as <$PlaybinSong>.duration) as <string>; label: bind $format_duration (template.song as <$AudreyPlaybinSong>.duration) as <string>;
} }
Button { Button {
focusable: true; focusable: true;
// TODO icon-name: bind $star_button_icon_name (template.song as <$PlaybinSong>.starred) as <string>; // TODO icon-name: bind $star_button_icon_name (template.song as <$AudreyPlaybinSong>.starred) as <string>;
icon-name: bind $star_button_icon_name () as <string>; icon-name: bind $star_button_icon_name () as <string>;
styles [ "flat" ] styles [ "flat" ]
valign: center; valign: center;
@ -116,7 +116,7 @@ template $UiPlayQueueSong: Box {
DropTarget { DropTarget {
actions: move; actions: move;
formats: "UiPlayQueueSong"; formats: "AudreyUiPlayQueueSong";
preload: true; preload: true;
drop => $on_drop (); drop => $on_drop ();

View file

@ -1,7 +1,7 @@
using Gtk 4.0; using Gtk 4.0;
using Adw 1; using Adw 1;
template $UiPlaybar: Adw.Bin { template $AudreyUiPlaybar: Adw.Bin {
child: CenterBox { child: CenterBox {
hexpand: true; hexpand: true;
styles [ styles [
@ -66,7 +66,7 @@ template $UiPlaybar: Adw.Bin {
"numeric", "numeric",
] ]
label: bind $format_timestamp (template.playbin as <$Playbin>.position) as <string>; label: bind $format_timestamp (template.playbin as <$AudreyPlaybin>.position) as <string>;
} }
[center] [center]
@ -74,12 +74,12 @@ template $UiPlaybar: Adw.Bin {
name: "seek-scale"; name: "seek-scale";
orientation: horizontal; orientation: horizontal;
width-request: 400; width-request: 400;
sensitive: bind $playbin_active (template.playbin as <$Playbin>.state as <$PlaybinState>) as <bool>; sensitive: bind $playbin_active (template.playbin as <$AudreyPlaybin>.state as <$AudreyPlaybinState>) as <bool>;
adjustment: Adjustment { adjustment: Adjustment {
lower: 0; lower: 0;
value: bind template.playbin as <$Playbin>.position; value: bind template.playbin as <$AudreyPlaybin>.position;
upper: bind template.playbin as <$Playbin>.duration; upper: bind template.playbin as <$AudreyPlaybin>.duration;
}; };
change-value => $on_play_position_seek (); change-value => $on_play_position_seek ();
@ -92,7 +92,7 @@ template $UiPlaybar: Adw.Bin {
"numeric", "numeric",
] ]
label: bind $format_timestamp (template.playbin as <$Playbin>.duration) as <string>; label: bind $format_timestamp (template.playbin as <$AudreyPlaybin>.duration) as <string>;
} }
} }
@ -103,7 +103,7 @@ template $UiPlaybar: Adw.Bin {
Button { Button {
icon-name: "media-skip-backward"; icon-name: "media-skip-backward";
valign: center; valign: center;
sensitive: bind $playbin_active (template.playbin as <$Playbin>.state as <$PlaybinState>) as <bool>; sensitive: bind $playbin_active (template.playbin as <$AudreyPlaybin>.state as <$AudreyPlaybinState>) as <bool>;
clicked => $on_skip_backward_clicked (); clicked => $on_skip_backward_clicked ();
} }
@ -111,15 +111,15 @@ template $UiPlaybar: Adw.Bin {
Button { Button {
icon-name: "media-seek-backward"; icon-name: "media-seek-backward";
valign: center; valign: center;
sensitive: bind $playbin_active (template.playbin as <$Playbin>.state as <$PlaybinState>) as <bool>; sensitive: bind $playbin_active (template.playbin as <$AudreyPlaybin>.state as <$AudreyPlaybinState>) as <bool>;
clicked => $seek_backward (); clicked => $seek_backward ();
} }
Button { Button {
icon-name: bind $play_pause_icon_name (template.playbin as <$Playbin>.state as <$PlaybinState>) as <string>; icon-name: bind $play_pause_icon_name (template.playbin as <$AudreyPlaybin>.state as <$AudreyPlaybinState>) as <string>;
valign: center; valign: center;
sensitive: bind $can_press_play (template.playbin as <$Playbin>.state as <$PlaybinState>, template.playbin as <$Playbin>.play-queue-length) as <bool>; sensitive: bind $can_press_play (template.playbin as <$AudreyPlaybin>.state as <$AudreyPlaybinState>, template.playbin as <$AudreyPlaybin>.play-queue-length) as <bool>;
clicked => $on_play_pause_clicked (); clicked => $on_play_pause_clicked ();
} }
@ -127,7 +127,7 @@ template $UiPlaybar: Adw.Bin {
Button { Button {
icon-name: "media-seek-forward"; icon-name: "media-seek-forward";
valign: center; valign: center;
sensitive: bind $playbin_active (template.playbin as <$Playbin>.state as <$PlaybinState>) as <bool>; sensitive: bind $playbin_active (template.playbin as <$AudreyPlaybin>.state as <$AudreyPlaybinState>) as <bool>;
clicked => $seek_forward (); clicked => $seek_forward ();
} }
@ -135,7 +135,7 @@ template $UiPlaybar: Adw.Bin {
Button { Button {
icon-name: "media-skip-forward"; icon-name: "media-skip-forward";
valign: center; valign: center;
sensitive: bind $playbin_active (template.playbin as <$Playbin>.state as <$PlaybinState>) as <bool>; sensitive: bind $playbin_active (template.playbin as <$AudreyPlaybin>.state as <$AudreyPlaybinState>) as <bool>;
clicked => $on_skip_forward_clicked (); clicked => $on_skip_forward_clicked ();
} }
@ -150,7 +150,7 @@ template $UiPlaybar: Adw.Bin {
} }
Button { Button {
icon-name: bind $mute_button_icon_name (template.playbin as <$Playbin>.mute) as <string>; icon-name: bind $mute_button_icon_name (template.playbin as <$AudreyPlaybin>.mute) as <string>;
valign: center; valign: center;
clicked => $on_mute_toggle (); clicked => $on_mute_toggle ();

View file

@ -1,7 +1,7 @@
using Gtk 4.0; using Gtk 4.0;
using Adw 1; using Adw 1;
template $UiSetup: Adw.PreferencesDialog { template $AudreyUiSetup: Adw.PreferencesDialog {
title: _("Setup"); title: _("Setup");
Adw.ToolbarView { Adw.ToolbarView {

View file

@ -1,7 +1,7 @@
using Gtk 4.0; using Gtk 4.0;
using Adw 1; using Adw 1;
template $UiWindow: Adw.ApplicationWindow { template $AudreyUiWindow: Adw.ApplicationWindow {
title: _("audrey"); title: _("audrey");
default-width: 800; default-width: 800;
default-height: 600; default-height: 600;
@ -109,7 +109,7 @@ template $UiWindow: Adw.ApplicationWindow {
} }
} }
$UiPlayQueue play_queue { $AudreyUiPlayQueue play_queue {
hexpand: true; hexpand: true;
halign: fill; halign: fill;
@ -126,7 +126,7 @@ template $UiWindow: Adw.ApplicationWindow {
}; };
[bottom] [bottom]
$UiPlaybar playbar { $AudreyUiPlaybar playbar {
song: bind template.song; song: bind template.song;
playbin: bind template.playbin; playbin: bind template.playbin;
playing_cover_art: bind template.playing_cover_art; playing_cover_art: bind template.playing_cover_art;

View file

@ -34,4 +34,5 @@ audrey_c = static_library(
'--gresources', '--gresources',
meson.project_source_root() / 'resources/audrey.gresource.xml', meson.project_source_root() / 'resources/audrey.gresource.xml',
], ],
vala_gir: 'audrey-0.gir',
) )

View file

@ -1,5 +1,5 @@
[DBus (name = "org.mpris.MediaPlayer2")] [DBus (name = "org.mpris.MediaPlayer2")]
class Mpris : Object { class Audrey.Mpris : Object {
internal signal void on_raise (); internal signal void on_raise ();
internal signal void on_quit (); internal signal void on_quit ();
@ -32,7 +32,7 @@ class Mpris : Object {
} }
[DBus (name = "org.mpris.MediaPlayer2.Player")] [DBus (name = "org.mpris.MediaPlayer2.Player")]
class MprisPlayer : Object { class Audrey.MprisPlayer : Object {
internal signal void on_next (); internal signal void on_next ();
internal signal void on_previous (); internal signal void on_previous ();
internal signal void on_pause (); internal signal void on_pause ();

2
src/playbin.rs Normal file
View file

@ -0,0 +1,2 @@
mod song;
pub use song::Song;

View file

@ -1,15 +1,15 @@
public enum PlaybinState { public enum Audrey.PlaybinState {
STOPPED, STOPPED,
PAUSED, PAUSED,
PLAYING, PLAYING,
} }
private struct CommandCallback { private struct Audrey.CommandCallback {
unowned SourceFunc callback; unowned SourceFunc callback;
int error; int error;
} }
public class PlaybinSong : Object { public class Audrey.PlaybinSong : Object {
private Subsonic.Song inner; private Subsonic.Song inner;
public string id { get { return inner.id; } } public string id { get { return inner.id; } }
public string title { get { return inner.title; } } public string title { get { return inner.title; } }
@ -59,7 +59,7 @@ public class PlaybinSong : Object {
} }
} }
public class Playbin : GLib.Object { public class Audrey.Playbin : GLib.Object {
private Mpv.Handle mpv = new Mpv.Handle (); private Mpv.Handle mpv = new Mpv.Handle ();
private int _volume = 100; private int _volume = 100;
private bool _mute = false; private bool _mute = false;

14
src/playbin/song.rs Normal file
View file

@ -0,0 +1,14 @@
mod imp {
#[derive(gtk::Properties, Default)]
#[properties(wrapper_type = super::Song)]
pub struct Song {
inner: RefCell<subsonic::Song>,
#[property(get = |song| song.inner.borrow().id)]
id: &'static str,
}
}
glib::wrapper! {
pub struct Song(ObjectSubclass<imp::Song>);
}

View file

@ -1,11 +1,11 @@
public errordomain Subsonic.Error { public errordomain Audrey.Subsonic.Error {
BAD_AUTHN, BAD_AUTHN,
ERROR, ERROR,
} }
public delegate void Subsonic.SongCallback (Song song); public delegate void Audrey.Subsonic.SongCallback (Song song);
public class Subsonic.Artist : Object { public class Audrey.Subsonic.Artist : Object {
public string index; public string index;
public string id; public string id;
public string name { get; private set; } public string name { get; private set; }
@ -38,7 +38,7 @@ public class Subsonic.Artist : Object {
} }
} }
public class Subsonic.Album : Object { public class Audrey.Subsonic.Album : Object {
public string id; public string id;
public string name; public string name;
@ -53,7 +53,7 @@ public class Subsonic.Album : Object {
} }
} }
public struct Subsonic.Song { public struct Audrey.Subsonic.Song {
public string id; public string id;
public string title; public string title;
public string album; public string album;
@ -109,7 +109,7 @@ public struct Subsonic.Song {
} }
} }
public class Subsonic.Client : Object { public class Audrey.Subsonic.Client : Object {
private Soup.Session session; private Soup.Session session;
private string url; private string url;
private string parameters; private string parameters;

2
src/ui/play_queue.rs Normal file
View file

@ -0,0 +1,2 @@
mod song;
pub use song::Song;

View file

@ -1,7 +1,7 @@
// song widget+drag behavior taken from gnome music // song widget+drag behavior taken from gnome music
[GtkTemplate (ui = "/eu/callcc/audrey/play_queue_song.ui")] [GtkTemplate (ui = "/eu/callcc/audrey/play_queue_song.ui")]
class Ui.PlayQueueSong : Gtk.Box { class Audrey.Ui.PlayQueueSong : Gtk.Box {
public bool draggable { get; set; default = false; } public bool draggable { get; set; default = false; }
public bool show_position { get; set; default = false; } public bool show_position { get; set; default = false; }
public bool show_artist { get; set; default = false; } public bool show_artist { get; set; default = false; }
@ -112,7 +112,7 @@ class Ui.PlayQueueSong : Gtk.Box {
} }
[GtkTemplate (ui = "/eu/callcc/audrey/play_queue.ui")] [GtkTemplate (ui = "/eu/callcc/audrey/play_queue.ui")]
public class Ui.PlayQueue : Adw.Bin { public class Audrey.Ui.PlayQueue : Adw.Bin {
private weak Playbin _playbin; private weak Playbin _playbin;
public Playbin playbin { public Playbin playbin {
get { return _playbin; } get { return _playbin; }

65
src/ui/play_queue/song.rs Normal file
View file

@ -0,0 +1,65 @@
mod imp {
use std::cell::RefCell;
//use crate::playbin;
use gtk::{glib, prelude::*, subclass::prelude::*};
#[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,
//playbin: playbin::Playbin,
connection: RefCell<u64>,
drag_x: RefCell<f64>,
drag_y: RefCell<f64>,
drag_widget: RefCell<Option<gtk::ListBox>>,
}
#[glib::object_subclass]
impl ObjectSubclass for Song {
const NAME: &'static str = "AudreyUiPlayQueueSong";
type Type = super::Song;
type ParentType = gtk::Box;
}
#[glib::derived_properties]
impl ObjectImpl for Song {}
impl WidgetImpl for Song {}
impl BoxImpl for Song {}
#[gtk::template_callbacks]
impl Song {
fn set_current(&self, value: bool) {
*self.current.borrow_mut() = value;
if value {
self.obj().add_css_class("playing");
} else {
self.obj().remove_css_class("playing");
}
}
}
}
use gtk::glib;
glib::wrapper! {
pub struct Song(ObjectSubclass<imp::Song>)
@extends gtk::Box, gtk::Widget,
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
}

View file

@ -1,5 +1,5 @@
[GtkTemplate (ui = "/eu/callcc/audrey/playbar.ui")] [GtkTemplate (ui = "/eu/callcc/audrey/playbar.ui")]
class Ui.Playbar : Adw.Bin { class Audrey.Ui.Playbar : Adw.Bin {
public PlaybinSong? song { get; set; } 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; }

View file

@ -17,7 +17,7 @@ static void salt_password (string password, out string token, out string salt) {
} }
[GtkTemplate (ui = "/eu/callcc/audrey/setup.ui")] [GtkTemplate (ui = "/eu/callcc/audrey/setup.ui")]
public class Ui.Setup : Adw.PreferencesDialog { public class Audrey.Ui.Setup : Adw.PreferencesDialog {
public string status { get; private set; default = _("Not connected"); } public string status { get; private set; default = _("Not connected"); }
public bool authn_can_edit { get; private set; default = true; } public bool authn_can_edit { get; private set; default = true; }

View file

@ -2,18 +2,18 @@ mod ffi {
use gtk::glib; use gtk::glib;
#[repr(C)] #[repr(C)]
pub struct UiWindow { pub struct AudreyUiWindow {
parent_instance: adw::ffi::AdwApplicationWindow, parent_instance: adw::ffi::AdwApplicationWindow,
} }
#[repr(C)] #[repr(C)]
pub struct UiWindowClass { pub struct AudreyUiWindowClass {
parent_class: adw::ffi::AdwApplicationWindowClass, parent_class: adw::ffi::AdwApplicationWindowClass,
} }
extern "C" { extern "C" {
pub fn ui_window_get_type() -> glib::ffi::GType; pub fn audrey_ui_window_get_type() -> glib::ffi::GType;
pub fn ui_window_new(app: *mut gtk::ffi::GtkApplication) -> *mut UiWindow; pub fn audrey_ui_window_new(app: *mut gtk::ffi::GtkApplication) -> *mut AudreyUiWindow;
} }
} }
@ -21,12 +21,12 @@ use adw::prelude::*;
use gtk::{gio, glib}; use gtk::{gio, glib};
glib::wrapper! { glib::wrapper! {
pub struct Window(Object<ffi::UiWindow, ffi::UiWindowClass>) pub struct Window(Object<ffi::AudreyUiWindow, ffi::AudreyUiWindowClass>)
@extends adw::ApplicationWindow, gtk::ApplicationWindow, gtk::Window, gtk::Widget, @extends adw::ApplicationWindow, gtk::ApplicationWindow, gtk::Window, gtk::Widget,
@implements gio::ActionGroup, gio::ActionMap, gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Native, gtk::Root, gtk::ShortcutManager; @implements gio::ActionGroup, gio::ActionMap, gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Native, gtk::Root, gtk::ShortcutManager;
match fn { match fn {
type_ => || ffi::ui_window_get_type(), type_ => || ffi::audrey_ui_window_get_type(),
} }
} }
@ -34,6 +34,6 @@ impl Window {
pub fn new(app: &impl IsA<gtk::Application>) -> Self { pub fn new(app: &impl IsA<gtk::Application>) -> Self {
use glib::translate::*; use glib::translate::*;
unsafe { from_glib_none(ffi::ui_window_new(app.as_ref().to_glib_none().0)) } unsafe { from_glib_none(ffi::audrey_ui_window_new(app.as_ref().to_glib_none().0)) }
} }
} }

View file

@ -1,7 +1,7 @@
[GtkTemplate (ui = "/eu/callcc/audrey/window.ui")] [GtkTemplate (ui = "/eu/callcc/audrey/window.ui")]
class Ui.Window : Adw.ApplicationWindow { class Audrey.Ui.Window : Adw.ApplicationWindow {
[GtkChild] public unowned Ui.PlayQueue play_queue; [GtkChild] public unowned PlayQueue play_queue;
[GtkChild] public unowned Ui.Playbar playbar; [GtkChild] public unowned Playbar playbar;
//[GtkChild] public unowned Adw.ButtonRow shuffle_all_tracks; //[GtkChild] public unowned Adw.ButtonRow shuffle_all_tracks;
private Setup setup; private Setup setup;