mirror of
https://github.com/cookiengineer/audacity
synced 2025-07-26 09:28:07 +02:00
Changed hit test priorities; message, cursor for text box mouse-over
This commit is contained in:
commit
1c0af82903
@ -121,9 +121,10 @@ class AUDACITY_DLL_API LabelTrack final : public Track
|
|||||||
|
|
||||||
virtual ~ LabelTrack();
|
virtual ~ LabelTrack();
|
||||||
|
|
||||||
HitTestResult HitTest
|
HitTestResult DetailedHitTest
|
||||||
(const TrackPanelMouseEvent &event,
|
(const TrackPanelMouseEvent &event,
|
||||||
const AudacityProject *pProject) override;
|
const AudacityProject *pProject, int currentTool, bool bMultiTool)
|
||||||
|
override;
|
||||||
|
|
||||||
bool DoCaptureKey(wxKeyEvent &event);
|
bool DoCaptureKey(wxKeyEvent &event);
|
||||||
unsigned CaptureKey
|
unsigned CaptureKey
|
||||||
|
@ -68,9 +68,10 @@ class AUDACITY_DLL_API NoteTrack final
|
|||||||
NoteTrack(const std::shared_ptr<DirManager> &projDirManager);
|
NoteTrack(const std::shared_ptr<DirManager> &projDirManager);
|
||||||
virtual ~NoteTrack();
|
virtual ~NoteTrack();
|
||||||
|
|
||||||
HitTestResult HitTest
|
HitTestResult DetailedHitTest
|
||||||
(const TrackPanelMouseEvent &event,
|
(const TrackPanelMouseEvent &event,
|
||||||
const AudacityProject *pProject) override;
|
const AudacityProject *pProject, int currentTool, bool bMultiTool)
|
||||||
|
override;
|
||||||
|
|
||||||
using Holder = std::unique_ptr<NoteTrack>;
|
using Holder = std::unique_ptr<NoteTrack>;
|
||||||
Track::Holder Duplicate() const override;
|
Track::Holder Duplicate() const override;
|
||||||
|
@ -49,9 +49,10 @@ class TimeTrack final : public Track {
|
|||||||
void Silence(double t0, double t1) override;
|
void Silence(double t0, double t1) override;
|
||||||
void InsertSilence(double t, double len) override;
|
void InsertSilence(double t, double len) override;
|
||||||
|
|
||||||
HitTestResult HitTest
|
HitTestResult DetailedHitTest
|
||||||
(const TrackPanelMouseEvent &event,
|
(const TrackPanelMouseEvent &event,
|
||||||
const AudacityProject *pProject) override;
|
const AudacityProject *pProject, int currentTool, bool bMultiTool)
|
||||||
|
override;
|
||||||
|
|
||||||
// Identifying the type of track
|
// Identifying the type of track
|
||||||
int GetKind() const override { return Time; }
|
int GetKind() const override { return Time; }
|
||||||
|
18
src/Track.h
18
src/Track.h
@ -108,7 +108,6 @@ class AUDACITY_DLL_API Track /* not final */
|
|||||||
bool mMinimized;
|
bool mMinimized;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
mutable wxSize vrulerSize;
|
|
||||||
|
|
||||||
// Given a bare pointer, find a shared_ptr. But this is not possible for
|
// Given a bare pointer, find a shared_ptr. But this is not possible for
|
||||||
// a track not owned by any list, so the result can be null.
|
// a track not owned by any list, so the result can be null.
|
||||||
@ -131,11 +130,22 @@ class AUDACITY_DLL_API Track /* not final */
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// An implementation is defined for call-through from subclasses, but
|
// Cause certain overriding tool modes (Zoom; future ones?) to behave
|
||||||
// the inherited method is still marked pure virtual
|
// uniformly in all tracks, disregarding track contents.
|
||||||
|
// Do not further override this...
|
||||||
HitTestResult HitTest
|
HitTestResult HitTest
|
||||||
(const TrackPanelMouseEvent &, const AudacityProject *pProject)
|
(const TrackPanelMouseEvent &, const AudacityProject *pProject)
|
||||||
override = 0;
|
final;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Rather override this for subclasses:
|
||||||
|
virtual HitTestResult DetailedHitTest
|
||||||
|
(const TrackPanelMouseEvent &,
|
||||||
|
const AudacityProject *pProject, int currentTool, bool bMultiTool)
|
||||||
|
= 0;
|
||||||
|
|
||||||
|
mutable wxSize vrulerSize;
|
||||||
|
|
||||||
// Return another, associated TrackPanelCell object that implements the
|
// Return another, associated TrackPanelCell object that implements the
|
||||||
// drop-down, close and minimize buttons, etc.
|
// drop-down, close and minimize buttons, etc.
|
||||||
|
@ -103,9 +103,10 @@ class AUDACITY_DLL_API WaveTrack final : public PlayableTrack {
|
|||||||
|
|
||||||
virtual ~WaveTrack();
|
virtual ~WaveTrack();
|
||||||
|
|
||||||
HitTestResult HitTest
|
HitTestResult DetailedHitTest
|
||||||
(const TrackPanelMouseEvent &event,
|
(const TrackPanelMouseEvent &event,
|
||||||
const AudacityProject *pProject) override;
|
const AudacityProject *pProject, int currentTool, bool bMultiTool)
|
||||||
|
override;
|
||||||
|
|
||||||
double GetOffset() const override;
|
double GetOffset() const override;
|
||||||
void SetOffset(double o) override;
|
void SetOffset(double o) override;
|
||||||
|
@ -21,12 +21,6 @@ LabelDefaultClickHandle::LabelDefaultClickHandle()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
LabelDefaultClickHandle &LabelDefaultClickHandle::Instance()
|
|
||||||
{
|
|
||||||
static LabelDefaultClickHandle instance;
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
LabelDefaultClickHandle::~LabelDefaultClickHandle()
|
LabelDefaultClickHandle::~LabelDefaultClickHandle()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -65,12 +59,16 @@ void LabelDefaultClickHandle::RestoreState( AudacityProject *pProject )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LabelDefaultClickHandle::DoClick
|
UIHandle::Result LabelDefaultClickHandle::Click
|
||||||
(const wxMouseEvent &event, AudacityProject *pProject, TrackPanelCell *pCell)
|
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
|
||||||
{
|
{
|
||||||
LabelTrack *pLT = static_cast<LabelTrack*>(pCell);
|
using namespace RefreshCode;
|
||||||
|
// Redraw to show the change of text box selection status
|
||||||
|
UIHandle::Result result = RefreshAll;
|
||||||
|
|
||||||
if (event.LeftDown())
|
LabelTrack *pLT = static_cast<LabelTrack*>(evt.pCell);
|
||||||
|
|
||||||
|
if (evt.event.LeftDown())
|
||||||
{
|
{
|
||||||
SaveState( pProject );
|
SaveState( pProject );
|
||||||
|
|
||||||
@ -79,7 +77,7 @@ void LabelDefaultClickHandle::DoClick
|
|||||||
Track *n = iter.First();
|
Track *n = iter.First();
|
||||||
|
|
||||||
while (n) {
|
while (n) {
|
||||||
if (n->GetKind() == Track::Label && pCell != n) {
|
if (n->GetKind() == Track::Label && evt.pCell != n) {
|
||||||
LabelTrack *const lt = static_cast<LabelTrack*>(n);
|
LabelTrack *const lt = static_cast<LabelTrack*>(n);
|
||||||
lt->ResetFlags();
|
lt->ResetFlags();
|
||||||
lt->Unselect();
|
lt->Unselect();
|
||||||
@ -87,22 +85,6 @@ void LabelDefaultClickHandle::DoClick
|
|||||||
n = iter.Next();
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
@ -110,19 +92,7 @@ UIHandle::Result LabelDefaultClickHandle::Click
|
|||||||
UIHandle::Result LabelDefaultClickHandle::Drag
|
UIHandle::Result LabelDefaultClickHandle::Drag
|
||||||
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
|
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
|
||||||
{
|
{
|
||||||
if (mpForward)
|
return RefreshCode::RefreshNone;
|
||||||
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
|
UIHandle::Result LabelDefaultClickHandle::Release
|
||||||
@ -130,40 +100,12 @@ UIHandle::Result LabelDefaultClickHandle::Release
|
|||||||
wxWindow *pParent)
|
wxWindow *pParent)
|
||||||
{
|
{
|
||||||
mLabelState.reset();
|
mLabelState.reset();
|
||||||
if (mpForward)
|
return RefreshCode::RefreshNone;
|
||||||
return mpForward->Release(evt, pProject, pParent);
|
|
||||||
else
|
|
||||||
return RefreshCode::RefreshNone;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UIHandle::Result LabelDefaultClickHandle::Cancel(AudacityProject *pProject)
|
UIHandle::Result LabelDefaultClickHandle::Cancel(AudacityProject *pProject)
|
||||||
{
|
{
|
||||||
UIHandle::Result result = RefreshCode::RefreshNone;
|
UIHandle::Result result = RefreshCode::RefreshNone;
|
||||||
if (mpForward)
|
|
||||||
result |= mpForward->Cancel(pProject);
|
|
||||||
RestoreState( pProject );
|
RestoreState( pProject );
|
||||||
return result;
|
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)
|
|
||||||
{
|
|
||||||
if (mpForward)
|
|
||||||
return mpForward->OnProjectChange(pProject);
|
|
||||||
UIHandle::OnProjectChange(pProject);
|
|
||||||
}
|
|
||||||
|
@ -18,29 +18,24 @@ class wxMouseEvent;
|
|||||||
struct HitTestResult;
|
struct HitTestResult;
|
||||||
class LabelTrack;
|
class LabelTrack;
|
||||||
|
|
||||||
// Adds some behavior to click, then calls through to other mouse handling.
|
// Used as a base class.
|
||||||
class LabelDefaultClickHandle final : public UIHandle
|
// Adds some behavior to clicks.
|
||||||
|
class LabelDefaultClickHandle /* not final */ : public UIHandle
|
||||||
{
|
{
|
||||||
LabelDefaultClickHandle();
|
|
||||||
LabelDefaultClickHandle(const LabelDefaultClickHandle&) = delete;
|
LabelDefaultClickHandle(const LabelDefaultClickHandle&) = delete;
|
||||||
LabelDefaultClickHandle &operator=(const LabelDefaultClickHandle&) = delete;
|
LabelDefaultClickHandle &operator=(const LabelDefaultClickHandle&) = delete;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static LabelDefaultClickHandle& Instance();
|
LabelDefaultClickHandle();
|
||||||
virtual ~LabelDefaultClickHandle();
|
virtual ~LabelDefaultClickHandle();
|
||||||
|
|
||||||
void DoClick
|
|
||||||
(const wxMouseEvent &event, AudacityProject *pProject, TrackPanelCell *pCell);
|
|
||||||
|
|
||||||
Result Click
|
Result Click
|
||||||
(const TrackPanelMouseEvent &event, AudacityProject *pProject) override;
|
(const TrackPanelMouseEvent &event, AudacityProject *pProject) override;
|
||||||
|
|
||||||
Result Drag
|
Result Drag
|
||||||
(const TrackPanelMouseEvent &event, AudacityProject *pProject) override;
|
(const TrackPanelMouseEvent &event, AudacityProject *pProject) override;
|
||||||
|
|
||||||
HitTestPreview Preview
|
// does not override Preview()
|
||||||
(const TrackPanelMouseEvent &event, const AudacityProject *pProject)
|
|
||||||
override;
|
|
||||||
|
|
||||||
Result Release
|
Result Release
|
||||||
(const TrackPanelMouseEvent &event, AudacityProject *pProject,
|
(const TrackPanelMouseEvent &event, AudacityProject *pProject,
|
||||||
@ -48,17 +43,6 @@ public:
|
|||||||
|
|
||||||
Result Cancel(AudacityProject *pProject) 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:
|
private:
|
||||||
struct LabelState;
|
struct LabelState;
|
||||||
std::unique_ptr< LabelState > mLabelState;
|
std::unique_ptr< LabelState > mLabelState;
|
||||||
|
@ -8,6 +8,7 @@ Paul Licameli split from TrackPanel.cpp
|
|||||||
|
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
|
#include "../../../Audacity.h"
|
||||||
#include "LabelGlyphHandle.h"
|
#include "LabelGlyphHandle.h"
|
||||||
#include "../../../HitTestResult.h"
|
#include "../../../HitTestResult.h"
|
||||||
#include "../../../LabelTrack.h"
|
#include "../../../LabelTrack.h"
|
||||||
@ -90,6 +91,8 @@ LabelGlyphHandle::~LabelGlyphHandle()
|
|||||||
UIHandle::Result LabelGlyphHandle::Click
|
UIHandle::Result LabelGlyphHandle::Click
|
||||||
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
|
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
|
||||||
{
|
{
|
||||||
|
auto result = LabelDefaultClickHandle::Click( evt, pProject );
|
||||||
|
|
||||||
TrackPanelCell *const pCell = evt.pCell;
|
TrackPanelCell *const pCell = evt.pCell;
|
||||||
const wxMouseEvent &event = evt.event;
|
const wxMouseEvent &event = evt.event;
|
||||||
const wxRect &rect = evt.rect;
|
const wxRect &rect = evt.rect;
|
||||||
@ -104,11 +107,11 @@ UIHandle::Result LabelGlyphHandle::Click
|
|||||||
{
|
{
|
||||||
// The positive hit test should have ensured otherwise
|
// The positive hit test should have ensured otherwise
|
||||||
//wxASSERT(false);
|
//wxASSERT(false);
|
||||||
return RefreshCode::Cancelled;
|
result |= RefreshCode::Cancelled;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
// redraw the track.
|
// redraw the track.
|
||||||
return RefreshCode::RefreshCell;
|
result |= RefreshCode::RefreshCell;
|
||||||
|
|
||||||
// handle shift+ctrl down
|
// handle shift+ctrl down
|
||||||
/*if (event.ShiftDown()) { // && event.ControlDown()) {
|
/*if (event.ShiftDown()) { // && event.ControlDown()) {
|
||||||
@ -117,19 +120,20 @@ UIHandle::Result LabelGlyphHandle::Click
|
|||||||
return;
|
return;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
return result;
|
||||||
return RefreshCode::RefreshNone;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UIHandle::Result LabelGlyphHandle::Drag
|
UIHandle::Result LabelGlyphHandle::Drag
|
||||||
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
|
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
|
||||||
{
|
{
|
||||||
|
auto result = LabelDefaultClickHandle::Drag( evt, pProject );
|
||||||
|
|
||||||
const wxMouseEvent &event = evt.event;
|
const wxMouseEvent &event = evt.event;
|
||||||
ViewInfo &viewInfo = pProject->GetViewInfo();
|
ViewInfo &viewInfo = pProject->GetViewInfo();
|
||||||
mpLT->HandleGlyphDragRelease(event, mRect, viewInfo, &viewInfo.selectedRegion);
|
mpLT->HandleGlyphDragRelease(event, mRect, viewInfo, &viewInfo.selectedRegion);
|
||||||
|
|
||||||
// Refresh all so that the change of selection is redrawn in all tracks
|
// Refresh all so that the change of selection is redrawn in all tracks
|
||||||
return RefreshCode::RefreshAll | RefreshCode::DrawOverlays;
|
return result | RefreshCode::RefreshAll | RefreshCode::DrawOverlays;
|
||||||
}
|
}
|
||||||
|
|
||||||
HitTestPreview LabelGlyphHandle::Preview
|
HitTestPreview LabelGlyphHandle::Preview
|
||||||
@ -142,6 +146,7 @@ UIHandle::Result LabelGlyphHandle::Release
|
|||||||
(const TrackPanelMouseEvent &evt, AudacityProject *pProject,
|
(const TrackPanelMouseEvent &evt, AudacityProject *pProject,
|
||||||
wxWindow *pParent)
|
wxWindow *pParent)
|
||||||
{
|
{
|
||||||
|
auto result = LabelDefaultClickHandle::Release( evt, pProject, pParent );
|
||||||
mpLT->mOldEdge = 0;
|
mpLT->mOldEdge = 0;
|
||||||
|
|
||||||
const wxMouseEvent &event = evt.event;
|
const wxMouseEvent &event = evt.event;
|
||||||
@ -153,12 +158,13 @@ UIHandle::Result LabelGlyphHandle::Release
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Refresh all so that the change of selection is redrawn in all tracks
|
// Refresh all so that the change of selection is redrawn in all tracks
|
||||||
return RefreshCode::RefreshAll | RefreshCode::DrawOverlays;
|
return result | RefreshCode::RefreshAll | RefreshCode::DrawOverlays;
|
||||||
}
|
}
|
||||||
|
|
||||||
UIHandle::Result LabelGlyphHandle::Cancel(AudacityProject *pProject)
|
UIHandle::Result LabelGlyphHandle::Cancel(AudacityProject *pProject)
|
||||||
{
|
{
|
||||||
mpLT->mOldEdge = 0;
|
mpLT->mOldEdge = 0;
|
||||||
pProject->RollbackState();
|
pProject->RollbackState();
|
||||||
return RefreshCode::RefreshAll;
|
auto result = LabelDefaultClickHandle::Cancel( pProject );
|
||||||
|
return result | RefreshCode::RefreshAll;
|
||||||
}
|
}
|
||||||
|
@ -11,14 +11,14 @@ Paul Licameli split from TrackPanel.cpp
|
|||||||
#ifndef __AUDACITY_LABEL_GLYPH_HANDLE__
|
#ifndef __AUDACITY_LABEL_GLYPH_HANDLE__
|
||||||
#define __AUDACITY_LABEL_GLYPH_HANDLE__
|
#define __AUDACITY_LABEL_GLYPH_HANDLE__
|
||||||
|
|
||||||
#include "../../../UIHandle.h"
|
#include "LabelDefaultClickHandle.h"
|
||||||
#include <wx/gdicmn.h>
|
#include <wx/gdicmn.h>
|
||||||
|
|
||||||
class wxMouseEvent;
|
class wxMouseEvent;
|
||||||
struct HitTestResult;
|
struct HitTestResult;
|
||||||
class LabelTrack;
|
class LabelTrack;
|
||||||
|
|
||||||
class LabelGlyphHandle final : public UIHandle
|
class LabelGlyphHandle final : public LabelDefaultClickHandle
|
||||||
{
|
{
|
||||||
LabelGlyphHandle();
|
LabelGlyphHandle();
|
||||||
LabelGlyphHandle(const LabelGlyphHandle&) = delete;
|
LabelGlyphHandle(const LabelGlyphHandle&) = delete;
|
||||||
|
@ -16,6 +16,7 @@ Paul Licameli split from TrackPanel.cpp
|
|||||||
#include "../../../RefreshCode.h"
|
#include "../../../RefreshCode.h"
|
||||||
#include "../../../TrackPanelMouseEvent.h"
|
#include "../../../TrackPanelMouseEvent.h"
|
||||||
#include "../../../ViewInfo.h"
|
#include "../../../ViewInfo.h"
|
||||||
|
#include "../../../images/Cursors.h"
|
||||||
|
|
||||||
LabelTextHandle::LabelTextHandle()
|
LabelTextHandle::LabelTextHandle()
|
||||||
{
|
{
|
||||||
@ -27,13 +28,23 @@ LabelTextHandle &LabelTextHandle::Instance()
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HitTestPreview LabelTextHandle::HitPreview()
|
||||||
|
{
|
||||||
|
static auto ibeamCursor =
|
||||||
|
::MakeCursor(wxCURSOR_IBEAM, IBeamCursorXpm, 17, 16);
|
||||||
|
return {
|
||||||
|
_("Click to edit label text"),
|
||||||
|
ibeamCursor.get()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
HitTestResult LabelTextHandle::HitTest(const wxMouseEvent &event, LabelTrack *pLT)
|
HitTestResult LabelTextHandle::HitTest(const wxMouseEvent &event, LabelTrack *pLT)
|
||||||
{
|
{
|
||||||
// If Control is down, let the select handle be hit instead
|
// If Control is down, let the select handle be hit instead
|
||||||
if (!event.ControlDown() &&
|
if (!event.ControlDown() &&
|
||||||
pLT->OverATextBox(event.m_x, event.m_y) >= 0)
|
pLT->OverATextBox(event.m_x, event.m_y) >= 0)
|
||||||
// There was no cursor change or status message for mousing over a label text box
|
// There was no cursor change or status message for mousing over a label text box
|
||||||
return { {}, &Instance() };
|
return { HitPreview(), &Instance() };
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -45,6 +56,8 @@ LabelTextHandle::~LabelTextHandle()
|
|||||||
UIHandle::Result LabelTextHandle::Click
|
UIHandle::Result LabelTextHandle::Click
|
||||||
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
|
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
|
||||||
{
|
{
|
||||||
|
auto result = LabelDefaultClickHandle::Click( evt, pProject );
|
||||||
|
|
||||||
auto &selectionState = pProject->GetSelectionState();
|
auto &selectionState = pProject->GetSelectionState();
|
||||||
TrackList *const tracks = pProject->GetTracks();
|
TrackList *const tracks = pProject->GetTracks();
|
||||||
mChanger =
|
mChanger =
|
||||||
@ -98,14 +111,14 @@ UIHandle::Result LabelTextHandle::Click
|
|||||||
if (!unsafe)
|
if (!unsafe)
|
||||||
pProject->ModifyState(false);
|
pProject->ModifyState(false);
|
||||||
|
|
||||||
return RefreshCode::RefreshCell | RefreshCode::UpdateSelection;
|
return result | RefreshCode::RefreshCell | RefreshCode::UpdateSelection;
|
||||||
}
|
}
|
||||||
|
|
||||||
UIHandle::Result LabelTextHandle::Drag
|
UIHandle::Result LabelTextHandle::Drag
|
||||||
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
|
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
|
||||||
{
|
{
|
||||||
using namespace RefreshCode;
|
using namespace RefreshCode;
|
||||||
Result result = RefreshNone;
|
auto result = LabelDefaultClickHandle::Drag( evt, pProject );
|
||||||
|
|
||||||
const wxMouseEvent &event = evt.event;
|
const wxMouseEvent &event = evt.event;
|
||||||
auto pLT = mpLT.lock();
|
auto pLT = mpLT.lock();
|
||||||
@ -138,13 +151,15 @@ UIHandle::Result LabelTextHandle::Drag
|
|||||||
HitTestPreview LabelTextHandle::Preview
|
HitTestPreview LabelTextHandle::Preview
|
||||||
(const TrackPanelMouseEvent &evt, const AudacityProject *pProject)
|
(const TrackPanelMouseEvent &evt, const AudacityProject *pProject)
|
||||||
{
|
{
|
||||||
return {};
|
return HitPreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
UIHandle::Result LabelTextHandle::Release
|
UIHandle::Result LabelTextHandle::Release
|
||||||
(const TrackPanelMouseEvent &evt, AudacityProject *pProject,
|
(const TrackPanelMouseEvent &evt, AudacityProject *pProject,
|
||||||
wxWindow *pParent)
|
wxWindow *pParent)
|
||||||
{
|
{
|
||||||
|
auto result = LabelDefaultClickHandle::Release( evt, pProject, pParent );
|
||||||
|
|
||||||
// Only selected a part of a text string and changed track selectedness.
|
// Only selected a part of a text string and changed track selectedness.
|
||||||
// No undoable effects.
|
// No undoable effects.
|
||||||
|
|
||||||
@ -162,7 +177,7 @@ UIHandle::Result LabelTextHandle::Release
|
|||||||
if (event.LeftUp())
|
if (event.LeftUp())
|
||||||
mLabelTrackStartXPos = -1;
|
mLabelTrackStartXPos = -1;
|
||||||
|
|
||||||
return RefreshCode::RefreshNone;
|
return result | RefreshCode::RefreshNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
UIHandle::Result LabelTextHandle::Cancel( AudacityProject *pProject )
|
UIHandle::Result LabelTextHandle::Cancel( AudacityProject *pProject )
|
||||||
@ -173,5 +188,6 @@ UIHandle::Result LabelTextHandle::Cancel( AudacityProject *pProject )
|
|||||||
mChanger.release();
|
mChanger.release();
|
||||||
ViewInfo &viewInfo = pProject->GetViewInfo();
|
ViewInfo &viewInfo = pProject->GetViewInfo();
|
||||||
viewInfo.selectedRegion = mSelectedRegion;
|
viewInfo.selectedRegion = mSelectedRegion;
|
||||||
return RefreshCode::RefreshAll;
|
auto result = LabelDefaultClickHandle::Cancel( pProject );
|
||||||
|
return result | RefreshCode::RefreshAll;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ Paul Licameli split from TrackPanel.cpp
|
|||||||
#ifndef __AUDACITY_LABEL_TEXT_HANDLE__
|
#ifndef __AUDACITY_LABEL_TEXT_HANDLE__
|
||||||
#define __AUDACITY_LABEL_TEXT_HANDLE__
|
#define __AUDACITY_LABEL_TEXT_HANDLE__
|
||||||
|
|
||||||
#include "../../../UIHandle.h"
|
#include "LabelDefaultClickHandle.h"
|
||||||
#include "../../../MemoryX.h"
|
#include "../../../MemoryX.h"
|
||||||
#include "../../../SelectedRegion.h"
|
#include "../../../SelectedRegion.h"
|
||||||
#include <wx/gdicmn.h>
|
#include <wx/gdicmn.h>
|
||||||
@ -21,13 +21,15 @@ struct HitTestResult;
|
|||||||
class LabelTrack;
|
class LabelTrack;
|
||||||
class SelectionStateChanger;
|
class SelectionStateChanger;
|
||||||
|
|
||||||
class LabelTextHandle final : public UIHandle
|
class LabelTextHandle final : public LabelDefaultClickHandle
|
||||||
{
|
{
|
||||||
LabelTextHandle();
|
LabelTextHandle();
|
||||||
LabelTextHandle(const LabelTextHandle&) = delete;
|
LabelTextHandle(const LabelTextHandle&) = delete;
|
||||||
LabelTextHandle &operator=(const LabelTextHandle&) = delete;
|
LabelTextHandle &operator=(const LabelTextHandle&) = delete;
|
||||||
static LabelTextHandle& Instance();
|
static LabelTextHandle& Instance();
|
||||||
|
|
||||||
|
static HitTestPreview HitPreview();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static HitTestResult HitTest(const wxMouseEvent &event, LabelTrack *pLT);
|
static HitTestResult HitTest(const wxMouseEvent &event, LabelTrack *pLT);
|
||||||
|
|
||||||
|
@ -20,49 +20,20 @@ Paul Licameli split from TrackPanel.cpp
|
|||||||
#include "../../../HitTestResult.h"
|
#include "../../../HitTestResult.h"
|
||||||
#include "../../../Project.h"
|
#include "../../../Project.h"
|
||||||
#include "../../../TrackPanelMouseEvent.h"
|
#include "../../../TrackPanelMouseEvent.h"
|
||||||
#include "../../../toolbars/ToolsToolBar.h"
|
|
||||||
|
|
||||||
HitTestResult LabelTrack::HitTest
|
HitTestResult LabelTrack::DetailedHitTest
|
||||||
(const TrackPanelMouseEvent &evt,
|
(const TrackPanelMouseEvent &evt,
|
||||||
const AudacityProject *pProject)
|
const AudacityProject *pProject, int, bool)
|
||||||
{
|
{
|
||||||
// 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;
|
HitTestResult result;
|
||||||
const wxMouseEvent &event = evt.event;
|
const wxMouseEvent &event = evt.event;
|
||||||
|
|
||||||
// Try label movement handles first
|
// Try label movement handles first
|
||||||
result = LabelGlyphHandle::HitTest(event, this);
|
result = LabelGlyphHandle::HitTest(event, this);
|
||||||
// Hit test may request refresh even if a miss
|
|
||||||
auto refreshResult = result.preview.refreshCode;
|
|
||||||
|
|
||||||
if ( !result.handle ) {
|
if ( !result.handle )
|
||||||
// Missed glyph, try text box
|
// Missed glyph, try text box
|
||||||
// This hit test does not define its own messages or cursor
|
|
||||||
HitTestResult defaultResult = Track::HitTest(evt, pProject);
|
|
||||||
if (!defaultResult.handle) {
|
|
||||||
// In case of multi tool, default to selection.
|
|
||||||
const ToolsToolBar *const pTtb = pProject->GetToolsToolBar();
|
|
||||||
if (pTtb->IsDown(multiTool))
|
|
||||||
defaultResult = SelectHandle::HitTest(evt, pProject, this);
|
|
||||||
}
|
|
||||||
result = LabelTextHandle::HitTest(event, this);
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -21,44 +21,18 @@ Paul Licameli split from TrackPanel.cpp
|
|||||||
#include "../../../../TrackPanelMouseEvent.h"
|
#include "../../../../TrackPanelMouseEvent.h"
|
||||||
#include "../../../ui/SelectHandle.h"
|
#include "../../../ui/SelectHandle.h"
|
||||||
#include "StretchHandle.h"
|
#include "StretchHandle.h"
|
||||||
#include "../../../../toolbars/ToolsToolBar.h"
|
|
||||||
|
|
||||||
HitTestResult NoteTrack::HitTest
|
HitTestResult NoteTrack::DetailedHitTest
|
||||||
(const TrackPanelMouseEvent &event,
|
(const TrackPanelMouseEvent &event,
|
||||||
const AudacityProject *pProject)
|
const AudacityProject *pProject, int, bool )
|
||||||
{
|
{
|
||||||
const ToolsToolBar *const pTtb = pProject->GetToolsToolBar();
|
|
||||||
|
|
||||||
// If the cursor is in the hot zone for stretching, that takes precedence
|
|
||||||
// over selection, but it didn't take precedence over other hits.
|
|
||||||
// That was the old logic, and maybe I tried too hard to preserve it just so.
|
|
||||||
// PRL.
|
|
||||||
|
|
||||||
// Eligible for stretch?
|
// Eligible for stretch?
|
||||||
HitTestResult result1;
|
HitTestResult result;
|
||||||
#ifdef USE_MIDI
|
#ifdef USE_MIDI
|
||||||
StretchHandle::StretchState state;
|
StretchHandle::StretchState state;
|
||||||
result1 = StretchHandle::HitTest( event, pProject, this, state );
|
result = StretchHandle::HitTest( event, pProject, this, state );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// But some other non-select tool like zoom may take priority.
|
|
||||||
HitTestResult result = Track::HitTest(event, pProject);
|
|
||||||
if (result.preview.cursor &&
|
|
||||||
!(result1.preview.cursor && pTtb->GetCurrentTool() == selectTool))
|
|
||||||
return result;
|
|
||||||
|
|
||||||
if (pTtb->IsDown(multiTool)) {
|
|
||||||
// Default to selection
|
|
||||||
if (!result1.preview.cursor &&
|
|
||||||
NULL != (result =
|
|
||||||
SelectHandle::HitTest(event, pProject, this)).preview.cursor)
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do stretch!
|
|
||||||
if (result1.preview.cursor)
|
|
||||||
return result1;
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,47 +23,66 @@ Paul Licameli split from TrackPanel.cpp
|
|||||||
#include "SampleHandle.h"
|
#include "SampleHandle.h"
|
||||||
#include "../../../ui/TimeShiftHandle.h"
|
#include "../../../ui/TimeShiftHandle.h"
|
||||||
|
|
||||||
HitTestResult WaveTrack::HitTest
|
HitTestResult WaveTrack::DetailedHitTest
|
||||||
(const TrackPanelMouseEvent &event,
|
(const TrackPanelMouseEvent &event,
|
||||||
const AudacityProject *pProject)
|
const AudacityProject *pProject, int currentTool, bool bMultiTool)
|
||||||
{
|
{
|
||||||
// FIXME: Should similar logic apply to NoteTrack (#if defined(USE_MIDI)) ?
|
// This is the only override of Track::DetailedHitTest that still
|
||||||
// From here on the order in which we hit test determines
|
// depends on the state of the Tools toolbar.
|
||||||
// which tool takes priority in the rare cases where it
|
// If that toolbar were eliminated, this could simplify to a sequence of
|
||||||
// could be more than one.
|
// hit test routines describable by a table.
|
||||||
|
|
||||||
// This hit was always tested first no matter which tool:
|
WaveTrack *const wavetrack = static_cast<WaveTrack*>(event.pCell);
|
||||||
HitTestResult result = CutlineHandle::HitTest(event.event, event.rect, pProject, this);
|
bool isWaveform = (wavetrack->GetDisplay() == WaveTrack::Waveform);
|
||||||
if (result.preview.cursor)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
result = Track::HitTest(event, pProject);
|
if (bMultiTool && event.event.CmdDown())
|
||||||
if (result.preview.cursor)
|
// Ctrl modifier key in multi-tool overrides everything else
|
||||||
return result;
|
// (But this does not do the time shift constrained to the vertical only,
|
||||||
|
// which is what happens when you hold Ctrl in the Time Shift tool mode)
|
||||||
|
return TimeShiftHandle::HitAnywhere(pProject);
|
||||||
|
|
||||||
const ToolsToolBar *const pTtb = pProject->GetToolsToolBar();
|
// Some special targets are not drawn in spectrogram,
|
||||||
if (pTtb->IsDown(multiTool)) {
|
// so don't hit them in such views.
|
||||||
// Replicate some of the logic of TrackPanel::DetermineToolToUse
|
else if (isWaveform) {
|
||||||
int currentTool = -1;
|
HitTestResult result;
|
||||||
if (event.event.CmdDown())
|
if (NULL !=
|
||||||
result = TimeShiftHandle::HitAnywhere(pProject);
|
(result = CutlineHandle::HitTest
|
||||||
else if (NULL !=
|
(event.event, event.rect, pProject, this))
|
||||||
(result = EnvelopeHandle::WaveTrackHitTest(event.event, event.rect, pProject, this))
|
.preview.cursor)
|
||||||
.preview.cursor)
|
// This overriding test applies in all tools
|
||||||
;
|
return result;
|
||||||
else if (NULL != (result =
|
else if (bMultiTool) {
|
||||||
TimeShiftHandle::HitTest(event.event, event.rect, pProject)).preview.cursor)
|
// Conditional hit tests
|
||||||
;
|
// If Tools toolbar were eliminated, we would keep these
|
||||||
else if (NULL != (result =
|
// The priority of these, in case more than one might apply at one
|
||||||
SampleHandle::HitTest(event.event, event.rect, pProject, this)).preview.cursor)
|
// point, seems arbitrary
|
||||||
;
|
if (NULL != (result = EnvelopeHandle::WaveTrackHitTest
|
||||||
else if (NULL != (result =
|
(event.event, event.rect, pProject, *this))
|
||||||
SelectHandle::HitTest(event, pProject, this)).preview.cursor)
|
.preview.cursor)
|
||||||
// default of all other hit tests
|
;
|
||||||
;
|
else if (NULL != (result = TimeShiftHandle::HitTest
|
||||||
|
(event.event, event.rect, pProject)).preview.cursor)
|
||||||
|
// This is the hit test on the "grips" drawn left and
|
||||||
|
// right in Multi only
|
||||||
|
;
|
||||||
|
else if (NULL != (result = SampleHandle::HitTest
|
||||||
|
(event.event, event.rect, pProject, this)).preview.cursor)
|
||||||
|
;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else switch ( currentTool ) {
|
||||||
|
// Unconditional hits appropriate to the tool
|
||||||
|
// If tools toolbar were eliminated, we would eliminate these
|
||||||
|
case envelopeTool:
|
||||||
|
return EnvelopeHandle::HitAnywhere(pProject);
|
||||||
|
case drawTool:
|
||||||
|
return SampleHandle::HitAnywhere(event.event, pProject);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<TrackControls> WaveTrack::GetControls()
|
std::shared_ptr<TrackControls> WaveTrack::GetControls()
|
||||||
|
@ -13,25 +13,17 @@ Paul Licameli split from TrackPanel.cpp
|
|||||||
#include "TimeTrackVRulerControls.h"
|
#include "TimeTrackVRulerControls.h"
|
||||||
|
|
||||||
#include "../../../HitTestResult.h"
|
#include "../../../HitTestResult.h"
|
||||||
|
#include "../../../TrackPanelMouseEvent.h"
|
||||||
#include "../../../Project.h"
|
#include "../../../Project.h"
|
||||||
#include "../../../toolbars/ToolsToolBar.h"
|
|
||||||
|
|
||||||
#include "../../ui/EnvelopeHandle.h"
|
#include "../../ui/EnvelopeHandle.h"
|
||||||
|
|
||||||
HitTestResult TimeTrack::HitTest
|
HitTestResult TimeTrack::DetailedHitTest
|
||||||
(const TrackPanelMouseEvent &event,
|
(const TrackPanelMouseEvent &event,
|
||||||
const AudacityProject *pProject)
|
const AudacityProject *pProject, int, bool)
|
||||||
{
|
{
|
||||||
HitTestResult result = Track::HitTest(event, pProject);
|
return EnvelopeHandle::TimeTrackHitTest
|
||||||
if (result.preview.cursor)
|
( event.event, event.rect, pProject, *this );
|
||||||
return result;
|
|
||||||
|
|
||||||
const ToolsToolBar *const pTtb = pProject->GetToolsToolBar();
|
|
||||||
if (pTtb->IsDown(multiTool))
|
|
||||||
// No hit test --unconditional availability.
|
|
||||||
result = EnvelopeHandle::HitAnywhere(pProject);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<TrackControls> TimeTrack::GetControls()
|
std::shared_ptr<TrackControls> TimeTrack::GetControls()
|
||||||
|
@ -62,39 +62,76 @@ HitTestResult EnvelopeHandle::HitAnywhere(const AudacityProject *pProject)
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
void GetTimeTrackData
|
||||||
|
(const AudacityProject &project, const TimeTrack &tt,
|
||||||
|
double &dBRange, bool &dB, float &zoomMin, float &zoomMax)
|
||||||
|
{
|
||||||
|
const auto &viewInfo = project.GetViewInfo();
|
||||||
|
dBRange = viewInfo.dBr;
|
||||||
|
dB = tt.GetDisplayLog();
|
||||||
|
zoomMin = tt.GetRangeLower(), zoomMax = tt.GetRangeUpper();
|
||||||
|
if (dB) {
|
||||||
|
// MB: silly way to undo the work of GetWaveYPos while still getting a logarithmic scale
|
||||||
|
zoomMin = LINEAR_TO_DB(std::max(1.0e-7, double(dBRange))) / dBRange + 1.0;
|
||||||
|
zoomMax = LINEAR_TO_DB(std::max(1.0e-7, double(zoomMax))) / dBRange + 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HitTestResult EnvelopeHandle::TimeTrackHitTest
|
||||||
|
(const wxMouseEvent &event, const wxRect &rect,
|
||||||
|
const AudacityProject *pProject, TimeTrack &tt)
|
||||||
|
{
|
||||||
|
auto envelope = tt.GetEnvelope();
|
||||||
|
if (!envelope)
|
||||||
|
return {};
|
||||||
|
bool dB;
|
||||||
|
double dBRange;
|
||||||
|
float zoomMin, zoomMax;
|
||||||
|
GetTimeTrackData( *pProject, tt, dBRange, dB, zoomMin, zoomMax);
|
||||||
|
return EnvelopeHandle::HitEnvelope
|
||||||
|
(event, rect, pProject, envelope, zoomMin, zoomMax, dB, dBRange);
|
||||||
|
}
|
||||||
|
|
||||||
HitTestResult EnvelopeHandle::WaveTrackHitTest
|
HitTestResult EnvelopeHandle::WaveTrackHitTest
|
||||||
(const wxMouseEvent &event, const wxRect &rect,
|
(const wxMouseEvent &event, const wxRect &rect,
|
||||||
const AudacityProject *pProject, Cell *pCell)
|
const AudacityProject *pProject, WaveTrack &wt)
|
||||||
{
|
{
|
||||||
const ViewInfo &viewInfo = pProject->GetViewInfo();
|
|
||||||
Track *const pTrack = static_cast<Track*>(pCell);
|
|
||||||
|
|
||||||
/// method that tells us if the mouse event landed on an
|
/// method that tells us if the mouse event landed on an
|
||||||
/// envelope boundary.
|
/// envelope boundary.
|
||||||
if (pTrack->GetKind() != Track::Wave)
|
const Envelope *const envelope = wt.GetEnvelopeAtX(event.GetX());
|
||||||
return {};
|
|
||||||
|
|
||||||
WaveTrack *const wavetrack = static_cast<WaveTrack*>(pTrack);
|
|
||||||
Envelope *const envelope = wavetrack->GetEnvelopeAtX(event.GetX());
|
|
||||||
|
|
||||||
if (!envelope)
|
if (!envelope)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
const int displayType = wavetrack->GetDisplay();
|
const int displayType = wt.GetDisplay();
|
||||||
// Not an envelope hit, unless we're using a type of wavetrack display
|
// Not an envelope hit, unless we're using a type of wavetrack display
|
||||||
// suitable for envelopes operations, ie one of the Wave displays.
|
// suitable for envelopes operations, ie one of the Wave displays.
|
||||||
if (displayType != WaveTrack::Waveform)
|
if (displayType != WaveTrack::Waveform)
|
||||||
return {}; // No envelope, not a hit, so return.
|
return {}; // No envelope, not a hit, so return.
|
||||||
|
|
||||||
// Get envelope point, range 0.0 to 1.0
|
// Get envelope point, range 0.0 to 1.0
|
||||||
const bool dB = !wavetrack->GetWaveformSettings().isLinear();
|
const bool dB = !wt.GetWaveformSettings().isLinear();
|
||||||
const double envValue =
|
|
||||||
envelope->GetValue(viewInfo.PositionToTime(event.m_x, rect.x));
|
|
||||||
|
|
||||||
float zoomMin, zoomMax;
|
float zoomMin, zoomMax;
|
||||||
wavetrack->GetDisplayBounds(&zoomMin, &zoomMax);
|
wt.GetDisplayBounds(&zoomMin, &zoomMax);
|
||||||
|
|
||||||
const float dBRange = wavetrack->GetWaveformSettings().dBRange;
|
const float dBRange = wt.GetWaveformSettings().dBRange;
|
||||||
|
|
||||||
|
return EnvelopeHandle::HitEnvelope
|
||||||
|
(event, rect, pProject, envelope, zoomMin, zoomMax, dB, dBRange);
|
||||||
|
}
|
||||||
|
|
||||||
|
HitTestResult EnvelopeHandle::HitEnvelope
|
||||||
|
(const wxMouseEvent &event, const wxRect &rect, const AudacityProject *pProject,
|
||||||
|
const Envelope *envelope, float zoomMin, float zoomMax,
|
||||||
|
bool dB, float dBRange)
|
||||||
|
{
|
||||||
|
const ViewInfo &viewInfo = pProject->GetViewInfo();
|
||||||
|
|
||||||
|
const double envValue =
|
||||||
|
envelope->GetValue(viewInfo.PositionToTime(event.m_x, rect.x));
|
||||||
|
|
||||||
// Get y position of envelope point.
|
// Get y position of envelope point.
|
||||||
int yValue = GetWaveYPos(envValue,
|
int yValue = GetWaveYPos(envValue,
|
||||||
@ -187,14 +224,7 @@ UIHandle::Result EnvelopeHandle::Click
|
|||||||
auto clickedEnvelope = tt->GetEnvelope();
|
auto clickedEnvelope = tt->GetEnvelope();
|
||||||
if (!clickedEnvelope)
|
if (!clickedEnvelope)
|
||||||
return Cancelled;
|
return Cancelled;
|
||||||
mLog = tt->GetDisplayLog();
|
GetTimeTrackData( *pProject, *tt, mdBRange, mLog, mLower, mUpper);
|
||||||
mLower = tt->GetRangeLower(), mUpper = tt->GetRangeUpper();
|
|
||||||
if (mLog) {
|
|
||||||
// MB: silly way to undo the work of GetWaveYPos while still getting a logarithmic scale
|
|
||||||
mdBRange = viewInfo.dBr;
|
|
||||||
mLower = LINEAR_TO_DB(std::max(1.0e-7, double(mLower))) / mdBRange + 1.0;
|
|
||||||
mUpper = LINEAR_TO_DB(std::max(1.0e-7, double(mUpper))) / mdBRange + 1.0;
|
|
||||||
}
|
|
||||||
mEnvelopeEditor =
|
mEnvelopeEditor =
|
||||||
std::make_unique< EnvelopeEditor >( *clickedEnvelope, false );
|
std::make_unique< EnvelopeEditor >( *clickedEnvelope, false );
|
||||||
mEnvelopeEditorRight.reset();
|
mEnvelopeEditorRight.reset();
|
||||||
|
@ -17,9 +17,11 @@ Paul Licameli split from TrackPanel.cpp
|
|||||||
class wxMouseEvent;
|
class wxMouseEvent;
|
||||||
#include <wx/gdicmn.h>
|
#include <wx/gdicmn.h>
|
||||||
|
|
||||||
|
class Envelope;
|
||||||
class EnvelopeEditor;
|
class EnvelopeEditor;
|
||||||
struct HitTestResult;
|
struct HitTestResult;
|
||||||
class ViewInfo;
|
class ViewInfo;
|
||||||
|
class TimeTrack;
|
||||||
class WaveTrack;
|
class WaveTrack;
|
||||||
|
|
||||||
class EnvelopeHandle final : public UIHandle
|
class EnvelopeHandle final : public UIHandle
|
||||||
@ -30,11 +32,20 @@ class EnvelopeHandle final : public UIHandle
|
|||||||
static EnvelopeHandle& Instance();
|
static EnvelopeHandle& Instance();
|
||||||
static HitTestPreview HitPreview(const AudacityProject *pProject, bool unsafe);
|
static HitTestPreview HitPreview(const AudacityProject *pProject, bool unsafe);
|
||||||
|
|
||||||
|
static HitTestResult HitEnvelope
|
||||||
|
(const wxMouseEvent &event, const wxRect &rect,
|
||||||
|
const AudacityProject *pProject,
|
||||||
|
const Envelope *envelope, float zoomMin, float zoomMax,
|
||||||
|
bool dB, float dBRange);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static HitTestResult HitAnywhere(const AudacityProject *pProject);
|
static HitTestResult HitAnywhere(const AudacityProject *pProject);
|
||||||
|
static HitTestResult TimeTrackHitTest
|
||||||
|
(const wxMouseEvent &event, const wxRect &rect,
|
||||||
|
const AudacityProject *pProject, TimeTrack &tt);
|
||||||
static HitTestResult WaveTrackHitTest
|
static HitTestResult WaveTrackHitTest
|
||||||
(const wxMouseEvent &event, const wxRect &rect,
|
(const wxMouseEvent &event, const wxRect &rect,
|
||||||
const AudacityProject *pProject, Cell *pCell);
|
const AudacityProject *pProject, WaveTrack &wt);
|
||||||
|
|
||||||
virtual ~EnvelopeHandle();
|
virtual ~EnvelopeHandle();
|
||||||
|
|
||||||
|
@ -28,34 +28,34 @@ HitTestResult Track::HitTest
|
|||||||
const AudacityProject *pProject)
|
const AudacityProject *pProject)
|
||||||
{
|
{
|
||||||
const ToolsToolBar * pTtb = pProject->GetToolsToolBar();
|
const ToolsToolBar * pTtb = pProject->GetToolsToolBar();
|
||||||
// Unless in Multimode keep using the current tool.
|
|
||||||
const bool isMultiTool = pTtb->IsDown(multiTool);
|
const bool isMultiTool = pTtb->IsDown(multiTool);
|
||||||
if (!isMultiTool) {
|
const auto currentTool = pTtb->GetCurrentTool();
|
||||||
switch (pTtb->GetCurrentTool()) {
|
|
||||||
case envelopeTool:
|
|
||||||
// Pass "false" for unsafe -- let the tool decide to cancel itself
|
|
||||||
return EnvelopeHandle::HitAnywhere(pProject);
|
|
||||||
case drawTool:
|
|
||||||
return SampleHandle::HitAnywhere(event.event, pProject);
|
|
||||||
case zoomTool:
|
|
||||||
return ZoomHandle::HitAnywhere(event.event, pProject);
|
|
||||||
case slideTool:
|
|
||||||
return TimeShiftHandle::HitAnywhere(pProject);
|
|
||||||
case selectTool:
|
|
||||||
return SelectHandle::HitTest(event, pProject, this);
|
|
||||||
|
|
||||||
default:
|
if ( !isMultiTool && currentTool == zoomTool )
|
||||||
// fallthru
|
// Zoom tool is a non-selecting tool that takes precedence in all tracks
|
||||||
;
|
// over all other tools, no matter what detail you point at.
|
||||||
}
|
return ZoomHandle::HitAnywhere(event.event, pProject);
|
||||||
}
|
|
||||||
|
|
||||||
// Replicate some of the logic of TrackPanel::DetermineToolToUse
|
// In other tools, let subclasses determine detailed hits.
|
||||||
HitTestResult result;
|
HitTestResult result =
|
||||||
|
DetailedHitTest( event, pProject, currentTool, isMultiTool );
|
||||||
|
|
||||||
if (isMultiTool)
|
// If there is no detailed hit for the subclass, there are still some
|
||||||
|
// general cases.
|
||||||
|
|
||||||
|
// Sliding applies in more than one track type.
|
||||||
|
if ( !result.handle && !isMultiTool && currentTool == slideTool )
|
||||||
|
result = TimeShiftHandle::HitAnywhere(pProject);
|
||||||
|
|
||||||
|
// Let the multi-tool right-click handler apply only in default of all
|
||||||
|
// other detailed hits.
|
||||||
|
if ( !result.handle && isMultiTool )
|
||||||
result = ZoomHandle::HitTest(event.event, pProject);
|
result = ZoomHandle::HitTest(event.event, pProject);
|
||||||
|
|
||||||
|
// Finally, default of all is adjustment of the selection box.
|
||||||
|
if ( !result.handle && ( isMultiTool || currentTool == selectTool) )
|
||||||
|
result = SelectHandle::HitTest(event, pProject, this);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user