1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-11-14 17:14:07 +01:00

Rename TrackPanel::HandleCursor as HandleMotion...

Call HitTest in just one place

Can now preserve repeatedly hit UIHandle objects during pre-click motion

Fields of HitTestResult besides the handle pointer are now unused

The need to repaint a track during mouse movement can be indicated when
constructing a UIHandle or when updating it for move; HitPreview no longer
does this

And the last allows simplifications of LabelTrack glyph highlighting

Also move the temporary state for label glyph dragging out of LabelTrack
This commit is contained in:
Paul Licameli
2017-06-17 21:37:41 -04:00
parent 2c1a16f593
commit f5b0afc2fc
10 changed files with 336 additions and 210 deletions

View File

@@ -24,23 +24,32 @@ Paul Licameli split from TrackPanel.cpp
#include <wx/translation.h>
LabelGlyphHandle::LabelGlyphHandle
(const std::shared_ptr<LabelTrack> &pLT, const wxRect &rect)
(const std::shared_ptr<LabelTrack> &pLT,
const wxRect &rect, const LabelTrackHit &hit)
: mpLT{ pLT }
, mRect{ rect }
{}
, mHit{ hit }
{
mChangeHighlight = RefreshCode::RefreshCell;
}
HitTestPreview LabelGlyphHandle::HitPreview
(bool hitCenter, unsigned refreshResult)
UIHandle::Result LabelGlyphHandle::NeedChangeHighlight
(const LabelGlyphHandle &oldState, const LabelGlyphHandle &newState)
{
if (oldState.mHit.mEdge != newState.mHit.mEdge)
// pointer moves between the circle and the chevron
return RefreshCode::RefreshCell;
return 0;
}
HitTestPreview LabelGlyphHandle::HitPreview(bool hitCenter)
{
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
&arrowCursor
};
}
@@ -49,39 +58,22 @@ HitTestResult LabelGlyphHandle::HitTest
const wxMouseState &state,
const std::shared_ptr<LabelTrack> &pLT, const wxRect &rect)
{
using namespace RefreshCode;
unsigned refreshResult = RefreshNone;
// Note: this has side effects on pLT!
int edge = pLT->OverGlyph(state.m_x, state.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;
}
LabelTrackHit hit{};
pLT->OverGlyph(hit, state.m_x, state.m_y);
// IF edge!=0 THEN we've set the cursor and we're done.
// signal this by setting the tip.
if (edge != 0)
if ( hit.mEdge & 3 )
{
auto result = std::make_shared<LabelGlyphHandle>( pLT, rect );
auto result = std::make_shared<LabelGlyphHandle>( pLT, rect, hit );
result = AssignUIHandlePtr(holder, result);
return {
HitPreview(pLT->mbHitCenter, refreshResult),
HitPreview( hit.mEdge & 4 ),
result
};
}
else {
// An empty result, except maybe, unusually, the refresh
return {
{ wxString{}, nullptr, refreshResult },
{}
};
}
return {};
}
LabelGlyphHandle::~LabelGlyphHandle()
@@ -96,9 +88,10 @@ UIHandle::Result LabelGlyphHandle::Click
const wxMouseEvent &event = evt.event;
ViewInfo &viewInfo = pProject->GetViewInfo();
mpLT->HandleGlyphClick(event, mRect, viewInfo, &viewInfo.selectedRegion);
mpLT->HandleGlyphClick
(mHit, event, mRect, viewInfo, &viewInfo.selectedRegion);
if (! mpLT->IsAdjustingLabel() )
if (! mHit.mIsAdjustingLabel )
{
// The positive hit test should have ensured otherwise
//wxASSERT(false);
@@ -125,7 +118,8 @@ UIHandle::Result LabelGlyphHandle::Drag
const wxMouseEvent &event = evt.event;
ViewInfo &viewInfo = pProject->GetViewInfo();
mpLT->HandleGlyphDragRelease(event, mRect, viewInfo, &viewInfo.selectedRegion);
mpLT->HandleGlyphDragRelease
(mHit, event, mRect, viewInfo, &viewInfo.selectedRegion);
// Refresh all so that the change of selection is redrawn in all tracks
return result | RefreshCode::RefreshAll | RefreshCode::DrawOverlays;
@@ -134,7 +128,7 @@ UIHandle::Result LabelGlyphHandle::Drag
HitTestPreview LabelGlyphHandle::Preview
(const TrackPanelMouseState &, const AudacityProject *)
{
return HitPreview(mpLT->mbHitCenter, 0);
return HitPreview( mHit.mEdge & 4 );
}
UIHandle::Result LabelGlyphHandle::Release
@@ -142,11 +136,11 @@ UIHandle::Result LabelGlyphHandle::Release
wxWindow *pParent)
{
auto result = LabelDefaultClickHandle::Release( evt, pProject, pParent );
mpLT->mOldEdge = 0;
const wxMouseEvent &event = evt.event;
ViewInfo &viewInfo = pProject->GetViewInfo();
if (mpLT->HandleGlyphDragRelease(event, mRect, viewInfo, &viewInfo.selectedRegion)) {
if (mpLT->HandleGlyphDragRelease
(mHit, event, mRect, viewInfo, &viewInfo.selectedRegion)) {
pProject->PushState(_("Modified Label"),
_("Label Edit"),
UndoPush::CONSOLIDATE);
@@ -158,7 +152,6 @@ UIHandle::Result LabelGlyphHandle::Release
UIHandle::Result LabelGlyphHandle::Cancel(AudacityProject *pProject)
{
mpLT->mOldEdge = 0;
pProject->RollbackState();
auto result = LabelDefaultClickHandle::Cancel( pProject );
return result | RefreshCode::RefreshAll;

View File

@@ -19,14 +19,33 @@ class wxMouseState;
struct HitTestResult;
class LabelTrack;
/// mEdge:
/// 0 if not over a glyph,
/// else a bitwise or of :
/// 1 if over the left-hand glyph,
/// 2 if over the right-hand glyph on a label,
/// 4 if over center.
///
/// mMouseLabelLeft - index of any left label hit
/// mMouseLabelRight - index of any right label hit
///
struct LabelTrackHit {
int mEdge{};
int mMouseOverLabelLeft{ -1 }; /// Keeps track of which left label the mouse is currently over.
int mMouseOverLabelRight{ -1 }; /// Keeps track of which right label the mouse is currently over.
bool mbIsMoving {};
bool mIsAdjustingLabel {};
};
class LabelGlyphHandle final : public LabelDefaultClickHandle
{
LabelGlyphHandle(const LabelGlyphHandle&) = delete;
static HitTestPreview HitPreview(bool hitCenter, unsigned refreshResult);
static HitTestPreview HitPreview(bool hitCenter);
public:
explicit LabelGlyphHandle
(const std::shared_ptr<LabelTrack> &pLT, const wxRect &rect);
(const std::shared_ptr<LabelTrack> &pLT,
const wxRect &rect, const LabelTrackHit &hit);
LabelGlyphHandle &operator=(LabelGlyphHandle&&) = default;
@@ -55,6 +74,11 @@ public:
bool StopsOnKeystroke() override { return true; }
LabelTrackHit mHit{};
static UIHandle::Result NeedChangeHighlight
(const LabelGlyphHandle &oldState, const LabelGlyphHandle &newState);
private:
std::shared_ptr<LabelTrack> mpLT {};
wxRect mRect {};

View File

@@ -31,13 +31,11 @@ HitTestResult LabelTrack::DetailedHitTest
// Try label movement handles first
result = LabelGlyphHandle::HitTest(
mGlyphHandle, state, Pointer<LabelTrack>(this), st.rect);
auto refresh = result.preview.refreshCode; // kludge
if ( !result.handle ) {
// Missed glyph, try text box
result = LabelTextHandle::HitTest(
mTextHandle, state, Pointer<LabelTrack>(this));
result.preview.refreshCode |= refresh; // kludge
}
return result;

View File

@@ -46,9 +46,6 @@ HitTestResult Track::HitTest
// If there is no detailed hit for the subclass, there are still some
// general cases.
// Label track kludge!
auto refresh = result.preview.refreshCode;
// Sliding applies in more than one track type.
if ( !result.handle && !isMultiTool && currentTool == slideTool )
result = TimeShiftHandle::HitAnywhere(
@@ -65,7 +62,6 @@ HitTestResult Track::HitTest
result = SelectHandle::HitTest(
mSelectHandle, st, pProject, Pointer(this));
result.preview.refreshCode |= refresh;
return result;
}