Blob Blame Raw


#include "toonzqt/styleeditor.h"
#include "toonzqt/colorfield.h"
#include "toonzqt/dvdialog.h"
#include "toonzqt/gutil.h"
#include "toonzqt/menubarcommand.h"
#include "toonz/cleanupcolorstyles.h"
#include "tconvert.h"
#include "tcolorstyles.h"
#include "trop.h"

#include <QLayout>
#include <QPainter>
#include <QMouseEvent>
#include <QLabel>

using namespace DVGui;

//=============================================================================
/*! \class DVGui::StyleSample
		\brief The StyleSample class provides to view a square color.

		Inherits \b QWidget.

		By default square color is set to \b TPixel32(235,235,235,255), you
		can set other color using setColor(); you can also define current color
		with a style \b TColorStyle, \b getStyle(), using setStyle().
		You can pass to constructor square size.

		StyleSample permit to manage click event, it's possile to enable this
		feature setting enableClick(bool on) to true.
		If it is enable when click in square class emit the signal
		clicked(const TColorStyle &style).
*/
/*!	\fn void DVGui::StyleSample::clicked(const TColorStyle &style)
		This signal is emitted when click event is enable and a style is set.
*/
/*!	\fn void DVGui::StyleSample::enableClick(bool on)
		Set click event enable if \b is true, disable otherwise.
		If true setStyle store current style and buttonPress emit signal
		clicked(const TColorStyle &style).
*/
StyleSample::StyleSample(QWidget *parent, int sizeX, int sizeY)
	: m_samplePixmap(sizeX, sizeY, QImage::Format_ARGB32), m_bgRas(sizeX, sizeY), m_style(0), m_clickEnabled(false), m_chessColor1(0, 0, 0), m_chessColor2(255, 255, 255), m_isEditing(false)
{
	setMinimumSize(sizeX, sizeY);
	setColor(TPixel32::Transparent);
	TRop::checkBoard(m_bgRas, m_chessColor1, m_chessColor2, TDimensionD(sizeX / 8, sizeX / 8), TPointD(0, 0));
	setEnable(true);
}

//-----------------------------------------------------------------------------

StyleSample::~StyleSample()
{
	if (m_style)
		delete m_style;
	m_style = 0;
}

//-----------------------------------------------------------------------------
/*! Return current StyleSample \b TColorStyle style.
*/
TColorStyle *StyleSample::getStyle() const
{
	return m_style;
}

//-----------------------------------------------------------------------------
/*! Update current square colore and, if click event is enable set current
		StyleSample \b TColorStyle style to \b style.
*/
void StyleSample::setStyle(TColorStyle &style)
{
	/*-- TSolidColorStyleの場合のみ、単色塗りつぶし --*/
	if (style.getTagId() == 3)
		setColor(style.getMainColor());
	else {
		TRaster32P icon = style.getIcon(qsize2Dimension(m_samplePixmap.rect().size()));
		m_samplePixmap = rasterToQImage(icon, false); //modified in 6.2
		update();
	}
	if (m_clickEnabled)
		m_style = style.clone();
}

//-----------------------------------------------------------------------------
/*! Update current square colore to \b TPixel32 \b color.
		Useful for efficiency if click event is disable.
*/
void StyleSample::setColor(const TPixel32 &pixel)
{
	QColor color(pixel.r, pixel.g, pixel.b, pixel.m);
	//iwsw commented out temporarily
	//if (Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled())
	//	Ghibli3DLutConverter::instance()->convert(color);
	m_samplePixmap.fill(color.rgba());
	update();
}

//-----------------------------------------------------------------------------

void StyleSample::setChessboardColors(const TPixel32 &col1, const TPixel32 &col2)
{
	m_chessColor1 = col1;
	m_chessColor2 = col2;
	TRop::checkBoard(m_bgRas, m_chessColor1, m_chessColor2, TDimensionD(m_bgRas->getLx() / 8, m_bgRas->getLy() / 8), TPointD(0, 0));
	update();
}

