SingleColourLayer.cpp

Go to the documentation of this file.
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
00002 
00003 /*
00004     Sonic Visualiser
00005     An audio file viewer and annotation editor.
00006     Centre for Digital Music, Queen Mary, University of London.
00007     This file copyright 2007 QMUL.
00008     
00009     This program is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU General Public License as
00011     published by the Free Software Foundation; either version 2 of the
00012     License, or (at your option) any later version.  See the file
00013     COPYING included with this distribution for more information.
00014 */
00015 
00016 #include "SingleColourLayer.h"
00017 #include "base/ColourDatabase.h"
00018 #include "view/View.h"
00019 
00020 #include <iostream>
00021 
00022 #include <QTextStream>
00023 #include <QApplication>
00024 
00025 //#define DEBUG_COLOUR_SELECTION 1
00026 
00027 SingleColourLayer::ColourRefCount 
00028 SingleColourLayer::m_colourRefCount;
00029 
00030 SingleColourLayer::SingleColourLayer() :
00031     m_colour(0),
00032     m_colourExplicitlySet(false),
00033     m_defaultColourSet(false)
00034 {
00035     setDefaultColourFor(0);
00036 }
00037 
00038 QPixmap
00039 SingleColourLayer::getLayerPresentationPixmap(QSize size) const
00040 {
00041     return ColourDatabase::getInstance()->getExamplePixmap(m_colour, size);
00042 }
00043 
00044 bool
00045 SingleColourLayer::hasLightBackground() const
00046 {
00047     bool dark = ColourDatabase::getInstance()->useDarkBackground(m_colour);
00048     return !dark;
00049 }
00050 
00051 Layer::PropertyList
00052 SingleColourLayer::getProperties() const
00053 {
00054     PropertyList list = Layer::getProperties();
00055     list.push_back("Colour");
00056     return list;
00057 }
00058 
00059 QString
00060 SingleColourLayer::getPropertyLabel(const PropertyName &name) const
00061 {
00062     if (name == "Colour") return tr("Colour");
00063     return "";
00064 }
00065 
00066 Layer::PropertyType
00067 SingleColourLayer::getPropertyType(const PropertyName &name) const
00068 {
00069     if (name == "Colour") return ColourProperty;
00070     return InvalidProperty;
00071 }
00072 
00073 QString
00074 SingleColourLayer::getPropertyGroupName(const PropertyName &) const
00075 {
00076     return QString();
00077 }
00078 
00079 int
00080 SingleColourLayer::getPropertyRangeAndValue(const PropertyName &name,
00081                                         int *min, int *max, int *deflt) const
00082 {
00083     int val = 0;
00084 
00085     int garbage0, garbage1, garbage2;
00086     if (!min) min = &garbage0;
00087     if (!max) max = &garbage1;
00088     if (!deflt) deflt = &garbage2;
00089 
00090     if (name == "Colour") {
00091 
00092         ColourDatabase::getInstance()->getColourPropertyRange(min, max);
00093         *deflt = 0; 
00094 
00095         val = m_colour;
00096 
00097     } else {
00098         val = Layer::getPropertyRangeAndValue(name, min, max, deflt);
00099     }
00100 
00101     return val;
00102 }
00103 
00104 QString
00105 SingleColourLayer::getPropertyValueLabel(const PropertyName &name,
00106                                     int value) const
00107 {
00108     if (name == "Colour") {
00109         return Layer::getPropertyValueLabel(name, value);
00110     }
00111     return tr("<unknown>");
00112 }
00113 
00114 RangeMapper *
00115 SingleColourLayer::getNewPropertyRangeMapper(const PropertyName &) const
00116 {
00117     return 0;
00118 }
00119 
00120 void
00121 SingleColourLayer::setProperty(const PropertyName &name, int value)
00122 {
00123     if (name == "Colour") {
00124         setBaseColour(value);
00125     }
00126 }
00127 
00128 void
00129 SingleColourLayer::setDefaultColourFor(View *v)
00130 {
00131 #ifdef DEBUG_COLOUR_SELECTION
00132     std::cerr << "SingleColourLayer::setDefaultColourFor: m_colourExplicitlySet = " << m_colourExplicitlySet << ", m_defaultColourSet " << m_defaultColourSet << std::endl;
00133 #endif
00134 
00135     if (m_colourExplicitlySet || m_defaultColourSet) return;
00136 
00137     if (v) m_defaultColourSet = true; // v==0 case doesn't really count
00138 
00139     bool dark = false;
00140     if (v) {
00141         dark = !v->hasLightBackground();
00142     } else {
00143         QColor bg = QApplication::palette().color(QPalette::Window);
00144         if (bg.red() + bg.green() + bg.blue() < 384) dark = true;
00145     }
00146 
00147     ColourDatabase *cdb = ColourDatabase::getInstance();
00148 
00149     int hint = -1;
00150     bool impose = false;
00151     if (v) {
00152         if (m_colourRefCount.find(m_colour) != m_colourRefCount.end() &&
00153             m_colourRefCount[m_colour] > 0) {
00154             m_colourRefCount[m_colour]--;
00155         }
00156         // We don't want to call this if !v because that probably
00157         // means we're being called from the constructor, and this is
00158         // a virtual function
00159         hint = getDefaultColourHint(dark, impose);
00160 #ifdef DEBUG_COLOUR_SELECTION
00161         std::cerr << "hint = " << hint << ", impose = " << impose << std::endl;
00162 #endif
00163     } else {
00164 #ifdef DEBUG_COLOUR_SELECTION
00165         std::cerr << "(from ctor)" << std::endl;
00166 #endif
00167     }
00168 
00169     if (hint >= 0 && impose) {
00170         setBaseColour(hint);
00171         return;
00172     }
00173 
00174     int bestCount = 0, bestColour = -1;
00175     
00176     for (int i = 0; i < cdb->getColourCount(); ++i) {
00177 
00178         int index = i;
00179         if (hint > 0) index = (index + hint) % cdb->getColourCount();
00180         if (cdb->useDarkBackground(index) != dark) continue;
00181 
00182         int count = 0;
00183         if (m_colourRefCount.find(index) != m_colourRefCount.end()) {
00184             count = m_colourRefCount[index];
00185         }
00186 
00187 #ifdef DEBUG_COLOUR_SELECTION
00188         std::cerr << "index = " << index << ", count = " << count;
00189 #endif
00190 
00191         if (bestColour < 0 || count < bestCount) {
00192             bestColour = index;
00193             bestCount = count;
00194 #ifdef DEBUG_COLOUR_SELECTION
00195             std::cerr << " *";
00196 #endif
00197         }
00198 
00199 #ifdef DEBUG_COLOUR_SELECTION
00200         std::cerr << std::endl;
00201 #endif
00202     }
00203     
00204     if (bestColour < 0) m_colour = 0;
00205     else m_colour = bestColour;
00206 
00207     if (m_colourRefCount.find(m_colour) == m_colourRefCount.end()) {
00208         m_colourRefCount[m_colour] = 1;
00209     } else {
00210         m_colourRefCount[m_colour]++;
00211     }
00212 }
00213 
00214 void
00215 SingleColourLayer::setBaseColour(int colour)
00216 {
00217     m_colourExplicitlySet = true;
00218 
00219     if (m_colour == colour) return;
00220 
00221     if (m_colourRefCount.find(m_colour) != m_colourRefCount.end() &&
00222         m_colourRefCount[m_colour] > 0) {
00223         m_colourRefCount[m_colour]--;
00224     }
00225 
00226     m_colour = colour;
00227 
00228     if (m_colourRefCount.find(m_colour) == m_colourRefCount.end()) {
00229         m_colourRefCount[m_colour] = 1;
00230     } else {
00231         m_colourRefCount[m_colour]++;
00232     }
00233 
00234     flagBaseColourChanged();
00235     emit layerParametersChanged();
00236 }
00237 
00238 int
00239 SingleColourLayer::getBaseColour() const
00240 {
00241     return m_colour;
00242 }
00243 
00244 QColor
00245 SingleColourLayer::getBaseQColor() const
00246 {
00247     return ColourDatabase::getInstance()->getColour(m_colour);
00248 }
00249 
00250 QColor
00251 SingleColourLayer::getBackgroundQColor(View *v) const
00252 {
00253     return v->getBackground();
00254 }
00255 
00256 QColor
00257 SingleColourLayer::getForegroundQColor(View *v) const
00258 {
00259     return v->getForeground();
00260 }
00261 
00262 std::vector<QColor>
00263 SingleColourLayer::getPartialShades(View *v) const
00264 {
00265     std::vector<QColor> s;
00266     QColor base = getBaseQColor();
00267     QColor bg = getBackgroundQColor(v);
00268     for (int i = 0; i < 3; ++i) {
00269         int red = base.red() + ((bg.red() - base.red()) * (i + 1)) / 4;
00270         int green = base.green() + ((bg.green() - base.green()) * (i + 1)) / 4;
00271         int blue = base.blue() + ((bg.blue() - base.blue()) * (i + 1)) / 4;
00272         s.push_back(QColor(red, green, blue));
00273     }
00274     return s;
00275 }
00276 
00277 void
00278 SingleColourLayer::toXml(QTextStream &stream,
00279                          QString indent, QString extraAttributes) const
00280 {
00281     QString s;
00282     
00283     QString colourName, colourSpec, darkbg;
00284     ColourDatabase::getInstance()->getStringValues
00285         (m_colour, colourName, colourSpec, darkbg);
00286 
00287     s += QString("colourName=\"%1\" "
00288                  "colour=\"%2\" "
00289                  "darkBackground=\"%3\" ")
00290         .arg(colourName)
00291         .arg(colourSpec)
00292         .arg(darkbg);
00293 
00294     Layer::toXml(stream, indent, extraAttributes + " " + s);
00295 }
00296 
00297 void
00298 SingleColourLayer::setProperties(const QXmlAttributes &attributes)
00299 {
00300     QString colourName = attributes.value("colourName");
00301     QString colourSpec = attributes.value("colour");
00302     QString darkbg = attributes.value("darkBackground");
00303 
00304     int colour = ColourDatabase::getInstance()->putStringValues
00305         (colourName, colourSpec, darkbg);
00306 
00307     m_colourExplicitlySet = true;
00308 
00309     if (m_colour != colour) {
00310 
00311 #ifdef DEBUG_COLOUR_SELECTION
00312         std::cerr << "SingleColourLayer::setProperties: changing colour from " << m_colour << " to " << colour << std::endl;
00313 #endif
00314 
00315         if (m_colourRefCount.find(m_colour) != m_colourRefCount.end() &&
00316             m_colourRefCount[m_colour] > 0) {
00317             m_colourRefCount[m_colour]--;
00318         }
00319 
00320         m_colour = colour;
00321 
00322         if (m_colourRefCount.find(m_colour) == m_colourRefCount.end()) {
00323             m_colourRefCount[m_colour] = 1;
00324         } else {
00325             m_colourRefCount[m_colour]++;
00326         }
00327 
00328         flagBaseColourChanged();
00329     }
00330 }
00331 

Generated on Wed Feb 20 15:45:28 2008 for SonicVisualiser by  doxygen 1.5.1