diff --git a/mac/Audacity.xcodeproj/project.pbxproj b/mac/Audacity.xcodeproj/project.pbxproj index a815cbb3b..e2c1a7c32 100644 --- a/mac/Audacity.xcodeproj/project.pbxproj +++ b/mac/Audacity.xcodeproj/project.pbxproj @@ -1208,6 +1208,7 @@ 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 */; }; + 5E73964D1DAFD95B00BA0A4D /* ButtonHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E73964B1DAFD95B00BA0A4D /* ButtonHandle.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 */; }; @@ -3013,6 +3014,8 @@ 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 = ""; }; + 5E73964B1DAFD95B00BA0A4D /* ButtonHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ButtonHandle.cpp; sourceTree = ""; }; + 5E73964C1DAFD95B00BA0A4D /* ButtonHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ButtonHandle.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 = ""; }; @@ -5737,6 +5740,7 @@ 5E74D2DC1CC4429700D88B0B /* ui */ = { isa = PBXGroup; children = ( + 5E73964B1DAFD95B00BA0A4D /* ButtonHandle.cpp */, 5E1512661DB0010C00702E29 /* CommonTrackPanelCell.cpp */, 5E74D2DD1CC4429700D88B0B /* EditCursorOverlay.cpp */, 5E7396451DAFD8F200BA0A4D /* EnvelopeHandle.cpp */, @@ -5747,6 +5751,7 @@ 5E15126A1DB0010C00702E29 /* TrackUI.cpp */, 5E15126B1DB0010C00702E29 /* TrackVRulerControls.cpp */, 5E73963C1DAFD86000BA0A4D /* ZoomHandle.cpp */, + 5E73964C1DAFD95B00BA0A4D /* ButtonHandle.h */, 5E1512671DB0010C00702E29 /* CommonTrackPanelCell.h */, 5E74D2DE1CC4429700D88B0B /* EditCursorOverlay.h */, 5E7396461DAFD8F200BA0A4D /* EnvelopeHandle.h */, @@ -7661,6 +7666,7 @@ 5E73964A1DAFD91D00BA0A4D /* CutlineHandle.cpp in Sources */, 1790B1A309883BFD008A330A /* Meter.cpp in Sources */, 1790B1A409883BFD008A330A /* MultiDialog.cpp in Sources */, + 5E73964D1DAFD95B00BA0A4D /* ButtonHandle.cpp in Sources */, 1790B1A509883BFD008A330A /* Ruler.cpp in Sources */, 1790B1A709883BFD008A330A /* Warning.cpp in Sources */, 1790B1A909883BFD008A330A /* XMLFileReader.cpp in Sources */, diff --git a/src/Makefile.am b/src/Makefile.am index 93e2a3d24..53622f954 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -573,6 +573,8 @@ audacity_SOURCES = \ tracks/timetrack/ui/TimeTrackUI.cpp \ tracks/timetrack/ui/TimeTrackVRulerControls.cpp \ tracks/timetrack/ui/TimeTrackVRulerControls.h \ + tracks/ui/ButtonHandle.h \ + tracks/ui/ButtonHandle.cpp \ tracks/ui/CommonTrackPanelCell.cpp \ tracks/ui/CommonTrackPanelCell.h \ tracks/ui/EditCursorOverlay.cpp \ diff --git a/src/tracks/ui/ButtonHandle.cpp b/src/tracks/ui/ButtonHandle.cpp new file mode 100644 index 000000000..6bec79fa5 --- /dev/null +++ b/src/tracks/ui/ButtonHandle.cpp @@ -0,0 +1,111 @@ +/********************************************************************** + +Audacity: A Digital Audio Editor + +ButtonHandle.cpp + +Paul Licameli + +**********************************************************************/ + +#include "ButtonHandle.h" +#include "../../HitTestResult.h" +#include "../../Project.h" +#include "../../RefreshCode.h" +#include "../../Track.h" +#include "../../TrackPanelMouseEvent.h" +#include "../ui/TrackControls.h" + +ButtonHandle::ButtonHandle(int dragCode) + : mDragCode(dragCode) +{ +} + +ButtonHandle::~ButtonHandle() +{ +} + +HitTestPreview ButtonHandle::HitPreview() +{ + // No special message or cursor + return {}; +} + +UIHandle::Result ButtonHandle::Click +(const TrackPanelMouseEvent &evt, AudacityProject *) +{ + const wxMouseEvent &event = evt.event; + using namespace RefreshCode; + if (!event.Button(wxMOUSE_BTN_LEFT)) + return Cancelled; + + // Come here for left click or double click + if (mRect.Contains(event.m_x, event.m_y)) { + mpTrack = static_cast(evt.pCell)->GetTrack(); + TrackControls::gCaptureState = mDragCode; + // Toggle visible button state + return RefreshCell; + } + else + return Cancelled; +} + +UIHandle::Result ButtonHandle::Drag +(const TrackPanelMouseEvent &evt, AudacityProject *) +{ + const wxMouseEvent &event = evt.event; + using namespace RefreshCode; + const int newState = + mRect.Contains(event.m_x, event.m_y) ? mDragCode : 0; + if (TrackControls::gCaptureState == newState) + return RefreshNone; + else { + TrackControls::gCaptureState = newState; + return RefreshCell; + } +} + +HitTestPreview ButtonHandle::Preview +(const TrackPanelMouseEvent &, const AudacityProject *) +{ + // No special message or cursor + return {}; +} + +UIHandle::Result ButtonHandle::Release +(const TrackPanelMouseEvent &evt, AudacityProject *pProject, + wxWindow *pParent) +{ + using namespace RefreshCode; + Result result = RefreshNone; + const wxMouseEvent &event = evt.event; + if (TrackControls::gCaptureState) { + TrackControls::gCaptureState = 0; + result = RefreshCell; + } + if (mpTrack && mRect.Contains(event.m_x, event.m_y)) + result |= CommitChanges(event, pProject, pParent); + return result; +} + +UIHandle::Result ButtonHandle::Cancel(AudacityProject *pProject) +{ + using namespace RefreshCode; + if (TrackControls::gCaptureState) { + TrackControls::gCaptureState = 0; + return RefreshCell; + } + else + return RefreshNone; +} + +void ButtonHandle::OnProjectChange(AudacityProject *pProject) +{ + if (! pProject->GetTracks()->Contains(mpTrack)) { + mpTrack = nullptr; + mRect = {}; + } + + UIHandle::OnProjectChange(pProject); +} + diff --git a/src/tracks/ui/ButtonHandle.h b/src/tracks/ui/ButtonHandle.h new file mode 100644 index 000000000..c128ad6b1 --- /dev/null +++ b/src/tracks/ui/ButtonHandle.h @@ -0,0 +1,63 @@ +/********************************************************************** + +Audacity: A Digital Audio Editor + +ButtonHandle.h + +Paul Licameli + +**********************************************************************/ + +#ifndef __AUDACITY_BUTTON_HANDLE__ +#define __AUDACITY_BUTTON_HANDLE__ + +#include "../../UIHandle.h" + +class wxMouseEvent; +#include + +class Track; + +class ButtonHandle /* not final */ : public UIHandle +{ + ButtonHandle(const ButtonHandle&) = delete; + ButtonHandle &operator=(const ButtonHandle&) = delete; + +protected: + explicit ButtonHandle(int dragCode); + virtual ~ButtonHandle(); + + // This new abstract virtual simplifies the duties of further subclasses. + // This class will decide whether to refresh the clicked cell for button state + // change. + // Subclass can decide to refresh other things and the results will be ORed. + virtual Result CommitChanges + (const wxMouseEvent &event, AudacityProject *pProject, wxWindow *pParent) = 0; + + // For derived class to define hit tests + static HitTestPreview HitPreview(); + + 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; + + void OnProjectChange(AudacityProject *pProject) override; + + wxRect mRect {}; + Track *mpTrack {}; + const int mDragCode; +}; + +#endif diff --git a/win/Projects/Audacity/Audacity.vcxproj b/win/Projects/Audacity/Audacity.vcxproj index f5256ec96..ed68c9e9a 100755 --- a/win/Projects/Audacity/Audacity.vcxproj +++ b/win/Projects/Audacity/Audacity.vcxproj @@ -238,6 +238,7 @@ + @@ -502,6 +503,7 @@ + @@ -1181,4 +1183,4 @@ - \ No newline at end of file + diff --git a/win/Projects/Audacity/Audacity.vcxproj.filters b/win/Projects/Audacity/Audacity.vcxproj.filters index d65938523..91ad1e04e 100755 --- a/win/Projects/Audacity/Audacity.vcxproj.filters +++ b/win/Projects/Audacity/Audacity.vcxproj.filters @@ -1004,6 +1004,9 @@ src\tracks\playabletrack\wavetrack\ui + + src\tracks\ui + @@ -2002,6 +2005,9 @@ src\tracks\playabletrack\wavetrack\ui + + src\tracks\ui + @@ -2225,4 +2231,4 @@ plug-ins - \ No newline at end of file +