mirror of
https://github.com/clangen/musikcube.git
synced 2025-02-10 15:40:28 +00:00
Implemented playback queue shuffle via "ALT+." hotkey.
This commit is contained in:
parent
7feeddc0e3
commit
f574d11ca7
@ -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
|
||||
|
@ -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)));
|
||||
|
@ -68,6 +68,7 @@ namespace musik {
|
||||
|
||||
private:
|
||||
void OnTrackListRequeried();
|
||||
void OnPlaybackShuffled(bool shuffled);
|
||||
void InitializeWindows();
|
||||
void RequeryTrackList();
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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()) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user