Krita Source Code Documentation
Loading...
Searching...
No Matches
WGMyPaintShadeSelector Class Reference

A port of MyPaint's "Crossed Bowl" color selector. More...

#include <WGMyPaintShadeSelector.h>

+ Inheritance diagram for WGMyPaintShadeSelector:

Public Member Functions

void setModel (KisVisualColorModelSP model) override
 
 WGMyPaintShadeSelector (WGSelectorDisplayConfigSP displayConfig, QWidget *parent, UiMode mode)
 
 ~WGMyPaintShadeSelector () override
 
- Public Member Functions inherited from WGSelectorWidgetBase
WGSelectorDisplayConfigSP displayConfiguration () const
 
const KisDisplayColorConverterdisplayConverter () const
 
virtual QPoint popupOffset () const
 The position, relative to the top left corner, where the cursor of the cursor shall be when showing the popup.
 
void setUiMode (UiMode mode)
 
UiMode uiMode () const
 
virtual void updateSettings ()
 
 WGSelectorWidgetBase (WGSelectorDisplayConfigSP displayConfig, QWidget *parent=nullptr, UiMode uiMode=UiMode::DockerMode)
 

Protected Member Functions

bool getChannelValues (QPoint pos, QVector4D &values, QVector4D &blendValues)
 
void mouseMoveEvent (QMouseEvent *event) override
 
void mousePressEvent (QMouseEvent *event) override
 
void mouseReleaseEvent (QMouseEvent *event) override
 
void paintEvent (QPaintEvent *) override
 
void pickColorAt (const QPointF &posF)
 
void recalculateSizeHD ()
 
void resizeEvent (QResizeEvent *event) override
 

Private Slots

void slotSetChannelValues (const QVector4D &values)
 

Private Attributes

bool m_allowUpdates {true}
 
float m_colorH {0.0f}
 
float m_colorS {0.0f}
 
float m_colorV {0.0f}
 
int m_heightHD
 
KisVisualColorModelSP m_model
 
KisPaintDeviceSP m_realCircleBorder
 
KisPaintDeviceSP m_realPixelCache
 
int m_sizeHD
 
int m_widthHD
 

Additional Inherited Members

- Public Types inherited from WGSelectorWidgetBase
enum  UiMode { DockerMode , PopupMode }
 
- Signals inherited from WGSelectorWidgetBase
void sigChannelValuesChanged (const QVector4D &values)
 
void sigColorInteraction (bool active)
 

Detailed Description

A port of MyPaint's "Crossed Bowl" color selector.

Definition at line 18 of file WGMyPaintShadeSelector.h.

Constructor & Destructor Documentation

◆ WGMyPaintShadeSelector()

WGMyPaintShadeSelector::WGMyPaintShadeSelector ( WGSelectorDisplayConfigSP displayConfig,
QWidget * parent,
UiMode mode )

Definition at line 44 of file WGMyPaintShadeSelector.cpp.

45 : WGSelectorWidgetBase(displayConfig, parent, mode)
46{
48}
WGSelectorWidgetBase(WGSelectorDisplayConfigSP displayConfig, QWidget *parent=nullptr, UiMode uiMode=UiMode::DockerMode)

References recalculateSizeHD().

◆ ~WGMyPaintShadeSelector()

WGMyPaintShadeSelector::~WGMyPaintShadeSelector ( )
override

Definition at line 50 of file WGMyPaintShadeSelector.cpp.

51{
52
53}

Member Function Documentation

◆ getChannelValues()

bool WGMyPaintShadeSelector::getChannelValues ( QPoint pos,
QVector4D & values,
QVector4D & blendValues )
protected

Definition at line 162 of file WGMyPaintShadeSelector.cpp.

