#include "splineitem.h"
#include "bpointitem.h"
#include "nearestpoint.h"
+#include "kdenlivesettings.h"
#include <QGraphicsScene>
#include <QCursor>
#include <QGraphicsSceneMouseEvent>
+#include <QGraphicsView>
inline QPointF closestPointInRect(QPointF point, QRectF rect)
SplineItem::SplineItem(const QList< BPoint >& points, QGraphicsItem* parent, QGraphicsScene *scene) :
- QGraphicsPathItem(parent, scene)
+ QGraphicsPathItem(parent, scene),
+ m_closed(true),
+ m_editing(false)
{
QPen framepen(Qt::SolidLine);
framepen.setColor(Qt::yellow);
setBrush(Qt::NoBrush);
setAcceptHoverEvents(true);
- m_closed = true;
- if (points.isEmpty()) {
- m_closed = false;
- grabMouse();
- return;
- }
+ m_view = scene->views().first();
- QPainterPath path(points.at(0).p);
- int j;
- for (int i = 0; i < points.count(); ++i) {
- new BPointItem(points.at(i), this);
- j = (i + 1) % points.count();
- path.cubicTo(points.at(i).h2, points.at(j).h1, points.at(j).p);
- }
- setPath(path);
+ setPoints(points);
}
int SplineItem::type() const
return Type;
}
-void SplineItem::updateSpline()
+bool SplineItem::editing() const
+{
+ return m_editing;
+}
+
+void SplineItem::updateSpline(bool editing)
{
QPainterPath path(qgraphicsitem_cast<BPointItem *>(childItems().at(0))->getPoint().p);
}
setPath(path);
- if (m_closed)
- emit changed();
+ m_editing = editing;
+
+ if (m_closed && (!editing || KdenliveSettings::monitorscene_directupdate()))
+ emit changed(editing);
}
-QList <BPoint> SplineItem::getPoints()
+QList <BPoint> SplineItem::getPoints() const
{
QList <BPoint> points;
foreach (QGraphicsItem *child, childItems())
return points;
}
+void SplineItem::setPoints(const QList< BPoint >& points)
+{
+ if (points.count() < 2) {
+ m_closed = false;
+ grabMouse();
+ return;
+ } else if (!m_closed) {
+ ungrabMouse();
+ m_closed = true;
+ }
+
+ qDeleteAll(childItems());
+ childItems().clear();
+
+ QPainterPath path(points.at(0).p);
+ int j;
+ for (int i = 0; i < points.count(); ++i) {
+ new BPointItem(points.at(i), this);
+ j = (i + 1) % points.count();
+ path.cubicTo(points.at(i).h2, points.at(j).h1, points.at(j).p);
+ }
+ setPath(path);
+}
+
void SplineItem::removeChild(QGraphicsItem* child)
{
if (childItems().count() > 2) {
return;
if (m_closed) {
- QRectF r(event->scenePos() - QPointF(6, 6), QSizeF(12, 12));
+ qreal size = 12 / m_view->matrix().m11();
+ QRectF r(event->scenePos() - QPointF(size / 2, size / 2), QSizeF(size, size));
if (event->button() == Qt::LeftButton && path().intersects(r) && !path().contains(r)) {
double t = 0;
BPointItem *i1, *i2;
updateSpline();
}
} else {
- if (event->button() == Qt::RightButton) {
- if (childItems().count() > 1) {
+ bool close = false;
+ QList <QGraphicsItem *> items = childItems();
+ if (items.count() > 1) {
+ BPointItem *bp = qgraphicsitem_cast<BPointItem *>(items.at(0));
+ int selectionType = bp->getSelection(mapToItem(bp, event->pos()));
+ // since h1 == p we need to check for both
+ if (selectionType == 0 || selectionType == 1)
+ close = true;
+ }
+
+ if (close || event->button() == Qt::RightButton) {
+ if (items.count() > 1) {
// close the spline
- BPointItem *i1 = qgraphicsitem_cast<BPointItem *>(childItems().first());
- BPointItem *i2 = qgraphicsitem_cast<BPointItem *>(childItems().last());
+ BPointItem *i1 = qgraphicsitem_cast<BPointItem *>(items.first());
+ BPointItem *i2 = qgraphicsitem_cast<BPointItem *>(items.last());
BPoint p1 = i1->getPoint();
BPoint p2 = i2->getPoint();
p1.h1 = QLineF(p1.p, p2.p).pointAt(.2);
} else if (event->modifiers() == Qt::NoModifier) {
BPoint p;
p.p = p.h1 = p.h2 = event->scenePos();
- if (childItems().count()) {
- BPointItem *i = qgraphicsitem_cast<BPointItem *>(childItems().last());
+ if (items.count()) {
+ BPointItem *i = qgraphicsitem_cast<BPointItem *>(items.last());
BPoint prev = i->getPoint();
prev.h2 = QLineF(prev.p, p.p).pointAt(.2);
p.h1 = QLineF(prev.p, p.p).pointAt(.8);
{
QGraphicsItem::hoverMoveEvent(event);
- QRectF r(event->scenePos() - QPointF(6, 6), QSizeF(12, 12));
+ qreal size = 12 / m_view->matrix().m11();
+ QRectF r(event->scenePos() - QPointF(size / 2, size / 2), QSizeF(size, size));
if (path().intersects(r) && !path().contains(r))
setCursor(QCursor(Qt::PointingHandCursor));
else
unsetCursor();
}
-int SplineItem::getClosestPointOnCurve(QPointF point, double *tFinal)
+int SplineItem::getClosestPointOnCurve(const QPointF &point, double *tFinal)
{
// TODO: proper minDiff
qreal diff = 10000, param = 0;
BPoint p1, p2;
int curveSegment = 0, j;
- for (int i = 0; i < childItems().count(); ++i) {
- j = (i + 1) % childItems().count();
- p1 = qgraphicsitem_cast<BPointItem *>(childItems().at(i))->getPoint();
- p2 = qgraphicsitem_cast<BPointItem *>(childItems().at(j))->getPoint();
+ QList <QGraphicsItem *> items = childItems();
+ for (int i = 0; i < items.count(); ++i) {
+ j = (i + 1) % items.count();
+ p1 = qgraphicsitem_cast<BPointItem *>(items.at(i))->getPoint();
+ p2 = qgraphicsitem_cast<BPointItem *>(items.at(j))->getPoint();
QPolygonF bounding = QPolygonF() << p1.p << p1.h2 << p2.h1 << p2.p;
QPointF cl = closestPointInRect(point, bounding.boundingRect());
+#if QT_VERSION >= 0x040600
qreal d = (point - cl).manhattanLength();
+#else
+ qreal d = qAbs((point - cl).x()) + qAbs((point - cl).y());
+#endif
if (d > diff)
continue;
cl.setX(n.x);
cl.setY(n.y);
+#if QT_VERSION >= 0x040600
d = (point - cl).manhattanLength();
+#else
+ d = qAbs((point - cl).x()) + qAbs((point - cl).y());
+#endif
if (d < diff) {
diff = d;
param = t;