]> git.sesse.net Git - kdenlive/commitdiff
This will hopefully fix most clip & group move issues. Should solve points b) and...
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Thu, 25 Dec 2008 03:53:52 +0000 (03:53 +0000)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Thu, 25 Dec 2008 03:53:52 +0000 (03:53 +0000)
http://www.kdenlive.org:80/mantis/view.php?id=271

svn path=/branches/KDE4/; revision=2821

src/abstractgroupitem.cpp
src/abstractgroupitem.h
src/clipitem.cpp

index 7e4cbb93bbdfe90db3eec78b8b774884168727e9..b032526bd6ae08e99961e0e0908661f537d5cb1d 100644 (file)
@@ -21,6 +21,7 @@
 #include <QGraphicsScene>
 #include <QGraphicsView>
 #include <QScrollBar>
+#include <QStyleOptionGraphicsItem>
 #include <QToolTip>
 
 #include <KDebug>
@@ -49,17 +50,16 @@ CustomTrackScene* AbstractGroupItem::projectScene() {
     return NULL;
 }
 
-
-QPolygonF AbstractGroupItem::groupShape(QPointF offset) {
+QPainterPath AbstractGroupItem::groupShape(QPointF offset) {
+    QPainterPath path;
     QList<QGraphicsItem *> 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: "<<pos().y()<<"->"<<newPos.y();
-        QPointF start = pos();//sceneBoundingRect().topLeft();
-        int posx = start.x() + newPos.x(); //projectScene()->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:"<<newTrack<<",START T:"<<startTrack<<",MAX:"<<projectScene()->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<QGraphicsItem*> collindingItems = scene()->items(sceneShape, Qt::IntersectsItemShape);
+        QPainterPath shape = groupShape(newPos - pos());
+        QList<QGraphicsItem*> 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: "<<start.y() + newPos.y()<<"SCN MP: "<<sc;
-        /*int newTrack = (start.y() + newPos.y()) / KdenliveSettings::trackheight();
-        int oldTrack = (start.y() + pos().y()) / KdenliveSettings::trackheight();
-        newPos.setY((newTrack) * KdenliveSettings::trackheight() - start.y() + 1);*/
-
-
-        //if (start.y() + newPos.y() < 1)  newTrack = oldTrack;
-
-        return newPos;
-
-        // Only one clip is moving
-
-        QList<QGraphicsItem*> 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: "<<items.at(i)->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:"<<collision->sceneBoundingRect();
+                    if (newPos.y() != start.y()) {
+                        // Track change results in collision, restore original position
+                        return start;
+                    }
+                    AbstractClipItem *item = static_cast <AbstractClipItem *>(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);
 }
index 88f7008a022e156dda8cab4efd126b773a38ad29..0c0c3009e5319c3e068694f337462e870b0712aa 100644 (file)
@@ -41,7 +41,7 @@ protected:
     virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
 
 private:
-    QPolygonF groupShape(QPointF);
+    QPainterPath groupShape(QPointF);
     void fixItemRect();
     double m_fps;
 };
index 204e6c282574c21ccc7c0affbffb33d22144dc18..259f6cb581bd2198c62575410e626510aef8cae1 100644 (file)
@@ -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<QGraphicsItem*> 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<QGraphicsItem*> 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<QGraphicsItem*> 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;