27
50
setBackgroundRole(QPalette::NoRole);
28
51
setAttribute(Qt::WA_NoSystemBackground);
29
52
setAttribute(Qt::WA_StaticContents);
30
// This is absolutely required for speed! Otherwise painfully slow because we get
31
// full rect paint events even on small scrolls! See help on QPainter::scroll().
32
setAttribute(Qt::WA_OpaquePaintEvent);
53
// This is absolutely required for speed! Otherwise painfully slow because of full background
54
// filling, even when requesting small udpdates! Background is drawn by us. (Just small corners.)
55
setAttribute(Qt::WA_OpaquePaintEvent);
56
//setFrameStyle(QFrame::Raised | QFrame::StyledPanel);
60
cur_yv = -1; // Flag as -1 to initialize in paint.
38
minScale = mtype == DBMeter ? config.minMeter : 0.0; // min value in dB or int
66
minScale = mtype == DBMeter ? MusEGlobal::config.minMeter : 0.0; // min value in dB or int
39
67
maxScale = mtype == DBMeter ? 10.0 : 127.0;
43
71
setMidLineWidth(0);
77
dark_red_end = QColor(0x8e0000);
78
dark_red_begin = QColor(0x8e3800);
80
dark_yellow_end = QColor(0x8e6800);
81
dark_yellow_center = QColor(0x8e8e00);
82
dark_yellow_begin = QColor(0x6a8400);
84
dark_green_end = QColor(0x467800);
85
dark_green_begin = QColor(0x007000);
87
light_red_end = QColor(0xff0000);
88
light_red_begin = QColor(0xdd8800);
90
light_yellow_end = QColor(0xddcc00);
91
light_yellow_center = QColor(0xffff00);
92
light_yellow_begin = QColor(0xddff00);
94
light_green_end = QColor(0x88ff00);
95
light_green_begin = QColor(0x00ff00);
97
mask_center = QColor(225, 225, 225, 64);
98
mask_edge = QColor(30, 30, 30, 64);
100
separator_color = QColor(0x666666);
101
peak_color = QColor(0xeeeeee);
103
darkGradGreen.setColorAt(1, dark_green_begin);
104
darkGradGreen.setColorAt(0, dark_green_end);
106
darkGradYellow.setColorAt(1, dark_yellow_begin);
107
darkGradYellow.setColorAt(0.5, dark_yellow_center);
108
darkGradYellow.setColorAt(0, dark_yellow_end);
110
darkGradRed.setColorAt(1, dark_red_begin);
111
darkGradRed.setColorAt(0, dark_red_end);
113
lightGradGreen.setColorAt(1, light_green_begin);
114
lightGradGreen.setColorAt(0, light_green_end);
116
lightGradYellow.setColorAt(1, light_yellow_begin);
117
lightGradYellow.setColorAt(0.5, light_yellow_center);
118
lightGradYellow.setColorAt(0, light_yellow_end);
120
lightGradRed.setColorAt(1, light_red_begin);
121
lightGradRed.setColorAt(0, light_red_end);
123
maskGrad.setColorAt(0, mask_edge);
124
maskGrad.setColorAt(0.5, mask_center);
125
maskGrad.setColorAt(1, mask_edge);
46
129
//---------------------------------------------------------
107
228
//---------------------------------------------------------
109
void Meter::paintEvent(QPaintEvent* /*ev*/)
230
void Meter::paintEvent(QPaintEvent* ev)
111
// TODO: Could make better use of event rectangle, for speed.
232
// For some reason upon resizing we get double calls here and in resizeEvent.
113
234
QPainter p(this);
235
p.setRenderHint(QPainter::Antialiasing);
115
237
double range = maxScale - minScale;
117
238
int fw = frameWidth();
118
239
int w = width() - 2*fw;
119
240
int h = height() - 2*fw;
241
const QRect& rect = ev->rect();
242
//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);
244
QPainterPath drawingPath, updatePath, finalPath, cornerPath;
245
//bool updFull = false;
123
yv = val == 0 ? h : int(((maxScale - (fast_log10(val) * 20.0)) * h)/range);
247
// Initialize. Can't do in ctor, must be done after layouts have been done. Most reliable to do it here.
252
cur_yv = val == 0 ? h : int(((maxScale - (MusECore::fast_log10(val) * 20.0)) * h)/range);
253
cur_ymax = maxVal == 0 ? fw : int(((maxScale - (MusECore::fast_log10(maxVal) * 20.0)) * h)/range);
257
cur_yv = val == 0 ? h : int(((maxScale - val) * h)/range);
258
cur_ymax = maxVal == 0 ? fw : int(((maxScale - maxVal) * h)/range);
260
if(cur_yv > h) cur_yv = h;
262
if(cur_ymax > h) cur_ymax = h;
263
last_ymax = cur_ymax;
265
updatePath.addRect(fw, fw, w, h); // Update the whole thing
125
yv = val == 0 ? h : int(((maxScale - val) * h)/range);
268
updatePath.addRect(rect.x(), rect.y(), rect.width(), rect.height()); // Update only the requested rectangle
270
drawingPath.addRoundedRect(fw, fw, w, h, xrad, yrad); // The actual desired shape of the meter
271
finalPath = drawingPath & updatePath;
273
// Draw corners as normal background colour.
274
cornerPath = updatePath - finalPath; // Elegantly simple. Path subtraction! Wee...
275
if(!cornerPath.isEmpty())
276
p.fillPath(cornerPath, palette().window());
279
p.setClipPath(finalPath); // Meh, nice but not so good. Clips at edge so antialising has no effect! Can it be done ?
129
282
// Draw the red, green, and yellow sections.
283
drawVU(p, rect, finalPath, cur_yv);
132
285
// Draw the peak white line.
135
ymax = maxVal == 0 ? 0 : int(((maxScale - (fast_log10(maxVal) * 20.0)) * h)/range);
137
ymax = maxVal == 0 ? 0 : int(((maxScale - maxVal) * h)/range);
139
p.drawLine(0, ymax, w, ymax);
286
//if(updFull || (cur_ymax >= rect.y() && cur_ymax < rect.height()))
288
p.setRenderHint(QPainter::Antialiasing, false); // No antialiasing. Makes the line fuzzy, double height, or not visible at all.
290
//p.setPen(peak_color);
291
//p.drawLine(fw, cur_ymax, w, cur_ymax); // Undesirable. Draws outside the top rounded corners.
293
//QPainterPath path; path.moveTo(fw, cur_ymax); path.lineTo(w, cur_ymax); // ? Didn't work. No line at all.
294
//p.drawPath(path & finalPath);
295
QPainterPath path; path.addRect(fw, cur_ymax, w, 1); path &= finalPath;
297
p.fillPath(path, QBrush(peak_color));
300
// Draw the transparent layer on top of everything to give a 3d look
301
p.setRenderHint(QPainter::Antialiasing);
302
maskGrad.setStart(QPointF(fw, fw));
303
maskGrad.setFinalStop(QPointF(w, fw));
305
p.fillRect(rect, QBrush(maskGrad));
307
//QPainterPath path; path.addRect(fw, fw, w);
308
//p.fillPath(finalPath & path, QBrush(maskGrad));
309
p.fillPath(finalPath, QBrush(maskGrad));
142
314
//---------------------------------------------------------
144
316
//---------------------------------------------------------
146
void Meter::drawVU(QPainter& p, int w, int h, int yv)
318
void Meter::drawVU(QPainter& p, const QRect& rect, const QPainterPath& drawPath, int yv)
320
int fw = frameWidth();
321
int w = width() - 2*fw;
322
int h = height() - 2*fw;
324
// Test OK. We are passed small rectangles on small value changes.
325
//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);
327
QRect pr(0, 0, w, 0);
328
if(mtype == DBMeter) // Meter type is dB...
150
330
double range = maxScale - minScale;
151
331
int y1 = int((maxScale - redScale) * h / range);
152
332
int y2 = int((maxScale - yellowScale) * h / range);
334
darkGradGreen.setStart(QPointF(fw, y2));
335
darkGradGreen.setFinalStop(QPointF(fw, h));
336
darkGradYellow.setStart(QPointF(fw, y1));
337
darkGradYellow.setFinalStop(QPointF(fw, y2));
338
darkGradRed.setStart(QPointF(fw, fw));
339
darkGradRed.setFinalStop(QPointF(fw, y1));
341
lightGradGreen.setStart(QPointF(fw, y2));
342
lightGradGreen.setFinalStop(QPointF(fw, h));
343
lightGradYellow.setStart(QPointF(fw, y1));
344
lightGradYellow.setFinalStop(QPointF(fw, y2));
345
lightGradRed.setStart(QPointF(fw, fw));
346
lightGradRed.setFinalStop(QPointF(fw, y1));
157
p.fillRect(0, 0, w, yv, QBrush(0x8e0000)); // dark red
158
p.fillRect(0, yv, w, y1-yv, QBrush(0xff0000)); // light red
352
pr.setTop(fw); pr.setHeight(yv);
353
p.fillRect(pr, QBrush(darkGradRed)); // dark red
354
pr.setTop(yv); pr.setHeight(y1-yv);
355
p.fillRect(pr & rect, QBrush(lightGradRed)); // light red
160
357
// Yellow section:
161
p.fillRect(0, y1, w, y2-y1, QBrush(0xffff00)); // light yellow
358
pr.setTop(y1); pr.setHeight(y2-y1);
359
p.fillRect(pr & rect, QBrush(lightGradYellow)); // light yellow
163
361
// Green section:
164
p.fillRect(0, y2, w, h-y2, QBrush(0x00ff00)); // light green
362
pr.setTop(y2); pr.setHeight(h-y2);
363
p.fillRect(pr & rect, QBrush(lightGradGreen)); // light green
170
p.fillRect(0, 0, w, y1, QBrush(0x8e0000)); // dark red
369
pr.setTop(fw); pr.setHeight(y1);
370
p.fillRect(pr & rect, QBrush(darkGradRed)); // dark red
172
372
// Yellow section:
173
p.fillRect(0, y1, w, yv-y1, QBrush(0x8e8e00)); // dark yellow
174
p.fillRect(0, yv, w, y2-yv, QBrush(0xffff00)); // light yellow
373
pr.setTop(y1); pr.setHeight(yv-y1);
374
p.fillRect(pr & rect, QBrush(darkGradYellow)); // dark yellow
375
pr.setTop(yv); pr.setHeight(y2-yv);
376
p.fillRect(pr & rect, QBrush(lightGradYellow)); // light yellow
176
378
// Green section:
177
p.fillRect(0, y2, w, h-y2, QBrush(0x00ff00)); // light green
379
pr.setTop(y2); pr.setHeight(h-y2);
380
p.fillRect(pr & rect, QBrush(lightGradGreen)); // light green
183
p.fillRect(0, 0, w, y1, QBrush(0x8e0000)); // dark red
386
pr.setTop(fw); pr.setHeight(y1);
387
p.fillRect(pr & rect, QBrush(darkGradRed)); // dark red
185
389
// Yellow section:
186
p.fillRect(0, y1, w, y2-y1, QBrush(0x8e8e00)); // dark yellow
390
pr.setTop(y1); pr.setHeight(y2-y1);
391
p.fillRect(pr & rect, QBrush(darkGradYellow)); // dark yellow
188
393
// Green section:
189
p.fillRect(0, y2, w, yv-y2, QBrush(0x007000)); // dark green
190
p.fillRect(0, yv, w, h-yv, QBrush(0x00ff00)); // light green
394
pr.setTop(y2); pr.setHeight(yv-y2);
395
p.fillRect(pr & rect, QBrush(darkGradGreen)); // dark green
396
pr.setTop(yv); pr.setHeight(h-yv);
397
p.fillRect(pr & rect, QBrush(lightGradGreen)); // light green
400
else // Meter type is linear...
195
p.fillRect(0, 0, w, yv, QBrush(0x007000)); // dark green
196
p.fillRect(0, yv, w, h-yv, QBrush(0x00ff00)); // light green
402
pr.setTop(fw); pr.setHeight(yv);
403
p.fillRect(pr & rect, QBrush(darkGradGreen)); // dark green
404
pr.setTop(yv); pr.setHeight(h-yv);
405
p.fillRect(pr & rect, QBrush(lightGradGreen)); // light green
408
#else // NOT _USE_CLIPPER
414
QPainterPath path; path.addRect(fw, fw, w, yv); path &= drawPath;
416
p.fillPath(path, QBrush(darkGradRed)); // dark red
419
QPainterPath path; path.addRect(fw, yv, w, y1-yv); path &= drawPath;
421
p.fillPath(path, QBrush(lightGradRed)); // light red
426
QPainterPath path; path.addRect(fw, y1, w, y2-y1); path &= drawPath;
428
p.fillPath(path, QBrush(lightGradYellow)); // light yellow
433
QPainterPath path; path.addRect(fw, y2, w, h-y2); path &= drawPath;
435
p.fillPath(path, QBrush(lightGradGreen)); // light green
443
QPainterPath path; path.addRect(fw, fw, w, y1); path &= drawPath;
445
p.fillPath(path, QBrush(darkGradRed)); // dark red
450
QPainterPath path; path.addRect(fw, y1, w, yv-y1); path &= drawPath;
452
p.fillPath(path, QBrush(darkGradYellow)); // dark yellow
455
QPainterPath path; path.addRect(fw, yv, w, y2-yv); path &= drawPath;
457
p.fillPath(path, QBrush(lightGradYellow)); // light yellow
462
QPainterPath path; path.addRect(fw, y2, w, h-y2); path &= drawPath;
464
p.fillPath(path, QBrush(lightGradGreen)); // light green
472
QPainterPath path; path.addRect(fw, fw, w, y1); path &= drawPath;
474
p.fillPath(path, QBrush(darkGradRed)); // dark red
479
QPainterPath path; path.addRect(fw, y1, w, y2-y1); path &= drawPath;
481
p.fillPath(path, QBrush(darkGradYellow)); // dark yellow
486
QPainterPath path; path.addRect(fw, y2, w, yv-y2); path &= drawPath;
488
p.fillPath(path, QBrush(darkGradGreen)); // dark green
491
QPainterPath path; path.addRect(fw, yv, w, h-yv); path &= drawPath;
493
p.fillPath(path, QBrush(lightGradGreen)); // light green
499
QRect r(0, y1, w, 1); r &= rect;
501
p.fillRect(r, separator_color);
504
QRect r(0, y2, w, 1); r &= rect;
506
p.fillRect(r, separator_color);
509
else // Meter type is linear...
511
darkGradGreen.setStart(QPointF(fw, fw));
512
darkGradGreen.setFinalStop(QPointF(fw, h));
514
lightGradGreen.setStart(QPointF(fw, fw));
515
lightGradGreen.setFinalStop(QPointF(fw, h));
518
QPainterPath path; path.addRect(fw, fw, w, yv); path &= drawPath;
520
p.fillPath(path, QBrush(darkGradGreen)); // dark green
523
QPainterPath path; path.addRect(fw, yv, w, h-yv); path &= drawPath;
525
p.fillPath(path, QBrush(lightGradGreen)); // light green
529
#endif // NOT _USE_CLIPPER
200
533
//---------------------------------------------------------
202
535
//---------------------------------------------------------
204
void Meter::resizeEvent(QResizeEvent* /*ev*/)
537
void Meter::resizeEvent(QResizeEvent* ev)
539
// For some reason upon resizing we get double calls here and in paintEvent.
540
//printf("Meter::resizeEvent w:%d h:%d\n", ev->size().width(), ev->size().height());
541
cur_yv = -1; // Force re-initialization.
542
QFrame::resizeEvent(ev);
209
546
//---------------------------------------------------------