kis_curve_widget.cpp 13.7 KB
Newer Older
Halla Rempt's avatar
Halla Rempt committed
1
/*
C. Boemann's avatar
C. Boemann committed
2
 *  Copyright (c) 2005 C. Boemann <cbo@boemann.dk>
3
 *  Copyright (c) 2009 Dmitry Kazakov <dimula73@gmail.com>
Casper Boemann's avatar
Casper Boemann committed
4
 *
Halla Rempt's avatar
Halla Rempt committed
5 6 7 8
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
Adrian Page's avatar
Adrian Page committed
9
 *
Halla Rempt's avatar
Halla Rempt committed
10 11 12 13
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
Adrian Page's avatar
Adrian Page committed
14
 *
Halla Rempt's avatar
Halla Rempt committed
15 16 17 18
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */
Adrian Page's avatar
Adrian Page committed
19

Halla Rempt's avatar
Halla Rempt committed
20

Casper Boemann's avatar
Casper Boemann committed
21 22 23 24 25 26 27
// C++ includes.

#include <cmath>
#include <cstdlib>

// Qt includes.

28 29
#include <QPixmap>
#include <QPainter>
30
#include <QPoint>
31 32 33
#include <QPen>
#include <QEvent>
#include <QRect>
34
#include <QFont>
35
#include <QFontMetrics>
Laurent Montel's avatar
qt3to4  
Laurent Montel committed
36 37 38
#include <QMouseEvent>
#include <QKeyEvent>
#include <QPaintEvent>
Adrian Page's avatar
Adrian Page committed
39
#include <QList>
Casper Boemann's avatar
Casper Boemann committed
40

41 42
#include <QSpinBox>

Casper Boemann's avatar
Casper Boemann committed
43 44
// KDE includes.

45
#include <kis_debug.h>
46
#include <kis_config.h>
Casper Boemann's avatar
Casper Boemann committed
47 48 49 50 51
#include <kcursor.h>
#include <klocale.h>

// Local includes.

52 53 54
#include "widgets/kis_curve_widget.h"


55 56 57 58 59
#define bounds(x,a,b) (x<a ? a : (x>b ? b :x))
#define MOUSE_AWAY_THRES 15
#define POINT_AREA       1E-4
#define CURVE_AREA       1E-4

60 61
#include "kis_curve_widget_p.h"

62

Halla Rempt's avatar
Halla Rempt committed
63
//static bool pointLessThan(const QPointF &a, const QPointF &b);
64 65


66
KisCurveWidget::KisCurveWidget(QWidget *parent, Qt::WFlags f)
Halla Rempt's avatar
Halla Rempt committed
67
        : QWidget(parent, f), d(new KisCurveWidget::Private(this))
68
{
69
    setObjectName("KisCurveWidget");
70 71 72
    d->m_grab_point_index = -1;
    d->m_readOnlyMode   = false;
    d->m_guideVisible   = false;
Halla Rempt's avatar
Halla Rempt committed
73 74
    d->m_pixmapDirty = true;
    d->m_pixmapCache = NULL;
75 76
    d->setState(ST_NORMAL);

Halla Rempt's avatar
Halla Rempt committed
77 78
    d->m_intIn = NULL;
    d->m_intOut = NULL;
Adrian Page's avatar
Adrian Page committed
79

80
    setMouseTracking(true);
Adrian Page's avatar
Adrian Page committed
81 82
    setAutoFillBackground(false);
    setAttribute(Qt::WA_OpaquePaintEvent);
83
    setMinimumSize(150, 50);
Halla Rempt's avatar
Halla Rempt committed
84
    setMaximumSize(250, 250);
85 86 87

    d->setCurveModified();

Laurent Montel's avatar
Laurent Montel committed
88
    setFocusPolicy(Qt::StrongFocus);
89 90
}

91
KisCurveWidget::~KisCurveWidget()
Casper Boemann's avatar
Casper Boemann committed
92
{
93
    delete d->m_pixmapCache;
94
    delete d;
Casper Boemann's avatar
Casper Boemann committed
95 96
}

