Added mute support to ITransport and IPlaybackService. Also improved focus

behavior and interaction with the transport while browsing the library.
This commit is contained in:
casey langen 2016-11-19 17:20:07 -08:00
parent 0c90323b99
commit a43ea0e2ce
15 changed files with 113 additions and 58 deletions

View File

@ -85,6 +85,11 @@ LRESULT CALLBACK ShellProc(int code, WPARAM wParam, LPARAM lParam) {
case 'j':
playback->Previous();
return 1;
case 'M':
case 'm':
playback->Previous();
return 1;
}
}
}

View File

@ -66,7 +66,8 @@ GaplessTransport::GaplessTransport()
: volume(1.0)
, state(PlaybackStopped)
, nextPlayer(nullptr)
, nextCanStart(false) {
, nextCanStart(false)
, muted(false) {
this->output = Player::CreateDefaultOutput();
}
@ -256,6 +257,18 @@ void GaplessTransport::SetPosition(double seconds) {
}
}
bool GaplessTransport::IsMuted() {
return this->muted;
}
void GaplessTransport::SetMuted(bool muted) {
if (this->muted != muted) {
this->muted = muted;
this->output->SetVolume(muted ? 0.0f : this->volume);
this->VolumeChanged();
}
}
double GaplessTransport::Volume() {
return this->volume;
}

View File

