#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),
- m_closed(false),
+ m_closed(true),
m_editing(false)
{
QPen framepen(Qt::SolidLine);
setBrush(Qt::NoBrush);
setAcceptHoverEvents(true);
+ m_view = scene->views().first();
+
setPoints(points);
}
return Type;
}
-bool SplineItem::editing()
+bool SplineItem::editing() const
{
return m_editing;
}
emit changed(editing);
}
-QList <BPoint> SplineItem::getPoints()
+QList <BPoint> SplineItem::getPoints() const
{
QList <BPoint> points;
foreach (QGraphicsItem *child, childItems())
m_closed = false;
grabMouse();
return;
- } else {
+ } else if (!m_closed) {
ungrabMouse();
m_closed = true;
}
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;