mirror of
https://github.com/cookiengineer/audacity
synced 2025-08-01 00:19:27 +02:00
TrackPanel no longer implements track selection click or rearrange drag...
... also implement ESC key for the drag
This commit is contained in:
parent
46b97084eb
commit
703abe87bc
@ -1233,6 +1233,7 @@
|
||||
5E7396561DAFDA0000BA0A4D /* WaveTrackSliderHandles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E7396541DAFDA0000BA0A4D /* WaveTrackSliderHandles.cpp */; };
|
||||
5E7396591DAFDA3600BA0A4D /* TrackButtonHandles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E7396571DAFDA3600BA0A4D /* TrackButtonHandles.cpp */; };
|
||||
5E73965C1DAFDAA400BA0A4D /* BackgroundCell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E73965A1DAFDAA400BA0A4D /* BackgroundCell.cpp */; };
|
||||
5E73965F1DAFDAEC00BA0A4D /* TrackSelectHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E73965D1DAFDAEC00BA0A4D /* TrackSelectHandle.cpp */; };
|
||||
5E74D2E31CC4429700D88B0B /* EditCursorOverlay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E74D2DD1CC4429700D88B0B /* EditCursorOverlay.cpp */; };
|
||||
5E74D2E41CC4429700D88B0B /* PlayIndicatorOverlay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E74D2DF1CC4429700D88B0B /* PlayIndicatorOverlay.cpp */; };
|
||||
5E74D2E51CC4429700D88B0B /* Scrubbing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E74D2E11CC4429700D88B0B /* Scrubbing.cpp */; };
|
||||
@ -3070,6 +3071,8 @@
|
||||
5E7396581DAFDA3600BA0A4D /* TrackButtonHandles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackButtonHandles.h; sourceTree = "<group>"; };
|
||||
5E73965A1DAFDAA400BA0A4D /* BackgroundCell.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BackgroundCell.cpp; sourceTree = "<group>"; };
|
||||
5E73965B1DAFDAA400BA0A4D /* BackgroundCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BackgroundCell.h; sourceTree = "<group>"; };
|
||||
5E73965D1DAFDAEC00BA0A4D /* TrackSelectHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TrackSelectHandle.cpp; sourceTree = "<group>"; };
|
||||
5E73965E1DAFDAEC00BA0A4D /* TrackSelectHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackSelectHandle.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>"; };
|
||||
5E74D2DD1CC4429700D88B0B /* EditCursorOverlay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EditCursorOverlay.cpp; sourceTree = "<group>"; };
|
||||
@ -5778,6 +5781,7 @@
|
||||
5E7396421DAFD8C600BA0A4D /* TimeShiftHandle.cpp */,
|
||||
5E7396571DAFDA3600BA0A4D /* TrackButtonHandles.cpp */,
|
||||
5E1512681DB0010C00702E29 /* TrackControls.cpp */,
|
||||
5E73965D1DAFDAEC00BA0A4D /* TrackSelectHandle.cpp */,
|
||||
5E15126A1DB0010C00702E29 /* TrackUI.cpp */,
|
||||
5E15126B1DB0010C00702E29 /* TrackVRulerControls.cpp */,
|
||||
5E73963C1DAFD86000BA0A4D /* ZoomHandle.cpp */,
|
||||
@ -5792,6 +5796,7 @@
|
||||
5E7396431DAFD8C600BA0A4D /* TimeShiftHandle.h */,
|
||||
5E7396581DAFDA3600BA0A4D /* TrackButtonHandles.h */,
|
||||
5E1512691DB0010C00702E29 /* TrackControls.h */,
|
||||
5E73965E1DAFDAEC00BA0A4D /* TrackSelectHandle.h */,
|
||||
5E15126C1DB0010C00702E29 /* TrackVRulerControls.h */,
|
||||
5E73963D1DAFD86000BA0A4D /* ZoomHandle.h */,
|
||||
);
|
||||
@ -7893,6 +7898,7 @@
|
||||
2888495E131B6CF600B59735 /* km.po in Sources */,
|
||||
2888495F131B6CF600B59735 /* ko.po in Sources */,
|
||||
28884960131B6CF600B59735 /* lt.po in Sources */,
|
||||
5E73965F1DAFDAEC00BA0A4D /* TrackSelectHandle.cpp in Sources */,
|
||||
28884961131B6CF600B59735 /* mk.po in Sources */,
|
||||
28884962131B6CF600B59735 /* my.po in Sources */,
|
||||
28884963131B6CF600B59735 /* nb.po in Sources */,
|
||||
|
@ -601,6 +601,8 @@ audacity_SOURCES = \
|
||||
tracks/ui/TrackButtonHandles.h \
|
||||
tracks/ui/TrackControls.cpp \
|
||||
tracks/ui/TrackControls.h \
|
||||
tracks/ui/TrackSelectHandle.cpp \
|
||||
tracks/ui/TrackSelectHandle.h \
|
||||
tracks/ui/TrackUI.cpp \
|
||||
tracks/ui/TrackVRulerControls.cpp \
|
||||
tracks/ui/TrackVRulerControls.h \
|
||||
|
@ -195,6 +195,8 @@ is time to refresh some aspect of the screen.
|
||||
//This loads the appropriate set of cursors, depending on platform.
|
||||
#include "../images/Cursors.h"
|
||||
|
||||
#include "widgets/ASlider.h"
|
||||
|
||||
DEFINE_EVENT_TYPE(EVT_TRACK_PANEL_TIMER)
|
||||
|
||||
/*
|
||||
@ -381,7 +383,6 @@ TrackPanel::TrackPanel(wxWindow * parent, wxWindowID id,
|
||||
|
||||
mArrowCursor = std::make_unique<wxCursor>(wxCURSOR_ARROW);
|
||||
mResizeCursor = std::make_unique<wxCursor>(wxCURSOR_SIZENS);
|
||||
mRearrangeCursor = std::make_unique<wxCursor>(wxCURSOR_HAND);
|
||||
mAdjustLeftSelectionCursor = std::make_unique<wxCursor>(wxCURSOR_POINT_LEFT);
|
||||
mAdjustRightSelectionCursor = std::make_unique<wxCursor>(wxCURSOR_POINT_RIGHT);
|
||||
|
||||
@ -873,7 +874,6 @@ void TrackPanel::HandleInterruptedDrag()
|
||||
So this includes the cases:
|
||||
|
||||
IsAdjustingLabel,
|
||||
IsRearranging,
|
||||
IsStretching
|
||||
*/
|
||||
|
||||
@ -1123,9 +1123,6 @@ bool TrackPanel::SetCursorByActivity( )
|
||||
case IsSelecting:
|
||||
SetCursor(*mSelectCursor);
|
||||
return true;
|
||||
case IsRearranging:
|
||||
SetCursor( unsafe ? *mDisabledCursor : *mRearrangeCursor);
|
||||
return true;
|
||||
case IsAdjustingLabel:
|
||||
case IsSelectingLabelText:
|
||||
return true;
|
||||
@ -1142,36 +1139,6 @@ bool TrackPanel::SetCursorByActivity( )
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(__WXMAC__)
|
||||
/* i18n-hint: Command names a modifier key on Macintosh keyboards */
|
||||
#define CTRL_CLICK _("Command-Click")
|
||||
#else
|
||||
/* i18n-hint: Ctrl names a modifier key on Windows or Linux keyboards */
|
||||
#define CTRL_CLICK _("Ctrl-Click")
|
||||
#endif
|
||||
|
||||
/// When in the "label" (TrackInfo or vertical ruler), we can either vertical zoom or re-order tracks.
|
||||
/// Dont't change cursor/tip to zoom if display is not waveform (either linear of dB) or Spectrum
|
||||
void TrackPanel::SetCursorAndTipWhenInLabel( Track * ,
|
||||
const wxMouseEvent &, wxString &tip )
|
||||
{
|
||||
if( GetTrackCount() > 1 ) {
|
||||
// Set a status message if over TrackInfo.
|
||||
//tip = _("Drag the track vertically to change the order of the tracks.");
|
||||
// i18n-hint: %s is replaced by (translation of) 'Ctrl-Click' on windows, 'Command-Click' on Mac
|
||||
tip = wxString::Format( _("%s to select or deselect track. Drag up or down to change track order."),
|
||||
CTRL_CLICK );
|
||||
SetCursor( *mArrowCursor );
|
||||
}
|
||||
else {
|
||||
// Set a status message if over TrackInfo.
|
||||
// i18n-hint: %s is replaced by (translation of) 'Ctrl-Click' on windows, 'Command-Click' on Mac
|
||||
tip = wxString::Format( _("%s to select or deselect track."),
|
||||
CTRL_CLICK );
|
||||
SetCursor(*mArrowCursor);
|
||||
}
|
||||
}
|
||||
|
||||
/// When in the resize area we can adjust size or relative size.
|
||||
void TrackPanel::SetCursorAndTipWhenInVResizeArea( bool bLinked, wxString &tip )
|
||||
{
|
||||
@ -1492,9 +1459,6 @@ void TrackPanel::HandleCursor(wxMouseEvent & event)
|
||||
pCursor = hitTest.preview.cursor;
|
||||
if (pCursor)
|
||||
SetCursor(*pCursor);
|
||||
else if (foundCell.type == CellType::Label ||
|
||||
foundCell.type == CellType::VRuler)
|
||||
SetCursorAndTipWhenInLabel(track, event, tip);
|
||||
}
|
||||
|
||||
// Is it a label track?
|
||||
@ -1671,11 +1635,12 @@ void TrackPanel::HandleSelect(wxMouseEvent & event)
|
||||
}
|
||||
|
||||
// Counts tracks, counting stereo tracks as one track.
|
||||
size_t TrackPanel::GetTrackCount(){
|
||||
size_t TrackPanel::GetTrackCount() const
|
||||
{
|
||||
size_t count = 0;
|
||||
|
||||
TrackListIterator iter(GetTracks());
|
||||
for (Track *t = iter.First(); t; t = iter.Next()) {
|
||||
TrackListConstIterator iter(GetTracks());
|
||||
for (auto t = iter.First(); t; t = iter.Next()) {
|
||||
count += 1;
|
||||
if( t->GetLinked() ){
|
||||
t = iter.Next();
|
||||
@ -1687,11 +1652,12 @@ size_t TrackPanel::GetTrackCount(){
|
||||
}
|
||||
|
||||
// Counts selected tracks, counting stereo tracks as one track.
|
||||
size_t TrackPanel::GetSelectedTrackCount(){
|
||||
size_t TrackPanel::GetSelectedTrackCount() const
|
||||
{
|
||||
size_t count = 0;
|
||||
|
||||
TrackListIterator iter(GetTracks());
|
||||
for (Track *t = iter.First(); t; t = iter.Next()) {
|
||||
TrackListConstIterator iter(GetTracks());
|
||||
for (auto t = iter.First(); t; t = iter.Next()) {
|
||||
count += t->GetSelected() ? 1:0;
|
||||
if( t->GetLinked() ){
|
||||
t = iter.Next();
|
||||
@ -3062,120 +3028,6 @@ bool TrackInfo::HideTopItem( const wxRect &rect, const wxRect &subRect,
|
||||
return subRect.y + subRect.height - allowance >= rect.y + limit;
|
||||
}
|
||||
|
||||
/// This handles when the user clicks on the "Label" area
|
||||
/// of a track, ie the part with all the buttons and the drop
|
||||
/// down menu, etc.
|
||||
// That is, TrackInfo and vertical ruler rect.
|
||||
void TrackPanel::HandleLabelClick(wxMouseEvent & event)
|
||||
{
|
||||
// AS: If not a click, ignore the mouse event.
|
||||
if (!event.ButtonDown() && !event.ButtonDClick()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// MIDI tracks use the right mouse button, but other tracks get confused
|
||||
// if they see anything other than a left click.
|
||||
bool isleft = event.Button(wxMOUSE_BTN_LEFT);
|
||||
|
||||
bool unsafe = IsUnsafe();
|
||||
|
||||
const auto foundCell = FindCell(event.m_x, event.m_y);
|
||||
auto &t = foundCell.pTrack;
|
||||
auto &rect = foundCell.rect;
|
||||
|
||||
if (!isleft) {
|
||||
return;
|
||||
}
|
||||
|
||||
// DM: If they weren't clicking on a particular part of a track label,
|
||||
// deselect other tracks and select this one.
|
||||
|
||||
// JH: also, capture the current track for rearranging, so the user
|
||||
// can drag the track up or down to swap it with others
|
||||
if (!unsafe) {
|
||||
mRearrangeCount = 0;
|
||||
SetCapturedTrack(t, IsRearranging);
|
||||
TrackPanel::CalculateRearrangingThresholds(event);
|
||||
}
|
||||
|
||||
GetProject()->HandleListSelection(t, event.ShiftDown(), event.ControlDown(), !unsafe);
|
||||
}
|
||||
|
||||
/// The user is dragging one of the tracks: change the track order
|
||||
/// accordingly
|
||||
void TrackPanel::HandleRearrange(wxMouseEvent & event)
|
||||
{
|
||||
// are we finishing the drag?
|
||||
if (event.LeftUp()) {
|
||||
if (mRearrangeCount != 0) {
|
||||
wxString dir;
|
||||
/* i18n-hint: a direction as in up or down.*/
|
||||
dir = mRearrangeCount < 0 ? _("up") : _("down");
|
||||
/* i18n-hint: will substitute name of track for first %s, "up" or "down" for the other.*/
|
||||
MakeParentPushState(wxString::Format(_("Moved '%s' %s"),
|
||||
mCapturedTrack->GetName().c_str(),
|
||||
dir.c_str()),
|
||||
_("Move Track"));
|
||||
}
|
||||
|
||||
SetCapturedTrack(NULL);
|
||||
SetCursor(*mArrowCursor);
|
||||
return;
|
||||
}
|
||||
|
||||
// probably harmless during play? However, we do disallow the click, so check this too.
|
||||
bool unsafe = IsUnsafe();
|
||||
if (unsafe)
|
||||
return;
|
||||
|
||||
MixerBoard* pMixerBoard = this->GetMixerBoard(); // Update mixer board, too.
|
||||
if (event.m_y < mMoveUpThreshold || event.m_y < 0) {
|
||||
mTracks->MoveUp(mCapturedTrack);
|
||||
--mRearrangeCount;
|
||||
if (pMixerBoard)
|
||||
if(auto pPlayable = dynamic_cast< const PlayableTrack* >( mCapturedTrack ))
|
||||
pMixerBoard->MoveTrackCluster(pPlayable, true /* up */);
|
||||
}
|
||||
else if (event.m_y > mMoveDownThreshold || event.m_y > GetRect().GetHeight()) {
|
||||
mTracks->MoveDown(mCapturedTrack);
|
||||
++mRearrangeCount;
|
||||
if (pMixerBoard)
|
||||
if(auto pPlayable = dynamic_cast< const PlayableTrack* >( mCapturedTrack ))
|
||||
pMixerBoard->MoveTrackCluster(pPlayable, false /* down */);
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// JH: if we moved up or down, recalculate the thresholds and make sure the
|
||||
// track is fully on-screen.
|
||||
TrackPanel::CalculateRearrangingThresholds(event);
|
||||
EnsureVisible(mCapturedTrack);
|
||||
}
|
||||
|
||||
/// Figure out how far the user must drag the mouse up or down
|
||||
/// before the track will swap with the one above or below
|
||||
void TrackPanel::CalculateRearrangingThresholds(wxMouseEvent & event)
|
||||
{
|
||||
wxASSERT(mCapturedTrack);
|
||||
|
||||
// JH: this will probably need to be tweaked a bit, I'm just
|
||||
// not sure what formula will have the best feel for the
|
||||
// user.
|
||||
if (mTracks->CanMoveUp(mCapturedTrack))
|
||||
mMoveUpThreshold =
|
||||
event.m_y - mTracks->GetGroupHeight( mTracks->GetPrev(mCapturedTrack,true) );
|
||||
else
|
||||
mMoveUpThreshold = INT_MIN;
|
||||
|
||||
if (mTracks->CanMoveDown(mCapturedTrack))
|
||||
mMoveDownThreshold =
|
||||
event.m_y + mTracks->GetGroupHeight( mTracks->GetNext(mCapturedTrack,true) );
|
||||
else
|
||||
mMoveDownThreshold = INT_MAX;
|
||||
}
|
||||
|
||||
/// ButtonDown means they just clicked and haven't released yet.
|
||||
/// We use this opportunity to save which track they clicked on,
|
||||
/// and the initial height of the track, so as they drag we can
|
||||
@ -3811,9 +3663,6 @@ try
|
||||
HandleResize(event);
|
||||
HandleCursor(event);
|
||||
break;
|
||||
case IsRearranging:
|
||||
HandleRearrange(event);
|
||||
break;
|
||||
case IsAdjustingLabel:
|
||||
// Reach this case only when the captured track was label
|
||||
HandleGlyphDragRelease(static_cast<LabelTrack *>(mCapturedTrack), event);
|
||||
@ -4069,13 +3918,6 @@ void TrackPanel::HandleTrackSpecificMouseEvent(wxMouseEvent & event)
|
||||
ProcessUIHandleResult(this, mRuler, pTrack, pTrack, refreshResult);
|
||||
}
|
||||
|
||||
else {
|
||||
if (foundCell.type == CellType::VRuler) {
|
||||
}
|
||||
else if (foundCell.type == CellType::Label)
|
||||
HandleLabelClick(event);
|
||||
}
|
||||
|
||||
HandleCursor(event);
|
||||
return;
|
||||
}
|
||||
|
@ -388,12 +388,14 @@ class AUDACITY_DLL_API TrackPanel final : public OverlayPanel {
|
||||
#endif
|
||||
|
||||
// AS: Selection handling
|
||||
size_t GetTrackCount();
|
||||
size_t GetSelectedTrackCount();
|
||||
virtual void HandleSelect(wxMouseEvent & event);
|
||||
virtual void SelectionHandleDrag(wxMouseEvent &event, Track *pTrack);
|
||||
|
||||
public:
|
||||
size_t GetTrackCount() const;
|
||||
size_t GetSelectedTrackCount() const;
|
||||
|
||||
protected:
|
||||
virtual void HandleSelect(wxMouseEvent & event);
|
||||
virtual void SelectionHandleDrag(wxMouseEvent &event, Track *pTrack);
|
||||
|
||||
virtual void SelectionHandleClick(wxMouseEvent &event,
|
||||
Track* pTrack, wxRect rect);
|
||||
@ -424,9 +426,9 @@ protected:
|
||||
|
||||
virtual void SelectTracksByLabel( LabelTrack *t );
|
||||
|
||||
protected:
|
||||
// AS: Cursor handling
|
||||
virtual bool SetCursorByActivity( );
|
||||
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 );
|
||||
virtual void SetCursorAndTipWhenSelectTool
|
||||
@ -448,11 +450,6 @@ protected:
|
||||
virtual void HandleResizeButtonUp(wxMouseEvent & event);
|
||||
virtual void HandleResize(wxMouseEvent & event);
|
||||
|
||||
virtual void HandleLabelClick(wxMouseEvent & event);
|
||||
|
||||
virtual void HandleRearrange(wxMouseEvent & event);
|
||||
virtual void CalculateRearrangingThresholds(wxMouseEvent & event);
|
||||
|
||||
public:
|
||||
virtual void MakeParentRedrawScrollbars();
|
||||
|
||||
@ -487,7 +484,8 @@ protected:
|
||||
// JKC Nov-2011: These four functions only used from within a dll such as mod-track-panel
|
||||
// They work around some messy problems with constructors.
|
||||
public:
|
||||
TrackList * GetTracks(){ return mTracks.get(); }
|
||||
const TrackList * GetTracks() const { return mTracks.get(); }
|
||||
TrackList * GetTracks() { return mTracks.get(); }
|
||||
ViewInfo * GetViewInfo(){ return mViewInfo;}
|
||||
TrackPanelListener * GetListener(){ return mListener;}
|
||||
AdornedRulerPanel * GetRuler(){ return mRuler;}
|
||||
@ -697,7 +695,6 @@ public:
|
||||
IsResizing,
|
||||
IsResizingBetweenLinkedTracks,
|
||||
IsResizingBelowLinkedTracks,
|
||||
IsRearranging,
|
||||
IsMuting,
|
||||
IsSoloing,
|
||||
IsMinimizing,
|
||||
@ -709,17 +706,10 @@ protected:
|
||||
|
||||
virtual void SetCapturedTrack( Track * t, enum MouseCaptureEnum MouseCapture=IsUncaptured );
|
||||
|
||||
// JH: if the user is dragging a track, at what y
|
||||
// coordinate should the dragging track move up or down?
|
||||
int mMoveUpThreshold;
|
||||
int mMoveDownThreshold;
|
||||
int mRearrangeCount;
|
||||
|
||||
std::unique_ptr<wxCursor>
|
||||
mArrowCursor, mSelectCursor,
|
||||
mResizeCursor, mEnvelopeCursor, // doubles as the center frequency cursor
|
||||
// for spectral selection
|
||||
mRearrangeCursor,
|
||||
mDisabledCursor, mAdjustLeftSelectionCursor, mAdjustRightSelectionCursor;
|
||||
#ifdef EXPERIMENTAL_SPECTRAL_EDITING
|
||||
std::unique_ptr<wxCursor>
|
||||
|
@ -11,6 +11,7 @@ Paul Licameli split from TrackPanel.cpp
|
||||
#include "../../Audacity.h"
|
||||
#include "TrackControls.h"
|
||||
#include "TrackButtonHandles.h"
|
||||
#include "TrackSelectHandle.h"
|
||||
#include "../../HitTestResult.h"
|
||||
#include "../../RefreshCode.h"
|
||||
#include "../../MixerBoard.h"
|
||||
@ -28,7 +29,7 @@ TrackControls::~TrackControls()
|
||||
|
||||
HitTestResult TrackControls::HitTest
|
||||
(const TrackPanelMouseEvent &evt,
|
||||
const AudacityProject *)
|
||||
const AudacityProject *project)
|
||||
{
|
||||
const wxMouseEvent &event = evt.event;
|
||||
const wxRect &rect = evt.rect;
|
||||
@ -43,7 +44,8 @@ HitTestResult TrackControls::HitTest
|
||||
if (NULL != (result = MinimizeButtonHandle::HitTest(event, rect)).handle)
|
||||
return result;
|
||||
|
||||
return result;
|
||||
return TrackSelectHandle::HitAnywhere
|
||||
(project->GetTrackPanel()->GetTrackCount());
|
||||
}
|
||||
|
||||
Track *TrackControls::FindTrack()
|
||||
|
227
src/tracks/ui/TrackSelectHandle.cpp
Normal file
227
src/tracks/ui/TrackSelectHandle.cpp
Normal file
@ -0,0 +1,227 @@
|
||||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
TrackSelectHandle.cpp
|
||||
|
||||
Paul Licameli split from TrackPanel.cpp
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include "../../Audacity.h"
|
||||
#include "TrackSelectHandle.h"
|
||||
#include "TrackControls.h"
|
||||
#include "../../Experimental.h"
|
||||
#include "../../HitTestResult.h"
|
||||
#include "../../MixerBoard.h"
|
||||
#include "../../Project.h"
|
||||
#include "../../RefreshCode.h"
|
||||
#include "../../TrackPanel.h"
|
||||
#include "../../TrackPanelMouseEvent.h"
|
||||
#include "../../WaveTrack.h"
|
||||
|
||||
#include "../../MemoryX.h"
|
||||
#include <wx/cursor.h>
|
||||
#include <wx/translation.h>
|
||||
|
||||
#include "../../../images/Cursors.h"
|
||||
|
||||
TrackSelectHandle::TrackSelectHandle()
|
||||
{
|
||||
}
|
||||
|
||||
TrackSelectHandle &TrackSelectHandle::Instance()
|
||||
{
|
||||
static TrackSelectHandle instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
#if defined(__WXMAC__)
|
||||
/* i18n-hint: Command names a modifier key on Macintosh keyboards */
|
||||
#define CTRL_CLICK _("Command-Click")
|
||||
#else
|
||||
/* i18n-hint: Ctrl names a modifier key on Windows or Linux keyboards */
|
||||
#define CTRL_CLICK _("Ctrl-Click")
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
wxString Message(unsigned trackCount) {
|
||||
if (trackCount > 1)
|
||||
// i18n-hint: %s is replaced by (translation of) 'Ctrl-Click' on windows, 'Command-Click' on Mac
|
||||
return wxString::Format(
|
||||
_("%s to select or deselect track. Drag up or down to change track order."),
|
||||
CTRL_CLICK );
|
||||
else
|
||||
// i18n-hint: %s is replaced by (translation of) 'Ctrl-Click' on windows, 'Command-Click' on Mac
|
||||
return wxString::Format(
|
||||
_("%s to select or deselect track."),
|
||||
CTRL_CLICK );
|
||||
}
|
||||
}
|
||||
|
||||
HitTestPreview TrackSelectHandle::HitPreview(unsigned trackCount)
|
||||
{
|
||||
static wxCursor arrowCursor{ wxCURSOR_ARROW };
|
||||
return {
|
||||
Message(trackCount),
|
||||
&arrowCursor
|
||||
};
|
||||
}
|
||||
|
||||
HitTestResult TrackSelectHandle::HitAnywhere(unsigned trackCount)
|
||||
{
|
||||
return {
|
||||
HitPreview(trackCount),
|
||||
&Instance()
|
||||
};
|
||||
}
|
||||
|
||||
TrackSelectHandle::~TrackSelectHandle()
|
||||
{
|
||||
}
|
||||
|
||||
UIHandle::Result TrackSelectHandle::Click
|
||||
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
|
||||
{
|
||||
using namespace RefreshCode;
|
||||
Result result = RefreshNone;
|
||||
|
||||
const wxMouseEvent &event = evt.event;
|
||||
|
||||
// AS: If not a click, ignore the mouse event.
|
||||
if (!event.ButtonDown() && !event.ButtonDClick())
|
||||
return Cancelled;
|
||||
if (!event.Button(wxMOUSE_BTN_LEFT))
|
||||
return Cancelled;
|
||||
|
||||
TrackControls *const pControls = static_cast<TrackControls*>(evt.pCell);
|
||||
Track *const pTrack = pControls->GetTrack();
|
||||
TrackPanel *const trackPanel = pProject->GetTrackPanel();
|
||||
const bool unsafe = pProject->IsAudioActive();
|
||||
|
||||
// DM: If they weren't clicking on a particular part of a track label,
|
||||
// deselect other tracks and select this one.
|
||||
|
||||
// JH: also, capture the current track for rearranging, so the user
|
||||
// can drag the track up or down to swap it with others
|
||||
if (unsafe)
|
||||
result |= Cancelled;
|
||||
else {
|
||||
mRearrangeCount = 0;
|
||||
mpTrack = pTrack;
|
||||
CalculateRearrangingThresholds(event);
|
||||
}
|
||||
|
||||
pProject->HandleListSelection
|
||||
(pTrack, event.ShiftDown(), event.ControlDown(), !unsafe);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
UIHandle::Result TrackSelectHandle::Drag
|
||||
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
|
||||
{
|
||||
using namespace RefreshCode;
|
||||
Result result = RefreshNone;
|
||||
|
||||
const wxMouseEvent &event = evt.event;
|
||||
|
||||
TrackList *const tracks = pProject->GetTracks();
|
||||
|
||||
// probably harmless during play? However, we do disallow the click, so check this too.
|
||||
bool unsafe = pProject->IsAudioActive();
|
||||
if (unsafe)
|
||||
return result;
|
||||
|
||||
MixerBoard* pMixerBoard = pProject->GetMixerBoard(); // Update mixer board, too.
|
||||
if (event.m_y < mMoveUpThreshold || event.m_y < 0) {
|
||||
tracks->MoveUp(mpTrack);
|
||||
--mRearrangeCount;
|
||||
if (pMixerBoard)
|
||||
if(auto pPlayable = dynamic_cast< const PlayableTrack* >( mpTrack ))
|
||||
pMixerBoard->MoveTrackCluster(pPlayable, true /* up */);
|
||||
}
|
||||
else if ( event.m_y > mMoveDownThreshold
|
||||
|| event.m_y > evt.whole.GetHeight() ) {
|
||||
tracks->MoveDown(mpTrack);
|
||||
++mRearrangeCount;
|
||||
if (pMixerBoard)
|
||||
if(auto pPlayable = dynamic_cast< const PlayableTrack* >( mpTrack ))
|
||||
pMixerBoard->MoveTrackCluster(pPlayable, false /* down */);
|
||||
}
|
||||
else
|
||||
return result;
|
||||
|
||||
// JH: if we moved up or down, recalculate the thresholds and make sure the
|
||||
// track is fully on-screen.
|
||||
CalculateRearrangingThresholds(event);
|
||||
|
||||
result |= EnsureVisible;
|
||||
return result;
|
||||
}
|
||||
|
||||
HitTestPreview TrackSelectHandle::Preview
|
||||
(const TrackPanelMouseEvent &, const AudacityProject *project)
|
||||
{
|
||||
// Note that this differs from HitPreview.
|
||||
|
||||
static auto disabledCursor =
|
||||
::MakeCursor(wxCURSOR_NO_ENTRY, DisabledCursorXpm, 16, 16);
|
||||
static wxCursor rearrangeCursor{ wxCURSOR_HAND };
|
||||
|
||||
const bool unsafe = GetActiveProject()->IsAudioActive();
|
||||
return {
|
||||
Message(project->GetTrackPanel()->GetTrackCount()),
|
||||
(unsafe
|
||||
? &*disabledCursor
|
||||
: &rearrangeCursor)
|
||||
};
|
||||
}
|
||||
|
||||
UIHandle::Result TrackSelectHandle::Release
|
||||
(const TrackPanelMouseEvent &, AudacityProject *, wxWindow *)
|
||||
{
|
||||
if (mRearrangeCount != 0) {
|
||||
AudacityProject *const project = ::GetActiveProject();
|
||||
wxString dir;
|
||||
/* i18n-hint: a direction as in up or down.*/
|
||||
dir = mRearrangeCount < 0 ? _("up") : _("down");
|
||||
/* i18n-hint: will substitute name of track for first %s, "up" or "down" for the other.*/
|
||||
project->PushState(wxString::Format(_("Moved '%s' %s"),
|
||||
mpTrack->GetName().c_str(),
|
||||
dir.c_str()),
|
||||
_("Move Track"));
|
||||
}
|
||||
// No need to redraw, that was done when drag moved the track
|
||||
return RefreshCode::RefreshNone;
|
||||
}
|
||||
|
||||
UIHandle::Result TrackSelectHandle::Cancel(AudacityProject *pProject)
|
||||
{
|
||||
pProject->RollbackState();
|
||||
return RefreshCode::RefreshAll;
|
||||
}
|
||||
|
||||
/// Figure out how far the user must drag the mouse up or down
|
||||
/// before the track will swap with the one above or below
|
||||
void TrackSelectHandle::CalculateRearrangingThresholds(const wxMouseEvent & event)
|
||||
{
|
||||
// JH: this will probably need to be tweaked a bit, I'm just
|
||||
// not sure what formula will have the best feel for the
|
||||
// user.
|
||||
|
||||
AudacityProject *const project = ::GetActiveProject();
|
||||
TrackList *const tracks = project->GetTracks();
|
||||
|
||||
if (tracks->CanMoveUp(mpTrack))
|
||||
mMoveUpThreshold =
|
||||
event.m_y - tracks->GetGroupHeight(tracks->GetPrev(mpTrack, true));
|
||||
else
|
||||
mMoveUpThreshold = INT_MIN;
|
||||
|
||||
if (tracks->CanMoveDown(mpTrack))
|
||||
mMoveDownThreshold =
|
||||
event.m_y + tracks->GetGroupHeight(tracks->GetNext(mpTrack, true));
|
||||
else
|
||||
mMoveDownThreshold = INT_MAX;
|
||||
}
|
63
src/tracks/ui/TrackSelectHandle.h
Normal file
63
src/tracks/ui/TrackSelectHandle.h
Normal file
@ -0,0 +1,63 @@
|
||||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
TrackSelectHandle.h
|
||||
|
||||
Paul Licameli split from TrackPanel.cpp
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef __AUDACITY_TRACK_SELECT_HANDLE__
|
||||
#define __AUDACITY_TRACK_SELECT_HANDLE__
|
||||
|
||||
#include "../../UIHandle.h"
|
||||
|
||||
class wxMouseEvent;
|
||||
struct HitTestResult;
|
||||
class Track;
|
||||
|
||||
class TrackSelectHandle final : public UIHandle
|
||||
{
|
||||
TrackSelectHandle();
|
||||
TrackSelectHandle(const TrackSelectHandle&) = delete;
|
||||
TrackSelectHandle &operator=(const TrackSelectHandle&) = delete;
|
||||
static TrackSelectHandle& Instance();
|
||||
static HitTestPreview HitPreview(unsigned trackCount);
|
||||
|
||||
public:
|
||||
static HitTestResult HitAnywhere(unsigned trackCount);
|
||||
|
||||
virtual ~TrackSelectHandle();
|
||||
|
||||
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 *) override;
|
||||
|
||||
bool StopsOnKeystroke() override { return true; }
|
||||
|
||||
private:
|
||||
Track *mpTrack {};
|
||||
|
||||
// JH: if the user is dragging a track, at what y
|
||||
// coordinate should the dragging track move up or down?
|
||||
int mMoveUpThreshold {};
|
||||
int mMoveDownThreshold {};
|
||||
int mRearrangeCount {};
|
||||
|
||||
void CalculateRearrangingThresholds(const wxMouseEvent & event);
|
||||
};
|
||||
|
||||
#endif
|
@ -251,6 +251,7 @@
|
||||
<ClCompile Include="..\..\..\src\tracks\ui\TimeShiftHandle.cpp" />
|
||||
<ClCompile Include="..\..\..\src\tracks\ui\TrackButtonHandles.cpp" />
|
||||
<ClCompile Include="..\..\..\src\tracks\ui\TrackControls.cpp" />
|
||||
<ClCompile Include="..\..\..\src\tracks\ui\TrackSelectHandle.cpp" />
|
||||
<ClCompile Include="..\..\..\src\tracks\ui\TrackUI.cpp" />
|
||||
<ClCompile Include="..\..\..\src\tracks\ui\TrackVRulerControls.cpp" />
|
||||
<ClCompile Include="..\..\..\src\tracks\ui\ZoomHandle.cpp" />
|
||||
@ -522,6 +523,7 @@
|
||||
<ClInclude Include="..\..\..\src\tracks\ui\TimeShiftHandle.h" />
|
||||
<ClInclude Include="..\..\..\src\tracks\ui\TrackButtonHandles.h" />
|
||||
<ClInclude Include="..\..\..\src\tracks\ui\TrackControls.h" />
|
||||
<ClInclude Include="..\..\..\src\tracks\ui\TrackSelectHandle.h" />
|
||||
<ClInclude Include="..\..\..\src\tracks\ui\ZoomHandle.h" />
|
||||
<ClInclude Include="..\..\..\src\tracks\timetrack\ui\TimeTrackVRulerControls.h" />
|
||||
<ClInclude Include="..\..\..\src\tracks\ui\TrackVRulerControls.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">
|
||||
<ItemGroup>
|
||||
<Filter Include="src">
|
||||
@ -1025,6 +1025,9 @@
|
||||
<ClCompile Include="..\..\..\src\tracks\ui\BackgroundCell.cpp">
|
||||
<Filter>src\tracks\ui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\tracks\ui\TrackSelectHandle.cpp">
|
||||
<Filter>src\tracks\ui</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\src\AboutDialog.h">
|
||||
@ -2041,6 +2044,9 @@
|
||||
<ClInclude Include="..\..\..\src\tracks\ui\BackgroundCell.h">
|
||||
<Filter>src\tracks\ui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\tracks\ui\TrackSelectHandle.h">
|
||||
<Filter>src\tracks\ui</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="..\..\audacity.ico">
|
||||
|
Loading…
x
Reference in New Issue
Block a user