WaveTrack does not depend directly on ProjectHistory...
... because we undo the move, "Demote vertical zooming code into WaveTrack.cpp ..." done at1f4bf26
That was done so that WaveTrack would not depend on WaveTrackVZoomHandle, but made it instead depend on ProjectHistory, which is undesirable. But since then, commit3797a52
moved the special minimizing code for WaveTrack into WaveTrackView.
This commit is contained in:
parent
499e3c01ce
commit
aa1ce03100
|
@ -2829,299 +2829,3 @@ void WaveTrack::AllClipsIterator::push( WaveClipHolders &clips )
|
|||
pClips = &(*first)->GetCutLines();
|
||||
}
|
||||
}
|
||||
|
||||
void WaveTrack::DoZoomPreset( int i)
|
||||
{
|
||||
// Don't do all channels, that causes problems when updating display
|
||||
// during recording and there are special pending tracks.
|
||||
// This function implements WaveTrack::DoSetMinimized which is always
|
||||
// called in a context that loops over linked tracks too and reinvokes.
|
||||
WaveTrack::DoZoom(
|
||||
NULL, this, false, (i==1)?kZoomHalfWave: kZoom1to1,
|
||||
wxRect(0,0,0,0), 0,0, true);
|
||||
}
|
||||
|
||||
#include "NumberScale.h"
|
||||
#include "ProjectHistory.h"
|
||||
|
||||
static bool IsDragZooming(int zoomStart, int zoomEnd)
|
||||
{
|
||||
const int DragThreshold = 3;// Anything over 3 pixels is a drag, else a click.
|
||||
bool bVZoom;
|
||||
gPrefs->Read(wxT("/GUI/VerticalZooming"), &bVZoom, false);
|
||||
return bVZoom && (abs(zoomEnd - zoomStart) > DragThreshold);
|
||||
}
|
||||
|
||||
// ZoomKind says how to zoom.
|
||||
// If ZoomStart and ZoomEnd are not equal, this may override
|
||||
// the zoomKind and cause a drag-zoom-in.
|
||||
void WaveTrack::DoZoom
|
||||
(AudacityProject *pProject,
|
||||
WaveTrack *pTrack, bool allChannels, int ZoomKind,
|
||||
const wxRect &rect, int zoomStart, int zoomEnd,
|
||||
bool fixedMousePoint)
|
||||
{
|
||||
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;
|
||||
const bool spectral = (pTrack->GetDisplay() == WaveTrack::Spectrum);
|
||||
const bool spectrumLinear = spectral &&
|
||||
(pTrack->GetSpectrogramSettings().scaleType == SpectrogramSettings::stLinear);
|
||||
|
||||
|
||||
bool bDragZoom = IsDragZooming(zoomStart, zoomEnd);
|
||||
// Add 100 if spectral to separate the kinds of zoom.
|
||||
const int kSpectral = 100;
|
||||
|
||||
// Possibly override the zoom kind.
|
||||
if( bDragZoom )
|
||||
ZoomKind = kZoomInByDrag;
|
||||
|
||||
// If we are actually zooming a spectrum rather than a wave.
|
||||
ZoomKind += spectral ? kSpectral:0;
|
||||
|
||||
float top=2.0;
|
||||
float half=0.5;
|
||||
|
||||
if (spectral) {
|
||||
pTrack->GetSpectrumBounds(&min, &max);
|
||||
scale = (specSettings.GetScale(min, max));
|
||||
const auto fftLength = specSettings.GetFFTLength();
|
||||
const float binSize = rate / fftLength;
|
||||
maxFreq = gPrefs->Read(wxT("/Spectrum/MaxFreq"), 8000L);
|
||||
// JKC: Following discussions of Bug 1208 I'm allowing zooming in
|
||||
// down to one bin.
|
||||
// const int minBins =
|
||||
// std::min(10, fftLength / 2); //minimum 10 freq bins, unless there are less
|
||||
const int minBins = 1;
|
||||
minBand = minBins * binSize;
|
||||
}
|
||||
else{
|
||||
pTrack->GetDisplayBounds(&min, &max);
|
||||
const WaveformSettings &waveSettings = pTrack->GetWaveformSettings();
|
||||
const bool linear = waveSettings.isLinear();
|
||||
if( !linear ){
|
||||
top = (LINEAR_TO_DB(2.0) + waveSettings.dBRange) / waveSettings.dBRange;
|
||||
half = (LINEAR_TO_DB(0.5) + waveSettings.dBRange) / waveSettings.dBRange;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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;
|
||||
case kZoomReset:
|
||||
case kZoom1to1:
|
||||
{
|
||||
// Zoom out full
|
||||
min = -1.0;
|
||||
max = 1.0;
|
||||
}
|
||||
break;
|
||||
case kZoomDiv2:
|
||||
{
|
||||
// Zoom out even more than full :-)
|
||||
// -2.0..+2.0 (or logarithmic equivalent)
|
||||
min = -top;
|
||||
max = top;
|
||||
}
|
||||
break;
|
||||
case kZoomTimes2:
|
||||
{
|
||||
// Zoom in to -0.5..+0.5
|
||||
min = -half;
|
||||
max = half;
|
||||
}
|
||||
break;
|
||||
case kZoomHalfWave:
|
||||
{
|
||||
// Zoom to show fractionally more than the top half of the wave.
|
||||
min = -0.01f;
|
||||
max = 1.0;
|
||||
}
|
||||
break;
|
||||
case kZoomInByDrag:
|
||||
{
|
||||
const float tmin = min, tmax = max;
|
||||
const float p1 = (zoomStart - ypos) / (float)height;
|
||||
const float p2 = (zoomEnd - ypos) / (float)height;
|
||||
max = (tmax * (1.0 - p1) + tmin * p1);
|
||||
min = (tmax * (1.0 - p2) + tmin * p2);
|
||||
|
||||
// Waveform view - allow zooming down to a range of ZOOMLIMIT
|
||||
if (max - min < ZOOMLIMIT) { // if user attempts to go smaller...
|
||||
float c = (min + max) / 2; // ...set centre of view to centre of dragged area and top/bottom to ZOOMLIMIT/2 above/below
|
||||
min = c - ZOOMLIMIT / 2.0;
|
||||
max = c + ZOOMLIMIT / 2.0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kZoomIn:
|
||||
{
|
||||
// Enforce maximum vertical zoom
|
||||
const float oldRange = max - min;
|
||||
const float l = std::max(ZOOMLIMIT, 0.5f * oldRange);
|
||||
const float ratio = l / (max - min);
|
||||
|
||||
const float p1 = (zoomStart - ypos) / (float)height;
|
||||
float c = (max * (1.0 - p1) + min * p1);
|
||||
if (fixedMousePoint)
|
||||
min = c - ratio * (1.0f - p1) * oldRange,
|
||||
max = c + ratio * p1 * oldRange;
|
||||
else
|
||||
min = c - 0.5 * l,
|
||||
max = c + 0.5 * l;
|
||||
}
|
||||
break;
|
||||
case kZoomOut:
|
||||
{
|
||||
// Zoom out
|
||||
if (min <= -1.0 && max >= 1.0) {
|
||||
min = -top;
|
||||
max = top;
|
||||
}
|
||||
else {
|
||||
// limit to +/- 1 range unless already outside that range...
|
||||
float minRange = (min < -1) ? -top : -1.0;
|
||||
float maxRange = (max > 1) ? top : 1.0;
|
||||
// and enforce vertical zoom limits.
|
||||
const float p1 = (zoomStart - ypos) / (float)height;
|
||||
if (fixedMousePoint) {
|
||||
const float oldRange = max - min;
|
||||
const float c = (max * (1.0 - p1) + min * p1);
|
||||
min = std::min(maxRange - ZOOMLIMIT,
|
||||
std::max(minRange, c - 2 * (1.0f - p1) * oldRange));
|
||||
max = std::max(minRange + ZOOMLIMIT,
|
||||
std::min(maxRange, c + 2 * p1 * oldRange));
|
||||
}
|
||||
else {
|
||||
const float c = p1 * min + (1 - p1) * max;
|
||||
const float l = (max - min);
|
||||
min = std::min(maxRange - ZOOMLIMIT,
|
||||
std::max(minRange, c - l));
|
||||
max = std::max(minRange + ZOOMLIMIT,
|
||||
std::min(maxRange, c + l));
|
||||
}
|
||||
}
|
||||
}
|
||||
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 (!allChannels && channel != pTrack)
|
||||
continue;
|
||||
if (spectral)
|
||||
channel->SetSpectrumBounds(min, max);
|
||||
else
|
||||
channel->SetDisplayBounds(min, max);
|
||||
}
|
||||
|
||||
zoomEnd = zoomStart = 0;
|
||||
if( pProject )
|
||||
ProjectHistory::Get( *pProject ).ModifyState(true);
|
||||
}
|
||||
|
||||
|
|
|
@ -61,17 +61,6 @@ using Regions = std::vector < Region >;
|
|||
|
||||
class Envelope;
|
||||
|
||||
// Note that these can be with or without spectrum view which
|
||||
// adds a constant.
|
||||
const int kZoom1to1 = 1;
|
||||
const int kZoomTimes2 = 2;
|
||||
const int kZoomDiv2 = 3;
|
||||
const int kZoomHalfWave = 4;
|
||||
const int kZoomInByDrag = 5;
|
||||
const int kZoomIn = 6;
|
||||
const int kZoomOut = 7;
|
||||
const int kZoomReset = 8;
|
||||
|
||||
class AUDACITY_DLL_API WaveTrack final : public PlayableTrack {
|
||||
public:
|
||||
|
||||
|
@ -552,13 +541,6 @@ private:
|
|||
//
|
||||
|
||||
|
||||
static void DoZoom
|
||||
(AudacityProject *pProject,
|
||||
WaveTrack *pTrack, bool allChannels, int ZoomKind,
|
||||
const wxRect &rect, int zoomStart, int zoomEnd,
|
||||
bool fixedMousePoint);
|
||||
void DoZoomPreset( int i);
|
||||
|
||||
typedef int WaveTrackDisplay;
|
||||
enum WaveTrackDisplayValues : int {
|
||||
|
||||
|
|
|
@ -49,6 +49,25 @@ std::vector<UIHandlePtr> WaveTrackVRulerControls::HitTest
|
|||
return results;
|
||||
}
|
||||
|
||||
void WaveTrackVRulerControls::DoZoomPreset( int i)
|
||||
{
|
||||
|
||||
const auto pTrack = FindTrack();
|
||||
if (!pTrack)
|
||||
return;
|
||||
|
||||
const auto wt = static_cast<WaveTrack*>(pTrack.get());
|
||||
|
||||
// Don't do all channels, that causes problems when updating display
|
||||
// during recording and there are special pending tracks.
|
||||
// This function implements WaveTrack::DoSetMinimized which is always
|
||||
// called in a context that loops over linked tracks too and reinvokes.
|
||||
WaveTrackVZoomHandle::DoZoom(
|
||||
NULL, wt, false, (i==1)?kZoomHalfWave: kZoom1to1,
|
||||
wxRect(0,0,0,0), 0,0, true);
|
||||
}
|
||||
|
||||
|
||||
unsigned WaveTrackVRulerControls::HandleWheelRotation
|
||||
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
|
||||
{
|
||||
|
@ -116,7 +135,7 @@ unsigned WaveTrackVRulerControls::HandleWheelRotation
|
|||
}
|
||||
else if (event.CmdDown() && !event.ShiftDown()) {
|
||||
const int yy = event.m_y;
|
||||
WaveTrack::DoZoom(
|
||||
WaveTrackVZoomHandle::DoZoom(
|
||||
pProject, wt, true, (steps < 0)?kZoomOut:kZoomIn,
|
||||
evt.rect, yy, yy, true);
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ public:
|
|||
unsigned HandleWheelRotation
|
||||
(const TrackPanelMouseEvent &event,
|
||||
AudacityProject *pProject) override;
|
||||
void DoZoomPreset( int i);
|
||||
private:
|
||||
std::weak_ptr<WaveTrackVZoomHandle> mVZoomHandle;
|
||||
};
|
||||
|
|
|
@ -16,6 +16,7 @@ Paul Licameli split from TrackPanel.cpp
|
|||
#include "WaveTrackVRulerControls.h"
|
||||
|
||||
#include "../../../../HitTestResult.h"
|
||||
#include "../../../../NumberScale.h"
|
||||
#include "../../../../prefs/SpectrogramSettings.h"
|
||||
#include "../../../../prefs/WaveformSettings.h"
|
||||
#include "../../../../Project.h"
|
||||
|
@ -62,6 +63,279 @@ void WaveTrackVZoomHandle::Enter(bool)
|
|||
#endif
|
||||
}
|
||||
|
||||
// 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, bool allChannels, int ZoomKind,
|
||||
const wxRect &rect, int zoomStart, int zoomEnd,
|
||||
bool fixedMousePoint)
|
||||
{
|
||||
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;
|
||||
const bool spectral = (pTrack->GetDisplay() == WaveTrack::Spectrum);
|
||||
const bool spectrumLinear = spectral &&
|
||||
(pTrack->GetSpectrogramSettings().scaleType == SpectrogramSettings::stLinear);
|
||||
|
||||
|
||||
bool bDragZoom = IsDragZooming(zoomStart, zoomEnd);
|
||||
// Add 100 if spectral to separate the kinds of zoom.
|
||||
const int kSpectral = 100;
|
||||
|
||||
// Possibly override the zoom kind.
|
||||
if( bDragZoom )
|
||||
ZoomKind = kZoomInByDrag;
|
||||
|
||||
// If we are actually zooming a spectrum rather than a wave.
|
||||
ZoomKind += spectral ? kSpectral:0;
|
||||
|
||||
float top=2.0;
|
||||
float half=0.5;
|
||||
|
||||
if (spectral) {
|
||||
pTrack->GetSpectrumBounds(&min, &max);
|
||||
scale = (specSettings.GetScale(min, max));
|
||||
const auto fftLength = specSettings.GetFFTLength();
|
||||
const float binSize = rate / fftLength;
|
||||
maxFreq = gPrefs->Read(wxT("/Spectrum/MaxFreq"), 8000L);
|
||||
// JKC: Following discussions of Bug 1208 I'm allowing zooming in
|
||||
// down to one bin.
|
||||
// const int minBins =
|
||||
// std::min(10, fftLength / 2); //minimum 10 freq bins, unless there are less
|
||||
const int minBins = 1;
|
||||
minBand = minBins * binSize;
|
||||
}
|
||||
else{
|
||||
pTrack->GetDisplayBounds(&min, &max);
|
||||
const WaveformSettings &waveSettings = pTrack->GetWaveformSettings();
|
||||
const bool linear = waveSettings.isLinear();
|
||||
if( !linear ){
|
||||
top = (LINEAR_TO_DB(2.0) + waveSettings.dBRange) / waveSettings.dBRange;
|
||||
half = (LINEAR_TO_DB(0.5) + waveSettings.dBRange) / waveSettings.dBRange;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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;
|
||||
case kZoomReset:
|
||||
case kZoom1to1:
|
||||
{
|
||||
// Zoom out full
|
||||
min = -1.0;
|
||||
max = 1.0;
|
||||
}
|
||||
break;
|
||||
case kZoomDiv2:
|
||||
{
|
||||
// Zoom out even more than full :-)
|
||||
// -2.0..+2.0 (or logarithmic equivalent)
|
||||
min = -top;
|
||||
max = top;
|
||||
}
|
||||
break;
|
||||
case kZoomTimes2:
|
||||
{
|
||||
// Zoom in to -0.5..+0.5
|
||||
min = -half;
|
||||
max = half;
|
||||
}
|
||||
break;
|
||||
case kZoomHalfWave:
|
||||
{
|
||||
// Zoom to show fractionally more than the top half of the wave.
|
||||
min = -0.01f;
|
||||
max = 1.0;
|
||||
}
|
||||
break;
|
||||
case kZoomInByDrag:
|
||||
{
|
||||
const float tmin = min, tmax = max;
|
||||
const float p1 = (zoomStart - ypos) / (float)height;
|
||||
const float p2 = (zoomEnd - ypos) / (float)height;
|
||||
max = (tmax * (1.0 - p1) + tmin * p1);
|
||||
min = (tmax * (1.0 - p2) + tmin * p2);
|
||||
|
||||
// Waveform view - allow zooming down to a range of ZOOMLIMIT
|
||||
if (max - min < ZOOMLIMIT) { // if user attempts to go smaller...
|
||||
float c = (min + max) / 2; // ...set centre of view to centre of dragged area and top/bottom to ZOOMLIMIT/2 above/below
|
||||
min = c - ZOOMLIMIT / 2.0;
|
||||
max = c + ZOOMLIMIT / 2.0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kZoomIn:
|
||||
{
|
||||
// Enforce maximum vertical zoom
|
||||
const float oldRange = max - min;
|
||||
const float l = std::max(ZOOMLIMIT, 0.5f * oldRange);
|
||||
const float ratio = l / (max - min);
|
||||
|
||||
const float p1 = (zoomStart - ypos) / (float)height;
|
||||
float c = (max * (1.0 - p1) + min * p1);
|
||||
if (fixedMousePoint)
|
||||
min = c - ratio * (1.0f - p1) * oldRange,
|
||||
max = c + ratio * p1 * oldRange;
|
||||
else
|
||||
min = c - 0.5 * l,
|
||||
max = c + 0.5 * l;
|
||||
}
|
||||
break;
|
||||
case kZoomOut:
|
||||
{
|
||||
// Zoom out
|
||||
if (min <= -1.0 && max >= 1.0) {
|
||||
min = -top;
|
||||
max = top;
|
||||
}
|
||||
else {
|
||||
// limit to +/- 1 range unless already outside that range...
|
||||
float minRange = (min < -1) ? -top : -1.0;
|
||||
float maxRange = (max > 1) ? top : 1.0;
|
||||
// and enforce vertical zoom limits.
|
||||
const float p1 = (zoomStart - ypos) / (float)height;
|
||||
if (fixedMousePoint) {
|
||||
const float oldRange = max - min;
|
||||
const float c = (max * (1.0 - p1) + min * p1);
|
||||
min = std::min(maxRange - ZOOMLIMIT,
|
||||
std::max(minRange, c - 2 * (1.0f - p1) * oldRange));
|
||||
max = std::max(minRange + ZOOMLIMIT,
|
||||
std::min(maxRange, c + 2 * p1 * oldRange));
|
||||
}
|
||||
else {
|
||||
const float c = p1 * min + (1 - p1) * max;
|
||||
const float l = (max - min);
|
||||
min = std::min(maxRange - ZOOMLIMIT,
|
||||
std::max(minRange, c - l));
|
||||
max = std::max(minRange + ZOOMLIMIT,
|
||||
std::min(maxRange, c + l));
|
||||
}
|
||||
}
|
||||
}
|
||||
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 (!allChannels && channel != pTrack)
|
||||
continue;
|
||||
if (spectral)
|
||||
channel->SetSpectrumBounds(min, max);
|
||||
else
|
||||
channel->SetDisplayBounds(min, max);
|
||||
}
|
||||
|
||||
zoomEnd = zoomStart = 0;
|
||||
if( pProject )
|
||||
ProjectHistory::Get( *pProject ).ModifyState(true);
|
||||
}
|
||||
|
||||
enum {
|
||||
OnZoomFitVerticalID = 20000,
|
||||
OnZoomResetID,
|
||||
|
@ -117,7 +391,7 @@ void WaveTrackVRulerMenuTable::InitMenu(Menu *, void *pUserData)
|
|||
|
||||
void WaveTrackVRulerMenuTable::OnZoom( int iZoomCode )
|
||||
{
|
||||
WaveTrack::DoZoom
|
||||
WaveTrackVZoomHandle::DoZoom
|
||||
(::GetActiveProject(), mpData->pTrack, true,
|
||||
iZoomCode, mpData->rect, mpData->yy, mpData->yy, false);
|
||||
|
||||
|
@ -402,7 +676,7 @@ UIHandle::Result WaveTrackVZoomHandle::Release
|
|||
if( bVZoom ){
|
||||
if( shiftDown )
|
||||
mZoomStart=mZoomEnd;
|
||||
WaveTrack::DoZoom(pProject, pTrack.get(), true,
|
||||
DoZoom(pProject, pTrack.get(), true,
|
||||
shiftDown ? (rightUp ? kZoom1to1 : kZoomOut) : kZoomIn,
|
||||
mRect, mZoomStart, mZoomEnd, !shiftDown);
|
||||
}
|
||||
|
|
|
@ -16,6 +16,17 @@ class WaveTrack;
|
|||
#include "../../../../UIHandle.h"
|
||||
|
||||
|
||||
// Note that these can be with or without spectrum view which
|
||||
// adds a constant.
|
||||
const int kZoom1to1 = 1;
|
||||
const int kZoomTimes2 = 2;
|
||||
const int kZoomDiv2 = 3;
|
||||
const int kZoomHalfWave = 4;
|
||||
const int kZoomInByDrag = 5;
|
||||
const int kZoomIn = 6;
|
||||
const int kZoomOut = 7;
|
||||
const int kZoomReset = 8;
|
||||
|
||||
class WaveTrackVZoomHandle : public UIHandle
|
||||
{
|
||||
WaveTrackVZoomHandle(const WaveTrackVZoomHandle&);
|
||||
|
@ -27,6 +38,12 @@ public:
|
|||
|
||||
WaveTrackVZoomHandle &operator=(const WaveTrackVZoomHandle&) = default;
|
||||
|
||||
static void DoZoom
|
||||
(AudacityProject *pProject,
|
||||
WaveTrack *pTrack, bool allChannels, int ZoomKind,
|
||||
const wxRect &rect, int zoomStart, int zoomEnd,
|
||||
bool fixedMousePoint);
|
||||
|
||||
virtual ~WaveTrackVZoomHandle();
|
||||
|
||||
std::shared_ptr<WaveTrack> GetTrack() const { return mpTrack.lock(); }
|
||||
|
|
Loading…
Reference in New Issue