diff options
author | Mahmoud Badri <mahmoud.badri@qt.io> | 2019-08-13 13:58:26 +0300 |
---|---|---|
committer | Mahmoud Badri <mahmoud.badri@qt.io> | 2019-08-14 10:25:24 +0300 |
commit | ff3d4e1936def46b57ff8f8337d09bf8728490e3 (patch) | |
tree | 3f93d1b323d4dbd38f8720f86aed5139199c4b52 /src/Authoring | |
parent | 82c4c1b1be223484b48b077f695bd4b5e2774b33 (diff) |
Support curve editor for color properties
Task-number: QT3DS-3855
Change-Id: I4cc287e9970965b7f6f4131ab13ba57224553965
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
Diffstat (limited to 'src/Authoring')
19 files changed, 174 insertions, 203 deletions
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ITimelineItemProperty.h b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ITimelineItemProperty.h index cdfbd0f1..c64bb5c7 100644 --- a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ITimelineItemProperty.h +++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ITimelineItemProperty.h @@ -66,8 +66,7 @@ public: virtual IKeyframe *GetKeyframeByIndex(long inIndex) const = 0; virtual long GetKeyframeCount() const = 0; virtual size_t GetChannelCount() const = 0; - virtual float GetChannelValueAtTime(long inChannelIndex, long inTime) = 0; - virtual void SetChannelValueAtTime(long inChannelIndex, long inTime, float inValue) = 0; + virtual float GetChannelValueAtTime(size_t chIndex, long time) = 0; virtual bool IsDynamicAnimation() = 0; }; diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemProperty.cpp b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemProperty.cpp index 66b22e58..68a04fe9 100644 --- a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemProperty.cpp +++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemProperty.cpp @@ -56,12 +56,6 @@ bool SortKeyframeByTime(const Qt3DSDMTimelineKeyframe *inLHS, const Qt3DSDMTimel return inLHS->GetTime() < inRHS->GetTime(); } -// DataModel stores it from 0..1, UI expects 0..255 -inline float DataModelToColor(float inValue) -{ - return inValue * 255; -} - Qt3DSDMTimelineItemProperty::Qt3DSDMTimelineItemProperty(CTimelineTranslationManager *inTransMgr, Qt3DSDMPropertyHandle inPropertyHandle, Qt3DSDMInstanceHandle inInstance) @@ -250,14 +244,13 @@ size_t Qt3DSDMTimelineItemProperty::GetChannelCount() const return m_AnimationHandles.size(); } -float Qt3DSDMTimelineItemProperty::GetChannelValueAtTime(long inChannelIndex, long inTime) +float Qt3DSDMTimelineItemProperty::GetChannelValueAtTime(size_t chIndex, long time) { // if no keyframes, get current property value. if (m_Keyframes.empty()) { Qt3DSDMTimelineItemBinding *theParentBinding = static_cast<Qt3DSDMTimelineItemBinding *>(GetParentBinding(m_rowTree)); if (theParentBinding) { - SValue theValue; qt3dsdm::IPropertySystem *thePropertySystem = m_TransMgr->GetStudioSystem()->GetPropertySystem(); @@ -265,67 +258,39 @@ float Qt3DSDMTimelineItemProperty::GetChannelValueAtTime(long inChannelIndex, lo m_PropertyHandle, theValue); switch (m_Type.first) { case DataModelDataType::Float4: { - if (m_Type.second == AdditionalMetaDataType::Color) { - SFloat4 theFloat4 = qt3dsdm::get<SFloat4>(theValue); - if (inChannelIndex >= 0 && inChannelIndex < 4) - return DataModelToColor(theFloat4[inChannelIndex]); - } else { - SFloat4 theFloat4 = qt3dsdm::get<SFloat4>(theValue); - if (inChannelIndex >= 0 && inChannelIndex < 4) - return theFloat4[inChannelIndex]; - } + SFloat4 theFloat4 = qt3dsdm::get<SFloat4>(theValue); + if (chIndex < 4) + return theFloat4[chIndex]; break; } case DataModelDataType::Float3: { SFloat3 theFloat3 = qt3dsdm::get<SFloat3>(theValue); - if (inChannelIndex >= 0 && inChannelIndex < 3) - return theFloat3[inChannelIndex]; + if (chIndex < 3) + return theFloat3[chIndex]; break; } case DataModelDataType::Float2: { SFloat2 theFloat2 = qt3dsdm::get<SFloat2>(theValue); - if (inChannelIndex >= 0 && inChannelIndex < 2) - return theFloat2[inChannelIndex]; + if (chIndex < 2) + return theFloat2[chIndex]; break; } case DataModelDataType::Float: return qt3dsdm::get<float>(theValue); - break; + default: // TODO: handle other types break; } } } - IAnimationCore *theAnimationCore = m_TransMgr->GetStudioSystem()->GetAnimationCore(); - if (!m_AnimationHandles.empty() && inChannelIndex >= 0 - && inChannelIndex < (long)m_AnimationHandles.size()) { - float theValue = theAnimationCore->EvaluateAnimation( - m_AnimationHandles[inChannelIndex], Qt3DSDMTimelineKeyframe::GetTimeInSecs(inTime)); - if (m_Type.first == DataModelDataType::Float4 - && m_Type.second == AdditionalMetaDataType::Color) - theValue = DataModelToColor(theValue); - - return theValue; - } - return 0.f; -} -void Qt3DSDMTimelineItemProperty::SetChannelValueAtTime(long inChannelIndex, long inTime, - float inValue) -{ - Qt3DSDMTimelineKeyframe *theKeyframeWrapper = - dynamic_cast<Qt3DSDMTimelineKeyframe *>(GetKeyframeByTime(inTime)); - if (theKeyframeWrapper) { - Qt3DSDMTimelineKeyframe::TKeyframeHandleList theKeyframes; - theKeyframeWrapper->GetKeyframeHandles(theKeyframes); - if (!theKeyframes.empty() && inChannelIndex < (long)theKeyframes.size()) { - inValue /= 255; - if (!m_SetKeyframeValueCommand) - m_SetKeyframeValueCommand = new CCmdDataModelSetKeyframeValue( - g_StudioApp.GetCore()->GetDoc(), theKeyframes[inChannelIndex], inValue); - m_SetKeyframeValueCommand->Update(inValue); - } + IAnimationCore *animCore = m_TransMgr->GetStudioSystem()->GetAnimationCore(); + if (!m_AnimationHandles.empty() && chIndex < m_AnimationHandles.size()) { + return animCore->EvaluateAnimation(m_AnimationHandles[chIndex], + Qt3DSDMTimelineKeyframe::GetTimeInSecs(time)); } + + return 0.f; } void Qt3DSDMTimelineItemProperty::setRowTree(RowTree *rowTree) diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemProperty.h b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemProperty.h index e386fe38..978f9b12 100644 --- a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemProperty.h +++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemProperty.h @@ -67,8 +67,7 @@ public: IKeyframe *GetKeyframeByIndex(long inIndex) const override; long GetKeyframeCount() const override; size_t GetChannelCount() const override; - float GetChannelValueAtTime(long inChannelIndex, long inTime) override; - void SetChannelValueAtTime(long inChannelIndex, long inTime, float inValue) override; + float GetChannelValueAtTime(size_t chIndex, long time) override; bool IsDynamicAnimation() override; void setRowTree(RowTree *rowTree) override; RowTree *getRowTree() const override; diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineKeyframe.cpp b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineKeyframe.cpp index c7431b3b..238ee360 100644 --- a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineKeyframe.cpp +++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineKeyframe.cpp @@ -43,8 +43,7 @@ using namespace qt3dsdm; // TODO: figure out if we can just use IDoc instead of CDoc Qt3DSDMTimelineKeyframe::Qt3DSDMTimelineKeyframe(IDoc *inDoc) - : m_Doc(dynamic_cast<CDoc *>(inDoc)) - , m_Selected(false) + : m_Doc(static_cast<CDoc *>(inDoc)) { } diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineKeyframe.h b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineKeyframe.h index 99596c84..63944764 100644 --- a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineKeyframe.h +++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineKeyframe.h @@ -27,9 +27,7 @@ ** ****************************************************************************/ #ifndef QT3DSDM_KEYFRAME_H -#define QT3DSDM_KEYFRAME_H 1 - -#pragma once +#define QT3DSDM_KEYFRAME_H #include "IKeyframe.h" @@ -42,26 +40,13 @@ class CCmdBatch; class COffsetKeyframesCommandHelper; struct Keyframe; -//============================================================================== -/** - * Wrapper for a keyframe in DataModel. - */ -//============================================================================== class Qt3DSDMTimelineKeyframe : public IKeyframe { public: typedef std::vector<qt3dsdm::Qt3DSDMKeyframeHandle> TKeyframeHandleList; -protected: - TKeyframeHandleList - m_KeyframeHandles; ///< no. corresponds to the channels the animated property has. - CDoc *m_Doc; - bool m_Selected; - Keyframe *m_ui = nullptr; - -public: Qt3DSDMTimelineKeyframe(IDoc *inDoc); - virtual ~Qt3DSDMTimelineKeyframe(); + virtual ~Qt3DSDMTimelineKeyframe() override; // IKeyframe bool IsSelected() const override; @@ -79,6 +64,12 @@ public: void GetKeyframeHandles(TKeyframeHandleList &outList) const; static float GetTimeInSecs(long inTime); + +private: + TKeyframeHandleList m_KeyframeHandles; // channels handles of the animated property + CDoc *m_Doc = nullptr; + bool m_Selected = false; + Keyframe *m_ui = nullptr; }; #endif // QT3DSDM_KEYFRAME_H diff --git a/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/Keyframe.h b/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/Keyframe.h index 3cbd9383..90210a6a 100644 --- a/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/Keyframe.h +++ b/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/Keyframe.h @@ -37,7 +37,6 @@ struct Keyframe { Keyframe(long time, RowTimeline *propRow) : time(time) - , propertyType(propRow->rowTree()->propertyType()) , rowProperty(propRow) , rowMaster(propRow->parentRow()) {} @@ -48,7 +47,6 @@ struct Keyframe } long time; // millis - QString propertyType; RowTimeline *rowProperty = nullptr; RowTimeline *rowMaster = nullptr; Qt3DSDMTimelineKeyframe *binding = nullptr; diff --git a/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp b/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp index d8c99c14..b663df98 100644 --- a/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp +++ b/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp @@ -853,7 +853,8 @@ void TimelineGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) } } else if (m_clickedTimelineControlType == TimelineControlType::BezierInHandle || m_clickedTimelineControlType == TimelineControlType::BezierOutHandle) { - m_editedTimelineRow->propertyGraph()->commitBezierEdit(); + if (m_editedTimelineRow->propertyGraph()) + m_editedTimelineRow->propertyGraph()->commitBezierEdit(); } } else if (!m_rulerPressed && (!m_releaseSelectRow.isNull() || !itemAt(event->scenePos(), QTransform()))) { diff --git a/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTimeline.cpp b/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTimeline.cpp index 867d6db8..61bf727f 100644 --- a/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTimeline.cpp +++ b/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTimeline.cpp @@ -52,6 +52,8 @@ #include <QtWidgets/qlabel.h> #include <QtCore/qdatetime.h> +using namespace TimelineConstants; + RowTimeline::RowTimeline() : InteractiveTimelineItem() { @@ -104,10 +106,11 @@ void RowTimeline::paint(QPainter *painter, const QStyleOptionGraphicsItem *optio if (!y()) // prevents flickering when the row is just inserted to the layout return; - const int currentHeight = size().height() - 1; + const int currHeight = size().height() - 1; - if (isColorProperty() && !m_keyframes.empty()) { - drawColorPropertyGradient(painter, widget->width()); + if (m_isColorProperty && m_drawColorGradient && !m_keyframes.empty()) { + QRectF gradRect(rowTree()->m_scene->ruler()->viewportX(), 0, widget->width(), currHeight); + drawColorPropertyGradient(painter, gradRect); } else { // Background QColor bgColor; @@ -119,7 +122,7 @@ void RowTimeline::paint(QPainter *painter, const QStyleOptionGraphicsItem *optio bgColor = CStudioPreferences::timelineRowColorOver(); else bgColor = CStudioPreferences::timelineRowColorNormal(); - painter->fillRect(0, 0, size().width(), currentHeight, bgColor); + painter->fillRect(0, 0, size().width(), currHeight, bgColor); } const double edgeOffset = TimelineConstants::RULER_EDGE_OFFSET; @@ -134,13 +137,13 @@ void RowTimeline::paint(QPainter *painter, const QStyleOptionGraphicsItem *optio painter->setBrush(QBrush(CStudioPreferences::timelineRowColorDurationOff1(), Qt::BDiagPattern)); painter->setPen(Qt::NoPen); - painter->fillRect(QRect(edgeOffset + m_startX, 0, m_endX - m_startX, currentHeight), + painter->fillRect(QRect(edgeOffset + m_startX, 0, m_endX - m_startX, currHeight), CStudioPreferences::timelineRowColorDurationOff2()); - painter->drawRect(QRect(edgeOffset + m_startX, 0, m_endX - m_startX, currentHeight)); + painter->drawRect(QRect(edgeOffset + m_startX, 0, m_endX - m_startX, currHeight)); painter->setPen(QPen(CStudioPreferences::timelineRowColorDurationEdge(), 2)); - painter->drawLine(edgeOffset + m_startX, 0, edgeOffset + m_startX, currentHeight); - painter->drawLine(edgeOffset + m_endX, 0, edgeOffset + m_endX, currentHeight); + painter->drawLine(edgeOffset + m_startX, 0, edgeOffset + m_startX, currHeight); + painter->drawLine(edgeOffset + m_endX, 0, edgeOffset + m_endX, currHeight); } else { // draw main duration part double x = edgeOffset + qMax(m_startX, m_minStartX); @@ -150,38 +153,37 @@ void RowTimeline::paint(QPainter *painter, const QStyleOptionGraphicsItem *optio painter->setPen(Qt::NoPen); if (m_controllerDataInput.size()) { - painter->fillRect(QRect(x, 0, w, currentHeight), + painter->fillRect(QRect(x, 0, w, currHeight), CStudioPreferences::dataInputColor()); } else if (m_rowTree->indexInLayout() != 1) { - painter->fillRect(QRect(x, 0, w, currentHeight), m_barColor); + painter->fillRect(QRect(x, 0, w, currHeight), m_barColor); } if (m_state == Selected) { // draw selection overlay on bar - painter->fillRect(QRect(x, marginY, w, currentHeight - marginY * 2), + painter->fillRect(QRect(x, marginY, w, currHeight - marginY * 2), CStudioPreferences::timelineRowColorDurationSelected()); } if (m_controllerDataInput.size()) { - static const QPixmap pixDataInput = QPixmap(":/images/Objects-DataInput-White.png"); - static const QPixmap pixDataInput2x - = QPixmap(":/images/Objects-DataInput-White@2x.png"); + static const QPixmap pixDataInput(":/images/Objects-DataInput-White.png"); + static const QPixmap pixDataInput2x(":/images/Objects-DataInput-White@2x.png"); static const QFontMetrics fm(painter->font()); // need clip region to limit datainput icon visibility to the same rect as we use // for text - painter->setClipRect(x, 0, w, currentHeight); + painter->setClipRect(x, 0, w, currHeight); painter->setClipping(true); painter->setPen(QPen(CStudioPreferences::textColor(), 2)); // +5 added to text location to make margin comparable to other datainput controls - painter->drawText(QRect(x + pixDataInput.width() + 5, 0, w, currentHeight), + painter->drawText(QRect(x + pixDataInput.width() + 5, 0, w, currHeight), m_controllerDataInput, QTextOption(Qt::AlignCenter)); // place the icon in front of the text int textwidth = fm.width(m_controllerDataInput); - int iconx = x + (w - textwidth) / 2; - if (iconx < x) - iconx = x; - painter->drawPixmap(iconx, marginY, hiResIcons ? pixDataInput2x : pixDataInput); + int iconX = x + (w - textwidth) / 2; + if (iconX < x) + iconX = x; + painter->drawPixmap(iconX, marginY, hiResIcons ? pixDataInput2x : pixDataInput); painter->setPen(Qt::NoPen); painter->setClipping(false); } @@ -192,31 +194,29 @@ void RowTimeline::paint(QPainter *painter, const QStyleOptionGraphicsItem *optio if (m_startX < m_minStartX) { painter->setPen(Qt::NoPen); painter->fillRect(QRect(edgeOffset + m_startX, 0, m_minStartX - m_startX, - currentHeight), + currHeight), CStudioPreferences::timelineRowColorDurationOff2()); painter->drawRect(QRect(edgeOffset + m_startX, 0, m_minStartX - m_startX, - currentHeight)); + currHeight)); painter->setPen(CStudioPreferences::timelineRowColorDurationEdge()); painter->drawLine(edgeOffset + m_minStartX, 0, edgeOffset + m_minStartX, - currentHeight); + currHeight); } // draw hashed part after if (m_endX > m_maxEndX) { painter->setPen(Qt::NoPen); - painter->fillRect(QRect(edgeOffset + m_maxEndX, 0, m_endX - m_maxEndX, - currentHeight), + painter->fillRect(QRect(edgeOffset + m_maxEndX, 0, m_endX - m_maxEndX, currHeight), CStudioPreferences::timelineRowColorDurationOff2()); - painter->drawRect(QRect(edgeOffset + m_maxEndX, 0, m_endX - m_maxEndX, - currentHeight)); + painter->drawRect(QRect(edgeOffset + m_maxEndX, 0, m_endX - m_maxEndX, currHeight)); painter->setPen(CStudioPreferences::timelineRowColorDurationEdge()); - painter->drawLine(edgeOffset + m_maxEndX, 0, edgeOffset + m_maxEndX, currentHeight); + painter->drawLine(edgeOffset + m_maxEndX, 0, edgeOffset + m_maxEndX, currHeight); } if (m_rowTree->indexInLayout() != 1) { painter->setPen(QPen(CStudioPreferences::timelineRowColorDurationEdge(), 2)); - painter->drawLine(edgeOffset + m_startX, 0, edgeOffset + m_startX, currentHeight); - painter->drawLine(edgeOffset + m_endX, 0, edgeOffset + m_endX, currentHeight); + painter->drawLine(edgeOffset + m_startX, 0, edgeOffset + m_startX, currHeight); + painter->drawLine(edgeOffset + m_endX, 0, edgeOffset + m_endX, currHeight); } } @@ -224,23 +224,21 @@ void RowTimeline::paint(QPainter *painter, const QStyleOptionGraphicsItem *optio } if (m_propertyGraph) { // Property graph - QRectF graphRect(rowTree()->m_scene->ruler()->viewportX(), 0, - widget->width(), currentHeight); + QRectF graphRect(rowTree()->m_scene->ruler()->viewportX(), 0, widget->width(), currHeight); m_propertyGraph->paintGraphs(painter, graphRect); } // Keyframes const qreal keyFrameH = 16.0; const qreal keyFrameHalfH = keyFrameH / 2.0; - const qreal keyFrameY = (qMin(currentHeight, TimelineConstants::ROW_H) / 2.0) - keyFrameHalfH; + const qreal keyFrameY = (qMin(currHeight, TimelineConstants::ROW_H) / 2.0) - keyFrameHalfH; const qreal hiddenKeyFrameY = keyFrameY + (keyFrameH * 2.0 / 3.0) + 2.0; const qreal keyFrameOffset = hiResIcons ? 8 : 7.5; // Hidden descendant keyframe indicators if (!m_rowTree->expanded()) { - static const QPixmap pixKeyframeHidden = QPixmap(":/images/keyframe-hidden-normal.png"); - static const QPixmap pixKeyframeHidden2x - = QPixmap(":/images/keyframe-hidden-normal@2x.png"); + static const QPixmap pixKeyframeHidden(":/images/keyframe-hidden-normal.png"); + static const QPixmap pixKeyframeHidden2x(":/images/keyframe-hidden-normal@2x.png"); QVector<long> childKeyframeTimes; collectChildKeyframeTimes(childKeyframeTimes); @@ -256,30 +254,26 @@ void RowTimeline::paint(QPainter *painter, const QStyleOptionGraphicsItem *optio } if (m_rowTree->hasPropertyChildren()) { // object row keyframes - static const QPixmap pixKeyframeMasterDisabled - = QPixmap(":/images/Keyframe-Master-Disabled.png"); - static const QPixmap pixKeyframeMasterNormal - = QPixmap(":/images/Keyframe-Master-Normal.png"); - static const QPixmap pixKeyframeMasterSelected - = QPixmap(":/images/Keyframe-Master-Selected.png"); - static const QPixmap pixKeyframeMasterDynamicDisabled - = QPixmap(":/images/Keyframe-MasterDynamic-Disabled.png"); - static const QPixmap pixKeyframeMasterDynamicNormal - = QPixmap(":/images/Keyframe-MasterDynamic-Normal.png"); - static const QPixmap pixKeyframeMasterDynamicSelected - = QPixmap(":/images/Keyframe-MasterDynamic-Selected.png"); - static const QPixmap pixKeyframeMasterDisabled2x - = QPixmap(":/images/Keyframe-Master-Disabled@2x.png"); - static const QPixmap pixKeyframeMasterNormal2x - = QPixmap(":/images/Keyframe-Master-Normal@2x.png"); - static const QPixmap pixKeyframeMasterSelected2x - = QPixmap(":/images/Keyframe-Master-Selected@2x.png"); - static const QPixmap pixKeyframeMasterDynamicDisabled2x - = QPixmap(":/images/Keyframe-MasterDynamic-Disabled@2x.png"); - static const QPixmap pixKeyframeMasterDynamicNormal2x - = QPixmap(":/images/Keyframe-MasterDynamic-Normal@2x.png"); - static const QPixmap pixKeyframeMasterDynamicSelected2x - = QPixmap(":/images/Keyframe-MasterDynamic-Selected@2x.png"); + static const QPixmap pixKeyframeMasterDisabled(":/images/Keyframe-Master-Disabled.png"); + static const QPixmap pixKeyframeMasterNormal(":/images/Keyframe-Master-Normal.png"); + static const QPixmap pixKeyframeMasterSelected(":/images/Keyframe-Master-Selected.png"); + static const QPixmap pixKeyframeMasterDynamicDisabled(":/images/Keyframe-MasterDynamic-" + "Disabled.png"); + static const QPixmap pixKeyframeMasterDynamicNormal(":/images/Keyframe-MasterDynamic-Normal" + ".png"); + static const QPixmap pixKeyframeMasterDynamicSelected(":/images/Keyframe-MasterDynamic-" + "Selected.png"); + static const QPixmap pixKeyframeMasterDisabled2x(":/images/Keyframe-Master-Disabled@2x" + ".png"); + static const QPixmap pixKeyframeMasterNormal2x(":/images/Keyframe-Master-Normal@2x.png"); + static const QPixmap pixKeyframeMasterSelected2x(":/images/Keyframe-Master-Selected@2x" + ".png"); + static const QPixmap pixKeyframeMasterDynamicDisabled2x(":/images/Keyframe-MasterDynamic-" + "Disabled@2x.png"); + static const QPixmap pixKeyframeMasterDynamicNormal2x(":/images/Keyframe-MasterDynamic-" + "Normal@2x.png"); + static const QPixmap pixKeyframeMasterDynamicSelected2x(":/images/Keyframe-MasterDynamic-" + "Selected@2x.png"); for (auto keyframe : qAsConst(m_keyframes)) { QPixmap pixmap; if (m_rowTree->locked()) { @@ -288,7 +282,7 @@ void RowTimeline::paint(QPainter *painter, const QStyleOptionGraphicsItem *optio : pixKeyframeMasterDynamicDisabled; } else { pixmap = hiResIcons ? pixKeyframeMasterDisabled2x - : pixKeyframeMasterDisabled; + : pixKeyframeMasterDisabled; } } else if (keyframe->selected()) { if (keyframe->dynamic) { @@ -322,30 +316,27 @@ void RowTimeline::paint(QPainter *painter, const QStyleOptionGraphicsItem *optio } } } else if (m_rowTree->isProperty()) { // property row keyframes - static const QPixmap pixKeyframePropertyDisabled - = QPixmap(":/images/Keyframe-Property-Disabled.png"); - static const QPixmap pixKeyframePropertyNormal - = QPixmap(":/images/Keyframe-Property-Normal.png"); - static const QPixmap pixKeyframePropertySelected - = QPixmap(":/images/Keyframe-Property-Selected.png"); - static const QPixmap pixKeyframePropertyDynamicDisabled - = QPixmap(":/images/Keyframe-PropertyDynamic-Disabled.png"); - static const QPixmap pixKeyframePropertyDynamicNormal - = QPixmap(":/images/Keyframe-PropertyDynamic-Normal.png"); - static const QPixmap pixKeyframePropertyDynamicSelected - = QPixmap(":/images/Keyframe-PropertyDynamic-Selected.png"); - static const QPixmap pixKeyframePropertyDisabled2x - = QPixmap(":/images/Keyframe-Property-Disabled@2x.png"); - static const QPixmap pixKeyframePropertyNormal2x - = QPixmap(":/images/Keyframe-Property-Normal@2x.png"); - static const QPixmap pixKeyframePropertySelected2x - = QPixmap(":/images/Keyframe-Property-Selected@2x.png"); - static const QPixmap pixKeyframePropertyDynamicDisabled2x - = QPixmap(":/images/Keyframe-PropertyDynamic-Disabled@2x.png"); - static const QPixmap pixKeyframePropertyDynamicNormal2x - = QPixmap(":/images/Keyframe-PropertyDynamic-Normal@2x.png"); - static const QPixmap pixKeyframePropertyDynamicSelected2x - = QPixmap(":/images/Keyframe-PropertyDynamic-Selected@2x.png"); + static const QPixmap pixKeyframePropertyDisabled(":/images/Keyframe-Property-Disabled.png"); + static const QPixmap pixKeyframePropertyNormal(":/images/Keyframe-Property-Normal.png"); + static const QPixmap pixKeyframePropertySelected(":/images/Keyframe-Property-Selected.png"); + static const QPixmap pixKeyframePropertyDynamicDisabled(":/images/Keyframe-PropertyDynamic-" + "Disabled.png"); + static const QPixmap pixKeyframePropertyDynamicNormal(":/images/Keyframe-PropertyDynamic-" + "Normal.png"); + static const QPixmap pixKeyframePropertyDynamicSelected(":/images/Keyframe-PropertyDynamic-" + "Selected.png"); + static const QPixmap pixKeyframePropertyDisabled2x(":/images/Keyframe-Property-Disabled@2x" + ".png"); + static const QPixmap pixKeyframePropertyNormal2x(":/images/Keyframe-Property-Normal@2x" + ".png"); + static const QPixmap pixKeyframePropertySelected2x(":/images/Keyframe-Property-Selected@2x" + ".png"); + static const QPixmap pixKeyframePropertyDynamicDisabled2x(":/images/Keyframe-Property" + "Dynamic-Disabled@2x.png"); + static const QPixmap pixKeyframePropertyDynamicNormal2x(":/images/Keyframe-PropertyDynamic-" + "Normal@2x.png"); + static const QPixmap pixKeyframePropertyDynamicSelected2x(":/images/Keyframe-Property" + "Dynamic-Selected@2x.png"); for (auto keyframe : qAsConst(m_keyframes)) { QPixmap pixmap; if (m_rowTree->locked()) { @@ -383,44 +374,32 @@ void RowTimeline::paint(QPainter *painter, const QStyleOptionGraphicsItem *optio } } -bool RowTimeline::isColorProperty() const +void RowTimeline::toggleColorGradient() { - ITimelineItemProperty *propBinding = m_rowTree->propBinding(); - if (propBinding) { - qt3dsdm::TDataTypePair type = propBinding->GetType(); - if (m_rowTree->isProperty() - && type.first == qt3dsdm::DataModelDataType::Float4 - && type.second == qt3dsdm::AdditionalMetaDataType::Color) { - return true; - } - } - return false; + m_drawColorGradient = !m_drawColorGradient; + update(); } -void RowTimeline::drawColorPropertyGradient(QPainter *painter, int width) +void RowTimeline::drawColorPropertyGradient(QPainter *painter, const QRectF &rect) { - // Gradient scaled width, or at least widget width - double minWidth = width; - double timelineScale = m_rowTree->m_scene->ruler()->timelineScale(); - double scaledWidth = width * (timelineScale / 2); - width = qMax(minWidth, scaledWidth); - + static const QPointF edgeOffset(RULER_EDGE_OFFSET, 0); ITimelineItemProperty *propBinding = m_rowTree->propBinding(); - QLinearGradient bgGradient(0, 0, width, 0); - for (auto keyframe : qAsConst(m_keyframes)) { - double xPos = m_rowTree->m_scene->ruler()->timeToDistance(keyframe->time); - double gradPos = xPos / width; - gradPos = qBound(0.0, gradPos, 1.0); - QColor currentColor; - // Get the color at the specified time. - currentColor.setRed(propBinding->GetChannelValueAtTime(0, keyframe->time)); - currentColor.setGreen(propBinding->GetChannelValueAtTime(1, keyframe->time)); - currentColor.setBlue(propBinding->GetChannelValueAtTime(2, keyframe->time)); - bgGradient.setColorAt(gradPos, currentColor); + QLinearGradient bgGradient(rect.topLeft(), rect.topRight()); + int start_x = int(qMax(rect.x(), edgeOffset.x())); + + for (int x = start_x; x <= rect.right(); x += 20) { // 20 = sampling step in pixels + long time = rowTree()->m_scene->ruler()->distanceToTime(x - edgeOffset.x()); // millis + double ratio = qBound(0.0, (x - edgeOffset.x()) / rect.width(), 1.0); + + bgGradient.setColorAt(ratio, QColor::fromRgbF( + qBound(0.0, double(propBinding->GetChannelValueAtTime(0, time)), 1.0), + qBound(0.0, double(propBinding->GetChannelValueAtTime(1, time)), 1.0), + qBound(0.0, double(propBinding->GetChannelValueAtTime(2, time)), 1.0), + qBound(0.0, double(propBinding->GetChannelValueAtTime(3, time)), 1.0))); } - painter->fillRect(TimelineConstants::RULER_EDGE_OFFSET, 0, - width, size().height() - 1, bgGradient); + + painter->fillRect(rect, bgGradient); } Keyframe *RowTimeline::getClickedKeyframe(const QPointF &scenePos) diff --git a/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTimeline.h b/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTimeline.h index 8ff0fadc..42a50190 100644 --- a/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTimeline.h +++ b/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTimeline.h @@ -85,6 +85,8 @@ public: QList<Keyframe *> getKeyframesInRange(const QRectF &rect) const; QList<Keyframe *> keyframes() const; void showToolTip(const QPointF &pos); + void toggleColorGradient(); + bool isColorProperty() const { return m_isColorProperty; } RowTimelinePropertyGraph *propertyGraph() const { return m_propertyGraph; } protected: @@ -98,8 +100,7 @@ private: void updateChildrenMaxEndXRecursive(RowTree *rowTree); void updateCommentItem(); void updateCommentItemPos(); - void drawColorPropertyGradient(QPainter *painter, int width); - bool isColorProperty() const; + void drawColorPropertyGradient(QPainter *painter, const QRectF &rect); QString formatTime(long millis) const; void collectChildKeyframeTimes(QVector<long> &childKeyframeTimes); @@ -115,6 +116,8 @@ private: double m_minStartX = 0; double m_maxEndX = 0; bool m_isProperty = false; // used in the destructor + bool m_isColorProperty = false; + bool m_drawColorGradient = true; QString m_controllerDataInput; QList<Keyframe *> m_keyframes; QColor m_barColor; diff --git a/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTimelinePropertyGraph.cpp b/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTimelinePropertyGraph.cpp index a1f6a62a..7fd54e93 100644 --- a/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTimelinePropertyGraph.cpp +++ b/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTimelinePropertyGraph.cpp @@ -121,7 +121,9 @@ void RowTimelinePropertyGraph::paintGraphs(QPainter *painter, const QRectF &rect int start_j = qMax(rect.x(), edgeOffset.x()); for (int j = start_j; j < rect.right(); j += 5) { // 5 = sampling step in pixels long time = (j - edgeOffset.x()) / (RULER_MILLI_W * timelineScale); // millis - qreal value = m_propBinding->GetChannelValueAtTime(m_activeChannelsIndex[i], time); + float value = m_propBinding->GetChannelValueAtTime(m_activeChannelsIndex[i], time); + adjustColorProperty(value); + qreal yPos = m_graphY - value * m_valScale; if (j == start_j) @@ -278,6 +280,8 @@ QPointF RowTimelinePropertyGraph::getBezierControlPosition(const SBezierKeyframe // time is in seconds QPointF RowTimelinePropertyGraph::getKeyframePosition(float time, float value) const { + adjustColorProperty(value); + return QPointF(m_rowTimeline->rowTree()->m_scene->ruler()->timeToDistance(time * 1000), m_graphY - value * m_valScale); } @@ -297,6 +301,7 @@ void RowTimelinePropertyGraph::updateBezierControlValue(TimelineControlType cont // time and value at current mouse position float time = m_rowTimeline->rowTree()->m_scene->ruler()->distanceToTime(p.x()) / 1000.f; // secs float value = (m_graphY - p.y()) / m_valScale; + adjustColorProperty(value, false); SBezierKeyframe kf = get<SBezierKeyframe>(m_currKeyframeData.second); bool isBezierIn = controlType == TimelineControlType::BezierInHandle; @@ -407,6 +412,9 @@ void RowTimelinePropertyGraph::fitGraph() } } + adjustColorProperty(maxVal); + adjustColorProperty(minVal); + m_valScale = m_graphH / (maxVal - minVal); checkValScaleLimits(); @@ -415,6 +423,13 @@ void RowTimelinePropertyGraph::fitGraph() m_rowTimeline->update(); } +// show color properties values in the range 0-255 +void RowTimelinePropertyGraph::adjustColorProperty(float &val, bool scaleUp) const +{ + if (m_rowTimeline->isColorProperty()) + scaleUp ? val *= 255.f : val /= 255.f; +} + void RowTimelinePropertyGraph::checkValScaleLimits() { // m_valScale can be NaN if maxVal and minVal are same (i.e. horizontal line curve) diff --git a/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTimelinePropertyGraph.h b/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTimelinePropertyGraph.h index bd165b4b..dbb28b16 100644 --- a/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTimelinePropertyGraph.h +++ b/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTimelinePropertyGraph.h @@ -73,6 +73,7 @@ private: BezierControlType type = BezierControlType::None) const; QPointF getKeyframePosition(float time, float value) const; void checkValScaleLimits(); + void adjustColorProperty(float &val, bool scaleUp = true) const; std::pair<qt3dsdm::Qt3DSDMKeyframeHandle, qt3dsdm::TKeyframe> m_currKeyframeData; RowTimeline *m_rowTimeline = nullptr; diff --git a/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTree.cpp b/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTree.cpp index 53de5fdc..c603c3cf 100644 --- a/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTree.cpp +++ b/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTree.cpp @@ -76,7 +76,6 @@ RowTree::RowTree(TimelineGraphicsScene *timelineScene, const QString &propType) , m_rowTimeline(new RowTimeline()) , m_isProperty(true) , m_scene(timelineScene) - , m_propertyType(propType) , m_label(propType) { m_rowTimeline->m_isProperty = true; @@ -337,8 +336,10 @@ void RowTree::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, Q // draw maximize, fit graph buttons static const QPixmap pixMaximize(":/images/maximize.png"); static const QPixmap pixFit(":/images/editcamera_tools_hi-00.png"); + static const QPixmap pixGradient(":/images/gradient.png"); static const QPixmap pixMaximizeDisabled(":/images/maximize_disabled.png"); static const QPixmap pixFitDisabled(":/images/editcamera_tools_hi-00_disabled.png"); + static const QPixmap pixGradientDisabled(":/images/gradient_disabled.png"); if (m_PropBinding->animationType() == qt3dsdm::EAnimationTypeBezier) { m_rectMaximizePropGraph.setRect(rightDividerX() - 16 * 1.2, TimelineConstants::ROW_H, ICON_SIZE, ICON_SIZE); @@ -350,6 +351,14 @@ void RowTree::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, Q painter->drawPixmap(m_rectMaximizePropGraph, m_locked ? pixMaximizeDisabled : pixMaximize); painter->drawPixmap(m_rectFitPropGraph, m_locked ? pixFitDisabled : pixFit); + + if (m_rowTimeline->isColorProperty()) { + m_rectColorGradient.setRect(rightDividerX() - 16 * 3.6, + TimelineConstants::ROW_H, ICON_SIZE, ICON_SIZE); + painter->drawRect(m_rectColorGradient); + painter->drawPixmap(m_rectColorGradient, m_locked ? pixGradientDisabled + : pixGradient); + } } // draw channel selection buttons @@ -616,6 +625,13 @@ void RowTree::setPropBinding(ITimelineItemProperty *binding) // Update label color m_labelItem.setMaster(m_PropBinding->IsMaster()); + + // update timeline isColorProperty + qt3dsdm::TDataTypePair propType = m_PropBinding->GetType(); + if (m_isProperty && propType.first == qt3dsdm::DataModelDataType::Float4 + && propType.second == qt3dsdm::AdditionalMetaDataType::Color) { + m_rowTimeline->m_isColorProperty = true; + } } void RowTree::setState(State state) @@ -662,11 +678,6 @@ EStudioObjectType RowTree::objectType() const return m_objectType; } -QString RowTree::propertyType() const -{ - return m_propertyType; -} - int RowTree::type() const { // Enable the use of qgraphicsitem_cast with this item. @@ -1023,6 +1034,9 @@ void RowTree::hoverMoveEvent(QGraphicsSceneHoverEvent *event) } else if (m_rectFitPropGraph.contains(p)) { setToolTip(tr("Fit curves")); hoveredRect = &m_rectFitPropGraph; + } else if (m_rectColorGradient.contains(p)) { + setToolTip(tr("Toggle color gradient")); + hoveredRect = &m_rectColorGradient; } else { setToolTip({}); @@ -1081,6 +1095,8 @@ TreeControlType RowTree::getClickedControl(const QPointF &scenePos) ? TimelineConstants::ROW_GRAPH_H_MAX : TimelineConstants::ROW_GRAPH_H; m_rowTimeline->propertyGraph()->setExpandHeight(m_propGraphHeight); animateExpand(ExpandState::Expanded); + } else if (m_rectColorGradient.contains(p)) { // toggle color gradient + m_rowTimeline->toggleColorGradient(); } else { // toggle channels auto it = std::find_if(m_rectChannels.begin(), m_rectChannels.end(), [&p](const QRect &r){ return r.contains(p); }); @@ -1093,7 +1109,7 @@ TreeControlType RowTree::getClickedControl(const QPointF &scenePos) bool isSingleSelected = numSelectedChannel == 1 && m_activeChannels[chIdx]; bool isMultiSelected = numSelectedChannel > 1 && m_activeChannels[chIdx]; if (!isSingleSelected && !(isMultiSelected && !ctrlDown)) - m_activeChannels[chIdx] ^= 1; + m_activeChannels[chIdx] = !m_activeChannels[chIdx]; if (!ctrlDown) { for (int i = 0; i < m_activeChannels.size(); ++i) { diff --git a/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTree.h b/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTree.h index 505c6eca..eeeb93e3 100644 --- a/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTree.h +++ b/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTree.h @@ -203,7 +203,6 @@ private: TimelineGraphicsScene *m_scene; RowTreeLabelItem m_labelItem; EStudioObjectType m_objectType = OBJTYPE_UNKNOWN; - QString m_propertyType; // for property rows QString m_label; QList<RowTree *> m_childRows; QList<RowTree *> m_childProps; @@ -219,6 +218,7 @@ private: QRect m_rectType; QRect m_rectMaximizePropGraph; QRect m_rectFitPropGraph; + QRect m_rectColorGradient; QVector<QRect> m_rectChannels; QVector<bool> m_activeChannels; diff --git a/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/Ruler.cpp b/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/Ruler.cpp index 62c6de01..9b883552 100644 --- a/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/Ruler.cpp +++ b/src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/Ruler.cpp @@ -181,6 +181,7 @@ void Ruler::setViewportX(int viewportX) } } +// x position at the left edge of the timeline (0 when no scrolling) int Ruler::viewportX() const { return m_viewportX; diff --git a/src/Authoring/Qt3DStudio/images.qrc b/src/Authoring/Qt3DStudio/images.qrc index a21a1fb9..b808711e 100644 --- a/src/Authoring/Qt3DStudio/images.qrc +++ b/src/Authoring/Qt3DStudio/images.qrc @@ -327,6 +327,10 @@ <file>images/maximize@2x.png</file> <file>images/maximize_disabled.png</file> <file>images/maximize_disabled@2x.png</file> + <file>images/gradient.png</file> + <file>images/gradient@2x.png</file> + <file>images/gradient_disabled.png</file> + <file>images/gradient_disabled@2x.png</file> </qresource> <qresource prefix="/startup"> <file alias="open_dialog.png">images/open_dialog.png</file> diff --git a/src/Authoring/Qt3DStudio/images/gradient.png b/src/Authoring/Qt3DStudio/images/gradient.png Binary files differnew file mode 100644 index 00000000..dda23252 --- /dev/null +++ b/src/Authoring/Qt3DStudio/images/gradient.png diff --git a/src/Authoring/Qt3DStudio/images/gradient@2x.png b/src/Authoring/Qt3DStudio/images/gradient@2x.png Binary files differnew file mode 100644 index 00000000..f0854021 --- /dev/null +++ b/src/Authoring/Qt3DStudio/images/gradient@2x.png diff --git a/src/Authoring/Qt3DStudio/images/gradient_disabled.png b/src/Authoring/Qt3DStudio/images/gradient_disabled.png Binary files differnew file mode 100644 index 00000000..4313fa74 --- /dev/null +++ b/src/Authoring/Qt3DStudio/images/gradient_disabled.png diff --git a/src/Authoring/Qt3DStudio/images/gradient_disabled@2x.png b/src/Authoring/Qt3DStudio/images/gradient_disabled@2x.png Binary files differnew file mode 100644 index 00000000..76ac98b6 --- /dev/null +++ b/src/Authoring/Qt3DStudio/images/gradient_disabled@2x.png |