Newer
Older
Kevin Whitaker
committed
/*
* Copyright (C) 2017 Kevin Whitaker <eyecreate@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#include "PlayerInterface.h"
#include <Wt/WText>
Kevin Whitaker
committed
#include "../GroovePlayer.h"
#include <grooveplayer/player.h>
Kevin Whitaker
committed
#include <Wt/WLength>
Kevin Whitaker
committed
#include <Wt/WColor>
#include <Wt/WBorder>
#include <Wt/WString>
Kevin Whitaker
committed
PlayerInterface::PlayerInterface(WebInterface* app)
{
this->app = app;
Kevin Whitaker
committed
interfaceLayout = new Wt::WVBoxLayout();
this->setLayout(interfaceLayout);
playControlLayout = new Wt::WHBoxLayout();
Kevin Whitaker
committed
playControlWidget = new Wt::WContainerWidget();
skipControls = new Wt::WContainerWidget();
Kevin Whitaker
committed
playControlWidget->setLayout(playControlLayout);
Kevin Whitaker
committed
currentTrackProgress = new Wt::WProgressBar();
currentTrackProgress->setFormat("");
trackProgress = new Wt::WTimer();
trackProgress->setInterval(1000);
trackProgress->timeout().connect(this,&PlayerInterface::updateProgressFromTimer);
Kevin Whitaker
committed
currentTrackDetails = new TrackDetails();
currentTrackDetails->setMinimumSize(Wt::WLength(100,Wt::WLength::Pixel),Wt::WLength(100,Wt::WLength::Pixel));
Kevin Whitaker
committed
currentTrackDetails->changeBackgroundColor(Wt::WColor("#6FFF6F"));
Kevin Whitaker
committed
playpause = new Wt::WPushButton();
playpause->setTextFormat(Wt::XHTMLText);
playpause->decorationStyle().font().setFamily(Wt::WFont::Default,"FontAwesome");
playpause->setText(groove_playlist_playing(GroovePlayerMgr::getInstance()->currentPlaylist)==1?Wt::WString::fromUTF8(""):Wt::WString::fromUTF8(""));
Kevin Whitaker
committed
playpause->setMaximumSize(Wt::WLength(60,Wt::WLength::Point),Wt::WLength(30,Wt::WLength::Point));
Kevin Whitaker
committed
isPaused = groove_playlist_playing(GroovePlayerMgr::getInstance()->currentPlaylist)==0;
playpause->clicked().connect(this, &PlayerInterface::playpauseClicked);
skipRequest = new Wt::WPushButton();
skipRequest->clicked().connect(this, &PlayerInterface::skipRequestClicked);
skipRequest->setTextFormat(Wt::XHTMLText);
skipRequest->decorationStyle().font().setFamily(Wt::WFont::Default,"FontAwesome");
skipRequest->setText("");
skipDeny = new Wt::WPushButton();
skipDeny->clicked().connect(this, &PlayerInterface::skipDenyClicked);
skipDeny->setTextFormat(Wt::XHTMLText);
skipDeny->decorationStyle().font().setFamily(Wt::WFont::Default,"FontAwesome");
skipDeny->setText("");
skipDeny->setHidden(true);
skipControls->addWidget(skipRequest);
Kevin Whitaker
committed
Kevin Whitaker
committed
mainDisplay = new Wt::WTabWidget();
Kevin Whitaker
committed
requestPane = new RequestInterface(app);
Kevin Whitaker
committed
voteMetaContainer = new Wt::WContainerWidget();
voteMetaLayout = new Wt::WVBoxLayout();
voteMetaContainer->setLayout(voteMetaLayout);
Kevin Whitaker
committed
voteControlContainer = new Wt::WContainerWidget();
voteControlContainer->setMaximumSize(Wt::WLength(75,Wt::WLength::Percentage),Wt::WLength::Auto);
Kevin Whitaker
committed
votePanel = new Wt::WPanel();
votePanel->addStyleClass("panel-primary");
Kevin Whitaker
committed
voteTracksContainer = new Wt::WContainerWidget();
voteTracksContainer->addStyleClass("panel-body");
voteTracksLayout = new Wt::WVBoxLayout();
track1 = new Wt::WHBoxLayout();
track1details = new TrackDetails();
track1details->changeBackgroundColor(Wt::WColor("gainsboro"));
track1vote = new Wt::WPushButton();
track1vote->setTextFormat(Wt::XHTMLText);
track1vote->decorationStyle().font().setFamily(Wt::WFont::Default,"FontAwesome");
track1vote->setMaximumSize(Wt::WLength(50,Wt::WLength::Pixel),Wt::WLength(50,Wt::WLength::Pixel));
track1vote->setText("");
track1votecount = new Wt::WText("0");
track1->addWidget(track1details,1,Wt::AlignmentFlag::AlignMiddle | Wt::AlignmentFlag::AlignLeft);
Kevin Whitaker
committed
track1->addWidget(track1vote,0,Wt::AlignmentFlag::AlignMiddle | Wt::AlignmentFlag::AlignRight);
track1->addWidget(track1votecount,0,Wt::AlignmentFlag::AlignMiddle | Wt::AlignmentFlag::AlignLeft);
Kevin Whitaker
committed
track2 = new Wt::WHBoxLayout();
track2details = new TrackDetails();
track2details->changeBackgroundColor(Wt::WColor("gainsboro"));
track2vote = new Wt::WPushButton();
track2vote->setTextFormat(Wt::XHTMLText);
track2vote->decorationStyle().font().setFamily(Wt::WFont::Default,"FontAwesome");
track2vote->setMaximumSize(Wt::WLength(50,Wt::WLength::Pixel),Wt::WLength(50,Wt::WLength::Pixel));
track2vote->setText("");
track2votecount = new Wt::WText("0");
track2->addWidget(track2details,1,Wt::AlignmentFlag::AlignMiddle | Wt::AlignmentFlag::AlignLeft);
Kevin Whitaker
committed
track2->addWidget(track2vote,0,Wt::AlignmentFlag::AlignMiddle | Wt::AlignmentFlag::AlignRight);
track2->addWidget(track2votecount,0,Wt::AlignmentFlag::AlignMiddle | Wt::AlignmentFlag::AlignLeft);
Kevin Whitaker
committed
track3 = new Wt::WHBoxLayout();
track3details = new TrackDetails();
track3details->changeBackgroundColor(Wt::WColor("gainsboro"));
track3vote = new Wt::WPushButton();
track3vote->setTextFormat(Wt::XHTMLText);
track3vote->decorationStyle().font().setFamily(Wt::WFont::Default,"FontAwesome");
track3vote->setMaximumSize(Wt::WLength(50,Wt::WLength::Pixel),Wt::WLength(50,Wt::WLength::Pixel));
track3vote->setText("");
track3votecount = new Wt::WText("0");
track3->addWidget(track3details,1,Wt::AlignmentFlag::AlignMiddle | Wt::AlignmentFlag::AlignLeft);
Kevin Whitaker
committed
track3->addWidget(track3vote,0,Wt::AlignmentFlag::AlignMiddle | Wt::AlignmentFlag::AlignRight);
track3->addWidget(track3votecount,0,Wt::AlignmentFlag::AlignMiddle | Wt::AlignmentFlag::AlignLeft);
track1vote->clicked().connect(this, &PlayerInterface::vote1clicked);
track2vote->clicked().connect(this, &PlayerInterface::vote2clicked);
track3vote->clicked().connect(this, &PlayerInterface::vote3clicked);
Kevin Whitaker
committed
Kevin Whitaker
committed
interfaceLayout->addWidget(playControlWidget);
Kevin Whitaker
committed
interfaceLayout->addWidget(currentTrackProgress);
Kevin Whitaker
committed
interfaceLayout->addWidget(mainDisplay);
mainDisplay->addTab(voteMetaContainer,"Up Next",Wt::WTabWidget::PreLoading);
Kevin Whitaker
committed
mainDisplay->addTab(requestPane, "Make Request", Wt::WTabWidget::LazyLoading);
playControlWidget->addStyleClass("panel");
playControlWidget->addStyleClass("panel-default");
playControlWidget->decorationStyle().setBackgroundColor(Wt::WColor("gainsboro"));
Kevin Whitaker
committed
voteMetaLayout->addWidget(voteControlContainer,0,Wt::AlignmentFlag::AlignCenter);
Kevin Whitaker
committed
playControlLayout->addWidget(playpause,0,Wt::AlignmentFlag::AlignLeft | Wt::AlignmentFlag::AlignMiddle);
playControlLayout->addWidget(currentTrackDetails,0,Wt::AlignmentFlag::AlignCenter | Wt::AlignmentFlag::AlignMiddle);
playControlLayout->addWidget(skipControls,0,Wt::AlignmentFlag::AlignRight | Wt::AlignmentFlag::AlignMiddle);
Kevin Whitaker
committed
votePanel->setTitle("Upcoming Tracks To Vote On");
votePanel->decorationStyle().setBackgroundColor(Wt::WColor("lightsteelblue"));
voteControlContainer->addWidget(votePanel);
votePanel->setCentralWidget(voteTracksContainer);
Kevin Whitaker
committed
voteTracksContainer->setLayout(voteTracksLayout);
voteTracksLayout->addLayout(track1);
voteTracksLayout->addSpacing(Wt::WLength(20,Wt::WLength::Pixel));
Kevin Whitaker
committed
voteTracksLayout->addLayout(track2);
voteTracksLayout->addSpacing(Wt::WLength(20,Wt::WLength::Pixel));
Kevin Whitaker
committed
voteTracksLayout->addLayout(track3);
Kevin Whitaker
committed
}
void PlayerInterface::playpauseClicked()
{
if(!isPaused)
{
GroovePlayerMgr::getInstance()->lastInternalEvents.push_back(GroovePlayerMgr::PlayerEvent() = {GroovePlayerMgr::PlayerEventType::PLAYING_PAUSED, app->currentUser, std::list<AudioTrack>{GroovePlayerMgr::getInstance()->currentTrack}});
Kevin Whitaker
committed
}
else
{
GroovePlayerMgr::getInstance()->lastInternalEvents.push_back(GroovePlayerMgr::PlayerEvent() = {GroovePlayerMgr::PlayerEventType::PLAYING_RESUMED, app->currentUser, std::list<AudioTrack>{GroovePlayerMgr::getInstance()->currentTrack}});
Kevin Whitaker
committed
}
}
void PlayerInterface::skipRequestClicked()
{
if(!isPaused)
{
GroovePlayerMgr::getInstance()->lastInternalEvents.push_back(GroovePlayerMgr::PlayerEvent() = {GroovePlayerMgr::PlayerEventType::SKIP_REQUESTED, app->currentUser, std::list<AudioTrack>{GroovePlayerMgr::getInstance()->currentTrack}});
}
}
void PlayerInterface::skipDenyClicked()
{
if(!isPaused)
{
GroovePlayerMgr::getInstance()->lastInternalEvents.push_back(GroovePlayerMgr::PlayerEvent() = {GroovePlayerMgr::PlayerEventType::SKIP_VOTE_CAST_AGAINST, app->currentUser, std::list<AudioTrack>{GroovePlayerMgr::getInstance()->currentTrack}});
}
}
void PlayerInterface::vote1clicked()
{
track1vote->setEnabled(false);
track2vote->setEnabled(false);
track3vote->setEnabled(false);
GroovePlayerMgr::getInstance()->lastInternalEvents.push_back(GroovePlayerMgr::PlayerEvent() = {GroovePlayerMgr::PlayerEventType::VOTE_CAST, app->currentUser, std::list<AudioTrack>{track1details->extractTrackFromDetails()}});
}
void PlayerInterface::vote2clicked()
{
track1vote->setEnabled(false);
track2vote->setEnabled(false);
track3vote->setEnabled(false);
GroovePlayerMgr::getInstance()->lastInternalEvents.push_back(GroovePlayerMgr::PlayerEvent() = {GroovePlayerMgr::PlayerEventType::VOTE_CAST, app->currentUser, std::list<AudioTrack>{track2details->extractTrackFromDetails()}});
}
void PlayerInterface::vote3clicked()
{
track1vote->setEnabled(false);
track2vote->setEnabled(false);
track3vote->setEnabled(false);
GroovePlayerMgr::getInstance()->lastInternalEvents.push_back(GroovePlayerMgr::PlayerEvent() = {GroovePlayerMgr::PlayerEventType::VOTE_CAST, app->currentUser, std::list<AudioTrack>{track3details->extractTrackFromDetails()}});
}
void PlayerInterface::updateSkipRequestedFromServer()
{
skipRequest->setHidden(true);
skipDeny->setHidden(false);
}
void PlayerInterface::updateSkipDeniedFromServer()
{
skipDeny->setHidden(true);
skipRequest->setHidden(false);
}
Kevin Whitaker
committed
void PlayerInterface::updateVotingEnded(AudioTrack winner)
Kevin Whitaker
committed
track1vote->setEnabled(false);
track2vote->setEnabled(false);
track3vote->setEnabled(false);
//show winning track
if(track1details->trackMatches(winner)) track1details->changeBackgroundColor(Wt::WColor("gold"));
else if(track2details->trackMatches(winner)) track2details->changeBackgroundColor(Wt::WColor("gold"));
else if(track3details->trackMatches(winner)) track3details->changeBackgroundColor(Wt::WColor("gold"));
void PlayerInterface::updateVoteCount(AudioTrack trackVoted)
{
//update track vote
if(track1details->trackMatches(trackVoted)) track1votecount->setText(std::to_string(std::stoi(track1votecount->text())+1));
else if(track2details->trackMatches(trackVoted)) track2votecount->setText(std::to_string(std::stoi(track2votecount->text())+1));
else if(track3details->trackMatches(trackVoted)) track3votecount->setText(std::to_string(std::stoi(track3votecount->text())+1));
}
Kevin Whitaker
committed
void PlayerInterface::playpauseUpdated()
{
if(isPaused)
{
playpause->setText(Wt::WString::fromUTF8(""));
Kevin Whitaker
committed
}
else
{
if(!GroovePlayerMgr::getInstance()->voteEndedButNotNextTrackYet) skipRequest->setEnabled(true);
playpause->setText(Wt::WString::fromUTF8(""));
Kevin Whitaker
committed
}
Kevin Whitaker
committed
}
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
void PlayerInterface::updateProgressFromTimer()
{
if(currentTrackProgress->maximum() >= currentTrackProgress->value()+1)
{
double secondsIn;
groove_player_position(GroovePlayerMgr::getInstance()->currentPlayer,nullptr, &secondsIn);
currentTrackProgress->setValue(secondsIn);
}
else if(currentTrackProgress->maximum() < currentTrackProgress->value()+1)
{
currentTrackProgress->setValue(currentTrackProgress->maximum());
trackProgress->stop();
}
}
void PlayerInterface::updateDetailsFromServer(AudioTrack track)
{
//Find current song playing and set progress state.
double secondsIn;
groove_player_position(GroovePlayerMgr::getInstance()->currentPlayer,nullptr, &secondsIn);
currentTrackProgress->setMaximum(track.trackLengthSeconds);
currentTrackProgress->setValue(secondsIn);
isPaused = groove_playlist_playing(GroovePlayerMgr::getInstance()->currentPlaylist) == 0;
if(!isPaused)
{
trackProgress->start();
}
playpauseUpdated();
if(GroovePlayerMgr::getInstance()->currentSkipRequester.size() > 0)
{
updateSkipRequestedFromServer();
}
else
{
updateSkipDeniedFromServer();
}
Kevin Whitaker
committed
currentTrackDetails->updateWithTrackDetails(track);
Kevin Whitaker
committed
void PlayerInterface::updateVoteableTracksFromServer(std::list<AudioTrack> tracks)
{
//Update current vote items
auto trackIter = tracks.begin();
track1details->updateWithTrackDetails(*trackIter);
track2details->updateWithTrackDetails(*++trackIter);
track3details->updateWithTrackDetails(*++trackIter);
track1vote->setEnabled(true);
track2vote->setEnabled(true);
track3vote->setEnabled(true);
//reset color state of tracks
track1details->changeBackgroundColor(Wt::WColor("gainsboro"));
track2details->changeBackgroundColor(Wt::WColor("gainsboro"));
track3details->changeBackgroundColor(Wt::WColor("gainsboro"));
}
void PlayerInterface::updateVoteTrackState()
{
//Update vote counts of tracks
auto trackIter = GroovePlayerMgr::getInstance()->currentVoteStatus.begin();
track1votecount->setText(std::to_string(trackIter->second));
++trackIter;
track2votecount->setText(std::to_string(trackIter->second));
++trackIter;
track3votecount->setText(std::to_string(trackIter->second));
//Make sure vote buttons are disabled if this user already voted
for(User user : GroovePlayerMgr::getInstance()->currentUsersVoted)
{
if(user.username == app->currentUser.username)
{
track1vote->setEnabled(false);
track2vote->setEnabled(false);
track3vote->setEnabled(false);
}
}
}