Audacity 3.2.0
TimeTrackView.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3Audacity: A Digital Audio Editor
4
5TimeTrackView.cpp
6
7Paul Licameli split from TrackPanel.cpp
8
9**********************************************************************/
10
11#include "TimeTrackView.h"
12#include "TimeTrack.h"
13
14#include "TimeTrackControls.h"
15
17#include "AColor.h"
18#include "AllThemeResources.h"
19#include "Envelope.h"
20#include "../../../EnvelopeEditor.h"
21#include "../../../HitTestResult.h"
22#include "PendingTracks.h"
23#include "Theme.h"
24#include "../../../TrackArtist.h"
25#include "../../../TrackPanelDrawingContext.h"
26#include "../../../TrackPanelMouseEvent.h"
27#include "ViewInfo.h"
28#include "../../../widgets/Ruler.h"
29#include "../../../widgets/LinearUpdater.h"
30#include "../../../widgets/TimeFormat.h"
31
32#include "../../ui/EnvelopeHandle.h"
33
34#include <wx/dc.h>
35
37
38TimeTrackView::TimeTrackView(const std::shared_ptr<Channel> &pChannel)
39 : CommonChannelView{ pChannel }
40{
41}
42
44{
45}
46
47std::vector<UIHandlePtr> TimeTrackView::DetailedHitTest
48(const TrackPanelMouseState &st,
49 const AudacityProject *pProject, int, bool)
50{
51 std::vector<UIHandlePtr> results;
53 mEnvelopeHandle, st.state, st.rect, pProject,
54 FindChannel<TimeTrack>());
55 if (result)
56 results.push_back(result);
57 return results;
58}
59
62 return [](TimeTrack &track, size_t) {
63 return std::make_shared<TimeTrackView>(track.SharedPointer<TimeTrack>());
64 };
65}
66
67std::shared_ptr<ChannelVRulerControls> TimeTrackView::DoGetVRulerControls()
68{
69 return
70 std::make_shared<TimeTrackVRulerControls>(shared_from_this());
71}
72
73namespace {
75( TrackPanelDrawingContext &context, const wxRect & r,
76 const TimeTrack &track, Ruler &ruler )
77{
78 auto &dc = context.dc;
79 const auto artist = TrackArtist::Get( context );
80 const auto &zoomInfo = *artist->pZoomInfo;
81
82 bool highlight = false;
83#ifdef EXPERIMENTAL_TRACK_PANEL_HIGHLIGHTING
84 auto target = dynamic_cast<EnvelopeHandle*>(context.target.get());
85 highlight = target && target->GetEnvelope() == track.GetEnvelope();
86#endif
87
88 double min = zoomInfo.PositionToTime(0);
89 double max = zoomInfo.PositionToTime(r.width);
90 if (min > max)
91 {
92 wxASSERT(false);
93 min = max;
94 }
95
96 AColor::UseThemeColour( &dc, clrUnselected );
97 dc.DrawRectangle(r);
98
99 //copy this rectangle away for future use.
100 wxRect mid = r;
101
102 // Draw the Ruler
103 ruler.SetBounds(r.x, r.y, r.x + r.width - 1, r.y + r.height - 1);
104 ruler.SetRange(min, max);
105 ruler.SetFlip(true); // tick marks at top of track.
106 ruler.Invalidate(); // otherwise does not redraw.
107 ruler.SetTickColour( theTheme.Colour( clrTrackPanelText ));
108 ruler.Draw(dc, track.GetEnvelope());
109
110 Doubles envValues{ size_t(mid.width) };
112 0, 0, envValues.get(), mid.width, 0, zoomInfo);
113
114 wxPen &pen = highlight ? AColor::uglyPen : AColor::envelopePen;
115 dc.SetPen( pen );
116
117 auto rangeLower = track.GetRangeLower(), rangeUpper = track.GetRangeUpper();
118 double logLower = log(std::max(1.0e-7, rangeLower)),
119 logUpper = log(std::max(1.0e-7, rangeUpper));
120
121 for (int x = 0; x < mid.width; x++)
122 {
123 double y;
124 if ( track.GetDisplayLog() )
125 y = (double)mid.height * (logUpper - log(envValues[x])) / (logUpper - logLower);
126 else
127 y = (double)mid.height * (rangeUpper - envValues[x]) / (rangeUpper - rangeLower);
128 int thisy = r.y + (int)y;
129 AColor::Line(dc, mid.x + x, thisy - 1, mid.x + x, thisy+2);
130 }
131}
132
134 const TimeTrack &track, Ruler &ruler,
135 const wxRect & rect)
136{
137 // Ruler and curve...
138 DrawHorzRulerAndCurve( context, rect, track, ruler );
139
140 // ... then the control points
141 wxRect envRect = rect;
142 envRect.height -= 2;
143 double lower = track.GetRangeLower(), upper = track.GetRangeUpper();
144 const auto artist = TrackArtist::Get( context );
145 const auto dbRange = artist->mdBrange;
146 if(track.GetDisplayLog()) {
147 // MB: silly way to undo the work of GetWaveYPos while still getting a logarithmic scale
148 lower = LINEAR_TO_DB(std::max(1.0e-7, lower)) / dbRange + 1.0;
149 upper = LINEAR_TO_DB(std::max(1.0e-7, upper)) / dbRange + 1.0;
150 }
152 context, envRect,
153 track.GetDisplayLog(), dbRange, lower, upper, false );
154}
155}
156
159 const wxRect &rect, unsigned iPass )
160{
161 if ( iPass == TrackArtist::PassTracks ) {
162 const auto artist = TrackArtist::Get(context);
163 const auto &pendingTracks = *artist->pPendingTracks;
164 const auto pChannel = FindChannel();
165 if (!pChannel)
166 return;
167 const auto pList =
168 static_cast<const TimeTrack*>(pChannel.get())->GetOwner();
169 if (!pList)
170 // Track isn't owned by a list. Can't proceed!
171 return;
172 const auto pProject = pList->GetOwner();
173 if (!pProject)
174 // List isn't owned by a project. Can't proceed!
175 // But this shouldn't happen when drawing it
176 return;
177
178 auto &zoomInfo = ViewInfo::Get(*pProject);
180 updater.SetData(&zoomInfo);
181
182 // Just using a stack-local Ruler object. Observe the "Invalidate"
183 // call above which has long been done with every redraw.
184 // Avoiding invalidation with every draw, and making the ruler persistent
185 // between drawings, would require that it be invalidated whenever the
186 // user drags points, or the time selection changes -- really too much
187 // work.
189 ruler.SetLabelEdges(false);
190
191 const auto &tt = static_cast<const TimeTrack&>(
192 pendingTracks.SubstitutePendingChangedChannel(*pChannel));
193 DrawTimeTrack(context, tt, ruler, rect);
194 }
195 CommonChannelView::Draw(context, rect, iPass);
196}
int min(int a, int b)
#define LINEAR_TO_DB(x)
Definition: MemoryX.h:339
THEME_API Theme theTheme
Definition: Theme.cpp:82
DEFINE_ATTACHED_VIRTUAL_OVERRIDE(DoGetTimeTrackView)
static CustomUpdaterValue updater
static void Line(wxDC &dc, wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
Definition: AColor.cpp:194
static wxPen uglyPen
Definition: AColor.h:140
static wxPen envelopePen
Definition: AColor.h:116
static void UseThemeColour(wxDC *dc, int iBrush, int iPen=-1, int alpha=255)
Definition: AColor.cpp:354
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
auto FindChannel() -> std::shared_ptr< Subtype >
May return null.
Implements some hit-testing shared by many ChannelView subtypes.
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.
void SetData(RulerUpdater::Labels majorLabels, RulerUpdater::Labels minorLabels, RulerUpdater::Labels minorMinorLabels)
Definition: CustomUpdater.h:27
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 TimeTrackHitTest(std::weak_ptr< EnvelopeHandle > &holder, const wxMouseState &state, const wxRect &rect, const AudacityProject *pProject, const std::shared_ptr< TimeTrack > &tt)
Envelope * GetEnvelope() const
Used to display a Ruler.
Definition: Ruler.h:34
void SetTickColour(const wxColour &colour)
Definition: Ruler.h:135
void SetFlip(bool flip)
Definition: Ruler.cpp:192
void Draw(wxDC &dc) const
Definition: Ruler.cpp:441
void SetLabelEdges(bool labelEdges)
Definition: Ruler.cpp:179
void SetBounds(int left, int top, int right, int bottom)
Definition: Ruler.cpp:304
void SetRange(double min, double max)
Definition: Ruler.cpp:152
void Invalidate()
Definition: Ruler.cpp:317
wxColour & Colour(int iIndex)
static const TimeFormat & Instance()
Definition: TimeFormat.cpp:15
A kind of Track used to 'warp time'.
Definition: TimeTrack.h:24
BoundedEnvelope * GetEnvelope()
Definition: TimeTrack.h:84
bool GetDisplayLog() const
Definition: TimeTrack.h:95
double GetRangeLower() const
Definition: TimeTrack.cpp:100
double GetRangeUpper() const
Definition: TimeTrack.cpp:105
~TimeTrackView() override
std::weak_ptr< EnvelopeHandle > mEnvelopeHandle
Definition: TimeTrackView.h:36
std::vector< UIHandlePtr > DetailedHitTest(const TrackPanelMouseState &state, const AudacityProject *pProject, int currentTool, bool bMultiTool) override
void Draw(TrackPanelDrawingContext &context, const wxRect &rect, unsigned iPass) override
std::shared_ptr< ChannelVRulerControls > DoGetVRulerControls() override
TimeTrackView(const TimeTrackView &)=delete
static TrackArtist * Get(TrackPanelDrawingContext &)
Definition: TrackArtist.cpp:81
std::shared_ptr< TrackList > GetOwner() const
Definition: Track.h:230
std::shared_ptr< Subclass > SharedPointer()
Definition: Track.h:146
virtual void Draw(TrackPanelDrawingContext &context, const wxRect &rect, unsigned iPass)
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:235
void DrawTimeTrack(TrackPanelDrawingContext &context, const TimeTrack &track, Ruler &ruler, const wxRect &rect)
void DrawHorzRulerAndCurve(TrackPanelDrawingContext &context, const wxRect &r, const TimeTrack &track, Ruler &ruler)
For defining overrides of the method.