diff options
| author | Tim E. Real <termtech@rogers.com> | 2013-03-01 03:36:47 +0000 | 
|---|---|---|
| committer | Tim E. Real <termtech@rogers.com> | 2013-03-01 03:36:47 +0000 | 
| commit | 887f6426bd58f1bfd2bc38d1a2b57f1f4be5edbc (patch) | |
| tree | 99e5109acaa03b3b061932d9163b96d6d0e47038 /muse2/muse | |
| parent | dbae4f58499946ec53d5f210ca6bf3af7574983f (diff) | |
Wave Editor: Fixed some painting problems. Optimizations, speed boosts.
Diffstat (limited to 'muse2/muse')
| -rw-r--r-- | muse2/muse/helper.cpp | 54 | ||||
| -rw-r--r-- | muse2/muse/helper.h | 4 | ||||
| -rw-r--r-- | muse2/muse/waveedit/wavecanvas.cpp | 219 | ||||
| -rw-r--r-- | muse2/muse/widgets/canvas.cpp | 4 | 
4 files changed, 192 insertions, 89 deletions
diff --git a/muse2/muse/helper.cpp b/muse2/muse/helper.cpp index 2a6992fc..c50fb66d 100644 --- a/muse2/muse/helper.cpp +++ b/muse2/muse/helper.cpp @@ -49,6 +49,8 @@  #include <QFileInfo>  #include <QFileDialog>  #include <QString> +#include <QLine> +#include <QRect>  using std::set; @@ -1099,6 +1101,58 @@ int populateMidiCtrlMenu(PopupMenu* menu, MusECore::PartList* part_list, MusECor        return est_width;        } +//--------------------------------------------------- +//  clipQLine +//--------------------------------------------------- + +QLine clipQLine(int x1, int y1, int x2, int y2, const QRect& rect) +{ +  const int rect_x     = rect.x(); +  const int rect_y     = rect.y(); +  const int rect_right = rect_x + rect.width(); +  const int rect_bot   = rect_y + rect.height(); +   +  if(x1 < rect_x) +  { +    if(x2 < rect_x) +      return QLine(); +    x1 = rect_x; +  } +  else +  if(x1 > rect_right) +  { +    if(x2 > rect_right) +      return QLine(); +    x1 = rect_right; +  } +   +  if(x2 < rect_x) +    x2 = rect_x; +  else +  if(x2 > rect_right) +    x2 = rect_right; +   +  if(y1 < rect_y) +  { +    if(y2 < rect_y) +      return QLine(); +    y1 = rect_y; +  } +  else +  if(y1 > rect_bot) +  { +    if(y2 > rect_bot) +      return QLine(); +    y1 = rect_bot; +  } +   +  if(y2 < rect_y) +    y2 = rect_y; +  if(y2 > rect_bot) +    y2 = rect_bot; + +  return QLine(x1, y1, x2, y2); +}  } // namespace MusEGui diff --git a/muse2/muse/helper.h b/muse2/muse/helper.h index 0eab7ee2..56bd0bc8 100644 --- a/muse2/muse/helper.h +++ b/muse2/muse/helper.h @@ -33,7 +33,8 @@ class QActionGroup;  class QString;  class QMenu;  class QWidget; - +class QLine; +class QRect;  namespace MusECore {  class Part; @@ -76,6 +77,7 @@ QString projectExtensionFromFilename(QString filename);  QString getUniqueUntitledName();  void populateMidiPorts();  int populateMidiCtrlMenu(PopupMenu* menu, MusECore::PartList* part_list, MusECore::Part* cur_part, int curDrumPitch); +QLine clipQLine(int x1, int y1, int x2, int y2, const QRect& rect);  }   #endif diff --git a/muse2/muse/waveedit/wavecanvas.cpp b/muse2/muse/waveedit/wavecanvas.cpp index 80341554..c27f6cef 100644 --- a/muse2/muse/waveedit/wavecanvas.cpp +++ b/muse2/muse/waveedit/wavecanvas.cpp @@ -40,6 +40,8 @@  #include <QPair>  #include <QMessageBox>  #include <QDir> +#include <QLine> +#include <QVector>  #include <set> @@ -69,6 +71,7 @@  #include "utils.h"  #include "tools.h"  #include "copy_on_write.h" +#include "helper.h"  namespace MusEGui { @@ -1032,14 +1035,14 @@ void WaveCanvas::drawItem(QPainter& p, const MusEGui::CItem* item, const QRect&          return;        int x1 = mr.x(); -      int x2 = mr.right() + 1; +      int x2 = x1 + mr.width();        if (x1 < 0)              x1 = 0;        if (x2 > width())              x2 = width();        int hh = height(); -      int h  = hh/2; -      int y  = mr.y() + h; +      int y1 = mr.y(); +      int y2 = y1 + mr.height();        int xScale = xmag;        if (xScale < 0) @@ -1065,10 +1068,6 @@ void WaveCanvas::drawItem(QPainter& p, const MusEGui::CItem* item, const QRect&        int pos = (xpos + sx) * xScale + event.spos() - event.frame() - px; -      //printf("pos=%d xpos=%d sx=%d ex=%d xScale=%d event.spos=%d event.frame=%d px=%d\n",    -      //      pos, xpos, sx, ex, xScale, event.spos(), event.frame(), px); - -              QBrush brush;        if (item->isMoving())         { @@ -1078,7 +1077,7 @@ void WaveCanvas::drawItem(QPainter& p, const MusEGui::CItem* item, const QRect&              gradient.setColorAt(0, c);              gradient.setColorAt(1, c.darker());              brush = QBrush(gradient); -            p.fillRect(sx, 0, ex - sx, hh, brush); +            p.fillRect(sx, y1, ex - sx + 1, y2, brush);        }        else         if (item->isSelected())  @@ -1088,94 +1087,142 @@ void WaveCanvas::drawItem(QPainter& p, const MusEGui::CItem* item, const QRect&            QLinearGradient gradient(r.topLeft(), r.bottomLeft());            // Use a colour only about 20% lighter than black, rather than the 50% we use in MusECore::gGradientFromQColor            //  and is used in darker()/lighter(), so that it is distinguished a bit better from grey non-part tracks. -          //c.setRgba(64, 64, 64, c.alpha());                    gradient.setColorAt(0, QColor(51, 51, 51, MusEGlobal::config.globalAlphaBlend));            gradient.setColorAt(1, c);            brush = QBrush(gradient); -          p.fillRect(sx, 0, ex - sx, hh, brush); -      } -      //else -      { -            QPen pen(Qt::DashLine); -            pen.setColor(Qt::black); -            pen.setCosmetic(true); -            p.setPen(pen); -            p.drawRect(sx, 0, ex - sx, hh); -      }   -      //p.fillRect(sx, 0, ex - sx, hh, brush); -      //p.drawRect(sx, 0, ex - sx, hh, brush); -       -      MusECore::SndFileR f = event.sndFile(); -      if(f.isNull()) -      { -        p.setWorldMatrixEnabled(wmtxen); -        return; +          p.fillRect(sx, y1, ex - sx + 1, y2, brush);        } -       -      int ev_channels = f.channels(); -      if (ev_channels == 0) { -            p.setWorldMatrixEnabled(wmtxen); -            printf("WaveCnvas::drawItem: ev_channels==0! %s\n", f.name().toLatin1().constData()); -            return; -            } -                   -      h       = hh / (ev_channels * 2); -      int cc  = hh % (ev_channels * 2) ? 0 : 1; -      unsigned peoffset = px + event.frame() - event.spos(); -       -      for (int i = sx; i < ex; i++) { -            y  = mr.y() + h; -            MusECore::SampleV sa[f.channels()]; -            f.read(sa, xScale, pos); -            pos += xScale; -            if (pos < event.spos()) -                  continue; +      MusECore::SndFileR f = event.sndFile(); +      if(!f.isNull()) +      { +        int ev_channels = f.channels(); +        if (ev_channels == 0) { +              p.setWorldMatrixEnabled(wmtxen); +              printf("WaveCnvas::drawItem: ev_channels==0! %s\n", f.name().toLatin1().constData()); +              return; +              } -            int selectionStartPos = selectionStart - peoffset; // Offset transformed to event coords -            int selectionStopPos  = selectionStop  - peoffset; - -            for (int k = 0; k < ev_channels; ++k) { -                  int kk = k % f.channels(); -                  int peak = (sa[kk].peak * (h - 1)) / yScale; -                  int rms  = (sa[kk].rms  * (h - 1)) / yScale; -                  if (peak > h) -                        peak = h; -                  if (rms > h) -                        rms = h; -                  QColor peak_color = QColor(Qt::darkGray); -                  QColor rms_color  = QColor(Qt::black); -                   -                  // Changed by T356. Reduces (but not eliminates) drawing artifacts. (TODO Cause of artifacts gone, correct this now.) -                  //if (pos > selectionStartPos && pos < selectionStopPos) { -                  if (pos > selectionStartPos && pos <= selectionStopPos) { -                         -                        peak_color = QColor(Qt::lightGray); -                        rms_color  = QColor(Qt::white); -                        // Draw inverted -                        p.setPen(QColor(Qt::black)); -                        p.drawLine(i, y - h + cc, i, y + h - cc ); +        int h   = hh / (ev_channels * 2); +        int cc  = hh % (ev_channels * 2) ? 0 : 1; + +        unsigned peoffset = px + event.frame() - event.spos(); + +        for (int i = sx; i < ex; i++) { +              int y = h; +              MusECore::SampleV sa[f.channels()]; +              f.read(sa, xScale, pos); +              pos += xScale; +              if (pos < event.spos()) +                    continue; + +              int selectionStartPos = selectionStart - peoffset; // Offset transformed to event coords +              int selectionStopPos  = selectionStop  - peoffset; + +              for (int k = 0; k < ev_channels; ++k) { +                    int kk = k % f.channels(); +                    int peak = (sa[kk].peak * (h - 1)) / yScale; +                    int rms  = (sa[kk].rms  * (h - 1)) / yScale; +                    if (peak > h) +                          peak = h; +                    if (rms > h) +                          rms = h; +                    QColor peak_color = QColor(Qt::darkGray); +                    QColor rms_color  = QColor(Qt::black); + +                    if (pos > selectionStartPos && pos < selectionStopPos) { +                          peak_color = QColor(Qt::lightGray); +                          rms_color  = QColor(Qt::white); +                          QLine l_inv = clipQLine(i, y - h + cc, i, y + h - cc, mr); +                          if(!l_inv.isNull()) +                          { +                            // Draw inverted +                            p.setPen(QColor(Qt::black)); +                            p.drawLine(l_inv); +                          }                          } -                  p.setPen(peak_color); -                  p.drawLine(i, y - peak - cc, i, y + peak); -                  p.setPen(rms_color); -                  p.drawLine(i, y - rms - cc, i, y + rms); -                  y  += 2 * h; + +                    QLine l_peak = clipQLine(i, y - peak - cc, i, y + peak, mr); +                    if(!l_peak.isNull()) +                    { +                      p.setPen(peak_color); +                      p.drawLine(l_peak); +                    } + +                    QLine l_rms = clipQLine(i, y - rms - cc, i, y + rms, mr); +                    if(!l_rms.isNull()) +                    { +                      p.setPen(rms_color); +                      p.drawLine(l_rms); +                    } + +                    y += 2 * h;                    } -            } +              } - -      int hn = hh / ev_channels; -      int hhn = hn / 2; -      for (int i = 0; i < ev_channels; ++i) { -            int h2     = hn * i; -            int center = hhn + h2; -            p.setPen(QColor(i & i ? Qt::red : Qt::blue)); -            p.drawLine(sx, center, ex, center); -            p.setPen(QColor(Qt::black)); -            p.drawLine(sx, h2, ex, h2); +        int hn = hh / ev_channels; +        int hhn = hn / 2; +        for (int i = 0; i < ev_channels; ++i) { +              int h2     = hn * i; +              int center = hhn + h2; +              if(center >= y1 && center < y2) +              { +                p.setPen(QColor(i & 1 ? Qt::red : Qt::blue)); +                p.drawLine(sx, center, ex, center); +              } +              if(i != 0 && h2 >= y1 && h2 < y2) +              { +                p.setPen(QColor(Qt::black)); +                p.drawLine(sx, h2, ex, h2); +              }              } -             +      } + +      //       +      // Draw custom dashed borders around the wave event +      // + +      QColor color(item->isSelected() ? Qt::white : Qt::black); +      QPen penH(color); +      QPen penV(color); +      penH.setCosmetic(true); +      penV.setCosmetic(true); +      QVector<qreal> customDashPattern; +      customDashPattern << 4.0 << 6.0; +      penH.setDashPattern(customDashPattern); +      penV.setDashPattern(customDashPattern); +      penV.setDashOffset(2.0); +      // FIXME: Some shifting still going on. Values likely not quite right here. +      //int xdiff = sx - r.x(); +      int xdiff = sx - mer.x(); +      if(xdiff > 0) +      { +        int doff = xdiff % 10; +        penH.setDashOffset(doff); +      } +      // Tested OK. Each segment drawn only when necessary. +      if(y1 <= 0) +      { +        p.setPen(penH); +        p.drawLine(sx, 0, ex, 0); +      } +      if(y2 >= hh - 1) +      { +        p.setPen(penH); +        p.drawLine(sx, hh - 1, ex, hh - 1); +      } +      if(x1 <= mer.x()) +      { +        p.setPen(penV); +        p.drawLine(mer.x(), y1, mer.x(), y2); +      } +      if(x2 >= mer.x() + mer.width()) +      { +        p.setPen(penV); +        p.drawLine(mer.x() + mer.width(), y1, mer.x() + mer.width(), y2); +      } + +      // Done. Restore and return.        p.setWorldMatrixEnabled(wmtxen);  } diff --git a/muse2/muse/widgets/canvas.cpp b/muse2/muse/widgets/canvas.cpp index b5df2494..51612884 100644 --- a/muse2/muse/widgets/canvas.cpp +++ b/muse2/muse/widgets/canvas.cpp @@ -730,26 +730,26 @@ void Canvas::viewMousePressEvent(QMouseEvent* event)                    case PanTool:                          {                            drag = DRAG_PAN; +                          setCursor();                            if(MusEGlobal::config.borderlessMouse)                            {                              QRect r = QApplication::desktop()->screenGeometry();                              ignore_mouse_move = true;      // Avoid recursion.                              QCursor::setPos( QPoint(r.width()/2, r.height()/2) );                            } -                          setCursor();                          }                          break;                    case ZoomTool:                          {                            drag = DRAG_ZOOM; +                          setCursor();                            if(MusEGlobal::config.borderlessMouse)                            {                              QRect r = QApplication::desktop()->screenGeometry();                              ignore_mouse_move = true;      // Avoid recursion.                              QCursor::setPos( QPoint(r.width()/2, r.height()/2) );                            } -                          setCursor();                            // Update the small zoom drawing area                            QPoint pt = mapFromGlobal(global_start);                            update(pt.x(), pt.y(), zoomIcon->width(), zoomIcon->height());  | 