97
void KisCurveWidget::setupInOutControls(QSpinBox *in, QSpinBox *out, int min, int max)
98
{
Halla Rempt's avatar
Halla Rempt committed
99 100
    d->m_intIn = in;
    d->m_intOut = out;
Halla Rempt's avatar
Halla Rempt committed
101

Halla Rempt's avatar
Halla Rempt committed
102
    if (!d->m_intIn || !d->m_intOut)
Halla Rempt's avatar
Halla Rempt committed
103
        return;
104

Halla Rempt's avatar
Halla Rempt committed
105 106
    d->m_inOutMin = min;
    d->m_inOutMax = max;
107 108 109

    d->m_intIn->setRange(d->m_inOutMin, d->m_inOutMax);
    d->m_intOut->setRange(d->m_inOutMin, d->m_inOutMax);
Halla Rempt's avatar
Halla Rempt committed
110

111 112 113 114

    connect(d->m_intIn, SIGNAL(valueChanged(int)), this, SLOT(inOutChanged(int)));
    connect(d->m_intOut, SIGNAL(valueChanged(int)), this, SLOT(inOutChanged(int)));
    d->syncIOControls();
Halla Rempt's avatar
Halla Rempt committed
115

116
}
117
void KisCurveWidget::dropInOutControls()
118
{
Halla Rempt's avatar
Halla Rempt committed
119
    if (!d->m_intIn || !d->m_intOut)
Halla Rempt's avatar
Halla Rempt committed
120
        return;
121 122 123 124

    disconnect(d->m_intIn, SIGNAL(valueChanged(int)), this, SLOT(inOutChanged(int)));
    disconnect(d->m_intOut, SIGNAL(valueChanged(int)), this, SLOT(inOutChanged(int)));

Halla Rempt's avatar
Halla Rempt committed
125
    d->m_intIn = d->m_intOut = NULL;
Halla Rempt's avatar
Halla Rempt committed
126

127 128
}

129
void KisCurveWidget::inOutChanged(int)
130 131 132
{
    QPointF pt;

Halla Rempt's avatar
Halla Rempt committed
133
    Q_ASSERT(d->m_grab_point_index >= 0);
134

135 136
    pt.setX(d->io2sp(d->m_intIn->value()));
    pt.setY(d->io2sp(d->m_intOut->value()));
Halla Rempt's avatar
Halla Rempt committed
137

Halla Rempt's avatar
Halla Rempt committed
138
    if (d->jumpOverExistingPoints(pt, d->m_grab_point_index)) {
139 140
        d->m_curve.setPoint(d->m_grab_point_index, pt);
        d->m_grab_point_index = d->m_curve.points().indexOf(pt);
141
        emit pointSelectedChanged();
Halla Rempt's avatar
Halla Rempt committed
142
    } else
143
        pt = d->m_curve.points()[d->m_grab_point_index];
Halla Rempt's avatar
Halla Rempt committed
144

145 146 147 148

    d->m_intIn->blockSignals(true);
    d->m_intOut->blockSignals(true);

149 150
    d->m_intIn->setValue(d->sp2io(pt.x()));
    d->m_intOut->setValue(d->sp2io(pt.y()));
151 152 153 154 155 156 157 158

    d->m_intIn->blockSignals(false);
    d->m_intOut->blockSignals(false);

    d->setCurveModified();
}


159
void KisCurveWidget::reset(void)
Casper Boemann's avatar
Casper Boemann committed
160
{
161
    d->m_grab_point_index = -1;
162
    emit pointSelectedChanged();
163
    d->m_guideVisible = false;
Halla Rempt's avatar
Halla Rempt committed
164

165
    d->setCurveModified();
Casper Boemann's avatar
Casper Boemann committed
166 167
}

168
void KisCurveWidget::setCurveGuide(const QColor & color)
Casper Boemann's avatar
Casper Boemann committed
169
{
170 171 172
    d->m_guideVisible = true;
    d->m_colorGuide   = color;

Casper Boemann's avatar
Casper Boemann committed
173 174
}

175
void KisCurveWidget::setPixmap(const QPixmap & pix)
Casper Boemann's avatar
Casper Boemann committed
176
{
177
    d->m_pix = pix;
Halla Rempt's avatar
Halla Rempt committed
178
    d->m_pixmapDirty = true;
179
    d->setCurveRepaint();
Casper Boemann's avatar
Casper Boemann committed
180 181
}

182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
QPixmap KisCurveWidget::getPixmap()
{
    return d->m_pix;
}

void KisCurveWidget::setBasePixmap(const QPixmap &pix)
{
    d->m_pixmapBase = pix;
}

QPixmap KisCurveWidget::getBasePixmap()
{
    return d->m_pixmapBase;
}

197 198 199 200 201
bool KisCurveWidget::pointSelected() const
{
    return d->m_grab_point_index > 0 && d->m_grab_point_index < d->m_curve.points().count() - 1;
}

202
void KisCurveWidget::keyPressEvent(QKeyEvent *e)
Casper Boemann's avatar
Casper Boemann committed
203
{
Halla Rempt's avatar
Halla Rempt committed
204
    if (e->key() == Qt::Key_Delete || e->key() == Qt::Key_Backspace) {
205
        if (d->m_grab_point_index > 0 && d->m_grab_point_index < d->m_curve.points().count() - 1) {
206 207
            //x() find closest point to get focus afterwards
            double grab_point_x = d->m_curve.points()[d->m_grab_point_index].x();
Adrian Page's avatar
Adrian Page committed
208

209 210
            int left_of_grab_point_index = d->m_grab_point_index - 1;
            int right_of_grab_point_index = d->m_grab_point_index + 1;
Adrian Page's avatar
Adrian Page committed
211 212
            int new_grab_point_index;

213 214
            if (fabs(d->m_curve.points()[left_of_grab_point_index].x() - grab_point_x) <
                    fabs(d->m_curve.points()[right_of_grab_point_index].x() - grab_point_x)) {
Adrian Page's avatar
Adrian Page committed
215
                new_grab_point_index = left_of_grab_point_index;
Halla Rempt's avatar
Halla Rempt committed
216
            } else {
217
                new_grab_point_index = d->m_grab_point_index;
Adrian Page's avatar
Adrian Page committed
218
            }
219
            d->m_curve.removePoint(d->m_grab_point_index);
220
            d->m_grab_point_index = new_grab_point_index;
221
            emit pointSelectedChanged();
Halla Rempt's avatar
Halla Rempt committed
222 223
            setCursor(Qt::ArrowCursor);
            d->setState(ST_NORMAL);
224
        }
225
        e->accept();
Halla Rempt's avatar
Halla Rempt committed
226
        d->setCurveModified();
Halla Rempt's avatar
Halla Rempt committed
227
    } else if (e->key() == Qt::Key_Escape && d->state() != ST_NORMAL) {
228
        d->m_curve.setPoint(d->m_grab_point_index, QPointF(d->m_grabOriginalX, d->m_grabOriginalY) );
Halla Rempt's avatar
Halla Rempt committed
229
        setCursor(Qt::ArrowCursor);
Halla Rempt's avatar
Halla Rempt committed
230
        d->setState(ST_NORMAL);
231

232
        e->accept();
Halla Rempt's avatar
Halla Rempt committed
233
        d->setCurveModified();
Halla Rempt's avatar
Halla Rempt committed
234
    } else if ((e->key() == Qt::Key_A || e->key() == Qt::Key_Insert) && d->state() == ST_NORMAL) {
Halla Rempt's avatar
Halla Rempt committed
235
        /* FIXME: Lets user choose the hotkeys */
236
        addPointInTheMiddle();
237
        e->accept();
Halla Rempt's avatar
Halla Rempt committed
238
    } else
Thomas Zander's avatar
Thomas Zander committed
239
        QWidget::keyPressEvent(e);
Casper Boemann's avatar
Casper Boemann committed
240 241
}

242
void KisCurveWidget::addPointInTheMiddle()
Casper Boemann's avatar
Casper Boemann committed
243
{
Adrian Page's avatar
Adrian Page committed
244
    QPointF pt(0.5, d->m_curve.value(0.5));
Halla Rempt's avatar
Halla Rempt committed
245

Halla Rempt's avatar
Halla Rempt committed
246
    if (!d->jumpOverExistingPoints(pt, -1))
Halla Rempt's avatar
Halla Rempt committed
247
        return;
248

249
    d->m_grab_point_index = d->m_curve.addPoint(pt);
250
    emit pointSelectedChanged();
Halla Rempt's avatar
Halla Rempt committed
251

Halla Rempt's avatar
Halla Rempt committed
252
    if (d->m_intIn)
Halla Rempt's avatar
Halla Rempt committed
253
        d->m_intIn->setFocus(Qt::TabFocusReason);
254 255
    d->setCurveModified();
}
Adrian Page's avatar
Adrian Page committed
256

