annotate layer/SingleColourLayer.cpp @ 287:cd2492c5fe45

* Add SingleColourLayer to manage colours for layers that have a single predominant colour (i.e. most of them).
author Chris Cannam
date Thu, 12 Jul 2007 16:14:59 +0000
parents
children 15b8a4bfe855
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@287 24 SingleColourLayer::ColourIndexPool
Chris@287 25 SingleColourLayer::m_usedColourIndices;
Chris@287 26
Chris@287 27 SingleColourLayer::SingleColourLayer() :
Chris@287 28 m_colour(0)
Chris@287 29 {
Chris@287 30 setDefaultColourFor(0);
Chris@287 31 }
Chris@287 32
Chris@287 33 bool
Chris@287 34 SingleColourLayer::hasLightBackground() const
Chris@287 35 {
Chris@287 36 bool dark = ColourDatabase::getInstance()->useDarkBackground(m_colour);
Chris@287 37 return !dark;
Chris@287 38 }
Chris@287 39
Chris@287 40 Layer::PropertyList
Chris@287 41 SingleColourLayer::getProperties() const
Chris@287 42 {
Chris@287 43 PropertyList list = Layer::getProperties();
Chris@287 44 list.push_back("Colour");
Chris@287 45 return list;
Chris@287 46 }
Chris@287 47
Chris@287 48 QString
Chris@287 49 SingleColourLayer::getPropertyLabel(const PropertyName &name) const
Chris@287 50 {
Chris@287 51 if (name == "Colour") return tr("Colour");
Chris@287 52 return "";
Chris@287 53 }
Chris@287 54
Chris@287 55 Layer::PropertyType
Chris@287 56 SingleColourLayer::getPropertyType(const PropertyName &name) const
Chris@287 57 {
Chris@287 58 if (name == "Colour") return ColourProperty;
Chris@287 59 return InvalidProperty;
Chris@287 60 }
Chris@287 61
Chris@287 62 QString
Chris@287 63 SingleColourLayer::getPropertyGroupName(const PropertyName &) const
Chris@287 64 {
Chris@287 65 return QString();
Chris@287 66 }
Chris@287 67
Chris@287 68 int
Chris@287 69 SingleColourLayer::getPropertyRangeAndValue(const PropertyName &name,
Chris@287 70 int *min, int *max, int *deflt) const
Chris@287 71 {
Chris@287 72 int val = 0;
Chris@287 73
Chris@287 74 int garbage0, garbage1, garbage2;
Chris@287 75 if (!min) min = &garbage0;
Chris@287 76 if (!max) max = &garbage1;
Chris@287 77 if (!deflt) deflt = &garbage2;
Chris@287 78
Chris@287 79 if (name == "Colour") {
Chris@287 80
Chris@287 81 ColourDatabase::getInstance()->getColourPropertyRange(min, max);
Chris@287 82 *deflt = 0; //!!!
Chris@287 83
Chris@287 84 val = m_colour;
Chris@287 85
Chris@287 86 } else {
Chris@287 87 val = Layer::getPropertyRangeAndValue(name, min, max, deflt);
Chris@287 88 }
Chris@287 89
Chris@287 90 return val;
Chris@287 91 }
Chris@287 92
Chris@287 93 QString
Chris@287 94 SingleColourLayer::getPropertyValueLabel(const PropertyName &name,
Chris@287 95 int value) const
Chris@287 96 {
Chris@287 97 if (name == "Colour") {
Chris@287 98 return Layer::getPropertyValueLabel(name, value);
Chris@287 99 }
Chris@287 100 return tr("<unknown>");
Chris@287 101 }
Chris@287 102
Chris@287 103 RangeMapper *
Chris@287 104 SingleColourLayer::getNewPropertyRangeMapper(const PropertyName &) const
Chris@287 105 {
Chris@287 106 return 0;
Chris@287 107 }
Chris@287 108
Chris@287 109 void
Chris@287 110 SingleColourLayer::setProperty(const PropertyName &name, int value)
Chris@287 111 {
Chris@287 112 if (name == "Colour") {
Chris@287 113 setBaseColour(value);
Chris@287 114 }
Chris@287 115 }
Chris@287 116
Chris@287 117 void
Chris@287 118 SingleColourLayer::setDefaultColourFor(View *v)
Chris@287 119 {
Chris@287 120 bool dark = false;
Chris@287 121 if (v) {
Chris@287 122 ColourIndexPool::iterator i = m_usedColourIndices.find(m_colour);
Chris@287 123 if (i != m_usedColourIndices.end()) m_usedColourIndices.erase(i);
Chris@287 124 dark = !v->hasLightBackground();
Chris@287 125 } else {
Chris@287 126 QColor bg = QApplication::palette().color(QPalette::Window);
Chris@287 127 if (bg.red() + bg.green() + bg.blue() < 384) dark = true;
Chris@287 128 }
Chris@287 129
Chris@287 130 m_colour = -1;
Chris@287 131 ColourDatabase *cdb = ColourDatabase::getInstance();
Chris@287 132
Chris@287 133 int hint = -1;
Chris@287 134 bool impose = false;
Chris@287 135 if (v) {
Chris@287 136 // We don't want to call this if !v because that probably
Chris@287 137 // means we're being called from the constructor, and this is
Chris@287 138 // a virtual function
Chris@287 139 hint = getDefaultColourHint(dark, impose);
Chris@287 140 std::cerr << "hint = " << hint << ", impose = " << impose << std::endl;
Chris@287 141 }
Chris@287 142
Chris@287 143 if (hint >= 0 && impose) {
Chris@287 144 m_colour = hint;
Chris@287 145 m_usedColourIndices.insert(m_colour);
Chris@287 146 return;
Chris@287 147 }
Chris@287 148
Chris@287 149 for (int i = 0; i < cdb->getColourCount(); ++i) {
Chris@287 150 int index = i;
Chris@287 151 if (hint > 0) index = (index + hint) % cdb->getColourCount();
Chris@287 152 if (cdb->useDarkBackground(index) != dark) continue;
Chris@287 153 if (m_colour < 0) m_colour = index;
Chris@287 154 if (m_usedColourIndices.find(index) == m_usedColourIndices.end()) {
Chris@287 155 m_colour = index;
Chris@287 156 break;
Chris@287 157 }
Chris@287 158 }
Chris@287 159
Chris@287 160 if (m_colour < 0) m_colour = 0;
Chris@287 161 m_usedColourIndices.insert(m_colour);
Chris@287 162 }
Chris@287 163
Chris@287 164 void
Chris@287 165 SingleColourLayer::setBaseColour(int colour)
Chris@287 166 {
Chris@287 167 if (m_colour == colour) return;
Chris@287 168 ColourIndexPool::iterator i = m_usedColourIndices.find(m_colour);
Chris@287 169 if (i != m_usedColourIndices.end()) m_usedColourIndices.erase(i);
Chris@287 170 m_colour = colour;
Chris@287 171 m_usedColourIndices.insert(m_colour);
Chris@287 172 flagBaseColourChanged();
Chris@287 173 emit layerParametersChanged();
Chris@287 174 }
Chris@287 175
Chris@287 176 int
Chris@287 177 SingleColourLayer::getBaseColour() const
Chris@287 178 {
Chris@287 179 return m_colour;
Chris@287 180 }
Chris@287 181
Chris@287 182 QColor
Chris@287 183 SingleColourLayer::getBaseQColor() const
Chris@287 184 {
Chris@287 185 return ColourDatabase::getInstance()->getColour(m_colour);
Chris@287 186 }
Chris@287 187
Chris@287 188 QColor
Chris@287 189 SingleColourLayer::getBackgroundQColor(View *v) const
Chris@287 190 {
Chris@287 191 return v->getBackground();
Chris@287 192 }
Chris@287 193
Chris@287 194 QColor
Chris@287 195 SingleColourLayer::getForegroundQColor(View *v) const
Chris@287 196 {
Chris@287 197 return v->getForeground();
Chris@287 198 }
Chris@287 199
Chris@287 200 std::vector<QColor>
Chris@287 201 SingleColourLayer::getPartialShades(View *v) const
Chris@287 202 {
Chris@287 203 std::vector<QColor> s;
Chris@287 204 QColor base = getBaseQColor();
Chris@287 205 QColor bg = getBackgroundQColor(v);
Chris@287 206 for (int i = 0; i < 3; ++i) {
Chris@287 207 int red = base.red() + ((bg.red() - base.red()) * (i + 1)) / 4;
Chris@287 208 int green = base.green() + ((bg.green() - base.green()) * (i + 1)) / 4;
Chris@287 209 int blue = base.blue() + ((bg.blue() - base.blue()) * (i + 1)) / 4;
Chris@287 210 s.push_back(QColor(red, green, blue));
Chris@287 211 }
Chris@287 212 return s;
Chris@287 213 }
Chris@287 214
Chris@287 215 QString
Chris@287 216 SingleColourLayer::toXmlString(QString indent, QString extraAttributes) const
Chris@287 217 {
Chris@287 218 QString s;
Chris@287 219
Chris@287 220 QString colourName, colourSpec, darkbg;
Chris@287 221 ColourDatabase::getInstance()->getStringValues
Chris@287 222 (m_colour, colourName, colourSpec, darkbg);
Chris@287 223
Chris@287 224 s += QString("colourName=\"%1\" "
Chris@287 225 "colour=\"%2\" "
Chris@287 226 "darkBackground=\"%3\" ")
Chris@287 227 .arg(colourName)
Chris@287 228 .arg(colourSpec)
Chris@287 229 .arg(darkbg);
Chris@287 230
Chris@287 231 return Layer::toXmlString(indent, extraAttributes + " " + s);
Chris@287 232 }
Chris@287 233
Chris@287 234 void
Chris@287 235 SingleColourLayer::setProperties(const QXmlAttributes &attributes)
Chris@287 236 {
Chris@287 237 QString colourName = attributes.value("colourName");
Chris@287 238 QString colourSpec = attributes.value("colour");
Chris@287 239 QString darkbg = attributes.value("darkBackground");
Chris@287 240 m_colour = ColourDatabase::getInstance()->putStringValues
Chris@287 241 (colourName, colourSpec, darkbg);
Chris@287 242 }
Chris@287 243