summaryrefslogtreecommitdiffstats
path: root/src/Authoring
diff options
context:
space:
mode:
authorMahmoud Badri <mahmoud.badri@qt.io>2019-08-13 13:58:26 +0300
committerMahmoud Badri <mahmoud.badri@qt.io>2019-08-14 10:25:24 +0300
commitff3d4e1936def46b57ff8f8337d09bf8728490e3 (patch)
tree3f93d1b323d4dbd38f8720f86aed5139199c4b52 /src/Authoring
parent82c4c1b1be223484b48b077f695bd4b5e2774b33 (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')
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ITimelineItemProperty.h3
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemProperty.cpp65
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemProperty.h3
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineKeyframe.cpp3
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineKeyframe.h25
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/Keyframe.h2
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp3
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTimeline.cpp211
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTimeline.h7
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTimelinePropertyGraph.cpp17
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTimelinePropertyGraph.h1
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTree.cpp30
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/RowTree.h2
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/TimelineGraphicsView/ui/Ruler.cpp1
-rw-r--r--src/Authoring/Qt3DStudio/images.qrc4
-rw-r--r--src/Authoring/Qt3DStudio/images/gradient.pngbin0 -> 1103 bytes
-rw-r--r--src/Authoring/Qt3DStudio/images/gradient@2x.pngbin0 -> 1470 bytes
-rw-r--r--src/Authoring/Qt3DStudio/images/gradient_disabled.pngbin0 -> 1101 bytes
-rw-r--r--src/Authoring/Qt3DStudio/images/gradient_disabled@2x.pngbin0 -> 1334 bytes
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
new file mode 100644
index 00000000..dda23252
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/images/gradient.png
Binary files differ
diff --git a/src/Authoring/Qt3DStudio/images/gradient@2x.png b/src/Authoring/Qt3DStudio/images/gradient@2x.png
new file mode 100644
index 00000000..f0854021
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/images/gradient@2x.png
Binary files differ
diff --git a/src/Authoring/Qt3DStudio/images/gradient_disabled.png b/src/Authoring/Qt3DStudio/images/gradient_disabled.png
new file mode 100644
index 00000000..4313fa74
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/images/gradient_disabled.png
Binary files differ
diff --git a/src/Authoring/Qt3DStudio/images/gradient_disabled@2x.png b/src/Authoring/Qt3DStudio/images/gradient_disabled@2x.png
new file mode 100644
index 00000000..76ac98b6
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/images/gradient_disabled@2x.png
Binary files differ