From: <tt...@us...> - 2011-01-01 21:07:06
|
Revision: 5233 http://kdenlive.svn.sourceforge.net/kdenlive/?rev=5233&view=rev Author: ttill Date: 2011-01-01 21:06:59 +0000 (Sat, 01 Jan 2011) Log Message: ----------- B?\195?\169zier spline: - rename BezierSplineWidget to BezierSplineEditor - add BezierSplineWidget containing the editor and more controls (for now spinboxes for the values) Modified Paths: -------------- trunk/kdenlive/src/CMakeLists.txt trunk/kdenlive/src/beziercurve/cubicbezierspline.h trunk/kdenlive/src/effectstackedit.cpp Added Paths: ----------- trunk/kdenlive/src/beziercurve/beziersplineeditor.cpp trunk/kdenlive/src/beziercurve/beziersplineeditor.h trunk/kdenlive/src/beziercurve/beziersplinewidget.cpp trunk/kdenlive/src/beziercurve/beziersplinewidget.h trunk/kdenlive/src/widgets/bezierspline_ui.ui Removed Paths: ------------- trunk/kdenlive/src/beziercurve/beziersplinewidget.cpp trunk/kdenlive/src/beziercurve/beziersplinewidget.h Modified: trunk/kdenlive/src/CMakeLists.txt =================================================================== --- trunk/kdenlive/src/CMakeLists.txt 2011-01-01 13:31:06 UTC (rev 5232) +++ trunk/kdenlive/src/CMakeLists.txt 2011-01-01 21:06:59 UTC (rev 5233) @@ -123,6 +123,7 @@ widgets/audiospectrum_ui.ui widgets/spectrogram_ui.ui widgets/smconfig_ui.ui + widgets/bezierspline_ui.ui ) set(kdenlive_SRCS @@ -263,6 +264,7 @@ kiss_fft/kiss_fft.c kiss_fft/tools/kiss_fftr.c beziercurve/cubicbezierspline.cpp + beziercurve/beziersplineeditor.cpp beziercurve/beziersplinewidget.cpp ) Copied: trunk/kdenlive/src/beziercurve/beziersplineeditor.cpp (from rev 5231, trunk/kdenlive/src/beziercurve/beziersplinewidget.cpp) =================================================================== --- trunk/kdenlive/src/beziercurve/beziersplineeditor.cpp (rev 0) +++ trunk/kdenlive/src/beziercurve/beziersplineeditor.cpp 2011-01-01 21:06:59 UTC (rev 5233) @@ -0,0 +1,381 @@ +/*************************************************************************** + * Copyright (C) 2010 by Till Theato (ro...@tt...) * + * This file is part of Kdenlive (www.kdenlive.org). * + * * + * Kdenlive 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. * + * * + * Kdenlive 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. * + * * + * You should have received a copy of the GNU General Public License * + * along with Kdenlive. If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + +#include "beziersplineeditor.h" + +#include <QPainter> +#include <QMouseEvent> + +#include <KDebug> + +BezierSplineEditor::BezierSplineEditor(QWidget* parent) : + QWidget(parent), + m_mode(ModeNormal), + m_currentPointIndex(-1) +{ + setMouseTracking(true); + setAutoFillBackground(false); + setAttribute(Qt::WA_OpaquePaintEvent); + setMinimumSize(150, 150); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); +} + +CubicBezierSpline BezierSplineEditor::spline() +{ + return m_spline; +} + +void BezierSplineEditor::setSpline(const CubicBezierSpline& spline) +{ + // TODO: cleanup + m_spline.fromString(spline.toString()); +} + +BPoint BezierSplineEditor::getCurrentPoint() +{ + if (m_currentPointIndex >= 0) + return m_spline.points()[m_currentPointIndex]; + else + return BPoint(); +} + +void BezierSplineEditor::updateCurrentPoint(const BPoint& p) +{ + if (m_currentPointIndex >= 0) { + m_spline.setPoint(m_currentPointIndex, p); + // during validation the point might have changed + emit currentPoint(m_spline.points()[m_currentPointIndex]); + update(); + } +} + +void BezierSplineEditor::paintEvent(QPaintEvent* event) +{ + Q_UNUSED(event); + + QPainter p(this); + + p.fillRect(rect(), palette().background()); + + int wWidth = width() - 1; + int wHeight = height() - 1; + + /* + * Spline + */ + double prevY = wHeight - m_spline.value(0.) * wHeight; + double prevX = 0.; + double curY; + double normalizedX = -1; + int x; + + p.setPen(QPen(Qt::black, 1, Qt::SolidLine)); + for (x = 0 ; x < wWidth ; ++x) { + normalizedX = x / (double)wWidth; + curY = wHeight - m_spline.value(normalizedX, true) * wHeight; + + /* + * Keep in mind that QLineF rounds doubles + * to ints mathematically, not just rounds down + * like in C + */ + p.drawLine(QLineF(prevX, prevY, + x, curY)); + prevX = x; + prevY = curY; + } + p.drawLine(QLineF(prevX, prevY , + x, wHeight - m_spline.value(1.0, true) * wHeight)); + + /* + * Points + Handles + */ + p.setPen(QPen(Qt::red, 1, Qt::SolidLine)); + BPoint point; + QPolygon handle(4); + handle.setPoints(4, + 1, -2, + 4, 1, + 1, 4, + -2, 1); + for (int i = 0; i < m_spline.points().count(); ++i) { + point = m_spline.points().at(i); + if (i == m_currentPointIndex) + p.setBrush(QBrush(QColor(Qt::red), Qt::SolidPattern)); + + p.drawConvexPolygon(handle.translated(point.h1.x() * wWidth, wHeight - point.h1.y() * wHeight)); + p.drawEllipse(QRectF(point.p.x() * wWidth - 3, + wHeight - 3 - point.p.y() * wHeight, 6, 6)); + p.drawConvexPolygon(handle.translated(point.h2.x() * wWidth, wHeight - point.h2.y() * wHeight)); + + if ( i == m_currentPointIndex) + p.setBrush(QBrush(Qt::NoBrush)); + } +} + +void BezierSplineEditor::resizeEvent(QResizeEvent* event) +{ + m_spline.setPrecision(width()); + QWidget::resizeEvent(event); +} + +void BezierSplineEditor::mousePressEvent(QMouseEvent* event) +{ + double x = event->pos().x() / (double)(width() - 1); + double y = 1.0 - event->pos().y() / (double)(height() - 1); + + point_types selectedPoint; + int closestPointIndex = nearestPointInRange(QPointF(x, y), width(), height(), &selectedPoint); + + if (event->button() == Qt::RightButton && closestPointIndex > 0 && closestPointIndex < m_spline.points().count() - 1 && selectedPoint == PTypeP) { + m_spline.removePoint(closestPointIndex); + setCursor(Qt::ArrowCursor); + m_mode = ModeNormal; + if (closestPointIndex < m_currentPointIndex) + --m_currentPointIndex; + update(); + if (m_currentPointIndex >= 0) + emit currentPoint(m_spline.points()[m_currentPointIndex]); + else + emit currentPoint(BPoint()); + emit modified(); + return; + } else if (event->button() != Qt::LeftButton) { + return; + } + + if (closestPointIndex < 0) { + BPoint po; + po.p = QPointF(x, y); + po.h1 = QPointF(x-0.05, y-0.05); + po.h2 = QPointF(x+0.05, y+0.05); + m_currentPointIndex = m_spline.addPoint(po); + m_currentPointType = PTypeP; + /*if (!d->jumpOverExistingPoints(newPoint, -1)) return;*/ + } else { + m_currentPointIndex = closestPointIndex; + m_currentPointType = selectedPoint; + } + + BPoint point = m_spline.points()[m_currentPointIndex]; + QPointF p; + switch (m_currentPointType) { + case PTypeH1: + p = point.h1; + break; + case PTypeP: + p = point.p; + break; + case PTypeH2: + p = point.h2; + } + + m_grabOriginalX = p.x(); + m_grabOriginalY = p.y(); + m_grabOffsetX = p.x() - x; + m_grabOffsetY = p.y() - y; + + switch (m_currentPointType) { + case PTypeH1: + point.h1 = QPointF(x + m_grabOffsetX, y + m_grabOffsetY); + break; + case PTypeP: + point.p = QPointF(x + m_grabOffsetX, y + m_grabOffsetY); + break; + case PTypeH2: + point.h2 = QPointF(x + m_grabOffsetX, y + m_grabOffsetY); + } + m_spline.setPoint(m_currentPointIndex, point); + + //d->m_draggedAwayPointIndex = -1; + + m_mode = ModeDrag; + + emit currentPoint(point); + update(); +} + +void BezierSplineEditor::mouseReleaseEvent(QMouseEvent* event) +{ + if (event->button() != Qt::LeftButton) + return; + + setCursor(Qt::ArrowCursor); + m_mode = ModeNormal; + + emit modified(); +} + +void BezierSplineEditor::mouseMoveEvent(QMouseEvent* event) +{ + double x = event->pos().x() / (double)(width() - 1); + double y = 1.0 - event->pos().y() / (double)(height() - 1); + + if (m_mode == ModeNormal) { // If no point is selected set the the cursor shape if on top + point_types type; + int nearestPointIndex = nearestPointInRange(QPointF(x, y), width(), height(), &type); + + if (nearestPointIndex < 0) + setCursor(Qt::ArrowCursor); + else + setCursor(Qt::CrossCursor); + } else { // Else, drag the selected point + /*bool crossedHoriz = event->pos().x() - width() > MOUSE_AWAY_THRES || + event->pos().x() < -MOUSE_AWAY_THRES; + bool crossedVert = event->pos().y() - height() > MOUSE_AWAY_THRES || + event->pos().y() < -MOUSE_AWAY_THRES; + + bool removePoint = (crossedHoriz || crossedVert); + + if (!removePoint && d->m_draggedAwayPointIndex >= 0) { + // point is no longer dragged away so reinsert it + QPointF newPoint(d->m_draggedAwayPoint); + d->m_grab_point_index = d->m_curve.addPoint(newPoint); + d->m_draggedAwayPointIndex = -1; + } + + if (removePoint && + (d->m_draggedAwayPointIndex >= 0)) + return; + */ + + setCursor(Qt::CrossCursor); + + x += m_grabOffsetX; + y += m_grabOffsetY; + + double leftX, rightX; + BPoint point = m_spline.points()[m_currentPointIndex]; + switch (m_currentPointType) { + case PTypeH1: + rightX = point.p.x(); + if (m_currentPointIndex == 0) + leftX = -1000; + else + leftX = m_spline.points()[m_currentPointIndex - 1].p.x(); + x = qBound(leftX, x, rightX); + point.h1 = QPointF(x, y); + break; + case PTypeP: + if (m_currentPointIndex == 0) { + leftX = 0.0; + rightX = 0.0; + /*if (d->m_curve.points().count() > 1) + * rightX = d->m_curve.points()[d->m_grab_point_index + 1].x() - POINT_AREA; + * else + * rightX = 1.0;*/ + } else if (m_currentPointIndex == m_spline.points().count() - 1) { + leftX = 1.0;//m_spline.points()[m_currentPointIndex - 1].p.x(); + rightX = 1.0; + } else { + //// the 1E-4 addition so we can grab the dot later. + leftX = m_spline.points()[m_currentPointIndex - 1].p.x();// + POINT_AREA; + rightX = m_spline.points()[m_currentPointIndex + 1].p.x();// - POINT_AREA; + } + x = qBound(leftX, x, rightX); + y = qBound(0., y, 1.); + + // move handles by same offset + point.h1 += QPointF(x, y) - point.p; + point.h2 += QPointF(x, y) - point.p; + + point.p = QPointF(x, y); + break; + case PTypeH2: + leftX = point.p.x(); + if (m_currentPointIndex == m_spline.points().count() - 1) + rightX = 1001; + else + rightX = m_spline.points()[m_currentPointIndex + 1].p.x(); + x = qBound(leftX, x, rightX); + point.h2 = QPointF(x, y); + }; + + m_spline.setPoint(m_currentPointIndex, point); + + /*if (removePoint && d->m_curve.points().count() > 2) { + d->m_draggedAwayPoint = d->m_curve.points()[d->m_grab_point_index]; + d->m_draggedAwayPointIndex = d->m_grab_point_index; + 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); + } + + d->setCurveModified();*/ + emit currentPoint(point); + update(); + } +} + +void BezierSplineEditor::leaveEvent(QEvent* event) +{ + QWidget::leaveEvent(event); +} + +int BezierSplineEditor::nearestPointInRange(QPointF p, int wWidth, int wHeight, BezierSplineEditor::point_types* sel) +{ + double nearestDistanceSquared = 1000; + point_types selectedPoint; + int nearestIndex = -1; + int i = 0; + + double distanceSquared; + foreach(const BPoint & point, m_spline.points()) { + distanceSquared = pow(point.h1.x() - p.x(), 2) + pow(point.h1.y() - p.y(), 2); + if (distanceSquared < nearestDistanceSquared) { + nearestIndex = i; + nearestDistanceSquared = distanceSquared; + selectedPoint = PTypeH1; + } + distanceSquared = pow(point.p.x() - p.x(), 2) + pow(point.p.y() - p.y(), 2); + if (distanceSquared < nearestDistanceSquared) { + nearestIndex = i; + nearestDistanceSquared = distanceSquared; + selectedPoint = PTypeP; + } + distanceSquared = pow(point.h2.x() - p.x(), 2) + pow(point.h2.y() - p.y(), 2); + if (distanceSquared < nearestDistanceSquared) { + nearestIndex = i; + nearestDistanceSquared = distanceSquared; + selectedPoint = PTypeH2; + } + ++i; + } + + if (nearestIndex >= 0) { + BPoint point = m_spline.points()[nearestIndex]; + QPointF p2; + switch (selectedPoint) { + case PTypeH1: + p2 = point.h1; + break; + case PTypeP: + p2 = point.p; + break; + case PTypeH2: + p2 = point.h2; + } + if (qAbs(p.x() - p2.x()) * (wWidth - 1) < 5 && qAbs(p.y() - p2.y()) * (wHeight - 1) < 5) { + *sel = selectedPoint; + return nearestIndex; + } + } + + return -1; +} + +#include "beziersplineeditor.moc" Copied: trunk/kdenlive/src/beziercurve/beziersplineeditor.h (from rev 5230, trunk/kdenlive/src/beziercurve/beziersplinewidget.h) =================================================================== --- trunk/kdenlive/src/beziercurve/beziersplineeditor.h (rev 0) +++ trunk/kdenlive/src/beziercurve/beziersplineeditor.h 2011-01-01 21:06:59 UTC (rev 5233) @@ -0,0 +1,71 @@ +/*************************************************************************** + * Copyright (C) 2010 by Till Theato (ro...@tt...) * + * This file is part of Kdenlive (www.kdenlive.org). * + * * + * Kdenlive 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. * + * * + * Kdenlive 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. * + * * + * You should have received a copy of the GNU General Public License * + * along with Kdenlive. If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + +#ifndef BEZIERSPLINEEDITOR_H +#define BEZIERSPLINEEDITOR_H + +#include "cubicbezierspline.h" + +#include <QtCore> +#include <QWidget> + +class BezierSplineEditor : public QWidget +{ + Q_OBJECT + +public: + BezierSplineEditor(QWidget* parent = 0); + + CubicBezierSpline spline(); + void setSpline(const CubicBezierSpline &spline); + + BPoint getCurrentPoint(); + void updateCurrentPoint(const BPoint &p); + +protected: + //void keyPressEvent(QKeyEvent *event); + void paintEvent(QPaintEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent * event); + void mouseMoveEvent(QMouseEvent * event); + void leaveEvent(QEvent *event); + void resizeEvent(QResizeEvent *event); + +private: + CubicBezierSpline m_spline; + enum modes { ModeDrag, ModeNormal }; + enum point_types { PTypeH1, PTypeP, PTypeH2 }; + modes m_mode; + int m_currentPointIndex; + point_types m_currentPointType; + double m_grabOffsetX; + double m_grabOffsetY; + double m_grabOriginalX; + double m_grabOriginalY; + //QPointF m_draggedAwayPoint; + //int m_draggedAwayPointIndex; + + //inline void drawGrid(QPainter &p, int width, int height); + int nearestPointInRange(QPointF p, int wWidth, int wHeight, point_types *sel); + +signals: + void modified(); + void currentPoint(const BPoint &p); +}; + +#endif Deleted: trunk/kdenlive/src/beziercurve/beziersplinewidget.cpp =================================================================== --- trunk/kdenlive/src/beziercurve/beziersplinewidget.cpp 2011-01-01 13:31:06 UTC (rev 5232) +++ trunk/kdenlive/src/beziercurve/beziersplinewidget.cpp 2011-01-01 21:06:59 UTC (rev 5233) @@ -1,357 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Till Theato (ro...@tt...) * - * This file is part of Kdenlive (www.kdenlive.org). * - * * - * Kdenlive 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. * - * * - * Kdenlive 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. * - * * - * You should have received a copy of the GNU General Public License * - * along with Kdenlive. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#include "beziersplinewidget.h" - -#include <QPainter> -#include <QMouseEvent> - -#include <KDebug> - -BezierSplineWidget::BezierSplineWidget(QWidget* parent) : - QWidget(parent), - m_mode(ModeNormal), - m_currentPointIndex(-1) -{ - setMouseTracking(true); - setAutoFillBackground(false); - setAttribute(Qt::WA_OpaquePaintEvent); - setMinimumSize(150, 150); - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); -} - -CubicBezierSpline BezierSplineWidget::spline() -{ - return m_spline; -} - -void BezierSplineWidget::setSpline(const CubicBezierSpline& spline) -{ - // TODO: cleanup - m_spline.fromString(spline.toString()); -} - -void BezierSplineWidget::paintEvent(QPaintEvent* event) -{ - Q_UNUSED(event); - - QPainter p(this); - - p.fillRect(rect(), palette().background()); - - int wWidth = width() - 1; - int wHeight = height() - 1; - - /* - * Spline - */ - double prevY = wHeight - m_spline.value(0.) * wHeight; - double prevX = 0.; - double curY; - double normalizedX = -1; - int x; - - p.setPen(QPen(Qt::black, 1, Qt::SolidLine)); - for (x = 0 ; x < wWidth ; ++x) { - normalizedX = x / (double)wWidth; - curY = wHeight - m_spline.value(normalizedX, true) * wHeight; - - /* - * Keep in mind that QLineF rounds doubles - * to ints mathematically, not just rounds down - * like in C - */ - p.drawLine(QLineF(prevX, prevY, - x, curY)); - prevX = x; - prevY = curY; - } - p.drawLine(QLineF(prevX, prevY , - x, wHeight - m_spline.value(1.0, true) * wHeight)); - - /* - * Points + Handles - */ - p.setPen(QPen(Qt::red, 1, Qt::SolidLine)); - BPoint point; - QPolygon handle(4); - handle.setPoints(4, - 1, -2, - 4, 1, - 1, 4, - -2, 1); - for (int i = 0; i < m_spline.points().count(); ++i) { - point = m_spline.points().at(i); - if (i == m_currentPointIndex) - p.setBrush(QBrush(QColor(Qt::red), Qt::SolidPattern)); - - p.drawConvexPolygon(handle.translated(point.h1.x() * wWidth, wHeight - point.h1.y() * wHeight)); - p.drawEllipse(QRectF(point.p.x() * wWidth - 3, - wHeight - 3 - point.p.y() * wHeight, 6, 6)); - p.drawConvexPolygon(handle.translated(point.h2.x() * wWidth, wHeight - point.h2.y() * wHeight)); - - if ( i == m_currentPointIndex) - p.setBrush(QBrush(Qt::NoBrush)); - } -} - -void BezierSplineWidget::resizeEvent(QResizeEvent* event) -{ - m_spline.setPrecision(width()); - QWidget::resizeEvent(event); -} - -void BezierSplineWidget::mousePressEvent(QMouseEvent* event) -{ - double x = event->pos().x() / (double)(width() - 1); - double y = 1.0 - event->pos().y() / (double)(height() - 1); - - point_types selectedPoint; - int closestPointIndex = nearestPointInRange(QPointF(x, y), width(), height(), &selectedPoint); - - if (event->button() == Qt::RightButton && closestPointIndex > 0 && closestPointIndex < m_spline.points().count() - 1 && selectedPoint == PTypeP) { - m_spline.removePoint(closestPointIndex); - setCursor(Qt::ArrowCursor); - m_mode = ModeNormal; - if (closestPointIndex < m_currentPointIndex) - --m_currentPointIndex; - update(); - emit modified(); - return; - } else if (event->button() != Qt::LeftButton) { - return; - } - - if (closestPointIndex < 0) { - BPoint po; - po.p = QPointF(x, y); - po.h1 = QPointF(x-0.05, y-0.05); - po.h2 = QPointF(x+0.05, y+0.05); - m_currentPointIndex = m_spline.addPoint(po); - m_currentPointType = PTypeP; - /*if (!d->jumpOverExistingPoints(newPoint, -1)) return;*/ - } else { - m_currentPointIndex = closestPointIndex; - m_currentPointType = selectedPoint; - } - - BPoint point = m_spline.points()[m_currentPointIndex]; - QPointF p; - switch (m_currentPointType) { - case PTypeH1: - p = point.h1; - break; - case PTypeP: - p = point.p; - break; - case PTypeH2: - p = point.h2; - } - - m_grabOriginalX = p.x(); - m_grabOriginalY = p.y(); - m_grabOffsetX = p.x() - x; - m_grabOffsetY = p.y() - y; - - switch (m_currentPointType) { - case PTypeH1: - point.h1 = QPointF(x + m_grabOffsetX, y + m_grabOffsetY); - break; - case PTypeP: - point.p = QPointF(x + m_grabOffsetX, y + m_grabOffsetY); - break; - case PTypeH2: - point.h2 = QPointF(x + m_grabOffsetX, y + m_grabOffsetY); - } - m_spline.setPoint(m_currentPointIndex, point); - - //d->m_draggedAwayPointIndex = -1; - - m_mode = ModeDrag; - - update(); -} - -void BezierSplineWidget::mouseReleaseEvent(QMouseEvent* event) -{ - if (event->button() != Qt::LeftButton) - return; - - setCursor(Qt::ArrowCursor); - m_mode = ModeNormal; - - emit modified(); -} - -void BezierSplineWidget::mouseMoveEvent(QMouseEvent* event) -{ - double x = event->pos().x() / (double)(width() - 1); - double y = 1.0 - event->pos().y() / (double)(height() - 1); - - if (m_mode == ModeNormal) { // If no point is selected set the the cursor shape if on top - point_types type; - int nearestPointIndex = nearestPointInRange(QPointF(x, y), width(), height(), &type); - - if (nearestPointIndex < 0) - setCursor(Qt::ArrowCursor); - else - setCursor(Qt::CrossCursor); - } else { // Else, drag the selected point - /*bool crossedHoriz = event->pos().x() - width() > MOUSE_AWAY_THRES || - event->pos().x() < -MOUSE_AWAY_THRES; - bool crossedVert = event->pos().y() - height() > MOUSE_AWAY_THRES || - event->pos().y() < -MOUSE_AWAY_THRES; - - bool removePoint = (crossedHoriz || crossedVert); - - if (!removePoint && d->m_draggedAwayPointIndex >= 0) { - // point is no longer dragged away so reinsert it - QPointF newPoint(d->m_draggedAwayPoint); - d->m_grab_point_index = d->m_curve.addPoint(newPoint); - d->m_draggedAwayPointIndex = -1; - } - - if (removePoint && - (d->m_draggedAwayPointIndex >= 0)) - return; - */ - - setCursor(Qt::CrossCursor); - - x += m_grabOffsetX; - y += m_grabOffsetY; - - double leftX, rightX; - BPoint point = m_spline.points()[m_currentPointIndex]; - switch (m_currentPointType) { - case PTypeH1: - rightX = point.p.x(); - if (m_currentPointIndex == 0) - leftX = -1000; - else - leftX = m_spline.points()[m_currentPointIndex - 1].p.x(); - x = qBound(leftX, x, rightX); - point.h1 = QPointF(x, y); - break; - case PTypeP: - if (m_currentPointIndex == 0) { - leftX = 0.0; - rightX = 0.0; - /*if (d->m_curve.points().count() > 1) - * rightX = d->m_curve.points()[d->m_grab_point_index + 1].x() - POINT_AREA; - * else - * rightX = 1.0;*/ - } else if (m_currentPointIndex == m_spline.points().count() - 1) { - leftX = 1.0;//m_spline.points()[m_currentPointIndex - 1].p.x(); - rightX = 1.0; - } else { - //// the 1E-4 addition so we can grab the dot later. - leftX = m_spline.points()[m_currentPointIndex - 1].p.x();// + POINT_AREA; - rightX = m_spline.points()[m_currentPointIndex + 1].p.x();// - POINT_AREA; - } - x = qBound(leftX, x, rightX); - y = qBound(0., y, 1.); - - // move handles by same offset - point.h1 += QPointF(x, y) - point.p; - point.h2 += QPointF(x, y) - point.p; - - point.p = QPointF(x, y); - break; - case PTypeH2: - leftX = point.p.x(); - if (m_currentPointIndex == m_spline.points().count() - 1) - rightX = 1001; - else - rightX = m_spline.points()[m_currentPointIndex + 1].p.x(); - x = qBound(leftX, x, rightX); - point.h2 = QPointF(x, y); - }; - - m_spline.setPoint(m_currentPointIndex, point); - - /*if (removePoint && d->m_curve.points().count() > 2) { - d->m_draggedAwayPoint = d->m_curve.points()[d->m_grab_point_index]; - d->m_draggedAwayPointIndex = d->m_grab_point_index; - 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); - } - - d->setCurveModified();*/ - update(); - } -} - -void BezierSplineWidget::leaveEvent(QEvent* event) -{ - QWidget::leaveEvent(event); -} - -int BezierSplineWidget::nearestPointInRange(QPointF p, int wWidth, int wHeight, BezierSplineWidget::point_types* sel) -{ - double nearestDistanceSquared = 1000; - point_types selectedPoint; - int nearestIndex = -1; - int i = 0; - - double distanceSquared; - foreach(const BPoint & point, m_spline.points()) { - distanceSquared = pow(point.h1.x() - p.x(), 2) + pow(point.h1.y() - p.y(), 2); - if (distanceSquared < nearestDistanceSquared) { - nearestIndex = i; - nearestDistanceSquared = distanceSquared; - selectedPoint = PTypeH1; - } - distanceSquared = pow(point.p.x() - p.x(), 2) + pow(point.p.y() - p.y(), 2); - if (distanceSquared < nearestDistanceSquared) { - nearestIndex = i; - nearestDistanceSquared = distanceSquared; - selectedPoint = PTypeP; - } - distanceSquared = pow(point.h2.x() - p.x(), 2) + pow(point.h2.y() - p.y(), 2); - if (distanceSquared < nearestDistanceSquared) { - nearestIndex = i; - nearestDistanceSquared = distanceSquared; - selectedPoint = PTypeH2; - } - ++i; - } - - if (nearestIndex >= 0) { - BPoint point = m_spline.points()[nearestIndex]; - QPointF p2; - switch (selectedPoint) { - case PTypeH1: - p2 = point.h1; - break; - case PTypeP: - p2 = point.p; - break; - case PTypeH2: - p2 = point.h2; - } - if (qAbs(p.x() - p2.x()) * (wWidth - 1) < 5 && qAbs(p.y() - p2.y()) * (wHeight - 1) < 5) { - *sel = selectedPoint; - return nearestIndex; - } - } - - return -1; -} - -#include "beziersplinewidget.moc" Added: trunk/kdenlive/src/beziercurve/beziersplinewidget.cpp =================================================================== --- trunk/kdenlive/src/beziercurve/beziersplinewidget.cpp (rev 0) +++ trunk/kdenlive/src/beziercurve/beziersplinewidget.cpp 2011-01-01 21:06:59 UTC (rev 5233) @@ -0,0 +1,99 @@ +/*************************************************************************** + * Copyright (C) 2010 by Till Theato (ro...@tt...) * + * This file is part of Kdenlive (www.kdenlive.org). * + * * + * Kdenlive 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. * + * * + * Kdenlive 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. * + * * + * You should have received a copy of the GNU General Public License * + * along with Kdenlive. If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + +#include "beziersplinewidget.h" + +#include <QVBoxLayout> + +#include <KIcon> + +BezierSplineWidget::BezierSplineWidget(const QString& spline, QWidget* parent) : + QWidget(parent) +{ + QVBoxLayout *layout = new QVBoxLayout(this); + layout->addWidget(&m_edit); + QWidget *widget = new QWidget(this); + m_ui.setupUi(widget); + layout->addWidget(widget); + + m_ui.buttonLinkHandles->setIcon(KIcon("insert-link")); + m_ui.buttonLinkHandles->setEnabled(false); + m_ui.widgetPoint->setEnabled(false); + + CubicBezierSpline s; + s.fromString(spline); + m_edit.setSpline(s); + + connect(&m_edit, SIGNAL(modified()), this, SIGNAL(modified())); + connect(&m_edit, SIGNAL(currentPoint(const BPoint&)), this, SLOT(slotUpdatePoint(const BPoint&))); + + connect(m_ui.spinPX, SIGNAL(editingFinished()), this, SLOT(slotUpdateSpline())); + connect(m_ui.spinPY, SIGNAL(editingFinished()), this, SLOT(slotUpdateSpline())); + connect(m_ui.spinH1X, SIGNAL(editingFinished()), this, SLOT(slotUpdateSpline())); + connect(m_ui.spinH1Y, SIGNAL(editingFinished()), this, SLOT(slotUpdateSpline())); + connect(m_ui.spinH2X, SIGNAL(editingFinished()), this, SLOT(slotUpdateSpline())); + connect(m_ui.spinH2Y, SIGNAL(editingFinished()), this, SLOT(slotUpdateSpline())); +} + +QString BezierSplineWidget::spline() +{ + return m_edit.spline().toString(); +} + +void BezierSplineWidget::slotUpdatePoint(const BPoint &p) +{ + blockSignals(true); + if (p == BPoint()) { + m_ui.widgetPoint->setEnabled(false); + } else { + m_ui.widgetPoint->setEnabled(true); + m_ui.spinPX->setValue(qRound(p.p.x() * 255)); + m_ui.spinPY->setValue(qRound(p.p.y() * 255)); + m_ui.spinH1X->setValue(qRound(p.h1.x() * 255)); + m_ui.spinH1Y->setValue(qRound(p.h1.y() * 255)); + m_ui.spinH2X->setValue(qRound(p.h2.x() * 255)); + m_ui.spinH2Y->setValue(qRound(p.h2.y() * 255)); + } + blockSignals(false); +} + +void BezierSplineWidget::slotUpdateSpline() +{ + BPoint p = m_edit.getCurrentPoint(); + + // check for every value, so we do not lose too much info through rounding + if (m_ui.spinPX->value() != qRound(p.p.x() * 255)) + p.p.setX(m_ui.spinPX->value() / 255.); + if (m_ui.spinPY->value() != qRound(p.p.y() * 255)) + p.p.setY(m_ui.spinPY->value() / 255.); + + if (m_ui.spinH1X->value() != qRound(p.h1.x() * 255)) + p.h1.setX(m_ui.spinH1X->value() / 255.); + if (m_ui.spinH1Y->value() != qRound(p.h1.y() * 255)) + p.h1.setY(m_ui.spinH1Y->value() / 255.); + + if (m_ui.spinH2X->value() != qRound(p.h2.x() * 255)) + p.h2.setX(m_ui.spinH2X->value() / 255.); + if (m_ui.spinH2Y->value() != qRound(p.h2.y() * 255)) + p.h2.setY(m_ui.spinH2Y->value() / 255.); + + m_edit.updateCurrentPoint(p); + emit modified(); +} + +#include "beziersplinewidget.moc" Deleted: trunk/kdenlive/src/beziercurve/beziersplinewidget.h =================================================================== --- trunk/kdenlive/src/beziercurve/beziersplinewidget.h 2011-01-01 13:31:06 UTC (rev 5232) +++ trunk/kdenlive/src/beziercurve/beziersplinewidget.h 2011-01-01 21:06:59 UTC (rev 5233) @@ -1,67 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Till Theato (ro...@tt...) * - * This file is part of Kdenlive (www.kdenlive.org). * - * * - * Kdenlive 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. * - * * - * Kdenlive 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. * - * * - * You should have received a copy of the GNU General Public License * - * along with Kdenlive. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifndef BEZIERSPLINEWIDGET_H -#define BEZIERSPLINEWIDGET_H - -#include "cubicbezierspline.h" - -#include <QtCore> -#include <QWidget> - -class BezierSplineWidget : public QWidget -{ - Q_OBJECT - -public: - BezierSplineWidget(QWidget* parent = 0); - - CubicBezierSpline spline(); - void setSpline(const CubicBezierSpline &spline); - -protected: - //void keyPressEvent(QKeyEvent *event); - void paintEvent(QPaintEvent *event); - void mousePressEvent(QMouseEvent *event); - void mouseReleaseEvent(QMouseEvent * event); - void mouseMoveEvent(QMouseEvent * event); - void leaveEvent(QEvent *event); - void resizeEvent(QResizeEvent *event); - -private: - CubicBezierSpline m_spline; - enum modes { ModeDrag, ModeNormal }; - enum point_types { PTypeH1, PTypeP, PTypeH2 }; - modes m_mode; - int m_currentPointIndex; - point_types m_currentPointType; - double m_grabOffsetX; - double m_grabOffsetY; - double m_grabOriginalX; - double m_grabOriginalY; - //QPointF m_draggedAwayPoint; - //int m_draggedAwayPointIndex; - - //inline void drawGrid(QPainter &p, int width, int height); - int nearestPointInRange(QPointF p, int wWidth, int wHeight, point_types *sel); - -signals: - void modified(); -}; - -#endif Added: trunk/kdenlive/src/beziercurve/beziersplinewidget.h =================================================================== --- trunk/kdenlive/src/beziercurve/beziersplinewidget.h (rev 0) +++ trunk/kdenlive/src/beziercurve/beziersplinewidget.h 2011-01-01 21:06:59 UTC (rev 5233) @@ -0,0 +1,50 @@ +/*************************************************************************** + * Copyright (C) 2010 by Till Theato (ro...@tt...) * + * This file is part of Kdenlive (www.kdenlive.org). * + * * + * Kdenlive 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. * + * * + * Kdenlive 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. * + * * + * You should have received a copy of the GNU General Public License * + * along with Kdenlive. If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + +#ifndef BEZIERSPLINEWIDGET_H +#define BEZIERSPLINEWIDGET_H + +#include "cubicbezierspline.h" +#include "beziersplineeditor.h" +#include "ui_bezierspline_ui.h" + +#include <QtCore> +#include <QWidget> + +class BezierSplineWidget : public QWidget +{ + Q_OBJECT + +public: + BezierSplineWidget(const QString &spline, QWidget* parent = 0); + + QString spline(); + +private slots: + void slotUpdatePoint(const BPoint &p); + void slotUpdateSpline(); + +private: + Ui::BezierSpline_UI m_ui; + BezierSplineEditor m_edit; + +signals: + void modified(); +}; + +#endif Modified: trunk/kdenlive/src/beziercurve/cubicbezierspline.h =================================================================== --- trunk/kdenlive/src/beziercurve/cubicbezierspline.h 2011-01-01 13:31:06 UTC (rev 5232) +++ trunk/kdenlive/src/beziercurve/cubicbezierspline.h 2011-01-01 21:06:59 UTC (rev 5233) @@ -29,6 +29,7 @@ QPointF p; // point QPointF h2; // handle 2 + BPoint() { p = QPointF(-1,-1); } // makes it illegal -> cannot be equal any point bool operator==(const BPoint &point) const { return point.h1 == h1 && point.p == p && point.h2 == h2; } }; Modified: trunk/kdenlive/src/effectstackedit.cpp =================================================================== --- trunk/kdenlive/src/effectstackedit.cpp 2011-01-01 13:31:06 UTC (rev 5232) +++ trunk/kdenlive/src/effectstackedit.cpp 2011-01-01 21:06:59 UTC (rev 5233) @@ -35,7 +35,6 @@ #include "doubleparameterwidget.h" #include "cornerswidget.h" #include "beziercurve/beziersplinewidget.h" -#include "beziercurve/cubicbezierspline.h" #include <KDebug> #include <KLocale> @@ -384,10 +383,7 @@ if (!depends.isEmpty()) meetDependency(paramName, type, EffectsList::parameter(e, depends)); } else if (type == "bezier_spline") { - BezierSplineWidget *widget = new BezierSplineWidget(this); - CubicBezierSpline spline; - spline.fromString(value); - widget->setSpline(spline); + BezierSplineWidget *widget = new BezierSplineWidget(value, this); stretch = false; m_vbox->addWidget(widget); m_valueItems[paramName] = widget; @@ -675,7 +671,7 @@ meetDependency(paramName, type, EffectsList::parameter(newparam, depends)); } else if (type == "bezier_spline") { BezierSplineWidget *widget = (BezierSplineWidget*)m_valueItems.value(paramName); - setValue = widget->spline().toString(); + setValue = widget->spline(); } else if (type == "corners") { CornersWidget *corners = ((CornersWidget*)m_valueItems.value(paramName)); QString xName = pa.attributes().namedItem("xpoints").nodeValue(); Added: trunk/kdenlive/src/widgets/bezierspline_ui.ui =================================================================== --- trunk/kdenlive/src/widgets/bezierspline_ui.ui (rev 0) +++ trunk/kdenlive/src/widgets/bezierspline_ui.ui 2011-01-01 21:06:59 UTC (rev 5233) @@ -0,0 +1,206 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>BezierSpline_UI</class> + <widget class="QWidget" name="BezierSpline_UI"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>471</width> + <height>84</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="1" column="5"> + <widget class="QWidget" name="widgetPoint" native="true"> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0" colspan="9"> + <widget class="QWidget" name="widget" native="true"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="margin"> + <number>0</number> + </property> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QSpinBox" name="spinPX"> + <property name="toolTip"> + <string>Point In</string> + </property> + <property name="maximum"> + <number>255</number> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Point</string> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="spinPY"> + <property name="toolTip"> + <string>Point Out</string> + </property> + <property name="maximum"> + <number>255</number> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + <item row="1" column="0"> + <widget class="QSpinBox" name="spinH1X"> + <property name="toolTip"> + <string>Handle 1 X</string> + </property> + <property name="minimum"> + <number>-100</number> + </property> + <property name="maximum"> + <number>400</number> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="label_2"> + <property name="toolTip"> + <string>Handle 1</string> + </property> + <property name="text"> + <string>H1</string> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QSpinBox" name="spinH1Y"> + <property name="toolTip"> + <string>Handle 1 Y</string> + </property> + <property name="minimum"> + <number>-100</number> + </property> + <property name="maximum"> + <number>400</number> + </property> + <property name="value"> + <number>0</number> + </property> + </widget> + </item> + <item row="1" column="3"> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="4"> + <widget class="QToolButton" name="buttonLinkHandles"> + <property name="toolTip"> + <string>Link the Handles' position so you draw a line through Handle -> Point -> Handle.<br />Results in a natural spline.</string> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="autoRaise"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="5"> + <spacer name="horizontalSpacer_4"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="6"> + <widget class="QSpinBox" name="spinH2X"> + <property name="toolTip"> + <string>Handle 2 X</string> + </property> + <property name="minimum"> + <number>-100</number> + </property> + <property name="maximum"> + <number>400</number> + </property> + </widget> + </item> + <item row="1" column="7"> + <widget class="QLabel" name="label_3"> + <property name="toolTip"> + <string>Handle 2</string> + </property> + <property name="text"> + <string>H2</string> + </property> + </widget> + </item> + <item row="1" column="8"> + <widget class="QSpinBox" name="spinH2Y"> + <property name="toolTip"> + <string>Handle 2 Y</string> + </property> + <property name="minimum"> + <number>-100</number> + </property> + <property name="maximum"> + <number>400</number> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |