summaryrefslogtreecommitdiff
path: root/muse2
diff options
context:
space:
mode:
Diffstat (limited to 'muse2')
-rw-r--r--muse2/ChangeLog19
-rw-r--r--muse2/muse/app.cpp4
-rw-r--r--muse2/muse/arranger/pcanvas.cpp1202
-rw-r--r--muse2/muse/arranger/pcanvas.h8
-rw-r--r--muse2/muse/arranger/tlist.cpp3
-rw-r--r--muse2/muse/ctrl/ctrlcanvas.cpp3
-rw-r--r--muse2/muse/driver/jack.cpp18
-rw-r--r--muse2/muse/functions.cpp6
-rw-r--r--muse2/muse/master/master.cpp3
-rw-r--r--muse2/muse/master/masteredit.cpp2
-rw-r--r--muse2/muse/master/tscale.cpp12
-rw-r--r--muse2/muse/midiedit/dcanvas.cpp6
-rw-r--r--muse2/muse/midiedit/dlist.cpp12
-rw-r--r--muse2/muse/midiedit/drumedit.cpp2
-rw-r--r--muse2/muse/midiedit/pianoroll.cpp2
-rw-r--r--muse2/muse/midiedit/prcanvas.cpp159
-rw-r--r--muse2/muse/midiedit/scoreedit.cpp6
-rw-r--r--muse2/muse/mixer/astrip.cpp40
-rw-r--r--muse2/muse/mixer/mstrip.cpp23
-rw-r--r--muse2/muse/mixer/strip.cpp2
-rw-r--r--muse2/muse/mixer/strip.h2
-rw-r--r--muse2/muse/part.cpp42
-rw-r--r--muse2/muse/part.h13
-rw-r--r--muse2/muse/steprec.cpp4
-rw-r--r--muse2/muse/widgets/canvas.cpp174
-rw-r--r--muse2/muse/widgets/canvas.h1
-rw-r--r--muse2/muse/widgets/combobox.cpp64
-rw-r--r--muse2/muse/widgets/combobox.h24
-rw-r--r--muse2/muse/widgets/knob.cpp31
-rw-r--r--muse2/muse/widgets/knob.h5
-rw-r--r--muse2/muse/widgets/meter.cpp168
-rw-r--r--muse2/muse/widgets/meter.h37
-rw-r--r--muse2/muse/widgets/verticalmeter.cpp81
-rw-r--r--muse2/muse/widgets/verticalmeter.h2
-rw-r--r--muse2/muse/widgets/view.cpp300
-rw-r--r--muse2/muse/widgets/view.h6
36 files changed, 2027 insertions, 459 deletions
diff --git a/muse2/ChangeLog b/muse2/ChangeLog
index 625ab3f4..d5dd93ce 100644
--- a/muse2/ChangeLog
+++ b/muse2/ChangeLog
@@ -1,3 +1,22 @@
+17.08.2011:
+ - Convert some Qt3 style coding in ComboBox to Qt4 in terms of menu entry handling. (Orcan)
+ - Add mouse wheel support to ComboBox. (Orcan)
+ - Fix AutoType indicator coloring. (Orcan)
+16.08.2011:
+ - More drawing fixes, improved accuracy (grids, timescales, edges, markers guaranteed to align now). (Tim p4.0.30)
+ Much drawing changed to device (pixel) space instead of virtual space, for accuracy.
+ - Fixed display of audio automation graphs. (But not editing). (Tim)
+ - Fixed unreadable Master Edit tempo scale (on left side), and added toolbar saving and restoring. (Tim p4.0.31)
+15.08.2011:
+ - Remodel the Meter and the VerticalMeter (Orcan)
+13.08.2011:
+ - Make the shininess of the Knob ring a little smarter (Orcan)
+05.08.2011:
+ - Parts having hidden events now drawn using 'jagged' ends and special white edges. (Tim p4.0.29)
+ - Improved border drawing guaranteed to show L/R touching part borders. TODO: Top and bottom borders. (Tim)
+ - Muted parts now show names and events. Filled with a special brush pattern for easy recognition. (Tim)
+ - Huge changes to PartCanvas::drawItem(). And to all View::XmapXXX methods for better accuracy. (Tim)
+ - Changed bool Part::hasHiddenNotes() to int Part::hasHiddenEvents(). Added int Part::cachedHasHiddenEvents(). (Tim)
02.08.2011:
- Changed behaviour of part clones (flo93)
diff --git a/muse2/muse/app.cpp b/muse2/muse/app.cpp
index e48425d7..8f059c73 100644
--- a/muse2/muse/app.cpp
+++ b/muse2/muse/app.cpp
@@ -1422,7 +1422,7 @@ void MusE::closeEvent(QCloseEvent* event)
n = QMessageBox::warning(this, appName,
tr("The current Project contains unsaved data\n"
"Save Current Project?"),
- tr("&Save"), tr("&Skip"), tr("&Cancel"), 0, 2);
+ tr("&Save"), tr("S&kip"), tr("&Cancel"), 0, 2);
if (n == 0) {
if (!save()) // dont quit if save failed
{
@@ -2601,7 +2601,7 @@ bool MusE::clearSong(bool clear_all)
tr("The current Project contains unsaved data\n"
"Load overwrites current Project:\n"
"Save Current Project?"),
- tr("&Save"), tr("&Skip"), tr("&Abort"), 0, 2);
+ tr("&Save"), tr("S&kip"), tr("&Abort"), 0, 2);
switch (n) {
case 0:
if (!save()) // abort if save failed
diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp
index d223321b..cf376042 100644
--- a/muse2/muse/arranger/pcanvas.cpp
+++ b/muse2/muse/arranger/pcanvas.cpp
@@ -3,6 +3,7 @@
// Linux Music Editor
// $Id: pcanvas.cpp,v 1.48.2.26 2009/11/22 11:08:33 spamatica Exp $
// (C) Copyright 1999 Werner Schweer (ws@seh.de)
+// Additions, modifications (C) Copyright 2011 Tim E. Real (terminator356 on users DOT sourceforge DOT net)
//=========================================================
#include <stdio.h>
@@ -45,7 +46,6 @@
#include "midictrl.h"
#include "utils.h"
-
//---------------------------------------------------------
// colorRect
// paints a rectangular icon with a given color
@@ -69,17 +69,12 @@ QIcon colorRect(const QColor& color, int width, int height) {
NPart::NPart(Part* e) : CItem(Event(), e)
{
- int th = track()->height();
- int y = track()->y();
+ leftBorderTouches = false;
+ rightBorderTouches = false;
- ///setPos(QPoint(e->tick(), y + 1));
+ int y = track()->y();
setPos(QPoint(e->tick(), y));
-
- ///setBBox(QRect(e->tick(), y + 1, e->lenTick(), th));
- // NOTE: For adjustable border size: If using a two-pixel border width while drawing, use second line.
- // If one-pixel width, use first line. Tim.
- //setBBox(QRect(e->tick(), y, e->lenTick(), th));
- setBBox(QRect(e->tick(), y + 1, e->lenTick(), th));
+ setBBox(QRect(e->tick(), y, e->lenTick(), track()->height()));
}
//---------------------------------------------------------
@@ -418,17 +413,31 @@ QPoint PartCanvas::raster(const QPoint& p) const
void PartCanvas::partsChanged()
{
items.clear();
- int idx = 0;
for (iTrack t = tracks->begin(); t != tracks->end(); ++t) {
PartList* pl = (*t)->parts();
for (iPart i = pl->begin(); i != pl->end(); ++i) {
- NPart* np = new NPart(i->second);
+ Part* part = i->second;
+ NPart* np = new NPart(part);
items.add(np);
if (i->second->selected()) {
selectItem(np, true);
}
- }
- ++idx;
+
+ // Check for touching borders. p4.0.29
+ Part* pp;
+ for(ciPart ii = pl->begin(); ii != pl->end(); ++ii)
+ {
+ pp = ii->second;
+ if(pp == part) // Ignore this part
+ continue;
+ if(pp->tick() > part->endTick())
+ break;
+ if(pp->endTick() == part->tick())
+ np->leftBorderTouches = true;
+ if(pp->tick() == part->endTick())
+ np->rightBorderTouches = true;
+ }
+ }
}
redraw();
}
@@ -1275,6 +1284,7 @@ void PartCanvas::keyPress(QKeyEvent* event)
// draws a part
//---------------------------------------------------------
+#if 0
void PartCanvas::drawItem(QPainter& p, const CItem* item, const QRect& rect)
{
int from = rect.x();
@@ -1298,84 +1308,215 @@ void PartCanvas::drawItem(QPainter& p, const CItem* item, const QRect& rect)
}
QRect r = item->bbox();
+ bool clone = part->events()->arefCount() > 1;
+ QBrush brush;
- int i = part->colorIndex();
- p.setPen(Qt::black);
- if (part->mute()) {
- QColor c(Qt::white);
+ //QRect rr = map(r);
+ //QRect rr = p.transform().mapRect(r);
+ //printf("PartCanvas::drawItem called map rx:%d rw:%d rrx:%d rrw:%d\n", r.x(), r.width(), rr.x(), rr.width());
+ //printf("PartCanvas::drawItem called map rx:%d rw:%d\n", r.x(), r.width());
+ //p.save();
+ //p.setWorldMatrixEnabled(false);
+
+ // NOTE: Optimization: For each item, hasHiddenEvents() is called once in Canvas::draw(), and we use cachedHasHiddenEvents().
+ // Not used for now.
+ //int het = part->cachedHasHiddenEvents();
+ int het = part->hasHiddenEvents();
+
+ int y_1 = rmapyDev(1); // Hack, try to replace.
+ double xs_0 = r.x();
+ double xe_0 = xs_0 + r.width();
+ double xs_m0 = rmapx_f(xs_0);
+ double xe_m0 = rmapx_f(xe_0);
+ double xs_1 = rmapxDev_f(xs_m0 + 1.0);
+ if(xs_1 > xe_0)
+ xs_1 = xe_0;
+ double xs_2 = rmapxDev_f(xs_m0 + 2.0);
+ if(xs_2 > xe_0)
+ xs_2 = xe_0;
+ double xs_6 = rmapxDev_f(xs_m0 + 6.0);
+ if(xs_6 > xe_0)
+ xs_6 = xe_0;
+
+ double xe_1 = rmapxDev_f(xe_m0 - 1.0);
+ if(xe_1 < xs_0)
+ xe_1 = xs_0;
+ double xe_2 = rmapxDev_f(xe_m0 - 2.0);
+ if(xe_2 < xs_0)
+ xe_2 = xs_0;
+ double xe_6 = rmapxDev_f(xe_m0 - 6.0);
+ if(xe_6 < xs_0)
+ xe_6 = xs_0;
+
+ double ys_0 = r.y();
+ double ye_0 = ys_0 + r.height();
+ double ys_m0 = rmapy_f(ys_0);
+ double ye_m0 = rmapy_f(ye_0);
+ double ys_1 = rmapyDev_f(ys_m0 + 1.0);
+ if(ys_1 > ye_0)
+ ys_1 = ye_0;
+ double ys_2 = rmapyDev_f(ys_m0 + 2.0);
+ if(ys_2 > ye_0)
+ ys_2 = ye_0;
+
+ double ye_1 = rmapyDev_f(ye_m0 - 1.0);
+ if(ye_1 < ys_0)
+ ye_1 = ys_0;
+ double ye_2 = rmapyDev_f(ye_m0 - 2.0);
+ if(ye_2 < ys_0)
+ ye_2 = ys_0;
+
+ int cidx = part->colorIndex();
+ if (item->isMoving())
+ {
+ QColor c(Qt::gray);
c.setAlpha(config.globalAlphaBlend);
QLinearGradient gradient(r.topLeft(), r.bottomLeft());
gradient.setColorAt(0, c);
gradient.setColorAt(1, c.darker());
- QBrush cc(gradient);
- p.setBrush(cc);
-
- // NOTE: For one-pixel border use first line For two-pixel border use second.
- p.drawRect(QRect(r.x(), r.y()-1, r.width(), r.height()));
-
- return;
- }
- if (item->isMoving()) {
- QColor c(Qt::gray);
+ brush = QBrush(gradient);
+ }
+ else
+ if (part->selected())
+ {
+ QColor c(Qt::black);
+ c.setAlpha(config.globalAlphaBlend);
+ QLinearGradient gradient(r.topLeft(), r.bottomLeft());
+ // Use a colour only about 20% lighter than black, rather than the 50% we use in 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, config.globalAlphaBlend));
+ gradient.setColorAt(1, c);
+ brush = QBrush(gradient);
+ }
+ else
+ if (part->mute())
+ {
+ QColor c(Qt::white);
c.setAlpha(config.globalAlphaBlend);
QLinearGradient gradient(r.topLeft(), r.bottomLeft());
gradient.setColorAt(0, c);
gradient.setColorAt(1, c.darker());
- QBrush cc(gradient);
- p.setBrush(cc);
-
- // NOTE: For one-pixel border use first line. For two-pixel border use second.
- p.drawRect(QRect(r.x(), r.y()-1, r.width(), r.height()));
- }
- else if (part->selected()) {
- bool clone = part->events()->arefCount() > 1;
-
- // NOTE: For one-pixel border use first line and don't bother with setCosmetic.
- // For a two-pixel border use second line and MUST use setCosmetic! Tim.
- //p.setPen(QPen(config.partColors[i], 0, clone ? Qt::DashLine : Qt::SolidLine));
- QPen pen(config.partColors[i], 2, clone ? Qt::DashLine : Qt::SolidLine);
- pen.setCosmetic(true);
+ brush = QBrush(gradient);
- p.setPen(pen);
- // Hm, put some kind of lower limit? If so do that globally to the adjustment.
- QColor c(Qt::black);
- c.setAlpha(config.globalAlphaBlend);
-
- QLinearGradient gradient(r.topLeft(), r.bottomLeft());
- //gradient.setColorAt(0, c);
- //gradient.setColorAt(1, c.darker());
- // Use a colour only about 20% lighter than black, rather than the 50% we use in 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, config.globalAlphaBlend));
- gradient.setColorAt(1, c);
- QBrush cc(gradient);
- //QBrush cc(gGradientFromQColor(c, r.topLeft(), r.bottomLeft()));
-
- p.setBrush(cc);
- p.drawRect(r);
- }
- else {
- bool clone = part->events()->arefCount() > 1;
-
- // NOTE: Pixel width: See above note.
- //p.setPen(QPen(Qt::black, 0, clone ? Qt::DashLine : Qt::SolidLine));
- QPen pen(Qt::black, 2, clone ? Qt::DashLine : Qt::SolidLine);
- pen.setCosmetic(true);
-
- p.setPen(pen);
- QColor c(config.partColors[i]);
+ // Not good. Aliasing missing lines happening at different mags.
+ // And it's too much. If notes + automation is displayed (by removing 'return' below), cross hatch interferes.
+ // TODO: Maybe try to draw a nice gradient SINGLE cross (or STAR) from corner to corner instead.
+ // Then remove the 'return' below and let it draw the name and notes.
+ //brush.setStyle(Qt::DiagCrossPattern);
+ //p.fillRect(rf, brush);
+ }
+ else
+ {
+ QColor c(config.partColors[cidx]);
c.setAlpha(config.globalAlphaBlend);
- //QLinearGradient gradient(r.topLeft(), r.bottomLeft());
- //gradient.setColorAt(0, c);
- //gradient.setColorAt(1, c.darker());
- //QBrush cc(gradient);
- QBrush cc(gGradientFromQColor(c, r.topLeft(), r.bottomLeft()));
- p.setBrush(cc);
-
- p.drawRect(r);
- }
+ brush = QBrush(gGradientFromQColor(c, r.topLeft(), r.bottomLeft()));
+ }
+
+ double h = r.height();
+ double s = h / 4.0;
+ double y0 = r.y();
+ double y1 = y0 + s;
+ double y2 = y0 + s * 2.0;
+ double y3 = y0 + s * 3.0;
+ double y4 = y0 + h;
+ QPointF points[16];
+ int pts;
+
+ //
+ // Fill the part rectangles, accounting for hidden events by using 'jagged' edges...
+ //
+
+ p.setBrush(brush);
+ p.setPen(Qt::NoPen);
+ if(het)
+ {
+ pts = 0;
+ if(het == (Part::LeftEventsHidden | Part::RightEventsHidden))
+ {
+ points[pts++] = QPointF(xs_0, y0);
+ points[pts++] = QPointF(xe_0, y0);
+ points[pts++] = QPointF(xe_6, y1);
+ points[pts++] = QPointF(xe_0, y2);
+ points[pts++] = QPointF(xe_6, y3);
+ points[pts++] = QPointF(xe_0, y4);
+ points[pts++] = QPointF(xs_0, y4);
+ points[pts++] = QPointF(xs_6, y3);
+ points[pts++] = QPointF(xs_0, y2);
+ points[pts++] = QPointF(xs_6, y1);
+ p.drawConvexPolygon(points, pts); // Help says may be faster on some platforms (X11).
+ }
+ else
+ if(het == Part::LeftEventsHidden)
+ {
+ points[pts++] = QPointF(xs_0, y0);
+ points[pts++] = QPointF(xe_0, y0);
+ points[pts++] = QPointF(xe_0, y4);
+ points[pts++] = QPointF(xs_0, y4);
+ points[pts++] = QPointF(xs_6, y3);
+ points[pts++] = QPointF(xs_0, y2);
+ points[pts++] = QPointF(xs_6, y1);
+ p.drawConvexPolygon(points, pts);
+ }
+ else
+ if(het == Part::RightEventsHidden)
+ {
+ points[pts++] = QPointF(xs_0, y0);
+ points[pts++] = QPointF(xe_0, y0);
+
+ points[pts++] = QPointF(xe_6, y1);
+ points[pts++] = QPointF(xe_0, y2);
+ points[pts++] = QPointF(xe_6, y3);
+ points[pts++] = QPointF(xe_0, y4);
+ points[pts++] = QPointF(xs_0, y4);
+ p.drawConvexPolygon(points, pts);
+ }
+
+ //
+ // Draw remaining 'hidden events' decorations with 'jagged' edges...
+ //
+
+ int part_r, part_g, part_b, brightness, color_brightness;
+ config.partColors[cidx].getRgb(&part_r, &part_g, &part_b);
+ brightness = part_r*29 + part_g*59 + part_b*12;
+ //if ((brightness < 12000 || part->selected()) && !part->mute() && !item->isMoving())
+ // color_brightness=223; // too dark: use lighter color
+ //else
+ // color_brightness=32; // otherwise use dark color
+ if ((brightness >= 12000 && !part->selected()))
+ color_brightness=32; // too light: use dark color
+ else
+ color_brightness=223; // too dark: use lighter color
+ QColor c(color_brightness,color_brightness,color_brightness, config.globalAlphaBlend);
+ p.setBrush(QBrush(gGradientFromQColor(c, r.topLeft(), r.bottomLeft())));
+ //p.setBrush(QBrush(c));
+ if(het & Part::RightEventsHidden)
+ {
+ pts = 0;
+ points[pts++] = QPointF(xe_0, y0);
+ points[pts++] = QPointF(xe_0, y4);
+ points[pts++] = QPointF(xe_6, y3);
+ points[pts++] = QPointF(xe_0, y2);
+ points[pts++] = QPointF(xe_6, y1);
+ p.drawConvexPolygon(points, pts);
+ }
+ if(het & Part::LeftEventsHidden)
+ {
+ pts = 0;
+ points[pts++] = QPointF(xs_0, y0);
+ points[pts++] = QPointF(xs_6, y1);
+ points[pts++] = QPointF(xs_0, y2);
+ points[pts++] = QPointF(xs_6, y3);
+ points[pts++] = QPointF(xs_0, y4);
+ p.drawConvexPolygon(points, pts);
+ }
+ }
+ else
+ {
+ p.fillRect(r, brush);
+ }
+
MidiPart* mp = 0;
WavePart* wp = 0;
Track::TrackType type = part->track()->type();
@@ -1393,40 +1534,640 @@ void PartCanvas::drawItem(QPainter& p, const CItem* item, const QRect& rect)
drawMidiPart(p, rect, mp->events(), (MidiTrack*)part->track(), mp, r, mp->tick(), from, to);
}
+ #if 0
+ //
+ // Now draw the borders...
+ // Works great but requires clones be drawn with the highest priority on top of all other parts, in Canvas::draw.
+ //
+
+ QPen pen(part->selected() ? config.partColors[i] : Qt::black, 2.0, clone ? Qt::DotLine : Qt::SolidLine);
+ pen.setCosmetic(true);
+ p.setPen(pen);
+ p.setBrush(Qt::NoBrush);
+ p.drawRect(r);
+
+ #else
+ //
+ // Now draw the borders, using custom segments...
+ //
+
+ // FIXME NOTE: For 1-pixel wide lines, setting pen style to anything other than solid didn't work out well.
+ // Much too screwy - the single-width lines kept getting shifted one pixel over intermittently.
+ // I tried EVERYTHING to make sure x is proper but the painter keeps shifting them over.
+ // Meanwhile the fills are correct. Seems painter doesn't like line patterns, whether stock or custom.
+ // Therefore I was forced to manually draw the left and right segments.
+ // It works. Which seems to be more proof that painter is handling line patterns and pen widths badly...
+ // DO NOT ERASE COMMENTED CODE BELOW for now, in case it can be fixed. Tim. p4.0.29
+
+ p.setBrush(Qt::NoBrush);
+
+ QColor pc((part->mute() || item->isMoving())? Qt::white : config.partColors[cidx]);
+ QPen penSelect1H(pc);
+ QPen penSelect2H(pc, 2.0);
+ QPen penSelect1V(pc);
+ QPen penSelect2V(pc, 2.0);
+ penSelect1H.setCosmetic(true);
+ penSelect2H.setCosmetic(true);
+ penSelect1V.setCosmetic(true);
+ penSelect2V.setCosmetic(true);
+
+ pc = Qt::black;
+ QPen penNormal1H(pc);
+ QPen penNormal2H(pc, 2.0);
+ QPen penNormal1V(pc);
+ QPen penNormal2V(pc, 2.0);
+ penNormal1H.setCosmetic(true);
+ penNormal2H.setCosmetic(true);
+ penNormal1V.setCosmetic(true);
+ penNormal2V.setCosmetic(true);
+
+ QVector<qreal> customDashPattern;
+ if(clone)
+ {
+ customDashPattern << 4.0 << 8.0;
+ penSelect1H.setDashPattern(customDashPattern);
+ penNormal1H.setDashPattern(customDashPattern);
+ //penSelect1V.setDashPattern(customDashPattern);
+ //penNormal1V.setDashPattern(customDashPattern);
+ customDashPattern.clear();
+ customDashPattern << 2.0 << 4.0;
+ penSelect2H.setDashPattern(customDashPattern);
+ penNormal2H.setDashPattern(customDashPattern);
+ //penSelect2V.setDashPattern(customDashPattern);
+ //penNormal2V.setDashPattern(customDashPattern);
+ }
+
+ pc = Qt::white;
+ QPen penHidden1(pc);
+ QPen penHidden2(pc, 2.0);
+ penHidden2.setCosmetic(true);
+ //customDashPattern.clear();
+ //customDashPattern << 2.0 << 10.0;
+ //penHidden1.setDashPattern(customDashPattern);
+ //customDashPattern.clear();
+ //customDashPattern << 1.0 << 5.0;
+ //penHidden2.setDashPattern(customDashPattern);
+
+ bool lbt = ((NPart*)item)->leftBorderTouches;
+ bool rbt = ((NPart*)item)->rightBorderTouches;
+
+ QLineF l1( lbt?xs_1:xs_0, ys_0, rbt?xe_1:xe_0, ys_0); // Top
+ //QLineF l2(rbt?xe_1:xe_0, r.y() + (rbt?y_1:y_2) - 1, rbt?xe_1:xe_0, r.y() + r.height() - 1); // Right
+ QLineF l3( lbt?xs_1:xs_0, ye_0, rbt?xe_1:xe_0, ye_0); // Bottom
+ //QLineF l4(r.x(), r.y() + (lbt?y_1:y_2), r.x(), r.y() + r.height() - (lbt?y_1:y_2)); // Left
+
+ if(het & Part::RightEventsHidden)
+ p.setPen(((NPart*)item)->rightBorderTouches ? penHidden1 : penHidden2);
+ else
+ {
+ if(((NPart*)item)->rightBorderTouches)
+ p.setPen(part->selected() ? penSelect1V : penNormal1V);
+ else
+ p.setPen(part->selected() ? penSelect2V : penNormal2V);
+ }
+ //p.drawLine(l2); // Right line
+
+ double xx = rbt?xe_1:xe_0;
+ if(clone)
+ {
+ double yinc = 7.0 * y_1;
+ for(double yy = (rbt?ys_1:ys_2); yy < ye_2; yy += yinc)
+ {
+ double yi = (rbt?3.0:2.0) * y_1;
+ if(yy + yi > ye_2)
+ yi = ye_2 - yy;
+ p.drawLine(QPointF(xx, yy), QPointF(xx, yy + yi)); // Right dashed line
+ }
+ }
+ else
+ p.drawLine(QPointF(xx, rbt?ys_1:ys_2), QPointF(xx, rbt?ye_1:ye_2)); // Right line
+
+ if(het & Part::LeftEventsHidden)
+ p.setPen(((NPart*)item)->leftBorderTouches ? penHidden1 : penHidden2);
+ else
+ {
+ if(((NPart*)item)->leftBorderTouches)
+ p.setPen(part->selected() ? penSelect1V : penNormal1V);
+ else
+ p.setPen(part->selected() ? penSelect2V : penNormal2V);
+ }
+ //p.drawLine(l4); // Left line
+
+ xx = xs_0;
+ if(clone)
+ {
+ double yinc = 7.0 * y_1;
+ for(double yy = (lbt?ys_1:ys_2); yy < ye_2; yy += yinc)
+ {
+ double yi = (lbt?3.0:2.0) * y_1;
+ if(yy + yi > ye_2)
+ yi = ye_2 - yy;
+ p.drawLine(QPointF(xx, yy), QPointF(xx, yy + yi)); // Left dashed line
+ }
+ }
+ else
+ p.drawLine(QPointF(xx, lbt?ys_1:ys_2), QPointF(xx, lbt?ye_1:ye_2)); // Left line
+
+ p.setPen(part->selected() ? penSelect2H : penNormal2H);
+ p.drawLine(l1); // Top line
+ p.drawLine(l3); // Bottom line
+
+ #endif
+
+ //p.restore();
+
if (config.canvasShowPartType & 1) { // show names
// draw name
// FN: Set text color depending on part color (black / white)
int part_r, part_g, part_b, brightness;
- //config.partColors[i].getRgb(&part_r, &part_g, &part_b);
// Since we'll draw the text on the bottom (to accommodate drum 'slivers'),
// get the lowest colour in the gradient used to draw the part.
QRect rr = map(r);
rr.setX(rr.x() + 3);
- gGradientFromQColor(config.partColors[i], rr.topLeft(), rr.bottomLeft()).stops().last().second.getRgb(&part_r, &part_g, &part_b);
+ gGradientFromQColor(config.partColors[cidx], rr.topLeft(), rr.bottomLeft()).stops().last().second.getRgb(&part_r, &part_g, &part_b);
brightness = part_r*29 + part_g*59 + part_b*12;
- //if (brightness < 12000 || part->selected())
- // p.setPen(Qt::white); /* too dark: use white for text color */
- //else
- // p.setPen(Qt::black); /* otherwise use black */
- bool rev = brightness < 12000 || part->selected();
- //QRect rr = map(r);
- //rr.setX(rr.x() + 3);
+ //bool rev = (brightness < 12000 || part->selected()) && !part->mute() && !item->isMoving();
+ bool rev = brightness >= 12000 && !part->selected();
p.save();
p.setFont(config.fonts[1]);
p.setWorldMatrixEnabled(false);
if (rev)
- p.setPen(Qt::black);
- else
p.setPen(Qt::white);
+ else
+ p.setPen(Qt::black);
p.drawText(rr.translated(1, 1), Qt::AlignBottom|Qt::AlignLeft, part->name());
if (rev)
- p.setPen(Qt::white);
- else
p.setPen(Qt::black);
+ else
+ p.setPen(Qt::white);
p.drawText(rr, Qt::AlignBottom|Qt::AlignLeft, part->name());
p.restore();
}
}
+#endif
+
+void PartCanvas::drawItem(QPainter& p, const CItem* item, const QRect& rect)
+ {
+ int from = rect.x();
+ int to = from + rect.width();
+
+ //printf("from %d to %d\n", from,to);
+ Part* part = ((NPart*)item)->part();
+ int pTick = part->tick();
+ from -= pTick;
+ to -= pTick;
+ if(from < 0)
+ from = 0;
+ if((unsigned int)to > part->lenTick())
+ to = part->lenTick();
+
+ bool clone = part->events()->arefCount() > 1;
+ QBrush brush;
+
+ QRect r = item->bbox();
+ // Compensation required for two pixel wide border. FIXME Prefer to do this after the map, but r is needed below.
+ r.moveTop(r.y() + rmapyDev(1));
+ //QRect rr = p.transform().mapRect(r); // Gives inconsistent positions. Source shows wrong operation for our needs.
+ QRect rr = map(r); // Use our own map instead.
+
+ // Item bounding box x is in tick coordinates, same as rectangle.
+ //if(item->bbox().intersect(rect).isNull())
+ //if((item->bbox() & rect).isNull())
+ if((rr & map(rect)).isNull())
+ {
+ //printf("PartCanvas::drawItem rectangle is null\n");
+ return;
+ }
+
+ //printf("PartCanvas::drawItem called map rx:%d rw:%d rrx:%d rrw:%d\n", r.x(), r.width(), rr.x(), rr.width());
+ //printf("PartCanvas::drawItem called map rx:%d rw:%d\n", r.x(), r.width());
+
+ p.save();
+ p.setWorldMatrixEnabled(false);
+
+ // NOTE: Optimization: For each item, hasHiddenEvents() is called once in Canvas::draw(), and we use cachedHasHiddenEvents().
+ // Not used for now.
+ //int het = part->cachedHasHiddenEvents();
+ int het = part->hasHiddenEvents();
+
+ int xs_0 = rr.x();
+ int xe_0 = xs_0 + rr.width();
+ int xs_1 = xs_0 + 1;
+ if(xs_1 > xe_0)
+ xs_1 = xe_0;
+ int xs_2 = xs_0 + 2;
+ if(xs_2 > xe_0)
+ xs_2 = xe_0;
+ int xs_j = xs_0 + 8;
+ if(xs_j > xe_0)
+ xs_j = xe_0;
+
+ int xe_1 = xe_0 - 1;
+ if(xe_1 < xs_0)
+ xe_1 = xs_0;
+ int xe_2 = xe_0 - 2;
+ if(xe_2 < xs_0)
+ xe_2 = xs_0;
+ int xe_j = xe_0 - 8;
+ if(xe_j < xs_0)
+ xe_j = xs_0;
+
+ int ys_0 = rr.y();
+ int ye_0 = ys_0 + rr.height();
+ int ys_1 = ys_0 + 1;
+ if(ys_1 > ye_0)
+ ys_1 = ye_0;
+ int ys_2 = ys_0 + 2;
+ if(ys_2 > ye_0)
+ ys_2 = ye_0;
+ int ys_3 = ys_0 + 3;
+ if(ys_3 > ye_0)
+ ys_3 = ye_0;
+
+ int ye_1 = ye_0 - 1;
+ if(ye_1 < ys_0)
+ ye_1 = ys_0;
+ int ye_2 = ye_0 - 2;
+ if(ye_2 < ys_0)
+ ye_2 = ys_0;
+
+ int cidx = part->colorIndex();
+ if (item->isMoving())
+ {
+ QColor c(Qt::gray);
+ c.setAlpha(config.globalAlphaBlend);
+ QLinearGradient gradient(rr.topLeft(), rr.bottomLeft());
+ gradient.setColorAt(0, c);
+ gradient.setColorAt(1, c.darker());
+ brush = QBrush(gradient);
+ }
+ else
+ if (part->selected())
+ {
+ QColor c(Qt::black);
+ c.setAlpha(config.globalAlphaBlend);
+ QLinearGradient gradient(rr.topLeft(), rr.bottomLeft());
+ // Use a colour only about 20% lighter than black, rather than the 50% we use in 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, config.globalAlphaBlend));
+ gradient.setColorAt(1, c);
+ brush = QBrush(gradient);
+ }
+ else
+ if (part->mute())
+ {
+ QColor c(Qt::white);
+ c.setAlpha(config.globalAlphaBlend);
+ QLinearGradient gradient(rr.topLeft(), rr.bottomLeft());
+ gradient.setColorAt(0, c);
+ gradient.setColorAt(1, c.darker());
+ brush = QBrush(gradient);
+ }
+ else
+ {
+ QColor c(config.partColors[cidx]);
+ c.setAlpha(config.globalAlphaBlend);
+ brush = QBrush(gGradientFromQColor(c, rr.topLeft(), rr.bottomLeft()));
+ }
+
+ int h = rr.height();
+ double s = double(h) / 4.0;
+ int y0 = ys_0;
+ //int y1 = y0 + lrint(s);
+ int y2 = y0 + lrint(s * 2.0);
+ //int y3 = y0 + lrint(s * 3.0);
+ int y4 = y0 + h;
+
+ //QPoint points[12];
+ QPoint points[8];
+ int pts;
+
+ //
+ // Fill the part rectangles, accounting for hidden events by using 'jagged' edges...
+ //
+
+ p.setBrush(brush);
+ p.setPen(Qt::NoPen);
+ if(het)
+ {
+ pts = 0;
+ if(het == (Part::LeftEventsHidden | Part::RightEventsHidden))
+ {
+ //points[pts++] = QPoint(xs_0, y0);
+ //points[pts++] = QPoint(xe_0, y0);
+ //points[pts++] = QPoint(xe_j, y1);
+ //points[pts++] = QPoint(xe_0, y2);
+ //points[pts++] = QPoint(xe_j, y3);
+ //points[pts++] = QPoint(xe_0, y4);
+ //points[pts++] = QPoint(xs_0, y4);
+ //points[pts++] = QPoint(xs_j, y3);
+ //points[pts++] = QPoint(xs_0, y2);
+ //points[pts++] = QPoint(xs_j, y1);
+
+ points[pts++] = QPoint(xs_0, y0);
+ points[pts++] = QPoint(xe_0, y0);
+ points[pts++] = QPoint(xe_j, y2);
+ points[pts++] = QPoint(xe_0, y4);
+ points[pts++] = QPoint(xs_0, y4);
+ points[pts++] = QPoint(xs_j, y2);
+
+ p.drawConvexPolygon(points, pts); // Help says may be faster on some platforms (X11).
+ }
+ else
+ if(het == Part::LeftEventsHidden)
+ {
+ //points[pts++] = QPoint(xs_0, y0);
+ //points[pts++] = QPoint(xe_0, y0);
+ //points[pts++] = QPoint(xe_0, y4);
+ //points[pts++] = QPoint(xs_0, y4);
+ //points[pts++] = QPoint(xs_j, y3);
+ //points[pts++] = QPoint(xs_0, y2);
+ //points[pts++] = QPoint(xs_j, y1);
+
+ points[pts++] = QPoint(xs_0, y0);
+ points[pts++] = QPoint(xe_0, y0);
+ points[pts++] = QPoint(xe_0, y4);
+ points[pts++] = QPoint(xs_0, y4);
+ points[pts++] = QPoint(xs_j, y2);
+
+ p.drawConvexPolygon(points, pts);
+ }
+ else
+ if(het == Part::RightEventsHidden)
+ {
+ //points[pts++] = QPoint(xs_0, y0);
+ //points[pts++] = QPoint(xe_0, y0);
+ //points[pts++] = QPoint(xe_j, y1);
+ //points[pts++] = QPoint(xe_0, y2);
+ //points[pts++] = QPoint(xe_j, y3);
+ //points[pts++] = QPoint(xe_0, y4);
+ //points[pts++] = QPoint(xs_0, y4);
+
+ points[pts++] = QPoint(xs_0, y0);
+ points[pts++] = QPoint(xe_0, y0);
+ points[pts++] = QPoint(xe_j, y2);
+ points[pts++] = QPoint(xe_0, y4);
+ points[pts++] = QPoint(xs_0, y4);
+
+ p.drawConvexPolygon(points, pts);
+ }
+
+ //
+ // Draw remaining 'hidden events' decorations with 'jagged' edges...
+ //
+
+ int part_r, part_g, part_b, brightness, color_brightness;
+ config.partColors[cidx].getRgb(&part_r, &part_g, &part_b);
+ brightness = part_r*29 + part_g*59 + part_b*12;
+ //if ((brightness < 12000 || part->selected()) && !part->mute() && !item->isMoving())
+ // color_brightness=223; // too dark: use lighter color
+ //else
+ // color_brightness=32; // otherwise use dark color
+ if ((brightness >= 12000 && !part->selected()))
+ color_brightness=96; //0; // too light: use dark color
+ else
+ color_brightness=180; //255; // too dark: use lighter color
+ QColor c(color_brightness,color_brightness,color_brightness, config.globalAlphaBlend);
+ p.setBrush(QBrush(gGradientFromQColor(c, rr.topLeft(), rr.bottomLeft())));
+ //p.setBrush(QBrush(c));
+ if(het & Part::RightEventsHidden)
+ {
+ pts = 0;
+ //points[pts++] = QPoint(xe_0, y0);
+ //points[pts++] = QPoint(xe_0, y4);
+ //points[pts++] = QPoint(xe_j, y3);
+ //points[pts++] = QPoint(xe_0, y2);
+ //points[pts++] = QPoint(xe_j, y1);
+
+ points[pts++] = QPoint(xe_0, y0);
+ points[pts++] = QPoint(xe_0, y4);
+ points[pts++] = QPoint(xe_j, y2);
+
+ p.drawConvexPolygon(points, pts);
+ }
+ if(het & Part::LeftEventsHidden)
+ {
+ pts = 0;
+ //points[pts++] = QPoint(xs_0, y0);
+ //points[pts++] = QPoint(xs_j, y1);
+ //points[pts++] = QPoint(xs_0, y2);
+ //points[pts++] = QPoint(xs_j, y3);
+ //points[pts++] = QPoint(xs_0, y4);
+
+ points[pts++] = QPoint(xs_0, y0);
+ points[pts++] = QPoint(xs_j, y2);
+ points[pts++] = QPoint(xs_0, y4);
+
+ p.drawConvexPolygon(points, pts);
+ }
+ }
+ else
+ {
+ p.fillRect(rr, brush);
+ }
+
+ // Draw a pattern brush on muted parts...
+ if(part->mute())
+ {
+ p.setPen(Qt::NoPen);
+ //brush.setStyle(Qt::DiagCrossPattern);
+ brush.setStyle(Qt::Dense7Pattern);
+
+ p.fillRect(rr, brush); // FIXME: Some shifting going on
+ //p.fillRect(QRect(rr.x(), rr.y(), rr.width() + 1, rr.height() + 1), brush); // Same here
+ }
+
+ p.setWorldMatrixEnabled(true);
+
+ MidiPart* mp = 0;
+ WavePart* wp = 0;
+ Track::TrackType type = part->track()->type();
+ if (type == Track::WAVE) {
+ wp =(WavePart*)part;
+ }
+ else {
+ mp = (MidiPart*)part;
+ }
+
+ if (wp)
+ drawWavePart(p, rect, wp, r);
+ else if (mp)
+ {
+ drawMidiPart(p, rect, mp->events(), (MidiTrack*)part->track(), mp, r, mp->tick(), from, to);
+ }
+
+ p.setWorldMatrixEnabled(false);
+
+ #if 0
+ //
+ // Now draw the borders...
+ // Works great but requires clones be drawn with the highest priority on top of all other parts, in Canvas::draw.
+ //
+
+ QPen pen(part->selected() ? config.partColors[i] : Qt::black, 2.0, clone ? Qt::DotLine : Qt::SolidLine);
+ pen.setCosmetic(true);
+ p.setPen(pen);
+ p.setBrush(Qt::NoBrush);
+ p.drawRect(r);
+
+ #else
+ //
+ // Now draw the borders, using custom segments...
+ //
+
+ p.setBrush(Qt::NoBrush);
+
+ QColor pc((part->mute() || item->isMoving())? Qt::white : config.partColors[cidx]);
+ QPen penSelect1H(pc);
+ QPen penSelect2H(pc, 2.0);
+ QPen penSelect1V(pc);
+ QPen penSelect2V(pc, 2.0);
+ penSelect1H.setCosmetic(true);
+ penSelect2H.setCosmetic(true);
+ penSelect1V.setCosmetic(true);
+ penSelect2V.setCosmetic(true);
+
+ pc = Qt::black;
+ QPen penNormal1H(pc);
+ QPen penNormal2H(pc, 2.0);
+ QPen penNormal1V(pc);
+ QPen penNormal2V(pc, 2.0);
+ penNormal1H.setCosmetic(true);
+ penNormal2H.setCosmetic(true);
+ penNormal1V.setCosmetic(true);
+ penNormal2V.setCosmetic(true);
+
+ //pc = Qt::white;
+ //pc = Qt::darkGray;
+ //QPen penHidden1(pc);
+ //QPen penHidden2(pc, 2.0);
+ //penHidden2.setCosmetic(true);
+
+ QVector<qreal> customDashPattern;
+
+ if(clone)
+ {
+ customDashPattern << 4.0 << 6.0;
+ penSelect1H.setDashPattern(customDashPattern);
+ penNormal1H.setDashPattern(customDashPattern);
+ penSelect1V.setDashPattern(customDashPattern);
+ penNormal1V.setDashPattern(customDashPattern);
+ penSelect1V.setDashOffset(2.0);
+ penNormal1V.setDashOffset(2.0);
+ //penHidden1.setDashPattern(customDashPattern);
+ customDashPattern.clear();
+ customDashPattern << 2.0 << 3.0;
+ penSelect2H.setDashPattern(customDashPattern);
+ penNormal2H.setDashPattern(customDashPattern);
+ penSelect2V.setDashPattern(customDashPattern);
+ penNormal2V.setDashPattern(customDashPattern);
+ penSelect2V.setDashOffset(1.0);
+ penNormal2V.setDashOffset(1.0);
+ //penHidden2.setDashPattern(customDashPattern);
+ }
+
+ bool lbt = ((NPart*)item)->leftBorderTouches;
+ bool rbt = ((NPart*)item)->rightBorderTouches;
+
+ QLine l1(lbt?xs_1:xs_0, ys_0, rbt?xe_1:xe_0, ys_0); // Top
+ //QLine l2(rbt?xe_1:xe_0, rbt?ys_1:ys_2, rbt?xe_1:xe_0, rbt?ye_1:ye_2); // Right
+ QLine l2(rbt?xe_1:xe_0, ys_0, rbt?xe_1:xe_0, ye_0); // Right
+ QLine l3(lbt?xs_1:xs_0, ye_0, rbt?xe_1:xe_0, ye_0); // Bottom
+ //QLine l4(xs_0, lbt?ys_1:ys_2, xs_0, lbt?ye_1:ye_2); // Left
+ QLine l4(xs_0, ys_0, xs_0, ye_0); // Left
+
+ //if(het & Part::RightEventsHidden)
+ // p.setPen(((NPart*)item)->rightBorderTouches ? penHidden1 : penHidden2);
+ //else
+ {
+ if(((NPart*)item)->rightBorderTouches)
+ p.setPen(part->selected() ? penSelect1V : penNormal1V);
+ else
+ p.setPen(part->selected() ? penSelect2V : penNormal2V);
+ }
+ p.drawLine(l2); // Right line
+
+ /*
+ int xx = rbt?xe_1:xe_0;
+ if(clone)
+ {
+ int yinc = 7;
+ for(int yy = (rbt?ys_1:ys_2); yy < ye_2; yy += yinc)
+ {
+ int yi = rbt?3:2;
+ if(yy + yi > ye_2)
+ yi = ye_2 - yy;
+ p.drawLine(QPoint(xx, yy), QPoint(xx, yy + yi)); // Right dashed line
+ }
+ }
+ else
+ p.drawLine(QPoint(xx, rbt?ys_1:ys_2), QPoint(xx, rbt?ye_1:ye_2)); // Right line
+ */
+
+ //if(het & Part::LeftEventsHidden)
+ // p.setPen(((NPart*)item)->leftBorderTouches ? penHidden1 : penHidden2);
+ //else
+ {
+ if(((NPart*)item)->leftBorderTouches)
+ p.setPen(part->selected() ? penSelect1V : penNormal1V);
+ else
+ p.setPen(part->selected() ? penSelect2V : penNormal2V);
+ }
+ p.drawLine(l4); // Left line
+
+ /*
+ xx = xs_0;
+ if(clone)
+ {
+ int yinc = 7;
+ for(int yy = (lbt?ys_1:ys_2); yy < ye_2; yy += yinc)
+ {
+ int yi = lbt?3:2;
+ if(yy + yi > ye_2)
+ yi = ye_2 - yy;
+ p.drawLine(QPoint(xx, yy), QPoint(xx, yy + yi)); // Left dashed line
+ }
+ }
+ else
+ p.drawLine(QPoint(xx, lbt?ys_1:ys_2), QPoint(xx, lbt?ye_1:ye_2)); // Left line
+ */
+
+ p.setPen(part->selected() ? penSelect2H : penNormal2H);
+ p.drawLine(l1); // Top line
+ p.drawLine(l3); // Bottom line
+
+ #endif
+
+ if (config.canvasShowPartType & 1) { // show names
+ // draw name
+ // FN: Set text color depending on part color (black / white)
+ int part_r, part_g, part_b, brightness;
+ // Since we'll draw the text on the bottom (to accommodate drum 'slivers'),
+ // get the lowest colour in the gradient used to draw the part.
+ //QRect rr = map(r);
+ QRect tr = rr;
+ tr.setX(tr.x() + 3);
+ gGradientFromQColor(config.partColors[cidx], tr.topLeft(), tr.bottomLeft()).stops().last().second.getRgb(&part_r, &part_g, &part_b);
+ brightness = part_r*29 + part_g*59 + part_b*12;
+ //bool rev = (brightness < 12000 || part->selected()) && !part->mute() && !item->isMoving();
+ bool rev = brightness >= 12000 && !part->selected();
+ p.setFont(config.fonts[1]);
+ if (rev)
+ p.setPen(Qt::white);
+ else
+ p.setPen(Qt::black);
+ p.drawText(tr.translated(1, 1), Qt::AlignBottom|Qt::AlignLeft, part->name());
+ if (rev)
+ p.setPen(Qt::black);
+ else
+ p.setPen(Qt::white);
+ p.drawText(tr, Qt::AlignBottom|Qt::AlignLeft, part->name());
+ }
+
+ p.restore();
+ //p.setWorldMatrixEnabled(true);
+ }
//---------------------------------------------------------
// drawMoving
@@ -1436,19 +2177,11 @@ void PartCanvas::drawItem(QPainter& p, const CItem* item, const QRect& rect)
void PartCanvas::drawMoving(QPainter& p, const CItem* item, const QRect&)
{
p.setPen( Qt::black);
-
- //p.setBrush( Qt::NoBrush);
- //QColor c(Qt::gray);
Part* part = ((NPart*)item)->part();
- QColor c(config.partColors[part->colorIndex()]);
-
- ///c.setAlpha(config.globalAlphaBlend);
+ QColor c(part->mute() ? Qt::white : config.partColors[part->colorIndex()]);
+ //c.setAlpha(config.globalAlphaBlend);
c.setAlpha(128); // Fix this regardless of global setting. Should be OK.
-
p.setBrush(c);
-
- // NOTE: For one-pixel border use second line. For two-pixel border use first.
- //p.drawRect(item->mp().x(), item->mp().y()+1, item->width(), item->height());
p.drawRect(item->mp().x(), item->mp().y(), item->width(), item->height());
}
@@ -1468,10 +2201,14 @@ void PartCanvas::drawMidiPart(QPainter& p, const QRect&, EventList* events, Midi
int part_r, part_g, part_b, brightness;
config.partColors[pt->colorIndex()].getRgb(&part_r, &part_g, &part_b);
brightness = part_r*29 + part_g*59 + part_b*12;
- if (brightness < 12000 || pt->selected())
- color_brightness=192; // too dark: use lighter color
+ //if ((brightness < 12000 || pt->selected()) && !pt->mute())
+ // color_brightness=192; // too dark: use lighter color
+ //else
+ // color_brightness=64; // otherwise use dark color
+ if (brightness >= 12000 && !pt->selected())
+ color_brightness=64; // 96; // too bright: use dark color
else
- color_brightness=64; // otherwise use dark color
+ color_brightness=190; //160; // too dark: use lighter color
}
else
color_brightness=80;
@@ -1656,9 +2393,11 @@ void PartCanvas::drawMidiPart(QPainter& p, const QRect&, EventList* events, Midi
if (te < (from + pTick))
continue;
- if (te > (to + pTick))
- te = to + pTick;
-
+ //if (te > (to + pTick))
+ // te = to + pTick;
+ if (te >= (to + pTick))
+ te = lrint(rmapxDev_f(rmapx_f(to + pTick) - 1.0));
+
EventType type = i->second.type();
if (type == Note) {
int pitch = i->second.pitch();
@@ -1685,8 +2424,10 @@ void PartCanvas::drawMidiPart(QPainter& p, const QRect&, EventList* events, Midi
void PartCanvas::drawWavePart(QPainter& p,
const QRect& bb, WavePart* wp, const QRect& _pr)
{
- QRect rr = p.worldMatrix().mapRect(bb);
- QRect pr = p.worldMatrix().mapRect(_pr);
+ //QRect rr = p.worldMatrix().mapRect(bb); // Gives inconsistent positions. Source shows wrong operation for our needs.
+ QRect rr = map(bb); // Use our own map instead.
+ //QRect pr = p.worldMatrix().mapRect(_pr);
+ QRect pr = map(_pr);
p.save();
p.resetTransform();
@@ -2359,9 +3100,22 @@ void PartCanvas::viewDropEvent(QDropEvent* event)
void PartCanvas::drawCanvas(QPainter& p, const QRect& rect)
{
int x = rect.x();
- int y = rect.y();
+ //int y = rect.y();
int w = rect.width();
- int h = rect.height();
+ //int h = rect.height();
+
+ // Changed to draw in device coordinate space instead of virtual, transformed space. Tim. p4.0.30
+
+ //QRect mr = p.transform().mapRect(rect); // Gives inconsistent positions. Source shows wrong operation for our needs.
+ QRect mr = map(rect); // Use our own map instead.
+
+ p.save();
+ p.setWorldMatrixEnabled(false);
+
+ int mx = mr.x();
+ int my = mr.y();
+ int mw = mr.width();
+ int mh = mr.height();
//////////
// GRID //
@@ -2379,13 +3133,17 @@ void PartCanvas::drawCanvas(QPainter& p, const QRect& rect)
AL::sigmap.tickValues(x, &bar, &beat, &tick);
for (;;) {
int xt = AL::sigmap.bar2tick(bar++, 0, 0);
+ //int xt = mapx(AL::sigmap.bar2tick(bar++, 0, 0));
if (xt >= x + w)
+ //if (xt >= mx + mw)
break;
if (!((bar-1) % 4))
p.setPen(baseColor.dark(115));
else
p.setPen(baseColor);
- p.drawLine(xt, y, xt, y+h);
+ //p.drawLine(xt, y, xt, y+h);
+ int xtm = mapx(xt);
+ p.drawLine(xtm, my, xtm, my+mh);
// append
int noDivisors=0;
@@ -2411,20 +3169,28 @@ void PartCanvas::drawCanvas(QPainter& p, const QRect& rect)
noDivisors=noDivisors/2;
}
p.setPen(baseColor);
+ int xx;
for (int t=1;t< noDivisors;t++)
- p.drawLine(xt+r*t, y, xt+r*t, y+h);
+ {
+ //p.drawLine(xt+r*t, y, xt+r*t, y+h);
+ xx = mapx(xt + r * t);
+ p.drawLine(xx, my, xx, my+mh);
+ }
}
}
}
+
//--------------------------------
// horizontal lines
//--------------------------------
TrackList* tl = song->tracks();
- int yy = 0;
+ //int yy = 0;
+ int yy = -rmapy(yorg) - ypos;
int th;
for (iTrack it = tl->begin(); it != tl->end(); ++it) {
- if (yy > y + h)
+ //if (yy > y + h)
+ if (yy > my + mh)
break;
Track* track = *it;
th = track->height();
@@ -2433,22 +3199,46 @@ void PartCanvas::drawCanvas(QPainter& p, const QRect& rect)
if (config.canvasShowGrid && (track->isMidiTrack() || track->type() == Track::WAVE)) // Tim.
{
p.setPen(baseColor.dark(130));
- p.drawLine(x, yy + th, x + w, yy + th); // Tim.
- p.setPen(baseColor);
- }
- if (!track->isMidiTrack() && (track->type() != Track::WAVE)) {
- QRect r = rect & QRect(x, yy, w, track->height());
- drawAudioTrack(p, r, (AudioTrack*)track);
- p.setPen(baseColor);
+ //p.drawLine(x, yy + th, x + w, yy + th);
+ p.drawLine(mx, yy + th, mx + mw, yy + th);
+ //p.setPen(baseColor);
}
- if (!track->isMidiTrack()) { // draw automation
- QRect r = rect & QRect(x, yy, w, track->height());
- drawAutomation(p, r, (AudioTrack*)track);
- p.setPen(baseColor);
-
- }
- yy += track->height();
+
+ // The update rectangle (rect and mr etc) is clipped at x<0 and y<0 in View::pdraw().
+ // The 'corrupt drawing' bug of drawAudioTrack was actually because the recently added gradient
+ // used the update rectangle, so the gradient was also being clipped at 0,0.
+ // One could remove that limiter, but no, that is the correct way. So instead let's construct a
+ // 'pseudo bounding box' (half update rectangle, half bounding box), un-clipped. The gradient needs this!
+ //
+ // Here is a different situation than PartCanvas::drawItem which uses un-clipped part bounding boxes and
+ // does NOT depend on the update rectangle (except to check intersection). That's why this issue
+ // does not show up there. Should probably try to make that routine more efficient, just like here. Tim. p4.0.30
+ QRect r(mx, yy, mw, th);
+ //if(r.intersects(mr))
+ {
+ if (!track->isMidiTrack() && (track->type() != Track::WAVE)) {
+ //QRect r = rect & QRect(x, yy, w, track->height());
+ drawAudioTrack(p, mr, r, (AudioTrack*)track);
+ //p.setPen(baseColor);
+ }
+
+ // This was redundant drawing. Not required, done via drawTopItem in Canvas::draw
+ /*
+ //p.setWorldMatrixEnabled(true);
+ //if (!track->isMidiTrack()) { // draw automation
+ if (!track->isMidiTrack() && (track->type() != Track::WAVE)) {
+ //QRect r = rect & QRect(x, yy, w, track->height());
+ drawAutomation(p, r, (AudioTrack*)track);
+ //p.setPen(baseColor);
+ }
+ //p.setWorldMatrixEnabled(false);
+ */
}
+ yy += th;
+ }
+
+ p.restore();
+ //p.setWorldMatrixEnabled(true);
}
//---------------------------------------------------------
@@ -2456,36 +3246,55 @@ void PartCanvas::drawCanvas(QPainter& p, const QRect& rect)
//---------------------------------------------------------
void PartCanvas::drawTopItem(QPainter& p, const QRect& rect)
{
- int x = rect.x();
- int y = rect.y();
- int w = rect.width();
- int h = rect.height();
+ //int x = rect.x();
+ //int y = rect.y();
+ //int w = rect.width();
+ //int h = rect.height();
+ // Changed to draw in device coordinate space instead of virtual, transformed space. Tim. p4.0.30
+
+ //QRect mr = p.transform().mapRect(rect); // Gives inconsistent positions. Source shows wrong operation for our needs.
+ QRect mr = map(rect); // Use our own map instead.
+
+ //printf("PartCanvas::drawTopItem x:%d y:%d w:%d h:%d\n", rect.x(), rect.y(), rect.width(), rect.height());
+
+ int mx = mr.x();
+ int my = mr.y();
+ int mw = mr.width();
+ int mh = mr.height();
+
QColor baseColor(config.partCanvasBg.light(104));
- p.setPen(baseColor);
+ //p.setPen(baseColor);
+ p.save();
+ p.setWorldMatrixEnabled(false);
+
TrackList* tl = song->tracks();
- int yy = 0;
+ int yoff = -rmapy(yorg) - ypos;
+ //int yy = 0;
+ int yy = yoff;
int th;
for (iTrack it = tl->begin(); it != tl->end(); ++it) {
- if (yy > y + h)
+ //if (yy > y + h)
+ if (yy > my + mh)
break;
Track* track = *it;
th = track->height();
if (!th)
continue;
if (!track->isMidiTrack()) { // draw automation
- QRect r = rect & QRect(x, yy, w, track->height());
- drawAutomation(p, r, (AudioTrack*)track);
- p.setPen(baseColor);
-
+ //QRect r = rect & QRect(x, yy, w, track->height());
+ QRect r(mx, yy, mw, th);
+ if(r.intersects(mr))
+ {
+ drawAutomation(p, r, (AudioTrack*)track);
+ //p.setPen(baseColor);
+ }
}
- yy += track->height();
+ //yy += track->height();
+ yy += th;
}
- QRect rr = p.worldMatrix().mapRect(rect);
-
-
unsigned int startPos = audio->getStartRecordPos().tick();
if (song->punchin())
startPos=song->lpos();
@@ -2493,38 +3302,47 @@ void PartCanvas::drawTopItem(QPainter& p, const QRect& rect)
int width = mapx(song->cpos()) - mapx(startPos);
if (song->cpos() < startPos) {
+ //p.setWorldMatrixEnabled(true);
+ p.restore();
return; // no drawing if we are before punch out
}
if (song->punchout() && song->cpos() > song->rpos()) {
+ //p.setWorldMatrixEnabled(true);
+ p.restore();
return; // no drawing if we are beyond punch out.
}
- p.save();
- p.resetTransform();
+ ///p.save();
+ ///p.resetTransform();
// write recording while it happens to get feedback
// should be enhanced with solution that draws waveform also
- int yPos=0;
+ //int yPos=0;
+ int yPos = yoff;
if (song->record() && audio->isPlaying()) {
for (iTrack it = tl->begin(); it != tl->end(); ++it) {
Track* track = *it;
+ th = track->height();
+ if (!th)
+ continue;
if (track->recordFlag()) {
QPen pen(Qt::black, 0, Qt::SolidLine);
p.setPen(pen);
QColor c(config.partColors[0]);
c.setAlpha(config.globalAlphaBlend);
- QLinearGradient gradient(QPoint(startx,yPos), QPoint(startx,yPos+track->height()));
+ QLinearGradient gradient(QPoint(startx,yPos), QPoint(startx,yPos+th));
gradient.setColorAt(0, c);
gradient.setColorAt(1, c.darker());
QBrush cc(gradient);
p.setBrush(cc);
- p.drawRect(startx,yPos, width, track->height());
+ p.drawRect(startx,yPos, width, th);
}
- yPos+=track->height();
+ yPos+=th;
}
}
p.restore();
+ //p.setWorldMatrixEnabled(true);
// draw midi events on
yPos=0;
@@ -2568,53 +3386,71 @@ void PartCanvas::drawTopItem(QPainter& p, const QRect& rect)
}
}
-
}
//---------------------------------------------------------
// drawAudioTrack
//---------------------------------------------------------
-void PartCanvas::drawAudioTrack(QPainter& p, const QRect& r, AudioTrack* /* t */)
+void PartCanvas::drawAudioTrack(QPainter& p, const QRect& r, const QRect& bbox, AudioTrack* /*t*/)
{
- // NOTE: For one-pixel border use first line and don't bother with setCosmetic.
- // For a two-pixel border use second line and MUST use setCosmetic! Tim.
- QPen pen(Qt::black, 0, Qt::SolidLine);
- //p.setPen(QPen(Qt::black, 2, Qt::SolidLine));
- //pen.setCosmetic(true);
- p.setPen(pen);
- //p.setBrush(Qt::gray);
-
+ QRect mr = r & bbox;
+ if(mr.isNull())
+ return;
+ int mx = mr.x();
+ int my = mr.y();
+ int mw = mr.width();
+ int mh = mr.height();
+ int mex = bbox.x();
+ int mey = bbox.y();
+ //int mew = bbox.width();
+ int meh = bbox.height();
+
+ p.setPen(Qt::black);
QColor c(Qt::gray);
c.setAlpha(config.globalAlphaBlend);
- QLinearGradient gradient(r.topLeft(), r.bottomLeft());
+ //QLinearGradient gradient(r.topLeft(), r.bottomLeft());
+ QLinearGradient gradient(mex + 1, mey + 1, mex + 1, mey + meh - 1); // Inside the border
gradient.setColorAt(0, c);
gradient.setColorAt(1, c.darker());
- QBrush cc(gradient);
- p.setBrush(cc);
- p.drawRect(r);
-
- // Factor in pen stroking size:
- //QRect rr(r);
- //rr.setHeight(rr.height() -1);
+ QBrush brush(gradient);
+ p.fillRect(mr, brush); // p4.0.30 ...
+
+ //int xx = -rmapx(xorg) - xpos;
+ //printf("PartCanvas::drawAudioTrack x:%d y:%d w:%d h:%d th:%d xx:%d\n", r.x(), r.y(), r.width(), r.height(), t->height(), xx);
+ //if(r.x() <= xx)
+ // p.drawLine(r.x(), r.y(), r.x(), r.y() + r.height()); // The left edge
+ //p.drawLine(r.x(), r.y(), r.x() + r.width(), r.y()); // The top edge
+ //p.drawLine(r.x(), r.y() + r.height(), r.x() + r.width(), r.y() + r.height()); // The bottom edge
-// p.fillRect(r, cc);
+ if(mex >= mx && mex <= mx + mw)
+ p.drawLine(mex, my, mex, my + mh - 1); // The left edge
+ //if(mex + mew >= mx && mex + mew <= mx + mw)
+ // p.drawLine(mex + mew, my, mex + mew, my + mh - 1); // The right edge. Not used - infinite to the right
+ if(mey >= my && mey <= my + mh)
+ p.drawLine(mx, mey, mx + mw - 1, mey); // The top edge
+ if(mey + meh >= my && mey + meh <= my + mh)
+ p.drawLine(mx, mey + meh, mx + mw - 1, mey + meh); // The bottom edge. Special for Audio track - draw one past bottom.
}
//---------------------------------------------------------
// drawAutomation
//---------------------------------------------------------
-void PartCanvas::drawAutomation(QPainter& p, const QRect& r, AudioTrack *t)
+void PartCanvas::drawAutomation(QPainter& p, const QRect& rr, AudioTrack *t)
{
- QRect rr = p.worldMatrix().mapRect(r);
+ ///QRect rr = p.worldMatrix().mapRect(r);
- p.save();
- p.resetTransform();
+ ///p.save();
+ ///p.resetTransform();
int height=rr.bottom()-rr.top()-4; // limit height
+ //printf("PartCanvas::drawAutomation x:%d y:%d w:%d h:%d height:%d\n", rr.x(), rr.y(), rr.width(), rr.height(), height);
+
+ p.setBrush(Qt::NoBrush);
+
CtrlListList* cll = t->controller();
- bool firstRun=true;
+ ///bool firstRun=true;
for(CtrlListList::iterator icll =cll->begin();icll!=cll->end();++icll)
{
//iCtrlList *icl = icll->second;
@@ -2625,7 +3461,8 @@ void PartCanvas::drawAutomation(QPainter& p, const QRect& r, AudioTrack *t)
iCtrl ic=cl->begin();
if (!cl->isVisible())
continue; // skip this iteration if this controller isn't in the visible list
- p.setPen(QPen(cl->color(),1,Qt::SolidLine));
+ ///p.setPen(QPen(cl->color(),1,Qt::SolidLine));
+ p.setPen(QPen(cl->color(), 0, Qt::SolidLine));
// First check that there ARE automation, ic == cl->end means no automation
if (ic != cl->end()) {
@@ -2651,6 +3488,7 @@ void PartCanvas::drawAutomation(QPainter& p, const QRect& r, AudioTrack *t)
p.drawRect(mapx(tempomap.frame2tick(prevPosFrame))-1, (rr.bottom()-2)-prevVal*height-1, 3, 3);
p.drawRect(mapx(tempomap.frame2tick(prevPosFrame))-2, (rr.bottom()-2)-prevVal*height-2, 5, 5);
+ bool firstRun=true;
for (; ic !=cl->end(); ++ic)
{
CtrlVal cv = ic->second;
@@ -2671,6 +3509,7 @@ void PartCanvas::drawAutomation(QPainter& p, const QRect& r, AudioTrack *t)
}
int currentPixel = mapx(tempomap.frame2tick(cv.frame));
+ //printf(" line x1:%d x2:%d prevVal:%f nextVal:%f\n", leftX, currentPixel, prevVal, nextVal);
p.drawLine( leftX,
(rr.bottom()-2)-prevVal*height,
currentPixel,
@@ -2683,20 +3522,23 @@ void PartCanvas::drawAutomation(QPainter& p, const QRect& r, AudioTrack *t)
prevPosFrame=cv.frame;
prevVal=nextVal;
if (currentPixel > rr.x()+ rr.width())
- goto quitDrawing;
+ ///goto quitDrawing;
+ break;
// draw a square around the point
p.drawRect(mapx(tempomap.frame2tick(prevPosFrame))-2, (rr.bottom()-2)-prevVal*height-2, 5, 5);
p.drawRect(mapx(tempomap.frame2tick(prevPosFrame))-1, (rr.bottom()-1)-prevVal*height-2, 3, 3);
}
+ //printf(" endline prevVal:%f\n", prevVal);
p.drawLine(mapx(tempomap.frame2tick(prevPosFrame)),
(rr.bottom()-2)-prevVal*height,
rr.x()+rr.width(),
(rr.bottom()-2)-prevVal*height);
}
}
-quitDrawing:
- p.restore();
+///quitDrawing:
+ ///p.restore();
+ return;
}
diff --git a/muse2/muse/arranger/pcanvas.h b/muse2/muse/arranger/pcanvas.h
index a0c25f6e..71a0129c 100644
--- a/muse2/muse/arranger/pcanvas.h
+++ b/muse2/muse/arranger/pcanvas.h
@@ -3,11 +3,14 @@
// Linux Music Editor
// $Id: pcanvas.h,v 1.11.2.4 2009/05/24 21:43:44 terminator356 Exp $
// (C) Copyright 1999 Werner Schweer (ws@seh.de)
+// Additions, modifications (C) Copyright 2011 Tim E. Real (terminator356 on users DOT sourceforge DOT net)
//=========================================================
#ifndef __PCANVAS_H__
#define __PCANVAS_H__
+#include <QVector>
+
#include "song.h"
#include "canvas.h"
#include "trackautomationview.h"
@@ -33,6 +36,9 @@ class NPart : public CItem {
const QString name() const { return part()->name(); }
void setName(const QString& s) { part()->setName(s); }
Track* track() const { return part()->track(); }
+
+ bool leftBorderTouches; // Whether the borders touch other part borders.
+ bool rightBorderTouches;
};
enum ControllerVals { doNothing, movingController, addNewController };
@@ -109,7 +115,7 @@ class PartCanvas : public Canvas {
//void drawMidiPart(QPainter&, const QRect& rect, EventList* events, MidiTrack*mt, const QRect& r, int pTick, int from, int to);
void drawMidiPart(QPainter&, const QRect& rect, EventList* events, MidiTrack*mt, MidiPart*pt, const QRect& r, int pTick, int from, int to);
Track* y2Track(int) const;
- void drawAudioTrack(QPainter& p, const QRect& r, AudioTrack* track);
+ void drawAudioTrack(QPainter& p, const QRect& r, const QRect& bbox, AudioTrack* track);
void drawAutomation(QPainter& p, const QRect& r, AudioTrack* track);
void drawTopItem(QPainter& p, const QRect& rect);
diff --git a/muse2/muse/arranger/tlist.cpp b/muse2/muse/arranger/tlist.cpp
index d7cda62f..6fe2f31d 100644
--- a/muse2/muse/arranger/tlist.cpp
+++ b/muse2/muse/arranger/tlist.cpp
@@ -227,8 +227,7 @@ void TList::paint(const QRect& r)
for (int index = 0; index < header->count(); ++index) {
int section = header->logicalIndex(index);
int w = header->sectionSize(section);
- //QRect r = p.xForm(QRect(x+2, yy, w-4, trackHeight));
- QRect r = p.combinedTransform().mapRect(QRect(x+2, yy, w-4, trackHeight));
+ QRect r = p.combinedTransform().mapRect(QRect(x+2, yy, w-4, trackHeight));
switch (section) {
case COL_RECORD:
diff --git a/muse2/muse/ctrl/ctrlcanvas.cpp b/muse2/muse/ctrl/ctrlcanvas.cpp
index 678cd823..68e29f20 100644
--- a/muse2/muse/ctrl/ctrlcanvas.cpp
+++ b/muse2/muse/ctrl/ctrlcanvas.cpp
@@ -25,9 +25,6 @@
#include "ctrlpanel.h"
#include "midiedit/drummap.h"
-extern void drawTickRaster(QPainter& p, int x, int y,
- int w, int h, int quant);
-
static MidiCtrlValList veloList(CTRL_VELOCITY); // dummy
//---------------------------------------------------------
diff --git a/muse2/muse/driver/jack.cpp b/muse2/muse/driver/jack.cpp
index 4857ede5..529e8a60 100644
--- a/muse2/muse/driver/jack.cpp
+++ b/muse2/muse/driver/jack.cpp
@@ -977,7 +977,8 @@ void JackAudioDevice::graphChanged()
// p3.3.37
//delete ports;
- free(ports);
+ //free(ports);
+ jack_free(ports); // p4.0.29
ports = NULL;
}
@@ -1063,7 +1064,8 @@ void JackAudioDevice::graphChanged()
// p3.3.37
//delete ports;
- free(ports);
+ //free(ports);
+ jack_free(ports); // p4.0.29
ports = NULL;
}
@@ -1182,7 +1184,8 @@ void JackAudioDevice::graphChanged()
// p3.3.55
// Done with ports. Free them.
- free(ports);
+ //free(ports);
+ jack_free(ports); // p4.0.29
}
}
}
@@ -1279,7 +1282,8 @@ void JackAudioDevice::graphChanged()
}
// p3.3.55
// Done with ports. Free them.
- free(ports);
+ //free(ports);
+ jack_free(ports); // p4.0.29
}
}
}
@@ -1662,7 +1666,8 @@ std::list<QString> JackAudioDevice::outputPorts(bool midi, int aliases)
// p3.3.37
if(ports)
- free(ports);
+ //free(ports);
+ jack_free(ports); // p4.0.29
return clientList;
}
@@ -1734,7 +1739,8 @@ std::list<QString> JackAudioDevice::inputPorts(bool midi, int aliases)
// p3.3.37
if(ports)
- free(ports);
+ //free(ports);
+ jack_free(ports); // p4.0.29
return clientList;
}
diff --git a/muse2/muse/functions.cpp b/muse2/muse/functions.cpp
index 7d5eecc0..5861ca9e 100644
--- a/muse2/muse/functions.cpp
+++ b/muse2/muse/functions.cpp
@@ -319,7 +319,7 @@ bool modify_notelen(const set<Part*>& parts, int range, int rate, int offset)
if (len <= 0)
len = 1;
- if ((event.tick()+len > part->lenTick()) && (!part->hasHiddenNotes()))
+ if ((event.tick()+len > part->lenTick()) && (!part->hasHiddenEvents()))
partlen[part]=event.tick()+len; // schedule auto-expanding
if (event.lenTick() != len)
@@ -522,7 +522,7 @@ bool move_notes(const set<Part*>& parts, int range, signed int ticks)
if (newEvent.endTick() > part->lenTick()) //if exceeding the part's end:
{
- if (part->hasHiddenNotes()) // auto-expanding is forbidden, clip
+ if (part->hasHiddenEvents()) // auto-expanding is forbidden, clip
{
if (part->lenTick() > newEvent.tick())
newEvent.setLenTick(part->lenTick() - newEvent.tick());
@@ -776,7 +776,7 @@ void paste_at(Part* dest_part, const QString& pt, int pos)
if (e.endTick() > dest_part->lenTick()) // event exceeds part?
{
- if (dest_part->hasHiddenNotes()) // auto-expanding is forbidden?
+ if (dest_part->hasHiddenEvents()) // auto-expanding is forbidden?
{
if (e.tick() < dest_part->lenTick())
e.setLenTick(dest_part->lenTick() - e.tick()); // clip
diff --git a/muse2/muse/master/master.cpp b/muse2/muse/master/master.cpp
index 4a33a8c4..6293e64c 100644
--- a/muse2/muse/master/master.cpp
+++ b/muse2/muse/master/master.cpp
@@ -22,9 +22,6 @@
#include "icons.h"
#include "audio.h"
-extern void drawTickRaster(QPainter& p, int x, int y,
- int w, int h, int quant);
-
//---------------------------------------------------------
// Master
//---------------------------------------------------------
diff --git a/muse2/muse/master/masteredit.cpp b/muse2/muse/master/masteredit.cpp
index 68e8a3b2..777e6066 100644
--- a/muse2/muse/master/masteredit.cpp
+++ b/muse2/muse/master/masteredit.cpp
@@ -112,6 +112,7 @@ MasterEdit::MasterEdit()
addToolBar(tools2);
QToolBar* enableMaster = addToolBar(tr("Enable master"));
+ enableMaster->setObjectName("Enable master");
enableButton = new QToolButton();
enableButton->setCheckable(true);
enableButton->setText(tr("Enable"));
@@ -121,6 +122,7 @@ MasterEdit::MasterEdit()
connect(enableButton, SIGNAL(toggled(bool)), song, SLOT(setMasterFlag(bool)));
QToolBar* info = addToolBar(tr("Info"));
+ info->setObjectName("Info");
QLabel* label = new QLabel(tr("Cursor"));
label->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
label->setIndent(3);
diff --git a/muse2/muse/master/tscale.cpp b/muse2/muse/master/tscale.cpp
index d37d5924..9ea34fba 100644
--- a/muse2/muse/master/tscale.cpp
+++ b/muse2/muse/master/tscale.cpp
@@ -20,8 +20,9 @@
TScale::TScale(QWidget* parent, int ymag)
: View(parent, 1, ymag)
{
- setFont(config.fonts[3]);
- int w = 4 * QFontMetrics(config.fonts[4]).width('0');
+ setFont(config.fonts[4]);
+ //int w = 4 * QFontMetrics(config.fonts[4]).width('0');
+ int w = 4 * fontMetrics().width('0');
setFixedWidth(w);
setMouseTracking(true);
}
@@ -34,7 +35,7 @@ void TScale::pdraw(QPainter& p, const QRect& r)
{
int y = r.y();
int h = r.height();
- p.setFont(config.fonts[4]);
+ //p.setFont(config.fonts[4]);
QString s;
for (int i = 30000; i <= 250000; i += 10000) {
int yy = mapy(280000 - i);
@@ -44,8 +45,9 @@ void TScale::pdraw(QPainter& p, const QRect& r)
continue;
p.drawLine(0, yy, width(), yy);
s.setNum(i/1000);
- QFontMetrics fm(config.fonts[4]);
- p.drawText(width() - fm.width(s) - 1, yy-2, s);
+ //QFontMetrics fm(config.fonts[4]);
+ //p.drawText(width() - fm.width(s) - 1, yy-2, s);
+ p.drawText(width() - fontMetrics().width(s) - 1, yy-2, s); // Use the window font. Tim p4.0.31
}
}
diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp
index 921e59f6..615653b3 100644
--- a/muse2/muse/midiedit/dcanvas.cpp
+++ b/muse2/muse/midiedit/dcanvas.cpp
@@ -158,7 +158,7 @@ Undo DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp
for(iPartToChange ip2c = parts2change.begin(); ip2c != parts2change.end(); ++ip2c)
{
Part* opart = ip2c->first;
- if (opart->hasHiddenNotes())
+ if (opart->hasHiddenEvents())
{
forbidden=true;
break;
@@ -350,7 +350,7 @@ void DrumCanvas::newItem(CItem* item, bool noSnap, bool replace)
Undo operations;
int diff = event.endTick()-part->lenTick();
- if (! ((diff > 0) && part->hasHiddenNotes()) ) //operation is allowed
+ if (! ((diff > 0) && part->hasHiddenEvents()) ) //operation is allowed
{
operations.push_back(UndoOp(UndoOp::AddEvent,event, part, false, false));
@@ -463,8 +463,6 @@ void DrumCanvas::drawMoving(QPainter& p, const CItem* item, const QRect& rect)
// drawCanvas
//---------------------------------------------------------
-extern void drawTickRaster(QPainter& p, int, int, int, int, int);
-
void DrumCanvas::drawCanvas(QPainter& p, const QRect& rect)
{
int x = rect.x();
diff --git a/muse2/muse/midiedit/dlist.cpp b/muse2/muse/midiedit/dlist.cpp
index 66922e83..d2d5659c 100644
--- a/muse2/muse/midiedit/dlist.cpp
+++ b/muse2/muse/midiedit/dlist.cpp
@@ -52,15 +52,18 @@ void DList::draw(QPainter& p, const QRect& rect)
// else
// p.eraseRect(x, yy, w, TH);
QHeaderView *h = header;
+ p.save();
+ p.setWorldMatrixEnabled(false);
for (int k = 0; k < h->count(); ++k) {
int x = h->sectionPosition(k);
int w = h->sectionSize(k);
- QRect r = p.combinedTransform().mapRect(QRect(x+2, yy, w-4, TH));
+ //QRect r = p.combinedTransform().mapRect(QRect(x+2, yy, w-4, TH)); // Gives inconsistent positions. Source shows wrong operation for our needs.
+ QRect r = map(QRect(x+2, yy, w-4, TH)); // Use our own map instead.
QString s;
int align = Qt::AlignVCenter | Qt::AlignHCenter;
- p.save();
- p.setWorldMatrixEnabled(false);
+ //p.save();
+ //p.setWorldMatrixEnabled(false);
switch (k) {
case COL_VOL:
s.setNum(dm->vol);
@@ -114,8 +117,9 @@ void DList::draw(QPainter& p, const QRect& rect)
}
if (!s.isEmpty())
p.drawText(r, align, s);
- p.restore();
+ //p.restore();
}
+ p.restore();
}
//---------------------------------------------------
diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp
index 5477752d..f8061c06 100644
--- a/muse2/muse/midiedit/drumedit.cpp
+++ b/muse2/muse/midiedit/drumedit.cpp
@@ -228,7 +228,7 @@ DrumEdit::DrumEdit(PartList* pl, QWidget* parent, const char* name, unsigned ini
signalMapper->setMapping(nextAction, DrumCanvas::CMD_SELECT_NEXT_PART);
// Functions
- menuFunctions = menuBar()->addMenu(tr("&Functions"));
+ menuFunctions = menuBar()->addMenu(tr("Fu&nctions"));
menuFunctions->setTearOffEnabled(true);
diff --git a/muse2/muse/midiedit/pianoroll.cpp b/muse2/muse/midiedit/pianoroll.cpp
index d8fdc34d..c98657ea 100644
--- a/muse2/muse/midiedit/pianoroll.cpp
+++ b/muse2/muse/midiedit/pianoroll.cpp
@@ -178,7 +178,7 @@ PianoRoll::PianoRoll(PartList* pl, QWidget* parent, const char* name, unsigned i
- menuFunctions = menuBar()->addMenu(tr("&Functions"));
+ menuFunctions = menuBar()->addMenu(tr("Fu&nctions"));
menuFunctions->setTearOffEnabled(true);
diff --git a/muse2/muse/midiedit/prcanvas.cpp b/muse2/muse/midiedit/prcanvas.cpp
index d06274b4..82a6a215 100644
--- a/muse2/muse/midiedit/prcanvas.cpp
+++ b/muse2/muse/midiedit/prcanvas.cpp
@@ -37,6 +37,7 @@
#include "song.h"
#include "audio.h"
#include "functions.h"
+#include "gconfig.h"
#define CHORD_TIMEOUT 75
@@ -101,7 +102,7 @@ PianoCanvas::PianoCanvas(MidiEditor* pr, QWidget* parent, int sx, int sy)
int PianoCanvas::pitch2y(int pitch) const
{
int tt[] = {
- 5, 12, 19, 26, 33, 44, 51, 58, 64, 71, 78, 85
+ 5, 13, 19, 26, 34, 44, 52, 58, 65, 71, 78, 85
};
int y = (75 * KH) - (tt[pitch%12] + (7 * KH) * (pitch/12));
if (y < 0)
@@ -146,9 +147,23 @@ void PianoCanvas::drawItem(QPainter& p, const CItem* item,
QRect r = item->bbox();
if(!virt())
r.moveCenter(map(item->pos()));
- r = r.intersected(rect);
- if(!r.isValid())
+
+ //QRect rr = p.transform().mapRect(rect); // Gives inconsistent positions. Source shows wrong operation for our needs.
+ QRect rr = map(rect); // Use our own map instead.
+ QRect mer = map(r);
+
+ ///r = r.intersected(rect);
+ //QRect rr = r & rect;
+ ///if(!r.isValid())
+ //if(!rr.isValid())
+ // return;
+ QRect mr = rr & mer;
+ //if(!mr.isValid())
+ if(mr.isNull())
return;
+
+ //p.save();
+
p.setPen(Qt::black);
struct Triple {
int r, g, b;
@@ -169,25 +184,25 @@ void PianoCanvas::drawItem(QPainter& p, const CItem* item,
{ 0xff, 0xbf, 0x7a }
};
+ QColor color;
NEvent* nevent = (NEvent*) item;
Event event = nevent->event();
if (nevent->part() != curPart){
if(item->isMoving())
- p.setBrush(Qt::gray);
+ color = Qt::gray;
else if(item->isSelected())
- p.setBrush(Qt::black);
+ color = Qt::black;
else
- p.setBrush(Qt::lightGray);
+ color = Qt::lightGray;
}
else {
if (item->isMoving()) {
- p.setBrush(Qt::gray);
+ color = Qt::gray;
}
else if (item->isSelected()) {
- p.setBrush(Qt::black);
+ color = Qt::black;
}
else {
- QColor color;
color.setRgb(0, 0, 255);
switch(colorMode) {
case 0:
@@ -208,10 +223,50 @@ void PianoCanvas::drawItem(QPainter& p, const CItem* item,
}
break;
}
- p.setBrush(color);
}
}
- p.drawRect(r);
+
+ bool wmtxen = p.worldMatrixEnabled();
+ p.setWorldMatrixEnabled(false);
+ int mx = mr.x();
+ int my = mr.y();
+ int mw = mr.width();
+ int mh = mr.height();
+ int mex = mer.x();
+ int mey = mer.y();
+ int mew = mer.width();
+ int meh = mer.height();
+ //int mfx = mx;
+ //if(mfx == mex) mfx += 1;
+ //int mfy = my;
+ //if(mfy == mey) mfy += 1;
+ //int mfw = mw;
+ //if(mfw == mew) mfw -= 1;
+ //if(mfx == mex) mfw -= 1;
+ //int mfh = mh;
+ //if(mfh == meh) mfh -= 1;
+ //if(mfy == mey) mfh -= 1;
+ color.setAlpha(config.globalAlphaBlend);
+ //QLinearGradient gradient(mex + 1, mey + 1, mex + 1, mey + meh - 2); // Inside the border
+ //gradient.setColorAt(0, color);
+ //gradient.setColorAt(1, color.darker());
+ //QBrush brush(gradient);
+ QBrush brush(color);
+ p.fillRect(mr, brush);
+ //p.fillRect(mfx, mfy, mfw, mfh, brush);
+
+ if(mex >= mx && mex <= mx + mw)
+ p.drawLine(mex, my, mex, my + mh - 1); // The left edge
+ if(mex + mew >= mx && mex + mew <= mx + mw)
+ p.drawLine(mex + mew, my, mex + mew, my + mh - 1); // The right edge
+ if(mey >= my && mey <= my + mh)
+ p.drawLine(mx, mey, mx + mw - 1, mey); // The top edge
+ if(mey + meh >= my && mey + meh <= my + mh)
+ p.drawLine(mx, mey + meh - 1, mx + mw - 1, mey + meh - 1); // The bottom edge
+
+ //p.setWorldMatrixEnabled(true);
+ p.setWorldMatrixEnabled(wmtxen);
+ //p.restore();
}
//---------------------------------------------------------
@@ -314,7 +369,7 @@ Undo PianoCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dty
for(iPartToChange ip2c = parts2change.begin(); ip2c != parts2change.end(); ++ip2c)
{
Part* opart = ip2c->first;
- if (opart->hasHiddenNotes())
+ if (opart->hasHiddenEvents())
{
forbidden=true;
break;
@@ -468,7 +523,7 @@ void PianoCanvas::newItem(CItem* item, bool noSnap)
Undo operations;
int diff = event.endTick()-part->lenTick();
- if (! ((diff > 0) && part->hasHiddenNotes()) ) //operation is allowed
+ if (! ((diff > 0) && part->hasHiddenEvents()) ) //operation is allowed
{
operations.push_back(UndoOp(UndoOp::AddEvent,event, part, false, false));
@@ -513,7 +568,7 @@ void PianoCanvas::resizeItem(CItem* item, bool noSnap, bool) // experime
Undo operations;
int diff = event.tick()+len-part->lenTick();
- if (! ((diff > 0) && part->hasHiddenNotes()) ) //operation is allowed
+ if (! ((diff > 0) && part->hasHiddenEvents()) ) //operation is allowed
{
newEvent.setLenTick(len);
operations.push_back(UndoOp(UndoOp::ModifyEvent,newEvent, event, nevent->part(), false, false));
@@ -680,48 +735,6 @@ void PianoCanvas::pianoReleased(int pitch, bool)
}
//---------------------------------------------------------
-// drawTickRaster
-//---------------------------------------------------------
-
-void drawTickRaster(QPainter& p, int x, int y, int w, int h, int raster)
- {
- int bar1, bar2, beat;
- unsigned tick;
- AL::sigmap.tickValues(x, &bar1, &beat, &tick);
- AL::sigmap.tickValues(x+w, &bar2, &beat, &tick);
- ++bar2;
- int y2 = y + h;
- for (int bar = bar1; bar < bar2; ++bar) {
- unsigned x = AL::sigmap.bar2tick(bar, 0, 0);
- p.setPen(Qt::black);
- p.drawLine(x, y, x, y2);
- int z, n;
- AL::sigmap.timesig(x, z, n);
- ///int q = p.xForm(QPoint(raster, 0)).x() - p.xForm(QPoint(0, 0)).x();
- int q = p.combinedTransform().map(QPoint(raster, 0)).x() - p.combinedTransform().map(QPoint(0, 0)).x();
- int qq = raster;
- if (q < 8) // grid too dense
- qq *= 2;
- p.setPen(Qt::lightGray);
- if (raster>=4) {
- int xx = x + qq;
- int xxx = AL::sigmap.bar2tick(bar, z, 0);
- while (xx <= xxx) {
- p.drawLine(xx, y, xx, y2);
- xx += qq;
- }
- xx = xxx;
- }
- p.setPen(Qt::gray);
- for (int beat = 1; beat < z; beat++) {
- int xx = AL::sigmap.bar2tick(bar, beat, 0);
- p.drawLine(xx, y, xx, y2);
- }
-
- }
- }
-
-//---------------------------------------------------------
// draw
//---------------------------------------------------------
@@ -732,31 +745,63 @@ void PianoCanvas::drawCanvas(QPainter& p, const QRect& rect)
int w = rect.width();
int h = rect.height();
+ // Changed to draw in device coordinate space instead of virtual, transformed space. Tim. p4.0.30
+
+ //int mx = mapx(x);
+ //int my = mapy(y);
+ //int mw = mapx(x + w) - mx;
+ //int mw = mapx(x + w) - mx - 1;
+ //int mh = mapy(y + h) - my;
+ //int mh = mapy(y + h) - my - 1;
+
+ // p.save();
+ // FIXME Can't get horizontal lines quite right yet. Draw in virtual space for now...
+ ///p.setWorldMatrixEnabled(false);
+
//---------------------------------------------------
// horizontal lines
//---------------------------------------------------
int yy = ((y-1) / KH) * KH + KH;
+ //int yy = my + KH;
+ //int yy = ((my-1) / KH) * KH + KH;
+ //int yoff = -rmapy(yorg) - ypos;
int key = 75 - (yy / KH);
+
+ //printf("PianoCanvas::drawCanvas x:%d y:%d w:%d h:%d mx:%d my:%d mw:%d mh:%d yy:%d key:%d\n", x, y, w, h, mx, my, mw, mh, yy, key);
+
for (; yy < y + h; yy += KH) {
+ //for (; yy + yoff < my + mh; yy += KH) {
+ //for (; yy < my + mh; yy += KH) {
switch (key % 7) {
case 0:
case 3:
p.setPen(Qt::black);
p.drawLine(x, yy, x + w, yy);
+ //p.drawLine(mx, yy + yoff, mx + mw, yy + yoff);
+ //p.drawLine(mx, yy, mx + mw, yy);
break;
default:
p.fillRect(x, yy-3, w, 6, QBrush(QColor(230,230,230)));
+ //p.fillRect(mx, yy-3 + yoff, mw, 6, QBrush(QColor(230,230,230)));
+ //p.fillRect(mx, yy-3, mw, 6, QBrush(QColor(230,230,230)));
break;
}
--key;
}
-
+ //p.restore();
+ ///p.setWorldMatrixEnabled(true);
+
+ //p.setWorldMatrixEnabled(false);
+
//---------------------------------------------------
// vertical lines
//---------------------------------------------------
drawTickRaster(p, x, y, w, h, editor->raster());
+
+ //p.restore();
+ //p.setWorldMatrixEnabled(true);
}
//---------------------------------------------------------
diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp
index 2f077365..157a6845 100644
--- a/muse2/muse/midiedit/scoreedit.cpp
+++ b/muse2/muse/midiedit/scoreedit.cpp
@@ -422,7 +422,7 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos)
- QMenu* functions_menu = menuBar()->addMenu(tr("&Functions"));
+ QMenu* functions_menu = menuBar()->addMenu(tr("Fu&nctions"));
func_quantize_action = functions_menu->addAction(tr("&Quantize"), menu_mapper, SLOT(map()));
func_notelen_action = functions_menu->addAction(tr("Change note &length"), menu_mapper, SLOT(map()));
@@ -3908,7 +3908,7 @@ void ScoreCanvas::mouseMoveEvent (QMouseEvent* event)
unsigned newpartlen=dragged_event_part->lenTick();
if (tmp.endTick() > dragged_event_part->lenTick())
{
- if (dragged_event_part->hasHiddenNotes()) // do not allow autoexpand
+ if (dragged_event_part->hasHiddenEvents()) // do not allow autoexpand
{
tmp.setLenTick(dragged_event_part->lenTick() - tmp.tick());
if (debugMsg) cout << "resized note would exceed its part; limiting length to " << tmp.lenTick() << endl;
@@ -4461,7 +4461,7 @@ void staff_t::update_part_indices()
*
* o maybe remove "insert empty measure"?
* o add "move other notes" or "overwrite notes" or "mix with notes" to paste
- * o draw the edge of parts hiding notes "jagged" (hasHiddenNotes() is interesting for this)
+ * o draw the edge of parts hiding notes "jagged" (hasHiddenEvents() is interesting for this) - Done. Tim.
* o shrink a part from its beginning as well! watch out for clones!
* o insert empty measure should also work inside parts, that is,
* move notes _within_ parts
diff --git a/muse2/muse/mixer/astrip.cpp b/muse2/muse/mixer/astrip.cpp
index 5644e6eb..658a4970 100644
--- a/muse2/muse/mixer/astrip.cpp
+++ b/muse2/muse/mixer/astrip.cpp
@@ -211,16 +211,14 @@ void AudioStrip::songChanged(int val)
autoType->setCurrentItem(track->automationType());
if(track->automationType() == AUTO_TOUCH || track->automationType() == AUTO_WRITE)
{
- //autoType->setPaletteBackgroundColor(Qt::red);
QPalette palette;
- palette.setColor(autoType->backgroundRole(), QColor(Qt::red));
+ palette.setColor(QPalette::Button, QColor(Qt::red));
autoType->setPalette(palette);
}
else
{
- //autoType->setPaletteBackgroundColor(qApp->palette().active().background());
QPalette palette;
- palette.setColor(autoType->backgroundRole(), qApp->palette().color(QPalette::Active, QPalette::Background));
+ palette.setColor(QPalette::Button, qApp->palette().color(QPalette::Active, QPalette::Background));
autoType->setPalette(palette);
}
@@ -927,41 +925,31 @@ AudioStrip::AudioStrip(QWidget* parent, AudioTrack* at)
// automation type
//---------------------------------------------------
- autoType = new ComboBox(this);
+ autoType = new ComboBox();
autoType->setFont(config.fonts[1]);
autoType->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum));
- autoType->setAlignment(Qt::AlignCenter);
- autoType->insertItem(tr("Off"), AUTO_OFF);
- autoType->insertItem(tr("Read"), AUTO_READ);
- autoType->insertItem(tr("Touch"), AUTO_TOUCH);
- autoType->insertItem(tr("Write"), AUTO_WRITE);
+ autoType->addAction(tr("Off"), AUTO_OFF);
+ autoType->addAction(tr("Read"), AUTO_READ);
+ autoType->addAction(tr("Touch"), AUTO_TOUCH);
+ autoType->addAction(tr("Write"), AUTO_WRITE);
autoType->setCurrentItem(t->automationType());
- // FIXME: TODO: Convert ComboBox to QT4
- //autoType->insertItem(AUTO_OFF, tr("Off"));
- //autoType->insertItem(AUTO_READ, tr("Read"));
- //autoType->insertItem(AUTO_TOUCH, tr("Touch"));
- //autoType->insertItem(AUTO_WRITE, tr("Write"));
- //autoType->setCurrentIndex(t->automationType());
-
+
if(t->automationType() == AUTO_TOUCH || t->automationType() == AUTO_WRITE)
{
- // FIXME:
- //autoType->setPaletteBackgroundColor(Qt::red);
- QPalette palette;
- palette.setColor(autoType->backgroundRole(), QColor(Qt::red));
- autoType->setPalette(palette);
+ QPalette palette;
+ palette.setColor(QPalette::Button, QColor(Qt::red));
+ autoType->setPalette(palette);
}
else
{
- // FIXME:
- //autoType->setPaletteBackgroundColor(qApp->palette().active().background());
QPalette palette;
- palette.setColor(autoType->backgroundRole(), qApp->palette().color(QPalette::Active, QPalette::Background));
+ palette.setColor(QPalette::Button, qApp->palette().color(QPalette::Active, QPalette::Background));
autoType->setPalette(palette);
}
+
autoType->setToolTip(tr("automation type"));
- connect(autoType, SIGNAL(activated(int,int)), SLOT(setAutomationType(int,int)));
+ connect(autoType, SIGNAL(activated(int)), SLOT(setAutomationType(int)));
grid->addWidget(autoType, _curGridRow++, 0, 1, 2);
if (off) {
diff --git a/muse2/muse/mixer/mstrip.cpp b/muse2/muse/mixer/mstrip.cpp
index d773708a..ad21916d 100644
--- a/muse2/muse/mixer/mstrip.cpp
+++ b/muse2/muse/mixer/mstrip.cpp
@@ -405,28 +405,21 @@ MidiStrip::MidiStrip(QWidget* parent, MidiTrack* t)
// automation mode
//---------------------------------------------------
- autoType = new ComboBox(this);
+ autoType = new ComboBox();
autoType->setFont(config.fonts[1]);
autoType->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum));
- autoType->setAlignment(Qt::AlignCenter);
autoType->setEnabled(false);
// Removed by T356.
// Disabled for now. There is no midi automation mechanism yet...
- //autoType->insertItem(tr("Off"), AUTO_OFF);
- //autoType->insertItem(tr("Read"), AUTO_READ);
- //autoType->insertItem(tr("Touch"), AUTO_TOUCH);
- //autoType->insertItem(tr("Write"), AUTO_WRITE);
+ //autoType->addAction(tr("Off"), AUTO_OFF);
+ //autoType->addAction(tr("Read"), AUTO_READ);
+ //autoType->addAction(tr("Touch"), AUTO_TOUCH);
+ //autoType->addAction(tr("Write"), AUTO_WRITE);
//autoType->setCurrentItem(t->automationType());
- // TODO: Convert ComboBox to QT4
- //autoType->insertItem(AUTO_OFF, tr("Off"));
- //autoType->insertItem(AUTO_READ, tr("Read"));
- //autoType->insertItem(AUTO_TOUCH, tr("Touch"));
- //autoType->insertItem(AUTO_WRITE, tr("Write"));
- //autoType->setCurrentIndex(t->automationType());
- //autoType->setToolTip(tr("automation type"));
-
- //connect(autoType, SIGNAL(activated(int,int)), SLOT(setAutomationType(int,int)));
+ //autoType->setToolTip(tr("automation type"));
+ //connect(autoType, SIGNAL(activated(int)), SLOT(setAutomationType(int)));
+
grid->addWidget(autoType, _curGridRow++, 0, 1, 2);
connect(heartBeatTimer, SIGNAL(timeout()), SLOT(heartBeat()));
inHeartBeat = false;
diff --git a/muse2/muse/mixer/strip.cpp b/muse2/muse/mixer/strip.cpp
index 0c4059d8..3cf9765d 100644
--- a/muse2/muse/mixer/strip.cpp
+++ b/muse2/muse/mixer/strip.cpp
@@ -257,7 +257,7 @@ Strip::~Strip()
// setAutomationType
//---------------------------------------------------------
-void Strip::setAutomationType(int t,int)
+void Strip::setAutomationType(int t)
{
track->setAutomationType(AutomationType(t));
song->update(SC_AUTOMATION);
diff --git a/muse2/muse/mixer/strip.h b/muse2/muse/mixer/strip.h
index b138992e..cf3babe8 100644
--- a/muse2/muse/mixer/strip.h
+++ b/muse2/muse/mixer/strip.h
@@ -60,7 +60,7 @@ class Strip : public QFrame {
protected slots:
virtual void heartBeat();
- void setAutomationType(int t,int);
+ void setAutomationType(int t);
public slots:
void resetPeaks();
diff --git a/muse2/muse/part.cpp b/muse2/muse/part.cpp
index 67cf441e..239d53d5 100644
--- a/muse2/muse/part.cpp
+++ b/muse2/muse/part.cpp
@@ -4,6 +4,7 @@
// $Id: part.cpp,v 1.12.2.17 2009/06/25 05:13:02 terminator356 Exp $
//
// (C) Copyright 1999/2000 Werner Schweer (ws@seh.de)
+// Additions, modifications (C) Copyright 2011 Tim E. Real (terminator356 on users DOT sourceforge DOT net)
//=========================================================
#include <stdio.h>
@@ -655,6 +656,7 @@ Part* PartList::find(int idx)
Part::Part(Track* t)
{
+ _hiddenEvents = NoEventsHidden;
_prevClone = this;
_nextClone = this;
setSn(newSn());
@@ -673,6 +675,7 @@ Part::Part(Track* t)
Part::Part(Track* t, EventList* ev)
{
+ _hiddenEvents = NoEventsHidden;
_prevClone = this;
_nextClone = this;
setSn(newSn());
@@ -849,7 +852,6 @@ void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len, bool doClo
Event newEvent = e.clone();
newEvent.setLenFrame(new_partlength - event_startframe);
// Do not do port controller values and clone parts.
- audio->msgChangeEvent(e, newEvent, nPart, false, false, false);
operations.push_back(UndoOp(UndoOp::ModifyEvent, newEvent, e, nPart, false,false));
}
}
@@ -889,7 +891,6 @@ void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len, bool doClo
nPart->setLenFrame(new_partlength);
// Do not do port controller values and clone parts.
- audio->msgChangePart(oPart, nPart, false, false, false);
operations.push_back(UndoOp(UndoOp::ModifyPart, oPart, nPart, false, false));
song->applyOperationGroup(operations);
}
@@ -1169,15 +1170,38 @@ WavePart* WavePart::clone() const
return new WavePart(*this);
}
+/*
+bool Part::hasHiddenNotes()
+{
+ unsigned lastNote=0;
+ for (iEvent ev=events()->begin(); ev!=events()->end(); ev++)
+ if (ev->second.endTick() > lastNote)
+ lastNote=ev->second.endTick();
+
+ return lastNote > lenTick();
+}
+*/
-bool Part::hasHiddenNotes()
+//---------------------------------------------------------
+// hasHiddenEvents
+// Returns combination of HiddenEventsType enum.
+//---------------------------------------------------------
+
+int Part::hasHiddenEvents()
{
- unsigned lastNote=0;
+ unsigned len = lenTick();
- for (iEvent ev=events()->begin(); ev!=events()->end(); ev++)
- if (ev->second.endTick() > lastNote)
- lastNote=ev->second.endTick();
-
- return lastNote > lenTick();
+ // TODO: For now, we don't support events before the left border, only events past the right border.
+ for(iEvent ev=events()->begin(); ev!=events()->end(); ev++)
+ {
+ if(ev->second.endTick() > len)
+ {
+ _hiddenEvents = RightEventsHidden; // Cache the result for later.
+ return _hiddenEvents;
+ }
+ }
+ _hiddenEvents = NoEventsHidden; // Cache the result for later.
+ return _hiddenEvents;
}
+
diff --git a/muse2/muse/part.h b/muse2/muse/part.h
index ff7091a6..67a67dbb 100644
--- a/muse2/muse/part.h
+++ b/muse2/muse/part.h
@@ -4,6 +4,7 @@
// $Id: part.h,v 1.5.2.4 2009/05/24 21:43:44 terminator356 Exp $
//
// (C) Copyright 1999/2000 Werner Schweer (ws@seh.de)
+// Additions, modifications (C) Copyright 2011 Tim E. Real (terminator356 on users DOT sourceforge DOT net)
//=========================================================
#ifndef __PART_H__
@@ -40,6 +41,10 @@ typedef CloneList::iterator iClone;
//---------------------------------------------------------
class Part : public PosLen {
+ public:
+ enum HiddenEventsType { NoEventsHidden = 0, LeftEventsHidden, RightEventsHidden };
+
+ private:
static int snGen;
int _sn;
@@ -48,6 +53,8 @@ class Part : public PosLen {
bool _mute;
int _colorIndex;
+ int _hiddenEvents; // Combination of HiddenEventsType.
+
protected:
Track* _track;
EventList* _events;
@@ -82,7 +89,11 @@ class Part : public PosLen {
void setPrevClone(Part* p) { _prevClone = p; }
void setNextClone(Part* p) { _nextClone = p; }
- bool hasHiddenNotes();
+ // Returns combination of HiddenEventsType enum.
+ int hasHiddenEvents();
+ // If repeated calls to hasHiddenEvents() are desired, then to avoid re-iteration of the event list,
+ // call this after hasHiddenEvents().
+ int cachedHasHiddenEvents() const { return _hiddenEvents; }
iEvent addEvent(Event& p);
diff --git a/muse2/muse/steprec.cpp b/muse2/muse/steprec.cpp
index c1fc23b1..45af3930 100644
--- a/muse2/muse/steprec.cpp
+++ b/muse2/muse/steprec.cpp
@@ -77,7 +77,7 @@ void StepRec::record(Part* part, int pitch, int len, int step, int velo, bool ct
{
// if we already entered the note, delete it
// if we would find a note after part->lenTick(), the above "if"
- // avoids this. this has to be avoided because then part->hasHiddenNotes() is true
+ // avoids this. this has to be avoided because then part->hasHiddenEvents() is true
// which results in forbidding any action beyond its end
EventRange range = events->equal_range(tick - part->tick());
for (iEvent i = range.first; i != range.second; ++i)
@@ -173,7 +173,7 @@ void StepRec::record(Part* part, int pitch, int len, int step, int velo, bool ct
}
steprec_record_foot:
- if (!((lasttick > part->lenTick()) && part->hasHiddenNotes())) // allowed?
+ if (!((lasttick > part->lenTick()) && part->hasHiddenEvents())) // allowed?
{
if (lasttick > part->lenTick()) // we have to expand the part?
schedule_resize_all_same_len_clone_parts(part, lasttick, operations);
diff --git a/muse2/muse/widgets/canvas.cpp b/muse2/muse/widgets/canvas.cpp
index a74e8a8f..c7186a2d 100644
--- a/muse2/muse/widgets/canvas.cpp
+++ b/muse2/muse/widgets/canvas.cpp
@@ -3,6 +3,7 @@
// Linux Music Editor
// $Id: canvas.cpp,v 1.10.2.17 2009/05/03 04:14:01 terminator356 Exp $
// (C) Copyright 1999 Werner Schweer (ws@seh.de)
+// Additions, modifications (C) Copyright 2011 Tim E. Real (terminator356 on users DOT sourceforge DOT net)
//=========================================================
#include <stdio.h>
@@ -18,6 +19,8 @@
#include <QMouseEvent>
#include <QWheelEvent>
+#include <vector>
+
#include "song.h"
#include "event.h"
#include "citem.h"
@@ -148,6 +151,11 @@ void Canvas::draw(QPainter& p, const QRect& rect)
int h = rect.height();
int x2 = x + w;
+ std::vector<CItem*> list1;
+ std::vector<CItem*> list2;
+ //std::vector<CItem*> list3;
+ std::vector<CItem*> list4;
+
if (virt()) {
drawCanvas(p, rect);
@@ -157,22 +165,24 @@ void Canvas::draw(QPainter& p, const QRect& rect)
iCItem to(items.lower_bound(x2));
+ /*
// Draw items from other parts behind all others.
// Only for items with events (not arranger parts).
for(iCItem i = items.begin(); i != to; ++i)
{
CItem* ci = i->second;
+ // NOTE Optimization: For each item call this once now, then use cached results later via cachedHasHiddenEvents().
+ ci->part()->hasHiddenEvents();
if(!ci->event().empty() && ci->part() != curPart)
- {
drawItem(p, ci, rect);
- }
}
-
+
+ // Draw unselected parts behind selected.
for (iCItem i = items.begin(); i != to; ++i)
{
CItem* ci = i->second;
- // Draw unselected parts behind selected.
- if(!ci->isSelected() && !ci->isMoving() && (ci->event().empty() || ci->part() == curPart))
+ if((!ci->isSelected() && !ci->isMoving() && (ci->event().empty() || ci->part() == curPart))
+ && !(ci->event().empty() && (ci->part()->events()->arefCount() > 1 || ci->part()->cachedHasHiddenEvents()))) // p4.0.29
{
drawItem(p, ci, rect);
}
@@ -181,12 +191,57 @@ void Canvas::draw(QPainter& p, const QRect& rect)
// Draw selected parts in front of unselected.
for (iCItem i = items.begin(); i != to; ++i)
{
- CItem* ci = i->second;
- if(ci->isSelected() && !ci->isMoving() && (ci->event().empty() || ci->part() == curPart))
- {
- drawItem(p, ci, rect);
- }
+ CItem* ci = i->second;
+ if(ci->isSelected() && !ci->isMoving() && (ci->event().empty() || ci->part() == curPart))
+ //if((ci->isSelected() && !ci->isMoving() && (ci->event().empty() || ci->part() == curPart))
+ // || (ci->event().empty() && (ci->part()->events()->arefCount() > 1 || ci->part()->cachedHasHiddenEvents())))
+ {
+ drawItem(p, ci, rect);
+ }
+ }
+ */
+
+ // p4.0.29
+ for(iCItem i = items.begin(); i != to; ++i)
+ {
+ CItem* ci = i->second;
+ // NOTE Optimization: For each item call this once now, then use cached results later via cachedHasHiddenEvents().
+ // Not required for now.
+ //ci->part()->hasHiddenEvents();
+
+ // Draw items from other parts behind all others.
+ // Only for items with events (not arranger parts).
+ if(!ci->event().empty() && ci->part() != curPart)
+ list1.push_back(ci);
+ else if(!ci->isMoving() && (ci->event().empty() || ci->part() == curPart))
+ {
+ // Draw selected parts in front of all others.
+ if(ci->isSelected())
+ list4.push_back(ci);
+ // Draw clone parts, and parts with hidden events, in front of others all except selected.
+ //else if(ci->event().empty() && (ci->part()->events()->arefCount() > 1 || ci->part()->cachedHasHiddenEvents()))
+ // Draw clone parts in front of others all except selected.
+ //else if(ci->event().empty() && (ci->part()->events()->arefCount() > 1))
+ // list3.push_back(ci);
+ else
+ // Draw unselected parts.
+ list2.push_back(ci);
+ }
}
+ int i;
+ int sz = list1.size();
+ for(i = 0; i != sz; ++i)
+ drawItem(p, list1[i], rect);
+ sz = list2.size();
+ for(i = 0; i != sz; ++i)
+ drawItem(p, list2[i], rect);
+ //sz = list3.size();
+ //for(i = 0; i != sz; ++i)
+ // drawItem(p, list3[i], rect);
+ sz = list4.size();
+ for(i = 0; i != sz; ++i)
+ drawItem(p, list4[i], rect);
+
to = moving.lower_bound(x2);
for (iCItem i = moving.begin(); i != to; ++i)
{
@@ -237,21 +292,22 @@ void Canvas::draw(QPainter& p, const QRect& rect)
//---------------------------------------------------
// draw Canvas Items
//---------------------------------------------------
-
+
+ /*
// Draw items from other parts behind all others.
// Only for items with events (not arranger parts).
for(iCItem i = items.begin(); i != items.end(); ++i)
{
CItem* ci = i->second;
+ // NOTE Optimization: For each item call this once now, then use cached results later via cachedHasHiddenEvents().
+ ci->part()->hasHiddenEvents();
if(!ci->event().empty() && ci->part() != curPart)
- {
drawItem(p, ci, rect);
- }
- }
-
+ }
+
+ // Draw unselected parts behind selected.
for (iCItem i = items.begin(); i != items.end(); ++i) {
CItem* ci = i->second;
- // Draw unselected parts behind selected.
if(!ci->isSelected() && !ci->isMoving() && (ci->event().empty() || ci->part() == curPart))
{
drawItem(p, ci, rect);
@@ -262,10 +318,55 @@ void Canvas::draw(QPainter& p, const QRect& rect)
for (iCItem i = items.begin(); i != items.end(); ++i) {
CItem* ci = i->second;
if(ci->isSelected() && !ci->isMoving() && (ci->event().empty() || ci->part() == curPart))
- {
- drawItem(p, ci, rect);
- }
- }
+ //if((ci->isSelected() && !ci->isMoving() && (ci->event().empty() || ci->part() == curPart))
+ // || (ci->event().empty() && (ci->part()->events()->arefCount() > 1 || ci->part()->cachedHasHiddenEvents())))
+ {
+ drawItem(p, ci, rect);
+ }
+ }
+ */
+
+ // p4.0.29
+ for(iCItem i = items.begin(); i != items.end(); ++i)
+ {
+ CItem* ci = i->second;
+ // NOTE Optimization: For each item call this once now, then use cached results later via cachedHasHiddenEvents().
+ // Not required for now.
+ //ci->part()->hasHiddenEvents();
+
+ // Draw items from other parts behind all others.
+ // Only for items with events (not arranger parts).
+ if(!ci->event().empty() && ci->part() != curPart)
+ list1.push_back(ci);
+ else if(!ci->isMoving() && (ci->event().empty() || ci->part() == curPart))
+ {
+ // Draw selected parts in front of all others.
+ if(ci->isSelected())
+ list4.push_back(ci);
+ // Draw clone parts, and parts with hidden events, in front of others all except selected.
+ //else if(ci->event().empty() && (ci->part()->events()->arefCount() > 1 || ci->part()->cachedHasHiddenEvents()))
+ // Draw clone parts in front of others all except selected.
+ //else if(ci->event().empty() && (ci->part()->events()->arefCount() > 1))
+ // list3.push_back(ci);
+ else
+ // Draw unselected parts.
+ list2.push_back(ci);
+ }
+ }
+ int i;
+ int sz = list1.size();
+ for(i = 0; i != sz; ++i)
+ drawItem(p, list1[i], rect);
+ sz = list2.size();
+ for(i = 0; i != sz; ++i)
+ drawItem(p, list2[i], rect);
+ //sz = list3.size();
+ //for(i = 0; i != sz; ++i)
+ // drawItem(p, list3[i], rect);
+ sz = list4.size();
+ for(i = 0; i != sz; ++i)
+ drawItem(p, list4[i], rect);
+
for (iCItem i = moving.begin(); i != moving.end(); ++i)
{
drawItem(p, i->second, rect);
@@ -273,19 +374,26 @@ void Canvas::draw(QPainter& p, const QRect& rect)
drawTopItem(p, QRect(x,y,w,h));
p.save();
setPainter(p);
- }
+ }
//---------------------------------------------------
// draw marker
//---------------------------------------------------
- int y2 = y + h;
+ //p.save();
+ bool wmtxen = p.worldMatrixEnabled();
+ p.setWorldMatrixEnabled(false);
+
+ int my = mapy(y);
+ //int y2 = y + h;
+ int my2 = mapy(y + h);
MarkerList* marker = song->marker();
for (iMarker m = marker->begin(); m != marker->end(); ++m) {
int xp = m->second.tick();
if (xp >= x && xp < x+w) {
p.setPen(Qt::green);
- p.drawLine(xp, y, xp, y2);
+ //p.drawLine(xp, y, xp, y2);
+ p.drawLine(mapx(xp), my, mapx(xp), my2);
}
}
@@ -294,16 +402,28 @@ void Canvas::draw(QPainter& p, const QRect& rect)
//---------------------------------------------------
p.setPen(Qt::blue);
+ int mx;
if (pos[1] >= unsigned(x) && pos[1] < unsigned(x2)) {
- p.drawLine(pos[1], y, pos[1], y2);
+ //p.drawLine(pos[1], y, pos[1], y2);
+ mx = mapx(pos[1]);
+ p.drawLine(mx, my, mx, my2);
+ }
+ if (pos[2] >= unsigned(x) && pos[2] < unsigned(x2)) {
+ //p.drawLine(pos[2], y, pos[2], y2);
+ mx = mapx(pos[2]);
+ p.drawLine(mx, my, mx, my2);
}
- if (pos[2] >= unsigned(x) && pos[2] < unsigned(x2))
- p.drawLine(pos[2], y, pos[2], y2);
p.setPen(Qt::red);
if (pos[0] >= unsigned(x) && pos[0] < unsigned(x2)) {
- p.drawLine(pos[0], y, pos[0], y2);
+ //p.drawLine(pos[0], y, pos[0], y2);
+ mx = mapx(pos[0]);
+ p.drawLine(mx, my, mx, my2);
}
+ //p.restore();
+ //p.setWorldMatrixEnabled(true);
+ p.setWorldMatrixEnabled(wmtxen);
+
//---------------------------------------------------
// draw lasso
//---------------------------------------------------
diff --git a/muse2/muse/widgets/canvas.h b/muse2/muse/widgets/canvas.h
index dbe13fcb..99bbabee 100644
--- a/muse2/muse/widgets/canvas.h
+++ b/muse2/muse/widgets/canvas.h
@@ -3,6 +3,7 @@
// Linux Music Editor
// $Id: canvas.h,v 1.3.2.8 2009/02/02 21:38:01 terminator356 Exp $
// (C) Copyright 1999 Werner Schweer (ws@seh.de)
+// Additions, modifications (C) Copyright 2011 Tim E. Real (terminator356 on users DOT sourceforge DOT net)
//=========================================================
#ifndef __CANVAS_H__
diff --git a/muse2/muse/widgets/combobox.cpp b/muse2/muse/widgets/combobox.cpp
index 9e278376..bd78d6f2 100644
--- a/muse2/muse/widgets/combobox.cpp
+++ b/muse2/muse/widgets/combobox.cpp
@@ -6,6 +6,8 @@
//=========================================================
#include <QMenu>
+#include <QSignalMapper>
+#include <QWheelEvent>
#include "combobox.h"
@@ -14,67 +16,75 @@
//---------------------------------------------------------
ComboBox::ComboBox(QWidget* parent, const char* name)
- : QLabel(parent)
+ : QToolButton(parent)
{
setObjectName(name);
_currentItem = 0;
- _id = -1;
- list = new QMenu(0);
- connect(list, SIGNAL(triggered(QAction*)), SLOT(activatedIntern(QAction*)));
- setFrameStyle(QFrame::Panel | QFrame::Raised);
- setLineWidth(2);
+
+ menu = new QMenu(this);
+
+ autoTypeSignalMapper = new QSignalMapper(this);
+ connect(autoTypeSignalMapper, SIGNAL(mapped(int)), this, SLOT(activatedIntern(int)));
}
ComboBox::~ComboBox()
{
- delete list;
+ delete menu;
}
//---------------------------------------------------------
// mousePressEvent
//---------------------------------------------------------
-void ComboBox::mousePressEvent(QMouseEvent*)
+void ComboBox::mousePressEvent(QMouseEvent* /*ev*/)
+ {
+ menu->exec(QCursor::pos());
+ }
+
+//---------------------------------------------------------
+// wheelEvent
+//---------------------------------------------------------
+
+void ComboBox::wheelEvent(QWheelEvent* ev)
{
- list->exec(QCursor::pos());
+ int i = itemlist.indexOf(_currentItem);
+ int len = itemlist.count();
+ if (ev->delta() > 0 && i > 0)
+ activatedIntern(_currentItem-1);
+ else if (ev->delta() < 0 && -1 < i && i < len - 1)
+ activatedIntern(_currentItem+1);
}
//---------------------------------------------------------
// activated
//---------------------------------------------------------
-void ComboBox::activatedIntern(QAction* act)
+void ComboBox::activatedIntern(int id)
{
- _currentItem = act->data().toInt();
- emit activated(_currentItem, _id);
- setText(act->text());
+ setCurrentItem(id);
+ emit activated(id);
}
//---------------------------------------------------------
// setCurrentItem
//---------------------------------------------------------
-void ComboBox::setCurrentItem(int i)
+void ComboBox::setCurrentItem(int id)
{
- _currentItem = i;
- // ORCAN - CHECK
- QList<QAction *> actions = list->actions();
- for (QList<QAction *>::iterator it = actions.begin(); it != actions.end(); ++it) {
- QAction* act = *it;
- if (act->data().toInt() == i) {
- setText(act->text());
- break;
- }
- }
+ QAction* act = (QAction*) autoTypeSignalMapper->mapping(id);
+ _currentItem = id;
+ setText(act->text());
}
//---------------------------------------------------------
// insertItem
//---------------------------------------------------------
-void ComboBox::insertItem(const QString& s, int id)
+void ComboBox::addAction(const QString& s, int id)
{
- QAction *act = list->addAction(s);
- act->setData(id);
+ QAction *act = menu->addAction(s);
+ connect(act, SIGNAL(triggered()), autoTypeSignalMapper, SLOT(map()));
+ autoTypeSignalMapper->setMapping(act, id);
+ itemlist << id;
}
diff --git a/muse2/muse/widgets/combobox.h b/muse2/muse/widgets/combobox.h
index 305ad0b3..c099b3ce 100644
--- a/muse2/muse/widgets/combobox.h
+++ b/muse2/muse/widgets/combobox.h
@@ -8,36 +8,38 @@
#ifndef __COMBOBOX_H__
#define __COMBOBOX_H__
-#include <QLabel>
+#include <QToolButton>
class QMenu;
+class QSignalMapper;
//---------------------------------------------------------
// ComboBox
//---------------------------------------------------------
-class ComboBox : public QLabel {
+class ComboBox : public QToolButton {
Q_OBJECT
- Q_PROPERTY( int id READ id WRITE setId )
- int _id;
int _currentItem;
- QMenu* list;
+ QList<int> itemlist;
+
+ QMenu* menu;
virtual void mousePressEvent(QMouseEvent*);
+ virtual void wheelEvent(QWheelEvent*);
+
+ QSignalMapper* autoTypeSignalMapper;
private slots:
- void activatedIntern(QAction*);
+ void activatedIntern(int id);
signals:
- void activated(int val, int id);
+ void activated(int id);
public:
- ComboBox(QWidget* parent, const char* name = 0);
+ ComboBox(QWidget* parent = 0, const char* name = 0);
~ComboBox();
void setCurrentItem(int);
- void insertItem(const QString& s, int id = -1);
- int id() const { return _id; }
- void setId(int i) { _id = i; }
+ void addAction(const QString& s, int id = -1);
};
#endif
diff --git a/muse2/muse/widgets/knob.cpp b/muse2/muse/widgets/knob.cpp
index ae88e2f4..dc41e1c4 100644
--- a/muse2/muse/widgets/knob.cpp
+++ b/muse2/muse/widgets/knob.cpp
@@ -64,6 +64,9 @@ Knob::Knob(QWidget* parent, const char* name)
d_markerColor = palette().dark().color().darker(125);
d_dotWidth = 8;
+ l_slope = 0;
+ l_const = 100;
+
setMinimumSize(30,30);
setUpdateTime(50);
}
@@ -94,6 +97,31 @@ void Knob::setTotalAngle (double angle)
}
//------------------------------------------------------------
+// Knob::setRange
+// Set the range and step size of the knob
+//
+// Sets the paramaters that define the shininess of the ring
+// surrounding the knob and then proceeds by passing the
+// parameters to the parent class' setRange() function.
+//------------------------------------------------------------
+
+void Knob::setRange(double vmin, double vmax, double vstep, int pagesize)
+ {
+ // divide by zero protection. probably too cautious
+ if (! (vmin == vmax || qMax(-vmin, vmax) == 0))
+ {
+ if (vmin * vmax < 0)
+ l_slope = 80.0 / qMax(-vmin, vmax);
+ else
+ {
+ l_slope = 80.0 / (vmax - vmin);
+ l_const = 100 - l_slope * vmin;
+ }
+ }
+ SliderBase::setRange(vmin, vmax, vstep, pagesize);
+ }
+
+//------------------------------------------------------------
// QwtKnob::drawKnob
// const QRect &r -- borders of the knob
//------------------------------------------------------------
@@ -132,7 +160,8 @@ void Knob::drawKnob(QPainter* p, const QRect& r)
QPen pn;
pn.setCapStyle(Qt::FlatCap);
- pn.setColor(d_shinyColor.lighter(100+ abs(d_angle*100)/300));
+
+ pn.setColor(d_shinyColor.lighter(l_const + abs(value() * l_slope)));
pn.setWidth(d_shineWidth * 2);
p->setPen(pn);
p->drawArc(aRect, 0, 360 * 16);
diff --git a/muse2/muse/widgets/knob.h b/muse2/muse/widgets/knob.h
index 09e13c93..2a553c4e 100644
--- a/muse2/muse/widgets/knob.h
+++ b/muse2/muse/widgets/knob.h
@@ -36,6 +36,9 @@ class Knob : public SliderBase, public ScaleIf
double d_totalAngle;
double d_nTurns;
+ double l_const;
+ double l_slope;
+
QRect kRect;
bool _faceColSel;
QColor d_faceColor;
@@ -62,6 +65,8 @@ class Knob : public SliderBase, public ScaleIf
Knob(QWidget* parent = 0, const char *name = 0);
~Knob() {}
+ void setRange(double vmin, double vmax, double vstep = 0.0,
+ int pagesize = 1);
void setKnobWidth(int w);
void setTotalAngle (double angle);
void setBorderWidth(int bw);
diff --git a/muse2/muse/widgets/meter.cpp b/muse2/muse/widgets/meter.cpp
index 6619d1dc..9f13059e 100644
--- a/muse2/muse/widgets/meter.cpp
+++ b/muse2/muse/widgets/meter.cpp
@@ -2,11 +2,11 @@
// MusE
// Linux Music Editor
// $Id: meter.cpp,v 1.4.2.2 2009/05/03 04:14:00 terminator356 Exp $
+// redesigned by oget on 2011/08/15
//
// (C) Copyright 2000 Werner Schweer (ws@seh.de)
//=========================================================
-#include <stdio.h>
#include <cmath>
#include <QMouseEvent>
@@ -30,7 +30,8 @@ Meter::Meter(QWidget* parent, MeterType type)
// 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().
setAttribute(Qt::WA_OpaquePaintEvent);
-
+ //setFrameStyle(QFrame::Raised | QFrame::StyledPanel);
+
mtype = type;
overflow = false;
val = 0.0;
@@ -41,6 +42,57 @@ Meter::Meter(QWidget* parent, MeterType type)
redScale = 0;
setLineWidth(0);
setMidLineWidth(0);
+
+ dark_red_end = QColor(0x8e0000);
+ dark_red_begin = QColor(0x8e3800);
+
+ dark_yellow_end = QColor(0x8e6800);
+ dark_yellow_center = QColor(0x8e8e00);
+ dark_yellow_begin = QColor(0x6a8400);
+
+ dark_green_end = QColor(0x467800);
+ dark_green_begin = QColor(0x007000);
+
+ light_red_end = QColor(0xff0000);
+ light_red_begin = QColor(0xdd8800);
+
+ light_yellow_end = QColor(0xddcc00);
+ light_yellow_center = QColor(0xffff00);
+ light_yellow_begin = QColor(0xddff00);
+
+ light_green_end = QColor(0x88ff00);
+ light_green_begin = QColor(0x00ff00);
+
+ mask_center = QColor(225, 225, 225, 64);
+ mask_edge = QColor(30, 30, 30, 64);
+
+ separator_color = QColor(0x666666);
+ peak_color = QColor(0xeeeeee);
+
+ darkGradGreen.setColorAt(1, dark_green_begin);
+ darkGradGreen.setColorAt(0, dark_green_end);
+
+ darkGradYellow.setColorAt(1, dark_yellow_begin);
+ darkGradYellow.setColorAt(0.5, dark_yellow_center);
+ darkGradYellow.setColorAt(0, dark_yellow_end);
+
+ darkGradRed.setColorAt(1, dark_red_begin);
+ darkGradRed.setColorAt(0, dark_red_end);
+
+ lightGradGreen.setColorAt(1, light_green_begin);
+ lightGradGreen.setColorAt(0, light_green_end);
+
+ lightGradYellow.setColorAt(1, light_yellow_begin);
+ lightGradYellow.setColorAt(0.5, light_yellow_center);
+ lightGradYellow.setColorAt(0, light_yellow_end);
+
+ lightGradRed.setColorAt(1, light_red_begin);
+ lightGradRed.setColorAt(0, light_red_end);
+
+ maskGrad.setColorAt(0, mask_edge);
+ maskGrad.setColorAt(0.5, mask_center);
+ maskGrad.setColorAt(1, mask_edge);
+
}
//---------------------------------------------------------
@@ -106,17 +158,23 @@ void Meter::setRange(double min, double max)
// paintEvent
//---------------------------------------------------------
-void Meter::paintEvent(QPaintEvent* /*ev*/)
+void Meter::paintEvent(QPaintEvent* ev)
{
// TODO: Could make better use of event rectangle, for speed.
QPainter p(this);
+ //p.setRenderHint(QPainter::Antialiasing);
double range = maxScale - minScale;
-
+ /*
int fw = frameWidth();
int w = width() - 2*fw;
int h = height() - 2*fw;
+ */
+
+ QRect rect = ev->rect();
+ int w = rect.width();
+ int h = rect.height();
int yv;
if(mtype == DBMeter)
@@ -135,10 +193,17 @@ void Meter::paintEvent(QPaintEvent* /*ev*/)
ymax = maxVal == 0 ? 0 : int(((maxScale - (fast_log10(maxVal) * 20.0)) * h)/range);
else
ymax = maxVal == 0 ? 0 : int(((maxScale - maxVal) * h)/range);
- p.setPen(Qt::white);
+ p.setPen(peak_color);
p.drawLine(0, ymax, w, ymax);
+
+ // Draw the transparent layer on top of everything to give a 3d look
+ maskGrad.setStart(QPointF(0, 0));
+ maskGrad.setFinalStop(QPointF(w, 0));
+ p.fillRect(0, 0, w, h, QBrush(maskGrad));
+
}
+
//---------------------------------------------------------
// drawVU
//---------------------------------------------------------
@@ -150,60 +215,119 @@ void Meter::drawVU(QPainter& p, int w, int h, int yv)
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));
+
if(yv < y1)
{
// Red section:
- p.fillRect(0, 0, w, yv, QBrush(0x8e0000)); // dark red
- p.fillRect(0, yv, w, y1-yv, QBrush(0xff0000)); // light red
+ p.fillRect(0, 0, w, yv, QBrush(darkGradRed)); // dark red
+ p.fillRect(0, yv, w, y1-yv, QBrush(lightGradRed)); // light red
// Yellow section:
- p.fillRect(0, y1, w, y2-y1, QBrush(0xffff00)); // light yellow
+ p.fillRect(0, y1, w, y2-y1, QBrush(lightGradYellow)); // light yellow
// Green section:
- p.fillRect(0, y2, w, h-y2, QBrush(0x00ff00)); // light green
+ p.fillRect(0, y2, w, h-y2, QBrush(lightGradGreen)); // light green
}
else
if(yv < y2)
{
// Red section:
- p.fillRect(0, 0, w, y1, QBrush(0x8e0000)); // dark red
+ p.fillRect(0, 0, w, y1, QBrush(darkGradRed)); // dark red
// Yellow section:
- p.fillRect(0, y1, w, yv-y1, QBrush(0x8e8e00)); // dark yellow
- p.fillRect(0, yv, w, y2-yv, QBrush(0xffff00)); // light yellow
+ 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.fillRect(0, y2, w, h-y2, QBrush(0x00ff00)); // light green
+ p.fillRect(0, y2, w, h-y2, QBrush(lightGradGreen)); // light green
}
else
//if(yv <= y3)
{
// Red section:
- p.fillRect(0, 0, w, y1, QBrush(0x8e0000)); // dark red
+ p.fillRect(0, 0, w, y1, QBrush(darkGradRed)); // dark red
// Yellow section:
- p.fillRect(0, y1, w, y2-y1, QBrush(0x8e8e00)); // dark yellow
+ p.fillRect(0, y1, w, y2-y1, QBrush(darkGradYellow)); // dark yellow
// Green section:
- p.fillRect(0, y2, w, yv-y2, QBrush(0x007000)); // dark green
- p.fillRect(0, yv, w, h-yv, QBrush(0x00ff00)); // light green
+ p.fillRect(0, y2, w, yv-y2, QBrush(darkGradGreen)); // dark green
+ p.fillRect(0, yv, w, h-yv, QBrush(lightGradGreen)); // light green
}
+
+ p.fillRect(0,y1, w, 1, separator_color);
+ p.fillRect(0,y2, w, 1, separator_color);
+
}
else
{
- p.fillRect(0, 0, w, yv, QBrush(0x007000)); // dark green
- p.fillRect(0, yv, w, h-yv, QBrush(0x00ff00)); // light green
+ darkGradGreen.setStart(QPointF(0, 0));
+ darkGradGreen.setFinalStop(QPointF(0, h));
+
+ lightGradGreen.setStart(QPointF(0, 0));
+ lightGradGreen.setFinalStop(QPointF(0, h));
+
+ p.fillRect(0, 0, w, yv, QBrush(darkGradGreen)); // dark green
+ p.fillRect(0, yv, w, h-yv, QBrush(lightGradGreen)); // light green
}
+
}
//---------------------------------------------------------
// resizeEvent
//---------------------------------------------------------
-void Meter::resizeEvent(QResizeEvent* /*ev*/)
+void Meter::resizeEvent(QResizeEvent* ev)
{
-
+ // Round corners of the widget.
+
+ QSize size = ev->size();
+ int w = size.width();
+ int h = size.height();
+ QPainterPath rounded_rect;
+ rounded_rect.addRoundedRect(0,0,w,h, w/2.5, w/3);
+ QRegion maskregion(rounded_rect.toFillPolygon().toPolygon());
+ setMask(maskregion);
+
+ /*
+ // Another method to do the above. I don't know yet which one is more efficient - Orcan
+ QRect rect(0,0,w,h);
+ int r = 6;
+
+ QRegion region;
+ // middle and borders
+ region += rect.adjusted(r, 0, -r, 0);
+ region += rect.adjusted(0, r, 0, -r);
+ // top left
+ QRect corner(rect.topLeft(), QSize(r*2, r*2));
+ region += QRegion(corner, QRegion::Ellipse);
+ // top right
+ corner.moveTopRight(rect.topRight());
+ region += QRegion(corner, QRegion::Ellipse);
+ // bottom left
+ corner.moveBottomLeft(rect.bottomLeft());
+ region += QRegion(corner, QRegion::Ellipse);
+ // bottom right
+ corner.moveBottomRight(rect.bottomRight());
+ region += QRegion(corner, QRegion::Ellipse);
+ // return region;
+ setMask(region);
+ */
+
}
//---------------------------------------------------------
diff --git a/muse2/muse/widgets/meter.h b/muse2/muse/widgets/meter.h
index cced6e7a..848ae855 100644
--- a/muse2/muse/widgets/meter.h
+++ b/muse2/muse/widgets/meter.h
@@ -2,6 +2,7 @@
// MusE
// Linux Music Editor
// $Id: meter.h,v 1.1.1.1.2.2 2009/05/03 04:14:00 terminator356 Exp $
+// redesigned by oget on 2011/08/15
//
// (C) Copyright 2000 Werner Schweer (ws@seh.de)
//=========================================================
@@ -20,6 +21,41 @@ class Meter : public QFrame {
Q_OBJECT
public:
enum MeterType {DBMeter, LinMeter};
+
+ protected:
+ QLinearGradient darkGradRed;
+ QColor dark_red_end;
+ QColor dark_red_begin;
+
+ QLinearGradient darkGradYellow;
+ QColor dark_yellow_end;
+ QColor dark_yellow_center;
+ QColor dark_yellow_begin;
+
+ QLinearGradient darkGradGreen;
+ QColor dark_green_end;
+ QColor dark_green_begin;
+
+ QLinearGradient lightGradRed;
+ QColor light_red_end;
+ QColor light_red_begin;
+
+ QLinearGradient lightGradYellow;
+ QColor light_yellow_end;
+ QColor light_yellow_center;
+ QColor light_yellow_begin;
+
+ QLinearGradient lightGradGreen;
+ QColor light_green_end;
+ QColor light_green_begin;
+
+ QLinearGradient maskGrad;
+ QColor mask_center;
+ QColor mask_edge;
+
+ QColor separator_color;;
+ QColor peak_color;
+
private:
MeterType mtype;
bool overflow;
@@ -30,7 +66,6 @@ class Meter : public QFrame {
void drawVU(QPainter& p, int, int, int);
-
void paintEvent(QPaintEvent*);
void resizeEvent(QResizeEvent*);
void mousePressEvent(QMouseEvent*);
diff --git a/muse2/muse/widgets/verticalmeter.cpp b/muse2/muse/widgets/verticalmeter.cpp
index dbe50723..76f8dcd1 100644
--- a/muse2/muse/widgets/verticalmeter.cpp
+++ b/muse2/muse/widgets/verticalmeter.cpp
@@ -2,11 +2,11 @@
// MusE
// Linux Music Editor
// $Id: meter.cpp,v 1.4.2.2 2009/05/03 04:14:00 terminator356 Exp $
+// redesigned by oget on 2011/08/15
//
// (C) Copyright 2000 Werner Schweer (ws@seh.de)
//=========================================================
-#include <stdio.h>
#include <cmath>
#include <QMouseEvent>
@@ -107,7 +107,7 @@ void VerticalMeter::setRange(double min, double max)
// paintEvent
//---------------------------------------------------------
-void VerticalMeter::paintEvent(QPaintEvent* /*ev*/)
+void VerticalMeter::paintEvent(QPaintEvent* ev)
{
// TODO: Could make better use of event rectangle, for speed.
@@ -115,9 +115,15 @@ void VerticalMeter::paintEvent(QPaintEvent* /*ev*/)
double range = maxScale - minScale;
+ /*
int fw = frameWidth();
int w = width() - 2*fw;
int h = height() - 2*fw;
+ */
+
+ QRect rect = ev->rect();
+ int w = rect.width();
+ int h = rect.height();
int xv;
@@ -139,8 +145,13 @@ void VerticalMeter::paintEvent(QPaintEvent* /*ev*/)
xcenter = maxVal == 0 ? 0 : int(((maxScale - (fast_log10(0) * 20.0)) * w)/range);
else
xcenter = maxVal == 0 ? 0 : int(((0) * w)/range);
- p.setPen(Qt::white);
+ p.setPen(peak_color);
p.drawLine(xcenter, 0, xcenter, h);
+
+ // Draw the transparent layer on top of everything to give a 3d look
+ maskGrad.setStart(QPointF(0, 0));
+ maskGrad.setFinalStop(QPointF(0, h));
+ p.fillRect(0, 0, w, h, QBrush(maskGrad));
}
//---------------------------------------------------------
@@ -154,58 +165,92 @@ void VerticalMeter::drawVU(QPainter& p, int w, int h, int xv)
double range = maxScale - minScale;
int x1 = int((maxScale - redScale) * w / range);
int x2 = int((maxScale - yellowScale) * w / range);
+
+ darkGradGreen.setStart(QPointF(x2, 0));
+ darkGradGreen.setFinalStop(QPointF(w, 0));
+ darkGradYellow.setStart(QPointF(x1, 0));
+ darkGradYellow.setFinalStop(QPointF(x2, 0));
+ darkGradRed.setStart(QPointF(0, 0));
+ darkGradRed.setFinalStop(QPointF(x1, 0));
+
+ lightGradGreen.setStart(QPointF(x2, 0));
+ lightGradGreen.setFinalStop(QPointF(w, 0));
+ lightGradYellow.setStart(QPointF(x1, 0));
+ lightGradYellow.setFinalStop(QPointF(x2, 0));
+ lightGradRed.setStart(QPointF(0, 0));
+ lightGradRed.setFinalStop(QPointF(x1, 0));
+
if(xv < x1)
{
// Red section:
- p.fillRect(0, 0, xv, h, QBrush(0x8e0000)); // dark red
- p.fillRect(xv, 0, x1-xv, h, QBrush(0xff0000)); // light red
+ p.fillRect(0, 0, xv, h, QBrush(darkGradRed)); // dark red
+ p.fillRect(xv, 0, x1-xv, h, QBrush(lightGradRed)); // light red
// Yellow section:
- p.fillRect(x1, 0, x2-x1, h, QBrush(0xffff00)); // light yellow
+ p.fillRect(x1, 0, x2-x1, h, QBrush(lightGradYellow)); // light yellow
// Green section:
- p.fillRect(x2, 0, w-x2, h, QBrush(0x00ff00)); // light green
+ p.fillRect(x2, 0, w-x2, h, QBrush(lightGradGreen)); // light green
}
else
if(xv < x2)
{
// Red section:
- p.fillRect(0, 0, x1, h, QBrush(0x8e0000)); // dark red
+ p.fillRect(0, 0, x1, h, QBrush(darkGradRed)); // dark red
// Yellow section:
- p.fillRect(x1, 0, xv-x1, h, QBrush(0x8e8e00)); // dark yellow
- p.fillRect(xv, 0, x2-xv, h, QBrush(0xffff00)); // light yellow
+ p.fillRect(x1, 0, xv-x1, h, QBrush(darkGradYellow)); // dark yellow
+ p.fillRect(xv, 0, x2-xv, h, QBrush(lightGradYellow)); // light yellow
// Green section:
- p.fillRect(x2, 0, w-x2, h, QBrush(0x00ff00)); // light green
+ p.fillRect(x2, 0, w-x2, h, QBrush(lightGradGreen)); // light green
}
else
//if(yv <= y3)
{
// Red section:
- p.fillRect(0, 0, x1, h, QBrush(0x8e0000)); // dark red
+ p.fillRect(0, 0, x1, h, QBrush(darkGradRed)); // dark red
// Yellow section:
- p.fillRect(x1, 0, x2-x1, h, QBrush(0x8e8e00)); // dark yellow
+ p.fillRect(x1, 0, x2-x1, h, QBrush(darkGradYellow)); // dark yellow
// Green section:
- p.fillRect(x2, 0, xv-x2, h, QBrush(0x007000)); // dark green
- p.fillRect(xv, 0, w-xv, h, QBrush(0x00ff00)); // light green
+ p.fillRect(x2, 0, xv-x2, h, QBrush(darkGradGreen)); // dark green
+ p.fillRect(xv, 0, w-xv, h, QBrush(lightGradGreen)); // light green
}
+
+ p.fillRect(x1,0, 1, h, separator_color);
+ p.fillRect(x2,0, 1, h, separator_color);
+
}
else
{
- p.fillRect(0, 0, xv, h, QBrush(0x00ff00)); // dark green
- p.fillRect(xv, 0, w-xv, h, QBrush(0x007000)); // light green
+ darkGradGreen.setStart(QPointF(0, 0));
+ darkGradGreen.setFinalStop(QPointF(w, 0));
+
+ lightGradGreen.setStart(QPointF(0, 0));
+ lightGradGreen.setFinalStop(QPointF(w, 0));
+
+ p.fillRect(0, 0, xv, h, QBrush(lightGradGreen)); // light green
+ p.fillRect(xv, 0, w-xv, h, QBrush(darkGradGreen)); // dark green
}
+
}
//---------------------------------------------------------
// resizeEvent
//---------------------------------------------------------
-void VerticalMeter::resizeEvent(QResizeEvent* /*ev*/)
+void VerticalMeter::resizeEvent(QResizeEvent* ev)
{
+ // Round corners of the widget.
+ QSize size = ev->size();
+ int w = size.width();
+ int h = size.height();
+ QPainterPath rounded_rect;
+ rounded_rect.addRoundedRect(0,0,w,h, h/3, h/2.5);
+ QRegion maskregion(rounded_rect.toFillPolygon().toPolygon());
+ setMask(maskregion);
}
diff --git a/muse2/muse/widgets/verticalmeter.h b/muse2/muse/widgets/verticalmeter.h
index facc8b8c..9613ec43 100644
--- a/muse2/muse/widgets/verticalmeter.h
+++ b/muse2/muse/widgets/verticalmeter.h
@@ -9,9 +9,9 @@
#ifndef __VERTICALMETER_H__
#define __VERTICALMETER_H__
-#include <QFrame>
#include "meter.h"
+class QPaintEvent;
class QResizeEvent;
class QMouseEvent;
class QPainter;
diff --git a/muse2/muse/widgets/view.cpp b/muse2/muse/widgets/view.cpp
index fb480527..57955c19 100644
--- a/muse2/muse/widgets/view.cpp
+++ b/muse2/muse/widgets/view.cpp
@@ -3,6 +3,7 @@
// Linux Music Editor
// $Id: view.cpp,v 1.3.2.2 2009/04/06 01:24:55 terminator356 Exp $
// (C) Copyright 1999 Werner Schweer (ws@seh.de)
+// Additions, modifications (C) Copyright 2011 Tim E. Real (terminator356 on users DOT sourceforge DOT net)
//=========================================================
#include "view.h"
@@ -16,6 +17,10 @@
#include <QKeyEvent>
#include <QPaintEvent>
+#include "math.h"
+
+#include "al/sig.h"
+
// Don't use this, it was just for debugging.
// It's much slower than muse-1 no matter how hard I tried.
// The left/right pixmap shifters in seXPos setYPos
@@ -491,26 +496,33 @@ void View::pdraw(QPainter& p, const QRect& r)
int w = r.width();
int h = r.height();
if (xmag <= 0) {
- x -= 1;
+ // TODO These adjustments are required, otherwise gaps. Tried, unable to remove them for now. p4.0.30
+ x -= 1;
w += 2;
- x = (x + xpos + rmapx(xorg)) * (-xmag);
+ //x = (x + xpos + rmapx(xorg)) * (-xmag);
+ x = lrint((double(x + xpos) + rmapx_f(xorg)) * double(-xmag));
w = w * (-xmag);
}
else {
- x = (x + xpos + rmapx(xorg)) / xmag;
- w = (w + xmag - 1) / xmag;
+ //x = (x + xpos + rmapx(xorg)) / xmag;
+ x = lrint((double(x + xpos) + rmapx_f(xorg)) / double(xmag));
+ //w = (w + xmag - 1) / xmag;
+ w = lrint(double(w) / double(xmag));
x -= 1;
w += 2;
}
if (ymag <= 0) {
y -= 1;
h += 2;
- y = (y + ypos + rmapy(yorg)) * (-ymag);
+ //y = (y + ypos + rmapy(yorg)) * (-ymag);
+ y = lrint((double(y + ypos) + rmapy_f(yorg)) * double(-ymag));
h = h * (-ymag);
}
else {
- y = (y + ypos + rmapy(yorg)) / ymag;
- h = (h + ymag - 1) / ymag;
+ //y = (y + ypos + rmapy(yorg)) / ymag;
+ y = lrint((double(y + ypos) + rmapy_f(yorg)) / double(ymag));
+ //h = (h + ymag - 1) / ymag;
+ h = lrint(double(h) / double(ymag));
y -= 1;
h += 2;
}
@@ -535,19 +547,116 @@ void View::setPainter(QPainter& p)
p.resetMatrix(); // Q3 support says use resetMatrix instead, but resetMatrix advises resetTransform instead...
//p.resetTransform();
- p.translate(double(-(xpos+rmapx(xorg))), double(-(ypos+rmapy(yorg))));
- double xMag = (xmag < 0) ? 1.0/(-xmag) : double(xmag);
- double yMag = (ymag < 0) ? 1.0/(-ymag) : double(ymag);
+ //p.translate(double(-(xpos+rmapx(xorg))), double(-(ypos+rmapy(yorg))));
+ p.translate( -(double(xpos) + rmapx_f(xorg)) , -(double(ypos) + rmapy(yorg)));
+ //double xMag = (xmag < 0) ? 1.0/(-xmag) : double(xmag);
+ //double yMag = (ymag < 0) ? 1.0/(-ymag) : double(ymag);
+ double xMag = (xmag < 0) ? 1.0/double(-xmag) : double(xmag);
+ double yMag = (ymag < 0) ? 1.0/double(-ymag) : double(ymag);
p.scale(xMag, yMag);
}
//---------------------------------------------------------
+// drawTickRaster
+//---------------------------------------------------------
+
+void View::drawTickRaster(QPainter& p, int x, int y, int w, int h, int raster)
+ {
+ // Changed to draw in device coordinate space instead of virtual, transformed space. Tim. p4.0.30
+
+ //int mx = mapx(x);
+ int my = mapy(y);
+ //int mw = mapx(x + w) - mx;
+ //int mw = mapx(x + w) - mx - 1;
+ //int mh = mapy(y + h) - my;
+ //int mh = mapy(y + h) - my - 1;
+
+ //p.save();
+ bool wmtxen = p.worldMatrixEnabled();
+ p.setWorldMatrixEnabled(false);
+
+ int xx,bar1, bar2, beat;
+ unsigned tick;
+ AL::sigmap.tickValues(x, &bar1, &beat, &tick);
+ AL::sigmap.tickValues(x+w, &bar2, &beat, &tick);
+ ++bar2;
+ ///int y2 = y + h;
+ //int y2 = my + mh;
+ int y2 = mapy(y + h) - 1;
+ //printf("View::drawTickRaster x:%d y:%d w:%d h:%d mx:%d my:%d mw:%d mh:%d y2:%d bar1:%d bar2:%d\n", x, y, w, h, mx, my, mw, mh, y2, bar1, bar2);
+ //printf("View::drawTickRaster x:%d y:%d w:%d h:%d my:%d mh:%d y2:%d bar1:%d bar2:%d\n", x, y, w, h, my, mh, y2, bar1, bar2);
+ for (int bar = bar1; bar < bar2; ++bar) {
+ ///unsigned x = AL::sigmap.bar2tick(bar, 0, 0);
+ unsigned xb = AL::sigmap.bar2tick(bar, 0, 0);
+ int xt = mapx(xb);
+ p.setPen(Qt::black);
+ ///p.drawLine(x, y, x, y2);
+ p.drawLine(xt, my, xt, y2);
+ int z, n;
+ ///AL::sigmap.timesig(x, z, n);
+ AL::sigmap.timesig(xb, z, n);
+ ///int q = p.xForm(QPoint(raster, 0)).x() - p.xForm(QPoint(0, 0)).x();
+ ///int q = p.combinedTransform().map(QPoint(raster, 0)).x() - p.combinedTransform().map(QPoint(0, 0)).x();
+ //int q = rmapx(raster);
+ int qq = raster;
+ //if (q < 8) // grid too dense
+ if (rmapx(raster) < 8) // grid too dense
+ qq *= 2;
+ p.setPen(Qt::lightGray);
+ if (raster>=4) {
+ ///int xx = x + qq;
+ //int xx = mapx(xb + qq);
+ xx = xb + qq;
+ int xxx = AL::sigmap.bar2tick(bar, z, 0);
+ //int xxx = mapx(AL::sigmap.bar2tick(bar, z, 0));
+ while (xx <= xxx) {
+ ///p.drawLine(xx, y, xx, y2);
+ int x = mapx(xx);
+ p.drawLine(x, my, x, y2);
+ xx += qq;
+ //xx += rmapx(qq);
+ }
+ //xx = xxx;
+ }
+ p.setPen(Qt::gray);
+ for (int beat = 1; beat < z; beat++) {
+ ///int xx = AL::sigmap.bar2tick(bar, beat, 0);
+ xx = mapx(AL::sigmap.bar2tick(bar, beat, 0));
+ //printf(" bar:%d z:%d beat:%d xx:%d\n", bar, z, beat, xx);
+ ///p.drawLine(xx, y, xx, y2);
+ p.drawLine(xx, my, xx, y2);
+ }
+
+ }
+ //p.setWorldMatrixEnabled(true);
+ p.setWorldMatrixEnabled(wmtxen);
+ //p.restore();
+ }
+
+//---------------------------------------------------------
// map
//---------------------------------------------------------
+QRect View::mapDev(const QRect& r) const
+ {
+ return QRect(mapxDev(r.x()), mapyDev(r.y()),
+ rmapxDev(r.width()), rmapyDev(r.height()));
+ }
+
+QPoint View::mapDev(const QPoint& r) const
+ {
+ return QPoint(mapxDev(r.x()), mapyDev(r.y()));
+ }
+
+#if 0
+ //
+ // Calculations using integer rounding methods...
+ //
+
QRect View::map(const QRect& r) const
{
int x, y, w, h;
+ //printf("View::map xmag:%d xpos:%d xorg:%d\n", xmag, xpos, xorg);
if (xmag < 0) {
x = r.x()/(-xmag) - (xpos + rmapx(xorg)); // round down
w = (r.width()-xmag-1) / (-xmag); // round up
@@ -585,17 +694,6 @@ QPoint View::map(const QPoint& p) const
return QPoint(x, y);
}
-QRect View::mapDev(const QRect& r) const
- {
- return QRect(mapxDev(r.x()), mapyDev(r.y()),
- rmapxDev(r.width()), rmapyDev(r.height()));
- }
-
-QPoint View::mapDev(const QPoint& r) const
- {
- return QPoint(mapxDev(r.x()), mapyDev(r.y()));
- }
-
int View::mapx(int x) const
{
if (xmag < 0) {
@@ -664,6 +762,166 @@ int View::rmapyDev(int y) const
return (y + ymag/2) / ymag;
}
+
+#else
+ //
+ // Calculations using more accurate methods... p4.0.29 Tim.
+ //
+
+QRect View::map(const QRect& r) const
+ {
+ //int x, y, w, h;
+ double x, y, w, h;
+ int xx, yy, ww, hh;
+ //printf("View::map xmag:%d xpos:%d xorg:%d\n", xmag, xpos, xorg);
+ if (xmag < 0) {
+ //x = lrint(double(r.x())/double(-xmag) - rmapx_f(xorg)) - xpos;
+ x = double(r.x())/double(-xmag) - rmapx_f(xorg) - xpos;
+ //w = lrint(double(r.width()) / double(-xmag));
+ w = double(r.width()) / double(-xmag);
+ xx = lrint(x);
+ ww = lrint(x + w) - xx;
+ }
+ else {
+ xx = r.x()*xmag - xpos - lrint(rmapx_f(xorg));
+ ww = r.width() * xmag;
+ }
+ if (ymag < 0) {
+ //y = lrint(double(r.y())/double(-ymag) - rmapy_f(yorg)) - ypos;
+ y = double(r.y())/double(-ymag) - rmapy_f(yorg) - ypos;
+ //h = lrint(double(r.height()) / double(-ymag));
+ h = double(r.height()) / double(-ymag);
+ yy = lrint(y);
+ hh = lrint(y + h) - yy;
+ }
+ else {
+ yy = r.y()*ymag - ypos - lrint(rmapy_f(yorg));
+ hh = r.height() * ymag;
+ }
+ return QRect(xx, yy, ww, hh);
+ }
+
+QPoint View::map(const QPoint& p) const
+ {
+ /*
+ int x, y;
+ if (xmag < 0) {
+ x = lrint(double(p.x())/double(-xmag) - rmapx_f(xorg)) - xpos;
+ }
+ else {
+ x = p.x()*xmag - xpos - lrint(rmapx_f(xorg));
+ }
+ if (ymag < 0) {
+ y = lrint(double(p.y())/double(-ymag) - rmapy_f(yorg)) - ypos;
+ }
+ else {
+ y = p.y()*ymag - ypos - lrint(rmapy_f(yorg));
+ }
+ return QPoint(x, y);
+ */
+ return QPoint(mapx(p.x()), mapy(p.y()));
+ }
+
+int View::mapx(int x) const
+ {
+ if (xmag < 0) {
+ return lrint(double(x)/double(-xmag) - rmapx_f(xorg)) - xpos;
+ }
+ else {
+ return x*xmag - xpos - lrint(rmapx_f(xorg));
+ }
+ }
+int View::mapy(int y) const
+ {
+ if (ymag < 0) {
+ return lrint(double(y)/double(-ymag) - rmapy_f(yorg)) - ypos;
+ }
+ else {
+ return y*ymag - ypos - lrint(rmapy_f(yorg));
+ }
+ }
+int View::mapxDev(int x) const
+ {
+ int val;
+ if (xmag <= 0)
+ val = lrint((double(x + xpos) + rmapx_f(xorg)) * double(-xmag));
+ else
+ val = lrint((double(x + xpos) + rmapx_f(xorg)) / double(xmag));
+ if (val < 0) // DEBUG
+ val = 0;
+ return val;
+ }
+
+int View::mapyDev(int y) const
+ {
+ if (ymag <= 0)
+ return lrint((double(y + ypos) + rmapy_f(yorg)) * double(-ymag));
+ else
+ return lrint((double(y + ypos) + rmapy_f(yorg)) / double(ymag));
+ }
+
+// r == relative conversion
+int View::rmapx(int x) const
+ {
+ if (xmag < 0)
+ return lrint(double(x) / double(-xmag));
+ else
+ return x * xmag;
+ }
+int View::rmapy(int y) const
+ {
+ if (ymag < 0)
+ return lrint(double(y) / double(-ymag));
+ else
+ return y * ymag;
+ }
+int View::rmapxDev(int x) const
+ {
+ if (xmag <= 0)
+ return x * (-xmag);
+ else
+ return lrint(double(x) / double(xmag));
+ }
+int View::rmapyDev(int y) const
+ {
+ if (ymag <= 0)
+ return y * (-ymag);
+ else
+ return lrint(double(y) / double(ymag));
+ }
+#endif
+
+double View::rmapx_f(double x) const
+ {
+ if (xmag < 0)
+ return x / double(-xmag);
+ else
+ return x * double(xmag);
+ }
+double View::rmapy_f(double y) const
+ {
+ if (ymag < 0)
+ return y / double(-ymag);
+ else
+ return y * double(ymag);
+ }
+double View::rmapxDev_f(double x) const
+ {
+ if (xmag <= 0)
+ return x * double(-xmag);
+ else
+ return x / double(xmag);
+ }
+double View::rmapyDev_f(double y) const
+ {
+ if (ymag <= 0)
+ return y * double(-ymag);
+ else
+ return y / double(ymag);
+ }
+
+
+
/*
QRect View::devToVirt(const QRect& r)
{
diff --git a/muse2/muse/widgets/view.h b/muse2/muse/widgets/view.h
index f53c4c72..a932f173 100644
--- a/muse2/muse/widgets/view.h
+++ b/muse2/muse/widgets/view.h
@@ -3,6 +3,7 @@
// Linux Music Editor
// $Id: view.h,v 1.2.2.1 2008/01/26 07:23:21 terminator356 Exp $
// (C) Copyright 1999 Werner Schweer (ws@seh.de)
+// Additions, modifications (C) Copyright 2011 Tim E. Real (terminator356 on users DOT sourceforge DOT net)
//=========================================================
#ifndef __VIEW_H__
@@ -49,6 +50,7 @@ class View : public QWidget {
virtual void draw(QPainter&, const QRect&) {}
virtual void drawOverlay(QPainter&) {}
virtual QRect overlayRect() const { return QRect(0, 0, 0, 0); }
+ virtual void drawTickRaster(QPainter& p, int x, int y, int w, int h, int raster);
virtual void pdraw(QPainter&, const QRect&);
@@ -77,6 +79,10 @@ class View : public QWidget {
int rmapy(int y) const;
int rmapyDev(int y) const;
//QRect devToVirt(const QRect&);
+ double rmapx_f(double x) const;
+ double rmapy_f(double y) const;
+ double rmapxDev_f(double x) const;
+ double rmapyDev_f(double y) const;
void setPainter(QPainter& p);