annotate layer/LogNumericalScale.cpp @ 1204:d421df27e184 3.0-integration

Further PropertyBox layout overhaul: avoid crash (/ assertion failure) when property type changes from e.g. colour to colourmap, by replacing the existing widget within the layout rather than trying to repopulate it
author Chris Cannam
date Tue, 20 Dec 2016 10:49:24 +0000
parents 5144d7185fb5
children cdaeff1858af
rev   line source
Chris@696 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@696 2
Chris@696 3 /*
Chris@696 4 Sonic Visualiser
Chris@696 5 An audio file viewer and annotation editor.
Chris@696 6 Centre for Digital Music, Queen Mary, University of London.
Chris@696 7 This file copyright 2006-2013 Chris Cannam and QMUL.
Chris@696 8
Chris@696 9 This program is free software; you can redistribute it and/or
Chris@696 10 modify it under the terms of the GNU General Public License as
Chris@696 11 published by the Free Software Foundation; either version 2 of the
Chris@696 12 License, or (at your option) any later version. See the file
Chris@696 13 COPYING included with this distribution for more information.
Chris@696 14 */
Chris@696 15
Chris@696 16 #include "LogNumericalScale.h"
Chris@696 17 #include "VerticalScaleLayer.h"
Chris@696 18
Chris@696 19 #include "base/LogRange.h"
Chris@696 20
Chris@696 21 #include <QPainter>
Chris@696 22
Chris@696 23 #include <cmath>
Chris@696 24
Chris@1077 25 #include "LayerGeometryProvider.h"
Chris@696 26
Chris@696 27 //#define DEBUG_TIME_VALUE_LAYER 1
Chris@696 28
Chris@696 29 int
Chris@918 30 LogNumericalScale::getWidth(LayerGeometryProvider *,
Chris@696 31 QPainter &paint)
Chris@696 32 {
Chris@699 33 return paint.fontMetrics().width("-000.00") + 10;
Chris@696 34 }
Chris@696 35
Chris@696 36 void
Chris@918 37 LogNumericalScale::paintVertical(LayerGeometryProvider *v,
Chris@696 38 const VerticalScaleLayer *layer,
Chris@696 39 QPainter &paint,
Chris@696 40 int x0,
Chris@904 41 double minlog,
Chris@904 42 double maxlog)
Chris@696 43 {
Chris@696 44 int w = getWidth(v, paint) + x0;
Chris@696 45
Chris@696 46 int n = 10;
Chris@696 47
Chris@904 48 double val = minlog;
Chris@904 49 double inc = (maxlog - val) / n; // even increments of log scale
Chris@696 50
Chris@696 51 // smallest increment as displayed
Chris@904 52 double minDispInc = LogRange::unmap(minlog + inc) - LogRange::unmap(minlog);
Chris@696 53
Chris@696 54 #ifdef DEBUG_TIME_VALUE_LAYER
Chris@696 55 cerr << "min = " << minlog << ", max = " << maxlog << ", inc = " << inc << ", minDispInc = " << minDispInc << endl;
Chris@696 56 #endif
Chris@696 57
Chris@864 58 const int buflen = 40;
Chris@864 59 char buffer[buflen];
Chris@696 60
Chris@904 61 double round = 1.f;
Chris@696 62 int dp = 0;
Chris@696 63
Chris@696 64 if (minDispInc > 0) {
Chris@905 65 int prec = int(trunc(log10(minDispInc)));
Chris@696 66 if (prec < 0) dp = -prec;
Chris@905 67 round = pow(10.0, prec);
Chris@704 68 if (dp > 4) dp = 4;
Chris@696 69 #ifdef DEBUG_TIME_VALUE_LAYER
Chris@696 70 cerr << "round = " << round << ", prec = " << prec << ", dp = " << dp << endl;
Chris@696 71 #endif
Chris@696 72 }
Chris@696 73
Chris@696 74 int prevy = -1;
Chris@696 75
Chris@696 76 for (int i = 0; i < n; ++i) {
Chris@696 77
Chris@696 78 int y, ty;
Chris@696 79 bool drawText = true;
Chris@696 80
Chris@696 81 if (i == n-1 &&
Chris@918 82 v->getPaintHeight() < paint.fontMetrics().height() * (n*2)) {
Chris@696 83 if (layer->getScaleUnits() != "") drawText = false;
Chris@696 84 }
Chris@696 85
Chris@904 86 double dispval = LogRange::unmap(val);
Chris@696 87 dispval = floor(dispval / round) * round;
Chris@696 88
Chris@696 89 #ifdef DEBUG_TIME_VALUE_LAYER
Chris@696 90 cerr << "val = " << val << ", dispval = " << dispval << endl;
Chris@696 91 #endif
Chris@696 92
Chris@696 93 y = layer->getYForValue(v, dispval);
Chris@696 94
Chris@696 95 ty = y - paint.fontMetrics().height() + paint.fontMetrics().ascent() + 2;
Chris@696 96
Chris@696 97 if (prevy >= 0 && (prevy - y) < paint.fontMetrics().height()) {
Chris@696 98 val += inc;
Chris@696 99 continue;
Chris@696 100 }
Chris@696 101
Chris@905 102 int digits = int(trunc(log10(dispval)));
Chris@696 103 int sf = dp + (digits > 0 ? digits : 0);
Chris@696 104 if (sf < 4) sf = 4;
Chris@704 105 #ifdef DEBUG_TIME_VALUE_LAYER
Chris@704 106 cerr << "sf = " << sf << endl;
Chris@704 107 #endif
Chris@864 108 snprintf(buffer, buflen, "%.*g", sf, dispval);
Chris@696 109
Chris@696 110 QString label = QString(buffer);
Chris@696 111
Chris@696 112 paint.drawLine(w - 5, y, w, y);
Chris@696 113
Chris@696 114 if (drawText) {
Chris@696 115 paint.drawText(w - paint.fontMetrics().width(label) - 6,
Chris@696 116 ty, label);
Chris@696 117 }
Chris@696 118
Chris@696 119 prevy = y;
Chris@696 120 val += inc;
Chris@696 121 }
Chris@696 122 }