22#include "../../../ui/EnvelopeHandle.h"
23#include "../../../ui/TimeShiftHandle.h"
26#include "../../../../EnvelopeEditor.h"
28#include "../../../../ProjectSettings.h"
31#include "../../../../TrackArt.h"
32#include "../../../../TrackArtist.h"
33#include "../../../../TrackPanelDrawingContext.h"
34#include "../../../../TrackPanelMouseEvent.h"
40#include "../../../../WaveTrackLocation.h"
41#include "../../../../prefs/WaveformSettings.h"
45#include <wx/graphics.h>
50 {
wxT(
"Waveform"),
XXO(
"Wa&veform") }
62 const auto pChannel = view.FindChannel<
WaveChannel>();
65 st, pProject, currentTool, bMultiTool, pChannel);
66 auto &results = pair.second;
79 results.push_back(result);
82 pChannel->GetTrack().SharedPointer())))
85 results.push_back(result);
89 results.push_back(result);
92 switch ( currentTool ) {
98 viewInfo.PositionToTime(st.
state.m_x, st.
rect.GetX());
102 view.mEnvelopeHandle, envelope,
103 std::dynamic_pointer_cast<const Channel>(pChannel),
109 view.mSampleHandle, st.
state, pChannel);
116 results.push_back(result);
120 return std::move( results );
128 gPrefs->
Read(
wxT(
"/GUI/CollapseToHalfWave"), &bHalfWave,
false);
129 if (wt && bHalfWave) {
133 cache.SetDisplayBounds( -0.01f, 1.0f );
136 cache.SetDisplayBounds( -1.0f, 1.0f );
149 return std::make_shared<WaveformVRulerControls>(shared_from_this());
156 int leftOffset,
const wxRect &rect,
158 float zoomMin,
float zoomMax,
159 int zeroLevelYCoordinate,
160 bool dB,
float dBRange,
161 double t0,
double t1,
162 bool bIsSyncLockSelected,
163 bool highlightEnvelope)
165 auto &dc = context.
dc;
167 const auto &zoomInfo = *artist->pZoomInfo;
179 int halfHeight = wxMax(h / 2, 1);
180 int maxtop, lmaxtop = 0;
181 int mintop, lmintop = 0;
182 int maxbot, lmaxbot = 0;
183 int minbot, lminbot = 0;
184 bool sel, lsel =
false;
188 const auto &blankBrush = artist->blankBrush;
189 const auto &selectedBrush = artist->selectedBrush;
190 const auto &unselectedBrush = artist->unselectedBrush;
192 dc.SetPen(*wxTRANSPARENT_PEN);
193 dc.SetBrush(blankBrush);
194 dc.DrawRectangle(rect);
197 int selectedX = zoomInfo.TimeToPosition(t0, -leftOffset);
199 double time = zoomInfo.PositionToTime(0, -leftOffset), nextTime;
200 for (xx = 0; xx < rect.width; ++xx, time = nextTime) {
201 nextTime = zoomInfo.PositionToTime(xx + 1, -leftOffset);
207 h, dB,
true, dBRange,
true);
209 h, dB,
false, dBRange,
true);
212 h, dB,
false, dBRange,
true);
214 h, dB,
true, dBRange,
true);
220 const auto drawEnvelope = artist->drawEnvelope;
221 if (!drawEnvelope || maxbot > mintop) {
226 sel = (t0 <= time && nextTime < t1);
227 sel = sel || (xx == selectedX);
229 sel = sel && !bIsSyncLockSelected;
231 if (lmaxtop == maxtop &&
239 dc.SetBrush(lsel ? selectedBrush : unselectedBrush);
243 if (lmaxbot < lmintop - 1) {
244 dc.DrawRectangle(l, rect.y + lmaxtop, w, lmaxbot - lmaxtop);
245 dc.DrawRectangle(l, rect.y + lmintop, w, lminbot - lmintop);
248 dc.DrawRectangle(l, rect.y + lmaxtop, w, lminbot - lmaxtop);
251 if (highlightEnvelope && lmaxbot < lmintop - 1) {
253 dc.DrawRectangle(l, rect.y + lmaxbot, w, lmintop - lmaxbot);
264 dc.SetBrush(lsel ? selectedBrush : unselectedBrush);
267 if (lmaxbot < lmintop - 1) {
268 dc.DrawRectangle(l, rect.y + lmaxtop, w, lmaxbot - lmaxtop);
269 dc.DrawRectangle(l, rect.y + lmintop, w, lminbot - lmintop);
272 dc.DrawRectangle(l, rect.y + lmaxtop, w, lminbot - lmaxtop);
274 if (highlightEnvelope && lmaxbot < lmintop - 1) {
276 dc.DrawRectangle(l, rect.y + lmaxbot, w, lmintop - lmaxbot);
280 if (bIsSyncLockSelected && t0 < t1) {
281 const int begin = std::max(0,
std::min(rect.width, (
int)(zoomInfo.TimeToPosition(t0, -leftOffset))));
282 const int end = std::max(0,
std::min(rect.width, (
int)(zoomInfo.TimeToPosition(t1, -leftOffset))));
289 if (zeroLevelYCoordinate >= rect.GetTop() &&
290 zeroLevelYCoordinate <= rect.GetBottom()) {
291 dc.SetPen(*wxBLACK_PEN);
293 rect.x + rect.width - 1, zeroLevelYCoordinate);
302 : rect(x, y, w, h), averageZoom(zoom), inFisheye(i)
307 (std::vector<WavePortion> &portions,
const wxRect &rect,
const ZoomInfo &zoomInfo,
315 const auto intervals = zoomInfo.
FindIntervals(rect.width, rect.x);
316 ZoomInfo::Intervals::const_iterator it = intervals.begin(),
end = intervals.end(), prev;
317 wxASSERT(it !=
end && it->position == rect.x);
318 const int rightmost = rect.x + rect.width;
319 for (
int left = rect.x; left < rightmost;) {
320 while (it !=
end && it->position <= left)
324 const int right = std::max(left, (
int)(it->position));
325 const int width = right - left;
329 prev->averageZoom, prev->inFisheye)
337 float zoomMin,
float zoomMax,
338 bool dB,
float dBRange,
339 const float *
min,
const float *max,
const float *rms,
342 auto &dc = context.
dc;
346 int lasth1 = std::numeric_limits<int>::max();
356 const auto bShowClipping = artist->mShowClipping;
358 clipped.
reinit(
size_t(rect.width) );
361 long pixAnimOffset = (long)fabs((
double)(wxDateTime::Now().GetTicks() * -10)) +
362 wxDateTime::Now().GetMillisecond() / 100;
364 const auto ms = wxDateTime::Now().GetMillisecond();
365 const auto ticks = (long)fabs((
double)(wxDateTime::Now().GetTicks() * -10));
367 const auto &muteSamplePen = artist->muteSamplePen;
368 const auto &samplePen = artist->samplePen;
370 dc.SetPen(muted ? muteSamplePen : samplePen);
371 for (
int x0 = 0; x0 < rect.width; ++x0) {
372 int xx = rect.x + x0;
374 v =
min[x0] * env[x0];
375 if (clipped && bShowClipping && (v <= -
MAX_AUDIO))
377 if (clipcnt == 0 || clipped[clipcnt - 1] != xx) {
378 clipped[clipcnt++] = xx;
382 rect.height, dB,
true, dBRange,
true);
384 v = max[x0] * env[x0];
385 if (clipped && bShowClipping && (v >=
MAX_AUDIO))
387 if (clipcnt == 0 || clipped[clipcnt - 1] != xx) {
388 clipped[clipcnt++] = xx;
392 rect.height, dB,
true, dBRange,
true);
407 r1[x0] =
GetWaveYPos(-rms[x0] * env[x0], zoomMin, zoomMax,
408 rect.height, dB,
true, dBRange,
true);
409 r2[x0] =
GetWaveYPos(rms[x0] * env[x0], zoomMin, zoomMax,
410 rect.height, dB,
true, dBRange,
true);
412 if (r1[x0] > h1 - 1) {
415 if (r2[x0] < h2 + 1) {
418 if (r2[x0] > r1[x0]) {
426 const auto &muteRmsPen = artist->muteRmsPen;
427 const auto &rmsPen = artist->rmsPen;
429 dc.SetPen(muted ? muteRmsPen : rmsPen);
430 for (
int x0 = 0; x0 < rect.width; ++x0) {
431 int xx = rect.x + x0;
432 if (r1[x0] != r2[x0]) {
433 AColor::Line(dc, xx, rect.y + r2[x0], xx, rect.y + r1[x0]);
439 const auto &muteClippedPen = artist->muteClippedPen;
440 const auto &clippedPen = artist->clippedPen;
442 dc.SetPen(muted ? muteClippedPen : clippedPen);
443 while (--clipcnt >= 0) {
444 int xx = clipped[clipcnt];
451 int leftOffset,
const wxRect &rect,
452 float zoomMin,
float zoomMax,
453 bool dB,
float dBRange,
455 bool showPoints,
bool muted,
459 auto &dc = context.
dc;
461 const auto &zoomInfo = *artist->pZoomInfo;
465 const double t0 = std::max(0.0, zoomInfo.PositionToTime(0, -leftOffset) - toffset);
471 const double t1 = zoomInfo.PositionToTime(rect.width - 1, -leftOffset) - toffset;
476 auto slen =
std::min(snSamples - s0, s1 - s0 + 1).as_size_t();
481 Floats buffer{ size_t(slen) };
491 const auto bShowClipping = artist->mShowClipping;
493 clipped.
reinit(
size_t(slen) );
495 const auto &muteSamplePen = artist->muteSamplePen;
496 const auto &samplePen = artist->samplePen;
497 auto &pen = highlight ?
AColor::uglyPen : muted ? muteSamplePen : samplePen;
500 for (
decltype(slen) s = 0; s < slen; s++) {
501 const double time = toffset + (s + s0).as_double() / rate;
504 (
int)(zoomInfo.TimeToPosition(time, -leftOffset))));
509 const double tt = buffer[s] * value;
512 clipped[clipcnt++] = xx;
517 rect.height, dB,
true, dBRange,
false)));
523 const auto bigPoints = artist->bigPoints;
524 const int tickSize = bigPoints ? 4 : 3;
527 pr.height = tickSize;
529 const auto &dragsampleBrush = artist->dragsampleBrush;
530 const auto &sampleBrush = artist->sampleBrush;
531 auto &brush = highlight
533 : bigPoints ? dragsampleBrush : sampleBrush;
534 dc.SetBrush( brush );
535 for (
decltype(slen) s = 0; s < slen; s++) {
536 if (ypos[s] >= 0 && ypos[s] < rect.height) {
537 pr.x = rect.x + xpos[s] - tickSize/2;
538 pr.y = rect.y + ypos[s] - tickSize/2;
544 const auto sampleDisplay = artist->mSampleDisplay;
549 int yZero =
GetWaveYPos(0.0, zoomMin, zoomMax, rect.height, dB,
true, dBRange,
false);
550 yZero = rect.y + std::max(-1,
std::min(rect.height, yZero));
551 for (
decltype(slen) s = 0; s < slen; s++) {
553 rect.x + xpos[s], rect.y + ypos[s],
554 rect.x + xpos[s], yZero);
559 for (
decltype(slen) s = 0; s < slen - 1; s++) {
561 rect.x + xpos[s], rect.y + ypos[s],
562 rect.x + xpos[s + 1], rect.y + ypos[s + 1]);
568 const auto &muteClippedPen = artist->muteClippedPen;
569 const auto &clippedPen = artist->clippedPen;
570 dc.SetPen(muted ? muteClippedPen : clippedPen);
571 while (--clipcnt >= 0) {
572 auto s = clipped[clipcnt];
573 AColor::Line(dc, rect.x + s, rect.y, rect.x + s, rect.y + rect.height);
580 const wxRect &rect,
int x0,
int y0,
int cy,
bool top )
582 auto &dc = context.
dc;
584 int xx = rect.x + x0;
585 int yy = rect.y + cy;
592 else if (y0 > rect.height) {
608 const wxRect &rect,
const double env[],
609 float zoomMin,
float zoomMax,
610 bool dB,
float dBRange,
bool highlight)
612 auto &dc = context.
dc;
619 for (
int x0 = 0; x0 < rect.width; ++x0) {
620 int cenvTop =
GetWaveYPos(env[x0], zoomMin, zoomMax,
621 h, dB,
true, dBRange,
true);
623 int cenvBot =
GetWaveYPos(-env[x0], zoomMin, zoomMax,
624 h, dB,
true, dBRange,
true);
626 int envTop =
GetWaveYPos(env[x0], zoomMin, zoomMax,
627 h, dB,
true, dBRange,
false);
629 int envBot =
GetWaveYPos(-env[x0], zoomMin, zoomMax,
630 h, dB,
true, dBRange,
false);
633 if (cenvBot - cenvTop < 9) {
634 int value = (int)((zoomMax / (zoomMax - zoomMin)) * h);
639 DrawEnvLine( context, rect, x0, envTop, cenvTop,
true );
640 DrawEnvLine( context, rect, x0, envBot, cenvBot,
false );
649 const wxRect &rect,
bool dB,
bool muted,
bool selected)
652 auto &dc = context.
dc;
654 const auto &selectedRegion = *artist->pSelectedRegion;
655 const auto &zoomInfo = *artist->pZoomInfo;
659 bool highlightEnvelope =
false;
660#ifdef EXPERIMENTAL_TRACK_PANEL_HIGHLIGHTING
662 highlightEnvelope = target && target->
GetEnvelope() == &envelope;
675 const wxRect &hiddenMid =
params.hiddenMid;
678 if (hiddenMid.width <= 0) {
682 const double &t0 =
params.t0;
684 const double &trackRectT0 =
params.trackRectT0;
685 const double &averagePixelsPerSecond =
params.averagePixelsPerSecond;
688 double leftOffset =
params.leftOffset;
689 const wxRect &mid =
params.mid;
692 const float dBRange =
settings.dBRange;
694 dc.SetPen(*wxTRANSPARENT_PEN);
696 artist->SetColours( iColorIndex );
700 float zoomMin, zoomMax;
702 cache.GetDisplayBounds(zoomMin, zoomMax);
704 std::vector<double> vEnv(mid.width);
705 double *
const env = &vEnv[0];
712 env, mid.width, leftOffset, zoomInfo);
719 const auto &track = channel.
GetTrack();
722 tt1 = track.SnapToSample(selectedRegion.t1());
729 cache.ZeroLevelYCoordinate(mid),
732 !track.GetSelected(), highlightEnvelope);
739 std::vector<WavePortion> portions;
741 const unsigned nPortions = portions.size();
744 const double threshold1 = 0.5 *
sampleRate / stretchRatio;
746 const double threshold2 = 3 *
sampleRate / stretchRatio;
751 bool showIndividualSamples =
false;
752 for (
unsigned ii = 0; !showIndividualSamples && ii < nPortions; ++ii) {
754 showIndividualSamples =
758 if (!showIndividualSamples) {
769 if (!clipCache.GetWaveDisplay(clip,
770 display, t0, averagePixelsPerSecond))
777 for (
unsigned ii = 0; ii < nPortions; ++ii) {
779 const bool showIndividualSamples = portion.
averageZoom > threshold1;
780 const bool showPoints = portion.
averageZoom > threshold2;
781 wxRect& rectPortion = portion.
rect;
782 rectPortion.Intersect(mid);
783 wxASSERT(rectPortion.width >= 0);
785 float *useMin = 0, *useMax = 0, *useRms = 0;
787 int skipped = 0, skippedLeft = 0, skippedRight = 0;
789 if (!showIndividualSamples) {
794 for (; jj < rectPortion.width; ++jj) {
796 zoomInfo.PositionToTime(jj, -leftOffset) - playStartTime;
803 if (sample >= numSamples)
805 fisheyeDisplay.
where[jj - skippedLeft] = sample;
808 skippedRight = rectPortion.width - jj;
809 skipped = skippedRight + skippedLeft;
810 rectPortion.width -= skipped;
814 fisheyeDisplay.
where[jj - skippedLeft] =
815 1 + fisheyeDisplay.
where[jj - skippedLeft - 1];
816 fisheyeDisplay.
width -= skipped;
818 if (rectPortion.width > 0)
819 if (!clipCache.GetWaveDisplay(clip,
820 fisheyeDisplay, t0, -1.0))
822 useMin = fisheyeDisplay.
min;
823 useMax = fisheyeDisplay.
max;
824 useRms = fisheyeDisplay.
rms;
828 const int pos = leftOffset -
params.hiddenLeftOffset;
829 useMin = display.
min + pos;
830 useMax = display.
max + pos;
831 useRms = display.
rms + pos;
834 leftOffset += skippedLeft;
836 if (rectPortion.width > 0) {
837 if (!showIndividualSamples) {
838 std::vector<double> vEnv2(rectPortion.width);
839 double *
const env2 = &vEnv2[0];
846 env2, rectPortion.width, leftOffset, zoomInfo);
851 useMin, useMax, useRms, muted);
854 bool highlight =
false;
855#ifdef EXPERIMENTAL_TRACK_PANEL_HIGHLIGHTING
857 highlight = target && target->
FindTrack().get() ==
861 context, leftOffset, rectPortion, zoomMin, zoomMax,
862 dB, dBRange, clip, showPoints, muted, highlight);
866 leftOffset += rectPortion.width + skippedRight;
869 const auto drawEnvelope = artist->drawEnvelope;
872 context, mid, env, zoomMin, zoomMax, dB, dBRange, highlightEnvelope);
874 context, mid, dB, dBRange, zoomMin, zoomMax,
true, rect.x - mid.x);
879 if (trackRectT0 == 0.0 && playStartTime < 0.0)
891 bool rightwards,
bool highlight )
893 auto &dc = context.
dc;
895 const int border = 3;
898 const int barSpacing = 4;
899 const int barWidth = 3;
903 if (rect.height <= ((taper+border + barSpacing) * 2)) {
906 if (rect.width <= (width * 2 + border * 3)) {
911 int leftTaper = rightwards ? 0 : 6;
912 int rightTaper = rightwards ? 6 : 0;
914 int xLeft = rightwards ? (rect.x + border - 2)
915 : (rect.x + rect.width + 1 - (border + width));
916 int yTop = rect.y + border;
917 int yBot = rect.y + rect.height - border - 1;
920 AColor::Line(dc, xLeft, yBot - leftTaper, xLeft, yTop + leftTaper);
921 AColor::Line(dc, xLeft, yTop + leftTaper, xLeft + xFlat, yTop);
922 AColor::Line(dc, xLeft + xFlat, yTop, xLeft + width, yTop + rightTaper);
925 AColor::Line(dc, xLeft + width, yTop + rightTaper, xLeft + width, yBot - rightTaper);
926 AColor::Line(dc, xLeft + width, yBot - rightTaper, xLeft + width-xFlat, yBot);
927 AColor::Line(dc, xLeft + width - xFlat, yBot, xLeft, yBot - leftTaper);
929 int firstBar = yTop + taper + taper / 2;
930 int nBars = (yBot - yTop - taper * 3) / barSpacing + 1;
931 xLeft += (width - barWidth + 1) / 2;
936 for (i = 0;i < nBars; i++) {
937 yy = firstBar + barSpacing * i;
941 for(i = 0;i < nBars; i++){
942 yy = firstBar + barSpacing * i + 1;
957 auto &dc = context.
dc;
960 bool highlight =
false;
961 bool gripHit =
false;
962#ifdef EXPERIMENTAL_TRACK_PANEL_HIGHLIGHTING
965 highlight = target && target->FindTrack().get() ==
971 const auto &blankSelectedBrush = artist->blankSelectedBrush;
972 const auto &blankBrush = artist->blankBrush;
974 context, rect, channel, blankSelectedBrush, blankBrush );
976 for (
const auto &pInterval : channel.
Intervals()) {
977 bool selected = selectedClip &&
978 selectedClip == &pInterval->GetClip();
983 const auto drawSliders = artist->drawSliders;
995 const auto &pendingTracks = *artist->pPendingTracks;
996 auto &dc = context.
dc;
1002 pendingTracks.SubstitutePendingChangedChannel(*pChannel));
1004 const auto hasSolo = artist->hasSolo;
1005 bool muted = (hasSolo || wc.GetTrack().GetMute()) &&
1008#if defined(__WXMAC__)
1009 wxAntialiasMode aamode = dc.GetGraphicsContext()->GetAntialiasMode();
1010 dc.GetGraphicsContext()->SetAntialiasMode(wxANTIALIAS_NONE);
1014 wxASSERT(waveChannelView.use_count());
1016 auto selectedClip = waveChannelView->GetSelectedClip();
1017 DoDraw(context, wc, selectedClip.get(), rect, muted);
1019#if defined(__WXMAC__)
1020 dc.GetGraphicsContext()->SetAntialiasMode(aamode);
1028 return std::make_shared<WaveformView>( view );
1038#include "../../../../widgets/PopupMenuTable.h"
1041#include "../../../../RefreshCode.h"
1078 return XXO(
"Instrument %i").Format( colorIndex+1 );
1086 const auto &track =
static_cast<WaveTrack&
>(pData->track);
1087 auto &
project = pData->project;
1090 menu.Check(
id,
id == me.IdOfWaveColor(
1092 menu.Enable(
id, !unsafe );
1096 std::call_once(
flag, [
this]{
1098 OnInstrument1ID = hostTable.ReserveId();
1099 OnInstrument2ID = hostTable.ReserveId();
1100 OnInstrument3ID = hostTable.ReserveId();
1101 OnInstrument4ID = hostTable.ReserveId();
1117{
return OnInstrument1ID + WaveColor;}
1123 int id =
event.GetId();
1136 XO(
"WaveColor Change"));
1145 {
"SubViews/Extra" },
1146 std::make_unique<PopupMenuSection>(
"WaveColor",
1148 PopupMenuTable::Adapt<WaveTrackPopupMenuTable>(
1152 const auto displays = view.GetDisplays();
1153 bool hasWaveform = (displays.end() != std::find(
1154 displays.begin(), displays.end(),
1156 WaveChannelViewConstants::Waveform, {} }
std::shared_ptr< UIHandle > UIHandlePtr
EffectDistortionSettings params
XXO("&Cut/Copy/Paste Toolbar")
audacity::BasicSettings * gPrefs
int GetWaveYPos(float value, float min, float max, int height, bool dB, bool outer, float dBr, bool clip)
static Settings & settings()
WaveTrackPopupMenuTable & GetWaveTrackMenuTable()
static void Line(wxDC &dc, wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
static void Light(wxDC *dc, bool selected, bool highlight=false)
static void Dark(wxDC *dc, bool selected, bool highlight=false)
void reinit(Integral count, bool initialize=false)
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
ChannelGroup & GetChannelGroup()
Channel object's lifetime is assumed to be nested in its Track's.
virtual void DoSetMinimized(bool isMinimized)
Client code makes static instance from a factory of attachments; passes it to Get or Find as a retrie...
auto FindChannel() -> std::shared_ptr< Subtype >
May return null.
static void GetEnvelopeValues(const Envelope &env, double aligned_time, double sampleDur, double *buffer, int bufferLen, int leftOffset, const ZoomInfo &zoomInfo)
Get many envelope points for pixel columns at once, but don't assume uniform time per pixel.
static void DrawPoints(const Envelope &env, TrackPanelDrawingContext &context, const wxRect &r, bool dB, double dBRange, float zoomMin, float zoomMax, bool mirrored, int origin=0)
static UIHandlePtr WaveChannelHitTest(std::weak_ptr< EnvelopeHandle > &holder, const wxMouseState &state, const wxRect &rect, const AudacityProject *pProject, const std::shared_ptr< WaveChannel > &wt)
Envelope * GetEnvelope() const
static UIHandlePtr HitAnywhere(std::weak_ptr< EnvelopeHandle > &holder, Envelope *envelope, std::weak_ptr< const Channel > wChannel, bool timeTrack)
Piecewise linear or piecewise exponential function from double to double.
double GetValue(double t, double sampleDur=0) const
Get envelope value at time t.
@ WaveformView
Time required to draw a single clip.
static Stopwatch CreateStopwatch(SectionID section) noexcept
Create a Stopwatch for the section specified.
bool IsAudioActive() const
static ProjectAudioIO & Get(AudacityProject &project)
void PushState(const TranslatableString &desc, const TranslatableString &shortDesc)
static ProjectHistory & Get(AudacityProject &project)
static UIHandlePtr HitAnywhere(std::weak_ptr< SampleHandle > &holder, const wxMouseState &state, const std::shared_ptr< WaveChannel > &pChannel)
std::shared_ptr< const Track > FindTrack() const override
static UIHandlePtr HitTest(std::weak_ptr< SampleHandle > &holder, const wxMouseState &state, const wxRect &rect, const AudacityProject *pProject, const std::shared_ptr< WaveChannel > &pChannel)
static bool IsSelectedOrSyncLockSelected(const Track &track)
static UIHandlePtr HitTest(std::weak_ptr< TimeShiftHandle > &holder, const wxMouseState &state, const wxRect &rect, const std::shared_ptr< Track > &pTrack)
static TrackArtist * Get(TrackPanelDrawingContext &)
Abstract base class for an object holding data associated with points on a time axis.
virtual void Draw(TrackPanelDrawingContext &context, const wxRect &rect, unsigned iPass)
Holds a msgid for the translation catalog; may also bind format arguments.
static ViewInfo & Get(AudacityProject &project)
IteratorRange< IntervalIterator< WaveClipChannel > > Intervals()
std::shared_ptr< WaveChannel > FindWaveChannel()
static void DrawBoldBoundaries(TrackPanelDrawingContext &context, const WaveChannel &channel, const wxRect &rect)
std::pair< bool, std::vector< UIHandlePtr > > DoDetailedHitTest(const TrackPanelMouseState &state, const AudacityProject *pProject, int currentTool, bool bMultiTool, const std::shared_ptr< WaveChannel > &wt)
std::weak_ptr< WaveChannelView > GetWaveChannelView() const
static bool ClipDetailsVisible(const ClipTimes &clip, const ZoomInfo &zoomInfo, const wxRect &viewRect)
static WaveChannelView & GetFirst(WaveTrack &wt)
Get the view of the first channel.
sampleCount GetVisibleSampleCount() const override
int GetRate() const override
double GetPlayStartTime() const override
double GetStretchRatio() const override
sampleCount TimeToSamples(double time) const override
bool GetSamples(samplePtr buffer, sampleFormat format, sampleCount start, size_t len, bool mayThrow=true) const
This allows multiple clips to be a part of one WaveTrack.
A Track that contains audio waveform data.
bool GetSolo() const override
May vary asynchronously.
double SnapToSample(double t) const
Intervals FindIntervals(int64 width, int64 origin=0) const
virtual bool Read(const wxString &key, bool *value) const =0
Positions or offsets within audio files need a wide type.
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
Namespace containing an enum 'what to do on a refresh?'.
std::unique_ptr< detail::IndirectItem< Item > > Indirect(const std::shared_ptr< Item > &ptr)
A convenience function.
AUDACITY_DLL_API void DrawSyncLockTiles(TrackPanelDrawingContext &context, const wxRect &rect)
AUDACITY_DLL_API void DrawClipFolded(wxDC &dc, const wxRect &rect)
AUDACITY_DLL_API void DrawClipEdges(wxDC &dc, const wxRect &clipRect, bool selected=false)
AUDACITY_DLL_API void DrawNegativeOffsetTrackArrows(TrackPanelDrawingContext &context, const wxRect &rect)
AUDACITY_DLL_API void DrawBackgroundWithSelection(TrackPanelDrawingContext &context, const wxRect &rect, const Channel &channel, const wxBrush &selBrush, const wxBrush &unselBrush, bool useSelection=true)
WAVE_TRACK_API Envelope * GetEnvelopeAtTime(WaveChannel &channel, double time)
constexpr auto sampleRate
AuthorizationHandler handler
const char * end(const char *str) noexcept
const char * begin(const char *str) noexcept
static wxRect GetClipRect(const ClipTimes &clip, const ZoomInfo &zoomInfo, const wxRect &viewRect, bool *outShowSamples=nullptr)
int GetColorIndex() const
static WaveColorAttachment & Get(WaveClip &clip)