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 WaveChannelVRulerControls.cpp
8
9**********************************************************************/
10
12
13#include "SpectrumVZoomHandle.h"
15
16#include "../../../ui/ChannelView.h"
17#include "NumberScale.h"
18#include "ProjectHistory.h"
19#include "../../../../RefreshCode.h"
20#include "../../../../TrackPanelMouseEvent.h"
21#include "WaveTrack.h"
22#include "../../../../prefs/SpectrogramSettings.h"
23#include "../../../../widgets/Ruler.h"
24#include "../../../../widgets/LinearUpdater.h"
25#include "../../../../widgets/LogarithmicUpdater.h"
26#include "../../../../widgets/IntFormat.h"
27#include "../../../../widgets/RealFormat.h"
28
30
31std::vector<UIHandlePtr> SpectrumVRulerControls::HitTest(
32 const TrackPanelMouseState &st,
33 const AudacityProject *pProject)
34{
35 std::vector<UIHandlePtr> results;
36
37 if ( st.state.GetX() <= st.rect.GetRight() - kGuard ) {
38 if (const auto pChannel = FindWaveChannel()) {
39 auto result = std::make_shared<SpectrumVZoomHandle>(
40 pChannel, st.rect, st.state.m_y);
41 result = AssignUIHandlePtr(mVZoomHandle, result);
42 results.push_back(result);
43 }
44 }
45
46 auto more = ChannelVRulerControls::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 pChannel = FindWaveChannel();
57 if (!pChannel)
58 return RefreshNone;
59 return DoHandleWheelRotation(evt, pProject, *pChannel);
60}
61
62std::shared_ptr<WaveChannel> SpectrumVRulerControls::FindWaveChannel()
63{
64 return FindChannel<WaveChannel>();
65}
66
68 const TrackPanelMouseEvent &evt, AudacityProject *pProject, WaveChannel &wc)
69{
70 using namespace RefreshCode;
71 const wxMouseEvent &event = evt.event;
72
73 if (!(event.ShiftDown() || event.CmdDown()))
74 return RefreshNone;
75
76 // Always stop propagation even if the ruler didn't change. The ruler
77 // is a narrow enough target.
78 evt.event.Skip(false);
79
80 auto steps = evt.steps;
81
82 using namespace WaveChannelViewConstants;
83 if (event.CmdDown() && !event.ShiftDown()) {
84 const int yy = event.m_y;
86 pProject, wc,
87 (steps < 0)
88 ? kZoomOut
89 : kZoomIn,
90 evt.rect, yy, yy, true);
91 }
92 else if (!event.CmdDown() && event.ShiftDown()) {
93 // Scroll some fixed number of pixels, independent of zoom level or track height:
94 static const float movement = 10.0f;
95 const int height = evt.rect.GetHeight();
96 {
97 const float delta = steps * movement / height;
99 const bool isLinear = settings.scaleType == SpectrogramSettings::stLinear;
100 float bottom, top;
101 SpectrogramBounds::Get(wc).GetBounds(wc, bottom, top);
102 const double rate = wc.GetRate();
103 const float bound = rate / 2;
104 const NumberScale numberScale(settings.GetScale(bottom, top));
105 float newTop =
106 std::min(bound, numberScale.PositionToValue(1.0f + delta));
107 const float newBottom =
108 std::max((isLinear ? 0.0f : 1.0f),
109 numberScale.PositionToValue(numberScale.ValueToPosition(newTop) - 1.0f));
110 newTop =
111 std::min(bound,
112 numberScale.PositionToValue(numberScale.ValueToPosition(newBottom) + 1.0f));
113
114 SpectrogramBounds::Get(wc).SetBounds(newBottom, newTop);
115 }
116 }
117 else
118 return RefreshNone;
119
120 ProjectHistory::Get( *pProject ).ModifyState(true);
121
122 return RefreshCell | UpdateVRuler;
123}
124
127 const wxRect &rect_, unsigned iPass )
128{
129 ChannelVRulerControls::Draw(context, rect_, iPass);
130 WaveChannelVRulerControls::DoDraw(*this, context, rect_, iPass);
131}
132
134{
135 const auto pChannel = FindWaveChannel();
136 if (!pChannel)
137 return;
138 DoUpdateVRuler(rect, *pChannel);
139}
140
142 const wxRect &rect, const WaveChannel &wc)
143{
145 const auto &settings = SpectrogramSettings::Get(wc);
146 float minFreq, maxFreq;
147 SpectrogramBounds::Get(wc).GetBounds(wc, minFreq, maxFreq);
148 vruler->SetDbMirrorValue(0.0);
149
150 switch (settings.scaleType) {
151 default:
152 wxASSERT(false);
154 {
155 // Spectrum
156
157 /*
158 draw the ruler
159 we will use Hz if maxFreq is < 2000, otherwise we represent kHz,
160 and append to the numbers a "k"
161 */
162 vruler->SetBounds(
163 rect.x, rect.y, rect.x + rect.width, rect.y + rect.height - 1);
164 vruler->SetOrientation(wxVERTICAL);
165 vruler->SetFormat(&RealFormat::LinearInstance());
166 vruler->SetLabelEdges(true);
167 // use kHz in scale, if appropriate
168 if (maxFreq >= 2000) {
169 vruler->SetRange((maxFreq / 1000.), (minFreq / 1000.));
170 /* i18n-hint k abbreviating kilo meaning thousands */
171 vruler->SetUnits(XO("k"));
172 }
173 else {
174 // use Hz
175 vruler->SetRange((int)(maxFreq), (int)(minFreq));
176 vruler->SetUnits({});
177 }
178 vruler->SetUpdater(&LinearUpdater::Instance());
179 }
180 break;
186 {
187 // SpectrumLog
188
189 /*
190 draw the ruler
191 we will use Hz if maxFreq is < 2000, otherwise we represent kHz,
192 and append to the numbers a "k"
193 */
194 vruler->SetBounds(
195 rect.x, rect.y, rect.x + rect.width, rect.y + rect.height - 1);
196 vruler->SetOrientation(wxVERTICAL);
197 vruler->SetFormat(&IntFormat::Instance());
198 vruler->SetLabelEdges(true);
199 vruler->SetRange(maxFreq, minFreq);
200 vruler->SetUnits({});
201 vruler->SetUpdater(&LogarithmicUpdater::Instance());
202 NumberScale scale(settings.GetScale(minFreq, maxFreq).Reversal());
203 vruler->SetNumberScale(scale);
204 }
205 break;
206 }
207 auto &size = ChannelView::Get(wc).vrulerSize;
208 vruler->GetMaxSize(&size.first, &size.second);
209}
const int kGuard
int min(int a, int b)
XO("Cut/Copy/Paste")
static Settings & settings()
Definition: TrackInfo.cpp:69
std::shared_ptr< Subclass > AssignUIHandlePtr(std::weak_ptr< Subclass > &holder, const std::shared_ptr< Subclass > &pNew)
Definition: UIHandle.h:164
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::vector< UIHandlePtr > HitTest(const TrackPanelMouseState &state, const AudacityProject *pProject) override
void Draw(TrackPanelDrawingContext &context, const wxRect &rect, unsigned iPass) override
static ChannelView & Get(Channel &channel)
std::pair< int, int > vrulerSize
Definition: ChannelView.h:129
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 SetBounds(float min, float max)
void GetBounds(const WaveChannel &wc, float &min, float &max) const
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)
static SpectrogramSettings & Own(WaveChannel &wc)
std::weak_ptr< SpectrumVZoomHandle > mVZoomHandle
static unsigned DoHandleWheelRotation(const TrackPanelMouseEvent &evt, AudacityProject *pProject, WaveChannel &wc)
std::shared_ptr< WaveChannel > FindWaveChannel()
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 DoUpdateVRuler(const wxRect &rect, const WaveChannel &wc)
static void DoZoom(AudacityProject *pProject, WaveChannel &wc, WaveChannelViewConstants::ZoomActions ZoomKind, const wxRect &rect, int zoomStart, int zoomEnd, bool fixedMousePoint)
double GetRate() const override
Definition: WaveTrack.cpp:793
Namespace containing an enum 'what to do on a refresh?'.
Definition: RefreshCode.h:16
AUDACITY_DLL_API Ruler & ScratchRuler()
AUDACITY_DLL_API void DoDraw(ChannelVRulerControls &controls, TrackPanelDrawingContext &context, const wxRect &rect, unsigned iPass)
void copy(const T *src, T *dst, int32_t n)
Definition: VectorOps.h:40