00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
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;
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
00157
00158
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