X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fabstractgroupitem.cpp;h=e91d1f81a310108101e4efb937ab80000424e1dc;hb=c3302003093710ee247ad84c0fe2ef3c579d417f;hp=f2a475f6b2bbc5ef02bac47889a9bad9b5a9515d;hpb=d7937111a5566523b67e1fe3e10d91c9a51c718b;p=kdenlive diff --git a/src/abstractgroupitem.cpp b/src/abstractgroupitem.cpp index f2a475f6..e91d1f81 100644 --- a/src/abstractgroupitem.cpp +++ b/src/abstractgroupitem.cpp @@ -34,8 +34,8 @@ AbstractGroupItem::AbstractGroupItem(double /* fps */) : - QObject(), - QGraphicsItemGroup() + QObject(), + QGraphicsItemGroup() { setZValue(1); setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable); @@ -53,7 +53,20 @@ int AbstractGroupItem::type() const int AbstractGroupItem::track() const { - return (int)(scenePos().y() / KdenliveSettings::trackheight()); + //return (int)(scenePos().y() / KdenliveSettings::trackheight()); + int topTrack = -1; + QList children = childItems(); + for (int i = 0; i < children.count(); ++i) { + if (children.at(i)->type() == GROUPWIDGET) { + children.append(children.at(i)->childItems()); + continue; + } + AbstractClipItem *item = static_cast (children.at(i)); + if (item && (topTrack == -1 || topTrack > item->track())) { + topTrack = item->track(); + } + } + return topTrack; } void AbstractGroupItem::setItemLocked(bool locked) @@ -79,21 +92,26 @@ CustomTrackScene* AbstractGroupItem::projectScene() return NULL; } -QPainterPath AbstractGroupItem::clipGroupShape(QPointF offset) const +QPainterPath AbstractGroupItem::clipGroupSpacerShape(const QPointF &offset) const +{ + return spacerGroupShape(AVWIDGET, offset); +} + +QPainterPath AbstractGroupItem::clipGroupShape(const QPointF &offset) const { return groupShape(AVWIDGET, offset); } -QPainterPath AbstractGroupItem::transitionGroupShape(QPointF offset) const +QPainterPath AbstractGroupItem::transitionGroupShape(const QPointF &offset) const { return groupShape(TRANSITIONWIDGET, offset); } -QPainterPath AbstractGroupItem::groupShape(GRAPHICSRECTITEM type, QPointF offset) const +QPainterPath AbstractGroupItem::groupShape(GRAPHICSRECTITEM type, const QPointF &offset) const { QPainterPath path; QList children = childItems(); - for (int i = 0; i < children.count(); i++) { + for (int i = 0; i < children.count(); ++i) { if (children.at(i)->type() == (int)type) { QRectF r(children.at(i)->sceneBoundingRect()); r.translate(offset); @@ -112,10 +130,40 @@ QPainterPath AbstractGroupItem::groupShape(GRAPHICSRECTITEM type, QPointF offset return path; } +QPainterPath AbstractGroupItem::spacerGroupShape(GRAPHICSRECTITEM type, const QPointF &offset) const +{ + QPainterPath path; + QList children = childItems(); + for (int i = 0; i < children.count(); ++i) { + if (children.at(i)->type() == (int)type) { + QRectF r(children.at(i)->sceneBoundingRect()); + r.translate(offset); + r.setRight(scene()->width()); + path.addRect(r); + } else if (children.at(i)->type() == GROUPWIDGET) { + QList subchildren = children.at(i)->childItems(); + for (int j = 0; j < subchildren.count(); j++) { + if (subchildren.at(j)->type() == (int)type) { + QRectF r(subchildren.at(j)->sceneBoundingRect()); + r.translate(offset); + r.setRight(scene()->width()); + path.addRect(r); + } + } + } + } + return path; +} + void AbstractGroupItem::addItem(QGraphicsItem * item) { addToGroup(item); - //fixItemRect(); + item->setFlag(QGraphicsItem::ItemIsMovable, false); +} + +void AbstractGroupItem::removeItem(QGraphicsItem * item) +{ + removeFromGroup(item); } void AbstractGroupItem::fixItemRect() @@ -140,15 +188,13 @@ void AbstractGroupItem::paint(QPainter *p, const QStyleOptionGraphicsItem *optio QColor bgcolor(100, 100, 200, 100); QRectF bound = option->exposedRect.adjusted(0, 0, 1, 1); p->setClipRect(bound); - const QRectF mapped = p->worldTransform().mapRect(option->exposedRect); - p->setWorldMatrixEnabled(false); p->setBrush(bgcolor); QPen pen = p->pen(); pen.setColor(QColor(200, 90, 90)); pen.setStyle(Qt::DashLine); pen.setWidthF(0.0); p->setPen(pen); - p->drawRoundedRect(mapped, 3, 3); + p->drawRoundedRect(boundingRect().adjusted(0, 0, -1, 0), 3, 3); } //virtual @@ -166,21 +212,25 @@ QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant int xpos = projectScene()->getSnapPointForPos((int)(start.x() + newPos.x() - pos().x()), KdenliveSettings::snaptopoints()); xpos = qMax(xpos, 0); - //kDebug()<<"GRP XPOS:"< groupTracks; QList children = childItems(); - for (int i = 0; i < children.count(); i++) { + for (int i = 0; i < children.count(); ++i) { int currentTrack = 0; - if (children.at(i)->type() == AVWIDGET || children.at(i)->type() == TRANSITIONWIDGET) currentTrack = static_cast (children.at(i))->track(); - else if (children.at(i)->type() == GROUPWIDGET) currentTrack = static_cast (children.at(i))->track(); - else continue; + if (children.at(i)->type() == AVWIDGET || children.at(i)->type() == TRANSITIONWIDGET) { + currentTrack = static_cast (children.at(i))->track(); + if (!groupTracks.contains(currentTrack)) groupTracks.append(currentTrack); + } + else if (children.at(i)->type() == GROUPWIDGET) { + currentTrack = static_cast (children.at(i))->track(); + } + else continue; if (children.at(i)->type() == AVWIDGET) { if (topTrack == -1 || currentTrack <= topTrack) { offset = 0; @@ -195,9 +245,10 @@ QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant QList subchildren = children.at(i)->childItems(); bool clipGroup = false; for (int j = 0; j < subchildren.count(); j++) { - if (subchildren.at(j)->type() == AVWIDGET) { + if (subchildren.at(j)->type() == AVWIDGET || subchildren.at(j)->type() == TRANSITIONWIDGET) { + int subTrack = static_cast (subchildren.at(j))->track(); + if (!groupTracks.contains(subTrack)) groupTracks.append(subTrack); clipGroup = true; - break; } } if (clipGroup) { @@ -213,6 +264,24 @@ QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant } } } + // Check no clip in the group goes outside of existing tracks + int maximumTrack = projectScene()->tracksCount() - 1; + int groupHeight = 0; + for (int i = 0; i < groupTracks.count(); ++i) { + int offset = groupTracks.at(i) - topTrack; + if (offset > groupHeight) groupHeight = offset; + } + maximumTrack -= groupHeight; + proposedTrack = qMin(proposedTrack, maximumTrack); + proposedTrack = qMax(proposedTrack, 0); + int groupOffset = proposedTrack - topTrack; + if (!lockedTracks.isEmpty()) { + for (int i = 0; i < groupTracks.count(); ++i) { + if (lockedTracks.contains(QString::number(groupTracks.at(i) + groupOffset))) { + return pos(); + } + } + } newPos.setY((int)((proposedTrack) * trackHeight) + offset); //if (newPos == start) return start; @@ -227,7 +296,7 @@ QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant shape = clipGroupShape(newPos - pos()); collidingItems = scene()->items(shape, Qt::IntersectsItemShape); collidingItems.removeAll(this); - for (int i = 0; i < children.count(); i++) { + for (int i = 0; i < children.count(); ++i) { if (children.at(i)->type() == GROUPWIDGET) { QList subchildren = children.at(i)->childItems(); for (int j = 0; j < subchildren.count(); j++) { @@ -240,7 +309,7 @@ QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant if (!collidingItems.isEmpty()) { bool forwardMove = xpos > start.x(); int offset = 0; - for (int i = 0; i < collidingItems.count(); i++) { + for (int i = 0; i < collidingItems.count(); ++i) { QGraphicsItem *collision = collidingItems.at(i); if (collision->type() == AVWIDGET) { // Collision @@ -273,7 +342,7 @@ QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant // If there is still a collision after our position adjust, restore original pos collidingItems = scene()->items(clipGroupShape(newPos - pos()), Qt::IntersectsItemShape); collidingItems.removeAll(this); - for (int i = 0; i < children.count(); i++) { + for (int i = 0; i < children.count(); ++i) { if (children.at(i)->type() == GROUPWIDGET) { QList subchildren = children.at(i)->childItems(); for (int j = 0; j < subchildren.count(); j++) { @@ -282,7 +351,7 @@ QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant } collidingItems.removeAll(children.at(i)); } - for (int i = 0; i < collidingItems.count(); i++) + for (int i = 0; i < collidingItems.count(); ++i) if (collidingItems.at(i)->type() == AVWIDGET) return pos(); } } @@ -291,7 +360,7 @@ QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant shape = transitionGroupShape(newPos - pos()); collidingItems = scene()->items(shape, Qt::IntersectsItemShape); collidingItems.removeAll(this); - for (int i = 0; i < children.count(); i++) { + for (int i = 0; i < children.count(); ++i) { if (children.at(i)->type() == GROUPWIDGET) { QList subchildren = children.at(i)->childItems(); for (int j = 0; j < subchildren.count(); j++) { @@ -305,7 +374,7 @@ QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant else { bool forwardMove = xpos > start.x(); int offset = 0; - for (int i = 0; i < collidingItems.count(); i++) { + for (int i = 0; i < collidingItems.count(); ++i) { QGraphicsItem *collision = collidingItems.at(i); if (collision->type() == TRANSITIONWIDGET) { // Collision @@ -337,10 +406,10 @@ QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant } // If there is still a collision after our position adjust, restore original pos collidingItems = scene()->items(transitionGroupShape(newPos - pos()), Qt::IntersectsItemShape); - for (int i = 0; i < children.count(); i++) { + for (int i = 0; i < children.count(); ++i) { collidingItems.removeAll(children.at(i)); } - for (int i = 0; i < collidingItems.count(); i++) + for (int i = 0; i < collidingItems.count(); ++i) if (collidingItems.at(i)->type() == TRANSITIONWIDGET) return pos(); } } @@ -361,12 +430,12 @@ void AbstractGroupItem::dropEvent(QGraphicsSceneDragDropEvent * event) QPointF dropPos = event->scenePos(); QList selection = scene()->items(dropPos); AbstractClipItem *dropChild = NULL; - for (int i = 0; i < selection.count(); i++) { - if (selection.at(i)->type() == AVWIDGET) { + for (int i = 0; i < selection.count(); ++i) { + if (selection.at(i)->type() == AVWIDGET) { dropChild = (AbstractClipItem *) selection.at(i); - break; + break; } - } + } if (view) view->slotAddGroupEffect(e, this, dropChild); } @@ -387,7 +456,17 @@ void AbstractGroupItem::mousePressEvent(QGraphicsSceneMouseEvent * event) if (event->modifiers() & Qt::ShiftModifier) { // User want to do a rectangle selection, so ignore the event to pass it to the view event->ignore(); - } else QGraphicsItem::mousePressEvent(event); + } else { + QList list = scene()->items(event->scenePos()); + // only allow group move if we click over an item in the group + foreach(const QGraphicsItem *item, list) { + if (item->type() == TRANSITIONWIDGET || item->type() == AVWIDGET) { + QGraphicsItem::mousePressEvent(event); + return; + } + } + event->ignore(); + } } void AbstractGroupItem::resizeStart(int diff) @@ -475,3 +554,5 @@ GenTime AbstractGroupItem::duration() } return end - start; } + +#include "abstractgroupitem.moc"