Implemented playback queue shuffle via "ALT+." hotkey.

This commit is contained in:
Casey Langen 2016-06-25 18:26:21 -07:00
parent 7feeddc0e3
commit f574d11ca7
8 changed files with 45 additions and 3 deletions

View File

@ -64,6 +64,7 @@ the current hotkeys are generally based around holding the alt/meta key with you
- `ALT+o` forward 10 seconds
- `ALT+r` repaint the screen
- `ALT+,` toggle repeat mode (off/track/list)
- `ALT+.` (un)shuffle play queue
- `CTRL+p` pause/resume (globally)
- `CTRL+x` stop (unload streams, free resources)
- `CTRL+d` quit

View File

@ -55,6 +55,7 @@ NowPlayingLayout::NowPlayingLayout(
, playback(playback)
, library(library) {
this->InitializeWindows();
this->playback.Shuffled.connect(this, &NowPlayingLayout::OnPlaybackShuffled);
}
NowPlayingLayout::~NowPlayingLayout() {
@ -105,6 +106,10 @@ void NowPlayingLayout::OnTrackListRequeried() {
}
}
void NowPlayingLayout::OnPlaybackShuffled(bool shuffled) {
this->RequeryTrackList();
}
void NowPlayingLayout::RequeryTrackList() {
this->trackList->Requery(std::shared_ptr<TrackListQueryBase>(
new NowPlayingTrackListQuery(this->library, this->playback)));

View File

@ -68,6 +68,7 @@ namespace musik {
private:
void OnTrackListRequeried();
void OnPlaybackShuffled(bool shuffled);
void InitializeWindows();
void RequeryTrackList();

View File

@ -107,8 +107,7 @@ TrackPtr TrackList::Get(size_t index) {
}
void TrackList::CopyFrom(TrackList& from) {
this->ids.clear();
this->ClearCache();
this->Clear();
std::copy(
from.ids.begin(),
@ -116,6 +115,15 @@ void TrackList::CopyFrom(TrackList& from) {
std::back_inserter(this->ids));
}
void TrackList::Shuffle() {
std::random_shuffle(this->ids.begin(), this->ids.end());
}
void TrackList::Clear() {
this->ClearCache();
this->ids.clear();
}
void TrackList::ClearCache() {
this->cacheList.clear();
this->cacheMap.clear();

View File

@ -51,8 +51,10 @@ namespace musik {
void Add(const DBID& id);
musik::core::TrackPtr Get(size_t index);
void ClearCache();
void Clear();
void Swap(TrackList& list);
void CopyFrom(TrackList& from);
void Shuffle();
private:
typedef std::list<DBID> CacheList;

View File

@ -87,6 +87,7 @@ PlaybackService::PlaybackService(LibraryPtr library, ITransport& transport)
: library(library)
, transport(transport)
, playlist(library)
, unshuffled(library)
, repeatMode(RepeatNone) {
transport.StreamEvent.connect(this, &PlaybackService::OnStreamEvent);
transport.PlaybackEvent.connect(this, &PlaybackService::OnPlaybackEvent);
@ -130,6 +131,20 @@ void PlaybackService::SetRepeatMode(RepeatMode mode) {
}
}
void PlaybackService::ToggleShuffle() {
boost::recursive_mutex::scoped_lock lock(this->playlistMutex);
if (this->unshuffled.Count() > 0) {
this->playlist.Clear();
this->playlist.Swap(this->unshuffled);
this->Shuffled(false);
}
else {
this->unshuffled.CopyFrom(this->playlist);
this->playlist.Shuffle();
this->Shuffled(true);
}
}
void PlaybackService::ProcessMessage(IMessage &message) {
if (message.Type() == MESSAGE_STREAM_EVENT) {
StreamMessage* streamMessage = static_cast<StreamMessage*>(&message);
@ -140,7 +155,7 @@ void PlaybackService::ProcessMessage(IMessage &message) {
if (this->nextIndex != NO_POSITION) {
/* in most cases when we get here it means that the next track is
starting, so we want to update our internal index. however, because
things are asynchronous, this may not always be the case, especially if
things are asynchronous, this may not always be the case, especially if
the tracks are very short, or the user is advancing through songs very
quickly. make compare the track URIs before we update internal state. */
if (this->GetTrackAtIndex(this->nextIndex)->URI() == streamMessage->GetUri()) {
@ -226,6 +241,7 @@ void PlaybackService::Play(TrackList& tracks, size_t index) {
{
boost::recursive_mutex::scoped_lock lock(this->playlistMutex);
this->playlist.Swap(temp);
this->unshuffled.Clear();
}
if (index <= tracks.Count()) {

View File

@ -52,6 +52,7 @@ namespace musik {
public:
sigslot::signal2<size_t, musik::core::TrackPtr> TrackChanged;
sigslot::signal0<> ModeChanged;
sigslot::signal1<bool> Shuffled;
enum RepeatMode {
RepeatNone,
@ -79,6 +80,9 @@ namespace musik {
RepeatMode GetRepeatMode() { return this->repeatMode; }
void SetRepeatMode(RepeatMode mode);
bool IsShuffled() { return this->unshuffled.Count() > 0; }
void ToggleShuffle();
musik::core::TrackPtr GetTrackAtIndex(size_t index);
size_t GetIndex();
@ -90,6 +94,7 @@ namespace musik {
void PrepareNextTrack();
TrackList playlist;
TrackList unshuffled;
boost::recursive_mutex playlistMutex;
musik::core::LibraryPtr library;

View File

@ -86,6 +86,10 @@ bool GlobalHotkeys::Handle(const std::string& kn) {
playback::ToggleRepeatMode(this->playback);
return true;
}
else if (kn == "M-." || kn == "M-period") {
this->playback.ToggleShuffle();
return true;
}
else if (kn == "^X") {
this->playback.Stop();
return true;