mirror of
https://github.com/clangen/musikcube.git
synced 2025-03-14 13:21:13 +00:00
* Constified ITrackList methods and added ITrackList::GetTrack
* Modified a couple IPlaybackService method args to accept const TrackLists, instead of non-const * Added IPlaybackService::GetTrackList to get a const reference to the internal tracklist. * Modified NowPlayingLayout to use the PlaybackService's TrackList by const reference, instead of making a copy for every mutating operation. * Fixed a nasty bug where PlaybackService::Shuffled could be broadcast on a background thread.
This commit is contained in:
parent
978ad2ec9d
commit
ec3a1909b2
@ -69,7 +69,8 @@ using Editor = PlaybackService::Editor;
|
||||
#define MESSAGE_VOLUME_CHANGED 1003
|
||||
#define MESSAGE_TIME_CHANGED 1004
|
||||
#define MESSAGE_MODE_CHANGED 1005
|
||||
#define MESSAGE_NOTIFY_EDITED 1006
|
||||
#define MESSAGE_SHUFFLED 1006
|
||||
#define MESSAGE_NOTIFY_EDITED 1007
|
||||
|
||||
class StreamMessage : public Message {
|
||||
public:
|
||||
@ -224,16 +225,16 @@ void PlaybackService::ToggleShuffle() {
|
||||
|
||||
this->playlist.ClearCache();
|
||||
this->unshuffled.ClearCache();
|
||||
bool shuffled = false;
|
||||
|
||||
if (this->unshuffled.Count() > 0) { /* shuffled -> unshuffled */
|
||||
this->playlist.Clear();
|
||||
this->playlist.Swap(this->unshuffled);
|
||||
this->Shuffled(false);
|
||||
}
|
||||
else { /* unshuffled -> shuffle */
|
||||
this->unshuffled.CopyFrom(this->playlist);
|
||||
this->playlist.Shuffle();
|
||||
this->Shuffled(true);
|
||||
shuffled = true;
|
||||
}
|
||||
|
||||
/* find the new playback index and prefetch the next track */
|
||||
@ -245,7 +246,8 @@ void PlaybackService::ToggleShuffle() {
|
||||
}
|
||||
}
|
||||
|
||||
POST(this, MESSAGE_MODE_CHANGED, 0, 0);
|
||||
POST(this, MESSAGE_SHUFFLED, shuffled ? 1 : 0, 0);
|
||||
POST(this, MESSAGE_NOTIFY_EDITED, 0, 0);
|
||||
}
|
||||
|
||||
void PlaybackService::ProcessMessage(IMessage &message) {
|
||||
@ -308,8 +310,8 @@ void PlaybackService::ProcessMessage(IMessage &message) {
|
||||
if (transport.GetPlaybackState() != PlaybackStopped) {
|
||||
size_t updatedIndex = (size_t)message.UserData1();
|
||||
|
||||
this->index = updatedIndex;
|
||||
if (updatedIndex != NO_POSITION) {
|
||||
this->index = updatedIndex;
|
||||
this->nextIndex = NO_POSITION; /* force recalc */
|
||||
}
|
||||
|
||||
@ -331,6 +333,9 @@ void PlaybackService::ProcessMessage(IMessage &message) {
|
||||
}
|
||||
this->ModeChanged();
|
||||
}
|
||||
else if (type == MESSAGE_SHUFFLED) {
|
||||
this->Shuffled(!!message.UserData1());
|
||||
}
|
||||
else if (type == MESSAGE_TIME_CHANGED) {
|
||||
this->TimeChanged(transport.Position());
|
||||
}
|
||||
@ -422,7 +427,7 @@ PlaybackState PlaybackService::GetPlaybackState() {
|
||||
return transport.GetPlaybackState();
|
||||
}
|
||||
|
||||
void PlaybackService::Play(TrackList& tracks, size_t index) {
|
||||
void PlaybackService::Play(const TrackList& tracks, size_t index) {
|
||||
/* do the copy outside of the critical section, then swap. */
|
||||
TrackList temp(this->library);
|
||||
temp.CopyFrom(tracks);
|
||||
@ -438,10 +443,10 @@ void PlaybackService::Play(TrackList& tracks, size_t index) {
|
||||
}
|
||||
}
|
||||
|
||||
void PlaybackService::Play(musik::core::sdk::ITrackList* source, size_t index) {
|
||||
void PlaybackService::Play(const musik::core::sdk::ITrackList* source, size_t index) {
|
||||
if (source) {
|
||||
/* see if we have a TrackList -- if we do we can optimize the copy */
|
||||
TrackList* sourceTrackList = dynamic_cast<TrackList*>(source);
|
||||
const TrackList* sourceTrackList = dynamic_cast<const TrackList*>(source);
|
||||
|
||||
if (sourceTrackList) {
|
||||
this->Play(*sourceTrackList, index);
|
||||
@ -466,7 +471,7 @@ void PlaybackService::CopyTo(TrackList& target) {
|
||||
target.CopyFrom(this->playlist);
|
||||
}
|
||||
|
||||
void PlaybackService::CopyFrom(TrackList& source) {
|
||||
void PlaybackService::CopyFrom(const TrackList& source) {
|
||||
std::unique_lock<std::recursive_mutex> lock(this->playlistMutex);
|
||||
|
||||
this->playlist.CopyFrom(source);
|
||||
@ -475,14 +480,16 @@ void PlaybackService::CopyFrom(TrackList& source) {
|
||||
|
||||
if (this->playingTrack) {
|
||||
this->index = playlist.IndexOf(this->playingTrack->GetId());
|
||||
POST(this, MESSAGE_PREPARE_NEXT_TRACK, NO_POSITION, 0);
|
||||
POST(this, MESSAGE_PREPARE_NEXT_TRACK, this->index, 0);
|
||||
}
|
||||
|
||||
POST(this, MESSAGE_NOTIFY_EDITED, NO_POSITION, 0);
|
||||
}
|
||||
|
||||
void PlaybackService::CopyFrom(musik::core::sdk::ITrackList* source) {
|
||||
void PlaybackService::CopyFrom(const musik::core::sdk::ITrackList* source) {
|
||||
if (source) {
|
||||
/* see if we have a TrackList -- if we do we can optimize the copy */
|
||||
TrackList* sourceTrackList = dynamic_cast<TrackList*>(source);
|
||||
const TrackList* sourceTrackList = dynamic_cast<const TrackList*>(source);
|
||||
|
||||
if (sourceTrackList) {
|
||||
this->CopyFrom(*sourceTrackList);
|
||||
@ -504,6 +511,8 @@ void PlaybackService::CopyFrom(musik::core::sdk::ITrackList* source) {
|
||||
this->index = playlist.IndexOf(this->playingTrack->GetId());
|
||||
POST(this, MESSAGE_PREPARE_NEXT_TRACK, NO_POSITION, 0);
|
||||
}
|
||||
|
||||
POST(this, MESSAGE_NOTIFY_EDITED, NO_POSITION, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,19 +100,24 @@ namespace musik { namespace core { namespace audio {
|
||||
virtual double GetDuration();
|
||||
virtual musik::core::sdk::IRetainedTrack* GetTrack(size_t index);
|
||||
virtual musik::core::sdk::IRetainedTrack* GetPlayingTrack();
|
||||
virtual void CopyFrom(musik::core::sdk::ITrackList* source);
|
||||
virtual void Play(musik::core::sdk::ITrackList* source, size_t index);
|
||||
virtual void CopyFrom(const musik::core::sdk::ITrackList* source);
|
||||
virtual void Play(const musik::core::sdk::ITrackList* source, size_t index);
|
||||
virtual musik::core::sdk::ITrackListEditor* EditPlaylist();
|
||||
|
||||
/* app-specific implementation. similar to some SDK methods, but use
|
||||
concrete data types with known optimizations */
|
||||
musik::core::audio::ITransport& GetTransport() { return this->transport; }
|
||||
void Play(musik::core::TrackList& tracks, size_t index);
|
||||
void Play(const musik::core::TrackList& tracks, size_t index);
|
||||
void CopyTo(musik::core::TrackList& target);
|
||||
void CopyFrom(musik::core::TrackList& source);
|
||||
void CopyFrom(const musik::core::TrackList& source);
|
||||
musik::core::TrackPtr GetTrackAtIndex(size_t index);
|
||||
musik::core::TrackPtr GetPlaying();
|
||||
|
||||
std::shared_ptr<const musik::core::TrackList> GetTrackList() {
|
||||
return std::shared_ptr<const musik::core::TrackList>(
|
||||
&this->playlist, [](const musik::core::TrackList*) {});
|
||||
}
|
||||
|
||||
/* required to make changes to the playlist. this little data structure
|
||||
privately owns a lock to the internal data structure and will release
|
||||
that lock when it's destructed. */
|
||||
|
@ -67,22 +67,26 @@ namespace musik { namespace core { namespace db { namespace local {
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual size_t Count() {
|
||||
virtual size_t Count() const {
|
||||
return this->wrapped->Count();
|
||||
}
|
||||
|
||||
virtual musik::core::sdk::IRetainedTrack* GetRetainedTrack(size_t index) {
|
||||
virtual musik::core::sdk::IRetainedTrack* GetRetainedTrack(size_t index) const {
|
||||
return this->wrapped->GetRetainedTrack(index);
|
||||
}
|
||||
|
||||
virtual unsigned long long GetId(size_t index) {
|
||||
virtual unsigned long long GetId(size_t index) const {
|
||||
return this->wrapped->GetId(index);
|
||||
}
|
||||
|
||||
virtual int IndexOf(unsigned long long id) {
|
||||
virtual int IndexOf(unsigned long long id) const {
|
||||
return this->wrapped->IndexOf(id);
|
||||
}
|
||||
|
||||
virtual musik::core::sdk::ITrack* GetTrack(size_t index) const {
|
||||
return this->wrapped->GetTrack(index);
|
||||
}
|
||||
|
||||
private:
|
||||
Result wrapped;
|
||||
};
|
||||
|
@ -77,7 +77,7 @@ TrackList::~TrackList() {
|
||||
|
||||
}
|
||||
|
||||
size_t TrackList::Count() {
|
||||
size_t TrackList::Count() const {
|
||||
return ids.size();
|
||||
}
|
||||
|
||||
@ -124,7 +124,7 @@ bool TrackList::Delete(size_t index) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TrackPtr TrackList::Get(size_t index) {
|
||||
TrackPtr TrackList::Get(size_t index) const {
|
||||
auto id = this->ids.at(index);
|
||||
auto cached = this->GetFromCache(id);
|
||||
|
||||
@ -140,15 +140,19 @@ TrackPtr TrackList::Get(size_t index) {
|
||||
return query->Result();
|
||||
}
|
||||
|
||||
IRetainedTrack* TrackList::GetRetainedTrack(size_t index) {
|
||||
IRetainedTrack* TrackList::GetRetainedTrack(size_t index) const {
|
||||
return new RetainedTrack(this->Get(index));
|
||||
}
|
||||
|
||||
unsigned long long TrackList::GetId(size_t index) {
|
||||
ITrack* TrackList::GetTrack(size_t index) const {
|
||||
return this->Get(index).get();
|
||||
}
|
||||
|
||||
unsigned long long TrackList::GetId(size_t index) const {
|
||||
return this->ids.at(index);
|
||||
}
|
||||
|
||||
void TrackList::CopyFrom(TrackList& from) {
|
||||
void TrackList::CopyFrom(const TrackList& from) {
|
||||
this->Clear();
|
||||
|
||||
std::copy(
|
||||
@ -157,7 +161,7 @@ void TrackList::CopyFrom(TrackList& from) {
|
||||
std::back_inserter(this->ids));
|
||||
}
|
||||
|
||||
int TrackList::IndexOf(unsigned long long id) {
|
||||
int TrackList::IndexOf(unsigned long long id) const {
|
||||
auto it = std::find(this->ids.begin(), this->ids.end(), id);
|
||||
return (it == this->ids.end()) ? -1 : it - this->ids.begin();
|
||||
}
|
||||
@ -180,7 +184,7 @@ void TrackList::Swap(TrackList& tl) {
|
||||
std::swap(tl.ids, this->ids);
|
||||
}
|
||||
|
||||
TrackPtr TrackList::GetFromCache(DBID key) {
|
||||
TrackPtr TrackList::GetFromCache(DBID key) const {
|
||||
auto it = this->cacheMap.find(key);
|
||||
if (it != this->cacheMap.end()) {
|
||||
this->cacheList.splice( /* promote to front */
|
||||
@ -194,7 +198,7 @@ TrackPtr TrackList::GetFromCache(DBID key) {
|
||||
return TrackPtr();
|
||||
}
|
||||
|
||||
void TrackList::AddToCache(DBID key, TrackPtr value) {
|
||||
void TrackList::AddToCache(DBID key, TrackPtr value) const {
|
||||
auto it = this->cacheMap.find(key);
|
||||
if (it != this->cacheMap.end()) {
|
||||
cacheList.erase(it->second.second);
|
||||
|
@ -64,10 +64,11 @@ namespace musik { namespace core {
|
||||
virtual ~TrackList();
|
||||
|
||||
/* ITrackList */
|
||||
virtual size_t Count();
|
||||
virtual musik::core::sdk::IRetainedTrack* GetRetainedTrack(size_t index);
|
||||
virtual unsigned long long GetId(size_t index);
|
||||
virtual int IndexOf(unsigned long long id);
|
||||
virtual size_t Count() const;
|
||||
virtual musik::core::sdk::IRetainedTrack* GetRetainedTrack(size_t index) const;
|
||||
virtual unsigned long long GetId(size_t index) const;
|
||||
virtual int IndexOf(unsigned long long id) const;
|
||||
virtual musik::core::sdk::ITrack* GetTrack(size_t index) const;
|
||||
|
||||
/* ITrackListEditor */
|
||||
virtual void Add(const unsigned long long id);
|
||||
@ -79,23 +80,22 @@ namespace musik { namespace core {
|
||||
virtual void Shuffle();
|
||||
|
||||
/* implementation specific */
|
||||
TrackPtr Get(size_t index);
|
||||
TrackPtr Get(size_t index) const;
|
||||
void ClearCache();
|
||||
void Swap(TrackList& list);
|
||||
void CopyFrom(TrackList& from);
|
||||
|
||||
void CopyFrom(const TrackList& from);
|
||||
|
||||
private:
|
||||
typedef std::list<DBID> CacheList;
|
||||
typedef std::pair<TrackPtr, CacheList::iterator> CacheValue;
|
||||
typedef std::unordered_map<DBID, CacheValue> CacheMap;
|
||||
|
||||
TrackPtr GetFromCache(DBID key);
|
||||
void AddToCache(DBID key, TrackPtr value);
|
||||
TrackPtr GetFromCache(DBID key) const;
|
||||
void AddToCache(DBID key, TrackPtr value) const;
|
||||
|
||||
/* lru cache structures */
|
||||
CacheList cacheList;
|
||||
CacheMap cacheMap;
|
||||
mutable CacheList cacheList;
|
||||
mutable CacheMap cacheMap;
|
||||
|
||||
std::vector<DBID> ids;
|
||||
ILibraryPtr library;
|
||||
|
@ -78,8 +78,8 @@ namespace musik { namespace core { namespace sdk {
|
||||
virtual IRetainedTrack* GetPlayingTrack() = 0;
|
||||
|
||||
/* sdk v3*/
|
||||
virtual void CopyFrom(ITrackList* trackList) = 0;
|
||||
virtual void Play(ITrackList* source, size_t index) = 0;
|
||||
virtual void CopyFrom(const ITrackList* trackList) = 0;
|
||||
virtual void Play(const ITrackList* source, size_t index) = 0;
|
||||
virtual ITrackListEditor* EditPlaylist() = 0;
|
||||
};
|
||||
|
||||
|
@ -43,11 +43,15 @@ namespace musik {
|
||||
|
||||
class ITrackList {
|
||||
public:
|
||||
/* sdk v1 */
|
||||
virtual void Release() = 0;
|
||||
virtual size_t Count() = 0;
|
||||
virtual IRetainedTrack* GetRetainedTrack(size_t index) = 0;
|
||||
virtual unsigned long long GetId(size_t index) = 0;
|
||||
virtual int IndexOf(unsigned long long id) = 0;
|
||||
virtual size_t Count() const = 0;
|
||||
virtual IRetainedTrack* GetRetainedTrack(size_t index) const = 0;
|
||||
virtual unsigned long long GetId(size_t index) const = 0;
|
||||
virtual int IndexOf(unsigned long long id) const = 0;
|
||||
|
||||
/* sdk v3 */
|
||||
virtual ITrack* GetTrack(size_t index) const = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -68,11 +68,9 @@ NowPlayingLayout::NowPlayingLayout(
|
||||
: LayoutBase()
|
||||
, playback(playback)
|
||||
, library(library)
|
||||
, reselectIndex(-1)
|
||||
, lastPlaylistQueryId(-1) {
|
||||
this->InitializeWindows();
|
||||
|
||||
this->playback.Shuffled.connect(this, &NowPlayingLayout::OnPlaybackShuffled);
|
||||
this->playback.QueueEdited.connect(this, &NowPlayingLayout::RequeryTrackList);
|
||||
|
||||
EDIT_KEYS = {
|
||||
@ -147,15 +145,17 @@ void NowPlayingLayout::OnVisibilityChanged(bool visible) {
|
||||
}
|
||||
|
||||
void NowPlayingLayout::OnTrackListRequeried(musik::core::db::local::TrackListQueryBase* query) {
|
||||
/* if the requery just finished for a regular playlist, we need to
|
||||
make sure we load it into the PlaybackService. generally we just read
|
||||
FROM the playback service */
|
||||
/* in most cases we pull the TrackList directly from the PlaybackService.
|
||||
however, some user operations cause the TrackList to be loaded from
|
||||
the database, e.g. loading regular playlists. in these cases, copy
|
||||
the tracks TO the PlaybackService, then refresh! */
|
||||
if (query && query->GetId() == this->lastPlaylistQueryId) {
|
||||
this->playback.CopyFrom(*query->GetResult());
|
||||
this->lastPlaylistQueryId = -1;
|
||||
}
|
||||
|
||||
if (playback.Count()) {
|
||||
/* regular logic (i.e, no edit operation) */
|
||||
if (this->reselectIndex == -1) {
|
||||
size_t index = playback.GetIndex();
|
||||
|
||||
@ -168,16 +168,22 @@ void NowPlayingLayout::OnTrackListRequeried(musik::core::db::local::TrackListQue
|
||||
this->trackListView->ScrollTo(index == 0 ? index : index - 1);
|
||||
}
|
||||
}
|
||||
else { /* requeried due to edit, so reselect... */
|
||||
/* user just finished an edit. this is a bit of a hack; we're notified
|
||||
of the edit completion asynchronously, so before we complete the edit
|
||||
we stash the index we need to re-select. */
|
||||
else {
|
||||
/* ensure the correct index is selected, and that it's properly
|
||||
scrolled into view */
|
||||
this->reselectIndex = std::min((int) this->trackListView->Count() - 1, this->reselectIndex);
|
||||
this->trackListView->SetSelectedIndex((int) this->reselectIndex);
|
||||
this->trackListView->SetSelectedIndex((size_t)this->reselectIndex);
|
||||
auto pos = this->trackListView->GetScrollPosition();
|
||||
int first = (int) pos.firstVisibleEntryIndex;
|
||||
int last = (int) first + pos.visibleEntryCount;
|
||||
int index = (int) this->reselectIndex;
|
||||
int first = (int)pos.firstVisibleEntryIndex;
|
||||
int last = (int)first + pos.visibleEntryCount;
|
||||
int index = (int)this->reselectIndex;
|
||||
if (index < first || index >= last) {
|
||||
this->trackListView->ScrollTo(this->reselectIndex);
|
||||
this->trackListView->ScrollTo((size_t)this->reselectIndex);
|
||||
}
|
||||
this->reselectIndex = -1;
|
||||
}
|
||||
|
||||
/* if after a bunch of monkeying around there's still nothing
|
||||
@ -188,17 +194,14 @@ void NowPlayingLayout::OnTrackListRequeried(musik::core::db::local::TrackListQue
|
||||
this->trackListView->ScrollTo(0);
|
||||
}
|
||||
}
|
||||
|
||||
this->reselectIndex = -1;
|
||||
}
|
||||
|
||||
void NowPlayingLayout::OnPlaybackShuffled(bool shuffled) {
|
||||
this->RequeryTrackList();
|
||||
else {
|
||||
this->trackListView->ScrollTo(0);
|
||||
}
|
||||
}
|
||||
|
||||
void NowPlayingLayout::RequeryTrackList() {
|
||||
this->trackListView->Requery(std::shared_ptr<TrackListQueryBase>(
|
||||
new NowPlayingTrackListQuery(this->library, this->playback)));
|
||||
this->trackListView->SetTrackList(this->playback.GetTrackList());
|
||||
this->OnTrackListRequeried(nullptr);
|
||||
}
|
||||
|
||||
void NowPlayingLayout::OnPlaylistSelected(DBID playlistId) {
|
||||
@ -246,28 +249,31 @@ bool NowPlayingLayout::KeyPress(const std::string& key) {
|
||||
bool NowPlayingLayout::ProcessEditOperation(const std::string& key) {
|
||||
if (EDIT_KEYS.find(key) != EDIT_KEYS.end()) {
|
||||
if (!playback.IsShuffled()) {
|
||||
PlaybackService::Editor editor = this->playback.Edit();
|
||||
size_t selected = this->trackListView->GetSelectedIndex();
|
||||
this->reselectIndex = (int)selected;
|
||||
this->reselectIndex = -1;
|
||||
|
||||
if (Hotkeys::Is(Hotkeys::PlayQueueMoveUp, key)) {
|
||||
if (selected > 0) {
|
||||
size_t to = selected - 1;
|
||||
editor.Move(selected, to);
|
||||
this->reselectIndex = (int)to;
|
||||
{
|
||||
PlaybackService::Editor editor = this->playback.Edit();
|
||||
if (Hotkeys::Is(Hotkeys::PlayQueueMoveUp, key)) {
|
||||
if (selected > 0) {
|
||||
size_t to = selected - 1;
|
||||
editor.Move(selected, to);
|
||||
reselectIndex = (int)to;
|
||||
}
|
||||
}
|
||||
else if (Hotkeys::Is(Hotkeys::PlayQueueMoveDown, key)) {
|
||||
if (selected < this->playback.Count() - 1) {
|
||||
size_t to = selected + 1;
|
||||
editor.Move(selected, to);
|
||||
reselectIndex = (int)to;
|
||||
}
|
||||
}
|
||||
else if (Hotkeys::Is(Hotkeys::PlayQueueDelete, key)) {
|
||||
editor.Delete(selected);
|
||||
reselectIndex = (int)selected;
|
||||
}
|
||||
}
|
||||
else if (Hotkeys::Is(Hotkeys::PlayQueueMoveDown, key)) {
|
||||
if (selected < this->playback.Count() - 1) {
|
||||
size_t to = selected + 1;
|
||||
editor.Move(selected, to);
|
||||
this->reselectIndex = (int)to;
|
||||
}
|
||||
}
|
||||
else if (Hotkeys::Is(Hotkeys::PlayQueueDelete, key)) {
|
||||
editor.Delete(selected);
|
||||
this->reselectIndex = (int)selected;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -74,14 +74,13 @@ namespace musik {
|
||||
|
||||
/* callbacks */
|
||||
void OnTrackListRequeried(musik::core::db::local::TrackListQueryBase* query);
|
||||
void OnPlaybackShuffled(bool shuffled);
|
||||
int64 RowDecorator(musik::core::TrackPtr track, size_t index);
|
||||
void OnPlaylistSelected(DBID playlistId);
|
||||
|
||||
musik::core::audio::PlaybackService& playback;
|
||||
musik::core::ILibraryPtr library;
|
||||
std::shared_ptr<TrackListView> trackListView;
|
||||
int reselectIndex; /* gross... */
|
||||
int reselectIndex; /* sigh... */
|
||||
int lastPlaylistQueryId;
|
||||
};
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ using namespace musik::core::audio;
|
||||
using namespace musik::core::db;
|
||||
using namespace musik::core::library;
|
||||
using namespace musik::core::runtime;
|
||||
using namespace musik::core::sdk;
|
||||
using namespace musik::box;
|
||||
using namespace musik::glue;
|
||||
using namespace cursespp;
|
||||
@ -128,10 +129,22 @@ void TrackListView::OnQueryCompleted(IQuery* query) {
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<TrackList> TrackListView::GetTrackList() {
|
||||
std::shared_ptr<const TrackList> TrackListView::GetTrackList() {
|
||||
return this->metadata;
|
||||
}
|
||||
|
||||
void TrackListView::SetTrackList(std::shared_ptr<const TrackList> trackList) {
|
||||
if (this->metadata != trackList) {
|
||||
this->metadata = trackList;
|
||||
this->SetSelectedIndex(0);
|
||||
this->ScrollToTop();
|
||||
this->OnAdapterChanged();
|
||||
}
|
||||
else {
|
||||
this->OnAdapterChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void TrackListView::Clear() {
|
||||
this->query.reset();
|
||||
this->metadata.reset(new TrackList(this->library));
|
||||
@ -291,7 +304,7 @@ IScrollAdapter::EntryPtr TrackListView::Adapter::GetEntry(cursespp::ScrollableWi
|
||||
? parent.formatter(track, this->GetWidth())
|
||||
: formatWithoutAlbum(track, this->GetWidth());
|
||||
|
||||
if (this->parent.headers->find(index) != this->parent.headers->end()) {
|
||||
if (this->parent.headers && this->parent.headers->find(index) != this->parent.headers->end()) {
|
||||
std::string album = track->GetValue(constants::Track::ALBUM);
|
||||
std::shared_ptr<EntryWithHeader> entry(new EntryWithHeader(album, text));
|
||||
entry->SetAttrs(COLOR_PAIR(CURSESPP_LIST_ITEM_HEADER), attrs);
|
||||
|
@ -78,7 +78,8 @@ namespace musik {
|
||||
virtual void ProcessMessage(musik::core::runtime::IMessage &message);
|
||||
virtual bool KeyPress(const std::string& key);
|
||||
|
||||
std::shared_ptr<musik::core::TrackList> GetTrackList();
|
||||
std::shared_ptr<const musik::core::TrackList> GetTrackList();
|
||||
void SetTrackList(std::shared_ptr<const musik::core::TrackList> trackList);
|
||||
|
||||
void Clear();
|
||||
musik::core::TrackPtr Get(size_t index);
|
||||
@ -108,7 +109,7 @@ namespace musik {
|
||||
void ScrollToPlaying();
|
||||
|
||||
std::shared_ptr<TrackListQueryBase> query;
|
||||
std::shared_ptr<musik::core::TrackList> metadata;
|
||||
std::shared_ptr<const musik::core::TrackList> metadata;
|
||||
Headers headers;
|
||||
Adapter* adapter;
|
||||
musik::core::audio::PlaybackService& playback;
|
||||
|
Loading…
x
Reference in New Issue
Block a user