163{
164 bool needsBlending = false;
165
166 const float v_factor = 0.6f;
167 const float s_factor = 0.6f;
168 const float v_factor2 = 0.013f;
169 const float s_factor2 = 0.013f;
170
171 const int stripe_width = (15 * m_sizeHD)/255;
172 int s_radiusHD = m_sizeHD/2.6;
173
174 float h = 0;
175 float s = 0;
176 float v = 0;
177
178 int dx = pos.x() - m_widthHD/2;
179 int dy = pos.y() - m_heightHD/2;
180 int diag = sqrt(2.0) * m_sizeHD/2;
181
182 int dxs, dys;
183 if (dx > 0)
184 dxs = dx - stripe_width;
185 else
186 dxs = dx + stripe_width;
187 if (dy > 0)
188 dys = dy - stripe_width;
189 else
190 dys = dy + stripe_width;
191
192 qreal r = std::sqrt(qreal(sqr(dxs)+sqr(dys)));
193
194 if (qMin(abs(dx), abs(dy)) < stripe_width) {
195 // horizontal and vertical lines
196 bool horizontal = std::abs(dx) > std::abs(dy);
197 dx = (dx/qreal(m_sizeHD))*255;
198 dy = (dy/qreal(m_sizeHD))*255;
199
200 h = 0;
201 // x-axis = value, y-axis = saturation
202 v = dx*v_factor + signedSqr(dx)*v_factor2;
203 s = - (dy*s_factor + signedSqr(dy)*s_factor2);
204 // but not both at once
205 if (horizontal) {
206 // horizontal stripe
207 s = 0.0;
208 } else {
209 // vertical stripe
210 v = 0.0;
211 }
212 }
213 else if (std::min(std::abs(dx - dy), std::abs(dx + dy)) < stripe_width) {
214
215 dx = (dx/qreal(m_sizeHD))*255;
216 dy = (dy/qreal(m_sizeHD))*255;
217
218 h = 0;
219 // x-axis = value, y-axis = saturation
220 v = dx*v_factor + signedSqr(dx)*v_factor2;
221 s = - (dy*s_factor + signedSqr(dy)*s_factor2);
222 // both at once
223 }
224 else if (r < s_radiusHD+1) {
225
226 // hue
227 if (dx > 0)
228 h = 90*sqr2(r/s_radiusHD);
229 else
230 h = 360 - 90*sqr2(r/s_radiusHD);
231 s = 256*(atan2f(std::abs(dxs),dys)/M_PI) - 128;
232
233 if (r > s_radiusHD) {
234 needsBlending = true;
235 // antialiasing boarder
236 qreal aaFactor = r-floor(r); // part after the decimal point
237 aaFactor = 1-aaFactor;
238
239 qreal fh = m_colorH + h/360.0;
240 qreal fs = m_colorS + s/255.0;
241 qreal fv = m_colorV + v/255.0;
242
243 fh -= floor(fh);
244 fs = qBound(qreal(0.0), fs, qreal(1.0));
245 fv = qBound(qreal(0.01), fv, qreal(1.0));
246 blendValues = QVector4D(fh, fs, fv, aaFactor);
247
248 h = 180 + 180*atan2f(dys,-dxs)/M_PI;
249 v = 255*(r-s_radiusHD)/(diag-s_radiusHD) - 128;
250 s = 0; // overwrite the s value that was meant for the inside of the circle
251 // here we already have drawn the inside, and the value left should be just the background value
252 }
253 }
254 else {
255 // background (hue+darkness gradient)
256 h = 180 + 180*atan2f(dys,-dxs)/M_PI;
257 v = 255*(r-s_radiusHD)/(diag-s_radiusHD) - 128;
258 }
259
260 qreal fh = m_colorH + h/360.0;
261 qreal fs = m_colorS + s/255.0;
262 qreal fv = m_colorV + v/255.0;
263
264 fh -= floor(fh);
265 fs = qBound(qreal(0.0), fs, qreal(1.0));
266 fv = qBound(qreal(0.01), fv, qreal(1.0));
267 values = QVector4D(fh, fs, fv, 0);
268
269 return needsBlending;
270}
qreal v
#define M_PI
Definition kis_global.h:111
int signedSqr(int x)
qreal sqr2(qreal x)
Point abs(const Point &pt)

References m_colorH, m_colorS, m_colorV, m_heightHD, M_PI, m_sizeHD, m_widthHD, signedSqr(), sqr(), sqr2(), and v.

◆ mouseMoveEvent()

void WGMyPaintShadeSelector::mouseMoveEvent ( QMouseEvent * event)
overrideprotected

Definition at line 81 of file WGMyPaintShadeSelector.cpp.

82{
83 if (event->buttons() & Qt::LeftButton) {
84 if (rect().contains(event->pos())) {
85 pickColorAt(event->localPos());
86 }
87 } else {
88 event->ignore();
89 }
90}
void pickColorAt(const QPointF &posF)

References pickColorAt().

◆ mousePressEvent()

void WGMyPaintShadeSelector::mousePressEvent ( QMouseEvent * event)
overrideprotected

Definition at line 71 of file WGMyPaintShadeSelector.cpp.

