From 64cfba1eba92aace58017b69ca6dbab1222779cf Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Thu, 25 Dec 2008 03:53:52 +0000 Subject: [PATCH] This will hopefully fix most clip & group move issues. Should solve points b) and c) from: http://www.kdenlive.org:80/mantis/view.php?id=271 svn path=/branches/KDE4/; revision=2821 --- src/abstractgroupitem.cpp | 113 ++++++++++++++++---------------------- src/abstractgroupitem.h | 2 +- src/clipitem.cpp | 45 ++++++++------- 3 files changed, 71 insertions(+), 89 deletions(-) diff --git a/src/abstractgroupitem.cpp b/src/abstractgroupitem.cpp index 7e4cbb93..b032526b 100644 --- a/src/abstractgroupitem.cpp +++ b/src/abstractgroupitem.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -49,17 +50,16 @@ CustomTrackScene* AbstractGroupItem::projectScene() { return NULL; } - -QPolygonF AbstractGroupItem::groupShape(QPointF offset) { +QPainterPath AbstractGroupItem::groupShape(QPointF offset) { + QPainterPath path; QList children = childItems(); - QPolygonF path; for (int i = 0; i < children.count(); i++) { if (children.at(i)->type() == AVWIDGET) { - QPolygonF r = QPolygonF(children.at(i)->sceneBoundingRect()); - path = path.united(r); + QRectF r(children.at(i)->sceneBoundingRect()); + r.translate(offset); + path.addRect(r); } } - path.translate(offset); return path; } @@ -77,8 +77,8 @@ void AbstractGroupItem::fixItemRect() { } // virtual -void AbstractGroupItem::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *) { - p->fillRect(boundingRect(), QColor(200, 100, 100, 100)); +void AbstractGroupItem::paint(QPainter *p, const QStyleOptionGraphicsItem *option, QWidget *) { + p->fillRect(option->exposedRect, QColor(200, 100, 100, 100)); } //virtual @@ -91,11 +91,7 @@ QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant xpos = qMax(xpos, 0); newPos.setX(xpos); - - //kDebug()<<"// GRP MOVE: "<"<getSnapPointForPos(start.x() + sc.x(), KdenliveSettings::snaptopoints()); - + QPointF start = pos(); int startTrack = (start.y() + trackHeight / 2) / trackHeight; int newTrack = (newPos.y()) / trackHeight; //kDebug()<<"// GROUP NEW T:"<tracksCount() - 1; @@ -120,78 +116,65 @@ QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant } } } - newPos.setY((int)((newTrack) * trackHeight) + offset); + if (newPos == start) return start; - //kDebug() << "------------------------------------GRUOP MOVE"; - - if (start.x() + newPos.x() - pos().x() < 0) { + if (newPos.x() < 0) { // If group goes below 0, adjust position to 0 return QPointF(pos().x() - start.x(), pos().y()); } - QPolygonF sceneShape = groupShape(newPos - pos()); - QList collindingItems = scene()->items(sceneShape, Qt::IntersectsItemShape); + QPainterPath shape = groupShape(newPos - pos()); + QList collindingItems = scene()->items(shape, Qt::IntersectsItemShape); for (int i = 0; i < children.count(); i++) { collindingItems.removeAll(children.at(i)); } if (collindingItems.isEmpty()) return newPos; else { + bool forwardMove = newPos.x() > start.x(); + int offset = 0; + const double width = sceneBoundingRect().width() + 1; for (int i = 0; i < collindingItems.count(); i++) { QGraphicsItem *collision = collindingItems.at(i); if (collision->type() == AVWIDGET) { // Collision - return pos(); - //TODO: improve movement when collision happens - /*if (startTrack != newTrack) return pos(); - if (collision->pos().x() > pos().x()) { - return QPointF(collision->sceneBoundingRect().x() - sceneBoundingRect().width() + pos().x() - start.x() - 1, newPos.y()); - }*/ - } - } - return newPos; - } - - //else posx -= startx; - //posx = qMax(posx, 0); - //newPos.setX(posx); - //kDebug()<<"Y POS: "< items = scene()->items(sceneShape, Qt::IntersectsItemShape); - - - if (!items.isEmpty()) { - for (int i = 0; i < items.count(); i++) { - if (items.at(i)->type() == AVWIDGET) { - // Collision! - //kDebug()<<"/// COLLISION WITH ITEM: "<sceneBoundingRect(); - return pos(); - QPointF otherPos = items.at(i)->pos(); - if ((int) otherPos.y() != (int) pos().y()) return pos(); - if (pos().x() < otherPos.x()) { - // move clip just before colliding clip - int npos = (static_cast < AbstractClipItem* >(items.at(i))->startPos()).frames(m_fps) - sceneBoundingRect().width(); - newPos.setX(npos); + //kDebug()<<"// COLLISION WIT:"<sceneBoundingRect(); + if (newPos.y() != start.y()) { + // Track change results in collision, restore original position + return start; + } + AbstractClipItem *item = static_cast (collision); + if (forwardMove) { + // Moving forward, determine best pos + QPainterPath clipPath; + clipPath.addRect(item->sceneBoundingRect()); + QPainterPath res = shape.intersected(clipPath); + offset = qMax(offset, (int)(res.boundingRect().width() + 0.5)); } else { - // get pos just after colliding clip - int npos = static_cast < AbstractClipItem* >(items.at(i))->endPos().frames(m_fps); - newPos.setX(npos); + // Moving backward, determine best pos + QPainterPath clipPath; + clipPath.addRect(item->sceneBoundingRect()); + QPainterPath res = shape.intersected(clipPath); + offset = qMax(offset, (int)(res.boundingRect().width() + 0.5)); } - return newPos; } } + if (offset > 0) { + if (forwardMove) { + newPos.setX(newPos.x() - offset); + } else { + newPos.setX(newPos.x() + offset); + } + // If there is still a collision after our position adjust, restore original pos + collindingItems = scene()->items(groupShape(newPos - pos()), Qt::IntersectsItemShape); + for (int i = 0; i < children.count(); i++) { + collindingItems.removeAll(children.at(i)); + } + for (int i = 0; i < collindingItems.count(); i++) + if (collindingItems.at(i)->type() == AVWIDGET) return pos(); + } + return newPos; } - return newPos; } return QGraphicsItem::itemChange(change, value); } diff --git a/src/abstractgroupitem.h b/src/abstractgroupitem.h index 88f7008a..0c0c3009 100644 --- a/src/abstractgroupitem.h +++ b/src/abstractgroupitem.h @@ -41,7 +41,7 @@ protected: virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *); private: - QPolygonF groupShape(QPointF); + QPainterPath groupShape(QPointF); void fixItemRect(); double m_fps; }; diff --git a/src/clipitem.cpp b/src/clipitem.cpp index 204e6c28..259f6cb5 100644 --- a/src/clipitem.cpp +++ b/src/clipitem.cpp @@ -495,7 +495,9 @@ void ClipItem::animate(qreal value) { void ClipItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) { - painter->setOpacity(m_opacity); + /*if (parentItem()) m_opacity = 0.5; + else m_opacity = 1.0; + painter->setOpacity(m_opacity);*/ QBrush paintColor = brush(); if (isSelected()) paintColor = QBrush(QColor(79, 93, 121)); QRectF br = rect(); @@ -1013,9 +1015,9 @@ void ClipItem::checkEffectsKeyframesPos(const int previous, const int current, b QVariant ClipItem::itemChange(GraphicsItemChange change, const QVariant &value) { if (change == ItemPositionChange && scene()) { // calculate new position. - if (group()) return pos(); + if (parentItem()) return pos(); QPointF newPos = value.toPointF(); - // kDebug() << "/// MOVING CLIP ITEM.------------\n++++++++++"; + //kDebug() << "/// MOVING CLIP ITEM.------------\n++++++++++"; int xpos = projectScene()->getSnapPointForPos((int) newPos.x(), KdenliveSettings::snaptopoints()); xpos = qMax(xpos, 0); newPos.setX(xpos); @@ -1028,7 +1030,8 @@ QVariant ClipItem::itemChange(GraphicsItemChange change, const QVariant &value) sceneShape.translate(newPos); QList items = scene()->items(sceneShape, Qt::IntersectsItemShape); items.removeAll(this); - + bool forwardMove = newPos.x() > pos().x(); + int offset = 0; if (!items.isEmpty()) { for (int i = 0; i < items.count(); i++) { if (items.at(i)->type() == type()) { @@ -1037,31 +1040,27 @@ QVariant ClipItem::itemChange(GraphicsItemChange change, const QVariant &value) if ((int) otherPos.y() != (int) pos().y()) { return pos(); } - if (pos().x() < otherPos.x()) { - // move clip just before colliding clip - int npos = (static_cast < AbstractClipItem* >(items.at(i))->startPos() - m_cropDuration).frames(m_fps); - // check we don't run into another clip - newPos.setX(npos); - sceneShape = rect(); - sceneShape.translate(newPos); - QList subitems = scene()->items(sceneShape, Qt::IntersectsItemShape); - items.removeAll(this); - for (int j = 0; j < subitems.count(); j++) { - if (subitems.at(j)->type() == type()) return pos(); - } + if (forwardMove) { + offset = qMax(offset, (int)(newPos.x() - (static_cast < AbstractClipItem* >(items.at(i))->startPos() - m_cropDuration).frames(m_fps))); } else { - // get pos just after colliding clip - int npos = static_cast < AbstractClipItem* >(items.at(i))->endPos().frames(m_fps); - // check we don't run into another clip - newPos.setX(npos); - sceneShape = rect(); - sceneShape.translate(newPos); + offset = qMax(offset, (int)((static_cast < AbstractClipItem* >(items.at(i))->endPos().frames(m_fps)) - newPos.x())); + } + + if (offset > 0) { + if (forwardMove) { + sceneShape.translate(QPointF(-offset, 0)); + newPos.setX(newPos.x() - offset); + } else { + sceneShape.translate(QPointF(offset, 0)); + newPos.setX(newPos.x() + offset); + } QList subitems = scene()->items(sceneShape, Qt::IntersectsItemShape); - items.removeAll(this); + subitems.removeAll(this); for (int j = 0; j < subitems.count(); j++) { if (subitems.at(j)->type() == type()) return pos(); } } + m_track = newTrack; m_startPos = GenTime((int) newPos.x(), m_fps); return newPos; -- 2.39.2