mirror of
https://github.com/cookiengineer/audacity
synced 2025-11-14 17:14:07 +01:00
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:
committed by
Paul Licameli
parent
bbfa574790
commit
efdb9889b1
181
src/tracks/labeltrack/ui/LabelDefaultClickHandle.cpp
Normal file
181
src/tracks/labeltrack/ui/LabelDefaultClickHandle.cpp
Normal 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);
|
||||
}
|
||||
70
src/tracks/labeltrack/ui/LabelDefaultClickHandle.h
Normal file
70
src/tracks/labeltrack/ui/LabelDefaultClickHandle.h
Normal 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
|
||||
164
src/tracks/labeltrack/ui/LabelGlyphHandle.cpp
Normal file
164
src/tracks/labeltrack/ui/LabelGlyphHandle.cpp
Normal 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;
|
||||
}
|
||||
58
src/tracks/labeltrack/ui/LabelGlyphHandle.h
Normal file
58
src/tracks/labeltrack/ui/LabelGlyphHandle.h
Normal 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
|
||||
184
src/tracks/labeltrack/ui/LabelTextHandle.cpp
Normal file
184
src/tracks/labeltrack/ui/LabelTextHandle.cpp
Normal 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);
|
||||
}
|
||||
63
src/tracks/labeltrack/ui/LabelTextHandle.h
Normal file
63
src/tracks/labeltrack/ui/LabelTextHandle.h
Normal 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
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user