257
void KisCurveWidget::resizeEvent(QResizeEvent *e)
258
{
Halla Rempt's avatar
Halla Rempt committed
259
    d->m_pixmapDirty = true;
260 261 262
    QWidget::resizeEvent(e);
}

263
void KisCurveWidget::paintEvent(QPaintEvent *)
264
{
Halla Rempt's avatar
Halla Rempt committed
265 266
    int    wWidth = width() - 1;
    int    wHeight = height() - 1;
Adrian Page's avatar
Adrian Page committed
267 268

    QPainter p(this);
269

Halla Rempt's avatar
Halla Rempt committed
270
    // Antialiasing is not a good idea here, because
271 272 273 274
    // the grid will drift one pixel to any side due to rounding of int
    // FIXME: let's user tell the last word (in config)
    //p.setRenderHint(QPainter::Antialiasing);

Scott Petrovic's avatar
Scott Petrovic committed
275 276
    // fill with color to show widget bounds
     p.fillRect(rect(), palette().base());
Adrian Page's avatar
Adrian Page committed
277

278
    //  draw background
279
    if (!d->m_pix.isNull()) {
Halla Rempt's avatar
Halla Rempt committed
280
        if (d->m_pixmapDirty || !d->m_pixmapCache) {
281
            delete d->m_pixmapCache;
Halla Rempt's avatar
Halla Rempt committed
282 283 284 285 286
            d->m_pixmapCache = new QPixmap(width(), height());
            QPainter cachePainter(d->m_pixmapCache);

            cachePainter.scale(1.0*width() / d->m_pix.width(), 1.0*height() / d->m_pix.height());
            cachePainter.drawPixmap(0, 0, d->m_pix);
Halla Rempt's avatar
Halla Rempt committed
287
            d->m_pixmapDirty = false;
Halla Rempt's avatar
Halla Rempt committed
288
        }
Halla Rempt's avatar
Halla Rempt committed
289
        p.drawPixmap(0, 0, *d->m_pixmapCache);
Scott Petrovic's avatar
Scott Petrovic committed
290
    }
Halla Rempt's avatar
Halla Rempt committed
291

292 293
    d->drawGrid(p, wWidth, wHeight);

294 295 296
    KisConfig cfg;
    if (cfg.antialiasCurves())
        p.setRenderHint(QPainter::Antialiasing);
297

298
    // Draw curve.
299 300 301 302
    double curY;
    double normalizedX;
    int x;

Halla Rempt's avatar
Halla Rempt committed
303 304
    QPolygonF poly;

305
    p.setPen(QPen(Qt::black, 1, Qt::SolidLine));
Halla Rempt's avatar
Halla Rempt committed
306
    for (x = 0 ; x < wWidth ; x++) {
307
        normalizedX = double(x) / wWidth;
308
        curY = wHeight - d->m_curve.value(normalizedX) * wHeight;
309

Halla Rempt's avatar
Halla Rempt committed
310 311
        /**
         * Keep in mind that QLineF rounds doubles
312
         * to ints mathematically, not just rounds down
Halla Rempt's avatar
Halla Rempt committed
313 314
         * like in C
         */
Halla Rempt's avatar
Halla Rempt committed
315
        poly.append(QPointF(x, curY));
316
    }
Halla Rempt's avatar
Halla Rempt committed
317 318
    poly.append(QPointF(x, wHeight - d->m_curve.value(1.0) * wHeight));
    p.drawPolyline(poly);
Adrian Page's avatar
Adrian Page committed
319

320
    // Drawing curve handles.
321 322 323
    double curveX;
    double curveY;
    if (!d->m_readOnlyMode) {
324 325 326
        for (int i = 0; i < d->m_curve.points().count(); ++i) {
            curveX = d->m_curve.points().at(i).x();
            curveY = d->m_curve.points().at(i).y();
327 328

            if (i == d->m_grab_point_index) {
329
                p.setPen(QPen(Qt::red, 3, Qt::SolidLine));
330 331
                p.drawEllipse(QRectF(curveX * wWidth - 2,
                                     wHeight - 2 - curveY * wHeight, 4, 4));
Halla Rempt's avatar
Halla Rempt committed
332
            } else {
333
                p.setPen(QPen(Qt::red, 1, Qt::SolidLine));
334 335
                p.drawEllipse(QRectF(curveX * wWidth - 3,
                                     wHeight - 3 - curveY * wHeight, 6, 6));
336 337 338
            }
        }
    }
Casper Boemann's avatar
Casper Boemann committed
339 340
}