72{
73 if (event->button() == Qt::LeftButton) {
74 Q_EMIT sigColorInteraction(true);
75 pickColorAt(event->localPos());
76 } else {
77 event->ignore();
78 }
79}
void sigColorInteraction(bool active)

References pickColorAt(), and WGSelectorWidgetBase::sigColorInteraction().

◆ mouseReleaseEvent()

void WGMyPaintShadeSelector::mouseReleaseEvent ( QMouseEvent * event)
overrideprotected

Definition at line 92 of file WGMyPaintShadeSelector.cpp.

93{
94 if (event->button() == Qt::LeftButton) {
95 Q_EMIT sigColorInteraction(false);
96 } else {
97 event->ignore();
98 }
99}

References WGSelectorWidgetBase::sigColorInteraction().

◆ paintEvent()

void WGMyPaintShadeSelector::paintEvent ( QPaintEvent * )
overrideprotected

Definition at line 101 of file WGMyPaintShadeSelector.cpp.

102{
103 // Hint to the casual reader: some of the calculation here do not
104 // what Martin Renold originally intended. Not everything here will make sense.
105 // It does not matter in the end, as long as the result looks good.
106 if (!m_model || !m_model->isHSXModel()) {
107 return;
108 }
109
110 // This selector was ported from MyPaint in 2010
111 if (!m_realPixelCache || m_realPixelCache->colorSpace() != m_model->colorSpace()) {
112 m_realPixelCache = new KisPaintDevice(m_model->colorSpace());
113 m_realCircleBorder = new KisPaintDevice(m_model->colorSpace());
114// m_cachedColorSpace = colorSpace();
115 }
116 else {
119 }
120
121 const int pixelSize = m_model->colorSpace()->pixelSize();
122
123 QRect pickRectHighDPI = QRect(QPoint(0, 0), size()*devicePixelRatioF());
124 KisSequentialIterator it(m_realPixelCache, pickRectHighDPI);
125 KisSequentialIterator borderIt(m_realCircleBorder, pickRectHighDPI);
126 QVector4D values;
127 QVector4D values2;
128
129 while (it.nextPixel() && borderIt.nextPixel()) {
130 const int x = it.x();
131 const int y = it.y();
132
133 bool needsBlending = getChannelValues(QPoint(x, y), values, values2);
134
135 if (needsBlending) {
136 const qreal aaFactor = static_cast<qreal>(values2[3]);
137 KoColor color = m_model->convertChannelValuesToKoColor(values2);
138 color.setOpacity(aaFactor);
139 setColorWithIterator(borderIt, color, pixelSize);
140 }
141
142 KoColor color = m_model->convertChannelValuesToKoColor(values);
143 setColorWithIterator(it, color, pixelSize);
144 }
145
147 gc.bitBlt(QPoint(0,0), m_realCircleBorder, QRect(rect().topLeft(), rect().size()*devicePixelRatioF()));
148
149 QPainter painter(this);
150 QImage renderedImage = displayConverter()->toQImage(m_realPixelCache, displayConfiguration()->previewInPaintingCS());
151 renderedImage.setDevicePixelRatio(devicePixelRatioF());
152
153 painter.drawImage(0, 0, renderedImage);
154}
void setColorWithIterator(Iterator &it, const KoColor &color, const int pixelSize)
QImage toQImage(KisPaintDeviceSP srcDevice, bool proofPaintColors=false) const
virtual void clear()
const KoColorSpace * colorSpace() const
void setOpacity(quint8 alpha)
Definition KoColor.cpp:333
bool getChannelValues(QPoint pos, QVector4D &values, QVector4D &blendValues)
KisVisualColorModelSP m_model
KisPaintDeviceSP m_realCircleBorder
const KisDisplayColorConverter * displayConverter() const
WGSelectorDisplayConfigSP displayConfiguration() const
int size(const Forest< T > &forest)
Definition KisForest.h:1232

