mirror of
https://github.com/cookiengineer/audacity
synced 2025-08-02 17:09:26 +02:00
Separate functions for vertical zooming of spectrum and waveform
This commit is contained in:
parent
fa7de8ce3a
commit
f7dc21436d
@ -125,7 +125,10 @@ unsigned WaveTrackVRulerControls::HandleWheelRotation
|
||||
}
|
||||
else if (event.CmdDown() && !event.ShiftDown()) {
|
||||
const int yy = event.m_y;
|
||||
WaveTrackVZoomHandle::DoZoom(
|
||||
auto doZoom = (wt->GetDisplay() == Spectrum)
|
||||
? WaveTrackVZoomHandle::DoSpectrumZoom
|
||||
: WaveTrackVZoomHandle::DoWaveformZoom;
|
||||
doZoom(
|
||||
pProject, wt,
|
||||
(steps < 0)
|
||||
? kZoomOut
|
||||
|
@ -39,6 +39,7 @@ public:
|
||||
wxRect rect;
|
||||
unsigned result;
|
||||
int yy;
|
||||
WaveTrackVZoomHandle::DoZoomFunction doZoom;
|
||||
};
|
||||
|
||||
bool IsDragZooming(int zoomStart, int zoomEnd)
|
||||
@ -67,12 +68,12 @@ void WaveTrackVZoomHandle::Enter(bool)
|
||||
// ZoomKind says how to zoom.
|
||||
// If ZoomStart and ZoomEnd are not equal, this may override
|
||||
// the zoomKind and cause a drag-zoom-in.
|
||||
void WaveTrackVZoomHandle::DoZoom
|
||||
(AudacityProject *pProject,
|
||||
WaveTrack *pTrack,
|
||||
WaveTrackViewConstants::ZoomActions inZoomKind,
|
||||
const wxRect &rect, int zoomStart, int zoomEnd,
|
||||
bool fixedMousePoint)
|
||||
void WaveTrackVZoomHandle::DoSpectrumZoom(
|
||||
AudacityProject *pProject,
|
||||
WaveTrack *pTrack,
|
||||
WaveTrackViewConstants::ZoomActions ZoomKind,
|
||||
const wxRect &rect, int zoomStart, int zoomEnd,
|
||||
bool fixedMousePoint)
|
||||
{
|
||||
using namespace WaveTrackViewConstants;
|
||||
static const float ZOOMLIMIT = 0.001f;
|
||||
@ -90,9 +91,7 @@ void WaveTrackVZoomHandle::DoZoom
|
||||
float maxFreq = 8000.0;
|
||||
const SpectrogramSettings &specSettings = pTrack->GetSpectrogramSettings();
|
||||
NumberScale scale;
|
||||
const bool spectral =
|
||||
(pTrack->GetDisplay() == Spectrum);
|
||||
const bool spectrumLinear = spectral &&
|
||||
const bool spectrumLinear =
|
||||
(pTrack->GetSpectrogramSettings().scaleType == SpectrogramSettings::stLinear);
|
||||
|
||||
|
||||
@ -102,15 +101,12 @@ void WaveTrackVZoomHandle::DoZoom
|
||||
|
||||
// Possibly override the zoom kind.
|
||||
if( bDragZoom )
|
||||
inZoomKind = kZoomInByDrag;
|
||||
|
||||
// If we are actually zooming a spectrum rather than a wave.
|
||||
int ZoomKind = (int)inZoomKind + (spectral ? kSpectral : 0);
|
||||
ZoomKind = kZoomInByDrag;
|
||||
|
||||
float top=2.0;
|
||||
float half=0.5;
|
||||
|
||||
if (spectral) {
|
||||
{
|
||||
pTrack->GetSpectrumBounds(&min, &max);
|
||||
scale = (specSettings.GetScale(min, max));
|
||||
const auto fftLength = specSettings.GetFFTLength();
|
||||
@ -123,7 +119,150 @@ void WaveTrackVZoomHandle::DoZoom
|
||||
const int minBins = 1;
|
||||
minBand = minBins * binSize;
|
||||
}
|
||||
else{
|
||||
|
||||
// Compute min and max.
|
||||
switch(ZoomKind)
|
||||
{
|
||||
default:
|
||||
// If we have covered all the cases, this won't happen.
|
||||
// In release builds Audacity will ignore the zoom.
|
||||
wxFAIL_MSG("Zooming Case not implemented by Audacity");
|
||||
break;
|
||||
|
||||
// VZooming on spectral we don't implement the other zoom presets.
|
||||
// They are also not in the menu.
|
||||
case kZoomReset:
|
||||
{
|
||||
// Zoom out to normal level.
|
||||
min = spectrumLinear ? 0.0f : 1.0f;
|
||||
max = maxFreq;
|
||||
}
|
||||
break;
|
||||
case kZoom1to1:
|
||||
case kZoomDiv2:
|
||||
case kZoomTimes2:
|
||||
case kZoomHalfWave:
|
||||
{
|
||||
// Zoom out full
|
||||
min = spectrumLinear ? 0.0f : 1.0f;
|
||||
max = halfrate;
|
||||
}
|
||||
break;
|
||||
case kZoomInByDrag:
|
||||
{
|
||||
double xmin = 1 - (zoomEnd - ypos) / (float)height;
|
||||
double xmax = 1 - (zoomStart - ypos) / (float)height;
|
||||
const float middle = (xmin + xmax) / 2;
|
||||
const float middleValue = scale.PositionToValue(middle);
|
||||
|
||||
min = std::max(spectrumLinear ? 0.0f : 1.0f,
|
||||
std::min(middleValue - minBand / 2,
|
||||
scale.PositionToValue(xmin)
|
||||
));
|
||||
max = std::min(halfrate,
|
||||
std::max(middleValue + minBand / 2,
|
||||
scale.PositionToValue(xmax)
|
||||
));
|
||||
}
|
||||
break;
|
||||
case kZoomIn:
|
||||
{
|
||||
// Center the zoom-in at the click
|
||||
const float p1 = (zoomStart - ypos) / (float)height;
|
||||
const float middle = 1.0f - p1;
|
||||
const float middleValue = scale.PositionToValue(middle);
|
||||
|
||||
if (fixedMousePoint) {
|
||||
min = std::max(spectrumLinear ? 0.0f : 1.0f,
|
||||
std::min(middleValue - minBand * middle,
|
||||
scale.PositionToValue(0.5f * middle)
|
||||
));
|
||||
max = std::min(halfrate,
|
||||
std::max(middleValue + minBand * p1,
|
||||
scale.PositionToValue(middle + 0.5f * p1)
|
||||
));
|
||||
}
|
||||
else {
|
||||
min = std::max(spectrumLinear ? 0.0f : 1.0f,
|
||||
std::min(middleValue - minBand / 2,
|
||||
scale.PositionToValue(middle - 0.25f)
|
||||
));
|
||||
max = std::min(halfrate,
|
||||
std::max(middleValue + minBand / 2,
|
||||
scale.PositionToValue(middle + 0.25f)
|
||||
));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kZoomOut:
|
||||
{
|
||||
// Zoom out
|
||||
const float p1 = (zoomStart - ypos) / (float)height;
|
||||
// (Used to zoom out centered at midline, ignoring the click, if linear view.
|
||||
// I think it is better to be consistent. PRL)
|
||||
// Center zoom-out at the midline
|
||||
const float middle = // spectrumLinear ? 0.5f :
|
||||
1.0f - p1;
|
||||
|
||||
if (fixedMousePoint) {
|
||||
min = std::max(spectrumLinear ? 0.0f : 1.0f, scale.PositionToValue(-middle));
|
||||
max = std::min(halfrate, scale.PositionToValue(1.0f + p1));
|
||||
}
|
||||
else {
|
||||
min = std::max(spectrumLinear ? 0.0f : 1.0f, scale.PositionToValue(middle - 1.0f));
|
||||
max = std::min(halfrate, scale.PositionToValue(middle + 1.0f));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Now actually apply the zoom.
|
||||
for (auto channel : TrackList::Channels(pTrack))
|
||||
channel->SetSpectrumBounds(min, max);
|
||||
|
||||
zoomEnd = zoomStart = 0;
|
||||
if( pProject )
|
||||
ProjectHistory::Get( *pProject ).ModifyState(true);
|
||||
}
|
||||
|
||||
// ZoomKind says how to zoom.
|
||||
// If ZoomStart and ZoomEnd are not equal, this may override
|
||||
// the zoomKind and cause a drag-zoom-in.
|
||||
void WaveTrackVZoomHandle::DoWaveformZoom(
|
||||
AudacityProject *pProject,
|
||||
WaveTrack *pTrack,
|
||||
WaveTrackViewConstants::ZoomActions ZoomKind,
|
||||
const wxRect &rect, int zoomStart, int zoomEnd,
|
||||
bool fixedMousePoint)
|
||||
{
|
||||
using namespace WaveTrackViewConstants;
|
||||
static const float ZOOMLIMIT = 0.001f;
|
||||
|
||||
int height = rect.height;
|
||||
int ypos = rect.y;
|
||||
|
||||
// Ensure start and end are in order (swap if not).
|
||||
if (zoomEnd < zoomStart)
|
||||
std::swap( zoomStart, zoomEnd );
|
||||
|
||||
float min, max, minBand = 0;
|
||||
const double rate = pTrack->GetRate();
|
||||
const float halfrate = rate / 2;
|
||||
float maxFreq = 8000.0;
|
||||
const SpectrogramSettings &specSettings = pTrack->GetSpectrogramSettings();
|
||||
NumberScale scale;
|
||||
|
||||
bool bDragZoom = IsDragZooming(zoomStart, zoomEnd);
|
||||
// Add 100 if spectral to separate the kinds of zoom.
|
||||
|
||||
// Possibly override the zoom kind.
|
||||
if( bDragZoom )
|
||||
ZoomKind = kZoomInByDrag;
|
||||
|
||||
float top=2.0;
|
||||
float half=0.5;
|
||||
|
||||
{
|
||||
pTrack->GetDisplayBounds(&min, &max);
|
||||
const WaveformSettings &waveSettings = pTrack->GetWaveformSettings();
|
||||
const bool linear = waveSettings.isLinear();
|
||||
@ -237,101 +376,11 @@ void WaveTrackVZoomHandle::DoZoom
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// VZooming on spectral we don't implement the other zoom presets.
|
||||
// They are also not in the menu.
|
||||
case kZoomReset + kSpectral:
|
||||
{
|
||||
// Zoom out to normal level.
|
||||
min = spectrumLinear ? 0.0f : 1.0f;
|
||||
max = maxFreq;
|
||||
}
|
||||
break;
|
||||
case kZoom1to1 + kSpectral:
|
||||
case kZoomDiv2 + kSpectral:
|
||||
case kZoomTimes2 + kSpectral:
|
||||
case kZoomHalfWave + kSpectral:
|
||||
{
|
||||
// Zoom out full
|
||||
min = spectrumLinear ? 0.0f : 1.0f;
|
||||
max = halfrate;
|
||||
}
|
||||
break;
|
||||
case kZoomInByDrag + kSpectral:
|
||||
{
|
||||
double xmin = 1 - (zoomEnd - ypos) / (float)height;
|
||||
double xmax = 1 - (zoomStart - ypos) / (float)height;
|
||||
const float middle = (xmin + xmax) / 2;
|
||||
const float middleValue = scale.PositionToValue(middle);
|
||||
|
||||
min = std::max(spectrumLinear ? 0.0f : 1.0f,
|
||||
std::min(middleValue - minBand / 2,
|
||||
scale.PositionToValue(xmin)
|
||||
));
|
||||
max = std::min(halfrate,
|
||||
std::max(middleValue + minBand / 2,
|
||||
scale.PositionToValue(xmax)
|
||||
));
|
||||
}
|
||||
break;
|
||||
case kZoomIn + kSpectral:
|
||||
{
|
||||
// Center the zoom-in at the click
|
||||
const float p1 = (zoomStart - ypos) / (float)height;
|
||||
const float middle = 1.0f - p1;
|
||||
const float middleValue = scale.PositionToValue(middle);
|
||||
|
||||
if (fixedMousePoint) {
|
||||
min = std::max(spectrumLinear ? 0.0f : 1.0f,
|
||||
std::min(middleValue - minBand * middle,
|
||||
scale.PositionToValue(0.5f * middle)
|
||||
));
|
||||
max = std::min(halfrate,
|
||||
std::max(middleValue + minBand * p1,
|
||||
scale.PositionToValue(middle + 0.5f * p1)
|
||||
));
|
||||
}
|
||||
else {
|
||||
min = std::max(spectrumLinear ? 0.0f : 1.0f,
|
||||
std::min(middleValue - minBand / 2,
|
||||
scale.PositionToValue(middle - 0.25f)
|
||||
));
|
||||
max = std::min(halfrate,
|
||||
std::max(middleValue + minBand / 2,
|
||||
scale.PositionToValue(middle + 0.25f)
|
||||
));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kZoomOut + kSpectral:
|
||||
{
|
||||
// Zoom out
|
||||
const float p1 = (zoomStart - ypos) / (float)height;
|
||||
// (Used to zoom out centered at midline, ignoring the click, if linear view.
|
||||
// I think it is better to be consistent. PRL)
|
||||
// Center zoom-out at the midline
|
||||
const float middle = // spectrumLinear ? 0.5f :
|
||||
1.0f - p1;
|
||||
|
||||
if (fixedMousePoint) {
|
||||
min = std::max(spectrumLinear ? 0.0f : 1.0f, scale.PositionToValue(-middle));
|
||||
max = std::min(halfrate, scale.PositionToValue(1.0f + p1));
|
||||
}
|
||||
else {
|
||||
min = std::max(spectrumLinear ? 0.0f : 1.0f, scale.PositionToValue(middle - 1.0f));
|
||||
max = std::min(halfrate, scale.PositionToValue(middle + 1.0f));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Now actually apply the zoom.
|
||||
for (auto channel : TrackList::Channels(pTrack)) {
|
||||
if (spectral)
|
||||
channel->SetSpectrumBounds(min, max);
|
||||
else
|
||||
channel->SetDisplayBounds(min, max);
|
||||
}
|
||||
for (auto channel : TrackList::Channels(pTrack))
|
||||
channel->SetDisplayBounds(min, max);
|
||||
|
||||
zoomEnd = zoomStart = 0;
|
||||
if( pProject )
|
||||
@ -401,9 +450,10 @@ void WaveTrackVRulerMenuTable::InitMenu(Menu *, void *pUserData)
|
||||
void WaveTrackVRulerMenuTable::OnZoom(
|
||||
WaveTrackViewConstants::ZoomActions iZoomCode )
|
||||
{
|
||||
WaveTrackVZoomHandle::DoZoom
|
||||
(::GetActiveProject(), mpData->pTrack,
|
||||
iZoomCode, mpData->rect, mpData->yy, mpData->yy, false);
|
||||
mpData->doZoom(
|
||||
::GetActiveProject(), mpData->pTrack,
|
||||
iZoomCode, mpData->rect, mpData->yy, mpData->yy, false
|
||||
);
|
||||
|
||||
using namespace RefreshCode;
|
||||
mpData->result = UpdateVRuler | RefreshAll;
|
||||
@ -648,7 +698,10 @@ UIHandle::Result WaveTrackVZoomHandle::Release
|
||||
!(event.ShiftDown() || event.CmdDown()))
|
||||
{
|
||||
InitMenuData data {
|
||||
pTrack.get(), mRect, RefreshCode::RefreshNone, event.m_y
|
||||
pTrack.get(), mRect, RefreshCode::RefreshNone, event.m_y,
|
||||
(pTrack->GetDisplay() == Spectrum)
|
||||
? WaveTrackVZoomHandle::DoSpectrumZoom
|
||||
: WaveTrackVZoomHandle::DoWaveformZoom
|
||||
};
|
||||
|
||||
PopupMenuTable *const pTable =
|
||||
@ -687,7 +740,10 @@ UIHandle::Result WaveTrackVZoomHandle::Release
|
||||
if( bVZoom ) {
|
||||
if( shiftDown )
|
||||
mZoomStart = mZoomEnd;
|
||||
DoZoom(pProject, pTrack.get(),
|
||||
auto doZoom = (pTrack->GetDisplay() == Spectrum)
|
||||
? WaveTrackVZoomHandle::DoSpectrumZoom
|
||||
: WaveTrackVZoomHandle::DoWaveformZoom;
|
||||
doZoom(pProject, pTrack.get(),
|
||||
shiftDown
|
||||
? (rightUp ? kZoom1to1 : kZoomOut)
|
||||
: kZoomIn,
|
||||
|
@ -28,12 +28,21 @@ public:
|
||||
|
||||
WaveTrackVZoomHandle &operator=(const WaveTrackVZoomHandle&) = default;
|
||||
|
||||
static void DoZoom
|
||||
(AudacityProject *pProject,
|
||||
WaveTrack *pTrack,
|
||||
WaveTrackViewConstants::ZoomActions ZoomKind,
|
||||
const wxRect &rect, int zoomStart, int zoomEnd,
|
||||
bool fixedMousePoint);
|
||||
using DoZoomFunction = void (*)( AudacityProject *pProject,
|
||||
WaveTrack *pTrack,
|
||||
WaveTrackViewConstants::ZoomActions ZoomKind,
|
||||
const wxRect &rect, int zoomStart, int zoomEnd,
|
||||
bool fixedMousePoint);
|
||||
static void DoSpectrumZoom( AudacityProject *pProject,
|
||||
WaveTrack *pTrack,
|
||||
WaveTrackViewConstants::ZoomActions ZoomKind,
|
||||
const wxRect &rect, int zoomStart, int zoomEnd,
|
||||
bool fixedMousePoint);
|
||||
static void DoWaveformZoom( AudacityProject *pProject,
|
||||
WaveTrack *pTrack,
|
||||
WaveTrackViewConstants::ZoomActions ZoomKind,
|
||||
const wxRect &rect, int zoomStart, int zoomEnd,
|
||||
bool fixedMousePoint);
|
||||
|
||||
virtual ~WaveTrackVZoomHandle();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user