diff --git a/src/Envelope.cpp b/src/Envelope.cpp index 24aa15daf..e523d943f 100644 --- a/src/Envelope.cpp +++ b/src/Envelope.cpp @@ -319,11 +319,14 @@ static void DrawPoint(wxDC & dc, const wxRect & r, int x, int y, bool top) /// TODO: This should probably move to track artist. void Envelope::DrawPoints -(TrackPanelDrawingContext &context, const wxRect & r, const ZoomInfo &zoomInfo, +(TrackPanelDrawingContext &context, const wxRect & r, bool dB, double dBRange, float zoomMin, float zoomMax, bool mirrored) const { auto &dc = context.dc; + const auto artist = TrackArtist::Get( context ); + const auto &zoomInfo = *artist->pZoomInfo; + bool highlight = false; #ifdef EXPERIMENTAL_TRACK_PANEL_HIGHLIGHTING auto target = dynamic_cast(context.target.get()); @@ -357,7 +360,7 @@ void Envelope::DrawPoints true, dBRange, false); // This follows the same logic as the envelop drawing in - // TrackArtist::DrawEnvelope(). + // TrackArt::DrawEnvelope(). // TODO: make this calculation into a reusable function. if (y2 - y < 9) { int value = (int)((zoomMax / (zoomMax - zoomMin)) * r.height); diff --git a/src/Envelope.h b/src/Envelope.h index 03663467d..ce64ddac0 100644 --- a/src/Envelope.h +++ b/src/Envelope.h @@ -119,7 +119,7 @@ public: void DrawPoints( TrackPanelDrawingContext &context, - const wxRect & r, const ZoomInfo &zoomInfo, + const wxRect & r, bool dB, double dBRange, float zoomMin, float zoomMax, bool mirrored) const; diff --git a/src/LabelTrack.cpp b/src/LabelTrack.cpp index 05656e5f4..008002efd 100644 --- a/src/LabelTrack.cpp +++ b/src/LabelTrack.cpp @@ -782,11 +782,12 @@ namespace { /// @param dc the device context /// @param r the LabelTrack rectangle. void LabelTrack::Draw -(TrackPanelDrawingContext &context, const wxRect & r, - const SelectedRegion &selectedRegion, - const ZoomInfo &zoomInfo) const +( TrackPanelDrawingContext &context, const wxRect & r ) const { auto &dc = context.dc; + const auto artist = TrackArtist::Get( context ); + const auto &zoomInfo = *artist->pZoomInfo; + auto pHit = findHit(); if(msFont.Ok()) @@ -795,9 +796,9 @@ void LabelTrack::Draw if (mFontHeight == -1) calculateFontHeight(dc); - TrackArtist::DrawBackgroundWithSelection(&dc, r, this, - AColor::labelSelectedBrush, AColor::labelUnselectedBrush, - selectedRegion, zoomInfo); + TrackArt::DrawBackgroundWithSelection( context, r, this, + AColor::labelSelectedBrush, AColor::labelUnselectedBrush, + ( GetSelected() || IsSyncLockSelected() ) ); wxCoord textWidth, textHeight; diff --git a/src/LabelTrack.h b/src/LabelTrack.h index 7442ef5e9..f3050c798 100644 --- a/src/LabelTrack.h +++ b/src/LabelTrack.h @@ -153,9 +153,7 @@ class AUDACITY_DLL_API LabelTrack final : public Track static wxFont GetFont(const wxString &faceName, int size = DefaultFontSize); static void ResetFont(); - void Draw(TrackPanelDrawingContext &context, const wxRect & r, - const SelectedRegion &selectedRegion, - const ZoomInfo &zoomInfo) const; + void Draw( TrackPanelDrawingContext &context, const wxRect & r ) const; int getSelectedIndex() const { return mSelIndex; } diff --git a/src/Printing.cpp b/src/Printing.cpp index 16b28e4e4..8fd0b543c 100644 --- a/src/Printing.cpp +++ b/src/Printing.cpp @@ -88,7 +88,10 @@ bool AudacityPrintout::OnPrintPage(int WXUNUSED(page)) artist.SetBackgroundBrushes(*wxWHITE_BRUSH, *wxWHITE_BRUSH, *wxWHITE_PEN, *wxWHITE_PEN); const double screenDuration = mTracks->GetEndTime(); + SelectedRegion region{}; + artist.pSelectedRegion = ®ion; ZoomInfo zoomInfo(0.0, width / screenDuration); + artist.pZoomInfo = &zoomInfo; int y = rulerPageHeight; for (auto n : mTracks->Any()) { @@ -98,9 +101,10 @@ bool AudacityPrintout::OnPrintPage(int WXUNUSED(page)) r.width = width; r.height = (int)(n->GetHeight() * scale); - TrackPanelDrawingContext context{ *dc, {}, {} }; - artist.DrawTrack( - context, n, r, SelectedRegion(), zoomInfo, false, false, false, false); + TrackPanelDrawingContext context{ + *dc, {}, {}, &artist + }; + TrackArt::DrawTrack( context, n, r ); dc->SetPen(*wxBLACK_PEN); AColor::Line(*dc, 0, r.y, width, r.y); diff --git a/src/TimeTrack.cpp b/src/TimeTrack.cpp index eb0e378d5..f6f51fd45 100644 --- a/src/TimeTrack.cpp +++ b/src/TimeTrack.cpp @@ -24,6 +24,7 @@ #include "Envelope.h" #include "Prefs.h" #include "Project.h" +#include "TrackArtist.h" #include "Internat.h" #include "ViewInfo.h" #include "AllThemeResources.h" @@ -265,9 +266,12 @@ void TimeTrack::WriteXML(XMLWriter &xmlFile) const #include "tracks/ui/EnvelopeHandle.h" void TimeTrack::Draw -(TrackPanelDrawingContext &context, const wxRect & r, const ZoomInfo &zoomInfo) const +( TrackPanelDrawingContext &context, const wxRect & r ) const { auto &dc = context.dc; + const auto artist = TrackArtist::Get( context ); + const auto &zoomInfo = *artist->pZoomInfo; + bool highlight = false; #ifdef EXPERIMENTAL_TRACK_PANEL_HIGHLIGHTING auto target = dynamic_cast(context.target.get()); diff --git a/src/TimeTrack.h b/src/TimeTrack.h index d06ce1e47..8e583e003 100644 --- a/src/TimeTrack.h +++ b/src/TimeTrack.h @@ -66,8 +66,7 @@ class TimeTrack final : public Track { double GetEndTime() const override { return 0.0; } void Draw - (TrackPanelDrawingContext &context, - const wxRect & r, const ZoomInfo &zoomInfo) const; + ( TrackPanelDrawingContext &context, const wxRect & r ) const; // XMLTagHandler callback methods for loading and saving diff --git a/src/TrackArtist.cpp b/src/TrackArtist.cpp index 7679b03b2..959c6e812 100644 --- a/src/TrackArtist.cpp +++ b/src/TrackArtist.cpp @@ -153,7 +153,7 @@ const int notePos[12] = { 1, 6, 11, 16, 21, 27, // IPITCH_TO_Y above, which computes coordinates relative to GetBottom() // Note the -NOTE_MARGIN, which leaves a little margin to draw notes that // are out of bounds. I'm not sure why the -2 is necessary. -int TrackArtist::GetBottom(NoteTrack *t, const wxRect &rect) +int TrackArt::GetBottom(NoteTrack *t, const wxRect &rect) { int bottomNote = t->GetBottomNote(); int bottom = rect.y + rect.height - 2 - t->GetNoteMargin() + @@ -173,12 +173,19 @@ TrackArtist::TrackArtist() SetColours(0); vruler = std::make_unique(); + + UpdatePrefs(); } TrackArtist::~TrackArtist() { } +TrackArtist * TrackArtist::Get( TrackPanelDrawingContext &context ) +{ + return static_cast< TrackArtist* >( context.pUserData ); +} + void TrackArtist::SetColours( int iColorIndex) { theTheme.SetBrushColour( blankBrush, clrBlank ); @@ -226,32 +233,19 @@ void TrackArtist::SetColours( int iColorIndex) } } -void TrackArtist::DrawTracks(TrackPanelDrawingContext &context, +void TrackArt::DrawTracks(TrackPanelDrawingContext &context, const TrackList * tracks, const wxRegion & reg, - const wxRect & clip, int leftOffset, - const SelectedRegion &selectedRegion, - const ZoomInfo &zoomInfo, - bool drawEnvelope, - bool bigPoints, - bool drawSliders) + const wxRect & clip) { // Fix the horizontal extent; will later change only the vertical extent. + const auto artist = TrackArtist::Get( context ); + const auto leftOffset = artist->leftOffset; wxRect teamRect{ clip.x + leftOffset, 0, clip.width - (leftOffset + kRightMargin), 0 }; - bool hasSolo = false; - for (const Track *t : *tracks) { - t = t->SubstitutePendingChangedTrack().get(); - auto pt = dynamic_cast(t); - if (pt && pt->GetSolo()) { - hasSolo = true; - break; - } - } - - gPrefs->Read(wxT("/GUI/ShowTrackNameInWaveform"), &mbShowTrackNameInWaveform, false); + const auto &zoomInfo = *artist->pZoomInfo; for(auto leader : tracks->Leaders()) { auto group = TrackList::Channels( leader ); @@ -285,31 +279,26 @@ void TrackArtist::DrawTracks(TrackPanelDrawingContext &context, teamRect.width, t->GetHeight() - (kTopMargin + kBottomMargin) }; - DrawTrack(context, t, trackRect, - selectedRegion, zoomInfo, - drawEnvelope, bigPoints, drawSliders, hasSolo); + DrawTrack( context, t, trackRect ); } } } } -void TrackArtist::DrawTrack(TrackPanelDrawingContext &context, +void TrackArt::DrawTrack(TrackPanelDrawingContext &context, const Track * t, - const wxRect & rect, - const SelectedRegion &selectedRegion, - const ZoomInfo &zoomInfo, - bool drawEnvelope, - bool bigPoints, - bool drawSliders, - bool hasSolo) + const wxRect & rect) { auto &dc = context.dc; + t->TypeSwitch( [&](const WaveTrack *wt) { for (const auto &clip : wt->GetClips()) { clip->ClearDisplayRect(); } + const auto artist = TrackArtist::Get( context ); + const auto hasSolo = artist->hasSolo; bool muted = (hasSolo || wt->GetMute()) && !wt->GetSolo(); @@ -320,11 +309,10 @@ void TrackArtist::DrawTrack(TrackPanelDrawingContext &context, switch (wt->GetDisplay()) { case WaveTrack::Waveform: - DrawWaveform(context, wt, rect, selectedRegion, zoomInfo, - drawEnvelope, bigPoints, drawSliders, muted); + DrawWaveform(context, wt, rect, muted); break; case WaveTrack::Spectrum: - DrawSpectrum(wt, dc, rect, selectedRegion, zoomInfo); + DrawSpectrum( context, wt, rect ); break; default: wxASSERT(false); @@ -334,7 +322,9 @@ void TrackArtist::DrawTrack(TrackPanelDrawingContext &context, dc.GetGraphicsContext()->SetAntialiasMode(aamode); #endif - if (mbShowTrackNameInWaveform && + const auto bShowTrackNameInWaveform = + artist->mbShowTrackNameInWaveform; + if (bShowTrackNameInWaveform && wt->IsLeader() && // Exclude empty name. !wt->GetName().IsEmpty()) { @@ -354,21 +344,23 @@ void TrackArtist::DrawTrack(TrackPanelDrawingContext &context, [&](const NoteTrack *nt) { bool muted = false; #ifdef EXPERIMENTAL_MIDI_OUT + const auto artist = TrackArtist::Get( context ); + const auto hasSolo = artist->hasSolo; muted = (hasSolo || nt->GetMute()) && !nt->GetSolo(); #endif - DrawNoteTrack(nt, dc, rect, selectedRegion, zoomInfo, muted); + DrawNoteTrack( context, nt, rect, muted ); }, #endif // USE_MIDI [&](const LabelTrack *lt) { - DrawLabelTrack(context, lt, rect, selectedRegion, zoomInfo); + lt->Draw( context, rect ); }, [&](const TimeTrack *tt) { - DrawTimeTrack(context, tt, rect, zoomInfo); + DrawTimeTrack( context, tt, rect ); } ); } -void TrackArtist::DrawVRuler +void TrackArt::DrawVRuler ( TrackPanelDrawingContext &context, const Track *t, const wxRect & rect_, bool bSelected ) { @@ -418,8 +410,10 @@ void TrackArtist::DrawVRuler rr.width -= adj; } - UpdateVRuler(t, rr); + const auto artist = TrackArtist::Get( context ); + artist->UpdateVRuler(t, rr); + const auto &vruler = artist->vruler; vruler->SetTickColour( theTheme.Colour( clrTrackPanelText )); vruler->Draw(*dc); }, @@ -441,8 +435,10 @@ void TrackArtist::DrawVRuler rr.width -= adj; } - UpdateVRuler(t, rr); + const auto artist = TrackArtist::Get( context ); + artist->UpdateVRuler(t, rr); + const auto &vruler = artist->vruler; vruler->SetTickColour( theTheme.Colour( clrTrackPanelText )); vruler->Draw(*dc); } @@ -451,7 +447,8 @@ void TrackArtist::DrawVRuler , [&](const NoteTrack *track) { // The note track draws a vertical keyboard to label pitches - UpdateVRuler(t, rect); + const auto artist = TrackArtist::Get( context ); + artist->UpdateVRuler(t, rect); dc->SetPen(highlight ? AColor::uglyPen : *wxTRANSPARENT_PEN); dc->SetBrush(*wxWHITE_BRUSH); @@ -899,8 +896,11 @@ float ValueOfPixel(int yy, int height, bool offset, return v; } -void TrackArtist::DrawNegativeOffsetTrackArrows(wxDC &dc, const wxRect &rect) +void TrackArt::DrawNegativeOffsetTrackArrows( + TrackPanelDrawingContext &context, const wxRect &rect ) { + auto &dc = context.dc; + // Draws two black arrows on the left side of the track to // indicate the user that the track has been time-shifted // to the left beyond t=0.0. @@ -926,16 +926,19 @@ void TrackArtist::DrawNegativeOffsetTrackArrows(wxDC &dc, const wxRect &rect) rect.x + 6, rect.y + rect.height - 12); } -void TrackArtist::DrawWaveformBackground(wxDC &dc, int leftOffset, const wxRect &rect, +void TrackArt::DrawWaveformBackground(TrackPanelDrawingContext &context, + int leftOffset, const wxRect &rect, const double env[], float zoomMin, float zoomMax, int zeroLevelYCoordinate, bool dB, float dBRange, double t0, double t1, - const ZoomInfo &zoomInfo, - bool drawEnvelope, bool bIsSyncLockSelected, + bool bIsSyncLockSelected, bool highlightEnvelope) { + auto &dc = context.dc; + const auto artist = TrackArtist::Get( context ); + const auto &zoomInfo = *artist->pZoomInfo; // Visually (one vertical slice of the waveform background, on its side; // the "*" is the actual waveform background we're drawing @@ -956,6 +959,10 @@ void TrackArtist::DrawWaveformBackground(wxDC &dc, int leftOffset, const wxRect int xx, lx = 0; int l, w; + const auto &blankBrush = artist->blankBrush; + const auto &selectedBrush = artist->selectedBrush; + const auto &unselectedBrush = artist->unselectedBrush; + dc.SetPen(*wxTRANSPARENT_PEN); dc.SetBrush(blankBrush); dc.DrawRectangle(rect); @@ -981,6 +988,7 @@ void TrackArtist::DrawWaveformBackground(wxDC &dc, int leftOffset, const wxRect mintop +=1; minbot +=1; + const auto drawEnvelope = artist->drawEnvelope; if (!drawEnvelope || maxbot > mintop) { maxbot = halfHeight; mintop = halfHeight; @@ -1041,7 +1049,8 @@ void TrackArtist::DrawWaveformBackground(wxDC &dc, int leftOffset, const wxRect if (bIsSyncLockSelected && t0 < t1) { const int begin = std::max(0, std::min(rect.width, (int)(zoomInfo.TimeToPosition(t0, -leftOffset)))); const int end = std::max(0, std::min(rect.width, (int)(zoomInfo.TimeToPosition(t1, -leftOffset)))); - DrawSyncLockTiles(&dc, wxRect(rect.x + begin, rect.y, end - 1 - begin, rect.height)); + DrawSyncLockTiles( context, + { rect.x + begin, rect.y, end - 1 - begin, rect.height } ); } //OK, the display bounds are between min and max, which @@ -1055,12 +1064,15 @@ void TrackArtist::DrawWaveformBackground(wxDC &dc, int leftOffset, const wxRect } -void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect & rect, const double env[], +void TrackArt::DrawMinMaxRMS( + TrackPanelDrawingContext &context, const wxRect & rect, const double env[], float zoomMin, float zoomMax, bool dB, float dBRange, const float *min, const float *max, const float *rms, const int *bl, bool /* showProgress */, bool muted) { + auto &dc = context.dc; + // Display a line representing the // min and max of the samples in this region int lasth1 = std::numeric_limits::max(); @@ -1072,7 +1084,9 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect & rect, const double env[ ArrayOf clipped; int clipcnt = 0; - if (mShowClipping) { + const auto artist = TrackArtist::Get( context ); + const auto bShowClipping = artist->mShowClipping; + if (bShowClipping) { clipped.reinit( size_t(rect.width) ); } @@ -1082,12 +1096,15 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect & rect, const double env[ bool drawStripes = true; bool drawWaveform = true; + const auto &muteSamplePen = artist->muteSamplePen; + const auto &samplePen = artist->samplePen; + dc.SetPen(muted ? muteSamplePen : samplePen); for (int x0 = 0; x0 < rect.width; ++x0) { int xx = rect.x + x0; double v; v = min[x0] * env[x0]; - if (clipped && mShowClipping && (v <= -MAX_AUDIO)) + if (clipped && bShowClipping && (v <= -MAX_AUDIO)) { if (clipcnt == 0 || clipped[clipcnt - 1] != xx) { clipped[clipcnt++] = xx; @@ -1097,7 +1114,7 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect & rect, const double env[ rect.height, dB, true, dBRange, true); v = max[x0] * env[x0]; - if (clipped && mShowClipping && (v >= MAX_AUDIO)) + if (clipped && bShowClipping && (v >= MAX_AUDIO)) { if (clipcnt == 0 || clipped[clipcnt - 1] != xx) { clipped[clipcnt++] = xx; @@ -1170,6 +1187,9 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect & rect, const double env[ } // Stroke rms over the min-max + const auto &muteRmsPen = artist->muteRmsPen; + const auto &rmsPen = artist->rmsPen; + dc.SetPen(muted ? muteRmsPen : rmsPen); for (int x0 = 0; x0 < rect.width; ++x0) { int xx = rect.x + x0; @@ -1182,6 +1202,9 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect & rect, const double env[ // Draw the clipping lines if (clipcnt) { + const auto &muteClippedPen = artist->muteClippedPen; + const auto &clippedPen = artist->clippedPen; + dc.SetPen(muted ? muteClippedPen : clippedPen); while (--clipcnt >= 0) { int xx = clipped[clipcnt]; @@ -1190,14 +1213,18 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect & rect, const double env[ } } -void TrackArtist::DrawIndividualSamples(wxDC &dc, int leftOffset, const wxRect &rect, +void TrackArt::DrawIndividualSamples(TrackPanelDrawingContext &context, + int leftOffset, const wxRect &rect, float zoomMin, float zoomMax, bool dB, float dBRange, const WaveClip *clip, - const ZoomInfo &zoomInfo, - bool bigPoints, bool showPoints, bool muted, + bool showPoints, bool muted, bool highlight) { + auto &dc = context.dc; + const auto artist = TrackArtist::Get( context ); + const auto &zoomInfo = *artist->pZoomInfo; + const double toffset = clip->GetOffset(); double rate = clip->GetRate(); const double t0 = std::max(0.0, zoomInfo.PositionToTime(0, -leftOffset) - toffset); @@ -1226,9 +1253,12 @@ void TrackArtist::DrawIndividualSamples(wxDC &dc, int leftOffset, const wxRect & ArrayOf clipped; int clipcnt = 0; - if (mShowClipping) + const auto bShowClipping = artist->mShowClipping; + if (bShowClipping) clipped.reinit( size_t(slen) ); + const auto &muteSamplePen = artist->muteSamplePen; + const auto &samplePen = artist->samplePen; auto &pen = highlight ? AColor::uglyPen : muted ? muteSamplePen : samplePen; dc.SetPen( pen ); @@ -1244,7 +1274,7 @@ void TrackArtist::DrawIndividualSamples(wxDC &dc, int leftOffset, const wxRect & clip->GetEnvelope()->GetValue( time, 1.0 / clip->GetRate() ); const double tt = buffer[s] * value; - if (clipped && mShowClipping && ((tt <= -MAX_AUDIO) || (tt >= MAX_AUDIO))) + if (clipped && bShowClipping && ((tt <= -MAX_AUDIO) || (tt >= MAX_AUDIO))) clipped[clipcnt++] = xx; ypos[s] = std::max(-1, @@ -1256,11 +1286,14 @@ void TrackArtist::DrawIndividualSamples(wxDC &dc, int leftOffset, const wxRect & if (showPoints) { // Draw points where spacing is enough + const auto bigPoints = artist->bigPoints; const int tickSize = bigPoints ? 4 : 3;// Bigger ellipses when draggable. wxRect pr; pr.width = tickSize; pr.height = tickSize; //different colour when draggable. + const auto &dragsampleBrush = artist->dragsampleBrush; + const auto &sampleBrush = artist->sampleBrush; auto &brush = highlight ? AColor::uglyBrush : bigPoints ? dragsampleBrush : sampleBrush; @@ -1274,7 +1307,8 @@ void TrackArtist::DrawIndividualSamples(wxDC &dc, int leftOffset, const wxRect & } } - if (showPoints && (mSampleDisplay == (int) WaveTrack::StemPlot)) { + const auto sampleDisplay = artist->mSampleDisplay; + if (showPoints && (sampleDisplay == (int) WaveTrack::StemPlot)) { // Draw vertical lines int yZero = GetWaveYPos(0.0, zoomMin, zoomMax, rect.height, dB, true, dBRange, false); yZero = rect.y + std::max(-1, std::min(rect.height, yZero)); @@ -1295,6 +1329,8 @@ void TrackArtist::DrawIndividualSamples(wxDC &dc, int leftOffset, const wxRect & // Draw clipping if (clipcnt) { + const auto &muteClippedPen = artist->muteClippedPen; + const auto &clippedPen = artist->clippedPen; dc.SetPen(muted ? muteClippedPen : clippedPen); while (--clipcnt >= 0) { auto s = clipped[clipcnt]; @@ -1303,10 +1339,13 @@ void TrackArtist::DrawIndividualSamples(wxDC &dc, int leftOffset, const wxRect & } } -void TrackArtist::DrawEnvelope(wxDC &dc, const wxRect &rect, const double env[], +void TrackArt::DrawEnvelope(TrackPanelDrawingContext &context, + const wxRect &rect, const double env[], float zoomMin, float zoomMax, bool dB, float dBRange, bool highlight) { + auto &dc = context.dc; + int h = rect.height; auto &pen = highlight ? AColor::uglyPen : AColor::envelopePen; @@ -1332,13 +1371,17 @@ void TrackArtist::DrawEnvelope(wxDC &dc, const wxRect &rect, const double env[], cenvBot = value + 4; } - DrawEnvLine(dc, rect, x0, envTop, cenvTop, true); - DrawEnvLine(dc, rect, x0, envBot, cenvBot, false); + DrawEnvLine( context, rect, x0, envTop, cenvTop, true ); + DrawEnvLine( context, rect, x0, envBot, cenvBot, false ); } } -void TrackArtist::DrawEnvLine(wxDC &dc, const wxRect &rect, int x0, int y0, int cy, bool top) +void TrackArt::DrawEnvLine( + TrackPanelDrawingContext &context, + const wxRect &rect, int x0, int y0, int cy, bool top ) { + auto &dc = context.dc; + int xx = rect.x + x0; int yy = rect.y + cy; @@ -1364,17 +1407,13 @@ void TrackArtist::DrawEnvLine(wxDC &dc, const wxRect &rect, int x0, int y0, int #include "tracks/ui/TimeShiftHandle.h" #include "tracks/playabletrack/wavetrack/ui/CutlineHandle.h" -void TrackArtist::DrawWaveform(TrackPanelDrawingContext &context, +void TrackArt::DrawWaveform(TrackPanelDrawingContext &context, const WaveTrack *track, const wxRect & rect, - const SelectedRegion &selectedRegion, - const ZoomInfo &zoomInfo, - bool drawEnvelope, - bool bigPoints, - bool drawSliders, bool muted) { auto &dc = context.dc; + const auto artist = TrackArtist::Get( context ); bool highlight = false; bool gripHit = false; @@ -1386,17 +1425,20 @@ void TrackArtist::DrawWaveform(TrackPanelDrawingContext &context, const bool dB = !track->GetWaveformSettings().isLinear(); - DrawBackgroundWithSelection(&dc, rect, track, blankSelectedBrush, blankBrush, - selectedRegion, zoomInfo); + const auto &blankSelectedBrush = artist->blankSelectedBrush; + const auto &blankBrush = artist->blankBrush; + DrawBackgroundWithSelection( + context, rect, track, blankSelectedBrush, blankBrush ); for (const auto &clip: track->GetClips()) - DrawClipWaveform(context, track, clip.get(), rect, selectedRegion, zoomInfo, - drawEnvelope, bigPoints, + DrawClipWaveform(context, track, clip.get(), rect, dB, muted); // Update cache for locations, e.g. cutlines and merge points track->UpdateLocationsCache(); + const auto &zoomInfo = *artist->pZoomInfo; + #ifdef EXPERIMENTAL_TRACK_PANEL_HIGHLIGHTING auto target2 = dynamic_cast(context.target.get()); #endif @@ -1428,9 +1470,10 @@ void TrackArtist::DrawWaveform(TrackPanelDrawingContext &context, } } + const auto drawSliders = artist->drawSliders; if (drawSliders) { - DrawTimeSlider(dc, rect, true, highlight && gripHit); // directed right - DrawTimeSlider(dc, rect, false, highlight && gripHit); // directed left + DrawTimeSlider( context, rect, true, highlight && gripHit ); // directed right + DrawTimeSlider( context, rect, false, highlight && gripHit ); // directed left } } @@ -1651,18 +1694,18 @@ void FindWavePortions #include "tracks/playabletrack/wavetrack/ui/SampleHandle.h" #include "tracks/ui/EnvelopeHandle.h" -void TrackArtist::DrawClipWaveform(TrackPanelDrawingContext &context, +void TrackArt::DrawClipWaveform(TrackPanelDrawingContext &context, const WaveTrack *track, const WaveClip *clip, const wxRect & rect, - const SelectedRegion &selectedRegion, - const ZoomInfo &zoomInfo, - bool drawEnvelope, - bool bigPoints, bool dB, bool muted) { auto &dc = context.dc; + const auto artist = TrackArtist::Get( context ); + const auto &selectedRegion = *artist->pSelectedRegion; + const auto &zoomInfo = *artist->pZoomInfo; + #ifdef PROFILE_WAVEFORM Profiler profiler; #endif @@ -1673,7 +1716,8 @@ void TrackArtist::DrawClipWaveform(TrackPanelDrawingContext &context, highlightEnvelope = target && target->GetEnvelope() == clip->GetEnvelope(); #endif - const ClipParameters params(false, track, clip, rect, selectedRegion, zoomInfo); + const ClipParameters params{ + false, track, clip, rect, selectedRegion, zoomInfo }; const wxRect &hiddenMid = params.hiddenMid; // The "hiddenMid" rect contains the part of the display actually // containing the waveform, as it appears without the fisheye. If it's empty, we're done. @@ -1696,7 +1740,7 @@ void TrackArtist::DrawClipWaveform(TrackPanelDrawingContext &context, dc.SetPen(*wxTRANSPARENT_PEN); int iColorIndex = clip->GetColourIndex(); - SetColours( iColorIndex ); + artist->SetColours( iColorIndex ); // If we get to this point, the clip is actually visible on the // screen, so remember the display rectangle. @@ -1729,12 +1773,12 @@ void TrackArtist::DrawClipWaveform(TrackPanelDrawingContext &context, } else tt0 = tt1 = 0.0; - DrawWaveformBackground(dc, leftOffset, mid, + DrawWaveformBackground(context, leftOffset, mid, env, zoomMin, zoomMax, track->ZeroLevelYCoordinate(mid), dB, dBRange, - tt0, tt1, zoomInfo, drawEnvelope, + tt0, tt1, !track->GetSelected(), highlightEnvelope); } @@ -1857,11 +1901,11 @@ void TrackArtist::DrawClipWaveform(TrackPanelDrawingContext &context, 0, // 1.0 / rate, env2, rectPortion.width, leftOffset, zoomInfo ); - DrawMinMaxRMS(dc, rectPortion, env2, + DrawMinMaxRMS( context, rectPortion, env2, zoomMin, zoomMax, dB, dBRange, useMin, useMax, useRms, useBl, - isLoadingOD, muted); + isLoadingOD, muted ); } else { bool highlight = false; @@ -1869,26 +1913,29 @@ void TrackArtist::DrawClipWaveform(TrackPanelDrawingContext &context, auto target = dynamic_cast(context.target.get()); highlight = target && target->GetTrack().get() == track; #endif - DrawIndividualSamples(dc, leftOffset, rectPortion, zoomMin, zoomMax, + DrawIndividualSamples( + context, leftOffset, rectPortion, zoomMin, zoomMax, dB, dBRange, - clip, zoomInfo, - bigPoints, showPoints, muted, highlight); + clip, + showPoints, muted, highlight ); } } leftOffset += rectPortion.width + skippedRight; } + const auto drawEnvelope = artist->drawEnvelope; if (drawEnvelope) { - DrawEnvelope(dc, mid, env, zoomMin, zoomMax, dB, dBRange, highlightEnvelope); + DrawEnvelope( + context, mid, env, zoomMin, zoomMax, dB, dBRange, highlightEnvelope ); clip->GetEnvelope()->DrawPoints - (context, rect, zoomInfo, dB, dBRange, zoomMin, zoomMax, true); + ( context, rect, dB, dBRange, zoomMin, zoomMax, true ); } // Draw arrows on the left side if the track extends to the left of the // beginning of time. :) if (h == 0.0 && tOffset < 0.0) { - DrawNegativeOffsetTrackArrows(dc, rect); + DrawNegativeOffsetTrackArrows( context, rect ); } // Draw clip edges @@ -1906,10 +1953,12 @@ void TrackArtist::DrawClipWaveform(TrackPanelDrawingContext &context, } -void TrackArtist::DrawTimeSlider(wxDC & dc, - const wxRect & rect, - bool rightwards, bool highlight) +void TrackArt::DrawTimeSlider( TrackPanelDrawingContext &context, + const wxRect & rect, + bool rightwards, bool highlight ) { + auto &dc = context.dc; + const int border = 3; // 3 pixels all round. const int width = 6; // width of the drag box. const int taper = 6; // how much the box tapers by. @@ -1962,19 +2011,19 @@ void TrackArtist::DrawTimeSlider(wxDC & dc, } } -void TrackArtist::DrawSpectrum(const WaveTrack *track, - wxDC & dc, - const wxRect & rect, - const SelectedRegion &selectedRegion, - const ZoomInfo &zoomInfo) +void TrackArt::DrawSpectrum( TrackPanelDrawingContext &context, + const WaveTrack *track, + const wxRect & rect ) { - DrawBackgroundWithSelection(&dc, rect, track, blankSelectedBrush, blankBrush, - selectedRegion, zoomInfo); + const auto artist = TrackArtist::Get( context ); + const auto &blankSelectedBrush = artist->blankSelectedBrush; + const auto &blankBrush = artist->blankBrush; + DrawBackgroundWithSelection( + context, rect, track, blankSelectedBrush, blankBrush ); WaveTrackCache cache(Track::Pointer(track)); - for (const auto &clip: track->GetClips()) { - DrawClipSpectrum(cache, clip.get(), dc, rect, selectedRegion, zoomInfo); - } + for (const auto &clip: track->GetClips()) + DrawClipSpectrum( context, cache, clip.get(), rect ); } static inline float findValue @@ -2058,13 +2107,16 @@ AColor::ColorGradientChoice ChooseColorSet( float bin0, float bin1, float selBin } -void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache, +void TrackArt::DrawClipSpectrum(TrackPanelDrawingContext &context, + WaveTrackCache &waveTrackCache, const WaveClip *clip, - wxDC & dc, - const wxRect & rect, - const SelectedRegion &selectedRegion, - const ZoomInfo &zoomInfo) + const wxRect & rect) { + auto &dc = context.dc; + const auto artist = TrackArtist::Get( context ); + const auto &selectedRegion = *artist->pSelectedRegion; + const auto &zoomInfo = *artist->pZoomInfo; + #ifdef PROFILE_WAVEFORM Profiler profiler; #endif @@ -2075,7 +2127,8 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache, enum { DASH_LENGTH = 10 /* pixels */ }; - const ClipParameters params(true, track, clip, rect, selectedRegion, zoomInfo); + const ClipParameters params{ + true, track, clip, rect, selectedRegion, zoomInfo }; const wxRect &hiddenMid = params.hiddenMid; // The "hiddenMid" rect contains the part of the display actually // containing the waveform, as it appears without the fisheye. If it's empty, we're done. @@ -2676,13 +2729,17 @@ int PitchToY(double p, int bottom) sel is equal to rect, and the entire region is drawn with unselected background colors. */ -void TrackArtist::DrawNoteBackground(const NoteTrack *track, wxDC &dc, +void TrackArt::DrawNoteBackground(TrackPanelDrawingContext &context, + const NoteTrack *track, const wxRect &rect, const wxRect &sel, - const ZoomInfo &zoomInfo, const wxBrush &wb, const wxPen &wp, const wxBrush &bb, const wxPen &bp, const wxPen &mp) { + auto &dc = context.dc; + const auto artist = TrackArtist::Get( context ); + const auto &zoomInfo = *artist->pZoomInfo; + dc.SetBrush(wb); dc.SetPen(wp); #ifndef EXPERIMENTAL_NOTETRACK_OVERLAY @@ -2772,13 +2829,16 @@ graphics. Since there may be notes outside of the display region, reserve a half-note-height margin at the top and bottom of the window and draw out-of-bounds notes here instead. */ -void TrackArtist::DrawNoteTrack(const NoteTrack *track, - wxDC & dc, +void TrackArt::DrawNoteTrack(TrackPanelDrawingContext &context, + const NoteTrack *track, const wxRect & rect, - const SelectedRegion &selectedRegion, - const ZoomInfo &zoomInfo, bool muted) { + auto &dc = context.dc; + const auto artist = TrackArtist::Get( context ); + const auto &selectedRegion = *artist->pSelectedRegion; + const auto &zoomInfo = *artist->pZoomInfo; + SonifyBeginNoteBackground(); double sel0 = selectedRegion.t0(); double sel1 = selectedRegion.t1(); @@ -2803,9 +2863,8 @@ void TrackArtist::DrawNoteTrack(const NoteTrack *track, track->PrepareIPitchToY(rect); #ifdef EXPERIMENTAL_NOTETRACK_OVERLAY - DrawBackgroundWithSelection(&dc, rect, track, - AColor::labelSelectedBrush, AColor::labelUnselectedBrush, - selectedRegion, zoomInfo); + DrawBackgroundWithSelection(context, rect, track, + AColor::labelSelectedBrush, AColor::labelUnselectedBrush); #endif // Background comes in 4 colors, that are now themed. @@ -2821,7 +2880,9 @@ void TrackArtist::DrawNoteTrack(const NoteTrack *track, wxPen barLinePen; barLinePen.SetColour(theTheme.Colour( clrMidiLines)); - DrawNoteBackground(track, dc, rect, rect, zoomInfo, blankBrush, blankPen, + const auto &blankBrush = artist->blankBrush; + const auto &blankPen = artist->blankPen; + DrawNoteBackground(context, track, rect, rect, blankBrush, blankPen, blackStripeBrush, blackStripePen, barLinePen); dc.SetClippingRegion(rect); @@ -2849,7 +2910,7 @@ void TrackArtist::DrawNoteTrack(const NoteTrack *track, wxPen selectedBarLinePen; selectedBarLinePen.SetColour(theTheme.Colour( clrMidiLines)); - DrawNoteBackground(track, dc, rect, selBG, zoomInfo, + DrawNoteBackground(context, track, rect, selBG, selectedWhiteKeyBrush, selectedWhiteKeyPen, selectedBlackKeyBrush, selectedBlackKeyPen, selectedBarLinePen); @@ -3124,7 +3185,7 @@ void TrackArtist::DrawNoteTrack(const NoteTrack *track, rect.x + rect.width, rect.y + rect.height - marg - 1); // top of line if (h == 0.0 && track->GetOffset() < 0.0) { - DrawNegativeOffsetTrackArrows(dc, rect); + DrawNegativeOffsetTrackArrows( context, rect ); } dc.DestroyClippingRegion(); @@ -3133,38 +3194,24 @@ void TrackArtist::DrawNoteTrack(const NoteTrack *track, #endif // USE_MIDI -void TrackArtist::DrawLabelTrack(TrackPanelDrawingContext &context, - const LabelTrack *track, - const wxRect & rect, - const SelectedRegion &selectedRegion, - const ZoomInfo &zoomInfo) -{ - double sel0 = selectedRegion.t0(); - double sel1 = selectedRegion.t1(); - - if (!track->GetSelected() && !track->IsSyncLockSelected()) - sel0 = sel1 = 0.0; - - track->Draw(context, rect, SelectedRegion(sel0, sel1), zoomInfo); -} - -void TrackArtist::DrawTimeTrack(TrackPanelDrawingContext &context, +void TrackArt::DrawTimeTrack(TrackPanelDrawingContext &context, const TimeTrack *track, - const wxRect & rect, - const ZoomInfo &zoomInfo) + const wxRect & rect) { - track->Draw(context, rect, zoomInfo); + track->Draw( context, rect ); wxRect envRect = rect; envRect.height -= 2; double lower = track->GetRangeLower(), upper = track->GetRangeUpper(); + const auto artist = TrackArtist::Get( context ); + const auto dbRange = artist->mdBrange; if(track->GetDisplayLog()) { // MB: silly way to undo the work of GetWaveYPos while still getting a logarithmic scale - lower = LINEAR_TO_DB(std::max(1.0e-7, lower)) / mdBrange + 1.0; - upper = LINEAR_TO_DB(std::max(1.0e-7, upper)) / mdBrange + 1.0; + lower = LINEAR_TO_DB(std::max(1.0e-7, lower)) / dbRange + 1.0; + upper = LINEAR_TO_DB(std::max(1.0e-7, upper)) / dbRange + 1.0; } track->GetEnvelope()->DrawPoints - (context, envRect, zoomInfo, - track->GetDisplayLog(), mdBrange, lower, upper, false); + ( context, envRect, + track->GetDisplayLog(), dbRange, lower, upper, false ); } void TrackArtist::UpdatePrefs() @@ -3172,6 +3219,10 @@ void TrackArtist::UpdatePrefs() mdBrange = gPrefs->Read(ENV_DB_KEY, mdBrange); mShowClipping = gPrefs->Read(wxT("/GUI/ShowClipping"), mShowClipping); mSampleDisplay = TracksPrefs::SampleViewChoice(); + + mbShowTrackNameInWaveform = + gPrefs->ReadBool(wxT("/GUI/ShowTrackNameInWaveform"), false); + SetColours(0); } @@ -3188,8 +3239,11 @@ void TrackArtist::UpdatePrefs() // 5x5 box. // // There may be a better way to do this, or a more appealing pattern. -void TrackArtist::DrawSyncLockTiles(wxDC *dc, const wxRect &rect) +void TrackArt::DrawSyncLockTiles( + TrackPanelDrawingContext &context, const wxRect &rect ) { + const auto dc = &context.dc; + wxBitmap syncLockBitmap(theTheme.Image(bmpSyncLockSelTile)); // Grid spacing is a bit smaller than actual image size @@ -3295,13 +3349,19 @@ void TrackArtist::DrawSyncLockTiles(wxDC *dc, const wxRect &rect) } } -void TrackArtist::DrawBackgroundWithSelection(wxDC *dc, const wxRect &rect, +void TrackArt::DrawBackgroundWithSelection( + TrackPanelDrawingContext &context, const wxRect &rect, const Track *track, const wxBrush &selBrush, const wxBrush &unselBrush, - const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo) + bool useSelection) { + const auto dc = &context.dc; + const auto artist = TrackArtist::Get( context ); + const auto &selectedRegion = *artist->pSelectedRegion; + const auto &zoomInfo = *artist->pZoomInfo; + //MM: Draw background. We should optimize that a bit more. - const double sel0 = selectedRegion.t0(); - const double sel1 = selectedRegion.t1(); + const double sel0 = useSelection ? selectedRegion.t0() : 0.0; + const double sel1 = useSelection ? selectedRegion.t1() : 0.0; dc->SetPen(*wxTRANSPARENT_PEN); if (track->GetSelected() || track->IsSyncLockSelected()) @@ -3337,7 +3397,7 @@ void TrackArtist::DrawBackgroundWithSelection(wxDC *dc, const wxRect &rect, // Per condition above, track must be sync-lock selected dc->SetBrush(unselBrush); dc->DrawRectangle(within); - DrawSyncLockTiles(dc, within); + DrawSyncLockTiles( context, within ); } after.x = 1 + within.GetRight(); diff --git a/src/TrackArtist.h b/src/TrackArtist.h index 205d2e2c0..3e7d112cb 100644 --- a/src/TrackArtist.h +++ b/src/TrackArtist.h @@ -24,7 +24,6 @@ #include "Experimental.h" #include "audacity/Types.h" -class wxDC; class wxRect; class wxHashTable; @@ -47,33 +46,114 @@ struct TrackPanelDrawingContext; typedef unsigned char uchar; #endif -class AUDACITY_DLL_API TrackArtist { - - public: - TrackArtist(); - ~TrackArtist(); - - void SetColours(int iColorIndex); +namespace TrackArt { void DrawTracks(TrackPanelDrawingContext &context, const TrackList *tracks, const wxRegion & reg, - const wxRect &clip, int leftOffset, - const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo, - bool drawEnvelope, bool bigPoints, bool drawSliders); + const wxRect &clip); void DrawTrack(TrackPanelDrawingContext &context, const Track *t, - const wxRect & rect, - const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo, - bool drawEnvelope, bool bigPoints, bool drawSliders, - bool hasSolo); + const wxRect & rect); void DrawVRuler(TrackPanelDrawingContext &context, const Track *t, const wxRect & rect, bool bSelected ); - void UpdateVRuler(const Track *t, const wxRect & rect); + // Helper: draws the "sync-locked" watermark tiled to a rectangle + void DrawSyncLockTiles( + TrackPanelDrawingContext &context, const wxRect &rect ); - void UpdatePrefs(); + // Helper: draws background with selection rect + void DrawBackgroundWithSelection(TrackPanelDrawingContext &contex, + const wxRect &rect, const Track *track, + const wxBrush &selBrush, const wxBrush &unselBrush, + bool useSelection = true); + + // + // Lower-level drawing functions + // + + void DrawWaveform(TrackPanelDrawingContext &context, + const WaveTrack *track, + const wxRect & rect, + bool muted); + + void DrawSpectrum(TrackPanelDrawingContext &context, + const WaveTrack *track, + const wxRect & rect); +#ifdef USE_MIDI + int GetBottom(NoteTrack *t, const wxRect &rect); + void DrawNoteBackground(TrackPanelDrawingContext &context, + const NoteTrack *track, + const wxRect &rect, const wxRect &sel, + const wxBrush &wb, const wxPen &wp, + const wxBrush &bb, const wxPen &bp, + const wxPen &mp); + void DrawNoteTrack(TrackPanelDrawingContext &context, + const NoteTrack *track, + const wxRect & rect, + bool muted); +#endif // USE_MIDI + + void DrawTimeTrack(TrackPanelDrawingContext &context, + const TimeTrack *track, + const wxRect & rect); + + void DrawTimeSlider(TrackPanelDrawingContext &context, + const wxRect & rect, + bool rightwards, bool highlight); + + void DrawClipWaveform(TrackPanelDrawingContext &context, + const WaveTrack *track, const WaveClip *clip, + const wxRect & rect, + bool dB, bool muted); + + void DrawClipSpectrum(TrackPanelDrawingContext &context, + WaveTrackCache &cache, const WaveClip *clip, + const wxRect & rect); + + // Waveform utility functions + + void DrawWaveformBackground(TrackPanelDrawingContext &context, + int leftOffset, const wxRect &rect, + const double env[], + float zoomMin, float zoomMax, + int zeroLevelYCoordinate, + bool dB, float dBRange, + double t0, double t1, + bool bIsSyncLockSelected, + bool highlightEnvelope); + void DrawMinMaxRMS(TrackPanelDrawingContext &context, + const wxRect & rect, const double env[], + float zoomMin, float zoomMax, + bool dB, float dBRange, + const float *min, const float *max, const float *rms, const int *bl, + bool /* showProgress */, bool muted); + void DrawIndividualSamples(TrackPanelDrawingContext &context, + int leftOffset, const wxRect & rect, + float zoomMin, float zoomMax, + bool dB, float dBRange, + const WaveClip *clip, + bool showPoints, bool muted, + bool highlight); + + void DrawNegativeOffsetTrackArrows( TrackPanelDrawingContext &context, + const wxRect & rect ); + + void DrawEnvelope(TrackPanelDrawingContext &context, + const wxRect & rect, const double env[], + float zoomMin, float zoomMax, + bool dB, float dBRange, bool highlight); + void DrawEnvLine(TrackPanelDrawingContext &context, + const wxRect & rect, int x0, int y0, int cy, bool top); +} + +class AUDACITY_DLL_API TrackArtist { + +public: + TrackArtist(); + ~TrackArtist(); + static TrackArtist *Get( TrackPanelDrawingContext & ); void SetBackgroundBrushes(wxBrush unselectedBrushIn, wxBrush selectedBrushIn, wxPen unselectedPenIn, wxPen selectedPenIn) { @@ -83,96 +163,11 @@ class AUDACITY_DLL_API TrackArtist { this->selectedPen = selectedPenIn; } - // Helper: draws the "sync-locked" watermark tiled to a rectangle - static void DrawSyncLockTiles(wxDC *dc, const wxRect &rect); + void SetColours(int iColorIndex); - // Helper: draws background with selection rect - static void DrawBackgroundWithSelection(wxDC *dc, const wxRect &rect, - const Track *track, const wxBrush &selBrush, const wxBrush &unselBrush, - const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo); + void UpdatePrefs(); - private: - - // - // Lower-level drawing functions - // - - void DrawWaveform(TrackPanelDrawingContext &context, - const WaveTrack *track, - const wxRect & rect, - const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo, - bool drawEnvelope, bool bigPoints, bool drawSliders, - bool muted); - - void DrawSpectrum(const WaveTrack *track, - wxDC & dc, const wxRect & rect, - const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo); -#ifdef USE_MIDI - int GetBottom(NoteTrack *t, const wxRect &rect); - void DrawNoteBackground(const NoteTrack *track, wxDC &dc, - const wxRect &rect, const wxRect &sel, - const ZoomInfo &zoomInfo, - const wxBrush &wb, const wxPen &wp, - const wxBrush &bb, const wxPen &bp, - const wxPen &mp); - void DrawNoteTrack(const NoteTrack *track, - wxDC & dc, const wxRect & rect, - const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo, - bool muted); -#endif // USE_MIDI - - void DrawLabelTrack(TrackPanelDrawingContext &context, - const LabelTrack *track, - const wxRect & rect, - const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo); - - void DrawTimeTrack(TrackPanelDrawingContext &context, - const TimeTrack *track, - const wxRect & rect, const ZoomInfo &zoomInfo); - - void DrawTimeSlider(wxDC & dc, const wxRect & rect, - bool rightwards, bool highlight); - - void DrawClipWaveform(TrackPanelDrawingContext &context, - const WaveTrack *track, const WaveClip *clip, - const wxRect & rect, - const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo, - bool drawEnvelope, bool bigPoints, - bool dB, bool muted); - - void DrawClipSpectrum(WaveTrackCache &cache, const WaveClip *clip, - wxDC & dc, const wxRect & rect, - const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo); - - // Waveform utility functions - - void DrawWaveformBackground(wxDC & dc, int leftOffset, const wxRect &rect, - const double env[], - float zoomMin, float zoomMax, - int zeroLevelYCoordinate, - bool dB, float dBRange, - double t0, double t1, const ZoomInfo &zoomInfo, - bool drawEnvelope, bool bIsSyncLockSelected, - bool highlightEnvelope); - void DrawMinMaxRMS(wxDC &dc, const wxRect & rect, const double env[], - float zoomMin, float zoomMax, - bool dB, float dBRange, - const float *min, const float *max, const float *rms, const int *bl, - bool /* showProgress */, bool muted); - void DrawIndividualSamples(wxDC & dc, int leftOffset, const wxRect & rect, - float zoomMin, float zoomMax, - bool dB, float dBRange, - const WaveClip *clip, - const ZoomInfo &zoomInfo, - bool bigPoints, bool showPoints, bool muted, - bool highlight); - - void DrawNegativeOffsetTrackArrows(wxDC & dc, const wxRect & rect); - - void DrawEnvelope(wxDC & dc, const wxRect & rect, const double env[], - float zoomMin, float zoomMax, - bool dB, float dBRange, bool highlight); - void DrawEnvLine(wxDC & dc, const wxRect & rect, int x0, int y0, int cy, bool top); + void UpdateVRuler(const Track *t, const wxRect & rect); // Preference values float mdBrange; // "/GUI/EnvdBRange" @@ -215,6 +210,15 @@ class AUDACITY_DLL_API TrackArtist { int findNotesNOld; bool findNotesQuantizeOld; #endif + + SelectedRegion *pSelectedRegion{}; + ZoomInfo *pZoomInfo{}; + + int leftOffset{ 0 }; + bool drawEnvelope{ false }; + bool bigPoints{ false }; + bool drawSliders{ false }; + bool hasSolo{ false }; }; extern int GetWaveYPos(float value, float min, float max, diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 39c21c946..c2e2942cb 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -1048,7 +1048,11 @@ void TrackPanel::DrawTracks(wxDC * dc) const wxRect clip = GetRect(); - TrackPanelDrawingContext context{ *dc, Target(), mLastMouseState }; + mTrackArtist->pSelectedRegion = &mViewInfo->selectedRegion; + mTrackArtist->pZoomInfo = mViewInfo; + TrackPanelDrawingContext context { + *dc, Target(), mLastMouseState, mTrackArtist.get() + }; // Draw margins on two or three sides. ClearLeftAndRightMargins(context, clip); @@ -1064,11 +1068,19 @@ void TrackPanel::DrawTracks(wxDC * dc) bool bigPointsFlag = pTtb->IsDown(drawTool) || bMultiToolDown; bool sliderFlag = bMultiToolDown; - // The track artist actually draws the stuff inside each track - mTrackArtist->DrawTracks(context, GetTracks(), - region, clip, GetLeftOffset(), - mViewInfo->selectedRegion, *mViewInfo, - envelopeFlag, bigPointsFlag, sliderFlag); + const bool hasSolo = GetTracks()->Any< PlayableTrack >() + .any_of( []( const PlayableTrack *pt ) { + pt = static_cast< const PlayableTrack * >( + pt->SubstitutePendingChangedTrack().get() ); + return (pt && pt->GetSolo()); + } ); + + mTrackArtist->leftOffset = GetLeftOffset(); + mTrackArtist->drawEnvelope = envelopeFlag; + mTrackArtist->bigPoints = bigPointsFlag; + mTrackArtist->drawSliders = sliderFlag; + mTrackArtist->hasSolo = hasSolo; + TrackArt::DrawTracks( context, GetTracks(), region, clip ); // Draw the rest, including the click-to-deselect blank area below all // tracks @@ -1142,7 +1154,7 @@ void TrackPanel::DrawEverythingElse(TrackPanelDrawingContext &context, GetVRulerWidth() + 1, trackRect.height - kSeparatorThickness }; - mTrackArtist->DrawVRuler(context, channel, rect, bSelected); + TrackArt::DrawVRuler(context, channel, rect, bSelected); } } } @@ -1638,7 +1650,7 @@ void TrackPanel::DrawOutside // wxRect tileFill = rect; // tileFill.x = GetVRulerOffset(); // tileFill.width = GetVRulerWidth(); - // TrackArtist::DrawSyncLockTiles(dc, tileFill); + // TrackArt::DrawSyncLockTiles(dc, tileFill); //} DrawBordersAroundTrack( dc, rect ); diff --git a/src/TrackPanelDrawingContext.h b/src/TrackPanelDrawingContext.h index 79c656090..aa08dd76b 100644 --- a/src/TrackPanelDrawingContext.h +++ b/src/TrackPanelDrawingContext.h @@ -24,6 +24,8 @@ struct TrackPanelDrawingContext { UIHandlePtr target; wxMouseState lastState; + void *pUserData; + // This redundancy fixes an MSVC compiler warning: TrackPanelDrawingContext() = delete; }; diff --git a/src/effects/Equalization.cpp b/src/effects/Equalization.cpp index d1b170e84..eadf269a3 100644 --- a/src/effects/Equalization.cpp +++ b/src/effects/Equalization.cpp @@ -90,6 +90,7 @@ #include "../FFT.h" #include "../Prefs.h" #include "../Project.h" +#include "../TrackArtist.h" #include "../WaveTrack.h" #include "../widgets/Ruler.h" #include "../xml/XMLFileReader.h" @@ -3049,9 +3050,12 @@ void EqualizationPanel::OnPaint(wxPaintEvent & WXUNUSED(event)) memDC.SetPen(*wxBLACK_PEN); if( mEffect->mDraw->GetValue() ) { - TrackPanelDrawingContext context{ memDC, {}, {} }; + ZoomInfo zoomInfo( 0.0, mEnvRect.width-1 ); + TrackArtist artist; + artist.pZoomInfo = &zoomInfo; + TrackPanelDrawingContext context{ memDC, {}, {}, &artist }; mEffect->mEnvelope->DrawPoints( - context, mEnvRect, ZoomInfo(0.0, mEnvRect.width-1), false, 0.0, + context, mEnvRect, false, 0.0, mEffect->mdBMin, mEffect->mdBMax, false); }