mirror of
https://github.com/cookiengineer/audacity
synced 2025-08-16 08:34:10 +02:00
Fix off-by-one or -few bugs in drawing and mousing; explained some magic numbers
This commit is contained in:
commit
9760f8aac2
@ -1387,7 +1387,7 @@ bool LabelTrack::HandleGlyphDragRelease(const wxMouseEvent & evt,
|
|||||||
//just reset its value and redraw.
|
//just reset its value and redraw.
|
||||||
// LL: Constrain to inside track rectangle for now. Should be changed
|
// LL: Constrain to inside track rectangle for now. Should be changed
|
||||||
// to allow scrolling while dragging labels
|
// to allow scrolling while dragging labels
|
||||||
int x = Constrain( evt.m_x + mxMouseDisplacement - r.x, 0, r.width - 2);
|
int x = Constrain( evt.m_x + mxMouseDisplacement - r.x, 0, r.width);
|
||||||
|
|
||||||
// If exactly one edge is selected we allow swapping
|
// If exactly one edge is selected we allow swapping
|
||||||
bool bAllowSwapping = (mMouseOverLabelLeft >=0 ) ^ ( mMouseOverLabelRight >= 0);
|
bool bAllowSwapping = (mMouseOverLabelLeft >=0 ) ^ ( mMouseOverLabelRight >= 0);
|
||||||
|
@ -4824,6 +4824,11 @@ void AudacityProject::OnZoomIn()
|
|||||||
ZoomInByFactor( 2.0 );
|
ZoomInByFactor( 2.0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double AudacityProject::GetScreenEndTime() const
|
||||||
|
{
|
||||||
|
return mTrackPanel->GetScreenEndTime();
|
||||||
|
}
|
||||||
|
|
||||||
void AudacityProject::ZoomInByFactor( double ZoomFactor )
|
void AudacityProject::ZoomInByFactor( double ZoomFactor )
|
||||||
{
|
{
|
||||||
// LLL: Handling positioning differently when audio is active
|
// LLL: Handling positioning differently when audio is active
|
||||||
@ -4838,13 +4843,16 @@ void AudacityProject::ZoomInByFactor( double ZoomFactor )
|
|||||||
// when there's a selection that's currently at least
|
// when there's a selection that's currently at least
|
||||||
// partially on-screen
|
// partially on-screen
|
||||||
|
|
||||||
|
const double endTime = GetScreenEndTime();
|
||||||
|
const double duration = endTime - mViewInfo.h;
|
||||||
|
|
||||||
bool selectionIsOnscreen =
|
bool selectionIsOnscreen =
|
||||||
(mViewInfo.selectedRegion.t0() < mViewInfo.h + mViewInfo.screen) &&
|
(mViewInfo.selectedRegion.t0() < endTime) &&
|
||||||
(mViewInfo.selectedRegion.t1() >= mViewInfo.h);
|
(mViewInfo.selectedRegion.t1() >= mViewInfo.h);
|
||||||
|
|
||||||
bool selectionFillsScreen =
|
bool selectionFillsScreen =
|
||||||
(mViewInfo.selectedRegion.t0() < mViewInfo.h) &&
|
(mViewInfo.selectedRegion.t0() < mViewInfo.h) &&
|
||||||
(mViewInfo.selectedRegion.t1() > mViewInfo.h + mViewInfo.screen);
|
(mViewInfo.selectedRegion.t1() > endTime);
|
||||||
|
|
||||||
if (selectionIsOnscreen && !selectionFillsScreen) {
|
if (selectionIsOnscreen && !selectionFillsScreen) {
|
||||||
// Start with the center of the selection
|
// Start with the center of the selection
|
||||||
@ -4856,24 +4864,26 @@ void AudacityProject::ZoomInByFactor( double ZoomFactor )
|
|||||||
if (selCenter < mViewInfo.h)
|
if (selCenter < mViewInfo.h)
|
||||||
selCenter = mViewInfo.h +
|
selCenter = mViewInfo.h +
|
||||||
(mViewInfo.selectedRegion.t1() - mViewInfo.h) / 2;
|
(mViewInfo.selectedRegion.t1() - mViewInfo.h) / 2;
|
||||||
if (selCenter > mViewInfo.h + mViewInfo.screen)
|
if (selCenter > endTime)
|
||||||
selCenter = mViewInfo.h + mViewInfo.screen -
|
selCenter = endTime -
|
||||||
(mViewInfo.h + mViewInfo.screen - mViewInfo.selectedRegion.t0()) / 2;
|
(endTime - mViewInfo.selectedRegion.t0()) / 2;
|
||||||
|
|
||||||
// Zoom in
|
// Zoom in
|
||||||
ZoomBy(ZoomFactor);
|
ZoomBy(ZoomFactor);
|
||||||
|
const double newDuration = GetScreenEndTime() - mViewInfo.h;
|
||||||
|
|
||||||
// Recenter on selCenter
|
// Recenter on selCenter
|
||||||
TP_ScrollWindow(selCenter - mViewInfo.screen / 2);
|
TP_ScrollWindow(selCenter - newDuration / 2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double origLeft = mViewInfo.h;
|
double origLeft = mViewInfo.h;
|
||||||
double origWidth = mViewInfo.screen;
|
double origWidth = duration;
|
||||||
ZoomBy(ZoomFactor);
|
ZoomBy(ZoomFactor);
|
||||||
|
|
||||||
double newh = origLeft + (origWidth - mViewInfo.screen) / 2;
|
const double newDuration = GetScreenEndTime() - mViewInfo.h;
|
||||||
|
double newh = origLeft + (origWidth - newDuration) / 2;
|
||||||
|
|
||||||
// MM: Commented this out because it was confusing users
|
// MM: Commented this out because it was confusing users
|
||||||
/*
|
/*
|
||||||
@ -4900,12 +4910,13 @@ void AudacityProject::OnZoomOut()
|
|||||||
void AudacityProject::ZoomOutByFactor( double ZoomFactor )
|
void AudacityProject::ZoomOutByFactor( double ZoomFactor )
|
||||||
{
|
{
|
||||||
//Zoom() may change these, so record original values:
|
//Zoom() may change these, so record original values:
|
||||||
double origLeft = mViewInfo.h;
|
const double origLeft = mViewInfo.h;
|
||||||
double origWidth = mViewInfo.screen;
|
const double origWidth = GetScreenEndTime() - origLeft;
|
||||||
|
|
||||||
ZoomBy(ZoomFactor);
|
ZoomBy(ZoomFactor);
|
||||||
|
const double newWidth = GetScreenEndTime() - mViewInfo.h;
|
||||||
|
|
||||||
double newh = origLeft + (origWidth - mViewInfo.screen) / 2;
|
const double newh = origLeft + (origWidth - newWidth) / 2;
|
||||||
// newh = (newh > 0) ? newh : 0;
|
// newh = (newh > 0) ? newh : 0;
|
||||||
TP_ScrollWindow(newh);
|
TP_ScrollWindow(newh);
|
||||||
|
|
||||||
@ -4952,8 +4963,8 @@ void AudacityProject::OnZoomFit()
|
|||||||
if (len <= 0.0)
|
if (len <= 0.0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int w, h;
|
int w;
|
||||||
mTrackPanel->GetTracksUsableArea(&w, &h);
|
mTrackPanel->GetTracksUsableArea(&w, NULL);
|
||||||
w -= 10;
|
w -= 10;
|
||||||
|
|
||||||
Zoom(w / len);
|
Zoom(w / len);
|
||||||
@ -4962,9 +4973,9 @@ void AudacityProject::OnZoomFit()
|
|||||||
|
|
||||||
void AudacityProject::DoZoomFitV()
|
void AudacityProject::DoZoomFitV()
|
||||||
{
|
{
|
||||||
int width, height, count;
|
int height, count;
|
||||||
|
|
||||||
mTrackPanel->GetTracksUsableArea(&width, &height);
|
mTrackPanel->GetTracksUsableArea(NULL, &height);
|
||||||
|
|
||||||
height -= 28;
|
height -= 28;
|
||||||
|
|
||||||
@ -5023,16 +5034,19 @@ void AudacityProject::OnZoomSel()
|
|||||||
// where the selected region may be scrolled off the left of the screen.
|
// where the selected region may be scrolled off the left of the screen.
|
||||||
// I know this isn't right, but until the real rounding or 1-off issue is
|
// I know this isn't right, but until the real rounding or 1-off issue is
|
||||||
// found, this will have to work.
|
// found, this will have to work.
|
||||||
Zoom((mViewInfo.GetScreenWidth() - 1) / denom);
|
// PRL: Did I fix this? I am not sure, so I leave the hack in place.
|
||||||
|
int width;
|
||||||
|
mTrackPanel->GetTracksUsableArea(&width, NULL);
|
||||||
|
Zoom((width - 1) / denom);
|
||||||
TP_ScrollWindow(mViewInfo.selectedRegion.t0());
|
TP_ScrollWindow(mViewInfo.selectedRegion.t0());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudacityProject::OnGoSelStart()
|
void AudacityProject::OnGoSelStart()
|
||||||
{
|
{
|
||||||
if (mViewInfo.selectedRegion.isPoint())
|
if (mViewInfo.selectedRegion.isPoint())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
TP_ScrollWindow(mViewInfo.selectedRegion.t0() - (mViewInfo.screen / 2));
|
TP_ScrollWindow(mViewInfo.selectedRegion.t0() - ((GetScreenEndTime() - mViewInfo.h) / 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudacityProject::OnGoSelEnd()
|
void AudacityProject::OnGoSelEnd()
|
||||||
@ -5040,7 +5054,7 @@ void AudacityProject::OnGoSelEnd()
|
|||||||
if (mViewInfo.selectedRegion.isPoint())
|
if (mViewInfo.selectedRegion.isPoint())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
TP_ScrollWindow(mViewInfo.selectedRegion.t1() - (mViewInfo.screen / 2));
|
TP_ScrollWindow(mViewInfo.selectedRegion.t1() - ((GetScreenEndTime() - mViewInfo.h) / 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudacityProject::OnShowClipping()
|
void AudacityProject::OnShowClipping()
|
||||||
|
@ -241,10 +241,14 @@ public:
|
|||||||
case nstErb:
|
case nstErb:
|
||||||
case nstUndertone:
|
case nstUndertone:
|
||||||
return Iterator
|
return Iterator
|
||||||
(mType, (mValue1 - mValue0) / nPositions, mValue0, mUnit);
|
(mType,
|
||||||
|
nPositions == 1 ? 0 : (mValue1 - mValue0) / (nPositions - 1),
|
||||||
|
mValue0, mUnit);
|
||||||
case nstLogarithmic:
|
case nstLogarithmic:
|
||||||
return Iterator
|
return Iterator
|
||||||
(mType, exp((mValue1 - mValue0) / nPositions), exp(mValue0), mUnit);
|
(mType,
|
||||||
|
nPositions == 1 ? 1 : exp((mValue1 - mValue0) / (nPositions - 1)),
|
||||||
|
exp(mValue0), mUnit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ bool AudacityPrintout::OnPrintPage(int WXUNUSED(page))
|
|||||||
artist.SetBackgroundBrushes(*wxWHITE_BRUSH, *wxWHITE_BRUSH,
|
artist.SetBackgroundBrushes(*wxWHITE_BRUSH, *wxWHITE_BRUSH,
|
||||||
*wxWHITE_PEN, *wxWHITE_PEN);
|
*wxWHITE_PEN, *wxWHITE_PEN);
|
||||||
const double screenDuration = mTracks->GetEndTime();
|
const double screenDuration = mTracks->GetEndTime();
|
||||||
ZoomInfo zoomInfo(0.0, screenDuration, width / screenDuration);
|
ZoomInfo zoomInfo(0.0, width / screenDuration);
|
||||||
int y = rulerPageHeight;
|
int y = rulerPageHeight;
|
||||||
|
|
||||||
TrackListIterator iter(mTracks);
|
TrackListIterator iter(mTracks);
|
||||||
|
@ -1472,9 +1472,10 @@ void AudacityProject::OnScrollRightButton(wxScrollEvent & event)
|
|||||||
|
|
||||||
double AudacityProject::ScrollingLowerBoundTime() const
|
double AudacityProject::ScrollingLowerBoundTime() const
|
||||||
{
|
{
|
||||||
return mScrollBeyondZero
|
if (!mScrollBeyondZero)
|
||||||
? std::min(mTracks->GetStartTime(), -mViewInfo.screen / 2.0)
|
return 0;
|
||||||
: 0;
|
const double screen = mTrackPanel->GetScreenEndTime() - mViewInfo.h;
|
||||||
|
return std::min(mTracks->GetStartTime(), -screen / 2.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxInt64 AudacityProject::PixelWidthBeforeTime(double scrollto) const
|
wxInt64 AudacityProject::PixelWidthBeforeTime(double scrollto) const
|
||||||
@ -1556,8 +1557,8 @@ void AudacityProject::FixScrollbars()
|
|||||||
double LastTime =
|
double LastTime =
|
||||||
std::max(mTracks->GetEndTime(), mViewInfo.selectedRegion.t1());
|
std::max(mTracks->GetEndTime(), mViewInfo.selectedRegion.t1());
|
||||||
|
|
||||||
mViewInfo.SetScreenWidth(panelWidth);
|
const double screen = GetScreenEndTime() - mViewInfo.h;
|
||||||
const double halfScreen = mViewInfo.screen / 2.0;
|
const double halfScreen = screen / 2.0;
|
||||||
|
|
||||||
// If we can scroll beyond zero,
|
// If we can scroll beyond zero,
|
||||||
// Add 1/2 of a screen of blank space to the end
|
// Add 1/2 of a screen of blank space to the end
|
||||||
@ -1567,13 +1568,13 @@ void AudacityProject::FixScrollbars()
|
|||||||
// May add even more to the end, so that you can always scroll the starting time to zero.
|
// May add even more to the end, so that you can always scroll the starting time to zero.
|
||||||
const double lowerBound = ScrollingLowerBoundTime();
|
const double lowerBound = ScrollingLowerBoundTime();
|
||||||
const double additional = mScrollBeyondZero
|
const double additional = mScrollBeyondZero
|
||||||
? -lowerBound + std::max(halfScreen, mViewInfo.screen - LastTime)
|
? -lowerBound + std::max(halfScreen, screen - LastTime)
|
||||||
: mViewInfo.screen / 4.0;
|
: screen / 4.0;
|
||||||
|
|
||||||
mViewInfo.total = LastTime + additional;
|
mViewInfo.total = LastTime + additional;
|
||||||
|
|
||||||
// Don't remove time from total that's still on the screen
|
// Don't remove time from total that's still on the screen
|
||||||
mViewInfo.total = std::max(mViewInfo.total, mViewInfo.h + mViewInfo.screen);
|
mViewInfo.total = std::max(mViewInfo.total, mViewInfo.h + screen);
|
||||||
|
|
||||||
if (mViewInfo.h < lowerBound) {
|
if (mViewInfo.h < lowerBound) {
|
||||||
mViewInfo.h = lowerBound;
|
mViewInfo.h = lowerBound;
|
||||||
@ -1581,7 +1582,7 @@ void AudacityProject::FixScrollbars()
|
|||||||
}
|
}
|
||||||
|
|
||||||
mViewInfo.sbarTotal = (wxInt64) (mViewInfo.GetTotalWidth());
|
mViewInfo.sbarTotal = (wxInt64) (mViewInfo.GetTotalWidth());
|
||||||
mViewInfo.sbarScreen = (wxInt64) (mViewInfo.GetScreenWidth());
|
mViewInfo.sbarScreen = (wxInt64)(panelWidth);
|
||||||
mViewInfo.sbarH = (wxInt64) (mViewInfo.GetBeforeScreenWidth());
|
mViewInfo.sbarH = (wxInt64) (mViewInfo.GetBeforeScreenWidth());
|
||||||
|
|
||||||
int lastv = mViewInfo.vpos;
|
int lastv = mViewInfo.vpos;
|
||||||
@ -1603,7 +1604,7 @@ void AudacityProject::FixScrollbars()
|
|||||||
|
|
||||||
bool oldhstate;
|
bool oldhstate;
|
||||||
bool oldvstate;
|
bool oldvstate;
|
||||||
bool newhstate = !mViewInfo.ZoomedAll();
|
bool newhstate = (GetScreenEndTime() - mViewInfo.h) < mViewInfo.total;
|
||||||
bool newvstate = panelHeight < totalHeight;
|
bool newvstate = panelHeight < totalHeight;
|
||||||
|
|
||||||
#ifdef __WXGTK__
|
#ifdef __WXGTK__
|
||||||
@ -1614,7 +1615,7 @@ void AudacityProject::FixScrollbars()
|
|||||||
#else
|
#else
|
||||||
oldhstate = mHsbar->IsEnabled();
|
oldhstate = mHsbar->IsEnabled();
|
||||||
oldvstate = mVsbar->IsEnabled();
|
oldvstate = mVsbar->IsEnabled();
|
||||||
mHsbar->Enable(!mViewInfo.ZoomedAll());
|
mHsbar->Enable(newhstate);
|
||||||
mVsbar->Enable(panelHeight < totalHeight);
|
mVsbar->Enable(panelHeight < totalHeight);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1624,7 +1625,7 @@ void AudacityProject::FixScrollbars()
|
|||||||
refresh = true;
|
refresh = true;
|
||||||
rescroll = false;
|
rescroll = false;
|
||||||
}
|
}
|
||||||
if (mViewInfo.ZoomedAll() && mViewInfo.sbarH != 0) {
|
if (!newhstate && mViewInfo.sbarH != 0) {
|
||||||
mViewInfo.sbarH = 0;
|
mViewInfo.sbarH = 0;
|
||||||
|
|
||||||
refresh = true;
|
refresh = true;
|
||||||
@ -1666,7 +1667,8 @@ void AudacityProject::FixScrollbars()
|
|||||||
panelHeight / mViewInfo.scrollStep, TRUE);
|
panelHeight / mViewInfo.scrollStep, TRUE);
|
||||||
mVsbar->Refresh();
|
mVsbar->Refresh();
|
||||||
|
|
||||||
if (refresh || (rescroll && !mViewInfo.ZoomedAll())) {
|
if (refresh || (rescroll &&
|
||||||
|
(GetScreenEndTime() - mViewInfo.h) < mViewInfo.total)) {
|
||||||
mTrackPanel->Refresh(false);
|
mTrackPanel->Refresh(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1849,8 +1851,12 @@ void AudacityProject::OnScroll(wxScrollEvent & WXUNUSED(event))
|
|||||||
mViewInfo.sbarH =
|
mViewInfo.sbarH =
|
||||||
(wxInt64)(mHsbar->GetThumbPosition() / mViewInfo.sbarScale) - offset;
|
(wxInt64)(mHsbar->GetThumbPosition() / mViewInfo.sbarScale) - offset;
|
||||||
|
|
||||||
if (mViewInfo.sbarH != hlast)
|
if (mViewInfo.sbarH != hlast) {
|
||||||
mViewInfo.SetBeforeScreenWidth(mViewInfo.sbarH, lowerBound);
|
int width;
|
||||||
|
mTrackPanel->GetTracksUsableArea(&width, NULL);
|
||||||
|
mViewInfo.SetBeforeScreenWidth(mViewInfo.sbarH, width, lowerBound);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (mScrollBeyondZero) {
|
if (mScrollBeyondZero) {
|
||||||
enum { SCROLL_PIXEL_TOLERANCE = 10 };
|
enum { SCROLL_PIXEL_TOLERANCE = 10 };
|
||||||
|
@ -301,6 +301,7 @@ class AUDACITY_DLL_API AudacityProject: public wxFrame,
|
|||||||
|
|
||||||
void HandleResize();
|
void HandleResize();
|
||||||
void UpdateLayout();
|
void UpdateLayout();
|
||||||
|
double GetScreenEndTime() const;
|
||||||
void ZoomInByFactor( double ZoomFactor );
|
void ZoomInByFactor( double ZoomFactor );
|
||||||
void ZoomOutByFactor( double ZoomFactor );
|
void ZoomOutByFactor( double ZoomFactor );
|
||||||
|
|
||||||
|
@ -503,7 +503,7 @@ void TrackArtist::DrawVRuler(Track *t, wxDC * dc, wxRect & rect)
|
|||||||
// But give it a beveled area
|
// But give it a beveled area
|
||||||
if (kind == Track::Label) {
|
if (kind == Track::Label) {
|
||||||
wxRect bev = rect;
|
wxRect bev = rect;
|
||||||
bev.Inflate(-1, -1);
|
bev.Inflate(-1, 0);
|
||||||
bev.width += 1;
|
bev.width += 1;
|
||||||
AColor::BevelTrackInfo(*dc, true, bev);
|
AColor::BevelTrackInfo(*dc, true, bev);
|
||||||
|
|
||||||
@ -513,7 +513,7 @@ void TrackArtist::DrawVRuler(Track *t, wxDC * dc, wxRect & rect)
|
|||||||
// Time tracks
|
// Time tracks
|
||||||
if (kind == Track::Time) {
|
if (kind == Track::Time) {
|
||||||
wxRect bev = rect;
|
wxRect bev = rect;
|
||||||
bev.Inflate(-1, -1);
|
bev.Inflate(-1, 0);
|
||||||
bev.width += 1;
|
bev.width += 1;
|
||||||
AColor::BevelTrackInfo(*dc, true, bev);
|
AColor::BevelTrackInfo(*dc, true, bev);
|
||||||
|
|
||||||
@ -537,7 +537,7 @@ void TrackArtist::DrawVRuler(Track *t, wxDC * dc, wxRect & rect)
|
|||||||
// The ruler needs a bevelled surround.
|
// The ruler needs a bevelled surround.
|
||||||
if (kind == Track::Wave) {
|
if (kind == Track::Wave) {
|
||||||
wxRect bev = rect;
|
wxRect bev = rect;
|
||||||
bev.Inflate(-1, -1);
|
bev.Inflate(-1, 0);
|
||||||
bev.width += 1;
|
bev.width += 1;
|
||||||
AColor::BevelTrackInfo(*dc, true, bev);
|
AColor::BevelTrackInfo(*dc, true, bev);
|
||||||
|
|
||||||
@ -566,13 +566,11 @@ void TrackArtist::DrawVRuler(Track *t, wxDC * dc, wxRect & rect)
|
|||||||
dc->SetBrush(*wxWHITE_BRUSH);
|
dc->SetBrush(*wxWHITE_BRUSH);
|
||||||
wxRect bev = rect;
|
wxRect bev = rect;
|
||||||
bev.x++;
|
bev.x++;
|
||||||
bev.y++;
|
|
||||||
bev.width--;
|
bev.width--;
|
||||||
bev.height--;
|
|
||||||
dc->DrawRectangle(bev);
|
dc->DrawRectangle(bev);
|
||||||
|
|
||||||
rect.y += 2;
|
rect.y += 1;
|
||||||
rect.height -= 2;
|
rect.height -= 1;
|
||||||
|
|
||||||
//int bottom = GetBottom((NoteTrack *) t, rect);
|
//int bottom = GetBottom((NoteTrack *) t, rect);
|
||||||
NoteTrack *track = (NoteTrack *) t;
|
NoteTrack *track = (NoteTrack *) t;
|
||||||
@ -671,7 +669,7 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & rect)
|
|||||||
min = tt->GetRangeLower() * 100.0;
|
min = tt->GetRangeLower() * 100.0;
|
||||||
max = tt->GetRangeUpper() * 100.0;
|
max = tt->GetRangeUpper() * 100.0;
|
||||||
|
|
||||||
vruler->SetBounds(rect.x, rect.y+1, rect.x + rect.width, rect.y + rect.height-1);
|
vruler->SetBounds(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height-1);
|
||||||
vruler->SetOrientation(wxVERTICAL);
|
vruler->SetOrientation(wxVERTICAL);
|
||||||
vruler->SetRange(max, min);
|
vruler->SetRange(max, min);
|
||||||
vruler->SetFormat((tt->GetDisplayLog()) ? Ruler::RealLogFormat : Ruler::RealFormat);
|
vruler->SetFormat((tt->GetDisplayLog()) ? Ruler::RealLogFormat : Ruler::RealFormat);
|
||||||
@ -720,7 +718,7 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & rect)
|
|||||||
wt->SetDisplayBounds(min, max);
|
wt->SetDisplayBounds(min, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
vruler->SetBounds(rect.x, rect.y + 1, rect.x + rect.width, rect.y + rect.height - 1);
|
vruler->SetBounds(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height - 1);
|
||||||
vruler->SetOrientation(wxVERTICAL);
|
vruler->SetOrientation(wxVERTICAL);
|
||||||
vruler->SetRange(max, min);
|
vruler->SetRange(max, min);
|
||||||
vruler->SetFormat(Ruler::RealFormat);
|
vruler->SetFormat(Ruler::RealFormat);
|
||||||
@ -782,7 +780,7 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & rect)
|
|||||||
botval = -((1 - min) * dBRange);
|
botval = -((1 - min) * dBRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
vruler->SetBounds(rect.x, rect.y + top + 1, rect.x + rect.width, rect.y + bot - 1);
|
vruler->SetBounds(rect.x, rect.y + top, rect.x + rect.width, rect.y + bot - 1);
|
||||||
vruler->SetOrientation(wxVERTICAL);
|
vruler->SetOrientation(wxVERTICAL);
|
||||||
vruler->SetRange(topval, botval);
|
vruler->SetRange(topval, botval);
|
||||||
}
|
}
|
||||||
@ -815,7 +813,7 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & rect)
|
|||||||
we will use Hz if maxFreq is < 2000, otherwise we represent kHz,
|
we will use Hz if maxFreq is < 2000, otherwise we represent kHz,
|
||||||
and append to the numbers a "k"
|
and append to the numbers a "k"
|
||||||
*/
|
*/
|
||||||
vruler->SetBounds(rect.x, rect.y + 1, rect.x + rect.width, rect.y + rect.height - 1);
|
vruler->SetBounds(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height - 1);
|
||||||
vruler->SetOrientation(wxVERTICAL);
|
vruler->SetOrientation(wxVERTICAL);
|
||||||
vruler->SetFormat(Ruler::RealFormat);
|
vruler->SetFormat(Ruler::RealFormat);
|
||||||
vruler->SetLabelEdges(true);
|
vruler->SetLabelEdges(true);
|
||||||
@ -853,7 +851,7 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & rect)
|
|||||||
we will use Hz if maxFreq is < 2000, otherwise we represent kHz,
|
we will use Hz if maxFreq is < 2000, otherwise we represent kHz,
|
||||||
and append to the numbers a "k"
|
and append to the numbers a "k"
|
||||||
*/
|
*/
|
||||||
vruler->SetBounds(rect.x, rect.y + 1, rect.x + rect.width, rect.y + rect.height - 1);
|
vruler->SetBounds(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height - 1);
|
||||||
vruler->SetOrientation(wxVERTICAL);
|
vruler->SetOrientation(wxVERTICAL);
|
||||||
vruler->SetFormat(Ruler::IntFormat);
|
vruler->SetFormat(Ruler::IntFormat);
|
||||||
vruler->SetLabelEdges(true);
|
vruler->SetLabelEdges(true);
|
||||||
@ -873,7 +871,7 @@ void TrackArtist::UpdateVRuler(Track *t, wxRect & rect)
|
|||||||
// The note track isn't drawing a ruler at all!
|
// The note track isn't drawing a ruler at all!
|
||||||
// But it needs to!
|
// But it needs to!
|
||||||
else if (t->GetKind() == Track::Note) {
|
else if (t->GetKind() == Track::Note) {
|
||||||
vruler->SetBounds(rect.x, rect.y+1, rect.x + 1, rect.y + rect.height-1);
|
vruler->SetBounds(rect.x, rect.y, rect.x + 1, rect.y + rect.height-1);
|
||||||
vruler->SetOrientation(wxVERTICAL);
|
vruler->SetOrientation(wxVERTICAL);
|
||||||
}
|
}
|
||||||
#endif // USE_MIDI
|
#endif // USE_MIDI
|
||||||
@ -946,7 +944,10 @@ float ValueOfPixel(int yy, int height, bool offset,
|
|||||||
bool dB, double dBRange, float zoomMin, float zoomMax)
|
bool dB, double dBRange, float zoomMin, float zoomMax)
|
||||||
{
|
{
|
||||||
wxASSERT(height > 0);
|
wxASSERT(height > 0);
|
||||||
float v = zoomMax - (yy / (float)height) * (zoomMax - zoomMin);
|
// Map 0 to max and height - 1 (not height) to min
|
||||||
|
float v =
|
||||||
|
height == 1 ? (zoomMin + zoomMax) / 2 :
|
||||||
|
zoomMax - (yy / (float)(height - 1)) * (zoomMax - zoomMin);
|
||||||
if (offset) {
|
if (offset) {
|
||||||
if (v > 0.0)
|
if (v > 0.0)
|
||||||
v += .5;
|
v += .5;
|
||||||
@ -1662,7 +1663,7 @@ void FindWavePortions
|
|||||||
// the fisheye.
|
// the fisheye.
|
||||||
|
|
||||||
ZoomInfo::Intervals intervals;
|
ZoomInfo::Intervals intervals;
|
||||||
zoomInfo.FindIntervals(params.rate, intervals, rect.x);
|
zoomInfo.FindIntervals(params.rate, intervals, rect.width, rect.x);
|
||||||
ZoomInfo::Intervals::const_iterator it = intervals.begin(), end = intervals.end(), prev;
|
ZoomInfo::Intervals::const_iterator it = intervals.begin(), end = intervals.end(), prev;
|
||||||
wxASSERT(it != end && it->position == rect.x);
|
wxASSERT(it != end && it->position == rect.x);
|
||||||
const int rightmost = rect.x + rect.width;
|
const int rightmost = rect.x + rect.width;
|
||||||
@ -3282,12 +3283,12 @@ void TrackArtist::DrawBackgroundWithSelection(wxDC *dc, const wxRect &rect,
|
|||||||
dc->SetBrush(unselBrush);
|
dc->SetBrush(unselBrush);
|
||||||
dc->DrawRectangle(before);
|
dc->DrawRectangle(before);
|
||||||
|
|
||||||
within.x = before.GetRight();
|
within.x = 1 + before.GetRight();
|
||||||
}
|
}
|
||||||
within.width = rect.x + int(zoomInfo.TimeToPosition(sel1) + 2) - within.x;
|
within.width = rect.x + int(zoomInfo.TimeToPosition(sel1) + 2) - within.x;
|
||||||
|
|
||||||
if (within.GetRight() > rect.GetRight()) {
|
if (within.GetRight() > rect.GetRight()) {
|
||||||
within.width = rect.GetRight() - within.x;
|
within.width = 1 + rect.GetRight() - within.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (within.width > 0) {
|
if (within.width > 0) {
|
||||||
@ -3302,14 +3303,14 @@ void TrackArtist::DrawBackgroundWithSelection(wxDC *dc, const wxRect &rect,
|
|||||||
DrawSyncLockTiles(dc, within);
|
DrawSyncLockTiles(dc, within);
|
||||||
}
|
}
|
||||||
|
|
||||||
after.x = within.GetRight();
|
after.x = 1 + within.GetRight();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// `within` not drawn; start where it would have gone
|
// `within` not drawn; start where it would have gone
|
||||||
after.x = within.x;
|
after.x = within.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
after.width = rect.GetRight() - after.x;
|
after.width = 1 + rect.GetRight() - after.x;
|
||||||
if (after.width > 0) {
|
if (after.width > 0) {
|
||||||
dc->SetBrush(unselBrush);
|
dc->SetBrush(unselBrush);
|
||||||
dc->DrawRectangle(after);
|
dc->DrawRectangle(after);
|
||||||
|
@ -206,9 +206,70 @@ is time to refresh some aspect of the screen.
|
|||||||
|
|
||||||
DEFINE_EVENT_TYPE(EVT_TRACK_PANEL_TIMER)
|
DEFINE_EVENT_TYPE(EVT_TRACK_PANEL_TIMER)
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
This is a diagram of TrackPanel's division of one (non-stereo) track rectangle.
|
||||||
|
Total height equals Track::GetHeight()'s value. Total width is the wxWindow's width.
|
||||||
|
Each charater that is not . represents one pixel.
|
||||||
|
|
||||||
|
Inset space of this track, and top inset of the next track, are used to draw the focus highlight.
|
||||||
|
|
||||||
|
Top inset of the right channel of a stereo track, and bottom shadow line of the
|
||||||
|
left channel, are used for the channel separator.
|
||||||
|
|
||||||
|
TrackInfo::GetTrackInfoWidth() == GetVRulerOffset()
|
||||||
|
counts columns from the left edge up to and including controls, and is a constant.
|
||||||
|
|
||||||
|
GetVRulerWidth() is variable -- all tracks have the same ruler width at any time,
|
||||||
|
but that width may be adjusted when tracks change their vertical scales.
|
||||||
|
|
||||||
|
GetLabelWidth() counts columns up to and including the VRuler.
|
||||||
|
GetLeftOffset() is yet one more -- it counts the "one pixel" column.
|
||||||
|
|
||||||
|
FindTrack() for label returns a rectangle up to and including the One Pixel column,
|
||||||
|
but OMITS left and top insets
|
||||||
|
|
||||||
|
FindTrack() for !label returns a rectangle with x == GetLeftOffset(), and INCLUDES
|
||||||
|
right and top insets
|
||||||
|
|
||||||
|
+--------------- ... ------ ... --------------------- ... ... -------------+
|
||||||
|
| Top Inset |
|
||||||
|
| |
|
||||||
|
| +------------ ... ------ ... --------------------- ... ... ----------+ |
|
||||||
|
| L|+-Border---- ... ------ ... --------------------- ... ... -Border-+ |R |
|
||||||
|
| e||+---------- ... -++--- ... -+++----------------- ... ... -------+| |i |
|
||||||
|
| f|B| || ||| |BS|g |
|
||||||
|
| t|o| Controls || V |O| The good stuff |oh|h |
|
||||||
|
| |r| || R |n| |ra|t |
|
||||||
|
| I|d| || u |e| |dd| |
|
||||||
|
| n|e| || l | | |eo|I |
|
||||||
|
| s|r| || e |P| |rw|n |
|
||||||
|
| e||| || r |i| ||||s |
|
||||||
|
| t||| || |x| ||||e |
|
||||||
|
| ||| || |e| ||||t |
|
||||||
|
| ||| || |l| |||| |
|
||||||
|
| ||| || ||| |||| |
|
||||||
|
|
||||||
|
. ... .. ... .... .
|
||||||
|
. ... .. ... .... .
|
||||||
|
. ... .. ... .... .
|
||||||
|
|
||||||
|
| ||| || ||| |||| |
|
||||||
|
| ||+---------- -++-- ... -+++----------------- ... ... -------+||| |
|
||||||
|
| |+-Border---- ... ----- ... --------------------- ... ... -Border-+|| |
|
||||||
|
| | Shadow---- ... ----- ... --------------------- ... ... --Shadow-+| |
|
||||||
|
*/
|
||||||
enum {
|
enum {
|
||||||
kLeftInset = 4,
|
kLeftInset = 4,
|
||||||
|
kRightInset = kLeftInset,
|
||||||
kTopInset = 4,
|
kTopInset = 4,
|
||||||
|
kShadowThickness = 1,
|
||||||
|
kBorderThickness = 1,
|
||||||
|
kTopMargin = kTopInset + kBorderThickness,
|
||||||
|
kBottomMargin = kShadowThickness + kBorderThickness,
|
||||||
|
kLeftMargin = kLeftInset + kBorderThickness,
|
||||||
|
kRightMargin = kRightInset + kShadowThickness + kBorderThickness,
|
||||||
|
|
||||||
kTimerInterval = 50, // milliseconds
|
kTimerInterval = 50, // milliseconds
|
||||||
kOneSecondCountdown = 1000 / kTimerInterval,
|
kOneSecondCountdown = 1000 / kTimerInterval,
|
||||||
};
|
};
|
||||||
@ -231,15 +292,9 @@ template < class A, class B, class DIST > bool within(A a, B b, DIST d)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < class LOW, class MID, class HIGH >
|
template < class LOW, class MID, class HIGH >
|
||||||
bool between_inclusive(LOW l, MID m, HIGH h)
|
bool between_incexc(LOW l, MID m, HIGH h)
|
||||||
{
|
{
|
||||||
return (m >= l && m <= h);
|
return (m >= l && m < h);
|
||||||
}
|
|
||||||
|
|
||||||
template < class LOW, class MID, class HIGH >
|
|
||||||
bool between_exclusive(LOW l, MID m, HIGH h)
|
|
||||||
{
|
|
||||||
return (m > l && m < h);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template < class CLIPPEE, class CLIPVAL >
|
template < class CLIPPEE, class CLIPVAL >
|
||||||
@ -536,7 +591,7 @@ TrackPanel::TrackPanel(wxWindow * parent, wxWindowID id,
|
|||||||
BuildMenus();
|
BuildMenus();
|
||||||
|
|
||||||
mTrackArtist = new TrackArtist();
|
mTrackArtist = new TrackArtist();
|
||||||
mTrackArtist->SetInset(1, kTopInset + 1, kLeftInset + 2, 2);
|
mTrackArtist->SetInset(1, kTopMargin, kRightMargin, kBottomMargin);
|
||||||
|
|
||||||
mCapturedTrack = NULL;
|
mCapturedTrack = NULL;
|
||||||
mPopupMenuTarget = NULL;
|
mPopupMenuTarget = NULL;
|
||||||
@ -1013,10 +1068,11 @@ void TrackPanel::SelectTrackLength(Track *t)
|
|||||||
void TrackPanel::GetTracksUsableArea(int *width, int *height) const
|
void TrackPanel::GetTracksUsableArea(int *width, int *height) const
|
||||||
{
|
{
|
||||||
GetSize(width, height);
|
GetSize(width, height);
|
||||||
*width -= GetLabelWidth();
|
if (width) {
|
||||||
// AS: MAGIC NUMBER: What does 2 represent?
|
*width -= GetLeftOffset();
|
||||||
*width -= 2 + kLeftInset;
|
*width -= kRightMargin;
|
||||||
*width = std::max(0, *width);
|
*width = std::max(0, *width);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the pointer to the AudacityProject that
|
/// Gets the pointer to the AudacityProject that
|
||||||
@ -1188,14 +1244,22 @@ void TrackPanel::DrawQuickPlayIndicator(wxDC & dc, double pos)
|
|||||||
// Draw the new indicator in its new location
|
// Draw the new indicator in its new location
|
||||||
AColor::Line(dc,
|
AColor::Line(dc,
|
||||||
pos,
|
pos,
|
||||||
y + kTopInset + 1,
|
y + kTopMargin,
|
||||||
pos,
|
pos,
|
||||||
y + t->GetHeight() - 3 );
|
// Minus one more because AColor::Line includes both endpoints
|
||||||
|
y + t->GetHeight() - kBottomMargin - 1 );
|
||||||
}
|
}
|
||||||
mOldQPIndicatorPos = pos;
|
mOldQPIndicatorPos = pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double TrackPanel::GetScreenEndTime() const
|
||||||
|
{
|
||||||
|
int width;
|
||||||
|
GetTracksUsableArea(&width, NULL);
|
||||||
|
return mViewInfo->PositionToTime(width, true);
|
||||||
|
}
|
||||||
|
|
||||||
void TrackPanel::TimerUpdateIndicator()
|
void TrackPanel::TimerUpdateIndicator()
|
||||||
{
|
{
|
||||||
double pos = 0.0;
|
double pos = 0.0;
|
||||||
@ -1209,7 +1273,8 @@ void TrackPanel::TimerUpdateIndicator()
|
|||||||
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
||||||
if (mSmoothScrollingScrub) {
|
if (mSmoothScrollingScrub) {
|
||||||
// Pan the view, so that we center the play indicator.
|
// Pan the view, so that we center the play indicator.
|
||||||
mViewInfo->h = pos - mViewInfo->screen / 2.0;
|
const double duration = GetScreenEndTime() - mViewInfo->h;
|
||||||
|
mViewInfo->h = pos - duration / 2.0;
|
||||||
if (!mScrollBeyondZero)
|
if (!mScrollBeyondZero)
|
||||||
// Can't scroll too far left
|
// Can't scroll too far left
|
||||||
mViewInfo->h = std::max(0.0, mViewInfo->h);
|
mViewInfo->h = std::max(0.0, mViewInfo->h);
|
||||||
@ -1218,9 +1283,9 @@ void TrackPanel::TimerUpdateIndicator()
|
|||||||
#endif
|
#endif
|
||||||
AudacityProject *p = GetProject();
|
AudacityProject *p = GetProject();
|
||||||
const bool
|
const bool
|
||||||
onScreen = between_inclusive(mViewInfo->h,
|
onScreen = between_incexc(mViewInfo->h,
|
||||||
pos,
|
pos,
|
||||||
mViewInfo->h + mViewInfo->screen);
|
GetScreenEndTime());
|
||||||
|
|
||||||
// This displays the audio time, too...
|
// This displays the audio time, too...
|
||||||
DisplaySelection();
|
DisplaySelection();
|
||||||
@ -1263,10 +1328,12 @@ void TrackPanel::UndrawIndicator(wxDC & dc)
|
|||||||
// Erase the old indicator.
|
// Erase the old indicator.
|
||||||
if (mLastIndicatorX != -1)
|
if (mLastIndicatorX != -1)
|
||||||
{
|
{
|
||||||
|
int width;
|
||||||
|
GetTracksUsableArea(&width, NULL);
|
||||||
const bool
|
const bool
|
||||||
onScreen = between_inclusive(GetLeftOffset(),
|
onScreen = between_incexc(GetLeftOffset(),
|
||||||
mLastIndicatorX,
|
mLastIndicatorX,
|
||||||
GetLeftOffset() + mViewInfo->GetScreenWidth());
|
GetLeftOffset() + width);
|
||||||
if (onScreen)
|
if (onScreen)
|
||||||
{
|
{
|
||||||
// LL: Keep from trying to blit outsize of the source DC. This results in a crash on
|
// LL: Keep from trying to blit outsize of the source DC. This results in a crash on
|
||||||
@ -1300,10 +1367,9 @@ void TrackPanel::DoDrawIndicator(wxDC & dc)
|
|||||||
|
|
||||||
// Ensure that we don't draw through the TrackInfo or vertical ruler.
|
// Ensure that we don't draw through the TrackInfo or vertical ruler.
|
||||||
wxRect clip = GetRect();
|
wxRect clip = GetRect();
|
||||||
int leftCutoff = clip.x + GetLabelWidth();
|
int leftCutoff = clip.x + GetLeftOffset();
|
||||||
int rightInset = kLeftInset + 2; // See the call to SetInset
|
int rightCutoff = clip.x + clip.width - kRightMargin;
|
||||||
int rightCutoff = clip.x + clip.width - rightInset;
|
if (!between_incexc(leftCutoff, mLastIndicatorX, rightCutoff))
|
||||||
if (!between_inclusive(leftCutoff, mLastIndicatorX, rightCutoff))
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1324,9 +1390,10 @@ void TrackPanel::DoDrawIndicator(wxDC & dc)
|
|||||||
// Draw the new indicator in its new location
|
// Draw the new indicator in its new location
|
||||||
AColor::Line(dc,
|
AColor::Line(dc,
|
||||||
mLastIndicatorX,
|
mLastIndicatorX,
|
||||||
y + kTopInset + 1,
|
y + kTopMargin,
|
||||||
mLastIndicatorX,
|
mLastIndicatorX,
|
||||||
y + t->GetHeight() - 3 );
|
// Minus one more because AColor::Line includes both endpoints
|
||||||
|
y + t->GetHeight() - kBottomMargin - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1366,9 +1433,11 @@ void TrackPanel::UndrawCursor(wxDC & dc)
|
|||||||
|
|
||||||
if( mLastCursorX != -1 )
|
if( mLastCursorX != -1 )
|
||||||
{
|
{
|
||||||
onScreen = between_inclusive(GetLeftOffset(),
|
int width;
|
||||||
mLastCursorX,
|
GetTracksUsableArea(&width, NULL);
|
||||||
GetLeftOffset() + mViewInfo->GetScreenWidth());
|
onScreen = between_incexc(GetLeftOffset(),
|
||||||
|
mLastCursorX,
|
||||||
|
GetLeftOffset() + width);
|
||||||
if( onScreen )
|
if( onScreen )
|
||||||
dc.Blit(mLastCursorX, 0, 1, mBacking->GetHeight(), &mBackingDC, mLastCursorX, 0);
|
dc.Blit(mLastCursorX, 0, 1, mBacking->GetHeight(), &mBackingDC, mLastCursorX, 0);
|
||||||
}
|
}
|
||||||
@ -1381,9 +1450,9 @@ void TrackPanel::DoDrawCursor(wxDC & dc)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
const bool
|
const bool
|
||||||
onScreen = between_inclusive( mViewInfo->h,
|
onScreen = between_incexc(mViewInfo->h,
|
||||||
mCursorTime,
|
mCursorTime,
|
||||||
mViewInfo->h + mViewInfo->screen );
|
GetScreenEndTime() );
|
||||||
|
|
||||||
if( !onScreen )
|
if( !onScreen )
|
||||||
return;
|
return;
|
||||||
@ -1396,9 +1465,10 @@ void TrackPanel::DoDrawCursor(wxDC & dc)
|
|||||||
{
|
{
|
||||||
if( t->GetSelected() || mAx->IsFocused( t ) )
|
if( t->GetSelected() || mAx->IsFocused( t ) )
|
||||||
{
|
{
|
||||||
int y = t->GetY() - mViewInfo->vpos + 1;
|
int y = t->GetY() - mViewInfo->vpos;
|
||||||
wxCoord top = y + kTopInset;
|
wxCoord top = y + kTopMargin;
|
||||||
wxCoord bottom = y + t->GetHeight() - kTopInset;
|
// Minus one more because AColor::Line includes both endpoints
|
||||||
|
wxCoord bottom = y + t->GetHeight() - kBottomMargin - 1;
|
||||||
|
|
||||||
// MB: warp() is not needed here as far as I know, in fact it creates a bug. Removing it fixes that.
|
// MB: warp() is not needed here as far as I know, in fact it creates a bug. Removing it fixes that.
|
||||||
AColor::Line(dc, mLastCursorX, top, mLastCursorX, bottom); // <-- The whole point of this routine.
|
AColor::Line(dc, mLastCursorX, top, mLastCursorX, bottom); // <-- The whole point of this routine.
|
||||||
@ -1608,12 +1678,12 @@ void TrackPanel::HandleControlKey(bool down)
|
|||||||
|
|
||||||
void TrackPanel::HandlePageUpKey()
|
void TrackPanel::HandlePageUpKey()
|
||||||
{
|
{
|
||||||
mListener->TP_ScrollWindow(mViewInfo->h + mViewInfo->screen);
|
mListener->TP_ScrollWindow(GetScreenEndTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackPanel::HandlePageDownKey()
|
void TrackPanel::HandlePageDownKey()
|
||||||
{
|
{
|
||||||
mListener->TP_ScrollWindow(mViewInfo->h - mViewInfo->screen);
|
mListener->TP_ScrollWindow(2 * mViewInfo->h - GetScreenEndTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackPanel::HandleCursorForLastMouseEvent()
|
void TrackPanel::HandleCursorForLastMouseEvent()
|
||||||
@ -2252,7 +2322,7 @@ double TrackPanel::FindScrubSpeed(double timeAtMouse) const
|
|||||||
// and the extremes to the maximum scrub speed.
|
// and the extremes to the maximum scrub speed.
|
||||||
|
|
||||||
// Width of visible track area, in time terms:
|
// Width of visible track area, in time terms:
|
||||||
const double screen = mViewInfo->screen;
|
const double screen = GetScreenEndTime() - mViewInfo->h;
|
||||||
const double origin = mViewInfo->h + screen / 2.0;
|
const double origin = mViewInfo->h + screen / 2.0;
|
||||||
|
|
||||||
// There are various snapping zones that are this fraction of screen:
|
// There are various snapping zones that are this fraction of screen:
|
||||||
@ -2299,7 +2369,7 @@ double TrackPanel::FindSeekSpeed(double timeAtMouse) const
|
|||||||
const double extreme = std::max(1.0, mMaxScrubSpeed * ARBITRARY_MULTIPLIER);
|
const double extreme = std::max(1.0, mMaxScrubSpeed * ARBITRARY_MULTIPLIER);
|
||||||
|
|
||||||
// Width of visible track area, in time terms:
|
// Width of visible track area, in time terms:
|
||||||
const double screen = mViewInfo->screen;
|
const double screen = GetScreenEndTime() - mViewInfo->h;
|
||||||
const double halfScreen = screen / 2.0;
|
const double halfScreen = screen / 2.0;
|
||||||
const double origin = mViewInfo->h + halfScreen;
|
const double origin = mViewInfo->h + halfScreen;
|
||||||
|
|
||||||
@ -2478,6 +2548,8 @@ void TrackPanel::SelectionHandleClick(wxMouseEvent & event,
|
|||||||
{
|
{
|
||||||
Track *rightTrack = NULL;
|
Track *rightTrack = NULL;
|
||||||
mCapturedTrack = pTrack;
|
mCapturedTrack = pTrack;
|
||||||
|
rect.y += kTopMargin;
|
||||||
|
rect.height -= kTopMargin + kBottomMargin;
|
||||||
mCapturedRect = rect;
|
mCapturedRect = rect;
|
||||||
|
|
||||||
mMouseCapture=IsSelecting;
|
mMouseCapture=IsSelecting;
|
||||||
@ -3352,9 +3424,11 @@ void TrackPanel::SelectionHandleDrag(wxMouseEvent & event, Track *clickedTrack)
|
|||||||
wxRect rect = mCapturedRect;
|
wxRect rect = mCapturedRect;
|
||||||
Track *pTrack = mCapturedTrack;
|
Track *pTrack = mCapturedTrack;
|
||||||
|
|
||||||
// AS: Note that FindTrack will replace rect's value.
|
if (!pTrack) {
|
||||||
if (!pTrack)
|
|
||||||
pTrack = FindTrack(event.m_x, event.m_y, false, false, &rect);
|
pTrack = FindTrack(event.m_x, event.m_y, false, false, &rect);
|
||||||
|
rect.y += kTopMargin;
|
||||||
|
rect.height -= kTopMargin + kBottomMargin;
|
||||||
|
}
|
||||||
|
|
||||||
// Also fuhggeddaboudit if not in a track.
|
// Also fuhggeddaboudit if not in a track.
|
||||||
if (!pTrack)
|
if (!pTrack)
|
||||||
@ -3643,8 +3717,8 @@ void TrackPanel::HandleEnvelope(wxMouseEvent & event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
mCapturedRect = rect;
|
mCapturedRect = rect;
|
||||||
mCapturedRect.y += kTopInset;
|
mCapturedRect.y += kTopMargin;
|
||||||
mCapturedRect.height -= kTopInset;
|
mCapturedRect.height -= kTopMargin + kBottomMargin;
|
||||||
}
|
}
|
||||||
// AS: if there's actually a selected track, then forward all of the
|
// AS: if there's actually a selected track, then forward all of the
|
||||||
// mouse events to its envelope.
|
// mouse events to its envelope.
|
||||||
@ -3670,8 +3744,6 @@ void TrackPanel::ForwardEventToTimeTrackEnvelope(wxMouseEvent & event)
|
|||||||
Envelope *pspeedenvelope = ptimetrack->GetEnvelope();
|
Envelope *pspeedenvelope = ptimetrack->GetEnvelope();
|
||||||
|
|
||||||
wxRect envRect = mCapturedRect;
|
wxRect envRect = mCapturedRect;
|
||||||
envRect.y++;
|
|
||||||
envRect.height -= 2;
|
|
||||||
double lower = ptimetrack->GetRangeLower(), upper = ptimetrack->GetRangeUpper();
|
double lower = ptimetrack->GetRangeLower(), upper = ptimetrack->GetRangeUpper();
|
||||||
const double dBRange = mViewInfo->dBr;
|
const double dBRange = mViewInfo->dBr;
|
||||||
if (ptimetrack->GetDisplayLog()) {
|
if (ptimetrack->GetDisplayLog()) {
|
||||||
@ -3713,8 +3785,6 @@ void TrackPanel::ForwardEventToWaveTrackEnvelope(wxMouseEvent & event)
|
|||||||
// AS: Then forward our mouse event to the envelope.
|
// AS: Then forward our mouse event to the envelope.
|
||||||
// It'll recalculate and then tell us whether or not to redraw.
|
// It'll recalculate and then tell us whether or not to redraw.
|
||||||
wxRect envRect = mCapturedRect;
|
wxRect envRect = mCapturedRect;
|
||||||
envRect.y++;
|
|
||||||
envRect.height -= 2;
|
|
||||||
float zoomMin, zoomMax;
|
float zoomMin, zoomMax;
|
||||||
pwavetrack->GetDisplayBounds(&zoomMin, &zoomMax);
|
pwavetrack->GetDisplayBounds(&zoomMin, &zoomMax);
|
||||||
needUpdate = penvelope->MouseEvent(
|
needUpdate = penvelope->MouseEvent(
|
||||||
@ -3732,8 +3802,6 @@ void TrackPanel::ForwardEventToWaveTrackEnvelope(wxMouseEvent & event)
|
|||||||
bool updateNeeded = false;
|
bool updateNeeded = false;
|
||||||
if (e2) {
|
if (e2) {
|
||||||
wxRect envRect = mCapturedRect;
|
wxRect envRect = mCapturedRect;
|
||||||
envRect.y++;
|
|
||||||
envRect.height -= 2;
|
|
||||||
float zoomMin, zoomMax;
|
float zoomMin, zoomMax;
|
||||||
pwavetrack->GetDisplayBounds(&zoomMin, &zoomMax);
|
pwavetrack->GetDisplayBounds(&zoomMin, &zoomMax);
|
||||||
updateNeeded = e2->MouseEvent(event, envRect,
|
updateNeeded = e2->MouseEvent(event, envRect,
|
||||||
@ -3746,8 +3814,6 @@ void TrackPanel::ForwardEventToWaveTrackEnvelope(wxMouseEvent & event)
|
|||||||
if( (e2 = link->GetActiveEnvelope()) != 0 ) // search for any active DragPoint
|
if( (e2 = link->GetActiveEnvelope()) != 0 ) // search for any active DragPoint
|
||||||
{
|
{
|
||||||
wxRect envRect = mCapturedRect;
|
wxRect envRect = mCapturedRect;
|
||||||
envRect.y++;
|
|
||||||
envRect.height -= 2;
|
|
||||||
float zoomMin, zoomMax;
|
float zoomMin, zoomMax;
|
||||||
pwavetrack->GetDisplayBounds(&zoomMin, &zoomMax);
|
pwavetrack->GetDisplayBounds(&zoomMin, &zoomMax);
|
||||||
needUpdate |= e2->MouseEvent(event, envRect,
|
needUpdate |= e2->MouseEvent(event, envRect,
|
||||||
@ -4092,8 +4158,8 @@ void TrackPanel::DoSlide(wxMouseEvent & event)
|
|||||||
if (mouseTrack == NULL) {
|
if (mouseTrack == NULL) {
|
||||||
// Allow sliding if the pointer is not over any track, but only if x is
|
// Allow sliding if the pointer is not over any track, but only if x is
|
||||||
// within the bounds of the tracks area.
|
// within the bounds of the tracks area.
|
||||||
int width, height;
|
int width;
|
||||||
GetTracksUsableArea(&width, &height);
|
GetTracksUsableArea(&width, NULL);
|
||||||
if (event.m_x >= GetLeftOffset() && event.m_x < GetLeftOffset() + width)
|
if (event.m_x >= GetLeftOffset() && event.m_x < GetLeftOffset() + width)
|
||||||
mouseTrack = mCapturedTrack;
|
mouseTrack = mCapturedTrack;
|
||||||
else
|
else
|
||||||
@ -4383,18 +4449,16 @@ void TrackPanel::HandleZoomClick(wxMouseEvent & event)
|
|||||||
/// Zoom drag
|
/// Zoom drag
|
||||||
void TrackPanel::HandleZoomDrag(wxMouseEvent & event)
|
void TrackPanel::HandleZoomDrag(wxMouseEvent & event)
|
||||||
{
|
{
|
||||||
int left, width, height;
|
const int left = GetLeftOffset();
|
||||||
|
const int right = GetSize().x - kRightMargin - 1;
|
||||||
left = GetLeftOffset();
|
|
||||||
GetTracksUsableArea(&width, &height);
|
|
||||||
|
|
||||||
mZoomEnd = event.m_x;
|
mZoomEnd = event.m_x;
|
||||||
|
|
||||||
if (event.m_x < left) {
|
if (event.m_x < left) {
|
||||||
mZoomEnd = left;
|
mZoomEnd = left;
|
||||||
}
|
}
|
||||||
else if (event.m_x >= left + width - 1) {
|
else if (event.m_x > right) {
|
||||||
mZoomEnd = left + width - 1;
|
mZoomEnd = right;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsDragZooming()) {
|
if (IsDragZooming()) {
|
||||||
@ -4405,11 +4469,8 @@ void TrackPanel::HandleZoomDrag(wxMouseEvent & event)
|
|||||||
/// Zoom button up
|
/// Zoom button up
|
||||||
void TrackPanel::HandleZoomButtonUp(wxMouseEvent & event)
|
void TrackPanel::HandleZoomButtonUp(wxMouseEvent & event)
|
||||||
{
|
{
|
||||||
if (mZoomEnd < mZoomStart) {
|
if (mZoomEnd < mZoomStart)
|
||||||
int temp = mZoomEnd;
|
std::swap(mZoomStart, mZoomEnd);
|
||||||
mZoomEnd = mZoomStart;
|
|
||||||
mZoomStart = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsDragZooming())
|
if (IsDragZooming())
|
||||||
DragZoom(event, GetLeftOffset());
|
DragZoom(event, GetLeftOffset());
|
||||||
@ -4443,8 +4504,7 @@ void TrackPanel::DragZoom(wxMouseEvent & event, int trackLeftEdge)
|
|||||||
{
|
{
|
||||||
double left = mViewInfo->PositionToTime(mZoomStart, trackLeftEdge);
|
double left = mViewInfo->PositionToTime(mZoomStart, trackLeftEdge);
|
||||||
double right = mViewInfo->PositionToTime(mZoomEnd, trackLeftEdge);
|
double right = mViewInfo->PositionToTime(mZoomEnd, trackLeftEdge);
|
||||||
|
double multiplier = (GetScreenEndTime() - mViewInfo->h) / (right - left);
|
||||||
double multiplier = mViewInfo->screen / (right - left);
|
|
||||||
if (event.ShiftDown())
|
if (event.ShiftDown())
|
||||||
multiplier = 1.0 / multiplier;
|
multiplier = 1.0 / multiplier;
|
||||||
|
|
||||||
@ -4601,8 +4661,8 @@ void TrackPanel::HandleWaveTrackVZoom
|
|||||||
bool fixedMousePoint)
|
bool fixedMousePoint)
|
||||||
{
|
{
|
||||||
WaveTrack *const partner = static_cast<WaveTrack *>(tracks->GetLink(track));
|
WaveTrack *const partner = static_cast<WaveTrack *>(tracks->GetLink(track));
|
||||||
int height = track->GetHeight();
|
int height = track->GetHeight() - (kTopMargin + kBottomMargin);
|
||||||
int ypos = rect.y;
|
int ypos = rect.y + kBorderThickness;
|
||||||
|
|
||||||
// Ensure start and end are in order (swap if not).
|
// Ensure start and end are in order (swap if not).
|
||||||
if (zoomEnd < zoomStart)
|
if (zoomEnd < zoomStart)
|
||||||
@ -4825,14 +4885,14 @@ void TrackPanel::HandleWaveTrackVZoom
|
|||||||
namespace {
|
namespace {
|
||||||
// Is the sample horizontally nearest to the cursor sufficiently separated from
|
// Is the sample horizontally nearest to the cursor sufficiently separated from
|
||||||
// its neighbors that the pencil tool should be allowed to drag it?
|
// its neighbors that the pencil tool should be allowed to drag it?
|
||||||
bool SampleResolutionTest(const ViewInfo &viewInfo, const WaveTrack *wt, double time, double rate)
|
bool SampleResolutionTest(const ViewInfo &viewInfo, const WaveTrack *wt, double time, double rate, int width)
|
||||||
{
|
{
|
||||||
// Require more than 3 pixels per sample
|
// Require more than 3 pixels per sample
|
||||||
// Round to an exact sample time
|
// Round to an exact sample time
|
||||||
const double adjustedTime = wt->LongSamplesToTime(wt->TimeToLongSamples(time));
|
const double adjustedTime = wt->LongSamplesToTime(wt->TimeToLongSamples(time));
|
||||||
const wxInt64 xx = std::max(wxInt64(0), viewInfo.TimeToPosition(adjustedTime));
|
const wxInt64 xx = std::max(wxInt64(0), viewInfo.TimeToPosition(adjustedTime));
|
||||||
ZoomInfo::Intervals intervals;
|
ZoomInfo::Intervals intervals;
|
||||||
viewInfo.FindIntervals(rate, intervals);
|
viewInfo.FindIntervals(rate, intervals, width);
|
||||||
ZoomInfo::Intervals::const_iterator it = intervals.begin(), end = intervals.end(), prev;
|
ZoomInfo::Intervals::const_iterator it = intervals.begin(), end = intervals.end(), prev;
|
||||||
wxASSERT(it != end && it->position == 0);
|
wxASSERT(it != end && it->position == 0);
|
||||||
do
|
do
|
||||||
@ -4874,7 +4934,9 @@ bool TrackPanel::IsSampleEditingPossible( wxMouseEvent &event, Track * t )
|
|||||||
WaveTrack *const wt = static_cast<WaveTrack*>(t);
|
WaveTrack *const wt = static_cast<WaveTrack*>(t);
|
||||||
const double rate = wt->GetRate();
|
const double rate = wt->GetRate();
|
||||||
const double time = mViewInfo->PositionToTime(event.m_x, rect.x);
|
const double time = mViewInfo->PositionToTime(event.m_x, rect.x);
|
||||||
showPoints = SampleResolutionTest(*mViewInfo, wt, time, rate);
|
int width;
|
||||||
|
GetTracksUsableArea(&width, NULL);
|
||||||
|
showPoints = SampleResolutionTest(*mViewInfo, wt, time, rate, width);
|
||||||
}
|
}
|
||||||
|
|
||||||
//If we aren't zoomed in far enough, show a message dialog.
|
//If we aren't zoomed in far enough, show a message dialog.
|
||||||
@ -4893,7 +4955,7 @@ float TrackPanel::FindSampleEditingLevel(wxMouseEvent &event, double dBRange, do
|
|||||||
mDrawingTrack->GetDisplayBounds(&zoomMin, &zoomMax);
|
mDrawingTrack->GetDisplayBounds(&zoomMin, &zoomMax);
|
||||||
|
|
||||||
const int y = event.m_y - mDrawingTrackTop;
|
const int y = event.m_y - mDrawingTrackTop;
|
||||||
const int height = mDrawingTrack->GetHeight();
|
const int height = mDrawingTrack->GetHeight() - (kTopMargin + kBottomMargin);
|
||||||
const bool dB = !mDrawingTrack->GetWaveformSettings().isLinear();
|
const bool dB = !mDrawingTrack->GetWaveformSettings().isLinear();
|
||||||
float newLevel =
|
float newLevel =
|
||||||
::ValueOfPixel(y, height, false, dB, dBRange, zoomMin, zoomMax);
|
::ValueOfPixel(y, height, false, dB, dBRange, zoomMin, zoomMax);
|
||||||
@ -4934,7 +4996,7 @@ void TrackPanel::HandleSampleEditingClick( wxMouseEvent & event )
|
|||||||
|
|
||||||
/// \todo Should mCapturedTrack take the place of mDrawingTrack??
|
/// \todo Should mCapturedTrack take the place of mDrawingTrack??
|
||||||
mDrawingTrack = static_cast<WaveTrack*>(t);
|
mDrawingTrack = static_cast<WaveTrack*>(t);
|
||||||
mDrawingTrackTop=rect.y;
|
mDrawingTrackTop=rect.y + kTopMargin;
|
||||||
|
|
||||||
//If we are still around, we are drawing in earnest. Set some member data structures up:
|
//If we are still around, we are drawing in earnest. Set some member data structures up:
|
||||||
//First, calculate the starting sample. To get this, we need the time
|
//First, calculate the starting sample. To get this, we need the time
|
||||||
@ -6232,7 +6294,7 @@ void TrackPanel::HandleWheelRotation(wxMouseEvent & event)
|
|||||||
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
||||||
if (mSmoothScrollingScrub) {
|
if (mSmoothScrollingScrub) {
|
||||||
// Expand or contract about the center, ignoring mouse position
|
// Expand or contract about the center, ignoring mouse position
|
||||||
center_h = mViewInfo->h + mViewInfo->screen / 2.0;
|
center_h = mViewInfo->h + (GetScreenEndTime() - mViewInfo->h) / 2.0;
|
||||||
xx = mViewInfo->TimeToPosition(center_h, trackLeftEdge);
|
xx = mViewInfo->TimeToPosition(center_h, trackLeftEdge);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -6697,8 +6759,7 @@ bool TrackPanel::HandleLabelTrackClick(LabelTrack * lTrack, wxRect &rect, wxMous
|
|||||||
}
|
}
|
||||||
|
|
||||||
mCapturedRect = rect;
|
mCapturedRect = rect;
|
||||||
mCapturedRect.x += kLeftInset;
|
mCapturedRect.width -= kRightMargin;
|
||||||
mCapturedRect.width -= kLeftInset;
|
|
||||||
|
|
||||||
lTrack->HandleClick(event, mCapturedRect, *mViewInfo, &mViewInfo->selectedRegion);
|
lTrack->HandleClick(event, mCapturedRect, *mViewInfo, &mViewInfo->selectedRegion);
|
||||||
|
|
||||||
@ -7112,7 +7173,9 @@ bool TrackPanel::HitTestSamples(Track *track, wxRect &rect, wxMouseEvent & event
|
|||||||
const bool dB = !wavetrack->GetWaveformSettings().isLinear();
|
const bool dB = !wavetrack->GetWaveformSettings().isLinear();
|
||||||
|
|
||||||
const double tt = mViewInfo->PositionToTime(event.m_x, rect.x);
|
const double tt = mViewInfo->PositionToTime(event.m_x, rect.x);
|
||||||
if (!SampleResolutionTest(*mViewInfo, wavetrack, tt, rate))
|
int width;
|
||||||
|
GetTracksUsableArea(&width, NULL);
|
||||||
|
if (!SampleResolutionTest(*mViewInfo, wavetrack, tt, rate, width))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Just get one sample.
|
// Just get one sample.
|
||||||
@ -7178,10 +7241,12 @@ void TrackPanel::RefreshTrack(Track *trk, bool refreshbacking)
|
|||||||
link = trk->GetLink();
|
link = trk->GetLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// subtract insets and shadows from the rectangle, but not border
|
||||||
|
// This matters because some separators do paint over the border
|
||||||
wxRect rect(kLeftInset,
|
wxRect rect(kLeftInset,
|
||||||
-mViewInfo->vpos + trk->GetY() + kTopInset,
|
-mViewInfo->vpos + trk->GetY() + kTopInset,
|
||||||
GetRect().GetWidth() - kLeftInset * 2 - 1,
|
GetRect().GetWidth() - kLeftInset - kRightInset - kShadowThickness,
|
||||||
trk->GetHeight() - kTopInset - 1);
|
trk->GetHeight() - kTopInset - kShadowThickness);
|
||||||
|
|
||||||
if (link) {
|
if (link) {
|
||||||
rect.height += link->GetHeight();
|
rect.height += link->GetHeight();
|
||||||
@ -7332,9 +7397,9 @@ void TrackPanel::DrawEverythingElse(wxDC * dc,
|
|||||||
if (region.Contains(0, trackRect.y, GetLeftOffset(), trackRect.height)) {
|
if (region.Contains(0, trackRect.y, GetLeftOffset(), trackRect.height)) {
|
||||||
wxRect rect = trackRect;
|
wxRect rect = trackRect;
|
||||||
rect.x += GetVRulerOffset();
|
rect.x += GetVRulerOffset();
|
||||||
rect.y += kTopInset;
|
rect.y += kTopMargin;
|
||||||
rect.width = GetVRulerWidth();
|
rect.width = GetVRulerWidth();
|
||||||
rect.height -= (kTopInset + 2);
|
rect.height -= (kTopMargin + kBottomMargin);
|
||||||
mTrackArtist->DrawVRuler(t, dc, rect);
|
mTrackArtist->DrawVRuler(t, dc, rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7345,9 +7410,9 @@ void TrackPanel::DrawEverythingElse(wxDC * dc,
|
|||||||
if (region.Contains(0, trackRect.y, GetLeftOffset(), trackRect.height)) {
|
if (region.Contains(0, trackRect.y, GetLeftOffset(), trackRect.height)) {
|
||||||
wxRect rect = trackRect;
|
wxRect rect = trackRect;
|
||||||
rect.x += GetVRulerOffset();
|
rect.x += GetVRulerOffset();
|
||||||
rect.y += kTopInset;
|
rect.y += kTopMargin;
|
||||||
rect.width = GetVRulerWidth();
|
rect.width = GetVRulerWidth();
|
||||||
rect.height -= (kTopInset + 2);
|
rect.height -= (kTopMargin + kBottomMargin);
|
||||||
mTrackArtist->DrawVRuler(t, dc, rect);
|
mTrackArtist->DrawVRuler(t, dc, rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7573,18 +7638,17 @@ void TrackPanel::DrawZooming(wxDC * dc, const wxRect & clip)
|
|||||||
dc->SetPen(*wxBLACK_DASHED_PEN);
|
dc->SetPen(*wxBLACK_DASHED_PEN);
|
||||||
|
|
||||||
if (mMouseCapture==IsVZooming) {
|
if (mMouseCapture==IsVZooming) {
|
||||||
int width, height;
|
rect.y = std::min(mZoomStart, mZoomEnd);
|
||||||
GetTracksUsableArea(&width, &height);
|
rect.height = 1 + abs(mZoomEnd - mZoomStart);
|
||||||
|
|
||||||
rect.y = mZoomStart;
|
|
||||||
rect.x = GetVRulerOffset();
|
rect.x = GetVRulerOffset();
|
||||||
rect.width = width + GetVRulerWidth() + 1; //+1 extends into border rect
|
rect.SetRight(GetSize().x - kRightMargin); // extends into border rect
|
||||||
rect.height = mZoomEnd - mZoomStart;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rect.x = mZoomStart;
|
rect.x = std::min(mZoomStart, mZoomEnd);
|
||||||
|
rect.width = 1 + abs(mZoomEnd - mZoomStart);
|
||||||
|
|
||||||
rect.y = -1;
|
rect.y = -1;
|
||||||
rect.width = mZoomEnd - mZoomStart;
|
|
||||||
rect.height = clip.height + 2;
|
rect.height = clip.height + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7752,9 +7816,11 @@ void TrackPanel::DrawOutsideOfTrack(Track * t, wxDC * dc, const wxRect & rect)
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (t->GetLinked()) {
|
if (t->GetLinked()) {
|
||||||
|
// Paint the channel separator over (what would be) the shadow of the top
|
||||||
|
// channel, and the top inset of the bottom channel
|
||||||
side = rect;
|
side = rect;
|
||||||
side.y += t->GetHeight() - 1;
|
side.y += t->GetHeight() - kShadowThickness;
|
||||||
side.height = kTopInset + 1;
|
side.height = kTopInset + kShadowThickness;
|
||||||
dc->DrawRectangle(side);
|
dc->DrawRectangle(side);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -7888,20 +7954,20 @@ void TrackPanel::UpdateTrackVRuler(Track *t)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
wxRect rect(GetVRulerOffset(),
|
wxRect rect(GetVRulerOffset(),
|
||||||
kTopInset,
|
kTopMargin,
|
||||||
GetVRulerWidth(),
|
GetVRulerWidth(),
|
||||||
t->GetHeight() - (kTopInset + 2));
|
t->GetHeight() - (kTopMargin + kBottomMargin));
|
||||||
|
|
||||||
mTrackArtist->UpdateVRuler(t, rect);
|
mTrackArtist->UpdateVRuler(t, rect);
|
||||||
Track *l = t->GetLink();
|
Track *l = t->GetLink();
|
||||||
if (l)
|
if (l)
|
||||||
{
|
{
|
||||||
rect.height = l->GetHeight() - (kTopInset + 2);
|
rect.height = l->GetHeight() - (kTopMargin + kBottomMargin);
|
||||||
mTrackArtist->UpdateVRuler(l, rect);
|
mTrackArtist->UpdateVRuler(l, rect);
|
||||||
}
|
}
|
||||||
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
|
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
|
||||||
else if(MONO_WAVE_PAN(t)){
|
else if(MONO_WAVE_PAN(t)){
|
||||||
rect.height = t->GetHeight(true) - (kTopInset + 2);
|
rect.height = t->GetHeight(true) - (kTopMargin + kBottomMargin);
|
||||||
mTrackArtist->UpdateVRuler(t, rect);
|
mTrackArtist->UpdateVRuler(t, rect);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -8192,14 +8258,11 @@ void TrackPanel::OnToggle()
|
|||||||
// Make sure selection edge is in view
|
// Make sure selection edge is in view
|
||||||
void TrackPanel::ScrollIntoView(double pos)
|
void TrackPanel::ScrollIntoView(double pos)
|
||||||
{
|
{
|
||||||
const int screenWidth = rint(mViewInfo->GetScreenWidth());
|
int w;
|
||||||
|
GetTracksUsableArea( &w, NULL );
|
||||||
int w, h;
|
|
||||||
GetTracksUsableArea( &w, &h );
|
|
||||||
// Or should we just set w = screenWidth ?
|
|
||||||
|
|
||||||
int pixel = mViewInfo->TimeToPosition(pos);
|
int pixel = mViewInfo->TimeToPosition(pos);
|
||||||
if (pixel < 0 || pixel >= screenWidth)
|
if (pixel < 0 || pixel >= w)
|
||||||
{
|
{
|
||||||
mListener->TP_ScrollWindow
|
mListener->TP_ScrollWindow
|
||||||
(mViewInfo->OffsetTimeByPixels(pos, -(w / 2)));
|
(mViewInfo->OffsetTimeByPixels(pos, -(w / 2)));
|
||||||
@ -9041,8 +9104,11 @@ void TrackPanel::DrawBordersAroundTrack(Track * t, wxDC * dc,
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (t->GetLinked()) {
|
if (t->GetLinked()) {
|
||||||
|
// The given rect has had the top inset subtracted
|
||||||
int h1 = rect.y + t->GetHeight() - kTopInset;
|
int h1 = rect.y + t->GetHeight() - kTopInset;
|
||||||
AColor::Line(*dc, vrul, h1 - 2, rect.x + rect.width - 1, h1 - 2);
|
// h1 is the top coordinate of the second tracks' rectangle
|
||||||
|
// Draw (part of) the bottom border of the top channel and top border of the bottom
|
||||||
|
AColor::Line(*dc, vrul, h1 - kBottomMargin, rect.x + rect.width - 1, h1 - kBottomMargin);
|
||||||
AColor::Line(*dc, vrul, h1 + kTopInset, rect.x + rect.width - 1, h1 + kTopInset);
|
AColor::Line(*dc, vrul, h1 + kTopInset, rect.x + rect.width - 1, h1 + kTopInset);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -9913,6 +9979,9 @@ void TrackPanel::OnSetFont(wxCommandEvent & WXUNUSED(event))
|
|||||||
Track *TrackPanel::FindTrack(int mouseX, int mouseY, bool label, bool link,
|
Track *TrackPanel::FindTrack(int mouseX, int mouseY, bool label, bool link,
|
||||||
wxRect * trackRect)
|
wxRect * trackRect)
|
||||||
{
|
{
|
||||||
|
// If label is true, resulting rectangle OMITS left and top insets.
|
||||||
|
// If label is false, resulting rectangle INCLUDES right and top insets.
|
||||||
|
|
||||||
wxRect rect;
|
wxRect rect;
|
||||||
rect.x = 0;
|
rect.x = 0;
|
||||||
rect.y = -mViewInfo->vpos;
|
rect.y = -mViewInfo->vpos;
|
||||||
|
@ -165,6 +165,8 @@ class AUDACITY_DLL_API TrackPanel:public wxPanel {
|
|||||||
|
|
||||||
virtual int GetLeftOffset() const { return GetLabelWidth() + 1;}
|
virtual int GetLeftOffset() const { return GetLabelWidth() + 1;}
|
||||||
|
|
||||||
|
// Width and height, relative to upper left corner at (GetLeftOffset(), 0)
|
||||||
|
// Either argument may be NULL
|
||||||
virtual void GetTracksUsableArea(int *width, int *height) const;
|
virtual void GetTracksUsableArea(int *width, int *height) const;
|
||||||
|
|
||||||
virtual void SelectNone();
|
virtual void SelectNone();
|
||||||
@ -232,6 +234,10 @@ class AUDACITY_DLL_API TrackPanel:public wxPanel {
|
|||||||
|
|
||||||
virtual void DrawQuickPlayIndicator(wxDC & dc, double pos);
|
virtual void DrawQuickPlayIndicator(wxDC & dc, double pos);
|
||||||
|
|
||||||
|
// Returns the time corresponding to the pixel column one past the track area
|
||||||
|
// (ignoring any fisheye)
|
||||||
|
virtual double GetScreenEndTime() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual MixerBoard* GetMixerBoard();
|
virtual MixerBoard* GetMixerBoard();
|
||||||
/** @brief Populates the track pop-down menu with the common set of
|
/** @brief Populates the track pop-down menu with the common set of
|
||||||
|
@ -22,10 +22,9 @@ static const double gMaxZoom = 6000000;
|
|||||||
static const double gMinZoom = 0.001;
|
static const double gMinZoom = 0.001;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZoomInfo::ZoomInfo(double start, double screenDuration, double pixelsPerSecond)
|
ZoomInfo::ZoomInfo(double start, double pixelsPerSecond)
|
||||||
: vpos(0)
|
: vpos(0)
|
||||||
, h(start)
|
, h(start)
|
||||||
, screen(screenDuration)
|
|
||||||
, zoom(pixelsPerSecond)
|
, zoom(pixelsPerSecond)
|
||||||
{
|
{
|
||||||
UpdatePrefs();
|
UpdatePrefs();
|
||||||
@ -84,12 +83,12 @@ void ZoomInfo::ZoomBy(double multiplier)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ZoomInfo::FindIntervals
|
void ZoomInfo::FindIntervals
|
||||||
(double /*rate*/, Intervals &results, wxInt64 origin) const
|
(double /*rate*/, Intervals &results, wxInt64 width, wxInt64 origin) const
|
||||||
{
|
{
|
||||||
results.clear();
|
results.clear();
|
||||||
results.reserve(2);
|
results.reserve(2);
|
||||||
|
|
||||||
const wxInt64 rightmost(origin + (0.5 + screen * zoom));
|
const wxInt64 rightmost(origin + (0.5 + width));
|
||||||
wxASSERT(origin <= rightmost);
|
wxASSERT(origin <= rightmost);
|
||||||
{
|
{
|
||||||
results.push_back(Interval(origin, zoom, false));
|
results.push_back(Interval(origin, zoom, false));
|
||||||
@ -101,10 +100,10 @@ void ZoomInfo::FindIntervals
|
|||||||
}
|
}
|
||||||
|
|
||||||
ViewInfo::ViewInfo(double start, double screenDuration, double pixelsPerSecond)
|
ViewInfo::ViewInfo(double start, double screenDuration, double pixelsPerSecond)
|
||||||
: ZoomInfo(start, screenDuration, pixelsPerSecond)
|
: ZoomInfo(start, pixelsPerSecond)
|
||||||
, selectedRegion()
|
, selectedRegion()
|
||||||
, track(NULL)
|
, track(NULL)
|
||||||
, total(screen)
|
, total(screenDuration)
|
||||||
, sbarH(0)
|
, sbarH(0)
|
||||||
, sbarScreen(1)
|
, sbarScreen(1)
|
||||||
, sbarTotal(1)
|
, sbarTotal(1)
|
||||||
@ -114,12 +113,12 @@ ViewInfo::ViewInfo(double start, double screenDuration, double pixelsPerSecond)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewInfo::SetBeforeScreenWidth(wxInt64 width, double lowerBoundTime)
|
void ViewInfo::SetBeforeScreenWidth(wxInt64 beforeWidth, wxInt64 screenWidth, double lowerBoundTime)
|
||||||
{
|
{
|
||||||
h =
|
h =
|
||||||
std::max(lowerBoundTime,
|
std::max(lowerBoundTime,
|
||||||
std::min(total - screen,
|
std::min(total - screenWidth / zoom,
|
||||||
width / zoom));
|
beforeWidth / zoom));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewInfo::WriteXMLAttributes(XMLWriter &xmlFile)
|
void ViewInfo::WriteXMLAttributes(XMLWriter &xmlFile)
|
||||||
|
@ -29,7 +29,7 @@ class Track;
|
|||||||
class AUDACITY_DLL_API ZoomInfo
|
class AUDACITY_DLL_API ZoomInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ZoomInfo(double start, double duration, double pixelsPerSecond);
|
ZoomInfo(double start, double pixelsPerSecond);
|
||||||
~ZoomInfo();
|
~ZoomInfo();
|
||||||
|
|
||||||
void UpdatePrefs();
|
void UpdatePrefs();
|
||||||
@ -38,8 +38,6 @@ public:
|
|||||||
|
|
||||||
double h; // h pos in secs
|
double h; // h pos in secs
|
||||||
|
|
||||||
double screen; // screen width in secs
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
double zoom; // pixels per second
|
double zoom; // pixels per second
|
||||||
|
|
||||||
@ -53,7 +51,7 @@ public:
|
|||||||
double PositionToTime(wxInt64 position,
|
double PositionToTime(wxInt64 position,
|
||||||
wxInt64 origin = 0
|
wxInt64 origin = 0
|
||||||
, bool ignoreFisheye = false
|
, bool ignoreFisheye = false
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
// do NOT use this once to convert a duration to a pixel width!
|
// do NOT use this once to convert a duration to a pixel width!
|
||||||
// Instead, call twice to convert start and end positions,
|
// Instead, call twice to convert start and end positions,
|
||||||
@ -62,7 +60,7 @@ public:
|
|||||||
wxInt64 TimeToPosition(double time,
|
wxInt64 TimeToPosition(double time,
|
||||||
wxInt64 origin = 0
|
wxInt64 origin = 0
|
||||||
, bool ignoreFisheye = false
|
, bool ignoreFisheye = false
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
double OffsetTimeByPixels(double time, wxInt64 offset) const
|
double OffsetTimeByPixels(double time, wxInt64 offset) const
|
||||||
{
|
{
|
||||||
@ -72,13 +70,6 @@ public:
|
|||||||
bool ZoomInAvailable() const;
|
bool ZoomInAvailable() const;
|
||||||
bool ZoomOutAvailable() const;
|
bool ZoomOutAvailable() const;
|
||||||
|
|
||||||
// Return pixels, but maybe not a whole number
|
|
||||||
double GetScreenWidth() const
|
|
||||||
{ return screen * zoom; }
|
|
||||||
|
|
||||||
void SetScreenWidth(wxInt64 width)
|
|
||||||
{ screen = width / zoom; }
|
|
||||||
|
|
||||||
static double GetDefaultZoom()
|
static double GetDefaultZoom()
|
||||||
{ return 44100.0 / 512.0; }
|
{ return 44100.0 / 512.0; }
|
||||||
|
|
||||||
@ -107,7 +98,7 @@ public:
|
|||||||
// first entry equals origin.
|
// first entry equals origin.
|
||||||
// @param origin specifies the pixel position corresponding to time ViewInfo::h.
|
// @param origin specifies the pixel position corresponding to time ViewInfo::h.
|
||||||
void FindIntervals
|
void FindIntervals
|
||||||
(double rate, Intervals &results, wxInt64 origin = 0) const;
|
(double rate, Intervals &results, wxInt64 width, wxInt64 origin = 0) const;
|
||||||
|
|
||||||
enum FisheyeState {
|
enum FisheyeState {
|
||||||
HIDDEN,
|
HIDDEN,
|
||||||
@ -120,7 +111,7 @@ public:
|
|||||||
|
|
||||||
// Return true if the mouse position is anywhere in the fisheye
|
// Return true if the mouse position is anywhere in the fisheye
|
||||||
// origin specifies the pixel corresponding to time h
|
// origin specifies the pixel corresponding to time h
|
||||||
bool InFisheye(wxInt64 position, wxInt64 WXUNUSED(origin = 0)) const
|
bool InFisheye(wxInt64 /*position*/, wxInt64 WXUNUSED(origin = 0)) const
|
||||||
{return false;} // stub
|
{return false;} // stub
|
||||||
|
|
||||||
// These accessors ignore the fisheye hiding state.
|
// These accessors ignore the fisheye hiding state.
|
||||||
@ -143,14 +134,11 @@ public:
|
|||||||
{
|
{
|
||||||
return h * zoom;
|
return h * zoom;
|
||||||
}
|
}
|
||||||
void SetBeforeScreenWidth(wxInt64 width, double lowerBoundTime = 0.0);
|
void SetBeforeScreenWidth(wxInt64 beforeWidth, wxInt64 screenWidth, double lowerBoundTime = 0.0);
|
||||||
|
|
||||||
double GetTotalWidth() const
|
double GetTotalWidth() const
|
||||||
{ return total * zoom; }
|
{ return total * zoom; }
|
||||||
|
|
||||||
bool ZoomedAll() const
|
|
||||||
{ return screen >= total; }
|
|
||||||
|
|
||||||
// Current selection
|
// Current selection
|
||||||
|
|
||||||
SelectedRegion selectedRegion;
|
SelectedRegion selectedRegion;
|
||||||
|
@ -2908,7 +2908,7 @@ void EqualizationPanel::OnPaint(wxPaintEvent & WXUNUSED(event))
|
|||||||
memDC.SetPen(*wxBLACK_PEN);
|
memDC.SetPen(*wxBLACK_PEN);
|
||||||
if( mEffect->mDraw->GetValue() )
|
if( mEffect->mDraw->GetValue() )
|
||||||
{
|
{
|
||||||
mEffect->mEnvelope->DrawPoints(memDC, mEnvRect, ZoomInfo(0.0, 1.0, mEnvRect.width-1), false, 0.0,
|
mEffect->mEnvelope->DrawPoints(memDC, mEnvRect, ZoomInfo(0.0, mEnvRect.width-1), false, 0.0,
|
||||||
mEffect->mdBMin, mEffect->mdBMax);
|
mEffect->mdBMin, mEffect->mdBMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2927,7 +2927,7 @@ void EqualizationPanel::OnMouseEvent(wxMouseEvent & event)
|
|||||||
CaptureMouse();
|
CaptureMouse();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mEffect->mEnvelope->MouseEvent(event, mEnvRect, ZoomInfo(0.0, 1.0, mEnvRect.width),
|
if (mEffect->mEnvelope->MouseEvent(event, mEnvRect, ZoomInfo(0.0, mEnvRect.width),
|
||||||
false, 0.0,
|
false, 0.0,
|
||||||
mEffect->mdBMin, mEffect->mdBMax))
|
mEffect->mdBMin, mEffect->mdBMax))
|
||||||
{
|
{
|
||||||
|
@ -267,6 +267,7 @@ PrefsDialog::PrefsDialog
|
|||||||
S.EndVerticalLay();
|
S.EndVerticalLay();
|
||||||
|
|
||||||
S.AddStandardButtons(eOkButton | eCancelButton | eApplyButton);
|
S.AddStandardButtons(eOkButton | eCancelButton | eApplyButton);
|
||||||
|
static_cast<wxButton*>(wxWindow::FindWindowById(wxID_OK, this))->SetDefault();
|
||||||
|
|
||||||
if (mUniquePage && !mUniquePage->ShowsApplyButton()) {
|
if (mUniquePage && !mUniquePage->ShowsApplyButton()) {
|
||||||
wxWindow *const applyButton =
|
wxWindow *const applyButton =
|
||||||
|
@ -56,6 +56,8 @@ AttachableScrollBar::~AttachableScrollBar(void)
|
|||||||
// Essentially a float to int conversion.
|
// Essentially a float to int conversion.
|
||||||
void AttachableScrollBar::SetScrollBarFromViewInfo()
|
void AttachableScrollBar::SetScrollBarFromViewInfo()
|
||||||
{
|
{
|
||||||
|
// fix me
|
||||||
|
#if 0
|
||||||
ViewInfo & mViewInfo = *mpViewInfo;
|
ViewInfo & mViewInfo = *mpViewInfo;
|
||||||
|
|
||||||
mViewInfo.sbarTotal = (int) (mViewInfo.GetTotalWidth());
|
mViewInfo.sbarTotal = (int) (mViewInfo.GetTotalWidth());
|
||||||
@ -64,11 +66,14 @@ void AttachableScrollBar::SetScrollBarFromViewInfo()
|
|||||||
|
|
||||||
SetScrollbar(mViewInfo.sbarH, mViewInfo.sbarScreen,
|
SetScrollbar(mViewInfo.sbarH, mViewInfo.sbarScreen,
|
||||||
mViewInfo.sbarTotal, mViewInfo.sbarScreen, TRUE);
|
mViewInfo.sbarTotal, mViewInfo.sbarScreen, TRUE);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Essentially an int to float conversion.
|
// Essentially an int to float conversion.
|
||||||
void AttachableScrollBar::SetViewInfoFromScrollBar()
|
void AttachableScrollBar::SetViewInfoFromScrollBar()
|
||||||
{
|
{
|
||||||
|
// fixme
|
||||||
|
#if 0
|
||||||
ViewInfo & mViewInfo = *mpViewInfo;
|
ViewInfo & mViewInfo = *mpViewInfo;
|
||||||
|
|
||||||
int hlast = mViewInfo.sbarH;
|
int hlast = mViewInfo.sbarH;
|
||||||
@ -76,7 +81,8 @@ void AttachableScrollBar::SetViewInfoFromScrollBar()
|
|||||||
mViewInfo.sbarH = GetThumbPosition();
|
mViewInfo.sbarH = GetThumbPosition();
|
||||||
|
|
||||||
if (mViewInfo.sbarH != hlast)
|
if (mViewInfo.sbarH != hlast)
|
||||||
mViewInfo.SetBeforeScreenWidth(mViewInfo.sbarH);
|
mViewInfo.SetBeforeScreenWidth(mViewInfo.sbarH);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used to associated a ViewInfo structure with a scrollbar.
|
// Used to associated a ViewInfo structure with a scrollbar.
|
||||||
|
@ -1936,8 +1936,8 @@ void AdornedRulerPanel::OnMouseEvents(wxMouseEvent &evt)
|
|||||||
|
|
||||||
// Keep Quick-Play within usable track area.
|
// Keep Quick-Play within usable track area.
|
||||||
TrackPanel *tp = mProject->GetTrackPanel();
|
TrackPanel *tp = mProject->GetTrackPanel();
|
||||||
int mousePosX, width, height;
|
int mousePosX, width;
|
||||||
tp->GetTracksUsableArea(&width, &height);
|
tp->GetTracksUsableArea(&width, NULL);
|
||||||
mousePosX = std::max(evt.GetX(), tp->GetLeftOffset());
|
mousePosX = std::max(evt.GetX(), tp->GetLeftOffset());
|
||||||
mousePosX = std::min(mousePosX, tp->GetLeftOffset() + width - 1);
|
mousePosX = std::min(mousePosX, tp->GetLeftOffset() + width - 1);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user