341
void KisCurveWidget::mousePressEvent(QMouseEvent * e)
Adrian Page's avatar
Adrian Page committed
342
{
343
    if (d->m_readOnlyMode) return;
Adrian Page's avatar
Adrian Page committed
344 345 346 347

    if (e->button() != Qt::LeftButton)
        return;

Halla Rempt's avatar
Halla Rempt committed
348 349
    double x = e->pos().x() / (double)(width() - 1);
    double y = 1.0 - e->pos().y() / (double)(height() - 1);
350

Adrian Page's avatar
Adrian Page committed
351

Halla Rempt's avatar
Halla Rempt committed
352

353
    int closest_point_index = d->nearestPointInRange(QPointF(x, y), width(), height());
Halla Rempt's avatar
Halla Rempt committed
354
    if (closest_point_index < 0) {
Halla Rempt's avatar
Halla Rempt committed
355
        QPointF newPoint(x, y);
Halla Rempt's avatar
Halla Rempt committed
356 357
        if (!d->jumpOverExistingPoints(newPoint, -1))
            return;
358
        d->m_grab_point_index = d->m_curve.addPoint(newPoint);
359
        emit pointSelectedChanged();
Halla Rempt's avatar
Halla Rempt committed
360
    } else {
Halla Rempt's avatar
Halla Rempt committed
361
        d->m_grab_point_index = closest_point_index;
362
        emit pointSelectedChanged();
363
    }
Halla Rempt's avatar
Halla Rempt committed
364

365 366 367 368
    d->m_grabOriginalX = d->m_curve.points()[d->m_grab_point_index].x();
    d->m_grabOriginalY = d->m_curve.points()[d->m_grab_point_index].y();
    d->m_grabOffsetX = d->m_curve.points()[d->m_grab_point_index].x() - x;
    d->m_grabOffsetY = d->m_curve.points()[d->m_grab_point_index].y() - y;
369
    d->m_curve.setPoint(d->m_grab_point_index, QPointF(x + d->m_grabOffsetX, y + d->m_grabOffsetY));
Halla Rempt's avatar
Halla Rempt committed
370

371
    d->m_draggedAwayPointIndex = -1;
Halla Rempt's avatar
Halla Rempt committed
372 373
    d->setState(ST_DRAG);

374 375

    d->setCurveModified();
Casper Boemann's avatar
Casper Boemann committed
376 377
}

378

379
void KisCurveWidget::mouseReleaseEvent(QMouseEvent *e)
Casper Boemann's avatar
Casper Boemann committed
380
{
381
    if (d->m_readOnlyMode) return;
Adrian Page's avatar
Adrian Page committed
382

383 384
    if (e->button() != Qt::LeftButton)
        return;
Adrian Page's avatar
Adrian Page committed
385

Halla Rempt's avatar
Halla Rempt committed
386
    setCursor(Qt::ArrowCursor);
387
    d->setState(ST_NORMAL);
Halla Rempt's avatar
Halla Rempt committed
388

389
    d->setCurveModified();
Casper Boemann's avatar
Casper Boemann committed
390 391
}

392

