1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-08-01 16:39:30 +02:00

Play region and its lock are stored together in ViewInfo

This commit is contained in:
Paul Licameli 2019-01-25 23:39:29 -05:00
parent 0a843806f8
commit 63b93fd2d1
11 changed files with 165 additions and 146 deletions

View File

@ -901,11 +901,6 @@ AdornedRulerPanel::AdornedRulerPanel(AudacityProject* project,
mLeftOffset = 0; mLeftOffset = 0;
mIndTime = -1; mIndTime = -1;
mPlayRegionStart = -1;
mPlayRegionLock = false;
mPlayRegionEnd = -1;
mOldPlayRegionStart = -1;
mOldPlayRegionEnd = -1;
mLeftDownClick = -1; mLeftDownClick = -1;
mMouseEventState = mesNone; mMouseEventState = mesNone;
mIsDragging = false; mIsDragging = false;
@ -1280,9 +1275,9 @@ auto AdornedRulerPanel::QPHandle::Click
} }
// Store the initial play region state // Store the initial play region state
mParent->mOldPlayRegionStart = mParent->mPlayRegionStart; const auto &viewInfo = ViewInfo::Get( *pProject );
mParent->mOldPlayRegionEnd = mParent->mPlayRegionEnd; const auto &playRegion = viewInfo.playRegion;
mParent->mPlayRegionLock = mParent->mProject->IsPlayRegionLocked(); mParent->mOldPlayRegion = playRegion;
// Save old selection, in case drag of selection is cancelled // Save old selection, in case drag of selection is cancelled
mOldSelection = ViewInfo::Get( *pProject ).selectedRegion; mOldSelection = ViewInfo::Get( *pProject ).selectedRegion;
@ -1298,27 +1293,29 @@ auto AdornedRulerPanel::QPHandle::Click
void AdornedRulerPanel::HandleQPClick(wxMouseEvent &evt, wxCoord mousePosX) void AdornedRulerPanel::HandleQPClick(wxMouseEvent &evt, wxCoord mousePosX)
{ {
// Temporarily unlock locked play region // Temporarily unlock locked play region
if (mPlayRegionLock && evt.LeftDown()) { if (mOldPlayRegion.Locked() && evt.LeftDown()) {
//mPlayRegionLock = true; //mPlayRegionLock = true;
TransportActions::DoUnlockPlayRegion(*mProject); TransportActions::DoUnlockPlayRegion(*mProject);
} }
mLeftDownClickUnsnapped = mQuickPlayPosUnsnapped; mLeftDownClickUnsnapped = mQuickPlayPosUnsnapped;
mLeftDownClick = mQuickPlayPos; mLeftDownClick = mQuickPlayPos;
bool isWithinStart = IsWithinMarker(mousePosX, mOldPlayRegionStart); bool isWithinStart = IsWithinMarker(mousePosX, mOldPlayRegion.GetStart());
bool isWithinEnd = IsWithinMarker(mousePosX, mOldPlayRegionEnd); bool isWithinEnd = IsWithinMarker(mousePosX, mOldPlayRegion.GetEnd());
if (isWithinStart || isWithinEnd) { if (isWithinStart || isWithinEnd) {
// If Quick-Play is playing from a point, we need to treat it as a click // If Quick-Play is playing from a point, we need to treat it as a click
// not as dragging. // not as dragging.
if (mOldPlayRegionStart == mOldPlayRegionEnd) if (mOldPlayRegion.Empty())
mMouseEventState = mesSelectingPlayRegionClick; mMouseEventState = mesSelectingPlayRegionClick;
// otherwise check which marker is nearer // otherwise check which marker is nearer
else { else {
// Don't compare times, compare positions. // Don't compare times, compare positions.
//if (fabs(mQuickPlayPos - mPlayRegionStart) < fabs(mQuickPlayPos - mPlayRegionEnd)) //if (fabs(mQuickPlayPos - mPlayRegionStart) < fabs(mQuickPlayPos - mPlayRegionEnd))
if (abs(Time2Pos(mQuickPlayPos) - Time2Pos(mPlayRegionStart)) < auto start = mOldPlayRegion.GetStart();
abs(Time2Pos(mQuickPlayPos) - Time2Pos(mPlayRegionEnd))) auto end = mOldPlayRegion.GetEnd();
if (abs(Time2Pos(mQuickPlayPos) - Time2Pos(start)) <
abs(Time2Pos(mQuickPlayPos) - Time2Pos(end)))
mMouseEventState = mesDraggingPlayRegionStart; mMouseEventState = mesDraggingPlayRegionStart;
else else
mMouseEventState = mesDraggingPlayRegionEnd; mMouseEventState = mesDraggingPlayRegionEnd;
@ -1351,45 +1348,47 @@ void AdornedRulerPanel::HandleQPDrag(wxMouseEvent &/*event*/, wxCoord mousePosX)
bool isWithinClick = bool isWithinClick =
(mLeftDownClickUnsnapped >= 0) && (mLeftDownClickUnsnapped >= 0) &&
IsWithinMarker(mousePosX, mLeftDownClickUnsnapped); IsWithinMarker(mousePosX, mLeftDownClickUnsnapped);
bool isWithinStart = IsWithinMarker(mousePosX, mOldPlayRegionStart); bool isWithinStart = IsWithinMarker(mousePosX, mOldPlayRegion.GetStart());
bool isWithinEnd = IsWithinMarker(mousePosX, mOldPlayRegionEnd); bool isWithinEnd = IsWithinMarker(mousePosX, mOldPlayRegion.GetEnd());
bool canDragSel = !mPlayRegionLock && mPlayRegionDragsSelection; bool canDragSel = !mOldPlayRegion.Locked() && mPlayRegionDragsSelection;
auto &viewInfo = ViewInfo::Get( *GetProject() );
auto &playRegion = viewInfo.playRegion;
switch (mMouseEventState) switch (mMouseEventState)
{ {
case mesNone: case mesNone:
// If close to either end of play region, snap to closest // If close to either end of play region, snap to closest
if (isWithinStart || isWithinEnd) { if (isWithinStart || isWithinEnd) {
if (fabs(mQuickPlayPos - mOldPlayRegionStart) < fabs(mQuickPlayPos - mOldPlayRegionEnd)) if (fabs(mQuickPlayPos - mOldPlayRegion.GetStart()) < fabs(mQuickPlayPos - mOldPlayRegion.GetEnd()))
mQuickPlayPos = mOldPlayRegionStart; mQuickPlayPos = mOldPlayRegion.GetStart();
else else
mQuickPlayPos = mOldPlayRegionEnd; mQuickPlayPos = mOldPlayRegion.GetEnd();
} }
break; break;
case mesDraggingPlayRegionStart: case mesDraggingPlayRegionStart:
// Don't start dragging until beyond tolerance initial playback start // Don't start dragging until beyond tolerance initial playback start
if (!mIsDragging && isWithinStart) if (!mIsDragging && isWithinStart)
mQuickPlayPos = mOldPlayRegionStart; mQuickPlayPos = mOldPlayRegion.GetStart();
else else
mIsDragging = true; mIsDragging = true;
// avoid accidental tiny selection // avoid accidental tiny selection
if (isWithinEnd) if (isWithinEnd)
mQuickPlayPos = mOldPlayRegionEnd; mQuickPlayPos = mOldPlayRegion.GetEnd();
mPlayRegionStart = mQuickPlayPos; playRegion.SetStart( mQuickPlayPos );
if (canDragSel) { if (canDragSel) {
DragSelection(); DragSelection();
} }
break; break;
case mesDraggingPlayRegionEnd: case mesDraggingPlayRegionEnd:
if (!mIsDragging && isWithinEnd) { if (!mIsDragging && isWithinEnd) {
mQuickPlayPos = mOldPlayRegionEnd; mQuickPlayPos = mOldPlayRegion.GetEnd();
} }
else else
mIsDragging = true; mIsDragging = true;
if (isWithinStart) { if (isWithinStart) {
mQuickPlayPos = mOldPlayRegionStart; mQuickPlayPos = mOldPlayRegion.GetStart();
} }
mPlayRegionEnd = mQuickPlayPos; playRegion.SetEnd( mQuickPlayPos );
if (canDragSel) { if (canDragSel) {
DragSelection(); DragSelection();
} }
@ -1399,8 +1398,7 @@ void AdornedRulerPanel::HandleQPDrag(wxMouseEvent &/*event*/, wxCoord mousePosX)
// Don't start dragging until mouse is beyond tolerance of initial click. // Don't start dragging until mouse is beyond tolerance of initial click.
if (isWithinClick || mLeftDownClick == -1) { if (isWithinClick || mLeftDownClick == -1) {
mQuickPlayPos = mLeftDownClick; mQuickPlayPos = mLeftDownClick;
mPlayRegionStart = mLeftDownClick; playRegion.SetTimes(mLeftDownClick, mLeftDownClick);
mPlayRegionEnd = mLeftDownClick;
} }
else { else {
mMouseEventState = mesSelectingPlayRegionRange; mMouseEventState = mesSelectingPlayRegionRange;
@ -1411,14 +1409,10 @@ void AdornedRulerPanel::HandleQPDrag(wxMouseEvent &/*event*/, wxCoord mousePosX)
mQuickPlayPos = mLeftDownClick; mQuickPlayPos = mLeftDownClick;
} }
if (mQuickPlayPos < mLeftDownClick) { if (mQuickPlayPos < mLeftDownClick)
mPlayRegionStart = mQuickPlayPos; playRegion.SetTimes( mQuickPlayPos, mLeftDownClick );
mPlayRegionEnd = mLeftDownClick; else
} playRegion.SetTimes( mLeftDownClick, mQuickPlayPos );
else {
mPlayRegionEnd = mQuickPlayPos;
mPlayRegionStart = mLeftDownClick;
}
if (canDragSel) { if (canDragSel) {
DragSelection(); DragSelection();
} }
@ -1474,9 +1468,9 @@ auto AdornedRulerPanel::QPHandle::Preview
showArrows = showArrows =
(mClicked == Button::Left) (mClicked == Button::Left)
|| mParent->IsWithinMarker( || mParent->IsWithinMarker(
state.state.m_x, mParent->mOldPlayRegionStart) state.state.m_x, mParent->mOldPlayRegion.GetStart())
|| mParent->IsWithinMarker( || mParent->IsWithinMarker(
state.state.m_x, mParent->mOldPlayRegionEnd); state.state.m_x, mParent->mOldPlayRegion.GetEnd());
return { return {
message, message,
@ -1498,11 +1492,13 @@ auto AdornedRulerPanel::QPHandle::Release
auto result = CommonRulerHandle::Release(event, pProject, pParent); auto result = CommonRulerHandle::Release(event, pProject, pParent);
if (!( result & RefreshCode::Cancelled )) { if (!( result & RefreshCode::Cancelled )) {
if (mClicked == Button::Left) { if (mClicked == Button::Left) {
if ( mParent ) if ( mParent ) {
mParent->HandleQPRelease( event.event ); mParent->HandleQPRelease( event.event );
// Update the hot zones for cursor changes // Update the hot zones for cursor changes
mParent->mOldPlayRegionStart = mParent->mPlayRegionStart; const auto &viewInfo = ViewInfo::Get( *pProject );
mParent->mOldPlayRegionEnd = mParent->mPlayRegionEnd; const auto &playRegion = viewInfo.playRegion;
mParent->mOldPlayRegion = playRegion;
}
} }
} }
return result; return result;
@ -1510,38 +1506,37 @@ auto AdornedRulerPanel::QPHandle::Release
void AdornedRulerPanel::HandleQPRelease(wxMouseEvent &evt) void AdornedRulerPanel::HandleQPRelease(wxMouseEvent &evt)
{ {
if (mPlayRegionEnd < mPlayRegionStart) { auto &viewInfo = ViewInfo::Get( *GetProject() );
// Swap values to ensure mPlayRegionStart < mPlayRegionEnd auto &playRegion = viewInfo.playRegion;
double tmp = mPlayRegionStart; playRegion.Order();
mPlayRegionStart = mPlayRegionEnd;
mPlayRegionEnd = tmp;
}
const double t0 = mTracks->GetStartTime(); const double t0 = mTracks->GetStartTime();
const double t1 = mTracks->GetEndTime(); const double t1 = mTracks->GetEndTime();
auto &viewInfo = ViewInfo::Get( *GetProject() );
const auto &selectedRegion = viewInfo.selectedRegion; const auto &selectedRegion = viewInfo.selectedRegion;
const double sel0 = selectedRegion.t0(); const double sel0 = selectedRegion.t0();
const double sel1 = selectedRegion.t1(); const double sel1 = selectedRegion.t1();
// We want some audio in the selection, but we allow a dragged // We want some audio in the selection, but we allow a dragged
// region to include selected white-space and space before audio start. // region to include selected white-space and space before audio start.
if (evt.ShiftDown() && (mPlayRegionStart == mPlayRegionEnd)) { if (evt.ShiftDown() && playRegion.Empty()) {
// Looping the selection or project. // Looping the selection or project.
// Disable if track selection is in white-space beyond end of tracks and // Disable if track selection is in white-space beyond end of tracks and
// play position is outside of track contents. // play position is outside of track contents.
if (((sel1 < t0) || (sel0 > t1)) && if (((sel1 < t0) || (sel0 > t1)) &&
((mPlayRegionStart < t0) || (mPlayRegionStart > t1))) { ((playRegion.GetStart() < t0) || (playRegion.GetStart() > t1))) {
ClearPlayRegion(); ClearPlayRegion();
} }
} }
// Disable if beyond end. // Disable if beyond end.
else if (mPlayRegionStart >= t1) { else if (playRegion.GetStart() >= t1) {
ClearPlayRegion(); ClearPlayRegion();
} }
// Disable if empty selection before start. // Disable if empty selection before start.
// (allow Quick-Play region to include 'pre-roll' white space) // (allow Quick-Play region to include 'pre-roll' white space)
else if (((mPlayRegionEnd - mPlayRegionStart) > 0.0) && (mPlayRegionEnd < t0)) { else if (
playRegion.GetEnd() - playRegion.GetStart() > 0.0 &&
playRegion.GetEnd() < t0
) {
ClearPlayRegion(); ClearPlayRegion();
} }
@ -1550,12 +1545,12 @@ void AdornedRulerPanel::HandleQPRelease(wxMouseEvent &evt)
mLeftDownClick = -1; mLeftDownClick = -1;
auto cleanup = finally( [&] { auto cleanup = finally( [&] {
if (mPlayRegionLock) { if (mOldPlayRegion.Locked()) {
// Restore Locked Play region // Restore Locked Play region
SetPlayRegion(mOldPlayRegionStart, mOldPlayRegionEnd); SetPlayRegion(mOldPlayRegion.GetStart(), mOldPlayRegion.GetEnd());
TransportActions::DoLockPlayRegion(*mProject); TransportActions::DoLockPlayRegion(*mProject);
// and release local lock // and release local lock
mPlayRegionLock = false; mOldPlayRegion.SetLocked( false );
} }
} ); } );
@ -1572,12 +1567,12 @@ auto AdornedRulerPanel::QPHandle::Cancel
ViewInfo::Get( *pProject ).selectedRegion = mOldSelection; ViewInfo::Get( *pProject ).selectedRegion = mOldSelection;
mParent->mMouseEventState = mesNone; mParent->mMouseEventState = mesNone;
mParent->SetPlayRegion( mParent->SetPlayRegion(
mParent->mOldPlayRegionStart, mParent->mOldPlayRegionEnd); mParent->mOldPlayRegion.GetStart(), mParent->mOldPlayRegion.GetEnd());
if (mParent->mPlayRegionLock) { if (mParent->mOldPlayRegion.Locked()) {
// Restore Locked Play region // Restore Locked Play region
TransportActions::DoLockPlayRegion(*pProject); TransportActions::DoLockPlayRegion(*pProject);
// and release local lock // and release local lock
mParent->mPlayRegionLock = false; mParent->mOldPlayRegion.SetLocked( false );
} }
} }
} }
@ -1590,12 +1585,13 @@ void AdornedRulerPanel::StartQPPlay(bool looped, bool cutPreview)
const double t0 = mTracks->GetStartTime(); const double t0 = mTracks->GetStartTime();
const double t1 = mTracks->GetEndTime(); const double t1 = mTracks->GetEndTime();
auto &viewInfo = ViewInfo::Get( *mProject ); auto &viewInfo = ViewInfo::Get( *mProject );
auto &playRegion = viewInfo.playRegion;
const auto &selectedRegion = viewInfo.selectedRegion; const auto &selectedRegion = viewInfo.selectedRegion;
const double sel0 = selectedRegion.t0(); const double sel0 = selectedRegion.t0();
const double sel1 = selectedRegion.t1(); const double sel1 = selectedRegion.t1();
// Start / Restart playback on left click. // Start / Restart playback on left click.
bool startPlaying = (mPlayRegionStart >= 0); bool startPlaying = (playRegion.GetStart() >= 0);
if (startPlaying) { if (startPlaying) {
auto &ctb = ControlToolBar::Get( *mProject ); auto &ctb = ControlToolBar::Get( *mProject );
@ -1604,9 +1600,9 @@ void AdornedRulerPanel::StartQPPlay(bool looped, bool cutPreview)
bool loopEnabled = true; bool loopEnabled = true;
double start, end; double start, end;
if ((mPlayRegionEnd - mPlayRegionStart == 0.0) && looped) { if (playRegion.Empty() && looped) {
// Loop play a point will loop either a selection or the project. // Loop play a point will loop either a selection or the project.
if ((mPlayRegionStart > sel0) && (mPlayRegionStart < sel1)) { if ((playRegion.GetStart() > sel0) && (playRegion.GetStart() < sel1)) {
// we are in a selection, so use the selection // we are in a selection, so use the selection
start = sel0; start = sel0;
end = sel1; end = sel1;
@ -1617,8 +1613,8 @@ void AdornedRulerPanel::StartQPPlay(bool looped, bool cutPreview)
} }
} }
else { else {
start = mPlayRegionStart; start = playRegion.GetStart();
end = mPlayRegionEnd; end = playRegion.GetEnd();
} }
// Looping a tiny selection may freeze, so just play it once. // Looping a tiny selection may freeze, so just play it once.
loopEnabled = ((end - start) > 0.001)? true : false; loopEnabled = ((end - start) > 0.001)? true : false;
@ -1626,7 +1622,7 @@ void AdornedRulerPanel::StartQPPlay(bool looped, bool cutPreview)
auto options = DefaultPlayOptions( *mProject ); auto options = DefaultPlayOptions( *mProject );
options.playLooped = (loopEnabled && looped); options.playLooped = (loopEnabled && looped);
auto oldStart = mPlayRegionStart; auto oldStart = playRegion.GetStart();
if (!cutPreview) if (!cutPreview)
options.pStartTime = &oldStart; options.pStartTime = &oldStart;
else else
@ -1637,8 +1633,7 @@ void AdornedRulerPanel::StartQPPlay(bool looped, bool cutPreview)
: options.playLooped ? PlayMode::loopedPlay : options.playLooped ? PlayMode::loopedPlay
: PlayMode::normalPlay; : PlayMode::normalPlay;
mPlayRegionStart = start; playRegion.SetTimes( start, end );
mPlayRegionEnd = end;
Refresh(); Refresh();
ctb.PlayPlayRegion((SelectedRegion(start, end)), ctb.PlayPlayRegion((SelectedRegion(start, end)),
@ -1740,6 +1735,8 @@ void AdornedRulerPanel::UpdateQuickPlayPos(wxCoord &mousePosX, bool shiftDown)
void AdornedRulerPanel::ShowMenu(const wxPoint & pos) void AdornedRulerPanel::ShowMenu(const wxPoint & pos)
{ {
const auto &viewInfo = ViewInfo::Get( *GetProject() );
const auto &playRegion = viewInfo.playRegion;
wxMenu rulerMenu; wxMenu rulerMenu;
if (mQuickPlayEnabled) if (mQuickPlayEnabled)
@ -1748,11 +1745,11 @@ void AdornedRulerPanel::ShowMenu(const wxPoint & pos)
rulerMenu.Append(OnToggleQuickPlayID, _("Enable Quick-Play")); rulerMenu.Append(OnToggleQuickPlayID, _("Enable Quick-Play"));
wxMenuItem *dragitem; wxMenuItem *dragitem;
if (mPlayRegionDragsSelection && !mProject->IsPlayRegionLocked()) if (mPlayRegionDragsSelection && !playRegion.Locked())
dragitem = rulerMenu.Append(OnSyncQuickPlaySelID, _("Disable dragging selection")); dragitem = rulerMenu.Append(OnSyncQuickPlaySelID, _("Disable dragging selection"));
else else
dragitem = rulerMenu.Append(OnSyncQuickPlaySelID, _("Enable dragging selection")); dragitem = rulerMenu.Append(OnSyncQuickPlaySelID, _("Enable dragging selection"));
dragitem->Enable(mQuickPlayEnabled && !mProject->IsPlayRegionLocked()); dragitem->Enable(mQuickPlayEnabled && !playRegion.Locked());
#if wxUSE_TOOLTIPS #if wxUSE_TOOLTIPS
if (mTimelineToolTip) if (mTimelineToolTip)
@ -1767,11 +1764,11 @@ void AdornedRulerPanel::ShowMenu(const wxPoint & pos)
rulerMenu.Append(OnAutoScrollID, _("Update display while playing")); rulerMenu.Append(OnAutoScrollID, _("Update display while playing"));
wxMenuItem *prlitem; wxMenuItem *prlitem;
if (!mProject->IsPlayRegionLocked()) if (!playRegion.Locked())
prlitem = rulerMenu.Append(OnLockPlayRegionID, _("Lock Play Region")); prlitem = rulerMenu.Append(OnLockPlayRegionID, _("Lock Play Region"));
else else
prlitem = rulerMenu.Append(OnLockPlayRegionID, _("Unlock Play Region")); prlitem = rulerMenu.Append(OnLockPlayRegionID, _("Unlock Play Region"));
prlitem->Enable(mProject->IsPlayRegionLocked() || (mPlayRegionStart != mPlayRegionEnd)); prlitem->Enable( playRegion.Locked() || !playRegion.Empty() );
wxMenuItem *ruleritem; wxMenuItem *ruleritem;
if (mShowScrubbing) if (mShowScrubbing)
@ -1811,9 +1808,10 @@ void AdornedRulerPanel::OnSyncSelToQuickPlay(wxCommandEvent&)
void AdornedRulerPanel::DragSelection() void AdornedRulerPanel::DragSelection()
{ {
auto &viewInfo = ViewInfo::Get( *GetProject() ); auto &viewInfo = ViewInfo::Get( *GetProject() );
const auto &playRegion = viewInfo.playRegion;
auto &selectedRegion = viewInfo.selectedRegion; auto &selectedRegion = viewInfo.selectedRegion;
selectedRegion.setT0(mPlayRegionStart, false); selectedRegion.setT0(playRegion.GetStart(), false);
selectedRegion.setT1(mPlayRegionEnd, true); selectedRegion.setT1(playRegion.GetEnd(), true);
} }
void AdornedRulerPanel::HandleSnapping() void AdornedRulerPanel::HandleSnapping()
@ -1854,7 +1852,9 @@ void AdornedRulerPanel::OnAutoScroll(wxCommandEvent&)
void AdornedRulerPanel::OnLockPlayRegion(wxCommandEvent&) void AdornedRulerPanel::OnLockPlayRegion(wxCommandEvent&)
{ {
if (mProject->IsPlayRegionLocked()) const auto &viewInfo = ViewInfo::Get( *GetProject() );
const auto &playRegion = viewInfo.playRegion;
if (playRegion.Locked())
TransportActions::DoUnlockPlayRegion(*mProject); TransportActions::DoUnlockPlayRegion(*mProject);
else else
TransportActions::DoLockPlayRegion(*mProject); TransportActions::DoLockPlayRegion(*mProject);
@ -1864,8 +1864,10 @@ void AdornedRulerPanel::OnLockPlayRegion(wxCommandEvent&)
// Draws the horizontal <===> // Draws the horizontal <===>
void AdornedRulerPanel::DoDrawPlayRegion(wxDC * dc) void AdornedRulerPanel::DoDrawPlayRegion(wxDC * dc)
{ {
double start, end; const auto &viewInfo = ViewInfo::Get( *GetProject() );
GetPlayRegion(&start, &end); const auto &playRegion = viewInfo.playRegion;
auto start = playRegion.GetStart();
auto end = playRegion.GetEnd();
if (start >= 0) if (start >= 0)
{ {
@ -1873,7 +1875,7 @@ void AdornedRulerPanel::DoDrawPlayRegion(wxDC * dc)
const int x2 = Time2Pos(end)-2; const int x2 = Time2Pos(end)-2;
int y = mInner.y - TopMargin + mInner.height/2; int y = mInner.y - TopMargin + mInner.height/2;
bool isLocked = mProject->IsPlayRegionLocked(); bool isLocked = playRegion.Locked();
AColor::PlayRegionColor(dc, isLocked); AColor::PlayRegionColor(dc, isLocked);
wxPoint tri[3]; wxPoint tri[3];
@ -2108,8 +2110,9 @@ void AdornedRulerPanel::SetPlayRegion(double playRegionStart,
if (mMouseEventState != mesNone) if (mMouseEventState != mesNone)
return; return;
mPlayRegionStart = playRegionStart; auto &viewInfo = ViewInfo::Get( *GetProject() );
mPlayRegionEnd = playRegionEnd; auto &playRegion = viewInfo.playRegion;
playRegion.SetTimes( playRegionStart, playRegionEnd );
Refresh(); Refresh();
} }
@ -2119,28 +2122,13 @@ void AdornedRulerPanel::ClearPlayRegion()
auto &ctb = ControlToolBar::Get( *mProject ); auto &ctb = ControlToolBar::Get( *mProject );
ctb.StopPlaying(); ctb.StopPlaying();
mPlayRegionStart = -1; auto &viewInfo = ViewInfo::Get( *GetProject() );
mPlayRegionEnd = -1; auto &playRegion = viewInfo.playRegion;
playRegion.SetTimes( -1, -1 );
Refresh(); Refresh();
} }
void AdornedRulerPanel::GetPlayRegion(double* playRegionStart,
double* playRegionEnd)
{
if (mPlayRegionStart >= 0 && mPlayRegionEnd >= 0 &&
mPlayRegionEnd < mPlayRegionStart)
{
// swap values to make sure end > start
*playRegionStart = mPlayRegionEnd;
*playRegionEnd = mPlayRegionStart;
} else
{
*playRegionStart = mPlayRegionStart;
*playRegionEnd = mPlayRegionEnd;
}
}
void AdornedRulerPanel::GetMaxSize(wxCoord *width, wxCoord *height) void AdornedRulerPanel::GetMaxSize(wxCoord *width, wxCoord *height)
{ {
mRuler.GetMaxSize(width, height); mRuler.GetMaxSize(width, height);

View File

@ -14,8 +14,8 @@
#include "CellularPanel.h" #include "CellularPanel.h"
#include "widgets/Ruler.h" // member variable #include "widgets/Ruler.h" // member variable
#include "Prefs.h" #include "Prefs.h"
#include "ViewInfo.h" // for PlayRegion
class ViewInfo;
class AudacityProject; class AudacityProject;
class SnapManager; class SnapManager;
class TrackList; class TrackList;
@ -54,7 +54,6 @@ public:
void SetPlayRegion(double playRegionStart, double playRegionEnd); void SetPlayRegion(double playRegionStart, double playRegionEnd);
void ClearPlayRegion(); void ClearPlayRegion();
void GetPlayRegion(double* playRegionStart, double* playRegionEnd);
void GetMaxSize(wxCoord *width, wxCoord *height); void GetMaxSize(wxCoord *width, wxCoord *height);
@ -132,11 +131,7 @@ private:
bool mIsSnapped; bool mIsSnapped;
bool mPlayRegionLock; PlayRegion mOldPlayRegion;
double mPlayRegionStart;
double mPlayRegionEnd;
double mOldPlayRegionStart;
double mOldPlayRegionEnd;
bool mIsRecording; bool mIsRecording;

View File

@ -546,11 +546,10 @@ CommandFlag MenuManager::GetUpdateFlags
flags |= GetFocusedFrame(project); flags |= GetFocusedFrame(project);
double start, end; const auto &playRegion = viewInfo.playRegion;
project.GetPlayRegion(&start, &end); if (playRegion.Locked())
if (project.IsPlayRegionLocked())
flags |= PlayRegionLockedFlag; flags |= PlayRegionLockedFlag;
else if (start != end) else if (!playRegion.Empty())
flags |= PlayRegionNotLockedFlag; flags |= PlayRegionNotLockedFlag;
if (flags & AudioIONotBusyFlag) { if (flags & AudioIONotBusyFlag) {

View File

@ -12,7 +12,6 @@
#include "Audacity.h" // for USE_* macros #include "Audacity.h" // for USE_* macros
#include "Project.h" #include "Project.h"
#include "AdornedRulerPanel.h"
#include "KeyboardCapture.h" #include "KeyboardCapture.h"
#include "ondemand/ODTaskThread.h" #include "ondemand/ODTaskThread.h"
@ -156,14 +155,6 @@ void AudacityProject::SetStatus(const wxString &msg)
} }
} }
void AudacityProject::GetPlayRegion(double* playRegionStart,
double *playRegionEnd)
{
auto &project = *this;
AdornedRulerPanel::Get( project ).GetPlayRegion(
playRegionStart, playRegionEnd);
}
wxFrame &GetProjectFrame( AudacityProject &project ) wxFrame &GetProjectFrame( AudacityProject &project )
{ {
auto ptr = project.GetFrame(); auto ptr = project.GetFrame();

View File

@ -122,10 +122,6 @@ class AUDACITY_DLL_API AudacityProject final
const wxFrame *GetFrame() const { return mFrame; } const wxFrame *GetFrame() const { return mFrame; }
void SetFrame( wxFrame *pFrame ); void SetFrame( wxFrame *pFrame );
void GetPlayRegion(double* playRegionStart, double *playRegionEnd);
bool IsPlayRegionLocked() { return mLockPlayRegion; }
void SetPlayRegionLocked(bool value) { mLockPlayRegion = value; }
wxString GetProjectName() const; wxString GetProjectName() const;
const FilePath &GetFileName() { return mFileName; } const FilePath &GetFileName() { return mFileName; }
@ -149,8 +145,6 @@ class AUDACITY_DLL_API AudacityProject final
int mBatchMode{ 0 };// 0 means not, >0 means in batch mode. int mBatchMode{ 0 };// 0 means not, >0 means in batch mode.
private: private:
bool mLockPlayRegion{ false };
wxString mLastMainStatusMessage; wxString mLastMainStatusMessage;
wxWeakRef< wxFrame > mFrame{}; wxWeakRef< wxFrame > mFrame{};

View File

@ -1590,8 +1590,9 @@ void ProjectWindow::TP_DisplaySelection()
auto &viewInfo = ViewInfo::Get( project ); auto &viewInfo = ViewInfo::Get( project );
const auto &selectedRegion = viewInfo.selectedRegion; const auto &selectedRegion = viewInfo.selectedRegion;
double audioTime; double audioTime;
auto &playRegion = ViewInfo::Get( project ).playRegion;
if (!gAudioIO->IsBusy() && project.IsPlayRegionLocked()) if (!gAudioIO->IsBusy() && playRegion.Locked())
ruler.SetPlayRegion( selectedRegion.t0(), selectedRegion.t1() ); ruler.SetPlayRegion( selectedRegion.t0(), selectedRegion.t1() );
else else
// Cause ruler redraw anyway, because we may be zooming or scrolling // Cause ruler redraw anyway, because we may be zooming or scrolling
@ -1599,10 +1600,8 @@ void ProjectWindow::TP_DisplaySelection()
if (gAudioIO->IsBusy()) if (gAudioIO->IsBusy())
audioTime = gAudioIO->GetStreamTime(); audioTime = gAudioIO->GetStreamTime();
else { else
double playEnd; audioTime = playRegion.GetStart();
project.GetPlayRegion(&audioTime, &playEnd);
}
SelectionBar::Get( project ).SetTimes(selectedRegion.t0(), SelectionBar::Get( project ).SetTimes(selectedRegion.t0(),
selectedRegion.t1(), audioTime); selectedRegion.t1(), audioTime);

View File

@ -11,6 +11,7 @@
#ifndef __AUDACITY_VIEWINFO__ #ifndef __AUDACITY_VIEWINFO__
#define __AUDACITY_VIEWINFO__ #define __AUDACITY_VIEWINFO__
#include <utility>
#include <vector> #include <vector>
#include <wx/event.h> // inherit wxEvtHandler #include <wx/event.h> // inherit wxEvtHandler
#include "ClientData.h" #include "ClientData.h"
@ -147,6 +148,58 @@ public:
{return 0;} // stub {return 0;} // stub
}; };
class PlayRegion
{
public:
PlayRegion() = default;
PlayRegion( const PlayRegion& ) = delete;
PlayRegion &operator= ( const PlayRegion &that )
{
mLocked = that.mLocked;
// Guarantee the equivalent un-swapped order of endpoints
mStart = that.GetStart();
mEnd = that.GetEnd();
return *this;
}
bool Locked() const { return mLocked; }
void SetLocked( bool locked ) { mLocked = locked; }
bool Empty() const { return GetStart() == GetEnd(); }
double GetStart() const
{
if ( mEnd < 0 )
return mStart;
else
return std::min( mStart, mEnd );
}
double GetEnd() const
{
if ( mStart < 0 )
return mEnd;
else
return std::max( mStart, mEnd );
}
void SetStart( double start ) { mStart = start; }
void SetEnd( double end ) { mEnd = end; }
void SetTimes( double start, double end ) { mStart = start, mEnd = end; }
void Order()
{
if ( mStart >= 0 && mEnd >= 0 && mStart > mEnd)
std::swap( mStart, mEnd );
}
private:
// Times:
double mStart{ -1.0 };
double mEnd{ -1.0 };
bool mLocked{ false };
};
class AUDACITY_DLL_API ViewInfo final class AUDACITY_DLL_API ViewInfo final
: public wxEvtHandler, public ZoomInfo : public wxEvtHandler, public ZoomInfo
{ {
@ -172,6 +225,7 @@ public:
// Current selection // Current selection
SelectedRegion selectedRegion; SelectedRegion selectedRegion;
PlayRegion playRegion;
// Scroll info // Scroll info

View File

@ -3512,11 +3512,10 @@ void EffectUIHost::OnPlay(wxCommandEvent & WXUNUSED(evt))
{ {
auto &viewInfo = ViewInfo::Get( *mProject ); auto &viewInfo = ViewInfo::Get( *mProject );
const auto &selectedRegion = viewInfo.selectedRegion; const auto &selectedRegion = viewInfo.selectedRegion;
if (mProject->IsPlayRegionLocked()) const auto &playRegion = viewInfo.playRegion;
if ( playRegion.Locked() )
{ {
double t0, t1; mRegion.setTimes(playRegion.GetStart(), playRegion.GetEnd());
mProject->GetPlayRegion(&t0, &t1);
mRegion.setTimes(t0, t1);
mPlayPos = mRegion.t0(); mPlayPos = mRegion.t0();
} }
else if (selectedRegion.t0() != mRegion.t0() || else if (selectedRegion.t0() != mRegion.t0() ||

View File

@ -307,14 +307,14 @@ void DoLockPlayRegion( AudacityProject &project )
auto &tracks = TrackList::Get( project ); auto &tracks = TrackList::Get( project );
auto &ruler = AdornedRulerPanel::Get( project ); auto &ruler = AdornedRulerPanel::Get( project );
double start, end; auto &viewInfo = ViewInfo::Get( project );
project.GetPlayRegion(&start, &end); auto &playRegion = viewInfo.playRegion;
if (start >= tracks.GetEndTime()) { if (playRegion.GetStart() >= tracks.GetEndTime()) {
AudacityMessageBox(_("Cannot lock region beyond\nend of project."), AudacityMessageBox(_("Cannot lock region beyond\nend of project."),
_("Error")); _("Error"));
} }
else { else {
project.SetPlayRegionLocked( true ); playRegion.SetLocked( true );
ruler.Refresh(false); ruler.Refresh(false);
} }
} }
@ -322,8 +322,9 @@ void DoLockPlayRegion( AudacityProject &project )
void DoUnlockPlayRegion( AudacityProject &project ) void DoUnlockPlayRegion( AudacityProject &project )
{ {
auto &ruler = AdornedRulerPanel::Get( project ); auto &ruler = AdornedRulerPanel::Get( project );
auto &viewInfo = ViewInfo::Get( project );
project.SetPlayRegionLocked( false ); auto &playRegion = viewInfo.playRegion;
playRegion.SetLocked( false );
ruler.Refresh(false); ruler.Refresh(false);
} }

View File

@ -770,8 +770,7 @@ void ControlToolBar::PlayCurrentRegion(bool looped /* = false */,
if (p) if (p)
{ {
double playRegionStart, playRegionEnd; const auto &playRegion = ViewInfo::Get( *p ).playRegion;
p->GetPlayRegion(&playRegionStart, &playRegionEnd);
auto options = DefaultPlayOptions( *p ); auto options = DefaultPlayOptions( *p );
options.playLooped = looped; options.playLooped = looped;
@ -781,7 +780,7 @@ void ControlToolBar::PlayCurrentRegion(bool looped /* = false */,
cutpreview ? PlayMode::cutPreviewPlay cutpreview ? PlayMode::cutPreviewPlay
: options.playLooped ? PlayMode::loopedPlay : options.playLooped ? PlayMode::loopedPlay
: PlayMode::normalPlay; : PlayMode::normalPlay;
PlayPlayRegion(SelectedRegion(playRegionStart, playRegionEnd), PlayPlayRegion(SelectedRegion(playRegion.GetStart(), playRegion.GetEnd()),
options, options,
mode); mode);
} }

View File

@ -487,11 +487,11 @@ void TranscriptionToolBar::PlayAtSpeed(bool looped, bool cutPreview)
} }
// Get the current play region // Get the current play region
double playRegionStart, playRegionEnd; const auto &viewInfo = ViewInfo::Get( *p );
p->GetPlayRegion(&playRegionStart, &playRegionEnd); const auto &playRegion = viewInfo.playRegion;
// Start playing // Start playing
if (playRegionStart < 0) if (playRegion.GetStart() < 0)
return; return;
if (bFixedSpeedPlay) if (bFixedSpeedPlay)
{ {
@ -504,8 +504,8 @@ void TranscriptionToolBar::PlayAtSpeed(bool looped, bool cutPreview)
: options.playLooped ? PlayMode::loopedPlay : options.playLooped ? PlayMode::loopedPlay
: PlayMode::normalPlay; : PlayMode::normalPlay;
auto &bar = ControlToolBar::Get( *p ); auto &bar = ControlToolBar::Get( *p );
bar.PlayPlayRegion bar.PlayPlayRegion(
(SelectedRegion(playRegionStart, playRegionEnd), SelectedRegion(playRegion.GetStart(), playRegion.GetEnd()),
options, options,
mode); mode);
} }
@ -513,7 +513,7 @@ void TranscriptionToolBar::PlayAtSpeed(bool looped, bool cutPreview)
{ {
auto &scrubber = Scrubber::Get( *p ); auto &scrubber = Scrubber::Get( *p );
scrubber.StartSpeedPlay(GetPlaySpeed(), scrubber.StartSpeedPlay(GetPlaySpeed(),
playRegionStart, playRegionEnd); playRegion.GetStart(), playRegion.GetEnd());
} }
} }