color_palette.cpp
Go to the documentation of this file.
1 
22 #include "color_palette.hpp"
23 #include <cmath>
24 #include <QFile>
25 #include <QTextStream>
26 #include <QHash>
27 #include <QPainter>
28 #include <QFileInfo>
29 
30 namespace color_widgets {
31 
33 {
34 public:
36  int columns;
37  QString name;
38  QString fileName;
39  bool dirty;
40 
41  bool valid_index(int index)
42  {
43  return index >= 0 && index < colors.size();
44  }
45 };
46 
48  const QString& name,
49  int columns)
50  : p ( new Private )
51 {
52  setName(name);
55 }
56 
57 ColorPalette::ColorPalette(const QString& name)
58  : p ( new Private )
59 {
60  setName(name);
61  p->columns = 0;
62  p->dirty = false;
63 }
64 
65 ColorPalette::ColorPalette(const QVector<QPair<QColor,QString> >& colors,
66  const QString& name,
67  int columns)
68 {
69  setName(name);
72  p->dirty = false;
73 }
74 
76  : QObject(), p ( new Private(*other.p) )
77 {
78 }
79 
81 {
82  *p = *other.p;
83  emitUpdate();
84  return *this;
85 }
86 
88 {
89  delete p;
90 }
91 
93  : QObject(), p ( other.p )
94 {
95  other.p = nullptr;
96 }
98 {
99  std::swap(p, other.p);
100  emitUpdate();
101  return *this;
102 }
103 
105 {
106  emit colorsChanged(p->colors);
107  emit columnsChanged(p->columns);
108  emit nameChanged(p->name);
109  emit fileNameChanged(p->fileName);
110  emit dirtyChanged(p->dirty);
111 }
112 
113 QColor ColorPalette::colorAt(int index) const
114 {
115  return p->valid_index(index) ? p->colors[index].first : QColor();
116 }
117 
118 QString ColorPalette::nameAt(int index) const
119 {
120  return p->valid_index(index) ? p->colors[index].second : QString();
121 }
122 
124 {
125  return p->colors;
126 }
127 
128 int ColorPalette::count() const
129 {
130  return p->colors.size();
131 }
132 
134 {
135  return p->columns;
136 }
137 
138 QString ColorPalette::name() const
139 {
140  return p->name;
141 }
142 
144 {
145  p->colors.clear();
146  p->colors.reserve(color_table.size());
147  for ( QRgb c : color_table )
148  {
149  QColor color ( c );
150  color.setAlpha(255);
151  p->colors.push_back(qMakePair(color,QString()));
152  }
153  emit colorsChanged(p->colors);
154  setDirty(true);
155 }
156 
157 bool ColorPalette::loadImage(const QImage& image)
158 {
159  if ( image.isNull() )
160  return false;
161  setColumns(image.width());
162 
163  p->colors.clear();
164  p->colors.reserve(image.width()*image.height());
165  for ( int y = 0; y < image.height(); y++ )
166  {
167  for ( int x = 0; x < image.width(); x++ )
168  {
169  QColor color ( image.pixel(x, y) );
170  color.setAlpha(255);
171  p->colors.push_back(qMakePair(color,QString()));
172  }
173  }
174  emit colorsChanged(p->colors);
175  setDirty(true);
176  return true;
177 }
178 
180 {
181  ColorPalette p;
182  p.fromImage(image);
183  return p;
184 }
185 
186 bool ColorPalette::load(const QString& name)
187 {
188  p->fileName = name;
189  p->colors.clear();
190  p->columns = 0;
191  p->dirty = false;
192  p->name = QFileInfo(name).baseName();
193 
194  QFile file(name);
195 
196  if ( !file.open(QFile::ReadOnly|QFile::Text) )
197  {
198  emitUpdate();
199  return false;
200  }
201 
202  QTextStream stream( &file );
203 
204  if ( stream.readLine() != "GIMP Palette" )
205  {
206  emitUpdate();
207  return false;
208  }
209 
210  QString line;
211 
212  // parse properties
213  QHash<QString,QString> properties;
214  while( !stream.atEnd() )
215  {
216  line = stream.readLine();
217  if ( line.isEmpty() )
218  continue;
219  if ( line[0] == '#' )
220  break;
221  int colon = line.indexOf(':');
222  if ( colon == -1 )
223  break;
224  properties[line.left(colon).toLower()] =
225  line.right(line.size() - colon - 1).trimmed();
226  }
228  setName(properties["name"]);
229  setColumns(properties["columns"].toInt());
230 
231  // Skip comments
232  if ( !stream.atEnd() && line[0] == '#' )
233  while( !stream.atEnd() )
234  {
235  qint64 pos = stream.pos();
236  line = stream.readLine();
237  if ( !line.isEmpty() && line[0] != '#' )
238  {
239  stream.seek(pos);
240  break;
241  }
242  }
243 
244  while( !stream.atEnd() )
245  {
246  int r = 0, g = 0, b = 0;
247  stream >> r >> g >> b;
248  line = stream.readLine().trimmed();
249  p->colors.push_back(qMakePair(QColor(r, g, b), line));
250  }
251 
252  emit colorsChanged(p->colors);
253  setDirty(false);
254 
255  return true;
256 }
257 
259 {
260  ColorPalette p;
261  p.load(name);
262  return p;
263 }
264 
265 bool ColorPalette::save(const QString& filename)
266 {
267  setFileName(filename);
268  return save();
269 }
270 
272 {
273  QString filename = p->fileName;
274  if ( filename.isEmpty() )
275  {
276  filename = unnamed(p->name)+".gpl";
277  }
278 
279  QFile file(filename);
280  if ( !file.open(QFile::Text|QFile::WriteOnly) )
281  return false;
282 
283  QTextStream stream(&file);
284 
285  stream << "GIMP Palette\n";
286  stream << "Name: " << unnamed(p->name) << '\n';
287  if ( p->columns )
288  stream << "Columns: " << p->columns << '\n';
290  stream << "#\n";
291 
292  for ( int i = 0; i < p->colors.size(); i++ )
293  {
294  stream << qSetFieldWidth(3) << p->colors[i].first.red() << qSetFieldWidth(0) << ' '
295  << qSetFieldWidth(3) << p->colors[i].first.green() << qSetFieldWidth(0) << ' '
296  << qSetFieldWidth(3) << p->colors[i].first.blue() << qSetFieldWidth(0) << '\t'
297  << unnamed(p->colors[i].second) << '\n';
298  }
299 
300  if ( !file.error() )
301  {
302  setDirty(false);
303  return true;
304  }
305 
306  return false;
307 }
308 
309 
310 QString ColorPalette::fileName() const
311 {
312  return p->fileName;
313 }
314 
315 
316 void ColorPalette::setColumns(int columns)
317 {
318  if ( columns <= 0 )
319  columns = 0;
320 
321  if ( columns != p->columns )
322  {
323  setDirty(true);
324  emit columnsChanged( p->columns = columns );
325  }
326 }
327 
329 {
330  p->colors.clear();
331  foreach(const QColor& col, colors)
332  p->colors.push_back(qMakePair(col,QString()));
333  setDirty(true);
334  emit colorsChanged(p->colors);
335 }
336 
337 void ColorPalette::setColors(const QVector<QPair<QColor,QString> >& colors)
338 {
339  p->colors = colors;
340  setDirty(true);
341  emit colorsChanged(p->colors);
342 }
343 
344 
345 void ColorPalette::setColorAt(int index, const QColor& color)
346 {
347  if ( !p->valid_index(index) )
348  return;
349 
350  p->colors[index].first = color;
351 
352  setDirty(true);
353  emit colorChanged(index);
354  emit colorsUpdated(p->colors);
355 }
356 
357 void ColorPalette::setColorAt(int index, const QColor& color, const QString& name)
358 {
359  if ( !p->valid_index(index) )
360  return;
361 
362  p->colors[index].first = color;
363  p->colors[index].second = name;
364  setDirty(true);
365  emit colorChanged(index);
366  emit colorsUpdated(p->colors);
367 }
368 
369 void ColorPalette::setNameAt(int index, const QString& name)
370 {
371  if ( !p->valid_index(index) )
372  return;
373 
374  p->colors[index].second = name;
375 
376  setDirty(true);
377  emit colorChanged(index);
378  emit colorsUpdated(p->colors);
379 }
380 
381 
382 void ColorPalette::appendColor(const QColor& color, const QString& name)
383 {
384  p->colors.push_back(qMakePair(color,name));
385  setDirty(true);
386  emit colorAdded(p->colors.size()-1);
387  emit colorsUpdated(p->colors);
388 }
389 
390 void ColorPalette::insertColor(int index, const QColor& color, const QString& name)
391 {
392  if ( index < 0 || index > p->colors.size() )
393  return;
394 
395  p->colors.insert(index, qMakePair(color, name));
396 
397  setDirty(true);
398  emit colorAdded(index);
399  emit colorsUpdated(p->colors);
400 }
401 
403 {
404  if ( !p->valid_index(index) )
405  return;
406 
407  p->colors.remove(index);
408 
409  setDirty(true);
410  emit colorRemoved(index);
411  emit colorsUpdated(p->colors);
412 }
413 
414 void ColorPalette::setName(const QString& name)
415 {
416  setDirty(true);
417  p->name = name;
418 }
419 
420 void ColorPalette::setFileName(const QString& name)
421 {
422  setDirty(true);
423  p->fileName = name;
424 }
425 
426 QString ColorPalette::unnamed(const QString& name) const
427 {
428  return name.isEmpty() ? tr("Unnamed") : name;
429 }
430 
431 
432 QPixmap ColorPalette::preview(const QSize& size, const QColor& background) const
433 {
434  if ( !size.isValid() || p->colors.empty() )
435  return QPixmap();
436 
437  QPixmap out( size );
438  out.fill(background);
439  QPainter painter(&out);
440 
441  int count = p->colors.size();
442  int columns = p->columns;
443  if ( !columns )
444  columns = std::ceil( std::sqrt( count * float(size.width()) / size.height() ) );
445  int rows = std::ceil( float(count) / columns );
446  QSizeF color_size(float(size.width()) / columns, float(size.height()) / rows);
447 
448  for ( int y = 0, i = 0; y < rows && i < count; y++ )
449  {
450  for ( int x = 0; x < columns && i < count; x++, i++ )
451  {
452  painter.fillRect(QRectF(x*color_size.width(), y*color_size.height(),
453  color_size.width(), color_size.height()),
454  p->colors[i].first
455  );
456  }
457  }
458 
459  return out;
460 }
461 
462 bool ColorPalette::dirty() const
463 {
464  return p->dirty;
465 }
466 
467 void ColorPalette::setDirty(bool dirty)
468 {
469  if ( dirty != p->dirty )
470  emit dirtyChanged( p->dirty = dirty );
471 }
472 
474 {
475  QVector<QColor> out;
476  out.reserve(p->colors.size());
477  for ( int i = 0; i < p->colors.size(); i++ )
478  out.push_back(p->colors[i].first);
479  return out;
480 }
481 
483 {
484  QVector<QRgb> out;
485  out.reserve(p->colors.size());
486  for ( const auto& color_pair : p->colors )
487  out.push_back(color_pair.first.rgba());
488  return out;
489 }
490 
492 {
493  ColorPalette palette;
494  palette.loadColorTable(table);
495  return palette;
496 }
497 
498 } // namespace color_widgets
color_widgets::ColorPalette::fileName
QString fileName
Name of the file the palette has been read from.
Definition: color_palette.hpp:57
color_widgets::ColorPalette::fromFile
static ColorPalette fromFile(const QString &name)
Creates a ColorPalette from a Gimp palette (gpl) file.
Definition: color_palette.cpp:258
color
color
Definition: color.h:16
color_widgets::ColorPalette::Private::valid_index
bool valid_index(int index)
Definition: color_palette.cpp:41
color_widgets::ColorPalette::colorsUpdated
void colorsUpdated(const QVector< QPair< QColor, QString >> &)
Emitted when the colors have been modified with a simple operation (set, append etc....
color_widgets::ColorPalette::fromImage
static ColorPalette fromImage(const QImage &image)
Creates a ColorPalette from a Gimp palette (gpl) file.
Definition: color_palette.cpp:179
color_widgets::ColorPalette::setColumns
void setColumns(int columns)
Definition: color_palette.cpp:316
color_widgets::ColorPalette::loadColorTable
Q_INVOKABLE void loadColorTable(const QVector< QRgb > &color_table)
Use a color table to set the colors.
Definition: color_palette.cpp:143
color_widgets::ColorPalette::Private::colors
QVector< QPair< QColor, QString > > colors
Definition: color_palette.cpp:35
color_widgets::ColorPalette::columns
int columns
Number of colors to display in a row, if 0 unspecified.
Definition: color_palette.hpp:49
color_widgets::ColorPalette::name
QString name
Name of the palette.
Definition: color_palette.hpp:45
color_widgets::ColorPalette::unnamed
QString unnamed(const QString &name=QString()) const
Returns name if it isn't null, otherwise a default value.
Definition: color_palette.cpp:426
color_widgets::ColorPalette::Private::fileName
QString fileName
Definition: color_palette.cpp:38
color_widgets::ColorPalette::Private::dirty
bool dirty
Definition: color_palette.cpp:39
QVector
Definition: qwt_clipper.h:23
color_widgets::ColorPalette::Private::columns
int columns
Definition: color_palette.cpp:36
color_widgets::ColorPalette
Definition: color_palette.hpp:34
mqtt_test_proto.x
x
Definition: mqtt_test_proto.py:34
color_widgets::ColorPalette::insertColor
void insertColor(int index, const QColor &color, const QString &name=QString())
Insert a color in an arbitrary location.
Definition: color_palette.cpp:390
color_widgets::ColorPalette::colorChanged
void colorChanged(int index)
Emitted when the color or the name at the given index has been modified.
mqtt_test_proto.y
y
Definition: mqtt_test_proto.py:35
color_widgets::ColorPalette::Private::name
QString name
Definition: color_palette.cpp:37
color_widgets::ColorPalette::preview
QPixmap preview(const QSize &size, const QColor &background=Qt::transparent) const
Returns a preview image of the colors in the palette.
Definition: color_palette.cpp:432
color_widgets::ColorPalette::setColors
void setColors(const QVector< QColor > &colors)
Definition: color_palette.cpp:328
color_widgets::ColorPalette::colorsChanged
void colorsChanged(const QVector< QPair< QColor, QString > > &)
Emitted when all the colors have changed.
nonstd::span_lite::size
span_constexpr std::size_t size(span< T, Extent > const &spn)
Definition: span.hpp:1554
color_widgets
Definition: color_dialog.hpp:33
color_widgets::ColorPalette::count
int count
Number of colors.
Definition: color_palette.hpp:53
color_widgets::ColorPalette::fileNameChanged
void fileNameChanged(const QString &)
color_widgets::ColorPalette::save
bool save()
save to file, the filename is fileName or determined automatically
Definition: color_palette.cpp:271
color_widgets::ColorPalette::colors
QVector< value_type > colors
The list of colors.
Definition: color_palette.hpp:41
color_palette.hpp
color_widgets::ColorPalette::columnsChanged
void columnsChanged(int)
color_widgets::ColorPalette::p
Private * p
Definition: color_palette.hpp:222
color_widgets::ColorPalette::setFileName
void setFileName(const QString &name)
Definition: color_palette.cpp:420
color_widgets::ColorPalette::nameAt
Q_INVOKABLE QString nameAt(int index) const
Color name at the given index.
Definition: color_palette.cpp:118
std::swap
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition: json.hpp:21884
color_widgets::ColorPalette::loadImage
Q_INVOKABLE bool loadImage(const QImage &image)
Use the pixels on an image to set the palette colors.
Definition: color_palette.cpp:157
color_widgets::ColorPalette::setName
void setName(const QString &name)
Definition: color_palette.cpp:414
color_widgets::ColorPalette::eraseColor
void eraseColor(int index)
Remove the color at the given index.
Definition: color_palette.cpp:402
color_widgets::ColorPalette::Private
Definition: color_palette.cpp:32
color_widgets::ColorPalette::colorAt
Q_INVOKABLE QColor colorAt(int index) const
Color at the given index.
Definition: color_palette.cpp:113
color_widgets::ColorPalette::nameChanged
void nameChanged(const QString &)
color_widgets::ColorPalette::setDirty
void setDirty(bool dirty)
Definition: color_palette.cpp:467
color_widgets::ColorPalette::~ColorPalette
~ColorPalette()
Definition: color_palette.cpp:87
color_widgets::ColorPalette::dirty
bool dirty
Whether it has been modified and it might be advisable to save it.
Definition: color_palette.hpp:61
color_widgets::ColorPalette::emitUpdate
void emitUpdate()
Emit all the necessary signals when the palette has been completely overwritten.
Definition: color_palette.cpp:104
color_widgets::ColorPalette::dirtyChanged
void dirtyChanged(bool)
color_widgets::ColorPalette::onlyColors
QVector< QColor > onlyColors() const
Definition: color_palette.cpp:473
color_widgets::ColorPalette::operator=
ColorPalette & operator=(const ColorPalette &other)
Definition: color_palette.cpp:80
color_widgets::ColorPalette::load
Q_INVOKABLE bool load(const QString &name)
Load contents from a Gimp palette (gpl) file.
Definition: color_palette.cpp:186
color_widgets::ColorPalette::colorRemoved
void colorRemoved(int index)
Emitted when the color at the given index has been removed.
color_widgets::ColorPalette::fromColorTable
static ColorPalette fromColorTable(const QVector< QRgb > &table)
Creates a ColorPalette from a color table.
Definition: color_palette.cpp:491
color_widgets::ColorPalette::ColorPalette
ColorPalette(const QVector< QColor > &colors, const QString &name=QString(), int columns=0)
Definition: color_palette.cpp:47
color_widgets::ColorPalette::setNameAt
void setNameAt(int index, const QString &name=QString())
Change the name of a color.
Definition: color_palette.cpp:369
color_widgets::ColorPalette::appendColor
void appendColor(const QColor &color, const QString &name=QString())
Append a color at the end.
Definition: color_palette.cpp:382
color_widgets::ColorPalette::colorTable
Q_INVOKABLE QVector< QRgb > colorTable() const
Convert to a color table.
Definition: color_palette.cpp:482
color_widgets::ColorPalette::setColorAt
void setColorAt(int index, const QColor &color)
Change the color at the given index.
Definition: color_palette.cpp:345
color_widgets::ColorPalette::colorAdded
void colorAdded(int index)
Emitted when a single color has been added.


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Aug 11 2024 02:24:22