mirror of
https://github.com/cookiengineer/audacity
synced 2025-07-26 09:28:07 +02:00
Ruler-drawing does not assume uniform zoom, ...
... and AdornedRulerPanel exposes an invalidation function for later use
This commit is contained in:
parent
8664c877ba
commit
6b9e7506dd
@ -156,6 +156,7 @@ class AUDACITY_DLL_API AudacityProject: public wxFrame,
|
|||||||
bool ZoomOutAvailable() const { return mViewInfo.ZoomOutAvailable(); }
|
bool ZoomOutAvailable() const { return mViewInfo.ZoomOutAvailable(); }
|
||||||
double GetSel0() { return mViewInfo.selectedRegion.t0(); }
|
double GetSel0() { return mViewInfo.selectedRegion.t0(); }
|
||||||
double GetSel1() { return mViewInfo.selectedRegion.t1(); }
|
double GetSel1() { return mViewInfo.selectedRegion.t1(); }
|
||||||
|
const ZoomInfo &GetZoomInfo() const { return mViewInfo; }
|
||||||
|
|
||||||
Track *GetFirstVisible();
|
Track *GetFirstVisible();
|
||||||
void UpdateFirstVisible();
|
void UpdateFirstVisible();
|
||||||
|
@ -53,7 +53,8 @@ TimeTrack::TimeTrack(DirManager *projDirManager):
|
|||||||
SetDefaultName(_("Time Track"));
|
SetDefaultName(_("Time Track"));
|
||||||
SetName(GetDefaultName());
|
SetName(GetDefaultName());
|
||||||
|
|
||||||
mRuler = new Ruler();
|
mRuler = new Ruler;
|
||||||
|
mRuler->SetUseZoomInfo(0);
|
||||||
mRuler->SetLabelEdges(false);
|
mRuler->SetLabelEdges(false);
|
||||||
mRuler->SetFormat(Ruler::TimeFormat);
|
mRuler->SetFormat(Ruler::TimeFormat);
|
||||||
|
|
||||||
@ -77,7 +78,8 @@ TimeTrack::TimeTrack(TimeTrack &orig):
|
|||||||
mEnvelope->Paste(0.0, orig.mEnvelope);
|
mEnvelope->Paste(0.0, orig.mEnvelope);
|
||||||
|
|
||||||
///@TODO: Give Ruler:: a copy-constructor instead of this?
|
///@TODO: Give Ruler:: a copy-constructor instead of this?
|
||||||
mRuler = new Ruler();
|
mRuler = new Ruler;
|
||||||
|
mRuler->SetUseZoomInfo(0);
|
||||||
mRuler->SetLabelEdges(false);
|
mRuler->SetLabelEdges(false);
|
||||||
mRuler->SetFormat(Ruler::TimeFormat);
|
mRuler->SetFormat(Ruler::TimeFormat);
|
||||||
|
|
||||||
|
@ -79,6 +79,7 @@ array of Ruler::Label.
|
|||||||
#include "../Prefs.h"
|
#include "../Prefs.h"
|
||||||
#include "../Snap.h"
|
#include "../Snap.h"
|
||||||
|
|
||||||
|
using std::min;
|
||||||
using std::max;
|
using std::max;
|
||||||
|
|
||||||
#define SELECT_TOLERANCE_PIXEL 4
|
#define SELECT_TOLERANCE_PIXEL 4
|
||||||
@ -157,6 +158,8 @@ Ruler::Ruler()
|
|||||||
mMinorGrid = false;
|
mMinorGrid = false;
|
||||||
|
|
||||||
mTwoTone = false;
|
mTwoTone = false;
|
||||||
|
|
||||||
|
mUseZoomInfo = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ruler::~Ruler()
|
Ruler::~Ruler()
|
||||||
@ -947,6 +950,10 @@ void Ruler::Update()
|
|||||||
|
|
||||||
void Ruler::Update(TimeTrack* timetrack)// Envelope *speedEnv, long minSpeed, long maxSpeed )
|
void Ruler::Update(TimeTrack* timetrack)// Envelope *speedEnv, long minSpeed, long maxSpeed )
|
||||||
{
|
{
|
||||||
|
const ZoomInfo *zoomInfo = NULL;
|
||||||
|
if (mUseZoomInfo && !mLog && mOrientation == wxHORIZONTAL)
|
||||||
|
zoomInfo = &GetActiveProject()->GetZoomInfo();
|
||||||
|
|
||||||
// This gets called when something has been changed
|
// This gets called when something has been changed
|
||||||
// (i.e. we've been invalidated). Recompute all
|
// (i.e. we've been invalidated). Recompute all
|
||||||
// tick positions and font size.
|
// tick positions and font size.
|
||||||
@ -1074,8 +1081,14 @@ void Ruler::Update(TimeTrack* timetrack)// Envelope *speedEnv, long minSpeed, lo
|
|||||||
|
|
||||||
// Zero (if it's in the middle somewhere)
|
// Zero (if it's in the middle somewhere)
|
||||||
if (mMin * mMax < 0.0) {
|
if (mMin * mMax < 0.0) {
|
||||||
int mid = (int)(mLength*(mMin/(mMin-mMax)) + 0.5);
|
int mid;
|
||||||
Tick(mid, 0.0, true, false);
|
if (zoomInfo != NULL)
|
||||||
|
mid = int(zoomInfo->TimeToPosition(0.0, mLeftOffset));
|
||||||
|
else
|
||||||
|
mid = (int)(mLength*(mMin / (mMin - mMax)) + 0.5);
|
||||||
|
const int iMaxPos = (mOrientation == wxHORIZONTAL) ? mRight : mBottom - 5;
|
||||||
|
if (mid >= 0 && mid < iMaxPos)
|
||||||
|
Tick(mid, 0.0, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
double sg = UPP > 0.0? 1.0: -1.0;
|
double sg = UPP > 0.0? 1.0: -1.0;
|
||||||
@ -1083,8 +1096,18 @@ void Ruler::Update(TimeTrack* timetrack)// Envelope *speedEnv, long minSpeed, lo
|
|||||||
// Major and minor ticks
|
// Major and minor ticks
|
||||||
for (int jj = 0; jj < 2; ++jj) {
|
for (int jj = 0; jj < 2; ++jj) {
|
||||||
const double denom = jj == 0 ? mMajor : mMinor;
|
const double denom = jj == 0 ? mMajor : mMinor;
|
||||||
double d, warpedD;
|
i = -1; j = 0;
|
||||||
d = mMin - UPP / 2;
|
double d, warpedD, nextD;
|
||||||
|
|
||||||
|
double prevTime = 0.0, time = 0.0;
|
||||||
|
if (zoomInfo != NULL) {
|
||||||
|
j = zoomInfo->TimeToPosition(mMin);
|
||||||
|
prevTime = zoomInfo->PositionToTime(--j);
|
||||||
|
time = zoomInfo->PositionToTime(++j);
|
||||||
|
d = (prevTime + time) / 2.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
d = mMin - UPP / 2;
|
||||||
if (timetrack)
|
if (timetrack)
|
||||||
warpedD = timetrack->ComputeWarpedLength(0.0, d);
|
warpedD = timetrack->ComputeWarpedLength(0.0, d);
|
||||||
else
|
else
|
||||||
@ -1092,14 +1115,22 @@ void Ruler::Update(TimeTrack* timetrack)// Envelope *speedEnv, long minSpeed, lo
|
|||||||
// using ints doesn't work, as
|
// using ints doesn't work, as
|
||||||
// this will overflow and be negative at high zoom.
|
// this will overflow and be negative at high zoom.
|
||||||
double step = floor(sg * warpedD / denom);
|
double step = floor(sg * warpedD / denom);
|
||||||
i = -1;
|
|
||||||
while (i <= mLength) {
|
while (i <= mLength) {
|
||||||
i++;
|
i++;
|
||||||
if (timetrack)
|
if (zoomInfo)
|
||||||
warpedD += timetrack->ComputeWarpedLength(d, d + UPP);
|
{
|
||||||
|
prevTime = time;
|
||||||
|
time = zoomInfo->PositionToTime(++j);
|
||||||
|
nextD = (prevTime + time) / 2.0;
|
||||||
|
// wxASSERT(time >= prevTime);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
warpedD += UPP;
|
nextD = d + UPP;
|
||||||
d += UPP;
|
if (timetrack)
|
||||||
|
warpedD += timetrack->ComputeWarpedLength(d, nextD);
|
||||||
|
else
|
||||||
|
warpedD = nextD;
|
||||||
|
d = nextD;
|
||||||
|
|
||||||
if (floor(sg * warpedD / denom) > step) {
|
if (floor(sg * warpedD / denom) > step) {
|
||||||
step = floor(sg * warpedD / denom);
|
step = floor(sg * warpedD / denom);
|
||||||
@ -1114,7 +1145,6 @@ void Ruler::Update(TimeTrack* timetrack)// Envelope *speedEnv, long minSpeed, lo
|
|||||||
Tick(0, mMin, true, false);
|
Tick(0, mMin, true, false);
|
||||||
Tick(mLength, mMax, true, false);
|
Tick(mLength, mMax, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// log case
|
// log case
|
||||||
@ -1517,6 +1547,12 @@ void Ruler::Label::Draw(wxDC&dc, bool twoTone) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Ruler::SetUseZoomInfo(int leftOffset)
|
||||||
|
{
|
||||||
|
mLeftOffset = leftOffset;
|
||||||
|
mUseZoomInfo = true;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// RulerPanel
|
// RulerPanel
|
||||||
//
|
//
|
||||||
@ -1620,8 +1656,8 @@ AdornedRulerPanel::AdornedRulerPanel(wxWindow* parent,
|
|||||||
SetName(GetLabel());
|
SetName(GetLabel());
|
||||||
|
|
||||||
mLeftOffset = 0;
|
mLeftOffset = 0;
|
||||||
mCurPos = -1;
|
mCurTime = -1;
|
||||||
mIndPos = -1;
|
mIndTime = -1;
|
||||||
mIndType = -1;
|
mIndType = -1;
|
||||||
mQuickPlayInd = false;
|
mQuickPlayInd = false;
|
||||||
mPlayRegionStart = -1;
|
mPlayRegionStart = -1;
|
||||||
@ -1644,6 +1680,7 @@ AdornedRulerPanel::AdornedRulerPanel(wxWindow* parent,
|
|||||||
mInner.width -= 2; // -2 for left and right bevels
|
mInner.width -= 2; // -2 for left and right bevels
|
||||||
mInner.height -= 3; // -3 for top and bottom bevels and bottom line
|
mInner.height -= 3; // -3 for top and bottom bevels and bottom line
|
||||||
|
|
||||||
|
ruler.SetUseZoomInfo(mLeftOffset);
|
||||||
ruler.SetBounds( mInner.GetLeft(),
|
ruler.SetBounds( mInner.GetLeft(),
|
||||||
mInner.GetTop(),
|
mInner.GetTop(),
|
||||||
mInner.GetRight(),
|
mInner.GetRight(),
|
||||||
@ -1698,6 +1735,11 @@ void AdornedRulerPanel::UpdatePrefs()
|
|||||||
RegenerateTooltips();
|
RegenerateTooltips();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AdornedRulerPanel::InvalidateRuler()
|
||||||
|
{
|
||||||
|
ruler.Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
void AdornedRulerPanel::RegenerateTooltips()
|
void AdornedRulerPanel::RegenerateTooltips()
|
||||||
{
|
{
|
||||||
#if wxUSE_TOOLTIPS
|
#if wxUSE_TOOLTIPS
|
||||||
@ -2317,8 +2359,8 @@ void AdornedRulerPanel::DoDrawBorder(wxDC * dc)
|
|||||||
|
|
||||||
void AdornedRulerPanel::DoDrawMarks(wxDC * dc, bool /*text */ )
|
void AdornedRulerPanel::DoDrawMarks(wxDC * dc, bool /*text */ )
|
||||||
{
|
{
|
||||||
double min = mViewInfo->h - mLeftOffset / mViewInfo->zoom;
|
const double min = Pos2Time(0);
|
||||||
double max = min + mInner.width / mViewInfo->zoom;
|
const double max = Pos2Time(mInner.width);
|
||||||
|
|
||||||
ruler.SetTickColour( theTheme.Colour( clrTrackPanelText ) );
|
ruler.SetTickColour( theTheme.Colour( clrTrackPanelText ) );
|
||||||
ruler.SetRange( min, max );
|
ruler.SetRange( min, max );
|
||||||
@ -2333,20 +2375,8 @@ void AdornedRulerPanel::DrawSelection()
|
|||||||
void AdornedRulerPanel::DoDrawSelection(wxDC * dc)
|
void AdornedRulerPanel::DoDrawSelection(wxDC * dc)
|
||||||
{
|
{
|
||||||
// Draw selection
|
// Draw selection
|
||||||
double zoom = mViewInfo->zoom;
|
const int p0 = 1 + max(0, Time2Pos(mViewInfo->selectedRegion.t0()));
|
||||||
double sel0 =
|
const int p1 = 2 + min(mInner.width, Time2Pos(mViewInfo->selectedRegion.t1()));
|
||||||
mViewInfo->selectedRegion.t0() - mViewInfo->h + mLeftOffset / zoom;
|
|
||||||
double sel1 =
|
|
||||||
mViewInfo->selectedRegion.t1() - mViewInfo->h + mLeftOffset / zoom;
|
|
||||||
|
|
||||||
if( sel0 < 0.0 )
|
|
||||||
sel0 = 0.0;
|
|
||||||
|
|
||||||
if( sel1 > ( mInner.width / zoom ) )
|
|
||||||
sel1 = mInner.width / zoom;
|
|
||||||
|
|
||||||
int p0 = int ( sel0 * zoom + 1.5 );
|
|
||||||
int p1 = int ( sel1 * zoom + 2.5 );
|
|
||||||
|
|
||||||
dc->SetBrush( wxBrush( theTheme.Colour( clrRulerBackground )) );
|
dc->SetBrush( wxBrush( theTheme.Colour( clrRulerBackground )) );
|
||||||
dc->SetPen( wxPen( theTheme.Colour( clrRulerBackground )) );
|
dc->SetPen( wxPen( theTheme.Colour( clrRulerBackground )) );
|
||||||
@ -2359,16 +2389,22 @@ void AdornedRulerPanel::DoDrawSelection(wxDC * dc)
|
|||||||
dc->DrawRectangle( r );
|
dc->DrawRectangle( r );
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdornedRulerPanel::DrawCursor(double pos)
|
void AdornedRulerPanel::SetLeftOffset(int offset)
|
||||||
{
|
{
|
||||||
mCurPos = pos;
|
mLeftOffset = offset;
|
||||||
|
ruler.SetUseZoomInfo(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdornedRulerPanel::DrawCursor(double time)
|
||||||
|
{
|
||||||
|
mCurTime = time;
|
||||||
|
|
||||||
Refresh(false);
|
Refresh(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdornedRulerPanel::DoDrawCursor(wxDC * dc)
|
void AdornedRulerPanel::DoDrawCursor(wxDC * dc)
|
||||||
{
|
{
|
||||||
int x = mLeftOffset + int ( ( mCurPos - mViewInfo->h ) * mViewInfo->zoom );
|
const int x = Time2Pos(mCurTime);
|
||||||
|
|
||||||
// Draw cursor in ruler
|
// Draw cursor in ruler
|
||||||
dc->DrawLine( x, 1, x, mInner.height );
|
dc->DrawLine( x, 1, x, mInner.height );
|
||||||
@ -2385,11 +2421,11 @@ void AdornedRulerPanel::ClearIndicator()
|
|||||||
Refresh(false);
|
Refresh(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdornedRulerPanel::DrawIndicator( double pos, bool rec )
|
void AdornedRulerPanel::DrawIndicator( double time, bool rec )
|
||||||
{
|
{
|
||||||
mIndPos = pos;
|
mIndTime = time;
|
||||||
|
|
||||||
if( mIndPos < 0 )
|
if (mIndTime < 0)
|
||||||
{
|
{
|
||||||
ClearIndicator();
|
ClearIndicator();
|
||||||
return;
|
return;
|
||||||
@ -2408,7 +2444,7 @@ void AdornedRulerPanel::DoDrawIndicator(wxDC * dc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int indsize = 6;
|
int indsize = 6;
|
||||||
int x = mLeftOffset + int ( ( mIndPos - mViewInfo->h ) * mViewInfo->zoom );
|
const int x = Time2Pos(mIndTime);
|
||||||
|
|
||||||
wxPoint tri[ 3 ];
|
wxPoint tri[ 3 ];
|
||||||
tri[ 0 ].x = x - indsize;
|
tri[ 0 ].x = x - indsize;
|
||||||
@ -2435,7 +2471,7 @@ void AdornedRulerPanel::DrawQuickPlayIndicator(wxDC * dc, bool clear)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int indsize = 4;
|
int indsize = 4;
|
||||||
int x = mLeftOffset + int((mQuickPlayPos - mViewInfo->h) * mViewInfo->zoom);
|
int x = Time2Pos(mQuickPlayPos);
|
||||||
|
|
||||||
wxPoint tri[3];
|
wxPoint tri[3];
|
||||||
tri[0].x = -indsize;
|
tri[0].x = -indsize;
|
||||||
|
@ -114,6 +114,8 @@ class AUDACITY_DLL_API Ruler {
|
|||||||
void SetCustomMajorLabels(wxArrayString *label, int numLabel, int start, int step);
|
void SetCustomMajorLabels(wxArrayString *label, int numLabel, int start, int step);
|
||||||
void SetCustomMinorLabels(wxArrayString *label, int numLabel, int start, int step);
|
void SetCustomMinorLabels(wxArrayString *label, int numLabel, int start, int step);
|
||||||
|
|
||||||
|
void SetUseZoomInfo(int leftOffset);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Drawing
|
// Drawing
|
||||||
//
|
//
|
||||||
@ -130,8 +132,10 @@ class AUDACITY_DLL_API Ruler {
|
|||||||
void SetTickColour( const wxColour & colour)
|
void SetTickColour( const wxColour & colour)
|
||||||
{ mTickColour = colour; mPen.SetColour( colour );}
|
{ mTickColour = colour; mPen.SetColour( colour );}
|
||||||
|
|
||||||
private:
|
// Force regeneration of labels at next draw time
|
||||||
void Invalidate();
|
void Invalidate();
|
||||||
|
|
||||||
|
private:
|
||||||
void Update();
|
void Update();
|
||||||
void Update(TimeTrack* timetrack);
|
void Update(TimeTrack* timetrack);
|
||||||
void FindTickSizes();
|
void FindTickSizes();
|
||||||
@ -213,6 +217,8 @@ private:
|
|||||||
int mGridLineLength; // end
|
int mGridLineLength; // end
|
||||||
wxString mUnits;
|
wxString mUnits;
|
||||||
bool mTwoTone;
|
bool mTwoTone;
|
||||||
|
bool mUseZoomInfo;
|
||||||
|
int mLeftOffset;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AUDACITY_DLL_API RulerPanel : public wxPanel {
|
class AUDACITY_DLL_API RulerPanel : public wxPanel {
|
||||||
@ -262,10 +268,10 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
static int GetRulerHeight() { return 28; }
|
static int GetRulerHeight() { return 28; }
|
||||||
void SetLeftOffset(int offset){ mLeftOffset = offset; }
|
void SetLeftOffset(int offset);
|
||||||
|
|
||||||
void DrawCursor(double pos);
|
void DrawCursor(double time);
|
||||||
void DrawIndicator(double pos, bool rec);
|
void DrawIndicator(double time, bool rec);
|
||||||
void DrawSelection();
|
void DrawSelection();
|
||||||
void ClearIndicator();
|
void ClearIndicator();
|
||||||
|
|
||||||
@ -273,9 +279,11 @@ public:
|
|||||||
void ClearPlayRegion();
|
void ClearPlayRegion();
|
||||||
void GetPlayRegion(double* playRegionStart, double* playRegionEnd);
|
void GetPlayRegion(double* playRegionStart, double* playRegionEnd);
|
||||||
|
|
||||||
void SetProject(AudacityProject* project) {mProject = project;};
|
void SetProject(AudacityProject* project) {mProject = project;}
|
||||||
void GetMaxSize(wxCoord *width, wxCoord *height);
|
void GetMaxSize(wxCoord *width, wxCoord *height);
|
||||||
|
|
||||||
|
void InvalidateRuler();
|
||||||
|
|
||||||
void UpdatePrefs();
|
void UpdatePrefs();
|
||||||
void RegenerateTooltips();
|
void RegenerateTooltips();
|
||||||
|
|
||||||
@ -313,10 +321,11 @@ private:
|
|||||||
|
|
||||||
int mLeftOffset; // Number of pixels before we hit the 'zero position'.
|
int mLeftOffset; // Number of pixels before we hit the 'zero position'.
|
||||||
|
|
||||||
double mCurPos;
|
double mCurTime;
|
||||||
|
|
||||||
int mIndType; // -1 = No indicator, 0 = Play, 1 = Record
|
|
||||||
double mIndPos;
|
int mIndType; // -1 = No indicator, 0 = Play, 1 = Record
|
||||||
|
double mIndTime;
|
||||||
bool mQuickPlayInd;
|
bool mQuickPlayInd;
|
||||||
double mQuickPlayPos;
|
double mQuickPlayPos;
|
||||||
SnapManager *mSnapManager;
|
SnapManager *mSnapManager;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user