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:
parent
30c37e9110
commit
0256156dec
@ -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())
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user