43 int channel2): QWidget(parent), m_d(new
Private)
45 m_d->dimension = dimension;
46 int maxchannel = parent->selectorModel()->colorSpace()->colorChannelCount()-1;
47 m_d->channel1 = qBound(0, channel1, maxchannel);
48 m_d->channel2 = qBound(0, channel2, maxchannel);
49 m_d->channelMask = 1 << channel1;
51 m_d->channelMask |= 1 << channel2;
53 this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
61 return m_d->currentCoordinates;
66 QPointF newPos(qBound(0.0, position.x(), 1.0), qBound(0.0, position.y(), 1.0));
67 if (newPos !=
m_d->currentCoordinates)
69 m_d->currentCoordinates = newPos;
71 m_d->currentChannelValues[
m_d->channel1] = newPos.x();
73 m_d->currentChannelValues[
m_d->channel2] = newPos.y();
85 m_d->currentChannelValues = channelValues;
86 bool setCursor = channelFlags &
m_d->channelMask;
88 m_d->currentCoordinates = QPointF(qBound(0.f, channelValues[
m_d->channel1], 1.f),
89 qBound(0.f, channelValues[
m_d->channel2], 1.f));
93 m_d->currentChannelValues[
m_d->channel1] =
m_d->currentCoordinates.x();
95 m_d->currentChannelValues[
m_d->channel2] =
m_d->currentCoordinates.y();
98 m_d->imagesNeedUpdate =
m_d->imagesNeedUpdate || channelFlags & ~m_d->channelMask;
104 m_d->acceptTabletEvents = on;
111 &&
m_d->channel1 == 0;
122 m_d->alphaNeedsUpdate =
true;
123 m_d->imagesNeedUpdate =
true;
141 return selectorWidget;
155 if (
m_d->imagesNeedUpdate) {
160 m_d->imagesNeedUpdate =
false;
162 return m_d->gradient;
168 Q_ASSERT(bufferSize == imgSize.width() * imgSize.height() * colorSpace->
pixelSize());
177 image = QImage(width(), height(), QImage::Format_ARGB32);
178 image.fill(Qt::black);
191 const qreal deviceDivider = 1.0 / devicePixelRatioF();
192 const int deviceWidth = qCeil(width() * devicePixelRatioF());
193 const int deviceHeight = qCeil(height() * devicePixelRatioF());
195 QScopedArrayPointer<quint8> raw(
new quint8[imageSize] {});
196 quint8 *dataPtr = raw.data();
197 QVector4D coordinates = channelValues;
200 bool checkAlpha = !alpha.isNull() && alpha.valid(deviceWidth - 1, deviceHeight - 1);
206 for (
int y = 0; y < deviceHeight; y++) {
207 const uchar *alphaLine = checkAlpha ? alpha.scanLine(y) : 0;
208 for (
int x=0; x < deviceWidth; x++) {
209 if (!checkAlpha || alphaLine[x]) {
211 coordinates[
m_d->channel1] = newcoordinate.x();
213 coordinates[
m_d->channel2] = newcoordinate.y();
216 memcpy(dataPtr, c.
data(), pixelSize);
221 memcpy(dataPtr, filler.
data(), pixelSize);
223 dataPtr += pixelSize;
226 QImage image =
convertImageMap(raw.data(), imageSize, QSize(deviceWidth, deviceHeight));
227 image.setDevicePixelRatio(devicePixelRatioF());
229 if (!alpha.isNull()) {
230 QPainter painter(&image);
232 painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
233 painter.drawImage(0, 0, alpha);
244 if (
m_d->alphaNeedsUpdate) {
246 if (!staticAlpha.isNull()) {
247 QVector4D neutralValues(1, 1, 1, 1);
252 neutralValues.setZ(0.5f);
260 m_d->alphaNeedsUpdate =
false;
262 if (
m_d->alphaMask.isNull()) {
263 return m_d->staticBackground;
267 if (!
m_d->staticBackground.isNull()) {
268 QPainter painter(&bgImage);
270 painter.setCompositionMode(QPainter::CompositionMode_DestinationOver);
271 painter.drawImage(0, 0,
m_d->staticBackground);
294 if (e->button() == Qt::LeftButton) {
295 m_d->dragStart = e->localPos();
307 if (e->buttons() & Qt::LeftButton) {
317 if (e->button() == Qt::LeftButton) {
328 if (
m_d->acceptTabletEvents &&
329 (event->button() == Qt::LeftButton || (event->buttons() & Qt::LeftButton)))
332 switch (event->type()) {
333 case QEvent::TabletPress: {
334 QMouseEvent mouseEvent(QEvent::MouseButtonPress, event->posF(), event->posF(),
335 event->globalPosF(), event->button(), event->buttons(),
336 event->modifiers(), Qt::MouseEventSynthesizedByApplication);
340 case QEvent::TabletMove: {
341 QMouseEvent mouseEvent(QEvent::MouseMove, event->posF(), event->posF(),
342 event->globalPosF(), event->button(), event->buttons(),
343 event->modifiers(), Qt::MouseEventSynthesizedByApplication);
347 case QEvent::TabletRelease: {
348 QMouseEvent mouseEvent(QEvent::MouseButtonRelease, event->posF(), event->posF(),
349 event->globalPosF(), event->button(), event->buttons(),
350 event->modifiers(), Qt::MouseEventSynthesizedByApplication);
362 QPainter painter(
this);
365 if (!fullSelector.isNull()) {
366 painter.drawImage(0, 0, fullSelector);
372 painter.setRenderHint(QPainter::Antialiasing);
392 return m_d->dimension;
407 if (dimension == 0) {
408 return m_d->channel1;
411 return m_d->channel2;
418 return m_d->channelMask;
The KisVisualColorModel class allows manipulating a KoColor using various color models.
const KoColorSpace * colorSpace() const
KoColor convertChannelValuesToKoColor(const QVector4D &values) const
KisVisualColorModel * selectorModel() const
void setCursorPosition(QPointF position, bool signal=false)
setCursorPosition Set the cursor to normalized shape coordinates. This will only repaint the cursor.
void setChannelValues(QVector4D channelValues, quint32 channelFlags)
setChannelValues Set the current channel values; Note that channel values controlled by the shape its...
void mouseReleaseEvent(QMouseEvent *e) override
KisVisualColorSelector * colorSelector() const
virtual bool supportsGamutMask() const
void mouseMoveEvent(QMouseEvent *e) override
void forceImageUpdate()
forceImageUpdate force the image to recache.
virtual QPointF convertWidgetCoordinateToShapeCoordinate(QPointF coordinate) const =0
convertWidgetCoordinateToShapeCoordinate Convert a coordinate in the widget's height/width to a shape...
QPointF getCursorPosition() const
getCursorPosition
virtual void drawCursor(QPainter &painter)=0
int channel(int dimension) const
channel Get the channel index associated with a selector shape dimension
virtual QImage renderStaticAlphaMask() const
virtual QImage renderBackground(const QVector4D &channelValues, const QImage &alpha) const
renderBackground Render the widget background visible inside the widget's mask in current color space...
virtual QImage compositeBackground() const
virtual QImage renderAlphaMask() const
render the alpha mask for the widget background the returned image is expected to be QImage::Format_A...
quint32 channelMask() const
void mousePressEvent(QMouseEvent *e) override
void setAcceptTabletEvents(bool on)
~KisVisualColorSelectorShape() override
virtual void updateGamutMask()
Notify shape that the gamut mask changed.
QColor getColorFromConverter(KoColor c)
getColorFromConverter
virtual void drawGamutMask(QPainter &painter)
void tabletEvent(QTabletEvent *event) override
virtual QRegion getMaskMap()=0
getPixmap
KoColor getCurrentColor()
getCurrentColor
void sigCursorMoved(QPointF pos)
const QScopedPointer< Private > m_d
bool isHueControl() const
void paintEvent(QPaintEvent *) override
KisVisualColorSelectorShape(KisVisualColorSelector *parent, KisVisualColorSelectorShape::Dimensions dimension, int channel1, int channel2)
Dimensions getDimensions() const
getDimensions
virtual QPointF mousePositionToShapeCoordinate(const QPointF &pos, const QPointF &dragStart) const
default implementation just calls convertWidgetCoordinateToShapeCoordinate(pos)
QImage convertImageMap(const quint8 *rawColor, quint32 bufferSize, QSize imgSize) const
convertImageMap convert image data containing raw KoColor data into a QImage
Dimensions
The Dimensions enum Whether or not the shape is single or two dimensional.
const QImage & getImageMap()
getImageMap returns the updated base image
void resizeEvent(QResizeEvent *) override
The KisVisualColorSelector class.
void sigInteraction(bool active)
sigInteraction is emitted whenever mouse interaction status changes
const KoColorDisplayRendererInterface * displayRenderer() const
KisVisualColorModelSP selectorModel() const
virtual QColor toQColor(const KoColor &c, bool proofToPaintColors=false) const =0
virtual QImage toQImage(const KoColorSpace *srcColorSpace, const quint8 *data, QSize size, bool proofPaintColors=false) const =0
Convert a consecutive block of pixel data to an ARGB32 QImage.
virtual quint32 pixelSize() const =0
#define KIS_SAFE_ASSERT_RECOVER(cond)
QVector4D currentChannelValues
QPointF currentCoordinates