diff options
author | Mahmoud Badri <mahmoud.badri@qt.io> | 2018-05-09 12:24:38 +0300 |
---|---|---|
committer | Mahmoud Badri <mahmoud.badri@qt.io> | 2018-05-09 09:33:52 +0000 |
commit | 8dbaa56ecd6cb56a617eb9c9156b037a48e59a71 (patch) | |
tree | a293afec940abe2c3894cb649b8a77de5d75be9a /src/Authoring/Studio | |
parent | 4037748fd38f7a30f92930f800e7f74a5469c4d0 (diff) |
Support drag&drop objects into timeline
Implement dragging items from the "Basic Objects" and project assets to
the timeline tree part.
Task-number: QT3DS-1455
Change-Id: Iafb58d647221c63dcaa5ac9cced3ab9ee8de2a68
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
Diffstat (limited to 'src/Authoring/Studio')
15 files changed, 304 insertions, 199 deletions
diff --git a/src/Authoring/Studio/Controls/Control.h b/src/Authoring/Studio/Controls/Control.h index 7beccd8e..b0079d31 100644 --- a/src/Authoring/Studio/Controls/Control.h +++ b/src/Authoring/Studio/Controls/Control.h @@ -117,7 +117,7 @@ public: virtual CPt GetSize() const; virtual void SetSize(CPt inSize); - void SetSize(long inWidth, long inHeight); + virtual void SetSize(long inWidth, long inHeight); virtual void OnSizeChanged(CPt inSize); virtual CPt GetMinimumSize(); diff --git a/src/Authoring/Studio/DragAndDrop/DropSource.cpp b/src/Authoring/Studio/DragAndDrop/DropSource.cpp index bd764dd4..190eb95a 100644 --- a/src/Authoring/Studio/DragAndDrop/DropSource.cpp +++ b/src/Authoring/Studio/DragAndDrop/DropSource.cpp @@ -41,6 +41,9 @@ #include "TimelineDropSource.h" #include "BasicObjectDropSource.h" #include "ListBoxDropSource.h" +#include "Views.h" +#include "MainFrm.h" +#include "TimelineWidget.h" CDropSource::CDropSource(long inFlavor, unsigned long inSize) : m_Flavor(inFlavor) @@ -49,10 +52,12 @@ CDropSource::CDropSource(long inFlavor, unsigned long inSize) , m_HasValidTarget(false) , m_CurrentFlags(0) { + g_StudioApp.GetViews()->getMainFrame()->getTimelineWidget()->enableDnD(); } CDropSource::~CDropSource() { + g_StudioApp.GetViews()->getMainFrame()->getTimelineWidget()->enableDnD(false); } CDropSource *CDropSourceFactory::Create(long inFlavor, void *inData, unsigned long inSize) diff --git a/src/Authoring/Studio/MainFrm.cpp b/src/Authoring/Studio/MainFrm.cpp index 0aace15e..bdca8bc2 100644 --- a/src/Authoring/Studio/MainFrm.cpp +++ b/src/Authoring/Studio/MainFrm.cpp @@ -60,6 +60,7 @@ #include "TimelineWidget.h" #include "ProjectView.h" #include "RowTree.h" +#include "WidgetControl.h" #include <QtGui/qevent.h> #include <QtGui/qdesktopservices.h> @@ -1845,8 +1846,9 @@ void CMainFrame::OnConnectionChanged(bool connected) TimelineWidget *CMainFrame::getTimelineWidget() const { - return static_cast<TimelineWidget *>(m_paletteManager->GetControl( - CPaletteManager::CONTROLTYPE_TIMELINE)->widget()); + WidgetControl *control = static_cast<WidgetControl *> + (m_paletteManager->GetControl(CPaletteManager::CONTROLTYPE_TIMELINE)->widget()); + return static_cast<TimelineWidget *>(control->getControl()); } CRecentItems *CMainFrame::GetRecentItems() diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowManager.cpp b/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowManager.cpp index fbca0934..eb78c31d 100644 --- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowManager.cpp +++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowManager.cpp @@ -141,7 +141,7 @@ RowTree *RowManager::createRow(EStudioObjectType rowType, RowTree *parentRow, co qWarning() << __FUNCTION__ << "Property row cannot have children. No row added."; } else { // If the row doesnt have a parent, insert it under the scene (first row is the tree header) - if (parentRow == nullptr && rowType != OBJTYPE_SCENE && m_layoutTree->count() > 1) + if (!parentRow && rowType != OBJTYPE_SCENE && m_layoutTree->count() > 1) parentRow = static_cast<RowTree *>(m_layoutTree->itemAt(1)); RowTree *rowTree = nullptr; @@ -168,18 +168,13 @@ RowTree *RowManager::createRow(EStudioObjectType rowType, RowTree *parentRow, co return nullptr; } -RowTree *RowManager::getRowAbove(RowTree *row) +RowTree *RowManager::getNextSiblingRow(RowTree *row) const { - int rowIndex = getRowIndex(row); - - if (rowIndex > 1) { - RowTree *rowAbove = static_cast<RowTree *>(m_layoutTree->itemAt(rowIndex - 1)); - - if (rowAbove) { - while (rowAbove && rowAbove->depth() > row->depth()) - rowAbove = rowAbove->parentRow(); - - return rowAbove; + if (row && m_layoutTree->count() > 1) { + for (int i = row->indexInLayout() + 1; i < m_layoutTree->count(); ++i) { + RowTree *row_i = static_cast<RowTree *>(m_layoutTree->itemAt(i)->graphicsItem()); + if (row_i->depth() <= row->depth()) + return row_i; } } @@ -209,7 +204,7 @@ RowTimeline *RowManager::rowTimelineAt(int idx) // Call this to select/unselect row, affecting bindings void RowManager::selectRow(RowTree *row, bool multiSelect) { - if (row == nullptr) + if (!row) return; if (row->isProperty()) @@ -269,7 +264,7 @@ void RowManager::updateRulerDuration() void RowManager::updateFiltering(RowTree *row) { - if (row == nullptr) { // update all rows + if (!row) { // update all rows RowTree *row_i; for (int i = 1; i < m_layoutTree->count(); ++i) { row_i = static_cast<RowTree *>(m_layoutTree->itemAt(i)->graphicsItem()); @@ -293,7 +288,7 @@ void RowManager::updateRowFilterRecursive(RowTree *row) void RowManager::updateRowFilter(RowTree *row) { - bool parentOk = row->parentRow() == nullptr || row->parentRow()->isVisible(); + bool parentOk = !row->parentRow()|| row->parentRow()->isVisible(); bool shyOk = !row->shy() || !m_scene->treeHeader()->filterShy(); bool visibleOk = row->visible() || !m_scene->treeHeader()->filterHidden(); bool lockOk = !row->locked() || !m_scene->treeHeader()->filterLocked(); @@ -306,10 +301,6 @@ void RowManager::updateRowFilter(RowTree *row) void RowManager::deleteRow(RowTree *row) { if (row && row->rowType() != OBJTYPE_SCENE) { - auto rowAbove = getRowAbove(row); - if (rowAbove) - selectRow(rowAbove); - if (row->parentRow()) row->parentRow()->removeChild(row); diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowManager.h b/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowManager.h index b74207e3..2b0778d2 100644 --- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowManager.h +++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowManager.h @@ -67,7 +67,7 @@ public: const QString &label = QString(), const QString &propType = QString(), int index = -1); RowTree *rowAt(int idx); - RowTree *getRowAbove(RowTree *row); + RowTree *getNextSiblingRow(RowTree *row) const; RowTree *selectedRow() const; QVector<RowTree *> selectedRows() const; RowTimeline *rowTimelineAt(int idx); diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowMover.cpp b/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowMover.cpp index c63d71fd..ca1ce405 100644 --- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowMover.cpp +++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowMover.cpp @@ -28,13 +28,18 @@ #include "RowMover.h" #include "RowTree.h" +#include "RowManager.h" +#include "TimelineGraphicsScene.h" #include "TimelineConstants.h" #include <QtGui/qpainter.h> #include <QtWidgets/qapplication.h> #include <QtWidgets/qgraphicsitem.h> +#include <QtWidgets/qgraphicslinearlayout.h> -RowMover::RowMover() : QGraphicsRectItem() +RowMover::RowMover(TimelineGraphicsScene *scene) + : QGraphicsRectItem() + , m_scene(scene) { setZValue(99); setRect(0, -5, TimelineConstants::TREE_MAX_W, 10); @@ -88,21 +93,23 @@ bool RowMover::isActive() void RowMover::start(RowTree *row) { - m_sourceRow = row; m_active = true; - m_sourceRow->setMoveSourceRecursive(true); - - qApp->setOverrideCursor(Qt::ClosedHandCursor); + if (row) { + m_sourceRow = row; + m_sourceRow->setMoveSourceRecursive(true); + qApp->setOverrideCursor(Qt::ClosedHandCursor); + } } -void RowMover::end() +void RowMover::end(bool force) { - if (m_active) { - m_sourceRow->setMoveSourceRecursive(false); - + if (m_active || force) { m_active = false; - m_sourceRow = nullptr; + if (m_sourceRow) { + m_sourceRow->setMoveSourceRecursive(false); + m_sourceRow = nullptr; + } setVisible(false); resetInsertionParent(); @@ -112,7 +119,6 @@ void RowMover::end() } } - void RowMover::updateState(int index, int depth, int rawIndex) { m_targetIndex = index; @@ -121,17 +127,125 @@ void RowMover::updateState(int index, int depth, int rawIndex) setVisible(true); } -// TODO: not used, probably delete -bool RowMover::isValidMove(int index, RowTree *rowAtIndex) +void RowMover::updateTargetRow(int mouseX, int mouseY) +{ + int indexRaw = qRound((float)mouseY / TimelineConstants::ROW_H) - 1; + int indexInLayout = indexRaw; + m_scene->rowManager()->correctIndex(indexInLayout); + bool valid = indexInLayout != -1; + + RowTree *rowAtIndex; + RowTree *nextRowAtIndex; + + if (valid) { // valid row index + rowAtIndex = static_cast<RowTree *>(m_scene->layoutTree()->itemAt(indexInLayout) + ->graphicsItem()); + nextRowAtIndex = indexInLayout > m_scene->layoutTree()->count() - 2 ? nullptr : + static_cast<RowTree *>(m_scene->layoutTree()->itemAt(indexInLayout + 1) + ->graphicsItem()); + + if (!rowAtIndex->expanded()) + nextRowAtIndex = m_scene->rowManager()->getNextSiblingRow(rowAtIndex); + + // not moving an ancestor into a decendent + valid = (!m_sourceRow || !rowAtIndex->isDecendentOf(m_sourceRow)) + + // not inserting as a first child of self + && (!m_sourceRow || !(rowAtIndex == m_sourceRow && !rowAtIndex->empty())) + + // not inserting non-layer at root level + && !((!m_sourceRow || m_sourceRow->rowType() != OBJTYPE_LAYER) + && rowAtIndex->rowType() == OBJTYPE_SCENE) + + // Layer cases + && validLayerMove(rowAtIndex, nextRowAtIndex); + } + + if (valid) { + // if dragging over a property or a parent of a property, move to the first row + // after the property + if (rowAtIndex->isProperty()) + indexRaw = rowAtIndex->parentRow()->childProps().last()->indexInLayout(); + else if (rowAtIndex->hasPropertyChildren() && rowAtIndex->expanded()) + indexRaw = rowAtIndex->childProps().last()->indexInLayout(); + + // calc insertion depth + int depth; + if (m_sourceRow && m_sourceRow->rowType() == OBJTYPE_LAYER) { + depth = 2; // layers can only be moved on depth 2 + } else { + int depthMin = nextRowAtIndex ? nextRowAtIndex->depth() : 3; + int depthMax = rowAtIndex->depth(); + + if (rowAtIndex->isContainer() && rowAtIndex->expanded() + && rowAtIndex != m_sourceRow) { + depthMax++; // Container: allow insertion as a child + } else if (rowAtIndex->isPropertyOrMaterial() + && !rowAtIndex->parentRow()->isContainer()) { + depthMax--; // non-container with properties and/or a material + } + + static const int LEFT_MARGIN = 20; + static const int STEP = 15; + depth = (mouseX - LEFT_MARGIN) / STEP; + depth = qBound(depthMin, depth, depthMax); + } + + // calc insertion parent + RowTree *insertParent = rowAtIndex; + for (int i = rowAtIndex->depth(); i >= depth; --i) + insertParent = insertParent->parentRow(); + resetInsertionParent(insertParent); + + if (m_sourceRow && m_sourceRow->rowType() == OBJTYPE_MATERIAL + && m_sourceRow->parentRow() != m_insertionParent) { + valid = false; // not moving a material row outside its parent + } + + if (valid) { + // calc insertion index + int index = rowAtIndex->index() + 1; + if ((rowAtIndex->isProperty() && depth == rowAtIndex->depth()) + || rowAtIndex == insertParent) { + index = 0; + } else if (depth < rowAtIndex->depth()) { + RowTree *row = rowAtIndex; + for (int i = depth; i < rowAtIndex->depth(); ++i) + row = row->parentRow(); + index = row->index() + 1; + } + + if (m_sourceRow && insertParent == m_sourceRow->parentRow() + && index > m_sourceRow->index()) { + index--; + } + + updateState(index, depth, indexRaw); + } + } + + if (!valid) { + setVisible(false); + resetInsertionParent(); + } +} + +bool RowMover::validLayerMove(RowTree *rowAtIndex, RowTree *nextRowAtIndex) { - return - // not the same row - //index != m_currentIndex && + // we don't care about non-layers in this method + if (!m_sourceRow || m_sourceRow->rowType() != OBJTYPE_LAYER) + return true; - // not moving an ancestor into a decendent - !rowAtIndex->isDecendentOf(m_sourceRow) + if (rowAtIndex->rowType() == OBJTYPE_SCENE) + return true; + + if (rowAtIndex->rowType() == OBJTYPE_LAYER) + return rowAtIndex->empty() || !rowAtIndex->expanded(); + + if (!nextRowAtIndex || (nextRowAtIndex->depth() <= rowAtIndex->depth() + && nextRowAtIndex->depth() == 2)) { + return true; + } - // not at the top of an expanded object with property children - && (rowAtIndex->childRows().empty() || !rowAtIndex->childRows().first()->isProperty() - || !rowAtIndex->expanded()); + return false; } diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowMover.h b/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowMover.h index 23988c93..d9cc1ea8 100644 --- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowMover.h +++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowMover.h @@ -34,27 +34,29 @@ #include <QtWidgets/qgraphicsitem.h> class RowTree; +class TimelineGraphicsScene; class RowMover : public QGraphicsRectItem { public: - RowMover(); + RowMover(TimelineGraphicsScene *m_scene); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override; - void start(RowTree *row); - void end(); - void resetInsertionParent(RowTree *newTarget = nullptr); - void updateState(int index, int depth, int rawIndex); - - RowTree *insertionParent() const; - RowTree *sourceRow() const; - + void start(RowTree *row = nullptr); + void end(bool force = false); + void updateTargetRow(int mouseX, int mouseY); int targetIndex() const; bool isActive(); - bool isValidMove(int index, RowTree *rowAtIndex); + bool validLayerMove(RowTree *rowAtIndex, RowTree *nextRowAtIndex); + RowTree *insertionParent() const; + RowTree *sourceRow() const; private: + void updateState(int index, int depth, int rawIndex); + void resetInsertionParent(RowTree *newTarget = nullptr); + + TimelineGraphicsScene *m_scene = nullptr; RowTree *m_insertionParent = nullptr; // insertion parent RowTree *m_sourceRow = nullptr; // dragged row int m_targetIndex = -1; // insertion index diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp index 899be517..6bd995a9 100644 --- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp +++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp @@ -75,7 +75,7 @@ TimelineGraphicsScene::TimelineGraphicsScene(TimelineWidget *timelineWidget) , m_ruler(new Ruler) , m_playHead(new PlayHead(m_ruler)) , m_selectionRect(new SelectionRect(m_ruler)) - , m_rowMover(new RowMover) + , m_rowMover(new RowMover(this)) , m_widgetTimeline(timelineWidget) , m_widgetRoot(new QGraphicsWidget) , m_rowManager(new RowManager(this, m_layoutTree, m_layoutTimeline)) @@ -276,19 +276,6 @@ void TimelineGraphicsScene::commitMoveRows() // updating the UI happens in TimelineWidget.onChildAdded() } -RowTree *TimelineGraphicsScene::getNextSiblingRow(RowTree *row) const -{ - if (row && m_layoutTree->count() > 1) { - for (int i = row->indexInLayout() + 1; i < m_layoutTree->count(); ++i) { - RowTree *row_i = static_cast<RowTree *>(m_layoutTree->itemAt(i)->graphicsItem()); - if (row_i->depth() <= row->depth()) - return row_i; - } - } - - return nullptr; -} - // TODO: not used, remove bool TimelineGraphicsScene::lastRowInAParent(RowTree *rowAtIndex, int index) { @@ -305,25 +292,6 @@ int TimelineGraphicsScene::nextRowDepth(int index) { return static_cast<RowTree *>(m_layoutTree->itemAt(index)->graphicsItem())->depth(); } -bool TimelineGraphicsScene::validLayerMove(RowTree *rowAtIndex, RowTree *nextRowAtIndex) -{ - // we don't care about non-layers in this method - if (m_rowMover->sourceRow()->rowType() != OBJTYPE_LAYER) - return true; - - if (rowAtIndex->rowType() == OBJTYPE_SCENE) - return true; - - if (rowAtIndex->rowType() == OBJTYPE_LAYER) - return rowAtIndex->empty() || !rowAtIndex->expanded(); - - if (nextRowAtIndex == nullptr || (nextRowAtIndex->depth() <= rowAtIndex->depth() - && nextRowAtIndex->depth() == 2)) - return true; - - return false; -} - void TimelineGraphicsScene::updateTreeWidth(double treeWidth) { if (m_treeWidth != treeWidth) { @@ -487,107 +455,7 @@ void TimelineGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) // moving rows vertically (reorder/reparent) // collapse all properties so correctIndex() counts correctly m_rowManager->collapseAllPropertyRows(); - int indexRaw = qRound(event->scenePos().y() / TimelineConstants::ROW_H) - 1; - int indexInLayout = indexRaw; - m_rowManager->correctIndex(indexInLayout); - bool valid = indexInLayout != -1; - - RowTree *rowAtIndex; - RowTree *nextRowAtIndex; - - if (valid) { // valid row index - rowAtIndex = static_cast<RowTree *>(m_layoutTree->itemAt(indexInLayout) - ->graphicsItem()); - nextRowAtIndex = indexInLayout > m_layoutTree->count() - 2 ? nullptr : - static_cast<RowTree *>(m_layoutTree->itemAt(indexInLayout + 1) - ->graphicsItem()); - - if (!rowAtIndex->expanded()) - nextRowAtIndex = getNextSiblingRow(rowAtIndex); - - // not moving an ancestor into a decendent - valid = !rowAtIndex->isDecendentOf(m_rowMover->sourceRow()) - - // not inserting as a first child of self - && !(rowAtIndex == m_rowMover->sourceRow() && !rowAtIndex->empty()) - - // not inserting non-layer at root level - && !(m_rowMover->sourceRow()->rowType() != OBJTYPE_LAYER - && rowAtIndex->rowType() == OBJTYPE_SCENE) - - // Layer cases - && validLayerMove(rowAtIndex, nextRowAtIndex) - - // Not inserting into a component - && rowAtIndex->rowType() != OBJTYPE_COMPONENT; - } - - if (valid) { - // if dragging over a property or a parent of a property, move to the first row - // after the property - if (rowAtIndex->isProperty()) - indexRaw = rowAtIndex->parentRow()->childProps().last()->indexInLayout(); - else if (rowAtIndex->hasPropertyChildren() && rowAtIndex->expanded()) - indexRaw = rowAtIndex->childProps().last()->indexInLayout(); - - // calc insertion depth - int depth; - if (m_rowMover->sourceRow()->rowType() == OBJTYPE_LAYER) { - depth = 2; // layers can only be moved on depth 2 - } else { - int depthMin = nextRowAtIndex ? nextRowAtIndex->depth() : 3; - int depthMax = rowAtIndex->depth(); - - if (rowAtIndex->isContainer() && rowAtIndex->expanded() - && rowAtIndex != m_rowMover->sourceRow()) { - depthMax++; // Container: allow insertion as a child - } else if (rowAtIndex->isPropertyOrMaterial() - && !rowAtIndex->parentRow()->isContainer()) { - depthMax--; // non-container with properties and/or a material - } - - depth = (event->scenePos().x() - 20) / 15; - depth = qBound(depthMin, depth, depthMax); - } - - // calc insertion parent - RowTree *insertParent = rowAtIndex; - for (int i = rowAtIndex->depth(); i >= depth; --i) - insertParent = insertParent->parentRow(); - m_rowMover->resetInsertionParent(insertParent); - - if (m_rowMover->sourceRow()->rowType() == OBJTYPE_MATERIAL - && m_rowMover->sourceRow()->parentRow() - != m_rowMover->insertionParent()) { - valid = false; // not moving a material row outside its parent - } - - if (valid) { - // calc insertion index - int index = rowAtIndex->index() + 1; - if ((rowAtIndex->isProperty() && depth == rowAtIndex->depth()) - || rowAtIndex == insertParent) { - index = 0; - } else if (depth < rowAtIndex->depth()) { - RowTree *row = rowAtIndex; - for (int i = depth; i < rowAtIndex->depth(); ++i) - row = row->parentRow(); - index = row->index() + 1; - } - - if (insertParent == m_rowMover->sourceRow()->parentRow() - && index > m_rowMover->sourceRow()->index()) { - index--; - } - - m_rowMover->updateState(index, depth, indexRaw); - } - } - - if (!valid) { - m_rowMover->setVisible(false); - m_rowMover->resetInsertionParent(); - } + m_rowMover->updateTargetRow(event->scenePos().x(), event->scenePos().y()); } else if (m_keyframePressed) { // moving selected keyframes double newX = event->scenePos().x() - m_ruler->x() - m_pressPosInKeyframe; @@ -948,3 +816,4 @@ QGraphicsWidget *TimelineGraphicsScene::widgetRoot() const { return m KeyframeManager *TimelineGraphicsScene::keyframeManager() const { return m_keyframeManager; } QGraphicsLinearLayout *TimelineGraphicsScene::layoutTree() const { return m_layoutTree; } QGraphicsLinearLayout *TimelineGraphicsScene::layoutTimeline() const { return m_layoutTimeline; } +TimelineWidget *TimelineGraphicsScene::widgetTimeline() const { return m_widgetTimeline; } diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.h b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.h index 5271a3f6..ad46b87b 100644 --- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.h +++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.h @@ -76,6 +76,7 @@ public: QGraphicsLinearLayout *layoutTimeline() const; TreeHeader *treeHeader() const; double treeWidth() const; + TimelineWidget *widgetTimeline() const; void updateTreeWidth(double x); void setMouseCursor(CMouseCursor::Qt3DSMouseCursor cursor); void resetMouseCursor(); @@ -100,8 +101,6 @@ private: void snap(double &value, bool snapToPlayHead = true); int nextRowDepth(int index); bool lastRowInAParent(RowTree *rowAtIndex, int index); - bool validLayerMove(RowTree *rowAtIndex, RowTree *nextRowAtIndex); - RowTree *getNextSiblingRow(RowTree *row) const; QGraphicsItem *getItemBelowType(TimelineItem::ItemType type, QGraphicsItem *item, const QPointF &scenePos); diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineWidget.cpp b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineWidget.cpp index 6757f136..94b3977a 100644 --- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineWidget.cpp +++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineWidget.cpp @@ -53,6 +53,8 @@ #include "Bindings/Qt3DSDMTimelineItemProperty.h" #include "TimeEditDlg.h" #include "IDocumentEditor.h" +#include "Control.h" +#include "TimelineDropTarget.h" #include <QtGui/qevent.h> #include <QtWidgets/qgraphicslinearlayout.h> @@ -134,6 +136,8 @@ TimelineWidget::TimelineWidget(QWidget *parent) , m_viewTimelineContent(new QGraphicsView(this)) , m_graphicsScene(new TimelineGraphicsScene(this)) { + // Mahmoud_TODO: CTimelineTranslationManager should be eventually removed or cleaned. Already + // most of its functionality is implemented in this class m_translationManager = new CTimelineTranslationManager(); setWindowTitle(tr("Timeline", "Title of timeline view")); @@ -443,6 +447,7 @@ void TimelineWidget::onSelectionChange(Q3DStudio::SSelectedValue inNewSelectable if (theInstances.size() > 0) { for (size_t idx = 0, end = theInstances.size(); idx < end; ++idx) { qt3dsdm::Qt3DSDMInstanceHandle theInstance(theInstances[idx]); + if (g_StudioApp.GetCore()->GetDoc()->GetStudioSystem()->IsInstance(theInstance)) { auto *binding = getBindingForHandle(theInstance, m_binding); if (binding) @@ -641,6 +646,85 @@ void TimelineWidget::onChildMoved(int inParent, int inChild, long inOldIndex, } } +void TimelineWidget::OnDraw(CRenderer *inRenderer, CRct &inDirtyRect, bool inIgnoreValidation) +{ + +} + +void TimelineWidget::Draw(CRenderer *inRenderer) +{ + +} + +void TimelineWidget::OnGainFocus() +{ + +} + +CDropTarget *TimelineWidget::FindDropCandidate(CPt &inMousePoint, Qt::KeyboardModifiers inFlags) +{ + CTimeLineDropTarget *theTarget = new CTimeLineDropTarget(); + + int mouseY = inMousePoint.y - m_navigationBar->height() + + viewTreeContent()->verticalScrollBar()->value() + - viewTreeContent()->verticalScrollBar()->minimum(); + RowMover *mover = m_graphicsScene->rowMover(); + mover->updateTargetRow(inMousePoint.x, mouseY); + + if (mover->insertionParent()) { + RowTree *targetRow = mover->insertionParent()->getChildAt(mover->targetIndex()-1); + + if (targetRow) { + theTarget->SetDestination(EDROPDESTINATION_BELOW); + targetRow->getBinding()->SetDropTarget(theTarget); + } else { + if (mover->insertionParent()->childRows().empty()) { + theTarget->SetDestination(EDROPDESTINATION_ON); + mover->insertionParent()->getBinding()->SetDropTarget(theTarget); + } else { + theTarget->SetDestination(EDROPDESTINATION_ABOVE); + mover->insertionParent()->getChildAt(0)->getBinding()->SetDropTarget(theTarget); + } + } + } + + return theTarget; +} + +bool TimelineWidget::OnMouseHover(CPt inPoint, Qt::KeyboardModifiers inFlags) +{ + return true; +} + +void TimelineWidget::OnMouseOut(CPt inPoint, Qt::KeyboardModifiers inFlags) +{ +} + +void TimelineWidget::OnMouseUp(CPt inPoint, Qt::KeyboardModifiers inFlags) +{ +} + +CPt TimelineWidget::GetPreferredSize() +{ + return CPt(); +} + +void TimelineWidget::SetSize(long inX, long inY) +{ + setFixedSize(inX, inY); +} + +// If views are interactive they block the DnD. If we could think of a way to make them do not block +// DnD, then this method can be removed (and it's callers) +void TimelineWidget::enableDnD(bool b) +{ + m_viewTreeHeader->setInteractive(!b); + m_viewTreeContent->setInteractive(!b); + + if (!b) + m_graphicsScene->rowMover()->end(true); +} + Qt3DSDMTimelineItemBinding *TimelineWidget::getBindingForHandle(int handle, Qt3DSDMTimelineItemBinding *binding) const { diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineWidget.h b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineWidget.h index 85d6e3a6..9a90ea63 100644 --- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineWidget.h +++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineWidget.h @@ -39,6 +39,7 @@ #include "TreeHeaderView.h" #include "Bindings/Qt3DSDMTimeline.h" #include "NavigationBar.h" +#include "Control.h" class RowTree; class TimelineToolbar; @@ -52,7 +53,8 @@ QT_FORWARD_DECLARE_CLASS(QGraphicsView) class TimelineWidget : public QWidget, public CPresentationChangeListener, - public CClientPlayChangeListener + public CClientPlayChangeListener, + public CControl { Q_OBJECT @@ -64,10 +66,10 @@ public: QGraphicsView *viewTimelineContent() const; QGraphicsView *viewTreeContent() const; QVector<RowTree *> selectedRows() const; - void openBarColorDialog(); void onTimeBarColorChanged(const QColor &color); void setSelectedTimeBarsColor(const QColor &color, bool preview); + void enableDnD(bool b = true); // Presentation Change Listener void OnNewPresentation() override; @@ -78,6 +80,17 @@ public: void OnTimeChanged(long inTime) override; bool hasSelectedKeyframes() const; + // CControl + void OnDraw(CRenderer *inRenderer, CRct &inDirtyRect, bool inIgnoreValidation = false) override; + void Draw(CRenderer *inRenderer) override; + void OnGainFocus() override; + CDropTarget *FindDropCandidate(CPt &inMousePoint, Qt::KeyboardModifiers inFlags) override; + bool OnMouseHover(CPt inPoint, Qt::KeyboardModifiers inFlags) override; + void OnMouseOut(CPt inPoint, Qt::KeyboardModifiers inFlags) override; + void OnMouseUp(CPt inPoint, Qt::KeyboardModifiers inFlags) override; + CPt GetPreferredSize() override; + void SetSize(long inX, long inY) override; + protected: // DataModel callbacks virtual void onActiveSlide(const qt3dsdm::Qt3DSDMSlideHandle &inMaster, int inIndex, diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTree.cpp b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTree.cpp index 0882474f..9d4159d3 100644 --- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTree.cpp +++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTree.cpp @@ -538,6 +538,14 @@ int RowTree::addChildToLayout(RowTree *child, int indexInLayout) return indexInLayout; } +RowTree *RowTree::getChildAt(int index) const +{ + if (index < 0 || index > m_childRows.count() - 1) + return nullptr; + + return m_childRows.at(index); +} + // TODO: so far not used, delete if end up not used void RowTree::moveChild(int from, int to) { @@ -799,8 +807,12 @@ void RowTree::setMoveSourceRecursive(bool value) bool RowTree::isContainer() const { - return !m_isProperty && m_rowType != OBJTYPE_ALIAS && m_rowType != OBJTYPE_MATERIAL - && m_rowType != OBJTYPE_IMAGE && m_rowType != OBJTYPE_TEXT; + return !m_isProperty + && m_rowType != OBJTYPE_ALIAS + && m_rowType != OBJTYPE_MATERIAL + && m_rowType != OBJTYPE_IMAGE + && m_rowType != OBJTYPE_TEXT + && m_rowType != OBJTYPE_COMPONENT; } bool RowTree::isProperty() const diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTree.h b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTree.h index e1f83641..ccafcdf0 100644 --- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTree.h +++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTree.h @@ -104,6 +104,7 @@ public: int treeWidth() const; EStudioObjectType rowType() const; QString propertyType() const; + RowTree *getChildAt(int index) const; RowTree *parentRow() const; RowTree *getPropertyRow(const QString &type) const; QList<RowTree *> childRows() const; diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/TimelineToolbar.cpp b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/TimelineToolbar.cpp index e80d4b22..755913a6 100644 --- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/TimelineToolbar.cpp +++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/TimelineToolbar.cpp @@ -394,12 +394,13 @@ void TimelineToolbar::updateTimelineTitleColor(bool controlled) { QString styleString; if (controlled) { - styleString= "QDockWidget { color: " + styleString = "QDockWidget { color: " + QString(CStudioPreferences::dataInputColor().name()) + "; }"; } else { styleString = "QDockWidget { color: " + QString(CStudioPreferences::textColor().name()) + "; }"; } - QWidget *timelineDock = parentWidget()->parentWidget(); + + QWidget *timelineDock = parentWidget()->parentWidget()->parentWidget()->parentWidget(); timelineDock->setStyleSheet(styleString); } diff --git a/src/Authoring/Studio/_Win/Palettes/PaletteManager.cpp b/src/Authoring/Studio/_Win/Palettes/PaletteManager.cpp index be98cdac..03def618 100644 --- a/src/Authoring/Studio/_Win/Palettes/PaletteManager.cpp +++ b/src/Authoring/Studio/_Win/Palettes/PaletteManager.cpp @@ -108,11 +108,23 @@ CPaletteManager::CPaletteManager(CMainFrame *inMainFrame) inMainFrame->tabifyDockWidget(m_basicObjectsDock, m_slideDock); m_ControlList.insert(std::make_pair(CONTROLTYPE_BASICOBJECTS, m_basicObjectsDock)); - m_timelineGVDock = new QDockWidget(QObject::tr("Timeline GV"), inMainFrame); + m_timelineGVDock = new QDockWidget(QObject::tr("Timeline GV")); m_timelineGVDock->setObjectName("timeline GV."); m_timelineGVDock->setAllowedAreas(Qt::BottomDockWidgetArea); - m_timelineWidget = new TimelineWidget(m_timelineGVDock); - m_timelineGVDock->setWidget(m_timelineWidget); + + m_timelineWidget = new TimelineWidget(); + WidgetControl *timeLineWidgetControl = new WidgetControl(m_timelineWidget, m_timelineGVDock); + timeLineWidgetControl->RegisterForDnd(timeLineWidgetControl); + timeLineWidgetControl->AddMainFlavor(QT3DS_FLAVOR_LISTBOX); + timeLineWidgetControl->AddMainFlavor(QT3DS_FLAVOR_FILE); + timeLineWidgetControl->AddMainFlavor(QT3DS_FLAVOR_ASSET_UICFILE); + timeLineWidgetControl->AddMainFlavor(QT3DS_FLAVOR_ASSET_LIB); + timeLineWidgetControl->AddMainFlavor(QT3DS_FLAVOR_ASSET_TL); + timeLineWidgetControl->AddMainFlavor(QT3DS_FLAVOR_BASIC_OBJECTS); + + m_timelineWidget->setParent(timeLineWidgetControl); + + m_timelineGVDock->setWidget(timeLineWidgetControl); inMainFrame->addDockWidget(Qt::BottomDockWidgetArea, m_timelineGVDock); m_ControlList.insert(std::make_pair(CONTROLTYPE_TIMELINE, m_timelineGVDock)); |