//-----------------------------------------------------------------------------
/*! Paint square color.
*/
void StyleSample::paintEvent(QPaintEvent *event)
{
	if (!isEnable())
		return;
	QPainter painter(this);
	QImage img(m_bgRas->getRawData(), m_bgRas->getLx(), m_bgRas->getLy(), QImage::Format_ARGB32);
	painter.drawImage(0, 0, img.scaled(size()));
	painter.drawImage(0, 0, m_samplePixmap.scaled(size()));
	if (m_isEditing) {
		//QRect rect(0,0,m_bgRas->getLx(),m_bgRas->getLy());
		painter.setPen(Qt::white);
		painter.drawRect(rect().adjusted(0, 0, -1, -1));
		painter.drawRect(rect().adjusted(2, 2, -3, -3));
		painter.setPen(QColor(180, 210, 255));
		painter.drawRect(rect().adjusted(1, 1, -2, -2));
	}
}

//-----------------------------------------------------------------------------
/*! If exist current style and event click is enable emit signal
		clicked(const TColorStyle &style).
*/
void StyleSample::mousePressEvent(QMouseEvent *event)
{
	if (m_style && m_clickEnabled)
		emit clicked(*m_style);
	else
		event->ignore();
}

//-----------------------------------------------------------------------------

void StyleSample::mouseDoubleClickEvent(QMouseEvent *event)
{
	event->ignore();
}

//=============================================================================
/*! \class DVGui::ChannelField
		\brief The ChannelField class is used to view an object to manage a color
					 value, red, green, blue or transparency channel.

		Inherits \b QWidget.

		The object is composed of grid layout \b QGridLayout which contains a label
		in first row, first column, to identify channel, a text field \b IntLineEdit
		in first row, second column, and a slider in second row, second column.
		Texf field and slider are connected, so if you change one the other automatically
		change. You can set current value getChannel(), using setChannel().
		This two object is used to manage channel value, them range is fixed to [0,255].
		This object size is fixed, [50, 2*DVGui::WidgetHeight].

		To know when channel parameter value change class provides a signal, valueChanged(int value);
		class emit signal when slider value change or when text field is editing,
		see SLOT: onSliderChanged(int value) and onEditChanged(const QString &str)
		to know when signal is emitted.
*/
/*!	\fn void DVGui::ChannelField::valueChanged(int value)
		This signal is emitted when ChannelField, slider or text field, value change;
		if slider position change or text field is editing.
		\sa onEditChanged(const QString &str) and onSliderChanged(int value).
*/
ChannelField::ChannelField(QWidget *parent,
						   const QString &string,
						   int value, int maxValue, bool horizontal, int labelWidth, int sliderWidth)
	: QWidget(parent), m_maxValue(maxValue)
{
	assert(maxValue > 0);
	assert(0 <= value && value <= m_maxValue);

	QLabel *channelName = new QLabel(string, this);
	m_channelEdit = new DVGui::IntLineEdit(this, value, 0, maxValue);
	m_channelSlider = new QSlider(Qt::Horizontal, this);

	channelName->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
	channelName->setFixedWidth(labelWidth);

	m_channelSlider->setRange(0, maxValue);
	m_channelSlider->setValue(value);

	//----layout
	QGridLayout *mainLayout = new QGridLayout(this);
	mainLayout->setMargin(0);
	mainLayout->setSpacing(3);
	{
		mainLayout->addWidget(channelName, 0, 0);
		mainLayout->addWidget(m_channelEdit, 0, 1);

		mainLayout->addWidget(m_channelSlider, horizontal ? 0 : 1, horizontal ? 2 : 1);
	}
	mainLayout->setColumnStretch(0, 0);
	mainLayout->setColumnStretch(1, 1);
	mainLayout->setRowStretch(2, 1);
	setLayout(mainLayout);

	//----singnal-slot connections

	bool ret = connect(m_channelEdit, SIGNAL(textChanged(const QString &)),
					   SLOT(onEditChanged(const QString &)));
	ret = ret && connect(m_channelSlider, SIGNAL(valueChanged(int)), SLOT(onSliderChanged(int)));
	ret = ret && connect(m_channelSlider, SIGNAL(sliderReleased()), SLOT(onSliderReleased()));
	assert(ret);
}

//-----------------------------------------------------------------------------
/*! Set current value to \b value.
		\sa getChannel()
*/
void ChannelField::setChannel(int value)
{
	if (getChannel() == value)
		return;
	assert(0 <= value && value <= m_maxValue);
	m_channelSlider->setValue(value);
	m_channelEdit->setValue(value);
}

