X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fabstractgroupitem.cpp;h=ff66ac007b57f56af46c9fe835d6d18e0dc53b76;hb=95231df40ffdcd433b080b9dad205dd66ea3b2a0;hp=79364deb60109700e0b875eacbbcf532c33f4fbd;hpb=5f58037fe6286c608fc74bf3b08dd467b5630954;p=kdenlive diff --git a/src/abstractgroupitem.cpp b/src/abstractgroupitem.cpp index 79364deb..ff66ac00 100644 --- a/src/abstractgroupitem.cpp +++ b/src/abstractgroupitem.cpp @@ -32,6 +32,7 @@ #include #include + AbstractGroupItem::AbstractGroupItem(double /* fps */) : QObject(), QGraphicsItemGroup() @@ -52,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) @@ -114,7 +128,12 @@ QPainterPath AbstractGroupItem::groupShape(GRAPHICSRECTITEM type, QPointF offset void AbstractGroupItem::addItem(QGraphicsItem * item) { addToGroup(item); - //fixItemRect(); + item->setFlag(QGraphicsItem::ItemIsMovable, false); +} + +void AbstractGroupItem::removeItem(QGraphicsItem * item) +{ + removeFromGroup(item); } void AbstractGroupItem::fixItemRect() @@ -136,18 +155,16 @@ void AbstractGroupItem::fixItemRect() // virtual void AbstractGroupItem::paint(QPainter *p, const QStyleOptionGraphicsItem *option, QWidget *) { - const double scale = option->matrix.m11(); QColor bgcolor(100, 100, 200, 100); QRectF bound = option->exposedRect.adjusted(0, 0, 1, 1); p->setClipRect(bound); - p->fillRect(option->exposedRect, bgcolor); + p->setBrush(bgcolor); QPen pen = p->pen(); pen.setColor(QColor(200, 90, 90)); pen.setStyle(Qt::DashLine); pen.setWidthF(0.0); - //pen.setCosmetic(true); p->setPen(pen); - p->drawRect(boundingRect().adjusted(0, 0, - 1 / scale, 0)); + p->drawRoundedRect(boundingRect().adjusted(0, 0, -1, 0), 3, 3); } //virtual @@ -167,23 +184,23 @@ QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant xpos = qMax(xpos, 0); //kDebug()<<"GRP XPOS:"<tracksCount() - (int)(boundingRect().height() + 5) / trackHeight); - correctedTrack = qMax(correctedTrack, 0); - - proposedTrack += (correctedTrack - realTrack); - + QStringList lockedTracks = property("locked_tracks").toStringList(); + int proposedTrack = (property("y_absolute").toInt() + newPos.y()) / trackHeight; // Check if top item is a clip or a transition int offset = 0; int topTrack = -1; + QList groupTracks; QList children = childItems(); for (int i = 0; i < children.count(); i++) { - int currentTrack = (int)(children.at(i)->scenePos().y() / trackHeight); + int currentTrack = 0; + 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; @@ -198,9 +215,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) { @@ -216,6 +234,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; @@ -359,8 +395,18 @@ void AbstractGroupItem::dropEvent(QGraphicsSceneDragDropEvent * event) QDomDocument doc; doc.setContent(effects, true); QDomElement e = doc.documentElement(); + e.setAttribute("kdenlive_ix", 0); CustomTrackView *view = (CustomTrackView *) scene()->views()[0]; - if (view) view->slotAddGroupEffect(e, this); + 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) { + dropChild = (AbstractClipItem *) selection.at(i); + break; + } + } + if (view) view->slotAddGroupEffect(e, this, dropChild); } //virtual @@ -380,7 +426,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)