Audacity 3.2.0
SpectrumVRulerControls.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3Audacity: A Digital Audio Editor
4
5SpectrumVRulerControls.cpp
6
7Paul Licameli split from WaveTrackVRulerControls.cpp
8
9**********************************************************************/
10
12
13#include "SpectrumVZoomHandle.h"
15
16#include "NumberScale.h"
17#include "ProjectHistory.h"
18#include "../../../../RefreshCode.h"
19#include "../../../../TrackPanelMouseEvent.h"
20#include "WaveTrack.h"
21#include "../../../../prefs/SpectrogramSettings.h"
22#include "../../../../widgets/Ruler.h"
23#include "../../../../widgets/LinearUpdater.h"
24#include "../../../../widgets/LogarithmicUpdater.h"
25#include "../../../../widgets/IntFormat.h"
26#include "../../../../widgets/RealFormat.h"
27
29
30std::vector<UIHandlePtr> SpectrumVRulerControls::HitTest(
31 const TrackPanelMouseState &st,
32 const AudacityProject *pProject)
33{
34 std::vector<UIHandlePtr> results;
35
36 if ( st.state.GetX() <= st.rect.GetRight() - kGuard ) {
37 auto pTrack = FindTrack()->SharedPointer<WaveTrack>( );
38 if (pTrack) {
39 auto result = std::make_shared<SpectrumVZoomHandle>(
40 pTrack, st.rect, st.state.m_y );
41 result = AssignUIHandlePtr(mVZoomHandle, result);
42 results.push_back(result);
43 }
44 }
45
46 auto more = TrackVRulerControls::HitTest(st, pProject);
47 std::copy(more.begin(), more.end(), std::back_inserter(results));
48
49 return results;
50}
51
53 const TrackPanelMouseEvent &evt, AudacityProject *pProject)
54{
55 using namespace RefreshCode;
56 const auto pTrack = FindTrack();
57 if (!pTrack)
58 return RefreshNone;
59 const auto wt = static_cast<WaveTrack*>(pTrack.get());
60 return DoHandleWheelRotation( evt, pProject, wt );
61}
62
64 const TrackPanelMouseEvent &evt, AudacityProject *pProject, WaveTrack *wt)
65{
66 using namespace RefreshCode;
67 const wxMouseEvent &event = evt.event;
68
69 if (!(event.ShiftDown() || event.CmdDown()))
70 return RefreshNone;
71
72 // Always stop propagation even if the ruler didn't change. The ruler
73 // is a narrow enough target.
74 evt.event.Skip(false);
75
76 auto steps = evt.steps;
77
78 using namespace WaveTrackViewConstants;
79 if (event.CmdDown() && !event.ShiftDown()) {
80 const int yy = event.m_y;
82 pProject, wt,
83 (steps < 0)
84 ? kZoomOut
85 : kZoomIn,
86 evt.rect, yy, yy, true);
87 }
88 else if (!event.CmdDown() && event.ShiftDown()) {
89 // Scroll some fixed number of pixels, independent of zoom level or track height:
90 static const float movement = 10.0f;
91 const int height = evt.rect.GetHeight();
92 {
93 const float delta = steps * movement / height;
95 const bool isLinear = settings.scaleType == SpectrogramSettings::stLinear;
96 float bottom, top;
97 SpectrogramBounds::Get(*wt).GetBounds(*wt, bottom, top);
98 const double rate = wt->GetRate();
99 const float bound = rate / 2;
100 const NumberScale numberScale(settings.GetScale(bottom, top));
101 float newTop =
102 std::min(bound, numberScale.PositionToValue(1.0f + delta));
103 const float newBottom =
104 std::max((isLinear ? 0.0f : 1.0f),
105 numberScale.PositionToValue(numberScale.ValueToPosition(newTop) - 1.0f));
106 newTop =
107 std::min(bound,
108 numberScale.PositionToValue(numberScale.ValueToPosition(newBottom) + 1.0f));
109
110 for (auto channel : TrackList::Channels(wt))
111 SpectrogramBounds::Get(*channel)
112 .SetBounds(newBottom, newTop);
113 }
114 }
115 else
116 return RefreshNone;
117
118 ProjectHistory::Get( *pProject ).ModifyState(true);
119
120 return RefreshCell | UpdateVRuler;
121}
122
125 const wxRect &rect_, unsigned iPass )
126{
127 TrackVRulerControls::Draw( context, rect_, iPass );
128 WaveTrackVRulerControls::DoDraw( *this, context, rect_, iPass );
129}
130
131void SpectrumVRulerControls::UpdateRuler( const wxRect &rect )
132{
133 const auto wt = std::static_pointer_cast< WaveTrack >( FindTrack() );
134 if (!wt)
135 return;
136 DoUpdateVRuler( rect, wt.get() );
137}
138
140 const wxRect &rect, const WaveTrack *wt )
141{
143 const auto &settings = SpectrogramSettings::Get(*wt);
144 float minFreq, maxFreq;
145 SpectrogramBounds::Get(*wt).GetBounds(*wt, minFreq, maxFreq);
146 vruler->SetDbMirrorValue( 0.0 );
147
148 switch (settings.scaleType) {
149 default:
150 wxASSERT(false);
152 {
153 // Spectrum
154
155 /*
156 draw the ruler
157 we will use Hz if maxFreq is < 2000, otherwise we represent kHz,
158 and append to the numbers a "k"
159 */
160 vruler->SetBounds(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height - 1);
161 vruler->SetOrientation(wxVERTICAL);
162 vruler->SetFormat(&RealFormat::LinearInstance());
163 vruler->SetLabelEdges(true);
164 // use kHz in scale, if appropriate
165 if (maxFreq >= 2000) {
166 vruler->SetRange((maxFreq / 1000.), (minFreq / 1000.));
167 /* i18n-hint k abbreviating kilo meaning thousands */
168 vruler->SetUnits(XO("k"));
169 }
170 else {
171 // use Hz
172 vruler->SetRange((int)(maxFreq), (int)(minFreq));
173 vruler->SetUnits({});
174 }
175 vruler->SetUpdater(&LinearUpdater::Instance());
176 }
177 break;
183 {
184 // SpectrumLog
185
186 /*
187 draw the ruler
188 we will use Hz if maxFreq is < 2000, otherwise we represent kHz,
189 and append to the numbers a "k"
190 */
191 vruler->SetBounds(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height - 1);
192 vruler->SetOrientation(wxVERTICAL);
193 vruler->SetFormat(&IntFormat::Instance());
194 vruler->SetLabelEdges(true);
195 vruler->SetRange(maxFreq, minFreq);
196 vruler->SetUnits({});
197 vruler->SetUpdater(&LogarithmicUpdater::Instance());
198 NumberScale scale(settings.GetScale(minFreq, maxFreq).Reversal());
199 vruler->SetNumberScale(scale);
200 }
201 break;
202 }
203 vruler->GetMaxSize( &wt->vrulerSize.first, &wt->vrulerSize.second );
204}
int min(int a, int b)
XO("Cut/Copy/Paste")
static Settings & settings()
Definition: TrackInfo.cpp:87
const int kGuard
std::shared_ptr< Subclass > AssignUIHandlePtr(std::weak_ptr< Subclass > &holder, const std::shared_ptr< Subclass > &pNew)
Definition: UIHandle.h:151
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
std::shared_ptr< Track > FindTrack()
static const IntFormat & Instance()
Definition: IntFormat.cpp:14
static const LinearUpdater & Instance()
static const LogarithmicUpdater & Instance()
float PositionToValue(float pp) const
Definition: NumberScale.h:155
float ValueToPosition(float val) const
Definition: NumberScale.h:256
void ModifyState(bool bWantsAutoSave)
static ProjectHistory & Get(AudacityProject &project)
static const RealFormat & LinearInstance()
Definition: RealFormat.cpp:14
void GetBounds(const WaveTrack &wt, float &min, float &max) const
void SetBounds(float min, float max)
static SpectrogramBounds & Get(WaveTrack &track)
Get either the global default settings, or the track's own if previously created.
Spectrogram settings, either for one track or as defaults.
static SpectrogramSettings & Get(const WaveTrack &track)
Mutative access to attachment even if the track argument is const.
static SpectrogramSettings & Own(WaveTrack &track)
static void DoUpdateVRuler(const wxRect &rect, const WaveTrack *wt)
std::weak_ptr< SpectrumVZoomHandle > mVZoomHandle
static unsigned DoHandleWheelRotation(const TrackPanelMouseEvent &evt, AudacityProject *pProject, WaveTrack *wt)
unsigned HandleWheelRotation(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
void UpdateRuler(const wxRect &rect) override
~SpectrumVRulerControls() override
std::vector< UIHandlePtr > HitTest(const TrackPanelMouseState &state, const AudacityProject *) override
void Draw(TrackPanelDrawingContext &context, const wxRect &rect, unsigned iPass) override
static void DoZoom(AudacityProject *pProject, WaveTrack *pTrack, WaveTrackViewConstants::ZoomActions ZoomKind, const wxRect &rect, int zoomStart, int zoomEnd, bool fixedMousePoint)
std::pair< int, int > vrulerSize
Definition: Track.h:387
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1544
void Draw(TrackPanelDrawingContext &context, const wxRect &rect, unsigned iPass) override
std::vector< UIHandlePtr > HitTest(const TrackPanelMouseState &state, const AudacityProject *pProject) override
A Track that contains audio waveform data.
Definition: WaveTrack.h:51
double GetRate() const override
Definition: WaveTrack.cpp:360
Namespace containing an enum 'what to do on a refresh?'.
Definition: RefreshCode.h:16
AUDACITY_DLL_API Ruler & ScratchRuler()
AUDACITY_DLL_API void DoDraw(TrackVRulerControls &controls, TrackPanelDrawingContext &context, const wxRect &rect, unsigned iPass)