@ -63,6 +63,9 @@ namespace musik { namespace core { namespace audio {
virtual double Volume();
virtual void SetVolume(double volume);
virtual bool IsMuted();
virtual void SetMuted(bool muted);
virtual PlaybackState GetPlaybackState();
private:
@ -93,6 +96,7 @@ namespace musik { namespace core { namespace audio {
Player* nextPlayer;
double volume;
bool nextCanStart;
bool muted;
};
} } }

View File

@ -76,6 +76,9 @@ namespace musik { namespace core { namespace audio {
virtual double Volume() = 0;
virtual void SetVolume(double volume) = 0;
virtual bool IsMuted() = 0;
virtual void SetMuted(bool muted) = 0;
virtual PlaybackState GetPlaybackState() = 0;
};

View File

@ -62,6 +62,9 @@ namespace musik { namespace core { namespace sdk {
virtual double GetVolume() = 0;
virtual void SetVolume(double volume) = 0;
virtual bool IsMuted() = 0;
virtual void ToggleMute() = 0;
virtual size_t GetIndex() = 0;
virtual size_t Count() = 0;
};

View File

@ -211,27 +211,14 @@ void LibraryLayout::OnSearchResultSelected(
this->browseLayout->ScrollTo(fieldType, fieldId);
}
IWindowPtr LibraryLayout::FocusTransportNext() {
if (this->transportView->FocusNext()) {
return this->transportView;
}
this->transportView->SetFocus(TransportWindow::FocusNone);
return this->visibleLayout->FocusFirst();
}
IWindowPtr LibraryLayout::FocusTransportPrev() {
if (this->transportView->FocusPrev()) {
return this->transportView;
}
this->transportView->SetFocus(TransportWindow::FocusNone);
return this->visibleLayout->FocusLast();
}
IWindowPtr LibraryLayout::FocusNext() {
if (this->transportView->IsFocused()) {
return this->FocusTransportNext();
if (this->transportView->FocusNext()) {
return this->transportView;
}
this->transportView->Blur();
return this->visibleLayout->FocusFirst();
}
return this->visibleLayout->FocusNext();
@ -239,7 +226,12 @@ IWindowPtr LibraryLayout::FocusNext() {
IWindowPtr LibraryLayout::FocusPrev() {
if (this->transportView->IsFocused()) {
return this->FocusTransportPrev();
if (this->transportView->FocusPrev()) {
return this->transportView;
}
this->transportView->Blur();
return this->visibleLayout->FocusLast();
}
return this->visibleLayout->FocusPrev();
@ -299,6 +291,16 @@ bool LibraryLayout::KeyPress(const std::string& key) {
this->ShowTrackSearch();
return true;
}
else if (this->GetFocus() == this->transportView && key == "KEY_UP") {
this->transportView->Blur();
this->visibleLayout->FocusLast();
return true;
}
else if (this->GetFocus() == this->transportView && key == "KEY_DOWN") {
this->transportView->Blur();
this->visibleLayout->FocusFirst();
return true;
}
/* forward to the visible layout */
else if (this->visibleLayout && this->visibleLayout->KeyPress(key)) {
return true;

View File

@ -96,9 +96,6 @@ namespace musik {
void OnLayoutChanged();
void UpdateShortcutsWindow();
cursespp::IWindowPtr FocusTransportNext();
cursespp::IWindowPtr FocusTransportPrev();
PlaybackService& playback;
musik::core::audio::ITransport& transport;
musik::core::LibraryPtr library;

View File

@ -302,7 +302,20 @@ size_t PlaybackService::Count() {
}
void PlaybackService::ToggleRepeatMode() {
playback::ToggleRepeatMode(*this);
PlaybackService::RepeatMode mode = GetRepeatMode();
switch (mode) {
case PlaybackService::RepeatNone:
SetRepeatMode(PlaybackService::RepeatList);
break;
case PlaybackService::RepeatList:
SetRepeatMode(PlaybackService::RepeatTrack);
break;
default:
SetRepeatMode(PlaybackService::RepeatNone);
break;
}
}
void PlaybackService::Play(TrackList& tracks, size_t index) {
@ -351,6 +364,14 @@ void PlaybackService::PauseOrResume() {
}
}
bool PlaybackService::IsMuted() {
return transport.IsMuted();
}
void PlaybackService::ToggleMute() {
transport.SetMuted(!transport.IsMuted());
}
void PlaybackService::SetVolume(double vol) {
transport.SetVolume(vol);
}

View File

@ -84,6 +84,8 @@ namespace musik {
virtual double GetVolume();
virtual void SetVolume(double vol);
virtual void PauseOrResume();
virtual bool IsMuted();
virtual void ToggleMute();
/* app-specific implementation */
musik::core::audio::ITransport& GetTransport() { return this->transport; }

View File

@ -58,7 +58,11 @@ GlobalHotkeys::~GlobalHotkeys() {
}
bool GlobalHotkeys::Handle(const std::string& kn) {
if (Hotkeys::Is(Hotkeys::TogglePause, kn)) {
if (Hotkeys::Is(Hotkeys::ToggleMute, kn)) {
this->playback.ToggleMute();
return true;
}
else if (Hotkeys::Is(Hotkeys::TogglePause, kn)) {
playback::PauseOrResume(this->transport);
return true;
}
@ -87,7 +91,7 @@ bool GlobalHotkeys::Handle(const std::string& kn) {
return true;
}
else if (Hotkeys::Is(Hotkeys::ToggleRepeat, kn)) {
playback::ToggleRepeatMode(this->playback);
this->playback.ToggleRepeatMode();
return true;
}
else if (Hotkeys::Is(Hotkeys::ToggleShuffle, kn)) {

View File

@ -67,6 +67,7 @@ static std::unordered_map<std::string, Id> NAME_TO_ID = {
{ "navigate_console", Id::NavigateConsole },
{ "navigate_jump_to_playing", Id::NavigateJumpToPlaying },
{ "playback_toggle_mute", Id::ToggleMute },
{ "playback_toggle_pause", Id::TogglePause },
{ "playback_next", Id::Next },
{ "playback_previous", Id::Previous },
@ -98,8 +99,9 @@ static std::unordered_map<Id, std::string, EnumHasher> ID_TO_DEFAULT = {
{ Id::NavigateLibraryPlayQueue, "n" },
{ Id::NavigateSettings, "s" },
{ Id::NavigateConsole, "`" },
{ Id::NavigateJumpToPlaying, "m" },
{ Id::NavigateJumpToPlaying, "x" },
{ Id::ToggleMute, "m" },
{ Id::TogglePause, "^P" },
{ Id::Next, "l" },
{ Id::Previous, "j" },

View File

@ -63,6 +63,7 @@ namespace musik {
ToggleVisualizer,
/* playback */
ToggleMute,
TogglePause,
Next,
Previous,

View File

@ -65,23 +65,6 @@ namespace musik {
}
}
void ToggleRepeatMode(PlaybackService& playback) {
PlaybackService::RepeatMode mode = playback.GetRepeatMode();
switch (mode) {
case PlaybackService::RepeatNone:
playback.SetRepeatMode(PlaybackService::RepeatList);
break;
case PlaybackService::RepeatList:
playback.SetRepeatMode(PlaybackService::RepeatTrack);
break;
default:
playback.SetRepeatMode(PlaybackService::RepeatNone);
break;
}
}
void VolumeUp(ITransport& transport) {
transport.SetVolume(transport.Volume() + 0.05);
}

View File

@ -53,8 +53,6 @@ namespace musik {
void SeekBack(musik::core::audio::ITransport& transport);
void PauseOrResume(musik::core::audio::ITransport& transport);
void ToggleRepeatMode(PlaybackService& playback);
}
}
}

View File

@ -200,11 +200,11 @@ static size_t writePlayingFormat(
}
static inline bool inc(const std::string& kn) {
return (kn == "KEY_UP" || kn == "KEY_RIGHT");
return (/*kn == "KEY_UP" ||*/ kn == "KEY_RIGHT");
}
static inline bool dec(const std::string& kn) {
return (kn == "KEY_DOWN" || kn == "KEY_LEFT");
return (/*kn == "KEY_DOWN" ||*/ kn == "KEY_LEFT");
}
TransportWindow::TransportWindow(musik::box::PlaybackService& playback)
@ -261,6 +261,10 @@ bool TransportWindow::KeyPress(const std::string& kn) {
playback::VolumeDown(this->transport);
return true;
}
else if (kn == "KEY_ENTER") {
transport.SetMuted(!transport.IsMuted());
return true;
}
}
else if (this->focus == FocusTime) {
if (inc(kn)) {
@ -351,12 +355,18 @@ void TransportWindow::Update(TimeMode timeMode) {
WINDOW *c = this->GetContent();
bool paused = (transport.GetPlaybackState() == ITransport::PlaybackPaused);
bool stopped = (transport.GetPlaybackState() == ITransport::PlaybackStopped);
bool muted = transport.IsMuted();
int64 gb = COLOR_PAIR(CURSESPP_TEXT_ACTIVE);
int64 disabled = COLOR_PAIR(CURSESPP_TEXT_DISABLED);
int64 volumeAttrs = (this->focus == FocusVolume)
? COLOR_PAIR(CURSESPP_TEXT_FOCUSED) : -1;
int64 volumeAttrs = -1;
if (this->focus == FocusVolume) {
volumeAttrs = COLOR_PAIR(CURSESPP_TEXT_FOCUSED);
}
else if (muted) {
volumeAttrs = gb;
}
int64 timerAttrs = (this->focus == FocusTime)
? COLOR_PAIR(CURSESPP_TEXT_FOCUSED) : -1;
@ -409,16 +419,23 @@ void TransportWindow::Update(TimeMode timeMode) {
int volumePercent = (size_t) round(this->transport.Volume() * 100.0f) - 1;
int thumbOffset = std::min(9, (volumePercent * 10) / 100);
std::string volume = "vol ";
std::string volume;
for (int i = 0; i < 10; i++) {
volume += (i == thumbOffset) ? "" : "";
if (muted) {
volume = "muted ";
}
else {
volume = "vol ";
volume += boost::str(boost::format(
" %d") % (int) std::round(this->transport.Volume() * 100));
for (int i = 0; i < 10; i++) {
volume += (i == thumbOffset) ? "" : "";
}
volume += "%% ";
volume += boost::str(boost::format(
" %d") % (int)std::round(this->transport.Volume() * 100));
volume += "%% ";
}
/* repeat mode setup */
@ -485,7 +502,7 @@ void TransportWindow::Update(TimeMode timeMode) {
const std::string totalTime = duration::Duration(secondsTotal);
int bottomRowControlsWidth =
u8cols(volume) - 1 + /* -1 for escaped percent sign */
u8cols(volume) - (muted ? 0 : 1) + /* -1 for escaped percent sign when not muted */
u8cols(currentTime) + 1 + /* +1 for space padding */
/* timer track with thumb */
1 + u8cols(totalTime) + /* +1 for space padding */