1 
2 
3 #include "toonzqt/styleeditor.h"
4 
5 // TnzQt includes
6 #include "toonzqt/gutil.h"
7 #include "toonzqt/filefield.h"
8 #include "historytypes.h"
9 #include "toonzqt/lutcalibrator.h"
10 
11 // TnzLib includes
12 #include "toonz/txshlevel.h"
13 #include "toonz/stylemanager.h"
14 #include "toonz/txshlevelhandle.h"
15 #include "toonz/toonzfolders.h"
16 #include "toonz/cleanupcolorstyles.h"
17 #include "toonz/palettecontroller.h"
18 #include "toonz/imagestyles.h"
19 #include "toonz/txshsimplelevel.h"  //iwsw
20 #include "toonz/levelproperties.h"  //iwsw
21 #include "toonz/mypaintbrushstyle.h"
22 #include "toonz/preferences.h"
23 
24 // TnzCore includes
25 #include "tconvert.h"
26 #include "tfiletype.h"
27 #include "tsystem.h"
28 #include "tundo.h"
29 #include "tcolorstyles.h"
30 #include "tpalette.h"
31 #include "tpixel.h"
32 #include "tvectorimage.h"
33 #include "trasterimage.h"
34 #include "tlevel_io.h"
35 #include "tofflinegl.h"
36 #include "tropcm.h"
37 #include "tvectorrenderdata.h"
38 #include "tsimplecolorstyles.h"
39 #include "tvectorbrushstyle.h"
40 
41 // Qt includes
42 #include <QHBoxLayout>
43 #include <QVBoxLayout>
44 #include <QGridLayout>
45 #include <QPainter>
46 #include <QButtonGroup>
47 #include <QMouseEvent>
48 #include <QLabel>
49 #include <QCheckBox>
50 #include <QPushButton>
51 #include <QRadioButton>
52 #include <QComboBox>
53 #include <QScrollArea>
54 #include <QStackedWidget>
55 #include <QStyleOptionSlider>
56 #include <QToolTip>
57 #include <QSplitter>
58 #include <QMenu>
59 #include <QOpenGLFramebufferObject>
60 
61 using namespace StyleEditorGUI;
62 
63 //*****************************************************************************
64 //    UndoPaletteChange  definition
65 //*****************************************************************************
66 
67 namespace {
68 
69 class UndoPaletteChange final : public TUndo {
70   TPaletteHandle *m_paletteHandle;
71   TPaletteP m_palette;
72 
73   int m_styleId;
74   const TColorStyleP m_oldColor, m_newColor;
75 
76   std::wstring m_oldName, m_newName;
77 
78   bool m_oldEditedFlag, m_newEditedFlag;
79 
80   int m_frame;
81 
82 public:
UndoPaletteChange(TPaletteHandle * paletteHandle,int styleId,const TColorStyle & oldColor,const TColorStyle & newColor)83   UndoPaletteChange(TPaletteHandle *paletteHandle, int styleId,
84                     const TColorStyle &oldColor, const TColorStyle &newColor)
85       : m_paletteHandle(paletteHandle)
86       , m_palette(paletteHandle->getPalette())
87       , m_styleId(styleId)
88       , m_oldColor(oldColor.clone())
89       , m_newColor(newColor.clone())
90       , m_oldName(oldColor.getName())
91       , m_newName(newColor.getName())
92       , m_frame(m_palette->getFrame())
93       , m_oldEditedFlag(oldColor.getIsEditedFlag())
94       , m_newEditedFlag(newColor.getIsEditedFlag()) {}
95 
undo() const96   void undo() const override {
97     m_palette->setStyle(m_styleId, m_oldColor->clone());
98     m_palette->getStyle(m_styleId)->setIsEditedFlag(m_oldEditedFlag);
99     m_palette->getStyle(m_styleId)->setName(m_oldName);
100 
101     if (m_palette->isKeyframe(m_styleId, m_frame))
102       m_palette->setKeyframe(m_styleId, m_frame);
103 
104     // don't change the dirty flag. because m_palette may not the current
105     // palette when undo executed
106     m_paletteHandle->notifyColorStyleChanged(false, false);
107   }
108 
redo() const109   void redo() const override {
110     m_palette->setStyle(m_styleId, m_newColor->clone());
111     m_palette->getStyle(m_styleId)->setIsEditedFlag(m_newEditedFlag);
112     m_palette->getStyle(m_styleId)->setName(m_newName);
113 
114     if (m_palette->isKeyframe(m_styleId, m_frame))
115       m_palette->setKeyframe(m_styleId, m_frame);
116 
117     // don't change the dirty flag. because m_palette may not the current
118     // palette when undo executed
119     m_paletteHandle->notifyColorStyleChanged(false, false);
120   }
121 
122   // imprecise - depends on the style
getSize() const123   int getSize() const override {
124     return sizeof(*this) + 2 * sizeof(TColorStyle *);
125   }
126 
getHistoryString()127   QString getHistoryString() override {
128     return QObject::tr(
129                "Change Style   Palette : %1  Style#%2  [R%3 G%4 B%5] -> [R%6 "
130                "G%7 B%8]")
131         .arg(QString::fromStdWString(m_palette->getPaletteName()))
132         .arg(QString::number(m_styleId))
133         .arg(m_oldColor->getMainColor().r)
134         .arg(m_oldColor->getMainColor().g)
135         .arg(m_oldColor->getMainColor().b)
136         .arg(m_newColor->getMainColor().r)
137         .arg(m_newColor->getMainColor().g)
138         .arg(m_newColor->getMainColor().b);
139   }
140 
getHistoryType()141   int getHistoryType() override { return HistoryType::Palette; }
142 };
143 
144 }  // namespace
145 
146 //*****************************************************************************
147 //    ColorModel  implementation
148 //*****************************************************************************
149 
150 const int ChannelMaxValues[]        = {255, 255, 255, 255, 359, 100, 100};
151 const int ChannelPairMaxValues[][2] = {{255, 255}, {255, 255}, {255, 255},
152                                        {255, 255}, {100, 100}, {359, 100},
153                                        {359, 100}};
154 
ColorModel()155 ColorModel::ColorModel() { memset(m_channels, 0, sizeof m_channels); }
156 
157 //-----------------------------------------------------------------------------
158 
rgb2hsv()159 void ColorModel::rgb2hsv() {
160   QColor converter(m_channels[0], m_channels[1], m_channels[2]);
161   m_channels[4] =
162       std::max(converter.hue(), 0);  // hue() ritorna -1 per colori acromatici
163   m_channels[5] = converter.saturation() * 100 / 255;
164   m_channels[6] = converter.value() * 100 / 255;
165 }
166 
167 //-----------------------------------------------------------------------------
168 
hsv2rgb()169 void ColorModel::hsv2rgb() {
170   QColor converter = QColor::fromHsv(m_channels[4], m_channels[5] * 255 / 100,
171                                      m_channels[6] * 255 / 100);
172 
173   m_channels[0] = converter.red();
174   m_channels[1] = converter.green();
175   m_channels[2] = converter.blue();
176 }
177 
178 //-----------------------------------------------------------------------------
179 
setTPixel(const TPixel32 & pix)180 void ColorModel::setTPixel(const TPixel32 &pix) {
181   QColor color(pix.r, pix.g, pix.b, pix.m);
182   m_channels[0] = color.red();
183   m_channels[1] = color.green();
184   m_channels[2] = color.blue();
185   m_channels[3] = color.alpha();
186   m_channels[4] =
187       std::max(color.hue(), 0);  // hue() ritorna -1 per colori acromatici
188   m_channels[5] = color.saturation() * 100 / 255;
189   m_channels[6] = color.value() * 100 / 255;
190 }
191 
192 //-----------------------------------------------------------------------------
193 
getTPixel() const194 TPixel32 ColorModel::getTPixel() const {
195   return TPixel32(m_channels[0], m_channels[1], m_channels[2], m_channels[3]);
196 }
197 
198 //-----------------------------------------------------------------------------
199 
setValue(ColorChannel channel,int value)200 void ColorModel::setValue(ColorChannel channel, int value) {
201   assert(0 <= (int)channel && (int)channel < 7);
202   assert(0 <= value && value <= ChannelMaxValues[channel]);
203   m_channels[(int)channel] = value;
204   if (channel >= eHue)
205     hsv2rgb();
206   else if (channel <= eBlue)
207     rgb2hsv();
208 }
209 
210 //-----------------------------------------------------------------------------
211 
setValues(ColorChannel channel,int v,int u)212 void ColorModel::setValues(ColorChannel channel, int v, int u) {
213   assert(0 <= (int)channel && (int)channel < 7);
214   switch (channel) {
215   case eRed:
216     setValue(eGreen, v);
217     setValue(eBlue, u);
218     break;
219   case eGreen:
220     setValue(eRed, v);
221     setValue(eBlue, u);
222     break;
223   case eBlue:
224     setValue(eRed, v);
225     setValue(eGreen, u);
226     break;
227   case eHue:
228     setValue(eSaturation, v);
229     setValue(eValue, u);
230     break;
231   case eSaturation:
232     setValue(eHue, v);
233     setValue(eValue, u);
234     break;
235   case eValue:
236     setValue(eHue, v);
237     setValue(eSaturation, u);
238     break;
239   default:
240     break;
241   }
242 }
243 
244 //-----------------------------------------------------------------------------
245 
getValue(ColorChannel channel) const246 int ColorModel::getValue(ColorChannel channel) const {
247   assert(0 <= (int)channel && (int)channel < 7);
248   return m_channels[(int)channel];
249 }
250 
251 //-----------------------------------------------------------------------------
252 
getValues(ColorChannel channel,int & u,int & v)253 void ColorModel::getValues(ColorChannel channel, int &u, int &v) {
254   switch (channel) {
255   case eRed:
256     u = getValue(eGreen);
257     v = getValue(eBlue);
258     break;
259   case eGreen:
260     u = getValue(eRed);
261     v = getValue(eBlue);
262     break;
263   case eBlue:
264     u = getValue(eRed);
265     v = getValue(eGreen);
266     break;
267   case eHue:
268     u = getValue(eSaturation);
269     v = getValue(eValue);
270     break;
271   case eSaturation:
272     u = getValue(eHue);
273     v = getValue(eValue);
274     break;
275   case eValue:
276     u = getValue(eHue);
277     v = getValue(eSaturation);
278     break;
279   default:
280     break;
281   }
282 }
283 
284 //-----------------------------------------------------------------------------
285 namespace {
286 //-----------------------------------------------------------------------------
287 
288 class RedShadeMaker {
289   const ColorModel &m_color;
290 
291 public:
RedShadeMaker(const ColorModel & color)292   RedShadeMaker(const ColorModel &color) : m_color(color) {}
shade(int value) const293   inline QRgb shade(int value) const {
294     return QColor(value, m_color.g(), m_color.b()).rgba();
295   }
296 };
297 
298 //-----------------------------------------------------------------------------
299 
300 class GreenShadeMaker {
301   const ColorModel &m_color;
302 
303 public:
GreenShadeMaker(const ColorModel & color)304   GreenShadeMaker(const ColorModel &color) : m_color(color) {}
shade(int value) const305   inline QRgb shade(int value) const {
306     return QColor(m_color.r(), value, m_color.b()).rgba();
307   }
308 };
309 
310 //-----------------------------------------------------------------------------
311 
312 class BlueShadeMaker {
313   const ColorModel &m_color;
314 
315 public:
BlueShadeMaker(const ColorModel & color)316   BlueShadeMaker(const ColorModel &color) : m_color(color) {}
shade(int value) const317   inline QRgb shade(int value) const {
318     return QColor(m_color.r(), m_color.g(), value).rgba();
319   }
320 };
321 
322 //-----------------------------------------------------------------------------
323 
324 class AlphaShadeMaker {
325   const ColorModel &m_color;
326 
327 public:
AlphaShadeMaker(const ColorModel & color)328   AlphaShadeMaker(const ColorModel &color) : m_color(color) {}
shade(int value) const329   inline QRgb shade(int value) const {
330     return QColor(m_color.r(), m_color.g(), m_color.b(), value).rgba();
331   }
332 };
333 
334 //-----------------------------------------------------------------------------
335 
336 class HueShadeMaker {
337   const ColorModel &m_color;
338 
339 public:
HueShadeMaker(const ColorModel & color)340   HueShadeMaker(const ColorModel &color) : m_color(color) {}
shade(int value) const341   inline QRgb shade(int value) const {
342     return QColor::fromHsv(359 * value / 255, m_color.s() * 255 / 100,
343                            m_color.v() * 255 / 100)
344         .rgba();
345   }
346 };
347 
348 //-----------------------------------------------------------------------------
349 
350 class SaturationShadeMaker {
351   const ColorModel &m_color;
352 
353 public:
SaturationShadeMaker(const ColorModel & color)354   SaturationShadeMaker(const ColorModel &color) : m_color(color) {}
shade(int value) const355   inline QRgb shade(int value) const {
356     return QColor::fromHsv(m_color.h(), value, m_color.v() * 255 / 100).rgba();
357   }
358 };
359 
360 //-----------------------------------------------------------------------------
361 
362 class ValueShadeMaker {
363   const ColorModel &m_color;
364 
365 public:
ValueShadeMaker(const ColorModel & color)366   ValueShadeMaker(const ColorModel &color) : m_color(color) {}
shade(int value) const367   inline QRgb shade(int value) const {
368     return QColor::fromHsv(m_color.h(), m_color.s() * 255 / 100, value).rgba();
369   }
370 };
371 
372 //-----------------------------------------------------------------------------
373 
374 class RedGreenShadeMaker {
375   const ColorModel &m_color;
376 
377 public:
RedGreenShadeMaker(const ColorModel & color)378   RedGreenShadeMaker(const ColorModel &color) : m_color(color) {}
shade(int u,int v) const379   inline QRgb shade(int u, int v) const {
380     return QColor(u, v, m_color.b()).rgba();
381   }
382 };
383 
384 //-----------------------------------------------------------------------------
385 
386 class RedBlueShadeMaker {
387   const ColorModel &m_color;
388 
389 public:
RedBlueShadeMaker(const ColorModel & color)390   RedBlueShadeMaker(const ColorModel &color) : m_color(color) {}
shade(int u,int v) const391   inline QRgb shade(int u, int v) const {
392     return QColor(u, m_color.g(), v).rgba();
393   }
394 };
395 
396 //-----------------------------------------------------------------------------
397 
398 class GreenBlueShadeMaker {
399   const ColorModel &m_color;
400 
401 public:
GreenBlueShadeMaker(const ColorModel & color)402   GreenBlueShadeMaker(const ColorModel &color) : m_color(color) {}
shade(int u,int v) const403   inline QRgb shade(int u, int v) const {
404     return QColor(m_color.r(), u, v).rgba();
405   }
406 };
407 
408 //-----------------------------------------------------------------------------
409 
410 class SaturationValueShadeMaker {
411   const ColorModel &m_color;
412 
413 public:
SaturationValueShadeMaker(const ColorModel & color)414   SaturationValueShadeMaker(const ColorModel &color) : m_color(color) {}
shade(int u,int v) const415   inline QRgb shade(int u, int v) const {
416     return QColor::fromHsv(m_color.h(), u, v).rgba();
417   }
418 };
419 
420 //-----------------------------------------------------------------------------
421 
422 class HueValueShadeMaker {
423   const ColorModel &m_color;
424 
425 public:
HueValueShadeMaker(const ColorModel & color)426   HueValueShadeMaker(const ColorModel &color) : m_color(color) {}
shade(int u,int v) const427   inline QRgb shade(int u, int v) const {
428     return QColor::fromHsv(359 * u / 255, m_color.s() * 255 / 100, v).rgba();
429   }
430 };
431 
432 //-----------------------------------------------------------------------------
433 
434 class HueSaturationShadeMaker {
435   const ColorModel &m_color;
436 
437 public:
HueSaturationShadeMaker(const ColorModel & color)438   HueSaturationShadeMaker(const ColorModel &color) : m_color(color) {}
shade(int u,int v) const439   inline QRgb shade(int u, int v) const {
440     return QColor::fromHsv(359 * u / 255, v, m_color.v() * 255 / 100).rgba();
441   }
442 };
443 
444 //-----------------------------------------------------------------------------
445 
446 template <class ShadeMaker>
makeLinearShading(const ShadeMaker & shadeMaker,int size,bool isVertical)447 QPixmap makeLinearShading(const ShadeMaker &shadeMaker, int size,
448                           bool isVertical) {
449   assert(size > 0);
450   QPixmap bgPixmap;
451   int i, dx, dy, w = 1, h = 1;
452   int x = 0, y = 0;
453   if (isVertical) {
454     dx = 0;
455     dy = -1;
456     h  = size;
457     y  = size - 1;
458   } else {
459     dx = 1;
460     dy = 0;
461     w  = size;
462   }
463   QImage image(w, h, QImage::Format_ARGB32);
464   for (i = 0; i < size; i++) {
465     int v = 255 * i / (size - 1);
466     image.setPixel(x, y, shadeMaker.shade(v));
467     x += dx;
468     y += dy;
469   }
470   return QPixmap::fromImage(image);
471 }
472 
473 //-----------------------------------------------------------------------------
474 
makeLinearShading(const ColorModel & color,ColorChannel channel,int size,bool isVertical)475 QPixmap makeLinearShading(const ColorModel &color, ColorChannel channel,
476                           int size, bool isVertical) {
477   switch (channel) {
478   case eRed:
479     if (isVertical)
480       return makeLinearShading(RedShadeMaker(color), size, isVertical);
481     else
482       return QPixmap(":Resources/grad_r.png").scaled(size, 1);
483   case eGreen:
484     if (isVertical)
485       return makeLinearShading(GreenShadeMaker(color), size, isVertical);
486     else
487       return QPixmap(":Resources/grad_g.png").scaled(size, 1);
488   case eBlue:
489     if (isVertical)
490       return makeLinearShading(BlueShadeMaker(color), size, isVertical);
491     else
492       return QPixmap(":Resources/grad_b.png").scaled(size, 1);
493   case eAlpha:
494     if (isVertical)
495       return makeLinearShading(AlphaShadeMaker(color), size, isVertical);
496     else
497       return QPixmap(":Resources/grad_m.png").scaled(size, 1);
498   case eHue:
499     return makeLinearShading(HueShadeMaker(color), size, isVertical);
500   case eSaturation:
501     return makeLinearShading(SaturationShadeMaker(color), size, isVertical);
502   case eValue:
503     return makeLinearShading(ValueShadeMaker(color), size, isVertical);
504   default:
505     assert(0);
506   }
507   return QPixmap();
508 }
509 
510 //-----------------------------------------------------------------------------
511 
512 template <class ShadeMaker>
makeSquareShading(const ShadeMaker & shadeMaker,int size)513 QPixmap makeSquareShading(const ShadeMaker &shadeMaker, int size) {
514   assert(size > 0);
515   QPixmap bgPixmap;
516   QImage image(size, size, QImage::Format_RGB32);
517   int i, j;
518   for (j = 0; j < size; j++) {
519     int u = 255 - (255 * j / (size - 1));
520     for (i = 0; i < size; i++) {
521       int v = 255 * i / (size - 1);
522       image.setPixel(i, j, shadeMaker.shade(v, u));
523     }
524   }
525   return QPixmap::fromImage(image);
526 }
527 
528 //-----------------------------------------------------------------------------
529 
makeSquareShading(const ColorModel & color,ColorChannel channel,int size)530 QPixmap makeSquareShading(const ColorModel &color, ColorChannel channel,
531                           int size) {
532   switch (channel) {
533   case eRed:
534     return makeSquareShading(GreenBlueShadeMaker(color), size);
535   case eGreen:
536     return makeSquareShading(RedBlueShadeMaker(color), size);
537   case eBlue:
538     return makeSquareShading(RedGreenShadeMaker(color), size);
539   case eHue:
540     return makeSquareShading(SaturationValueShadeMaker(color), size);
541   case eSaturation:
542     return makeSquareShading(HueValueShadeMaker(color), size);
543   case eValue:
544     return makeSquareShading(HueSaturationShadeMaker(color), size);
545   default:
546     assert(0);
547   }
548   return QPixmap();
549 }
550 
551 //-----------------------------------------------------------------------------
552 }  // namespace
553 //-----------------------------------------------------------------------------
554 
555 //*****************************************************************************
556 //    HexagonalColorWheel  implementation
557 //*****************************************************************************
558 
HexagonalColorWheel(QWidget * parent)559 HexagonalColorWheel::HexagonalColorWheel(QWidget *parent)
560     : GLWidgetForHighDpi(parent)
561     , m_bgColor(128, 128, 128)  // defaul value in case this value does not set
562                                 // in the style sheet
563 {
564   setObjectName("HexagonalColorWheel");
565   setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
566   setFocusPolicy(Qt::NoFocus);
567   m_currentWheel = none;
568   if (Preferences::instance()->isColorCalibrationEnabled())
569     m_lutCalibrator = new LutCalibrator();
570 }
571 
572 //-----------------------------------------------------------------------------
573 
~HexagonalColorWheel()574 HexagonalColorWheel::~HexagonalColorWheel() {
575   if (m_fbo) delete m_fbo;
576 }
577 
578 //-----------------------------------------------------------------------------
579 
updateColorCalibration()580 void HexagonalColorWheel::updateColorCalibration() {
581   if (Preferences::instance()->isColorCalibrationEnabled()) {
582     makeCurrent();
583     if (!m_lutCalibrator)
584       m_lutCalibrator = new LutCalibrator();
585     else
586       m_lutCalibrator->cleanup();
587     m_lutCalibrator->initialize();
588     connect(context(), SIGNAL(aboutToBeDestroyed()), this,
589             SLOT(onContextAboutToBeDestroyed()));
590     if (m_lutCalibrator->isValid() && !m_fbo)
591       m_fbo = new QOpenGLFramebufferObject(width(), height());
592     doneCurrent();
593   }
594   update();
595 }
596 
597 //-----------------------------------------------------------------------------
598 
showEvent(QShowEvent *)599 void HexagonalColorWheel::showEvent(QShowEvent *) {
600   if (m_cuedCalibrationUpdate) {
601     updateColorCalibration();
602     m_cuedCalibrationUpdate = false;
603   }
604 }
605 
606 //-----------------------------------------------------------------------------
607 
initializeGL()608 void HexagonalColorWheel::initializeGL() {
609   initializeOpenGLFunctions();
610 
611   // to be computed once through the software
612   if (m_lutCalibrator && !m_lutCalibrator->isInitialized()) {
613     m_lutCalibrator->initialize();
614     connect(context(), SIGNAL(aboutToBeDestroyed()), this,
615             SLOT(onContextAboutToBeDestroyed()));
616   }
617 
618   QColor const color = getBGColor();
619   glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF());
620 
621   // Without the following lines, the wheel in a floating style editor
622   // dissapears on switching the room due to context switching.
623   if (m_firstInitialized)
624     m_firstInitialized = false;
625   else {
626     resizeGL(width(), height());
627     update();
628   }
629 }
630 
631 //-----------------------------------------------------------------------------
632 
resizeGL(int w,int h)633 void HexagonalColorWheel::resizeGL(int w, int h) {
634   w *= getDevPixRatio();
635   h *= getDevPixRatio();
636   float d                 = (w - 5.0f) / 2.5f;
637   bool isHorizontallyLong = ((d * 1.732f) < h) ? false : true;
638 
639   if (isHorizontallyLong) {
640     m_triEdgeLen = (float)h / 1.732f;
641     m_triHeight  = (float)h / 2.0f;
642     m_wheelPosition.setX(((float)w - (m_triEdgeLen * 2.5f + 5.0f)) / 2.0f);
643     m_wheelPosition.setY(0.0f);
644   } else {
645     m_triEdgeLen = d;
646     m_triHeight  = m_triEdgeLen * 0.866f;
647     m_wheelPosition.setX(0.0f);
648     m_wheelPosition.setY(((float)h - (m_triHeight * 2.0f)) / 2.0f);
649   }
650 
651   // set all vertices positions
652   m_wp[0].setX(m_triEdgeLen);
653   m_wp[0].setY(m_triHeight);
654   m_wp[1].setX(m_triEdgeLen * 0.5f);
655   m_wp[1].setY(0.0f);
656   m_wp[2].setX(0.0f);
657   m_wp[2].setY(m_triHeight);
658   m_wp[3].setX(m_triEdgeLen * 0.5f);
659   m_wp[3].setY(m_triHeight * 2.0f);
660   m_wp[4].setX(m_triEdgeLen * 1.5f);
661   m_wp[4].setY(m_triHeight * 2.0f);
662   m_wp[5].setX(m_triEdgeLen * 2.0f);
663   m_wp[5].setY(m_triHeight);
664   m_wp[6].setX(m_triEdgeLen * 1.5f);
665   m_wp[6].setY(0.0f);
666 
667   m_leftp[0].setX(m_wp[6].x() + 5.0f);
668   m_leftp[0].setY(0.0f);
669   m_leftp[1].setX(m_leftp[0].x() + m_triEdgeLen);
670   m_leftp[1].setY(m_triHeight * 2.0f);
671   m_leftp[2].setX(m_leftp[1].x());
672   m_leftp[2].setY(0.0f);
673 
674   // GL settings
675   glViewport(0, 0, w, h);
676   glMatrixMode(GL_PROJECTION);
677   glLoadIdentity();
678   glOrtho(0.0, (GLdouble)w, (GLdouble)h, 0.0, 1.0, -1.0);
679 
680   // remake fbo with new size
681   if (m_lutCalibrator && m_lutCalibrator->isValid()) {
682     if (m_fbo) delete m_fbo;
683     m_fbo = new QOpenGLFramebufferObject(w, h);
684   }
685 }
686 
687 //-----------------------------------------------------------------------------
688 
paintGL()689 void HexagonalColorWheel::paintGL() {
690   // call ClearColor() here in order to update bg color when the stylesheet is
691   // switched
692   QColor const color = getBGColor();
693   glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF());
694 
695   glMatrixMode(GL_MODELVIEW);
696 
697   if (m_lutCalibrator && m_lutCalibrator->isValid()) m_fbo->bind();
698 
699   glClear(GL_COLOR_BUFFER_BIT);
700 
701   float v = (float)m_color.getValue(eValue) / 100.0f;
702 
703   glPushMatrix();
704 
705   // draw hexagonal color wheel
706   glTranslatef(m_wheelPosition.rx(), m_wheelPosition.ry(), 0.0f);
707   glBegin(GL_TRIANGLE_FAN);
708   glColor3f(v, v, v);
709   glVertex2f(m_wp[0].x(), m_wp[0].y());
710 
711   glColor3f(0.0f, v, 0.0f);
712   glVertex2f(m_wp[1].x(), m_wp[1].y());
713   glColor3f(0.0f, v, v);
714   glVertex2f(m_wp[2].x(), m_wp[2].y());
715   glColor3f(0.0f, 0.0f, v);
716   glVertex2f(m_wp[3].x(), m_wp[3].y());
717   glColor3f(v, 0.0f, v);
718   glVertex2f(m_wp[4].x(), m_wp[4].y());
719   glColor3f(v, 0.0f, 0.0f);
720   glVertex2f(m_wp[5].x(), m_wp[5].y());
721   glColor3f(v, v, 0.0f);
722   glVertex2f(m_wp[6].x(), m_wp[6].y());
723   glColor3f(0.0f, v, 0.0f);
724   glVertex2f(m_wp[1].x(), m_wp[1].y());
725   glEnd();
726 
727   QColor leftCol = QColor().fromHsv(m_color.getValue(eHue), 255, 255);
728 
729   // draw triangle color picker
730   glBegin(GL_TRIANGLES);
731   glColor3f(leftCol.redF(), leftCol.greenF(), leftCol.blueF());
732   glVertex2f(m_leftp[0].x(), m_leftp[0].y());
733   glColor3f(0.0f, 0.0f, 0.0f);
734   glVertex2f(m_leftp[1].x(), m_leftp[1].y());
735   glColor3f(1.0f, 1.0f, 1.0f);
736   glVertex2f(m_leftp[2].x(), m_leftp[2].y());
737   glEnd();
738 
739   // draw small quad at current color position
740   drawCurrentColorMark();
741 
742   glPopMatrix();
743 
744   if (m_lutCalibrator && m_lutCalibrator->isValid())
745     m_lutCalibrator->onEndDraw(m_fbo);
746 }
747 
748 //-----------------------------------------------------------------------------
749 
drawCurrentColorMark()750 void HexagonalColorWheel::drawCurrentColorMark() {
751   int h;
752   float s, v;
753 
754   // show hue in a counterclockwise fashion
755   h = 360 - m_color.getValue(eHue);
756 
757   s = (float)m_color.getValue(eSaturation) / 100.0f;
758   v = (float)m_color.getValue(eValue) / 100.0f;
759 
760   // d is a distance from a center of the wheel
761   float d, phi;
762   phi = (float)(h % 60 - 30) / 180.0f * 3.1415f;
763   d   = s * m_triHeight / cosf(phi);
764 
765   // set marker color
766   if (v > 0.4f)
767     glColor3f(0.0f, 0.0f, 0.0f);
768   else
769     glColor3f(1.0f, 1.0f, 1.0f);
770 
771   // draw marker (in the wheel)
772   glPushMatrix();
773   glTranslatef(m_wp[0].x(), m_wp[0].y(), 0.1f);
774   glRotatef(h, 0.0, 0.0, 1.0);
775   glTranslatef(d, 0.0f, 0.0f);
776   glRotatef(-h, 0.0, 0.0, 1.0);
777   glBegin(GL_LINE_LOOP);
778   glVertex2f(-3, -3);
779   glVertex2f(3, -3);
780   glVertex2f(3, 3);
781   glVertex2f(-3, 3);
782   glEnd();
783   glPopMatrix();
784 
785   // draw marker (in the triangle)
786   glPushMatrix();
787   glTranslatef(m_leftp[1].x(), m_leftp[1].y(), 0.1f);
788   glTranslatef(-m_triEdgeLen * v * s, -m_triHeight * v * 2.0f, 0.0f);
789   glBegin(GL_LINE_LOOP);
790   glVertex2f(-3, -3);
791   glVertex2f(3, -3);
792   glVertex2f(3, 3);
793   glVertex2f(-3, 3);
794   glEnd();
795   glPopMatrix();
796 }
797 
798 //-----------------------------------------------------------------------------
799 
mousePressEvent(QMouseEvent * event)800 void HexagonalColorWheel::mousePressEvent(QMouseEvent *event) {
801   if (~event->buttons() & Qt::LeftButton) return;
802 
803   // check whether the mouse cursor is in the wheel or in the triangle (or
804   // nothing).
805   QPoint curPos = event->pos() * getDevPixRatio();
806 
807   QPolygonF wheelPolygon;
808   // in the case of the wheel
809   wheelPolygon << m_wp[1] << m_wp[2] << m_wp[3] << m_wp[4] << m_wp[5]
810                << m_wp[6];
811   wheelPolygon.translate(m_wheelPosition);
812   if (wheelPolygon.toPolygon().containsPoint(curPos, Qt::OddEvenFill)) {
813     m_currentWheel = leftWheel;
814     clickLeftWheel(curPos);
815     return;
816   }
817 
818   wheelPolygon.clear();
819   // in the case of the triangle
820   wheelPolygon << m_leftp[0] << m_leftp[1] << m_leftp[2];
821   wheelPolygon.translate(m_wheelPosition);
822   if (wheelPolygon.toPolygon().containsPoint(curPos, Qt::OddEvenFill)) {
823     m_currentWheel = rightTriangle;
824     clickRightTriangle(curPos);
825     return;
826   }
827 
828   //... or, in the case of nothing
829   m_currentWheel = none;
830 }
831 
832 //-----------------------------------------------------------------------------
833 
mouseMoveEvent(QMouseEvent * event)834 void HexagonalColorWheel::mouseMoveEvent(QMouseEvent *event) {
835   // change the behavior according to the current touching wheel
836   switch (m_currentWheel) {
837   case none:
838     break;
839   case leftWheel:
840     clickLeftWheel(event->pos() * getDevPixRatio());
841     break;
842   case rightTriangle:
843     clickRightTriangle(event->pos() * getDevPixRatio());
844     break;
845   }
846 }
847 
848 //-----------------------------------------------------------------------------
849 
mouseReleaseEvent(QMouseEvent * event)850 void HexagonalColorWheel::mouseReleaseEvent(QMouseEvent *event) {
851   m_currentWheel = none;
852   emit colorChanged(m_color, false);
853 }
854 
855 //-----------------------------------------------------------------------------
856 /*! compute hue and saturation position. saturation value must be clamped
857  */
clickLeftWheel(const QPoint & pos)858 void HexagonalColorWheel::clickLeftWheel(const QPoint &pos) {
859   QLineF p(m_wp[0] + m_wheelPosition, QPointF(pos));
860   QLineF horizontal(0, 0, 1, 0);
861   float theta = (p.dy() < 0) ? p.angle(horizontal) : 360 - p.angle(horizontal);
862   float phi   = theta;
863   while (phi >= 60.0f) phi -= 60.0f;
864   phi -= 30.0f;
865   // d is a length from center to edge of the wheel when saturation = 100
866   float d = m_triHeight / cosf(phi / 180.0f * 3.1415f);
867 
868   int h = (int)theta;
869   if (h > 359) h = 359;
870   // clamping
871   int s = (int)(std::min(p.length() / d, 1.0) * 100.0f);
872 
873   m_color.setValues(eValue, h, s);
874 
875   emit colorChanged(m_color, true);
876 }
877 
878 //-----------------------------------------------------------------------------
879 
clickRightTriangle(const QPoint & pos)880 void HexagonalColorWheel::clickRightTriangle(const QPoint &pos) {
881   int s, v;
882   QPointF p = m_leftp[1] + m_wheelPosition - QPointF(pos);
883   if (p.ry() <= 0.0f) {
884     s = 0;
885     v = 0;
886   } else {
887     float v_ratio = std::min((float)(p.ry() / (m_triHeight * 2.0f)), 1.0f);
888     float s_f     = p.rx() / (m_triEdgeLen * v_ratio);
889     v             = (int)(v_ratio * 100.0f);
890     s             = (int)(std::min(std::max(s_f, 0.0f), 1.0f) * 100.0f);
891   }
892   m_color.setValues(eHue, s, v);
893   emit colorChanged(m_color, true);
894 }
895 
896 //-----------------------------------------------------------------------------
897 
onContextAboutToBeDestroyed()898 void HexagonalColorWheel::onContextAboutToBeDestroyed() {
899   if (!m_lutCalibrator) return;
900   makeCurrent();
901   m_lutCalibrator->cleanup();
902   doneCurrent();
903   disconnect(context(), SIGNAL(aboutToBeDestroyed()), this,
904              SLOT(onContextAboutToBeDestroyed()));
905 }
906 
907 //*****************************************************************************
908 //    SquaredColorWheel  implementation
909 //*****************************************************************************
910 
SquaredColorWheel(QWidget * parent)911 SquaredColorWheel::SquaredColorWheel(QWidget *parent)
912     : QWidget(parent), m_channel(eRed), m_color() {}
913 
914 //-----------------------------------------------------------------------------
915 
paintEvent(QPaintEvent *)916 void SquaredColorWheel::paintEvent(QPaintEvent *) {
917   QPainter p(this);
918   // calcolo lo sfondo
919   int size = width();
920 
921   QPixmap bgPixmap = makeSquareShading(m_color, m_channel, size);
922 
923   if (!bgPixmap.isNull()) p.drawTiledPixmap(0, 0, size, size, bgPixmap);
924 
925   int u = 0, v = 0;
926   m_color.getValues(m_channel, u, v);
927   int x = u * width() / ChannelPairMaxValues[m_channel][0];
928   int y = (ChannelPairMaxValues[m_channel][1] - v) * height() /
929           ChannelPairMaxValues[m_channel][1];
930 
931   if (m_color.v() > 127)
932     p.setPen(Qt::black);
933   else
934     p.setPen(Qt::white);
935   p.drawRect(x - 1, y - 1, 3, 3);
936 }
937 
938 //-----------------------------------------------------------------------------
939 
click(const QPoint & pos)940 void SquaredColorWheel::click(const QPoint &pos) {
941   int u = ChannelPairMaxValues[m_channel][0] * pos.x() / width();
942   int v = ChannelPairMaxValues[m_channel][1] * (height() - pos.y()) / height();
943   u     = tcrop(u, 0, ChannelPairMaxValues[m_channel][0]);
944   v     = tcrop(v, 0, ChannelPairMaxValues[m_channel][1]);
945   m_color.setValues(m_channel, u, v);
946   update();
947   emit colorChanged(m_color, true);
948 }
949 
950 //-----------------------------------------------------------------------------
951 
mousePressEvent(QMouseEvent * event)952 void SquaredColorWheel::mousePressEvent(QMouseEvent *event) {
953   if (event->buttons() & Qt::LeftButton) click(event->pos());
954 }
955 
956 //-----------------------------------------------------------------------------
957 
mouseMoveEvent(QMouseEvent * event)958 void SquaredColorWheel::mouseMoveEvent(QMouseEvent *event) {
959   if (event->buttons() & Qt::LeftButton) click(event->pos());
960 }
961 
962 //-----------------------------------------------------------------------------
963 
mouseReleaseEvent(QMouseEvent * event)964 void SquaredColorWheel::mouseReleaseEvent(QMouseEvent *event) {
965   emit colorChanged(m_color, false);
966 }
967 
968 //-----------------------------------------------------------------------------
969 
setColor(const ColorModel & color)970 void SquaredColorWheel::setColor(const ColorModel &color) { m_color = color; }
971 
972 //-----------------------------------------------------------------------------
973 
setChannel(int channel)974 void SquaredColorWheel::setChannel(int channel) {
975   assert(0 <= channel && channel < 7);
976   m_channel = (ColorChannel)channel;
977   update();
978 }
979 
980 //*****************************************************************************
981 //    ColorSlider  implementation
982 //*****************************************************************************
983 
ColorSlider(Qt::Orientation orientation,QWidget * parent)984 ColorSlider::ColorSlider(Qt::Orientation orientation, QWidget *parent)
985     : QSlider(orientation, parent), m_channel(eRed), m_color() {
986   setFocusPolicy(Qt::NoFocus);
987 
988   setOrientation(orientation);
989   setMinimum(0);
990   setMaximum(ChannelMaxValues[m_channel]);
991 
992   setMinimumHeight(7);
993   setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
994 
995   // Attenzione: necessario per poter individuare l'oggetto nel file di
996   // definizione dello stile
997   setObjectName("colorSlider");
998 }
999 
1000 //-----------------------------------------------------------------------------
1001 
setChannel(ColorChannel channel)1002 void ColorSlider::setChannel(ColorChannel channel) {
1003   if (m_channel == channel) return;
1004   m_channel = channel;
1005   setMaximum(ChannelMaxValues[m_channel]);
1006 }
1007 
1008 //-----------------------------------------------------------------------------
1009 
setColor(const ColorModel & color)1010 void ColorSlider::setColor(const ColorModel &color) { m_color = color; }
1011 
1012 //-----------------------------------------------------------------------------
1013 
paintEvent(QPaintEvent * event)1014 void ColorSlider::paintEvent(QPaintEvent *event) {
1015   QPainter p(this);
1016 
1017   int x = rect().x();
1018   int y = rect().y();
1019   int w = width();
1020   int h = height();
1021 
1022   bool isVertical = orientation() == Qt::Vertical;
1023 
1024   if (!isVertical) h -= 5;
1025 
1026   QPixmap bgPixmap =
1027       makeLinearShading(m_color, m_channel, isVertical ? h : w, isVertical);
1028 
1029   if (m_channel == eAlpha) {
1030     static QPixmap checkboard(":Resources/backg.png");
1031     p.drawTiledPixmap(x, y + 1, w, h, checkboard);
1032   }
1033 
1034   if (!bgPixmap.isNull()) {
1035     p.drawTiledPixmap(x, y + 1, w, h, bgPixmap);
1036   }
1037 
1038   /*!
1039      Bug in Qt 4.3: The vertical Slider cannot be styled due to a bug.
1040      In this case we draw "manually" the slider handle at correct position
1041   */
1042   if (isVertical) {
1043     int pos = QStyle::sliderPositionFromValue(minimum(), maximum(), value(),
1044                                               h - 9, true);
1045     static QPixmap vHandlePixmap(":Resources/v_chandle.png");
1046     p.drawPixmap(0, pos, vHandlePixmap);
1047   } else {
1048     static QPixmap hHandleUpPm(":Resources/h_chandleUp.png");
1049     static QPixmap hHandleDownPm(":Resources/h_chandleDown.png");
1050     static QPixmap hHandleCenterPm(":Resources/h_chandleCenter.png");
1051     int pos = QStyle::sliderPositionFromValue(
1052         0, maximum(), value(), width() - hHandleCenterPm.width(), false);
1053     p.drawPixmap(pos, 0, hHandleUpPm);
1054     p.drawPixmap(pos, height() - hHandleDownPm.height(), hHandleDownPm);
1055     p.drawPixmap(pos, hHandleUpPm.height(), hHandleCenterPm.width(),
1056                  height() - hHandleUpPm.height() - hHandleDownPm.height(),
1057                  hHandleCenterPm);
1058   }
1059 };
1060 
1061 //-----------------------------------------------------------------------------
1062 
mousePressEvent(QMouseEvent * event)1063 void ColorSlider::mousePressEvent(QMouseEvent *event) {
1064   // vogliamo che facendo click sullo slider, lontano dall'handle
1065   // l'handle salti subito nella posizione giusta invece di far partire
1066   // l'autorepeat.
1067   //
1068   // cfr. qslider.cpp:429: sembra che questo comportamento si possa ottenere
1069   // anche con SH_Slider_AbsoluteSetButtons. Ma non capisco come si possa fare
1070   // per definire quest hint
1071   QStyleOptionSlider opt;
1072   initStyleOption(&opt);
1073   const QRect handleRect = style()->subControlRect(
1074       QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this);
1075   if (!handleRect.contains(event->pos())) {
1076     const QPoint handleCenter = handleRect.center();
1077     const QRect grooveRect    = style()->subControlRect(
1078         QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, this);
1079     int pos, span;
1080     bool upsideDown = false;
1081     if (opt.orientation == Qt::Vertical) {
1082       upsideDown     = true;
1083       int handleSize = handleRect.height();
1084       pos            = event->pos().y() - handleSize / 2;
1085       span           = grooveRect.height() - handleSize;
1086     } else {
1087       int handleSize = QPixmap(":Resources/h_chandleCenter.png").width();
1088       pos            = event->pos().x() - handleSize / 2;
1089       span           = grooveRect.width() - handleSize;
1090     }
1091     int value = QStyle::sliderValueFromPosition(minimum(), maximum(), pos, span,
1092                                                 upsideDown);
1093     setValue(value);
1094   }
1095   QSlider::mousePressEvent(event);
1096 }
1097 
1098 //-----------------------------------------------------------------------------
1099 
mouseReleaseEvent(QMouseEvent * event)1100 void ColorSlider::mouseReleaseEvent(QMouseEvent *event) {
1101   emit sliderReleased();
1102 }
1103 
1104 //*****************************************************************************
1105 //    ArrowButton  implementation
1106 //*****************************************************************************
1107 
ArrowButton(QWidget * parent,Qt::Orientation orientation,bool isFirstArrow)1108 ArrowButton::ArrowButton(QWidget *parent, Qt::Orientation orientation,
1109                          bool isFirstArrow)
1110     : QToolButton(parent)
1111     , m_orientaion(orientation)
1112     , m_isFirstArrow(isFirstArrow)
1113     , m_timerId(0)
1114     , m_firstTimerId(0) {
1115   setFixedSize(10, 10);
1116   setObjectName("StyleEditorArrowButton");
1117   bool isVertical = orientation == Qt::Vertical;
1118   if (m_isFirstArrow) {
1119     if (isVertical)
1120       setIcon(createQIconPNG("arrow_up"));
1121     else
1122       setIcon(createQIconPNG("arrow_left"));
1123   } else {
1124     if (isVertical)
1125       setIcon(createQIconPNG("arrow_down"));
1126     else
1127       setIcon(createQIconPNG("arrow_right"));
1128   }
1129   connect(this, SIGNAL(pressed()), this, SLOT(onPressed()));
1130   connect(this, SIGNAL(released()), this, SLOT(onRelease()));
1131 }
1132 
1133 //-----------------------------------------------------------------------------
1134 
timerEvent(QTimerEvent * event)1135 void ArrowButton::timerEvent(QTimerEvent *event) {
1136   if (m_firstTimerId != 0) {
1137     killTimer(m_firstTimerId);
1138     m_firstTimerId = 0;
1139     m_timerId      = startTimer(10);
1140   }
1141   notifyChanged();
1142 }
1143 
1144 //-----------------------------------------------------------------------------
1145 
notifyChanged()1146 void ArrowButton::notifyChanged() {
1147   bool isVertical = m_orientaion == Qt::Vertical;
1148   if ((m_isFirstArrow && !isVertical) || (!m_isFirstArrow && isVertical))
1149     emit remove();
1150   else
1151     emit add();
1152 }
1153 
1154 //-----------------------------------------------------------------------------
1155 
onPressed()1156 void ArrowButton::onPressed() {
1157   notifyChanged();
1158   assert(m_timerId == 0 && m_firstTimerId == 0);
1159   m_firstTimerId = startTimer(500);
1160 }
1161 
1162 //-----------------------------------------------------------------------------
1163 
onRelease()1164 void ArrowButton::onRelease() {
1165   if (m_firstTimerId != 0) {
1166     killTimer(m_firstTimerId);
1167     m_firstTimerId = 0;
1168   } else if (m_timerId != 0) {
1169     killTimer(m_timerId);
1170     m_timerId = 0;
1171   }
1172 }
1173 
1174 //*****************************************************************************
1175 //    ColorSliderBar  implementation
1176 //*****************************************************************************
1177 
ColorSliderBar(QWidget * parent,Qt::Orientation orientation)1178 ColorSliderBar::ColorSliderBar(QWidget *parent, Qt::Orientation orientation)
1179     : QWidget(parent) {
1180   bool isVertical = orientation == Qt::Vertical;
1181 
1182   ArrowButton *first = new ArrowButton(this, orientation, true);
1183   connect(first, SIGNAL(remove()), this, SLOT(onRemove()));
1184   connect(first, SIGNAL(add()), this, SLOT(onAdd()));
1185 
1186   m_colorSlider = new ColorSlider(orientation, this);
1187   if (isVertical) m_colorSlider->setMaximumWidth(22);
1188 
1189   ArrowButton *last = new ArrowButton(this, orientation, false);
1190   connect(last, SIGNAL(add()), this, SLOT(onAdd()));
1191   connect(last, SIGNAL(remove()), this, SLOT(onRemove()));
1192 
1193   connect(m_colorSlider, SIGNAL(valueChanged(int)), this,
1194           SIGNAL(valueChanged(int)));
1195   connect(m_colorSlider, SIGNAL(sliderReleased()), this,
1196           SIGNAL(valueChanged()));
1197 
1198   QBoxLayout *layout;
1199   if (!isVertical)
1200     layout = new QHBoxLayout(this);
1201   else
1202     layout = new QVBoxLayout(this);
1203 
1204   layout->setSpacing(0);
1205   layout->setMargin(0);
1206   layout->addWidget(first, 0, Qt::AlignCenter);
1207   layout->addWidget(m_colorSlider, 1);
1208   layout->addWidget(last, 0, Qt::AlignCenter);
1209   setLayout(layout);
1210 }
1211 
1212 //-----------------------------------------------------------------------------
1213 
onRemove()1214 void ColorSliderBar::onRemove() {
1215   int value = m_colorSlider->value();
1216   if (value <= m_colorSlider->minimum()) return;
1217   m_colorSlider->setValue(value - 1);
1218 }
1219 
1220 //-----------------------------------------------------------------------------
1221 
onAdd()1222 void ColorSliderBar::onAdd() {
1223   int value = m_colorSlider->value();
1224   if (value >= m_colorSlider->maximum()) return;
1225   m_colorSlider->setValue(value + 1);
1226 }
1227 
1228 //*****************************************************************************
1229 //    ChannelLineEdit  implementation
1230 //*****************************************************************************
1231 
mousePressEvent(QMouseEvent * e)1232 void ChannelLineEdit::mousePressEvent(QMouseEvent *e) {
1233   IntLineEdit::mousePressEvent(e);
1234 
1235   if (!m_isEditing) {
1236     selectAll();
1237     m_isEditing = true;
1238   }
1239 }
1240 
1241 //-----------------------------------------------------------------------------
1242 
focusOutEvent(QFocusEvent * e)1243 void ChannelLineEdit::focusOutEvent(QFocusEvent *e) {
1244   IntLineEdit::focusOutEvent(e);
1245 
1246   m_isEditing = false;
1247 }
1248 
1249 //-----------------------------------------------------------------------------
1250 
paintEvent(QPaintEvent * e)1251 void ChannelLineEdit::paintEvent(QPaintEvent *e) {
1252   IntLineEdit::paintEvent(e);
1253 
1254   /* Now that stylesheets added lineEdit focus this is likely redundant,
1255    * commenting out in-case it is still required.
1256   if (m_isEditing) {
1257     QPainter p(this);
1258     p.setPen(Qt::yellow);
1259     p.drawRect(rect().adjusted(0, 0, -1, -1));
1260   }
1261   */
1262 }
1263 
1264 //*****************************************************************************
1265 //    ColorChannelControl  implementation
1266 //*****************************************************************************
1267 
ColorChannelControl(ColorChannel channel,QWidget * parent)1268 ColorChannelControl::ColorChannelControl(ColorChannel channel, QWidget *parent)
1269     : QWidget(parent), m_channel(channel), m_value(0), m_signalEnabled(true) {
1270   setFocusPolicy(Qt::NoFocus);
1271 
1272   QStringList channelList;
1273   channelList << tr("R") << tr("G") << tr("B") << tr("A") << tr("H") << tr("S")
1274               << tr("V");
1275   assert(0 <= (int)m_channel && (int)m_channel < 7);
1276   QString text = channelList.at(m_channel);
1277   m_label      = new QLabel(text, this);
1278 
1279   int minValue = 0;
1280   int maxValue = 0;
1281   if (m_channel < 4)  // RGBA
1282     maxValue = 255;
1283   else if (m_channel == 4)  // H
1284     maxValue = 359;
1285   else  // SV
1286     maxValue = 100;
1287 
1288   m_field  = new ChannelLineEdit(this, 0, minValue, maxValue);
1289   m_slider = new ColorSlider(Qt::Horizontal, this);
1290 
1291   // buttons to increment/decrement the values by 1
1292   QPushButton *addButton = new QPushButton(this);
1293   QPushButton *subButton = new QPushButton(this);
1294 
1295   m_slider->setValue(0);
1296   m_slider->setChannel(m_channel);
1297 
1298   m_label->setObjectName("colorSliderLabel");
1299   m_label->setFixedWidth(11);
1300   m_label->setMinimumHeight(7);
1301   m_label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
1302 
1303   m_field->setObjectName("colorSliderField");
1304   m_field->setFixedWidth(fontMetrics().width('0') * 4);
1305   m_field->setMinimumHeight(7);
1306 
1307   addButton->setObjectName("colorSliderAddButton");
1308   subButton->setObjectName("colorSliderSubButton");
1309   addButton->setFixedWidth(18);
1310   subButton->setFixedWidth(18);
1311   addButton->setMinimumHeight(7);
1312   subButton->setMinimumHeight(7);
1313   addButton->setFlat(true);
1314   subButton->setFlat(true);
1315   addButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
1316   subButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
1317   addButton->setAutoRepeat(true);
1318   subButton->setAutoRepeat(true);
1319   addButton->setAutoRepeatInterval(25);
1320   subButton->setAutoRepeatInterval(25);
1321   addButton->setFocusPolicy(Qt::NoFocus);
1322   subButton->setFocusPolicy(Qt::NoFocus);
1323 
1324   QHBoxLayout *mainLayout = new QHBoxLayout(this);
1325   mainLayout->setMargin(0);
1326   mainLayout->setSpacing(1);
1327   {
1328     mainLayout->addWidget(m_label, 0);
1329     mainLayout->addSpacing(2);
1330     mainLayout->addWidget(m_field, 0);
1331     mainLayout->addSpacing(2);
1332     mainLayout->addWidget(subButton, 0);
1333     mainLayout->addWidget(m_slider, 1);
1334     mainLayout->addWidget(addButton, 0);
1335   }
1336   setLayout(mainLayout);
1337 
1338   bool ret =
1339       connect(m_field, SIGNAL(editingFinished()), this, SLOT(onFieldChanged()));
1340   ret = ret && connect(m_slider, SIGNAL(valueChanged(int)), this,
1341                        SLOT(onSliderChanged(int)));
1342   ret = ret && connect(m_slider, SIGNAL(sliderReleased()), this,
1343                        SLOT(onSliderReleased()));
1344   ret = ret &&
1345         connect(addButton, SIGNAL(clicked()), this, SLOT(onAddButtonClicked()));
1346   ret = ret &&
1347         connect(subButton, SIGNAL(clicked()), this, SLOT(onSubButtonClicked()));
1348   assert(ret);
1349 }
1350 
1351 //-----------------------------------------------------------------------------
1352 
onAddButtonClicked()1353 void ColorChannelControl::onAddButtonClicked() {
1354   m_slider->setValue(m_slider->value() + 1);
1355 }
1356 
1357 //-----------------------------------------------------------------------------
1358 
onSubButtonClicked()1359 void ColorChannelControl::onSubButtonClicked() {
1360   m_slider->setValue(m_slider->value() - 1);
1361 }
1362 
1363 //-----------------------------------------------------------------------------
1364 
setColor(const ColorModel & color)1365 void ColorChannelControl::setColor(const ColorModel &color) {
1366   m_color = color;
1367   m_slider->setColor(color);
1368   int value = color.getValue(m_channel);
1369   if (m_value != value) {
1370     bool signalEnabled = m_signalEnabled;
1371     m_signalEnabled    = false;
1372     m_value            = value;
1373     m_field->setText(QString::number(value));
1374     m_slider->setValue(value);
1375     m_signalEnabled = signalEnabled;
1376   }
1377 }
1378 
1379 //-----------------------------------------------------------------------------
1380 
onFieldChanged()1381 void ColorChannelControl::onFieldChanged() {
1382   int value = m_field->text().toInt();
1383   if (m_value == value) return;
1384   m_value = value;
1385   m_slider->setValue(value);
1386   if (m_signalEnabled) {
1387     m_color.setValue(m_channel, value);
1388     emit colorChanged(m_color, false);
1389   }
1390 }
1391 
1392 //-----------------------------------------------------------------------------
1393 
onSliderChanged(int value)1394 void ColorChannelControl::onSliderChanged(int value) {
1395   if (m_value == value) return;
1396   m_value = value;
1397   m_field->setText(QString::number(value));
1398   if (m_signalEnabled) {
1399     m_color.setValue(m_channel, value);
1400     emit colorChanged(m_color, true);
1401   }
1402 }
1403 
1404 //-----------------------------------------------------------------------------
1405 
onSliderReleased()1406 void ColorChannelControl::onSliderReleased() {
1407   emit colorChanged(m_color, false);
1408 }
1409 
1410 //*****************************************************************************
1411 //    StyleEditorPage  implementation
1412 //*****************************************************************************
1413 
StyleEditorPage(QWidget * parent)1414 StyleEditorPage::StyleEditorPage(QWidget *parent) : QFrame(parent) {
1415   setFocusPolicy(Qt::NoFocus);
1416 
1417   // It is necessary for the style sheets
1418   setObjectName("styleEditorPage");
1419   setFrameStyle(QFrame::StyledPanel);
1420 }
1421 
1422 //*****************************************************************************
1423 //    ColorParameterSelector  implementation
1424 //*****************************************************************************
1425 
ColorParameterSelector(QWidget * parent)1426 ColorParameterSelector::ColorParameterSelector(QWidget *parent)
1427     : QWidget(parent)
1428     , m_index(-1)
1429     , m_chipSize(21, 21)
1430     , m_chipOrigin(0, 1)
1431     , m_chipDelta(21, 0) {
1432   setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
1433 }
1434 
1435 //-----------------------------------------------------------------------------
1436 
paintEvent(QPaintEvent * event)1437 void ColorParameterSelector::paintEvent(QPaintEvent *event) {
1438   if (m_colors.empty()) return;
1439   QPainter p(this);
1440   int i;
1441   QRect currentChipRect = QRect();
1442   for (i = 0; i < (int)m_colors.size(); i++) {
1443     QRect chipRect(m_chipOrigin + i * m_chipDelta, m_chipSize);
1444     p.fillRect(chipRect, m_colors[i]);
1445     if (i == m_index) currentChipRect = chipRect;
1446   }
1447   // Current index border
1448   if (!currentChipRect.isEmpty()) {
1449     p.setPen(QColor(199, 202, 50));
1450     p.drawRect(currentChipRect.adjusted(0, 0, -1, -1));
1451     p.setPen(Qt::white);
1452     p.drawRect(currentChipRect.adjusted(1, 1, -2, -2));
1453     p.setPen(Qt::black);
1454     p.drawRect(currentChipRect.adjusted(2, 2, -3, -3));
1455   }
1456 }
1457 
1458 //-----------------------------------------------------------------------------
1459 
setStyle(const TColorStyle & style)1460 void ColorParameterSelector::setStyle(const TColorStyle &style) {
1461   int count = style.getColorParamCount();
1462   if (count <= 1) {
1463     clear();
1464     return;
1465   }
1466   if (m_colors.size() != count) {
1467     m_index = 0;
1468     m_colors.resize(count);
1469   }
1470   int i;
1471   for (i = 0; i < count; i++) {
1472     TPixel32 color = style.getColorParamValue(i);
1473     m_colors[i]    = QColor(color.r, color.g, color.b, color.m);
1474   }
1475   update();
1476 }
1477 
1478 //-----------------------------------------------------------------------------
1479 
clear()1480 void ColorParameterSelector::clear() {
1481   if (m_colors.size() != 0) m_colors.clear();
1482   m_index = -1;
1483   update();
1484 }
1485 
1486 //-----------------------------------------------------------------------------
1487 
mousePressEvent(QMouseEvent * event)1488 void ColorParameterSelector::mousePressEvent(QMouseEvent *event) {
1489   QPoint pos = event->pos() - m_chipOrigin;
1490   int index  = pos.x() / m_chipDelta.x();
1491   QRect chipRect(index * m_chipDelta, m_chipSize);
1492   if (chipRect.contains(pos)) {
1493     m_index = index;
1494     emit colorParamChanged();
1495     update();
1496   }
1497 }
1498 
1499 //-----------------------------------------------------------------------------
1500 
sizeHint() const1501 QSize ColorParameterSelector::sizeHint() const {
1502   return QSize(m_chipOrigin.x() + (m_colors.size() - 1) * m_chipDelta.x() +
1503                    m_chipSize.width(),
1504                m_chipOrigin.y() + m_chipSize.height());
1505 }
1506 
1507 //*****************************************************************************
1508 //    PlainColorPage  implementation
1509 //*****************************************************************************
1510 
PlainColorPage(QWidget * parent)1511 PlainColorPage::PlainColorPage(QWidget *parent)
1512     : StyleEditorPage(parent), m_color(), m_signalEnabled(true) {
1513   setFocusPolicy(Qt::NoFocus);
1514 
1515   // m_squaredColorWheel = new SquaredColorWheel(this);
1516 
1517   // m_verticalSlider = new ColorSliderBar(this, Qt::Vertical);
1518 
1519   m_hexagonalColorWheel = new HexagonalColorWheel(this);
1520 
1521   /*
1522   QButtonGroup *channelButtonGroup = new QButtonGroup();
1523   int i;
1524   for (i = 0; i<7; i++)
1525   {
1526           if (i != (int)eAlpha)
1527           {
1528                   QRadioButton *button = new QRadioButton(this);
1529                   m_modeButtons[i] = button;
1530                   if (i == 0) button->setChecked(true);
1531                   channelButtonGroup->addButton(button, i);
1532                   //slidersLayout->addWidget(button,i,0);
1533                   //とりあえず隠す
1534                   m_modeButtons[i]->hide();
1535           }
1536           else
1537                   m_modeButtons[i] = 0;
1538 
1539           m_channelControls[i] = new ColorChannelControl((ColorChannel)i, this);
1540           m_channelControls[i]->setColor(m_color);
1541           bool ret = connect(m_channelControls[i], SIGNAL(colorChanged(const
1542   ColorModel &, bool)),
1543                   this, SLOT(onControlChanged(const ColorModel &, bool)));
1544   }
1545   */
1546   for (int i = 0; i < 7; i++) {
1547     m_channelControls[i] = new ColorChannelControl((ColorChannel)i, this);
1548     m_channelControls[i]->setColor(m_color);
1549     bool ret = connect(m_channelControls[i],
1550                        SIGNAL(colorChanged(const ColorModel &, bool)), this,
1551                        SLOT(onControlChanged(const ColorModel &, bool)));
1552   }
1553 
1554   m_wheelFrame = new QFrame(this);
1555   m_hsvFrame   = new QFrame(this);
1556   m_alphaFrame = new QFrame(this);
1557   m_rgbFrame   = new QFrame(this);
1558 
1559   m_slidersContainer = new QFrame(this);
1560   m_vSplitter        = new QSplitter(this);
1561 
1562   //プロパティの設定
1563   // channelButtonGroup->setExclusive(true);
1564 
1565   m_wheelFrame->setObjectName("PlainColorPageParts");
1566   m_hsvFrame->setObjectName("PlainColorPageParts");
1567   m_alphaFrame->setObjectName("PlainColorPageParts");
1568   m_rgbFrame->setObjectName("PlainColorPageParts");
1569 
1570   m_vSplitter->setOrientation(Qt::Vertical);
1571   m_vSplitter->setFocusPolicy(Qt::NoFocus);
1572 
1573   // m_verticalSlider->hide();
1574   // m_squaredColorWheel->hide();
1575   // m_ghibliColorWheel->hide();
1576 
1577   // layout
1578   QVBoxLayout *mainLayout = new QVBoxLayout();
1579   mainLayout->setSpacing(0);
1580   mainLayout->setMargin(0);
1581   {
1582     QHBoxLayout *wheelLayout = new QHBoxLayout();
1583     wheelLayout->setMargin(5);
1584     wheelLayout->setSpacing(0);
1585     { wheelLayout->addWidget(m_hexagonalColorWheel); }
1586     m_wheelFrame->setLayout(wheelLayout);
1587     m_vSplitter->addWidget(m_wheelFrame);
1588 
1589     QVBoxLayout *slidersLayout = new QVBoxLayout();
1590     slidersLayout->setMargin(0);
1591     slidersLayout->setSpacing(0);
1592     {
1593       QVBoxLayout *hsvLayout = new QVBoxLayout();
1594       hsvLayout->setMargin(4);
1595       hsvLayout->setSpacing(4);
1596       {
1597         hsvLayout->addWidget(m_channelControls[eHue]);
1598         hsvLayout->addWidget(m_channelControls[eSaturation]);
1599         hsvLayout->addWidget(m_channelControls[eValue]);
1600       }
1601       m_hsvFrame->setLayout(hsvLayout);
1602       slidersLayout->addWidget(m_hsvFrame, 3);
1603 
1604       QVBoxLayout *alphaLayout = new QVBoxLayout();
1605       alphaLayout->setMargin(4);
1606       alphaLayout->setSpacing(4);
1607       { alphaLayout->addWidget(m_channelControls[eAlpha]); }
1608       m_alphaFrame->setLayout(alphaLayout);
1609       slidersLayout->addWidget(m_alphaFrame, 1);
1610 
1611       QVBoxLayout *rgbLayout = new QVBoxLayout();
1612       rgbLayout->setMargin(4);
1613       rgbLayout->setSpacing(4);
1614       {
1615         rgbLayout->addWidget(m_channelControls[eRed]);
1616         rgbLayout->addWidget(m_channelControls[eGreen]);
1617         rgbLayout->addWidget(m_channelControls[eBlue]);
1618       }
1619       m_rgbFrame->setLayout(rgbLayout);
1620       slidersLayout->addWidget(m_rgbFrame, 3);
1621     }
1622     m_slidersContainer->setLayout(slidersLayout);
1623     m_vSplitter->addWidget(m_slidersContainer);
1624 
1625     mainLayout->addWidget(m_vSplitter, 1);
1626   }
1627   setLayout(mainLayout);
1628 
1629   QList<int> list;
1630   list << rect().height() / 2 << rect().height() / 2;
1631   m_vSplitter->setSizes(list);
1632 
1633   // connect(m_squaredColorWheel, SIGNAL(colorChanged(const ColorModel &,
1634   // bool)),
1635   //	this, SLOT(onWheelChanged(const ColorModel &, bool)));
1636   connect(m_hexagonalColorWheel, SIGNAL(colorChanged(const ColorModel &, bool)),
1637           this, SLOT(onWheelChanged(const ColorModel &, bool)));
1638   // m_verticalSlider->setMaximumSize(20,150);
1639   // connect(m_verticalSlider, SIGNAL(valueChanged(int)), this,
1640   // SLOT(onWheelSliderChanged(int)));
1641   // connect(m_verticalSlider, SIGNAL(valueChanged()), this,
1642   // SLOT(onWheelSliderReleased()));
1643   // connect( m_verticalSlider,		SIGNAL(sliderReleased()),	this,
1644   // SLOT(onWheelSliderReleased()));
1645   // connect(channelButtonGroup, SIGNAL(buttonClicked(int)), this,
1646   // SLOT(setWheelChannel(int)));
1647 }
1648 
1649 //-----------------------------------------------------------------------------
1650 
resizeEvent(QResizeEvent *)1651 void PlainColorPage::resizeEvent(QResizeEvent *) {
1652   int w = width();
1653   int h = height();
1654 
1655   int parentW = parentWidget()->width();
1656 }
1657 
1658 //-----------------------------------------------------------------------------
1659 
updateControls()1660 void PlainColorPage::updateControls() {
1661   int i;
1662   for (i = 0; i < 7; i++) {
1663     m_channelControls[i]->setColor(m_color);
1664     m_channelControls[i]->update();
1665   }
1666   /*
1667   m_squaredColorWheel->setColor(m_color);
1668   m_squaredColorWheel->update();
1669   */
1670 
1671   m_hexagonalColorWheel->setColor(m_color);
1672   m_hexagonalColorWheel->update();
1673 
1674   /*
1675 bool signalsBlocked = m_verticalSlider->blockSignals(true);
1676   m_verticalSlider->setColor(m_color);
1677 int value = m_color.getValue(m_verticalSlider->getChannel());
1678 m_verticalSlider->setValue(value);
1679   m_verticalSlider->update();
1680 m_verticalSlider->blockSignals(signalsBlocked);
1681 */
1682 }
1683 
1684 //-----------------------------------------------------------------------------
1685 
setColor(const TColorStyle & style,int colorParameterIndex)1686 void PlainColorPage::setColor(const TColorStyle &style,
1687                               int colorParameterIndex) {
1688   TPixel32 newPixel = style.getColorParamValue(colorParameterIndex);
1689   if (m_color.getTPixel() == newPixel) return;
1690   bool oldSignalEnabled = m_signalEnabled;
1691   m_signalEnabled       = false;
1692   m_color.setTPixel(newPixel);
1693   updateControls();
1694   m_signalEnabled = oldSignalEnabled;
1695 }
1696 
1697 //-----------------------------------------------------------------------------
1698 
setIsVertical(bool isVertical)1699 void PlainColorPage::setIsVertical(bool isVertical) {
1700   // if (m_isVertical == isVertical) return;
1701   // not returning even if it already is the same orientation
1702   // to take advantage of the resizing here
1703   // this is useful for the first time the splitter is set
1704   // afterwards, it will be overridden by the saved state
1705   // from settings.
1706   m_isVertical = isVertical;
1707   if (isVertical) {
1708     m_vSplitter->setOrientation(Qt::Vertical);
1709     QList<int> sectionSizes;
1710     // maximize color wheel space
1711     sectionSizes << height() - 1 << 1;
1712     m_vSplitter->setSizes(sectionSizes);
1713   } else {
1714     m_vSplitter->setOrientation(Qt::Horizontal);
1715     QList<int> sectionSizes;
1716     sectionSizes << width() / 2 << width() / 2;
1717     m_vSplitter->setSizes(sectionSizes);
1718   }
1719 }
1720 
1721 //-----------------------------------------------------------------------------
1722 
toggleOrientation()1723 void PlainColorPage::toggleOrientation() { setIsVertical(!m_isVertical); }
1724 
1725 //-----------------------------------------------------------------------------
1726 
getSplitterState()1727 QByteArray PlainColorPage::getSplitterState() {
1728   return m_vSplitter->saveState();
1729 }
1730 
1731 //-----------------------------------------------------------------------------
1732 
setSplitterState(QByteArray state)1733 void PlainColorPage::setSplitterState(QByteArray state) {
1734   m_vSplitter->restoreState(state);
1735 }
1736 
1737 //-----------------------------------------------------------------------------
1738 
updateColorCalibration()1739 void PlainColorPage::updateColorCalibration() {
1740   if (m_hexagonalColorWheel->isVisible())
1741     m_hexagonalColorWheel->updateColorCalibration();
1742   else
1743     m_hexagonalColorWheel->cueCalibrationUpdate();
1744 }
1745 
1746 //-----------------------------------------------------------------------------
1747 /*
1748 void PlainColorPage::setWheelChannel(int channel)
1749 {
1750         assert(0<=channel && channel<7);
1751         m_squaredColorWheel->setChannel(channel);
1752   bool signalsBlocked = m_verticalSlider->signalsBlocked();
1753         m_verticalSlider->blockSignals(true);
1754         m_verticalSlider->setChannel((ColorChannel)channel);
1755   m_verticalSlider->setRange(0,ChannelMaxValues[channel]);
1756   m_verticalSlider->setValue(m_color.getValue((ColorChannel)channel));
1757   m_verticalSlider->update();
1758   m_verticalSlider->blockSignals(signalsBlocked);
1759 }
1760 */
1761 //-----------------------------------------------------------------------------
1762 
onControlChanged(const ColorModel & color,bool isDragging)1763 void PlainColorPage::onControlChanged(const ColorModel &color,
1764                                       bool isDragging) {
1765   if (!(m_color == color)) {
1766     m_color = color;
1767     updateControls();
1768   }
1769 
1770   if (m_signalEnabled) emit colorChanged(m_color, isDragging);
1771 }
1772 
1773 //-----------------------------------------------------------------------------
1774 
onWheelChanged(const ColorModel & color,bool isDragging)1775 void PlainColorPage::onWheelChanged(const ColorModel &color, bool isDragging) {
1776   if (!(m_color == color)) {
1777     m_color = color;
1778     updateControls();
1779   }
1780   if (m_signalEnabled) emit colorChanged(m_color, isDragging);
1781 }
1782 
1783 //-----------------------------------------------------------------------------
1784 /*
1785 void PlainColorPage::onWheelSliderChanged(int value)
1786 {
1787         if(m_color.getValue(m_verticalSlider->getChannel()) == value) return;
1788         m_color.setValue(m_verticalSlider->getChannel(), value);
1789   updateControls();
1790   if(m_signalEnabled)
1791     emit colorChanged(m_color, true);
1792 }
1793 */
1794 //-----------------------------------------------------------------------------
1795 /*
1796 void PlainColorPage::onWheelSliderReleased()
1797 {
1798   emit colorChanged(m_color, false);
1799 }
1800 */
1801 
1802 //*****************************************************************************
1803 //    StyleChooserPage  implementation
1804 //*****************************************************************************
1805 
1806 TFilePath StyleChooserPage::m_rootPath;
1807 
1808 //-----------------------------------------------------------------------------
1809 
StyleChooserPage(QWidget * parent)1810 StyleChooserPage::StyleChooserPage(QWidget *parent)
1811     : StyleEditorPage(parent)
1812     , m_chipOrigin(5, 3)
1813     , m_chipSize(25, 25)
1814     , m_chipPerRow(0)
1815     , m_currentIndex(-1) {}
1816 
1817 //-----------------------------------------------------------------------------
1818 
paintEvent(QPaintEvent *)1819 void StyleChooserPage::paintEvent(QPaintEvent *) {
1820   if (loadIfNeeded()) computeSize();
1821 
1822   QPainter p(this);
1823   // p.setRenderHint(QPainter::SmoothPixmapTransform);
1824   if (m_chipPerRow == 0 || getChipCount() == 0) return;
1825 
1826   int w      = parentWidget()->width();
1827   int chipLx = m_chipSize.width(), chipLy = m_chipSize.height();
1828   int nX = m_chipPerRow;
1829   int nY = (getChipCount() + m_chipPerRow - 1) / m_chipPerRow;
1830   int x0 = m_chipOrigin.x();
1831   int y0 = m_chipOrigin.y();
1832   int i, j;
1833   QRect currentIndexRect = QRect();
1834   int count              = 0;
1835   for (i = 0; i < nY; i++)
1836     for (j = 0; j < nX; j++) {
1837       QRect rect(x0 + chipLx * j + 2, y0 + chipLy * i + 2, chipLx, chipLy);
1838 
1839       drawChip(p, rect, count);
1840       p.setPen(Qt::black);
1841       p.drawRect(rect);
1842 
1843       if (m_currentIndex == count) currentIndexRect = rect;
1844 
1845       count++;
1846       if (count >= getChipCount()) break;
1847     }
1848 
1849   if (!currentIndexRect.isEmpty()) {
1850     // Draw the curentIndex border
1851     p.setPen(Qt::white);
1852     p.drawRect(currentIndexRect);
1853     p.setPen(QColor(199, 202, 50));
1854     p.drawRect(currentIndexRect.adjusted(1, 1, -1, -1));
1855     p.setPen(Qt::white);
1856     p.drawRect(currentIndexRect.adjusted(2, 2, -2, -2));
1857     p.setPen(Qt::black);
1858     p.drawRect(currentIndexRect.adjusted(3, 3, -3, -3));
1859   }
1860 }
1861 
1862 //-----------------------------------------------------------------------------
1863 
computeSize()1864 void StyleChooserPage::computeSize() {
1865   int w        = width();
1866   m_chipPerRow = (w - 15) / m_chipSize.width();
1867   int rowCount = 0;
1868   if (m_chipPerRow != 0)
1869     rowCount = (getChipCount() + m_chipPerRow - 1) / m_chipPerRow;
1870   setMinimumSize(3 * m_chipSize.width(), rowCount * m_chipSize.height() + 10);
1871   update();
1872 }
1873 
1874 //-----------------------------------------------------------------------------
1875 
posToIndex(const QPoint & pos) const1876 int StyleChooserPage::posToIndex(const QPoint &pos) const {
1877   if (m_chipPerRow == 0) return -1;
1878 
1879   int x = (pos.x() - m_chipOrigin.x() - 2) / m_chipSize.width();
1880   if (x >= m_chipPerRow) return -1;
1881 
1882   int y = (pos.y() - m_chipOrigin.y() - 2) / m_chipSize.height();
1883 
1884   int index = x + m_chipPerRow * y;
1885   if (index < 0 || index >= getChipCount()) return -1;
1886 
1887   return index;
1888 }
1889 
1890 //-----------------------------------------------------------------------------
1891 
mousePressEvent(QMouseEvent * event)1892 void StyleChooserPage::mousePressEvent(QMouseEvent *event) {
1893   QPoint pos       = event->pos();
1894   int currentIndex = posToIndex(pos);
1895   if (currentIndex < 0) return;
1896   m_currentIndex = currentIndex;
1897   onSelect(currentIndex);
1898 
1899   update();
1900 }
1901 
1902 //-----------------------------------------------------------------------------
1903 
mouseReleaseEvent(QMouseEvent * event)1904 void StyleChooserPage::mouseReleaseEvent(QMouseEvent *event) {}
1905 
1906 //-----------------------------------------------------------------------------
1907 // TOGLIERE
setRootPath(const TFilePath & rootPath)1908 void StyleChooserPage::setRootPath(const TFilePath &rootPath) {
1909   m_rootPath = rootPath;
1910 }
1911 
1912 //*****************************************************************************
1913 //    CustomStyleChooser  definition
1914 //*****************************************************************************
1915 
1916 class CustomStyleChooserPage final : public StyleChooserPage {
1917 public:
CustomStyleChooserPage(QWidget * parent=0)1918   CustomStyleChooserPage(QWidget *parent = 0) : StyleChooserPage(parent) {}
1919 
1920   static CustomStyleManager *styleManager();
1921 
1922   bool event(QEvent *e) override;
1923 
showEvent(QShowEvent *)1924   void showEvent(QShowEvent *) override {
1925     connect(styleManager(), SIGNAL(patternAdded()), this, SLOT(computeSize()));
1926     styleManager()->loadItems();
1927   }
hideEvent(QHideEvent *)1928   void hideEvent(QHideEvent *) override {
1929     disconnect(styleManager(), SIGNAL(patternAdded()), this,
1930                SLOT(computeSize()));
1931   }
loadIfNeeded()1932   bool loadIfNeeded() override { return false; }  // serve?
1933   /*
1934 if(!m_loaded) {loadItems(); m_loaded=true;return true;}
1935 else return false;
1936 }
1937   */
1938 
getChipCount() const1939   int getChipCount() const override {
1940     return styleManager()->getPatternCount();
1941   }
1942 
drawChip(QPainter & p,QRect rect,int index)1943   void drawChip(QPainter &p, QRect rect, int index) override {
1944     assert(0 <= index && index < getChipCount());
1945     CustomStyleManager::PatternData pattern = styleManager()->getPattern(index);
1946     if (pattern.m_image && !pattern.m_image->isNull())
1947       p.drawImage(rect, *pattern.m_image);
1948   }
1949   void onSelect(int index) override;
1950 };
1951 
1952 //-----------------------------------------------------------------------------
1953 
styleManager()1954 CustomStyleManager *CustomStyleChooserPage::styleManager() {
1955   static const QString filters(
1956       "*.pli *.tif *.png *.tga *.tiff *.sgi *.rgb *.pct *.pic");
1957   static CustomStyleManager theManager(TFilePath("custom styles"), filters);
1958   return &theManager;
1959 }
1960 
1961 //-----------------------------------------------------------------------------
1962 
event(QEvent * e)1963 bool CustomStyleChooserPage::event(QEvent *e) {
1964   // Intercept tooltip events
1965   if (e->type() != QEvent::ToolTip) return StyleChooserPage::event(e);
1966 
1967   // see StyleChooserPage::paintEvent
1968   CustomStyleManager *manager = styleManager();
1969   QHelpEvent *he              = static_cast<QHelpEvent *>(e);
1970 
1971   int chipIdx = posToIndex(he->pos()), chipCount = manager->getPatternCount();
1972   if (chipIdx < 0 || chipIdx >= chipCount) return false;
1973 
1974   CustomStyleManager::PatternData pattern = manager->getPattern(chipIdx);
1975   QToolTip::showText(he->globalPos(),
1976                      QString::fromStdString(pattern.m_patternName));
1977 
1978   return true;
1979 }
1980 
1981 //-----------------------------------------------------------------------------
1982 
onSelect(int index)1983 void CustomStyleChooserPage::onSelect(int index) {
1984   if (index < 0 || index >= getChipCount()) return;
1985 
1986   CustomStyleManager::PatternData pattern = styleManager()->getPattern(index);
1987 
1988   if (m_currentIndex < 0) return;
1989 
1990   std::string name = pattern.m_patternName;
1991   if (pattern.m_isVector) {
1992     TVectorImagePatternStrokeStyle cs(name);
1993     emit styleSelected(cs);
1994   } else {
1995     TRasterImagePatternStrokeStyle cs(name);
1996     emit styleSelected(cs);
1997   }
1998 }
1999 
2000 //*****************************************************************************
2001 //    VectorBrushStyleChooser  definition
2002 //*****************************************************************************
2003 
2004 class VectorBrushStyleChooserPage final : public StyleChooserPage {
2005 public:
VectorBrushStyleChooserPage(QWidget * parent=0)2006   VectorBrushStyleChooserPage(QWidget *parent = 0) : StyleChooserPage(parent) {
2007     m_chipSize = QSize(60, 25);
2008   }
2009 
2010   static CustomStyleManager *styleManager();
2011 
2012   bool event(QEvent *e) override;
2013 
showEvent(QShowEvent *)2014   void showEvent(QShowEvent *) override {
2015     connect(styleManager(), SIGNAL(patternAdded()), this, SLOT(computeSize()));
2016     styleManager()->loadItems();
2017   }
hideEvent(QHideEvent *)2018   void hideEvent(QHideEvent *) override {
2019     disconnect(styleManager(), SIGNAL(patternAdded()), this,
2020                SLOT(computeSize()));
2021   }
loadIfNeeded()2022   bool loadIfNeeded() override { return false; }
2023 
getChipCount() const2024   int getChipCount() const override {
2025     return styleManager()->getPatternCount() + 1;
2026   }
2027 
2028   void drawChip(QPainter &p, QRect rect, int index) override;
2029   void onSelect(int index) override;
2030 };
2031 
2032 //-----------------------------------------------------------------------------
2033 
styleManager()2034 CustomStyleManager *VectorBrushStyleChooserPage::styleManager() {
2035   static CustomStyleManager theManager(TFilePath("vector brushes"), "*.pli",
2036                                        QSize(60, 25));
2037   return &theManager;
2038 }
2039 
2040 //-----------------------------------------------------------------------------
2041 
event(QEvent * e)2042 bool VectorBrushStyleChooserPage::event(QEvent *e) {
2043   // Intercept tooltip events
2044   if (e->type() != QEvent::ToolTip) return StyleChooserPage::event(e);
2045 
2046   // see StyleChooserPage::paintEvent
2047   CustomStyleManager *manager = styleManager();
2048   QHelpEvent *he              = static_cast<QHelpEvent *>(e);
2049 
2050   int chipIdx = posToIndex(he->pos()), chipCount = getChipCount();
2051   if (chipIdx < 0 || chipIdx >= chipCount) return false;
2052 
2053   if (chipIdx > 0) {
2054     CustomStyleManager::PatternData pattern = manager->getPattern(chipIdx - 1);
2055     QToolTip::showText(he->globalPos(),
2056                        QString::fromStdString(pattern.m_patternName));
2057   } else
2058     QToolTip::showText(
2059         he->globalPos(),
2060         QObject::tr("Plain color", "VectorBrushStyleChooserPage"));
2061 
2062   return true;
2063 }
2064 
2065 //-----------------------------------------------------------------------------
2066 
drawChip(QPainter & p,QRect rect,int index)2067 void VectorBrushStyleChooserPage::drawChip(QPainter &p, QRect rect, int index) {
2068   if (index == 0) {
2069     static QImage noSpecialStyleImage(":Resources/no_vectorbrush.png");
2070     p.drawImage(rect, noSpecialStyleImage);
2071   } else {
2072     assert(0 <= index && index < getChipCount());
2073     CustomStyleManager::PatternData pattern =
2074         styleManager()->getPattern(index - 1);
2075     p.drawImage(rect, *pattern.m_image);
2076   }
2077 }
2078 
2079 //-----------------------------------------------------------------------------
2080 
onSelect(int index)2081 void VectorBrushStyleChooserPage::onSelect(int index) {
2082   if (index < 0 || index >= getChipCount()) return;
2083 
2084   if (index > 0) {
2085     --index;
2086 
2087     CustomStyleManager::PatternData pattern = styleManager()->getPattern(index);
2088 
2089     if (m_currentIndex < 0) return;
2090 
2091     std::string name = pattern.m_patternName;
2092     assert(pattern.m_isVector);
2093     if (!pattern.m_isVector) return;
2094 
2095     TVectorBrushStyle cs(name);
2096     emit styleSelected(cs);
2097   } else {
2098     TSolidColorStyle cs(TPixel32::Black);
2099     emit styleSelected(cs);
2100   }
2101 }
2102 
2103 //*****************************************************************************
2104 //    TextureStyleChooser  definition
2105 //*****************************************************************************
2106 
2107 struct Texture {
2108   TRasterP m_raster;
2109   QString m_name;
2110 };
2111 
2112 //-----------------------------------------------------------------------------
2113 
2114 class TextureStyleChooserPage final : public StyleChooserPage {
2115   static std::vector<Texture> m_textures;
2116   static bool m_loaded;
2117 
2118 public:
TextureStyleChooserPage(QWidget * parent=0)2119   TextureStyleChooserPage(QWidget *parent = 0) : StyleChooserPage(parent) {}
2120 
loadIfNeeded()2121   bool loadIfNeeded() override {
2122     if (!m_loaded) {
2123       loadItems();
2124       m_loaded = true;
2125       return true;
2126     } else
2127       return false;
2128   }
2129 
getChipCount() const2130   int getChipCount() const override { return m_textures.size(); }
2131 
2132   static void loadTexture(const TFilePath &fp);
2133   static void loadItems();
2134 
drawChip(QPainter & p,QRect rect,int index)2135   void drawChip(QPainter &p, QRect rect, int index) override {
2136     assert(0 <= index && index < getChipCount());
2137     p.drawImage(rect, rasterToQImage(m_textures[index].m_raster));
2138   }
2139 
2140   void onSelect(int index) override;
2141 
2142   bool event(QEvent *e) override;
2143 };
2144 
2145 //-----------------------------------------------------------------------------
2146 
2147 std::vector<Texture> TextureStyleChooserPage::m_textures;
2148 bool TextureStyleChooserPage::m_loaded(false);
2149 
2150 //-----------------------------------------------------------------------------
2151 
loadTexture(const TFilePath & fp)2152 void TextureStyleChooserPage::loadTexture(const TFilePath &fp) {
2153   if (fp == TFilePath()) {
2154     TRaster32P ras(25, 25);
2155     TTextureStyle::fillCustomTextureIcon(ras);
2156     // ras->fill(TPixel::Blue);
2157     Texture customText = {ras, QString("")};
2158 
2159     m_textures.push_back(customText);
2160     return;
2161   }
2162 
2163   TRasterP ras;
2164   TImageReader::load(fp, ras);
2165   if (!ras || ras->getLx() < 2 || ras->getLy() < 2) return;
2166 
2167   TRaster32P ras32 = ras;
2168   if (!ras32) return;
2169 
2170   TDimension d(2, 2);
2171   while (d.lx < 256 && d.lx * 2 <= ras32->getLx()) d.lx *= 2;
2172   while (d.ly < 256 && d.ly * 2 <= ras32->getLy()) d.ly *= 2;
2173 
2174   TRaster32P texture;
2175   if (d == ras32->getSize())
2176     texture = ras32;
2177   else {
2178     texture = TRaster32P(d);
2179     TScale sc((double)texture->getLx() / ras32->getLx(),
2180               (double)texture->getLy() / ras32->getLy());
2181     TRop::resample(texture, ras32, sc);
2182   }
2183 
2184   Texture text = {texture, QString::fromStdWString(fp.getLevelNameW())};
2185 
2186   m_textures.push_back(text);
2187 }
2188 
2189 //-----------------------------------------------------------------------------
2190 
loadItems()2191 void TextureStyleChooserPage::loadItems() {
2192   m_textures.clear();
2193   if (getRootPath() == TFilePath()) return;
2194   TFilePath texturePath = getRootPath() + "textures";
2195   TFilePathSet fps;
2196   try {
2197     fps = TSystem::readDirectory(texturePath);
2198   } catch (...) {
2199     return;
2200   }
2201   if (fps.empty()) return;
2202   int count = 0;
2203   for (TFilePathSet::iterator it = fps.begin(); it != fps.end(); it++)
2204     if (TFileType::getInfo(*it) == TFileType::RASTER_IMAGE) {
2205       try {
2206         loadTexture(*it);
2207         ++count;
2208       } catch (...) {
2209       }
2210     }
2211   loadTexture(TFilePath());  // custom texture
2212 }
2213 
2214 //-----------------------------------------------------------------------------
2215 
onSelect(int index)2216 void TextureStyleChooserPage::onSelect(int index) {
2217   assert(0 <= index && index < (int)m_textures.size());
2218 
2219   TTextureStyle style(m_textures[index].m_raster,
2220                       TFilePath(m_textures[index].m_name.toStdWString()));
2221   emit styleSelected(style);
2222 }
2223 
2224 //-----------------------------------------------------------------------------
2225 
event(QEvent * e)2226 bool TextureStyleChooserPage::event(QEvent *e) {
2227   if (e->type() == QEvent::ToolTip) {
2228     QHelpEvent *helpEvent = dynamic_cast<QHelpEvent *>(e);
2229     QString toolTip;
2230     QPoint pos = helpEvent->pos();
2231     int index  = posToIndex(pos);
2232     if (index >= 0 && index < (int)m_textures.size()) {
2233       toolTip = m_textures[index].m_name;
2234       QToolTip::showText(
2235           helpEvent->globalPos(),
2236           toolTip != QString()
2237               ? toolTip
2238               : QObject::tr("Custom Texture", "TextureStyleChooserPage"));
2239     }
2240     e->accept();
2241   }
2242   return StyleChooserPage::event(e);
2243 }
2244 
2245 //*****************************************************************************
2246 //    MyPaintBrushStyleChooserPage definition
2247 //*****************************************************************************
2248 
2249 class MyPaintBrushStyleChooserPage final : public StyleChooserPage {
2250 public:
2251   struct Brush {
2252     TRasterP m_raster;
2253     QString m_name;
2254   };
2255 
2256 private:
2257   static std::vector<TMyPaintBrushStyle> m_brushes;
2258 
2259 public:
MyPaintBrushStyleChooserPage(QWidget * parent=0)2260   MyPaintBrushStyleChooserPage(QWidget *parent = 0) : StyleChooserPage(parent) {
2261     m_chipSize = QSize(64, 64);
2262   }
2263 
loadIfNeeded()2264   bool loadIfNeeded() override {
2265     static bool m_loaded = false;
2266     if (!m_loaded) {
2267       loadItems();
2268       m_loaded = true;
2269       return true;
2270     } else
2271       return false;
2272   }
2273 
getChipCount() const2274   int getChipCount() const override { return m_brushes.size() + 1; }
2275 
2276   static void loadItems();
2277 
drawChip(QPainter & p,QRect rect,int index)2278   void drawChip(QPainter &p, QRect rect, int index) override {
2279     assert(0 <= index && index <= (int)m_brushes.size());
2280     static QImage noStyleImage(":Resources/no_mypaintbrush.png");
2281     p.drawImage(rect, index == 0
2282                           ? noStyleImage
2283                           : rasterToQImage(m_brushes[index - 1].getPreview()));
2284   }
2285 
onSelect(int index)2286   void onSelect(int index) override {
2287     assert(0 <= index && index <= (int)m_brushes.size());
2288     static TSolidColorStyle noStyle(TPixel32::Black);
2289     if (index == 0) {
2290       emit styleSelected(noStyle);
2291     } else {
2292       emit styleSelected(m_brushes[index - 1]);
2293     }
2294   }
2295 
event(QEvent * e)2296   bool event(QEvent *e) override {
2297     static TSolidColorStyle noStyle(TPixel32::Black);
2298     if (e->type() == QEvent::ToolTip) {
2299       QHelpEvent *helpEvent = dynamic_cast<QHelpEvent *>(e);
2300       QString toolTip;
2301       QPoint pos = helpEvent->pos();
2302       int index  = posToIndex(pos);
2303       if (index == 0) {
2304         toolTip = QObject::tr("Plain color", "MyPaintBrushStyleChooserPage");
2305       } else if (index > 0 && index <= (int)m_brushes.size()) {
2306         toolTip = m_brushes[index - 1].getPath().getQString();
2307       }
2308       QToolTip::showText(helpEvent->globalPos(), toolTip);
2309       e->accept();
2310     }
2311     return StyleChooserPage::event(e);
2312   }
2313 };
2314 
2315 //-----------------------------------------------------------------------------
2316 
2317 std::vector<TMyPaintBrushStyle> MyPaintBrushStyleChooserPage::m_brushes;
2318 
2319 //-----------------------------------------------------------------------------
2320 
loadItems()2321 void MyPaintBrushStyleChooserPage::loadItems() {
2322   m_brushes.clear();
2323   std::set<TFilePath> brushFiles;
2324 
2325   TFilePathSet dirs = TMyPaintBrushStyle::getBrushesDirs();
2326   for (TFilePathSet::iterator i = dirs.begin(); i != dirs.end(); ++i) {
2327     TFileStatus fs(*i);
2328     if (fs.doesExist() && fs.isDirectory()) {
2329       TFilePathSet files = TSystem::readDirectoryTree(*i, false, true);
2330       for (TFilePathSet::iterator j = files.begin(); j != files.end(); ++j)
2331         if (j->getType() == TMyPaintBrushStyle::getBrushType())
2332           brushFiles.insert(*j - *i);
2333     }
2334   }
2335 
2336   // reserve memory to avoid reallocation
2337   m_brushes.reserve(brushFiles.size());
2338   for (std::set<TFilePath>::iterator i = brushFiles.begin();
2339        i != brushFiles.end(); ++i)
2340     m_brushes.push_back(TMyPaintBrushStyle(*i));
2341 }
2342 
2343 //*****************************************************************************
2344 //    SpecialStyleChooser  definition
2345 //*****************************************************************************
2346 
2347 class SpecialStyleChooserPage final : public StyleChooserPage {
2348   static std::vector<std::pair<int, QImage *>> m_customStyles;
2349   static bool m_loaded;
2350 
2351 public:
SpecialStyleChooserPage(QWidget * parent=0,const TFilePath & rootDir=TFilePath ())2352   SpecialStyleChooserPage(QWidget *parent          = 0,
2353                           const TFilePath &rootDir = TFilePath())
2354       : StyleChooserPage(parent) {}
2355 
loadIfNeeded()2356   bool loadIfNeeded() override {
2357     if (!m_loaded) {
2358       loadItems();
2359       m_loaded = true;
2360       return true;
2361     } else
2362       return false;
2363   }
getChipCount() const2364   int getChipCount() const override { return m_customStyles.size(); }
2365 
2366   void loadItems();
2367 
2368   void drawChip(QPainter &p, QRect rect, int index) override;
2369   void onSelect(int index) override;
2370   bool event(QEvent *e) override;
2371 };
2372 
2373 //-----------------------------------------------------------------------------
2374 
2375 std::vector<std::pair<int, QImage *>> SpecialStyleChooserPage::m_customStyles;
2376 bool SpecialStyleChooserPage::m_loaded(false);
2377 
2378 //-----------------------------------------------------------------------------
2379 
loadItems()2380 void SpecialStyleChooserPage::loadItems() {
2381   std::vector<int> tags;
2382   TColorStyle::getAllTags(tags);
2383 
2384   int chipCount = 0;
2385 
2386   for (int j = 0; j < (int)tags.size(); j++) {
2387     int tagId = tags[j];
2388     if (tagId == 3 ||     // solid color
2389         tagId == 4 ||     // texture
2390         tagId == 100 ||   // obsolete imagepattern id
2391         tagId == 2000 ||  // imagepattern
2392         tagId == 2800 ||  // imagepattern
2393         tagId == 2001 ||  // cleanup
2394         tagId == 2002 ||  // ??
2395         tagId == 3000 ||  // vector brush
2396         tagId == 4001     // mypaint brush
2397     )
2398       continue;
2399 
2400     TColorStyle *style = TColorStyle::create(tagId);
2401     if (style->isRasterStyle()) {
2402       delete style;
2403       continue;
2404     }
2405     TDimension chipSize(getChipSize().width(), getChipSize().height());
2406     QImage *image = new QImage(rasterToQImage(style->getIcon(chipSize), false));
2407     m_customStyles.push_back(std::make_pair(tagId, image));
2408     delete style;
2409   }
2410 }
2411 
2412 //-----------------------------------------------------------------------------
2413 
drawChip(QPainter & p,QRect rect,int index)2414 void SpecialStyleChooserPage::drawChip(QPainter &p, QRect rect, int index) {
2415   if (index == 0) {
2416     static QImage noSpecialStyleImage(":Resources/no_specialstyle.png");
2417     p.drawImage(rect, noSpecialStyleImage);
2418   } else {
2419     int j = index - 1;
2420     if (0 <= j && j < (int)m_customStyles.size())
2421       p.drawImage(rect, *m_customStyles[j].second);
2422     else
2423       p.fillRect(rect, QBrush(QColor(255, 0, 0)));
2424   }
2425 }
2426 
2427 //-----------------------------------------------------------------------------
2428 
onSelect(int index)2429 void SpecialStyleChooserPage::onSelect(int index) {
2430   assert(0 <= index && index < (int)m_customStyles.size());
2431   TColorStyle *cs = 0;
2432   if (m_currentIndex < 0) return;
2433   if (index == 0)
2434     cs = new TSolidColorStyle(TPixel32::Black);
2435   else {
2436     int j = index - 1;
2437     assert(0 <= j && j < (int)m_customStyles.size());
2438     int tagId = m_customStyles[j].first;
2439     cs        = TColorStyle::create(tagId);
2440   }
2441   emit styleSelected(*cs);
2442 }
2443 
2444 //-----------------------------------------------------------------------------
2445 
event(QEvent * e)2446 bool SpecialStyleChooserPage::event(QEvent *e) {
2447   if (e->type() == QEvent::ToolTip) {
2448     QHelpEvent *helpEvent = dynamic_cast<QHelpEvent *>(e);
2449     QString toolTip;
2450     QPoint pos = helpEvent->pos();
2451     int index  = posToIndex(pos);
2452     if (index == 0)
2453       toolTip = QObject::tr("Plain color", "SpecialStyleChooserPage");
2454     else {
2455       int j = index - 1;
2456       if (0 <= j && j < (int)m_customStyles.size()) {
2457         int tagId       = m_customStyles[j].first;
2458         TColorStyle *cs = TColorStyle::create(tagId);
2459         if (cs) {
2460           toolTip = cs->getDescription();
2461           delete cs;
2462         }
2463       }
2464     }
2465     if (toolTip != "")
2466       QToolTip::showText(helpEvent->globalPos(), toolTip);
2467     else
2468       QToolTip::hideText();
2469     e->accept();
2470   }
2471   return StyleChooserPage::event(e);
2472 }
2473 
2474 //=============================================================================
2475 // SettingBox
2476 //-----------------------------------------------------------------------------
2477 /*
2478 SettingBox::SettingBox(QWidget *parent, int index)
2479 : QWidget(parent)
2480 , m_index(index)
2481 , m_style(0)
2482 {
2483         QHBoxLayout* hLayout = new QHBoxLayout(this);
2484         hLayout->setSpacing(5);
2485         hLayout->setMargin(0);
2486         hLayout->addSpacing(10);
2487         m_name = new QLabel(this);
2488         m_name->setFixedSize(82,20);
2489         m_name->setStyleSheet("border: 0px;");
2490         hLayout->addWidget(m_name,0);
2491         m_doubleField = new DoubleField(this, true);
2492         hLayout->addWidget(m_doubleField,1);
2493         hLayout->addSpacing(10);
2494         bool ret = connect(m_doubleField, SIGNAL(valueChanged(bool)), this,
2495 SLOT(onValueChanged(bool)));
2496   assert(ret);
2497         setLayout(hLayout);
2498         setFixedHeight(22);
2499 }
2500 
2501 //-----------------------------------------------------------------------------
2502 
2503 void SettingBox::setParameters(TColorStyle* cs)
2504 {
2505         if(!cs)
2506         {
2507                 m_style = cs;
2508                 return;
2509         }
2510         if(cs->getParamCount() == 0 || m_index<0 ||
2511 cs->getParamCount()<=m_index)
2512                 return;
2513         QString paramName = cs->getParamNames(m_index);
2514         m_name->setText(paramName);
2515    double newValue = cs->getParamValue(TColorStyle::double_tag(), m_index);
2516         double value = m_doubleField->getValue();
2517         m_style = cs;
2518         if(value != newValue)
2519         {
2520                 double min=0, max=1;
2521                 cs->getParamRange(m_index,min,max);
2522                 m_doubleField->setValues(newValue, min, max);
2523         }
2524         TCleanupStyle* cleanupStyle = dynamic_cast<TCleanupStyle*>(cs);
2525         if(paramName == "Contrast" && cleanupStyle)
2526         {
2527                 if(!cleanupStyle->isContrastEnabled())
2528                         m_doubleField->setEnabled(false);
2529                 else
2530                         m_doubleField->setEnabled(true);
2531         }
2532         update();
2533 }
2534 
2535 //-----------------------------------------------------------------------------
2536 
2537 void SettingBox::setColorStyleParam(double value, bool isDragging)
2538 {
2539   TColorStyle* style = m_style;
2540   assert(style && m_index < style->getParamCount());
2541 
2542   double min = 0.0, max = 1.0;
2543   style->getParamRange(m_index, min, max);
2544 
2545   style->setParamValue(m_index, tcrop(value, min, max));
2546 
2547   emit valueChanged(*style, isDragging);
2548 }
2549 
2550 //-----------------------------------------------------------------------------
2551 
2552 void SettingBox::onValueChanged(bool isDragging)
2553 {
2554         if(!m_style || m_style->getParamCount() == 0)
2555                 return;
2556 
2557         double value = m_doubleField->getValue();
2558         if(isDragging && m_style->getParamValue(TColorStyle::double_tag(),
2559 m_index) == value)
2560                 return;
2561 
2562         setColorStyleParam(value, isDragging);
2563 }
2564 */
2565 
2566 //*****************************************************************************
2567 //    SettingsPage  implementation
2568 //*****************************************************************************
2569 
SettingsPage(QWidget * parent)2570 SettingsPage::SettingsPage(QWidget *parent)
2571     : QScrollArea(parent), m_updating(false) {
2572   bool ret = true;
2573 
2574   setObjectName("styleEditorPage");  // It is necessary for the styleSheet
2575   setFrameStyle(QFrame::StyledPanel);
2576 
2577   setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
2578   setWidgetResizable(true);
2579 
2580   // Build the scrolled widget
2581   QFrame *paramsContainer = new QFrame(this);
2582   setWidget(paramsContainer);
2583 
2584   QVBoxLayout *paramsContainerLayout = new QVBoxLayout(this);
2585   paramsContainerLayout->setMargin(10);
2586   paramsContainerLayout->setSpacing(10);
2587   paramsContainer->setLayout(paramsContainerLayout);
2588 
2589   // Add a vertical layout to store the "autofill" checkbox widgets
2590   m_autoFillCheckBox = new QCheckBox(tr("Autopaint for Lines"), this);
2591   paramsContainerLayout->addWidget(m_autoFillCheckBox, 0,
2592                                    Qt::AlignLeft | Qt::AlignVCenter);
2593 
2594   ret = connect(m_autoFillCheckBox, SIGNAL(stateChanged(int)), this,
2595                 SLOT(onAutofillChanged()));
2596   assert(ret);
2597 
2598   // Prepare the style parameters layout
2599   m_paramsLayout = new QGridLayout;
2600   m_paramsLayout->setMargin(0);
2601   m_paramsLayout->setVerticalSpacing(8);
2602   m_paramsLayout->setHorizontalSpacing(5);
2603   paramsContainerLayout->addLayout(m_paramsLayout);
2604 
2605   paramsContainerLayout->addStretch(1);
2606 }
2607 
2608 //-----------------------------------------------------------------------------
2609 
enableAutopaintToggle(bool enabled)2610 void SettingsPage::enableAutopaintToggle(bool enabled) {
2611   m_autoFillCheckBox->setVisible(enabled);
2612 }
2613 
2614 //-----------------------------------------------------------------------------
2615 
setStyle(const TColorStyleP & editedStyle)2616 void SettingsPage::setStyle(const TColorStyleP &editedStyle) {
2617   struct locals {
2618     inline static void clearLayout(QLayout *layout) {
2619       QLayoutItem *item;
2620       while ((item = layout->takeAt(0)) != 0) {
2621         delete item->layout();
2622         delete item->spacerItem();
2623         delete item->widget();
2624         delete item;
2625       }
2626     }
2627   };  // locals
2628 
2629   // NOTE: Layout reubilds must be avoided whenever possible. In particular, be
2630   // warned that this
2631   // function may be invoked when signals emitted from this function are still
2632   // "flying"...
2633 
2634   bool clearLayout =
2635       m_editedStyle &&
2636       !(editedStyle && typeid(*m_editedStyle) == typeid(*editedStyle));
2637   bool buildLayout =
2638       editedStyle &&
2639       !(m_editedStyle && typeid(*m_editedStyle) == typeid(*editedStyle));
2640 
2641   m_editedStyle = editedStyle;
2642 
2643   if (clearLayout) locals::clearLayout(m_paramsLayout);
2644 
2645   if (buildLayout) {
2646     assert(m_paramsLayout->count() == 0);
2647 
2648     // Assign new settings widgets - one label/editor for each parameter
2649     bool ret = true;
2650 
2651     int p, pCount = editedStyle->getParamCount();
2652     for (p = 0; p != pCount; ++p) {
2653       // Assign label
2654       QLabel *label = new QLabel(editedStyle->getParamNames(p));
2655       m_paramsLayout->addWidget(label, p, 0);
2656 
2657       // Assign parameter
2658       switch (editedStyle->getParamType(p)) {
2659       case TColorStyle::BOOL: {
2660         QCheckBox *checkBox = new QCheckBox;
2661         m_paramsLayout->addWidget(checkBox, p, 1);
2662 
2663         ret = QObject::connect(checkBox, SIGNAL(toggled(bool)), this,
2664                                SLOT(onValueChanged())) &&
2665               ret;
2666 
2667         break;
2668       }
2669 
2670       case TColorStyle::INT: {
2671         DVGui::IntField *intField = new DVGui::IntField;
2672         m_paramsLayout->addWidget(intField, p, 1);
2673 
2674         int min, max;
2675         m_editedStyle->getParamRange(p, min, max);
2676 
2677         intField->setRange(min, max);
2678 
2679         ret = QObject::connect(intField, SIGNAL(valueChanged(bool)), this,
2680                                SLOT(onValueChanged(bool))) &&
2681               ret;
2682 
2683         break;
2684       }
2685 
2686       case TColorStyle::ENUM: {
2687         QComboBox *comboBox = new QComboBox;
2688         m_paramsLayout->addWidget(comboBox, p, 1);
2689 
2690         QStringList items;
2691         m_editedStyle->getParamRange(p, items);
2692 
2693         comboBox->addItems(items);
2694 
2695         ret = QObject::connect(comboBox, SIGNAL(currentIndexChanged(int)), this,
2696                                SLOT(onValueChanged())) &&
2697               ret;
2698 
2699         break;
2700       }
2701 
2702       case TColorStyle::DOUBLE: {
2703         DVGui::DoubleField *doubleField = new DVGui::DoubleField;
2704         m_paramsLayout->addWidget(doubleField, p, 1);
2705 
2706         double min, max;
2707         m_editedStyle->getParamRange(p, min, max);
2708 
2709         doubleField->setRange(min, max);
2710 
2711         ret = QObject::connect(doubleField, SIGNAL(valueChanged(bool)), this,
2712                                SLOT(onValueChanged(bool))) &&
2713               ret;
2714 
2715         break;
2716       }
2717 
2718       case TColorStyle::FILEPATH: {
2719         DVGui::FileField *fileField = new DVGui::FileField;
2720         m_paramsLayout->addWidget(fileField, p, 1);
2721 
2722         QStringList extensions;
2723         m_editedStyle->getParamRange(p, extensions);
2724 
2725         fileField->setFileMode(QFileDialog::AnyFile);
2726         fileField->setFilters(extensions);
2727 
2728         fileField->setPath(QString::fromStdWString(
2729             editedStyle->getParamValue(TColorStyle::TFilePath_tag(), p)
2730                 .getWideString()));
2731 
2732         ret = QObject::connect(fileField, SIGNAL(pathChanged()), this,
2733                                SLOT(onValueChanged())) &&
2734               ret;
2735 
2736         break;
2737       }
2738       }
2739 
2740       // "reset to default" button
2741       if (m_editedStyle->hasParamDefault(p)) {
2742         QPushButton *pushButton = new QPushButton;
2743         pushButton->setToolTip(tr("Reset to default"));
2744         pushButton->setIcon(createQIcon("delete"));
2745         pushButton->setFixedSize(24, 24);
2746         m_paramsLayout->addWidget(pushButton, p, 2);
2747         ret = QObject::connect(pushButton, SIGNAL(clicked(bool)), this,
2748                                SLOT(onValueReset())) &&
2749               ret;
2750       }
2751 
2752       assert(ret);
2753     }
2754   }
2755 
2756   updateValues();
2757 }
2758 
2759 //-----------------------------------------------------------------------------
2760 
updateValues()2761 void SettingsPage::updateValues() {
2762   if (!m_editedStyle) return;
2763 
2764   struct Updating {
2765     SettingsPage *m_this;  // Prevent 'param changed' signals from being
2766     ~Updating() {
2767       m_this->m_updating = false;
2768     }  // sent when updating editor widgets - this is
2769   } updating = {(m_updating = true, this)};  // just a view REFRESH function.
2770 
2771   // Deal with the autofill
2772   m_autoFillCheckBox->setChecked(m_editedStyle->getFlags() & 1);
2773 
2774   int p, pCount = m_editedStyle->getParamCount();
2775   for (p = 0; p != pCount; ++p) {
2776     // Update state of "reset to default" button
2777     if (m_editedStyle->hasParamDefault(p)) {
2778       QPushButton *pushButton = static_cast<QPushButton *>(
2779           m_paramsLayout->itemAtPosition(p, 2)->widget());
2780       pushButton->setEnabled(m_editedStyle->isParamDefault(p));
2781     }
2782 
2783     // Update editor values
2784     switch (m_editedStyle->getParamType(p)) {
2785     case TColorStyle::BOOL: {
2786       QCheckBox *checkBox = static_cast<QCheckBox *>(
2787           m_paramsLayout->itemAtPosition(p, 1)->widget());
2788 
2789       checkBox->setChecked(
2790           m_editedStyle->getParamValue(TColorStyle::bool_tag(), p));
2791 
2792       break;
2793     }
2794 
2795     case TColorStyle::INT: {
2796       DVGui::IntField *intField = static_cast<DVGui::IntField *>(
2797           m_paramsLayout->itemAtPosition(p, 1)->widget());
2798 
2799       intField->setValue(
2800           m_editedStyle->getParamValue(TColorStyle::int_tag(), p));
2801 
2802       break;
2803     }
2804 
2805     case TColorStyle::ENUM: {
2806       QComboBox *comboBox = static_cast<QComboBox *>(
2807           m_paramsLayout->itemAtPosition(p, 1)->widget());
2808 
2809       comboBox->setCurrentIndex(
2810           m_editedStyle->getParamValue(TColorStyle::int_tag(), p));
2811 
2812       break;
2813     }
2814 
2815     case TColorStyle::DOUBLE: {
2816       DVGui::DoubleField *doubleField = static_cast<DVGui::DoubleField *>(
2817           m_paramsLayout->itemAtPosition(p, 1)->widget());
2818 
2819       doubleField->setValue(
2820           m_editedStyle->getParamValue(TColorStyle::double_tag(), p));
2821 
2822       break;
2823     }
2824 
2825     case TColorStyle::FILEPATH: {
2826       DVGui::FileField *fileField = static_cast<DVGui::FileField *>(
2827           m_paramsLayout->itemAtPosition(p, 1)->widget());
2828 
2829       fileField->setPath(QString::fromStdWString(
2830           m_editedStyle->getParamValue(TColorStyle::TFilePath_tag(), p)
2831               .getWideString()));
2832 
2833       break;
2834     }
2835     }
2836   }
2837 }
2838 
2839 //-----------------------------------------------------------------------------
2840 
onAutofillChanged()2841 void SettingsPage::onAutofillChanged() {
2842   m_editedStyle->setFlags((unsigned int)(m_autoFillCheckBox->isChecked()));
2843 
2844   if (!m_updating)
2845     emit paramStyleChanged(false);  // Forward the signal to the style editor
2846 }
2847 
2848 //-----------------------------------------------------------------------------
2849 
getParamIndex(const QWidget * widget)2850 int SettingsPage::getParamIndex(const QWidget *widget) {
2851   int p, pCount = m_paramsLayout->rowCount();
2852   for (p = 0; p != pCount; ++p)
2853     for (int c = 0; c < 3; ++c)
2854       if (QLayoutItem *item = m_paramsLayout->itemAtPosition(p, c))
2855         if (item->widget() == widget) return p;
2856   return -1;
2857 }
2858 
2859 //-----------------------------------------------------------------------------
2860 
onValueReset()2861 void SettingsPage::onValueReset() {
2862   assert(m_editedStyle);
2863 
2864   // Extract the parameter index
2865   QWidget *senderWidget = static_cast<QWidget *>(sender());
2866   int p                 = getParamIndex(senderWidget);
2867 
2868   assert(0 <= p && p < m_editedStyle->getParamCount());
2869   m_editedStyle->setParamDefault(p);
2870 
2871   // Forward the signal to the style editor
2872   if (!m_updating) emit paramStyleChanged(false);
2873 }
2874 
2875 //-----------------------------------------------------------------------------
2876 
onValueChanged(bool isDragging)2877 void SettingsPage::onValueChanged(bool isDragging) {
2878   assert(m_editedStyle);
2879 
2880   // Extract the parameter index
2881   QWidget *senderWidget = static_cast<QWidget *>(sender());
2882   int p                 = getParamIndex(senderWidget);
2883 
2884   assert(0 <= p && p < m_editedStyle->getParamCount());
2885 
2886   // Update the style's parameter value
2887   switch (m_editedStyle->getParamType(p)) {
2888   case TColorStyle::BOOL:
2889     m_editedStyle->setParamValue(
2890         p, static_cast<QCheckBox *>(senderWidget)->isChecked());
2891     break;
2892   case TColorStyle::INT:
2893     m_editedStyle->setParamValue(
2894         p, static_cast<DVGui::IntField *>(senderWidget)->getValue());
2895     break;
2896   case TColorStyle::ENUM:
2897     m_editedStyle->setParamValue(
2898         p, static_cast<QComboBox *>(senderWidget)->currentIndex());
2899     break;
2900   case TColorStyle::DOUBLE:
2901     m_editedStyle->setParamValue(
2902         p, static_cast<DVGui::DoubleField *>(senderWidget)->getValue());
2903     break;
2904   case TColorStyle::FILEPATH: {
2905     const QString &string =
2906         static_cast<DVGui::FileField *>(senderWidget)->getPath();
2907     m_editedStyle->setParamValue(p, TFilePath(string.toStdWString()));
2908     break;
2909   }
2910   }
2911 
2912   // Forward the signal to the style editor
2913   if (!m_updating) emit paramStyleChanged(isDragging);
2914 }
2915 
2916 //=============================================================================
2917 
2918 namespace {
2919 
makeChooserPage(QWidget * chooser)2920 QScrollArea *makeChooserPage(QWidget *chooser) {
2921   QScrollArea *scrollArea = new QScrollArea();
2922   scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
2923   scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
2924   scrollArea->setWidgetResizable(true);
2925   scrollArea->setWidget(chooser);
2926   return scrollArea;
2927 }
2928 
2929 //-----------------------------------------------------------------------------
2930 
makeChooserPageWithoutScrollBar(QWidget * chooser)2931 QScrollArea *makeChooserPageWithoutScrollBar(QWidget *chooser) {
2932   QScrollArea *scrollArea = new QScrollArea();
2933   scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
2934   scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
2935   scrollArea->setWidgetResizable(true);
2936   scrollArea->setWidget(chooser);
2937   return scrollArea;
2938 }
2939 
2940 }  // namespace
2941 
2942 //*****************************************************************************
2943 //    StyleEditor  implementation
2944 //*****************************************************************************
2945 
StyleEditor(PaletteController * paletteController,QWidget * parent)2946 StyleEditor::StyleEditor(PaletteController *paletteController, QWidget *parent)
2947     : QWidget(parent)
2948     , m_paletteController(paletteController)
2949     , m_paletteHandle(paletteController->getCurrentPalette())
2950     , m_cleanupPaletteHandle(paletteController->getCurrentCleanupPalette())
2951     , m_toolBar(0)
2952     , m_enabled(false)
2953     , m_enabledOnlyFirstTab(false)
2954     , m_enabledFirstAndLastTab(false)
2955     , m_oldStyle(0)
2956     , m_parent(parent)
2957     , m_editedStyle(0) {
2958   setFocusPolicy(Qt::NoFocus);
2959   // TOGLIERE
2960   TFilePath libraryPath = ToonzFolder::getLibraryFolder();
2961   setRootPath(libraryPath);
2962 
2963   m_styleBar = new DVGui::TabBar(this);
2964   m_styleBar->setDrawBase(false);
2965   m_styleBar->setObjectName("StyleEditorTabBar");
2966 
2967   // This widget is used to set the background color of the tabBar
2968   // using the styleSheet.
2969   // It is also used to take 6px on the left before the tabBar
2970   // and to draw the two lines on the bottom size
2971   m_tabBarContainer        = new TabBarContainter(this);
2972   m_colorParameterSelector = new ColorParameterSelector(this);
2973 
2974   m_plainColorPage          = new PlainColorPage(0);
2975   m_textureStylePage        = new TextureStyleChooserPage(0);
2976   m_specialStylePage        = new SpecialStyleChooserPage(0);
2977   m_customStylePage         = new CustomStyleChooserPage(0);
2978   m_vectorBrushesStylePage  = new VectorBrushStyleChooserPage(0);
2979   m_mypaintBrushesStylePage = new MyPaintBrushStyleChooserPage(0);
2980   m_settingsPage            = new SettingsPage(0);
2981 
2982   QWidget *emptyPage = new StyleEditorPage(0);
2983 
2984   // For the plainColorPage and the settingsPage
2985   // I create a "fake" QScrollArea (without ScrollingBar
2986   // in order to use the styleSheet to stylish its background
2987   QScrollArea *plainArea   = makeChooserPageWithoutScrollBar(m_plainColorPage);
2988   QScrollArea *textureArea = makeChooserPage(m_textureStylePage);
2989   QScrollArea *mypaintBrushesArea = makeChooserPage(m_mypaintBrushesStylePage);
2990   QScrollArea *settingsArea = makeChooserPageWithoutScrollBar(m_settingsPage);
2991   QScrollArea *vectorOutsideArea =
2992       makeChooserPageWithoutScrollBar(createVectorPage());
2993   vectorOutsideArea->setMinimumWidth(50);
2994 
2995   m_styleChooser = new QStackedWidget(this);
2996   m_styleChooser->addWidget(plainArea);
2997   m_styleChooser->addWidget(textureArea);
2998   m_styleChooser->addWidget(vectorOutsideArea);
2999   m_styleChooser->addWidget(mypaintBrushesArea);
3000   m_styleChooser->addWidget(settingsArea);
3001   m_styleChooser->addWidget(makeChooserPageWithoutScrollBar(emptyPage));
3002   m_styleChooser->setFocusPolicy(Qt::NoFocus);
3003 
3004   QFrame *bottomWidget = createBottomWidget();
3005 
3006   m_toolBar = new QToolBar(this);
3007   m_toolBar->setMovable(false);
3008   m_toolBar->setMaximumHeight(22);
3009   m_toolBar->addWidget(m_colorParameterSelector);
3010 
3011   QMenu *menu   = new QMenu();
3012   m_wheelAction = new QAction(tr("Wheel"), this);
3013   m_hsvAction   = new QAction(tr("HSV"), this);
3014   m_alphaAction = new QAction(tr("Alpha"), this);
3015   m_rgbAction   = new QAction(tr("RGB"), this);
3016 
3017   m_wheelAction->setCheckable(true);
3018   m_hsvAction->setCheckable(true);
3019   m_alphaAction->setCheckable(true);
3020   m_rgbAction->setCheckable(true);
3021   m_wheelAction->setChecked(true);
3022   m_hsvAction->setChecked(true);
3023   m_alphaAction->setChecked(true);
3024   m_rgbAction->setChecked(true);
3025   menu->addAction(m_wheelAction);
3026   menu->addAction(m_hsvAction);
3027   menu->addAction(m_alphaAction);
3028   menu->addAction(m_rgbAction);
3029 
3030   QToolButton *toolButton = new QToolButton(this);
3031   toolButton->setIcon(createQIcon("menu"));
3032   toolButton->setFixedSize(22, 22);
3033   toolButton->setMenu(menu);
3034   toolButton->setPopupMode(QToolButton::InstantPopup);
3035   toolButton->setToolTip(tr("Show or hide parts of the Color Page."));
3036   QToolBar *displayToolbar = new QToolBar(this);
3037   m_toggleOrientationAction =
3038       displayToolbar->addAction(createQIcon("orientation_h"), "");
3039   m_toggleOrientationAction->setToolTip(
3040       tr("Toggle orientation of the Color Page."));
3041   QWidget *toggleOrientationButton =
3042       displayToolbar->widgetForAction(m_toggleOrientationAction);
3043   toggleOrientationButton->setFixedSize(22, 22);
3044   toggleOrientationButton->setFocusPolicy(Qt::NoFocus);
3045   displayToolbar->addWidget(toolButton);
3046   displayToolbar->setMaximumHeight(22);
3047   displayToolbar->setIconSize(QSize(16, 16));
3048 
3049   /* ------- layout ------- */
3050   QGridLayout *mainLayout = new QGridLayout;
3051   mainLayout->setMargin(0);
3052   mainLayout->setSpacing(0);
3053   {
3054     QHBoxLayout *hLayout = new QHBoxLayout;
3055     hLayout->setMargin(0);
3056     {
3057       hLayout->addSpacing(0);
3058       hLayout->addWidget(m_styleBar);
3059       hLayout->addStretch();
3060     }
3061     m_tabBarContainer->setLayout(hLayout);
3062 
3063     mainLayout->addWidget(m_tabBarContainer, 0, 0, 1, 2);
3064     mainLayout->addWidget(m_styleChooser, 1, 0, 1, 2);
3065     mainLayout->addWidget(bottomWidget, 2, 0, 1, 2);
3066     mainLayout->addWidget(m_toolBar, 3, 0);
3067     mainLayout->addWidget(displayToolbar, 3, 1);
3068   }
3069   mainLayout->setColumnStretch(0, 1);
3070   mainLayout->setRowStretch(1, 1);
3071   setLayout(mainLayout);
3072 
3073   /* ------- signal-slot connections ------- */
3074 
3075   bool ret = true;
3076   ret      = ret && connect(m_styleBar, SIGNAL(currentChanged(int)), this,
3077                        SLOT(setPage(int)));
3078   ret = ret && connect(m_colorParameterSelector, SIGNAL(colorParamChanged()),
3079                        this, SLOT(onColorParamChanged()));
3080   ret = ret &&
3081         connect(m_textureStylePage, SIGNAL(styleSelected(const TColorStyle &)),
3082                 this, SLOT(selectStyle(const TColorStyle &)));
3083   ret = ret &&
3084         connect(m_specialStylePage, SIGNAL(styleSelected(const TColorStyle &)),
3085                 this, SLOT(selectStyle(const TColorStyle &)));
3086   ret = ret &&
3087         connect(m_customStylePage, SIGNAL(styleSelected(const TColorStyle &)),
3088                 this, SLOT(selectStyle(const TColorStyle &)));
3089   ret = ret && connect(m_vectorBrushesStylePage,
3090                        SIGNAL(styleSelected(const TColorStyle &)), this,
3091                        SLOT(selectStyle(const TColorStyle &)));
3092   ret = ret && connect(m_mypaintBrushesStylePage,
3093                        SIGNAL(styleSelected(const TColorStyle &)), this,
3094                        SLOT(selectStyle(const TColorStyle &)));
3095   ret = ret && connect(m_settingsPage, SIGNAL(paramStyleChanged(bool)), this,
3096                        SLOT(onParamStyleChanged(bool)));
3097   ret = ret && connect(m_plainColorPage,
3098                        SIGNAL(colorChanged(const ColorModel &, bool)), this,
3099                        SLOT(onColorChanged(const ColorModel &, bool)));
3100 
3101   ret = ret && connect(m_wheelAction, SIGNAL(toggled(bool)),
3102                        m_plainColorPage->m_wheelFrame, SLOT(setVisible(bool)));
3103   ret = ret && connect(m_hsvAction, SIGNAL(toggled(bool)),
3104                        m_plainColorPage->m_hsvFrame, SLOT(setVisible(bool)));
3105   ret = ret && connect(m_alphaAction, SIGNAL(toggled(bool)),
3106                        m_plainColorPage->m_alphaFrame, SLOT(setVisible(bool)));
3107   ret = ret && connect(m_rgbAction, SIGNAL(toggled(bool)),
3108                        m_plainColorPage->m_rgbFrame, SLOT(setVisible(bool)));
3109   ret = ret && connect(m_toggleOrientationAction, SIGNAL(triggered()),
3110                        m_plainColorPage, SLOT(toggleOrientation()));
3111   ret = ret && connect(m_toggleOrientationAction, SIGNAL(triggered()), this,
3112                        SLOT(updateOrientationButton()));
3113   assert(ret);
3114   /* ------- initial conditions ------- */
3115   enable(false, false, false);
3116   // set to the empty page
3117   m_styleChooser->setCurrentIndex(m_styleChooser->count() - 1);
3118 }
3119 
3120 //-----------------------------------------------------------------------------
3121 
~StyleEditor()3122 StyleEditor::~StyleEditor() {}
3123 
3124 //-----------------------------------------------------------------------------
3125 /*
3126 void StyleEditor::setPaletteHandle(TPaletteHandle* paletteHandle)
3127 {
3128         if(m_paletteHandle != paletteHandle)
3129                 m_paletteHandle = paletteHandle;
3130         onStyleSwitched();
3131 }
3132 */
3133 //-----------------------------------------------------------------------------
3134 
createBottomWidget()3135 QFrame *StyleEditor::createBottomWidget() {
3136   QFrame *bottomWidget = new QFrame(this);
3137   m_autoButton         = new QPushButton(tr("Auto"));
3138   m_oldColor           = new DVGui::StyleSample(this, 42, 20);
3139   m_newColor           = new DVGui::StyleSample(this, 42, 20);
3140   m_applyButton        = new QPushButton(tr("Apply"));
3141 
3142   bottomWidget->setFrameStyle(QFrame::StyledPanel);
3143   bottomWidget->setObjectName("bottomWidget");
3144   bottomWidget->setContentsMargins(0, 0, 0, 0);
3145   m_applyButton->setToolTip(tr("Apply changes to current style"));
3146   m_applyButton->setDisabled(m_paletteController->isColorAutoApplyEnabled());
3147   m_applyButton->setFocusPolicy(Qt::NoFocus);
3148 
3149   m_autoButton->setCheckable(true);
3150   m_autoButton->setToolTip(tr("Automatically update style changes"));
3151   m_autoButton->setChecked(m_paletteController->isColorAutoApplyEnabled());
3152   m_autoButton->setFocusPolicy(Qt::NoFocus);
3153 
3154   m_oldColor->setToolTip(tr("Return To Previous Style"));
3155   m_oldColor->enableClick(true);
3156   m_oldColor->setEnable(false);
3157   m_newColor->setToolTip(tr("Current Style"));
3158   m_newColor->setEnable(false);
3159 
3160   /* ------ layout ------ */
3161   QVBoxLayout *mainLayout = new QVBoxLayout;
3162   mainLayout->setMargin(2);
3163   mainLayout->setSpacing(1);
3164   {
3165     QHBoxLayout *hLayout = new QHBoxLayout;
3166     hLayout->setMargin(0);
3167     hLayout->setSpacing(0);
3168     {
3169       hLayout->addWidget(m_autoButton);
3170       hLayout->addWidget(m_applyButton);
3171       hLayout->addSpacing(2);
3172       hLayout->addWidget(m_newColor, 1);
3173       hLayout->addWidget(m_oldColor, 1);
3174     }
3175     mainLayout->addLayout(hLayout);
3176 
3177     // QHBoxLayout *buttonsLayout = new QHBoxLayout;
3178     // buttonsLayout->setMargin(0);
3179     // buttonsLayout->setSpacing(5);
3180     //{ buttonsLayout->addWidget(m_applyButton); }
3181     // mainLayout->addLayout(buttonsLayout);
3182   }
3183   bottomWidget->setLayout(mainLayout);
3184 
3185   /* ------ signal-slot connections ------ */
3186   bool ret = true;
3187   ret      = ret && connect(m_applyButton, SIGNAL(clicked()), this,
3188                        SLOT(applyButtonClicked()));
3189   ret      = ret && connect(m_autoButton, SIGNAL(toggled(bool)), this,
3190                        SLOT(autoCheckChanged(bool)));
3191   ret = ret && connect(m_oldColor, SIGNAL(clicked(const TColorStyle &)), this,
3192                        SLOT(onOldStyleClicked(const TColorStyle &)));
3193   assert(ret);
3194 
3195   return bottomWidget;
3196 }
3197 
3198 //-----------------------------------------------------------------------------
3199 
createVectorPage()3200 QFrame *StyleEditor::createVectorPage() {
3201   QFrame *vectorOutsideFrame = new QFrame(this);
3202   vectorOutsideFrame->setMinimumWidth(50);
3203 
3204   QPushButton *specialButton     = new QPushButton(tr("Generated"), this);
3205   QPushButton *customButton      = new QPushButton(tr("Trail"), this);
3206   QPushButton *vectorBrushButton = new QPushButton(tr("Vector Brush"), this);
3207 
3208   specialButton->setCheckable(true);
3209   customButton->setCheckable(true);
3210   vectorBrushButton->setCheckable(true);
3211   specialButton->setChecked(true);
3212   customButton->setChecked(true);
3213   vectorBrushButton->setChecked(true);
3214 
3215   /* ------ layout ------ */
3216   QVBoxLayout *vectorOutsideLayout = new QVBoxLayout();
3217   vectorOutsideLayout->setMargin(0);
3218   vectorOutsideLayout->setSpacing(0);
3219   vectorOutsideLayout->setSizeConstraint(QLayout::SetNoConstraint);
3220   {
3221     QHBoxLayout *vectorButtonLayout = new QHBoxLayout();
3222     vectorButtonLayout->setSizeConstraint(QLayout::SetNoConstraint);
3223     {
3224       vectorButtonLayout->addWidget(specialButton);
3225       vectorButtonLayout->addWidget(customButton);
3226       vectorButtonLayout->addWidget(vectorBrushButton);
3227     }
3228     vectorOutsideLayout->addLayout(vectorButtonLayout);
3229 
3230     QVBoxLayout *vectorLayout = new QVBoxLayout();
3231     vectorLayout->setMargin(0);
3232     vectorLayout->setSpacing(0);
3233     vectorLayout->setSizeConstraint(QLayout::SetNoConstraint);
3234     {
3235       vectorLayout->addWidget(m_specialStylePage);
3236       vectorLayout->addWidget(m_customStylePage);
3237       vectorLayout->addWidget(m_vectorBrushesStylePage);
3238     }
3239     QFrame *vectorFrame = new QFrame(this);
3240     vectorFrame->setMinimumWidth(50);
3241     vectorFrame->setLayout(vectorLayout);
3242     m_vectorArea = makeChooserPage(vectorFrame);
3243     m_vectorArea->setMinimumWidth(50);
3244     vectorOutsideLayout->addWidget(m_vectorArea);
3245   }
3246   vectorOutsideFrame->setLayout(vectorOutsideLayout);
3247 
3248   /* ------ signal-slot connections ------ */
3249   bool ret = true;
3250   ret      = ret && connect(specialButton, SIGNAL(toggled(bool)), this,
3251                        SLOT(onSpecialButtonToggled(bool)));
3252   ret      = ret && connect(customButton, SIGNAL(toggled(bool)), this,
3253                        SLOT(onCustomButtonToggled(bool)));
3254   ret      = ret && connect(vectorBrushButton, SIGNAL(toggled(bool)), this,
3255                        SLOT(onVectorBrushButtonToggled(bool)));
3256   assert(ret);
3257   return vectorOutsideFrame;
3258 }
3259 
3260 //-----------------------------------------------------------------------------
3261 
updateTabBar()3262 void StyleEditor::updateTabBar() {
3263   m_styleBar->clearTabBar();
3264   if (m_enabled && !m_enabledOnlyFirstTab && !m_enabledFirstAndLastTab) {
3265     m_styleBar->addSimpleTab(tr("Color"));
3266     m_styleBar->addSimpleTab(tr("Texture"));
3267     m_styleBar->addSimpleTab(tr("Vector"));
3268     m_styleBar->addSimpleTab(tr("Raster"));
3269     m_styleBar->addSimpleTab(tr("Settings"));
3270   } else if (m_enabled && m_enabledOnlyFirstTab && !m_enabledFirstAndLastTab)
3271     m_styleBar->addSimpleTab(tr("Color"));
3272   else if (m_enabled && !m_enabledOnlyFirstTab && m_enabledFirstAndLastTab) {
3273     m_styleBar->addSimpleTab(tr("Color"));
3274     m_styleBar->addSimpleTab(tr("Settings"));
3275   } else {
3276     m_styleChooser->setCurrentIndex(m_styleChooser->count() - 1);
3277     return;
3278   }
3279   m_tabBarContainer->layout()->update();
3280   m_styleChooser->setCurrentIndex(0);
3281 }
3282 
3283 //-----------------------------------------------------------------------------
3284 
showEvent(QShowEvent *)3285 void StyleEditor::showEvent(QShowEvent *) {
3286   m_autoButton->setChecked(m_paletteController->isColorAutoApplyEnabled());
3287   onStyleSwitched();
3288   bool ret = true;
3289   ret      = ret && connect(m_paletteHandle, SIGNAL(colorStyleSwitched()),
3290                        SLOT(onStyleSwitched()));
3291   ret      = ret && connect(m_paletteHandle, SIGNAL(colorStyleChanged(bool)),
3292                        SLOT(onStyleChanged(bool)));
3293   ret      = ret && connect(m_paletteHandle, SIGNAL(paletteSwitched()), this,
3294                        SLOT(onStyleSwitched()));
3295   ret = ret && connect(m_paletteController, SIGNAL(checkPaletteLock()), this,
3296                        SLOT(checkPaletteLock()));
3297   if (m_cleanupPaletteHandle)
3298     ret =
3299         ret && connect(m_cleanupPaletteHandle, SIGNAL(colorStyleChanged(bool)),
3300                        SLOT(onCleanupStyleChanged(bool)));
3301 
3302   ret = ret && connect(m_paletteController, SIGNAL(colorAutoApplyEnabled(bool)),
3303                        this, SLOT(enableColorAutoApply(bool)));
3304   ret = ret && connect(m_paletteController,
3305                        SIGNAL(colorSampleChanged(const TPixel32 &)), this,
3306                        SLOT(setColorSample(const TPixel32 &)));
3307   m_plainColorPage->m_wheelFrame->setVisible(m_wheelAction->isChecked());
3308   m_plainColorPage->m_hsvFrame->setVisible(m_hsvAction->isChecked());
3309   m_plainColorPage->m_alphaFrame->setVisible(m_alphaAction->isChecked());
3310   m_plainColorPage->m_rgbFrame->setVisible(m_rgbAction->isChecked());
3311   updateOrientationButton();
3312   assert(ret);
3313 }
3314 
3315 //-----------------------------------------------------------------------------
3316 
hideEvent(QHideEvent *)3317 void StyleEditor::hideEvent(QHideEvent *) {
3318   disconnect(m_paletteHandle, 0, this, 0);
3319   if (m_cleanupPaletteHandle) disconnect(m_cleanupPaletteHandle, 0, this, 0);
3320   disconnect(m_paletteController, 0, this, 0);
3321 }
3322 
3323 //-----------------------------------------------------------------------------
3324 
updateOrientationButton()3325 void StyleEditor::updateOrientationButton() {
3326   if (m_plainColorPage->getIsVertical()) {
3327     m_toggleOrientationAction->setIcon(createQIcon("orientation_h"));
3328   } else {
3329     m_toggleOrientationAction->setIcon(createQIcon("orientation_v"));
3330   }
3331 }
3332 
3333 //-----------------------------------------------------------------------------
3334 
onStyleSwitched()3335 void StyleEditor::onStyleSwitched() {
3336   TPalette *palette = getPalette();
3337 
3338   if (!palette) {
3339     // set the current page to empty
3340     m_styleChooser->setCurrentIndex(m_styleChooser->count() - 1);
3341     enable(false);
3342     m_colorParameterSelector->clear();
3343     m_oldStyle    = TColorStyleP();
3344     m_editedStyle = TColorStyleP();
3345 
3346     m_parent->setWindowTitle(tr("No Style Selected"));
3347     return;
3348   }
3349 
3350   int styleIndex = getStyleIndex();
3351   setEditedStyleToStyle(palette->getStyle(styleIndex));
3352 
3353   bool isStyleNull    = setStyle(m_editedStyle.getPointer());
3354   bool isColorInField = palette->getPaletteName() == L"EmptyColorFieldPalette";
3355   bool isValidIndex   = styleIndex > 0 || isColorInField;
3356   bool isCleanUpPalette = palette->isCleanupPalette();
3357 
3358   /* ------ update the status text ------ */
3359   if (!isStyleNull && isValidIndex) {
3360     QString statusText;
3361     // palette type
3362     if (isCleanUpPalette)
3363       statusText = tr("Cleanup ");
3364     else if (palette->getGlobalName() != L"")
3365       statusText = tr("Studio ");
3366     else
3367       statusText = tr("Level ");
3368 
3369     // palette name
3370     statusText += tr("Palette") + " : " +
3371                   QString::fromStdWString(palette->getPaletteName());
3372 
3373     // style name
3374     statusText += QString::fromStdWString(L" | #");
3375     statusText += QString::number(styleIndex);
3376     statusText += QString::fromStdWString(L" : " + m_editedStyle->getName());
3377     TPoint pickedPos = m_editedStyle->getPickedPosition().pos;
3378     if (pickedPos != TPoint())
3379       statusText +=
3380           QString(" (Picked from %1,%2)").arg(pickedPos.x).arg(pickedPos.y);
3381 
3382     m_parent->setWindowTitle(statusText);
3383   } else {
3384     m_parent->setWindowTitle(tr("Style Editor - No Valid Style Selected"));
3385   }
3386   enable(!isStyleNull && isValidIndex, isColorInField, isCleanUpPalette);
3387 }
3388 
3389 //-----------------------------------------------------------------------------
3390 
onStyleChanged(bool isDragging)3391 void StyleEditor::onStyleChanged(bool isDragging) {
3392   TPalette *palette = getPalette();
3393   if (!palette) return;
3394 
3395   int styleIndex = getStyleIndex();
3396   assert(0 <= styleIndex && styleIndex < palette->getStyleCount());
3397 
3398   setEditedStyleToStyle(palette->getStyle(styleIndex));
3399   if (!isDragging) {
3400     setOldStyleToStyle(
3401         m_editedStyle
3402             .getPointer());  // This line is needed for proper undo behavior
3403   }
3404   m_plainColorPage->setColor(*m_editedStyle, getColorParam());
3405   m_colorParameterSelector->setStyle(*m_editedStyle);
3406   m_settingsPage->setStyle(m_editedStyle);
3407   m_newColor->setStyle(*m_editedStyle);
3408   m_oldColor->setStyle(
3409       *m_oldStyle);  // This line is needed for proper undo behavior
3410 }
3411 
3412 //-----------------------------------------------------------------------
3413 
onCleanupStyleChanged(bool isDragging)3414 void StyleEditor::onCleanupStyleChanged(bool isDragging) {
3415   if (!m_cleanupPaletteHandle) return;
3416 
3417   onStyleChanged(isDragging);
3418 }
3419 
3420 //-----------------------------------------------------------------------------
3421 // TOGLIERE
setRootPath(const TFilePath & rootPath)3422 void StyleEditor::setRootPath(const TFilePath &rootPath) {
3423   m_textureStylePage->setRootPath(rootPath);
3424 }
3425 
3426 //-----------------------------------------------------------------------------
3427 
copyEditedStyleToPalette(bool isDragging)3428 void StyleEditor::copyEditedStyleToPalette(bool isDragging) {
3429   TPalette *palette = getPalette();
3430   assert(palette);
3431 
3432   int styleIndex = getStyleIndex();
3433   assert(0 <= styleIndex && styleIndex < palette->getStyleCount());
3434 
3435   if (!(*m_oldStyle == *m_editedStyle) &&
3436       (!isDragging || m_paletteController->isColorAutoApplyEnabled()) &&
3437       m_editedStyle->getGlobalName() != L"" &&
3438       m_editedStyle->getOriginalName() != L"") {
3439     // If the adited style is linked to the studio palette, then activate the
3440     // edited flag
3441     m_editedStyle->setIsEditedFlag(true);
3442   }
3443 
3444   palette->setStyle(styleIndex,
3445                     m_editedStyle->clone());  // Must be done *before* setting
3446                                               // the eventual palette keyframe
3447   if (!isDragging) {
3448     if (!(*m_oldStyle == *m_editedStyle)) {
3449       // do not register undo if the edited color is special one (e.g. changing
3450       // the ColorField in the fx settings)
3451       if (palette->getPaletteName() != L"EmptyColorFieldPalette")
3452         TUndoManager::manager()->add(new UndoPaletteChange(
3453             m_paletteHandle, styleIndex, *m_oldStyle, *m_editedStyle));
3454     }
3455 
3456     setOldStyleToStyle(m_editedStyle.getPointer());
3457 
3458     // In case the frame is a keyframe, update it
3459     if (palette->isKeyframe(styleIndex, palette->getFrame()))  // here
3460       palette->setKeyframe(styleIndex, palette->getFrame());   //
3461 
3462     palette->setDirtyFlag(true);
3463   }
3464 
3465   m_paletteHandle->notifyColorStyleChanged(isDragging);
3466 }
3467 
3468 //-----------------------------------------------------------------------------
3469 
onColorChanged(const ColorModel & color,bool isDragging)3470 void StyleEditor::onColorChanged(const ColorModel &color, bool isDragging) {
3471   TPalette *palette = getPalette();
3472   if (!palette) return;
3473 
3474   int styleIndex = getStyleIndex();
3475   if (styleIndex < 0 || styleIndex > palette->getStyleCount()) return;
3476 
3477   setEditedStyleToStyle(palette->getStyle(styleIndex));  // CLONES the argument
3478 
3479   if (m_editedStyle)  // Should be styleIndex's style at this point
3480   {
3481     TPixel tColor = color.getTPixel();
3482 
3483     if (m_editedStyle->hasMainColor()) {
3484       int index = getColorParam(), count = m_editedStyle->getColorParamCount();
3485 
3486       if (0 <= index && index < count)
3487         m_editedStyle->setColorParamValue(index, tColor);
3488       else
3489         m_editedStyle->setMainColor(tColor);
3490 
3491       m_editedStyle->invalidateIcon();
3492     } else {
3493       // The argument has NO (main) COLOR. Since color data is being updated, a
3494       // 'fake'
3495       // solid style will be created and operated on.
3496       TSolidColorStyle *style = new TSolidColorStyle(tColor);
3497       style->assignNames(m_editedStyle.getPointer());
3498 
3499       setEditedStyleToStyle(style);  // CLONES the argument
3500 
3501       delete style;
3502     }
3503 
3504     m_newColor->setStyle(*m_editedStyle);
3505     m_colorParameterSelector->setStyle(*m_editedStyle);
3506     // Auto Button should be disabled with locked palette
3507     if (m_autoButton->isEnabled() && m_autoButton->isChecked()) {
3508       copyEditedStyleToPalette(isDragging);
3509     }
3510   }
3511 }
3512 
3513 //-----------------------------------------------------------------------------
3514 
enable(bool enabled,bool enabledOnlyFirstTab,bool enabledFirstAndLastTab)3515 void StyleEditor::enable(bool enabled, bool enabledOnlyFirstTab,
3516                          bool enabledFirstAndLastTab) {
3517   if (m_enabled != enabled || m_enabledOnlyFirstTab != enabledOnlyFirstTab ||
3518       m_enabledFirstAndLastTab != enabledFirstAndLastTab) {
3519     m_enabled                = enabled;
3520     m_enabledOnlyFirstTab    = enabledOnlyFirstTab;
3521     m_enabledFirstAndLastTab = enabledFirstAndLastTab;
3522     updateTabBar();
3523     m_autoButton->setEnabled(enabled);
3524     m_applyButton->setDisabled(!enabled || m_autoButton->isChecked());
3525     m_oldColor->setEnable(enabled);
3526     m_newColor->setEnable(enabled);
3527     if (enabled == false) {
3528       m_oldColor->setColor(TPixel32::Transparent);
3529       m_newColor->setColor(TPixel32::Transparent);
3530     }
3531   }
3532 
3533   // lock button behavior
3534   TPalette *palette = getPalette();
3535   if (palette && enabled) {
3536     // when the palette is locked
3537     if (palette->isLocked()) {
3538       m_applyButton->setEnabled(false);
3539       m_autoButton->setEnabled(false);
3540     } else  // when the palette is unlocked
3541     {
3542       m_applyButton->setDisabled(m_autoButton->isChecked());
3543       m_autoButton->setEnabled(true);
3544     }
3545   }
3546 }
3547 //-----------------------------------------------------------------------------
3548 
checkPaletteLock()3549 void StyleEditor::checkPaletteLock() {
3550   if (getPalette() && getPalette()->isLocked()) {
3551     m_applyButton->setEnabled(false);
3552     m_autoButton->setEnabled(false);
3553   } else {
3554     m_applyButton->setDisabled(m_autoButton->isChecked());
3555     m_autoButton->setEnabled(true);
3556   }
3557 }
3558 
3559 //-----------------------------------------------------------------------------
3560 
onOldStyleClicked(const TColorStyle &)3561 void StyleEditor::onOldStyleClicked(const TColorStyle &) {
3562   if (!m_enabled) return;
3563   selectStyle(*(m_oldColor->getStyle()));
3564 }
3565 
3566 //-----------------------------------------------------------------------------
3567 
setPage(int index)3568 void StyleEditor::setPage(int index) {
3569   if (!m_enabledFirstAndLastTab) {
3570     m_styleChooser->setCurrentIndex(index);
3571     return;
3572   }
3573 
3574   // Se sono nel caso first and last page enable e index == 1 la pagina che
3575   // voglio settare e' l'ultima!
3576   if (index == 1)
3577     index = m_styleChooser->count() -
3578             2;  // 2 perche' alla fine c'e' una pagina vuota
3579   m_styleChooser->setCurrentIndex(index);
3580 }
3581 
3582 //-----------------------------------------------------------------------------
3583 
applyButtonClicked()3584 void StyleEditor::applyButtonClicked() {
3585   TPalette *palette = getPalette();
3586   int styleIndex    = getStyleIndex();
3587   if (!palette || styleIndex < 0 || styleIndex > palette->getStyleCount())
3588     return;
3589 
3590   copyEditedStyleToPalette(false);
3591 }
3592 
3593 //-----------------------------------------------------------------------------
3594 
autoCheckChanged(bool value)3595 void StyleEditor::autoCheckChanged(bool value) {
3596   m_paletteController->enableColorAutoApply(value);
3597 
3598   if (!m_enabled) return;
3599 
3600   m_applyButton->setDisabled(value);
3601 }
3602 
3603 //-----------------------------------------------------------------------------
3604 
enableColorAutoApply(bool enabled)3605 void StyleEditor::enableColorAutoApply(bool enabled) {
3606   if (m_autoButton->isChecked() != enabled) {
3607     m_autoButton->setChecked(enabled);
3608   }
3609 }
3610 
3611 //-----------------------------------------------------------------------------
3612 
setColorSample(const TPixel32 & color)3613 void StyleEditor::setColorSample(const TPixel32 &color) {
3614   // m_colorParameterSelector->setColor(*style);
3615   ColorModel cm;
3616   cm.setTPixel(color);
3617   onColorChanged(cm, true);
3618 }
3619 
3620 //-----------------------------------------------------------------------------
3621 
setStyle(TColorStyle * currentStyle)3622 bool StyleEditor::setStyle(TColorStyle *currentStyle) {
3623   assert(currentStyle);
3624 
3625   bool isStyleNull = false;
3626 
3627   QString gname = QString::fromStdWString(currentStyle->getGlobalName());
3628   // if(!gname.isEmpty() && gname == "ColorFieldSimpleColor")
3629   //	isStyleNull = true;
3630   // else
3631   if (!gname.isEmpty() && gname[0] != L'-') {
3632     currentStyle = 0;
3633     isStyleNull  = true;
3634   }
3635 
3636   if (currentStyle) {
3637     m_colorParameterSelector->setStyle(*currentStyle);
3638     m_plainColorPage->setColor(*currentStyle, getColorParam());
3639     m_oldColor->setStyle(*currentStyle);
3640     m_newColor->setStyle(*currentStyle);
3641 
3642     setOldStyleToStyle(currentStyle);
3643   }
3644 
3645   // Va fatto anche se non c'e' lo style perche' svuota la pagina
3646   m_settingsPage->setStyle(m_editedStyle);
3647 
3648   return isStyleNull;
3649 }
3650 
3651 //-----------------------------------------------------------------------------
3652 
setEditedStyleToStyle(const TColorStyle * style)3653 void StyleEditor::setEditedStyleToStyle(const TColorStyle *style) {
3654   if (style == m_editedStyle.getPointer()) return;
3655 
3656   m_editedStyle = TColorStyleP(style->clone());
3657 }
3658 
3659 //-----------------------------------------------------------------------------
3660 
setOldStyleToStyle(const TColorStyle * style)3661 void StyleEditor::setOldStyleToStyle(const TColorStyle *style) {
3662   if (style == m_oldStyle.getPointer()) return;
3663   m_oldStyle = TColorStyleP(style->clone());
3664 }
3665 
3666 //-----------------------------------------------------------------------------
3667 
selectStyle(const TColorStyle & newStyle)3668 void StyleEditor::selectStyle(const TColorStyle &newStyle) {
3669   TPalette *palette = m_paletteHandle->getPalette();
3670   if (!palette) return;
3671 
3672   int styleIndex = m_paletteHandle->getStyleIndex();
3673   if (styleIndex < 0 || palette->getStyleCount() <= styleIndex) return;
3674 
3675   // Register the new previous/edited style pairs
3676   setOldStyleToStyle(palette->getStyle(styleIndex));
3677   setEditedStyleToStyle(&newStyle);
3678 
3679   m_editedStyle->assignNames(
3680       m_oldStyle.getPointer());  // Copy original name stored in the palette
3681 
3682   // For convenience's sake, copy the main color from the old color, if both
3683   // have one
3684   if (m_oldStyle && m_oldStyle->hasMainColor() && m_editedStyle &&
3685       m_editedStyle->hasMainColor())
3686     m_editedStyle->setMainColor(m_oldStyle->getMainColor());
3687 
3688   if (m_autoButton->isChecked()) {
3689     // If the adited style is linked to the studio palette, then activate the
3690     // edited flag
3691     if (m_editedStyle->getGlobalName() != L"" &&
3692         m_editedStyle->getOriginalName() != L"")
3693       m_editedStyle->setIsEditedFlag(true);
3694 
3695     // Apply new style, if required
3696     TUndoManager::manager()->add(new UndoPaletteChange(
3697         m_paletteHandle, styleIndex, *m_oldStyle, *m_editedStyle));
3698 
3699     palette->setStyle(styleIndex, m_editedStyle->clone());
3700 
3701     m_paletteHandle->notifyColorStyleChanged(false);
3702     palette->setDirtyFlag(true);
3703   }
3704 
3705   // Update editor widgets
3706   m_newColor->setStyle(*m_editedStyle);
3707   m_plainColorPage->setColor(*m_editedStyle, getColorParam());
3708   m_colorParameterSelector->setStyle(*m_editedStyle);
3709   m_settingsPage->setStyle(m_editedStyle);
3710 }
3711 
3712 //-----------------------------------------------------------------------------
3713 
onColorParamChanged()3714 void StyleEditor::onColorParamChanged() {
3715   TPalette *palette = getPalette();
3716   if (!palette) return;
3717 
3718   int styleIndex = getStyleIndex();
3719   if (styleIndex < 0 || palette->getStyleCount() <= styleIndex) return;
3720 
3721   m_paletteHandle->setStyleParamIndex(getColorParam());
3722 
3723   if (TColorStyle *currentStyle = palette->getStyle(styleIndex)) {
3724     setEditedStyleToStyle(currentStyle);
3725 
3726     m_plainColorPage->setColor(*m_editedStyle, getColorParam());
3727     m_settingsPage->setStyle(m_editedStyle);
3728   }
3729 }
3730 
3731 //-----------------------------------------------------------------------------
3732 
onParamStyleChanged(bool isDragging)3733 void StyleEditor::onParamStyleChanged(bool isDragging) {
3734   TPalette *palette = getPalette();
3735   if (!palette) return;
3736 
3737   int styleIndex = getStyleIndex();
3738   if (styleIndex < 0 || styleIndex > palette->getStyleCount()) return;
3739 
3740   if (m_autoButton->isChecked()) copyEditedStyleToPalette(isDragging);
3741 
3742   m_editedStyle->invalidateIcon();       // Refresh the new color icon
3743   m_newColor->setStyle(*m_editedStyle);  //
3744 }
3745 
3746 //-----------------------------------------------------------------------------
3747 
onSpecialButtonToggled(bool on)3748 void StyleEditor::onSpecialButtonToggled(bool on) {
3749   m_specialStylePage->setVisible(on);
3750   m_vectorArea->widget()->resize(m_vectorArea->widget()->sizeHint());
3751   qApp->processEvents();
3752 }
3753 
3754 //-----------------------------------------------------------------------------
3755 
onCustomButtonToggled(bool on)3756 void StyleEditor::onCustomButtonToggled(bool on) {
3757   m_customStylePage->setVisible(on);
3758   m_vectorArea->widget()->resize(m_vectorArea->widget()->sizeHint());
3759   qApp->processEvents();
3760 }
3761 
3762 //-----------------------------------------------------------------------------
3763 
onVectorBrushButtonToggled(bool on)3764 void StyleEditor::onVectorBrushButtonToggled(bool on) {
3765   m_vectorBrushesStylePage->setVisible(on);
3766   m_vectorArea->widget()->resize(m_vectorArea->widget()->sizeHint());
3767   qApp->processEvents();
3768 }
3769 
3770 //-----------------------------------------------------------------------------
3771 
save(QSettings & settings) const3772 void StyleEditor::save(QSettings &settings) const {
3773   settings.setValue("isVertical", m_plainColorPage->getIsVertical());
3774   int visibleParts = 0;
3775   if (m_wheelAction->isChecked()) visibleParts |= 0x01;
3776   if (m_hsvAction->isChecked()) visibleParts |= 0x02;
3777   if (m_alphaAction->isChecked()) visibleParts |= 0x04;
3778   if (m_rgbAction->isChecked()) visibleParts |= 0x08;
3779   settings.setValue("visibleParts", visibleParts);
3780   settings.setValue("splitterState", m_plainColorPage->getSplitterState());
3781 }
load(QSettings & settings)3782 void StyleEditor::load(QSettings &settings) {
3783   QVariant isVertical = settings.value("isVertical");
3784   if (isVertical.canConvert(QVariant::Bool)) {
3785     m_colorPageIsVertical = isVertical.toBool();
3786     m_plainColorPage->setIsVertical(m_colorPageIsVertical);
3787   }
3788   QVariant visibleParts = settings.value("visibleParts");
3789   if (visibleParts.canConvert(QVariant::Int)) {
3790     int visiblePartsInt = visibleParts.toInt();
3791 
3792     if (visiblePartsInt & 0x01)
3793       m_wheelAction->setChecked(true);
3794     else
3795       m_wheelAction->setChecked(false);
3796     if (visiblePartsInt & 0x02)
3797       m_hsvAction->setChecked(true);
3798     else
3799       m_hsvAction->setChecked(false);
3800     if (visiblePartsInt & 0x04)
3801       m_alphaAction->setChecked(true);
3802     else
3803       m_alphaAction->setChecked(false);
3804     if (visiblePartsInt & 0x08)
3805       m_rgbAction->setChecked(true);
3806     else
3807       m_rgbAction->setChecked(false);
3808   }
3809   QVariant splitterState = settings.value("splitterState");
3810   if (splitterState.canConvert(QVariant::ByteArray))
3811     m_plainColorPage->setSplitterState(splitterState.toByteArray());
3812 }
3813 
3814 //-----------------------------------------------------------------------------
3815 
updateColorCalibration()3816 void StyleEditor::updateColorCalibration() {
3817   m_plainColorPage->updateColorCalibration();
3818 }