Coloured clips basics
These basics add a colour index to each clip and track, and allow for a choice of four colours to be set from the track menu drop down. The additional wave colours (red, green and black) are not currently configurable, and the colour index is not currently saved.
This commit is contained in:
parent
fd3813fa30
commit
42c52de7f1
|
@ -275,7 +275,7 @@ TrackArtist::TrackArtist()
|
|||
mSampleDisplay = 1;// Stem plots by default.
|
||||
UpdatePrefs();
|
||||
|
||||
SetColours();
|
||||
SetColours(0);
|
||||
vruler = std::make_unique<Ruler>();
|
||||
}
|
||||
|
||||
|
@ -283,7 +283,7 @@ TrackArtist::~TrackArtist()
|
|||
{
|
||||
}
|
||||
|
||||
void TrackArtist::SetColours()
|
||||
void TrackArtist::SetColours( int iColorIndex)
|
||||
{
|
||||
theTheme.SetBrushColour( blankBrush, clrBlank );
|
||||
theTheme.SetBrushColour( unselectedBrush, clrUnselected);
|
||||
|
@ -296,17 +296,38 @@ void TrackArtist::SetColours()
|
|||
theTheme.SetPenColour( blankPen, clrBlank);
|
||||
theTheme.SetPenColour( unselectedPen, clrUnselected);
|
||||
theTheme.SetPenColour( selectedPen, clrSelected);
|
||||
theTheme.SetPenColour( samplePen, clrSample);
|
||||
theTheme.SetPenColour( selsamplePen, clrSelSample);
|
||||
theTheme.SetPenColour( muteSamplePen, clrMuteSample);
|
||||
theTheme.SetPenColour( odProgressDonePen, clrProgressDone);
|
||||
theTheme.SetPenColour( odProgressNotYetPen, clrProgressNotYet);
|
||||
theTheme.SetPenColour( rmsPen, clrRms);
|
||||
theTheme.SetPenColour( muteRmsPen, clrMuteRms);
|
||||
theTheme.SetPenColour( shadowPen, clrShadow);
|
||||
theTheme.SetPenColour( clippedPen, clrClipped);
|
||||
theTheme.SetPenColour( muteClippedPen, clrMuteClipped);
|
||||
theTheme.SetPenColour( blankSelectedPen,clrBlankSelected);
|
||||
|
||||
theTheme.SetPenColour( selsamplePen, clrSelSample);
|
||||
theTheme.SetPenColour( muteRmsPen, clrMuteRms);
|
||||
|
||||
switch( iColorIndex %4 )
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
theTheme.SetPenColour( samplePen, clrSample);
|
||||
theTheme.SetPenColour( rmsPen, clrRms);
|
||||
break;
|
||||
case 1: // RED
|
||||
samplePen.SetColour( wxColor( 160,10,10 ) );
|
||||
rmsPen.SetColour( wxColor( 230,80,80 ) );
|
||||
break;
|
||||
case 2: // GREEN
|
||||
samplePen.SetColour( wxColor( 35,110,35 ) );
|
||||
rmsPen.SetColour( wxColor( 75,200,75 ) );
|
||||
break;
|
||||
case 3: //BLACK
|
||||
samplePen.SetColour( wxColor( 0,0,0 ) );
|
||||
rmsPen.SetColour( wxColor( 100,100,100 ) );
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void TrackArtist::SetMargins(int left, int top, int right, int bottom)
|
||||
|
@ -1827,6 +1848,8 @@ void TrackArtist::DrawClipWaveform(TrackPanelDrawingContext &context,
|
|||
const float dBRange = track->GetWaveformSettings().dBRange;
|
||||
|
||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||
int iColorIndex = clip->GetColourIndex();
|
||||
SetColours( iColorIndex );
|
||||
|
||||
// If we get to this point, the clip is actually visible on the
|
||||
// screen, so remember the display rectangle.
|
||||
|
@ -3304,7 +3327,7 @@ void TrackArtist::UpdatePrefs()
|
|||
mdBrange = gPrefs->Read(ENV_DB_KEY, mdBrange);
|
||||
mShowClipping = gPrefs->Read(wxT("/GUI/ShowClipping"), mShowClipping);
|
||||
gPrefs->Read(wxT("/GUI/SampleView"), &mSampleDisplay, 1);
|
||||
SetColours();
|
||||
SetColours(0);
|
||||
}
|
||||
|
||||
// Draws the sync-lock bitmap, tiled; always draws stationary relative to the DC
|
||||
|
|
|
@ -53,7 +53,7 @@ class AUDACITY_DLL_API TrackArtist {
|
|||
TrackArtist();
|
||||
~TrackArtist();
|
||||
|
||||
void SetColours();
|
||||
void SetColours(int iColorIndex);
|
||||
void DrawTracks(TrackPanelDrawingContext &context,
|
||||
TrackList *tracks, Track *start,
|
||||
const wxRegion & reg,
|
||||
|
|
|
@ -298,9 +298,10 @@ static void ComputeSpectrumUsingRealFFTf
|
|||
}
|
||||
|
||||
WaveClip::WaveClip(const std::shared_ptr<DirManager> &projDirManager,
|
||||
sampleFormat format, int rate)
|
||||
sampleFormat format, int rate, int colourIndex)
|
||||
{
|
||||
mRate = rate;
|
||||
mColourIndex = colourIndex;
|
||||
mSequence = std::make_unique<Sequence>(projDirManager, format);
|
||||
|
||||
mEnvelope = std::make_unique<Envelope>(true, 1e-7, 2.0, 1.0);
|
||||
|
@ -320,6 +321,7 @@ WaveClip::WaveClip(const WaveClip& orig,
|
|||
|
||||
mOffset = orig.mOffset;
|
||||
mRate = orig.mRate;
|
||||
mColourIndex = orig.mColourIndex;
|
||||
mSequence = std::make_unique<Sequence>(*orig.mSequence, projDirManager);
|
||||
|
||||
mEnvelope = std::make_unique<Envelope>(*orig.mEnvelope);
|
||||
|
@ -345,6 +347,7 @@ WaveClip::WaveClip(const WaveClip& orig,
|
|||
|
||||
mOffset = orig.mOffset;
|
||||
mRate = orig.mRate;
|
||||
mColourIndex = orig.mColourIndex;
|
||||
|
||||
mWaveCache = std::make_unique<WaveCache>();
|
||||
mSpecCache = std::make_unique<SpecCache>();
|
||||
|
@ -1540,7 +1543,7 @@ XMLTagHandler *WaveClip::HandleXMLChild(const wxChar *tag)
|
|||
// Nested wave clips are cut lines
|
||||
mCutLines.push_back(
|
||||
make_movable<WaveClip>(mSequence->GetDirManager(),
|
||||
mSequence->GetSampleFormat(), mRate));
|
||||
mSequence->GetSampleFormat(), mRate, 0 /*colourindex*/));
|
||||
return mCutLines.back().get();
|
||||
}
|
||||
else
|
||||
|
|
|
@ -184,7 +184,8 @@ private:
|
|||
|
||||
public:
|
||||
// typical constructor
|
||||
WaveClip(const std::shared_ptr<DirManager> &projDirManager, sampleFormat format, int rate);
|
||||
WaveClip(const std::shared_ptr<DirManager> &projDirManager, sampleFormat format,
|
||||
int rate, int colourIndex);
|
||||
|
||||
// essentially a copy constructor - but you must pass in the
|
||||
// current project's DirManager, because we might be copying
|
||||
|
@ -213,6 +214,8 @@ public:
|
|||
// the length of the clip
|
||||
void Resample(int rate, ProgressDialog *progress = NULL);
|
||||
|
||||
void SetColourIndex( int index ){ mColourIndex = index;};
|
||||
int GetColourIndex( ) const { return mColourIndex;};
|
||||
void SetOffset(double offset);
|
||||
double GetOffset() const { return mOffset; }
|
||||
void Offset(double delta) // NOFAIL-GUARANTEE
|
||||
|
@ -369,6 +372,8 @@ protected:
|
|||
double mOffset { 0 };
|
||||
int mRate;
|
||||
int mDirty { 0 };
|
||||
int mColourIndex;
|
||||
|
||||
std::unique_ptr<Sequence> mSequence;
|
||||
std::unique_ptr<Envelope> mEnvelope;
|
||||
|
||||
|
|
|
@ -108,6 +108,7 @@ WaveTrack::WaveTrack(const std::shared_ptr<DirManager> &projDirManager, sampleFo
|
|||
mRate = (int) rate;
|
||||
mGain = 1.0;
|
||||
mPan = 0.0;
|
||||
mWaveColorIndex = 0;
|
||||
SetDefaultName(TracksPrefs::GetDefaultAudioTrackNamePreference());
|
||||
SetName(GetDefaultName());
|
||||
mDisplayMin = -1.0;
|
||||
|
@ -148,6 +149,7 @@ void WaveTrack::Init(const WaveTrack &orig)
|
|||
{
|
||||
PlayableTrack::Init(orig);
|
||||
mFormat = orig.mFormat;
|
||||
mWaveColorIndex = orig.mWaveColorIndex;
|
||||
mRate = orig.mRate;
|
||||
mGain = orig.mGain;
|
||||
mPan = orig.mPan;
|
||||
|
@ -538,6 +540,15 @@ float WaveTrack::GetChannelGain(int channel) const
|
|||
return right*mGain;
|
||||
}
|
||||
|
||||
void WaveTrack::SetWaveColorIndex(int colorIndex)
|
||||
// STRONG-GUARANTEE
|
||||
{
|
||||
for (const auto &clip : mClips)
|
||||
clip->SetColourIndex( colorIndex );
|
||||
mWaveColorIndex = colorIndex;
|
||||
}
|
||||
|
||||
|
||||
void WaveTrack::ConvertToSampleFormat(sampleFormat format)
|
||||
// WEAK-GUARANTEE
|
||||
// might complete on only some tracks
|
||||
|
@ -711,7 +722,8 @@ Track::Holder WaveTrack::Copy(double t0, double t1, bool forClipboard) const
|
|||
{
|
||||
auto placeholder = make_movable<WaveClip>(mDirManager,
|
||||
newTrack->GetSampleFormat(),
|
||||
static_cast<int>(newTrack->GetRate()));
|
||||
static_cast<int>(newTrack->GetRate()),
|
||||
0 /*colourindex*/);
|
||||
placeholder->SetIsPlaceholder(true);
|
||||
placeholder->InsertSilence(0, (t1 - t0) - newTrack->GetEndTime());
|
||||
placeholder->Offset(newTrack->GetEndTime());
|
||||
|
@ -1425,7 +1437,7 @@ void WaveTrack::InsertSilence(double t, double len)
|
|||
if (mClips.empty())
|
||||
{
|
||||
// Special case if there is no clip yet
|
||||
auto clip = make_movable<WaveClip>(mDirManager, mFormat, mRate);
|
||||
auto clip = make_movable<WaveClip>(mDirManager, mFormat, mRate, 0 /*colourindex*/);
|
||||
clip->InsertSilence(0, len);
|
||||
// use NOFAIL-GUARANTEE
|
||||
mClips.push_back( std::move( clip ) );
|
||||
|
@ -2261,7 +2273,7 @@ Sequence* WaveTrack::GetSequenceAtX(int xcoord)
|
|||
|
||||
WaveClip* WaveTrack::CreateClip()
|
||||
{
|
||||
mClips.push_back(make_movable<WaveClip>(mDirManager, mFormat, mRate));
|
||||
mClips.push_back(make_movable<WaveClip>(mDirManager, mFormat, mRate,0 /*colurindex*/));
|
||||
return mClips.back().get();
|
||||
}
|
||||
|
||||
|
|
|
@ -161,6 +161,10 @@ class AUDACITY_DLL_API WaveTrack final : public PlayableTrack {
|
|||
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
|
||||
void SetVirtualState(bool state, bool half=false);
|
||||
#endif
|
||||
|
||||
int GetWaveColorIndex() const { return mWaveColorIndex; };
|
||||
void SetWaveColorIndex(int colorIndex);
|
||||
|
||||
sampleFormat GetSampleFormat() const { return mFormat; }
|
||||
void ConvertToSampleFormat(sampleFormat format);
|
||||
|
||||
|
@ -606,6 +610,7 @@ class AUDACITY_DLL_API WaveTrack final : public PlayableTrack {
|
|||
int mRate;
|
||||
float mGain;
|
||||
float mPan;
|
||||
int mWaveColorIndex;
|
||||
|
||||
|
||||
//
|
||||
|
|
|
@ -121,6 +121,11 @@ enum {
|
|||
OnChannelMonoID,
|
||||
|
||||
OnMergeStereoID,
|
||||
OnWaveColorID,
|
||||
OnInstrument1ID,
|
||||
OnInstrument2ID,
|
||||
OnInstrument3ID,
|
||||
OnInstrument4ID,
|
||||
|
||||
OnSwapChannelsID,
|
||||
OnSplitStereoID,
|
||||
|
@ -129,6 +134,106 @@ enum {
|
|||
ChannelMenuID,
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// Table class for a sub-menu
|
||||
class WaveColorMenuTable : public PopupMenuTable
|
||||
{
|
||||
WaveColorMenuTable() : mpData(NULL) {}
|
||||
DECLARE_POPUP_MENU(WaveColorMenuTable);
|
||||
|
||||
public:
|
||||
static WaveColorMenuTable &Instance();
|
||||
|
||||
private:
|
||||
void InitMenu(Menu *pMenu, void *pUserData) override;
|
||||
|
||||
void DestroyMenu() override
|
||||
{
|
||||
mpData = NULL;
|
||||
}
|
||||
|
||||
TrackControls::InitMenuData *mpData;
|
||||
|
||||
int IdOfWaveColor(int WaveColor);
|
||||
void OnWaveColorChange(wxCommandEvent & event);
|
||||
};
|
||||
|
||||
WaveColorMenuTable &WaveColorMenuTable::Instance()
|
||||
{
|
||||
static WaveColorMenuTable instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
void WaveColorMenuTable::InitMenu(Menu *pMenu, void *pUserData)
|
||||
{
|
||||
mpData = static_cast<TrackControls::InitMenuData*>(pUserData);
|
||||
WaveTrack *const pTrack = static_cast<WaveTrack*>(mpData->pTrack);
|
||||
auto WaveColorId = IdOfWaveColor( pTrack->GetWaveColorIndex());
|
||||
SetMenuChecks(*pMenu, [=](int id){ return id == WaveColorId; });
|
||||
|
||||
AudacityProject *const project = ::GetActiveProject();
|
||||
bool unsafe = project->IsAudioActive();
|
||||
for (int i = OnInstrument1ID; i <= OnInstrument4ID; i++) {
|
||||
pMenu->Enable(i, !unsafe);
|
||||
}
|
||||
}
|
||||
|
||||
const wxString GetWaveColorStr(int colorIndex)
|
||||
{
|
||||
return wxString::Format( _("Instrument %i"), colorIndex+1 );
|
||||
}
|
||||
|
||||
|
||||
BEGIN_POPUP_MENU(WaveColorMenuTable)
|
||||
POPUP_MENU_RADIO_ITEM(OnInstrument1ID,
|
||||
GetWaveColorStr(0), OnWaveColorChange)
|
||||
POPUP_MENU_RADIO_ITEM(OnInstrument2ID,
|
||||
GetWaveColorStr(1), OnWaveColorChange)
|
||||
POPUP_MENU_RADIO_ITEM(OnInstrument3ID,
|
||||
GetWaveColorStr(2), OnWaveColorChange)
|
||||
POPUP_MENU_RADIO_ITEM(OnInstrument4ID,
|
||||
GetWaveColorStr(3), OnWaveColorChange)
|
||||
END_POPUP_MENU()
|
||||
|
||||
/// Converts a WaveColor enumeration to a wxWidgets menu item Id.
|
||||
int WaveColorMenuTable::IdOfWaveColor(int WaveColor)
|
||||
{ return OnInstrument1ID + WaveColor;}
|
||||
|
||||
/// Handles the selection from the WaveColor submenu of the
|
||||
/// track menu.
|
||||
void WaveColorMenuTable::OnWaveColorChange(wxCommandEvent & event)
|
||||
{
|
||||
int id = event.GetId();
|
||||
wxASSERT(id >= OnInstrument1ID && id <= OnInstrument4ID);
|
||||
WaveTrack *const pTrack = static_cast<WaveTrack*>(mpData->pTrack);
|
||||
wxASSERT(pTrack && pTrack->GetKind() == Track::Wave);
|
||||
|
||||
int newWaveColor = id - OnInstrument1ID;
|
||||
|
||||
AudacityProject *const project = ::GetActiveProject();
|
||||
// TrackList *const tracks = project->GetTracks();
|
||||
|
||||
pTrack->SetWaveColorIndex(newWaveColor);
|
||||
|
||||
// Assume partner is wave or null
|
||||
const auto partner = static_cast<WaveTrack*>(pTrack->GetLink());
|
||||
if (partner)
|
||||
partner->SetWaveColorIndex(newWaveColor);
|
||||
|
||||
project->PushState(wxString::Format(_("Changed '%s' to %s"),
|
||||
pTrack->GetName().
|
||||
c_str(),
|
||||
GetWaveColorStr(newWaveColor)),
|
||||
_("WaveColor Change"));
|
||||
|
||||
using namespace RefreshCode;
|
||||
mpData->result = RefreshAll | FixScrollbars;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// Table class for a sub-menu
|
||||
class FormatMenuTable : public PopupMenuTable
|
||||
|
@ -550,8 +655,12 @@ void WaveTrackMenuTable::InitMenu(Menu *pMenu, void *pUserData)
|
|||
pMenu->Enable(OnSwapChannelsID, !isMono && !unsafe);
|
||||
pMenu->Enable(OnSplitStereoID, !isMono && !unsafe);
|
||||
|
||||
// Several menu items no longer needed....
|
||||
#ifndef EXPERIMENTAL_DA
|
||||
// Can be achieved by split stereo and then dragging pan slider.
|
||||
pMenu->Enable(OnSplitStereoMonoID, !isMono && !unsafe);
|
||||
#endif
|
||||
|
||||
// Several menu items no longer needed....
|
||||
#if 0
|
||||
pMenu->Enable(OnChannelMonoID, isMono);
|
||||
pMenu->Enable(OnChannelLeftID, isMono);
|
||||
|
@ -580,7 +689,9 @@ BEGIN_POPUP_MENU(WaveTrackMenuTable)
|
|||
POPUP_MENU_ITEM(OnSplitStereoMonoID, _("Split Stereo to Mo&no"), OnSplitStereoMono)
|
||||
#endif
|
||||
POPUP_MENU_SEPARATOR()
|
||||
POPUP_MENU_SUB_MENU(0, _("&Wave Color"), WaveColorMenuTable)
|
||||
|
||||
POPUP_MENU_SEPARATOR()
|
||||
POPUP_MENU_SUB_MENU(0, _("&Format"), FormatMenuTable)
|
||||
POPUP_MENU_SEPARATOR()
|
||||
POPUP_MENU_SUB_MENU(0, _("Rat&e"), RateMenuTable)
|
||||
|
|
Loading…
Reference in New Issue