TrackPanel no longer implements clip joining or cutline expansion/deletion...
... also implement ESC key for these and added status bar message for mouse-over
This commit is contained in:
parent
2496b0d7bc
commit
43968c4ac9
|
@ -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 = "<group>"; };
|
||||
5E7396451DAFD8F200BA0A4D /* EnvelopeHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EnvelopeHandle.cpp; sourceTree = "<group>"; };
|
||||
5E7396461DAFD8F200BA0A4D /* EnvelopeHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EnvelopeHandle.h; sourceTree = "<group>"; };
|
||||
5E7396481DAFD91D00BA0A4D /* CutlineHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CutlineHandle.cpp; sourceTree = "<group>"; };
|
||||
5E7396491DAFD91D00BA0A4D /* CutlineHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CutlineHandle.h; 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>"; };
|
||||
5E07842C1DEE6B8600CA76EA /* FileException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileException.cpp; sourceTree = "<group>"; };
|
||||
|
@ -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 */,
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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<WaveTrack*>(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<WaveTrack*>(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<WaveTrack*>(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<WaveTrack*>(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 ||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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<WaveTrack*>(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<Track*>(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<WaveTrack*>(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*>(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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -230,6 +230,7 @@
|
|||
<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\NoteTrackVRulerControls.cpp" />
|
||||
<ClCompile Include="..\..\..\src\tracks\playabletrack\wavetrack\ui\CutlineHandle.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\WaveTrackUI.cpp" />
|
||||
|
@ -493,6 +494,7 @@
|
|||
<ClInclude Include="..\..\..\src\TrackPanelMouseEvent.h" />
|
||||
<ClInclude Include="..\..\..\src\tracks\playabletrack\notetrack\ui\NoteTrackControls.h" />
|
||||
<ClInclude Include="..\..\..\src\tracks\playabletrack\notetrack\ui\NoteTrackVRulerControls.h" />
|
||||
<ClInclude Include="..\..\..\src\tracks\playabletrack\wavetrack\ui\CutlineHandle.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\WaveTrackVRulerControls.h" />
|
||||
|
@ -1179,4 +1181,4 @@
|
|||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\ny.targets" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
|
@ -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">
|
||||
<ItemGroup>
|
||||
<Filter Include="src">
|
||||
|
@ -1001,6 +1001,9 @@
|
|||
<ClCompile Include="..\..\..\src\tracks\playabletrack\wavetrack\ui\SampleHandle.cpp">
|
||||
<Filter>src\tracks\playabletrack\wavetrack\ui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\tracks\playabletrack\wavetrack\ui\CutlineHandle.cpp">
|
||||
<Filter>src\tracks\playabletrack\wavetrack\ui</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\src\AboutDialog.h">
|
||||
|
@ -1996,6 +1999,9 @@
|
|||
<ClInclude Include="..\..\..\src\tracks\ui\EnvelopeHandle.h">
|
||||
<Filter>src\tracks\ui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\tracks\playabletrack\wavetrack\ui\CutlineHandle.h">
|
||||
<Filter>src\tracks\playabletrack\wavetrack\ui</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="..\..\audacity.ico">
|
||||
|
@ -2219,4 +2225,4 @@
|
|||
<Filter>plug-ins</Filter>
|
||||
</copy>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
Loading…
Reference in New Issue