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

Reply via email to