mirror of
https://github.com/cookiengineer/audacity
synced 2025-05-02 08:39:46 +02:00
Move AudacityProject::DoTrackMute and DoTrackSolo...
... also fixed the bug that muting and soloing from the mixer board did not update accessibility.
This commit is contained in:
parent
51c3541716
commit
50f8579475
@ -140,6 +140,11 @@ namespace TrackActions {
|
||||
};
|
||||
/// Move a track up, down, to top or to bottom.
|
||||
void DoMoveTrack( AudacityProject &project, Track* target, MoveChoice choice );
|
||||
// "exclusive" mute means mute the chosen track and unmute all others.
|
||||
void DoTrackMute( AudacityProject &project, Track *pTrack, bool exclusive );
|
||||
// Type of solo (standard or simple) follows the set preference, unless
|
||||
// exclusive == true, which causes the opposite behavior.
|
||||
void DoTrackSolo( AudacityProject &project, Track *pTrack, bool exclusive );
|
||||
void DoRemoveTrack( AudacityProject &project, Track * toRemove );
|
||||
void DoRemoveTracks( AudacityProject & );
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
**********************************************************************/
|
||||
|
||||
#include "Audacity.h"
|
||||
#include "Menus.h"
|
||||
#include "MixerBoard.h"
|
||||
|
||||
#include <cfloat>
|
||||
@ -744,7 +745,8 @@ void MixerTrackCluster::OnSlider_Pan(wxCommandEvent& WXUNUSED(event))
|
||||
|
||||
void MixerTrackCluster::OnButton_Mute(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
mProject->HandleTrackMute(mTrack.get(), mToggleButton_Mute->WasShiftDown());
|
||||
TrackActions::DoTrackMute(
|
||||
*mProject, mTrack.get(), mToggleButton_Mute->WasShiftDown());
|
||||
mToggleButton_Mute->SetAlternateIdx(mTrack->GetSolo() ? 1 : 0);
|
||||
|
||||
// Update the TrackPanel correspondingly.
|
||||
@ -759,7 +761,8 @@ void MixerTrackCluster::OnButton_Mute(wxCommandEvent& WXUNUSED(event))
|
||||
|
||||
void MixerTrackCluster::OnButton_Solo(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
mProject->HandleTrackSolo(mTrack.get(), mToggleButton_Solo->WasShiftDown());
|
||||
TrackActions::DoTrackSolo(
|
||||
*mProject, mTrack.get(), mToggleButton_Solo->WasShiftDown());
|
||||
bool bIsSolo = mTrack->GetSolo();
|
||||
mToggleButton_Mute->SetAlternateIdx(bIsSolo ? 1 : 0);
|
||||
|
||||
|
107
src/Project.cpp
107
src/Project.cpp
@ -5312,113 +5312,6 @@ void AudacityProject::SetSyncLock(bool flag)
|
||||
}
|
||||
}
|
||||
|
||||
void AudacityProject::DoTrackMute(Track *t, bool exclusive)
|
||||
{
|
||||
HandleTrackMute(t, exclusive);
|
||||
|
||||
mTrackPanel->UpdateAccessibility();
|
||||
mTrackPanel->Refresh(false);
|
||||
}
|
||||
|
||||
void AudacityProject::DoTrackSolo(Track *t, bool exclusive)
|
||||
{
|
||||
HandleTrackSolo(t, exclusive);
|
||||
|
||||
mTrackPanel->UpdateAccessibility();
|
||||
mTrackPanel->Refresh(false);
|
||||
}
|
||||
|
||||
void AudacityProject::HandleTrackMute(Track *t, const bool exclusive)
|
||||
{
|
||||
// Whatever t is, replace with lead channel
|
||||
t = *GetTracks()->FindLeader(t);
|
||||
|
||||
// "exclusive" mute means mute the chosen track and unmute all others.
|
||||
if (exclusive) {
|
||||
for (auto leader : GetTracks()->Leaders<PlayableTrack>()) {
|
||||
const auto group = TrackList::Channels(leader);
|
||||
bool chosen = (t == leader);
|
||||
for (auto channel : group)
|
||||
channel->SetMute( chosen ),
|
||||
channel->SetSolo( false );
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Normal click toggles this track.
|
||||
auto pt = dynamic_cast<PlayableTrack *>( t );
|
||||
if (!pt)
|
||||
return;
|
||||
|
||||
bool wasMute = pt->GetMute();
|
||||
for (auto channel : TrackList::Channels(pt))
|
||||
channel->SetMute( !wasMute );
|
||||
|
||||
if (IsSoloSimple() || IsSoloNone())
|
||||
{
|
||||
// We also set a solo indicator if we have just one track / stereo pair playing.
|
||||
// in a group of more than one playable tracks.
|
||||
// otherwise clear solo on everything.
|
||||
|
||||
auto range = GetTracks()->Leaders<PlayableTrack>();
|
||||
auto nPlayableTracks = range.size();
|
||||
auto nPlaying = (range - &PlayableTrack::GetMute).size();
|
||||
|
||||
for (auto track : GetTracks()->Any<PlayableTrack>())
|
||||
// will set both of a stereo pair
|
||||
track->SetSolo( (nPlaying==1) && (nPlayableTracks > 1 ) && !track->GetMute() );
|
||||
}
|
||||
}
|
||||
ModifyState(true);
|
||||
}
|
||||
|
||||
// Type of solo (standard or simple) follows the set preference, unless
|
||||
// alternate == true, which causes the opposite behavior.
|
||||
void AudacityProject::HandleTrackSolo(Track *t, const bool alternate)
|
||||
{
|
||||
// Whatever t is, replace with lead channel
|
||||
t = *GetTracks()->FindLeader(t);
|
||||
|
||||
const auto pt = dynamic_cast<PlayableTrack *>( t );
|
||||
if (!pt)
|
||||
return;
|
||||
bool bWasSolo = pt->GetSolo();
|
||||
|
||||
bool bSoloMultiple = !IsSoloSimple() ^ alternate;
|
||||
|
||||
// Standard and Simple solo have opposite defaults:
|
||||
// Standard - Behaves as individual buttons, shift=radio buttons
|
||||
// Simple - Behaves as radio buttons, shift=individual
|
||||
// In addition, Simple solo will mute/unmute tracks
|
||||
// when in standard radio button mode.
|
||||
if ( bSoloMultiple )
|
||||
{
|
||||
for (auto channel : TrackList::Channels(pt))
|
||||
channel->SetSolo( !bWasSolo );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Normal click solo this track only, mute everything else.
|
||||
// OR unmute and unsolo everything.
|
||||
for (auto leader : GetTracks()->Leaders<PlayableTrack>()) {
|
||||
const auto group = TrackList::Channels(leader);
|
||||
bool chosen = (t == leader);
|
||||
for (auto channel : group) {
|
||||
if (chosen) {
|
||||
channel->SetSolo( !bWasSolo );
|
||||
if( IsSoloSimple() )
|
||||
channel->SetMute( false );
|
||||
}
|
||||
else {
|
||||
channel->SetSolo( false );
|
||||
if( IsSoloSimple() )
|
||||
channel->SetMute( !bWasSolo );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ModifyState(true);
|
||||
}
|
||||
|
||||
// Keyboard capture
|
||||
|
||||
// static
|
||||
|
@ -425,16 +425,6 @@ public:
|
||||
bool IsSyncLocked();
|
||||
void SetSyncLock(bool flag);
|
||||
|
||||
void DoTrackMute(Track *pTrack, bool exclusive);
|
||||
void DoTrackSolo(Track *pTrack, bool exclusive);
|
||||
|
||||
// "exclusive" mute means mute the chosen track and unmute all others.
|
||||
void HandleTrackMute(Track *t, const bool exclusive);
|
||||
|
||||
// Type of solo (standard or simple) follows the set preference, unless
|
||||
// alternate == true, which causes the opposite behavior.
|
||||
void HandleTrackSolo(Track *t, const bool alternate);
|
||||
|
||||
// Snap To
|
||||
|
||||
void SetSnapTo(int snap);
|
||||
|
@ -575,6 +575,107 @@ void DoRemoveTracks( AudacityProject &project )
|
||||
trackPanel->Refresh(false);
|
||||
}
|
||||
|
||||
void DoTrackMute(AudacityProject &project, Track *t, bool exclusive)
|
||||
{
|
||||
auto &tracks = *project.GetTracks();
|
||||
auto &trackPanel = *project.GetTrackPanel();
|
||||
|
||||
// Whatever t is, replace with lead channel
|
||||
t = *tracks.FindLeader(t);
|
||||
|
||||
// "exclusive" mute means mute the chosen track and unmute all others.
|
||||
if (exclusive) {
|
||||
for (auto leader : tracks.Leaders<PlayableTrack>()) {
|
||||
const auto group = TrackList::Channels(leader);
|
||||
bool chosen = (t == leader);
|
||||
for (auto channel : group)
|
||||
channel->SetMute( chosen ),
|
||||
channel->SetSolo( false );
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Normal click toggles this track.
|
||||
auto pt = dynamic_cast<PlayableTrack *>( t );
|
||||
if (!pt)
|
||||
return;
|
||||
|
||||
bool wasMute = pt->GetMute();
|
||||
for (auto channel : TrackList::Channels(pt))
|
||||
channel->SetMute( !wasMute );
|
||||
|
||||
if (project.IsSoloSimple() || project.IsSoloNone())
|
||||
{
|
||||
// We also set a solo indicator if we have just one track / stereo pair playing.
|
||||
// in a group of more than one playable tracks.
|
||||
// otherwise clear solo on everything.
|
||||
|
||||
auto range = tracks.Leaders<PlayableTrack>();
|
||||
auto nPlayableTracks = range.size();
|
||||
auto nPlaying = (range - &PlayableTrack::GetMute).size();
|
||||
|
||||
for (auto track : tracks.Any<PlayableTrack>())
|
||||
// will set both of a stereo pair
|
||||
track->SetSolo( (nPlaying==1) && (nPlayableTracks > 1 ) && !track->GetMute() );
|
||||
}
|
||||
}
|
||||
project.ModifyState(true);
|
||||
|
||||
trackPanel.UpdateAccessibility();
|
||||
trackPanel.Refresh(false);
|
||||
}
|
||||
|
||||
void DoTrackSolo(AudacityProject &project, Track *t, bool exclusive)
|
||||
{
|
||||
auto &tracks = *project.GetTracks();
|
||||
auto &trackPanel = *project.GetTrackPanel();
|
||||
|
||||
// Whatever t is, replace with lead channel
|
||||
t = *tracks.FindLeader(t);
|
||||
|
||||
const auto pt = dynamic_cast<PlayableTrack *>( t );
|
||||
if (!pt)
|
||||
return;
|
||||
bool bWasSolo = pt->GetSolo();
|
||||
|
||||
bool bSoloMultiple = !project.IsSoloSimple() ^ exclusive;
|
||||
|
||||
// Standard and Simple solo have opposite defaults:
|
||||
// Standard - Behaves as individual buttons, shift=radio buttons
|
||||
// Simple - Behaves as radio buttons, shift=individual
|
||||
// In addition, Simple solo will mute/unmute tracks
|
||||
// when in standard radio button mode.
|
||||
if ( bSoloMultiple )
|
||||
{
|
||||
for (auto channel : TrackList::Channels(pt))
|
||||
channel->SetSolo( !bWasSolo );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Normal click solo this track only, mute everything else.
|
||||
// OR unmute and unsolo everything.
|
||||
for (auto leader : tracks.Leaders<PlayableTrack>()) {
|
||||
const auto group = TrackList::Channels(leader);
|
||||
bool chosen = (t == leader);
|
||||
for (auto channel : group) {
|
||||
if (chosen) {
|
||||
channel->SetSolo( !bWasSolo );
|
||||
if( project.IsSoloSimple() )
|
||||
channel->SetMute( false );
|
||||
}
|
||||
else {
|
||||
channel->SetSolo( false );
|
||||
if( project.IsSoloSimple() )
|
||||
channel->SetMute( !bWasSolo );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
project.ModifyState(true);
|
||||
|
||||
trackPanel.UpdateAccessibility();
|
||||
trackPanel.Refresh(false);
|
||||
}
|
||||
|
||||
void DoRemoveTrack(AudacityProject &project, Track * toRemove)
|
||||
{
|
||||
auto &tracks = *project.GetTracks();
|
||||
@ -1234,7 +1335,7 @@ void OnTrackMute(const CommandContext &context)
|
||||
|
||||
const auto track = trackPanel->GetFocusedTrack();
|
||||
if (track) track->TypeSwitch( [&](PlayableTrack *t) {
|
||||
project.DoTrackMute(t, false);
|
||||
DoTrackMute(project, t, false);
|
||||
});
|
||||
}
|
||||
|
||||
@ -1245,7 +1346,7 @@ void OnTrackSolo(const CommandContext &context)
|
||||
|
||||
const auto track = trackPanel->GetFocusedTrack();
|
||||
if (track) track->TypeSwitch( [&](PlayableTrack *t) {
|
||||
project.DoTrackSolo(t, false);
|
||||
DoTrackSolo(project, t, false);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ Paul Licameli split from TrackPanel.cpp
|
||||
|
||||
#include "../../../commands/CommandManager.h"
|
||||
#include "../../../HitTestResult.h"
|
||||
#include "../../../Menus.h"
|
||||
#include "../../../Project.h"
|
||||
#include "../../../RefreshCode.h"
|
||||
#include "../../../Track.h"
|
||||
@ -33,7 +34,7 @@ UIHandle::Result MuteButtonHandle::CommitChanges
|
||||
{
|
||||
auto pTrack = mpTrack.lock();
|
||||
if ( dynamic_cast< PlayableTrack* >( pTrack.get() ) )
|
||||
pProject->DoTrackMute(pTrack.get(), event.ShiftDown());
|
||||
TrackActions::DoTrackMute(*pProject, pTrack.get(), event.ShiftDown());
|
||||
|
||||
return RefreshCode::RefreshNone;
|
||||
}
|
||||
@ -89,7 +90,7 @@ UIHandle::Result SoloButtonHandle::CommitChanges
|
||||
{
|
||||
auto pTrack = mpTrack.lock();
|
||||
if ( dynamic_cast< PlayableTrack* >( pTrack.get() ) )
|
||||
pProject->DoTrackSolo(pTrack.get(), event.ShiftDown());
|
||||
TrackActions::DoTrackSolo(*pProject, pTrack.get(), event.ShiftDown());
|
||||
|
||||
return RefreshCode::RefreshNone;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user