From 0cab73d2dc68d68d0027763543772d43bcd31958 Mon Sep 17 00:00:00 2001 From: "Tim E. Real" Date: Wed, 28 Sep 2011 08:00:58 +0000 Subject: Optimization: Orcan's meters are insanely lightning-fast now. --- muse2/ChangeLog | 4 + muse2/muse/widgets/meter.cpp | 583 +++++++++++++++++-------------------------- muse2/muse/widgets/meter.h | 7 +- muse2/muse/widgets/utils.cpp | 5 - 4 files changed, 237 insertions(+), 362 deletions(-) diff --git a/muse2/ChangeLog b/muse2/ChangeLog index f8032198..949366e9 100644 --- a/muse2/ChangeLog +++ b/muse2/ChangeLog @@ -1,3 +1,7 @@ +28.09.2011: + - Optimization: Orcan's meters are insanely lightning-fast now. (Tim) + TODO: Fix very slight oversize at bottom upon first showing of mixer. Workaround: Simply resize vertically. + TODO: Redo the VerticalMeter (actually Horz) drawing, else should be easy Horz integration into existing Meter class. 21.09.2011: - Drawing speed boosts in part canvas. TODO Fix slight dashed border shifting. Do 'hidden' polygons (Tim) - Working on meter speed. WIP. Can enable by commenting out #define _USE_NEW_METERS in meter.cpp (Tim) diff --git a/muse2/muse/widgets/meter.cpp b/muse2/muse/widgets/meter.cpp index 50d265b5..789089fe 100644 --- a/muse2/muse/widgets/meter.cpp +++ b/muse2/muse/widgets/meter.cpp @@ -35,8 +35,8 @@ #include "gconfig.h" #include "fastlog.h" -// Uncomment to use the new meters. Warning: They are currently very time-consuming and unoptimized. -#define _USE_NEW_METERS 1 +// Just an experiment. Some undesirable effects, see below... +//#define _USE_CLIPPER 1 namespace MusEWidget { @@ -50,18 +50,17 @@ Meter::Meter(QWidget* parent, MeterType type) setBackgroundRole(QPalette::NoRole); setAttribute(Qt::WA_NoSystemBackground); setAttribute(Qt::WA_StaticContents); - // This is absolutely required for speed! Otherwise painfully slow because we get - // full rect paint events even on small scrolls! See help on QPainter::scroll(). - // Commented out for now. Orcan 20110911 - #ifndef _USE_NEW_METERS + // This is absolutely required for speed! Otherwise painfully slow because of full background + // filling, even when requesting small udpdates! Background is drawn by us. (Just small corners.) setAttribute(Qt::WA_OpaquePaintEvent); - #endif //setFrameStyle(QFrame::Raised | QFrame::StyledPanel); mtype = type; overflow = false; cur_yv = -1; // Flag as -1 to initialize in paint. last_yv = 0; + cur_ymax = 0; + last_ymax = 0; val = 0.0; maxVal = 0.0; minScale = mtype == DBMeter ? MusEConfig::config.minMeter : 0.0; // min value in dB or int @@ -154,46 +153,51 @@ void Meter::setVal(double v, double max, bool ovl) } } + double range = maxScale - minScale; + int fw = frameWidth(); + int w = width() - 2*fw; + int h = height() - 2*fw; + QRect udRect; + bool udPeak = false; + if(maxVal != max) { maxVal = max; + if(mtype == DBMeter) + cur_ymax = maxVal == 0 ? fw : int(((maxScale - (fast_log10(maxVal) * 20.0)) * h)/range); + else + cur_ymax = maxVal == 0 ? fw : int(((maxScale - maxVal) * h)/range); + if(cur_ymax > h) cur_ymax = h; + // Not using regions. Just lump them together. + udRect = QRect(fw, last_ymax, w, 1) | QRect(fw, cur_ymax, w, 1); + //printf("Meter::setVal peak cur_ymax:%d last_ymax:%d\n", cur_ymax, last_ymax); + last_ymax = cur_ymax; ud = true; + udPeak = true; } if(ud) { - #ifdef _USE_NEW_METERS - update(); - - #else - double range = maxScale - minScale; - int fw = frameWidth(); - int w = width() - 2*fw; - int h = height() - 2*fw; - if(mtype == DBMeter) cur_yv = val == 0 ? h : int(((maxScale - (fast_log10(val) * 20.0)) * h)/range); else cur_yv = val == 0 ? h : int(((maxScale - val) * h)/range); - if(cur_yv > h) cur_yv = h; - + + //printf("Meter::setVal cur_yv:%d last_yv:%d\n", cur_yv, last_yv); int y1, y2; - if(last_yv < cur_yv) - { - y1 = last_yv; - y2 = cur_yv; - } - else - { - y1 = cur_yv; - y2 = last_yv; - } + if(last_yv < cur_yv) { y1 = last_yv; y2 = cur_yv; } else { y1 = cur_yv; y2 = last_yv; } last_yv = cur_yv; - update(fw, y1, w, y2); - #endif + + if(udPeak) + update(udRect | QRect(fw, y1, w, y2 - y1 + 1)); + //repaint(udRect | QRect(fw, y1, w, y2 - y1 + 1)); + else + update(QRect(fw, y1, w, y2 - y1 + 1)); + //repaint(QRect(fw, y1, w, y2 - y1 + 1)); } } + //--------------------------------------------------------- // resetPeaks // reset peak and overflow indicator @@ -203,6 +207,7 @@ void Meter::resetPeaks() { maxVal = val; overflow = val > 0.0; + cur_yv = -1; // Force re-initialization. update(); } @@ -224,69 +229,91 @@ void Meter::setRange(double min, double max) void Meter::paintEvent(QPaintEvent* ev) { - // TODO: Could make better use of event rectangle, for speed. - QPainter p(this); - #ifdef _USE_NEW_METERS p.setRenderHint(QPainter::Antialiasing); - #endif - + double range = maxScale - minScale; - int fw = frameWidth(); int w = width() - 2*fw; int h = height() - 2*fw; - const QRect& rect = ev->rect(); //printf("Meter::paintEvent rx:%d ry:%d rw:%d rh:%d w:%d h:%d\n", rect.x(), rect.y(), rect.width(), rect.height(), w, h); - //p.setClipRect(rect); // Nope, didn't help (I think it's already clipped. So check why we bother to do it in View). + + QPainterPath drawingPath, updatePath, finalPath, cornerPath; + //bool updFull = false; // Initialize. Can't do in ctor, must be done after layouts have been done. Most reliable to do it here. - #ifndef _USE_NEW_METERS if(cur_yv == -1) - #endif { if(mtype == DBMeter) + { cur_yv = val == 0 ? h : int(((maxScale - (fast_log10(val) * 20.0)) * h)/range); + cur_ymax = maxVal == 0 ? fw : int(((maxScale - (fast_log10(maxVal) * 20.0)) * h)/range); + } else + { cur_yv = val == 0 ? h : int(((maxScale - val) * h)/range); + cur_ymax = maxVal == 0 ? fw : int(((maxScale - maxVal) * h)/range); + } if(cur_yv > h) cur_yv = h; - //last_yv = cur_yv; + last_yv = cur_yv; + if(cur_ymax > h) cur_ymax = h; + last_ymax = cur_ymax; + //updFull = true; + updatePath.addRect(fw, fw, w, h); // Update the whole thing } + else + updatePath.addRect(rect.x(), rect.y(), rect.width(), rect.height()); // Update only the requested rectangle + + drawingPath.addRoundedRect(fw, fw, w, h, xrad, yrad); // The actual desired shape of the meter + finalPath = drawingPath & updatePath; + + // Draw corners as normal background colour. + cornerPath = updatePath - finalPath; // Elegantly simple. Path subtraction! Wee... + if(!cornerPath.isEmpty()) + p.fillPath(cornerPath, palette().window()); + +#ifdef _USE_CLIPPER + p.setClipPath(finalPath); // Meh, nice but not so good. Clips at edge so antialising has no effect! Can it be done ? +#endif // Draw the red, green, and yellow sections. - drawVU(p, rect, cur_yv); + drawVU(p, rect, finalPath, cur_yv); // Draw the peak white line. - int ymax; - if(mtype == DBMeter) - ymax = maxVal == 0 ? 0 : int(((maxScale - (fast_log10(maxVal) * 20.0)) * h)/range); - else - ymax = maxVal == 0 ? 0 : int(((maxScale - maxVal) * h)/range); - if(ymax >= rect.y() && ymax < rect.height()) + //if(updFull || (cur_ymax >= rect.y() && cur_ymax < rect.height())) { - p.setPen(peak_color); - p.drawLine(0, ymax, w, ymax); + p.setRenderHint(QPainter::Antialiasing, false); // No antialiasing. Makes the line fuzzy, double height, or not visible at all. + + //p.setPen(peak_color); + //p.drawLine(fw, cur_ymax, w, cur_ymax); // Undesirable. Draws outside the top rounded corners. + // + //QPainterPath path; path.moveTo(fw, cur_ymax); path.lineTo(w, cur_ymax); // ? Didn't work. No line at all. + //p.drawPath(path & finalPath); + QPainterPath path; path.addRect(fw, cur_ymax, w, 1); path &= finalPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(peak_color)); } - #ifdef _USE_NEW_METERS // Draw the transparent layer on top of everything to give a 3d look - QPainterPath round_path = MusEUtil::roundedPath(0, 0, w, h, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::UpperLeft | MusEUtil::UpperRight | MusEUtil::LowerLeft | MusEUtil::LowerRight ) ); - maskGrad.setStart(QPointF(0, 0)); - maskGrad.setFinalStop(QPointF(w, 0)); - p.fillPath(round_path, QBrush(maskGrad)); - #endif + p.setRenderHint(QPainter::Antialiasing); + maskGrad.setStart(QPointF(fw, fw)); + maskGrad.setFinalStop(QPointF(w, fw)); +#ifdef _USE_CLIPPER + p.fillRect(rect, QBrush(maskGrad)); +#else + //QPainterPath path; path.addRect(fw, fw, w); + //p.fillPath(finalPath & path, QBrush(maskGrad)); + p.fillPath(finalPath, QBrush(maskGrad)); +#endif } - //--------------------------------------------------------- // drawVU //--------------------------------------------------------- -void Meter::drawVU(QPainter& p, const QRect& rect, int yv) +void Meter::drawVU(QPainter& p, const QRect& rect, const QPainterPath& drawPath, int yv) { int fw = frameWidth(); int w = width() - 2*fw; @@ -295,362 +322,210 @@ void Meter::drawVU(QPainter& p, const QRect& rect, int yv) // Test OK. We are passed small rectangles on small value changes. //printf("Meter::drawVU rx:%d ry:%d rw:%d rh:%d w:%d h:%d\n", rect.x(), rect.y(), rect.width(), rect.height(), w, h); - #ifdef _USE_NEW_METERS - - if(mtype == DBMeter) - { - double range = maxScale - minScale; - int y1 = int((maxScale - redScale) * h / range); - int y2 = int((maxScale - yellowScale) * h / range); - - darkGradGreen.setStart(QPointF(0, y2)); - darkGradGreen.setFinalStop(QPointF(0, h)); - darkGradYellow.setStart(QPointF(0, y1)); - darkGradYellow.setFinalStop(QPointF(0, y2)); - darkGradRed.setStart(QPointF(0, 0)); - darkGradRed.setFinalStop(QPointF(0, y1)); - - lightGradGreen.setStart(QPointF(0, y2)); - lightGradGreen.setFinalStop(QPointF(0, h)); - lightGradYellow.setStart(QPointF(0, y1)); - lightGradYellow.setFinalStop(QPointF(0, y2)); - lightGradRed.setStart(QPointF(0, 0)); - lightGradRed.setFinalStop(QPointF(0, y1)); - - QPainterPath p_top = MusEUtil::roundedPath(0, 0, w, y1, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::UpperLeft | MusEUtil::UpperRight ) ); - - QPainterPath p_bottom = MusEUtil::roundedPath(0, y2, w, h-y2, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::LowerLeft | MusEUtil::LowerRight ) ); - - if(yv < y1) - { - - QPainterPath p_dark_red = MusEUtil::roundedPath(0, 0, w, yv, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::UpperLeft | MusEUtil::UpperRight ) ); - - p_top = p_top.subtracted(p_dark_red); - - // Red section: - p.fillPath(p_dark_red, QBrush(darkGradRed)); // dark red - p.fillPath(p_top, QBrush(lightGradRed)); // light red - - // Yellow section: - p.fillRect(0, y1, w, y2-y1, QBrush(lightGradYellow)); // light yellow - - // Green section: - p.fillPath(p_bottom, QBrush(lightGradGreen)); // light green - } - else - if(yv < y2) - { - // Red section: - p.fillPath(p_top, QBrush(darkGradRed)); // dark red - - // Yellow section: - p.fillRect(0, y1, w, yv-y1, QBrush(darkGradYellow)); // dark yellow - p.fillRect(0, yv, w, y2-yv, QBrush(lightGradYellow)); // light yellow - - // Green section: - p.fillPath(p_bottom, QBrush(lightGradGreen)); // light green - } - else - //if(yv <= y3) - { - QPainterPath p_light_green = MusEUtil::roundedPath(0, yv, w, h-yv, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::LowerLeft | MusEUtil::LowerRight ) ); - p_bottom = p_bottom.subtracted(p_light_green); - - // Red section: - p.fillPath(p_top, QBrush(darkGradRed)); // dark red - - // Yellow section: - p.fillRect(0, y1, w, y2-y1, QBrush(darkGradYellow)); // dark yellow - - // Green section: - p.fillPath(p_bottom, QBrush(darkGradGreen)); // dark green - p.fillPath(p_light_green, QBrush(lightGradGreen)); // light green - } - - p.fillRect(0,y1, w, 1, separator_color); - p.fillRect(0,y2, w, 1, separator_color); - - } - else - { - darkGradGreen.setStart(QPointF(0, 0)); - darkGradGreen.setFinalStop(QPointF(0, h)); - - lightGradGreen.setStart(QPointF(0, 0)); - lightGradGreen.setFinalStop(QPointF(0, h)); - - // We need to draw the meter in two parts. The cutoff for upper rectangle can be - // anywhere between yrad and h-yrad. Without loss of generality we pick the lower limit. - int cut = yrad; - - QPainterPath p_top = MusEUtil::roundedPath(0, 0, w, cut, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::UpperLeft | MusEUtil::UpperRight ) ); - - QPainterPath p_bottom = MusEUtil::roundedPath(0, cut, w, h-cut, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::LowerLeft | MusEUtil::LowerRight ) ); - - if(yv < cut) - { - - QPainterPath p_dark = MusEUtil::roundedPath(0, 0, w, yv, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::UpperLeft | MusEUtil::UpperRight ) ); - - p_top = p_top.subtracted(p_dark); - - // top section: - p.fillPath(p_dark, QBrush(darkGradGreen)); // dark green - p.fillPath(p_top, QBrush(lightGradGreen)); // light green - - // bottom section: - p.fillPath(p_bottom, QBrush(lightGradGreen)); // light green - } - else - { - QPainterPath p_light = MusEUtil::roundedPath(0, yv, w, h-yv, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::LowerLeft | MusEUtil::LowerRight ) ); - p_bottom = p_bottom.subtracted(p_light); - - // top section: - p.fillPath(p_top, QBrush(darkGradGreen)); // dark green - - // bottom section: - p.fillPath(p_bottom, QBrush(darkGradGreen)); // dark green - p.fillPath(p_light, QBrush(lightGradGreen)); // light green - } - - } - - /* WIP... - // TODO: Instead of drawing the whole area, make this respect the requested drawing rectangle, for speed... - // Done. But not correct yet. And could possibly simplify the whole drawing some more... QRect pr(0, 0, w, 0); - QPainterPath rectp; - rectp.addRect(rect.x(), rect.y(), rect.width(), rect.height()); - if(mtype == DBMeter) + if(mtype == DBMeter) // Meter type is dB... { double range = maxScale - minScale; int y1 = int((maxScale - redScale) * h / range); int y2 = int((maxScale - yellowScale) * h / range); - darkGradGreen.setStart(QPointF(0, y2)); - darkGradGreen.setFinalStop(QPointF(0, h)); - darkGradYellow.setStart(QPointF(0, y1)); - darkGradYellow.setFinalStop(QPointF(0, y2)); - darkGradRed.setStart(QPointF(0, 0)); - darkGradRed.setFinalStop(QPointF(0, y1)); - - lightGradGreen.setStart(QPointF(0, y2)); - lightGradGreen.setFinalStop(QPointF(0, h)); - lightGradYellow.setStart(QPointF(0, y1)); - lightGradYellow.setFinalStop(QPointF(0, y2)); - lightGradRed.setStart(QPointF(0, 0)); - lightGradRed.setFinalStop(QPointF(0, y1)); - - QPainterPath p_top = MusEUtil::roundedPath(0, 0, w, y1, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::UpperLeft | MusEUtil::UpperRight ) ); - - QPainterPath p_bottom = MusEUtil::roundedPath(0, y2, w, h-y2, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::LowerLeft | MusEUtil::LowerRight ) ); - + darkGradGreen.setStart(QPointF(fw, y2)); + darkGradGreen.setFinalStop(QPointF(fw, h)); + darkGradYellow.setStart(QPointF(fw, y1)); + darkGradYellow.setFinalStop(QPointF(fw, y2)); + darkGradRed.setStart(QPointF(fw, fw)); + darkGradRed.setFinalStop(QPointF(fw, y1)); + + lightGradGreen.setStart(QPointF(fw, y2)); + lightGradGreen.setFinalStop(QPointF(fw, h)); + lightGradYellow.setStart(QPointF(fw, y1)); + lightGradYellow.setFinalStop(QPointF(fw, y2)); + lightGradRed.setStart(QPointF(fw, fw)); + lightGradRed.setFinalStop(QPointF(fw, y1)); + +#ifdef _USE_CLIPPER if(yv < y1) { - - QPainterPath p_dark_red = MusEUtil::roundedPath(0, 0, w, yv, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::UpperLeft | MusEUtil::UpperRight ) ); - - p_top = p_top.subtracted(p_dark_red); - // Red section: - p.fillPath(p_dark_red & rectp, QBrush(darkGradRed)); // dark red - p.fillPath(p_top & rectp, QBrush(lightGradRed)); // light red - + pr.setTop(fw); pr.setHeight(yv); + p.fillRect(pr, QBrush(darkGradRed)); // dark red + pr.setTop(yv); pr.setHeight(y1-yv); + p.fillRect(pr & rect, QBrush(lightGradRed)); // light red + // Yellow section: pr.setTop(y1); pr.setHeight(y2-y1); - p.fillRect(pr & rect, QBrush(lightGradYellow)); // light yellow - + p.fillRect(pr & rect, QBrush(lightGradYellow)); // light yellow + // Green section: - p.fillPath(p_bottom & rectp, QBrush(lightGradGreen)); // light green + pr.setTop(y2); pr.setHeight(h-y2); + p.fillRect(pr & rect, QBrush(lightGradGreen)); // light green } else if(yv < y2) { // Red section: - p.fillPath(p_top & rectp, QBrush(darkGradRed)); // dark red - + pr.setTop(fw); pr.setHeight(y1); + p.fillRect(pr & rect, QBrush(darkGradRed)); // dark red + // Yellow section: pr.setTop(y1); pr.setHeight(yv-y1); - p.fillRect(pr & rect, QBrush(darkGradYellow)); // dark yellow + p.fillRect(pr & rect, QBrush(darkGradYellow)); // dark yellow pr.setTop(yv); pr.setHeight(y2-yv); - p.fillRect(pr & rect, QBrush(lightGradYellow)); // light yellow - + p.fillRect(pr & rect, QBrush(lightGradYellow)); // light yellow + // Green section: - p.fillPath(p_bottom & rectp, QBrush(lightGradGreen)); // light green + pr.setTop(y2); pr.setHeight(h-y2); + p.fillRect(pr & rect, QBrush(lightGradGreen)); // light green } else //if(yv <= y3) { - QPainterPath p_light_green = MusEUtil::roundedPath(0, yv, w, h-yv, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::LowerLeft | MusEUtil::LowerRight ) ); - p_bottom = p_bottom.subtracted(p_light_green); - // Red section: - p.fillPath(p_top & rectp, QBrush(darkGradRed)); // dark red - + pr.setTop(fw); pr.setHeight(y1); + p.fillRect(pr & rect, QBrush(darkGradRed)); // dark red + // Yellow section: pr.setTop(y1); pr.setHeight(y2-y1); - p.fillRect(pr & rect, QBrush(darkGradYellow)); // dark yellow - + p.fillRect(pr & rect, QBrush(darkGradYellow)); // dark yellow + // Green section: - p.fillPath(p_bottom & rectp, QBrush(darkGradGreen)); // dark green - p.fillPath(p_light_green & rectp, QBrush(lightGradGreen)); // light green + pr.setTop(y2); pr.setHeight(yv-y2); + p.fillRect(pr & rect, QBrush(darkGradGreen)); // dark green + pr.setTop(yv); pr.setHeight(h-yv); + p.fillRect(pr & rect, QBrush(lightGradGreen)); // light green } - - pr.setTop(y1); pr.setHeight(1); - p.fillRect(pr & rect, separator_color); - pr.setTop(y2); //pr.setHeight(1); - p.fillRect(pr & rect, separator_color); - } - else + else // Meter type is linear... { - darkGradGreen.setStart(QPointF(0, 0)); - darkGradGreen.setFinalStop(QPointF(0, h)); - - lightGradGreen.setStart(QPointF(0, 0)); - lightGradGreen.setFinalStop(QPointF(0, h)); - - // We need to draw the meter in two parts. The cutoff for upper rectangle can be - // anywhere between yrad and h-yrad. Without loss of generality we pick the lower limit. - int cut = yrad; - - QPainterPath p_top = MusEUtil::roundedPath(0, 0, w, cut, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::UpperLeft | MusEUtil::UpperRight ) ); - - QPainterPath p_bottom = MusEUtil::roundedPath(0, cut, w, h-cut, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::LowerLeft | MusEUtil::LowerRight ) ); - - if(yv < cut) - { - - QPainterPath p_dark = MusEUtil::roundedPath(0, 0, w, yv, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::UpperLeft | MusEUtil::UpperRight ) ); - - p_top = p_top.subtracted(p_dark); - - // top section: - p.fillPath(p_dark & rectp, QBrush(darkGradGreen)); // dark green - p.fillPath(p_top & rectp, QBrush(lightGradGreen)); // light green - - // bottom section: - p.fillPath(p_bottom & rectp, QBrush(lightGradGreen)); // light green - } - else - { - QPainterPath p_light = MusEUtil::roundedPath(0, yv, w, h-yv, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::LowerLeft | MusEUtil::LowerRight ) ); - p_bottom = p_bottom.subtracted(p_light); - - // top section: - p.fillPath(p_top & rectp, QBrush(darkGradGreen)); // dark green + pr.setTop(fw); pr.setHeight(yv); + p.fillRect(pr & rect, QBrush(darkGradGreen)); // dark green + pr.setTop(yv); pr.setHeight(h-yv); + p.fillRect(pr & rect, QBrush(lightGradGreen)); // light green + } - // bottom section: - p.fillPath(p_bottom & rectp, QBrush(darkGradGreen)); // dark green - p.fillPath(p_light & rectp, QBrush(lightGradGreen)); // light green - } +#else // NOT _USE_CLIPPER - } - */ - - #else - - QRect pr(0, 0, w, 0); - if(mtype == DBMeter) - { - double range = maxScale - minScale; - int y1 = int((maxScale - redScale) * h / range); - int y2 = int((maxScale - yellowScale) * h / range); - if(yv < y1) { // Red section: - pr.setTop(0); pr.setHeight(yv); - p.fillRect(pr & rect, QBrush(0x8e0000)); // dark red - pr.setTop(yv); pr.setHeight(y1-yv); - p.fillRect(pr & rect, QBrush(0xff0000)); // light red + { + QPainterPath path; path.addRect(fw, fw, w, yv); path &= drawPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(darkGradRed)); // dark red + } + { + QPainterPath path; path.addRect(fw, yv, w, y1-yv); path &= drawPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(lightGradRed)); // light red + } // Yellow section: - pr.setTop(y1); pr.setHeight(y2-y1); - p.fillRect(pr & rect, QBrush(0xffff00)); // light yellow + { + QPainterPath path; path.addRect(fw, y1, w, y2-y1); path &= drawPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(lightGradYellow)); // light yellow + } // Green section: - pr.setTop(y2); pr.setHeight(h-y2); - p.fillRect(pr & rect, QBrush(0x00ff00)); // light green + { + QPainterPath path; path.addRect(fw, y2, w, h-y2); path &= drawPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(lightGradGreen)); // light green + } } else if(yv < y2) { // Red section: - pr.setTop(0); pr.setHeight(y1); - p.fillRect(pr & rect, QBrush(0x8e0000)); // dark red + { + QPainterPath path; path.addRect(fw, fw, w, y1); path &= drawPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(darkGradRed)); // dark red + } // Yellow section: - pr.setTop(y1); pr.setHeight(yv-y1); - p.fillRect(pr & rect, QBrush(0x8e8e00)); // dark yellow - pr.setTop(yv); pr.setHeight(y2-yv); - p.fillRect(pr & rect, QBrush(0xffff00)); // light yellow + { + QPainterPath path; path.addRect(fw, y1, w, yv-y1); path &= drawPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(darkGradYellow)); // dark yellow + } + { + QPainterPath path; path.addRect(fw, yv, w, y2-yv); path &= drawPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(lightGradYellow)); // light yellow + } // Green section: - pr.setTop(y2); pr.setHeight(h-y2); - p.fillRect(pr & rect, QBrush(0x00ff00)); // light green + { + QPainterPath path; path.addRect(fw, y2, w, h-y2); path &= drawPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(lightGradGreen)); // light green + } } else //if(yv <= y3) { // Red section: - pr.setTop(0); pr.setHeight(y1); - p.fillRect(pr & rect, QBrush(0x8e0000)); // dark red + { + QPainterPath path; path.addRect(fw, fw, w, y1); path &= drawPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(darkGradRed)); // dark red + } // Yellow section: - pr.setTop(y1); pr.setHeight(y2-y1); - p.fillRect(pr & rect, QBrush(0x8e8e00)); // dark yellow + { + QPainterPath path; path.addRect(fw, y1, w, y2-y1); path &= drawPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(darkGradYellow)); // dark yellow + } // Green section: - pr.setTop(y2); pr.setHeight(yv-y2); - p.fillRect(pr & rect, QBrush(0x007000)); // dark green - pr.setTop(yv); pr.setHeight(h-yv); - p.fillRect(pr & rect, QBrush(0x00ff00)); // light green + { + QPainterPath path; path.addRect(fw, y2, w, yv-y2); path &= drawPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(darkGradGreen)); // dark green + } + { + QPainterPath path; path.addRect(fw, yv, w, h-yv); path &= drawPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(lightGradGreen)); // light green + } } + + // Separators: + { + QRect r(0, y1, w, 1); r &= rect; + if(!r.isNull()) + p.fillRect(r, separator_color); + } + { + QRect r(0, y2, w, 1); r &= rect; + if(!r.isNull()) + p.fillRect(r, separator_color); + } } - else + else // Meter type is linear... { - pr.setTop(0); pr.setHeight(yv); - p.fillRect(pr & rect, QBrush(0x007000)); // dark green - pr.setTop(yv); pr.setHeight(h-yv); - p.fillRect(pr & rect, QBrush(0x00ff00)); // light green - } - - #endif + darkGradGreen.setStart(QPointF(fw, fw)); + darkGradGreen.setFinalStop(QPointF(fw, h)); + + lightGradGreen.setStart(QPointF(fw, fw)); + lightGradGreen.setFinalStop(QPointF(fw, h)); + + { + QPainterPath path; path.addRect(fw, fw, w, yv); path &= drawPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(darkGradGreen)); // dark green + } + { + QPainterPath path; path.addRect(fw, yv, w, h-yv); path &= drawPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(lightGradGreen)); // light green + } + } + +#endif // NOT _USE_CLIPPER + } //--------------------------------------------------------- diff --git a/muse2/muse/widgets/meter.h b/muse2/muse/widgets/meter.h index ba816319..7b5369b6 100644 --- a/muse2/muse/widgets/meter.h +++ b/muse2/muse/widgets/meter.h @@ -32,6 +32,7 @@ class QResizeEvent; class QMouseEvent; class QPainter; +class QPainterPath; namespace MusEWidget { @@ -74,7 +75,7 @@ class Meter : public QFrame { QColor separator_color;; QColor peak_color; int xrad, yrad; - + private: MeterType mtype; bool overflow; @@ -82,9 +83,9 @@ class Meter : public QFrame { double maxVal; double minScale, maxScale; int yellowScale, redScale; - int cur_yv, last_yv; + int cur_yv, last_yv, cur_ymax, last_ymax; - void drawVU(QPainter& p, const QRect&, int); + void drawVU(QPainter& p, const QRect&, const QPainterPath&, int); void paintEvent(QPaintEvent*); void resizeEvent(QResizeEvent*); diff --git a/muse2/muse/widgets/utils.cpp b/muse2/muse/widgets/utils.cpp index c900f3b6..41c5a180 100644 --- a/muse2/muse/widgets/utils.cpp +++ b/muse2/muse/widgets/utils.cpp @@ -167,7 +167,6 @@ QString bitmap2String(int bm) //--------------------------------------------------------- // u32bitmap2String //--------------------------------------------------------- -// Added by Tim. p3.3.8 QString u32bitmap2String(unsigned int bm) { @@ -274,7 +273,6 @@ int string2bitmap(const QString& str) //--------------------------------------------------------- // string2u32bitmap //--------------------------------------------------------- -// Added by Tim. p3.3.8 unsigned int string2u32bitmap(const QString& str) { @@ -343,7 +341,6 @@ unsigned int string2u32bitmap(const QString& str) // ignoreWidth: Set if dealing with a vertically constrained widget - one which is free to resize horizontally. // ignoreHeight: Set if dealing with a horizontally constrained widget - one which is free to resize vertically. //--------------------------------------------------------- -// Added by Tim. p3.3.8 bool autoAdjustFontSize(QFrame* w, const QString& s, bool ignoreWidth, bool ignoreHeight, int max, int min) { @@ -373,12 +370,10 @@ bool autoAdjustFontSize(QFrame* w, const QString& s, bool ignoreWidth, bool igno if((ignoreWidth || (r.width() <= (cr.width() - extra))) && (ignoreHeight || (r.height() <= cr.height()))) break; } - // Added by Tim. p3.3.9 //printf("autoAdjustFontSize: ptsz:%d widget:%s before setFont x:%d y:%d w:%d h:%d\n", fnt.pointSize(), w->name(), w->x(), w->y(), w->width(), w->height()); // Here we will always have a font ranging from min to max point size. w->setFont(fnt); - // Added by Tim. p3.3.9 //printf("autoAdjustFontSize: ptsz:%d widget:%s x:%d y:%d w:%d h:%d frame w:%d rw:%d rh:%d\n", fnt.pointSize(), w->name(), w->x(), w->y(), w->width(), w->height(), w->frameWidth(), cr.width(), cr.height()); // Force minimum height. Use the expected height for the highest given point size. -- cgit v1.2.3 From 7616dd54d964e86393cdfa6cc3e5c2df811a0437 Mon Sep 17 00:00:00 2001 From: "Tim E. Real" Date: Fri, 30 Sep 2011 22:59:30 +0000 Subject: Fixed long-standing problem with themes (Ora/Bespin etc) and button icons. Fixed midi strip blank automation box at bottom, too high. Repaired some non-virtual paintEvent(), resizeEvent(), event() etc. --- muse2/ChangeLog | 6 ++ muse2/muse/appearance.cpp | 2 +- muse2/muse/arranger/tlist.cpp | 11 ++- muse2/muse/arranger/tlist.h | 2 +- muse2/muse/arranger/trackautomationview.h | 2 +- muse2/muse/icons.cpp | 24 +++--- muse2/muse/icons.h | 4 +- muse2/muse/mixer/astrip.cpp | 134 +++++++++++++++--------------- muse2/muse/mixer/astrip.h | 1 + muse2/muse/mixer/mstrip.cpp | 86 ++++++++----------- muse2/muse/mixer/mstrip.h | 1 + muse2/muse/mixer/strip.cpp | 43 ++++++++-- muse2/muse/mixer/strip.h | 3 +- muse2/muse/widgets/bigtime.cpp | 1 + muse2/muse/widgets/knob.cpp | 3 +- muse2/muse/widgets/knob.h | 4 +- muse2/muse/widgets/meter.cpp | 3 +- muse2/muse/widgets/meter.h | 8 +- muse2/muse/widgets/mtrackinfo.cpp | 70 +++++++++++++--- muse2/muse/widgets/mtrackinfo.h | 6 +- muse2/muse/widgets/posedit.cpp | 13 +-- muse2/muse/widgets/posedit.h | 4 +- muse2/muse/widgets/scrollscale.cpp | 5 +- muse2/muse/widgets/sigedit.cpp | 15 ++-- muse2/muse/widgets/sigedit.h | 4 +- muse2/muse/widgets/slider.cpp | 2 +- muse2/muse/widgets/slider.h | 4 +- muse2/muse/widgets/swidget.cpp | 3 +- muse2/muse/widgets/verticalmeter.cpp | 3 +- muse2/muse/widgets/verticalmeter.h | 4 +- muse2/muse/widgets/view.cpp | 3 +- muse2/synti/deicsonze/deicsonzegui.h | 8 +- 32 files changed, 281 insertions(+), 201 deletions(-) diff --git a/muse2/ChangeLog b/muse2/ChangeLog index 949366e9..e7ddcec9 100644 --- a/muse2/ChangeLog +++ b/muse2/ChangeLog @@ -1,3 +1,9 @@ +30.09.2011: + - Fixed long-standing problem with themes (Ia Ora / Bespin etc) and MusE button icons. Some themes don't support + multiple-pixmap icons. So mute/solo/rec/stereo/thru always showed the same icon. Replaced w single pm icons. (Tim) + - Fixed midi strip blank automation box at bottom, too high. (Tim) + - Gradient for strip labels. (Hm, too pastel? Had to go top-high. Maybe change colours again Orcan, he he...) (Tim) + - Repaired some non-virtual paintEvent(), resizeEvent(), event() etc. (Tim) 28.09.2011: - Optimization: Orcan's meters are insanely lightning-fast now. (Tim) TODO: Fix very slight oversize at bottom upon first showing of mixer. Workaround: Simply resize vertically. diff --git a/muse2/muse/appearance.cpp b/muse2/muse/appearance.cpp index b49b951b..b3e89aa1 100644 --- a/muse2/muse/appearance.cpp +++ b/muse2/muse/appearance.cpp @@ -58,7 +58,7 @@ class BgPreviewWidget : public QWidget { int text_w; protected: - void paintEvent(QPaintEvent* event) + virtual void paintEvent(QPaintEvent* event) { QPainter p(this); int w = t_widget->width() - 65; diff --git a/muse2/muse/arranger/tlist.cpp b/muse2/muse/arranger/tlist.cpp index c28a40b2..68f6dceb 100644 --- a/muse2/muse/arranger/tlist.cpp +++ b/muse2/muse/arranger/tlist.cpp @@ -265,8 +265,11 @@ void TList::paint(const QRect& r) switch (section) { case COL_RECORD: if (track->canRecord() && !header->isSectionHidden(COL_RECORD)) { + //bool aa = p.testRenderHint(QPainter::SmoothPixmapTransform); // Antialiasing); // The rec icon currently looks very jagged. AA should help. + //p.setRenderHint(QPainter::SmoothPixmapTransform); //Antialiasing); drawCenteredPixmap(p, track->recordFlag() ? record_on_Icon : record_off_Icon, r); + //p.setRenderHint(QPainter::SmoothPixmapTransform, aa); //Antialiasing, aa); } break; case COL_CLASS: @@ -1689,10 +1692,10 @@ void TList::setYPos(int y) // resizeEvent //--------------------------------------------------------- -void TList::resizeEvent(QResizeEvent* /*ev*/) - { - - } +//void TList::resizeEvent(QResizeEvent* /*ev*/) +// { +// +// } //--------------------------------------------------------- // classesPopupMenu diff --git a/muse2/muse/arranger/tlist.h b/muse2/muse/arranger/tlist.h index 01b13eb3..db19ef6b 100644 --- a/muse2/muse/arranger/tlist.h +++ b/muse2/muse/arranger/tlist.h @@ -103,7 +103,7 @@ class TList : public QWidget { void moveSelection(int n); void adjustScrollbar(); void paint(const QRect& r); - virtual void resizeEvent(QResizeEvent*); + //virtual void resizeEvent(QResizeEvent*); void redraw(const QRect& r); Track* y2Track(int) const; void classesPopupMenu(Track*, int x, int y); diff --git a/muse2/muse/arranger/trackautomationview.h b/muse2/muse/arranger/trackautomationview.h index f169e968..8c7aed84 100644 --- a/muse2/muse/arranger/trackautomationview.h +++ b/muse2/muse/arranger/trackautomationview.h @@ -33,7 +33,7 @@ namespace MusEArranger { class TrackAutomationView : public QWidget { Track *_t; - void paintEvent(QPaintEvent *e); + virtual void paintEvent(QPaintEvent *e); std::map automationList; public: TrackAutomationView(QWidget *parent, Track *t); diff --git a/muse2/muse/icons.cpp b/muse2/muse/icons.cpp index 423e65fa..89a3a48e 100644 --- a/muse2/muse/icons.cpp +++ b/muse2/muse/icons.cpp @@ -367,8 +367,8 @@ QPixmap* soloIconOn; QPixmap* soloIconOff; QPixmap* soloblksqIconOn; QPixmap* soloblksqIconOff; -QIcon* soloIconSet1; -QIcon* soloIconSet2; +//QIcon* soloIconSet1; +//QIcon* soloIconSet2; QPixmap* editmuteIcon; QPixmap* editmuteSIcon; @@ -582,8 +582,12 @@ void initIcons() editpaste2TrackIcon = new MICON(editpaste2track_xpm, NULL); editpasteClone2TrackIcon = new MICON(editpasteclone2track_xpm, NULL); */ - exitIcon = new MPIXMAP(exit_xpm, "application-exit"); - exit1Icon = new MPIXMAP(exit1_xpm, "application-exit"); + + //exitIcon = new MPIXMAP(exit_xpm, "application-exit"); + //exit1Icon = new MPIXMAP(exit1_xpm, "application-exit"); + // Changed by Tim. There are IMO no suitable theme substitutes for these two so far... + exitIcon = new MPIXMAP(exit_xpm, NULL); + exit1Icon = new MPIXMAP(exit1_xpm, NULL); // 2 lines odd code newmuteIcon = new MPIXMAP(newmutebutton_xpm, NULL); @@ -597,12 +601,12 @@ void initIcons() soloIconOff = new MPIXMAP(solobutton_off_xpm, NULL); soloblksqIconOn = new MPIXMAP(solobutton_on_blksq_xpm, NULL); soloblksqIconOff = new MPIXMAP(solobutton_off_blksq_xpm, NULL); - soloIconSet1 = new QIcon(); - soloIconSet2 = new QIcon(); - soloIconSet1->addPixmap(*soloIconOn, QIcon::Normal, QIcon::On); - soloIconSet1->addPixmap(*soloIconOff, QIcon::Normal, QIcon::Off); - soloIconSet2->addPixmap(*soloblksqIconOn, QIcon::Normal, QIcon::On); - soloIconSet2->addPixmap(*soloblksqIconOff, QIcon::Normal, QIcon::Off); + //soloIconSet1 = new QIcon(); + //soloIconSet2 = new QIcon(); + //soloIconSet1->addPixmap(*soloIconOn, QIcon::Normal, QIcon::On); + //soloIconSet1->addPixmap(*soloIconOff, QIcon::Normal, QIcon::Off); + //soloIconSet2->addPixmap(*soloblksqIconOn, QIcon::Normal, QIcon::On); + //soloIconSet2->addPixmap(*soloblksqIconOff, QIcon::Normal, QIcon::Off); redLedIcon = new MPIXMAP(redled_xpm, NULL); darkRedLedIcon = new MPIXMAP(darkredled_xpm, NULL); diff --git a/muse2/muse/icons.h b/muse2/muse/icons.h index 8d55b255..957f4a74 100644 --- a/muse2/muse/icons.h +++ b/muse2/muse/icons.h @@ -151,8 +151,8 @@ extern QPixmap* soloIconOn; extern QPixmap* soloIconOff; extern QPixmap* soloblksqIconOn; extern QPixmap* soloblksqIconOff; -extern QIcon* soloIconSet1; -extern QIcon* soloIconSet2; +//extern QIcon* soloIconSet1; +//extern QIcon* soloIconSet2; extern QPixmap* redLedIcon; extern QPixmap* darkRedLedIcon; diff --git a/muse2/muse/mixer/astrip.cpp b/muse2/muse/mixer/astrip.cpp index 156017e8..bf31d820 100644 --- a/muse2/muse/mixer/astrip.cpp +++ b/muse2/muse/mixer/astrip.cpp @@ -4,6 +4,7 @@ // $Id: astrip.cpp,v 1.23.2.17 2009/11/16 01:55:55 terminator356 Exp $ // // (C) Copyright 2000-2004 Werner Schweer (ws@seh.de) +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -172,28 +173,19 @@ void AudioStrip::songChanged(int val) mute->blockSignals(true); mute->setChecked(src->mute()); mute->blockSignals(false); + mute->setIcon(src->mute() ? QIcon(*muteIconOff) : QIcon(*muteIconOn)); + //mute->setIconSize(muteIconOn->size()); updateOffState(); } if (solo && (val & SC_SOLO)) { - if((bool)track->internalSolo()) - { - if(!useSoloIconSet2) - { - solo->setIcon(*soloIconSet2); - solo->setIconSize(soloIconOn->size()); - useSoloIconSet2 = true; - } - } - else if(useSoloIconSet2) - { - solo->setIcon(*soloIconSet1); - solo->setIconSize(soloblksqIconOn->size()); - useSoloIconSet2 = false; - } - solo->blockSignals(true); solo->setChecked(track->solo()); solo->blockSignals(false); + if(track->internalSolo()) + solo->setIcon(track->solo() ? QIcon(*soloblksqIconOn) : QIcon(*soloblksqIconOff)); + else + solo->setIcon(track->solo() ? QIcon(*soloIconOn) : QIcon(*soloIconOff)); + //solo->setIconSize(soloIconOn->size()); } if (val & SC_RECFLAG) setRecordFlag(track->recordFlag()); @@ -232,19 +224,31 @@ void AudioStrip::songChanged(int val) if(track->automationType() == AUTO_TOUCH || track->automationType() == AUTO_WRITE) { palette.setColor(QPalette::Button, QColor(215, 76, 39)); // red - //QColor c(Qt::red); - //gradient.setColorAt(0, c); - //gradient.setColorAt(1, c.darker()); - //palette.setBrush(QPalette::Button, gradient); + //palette.setColor(QPalette::Window, QColor(215, 76, 39)); // red + /*QLinearGradient gradient(autoType->geometry().topLeft(), autoType->geometry().bottomLeft()); + QColor c(Qt::red); + //QColor c(215, 76, 39); // red + gradient.setColorAt(0, c.darker()); + gradient.setColorAt(0.5, c); + gradient.setColorAt(1, c.darker()); + palette.setBrush(QPalette::Button, gradient); + //palette.setBrush(autoType->backgroundRole(), gradient); + //palette.setBrush(QPalette::Window, gradient); */ autoType->setPalette(palette); } else if(track->automationType() == AUTO_READ) { palette.setColor(QPalette::Button, QColor(100, 172, 49)); // green - //QColor c(Qt::green); - //gradient.setColorAt(0, c); - //gradient.setColorAt(1, c.darker()); - //palette.setBrush(QPalette::Button, gradient); + //palette.setColor(QPalette::Window, QColor(100, 172, 49)); // green + /*QLinearGradient gradient(autoType->geometry().topLeft(), autoType->geometry().bottomLeft()); + QColor c(Qt::green); + //QColor c(100, 172, 49); // green + gradient.setColorAt(0, c.darker()); + gradient.setColorAt(0.5, c); + gradient.setColorAt(1, c.darker()); + palette.setBrush(QPalette::Button, gradient); + //palette.setBrush(autoType->backgroundRole(), gradient); + //palette.setBrush(QPalette::Window, gradient); */ autoType->setPalette(palette); } else @@ -354,6 +358,8 @@ void AudioStrip::updateOffState() off->blockSignals(true); off->setChecked(track->off()); off->blockSignals(false); + off->setIcon(track->off() ? QIcon(*exit1Icon) : QIcon(*exitIcon)); + //off->setIconSize(exit1Icon->size()); } } @@ -623,6 +629,8 @@ void AudioStrip::updateChannels() stereo->blockSignals(true); stereo->setChecked(channel == 2); stereo->blockSignals(false); + stereo->setIcon(channel == 2 ? QIcon(*stereoIcon) : QIcon(*monoIcon)); + //stereo->setIconSize(stereoIcon->size()); } //--------------------------------------------------------- @@ -753,15 +761,11 @@ AudioStrip::AudioStrip(QWidget* parent, AudioTrack* at) stereo = new QToolButton(); stereo->setFont(MusEConfig::config.fonts[1]); - QIcon stereoSet; - stereoSet.addPixmap(*monoIcon, QIcon::Normal, QIcon::Off); - stereoSet.addPixmap(*stereoIcon, QIcon::Normal, QIcon::On); - stereo->setIcon(stereoSet); - stereo->setIconSize(monoIcon->size()); - stereo->setCheckable(true); stereo->setToolTip(tr("1/2 channel")); stereo->setChecked(channel == 2); + stereo->setIcon(channel == 2 ? QIcon(*stereoIcon) : QIcon(*monoIcon)); + stereo->setIconSize(monoIcon->size()); stereo->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); connect(stereo, SIGNAL(clicked(bool)), SLOT(stereoToggled(bool))); @@ -868,47 +872,33 @@ AudioStrip::AudioStrip(QWidget* parent, AudioTrack* at) record->setCheckable(true); record->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); record->setBackgroundRole(QPalette::Mid); - QIcon iconSet; - iconSet.addPixmap(*record_on_Icon, QIcon::Normal, QIcon::On); - iconSet.addPixmap(*record_off_Icon, QIcon::Normal, QIcon::Off); - record->setIcon(iconSet); - record->setIconSize(record_on_Icon->size()); record->setToolTip(tr("record")); record->setChecked(t->recordFlag()); + record->setIcon(t->recordFlag() ? QIcon(*record_on_Icon) : QIcon(*record_off_Icon)); + record->setIconSize(record_on_Icon->size()); connect(record, SIGNAL(clicked(bool)), SLOT(recordToggled(bool))); } Track::TrackType type = t->type(); mute = new QToolButton(); - QIcon muteSet; - muteSet.addPixmap(*muteIconOn, QIcon::Normal, QIcon::Off); - muteSet.addPixmap(*muteIconOff, QIcon::Normal, QIcon::On); - mute->setIcon(muteSet); - mute->setIconSize(muteIconOn->size()); mute->setCheckable(true); mute->setToolTip(tr("mute")); mute->setChecked(t->mute()); + mute->setIcon(t->mute() ? QIcon(*muteIconOff) : QIcon(*muteIconOn)); + mute->setIconSize(muteIconOn->size()); mute->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); connect(mute, SIGNAL(clicked(bool)), SLOT(muteToggled(bool))); solo = new QToolButton(); - if((bool)t->internalSolo()) - { - solo->setIcon(*soloIconSet2); - solo->setIconSize(soloIconOn->size()); - useSoloIconSet2 = true; - } - else - { - solo->setIcon(*soloIconSet1); - solo->setIconSize(soloblksqIconOn->size()); - useSoloIconSet2 = false; - } - solo->setCheckable(true); solo->setChecked(t->solo()); + if(t->internalSolo()) + solo->setIcon(t->solo() ? QIcon(*soloblksqIconOn) : QIcon(*soloblksqIconOff)); + else + solo->setIcon(t->solo() ? QIcon(*soloIconOn) : QIcon(*soloIconOff)); + solo->setIconSize(soloIconOn->size()); solo->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); connect(solo, SIGNAL(clicked(bool)), SLOT(soloToggled(bool))); if (type == Track::AUDIO_OUTPUT) { @@ -922,16 +912,13 @@ AudioStrip::AudioStrip(QWidget* parent, AudioTrack* at) } off = new MusEWidget::TransparentToolButton(this); - QIcon iconSet; - iconSet.addPixmap(*exit1Icon, QIcon::Normal, QIcon::On); - iconSet.addPixmap(*exitIcon, QIcon::Normal, QIcon::Off); - off->setIcon(iconSet); - off->setIconSize(exit1Icon->size()); off->setBackgroundRole(QPalette::Mid); off->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); off->setCheckable(true); off->setToolTip(tr("off")); off->setChecked(t->off()); + off->setIcon(t->off() ? QIcon(*exit1Icon) : QIcon(*exitIcon)); + off->setIconSize(exit1Icon->size()); connect(off, SIGNAL(clicked(bool)), SLOT(offToggled(bool))); grid->addWidget(off, _curGridRow, 0); @@ -972,6 +959,7 @@ AudioStrip::AudioStrip(QWidget* parent, AudioTrack* at) autoType = new MusEWidget::ComboBox(); autoType->setFont(MusEConfig::config.fonts[1]); autoType->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); + //autoType->setAutoFillBackground(true); autoType->addAction(tr("Off"), AUTO_OFF); autoType->addAction(tr("Read"), AUTO_READ); @@ -983,20 +971,30 @@ AudioStrip::AudioStrip(QWidget* parent, AudioTrack* at) //QLinearGradient gradient(autoType->geometry().topLeft(), autoType->geometry().bottomLeft()); if(t->automationType() == AUTO_TOUCH || t->automationType() == AUTO_WRITE) { - palette.setColor(QPalette::Button, QColor(Qt::red)); - //QColor c(Qt::red); - //gradient.setColorAt(0, c); - //gradient.setColorAt(1, c.darker()); - //palette.setBrush(QPalette::Button, gradient); + palette.setColor(QPalette::Button, QColor(215, 76, 39)); // red + /* QLinearGradient gradient(autoType->geometry().topLeft(), autoType->geometry().bottomLeft()); + QColor c(Qt::red); + //QColor c(215, 76, 39); // red + gradient.setColorAt(0, c.darker()); + gradient.setColorAt(0.5, c); + gradient.setColorAt(1, c.darker()); + palette.setBrush(QPalette::Button, gradient); + //palette.setBrush(autoType->backgroundRole(), gradient); + //palette.setBrush(QPalette::Window, gradient); */ autoType->setPalette(palette); } else if(t->automationType() == AUTO_READ) { - palette.setColor(QPalette::Button, QColor(Qt::green)); - //QColor c(Qt::green); - //gradient.setColorAt(0, c); - //gradient.setColorAt(1, c.darker()); - //palette.setBrush(QPalette::Button, gradient); + palette.setColor(QPalette::Button, QColor(100, 172, 49)); // green + /*QLinearGradient gradient(autoType->geometry().topLeft(), autoType->geometry().bottomLeft()); + QColor c(Qt::green); + //QColor c(100, 172, 49); // green + gradient.setColorAt(0, c.darker()); + gradient.setColorAt(0.5, c); + gradient.setColorAt(1, c.darker()); + palette.setBrush(QPalette::Button, gradient); + //palette.setBrush(autoType->backgroundRole(), gradient); + //palette.setBrush(QPalette::Window, gradient); */ autoType->setPalette(palette); } else diff --git a/muse2/muse/mixer/astrip.h b/muse2/muse/mixer/astrip.h index 72e88cca..3e2b6c1d 100644 --- a/muse2/muse/mixer/astrip.h +++ b/muse2/muse/mixer/astrip.h @@ -4,6 +4,7 @@ // $Id: astrip.h,v 1.8.2.6 2009/11/14 03:37:48 terminator356 Exp $ // // (C) Copyright 2000-2004 Werner Schweer (ws@seh.de) +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License diff --git a/muse2/muse/mixer/mstrip.cpp b/muse2/muse/mixer/mstrip.cpp index c6832e6b..c920d6c6 100644 --- a/muse2/muse/mixer/mstrip.cpp +++ b/muse2/muse/mixer/mstrip.cpp @@ -4,6 +4,7 @@ // $Id: mstrip.cpp,v 1.9.2.13 2009/11/14 03:37:48 terminator356 Exp $ // // (C) Copyright 2000-2004 Werner Schweer (ws@seh.de) +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -296,48 +297,32 @@ MidiStrip::MidiStrip(QWidget* parent, MidiTrack* t) record->setBackgroundRole(QPalette::Mid); record->setCheckable(true); record->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); - - QIcon iconSet; - iconSet.addPixmap(*record_on_Icon, QIcon::Normal, QIcon::On); - iconSet.addPixmap(*record_off_Icon, QIcon::Normal, QIcon::Off); - record->setIcon(iconSet); - record->setIconSize(record_on_Icon->size()); record->setToolTip(tr("record")); record->setChecked(track->recordFlag()); + record->setIcon(track->recordFlag() ? QIcon(*record_on_Icon) : QIcon(*record_off_Icon)); + record->setIconSize(record_on_Icon->size()); connect(record, SIGNAL(clicked(bool)), SLOT(recordToggled(bool))); mute = new QToolButton(); - QIcon muteSet; - muteSet.addPixmap(*muteIconOn, QIcon::Normal, QIcon::Off); - muteSet.addPixmap(*muteIconOff, QIcon::Normal, QIcon::On); - mute->setIcon(muteSet); - mute->setIconSize(muteIconOn->size()); mute->setCheckable(true); mute->setToolTip(tr("mute")); mute->setChecked(track->mute()); + mute->setIcon(track->mute() ? QIcon(*muteIconOff) : QIcon(*muteIconOn)); + mute->setIconSize(muteIconOn->size()); mute->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); connect(mute, SIGNAL(clicked(bool)), SLOT(muteToggled(bool))); solo = new QToolButton(); - - if((bool)t->internalSolo()) - { - solo->setIcon(*soloIconSet2); - solo->setIconSize(soloIconOn->size()); - useSoloIconSet2 = true; - } - else - { - solo->setIcon(*soloIconSet1); - solo->setIconSize(soloblksqIconOn->size()); - useSoloIconSet2 = false; - } - //solo->setToolTip(tr("pre fader listening")); solo->setToolTip(tr("solo mode")); solo->setCheckable(true); - solo->setChecked(t->solo()); + solo->setChecked(track->solo()); solo->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); + if(track->internalSolo()) + solo->setIcon(track->solo() ? QIcon(*soloblksqIconOn) : QIcon(*soloblksqIconOff)); + else + solo->setIcon(track->solo() ? QIcon(*soloIconOn) : QIcon(*soloIconOff)); + solo->setIconSize(soloIconOn->size()); connect(solo, SIGNAL(clicked(bool)), SLOT(soloToggled(bool))); /* @@ -363,8 +348,8 @@ MidiStrip::MidiStrip(QWidget* parent, MidiTrack* t) ///dev_ch_label->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum)); dev_ch_label->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); dev_ch_label->setAlignment(Qt::AlignCenter); - int port = t->outPort(); - int channel = t->outChannel(); + int port = track->outPort(); + int channel = track->outChannel(); QString dcs; dcs.sprintf("%d-%d", port + 1, channel + 1); dev_ch_label->setText(dcs); @@ -377,16 +362,13 @@ MidiStrip::MidiStrip(QWidget* parent, MidiTrack* t) */ off = new MusEWidget::TransparentToolButton(this); - QIcon iconOff; - iconOff.addPixmap(*exit1Icon, QIcon::Normal, QIcon::On); - iconOff.addPixmap(*exitIcon, QIcon::Normal, QIcon::Off); - off->setIcon(iconOff); - off->setIconSize(exit1Icon->size()); off->setBackgroundRole(QPalette::Mid); off->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); off->setCheckable(true); off->setToolTip(tr("off")); - off->setChecked(t->off()); + off->setChecked(track->off()); + off->setIcon(track->off() ? QIcon(*exit1Icon) : QIcon(*exitIcon)); + off->setIconSize(exit1Icon->size()); connect(off, SIGNAL(clicked(bool)), SLOT(offToggled(bool))); grid->addWidget(off, _curGridRow, 0); @@ -436,6 +418,8 @@ MidiStrip::MidiStrip(QWidget* parent, MidiTrack* t) //autoType->setCurrentItem(t->automationType()); //autoType->setToolTip(tr("automation type")); //connect(autoType, SIGNAL(activated(int)), SLOT(setAutomationType(int))); + autoType->addAction(" ", AUTO_OFF); // Just a dummy text to fix sizing problems. REMOVE later if full automation added. + autoType->setCurrentItem(AUTO_OFF); // grid->addWidget(autoType, _curGridRow++, 0, 1, 2); connect(MusEGlobal::heartBeatTimer, SIGNAL(timeout()), SLOT(heartBeat())); @@ -461,8 +445,9 @@ void MidiStrip::updateOffState() solo->setEnabled(val); if (mute) mute->setEnabled(val); - if (autoType) - autoType->setEnabled(val); + // TODO: Disabled for now. + //if (autoType) + // autoType->setEnabled(val); if (iR) iR->setEnabled(val); // TODO: Disabled for now. @@ -472,6 +457,8 @@ void MidiStrip::updateOffState() off->blockSignals(true); off->setChecked(track->off()); off->blockSignals(false); + off->setIcon(track->off() ? QIcon(*exit1Icon) : QIcon(*exitIcon)); + //off->setIconSize(exit1Icon->size()); } } @@ -483,30 +470,23 @@ void MidiStrip::songChanged(int val) { if (mute && (val & SC_MUTE)) { // mute && off mute->blockSignals(true); - mute->setChecked(track->isMute()); - updateOffState(); + //mute->setChecked(track->isMute()); + mute->setChecked(track->mute()); mute->blockSignals(false); + mute->setIcon(track->mute() ? QIcon(*muteIconOff) : QIcon(*muteIconOn)); + //mute->setIconSize(muteIconOn->size()); + updateOffState(); } if (solo && (val & SC_SOLO)) { - if((bool)track->internalSolo()) - { - if(!useSoloIconSet2) - { - solo->setIcon(*soloIconSet2); - solo->setIconSize(soloIconOn->size()); - useSoloIconSet2 = true; - } - } - else if(useSoloIconSet2) - { - solo->setIcon(*soloIconSet1); - solo->setIconSize(soloblksqIconOn->size()); - useSoloIconSet2 = false; - } solo->blockSignals(true); solo->setChecked(track->solo()); solo->blockSignals(false); + if(track->internalSolo()) + solo->setIcon(track->solo() ? QIcon(*soloblksqIconOn) : QIcon(*soloblksqIconOff)); + else + solo->setIcon(track->solo() ? QIcon(*soloIconOn) : QIcon(*soloIconOff)); + //solo->setIconSize(soloIconOn->size()); } if (val & SC_RECFLAG) diff --git a/muse2/muse/mixer/mstrip.h b/muse2/muse/mixer/mstrip.h index d8e947f9..0535eaa8 100644 --- a/muse2/muse/mixer/mstrip.h +++ b/muse2/muse/mixer/mstrip.h @@ -4,6 +4,7 @@ // $Id: mstrip.h,v 1.4.2.4 2009/10/25 19:26:29 lunar_shuttle Exp $ // // (C) Copyright 2000-2004 Werner Schweer (ws@seh.de) +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License diff --git a/muse2/muse/mixer/strip.cpp b/muse2/muse/mixer/strip.cpp index e9f92e9b..59149222 100644 --- a/muse2/muse/mixer/strip.cpp +++ b/muse2/muse/mixer/strip.cpp @@ -4,6 +4,7 @@ // $Id: strip.cpp,v 1.6.2.5 2009/11/14 03:37:48 terminator356 Exp $ // // (C) Copyright 2000-2004 Werner Schweer (ws@seh.de) +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -38,6 +39,7 @@ #include "strip.h" #include "meter.h" #include "utils.h" +#include "icons.h" namespace MusEMixer { @@ -51,6 +53,8 @@ void Strip::setRecordFlag(bool flag) record->blockSignals(true); record->setChecked(flag); record->blockSignals(false); + record->setIcon(flag ? QIcon(*record_on_Icon) : QIcon(*record_off_Icon)); + //record->setIconSize(record_on_Icon->size()); } } @@ -75,7 +79,11 @@ void Strip::recordToggled(bool val) } audio->msgSetRecord((AudioOutput*)track, val); if (!((AudioOutput*)track)->recFile()) + { record->setChecked(false); + record->setIcon(QIcon(*record_off_Icon)); + //record->setIconSize(record_on_Icon->size()); + } return; } song->setRecordFlag(track, val); @@ -148,8 +156,18 @@ void Strip::setLabelText() label->setText(track->name()); QPalette palette; - palette.setColor(label->backgroundRole(), c); + //palette.setColor(label->backgroundRole(), c); + QLinearGradient gradient(label->geometry().topLeft(), label->geometry().bottomLeft()); + //gradient.setColorAt(0, c.darker()); + //gradient.setColorAt(0, c); + //gradient.setColorAt(1, c.darker()); + gradient.setColorAt(0, c.lighter()); + gradient.setColorAt(1, c); + //palette.setBrush(QPalette::Button, gradient); + //palette.setBrush(QPalette::Window, gradient); + palette.setBrush(label->backgroundRole(), gradient); label->setPalette(palette); + //label->setStyleSheet(QString("background-color: ") + c.name()); } @@ -186,18 +204,16 @@ Strip::Strip(QWidget* parent, Track* t) iR = 0; oR = 0; - setBackgroundRole(QPalette::Mid); + ///setBackgroundRole(QPalette::Mid); setFrameStyle(Panel | Raised); setLineWidth(2); // NOTE: Workaround for freakin' improper disabled button text colour (at least with Oxygen colours). // Just set the parent palette. - QPalette pal(palette()); - pal.setColor(QPalette::Disabled, QPalette::ButtonText, - pal.color(QPalette::Disabled, QPalette::WindowText)); - setPalette(pal); - - useSoloIconSet2 = false; + //QPalette pal(palette()); + //pal.setColor(QPalette::Disabled, QPalette::ButtonText, + // pal.color(QPalette::Disabled, QPalette::WindowText)); + //setPalette(pal); track = t; meter[0] = 0; @@ -233,7 +249,7 @@ Strip::Strip(QWidget* parent, Track* t) // Therefore 'fake' set the size of the label now. // Added by Tim. p3.3.9 //label->setGeometry(label->x(), label->y(), STRIP_WIDTH - 2*frameWidth() - 2*layout->margin(), label->height()); - label->setGeometry(label->x(), label->y(), STRIP_WIDTH - 2*grid->margin(), label->height()); + ///label->setGeometry(label->x(), label->y(), STRIP_WIDTH - 2*grid->margin(), label->height()); label->setTextFormat(Qt::PlainText); @@ -279,5 +295,14 @@ void Strip::setAutomationType(int t) track->setAutomationType(AutomationType(t)); song->update(SC_AUTOMATION); } + +void Strip::resizeEvent(QResizeEvent* ev) +{ + //printf("Strip::resizeEvent\n"); + QFrame::resizeEvent(ev); + setLabelText(); + setLabelFont(); +} + } // namespace MusEMixer diff --git a/muse2/muse/mixer/strip.h b/muse2/muse/mixer/strip.h index ea4d2693..f5749177 100644 --- a/muse2/muse/mixer/strip.h +++ b/muse2/muse/mixer/strip.h @@ -4,6 +4,7 @@ // $Id: strip.h,v 1.3.2.2 2009/11/14 03:37:48 terminator356 Exp $ // // (C) Copyright 2000-2004 Werner Schweer (ws@seh.de) +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -62,7 +63,6 @@ class Strip : public QFrame { QGridLayout* grid; int _curGridRow; MusEWidget::Meter* meter[MAX_CHANNELS]; - bool useSoloIconSet2; QToolButton* record; QToolButton* solo; @@ -72,6 +72,7 @@ class Strip : public QFrame { QGridLayout* sliderGrid; MusEWidget::ComboBox* autoType; void setLabelText(); + virtual void resizeEvent(QResizeEvent*); private slots: void recordToggled(bool); diff --git a/muse2/muse/widgets/bigtime.cpp b/muse2/muse/widgets/bigtime.cpp index 572710e2..f4162041 100644 --- a/muse2/muse/widgets/bigtime.cpp +++ b/muse2/muse/widgets/bigtime.cpp @@ -334,6 +334,7 @@ void BigTime::setPos(int idx, unsigned v, bool) void BigTime::resizeEvent(QResizeEvent *ev) { + QWidget::resizeEvent(ev); dwin->resize(ev->size()); QFont f = dwin->font(); QFontMetrics fm(f); diff --git a/muse2/muse/widgets/knob.cpp b/muse2/muse/widgets/knob.cpp index 9bc63b33..ac035065 100644 --- a/muse2/muse/widgets/knob.cpp +++ b/muse2/muse/widgets/knob.cpp @@ -327,8 +327,9 @@ void Knob::rangeChange() // resizeEvent //--------------------------------------------------------- -void Knob::resizeEvent(QResizeEvent *) +void Knob::resizeEvent(QResizeEvent* ev) { + MusEWidget::SliderBase::resizeEvent(ev); int width, width_2; const QRect& r = rect(); diff --git a/muse2/muse/widgets/knob.h b/muse2/muse/widgets/knob.h index a629f158..257ff0c7 100644 --- a/muse2/muse/widgets/knob.h +++ b/muse2/muse/widgets/knob.h @@ -78,8 +78,8 @@ class Knob : public SliderBase, public ScaleIf void drawKnob(QPainter *p, const QRect &r); void drawMarker(QPainter *p, double arc, const QColor &c); - void paintEvent(QPaintEvent *); - void resizeEvent(QResizeEvent *e); + virtual void paintEvent(QPaintEvent *); + virtual void resizeEvent(QResizeEvent *e); double getValue(const QPoint &p); void getScrollMode( QPoint &p, const Qt::MouseButton &button, int &scrollMode, int &direction ); void scaleChange() { repaint(); } diff --git a/muse2/muse/widgets/meter.cpp b/muse2/muse/widgets/meter.cpp index 789089fe..590e7f65 100644 --- a/muse2/muse/widgets/meter.cpp +++ b/muse2/muse/widgets/meter.cpp @@ -532,8 +532,9 @@ void Meter::drawVU(QPainter& p, const QRect& rect, const QPainterPath& drawPath, // resizeEvent //--------------------------------------------------------- -void Meter::resizeEvent(QResizeEvent* /*ev*/) +void Meter::resizeEvent(QResizeEvent* ev) { + QFrame::resizeEvent(ev); cur_yv = -1; // Force re-initialization. } diff --git a/muse2/muse/widgets/meter.h b/muse2/muse/widgets/meter.h index 7b5369b6..1de3841f 100644 --- a/muse2/muse/widgets/meter.h +++ b/muse2/muse/widgets/meter.h @@ -75,6 +75,10 @@ class Meter : public QFrame { QColor separator_color;; QColor peak_color; int xrad, yrad; + + virtual void resizeEvent(QResizeEvent*); + virtual void paintEvent(QPaintEvent*); + virtual void mousePressEvent(QMouseEvent*); private: MeterType mtype; @@ -87,10 +91,6 @@ class Meter : public QFrame { void drawVU(QPainter& p, const QRect&, const QPainterPath&, int); - void paintEvent(QPaintEvent*); - void resizeEvent(QResizeEvent*); - void mousePressEvent(QMouseEvent*); - public slots: void resetPeaks(); void setVal(double, double, bool); diff --git a/muse2/muse/widgets/mtrackinfo.cpp b/muse2/muse/widgets/mtrackinfo.cpp index e4c4e217..56429879 100644 --- a/muse2/muse/widgets/mtrackinfo.cpp +++ b/muse2/muse/widgets/mtrackinfo.cpp @@ -2,6 +2,7 @@ // MusE // Linux Music Editor // (C) Copyright 2010 Werner Schweer and others (ws@seh.de) +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -21,6 +22,9 @@ #include #include +#include +#include +#include #include #include @@ -60,8 +64,10 @@ void MidiTrackInfo::setTrack(Track* t) if(!t->isMidiTrack()) return; selected = t; + + trackNameLabel->setObjectName(selected->cname()); - QPalette pal; + /*QPalette pal; if(selected->type() == Track::DRUM) { pal.setColor(trackNameLabel->backgroundRole(), MusEConfig::config.drumTrackLabelBg); iOutputChannel->setEnabled(false); @@ -69,7 +75,8 @@ void MidiTrackInfo::setTrack(Track* t) pal.setColor(trackNameLabel->backgroundRole(), MusEConfig::config.midiTrackLabelBg); iOutputChannel->setEnabled(true); } - trackNameLabel->setPalette(pal); + trackNameLabel->setPalette(pal); */ + //setLabelText(); updateTrackInfo(-1); } @@ -97,10 +104,7 @@ MidiTrackInfo::MidiTrackInfo(QWidget* parent, Track* sel_track) : QWidget(parent //iChanDetectLabel->setPixmap(*darkgreendotIcon); iChanDetectLabel->setPixmap(*darkRedLedIcon); - QIcon recEchoIconSet; - recEchoIconSet.addPixmap(*midiThruOnIcon, QIcon::Normal, QIcon::On); - recEchoIconSet.addPixmap(*midiThruOffIcon, QIcon::Normal, QIcon::Off); - recEchoButton->setIcon(recEchoIconSet); + recEchoButton->setIcon((selected && ((MidiTrack*)selected)->recEcho()) ? QIcon(*midiThruOnIcon) : QIcon(*midiThruOffIcon)); recEchoButton->setIconSize(midiThruOnIcon->size()); // MusE-2: AlignCenter and WordBreak are set in the ui(3) file, but not supported by QLabel. Turn them on here. @@ -114,14 +118,26 @@ MidiTrackInfo::MidiTrackInfo(QWidget* parent, Track* sel_track) : QWidget(parent if(selected) { trackNameLabel->setObjectName(selected->cname()); - QPalette pal; + + /*QPalette pal; + QColor c; //pal.setColor(trackNameLabel->backgroundRole(), QColor(0, 160, 255)); // Med blue if(selected->type() == Track::DRUM) - pal.setColor(trackNameLabel->backgroundRole(), MusEConfig::config.drumTrackLabelBg); + c = MusEConfig::config.drumTrackLabelBg; else - pal.setColor(trackNameLabel->backgroundRole(), MusEConfig::config.midiTrackLabelBg); - trackNameLabel->setPalette(pal); - } + c = MusEConfig::config.midiTrackLabelBg; + + QLinearGradient gradient(trackNameLabel->geometry().topLeft(), trackNameLabel->geometry().bottomLeft()); + //gradient.setColorAt(0, c.darker()); + //gradient.setColorAt(0, c); + //gradient.setColorAt(1, c.darker()); + gradient.setColorAt(0, c.lighter()); + gradient.setColorAt(1, c); + //palette.setBrush(QPalette::Button, gradient); + //palette.setBrush(QPalette::Window, gradient); + pal.setBrush(trackNameLabel->backgroundRole(), gradient); + trackNameLabel->setPalette(pal); */ + } //else //{ // pal.setColor(trackNameLabel->backgroundRole(), MusEConfig::config.midiTrackLabelBg); @@ -543,6 +559,28 @@ void MidiTrackInfo::setLabelText() trackNameLabel->setText(track->name()); else trackNameLabel->setText(QString()); + + if(track) + { + QPalette pal; + QColor c; + //pal.setColor(trackNameLabel->backgroundRole(), QColor(0, 160, 255)); // Med blue + if(track->type() == Track::DRUM) + c = MusEConfig::config.drumTrackLabelBg; + else + c = MusEConfig::config.midiTrackLabelBg; + + QLinearGradient gradient(trackNameLabel->geometry().topLeft(), trackNameLabel->geometry().bottomLeft()); + //gradient.setColorAt(0, c.darker()); + //gradient.setColorAt(0, c); + //gradient.setColorAt(1, c.darker()); + gradient.setColorAt(0, c.lighter()); + gradient.setColorAt(1, c); + //palette.setBrush(QPalette::Button, gradient); + //palette.setBrush(QPalette::Window, gradient); + pal.setBrush(trackNameLabel->backgroundRole(), gradient); + trackNameLabel->setPalette(pal); + } } //--------------------------------------------------------- @@ -1340,6 +1378,8 @@ void MidiTrackInfo::updateTrackInfo(int flags) recEchoButton->setChecked(track->recEcho()); recEchoButton->blockSignals(false); } + recEchoButton->setIcon(track->recEcho() ? QIcon(*midiThruOnIcon) : QIcon(*midiThruOffIcon)); + //recEchoButton->setIconSize(midiThruOnIcon->size()); } int outChannel = track->outChannel(); @@ -1566,4 +1606,12 @@ void MidiTrackInfo::recordClicked() } } +void MidiTrackInfo::resizeEvent(QResizeEvent* ev) +{ + //printf("MidiTrackInfo::resizeEvent\n"); + QWidget::resizeEvent(ev); + setLabelText(); + setLabelFont(); +} + } // namespace MusEWidget diff --git a/muse2/muse/widgets/mtrackinfo.h b/muse2/muse/widgets/mtrackinfo.h index 42be1f58..42bcb2bf 100644 --- a/muse2/muse/widgets/mtrackinfo.h +++ b/muse2/muse/widgets/mtrackinfo.h @@ -2,6 +2,7 @@ // MusE // Linux Music Editor // (C) Copyright 2010 Werner Schweer and others (ws@seh.de) +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -40,7 +41,10 @@ class MidiTrackInfo : public QWidget, public Ui::MidiTrackInfoBase int program, pan, volume; int heartBeatCounter; - private slots: + protected: + virtual void resizeEvent(QResizeEvent*); + + private slots: void iOutputChannelChanged(int); void iOutputPortChanged(int); void iProgHBankChanged(); diff --git a/muse2/muse/widgets/posedit.cpp b/muse2/muse/widgets/posedit.cpp index 0e031c38..772d434a 100644 --- a/muse2/muse/widgets/posedit.cpp +++ b/muse2/muse/widgets/posedit.cpp @@ -77,11 +77,11 @@ class PosEditor : public QLineEdit protected: void init(); - bool event(QEvent *e); - void resizeEvent(QResizeEvent*); - void paintEvent(QPaintEvent*); - void mousePressEvent(QMouseEvent *e); - void keyPressEvent(QKeyEvent * event ); + virtual bool event(QEvent *e); + virtual void resizeEvent(QResizeEvent*); + virtual void paintEvent(QPaintEvent*); + virtual void mousePressEvent(QMouseEvent *e); + virtual void keyPressEvent(QKeyEvent * event ); void applyFocusSelection() {} public: @@ -817,8 +817,9 @@ void PosEdit::removeLastNumber(int secNo) // resizeEvent //--------------------------------------------------------- -void PosEdit::resizeEvent(QResizeEvent *) +void PosEdit::resizeEvent(QResizeEvent* ev) { + QWidget::resizeEvent(ev); controls->resize(width(), height()); } diff --git a/muse2/muse/widgets/posedit.h b/muse2/muse/widgets/posedit.h index 3224a3a6..5f763f51 100644 --- a/muse2/muse/widgets/posedit.h +++ b/muse2/muse/widgets/posedit.h @@ -74,9 +74,9 @@ class PosEdit : public QWidget void returnPressed(); protected: - bool event(QEvent *e ); + virtual bool event(QEvent *e ); void timerEvent(QTimerEvent* e); - void resizeEvent(QResizeEvent*); + virtual void resizeEvent(QResizeEvent*); QString sectionFormattedText(int sec); void addNumber(int sec, int num); void removeLastNumber(int sec); diff --git a/muse2/muse/widgets/scrollscale.cpp b/muse2/muse/widgets/scrollscale.cpp index 21ed10b6..e7d40f67 100644 --- a/muse2/muse/widgets/scrollscale.cpp +++ b/muse2/muse/widgets/scrollscale.cpp @@ -197,9 +197,10 @@ void ScrollScale::setPosNoLimit ( unsigned pos ) // resizeEvent //--------------------------------------------------------- -void ScrollScale::resizeEvent ( QResizeEvent* ) +void ScrollScale::resizeEvent ( QResizeEvent* ev) { - setScale ( scale->value() ); + QWidget::resizeEvent(ev); + setScale ( scale->value() ); } //--------------------------------------------------------- diff --git a/muse2/muse/widgets/sigedit.cpp b/muse2/muse/widgets/sigedit.cpp index c2c5a842..a952cfef 100644 --- a/muse2/muse/widgets/sigedit.cpp +++ b/muse2/muse/widgets/sigedit.cpp @@ -103,11 +103,11 @@ class SigEditor : public QLineEdit protected: void init(); - bool event(QEvent *e); - void resizeEvent(QResizeEvent*); - void paintEvent(QPaintEvent*); - void mousePressEvent(QMouseEvent *e); - void keyPressEvent(QKeyEvent * event ); + virtual bool event(QEvent *e); + virtual void resizeEvent(QResizeEvent*); + virtual void paintEvent(QPaintEvent*); + virtual void mousePressEvent(QMouseEvent *e); + virtual void keyPressEvent(QKeyEvent * event ); void applyFocusSelection() {} public: @@ -699,9 +699,10 @@ void SigEdit::removeLastNumber(int secNo) // resizeEvent //--------------------------------------------------------- -void SigEdit::resizeEvent(QResizeEvent *) +void SigEdit::resizeEvent(QResizeEvent* ev) { - controls->resize(width(), height()); + QWidget::resizeEvent(ev); + controls->resize(width(), height()); } //--------------------------------------------------------- diff --git a/muse2/muse/widgets/sigedit.h b/muse2/muse/widgets/sigedit.h index 3b1ca635..05684db1 100644 --- a/muse2/muse/widgets/sigedit.h +++ b/muse2/muse/widgets/sigedit.h @@ -72,9 +72,9 @@ class SigEdit : public QWidget void returnPressed(); protected: - bool event(QEvent *e ); + virtual bool event(QEvent *e ); void timerEvent(QTimerEvent* e); - void resizeEvent(QResizeEvent*); + virtual void resizeEvent(QResizeEvent*); QString sectionFormattedText(int sec); void addNumber(int sec, int num); void removeLastNumber(int sec); diff --git a/muse2/muse/widgets/slider.cpp b/muse2/muse/widgets/slider.cpp index 593b3df6..863933d2 100644 --- a/muse2/muse/widgets/slider.cpp +++ b/muse2/muse/widgets/slider.cpp @@ -580,7 +580,7 @@ void Slider::paintEvent(QPaintEvent* /*ev*/) void Slider::resizeEvent(QResizeEvent *e) { - + MusEWidget::SliderBase::resizeEvent(e); d_resized = TRUE; QSize s = e->size(); /* Scale is not supported diff --git a/muse2/muse/widgets/slider.h b/muse2/muse/widgets/slider.h index 5a2bff71..b1281da0 100644 --- a/muse2/muse/widgets/slider.h +++ b/muse2/muse/widgets/slider.h @@ -79,8 +79,8 @@ class Slider : public SliderBase, public ScaleIf virtual void drawSlider (QPainter *p, const QRect &r); double getValue(const QPoint &p); void getScrollMode( QPoint &p, const Qt::MouseButton &button, int &scrollMode, int &direction); - void resizeEvent(QResizeEvent *e); - void paintEvent (QPaintEvent *e); + virtual void resizeEvent(QResizeEvent *e); + virtual void paintEvent (QPaintEvent *e); void valueChange(); void rangeChange(); void scaleChange(); diff --git a/muse2/muse/widgets/swidget.cpp b/muse2/muse/widgets/swidget.cpp index f8461977..51796781 100644 --- a/muse2/muse/widgets/swidget.cpp +++ b/muse2/muse/widgets/swidget.cpp @@ -32,7 +32,8 @@ namespace MusEWidget { void SWidget::resizeEvent(QResizeEvent* ev) { - emit heightChanged(ev->size().height()); + QWidget::resizeEvent(ev); + emit heightChanged(ev->size().height()); } } // namespace MusEWidget diff --git a/muse2/muse/widgets/verticalmeter.cpp b/muse2/muse/widgets/verticalmeter.cpp index 74b4b695..4553b156 100644 --- a/muse2/muse/widgets/verticalmeter.cpp +++ b/muse2/muse/widgets/verticalmeter.cpp @@ -333,8 +333,9 @@ void VerticalMeter::drawVU(QPainter& p, int w, int h, int xv) // resizeEvent //--------------------------------------------------------- -void VerticalMeter::resizeEvent(QResizeEvent* /*ev*/) +void VerticalMeter::resizeEvent(QResizeEvent* ev) { + MusEWidget::Meter::resizeEvent(ev); } } // namespace MusEWidget diff --git a/muse2/muse/widgets/verticalmeter.h b/muse2/muse/widgets/verticalmeter.h index d6bee245..024ecc10 100644 --- a/muse2/muse/widgets/verticalmeter.h +++ b/muse2/muse/widgets/verticalmeter.h @@ -47,8 +47,8 @@ class VerticalMeter : public Meter { void drawVU(QPainter& p, int, int, int); - void paintEvent(QPaintEvent*); - void resizeEvent(QResizeEvent*); + virtual void paintEvent(QPaintEvent*); + virtual void resizeEvent(QResizeEvent*); public slots: void resetPeaks(); diff --git a/muse2/muse/widgets/view.cpp b/muse2/muse/widgets/view.cpp index 9be66ed5..8a9d82b4 100644 --- a/muse2/muse/widgets/view.cpp +++ b/muse2/muse/widgets/view.cpp @@ -290,8 +290,9 @@ void View::setYPos(int y) // resizeEvent //--------------------------------------------------------- -void View::resizeEvent(QResizeEvent* /*ev*/) +void View::resizeEvent(QResizeEvent* ev) { + QWidget::resizeEvent(ev); #ifdef VIEW_USE_DOUBLE_BUFFERING //pm.resize(ev->size()); //printf("View::resizeEvent width:%d height:%d\n", diff --git a/muse2/synti/deicsonze/deicsonzegui.h b/muse2/synti/deicsonze/deicsonzegui.h index f82e072b..7dec344f 100644 --- a/muse2/synti/deicsonze/deicsonzegui.h +++ b/muse2/synti/deicsonze/deicsonzegui.h @@ -526,10 +526,10 @@ class QFramePitchEnvelope:private QFrame { void env2Points(int pl1, int pl2, int pl3, int pr1, int pr2, int pr3); void updateEnv(void) {update();}; protected: - void paintEvent(QPaintEvent* e); - void mouseMoveEvent(QMouseEvent* e); - void mousePressEvent(QMouseEvent * e); - void mouseReleaseEvent(QMouseEvent * e); + virtual void paintEvent(QPaintEvent* e); + virtual void mouseMoveEvent(QMouseEvent* e); + virtual void mousePressEvent(QMouseEvent * e); + virtual void mouseReleaseEvent(QMouseEvent * e); }; class QFrameEnvelope:private QFrame { -- cgit v1.2.3 From 9200bb81f55b0d33e0a61af0112f1ca294375554 Mon Sep 17 00:00:00 2001 From: Robert Jonsson Date: Sun, 2 Oct 2011 18:54:37 +0000 Subject: some rework on SigEdit --- muse2/ChangeLog | 3 + muse2/awl/sigedit.cpp | 227 ++++++++++-------------------------------- muse2/awl/sigedit.h | 23 +++-- muse2/muse/master/lmaster.cpp | 5 +- 4 files changed, 73 insertions(+), 185 deletions(-) diff --git a/muse2/ChangeLog b/muse2/ChangeLog index e7ddcec9..76feeabe 100644 --- a/muse2/ChangeLog +++ b/muse2/ChangeLog @@ -1,3 +1,6 @@ +02.09.2011: + - SigEdit reworked to use two spinboxes, plan on adding Enter/Return detection so the widget will close when + Enter/Return is pressed (rj) 30.09.2011: - Fixed long-standing problem with themes (Ia Ora / Bespin etc) and MusE button icons. Some themes don't support multiple-pixmap icons. So mute/solo/rec/stereo/thru always showed the same icon. Replaced w single pm icons. (Tim) diff --git a/muse2/awl/sigedit.cpp b/muse2/awl/sigedit.cpp index 1d2bce48..74e4b060 100644 --- a/muse2/awl/sigedit.cpp +++ b/muse2/awl/sigedit.cpp @@ -28,6 +28,7 @@ #include #include +#include namespace Awl { @@ -38,212 +39,92 @@ namespace Awl { //--------------------------------------------------------- SigEdit::SigEdit(QWidget* parent) - : QAbstractSpinBox(parent) + : QWidget(parent) { initialized = false; - setReadOnly(false); - setMinimumWidth(100); //TD: sizeHint - lineEdit()->setInputMask("99/99"); - } + slash = new QLabel("/",this); + zSpin = new QSpinBox(this); + nSpin = new QSpinBox(this); + zSpin->setRange(1,100); + nSpin->setRange(1,100); + layout = new QHBoxLayout(this); + layout->setContentsMargins(0,0,0,0); + layout->setSpacing(1); + layout->addWidget(zSpin); + layout->addWidget(slash); + layout->addWidget(nSpin); + layout->addSpacing(40); + connect(zSpin, SIGNAL(valueChanged(int)), SLOT(setZ(int))); + connect(nSpin, SIGNAL(valueChanged(int)), SLOT(setN(int))); -SigEdit::~SigEdit() - { } -//--------------------------------------------------------- -// event -// filter Tab and Backtab key events -//--------------------------------------------------------- - -bool SigEdit::event(QEvent* event) - { - if (event->type() == QEvent::KeyPress) { - QKeyEvent* ke = static_cast(event); - int segment = curSegment(); - if (ke->key() == Qt::Key_Return) - { - int z, n; - sscanf(lineEdit()->text().toLatin1().data(), "%d/%d", &z, &n); - AL::TimeSignature sig(z, n); - _sig = sig; - - emit returnPressed(); - return true; - } - if (ke->key() == Qt::Key_Backtab) { - if (segment == 2) { - lineEdit()->setSelection(5, 2); - return true; - } - if (segment == 1) { - lineEdit()->setSelection(0, 4); - return true; - } - } - if (ke->key() == Qt::Key_Tab) { - if (segment == 0) { - lineEdit()->setSelection(5, 2); - return true; - } - if (segment == 1) { - lineEdit()->setSelection(8, 3); - return true; - } - } - } - else if (event->type() == QEvent::FocusIn) { - QFocusEvent* fe = static_cast(event); - QAbstractSpinBox::focusInEvent(fe); - int segment = curSegment(); - switch(segment) { - case 0: lineEdit()->setSelection(0,4); break; - case 1: lineEdit()->setSelection(5,2); break; - case 2: lineEdit()->setSelection(8,3); break; - } - return true; - } - return QAbstractSpinBox::event(event); - } - -//--------------------------------------------------------- -// setValue -//--------------------------------------------------------- - -void SigEdit::setValue(const AL::TimeSignature& s) +SigEdit::~SigEdit() { - _sig = s; - updateValue(); + delete layout; + delete zSpin; + delete nSpin; } -void SigEdit::setValue(const QString& s) - { - int z = 4, n = 4; - sscanf(s.toLatin1().constData(), "%d/%d", &z, &n); - AL::TimeSignature sig(z, n); - setValue(sig); - } //--------------------------------------------------------- -// updateValue +// setZ //--------------------------------------------------------- -void SigEdit::updateValue() - { - //printf("updateValue\n"); - char buffer[64]; - sprintf(buffer, "%d/%d", _sig.z, _sig.n); - lineEdit()->setText(buffer); - } - +void SigEdit::setZ(const int z) +{ + _sig.z=z; + if (_sig.isValid()) { + zSpin->setStyleSheet(""); + emit valueChanged(_sig); + } + else + zSpin->setStyleSheet("QSpinBox { background-color: red; }"); +} //--------------------------------------------------------- -// stepEnables +// setN //--------------------------------------------------------- -QAbstractSpinBox::StepEnabled SigEdit::stepEnabled() const - { - int segment = curSegment(); - QAbstractSpinBox::StepEnabled en = QAbstractSpinBox::StepUpEnabled | QAbstractSpinBox::StepDownEnabled; - - switch (segment) { - case 0: - if (_sig.z == 1) - en &= ~QAbstractSpinBox::StepDownEnabled; - break; - case 1: - if (_sig.n == 1) - en &= ~QAbstractSpinBox::StepDownEnabled; - break; - } - return en; - } +void SigEdit::setN(const int n) +{ + _sig.n=n; + if (_sig.isValid()) { + nSpin->setStyleSheet(""); + emit valueChanged(_sig); + } + else + nSpin->setStyleSheet("QSpinBox { background-color: red; }"); -//--------------------------------------------------------- -// fixup -//--------------------------------------------------------- - -void SigEdit::fixup(QString& /*input*/) const - { -// printf("fixup <%s>\n", input.toLatin1().constData()); - } +} //--------------------------------------------------------- -// validate +// setValue //--------------------------------------------------------- -QValidator::State SigEdit::validate(QString&,int&) const +void SigEdit::setValue(const AL::TimeSignature& s) { - // TODO - //printf("validate\n"); - return QValidator::Acceptable; - } - -//--------------------------------------------------------- -// curSegment -//--------------------------------------------------------- + _sig = s; -int SigEdit::curSegment() const - { - QLineEdit* le = lineEdit(); - int pos = le->cursorPosition(); - int segment = -1; - - if (pos >= 0 && pos <= 4) - segment = 0; - else if (pos >= 5 && pos <= 7) - segment = 1; - else if (pos >= 8) - segment = 2; - else - printf("curSegment = -1, pos %d\n", pos); - return segment; + updateValue(); } //--------------------------------------------------------- -// stepBy +// updateValue //--------------------------------------------------------- -void SigEdit::stepBy(int steps) +void SigEdit::updateValue() { - int segment = curSegment(); - int selPos; - int selLen; - - bool changed = false; - AL::TimeSignature osig(_sig); - - switch(segment) { - case 0: - _sig.z += steps; - if (_sig.z < 1) - _sig.z = 1; - selPos = 0; - selLen = 2; - break; - case 1: - _sig.n += steps; - if (_sig.n < 1) - _sig.n = 1; - selPos = 3; - selLen = 2; - break; - default: - return; - } - if (osig.z != _sig.z || osig.n != _sig.n) { - changed = true; - } - if (changed) { - updateValue(); - emit valueChanged(_sig); - } - lineEdit()->setSelection(selPos, selLen); + zSpin->setValue(_sig.z); + nSpin->setValue(_sig.n); } - void SigEdit::paintEvent(QPaintEvent* event) { + void SigEdit::paintEvent(QPaintEvent* event) { if (!initialized) updateValue(); initialized = true; - QAbstractSpinBox::paintEvent(event); + QPainter p(this); + p.fillRect(event->rect(), Qt::white); + QWidget::paintEvent(event); } } diff --git a/muse2/awl/sigedit.h b/muse2/awl/sigedit.h index 259812dd..acb0b9d8 100644 --- a/muse2/awl/sigedit.h +++ b/muse2/awl/sigedit.h @@ -26,7 +26,10 @@ #include "al/sig.h" //#include "sig.h" -#include +#include +#include +#include +#include namespace AL { class TimeSignature; @@ -38,29 +41,29 @@ namespace Awl { // SigEdit //--------------------------------------------------------- -class SigEdit : public QAbstractSpinBox +class SigEdit : public QWidget { Q_OBJECT AL::TimeSignature _sig; bool initialized; + QLabel *slash; + QSpinBox *zSpin; + QSpinBox *nSpin; + QHBoxLayout *layout; virtual void paintEvent(QPaintEvent* event); - virtual void stepBy(int steps); - virtual StepEnabled stepEnabled() const; - virtual void fixup(QString& input) const; - virtual QValidator::State validate(QString&, int&) const; void updateValue(); - int curSegment() const; - virtual bool event(QEvent*); signals: void valueChanged(const AL::TimeSignature&); - void returnPressed(); + + private slots: + void setN(const int n); + void setZ(const int z); public slots: void setValue(const AL::TimeSignature&); - void setValue(const QString& s); public: SigEdit(QWidget* parent = 0); diff --git a/muse2/muse/master/lmaster.cpp b/muse2/muse/master/lmaster.cpp index a2cc8538..ce6010c7 100644 --- a/muse2/muse/master/lmaster.cpp +++ b/muse2/muse/master/lmaster.cpp @@ -601,7 +601,8 @@ void LMaster::itemDoubleClicked(QTreeWidgetItem* i) tempo_editor->selectAll(); } else if (editedItem->getType() == LMASTER_SIGEVENT) { // Edit signatur value: - sig_editor->setValue(editedItem->text(LMASTER_VAL_COL)); + //sig_editor->setValue(editedItem->text(LMASTER_VAL_COL)); + sig_editor->setValue(((LMasterSigEventItem*)editedItem)->getEvent()->sig); sig_editor->setGeometry(itemRect); sig_editor->show(); sig_editor->setFocus(); @@ -923,7 +924,7 @@ LMasterSigEventItem::LMasterSigEventItem(QTreeWidget* parent, const AL::SigEvent int msec = int((time - (min*60 + sec)) * 1000.0); c2.sprintf("%03d:%02d:%03d", min, sec, msec); c3 = "Timesig"; - c4.sprintf("%d/%d", ev->sig.z, ev->sig.n); + c4.sprintf("%d / %d", ev->sig.z, ev->sig.n); setText(0, c1); setText(1, c2); setText(2, c3); -- cgit v1.2.3 From f3313cc78e637ec9bc11efce5eb943434da93416 Mon Sep 17 00:00:00 2001 From: "Tim E. Real" Date: Mon, 3 Oct 2011 01:56:34 +0000 Subject: Fixed HUGE massive memory leaks in all things using CItemList, and SndFile, dssi, fluidsynth and other huge leaks. Large song with several dssi, vst, fluidsynths leaked 100's of MB, now only ~2MB. --- muse2/ChangeLog | 6 + muse2/muse/app.cpp | 10 +- muse2/muse/arranger/pcanvas.cpp | 8 +- muse2/muse/arranger/pcanvas.h | 1 + muse2/muse/audiotrack.cpp | 3 + muse2/muse/driver/alsamidi.cpp | 25 +- muse2/muse/driver/alsamidi.h | 3 +- muse2/muse/dssihost.cpp | 14 +- muse2/muse/dssihost.h | 2 +- muse2/muse/midiedit/dcanvas.cpp | 5 + muse2/muse/midiedit/dcanvas.h | 1 + muse2/muse/midiedit/ecanvas.cpp | 3 +- muse2/muse/osc.cpp | 523 +++++++++------------------------- muse2/muse/osc.h | 98 +------ muse2/muse/part.h | 5 + muse2/muse/plugin.cpp | 17 +- muse2/muse/plugin.h | 1 + muse2/muse/song.cpp | 8 +- muse2/muse/track.cpp | 5 + muse2/muse/track.h | 2 +- muse2/muse/wave.cpp | 4 +- muse2/muse/wave.h | 30 +- muse2/muse/widgets/canvas.cpp | 5 + muse2/muse/widgets/canvas.h | 1 + muse2/muse/widgets/citem.h | 5 + muse2/muse/widgets/scrollscale.cpp | 1 + muse2/muse/widgets/siglabel.cpp | 6 +- muse2/muse/widgets/tools.cpp | 2 +- muse2/muse/widgets/visibletracks.cpp | 2 +- muse2/synti/fluidsynth/fluidsynti.cpp | 11 + 30 files changed, 290 insertions(+), 517 deletions(-) diff --git a/muse2/ChangeLog b/muse2/ChangeLog index 76feeabe..4c45bc99 100644 --- a/muse2/ChangeLog +++ b/muse2/ChangeLog @@ -1,6 +1,12 @@ 02.09.2011: - SigEdit reworked to use two spinboxes, plan on adding Enter/Return detection so the widget will close when Enter/Return is pressed (rj) + - Fixed HUGE massive memory leaks in all things using CItemList, and SndFile, dssi, fluidsynth and other huge leaks. (Tim) + Addition of 'delete' in places hopefully does not introduce any new unforseen instabilities. + Result: A song with 20 wave/midi tracks and several dssi, vst and fluidsynths, which leaked HUNDREDS of megabytes, + now only leaks about 2 megabytes. TODO: Still some funny business with ALSA, and dssi scanning. + Post-fix LEAK SUMMARY: definitely lost: 259,863 bytes in 356 blocks indirectly lost: 611,874 bytes in 22,834 blocks + possibly lost: 180,508 bytes in 5,211 blocks still reachable: 1,061,068 bytes in 10,522 blocks 30.09.2011: - Fixed long-standing problem with themes (Ia Ora / Bespin etc) and MusE button icons. Some themes don't support multiple-pixmap icons. So mute/solo/rec/stereo/thru always showed the same icon. Replaced w single pm icons. (Tim) diff --git a/muse2/muse/app.cpp b/muse2/muse/app.cpp index 9f858bc3..fd024d57 100644 --- a/muse2/muse/app.cpp +++ b/muse2/muse/app.cpp @@ -112,6 +112,7 @@ extern void initMidiSynth(); extern void exitJackAudio(); extern void exitDummyAudio(); extern void exitOSC(); +extern void exitMidiAlsa(); #ifdef HAVE_LASH #include @@ -1562,12 +1563,13 @@ void MusE::closeEvent(QCloseEvent* event) } #endif - // Changed by Tim. p3.3.14 - //SynthIList* sl = song->syntis(); - //for (iSynthI i = sl->begin(); i != sl->end(); ++i) - // delete *i; song->cleanupForQuit(); + // Give midi devices a chance to close first, above in cleanupForQuit. + if(MusEGlobal::debugMsg) + printf("Muse: Exiting ALSA midi\n"); + exitMidiAlsa(); + if(MusEGlobal::debugMsg) printf("Muse: Cleaning up temporary wavefiles + peakfiles\n"); // Cleanup temporary wavefiles + peakfiles used for undo diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp index 0de8d278..5b5f3a6f 100644 --- a/muse2/muse/arranger/pcanvas.cpp +++ b/muse2/muse/arranger/pcanvas.cpp @@ -112,6 +112,11 @@ PartCanvas::PartCanvas(int* r, QWidget* parent, int sx, int sy) partsChanged(); } +PartCanvas::~PartCanvas() +{ + //items.clearDelete(); +} + //--------------------------------------------------------- // y2pitch //--------------------------------------------------------- @@ -427,7 +432,8 @@ QPoint PartCanvas::raster(const QPoint& p) const void PartCanvas::partsChanged() { - items.clear(); + //items.clear(); + items.clearDelete(); for (iTrack t = tracks->begin(); t != tracks->end(); ++t) { PartList* pl = (*t)->parts(); for (iPart i = pl->begin(); i != pl->end(); ++i) { diff --git a/muse2/muse/arranger/pcanvas.h b/muse2/muse/arranger/pcanvas.h index 3e320e56..e0c601fe 100644 --- a/muse2/muse/arranger/pcanvas.h +++ b/muse2/muse/arranger/pcanvas.h @@ -171,6 +171,7 @@ class PartCanvas : public MusEWidget::Canvas { CMD_PASTE_DIALOG, CMD_PASTE_CLONE_DIALOG, CMD_INSERT_EMPTYMEAS }; PartCanvas(int* raster, QWidget* parent, int, int); + virtual ~PartCanvas(); void partsChanged(); void cmd(int); public slots: diff --git a/muse2/muse/audiotrack.cpp b/muse2/muse/audiotrack.cpp index 1db8dda3..6426a377 100644 --- a/muse2/muse/audiotrack.cpp +++ b/muse2/muse/audiotrack.cpp @@ -202,6 +202,9 @@ AudioTrack::~AudioTrack() } delete[] outBuffers; + for(iCtrlList i = _controller.begin(); i != _controller.end(); ++i) + delete i->second; + } //--------------------------------------------------------- diff --git a/muse2/muse/driver/alsamidi.cpp b/muse2/muse/driver/alsamidi.cpp index 6395bf2d..8ad9c510 100644 --- a/muse2/muse/driver/alsamidi.cpp +++ b/muse2/muse/driver/alsamidi.cpp @@ -3,7 +3,7 @@ // Linux Music Editor // $Id: alsamidi.cpp,v 1.8.2.7 2009/11/19 04:20:33 terminator356 Exp $ // (C) Copyright 2000-2001 Werner Schweer (ws@seh.de) -// (C) Copyright 2011 Tim E. Real (terminator356 on users dot sourceforge dot net) +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -42,7 +42,7 @@ static int alsaSeqFdi = -1; static int alsaSeqFdo = -1; -snd_seq_t* alsaSeq; +snd_seq_t* alsaSeq = 0; static snd_seq_addr_t musePort; //--------------------------------------------------------- @@ -795,6 +795,27 @@ bool initMidiAlsa() return false; } +namespace MusEApp { + +//--------------------------------------------------------- +// exitMidiAlsa +//--------------------------------------------------------- + +void exitMidiAlsa() +{ + if(alsaSeq) + { + int error = snd_seq_close(alsaSeq); // FIXME Hm, this did not get rid of a buch of valgrind leaks. + if(error < 0) + { + fprintf(stderr, "Could not close ALSA sequencer: %s\n", snd_strerror(error)); + } + } +} + +} // namespace MusEApp + + struct AlsaPort { snd_seq_addr_t adr; char* name; diff --git a/muse2/muse/driver/alsamidi.h b/muse2/muse/driver/alsamidi.h index 13e07ca4..9badd7c4 100644 --- a/muse2/muse/driver/alsamidi.h +++ b/muse2/muse/driver/alsamidi.h @@ -3,7 +3,7 @@ // Linux Music Editor // $Id: alsamidi.h,v 1.2 2004/01/14 09:06:43 wschweer Exp $ // (C) Copyright 2001 Werner Schweer (ws@seh.de) -// (C) Copyright 2011 Tim E. Real (terminator356 on users dot sourceforge dot net) +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -77,6 +77,7 @@ class MidiAlsaDevice : public MidiDevice { }; extern bool initMidiAlsa(); +extern bool exitMidiAlsa(); extern int alsaSelectRfd(); extern int alsaSelectWfd(); extern void alsaProcessMidiInput(); diff --git a/muse2/muse/dssihost.cpp b/muse2/muse/dssihost.cpp index 42653a91..ad4b2401 100644 --- a/muse2/muse/dssihost.cpp +++ b/muse2/muse/dssihost.cpp @@ -4,7 +4,7 @@ // $Id: dssihost.cpp,v 1.15.2.16 2009/12/15 03:39:58 terminator356 Exp $ // // Copyright (C) 1999-2011 by Werner Schweer and others -// (C) Copyright 2011 Tim E. Real (terminator356 on users dot sourceforge dot net) +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License @@ -84,8 +84,6 @@ static void scanDSSILib(QFileInfo& fi) // ddskrjo removed const for argument { const DSSI_Descriptor* descr; - // CRAPPY PLUGIN ALERT: - // Out of many plugins, with several, Valgrind says something in here is allocated with new. descr = dssi(i); if (descr == 0) break; @@ -120,8 +118,10 @@ static void scanDSSILib(QFileInfo& fi) // ddskrjo removed const for argument break; } if(is != synthis.end()) + { + //delete descr; continue; - + } DssiSynth* s = new DssiSynth(fi, descr); if(MusEGlobal::debugMsg) @@ -149,6 +149,9 @@ static void scanDSSILib(QFileInfo& fi) // ddskrjo removed const for argument synthis.push_back(s); } + //else + // delete descr; + } } dlclose(handle); @@ -270,7 +273,8 @@ DssiSynth::DssiSynth(QFileInfo& fi, const DSSI_Descriptor* d) : // ddskrjo remov DssiSynth::~DssiSynth() { - + if(dssi) + delete dssi; } //--------------------------------------------------------- diff --git a/muse2/muse/dssihost.h b/muse2/muse/dssihost.h index cea46e69..05e3b91c 100644 --- a/muse2/muse/dssihost.h +++ b/muse2/muse/dssihost.h @@ -4,7 +4,7 @@ // $Id: dssihost.h,v 1.10.2.7 2009/12/06 10:05:00 terminator356 Exp $ // // Copyright (C) 1999-2011 by Werner Schweer and others -// (C) Copyright 2011 Tim E. Real (terminator356 on users dot sourceforge dot net) +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index 3f80133a..138511d6 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -111,6 +111,11 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx, connect(song, SIGNAL(midiNote(int, int)), SLOT(midiNote(int,int))); } +DrumCanvas::~DrumCanvas() +{ + //items.clearDelete(); +} + //--------------------------------------------------------- // moveCanvasItems //--------------------------------------------------------- diff --git a/muse2/muse/midiedit/dcanvas.h b/muse2/muse/midiedit/dcanvas.h index c25f71ca..c5c51310 100644 --- a/muse2/muse/midiedit/dcanvas.h +++ b/muse2/muse/midiedit/dcanvas.h @@ -114,6 +114,7 @@ class DrumCanvas : public EventCanvas { }; DrumCanvas(MidiEditor*, QWidget*, int, int, const char* name = 0); + virtual ~DrumCanvas(); void cmd(int); virtual void modifySelected(MusEWidget::NoteInfo::ValType type, int delta); virtual void keyPress(QKeyEvent* event); diff --git a/muse2/muse/midiedit/ecanvas.cpp b/muse2/muse/midiedit/ecanvas.cpp index cb96118f..b30574f1 100644 --- a/muse2/muse/midiedit/ecanvas.cpp +++ b/muse2/muse/midiedit/ecanvas.cpp @@ -147,7 +147,8 @@ void EventCanvas::songChanged(int flags) return; if (flags & ~SC_SELECTION) { - items.clear(); + //items.clear(); + items.clearDelete(); start_tick = MAXINT; end_tick = 0; curPart = 0; diff --git a/muse2/muse/osc.cpp b/muse2/muse/osc.cpp index e7aaa46b..c0d936ec 100644 --- a/muse2/muse/osc.cpp +++ b/muse2/muse/osc.cpp @@ -4,7 +4,7 @@ // $Id: osc.cpp,v 1.0.0.0 2010/04/22 03:39:58 terminator356 Exp $ // // Copyright (C) 1999-2011 by Werner Schweer and others -// OSC module added by Tim. +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License @@ -28,21 +28,23 @@ // Turn on debugging messages //#define OSC_DEBUG +// Whether to use a QProcess or fork + execlp to start the gui. (Note fork + execlp give problems - zombies when synth window closed.) +#define _USE_QPROCESS_FOR_GUI_ 1 + #include -//#include -//#include #include -#include -#include -//#include -//#include -#include #include #include #include -#include -#include + +#ifdef _USE_QPROCESS_FOR_GUI_ + #include +#else + #include + #include + #include +#endif #include @@ -55,23 +57,11 @@ #include "track.h" #include "song.h" #include "synth.h" -//#include "audio.h" -//#include "jackaudio.h" -//#include "midi.h" -//#include "midiport.h" -//#include "al/al.h" -//#include "al/xml.h" -//#include "xml.h" -//#include "midictrl.h" -//#include "ladspaplugin.h" - #include "app.h" #include "globals.h" #include "globaldefs.h" -//#include "al/dsp.h" static lo_server_thread serverThread = 0; -///static char osc_path_tmp[1024]; static char* url = 0; static bool oscServerRunning = false; @@ -107,7 +97,6 @@ static int oscDebugHandler(const char* path, const char* types, lo_arg** argv, int oscMessageHandler(const char* path, const char* types, lo_arg** argv, int argc, void* data, void* user_data) - //int argc, lo_message data, void* user_data) { const char* p = path; @@ -409,61 +398,6 @@ void stopOSC() } // namespace MusEApp -/* -//--------------------------------------------------------- -// OscControlFifo -// put -// return true on fifo overflow -//--------------------------------------------------------- - -bool OscControlFifo::put(const OscControlValue& event) - { - if (size < OSC_FIFO_SIZE) { - fifo[wIndex] = event; - wIndex = (wIndex + 1) % OSC_FIFO_SIZE; - // q_atomic_increment(&size); - ++size; - return false; - } - return true; - } - -//--------------------------------------------------------- -// get -//--------------------------------------------------------- - -OscControlValue OscControlFifo::get() - { - OscControlValue event(fifo[rIndex]); - rIndex = (rIndex + 1) % OSC_FIFO_SIZE; - // q_atomic_decrement(&size); - --size; - return event; - } - -//--------------------------------------------------------- -// peek -//--------------------------------------------------------- - -const OscControlValue& OscControlFifo::peek(int n) - { - int idx = (rIndex + n) % OSC_FIFO_SIZE; - return fifo[idx]; - } - -//--------------------------------------------------------- -// remove -//--------------------------------------------------------- - -void OscControlFifo::remove() - { - rIndex = (rIndex + 1) % OSC_FIFO_SIZE; - // q_atomic_decrement(&size); - --size; - } -*/ - - //--------------------------------------------------------- // OscIF // Open Sound Control Interface @@ -471,12 +405,6 @@ void OscControlFifo::remove() OscIF::OscIF() { - //_oscPluginI = 0; - - //#ifdef DSSI_SUPPORT - //_oscSynthIF = 0; - //#endif - _uiOscTarget = 0; _uiOscSampleRatePath = 0; _uiOscShowPath = 0; @@ -484,17 +412,17 @@ OscIF::OscIF() _uiOscConfigurePath = 0; _uiOscProgramPath = 0; _uiOscPath = 0; - //guiPid = -1; +#ifdef _USE_QPROCESS_FOR_GUI_ _oscGuiQProc = 0; +#else + _guiPid = -1; +#endif _oscGuiVisible = false; - - //_oscControlFifos = 0; } OscIF::~OscIF() { - //if (guiPid != -1) - // kill(guiPid, SIGHUP); +#ifdef _USE_QPROCESS_FOR_GUI_ if(_oscGuiQProc) { if(_oscGuiQProc->state()) @@ -516,10 +444,20 @@ OscIF::~OscIF() // so kill is not desirable. // We could wait until terminate finished but don't think that's good here. ///QTimer::singleShot( 5000, _oscGuiQProc, SLOT( kill() ) ); + _oscGuiQProc->waitForFinished(3000); } - //delete _oscGuiQProc; + delete _oscGuiQProc; } - + +#else // NOT _USE_QPROCESS_FOR_GUI_ + + if (_guiPid != -1) + { + if(kill(_guiPid, SIGHUP) != -1) + _guiPid = -1; + } +#endif // _USE_QPROCESS_FOR_GUI_ + if(_uiOscTarget) lo_address_free(_uiOscTarget); if(_uiOscSampleRatePath) @@ -534,23 +472,7 @@ OscIF::~OscIF() free(_uiOscProgramPath); if(_uiOscPath) free(_uiOscPath); - - //if(_oscControlFifos) - // delete[] _oscControlFifos; -} - -/* -//--------------------------------------------------------- -// oscFifo -//--------------------------------------------------------- - -OscControlFifo* OscIF::oscFifo(unsigned long i) const -{ - if(!_oscControlFifos) - return 0; - return &_oscControlFifos[i]; } -*/ //--------------------------------------------------------- // oscUpdate @@ -709,6 +631,9 @@ int OscIF::oscExiting(lo_arg**) // The gui is gone now, right? _oscGuiVisible = false; +// Just an attempt to really kill the process, an attempt to fix gui not re-showing after closing. Doesn't help. +/* +#ifdef _USE_QPROCESS_FOR_GUI_ if(_oscGuiQProc) { if(_oscGuiQProc->state()) @@ -730,10 +655,34 @@ int OscIF::oscExiting(lo_arg**) // so kill is not desirable. // We could wait until terminate finished but don't think that's good here. ///QTimer::singleShot( 5000, _oscGuiQProc, SLOT( kill() ) ); + _oscGuiQProc->waitForFinished(3000); } //delete _oscGuiQProc; + //_oscGuiQProc = 0; } - + + +#else // NOT _USE_QPROCESS_FOR_GUI_ + + if(_guiPid != -1) + { + #ifdef OSC_DEBUG + printf("OscIF::oscExiting hanging up _guiPid:%d\n", _guiPid); + #endif + //if(kill(_guiPid, SIGHUP) != -1) + //if(kill(_guiPid, SIGTERM) != -1) + if(kill(_guiPid, SIGKILL) != -1) + { + #ifdef OSC_DEBUG + printf(" hang up sent\n"); + #endif + _guiPid = -1; + } + } + +#endif // _USE_QPROCESS_FOR_GUI_ +*/ + if(_uiOscTarget) lo_address_free(_uiOscTarget); _uiOscTarget = 0; @@ -756,9 +705,6 @@ int OscIF::oscExiting(lo_arg**) free(_uiOscPath); _uiOscPath = 0; - //if(_oscControlFifos) - // delete[] _oscControlFifos; - //const DSSI_Descriptor* dssi = synth->dssi; //const LADSPA_Descriptor* ld = dssi->LADSPA_Plugin; //if(ld->deactivate) @@ -851,14 +797,22 @@ void OscIF::oscSendConfigure(const char *key, const char *val) // oscInitGui //--------------------------------------------------------- -//bool OscIF::oscInitGui() bool OscIF::oscInitGui(const QString& typ, const QString& baseName, const QString& name, const QString& label, const QString& filePath, const QString& guiPath) { // Are we already running? We don't want to allow another process do we... +#ifdef _USE_QPROCESS_FOR_GUI_ if((_oscGuiQProc != 0) && (_oscGuiQProc->state())) return true; +#else + if(_guiPid != -1) + return true; +#endif + #ifdef OSC_DEBUG + fprintf(stderr, "OscIF::oscInitGui\n"); + #endif + if(!url) { fprintf(stderr, "OscIF::oscInitGui no server url!\n"); @@ -871,198 +825,83 @@ bool OscIF::oscInitGui(const QString& typ, const QString& baseName, const QStrin return false; } - // - // start gui - // - //static char oscUrl[1024]; - //char oscUrl[1024]; QString oscUrl; - - //snprintf(oscUrl, 1024, "%s/%s/%s", url, baseName.ascii(), name.ascii()); - //snprintf(oscUrl, 1024, "%s%s/%s/%s", url, typ.toLatin1().constData(), baseName.toLatin1().constData(), name.toLatin1().constData()); - //oscUrl = QString("%1%2/%3/%4").arg(QString(QT_TRANSLATE_NOOP("@default", url))).arg(typ).arg(baseName).arg(name); oscUrl = QString("%1%2/%3/%4").arg(QString(QT_TRANSLATE_NOOP("@default", url))).arg(typ).arg(baseName).arg(label); - // Removed p4.0.19 Tim - /* - //QString guiPath(info.path() + "/" + info.baseName()); - //QString guiPath(synth->info.dirPath() + "/" + synth->info.baseName()); - QString guiPath(dirPath + "/" + baseName); + +#ifdef _USE_QPROCESS_FOR_GUI_ + + // fork + execlp cause the process to remain (zombie) after closing gui, requiring manual kill. + // Using QProcess works OK. + // No QProcess created yet? Do it now. Only once per SynthIF instance. Exists until parent destroyed. + if(_oscGuiQProc == 0) + //_oscGuiQProc = new QProcess(muse); + _oscGuiQProc = new QProcess(); + + QString program(guiPath); + QStringList arguments; + arguments << oscUrl + << filePath + << name + << QString("channel-1"); #ifdef OSC_DEBUG - fprintf(stderr, "OscIF::oscInitGui guiPath:%s\n", guiPath.toLatin1().constData()); + fprintf(stderr, "OscIF::oscInitGui starting QProcess\n"); #endif - - QDir guiDir(guiPath, "*", QDir::Unsorted, QDir::Files); - if (guiDir.exists()) + _oscGuiQProc->start(program, arguments); + + if(_oscGuiQProc->state()) { - //const QFileInfoList list = guiDir.entryInfoList(); - QStringList list = guiDir.entryList(); - - //for (int i = 0; i < list.size(); ++i) { - for (int i = 0; i < list.count(); ++i) - { - - //QFileInfo fi = list.at(i); - QFileInfo fi(guiPath + QString("/") + list[i]); - - QString gui(fi.filePath()); - if (gui.contains('_') == 0) - continue; - struct stat buf; - - //if (stat(gui.toAscii().data(), &buf)) { - if (stat(gui.toLatin1().constData(), &buf)) { - - perror("stat failed"); - continue; - } - - #ifdef OSC_DEBUG - fprintf(stderr, "OscIF::oscInitGui %s %s %s %s\n", - //fi.filePath().toAscii().data(), - //fi.fileName().toAscii().data(), - fi.filePath().toLatin1().constData(), - //fi.fileName().ascii(), - - oscUrl.toLatin1().constData(), - - //synth->info.filePath().ascii(), - filePath.toLatin1().constData(), - - //name().toAscii().data(), - //synth->name().ascii()); - name.toLatin1().constData()); - #endif - */ - - //if ((S_ISREG(buf.st_mode) || S_ISLNK(buf.st_mode)) && - // (buf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) - //{ - - // Changed by T356. - // fork + execlp were causing the processes to remain after closing gui, requiring manual kill. - // Changed to QProcess, works OK now. - //if((guiPid = fork()) == 0) - //{ - // No QProcess created yet? Do it now. Only once per SynthIF instance. Exists until parent destroyed. - if(_oscGuiQProc == 0) - //_oscGuiQProc = new QProcess(muse); - _oscGuiQProc = new QProcess(); - - //QString program(fi.filePath()); - QString program(guiPath); - QStringList arguments; - arguments << oscUrl - << filePath - << name - << QString("channel-1"); - - /* - fprintf(stderr, "OscIF::oscInitGui %s %s %s %s\n", - //fi.filePath().toAscii().data(), - //fi.fileName().toAscii().data(), - guiPath.toLatin1().constData(), - //fi.fileName().ascii(), - - oscUrl.toLatin1().constData(), - - //synth->info.filePath().ascii(), - filePath.toLatin1().constData(), - - //name().toAscii().data(), - //synth->name().ascii()); - name.toLatin1().constData()); - */ - - /* Leave out Qt3 stuff for reference - Orcan: - // Don't forget this, he he... - _oscGuiQProc->clearArguments(); - - _oscGuiQProc->addArgument(fi.filePath()); - //_oscGuiQProc->addArgument(fi.fileName()); // No conventional 'Arg0' here. - //_oscGuiQProc->addArgument(QString(oscUrl)); - _oscGuiQProc->addArgument(oscUrl); - //_oscGuiQProc->addArgument(synth->info.filePath()); - _oscGuiQProc->addArgument(filePath); - //_oscGuiQProc->addArgument(synth->name()); - _oscGuiQProc->addArgument(name); - _oscGuiQProc->addArgument(QString("channel-1")); - */ - #ifdef OSC_DEBUG - fprintf(stderr, "OscIF::oscInitGui starting QProcess\n"); - #endif - _oscGuiQProc->start(program, arguments); - - - if(_oscGuiQProc->state()) - { - #ifdef OSC_DEBUG - fprintf(stderr, "OscIF::oscInitGui started QProcess\n"); - #endif - - //guiPid = _oscGuiQProc->processIdentifier(); - } - else - { - - /* - execlp( - //fi.filePath().toAscii().data(), - //fi.fileName().toAscii().data(), - fi.filePath().ascii(), - fi.fileName().ascii(), - - oscUrl, - - //info.filePath().toAscii().data(), - //name().toAscii().data(), - synth->info.filePath().ascii(), - synth->name().ascii(), - - "channel 1", (void*)0); - */ - - fprintf(stderr, "exec %s %s %s failed: %s\n", - //fi.filePath().toAscii().data(), - //fi.fileName().toAscii().data(), - //fi.filePath().toLatin1().constData(), - guiPath.toLatin1().constData(), - //fi.fileName().toLatin1().constData(), - - oscUrl.toLatin1().constData(), - - //name().toAscii().data(), - //synth->name().ascii(), - name.toLatin1().constData(), - - strerror(errno)); - - // It's Ok, Keep going. So nothing happens. So what. The timeout in showGui will just leave. - // Maybe it's a 'busy' issue somewhere - allow to try again later + save work now. - //exit(1); + #ifdef OSC_DEBUG + fprintf(stderr, "OscIF::oscInitGui started QProcess\n"); + #endif + } + else + { + fprintf(stderr, "exec %s %s %s %s failed: %s\n", + guiPath.toLatin1().constData(), + oscUrl.toLatin1().constData(), + filePath.toLatin1().constData(), + name.toLatin1().constData(), + strerror(errno)); + //exit(1); + } + + #ifdef OSC_DEBUG + fprintf(stderr, "OscIF::oscInitGui after QProcess\n"); + #endif + +#else // NOT _USE_QPROCESS_FOR_GUI_ - } - - #ifdef OSC_DEBUG - fprintf(stderr, "OscIF::oscInitGui after QProcess\n"); - #endif - //} - //} - //} - //synth->_hasGui = true; - /* + #ifdef OSC_DEBUG + fprintf(stderr, "forking...\n"); + #endif + + QString guiName = QFileInfo(guiPath).fileName(); + // Note: fork + execlp cause the process to remain (zombie) after closing gui, requiring manual kill. Use QProcess instead. + if((_guiPid = fork()) == 0) + { + execlp( + guiPath.toLatin1().constData(), + guiName.toLatin1().constData(), + oscUrl.toLatin1().constData(), + filePath.toLatin1().constData(), + name.toLatin1().constData(), + "channel 1", (void*)0); + + // Should not return after execlp. If so it's an error. + fprintf(stderr, "exec %s %s %s %s %s failed: %s\n", + guiPath.toLatin1().constData(), + guiName.toLatin1().constData(), + oscUrl.toLatin1().constData(), + filePath.toLatin1().constData(), + name.toLatin1().constData(), + strerror(errno)); + //exit(1); } - else { - printf("OscIF::oscInitGui %s: no dir for gui found: %s\n", - //name().toAscii().data(), guiPath.toAscii().data()); - //synth->name().ascii(), guiPath.ascii()); - name.toLatin1().constData(), guiPath.toLatin1().constData()); - - //synth->_hasGui = false; - } - */ - + +#endif // _USE_QPROCESS_FOR_GUI_ + return true; } @@ -1080,8 +919,11 @@ void OscIF::oscShowGui(bool v) if (v == oscGuiVisible()) return; - //if(guiPid == -1) +#ifdef _USE_QPROCESS_FOR_GUI_ if((_oscGuiQProc == 0) || (!_oscGuiQProc->state())) +#else + if(_guiPid == -1) +#endif { // We need an indicator that update was called - update must have been called to get new path etc... // If the process is not running this path is invalid, right? @@ -1138,19 +980,9 @@ bool OscIF::oscGuiVisible() const // oscSetSynthIF //--------------------------------------------------------- -//void OscIF::oscSetSynthIF(DssiSynthIF* s) void OscDssiIF::oscSetSynthIF(DssiSynthIF* s) { _oscSynthIF = s; - //if(_oscControlFifos) - // delete[] _oscControlFifos; - //_oscControlFifos = 0; - - //if(_oscSynthIF && _oscSynthIF->dssiSynth()) - //{ - // unsigned long ports = _oscSynthIF->dssiSynth()->inControls(); - // _oscControlFifos = new OscControlFifo[ports]; - //} } //--------------------------------------------------------- @@ -1172,58 +1004,6 @@ int OscDssiIF::oscUpdate(lo_arg **argv) if(_oscSynthIF) _oscSynthIF->oscUpdate(); - /* - if(_oscSynthIF) - { - // Send current string configuration parameters. - StringParamMap& map = _oscSynthIF->dssiSynthI()->stringParameters(); - int i = 0; - for(ciStringParamMap r = map.begin(); r != map.end(); ++r) - { - lo_send(_uiOscTarget, _uiOscConfigurePath, "ss", r->first.c_str(), r->second.c_str()); - // Avoid overloading the GUI if there are lots and lots of params. - if((i+1) % 50 == 0) - usleep(300000); - ++i; - } - - // Send current bank and program. - unsigned long bank, prog; - _oscSynthIF->dssiSynthI()->currentProg(&prog, &bank, 0); - lo_send(_uiOscTarget, _uiOscProgramPath, "ii", bank, prog); - - // Send current control values. - unsigned long ports = _oscSynthIF->dssiSynth()->inControls(); - for(unsigned long i = 0; i < ports; ++i) - { - unsigned long k = _oscSynthIF->dssiSynth()->inControlPortIdx(i); - lo_send(_uiOscTarget, _uiOscControlPath, "if", k, _oscSynthIF->getParameter(i)); - // Avoid overloading the GUI if there are lots and lots of ports. - if((i+1) % 50 == 0) - usleep(300000); - } - } - */ - - /* - char uiOscGuiPath[strlen(_uiOscPath)+6]; - sprintf(uiOscGuiPath, "%s/%s", _uiOscPath, "show"); - - #ifdef OSC_DEBUG - printf("OscIF::oscUpdate Sending show uiOscGuiPath:%s\n", uiOscGuiPath); - #endif - - lo_send(_uiOscTarget, uiOscGuiPath, ""); - - sprintf(uiOscGuiPath, "%s/%s", _uiOscPath, "hide"); - - #ifdef OSC_DEBUG - printf("OscIF::oscUpdate Sending hide uiOscGuiPath:%s\n", uiOscGuiPath); - #endif - - lo_send(_uiOscTarget, uiOscGuiPath, ""); - */ - #if 0 /* Send current bank/program (-FIX- another race...) */ if (instance->pendingProgramChange < 0) { @@ -1256,8 +1036,6 @@ int OscDssiIF::oscUpdate(lo_arg **argv) int OscDssiIF::oscConfigure(lo_arg** argv) { - //OscIF::oscConfigure(argv); - if(_oscSynthIF) _oscSynthIF->oscConfigure((const char*)&argv[0]->s, (const char*)&argv[1]->s); return 0; @@ -1269,8 +1047,6 @@ int OscDssiIF::oscConfigure(lo_arg** argv) int OscDssiIF::oscMidi(lo_arg** argv) { - //OscIF::oscMidi(argv); - if(_oscSynthIF) _oscSynthIF->oscMidi(argv[0]->m[1], argv[0]->m[2], argv[0]->m[3]); @@ -1283,8 +1059,6 @@ int OscDssiIF::oscMidi(lo_arg** argv) int OscDssiIF::oscProgram(lo_arg** argv) { - //OscIF::oscProgram(argv); - if(_oscSynthIF) _oscSynthIF->oscProgram(argv[1]->i, argv[0]->i); @@ -1297,8 +1071,6 @@ int OscDssiIF::oscProgram(lo_arg** argv) int OscDssiIF::oscControl(lo_arg** argv) { - //OscIF::oscControl(argv); - int port = argv[0]->i; if(port < 0) return 0; @@ -1319,8 +1091,7 @@ bool OscDssiIF::oscInitGui() return OscIF::oscInitGui(QT_TRANSLATE_NOOP("@default", "dssi_synth"), _oscSynthIF->dssiSynth()->baseName(), _oscSynthIF->dssiSynth()->name(), _oscSynthIF->dssiSynthI()->name(), - //_oscSynthIF->dssiSynth()->filePath(), _oscSynthIF->dssiSynth()->path()); - _oscSynthIF->dssiSynth()->fileName(), _oscSynthIF->dssi_ui_filename()); // p4.0.19 + _oscSynthIF->dssiSynth()->fileName(), _oscSynthIF->dssi_ui_filename()); } #endif // DSSI_SUPPORT @@ -1334,15 +1105,6 @@ bool OscDssiIF::oscInitGui() void OscEffectIF::oscSetPluginI(PluginI* s) { _oscPluginI = s; - //if(_oscControlFifos) - // delete[] _oscControlFifos; - //_oscControlFifos = 0; - - //if(_oscPluginI && _oscPluginI->plugin()) - //{ - // unsigned long ports = _oscPluginI->plugin()->controlInPorts(); - // _oscControlFifos = new OscControlFifo[ports]; - //} } //--------------------------------------------------------- @@ -1370,8 +1132,6 @@ int OscEffectIF::oscUpdate(lo_arg** argv) int OscEffectIF::oscConfigure(lo_arg** argv) { - //OscIF::oscConfigure(argv); - if(_oscPluginI) _oscPluginI->oscConfigure((const char*)&argv[0]->s, (const char*)&argv[1]->s); @@ -1384,8 +1144,6 @@ int OscEffectIF::oscConfigure(lo_arg** argv) int OscEffectIF::oscControl(lo_arg** argv) { - //OscIF::oscControl(argv); - int port = argv[0]->i; if(port < 0) return 0; @@ -1406,8 +1164,7 @@ bool OscEffectIF::oscInitGui() return OscIF::oscInitGui(QT_TRANSLATE_NOOP("@default", "ladspa_efx"), _oscPluginI->plugin()->lib(false), _oscPluginI->plugin()->label(), _oscPluginI->label(), - //_oscPluginI->plugin()->filePath(), _oscPluginI->plugin()->dirPath(false)); - _oscPluginI->plugin()->fileName(), _oscPluginI->dssi_ui_filename()); // p4.0.19 + _oscPluginI->plugin()->fileName(), _oscPluginI->dssi_ui_filename()); } diff --git a/muse2/muse/osc.h b/muse2/muse/osc.h index a0973ac7..8b6ba746 100644 --- a/muse2/muse/osc.h +++ b/muse2/muse/osc.h @@ -4,6 +4,7 @@ // $Id: osc.h,v 1.0.0.0 2010/04/22 10:05:00 terminator356 Exp $ // // Copyright (C) 1999-2011 by Werner Schweer and others +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License @@ -36,101 +37,10 @@ class QString; class PluginI; class OscIF; -/* -// Keep the OSC fifo small. There may be thousands of controls, and each control needs a fifo. -// Oops, no, if the user keeps adjusting a slider without releasing the mouse button, then all of the -// events are sent at once upon releasing the button, meaning there might be thousands of events at once. -#define OSC_FIFO_SIZE 512 - -//--------------------------------------------------------- -// OscControlValue -// Item struct for OscGuiControlFifo. -//--------------------------------------------------------- - -struct OscControlValue -{ - //int idx; - float value; - int frame; // Added p4.0.15 -}; - -//--------------------------------------------------------- -// OscControlFifo -// A fifo for each of the OSC controls. -//--------------------------------------------------------- - -class OscControlFifo -{ - OscControlValue fifo[OSC_FIFO_SIZE]; - volatile int size; - int wIndex; - int rIndex; - - public: - OscControlFifo() { clear(); } - bool put(const OscControlValue& event); // returns true on fifo overflow - OscControlValue get(); - const OscControlValue& peek(int n = 0); - void remove(); - bool isEmpty() const { return size == 0; } - void clear() { size = 0, wIndex = 0, rIndex = 0; } - int getSize() const { return size; } -}; -*/ - -//--------------------------------------------------------- -// OscIF -// Open Sound Control Interface -//--------------------------------------------------------- - -/* -class OscIF -{ - private: - PluginI* _oscPluginI; - - #ifdef DSSI_SUPPORT - DssiSynthIF* _oscSynthIF; - #endif - - QProcess* _oscGuiQProc; - void* _uiOscTarget; - char* _uiOscShowPath; - char* _uiOscControlPath; - char* _uiOscConfigurePath; - char* _uiOscProgramPath; - char* _uiOscPath; - bool _oscGuiVisible; - - OscControlFifo* _oscControlFifos; - - public: - OscIF(); - ~OscIF(); - - void oscSetPluginI(PluginI*); - - #ifdef DSSI_SUPPORT - void oscSetSynthIF(DssiSynthIF*); - #endif - - int oscUpdate(lo_arg**); - int oscProgram(lo_arg**); - int oscControl(lo_arg**); - int oscExiting(lo_arg**); - int oscMidi(lo_arg**); - int oscConfigure(lo_arg**); - - bool oscInitGui(); - void oscShowGui(bool); - bool oscGuiVisible() const; - OscControlFifo* oscFifo(unsigned long) const; -}; -*/ - class OscIF { protected: + pid_t _guiPid; QProcess* _oscGuiQProc; void* _uiOscTarget; char* _uiOscPath; @@ -141,8 +51,6 @@ class OscIF char* _uiOscShowPath; bool _oscGuiVisible; - //OscControlFifo* _oscControlFifos; - virtual bool oscInitGui(const QString& /*typ*/, const QString& /*baseName*/, const QString& /*name*/, const QString& /*label*/, const QString& /*filePath*/, const QString& /*guiPath*/); @@ -150,8 +58,6 @@ class OscIF OscIF(); virtual ~OscIF(); - //OscControlFifo* oscFifo(unsigned long) const; - virtual int oscUpdate(lo_arg**); virtual int oscProgram(lo_arg**) { return 0; } virtual int oscControl(lo_arg**) { return 0; } diff --git a/muse2/muse/part.h b/muse2/muse/part.h index d5b85b03..7042eedf 100644 --- a/muse2/muse/part.h +++ b/muse2/muse/part.h @@ -169,6 +169,11 @@ class PartList : public std::multimap > { void remove(Part* part); int index(Part*); Part* find(int idx); + void clearDelete() { + for (iPart i = begin(); i != end(); ++i) + delete i->second; + clear(); + } }; extern void chainClone(Part* p); diff --git a/muse2/muse/plugin.cpp b/muse2/muse/plugin.cpp index 53e3d471..7205f482 100644 --- a/muse2/muse/plugin.cpp +++ b/muse2/muse/plugin.cpp @@ -4,6 +4,7 @@ // $Id: plugin.cpp,v 1.21.2.23 2009/12/15 22:07:12 spamatica Exp $ // // (C) Copyright 2000 Werner Schweer (ws@seh.de) +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -770,6 +771,8 @@ Plugin::~Plugin() { //if(_portDescriptors) // delete[] _portDescriptors; + if(plugin) + delete plugin; } //--------------------------------------------------------- @@ -851,6 +854,8 @@ int Plugin::incReferences(int val) plugin = descr->LADSPA_Plugin; break; } + //else + // delete descr; } } else @@ -881,6 +886,8 @@ int Plugin::incReferences(int val) break; } + //else + // delete descr; } } } @@ -1106,8 +1113,10 @@ static void loadPluginLib(QFileInfo* fi) { // Make sure it doesn't already exist. if(plugins.find(fi->completeBaseName(), QString(descr->LADSPA_Plugin->Label)) != 0) + { + //delete descr; continue; - + } #ifdef PLUGIN_DEBUGIN fprintf(stderr, "loadPluginLib: dssi effect name:%s inPlaceBroken:%d\n", descr->LADSPA_Plugin->Name, LADSPA_IS_INPLACE_BROKEN(descr->LADSPA_Plugin->Properties)); #endif @@ -1120,6 +1129,8 @@ static void loadPluginLib(QFileInfo* fi) plugins.add(fi, descr->LADSPA_Plugin, true); } + //else + // delete descr; } } else @@ -1152,8 +1163,10 @@ static void loadPluginLib(QFileInfo* fi) // Make sure it doesn't already exist. if(plugins.find(fi->completeBaseName(), QString(descr->Label)) != 0) + { + //delete descr; continue; - + } #ifdef PLUGIN_DEBUGIN fprintf(stderr, "loadPluginLib: ladspa effect name:%s inPlaceBroken:%d\n", descr->Name, LADSPA_IS_INPLACE_BROKEN(descr->Properties)); #endif diff --git a/muse2/muse/plugin.h b/muse2/muse/plugin.h index 2a98760e..00144610 100644 --- a/muse2/muse/plugin.h +++ b/muse2/muse/plugin.h @@ -4,6 +4,7 @@ // $Id: plugin.h,v 1.9.2.13 2009/12/06 01:25:21 terminator356 Exp $ // // (C) Copyright 2000 Werner Schweer (ws@seh.de) +// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp index 6a43e457..a994b0e6 100644 --- a/muse2/muse/song.cpp +++ b/muse2/muse/song.cpp @@ -2341,6 +2341,8 @@ void Song::cleanupForQuit() printf("deleting midi devices except synths\n"); for(iMidiDevice imd = midiDevices.begin(); imd != midiDevices.end(); ++imd) { + // Close the device. Handy to do all devices here, including synths. + (*imd)->close(); // Since Syntis are midi devices, there's no need to delete them below. if((*imd)->isSynti()) continue; @@ -2373,11 +2375,15 @@ void Song::cleanupForQuit() continue; delete (*imi); } - midiInstruments.clear(); // midi devices + midiInstruments.clear(); // midi instruments // Nothing required for ladspa plugin list, and rack instances of them // are handled by ~AudioTrack. + if(MusEGlobal::debugMsg) + printf("Muse: Deleting sound files\n"); + SndFile::sndFiles.clearDelete(); + if(MusEGlobal::debugMsg) printf("...finished cleaning up.\n"); } diff --git a/muse2/muse/track.cpp b/muse2/muse/track.cpp index 57c4a658..18578d88 100644 --- a/muse2/muse/track.cpp +++ b/muse2/muse/track.cpp @@ -252,6 +252,11 @@ Track::Track(const Track& t, bool cloneParts) } } +Track::~Track() +{ + _parts.clearDelete(); +} + //--------------------------------------------------------- // operator = // Added by Tim. Parts' track members MUST point to this track, diff --git a/muse2/muse/track.h b/muse2/muse/track.h index 9c6aea24..f0f8ebde 100644 --- a/muse2/muse/track.h +++ b/muse2/muse/track.h @@ -104,7 +104,7 @@ class Track { Track(TrackType); //Track(const Track&); Track(const Track&, bool cloneParts); - virtual ~Track() {}; + virtual ~Track(); virtual Track& operator=(const Track& t); static const char* _cname[]; diff --git a/muse2/muse/wave.cpp b/muse2/muse/wave.cpp index 731606d3..e9fa64d2 100644 --- a/muse2/muse/wave.cpp +++ b/muse2/muse/wave.cpp @@ -90,7 +90,7 @@ SndFile::~SndFile() delete finfo; if (cache) { for (unsigned i = 0; i < channels(); ++i) - delete cache[i]; + delete [] cache[i]; delete[] cache; cache = 0; } @@ -150,7 +150,7 @@ void SndFile::readCache(const QString& path, bool showProgress) if (cache) { for (unsigned i = 0; i < channels(); ++i) - delete cache[i]; + delete [] cache[i]; delete[] cache; } if (samples() == 0) { diff --git a/muse2/muse/wave.h b/muse2/muse/wave.h index 2f97e6c5..231ed7dc 100644 --- a/muse2/muse/wave.h +++ b/muse2/muse/wave.h @@ -42,18 +42,7 @@ struct SampleV { unsigned char rms; }; -//--------------------------------------------------------- -// SndFileList -//--------------------------------------------------------- - -class SndFile; -class SndFileList : public std::list { - public: - SndFile* search(const QString& name); - }; - -typedef SndFileList::iterator iSndFile; -typedef SndFileList::const_iterator ciSndFile; +class SndFileList; //--------------------------------------------------------- // SndFile @@ -183,6 +172,23 @@ class SndFileR { }; +//--------------------------------------------------------- +// SndFileList +//--------------------------------------------------------- + +class SndFileList : public std::list { + public: + SndFile* search(const QString& name); + void clearDelete() { + for (SndFileList::iterator i = begin(); i != end(); ++i) + delete *i; + clear(); + } + }; + +typedef SndFileList::iterator iSndFile; +typedef SndFileList::const_iterator ciSndFile; + #if 0 class Clip; diff --git a/muse2/muse/widgets/canvas.cpp b/muse2/muse/widgets/canvas.cpp index c498bfd1..811561e3 100644 --- a/muse2/muse/widgets/canvas.cpp +++ b/muse2/muse/widgets/canvas.cpp @@ -82,6 +82,11 @@ Canvas::Canvas(QWidget* parent, int sx, int sy, const char* name) connect(song, SIGNAL(posChanged(int, unsigned, bool)), this, SLOT(setPos(int, unsigned, bool))); } +Canvas::~Canvas() +{ + items.clearDelete(); +} + //--------------------------------------------------------- // setPos // set one of three markers diff --git a/muse2/muse/widgets/canvas.h b/muse2/muse/widgets/canvas.h index 553ef407..954b865d 100644 --- a/muse2/muse/widgets/canvas.h +++ b/muse2/muse/widgets/canvas.h @@ -190,6 +190,7 @@ class Canvas : public View { void horizontalZoomOut(); public: Canvas(QWidget* parent, int sx, int sy, const char* name = 0); + virtual ~Canvas(); bool isSingleSelection(); int selectionSize(); Tool tool() const { return _tool; } diff --git a/muse2/muse/widgets/citem.h b/muse2/muse/widgets/citem.h index bdeca213..e2ddd8a0 100644 --- a/muse2/muse/widgets/citem.h +++ b/muse2/muse/widgets/citem.h @@ -101,6 +101,11 @@ class CItemList: public std::multimap > { public: void add(CItem*); CItem* find(const QPoint& pos) const; + void clearDelete() { + for (iCItem i = begin(); i != end(); ++i) + delete i->second; + clear(); + } }; } // namespace MusEWidget diff --git a/muse2/muse/widgets/scrollscale.cpp b/muse2/muse/widgets/scrollscale.cpp index e7d40f67..572a1d86 100644 --- a/muse2/muse/widgets/scrollscale.cpp +++ b/muse2/muse/widgets/scrollscale.cpp @@ -224,6 +224,7 @@ ScrollScale::ScrollScale ( int s1, int s2, int cs, int max_, Qt::Orientation o, down = 0; logbase = bas; invers = inv; + scaleVal = 0; double min, max; if ( scaleMin < 0 ) diff --git a/muse2/muse/widgets/siglabel.cpp b/muse2/muse/widgets/siglabel.cpp index 9916bd0a..f571c2f1 100644 --- a/muse2/muse/widgets/siglabel.cpp +++ b/muse2/muse/widgets/siglabel.cpp @@ -43,12 +43,12 @@ namespace MusEWidget { // edit Signature Values (4/4) //--------------------------------------------------------- -SigLabel::SigLabel(int z, int n, QWidget* parent) : QLabel(parent) +SigLabel::SigLabel(int zz, int nn, QWidget* parent) : QLabel(parent) { - z = n = 0; + z = n = 0; setFocusPolicy(Qt::NoFocus); setAlignment(Qt::AlignCenter); - setValue(z, n); + setValue(zz, nn); } SigLabel::SigLabel(const AL::TimeSignature& sig, QWidget* parent) : QLabel(parent) diff --git a/muse2/muse/widgets/tools.cpp b/muse2/muse/widgets/tools.cpp index ccd0f89b..113de6c4 100644 --- a/muse2/muse/widgets/tools.cpp +++ b/muse2/muse/widgets/tools.cpp @@ -129,7 +129,7 @@ void EditToolBar::toolChanged(QAction* action) EditToolBar::~EditToolBar() { - delete actions; + delete [] actions; } //--------------------------------------------------------- diff --git a/muse2/muse/widgets/visibletracks.cpp b/muse2/muse/widgets/visibletracks.cpp index 1b549975..7e56bb36 100644 --- a/muse2/muse/widgets/visibletracks.cpp +++ b/muse2/muse/widgets/visibletracks.cpp @@ -139,7 +139,7 @@ void VisibleTracks::visibilityChanged(QAction* action) VisibleTracks::~VisibleTracks() { - delete actions; + delete [] actions; } } // namespace MusEWidget diff --git a/muse2/synti/fluidsynth/fluidsynti.cpp b/muse2/synti/fluidsynth/fluidsynti.cpp index a03c5da8..cc5c496a 100644 --- a/muse2/synti/fluidsynth/fluidsynti.cpp +++ b/muse2/synti/fluidsynth/fluidsynti.cpp @@ -115,6 +115,17 @@ FluidSynth::FluidSynth(int sr, pthread_mutex_t *_Globalsfloader_mutex) : Mess(2) FluidSynth::~FluidSynth() { + + for (std::list::iterator it =stack.begin(); it !=stack.end(); it++) + { + if(it->intid == FS_UNSPECIFIED_FONT || it->intid == FS_UNSPECIFIED_ID) + continue; + //Try to unload soundfont + int err = fluid_synth_sfunload(fluidsynth, it->intid, 0); + if(err == -1) + std::cerr << DEBUG_ARGS << "Error unloading soundfont!" << fluid_synth_error(fluidsynth) << std::endl; + } + int err = delete_fluid_synth (fluidsynth); if(gui) delete gui; -- cgit v1.2.3