//-----------------------------------------------------------------------------
/*! Return current channel value.
		\sa setChannel()
*/
int ChannelField::getChannel()
{
	int value = m_channelEdit->getValue();
	assert(m_channelSlider->value() == value);
	return value;
}

//-----------------------------------------------------------------------------
/*!	Set slider value to new string \b str value.
		Verify if value is lower than 255 or greater than 0, range, otherwise set
		current value to 255 or 0. If slider value is different from value in \b str
		emit signal valueChanged(int value).
*/
void ChannelField::onEditChanged(const QString &str)
{
	int value = str.toInt();
	if (value < 0)
		value = 0;
	if (value > m_maxValue)
		value = m_maxValue;
	assert(0 <= value && value <= m_maxValue);
	if (str.toInt() != value)
		m_channelEdit->setValue(value);
	if (m_channelSlider->value() == value)
		return;
	m_channelSlider->setValue(value);
	emit valueChanged(value, false);
}

//-----------------------------------------------------------------------------
/*! Set text field value to \b value. If text field value is different from \b value
		emit signal valueChanged(int value).
*/
void ChannelField::onSliderChanged(int value)
{
	assert(0 <= value && value <= m_maxValue);
	if (m_channelEdit->getValue() == value)
		return;
	m_channelEdit->setText(QString(toString(value).c_str()));
	emit valueChanged(value, true);
}

//-----------------------------------------------------------------------------

void ChannelField::onSliderReleased()
{
	emit valueChanged(m_channelSlider->value(), false);
}

//=============================================================================

ColorField::ColorFieldEditorController *ColorField::m_editorController = 0;
//																							new ColorField::ColorFieldEditorController();

//=============================================================================
/*! \class DVGui::ColorField
		\brief The ColorField class is used to view an object to manage a color.

		Inherits \b QWidget.

		The object is composed of a horizontal layout \b QHBoxLayout which contains
		a StyleSample, and three or four ChannelField, it depend if transparency is
		count, to manage color channel.
		You can pass to constructor current color value, getColor(), or set it
		calling setColor(). You can also pass to constructor a boolean to know if
		manage transparency channel or not, and an integer for StyleSample size.

		To know when color value change class provides a signal, colorChanged(const TPixel32 &);
		class emit signal when one ChannelField value change.
		See SLOT: onRedChannelChanged(int value), onGreenChannelChanged(int value),
		onBlueChannelChanged(int value) and onAlphaChannelChanged(int value) to know
		when signal is emitted.

		\b Example: initialize a ColorField with transparency channel.
		\code
			ColorField* colorFld = new ColorField(0,true,TPixel32(0,0,255,255),50);
		\endcode
		\b Result:
			\image html ColorField.jpg
*/
/*!	\fn void DVGui::ColorField::colorChanged(const TPixel32 &)
		This signal is emitted when a channel value of current color change.
*/
/*!	\fn TPixel32  DVGui::ColorField::getColor() const
		Return ColorField current color.
*/
ColorField::ColorField(QWidget *parent,
					   bool isAlphaActive,
					   TPixel32 color,
					   int squareSize,
					   bool useStyleEditor)
	: QWidget(parent), m_color(color), m_notifyEditingChange(true), m_useStyleEditor(useStyleEditor)
{
	setMaximumHeight(squareSize);
	QHBoxLayout *layout = new QHBoxLayout(this);
	layout->setMargin(0);
	layout->setSpacing(5);

	layout->setSizeConstraint(QLayout::SetFixedSize);

	int h = WidgetHeight;

	m_colorSample = new StyleSample(this, squareSize, squareSize);
	m_colorSample->setColor(m_color);
	m_redChannel = new ChannelField(this, QString("R:"), m_color.r);
	connect(m_redChannel, SIGNAL(valueChanged(int, bool)), SLOT(onRedChannelChanged(int, bool)));
	m_greenChannel = new ChannelField(this, QString("G:"), m_color.g);
	connect(m_greenChannel, SIGNAL(valueChanged(int, bool)), SLOT(onGreenChannelChanged(int, bool)));
	m_blueChannel = new ChannelField(this, QString("B:"), m_color.b);
	connect(m_blueChannel, SIGNAL(valueChanged(int, bool)), SLOT(onBlueChannelChanged(int, bool)));
	m_alphaChannel = new ChannelField(this, QString("M:"), m_color.m);
	connect(m_alphaChannel, SIGNAL(valueChanged(int, bool)), SLOT(onAlphaChannelChanged(int, bool)));

	layout->addWidget(m_colorSample);
	layout->addWidget(m_redChannel);
	layout->addWidget(m_greenChannel);
	layout->addWidget(m_blueChannel);
	layout->addWidget(m_alphaChannel);

	if (!isAlphaActive)
		m_alphaChannel->hide();
	setLayout(layout);
}

