diff --git a/mac/Audacity.xcodeproj/project.pbxproj b/mac/Audacity.xcodeproj/project.pbxproj index 2f540ad60..a815cbb3b 100644 --- a/mac/Audacity.xcodeproj/project.pbxproj +++ b/mac/Audacity.xcodeproj/project.pbxproj @@ -1207,6 +1207,7 @@ 5E000A211EC7B5D500E8FD93 /* SampleHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E000A1F1EC7B5D500E8FD93 /* SampleHandle.cpp */; }; 5E7396441DAFD8C600BA0A4D /* TimeShiftHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E7396421DAFD8C600BA0A4D /* TimeShiftHandle.cpp */; }; 5E7396471DAFD8F200BA0A4D /* EnvelopeHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E7396451DAFD8F200BA0A4D /* EnvelopeHandle.cpp */; }; + 5E73964A1DAFD91D00BA0A4D /* CutlineHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E7396481DAFD91D00BA0A4D /* CutlineHandle.cpp */; }; 5E02BFF21D1164DF00EB7578 /* Distortion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E02BFF01D1164DF00EB7578 /* Distortion.cpp */; }; 5E07842E1DEE6B8600CA76EA /* FileException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E07842C1DEE6B8600CA76EA /* FileException.cpp */; }; 5E0784311DF1E4F400CA76EA /* UserException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E07842F1DF1E4F400CA76EA /* UserException.cpp */; }; @@ -3010,6 +3011,8 @@ 5E7396431DAFD8C600BA0A4D /* TimeShiftHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TimeShiftHandle.h; sourceTree = ""; }; 5E7396451DAFD8F200BA0A4D /* EnvelopeHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EnvelopeHandle.cpp; sourceTree = ""; }; 5E7396461DAFD8F200BA0A4D /* EnvelopeHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EnvelopeHandle.h; sourceTree = ""; }; + 5E7396481DAFD91D00BA0A4D /* CutlineHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CutlineHandle.cpp; sourceTree = ""; }; + 5E7396491DAFD91D00BA0A4D /* CutlineHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CutlineHandle.h; sourceTree = ""; }; 5E02BFF01D1164DF00EB7578 /* Distortion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Distortion.cpp; sourceTree = ""; }; 5E02BFF11D1164DF00EB7578 /* Distortion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Distortion.h; sourceTree = ""; }; 5E07842C1DEE6B8600CA76EA /* FileException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileException.cpp; sourceTree = ""; }; @@ -5797,12 +5800,14 @@ 5EA018221EC7B226001F2996 /* ui */ = { isa = PBXGroup; children = ( + 5E7396481DAFD91D00BA0A4D /* CutlineHandle.cpp */, 5E000A1F1EC7B5D500E8FD93 /* SampleHandle.cpp */, - 5E000A201EC7B5D500E8FD93 /* SampleHandle.h */, 5EA018231EC7B226001F2996 /* WaveTrackControls.cpp */, - 5EA018241EC7B226001F2996 /* WaveTrackControls.h */, 5EA018251EC7B226001F2996 /* WaveTrackUI.cpp */, 5EA018261EC7B226001F2996 /* WaveTrackVRulerControls.cpp */, + 5E7396491DAFD91D00BA0A4D /* CutlineHandle.h */, + 5E000A201EC7B5D500E8FD93 /* SampleHandle.h */, + 5EA018241EC7B226001F2996 /* WaveTrackControls.h */, 5EA018271EC7B226001F2996 /* WaveTrackVRulerControls.h */, ); path = ui; @@ -7653,6 +7658,7 @@ 1790B1A009883BFD008A330A /* WaveTrack.cpp in Sources */, 1790B1A109883BFD008A330A /* AButton.cpp in Sources */, 1790B1A209883BFD008A330A /* ASlider.cpp in Sources */, + 5E73964A1DAFD91D00BA0A4D /* CutlineHandle.cpp in Sources */, 1790B1A309883BFD008A330A /* Meter.cpp in Sources */, 1790B1A409883BFD008A330A /* MultiDialog.cpp in Sources */, 1790B1A509883BFD008A330A /* Ruler.cpp in Sources */, diff --git a/src/Makefile.am b/src/Makefile.am index 95c9588ef..93e2a3d24 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -559,6 +559,8 @@ audacity_SOURCES = \ tracks/playabletrack/notetrack/ui/NoteTrackUI.cpp \ tracks/playabletrack/notetrack/ui/NoteTrackVRulerControls.cpp \ tracks/playabletrack/notetrack/ui/NoteTrackVRulerControls.h \ + tracks/playabletrack/wavetrack/ui/CutlineHandle.cpp \ + tracks/playabletrack/wavetrack/ui/CutlineHandle.h \ tracks/playabletrack/wavetrack/ui/SampleHandle.cpp \ tracks/playabletrack/wavetrack/ui/SampleHandle.h \ tracks/playabletrack/wavetrack/ui/WaveTrackControls.cpp \ diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index d5a0585af..f1e6610b6 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -1151,7 +1151,6 @@ void TrackPanel::HandleInterruptedDrag() IsRearranging, IsGainSliding, IsPanSliding, - WasOverCutLine, IsStretching, IsVelocitySliding */ @@ -1423,17 +1422,6 @@ bool TrackPanel::SetCursorByActivity( ) return false; } -bool TrackPanel::SetCursorForCutline(WaveTrack * track, const wxRect &rect, const wxMouseEvent &event) -{ - if (IsOverCutline(track, rect, event)) { - bool unsafe = IsUnsafe(); - SetCursor(unsafe ? *mDisabledCursor : *mArrowCursor); - return true; - // No tip string? - } - return false; -} - #if defined(__WXMAC__) /* i18n-hint: Command names a modifier key on Macintosh keyboards */ #define CTRL_CLICK _("Command-Click") @@ -1826,13 +1814,6 @@ void TrackPanel::HandleCursor(wxMouseEvent & event) // we go on to do all the standard track hit tests. } - if (pCursor == NULL && tip == wxString() && - !(foundCell.type == CellType::Label || - foundCell.type == CellType::VRuler) && - track->GetKind() == Track::Wave && - SetCursorForCutline(static_cast(track), rect, event)) - return; - if( pCursor == NULL && tip == wxString() ) { ToolsToolBar * ttb = mListener->TP_GetToolsToolBar(); @@ -5214,143 +5195,6 @@ catch( ... ) throw; } -namespace { - int FindMergeLine(WaveTrack *track, double time) - { - const double tolerance = 0.5 / track->GetRate(); - int ii = 0; - for (const auto loc: track->GetCachedLocations()) { - if (loc.typ == WaveTrackLocation::locationMergePoint && - fabs(time - loc.pos) < tolerance) - return ii; - ++ii; - } - return -1; - } -} - -bool TrackPanel::HandleTrackLocationMouseEvent(WaveTrack * track, const wxRect &rect, wxMouseEvent &event) -{ - // FIXME: Disable this and return true when CutLines aren't showing? - // (Don't use gPrefs-> for the fix as registry access is slow). - - if (mMouseCapture == WasOverCutLine) - { - if (event.ButtonUp()) { - mMouseCapture = IsUncaptured; - return false; - } - else - // Needed to avoid select events after button down - return true; - } - else if (!IsUnsafe() && IsOverCutline(track, rect, event)) - { - if (!mCapturedTrackLocationRect.Contains(event.m_x, event.m_y)) - { - SetCapturedTrack( NULL ); - return false; - } - - bool handled = false; - - if (event.LeftDown()) - { - if (mCapturedTrackLocation.typ == WaveTrackLocation::locationCutLine) - { - // When user presses left button on cut line, expand the line again - double cutlineStart = 0, cutlineEnd = 0; - - track->ExpandCutLine(mCapturedTrackLocation.pos, &cutlineStart, &cutlineEnd); - { - // Assume linked track is wave or null - const auto linked = - static_cast(track->GetLink()); - if (linked) - // Expand the cutline in the opposite channel if it is present. - linked->ExpandCutLine(mCapturedTrackLocation.pos); - - mViewInfo->selectedRegion.setTimes(cutlineStart, cutlineEnd); - DisplaySelection(); - MakeParentPushState(_("Expanded Cut Line"), _("Expand")); - handled = true; - } - } - else if (mCapturedTrackLocation.typ == WaveTrackLocation::locationMergePoint) { - const double pos = mCapturedTrackLocation.pos; - track->MergeClips(mCapturedTrackLocation.clipidx1, mCapturedTrackLocation.clipidx2); - - // Assume linked track is wave or null - const auto linked = - static_cast(track->GetLink()); - if (linked) { - // Don't assume correspondence of merge points across channels! - int idx = FindMergeLine(linked, pos); - if (idx >= 0) { - WaveTrack::Location location = linked->GetCachedLocations()[idx]; - linked->MergeClips(location.clipidx1, location.clipidx2); - } - } - - MakeParentPushState(_("Merged Clips"),_("Merge"), UndoPush::CONSOLIDATE); - handled = true; - } - } - - if (!handled && event.RightDown()) - { - track->RemoveCutLine(mCapturedTrackLocation.pos); - // Assume linked track is wave or null - const auto linked = - static_cast(track->GetLink()); - if (linked) - linked->RemoveCutLine(mCapturedTrackLocation.pos); - MakeParentPushState(_("Removed Cut Line"), _("Remove") ); - handled = true; - } - - if (handled) - { - SetCapturedTrack( NULL ); - // Effect happened at button-down, but treat like a dragging mode until - // button-up. - mMouseCapture = WasOverCutLine; - RefreshTrack(track); - return true; - } - - - return true; - } - - return false; -} - -bool TrackPanel::IsOverCutline(WaveTrack * track, const wxRect &rect, const wxMouseEvent &event) -{ - for (auto loc: track->GetCachedLocations()) - { - const double x = mViewInfo->TimeToPosition(loc.pos); - if (x >= 0 && x < rect.width) - { - wxRect locRect; - locRect.x = (int)(rect.x + x) - 5; - locRect.width = 11; - locRect.y = rect.y; - locRect.height = rect.height; - if (locRect.Contains(event.m_x, event.m_y)) - { - mCapturedTrackLocation = loc; - mCapturedTrackLocationRect = locRect; - return true; - } - } - } - - return false; -} - - /// Event has happened on a track and it has been determined to be a label track. bool TrackPanel::HandleLabelTrackClick(LabelTrack * lTrack, const wxRect &rect, wxMouseEvent & event) { @@ -5594,12 +5438,6 @@ void TrackPanel::HandleTrackSpecificMouseEvent(wxMouseEvent & event) bool handled = false; - if (!mUIHandle && - pTrack && foundCell.type == CellType::Track && - (pTrack->GetKind() == Track::Wave) && - (mMouseCapture == IsUncaptured || mMouseCapture == WasOverCutLine)) - handled = HandleTrackLocationMouseEvent((WaveTrack *)pTrack, rect, event); - ToolsToolBar * pTtb = mListener->TP_GetToolsToolBar(); if( !handled && pTtb != NULL && ( foundCell.type == CellType::Track || diff --git a/src/TrackPanel.h b/src/TrackPanel.h index 459e06192..2b3a33d91 100644 --- a/src/TrackPanel.h +++ b/src/TrackPanel.h @@ -19,7 +19,6 @@ #include "Experimental.h" #include "SelectedRegion.h" -#include "WaveTrackLocation.h" #include "widgets/OverlayPanel.h" @@ -365,8 +364,6 @@ class AUDACITY_DLL_API TrackPanel final : public OverlayPanel { virtual bool HandleLabelTrackClick(LabelTrack * lTrack, const wxRect &rect, wxMouseEvent & event); virtual void HandleGlyphDragRelease(LabelTrack * lTrack, wxMouseEvent & event); virtual void HandleTextDragRelease(LabelTrack * lTrack, wxMouseEvent & event); - virtual bool HandleTrackLocationMouseEvent(WaveTrack * track, const wxRect &rect, wxMouseEvent &event); - virtual bool IsOverCutline(WaveTrack * track, const wxRect &rect, const wxMouseEvent &event); virtual void HandleTrackSpecificMouseEvent(wxMouseEvent & event); virtual void ScrollDuringDrag(); @@ -453,7 +450,6 @@ protected: // AS: Cursor handling virtual bool SetCursorByActivity( ); - virtual bool SetCursorForCutline(WaveTrack * track, const wxRect &rect, const wxMouseEvent &event); virtual void SetCursorAndTipWhenInLabel( Track * t, const wxMouseEvent &event, wxString &tip ); virtual void SetCursorAndTipWhenInVResizeArea( bool blinked, wxString &tip ); virtual void SetCursorAndTipWhenInLabelTrack( LabelTrack * pLT, const wxMouseEvent & event, wxString &tip ); @@ -719,8 +715,6 @@ protected: #endif Track *mCapturedTrack; - WaveTrackLocation mCapturedTrackLocation; - wxRect mCapturedTrackLocationRect; wxRect mCapturedRect; bool mRedrawAfterStop; @@ -816,7 +810,6 @@ public: IsGainSliding, IsPanSliding, IsMinimizing, - WasOverCutLine, IsPopping, #ifdef EXPERIMENTAL_MIDI_OUT IsVelocitySliding, diff --git a/src/tracks/playabletrack/wavetrack/ui/CutlineHandle.cpp b/src/tracks/playabletrack/wavetrack/ui/CutlineHandle.cpp new file mode 100644 index 000000000..cbe9e2e12 --- /dev/null +++ b/src/tracks/playabletrack/wavetrack/ui/CutlineHandle.cpp @@ -0,0 +1,262 @@ +/********************************************************************** + +Audacity: A Digital Audio Editor + +CutlineHandle.cpp + +Paul Licameli split from TrackPanel.cpp + +**********************************************************************/ + +#include "../../../../Audacity.h" +#include "CutlineHandle.h" + +#include "../../../../MemoryX.h" + +#include "../../../../HitTestResult.h" +#include "../../../../Project.h" +#include "../../../../RefreshCode.h" +#include "../../../../TrackPanelMouseEvent.h" +#include "../../../../UndoManager.h" +#include "../../../../WaveTrack.h" +#include "../../../../WaveTrackLocation.h" +#include "../../../../../images/Cursors.h" + +CutlineHandle::CutlineHandle() +{ +} + +CutlineHandle &CutlineHandle::Instance() +{ + static CutlineHandle instance; + return instance; +} + +HitTestPreview CutlineHandle::HitPreview(bool cutline, bool unsafe) +{ + static auto disabledCursor = + ::MakeCursor(wxCURSOR_NO_ENTRY, DisabledCursorXpm, 16, 16); + static wxCursor arrowCursor{ wxCURSOR_ARROW }; + return { + (cutline + ? _("Left-Click to expand, Right-Click to remove") + : _("Left-Click to join clips")), + (unsafe + ? &*disabledCursor + : &arrowCursor) + }; +} + +HitTestResult CutlineHandle::HitAnywhere(const AudacityProject *pProject, bool cutline) +{ + const bool unsafe = pProject->IsAudioActive(); + return { + HitPreview(cutline, unsafe), + (unsafe + ? NULL + : &Instance()) + }; +} + +namespace +{ + int FindMergeLine(WaveTrack *track, double time) + { + const double tolerance = 0.5 / track->GetRate(); + int ii = 0; + for (const auto loc: track->GetCachedLocations()) { + if (loc.typ == WaveTrackLocation::locationMergePoint && + fabs(time - loc.pos) < tolerance) + return ii; + ++ii; + } + return -1; + } + + bool IsOverCutline + (const ViewInfo &viewInfo, WaveTrack * track, + const wxRect &rect, const wxMouseEvent &event, + WaveTrackLocation *pCapturedTrackLocation) + { + for (auto loc: track->GetCachedLocations()) + { + const double x = viewInfo.TimeToPosition(loc.pos); + if (x >= 0 && x < rect.width) + { + wxRect locRect; + locRect.x = (int)(rect.x + x) - 5; + locRect.width = 11; + locRect.y = rect.y; + locRect.height = rect.height; + if (locRect.Contains(event.m_x, event.m_y)) + { + if (pCapturedTrackLocation) + *pCapturedTrackLocation = loc; + return true; + } + } + } + + return false; + } +} + +HitTestResult CutlineHandle::HitTest +(const wxMouseEvent &event, const wxRect &rect, const AudacityProject *pProject, Track *pTrack) +{ + const ViewInfo &viewInfo = pProject->GetViewInfo(); + /// method that tells us if the mouse event landed on an + /// editable Cutline + if (pTrack->GetKind() != Track::Wave) + return {}; + + WaveTrack *wavetrack = static_cast(pTrack); + WaveTrackLocation location; + if (!IsOverCutline(viewInfo, wavetrack, rect, event, &location)) + return {}; + + return HitAnywhere(pProject, location.typ == WaveTrackLocation::locationCutLine); +} + +CutlineHandle::~CutlineHandle() +{ +} + +UIHandle::Result CutlineHandle::Click +(const TrackPanelMouseEvent &evt, AudacityProject *pProject) +{ + const wxMouseEvent &event = evt.event; + ViewInfo &viewInfo = pProject->GetViewInfo(); + Track *const pTrack = static_cast(evt.pCell); + + // Can affect the track by merging clips, expanding a cutline, or + // deleting a cutline. + // All the change is done at button-down. Button-up just commits the undo item. + using namespace RefreshCode; + + /// Someone has just clicked the mouse. What do we do? + const bool unsafe = pProject->IsAudioActive(); + if (unsafe) + return Cancelled; + + WaveTrackLocation capturedTrackLocation; + + WaveTrack *wavetrack = static_cast(pTrack); + if (!IsOverCutline(viewInfo, wavetrack, evt.rect, event, &capturedTrackLocation)) + return Cancelled; + mbCutline = (capturedTrackLocation.typ == WaveTrackLocation::locationCutLine); + + // FIXME: Disable this and return true when CutLines aren't showing? + // (Don't use gPrefs-> for the fix as registry access is slow). + + // Cutline data changed on either branch, so refresh the track display. + UIHandle::Result result = RefreshCell; + // Assume linked track is wave or null + const auto linked = static_cast(wavetrack->GetLink()); + + if (event.LeftDown()) + { + if (capturedTrackLocation.typ == WaveTrackLocation::locationCutLine) + { + mOperation = Expand; + mStartTime = viewInfo.selectedRegion.t0(); + mEndTime = viewInfo.selectedRegion.t1(); + + // When user presses left button on cut line, expand the line again + double cutlineStart = 0, cutlineEnd = 0; + + wavetrack->ExpandCutLine(capturedTrackLocation.pos, &cutlineStart, &cutlineEnd); + + if (linked) + // Expand the cutline in the opposite channel if it is present. + linked->ExpandCutLine(capturedTrackLocation.pos); + + viewInfo.selectedRegion.setTimes(cutlineStart, cutlineEnd); + result |= UpdateSelection; + } + else if (capturedTrackLocation.typ == WaveTrackLocation::locationMergePoint) { + const double pos = capturedTrackLocation.pos; + wavetrack->MergeClips(capturedTrackLocation.clipidx1, capturedTrackLocation.clipidx2); + + if (linked) { + // Don't assume correspondence of merge points across channels! + int idx = FindMergeLine(linked, pos); + if (idx >= 0) { + WaveTrack::Location location = linked->GetCachedLocations()[idx]; + linked->MergeClips(location.clipidx1, location.clipidx2); + } + } + + mOperation = Merge; + } + } + else if (event.RightDown()) + { + bool removed = wavetrack->RemoveCutLine(capturedTrackLocation.pos); + + if (linked) + removed = linked->RemoveCutLine(capturedTrackLocation.pos) || removed; + + if (!removed) + // Nothing happened, make no Undo item + return Cancelled; + + mOperation = Remove; + } + else + result = RefreshNone; + + return result; +} + +UIHandle::Result CutlineHandle::Drag +(const TrackPanelMouseEvent &, AudacityProject *) +{ + return RefreshCode::RefreshNone; +} + +HitTestPreview CutlineHandle::Preview +(const TrackPanelMouseEvent &, const AudacityProject *) +{ + return HitPreview(mbCutline, false); +} + +UIHandle::Result CutlineHandle::Release +(const TrackPanelMouseEvent &, AudacityProject *pProject, wxWindow *) +{ + UIHandle::Result result = RefreshCode::RefreshNone; + + // Only now commit the result to the undo stack + AudacityProject *const project = pProject; + switch (mOperation) { + default: + wxASSERT(false); + case Merge: + project->PushState(_("Merged Clips"), _("Merge"), UndoPush::CONSOLIDATE); + break; + case Expand: + project->PushState(_("Expanded Cut Line"), _("Expand")); + result |= RefreshCode::UpdateSelection; + break; + case Remove: + project->PushState(_("Removed Cut Line"), _("Remove")); + break; + } + + // Nothing to do for the display + return result; +} + +UIHandle::Result CutlineHandle::Cancel(AudacityProject *pProject) +{ + using namespace RefreshCode; + UIHandle::Result result = RefreshCell; + pProject->RollbackState(); + if (mOperation == Expand) { + AudacityProject *const project = pProject; + project->SetSel0(mStartTime); + project->SetSel1(mEndTime); + result |= UpdateSelection; + } + return result; +} diff --git a/src/tracks/playabletrack/wavetrack/ui/CutlineHandle.h b/src/tracks/playabletrack/wavetrack/ui/CutlineHandle.h new file mode 100644 index 000000000..0813e3d75 --- /dev/null +++ b/src/tracks/playabletrack/wavetrack/ui/CutlineHandle.h @@ -0,0 +1,61 @@ +/********************************************************************** + +Audacity: A Digital Audio Editor + +CutlineHandle.h + +Paul Licameli + +**********************************************************************/ + +#ifndef __AUDACITY_CUTLINE_HANDLE__ +#define __AUDACITY_CUTLINE_HANDLE__ + +#include "../../../../UIHandle.h" + +class wxMouseEvent; +struct HitTestResult; +class Track; + +class CutlineHandle final : public UIHandle +{ + CutlineHandle(); + CutlineHandle(const CutlineHandle&) = delete; + CutlineHandle &operator=(const CutlineHandle&) = delete; + static CutlineHandle& Instance(); + static HitTestPreview HitPreview(bool cutline, bool unsafe); + +public: + static HitTestResult HitAnywhere(const AudacityProject *pProject, bool cutline); + static HitTestResult HitTest + (const wxMouseEvent &event, const wxRect &rect, + const AudacityProject *pProject, Track *pTrack); + + virtual ~CutlineHandle(); + + Result Click + (const TrackPanelMouseEvent &event, AudacityProject *pProject) override; + + Result Drag + (const TrackPanelMouseEvent &event, AudacityProject *pProject) override; + + HitTestPreview Preview + (const TrackPanelMouseEvent &event, const AudacityProject *pProject) + override; + + Result Release + (const TrackPanelMouseEvent &event, AudacityProject *pProject, + wxWindow *pParent) override; + + Result Cancel(AudacityProject *pProject) override; + + bool StopsOnKeystroke() override { return true; } + +private: + enum Operation { Merge, Expand, Remove }; + Operation mOperation{ Merge }; + double mStartTime{}, mEndTime{}; + bool mbCutline{}; +}; + +#endif diff --git a/src/tracks/playabletrack/wavetrack/ui/WaveTrackUI.cpp b/src/tracks/playabletrack/wavetrack/ui/WaveTrackUI.cpp index c7fbf0fa2..7f7a09e0a 100644 --- a/src/tracks/playabletrack/wavetrack/ui/WaveTrackUI.cpp +++ b/src/tracks/playabletrack/wavetrack/ui/WaveTrackUI.cpp @@ -17,6 +17,7 @@ Paul Licameli split from TrackPanel.cpp #include "../../../../TrackPanelMouseEvent.h" #include "../../../../toolbars/ToolsToolBar.h" +#include "CutlineHandle.h" #include "../../../ui/EnvelopeHandle.h" #include "SampleHandle.h" #include "../../../ui/TimeShiftHandle.h" @@ -25,7 +26,12 @@ HitTestResult WaveTrack::HitTest (const TrackPanelMouseEvent &event, const AudacityProject *pProject) { - HitTestResult result = Track::HitTest(event, pProject); + // This hit was always tested first no matter which tool: + HitTestResult result = CutlineHandle::HitTest(event.event, event.rect, pProject, this); + if (result.preview.cursor) + return result; + + result = Track::HitTest(event, pProject); if (result.preview.cursor) return result; diff --git a/win/Projects/Audacity/Audacity.vcxproj b/win/Projects/Audacity/Audacity.vcxproj index 1034eff40..f5256ec96 100755 --- a/win/Projects/Audacity/Audacity.vcxproj +++ b/win/Projects/Audacity/Audacity.vcxproj @@ -230,6 +230,7 @@ + @@ -493,6 +494,7 @@ + @@ -1179,4 +1181,4 @@ - + \ No newline at end of file diff --git a/win/Projects/Audacity/Audacity.vcxproj.filters b/win/Projects/Audacity/Audacity.vcxproj.filters index f4899145f..d65938523 100755 --- a/win/Projects/Audacity/Audacity.vcxproj.filters +++ b/win/Projects/Audacity/Audacity.vcxproj.filters @@ -1,4 +1,4 @@ - + @@ -1001,6 +1001,9 @@ src\tracks\playabletrack\wavetrack\ui + + src\tracks\playabletrack\wavetrack\ui + @@ -1996,6 +1999,9 @@ src\tracks\ui + + src\tracks\playabletrack\wavetrack\ui + @@ -2219,4 +2225,4 @@ plug-ins - + \ No newline at end of file