svgui
1.9
|
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 "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 // Reference current colour because setDefaulColourFor 00036 // will unreference it before (possibly) changing it. 00037 refColor(); 00038 setDefaultColourFor(0); 00039 } 00040 00041 SingleColourLayer::~SingleColourLayer() 00042 { 00043 unrefColor(); 00044 } 00045 00046 QPixmap 00047 SingleColourLayer::getLayerPresentationPixmap(QSize size) const 00048 { 00049 return ColourDatabase::getInstance()->getExamplePixmap(m_colour, size); 00050 } 00051 00052 bool 00053 SingleColourLayer::hasLightBackground() const 00054 { 00055 bool dark = ColourDatabase::getInstance()->useDarkBackground(m_colour); 00056 return !dark; 00057 } 00058 00059 Layer::PropertyList 00060 SingleColourLayer::getProperties() const 00061 { 00062 PropertyList list = Layer::getProperties(); 00063 list.push_back("Colour"); 00064 return list; 00065 } 00066 00067 QString 00068 SingleColourLayer::getPropertyLabel(const PropertyName &name) const 00069 { 00070 if (name == "Colour") return tr("Colour"); 00071 return ""; 00072 } 00073 00074 Layer::PropertyType 00075 SingleColourLayer::getPropertyType(const PropertyName &name) const 00076 { 00077 if (name == "Colour") return ColourProperty; 00078 return InvalidProperty; 00079 } 00080 00081 QString 00082 SingleColourLayer::getPropertyGroupName(const PropertyName &) const 00083 { 00084 return QString(); 00085 } 00086 00087 int 00088 SingleColourLayer::getPropertyRangeAndValue(const PropertyName &name, 00089 int *min, int *max, int *deflt) const 00090 { 00091 int val = 0; 00092 00093 int garbage0, garbage1, garbage2; 00094 if (!min) min = &garbage0; 00095 if (!max) max = &garbage1; 00096 if (!deflt) deflt = &garbage2; 00097 00098 if (name == "Colour") { 00099 00100 ColourDatabase::getInstance()->getColourPropertyRange(min, max); 00101 *deflt = 0; 00102 00103 val = m_colour; 00104 00105 } else { 00106 val = Layer::getPropertyRangeAndValue(name, min, max, deflt); 00107 } 00108 00109 return val; 00110 } 00111 00112 QString 00113 SingleColourLayer::getPropertyValueLabel(const PropertyName &name, 00114 int value) const 00115 { 00116 if (name == "Colour") { 00117 ColourDatabase *db = ColourDatabase::getInstance(); 00118 if (value >= 0 && value < db->getColourCount()) { 00119 return db->getColourName(value); 00120 } 00121 } 00122 return tr("<unknown>"); 00123 } 00124 00125 RangeMapper * 00126 SingleColourLayer::getNewPropertyRangeMapper(const PropertyName &) const 00127 { 00128 return 0; 00129 } 00130 00131 void 00132 SingleColourLayer::setProperty(const PropertyName &name, int value) 00133 { 00134 if (name == "Colour") { 00135 setBaseColour(value); 00136 } 00137 } 00138 00139 void 00140 SingleColourLayer::setDefaultColourFor(View *v) 00141 { 00142 #ifdef DEBUG_COLOUR_SELECTION 00143 SVDEBUG << "SingleColourLayer::setDefaultColourFor: m_colourExplicitlySet = " << m_colourExplicitlySet << ", m_defaultColourSet " << m_defaultColourSet << endl; 00144 #endif 00145 00146 if (m_colourExplicitlySet || m_defaultColourSet) return; 00147 00148 if (v) m_defaultColourSet = true; // v==0 case doesn't really count 00149 00150 bool dark = false; 00151 if (v) { 00152 dark = !v->hasLightBackground(); 00153 } else { 00154 QColor bg = QApplication::palette().color(QPalette::Window); 00155 if (bg.red() + bg.green() + bg.blue() < 384) dark = true; 00156 } 00157 00158 ColourDatabase *cdb = ColourDatabase::getInstance(); 00159 00160 int hint = -1; 00161 bool impose = false; 00162 if (v) { 00163 // We don't want to call this if !v because that probably 00164 // means we're being called from the constructor, and this is 00165 // a virtual function 00166 hint = getDefaultColourHint(dark, impose); 00167 #ifdef DEBUG_COLOUR_SELECTION 00168 cerr << "hint = " << hint << ", impose = " << impose << endl; 00169 #endif 00170 } else { 00171 #ifdef DEBUG_COLOUR_SELECTION 00172 cerr << "(from ctor)" << endl; 00173 #endif 00174 } 00175 00176 if (hint >= 0 && impose) { 00177 setBaseColour(hint); 00178 return; 00179 } 00180 00181 unrefColor(); 00182 00183 int bestCount = 0, bestColour = -1; 00184 00185 for (int i = 0; i < cdb->getColourCount(); ++i) { 00186 00187 int index = i; 00188 if (hint > 0) index = (index + hint) % cdb->getColourCount(); 00189 if (cdb->useDarkBackground(index) != dark) continue; 00190 00191 int count = 0; 00192 if (m_colourRefCount.find(index) != m_colourRefCount.end()) { 00193 count = m_colourRefCount[index]; 00194 } 00195 00196 #ifdef DEBUG_COLOUR_SELECTION 00197 cerr << "index = " << index << ", count = " << count; 00198 #endif 00199 00200 if (bestColour < 0 || count < bestCount) { 00201 bestColour = index; 00202 bestCount = count; 00203 #ifdef DEBUG_COLOUR_SELECTION 00204 cerr << " *"; 00205 #endif 00206 } 00207 00208 #ifdef DEBUG_COLOUR_SELECTION 00209 cerr << endl; 00210 #endif 00211 } 00212 00213 if (bestColour < 0) m_colour = 0; 00214 else m_colour = bestColour; 00215 00216 refColor(); 00217 } 00218 00219 void 00220 SingleColourLayer::setBaseColour(int colour) 00221 { 00222 m_colourExplicitlySet = true; 00223 00224 if (m_colour == colour) return; 00225 00226 refColor(); 00227 m_colour = colour; 00228 unrefColor(); 00229 00230 flagBaseColourChanged(); 00231 emit layerParametersChanged(); 00232 } 00233 00234 int 00235 SingleColourLayer::getBaseColour() const 00236 { 00237 return m_colour; 00238 } 00239 00240 QColor 00241 SingleColourLayer::getBaseQColor() const 00242 { 00243 return ColourDatabase::getInstance()->getColour(m_colour); 00244 } 00245 00246 QColor 00247 SingleColourLayer::getBackgroundQColor(View *v) const 00248 { 00249 return v->getBackground(); 00250 } 00251 00252 QColor 00253 SingleColourLayer::getForegroundQColor(View *v) const 00254 { 00255 return v->getForeground(); 00256 } 00257 00258 std::vector<QColor> 00259 SingleColourLayer::getPartialShades(View *v) const 00260 { 00261 std::vector<QColor> s; 00262 QColor base = getBaseQColor(); 00263 QColor bg = getBackgroundQColor(v); 00264 for (int i = 0; i < 3; ++i) { 00265 int red = base.red() + ((bg.red() - base.red()) * (i + 1)) / 4; 00266 int green = base.green() + ((bg.green() - base.green()) * (i + 1)) / 4; 00267 int blue = base.blue() + ((bg.blue() - base.blue()) * (i + 1)) / 4; 00268 s.push_back(QColor(red, green, blue)); 00269 } 00270 return s; 00271 } 00272 00273 void 00274 SingleColourLayer::toXml(QTextStream &stream, 00275 QString indent, QString extraAttributes) const 00276 { 00277 QString s; 00278 00279 QString colourName, colourSpec, darkbg; 00280 ColourDatabase::getInstance()->getStringValues 00281 (m_colour, colourName, colourSpec, darkbg); 00282 00283 s += QString("colourName=\"%1\" " 00284 "colour=\"%2\" " 00285 "darkBackground=\"%3\" ") 00286 .arg(colourName) 00287 .arg(colourSpec) 00288 .arg(darkbg); 00289 00290 Layer::toXml(stream, indent, extraAttributes + " " + s); 00291 } 00292 00293 void 00294 SingleColourLayer::setProperties(const QXmlAttributes &attributes) 00295 { 00296 QString colourName = attributes.value("colourName"); 00297 QString colourSpec = attributes.value("colour"); 00298 QString darkbg = attributes.value("darkBackground"); 00299 00300 int colour = ColourDatabase::getInstance()->putStringValues 00301 (colourName, colourSpec, darkbg); 00302 00303 if (colour == -1) 00304 return; 00305 00306 m_colourExplicitlySet = true; 00307 00308 if (m_colour != colour) { 00309 00310 #ifdef DEBUG_COLOUR_SELECTION 00311 SVDEBUG << "SingleColourLayer::setProperties: changing colour from " << m_colour << " to " << colour << endl; 00312 #endif 00313 00314 unrefColor(); 00315 m_colour = colour; 00316 refColor(); 00317 00318 flagBaseColourChanged(); 00319 } 00320 } 00321 00322 void SingleColourLayer::refColor() 00323 { 00324 if (m_colourRefCount.find(m_colour) == m_colourRefCount.end()) { 00325 m_colourRefCount[m_colour] = 1; 00326 } else { 00327 m_colourRefCount[m_colour]++; 00328 } 00329 } 00330 00331 void SingleColourLayer::unrefColor() 00332 { 00333 if (m_colourRefCount.find(m_colour) != m_colourRefCount.end() && 00334 m_colourRefCount[m_colour] > 0) { 00335 m_colourRefCount[m_colour]--; 00336 } 00337 }