annotate layer/ColourMapper.cpp @ 789:9fd1bdf214dd tonioni

Play pointer: when user drags pane during playback such that the pointer is no longer visible, accept that and stop trying to track it until pointer naturally comes back within visible area
author Chris Cannam
date Thu, 12 Jun 2014 12:48:11 +0100
parents 1a0dfcbffaf1
children 1d526ba11a24
rev   line source
Chris@376 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@376 2
Chris@376 3 /*
Chris@376 4 Sonic Visualiser
Chris@376 5 An audio file viewer and annotation editor.
Chris@376 6 Centre for Digital Music, Queen Mary, University of London.
Chris@376 7 This file copyright 2006-2007 Chris Cannam and QMUL.
Chris@376 8
Chris@376 9 This program is free software; you can redistribute it and/or
Chris@376 10 modify it under the terms of the GNU General Public License as
Chris@376 11 published by the Free Software Foundation; either version 2 of the
Chris@376 12 License, or (at your option) any later version. See the file
Chris@376 13 COPYING included with this distribution for more information.
Chris@376 14 */
Chris@376 15
Chris@376 16 #include "ColourMapper.h"
Chris@376 17
Chris@376 18 #include <iostream>
Chris@376 19
Chris@376 20 #include <cmath>
Chris@376 21
Chris@682 22 #include "base/Debug.h"
Chris@682 23
Chris@376 24 ColourMapper::ColourMapper(int map, float min, float max) :
Chris@376 25 QObject(),
Chris@376 26 m_map(map),
Chris@376 27 m_min(min),
Chris@376 28 m_max(max)
Chris@376 29 {
Chris@376 30 if (m_min == m_max) {
Chris@682 31 cerr << "WARNING: ColourMapper: min == max (== " << m_min
Chris@682 32 << "), adjusting" << endl;
Chris@376 33 m_max = m_min + 1;
Chris@376 34 }
Chris@376 35 }
Chris@376 36
Chris@376 37 ColourMapper::~ColourMapper()
Chris@376 38 {
Chris@376 39 }
Chris@376 40
Chris@376 41 int
Chris@376 42 ColourMapper::getColourMapCount()
Chris@376 43 {
Chris@536 44 return 12;
Chris@376 45 }
Chris@376 46
Chris@376 47 QString
Chris@376 48 ColourMapper::getColourMapName(int n)
Chris@376 49 {
Chris@376 50 if (n >= getColourMapCount()) return tr("<unknown>");
Chris@376 51 StandardMap map = (StandardMap)n;
Chris@376 52
Chris@376 53 switch (map) {
Chris@376 54 case DefaultColours: return tr("Default");
Chris@376 55 case WhiteOnBlack: return tr("White on Black");
Chris@376 56 case BlackOnWhite: return tr("Black on White");
Chris@376 57 case RedOnBlue: return tr("Red on Blue");
Chris@376 58 case YellowOnBlack: return tr("Yellow on Black");
Chris@376 59 case BlueOnBlack: return tr("Blue on Black");
Chris@376 60 case Sunset: return tr("Sunset");
Chris@376 61 case FruitSalad: return tr("Fruit Salad");
Chris@376 62 case Banded: return tr("Banded");
Chris@376 63 case Highlight: return tr("Highlight");
Chris@376 64 case Printer: return tr("Printer");
Chris@536 65 case HighGain: return tr("High Gain");
Chris@376 66 }
Chris@376 67
Chris@376 68 return tr("<unknown>");
Chris@376 69 }
Chris@376 70
Chris@376 71 QColor
Chris@376 72 ColourMapper::map(float value) const
Chris@376 73 {
Chris@376 74 float norm = (value - m_min) / (m_max - m_min);
Chris@376 75 if (norm < 0.f) norm = 0.f;
Chris@376 76 if (norm > 1.f) norm = 1.f;
Chris@376 77
Chris@376 78 float h = 0.f, s = 0.f, v = 0.f, r = 0.f, g = 0.f, b = 0.f;
Chris@376 79 bool hsv = true;
Chris@376 80
Chris@376 81 // float red = 0.f, green = 0.3333f;
Chris@376 82 float blue = 0.6666f, pieslice = 0.3333f;
Chris@376 83
Chris@376 84 if (m_map >= getColourMapCount()) return Qt::black;
Chris@376 85 StandardMap map = (StandardMap)m_map;
Chris@376 86
Chris@376 87 switch (map) {
Chris@376 88
Chris@376 89 case DefaultColours:
Chris@376 90 h = blue - norm * 2.f * pieslice;
Chris@376 91 s = 0.5f + norm/2.f;
Chris@376 92 v = norm;
Chris@376 93 break;
Chris@376 94
Chris@376 95 case WhiteOnBlack:
Chris@376 96 r = g = b = norm;
Chris@376 97 hsv = false;
Chris@376 98 break;
Chris@376 99
Chris@376 100 case BlackOnWhite:
Chris@376 101 r = g = b = 1.f - norm;
Chris@376 102 hsv = false;
Chris@376 103 break;
Chris@376 104
Chris@376 105 case RedOnBlue:
Chris@376 106 h = blue - pieslice/4.f + norm * (pieslice + pieslice/4.f);
Chris@376 107 s = 1.f;
Chris@376 108 v = norm;
Chris@376 109 break;
Chris@376 110
Chris@376 111 case YellowOnBlack:
Chris@376 112 h = 0.15f;
Chris@376 113 s = 1.f;
Chris@376 114 v = norm;
Chris@376 115 break;
Chris@376 116
Chris@376 117 case BlueOnBlack:
Chris@376 118 h = blue;
Chris@376 119 s = 1.f;
Chris@376 120 v = norm * 2.f;
Chris@376 121 if (v > 1.f) {
Chris@376 122 v = 1.f;
Chris@376 123 s = 1.f - (sqrtf(norm) - 0.707f) * 3.413f;
Chris@376 124 if (s < 0.f) s = 0.f;
Chris@376 125 if (s > 1.f) s = 1.f;
Chris@376 126 }
Chris@376 127 break;
Chris@376 128
Chris@376 129 case Sunset:
Chris@376 130 r = (norm - 0.24f) * 2.38f;
Chris@376 131 if (r > 1.f) r = 1.f;
Chris@376 132 if (r < 0.f) r = 0.f;
Chris@376 133 g = (norm - 0.64f) * 2.777f;
Chris@376 134 if (g > 1.f) g = 1.f;
Chris@376 135 if (g < 0.f) g = 0.f;
Chris@376 136 b = (3.6f * norm);
Chris@376 137 if (norm > 0.277f) b = 2.f - b;
Chris@376 138 if (b > 1.f) b = 1.f;
Chris@376 139 if (b < 0.f) b = 0.f;
Chris@376 140 hsv = false;
Chris@376 141 break;
Chris@376 142
Chris@376 143 case FruitSalad:
Chris@376 144 h = blue + (pieslice/6.f) - norm;
Chris@376 145 if (h < 0.f) h += 1.f;
Chris@376 146 s = 1.f;
Chris@376 147 v = 1.f;
Chris@376 148 break;
Chris@376 149
Chris@376 150 case Banded:
Chris@376 151 if (norm < 0.125) return Qt::darkGreen;
Chris@376 152 else if (norm < 0.25) return Qt::green;
Chris@376 153 else if (norm < 0.375) return Qt::darkBlue;
Chris@376 154 else if (norm < 0.5) return Qt::blue;
Chris@376 155 else if (norm < 0.625) return Qt::darkYellow;
Chris@376 156 else if (norm < 0.75) return Qt::yellow;
Chris@376 157 else if (norm < 0.875) return Qt::darkRed;
Chris@376 158 else return Qt::red;
Chris@376 159 break;
Chris@376 160
Chris@376 161 case Highlight:
Chris@376 162 if (norm > 0.99) return Qt::white;
Chris@376 163 else return Qt::darkBlue;
Chris@376 164
Chris@376 165 case Printer:
Chris@376 166 if (norm > 0.8) {
Chris@376 167 r = 1.f;
Chris@376 168 } else if (norm > 0.7) {
Chris@376 169 r = 0.9f;
Chris@376 170 } else if (norm > 0.6) {
Chris@376 171 r = 0.8f;
Chris@376 172 } else if (norm > 0.5) {
Chris@376 173 r = 0.7f;
Chris@376 174 } else if (norm > 0.4) {
Chris@376 175 r = 0.6f;
Chris@376 176 } else if (norm > 0.3) {
Chris@376 177 r = 0.5f;
Chris@376 178 } else if (norm > 0.2) {
Chris@376 179 r = 0.4f;
Chris@376 180 } else {
Chris@376 181 r = 0.f;
Chris@376 182 }
Chris@376 183 r = g = b = 1.f - r;
Chris@376 184 hsv = false;
Chris@376 185 break;
Chris@536 186
Chris@536 187 case HighGain:
Chris@536 188 if (norm <= 1.f / 256.f) {
Chris@536 189 norm = 0.f;
Chris@536 190 } else {
Chris@536 191 norm = 0.1f + (powf(((norm - 0.5f) * 2.f), 3.f) + 1.f) / 2.081f;
Chris@536 192 }
Chris@536 193 // now as for Sunset
Chris@536 194 r = (norm - 0.24f) * 2.38f;
Chris@536 195 if (r > 1.f) r = 1.f;
Chris@536 196 if (r < 0.f) r = 0.f;
Chris@536 197 g = (norm - 0.64f) * 2.777f;
Chris@536 198 if (g > 1.f) g = 1.f;
Chris@536 199 if (g < 0.f) g = 0.f;
Chris@536 200 b = (3.6f * norm);
Chris@536 201 if (norm > 0.277f) b = 2.f - b;
Chris@536 202 if (b > 1.f) b = 1.f;
Chris@536 203 if (b < 0.f) b = 0.f;
Chris@536 204 hsv = false;
Chris@536 205 /*
Chris@536 206 if (r > 1.f) r = 1.f;
Chris@536 207 r = g = b = 1.f - r;
Chris@536 208 hsv = false;
Chris@536 209 */
Chris@536 210 break;
Chris@376 211 }
Chris@376 212
Chris@376 213 if (hsv) {
Chris@376 214 return QColor::fromHsvF(h, s, v);
Chris@376 215 } else {
Chris@376 216 return QColor::fromRgbF(r, g, b);
Chris@376 217 }
Chris@376 218 }
Chris@376 219
Chris@376 220 QColor
Chris@376 221 ColourMapper::getContrastingColour() const
Chris@376 222 {
Chris@376 223 if (m_map >= getColourMapCount()) return Qt::white;
Chris@376 224 StandardMap map = (StandardMap)m_map;
Chris@376 225
Chris@376 226 switch (map) {
Chris@376 227
Chris@376 228 case DefaultColours:
Chris@376 229 return QColor(255, 150, 50);
Chris@376 230
Chris@376 231 case WhiteOnBlack:
Chris@376 232 return Qt::red;
Chris@376 233
Chris@376 234 case BlackOnWhite:
Chris@376 235 return Qt::darkGreen;
Chris@376 236
Chris@376 237 case RedOnBlue:
Chris@376 238 return Qt::green;
Chris@376 239
Chris@376 240 case YellowOnBlack:
Chris@376 241 return QColor::fromHsv(240, 255, 255);
Chris@376 242
Chris@376 243 case BlueOnBlack:
Chris@376 244 return Qt::red;
Chris@376 245
Chris@376 246 case Sunset:
Chris@376 247 return Qt::white;
Chris@376 248
Chris@376 249 case FruitSalad:
Chris@376 250 return Qt::white;
Chris@376 251
Chris@376 252 case Banded:
Chris@376 253 return Qt::cyan;
Chris@376 254
Chris@376 255 case Highlight:
Chris@376 256 return Qt::red;
Chris@376 257
Chris@376 258 case Printer:
Chris@376 259 return Qt::red;
Chris@536 260
Chris@536 261 case HighGain:
Chris@536 262 return Qt::red;
Chris@376 263 }
Chris@376 264
Chris@376 265 return Qt::white;
Chris@376 266 }
Chris@376 267
Chris@376 268 bool
Chris@376 269 ColourMapper::hasLightBackground() const
Chris@376 270 {
Chris@376 271 if (m_map >= getColourMapCount()) return false;
Chris@376 272 StandardMap map = (StandardMap)m_map;
Chris@376 273
Chris@376 274 switch (map) {
Chris@376 275
Chris@376 276 case BlackOnWhite:
Chris@376 277 case Printer:
Chris@536 278 case HighGain:
Chris@376 279 return true;
Chris@376 280
Chris@376 281 default:
Chris@376 282 return false;
Chris@376 283 }
Chris@376 284 }
Chris@376 285
Chris@376 286