18#include "../../../../HitTestResult.h"
22#include "../../../../RefreshCode.h"
23#include "../../../../TrackArt.h"
24#include "../../../../TrackArtist.h"
25#include "../../../../TrackPanelMouseEvent.h"
31#include "../../../../../images/Cursors.h"
42 : mClickedTrack{ pTrack }
48#ifdef EXPERIMENTAL_TRACK_PANEL_HIGHLIGHTING
54(
const wxMouseState &state,
const AudacityProject *WXUNUSED(pProject),
bool unsafe)
56 static auto disabledCursor =
57 ::MakeCursor(wxCURSOR_NO_ENTRY, DisabledCursorXpm, 16, 16);
58 static wxCursor smoothCursor{ wxCURSOR_SPRAYCAN };
59 static auto pencilCursor =
64 auto message =
XO(
"Click and drag to edit the samples");
77 const wxMouseState &,
const std::shared_ptr<WaveChannel> &pChannel)
79 auto result = std::make_shared<SampleHandle>(pChannel);
91 const auto sampleOffset =
92 clip->TimeToSamples(time - clip->GetPlayStartTime());
93 return clip->SamplesToTime(sampleOffset) + clip->GetPlayStartTime();
103 const auto xx = std::max<ZoomInfo::int64>(
106 ZoomInfo::Intervals::const_iterator it = intervals.begin(),
107 end = intervals.end(), prev;
108 wxASSERT(it !=
end && it->position == 0);
111 while (it !=
end && it->position <= xx);
112 const double threshold = 3 * rate;
114 return prev->averageZoom > threshold;
119 const wxMouseState &state,
const wxRect &rect,
120 const AudacityProject *pProject,
const std::shared_ptr<WaveChannel> &pChannel)
129 auto &waveChannel = *pChannel;
130 const auto time = viewInfo.PositionToTime(state.m_x, rect.x);
131 const auto clickedClip =
136 const double tt =
adjustTime(waveChannel, time);
137 const auto intervals = viewInfo.FindIntervals(rect.width);
143 constexpr auto mayThrow =
false;
145 tt, oneSample, mayThrow))
150 float zoomMin, zoomMax;
151 cache.GetDisplayBounds(zoomMin, zoomMax);
153 double envValue = 1.0;
157 envValue = env->GetValue(tt);
160 const bool dB = !
settings.isLinear();
163 rect.height, dB,
true,
167 int yMouse = state.m_y;
170 const int yTolerance = 10;
171 if (abs(yValue - yMouse) >= yTolerance)
195 const wxMouseEvent &
event = evt.
event;
196 const wxRect &rect = evt.
rect;
199 const double t0 = viewInfo.PositionToTime(event.m_x, rect.x);
205 const auto intervals = viewInfo.FindIntervals(rect.width);
210 XO(
"To use Draw, zoom in further until you can see the individual samples."),
240 Floats sampleRegion{ sampleRegionSize };
244 constexpr auto mayThrow =
false;
246 t0, sampleRegion.get(),
251 float sumOfSamples = 0;
254 const auto sampleRegionIndex =
256 const auto inRange = sampleRegionRange.first <= sampleRegionIndex &&
257 sampleRegionIndex < sampleRegionRange.second;
269 sampleRegion[sampleRegionIndex];
335 assert(n < sortedClips.size());
336 const auto increment =
forward ? 1 : -1;
337 int last = n + increment;
338 const auto limit =
forward ? sortedClips.size() : -1;
339 while (last != limit)
346 assert(last >= 0 && last < sortedClips.size());
356 const wxMouseEvent &
event = evt.
event;
381 const double t1 = viewInfo.PositionToTime(event.m_x,
mRect.x);
386 const auto start =
std::min(t0, t1);
387 const auto end = std::max(t0, t1);
395 const auto iter = std::find_if(clips.begin(), clips.end(),
397 [
this](
const auto &pClip){ return *pClip == *mClickedClip; });
398 const auto clickedClipIndex = std::distance(clips.begin(), iter);
400 const auto intervals = viewInfo.FindIntervals(
mRect.width);
402 clickedClipIndex, !
forward, clips, viewInfo, intervals);
404 clickedClipIndex,
forward, clips, viewInfo, intervals);
406 const auto editStart =
407 std::max(start, clips[leftmostEditable]->GetPlayStartTime());
409 std::min(
end, clips[rightmostEditable]->GetPlayEndTime());
414 v1 = newLevel](
double t) {
417 const auto gradient = (v1 - v0) / (t1 - t0);
418 const auto value =
static_cast<float>(gradient * (t - t0) + v0);
420 return std::clamp(value,
std::min(v0, v1), std::max(v0, v1));
444 return this->
Cancel(pProject);
468 (
const wxMouseEvent &event,
const ViewInfo &viewInfo,
double t0)
472 float zoomMin, zoomMax;
474 cache.GetDisplayBounds(zoomMin, zoomMax);
476 const int yy =
event.m_y -
mRect.y;
477 const int height =
mRect.GetHeight();
479 const bool dB = !
settings.isLinear();
482 settings.dBRange, zoomMin, zoomMax);
488 double envValue = env->GetValue(t0);
490 newLevel /= envValue;
495 newLevel = std::max(-1.0f,
std::min(1.0f, newLevel));
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
std::shared_ptr< UIHandle > UIHandlePtr
static const int SMOOTHING_BRUSH_RADIUS
static const double SMOOTHING_PROPORTION_MAX
static const int SMOOTHING_KERNEL_RADIUS
static const double SMOOTHING_PROPORTION_MIN
int GetWaveYPos(float value, float min, float max, int height, bool dB, bool outer, float dBr, bool clip)
float ValueOfPixel(int yy, int height, bool offset, bool dB, double dBRange, float zoomMin, float zoomMax)
static Settings & settings()
std::unique_ptr< wxCursor > MakeCursor(int WXUNUSED(CursorId), const char *const pXpm[36], int HotX, int HotY)
std::shared_ptr< Subclass > AssignUIHandlePtr(std::weak_ptr< Subclass > &holder, const std::shared_ptr< Subclass > &pNew)
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
bool IsAudioActive() const
static ProjectAudioIO & Get(AudacityProject &project)
void PushState(const TranslatableString &desc, const TranslatableString &shortDesc)
static ProjectHistory & Get(AudacityProject &project)
std::shared_ptr< WaveClipChannel > mClickedClip
Result Release(const TrackPanelMouseEvent &event, AudacityProject *pProject, wxWindow *pParent) override
float FindSampleEditingLevel(const wxMouseEvent &event, const ViewInfo &viewInfo, double t0)
float mLastDragSampleValue
std::shared_ptr< WaveChannel > mClickedTrack
Result Cancel(AudacityProject *pProject) override
static HitTestPreview HitPreview(const wxMouseState &state, const AudacityProject *pProject, bool unsafe)
static UIHandlePtr HitAnywhere(std::weak_ptr< SampleHandle > &holder, const wxMouseState &state, const std::shared_ptr< WaveChannel > &pChannel)
void Enter(bool forward, AudacityProject *) override
Result Click(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
std::shared_ptr< const Track > FindTrack() const override
HitTestPreview Preview(const TrackPanelMouseState &state, AudacityProject *pProject) override
Result Drag(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
static UIHandlePtr HitTest(std::weak_ptr< SampleHandle > &holder, const wxMouseState &state, const wxRect &rect, const AudacityProject *pProject, const std::shared_ptr< WaveChannel > &pChannel)
SampleHandle(const SampleHandle &)=delete
static std::shared_ptr< const Track > TrackFromChannel(const std::shared_ptr< const Channel > &pChannel)
A frequent convenience in the definition of UIHandles.
static ViewInfo & Get(AudacityProject &project)
int GetRate() const override
double GetPlayStartTime() const override
double GetStretchRatio() const override
double SnapToSample(double t) const
double PositionToTime(int64 position, int64 origin=0, bool ignoreFisheye=false) const
std::vector< Interval > Intervals
int64 TimeToPosition(double time, int64 origin=0, bool ignoreFisheye=false) const
STM: Converts a project time to screen x position.
Namespace containing an enum 'what to do on a refresh?'.
WAVE_TRACK_API void SetFloatsCenteredAroundTime(WaveChannel &channel, double t, const float *buffer, size_t numSideSamples, sampleFormat effectiveFormat)
Similar to GetFloatsCenteredAroundTime, but for writing. Sets as many samples as it can according to ...
std::vector< ClipPointer > ClipPointers
WAVE_TRACK_API void SetFloatsWithinTimeRange(WaveChannel &channel, double t0, double t1, const std::function< float(double sampleTime)> &producer, sampleFormat effectiveFormat)
Provides a means of setting clip values as a function of time. Included are closest sample to t0 up t...
WAVE_TRACK_API std::pair< size_t, size_t > GetFloatsCenteredAroundTime(const WaveChannel &channel, double t, float *buffer, size_t numSideSamples, bool mayThrow)
Gets as many samples as it can, but no more than 2 * numSideSamples + 1, centered around t....
WAVE_TRACK_API ClipPointer GetClipAtTime(WaveChannel &channel, double time)
WAVE_TRACK_API bool GetFloatAtTime(const WaveChannel &channel, double t, float &value, bool mayThrow)
WAVE_TRACK_API Envelope * GetEnvelopeAtTime(WaveChannel &channel, double time)
WAVE_TRACK_API void SetFloatAtTime(WaveChannel &channel, double t, float value, sampleFormat effectiveFormat)
Sets sample nearest to t to value. Silently fails if GetClipAtTime(t) == nullptr.
WAVE_TRACK_API ClipPointers SortedClipArray(WaveChannel &channel)
Get clips sorted by play start time.
size_t GetLastEditableClipStartingFromNthClip(size_t n, bool forward, const WaveChannelUtilities::ClipPointers &sortedClips, const ViewInfo &viewInfo, const ZoomInfo::Intervals &intervals)
double adjustTime(const WaveChannel &wt, double time)
bool SampleResolutionTest(const ViewInfo &viewInfo, const WaveChannelInterval &clip, const ZoomInfo::Intervals &intervals)
const char * end(const char *str) noexcept