svgui  1.9
SingleColourLayer.cpp
Go to the documentation of this file.
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 "ColourDatabase.h"
18 #include "view/View.h"
19 
20 #include <iostream>
21 
22 #include <QTextStream>
23 #include <QApplication>
24 
25 //#define DEBUG_COLOUR_SELECTION 1
26 
29 
31  m_colour(0),
32  m_colourExplicitlySet(false),
33  m_defaultColourSet(false)
34 {
35  // Reference current colour because setDefaulColourFor
36  // will unreference it before (possibly) changing it.
37  refColor();
39 }
40 
42 {
43  unrefColor();
44 }
45 
46 QPixmap
48 {
50 }
51 
52 bool
54 {
56  return !dark;
57 }
58 
59 Layer::PropertyList
61 {
62  PropertyList list = Layer::getProperties();
63  list.push_back("Colour");
64  return list;
65 }
66 
67 QString
68 SingleColourLayer::getPropertyLabel(const PropertyName &name) const
69 {
70  if (name == "Colour") return tr("Colour");
71  return "";
72 }
73 
74 Layer::PropertyType
75 SingleColourLayer::getPropertyType(const PropertyName &name) const
76 {
77  if (name == "Colour") return ColourProperty;
78  return InvalidProperty;
79 }
80 
81 QString
82 SingleColourLayer::getPropertyGroupName(const PropertyName &) const
83 {
84  return QString();
85 }
86 
87 int
89  int *min, int *max, int *deflt) const
90 {
91  int val = 0;
92 
93  int garbage0, garbage1, garbage2;
94  if (!min) min = &garbage0;
95  if (!max) max = &garbage1;
96  if (!deflt) deflt = &garbage2;
97 
98  if (name == "Colour") {
99 
101  *deflt = 0;
102 
103  val = m_colour;
104 
105  } else {
106  val = Layer::getPropertyRangeAndValue(name, min, max, deflt);
107  }
108 
109  return val;
110 }
111 
112 QString
114  int value) const
115 {
116  if (name == "Colour") {
118  if (value >= 0 && value < db->getColourCount()) {
119  return db->getColourName(value);
120  }
121  }
122  return tr("<unknown>");
123 }
124 
125 RangeMapper *
127 {
128  return 0;
129 }
130 
131 void
132 SingleColourLayer::setProperty(const PropertyName &name, int value)
133 {
134  if (name == "Colour") {
135  setBaseColour(value);
136  }
137 }
138 
139 void
141 {
142 #ifdef DEBUG_COLOUR_SELECTION
143  SVDEBUG << "SingleColourLayer::setDefaultColourFor: m_colourExplicitlySet = " << m_colourExplicitlySet << ", m_defaultColourSet " << m_defaultColourSet << endl;
144 #endif
145 
147 
148  if (v) m_defaultColourSet = true; // v==0 case doesn't really count
149 
150  bool dark = false;
151  if (v) {
152  dark = !v->hasLightBackground();
153  } else {
154  QColor bg = QApplication::palette().color(QPalette::Window);
155  if (bg.red() + bg.green() + bg.blue() < 384) dark = true;
156  }
157 
159 
160  int hint = -1;
161  bool impose = false;
162  if (v) {
163  // We don't want to call this if !v because that probably
164  // means we're being called from the constructor, and this is
165  // a virtual function
166  hint = getDefaultColourHint(dark, impose);
167 #ifdef DEBUG_COLOUR_SELECTION
168  cerr << "hint = " << hint << ", impose = " << impose << endl;
169 #endif
170  } else {
171 #ifdef DEBUG_COLOUR_SELECTION
172  cerr << "(from ctor)" << endl;
173 #endif
174  }
175 
176  if (hint >= 0 && impose) {
177  setBaseColour(hint);
178  return;
179  }
180 
181  unrefColor();
182 
183  int bestCount = 0, bestColour = -1;
184 
185  for (int i = 0; i < cdb->getColourCount(); ++i) {
186 
187  int index = i;
188  if (hint > 0) index = (index + hint) % cdb->getColourCount();
189  if (cdb->useDarkBackground(index) != dark) continue;
190 
191  int count = 0;
192  if (m_colourRefCount.find(index) != m_colourRefCount.end()) {
193  count = m_colourRefCount[index];
194  }
195 
196 #ifdef DEBUG_COLOUR_SELECTION
197  cerr << "index = " << index << ", count = " << count;
198 #endif
199 
200  if (bestColour < 0 || count < bestCount) {
201  bestColour = index;
202  bestCount = count;
203 #ifdef DEBUG_COLOUR_SELECTION
204  cerr << " *";
205 #endif
206  }
207 
208 #ifdef DEBUG_COLOUR_SELECTION
209  cerr << endl;
210 #endif
211  }
212 
213  if (bestColour < 0) m_colour = 0;
214  else m_colour = bestColour;
215 
216  refColor();
217 }
218 
219 void
221 {
222  m_colourExplicitlySet = true;
223 
224  if (m_colour == colour) return;
225 
226  refColor();
227  m_colour = colour;
228  unrefColor();
229 
231  emit layerParametersChanged();
232 }
233 
234 int
236 {
237  return m_colour;
238 }
239 
240 QColor
242 {
244 }
245 
246 QColor
248 {
249  return v->getBackground();
250 }
251 
252 QColor
254 {
255  return v->getForeground();
256 }
257 
258 std::vector<QColor>
260 {
261  std::vector<QColor> s;
262  QColor base = getBaseQColor();
263  QColor bg = getBackgroundQColor(v);
264  for (int i = 0; i < 3; ++i) {
265  int red = base.red() + ((bg.red() - base.red()) * (i + 1)) / 4;
266  int green = base.green() + ((bg.green() - base.green()) * (i + 1)) / 4;
267  int blue = base.blue() + ((bg.blue() - base.blue()) * (i + 1)) / 4;
268  s.push_back(QColor(red, green, blue));
269  }
270  return s;
271 }
272 
273 void
274 SingleColourLayer::toXml(QTextStream &stream,
275  QString indent, QString extraAttributes) const
276 {
277  QString s;
278 
279  QString colourName, colourSpec, darkbg;
281  (m_colour, colourName, colourSpec, darkbg);
282 
283  s += QString("colourName=\"%1\" "
284  "colour=\"%2\" "
285  "darkBackground=\"%3\" ")
286  .arg(colourName)
287  .arg(colourSpec)
288  .arg(darkbg);
289 
290  Layer::toXml(stream, indent, extraAttributes + " " + s);
291 }
292 
293 void
294 SingleColourLayer::setProperties(const QXmlAttributes &attributes)
295 {
296  QString colourName = attributes.value("colourName");
297  QString colourSpec = attributes.value("colour");
298  QString darkbg = attributes.value("darkBackground");
299 
301  (colourName, colourSpec, darkbg);
302 
303  if (colour == -1)
304  return;
305 
306  m_colourExplicitlySet = true;
307 
308  if (m_colour != colour) {
309 
310 #ifdef DEBUG_COLOUR_SELECTION
311  SVDEBUG << "SingleColourLayer::setProperties: changing colour from " << m_colour << " to " << colour << endl;
312 #endif
313 
314  unrefColor();
315  m_colour = colour;
316  refColor();
317 
319  }
320 }
321 
323 {
324  if (m_colourRefCount.find(m_colour) == m_colourRefCount.end()) {
326  } else {
328  }
329 }
330 
332 {
333  if (m_colourRefCount.find(m_colour) != m_colourRefCount.end() &&
334  m_colourRefCount[m_colour] > 0) {
336  }
337 }
QString getColourName(int c) const
virtual void setDefaultColourFor(View *v)
virtual void flagBaseColourChanged()
virtual QPixmap getLayerPresentationPixmap(QSize size) const
virtual QColor getForeground() const
Definition: View.cpp:513
virtual void toXml(QTextStream &stream, QString indent="", QString extraAttributes="") const
Convert the layer's data (though not those of the model it refers to) into XML for file output.
Definition: Layer.cpp:592
QPixmap getExamplePixmap(int index, QSize size) const
void getStringValues(int index, QString &colourName, QString &colourSpec, QString &darkbg) const
virtual void setBaseColour(int)
Set the colour used to draw primary items in the layer.
virtual void toXml(QTextStream &stream, QString indent="", QString extraAttributes="") const
Convert the layer's data (though not those of the model it refers to) into XML for file output.
bool useDarkBackground(int c) const
virtual bool hasLightBackground() const
Definition: View.cpp:463
int putStringValues(QString colourName, QString colourSpec, QString darkbg)
virtual QColor getForegroundQColor(View *v) const
virtual int getDefaultColourHint(bool, bool &)
virtual QColor getBaseQColor() const
std::vector< QColor > getPartialShades(View *v) const
static ColourRefCount m_colourRefCount
virtual QString getPropertyLabel(const PropertyName &) const
virtual QColor getBackgroundQColor(View *v) const
void layerParametersChanged()
virtual QString getPropertyGroupName(const PropertyName &) const
virtual void setProperties(const QXmlAttributes &attributes)
Set the particular properties of a layer (those specific to the subclass) from a set of XML attribute...
virtual bool hasLightBackground() const
Return true if the layer currently has a dark colour on a light background, false if it has a light c...
int getColourCount() const
virtual int getPropertyRangeAndValue(const PropertyName &, int *min, int *max, int *deflt) const
virtual RangeMapper * getNewPropertyRangeMapper(const PropertyName &) const
View is the base class of widgets that display one or more overlaid views of data against a horizonta...
Definition: View.h:50
virtual QString getPropertyValueLabel(const PropertyName &, int value) const
std::map< int, int > ColourRefCount
void getColourPropertyRange(int *min, int *max) const
virtual PropertyList getProperties() const
virtual QColor getBackground() const
Definition: View.cpp:493
virtual PropertyType getPropertyType(const PropertyName &) const
virtual int getBaseColour() const
Retrieve the current primary drawing colour, as a ColourDatabase index value.
static ColourDatabase * getInstance()
virtual void setProperty(const PropertyName &, int value)
QColor getColour(int c) const