summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim E. Real <termtech@rogers.com>2013-03-01 03:36:47 +0000
committerTim E. Real <termtech@rogers.com>2013-03-01 03:36:47 +0000
commit887f6426bd58f1bfd2bc38d1a2b57f1f4be5edbc (patch)
tree99e5109acaa03b3b061932d9163b96d6d0e47038
parentdbae4f58499946ec53d5f210ca6bf3af7574983f (diff)
Wave Editor: Fixed some painting problems. Optimizations, speed boosts.
-rw-r--r--muse2/ChangeLog2
-rw-r--r--muse2/muse/helper.cpp54
-rw-r--r--muse2/muse/helper.h4
-rw-r--r--muse2/muse/waveedit/wavecanvas.cpp219
-rw-r--r--muse2/muse/widgets/canvas.cpp4
5 files changed, 194 insertions, 89 deletions
diff --git a/muse2/ChangeLog b/muse2/ChangeLog
index 83ad8da6..d6b03f1a 100644
--- a/muse2/ChangeLog
+++ b/muse2/ChangeLog
@@ -1,3 +1,5 @@
+28.02.2013:
+ - Wave Editor: Fixed some painting problems. Optimizations, speed boosts. (Tim)
24.02.2013:
- Improved dark theme, midi editors now set background color, the current part of the ruler is darker.
Theme setting separated from the regular Ok button in the Appearance settings. Also fixed the color
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());