Defined EXPERIMENTAL_SCROLLING LIMITS

When it is enabled, the project can scroll up to one-half of a screenful
beyond time zero or the maximum track time.  I was careful to disable selection
of negative times.

This is motivated by the smooth scrolling scrub.  It behaves more sensibly at
the extremes.  It can still keep the play indicator centered.

Also removed an unused member of ViewInfo.
This commit is contained in:
Paul Licameli 2015-05-24 13:31:18 -04:00
parent b56a8b2d2f
commit 5c62b80bc4
6 changed files with 78 additions and 38 deletions

View File

@ -170,7 +170,7 @@
// #define EXPERIMENTAL_NYQUIST_SPLIT_CONTROL
// Paul Licameli (PRL) 16 Apr 2015
//Support for scrubbing in the AudioIO engine, without calls to it
// Support for scrubbing in the AudioIO engine, without calls to it
#define EXPERIMENTAL_SCRUBBING_SUPPORT
// The following enable parts of the scrubbing user interface.
@ -181,6 +181,10 @@
// You must define EXPERIMENTAL_SCRUBBING_BASIC if you enable this:
#define EXPERIMENTAL_SCRUBBING_SCROLL_WHEEL
// Paul Licameli (PRL) 24 May 2015
// Allow scrolling up to one half of a screenful beyond either end of the project.
// This allows smooth-scrolling scrub to work more reasonably at the ends.
#define EXPERIMENTAL_SCROLLING_LIMITS
// Define to include crash reporting
#define EXPERIMENTAL_CRASH_REPORT

View File

@ -86,7 +86,6 @@ bool AudacityPrintout::OnPrintPage(int WXUNUSED(page))
viewInfo.h = 0.0;
viewInfo.screen = mTracks->GetEndTime() - viewInfo.h;
viewInfo.total = viewInfo.screen;
viewInfo.zoom = viewInfo.lastZoom = width / viewInfo.screen;
int y = rulerPageHeight;
TrackListIterator iter(mTracks);

View File

