comparison 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
comparison
equal deleted inserted replaced
286:7554ae119882 287:cd2492c5fe45
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3 /*
4 Sonic Visualiser
5 An audio file viewer and annotation editor.
6 Centre for Digital Music, Queen Mary, University of London.
7 This file copyright 2007 QMUL.
8
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version. See the file
13 COPYING included with this distribution for more information.
14 */
15
16 #include "SingleColourLayer.h"
17 #include "base/ColourDatabase.h"
18 #include "view/View.h"
19
20 #include <iostream>
21
22 #include <QApplication>
23
24 SingleColourLayer::ColourIndexPool
25 SingleColourLayer::m_usedColourIndices;
26
27 SingleColourLayer::SingleColourLayer() :
28 m_colour(0)
29 {
30 setDefaultColourFor(0);
31 }
32
33 bool
34 SingleColourLayer::hasLightBackground() const
35 {
36 bool dark = ColourDatabase::getInstance()->useDarkBackground(m_colour);
37 return !dark;
38 }
39
40 Layer::PropertyList
41 SingleColourLayer::getProperties() const
42 {
43 PropertyList list = Layer::getProperties();
44 list.push_back("Colour");
45 return list;
46 }
47
48 QString
49 SingleColourLayer::getPropertyLabel(const PropertyName &name) const
50 {
51 if (name == "Colour") return tr("Colour");
52 return "";
53 }
54
55 Layer::PropertyType
56 SingleColourLayer::getPropertyType(const PropertyName &name) const
57 {
58 if (name == "Colour") return ColourProperty;
59 return InvalidProperty;
60 }
61
62 QString
63 SingleColourLayer::getPropertyGroupName(const PropertyName &) const
64 {
65 return QString();
66 }
67
68 int
69 SingleColourLayer::getPropertyRangeAndValue(const PropertyName &name,
70 int *min, int *max, int *deflt) const
71 {
72 int val = 0;
73
74 int garbage0, garbage1, garbage2;
75 if (!min) min = &garbage0;
76 if (!max) max = &garbage1;
77 if (!deflt) deflt = &garbage2;
78
79 if (name == "Colour") {
80
81 ColourDatabase::getInstance()->getColourPropertyRange(min, max);
82 *deflt = 0; //!!!
83
84 val = m_colour;
85
86 } else {
87 val = Layer::getPropertyRangeAndValue(name, min, max, deflt);
88 }
89
90 return val;
91 }
92
93 QString
94 SingleColourLayer::getPropertyValueLabel(const PropertyName &name,
95 int value) const
96 {
97 if (name == "Colour") {
98 return Layer::getPropertyValueLabel(name, value);
99 }
100 return tr("<unknown>");
101 }
102
103 RangeMapper *
104 SingleColourLayer::getNewPropertyRangeMapper(const PropertyName &) const
105 {
106 return 0;
107 }
108
109 void
110 SingleColourLayer::setProperty(const PropertyName &name, int value)
111 {
112 if (name == "Colour") {
113 setBaseColour(value);
114 }
115 }
116
117 void
118 SingleColourLayer::setDefaultColourFor(View *v)
119 {
120 bool dark = false;
121 if (v) {
122 ColourIndexPool::iterator i = m_usedColourIndices.find(m_colour);
123 if (i != m_usedColourIndices.end()) m_usedColourIndices.erase(i);
124 dark = !v->hasLightBackground();
125 } else {
126 QColor bg = QApplication::palette().color(QPalette::Window);
127 if (bg.red() + bg.green() + bg.blue() < 384) dark = true;
128 }
129
130 m_colour = -1;
131 ColourDatabase *cdb = ColourDatabase::getInstance();
132
133 int hint = -1;
134 bool impose = false;
135 if (v) {
136 // We don't want to call this if !v because that probably
137 // means we're being called from the constructor, and this is
138 // a virtual function
139 hint = getDefaultColourHint(dark, impose);
140 std::cerr << "hint = " << hint << ", impose = " << impose << std::endl;
141 }
142
143 if (hint >= 0 && impose) {
144 m_colour = hint;
145 m_usedColourIndices.insert(m_colour);
146 return;
147 }
148
149 for (int i = 0; i < cdb->getColourCount(); ++i) {
150 int index = i;
151 if (hint > 0) index = (index + hint) % cdb->getColourCount();
152 if (cdb->useDarkBackground(index) != dark) continue;
153 if (m_colour < 0) m_colour = index;
154 if (m_usedColourIndices.find(index) == m_usedColourIndices.end()) {
155 m_colour = index;
156 break;
157 }
158 }
159
160 if (m_colour < 0) m_colour = 0;
161 m_usedColourIndices.insert(m_colour);
162 }
163
164 void
165 SingleColourLayer::setBaseColour(int colour)
166 {
167 if (m_colour == colour) return;
168 ColourIndexPool::iterator i = m_usedColourIndices.find(m_colour);
169 if (i != m_usedColourIndices.end()) m_usedColourIndices.erase(i);
170 m_colour = colour;
171 m_usedColourIndices.insert(m_colour);
172 flagBaseColourChanged();
173 emit layerParametersChanged();
174 }
175
176 int
177 SingleColourLayer::getBaseColour() const
178 {
179 return m_colour;
180 }
181
182 QColor
183 SingleColourLayer::getBaseQColor() const
184 {
185 return ColourDatabase::getInstance()->getColour(m_colour);
186 }
187
188 QColor
189 SingleColourLayer::getBackgroundQColor(View *v) const
190 {
191 return v->getBackground();
192 }
193
194 QColor
195 SingleColourLayer::getForegroundQColor(View *v) const
196 {
197 return v->getForeground();
198 }
199
200 std::vector<QColor>
201 SingleColourLayer::getPartialShades(View *v) const
202 {
203 std::vector<QColor> s;
204 QColor base = getBaseQColor();
205 QColor bg = getBackgroundQColor(v);
206 for (int i = 0; i < 3; ++i) {
207 int red = base.red() + ((bg.red() - base.red()) * (i + 1)) / 4;
208 int green = base.green() + ((bg.green() - base.green()) * (i + 1)) / 4;
209 int blue = base.blue() + ((bg.blue() - base.blue()) * (i + 1)) / 4;
210 s.push_back(QColor(red, green, blue));
211 }
212 return s;
213 }
214
215 QString
216 SingleColourLayer::toXmlString(QString indent, QString extraAttributes) const
217 {
218 QString s;
219
220 QString colourName, colourSpec, darkbg;
221 ColourDatabase::getInstance()->getStringValues
222 (m_colour, colourName, colourSpec, darkbg);
223
224 s += QString("colourName=\"%1\" "
225 "colour=\"%2\" "
226 "darkBackground=\"%3\" ")
227 .arg(colourName)
228 .arg(colourSpec)
229 .arg(darkbg);
230
231 return Layer::toXmlString(indent, extraAttributes + " " + s);
232 }
233
234 void
235 SingleColourLayer::setProperties(const QXmlAttributes &attributes)
236 {
237 QString colourName = attributes.value("colourName");
238 QString colourSpec = attributes.value("colour");
239 QString darkbg = attributes.value("darkBackground");
240 m_colour = ColourDatabase::getInstance()->putStringValues
241 (colourName, colourSpec, darkbg);
242 }
243