annotate layer/SingleColourLayer.cpp @ 312:6de6f78b13a1

* Make it possible to drop audio files, layer files, session files and images onto SV panes. Need to do a bit more work on where we expect the dropped file to go, particularly in the case of audio files -- at the moment they're always opened in new panes, but it may be better to by default replace whatever is in the target pane.
author Chris Cannam
date Wed, 10 Oct 2007 15:18:02 +0000
parents 5c59c433b358
children c0b9eec70639
rev   line source
Chris@287 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@287 2
Chris@287 3 /*
Chris@287 4 Sonic Visualiser
Chris@287 5 An audio file viewer and annotation editor.
Chris@287 6 Centre for Digital Music, Queen Mary, University of London.
Chris@287 7 This file copyright 2007 QMUL.
Chris@287 8
Chris@287 9 This program is free software; you can redistribute it and/or
Chris@287 10 modify it under the terms of the GNU General Public License as
Chris@287 11 published by the Free Software Foundation; either version 2 of the
Chris@287 12 License, or (at your option) any later version. See the file
Chris@287 13 COPYING included with this distribution for more information.
Chris@287 14 */
Chris@287 15
Chris@287 16 #include "SingleColourLayer.h"
Chris@287 17 #include "base/ColourDatabase.h"
Chris@287 18 #include "view/View.h"
Chris@287 19
Chris@287 20 #include <iostream>
Chris@287 21
Chris@287 22 #include <QApplication>
Chris@287 23
Chris@293 24 SingleColourLayer::ColourRefCount
Chris@293 25 SingleColourLayer::m_colourRefCount;
Chris@287 26
Chris@287 27 SingleColourLayer::SingleColourLayer() :
Chris@294 28 m_colour(0),
Chris@294 29 m_colourExplicitlySet(false)
Chris@287 30 {
Chris@287 31 setDefaultColourFor(0);
Chris@287 32 }
Chris@287 33
Chris@299 34 QPixmap
Chris@299 35 SingleColourLayer::getLayerPresentationPixmap(QSize size) const
Chris@299 36 {
Chris@299 37 return ColourDatabase::getInstance()->getExamplePixmap(m_colour, size);
Chris@299 38 }
Chris@299 39
Chris@287 40 bool
Chris@287 41 SingleColourLayer::hasLightBackground() const
Chris@287 42 {
Chris@287 43 bool dark = ColourDatabase::getInstance()->useDarkBackground(m_colour);
Chris@287 44 return !dark;
Chris@287 45 }
Chris@287 46
Chris@287 47 Layer::PropertyList
Chris@287 48 SingleColourLayer::getProperties() const
Chris@287 49 {
Chris@287 50 PropertyList list = Layer::getProperties();
Chris@287 51 list.push_back("Colour");
Chris@287 52 return list;
Chris@287 53 }
Chris@287 54
Chris@287 55 QString
Chris@287 56 SingleColourLayer::getPropertyLabel(const PropertyName &name) const
Chris@287 57 {
Chris@287 58 if (name == "Colour") return tr("Colour");
Chris@287 59 return "";
Chris@287 60 }
Chris@287 61
Chris@287 62 Layer::PropertyType
Chris@287 63 SingleColourLayer::getPropertyType(const PropertyName &name) const
Chris@287 64 {
Chris@287 65 if (name == "Colour") return ColourProperty;
Chris@287 66 return InvalidProperty;
Chris@287 67 }
Chris@287 68
Chris@287 69 QString
Chris@287 70 SingleColourLayer::getPropertyGroupName(const PropertyName &) const
Chris@287 71 {
Chris@287 72 return QString();
Chris@287 73 }
Chris@287 74
Chris@287 75 int
Chris@287 76 SingleColourLayer::getPropertyRangeAndValue(const PropertyName &name,
Chris@287 77 int *min, int *max, int *deflt) const
Chris@287 78 {
Chris@287 79 int val = 0;
Chris@287 80
Chris@287 81 int garbage0, garbage1, garbage2;
Chris@287 82 if (!min) min = &garbage0;
Chris@287 83 if (!max) max = &garbage1;
Chris@287 84 if (!deflt) deflt = &garbage2;
Chris@287 85
Chris@287 86 if (name == "Colour") {
Chris@287 87
Chris@287 88 ColourDatabase::getInstance()->getColourPropertyRange(min, max);
Chris@287 89 *deflt = 0; //!!!
Chris@287 90
Chris@287 91 val = m_colour;
Chris@287 92
Chris@287 93 } else {
Chris@287 94 val = Layer::getPropertyRangeAndValue(name, min, max, deflt);
Chris@287 95 }
Chris@287 96
Chris@287 97 return val;
Chris@287 98 }
Chris@287 99
Chris@287 100 QString
Chris@287 101 SingleColourLayer::getPropertyValueLabel(const PropertyName &name,
Chris@287 102 int value) const
Chris@287 103 {
Chris@287 104 if (name == "Colour") {
Chris@287 105 return Layer::getPropertyValueLabel(name, value);
Chris@287 106 }
Chris@287 107 return tr("<unknown>");
Chris@287 108 }
Chris@287 109
Chris@287 110 RangeMapper *
Chris@287 111 SingleColourLayer::getNewPropertyRangeMapper(const PropertyName &) const
Chris@287 112 {
Chris@287 113 return 0;
Chris@287 114 }
Chris@287 115
Chris@287 116 void
Chris@287 117 SingleColourLayer::setProperty(const PropertyName &name, int value)
Chris@287 118 {
Chris@287 119 if (name == "Colour") {
Chris@287 120 setBaseColour(value);
Chris@287 121 }
Chris@287 122 }
Chris@287 123
Chris@287 124 void
Chris@287 125 SingleColourLayer::setDefaultColourFor(View *v)
Chris@287 126 {
Chris@294 127 if (m_colourExplicitlySet) return;
Chris@294 128
Chris@287 129 bool dark = false;
Chris@287 130 if (v) {
Chris@287 131 dark = !v->hasLightBackground();
Chris@287 132 } else {
Chris@287 133 QColor bg = QApplication::palette().color(QPalette::Window);
Chris@287 134 if (bg.red() + bg.green() + bg.blue() < 384) dark = true;
Chris@287 135 }
Chris@287 136
Chris@287 137 ColourDatabase *cdb = ColourDatabase::getInstance();
Chris@287 138
Chris@287 139 int hint = -1;
Chris@287 140 bool impose = false;
Chris@287 141 if (v) {
Chris@293 142 if (m_colourRefCount.find(m_colour) != m_colourRefCount.end() &&
Chris@293 143 m_colourRefCount[m_colour] > 0) {
Chris@293 144 m_colourRefCount[m_colour]--;
Chris@293 145 }
Chris@287 146 // We don't want to call this if !v because that probably
Chris@287 147 // means we're being called from the constructor, and this is
Chris@287 148 // a virtual function
Chris@287 149 hint = getDefaultColourHint(dark, impose);
Chris@297 150 // std::cerr << "hint = " << hint << ", impose = " << impose << std::endl;
Chris@293 151 } else {
Chris@297 152 // std::cerr << "(from ctor)" << std::endl;
Chris@287 153 }
Chris@287 154
Chris@287 155 if (hint >= 0 && impose) {
Chris@293 156 setBaseColour(hint);
Chris@287 157 return;
Chris@287 158 }
Chris@287 159
Chris@293 160 int bestCount = 0, bestColour = -1;
Chris@293 161
Chris@287 162 for (int i = 0; i < cdb->getColourCount(); ++i) {
Chris@293 163
Chris@287 164 int index = i;
Chris@287 165 if (hint > 0) index = (index + hint) % cdb->getColourCount();
Chris@287 166 if (cdb->useDarkBackground(index) != dark) continue;
Chris@293 167
Chris@293 168 int count = 0;
Chris@293 169 if (m_colourRefCount.find(index) != m_colourRefCount.end()) {
Chris@293 170 count = m_colourRefCount[index];
Chris@287 171 }
Chris@293 172
Chris@297 173 // std::cerr << "index = " << index << ", count = " << count;
Chris@293 174
Chris@293 175 if (bestColour < 0 || count < bestCount) {
Chris@293 176 bestColour = index;
Chris@293 177 bestCount = count;
Chris@297 178 // std::cerr << " *";
Chris@293 179 }
Chris@293 180
Chris@297 181 // std::cerr << std::endl;
Chris@287 182 }
Chris@293 183
Chris@293 184 if (bestColour < 0) m_colour = 0;
Chris@293 185 else m_colour = bestColour;
Chris@287 186
Chris@293 187 if (m_colourRefCount.find(m_colour) == m_colourRefCount.end()) {
Chris@293 188 m_colourRefCount[m_colour] = 1;
Chris@293 189 } else {
Chris@293 190 m_colourRefCount[m_colour]++;
Chris@293 191 }
Chris@287 192 }
Chris@287 193
Chris@287 194 void
Chris@287 195 SingleColourLayer::setBaseColour(int colour)
Chris@287 196 {
Chris@294 197 m_colourExplicitlySet = true;
Chris@294 198
Chris@287 199 if (m_colour == colour) return;
Chris@293 200
Chris@293 201 if (m_colourRefCount.find(m_colour) != m_colourRefCount.end() &&
Chris@293 202 m_colourRefCount[m_colour] > 0) {
Chris@293 203 m_colourRefCount[m_colour]--;
Chris@293 204 }
Chris@293 205
Chris@287 206 m_colour = colour;
Chris@293 207
Chris@293 208 if (m_colourRefCount.find(m_colour) == m_colourRefCount.end()) {
Chris@293 209 m_colourRefCount[m_colour] = 1;
Chris@293 210 } else {
Chris@293 211 m_colourRefCount[m_colour]++;
Chris@293 212 }
Chris@293 213
Chris@287 214 flagBaseColourChanged();
Chris@287 215 emit layerParametersChanged();
Chris@287 216 }
Chris@287 217
Chris@287 218 int
Chris@287 219 SingleColourLayer::getBaseColour() const
Chris@287 220 {
Chris@287 221 return m_colour;
Chris@287 222 }
Chris@287 223
Chris@287 224 QColor
Chris@287 225 SingleColourLayer::getBaseQColor() const
Chris@287 226 {
Chris@287 227 return ColourDatabase::getInstance()->getColour(m_colour);
Chris@287 228 }
Chris@287 229
Chris@287 230 QColor
Chris@287 231 SingleColourLayer::getBackgroundQColor(View *v) const
Chris@287 232 {
Chris@287 233 return v->getBackground();
Chris@287 234 }
Chris@287 235
Chris@287 236 QColor
Chris@287 237 SingleColourLayer::getForegroundQColor(View *v) const
Chris@287 238 {
Chris@287 239 return v->getForeground();
Chris@287 240 }
Chris@287 241
Chris@287 242 std::vector<QColor>
Chris@287 243 SingleColourLayer::getPartialShades(View *v) const
Chris@287 244 {
Chris@287 245 std::vector<QColor> s;
Chris@287 246 QColor base = getBaseQColor();
Chris@287 247 QColor bg = getBackgroundQColor(v);
Chris@287 248 for (int i = 0; i < 3; ++i) {
Chris@287 249 int red = base.red() + ((bg.red() - base.red()) * (i + 1)) / 4;
Chris@287 250 int green = base.green() + ((bg.green() - base.green()) * (i + 1)) / 4;
Chris@287 251 int blue = base.blue() + ((bg.blue() - base.blue()) * (i + 1)) / 4;
Chris@287 252 s.push_back(QColor(red, green, blue));
Chris@287 253 }
Chris@287 254 return s;
Chris@287 255 }
Chris@287 256
Chris@287 257 QString
Chris@287 258 SingleColourLayer::toXmlString(QString indent, QString extraAttributes) const
Chris@287 259 {
Chris@287 260 QString s;
Chris@287 261
Chris@287 262 QString colourName, colourSpec, darkbg;
Chris@287 263 ColourDatabase::getInstance()->getStringValues
Chris@287 264 (m_colour, colourName, colourSpec, darkbg);
Chris@287 265
Chris@287 266 s += QString("colourName=\"%1\" "
Chris@287 267 "colour=\"%2\" "
Chris@287 268 "darkBackground=\"%3\" ")
Chris@287 269 .arg(colourName)
Chris@287 270 .arg(colourSpec)
Chris@287 271 .arg(darkbg);
Chris@287 272
Chris@287 273 return Layer::toXmlString(indent, extraAttributes + " " + s);
Chris@287 274 }
Chris@287 275
Chris@287 276 void
Chris@287 277 SingleColourLayer::setProperties(const QXmlAttributes &attributes)
Chris@287 278 {
Chris@287 279 QString colourName = attributes.value("colourName");
Chris@287 280 QString colourSpec = attributes.value("colour");
Chris@287 281 QString darkbg = attributes.value("darkBackground");
Chris@296 282
Chris@296 283 int colour = ColourDatabase::getInstance()->putStringValues
Chris@287 284 (colourName, colourSpec, darkbg);
Chris@296 285
Chris@296 286 m_colourExplicitlySet = true;
Chris@296 287
Chris@296 288 if (m_colour != colour) {
Chris@296 289
Chris@296 290 std::cerr << "SingleColourLayer::setProperties: changing colour from " << m_colour << " to " << colour << std::endl;
Chris@296 291
Chris@296 292 if (m_colourRefCount.find(m_colour) != m_colourRefCount.end() &&
Chris@296 293 m_colourRefCount[m_colour] > 0) {
Chris@296 294 m_colourRefCount[m_colour]--;
Chris@296 295 }
Chris@296 296
Chris@296 297 m_colour = colour;
Chris@296 298
Chris@296 299 if (m_colourRefCount.find(m_colour) == m_colourRefCount.end()) {
Chris@296 300 m_colourRefCount[m_colour] = 1;
Chris@296 301 } else {
Chris@296 302 m_colourRefCount[m_colour]++;
Chris@296 303 }
Chris@296 304
Chris@296 305 flagBaseColourChanged();
Chris@294 306 }
Chris@287 307 }
Chris@287 308