diff options
author | Mahmoud Badri <mahmoud.badri@qt.io> | 2018-05-25 10:43:35 +0300 |
---|---|---|
committer | Mahmoud Badri <mahmoud.badri@qt.io> | 2018-05-29 12:48:08 +0000 |
commit | be7b024ca0933d1ccac960cd0f38731438227524 (patch) | |
tree | 31f46f33ae9b445d24a99b8273c7e3db6f1b97bd /src/Authoring/Studio/Palettes/TimelineGraphicsView/RowMover.cpp | |
parent | 8175869f2787e2059a1e61cc8c8fedf313d41274 (diff) |
implement DnD auto scroll, expand, and collapse functionalities
- While Dragging a row, hover over a container row and it will auto
expand. Hover out of it and it will auto collapse.
- Hover over the top or the bottom of the tree list and it will auto
scroll.
- While DnD is active, currently hovered row is highlighted so that auto
expand/collapse is more clear.
Task-number: QT3DS-1711
Change-Id: I00680bb9e8b00530b257ca7a39a9789b7b040a5a
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Diffstat (limited to 'src/Authoring/Studio/Palettes/TimelineGraphicsView/RowMover.cpp')
-rw-r--r-- | src/Authoring/Studio/Palettes/TimelineGraphicsView/RowMover.cpp | 75 |
1 files changed, 58 insertions, 17 deletions
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowMover.cpp b/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowMover.cpp index 1d367873..80aad3e5 100644 --- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowMover.cpp +++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowMover.cpp @@ -43,6 +43,19 @@ RowMover::RowMover(TimelineGraphicsScene *scene) { setZValue(99); setGeometry(0, 0, TimelineConstants::TREE_MAX_W, 10); + + m_autoExpandTimer.setSingleShot(true); + connect(&m_autoExpandTimer, &QTimer::timeout, [this]() { + if (m_rowAutoExpand) { + m_rowAutoExpand->updateExpandStatus(RowTree::ExpandState::Expanded, true); + // Update RowMover after the expansion. The +50 below is just a small margin to ensure + // correct row heights before updateTargetRowLater is called. + QTimer::singleShot(TimelineConstants::EXPAND_ANIMATION_DURATION + 50, [this]() { + if (updateTargetRowLater) + updateTargetRowLater(); + }); + } + }); } void RowMover::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) @@ -50,15 +63,12 @@ void RowMover::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, Q_UNUSED(option) Q_UNUSED(widget) - painter->save(); - + static const QPolygon polygon({QPoint(0, 0), QPoint(0, 3), QPoint(7, 3), QPoint(7, 1), + QPoint(TimelineConstants::TREE_BOUND_W, 1), + QPoint(TimelineConstants::TREE_BOUND_W, 0)}); painter->setPen(QPen(QColor(TimelineConstants::ROW_MOVER_COLOR), 1)); - painter->drawLine(0, 0, TimelineConstants::TREE_BOUND_W, 0); - - painter->setPen(QPen(QColor(TimelineConstants::ROW_MOVER_COLOR), 4)); - painter->drawLine(0, 2, 5, 2); - - painter->restore(); + painter->setBrush(QColor(TimelineConstants::ROW_MOVER_COLOR)); + painter->drawConvexPolygon(polygon); } RowTree *RowMover::insertionTarget() const @@ -79,13 +89,13 @@ QVector<RowTree *> RowMover::sourceRows() const void RowMover::resetInsertionParent(RowTree *newParent) { if (m_insertionParent) { - m_insertionParent->setMoveTarget(false); + m_insertionParent->setDnDState(RowTree::DnDState::None, RowTree::DnDState::Parent); m_insertionParent = nullptr; } if (newParent) { m_insertionParent = newParent; - m_insertionParent->setMoveTarget(true); + m_insertionParent->setDnDState(RowTree::DnDState::Parent, RowTree::DnDState::None); } else { m_insertionTarget = nullptr; } @@ -116,7 +126,7 @@ void RowMover::start(const QVector<RowTree *> &rows) if (!m_sourceRows.isEmpty()) { m_active = true; for (auto row : qAsConst(m_sourceRows)) - row->setMoveSourceRecursive(true); + row->setDnDState(RowTree::DnDState::Source, RowTree::DnDState::None, true); qApp->setOverrideCursor(Qt::ClosedHandCursor); } } @@ -127,20 +137,22 @@ void RowMover::end(bool force) if (m_active || force) { m_active = false; for (auto row : qAsConst(m_sourceRows)) - row->setMoveSourceRecursive(false); + row->setDnDState(RowTree::DnDState::None, RowTree::DnDState::Any, true); m_sourceRows.clear(); setVisible(false); resetInsertionParent(); - + updateTargetRowLater = {}; qApp->changeOverrideCursor(Qt::ArrowCursor); qApp->restoreOverrideCursor(); + + m_autoExpandTimer.stop(); } } void RowMover::updateState(int depth, double y) { - setPos(25 + depth * TimelineConstants::ROW_DEPTH_STEP, y); + setPos(24 + depth * TimelineConstants::ROW_DEPTH_STEP, y); setVisible(true); } @@ -158,6 +170,18 @@ RowTree *RowMover::getRowAtPos(const QPointF &scenePos) return nullptr; } +bool RowMover::isSourceRowsDescendant(const RowTree *row) const +{ + if (row) { + for (auto sourceRow : qAsConst(m_sourceRows)) { + if (row == sourceRow || row->isDecendentOf(sourceRow)) + return true; + } + } + + return false; +} + // rowType parameter is used to highlight the target row when RowMover is not active, // i.e. when dragging from project or basic objects palettes void RowMover::updateTargetRow(const QPointF &scenePos, EStudioObjectType rowType) @@ -188,10 +212,12 @@ void RowMover::updateTargetRow(const QPointF &scenePos, EStudioObjectType rowTyp int depth; int depthMin = rowInsert2 ? rowInsert2->depth() : (theRowType == OBJTYPE_LAYER ? 2 : 3); int depthMax = rowInsert1->depth(); - if (rowInsert1->isContainer() && !m_sourceRows.contains(rowInsert1)) + if (!rowInsert1->locked() && rowInsert1->isContainer() + && !m_sourceRows.contains(rowInsert1)) { depthMax++; // Container: allow insertion as a child - else if (rowInsert1->isPropertyOrMaterial() && !rowInsert1->parentRow()->isContainer()) + } else if (rowInsert1->isPropertyOrMaterial() && !rowInsert1->parentRow()->isContainer()) { depthMax--; // non-container with properties and/or a material + } if (theRowType == OBJTYPE_LAYER) { depth = 2; // layers can only be moved on depth 2 @@ -265,11 +291,26 @@ void RowMover::updateTargetRow(const QPointF &scenePos, EStudioObjectType rowTyp && m_insertionTarget->index() - m_sourceRows[0]->index() == 1)))) { valid = false; } - if (valid) + if (valid) { updateState(depth, rowInsert1->y() + TimelineConstants::ROW_H); + + // auto expand + if (!rowInsert1->locked() && !rowInsert1->expanded() && rowInsert1->isContainer() + && !rowInsert1->empty() && !isSourceRowsDescendant(rowInsert1)) { + updateTargetRowLater = std::bind(&RowMover::updateTargetRow, this, + scenePos, rowType); + m_rowAutoExpand = rowInsert1; + m_autoExpandTimer.start(TimelineConstants::AUTO_EXPAND_Time); + } else { + m_rowAutoExpand = nullptr; + m_autoExpandTimer.stop(); + } + } } if (!valid) { + m_rowAutoExpand = nullptr; + m_autoExpandTimer.stop(); setVisible(false); resetInsertionParent(); } |