79 Q_ASSERT(
d->m_grab_point_index >= 0);
81 bool needResyncControls =
true;
85 d->m_curve.setPointAsCorner(
d->m_grab_point_index, setAsCorner);
86 isCorner = setAsCorner;
91 QPointF newPosition(position);
93 if (
d->jumpOverExistingPoints(newPosition,
d->m_grab_point_index)) {
94 needResyncControls =
false;
95 d->m_curve.setPointPosition(
d->m_grab_point_index, newPosition);
96 d->m_grab_point_index =
d->m_curve.curvePoints().indexOf(
102 d->setCurveModified(
false);
103 return needResyncControls;
200 if (e->key() == Qt::Key_Delete || e->key() == Qt::Key_Backspace) {
201 if (
d->m_grab_point_index > 0 &&
d->m_grab_point_index <
d->m_curve.curvePoints().count() - 1) {
203 double grab_point_x =
d->m_curve.curvePoints()[
d->m_grab_point_index].x();
205 int left_of_grab_point_index =
d->m_grab_point_index - 1;
206 int right_of_grab_point_index =
d->m_grab_point_index + 1;
207 int new_grab_point_index;
209 if (fabs(
d->m_curve.curvePoints()[left_of_grab_point_index].x() - grab_point_x) <
210 fabs(
d->m_curve.curvePoints()[right_of_grab_point_index].x() - grab_point_x)) {
211 new_grab_point_index = left_of_grab_point_index;
213 new_grab_point_index =
d->m_grab_point_index;
215 d->m_curve.removePoint(
d->m_grab_point_index);
216 d->m_grab_point_index = new_grab_point_index;
218 setCursor(Qt::ArrowCursor);
222 d->setCurveModified();
223 }
else if (e->key() == Qt::Key_Escape &&
d->state() !=
ST_NORMAL) {
224 d->m_curve.setPointPosition(
d->m_grab_point_index, QPointF(
d->m_grabOriginalX,
d->m_grabOriginalY) );
225 setCursor(Qt::ArrowCursor);
229 d->setCurveModified();
230 }
else if ((e->key() == Qt::Key_A || e->key() == Qt::Key_Insert) &&
d->state() ==
ST_NORMAL) {
234 }
else if (e->key() == Qt::Key_S &&
242 QWidget::keyPressEvent(e);
269 int wWidth = width() - 1;
270 int wHeight = height() - 1;
279 QPalette appPalette = QApplication::palette();
280 p.fillRect(
rect(), appPalette.color(QPalette::Base));
283 if (!this->isEnabled()) {
290 if (!
d->m_pix.isNull()) {
291 if (
d->m_pixmapDirty || !
d->m_pixmapCache) {
292 delete d->m_pixmapCache;
293 d->m_pixmapCache =
new QPixmap(width(), height());
294 QPainter cachePainter(
d->m_pixmapCache);
296 cachePainter.scale(1.0*width() /
d->m_pix.width(), 1.0*height() /
d->m_pix.height());
297 cachePainter.drawPixmap(0, 0,
d->m_pix);
298 d->m_pixmapDirty =
false;
300 p.drawPixmap(0, 0, *
d->m_pixmapCache);
303 d->drawGrid(
p, wWidth, wHeight);
307 p.setRenderHint(QPainter::Antialiasing);
317 p.setPen(QPen(appPalette.color(QPalette::Text), 2, Qt::SolidLine));
318 for (x = 0 ; x < wWidth ; x++) {
319 normalizedX = double(x) / wWidth;
320 curY = wHeight -
d->m_curve.value(normalizedX) * wHeight;
327 poly.append(QPointF(x, curY));
329 poly.append(QPointF(x, wHeight -
d->m_curve.value(1.0) * wHeight));
330 p.drawPolyline(poly);
332 QPainterPath fillCurvePath;
333 QPolygonF fillPoly = poly;
334 fillPoly.append(QPoint(
rect().width(),
rect().height()));
335 fillPoly.append(QPointF(0,
rect().height()));
339 QColor fillColor = appPalette.color(QPalette::Text);
340 fillColor.setAlphaF(0.2);
342 fillCurvePath.addPolygon(fillPoly);
343 p.fillPath(fillCurvePath, fillColor);
348 if (!
d->m_readOnlyMode) {
349 const qreal halfHandleSize =
d->m_handleSize * 0.5;
351 for (
int i = 0; i <
d->m_curve.curvePoints().count(); ++i) {
354 if (i ==
d->m_grab_point_index) {
356 p.setPen(QPen(appPalette.color(QPalette::Text), 4, Qt::SolidLine));
358 p.setPen(QPen(appPalette.color(QPalette::Text), 2, Qt::SolidLine));
361 const QPointF handleCenter(point.
x() * wWidth, wHeight - point.
y() * wHeight);
364 QPolygonF rhombusHandle;
365 rhombusHandle.append(QPointF(handleCenter.x() - halfHandleSize, handleCenter.y()));
366 rhombusHandle.append(QPointF(handleCenter.x(), handleCenter.y() - halfHandleSize));
367 rhombusHandle.append(QPointF(handleCenter.x() + halfHandleSize, handleCenter.y()));
368 rhombusHandle.append(QPointF(handleCenter.x(), handleCenter.y() + halfHandleSize));
369 p.drawPolygon(rhombusHandle);
371 p.drawEllipse(handleCenter, halfHandleSize, halfHandleSize);
377 QPainterPath widgetBoundsPath;
378 widgetBoundsPath.addRect(
rect());
379 p.strokePath(widgetBoundsPath, appPalette.color(QPalette::Text));
387 if (
d->m_readOnlyMode)
return;
389 if (e->button() != Qt::LeftButton)
392 double x = e->pos().x() / (double)(width() - 1);
393 double y = 1.0 - e->pos().y() / (double)(height() - 1);
397 int closest_point_index =
d->nearestPointInRange(QPointF(x, y), width(), height());
398 if (closest_point_index < 0) {
399 QPointF newPoint(x, y);
400 if (!
d->jumpOverExistingPoints(newPoint, -1))
404 d->m_grab_point_index =
d->m_curve.addPoint(newPoint, setAsCorner);
407 d->m_grab_point_index = closest_point_index;
417 if (e->modifiers().testFlag(Qt::ControlModifier) &&
d->m_globalPointConstrain ==
PointConstrain_None) {
418 d->m_curve.setPointAsCorner(
d->m_grab_point_index, !
currentPoint.isSetAsCorner());
420 d->m_curve.setPointPosition(
d->m_grab_point_index, QPointF(x +
d->m_grabOffsetX, y +
d->m_grabOffsetY));
422 d->m_draggedAwayPointIndex = -1;
426 d->setCurveModified();
446 if (
d->m_readOnlyMode)
return;
448 double x = e->pos().x() / (double)(width() - 1);
449 double y = 1.0 - e->pos().y() / (double)(height() - 1);
452 int nearestPointIndex =
d->nearestPointInRange(QPointF(x, y), width(), height());
454 if (nearestPointIndex < 0)
455 setCursor(Qt::ArrowCursor);
457 setCursor(Qt::CrossCursor);
464 bool removePoint = (crossedHoriz || crossedVert);
466 if (!removePoint &&
d->m_draggedAwayPointIndex >= 0) {
469 d->m_grab_point_index =
d->m_curve.addPoint(newPoint);
470 d->m_draggedAwayPointIndex = -1;
474 (
d->m_draggedAwayPointIndex >= 0))
478 setCursor(Qt::CrossCursor);
480 x +=
d->m_grabOffsetX;
481 y +=
d->m_grabOffsetY;
485 if (
d->m_grab_point_index == 0) {
487 if (
d->m_curve.curvePoints().count() > 1)
488 rightX =
d->m_curve.curvePoints()[
d->m_grab_point_index + 1].x() -
POINT_AREA;
491 }
else if (
d->m_grab_point_index ==
d->m_curve.curvePoints().count() - 1) {
492 leftX =
d->m_curve.curvePoints()[
d->m_grab_point_index - 1].x() +
POINT_AREA;
495 Q_ASSERT(
d->m_grab_point_index > 0 &&
d->m_grab_point_index <
d->m_curve.curvePoints().count() - 1);
498 leftX =
d->m_curve.curvePoints()[
d->m_grab_point_index - 1].x() +
POINT_AREA;
499 rightX =
d->m_curve.curvePoints()[
d->m_grab_point_index + 1].x() -
POINT_AREA;
502 x =
bounds(x, leftX, rightX);
505 d->m_curve.setPointPosition(
d->m_grab_point_index, QPointF(x, y));
507 if (removePoint &&
d->m_curve.curvePoints().count() > 2) {
508 d->m_draggedAwayPoint =
d->m_curve.curvePoints()[
d->m_grab_point_index];
509 d->m_draggedAwayPointIndex =
d->m_grab_point_index;
510 d->m_curve.removePoint(
d->m_grab_point_index);
511 d->m_grab_point_index =
bounds(
d->m_grab_point_index, 0,
d->m_curve.curvePoints().count() - 1);
515 d->setCurveModified();