//-----------------------------------------------------------------------------
/*! Set ColorField current color to \b color. Update channel value of
		\b ChannelField and \b StyleSample color.
*/

void ColorField::setAlphaActive(bool active)
{
	if (active && !m_alphaChannel->isVisible()) {
		m_alphaChannel->show();
		connect(m_alphaChannel, SIGNAL(valueChanged(int, bool)), SLOT(onAlphaChannelChanged(int, bool)));
		assert(m_color.m == 255);
		//m_color.m = m_alphaChannel->getChannel();
		//m_colorSample->setColor(m_color);
	} else if (!active && m_alphaChannel->isVisible()) {
		m_alphaChannel->hide();
		disconnect(m_alphaChannel, SIGNAL(valueChanged(int, bool)), this, SLOT(onAlphaChannelChanged(int, bool)));
		if (m_color.m != 255) {
			m_alphaChannel->setChannel(255);
			m_color.m = 255;
			m_colorSample->setColor(m_color);
			emit colorChanged(m_color, false);
		}
	}
}

//------------------------------

void ColorField::setColor(const TPixel32 &color)
{
	if (m_color == color)
		return;
	m_color = color;
	updateChannels();
	m_colorSample->setColor(m_color);
}

//-----------------------------------------------------------------------------
/*! Set all \b ChannelField channel value to ColorField current color.
*/
void ColorField::hideChannelsFields(bool hide)
{
	if (hide) {
		m_redChannel->hide();
		m_greenChannel->hide();
		m_blueChannel->hide();
		m_alphaChannel->hide();
		disconnect(m_redChannel, SIGNAL(valueChanged(int, bool)), this, SLOT(onRedChannelChanged(int, bool)));
		disconnect(m_greenChannel, SIGNAL(valueChanged(int, bool)), this, SLOT(onGreenChannelChanged(int, bool)));
		disconnect(m_blueChannel, SIGNAL(valueChanged(int, bool)), this, SLOT(onBlueChannelChanged(int, bool)));
		disconnect(m_alphaChannel, SIGNAL(valueChanged(int, bool)), this, SLOT(onAlphaChannelChanged(int, bool)));
	} else {
		m_redChannel->show();
		m_greenChannel->show();
		m_blueChannel->show();
		m_alphaChannel->show();
		;
		connect(m_redChannel, SIGNAL(valueChanged(int, bool)), SLOT(onRedChannelChanged(int, bool)));
		connect(m_greenChannel, SIGNAL(valueChanged(int, bool)), SLOT(onGreenChannelChanged(int, bool)));
		connect(m_blueChannel, SIGNAL(valueChanged(int, bool)), SLOT(onBlueChannelChanged(int, bool)));
		connect(m_alphaChannel, SIGNAL(valueChanged(int, bool)), SLOT(onAlphaChannelChanged(int, bool)));
	}
}

//-----------------------------------------------------------------------------
/*! Set all \b ChannelField channel value to ColorField current color.
*/
void ColorField::updateChannels()
{
	m_redChannel->setChannel(m_color.r);
	m_greenChannel->setChannel(m_color.g);
	m_blueChannel->setChannel(m_color.b);
	m_alphaChannel->setChannel(m_color.m);
}

//-----------------------------------------------------------------------------

void ColorField::mousePressEvent(QMouseEvent *event)
{
	if (event->button() != Qt::LeftButton)
		return;
	QPoint p = event->pos();
	if (!m_colorSample->visibleRegion().contains(p))
		return;

	if (!m_useStyleEditor || !getEditorController())
		return;

	getEditorController()->edit(this);
}

//-----------------------------------------------------------------------------

