1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-05-03 17:19:43 +02:00

Reimplement quick play indicator as an overlay like the cursor

This commit is contained in:
Paul Licameli 2015-08-24 14:14:09 -04:00 committed by Paul Licameli
parent 8b7ae748a3
commit 9f65b80647
4 changed files with 106 additions and 50 deletions

View File

@ -550,8 +550,6 @@ TrackPanel::TrackPanel(wxWindow * parent, wxWindowID id,
mSnapLeft = -1;
mSnapRight = -1;
mOldQPIndicatorPos = -1;
// Register for tracklist updates
mTracks->Connect(EVT_TRACKLIST_RESIZED,
wxCommandEventHandler(TrackPanel::OnTrackListResized),
@ -1039,47 +1037,6 @@ void TrackPanel::ScrollDuringDrag()
}
}
void TrackPanel::DrawQuickPlayIndicator(int x, bool snapped)
{
wxClientDC dc(this);
// Erase the old indicator.
if (mOldQPIndicatorPos != x) {
#if defined(__WXMAC__)
// On OSX, if a HiDPI resolution is being used, the line will actually take up
// more than 1 pixel (even though it is drawn as 1), so we restore the surrounding
// pixels as well. (This is because the wxClientDC doesn't know about the scaling.)
dc.Blit(mOldQPIndicatorPos - 1, 0, 3, mBacking->GetHeight(), &mBackingDC, mOldQPIndicatorPos - 1, 0);
#else
dc.Blit(mOldQPIndicatorPos, 0, 1, mBacking->GetHeight(), &mBackingDC, mOldQPIndicatorPos, 0);
#endif
mOldQPIndicatorPos = -1;
}
if (x >= 0) {
snapped ? AColor::SnapGuidePen(&dc) : AColor::Light(&dc, false);
// Draw indicator in all visible tracks
VisibleTrackIterator iter(GetProject());
for (Track *t = iter.First(); t; t = iter.Next())
{
// Convert virtual coordinate to physical
int y = t->GetY() - mViewInfo->vpos;
// Draw the NEW indicator in its new location
AColor::Line(dc,
x,
y + kTopMargin,
x,
// Minus one more because AColor::Line includes both endpoints
y + t->GetHeight() - kBottomMargin - 1 );
}
mOldQPIndicatorPos = x;
}
}
double TrackPanel::GetScreenEndTime() const
{
int width;

View File

@ -229,8 +229,6 @@ class AUDACITY_DLL_API TrackPanel final : public wxPanel {
virtual void UpdateTrackVRuler(Track *t);
virtual void UpdateVRulerSize();
virtual void DrawQuickPlayIndicator(int x, bool snapped = false);
// Returns the time corresponding to the pixel column one past the track area
// (ignoring any fisheye)
virtual double GetScreenEndTime() const;
@ -566,9 +564,6 @@ protected:
TrackPanel *parent;
} mTimer;
// Quick-Play indicator postion
int mOldQPIndicatorPos;
int mTimeCount;
wxMemoryDC mBackingDC;

View File

@ -66,6 +66,7 @@ array of Ruler::Label.
#include <wx/menuitem.h>
#include <wx/tooltip.h>
#include "../AColor.h"
#include "../AudioIO.h"
#include "../Internat.h"
#include "../Project.h"
@ -75,6 +76,8 @@ array of Ruler::Label.
#include "../Experimental.h"
#include "../TimeTrack.h"
#include "../TrackPanel.h"
#include "../TrackPanelCellIterator.h"
#include "../TrackPanelOverlay.h"
#include "../Menus.h"
#include "../NumberScale.h"
#include "../Prefs.h"
@ -1643,6 +1646,91 @@ void RulerPanel::DoSetSize(int x, int y,
ruler.SetBounds(0, 0, w-1, h-1);
}
/**********************************************************************
QuickPlayIndicatorOverlay.
Graphical helper for AdornedRulerPanel.
**********************************************************************/
class QuickPlayIndicatorOverlay final : public TrackPanelOverlay
{
public:
QuickPlayIndicatorOverlay(AudacityProject *project)
: mProject(project)
, mOldQPIndicatorPos(-1)
, mNewQPIndicatorPos(-1)
, mOldQPIndicatorSnapped(false)
, mNewQPIndicatorSnapped(false)
{
}
virtual ~QuickPlayIndicatorOverlay()
{
}
void Update(int x, bool snapped = false)
{
mNewQPIndicatorPos = x;
mNewQPIndicatorSnapped = snapped;
// Not strictly needed, but this reduces the lag in updating
// track panel causing momentary mismatch between the triangle
// in the ruler and the white line.
mProject->GetTrackPanel()->DrawOverlays(false);
}
private:
std::pair<wxRect, bool> DoGetRectangle(wxSize size) override;
void Draw
(wxDC &dc, TrackPanelCellIterator begin, TrackPanelCellIterator end) override;
AudacityProject *mProject;
int mOldQPIndicatorPos;
int mNewQPIndicatorPos;
bool mOldQPIndicatorSnapped;
bool mNewQPIndicatorSnapped;
};
std::pair<wxRect, bool> QuickPlayIndicatorOverlay::DoGetRectangle(wxSize size)
{
wxRect rect(mOldQPIndicatorPos, 0, 1, size.GetHeight());
return std::make_pair(
rect,
(mOldQPIndicatorPos != mNewQPIndicatorPos ||
mOldQPIndicatorSnapped != mNewQPIndicatorSnapped)
);
}
void QuickPlayIndicatorOverlay::Draw
(wxDC &dc, TrackPanelCellIterator begin, TrackPanelCellIterator end)
{
mOldQPIndicatorPos = mNewQPIndicatorPos;
mOldQPIndicatorSnapped = mNewQPIndicatorSnapped;
if (mOldQPIndicatorPos >= 0) {
mOldQPIndicatorSnapped ? AColor::SnapGuidePen(&dc) : AColor::Light(&dc, false);
// Draw indicator in all visible tracks
for (; begin != end; ++begin)
{
TrackPanelCellIterator::value_type data(*begin);
Track *const pTrack = dynamic_cast<Track*>(data.first);
if (!pTrack)
continue;
const wxRect &rect = data.second;
// Draw the NEW indicator in its NEW location
AColor::Line(dc,
mOldQPIndicatorPos,
rect.GetTop(),
mOldQPIndicatorPos,
rect.GetBottom());
}
}
}
/**********************************************************************
Implementation of AdornedRulerPanel.
@ -2525,6 +2613,16 @@ void AdornedRulerPanel::DoDrawIndicator(wxDC * dc)
dc->DrawPolygon( 3, tri );
}
QuickPlayIndicatorOverlay *AdornedRulerPanel::GetOverlay()
{
if (!mOverlay) {
TrackPanel *tp = mProject->GetTrackPanel();
mOverlay = std::make_unique<QuickPlayIndicatorOverlay>(mProject);
tp->AddOverlay(mOverlay.get());
}
return mOverlay.get();
}
// Draws the vertical line and green triangle indicating the Quick Play cursor position.
void AdornedRulerPanel::DrawQuickPlayIndicator(wxDC * dc)
{
@ -2532,7 +2630,7 @@ void AdornedRulerPanel::DrawQuickPlayIndicator(wxDC * dc)
double latestEnd = std::max(mTracks->GetEndTime(), mProject->GetSel1());
if (dc == NULL || (mQuickPlayPos >= latestEnd)) {
tp->DrawQuickPlayIndicator(-1);
GetOverlay()->Update(-1);
mLastQuickPlayX = -1;
return;
}
@ -2564,7 +2662,7 @@ void AdornedRulerPanel::DrawQuickPlayIndicator(wxDC * dc)
AColor::IndicatorColor( dc, true);
dc->DrawPolygon( 3, tri, x );
tp->DrawQuickPlayIndicator(x, mIsSnapped);
GetOverlay()->Update(x, mIsSnapped);
}
void AdornedRulerPanel::SetPlayRegion(double playRegionStart,

View File

@ -11,6 +11,7 @@
#ifndef __AUDACITY_RULER__
#define __AUDACITY_RULER__
#include "../MemoryX.h"
#include <wx/bitmap.h>
#include <wx/dc.h>
#include <wx/dcmemory.h>
@ -269,6 +270,8 @@ private:
DECLARE_EVENT_TABLE()
};
class QuickPlayIndicatorOverlay;
// This is an Audacity Specific ruler panel which additionally
// has border, selection markers, play marker.
// Once TrackPanel uses wxSizers, we will derive it from some
@ -320,6 +323,7 @@ private:
void DoDrawCursor(wxDC * dc);
void DoDrawSelection(wxDC * dc);
void DoDrawIndicator(wxDC * dc);
QuickPlayIndicatorOverlay *GetOverlay();
void DrawQuickPlayIndicator(wxDC * dc /*NULL to DELETE old only*/);
void DoDrawPlayRegion(wxDC * dc);
@ -398,6 +402,8 @@ private:
int mLastMouseX; // Pixel position
bool mIsDragging;
std::unique_ptr<QuickPlayIndicatorOverlay> mOverlay;
DECLARE_EVENT_TABLE()
};