Demote vertical zooming code into WaveTrack.cpp ...
... Freeing WaveTrackVRulerControls and WaveTrackVZoomHandle from the big s.c.c., to higher levels, though still in a cycle of two
This commit is contained in:
parent
e969315c90
commit
1f4bf262b1
|
@ -63,10 +63,6 @@ Track classes.
|
|||
#include "InconsistencyException.h"
|
||||
|
||||
#include "TrackPanel.h" // for TrackInfo
|
||||
// Assumptions in objects separation were wrong. We need to activate
|
||||
// VZooming (that lives in WaveTrackVRulerHandle) from an action on the
|
||||
// TCP collapse/expand. So we need visibility here.
|
||||
#include "tracks/playabletrack/wavetrack/ui/WaveTrackVRulerControls.h"
|
||||
|
||||
using std::max;
|
||||
|
||||
|
@ -493,15 +489,7 @@ void WaveTrack::DoSetMinimized(bool isMinimized){
|
|||
gPrefs->Read(wxT("/GUI/CollapseToHalfWave"), &bHalfWave, false);
|
||||
if( bHalfWave )
|
||||
{
|
||||
// Show half wave on collapse, full on restore.
|
||||
std::shared_ptr<TrackVRulerControls> pTvc = GetVRulerControl();
|
||||
|
||||
// An awkward workaround for a function that lives 'in the wrong place'.
|
||||
// We use magic numbers, 0 and 1, to tell it to zoom reset or zoom half-wave.
|
||||
WaveTrackVRulerControls * pWtvc =
|
||||
static_cast<WaveTrackVRulerControls*>(pTvc.get());
|
||||
if( pWtvc )
|
||||
pWtvc->DoZoomPreset( isMinimized ? 1:0);
|
||||
DoZoomPreset( isMinimized ? 1:0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2871,3 +2859,298 @@ 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);
|
||||
}
|
||||
|
|
|
@ -65,6 +65,17 @@ 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,6 +563,13 @@ 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,25 +49,6 @@ 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)
|
||||
{
|
||||
|
@ -135,7 +116,7 @@ unsigned WaveTrackVRulerControls::HandleWheelRotation
|
|||
}
|
||||
else if (event.CmdDown() && !event.ShiftDown()) {
|
||||
const int yy = event.m_y;
|
||||
WaveTrackVZoomHandle::DoZoom(
|
||||
WaveTrack::DoZoom(
|
||||
pProject, wt, true, (steps < 0)?kZoomOut:kZoomIn,
|
||||
evt.rect, yy, yy, true);
|
||||
}
|
||||
|
|
|
@ -33,7 +33,6 @@ public:
|
|||
unsigned HandleWheelRotation
|
||||
(const TrackPanelMouseEvent &event,
|
||||
AudacityProject *pProject) override;
|
||||
void DoZoomPreset( int i);
|
||||
private:
|
||||
std::weak_ptr<WaveTrackVZoomHandle> mVZoomHandle;
|
||||
};
|
||||
|
|
|
@ -16,7 +16,6 @@ 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"
|
||||
|
@ -63,279 +62,6 @@ 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,
|
||||
|
@ -391,7 +117,7 @@ void WaveTrackVRulerMenuTable::InitMenu(Menu *, void *pUserData)
|
|||
|
||||
void WaveTrackVRulerMenuTable::OnZoom( int iZoomCode )
|
||||
{
|
||||
WaveTrackVZoomHandle::DoZoom
|
||||
WaveTrack::DoZoom
|
||||
(::GetActiveProject(), mpData->pTrack, true,
|
||||
iZoomCode, mpData->rect, mpData->yy, mpData->yy, false);
|
||||
|
||||
|
@ -676,7 +402,7 @@ UIHandle::Result WaveTrackVZoomHandle::Release
|
|||
if( bVZoom ){
|
||||
if( shiftDown )
|
||||
mZoomStart=mZoomEnd;
|
||||
DoZoom(pProject, pTrack.get(), true,
|
||||
WaveTrack::DoZoom(pProject, pTrack.get(), true,
|
||||
shiftDown ? (rightUp ? kZoom1to1 : kZoomOut) : kZoomIn,
|
||||
mRect, mZoomStart, mZoomEnd, !shiftDown);
|
||||
}
|
||||
|
|
|
@ -16,17 +16,6 @@ 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&);
|
||||
|
@ -38,12 +27,6 @@ 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