void ColorField::mouseDoubleClickEvent(QMouseEvent *event)
{
	QPoint p = event->pos();
	if (!m_colorSample->visibleRegion().contains(p))
		return;

	if (!m_useStyleEditor || !getEditorController())
		return;

	CommandManager::instance()->execute("MI_OpenStyleControl");
	getEditorController()->edit(this);
}

//-----------------------------------------------------------------------------

void ColorField::hideEvent(QHideEvent *)
{
	if (!m_useStyleEditor || !getEditorController())
		return;

	getEditorController()->hide();
}

//-----------------------------------------------------------------------------
/*! If current red channel value of color is different from \b value set it,
		change \b StyleSample color and emit signal \b colorChanged(const TPixel32 &).
*/
void ColorField::onRedChannelChanged(int value, bool isDragging)
{
	if (m_color.r == value) {
		if (!isDragging)
			emit colorChanged(m_color, isDragging);
		return;
	}
	m_color = TPixel32(value, m_color.g, m_color.b, m_color.m);
	m_colorSample->setColor(m_color);
	emit colorChanged(m_color, isDragging);
}

//-----------------------------------------------------------------------------
/*! If current green channel value of color is different from \b value set it,
		change \b StyleSample color and emit signal \b colorChanged(const TPixel32 &).
*/
void ColorField::onGreenChannelChanged(int value, bool isDragging)
{
	if (m_color.g == value) {
		if (!isDragging)
			emit colorChanged(m_color, isDragging);
		return;
	}
	m_color = TPixel32(m_color.r, value, m_color.b, m_color.m);
	m_colorSample->setColor(m_color);
	emit colorChanged(m_color, isDragging);
}

//-----------------------------------------------------------------------------
/*! If current blue channel value of color is different from \b value set it,
		change \b StyleSample color and emit signal \b colorChanged(const TPixel32 &).
*/
void ColorField::onBlueChannelChanged(int value, bool isDragging)
{
	if (m_color.b == value) {
		if (!isDragging)
			emit colorChanged(m_color, isDragging);
		return;
	}
	m_color = TPixel32(m_color.r, m_color.g, value, m_color.m);
	m_colorSample->setColor(m_color);
	emit colorChanged(m_color, isDragging);
}

//-----------------------------------------------------------------------------
/*! If current alpha channel value of color is different from \b value set it,
		change \b StyleSample color and emit signal \b colorChanged(const TPixel32 &).
*/
void ColorField::onAlphaChannelChanged(int value, bool isDragging)
{
	if (m_color.m == value) {
		if (!isDragging)
			emit colorChanged(m_color, isDragging);
		return;
	}
	m_color = TPixel32(m_color.r, m_color.g, m_color.b, value);
	m_colorSample->setColor(m_color);
	emit colorChanged(m_color, isDragging);
}

//-----------------------------------------------------------------------------

void ColorField::setChessboardColors(const TPixel32 &col1, const TPixel32 &col2)
{
	m_colorSample->setChessboardColors(col1, col2);
}

//-----------------------------------------------------------------------------

void ColorField::setEditorController(ColorFieldEditorController *editorController)
{
	m_editorController = editorController;
}

//-----------------------------------------------------------------------------

ColorField::ColorFieldEditorController *ColorField::getEditorController()
{
	return m_editorController;
}

//-----------------------------------------------------------------------
#define SQUARESIZE 50

void CleanupColorField::onBrightnessChannelChanged(int value, bool dragging)
{
	m_cleanupStyle->setBrightness(value);
	m_ph->notifyColorStyleChanged(dragging);
}

//-----------------------------------------------

void CleanupColorField::onContrastChannelChanged(int value, bool dragging)
{
	m_cleanupStyle->setContrast(value);
	m_ph->notifyColorStyleChanged(dragging);
}

//-----------------------------------------------

void CleanupColorField::onCThresholdChannelChanged(int value, bool dragging)
{
	((TBlackCleanupStyle *)m_cleanupStyle)->setColorThreshold((double)value);
	m_ph->notifyColorStyleChanged(dragging);
}

//-----------------------------------------------

void CleanupColorField::onWThresholdChannelChanged(int value, bool dragging)
{
	((TBlackCleanupStyle *)m_cleanupStyle)->setWhiteThreshold((double)value);
	m_ph->notifyColorStyleChanged(dragging);
}

