Update of /cvsroot/audacity/audacity-src/src/widgets
In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv12524
Modified Files:
Ruler.cpp Ruler.h
Log Message:
Adding a custom ruler and a grid, by Simone Campanini (slightly modified by
MJS).
Index: Ruler.h
===================================================================
RCS file: /cvsroot/audacity/audacity-src/src/widgets/Ruler.h,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- Ruler.h 28 Dec 2008 01:20:14 -0000 1.27
+++ Ruler.h 16 Feb 2009 22:34:34 -0000 1.28
@@ -80,6 +80,9 @@
// and a horizontal ruler hug the top (instead of bottom)
void SetFlip(bool flip);
+ // Set it to false if you don't want minor labels.
+ void SetMinor(bool value);
+
// Good defaults are provided, but you can override here
void SetFonts(const wxFont &minorFont, const wxFont &majorFont, const
wxFont &minorMinorFont);
@@ -94,6 +97,18 @@
//
void GetMaxSize(wxCoord *width, wxCoord *height);
+
+ // The following functions should allow a custom ruler setup:
+ // autosize is a GREAT thing, but for some applications it's
+ // useful the definition of a label array and label step by
+ // the user.
+ void SetCustomMode(bool value);
+ // If this is the case, you should provide a wxString array of labels, start
+ // label position, and labels step. The range eventually specified will be
+ // ignored.
+ void SetCustomMajorLabels(wxArrayString *label, int numLabel, int start,
int step);
+ void SetCustomMinorLabels(wxArrayString *label, int numLabel, int start,
int step);
+
//
// Drawing
//
@@ -101,6 +116,9 @@
// Note that it will not erase for you...
void Draw(wxDC& dc);
void Draw(wxDC& dc, Envelope *speedEnv, long minSpeed, long maxSpeed);
+ // If length <> 0, draws lines perpendiculars to ruler corresponding
+ // to selected ticks (major, minor, or both), in an adjacent window.
+ void DrawGrid(wxDC& dc, int length, bool minor = true, bool major = true);
// So we can have white ticks on black...
void SetTickColour( const wxColour & colour)
@@ -116,6 +134,9 @@
void Tick(int pos, double d, bool major, bool minor);
+ // Another tick generator for custom ruler case (noauto) .
+ void TickCustom(int labelIdx, bool major, bool minor);
+
public:
bool mbTicksOnly;
bool mbTicksAtExtremes;
@@ -162,7 +183,13 @@
int mNumMinorMinor;
Label *mMinorMinorLabels;
+ // Returns 'zero' label coordinate (for grid drawing)
+ int FindZero(Label * label, int len);
+
+ public:
+ int GetZeroPosition();
+ private:
int mOrientation;
int mSpacing;
bool mHasSetSpacing;
@@ -170,6 +197,12 @@
RulerFormat mFormat;
bool mLog;
bool mFlip;
+ bool mCustom;
+ bool mbMinor;
+ bool mMajorGrid; // for grid drawing
+ bool mMinorGrid; // .
+ int mGridLineLength; // .
+ int mZeroPosition; // end
wxString mUnits;
};
Index: Ruler.cpp
===================================================================
RCS file: /cvsroot/audacity/audacity-src/src/widgets/Ruler.cpp,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -d -r1.55 -r1.56
--- Ruler.cpp 28 Dec 2008 01:20:14 -0000 1.55
+++ Ruler.cpp 16 Feb 2009 22:34:34 -0000 1.56
@@ -135,6 +135,15 @@
mUserBitLen = 0;
mValid = false;
+
+ mCustom = false;
+ mbMinor = true;
+
+ mGridLineLength = 0;
+ mMajorGrid = false;
+ mMinorGrid = false;
+
+ mZeroPosition = -1;
}
Ruler::~Ruler()
@@ -253,6 +262,11 @@
}
}
+void Ruler::SetMinor(bool value)
+{
+ mbMinor = value;
+}
+
void Ruler::SetFonts(const wxFont &minorFont, const wxFont &majorFont, const
wxFont &minorMinorFont)
{
*mMinorMinorFont = minorMinorFont;
@@ -769,6 +783,121 @@
wxRect r(strLeft, strTop, strW, strH);
mRect.Union(r);
+
+}
+
+void Ruler::TickCustom(int labelIdx, bool major, bool minor)
+{
+ //This should only used in the mCustom case
+ // Many code comes from 'Tick' method: this should
+ // be optimized.
+
+ int pos;
+ wxString l;
+ wxCoord strW, strH, strD, strL;
+ int strPos, strLen, strLeft, strTop;
+
+ // FIXME: We don't draw a tick if of end of our label arrays
+ // But we shouldn't have an array of labels.
+ if( mNumMinor >= mLength )
+ return;
+ if( mNumMajor >= mLength )
+ return;
+
+ Label *label;
+ if (major)
+ label = &mMajorLabels[labelIdx];
+ else if (minor)
+ label = &mMinorLabels[labelIdx];
+ else
+ label = &mMinorMinorLabels[labelIdx];
+
+ pos = label->pos; // already stored in label class
+ l = label->text;
+ label->lx = mLeft - 1000; // don't display
+ label->ly = mTop - 1000; // don't display
+
+ mDC->SetFont(major? *mMajorFont: minor? *mMinorFont : *mMinorMinorFont);
+
+ mDC->GetTextExtent(l, &strW, &strH, &strD, &strL);
+
+ if (mOrientation == wxHORIZONTAL) {
+ strLen = strW;
+ strPos = pos - strW/2;
+ if (strPos < 0)
+ strPos = 0;
+ if (strPos + strW >= mLength)
+ strPos = mLength - strW;
+ strLeft = mLeft + strPos;
+ if (mFlip) {
+ strTop = mTop + 4;
+ mMaxHeight = max(mMaxHeight, strH + 4);
+ }
+ else {
+
+ strTop =-strH-mLead;
+ strTop = mTop- mLead+4;// More space was needed...
+ mMaxHeight = max(mMaxHeight, strH + 6);
+ }
+ }
+ else {
+ strLen = strH;
+ strPos = pos - strH/2;
+ if (strPos < 0)
+ strPos = 0;
+ if (strPos + strH >= mLength)
+ strPos = mLength - strH;
+ strTop = mTop + strPos;
+ if (mFlip) {
+ strLeft = mLeft + 5;
+ mMaxWidth = max(mMaxWidth, strW + 5);
+ }
+ else {
+
+ strLeft =-strW-6;
+ }
+ }
+
+
+ // FIXME: we shouldn't even get here if strPos < 0.
+ // Ruler code currently does not handle very small or
+ // negative sized windows (i.e. don't draw) properly.
+ if( strPos < 0 )
+ return;
+
+ // See if any of the pixels we need to draw this
+ // label is already covered
+
+ int i;
+ for(i=0; i<strLen; i++)
+ if (mBits[strPos+i])
+ return;
+
+ // If not, position the label
+
+ label->lx = strLeft;
+ label->ly = strTop;
+
+ // And mark these pixels, plus some surrounding
+ // ones (the spacing between labels), as covered
+ int leftMargin = mSpacing;
+ if (strPos < leftMargin)
+ leftMargin = strPos;
+ strPos -= leftMargin;
+ strLen += leftMargin;
+
+ int rightMargin = mSpacing;
+ if (strPos + strLen > mLength - mSpacing)
+ rightMargin = mLength - strPos - strLen;
+ strLen += rightMargin;
+
+ for(i=0; i<strLen; i++)
+ mBits[strPos+i] = 1;
+
+
+ wxRect r(strLeft, strTop, strW, strH);
+ mRect.Union(r);
+
}
void Ruler::Update()
@@ -846,23 +975,27 @@
}
// FIXME: Surely we do not need to allocate storage for the labels?
- // We can just recompute them as we need them?
- mNumMajor = 0;
- mNumMinor = 0;
- mNumMinorMinor = 0;
- if (mLength!=mLengthOld) {
- if (mMajorLabels)
- delete[] mMajorLabels;
- mMajorLabels = new Label[mLength+1];
- if (mMinorLabels)
- delete[] mMinorLabels;
- mMinorLabels = new Label[mLength+1];
- if (mMinorMinorLabels)
- delete[] mMinorMinorLabels;
- mMinorMinorLabels = new Label[mLength+1];
- mLengthOld = mLength;
+ // We can just recompute them as we need them? Yes, but only if
+ // mCustom is false!!!!
+
+ if(!mCustom) {
+ mNumMajor = 0;
+ mNumMinor = 0;
+ mNumMinorMinor = 0;
+ if (mLength!=mLengthOld) {
+ if (mMajorLabels)
+ delete[] mMajorLabels;
+ mMajorLabels = new Label[mLength+1];
+ if (mMinorLabels)
+ delete[] mMinorLabels;
+ mMinorLabels = new Label[mLength+1];
+ if (mMinorMinorLabels)
+ delete[] mMinorMinorLabels;
+ mMinorMinorLabels = new Label[mLength+1];
+ mLengthOld = mLength;
+ }
}
-
+
if (mBits)
delete[] mBits;
mBits = new int[mLength+1];
@@ -873,10 +1006,24 @@
for(i=0; i<=mLength; i++)
mBits[i] = 0;
- if(mLog==false) {
+ // *************** Label calculation routine **************
+ if(mCustom == true) {
+
+ // SET PARAMETER IN MCUSTOM CASE
+ // Works only with major labels
+
+ int numLabel = mNumMajor;
+
+ i = 0;
+ while((i<numLabel) && (i<=mLength)) {
+
+ TickCustom(i, true, false);
+ i++;
+ }
- double UPP = (mMax-mMin)/mLength; // Units per pixel
+ } else if(mLog==false) {
+ double UPP = (mMax-mMin)/mLength; // Units per pixel
FindLinearTickSizes(UPP);
// Left and Right Edges
@@ -919,7 +1066,7 @@
Tick(i, sg * majorInt * mMajor, true, false);
}
}
-
+
// Minor ticks
d = mMin - UPP/2;
lastD = d;
@@ -1074,7 +1221,6 @@
void Ruler::Draw(wxDC& dc, Envelope *speedEnv, long minSpeed, long maxSpeed)
{
mDC = &dc;
-
if( mLength <=0 )
return;
@@ -1145,37 +1291,36 @@
mMajorLabels[i].ly);
}
- mDC->SetFont(*mMinorFont);
-
- for(i=0; i<mNumMinor; i++) {
- int pos = mMinorLabels[i].pos;
-
- if( mbTicksAtExtremes || ((pos!=0)&&(pos!=iMaxPos)))
- {
- if (mOrientation == wxHORIZONTAL)
- {
- if (mFlip)
- mDC->DrawLine(mLeft + pos, mTop,
- mLeft + pos, mTop + 2);
- else
- mDC->DrawLine(mLeft + pos, mBottom - 2,
- mLeft + pos, mBottom);
- }
- else
+ if(mbMinor == true) {
+ mDC->SetFont(*mMinorFont);
+ for(i=0; i<mNumMinor; i++) {
+ int pos = mMinorLabels[i].pos;
+ if( mbTicksAtExtremes || ((pos!=0)&&(pos!=iMaxPos)))
{
- if (mFlip)
- mDC->DrawLine(mLeft, mTop + pos,
- mLeft + 2, mTop + pos);
- else
- mDC->DrawLine(mRight - 2, mTop + pos,
- mRight, mTop + pos);
+ if (mOrientation == wxHORIZONTAL)
+ {
+ if (mFlip)
+ mDC->DrawLine(mLeft + pos, mTop,
+ mLeft + pos, mTop + 2);
+ else
+ mDC->DrawLine(mLeft + pos, mBottom - 2,
+ mLeft + pos, mBottom);
+ }
+ else
+ {
+ if (mFlip)
+ mDC->DrawLine(mLeft, mTop + pos,
+ mLeft + 2, mTop + pos);
+ else
+ mDC->DrawLine(mRight - 2, mTop + pos,
+ mRight, mTop + pos);
+ }
}
+ if (mMinorLabels[i].text != wxT(""))
+ mDC->DrawText(mMinorLabels[i].text,
+ mMinorLabels[i].lx,
+ mMinorLabels[i].ly);
}
-
- if (mMinorLabels[i].text != wxT(""))
- mDC->DrawText(mMinorLabels[i].text,
- mMinorLabels[i].lx,
- mMinorLabels[i].ly);
}
mDC->SetFont(*mMinorMinorFont);
@@ -1210,9 +1355,96 @@
mMinorMinorLabels[i].lx,
mMinorMinorLabels[i].ly);
}
+ }
+}
+
+// ********** Draw grid ***************************
+void Ruler::DrawGrid(wxDC& dc, int length, bool minor, bool major)
+{
+ mGridLineLength = length;
+ mMajorGrid = major;
+ mMinorGrid = minor;
+ mDC = &dc;
+
+ int gridPos;
+ wxPen gridPen;
+
+ if(mbMinor && (mMinorGrid && (mGridLineLength != 0 ))) {
+ gridPen.SetColour(178, 178, 178); // very light grey
+ mDC->SetPen(gridPen);
+ for(int i=0; i<mNumMinor; i++) {
+ gridPos = mMinorLabels[i].pos;
+ if(mOrientation == wxHORIZONTAL) {
+ if((gridPos != 0) && (gridPos != mGridLineLength))
+ mDC->DrawLine(gridPos+1, 1, gridPos+1, mGridLineLength);
+ }
+ else {
+ if((gridPos != 0) && (gridPos != mGridLineLength))
+ mDC->DrawLine(1, gridPos+1, mGridLineLength, gridPos+1);
+ }
+ }
+ }
+
+ if(mMajorGrid && (mGridLineLength != 0 )) {
+ gridPen.SetColour(127, 127, 127); // light grey
+ mDC->SetPen(gridPen);
+ for(int i=0; i<mNumMajor; i++) {
+ gridPos = mMajorLabels[i].pos;
+ if(mOrientation == wxHORIZONTAL) {
+ if((gridPos != 0) && (gridPos != mGridLineLength))
+ mDC->DrawLine(gridPos+1, 1, gridPos+1, mGridLineLength);
+ }
+ else {
+ if((gridPos != 0) && (gridPos != mGridLineLength))
+ mDC->DrawLine(1, gridPos+1, mGridLineLength, gridPos+1);
+ }
+ }
+
+ GetZeroPosition();
+ if(mZeroPosition > 0) {
+ // Draw 'zero' grid line in black
+ mDC->SetPen(*wxBLACK_PEN);
+ if(mOrientation == wxHORIZONTAL) {
+ if(mZeroPosition != mGridLineLength)
+ mDC->DrawLine(mZeroPosition+1, 1, mZeroPosition+1,
mGridLineLength);
+ }
+ else {
+ if(mZeroPosition != mGridLineLength)
+ mDC->DrawLine(1, mZeroPosition+1, mGridLineLength,
mZeroPosition+1);
+ }
+ }
}
}
+int Ruler::FindZero(Label * label, const int len)
+{
+ int i = 0;
+ double d = 1.0; // arbitrary
+ wxString s;
+
+ do {
+ s = label[i].text;
+ if(!s.IsEmpty())
+ s.ToDouble(&d);
+ else
+ d = 1.0; // arbitrary, looking for some text here
+ i++;
+ } while( (i < len) && (d != 0.0) );
+
+ if(d == 0.0)
+ return (mZeroPosition = label[i - 1].pos) ;
+ else
+ return -1;
+}
+
+int Ruler::GetZeroPosition()
+{
+ int zero;
+ if((zero = FindZero(mMajorLabels, mNumMajor)) < 0)
+ zero = FindZero(mMinorLabels, mNumMinor);
+ return zero;
+}
+
void Ruler::GetMaxSize(wxCoord *width, wxCoord *height)
{
@@ -1232,6 +1464,36 @@
}
+void Ruler::SetCustomMode(bool value) { mCustom = value; }
+
+void Ruler::SetCustomMajorLabels(wxArrayString *label, int numLabel, int
start, int step)
+{
+ int i;
+
+ mNumMajor = numLabel;
+ mMajorLabels = new Label[numLabel];
+
+ for(i=0; i<numLabel; i++) {
+ mMajorLabels[i].text = label->Item(i);
+ mMajorLabels[i].pos = start + i*step;
+ }
+ //Remember: delete majorlabels....
+}
+
+void Ruler::SetCustomMinorLabels(wxArrayString *label, int numLabel, int
start, int step)
+{
+ int i;
+
+ mNumMinor = numLabel;
+ mMinorLabels = new Label[numLabel];
+
+ for(i=0; i<numLabel; i++) {
+ mMinorLabels[i].text = label->Item(i);
+ mMinorLabels[i].pos = start + i*step;
+ }
+ //Remember: delete majorlabels....
+}
+
//
// RulerPanel
//
------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
_______________________________________________
Audacity-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/audacity-cvs