Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ config_file = configure_file(
)

adw_dep = dependency('libadwaita-1', version: '>=1.4.0')
granite_dep = dependency('granite-7')
granite_dep = dependency('granite-7', version: '>=7.6.0')
gstreamer_dep = dependency('gstreamer-1.0')
gstreamer_pbutils_dep = dependency('gstreamer-pbutils-1.0')
gstreamer_tag_dep = dependency('gstreamer-tag-1.0')
Expand Down
68 changes: 46 additions & 22 deletions src/MainWindow.vala
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@
*/

public class Music.MainWindow : Gtk.ApplicationWindow {
private Granite.Placeholder queue_placeholder;
private Gtk.Button repeat_button;
private Gtk.Button shuffle_button;
private Settings settings;
private Gtk.SearchEntry search_entry;
private Gtk.ListView queue_listview;
private Gtk.Revealer search_revealer;
private Gtk.ScrolledWindow scrolled;
private Gtk.SearchEntry search_entry;
private Gtk.SingleSelection selection_model;
private Gtk.Stack queue_stack;
private Settings settings;

construct {
var playback_manager = PlaybackManager.get_default ();
Expand Down Expand Up @@ -42,22 +47,29 @@ public class Music.MainWindow : Gtk.ApplicationWindow {
queue_header.pack_end (shuffle_button);
queue_header.pack_end (repeat_button);

var queue_placeholder = new Granite.Placeholder (_("Queue is Empty")) {
queue_placeholder = new Granite.Placeholder (_("Queue is Empty")) {
description = _("Audio files opened from Files will appear here"),
icon = new ThemedIcon ("playlist-queue")
};

var queue_listbox = new Gtk.ListBox () {
selection_model = new Gtk.SingleSelection (playback_manager.queue_liststore);

var factory = new Gtk.SignalListItemFactory ();

queue_listview = new Gtk.ListView (selection_model, factory) {
single_click_activate = true,
hexpand = true,
vexpand = true
};
queue_listbox.bind_model (playback_manager.queue_liststore, create_queue_row);
queue_listbox.set_placeholder (queue_placeholder);

var scrolled = new Gtk.ScrolledWindow () {
child = queue_listbox
scrolled = new Gtk.ScrolledWindow () {
child = queue_listview
};

queue_stack = new Gtk.Stack ();
queue_stack.add_child (queue_placeholder);
queue_stack.add_child (scrolled);

var drop_target = new Gtk.DropTarget (typeof (Gdk.FileList), Gdk.DragAction.COPY);

var add_button_label = new Gtk.Label (_("Open Files…"));
Expand Down Expand Up @@ -98,7 +110,7 @@ public class Music.MainWindow : Gtk.ApplicationWindow {

var queue = new Adw.ToolbarView () {
bottom_bar_style = RAISED,
content = scrolled
content = queue_stack
};
queue.add_controller (drop_target);
queue.add_css_class (Granite.STYLE_CLASS_VIEW);
Expand Down Expand Up @@ -201,25 +213,34 @@ public class Music.MainWindow : Gtk.ApplicationWindow {
}
});

queue_listbox.row_activated.connect ((row) => {
playback_manager.current_audio = ((TrackRow) row).audio_object;
factory.setup.connect ((obj) => {
var list_item = (Gtk.ListItem) obj;
list_item.child = new TrackRow ();
});

factory.bind.connect ((obj) => {
var list_item = (Gtk.ListItem) obj;
((TrackRow) list_item.child).audio_object = (AudioObject) list_item.item;
});

queue_listview.activate.connect ((index) => {
playback_manager.current_audio = (AudioObject) selection_model.get_item (index);
});

selection_model.items_changed.connect (on_items_changed);

search_entry.search_changed.connect (() => {
int pos = playback_manager.find_title (search_entry.text);
if (pos >= 0) {
queue_listbox.select_row (queue_listbox.get_row_at_index (pos));
var adj = scrolled.vadjustment;
// Search entry is hidden if n_items is zero so no need to check
var ratio = (double)pos / (double)playback_manager.n_items;
adj.@value = adj.upper * ratio;
queue_listview.scroll_to (pos, SELECT, null);
}
});

search_entry.activate.connect (() => {
var selected = queue_listbox.get_selected_row ();
if (selected != null) {
selected.activate ();
var selected = selection_model.get_selected ();
if (selected != -1) {
var selected_audio = (AudioObject) selection_model.get_item (selected);
playback_manager.current_audio = selected_audio;
}
});
}
Expand Down Expand Up @@ -301,8 +322,11 @@ public class Music.MainWindow : Gtk.ApplicationWindow {
}
}

private Gtk.Widget create_queue_row (GLib.Object object) {
unowned var audio_object = (AudioObject) object;
return new TrackRow (audio_object);
private void on_items_changed () {
if (selection_model.n_items > 0) {
queue_stack.visible_child = scrolled;
} else {
queue_stack.visible_child = queue_placeholder;
}
}
}
68 changes: 52 additions & 16 deletions src/Widgets/TrackRow.vala
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,62 @@
* SPDX-FileCopyrightText: 2021 elementary, Inc. (https://elementary.io)
*/

public class Music.TrackRow : Gtk.ListBoxRow {
public AudioObject audio_object { get; construct; }
public class Music.TrackRow : Granite.Bin {
private AudioObject _audio_object = null;
public AudioObject audio_object {
get {
return _audio_object;
}

private static PlaybackManager playback_manager;
set {
if (_audio_object != null) {
_audio_object.notify["artist"].disconnect (update_artist_label);
_audio_object.notify["title"].disconnect (update_title_label);
_audio_object.notify["texture"].disconnect (update_cover_art);
}

private Gtk.Spinner play_icon;
_audio_object = value;

if (_audio_object == null) {
return;
}

public TrackRow (AudioObject audio_object) {
Object (audio_object: audio_object);
update_artist_label ();
update_title_label ();
update_cover_art ();
_audio_object.notify["artist"].connect (update_artist_label);
_audio_object.notify["title"].connect (update_title_label);
_audio_object.notify["texture"].connect (update_cover_art);

}
}

private static PlaybackManager playback_manager;

private Gtk.Label artist_label;
private Gtk.Label title_label;
private Gtk.Spinner play_icon;
private Music.AlbumImage album_image;

static construct {
playback_manager = PlaybackManager.get_default ();
}

construct {
play_icon = new Gtk.Spinner () {
spinning = playback_manager.current_audio == audio_object
};
play_icon = new Gtk.Spinner ();
play_icon.add_css_class ("play-indicator");

var album_image = new Music.AlbumImage ();
album_image = new Music.AlbumImage ();
album_image.image.height_request = 32;
album_image.image.width_request = 32;

var title_label = new Gtk.Label (audio_object.title) {
title_label = new Gtk.Label (null) {
ellipsize = Pango.EllipsizeMode.MIDDLE,
hexpand = true,
xalign = 0
};

var artist_label = new Gtk.Label (audio_object.artist) {
artist_label = new Gtk.Label (null) {
ellipsize = Pango.EllipsizeMode.MIDDLE,
hexpand = true,
xalign = 0
Expand All @@ -56,10 +80,6 @@ public class Music.TrackRow : Gtk.ListBoxRow {

child = grid;

audio_object.bind_property ("artist", artist_label, "label", BindingFlags.SYNC_CREATE);
audio_object.bind_property ("title", title_label, "label", BindingFlags.SYNC_CREATE);
audio_object.bind_property ("texture", album_image.image, "paintable", BindingFlags.SYNC_CREATE);

playback_manager.notify["current-audio"].connect (() => {
play_icon.spinning = playback_manager.current_audio == audio_object;
});
Expand All @@ -73,6 +93,10 @@ public class Music.TrackRow : Gtk.ListBoxRow {
}
});

notify["audio-object"].connect (() => {
play_icon.spinning = playback_manager.current_audio == audio_object;
});

var action_remove = new SimpleAction ("remove", null);
action_remove.activate.connect (() => {
playback_manager.remove (this.audio_object);
Expand Down Expand Up @@ -126,4 +150,16 @@ public class Music.TrackRow : Gtk.ListBoxRow {
play_icon.remove_css_class ("playing");
}
}

private void update_title_label () {
title_label.label = _audio_object.title;
}

private void update_artist_label () {
artist_label.label = _audio_object.artist;
}

private void update_cover_art () {
album_image.image.paintable = _audio_object.texture;
}
}