split playbar into its own template
This commit is contained in:
parent
8e1edd39c8
commit
cc525dcc80
7 changed files with 242 additions and 223 deletions
|
@ -5,6 +5,7 @@
|
||||||
<file preprocess="xml-stripblanks">gtk/help-overlay.ui</file>
|
<file preprocess="xml-stripblanks">gtk/help-overlay.ui</file>
|
||||||
<file preprocess="xml-stripblanks">ui/play_queue.ui</file>
|
<file preprocess="xml-stripblanks">ui/play_queue.ui</file>
|
||||||
<file preprocess="xml-stripblanks">ui/play_queue_song.ui</file>
|
<file preprocess="xml-stripblanks">ui/play_queue_song.ui</file>
|
||||||
|
<file preprocess="xml-stripblanks">ui/playbar.ui</file>
|
||||||
<file preprocess="xml-stripblanks">ui/setup.ui</file>
|
<file preprocess="xml-stripblanks">ui/setup.ui</file>
|
||||||
<file preprocess="xml-stripblanks">ui/window.ui</file>
|
<file preprocess="xml-stripblanks">ui/window.ui</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
|
|
|
@ -6,6 +6,7 @@ audrey_sources = [
|
||||||
'playbin.vala',
|
'playbin.vala',
|
||||||
'subsonic.vala',
|
'subsonic.vala',
|
||||||
'ui/play_queue.vala',
|
'ui/play_queue.vala',
|
||||||
|
'ui/playbar.vala',
|
||||||
'ui/setup.vala',
|
'ui/setup.vala',
|
||||||
'ui/window.vala',
|
'ui/window.vala',
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
blueprints = custom_target(
|
blueprints = custom_target(
|
||||||
'blueprints',
|
'blueprints',
|
||||||
input: files('play_queue.blp', 'play_queue_song.blp', 'setup.blp', 'window.blp'),
|
input: files('play_queue.blp', 'play_queue_song.blp', 'playbar.blp', 'setup.blp', 'window.blp'),
|
||||||
output: ['play_queue.ui', 'play_queue_song.ui', 'setup.ui', 'window.ui'],
|
output: ['play_queue.ui', 'play_queue_song.ui', 'playbar.ui', 'setup.ui', 'window.ui'],
|
||||||
command: [
|
command: [
|
||||||
find_program('blueprint-compiler'),
|
find_program('blueprint-compiler'),
|
||||||
'batch-compile',
|
'batch-compile',
|
||||||
|
|
154
src/ui/playbar.blp
Normal file
154
src/ui/playbar.blp
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
using Gtk 4.0;
|
||||||
|
|
||||||
|
template $UiPlaybar: Box {
|
||||||
|
styles [
|
||||||
|
"toolbar",
|
||||||
|
]
|
||||||
|
|
||||||
|
CenterBox {
|
||||||
|
[start]
|
||||||
|
Box {
|
||||||
|
orientation: vertical;
|
||||||
|
valign: center;
|
||||||
|
|
||||||
|
Label {
|
||||||
|
styles [ "heading" ]
|
||||||
|
xalign: 0;
|
||||||
|
halign: start;
|
||||||
|
label: bind $song_title (template.song) as <string>;
|
||||||
|
ellipsize: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
styles [ "caption" ]
|
||||||
|
xalign: 0;
|
||||||
|
label: bind $song_artist (template.song) as <string>;
|
||||||
|
ellipsize: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
styles [ "caption" ]
|
||||||
|
xalign: 0;
|
||||||
|
label: bind $song_album (template.song) as <string>;
|
||||||
|
ellipsize: end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[center]
|
||||||
|
Box {
|
||||||
|
orientation: vertical;
|
||||||
|
halign: center;
|
||||||
|
hexpand: true;
|
||||||
|
|
||||||
|
CenterBox {
|
||||||
|
[start]
|
||||||
|
Label play_position_label {
|
||||||
|
styles [
|
||||||
|
"caption",
|
||||||
|
"numeric",
|
||||||
|
]
|
||||||
|
|
||||||
|
label: bind $format_timestamp (template.playbin as <$Playbin>.position) as <string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
[center]
|
||||||
|
Scale play_position {
|
||||||
|
name: "seek-scale";
|
||||||
|
orientation: horizontal;
|
||||||
|
width-request: 400;
|
||||||
|
sensitive: bind $playbin_active (template.playbin as <$Playbin>.state as <$PlaybinState>) as <bool>;
|
||||||
|
|
||||||
|
adjustment: Adjustment {
|
||||||
|
lower: 0;
|
||||||
|
value: bind template.playbin as <$Playbin>.position;
|
||||||
|
upper: bind template.playbin as <$Playbin>.duration;
|
||||||
|
};
|
||||||
|
|
||||||
|
change-value => $on_play_position_seek ();
|
||||||
|
}
|
||||||
|
|
||||||
|
[end]
|
||||||
|
Label play_duration {
|
||||||
|
styles [
|
||||||
|
"caption",
|
||||||
|
"numeric",
|
||||||
|
]
|
||||||
|
|
||||||
|
label: bind $format_timestamp (template.playbin as <$Playbin>.duration) as <string>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Box {
|
||||||
|
halign: center;
|
||||||
|
orientation: horizontal;
|
||||||
|
|
||||||
|
Button {
|
||||||
|
icon-name: "media-skip-backward";
|
||||||
|
valign: center;
|
||||||
|
sensitive: bind $playbin_active (template.playbin as <$Playbin>.state as <$PlaybinState>) as <bool>;
|
||||||
|
|
||||||
|
clicked => $on_skip_backward_clicked ();
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
icon-name: "media-seek-backward";
|
||||||
|
valign: center;
|
||||||
|
sensitive: bind $playbin_active (template.playbin as <$Playbin>.state as <$PlaybinState>) as <bool>;
|
||||||
|
|
||||||
|
clicked => $seek_backward ();
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
icon-name: bind $play_pause_icon_name (template.playbin as <$Playbin>.state as <$PlaybinState>) as <string>;
|
||||||
|
valign: center;
|
||||||
|
sensitive: bind $playbin_active (template.playbin as <$Playbin>.state as <$PlaybinState>) as <bool>;
|
||||||
|
|
||||||
|
clicked => $on_play_pause_clicked ();
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
icon-name: "media-seek-forward";
|
||||||
|
valign: center;
|
||||||
|
sensitive: bind $playbin_active (template.playbin as <$Playbin>.state as <$PlaybinState>) as <bool>;
|
||||||
|
|
||||||
|
clicked => $seek_forward ();
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
icon-name: "media-skip-forward";
|
||||||
|
valign: center;
|
||||||
|
sensitive: bind $playbin_active (template.playbin as <$Playbin>.state as <$PlaybinState>) as <bool>;
|
||||||
|
|
||||||
|
clicked => $on_skip_forward_clicked ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[end]
|
||||||
|
Box {
|
||||||
|
Button {
|
||||||
|
icon-name: "non-starred";
|
||||||
|
valign: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
icon-name: bind $mute_button_icon_name (template.playbin as <$Playbin>.mute) as <string>;
|
||||||
|
valign: center;
|
||||||
|
|
||||||
|
clicked => $on_mute_toggle ();
|
||||||
|
}
|
||||||
|
|
||||||
|
Scale {
|
||||||
|
name: "volume-scale";
|
||||||
|
orientation: horizontal;
|
||||||
|
width-request: 130;
|
||||||
|
|
||||||
|
adjustment: Adjustment {
|
||||||
|
lower: 0;
|
||||||
|
value: bind template.volume bidirectional;
|
||||||
|
upper: 100;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
80
src/ui/playbar.vala
Normal file
80
src/ui/playbar.vala
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
[GtkTemplate (ui = "/eu/callcc/audrey/ui/playbar.ui")]
|
||||||
|
class Ui.Playbar : Gtk.Box {
|
||||||
|
public Subsonic.Song? song { get; set; }
|
||||||
|
public Playbin playbin { get; set; }
|
||||||
|
public int volume {
|
||||||
|
get { return playbin == null ? 100 : playbin.volume; }
|
||||||
|
set { playbin.volume = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[GtkCallback] private string format_timestamp (double s) {
|
||||||
|
return "%02d:%02d".printf (((int) s)/60, ((int) s)%60);
|
||||||
|
}
|
||||||
|
|
||||||
|
[GtkCallback] private bool on_play_position_seek (Gtk.Range range, Gtk.ScrollType scroll_type, double value) {
|
||||||
|
this.playbin.seek ((int64) value);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
[GtkCallback] private void on_play_pause_clicked () {
|
||||||
|
if (this.playbin.state == PlaybinState.PLAYING) {
|
||||||
|
this.playbin.pause();
|
||||||
|
} else {
|
||||||
|
this.playbin.play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[GtkCallback] private string play_pause_icon_name (PlaybinState state) {
|
||||||
|
if (state == PlaybinState.PLAYING) {
|
||||||
|
return "media-playback-pause";
|
||||||
|
} else {
|
||||||
|
return "media-playback-start";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[GtkCallback] private bool playbin_active (PlaybinState state) {
|
||||||
|
return state != PlaybinState.STOPPED;
|
||||||
|
}
|
||||||
|
|
||||||
|
[GtkCallback] private string mute_button_icon_name (bool mute) {
|
||||||
|
return mute ? "audio-volume-muted" : "audio-volume-high";
|
||||||
|
}
|
||||||
|
|
||||||
|
[GtkCallback] private void on_mute_toggle () {
|
||||||
|
this.playbin.mute = !this.playbin.mute;
|
||||||
|
}
|
||||||
|
|
||||||
|
[GtkCallback] private void on_skip_forward_clicked () {
|
||||||
|
this.playbin.next_track ();
|
||||||
|
}
|
||||||
|
|
||||||
|
[GtkCallback] private void on_skip_backward_clicked () {
|
||||||
|
this.playbin.prev_track ();
|
||||||
|
}
|
||||||
|
|
||||||
|
[GtkCallback] private void seek_backward () {
|
||||||
|
// 10 seconds
|
||||||
|
double new_position = playbin.position - 10.0;
|
||||||
|
if (new_position < 0.0) new_position = 0.0;
|
||||||
|
this.playbin.seek (new_position);
|
||||||
|
}
|
||||||
|
|
||||||
|
[GtkCallback] private void seek_forward () {
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
[GtkCallback] private string song_title (Subsonic.Song? song) {
|
||||||
|
return song == null ? "" : song.title;
|
||||||
|
}
|
||||||
|
|
||||||
|
[GtkCallback] private string song_artist (Subsonic.Song? song) {
|
||||||
|
return song == null ? "" : song.artist;
|
||||||
|
}
|
||||||
|
|
||||||
|
[GtkCallback] private string song_album (Subsonic.Song? song) {
|
||||||
|
return song == null ? "" : song.album;
|
||||||
|
}
|
||||||
|
}
|
|
@ -95,156 +95,9 @@ template $UiWindow: Adw.ApplicationWindow {
|
||||||
Box {}
|
Box {}
|
||||||
|
|
||||||
[bottom-bar]
|
[bottom-bar]
|
||||||
CenterBox {
|
$UiPlaybar playbar {
|
||||||
styles [
|
song: bind template.song;
|
||||||
"toolbar",
|
playbin: bind template.playbin;
|
||||||
]
|
|
||||||
|
|
||||||
[start]
|
|
||||||
Box {
|
|
||||||
orientation: vertical;
|
|
||||||
valign: center;
|
|
||||||
|
|
||||||
Label {
|
|
||||||
styles [ "heading" ]
|
|
||||||
xalign: 0;
|
|
||||||
halign: start;
|
|
||||||
label: bind $song_title (template.song) as <string>;
|
|
||||||
ellipsize: end;
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
styles [ "caption" ]
|
|
||||||
xalign: 0;
|
|
||||||
label: bind $song_artist (template.song) as <string>;
|
|
||||||
ellipsize: end;
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
styles [ "caption" ]
|
|
||||||
xalign: 0;
|
|
||||||
label: bind $song_album (template.song) as <string>;
|
|
||||||
ellipsize: end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[center]
|
|
||||||
Box {
|
|
||||||
orientation: vertical;
|
|
||||||
halign: center;
|
|
||||||
hexpand: true;
|
|
||||||
|
|
||||||
CenterBox {
|
|
||||||
[start]
|
|
||||||
Label play_position_label {
|
|
||||||
styles [
|
|
||||||
"caption",
|
|
||||||
"numeric",
|
|
||||||
]
|
|
||||||
|
|
||||||
label: bind $format_timestamp (template.playbin as <$Playbin>.position) as <string>;
|
|
||||||
}
|
|
||||||
|
|
||||||
[center]
|
|
||||||
Scale play_position {
|
|
||||||
name: "seek-scale";
|
|
||||||
orientation: horizontal;
|
|
||||||
width-request: 400;
|
|
||||||
sensitive: bind $playbin_active (template.playbin as <$Playbin>.state as <$PlaybinState>) as <bool>;
|
|
||||||
|
|
||||||
adjustment: Adjustment {
|
|
||||||
lower: 0;
|
|
||||||
value: bind template.playbin as <$Playbin>.position;
|
|
||||||
upper: bind template.playbin as <$Playbin>.duration;
|
|
||||||
};
|
|
||||||
|
|
||||||
change-value => $on_play_position_seek ();
|
|
||||||
}
|
|
||||||
|
|
||||||
[end]
|
|
||||||
Label play_duration {
|
|
||||||
styles [
|
|
||||||
"caption",
|
|
||||||
"numeric",
|
|
||||||
]
|
|
||||||
|
|
||||||
label: bind $format_timestamp (template.playbin as <$Playbin>.duration) as <string>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Box {
|
|
||||||
halign: center;
|
|
||||||
orientation: horizontal;
|
|
||||||
|
|
||||||
Button {
|
|
||||||
icon-name: "media-skip-backward";
|
|
||||||
valign: center;
|
|
||||||
sensitive: bind $playbin_active (template.playbin as <$Playbin>.state as <$PlaybinState>) as <bool>;
|
|
||||||
|
|
||||||
clicked => $on_skip_backward_clicked ();
|
|
||||||
}
|
|
||||||
|
|
||||||
Button {
|
|
||||||
icon-name: "media-seek-backward";
|
|
||||||
valign: center;
|
|
||||||
sensitive: bind $playbin_active (template.playbin as <$Playbin>.state as <$PlaybinState>) as <bool>;
|
|
||||||
|
|
||||||
clicked => $seek_backward ();
|
|
||||||
}
|
|
||||||
|
|
||||||
Button {
|
|
||||||
icon-name: bind $play_pause_icon_name (template.playbin as <$Playbin>.state as <$PlaybinState>) as <string>;
|
|
||||||
valign: center;
|
|
||||||
sensitive: bind $playbin_active (template.playbin as <$Playbin>.state as <$PlaybinState>) as <bool>;
|
|
||||||
|
|
||||||
clicked => $on_play_pause_clicked ();
|
|
||||||
}
|
|
||||||
|
|
||||||
Button {
|
|
||||||
icon-name: "media-seek-forward";
|
|
||||||
valign: center;
|
|
||||||
sensitive: bind $playbin_active (template.playbin as <$Playbin>.state as <$PlaybinState>) as <bool>;
|
|
||||||
|
|
||||||
clicked => $seek_forward ();
|
|
||||||
}
|
|
||||||
|
|
||||||
Button {
|
|
||||||
icon-name: "media-skip-forward";
|
|
||||||
valign: center;
|
|
||||||
sensitive: bind $playbin_active (template.playbin as <$Playbin>.state as <$PlaybinState>) as <bool>;
|
|
||||||
|
|
||||||
clicked => $on_skip_forward_clicked ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[end]
|
|
||||||
Box {
|
|
||||||
Button {
|
|
||||||
icon-name: "non-starred";
|
|
||||||
valign: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
Button {
|
|
||||||
icon-name: bind $mute_button_icon_name (template.mute) as <string>;
|
|
||||||
valign: center;
|
|
||||||
|
|
||||||
clicked => $on_mute_toggle ();
|
|
||||||
}
|
|
||||||
|
|
||||||
Scale {
|
|
||||||
name: "volume-scale";
|
|
||||||
orientation: horizontal;
|
|
||||||
width-request: 130;
|
|
||||||
|
|
||||||
adjustment: Adjustment {
|
|
||||||
lower: 0;
|
|
||||||
value: bind template.volume bidirectional;
|
|
||||||
upper: 100;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ class Ui.Window : Adw.ApplicationWindow {
|
||||||
[GtkChild] private unowned Gtk.Stack stack;
|
[GtkChild] private unowned Gtk.Stack stack;
|
||||||
|
|
||||||
[GtkChild] public unowned Ui.PlayQueue play_queue;
|
[GtkChild] public unowned Ui.PlayQueue play_queue;
|
||||||
|
[GtkChild] public unowned Ui.Playbar playbar;
|
||||||
[GtkChild] public unowned Adw.ButtonRow shuffle_all_tracks;
|
[GtkChild] public unowned Adw.ButtonRow shuffle_all_tracks;
|
||||||
|
|
||||||
private Setup setup;
|
private Setup setup;
|
||||||
|
@ -115,78 +116,7 @@ class Ui.Window : Adw.ApplicationWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[GtkCallback] private string format_timestamp (double s) {
|
|
||||||
return "%02d:%02d".printf (((int) s)/60, ((int) s)%60);
|
|
||||||
}
|
|
||||||
|
|
||||||
[GtkCallback] private bool on_play_position_seek (Gtk.Range range, Gtk.ScrollType scroll_type, double value) {
|
|
||||||
this.playbin.seek ((int64) value);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
[GtkCallback] private void on_play_pause_clicked () {
|
|
||||||
if (this.playbin.state == PlaybinState.PLAYING) {
|
|
||||||
this.playbin.pause();
|
|
||||||
} else {
|
|
||||||
this.playbin.play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[GtkCallback] private string play_pause_icon_name (PlaybinState state) {
|
|
||||||
if (state == PlaybinState.PLAYING) {
|
|
||||||
return "media-playback-pause";
|
|
||||||
} else {
|
|
||||||
return "media-playback-start";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[GtkCallback] private bool playbin_active (PlaybinState state) {
|
|
||||||
return state != PlaybinState.STOPPED;
|
|
||||||
}
|
|
||||||
|
|
||||||
[GtkCallback] private string mute_button_icon_name (bool mute) {
|
|
||||||
return mute ? "audio-volume-muted" : "audio-volume-high";
|
|
||||||
}
|
|
||||||
|
|
||||||
[GtkCallback] private void on_mute_toggle () {
|
|
||||||
this.mute = !this.mute;
|
|
||||||
}
|
|
||||||
|
|
||||||
[GtkCallback] private void on_skip_forward_clicked () {
|
|
||||||
this.playbin.next_track ();
|
|
||||||
}
|
|
||||||
|
|
||||||
[GtkCallback] private void on_skip_backward_clicked () {
|
|
||||||
this.playbin.prev_track ();
|
|
||||||
}
|
|
||||||
|
|
||||||
[GtkCallback] private void show_setup_dialog () {
|
[GtkCallback] private void show_setup_dialog () {
|
||||||
this.setup.present (this);
|
this.setup.present (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
[GtkCallback] private void seek_backward () {
|
|
||||||
// 10 seconds
|
|
||||||
double new_position = playbin.position - 10.0;
|
|
||||||
if (new_position < 0.0) new_position = 0.0;
|
|
||||||
this.playbin.seek (new_position);
|
|
||||||
}
|
|
||||||
|
|
||||||
[GtkCallback] private void seek_forward () {
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
[GtkCallback] private string song_title (Subsonic.Song? song) {
|
|
||||||
return song == null ? "" : song.title;
|
|
||||||
}
|
|
||||||
|
|
||||||
[GtkCallback] private string song_artist (Subsonic.Song? song) {
|
|
||||||
return song == null ? "" : song.artist;
|
|
||||||
}
|
|
||||||
|
|
||||||
[GtkCallback] private string song_album (Subsonic.Song? song) {
|
|
||||||
return song == null ? "" : song.album;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue