mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-17 16:40:07 +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:
parent
30c37e9110
commit
0256156dec
@ -120,6 +120,7 @@ enum {
|
|||||||
On24BitID, // |
|
On24BitID, // |
|
||||||
OnFloatID, // <---
|
OnFloatID, // <---
|
||||||
|
|
||||||
|
OnMultiViewID,
|
||||||
OnWaveformID,
|
OnWaveformID,
|
||||||
OnSpectrumID,
|
OnSpectrumID,
|
||||||
OnSpectrogramSettingsID,
|
OnSpectrogramSettingsID,
|
||||||
@ -567,6 +568,7 @@ protected:
|
|||||||
|
|
||||||
PlayableTrackControls::InitMenuData *mpData;
|
PlayableTrackControls::InitMenuData *mpData;
|
||||||
|
|
||||||
|
void OnMultiView(wxCommandEvent & event);
|
||||||
void OnSetDisplay(wxCommandEvent & event);
|
void OnSetDisplay(wxCommandEvent & event);
|
||||||
void OnSpectrogramSettings(wxCommandEvent & event);
|
void OnSpectrogramSettings(wxCommandEvent & event);
|
||||||
|
|
||||||
@ -602,7 +604,11 @@ void WaveTrackMenuTable::InitMenu(Menu *pMenu, void *pUserData)
|
|||||||
|
|
||||||
std::vector<int> checkedIds;
|
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 ) {
|
for ( auto display : displays ) {
|
||||||
checkedIds.push_back(
|
checkedIds.push_back(
|
||||||
display == WaveTrackViewConstants::Waveform
|
display == WaveTrackViewConstants::Waveform
|
||||||
@ -687,18 +693,28 @@ void WaveTrackMenuTable::InitMenu(Menu *pMenu, void *pUserData)
|
|||||||
}
|
}
|
||||||
|
|
||||||
BEGIN_POPUP_MENU(WaveTrackMenuTable)
|
BEGIN_POPUP_MENU(WaveTrackMenuTable)
|
||||||
|
|
||||||
|
WaveTrack *const pTrack = static_cast<WaveTrack*>(mpTrack);
|
||||||
|
const auto &view = WaveTrackView::Get( *pTrack );
|
||||||
|
|
||||||
POPUP_MENU_SEPARATOR()
|
POPUP_MENU_SEPARATOR()
|
||||||
|
|
||||||
// View types are now a non-exclusive choice. The first two are mutually
|
POPUP_MENU_CHECK_ITEM(OnMultiViewID, XO("&Multi View"), OnMultiView)
|
||||||
// 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
|
if ( view.GetMultiView() ) {
|
||||||
// view take up all the height.
|
POPUP_MENU_CHECK_ITEM(OnWaveformID, XO("Wa&veform"), OnSetDisplay)
|
||||||
POPUP_MENU_CHECK_ITEM(OnWaveformID, XO("Wa&veform"), OnSetDisplay)
|
POPUP_MENU_CHECK_ITEM(OnSpectrumID, XO("&Spectrogram"), 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_ITEM(OnSpectrogramSettingsID, XO("S&pectrogram Settings..."), OnSpectrogramSettings)
|
||||||
POPUP_MENU_SEPARATOR()
|
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(OnChannelMonoID, XO("&Mono"), OnChannelChange)
|
||||||
// POPUP_MENU_RADIO_ITEM(OnChannelLeftID, XO("&Left Channel"), OnChannelChange)
|
// POPUP_MENU_RADIO_ITEM(OnChannelLeftID, XO("&Left Channel"), OnChannelChange)
|
||||||
// POPUP_MENU_RADIO_ITEM(OnChannelRightID, XO("R&ight 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)
|
POPUP_MENU_ITEM(OnSplitStereoMonoID, XO("Split Stereo to Mo&no"), OnSplitStereoMono)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
WaveTrack *const pTrack = static_cast<WaveTrack*>(mpTrack);
|
|
||||||
if ( pTrack ) {
|
if ( pTrack ) {
|
||||||
const auto displays = WaveTrackView::Get( *pTrack ).GetDisplays();
|
const auto displays = view.GetDisplays();
|
||||||
bool hasWaveform =
|
bool hasWaveform =
|
||||||
make_iterator_range( displays.begin(), displays.end() )
|
make_iterator_range( displays.begin(), displays.end() )
|
||||||
.contains( WaveTrackViewConstants::Waveform );
|
.contains( WaveTrackViewConstants::Waveform );
|
||||||
@ -730,6 +745,23 @@ BEGIN_POPUP_MENU(WaveTrackMenuTable)
|
|||||||
END_POPUP_MENU()
|
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.
|
/// Set the Display mode based on the menu choice in the Track Menu.
|
||||||
void WaveTrackMenuTable::OnSetDisplay(wxCommandEvent & event)
|
void WaveTrackMenuTable::OnSetDisplay(wxCommandEvent & event)
|
||||||
{
|
{
|
||||||
@ -747,20 +779,28 @@ void WaveTrackMenuTable::OnSetDisplay(wxCommandEvent & event)
|
|||||||
id = Spectrum; break;
|
id = Spectrum; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto displays = WaveTrackView::Get( *pTrack ).GetDisplays();
|
auto &view = WaveTrackView::Get( *pTrack );
|
||||||
const bool wrongType = !(displays.size() == 1 && displays[0] == id);
|
if ( view.GetMultiView() ) {
|
||||||
if (wrongType) {
|
|
||||||
for (auto channel : TrackList::Channels(pTrack)) {
|
for (auto channel : TrackList::Channels(pTrack)) {
|
||||||
channel->SetLastScaleType();
|
WaveTrackView::Get( *channel ).ToggleSubView( id );
|
||||||
WaveTrackView::Get( *channel )
|
|
||||||
.SetDisplay(WaveTrackView::WaveTrackDisplay(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();
|
AudacityProject *const project = ::GetActiveProject();
|
||||||
ProjectHistory::Get( *project ).ModifyState(true);
|
ProjectHistory::Get( *project ).ModifyState(true);
|
||||||
|
|
||||||
using namespace RefreshCode;
|
using namespace RefreshCode;
|
||||||
mpData->result = RefreshAll | UpdateVRuler;
|
mpData->result = RefreshAll | UpdateVRuler;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -896,6 +936,7 @@ void WaveTrackMenuTable::OnMergeStereo(wxCommandEvent &)
|
|||||||
partnerView.SetMinimized(bBothMinimizedp);
|
partnerView.SetMinimized(bBothMinimizedp);
|
||||||
|
|
||||||
partnerView.RestorePlacements( view.SavePlacements() );
|
partnerView.RestorePlacements( view.SavePlacements() );
|
||||||
|
partnerView.SetMultiView( view.GetMultiView() );
|
||||||
|
|
||||||
//On Demand - join the queues together.
|
//On Demand - join the queues together.
|
||||||
if (ODManager::IsInstanceCreated())
|
if (ODManager::IsInstanceCreated())
|
||||||
|
@ -197,6 +197,9 @@ public:
|
|||||||
WaveTrackView &view, WaveTrackSubView &subView,
|
WaveTrackView &view, WaveTrackSubView &subView,
|
||||||
const TrackPanelMouseState &state )
|
const TrackPanelMouseState &state )
|
||||||
{
|
{
|
||||||
|
if ( !view.GetMultiView() )
|
||||||
|
return {};
|
||||||
|
|
||||||
SubViewAdjuster adjuster{ view };
|
SubViewAdjuster adjuster{ view };
|
||||||
auto hit = adjuster.HitTest( subView,
|
auto hit = adjuster.HitTest( subView,
|
||||||
state.state.GetY(), state.rect.GetTop(), state.rect.GetHeight() );
|
state.state.GetY(), state.rect.GetTop(), state.rect.GetHeight() );
|
||||||
@ -470,8 +473,9 @@ void WaveTrackView::CopyTo( Track &track ) const
|
|||||||
auto &other = TrackView::Get( track );
|
auto &other = TrackView::Get( track );
|
||||||
|
|
||||||
if ( const auto pOther = dynamic_cast< WaveTrackView* >( &other ) ) {
|
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->RestorePlacements( SavePlacements() );
|
||||||
|
pOther->mMultiView = mMultiView;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -542,6 +546,47 @@ void WaveTrackView::SetDisplay(WaveTrackDisplay display)
|
|||||||
DoSetDisplay( 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)
|
void WaveTrackView::DoSetDisplay(WaveTrackDisplay display)
|
||||||
{
|
{
|
||||||
size_t ii = 0;
|
size_t ii = 0;
|
||||||
|
@ -91,6 +91,8 @@ public:
|
|||||||
void RestorePlacements( const WaveTrackSubViewPlacements &placements )
|
void RestorePlacements( const WaveTrackSubViewPlacements &placements )
|
||||||
{ mPlacements = placements; }
|
{ mPlacements = placements; }
|
||||||
|
|
||||||
|
void ToggleSubView( WaveTrackDisplay id );
|
||||||
|
|
||||||
// Get all the sub-views, in a sequence that is unspecified but in
|
// Get all the sub-views, in a sequence that is unspecified but in
|
||||||
// correspondence with the result of SavePlacements
|
// correspondence with the result of SavePlacements
|
||||||
std::vector< std::shared_ptr< WaveTrackSubView > > GetAllSubViews();
|
std::vector< std::shared_ptr< WaveTrackSubView > > GetAllSubViews();
|
||||||
@ -98,6 +100,9 @@ public:
|
|||||||
// Return cached height of rect in last call of GetSubViews
|
// Return cached height of rect in last call of GetSubViews
|
||||||
wxCoord GetLastHeight() const { return mLastHeight; }
|
wxCoord GetLastHeight() const { return mLastHeight; }
|
||||||
|
|
||||||
|
bool GetMultiView() const { return mMultiView; }
|
||||||
|
void SetMultiView( bool value ) { mMultiView = value; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void BuildSubViews() const;
|
void BuildSubViews() const;
|
||||||
void DoSetDisplay(WaveTrackDisplay display);
|
void DoSetDisplay(WaveTrackDisplay display);
|
||||||
@ -121,6 +126,8 @@ protected:
|
|||||||
|
|
||||||
WaveTrackSubViewPlacements mPlacements;
|
WaveTrackSubViewPlacements mPlacements;
|
||||||
mutable wxCoord mLastHeight{};
|
mutable wxCoord mLastHeight{};
|
||||||
|
|
||||||
|
bool mMultiView{ false };
|
||||||
};
|
};
|
||||||
|
|
||||||
// Helper for drawing routines
|
// Helper for drawing routines
|
||||||
|
Loading…
x
Reference in New Issue
Block a user