diff --git a/src/effects/nyquist/Nyquist.cpp b/src/effects/nyquist/Nyquist.cpp index 3ba86ddb8..32efc085f 100644 --- a/src/effects/nyquist/Nyquist.cpp +++ b/src/effects/nyquist/Nyquist.cpp @@ -544,8 +544,11 @@ bool NyquistEffect::Init() for ( auto t : TrackList::Get( *project ).Selected< const WaveTrack >() ) { - if (WaveTrackView::Get(*t).GetDisplay() - != WaveTrackViewConstants::Spectrum || + const auto displays = WaveTrackView::Get(*t).GetDisplays(); + bool hasSpectral = + make_iterator_range( displays.begin(), displays.end()) + .contains( WaveTrackViewConstants::Spectrum ); + if ( !hasSpectral || !(t->GetSpectrogramSettings().SpectralSelectionEnabled())) { bAllowSpectralEditing = false; break; @@ -1069,7 +1072,12 @@ bool NyquistEffect::ProcessOne() [&](const WaveTrack *wt) { type = wxT("wave"); spectralEditp = mCurTrack[0]->GetSpectrogramSettings().SpectralSelectionEnabled()? wxT("T") : wxT("NIL"); - switch ( WaveTrackView::Get( *wt ).GetDisplay() ) + // To do: accommodate split views + auto viewType = WaveTrackViewConstants::NoDisplay; + auto displays = WaveTrackView::Get( *wt ).GetDisplays(); + if (!displays.empty()) + viewType = displays[0]; + switch ( viewType ) { case Waveform: view = (mCurTrack[0]->GetWaveformSettings().scaleType == 0) ? wxT("\"Waveform\"") : wxT("\"Waveform (dB)\""); diff --git a/src/menus/SelectMenus.cpp b/src/menus/SelectMenus.cpp index 6210bfb1f..65d2f6edd 100644 --- a/src/menus/SelectMenus.cpp +++ b/src/menus/SelectMenus.cpp @@ -35,8 +35,9 @@ void DoNextPeakFrequency(AudacityProject &project, bool up) // Find the first selected wave track that is in a spectrogram view. const WaveTrack *pTrack {}; for ( auto wt : tracks.Selected< const WaveTrack >() ) { - const auto display = WaveTrackView::Get( *wt ).GetDisplay(); - if (display == WaveTrackViewConstants::Spectrum) { + const auto displays = WaveTrackView::Get( *wt ).GetDisplays(); + if ( make_iterator_range( displays.begin(), displays.end() ) + .contains( WaveTrackViewConstants::Spectrum) ) { pTrack = wt; break; } diff --git a/src/tracks/playabletrack/wavetrack/ui/WaveTrackControls.cpp b/src/tracks/playabletrack/wavetrack/ui/WaveTrackControls.cpp index 77ae52c87..000f4318e 100644 --- a/src/tracks/playabletrack/wavetrack/ui/WaveTrackControls.cpp +++ b/src/tracks/playabletrack/wavetrack/ui/WaveTrackControls.cpp @@ -599,19 +599,23 @@ void WaveTrackMenuTable::InitMenu(Menu *pMenu, void *pUserData) std::vector checkedIds; - const auto display = WaveTrackView::Get( *pTrack ).GetDisplay(); - checkedIds.push_back( - display == WaveTrackViewConstants::Waveform - ? (pTrack->GetWaveformSettings().isLinear() - ? OnWaveformID : OnWaveformDBID) - : OnSpectrumID); + const auto displays = WaveTrackView::Get( *pTrack ).GetDisplays(); + for ( auto display : displays ) { + checkedIds.push_back( + display == WaveTrackViewConstants::Waveform + ? (pTrack->GetWaveformSettings().isLinear() + ? OnWaveformID : OnWaveformDBID) + : OnSpectrumID); + } // Bug 1253. Shouldn't open preferences if audio is busy. // We can't change them on the fly yet anyway. auto gAudioIO = AudioIOBase::Get(); const bool bAudioBusy = gAudioIO->IsBusy(); - pMenu->Enable(OnSpectrogramSettingsID, - (display == WaveTrackViewConstants::Spectrum) && !bAudioBusy); + bool hasSpectrum = + make_iterator_range( displays.begin(), displays.end() ) + .contains( WaveTrackViewConstants::Spectrum ); + pMenu->Enable(OnSpectrogramSettingsID, hasSpectrum && !bAudioBusy); AudacityProject *const project = ::GetActiveProject(); auto &tracks = TrackList::Get( *project ); @@ -683,9 +687,9 @@ void WaveTrackMenuTable::InitMenu(Menu *pMenu, void *pUserData) BEGIN_POPUP_MENU(WaveTrackMenuTable) POPUP_MENU_SEPARATOR() - POPUP_MENU_RADIO_ITEM(OnWaveformID, _("Wa&veform"), OnSetDisplay) - POPUP_MENU_RADIO_ITEM(OnWaveformDBID, _("&Waveform (dB)"), OnSetDisplay) - POPUP_MENU_RADIO_ITEM(OnSpectrumID, _("&Spectrogram"), OnSetDisplay) + POPUP_MENU_CHECK_ITEM(OnWaveformID, _("Wa&veform"), OnSetDisplay) + POPUP_MENU_CHECK_ITEM(OnWaveformDBID, _("&Waveform (dB)"), OnSetDisplay) + POPUP_MENU_CHECK_ITEM(OnSpectrumID, _("&Spectrogram"), OnSetDisplay) POPUP_MENU_ITEM(OnSpectrogramSettingsID, _("S&pectrogram Settings..."), OnSpectrogramSettings) POPUP_MENU_SEPARATOR() @@ -702,11 +706,15 @@ BEGIN_POPUP_MENU(WaveTrackMenuTable) #endif WaveTrack *const pTrack = static_cast(mpTrack); - if( pTrack && - WaveTrackView::Get( *pTrack ).GetDisplay() - != WaveTrackViewConstants::Spectrum ){ - POPUP_MENU_SEPARATOR() - POPUP_MENU_SUB_MENU(OnWaveColorID, _("&Wave Color"), WaveColorMenuTable) + if ( pTrack ) { + const auto displays = WaveTrackView::Get( *pTrack ).GetDisplays(); + bool hasWaveform = + make_iterator_range( displays.begin(), displays.end() ) + .contains( WaveTrackViewConstants::Waveform ); + if( hasWaveform ){ + POPUP_MENU_SEPARATOR() + POPUP_MENU_SUB_MENU(OnWaveColorID, _("&Wave Color"), WaveColorMenuTable) + } } POPUP_MENU_SEPARATOR() @@ -736,7 +744,8 @@ void WaveTrackMenuTable::OnSetDisplay(wxCommandEvent & event) id = Spectrum; break; } - const bool wrongType = WaveTrackView::Get( *pTrack ).GetDisplay() != id; + const auto displays = WaveTrackView::Get( *pTrack ).GetDisplays(); + const bool wrongType = !(displays.size() == 1 && displays[0] == id); const bool wrongScale = (id == Waveform && pTrack->GetWaveformSettings().isLinear() != linear); diff --git a/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.cpp b/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.cpp index efab68bc1..bd9931763 100644 --- a/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.cpp +++ b/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.cpp @@ -113,18 +113,23 @@ WaveTrackView::DoDetailedHitTest return { false, results }; } -auto WaveTrackView::GetDisplay() const -> WaveTrackDisplay +auto WaveTrackView::GetDisplays() const -> std::vector { - // To do: make the return a vector of values. For now, just report the - // last sub-view that is visible. - WaveTrackDisplay display{ WaveTrackViewConstants::NoDisplay }; + // Collect the display types of visible views and sort them by position + using Pair = std::pair< int, WaveTrackDisplay >; + std::vector< Pair > pairs; size_t ii = 0; WaveTrackSubViews::ForEach( [&]( const WaveTrackSubView &subView ){ - if ( mPlacements[ii].fraction > 0 ) - display = subView.SubViewType(); + auto &placement = mPlacements[ii]; + if ( placement.fraction > 0 ) + pairs.emplace_back( placement.index, subView.SubViewType() ); ++ii; } ); - return display; + std::sort( pairs.begin(), pairs.end() ); + std::vector results; + for ( const auto &pair : pairs ) + results.push_back( pair.second ); + return results; } void WaveTrackView::SetDisplay(WaveTrackDisplay display) diff --git a/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.h b/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.h index 92ec347b2..396e24b7a 100644 --- a/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.h +++ b/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.h @@ -69,7 +69,7 @@ public: using WaveTrackDisplay = WaveTrackViewConstants::Display; - WaveTrackDisplay GetDisplay() const; + std::vector GetDisplays() const; void SetDisplay(WaveTrackDisplay display); const WaveTrackSubViewPlacements &SavePlacements() const