From e801b399433d6a36f6930a4e4453a15e609c6534 Mon Sep 17 00:00:00 2001 From: "james.k.crook" Date: Fri, 12 Feb 2010 21:28:34 +0000 Subject: [PATCH] Bugzilla#115. Split TimeConverter from the TimeTextCtrl GUI class so that we do not create a ctrl every time we want to do a time conversion. Also avoided creating a SnapManager when snap-to is disabled. --- src/Snap.cpp | 24 ++++++- src/TrackPanel.cpp | 14 +++- src/widgets/TimeTextCtrl.cpp | 131 +++++++++++++++++++++++------------ src/widgets/TimeTextCtrl.h | 34 +++++---- 4 files changed, 143 insertions(+), 60 deletions(-) diff --git a/src/Snap.cpp b/src/Snap.cpp index 99d78fdec..71b60ab28 100644 --- a/src/Snap.cpp +++ b/src/Snap.cpp @@ -31,6 +31,13 @@ SnapManager::SnapManager(TrackList *tracks, TrackClipArray *exclusions, // Grab time-snapping prefs (unless otherwise requested) mSnapToTime = false; TimeTextCtrl *ttc = NULL; + + // TODO: Switch over from using TimeTextCtrl to TimeConverter. + // This will prevent an annoying tiny toolbar appearing in top left + // every time we click the mouse left button. It's the time text + // ctrl. + + //TimeConverter *pTc=NULL; if (gPrefs->Read(wxT("/SnapTo"), 0L) != 0L && !noTimeSnap) { // Look up the format string @@ -249,11 +256,26 @@ bool SnapManager::Snap(Track *currentTrack, else { // Snap time to the grid AudacityProject *p = GetActiveProject(); +#if 0 + // Old code for snapping. + // This created a new ctrl for every tiny drag. TimeTextCtrl ttc(p, wxID_ANY, wxT(""), 0.0, p->GetRate()); ttc.SetFormatString(mFormat); - ttc.SetTimeValue(t); *out_t = ttc.GetTimeValue(); +#else + // Replacement code. It's still inefficient, since we + // repeatedly parse the format, but it now doesn't + // create a new ctrl too. + // TODO: Move Tc into being a member variable of + // SnapManager. Then we won't be repeatedly + // parsing the format string. + TimeConverter Tc; + Tc.mSampleRate = p->GetRate(); + Tc.ParseFormatString( mFormat ); + Tc.ValueToControls( t ); + *out_t = Tc.ControlsToValue(); +#endif *snappedTime = true; } } diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 8462333b7..726848c84 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -1789,12 +1789,20 @@ void TrackPanel::SelectionHandleClick(wxMouseEvent & event, bool startNewSelection = true; mMouseCapture=IsSelecting; + // Need a comment explaining why we need a new SnapManager + // with each mouse-down. if (mSnapManager) delete mSnapManager; + mSnapManager = NULL; + + // If we're not snapping, we don't need a snap manager. + if( GetActiveProject()->GetSnapTo() ) + { + mSnapManager = new SnapManager(mTracks, NULL, + mViewInfo->zoom, + 4); // pixel tolerance + } - mSnapManager = new SnapManager(mTracks, NULL, - mViewInfo->zoom, - 4); // pixel tolerance mSnapLeft = -1; mSnapRight = -1; diff --git a/src/widgets/TimeTextCtrl.cpp b/src/widgets/TimeTextCtrl.cpp index 1312eac2c..101e331fb 100644 --- a/src/widgets/TimeTextCtrl.cpp +++ b/src/widgets/TimeTextCtrl.cpp @@ -129,6 +129,14 @@ in the status bar of Audacity. \class TimeTextCtrlAx \brief TimeTextCtrlAx gives the TimeTextCtrl Accessibility. +*******************************************************************//** + +\class TimeConverter +\brief TimeConverter has all the time conversion and snapping +functionality that used to live in TimeTextCtrl. The idea is to have +a GUI-less class which can do the conversions, so that we can use it +in sanpping without having a window created each time. + *//****************************************************************//** \class BuiltinFormatString @@ -252,7 +260,6 @@ TimeTextCtrl::TimeTextCtrl(wxWindow *parent, bool autoPos): wxControl(parent, id, pos, size, wxSUNKEN_BORDER | wxWANTS_CHARS), mTimeValue(timeValue), - mSampleRate(sampleRate), mFormatString(formatString), mBackgroundBitmap(NULL), mDigitFont(NULL), @@ -261,6 +268,7 @@ TimeTextCtrl::TimeTextCtrl(wxWindow *parent, mLastField(1), mAutoPos(autoPos) { + mConverter.mSampleRate = sampleRate; /* i18n-hint: Name of time display format that shows time in seconds */ BuiltinFormatStrings[0].name = _("seconds"); /* i18n-hint: Format string for displaying time in seconds. Change the comma @@ -396,7 +404,7 @@ TimeTextCtrl::TimeTextCtrl(wxWindow *parent, mMenuEnabled = true; mButtonWidth = 9; - ParseFormatString(); + mConverter.ParseFormatString( mFormatString); Layout(); Fit(); ValueToControls(); @@ -433,7 +441,7 @@ void TimeTextCtrl::UpdateAutoFocus() mFocusedDigit = 0; while (mFocusedDigit < ((int)mDigits.GetCount() - 1)) { - wxChar dgt = mValueString[mDigits[mFocusedDigit].pos]; + wxChar dgt = mConverter.mValueString[mDigits[mFocusedDigit].pos]; if (dgt != '0') { break; } @@ -444,7 +452,7 @@ void TimeTextCtrl::UpdateAutoFocus() void TimeTextCtrl::SetFormatString(wxString formatString) { mFormatString = formatString; - ParseFormatString(); + mConverter.ParseFormatString( mFormatString); Layout(); Fit(); ValueToControls(); @@ -454,8 +462,8 @@ void TimeTextCtrl::SetFormatString(wxString formatString) void TimeTextCtrl::SetSampleRate(double sampleRate) { - mSampleRate = sampleRate; - ParseFormatString(); + mConverter.mSampleRate = sampleRate; + mConverter.ParseFormatString( mFormatString); Layout(); Fit(); ValueToControls(); @@ -561,13 +569,24 @@ wxString TimeTextCtrl::GetBuiltinFormat(const wxString &name) return TimeTextCtrl::GetBuiltinFormat(ndx); } -void TimeTextCtrl::ParseFormatString() +TimeConverter::TimeConverter() +{ + mPrefix = wxT(""); + mValueTemplate = wxT(""); + mValueMask = wxT(""); + mValueString = wxT(""); + + mScalingFactor = 1.0f; + mSampleRate = 1.0f; + mNtscDrop = false; +} + +void TimeConverter::ParseFormatString( const wxString & format) { mPrefix = wxT(""); mFields.Clear(); mScalingFactor = 1.0; - const wxString format = mFormatString; bool inFrac = false; int fracMult = 1; int numWholeFields = 0; @@ -709,7 +728,7 @@ void TimeTextCtrl::ParseFormatString() } } -void TimeTextCtrl::PrintDebugInfo() +void TimeConverter::PrintDebugInfo() { unsigned int i; @@ -738,7 +757,7 @@ wxString TimeTextCtrl::GetTimeString() { ValueToControls(); - return mValueString; + return mConverter.mValueString; } bool TimeTextCtrl::Layout() @@ -795,9 +814,12 @@ bool TimeTextCtrl::Layout() pos = 0; memDC.SetFont(*mLabelFont); - memDC.GetTextExtent(mPrefix, &strW, &strH); + memDC.GetTextExtent(mConverter.mPrefix, &strW, &strH); x += strW; - pos += mPrefix.Length(); + pos += mConverter.mPrefix.Length(); + + // Slightly messy trick to save us some prefixing. + TimeFieldArray & mFields = mConverter.mFields; for(i=0; i= WXK_NUMPAD0) && (keyCode <= WXK_NUMPAD9)) keyCode -= WXK_NUMPAD0 - '0'; if (keyCode >= '0' && keyCode <= '9') { - mValueString[mDigits[mFocusedDigit].pos] = wxChar(keyCode); + mConverter.mValueString[mDigits[mFocusedDigit].pos] = wxChar(keyCode); ControlsToValue(); ValueToControls(); mFocusedDigit = (mFocusedDigit+1)%(mDigits.GetCount()); @@ -1083,7 +1105,7 @@ void TimeTextCtrl::OnKeyDown(wxKeyEvent &event) mFocusedDigit--; mFocusedDigit += mDigits.GetCount(); mFocusedDigit %= mDigits.GetCount(); - mValueString[mDigits[mFocusedDigit].pos] = '0'; + mConverter.mValueString[mDigits[mFocusedDigit].pos] = '0'; ControlsToValue(); ValueToControls(); Updated(); @@ -1195,36 +1217,39 @@ void TimeTextCtrl::Updated() void TimeTextCtrl::Increase(int steps) { + // Slightly messy trick to save us some prefixing. + TimeFieldArray & mFields = mConverter.mFields; + while(steps > 0) { for(unsigned int i=0; i=mFields[i].pos) && (mDigits[mFocusedDigit].pos 0) { for(unsigned int i=0; i=mFields[i].pos) && (mDigits[mFocusedDigit].posmConverter.mFields; + wxString value = mCtrl->GetTimeString(); int field = mCtrl->GetFocusedField(); @@ -1528,15 +1571,15 @@ wxAccStatus TimeTextCtrlAx::GetName(int childId, wxString *name) // The user has moved from one field of the time to another so // report the value of the field and the field's label. else if (mLastField != field) { - wxString label = mCtrl->mFields[field - 1].label; - int cnt = mCtrl->mFields.GetCount(); + wxString label = mFields[field - 1].label; + int cnt = mFields.GetCount(); wxString decimal = wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT, wxLOCALE_CAT_NUMBER); // If the new field is the last field, then check it to see if // it represents fractions of a second. if (field > 1 && field == cnt) { - if (mCtrl->mFields[field - 2].label == decimal) { - int digits = mCtrl->mFields[field - 1].digits; + if (mFields[field - 2].label == decimal) { + int digits = mFields[field - 1].digits; if (digits == 2) { label = _("centiseconds"); } @@ -1548,10 +1591,10 @@ wxAccStatus TimeTextCtrlAx::GetName(int childId, wxString *name) // If the field following this one represents fractions of a // second then use that label instead of the decimal point. else if (label == decimal && field == cnt - 1) { - label = mCtrl->mFields[field].label; + label = mFields[field].label; } - *name = mCtrl->mFields[field - 1].str + + *name = mFields[field - 1].str + wxT(" ") + label + wxT(" ") + @@ -1568,7 +1611,7 @@ wxAccStatus TimeTextCtrlAx::GetName(int childId, wxString *name) // The user has updated the value of a field, so report the field's // value only. else { - *name = mCtrl->mFields[field - 1].str; + *name = mFields[field - 1].str; } return wxACC_OK; diff --git a/src/widgets/TimeTextCtrl.h b/src/widgets/TimeTextCtrl.h index 1751a0dce..340e3b3e0 100644 --- a/src/widgets/TimeTextCtrl.h +++ b/src/widgets/TimeTextCtrl.h @@ -43,6 +43,26 @@ WX_DECLARE_OBJARRAY(TimeField, TimeFieldArray); class DigitInfo; WX_DECLARE_OBJARRAY(DigitInfo, DigitInfoArray); +class TimeConverter +{ +public: + TimeConverter(); + TimeFieldArray mFields; + wxString mPrefix; + wxString mValueTemplate; + wxString mValueMask; + wxString mValueString; + + double mScalingFactor; + double mSampleRate; + bool mNtscDrop; + + void ParseFormatString( const wxString & format ); + void PrintDebugInfo(); + void ValueToControls( double RawTime ); + double ControlsToValue(); +}; + class TimeTextCtrl: public wxControl{ friend class TimeTextCtrlAx; @@ -97,8 +117,6 @@ private: void OnContext(wxContextMenuEvent &event); void OnMenu(wxCommandEvent &event); - void ParseFormatString(); - void ValueToControls(); void ControlsToValue(); @@ -118,16 +136,10 @@ private: * need adjusting if new time formats are added */ BuiltinFormatString BuiltinFormatStrings[16]; double mTimeValue; - double mSampleRate; + wxString mFormatString; - wxString mValueString; - wxString mValueTemplate; - wxString mValueMask; - bool mMenuEnabled; - wxString mPrefix; - wxBitmap *mBackgroundBitmap; wxFont *mDigitFont; @@ -151,10 +163,8 @@ private: bool mAutoPos; DigitInfoArray mDigits; + TimeConverter mConverter; - TimeFieldArray mFields; - double mScalingFactor; - bool mNtscDrop; // Keeps track of extra fractional scrollwheel steps double mScrollRemainder;