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

#include <kis_curve_widget.h>

+ Inheritance diagram for KisCurveWidget:

Public Types

enum  PointConstrain { PointConstrain_None , PointConstrain_AlwaysCorner , PointConstrain_AlwaysSmooth }
 

Public Slots

void setCurve (KisCubicCurve inlist)
 

Signals

void compressorShouldEmitModified ()
 
void curveChanged (const KisCubicCurve &)
 
void modified (void)
 
void pointSelectedChanged ()
 
void shouldFocusIOControls ()
 
void shouldSyncIOControls ()
 

Public Member Functions

void addPointInTheMiddle ()
 
void applyGlobalPointConstrain ()
 
std::optional< KisCubicCurvePointcurrentPoint () const
 
std::optional< QPointF > currentPointPosition () const
 
KisCubicCurve curve ()
 
void drawGrid (QPainter &p, int wWidth, int wHeight)
 
void dropInOutControls ()
 
QPixmap getPixmap ()
 
PointConstrain globalPointConstrain () const
 
std::optional< bool > isCurrentPointSetAsCorner () const
 
bool jumpOverExistingPoints (QPointF &pt, int skipIndex)
 
 KisCurveWidget (QWidget *parent=nullptr, Qt::WindowFlags f=Qt::WindowFlags())
 
int nearestPointInRange (QPointF pt, int wWidth, int wHeight) const
 
bool pointSelected () const
 
 Private (KisCurveWidget *parent)
 
void reset (void)
 
bool setCurrentPoint (const QPointF &position, bool setAsCorner)
 
bool setCurrentPointAsCorner (bool setAsCorner)
 
bool setCurrentPointPosition (const QPointF &position)
 
void setCurveModified (bool rewriteSpinBoxesValues=true)
 
void setCurveRepaint ()
 
void setGlobalPointConstrain (PointConstrain constrain)
 
void setPixmap (const QPixmap &pix)
 
void setState (enumState st)
 
void setupInOutControls (QSpinBox *in, QSpinBox *out, int inMin, int inMax, int outMin, int outMax)
 
enumState state () const
 
void syncIOControls ()
 
 ~KisCurveWidget () override
 

Public Attributes

KisCubicCurve m_curve
 
KisCubicCurvePoint m_draggedAwayPoint
 
int m_draggedAwayPointIndex {0}
 
KisCurveWidget::PointConstrain m_globalPointConstrain {KisCurveWidget::PointConstrain_None}
 
int m_grab_point_index {-1}
 
double m_grabOffsetX {0.0}
 
double m_grabOffsetY {0.0}
 
double m_grabOriginalX {0.0}
 
double m_grabOriginalY {0.0}
 
int m_handleSize {12}
 
KisThreadSafeSignalCompressor m_modifiedSignalsCompressor
 
QPixmap m_pix
 
QPixmap * m_pixmapCache {nullptr}
 
bool m_pixmapDirty {true}
 
bool m_readOnlyMode {false}
 
bool m_splineDirty {false}
 
enumState m_state {enumState::ST_NORMAL}
 

Protected Slots

void notifyModified ()
 
void slotCompressorShouldEmitModified ()
 

Protected Member Functions

void keyPressEvent (QKeyEvent *) override
 
void leaveEvent (QEvent *) override
 
void mouseMoveEvent (QMouseEvent *e) override
 
void mousePressEvent (QMouseEvent *e) override
 
void mouseReleaseEvent (QMouseEvent *e) override
 
void paintEvent (QPaintEvent *) override
 
void resizeEvent (QResizeEvent *e) override
 

Properties

bool pointSelected
 

Private Attributes

Private *const d {nullptr}
 
KisCurveWidgetm_curveWidget {nullptr}
 
- Private Attributes inherited from Private
KisCanvas2canvas
 
int displayedFrame
 
int intendedFrame
 

Friends

class CurveEditorItem
 

Additional Inherited Members

- Private Member Functions inherited from Private
 Private (KisCanvas2 *c)
 

Detailed Description

KisCurveWidget is a widget that shows a single curve that can be edited by the user. The user can grab the curve and move it; this creates a new control point. Control points can be deleted by selecting a point and pressing the delete key.

