mirror of
https://github.com/cookiengineer/audacity
synced 2025-10-29 08:43:56 +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:
@@ -758,7 +758,7 @@ void TrackPanel::Uncapture(wxMouseEvent *pEvent)
|
||||
{
|
||||
if (HasCapture())
|
||||
ReleaseMouse();
|
||||
HandleCursor( pEvent );
|
||||
HandleMotion( pEvent );
|
||||
}
|
||||
|
||||
void TrackPanel::CancelDragging()
|
||||
@@ -768,9 +768,10 @@ void TrackPanel::CancelDragging()
|
||||
auto pTrack = GetTracks()->Lock(mpClickedTrack);
|
||||
if (pTrack)
|
||||
ProcessUIHandleResult(
|
||||
this, mRuler, pTrack.get(), NULL, refreshResult);
|
||||
this, mRuler, pTrack.get(), NULL,
|
||||
refreshResult | mMouseOverUpdateFlags );
|
||||
mpClickedTrack.reset();
|
||||
mUIHandle.reset();
|
||||
mUIHandle.reset(), ClearTargets();
|
||||
Uncapture();
|
||||
}
|
||||
}
|
||||
@@ -830,7 +831,7 @@ void TrackPanel::HandleCursorForLastMouseState()
|
||||
// Come here on modifier key or mouse button transitions,
|
||||
// or on starting or stopping of play or record,
|
||||
// and change the cursor appropriately.
|
||||
HandleCursor( &mLastMouseState );
|
||||
HandleMotion( &mLastMouseState );
|
||||
}
|
||||
|
||||
bool TrackPanel::IsAudioActive()
|
||||
@@ -840,10 +841,14 @@ bool TrackPanel::IsAudioActive()
|
||||
}
|
||||
|
||||
|
||||
/// TrackPanel::HandleCursor( ) sets the cursor drawn at the mouse location.
|
||||
/// TrackPanel::HandleMotion( ) sets the cursor drawn at the mouse location,
|
||||
/// and updates the status bar message.
|
||||
/// We treat certain other changes of mouse button and key state as "motions"
|
||||
/// too, and also starting and stopping of playback or recording, all of which
|
||||
/// may cause the appropriate cursor and message to change.
|
||||
/// As this procedure checks which region the mouse is over, it is
|
||||
/// appropriate to establish the message in the status bar.
|
||||
void TrackPanel::HandleCursor( wxMouseState *pState )
|
||||
void TrackPanel::HandleMotion( wxMouseState *pState )
|
||||
{
|
||||
wxMouseState dummy;
|
||||
if (!pState)
|
||||
@@ -857,39 +862,78 @@ void TrackPanel::HandleCursor( wxMouseState *pState )
|
||||
auto &rect = foundCell.rect;
|
||||
auto &pCell = foundCell.pCell;
|
||||
const TrackPanelMouseState tpmState{ state, rect, pCell };
|
||||
HandleCursor( tpmState );
|
||||
HandleMotion( tpmState );
|
||||
}
|
||||
|
||||
void TrackPanel::HandleCursor( const TrackPanelMouseState &tpmState )
|
||||
void TrackPanel::HandleMotion( const TrackPanelMouseState &tpmState )
|
||||
{
|
||||
if ( mUIHandle ) {
|
||||
// UIHANDLE PREVIEW
|
||||
// Update status message and cursor during drag
|
||||
HitTestPreview preview = mUIHandle->Preview( tpmState, GetProject() );
|
||||
mListener->TP_DisplayStatusMessage( preview.message );
|
||||
if ( preview.cursor )
|
||||
SetCursor( *preview.cursor );
|
||||
}
|
||||
else {
|
||||
wxCursor *pCursor = NULL;
|
||||
HitTestResult result;
|
||||
auto handle = mUIHandle;
|
||||
|
||||
wxString tip;
|
||||
auto oldHandle = mLastHitTest.handle;
|
||||
auto oldCell = mLastCell.lock();
|
||||
auto newCell = tpmState.pCell;
|
||||
|
||||
auto pCell = tpmState.pCell;
|
||||
auto track = static_cast<CommonTrackPanelCell*>( pCell.get() )->FindTrack();
|
||||
if (pCell && pCursor == NULL && tip == wxString()) {
|
||||
HitTestResult hitTest( pCell->HitTest(tpmState, GetProject()) );
|
||||
tip = hitTest.preview.message;
|
||||
ProcessUIHandleResult
|
||||
(this, mRuler, track.get(), track.get(), hitTest.preview.refreshCode);
|
||||
pCursor = hitTest.preview.cursor;
|
||||
if (pCursor)
|
||||
SetCursor(*pCursor);
|
||||
std::shared_ptr<Track> newTrack;
|
||||
if ( newCell )
|
||||
newTrack = static_cast<CommonTrackPanelCell*>( newCell.get() )->FindTrack();
|
||||
|
||||
std::shared_ptr<Track> oldTrack;
|
||||
if ( oldCell )
|
||||
oldTrack = static_cast<CommonTrackPanelCell*>( oldCell.get() )->FindTrack();
|
||||
|
||||
wxString tip{};
|
||||
wxCursor *pCursor{};
|
||||
unsigned refreshCode = 0;
|
||||
|
||||
if ( !mUIHandle ) {
|
||||
// Not yet dragging.
|
||||
unsigned updateFlags = mMouseOverUpdateFlags;
|
||||
|
||||
// First check whether crossing cell to cell
|
||||
if ( newCell == oldCell )
|
||||
oldCell.reset();
|
||||
else {
|
||||
// Forget old targets
|
||||
ClearTargets();
|
||||
// Re-draw any highlighting
|
||||
if (oldCell) {
|
||||
ProcessUIHandleResult(
|
||||
this, GetRuler(), oldTrack.get(), oldTrack.get(), updateFlags);
|
||||
}
|
||||
}
|
||||
|
||||
if (pCursor != NULL || tip != wxString())
|
||||
mListener->TP_DisplayStatusMessage(tip);
|
||||
|
||||
// Now do the
|
||||
// UIHANDLE HIT TEST !
|
||||
result = newCell->HitTest(tpmState, GetProject());
|
||||
handle = result.handle;
|
||||
|
||||
mLastCell = newCell;
|
||||
mLastHitTestValid = true;
|
||||
mLastHitTest = result;
|
||||
|
||||
if (!oldCell && oldHandle != handle)
|
||||
// Did not move cell to cell, but did change the target
|
||||
refreshCode = updateFlags;
|
||||
}
|
||||
|
||||
// UIHANDLE PREVIEW
|
||||
// Update status message and cursor, whether dragging or not
|
||||
if (handle) {
|
||||
auto preview = handle->Preview( tpmState, GetProject() );
|
||||
tip = preview.message;
|
||||
pCursor = preview.cursor;
|
||||
auto code = handle->GetChangeHighlight();
|
||||
handle->SetChangeHighlight(RefreshCode::RefreshNone);
|
||||
refreshCode |= code;
|
||||
mMouseOverUpdateFlags |= code;
|
||||
}
|
||||
mListener->TP_DisplayStatusMessage(tip);
|
||||
if (pCursor)
|
||||
SetCursor( *pCursor );
|
||||
|
||||
ProcessUIHandleResult(
|
||||
this, GetRuler(), newTrack.get(), newTrack.get(), refreshCode);
|
||||
}
|
||||
|
||||
void TrackPanel::UpdateSelectionDisplay()
|
||||
@@ -1238,7 +1282,8 @@ void TrackPanel::HandleWheelRotation( TrackPanelMouseEvent &tpmEvent )
|
||||
unsigned result =
|
||||
pCell->HandleWheelRotation( tpmEvent, GetProject() );
|
||||
auto pTrack = static_cast<CommonTrackPanelCell*>(pCell.get())->FindTrack();
|
||||
ProcessUIHandleResult(this, mRuler, pTrack.get(), pTrack.get(), result);
|
||||
ProcessUIHandleResult(
|
||||
this, mRuler, pTrack.get(), pTrack.get(), result);
|
||||
}
|
||||
|
||||
/// Filter captured keys typed into LabelTracks.
|
||||
@@ -1361,6 +1406,8 @@ void TrackPanel::OnKeyUp(wxKeyEvent & event)
|
||||
/// Should handle the case when the mouse capture is lost.
|
||||
void TrackPanel::OnCaptureLost(wxMouseCaptureLostEvent & WXUNUSED(event))
|
||||
{
|
||||
ClearTargets();
|
||||
|
||||
wxMouseEvent e(wxEVT_LEFT_UP);
|
||||
|
||||
e.m_x = mMouseMostRecentX;
|
||||
@@ -1436,6 +1483,9 @@ try
|
||||
|
||||
if (event.Leaving())
|
||||
{
|
||||
if ( !mUIHandle )
|
||||
ClearTargets();
|
||||
|
||||
auto buttons =
|
||||
// Bug 1325: button state in Leaving events is unreliable on Mac.
|
||||
// Poll the global state instead.
|
||||
@@ -1463,32 +1513,32 @@ try
|
||||
mUIHandle->Drag( tpmEvent, GetProject() );
|
||||
ProcessUIHandleResult
|
||||
(this, mRuler, pClickedTrack.get(), pTrack.get(), refreshResult);
|
||||
mMouseOverUpdateFlags |= refreshResult;
|
||||
if (refreshResult & RefreshCode::Cancelled) {
|
||||
// Drag decided to abort itself
|
||||
mUIHandle.reset();
|
||||
mUIHandle.reset(), ClearTargets();
|
||||
mpClickedTrack.reset();
|
||||
Uncapture( &event );
|
||||
}
|
||||
else {
|
||||
TrackPanelMouseState tpmState{
|
||||
tpmEvent.event,
|
||||
tpmEvent.rect,
|
||||
tpmEvent.pCell
|
||||
};
|
||||
HandleCursor( tpmState );
|
||||
UpdateMouseState(event);
|
||||
TrackPanelMouseState tpmState{ mLastMouseState, rect, pCell };
|
||||
HandleMotion( tpmState );
|
||||
}
|
||||
}
|
||||
else if (event.ButtonUp()) {
|
||||
// UIHANDLE RELEASE
|
||||
auto uiHandle = mUIHandle;
|
||||
// Null this pointer out first before calling Release -- because on Windows, we can
|
||||
// Null mUIHandle out first before calling Release -- because on Windows, we can
|
||||
// come back recursively to this place during handling of the context menu,
|
||||
// because of a capture lost event.
|
||||
mUIHandle.reset();
|
||||
unsigned moreFlags = mMouseOverUpdateFlags;
|
||||
mUIHandle.reset(), ClearTargets();
|
||||
UIHandle::Result refreshResult =
|
||||
uiHandle->Release( tpmEvent, GetProject(), this );
|
||||
ProcessUIHandleResult
|
||||
(this, mRuler, pClickedTrack.get(), pTrack.get(), refreshResult);
|
||||
(this, mRuler, pClickedTrack.get(), pTrack.get(),
|
||||
refreshResult | moreFlags);
|
||||
mpClickedTrack.reset();
|
||||
// will also Uncapture() below
|
||||
}
|
||||
@@ -1498,7 +1548,7 @@ try
|
||||
// consider it not a drag, even if button is down during motion, if
|
||||
// mUIHandle is null, as it becomes during interrupted drag
|
||||
// (e.g. by hitting space to play while dragging an envelope point)
|
||||
HandleCursor( &event );
|
||||
HandleMotion( &event );
|
||||
else if ( event.ButtonDown() || event.ButtonDClick() )
|
||||
HandleClick( tpmEvent );
|
||||
|
||||
@@ -1538,32 +1588,44 @@ void TrackPanel::HandleClick( const TrackPanelMouseEvent &tpmEvent )
|
||||
const auto &rect = tpmEvent.rect;
|
||||
auto pTrack = static_cast<CommonTrackPanelCell *>( pCell.get() )->FindTrack();
|
||||
|
||||
if ( !mUIHandle && pCell ) {
|
||||
// Do hit test once more, in case the button really pressed was not the
|
||||
// one "anticipated."
|
||||
{
|
||||
TrackPanelMouseState tpmState{
|
||||
tpmEvent.event,
|
||||
tpmEvent.rect,
|
||||
tpmEvent.pCell
|
||||
};
|
||||
mUIHandle =
|
||||
pCell->HitTest( tpmState, GetProject() ).handle;
|
||||
HandleMotion( tpmState );
|
||||
}
|
||||
|
||||
auto target = Target();
|
||||
if (target)
|
||||
mUIHandle = target->handle;
|
||||
else
|
||||
mUIHandle = {};
|
||||
|
||||
if (mUIHandle) {
|
||||
// UIHANDLE CLICK
|
||||
UIHandle::Result refreshResult =
|
||||
mUIHandle->Click( tpmEvent, GetProject() );
|
||||
if (refreshResult & RefreshCode::Cancelled)
|
||||
mUIHandle.reset();
|
||||
else
|
||||
mUIHandle.reset(), ClearTargets();
|
||||
else {
|
||||
mpClickedTrack = pTrack;
|
||||
ProcessUIHandleResult
|
||||
(this, mRuler, pTrack.get(), pTrack.get(), refreshResult);
|
||||
TrackPanelMouseState tpmState{
|
||||
tpmEvent.event,
|
||||
tpmEvent.rect,
|
||||
tpmEvent.pCell
|
||||
};
|
||||
HandleCursor( tpmState );
|
||||
|
||||
// Perhaps the clicked handle wants to update cursor and state message
|
||||
// after a click.
|
||||
TrackPanelMouseState tpmState{
|
||||
tpmEvent.event,
|
||||
tpmEvent.rect,
|
||||
tpmEvent.pCell
|
||||
};
|
||||
HandleMotion( tpmState );
|
||||
}
|
||||
ProcessUIHandleResult(
|
||||
this, mRuler, pTrack.get(), pTrack.get(), refreshResult);
|
||||
mMouseOverUpdateFlags |= refreshResult;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1574,6 +1636,9 @@ double TrackPanel::GetMostRecentXPos()
|
||||
|
||||
void TrackPanel::RefreshTrack(Track *trk, bool refreshbacking)
|
||||
{
|
||||
if (!trk)
|
||||
return;
|
||||
|
||||
Track *link = trk->GetLink();
|
||||
|
||||
if (link && !trk->GetLinked()) {
|
||||
|
||||
Reference in New Issue
Block a user