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
|