(From: https://techbase.kde.org/Projects/Widgets_and_Classes#KisCurveWidget) KisCurveWidget allows editing of spline based y=f(x) curves. Handy for cases where you want the user to control such things as tablet pressure response, color transformations, acceleration by time, aeroplane lift by angle of attack.

Private members for KisCurveWidget class

Definition at line 40 of file kis_curve_widget.h.

Member Enumeration Documentation

◆ PointConstrain

Enumerator
PointConstrain_None 
PointConstrain_AlwaysCorner 
PointConstrain_AlwaysSmooth 

Definition at line 80 of file kis_curve_widget.h.

Constructor & Destructor Documentation

◆ KisCurveWidget()

KisCurveWidget::KisCurveWidget ( QWidget * parent = nullptr,
Qt::WindowFlags f = Qt::WindowFlags() )

Create a new curve widget with a default curve, that is a straight line from bottom-left to top-right.

Definition at line 53 of file kis_curve_widget.cpp.

54 : QWidget(parent, f), d(new KisCurveWidget::Private(this))
55{
56 setObjectName("KisCurveWidget");
57
58 connect(&d->m_modifiedSignalsCompressor, SIGNAL(timeout()), SLOT(notifyModified()));
59 connect(this, SIGNAL(compressorShouldEmitModified()), SLOT(slotCompressorShouldEmitModified()));
60
61 setMouseTracking(true);
62 setAutoFillBackground(false);
63 setAttribute(Qt::WA_OpaquePaintEvent);
64 setMinimumSize(150, 50);
65 setMaximumSize(250, 250);
66
67 // Curves widgets don't have context menus. Setting this prevents any
68 // long-presses from delaying inputs, see KisLongPressEventFilter.cpp.
69 setContextMenuPolicy(Qt::PreventContextMenu);
70
71 setFocusPolicy(Qt::StrongFocus);
72}
Private *const d
void slotCompressorShouldEmitModified()
void compressorShouldEmitModified()
Private(KisCurveWidget *parent)

References compressorShouldEmitModified(), d, notifyModified(), and slotCompressorShouldEmitModified().

◆ ~KisCurveWidget()

KisCurveWidget::~KisCurveWidget ( )
override

Definition at line 74 of file kis_curve_widget.cpp.

75{
76 delete d->m_pixmapCache;
77 delete d;
78}

References d.

Member Function Documentation

◆ addPointInTheMiddle()

void KisCurveWidget::addPointInTheMiddle ( )

Handy function that creates new point in the middle of the curve and sets focus on the m_intIn field, so the user can move this point anywhere in a moment

Definition at line 248 of file kis_curve_widget.cpp.

249{
250 QPointF position(0.5, d->m_curve.value(0.5));
251
252 if (!d->jumpOverExistingPoints(position, -1))
253 return;
254
255 const bool setAsCorner = d->m_globalPointConstrain == PointConstrain_AlwaysCorner;
256
257 d->m_grab_point_index = d->m_curve.addPoint(position, setAsCorner);
258 Q_EMIT pointSelectedChanged();
259
260 Q_EMIT shouldFocusIOControls();
261 d->setCurveModified();
262}
void pointSelectedChanged()
void shouldFocusIOControls()

References d, PointConstrain_AlwaysCorner, pointSelectedChanged(), and shouldFocusIOControls().

◆ applyGlobalPointConstrain()

void KisCurveWidget::applyGlobalPointConstrain ( )

Ensure that all points conform to the global constrain set

◆ compressorShouldEmitModified

void KisCurveWidget::compressorShouldEmitModified ( )
signal

Emitted to notify that the start() function in compressor can be activated. Thanks to that, blocking signals in curve widget blocks "sending signals" (calling start() function) to the signal compressor. It effectively makes signals work nearly the same way they worked before adding the signal compressor in between.

◆ currentPoint()

std::optional< KisCubicCurvePoint > KisCurveWidget::currentPoint ( ) const

Definition at line 145 of file kis_curve_widget.cpp.

146{
147 return d->m_grab_point_index >= 0 && d->m_grab_point_index < d->m_curve.curvePoints().count()
148 ? std::make_optional(d->m_curve.curvePoints()[d->m_grab_point_index])
149 : std::nullopt;
150}

References d.

◆ currentPointPosition()

std::optional< QPointF > KisCurveWidget::currentPointPosition ( ) const

Definition at line 152 of file kis_curve_widget.cpp.

153{
154 return d->m_grab_point_index >= 0 && d->m_grab_point_index < d->m_curve.curvePoints().count()
155 ? std::make_optional(d->m_curve.curvePoints()[d->m_grab_point_index].position())
156 : std::nullopt;
157}

References d.

◆ curve()

KisCubicCurve KisCurveWidget::curve ( )
Returns
get a list with all defined points. If you want to know what the y value for a given x is on the curve defined by these points, use getCurveValue().
See also
getCurveValue

Definition at line 522 of file kis_curve_widget.cpp.

523{
524 return d->m_curve;
525}

References d.

◆ curveChanged

void KisCurveWidget::curveChanged ( const KisCubicCurve & )
signal

◆ drawGrid()

void KisCurveWidget::drawGrid ( QPainter & p,
int wWidth,
int wHeight )
inline

Nothing to be said! =)

