mirror of
https://github.com/cookiengineer/audacity
synced 2025-09-18 09:00:52 +02:00
Further regularize the odd case of hit-test on the resizer region
This commit is contained in:
parent
34026d19fd
commit
a94eb75b4e
@ -854,11 +854,10 @@ void TrackPanel::HandleCursor( wxMouseEvent *pEvent )
|
||||
auto &pCell = foundCell.pCell;
|
||||
const auto size = GetSize();
|
||||
const TrackPanelMouseEvent tpmEvent{ event, rect, size, pCell };
|
||||
HandleCursor( tpmEvent, foundCell.type );
|
||||
HandleCursor( tpmEvent );
|
||||
}
|
||||
|
||||
void TrackPanel::HandleCursor
|
||||
( const TrackPanelMouseEvent &tpmEvent, CellType cellType )
|
||||
void TrackPanel::HandleCursor( const TrackPanelMouseEvent &tpmEvent )
|
||||
{
|
||||
if ( mUIHandle ) {
|
||||
// UIHANDLE PREVIEW
|
||||
@ -875,22 +874,8 @@ void TrackPanel::HandleCursor
|
||||
|
||||
// Are we within the vertical resize area?
|
||||
// (Add margin back to bottom of the rectangle)
|
||||
auto &event = tpmEvent.event;
|
||||
auto pCell = tpmEvent.pCell;
|
||||
auto track = static_cast<CommonTrackPanelCell*>( pCell )->FindTrack();
|
||||
auto &rect = tpmEvent.rect;
|
||||
if (track &&
|
||||
within(event.m_y, rect.GetBottom() + kBorderThickness, TRACK_RESIZE_REGION))
|
||||
{
|
||||
HitTestPreview preview
|
||||
( TrackPanelResizeHandle::HitPreview(
|
||||
( cellType != CellType::Label) && track->GetLinked() ) );
|
||||
tip = preview.message;
|
||||
wxCursor *const pCursor = preview.cursor;
|
||||
if (pCursor)
|
||||
SetCursor(*pCursor);
|
||||
}
|
||||
|
||||
if (pCell && pCursor == NULL && tip == wxString()) {
|
||||
const auto size = GetSize();
|
||||
HitTestResult hitTest( pCell->HitTest(tpmEvent, GetProject()) );
|
||||
@ -1524,9 +1509,7 @@ try
|
||||
|
||||
const auto foundCell = FindCell(event.m_x, event.m_y);
|
||||
auto t = foundCell.pTrack;
|
||||
if (t
|
||||
&& foundCell.type == CellType::Track
|
||||
)
|
||||
if ( t )
|
||||
EnsureVisible(t);
|
||||
}
|
||||
}
|
||||
@ -1549,19 +1532,6 @@ void TrackPanel::HandleClick( const TrackPanelMouseEvent &tpmEvent )
|
||||
const auto &rect = tpmEvent.rect;
|
||||
auto pTrack = static_cast<CommonTrackPanelCell *>( pCell )->FindTrack();
|
||||
|
||||
// see if I'm over the border area.
|
||||
// TrackPanelResizeHandle is the UIHandle subclass that TrackPanel knows
|
||||
// and uses directly, because allocating area to cells is TrackPanel's business,
|
||||
// and we implement a "hit test" directly here.
|
||||
if (mUIHandle == NULL &&
|
||||
event.LeftDown()) {
|
||||
if (pCell &&
|
||||
(within(event.m_y,
|
||||
(rect.GetBottom() + (kBottomMargin + kTopMargin) / 2),
|
||||
TRACK_RESIZE_REGION)))
|
||||
mUIHandle = &TrackPanelResizeHandle::Instance();
|
||||
}
|
||||
|
||||
if ( !mUIHandle && pCell )
|
||||
mUIHandle =
|
||||
pCell->HitTest( tpmEvent, GetProject() ).handle;
|
||||
@ -2518,9 +2488,11 @@ void TrackPanel::DrawShadow(Track * /* t */ , wxDC * dc, const wxRect & rect)
|
||||
/// @param mouseY - mouse Y position.
|
||||
TrackPanel::FoundCell TrackPanel::FindCell(int mouseX, int mouseY)
|
||||
{
|
||||
enum class CellType { Label, Track, VRuler, Background };
|
||||
auto size = GetSize();
|
||||
size.x -= kRightMargin;
|
||||
wxRect rect { 0, 0, 0, 0 };
|
||||
bool betweenTracks = false;
|
||||
|
||||
// The type of cell that may be found is determined by the x coordinate.
|
||||
CellType type = CellType::Track;
|
||||
@ -2540,9 +2512,25 @@ TrackPanel::FoundCell TrackPanel::FindCell(int mouseX, int mouseY)
|
||||
rect.width = size.x - GetLeftOffset();
|
||||
|
||||
auto output = [&](Track *pTrack) -> FoundCell {
|
||||
TrackPanelCell *pCell {};
|
||||
|
||||
// Did we actually hit in the resizer region, which encompasses the
|
||||
// bottom margin proper to "this" track, plus the top margin of the
|
||||
// "next" track (or, an equally wide zone below, in case there is no
|
||||
// next track)?
|
||||
const auto margin = kBottomMargin + kTopMargin;
|
||||
if ( rect.y + rect.height - mouseY <= margin ) {
|
||||
auto instance = &TrackPanelResizerCell::Instance();
|
||||
instance->mpTrack = pTrack;
|
||||
instance->mBetweenTracks = betweenTracks;
|
||||
pCell = instance;
|
||||
rect.y = rect.y + rect.height - kTopMargin;
|
||||
rect.height = margin;
|
||||
return { pTrack, pCell, rect };
|
||||
}
|
||||
|
||||
// Undo the bias mentioned below.
|
||||
rect.y -= kTopMargin;
|
||||
TrackPanelCell *pCell {};
|
||||
if (pTrack) switch (type) {
|
||||
case CellType::Label:
|
||||
pCell = pTrack->GetTrackControl(); break;
|
||||
@ -2552,9 +2540,9 @@ TrackPanel::FoundCell TrackPanel::FindCell(int mouseX, int mouseY)
|
||||
pCell = pTrack; break;
|
||||
}
|
||||
if (pTrack)
|
||||
return { pTrack, pCell, type, rect };
|
||||
return { pTrack, pCell, rect };
|
||||
else
|
||||
return { nullptr, nullptr, type, {} };
|
||||
return { nullptr, nullptr, {} };
|
||||
};
|
||||
|
||||
VisibleTrackIterator iter(GetProject());
|
||||
@ -2569,10 +2557,10 @@ TrackPanel::FoundCell TrackPanel::FindCell(int mouseX, int mouseY)
|
||||
if (t->GetLink()) {
|
||||
Track *l = t->GetLink();
|
||||
int h = l->GetHeight();
|
||||
if (!t->GetLinked()) {
|
||||
if (!t->GetLinked())
|
||||
rect.y = l->GetY() - mViewInfo->vpos + kTopMargin;
|
||||
else
|
||||
t = l;
|
||||
rect.y = t->GetY() - mViewInfo->vpos + kTopMargin;
|
||||
}
|
||||
rect.height += h;
|
||||
}
|
||||
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
|
||||
@ -2580,6 +2568,14 @@ TrackPanel::FoundCell TrackPanel::FindCell(int mouseX, int mouseY)
|
||||
rect.height += t->GetHeight(true);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
|
||||
if( MONO_WAVE_PAN(t) )
|
||||
betweenTracks = true;
|
||||
else
|
||||
#endif
|
||||
betweenTracks = t->GetLinked();
|
||||
}
|
||||
|
||||
//Determine whether the mouse is inside
|
||||
//the current rectangle. If so, return.
|
||||
@ -2592,6 +2588,7 @@ TrackPanel::FoundCell TrackPanel::FindCell(int mouseX, int mouseY)
|
||||
}
|
||||
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
|
||||
if(type != CellType::Label && MONO_WAVE_PAN(t)){
|
||||
betweenTracks = false;
|
||||
rect.y = t->GetY(true) - mViewInfo->vpos + kTopMargin;
|
||||
rect.height = t->GetHeight(true);
|
||||
if (rect.Contains(mouseX, mouseY)) {
|
||||
@ -2612,15 +2609,12 @@ TrackPanel::FoundCell TrackPanel::FindCell(int mouseX, int mouseY)
|
||||
rect.y =
|
||||
std::min( size.y,
|
||||
std::max( 0,
|
||||
rect.y - kTopMargin + rect.height ) );
|
||||
rect.y + rect.height ) );
|
||||
rect.height = size.y - rect.y;
|
||||
return {
|
||||
nullptr, mpBackground.get(),
|
||||
CellType::Background, rect
|
||||
};
|
||||
return { nullptr, mpBackground.get(), rect };
|
||||
}
|
||||
else
|
||||
return { nullptr, nullptr, type, {} };
|
||||
return { nullptr, nullptr, {} };
|
||||
}
|
||||
|
||||
/// This finds the rectangle of a given track, either the
|
||||
|
@ -362,19 +362,15 @@ protected:
|
||||
// a crash, as it can take many seconds for large (eg. 10 track-hours) projects
|
||||
|
||||
// Find track info by coordinate
|
||||
enum class CellType { Label, Track, VRuler, Background };
|
||||
struct FoundCell {
|
||||
Track *pTrack;
|
||||
TrackPanelCell *pCell;
|
||||
CellType type;
|
||||
wxRect rect;
|
||||
};
|
||||
FoundCell FindCell(int mouseX, int mouseY);
|
||||
|
||||
void HandleCursor( wxMouseEvent *pEvent );
|
||||
void HandleCursor
|
||||
( const TrackPanelMouseEvent &tpmEvent,
|
||||
CellType cellType = CellType::Background );
|
||||
void HandleCursor( const TrackPanelMouseEvent &tpmEvent );
|
||||
|
||||
// If label, rectangle includes track control panel only.
|
||||
// If !label, rectangle includes all of that, and the vertical ruler, and
|
||||
@ -569,9 +565,4 @@ enum : int {
|
||||
#pragma warning( pop )
|
||||
#endif
|
||||
|
||||
|
||||
//This constant determines the size of the vertical region (in pixels) around
|
||||
//the bottom of a track that can be used for vertical track resizing.
|
||||
#define TRACK_RESIZE_REGION 5
|
||||
|
||||
#endif
|
||||
|
@ -391,3 +391,17 @@ void TrackPanelResizeHandle::OnProjectChange(AudacityProject *pProject)
|
||||
UIHandle::OnProjectChange(pProject);
|
||||
}
|
||||
|
||||
TrackPanelResizerCell &TrackPanelResizerCell::Instance()
|
||||
{
|
||||
static TrackPanelResizerCell instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
HitTestResult TrackPanelResizerCell::HitTest
|
||||
(const TrackPanelMouseEvent &event, const AudacityProject *pProject)
|
||||
{
|
||||
return {
|
||||
TrackPanelResizeHandle::HitPreview( mBetweenTracks ),
|
||||
&TrackPanelResizeHandle::Instance()
|
||||
};
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ Paul Licameli split from TrackPanel.cpp
|
||||
#ifndef __AUDACITY_TRACK_PANEL_RESIZE_HANDLE__
|
||||
#define __AUDACITY_TRACK_PANEL_RESIZE_HANDLE__
|
||||
|
||||
#include "CommonTrackPanelCell.h"
|
||||
#include "UIHandle.h"
|
||||
|
||||
struct HitTestResult;
|
||||
@ -65,4 +66,23 @@ private:
|
||||
int mMouseClickY{};
|
||||
};
|
||||
|
||||
class TrackPanelResizerCell : public CommonTrackPanelCell
|
||||
{
|
||||
TrackPanelResizerCell() {}
|
||||
TrackPanelResizerCell(const TrackPanelResizerCell&) = delete;
|
||||
TrackPanelResizerCell &operator= (const TrackPanelResizerCell&) = delete;
|
||||
public:
|
||||
static TrackPanelResizerCell &Instance();
|
||||
|
||||
HitTestResult HitTest
|
||||
(const TrackPanelMouseEvent &event,
|
||||
const AudacityProject *pProject) override;
|
||||
|
||||
Track *FindTrack() override { return mpTrack; };
|
||||
private:
|
||||
friend class TrackPanel;
|
||||
Track *mpTrack {};
|
||||
bool mBetweenTracks {};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user