mirror of
https://github.com/cookiengineer/audacity
synced 2025-08-02 17:09:26 +02:00
[Bug 647] Snap-To clicks find nearest snap point, not nearest previous.
Convert SnapTo from on/off to a choice of off/nearest/prior.
This commit is contained in:
parent
05302d7483
commit
ce00d5b507
@ -107,6 +107,7 @@ scroll information. It also has some status flags.
|
|||||||
#include "Mix.h"
|
#include "Mix.h"
|
||||||
#include "NoteTrack.h"
|
#include "NoteTrack.h"
|
||||||
#include "Prefs.h"
|
#include "Prefs.h"
|
||||||
|
#include "Snap.h"
|
||||||
#include "Tags.h"
|
#include "Tags.h"
|
||||||
#include "Track.h"
|
#include "Track.h"
|
||||||
#include "TrackPanel.h"
|
#include "TrackPanel.h"
|
||||||
@ -729,7 +730,7 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id,
|
|||||||
mRate((double) gPrefs->Read(wxT("/SamplingRate/DefaultProjectSampleRate"), AudioIO::GetOptimalSupportedSampleRate())),
|
mRate((double) gPrefs->Read(wxT("/SamplingRate/DefaultProjectSampleRate"), AudioIO::GetOptimalSupportedSampleRate())),
|
||||||
mDefaultFormat((sampleFormat) gPrefs->
|
mDefaultFormat((sampleFormat) gPrefs->
|
||||||
Read(wxT("/SamplingRate/DefaultProjectSampleFormat"), floatSample)),
|
Read(wxT("/SamplingRate/DefaultProjectSampleFormat"), floatSample)),
|
||||||
mSnapTo((bool) gPrefs->Read(wxT("/SnapTo"), (long) false)),
|
mSnapTo(gPrefs->Read(wxT("/SnapTo"), SNAP_OFF)),
|
||||||
mSelectionFormat(gPrefs->Read(wxT("/SelectionFormat"), wxT(""))),
|
mSelectionFormat(gPrefs->Read(wxT("/SelectionFormat"), wxT(""))),
|
||||||
mDirty(false),
|
mDirty(false),
|
||||||
mTrackPanel(NULL),
|
mTrackPanel(NULL),
|
||||||
@ -1184,16 +1185,17 @@ void AudacityProject::AS_SetRate(double rate)
|
|||||||
mRate = rate;
|
mRate = rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudacityProject::AS_GetSnapTo()
|
int AudacityProject::AS_GetSnapTo()
|
||||||
{
|
{
|
||||||
return GetSnapTo();
|
return GetSnapTo();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudacityProject::AS_SetSnapTo(bool state)
|
void AudacityProject::AS_SetSnapTo(int snap)
|
||||||
{
|
{
|
||||||
mSnapTo = state;
|
mSnapTo = snap;
|
||||||
|
|
||||||
mCommandManager.Check(wxT("Snap"), mSnapTo);
|
// LLL: TODO - what should this be changed to???
|
||||||
|
// mCommandManager.Check(wxT("Snap"), mSnapTo);
|
||||||
gPrefs->Write(wxT("/SnapTo"), mSnapTo);
|
gPrefs->Write(wxT("/SnapTo"), mSnapTo);
|
||||||
gPrefs->Flush();
|
gPrefs->Flush();
|
||||||
|
|
||||||
@ -4565,15 +4567,15 @@ bool AudacityProject::GetCacheBlockFiles()
|
|||||||
return cacheBlockFiles;
|
return cacheBlockFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudacityProject::SetSnapTo(bool state)
|
void AudacityProject::SetSnapTo(int snap)
|
||||||
{
|
{
|
||||||
AS_SetSnapTo(state);
|
AS_SetSnapTo(snap);
|
||||||
if (GetSelectionBar()) {
|
if (GetSelectionBar()) {
|
||||||
GetSelectionBar()->SetSnapTo(state);
|
GetSelectionBar()->SetSnapTo(snap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudacityProject::GetSnapTo()
|
int AudacityProject::GetSnapTo()
|
||||||
{
|
{
|
||||||
return mSnapTo;
|
return mSnapTo;
|
||||||
}
|
}
|
||||||
|
@ -303,8 +303,8 @@ class AUDACITY_DLL_API AudacityProject: public wxFrame,
|
|||||||
|
|
||||||
// Snap To
|
// Snap To
|
||||||
|
|
||||||
void SetSnapTo(bool state);
|
void SetSnapTo(int snap);
|
||||||
bool GetSnapTo();
|
int GetSnapTo();
|
||||||
|
|
||||||
// Selection Format
|
// Selection Format
|
||||||
|
|
||||||
@ -367,8 +367,8 @@ class AUDACITY_DLL_API AudacityProject: public wxFrame,
|
|||||||
|
|
||||||
virtual double AS_GetRate();
|
virtual double AS_GetRate();
|
||||||
virtual void AS_SetRate(double rate);
|
virtual void AS_SetRate(double rate);
|
||||||
virtual bool AS_GetSnapTo();
|
virtual int AS_GetSnapTo();
|
||||||
virtual void AS_SetSnapTo(bool state);
|
virtual void AS_SetSnapTo(int snap);
|
||||||
virtual const wxString & AS_GetSelectionFormat();
|
virtual const wxString & AS_GetSelectionFormat();
|
||||||
virtual void AS_SetSelectionFormat(const wxString & format);
|
virtual void AS_SetSelectionFormat(const wxString & format);
|
||||||
virtual void AS_ModifySelection(double &start, double &end, bool done);
|
virtual void AS_ModifySelection(double &start, double &end, bool done);
|
||||||
@ -445,7 +445,7 @@ class AUDACITY_DLL_API AudacityProject: public wxFrame,
|
|||||||
// List of tracks and display info
|
// List of tracks and display info
|
||||||
TrackList *mTracks;
|
TrackList *mTracks;
|
||||||
|
|
||||||
bool mSnapTo;
|
int mSnapTo;
|
||||||
wxString mSelectionFormat;
|
wxString mSelectionFormat;
|
||||||
|
|
||||||
TrackList *mLastSavedTracks;
|
TrackList *mLastSavedTracks;
|
||||||
|
49
src/Snap.cpp
49
src/Snap.cpp
@ -255,7 +255,7 @@ bool SnapManager::Snap(Track *currentTrack,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Snap time to the grid
|
// Snap time to the grid
|
||||||
mConverter.ValueToControls(t, SNAP_TO_NEAREST);
|
mConverter.ValueToControls(t, GetActiveProject()->GetSnapTo() == SNAP_NEAREST);
|
||||||
mConverter.ControlsToValue();
|
mConverter.ControlsToValue();
|
||||||
*out_t = mConverter.GetTimeValue();
|
*out_t = mConverter.GetTimeValue();
|
||||||
*snappedTime = true;
|
*snappedTime = true;
|
||||||
@ -264,3 +264,50 @@ bool SnapManager::Snap(Track *currentTrack,
|
|||||||
|
|
||||||
return *snappedPoint || *snappedTime;
|
return *snappedPoint || *snappedTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ wxArrayString SnapManager::GetSnapLabels()
|
||||||
|
{
|
||||||
|
wxArrayString labels;
|
||||||
|
|
||||||
|
labels.Add(_("Off"));
|
||||||
|
labels.Add(_("Nearest"));
|
||||||
|
labels.Add(_("Prior"));
|
||||||
|
|
||||||
|
return labels;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ wxArrayString SnapManager::GetSnapValues()
|
||||||
|
{
|
||||||
|
wxArrayString values;
|
||||||
|
|
||||||
|
values.Add(wxT("Off"));
|
||||||
|
values.Add(wxT("Nearest"));
|
||||||
|
values.Add(wxT("Prior"));
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ const wxString & SnapManager::GetSnapValue(int index)
|
||||||
|
{
|
||||||
|
wxArrayString values = SnapManager::GetSnapValues();
|
||||||
|
|
||||||
|
if (index >= 0 && index < (int) values.GetCount())
|
||||||
|
{
|
||||||
|
return values[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
return values[SNAP_OFF];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ int SnapManager::GetSnapIndex(const wxString & value)
|
||||||
|
{
|
||||||
|
wxArrayString values = SnapManager::GetSnapValues();
|
||||||
|
int index = values.Index(value);
|
||||||
|
|
||||||
|
if (index != wxNOT_FOUND)
|
||||||
|
{
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SNAP_OFF;
|
||||||
|
}
|
||||||
|
12
src/Snap.h
12
src/Snap.h
@ -23,6 +23,13 @@
|
|||||||
|
|
||||||
class TrackClipArray;
|
class TrackClipArray;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SNAP_OFF,
|
||||||
|
SNAP_NEAREST,
|
||||||
|
SNAP_PRIOR
|
||||||
|
};
|
||||||
|
|
||||||
class SnapPoint {
|
class SnapPoint {
|
||||||
public:
|
public:
|
||||||
SnapPoint(double t, Track *track) {
|
SnapPoint(double t, Track *track) {
|
||||||
@ -53,6 +60,11 @@ class SnapManager {
|
|||||||
bool *snappedPoint,
|
bool *snappedPoint,
|
||||||
bool *snappedTime);
|
bool *snappedTime);
|
||||||
|
|
||||||
|
static wxArrayString GetSnapLabels();
|
||||||
|
static wxArrayString GetSnapValues();
|
||||||
|
static const wxString & GetSnapValue(int index);
|
||||||
|
static int GetSnapIndex(const wxString & value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CondListAdd(double t, Track *tr);
|
void CondListAdd(double t, Track *tr);
|
||||||
double Get(int index);
|
double Get(int index);
|
||||||
|
@ -6516,7 +6516,7 @@ void TrackPanel::OnCursorLeft( bool shift, bool ctrl, bool keyup )
|
|||||||
}
|
}
|
||||||
mLastSelectionAdjustment = curtime;
|
mLastSelectionAdjustment = curtime;
|
||||||
|
|
||||||
bool snapToTime = GetActiveProject()->GetSnapTo();
|
int snapToTime = GetActiveProject()->GetSnapTo();
|
||||||
|
|
||||||
// Contract selection from the right to the left
|
// Contract selection from the right to the left
|
||||||
if( shift && ctrl )
|
if( shift && ctrl )
|
||||||
@ -6630,7 +6630,7 @@ void TrackPanel::OnCursorRight( bool shift, bool ctrl, bool keyup )
|
|||||||
}
|
}
|
||||||
mLastSelectionAdjustment = curtime;
|
mLastSelectionAdjustment = curtime;
|
||||||
|
|
||||||
bool snapToTime = GetActiveProject()->GetSnapTo();
|
int snapToTime = GetActiveProject()->GetSnapTo();
|
||||||
|
|
||||||
// Contract selection from the left to the right
|
// Contract selection from the left to the right
|
||||||
if( shift && ctrl )
|
if( shift && ctrl )
|
||||||
|
@ -49,6 +49,7 @@ with changes in the SelectionBar.
|
|||||||
#include "../AudioIO.h"
|
#include "../AudioIO.h"
|
||||||
#include "../AColor.h"
|
#include "../AColor.h"
|
||||||
#include "../Prefs.h"
|
#include "../Prefs.h"
|
||||||
|
#include "../Snap.h"
|
||||||
#include "../widgets/TimeTextCtrl.h"
|
#include "../widgets/TimeTextCtrl.h"
|
||||||
|
|
||||||
IMPLEMENT_CLASS(SelectionBar, ToolBar);
|
IMPLEMENT_CLASS(SelectionBar, ToolBar);
|
||||||
@ -75,7 +76,7 @@ BEGIN_EVENT_TABLE(SelectionBar, ToolBar)
|
|||||||
EVT_TEXT(OnRightTimeID, SelectionBar::OnRightTime)
|
EVT_TEXT(OnRightTimeID, SelectionBar::OnRightTime)
|
||||||
EVT_RADIOBUTTON(OnLengthRadioID, SelectionBar::OnLengthRadio)
|
EVT_RADIOBUTTON(OnLengthRadioID, SelectionBar::OnLengthRadio)
|
||||||
EVT_RADIOBUTTON(OnEndRadioID, SelectionBar::OnEndRadio)
|
EVT_RADIOBUTTON(OnEndRadioID, SelectionBar::OnEndRadio)
|
||||||
EVT_CHECKBOX(OnSnapToID, SelectionBar::OnSnapTo)
|
EVT_CHOICE(OnSnapToID, SelectionBar::OnSnapTo)
|
||||||
EVT_COMBOBOX(OnRateID, SelectionBar::OnRate)
|
EVT_COMBOBOX(OnRateID, SelectionBar::OnRate)
|
||||||
EVT_TEXT(OnRateID, SelectionBar::OnRate)
|
EVT_TEXT(OnRateID, SelectionBar::OnRate)
|
||||||
EVT_COMMAND(wxID_ANY, EVT_TIMETEXTCTRL_UPDATED, SelectionBar::OnUpdate)
|
EVT_COMMAND(wxID_ANY, EVT_TIMETEXTCTRL_UPDATED, SelectionBar::OnUpdate)
|
||||||
@ -135,7 +136,8 @@ void SelectionBar::Populate()
|
|||||||
|
|
||||||
mainSizer->Add(5, 1);
|
mainSizer->Add(5, 1);
|
||||||
|
|
||||||
mainSizer->Add(5, 1);
|
mainSizer->Add(new wxStaticText(this, -1, _("Snap To:")),
|
||||||
|
0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
|
||||||
|
|
||||||
mainSizer->Add(new wxStaticText(this, -1, _("Selection Start:")),
|
mainSizer->Add(new wxStaticText(this, -1, _("Selection Start:")),
|
||||||
0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
|
0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
|
||||||
@ -223,21 +225,14 @@ void SelectionBar::Populate()
|
|||||||
wxSize(1, toolbarSingle),
|
wxSize(1, toolbarSingle),
|
||||||
wxLI_VERTICAL),
|
wxLI_VERTICAL),
|
||||||
0, wxRIGHT, 5);
|
0, wxRIGHT, 5);
|
||||||
/* i18n-hint: The snap-to mode, when enabled, means for example that selections
|
|
||||||
* are always at whole second boundaries. You can't select a range 4.5s to 7.9s
|
mSnapTo = new wxChoice(this, OnSnapToID,
|
||||||
* because the boundaries 'snap to' the nearest whole number.*/
|
|
||||||
mSnapTo = new wxCheckBox(this, OnSnapToID, _("Snap To"),
|
|
||||||
wxDefaultPosition, wxDefaultSize,
|
wxDefaultPosition, wxDefaultSize,
|
||||||
#if defined(__WXGTK__)
|
SnapManager::GetSnapLabels());
|
||||||
// See bug #356 for explanation
|
|
||||||
wxALIGN_LEFT);
|
|
||||||
#else
|
|
||||||
wxALIGN_RIGHT);
|
|
||||||
#endif
|
|
||||||
mainSizer->Add(mSnapTo,
|
mainSizer->Add(mSnapTo,
|
||||||
0, wxALIGN_CENTER_VERTICAL | wxALIGN_CENTER | wxRIGHT, 5);
|
0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
|
||||||
mSnapTo->SetName(_("Snap To"));
|
mSnapTo->SetName(_("Snap To"));
|
||||||
mSnapTo->SetValue(mListener ? mListener->AS_GetSnapTo() : false);
|
mSnapTo->SetSelection(mListener ? mListener->AS_GetSnapTo() : SNAP_OFF);
|
||||||
#if wxUSE_TOOLTIPS
|
#if wxUSE_TOOLTIPS
|
||||||
mSnapTo->SetToolTip(wxString::Format(_("Snap Clicks/Selections to %s"), formatName.c_str()));
|
mSnapTo->SetToolTip(wxString::Format(_("Snap Clicks/Selections to %s"), formatName.c_str()));
|
||||||
#endif
|
#endif
|
||||||
@ -466,9 +461,9 @@ void SelectionBar::SetField(const wxChar *msg, int fieldNum)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectionBar::SetSnapTo(bool state)
|
void SelectionBar::SetSnapTo(int snap)
|
||||||
{
|
{
|
||||||
mSnapTo->SetValue(state);
|
mSnapTo->SetSelection(snap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectionBar::SetSelectionFormat(const wxString & format)
|
void SelectionBar::SetSelectionFormat(const wxString & format)
|
||||||
@ -571,7 +566,7 @@ void SelectionBar::OnCaptureKey(wxCommandEvent &event)
|
|||||||
|
|
||||||
void SelectionBar::OnSnapTo(wxCommandEvent & WXUNUSED(event))
|
void SelectionBar::OnSnapTo(wxCommandEvent & WXUNUSED(event))
|
||||||
{
|
{
|
||||||
mListener->AS_SetSnapTo(mSnapTo->GetValue());
|
mListener->AS_SetSnapTo(mSnapTo->GetSelection());
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -34,8 +34,8 @@ class AUDACITY_DLL_API SelectionBarListener {
|
|||||||
|
|
||||||
virtual double AS_GetRate() = 0;
|
virtual double AS_GetRate() = 0;
|
||||||
virtual void AS_SetRate(double rate) = 0;
|
virtual void AS_SetRate(double rate) = 0;
|
||||||
virtual bool AS_GetSnapTo() = 0;
|
virtual int AS_GetSnapTo() = 0;
|
||||||
virtual void AS_SetSnapTo(bool state) = 0;
|
virtual void AS_SetSnapTo(int snap) = 0;
|
||||||
virtual const wxString & AS_GetSelectionFormat() = 0;
|
virtual const wxString & AS_GetSelectionFormat() = 0;
|
||||||
virtual void AS_SetSelectionFormat(const wxString & format) = 0;
|
virtual void AS_SetSelectionFormat(const wxString & format) = 0;
|
||||||
virtual void AS_ModifySelection(double &start, double &end, bool done) = 0;
|
virtual void AS_ModifySelection(double &start, double &end, bool done) = 0;
|
||||||
@ -59,7 +59,7 @@ class SelectionBar:public ToolBar {
|
|||||||
double GetLeftTime();
|
double GetLeftTime();
|
||||||
double GetRightTime();
|
double GetRightTime();
|
||||||
void SetField(const wxChar *msg, int fieldNum);
|
void SetField(const wxChar *msg, int fieldNum);
|
||||||
void SetSnapTo(bool state);
|
void SetSnapTo(int);
|
||||||
void SetSelectionFormat(const wxString & format);
|
void SetSelectionFormat(const wxString & format);
|
||||||
void SetRate(double rate);
|
void SetRate(double rate);
|
||||||
void SetListener(SelectionBarListener *l);
|
void SetListener(SelectionBarListener *l);
|
||||||
@ -99,7 +99,7 @@ class SelectionBar:public ToolBar {
|
|||||||
TimeTextCtrl *mAudioTime;
|
TimeTextCtrl *mAudioTime;
|
||||||
|
|
||||||
wxComboBox *mRateBox;
|
wxComboBox *mRateBox;
|
||||||
wxCheckBox *mSnapTo;
|
wxChoice *mSnapTo;
|
||||||
|
|
||||||
wxWindow *mRateText;
|
wxWindow *mRateText;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user