mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-17 00:20:06 +02:00
TrackPanel no longer implements the draw tool...
... also implement ESC key for it
This commit is contained in:
parent
85c03bb3b3
commit
f1f254f974
@ -1204,6 +1204,7 @@
|
|||||||
28FC1AFB0A47762C00A188AE /* WrappedType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28FC1AF90A47762C00A188AE /* WrappedType.cpp */; };
|
28FC1AFB0A47762C00A188AE /* WrappedType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28FC1AF90A47762C00A188AE /* WrappedType.cpp */; };
|
||||||
28FE4A080ABF4E960056F5C4 /* mmx_optimized.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28FE4A060ABF4E960056F5C4 /* mmx_optimized.cpp */; };
|
28FE4A080ABF4E960056F5C4 /* mmx_optimized.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28FE4A060ABF4E960056F5C4 /* mmx_optimized.cpp */; };
|
||||||
28FE4A090ABF4E960056F5C4 /* sse_optimized.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28FE4A070ABF4E960056F5C4 /* sse_optimized.cpp */; };
|
28FE4A090ABF4E960056F5C4 /* sse_optimized.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28FE4A070ABF4E960056F5C4 /* sse_optimized.cpp */; };
|
||||||
|
5E000A211EC7B5D500E8FD93 /* SampleHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E000A1F1EC7B5D500E8FD93 /* SampleHandle.cpp */; };
|
||||||
5E02BFF21D1164DF00EB7578 /* Distortion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E02BFF01D1164DF00EB7578 /* Distortion.cpp */; };
|
5E02BFF21D1164DF00EB7578 /* Distortion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E02BFF01D1164DF00EB7578 /* Distortion.cpp */; };
|
||||||
5E07842E1DEE6B8600CA76EA /* FileException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E07842C1DEE6B8600CA76EA /* FileException.cpp */; };
|
5E07842E1DEE6B8600CA76EA /* FileException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E07842C1DEE6B8600CA76EA /* FileException.cpp */; };
|
||||||
5E0784311DF1E4F400CA76EA /* UserException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E07842F1DF1E4F400CA76EA /* UserException.cpp */; };
|
5E0784311DF1E4F400CA76EA /* UserException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E07842F1DF1E4F400CA76EA /* UserException.cpp */; };
|
||||||
@ -1220,6 +1221,8 @@
|
|||||||
5E15126E1DB0010C00702E29 /* TrackControls.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E1512681DB0010C00702E29 /* TrackControls.cpp */; };
|
5E15126E1DB0010C00702E29 /* TrackControls.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E1512681DB0010C00702E29 /* TrackControls.cpp */; };
|
||||||
5E15126F1DB0010C00702E29 /* TrackUI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E15126A1DB0010C00702E29 /* TrackUI.cpp */; };
|
5E15126F1DB0010C00702E29 /* TrackUI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E15126A1DB0010C00702E29 /* TrackUI.cpp */; };
|
||||||
5E1512701DB0010C00702E29 /* TrackVRulerControls.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E15126B1DB0010C00702E29 /* TrackVRulerControls.cpp */; };
|
5E1512701DB0010C00702E29 /* TrackVRulerControls.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E15126B1DB0010C00702E29 /* TrackVRulerControls.cpp */; };
|
||||||
|
5E73963B1DAFD82D00BA0A4D /* PopupMenuTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E7396391DAFD82D00BA0A4D /* PopupMenuTable.cpp */; };
|
||||||
|
5E73963E1DAFD86000BA0A4D /* ZoomHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E73963C1DAFD86000BA0A4D /* ZoomHandle.cpp */; };
|
||||||
5E74D2E31CC4429700D88B0B /* EditCursorOverlay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E74D2DD1CC4429700D88B0B /* EditCursorOverlay.cpp */; };
|
5E74D2E31CC4429700D88B0B /* EditCursorOverlay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E74D2DD1CC4429700D88B0B /* EditCursorOverlay.cpp */; };
|
||||||
5E74D2E41CC4429700D88B0B /* PlayIndicatorOverlay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E74D2DF1CC4429700D88B0B /* PlayIndicatorOverlay.cpp */; };
|
5E74D2E41CC4429700D88B0B /* PlayIndicatorOverlay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E74D2DF1CC4429700D88B0B /* PlayIndicatorOverlay.cpp */; };
|
||||||
5E74D2E51CC4429700D88B0B /* Scrubbing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E74D2E11CC4429700D88B0B /* Scrubbing.cpp */; };
|
5E74D2E51CC4429700D88B0B /* Scrubbing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E74D2E11CC4429700D88B0B /* Scrubbing.cpp */; };
|
||||||
@ -1238,8 +1241,6 @@
|
|||||||
5ED1D0B11CDE560C00471E3C /* BackedPanel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5ED1D0AF1CDE560C00471E3C /* BackedPanel.cpp */; };
|
5ED1D0B11CDE560C00471E3C /* BackedPanel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5ED1D0AF1CDE560C00471E3C /* BackedPanel.cpp */; };
|
||||||
5EF17C231D1F0A690090A642 /* ScrubbingToolBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5EF17C211D1F0A690090A642 /* ScrubbingToolBar.cpp */; };
|
5EF17C231D1F0A690090A642 /* ScrubbingToolBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5EF17C211D1F0A690090A642 /* ScrubbingToolBar.cpp */; };
|
||||||
5EF958851DEB121800191280 /* InconsistencyException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5EF958831DEB121800191280 /* InconsistencyException.cpp */; };
|
5EF958851DEB121800191280 /* InconsistencyException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5EF958831DEB121800191280 /* InconsistencyException.cpp */; };
|
||||||
5E73963B1DAFD82D00BA0A4D /* PopupMenuTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E7396391DAFD82D00BA0A4D /* PopupMenuTable.cpp */; };
|
|
||||||
5E73963E1DAFD86000BA0A4D /* ZoomHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E73963C1DAFD86000BA0A4D /* ZoomHandle.cpp */; };
|
|
||||||
8406A93812D0F2510011EA01 /* EQDefaultCurves.xml in Resources */ = {isa = PBXBuildFile; fileRef = 8406A93712D0F2510011EA01 /* EQDefaultCurves.xml */; };
|
8406A93812D0F2510011EA01 /* EQDefaultCurves.xml in Resources */ = {isa = PBXBuildFile; fileRef = 8406A93712D0F2510011EA01 /* EQDefaultCurves.xml */; };
|
||||||
8484F31413086237002DF7F0 /* DeviceManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8484F31213086237002DF7F0 /* DeviceManager.cpp */; };
|
8484F31413086237002DF7F0 /* DeviceManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8484F31213086237002DF7F0 /* DeviceManager.cpp */; };
|
||||||
AA0084191EA8C6E70070CCE3 /* TracksBehaviorsPrefs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AA0084181EA8C6E70070CCE3 /* TracksBehaviorsPrefs.cpp */; };
|
AA0084191EA8C6E70070CCE3 /* TracksBehaviorsPrefs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AA0084181EA8C6E70070CCE3 /* TracksBehaviorsPrefs.cpp */; };
|
||||||
@ -3001,6 +3002,8 @@
|
|||||||
28FE4A060ABF4E960056F5C4 /* mmx_optimized.cpp */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 3; lastKnownFileType = sourcecode.cpp.cpp; path = mmx_optimized.cpp; sourceTree = "<group>"; tabWidth = 3; };
|
28FE4A060ABF4E960056F5C4 /* mmx_optimized.cpp */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 3; lastKnownFileType = sourcecode.cpp.cpp; path = mmx_optimized.cpp; sourceTree = "<group>"; tabWidth = 3; };
|
||||||
28FE4A070ABF4E960056F5C4 /* sse_optimized.cpp */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 3; lastKnownFileType = sourcecode.cpp.cpp; path = sse_optimized.cpp; sourceTree = "<group>"; tabWidth = 3; };
|
28FE4A070ABF4E960056F5C4 /* sse_optimized.cpp */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 3; lastKnownFileType = sourcecode.cpp.cpp; path = sse_optimized.cpp; sourceTree = "<group>"; tabWidth = 3; };
|
||||||
28FEC1B21A12B6FB00FACE48 /* EffectAutomationParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EffectAutomationParameters.h; path = ../include/audacity/EffectAutomationParameters.h; sourceTree = SOURCE_ROOT; };
|
28FEC1B21A12B6FB00FACE48 /* EffectAutomationParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EffectAutomationParameters.h; path = ../include/audacity/EffectAutomationParameters.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
5E000A1F1EC7B5D500E8FD93 /* SampleHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SampleHandle.cpp; sourceTree = "<group>"; };
|
||||||
|
5E000A201EC7B5D500E8FD93 /* SampleHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SampleHandle.h; sourceTree = "<group>"; };
|
||||||
5E02BFF01D1164DF00EB7578 /* Distortion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Distortion.cpp; sourceTree = "<group>"; };
|
5E02BFF01D1164DF00EB7578 /* Distortion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Distortion.cpp; sourceTree = "<group>"; };
|
||||||
5E02BFF11D1164DF00EB7578 /* Distortion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Distortion.h; sourceTree = "<group>"; };
|
5E02BFF11D1164DF00EB7578 /* Distortion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Distortion.h; sourceTree = "<group>"; };
|
||||||
5E07842C1DEE6B8600CA76EA /* FileException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileException.cpp; sourceTree = "<group>"; };
|
5E07842C1DEE6B8600CA76EA /* FileException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileException.cpp; sourceTree = "<group>"; };
|
||||||
@ -3034,6 +3037,9 @@
|
|||||||
5E15126C1DB0010C00702E29 /* TrackVRulerControls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackVRulerControls.h; sourceTree = "<group>"; };
|
5E15126C1DB0010C00702E29 /* TrackVRulerControls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackVRulerControls.h; sourceTree = "<group>"; };
|
||||||
5E4685F81CCA9D84008741F2 /* CommandFunctors.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CommandFunctors.h; sourceTree = "<group>"; };
|
5E4685F81CCA9D84008741F2 /* CommandFunctors.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CommandFunctors.h; sourceTree = "<group>"; };
|
||||||
5E61EE0C1CBAA6BB0009FCF1 /* MemoryX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemoryX.h; sourceTree = "<group>"; };
|
5E61EE0C1CBAA6BB0009FCF1 /* MemoryX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemoryX.h; sourceTree = "<group>"; };
|
||||||
|
5E7396391DAFD82D00BA0A4D /* PopupMenuTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PopupMenuTable.cpp; sourceTree = "<group>"; };
|
||||||
|
5E73963C1DAFD86000BA0A4D /* ZoomHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ZoomHandle.cpp; sourceTree = "<group>"; };
|
||||||
|
5E73963D1DAFD86000BA0A4D /* ZoomHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZoomHandle.h; sourceTree = "<group>"; };
|
||||||
5E74D2D91CC4427B00D88B0B /* TrackPanelCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackPanelCell.h; sourceTree = "<group>"; };
|
5E74D2D91CC4427B00D88B0B /* TrackPanelCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackPanelCell.h; sourceTree = "<group>"; };
|
||||||
5E74D2DA1CC4427B00D88B0B /* TrackPanelCellIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackPanelCellIterator.h; sourceTree = "<group>"; };
|
5E74D2DA1CC4427B00D88B0B /* TrackPanelCellIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackPanelCellIterator.h; sourceTree = "<group>"; };
|
||||||
5E74D2DD1CC4429700D88B0B /* EditCursorOverlay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EditCursorOverlay.cpp; sourceTree = "<group>"; };
|
5E74D2DD1CC4429700D88B0B /* EditCursorOverlay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EditCursorOverlay.cpp; sourceTree = "<group>"; };
|
||||||
@ -3074,10 +3080,7 @@
|
|||||||
5EF17C221D1F0A690090A642 /* ScrubbingToolBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrubbingToolBar.h; sourceTree = "<group>"; };
|
5EF17C221D1F0A690090A642 /* ScrubbingToolBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrubbingToolBar.h; sourceTree = "<group>"; };
|
||||||
5EF958831DEB121800191280 /* InconsistencyException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InconsistencyException.cpp; sourceTree = "<group>"; };
|
5EF958831DEB121800191280 /* InconsistencyException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InconsistencyException.cpp; sourceTree = "<group>"; };
|
||||||
5EF958841DEB121800191280 /* InconsistencyException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InconsistencyException.h; sourceTree = "<group>"; };
|
5EF958841DEB121800191280 /* InconsistencyException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InconsistencyException.h; sourceTree = "<group>"; };
|
||||||
5E7396391DAFD82D00BA0A4D /* PopupMenuTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PopupMenuTable.cpp; sourceTree = "<group>"; };
|
|
||||||
5E73963A1DAFD82D00BA0A4D /* PopupMenuTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PopupMenuTable.h; sourceTree = "<group>"; };
|
5E73963A1DAFD82D00BA0A4D /* PopupMenuTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PopupMenuTable.h; sourceTree = "<group>"; };
|
||||||
5E73963C1DAFD86000BA0A4D /* ZoomHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ZoomHandle.cpp; sourceTree = "<group>"; };
|
|
||||||
5E73963D1DAFD86000BA0A4D /* ZoomHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZoomHandle.h; sourceTree = "<group>"; };
|
|
||||||
82FF184D13CF01A600C1B664 /* dBTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dBTable.cpp; path = sbsms/src/dBTable.cpp; sourceTree = "<group>"; };
|
82FF184D13CF01A600C1B664 /* dBTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dBTable.cpp; path = sbsms/src/dBTable.cpp; sourceTree = "<group>"; };
|
||||||
82FF184E13CF01A600C1B664 /* dBTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dBTable.h; path = sbsms/src/dBTable.h; sourceTree = "<group>"; };
|
82FF184E13CF01A600C1B664 /* dBTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dBTable.h; path = sbsms/src/dBTable.h; sourceTree = "<group>"; };
|
||||||
82FF184F13CF01A600C1B664 /* slide.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = slide.cpp; path = sbsms/src/slide.cpp; sourceTree = "<group>"; };
|
82FF184F13CF01A600C1B664 /* slide.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = slide.cpp; path = sbsms/src/slide.cpp; sourceTree = "<group>"; };
|
||||||
@ -5784,6 +5787,8 @@
|
|||||||
5EA018221EC7B226001F2996 /* ui */ = {
|
5EA018221EC7B226001F2996 /* ui */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
5E000A1F1EC7B5D500E8FD93 /* SampleHandle.cpp */,
|
||||||
|
5E000A201EC7B5D500E8FD93 /* SampleHandle.h */,
|
||||||
5EA018231EC7B226001F2996 /* WaveTrackControls.cpp */,
|
5EA018231EC7B226001F2996 /* WaveTrackControls.cpp */,
|
||||||
5EA018241EC7B226001F2996 /* WaveTrackControls.h */,
|
5EA018241EC7B226001F2996 /* WaveTrackControls.h */,
|
||||||
5EA018251EC7B226001F2996 /* WaveTrackUI.cpp */,
|
5EA018251EC7B226001F2996 /* WaveTrackUI.cpp */,
|
||||||
@ -7550,6 +7555,7 @@
|
|||||||
1790B13C09883BFD008A330A /* Fade.cpp in Sources */,
|
1790B13C09883BFD008A330A /* Fade.cpp in Sources */,
|
||||||
1790B13E09883BFD008A330A /* Invert.cpp in Sources */,
|
1790B13E09883BFD008A330A /* Invert.cpp in Sources */,
|
||||||
1790B13F09883BFD008A330A /* LadspaEffect.cpp in Sources */,
|
1790B13F09883BFD008A330A /* LadspaEffect.cpp in Sources */,
|
||||||
|
5E000A211EC7B5D500E8FD93 /* SampleHandle.cpp in Sources */,
|
||||||
1790B14109883BFD008A330A /* Leveller.cpp in Sources */,
|
1790B14109883BFD008A330A /* Leveller.cpp in Sources */,
|
||||||
1790B14209883BFD008A330A /* LoadEffects.cpp in Sources */,
|
1790B14209883BFD008A330A /* LoadEffects.cpp in Sources */,
|
||||||
5E0784311DF1E4F400CA76EA /* UserException.cpp in Sources */,
|
5E0784311DF1E4F400CA76EA /* UserException.cpp in Sources */,
|
||||||
|
@ -559,6 +559,8 @@ audacity_SOURCES = \
|
|||||||
tracks/playabletrack/notetrack/ui/NoteTrackUI.cpp \
|
tracks/playabletrack/notetrack/ui/NoteTrackUI.cpp \
|
||||||
tracks/playabletrack/notetrack/ui/NoteTrackVRulerControls.cpp \
|
tracks/playabletrack/notetrack/ui/NoteTrackVRulerControls.cpp \
|
||||||
tracks/playabletrack/notetrack/ui/NoteTrackVRulerControls.h \
|
tracks/playabletrack/notetrack/ui/NoteTrackVRulerControls.h \
|
||||||
|
tracks/playabletrack/wavetrack/ui/SampleHandle.cpp \
|
||||||
|
tracks/playabletrack/wavetrack/ui/SampleHandle.h \
|
||||||
tracks/playabletrack/wavetrack/ui/WaveTrackControls.cpp \
|
tracks/playabletrack/wavetrack/ui/WaveTrackControls.cpp \
|
||||||
tracks/playabletrack/wavetrack/ui/WaveTrackControls.h \
|
tracks/playabletrack/wavetrack/ui/WaveTrackControls.h \
|
||||||
tracks/playabletrack/wavetrack/ui/WaveTrackVRulerControls.cpp \
|
tracks/playabletrack/wavetrack/ui/WaveTrackVRulerControls.cpp \
|
||||||
|
@ -467,7 +467,6 @@ TrackPanel::TrackPanel(wxWindow * parent, wxWindowID id,
|
|||||||
|
|
||||||
mRedrawAfterStop = false;
|
mRedrawAfterStop = false;
|
||||||
|
|
||||||
mPencilCursor = MakeCursor( wxCURSOR_PENCIL, DrawCursorXpm, 12, 22);
|
|
||||||
mSelectCursor = MakeCursor( wxCURSOR_IBEAM, IBeamCursorXpm, 17, 16);
|
mSelectCursor = MakeCursor( wxCURSOR_IBEAM, IBeamCursorXpm, 17, 16);
|
||||||
mEnvelopeCursor= MakeCursor( wxCURSOR_ARROW, EnvCursorXpm, 16, 16);
|
mEnvelopeCursor= MakeCursor( wxCURSOR_ARROW, EnvCursorXpm, 16, 16);
|
||||||
mDisabledCursor= MakeCursor( wxCURSOR_NO_ENTRY, DisabledCursorXpm,16, 16);
|
mDisabledCursor= MakeCursor( wxCURSOR_NO_ENTRY, DisabledCursorXpm,16, 16);
|
||||||
@ -492,7 +491,6 @@ TrackPanel::TrackPanel(wxWindow * parent, wxWindowID id,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
mArrowCursor = std::make_unique<wxCursor>(wxCURSOR_ARROW);
|
mArrowCursor = std::make_unique<wxCursor>(wxCURSOR_ARROW);
|
||||||
mSmoothCursor = std::make_unique<wxCursor>(wxCURSOR_SPRAYCAN);
|
|
||||||
mResizeCursor = std::make_unique<wxCursor>(wxCURSOR_SIZENS);
|
mResizeCursor = std::make_unique<wxCursor>(wxCURSOR_SIZENS);
|
||||||
mRearrangeCursor = std::make_unique<wxCursor>(wxCURSOR_HAND);
|
mRearrangeCursor = std::make_unique<wxCursor>(wxCURSOR_HAND);
|
||||||
mAdjustLeftSelectionCursor = std::make_unique<wxCursor>(wxCURSOR_POINT_LEFT);
|
mAdjustLeftSelectionCursor = std::make_unique<wxCursor>(wxCURSOR_POINT_LEFT);
|
||||||
@ -520,10 +518,6 @@ TrackPanel::TrackPanel(wxWindow * parent, wxWindowID id,
|
|||||||
// Timer is started after the window is visible
|
// Timer is started after the window is visible
|
||||||
GetProject()->Bind(wxEVT_IDLE, &TrackPanel::OnIdle, this);
|
GetProject()->Bind(wxEVT_IDLE, &TrackPanel::OnIdle, this);
|
||||||
|
|
||||||
//Initialize a member variable pointing to the current
|
|
||||||
//drawing track.
|
|
||||||
mDrawingTrack =NULL;
|
|
||||||
|
|
||||||
mZoomStart = -1;
|
mZoomStart = -1;
|
||||||
mZoomEnd = -1;
|
mZoomEnd = -1;
|
||||||
|
|
||||||
@ -1157,7 +1151,6 @@ void TrackPanel::HandleInterruptedDrag()
|
|||||||
|
|
||||||
IsClosing,
|
IsClosing,
|
||||||
IsAdjustingLabel,
|
IsAdjustingLabel,
|
||||||
IsAdjustingSample,
|
|
||||||
IsRearranging,
|
IsRearranging,
|
||||||
IsSliding,
|
IsSliding,
|
||||||
IsEnveloping,
|
IsEnveloping,
|
||||||
@ -1298,7 +1291,6 @@ bool TrackPanel::HandleEscapeKey(bool down)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IsVZooming:
|
case IsVZooming:
|
||||||
//case IsAdjustingSample:
|
|
||||||
break;
|
break;
|
||||||
case IsResizing:
|
case IsResizing:
|
||||||
mCapturedTrack->SetHeight(mInitialActualHeight);
|
mCapturedTrack->SetHeight(mInitialActualHeight);
|
||||||
@ -1762,7 +1754,7 @@ void TrackPanel::SetCursorAndTipWhenSelectTool( Track * t,
|
|||||||
/// In this method we know what tool we are using,
|
/// In this method we know what tool we are using,
|
||||||
/// so set the cursor accordingly.
|
/// so set the cursor accordingly.
|
||||||
void TrackPanel::SetCursorAndTipByTool( int tool,
|
void TrackPanel::SetCursorAndTipByTool( int tool,
|
||||||
const wxMouseEvent & event, wxString& )
|
const wxMouseEvent &, wxString& )
|
||||||
{
|
{
|
||||||
bool unsafe = IsUnsafe();
|
bool unsafe = IsUnsafe();
|
||||||
|
|
||||||
@ -1777,12 +1769,6 @@ void TrackPanel::SetCursorAndTipByTool( int tool,
|
|||||||
case slideTool:
|
case slideTool:
|
||||||
SetCursor(unsafe ? *mDisabledCursor : *mSlideCursor);
|
SetCursor(unsafe ? *mDisabledCursor : *mSlideCursor);
|
||||||
break;
|
break;
|
||||||
case drawTool:
|
|
||||||
if (unsafe)
|
|
||||||
SetCursor(*mDisabledCursor);
|
|
||||||
else
|
|
||||||
SetCursor(event.AltDown()? *mSmoothCursor : *mPencilCursor);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
// doesn't actually change the tip itself, but it could (should?) do at some
|
// doesn't actually change the tip itself, but it could (should?) do at some
|
||||||
// future date.
|
// future date.
|
||||||
@ -4407,330 +4393,6 @@ void TrackPanel::HandleWaveTrackVZoom
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
|
||||||
// Is the sample horizontally nearest to the cursor sufficiently separated from
|
|
||||||
// its neighbors that the pencil tool should be allowed to drag it?
|
|
||||||
bool SampleResolutionTest(const ViewInfo &viewInfo, const WaveTrack *wt, double time, double rate, int width)
|
|
||||||
{
|
|
||||||
// Require more than 3 pixels per sample
|
|
||||||
// Round to an exact sample time
|
|
||||||
const double adjustedTime = wt->LongSamplesToTime(wt->TimeToLongSamples(time));
|
|
||||||
const wxInt64 xx = std::max(wxInt64(0), viewInfo.TimeToPosition(adjustedTime));
|
|
||||||
ZoomInfo::Intervals intervals;
|
|
||||||
viewInfo.FindIntervals(rate, intervals, width);
|
|
||||||
ZoomInfo::Intervals::const_iterator it = intervals.begin(), end = intervals.end(), prev;
|
|
||||||
wxASSERT(it != end && it->position == 0);
|
|
||||||
do
|
|
||||||
prev = it++;
|
|
||||||
while (it != end && it->position <= xx);
|
|
||||||
const double threshold = 3 * rate; // three times as many pixels per second, as samples
|
|
||||||
return prev->averageZoom > threshold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Determines if we can edit samples in a wave track.
|
|
||||||
/// Also pops up warning messages in certain cases where we can't.
|
|
||||||
/// @return true if we can edit the samples, false otherwise.
|
|
||||||
bool TrackPanel::IsSampleEditingPossible( wxMouseEvent &event, const WaveTrack * wt )
|
|
||||||
{
|
|
||||||
//Exit if it's not waveform display
|
|
||||||
//Get out of here if we shouldn't be drawing right now:
|
|
||||||
//If we aren't displaying the waveform, Display a message dialog
|
|
||||||
const int display = wt->GetDisplay();
|
|
||||||
|
|
||||||
if (WaveTrack::Waveform != display)
|
|
||||||
{
|
|
||||||
wxMessageBox(_("To use Draw, choose 'Waveform' or 'Waveform (dB)' in the Track Dropdown Menu."), _("Draw Tool"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool showPoints;
|
|
||||||
{
|
|
||||||
const auto foundCell = FindCell(event.m_x, event.m_y);
|
|
||||||
if ( foundCell.type != CellType::Track )
|
|
||||||
return false;
|
|
||||||
const double rate = wt->GetRate();
|
|
||||||
const double time = mViewInfo->PositionToTime(event.m_x, foundCell.rect.x);
|
|
||||||
int width;
|
|
||||||
GetTracksUsableArea(&width, NULL);
|
|
||||||
showPoints = SampleResolutionTest(*mViewInfo, wt, time, rate, width);
|
|
||||||
}
|
|
||||||
|
|
||||||
//If we aren't zoomed in far enough, show a message dialog.
|
|
||||||
if(!showPoints)
|
|
||||||
{
|
|
||||||
wxMessageBox(_("To use Draw, zoom in further until you can see the individual samples."), _("Draw Tool"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
float TrackPanel::FindSampleEditingLevel(wxMouseEvent &event, double dBRange, double t0)
|
|
||||||
{
|
|
||||||
// Calculate where the mouse is located vertically (between +/- 1)
|
|
||||||
float zoomMin, zoomMax;
|
|
||||||
mDrawingTrack->GetDisplayBounds(&zoomMin, &zoomMax);
|
|
||||||
|
|
||||||
const int y = event.m_y - mDrawingTrackTop;
|
|
||||||
const int height = mDrawingTrack->GetHeight() - (kTopMargin + kBottomMargin);
|
|
||||||
const bool dB = !mDrawingTrack->GetWaveformSettings().isLinear();
|
|
||||||
float newLevel =
|
|
||||||
::ValueOfPixel(y, height, false, dB, dBRange, zoomMin, zoomMax);
|
|
||||||
|
|
||||||
//Take the envelope into account
|
|
||||||
Envelope *const env = mDrawingTrack->GetEnvelopeAtX(event.m_x);
|
|
||||||
if (env)
|
|
||||||
{
|
|
||||||
// Calculate sample as it would be rendered, so quantize time
|
|
||||||
double envValue = env->GetValue( t0, 1.0 / mDrawingTrack->GetRate() );
|
|
||||||
if (envValue > 0)
|
|
||||||
newLevel /= envValue;
|
|
||||||
else
|
|
||||||
newLevel = 0;
|
|
||||||
|
|
||||||
//Make sure the NEW level is between +/-1
|
|
||||||
newLevel = std::max(-1.0f, std::min(1.0f, newLevel));
|
|
||||||
}
|
|
||||||
|
|
||||||
return newLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// We're in a track view and zoomed enough to see the samples.
|
|
||||||
/// Someone has just clicked the mouse. What do we do?
|
|
||||||
void TrackPanel::HandleSampleEditingClick( wxMouseEvent & event )
|
|
||||||
{
|
|
||||||
//Get the track the mouse is over, and save it away for future events
|
|
||||||
mDrawingTrack = NULL;
|
|
||||||
const auto foundCell = FindCell(event.m_x, event.m_y);
|
|
||||||
auto &t = foundCell.pTrack;
|
|
||||||
auto &rect = foundCell.rect;
|
|
||||||
|
|
||||||
if (!t || (t->GetKind() != Track::Wave)
|
|
||||||
|| foundCell.type != CellType::Track)
|
|
||||||
return;
|
|
||||||
const auto wt = static_cast<WaveTrack *>(t);
|
|
||||||
if( !IsSampleEditingPossible( event, wt ) )
|
|
||||||
return;
|
|
||||||
|
|
||||||
/// \todo Should mCapturedTrack take the place of mDrawingTrack??
|
|
||||||
mDrawingTrack = wt;
|
|
||||||
mDrawingTrackTop = rect.y + kTopMargin;
|
|
||||||
|
|
||||||
//If we are still around, we are drawing in earnest. Set some member data structures up:
|
|
||||||
//First, calculate the starting sample. To get this, we need the time
|
|
||||||
double t0 = mViewInfo->PositionToTime(event.m_x, GetLeftOffset());
|
|
||||||
|
|
||||||
//convert t0 to samples
|
|
||||||
mDrawingStartSample = mDrawingTrack->TimeToLongSamples(t0);
|
|
||||||
// quantize
|
|
||||||
t0 = mDrawingTrack->LongSamplesToTime(mDrawingStartSample);
|
|
||||||
|
|
||||||
//Determine how drawing should occur. If alt is down,
|
|
||||||
//do a smoothing, instead of redrawing.
|
|
||||||
if( event.m_altDown )
|
|
||||||
{
|
|
||||||
//*************************************************
|
|
||||||
//*** ALT-DOWN-CLICK (SAMPLE SMOOTHING) ***
|
|
||||||
//*************************************************
|
|
||||||
//
|
|
||||||
// Smoothing works like this: There is a smoothing kernel radius constant that
|
|
||||||
// determines how wide the averaging window is. Plus, there is a smoothing brush radius,
|
|
||||||
// which determines how many pixels wide around the selected pixel this smoothing is applied.
|
|
||||||
//
|
|
||||||
// Samples will be replaced by a mixture of the original points and the smoothed points,
|
|
||||||
// with a triangular mixing probability whose value at the center point is
|
|
||||||
// SMOOTHING_PROPORTION_MAX and at the far bounds is SMOOTHING_PROPORTION_MIN
|
|
||||||
|
|
||||||
//Get the region of samples around the selected point
|
|
||||||
size_t sampleRegionSize = 1 + 2 * (SMOOTHING_KERNEL_RADIUS + SMOOTHING_BRUSH_RADIUS);
|
|
||||||
Floats sampleRegion{ sampleRegionSize };
|
|
||||||
Floats newSampleRegion{ 1 + 2 * (size_t)SMOOTHING_BRUSH_RADIUS };
|
|
||||||
|
|
||||||
//Get a sample from the track to do some tricks on.
|
|
||||||
mDrawingTrack->Get((samplePtr)sampleRegion.get(), floatSample,
|
|
||||||
mDrawingStartSample - SMOOTHING_KERNEL_RADIUS - SMOOTHING_BRUSH_RADIUS,
|
|
||||||
sampleRegionSize);
|
|
||||||
//Go through each point of the smoothing brush and apply a smoothing operation.
|
|
||||||
for(auto j = -SMOOTHING_BRUSH_RADIUS; j <= SMOOTHING_BRUSH_RADIUS; j++){
|
|
||||||
float sumOfSamples = 0;
|
|
||||||
for (auto i = -SMOOTHING_KERNEL_RADIUS; i <= SMOOTHING_KERNEL_RADIUS; i++){
|
|
||||||
//Go through each point of the smoothing kernel and find the average
|
|
||||||
|
|
||||||
//The average is a weighted average, scaled by a weighting kernel that is simply triangular
|
|
||||||
// A triangular kernel across N items, with a radius of R ( 2 R + 1 points), if the farthest:
|
|
||||||
// points have a probability of a, the entire triangle has total probability of (R + 1)^2.
|
|
||||||
// For sample number i and middle brush sample M, (R + 1 - abs(M-i))/ ((R+1)^2) gives a
|
|
||||||
// legal distribution whose total probability is 1.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// weighting factor value
|
|
||||||
sumOfSamples += (SMOOTHING_KERNEL_RADIUS + 1 - abs(i)) * sampleRegion[i + j + SMOOTHING_KERNEL_RADIUS + SMOOTHING_BRUSH_RADIUS];
|
|
||||||
|
|
||||||
}
|
|
||||||
newSampleRegion[j + SMOOTHING_BRUSH_RADIUS] = sumOfSamples/((SMOOTHING_KERNEL_RADIUS + 1) *(SMOOTHING_KERNEL_RADIUS + 1) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Now that the NEW sample levels are determined, go through each and mix it appropriately
|
|
||||||
// with the original point, according to a 2-part linear function whose center has probability
|
|
||||||
// SMOOTHING_PROPORTION_MAX and extends out SMOOTHING_BRUSH_RADIUS, at which the probability is
|
|
||||||
// SMOOTHING_PROPORTION_MIN. _MIN and _MAX specify how much of the smoothed curve make it through.
|
|
||||||
|
|
||||||
float prob;
|
|
||||||
|
|
||||||
for(auto j = -SMOOTHING_BRUSH_RADIUS; j <= SMOOTHING_BRUSH_RADIUS; j++){
|
|
||||||
|
|
||||||
prob = SMOOTHING_PROPORTION_MAX - (float)abs(j)/SMOOTHING_BRUSH_RADIUS * (SMOOTHING_PROPORTION_MAX - SMOOTHING_PROPORTION_MIN);
|
|
||||||
|
|
||||||
newSampleRegion[j+SMOOTHING_BRUSH_RADIUS] =
|
|
||||||
newSampleRegion[j + SMOOTHING_BRUSH_RADIUS] * prob +
|
|
||||||
sampleRegion[SMOOTHING_BRUSH_RADIUS + SMOOTHING_KERNEL_RADIUS + j] * (1 - prob);
|
|
||||||
}
|
|
||||||
//Set the sample to the point of the mouse event
|
|
||||||
mDrawingTrack->Set((samplePtr)newSampleRegion.get(), floatSample, mDrawingStartSample - SMOOTHING_BRUSH_RADIUS, 1 + 2 * SMOOTHING_BRUSH_RADIUS);
|
|
||||||
|
|
||||||
mDrawingLastDragSampleValue = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//*************************************************
|
|
||||||
//*** PLAIN DOWN-CLICK (NORMAL DRAWING) ***
|
|
||||||
//*************************************************
|
|
||||||
|
|
||||||
SetCapturedTrack(t, IsAdjustingSample);
|
|
||||||
|
|
||||||
//Otherwise (e.g., the alt button is not down) do normal redrawing, based on the mouse position.
|
|
||||||
const float newLevel = FindSampleEditingLevel
|
|
||||||
(event, mDrawingTrack->GetWaveformSettings().dBRange, t0);
|
|
||||||
|
|
||||||
//Set the sample to the point of the mouse event
|
|
||||||
mDrawingTrack->Set((samplePtr)&newLevel, floatSample, mDrawingStartSample, 1);
|
|
||||||
|
|
||||||
mDrawingLastDragSampleValue = newLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Set the member data structures for drawing
|
|
||||||
mDrawingLastDragSample=mDrawingStartSample;
|
|
||||||
|
|
||||||
//Redraw the region of the selected track
|
|
||||||
RefreshTrack(mDrawingTrack);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TrackPanel::HandleSampleEditingDrag( wxMouseEvent & event )
|
|
||||||
{
|
|
||||||
//*************************************************
|
|
||||||
//*** DRAG-DRAWING ***
|
|
||||||
//*************************************************
|
|
||||||
|
|
||||||
//The following will happen on a drag or a down-click.
|
|
||||||
// The point should get re-drawn at the location of the mouse.
|
|
||||||
//Exit if the mDrawingTrack is null.
|
|
||||||
if( mDrawingTrack == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
//Exit dragging if the alt key is down--Don't allow left-right dragging for smoothing operation
|
|
||||||
if (mMouseCapture != IsAdjustingSample)
|
|
||||||
return;
|
|
||||||
|
|
||||||
sampleCount s0; //declare this for use below. It designates the sample number which to draw.
|
|
||||||
|
|
||||||
// Figure out what time the click was at
|
|
||||||
//Find the point that we want to redraw at. If the control button is down,
|
|
||||||
//adjust only the originally clicked-on sample
|
|
||||||
|
|
||||||
if( event.m_controlDown) {
|
|
||||||
//*************************************************
|
|
||||||
//*** CTRL-DOWN (Hold Initial Sample Constant ***
|
|
||||||
//*************************************************
|
|
||||||
|
|
||||||
s0 = mDrawingStartSample;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//*************************************************
|
|
||||||
//*** Normal CLICK-drag (Normal drawing) ***
|
|
||||||
//*************************************************
|
|
||||||
|
|
||||||
//Otherwise, adjust the sample you are dragging over right now.
|
|
||||||
//convert this to samples
|
|
||||||
const double t = mViewInfo->PositionToTime(event.m_x, GetLeftOffset());
|
|
||||||
s0 = mDrawingTrack->TimeToLongSamples(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
const double t0 = mDrawingTrack->LongSamplesToTime(s0);
|
|
||||||
|
|
||||||
//Otherwise, do normal redrawing, based on the mouse position.
|
|
||||||
// Calculate where the mouse is located vertically (between +/- 1)
|
|
||||||
|
|
||||||
const float newLevel = FindSampleEditingLevel
|
|
||||||
(event, mDrawingTrack->GetWaveformSettings().dBRange, t0);
|
|
||||||
|
|
||||||
//Now, redraw all samples between current and last redrawn sample, inclusive
|
|
||||||
//Go from the smaller to larger sample.
|
|
||||||
const auto start = std::min( s0, mDrawingLastDragSample);
|
|
||||||
const auto end = std::max( s0, mDrawingLastDragSample);
|
|
||||||
// Few enough samples to be drawn individually on screen will not
|
|
||||||
// overflow size_t:
|
|
||||||
const auto size = ( end - start + 1 ).as_size_t();
|
|
||||||
if (size == 1) {
|
|
||||||
mDrawingTrack->Set((samplePtr)&newLevel, floatSample, start, size);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
std::vector<float> values(size);
|
|
||||||
for (auto i = start; i <= end; ++i) {
|
|
||||||
//This interpolates each sample linearly:
|
|
||||||
// i - start will not overflow size_t either:
|
|
||||||
values[( i - start ).as_size_t()] =
|
|
||||||
mDrawingLastDragSampleValue + (newLevel - mDrawingLastDragSampleValue) *
|
|
||||||
(i - mDrawingLastDragSample).as_float() /
|
|
||||||
(s0 - mDrawingLastDragSample).as_float();
|
|
||||||
}
|
|
||||||
mDrawingTrack->Set((samplePtr)&values[0], floatSample, start, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Update the member data structures.
|
|
||||||
mDrawingLastDragSample=s0;
|
|
||||||
mDrawingLastDragSampleValue = newLevel;
|
|
||||||
|
|
||||||
//Redraw the region of the selected track
|
|
||||||
RefreshTrack(mDrawingTrack);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TrackPanel::HandleSampleEditingButtonUp( wxMouseEvent & WXUNUSED(event))
|
|
||||||
{
|
|
||||||
//*************************************************
|
|
||||||
//*** UP-CLICK (Finish drawing) ***
|
|
||||||
//*************************************************
|
|
||||||
SetCapturedTrack( NULL );
|
|
||||||
//On up-click, send the state to the undo stack
|
|
||||||
mDrawingTrack=NULL; //Set this to NULL so it will catch improper drag events.
|
|
||||||
MakeParentPushState(_("Moved Samples"),
|
|
||||||
_("Sample Edit"),
|
|
||||||
UndoPush::CONSOLIDATE | UndoPush::AUTOSAVE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// This handles adjusting individual samples by hand using the draw tool(s)
|
|
||||||
///
|
|
||||||
/// There are several member data structure for handling drawing:
|
|
||||||
/// - mDrawingTrack: keeps track of which track you clicked down on, so drawing doesn't
|
|
||||||
/// jump to a NEW track
|
|
||||||
/// - mDrawingTrackTop: The top position of the drawing track--makes drawing easier.
|
|
||||||
/// - mDrawingStartSample: The sample you clicked down on, so that you can hold it steady
|
|
||||||
/// - mDrawingLastDragSample: When drag-drawing, this keeps track of the last sample you dragged over,
|
|
||||||
/// so it can smoothly redraw samples that got skipped over
|
|
||||||
/// - mDrawingLastDragSampleValue: The value of the last
|
|
||||||
void TrackPanel::HandleSampleEditing(wxMouseEvent & event)
|
|
||||||
{
|
|
||||||
if (event.LeftDown() ) {
|
|
||||||
HandleSampleEditingClick( event);
|
|
||||||
} else if (mDrawingTrack && event.Dragging()) {
|
|
||||||
HandleSampleEditingDrag( event );
|
|
||||||
} else if(mDrawingTrack && event.ButtonUp()) {
|
|
||||||
HandleSampleEditingButtonUp( event );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// This is for when a given track gets the x.
|
// This is for when a given track gets the x.
|
||||||
void TrackPanel::HandleClosing(wxMouseEvent & event)
|
void TrackPanel::HandleClosing(wxMouseEvent & event)
|
||||||
{
|
{
|
||||||
@ -6885,10 +6547,6 @@ void TrackPanel::HandleTrackSpecificMouseEvent(wxMouseEvent & event)
|
|||||||
if (!unsafe)
|
if (!unsafe)
|
||||||
HandleSlide(event);
|
HandleSlide(event);
|
||||||
break;
|
break;
|
||||||
case drawTool:
|
|
||||||
if (!unsafe)
|
|
||||||
HandleSampleEditing(event);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6958,8 +6616,6 @@ int TrackPanel::DetermineToolToUse( ToolsToolBar * pTtb, const wxMouseEvent & ev
|
|||||||
currentTool = envelopeTool;
|
currentTool = envelopeTool;
|
||||||
} else if( HitTestSlide( pTrack, rect, event )){
|
} else if( HitTestSlide( pTrack, rect, event )){
|
||||||
currentTool = slideTool;
|
currentTool = slideTool;
|
||||||
} else if( HitTestSamples( pTrack, rect, event )){
|
|
||||||
currentTool = drawTool;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Use the false argument since in multimode we don't
|
//Use the false argument since in multimode we don't
|
||||||
@ -7069,62 +6725,6 @@ bool TrackPanel::HitTestEnvelope(Track *track, const wxRect &rect, const wxMouse
|
|||||||
return( distance < yTolerance );
|
return( distance < yTolerance );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// method that tells us if the mouse event landed on an
|
|
||||||
/// editable sample
|
|
||||||
bool TrackPanel::HitTestSamples(Track *track, const wxRect &rect, const wxMouseEvent & event)
|
|
||||||
{
|
|
||||||
wxASSERT(track);
|
|
||||||
if( track->GetKind() != Track::Wave )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
WaveTrack *wavetrack = (WaveTrack *)track;
|
|
||||||
//Get rate in order to calculate the critical zoom threshold
|
|
||||||
double rate = wavetrack->GetRate();
|
|
||||||
const double dBRange = wavetrack->GetWaveformSettings().dBRange;
|
|
||||||
|
|
||||||
const int displayType = wavetrack->GetDisplay();
|
|
||||||
if (WaveTrack::Waveform != displayType)
|
|
||||||
return false; // Not a wave, so return.
|
|
||||||
const bool dB = !wavetrack->GetWaveformSettings().isLinear();
|
|
||||||
|
|
||||||
const double tt = mViewInfo->PositionToTime(event.m_x, rect.x);
|
|
||||||
int width;
|
|
||||||
GetTracksUsableArea(&width, NULL);
|
|
||||||
if (!SampleResolutionTest(*mViewInfo, wavetrack, tt, rate, width))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Just get one sample.
|
|
||||||
float oneSample;
|
|
||||||
auto s0 = (sampleCount)(tt * rate + 0.5);
|
|
||||||
if ( !wavetrack->Get(
|
|
||||||
(samplePtr)&oneSample, floatSample, s0, 1, fillZero,
|
|
||||||
// Do not propagate exception but return a failure value
|
|
||||||
false))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Get y distance of envelope point from center line (in pixels).
|
|
||||||
float zoomMin, zoomMax;
|
|
||||||
|
|
||||||
wavetrack->GetDisplayBounds(&zoomMin, &zoomMax);
|
|
||||||
|
|
||||||
double envValue = 1.0;
|
|
||||||
Envelope* env = wavetrack->GetEnvelopeAtX(event.GetX());
|
|
||||||
if (env)
|
|
||||||
// Calculate sample as it would be rendered, so quantize time
|
|
||||||
envValue = env->GetValue( tt, 1.0 / wavetrack->GetRate() );
|
|
||||||
|
|
||||||
int yValue = GetWaveYPos( oneSample * envValue,
|
|
||||||
zoomMin, zoomMax,
|
|
||||||
rect.height, dB, true, dBRange, false) + rect.y;
|
|
||||||
|
|
||||||
// Get y position of mouse (in pixels)
|
|
||||||
int yMouse = event.m_y;
|
|
||||||
|
|
||||||
// Perhaps yTolerance should be put into preferences?
|
|
||||||
const int yTolerance = 10; // More tolerance on samples than on envelope.
|
|
||||||
return( abs( yValue - yMouse ) < yTolerance );
|
|
||||||
}
|
|
||||||
|
|
||||||
/// method that tells us if the mouse event landed on a
|
/// method that tells us if the mouse event landed on a
|
||||||
/// time-slider that allows us to time shift the sequence.
|
/// time-slider that allows us to time shift the sequence.
|
||||||
bool TrackPanel::HitTestSlide(Track * WXUNUSED(track), const wxRect &rect, const wxMouseEvent & event)
|
bool TrackPanel::HitTestSlide(Track * WXUNUSED(track), const wxRect &rect, const wxMouseEvent & event)
|
||||||
|
@ -398,7 +398,6 @@ class AUDACITY_DLL_API TrackPanel final : public OverlayPanel {
|
|||||||
// Working out where to dispatch the event to.
|
// Working out where to dispatch the event to.
|
||||||
virtual int DetermineToolToUse( ToolsToolBar * pTtb, const wxMouseEvent & event);
|
virtual int DetermineToolToUse( ToolsToolBar * pTtb, const wxMouseEvent & event);
|
||||||
virtual bool HitTestEnvelope(Track *track, const wxRect &rect, const wxMouseEvent & event);
|
virtual bool HitTestEnvelope(Track *track, const wxRect &rect, const wxMouseEvent & event);
|
||||||
virtual bool HitTestSamples(Track *track, const wxRect &rect, const wxMouseEvent & event);
|
|
||||||
virtual bool HitTestSlide(Track *track, const wxRect &rect, const wxMouseEvent & event);
|
virtual bool HitTestSlide(Track *track, const wxRect &rect, const wxMouseEvent & event);
|
||||||
#ifdef USE_MIDI
|
#ifdef USE_MIDI
|
||||||
// data for NoteTrack interactive stretch operations:
|
// data for NoteTrack interactive stretch operations:
|
||||||
@ -529,14 +528,6 @@ protected:
|
|||||||
WaveTrack *track, bool shiftDown, bool rightUp,
|
WaveTrack *track, bool shiftDown, bool rightUp,
|
||||||
bool fixedMousePoint);
|
bool fixedMousePoint);
|
||||||
|
|
||||||
// Handle sample editing using the 'draw' tool.
|
|
||||||
virtual bool IsSampleEditingPossible( wxMouseEvent & event, const WaveTrack * t );
|
|
||||||
virtual void HandleSampleEditing(wxMouseEvent & event);
|
|
||||||
float FindSampleEditingLevel(wxMouseEvent &event, double dBRange, double t0);
|
|
||||||
virtual void HandleSampleEditingClick( wxMouseEvent & event );
|
|
||||||
virtual void HandleSampleEditingDrag( wxMouseEvent & event );
|
|
||||||
virtual void HandleSampleEditingButtonUp( wxMouseEvent & event );
|
|
||||||
|
|
||||||
// MM: Handle mouse wheel rotation
|
// MM: Handle mouse wheel rotation
|
||||||
virtual void HandleWheelRotation(wxMouseEvent & event);
|
virtual void HandleWheelRotation(wxMouseEvent & event);
|
||||||
virtual void HandleWheelRotationInVRuler
|
virtual void HandleWheelRotationInVRuler
|
||||||
@ -823,12 +814,6 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
WaveTrack * mDrawingTrack; // Keeps track of which track you are drawing on between events cf. HandleDraw()
|
|
||||||
int mDrawingTrackTop; // Keeps track of the top position of the drawing track.
|
|
||||||
sampleCount mDrawingStartSample; // sample of last click-down
|
|
||||||
sampleCount mDrawingLastDragSample; // sample of last drag-over
|
|
||||||
float mDrawingLastDragSampleValue; // value of last drag-over
|
|
||||||
|
|
||||||
#ifdef EXPERIMENTAL_SPECTRAL_EDITING
|
#ifdef EXPERIMENTAL_SPECTRAL_EDITING
|
||||||
void HandleCenterFrequencyCursor
|
void HandleCenterFrequencyCursor
|
||||||
(bool shiftDown, wxString &tip, const wxCursor ** ppCursor);
|
(bool shiftDown, wxString &tip, const wxCursor ** ppCursor);
|
||||||
@ -880,7 +865,6 @@ public:
|
|||||||
IsSelecting,
|
IsSelecting,
|
||||||
IsAdjustingLabel,
|
IsAdjustingLabel,
|
||||||
IsSelectingLabelText,
|
IsSelectingLabelText,
|
||||||
IsAdjustingSample,
|
|
||||||
IsResizing,
|
IsResizing,
|
||||||
IsResizingBetweenLinkedTracks,
|
IsResizingBetweenLinkedTracks,
|
||||||
IsResizingBelowLinkedTracks,
|
IsResizingBelowLinkedTracks,
|
||||||
@ -913,10 +897,10 @@ protected:
|
|||||||
int mRearrangeCount;
|
int mRearrangeCount;
|
||||||
|
|
||||||
std::unique_ptr<wxCursor>
|
std::unique_ptr<wxCursor>
|
||||||
mArrowCursor, mPencilCursor, mSelectCursor,
|
mArrowCursor, mSelectCursor,
|
||||||
mResizeCursor, mSlideCursor, mEnvelopeCursor, // doubles as the center frequency cursor
|
mResizeCursor, mSlideCursor, mEnvelopeCursor, // doubles as the center frequency cursor
|
||||||
// for spectral selection
|
// for spectral selection
|
||||||
mSmoothCursor, mZoomInCursor, mZoomOutCursor,
|
mZoomInCursor, mZoomOutCursor,
|
||||||
mRearrangeCursor,
|
mRearrangeCursor,
|
||||||
mDisabledCursor, mAdjustLeftSelectionCursor, mAdjustRightSelectionCursor;
|
mDisabledCursor, mAdjustLeftSelectionCursor, mAdjustRightSelectionCursor;
|
||||||
#ifdef EXPERIMENTAL_SPECTRAL_EDITING
|
#ifdef EXPERIMENTAL_SPECTRAL_EDITING
|
||||||
@ -1026,10 +1010,5 @@ enum : int {
|
|||||||
// for vertical selection adjusting)
|
// for vertical selection adjusting)
|
||||||
#define SELECTION_RESIZE_REGION 3
|
#define SELECTION_RESIZE_REGION 3
|
||||||
|
|
||||||
#define SMOOTHING_KERNEL_RADIUS 3
|
|
||||||
#define SMOOTHING_BRUSH_RADIUS 5
|
|
||||||
#define SMOOTHING_PROPORTION_MAX 0.7
|
|
||||||
#define SMOOTHING_PROPORTION_MIN 0.0
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -88,6 +88,9 @@ ToolsToolBar::ToolsToolBar()
|
|||||||
mMessageOfTool[selectTool] = _("Click and drag to select audio");
|
mMessageOfTool[selectTool] = _("Click and drag to select audio");
|
||||||
|
|
||||||
mMessageOfTool[envelopeTool] = _("Click and drag to edit the amplitude envelope");
|
mMessageOfTool[envelopeTool] = _("Click and drag to edit the amplitude envelope");
|
||||||
|
|
||||||
|
// TODO: message should also mention the brush. Describing the modifier key
|
||||||
|
// (alt, or other) varies with operating system.
|
||||||
mMessageOfTool[drawTool] = _("Click and drag to edit the samples");
|
mMessageOfTool[drawTool] = _("Click and drag to edit the samples");
|
||||||
|
|
||||||
// TODO: Why not mention middle click to zoom normal on Windows too?
|
// TODO: Why not mention middle click to zoom normal on Windows too?
|
||||||
|
483
src/tracks/playabletrack/wavetrack/ui/SampleHandle.cpp
Normal file
483
src/tracks/playabletrack/wavetrack/ui/SampleHandle.cpp
Normal file
@ -0,0 +1,483 @@
|
|||||||
|
/**********************************************************************
|
||||||
|
|
||||||
|
Audacity: A Digital Audio Editor
|
||||||
|
|
||||||
|
SampleHandle.cpp
|
||||||
|
|
||||||
|
Paul Licameli split from TrackPanel.cpp
|
||||||
|
|
||||||
|
**********************************************************************/
|
||||||
|
|
||||||
|
#include "../../../../Audacity.h"
|
||||||
|
#include "SampleHandle.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include "../../../../MemoryX.h"
|
||||||
|
#include <wx/gdicmn.h>
|
||||||
|
|
||||||
|
#include "../../../../Envelope.h"
|
||||||
|
#include "../../../../HitTestResult.h"
|
||||||
|
#include "../../../../prefs/WaveformSettings.h"
|
||||||
|
#include "../../../../Project.h"
|
||||||
|
#include "../../../../RefreshCode.h"
|
||||||
|
#include "../../../../toolbars/ToolsToolBar.h"
|
||||||
|
#include "../../../../TrackArtist.h"
|
||||||
|
#include "../../../../TrackPanelMouseEvent.h"
|
||||||
|
#include "../../../../UndoManager.h"
|
||||||
|
#include "../../../../ViewInfo.h"
|
||||||
|
#include "../../../../WaveTrack.h"
|
||||||
|
#include "../../../../../images/Cursors.h"
|
||||||
|
|
||||||
|
|
||||||
|
static const int SMOOTHING_KERNEL_RADIUS = 3;
|
||||||
|
static const int SMOOTHING_BRUSH_RADIUS = 5;
|
||||||
|
static const double SMOOTHING_PROPORTION_MAX = 0.7;
|
||||||
|
static const double SMOOTHING_PROPORTION_MIN = 0.0;
|
||||||
|
|
||||||
|
SampleHandle::SampleHandle()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SampleHandle &SampleHandle::Instance()
|
||||||
|
{
|
||||||
|
static SampleHandle instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
HitTestPreview SampleHandle::HitPreview
|
||||||
|
(const wxMouseEvent &event, const AudacityProject *pProject, bool unsafe)
|
||||||
|
{
|
||||||
|
static auto disabledCursor =
|
||||||
|
::MakeCursor(wxCURSOR_NO_ENTRY, DisabledCursorXpm, 16, 16);
|
||||||
|
static wxCursor smoothCursor{ wxCURSOR_SPRAYCAN };
|
||||||
|
static auto pencilCursor =
|
||||||
|
::MakeCursor(wxCURSOR_PENCIL, DrawCursorXpm, 12, 22);
|
||||||
|
const ToolsToolBar *const ttb = pProject->GetToolsToolBar();
|
||||||
|
return {
|
||||||
|
ttb->GetMessageForTool(drawTool),
|
||||||
|
(unsafe
|
||||||
|
? &*disabledCursor
|
||||||
|
: (event.AltDown()
|
||||||
|
? &smoothCursor
|
||||||
|
: &*pencilCursor))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
HitTestResult SampleHandle::HitAnywhere
|
||||||
|
(const wxMouseEvent &event, const AudacityProject *pProject)
|
||||||
|
{
|
||||||
|
const bool unsafe = pProject->IsAudioActive();
|
||||||
|
return {
|
||||||
|
HitPreview(event, pProject, unsafe),
|
||||||
|
(unsafe
|
||||||
|
? NULL
|
||||||
|
: &Instance())
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
inline double adjustTime(const WaveTrack *wt, double time)
|
||||||
|
{
|
||||||
|
// Round to an exact sample time
|
||||||
|
return wt->LongSamplesToTime(wt->TimeToLongSamples(time));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is the sample horizontally nearest to the cursor sufficiently separated
|
||||||
|
// from its neighbors that the pencil tool should be allowed to drag it?
|
||||||
|
bool SampleResolutionTest
|
||||||
|
( const ViewInfo &viewInfo, const WaveTrack *wt, double time, int width )
|
||||||
|
{
|
||||||
|
// Require more than 3 pixels per sample
|
||||||
|
const wxInt64 xx = std::max(wxInt64(0), viewInfo.TimeToPosition(time));
|
||||||
|
ZoomInfo::Intervals intervals;
|
||||||
|
const double rate = wt->GetRate();
|
||||||
|
viewInfo.FindIntervals(rate, intervals, width);
|
||||||
|
ZoomInfo::Intervals::const_iterator it = intervals.begin(),
|
||||||
|
end = intervals.end(), prev;
|
||||||
|
wxASSERT(it != end && it->position == 0);
|
||||||
|
do
|
||||||
|
prev = it++;
|
||||||
|
while (it != end && it->position <= xx);
|
||||||
|
const double threshold = 3 * rate;
|
||||||
|
// three times as many pixels per second, as samples
|
||||||
|
return prev->averageZoom > threshold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HitTestResult SampleHandle::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 sample
|
||||||
|
if (pTrack->GetKind() != Track::Wave)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
WaveTrack *wavetrack = static_cast<WaveTrack*>(pTrack);
|
||||||
|
|
||||||
|
const int displayType = wavetrack->GetDisplay();
|
||||||
|
if (WaveTrack::Waveform != displayType)
|
||||||
|
return {}; // Not a wave, so return.
|
||||||
|
|
||||||
|
const double tt =
|
||||||
|
adjustTime(wavetrack, viewInfo.PositionToTime(event.m_x, rect.x));
|
||||||
|
if (!SampleResolutionTest(viewInfo, wavetrack, tt, rect.width))
|
||||||
|
return {};
|
||||||
|
|
||||||
|
// Just get one sample.
|
||||||
|
float oneSample;
|
||||||
|
const double rate = wavetrack->GetRate();
|
||||||
|
const auto s0 = (sampleCount)(tt * rate + 0.5);
|
||||||
|
if (! wavetrack->Get((samplePtr)&oneSample, floatSample, s0, 1, fillZero,
|
||||||
|
// Do not propagate exception but return a failure value
|
||||||
|
false) )
|
||||||
|
return {};
|
||||||
|
|
||||||
|
// Get y distance of envelope point from center line (in pixels).
|
||||||
|
float zoomMin, zoomMax;
|
||||||
|
|
||||||
|
wavetrack->GetDisplayBounds(&zoomMin, &zoomMax);
|
||||||
|
|
||||||
|
double envValue = 1.0;
|
||||||
|
Envelope* env = wavetrack->GetEnvelopeAtX(event.GetX());
|
||||||
|
if (env)
|
||||||
|
// Calculate sample as it would be rendered, so quantize time
|
||||||
|
envValue = env->GetValue( tt, 1.0 / wavetrack->GetRate() );
|
||||||
|
|
||||||
|
const bool dB = !wavetrack->GetWaveformSettings().isLinear();
|
||||||
|
int yValue = GetWaveYPos(oneSample * envValue,
|
||||||
|
zoomMin, zoomMax,
|
||||||
|
rect.height, dB, true,
|
||||||
|
wavetrack->GetWaveformSettings().dBRange, false) + rect.y;
|
||||||
|
|
||||||
|
// Get y position of mouse (in pixels)
|
||||||
|
int yMouse = event.m_y;
|
||||||
|
|
||||||
|
// Perhaps yTolerance should be put into preferences?
|
||||||
|
const int yTolerance = 10; // More tolerance on samples than on envelope.
|
||||||
|
if (abs(yValue - yMouse) >= yTolerance)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return HitAnywhere(event, pProject);
|
||||||
|
}
|
||||||
|
|
||||||
|
SampleHandle::~SampleHandle()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
/// Determines if we can edit samples in a wave track.
|
||||||
|
/// Also pops up warning messages in certain cases where we can't.
|
||||||
|
/// @return true if we can edit the samples, false otherwise.
|
||||||
|
bool IsSampleEditingPossible
|
||||||
|
(const wxMouseEvent &event,
|
||||||
|
const wxRect &rect, const ViewInfo &viewInfo, Track *pTrack, int width)
|
||||||
|
{
|
||||||
|
if (pTrack->GetKind() != Track::Wave)
|
||||||
|
return false;
|
||||||
|
WaveTrack *wt = static_cast<WaveTrack*>(pTrack);
|
||||||
|
|
||||||
|
//Get out of here if we shouldn't be drawing right now:
|
||||||
|
//If we aren't displaying the waveform, Display a message dialog
|
||||||
|
const int display = wt->GetDisplay();
|
||||||
|
if (WaveTrack::Waveform != display)
|
||||||
|
{
|
||||||
|
wxMessageBox(_(
|
||||||
|
"To use Draw, choose 'Waveform' or 'Waveform (dB)' in the Track Dropdown Menu."),
|
||||||
|
_("Draw Tool"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//If we aren't zoomed in far enough, show a message dialog.
|
||||||
|
const double time = adjustTime(wt, viewInfo.PositionToTime(event.m_x, rect.x));
|
||||||
|
if (!SampleResolutionTest(viewInfo, wt, time, width))
|
||||||
|
{
|
||||||
|
wxMessageBox(_(
|
||||||
|
"To use Draw, zoom in further until you can see the individual samples."),
|
||||||
|
_("Draw Tool"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UIHandle::Result SampleHandle::Click
|
||||||
|
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
|
||||||
|
{
|
||||||
|
const wxMouseEvent &event = evt.event;
|
||||||
|
const wxRect &rect = evt.rect;
|
||||||
|
const ViewInfo &viewInfo = pProject->GetViewInfo();
|
||||||
|
Track *const pTrack = static_cast<Track*>(evt.pCell);
|
||||||
|
|
||||||
|
using namespace RefreshCode;
|
||||||
|
|
||||||
|
/// Someone has just clicked the mouse. What do we do?
|
||||||
|
const bool unsafe = pProject->IsAudioActive();
|
||||||
|
if (unsafe)
|
||||||
|
return Cancelled;
|
||||||
|
if (!IsSampleEditingPossible
|
||||||
|
(event, rect, viewInfo, pTrack, rect.width))
|
||||||
|
return Cancelled;
|
||||||
|
|
||||||
|
/// We're in a track view and zoomed enough to see the samples.
|
||||||
|
mClickedTrack = static_cast<WaveTrack*>(pTrack);
|
||||||
|
mRect = rect;
|
||||||
|
|
||||||
|
//If we are still around, we are drawing in earnest. Set some member data structures up:
|
||||||
|
//First, calculate the starting sample. To get this, we need the time
|
||||||
|
const double t0 =
|
||||||
|
adjustTime(mClickedTrack, viewInfo.PositionToTime(event.m_x, rect.x));
|
||||||
|
|
||||||
|
//convert t0 to samples
|
||||||
|
mClickedStartSample = mClickedTrack->TimeToLongSamples(t0);
|
||||||
|
|
||||||
|
//Determine how drawing should occur. If alt is down,
|
||||||
|
//do a smoothing, instead of redrawing.
|
||||||
|
if (event.m_altDown)
|
||||||
|
{
|
||||||
|
mAltKey = true;
|
||||||
|
//*************************************************
|
||||||
|
//*** ALT-DOWN-CLICK (SAMPLE SMOOTHING) ***
|
||||||
|
//*************************************************
|
||||||
|
//
|
||||||
|
// Smoothing works like this: There is a smoothing kernel radius constant that
|
||||||
|
// determines how wide the averaging window is. Plus, there is a smoothing brush radius,
|
||||||
|
// which determines how many pixels wide around the selected pixel this smoothing is applied.
|
||||||
|
//
|
||||||
|
// Samples will be replaced by a mixture of the original points and the smoothed points,
|
||||||
|
// with a triangular mixing probability whose value at the center point is
|
||||||
|
// SMOOTHING_PROPORTION_MAX and at the far bounds is SMOOTHING_PROPORTION_MIN
|
||||||
|
|
||||||
|
//Get the region of samples around the selected point
|
||||||
|
size_t sampleRegionSize = 1 + 2 * (SMOOTHING_KERNEL_RADIUS + SMOOTHING_BRUSH_RADIUS);
|
||||||
|
Floats sampleRegion{ sampleRegionSize };
|
||||||
|
Floats newSampleRegion{ 1 + 2 * (size_t)SMOOTHING_BRUSH_RADIUS };
|
||||||
|
|
||||||
|
//Get a sample from the track to do some tricks on.
|
||||||
|
mClickedTrack->Get((samplePtr)sampleRegion.get(), floatSample,
|
||||||
|
mClickedStartSample - SMOOTHING_KERNEL_RADIUS - SMOOTHING_BRUSH_RADIUS,
|
||||||
|
sampleRegionSize);
|
||||||
|
|
||||||
|
//Go through each point of the smoothing brush and apply a smoothing operation.
|
||||||
|
for (auto jj = -SMOOTHING_BRUSH_RADIUS; jj <= SMOOTHING_BRUSH_RADIUS; ++jj) {
|
||||||
|
float sumOfSamples = 0;
|
||||||
|
for (auto ii = -SMOOTHING_KERNEL_RADIUS; ii <= SMOOTHING_KERNEL_RADIUS; ++ii) {
|
||||||
|
//Go through each point of the smoothing kernel and find the average
|
||||||
|
|
||||||
|
//The average is a weighted average, scaled by a weighting kernel that is simply triangular
|
||||||
|
// A triangular kernel across N items, with a radius of R ( 2 R + 1 points), if the farthest:
|
||||||
|
// points have a probability of a, the entire triangle has total probability of (R + 1)^2.
|
||||||
|
// For sample number ii and middle brush sample M, (R + 1 - abs(M-ii))/ ((R+1)^2) gives a
|
||||||
|
// legal distribution whose total probability is 1.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// weighting factor value
|
||||||
|
sumOfSamples +=
|
||||||
|
(SMOOTHING_KERNEL_RADIUS + 1 - abs(ii)) *
|
||||||
|
sampleRegion[ii + jj + SMOOTHING_KERNEL_RADIUS + SMOOTHING_BRUSH_RADIUS];
|
||||||
|
|
||||||
|
}
|
||||||
|
newSampleRegion[jj + SMOOTHING_BRUSH_RADIUS] =
|
||||||
|
sumOfSamples /
|
||||||
|
((SMOOTHING_KERNEL_RADIUS + 1) *(SMOOTHING_KERNEL_RADIUS + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Now that the NEW sample levels are determined, go through each and mix it appropriately
|
||||||
|
// with the original point, according to a 2-part linear function whose center has probability
|
||||||
|
// SMOOTHING_PROPORTION_MAX and extends out SMOOTHING_BRUSH_RADIUS, at which the probability is
|
||||||
|
// SMOOTHING_PROPORTION_MIN. _MIN and _MAX specify how much of the smoothed curve make it through.
|
||||||
|
|
||||||
|
float prob;
|
||||||
|
|
||||||
|
for (auto jj = -SMOOTHING_BRUSH_RADIUS; jj <= SMOOTHING_BRUSH_RADIUS; ++jj) {
|
||||||
|
|
||||||
|
prob =
|
||||||
|
SMOOTHING_PROPORTION_MAX -
|
||||||
|
(float)abs(jj) / SMOOTHING_BRUSH_RADIUS *
|
||||||
|
(SMOOTHING_PROPORTION_MAX - SMOOTHING_PROPORTION_MIN);
|
||||||
|
|
||||||
|
newSampleRegion[jj + SMOOTHING_BRUSH_RADIUS] =
|
||||||
|
newSampleRegion[jj + SMOOTHING_BRUSH_RADIUS] * prob +
|
||||||
|
sampleRegion[SMOOTHING_BRUSH_RADIUS + SMOOTHING_KERNEL_RADIUS + jj] *
|
||||||
|
(1 - prob);
|
||||||
|
}
|
||||||
|
//Set the sample to the point of the mouse event
|
||||||
|
mClickedTrack->Set((samplePtr)newSampleRegion.get(), floatSample,
|
||||||
|
mClickedStartSample - SMOOTHING_BRUSH_RADIUS, 1 + 2 * SMOOTHING_BRUSH_RADIUS);
|
||||||
|
|
||||||
|
// mLastDragSampleValue will not be used
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mAltKey = false;
|
||||||
|
//*************************************************
|
||||||
|
//*** PLAIN DOWN-CLICK (NORMAL DRAWING) ***
|
||||||
|
//*************************************************
|
||||||
|
|
||||||
|
//Otherwise (e.g., the alt button is not down) do normal redrawing, based on the mouse position.
|
||||||
|
const float newLevel = FindSampleEditingLevel(event, viewInfo, t0);
|
||||||
|
|
||||||
|
//Set the sample to the point of the mouse event
|
||||||
|
mClickedTrack->Set((samplePtr)&newLevel, floatSample, mClickedStartSample, 1);
|
||||||
|
|
||||||
|
mLastDragSampleValue = newLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set the member data structures for drawing
|
||||||
|
mLastDragSample = mClickedStartSample;
|
||||||
|
|
||||||
|
// Sample data changed on either branch, so refresh the track display.
|
||||||
|
return RefreshCell;
|
||||||
|
}
|
||||||
|
|
||||||
|
UIHandle::Result SampleHandle::Drag
|
||||||
|
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
|
||||||
|
{
|
||||||
|
using namespace RefreshCode;
|
||||||
|
const wxMouseEvent &event = evt.event;
|
||||||
|
const ViewInfo &viewInfo = pProject->GetViewInfo();
|
||||||
|
|
||||||
|
const bool unsafe = pProject->IsAudioActive();
|
||||||
|
if (unsafe) {
|
||||||
|
this->Cancel(pProject);
|
||||||
|
return RefreshCell | Cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************
|
||||||
|
//*** DRAG-DRAWING ***
|
||||||
|
//*************************************************
|
||||||
|
|
||||||
|
//No dragging effects if the alt key is down--
|
||||||
|
//Don't allow left-right dragging for smoothing operation
|
||||||
|
if (mAltKey)
|
||||||
|
return RefreshNone;
|
||||||
|
|
||||||
|
sampleCount s0; //declare this for use below. It designates which sample number to draw.
|
||||||
|
|
||||||
|
// Figure out what time the click was at
|
||||||
|
//Find the point that we want to redraw at. If the control button is down,
|
||||||
|
//adjust only the originally clicked-on sample
|
||||||
|
|
||||||
|
if (event.m_controlDown) {
|
||||||
|
//*************************************************
|
||||||
|
//*** CTRL-DOWN (Hold Initial Sample Constant ***
|
||||||
|
//*************************************************
|
||||||
|
|
||||||
|
s0 = mClickedStartSample;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//*************************************************
|
||||||
|
//*** Normal CLICK-drag (Normal drawing) ***
|
||||||
|
//*************************************************
|
||||||
|
|
||||||
|
//Otherwise, adjust the sample you are dragging over right now.
|
||||||
|
//convert this to samples
|
||||||
|
const double tt = viewInfo.PositionToTime(event.m_x, mRect.x);
|
||||||
|
s0 = mClickedTrack->TimeToLongSamples(tt);
|
||||||
|
}
|
||||||
|
|
||||||
|
const double t0 = mClickedTrack->LongSamplesToTime(s0);
|
||||||
|
|
||||||
|
// Do redrawing, based on the mouse position.
|
||||||
|
// Calculate where the mouse is located vertically (between +/- 1)
|
||||||
|
|
||||||
|
const float newLevel = FindSampleEditingLevel(event, viewInfo, t0);
|
||||||
|
|
||||||
|
//Now, redraw all samples between current and last redrawn sample, inclusive
|
||||||
|
//Go from the smaller to larger sample.
|
||||||
|
const auto start = std::min(s0, mLastDragSample);
|
||||||
|
const auto end = std::max(s0, mLastDragSample);
|
||||||
|
// Few enough samples to be drawn individually on screen will not
|
||||||
|
// overflow size_t:
|
||||||
|
const auto size = ( end - start + 1 ).as_size_t();
|
||||||
|
if (size == 1) {
|
||||||
|
mClickedTrack->Set((samplePtr)&newLevel, floatSample, start, size);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::vector<float> values(size);
|
||||||
|
for (auto ii = start; ii <= end; ++ii) {
|
||||||
|
//This interpolates each sample linearly:
|
||||||
|
// i - start will not overflow size_t either:
|
||||||
|
values[( ii - start ).as_size_t()] =
|
||||||
|
mLastDragSampleValue + (newLevel - mLastDragSampleValue) *
|
||||||
|
(ii - mLastDragSample).as_float() /
|
||||||
|
(s0 - mLastDragSample).as_float();
|
||||||
|
}
|
||||||
|
mClickedTrack->Set((samplePtr)&values[0], floatSample, start, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Update the member data structures.
|
||||||
|
mLastDragSample = s0;
|
||||||
|
mLastDragSampleValue = newLevel;
|
||||||
|
|
||||||
|
return RefreshCell;
|
||||||
|
}
|
||||||
|
|
||||||
|
HitTestPreview SampleHandle::Preview
|
||||||
|
(const TrackPanelMouseEvent &evt, const AudacityProject *pProject)
|
||||||
|
{
|
||||||
|
return HitPreview(evt.event, pProject, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
UIHandle::Result SampleHandle::Release
|
||||||
|
(const TrackPanelMouseEvent &, AudacityProject *pProject,
|
||||||
|
wxWindow *)
|
||||||
|
{
|
||||||
|
const bool unsafe = pProject->IsAudioActive();
|
||||||
|
if (unsafe)
|
||||||
|
return this->Cancel(pProject);
|
||||||
|
|
||||||
|
//*************************************************
|
||||||
|
//*** UP-CLICK (Finish drawing) ***
|
||||||
|
//*************************************************
|
||||||
|
//On up-click, send the state to the undo stack
|
||||||
|
mClickedTrack = nullptr; //Set this to NULL so it will catch improper drag events.
|
||||||
|
pProject->PushState(_("Moved Samples"),
|
||||||
|
_("Sample Edit"),
|
||||||
|
UndoPush::CONSOLIDATE | UndoPush::AUTOSAVE);
|
||||||
|
|
||||||
|
// No change to draw since last drag
|
||||||
|
return RefreshCode::RefreshNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
UIHandle::Result SampleHandle::Cancel(AudacityProject *pProject)
|
||||||
|
{
|
||||||
|
pProject->RollbackState();
|
||||||
|
mClickedTrack = nullptr;
|
||||||
|
return RefreshCode::RefreshCell;
|
||||||
|
}
|
||||||
|
|
||||||
|
float SampleHandle::FindSampleEditingLevel
|
||||||
|
(const wxMouseEvent &event, const ViewInfo &, double t0)
|
||||||
|
{
|
||||||
|
// Calculate where the mouse is located vertically (between +/- 1)
|
||||||
|
float zoomMin, zoomMax;
|
||||||
|
mClickedTrack->GetDisplayBounds(&zoomMin, &zoomMax);
|
||||||
|
|
||||||
|
const int yy = event.m_y - mRect.y;
|
||||||
|
const int height = mRect.GetHeight();
|
||||||
|
const bool dB = !mClickedTrack->GetWaveformSettings().isLinear();
|
||||||
|
float newLevel =
|
||||||
|
::ValueOfPixel(yy, height, false, dB,
|
||||||
|
mClickedTrack->GetWaveformSettings().dBRange, zoomMin, zoomMax);
|
||||||
|
|
||||||
|
//Take the envelope into account
|
||||||
|
Envelope *const env = mClickedTrack->GetEnvelopeAtX(event.m_x);
|
||||||
|
if (env)
|
||||||
|
{
|
||||||
|
// Calculate sample as it would be rendered, so quantize time
|
||||||
|
double envValue = env->GetValue( t0, 1.0 / mClickedTrack->GetRate());
|
||||||
|
if (envValue > 0)
|
||||||
|
newLevel /= envValue;
|
||||||
|
else
|
||||||
|
newLevel = 0;
|
||||||
|
|
||||||
|
//Make sure the NEW level is between +/-1
|
||||||
|
newLevel = std::max(-1.0f, std::min(1.0f, newLevel));
|
||||||
|
}
|
||||||
|
|
||||||
|
return newLevel;
|
||||||
|
}
|
74
src/tracks/playabletrack/wavetrack/ui/SampleHandle.h
Normal file
74
src/tracks/playabletrack/wavetrack/ui/SampleHandle.h
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
/**********************************************************************
|
||||||
|
|
||||||
|
Audacity: A Digital Audio Editor
|
||||||
|
|
||||||
|
SampleHandle.h
|
||||||
|
|
||||||
|
Paul Licameli
|
||||||
|
|
||||||
|
**********************************************************************/
|
||||||
|
|
||||||
|
#ifndef __AUDACITY_SAMPLE_HANDLE__
|
||||||
|
#define __AUDACITY_SAMPLE_HANDLE__
|
||||||
|
|
||||||
|
#include "../../../../UIHandle.h"
|
||||||
|
#include "audacity/Types.h"
|
||||||
|
|
||||||
|
class wxMouseEvent;
|
||||||
|
#include <wx/gdicmn.h>
|
||||||
|
|
||||||
|
struct HitTestResult;
|
||||||
|
class Track;
|
||||||
|
class ViewInfo;
|
||||||
|
class WaveTrack;
|
||||||
|
|
||||||
|
class SampleHandle final : public UIHandle
|
||||||
|
{
|
||||||
|
SampleHandle();
|
||||||
|
SampleHandle(const SampleHandle&) = delete;
|
||||||
|
SampleHandle &operator=(const SampleHandle&) = delete;
|
||||||
|
static SampleHandle& Instance();
|
||||||
|
static HitTestPreview HitPreview
|
||||||
|
(const wxMouseEvent &event, const AudacityProject *pProject, bool unsafe);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static HitTestResult HitAnywhere
|
||||||
|
(const wxMouseEvent &event, const AudacityProject *pProject);
|
||||||
|
static HitTestResult HitTest
|
||||||
|
(const wxMouseEvent &event, const wxRect &rect,
|
||||||
|
const AudacityProject *pProject, Track *pTrack);
|
||||||
|
|
||||||
|
virtual ~SampleHandle();
|
||||||
|
|
||||||
|
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:
|
||||||
|
float FindSampleEditingLevel
|
||||||
|
(const wxMouseEvent &event, const ViewInfo &viewInfo, double t0);
|
||||||
|
|
||||||
|
WaveTrack *mClickedTrack{};
|
||||||
|
wxRect mRect{};
|
||||||
|
|
||||||
|
sampleCount mClickedStartSample{};
|
||||||
|
sampleCount mLastDragSample{};
|
||||||
|
float mLastDragSampleValue{};
|
||||||
|
bool mAltKey{};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -13,12 +13,28 @@ Paul Licameli split from TrackPanel.cpp
|
|||||||
#include "WaveTrackVRulerControls.h"
|
#include "WaveTrackVRulerControls.h"
|
||||||
|
|
||||||
#include "../../../../HitTestResult.h"
|
#include "../../../../HitTestResult.h"
|
||||||
|
#include "../../../../Project.h"
|
||||||
|
#include "../../../../TrackPanelMouseEvent.h"
|
||||||
|
#include "../../../../toolbars/ToolsToolBar.h"
|
||||||
|
|
||||||
|
#include "SampleHandle.h"
|
||||||
|
|
||||||
HitTestResult WaveTrack::HitTest
|
HitTestResult WaveTrack::HitTest
|
||||||
(const TrackPanelMouseEvent &event,
|
(const TrackPanelMouseEvent &event,
|
||||||
const AudacityProject *pProject)
|
const AudacityProject *pProject)
|
||||||
{
|
{
|
||||||
return Track::HitTest(event, pProject);
|
HitTestResult result = Track::HitTest(event, pProject);
|
||||||
|
if (result.preview.cursor)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
const ToolsToolBar *const pTtb = pProject->GetToolsToolBar();
|
||||||
|
if (pTtb->IsDown(multiTool)) {
|
||||||
|
if (NULL != (result =
|
||||||
|
SampleHandle::HitTest(event.event, event.rect, pProject, this)).preview.cursor)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackControls *WaveTrack::GetControls()
|
TrackControls *WaveTrack::GetControls()
|
||||||
|
@ -17,6 +17,7 @@ Paul Licameli split from TrackPanel.cpp
|
|||||||
#include "../../Project.h"
|
#include "../../Project.h"
|
||||||
#include "../../toolbars/ToolsToolBar.h"
|
#include "../../toolbars/ToolsToolBar.h"
|
||||||
|
|
||||||
|
#include "../playabletrack/wavetrack/ui/SampleHandle.h"
|
||||||
#include "ZoomHandle.h"
|
#include "ZoomHandle.h"
|
||||||
|
|
||||||
HitTestResult Track::HitTest
|
HitTestResult Track::HitTest
|
||||||
@ -28,12 +29,13 @@ HitTestResult Track::HitTest
|
|||||||
const bool isMultiTool = pTtb->IsDown(multiTool);
|
const bool isMultiTool = pTtb->IsDown(multiTool);
|
||||||
if (!isMultiTool) {
|
if (!isMultiTool) {
|
||||||
switch (pTtb->GetCurrentTool()) {
|
switch (pTtb->GetCurrentTool()) {
|
||||||
|
case drawTool:
|
||||||
|
return SampleHandle::HitAnywhere(event.event, pProject);
|
||||||
case zoomTool:
|
case zoomTool:
|
||||||
return ZoomHandle::HitAnywhere(event.event, pProject);
|
return ZoomHandle::HitAnywhere(event.event, pProject);
|
||||||
|
|
||||||
case selectTool:
|
case selectTool:
|
||||||
case envelopeTool:
|
case envelopeTool:
|
||||||
case drawTool:
|
|
||||||
case slideTool:
|
case slideTool:
|
||||||
default:
|
default:
|
||||||
// cases not yet implemented
|
// cases not yet implemented
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
@ -230,6 +230,7 @@
|
|||||||
<ClCompile Include="..\..\..\src\tracks\playabletrack\notetrack\ui\NoteTrackControls.cpp" />
|
<ClCompile Include="..\..\..\src\tracks\playabletrack\notetrack\ui\NoteTrackControls.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\tracks\playabletrack\notetrack\ui\NoteTrackUI.cpp" />
|
<ClCompile Include="..\..\..\src\tracks\playabletrack\notetrack\ui\NoteTrackUI.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\tracks\playabletrack\notetrack\ui\NoteTrackVRulerControls.cpp" />
|
<ClCompile Include="..\..\..\src\tracks\playabletrack\notetrack\ui\NoteTrackVRulerControls.cpp" />
|
||||||
|
<ClCompile Include="..\..\..\src\tracks\playabletrack\wavetrack\ui\SampleHandle.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\tracks\playabletrack\wavetrack\ui\WaveTrackControls.cpp" />
|
<ClCompile Include="..\..\..\src\tracks\playabletrack\wavetrack\ui\WaveTrackControls.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\tracks\playabletrack\wavetrack\ui\WaveTrackUI.cpp" />
|
<ClCompile Include="..\..\..\src\tracks\playabletrack\wavetrack\ui\WaveTrackUI.cpp" />
|
||||||
<ClCompile Include="..\..\..\src\tracks\playabletrack\wavetrack\ui\WaveTrackVRulerControls.cpp" />
|
<ClCompile Include="..\..\..\src\tracks\playabletrack\wavetrack\ui\WaveTrackVRulerControls.cpp" />
|
||||||
@ -490,6 +491,7 @@
|
|||||||
<ClInclude Include="..\..\..\src\TrackPanelMouseEvent.h" />
|
<ClInclude Include="..\..\..\src\TrackPanelMouseEvent.h" />
|
||||||
<ClInclude Include="..\..\..\src\tracks\playabletrack\notetrack\ui\NoteTrackControls.h" />
|
<ClInclude Include="..\..\..\src\tracks\playabletrack\notetrack\ui\NoteTrackControls.h" />
|
||||||
<ClInclude Include="..\..\..\src\tracks\playabletrack\notetrack\ui\NoteTrackVRulerControls.h" />
|
<ClInclude Include="..\..\..\src\tracks\playabletrack\notetrack\ui\NoteTrackVRulerControls.h" />
|
||||||
|
<ClInclude Include="..\..\..\src\tracks\playabletrack\wavetrack\ui\SampleHandle.h" />
|
||||||
<ClInclude Include="..\..\..\src\tracks\playabletrack\wavetrack\ui\WaveTrackControls.h" />
|
<ClInclude Include="..\..\..\src\tracks\playabletrack\wavetrack\ui\WaveTrackControls.h" />
|
||||||
<ClInclude Include="..\..\..\src\tracks\playabletrack\wavetrack\ui\WaveTrackVRulerControls.h" />
|
<ClInclude Include="..\..\..\src\tracks\playabletrack\wavetrack\ui\WaveTrackVRulerControls.h" />
|
||||||
<ClInclude Include="..\..\..\src\tracks\ui\CommonTrackPanelCell.h" />
|
<ClInclude Include="..\..\..\src\tracks\ui\CommonTrackPanelCell.h" />
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="src">
|
<Filter Include="src">
|
||||||
@ -992,6 +992,9 @@
|
|||||||
<ClCompile Include="..\..\..\src\widgets\PopupMenuTable.cpp">
|
<ClCompile Include="..\..\..\src\widgets\PopupMenuTable.cpp">
|
||||||
<Filter>src\widgets</Filter>
|
<Filter>src\widgets</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\src\tracks\playabletrack\wavetrack\ui\SampleHandle.cpp">
|
||||||
|
<Filter>src\tracks\playabletrack\wavetrack\ui</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\..\src\AboutDialog.h">
|
<ClInclude Include="..\..\..\src\AboutDialog.h">
|
||||||
@ -1978,6 +1981,9 @@
|
|||||||
<ClInclude Include="..\..\..\src\widgets\PopupMenuTable.h">
|
<ClInclude Include="..\..\..\src\widgets\PopupMenuTable.h">
|
||||||
<Filter>src\widgets</Filter>
|
<Filter>src\widgets</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\src\tracks\playabletrack\wavetrack\ui\SampleHandle.h">
|
||||||
|
<Filter>src\tracks\playabletrack\wavetrack\ui</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Image Include="..\..\audacity.ico">
|
<Image Include="..\..\audacity.ico">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user