1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-17 00:20:06 +02:00

Implement Multi View checkbox menu item in wave track TCP...

... When it's off (default), Spectrum and Waveform buttons behave as before,
and dragging of the sub-view separator is disabled.

When it transitions to off, and the view is split, then the top sub-view takes
up the whole view.

When it transitions on, nothing visible happens.

When it is on, and you choose Spectrum or Waveform, then the corrsponding
sub-view toggles visibility.

When a sub-view is turned on by the menu item, it appears lowest.
This commit is contained in:
Paul Licameli 2020-01-01 15:22:21 -05:00
parent 30c37e9110
commit 0256156dec
3 changed files with 113 additions and 20 deletions

View File

@ -120,6 +120,7 @@ enum {
On24BitID, // |
OnFloatID, // <---
OnMultiViewID,
OnWaveformID,
OnSpectrumID,
OnSpectrogramSettingsID,
@ -567,6 +568,7 @@ protected:
PlayableTrackControls::InitMenuData *mpData;
void OnMultiView(wxCommandEvent & event);
void OnSetDisplay(wxCommandEvent & event);
void OnSpectrogramSettings(wxCommandEvent & event);
@ -602,7 +604,11 @@ void WaveTrackMenuTable::InitMenu(Menu *pMenu, void *pUserData)
std::vector<int> checkedIds;
const auto displays = WaveTrackView::Get( *pTrack ).GetDisplays();
const auto &view = WaveTrackView::Get( *pTrack );
if (view.GetMultiView())
checkedIds.push_back( OnMultiViewID );
const auto displays = view.GetDisplays();
for ( auto display : displays ) {
checkedIds.push_back(
display == WaveTrackViewConstants::Waveform
@ -687,18 +693,28 @@ void WaveTrackMenuTable::InitMenu(Menu *pMenu, void *pUserData)
}
BEGIN_POPUP_MENU(WaveTrackMenuTable)
WaveTrack *const pTrack = static_cast<WaveTrack*>(mpTrack);
const auto &view = WaveTrackView::Get( *pTrack );
POPUP_MENU_SEPARATOR()
// View types are now a non-exclusive choice. The first two are mutually
// exclusive, but the view may be in a state with either of those, and also
// spectrogram, after a mouse drag. Clicking any of these three makes that
// view take up all the height.
POPUP_MENU_CHECK_ITEM(OnWaveformID, XO("Wa&veform"), OnSetDisplay)
POPUP_MENU_CHECK_ITEM(OnSpectrumID, XO("&Spectrogram"), OnSetDisplay)
POPUP_MENU_CHECK_ITEM(OnMultiViewID, XO("&Multi View"), OnMultiView)
if ( view.GetMultiView() ) {
POPUP_MENU_CHECK_ITEM(OnWaveformID, XO("Wa&veform"), OnSetDisplay)
POPUP_MENU_CHECK_ITEM(OnSpectrumID, XO("&Spectrogram"), OnSetDisplay)
}
else {
POPUP_MENU_RADIO_ITEM(OnWaveformID, XO("Wa&veform"), OnSetDisplay)
POPUP_MENU_RADIO_ITEM(OnSpectrumID, XO("&Spectrogram"), OnSetDisplay)
}
POPUP_MENU_ITEM(OnSpectrogramSettingsID, XO("S&pectrogram Settings..."), OnSpectrogramSettings)
POPUP_MENU_SEPARATOR()
// If these are enabled again, choose a hot key for Mono that does not conflict
// with Multi View
// POPUP_MENU_RADIO_ITEM(OnChannelMonoID, XO("&Mono"), OnChannelChange)
// POPUP_MENU_RADIO_ITEM(OnChannelLeftID, XO("&Left Channel"), OnChannelChange)
// POPUP_MENU_RADIO_ITEM(OnChannelRightID, XO("R&ight Channel"), OnChannelChange)
@ -711,9 +727,8 @@ BEGIN_POPUP_MENU(WaveTrackMenuTable)
POPUP_MENU_ITEM(OnSplitStereoMonoID, XO("Split Stereo to Mo&no"), OnSplitStereoMono)
#endif
WaveTrack *const pTrack = static_cast<WaveTrack*>(mpTrack);
if ( pTrack ) {
const auto displays = WaveTrackView::Get( *pTrack ).GetDisplays();
const auto displays = view.GetDisplays();
bool hasWaveform =
make_iterator_range( displays.begin(), displays.end() )
.contains( WaveTrackViewConstants::Waveform );
@ -730,6 +745,23 @@ BEGIN_POPUP_MENU(WaveTrackMenuTable)
END_POPUP_MENU()
void WaveTrackMenuTable::OnMultiView(wxCommandEvent & event)
{
const auto pTrack = static_cast<WaveTrack*>(mpData->pTrack);
const auto &view = WaveTrackView::Get( *pTrack );
bool multi = !view.GetMultiView();
WaveTrackView::WaveTrackDisplay display;
if ( !multi )
display = *view.GetDisplays().begin();
for (const auto channel : TrackList::Channels(pTrack)) {
auto &channelView = WaveTrackView::Get( *channel );
channelView.SetMultiView( multi );
if ( !multi )
// Whichever sub-view was on top will take up all
channelView.SetDisplay( display );
}
}
/// Set the Display mode based on the menu choice in the Track Menu.
void WaveTrackMenuTable::OnSetDisplay(wxCommandEvent & event)
{
@ -747,20 +779,28 @@ void WaveTrackMenuTable::OnSetDisplay(wxCommandEvent & event)
id = Spectrum; break;
}
const auto displays = WaveTrackView::Get( *pTrack ).GetDisplays();
const bool wrongType = !(displays.size() == 1 && displays[0] == id);
if (wrongType) {
auto &view = WaveTrackView::Get( *pTrack );
if ( view.GetMultiView() ) {
for (auto channel : TrackList::Channels(pTrack)) {
channel->SetLastScaleType();
WaveTrackView::Get( *channel )
.SetDisplay(WaveTrackView::WaveTrackDisplay(id));
WaveTrackView::Get( *channel ).ToggleSubView( id );
}
}
else {
const auto displays = view.GetDisplays();
const bool wrongType = !(displays.size() == 1 && displays[0] == id);
if (wrongType) {
for (auto channel : TrackList::Channels(pTrack)) {
channel->SetLastScaleType();
WaveTrackView::Get( *channel )
.SetDisplay(WaveTrackView::WaveTrackDisplay(id));
}
AudacityProject *const project = ::GetActiveProject();
ProjectHistory::Get( *project ).ModifyState(true);
AudacityProject *const project = ::GetActiveProject();
ProjectHistory::Get( *project ).ModifyState(true);
using namespace RefreshCode;
mpData->result = RefreshAll | UpdateVRuler;
using namespace RefreshCode;
mpData->result = RefreshAll | UpdateVRuler;
}
}
}
@ -896,6 +936,7 @@ void WaveTrackMenuTable::OnMergeStereo(wxCommandEvent &)
partnerView.SetMinimized(bBothMinimizedp);
partnerView.RestorePlacements( view.SavePlacements() );
partnerView.SetMultiView( view.GetMultiView() );
//On Demand - join the queues together.
if (ODManager::IsInstanceCreated())

View File

@ -197,6 +197,9 @@ public:
WaveTrackView &view, WaveTrackSubView &subView,
const TrackPanelMouseState &state )
{
if ( !view.GetMultiView() )
return {};
SubViewAdjuster adjuster{ view };
auto hit = adjuster.HitTest( subView,
state.state.GetY(), state.rect.GetTop(), state.rect.GetHeight() );
@ -470,8 +473,9 @@ void WaveTrackView::CopyTo( Track &track ) const
auto &other = TrackView::Get( track );
if ( const auto pOther = dynamic_cast< WaveTrackView* >( &other ) ) {
// only one field is important to preserve in undo/redo history
// only these fields are important to preserve in undo/redo history
pOther->RestorePlacements( SavePlacements() );
pOther->mMultiView = mMultiView;
}
}
@ -542,6 +546,47 @@ void WaveTrackView::SetDisplay(WaveTrackDisplay display)
DoSetDisplay( display );
}
void WaveTrackView::ToggleSubView(WaveTrackDisplay display)
{
size_t ii = 0;
size_t found = 0;
if ( WaveTrackSubViews::FindIf( [&]( const WaveTrackSubView &subView ) {
if ( subView.SubViewType() == display ) {
found = ii;
return true;
}
++ii;
return false;
} ) ) {
auto &foundPlacement = mPlacements[found];
if ( foundPlacement.fraction > 0.0 ) {
auto index = foundPlacement.index;
foundPlacement = { -1, 0.0 };
if (index >= 0) {
for ( auto &placement : mPlacements ) {
if ( placement.index > index )
--placement.index;
}
}
}
else {
float total = 0;
int greatest = -1;
unsigned nn = 0;
for ( const auto &placement : mPlacements ) {
if ( placement.fraction >= 0.0 && placement.index >= 0 ) {
total += placement.fraction;
greatest = std::max( greatest, placement.index );
++nn;
}
}
// Turn on the sub-view, putting it lowest, and with average of the
// heights of the other sub-views
foundPlacement = { greatest + 1, total / nn };
}
}
}
void WaveTrackView::DoSetDisplay(WaveTrackDisplay display)
{
size_t ii = 0;

View File

@ -91,6 +91,8 @@ public:
void RestorePlacements( const WaveTrackSubViewPlacements &placements )
{ mPlacements = placements; }
void ToggleSubView( WaveTrackDisplay id );
// Get all the sub-views, in a sequence that is unspecified but in
// correspondence with the result of SavePlacements
std::vector< std::shared_ptr< WaveTrackSubView > > GetAllSubViews();
@ -98,6 +100,9 @@ public:
// Return cached height of rect in last call of GetSubViews
wxCoord GetLastHeight() const { return mLastHeight; }
bool GetMultiView() const { return mMultiView; }
void SetMultiView( bool value ) { mMultiView = value; }
private:
void BuildSubViews() const;
void DoSetDisplay(WaveTrackDisplay display);
@ -121,6 +126,8 @@ protected:
WaveTrackSubViewPlacements mPlacements;
mutable wxCoord mLastHeight{};
bool mMultiView{ false };
};
// Helper for drawing routines