Added some logic in the playqueue (play next / play previous handling)

This commit is contained in:
emeric
2018-03-19 13:45:09 +01:00
parent 50036c8918
commit 5006a82ce6
8 changed files with 163 additions and 188 deletions
+17
View File
@@ -340,6 +340,23 @@ LmsApplication::handleAuthEvent(void)
auto player = new MediaPlayer();
main->bindWidget("player", player);
// Events from MediaPlayer
player->playNext.connect(std::bind([=]
{
playqueue->playNext();
}));
player->playPrevious.connect(std::bind([=]
{
playqueue->playPrevious();
}));
player->playbackEnded.connect(std::bind([=]
{
playqueue->playNext();
}));
// Events from the PlayQueue
playqueue->playTrack.connect(player, &MediaPlayer::playTrack);
// Events from MediaScanner
if (CurrentUser()->isAdmin())
{
+15
View File
@@ -21,6 +21,8 @@
#include <Wt/WTemplate>
#include <Wt/WText>
#include "utils/Logger.hpp"
#include "MediaPlayer.hpp"
namespace UserInterface {
@@ -35,9 +37,17 @@ MediaPlayer::MediaPlayer(Wt::WContainerWidget* parent)
auto prevBtn = new Wt::WText(Wt::WString::tr("btn-mediaplayer-prev"), Wt::XHTMLText);
player->bindWidget("previous", prevBtn);
prevBtn->clicked().connect(std::bind([=]
{
playPrevious.emit();
}));
auto nextBtn = new Wt::WText(Wt::WString::tr("btn-mediaplayer-next"), Wt::XHTMLText);
player->bindWidget("next", nextBtn);
nextBtn->clicked().connect(std::bind([=]
{
playNext.emit();
}));
auto shuffleBtn = new Wt::WText(Wt::WString::tr("btn-mediaplayer-shuffle"), Wt::XHTMLText);
player->bindWidget("shuffle", shuffleBtn);
@@ -53,7 +63,12 @@ MediaPlayer::MediaPlayer(Wt::WContainerWidget* parent)
auto trackName = new Wt::WText("---");
player->bindWidget("track-name", trackName);
}
void
MediaPlayer::playTrack(Database::Track::id_type id)
{
LMS_LOG(UI, DEBUG) << "Playing track ID = " << id;
}
} // namespace UserInterface
+11
View File
@@ -19,14 +19,25 @@
#pragma once
#include <Wt/WSignal>
#include <Wt/WContainerWidget>
#include "database/Types.hpp"
namespace UserInterface {
class MediaPlayer : public Wt::WContainerWidget
{
public:
MediaPlayer(Wt::WContainerWidget* parent = 0);
void playTrack(Database::Track::id_type);
// Signals
Wt::Signal<void> playbackEnded;
Wt::Signal<void> playPrevious;
Wt::Signal<void> playNext;
};
} // namespace UserInterface
+88 -1
View File
@@ -75,6 +75,8 @@ PlayQueue::PlayQueue(Wt::WContainerWidget* parent)
auto playlist = Database::Playlist::get(DboSession(), currentPlayQueueName, CurrentUser());
if (!playlist)
playlist = Database::Playlist::create(DboSession(), currentPlayQueueName, false, CurrentUser());
_trackPos = CurrentUser()->getCurPlayingTrackPos();
}
_showMore->clicked().connect(std::bind([=]
@@ -86,6 +88,63 @@ PlayQueue::PlayQueue(Wt::WContainerWidget* parent)
addSome();
}
void
PlayQueue::stop()
{
updateCurrentTrack(false);
_trackPos.reset();
}
void
PlayQueue::play(std::size_t pos)
{
updateCurrentTrack(false);
Database::Track::id_type trackId;
{
Wt::Dbo::Transaction transaction(DboSession());
auto playlist = Database::Playlist::get(DboSession(), currentPlayQueueName, CurrentUser());
// If out of range, stop playing
if (pos >= playlist->getCount())
{
stop();
return;
}
_trackPos = pos;
trackId = playlist->getEntry(*_trackPos)->getTrack().id();
updateCurrentTrack(true);
}
playTrack.emit(trackId);
}
void
PlayQueue::playPrevious()
{
if (!_trackPos)
return;
if (*_trackPos == 0)
stop();
else
play(*_trackPos - 1);
}
void
PlayQueue::playNext()
{
if (!_trackPos)
{
play(0);
return;
}
play(*_trackPos + 1);
}
void
PlayQueue::updateInfo()
{
@@ -95,6 +154,22 @@ PlayQueue::updateInfo()
_nbTracks->setText(Wt::WString::tr("Lms.PlayQueue.nb-tracks").arg(playlist->getCount()));
}
void
PlayQueue::updateCurrentTrack(bool selected)
{
if (!_trackPos || *_trackPos >= static_cast<std::size_t>(_entriesContainer->count()))
return;
auto track = _entriesContainer->widget(*_trackPos);
if (track)
{
if (selected)
track->addStyleClass("Lms-playqueue-selected");
else
track->removeStyleClass("Lms-playqueue-selected");
}
}
void
PlayQueue::addTracks(const std::vector<Database::Track::pointer>& tracks)
{
@@ -169,7 +244,12 @@ PlayQueue::addSome()
auto playBtn = new Wt::WText(Wt::WString::tr("Lms.PlayQueue.play"), Wt::XHTMLText);
entry->bindWidget("play-btn", playBtn);
// TODO
playBtn->clicked().connect(std::bind([=]
{
auto pos = _entriesContainer->indexOf(entry);
if (pos >= 0)
play(pos);
}));
auto delBtn = new Wt::WText(Wt::WString::tr("Lms.PlayQueue.delete"), Wt::XHTMLText);
entry->bindWidget("del-btn", delBtn);
@@ -183,6 +263,13 @@ PlayQueue::addSome()
entryToRemove.remove();
}
if (_trackPos)
{
auto pos = _entriesContainer->indexOf(entry);
if (pos > 0 && *_trackPos >= static_cast<std::size_t>(pos))
(*_trackPos)--;
}
_entriesContainer->removeWidget(entry);
updateInfo();
+17
View File
@@ -20,9 +20,12 @@
#pragma once
#include <Wt/WContainerWidget>
#include <Wt/WSignal>
#include <Wt/WTemplate>
#include <Wt/WText>
#include <boost/optional.hpp>
#include "database/Types.hpp"
namespace UserInterface {
@@ -35,13 +38,27 @@ class PlayQueue : public Wt::WContainerWidget
void addTracks(const std::vector<Database::Track::pointer>& tracks);
void playTracks(const std::vector<Database::Track::pointer>& tracks);
// play the next track in the queue
void playNext();
// play the previous track in the queue
void playPrevious();
// Signal emitted when a track is to be played
Wt::Signal<Database::Track::id_type> playTrack;
private:
void addSome();
void updateInfo();
void updateCurrentTrack(bool selected);
void play(std::size_t pos);
void stop();
Wt::WContainerWidget* _entriesContainer;
Wt::WTemplate* _showMore;
Wt::WText* _nbTracks;
boost::optional<std::size_t> _trackPos; // current track position, if set
};
} // namespace UserInterface