void CleanupColorField::onHRangeChannelChanged(int value, bool dragging)
{
	((TColorCleanupStyle *)m_cleanupStyle)->setHRange(value);
	m_ph->notifyColorStyleChanged(dragging);
}

//-----------------------------------------------

void CleanupColorField::onLineWidthChannelChanged(int value, bool dragging)
{
	((TColorCleanupStyle *)m_cleanupStyle)->setLineWidth(value);
	m_ph->notifyColorStyleChanged(dragging);
}

//---------------------------------------------------

void CleanupColorField::mousePressEvent(QMouseEvent *event)
{
	if (event->button() != Qt::LeftButton)
		return;

	emit StyleSelected(m_cleanupStyle);

	if (getEditorController())
		getEditorController()->edit(this);
}

//-----------------------------------------------
CleanupColorField::CleanupColorField(QWidget *parent, TCleanupStyle *cleanupStyle,
									 TPaletteHandle *ph, bool greyMode)
	: QWidget(parent), m_style(cleanupStyle), m_cleanupStyle(cleanupStyle), m_ph(ph), m_greyMode(greyMode), m_notifyEditingChange(true)
{
	TBlackCleanupStyle *bs = dynamic_cast<TBlackCleanupStyle *>(cleanupStyle);
	TColorCleanupStyle *cs = dynamic_cast<TColorCleanupStyle *>(cleanupStyle);
	assert(bs || cs);

	m_colorSample = new StyleSample(this, SQUARESIZE / 2, SQUARESIZE);
	m_brightnessChannel = new ChannelField(this, DVGui::CleanupColorField::tr("Brightness:"), cleanupStyle->getBrightness(), 100, true, 75, -1);
	m_contrastChannel = new ChannelField(this, DVGui::CleanupColorField::tr("Contrast:"), cleanupStyle->getContrast(), 100, true, 75, -1);
	if (!greyMode) {
		if (bs) {
			m_cThresholdChannel = new ChannelField(this, DVGui::CleanupColorField::tr("Color Thres"), bs->getColorThreshold(), 100, true, 75, -1);
			m_wThresholdChannel = new ChannelField(this, DVGui::CleanupColorField::tr("White Thres"), bs->getWhiteThreshold(), 100, true, 75, -1);
		} else //cs
		{
			m_hRangeChannel = new ChannelField(this, DVGui::CleanupColorField::tr("H Range"), cs->getHRange(), 120, true, 75, -1);
			m_lineWidthChannel = new ChannelField(this, DVGui::CleanupColorField::tr("Line Width"), cs->getLineWidth(), 100, true, 75, -1);
		}
	}

	m_colorSample->setStyle(*cleanupStyle);

	//---- layout

	QHBoxLayout *mainLay = new QHBoxLayout();
	mainLay->setMargin(8);
	mainLay->setSpacing(5);
	{
		mainLay->addWidget(m_colorSample, 0);

		QVBoxLayout *paramLay = new QVBoxLayout();
		paramLay->setMargin(0);
		paramLay->setSpacing(3);
		{
			paramLay->addWidget(m_brightnessChannel);
			paramLay->addWidget(m_contrastChannel);
			if (!greyMode) {
				if (bs) {
					paramLay->addWidget(m_cThresholdChannel);
					paramLay->addWidget(m_wThresholdChannel);
				} else {
					paramLay->addWidget(m_hRangeChannel);
					paramLay->addWidget(m_lineWidthChannel);
				}
			}
		}
		mainLay->addLayout(paramLay, 1);
	}
	setLayout(mainLay);

	//---- signal-slot connections

	bool ret = true;
	ret = ret && connect(m_brightnessChannel, SIGNAL(valueChanged(int, bool)), SLOT(onBrightnessChannelChanged(int, bool)));
	ret = ret && connect(m_contrastChannel, SIGNAL(valueChanged(int, bool)), SLOT(onContrastChannelChanged(int, bool)));
	if (!greyMode) {
		if (bs) {
			ret = ret && connect(m_cThresholdChannel, SIGNAL(valueChanged(int, bool)), SLOT(onCThresholdChannelChanged(int, bool)));
			ret = ret && connect(m_wThresholdChannel, SIGNAL(valueChanged(int, bool)), SLOT(onWThresholdChannelChanged(int, bool)));
		} else {
			ret = ret && connect(m_hRangeChannel, SIGNAL(valueChanged(int, bool)), SLOT(onHRangeChannelChanged(int, bool)));
			ret = ret && connect(m_lineWidthChannel, SIGNAL(valueChanged(int, bool)), SLOT(onLineWidthChannelChanged(int, bool)));
		}
	}
}

