From 2f544bda7a7cf52a2d2cd3e88606d89bc5b73926 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Tue, 9 Jul 2019 16:41:41 -0400 Subject: [PATCH] Reimplement WaveTrackView::SetDisplay, eliminating mDisplay... ... and much generality for the future in reporting the sub-view division to TrackPanel. SetDisplay will have the effect of making one of possibly multiple views take up all the height. Where we need to save and restore or otherwise copy the sub-views, there is more information now than just one enum value. --- src/prefs/SpectrumPrefs.cpp | 4 +- src/prefs/SpectrumPrefs.h | 4 +- .../wavetrack/ui/WaveTrackControls.cpp | 2 +- .../wavetrack/ui/WaveTrackView.cpp | 81 +++++++++++++++---- .../wavetrack/ui/WaveTrackView.h | 17 +++- 5 files changed, 85 insertions(+), 23 deletions(-) diff --git a/src/prefs/SpectrumPrefs.cpp b/src/prefs/SpectrumPrefs.cpp index 65f272cdf..51dae7154 100644 --- a/src/prefs/SpectrumPrefs.cpp +++ b/src/prefs/SpectrumPrefs.cpp @@ -49,7 +49,7 @@ SpectrumPrefs::SpectrumPrefs(wxWindow * parent, wxWindowID winid, WaveTrack *wt) wt->GetSpectrumBounds(&mOrigMin, &mOrigMax); mTempSettings.maxFreq = mOrigMax; mTempSettings.minFreq = mOrigMin; - mOrigDisplay = WaveTrackView::Get( *mWt ).GetDisplay(); + mOrigPlacements = WaveTrackView::Get( *mWt ).SavePlacements(); } else { mTempSettings = mOrigSettings = SpectrogramSettings::defaults(); @@ -424,7 +424,7 @@ void SpectrumPrefs::Rollback() if (mWt && isOpenPage) { auto channels = TrackList::Channels(mWt); for (auto channel : channels) - WaveTrackView::Get( *channel ).SetDisplay( mOrigDisplay ); + WaveTrackView::Get( *channel ).RestorePlacements( mOrigPlacements ); } if (isOpenPage) { diff --git a/src/prefs/SpectrumPrefs.h b/src/prefs/SpectrumPrefs.h index 4158e0f42..f22e1e7e1 100644 --- a/src/prefs/SpectrumPrefs.h +++ b/src/prefs/SpectrumPrefs.h @@ -23,6 +23,7 @@ #include "../Experimental.h" +#include #include #include "../tracks/playabletrack/wavetrack/ui/WaveTrackViewConstants.h" @@ -38,6 +39,7 @@ struct FFTParam; class ShuttleGui; class SpectrogramSettings; class WaveTrack; +struct WaveTrackSubViewPlacement; #define SPECTRUM_PREFS_PLUGIN_SYMBOL ComponentInterfaceSymbol{ XO("Spectrum") } @@ -98,7 +100,7 @@ class SpectrumPrefs final : public PrefsPanel SpectrogramSettings mTempSettings, mOrigSettings; - WaveTrackViewConstants::Display mOrigDisplay; + std::vector mOrigPlacements; float mOrigMin, mOrigMax; bool mPopulating; diff --git a/src/tracks/playabletrack/wavetrack/ui/WaveTrackControls.cpp b/src/tracks/playabletrack/wavetrack/ui/WaveTrackControls.cpp index 9ec4a0ecc..77ae52c87 100644 --- a/src/tracks/playabletrack/wavetrack/ui/WaveTrackControls.cpp +++ b/src/tracks/playabletrack/wavetrack/ui/WaveTrackControls.cpp @@ -889,7 +889,7 @@ void WaveTrackMenuTable::OnMergeStereo(wxCommandEvent &) view.SetMinimized(bBothMinimizedp); partnerView.SetMinimized(bBothMinimizedp); - partnerView.SetDisplay( view.GetDisplay() ); + partnerView.RestorePlacements( view.SavePlacements() ); //On Demand - join the queues together. if (ODManager::IsInstanceCreated()) diff --git a/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.cpp b/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.cpp index c88296345..efab68bc1 100644 --- a/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.cpp +++ b/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.cpp @@ -42,16 +42,20 @@ WaveTrackView::WaveTrackView( const std::shared_ptr &pTrack ) { WaveTrackSubViews::BuildAll(); - mDisplay = TracksPrefs::ViewModeChoice(); + auto display = TracksPrefs::ViewModeChoice(); // Force creation always: WaveformSettings &settings = static_cast< WaveTrack* >( pTrack.get() ) ->GetIndependentWaveformSettings(); - if (mDisplay == WaveTrackViewConstants::obsoleteWaveformDBDisplay) { - mDisplay = WaveTrackViewConstants::Waveform; + if (display == WaveTrackViewConstants::obsoleteWaveformDBDisplay) { + display = WaveTrackViewConstants::Waveform; settings.scaleType = WaveformSettings::stLogarithmic; } + + mPlacements.resize( WaveTrackSubViews::size() ); + + SetDisplay( display ); } WaveTrackView::~WaveTrackView() @@ -65,7 +69,7 @@ void WaveTrackView::CopyTo( Track &track ) const if ( const auto pOther = dynamic_cast< WaveTrackView* >( &other ) ) { // only one field is important to preserve in undo/redo history - pOther->mDisplay = mDisplay; + pOther->RestorePlacements( SavePlacements() ); } } @@ -109,22 +113,67 @@ WaveTrackView::DoDetailedHitTest return { false, results }; } -auto WaveTrackView::GetSubViews( const wxRect &rect ) -> Refinement +auto WaveTrackView::GetDisplay() const -> WaveTrackDisplay { - auto display = mDisplay; - std::shared_ptr pSubView; + // To do: make the return a vector of values. For now, just report the + // last sub-view that is visible. + WaveTrackDisplay display{ WaveTrackViewConstants::NoDisplay }; + size_t ii = 0; + WaveTrackSubViews::ForEach( [&]( const WaveTrackSubView &subView ){ + if ( mPlacements[ii].fraction > 0 ) + display = subView.SubViewType(); + ++ii; + } ); + return display; +} + +void WaveTrackView::SetDisplay(WaveTrackDisplay display) +{ + size_t ii = 0; WaveTrackSubViews::ForEach( [&,display]( WaveTrackSubView &subView ){ if ( subView.SubViewType() == display ) - pSubView = subView.shared_from_this(); + mPlacements[ii] = { 0, 1.0 }; + else + mPlacements[ii] = { -1, 0.0 }; + ++ii; } ); - if ( !pSubView ) - return {}; - return { - { - rect.GetTop(), - pSubView - } - }; +} + +auto WaveTrackView::GetSubViews( const wxRect &rect ) -> Refinement +{ + // Collect the visible views + using Pair = std::pair< float, std::shared_ptr< TrackView > >; + std::vector< Pair > pairs( mPlacements.size() ); + size_t ii = 0; + float total = 0; + WaveTrackSubViews::ForEach( [&]( WaveTrackSubView &subView ){ + const auto &placement = mPlacements[ii]; + auto index = placement.index; + auto fraction = placement.fraction; + if ( index >= 0 && fraction > 0.0 ) + total += fraction, + pairs[ index ] = { fraction, subView.shared_from_this() }; + ++ii; + } ); + + // Remove views we don't need + auto begin = pairs.begin(), end = pairs.end(), + newEnd = std::remove_if( begin, end, + []( const Pair &item ){ return !item.second; } ); + pairs.erase( newEnd, end ); + + // Assign coordinates + Refinement results; + results.reserve( pairs.size() ); + float partial = 0; + const auto top = rect.GetTop(); + const auto height = rect.GetHeight(); + for ( const auto &pair : pairs ) { + results.emplace_back( top + (partial / total) * height, pair.second ); + partial += pair.first; + } + + return results; } void WaveTrackView::DoSetMinimized( bool minimized ) diff --git a/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.h b/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.h index b78dbccee..92ec347b2 100644 --- a/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.h +++ b/src/tracks/playabletrack/wavetrack/ui/WaveTrackView.h @@ -24,6 +24,12 @@ public: virtual WaveTrackViewConstants::Display SubViewType() const = 0; }; +struct WaveTrackSubViewPlacement { + int index; + float fraction; +}; +using WaveTrackSubViewPlacements = std::vector< WaveTrackSubViewPlacement >; + class WaveTrackView; using WaveTrackSubViews = ClientData::Site< WaveTrackView, WaveTrackSubView, ClientData::SkipCopying, std::shared_ptr @@ -63,8 +69,13 @@ public: using WaveTrackDisplay = WaveTrackViewConstants::Display; - WaveTrackDisplay GetDisplay() const { return mDisplay; } - void SetDisplay(WaveTrackDisplay display) { mDisplay = display; } + WaveTrackDisplay GetDisplay() const; + void SetDisplay(WaveTrackDisplay display); + + const WaveTrackSubViewPlacements &SavePlacements() const + { return mPlacements; } + void RestorePlacements( const WaveTrackSubViewPlacements &placements ) + { mPlacements = placements; } private: // TrackPanelDrawable implementation @@ -83,7 +94,7 @@ private: protected: void DoSetMinimized( bool minimized ) override; - WaveTrackDisplay mDisplay; + WaveTrackSubViewPlacements mPlacements; }; // Helper for drawing routines