1 
2 
3 #include "toonzqt/styleeditor.h"
4 #include "toonzqt/colorfield.h"
5 #include "toonzqt/dvdialog.h"
6 #include "toonzqt/gutil.h"
7 #include "toonzqt/menubarcommand.h"
8 #include "toonz/cleanupcolorstyles.h"
9 #include "tconvert.h"
10 #include "tcolorstyles.h"
11 #include "trop.h"
12 #include "toonzqt/lutcalibrator.h"
13 
14 #include <QLayout>
15 #include <QPainter>
16 #include <QMouseEvent>
17 #include <QLabel>
18 
19 using namespace DVGui;
20 
21 //=============================================================================
22 /*! \class DVGui::StyleSample
23                 \brief The StyleSample class provides to view a square color.
24 
25                 Inherits \b QWidget.
26 
27                 By default square color is set to \b TPixel32(235,235,235,255),
28    you
29                 can set other color using setColor(); you can also define
30    current color
31                 with a style \b TColorStyle, \b getStyle(), using setStyle().
32                 You can pass to constructor square size.
33 
34                 StyleSample permit to manage click event, it's possile to enable
35    this
36                 feature setting enableClick(bool on) to true.
37                 If it is enable when click in square class emit the signal
38                 clicked(const TColorStyle &style).
39 */
40 /*!	\fn void DVGui::StyleSample::clicked(const TColorStyle &style)
41                 This signal is emitted when click event is enable and a style is
42    set.
43 */
44 /*!	\fn void DVGui::StyleSample::enableClick(bool on)
45                 Set click event enable if \b is true, disable otherwise.
46                 If true setStyle store current style and buttonPress emit signal
47                 clicked(const TColorStyle &style).
48 */
StyleSample(QWidget * parent,int sizeX,int sizeY)49 StyleSample::StyleSample(QWidget *parent, int sizeX, int sizeY)
50     : m_samplePixmap(sizeX, sizeY, QImage::Format_ARGB32)
51     , m_bgRas(sizeX, sizeY)
52     , m_style(0)
53     , m_clickEnabled(false)
54     , m_chessColor1(0, 0, 0)
55     , m_chessColor2(255, 255, 255)
56     , m_isEditing(false) {
57   setMinimumSize(sizeX, sizeY);
58   setColor(TPixel32::Transparent);
59   TRop::checkBoard(m_bgRas, m_chessColor1, m_chessColor2,
60                    TDimensionD(sizeX / 8, sizeX / 8), TPointD(0, 0));
61   setEnable(true);
62 }
63 
64 //-----------------------------------------------------------------------------
65 
~StyleSample()66 StyleSample::~StyleSample() {
67   if (m_style) delete m_style;
68   m_style = 0;
69 }
70 
71 //-----------------------------------------------------------------------------
72 /*! Return current StyleSample \b TColorStyle style.
73  */
getStyle() const74 TColorStyle *StyleSample::getStyle() const { return m_style; }
75 
76 //-----------------------------------------------------------------------------
77 /*! Update current square colore and, if click event is enable set current
78                 StyleSample \b TColorStyle style to \b style.
79 */
setStyle(TColorStyle & style)80 void StyleSample::setStyle(TColorStyle &style) {
81   /*-- TSolidColorStyleの場合のみ、単色塗りつぶし --*/
82   if (style.getTagId() == 3)
83     setColor(style.getMainColor());
84   else {
85     TRaster32P icon =
86         style.getIcon(qsize2Dimension(m_samplePixmap.rect().size()));
87     m_samplePixmap = rasterToQImage(icon, false);  // modified in 6.2
88     update();
89   }
90   if (m_clickEnabled) m_style = style.clone();
91 }
92 
93 //-----------------------------------------------------------------------------
94 /*! Update current square colore to \b TPixel32 \b color.
95                 Useful for efficiency if click event is disable.
96 */
setColor(const TPixel32 & pixel)97 void StyleSample::setColor(const TPixel32 &pixel) {
98   QColor color(pixel.r, pixel.g, pixel.b, pixel.m);
99   if (LutManager::instance()->isValid()) LutManager::instance()->convert(color);
100 
101   m_samplePixmap.fill(color.rgba());
102   update();
103 }
104 
105 //-----------------------------------------------------------------------------
106 
setChessboardColors(const TPixel32 & col1,const TPixel32 & col2)107 void StyleSample::setChessboardColors(const TPixel32 &col1,
108                                       const TPixel32 &col2) {
109   m_chessColor1 = col1;
110   m_chessColor2 = col2;
111   TRop::checkBoard(m_bgRas, m_chessColor1, m_chessColor2,
112                    TDimensionD(m_bgRas->getLx() / 8, m_bgRas->getLy() / 8),
113                    TPointD(0, 0));
114   update();
115 }
116 
117 //-----------------------------------------------------------------------------
118 /*! Paint square color.
119  */
paintEvent(QPaintEvent * event)120 void StyleSample::paintEvent(QPaintEvent *event) {
121   if (!isEnable()) return;
122   QPainter painter(this);
123   QImage img(m_bgRas->getRawData(), m_bgRas->getLx(), m_bgRas->getLy(),
124              QImage::Format_ARGB32);
125   painter.drawImage(0, 0, img.scaled(size()));
126   painter.drawImage(0, 0, m_samplePixmap.scaled(size()));
127   if (m_isEditing) {
128     // QRect rect(0,0,m_bgRas->getLx(),m_bgRas->getLy());
129     painter.setPen(Qt::white);
130     painter.drawRect(rect().adjusted(0, 0, -1, -1));
131     painter.drawRect(rect().adjusted(2, 2, -3, -3));
132     painter.setPen(QColor(180, 210, 255));
133     painter.drawRect(rect().adjusted(1, 1, -2, -2));
134   }
135 }
136 
137 //-----------------------------------------------------------------------------
138 /*! If exist current style and event click is enable emit signal
139                 clicked(const TColorStyle &style).
140 */
mousePressEvent(QMouseEvent * event)141 void StyleSample::mousePressEvent(QMouseEvent *event) {
142   if (m_style && m_clickEnabled)
143     emit clicked(*m_style);
144   else
145     event->ignore();
146 }
147 
148 //-----------------------------------------------------------------------------
149 
mouseDoubleClickEvent(QMouseEvent * event)150 void StyleSample::mouseDoubleClickEvent(QMouseEvent *event) { event->ignore(); }
151 
152 //=============================================================================
153 /*! \class DVGui::ChannelField
154                 \brief The ChannelField class is used to view an object to
155    manage a color
156                                          value, red, green, blue or transparency
157    channel.
158 
159                 Inherits \b QWidget.
160 
161                 The object is composed of grid layout \b QGridLayout which
162    contains a label
163                 in first row, first column, to identify channel, a text field \b
164    IntLineEdit
165                 in first row, second column, and a slider in second row, second
166    column.
167                 Texf field and slider are connected, so if you change one the
168    other automatically
169                 change. You can set current value getChannel(), using
170    setChannel().
171                 This two object is used to manage channel value, them range is
172    fixed to [0,255].
173                 This object size is fixed, [50, 2*DVGui::WidgetHeight].
174 
175                 To know when channel parameter value change class provides a
176    signal, valueChanged(int value);
177                 class emit signal when slider value change or when text field is
178    editing,
179                 see SLOT: onSliderChanged(int value) and onEditChanged(const
180    QString &str)
181                 to know when signal is emitted.
182 */
183 /*!	\fn void DVGui::ChannelField::valueChanged(int value)
184                 This signal is emitted when ChannelField, slider or text field,
185    value change;
186                 if slider position change or text field is editing.
187                 \sa onEditChanged(const QString &str) and onSliderChanged(int
188    value).
189 */
ChannelField(QWidget * parent,const QString & string,int value,int maxValue,bool horizontal,int labelWidth,int sliderWidth)190 ChannelField::ChannelField(QWidget *parent, const QString &string, int value,
191                            int maxValue, bool horizontal, int labelWidth,
192                            int sliderWidth)
193     : QWidget(parent), m_maxValue(maxValue) {
194   assert(maxValue > 0);
195   assert(0 <= value && value <= m_maxValue);
196 
197   QLabel *channelName = new QLabel(string, this);
198   m_channelEdit       = new DVGui::IntLineEdit(this, value, 0, maxValue);
199   m_channelSlider     = new QSlider(Qt::Horizontal, this);
200   m_channelSlider->setFocusPolicy(Qt::NoFocus);
201   channelName->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
202   channelName->setFixedWidth(labelWidth);
203 
204   m_channelSlider->setRange(0, maxValue);
205   m_channelSlider->setValue(value);
206   if (sliderWidth > 0) m_channelSlider->setFixedWidth(sliderWidth);
207 
208   //----layout
209   QGridLayout *mainLayout = new QGridLayout(this);
210   mainLayout->setMargin(0);
211   mainLayout->setSpacing(3);
212   {
213     mainLayout->addWidget(channelName, 0, 0);
214     mainLayout->addWidget(m_channelEdit, 0, 1);
215 
216     mainLayout->addWidget(m_channelSlider, horizontal ? 0 : 1,
217                           horizontal ? 2 : 1);
218   }
219   mainLayout->setColumnStretch(0, 0);
220   mainLayout->setColumnStretch(1, 1);
221   mainLayout->setRowStretch(2, 1);
222   setLayout(mainLayout);
223 
224   //----singnal-slot connections
225 
226   bool ret = connect(m_channelEdit, SIGNAL(textChanged(const QString &)),
227                      SLOT(onEditChanged(const QString &)));
228   ret      = ret && connect(m_channelEdit, SIGNAL(editingFinished()),
229                        SLOT(onEditFinished()));
230   ret      = ret && connect(m_channelSlider, SIGNAL(valueChanged(int)),
231                        SLOT(onSliderChanged(int)));
232   ret      = ret && connect(m_channelSlider, SIGNAL(sliderReleased()),
233                        SLOT(onSliderReleased()));
234   assert(ret);
235 }
236 
237 //-----------------------------------------------------------------------------
238 /*! Set current value to \b value.
239                 \sa getChannel()
240 */
setChannel(int value)241 void ChannelField::setChannel(int value) {
242   if (getChannel() == value) return;
243   assert(0 <= value && value <= m_maxValue);
244   m_channelSlider->setValue(value);
245   m_channelEdit->setValue(value);
246 }
247 
248 //-----------------------------------------------------------------------------
249 /*! Return current channel value.
250                 \sa setChannel()
251 */
getChannel()252 int ChannelField::getChannel() {
253   int value = m_channelEdit->getValue();
254   assert(m_channelSlider->value() == value);
255   return value;
256 }
257 
258 //-----------------------------------------------------------------------------
259 /*!	Set slider value to new string \b str value.
260                 Verify if value is lower than 255 or greater than 0, range,
261    otherwise set
262                 current value to 255 or 0. If slider value is different from
263    value in \b str
264                 emit signal valueChanged(int value).
265 */
onEditChanged(const QString & str)266 void ChannelField::onEditChanged(const QString &str) {
267   int value = str.toInt();
268   if (value < 0) value = 0;
269   if (value > m_maxValue) value = m_maxValue;
270   assert(0 <= value && value <= m_maxValue);
271   if (str.toInt() != value) m_channelEdit->setValue(value);
272   if (m_channelSlider->value() == value) return;
273   m_channelSlider->setValue(value);
274   emit valueChanged(value, true);
275 }
276 
277 //-----------------------------------------------------------------------------
278 
onEditFinished()279 void ChannelField::onEditFinished() {
280   emit valueChanged(m_channelEdit->getValue(), false);
281 }
282 
283 //-----------------------------------------------------------------------------
284 /*! Set text field value to \b value. If text field value is different from \b
285    value
286                 emit signal valueChanged(int value).
287 */
onSliderChanged(int value)288 void ChannelField::onSliderChanged(int value) {
289   assert(0 <= value && value <= m_maxValue);
290   if (m_channelEdit->getValue() == value) return;
291   m_channelEdit->setText(QString(std::to_string(value).c_str()));
292   emit valueChanged(value, true);
293 }
294 
295 //-----------------------------------------------------------------------------
296 
onSliderReleased()297 void ChannelField::onSliderReleased() {
298   emit valueChanged(m_channelSlider->value(), false);
299 }
300 
301 //=============================================================================
302 
303 ColorField::ColorFieldEditorController *ColorField::m_editorController = 0;
304 //																							new
305 // ColorField::ColorFieldEditorController();
306 
307 //=============================================================================
308 /*! \class DVGui::ColorField
309                 \brief The ColorField class is used to view an object to manage
310    a color.
311 
312                 Inherits \b QWidget.
313 
314                 The object is composed of a horizontal layout \b QHBoxLayout
315    which contains
316                 a StyleSample, and three or four ChannelField, it depend if
317    transparency is
318                 count, to manage color channel.
319                 You can pass to constructor current color value, getColor(), or
320    set it
321                 calling setColor(). You can also pass to constructor a boolean
322    to know if
323                 manage transparency channel or not, and an integer for
324    StyleSample size.
325 
326                 To know when color value change class provides a signal,
327    colorChanged(const TPixel32 &);
328                 class emit signal when one ChannelField value change.
329                 See SLOT: onRedChannelChanged(int value),
330    onGreenChannelChanged(int value),
331                 onBlueChannelChanged(int value) and onAlphaChannelChanged(int
332    value) to know
333                 when signal is emitted.
334 
335                 \b Example: initialize a ColorField with transparency channel.
336                 \code
337                         ColorField* colorFld = new
338    ColorField(0,true,TPixel32(0,0,255,255),50);
339                 \endcode
340                 \b Result:
341                         \image html ColorField.jpg
342 */
343 /*!	\fn void DVGui::ColorField::colorChanged(const TPixel32 &)
344                 This signal is emitted when a channel value of current color
345    change.
346 */
347 /*!	\fn TPixel32  DVGui::ColorField::getColor() const
348                 Return ColorField current color.
349 */
ColorField(QWidget * parent,bool isAlphaActive,TPixel32 color,int squareSize,bool useStyleEditor,int sliderWidth)350 ColorField::ColorField(QWidget *parent, bool isAlphaActive, TPixel32 color,
351                        int squareSize, bool useStyleEditor, int sliderWidth)
352     : QWidget(parent)
353     , m_color(color)
354     , m_notifyEditingChange(true)
355     , m_useStyleEditor(useStyleEditor) {
356   setMaximumHeight(squareSize);
357   QHBoxLayout *layout = new QHBoxLayout(this);
358   layout->setMargin(0);
359   layout->setSpacing(5);
360 
361   layout->setSizeConstraint(QLayout::SetFixedSize);
362 
363   int h = WidgetHeight;
364 
365   m_colorSample = new StyleSample(this, squareSize, squareSize);
366   m_colorSample->setColor(m_color);
367   m_redChannel =
368       new ChannelField(this, tr("R:"), m_color.r, 255, false, 13, sliderWidth);
369   connect(m_redChannel, SIGNAL(valueChanged(int, bool)),
370           SLOT(onRedChannelChanged(int, bool)));
371   m_greenChannel =
372       new ChannelField(this, tr("G:"), m_color.g, 255, false, 13, sliderWidth);
373   connect(m_greenChannel, SIGNAL(valueChanged(int, bool)),
374           SLOT(onGreenChannelChanged(int, bool)));
375   m_blueChannel =
376       new ChannelField(this, tr("B:"), m_color.b, 255, false, 13, sliderWidth);
377   connect(m_blueChannel, SIGNAL(valueChanged(int, bool)),
378           SLOT(onBlueChannelChanged(int, bool)));
379   m_alphaChannel =
380       new ChannelField(this, tr("A:"), m_color.m, 255, false, 13, sliderWidth);
381   connect(m_alphaChannel, SIGNAL(valueChanged(int, bool)),
382           SLOT(onAlphaChannelChanged(int, bool)));
383 
384   layout->addWidget(m_colorSample);
385   layout->addWidget(m_redChannel);
386   layout->addWidget(m_greenChannel);
387   layout->addWidget(m_blueChannel);
388   layout->addWidget(m_alphaChannel);
389 
390   if (!isAlphaActive) m_alphaChannel->hide();
391   setLayout(layout);
392 }
393 
394 //-----------------------------------------------------------------------------
395 /*! Set ColorField current color to \b color. Update channel value of
396                 \b ChannelField and \b StyleSample color.
397 */
398 
setAlphaActive(bool active)399 void ColorField::setAlphaActive(bool active) {
400   if (active && !m_alphaChannel->isVisible()) {
401     m_alphaChannel->show();
402     connect(m_alphaChannel, SIGNAL(valueChanged(int, bool)),
403             SLOT(onAlphaChannelChanged(int, bool)));
404     assert(m_color.m == 255);
405     m_alphaChannel->setChannel(0);
406     m_color.m = 0;
407     m_colorSample->setColor(m_color);
408     emit colorChanged(m_color, false);
409   } else if (!active && m_alphaChannel->isVisible()) {
410     m_alphaChannel->hide();
411     disconnect(m_alphaChannel, SIGNAL(valueChanged(int, bool)), this,
412                SLOT(onAlphaChannelChanged(int, bool)));
413     if (m_color.m != 255) {
414       m_alphaChannel->setChannel(255);
415       m_color.m = 255;
416       m_colorSample->setColor(m_color);
417       emit colorChanged(m_color, false);
418     }
419   }
420 }
421 
422 //------------------------------
423 
setColor(const TPixel32 & color)424 void ColorField::setColor(const TPixel32 &color) {
425   if (m_color == color) return;
426   m_color = color;
427   updateChannels();
428   m_colorSample->setColor(m_color);
429 }
430 
431 //-----------------------------------------------------------------------------
432 /*! Set all \b ChannelField channel value to ColorField current color.
433  */
hideChannelsFields(bool hide)434 void ColorField::hideChannelsFields(bool hide) {
435   if (hide) {
436     m_redChannel->hide();
437     m_greenChannel->hide();
438     m_blueChannel->hide();
439     m_alphaChannel->hide();
440     disconnect(m_redChannel, SIGNAL(valueChanged(int, bool)), this,
441                SLOT(onRedChannelChanged(int, bool)));
442     disconnect(m_greenChannel, SIGNAL(valueChanged(int, bool)), this,
443                SLOT(onGreenChannelChanged(int, bool)));
444     disconnect(m_blueChannel, SIGNAL(valueChanged(int, bool)), this,
445                SLOT(onBlueChannelChanged(int, bool)));
446     disconnect(m_alphaChannel, SIGNAL(valueChanged(int, bool)), this,
447                SLOT(onAlphaChannelChanged(int, bool)));
448   } else {
449     m_redChannel->show();
450     m_greenChannel->show();
451     m_blueChannel->show();
452     m_alphaChannel->show();
453     ;
454     connect(m_redChannel, SIGNAL(valueChanged(int, bool)),
455             SLOT(onRedChannelChanged(int, bool)));
456     connect(m_greenChannel, SIGNAL(valueChanged(int, bool)),
457             SLOT(onGreenChannelChanged(int, bool)));
458     connect(m_blueChannel, SIGNAL(valueChanged(int, bool)),
459             SLOT(onBlueChannelChanged(int, bool)));
460     connect(m_alphaChannel, SIGNAL(valueChanged(int, bool)),
461             SLOT(onAlphaChannelChanged(int, bool)));
462   }
463 }
464 
465 //-----------------------------------------------------------------------------
466 /*! Set all \b ChannelField channel value to ColorField current color.
467  */
updateChannels()468 void ColorField::updateChannels() {
469   m_redChannel->setChannel(m_color.r);
470   m_greenChannel->setChannel(m_color.g);
471   m_blueChannel->setChannel(m_color.b);
472   m_alphaChannel->setChannel(m_color.m);
473 }
474 
475 //-----------------------------------------------------------------------------
476 
mousePressEvent(QMouseEvent * event)477 void ColorField::mousePressEvent(QMouseEvent *event) {
478   if (event->button() != Qt::LeftButton) return;
479   QPoint p = event->pos();
480   if (!m_colorSample->visibleRegion().contains(p)) return;
481 
482   if (!m_useStyleEditor || !getEditorController()) return;
483 
484   getEditorController()->edit(this);
485 }
486 
487 //-----------------------------------------------------------------------------
488 
mouseDoubleClickEvent(QMouseEvent * event)489 void ColorField::mouseDoubleClickEvent(QMouseEvent *event) {
490   QPoint p = event->pos();
491   if (!m_colorSample->visibleRegion().contains(p)) return;
492 
493   if (!m_useStyleEditor || !getEditorController()) return;
494 
495   CommandManager::instance()->execute("MI_OpenStyleControl");
496   getEditorController()->edit(this);
497 }
498 
499 //-----------------------------------------------------------------------------
500 
hideEvent(QHideEvent *)501 void ColorField::hideEvent(QHideEvent *) {
502   if (!m_useStyleEditor || !getEditorController()) return;
503 
504   getEditorController()->hide();
505 }
506 
507 //-----------------------------------------------------------------------------
508 /*! If current red channel value of color is different from \b value set it,
509                 change \b StyleSample color and emit signal \b
510    colorChanged(const TPixel32 &).
511 */
onRedChannelChanged(int value,bool isDragging)512 void ColorField::onRedChannelChanged(int value, bool isDragging) {
513   if (m_color.r == value) {
514     if (!isDragging) emit colorChanged(m_color, isDragging);
515     return;
516   }
517   m_color = TPixel32(value, m_color.g, m_color.b, m_color.m);
518   m_colorSample->setColor(m_color);
519   emit colorChanged(m_color, isDragging);
520 }
521 
522 //-----------------------------------------------------------------------------
523 /*! If current green channel value of color is different from \b value set it,
524                 change \b StyleSample color and emit signal \b
525    colorChanged(const TPixel32 &).
526 */
onGreenChannelChanged(int value,bool isDragging)527 void ColorField::onGreenChannelChanged(int value, bool isDragging) {
528   if (m_color.g == value) {
529     if (!isDragging) emit colorChanged(m_color, isDragging);
530     return;
531   }
532   m_color = TPixel32(m_color.r, value, m_color.b, m_color.m);
533   m_colorSample->setColor(m_color);
534   emit colorChanged(m_color, isDragging);
535 }
536 
537 //-----------------------------------------------------------------------------
538 /*! If current blue channel value of color is different from \b value set it,
539                 change \b StyleSample color and emit signal \b
540    colorChanged(const TPixel32 &).
541 */
onBlueChannelChanged(int value,bool isDragging)542 void ColorField::onBlueChannelChanged(int value, bool isDragging) {
543   if (m_color.b == value) {
544     if (!isDragging) emit colorChanged(m_color, isDragging);
545     return;
546   }
547   m_color = TPixel32(m_color.r, m_color.g, value, m_color.m);
548   m_colorSample->setColor(m_color);
549   emit colorChanged(m_color, isDragging);
550 }
551 
552 //-----------------------------------------------------------------------------
553 /*! If current alpha channel value of color is different from \b value set it,
554                 change \b StyleSample color and emit signal \b
555    colorChanged(const TPixel32 &).
556 */
onAlphaChannelChanged(int value,bool isDragging)557 void ColorField::onAlphaChannelChanged(int value, bool isDragging) {
558   if (m_color.m == value) {
559     if (!isDragging) emit colorChanged(m_color, isDragging);
560     return;
561   }
562   m_color = TPixel32(m_color.r, m_color.g, m_color.b, value);
563   m_colorSample->setColor(m_color);
564   emit colorChanged(m_color, isDragging);
565 }
566 
567 //-----------------------------------------------------------------------------
568 
setChessboardColors(const TPixel32 & col1,const TPixel32 & col2)569 void ColorField::setChessboardColors(const TPixel32 &col1,
570                                      const TPixel32 &col2) {
571   m_colorSample->setChessboardColors(col1, col2);
572 }
573 
574 //-----------------------------------------------------------------------------
575 
setEditorController(ColorFieldEditorController * editorController)576 void ColorField::setEditorController(
577     ColorFieldEditorController *editorController) {
578   m_editorController = editorController;
579 }
580 
581 //-----------------------------------------------------------------------------
582 
getEditorController()583 ColorField::ColorFieldEditorController *ColorField::getEditorController() {
584   return m_editorController;
585 }
586 
587 //-----------------------------------------------------------------------
588 #define SQUARESIZE 50
589 
onBrightnessChannelChanged(int value,bool dragging)590 void CleanupColorField::onBrightnessChannelChanged(int value, bool dragging) {
591   m_cleanupStyle->setBrightness(value);
592   m_ph->notifyColorStyleChanged(dragging);
593 }
594 
595 //-----------------------------------------------
596 
onContrastChannelChanged(int value,bool dragging)597 void CleanupColorField::onContrastChannelChanged(int value, bool dragging) {
598   m_cleanupStyle->setContrast(value);
599   m_ph->notifyColorStyleChanged(dragging);
600 }
601 
602 //-----------------------------------------------
603 
onCThresholdChannelChanged(int value,bool dragging)604 void CleanupColorField::onCThresholdChannelChanged(int value, bool dragging) {
605   ((TBlackCleanupStyle *)m_cleanupStyle)->setColorThreshold((double)value);
606   m_ph->notifyColorStyleChanged(dragging);
607 }
608 
609 //-----------------------------------------------
610 
onWThresholdChannelChanged(int value,bool dragging)611 void CleanupColorField::onWThresholdChannelChanged(int value, bool dragging) {
612   ((TBlackCleanupStyle *)m_cleanupStyle)->setWhiteThreshold((double)value);
613   m_ph->notifyColorStyleChanged(dragging);
614 }
615 
onHRangeChannelChanged(int value,bool dragging)616 void CleanupColorField::onHRangeChannelChanged(int value, bool dragging) {
617   ((TColorCleanupStyle *)m_cleanupStyle)->setHRange(value);
618   m_ph->notifyColorStyleChanged(dragging);
619 }
620 
621 //-----------------------------------------------
622 
onLineWidthChannelChanged(int value,bool dragging)623 void CleanupColorField::onLineWidthChannelChanged(int value, bool dragging) {
624   ((TColorCleanupStyle *)m_cleanupStyle)->setLineWidth(value);
625   m_ph->notifyColorStyleChanged(dragging);
626 }
627 
628 //---------------------------------------------------
629 
mousePressEvent(QMouseEvent * event)630 void CleanupColorField::mousePressEvent(QMouseEvent *event) {
631   if (event->button() != Qt::LeftButton) return;
632 
633   emit StyleSelected(m_cleanupStyle);
634 
635   if (getEditorController()) getEditorController()->edit(this);
636 }
637 
638 //-----------------------------------------------
CleanupColorField(QWidget * parent,TCleanupStyle * cleanupStyle,TPaletteHandle * ph,bool greyMode)639 CleanupColorField::CleanupColorField(QWidget *parent,
640                                      TCleanupStyle *cleanupStyle,
641                                      TPaletteHandle *ph, bool greyMode)
642     : QWidget(parent)
643     , m_style(cleanupStyle)
644     , m_cleanupStyle(cleanupStyle)
645     , m_ph(ph)
646     , m_greyMode(greyMode)
647     , m_notifyEditingChange(true) {
648   TBlackCleanupStyle *bs = dynamic_cast<TBlackCleanupStyle *>(cleanupStyle);
649   TColorCleanupStyle *cs = dynamic_cast<TColorCleanupStyle *>(cleanupStyle);
650   assert(bs || cs);
651 
652   m_colorSample = new StyleSample(this, SQUARESIZE / 2, SQUARESIZE);
653   m_brightnessChannel =
654       new ChannelField(this, DVGui::CleanupColorField::tr("Brightness:"),
655                        cleanupStyle->getBrightness(), 100, true, 75, -1);
656   m_contrastChannel =
657       new ChannelField(this, DVGui::CleanupColorField::tr("Contrast:"),
658                        cleanupStyle->getContrast(), 100, true, 75, -1);
659   if (!greyMode) {
660     if (bs) {
661       m_cThresholdChannel =
662           new ChannelField(this, DVGui::CleanupColorField::tr("Color Thres"),
663                            bs->getColorThreshold(), 100, true, 75, -1);
664       m_wThresholdChannel =
665           new ChannelField(this, DVGui::CleanupColorField::tr("White Thres"),
666                            bs->getWhiteThreshold(), 100, true, 75, -1);
667     } else  // cs
668     {
669       m_hRangeChannel =
670           new ChannelField(this, DVGui::CleanupColorField::tr("H Range"),
671                            cs->getHRange(), 120, true, 75, -1);
672       m_lineWidthChannel =
673           new ChannelField(this, DVGui::CleanupColorField::tr("Line Width"),
674                            cs->getLineWidth(), 100, true, 75, -1);
675     }
676   }
677 
678   m_colorSample->setStyle(*cleanupStyle);
679 
680   //---- layout
681 
682   QHBoxLayout *mainLay = new QHBoxLayout();
683   mainLay->setMargin(8);
684   mainLay->setSpacing(5);
685   {
686     mainLay->addWidget(m_colorSample, 0);
687 
688     QVBoxLayout *paramLay = new QVBoxLayout();
689     paramLay->setMargin(0);
690     paramLay->setSpacing(3);
691     {
692       paramLay->addWidget(m_brightnessChannel);
693       paramLay->addWidget(m_contrastChannel);
694       if (!greyMode) {
695         if (bs) {
696           paramLay->addWidget(m_cThresholdChannel);
697           paramLay->addWidget(m_wThresholdChannel);
698         } else {
699           paramLay->addWidget(m_hRangeChannel);
700           paramLay->addWidget(m_lineWidthChannel);
701         }
702       }
703     }
704     mainLay->addLayout(paramLay, 1);
705   }
706   setLayout(mainLay);
707 
708   //---- signal-slot connections
709 
710   bool ret = true;
711   ret = ret && connect(m_brightnessChannel, SIGNAL(valueChanged(int, bool)),
712                        SLOT(onBrightnessChannelChanged(int, bool)));
713   ret = ret && connect(m_contrastChannel, SIGNAL(valueChanged(int, bool)),
714                        SLOT(onContrastChannelChanged(int, bool)));
715   if (!greyMode) {
716     if (bs) {
717       ret = ret && connect(m_cThresholdChannel, SIGNAL(valueChanged(int, bool)),
718                            SLOT(onCThresholdChannelChanged(int, bool)));
719       ret = ret && connect(m_wThresholdChannel, SIGNAL(valueChanged(int, bool)),
720                            SLOT(onWThresholdChannelChanged(int, bool)));
721     } else {
722       ret = ret && connect(m_hRangeChannel, SIGNAL(valueChanged(int, bool)),
723                            SLOT(onHRangeChannelChanged(int, bool)));
724       ret = ret && connect(m_lineWidthChannel, SIGNAL(valueChanged(int, bool)),
725                            SLOT(onLineWidthChannelChanged(int, bool)));
726     }
727   }
728 }
729 
730 //--------------------------------------------------------------
731 
updateColor()732 void CleanupColorField::updateColor() {
733   if (m_cleanupStyle->canUpdate()) {
734     m_cleanupStyle->invalidateIcon();
735     m_colorSample->setStyle(*m_cleanupStyle);
736 
737     m_brightnessChannel->setChannel(m_cleanupStyle->getBrightness());
738     if (m_cleanupStyle->isContrastEnabled())
739       m_contrastChannel->setChannel(m_cleanupStyle->getContrast());
740 
741     TBlackCleanupStyle *bs;
742     TColorCleanupStyle *cs;
743     if ((bs = dynamic_cast<TBlackCleanupStyle *>(m_cleanupStyle)) &&
744         !m_greyMode) {
745       m_cThresholdChannel->setChannel(bs->getColorThreshold());
746       m_wThresholdChannel->setChannel(bs->getWhiteThreshold());
747     } else if ((cs = dynamic_cast<TColorCleanupStyle *>(m_cleanupStyle))) {
748       m_hRangeChannel->setChannel(cs->getHRange());
749       m_lineWidthChannel->setChannel(cs->getLineWidth());
750     }
751   }
752 }
753 
754 //--------------------------------------------------------------
755 
getColor() const756 TPixel32 CleanupColorField::getColor() const {
757   return m_cleanupStyle->getMainColor();
758 }
759 
760 //--------------------------------------------------------------
761 
setColor(const TPixel32 & color)762 void CleanupColorField::setColor(const TPixel32 &color) {
763   if (m_cleanupStyle->getMainColor() == color) return;
764 
765   m_cleanupStyle->setMainColor(color);
766   m_cleanupStyle->invalidateIcon();
767   m_colorSample->setStyle(*m_cleanupStyle);
768   m_ph->notifyColorStyleChanged(false);
769 }
770 
771 //------------------------------------------------------------
772 
getOutputColor() const773 TPixel32 CleanupColorField::getOutputColor() const {
774   return m_cleanupStyle->getColorParamValue(1);
775 }
776 
777 //------------------------------------------------------------
778 
setOutputColor(const TPixel32 & color)779 void CleanupColorField::setOutputColor(const TPixel32 &color) {
780   if (getOutputColor() == color) return;
781 
782   m_cleanupStyle->setColorParamValue(1, color);
783   m_cleanupStyle->invalidateIcon();
784   m_colorSample->setStyle(*m_cleanupStyle);
785   m_ph->notifyColorStyleChanged();
786 }
787 
788 //------------------------------------------------------------
789 
setStyle(TColorStyle * style)790 void CleanupColorField::setStyle(TColorStyle *style) {
791   if (getColor() == style->getMainColor() &&
792       getOutputColor() == style->getColorParamValue(1))
793     return;
794 
795   m_cleanupStyle->setMainColor(style->getMainColor());
796   m_cleanupStyle->setColorParamValue(1, style->getColorParamValue(1));
797   m_cleanupStyle->invalidateIcon();
798   m_colorSample->setStyle(*m_cleanupStyle);
799   m_ph->notifyColorStyleChanged();
800 }
801 
802 //------------------------------------------------------------
803 
804 CleanupColorField::CleanupColorFieldEditorController
805     *CleanupColorField::m_editorController = 0;
806 
807 CleanupColorField::CleanupColorFieldEditorController *
getEditorController()808 CleanupColorField::getEditorController() {
809   return m_editorController;
810 }
811 
812 //-----------------------------------------------------------------------------
813 
setEditorController(CleanupColorFieldEditorController * editorController)814 void CleanupColorField::setEditorController(
815     CleanupColorFieldEditorController *editorController) {
816   m_editorController = editorController;
817 }
818 
819 //------------------------------------------------------------------
820 
mouseDoubleClickEvent(QMouseEvent * event)821 void CleanupColorField::mouseDoubleClickEvent(QMouseEvent *event) {
822   QPoint p = event->pos();
823   if (!m_colorSample->visibleRegion().contains(p)) return;
824   emit StyleSelected(m_cleanupStyle);
825   if (!getEditorController()) return;
826 
827   CommandManager::instance()->execute("MI_OpenStyleControl");
828   getEditorController()->edit(this);
829 }
830 
831 //-----------------------------------------------------------
832 
hideEvent(QHideEvent *)833 void CleanupColorField::hideEvent(QHideEvent *) {
834   if (!getEditorController()) return;
835   getEditorController()->edit(0);
836   getEditorController()->hide();
837   // setEditorController(0);
838 }
839 
840 //-----------------------------------------------------------
841 
setContrastEnabled(bool enable)842 void CleanupColorField::setContrastEnabled(bool enable) {
843   m_contrastChannel->setEnabled(enable);
844   m_cleanupStyle->enableContrast(enable);
845 }
846