void SjPlayer::ReceiveSignal(int signal, uintptr_t extraLong) { if( !m_isInitialized ) { return; } if( signal == THREAD_PREPARE_NEXT || signal == THREAD_OUT_OF_DATA ) { // just stop after this track? if( m_stopAfterThisTrack || m_stopAfterEachTrack ) { if( signal == THREAD_OUT_OF_DATA ) { Stop(); // Stop() clears the m_stopAfterThisTrack flag if( HasNextIgnoreAP() ) // make sure, the next hit on play goes to the next track, see { // http://www.silverjuke.net/forum/topic-1769.html GotoNextIgnoreAP(false); g_mainFrame->UpdateDisplay(); } } wxLogDebug(wxT(" SjPlayer::ReceiveSignal(): \"stop after this/each track\" executed.")); return; } } // more signal handling in the implementation part DoReceiveSignal(signal, extraLong); }
wxString SjMainFrame::GetNextMenuTitle() { if( !HasNextIgnoreAP() && HasNextRegardAP() ) { wxString from; if( m_autoCtrl.m_autoPlayMusicSelId == 0 ) { from = _("Current view"); } else { SjAdvSearch advSearch = g_advSearchModule->GetSearchById(m_autoCtrl.m_autoPlayMusicSelId); from = advSearch.GetName(); } return wxString::Format(_("Next track from \"%s\""), from.c_str()); } else { return _("Next track"); } }
void SjMainFrame::OnSkinDisplayEvent(int targetId, SjSkinValue& value, long accelFlags) { if( targetId >= IDT_DISPLAY_LINE_FIRST && targetId <= IDT_DISPLAY_LINE_LAST ) { long displayLine = targetId-IDT_DISPLAY_LINE_FIRST; GotDisplayInputFromUser(); if( !m_display.m_msg1.IsEmpty() ) { ClearDisplayMsg(); return; } long queuePos = m_display.m_firstLineQueuePos + displayLine; if( queuePos >= 0 && queuePos < m_player.m_queue.GetCount() ) { if( value.value == SJ_SUBITEM_ICONRIGHT && IsOpAvailable(SJ_OP_UNQUEUE) ) { UnqueueByPos(queuePos); } else if( value.value == SJ_SUBITEM_ICONLEFT ) { if( m_player.m_queue.GetCurrPos() == queuePos ) { if( IsOpAvailable(SJ_OP_PLAYPAUSE) ) { PlayOrPause(accelFlags != 0); } } else if( m_player.m_queue.WasPlayed(queuePos) ) { if( IsOpAvailable(SJ_OP_EDIT_QUEUE) ) { m_player.m_queue.ResetPlayCount(queuePos); UpdateDisplay(); } } } else if( value.value == SJ_SUBITEM_TEXT_DCLICK && IsOpAvailable(SJ_OP_EDIT_QUEUE) ) { #ifdef DEBUG_DISPLAY SjPlaylistEntry& urlInfo = m_player.m_queue.GetInfo(queuePos); wxLogDebug("Line pos. %i: %s - %s", (int)queuePos, urlInfo.GetLeadArtistName().c_str(), urlInfo.GetTrackName().c_str()); #endif if( m_player.m_queue.GetCurrPos() == queuePos && IsPlaying() ) { ; // PlayOrPause(); // better do nothing } else { m_player.GotoAbsPos(queuePos, accelFlags!=0); if( !IsPlaying() ) { Play(); UpdateDisplay(); } } } else if( (value.value == SJ_SUBITEM_TEXT_MOUSEDOWN || value.value == SJ_SUBITEM_TEXT/*_MOUSEUP*/ ) && IsOpAvailable(SJ_OP_EDIT_QUEUE) ) { MarkDisplayTrack(targetId, value.value == SJ_SUBITEM_TEXT_MOUSEDOWN, value.vmin); } else if( value.value == SJ_SUBITEM_TEXT_MIDDLECLICK ) { if( g_accelModule->m_middleMouseAction ) { long queueId = m_player.m_queue.GetIdByPos(queuePos); if( queueId == 0 ) { return; } if( !m_display.m_selectedIds.Lookup(queueId) ) { // mark the item under the mouse if it is not marked m_display.m_selectedIds.Clear(); m_display.m_selectedIds.Insert(queueId, 1); m_display.m_selectedAnchorId = queueId; UpdateDisplay(); } m_display.m_selectedIdsTimestamp = SjTools::GetMsTicks(); m_display.m_selectedIdsLockMs = SJ_DISPLAY_SELECTION_LOCK_MS; m_contextMenuClickedUrls = m_player.m_queue.GetUrlsByIds(m_display.m_selectedIds); m_contextMenuClickedId = queueId; switch( g_accelModule->m_middleMouseAction ) { case SJ_ACCEL_MID_OPENS_TAG_EDITOR: if( IsAllAvailable() ) { g_tagEditorModule->OpenTagEditor(new SjDisplayEditDlg()); } break; } } } } else { // click on empty line; remove all marks m_display.m_selectedIds.Clear(); m_display.m_selectedAnchorId = 0; UpdateDisplay(); } } else switch( targetId ) { // curr / next tracks case IDT_CURR_TRACK: if( value.value == SJ_SUBITEM_TEXT_DCLICK && !IsStopped() && IsPaused() && IsOpAvailable(SJ_OP_PLAYPAUSE) ) { Play(); UpdateDisplay(); } break; case IDT_NEXT_TRACK: if( value.value == SJ_SUBITEM_TEXT_DCLICK && !IsStopped() && !GetShuffle() && HasNextIgnoreAP() && IsOpAvailable(SJ_OP_EDIT_QUEUE) ) { GotoNextRegardAP(accelFlags!=0); if( !IsPlaying() ) Play(); UpdateDisplay(); } break; // main volume case IDT_MAIN_VOL_UP: case IDT_MAIN_VOL_DOWN: if( IsOpAvailable(SJ_OP_MAIN_VOL) ) { SetRelMainVol(targetId==IDT_MAIN_VOL_UP? 8 : -8); SetSkinTargetValue(IDT_MAIN_VOL_MUTE, m_player.GetMainVolMute()? 1 : 0); // maybe later -- SetDisplayMsg(_("Volume")+wxString::Format(": %i%%", (m_player.GetMainVolume()*100)/255), SDM_STATE_CHANGE_MS); } break; case IDT_MAIN_VOL_SLIDER: if( IsOpAvailable(SJ_OP_MAIN_VOL) ) { SetAbsMainVol(value.value); SetSkinTargetValue(IDT_MAIN_VOL_MUTE, m_player.GetMainVolMute()? 1 : 0); // maybe later -- SetDisplayMsg(_("Volume")+wxString::Format(": %i%%", (m_player.GetMainVolume()*100)/255), SDM_STATE_CHANGE_MS); } break; case IDT_MAIN_VOL_MUTE: if( IsOpAvailable(SJ_OP_MAIN_VOL) ) { m_player.ToggleMainVolMute(); UpdateDisplay(); } break; // seek case IDT_SEEK: if( IsOpAvailable(SJ_OP_EDIT_QUEUE) ) { SjPlayer* recentPlayer = &g_mainFrame->m_player; recentPlayer->SeekAbs(value.value*SJ_SEEK_RESOLUTION); UpdateDisplay(); } break; case IDT_SEEK_BWD: case IDT_SEEK_FWD: if( IsOpAvailable(SJ_OP_EDIT_QUEUE) ) { SjPlayer* recentPlayer = &g_mainFrame->m_player; recentPlayer->SeekRel(targetId==IDT_SEEK_BWD? -5000 : 5000); UpdateDisplay(); } break; // misc. case IDO_DISPLAY_COVER_EXPLR: { SjPlayer* recentPlayer = &g_mainFrame->m_player; g_tools->ExploreUrl(m_columnMixer.GetTrackCoverUrl(recentPlayer->m_queue.GetUrlByPos(-1))); } break; case IDT_DISPLAY_COVER: case IDO_DISPLAY_COVER: // IDO_DISPLAY_COVER is only used for the menu item if( value.value == SJ_SUBITEM_TEXT_DCLICK || (value.value == SJ_SUBITEM_TEXT_MIDDLECLICK && g_accelModule->m_middleMouseAction==SJ_ACCEL_MID_OPENS_TAG_EDITOR) || targetId != IDT_DISPLAY_COVER ) { // open the cover editor for the display cover SjPlayer* recentPlayer = &g_mainFrame->m_player; wxString trackUrl = recentPlayer->m_queue.GetUrlByPos(-1); wxSqlt sql; sql.Query(wxT("SELECT albumid FROM tracks WHERE url='") + sql.QParam(trackUrl) + wxT("';")); unsigned long albumId = sql.Next()? sql.GetLong(0) : 0; wxString selArtUrl = m_columnMixer.GetTrackCoverUrl(recentPlayer->m_queue.GetUrlByPos(-1)); wxArrayLong artIds; wxArrayString artUrls; g_mainFrame->m_libraryModule->GetPossibleAlbumArts(albumId, artIds, &artUrls, true/*addAutoCover*/); g_artEditorModule->OnArtMenu(g_mainFrame, artUrls, selArtUrl, albumId, IDM_OPENARTEDITOR, NULL, true /*IsPlaylistCover*/ ); /* // simulate a double click on the cover row or explore the cover url long index, r; SjCol* col = m_columnMixer.GetMaskedCol(recentPlayer->m_queue.GetUrlByPos(recentPlayer->m_queue.GetCurrPos()), index); SjAlbumCoverRow* row; if( col ) { for( r = 0; r < col->m_rowCount; r++ ) { if( col->m_rows[r]->m_roughType == SJ_RRTYPE_COVER ) { row = (SjAlbumCoverRow*)col->m_rows[r]; row->IsPlaylistCover(true); // if set to true, "follow playlist" is always active row->OnMiddleClick(false); break; } } delete col; } */ } break; case IDT_DISPLAY_UP: GotDisplayInputFromUser(); if( m_display.m_scrollPos == -1 ) { m_display.m_scrollPos = GetQueuePos(); } if( m_display.m_scrollPos >= 1 ) { m_display.m_scrollPos--; UpdateDisplay(); } break; case IDT_DISPLAY_DOWN: GotDisplayInputFromUser(); if( m_display.m_scrollPos == -1 ) { m_display.m_scrollPos = GetQueuePos(); } m_display.m_scrollPos++; // corrected in UpdateDisplay() UpdateDisplay(); break; case IDT_DISPLAY_V_SCROLL: GotDisplayInputFromUser(); m_display.m_scrollPos = value.value; UpdateDisplay(); break; } }