TrackPanel no longer implements label keystrokes, drags, text selection...

... also implemented ESC key for those drags

... temporarily loses the special CTRL click handling
This commit is contained in:
Paul Licameli 2015-08-17 17:49:00 -04:00 committed by Paul Licameli
parent bbfa574790
commit efdb9889b1
15 changed files with 923 additions and 326 deletions

View File

@ -1235,6 +1235,9 @@
5E73965C1DAFDAA400BA0A4D /* BackgroundCell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E73965A1DAFDAA400BA0A4D /* BackgroundCell.cpp */; };
5E73965F1DAFDAEC00BA0A4D /* TrackSelectHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E73965D1DAFDAEC00BA0A4D /* TrackSelectHandle.cpp */; };
5E7396621DAFDB1E00BA0A4D /* TrackPanelResizeHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E7396601DAFDB1E00BA0A4D /* TrackPanelResizeHandle.cpp */; };
5E7396691DAFDB5600BA0A4D /* LabelDefaultClickHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E7396631DAFDB5600BA0A4D /* LabelDefaultClickHandle.cpp */; };
5E73966A1DAFDB5600BA0A4D /* LabelGlyphHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E7396651DAFDB5600BA0A4D /* LabelGlyphHandle.cpp */; };
5E73966B1DAFDB5600BA0A4D /* LabelTextHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E7396671DAFDB5600BA0A4D /* LabelTextHandle.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 */; };
@ -3076,6 +3079,12 @@
5E73965E1DAFDAEC00BA0A4D /* TrackSelectHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackSelectHandle.h; sourceTree = "<group>"; };
5E7396601DAFDB1E00BA0A4D /* TrackPanelResizeHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TrackPanelResizeHandle.cpp; sourceTree = "<group>"; };
5E7396611DAFDB1E00BA0A4D /* TrackPanelResizeHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackPanelResizeHandle.h; sourceTree = "<group>"; };
5E7396631DAFDB5600BA0A4D /* LabelDefaultClickHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LabelDefaultClickHandle.cpp; sourceTree = "<group>"; };
5E7396641DAFDB5600BA0A4D /* LabelDefaultClickHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LabelDefaultClickHandle.h; sourceTree = "<group>"; };
5E7396651DAFDB5600BA0A4D /* LabelGlyphHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LabelGlyphHandle.cpp; sourceTree = "<group>"; };
5E7396661DAFDB5600BA0A4D /* LabelGlyphHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LabelGlyphHandle.h; sourceTree = "<group>"; };
5E7396671DAFDB5600BA0A4D /* LabelTextHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LabelTextHandle.cpp; sourceTree = "<group>"; };
5E7396681DAFDB5600BA0A4D /* LabelTextHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LabelTextHandle.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>"; };
@ -5732,9 +5741,15 @@
5E15123F1DB000DC00702E29 /* ui */ = {
isa = PBXGroup;
children = (
5E7396631DAFDB5600BA0A4D /* LabelDefaultClickHandle.cpp */,
5E7396651DAFDB5600BA0A4D /* LabelGlyphHandle.cpp */,
5E7396671DAFDB5600BA0A4D /* LabelTextHandle.cpp */,
5E1512401DB000DC00702E29 /* LabelTrackControls.cpp */,
5E1512421DB000DC00702E29 /* LabelTrackUI.cpp */,
5E1512431DB000DC00702E29 /* LabelTrackVRulerControls.cpp */,
5E7396641DAFDB5600BA0A4D /* LabelDefaultClickHandle.h */,
5E7396661DAFDB5600BA0A4D /* LabelGlyphHandle.h */,
5E7396681DAFDB5600BA0A4D /* LabelTextHandle.h */,
5E1512411DB000DC00702E29 /* LabelTrackControls.h */,
5E1512441DB000DC00702E29 /* LabelTrackVRulerControls.h */,
);
@ -7652,6 +7667,7 @@
1790B15E09883BFD008A330A /* ExportMultiple.cpp in Sources */,
1790B15F09883BFD008A330A /* ExportOGG.cpp in Sources */,
1790B16009883BFD008A330A /* ExportPCM.cpp in Sources */,
5E7396691DAFDB5600BA0A4D /* LabelDefaultClickHandle.cpp in Sources */,
1790B16109883BFD008A330A /* FFT.cpp in Sources */,
1790B16209883BFD008A330A /* FileFormats.cpp in Sources */,
1790B16309883BFD008A330A /* FreqWindow.cpp in Sources */,
@ -7824,6 +7840,7 @@
284B279E0FC66864005EAC96 /* ProjectsPrefs.cpp in Sources */,
5E78388E1DE4995F003270C0 /* AudacityException.cpp in Sources */,
284B279F0FC66864005EAC96 /* RecordingPrefs.cpp in Sources */,
5E73966B1DAFDB5600BA0A4D /* LabelTextHandle.cpp in Sources */,
284B27E40FC66CCD005EAC96 /* TracksPrefs.cpp in Sources */,
284B27E50FC66CCD005EAC96 /* WarningsPrefs.cpp in Sources */,
5E15125B1DB000DC00702E29 /* LabelTrackUI.cpp in Sources */,
@ -7921,6 +7938,7 @@
ED87F50A1986424100AC520B /* ta.po in Sources */,
2888496E131B6CF600B59735 /* tg.po in Sources */,
5E7396441DAFD8C600BA0A4D /* TimeShiftHandle.cpp in Sources */,
5E73966A1DAFDB5600BA0A4D /* LabelGlyphHandle.cpp in Sources */,
2888496F131B6CF600B59735 /* tr.po in Sources */,
28884970131B6CF600B59735 /* uk.po in Sources */,
28884971131B6CF600B59735 /* vi.po in Sources */,

View File

@ -30,6 +30,7 @@ for drawing different aspects of the label and its text box.
#include "Audacity.h"
#include "LabelTrack.h"
#include "TrackPanel.h"
#include <stdio.h>
#include <algorithm>
@ -55,6 +56,7 @@ for drawing different aspects of the label and its text box.
#include "DirManager.h"
#include "Internat.h"
#include "Prefs.h"
#include "RefreshCode.h"
#include "Theme.h"
#include "AllThemeResources.h"
#include "AColor.h"
@ -280,6 +282,15 @@ void LabelTrack::ResetFlags()
mDrawCursor = false;
}
void LabelTrack::RestoreFlags( const Flags& flags )
{
mInitialCursorPos = flags.mInitialCursorPos;
mCurrentCursorPos = flags.mCurrentCursorPos;
mSelIndex = flags.mSelIndex;
mRightDragging = flags.mRightDragging;
mDrawCursor = flags.mDrawCursor;
}
wxFont LabelTrack::GetFont(const wxString &faceName, int size)
{
wxFontEncoding encoding;
@ -1545,7 +1556,7 @@ void LabelTrack::HandleTextDragRelease(const wxMouseEvent & evt)
return;
}
void LabelTrack::HandleClick(const wxMouseEvent & evt,
void LabelTrack::HandleGlyphClick(const wxMouseEvent & evt,
const wxRect & r, const ZoomInfo &zoomInfo,
SelectedRegion *newSel)
{
@ -1596,6 +1607,15 @@ void LabelTrack::HandleClick(const wxMouseEvent & evt,
mxMouseDisplacement = zoomInfo.TimeToPosition(t, r.x) - evt.m_x;
return;
}
}
}
void LabelTrack::HandleTextClick(const wxMouseEvent & evt,
const wxRect & r, const ZoomInfo &zoomInfo,
SelectedRegion *newSel)
{
if (evt.ButtonDown())
{
mSelIndex = OverATextBox(evt.m_x, evt.m_y);
if (mSelIndex != -1) {
@ -1660,7 +1680,6 @@ void LabelTrack::HandleClick(const wxMouseEvent & evt,
}
#endif
}
#if defined(__WXGTK__) && (HAVE_GTK)
if (evt.MiddleDown()) {
// Paste text, making a NEW label if none is selected.
@ -1673,7 +1692,7 @@ void LabelTrack::HandleClick(const wxMouseEvent & evt,
}
// Check for keys that we will process
bool LabelTrack::CaptureKey(wxKeyEvent & event)
bool LabelTrack::DoCaptureKey(wxKeyEvent & event)
{
// Check for modifiers and only allow shift
int mods = event.GetModifiers();
@ -1725,6 +1744,69 @@ bool LabelTrack::CaptureKey(wxKeyEvent & event)
return false;
}
unsigned LabelTrack::CaptureKey(wxKeyEvent & event, ViewInfo &, wxWindow *)
{
event.Skip(!DoCaptureKey(event));
return RefreshCode::RefreshNone;
}
unsigned LabelTrack::KeyDown(wxKeyEvent & event, ViewInfo &viewInfo, wxWindow *pParent)
{
double bkpSel0 = viewInfo.selectedRegion.t0(),
bkpSel1 = viewInfo.selectedRegion.t1();
AudacityProject *const pProj = GetActiveProject();
// Pass keystroke to labeltrack's handler and add to history if any
// updates were done
if (OnKeyDown(viewInfo.selectedRegion, event)) {
pProj->PushState(_("Modified Label"),
_("Label Edit"),
UndoPush::CONSOLIDATE);
}
// Make sure caret is in view
int x;
if (CalcCursorX(&x)) {
pProj->GetTrackPanel()->ScrollIntoView(x);
}
// If selection modified, refresh
// Otherwise, refresh track display if the keystroke was handled
if (bkpSel0 != viewInfo.selectedRegion.t0() ||
bkpSel1 != viewInfo.selectedRegion.t1())
return RefreshCode::RefreshAll;
else if (!event.GetSkipped())
return RefreshCode::RefreshCell;
return RefreshCode::RefreshNone;
}
unsigned LabelTrack::Char(wxKeyEvent & event, ViewInfo &viewInfo, wxWindow *)
{
double bkpSel0 = viewInfo.selectedRegion.t0(),
bkpSel1 = viewInfo.selectedRegion.t1();
// Pass keystroke to labeltrack's handler and add to history if any
// updates were done
AudacityProject *const pProj = GetActiveProject();
if (OnChar(viewInfo.selectedRegion, event))
pProj->PushState(_("Modified Label"),
_("Label Edit"),
UndoPush::CONSOLIDATE);
// If selection modified, refresh
// Otherwise, refresh track display if the keystroke was handled
if (bkpSel0 != viewInfo.selectedRegion.t0() ||
bkpSel1 != viewInfo.selectedRegion.t1())
return RefreshCode::RefreshAll;
else if (!event.GetSkipped())
return RefreshCode::RefreshCell;
return RefreshCode::RefreshNone;
}
/// KeyEvent is called for every keypress when over the label track.
bool LabelTrack::OnKeyDown(SelectedRegion &newSel, wxKeyEvent & event)
{

View File

@ -125,6 +125,16 @@ class AUDACITY_DLL_API LabelTrack final : public Track
(const TrackPanelMouseEvent &event,
const AudacityProject *pProject) override;
bool DoCaptureKey(wxKeyEvent &event);
unsigned CaptureKey
(wxKeyEvent &event, ViewInfo &viewInfo, wxWindow *pParent) override;
unsigned KeyDown
(wxKeyEvent &event, ViewInfo &viewInfo, wxWindow *pParent) override;
unsigned Char
(wxKeyEvent &event, ViewInfo &viewInfo, wxWindow *pParent) override;
void SetOffset(double dOffset) override;
static const int DefaultFontSize = 12;
@ -171,7 +181,20 @@ class AUDACITY_DLL_API LabelTrack final : public Track
static wxBitmap & GetGlyph( int i);
struct Flags {
int mInitialCursorPos, mCurrentCursorPos, mSelIndex;
bool mRightDragging, mDrawCursor;
};
void ResetFlags();
Flags SaveFlags() const
{
return {
mInitialCursorPos, mCurrentCursorPos, mSelIndex,
mRightDragging, mDrawCursor
};
}
void RestoreFlags( const Flags& flags );
int OverATextBox(int xx, int yy) const;
bool OverTextBox(const LabelStruct *pLabel, int x, int y) const;
bool CutSelectedText();
@ -179,13 +202,16 @@ class AUDACITY_DLL_API LabelTrack final : public Track
bool PasteSelectedText(double sel0, double sel1);
static bool IsTextClipSupported();
void HandleClick(const wxMouseEvent & evt, const wxRect & r, const ZoomInfo &zoomInfo,
SelectedRegion *newSel);
void HandleGlyphClick
(const wxMouseEvent & evt, const wxRect & r, const ZoomInfo &zoomInfo,
SelectedRegion *newSel);
void HandleTextClick
(const wxMouseEvent & evt, const wxRect & r, const ZoomInfo &zoomInfo,
SelectedRegion *newSel);
bool HandleGlyphDragRelease(const wxMouseEvent & evt, wxRect & r, const ZoomInfo &zoomInfo,
SelectedRegion *newSel);
void HandleTextDragRelease(const wxMouseEvent & evt);
bool CaptureKey(wxKeyEvent & event);
bool OnKeyDown(SelectedRegion &sel, wxKeyEvent & event);
bool OnChar(SelectedRegion &sel, wxKeyEvent & event);

View File

@ -551,6 +551,12 @@ audacity_SOURCES = \
toolbars/ToolsToolBar.h \
toolbars/TranscriptionToolBar.cpp \
toolbars/TranscriptionToolBar.h \
tracks/labeltrack/ui/LabelDefaultClickHandle.cpp \
tracks/labeltrack/ui/LabelDefaultClickHandle.h \
tracks/labeltrack/ui/LabelGlyphHandle.cpp \
tracks/labeltrack/ui/LabelGlyphHandle.h \
tracks/labeltrack/ui/LabelTextHandle.cpp \
tracks/labeltrack/ui/LabelTextHandle.h \
tracks/labeltrack/ui/LabelTrackControls.cpp \
tracks/labeltrack/ui/LabelTrackControls.h \
tracks/labeltrack/ui/LabelTrackUI.cpp \

View File

@ -166,7 +166,6 @@ is time to refresh some aspect of the screen.
#include "AllThemeResources.h"
#include "AudioIO.h"
#include "float_cast.h"
#include "LabelTrack.h"
#include "MixerBoard.h"
#include "NoteTrack.h"
@ -356,8 +355,6 @@ TrackPanel::TrackPanel(wxWindow * parent, wxWindowID id,
}
mMouseCapture = IsUncaptured;
mLabelTrackStartXPos=-1;
mRedrawAfterStop = false;
@ -553,28 +550,6 @@ void TrackPanel::SetCapturedTrack( Track * t, enum MouseCaptureEnum MouseCapture
mMouseCapture = MouseCapture;
}
/// Select all tracks marked by the label track lt
void TrackPanel::SelectTracksByLabel( LabelTrack *lt )
{
TrackListIterator iter(GetTracks());
Track *t = iter.First();
//do nothing if at least one other track is selected
while (t) {
if( t->GetSelected() && t != lt )
return;
t = iter.Next();
}
//otherwise, select all tracks
t = iter.First();
while( t )
{
GetSelectionState().SelectTrack( *mTracks, *t, true, true, GetMixerBoard() );
t = iter.Next();
}
}
void TrackPanel::GetTracksUsableArea(int *width, int *height) const
{
GetSize(width, height);
@ -859,7 +834,6 @@ void TrackPanel::HandleInterruptedDrag()
{
case IsUncaptured:
case IsSelecting:
case IsSelectingLabelText:
sendEvent = false;
default:
@ -867,9 +841,8 @@ void TrackPanel::HandleInterruptedDrag()
}
/*
So this includes the cases:
So this includes the case:
IsAdjustingLabel,
IsStretching
*/
@ -1087,9 +1060,6 @@ bool TrackPanel::SetCursorByActivity( )
case IsSelecting:
SetCursor(*mSelectCursor);
return true;
case IsAdjustingLabel:
case IsSelectingLabelText:
return true;
#if 0
case IsStretching:
SetCursor( unsafe
@ -1103,37 +1073,6 @@ bool TrackPanel::SetCursorByActivity( )
return false;
}
/// When in a label track, find out if we've hit anything that
/// would cause a cursor change.
void TrackPanel::SetCursorAndTipWhenInLabelTrack( LabelTrack * pLT,
const wxMouseEvent & event, wxString &tip )
{
int edge=pLT->OverGlyph(event.m_x, event.m_y);
if(edge !=0)
{
SetCursor(*mArrowCursor);
}
//KLUDGE: We refresh the whole Label track when the icon hovered over
//changes colouration. As well as being inefficient we are also
//doing stuff that should be delegated to the label track itself.
edge += pLT->mbHitCenter ? 4:0;
if( edge != pLT->mOldEdge )
{
pLT->mOldEdge = edge;
RefreshTrack( pLT );
}
// IF edge!=0 THEN we've set the cursor and we're done.
// signal this by setting the tip.
if( edge != 0 )
{
tip =
(pLT->mbHitCenter ) ?
_("Drag one or more label boundaries.") :
_("Drag label boundary.");
}
}
namespace {
// This returns true if we're a spectral editing track.
@ -1415,16 +1354,6 @@ void TrackPanel::HandleCursor(wxMouseEvent & event)
SetCursor(*pCursor);
}
// Is it a label track?
if (track &&
pCursor == NULL && tip == wxString() && track->GetKind() == Track::Label)
{
// We are over a label track
SetCursorAndTipWhenInLabelTrack( static_cast<LabelTrack*>(track), event, tip );
// ..and if we haven't yet determined the cursor,
// we go on to do all the standard track hit tests.
}
if( pCursor == NULL && tip == wxString() )
{
ToolsToolBar * ttb = mListener->TP_GetToolsToolBar();
@ -3038,9 +2967,6 @@ void TrackPanel::OnCaptureKey(wxCommandEvent & event)
HandleInterruptedDrag();
Track * const t = GetFocusedTrack();
if (t && t->GetKind() == Track::Label)
event.Skip(!((LabelTrack *)t)->CaptureKey(*kevent));
else
if (t) {
const unsigned refreshResult =
((TrackPanelCell*)t)->CaptureKey(*kevent, *mViewInfo, this);
@ -3087,33 +3013,6 @@ void TrackPanel::OnKeyDown(wxKeyEvent & event)
Track *const t = GetFocusedTrack();
if (t && t->GetKind() == Track::Label) {
LabelTrack *lt = (LabelTrack *)t;
double bkpSel0 = mViewInfo->selectedRegion.t0(),
bkpSel1 = mViewInfo->selectedRegion.t1();
// Pass keystroke to labeltrack's handler and add to history if any
// updates were done
if (lt->OnKeyDown(mViewInfo->selectedRegion, event))
MakeParentPushState(_("Modified Label"),
_("Label Edit"),
UndoPush::CONSOLIDATE);
// Make sure caret is in view
int x;
if (lt->CalcCursorX(&x)) {
ScrollIntoView(x);
}
// If selection modified, refresh
// Otherwise, refresh track display if the keystroke was handled
if (bkpSel0 != mViewInfo->selectedRegion.t0() ||
bkpSel1 != mViewInfo->selectedRegion.t1())
Refresh(false);
else if (!event.GetSkipped())
RefreshTrack(t);
}
else
if (t) {
const unsigned refreshResult =
((TrackPanelCell*)t)->KeyDown(event, *mViewInfo, this);
@ -3137,25 +3036,6 @@ void TrackPanel::OnChar(wxKeyEvent & event)
}
Track *const t = GetFocusedTrack();
if (t && t->GetKind() == Track::Label) {
double bkpSel0 = mViewInfo->selectedRegion.t0(),
bkpSel1 = mViewInfo->selectedRegion.t1();
// Pass keystroke to labeltrack's handler and add to history if any
// updates were done
if (((LabelTrack *)t)->OnChar(mViewInfo->selectedRegion, event))
MakeParentPushState(_("Modified Label"),
_("Label Edit"),
UndoPush::CONSOLIDATE);
// If selection modified, refresh
// Otherwise, refresh track display if the keystroke was handled
if (bkpSel0 != mViewInfo->selectedRegion.t0() ||
bkpSel1 != mViewInfo->selectedRegion.t1())
Refresh(false);
else if (!event.GetSkipped())
RefreshTrack(t);
}
else
if (t) {
const unsigned refreshResult =
((TrackPanelCell*)t)->Char(event, *mViewInfo, this);
@ -3341,19 +3221,10 @@ try
// HandleCursor(event);
}
}
else switch( mMouseCapture ) {
case IsAdjustingLabel:
// Reach this case only when the captured track was label
HandleGlyphDragRelease(static_cast<LabelTrack *>(mCapturedTrack), event);
break;
case IsSelectingLabelText:
// Reach this case only when the captured track was label
HandleTextDragRelease(static_cast<LabelTrack *>(mCapturedTrack), event);
break;
default: //includes case of IsUncaptured
else {
// includes case of IsUncaptured
// This is where most button-downs are detected
HandleTrackSpecificMouseEvent(event);
break;
}
if (event.ButtonDown() && IsMouseCaptured()) {
@ -3390,171 +3261,6 @@ catch( ... )
throw;
}
/// 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)
{
if (!event.ButtonDown())
return false;
if(event.LeftDown())
{
/// \todo This method is one of a large number of methods in
/// TrackPanel which suitably modified belong in other classes.
TrackListIterator iter(GetTracks());
Track *n = iter.First();
while (n) {
if (n->GetKind() == Track::Label && lTrack != n) {
((LabelTrack *)n)->ResetFlags();
((LabelTrack *)n)->Unselect();
}
n = iter.Next();
}
}
mCapturedRect = rect;
lTrack->HandleClick(event, mCapturedRect, *mViewInfo, &mViewInfo->selectedRegion);
if (lTrack->IsAdjustingLabel())
{
SetCapturedTrack(lTrack, IsAdjustingLabel);
//If we are adjusting a label on a labeltrack, do not do anything
//that follows. Instead, redraw the track.
RefreshTrack(lTrack);
return true;
}
if( event.LeftDown() ){
bool bShift = event.ShiftDown();
bool bCtrlDown = event.ControlDown();
bool unsafe = IsUnsafe();
if( /*bShift ||*/ bCtrlDown ){
GetProject()->HandleListSelection(lTrack, bShift, bCtrlDown, !unsafe);
return true;
}
}
// IF the user clicked a label, THEN select all other tracks by Label
if (lTrack->IsSelected()) {
SelectTracksByLabel(lTrack);
// Do this after, for the effect on mLastPickedTrack:
GetSelectionState().SelectTrack
( *mTracks, *lTrack, true, true, GetMixerBoard() );
DisplaySelection();
// Not starting a drag
SetCapturedTrack(NULL, IsUncaptured);
if(mCapturedTrack == NULL)
SetCapturedTrack(lTrack, IsSelectingLabelText);
RefreshTrack(lTrack);
// PRL: bug1659 -- make selection change undo correctly
if (!IsUnsafe())
MakeParentModifyState(false);
return true;
}
// handle shift+ctrl down
/*if (event.ShiftDown()) { // && event.ControlDown()) {
lTrack->SetHighlightedByKey(true);
Refresh(false);
return;
}*/
// return false, there is more to do...
return false;
}
/// Event has happened on a track and it has been determined to be a label track.
void TrackPanel::HandleGlyphDragRelease(LabelTrack * lTrack, wxMouseEvent & event)
{
if (!lTrack)
return;
/// \todo This method is one of a large number of methods in
/// TrackPanel which suitably modified belong in other classes.
if (event.Dragging()) {
;
}
else if (event.LeftUp())
SetCapturedTrack(NULL);
if (lTrack->HandleGlyphDragRelease(event, mCapturedRect,
*mViewInfo, &mViewInfo->selectedRegion)) {
MakeParentPushState(_("Modified Label"),
_("Label Edit"),
UndoPush::CONSOLIDATE);
}
// Update cursor on the screen if it is a point.
DrawOverlays(false);
mRuler->DrawOverlays(false);
//If we are adjusting a label on a labeltrack, do not do anything
//that follows. Instead, redraw the track.
RefreshTrack(lTrack);
return;
}
/// Event has happened on a track and it has been determined to be a label track.
void TrackPanel::HandleTextDragRelease(LabelTrack * lTrack, wxMouseEvent & event)
{
if (!lTrack)
return;
lTrack->HandleTextDragRelease(event);
/// \todo This method is one of a large number of methods in
/// TrackPanel which suitably modified belong in other classes.
if (event.Dragging()) {
;
}
else if (event.ButtonUp())
SetCapturedTrack(NULL);
// handle dragging
if (event.Dragging()) {
// locate the initial mouse position
if (event.LeftIsDown()) {
if (mLabelTrackStartXPos == -1) {
mLabelTrackStartXPos = event.m_x;
mLabelTrackStartYPos = event.m_y;
if ((lTrack->getSelectedIndex() != -1) &&
lTrack->OverTextBox(
lTrack->GetLabel(lTrack->getSelectedIndex()),
mLabelTrackStartXPos,
mLabelTrackStartYPos))
{
mLabelTrackStartYPos = -1;
}
}
// if initial mouse position in the text box
// then only drag text
if (mLabelTrackStartYPos == -1) {
RefreshTrack(lTrack);
return;
}
}
}
// handle mouse left button up
if (event.LeftUp()) {
mLabelTrackStartXPos = -1;
}
}
// AS: I don't really understand why this code is sectioned off
// from the other OnMouseEvent code.
void TrackPanel::HandleTrackSpecificMouseEvent(wxMouseEvent & event)
@ -3605,16 +3311,6 @@ void TrackPanel::HandleTrackSpecificMouseEvent(wxMouseEvent & event)
// To do: remove the following special things
// so that we can coalesce the code for track and non-track clicks
//Determine if user clicked on a label track.
//If so, use MouseDown handler for the label track.
if (!mUIHandle &&
pTrack && foundCell.type == CellType::Track &&
(pTrack->GetKind() == Track::Label))
{
if (HandleLabelTrackClick((LabelTrack *)pTrack, rect, event))
return;
}
bool handled = false;
ToolsToolBar * pTtb = mListener->TP_GetToolsToolBar();

View File

@ -337,9 +337,6 @@ class AUDACITY_DLL_API TrackPanel final : public OverlayPanel {
virtual bool IsAudioActive();
virtual bool IsUnsafe();
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 void HandleTrackSpecificMouseEvent(wxMouseEvent & event);
virtual void ScrollDuringDrag();
@ -424,12 +421,9 @@ protected:
#endif
virtual void SelectTracksByLabel( LabelTrack *t );
protected:
// AS: Cursor handling
virtual bool SetCursorByActivity( );
virtual void SetCursorAndTipWhenInLabelTrack( LabelTrack * pLT, const wxMouseEvent & event, wxString &tip );
virtual void SetCursorAndTipWhenSelectTool
( Track * t, const wxMouseEvent & event, const wxRect &rect, bool bMultiToolMode, wxString &tip, const wxCursor ** ppCursor );
virtual void SetCursorAndTipByTool( int tool, const wxMouseEvent & event, wxString &tip );
@ -520,9 +514,6 @@ public:
static bool HasSoloButton(){ return gSoloPref!=wxT("None");}
protected:
//JKC: These two belong in the label track.
int mLabelTrackStartXPos;
int mLabelTrackStartYPos;
TrackInfo mTrackInfo;
@ -676,8 +667,6 @@ public:
IsUncaptured=0, // This is the normal state for the mouse
IsClosing,
IsSelecting,
IsAdjustingLabel,
IsSelectingLabelText,
IsMuting,
IsSoloing,
IsMinimizing,

View File

@ -0,0 +1,181 @@
/**********************************************************************
Audacity: A Digital Audio Editor
LabelDefaultClickHandle.cpp
Paul Licameli split from TrackPanel.cpp
**********************************************************************/
#include "../../../Audacity.h"
#include "LabelDefaultClickHandle.h"
#include "../../../HitTestResult.h"
#include "../../../LabelTrack.h"
#include "../../../Project.h"
#include "../../../RefreshCode.h"
#include "../../../TrackPanelMouseEvent.h"
#include "../../../ViewInfo.h"
LabelDefaultClickHandle::LabelDefaultClickHandle()
{
}
LabelDefaultClickHandle &LabelDefaultClickHandle::Instance()
{
static LabelDefaultClickHandle instance;
return instance;
}
LabelDefaultClickHandle::~LabelDefaultClickHandle()
{
}
struct LabelDefaultClickHandle::LabelState {
std::vector< std::pair< LabelTrack*, LabelTrack::Flags > > mPairs;
};
void LabelDefaultClickHandle::SaveState( AudacityProject *pProject )
{
mLabelState = std::make_unique<LabelState>();
auto &pairs = mLabelState->mPairs;
TrackList *const tracks = pProject->GetTracks();
TrackListIterator iter(tracks);
Track *n = iter.First();
while (n) {
if (n->GetKind() == Track::Label) {
LabelTrack *const lt = static_cast<LabelTrack*>(n);
pairs.push_back( std::make_pair( lt, lt->SaveFlags() ) );
}
n = iter.Next();
}
}
void LabelDefaultClickHandle::UpdateState( AudacityProject *pProject )
{
if ( mLabelState ) {
auto trackList = pProject->GetTracks();
auto &pairs = mLabelState->mPairs;
auto it = pairs.begin();
while ( it != pairs.end() ) {
if ( trackList->Contains( it->first ) )
++it;
else
it = pairs.erase( it );
}
}
}
void LabelDefaultClickHandle::RestoreState( AudacityProject *pProject )
{
if ( mLabelState ) {
for ( const auto &pair : mLabelState->mPairs )
pair.first->RestoreFlags( pair.second );
mLabelState.reset();
}
}
void LabelDefaultClickHandle::DoClick
(const wxMouseEvent &event, AudacityProject *pProject, TrackPanelCell *pCell)
{
LabelTrack *pLT = static_cast<LabelTrack*>(pCell);
if (event.LeftDown())
{
SaveState( pProject );
TrackList *const tracks = pProject->GetTracks();
TrackListIterator iter(tracks);
Track *n = iter.First();
while (n) {
if (n->GetKind() == Track::Label && pCell != n) {
LabelTrack *const lt = static_cast<LabelTrack*>(n);
lt->ResetFlags();
lt->Unselect();
}
n = iter.Next();
}
}
}
UIHandle::Result LabelDefaultClickHandle::Click
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
{
using namespace RefreshCode;
// Redraw to show the change of text box selection status
UIHandle::Result result = RefreshAll;
DoClick(evt.event, pProject, evt.pCell);
if (mpForward)
result |= mpForward->Click(evt, pProject);
else
// No drag or release follows
result |= Cancelled;
return result;
}
UIHandle::Result LabelDefaultClickHandle::Drag
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
{
if (mpForward)
return mpForward->Drag(evt, pProject);
else
return RefreshCode::RefreshNone;
}
HitTestPreview LabelDefaultClickHandle::Preview
(const TrackPanelMouseEvent &evt, const AudacityProject *pProject)
{
if (mpForward)
return mpForward->Preview(evt, pProject);
else
return {};
}
UIHandle::Result LabelDefaultClickHandle::Release
(const TrackPanelMouseEvent &evt, AudacityProject *pProject,
wxWindow *pParent)
{
mLabelState.reset();
if (mpForward)
return mpForward->Release(evt, pProject, pParent);
else
return RefreshCode::RefreshNone;
}
UIHandle::Result LabelDefaultClickHandle::Cancel(AudacityProject *pProject)
{
UIHandle::Result result = RefreshCode::RefreshNone;
if (mpForward)
result |= mpForward->Cancel(pProject);
RestoreState( pProject );
return result;
}
void LabelDefaultClickHandle::DrawExtras
(DrawingPass pass,
wxDC * dc, const wxRegion &updateRegion, const wxRect &panelRect)
{
UIHandle::DrawExtras(pass, dc, updateRegion, panelRect);
if (mpForward)
mpForward->DrawExtras(pass, dc, updateRegion, panelRect);
}
bool LabelDefaultClickHandle::StopsOnKeystroke()
{
return
(mpForward && mpForward->StopsOnKeystroke()) ||
UIHandle::StopsOnKeystroke();
}
void LabelDefaultClickHandle::OnProjectChange(AudacityProject *pProject)
{
UpdateState( pProject );
if (mpForward)
return mpForward->OnProjectChange(pProject);
UIHandle::OnProjectChange(pProject);
}

View File

@ -0,0 +1,70 @@
/**********************************************************************
Audacity: A Digital Audio Editor
LabelDefaultClickHandle.h
Paul Licameli split from TrackPanel.cpp
**********************************************************************/
#ifndef __AUDACITY_LABEL_DEFAULT_CLICK_HANDLE__
#define __AUDACITY_LABEL_DEFAULT_CLICK_HANDLE__
#include "../../../UIHandle.h"
#include "../../../MemoryX.h"
class wxMouseEvent;
struct HitTestResult;
class LabelTrack;
// Adds some behavior to click, then calls through to other mouse handling.
class LabelDefaultClickHandle final : public UIHandle
{
LabelDefaultClickHandle();
LabelDefaultClickHandle(const LabelDefaultClickHandle&) = delete;
LabelDefaultClickHandle &operator=(const LabelDefaultClickHandle&) = delete;
public:
static LabelDefaultClickHandle& Instance();
virtual ~LabelDefaultClickHandle();
void DoClick
(const wxMouseEvent &event, AudacityProject *pProject, TrackPanelCell *pCell);
Result Click
(const TrackPanelMouseEvent &event, AudacityProject *pProject) override;
Result Drag
(const TrackPanelMouseEvent &event, AudacityProject *pProject) override;
HitTestPreview Preview
(const TrackPanelMouseEvent &event, const AudacityProject *pProject)
override;
Result Release
(const TrackPanelMouseEvent &event, AudacityProject *pProject,
wxWindow *pParent) override;
Result Cancel(AudacityProject *pProject) override;
void DrawExtras
(DrawingPass pass,
wxDC * dc, const wxRegion &updateRegion, const wxRect &panelRect)
override;
bool StopsOnKeystroke() override;
void OnProjectChange(AudacityProject *pProject) override;
UIHandle *mpForward {};
private:
struct LabelState;
std::unique_ptr< LabelState > mLabelState;
void SaveState( AudacityProject *pProject );
void UpdateState( AudacityProject *pProject );
void RestoreState( AudacityProject *pProject );
};
#endif

View File

@ -0,0 +1,164 @@
/**********************************************************************
Audacity: A Digital Audio Editor
LabelGlyphHandle.cpp
Paul Licameli split from TrackPanel.cpp
**********************************************************************/
#include "LabelGlyphHandle.h"
#include "../../../HitTestResult.h"
#include "../../../LabelTrack.h"
#include "../../../Project.h"
#include "../../../RefreshCode.h"
#include "../../../TrackPanelMouseEvent.h"
#include "../../../UndoManager.h"
#include "../../../ViewInfo.h"
#include "../../../MemoryX.h"
#include <wx/cursor.h>
#include <wx/translation.h>
LabelGlyphHandle::LabelGlyphHandle()
{
}
LabelGlyphHandle &LabelGlyphHandle::Instance()
{
static LabelGlyphHandle instance;
return instance;
}
HitTestPreview LabelGlyphHandle::HitPreview
(bool hitCenter, unsigned refreshResult)
{
static wxCursor arrowCursor{ wxCURSOR_ARROW };
return {
(hitCenter
? _("Drag one or more label boundaries.")
: _("Drag label boundary.")),
&arrowCursor,
// Unusually, can have a non-zero third member of HitTestPreview, so that
// mouse-over highlights it.
refreshResult
};
}
HitTestResult LabelGlyphHandle::HitTest
(const wxMouseEvent &event, LabelTrack *pLT)
{
using namespace RefreshCode;
unsigned refreshResult = RefreshNone;
// Note: this has side effects on pLT!
int edge = pLT->OverGlyph(event.m_x, event.m_y);
//KLUDGE: We refresh the whole Label track when the icon hovered over
//changes colouration. Inefficient.
edge += pLT->mbHitCenter ? 4 : 0;
if (edge != pLT->mOldEdge)
{
pLT->mOldEdge = edge;
refreshResult |= RefreshCell;
}
// IF edge!=0 THEN we've set the cursor and we're done.
// signal this by setting the tip.
if (edge != 0)
{
return {
HitPreview(pLT->mbHitCenter, refreshResult),
&Instance()
};
}
else {
// An empty result, except maybe, unusually, the refresh
return {
{ wxString{}, nullptr, refreshResult },
nullptr
};
}
}
LabelGlyphHandle::~LabelGlyphHandle()
{
}
UIHandle::Result LabelGlyphHandle::Click
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
{
TrackPanelCell *const pCell = evt.pCell;
const wxMouseEvent &event = evt.event;
const wxRect &rect = evt.rect;
mpLT = static_cast<LabelTrack*>(pCell);
mRect = rect;
ViewInfo &viewInfo = pProject->GetViewInfo();
mpLT->HandleGlyphClick(event, rect, viewInfo, &viewInfo.selectedRegion);
if (! mpLT->IsAdjustingLabel() )
{
// The positive hit test should have ensured otherwise
//wxASSERT(false);
return RefreshCode::Cancelled;
}
// redraw the track.
return RefreshCode::RefreshCell;
// handle shift+ctrl down
/*if (event.ShiftDown()) { // && event.ControlDown()) {
lTrack->SetHighlightedByKey(true);
Refresh(false);
return;
}*/
return RefreshCode::RefreshNone;
}
UIHandle::Result LabelGlyphHandle::Drag
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
{
const wxMouseEvent &event = evt.event;
ViewInfo &viewInfo = pProject->GetViewInfo();
mpLT->HandleGlyphDragRelease(event, mRect, viewInfo, &viewInfo.selectedRegion);
// Refresh all so that the change of selection is redrawn in all tracks
return RefreshCode::RefreshAll | RefreshCode::DrawOverlays;
}
HitTestPreview LabelGlyphHandle::Preview
(const TrackPanelMouseEvent &evt, const AudacityProject *pProject)
{
return HitPreview(mpLT->mbHitCenter, 0);
}
UIHandle::Result LabelGlyphHandle::Release
(const TrackPanelMouseEvent &evt, AudacityProject *pProject,
wxWindow *pParent)
{
mpLT->mOldEdge = 0;
const wxMouseEvent &event = evt.event;
ViewInfo &viewInfo = pProject->GetViewInfo();
if (mpLT->HandleGlyphDragRelease(event, mRect, viewInfo, &viewInfo.selectedRegion)) {
pProject->PushState(_("Modified Label"),
_("Label Edit"),
UndoPush::CONSOLIDATE);
}
// Refresh all so that the change of selection is redrawn in all tracks
return RefreshCode::RefreshAll | RefreshCode::DrawOverlays;
}
UIHandle::Result LabelGlyphHandle::Cancel(AudacityProject *pProject)
{
mpLT->mOldEdge = 0;
pProject->RollbackState();
return RefreshCode::RefreshAll;
}

View File

@ -0,0 +1,58 @@
/**********************************************************************
Audacity: A Digital Audio Editor
LabelGlyphHandle.h
Paul Licameli split from TrackPanel.cpp
**********************************************************************/
#ifndef __AUDACITY_LABEL_GLYPH_HANDLE__
#define __AUDACITY_LABEL_GLYPH_HANDLE__
#include "../../../UIHandle.h"
#include <wx/gdicmn.h>
class wxMouseEvent;
struct HitTestResult;
class LabelTrack;
class LabelGlyphHandle final : public UIHandle
{
LabelGlyphHandle();
LabelGlyphHandle(const LabelGlyphHandle&) = delete;
LabelGlyphHandle &operator=(const LabelGlyphHandle&) = delete;
static LabelGlyphHandle& Instance();
static HitTestPreview HitPreview(bool hitCenter, unsigned refreshResult);
public:
static HitTestResult HitTest
(const wxMouseEvent &event, LabelTrack *pLT);
virtual ~LabelGlyphHandle();
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:
LabelTrack *mpLT {};
wxRect mRect {};
};
#endif

View File

@ -0,0 +1,184 @@
/**********************************************************************
Audacity: A Digital Audio Editor
LabelTextHandle.cpp
Paul Licameli split from TrackPanel.cpp
**********************************************************************/
#include "../../../Audacity.h"
#include "LabelTextHandle.h"
#include "../../../HitTestResult.h"
#include "../../../LabelTrack.h"
#include "../../../Project.h"
#include "../../../RefreshCode.h"
#include "../../../TrackPanelMouseEvent.h"
#include "../../../ViewInfo.h"
LabelTextHandle::LabelTextHandle()
{
}
LabelTextHandle &LabelTextHandle::Instance()
{
static LabelTextHandle instance;
return instance;
}
HitTestResult LabelTextHandle::HitTest(const wxMouseEvent &event, LabelTrack *pLT)
{
// If Control is down, let the select handle be hit instead
if (!event.ControlDown() &&
pLT->OverATextBox(event.m_x, event.m_y) >= 0)
// There was no cursor change or status message for mousing over a label text box
return { {}, &Instance() };
return {};
}
LabelTextHandle::~LabelTextHandle()
{
}
UIHandle::Result LabelTextHandle::Click
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
{
auto &selectionState = pProject->GetSelectionState();
TrackList *const tracks = pProject->GetTracks();
mChanger =
std::make_unique< SelectionStateChanger >( selectionState, *tracks );
TrackPanelCell *const pCell = evt.pCell;
const wxMouseEvent &event = evt.event;
ViewInfo &viewInfo = pProject->GetViewInfo();
mpLT = static_cast<LabelTrack*>(pCell);
mSelectedRegion = viewInfo.selectedRegion;
mpLT->HandleTextClick( event, evt.rect, viewInfo, &viewInfo.selectedRegion );
wxASSERT(mpLT->IsSelected());
{
// IF the user clicked a label, THEN select all other tracks by Label
TrackListIterator iter(tracks);
Track *t = iter.First();
//do nothing if at least one other track is selected
bool done = false;
while (!done && t) {
if (t->GetSelected() && t != mpLT)
done = true;
t = iter.Next();
}
if (!done) {
//otherwise, select all tracks
t = iter.First();
while (t)
{
selectionState.SelectTrack
( *pProject->GetTracks(), *t, true, true,
pProject->GetMixerBoard() );
t = iter.Next();
}
}
// Do this after, for its effect on TrackPanel's memory of last selected
// track (which affects shift-click actions)
selectionState.SelectTrack
( *pProject->GetTracks(), *mpLT, true, true,
pProject->GetMixerBoard() );
}
// PRL: bug1659 -- make selection change undo correctly
const bool unsafe = pProject->IsAudioActive();
if (!unsafe)
pProject->ModifyState(false);
return RefreshCode::RefreshCell | RefreshCode::UpdateSelection;
}
UIHandle::Result LabelTextHandle::Drag
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
{
using namespace RefreshCode;
Result result = RefreshNone;
const wxMouseEvent &event = evt.event;
if(mpLT)
mpLT->HandleTextDragRelease(event);
// locate the initial mouse position
if (event.LeftIsDown()) {
if (mLabelTrackStartXPos == -1) {
mLabelTrackStartXPos = event.m_x;
mLabelTrackStartYPos = event.m_y;
if (mpLT &&
(mpLT->getSelectedIndex() != -1) &&
mpLT->OverTextBox(
mpLT->GetLabel(mpLT->getSelectedIndex()),
mLabelTrackStartXPos,
mLabelTrackStartYPos))
mLabelTrackStartYPos = -1;
}
// if initial mouse position in the text box
// then only drag text
if (mLabelTrackStartYPos == -1)
result |= RefreshCell;
}
return result;
}
HitTestPreview LabelTextHandle::Preview
(const TrackPanelMouseEvent &evt, const AudacityProject *pProject)
{
return {};
}
UIHandle::Result LabelTextHandle::Release
(const TrackPanelMouseEvent &evt, AudacityProject *pProject,
wxWindow *pParent)
{
// Only selected a part of a text string and changed track selectedness.
// No undoable effects.
if (mChanger) {
mChanger->Commit();
mChanger.release();
}
const wxMouseEvent &event = evt.event;
if (mpLT)
mpLT->HandleTextDragRelease(event);
// handle mouse left button up
if (event.LeftUp())
mLabelTrackStartXPos = -1;
return RefreshCode::RefreshNone;
}
UIHandle::Result LabelTextHandle::Cancel( AudacityProject *pProject )
{
// Restore the selection states of tracks
// Note that we are also relying on LabelDefaultClickHandle::Cancel
// to restore the selection state of the labels in the tracks.
mChanger.release();
ViewInfo &viewInfo = pProject->GetViewInfo();
viewInfo.selectedRegion = mSelectedRegion;
return RefreshCode::RefreshAll;
}
void LabelTextHandle::OnProjectChange(AudacityProject *pProject)
{
if (! pProject->GetTracks()->Contains(mpLT)) {
mpLT = nullptr;
mRect = {};
}
UIHandle::OnProjectChange(pProject);
}

View File

@ -0,0 +1,63 @@
/**********************************************************************
Audacity: A Digital Audio Editor
LabelTextHandle.h
Paul Licameli split from TrackPanel.cpp
**********************************************************************/
#ifndef __AUDACITY_LABEL_TEXT_HANDLE__
#define __AUDACITY_LABEL_TEXT_HANDLE__
#include "../../../UIHandle.h"
#include "../../../MemoryX.h"
#include "../../../SelectedRegion.h"
#include <wx/gdicmn.h>
class wxMouseEvent;
struct HitTestResult;
class LabelTrack;
class SelectionStateChanger;
class LabelTextHandle final : public UIHandle
{
LabelTextHandle();
LabelTextHandle(const LabelTextHandle&) = delete;
LabelTextHandle &operator=(const LabelTextHandle&) = delete;
static LabelTextHandle& Instance();
public:
static HitTestResult HitTest(const wxMouseEvent &event, LabelTrack *pLT);
virtual ~LabelTextHandle();
Result Click
(const TrackPanelMouseEvent &event, AudacityProject *pProject) override;
Result Drag
(const TrackPanelMouseEvent &event, AudacityProject *pProject) override;
HitTestPreview Preview
(const TrackPanelMouseEvent &event, const AudacityProject *pProject)
override;
Result Release
(const TrackPanelMouseEvent &event, AudacityProject *pProject,
wxWindow *pParent) override;
Result Cancel(AudacityProject *pProject) override;
void OnProjectChange(AudacityProject *pProject) override;
private:
LabelTrack *mpLT {};
wxRect mRect {};
int mLabelTrackStartXPos { -1 };
int mLabelTrackStartYPos { -1 };
SelectedRegion mSelectedRegion{};
std::unique_ptr<SelectionStateChanger> mChanger;
};
#endif

View File

@ -10,15 +10,51 @@ Paul Licameli split from TrackPanel.cpp
#include "../../../LabelTrack.h"
#include "LabelTrackControls.h"
#include "LabelDefaultClickHandle.h"
#include "LabelTrackVRulerControls.h"
#include "LabelGlyphHandle.h"
#include "LabelTextHandle.h"
#include "../../../HitTestResult.h"
#include "../../../TrackPanelMouseEvent.h"
HitTestResult LabelTrack::HitTest
(const TrackPanelMouseEvent &event,
(const TrackPanelMouseEvent &evt,
const AudacityProject *pProject)
{
return Track::HitTest(event, pProject);
// PRL: Maybe I did too much work to preserve old behavior, but anyway,
// this unusually combines parts of two or more hit test results.
HitTestResult result;
const wxMouseEvent &event = evt.event;
// Try label movement handles first
result = LabelGlyphHandle::HitTest(event, this);
// Hit test may request refresh even if a miss
auto refreshResult = result.preview.refreshCode;
if ( !result.handle ) {
// Missed glyph, try text box
// This hit test does not define its own messages or cursor
HitTestResult defaultResult = Track::HitTest(evt, pProject);
result = LabelTextHandle::HitTest(event, this);
if (result.handle)
// Use any cursor or status message change from catchall,
// But let the text ui handle pass
result.preview = defaultResult.preview;
else
result = defaultResult;
}
// Now attach some common extra work to the click action
LabelDefaultClickHandle::Instance().mpForward = result.handle;
result.handle = &LabelDefaultClickHandle::Instance();
// Don't lose the refresh result side effect of the glyph
// hit test
result.preview.refreshCode |= refreshResult;
return result;
}
TrackControls *LabelTrack::GetControls()

View File

@ -225,6 +225,9 @@
<ClCompile Include="..\..\..\src\TrackPanel.cpp" />
<ClCompile Include="..\..\..\src\TrackPanelAx.cpp" />
<ClCompile Include="..\..\..\src\TrackPanelResizeHandle.cpp" />
<ClCompile Include="..\..\..\src\tracks\labeltrack\ui\LabelDefaultClickHandle.cpp" />
<ClCompile Include="..\..\..\src\tracks\labeltrack\ui\LabelGlyphHandle.cpp" />
<ClCompile Include="..\..\..\src\tracks\labeltrack\ui\LabelTextHandle.cpp" />
<ClCompile Include="..\..\..\src\tracks\labeltrack\ui\LabelTrackControls.cpp" />
<ClCompile Include="..\..\..\src\tracks\labeltrack\ui\LabelTrackUI.cpp" />
<ClCompile Include="..\..\..\src\tracks\labeltrack\ui\LabelTrackVRulerControls.cpp" />
@ -509,6 +512,9 @@
<ClInclude Include="..\..\..\src\tracks\playabletrack\wavetrack\ui\WaveTrackSliderHandles.h" />
<ClInclude Include="..\..\..\src\tracks\playabletrack\wavetrack\ui\WaveTrackVRulerControls.h" />
<ClInclude Include="..\..\..\src\TrackPanelResizeHandle.h" />
<ClInclude Include="..\..\..\src\tracks\labeltrack\ui\LabelDefaultClickHandle.h" />
<ClInclude Include="..\..\..\src\tracks\labeltrack\ui\LabelGlyphHandle.h" />
<ClInclude Include="..\..\..\src\tracks\labeltrack\ui\LabelTextHandle.h" />
<ClInclude Include="..\..\..\src\tracks\ui\BackgroundCell.h" />
<ClInclude Include="..\..\..\src\tracks\ui\CommonTrackPanelCell.h" />
<ClInclude Include="..\..\..\src\tracks\labeltrack\ui\LabelTrackControls.h" />

View File

@ -1031,6 +1031,15 @@
<ClCompile Include="..\..\..\src\TrackPanelResizeHandle.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\tracks\labeltrack\ui\LabelTextHandle.cpp">
<Filter>src\tracks\labeltrack\ui</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\tracks\labeltrack\ui\LabelGlyphHandle.cpp">
<Filter>src\tracks\labeltrack\ui</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\tracks\labeltrack\ui\LabelDefaultClickHandle.cpp">
<Filter>src\tracks\labeltrack\ui</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\src\AboutDialog.h">
@ -2053,6 +2062,15 @@
<ClInclude Include="..\..\..\src\TrackPanelResizeHandle.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\tracks\labeltrack\ui\LabelGlyphHandle.h">
<Filter>src\tracks\labeltrack\ui</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\tracks\labeltrack\ui\LabelTextHandle.h">
<Filter>src\tracks\labeltrack\ui</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\tracks\labeltrack\ui\LabelDefaultClickHandle.h">
<Filter>src\tracks\labeltrack\ui</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Image Include="..\..\audacity.ico">