//--------------------------------------------------------------

void CleanupColorField::updateColor()
{
	if (m_cleanupStyle->canUpdate()) {
		m_cleanupStyle->invalidateIcon();
		m_colorSample->setStyle(*m_cleanupStyle);

		m_brightnessChannel->setChannel(m_cleanupStyle->getBrightness());
		if (m_cleanupStyle->isContrastEnabled())
			m_contrastChannel->setChannel(m_cleanupStyle->getContrast());

		TBlackCleanupStyle *bs;
		TColorCleanupStyle *cs;
		if ((bs = dynamic_cast<TBlackCleanupStyle *>(m_cleanupStyle)) && !m_greyMode) {
			m_cThresholdChannel->setChannel(bs->getColorThreshold());
			m_wThresholdChannel->setChannel(bs->getWhiteThreshold());
		} else if (cs = dynamic_cast<TColorCleanupStyle *>(m_cleanupStyle)) {
			m_hRangeChannel->setChannel(cs->getHRange());
			m_lineWidthChannel->setChannel(cs->getLineWidth());
		}
	}
}

//--------------------------------------------------------------

TPixel32 CleanupColorField::getColor() const
{
	return m_cleanupStyle->getMainColor();
}

//--------------------------------------------------------------

void CleanupColorField::setColor(const TPixel32 &color)
{
	if (m_cleanupStyle->getMainColor() == color)
		return;

	m_cleanupStyle->setMainColor(color);
	m_cleanupStyle->invalidateIcon();
	m_colorSample->setStyle(*m_cleanupStyle);
	m_ph->notifyColorStyleChanged(false);
}

//------------------------------------------------------------

TPixel32 CleanupColorField::getOutputColor() const
{
	return m_cleanupStyle->getColorParamValue(1);
}

//------------------------------------------------------------

void CleanupColorField::setOutputColor(const TPixel32 &color)
{
	if (getOutputColor() == color)
		return;

	m_cleanupStyle->setColorParamValue(1, color);
	m_cleanupStyle->invalidateIcon();
	m_colorSample->setStyle(*m_cleanupStyle);
	m_ph->notifyColorStyleChanged();
}

//------------------------------------------------------------

void CleanupColorField::setStyle(TColorStyle *style)
{
	if (getColor() == style->getMainColor() &&
		getOutputColor() == style->getColorParamValue(1))
		return;

	m_cleanupStyle->setMainColor(style->getMainColor());
	m_cleanupStyle->setColorParamValue(1, style->getColorParamValue(1));
	m_cleanupStyle->invalidateIcon();
	m_colorSample->setStyle(*m_cleanupStyle);
	m_ph->notifyColorStyleChanged();
}

//------------------------------------------------------------

CleanupColorField::CleanupColorFieldEditorController *CleanupColorField::m_editorController = 0;

CleanupColorField::CleanupColorFieldEditorController *CleanupColorField::getEditorController()
{
	return m_editorController;
}

//-----------------------------------------------------------------------------

void CleanupColorField::setEditorController(CleanupColorFieldEditorController *editorController)
{
	m_editorController = editorController;
}

//------------------------------------------------------------------

void CleanupColorField::mouseDoubleClickEvent(QMouseEvent *event)
{
	QPoint p = event->pos();
	if (!m_colorSample->visibleRegion().contains(p))
		return;
	emit StyleSelected(m_cleanupStyle);
	if (!getEditorController())
		return;

	CommandManager::instance()->execute("MI_OpenStyleControl");
	getEditorController()->edit(this);
}

//-----------------------------------------------------------

void CleanupColorField::hideEvent(QHideEvent *)
{
	if (!getEditorController())
		return;
	getEditorController()->edit(0);
	getEditorController()->hide();
	//setEditorController(0);
}

//-----------------------------------------------------------

void CleanupColorField::setContrastEnabled(bool enable)
{
	m_contrastChannel->setEnabled(enable);
	m_cleanupStyle->enableContrast(enable);
}