summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMahmoud Badri <mahmoud.badri@qt.io>2019-01-29 13:23:53 +0200
committerMahmoud Badri <mahmoud.badri@qt.io>2019-01-30 07:18:09 +0000
commit9b3f171a0256936452c23834539594ce8b3ed70e (patch)
treedd3e9ff64694485551e2473340612b129c86473d
parentd32e58d8ac09fd04dac3293b06c2c9300919d181 (diff)
Fix 'set keyframe time' dialog issue
- Fixed an issue that happens when the user sets the time to a value that makes the keyframe with min. time go below zero when setting the time for multiple keyframes. - Highlighted the pressed keyframe from a multi-selection so that it is clear which keyframe is affected by setting the time or snapping. - removed some useless code and simplified some logic. Task-number: QT3DS-2957 Change-Id: I023b95f18c9f9902da3b71f0d5701251c33b6005 Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
-rw-r--r--src/Authoring/Client/Code/Core/Doc/IKeyframesManager.h1
-rw-r--r--src/Authoring/Client/Code/Core/Utility/StudioPreferences.cpp7
-rw-r--r--src/Authoring/Client/Code/Core/Utility/StudioPreferences.h1
-rw-r--r--src/Authoring/Studio/Application/TimeEditDlg.cpp142
-rw-r--r--src/Authoring/Studio/Application/TimeEditDlg.h16
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/KeyframeManager.cpp62
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/KeyframeManager.h7
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp9
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.h2
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTimeline.cpp8
-rw-r--r--src/Authoring/Studio/Workspace/Dialogs.cpp2
-rw-r--r--src/Authoring/Studio/Workspace/Dialogs.h4
12 files changed, 113 insertions, 148 deletions
diff --git a/src/Authoring/Client/Code/Core/Doc/IKeyframesManager.h b/src/Authoring/Client/Code/Core/Doc/IKeyframesManager.h
index f2bf4ebb..df028c3f 100644
--- a/src/Authoring/Client/Code/Core/Doc/IKeyframesManager.h
+++ b/src/Authoring/Client/Code/Core/Doc/IKeyframesManager.h
@@ -48,7 +48,6 @@ public:
virtual void SetKeyframeTime(long inTime) = 0;
virtual void SetKeyframesDynamic(bool inDynamic) = 0;
- virtual long OffsetSelectedKeyframes(long inOffset) = 0;
virtual void CommitChangedKeyframes() = 0;
virtual void RollbackChangedKeyframes() = 0;
};
diff --git a/src/Authoring/Client/Code/Core/Utility/StudioPreferences.cpp b/src/Authoring/Client/Code/Core/Utility/StudioPreferences.cpp
index 921af967..967687ad 100644
--- a/src/Authoring/Client/Code/Core/Utility/StudioPreferences.cpp
+++ b/src/Authoring/Client/Code/Core/Utility/StudioPreferences.cpp
@@ -84,6 +84,7 @@ static QColor s_timelinePlayheadLineColor;
static QColor s_timelineFilterButtonSelectedColor;
static QColor s_timelineFilterButtonHoveredColor;
static QColor s_timelineRowCommentBgColor;
+static QColor s_timelinePressedKeyframeColor; // pressed keyframe from multiple selection
static int s_fontSize;
static int s_controlBaseHeight;
@@ -179,6 +180,7 @@ void CStudioPreferences::loadPreferences(const QString &filePath)
s_timelineRowSubpColor = QColor("#e2ceff");
s_timelineRowSubpDescendantColor = QColor("#a263ff");
s_timelineRowCommentBgColor = QColor("#d0000000");
+ s_timelinePressedKeyframeColor = QColor("#ffff00");
s_fontSize = 12;
s_controlBaseHeight = 22;
@@ -1036,6 +1038,11 @@ QColor CStudioPreferences::timelineRowCommentBgColor()
return s_timelineRowCommentBgColor;
}
+QColor CStudioPreferences::timelinePressedKeyframeColor()
+{
+ return s_timelinePressedKeyframeColor;
+}
+
int CStudioPreferences::fontSize()
{
return s_fontSize;
diff --git a/src/Authoring/Client/Code/Core/Utility/StudioPreferences.h b/src/Authoring/Client/Code/Core/Utility/StudioPreferences.h
index 2c7d80b7..61ac3369 100644
--- a/src/Authoring/Client/Code/Core/Utility/StudioPreferences.h
+++ b/src/Authoring/Client/Code/Core/Utility/StudioPreferences.h
@@ -198,6 +198,7 @@ public:
static QColor timelineRowSubpColor();
static QColor timelineRowSubpDescendantColor();
static QColor timelineRowCommentBgColor();
+ static QColor timelinePressedKeyframeColor();
static int fontSize();
static int controlBaseHeight();
diff --git a/src/Authoring/Studio/Application/TimeEditDlg.cpp b/src/Authoring/Studio/Application/TimeEditDlg.cpp
index cf806d5d..93834c8f 100644
--- a/src/Authoring/Studio/Application/TimeEditDlg.cpp
+++ b/src/Authoring/Studio/Application/TimeEditDlg.cpp
@@ -29,14 +29,14 @@
#include "ui_TimeEditDlg.h"
#include "TimeEditDlg.h"
-#include "IKeyframesManager.h"
+#include "KeyframeManager.h"
#include "IDoc.h"
#include "TimeEnums.h"
#include <QtGui/qvalidator.h>
-CTimeEditDlg::CTimeEditDlg(IKeyframesManager *keyframeManager)
+CTimeEditDlg::CTimeEditDlg(KeyframeManager *keyframeManager)
: m_ui(new Ui::TimeEditDlg)
- , m_KeyframesManager(keyframeManager)
+ , m_keyframeManager(keyframeManager)
{
m_ui->setupUi(this);
setAutoFillBackground(true);
@@ -63,54 +63,48 @@ CTimeEditDlg::~CTimeEditDlg()
delete m_ui;
}
-//=============================================================================
/**
- * showDialog: Initializes and shows the Time Edit Dialog Box.
- * @param inTime is the initial time, which will be shown when the time edit
- * dialog box pops up
+ * Initializes and shows the dialog
+ * @param inTime the initial time which will be shown when the dialog pops up
* @param inDoc this can be nullptr where its not applicable
- * @param inObjectAssociation is the identifier for that identifies the object
- * associated with the time edit dialog
- * (e.g. playhead, keyframe)
+ * @param inObjectAssociation the identifier for the object associated with the dialog (playhead
+ * or keyframe)
*/
void CTimeEditDlg::showDialog(long inTime, IDoc *inDoc, long inObjectAssociation)
{
- m_InitialTime = inTime;
- m_ObjectAssociation = inObjectAssociation;
+ m_initialTime = inTime;
+ m_objectAssociation = inObjectAssociation;
m_Doc = inDoc;
// Set initial values to dialog
- formatTime(m_InitialTime);
+ formatTime(m_initialTime);
exec();
}
void CTimeEditDlg::formatTime(long inTime)
{
- long theTime = inTime;
- long min = 0;
- long sec = 0;
- long msec = 0;
+ long mins = 0;
+ long secs = 0;
+ long mils = 0;
- // Translates the m_initialTime (in milliseconds) into Minutes, Seconds and Milliseconds
if (inTime != 0) {
- min = timeConversion(theTime, CONVERT_MSEC_TO_MIN);
- theTime = theTime - timeConversion(min, CONVERT_MIN_TO_MSEC);
- sec = timeConversion(theTime, CONVERT_MSEC_TO_SEC);
- theTime = theTime - timeConversion(sec, CONVERT_SEC_TO_MSEC);
- msec = theTime;
+ mins = inTime % 3600000 / 60000;
+ secs = inTime % 60000 / 1000;
+ mils = inTime % 1000;
}
- // Default to 3 digits, e.g. "5" -> "005"
- QString msecString = QString("%1").arg(msec, 3, 10, QChar('0'));
- m_ui->lineEditMinutes->setText(QString::number(min));
- m_ui->lineEditSeconds->setText(QString::number(sec));
- m_ui->lineEditMilliseconds->setText(msecString);
+
+ // display milliseconds in 3 digits (5 -> 005)
+ QString milsStr = QString("%1").arg(mils, 3, 10, QChar('0'));
+ m_ui->lineEditMinutes->setText(QString::number(mins));
+ m_ui->lineEditSeconds->setText(QString::number(secs));
+ m_ui->lineEditMilliseconds->setText(milsStr);
// Select the biggest non-zero unit
- if (min > 0) {
+ if (mins > 0) {
m_ui->lineEditMinutes->setFocus();
m_ui->lineEditMinutes->selectAll();
- } else if (sec > 0) {
+ } else if (secs > 0) {
m_ui->lineEditSeconds->setFocus();
m_ui->lineEditSeconds->selectAll();
} else {
@@ -119,23 +113,23 @@ void CTimeEditDlg::formatTime(long inTime)
}
}
-void CTimeEditDlg::showEvent(QShowEvent *ev)
+void CTimeEditDlg::showEvent(QShowEvent *e)
{
onInitDialog();
- QDialog::showEvent(ev);
+ QDialog::showEvent(e);
}
void CTimeEditDlg::onInitDialog()
{
QString title;
// Display the window captions for the correct object type
- switch (m_ObjectAssociation) {
+ switch (m_objectAssociation) {
case PLAYHEAD:
title = QObject::tr("Go To Time");
break;
case ASSETKEYFRAME:
title = QObject::tr("Set Keyframe Time");
- Q_ASSERT(m_KeyframesManager != nullptr);
+ Q_ASSERT(m_keyframeManager != nullptr);
break;
}
setWindowTitle(title);
@@ -145,11 +139,11 @@ void CTimeEditDlg::onInitDialog()
void CTimeEditDlg::accept()
{
// Only commit here, cos dup keyframes will be deleted.
- if (m_ObjectAssociation == ASSETKEYFRAME && m_Doc) {
- if (m_OffsetFromInitialTime == 0)
- m_KeyframesManager->RollbackChangedKeyframes();
+ if (m_objectAssociation == ASSETKEYFRAME && m_Doc) {
+ if (m_endTime == m_initialTime)
+ m_keyframeManager->RollbackChangedKeyframes();
else
- m_KeyframesManager->CommitChangedKeyframes();
+ m_keyframeManager->CommitChangedKeyframes();
}
QDialog::accept();
@@ -158,68 +152,26 @@ void CTimeEditDlg::accept()
void CTimeEditDlg::reject()
{
// Only commit here, cos dup keyframes will be deleted.
- if (m_ObjectAssociation == ASSETKEYFRAME && m_Doc)
- m_KeyframesManager->RollbackChangedKeyframes();
+ if (m_objectAssociation == ASSETKEYFRAME && m_Doc)
+ m_keyframeManager->RollbackChangedKeyframes();
QDialog::reject();
}
-int CTimeEditDlg::numberOfDigits(long number)
-{
- long n = 0;
- for (long i = number; i >= 1; i /= 10)
- ++n;
-
- return n;
-}
-
-//==============================================================================
-/**
- * timeConversion: Converts inTime to the format specified by inFlags.
- * For example:
- * inTime = 5 sec inFlags = CONVERT_SEC_TO_MSEC
- * The method will convert 5 sec into 5000 msec and
- * returns the result.
- * @param inTime stores the time to be converted.
- * inOperationCode determines the type of time conversion to be done on the
- * inTime.
- * @return theResult stores the result of the time conversion.
- */
-long CTimeEditDlg::timeConversion(long inTime, long inOperationCode)
-{
- switch (inOperationCode) {
- case CONVERT_MIN_TO_MSEC:
- return inTime * 60000;
- case CONVERT_SEC_TO_MSEC:
- return inTime * 1000;
- case CONVERT_MSEC_TO_MIN:
- return inTime / 60000;
- case CONVERT_MSEC_TO_SEC:
- return inTime / 1000;
- }
-
- return 0;
-}
-
-//==============================================================================
/**
- * updateObjectTime: It updates the playhead or keyframe time according
- * to the time displayed in the time edit dialogue.
- * @param inTime is the time that will be updated.
+ * Updates the playhead or keyframe time according to the time displayed in the time edit dialogue.
+ * @param inTime the time that will be updated.
*/
void CTimeEditDlg::updateObjectTime(long inTime)
{
- long theDiff = 0;
- switch (m_ObjectAssociation) {
+ switch (m_objectAssociation) {
case PLAYHEAD: // Update the playhead time
if (m_Doc)
m_Doc->NotifyTimeChanged(inTime);
break;
case ASSETKEYFRAME: // Update the keyframe time
if (m_Doc) {
- theDiff = inTime - m_OffsetFromInitialTime - m_InitialTime;
- m_OffsetFromInitialTime = m_OffsetFromInitialTime + theDiff;
- if (theDiff != 0)
- m_KeyframesManager->OffsetSelectedKeyframes(theDiff);
+ m_endTime = inTime;
+ m_keyframeManager->moveSelectedKeyframes(inTime);
}
break;
}
@@ -231,21 +183,23 @@ void CTimeEditDlg::onTimeChanged()
long sec = m_ui->lineEditSeconds->text().toInt();
long msec = m_ui->lineEditMilliseconds->text().toInt();
- long theGoToTime = timeConversion(min, CONVERT_MIN_TO_MSEC)
- + timeConversion(sec, CONVERT_SEC_TO_MSEC) + msec;
+ long theGoToTime = min * 60000 + sec * 1000 + msec;
+ // make sure min keyframe time doesn't go below zero
+ long offset = m_keyframeManager->getPressedKeyframeOffset();
+ if (theGoToTime - offset < 0) {
+ theGoToTime = offset;
+ formatTime(theGoToTime);
+ }
// Go to the time specified in the time edit display
updateObjectTime(theGoToTime);
// If max number of digits reached in a number field, select the next
- if (m_min != min && numberOfDigits(min) == 4) {
+ if (min > 999) {
m_ui->lineEditSeconds->setFocus();
m_ui->lineEditSeconds->selectAll();
- } else if (m_sec != sec && numberOfDigits(sec) == 2) {
+ } else if (sec > 9) {
m_ui->lineEditMilliseconds->setFocus();
m_ui->lineEditMilliseconds->selectAll();
}
-
- m_min = min;
- m_sec = sec;
}
diff --git a/src/Authoring/Studio/Application/TimeEditDlg.h b/src/Authoring/Studio/Application/TimeEditDlg.h
index 2490d2dd..ef4f8d1a 100644
--- a/src/Authoring/Studio/Application/TimeEditDlg.h
+++ b/src/Authoring/Studio/Application/TimeEditDlg.h
@@ -34,7 +34,7 @@
class CTimebarControl;
class IDoc;
-class IKeyframesManager;
+class KeyframeManager;
#ifdef QT_NAMESPACE
using namespace QT_NAMESPACE;
@@ -51,7 +51,7 @@ class CTimeEditDlg : public QDialog
Q_OBJECT
public:
- CTimeEditDlg(IKeyframesManager *keyframeManager);
+ CTimeEditDlg(KeyframeManager *keyframeManager);
virtual ~CTimeEditDlg() override;
void showDialog(long inTime, IDoc *inDoc, long inObjectAssociation);
@@ -67,17 +67,13 @@ private:
void onTimeChanged();
void formatTime(long inTime);
- int numberOfDigits(long number);
- long timeConversion(long inTime, long inOperationCode);
void updateObjectTime(long inTime);
Ui::TimeEditDlg *m_ui = nullptr;
IDoc *m_Doc = nullptr;
- IKeyframesManager *m_KeyframesManager = nullptr;
- long m_InitialTime = 0;
- long m_ObjectAssociation = 0;
- long m_OffsetFromInitialTime = 0;
- int m_min = -1;
- int m_sec = -1;
+ KeyframeManager *m_keyframeManager = nullptr;
+ long m_initialTime = 0;
+ long m_endTime = 0;
+ long m_objectAssociation = 0;
};
#endif // TIME_EDIT_DIALOG_H
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/KeyframeManager.cpp b/src/Authoring/Studio/Palettes/TimelineGraphicsView/KeyframeManager.cpp
index c495b099..57694a29 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/KeyframeManager.cpp
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/KeyframeManager.cpp
@@ -370,51 +370,45 @@ void KeyframeManager::pasteKeyframes()
}
}
-void KeyframeManager::moveSelectedKeyframesTo(Keyframe *pressedKeyframe, double newX)
+void KeyframeManager::moveSelectedKeyframes(long newTime)
{
- long t = m_scene->ruler()->distanceToTime(newX);
+ Keyframe *pressedKeyframe = m_scene->pressedKeyframe();
- // make sure the min-time keyframe doesn't go below zero
- long minTime = LONG_MAX;
- for (auto keyframe : qAsConst(m_selectedKeyframes)) {
- if (keyframe->time < minTime)
- minTime = keyframe->time;
- }
+ Q_ASSERT(pressedKeyframe);
- if (pressedKeyframe->time - minTime > t)
- t = pressedKeyframe->time - minTime;
+ // make sure the min-time keyframe doesn't go below zero
+ long minTime = getMinSelectedKeyframesTime();
+ if (pressedKeyframe->time - minTime > newTime)
+ newTime = pressedKeyframe->time - minTime;
for (auto keyframe : qAsConst(m_selectedKeyframes)) {
if (keyframe != pressedKeyframe)
- keyframe->time = t - (pressedKeyframe->time - keyframe->time);
+ keyframe->time = newTime - (pressedKeyframe->time - keyframe->time);
}
- pressedKeyframe->time = t;
+ pressedKeyframe->time = newTime;
for (auto row : qAsConst(m_selectedKeyframesMasterRows))
row->updateKeyframes();
}
-// TODO: update TimeEditDlg.cpp to use the method above and remove this one
-void KeyframeManager::moveSelectedKeyframes(double dx)
+long KeyframeManager::getMinSelectedKeyframesTime() const
{
- long dt = m_scene->ruler()->distanceToTime(dx);
-
- if (dt < 0) { // check min limit
- long minTime = LONG_MAX;
- for (auto keyframe : qAsConst(m_selectedKeyframes)) {
- if (keyframe->time < minTime)
- minTime = keyframe->time;
- }
-
- if (minTime + dt < 0)
- dt = -minTime;
+ long minTime = LONG_MAX;
+ for (auto keyframe : qAsConst(m_selectedKeyframes)) {
+ if (keyframe->time < minTime)
+ minTime = keyframe->time;
}
- for (auto keyframe : qAsConst(m_selectedKeyframes))
- keyframe->time += dt;
+ return minTime;
+}
- for (auto row : qAsConst(m_selectedKeyframesMasterRows))
- row->updateKeyframes();
+// returns the distance between the pressed keyframe and the min-time keyframe in a multiselection
+long KeyframeManager::getPressedKeyframeOffset() const
+{
+ if (m_scene->pressedKeyframe())
+ return m_scene->pressedKeyframe()->time - getMinSelectedKeyframesTime();
+
+ return 0;
}
// selected keyframes belong to only one master row
@@ -479,20 +473,16 @@ void KeyframeManager::SetKeyframesDynamic(bool inDynamic)
g_StudioApp.GetCore()->ExecuteCommand(cmd);
}
-long KeyframeManager::OffsetSelectedKeyframes(long inOffset)
-{
- double dx = m_scene->ruler()->timeToDistance(inOffset);
- moveSelectedKeyframes(dx);
- return 0;
-}
-
void KeyframeManager::CommitChangedKeyframes()
{
+ m_scene->resetPressedKeyframe();
commitMoveSelectedKeyframes();
}
void KeyframeManager::RollbackChangedKeyframes()
{
+ m_scene->resetPressedKeyframe();
+
for (Keyframe *keyframe : qAsConst(m_selectedKeyframes))
keyframe->time = keyframe->binding->GetTime();
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/KeyframeManager.h b/src/Authoring/Studio/Palettes/TimelineGraphicsView/KeyframeManager.h
index 4b6d8f80..9c160687 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/KeyframeManager.h
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/KeyframeManager.h
@@ -63,8 +63,7 @@ public:
void deleteKeyframes(RowTimeline *row, bool repaint = true);
void copySelectedKeyframes();
void pasteKeyframes();
- void moveSelectedKeyframes(double dx);
- void moveSelectedKeyframesTo(Keyframe *pressedKeyframe, double newX);
+ void moveSelectedKeyframes(long newTime);
void commitMoveSelectedKeyframes();
bool deleteSelectedKeyframes();
bool oneMasterRowSelected() const;
@@ -75,7 +74,6 @@ public:
// IKeyframesManager interface
void SetKeyframeTime(long inTime) override;
void SetKeyframesDynamic(bool inDynamic) override;
- long OffsetSelectedKeyframes(long inOffset) override;
void CommitChangedKeyframes() override;
void RollbackChangedKeyframes() override;
bool HasSelectedKeyframes() override;
@@ -88,10 +86,13 @@ public:
void SetKeyframeInterpolation() override;
void DeselectAllKeyframes() override;
void SetChangedKeyframes() override;
+ long getPressedKeyframeOffset() const;
private:
qt3dsdm::SGetOrSetKeyframeInfo setKeyframeInfo(qt3dsdm::Qt3DSDMKeyframeHandle inKeyframe,
qt3dsdm::IAnimationCore &inCore);
+ long getMinSelectedKeyframesTime() const;
+
CPasteKeyframeCommandHelper *m_pasteKeyframeCommandHelper = nullptr;
TimelineGraphicsScene *m_scene;
QList<Keyframe *> m_selectedKeyframes;
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp
index 1f09f899..850971c4 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp
@@ -640,7 +640,7 @@ void TimelineGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
if (shift)
snap(newX);
- m_keyframeManager->moveSelectedKeyframesTo(m_pressedKeyframe, newX);
+ m_keyframeManager->moveSelectedKeyframes(ruler()->distanceToTime(newX));
m_pressPos.setX(newX);
}
@@ -745,6 +745,11 @@ void TimelineGraphicsScene::resetMousePressParams()
m_lastAutoScrollY = -1.0;
}
+void TimelineGraphicsScene::resetPressedKeyframe()
+{
+ m_pressedKeyframe = nullptr;
+}
+
QLabel *TimelineGraphicsScene::timebarTooltip()
{
return m_timebarToolTip;
@@ -877,6 +882,7 @@ void TimelineGraphicsScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *even
RowTimeline *rowTimeline = static_cast<RowTimeline *>(item);
Keyframe *clickedKeyframe = rowTimeline->getClickedKeyframe(scenePos);
if (clickedKeyframe) {
+ m_pressedKeyframe = clickedKeyframe;
g_StudioApp.GetDialogs()->asyncDisplayTimeEditDialog(
clickedKeyframe->time, g_StudioApp.GetCore()->GetDoc(),
ASSETKEYFRAME, m_keyframeManager);
@@ -1117,3 +1123,4 @@ KeyframeManager *TimelineGraphicsScene::keyframeManager() const { return m
QGraphicsLinearLayout *TimelineGraphicsScene::layoutTree() const { return m_layoutTree; }
QGraphicsLinearLayout *TimelineGraphicsScene::layoutTimeline() const { return m_layoutTimeline; }
TimelineWidget *TimelineGraphicsScene::widgetTimeline() const { return m_widgetTimeline; }
+Keyframe *TimelineGraphicsScene::pressedKeyframe() const { return m_pressedKeyframe; }
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.h b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.h
index 66192b3e..cfef0bae 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.h
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.h
@@ -95,6 +95,8 @@ public:
QPoint getScrollbarOffsets() const;
void handleShowDISelector(const QString &propertyname, qt3dsdm::Qt3DSDMInstanceHandle inInst,
const QPoint &pos);
+ void resetPressedKeyframe();
+ Keyframe *pressedKeyframe() const;
protected:
bool event(QEvent *event) override;
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTimeline.cpp b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTimeline.cpp
index 9f7798ff..29f13df5 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTimeline.cpp
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTimeline.cpp
@@ -276,6 +276,14 @@ void RowTimeline::paint(QPainter *painter, const QStyleOptionGraphicsItem *optio
pixmap = pixKeyframeMasterNormal;
}
painter->drawPixmap(QPointF(timeToX(keyframe->time) - 8.5, keyFrameY), pixmap);
+
+ // highlight the pressed keyframe in a multi-selection (the keyframe that is affected
+ // by snapping, and setting time dialog)
+ if (m_rowTree->m_scene->keyframeManager()->selectedKeyframes().size() > 1
+ && m_rowTree->m_scene->pressedKeyframe() == keyframe) {
+ painter->setPen(QPen(CStudioPreferences::timelinePressedKeyframeColor(), 1));
+ painter->drawArc(timeToX(keyframe->time) - 4, keyFrameY + 4, 9, 9, 0, 5760);
+ }
}
} else if (m_rowTree->isProperty()) {
static const QPixmap pixKeyframePropertyDisabled
diff --git a/src/Authoring/Studio/Workspace/Dialogs.cpp b/src/Authoring/Studio/Workspace/Dialogs.cpp
index 38e19671..093f154d 100644
--- a/src/Authoring/Studio/Workspace/Dialogs.cpp
+++ b/src/Authoring/Studio/Workspace/Dialogs.cpp
@@ -1339,7 +1339,7 @@ void CDialogs::DisplayGLVersionWarning(const Q3DStudio::CString &inGLVersion,
}
void CDialogs::asyncDisplayTimeEditDialog(long time, IDoc *doc, long objectAssociation,
- IKeyframesManager *keyframesManager) const
+ KeyframeManager *keyframesManager) const
{
QTimer::singleShot(0, [time, doc, objectAssociation, keyframesManager]() {
CTimeEditDlg timeEditDlg(keyframesManager);
diff --git a/src/Authoring/Studio/Workspace/Dialogs.h b/src/Authoring/Studio/Workspace/Dialogs.h
index 3c7f2218..2579e61f 100644
--- a/src/Authoring/Studio/Workspace/Dialogs.h
+++ b/src/Authoring/Studio/Workspace/Dialogs.h
@@ -55,7 +55,7 @@ class CStudioApp;
class CControl;
class CDialogControl;
class CProgressView;
-class IKeyframesManager;
+class KeyframeManager;
class ITimeChangeCallback;
class CDialogs : public QObject
@@ -183,7 +183,7 @@ public:
const Q3DStudio::CString &inRecommendedVersion);
void asyncDisplayTimeEditDialog(long time, IDoc *doc, long objectAssociation,
- IKeyframesManager *keyframesManager = nullptr) const;
+ KeyframeManager *keyframesManager = nullptr) const;
void asyncDisplayDurationEditDialog(long startTime, long endTime, IDoc *doc,
ITimeChangeCallback *callback) const;