393
void KisCurveWidget::mouseMoveEvent(QMouseEvent * e)
Casper Boemann's avatar
Casper Boemann committed
394
{
395
    if (d->m_readOnlyMode) return;
Adrian Page's avatar
Adrian Page committed
396

Halla Rempt's avatar
Halla Rempt committed
397 398
    double x = e->pos().x() / (double)(width() - 1);
    double y = 1.0 - e->pos().y() / (double)(height() - 1);
Adrian Page's avatar
Adrian Page committed
399

400
    if (d->state() == ST_NORMAL) { // If no point is selected set the cursor shape if on top
401
        int nearestPointIndex = d->nearestPointInRange(QPointF(x, y), width(), height());
Halla Rempt's avatar
Halla Rempt committed
402

Adrian Page's avatar
Adrian Page committed
403
        if (nearestPointIndex < 0)
Halla Rempt's avatar
Halla Rempt committed
404
            setCursor(Qt::ArrowCursor);
405
        else
Halla Rempt's avatar
Halla Rempt committed
406
            setCursor(Qt::CrossCursor);
Halla Rempt's avatar
Halla Rempt committed
407
    } else { // Else, drag the selected point
Halla Rempt's avatar
Halla Rempt committed
408 409 410 411 412
        bool crossedHoriz = e->pos().x() - width() > MOUSE_AWAY_THRES ||
                            e->pos().x() < -MOUSE_AWAY_THRES;
        bool crossedVert =  e->pos().y() - height() > MOUSE_AWAY_THRES ||
                            e->pos().y() < -MOUSE_AWAY_THRES;

Halla Rempt's avatar
Halla Rempt committed
413
        bool removePoint = (crossedHoriz || crossedVert);
414

Halla Rempt's avatar
Halla Rempt committed
415
        if (!removePoint && d->m_draggedAwayPointIndex >= 0) {
416
            // point is no longer dragged away so reinsert it
417
            QPointF newPoint(d->m_draggedAwayPoint);
418
            d->m_grab_point_index = d->m_curve.addPoint(newPoint);
419
            d->m_draggedAwayPointIndex = -1;
420 421
        }

Halla Rempt's avatar
Halla Rempt committed
422
        if (removePoint &&
Halla Rempt's avatar
Halla Rempt committed
423
                (d->m_draggedAwayPointIndex >= 0))
Halla Rempt's avatar
Halla Rempt committed
424
            return;
425

426

Halla Rempt's avatar
Halla Rempt committed
427
        setCursor(Qt::CrossCursor);
Adrian Page's avatar
Adrian Page committed
428

429 430
        x += d->m_grabOffsetX;
        y += d->m_grabOffsetY;
Adrian Page's avatar
Adrian Page committed
431

432 433
        double leftX;
        double rightX;
434
        if (d->m_grab_point_index == 0) {
435
            leftX = 0.0;
436
            if (d->m_curve.points().count() > 1)
437
                rightX = d->m_curve.points()[d->m_grab_point_index + 1].x() - POINT_AREA;
438 439
            else
                rightX = 1.0;
440
        } else if (d->m_grab_point_index == d->m_curve.points().count() - 1) {
441
            leftX = d->m_curve.points()[d->m_grab_point_index - 1].x() + POINT_AREA;
442
            rightX = 1.0;
Halla Rempt's avatar
Halla Rempt committed
443
        } else {
444
            Q_ASSERT(d->m_grab_point_index > 0 && d->m_grab_point_index < d->m_curve.points().count() - 1);
Adrian Page's avatar
Adrian Page committed
445

446
            // the 1E-4 addition so we can grab the dot later.
447 448
            leftX = d->m_curve.points()[d->m_grab_point_index - 1].x() + POINT_AREA;
            rightX = d->m_curve.points()[d->m_grab_point_index + 1].x() - POINT_AREA;
449
        }
Adrian Page's avatar
Adrian Page committed
450

Halla Rempt's avatar
Halla Rempt committed
451 452
        x = bounds(x, leftX, rightX);
        y = bounds(y, 0., 1.);
Adrian Page's avatar
Adrian Page committed
453

454
        d->m_curve.setPoint(d->m_grab_point_index, QPointF(x, y));
Adrian Page's avatar
Adrian Page committed
455

456
        if (removePoint && d->m_curve.points().count() > 2) {
457
            d->m_draggedAwayPoint = d->m_curve.points()[d->m_grab_point_index];
458
            d->m_draggedAwayPointIndex = d->m_grab_point_index;
459 460
            d->m_curve.removePoint(d->m_grab_point_index);
            d->m_grab_point_index = bounds(d->m_grab_point_index, 0, d->m_curve.points().count() - 1);
461
            emit pointSelectedChanged();
462 463
        }

Halla Rempt's avatar
Halla Rempt committed
464
        d->setCurveModified();
465
    }
466
}
Casper Boemann's avatar
Casper Boemann committed
467

468
KisCubicCurve KisCurveWidget::curve()
469
{
470
    return d->m_curve;
471 472
}

473
void KisCurveWidget::setCurve(KisCubicCurve inlist)
474
{
475 476
    d->m_curve = inlist;
    d->m_grab_point_index = qBound(0, d->m_grab_point_index, d->m_curve.points().count() - 1);
477
    emit pointSelectedChanged();
478
    d->setCurveModified();
479 480
}

481
void KisCurveWidget::leaveEvent(QEvent *)
Casper Boemann's avatar
Casper Boemann committed
482 483 484
{
}

485
#include "kis_curve_widget.moc"