annotate layer/PianoScale.cpp @ 1269:f2894944c6b8

Make the overlays at either end translucent, so they don't completely crop out any underlying text or necessary info (e.g. selection extents)
author Chris Cannam
date Thu, 19 Apr 2018 14:35:59 +0100
parents a34a2a25907c
children b4cb11ca8233
rev   line source
Chris@690 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@690 2
Chris@690 3 /*
Chris@690 4 Sonic Visualiser
Chris@690 5 An audio file viewer and annotation editor.
Chris@690 6 Centre for Digital Music, Queen Mary, University of London.
Chris@690 7 This file copyright 2006-2013 Chris Cannam and QMUL.
Chris@690 8
Chris@690 9 This program is free software; you can redistribute it and/or
Chris@690 10 modify it under the terms of the GNU General Public License as
Chris@690 11 published by the Free Software Foundation; either version 2 of the
Chris@690 12 License, or (at your option) any later version. See the file
Chris@690 13 COPYING included with this distribution for more information.
Chris@690 14 */
Chris@690 15
Chris@690 16 #include "PianoScale.h"
Chris@690 17
Chris@690 18 #include <QPainter>
Chris@690 19
Chris@690 20 #include <cmath>
Chris@690 21
Chris@690 22 #include "base/Pitch.h"
Chris@690 23
Chris@1077 24 #include "LayerGeometryProvider.h"
Chris@690 25
Chris@1238 26 #include <iostream>
Chris@1238 27 using namespace std;
Chris@1238 28
Chris@690 29 void
Chris@918 30 PianoScale::paintPianoVertical(LayerGeometryProvider *v,
Chris@1266 31 QPainter &paint,
Chris@1266 32 QRect r,
Chris@1266 33 double minf,
Chris@1266 34 double maxf)
Chris@690 35 {
Chris@690 36 int x0 = r.x(), y0 = r.y(), x1 = r.x() + r.width(), y1 = r.y() + r.height();
Chris@690 37
Chris@690 38 paint.drawLine(x0, y0, x0, y1);
Chris@690 39
Chris@690 40 int py = y1, ppy = y1;
Chris@690 41 paint.setBrush(paint.pen().color());
Chris@690 42
Chris@690 43 for (int i = 0; i < 128; ++i) {
Chris@690 44
Chris@1266 45 double f = Pitch::getFrequencyForPitch(i);
Chris@1266 46 int y = int(lrint(v->getYForFrequency(f, minf, maxf, true)));
Chris@690 47
Chris@1266 48 if (y < y0 - 2) break;
Chris@1266 49 if (y > y1 + 2) {
Chris@1266 50 continue;
Chris@1266 51 }
Chris@1266 52
Chris@1266 53 int n = (i % 12);
Chris@1266 54
Chris@1266 55 if (n == 1) {
Chris@1266 56 // C# -- fill the C from here
Chris@1266 57 QColor col = Qt::gray;
Chris@1266 58 if (i == 61) { // filling middle C
Chris@1266 59 col = Qt::blue;
Chris@1266 60 col = col.light(150);
Chris@1266 61 }
Chris@1266 62 if (ppy - y > 2) {
Chris@1266 63 paint.fillRect(x0 + 1,
Chris@1266 64 y,
Chris@1266 65 x1 - x0,
Chris@1266 66 (py + ppy) / 2 - y,
Chris@1266 67 col);
Chris@1266 68 }
Chris@1266 69 }
Chris@1266 70
Chris@1266 71 if (n == 1 || n == 3 || n == 6 || n == 8 || n == 10) {
Chris@1266 72 // black notes
Chris@1266 73 paint.drawLine(x0 + 1, y, x1, y);
Chris@1266 74 int rh = ((py - y) / 4) * 2;
Chris@1266 75 if (rh < 2) rh = 2;
Chris@1266 76 paint.drawRect(x0 + 1, y - (py-y)/4, (x1 - x0) / 2, rh);
Chris@1266 77 } else if (n == 0 || n == 5) {
Chris@1266 78 // C, F
Chris@1266 79 if (py < y1) {
Chris@1266 80 paint.drawLine(x0 + 1, (y + py) / 2, x1, (y + py) / 2);
Chris@1266 81 }
Chris@1266 82 }
Chris@1266 83
Chris@1266 84 ppy = py;
Chris@1266 85 py = y;
Chris@690 86 }
Chris@690 87 }
Chris@690 88
Chris@1238 89 void
Chris@1238 90 PianoScale::paintPianoHorizontal(LayerGeometryProvider *v,
Chris@1238 91 const HorizontalScaleProvider *p,
Chris@1238 92 QPainter &paint,
Chris@1238 93 QRect r)
Chris@1238 94 {
Chris@1238 95 int x0 = r.x(), y0 = r.y(), x1 = r.x() + r.width(), y1 = r.y() + r.height();
Chris@1238 96
Chris@1238 97 paint.drawLine(x0, y0, x1, y0);
Chris@1238 98
Chris@1238 99 int px = x0, ppx = x0;
Chris@1238 100 paint.setBrush(paint.pen().color());
Chris@1238 101
Chris@1238 102 for (int i = 0; i < 128; ++i) {
Chris@1238 103
Chris@1238 104 double f = Pitch::getFrequencyForPitch(i);
Chris@1238 105 int x = int(lrint(p->getXForFrequency(v, f)));
Chris@1238 106
Chris@1238 107 if (i == 0) {
Chris@1238 108 px = ppx = x;
Chris@1238 109 }
Chris@1238 110 if (i == 1) {
Chris@1238 111 ppx = px - (x - px);
Chris@1238 112 }
Chris@1238 113
Chris@1238 114 if (x < x0) {
Chris@1238 115 ppx = px;
Chris@1238 116 px = x;
Chris@1238 117 continue;
Chris@1238 118 }
Chris@1238 119
Chris@1238 120 if (x > x1) {
Chris@1238 121 break;
Chris@1238 122 }
Chris@1238 123
Chris@1238 124 int n = (i % 12);
Chris@1238 125
Chris@1238 126 if (n == 1) {
Chris@1238 127 // C# -- fill the C from here
Chris@1238 128 QColor col = Qt::gray;
Chris@1238 129 if (i == 61) { // filling middle C
Chris@1238 130 col = Qt::blue;
Chris@1238 131 col = col.light(150);
Chris@1238 132 }
Chris@1238 133 if (x - ppx > 2) {
Chris@1238 134 paint.fillRect((px + ppx) / 2 + 1,
Chris@1238 135 y0 + 1,
Chris@1238 136 x - (px + ppx) / 2 - 1,
Chris@1238 137 y1 - y0,
Chris@1238 138 col);
Chris@1238 139 }
Chris@1238 140 }
Chris@1238 141
Chris@1238 142 if (n == 1 || n == 3 || n == 6 || n == 8 || n == 10) {
Chris@1238 143 // black notes
Chris@1238 144 paint.drawLine(x, y0, x, y1);
Chris@1238 145 int rw = int(lrint(double(x - px) / 4) * 2);
Chris@1238 146 if (rw < 2) rw = 2;
Chris@1238 147 paint.drawRect(x - rw/2, (y0 + y1) / 2, rw, (y1 - y0) / 2);
Chris@1238 148 } else if (n == 0 || n == 5) {
Chris@1238 149 // C, F
Chris@1238 150 if (px < x1) {
Chris@1238 151 paint.drawLine((x + px) / 2, y0, (x + px) / 2, y1);
Chris@1238 152 }
Chris@1238 153 }
Chris@1238 154
Chris@1238 155 ppx = px;
Chris@1238 156 px = x;
Chris@1238 157 }
Chris@1238 158 }
Chris@1238 159
Chris@1238 160