@ -174,17 +174,17 @@ ODLock *AudacityProject::msAllProjectDeleteMutex = new ODLock();
const int sbarSpaceWidth = 15;
const int sbarControlWidth = 16;
const int sbarExtraLen = 1;
const int sbarHjump = 30; //STM: This is how far the thumb jumps when the l/r buttons are pressed, or auto-scrolling occurs
const int sbarHjump = 30; //STM: This is how far the thumb jumps when the l/r buttons are pressed, or auto-scrolling occurs -- in pixels
#elif defined(__WXMSW__)
const int sbarSpaceWidth = 16;
const int sbarControlWidth = 16;
const int sbarExtraLen = 0;
const int sbarHjump = 30; //STM: This is how far the thumb jumps when the l/r buttons are pressed, or auto-scrolling occurs
const int sbarHjump = 30; //STM: This is how far the thumb jumps when the l/r buttons are pressed, or auto-scrolling occurs -- in pixels
#else // wxGTK, wxMOTIF, wxX11
const int sbarSpaceWidth = 15;
const int sbarControlWidth = 15;
const int sbarExtraLen = 0;
const int sbarHjump = 30; //STM: This is how far the thumb jumps when the l/r buttons are pressed, or auto-scrolling occurs
const int sbarHjump = 30; //STM: This is how far the thumb jumps when the l/r buttons are pressed, or auto-scrolling occurs -- in pixels
#include "Theme.h"
#include "AllThemeResources.h"
#endif
@ -811,7 +811,6 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id,
mViewInfo.screen = 1.0;
mViewInfo.h = 0.0;
mViewInfo.zoom = 44100.0 / 512.0;
mViewInfo.lastZoom = mViewInfo.zoom;
// Vertical scrollbar
mViewInfo.track = NULL;
@ -1461,7 +1460,13 @@ void AudacityProject::OnScrollRightButton(wxScrollEvent & event)
//
void AudacityProject::TP_ScrollWindow(double scrollto)
{
int pos = (int) (scrollto * mViewInfo.zoom * mViewInfo.sbarScale);
double timeOffset = 0;
#ifdef EXPERIMENTAL_SCROLLING_LIMITS
timeOffset = mViewInfo.screen / 2.0;
#endif
int pos = (int) (
(scrollto + timeOffset) * mViewInfo.zoom * mViewInfo.sbarScale
);
int max = mHsbar->GetRange() - mHsbar->GetThumbSize();
if (pos > max)
@ -1520,18 +1525,29 @@ void AudacityProject::FixScrollbars()
int panelWidth, panelHeight;
mTrackPanel->GetTracksUsableArea(&panelWidth, &panelHeight);
// Add 1/4 of a screen of blank space to the end of the longest track
mViewInfo.screen = ((double) panelWidth) / mViewInfo.zoom;
double additional, lowerBound;
#ifdef EXPERIMENTAL_SCROLLING_LIMITS
// Add 1/2 of a screen of blank space to the end
// and another 1/2 screen before the beginning
// so that any point within the union of the selection and the track duration
// may be scrolled to the midline.
additional = mViewInfo.screen;
lowerBound = - additional / 2.0;
#else
// Formerly just added 1/4 screen at the end
additional = mViewInfo.screen / 4.0;
lowerBound = 0.0;
#endif
double LastTime =
wxMax( mTracks->GetEndTime(), mViewInfo.selectedRegion.t1() );
mViewInfo.total = LastTime + mViewInfo.screen / 4;
std::max( mTracks->GetEndTime(), mViewInfo.selectedRegion.t1() );
mViewInfo.total = LastTime + additional;
// Don't remove time from total that's still on the screen
if (mViewInfo.h > mViewInfo.total - mViewInfo.screen) {
mViewInfo.total = mViewInfo.h + mViewInfo.screen;
}
if (mViewInfo.h < 0.0) {
mViewInfo.h = 0.0;
mViewInfo.total = std::max(mViewInfo.total, mViewInfo.h + mViewInfo.screen);
if (mViewInfo.h < lowerBound) {
mViewInfo.h = lowerBound;
rescroll = true;
}
@ -1603,13 +1619,21 @@ void AudacityProject::FixScrollbars()
else
mViewInfo.sbarScale = 1.0; // use maximum resolution
int scaledSbarH = (int)(mViewInfo.sbarH * mViewInfo.sbarScale);
int scaledSbarScreen = (int)(mViewInfo.sbarScreen * mViewInfo.sbarScale);
int scaledSbarTotal = (int)(mViewInfo.sbarTotal * mViewInfo.sbarScale);
{
int scaledSbarH = (int)(mViewInfo.sbarH * mViewInfo.sbarScale);
int scaledSbarScreen = (int)(mViewInfo.sbarScreen * mViewInfo.sbarScale);
int scaledSbarTotal = (int)(mViewInfo.sbarTotal * mViewInfo.sbarScale);
int offset;
#ifdef EXPERIMENTAL_SCROLLING_LIMITS
offset = scaledSbarScreen / 2;
#else
offset = 0;
#endif
mHsbar->SetScrollbar(scaledSbarH, scaledSbarScreen, scaledSbarTotal,
scaledSbarScreen, TRUE);
mHsbar->Refresh();
mHsbar->SetScrollbar(scaledSbarH + offset, scaledSbarScreen, scaledSbarTotal,
scaledSbarScreen, TRUE);
mHsbar->Refresh();
}
// Vertical scrollbar
mVsbar->SetScrollbar(mViewInfo.vpos / mViewInfo.scrollStep,
@ -1617,7 +1641,6 @@ void AudacityProject::FixScrollbars()
totalHeight / mViewInfo.scrollStep,
panelHeight / mViewInfo.scrollStep, TRUE);
mVsbar->Refresh();
mViewInfo.lastZoom = mViewInfo.zoom;
if (refresh || (rescroll && mViewInfo.screen < mViewInfo.total)) {
mTrackPanel->Refresh(false);
@ -1796,16 +1819,26 @@ void AudacityProject::OnScroll(wxScrollEvent & WXUNUSED(event))
{
wxInt64 hlast = mViewInfo.sbarH;
mViewInfo.sbarH = (wxInt64)
(mHsbar->GetThumbPosition() / mViewInfo.sbarScale);
double lowerBound;
wxInt64 offset;
#ifdef EXPERIMENTAL_SCROLLING_LIMITS
offset = (0.5 + (mViewInfo.zoom * mViewInfo.screen / 2.0));
lowerBound = -mViewInfo.screen / 2.0;
#else
offset = 0.0;
lowerBound = 0.0;
#endif
mViewInfo.sbarH =
(wxInt64)(mHsbar->GetThumbPosition() / mViewInfo.sbarScale) - offset;
if (mViewInfo.sbarH != hlast) {
mViewInfo.h = mViewInfo.sbarH / mViewInfo.zoom;
if (mViewInfo.h > mViewInfo.total - mViewInfo.screen)
mViewInfo.h = mViewInfo.total - mViewInfo.screen;
if (mViewInfo.h < 0.0)
mViewInfo.h = 0.0;
if (mViewInfo.h < lowerBound)
mViewInfo.h = lowerBound;
}
int lastv = mViewInfo.vpos;

View File

@ -1489,7 +1489,11 @@ void TrackPanel::OnPaint(wxPaintEvent & /* event */)
// the drawing of the tracks. This prevents flashing of the indicator
// at higher magnifications, and keeps the green line still in the middle.
indicator = gAudioIO->GetStreamTime();
mViewInfo->h = std::max(0.0, indicator - mViewInfo->screen / 2.0);
mViewInfo->h = indicator - mViewInfo->screen / 2.0;
#if !defined(EXPERIMENTAL_SCROLLING_LIMITS)
// Can't scroll too far left
mViewInfo->h = std::max(0.0, mViewInfo->h);
#endif
}
#endif
@ -2409,9 +2413,9 @@ bool TrackPanel::ContinueScrubbing(wxCoord position, bool maySkip)
{
wxCoord leadPosition = position;
double newEnd =
std::max(0.0,
std::min(PositionToTime(leadPosition, GetLeftOffset()),
mTracks->GetEndTime()
std::max(0.0,
std::min(PositionToTime(leadPosition, GetLeftOffset()),
mTracks->GetEndTime()
));
if (maySkip)
@ -2710,7 +2714,7 @@ void TrackPanel::SelectionHandleClick(wxMouseEvent & event,
if (startNewSelection) { // mouse is not at an edge, but after
// quantization, we could be indicating the selection edge
mSelStartValid = true;
mSelStart = PositionToTime(event.m_x, r.x);
mSelStart = std::max(0.0, PositionToTime(event.m_x, r.x));
mStretchStart = nt->NearestBeatTime(mSelStart, &centerBeat);
if (within(qBeat0, centerBeat, 0.1)) {
mListener->TP_DisplayStatusMessage(
@ -2801,8 +2805,10 @@ void TrackPanel::SelectionHandleClick(wxMouseEvent & event,
void TrackPanel::StartSelection(int mouseXCoordinate, int trackLeftEdge)
{
mSelStartValid = true;
mSelStart = mViewInfo->h + ((mouseXCoordinate - trackLeftEdge)
/ mViewInfo->zoom);
mSelStart =
std::max(0.0,
mViewInfo->h + ((mouseXCoordinate - trackLeftEdge)
/ mViewInfo->zoom));
double s = mSelStart;
@ -2832,7 +2838,7 @@ void TrackPanel::ExtendSelection(int mouseXCoordinate, int trackLeftEdge,
// Must be dragging frequency bounds only.
return;
double selend = PositionToTime(mouseXCoordinate, trackLeftEdge);
double selend = std::max(0.0, PositionToTime(mouseXCoordinate, trackLeftEdge));
clip_bottom(selend, 0.0);
double origSel0, origSel1;
@ -3264,7 +3270,7 @@ void TrackPanel::Stretch(int mouseXCoordinate, int trackLeftEdge,
}
NoteTrack *pNt = (NoteTrack *) pTrack;
double moveto = PositionToTime(mouseXCoordinate, trackLeftEdge);
double moveto = std::max(0.0, PositionToTime(mouseXCoordinate, trackLeftEdge));
// check to make sure tempo is not higher than 20 beats per second
// (In principle, tempo can be higher, but not infinity.)

View File

@ -33,7 +33,6 @@ struct ViewInfo {
double screen; // screen width in secs
double total; // total width in secs
double zoom; // pixels per second
double lastZoom;
// Current horizontal scroll bar positions, in pixels
wxInt64 sbarH;
@ -43,6 +42,7 @@ struct ViewInfo {
// Internal wxScrollbar positions are only int in range, so multiply
// the above values with the following member to get the actual
// scroll bar positions as reported by the horizontal wxScrollbar's members
// i.e. units are scroll increments per pixel
double sbarScale;
// Vertical scroll step

View File

@ -64,8 +64,6 @@ void AttachableScrollBar::SetScrollBarFromViewInfo()
SetScrollbar(mViewInfo.sbarH, mViewInfo.sbarScreen,
mViewInfo.sbarTotal, mViewInfo.sbarScreen, TRUE);
mViewInfo.lastZoom = mViewInfo.zoom;
}
// Essentially an int to float conversion.