mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-16 16:10:06 +02:00
Fix lots of snapping problems by moving snap-to-time into SnapManager.
Do a 'make dep' after updating, some #includes are added.
This commit is contained in:
parent
8bc7f68edc
commit
dbc4aab314
@ -4140,10 +4140,6 @@ void AudacityProject::TP_DisplaySelection()
|
|||||||
}
|
}
|
||||||
|
|
||||||
GetSelectionBar()->SetTimes(mViewInfo.sel0, mViewInfo.sel1, audioTime);
|
GetSelectionBar()->SetTimes(mViewInfo.sel0, mViewInfo.sel1, audioTime);
|
||||||
if( mSnapTo ) {
|
|
||||||
mViewInfo.sel0 = GetSelectionBar()->GetLeftTime();
|
|
||||||
mViewInfo.sel1 = GetSelectionBar()->GetRightTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gAudioIO->IsBusy() && !mLockPlayRegion)
|
if (!gAudioIO->IsBusy() && !mLockPlayRegion)
|
||||||
mRuler->SetPlayRegion(mViewInfo.sel0, mViewInfo.sel1);
|
mRuler->SetPlayRegion(mViewInfo.sel0, mViewInfo.sel1);
|
||||||
|
88
src/Snap.cpp
88
src/Snap.cpp
@ -11,9 +11,12 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include "LabelTrack.h"
|
#include "LabelTrack.h"
|
||||||
|
#include "Prefs.h"
|
||||||
|
#include "Project.h"
|
||||||
#include "Snap.h"
|
#include "Snap.h"
|
||||||
#include "TrackPanel.h"
|
#include "TrackPanel.h"
|
||||||
#include "WaveTrack.h"
|
#include "WaveTrack.h"
|
||||||
|
#include "widgets/TimeTextCtrl.h"
|
||||||
|
|
||||||
int CompareSnapPoints(SnapPoint *s1, SnapPoint *s2)
|
int CompareSnapPoints(SnapPoint *s1, SnapPoint *s2)
|
||||||
{
|
{
|
||||||
@ -21,10 +24,27 @@ int CompareSnapPoints(SnapPoint *s1, SnapPoint *s2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SnapManager::SnapManager(TrackList *tracks, TrackClipArray *exclusions,
|
SnapManager::SnapManager(TrackList *tracks, TrackClipArray *exclusions,
|
||||||
double zoom, int pixelTolerance)
|
double zoom, int pixelTolerance, bool noTimeSnap)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
// Grab time-snapping prefs (unless otherwise requested)
|
||||||
|
mSnapToTime = false;
|
||||||
|
TimeTextCtrl *ttc = NULL;
|
||||||
|
if (gPrefs->Read(wxT("/SnapTo"), 0L) != 0L && !noTimeSnap)
|
||||||
|
{
|
||||||
|
// Look up the format string
|
||||||
|
AudacityProject *p = GetActiveProject();
|
||||||
|
if (p) {
|
||||||
|
mSnapToTime = true;
|
||||||
|
ttc = new TimeTextCtrl(p, wxID_ANY, wxT(""), 0.0, p->GetRate());
|
||||||
|
wxString formatName;
|
||||||
|
gPrefs->Read(wxT("/SelectionFormat"), &formatName);
|
||||||
|
mFormat = ttc->GetBuiltinFormat(formatName);
|
||||||
|
ttc->SetFormatString(mFormat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mSnapPoints = new SnapPointArray(CompareSnapPoints);
|
mSnapPoints = new SnapPointArray(CompareSnapPoints);
|
||||||
if (zoom > 0 && pixelTolerance > 0)
|
if (zoom > 0 && pixelTolerance > 0)
|
||||||
mTolerance = pixelTolerance / zoom;
|
mTolerance = pixelTolerance / zoom;
|
||||||
@ -46,9 +66,10 @@ SnapManager::SnapManager(TrackList *tracks, TrackClipArray *exclusions,
|
|||||||
LabelTrack *labelTrack = (LabelTrack *)track;
|
LabelTrack *labelTrack = (LabelTrack *)track;
|
||||||
for(i = 0; i < labelTrack->GetNumLabels(); i++) {
|
for(i = 0; i < labelTrack->GetNumLabels(); i++) {
|
||||||
const LabelStruct *label = labelTrack->GetLabel(i);
|
const LabelStruct *label = labelTrack->GetLabel(i);
|
||||||
mSnapPoints->Add(new SnapPoint(label->t, labelTrack));
|
CondListAdd(label->t, labelTrack, ttc);
|
||||||
if (label->t1 != label->t)
|
if (label->t1 != label->t) {
|
||||||
mSnapPoints->Add(new SnapPoint(label->t1, labelTrack));
|
CondListAdd(label->t1, labelTrack, ttc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (track->GetKind() == Track::Wave) {
|
if (track->GetKind() == Track::Wave) {
|
||||||
@ -66,13 +87,26 @@ SnapManager::SnapManager(TrackList *tracks, TrackClipArray *exclusions,
|
|||||||
if (skip)
|
if (skip)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
mSnapPoints->Add(new SnapPoint(clip->GetStartTime(), waveTrack));
|
CondListAdd(clip->GetStartTime(), waveTrack, ttc);
|
||||||
mSnapPoints->Add(new SnapPoint(clip->GetEndTime(), waveTrack));
|
CondListAdd(clip->GetEndTime(), waveTrack, ttc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
track = iter.Next();
|
track = iter.Next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ttc)
|
||||||
|
delete ttc;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds to mSnapPoints, filtering by ttc if it's not NULL
|
||||||
|
void SnapManager::CondListAdd(double t, Track *tr, TimeTextCtrl *ttc)
|
||||||
|
{
|
||||||
|
if (ttc)
|
||||||
|
ttc->SetTimeValue(t);
|
||||||
|
|
||||||
|
if (!ttc || ttc->GetTimeValue() == t)
|
||||||
|
mSnapPoints->Add(new SnapPoint(t, tr));
|
||||||
}
|
}
|
||||||
|
|
||||||
SnapManager::~SnapManager()
|
SnapManager::~SnapManager()
|
||||||
@ -130,10 +164,11 @@ int SnapManager::Find(double t)
|
|||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SnapManager::Snap(Track *currentTrack,
|
// Helper: performs snap-to-points for Snap(). Returns true if a snap happened.
|
||||||
double t,
|
bool SnapManager::SnapToPoints(Track *currentTrack,
|
||||||
bool rightEdge,
|
double t,
|
||||||
double *out_t)
|
bool rightEdge,
|
||||||
|
double *out_t)
|
||||||
{
|
{
|
||||||
int len = (int)mSnapPoints->GetCount();
|
int len = (int)mSnapPoints->GetCount();
|
||||||
*out_t = t;
|
*out_t = t;
|
||||||
@ -193,6 +228,39 @@ bool SnapManager::Snap(Track *currentTrack,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SnapManager::Snap(Track *currentTrack,
|
||||||
|
double t,
|
||||||
|
bool rightEdge,
|
||||||
|
double *out_t,
|
||||||
|
bool *snappedPoint,
|
||||||
|
bool *snappedTime)
|
||||||
|
{
|
||||||
|
// First snap to points in mSnapPoints
|
||||||
|
*out_t = t;
|
||||||
|
*snappedPoint = SnapToPoints(currentTrack, t, rightEdge, out_t);
|
||||||
|
|
||||||
|
// Now snap to the time grid
|
||||||
|
*snappedTime = false;
|
||||||
|
if (mSnapToTime) {
|
||||||
|
if (*snappedPoint) {
|
||||||
|
// Since mSnapPoints only contains points on the grid, we're done
|
||||||
|
*snappedTime = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Snap time to the grid
|
||||||
|
AudacityProject *p = GetActiveProject();
|
||||||
|
TimeTextCtrl ttc(p, wxID_ANY, wxT(""), 0.0, p->GetRate());
|
||||||
|
ttc.SetFormatString(mFormat);
|
||||||
|
|
||||||
|
ttc.SetTimeValue(t);
|
||||||
|
*out_t = ttc.GetTimeValue();
|
||||||
|
*snappedTime = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return *snappedPoint || *snappedTime;
|
||||||
|
}
|
||||||
|
|
||||||
// Indentation settings for Vim and Emacs.
|
// Indentation settings for Vim and Emacs.
|
||||||
// Please do not modify past this point.
|
// Please do not modify past this point.
|
||||||
//
|
//
|
||||||
|
16
src/Snap.h
16
src/Snap.h
@ -22,6 +22,7 @@
|
|||||||
#include "ViewInfo.h"
|
#include "ViewInfo.h"
|
||||||
|
|
||||||
class TrackClipArray;
|
class TrackClipArray;
|
||||||
|
class TimeTextCtrl;
|
||||||
|
|
||||||
class SnapPoint {
|
class SnapPoint {
|
||||||
public:
|
public:
|
||||||
@ -37,8 +38,10 @@ WX_DEFINE_SORTED_ARRAY(SnapPoint *, SnapPointArray);
|
|||||||
|
|
||||||
class SnapManager {
|
class SnapManager {
|
||||||
public:
|
public:
|
||||||
|
// Set gridCtrl to a TimeTextCtrl to use for snap-to-time; if NULL we won't
|
||||||
|
// snap to time
|
||||||
SnapManager(TrackList *tracks, TrackClipArray *exclusions,
|
SnapManager(TrackList *tracks, TrackClipArray *exclusions,
|
||||||
double zoom, int pixelTolerance);
|
double zoom, int pixelTolerance, bool noTimeSnap = false);
|
||||||
|
|
||||||
~SnapManager();
|
~SnapManager();
|
||||||
|
|
||||||
@ -49,18 +52,27 @@ class SnapManager {
|
|||||||
bool Snap(Track *currentTrack,
|
bool Snap(Track *currentTrack,
|
||||||
double t,
|
double t,
|
||||||
bool rightEdge,
|
bool rightEdge,
|
||||||
double *out_t);
|
double *out_t,
|
||||||
|
bool *snappedPoint,
|
||||||
|
bool *snappedTime);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void CondListAdd(double t, Track *tr, TimeTextCtrl *ttc);
|
||||||
double Get(int index);
|
double Get(int index);
|
||||||
double Diff(double t, int index);
|
double Diff(double t, int index);
|
||||||
int Find(double t, int i0, int i1);
|
int Find(double t, int i0, int i1);
|
||||||
int Find(double t);
|
int Find(double t);
|
||||||
|
bool SnapToPoints(Track *currentTrack, double t, bool rightEdge,
|
||||||
|
double *out_t);
|
||||||
|
|
||||||
double mEpsilon;
|
double mEpsilon;
|
||||||
double mTolerance;
|
double mTolerance;
|
||||||
double mZoom;
|
double mZoom;
|
||||||
SnapPointArray *mSnapPoints;
|
SnapPointArray *mSnapPoints;
|
||||||
|
|
||||||
|
// Info for snap-to-time
|
||||||
|
bool mSnapToTime;
|
||||||
|
wxString mFormat;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -215,6 +215,7 @@ is time to refresh some aspect of the screen.
|
|||||||
|
|
||||||
#include "widgets/ASlider.h"
|
#include "widgets/ASlider.h"
|
||||||
#include "widgets/Ruler.h"
|
#include "widgets/Ruler.h"
|
||||||
|
#include "widgets/TimeTextCtrl.h"
|
||||||
|
|
||||||
#include <wx/arrimpl.cpp>
|
#include <wx/arrimpl.cpp>
|
||||||
|
|
||||||
@ -443,8 +444,8 @@ TrackPanel::TrackPanel(wxWindow * parent, wxWindowID id,
|
|||||||
mBacking(NULL),
|
mBacking(NULL),
|
||||||
mRefreshBacking(false),
|
mRefreshBacking(false),
|
||||||
mAutoScrolling(false),
|
mAutoScrolling(false),
|
||||||
vrulerSize(36,0),
|
mVertScrollRemainder(0),
|
||||||
mVertScrollRemainder(0)
|
vrulerSize(36,0)
|
||||||
#ifndef __WXGTK__ //Get rid if this pragma for gtk
|
#ifndef __WXGTK__ //Get rid if this pragma for gtk
|
||||||
#pragma warning( default: 4355 )
|
#pragma warning( default: 4355 )
|
||||||
#endif
|
#endif
|
||||||
@ -1791,13 +1792,9 @@ void TrackPanel::SelectionHandleClick(wxMouseEvent & event,
|
|||||||
if (mSnapManager)
|
if (mSnapManager)
|
||||||
delete mSnapManager;
|
delete mSnapManager;
|
||||||
|
|
||||||
// "/SnapTo" pref refers to snapping to time. Don't use the snap manager in
|
mSnapManager = new SnapManager(mTracks, NULL,
|
||||||
// this case
|
mViewInfo->zoom,
|
||||||
if (gPrefs->Read(wxT("/SnapTo"), 0L) == 0) {
|
4); // pixel tolerance
|
||||||
mSnapManager = new SnapManager(mTracks, NULL,
|
|
||||||
mViewInfo->zoom,
|
|
||||||
4); // pixel tolerance
|
|
||||||
}
|
|
||||||
mSnapLeft = -1;
|
mSnapLeft = -1;
|
||||||
mSnapRight = -1;
|
mSnapRight = -1;
|
||||||
|
|
||||||
@ -1938,8 +1935,11 @@ void TrackPanel::StartSelection(int mouseXCoordinate, int trackLeftEdge)
|
|||||||
if (mSnapManager) {
|
if (mSnapManager) {
|
||||||
mSnapLeft = -1;
|
mSnapLeft = -1;
|
||||||
mSnapRight = -1;
|
mSnapRight = -1;
|
||||||
if (mSnapManager->Snap(mCapturedTrack, mSelStart, false, &s)) {
|
bool snappedPoint, snappedTime;
|
||||||
mSnapLeft = TimeToPosition(s, trackLeftEdge);
|
if (mSnapManager->Snap(mCapturedTrack, mSelStart, false,
|
||||||
|
&s, &snappedPoint, &snappedTime)) {
|
||||||
|
if (snappedPoint)
|
||||||
|
mSnapLeft = TimeToPosition(s, trackLeftEdge);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1978,15 +1978,22 @@ void TrackPanel::ExtendSelection(int mouseXCoordinate, int trackLeftEdge,
|
|||||||
if (mSnapManager) {
|
if (mSnapManager) {
|
||||||
mSnapLeft = -1;
|
mSnapLeft = -1;
|
||||||
mSnapRight = -1;
|
mSnapRight = -1;
|
||||||
if (mSnapManager->Snap(mCapturedTrack, sel0, false, &sel0)) {
|
bool snappedPoint, snappedTime;
|
||||||
mSnapLeft = TimeToPosition(sel0, trackLeftEdge);
|
if (mSnapManager->Snap(mCapturedTrack, sel0, false,
|
||||||
|
&sel0, &snappedPoint, &snappedTime)) {
|
||||||
|
if (snappedPoint)
|
||||||
|
mSnapLeft = TimeToPosition(sel0, trackLeftEdge);
|
||||||
}
|
}
|
||||||
if (mSnapManager->Snap(mCapturedTrack, sel1, true, &sel1)) {
|
if (mSnapManager->Snap(mCapturedTrack, sel1, true,
|
||||||
mSnapRight = TimeToPosition(sel1, trackLeftEdge);
|
&sel1, &snappedPoint, &snappedTime)) {
|
||||||
|
if (snappedPoint)
|
||||||
|
mSnapRight = TimeToPosition(sel1, trackLeftEdge);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSnapLeft >= 0 && mSnapRight >= 0 && mSnapRight - mSnapLeft < 3) {
|
// Check if selection endpoints are too close together to snap (unless
|
||||||
// Too close together. Better not to snap at all.
|
// using snap-to-time -- then we always accept the snap results)
|
||||||
|
if (mSnapLeft >= 0 && mSnapRight >= 0 && mSnapRight - mSnapLeft < 3 &&
|
||||||
|
!snappedTime) {
|
||||||
sel0 = origSel0;
|
sel0 = origSel0;
|
||||||
sel1 = origSel1;
|
sel1 = origSel1;
|
||||||
mSnapLeft = -1;
|
mSnapLeft = -1;
|
||||||
@ -2415,7 +2422,8 @@ void TrackPanel::StartSlide(wxMouseEvent & event)
|
|||||||
mSnapManager = new SnapManager(mTracks,
|
mSnapManager = new SnapManager(mTracks,
|
||||||
&mCapturedClipArray,
|
&mCapturedClipArray,
|
||||||
mViewInfo->zoom,
|
mViewInfo->zoom,
|
||||||
4); // pixel tolerance
|
4, // pixel tolerance
|
||||||
|
true); // don't snap to time
|
||||||
mSnapLeft = -1;
|
mSnapLeft = -1;
|
||||||
mSnapRight = -1;
|
mSnapRight = -1;
|
||||||
mSnapPreferRightEdge = false;
|
mSnapPreferRightEdge = false;
|
||||||
@ -2510,8 +2518,11 @@ void TrackPanel::DoSlide(wxMouseEvent & event)
|
|||||||
double newClipLeft = clipLeft;
|
double newClipLeft = clipLeft;
|
||||||
double newClipRight = clipRight;
|
double newClipRight = clipRight;
|
||||||
|
|
||||||
mSnapManager->Snap(mCapturedTrack, clipLeft, false, &newClipLeft);
|
bool dummy1, dummy2;
|
||||||
mSnapManager->Snap(mCapturedTrack, clipRight, false, &newClipRight);
|
mSnapManager->Snap(mCapturedTrack, clipLeft, false, &newClipLeft,
|
||||||
|
&dummy1, &dummy2);
|
||||||
|
mSnapManager->Snap(mCapturedTrack, clipRight, false, &newClipRight,
|
||||||
|
&dummy1, &dummy2);
|
||||||
|
|
||||||
// Only one of them is allowed to snap
|
// Only one of them is allowed to snap
|
||||||
if (newClipLeft != clipLeft && newClipRight != clipRight) {
|
if (newClipLeft != clipLeft && newClipRight != clipRight) {
|
||||||
@ -5518,11 +5529,18 @@ void TrackPanel::OnCursorLeft( bool shift, bool ctrl )
|
|||||||
// Get currently focused track if there is one
|
// Get currently focused track if there is one
|
||||||
t = GetFocusedTrack();
|
t = GetFocusedTrack();
|
||||||
|
|
||||||
|
bool snapToTime = (gPrefs->Read(wxT("/SnapTo"), 0L) != 0);
|
||||||
|
|
||||||
// Contract selection from the right to the left
|
// Contract selection from the right to the left
|
||||||
if( shift && ctrl )
|
if( shift && ctrl )
|
||||||
{
|
{
|
||||||
// Reduce and constrain (counter-intuitive)
|
// Reduce and constrain (counter-intuitive)
|
||||||
mViewInfo->sel1 -= multiplier / mViewInfo->zoom;
|
if (snapToTime) {
|
||||||
|
mViewInfo->sel1 = GridMove(mViewInfo->sel1, -multiplier);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mViewInfo->sel1 -= multiplier / mViewInfo->zoom;
|
||||||
|
}
|
||||||
if( mViewInfo->sel1 < mViewInfo->sel0 )
|
if( mViewInfo->sel1 < mViewInfo->sel0 )
|
||||||
{
|
{
|
||||||
mViewInfo->sel1 = mViewInfo->sel0;
|
mViewInfo->sel1 = mViewInfo->sel0;
|
||||||
@ -5546,7 +5564,12 @@ void TrackPanel::OnCursorLeft( bool shift, bool ctrl )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Expand and constrain
|
// Expand and constrain
|
||||||
mViewInfo->sel0 -= multiplier / mViewInfo->zoom;
|
if (snapToTime) {
|
||||||
|
mViewInfo->sel0 = GridMove(mViewInfo->sel0, -multiplier);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mViewInfo->sel0 -= multiplier / mViewInfo->zoom;
|
||||||
|
}
|
||||||
if( mViewInfo->sel0 < 0.0 )
|
if( mViewInfo->sel0 < 0.0 )
|
||||||
{
|
{
|
||||||
mViewInfo->sel0 = 0.0;
|
mViewInfo->sel0 = 0.0;
|
||||||
@ -5573,7 +5596,12 @@ void TrackPanel::OnCursorLeft( bool shift, bool ctrl )
|
|||||||
if( mViewInfo->sel0 == mViewInfo->sel1 )
|
if( mViewInfo->sel0 == mViewInfo->sel1 )
|
||||||
{
|
{
|
||||||
// Move and constrain
|
// Move and constrain
|
||||||
mViewInfo->sel0 -= multiplier / mViewInfo->zoom;
|
if (snapToTime) {
|
||||||
|
mViewInfo->sel0 = GridMove(mViewInfo->sel0, -multiplier);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mViewInfo->sel0 -= multiplier / mViewInfo->zoom;
|
||||||
|
}
|
||||||
if( mViewInfo->sel0 < 0.0 )
|
if( mViewInfo->sel0 < 0.0 )
|
||||||
{
|
{
|
||||||
mViewInfo->sel0 = 0.0;
|
mViewInfo->sel0 = 0.0;
|
||||||
@ -5616,11 +5644,18 @@ void TrackPanel::OnCursorRight( bool shift, bool ctrl )
|
|||||||
// Get currently focused track if there is one
|
// Get currently focused track if there is one
|
||||||
t = GetFocusedTrack();
|
t = GetFocusedTrack();
|
||||||
|
|
||||||
|
bool snapToTime = (gPrefs->Read(wxT("/SnapTo"), 0L) != 0);
|
||||||
|
|
||||||
// Contract selection from the left to the right
|
// Contract selection from the left to the right
|
||||||
if( shift && ctrl )
|
if( shift && ctrl )
|
||||||
{
|
{
|
||||||
// Reduce and constrain (counter-intuitive)
|
// Reduce and constrain (counter-intuitive)
|
||||||
mViewInfo->sel0 += multiplier / mViewInfo->zoom;
|
if (snapToTime) {
|
||||||
|
mViewInfo->sel0 = GridMove(mViewInfo->sel0, multiplier);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mViewInfo->sel0 += multiplier / mViewInfo->zoom;
|
||||||
|
}
|
||||||
if( mViewInfo->sel0 > mViewInfo->sel1 )
|
if( mViewInfo->sel0 > mViewInfo->sel1 )
|
||||||
{
|
{
|
||||||
mViewInfo->sel0 = mViewInfo->sel1;
|
mViewInfo->sel0 = mViewInfo->sel1;
|
||||||
@ -5644,7 +5679,12 @@ void TrackPanel::OnCursorRight( bool shift, bool ctrl )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Expand and constrain
|
// Expand and constrain
|
||||||
mViewInfo->sel1 += multiplier/mViewInfo->zoom;
|
if (snapToTime) {
|
||||||
|
mViewInfo->sel1 = GridMove(mViewInfo->sel1, multiplier);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mViewInfo->sel1 += multiplier/mViewInfo->zoom;
|
||||||
|
}
|
||||||
double end = mTracks->GetEndTime();
|
double end = mTracks->GetEndTime();
|
||||||
if( mViewInfo->sel1 > end )
|
if( mViewInfo->sel1 > end )
|
||||||
{
|
{
|
||||||
@ -5672,7 +5712,12 @@ void TrackPanel::OnCursorRight( bool shift, bool ctrl )
|
|||||||
if (mViewInfo->sel0 == mViewInfo->sel1)
|
if (mViewInfo->sel0 == mViewInfo->sel1)
|
||||||
{
|
{
|
||||||
// Move and constrain
|
// Move and constrain
|
||||||
mViewInfo->sel1 += multiplier / mViewInfo->zoom;
|
if (snapToTime) {
|
||||||
|
mViewInfo->sel1 = GridMove(mViewInfo->sel1, multiplier);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mViewInfo->sel1 += multiplier / mViewInfo->zoom;
|
||||||
|
}
|
||||||
double end = mTracks->GetEndTime();
|
double end = mTracks->GetEndTime();
|
||||||
if( mViewInfo->sel1 > end )
|
if( mViewInfo->sel1 > end )
|
||||||
{
|
{
|
||||||
@ -5699,6 +5744,34 @@ void TrackPanel::OnCursorRight( bool shift, bool ctrl )
|
|||||||
MakeParentModifyState();
|
MakeParentModifyState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handles moving a selection edge with the keyboard in snap-to-time mode;
|
||||||
|
// returns the moved value.
|
||||||
|
// Will move at least minPix pixels -- set minPix positive to move forward,
|
||||||
|
// negative to move backward.
|
||||||
|
double TrackPanel::GridMove(double t, int minPix)
|
||||||
|
{
|
||||||
|
TimeTextCtrl ttc(this, wxID_ANY, wxT(""), 0.0, GetProject()->GetRate());
|
||||||
|
wxString formatName;
|
||||||
|
gPrefs->Read(wxT("/SelectionFormat"), &formatName);
|
||||||
|
ttc.SetFormatString(ttc.GetBuiltinFormat(formatName));
|
||||||
|
ttc.SetTimeValue(t);
|
||||||
|
|
||||||
|
// Try incrementing/decrementing the value; if we've moved far enough we're
|
||||||
|
// done
|
||||||
|
double result;
|
||||||
|
minPix >= 0 ? ttc.Increment() : ttc.Decrement();
|
||||||
|
result = ttc.GetTimeValue();
|
||||||
|
if (fabs(result - t) * mViewInfo->zoom >= fabs(minPix)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, move minPix pixels, then snap to the time.
|
||||||
|
result = t + minPix / mViewInfo->zoom;
|
||||||
|
ttc.SetTimeValue(result);
|
||||||
|
result = ttc.GetTimeValue();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void TrackPanel::OnBoundaryMove(bool left, bool boundaryContract)
|
void TrackPanel::OnBoundaryMove(bool left, bool boundaryContract)
|
||||||
{
|
{
|
||||||
// Move the left/right selection boundary, to either expand or contract the selection
|
// Move the left/right selection boundary, to either expand or contract the selection
|
||||||
|
@ -254,6 +254,8 @@ class TrackPanel:public wxPanel {
|
|||||||
void SelectTracksByLabel( LabelTrack *t );
|
void SelectTracksByLabel( LabelTrack *t );
|
||||||
void SelectTrackLength(Track *t);
|
void SelectTrackLength(Track *t);
|
||||||
|
|
||||||
|
// Helper for moving by keyboard with snap-to-grid enabled
|
||||||
|
double GridMove(double t, int minPix);
|
||||||
|
|
||||||
// AS: Cursor handling
|
// AS: Cursor handling
|
||||||
bool SetCursorByActivity( );
|
bool SetCursorByActivity( );
|
||||||
|
@ -106,25 +106,14 @@ void SelectionBar::Populate()
|
|||||||
wxFlexGridSizer *mainSizer;
|
wxFlexGridSizer *mainSizer;
|
||||||
wxBoxSizer *hSizer;
|
wxBoxSizer *hSizer;
|
||||||
|
|
||||||
int formatIndex = 1;
|
|
||||||
/* we don't actually need a control yet, but we want to use it's methods
|
/* we don't actually need a control yet, but we want to use it's methods
|
||||||
* to do some look-ups, so we'll have to create one. We can't make the
|
* to do some look-ups, so we'll have to create one. We can't make the
|
||||||
* look-ups static because they depend on translations which are done at
|
* look-ups static because they depend on translations which are done at
|
||||||
* runtime */
|
* runtime */
|
||||||
TimeTextCtrl *ttc = new TimeTextCtrl(this, wxID_ANY, wxT(""), 0.0, mRate);
|
TimeTextCtrl *ttc = new TimeTextCtrl(this, wxID_ANY, wxT(""), 0.0, mRate);
|
||||||
wxString formatName;
|
wxString formatName;
|
||||||
if (gPrefs->Read(wxT("/SelectionFormat"), &formatName)) {
|
gPrefs->Read(wxT("/SelectionFormat"), &formatName);
|
||||||
for(int i = 0; i < ttc->GetNumBuiltins(); i++) {
|
wxString format = ttc->GetBuiltinFormat(formatName);
|
||||||
if (ttc->GetBuiltinName(i) == formatName) {
|
|
||||||
formatIndex = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
formatIndex = 1;
|
|
||||||
|
|
||||||
wxString format = ttc->GetBuiltinFormat(formatIndex);
|
|
||||||
delete ttc;
|
delete ttc;
|
||||||
|
|
||||||
mainSizer = new wxFlexGridSizer(7, 1, 1);
|
mainSizer = new wxFlexGridSizer(7, 1, 1);
|
||||||
|
@ -469,6 +469,18 @@ void TimeTextCtrl::SetTimeValue(double newTime)
|
|||||||
ControlsToValue();
|
ControlsToValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TimeTextCtrl::Increment()
|
||||||
|
{
|
||||||
|
mFocusedDigit = mDigits.GetCount() - 1;
|
||||||
|
Increase(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeTextCtrl::Decrement()
|
||||||
|
{
|
||||||
|
mFocusedDigit = mDigits.GetCount() - 1;
|
||||||
|
Decrease(1);
|
||||||
|
}
|
||||||
|
|
||||||
void TimeTextCtrl::EnableMenu(bool enable)
|
void TimeTextCtrl::EnableMenu(bool enable)
|
||||||
{
|
{
|
||||||
#if wxUSE_TOOLTIPS
|
#if wxUSE_TOOLTIPS
|
||||||
|
@ -67,6 +67,8 @@ class TimeTextCtrl: public wxControl{
|
|||||||
void SetFormatString(wxString formatString);
|
void SetFormatString(wxString formatString);
|
||||||
void SetSampleRate(double sampleRate);
|
void SetSampleRate(double sampleRate);
|
||||||
void SetTimeValue(double newTime);
|
void SetTimeValue(double newTime);
|
||||||
|
void Increment();
|
||||||
|
void Decrement();
|
||||||
const double GetTimeValue();
|
const double GetTimeValue();
|
||||||
|
|
||||||
wxString GetTimeString();
|
wxString GetTimeString();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user