◆ dropInOutControls()

void KisCurveWidget::dropInOutControls ( )

◆ getPixmap()

QPixmap KisCurveWidget::getPixmap ( )

Definition at line 191 of file kis_curve_widget.cpp.

192{
193 return d->m_pix;
194}

References d.

◆ globalPointConstrain()

KisCurveWidget::PointConstrain KisCurveWidget::globalPointConstrain ( ) const

Definition at line 166 of file kis_curve_widget.cpp.

167{
168 return d->m_globalPointConstrain;
169}

References d.

◆ isCurrentPointSetAsCorner()

std::optional< bool > KisCurveWidget::isCurrentPointSetAsCorner ( ) const

Definition at line 159 of file kis_curve_widget.cpp.

160{
161 return d->m_grab_point_index >= 0 && d->m_grab_point_index < d->m_curve.curvePoints().count()
162 ? std::make_optional(d->m_curve.curvePoints()[d->m_grab_point_index].isSetAsCorner())
163 : std::nullopt;
164}

References d.

◆ jumpOverExistingPoints()

bool KisCurveWidget::jumpOverExistingPoints ( QPointF & pt,
int skipIndex )

Check whether newly created/moved point pt doesn't overlap with any of existing ones from m_points and adjusts its coordinates. skipIndex is the index of the point, that shouldn't be taken into account during the search (e.g. because it's pt itself)

Returns false in case the point can't be placed anywhere without overlapping

◆ keyPressEvent()

void KisCurveWidget::keyPressEvent ( QKeyEvent * e)
overrideprotected

Definition at line 201 of file kis_curve_widget.cpp.

202{
203 if (e->key() == Qt::Key_Delete || e->key() == Qt::Key_Backspace) {
204 if (d->m_grab_point_index > 0 && d->m_grab_point_index < d->m_curve.curvePoints().count() - 1) {
205 //x() find closest point to get focus afterwards
206 double grab_point_x = d->m_curve.curvePoints()[d->m_grab_point_index].x();
207
208 int left_of_grab_point_index = d->m_grab_point_index - 1;
209 int right_of_grab_point_index = d->m_grab_point_index + 1;
210 int new_grab_point_index;
211
212 if (fabs(d->m_curve.curvePoints()[left_of_grab_point_index].x() - grab_point_x) <
213 fabs(d->m_curve.curvePoints()[right_of_grab_point_index].x() - grab_point_x)) {
214 new_grab_point_index = left_of_grab_point_index;
215 } else {
216 new_grab_point_index = d->m_grab_point_index;
217 }
218 d->m_curve.removePoint(d->m_grab_point_index);
219 d->m_grab_point_index = new_grab_point_index;
220 Q_EMIT pointSelectedChanged();
221 setCursor(Qt::ArrowCursor);
222 d->setState(ST_NORMAL);
223 }
224 e->accept();
225 d->setCurveModified();
226 } else if (e->key() == Qt::Key_Escape && d->state() != ST_NORMAL) {
227 d->m_curve.setPointPosition(d->m_grab_point_index, QPointF(d->m_grabOriginalX, d->m_grabOriginalY) );
228 setCursor(Qt::ArrowCursor);
229 d->setState(ST_NORMAL);
230
231 e->accept();
232 d->setCurveModified();
233 } else if ((e->key() == Qt::Key_A || e->key() == Qt::Key_Insert) && d->state() == ST_NORMAL) {
234 /* FIXME: Lets user choose the hotkeys */
236 e->accept();
237 } else if (e->key() == Qt::Key_S &&
238 d->m_globalPointConstrain == PointConstrain_None &&
239 pointSelected() &&
240 d->state() == ST_NORMAL) {
241 /* FIXME: Lets user choose the hotkeys */
243 e->accept();
244 } else
245 QWidget::keyPressEvent(e);
246}
std::optional< bool > isCurrentPointSetAsCorner() const
bool setCurrentPointAsCorner(bool setAsCorner)
@ ST_NORMAL

References addPointInTheMiddle(), d, isCurrentPointSetAsCorner(), PointConstrain_None, pointSelected, pointSelectedChanged(), setCurrentPointAsCorner(), and ST_NORMAL.

◆ leaveEvent()

void KisCurveWidget::leaveEvent ( QEvent * )
overrideprotected

Definition at line 536 of file kis_curve_widget.cpp.

537{
538}

◆ modified

void KisCurveWidget::modified ( void )
signal

Emitted whenever a control point has changed position.

◆ mouseMoveEvent()

void KisCurveWidget::mouseMoveEvent ( QMouseEvent * e)
overrideprotected

Definition at line 447 of file kis_curve_widget.cpp.

448{
449 if (d->m_readOnlyMode) return;
450
451 double x = e->pos().x() / (double)(width() - 1);
452 double y = 1.0 - e->pos().y() / (double)(height() - 1);
453
454 if (d->state() == ST_NORMAL) { // If no point is selected set the cursor shape if on top
455 int nearestPointIndex = d->nearestPointInRange(QPointF(x, y), width(), height());
456
457 if (nearestPointIndex < 0)
458 setCursor(Qt::ArrowCursor);
459 else
460 setCursor(Qt::CrossCursor);
461 } else { // Else, drag the selected point
462 bool crossedHoriz = e->pos().x() - width() > MOUSE_AWAY_THRES ||
463 e->pos().x() < -MOUSE_AWAY_THRES;
464 bool crossedVert = e->pos().y() - height() > MOUSE_AWAY_THRES ||
465 e->pos().y() < -MOUSE_AWAY_THRES;
466
467 bool removePoint = (crossedHoriz || crossedVert);
468
469 if (!removePoint && d->m_draggedAwayPointIndex >= 0) {
470 // point is no longer dragged away so reinsert it
471 KisCubicCurvePoint newPoint(d->m_draggedAwayPoint);
472 d->m_grab_point_index = d->m_curve.addPoint(newPoint);
473 d->m_draggedAwayPointIndex = -1;
474 }
475
476 if (removePoint &&
477 (d->m_draggedAwayPointIndex >= 0))
478 return;
479
480
481 setCursor(Qt::CrossCursor);
482
483 x += d->m_grabOffsetX;
484 y += d->m_grabOffsetY;
485
486 double leftX;
487 double rightX;
488 if (d->m_grab_point_index == 0) {
489 leftX = 0.0;
490 if (d->m_curve.curvePoints().count() > 1)
491 rightX = d->m_curve.curvePoints()[d->m_grab_point_index + 1].x() - POINT_AREA;
492 else
493 rightX = 1.0;
494 } else if (d->m_grab_point_index == d->m_curve.curvePoints().count() - 1) {
495 leftX = d->m_curve.curvePoints()[d->m_grab_point_index - 1].x() + POINT_AREA;
496 rightX = 1.0;
497 } else {
498 Q_ASSERT(d->m_grab_point_index > 0 && d->m_grab_point_index < d->m_curve.curvePoints().count() - 1);
499
500 // the 1E-4 addition so we can grab the dot later.
501 leftX = d->m_curve.curvePoints()[d->m_grab_point_index - 1].x() + POINT_AREA;
502 rightX = d->m_curve.curvePoints()[d->m_grab_point_index + 1].x() - POINT_AREA;
503 }
504
505 x = bounds(x, leftX, rightX);
506 y = bounds(y, 0., 1.);
507
508 d->m_curve.setPointPosition(d->m_grab_point_index, QPointF(x, y));
509
510 if (removePoint && d->m_curve.curvePoints().count() > 2) {
511 d->m_draggedAwayPoint = d->m_curve.curvePoints()[d->m_grab_point_index];
512 d->m_draggedAwayPointIndex = d->m_grab_point_index;
513 d->m_curve.removePoint(d->m_grab_point_index);
514 d->m_grab_point_index = bounds(d->m_grab_point_index, 0, d->m_curve.curvePoints().count() - 1);
515 Q_EMIT pointSelectedChanged();
516 }
517
518 d->setCurveModified();
519 }
520}
#define MOUSE_AWAY_THRES
#define POINT_AREA
#define bounds(x, a, b)

References bounds, d, MOUSE_AWAY_THRES, POINT_AREA, pointSelectedChanged(), and ST_NORMAL.

◆ mousePressEvent()

void KisCurveWidget::mousePressEvent ( QMouseEvent * e)
overrideprotected

Definition at line 388 of file kis_curve_widget.cpp.

389{
390 if (d->m_readOnlyMode) return;
391
392 if (e->button() != Qt::LeftButton)
393 return;
394
395 double x = e->pos().x() / (double)(width() - 1);
396 double y = 1.0 - e->pos().y() / (double)(height() - 1);
397
398
399
400 int closest_point_index = d->nearestPointInRange(QPointF(x, y), width(), height());
401 if (closest_point_index < 0) {
402 QPointF newPoint(x, y);
403 if (!d->jumpOverExistingPoints(newPoint, -1))
404 return;
405
406 const bool setAsCorner = d->m_globalPointConstrain == PointConstrain_AlwaysCorner;
407 d->m_grab_point_index = d->m_curve.addPoint(newPoint, setAsCorner);
408 Q_EMIT pointSelectedChanged();
409 } else {
410 d->m_grab_point_index = closest_point_index;
411 Q_EMIT pointSelectedChanged();
412 }
413
414 const KisCubicCurvePoint &currentPoint = d->m_curve.curvePoints()[d->m_grab_point_index];
415
416 d->m_grabOriginalX = currentPoint.x();
417 d->m_grabOriginalY = currentPoint.y();
418 d->m_grabOffsetX = currentPoint.x() - x;
419 d->m_grabOffsetY = currentPoint.y() - y;
420 if (e->modifiers().testFlag(Qt::ControlModifier) && d->m_globalPointConstrain == PointConstrain_None) {
421 d->m_curve.setPointAsCorner(d->m_grab_point_index, !currentPoint.isSetAsCorner());
422 }
423 d->m_curve.setPointPosition(d->m_grab_point_index, QPointF(x + d->m_grabOffsetX, y + d->m_grabOffsetY));
424
425 d->m_draggedAwayPointIndex = -1;
426 d->setState(ST_DRAG);
427
428
429 d->setCurveModified();
430}
std::optional< KisCubicCurvePoint > currentPoint() const
@ ST_DRAG

References currentPoint(), d, PointConstrain_AlwaysCorner, PointConstrain_None, pointSelectedChanged(), and ST_DRAG.

◆ mouseReleaseEvent()

void KisCurveWidget::mouseReleaseEvent ( QMouseEvent * e)
overrideprotected

Definition at line 433 of file kis_curve_widget.cpp.

434{
435 if (d->m_readOnlyMode) return;
436
437 if (e->button() != Qt::LeftButton)
438 return;
439
440 setCursor(Qt::ArrowCursor);
441 d->setState(ST_NORMAL);
442
443 d->setCurveModified();
444}

References d, and ST_NORMAL.

◆ nearestPointInRange()

int KisCurveWidget::nearestPointInRange ( QPointF pt,
int wWidth,
int wHeight ) const

Find the nearest point to pt from m_points

◆ notifyModified

void KisCurveWidget::notifyModified ( )
protectedslot

Definition at line 540 of file kis_curve_widget.cpp.

541{
542 Q_EMIT modified();
543 Q_EMIT curveChanged(d->m_curve);
544}
void modified(void)
void curveChanged(const KisCubicCurve &)

References curveChanged(), d, and modified().

◆ paintEvent()

void KisCurveWidget::paintEvent ( QPaintEvent * )
overrideprotected

Keep in mind that QLineF rounds doubles to ints mathematically, not just rounds down like in C

Definition at line 270 of file kis_curve_widget.cpp.

271{
272 int wWidth = width() - 1;
273 int wHeight = height() - 1;
274
275
276 QPainter p(this);
277
278 // Antialiasing is not a good idea here, because
279 // the grid will drift one pixel to any side due to rounding of int
280 // FIXME: let's user tell the last word (in config)
281 //p.setRenderHint(QPainter::Antialiasing);
282 QPalette appPalette = QApplication::palette();
283 p.fillRect(rect(), appPalette.color(QPalette::Base)); // clear out previous paint call results
284
285 // make the entire widget grayed out if it is disabled
286 if (!this->isEnabled()) {
287 p.setOpacity(0.2);
288 }
289
290
291
292 // draw background
293 if (!d->m_pix.isNull()) {
294 if (d->m_pixmapDirty || !d->m_pixmapCache) {
295 delete d->m_pixmapCache;
296 d->m_pixmapCache = new QPixmap(width(), height());
297 QPainter cachePainter(d->m_pixmapCache);
298
299 cachePainter.scale(1.0*width() / d->m_pix.width(), 1.0*height() / d->m_pix.height());
300 cachePainter.drawPixmap(0, 0, d->m_pix);
301 d->m_pixmapDirty = false;
302 }
303 p.drawPixmap(0, 0, *d->m_pixmapCache);
304 }
305
306 d->drawGrid(p, wWidth, wHeight);
307
308 KisConfig cfg(true);
309 if (cfg.antialiasCurves()) {
310 p.setRenderHint(QPainter::Antialiasing);
311 }
312
313 // Draw curve.
314 double curY;
315 double normalizedX;
316 int x;
317
318 QPolygonF poly;
319
320 p.setPen(QPen(appPalette.color(QPalette::Text), 2, Qt::SolidLine));
321 for (x = 0 ; x < wWidth ; x++) {
322 normalizedX = double(x) / wWidth;
323 curY = wHeight - d->m_curve.value(normalizedX) * wHeight;
324
330 poly.append(QPointF(x, curY));
331 }
332 poly.append(QPointF(x, wHeight - d->m_curve.value(1.0) * wHeight));
333 p.drawPolyline(poly);
334
335 QPainterPath fillCurvePath;
336 QPolygonF fillPoly = poly;
337 fillPoly.append(QPoint(rect().width(), rect().height()));
338 fillPoly.append(QPointF(0,rect().height()));
339
340 // add a couple points to the edges so it fills in below always
341
342 QColor fillColor = appPalette.color(QPalette::Text);
343 fillColor.setAlphaF(0.2);
344
345 fillCurvePath.addPolygon(fillPoly);
346 p.fillPath(fillCurvePath, fillColor);
347
348
349
350 // Drawing curve handles.
351 if (!d->m_readOnlyMode) {
352 const qreal halfHandleSize = d->m_handleSize * 0.5;
353
354 for (int i = 0; i < d->m_curve.curvePoints().count(); ++i) {
355 const KisCubicCurvePoint &point = d->m_curve.points().at(i);
356
357 if (i == d->m_grab_point_index) {
358 // active point is slightly more "bold"
359 p.setPen(QPen(appPalette.color(QPalette::Text), 4, Qt::SolidLine));
360 } else {
361 p.setPen(QPen(appPalette.color(QPalette::Text), 2, Qt::SolidLine));
362 }
363
364 const QPointF handleCenter(point.x() * wWidth, wHeight - point.y() * wHeight);
365
366 if (point.isSetAsCorner()) {
367 QPolygonF rhombusHandle;
368 rhombusHandle.append(QPointF(handleCenter.x() - halfHandleSize, handleCenter.y()));
369 rhombusHandle.append(QPointF(handleCenter.x(), handleCenter.y() - halfHandleSize));
370 rhombusHandle.append(QPointF(handleCenter.x() + halfHandleSize, handleCenter.y()));
371 rhombusHandle.append(QPointF(handleCenter.x(), handleCenter.y() + halfHandleSize));
372 p.drawPolygon(rhombusHandle);
373 } else {
374 p.drawEllipse(handleCenter, halfHandleSize, halfHandleSize);
375 }
376 }
377 }
378
379 // add border around widget to help contain everything
380 QPainterPath widgetBoundsPath;
381 widgetBoundsPath.addRect(rect());
382 p.strokePath(widgetBoundsPath, appPalette.color(QPalette::Text));
383
384
385 p.setOpacity(1.0); // reset to 1.0 in case we were drawing a disabled widget before
386}
const Params2D p
bool isSetAsCorner() const

References KisConfig::antialiasCurves(), d, KisCubicCurvePoint::isSetAsCorner(), p, KisCubicCurvePoint::x(), and KisCubicCurvePoint::y().

◆ pointSelected()

bool KisCurveWidget::pointSelected ( ) const

Whether or not there is a point selected This does NOT include the first and last points

Definition at line 196 of file kis_curve_widget.cpp.

197{
198 return d->m_grab_point_index > 0 && d->m_grab_point_index < d->m_curve.curvePoints().count();
199}

References d.

◆ pointSelectedChanged

void KisCurveWidget::pointSelectedChanged ( )
signal

Emitted whenever the status of whether a control point is selected or not changes

◆ Private()

KisCurveWidget::Private ( KisCurveWidget * parent)

◆ reset()

void KisCurveWidget::reset ( void )

Reset the curve to the default shape

Definition at line 171 of file kis_curve_widget.cpp.

172{
173 d->m_grab_point_index = -1;
174 Q_EMIT pointSelectedChanged();
175
176 //remove total - 2 points.
177 while (d->m_curve.curvePoints().count() - 2 ) {
178 d->m_curve.removePoint(d->m_curve.curvePoints().count() - 2);
179 }
180
181 d->setCurveModified();
182}

References d, and pointSelectedChanged().

◆ resizeEvent()

void KisCurveWidget::resizeEvent ( QResizeEvent * e)
overrideprotected

Definition at line 264 of file kis_curve_widget.cpp.

265{
266 d->m_pixmapDirty = true;
267 QWidget::resizeEvent(e);
268}

References d.

◆ setCurrentPoint()

bool KisCurveWidget::setCurrentPoint ( const QPointF & position,
bool setAsCorner )

Definition at line 80 of file kis_curve_widget.cpp.

81{
82 Q_ASSERT(d->m_grab_point_index >= 0);
83
84 bool needResyncControls = true;
85 bool isCorner;
86
87 if (d->m_globalPointConstrain == PointConstrain_None) {
88 d->m_curve.setPointAsCorner(d->m_grab_point_index, setAsCorner);
89 isCorner = setAsCorner;
90 } else {
91 isCorner = d->m_globalPointConstrain == PointConstrain_AlwaysCorner;
92 }
93
94 QPointF newPosition(position);
95
96 if (d->jumpOverExistingPoints(newPosition, d->m_grab_point_index)) {
97 needResyncControls = false;
98 d->m_curve.setPointPosition(d->m_grab_point_index, newPosition);
99 d->m_grab_point_index = d->m_curve.curvePoints().indexOf(
100 KisCubicCurvePoint(newPosition, isCorner)
101 );
102 Q_EMIT pointSelectedChanged();
103 }
104
105 d->setCurveModified(false);
106 return needResyncControls;
107}

References d, PointConstrain_AlwaysCorner, PointConstrain_None, and pointSelectedChanged().

◆ setCurrentPointAsCorner()

bool KisCurveWidget::setCurrentPointAsCorner ( bool setAsCorner)

Definition at line 116 of file kis_curve_widget.cpp.

117{
118 Q_ASSERT(d->m_grab_point_index >= 0);
119
120 // Setting the point corner flag is not allowed if there is some global constrain set
121 if (d->m_globalPointConstrain != PointConstrain_None) {
122 return false;
123 }
124
125 if (setAsCorner != d->m_curve.curvePoints()[d->m_grab_point_index].isSetAsCorner()) {
126 d->m_curve.setPointAsCorner(d->m_grab_point_index, setAsCorner);
127 d->setCurveModified(false);
128 }
129
130 return false;
131}

References d, and PointConstrain_None.

◆ setCurrentPointPosition()

bool KisCurveWidget::setCurrentPointPosition ( const QPointF & position)

Definition at line 109 of file kis_curve_widget.cpp.

110{
111 Q_ASSERT(d->m_grab_point_index >= 0);
112
113 return setCurrentPoint(position, d->m_curve.curvePoints()[d->m_grab_point_index].isSetAsCorner());
114}
bool setCurrentPoint(const QPointF &position, bool setAsCorner)

References d, and setCurrentPoint().

◆ setCurve

void KisCurveWidget::setCurve ( KisCubicCurve inlist)
slot

Replace the current curve with a curve specified by the curve defined by the control points in inlist.

Definition at line 527 of file kis_curve_widget.cpp.

528{
529 d->m_curve = inlist;
530 d->m_grab_point_index = qBound(0, d->m_grab_point_index, d->m_curve.curvePoints().count() - 1);
531 d->applyGlobalPointConstrain();
532 d->setCurveModified();
533 Q_EMIT pointSelectedChanged();
534}

References d, and pointSelectedChanged().

◆ setCurveModified()

void KisCurveWidget::setCurveModified ( bool rewriteSpinBoxesValues = true)

Common update routines

◆ setCurveRepaint()

void KisCurveWidget::setCurveRepaint ( )

◆ setGlobalPointConstrain()

void KisCurveWidget::setGlobalPointConstrain ( PointConstrain constrain)

Definition at line 133 of file kis_curve_widget.cpp.

134{
135 if (d->m_globalPointConstrain == constrain) {
136 return;
137 }
138
139 d->m_globalPointConstrain = constrain;
140 d->applyGlobalPointConstrain();
141
142 d->setCurveModified(false);
143}

References d.

◆ setPixmap()

void KisCurveWidget::setPixmap ( const QPixmap & pix)

Set a background pixmap. The background pixmap will be drawn under the grid and the curve.

XXX: or is the pixmap what is drawn to the left and bottom of the curve itself?

Definition at line 184 of file kis_curve_widget.cpp.

185{
186 d->m_pix = pix;
187 d->m_pixmapDirty = true;
188 d->setCurveRepaint();
189}

References d.

◆ setState()

void KisCurveWidget::setState ( enumState st)
inline

◆ setupInOutControls()

void KisCurveWidget::setupInOutControls ( QSpinBox * in,
QSpinBox * out,
int inMin,
int inMax,
int outMin,
int outMax )

Connect/disconnect external spinboxes to the curve inMin / inMax - is the range for input values outMin / outMax - is the range for output values

◆ shouldFocusIOControls

void KisCurveWidget::shouldFocusIOControls ( )
signal

◆ shouldSyncIOControls

void KisCurveWidget::shouldSyncIOControls ( )
signal

◆ slotCompressorShouldEmitModified

void KisCurveWidget::slotCompressorShouldEmitModified ( )
protectedslot

This function is called when compressorShouldEmitModified() is emitted. For why it's needed,

See also
compressorShouldEmitModified()

Definition at line 546 of file kis_curve_widget.cpp.

547{
548 d->m_modifiedSignalsCompressor.start();
549}

References d.

◆ state()

enumState KisCurveWidget::state ( ) const
inline

◆ syncIOControls()

void KisCurveWidget::syncIOControls ( )

Synchronize In/Out spinboxes with the curve

Friends And Related Symbol Documentation

◆ CurveEditorItem

friend class CurveEditorItem
friend

Definition at line 46 of file kis_curve_widget.h.

Member Data Documentation

◆ d

Private* const KisCurveWidget::d {nullptr}
private

Definition at line 175 of file kis_curve_widget.h.

175{nullptr};

◆ m_curve

KisCubicCurve KisCurveWidget::m_curve

Definition at line 42 of file kis_curve_widget_p.h.

◆ m_curveWidget

KisCurveWidget* KisCurveWidget::m_curveWidget {nullptr}
private

Definition at line 24 of file kis_curve_widget_p.h.

24{nullptr};

◆ m_draggedAwayPoint

KisCubicCurvePoint KisCurveWidget::m_draggedAwayPoint

Definition at line 35 of file kis_curve_widget_p.h.

◆ m_draggedAwayPointIndex

int KisCurveWidget::m_draggedAwayPointIndex {0}

Definition at line 36 of file kis_curve_widget_p.h.

36{0};

◆ m_globalPointConstrain

◆ m_grab_point_index

int KisCurveWidget::m_grab_point_index {-1}

Definition at line 30 of file kis_curve_widget_p.h.

30{-1};

◆ m_grabOffsetX

double KisCurveWidget::m_grabOffsetX {0.0}

Definition at line 31 of file kis_curve_widget_p.h.

31{0.0};

◆ m_grabOffsetY

double KisCurveWidget::m_grabOffsetY {0.0}

Definition at line 32 of file kis_curve_widget_p.h.

32{0.0};

◆ m_grabOriginalX

double KisCurveWidget::m_grabOriginalX {0.0}

Definition at line 33 of file kis_curve_widget_p.h.

33{0.0};

◆ m_grabOriginalY

double KisCurveWidget::m_grabOriginalY {0.0}

Definition at line 34 of file kis_curve_widget_p.h.

34{0.0};

◆ m_handleSize

int KisCurveWidget::m_handleSize {12}

Definition at line 50 of file kis_curve_widget_p.h.

50{12}; // size of the control points (diameter, in logical pixels) - both for painting and for detecting clicks

◆ m_modifiedSignalsCompressor

KisThreadSafeSignalCompressor KisCurveWidget::m_modifiedSignalsCompressor

Compresses the modified() signals

Definition at line 64 of file kis_curve_widget_p.h.

◆ m_pix

QPixmap KisCurveWidget::m_pix

Definition at line 45 of file kis_curve_widget_p.h.

◆ m_pixmapCache

QPixmap* KisCurveWidget::m_pixmapCache {nullptr}

Definition at line 47 of file kis_curve_widget_p.h.

47{nullptr};

◆ m_pixmapDirty

bool KisCurveWidget::m_pixmapDirty {true}

Definition at line 46 of file kis_curve_widget_p.h.

46{true};

◆ m_readOnlyMode

bool KisCurveWidget::m_readOnlyMode {false}

Definition at line 38 of file kis_curve_widget_p.h.

38{false};

◆ m_splineDirty

bool KisCurveWidget::m_splineDirty {false}

Definition at line 41 of file kis_curve_widget_p.h.

41{false};

◆ m_state

enumState KisCurveWidget::m_state {enumState::ST_NORMAL}

State functions. At the moment used only for dragging.

Definition at line 56 of file kis_curve_widget_p.h.

Property Documentation

◆ pointSelected

bool KisCurveWidget::pointSelected
read

Definition at line 43 of file kis_curve_widget.h.


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