diff options
Diffstat (limited to 'src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp')
-rw-r--r-- | src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp | 240 |
1 files changed, 135 insertions, 105 deletions
diff --git a/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp b/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp index b4a52760..bae5af8f 100644 --- a/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp +++ b/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp @@ -32,6 +32,7 @@ #include "Ruler.h" #include "PlayHead.h" #include "RowTree.h" +#include "RowTimelinePropertyGraph.h" #include "RowMover.h" #include "RowTimeline.h" #include "TimelineConstants.h" @@ -188,8 +189,7 @@ TimelineGraphicsScene::TimelineGraphicsScene(TimelineWidget *timelineWidget) // Resize keyframe selection rect const QPointF scenePoint = timelineContent->mapToScene(p); - timelineContent->ensureVisible(scenePoint.x(), scenePoint.y(), - 0, 0, 0, 0); + timelineContent->ensureVisible(scenePoint.x(), scenePoint.y(), 0, 0, 0, 0); QRectF visibleScene( timelineContent->mapToScene(contentRect.topLeft()), timelineContent->mapToScene(contentRect.bottomRight() @@ -226,7 +226,7 @@ TimelineGraphicsScene::TimelineGraphicsScene(TimelineWidget *timelineWidget) } if (m_dragging) { - if (m_clickedTimelineControlType == TimelineControlType::StartHandle) { + if (m_clickedTimelineControlType == TimelineControlType::DurationStartHandle) { double visiblePtX = distance > 0 ? m_editedTimelineRow->getStartX() : 0; if (distance > m_editedTimelineRow->getEndX()) visiblePtX += TimelineConstants::RULER_EDGE_OFFSET; @@ -237,7 +237,8 @@ TimelineGraphicsScene::TimelineGraphicsScene(TimelineWidget *timelineWidget) + TimelineConstants::RULER_EDGE_OFFSET + visiblePtX, m_editedTimelineRow->y(), 0, 0, 0, 0); - } else if (m_clickedTimelineControlType == TimelineControlType::EndHandle) { + } else if (m_clickedTimelineControlType + == TimelineControlType::DurationEndHandle) { long time = m_ruler->distanceToTime(distance); double edgeMargin = 0; if (time > TimelineConstants::MAX_SLIDE_TIME) { @@ -284,7 +285,7 @@ TimelineGraphicsScene::TimelineGraphicsScene(TimelineWidget *timelineWidget) }); QTimer::singleShot(0, this, [this]() { - m_playHead->setPosition(0); + m_playHead->setTime(0); m_widgetTimeline->viewTreeContent()->horizontalScrollBar()->setValue(0); }); @@ -343,6 +344,7 @@ TimelineGraphicsScene::~TimelineGraphicsScene() disconnect(qApp, &QApplication::focusChanged, this, &TimelineGraphicsScene::handleApplicationFocusLoss); delete m_dataInputSelector; + delete m_keyframeManager; } void TimelineGraphicsScene::setTimelineScale(int scl) @@ -368,22 +370,12 @@ void TimelineGraphicsScene::setControllerText(const QString &controller) void TimelineGraphicsScene::updateTimelineLayoutWidth() { double timelineWidth = TimelineConstants::RULER_EDGE_OFFSET * 2 - + m_ruler->maxDuration() * TimelineConstants::RULER_MILLI_W - * m_ruler->timelineScale(); + + m_ruler->timeToDistance(m_ruler->maxDuration()); m_layoutTimeline->setMinimumWidth(timelineWidth); m_layoutTimeline->setMaximumWidth(timelineWidth); } -void TimelineGraphicsScene::updateControllerLayoutWidth() -{ - if (m_layoutTimeline->count() < 2) - return; - auto root = m_layoutTimeline->itemAt(1); - - static_cast<RowTimeline *>(root->graphicsItem())->setEndTime(ruler()->duration()); -} - void TimelineGraphicsScene::updateController() { setControllerText(m_widgetTimeline->toolbar()->getCurrentController()); @@ -466,19 +458,34 @@ void TimelineGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event) { g_StudioApp.setLastActiveView(m_widgetTimeline); - if ((event->modifiers() & Qt::AltModifier) && !m_dragging) { - if (event->button() == Qt::RightButton && !m_timelinePanning) { - // Start zooming - m_timelineZooming = true; + if ((event->modifiers() & Qt::AltModifier) && !m_dragging + && m_timelineAltModifierMode == TimelineAltModifierMode::None) { + if (event->button() == Qt::RightButton) { + // Start scaling + m_timelineAltModifierMode = TimelineAltModifierMode::ScaleTimeline; m_pressScreenPos = event->screenPos(); event->accept(); return; - } else if (event->button() == Qt::MiddleButton && !m_timelineZooming) { + } else if (event->button() == Qt::MiddleButton) { // Start panning - m_timelinePanning = true; + m_timelineAltModifierMode = TimelineAltModifierMode::PanTimeline; m_pressPos = event->scenePos(); event->accept(); return; + } else if (event->button() == Qt::LeftButton) { + // Start property graph panning + m_pressPos = event->scenePos(); + QGraphicsItem *item = getItemAt(m_pressPos); + if (item && item->type() == TimelineItem::TypeRowTimeline) { + RowTimeline *rowTimeline = static_cast<RowTimeline *>(item); + if (rowTimeline->propertyGraph()) { + m_timelineAltModifierMode = TimelineAltModifierMode::PanPropertyGraph; + m_panProperyGraph = rowTimeline->propertyGraph(); + m_panProperyGraph->startPan(); + event->accept(); + return; + } + } } } @@ -494,10 +501,11 @@ void TimelineGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event) if (!m_widgetTimeline->isFullReconstructPending() && event->button() == Qt::LeftButton) { resetMousePressParams(); m_pressPos = event->scenePos(); - QGraphicsItem *item = itemAt(m_pressPos, QTransform()); + + QGraphicsItem *item = getItemAt(m_pressPos); + const bool ctrlKeyDown = event->modifiers() & Qt::ControlModifier; if (item) { - item = getItemBelowType(TimelineItem::TypePlayHead, item, m_pressPos); if (item->type() == TimelineItem::TypeRuler) { m_rulerPressed = true; m_autoScrollTimelineTimer.start(); @@ -506,9 +514,7 @@ void TimelineGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event) m_rowManager->updateFiltering(); updateSnapSteps(); } - } else if (item->type() == TimelineItem::TypeRowTree - || item->type() == TimelineItem::TypeRowTreeLabelItem) { - item = getItemBelowType(TimelineItem::TypeRowTreeLabelItem, item, m_pressPos); + } else if (item->type() == TimelineItem::TypeRowTree) { RowTree *rowTree = static_cast<RowTree *>(item); m_clickedTreeControlType = rowTree->getClickedControl(m_pressPos); if (m_clickedTreeControlType == TreeControlType::Shy @@ -520,7 +526,7 @@ void TimelineGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event) // Prepare to change selection to single selection at release if a multiselected // row is clicked without ctrl. if (!ctrlKeyDown && m_rowManager->isRowSelected(rowTree) - && !m_rowManager->isSingleSelected() ) { + && !m_rowManager->isSingleSelected()) { m_releaseSelectRow = rowTree; } m_rowManager->selectRow(rowTree, ctrlKeyDown); @@ -570,11 +576,13 @@ void TimelineGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event) m_rowManager->selectRow(m_editedTimelineRow->rowTree(), ctrlKeyDown); // click position in ruler space m_editedTimelineRow->startDurationMove(m_pressPos.x() - m_ruler->x()); - } else if (m_clickedTimelineControlType == TimelineControlType::StartHandle - || m_clickedTimelineControlType == TimelineControlType::EndHandle) { + } else if (m_clickedTimelineControlType + == TimelineControlType::DurationStartHandle + || m_clickedTimelineControlType + == TimelineControlType::DurationEndHandle) { m_editedTimelineRow->updateBoundChildren( m_clickedTimelineControlType - == TimelineControlType::StartHandle); + == TimelineControlType::DurationStartHandle); } m_autoScrollTimelineTimer.start(); } @@ -594,9 +602,9 @@ void TimelineGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event) void TimelineGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { - if (m_timelineZooming) { - int deltaY = event->screenPos().y() - m_pressScreenPos.y(); + if (m_timelineAltModifierMode == TimelineAltModifierMode::ScaleTimeline) { int deltaX = event->screenPos().x() - m_pressScreenPos.x(); + int deltaY = event->screenPos().y() - m_pressScreenPos.y(); // Zooming in when moving down/right. int delta = -deltaX - deltaY; const int threshold = 20; @@ -607,24 +615,31 @@ void TimelineGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) m_widgetTimeline->toolbar()->onZoomOutButtonClicked(); m_pressScreenPos = event->screenPos(); } - } else if (m_timelinePanning) { + } else if (m_timelineAltModifierMode == TimelineAltModifierMode::PanTimeline) { int deltaX = event->scenePos().x() - m_pressPos.x(); QScrollBar *scrollbar = m_widgetTimeline->viewTimelineContent()->horizontalScrollBar(); scrollbar->setValue(scrollbar->value() - deltaX); + } else if (m_timelineAltModifierMode == TimelineAltModifierMode::PanPropertyGraph) { + qreal deltaY = event->scenePos().y() - m_pressPos.y(); + m_panProperyGraph->pan(deltaY); } if (m_editedTimelineRow.isNull()) updateHoverStatus(event->scenePos()); - if (!m_dragging && !m_timelineZooming && !m_timelinePanning - && m_pressPos != invalidPoint - && (event->scenePos() - m_pressPos).manhattanLength() > 10) { + if (!m_dragging && m_timelineAltModifierMode == TimelineAltModifierMode::None + && m_pressPos != invalidPoint && (event->scenePos() - m_pressPos).manhattanLength() > 10) { m_dragging = true; } bool shift = event->modifiers() & Qt::ShiftModifier; if (m_dragging) { - if (m_startRowMoverOnNextDrag || m_rowMover->isActive()) { + if (m_clickedTimelineControlType & TimelineControlType::IsBezierControl) { + if (m_editedTimelineRow && m_editedTimelineRow->propertyGraph()) { + m_editedTimelineRow->propertyGraph()->updateBezierControlValue( + m_clickedTimelineControlType, event->scenePos()); + } + } else if (m_startRowMoverOnNextDrag || m_rowMover->isActive()) { // moving rows vertically (reorder/reparent) if (m_startRowMoverOnNextDrag) { m_startRowMoverOnNextDrag = false; @@ -696,14 +711,16 @@ void TimelineGraphicsScene::updateSnapSteps() // i = 1 is always the scene row (or component root) for (int i = 2; i < m_layoutTimeline->count(); i++) { RowTree *rowTree = static_cast<RowTree *>(m_layoutTree->itemAt(i)->graphicsItem()); - if (rowTree->hasDurationBar() && rowTree->isVisible()) { - double startX = rowTree->rowTimeline()->getStartX(); - if (!m_snapSteps.contains(startX)) - m_snapSteps.push_back(startX); - - double endX = rowTree->rowTimeline()->getEndX(); - if (!m_snapSteps.contains(endX)) - m_snapSteps.push_back(endX); + if (rowTree->isVisible()) { + if (rowTree->hasDurationBar()) { + double startX = rowTree->rowTimeline()->getStartX(); + if (!m_snapSteps.contains(startX)) + m_snapSteps.push_back(startX); + + double endX = rowTree->rowTimeline()->getEndX(); + if (!m_snapSteps.contains(endX)) + m_snapSteps.push_back(endX); + } // add keyframes times if (rowTree->hasPropertyChildren()) { @@ -723,17 +740,22 @@ TExpandMap &TimelineGraphicsScene::expandMap() return m_expandMap; } +TPropGraphHeightMap &TimelineGraphicsScene::propGraphHeightMap() +{ + return m_propGraphHeightMap; +} + void TimelineGraphicsScene::resetMousePressParams() { m_autoScrollTimelineTimer.stop(); m_selectionRect->end(); m_rowMover->end(); m_dragging = false; - m_timelineZooming = false; - m_timelinePanning = false; m_startRowMoverOnNextDrag = false; m_rulerPressed = false; m_pressedKeyframe = nullptr; + m_panProperyGraph = nullptr; + m_timelineAltModifierMode = TimelineAltModifierMode::None; m_clickedTimelineControlType = TimelineControlType::None; m_editedTimelineRow.clear(); m_releaseSelectRow.clear(); @@ -762,7 +784,7 @@ void TimelineGraphicsScene::snap(double &value, bool snapToPlayHead) if (snapToPlayHead) { double playHeadX = m_playHead->x() - TimelineConstants::TREE_BOUND_W - TimelineConstants::RULER_EDGE_OFFSET; - if (abs(value - playHeadX) < CStudioPreferences::GetSnapRange()) { + if (abs(value - playHeadX) < CStudioPreferences::snapRange()) { value = playHeadX; return; } @@ -770,22 +792,22 @@ void TimelineGraphicsScene::snap(double &value, bool snapToPlayHead) // duration edges snap for (double v : qAsConst(m_snapSteps)) { - if (abs(value - v) < CStudioPreferences::GetSnapRange()) { + if (abs(value - v) < CStudioPreferences::snapRange()) { value = v; return; } } // time steps snap - if (CStudioPreferences::IsTimelineSnappingGridActive()) { + if (CStudioPreferences::isTimelineSnappingGridActive()) { double snapStep = TimelineConstants::RULER_SEC_W * m_ruler->timelineScale(); - if (CStudioPreferences::GetTimelineSnappingGridResolution() == SNAPGRID_HALFSECONDS) + if (CStudioPreferences::timelineSnappingGridResolution() == SNAPGRID_HALFSECONDS) snapStep *= .5; - else if (CStudioPreferences::GetTimelineSnappingGridResolution() == SNAPGRID_TICKMARKS) + else if (CStudioPreferences::timelineSnappingGridResolution() == SNAPGRID_TICKMARKS) snapStep *= .1; double snapValue = round(value / snapStep) * snapStep; - if (abs(value - snapValue) < CStudioPreferences::GetSnapRange()) + if (abs(value - snapValue) < CStudioPreferences::snapRange()) value = snapValue; } } @@ -797,16 +819,15 @@ void TimelineGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) if (m_rowMover->isActive()) { // moving rows (reorder/reparent) commitMoveRows(); } else if (m_pressedKeyframe) { - // update keyframe movement (time) to binding m_keyframeManager->commitMoveSelectedKeyframes(); - } else if (m_clickedTimelineControlType == TimelineControlType::StartHandle) { + } else if (m_clickedTimelineControlType == TimelineControlType::DurationStartHandle) { if (!m_editedTimelineRow.isNull()) { ITimelineTimebar *timebar = m_editedTimelineRow->rowTree()->getBinding() ->GetTimelineItem()->GetTimebar(); timebar->ChangeTime(m_editedTimelineRow->getStartTime(), true); timebar->CommitTimeChange(); } - } else if (m_clickedTimelineControlType == TimelineControlType::EndHandle) { + } else if (m_clickedTimelineControlType == TimelineControlType::DurationEndHandle) { if (!m_editedTimelineRow.isNull()) { ITimelineTimebar *timebar = m_editedTimelineRow->rowTree()->getBinding() ->GetTimelineItem()->GetTimebar(); @@ -824,6 +845,9 @@ void TimelineGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) if (m_playHead->time() > ruler()->duration()) g_StudioApp.GetCore()->GetDoc()->NotifyTimeChanged(ruler()->duration()); } + } else if (m_clickedTimelineControlType & TimelineControlType::IsBezierControl) { + if (m_editedTimelineRow->propertyGraph()) + m_editedTimelineRow->propertyGraph()->commitBezierEdit(); } } else if (!m_rulerPressed && (!m_releaseSelectRow.isNull() || !itemAt(event->scenePos(), QTransform()))) { @@ -833,7 +857,7 @@ void TimelineGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) } } - if (m_timelineZooming) + if (m_timelineAltModifierMode == TimelineAltModifierMode::ScaleTimeline) updateSnapSteps(); resetMousePressParams(); @@ -845,38 +869,32 @@ void TimelineGraphicsScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *even { if (event->button() == Qt::LeftButton) { const QPointF scenePos = event->scenePos(); - QGraphicsItem *item = itemAt(scenePos, QTransform()); + QGraphicsItem *item = getItemAt(scenePos); + if (item) { - QGraphicsItem *itemBelowPlayhead = - getItemBelowType(TimelineItem::TypePlayHead, item, scenePos); - if (item->type() == TimelineItem::TypeRuler - || itemBelowPlayhead->type() == TimelineItem::TypeRuler) { - CDoc *doc = g_StudioApp.GetCore()->GetDoc(); + CDoc *doc = g_StudioApp.GetCore()->GetDoc(); + if (item->type() == TimelineItem::TypeRuler) { g_StudioApp.GetDialogs()->asyncDisplayTimeEditDialog(doc->GetCurrentViewTime(), doc, PLAYHEAD, m_keyframeManager); } else { - item = itemBelowPlayhead; if (item->type() == TimelineItem::TypeRowTree) { - RowTree *treeItem = static_cast<RowTree *>(item); - if (treeItem->isProperty()) - treeItem->togglePropertyExpanded(); - } else if (item->type() == TimelineItem::TypeRowTreeLabelItem) { - RowTreeLabelItem *treeLabelItem = static_cast<RowTreeLabelItem *>(item); - if (treeLabelItem->parentRow()->isProperty()) { - treeLabelItem->parentRow()->togglePropertyExpanded(); - } else if (!treeLabelItem->isLocked() - && treeLabelItem->parentRow()->objectType() != OBJTYPE_SCENE - && treeLabelItem->parentRow()->objectType() != OBJTYPE_IMAGE) { - int instance = treeLabelItem->parentRow()->instance(); - const auto bridge = g_StudioApp.GetCore()->GetDoc()->GetStudioSystem() - ->GetClientDataModelBridge(); - if (bridge->GetObjectType(instance) != OBJTYPE_REFERENCEDMATERIAL - || bridge->GetSourcePath(instance).isEmpty()) { - // Tree labels text can be edited with double-click, - // except for Scene label and basic materials - treeLabelItem->setEnabled(true); - treeLabelItem->setFocus(); + RowTree *rowTree = static_cast<RowTree *>(item); + if (rowTree->isProperty()) { // toggle property graph + rowTree->togglePropertyExpanded(scenePos); + } else { + // check label edit + QGraphicsItem *topItem = itemAt(scenePos, {}); + if (topItem->type() == TimelineItem::TypeRowTreeLabel) { + RowTreeLabel *rowTreeLabel = static_cast<RowTreeLabel *>(topItem); + const auto bridge = doc->GetStudioSystem()->GetClientDataModelBridge(); + EStudioObjectType rowObjType = rowTreeLabel->rowTree()->objectType(); + int instance = rowTreeLabel->rowTree()->instance(); + if (!rowTreeLabel->isLocked() && !bridge->isBasicMaterial(instance) + && rowObjType & ~(OBJTYPE_SCENE | OBJTYPE_IMAGE)) { + rowTreeLabel->setEnabled(true); + rowTreeLabel->setFocus(); + } } } } else if (item->type() == TimelineItem::TypeRowTimeline) { @@ -901,6 +919,17 @@ void TimelineGraphicsScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *even void TimelineGraphicsScene::wheelEvent(QGraphicsSceneWheelEvent *wheelEvent) { + // adjust property graph scale + if (wheelEvent->modifiers() & Qt::AltModifier) { + const QPointF pos = wheelEvent->scenePos(); + QGraphicsItem *item = getItemAt(pos); + if (item && item->type() == TimelineItem::TypeRowTimeline) { + RowTimeline *rowTimeline = static_cast<RowTimeline *>(item); + if (rowTimeline->propertyGraph()) + rowTimeline->propertyGraph()->adjustScale(pos, wheelEvent->delta() > 0); + } + } + // Make sure drag states update on wheel scrolls done during drag m_lastAutoScrollX = -1.0; m_lastAutoScrollY = -1.0; @@ -981,25 +1010,21 @@ bool TimelineGraphicsScene::event(QEvent *event) void TimelineGraphicsScene::updateHoverStatus(const QPointF &scenePos) { bool variantsAreaHovered = false; - QGraphicsItem *item = itemAt(scenePos, QTransform()); + QGraphicsItem *item = getItemAt(scenePos); if (item) { - item = getItemBelowType(TimelineItem::TypePlayHead, item, scenePos); // update timeline row cursor if (item->type() == TimelineItem::TypeRowTimeline) { - RowTimeline *timelineItem = static_cast<RowTimeline *>(item); - TimelineControlType controlType = timelineItem->getClickedControl(scenePos); - if (controlType == TimelineControlType::StartHandle - || controlType == TimelineControlType::EndHandle) { + RowTimeline *rowTimeline = static_cast<RowTimeline *>(item); + TimelineControlType controlType = rowTimeline->getClickedControl(scenePos, true); + if (controlType == TimelineControlType::DurationStartHandle + || controlType == TimelineControlType::DurationEndHandle) { setMouseCursor(CMouseCursor::CURSOR_RESIZE_LEFTRIGHT); } else { resetMouseCursor(); } - } else if (!m_dragging && (item->type() == TimelineItem::TypeRowTree - || item->type() == TimelineItem::TypeRowTreeLabelItem)) { + } else if (!m_dragging && item->type() == TimelineItem::TypeRowTree) { // update tree row variants tooltip - RowTree *rowTree = item->type() == TimelineItem::TypeRowTree - ? static_cast<RowTree *>(item) - : static_cast<RowTreeLabelItem *>(item)->parentRow(); + RowTree *rowTree = static_cast<RowTree *>(item); if (!rowTree->isProperty()) { int left = rowTree->clipX(); int right = (int)rowTree->treeWidth() - TimelineConstants::TREE_ICONS_W; @@ -1065,18 +1090,23 @@ void TimelineGraphicsScene::updateHoverStatus(const QPointF &scenePos) } } -// Return next item below [type] item, or item itself -// Used at least for skipping PlayHead and RowTreeLabelItem -QGraphicsItem *TimelineGraphicsScene::getItemBelowType(TimelineItem::ItemType type, - QGraphicsItem *item, - const QPointF &scenePos) const +// This method is similar to itemAt() but if it finds a playhead or tree label items, it returns +// what is below them +QGraphicsItem *TimelineGraphicsScene::getItemAt(const QPointF &scenePos) const { - if (item->type() == type) { - const QList<QGraphicsItem *> hoverItems = items(scenePos); - if (hoverItems.size() > 1) - return hoverItems.at(1); + const QList<QGraphicsItem *> hoverItems = items(scenePos); + + if (!hoverItems.empty()) { + QGraphicsItem *item = hoverItems.at(0); + + int typeMask = TimelineItem::TypePlayHead | TimelineItem::TypeRowTreeLabel; + if (item->type() & typeMask && hoverItems.size() > 1) + item = hoverItems.at(1); + + return item; } - return item; + + return nullptr; } QPoint TimelineGraphicsScene::getScrollbarOffsets() const |