References KisPainter::bitBlt(), KisPaintDevice::clear(), KisPaintDevice::colorSpace(), WGSelectorWidgetBase::displayConfiguration(), WGSelectorWidgetBase::displayConverter(), getChannelValues(), m_model, m_realCircleBorder, m_realPixelCache, KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::nextPixel(), setColorWithIterator(), KoColor::setOpacity(), KisDisplayColorConverter::toQImage(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::x(), and KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::y().

◆ pickColorAt()

void WGMyPaintShadeSelector::pickColorAt ( const QPointF & posF)
protected

Definition at line 272 of file WGMyPaintShadeSelector.cpp.

273{
274 QPoint pos = (posF * devicePixelRatioF()).toPoint();
275 QVector4D values, dummy;
276 getChannelValues(pos, values, dummy);
277 m_allowUpdates = false;
278 Q_EMIT sigChannelValuesChanged(values);
279 m_allowUpdates = true;
280}
void sigChannelValuesChanged(const QVector4D &values)

References getChannelValues(), m_allowUpdates, and WGSelectorWidgetBase::sigChannelValuesChanged().

◆ recalculateSizeHD()

void WGMyPaintShadeSelector::recalculateSizeHD ( )
protected

Definition at line 282 of file WGMyPaintShadeSelector.cpp.

283{
284 m_widthHD = qMax(1, width()) * devicePixelRatioF();
285 m_heightHD = qMax(1, height()) *devicePixelRatioF();
287}

References m_heightHD, m_sizeHD, and m_widthHD.

◆ resizeEvent()

void WGMyPaintShadeSelector::resizeEvent ( QResizeEvent * event)
overrideprotected

Definition at line 156 of file WGMyPaintShadeSelector.cpp.

157{
158 WGSelectorWidgetBase::resizeEvent(event);
160}

References recalculateSizeHD().

◆ setModel()

void WGMyPaintShadeSelector::setModel ( KisVisualColorModelSP model)
overridevirtual

Reimplemented from WGSelectorWidgetBase.

Definition at line 55 of file WGMyPaintShadeSelector.cpp.

56{
57 if (m_model) {
58 disconnect(m_model.data());
59 m_model->disconnect(this);
60 }
61 m_model = model;
62 connect(this, SIGNAL(sigChannelValuesChanged(QVector4D)),
63 m_model.data(), SLOT(slotSetChannelValues(QVector4D)));
64 connect(m_model.data(), SIGNAL(sigChannelValuesChanged(QVector4D,quint32)),
65 this, SLOT(slotSetChannelValues(QVector4D)));
66 if (m_model->isHSXModel()) {
67 slotSetChannelValues(m_model->channelValues());
68 }
69}
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
void slotSetChannelValues(const QVector4D &values)

References connect(), m_model, WGSelectorWidgetBase::sigChannelValuesChanged(), and slotSetChannelValues().

◆ slotSetChannelValues

void WGMyPaintShadeSelector::slotSetChannelValues ( const QVector4D & values)
privateslot

Definition at line 289 of file WGMyPaintShadeSelector.cpp.

290{
291 if (m_allowUpdates) {
292 m_colorH = values.x();
293 m_colorS = values.y();
294 m_colorV = values.z();
295 update();
296 }
297}
bool update(QSpinBox *spinBox)

References m_allowUpdates, m_colorH, m_colorS, and m_colorV.

Member Data Documentation

◆ m_allowUpdates

bool WGMyPaintShadeSelector::m_allowUpdates {true}
private

Definition at line 51 of file WGMyPaintShadeSelector.h.

51{true};

◆ m_colorH

float WGMyPaintShadeSelector::m_colorH {0.0f}
private

Definition at line 45 of file WGMyPaintShadeSelector.h.

45{0.0f};

◆ m_colorS

float WGMyPaintShadeSelector::m_colorS {0.0f}
private

Definition at line 46 of file WGMyPaintShadeSelector.h.

46{0.0f};

◆ m_colorV

float WGMyPaintShadeSelector::m_colorV {0.0f}
private

Definition at line 47 of file WGMyPaintShadeSelector.h.

47{0.0f};

◆ m_heightHD

int WGMyPaintShadeSelector::m_heightHD
private

Definition at line 50 of file WGMyPaintShadeSelector.h.

◆ m_model

KisVisualColorModelSP WGMyPaintShadeSelector::m_model
private

Definition at line 42 of file WGMyPaintShadeSelector.h.

◆ m_realCircleBorder

KisPaintDeviceSP WGMyPaintShadeSelector::m_realCircleBorder
private

Definition at line 44 of file WGMyPaintShadeSelector.h.

◆ m_realPixelCache

KisPaintDeviceSP WGMyPaintShadeSelector::m_realPixelCache
private

Definition at line 43 of file WGMyPaintShadeSelector.h.

◆ m_sizeHD

int WGMyPaintShadeSelector::m_sizeHD
private

Definition at line 48 of file WGMyPaintShadeSelector.h.

◆ m_widthHD

int WGMyPaintShadeSelector::m_widthHD
private

Definition at line 49 of file WGMyPaintShadeSelector.h.


The documentation for this class was generated from the following files: