diff options
| author | Tim E. Real <termtech@rogers.com> | 2011-09-28 08:00:58 +0000 | 
|---|---|---|
| committer | Tim E. Real <termtech@rogers.com> | 2011-09-28 08:00:58 +0000 | 
| commit | 0cab73d2dc68d68d0027763543772d43bcd31958 (patch) | |
| tree | a09b96c5d305eed58be04abd0cd04d7ed2ed857c /muse2/muse | |
| parent | d52fac00567bb85944188f3c946b86b2a420819c (diff) | |
Optimization: Orcan's meters are insanely lightning-fast now.
Diffstat (limited to 'muse2/muse')
| -rw-r--r-- | muse2/muse/widgets/meter.cpp | 583 | ||||
| -rw-r--r-- | muse2/muse/widgets/meter.h | 7 | ||||
| -rw-r--r-- | muse2/muse/widgets/utils.cpp | 5 | 
3 files changed, 233 insertions, 362 deletions
| diff --git a/muse2/muse/widgets/meter.cpp b/muse2/muse/widgets/meter.cpp index 50d265b5..789089fe 100644 --- a/muse2/muse/widgets/meter.cpp +++ b/muse2/muse/widgets/meter.cpp @@ -35,8 +35,8 @@  #include "gconfig.h"  #include "fastlog.h" -// Uncomment to use the new meters. Warning: They are currently very time-consuming and unoptimized. -#define _USE_NEW_METERS 1  +// Just an experiment. Some undesirable effects, see below... +//#define _USE_CLIPPER 1   namespace MusEWidget { @@ -50,18 +50,17 @@ Meter::Meter(QWidget* parent, MeterType type)        setBackgroundRole(QPalette::NoRole);        setAttribute(Qt::WA_NoSystemBackground);        setAttribute(Qt::WA_StaticContents); -      // This is absolutely required for speed! Otherwise painfully slow because we get  -      //  full rect paint events even on small scrolls! See help on QPainter::scroll(). -      // Commented out for now. Orcan 20110911 -      #ifndef _USE_NEW_METERS +      // This is absolutely required for speed! Otherwise painfully slow because of full background  +      //  filling, even when requesting small udpdates! Background is drawn by us. (Just small corners.)        setAttribute(Qt::WA_OpaquePaintEvent);     -      #endif        //setFrameStyle(QFrame::Raised | QFrame::StyledPanel);        mtype = type;        overflow    = false;        cur_yv      = -1;     // Flag as -1 to initialize in paint.        last_yv     = 0; +      cur_ymax    = 0; +      last_ymax   = 0;        val         = 0.0;        maxVal      = 0.0;        minScale    = mtype == DBMeter ? MusEConfig::config.minMeter : 0.0;      // min value in dB or int @@ -154,46 +153,51 @@ void Meter::setVal(double v, double max, bool ovl)          }        }   +      double range = maxScale - minScale; +      int fw = frameWidth(); +      int w  = width() - 2*fw; +      int h  = height() - 2*fw; +      QRect udRect; +      bool udPeak = false; +              if(maxVal != max)        {          maxVal = max; +        if(mtype == DBMeter) +          cur_ymax = maxVal == 0 ? fw : int(((maxScale - (fast_log10(maxVal) * 20.0)) * h)/range); +        else +          cur_ymax = maxVal == 0 ? fw : int(((maxScale - maxVal) * h)/range); +        if(cur_ymax > h) cur_ymax = h; +        // Not using regions. Just lump them together. +        udRect = QRect(fw, last_ymax, w, 1) | QRect(fw, cur_ymax, w, 1); +        //printf("Meter::setVal peak cur_ymax:%d last_ymax:%d\n", cur_ymax, last_ymax);  +        last_ymax = cur_ymax;           ud = true; +        udPeak = true;        }        if(ud)                { -        #ifdef _USE_NEW_METERS -        update();  -         -        #else -        double range = maxScale - minScale; -        int fw = frameWidth(); -        int w  = width() - 2*fw; -        int h  = height() - 2*fw; -                  if(mtype == DBMeter)            cur_yv = val == 0 ? h : int(((maxScale - (fast_log10(val) * 20.0)) * h)/range);          else            cur_yv = val == 0 ? h : int(((maxScale - val) * h)/range); -                  if(cur_yv > h) cur_yv = h; -         + +        //printf("Meter::setVal cur_yv:%d last_yv:%d\n", cur_yv, last_yv);           int y1, y2; -        if(last_yv < cur_yv) -        { -          y1 = last_yv; -          y2 = cur_yv; -        } -        else -        { -          y1 = cur_yv; -          y2 = last_yv; -        } +        if(last_yv < cur_yv) { y1 = last_yv; y2 = cur_yv; } else { y1 = cur_yv; y2 = last_yv; }          last_yv = cur_yv; -        update(fw, y1, w, y2);  -        #endif +         +        if(udPeak) +          update(udRect | QRect(fw, y1, w, y2 - y1 + 1));  +          //repaint(udRect | QRect(fw, y1, w, y2 - y1 + 1));  +        else +          update(QRect(fw, y1, w, y2 - y1 + 1));  +          //repaint(QRect(fw, y1, w, y2 - y1 + 1));         }      } +  //---------------------------------------------------------  //   resetPeaks  //    reset peak and overflow indicator @@ -203,6 +207,7 @@ void Meter::resetPeaks()        {        maxVal   = val;        overflow = val > 0.0; +      cur_yv = -1;  // Force re-initialization.        update();                       } @@ -224,69 +229,91 @@ void Meter::setRange(double min, double max)  void Meter::paintEvent(QPaintEvent* ev)        { -      // TODO: Could make better use of event rectangle, for speed. -              QPainter p(this); -      #ifdef _USE_NEW_METERS        p.setRenderHint(QPainter::Antialiasing);   -      #endif -       +        double range = maxScale - minScale; -              int fw = frameWidth();        int w  = width() - 2*fw;        int h  = height() - 2*fw; -        const QRect& rect = ev->rect();        //printf("Meter::paintEvent rx:%d ry:%d rw:%d rh:%d w:%d h:%d\n", rect.x(), rect.y(), rect.width(), rect.height(), w, h);  -      //p.setClipRect(rect); // Nope, didn't help (I think it's already clipped. So check why we bother to do it in View). + +      QPainterPath drawingPath, updatePath, finalPath, cornerPath; +      //bool updFull = false;        // Initialize. Can't do in ctor, must be done after layouts have been done. Most reliable to do it here. -      #ifndef _USE_NEW_METERS        if(cur_yv == -1)  -      #endif            {          if(mtype == DBMeter) +        {              cur_yv = val == 0 ? h : int(((maxScale - (fast_log10(val) * 20.0)) * h)/range); +          cur_ymax = maxVal == 0 ? fw : int(((maxScale - (fast_log10(maxVal) * 20.0)) * h)/range); +        }            else +        {              cur_yv = val == 0 ? h : int(((maxScale - val) * h)/range); +          cur_ymax = maxVal == 0 ? fw : int(((maxScale - maxVal) * h)/range); +        }            if(cur_yv > h) cur_yv = h; -        //last_yv = cur_yv; +        last_yv = cur_yv; +        if(cur_ymax > h) cur_ymax = h; +        last_ymax = cur_ymax; +        //updFull = true; +        updatePath.addRect(fw, fw, w, h);  // Update the whole thing        } +      else +        updatePath.addRect(rect.x(), rect.y(), rect.width(), rect.height());  // Update only the requested rectangle +       +      drawingPath.addRoundedRect(fw, fw, w, h, xrad, yrad);  // The actual desired shape of the meter +      finalPath = drawingPath & updatePath; + +      // Draw corners as normal background colour. +      cornerPath = updatePath - finalPath;            // Elegantly simple. Path subtraction! Wee... +      if(!cornerPath.isEmpty()) +        p.fillPath(cornerPath, palette().window());   +       +#ifdef _USE_CLIPPER +      p.setClipPath(finalPath);       //  Meh, nice but not so good. Clips at edge so antialising has no effect! Can it be done ? +#endif        // Draw the red, green, and yellow sections. -      drawVU(p, rect, cur_yv); +      drawVU(p, rect, finalPath, cur_yv);        // Draw the peak white line. -      int ymax; -      if(mtype == DBMeter) -        ymax = maxVal == 0 ? 0 : int(((maxScale - (fast_log10(maxVal) * 20.0)) * h)/range); -      else -        ymax = maxVal == 0 ? 0 : int(((maxScale - maxVal) * h)/range); -      if(ymax >= rect.y() && ymax < rect.height()) +      //if(updFull || (cur_ymax >= rect.y() && cur_ymax < rect.height()))        { -        p.setPen(peak_color); -        p.drawLine(0, ymax, w, ymax); +        p.setRenderHint(QPainter::Antialiasing, false);  // No antialiasing. Makes the line fuzzy, double height, or not visible at all. + +        //p.setPen(peak_color); +        //p.drawLine(fw, cur_ymax, w, cur_ymax); // Undesirable. Draws outside the top rounded corners. +        // +        //QPainterPath path; path.moveTo(fw, cur_ymax); path.lineTo(w, cur_ymax);  // ? Didn't work. No line at all. +        //p.drawPath(path & finalPath); +        QPainterPath path; path.addRect(fw, cur_ymax, w, 1); path &= finalPath; +        if(!path.isEmpty()) +          p.fillPath(path, QBrush(peak_color));        } -      #ifdef _USE_NEW_METERS        // Draw the transparent layer on top of everything to give a 3d look -      QPainterPath round_path = MusEUtil::roundedPath(0, 0, w, h, -                                            xrad, yrad, -                                            (MusEUtil::Corner) (MusEUtil::UpperLeft | MusEUtil::UpperRight | MusEUtil::LowerLeft | MusEUtil::LowerRight ) ); -      maskGrad.setStart(QPointF(0, 0)); -      maskGrad.setFinalStop(QPointF(w, 0)); -      p.fillPath(round_path, QBrush(maskGrad)); -      #endif +      p.setRenderHint(QPainter::Antialiasing);   +      maskGrad.setStart(QPointF(fw, fw)); +      maskGrad.setFinalStop(QPointF(w, fw)); +#ifdef _USE_CLIPPER +      p.fillRect(rect, QBrush(maskGrad)); +#else +      //QPainterPath path; path.addRect(fw, fw, w); +      //p.fillPath(finalPath & path, QBrush(maskGrad)); +      p.fillPath(finalPath, QBrush(maskGrad)); +#endif              } -  //---------------------------------------------------------  //   drawVU  //--------------------------------------------------------- -void Meter::drawVU(QPainter& p, const QRect& rect, int yv) +void Meter::drawVU(QPainter& p, const QRect& rect, const QPainterPath& drawPath, int yv)  {        int fw = frameWidth();        int w  = width() - 2*fw; @@ -295,362 +322,210 @@ void Meter::drawVU(QPainter& p, const QRect& rect, int yv)        // Test OK. We are passed small rectangles on small value changes.        //printf("Meter::drawVU rx:%d ry:%d rw:%d rh:%d w:%d h:%d\n", rect.x(), rect.y(), rect.width(), rect.height(), w, h);  -  #ifdef _USE_NEW_METERS -       -      if(mtype == DBMeter) -      { -        double range = maxScale - minScale; -        int y1 = int((maxScale - redScale) * h / range); -        int y2 = int((maxScale - yellowScale) * h / range); - -        darkGradGreen.setStart(QPointF(0, y2)); -        darkGradGreen.setFinalStop(QPointF(0, h)); -        darkGradYellow.setStart(QPointF(0, y1)); -        darkGradYellow.setFinalStop(QPointF(0, y2)); -        darkGradRed.setStart(QPointF(0, 0)); -        darkGradRed.setFinalStop(QPointF(0, y1)); - -        lightGradGreen.setStart(QPointF(0, y2)); -        lightGradGreen.setFinalStop(QPointF(0, h)); -        lightGradYellow.setStart(QPointF(0, y1)); -        lightGradYellow.setFinalStop(QPointF(0, y2)); -        lightGradRed.setStart(QPointF(0, 0)); -        lightGradRed.setFinalStop(QPointF(0, y1)); - -        QPainterPath p_top = MusEUtil::roundedPath(0, 0, w, y1, -                                         xrad, yrad, -                                         (MusEUtil::Corner) (MusEUtil::UpperLeft | MusEUtil::UpperRight ) ); - -	QPainterPath p_bottom = MusEUtil::roundedPath(0, y2, w, h-y2, -                                            xrad, yrad, -                                            (MusEUtil::Corner) (MusEUtil::LowerLeft | MusEUtil::LowerRight ) ); - -        if(yv < y1) -        { - -          QPainterPath p_dark_red = MusEUtil::roundedPath(0, 0, w, yv, -                                                xrad, yrad, -                                                (MusEUtil::Corner) (MusEUtil::UpperLeft | MusEUtil::UpperRight ) ); - -          p_top = p_top.subtracted(p_dark_red); - -          // Red section: -          p.fillPath(p_dark_red,        QBrush(darkGradRed));       // dark red   -          p.fillPath(p_top,             QBrush(lightGradRed));      // light red - -          // Yellow section: -          p.fillRect(0, y1, w, y2-y1,   QBrush(lightGradYellow));   // light yellow - -          // Green section: -          p.fillPath(p_bottom,          QBrush(lightGradGreen));    // light green -        } -        else -        if(yv < y2) -        { -          // Red section: -          p.fillPath(p_top,             QBrush(darkGradRed));       // dark red   - -          // Yellow section: -          p.fillRect(0, y1, w, yv-y1,   QBrush(darkGradYellow));    // dark yellow -          p.fillRect(0, yv, w, y2-yv,   QBrush(lightGradYellow));   // light yellow - -          // Green section: -          p.fillPath(p_bottom,          QBrush(lightGradGreen));    // light green -        } -        else -        //if(yv <= y3)    -        { -          QPainterPath p_light_green = MusEUtil::roundedPath(0, yv, w, h-yv, -                                                   xrad, yrad, -                                                   (MusEUtil::Corner) (MusEUtil::LowerLeft | MusEUtil::LowerRight ) ); -          p_bottom = p_bottom.subtracted(p_light_green); - -          // Red section: -          p.fillPath(p_top,             QBrush(darkGradRed));      // dark red   - -          // Yellow section: -          p.fillRect(0, y1, w, y2-y1,   QBrush(darkGradYellow));   // dark yellow - -          // Green section: -          p.fillPath(p_bottom,          QBrush(darkGradGreen));    // dark green -          p.fillPath(p_light_green,     QBrush(lightGradGreen));   // light green -        } - -        p.fillRect(0,y1, w, 1, separator_color); -        p.fillRect(0,y2, w, 1, separator_color); - -      }   -      else -      { -        darkGradGreen.setStart(QPointF(0, 0)); -        darkGradGreen.setFinalStop(QPointF(0, h)); - -        lightGradGreen.setStart(QPointF(0, 0)); -        lightGradGreen.setFinalStop(QPointF(0, h)); - -        // We need to draw the meter in two parts. The cutoff for upper rectangle can be -        // anywhere between yrad and h-yrad. Without loss of generality we pick the lower limit. -	int cut = yrad; - -        QPainterPath p_top = MusEUtil::roundedPath(0, 0, w, cut, -                                         xrad, yrad, -                                         (MusEUtil::Corner) (MusEUtil::UpperLeft | MusEUtil::UpperRight ) ); - -	QPainterPath p_bottom = MusEUtil::roundedPath(0, cut, w, h-cut, -                                            xrad, yrad, -                                            (MusEUtil::Corner) (MusEUtil::LowerLeft | MusEUtil::LowerRight ) ); - -        if(yv < cut) -        { - -          QPainterPath p_dark = MusEUtil::roundedPath(0, 0, w, yv, -                                            xrad, yrad, -                                            (MusEUtil::Corner) (MusEUtil::UpperLeft | MusEUtil::UpperRight ) ); - -          p_top = p_top.subtracted(p_dark); - -          // top section: -          p.fillPath(p_dark,            QBrush(darkGradGreen));       // dark green -          p.fillPath(p_top,             QBrush(lightGradGreen));      // light green - -          // bottom section: -          p.fillPath(p_bottom,          QBrush(lightGradGreen));      // light green -        } -        else -        { -          QPainterPath p_light = MusEUtil::roundedPath(0, yv, w, h-yv, -                                                   xrad, yrad, -                                                   (MusEUtil::Corner) (MusEUtil::LowerLeft | MusEUtil::LowerRight ) ); -          p_bottom = p_bottom.subtracted(p_light); - -          // top section: -          p.fillPath(p_top,             QBrush(darkGradGreen));       // dark green - -          // bottom section: -          p.fillPath(p_bottom,          QBrush(darkGradGreen));       // dark green -          p.fillPath(p_light,           QBrush(lightGradGreen));      // light green -        } - -      } -       -      /*  WIP... -      // TODO: Instead of drawing the whole area, make this respect the requested drawing rectangle, for speed... -      //       Done. But not correct yet. And could possibly simplify the whole drawing some more...        QRect pr(0, 0,  w, 0); -      QPainterPath rectp; -      rectp.addRect(rect.x(), rect.y(), rect.width(), rect.height()); -      if(mtype == DBMeter) +      if(mtype == DBMeter)     // Meter type is dB...        {          double range = maxScale - minScale;          int y1 = int((maxScale - redScale) * h / range);          int y2 = int((maxScale - yellowScale) * h / range); -        darkGradGreen.setStart(QPointF(0, y2)); -        darkGradGreen.setFinalStop(QPointF(0, h)); -        darkGradYellow.setStart(QPointF(0, y1)); -        darkGradYellow.setFinalStop(QPointF(0, y2)); -        darkGradRed.setStart(QPointF(0, 0)); -        darkGradRed.setFinalStop(QPointF(0, y1)); - -        lightGradGreen.setStart(QPointF(0, y2)); -        lightGradGreen.setFinalStop(QPointF(0, h)); -        lightGradYellow.setStart(QPointF(0, y1)); -        lightGradYellow.setFinalStop(QPointF(0, y2)); -        lightGradRed.setStart(QPointF(0, 0)); -        lightGradRed.setFinalStop(QPointF(0, y1)); - -        QPainterPath p_top = MusEUtil::roundedPath(0, 0, w, y1, -                                         xrad, yrad, -                                         (MusEUtil::Corner) (MusEUtil::UpperLeft | MusEUtil::UpperRight ) ); - -        QPainterPath p_bottom = MusEUtil::roundedPath(0, y2, w, h-y2, -                                            xrad, yrad, -                                            (MusEUtil::Corner) (MusEUtil::LowerLeft | MusEUtil::LowerRight ) ); - +        darkGradGreen.setStart(QPointF(fw, y2)); +        darkGradGreen.setFinalStop(QPointF(fw, h)); +        darkGradYellow.setStart(QPointF(fw, y1)); +        darkGradYellow.setFinalStop(QPointF(fw, y2)); +        darkGradRed.setStart(QPointF(fw, fw)); +        darkGradRed.setFinalStop(QPointF(fw, y1)); + +        lightGradGreen.setStart(QPointF(fw, y2)); +        lightGradGreen.setFinalStop(QPointF(fw, h)); +        lightGradYellow.setStart(QPointF(fw, y1)); +        lightGradYellow.setFinalStop(QPointF(fw, y2)); +        lightGradRed.setStart(QPointF(fw, fw)); +        lightGradRed.setFinalStop(QPointF(fw, y1)); + +#ifdef _USE_CLIPPER          if(yv < y1)          { - -          QPainterPath p_dark_red = MusEUtil::roundedPath(0, 0, w, yv, -                                                xrad, yrad, -                                                (MusEUtil::Corner) (MusEUtil::UpperLeft | MusEUtil::UpperRight ) ); - -          p_top = p_top.subtracted(p_dark_red); -            // Red section: -          p.fillPath(p_dark_red & rectp,        QBrush(darkGradRed));       // dark red   -          p.fillPath(p_top & rectp,             QBrush(lightGradRed));      // light red - +          pr.setTop(fw); pr.setHeight(yv); +          p.fillRect(pr, QBrush(darkGradRed));     // dark red   +          pr.setTop(yv); pr.setHeight(y1-yv); +          p.fillRect(pr & rect, QBrush(lightGradRed));     // light red +                      // Yellow section:            pr.setTop(y1); pr.setHeight(y2-y1); -          p.fillRect(pr & rect, QBrush(lightGradYellow));   // light yellow - +          p.fillRect(pr & rect, QBrush(lightGradYellow));     // light yellow +                      // Green section: -          p.fillPath(p_bottom & rectp, QBrush(lightGradGreen));    // light green +          pr.setTop(y2); pr.setHeight(h-y2); +          p.fillRect(pr & rect, QBrush(lightGradGreen));     // light green          }          else          if(yv < y2)          {            // Red section: -          p.fillPath(p_top & rectp, QBrush(darkGradRed));       // dark red   - +          pr.setTop(fw); pr.setHeight(y1); +          p.fillRect(pr & rect, QBrush(darkGradRed));     // dark red   +                      // Yellow section:            pr.setTop(y1); pr.setHeight(yv-y1); -          p.fillRect(pr & rect, QBrush(darkGradYellow));    // dark yellow +          p.fillRect(pr & rect, QBrush(darkGradYellow));     // dark yellow            pr.setTop(yv); pr.setHeight(y2-yv); -          p.fillRect(pr & rect, QBrush(lightGradYellow));   // light yellow - +          p.fillRect(pr & rect, QBrush(lightGradYellow));     // light yellow +                      // Green section: -          p.fillPath(p_bottom & rectp, QBrush(lightGradGreen));    // light green +          pr.setTop(y2); pr.setHeight(h-y2); +          p.fillRect(pr & rect, QBrush(lightGradGreen));     // light green          }          else          //if(yv <= y3)             { -          QPainterPath p_light_green = MusEUtil::roundedPath(0, yv, w, h-yv, -                                                   xrad, yrad, -                                                   (MusEUtil::Corner) (MusEUtil::LowerLeft | MusEUtil::LowerRight ) ); -          p_bottom = p_bottom.subtracted(p_light_green); -            // Red section: -          p.fillPath(p_top & rectp, QBrush(darkGradRed));      // dark red   - +          pr.setTop(fw); pr.setHeight(y1); +          p.fillRect(pr & rect, QBrush(darkGradRed));     // dark red   +                      // Yellow section:            pr.setTop(y1); pr.setHeight(y2-y1); -          p.fillRect(pr & rect, QBrush(darkGradYellow));   // dark yellow - +          p.fillRect(pr & rect, QBrush(darkGradYellow));     // dark yellow +                      // Green section: -          p.fillPath(p_bottom & rectp, QBrush(darkGradGreen));    // dark green -          p.fillPath(p_light_green & rectp, QBrush(lightGradGreen));   // light green +          pr.setTop(y2); pr.setHeight(yv-y2); +          p.fillRect(pr & rect, QBrush(darkGradGreen));     // dark green +          pr.setTop(yv); pr.setHeight(h-yv); +          p.fillRect(pr & rect, QBrush(lightGradGreen));     // light green          } - -        pr.setTop(y1); pr.setHeight(1); -        p.fillRect(pr & rect, separator_color); -        pr.setTop(y2); //pr.setHeight(1); -        p.fillRect(pr & rect, separator_color); -        }   -      else +      else     // Meter type is linear...        { -        darkGradGreen.setStart(QPointF(0, 0)); -        darkGradGreen.setFinalStop(QPointF(0, h)); - -        lightGradGreen.setStart(QPointF(0, 0)); -        lightGradGreen.setFinalStop(QPointF(0, h)); - -        // We need to draw the meter in two parts. The cutoff for upper rectangle can be -        // anywhere between yrad and h-yrad. Without loss of generality we pick the lower limit. -        int cut = yrad; - -        QPainterPath p_top = MusEUtil::roundedPath(0, 0, w, cut, -                                         xrad, yrad, -                                         (MusEUtil::Corner) (MusEUtil::UpperLeft | MusEUtil::UpperRight ) ); - -        QPainterPath p_bottom = MusEUtil::roundedPath(0, cut, w, h-cut, -                                            xrad, yrad, -                                            (MusEUtil::Corner) (MusEUtil::LowerLeft | MusEUtil::LowerRight ) ); - -        if(yv < cut) -        { - -          QPainterPath p_dark = MusEUtil::roundedPath(0, 0, w, yv, -                                            xrad, yrad, -                                            (MusEUtil::Corner) (MusEUtil::UpperLeft | MusEUtil::UpperRight ) ); - -          p_top = p_top.subtracted(p_dark); - -          // top section: -          p.fillPath(p_dark & rectp, QBrush(darkGradGreen));       // dark green -          p.fillPath(p_top & rectp, QBrush(lightGradGreen));      // light green - -          // bottom section: -          p.fillPath(p_bottom & rectp, QBrush(lightGradGreen));      // light green -        } -        else -        { -          QPainterPath p_light = MusEUtil::roundedPath(0, yv, w, h-yv, -                                                   xrad, yrad, -                                                   (MusEUtil::Corner) (MusEUtil::LowerLeft | MusEUtil::LowerRight ) ); -          p_bottom = p_bottom.subtracted(p_light); - -          // top section: -          p.fillPath(p_top & rectp, QBrush(darkGradGreen));       // dark green +        pr.setTop(fw); pr.setHeight(yv); +        p.fillRect(pr & rect, QBrush(darkGradGreen));   // dark green +        pr.setTop(yv); pr.setHeight(h-yv); +        p.fillRect(pr & rect, QBrush(lightGradGreen));   // light green +      } -          // bottom section: -          p.fillPath(p_bottom & rectp, QBrush(darkGradGreen));       // dark green -          p.fillPath(p_light & rectp, QBrush(lightGradGreen));      // light green -        } +#else   // NOT    _USE_CLIPPER -      } -      */ -       -  #else -       -      QRect pr(0, 0,  w, 0); -      if(mtype == DBMeter) -      { -        double range = maxScale - minScale; -        int y1 = int((maxScale - redScale) * h / range); -        int y2 = int((maxScale - yellowScale) * h / range); -                  if(yv < y1)          {            // Red section: -          pr.setTop(0); pr.setHeight(yv); -          p.fillRect(pr & rect, QBrush(0x8e0000));     // dark red   -          pr.setTop(yv); pr.setHeight(y1-yv); -          p.fillRect(pr & rect, QBrush(0xff0000));     // light red +          { +            QPainterPath path; path.addRect(fw, fw, w, yv); path &= drawPath; +            if(!path.isEmpty()) +              p.fillPath(path, QBrush(darkGradRed));       // dark red +          } +          { +            QPainterPath path; path.addRect(fw, yv, w, y1-yv); path &= drawPath; +            if(!path.isEmpty()) +              p.fillPath(path, QBrush(lightGradRed));       // light red +          }            // Yellow section: -          pr.setTop(y1); pr.setHeight(y2-y1); -          p.fillRect(pr & rect, QBrush(0xffff00));     // light yellow +          { +            QPainterPath path; path.addRect(fw, y1, w, y2-y1); path &= drawPath; +            if(!path.isEmpty()) +              p.fillPath(path, QBrush(lightGradYellow));   // light yellow +          }            // Green section: -          pr.setTop(y2); pr.setHeight(h-y2); -          p.fillRect(pr & rect, QBrush(0x00ff00));     // light green +          { +            QPainterPath path; path.addRect(fw, y2, w, h-y2); path &= drawPath; +            if(!path.isEmpty()) +              p.fillPath(path, QBrush(lightGradGreen));   // light green +          }          }          else          if(yv < y2)          {            // Red section: -          pr.setTop(0); pr.setHeight(y1); -          p.fillRect(pr & rect, QBrush(0x8e0000));     // dark red   +          { +            QPainterPath path; path.addRect(fw, fw, w, y1); path &= drawPath; +            if(!path.isEmpty()) +              p.fillPath(path, QBrush(darkGradRed));       // dark red +          }            // Yellow section: -          pr.setTop(y1); pr.setHeight(yv-y1); -          p.fillRect(pr & rect, QBrush(0x8e8e00));     // dark yellow -          pr.setTop(yv); pr.setHeight(y2-yv); -          p.fillRect(pr & rect, QBrush(0xffff00));     // light yellow +          { +            QPainterPath path; path.addRect(fw, y1, w, yv-y1); path &= drawPath; +            if(!path.isEmpty()) +              p.fillPath(path, QBrush(darkGradYellow));   // dark yellow +          } +          { +            QPainterPath path; path.addRect(fw, yv, w, y2-yv); path &= drawPath; +            if(!path.isEmpty()) +              p.fillPath(path, QBrush(lightGradYellow));   // light yellow +          }            // Green section: -          pr.setTop(y2); pr.setHeight(h-y2); -          p.fillRect(pr & rect, QBrush(0x00ff00));     // light green +          { +            QPainterPath path; path.addRect(fw, y2, w, h-y2); path &= drawPath; +            if(!path.isEmpty()) +              p.fillPath(path, QBrush(lightGradGreen));   // light green +          }          }          else          //if(yv <= y3)             {            // Red section: -          pr.setTop(0); pr.setHeight(y1); -          p.fillRect(pr & rect, QBrush(0x8e0000));     // dark red   +          { +            QPainterPath path; path.addRect(fw, fw, w, y1); path &= drawPath; +            if(!path.isEmpty()) +              p.fillPath(path, QBrush(darkGradRed));       // dark red +          }            // Yellow section: -          pr.setTop(y1); pr.setHeight(y2-y1); -          p.fillRect(pr & rect, QBrush(0x8e8e00));     // dark yellow +          { +            QPainterPath path; path.addRect(fw, y1, w, y2-y1); path &= drawPath; +            if(!path.isEmpty()) +              p.fillPath(path, QBrush(darkGradYellow));   // dark yellow +          }            // Green section: -          pr.setTop(y2); pr.setHeight(yv-y2); -          p.fillRect(pr & rect, QBrush(0x007000));     // dark green -          pr.setTop(yv); pr.setHeight(h-yv); -          p.fillRect(pr & rect, QBrush(0x00ff00));     // light green +          { +            QPainterPath path; path.addRect(fw, y2, w, yv-y2); path &= drawPath; +            if(!path.isEmpty()) +              p.fillPath(path, QBrush(darkGradGreen));   // dark green +          } +          { +            QPainterPath path; path.addRect(fw, yv, w, h-yv); path &= drawPath; +            if(!path.isEmpty()) +              p.fillPath(path, QBrush(lightGradGreen));   // light green +          }          } + +        // Separators:  +        { +          QRect r(0, y1, w, 1); r &= rect; +          if(!r.isNull()) +            p.fillRect(r, separator_color);   +        }   +        { +          QRect r(0, y2, w, 1); r &= rect; +          if(!r.isNull()) +            p.fillRect(r, separator_color);   +        }          }   -      else +      else      // Meter type is linear...        { -        pr.setTop(0); pr.setHeight(yv); -        p.fillRect(pr & rect, QBrush(0x007000));   // dark green -        pr.setTop(yv); pr.setHeight(h-yv); -        p.fillRect(pr & rect, QBrush(0x00ff00));   // light green -      } -       -  #endif +        darkGradGreen.setStart(QPointF(fw, fw)); +        darkGradGreen.setFinalStop(QPointF(fw, h)); + +        lightGradGreen.setStart(QPointF(fw, fw)); +        lightGradGreen.setFinalStop(QPointF(fw, h)); + +        { +          QPainterPath path; path.addRect(fw, fw, w, yv); path &= drawPath; +          if(!path.isEmpty()) +            p.fillPath(path, QBrush(darkGradGreen));   // dark green +        } +        { +          QPainterPath path; path.addRect(fw, yv, w, h-yv); path &= drawPath; +          if(!path.isEmpty()) +            p.fillPath(path, QBrush(lightGradGreen));   // light green +        } +      }   + +#endif  // NOT   _USE_CLIPPER +  }  //--------------------------------------------------------- diff --git a/muse2/muse/widgets/meter.h b/muse2/muse/widgets/meter.h index ba816319..7b5369b6 100644 --- a/muse2/muse/widgets/meter.h +++ b/muse2/muse/widgets/meter.h @@ -32,6 +32,7 @@  class QResizeEvent;  class QMouseEvent;  class QPainter; +class QPainterPath;  namespace MusEWidget { @@ -74,7 +75,7 @@ class Meter : public QFrame {        QColor separator_color;;        QColor peak_color;        int xrad, yrad; - +           private:        MeterType mtype;        bool overflow; @@ -82,9 +83,9 @@ class Meter : public QFrame {        double maxVal;        double minScale, maxScale;        int yellowScale, redScale; -      int cur_yv, last_yv; +      int cur_yv, last_yv, cur_ymax, last_ymax; -      void drawVU(QPainter& p, const QRect&, int); +      void drawVU(QPainter& p, const QRect&, const QPainterPath&, int);        void paintEvent(QPaintEvent*);        void resizeEvent(QResizeEvent*); diff --git a/muse2/muse/widgets/utils.cpp b/muse2/muse/widgets/utils.cpp index c900f3b6..41c5a180 100644 --- a/muse2/muse/widgets/utils.cpp +++ b/muse2/muse/widgets/utils.cpp @@ -167,7 +167,6 @@ QString bitmap2String(int bm)  //---------------------------------------------------------  //   u32bitmap2String  //--------------------------------------------------------- -// Added by Tim. p3.3.8  QString u32bitmap2String(unsigned int bm)        { @@ -274,7 +273,6 @@ int string2bitmap(const QString& str)  //---------------------------------------------------------  //   string2u32bitmap  //--------------------------------------------------------- -// Added by Tim. p3.3.8  unsigned int string2u32bitmap(const QString& str)        { @@ -343,7 +341,6 @@ unsigned int string2u32bitmap(const QString& str)  //   ignoreWidth: Set if dealing with a vertically constrained widget - one which is free to resize horizontally.  //   ignoreHeight: Set if dealing with a horizontally constrained widget - one which is free to resize vertically.   //--------------------------------------------------------- -// Added by Tim. p3.3.8  bool autoAdjustFontSize(QFrame* w, const QString& s, bool ignoreWidth, bool ignoreHeight, int max, int min)  { @@ -373,12 +370,10 @@ bool autoAdjustFontSize(QFrame* w, const QString& s, bool ignoreWidth, bool igno      if((ignoreWidth || (r.width() <= (cr.width() - extra))) && (ignoreHeight || (r.height() <= cr.height())))        break;    } -  // Added by Tim. p3.3.9    //printf("autoAdjustFontSize: ptsz:%d widget:%s before setFont x:%d y:%d w:%d h:%d\n", fnt.pointSize(), w->name(), w->x(), w->y(), w->width(), w->height());    // Here we will always have a font ranging from min to max point size.    w->setFont(fnt); -  // Added by Tim. p3.3.9    //printf("autoAdjustFontSize: ptsz:%d widget:%s x:%d y:%d w:%d h:%d frame w:%d rw:%d rh:%d\n", fnt.pointSize(), w->name(), w->x(), w->y(), w->width(), w->height(), w->frameWidth(), cr.width(), cr.height());    // Force minimum height. Use the expected height for the highest given point size. | 
