summaryrefslogtreecommitdiff
path: root/muse2/muse
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 /muse2/muse
parentdbae4f58499946ec53d5f210ca6bf3af7574983f (diff)
Wave Editor: Fixed some painting problems. Optimizations, speed boosts.
Diffstat (limited to 'muse2/muse')
-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
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());