summaryrefslogtreecommitdiffstats
path: root/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings
diff options
context:
space:
mode:
Diffstat (limited to 'src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings')
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/BehaviorTimelineItemBinding.cpp58
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/BehaviorTimelineItemBinding.h61
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/EmptyTimelineTimebar.cpp103
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/EmptyTimelineTimebar.h65
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/GroupTimelineItemBinding.cpp107
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/GroupTimelineItemBinding.h62
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/IBreadCrumbProvider.h72
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ITimelineItem.h75
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ITimelineItemBinding.h181
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ITimelineItemProperty.h73
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ITimelineTimebar.h73
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ImageTimelineItemBinding.cpp79
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ImageTimelineItemBinding.h76
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/LayerTimelineItemBinding.cpp254
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/LayerTimelineItemBinding.h79
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/MaterialTimelineItemBinding.cpp210
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/MaterialTimelineItemBinding.h82
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/OffsetKeyframesCommandHelper.cpp66
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/OffsetKeyframesCommandHelper.h65
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/PasteKeyframesCommandHelper.h118
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/PathAnchorPointTimelineItemBinding.cpp44
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/PathAnchorPointTimelineItemBinding.h68
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/PathTimelineItemBinding.cpp58
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/PathTimelineItemBinding.h63
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMAssetTimelineKeyframe.cpp90
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMAssetTimelineKeyframe.h74
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimeline.h42
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.cpp1164
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.h205
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemProperty.cpp470
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemProperty.h114
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineKeyframe.cpp223
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineKeyframe.h88
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineTimebar.cpp222
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineTimebar.h90
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/SlideTimelineItemBinding.cpp92
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/SlideTimelineItemBinding.h104
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/TimelineBreadCrumbProvider.cpp241
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/TimelineBreadCrumbProvider.h74
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/TimelineTranslationManager.cpp130
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/TimelineTranslationManager.h61
41 files changed, 5676 insertions, 0 deletions
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/BehaviorTimelineItemBinding.cpp b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/BehaviorTimelineItemBinding.cpp
new file mode 100644
index 00000000..a1e9ae40
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/BehaviorTimelineItemBinding.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "Qt3DSCommonPrecompile.h"
+#include "BehaviorTimelineItemBinding.h"
+#include "TimelineTranslationManager.h"
+#include "StudioApp.h"
+#include "Qt3DSDMStudioSystem.h"
+#include "ClientDataModelBridge.h"
+#include "Doc.h"
+
+using namespace qt3dsdm;
+
+CBehaviorTimelineItemBinding::CBehaviorTimelineItemBinding(CTimelineTranslationManager *inMgr,
+ Qt3DSDMInstanceHandle inDataHandle)
+ : Qt3DSDMTimelineItemBinding(inMgr, inDataHandle)
+{
+}
+
+EStudioObjectType CBehaviorTimelineItemBinding::GetObjectType() const
+{
+ return OBJTYPE_BEHAVIOR;
+}
+
+//=============================================================================
+/**
+ * Open the associated item as though it was double-clicked in explorer
+ */
+bool CBehaviorTimelineItemBinding::OpenAssociatedEditor()
+{
+ return OpenSourcePathFile();
+}
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/BehaviorTimelineItemBinding.h b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/BehaviorTimelineItemBinding.h
new file mode 100644
index 00000000..d8f809d1
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/BehaviorTimelineItemBinding.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//==============================================================================
+// Prefix
+//==============================================================================
+#ifndef INCLUDED_BEHAVIOR_TIMELINEITEM_BINDING_H
+#define INCLUDED_BEHAVIOR_TIMELINEITEM_BINDING_H 1
+
+#pragma once
+
+#include "Qt3DSDMTimelineItemBinding.h"
+
+//==============================================================================
+// Classes
+//==============================================================================
+class CTimelineTranslationManager;
+
+//=============================================================================
+/**
+ * Binding to a DataModel object of Behavior type
+ */
+class CBehaviorTimelineItemBinding : public Qt3DSDMTimelineItemBinding
+{
+public:
+ CBehaviorTimelineItemBinding(CTimelineTranslationManager *inMgr,
+ qt3dsdm::Qt3DSDMInstanceHandle inDataHandle);
+ ~CBehaviorTimelineItemBinding() {}
+
+ // Qt3DSDMTimelineItemBinding
+ EStudioObjectType GetObjectType() const override;
+ bool OpenAssociatedEditor() override;
+};
+
+#endif // INCLUDED_BEHAVIOR_TIMELINEITEM_BINDING_H
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/EmptyTimelineTimebar.cpp b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/EmptyTimelineTimebar.cpp
new file mode 100644
index 00000000..b135e2c0
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/EmptyTimelineTimebar.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "Qt3DSCommonPrecompile.h"
+#include "EmptyTimelineTimebar.h"
+#include "StudioPreferences.h"
+
+CEmptyTimelineTimebar::CEmptyTimelineTimebar()
+{
+}
+
+CEmptyTimelineTimebar::~CEmptyTimelineTimebar()
+{
+}
+
+long CEmptyTimelineTimebar::GetStartTime() const
+{
+ return 0;
+}
+
+long CEmptyTimelineTimebar::GetEndTime() const
+{
+ return 0;
+}
+
+long CEmptyTimelineTimebar::GetDuration() const
+{
+ return 0;
+}
+
+bool CEmptyTimelineTimebar::ShowHandleBars() const
+{ // makes no sense to show handle bars, when this does not have start/end times.
+ return false;
+}
+
+void CEmptyTimelineTimebar::OnBeginDrag()
+{
+}
+
+void CEmptyTimelineTimebar::OffsetTime(long inDiff)
+{
+ Q_UNUSED(inDiff);
+}
+
+void CEmptyTimelineTimebar::ChangeTime(long inTime, bool inSetStart)
+{
+ Q_UNUSED(inTime);
+ Q_UNUSED(inSetStart);
+}
+
+void CEmptyTimelineTimebar::CommitTimeChange()
+{
+}
+
+void CEmptyTimelineTimebar::RollbackTimeChange()
+{
+}
+
+::CColor CEmptyTimelineTimebar::GetTimebarColor()
+{
+ return CStudioPreferences::GetObjectTimebarColor();
+}
+
+QString CEmptyTimelineTimebar::GetTimebarComment() const
+{
+ return {};
+}
+
+void CEmptyTimelineTimebar::SetTimebarComment(const QString &inComment)
+{
+ Q_UNUSED(inComment);
+}
+
+void CEmptyTimelineTimebar::SetTimebarTime(ITimeChangeCallback *inCallback /*= nullptr*/)
+{
+ Q_UNUSED(inCallback);
+}
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/EmptyTimelineTimebar.h b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/EmptyTimelineTimebar.h
new file mode 100644
index 00000000..09c00582
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/EmptyTimelineTimebar.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//==============================================================================
+// Prefix
+//==============================================================================
+#pragma once
+
+#include "ITimelineTimebar.h"
+
+//=============================================================================
+/**
+ * The current timeline UI design is such that even when no timebar shows up ( with the exception of
+ * the top row, ie the time context )
+ * there is a timebar control to store the keyframes for the animated properties.
+ * Hence, instead of return nullptr for GetTimebar for ITimelineItem, this class will ensure the UI
+ * classes still work.
+ */
+class CEmptyTimelineTimebar : public ITimelineTimebar
+{
+public:
+ CEmptyTimelineTimebar();
+ virtual ~CEmptyTimelineTimebar();
+
+ // ITimelineTimebar
+ long GetStartTime() const override;
+ long GetEndTime() const override;
+ long GetDuration() const override;
+ bool ShowHandleBars() const override;
+ void OnBeginDrag() override;
+ void OffsetTime(long inDiff) override;
+ void ChangeTime(long inTime, bool inSetStart) override;
+ void CommitTimeChange() override;
+ void RollbackTimeChange() override;
+ ::CColor GetTimebarColor() override;
+ QString GetTimebarComment() const override;
+ void SetTimebarComment(const QString &inComment) override;
+ void SetTimebarTime(ITimeChangeCallback *inCallback = nullptr) override;
+};
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/GroupTimelineItemBinding.cpp b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/GroupTimelineItemBinding.cpp
new file mode 100644
index 00000000..a860b24c
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/GroupTimelineItemBinding.cpp
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "Qt3DSCommonPrecompile.h"
+#include "GroupTimelineItemBinding.h"
+#include "TimelineTranslationManager.h"
+#include "StudioApp.h"
+#include "Core.h"
+#include "Dialogs.h"
+
+// Data model specific
+#include "Doc.h"
+#include "CmdGeneric.h"
+
+#include "Qt3DSDMStudioSystem.h"
+#include "ClientDataModelBridge.h"
+#include "Qt3DSDMSlides.h"
+#include "Qt3DSDMDataCore.h"
+#include "Qt3DSFileTools.h"
+
+using namespace qt3dsdm;
+
+CGroupTimelineItemBinding::CGroupTimelineItemBinding(CTimelineTranslationManager *inMgr,
+ Qt3DSDMInstanceHandle inDataHandle)
+ : Qt3DSDMTimelineItemBinding(inMgr, inDataHandle)
+{
+}
+
+//=============================================================================
+/**
+ * Ideally we like to be able to edit the component in a different editor ( we've been hoping for
+ * that feature ) BUT we don't have that,
+ * and it has always been we 'dive' into the component within Studio.
+ */
+bool CGroupTimelineItemBinding::OpenAssociatedEditor()
+{
+ if (GetObjectType() == OBJTYPE_COMPONENT) {
+ ISlideSystem *theSlideSystem = m_StudioSystem->GetSlideSystem();
+
+ qt3dsdm::Qt3DSDMInstanceHandle theInstance = GetInstance();
+ Q3DStudio::CId theId = m_StudioSystem->GetClientDataModelBridge()->GetGUID(theInstance);
+ qt3dsdm::Qt3DSDMSlideHandle theMasterSlide =
+ theSlideSystem->GetMasterSlideByComponentGuid(GuidtoSLong4(theId));
+
+ if (theMasterSlide.Valid()) {
+ Qt3DSDMSlideHandle theActiveSlide = theSlideSystem->GetActiveSlide(theMasterSlide);
+
+ CCmd *theCmd = new CCmdGeneric<CDoc, Qt3DSDMSlideHandle>(
+ m_TransMgr->GetDoc(), &CDoc::NotifyActiveSlideChanged,
+ &CDoc::NotifyActiveSlideChanged, theActiveSlide, NULL, "");
+ theCmd->SetUndoable(false);
+ theCmd->SetModifiedFlag(false);
+ m_TransMgr->GetDoc()->GetCore()->ExecuteCommand(theCmd, false);
+ }
+ return true;
+ }
+ return false;
+}
+
+bool CGroupTimelineItemBinding::IsImported() const
+{
+
+ qt3dsdm::Qt3DSDMInstanceHandle theInstance = GetInstance();
+ qt3dsdm::IPropertySystem *thePropertySystem =
+ m_TransMgr->GetDoc()->GetStudioSystem()->GetPropertySystem();
+ qt3dsdm::SValue theValue;
+ if (thePropertySystem->GetInstancePropertyValue(theInstance, m_TransMgr->GetDoc()
+ ->GetStudioSystem()
+ ->GetClientDataModelBridge()
+ ->GetSourcePathProperty(),
+ theValue)) {
+ qt3dsdm::TDataStrPtr theSrcPath(qt3dsdm::get<qt3dsdm::TDataStrPtr>(theValue));
+ Q3DStudio::CFilePath theFilePath(theSrcPath->GetData());
+ if (theFilePath.GetExtension() == CDialogs::GetWideImportFileExtension())
+ return true;
+ }
+ // If it is, check to be sure that
+ // we can get to the import file.
+ // If we can, then we are imported.
+ return false;
+}
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/GroupTimelineItemBinding.h b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/GroupTimelineItemBinding.h
new file mode 100644
index 00000000..cd7f9dad
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/GroupTimelineItemBinding.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//==============================================================================
+// Prefix
+//==============================================================================
+#ifndef INCLUDED_GROUP_TIMELINEITEM_BINDING_H
+#define INCLUDED_GROUP_TIMELINEITEM_BINDING_H 1
+
+#pragma once
+
+#include "Qt3DSDMTimelineItemBinding.h"
+
+//==============================================================================
+// Classes
+//==============================================================================
+class ITimelineItem;
+class CTimelineTranslationManager;
+
+//=============================================================================
+/**
+ * Binding to a DataModel object of Group type
+ */
+class CGroupTimelineItemBinding : public Qt3DSDMTimelineItemBinding
+{
+public:
+ CGroupTimelineItemBinding(CTimelineTranslationManager *inMgr,
+ qt3dsdm::Qt3DSDMInstanceHandle inDataHandle);
+ ~CGroupTimelineItemBinding() {}
+
+ // Qt3DSDMTimelineItemBinding
+ bool OpenAssociatedEditor() override;
+ bool IsImported() const override;
+};
+
+#endif // INCLUDED_GROUP_TIMELINEITEM_BINDING_H
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/IBreadCrumbProvider.h b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/IBreadCrumbProvider.h
new file mode 100644
index 00000000..1a8beb0a
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/IBreadCrumbProvider.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef INCLUDED_IBREADCRUMBPROVIDER_H
+#define INCLUDED_IBREADCRUMBPROVIDER_H 1
+
+#pragma once
+
+#include <QColor>
+#include <QString>
+#include <QObject>
+
+QT_FORWARD_DECLARE_CLASS(QPixmap)
+
+struct SBreadCrumb
+{
+ QColor m_Color; /// Color for text of the bread crumb
+ QString m_String; /// Text to be displayed for the bread crumb
+};
+
+//=============================================================================
+/**
+ * A interface class for the breadcrumb control, to walk down the breadcrumb trail, without having
+ * to know any underlying implementations.
+ */
+class IBreadCrumbProvider : public QObject
+{
+ Q_OBJECT
+public:
+ typedef std::vector<SBreadCrumb> TTrailList;
+
+public:
+ virtual ~IBreadCrumbProvider() {}
+
+ virtual TTrailList GetTrail(bool inRefresh = true) = 0;
+ virtual void OnBreadCrumbClicked(long inTrailIndex) = 0;
+
+ virtual QPixmap GetRootImage() const = 0;
+ virtual QPixmap GetBreadCrumbImage() const = 0;
+ virtual QPixmap GetSeparatorImage() const = 0;
+ virtual QPixmap GetActiveBreadCrumbImage() const = 0;
+Q_SIGNALS:
+ void SigBreadCrumbUpdate();
+};
+
+#endif // INCLUDED_IBREADCRUMBPROVIDER_H
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ITimelineItem.h b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ITimelineItem.h
new file mode 100644
index 00000000..4308fb2b
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ITimelineItem.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef INCLUDED_ITIMELINE_ITEM_H
+#define INCLUDED_ITIMELINE_ITEM_H 1
+
+#pragma once
+
+#include "INamable.h"
+#include "StudioObjectTypes.h"
+
+class ITimelineTimebar;
+
+//=============================================================================
+/**
+ * Abstraction of a data model item in the Scene. This might end up deriving from a more generic
+ * interface, so that common
+ * functions can be generalized for items in the different palettes.
+ */
+//=============================================================================
+class ITimelineItem : public INamable
+{
+public:
+ virtual ~ITimelineItem() {}
+
+ virtual EStudioObjectType GetObjectType() const = 0;
+ virtual bool IsMaster() const = 0;
+
+ virtual bool IsShy() const = 0;
+ virtual void SetShy(bool) = 0;
+ virtual bool IsLocked() const = 0;
+ virtual void SetLocked(bool) = 0;
+ virtual bool IsVisible() const = 0;
+ virtual void SetVisible(bool) = 0;
+ virtual bool IsImported() const { return false; }
+ virtual bool IsVisibilityControlled() const = 0;
+
+ // Actions
+ virtual bool HasAction(bool inMaster) = 0;
+ virtual bool ChildrenHasAction(bool inMaster) = 0;
+ virtual bool ComponentHasAction(bool inMaster) = 0;
+
+ // subpresentations
+ virtual bool hasSubpresentation() const = 0;
+
+ virtual ITimelineTimebar *GetTimebar() = 0;
+};
+
+#endif // INCLUDED_ITIMELINE_ITEM_H
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ITimelineItemBinding.h b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ITimelineItemBinding.h
new file mode 100644
index 00000000..cebc46d1
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ITimelineItemBinding.h
@@ -0,0 +1,181 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef INCLUDED_ITIMELINE_ITEM_BINDINGS_H
+#define INCLUDED_ITIMELINE_ITEM_BINDINGS_H 1
+
+#pragma once
+
+#include "ITimelineItem.h"
+#include "ITimelineItemProperty.h"
+#include "SIterator.h"
+
+class RowTree;
+class CControlWindowListener;
+
+// Data model specific ??
+class CDropTarget;
+
+class ITimelineItemKeyframesHolder
+{
+public:
+ virtual ~ITimelineItemKeyframesHolder() {}
+
+ virtual void InsertKeyframe() = 0;
+ virtual void DeleteAllChannelKeyframes() = 0;
+ virtual IKeyframe *GetKeyframeByTime(long inTime) const = 0;
+};
+
+//=============================================================================
+/**
+ * Interface to encapsulate data model specific functions, that Timeline UI objects can talk to.
+ */
+//=============================================================================
+class ITimelineItemBinding : public ITimelineItemKeyframesHolder
+{
+public:
+ // List of possible transactions that requires querying the data model if they are valid
+ enum EUserTransaction {
+ EUserTransaction_None,
+ EUserTransaction_Rename,
+ EUserTransaction_Duplicate,
+ EUserTransaction_Cut,
+ EUserTransaction_Copy,
+ EUserTransaction_Paste,
+ EUserTransaction_Delete,
+ EUserTransaction_MakeComponent,
+ EUserTransaction_EditComponent,
+ EUserTransaction_MakeAnimatable,
+ EUserTransaction_Group,
+ EUserTransaction_Ungroup,
+ EUserTransaction_AddLayer,
+ };
+
+public:
+ virtual ~ITimelineItemBinding() {}
+
+ virtual ITimelineItem *GetTimelineItem() = 0;
+ virtual RowTree *getRowTree() const = 0; // UI
+ virtual void setRowTree(RowTree *row) = 0;
+
+ // Events
+ virtual void SetSelected(bool multiSelect) = 0;
+ virtual void OnCollapsed() = 0;
+ virtual bool OpenAssociatedEditor() = 0;
+ virtual void SetDropTarget(CDropTarget *inTarget) = 0;
+
+ // Hierarchy
+ virtual long GetChildrenCount() = 0;
+ virtual ITimelineItemBinding *GetChild(long inIndex) = 0;
+ virtual QList<ITimelineItemBinding *> GetChildren() = 0;
+ virtual ITimelineItemBinding *GetParent() = 0;
+ virtual void SetParent(ITimelineItemBinding *parent) = 0;
+ // Properties
+ virtual long GetPropertyCount() = 0;
+ virtual ITimelineItemProperty *GetProperty(long inIndex) = 0;
+
+ // Eye/Lock toggles
+ virtual bool ShowToggleControls() const = 0;
+ virtual bool IsLockedEnabled() const = 0;
+ virtual bool IsVisibleEnabled() const = 0;
+
+ // ContextMenu
+ virtual bool IsValidTransaction(EUserTransaction inTransaction) = 0;
+ virtual void PerformTransaction(EUserTransaction inTransaction) = 0;
+ virtual Q3DStudio::CString GetObjectPath() = 0;
+
+ virtual bool IsExternalizeable() { return false; }
+ virtual void Externalize() {}
+ virtual bool IsInternalizeable() { return false; }
+ virtual void Internalize() {}
+
+ void setCreateUIRow(bool create) { m_createUIRow = create; }
+
+protected:
+ bool m_createUIRow = true; // control creation of UI row for old style timeline UI
+};
+
+//=============================================================================
+/**
+ * Helper iterator class that iterates over a ITimeline's children in a ordered (priority) list.
+ */
+//=============================================================================
+class CTimelineItemOrderedIterator : public CSIterator<ITimelineItemBinding *>
+{
+public:
+ CTimelineItemOrderedIterator(ITimelineItemBinding *inRootTimelineItem)
+ {
+ m_RootTimelineItem = inRootTimelineItem;
+ Reset();
+ }
+ bool IsDone() override { return (m_Index >= m_Total); }
+ void operator++() override { m_Index++; }
+ void operator+=(const long inNumToInc) override { m_Index += inNumToInc; }
+ ITimelineItemBinding *GetCurrent() override { return m_RootTimelineItem->GetChild(m_Index); }
+ virtual void Reset()
+ {
+ m_Index = 0;
+ m_Total = m_RootTimelineItem->GetChildrenCount();
+ }
+
+protected:
+ ITimelineItemBinding *m_RootTimelineItem;
+ long m_Index;
+ long m_Total;
+};
+
+//=============================================================================
+/**
+ * Helper iterator class that iterates over a ITimeline's properties
+ */
+//=============================================================================
+class CTimelineItemPropertyIterator : public CSIterator<ITimelineItemProperty *>
+{
+public:
+ CTimelineItemPropertyIterator(ITimelineItemBinding *inTimelineItem)
+ {
+ m_TimelineItem = inTimelineItem;
+ Reset();
+ }
+ bool IsDone() override { return (m_Index >= m_Total); }
+ void operator++() override { m_Index++; }
+ void operator+=(const long inNumToInc) override { m_Index += inNumToInc; }
+ ITimelineItemProperty *GetCurrent() override { return m_TimelineItem->GetProperty(m_Index); }
+ virtual void Reset()
+ {
+ m_Index = 0;
+ m_Total = m_TimelineItem->GetPropertyCount();
+ }
+
+protected:
+ ITimelineItemBinding *m_TimelineItem;
+ long m_Index;
+ long m_Total;
+};
+
+#endif // INCLUDED_ITIMELINE_ITEM_BINDINGS_H
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ITimelineItemProperty.h b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ITimelineItemProperty.h
new file mode 100644
index 00000000..72488480
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ITimelineItemProperty.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef INCLUDED_ITIMELINE_ITEM_PROPERTY_H
+#define INCLUDED_ITIMELINE_ITEM_PROPERTY_H 1
+
+#pragma once
+
+#include "Qt3DSDMMetaData.h"
+#include "Qt3DSString.h"
+
+class RowTree;
+class IKeyframe;
+
+//=============================================================================
+/**
+ * Abstraction of a data model item's property that is displayed in the Timeline.
+ */
+//=============================================================================
+class ITimelineItemProperty
+{
+public:
+ virtual ~ITimelineItemProperty() {}
+
+ virtual Q3DStudio::CString GetName() const = 0;
+ virtual bool IsMaster() const = 0;
+ virtual qt3dsdm::TDataTypePair GetType() const = 0;
+ virtual float GetMaximumValue() const = 0;
+ virtual float GetMinimumValue() const = 0;
+
+ virtual void SetSelected() = 0;
+ virtual void DeleteAllKeys() = 0;
+
+ virtual void setRowTree(RowTree *row) = 0;
+ virtual RowTree *getRowTree() const = 0;
+
+ // Keyframes
+ virtual IKeyframe *GetKeyframeByTime(long inTime) const = 0;
+ virtual IKeyframe *GetKeyframeByIndex(long inIndex) const = 0;
+ virtual long GetKeyframeCount() const = 0;
+ virtual long GetChannelCount() const = 0;
+ virtual float GetChannelValueAtTime(long inChannelIndex, long inTime) = 0;
+ virtual void SetChannelValueAtTime(long inChannelIndex, long inTime, float inValue) = 0;
+ virtual bool IsDynamicAnimation() = 0;
+};
+
+#endif // INCLUDED_ITIMELINE_ITEM_H
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ITimelineTimebar.h b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ITimelineTimebar.h
new file mode 100644
index 00000000..2a5ef827
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ITimelineTimebar.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef INCLUDED_ITIMELINE_TIMEBAR_H
+#define INCLUDED_ITIMELINE_TIMEBAR_H 1
+
+#pragma once
+
+#include "Qt3DSString.h"
+
+class ITimeChangeCallback;
+
+class CColor;
+
+//=============================================================================
+/**
+ * Interface for a Timebar
+ */
+//=============================================================================
+class ITimelineTimebar
+{
+public:
+ virtual ~ITimelineTimebar() {}
+
+ virtual long GetStartTime() const = 0;
+ virtual long GetEndTime() const = 0;
+ virtual long GetDuration() const = 0;
+ virtual bool ShowHandleBars() const = 0;
+ //=============================================================================
+ /**
+ * TODO: consider refactor. drag&drop specfics should not be in the Data Model.
+ */
+ virtual void OnBeginDrag() = 0;
+ //
+ virtual void OffsetTime(long inDiff) = 0;
+ // Change the start time or the end time of the timebar. inTime: time to change to, inSetStart:
+ // true to set start time, false to set end time.
+ virtual void ChangeTime(long inTime, bool inSetStart) = 0;
+ virtual void CommitTimeChange() = 0;
+ virtual void RollbackTimeChange() = 0;
+ //
+ virtual CColor GetTimebarColor() = 0;
+ virtual QString GetTimebarComment() const = 0;
+ virtual void SetTimebarComment(const QString &inComment) = 0;
+ virtual void SetTimebarTime(ITimeChangeCallback *inCallback = nullptr) = 0;
+};
+
+#endif // INCLUDED_ITIMELINE_TIMEBAR_H
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ImageTimelineItemBinding.cpp b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ImageTimelineItemBinding.cpp
new file mode 100644
index 00000000..ac0fa169
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ImageTimelineItemBinding.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "ImageTimelineItemBinding.h"
+#include "TimelineTranslationManager.h"
+#include "EmptyTimelineTimebar.h"
+
+using namespace qt3dsdm;
+
+CImageTimelineItemBinding::CImageTimelineItemBinding(CTimelineTranslationManager *inMgr,
+ Qt3DSDMInstanceHandle inDataHandle)
+ : Qt3DSDMTimelineItemBinding(inMgr, inDataHandle)
+{
+}
+
+CImageTimelineItemBinding::~CImageTimelineItemBinding()
+{
+}
+
+ITimelineTimebar *CImageTimelineItemBinding::GetTimebar()
+{ // No timebars on images
+ return new CEmptyTimelineTimebar();
+}
+
+Q3DStudio::CString CImageTimelineItemBinding::GetName() const
+{
+ return m_Name;
+}
+
+void CImageTimelineItemBinding::SetName(const Q3DStudio::CString &inName)
+{
+ m_Name = inName;
+}
+
+EStudioObjectType CImageTimelineItemBinding::GetObjectType() const
+{
+ return OBJTYPE_IMAGE;
+}
+
+bool CImageTimelineItemBinding::ShowToggleControls() const
+{
+ // no toggle controls, by design
+ return false;
+}
+
+//=============================================================================
+/**
+ * Open the associated item as though it was double-clicked in explorer
+ */
+bool CImageTimelineItemBinding::OpenAssociatedEditor()
+{
+ return OpenSourcePathFile();
+}
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ImageTimelineItemBinding.h b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ImageTimelineItemBinding.h
new file mode 100644
index 00000000..b9343872
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/ImageTimelineItemBinding.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//==============================================================================
+// Prefix
+//==============================================================================
+#ifndef INCLUDED_IMAGE_TIMELINEITEM_BINDING_H
+#define INCLUDED_IMAGE_TIMELINEITEM_BINDING_H 1
+
+#pragma once
+
+#include "Qt3DSDMTimelineItemBinding.h"
+
+//==============================================================================
+// Classes
+//==============================================================================
+class CTimelineTranslationManager;
+class ITimelineTimebar;
+
+//=============================================================================
+/**
+ * Binding to a DataModel object of Image type
+ */
+class CImageTimelineItemBinding : public Qt3DSDMTimelineItemBinding
+{
+public:
+ CImageTimelineItemBinding(CTimelineTranslationManager *inMgr,
+ qt3dsdm::Qt3DSDMInstanceHandle inDataHandle);
+ virtual ~CImageTimelineItemBinding();
+
+ // Qt3DSDMTimelineItemBinding
+ ITimelineTimebar *GetTimebar() override;
+ Q3DStudio::CString GetName() const override;
+ void SetName(const Q3DStudio::CString &inName) override;
+ EStudioObjectType GetObjectType() const override;
+ bool ShowToggleControls() const override;
+ bool OpenAssociatedEditor() override;
+
+ void SetPropertyHandle(qt3dsdm::Qt3DSDMPropertyHandle inProperty)
+ {
+ m_PropertyHandle = inProperty;
+ }
+ qt3dsdm::Qt3DSDMPropertyHandle GetPropertyHandle() const { return m_PropertyHandle; }
+
+protected:
+ Q3DStudio::CString m_Name;
+ qt3dsdm::Qt3DSDMPropertyHandle m_PropertyHandle;
+};
+
+#endif // INCLUDED_IMAGE_TIMELINEITEM_BINDING_H
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/LayerTimelineItemBinding.cpp b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/LayerTimelineItemBinding.cpp
new file mode 100644
index 00000000..79d5da54
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/LayerTimelineItemBinding.cpp
@@ -0,0 +1,254 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "Qt3DSCommonPrecompile.h"
+#include "LayerTimelineItemBinding.h"
+#include "TimelineTranslationManager.h"
+#include "ImageTimelineItemBinding.h"
+#include "EmptyTimelineTimebar.h"
+
+// Data model specific
+#include "IDoc.h"
+#include "ClientDataModelBridge.h"
+#include "DropSource.h"
+#include "Doc.h"
+
+#include "Qt3DSDMHandles.h"
+#include "Qt3DSDMStudioSystem.h"
+
+#include "Qt3DSDMMetaData.h"
+#include "Qt3DSDMDataCore.h"
+#include "StudioFullSystem.h"
+#include "StudioCoreSystem.h"
+#include "Qt3DSDMSlides.h"
+
+using namespace qt3dsdm;
+
+namespace {
+
+bool ImageSlotIsFilled(qt3dsdm::IPropertySystem *inPropertySystem, Qt3DSDMInstanceHandle inInstance,
+ const TCharStr &inStr)
+{
+ Qt3DSDMPropertyHandle theProperty =
+ inPropertySystem->GetAggregateInstancePropertyByName(inInstance, inStr);
+ SValue theValue;
+ inPropertySystem->GetInstancePropertyValue(inInstance, theProperty, theValue);
+
+ SLong4 theLong4 = qt3dsdm::get<SLong4>(theValue);
+ bool theReturn = theLong4.m_Longs[0] != 0 || theLong4.m_Longs[1] != 0
+ || theLong4.m_Longs[2] != 0 || theLong4.m_Longs[3] != 0;
+
+ return theReturn;
+}
+}
+
+CLayerTimelineItemBinding::CLayerTimelineItemBinding(CTimelineTranslationManager *inMgr,
+ qt3dsdm::Qt3DSDMInstanceHandle inDataHandle)
+ : Qt3DSDMTimelineItemBinding(inMgr, inDataHandle)
+{
+ qt3dsdm::IPropertySystem *thePropertySystem = m_TransMgr->GetStudioSystem()->GetPropertySystem();
+ TPropertyHandleList theProperties;
+ thePropertySystem->GetAggregateInstanceProperties(inDataHandle, theProperties);
+
+ size_t thePropertyCount = theProperties.size();
+ for (size_t thePropertyIndex = 0; thePropertyIndex < thePropertyCount; ++thePropertyIndex) {
+ Qt3DSDMPropertyHandle theProperty = theProperties[thePropertyIndex];
+
+ AdditionalMetaDataType::Value theAdditionalMetaDataType =
+ thePropertySystem->GetAdditionalMetaDataType(inDataHandle, theProperty);
+
+ if (theAdditionalMetaDataType == AdditionalMetaDataType::Image) {
+ TCharStr theName(thePropertySystem->GetName(theProperty));
+ TCharStr theFormalName(thePropertySystem->GetFormalName(inDataHandle, theProperty));
+ TNameFormalNamePair thePair =
+ std::make_tuple(theName, theFormalName, theProperty);
+ m_ImageNameFormalNamePairs.push_back(thePair);
+ }
+ }
+}
+
+CLayerTimelineItemBinding::~CLayerTimelineItemBinding()
+{
+}
+
+EStudioObjectType CLayerTimelineItemBinding::GetObjectType() const
+{
+ return OBJTYPE_LAYER;
+}
+
+ITimelineItemBinding *CLayerTimelineItemBinding::GetChild(long inIndex)
+{
+ qt3dsdm::Qt3DSDMInstanceHandle theInstance = GetInstance();
+ if (theInstance.Valid()) {
+ Q3DStudio::CGraphIterator theChildren;
+ Qt3DSDMSlideHandle theActiveSlide = m_TransMgr->GetDoc()->GetActiveSlide();
+ GetAssetChildrenInTimeParent(theInstance, m_TransMgr->GetDoc(), AmITimeParent(),
+ theChildren, theActiveSlide);
+ theChildren += inIndex;
+ return GetOrCreateBinding(theChildren.GetCurrent());
+ }
+ return nullptr;
+}
+
+QList<ITimelineItemBinding *> CLayerTimelineItemBinding::GetChildren()
+{
+ QList<ITimelineItemBinding *> retlist;
+ qt3dsdm::Qt3DSDMInstanceHandle theInstance = GetInstance();
+ if (theInstance.Valid()) {
+ Q3DStudio::CGraphIterator theChildren;
+ Qt3DSDMSlideHandle theActiveSlide = m_TransMgr->GetDoc()->GetActiveSlide();
+ GetAssetChildrenInTimeParent(theInstance, m_TransMgr->GetDoc(), AmITimeParent(),
+ theChildren, theActiveSlide);
+ int childCount = int(theChildren.GetCount());
+ retlist.reserve(childCount);
+ for (int i = 0; i < childCount; ++i) {
+ retlist.append(GetOrCreateBinding(theChildren.GetCurrent()));
+ ++theChildren;
+ }
+ }
+
+ return retlist;
+}
+
+void CLayerTimelineItemBinding::OnAddChild(qt3dsdm::Qt3DSDMInstanceHandle inInstance)
+{
+ using namespace qt3dsdm;
+ CClientDataModelBridge *theBridge = m_TransMgr->GetStudioSystem()->GetClientDataModelBridge();
+ // This is handled via the OnPropertyChanged call below
+ if (theBridge->IsImageInstance(inInstance))
+ return;
+ else
+ Qt3DSDMTimelineItemBinding::OnAddChild(inInstance);
+}
+
+void CLayerTimelineItemBinding::OnPropertyChanged(Qt3DSDMPropertyHandle inPropertyHandle)
+{
+ Qt3DSDMTimelineItemBinding::OnPropertyChanged(inPropertyHandle);
+}
+
+qt3dsdm::Qt3DSDMInstanceHandle
+CLayerTimelineItemBinding::GetImage(qt3dsdm::Qt3DSDMPropertyHandle inPropertyHandle)
+{
+ qt3dsdm::IPropertySystem *thePropertySystem = m_TransMgr->GetStudioSystem()->GetPropertySystem();
+ SValue theImageValue;
+ thePropertySystem->GetInstancePropertyValue(m_DataHandle, inPropertyHandle, theImageValue);
+ SLong4 theImageLong4 = qt3dsdm::get<SLong4>(theImageValue);
+ return m_TransMgr->GetStudioSystem()->GetClientDataModelBridge()->GetImageInstanceByGUID(
+ theImageLong4);
+}
+
+ITimelineItemBinding *
+CLayerTimelineItemBinding::GetOrCreateImageBinding(qt3dsdm::Qt3DSDMPropertyHandle inPropertyHandle,
+ const wchar_t *inName)
+{
+ qt3dsdm::Qt3DSDMInstanceHandle theImageInstance = GetImage(inPropertyHandle);
+ if (!theImageInstance.Valid())
+ return nullptr;
+ ITimelineItemBinding *theImageTimelineRow = m_TransMgr->GetBinding(theImageInstance);
+ if (!theImageTimelineRow) // create
+ {
+ theImageTimelineRow = m_TransMgr->GetOrCreate(theImageInstance);
+ // Set the name, by spec: the nice name.
+ theImageTimelineRow->GetTimelineItem()->SetName(inName);
+ CImageTimelineItemBinding *theImageBinding =
+ dynamic_cast<CImageTimelineItemBinding *>(theImageTimelineRow);
+ if (theImageBinding)
+ theImageBinding->SetPropertyHandle(inPropertyHandle);
+ }
+ return theImageTimelineRow;
+}
+
+ITimelineItemBinding *CLayerTimelineItemBinding::GetOrCreateBinding(Qt3DSDMInstanceHandle instance)
+{
+ if (instance.Valid()) {
+ qt3dsdm::Qt3DSDMInstanceHandle theInstance = GetInstance();
+ qt3dsdm::IPropertySystem *thePropertySystem =
+ m_TransMgr->GetStudioSystem()->GetPropertySystem();
+ std::shared_ptr<IDataCore> theDataCore =
+ m_TransMgr->GetStudioSystem()->GetFullSystem()->GetCoreSystem()->GetDataCore();
+ ISlideSystem *theSlideSystem = m_TransMgr->GetStudioSystem()->GetSlideSystem();
+ ISlideCore *theSlideCore = m_TransMgr->GetStudioSystem()->GetSlideCore();
+
+ size_t theSlotCursor = (size_t)-1;
+ {
+ qt3dsdm::IPropertySystem *thePropertySystem =
+ m_TransMgr->GetStudioSystem()->GetPropertySystem();
+ qt3dsdm::SLong4 theGuid;
+ {
+ Qt3DSDMPropertyHandle theTypeProperty =
+ thePropertySystem->GetAggregateInstancePropertyByName(instance, L"id");
+ SValue theIdValue;
+ thePropertySystem->GetInstancePropertyValue(instance, theTypeProperty, theIdValue);
+ theGuid = qt3dsdm::get<qt3dsdm::SLong4>(theIdValue);
+ }
+ for (size_t theSlotIndex = 0, theSlotCount = m_ImageNameFormalNamePairs.size();
+ theSlotIndex < theSlotCount; ++theSlotIndex) {
+ bool theIsMatch = false;
+ qt3dsdm::Qt3DSDMPropertyHandle theProperty =
+ std::get<2>(m_ImageNameFormalNamePairs[theSlotIndex]);
+ SValue theValue;
+ const Qt3DSDMPropertyDefinition &theDefinition(
+ theDataCore->GetProperty(theProperty));
+ if (theDefinition.m_Type == DataModelDataType::Long4) {
+ SValue theDCValue;
+ if (theDataCore->GetInstancePropertyValue(theInstance, theProperty,
+ theDCValue)) {
+ SLong4 thePropGuid = get<SLong4>(theDCValue);
+ if (thePropGuid == theGuid)
+ theIsMatch = true;
+ }
+ Qt3DSDMSlideHandle theSlide =
+ theSlideSystem->GetAssociatedSlide(instance);
+ Qt3DSDMSlideHandle theMasterSlide = theSlideSystem->GetMasterSlide(theSlide);
+ if (theIsMatch == false && theSlide.Valid()
+ && theSlideCore->GetSpecificInstancePropertyValue(
+ theSlide, theInstance, theProperty, theValue)) {
+ SLong4 thePropGuid = get<SLong4>(theValue);
+ if (thePropGuid == theGuid)
+ theIsMatch = true;
+ }
+ }
+ if (theIsMatch) {
+ theSlotCursor = theSlotIndex;
+ break;
+ }
+ }
+ }
+ if (theSlotCursor != (size_t)-1) {
+ Qt3DSDMPropertyHandle theImageProperty =
+ thePropertySystem->GetAggregateInstancePropertyByName(
+ m_DataHandle, std::get<0>(m_ImageNameFormalNamePairs[theSlotCursor]));
+ return GetOrCreateImageBinding(
+ theImageProperty,
+ std::get<1>(m_ImageNameFormalNamePairs[theSlotCursor]).wide_str());
+ } else
+ return m_TransMgr->GetOrCreate(instance);
+ }
+ return nullptr;
+}
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/LayerTimelineItemBinding.h b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/LayerTimelineItemBinding.h
new file mode 100644
index 00000000..74630a64
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/LayerTimelineItemBinding.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//==============================================================================
+// Prefix
+//==============================================================================
+#ifndef INCLUDED_LAYER_TIMELINEITEM_BINDING_H
+#define INCLUDED_LAYER_TIMELINEITEM_BINDING_H 1
+
+#pragma once
+
+#include "Qt3DSDMTimelineItemBinding.h"
+
+namespace qt3dsdm {
+class CStudioSystem;
+}
+
+//=============================================================================
+/**
+ * Binding to generic DataModel object
+ */
+class CLayerTimelineItemBinding : public Qt3DSDMTimelineItemBinding
+{
+public: // Types
+ typedef std::tuple<qt3dsdm::TCharStr, qt3dsdm::TCharStr, qt3dsdm::Qt3DSDMPropertyHandle>
+ TNameFormalNamePair;
+ typedef std::vector<TNameFormalNamePair> TNameFormalNamePairList;
+
+protected: // Members
+ TNameFormalNamePairList m_ImageNameFormalNamePairs;
+
+public: // Construction
+ CLayerTimelineItemBinding(CTimelineTranslationManager *inMgr,
+ qt3dsdm::Qt3DSDMInstanceHandle inDataHandle);
+ virtual ~CLayerTimelineItemBinding();
+
+public: // Qt3DSDMTimelineItemBinding
+ EStudioObjectType GetObjectType() const override;
+ // Hierarchy
+ ITimelineItemBinding *GetChild(long inIndex) override;
+ QList<ITimelineItemBinding *> GetChildren() override;
+ void OnAddChild(qt3dsdm::Qt3DSDMInstanceHandle inInstance) override;
+ // Event callback
+ void OnPropertyChanged(qt3dsdm::Qt3DSDMPropertyHandle inPropertyHandle) override;
+
+protected:
+ qt3dsdm::Qt3DSDMInstanceHandle GetImage(qt3dsdm::Qt3DSDMPropertyHandle inPropertyHandle);
+ ITimelineItemBinding *GetOrCreateImageBinding(qt3dsdm::Qt3DSDMPropertyHandle inPropertyHandle,
+ const wchar_t *inName);
+ ITimelineItemBinding *GetOrCreateBinding(qt3dsdm::Qt3DSDMInstanceHandle instance);
+};
+
+#endif // INCLUDED_LAYER_TIMELINEITEM_BINDING_H
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/MaterialTimelineItemBinding.cpp b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/MaterialTimelineItemBinding.cpp
new file mode 100644
index 00000000..e3483969
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/MaterialTimelineItemBinding.cpp
@@ -0,0 +1,210 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "Qt3DSCommonPrecompile.h"
+#include "MaterialTimelineItemBinding.h"
+#include "TimelineTranslationManager.h"
+#include "ImageTimelineItemBinding.h"
+#include "EmptyTimelineTimebar.h"
+
+// Data model specific
+#include "IDoc.h"
+#include "ClientDataModelBridge.h"
+#include "DropSource.h"
+
+#include "Qt3DSDMHandles.h"
+#include "Qt3DSDMStudioSystem.h"
+
+#include "Qt3DSDMMetaData.h"
+#include "Qt3DSDMDataCore.h"
+#include "StudioFullSystem.h"
+#include "StudioCoreSystem.h"
+
+using namespace qt3dsdm;
+
+CMaterialTimelineItemBinding::CMaterialTimelineItemBinding(CTimelineTranslationManager *inMgr,
+ Qt3DSDMInstanceHandle inDataHandle)
+ : Qt3DSDMTimelineItemBinding(inMgr, inDataHandle)
+{
+ qt3dsdm::IPropertySystem *thePropertySystem = m_TransMgr->GetStudioSystem()->GetPropertySystem();
+ TPropertyHandleList theProperties;
+ thePropertySystem->GetAggregateInstanceProperties(inDataHandle, theProperties);
+
+ size_t thePropertyCount = theProperties.size();
+ for (size_t thePropertyIndex = 0; thePropertyIndex < thePropertyCount; ++thePropertyIndex) {
+ Qt3DSDMPropertyHandle theProperty = theProperties[thePropertyIndex];
+
+ AdditionalMetaDataType::Value theAdditionalMetaDataType =
+ thePropertySystem->GetAdditionalMetaDataType(inDataHandle, theProperty);
+
+ if (theAdditionalMetaDataType == AdditionalMetaDataType::Image) {
+ TCharStr theName(thePropertySystem->GetName(theProperty));
+ TCharStr theFormalName(thePropertySystem->GetFormalName(inDataHandle, theProperty));
+ TNameFormalNamePair thePair = std::make_tuple(theName, theFormalName);
+ m_ImageNameFormalNamePairs.push_back(thePair);
+ }
+ }
+}
+
+CMaterialTimelineItemBinding::~CMaterialTimelineItemBinding()
+{
+}
+
+ITimelineTimebar *CMaterialTimelineItemBinding::GetTimebar()
+{ // No timebars on materials
+ return new CEmptyTimelineTimebar();
+}
+
+bool CMaterialTimelineItemBinding::ShowToggleControls() const
+{
+ // Materials have no toggle controls, by design
+ return false;
+}
+
+bool ImageSlotIsFilled(qt3dsdm::IPropertySystem *inPropertySystem, Qt3DSDMInstanceHandle inInstance,
+ const TCharStr &inStr)
+{
+ Qt3DSDMPropertyHandle theProperty =
+ inPropertySystem->GetAggregateInstancePropertyByName(inInstance, inStr);
+ SValue theValue;
+ inPropertySystem->GetInstancePropertyValue(inInstance, theProperty, theValue);
+
+ // Prevent assertion down the path when changing from edited standard material to reference material
+ if (qt3dsdm::GetValueType(theValue) == DataModelDataType::None)
+ return false;
+
+ SLong4 theLong4 = qt3dsdm::get<SLong4>(theValue);
+ bool theReturn = theLong4.m_Longs[0] != 0 || theLong4.m_Longs[1] != 0
+ || theLong4.m_Longs[2] != 0 || theLong4.m_Longs[3] != 0;
+
+ return theReturn;
+}
+
+long CMaterialTimelineItemBinding::GetChildrenCount()
+{
+ long theReturnCount = 0;
+ if (m_TransMgr->GetStudioSystem()->IsInstance(m_DataHandle)) {
+ qt3dsdm::IPropertySystem *thePropertySystem =
+ m_TransMgr->GetStudioSystem()->GetPropertySystem();
+ size_t theSlotCount = m_ImageNameFormalNamePairs.size();
+ for (size_t theSlotIndex = 0; theSlotIndex < theSlotCount; ++theSlotIndex) {
+ if (ImageSlotIsFilled(thePropertySystem, m_DataHandle,
+ std::get<0>(m_ImageNameFormalNamePairs[theSlotIndex]))) {
+ ++theReturnCount;
+ }
+ }
+ }
+
+ return theReturnCount;
+}
+
+ITimelineItemBinding *CMaterialTimelineItemBinding::GetChild(long inIndex)
+{
+ qt3dsdm::IPropertySystem *thePropertySystem = m_TransMgr->GetStudioSystem()->GetPropertySystem();
+
+ size_t theSlotCursor = 0;
+ size_t theSlotCount = m_ImageNameFormalNamePairs.size();
+ for (size_t theSlotIndex = 0; theSlotIndex < theSlotCount; ++theSlotIndex) {
+ if (ImageSlotIsFilled(thePropertySystem, m_DataHandle,
+ std::get<0>(m_ImageNameFormalNamePairs[theSlotIndex]))) {
+ inIndex--;
+
+ if (inIndex < 0) {
+ theSlotCursor = theSlotIndex;
+ break;
+ }
+ }
+ }
+ Qt3DSDMPropertyHandle theImageProperty = thePropertySystem->GetAggregateInstancePropertyByName(
+ m_DataHandle, std::get<0>(m_ImageNameFormalNamePairs[theSlotCursor]));
+ return GetOrCreateImageBinding(
+ theImageProperty, std::get<1>(m_ImageNameFormalNamePairs[theSlotCursor]).wide_str());
+}
+
+QList<ITimelineItemBinding *> CMaterialTimelineItemBinding::GetChildren()
+{
+ int childCount = GetChildrenCount();
+ QList<ITimelineItemBinding *> retlist;
+ retlist.reserve(childCount);
+ for (int i = 0; i < childCount; ++i)
+ retlist.append(GetChild(i));
+
+ return retlist;
+}
+
+void CMaterialTimelineItemBinding::OnAddChild(qt3dsdm::Qt3DSDMInstanceHandle inInstance)
+{
+ using namespace qt3dsdm;
+ CClientDataModelBridge *theBridge = m_TransMgr->GetStudioSystem()->GetClientDataModelBridge();
+ // This is handled via the OnPropertyChanged call below
+ if (theBridge->IsImageInstance(inInstance))
+ return;
+ else
+ Qt3DSDMTimelineItemBinding::OnAddChild(inInstance);
+}
+
+void CMaterialTimelineItemBinding::OnPropertyChanged(Qt3DSDMPropertyHandle inPropertyHandle)
+{
+ Qt3DSDMTimelineItemBinding::OnPropertyChanged(inPropertyHandle);
+}
+
+void CMaterialTimelineItemBinding::OnPropertyLinked(Qt3DSDMPropertyHandle inPropertyHandle)
+{
+ Qt3DSDMTimelineItemBinding::OnPropertyLinked(inPropertyHandle);
+}
+
+qt3dsdm::Qt3DSDMInstanceHandle
+CMaterialTimelineItemBinding::GetImage(qt3dsdm::Qt3DSDMPropertyHandle inPropertyHandle)
+{
+ qt3dsdm::IPropertySystem *thePropertySystem = m_TransMgr->GetStudioSystem()->GetPropertySystem();
+ SValue theImageValue;
+ thePropertySystem->GetInstancePropertyValue(m_DataHandle, inPropertyHandle, theImageValue);
+ SLong4 theImageLong4 = qt3dsdm::get<SLong4>(theImageValue);
+ return m_TransMgr->GetStudioSystem()->GetClientDataModelBridge()->GetImageInstanceByGUID(
+ theImageLong4);
+}
+
+ITimelineItemBinding *
+CMaterialTimelineItemBinding::GetOrCreateImageBinding(qt3dsdm::Qt3DSDMPropertyHandle inPropertyHandle,
+ const wchar_t *inName)
+{
+ qt3dsdm::Qt3DSDMInstanceHandle theImageInstance = GetImage(inPropertyHandle);
+ ITimelineItemBinding *theImageTimelineRow = m_TransMgr->GetBinding(theImageInstance);
+ if (!theImageTimelineRow) // create
+ {
+ theImageTimelineRow = m_TransMgr->GetOrCreate(theImageInstance);
+ // Set the name, by spec: the nice name.
+ theImageTimelineRow->GetTimelineItem()->SetName(inName);
+ CImageTimelineItemBinding *theImageBinding =
+ dynamic_cast<CImageTimelineItemBinding *>(theImageTimelineRow);
+ if (theImageBinding)
+ theImageBinding->SetPropertyHandle(inPropertyHandle);
+ }
+ return theImageTimelineRow;
+}
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/MaterialTimelineItemBinding.h b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/MaterialTimelineItemBinding.h
new file mode 100644
index 00000000..8e188a52
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/MaterialTimelineItemBinding.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//==============================================================================
+// Prefix
+//==============================================================================
+#ifndef INCLUDED_MATERIAL_TIMELINEITEM_BINDING_H
+#define INCLUDED_MATERIAL_TIMELINEITEM_BINDING_H 1
+
+#pragma once
+
+#include "Qt3DSDMTimelineItemBinding.h"
+#include "Qt3DSDMDataTypes.h"
+
+//==============================================================================
+// Classes
+//==============================================================================
+class CTimelineTranslationManager;
+
+//=============================================================================
+/**
+ * Binding to a DataModel object of Material type
+ */
+class CMaterialTimelineItemBinding : public Qt3DSDMTimelineItemBinding
+{
+public: // Types
+ typedef std::tuple<qt3dsdm::TCharStr, qt3dsdm::TCharStr> TNameFormalNamePair;
+ typedef std::vector<TNameFormalNamePair> TNameFormalNamePairList;
+
+protected: // Members
+ TNameFormalNamePairList m_ImageNameFormalNamePairs;
+
+public: // Construction
+ CMaterialTimelineItemBinding(CTimelineTranslationManager *inMgr,
+ qt3dsdm::Qt3DSDMInstanceHandle inDataHandle);
+ virtual ~CMaterialTimelineItemBinding();
+
+public: // Qt3DSDMTimelineItemBinding
+ ITimelineTimebar *GetTimebar() override;
+ bool ShowToggleControls() const override;
+ // Hierarchy
+ long GetChildrenCount() override;
+ ITimelineItemBinding *GetChild(long inIndex) override;
+ QList<ITimelineItemBinding *> GetChildren() override;
+ void OnAddChild(qt3dsdm::Qt3DSDMInstanceHandle inInstance) override;
+ // Event callback
+ void OnPropertyChanged(qt3dsdm::Qt3DSDMPropertyHandle inPropertyHandle) override;
+ void OnPropertyLinked(qt3dsdm::Qt3DSDMPropertyHandle inPropertyHandle) override;
+
+protected:
+ qt3dsdm::Qt3DSDMInstanceHandle GetImage(qt3dsdm::Qt3DSDMPropertyHandle inPropertyHandle);
+ ITimelineItemBinding *GetOrCreateImageBinding(qt3dsdm::Qt3DSDMPropertyHandle inPropertyHandle,
+ const wchar_t *inName);
+};
+
+#endif // INCLUDED_MATERIAL_TIMELINEITEM_BINDING_H
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/OffsetKeyframesCommandHelper.cpp b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/OffsetKeyframesCommandHelper.cpp
new file mode 100644
index 00000000..a0c4ee99
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/OffsetKeyframesCommandHelper.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "Qt3DSCommonPrecompile.h"
+#include "OffsetKeyframesCommandHelper.h"
+#include "Core.h"
+
+// Data model specific
+#include "IDoc.h"
+#include "CmdDataModelChangeKeyframe.h"
+#include "IDocumentEditor.h"
+
+#include "Qt3DSDMTimelineKeyframe.h" //TODO: remove once we resolve the precision issue
+
+using namespace qt3dsdm;
+
+COffsetKeyframesCommandHelper::COffsetKeyframesCommandHelper(CDoc &inDoc)
+ : Q3DStudio::CUpdateableDocumentEditor(inDoc)
+ , m_Doc(inDoc)
+{
+}
+
+COffsetKeyframesCommandHelper::~COffsetKeyframesCommandHelper()
+{
+ Finalize();
+}
+
+//@param inTime time in millisecs
+void COffsetKeyframesCommandHelper::SetCommandTime(qt3dsdm::Qt3DSDMKeyframeHandle inKeyframe,
+ long inTime)
+{
+ // The DataModel system will take care of merging these under the hood.
+ ENSURE_EDITOR(QObject::tr("Set Keyframe Time")).SetKeyframeTime(inKeyframe, inTime);
+}
+
+// equivalent to commit (onmouseup)
+void COffsetKeyframesCommandHelper::Finalize()
+{
+ CommitEditor();
+}
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/OffsetKeyframesCommandHelper.h b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/OffsetKeyframesCommandHelper.h
new file mode 100644
index 00000000..0e57773e
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/OffsetKeyframesCommandHelper.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//==============================================================================
+// Prefix
+//==============================================================================
+#ifndef INCLUDED_OFFSET_KEYFRAMES_COMMAND_HELPER_H
+#define INCLUDED_OFFSET_KEYFRAMES_COMMAND_HELPER_H 1
+
+#pragma once
+
+// Data model
+#include "Qt3DSDMHandles.h"
+#include "IDocumentEditor.h"
+
+namespace Q3DStudio {
+class IDocumentEditor;
+}
+
+//==============================================================================
+// Classes
+//==============================================================================
+class CCmdDataModelSetKeyframeTime;
+
+class COffsetKeyframesCommandHelper : public Q3DStudio::CUpdateableDocumentEditor
+{
+protected:
+ CDoc &m_Doc;
+
+public:
+ COffsetKeyframesCommandHelper(CDoc &inDoc);
+ ~COffsetKeyframesCommandHelper();
+
+ void SetCommandTime(qt3dsdm::Qt3DSDMKeyframeHandle inKeyframe, long inTime);
+ void Finalize();
+ void Rollback() { RollbackEditor(); }
+};
+
+#endif \ No newline at end of file
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/PasteKeyframesCommandHelper.h b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/PasteKeyframesCommandHelper.h
new file mode 100644
index 00000000..ead15d2e
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/PasteKeyframesCommandHelper.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef INCLUDED_PASTE_KEYFRAME_COMMAND_HELPER_H
+#define INCLUDED_PASTE_KEYFRAME_COMMAND_HELPER_H 1
+
+#pragma once
+
+//==============================================================================
+// Include
+//==============================================================================
+#include "CmdDataModelInsertKeyframe.h"
+#include "Qt3DSDMPropertyDefinition.h"
+#include "Qt3DSDMDataCore.h"
+
+// This caches all copied keyframes' time and data, for a paste action.
+// This has to deal with the actual data and not keyframe handles, because a prior Cut can
+// invalidate those handles.
+class CPasteKeyframeCommandHelper
+{
+protected:
+ typedef std::vector<CCmdDataModelInsertKeyframe::STimeKeyframeData> TCopiedKeyframeList;
+ TCopiedKeyframeList m_CopiedKeyframeList;
+
+public: // Construction
+ CPasteKeyframeCommandHelper() {}
+ ~CPasteKeyframeCommandHelper() {}
+
+ // inTime should be relative to the earliest keyframe time in this list
+ void AddKeyframeData(qt3dsdm::Qt3DSDMPropertyHandle inProperty, float inKeyframeTime,
+ qt3dsdm::SGetOrSetKeyframeInfo *inInfos, size_t inInfoCount)
+ {
+ m_CopiedKeyframeList.push_back(CCmdDataModelInsertKeyframe::STimeKeyframeData(
+ inProperty, inKeyframeTime, inInfos, inInfoCount));
+ }
+
+ bool HasCopiedKeyframes() const { return !m_CopiedKeyframeList.empty(); }
+
+ // Triggered by a "Paste Keyframe" action
+ // Note: The logic is based on what the Animation Manager in the old system used to do.
+ // 1. The condition for paste to occur is that the property name matches.
+ // The old data model has a limitation that if the destination property is a linked property,
+ // the source has to come from the same instance, most likely a easy way out than to deal with
+ // with having to 'sync' all linked animation tracks.
+ // but that is not an issue in the new data model.
+ //
+ // 2. The first pasted keyframe is at current view time and the rest are offset accordingly.
+ CCmdDataModelInsertKeyframe *GetCommand(CDoc *inDoc, long inTimeOffsetInMilliseconds,
+ qt3dsdm::Qt3DSDMInstanceHandle inTargetInstance)
+ {
+ using namespace qt3dsdm;
+
+ CCmdDataModelInsertKeyframe *theInsertKeyframesCommand = nullptr;
+ TCopiedKeyframeList::iterator theIter = m_CopiedKeyframeList.begin();
+ qt3dsdm::IPropertySystem *thePropertySystem = inDoc->GetStudioSystem()->GetPropertySystem();
+ CClientDataModelBridge *theBridge = inDoc->GetStudioSystem()->GetClientDataModelBridge();
+
+ for (; theIter != m_CopiedKeyframeList.end(); ++theIter) {
+ TCharStr thePropertyName = thePropertySystem->GetName(theIter->m_Property);
+ DataModelDataType::Value thePropertyType =
+ thePropertySystem->GetDataType(theIter->m_Property);
+ Qt3DSDMPropertyHandle theTargetPropertyHandle =
+ theBridge->GetAggregateInstancePropertyByName(inTargetInstance, thePropertyName);
+ if (theTargetPropertyHandle.Valid()) // property exists on target
+ {
+ // sanity check for type match
+ DataModelDataType::Value theTargetPropertyType =
+ thePropertySystem->GetDataType(theTargetPropertyHandle);
+ if (theTargetPropertyType == thePropertyType) {
+ // 2. Offset keyframe time by current view time
+ double milliseconds = theIter->m_KeyframeTime * 1000.0;
+ double theTimeInMilliseconds = milliseconds + inTimeOffsetInMilliseconds;
+ float theTimeInSeconds = static_cast<float>(theTimeInMilliseconds / 1000.0);
+
+ if (!theInsertKeyframesCommand)
+ theInsertKeyframesCommand = new CCmdDataModelInsertKeyframe(
+ inDoc, inTargetInstance, theTargetPropertyHandle, theTimeInSeconds,
+ theIter->m_Infos, theIter->m_ValidInfoCount);
+ else
+ theInsertKeyframesCommand->AddKeyframeData(
+ theTargetPropertyHandle, theTimeInSeconds, theIter->m_Infos,
+ theIter->m_ValidInfoCount);
+ }
+ }
+ }
+ return theInsertKeyframesCommand;
+ }
+
+ void Clear() { m_CopiedKeyframeList.clear(); }
+};
+
+#endif
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/PathAnchorPointTimelineItemBinding.cpp b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/PathAnchorPointTimelineItemBinding.cpp
new file mode 100644
index 00000000..192c4414
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/PathAnchorPointTimelineItemBinding.cpp
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "Qt3DSCommonPrecompile.h"
+#include "PathAnchorPointTimelineItemBinding.h"
+#include "EmptyTimelineTimebar.h"
+
+using namespace qt3dsdm;
+
+CPathAnchorPointTimelineItemBinding::CPathAnchorPointTimelineItemBinding(
+ CTimelineTranslationManager *inMgr, Qt3DSDMInstanceHandle inDataHandle)
+ : Qt3DSDMTimelineItemBinding(inMgr, inDataHandle)
+{
+}
+
+ITimelineTimebar *CPathAnchorPointTimelineItemBinding::GetTimebar()
+{
+ return new CEmptyTimelineTimebar();
+}
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/PathAnchorPointTimelineItemBinding.h b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/PathAnchorPointTimelineItemBinding.h
new file mode 100644
index 00000000..b806093d
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/PathAnchorPointTimelineItemBinding.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//==============================================================================
+// Prefix
+//==============================================================================
+#ifndef PATH_ANCHOR_POINT_TIMELINE_ITEM_BINDING
+#define PATH_ANCHOR_POINT_TIMELINE_ITEM_BINDING
+#pragma once
+
+#include "Qt3DSDMTimelineItemBinding.h"
+#include "Qt3DSDMDataTypes.h"
+
+//==============================================================================
+// Classes
+//==============================================================================
+class CTimelineTranslationManager;
+
+//=============================================================================
+/**
+ * Binding to a DataModel object of Material type
+ */
+class CPathAnchorPointTimelineItemBinding : public Qt3DSDMTimelineItemBinding
+{
+public: // Construction
+ CPathAnchorPointTimelineItemBinding(CTimelineTranslationManager *inMgr,
+ qt3dsdm::Qt3DSDMInstanceHandle inDataHandle);
+
+ bool ShowToggleControls() const override { return false; }
+ bool IsVisible() const override { return true; }
+ void SetVisible(bool) override {}
+ ITimelineTimebar *GetTimebar() override;
+ bool IsLocked() const override { return false; }
+ void SetLocked(bool) override {}
+ bool IsShy() const override { return false; }
+ void SetShy(bool) override {}
+ bool IsVisibilityControlled() const override { return false; }
+ Q3DStudio::CString GetName() const override { return L"Anchor Point"; }
+ void SetName(const Q3DStudio::CString &) override {}
+};
+
+#endif
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/PathTimelineItemBinding.cpp b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/PathTimelineItemBinding.cpp
new file mode 100644
index 00000000..f646415d
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/PathTimelineItemBinding.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "Qt3DSCommonPrecompile.h"
+#include "PathTimelineItemBinding.h"
+#include "TimelineTranslationManager.h"
+#include "Doc.h"
+
+bool CPathTimelineItemBinding::IsExternalizeable()
+{
+ // If this path has subpath children, then it is externalizeable.
+ return m_TransMgr->GetDoc()->GetDocumentReader().IsPathExternalizeable(GetInstance());
+}
+
+void CPathTimelineItemBinding::Externalize()
+{
+ Q3DStudio::ScopedDocumentEditor(*m_TransMgr->GetDoc(), QObject::tr("Externalize Path Buffer"),
+ __FILE__, __LINE__)
+ ->ExternalizePath(GetInstance());
+}
+
+bool CPathTimelineItemBinding::IsInternalizeable()
+{
+ // If this path has a sourcepath, then it might be internalizeable
+ return m_TransMgr->GetDoc()->GetDocumentReader().IsPathInternalizeable(GetInstance());
+}
+
+void CPathTimelineItemBinding::Internalize()
+{
+ Q3DStudio::ScopedDocumentEditor(*m_TransMgr->GetDoc(), QObject::tr("Internalize Path Buffer"),
+ __FILE__, __LINE__)
+ ->InternalizePath(GetInstance());
+}
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/PathTimelineItemBinding.h b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/PathTimelineItemBinding.h
new file mode 100644
index 00000000..ea006044
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/PathTimelineItemBinding.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//==============================================================================
+// Prefix
+//==============================================================================
+#ifndef PATH_TIMELINE_ITEM_BINDING
+#define PATH_TIMELINE_ITEM_BINDING
+#pragma once
+#include "Qt3DSDMTimelineItemBinding.h"
+#include "Qt3DSDMDataTypes.h"
+
+//==============================================================================
+// Classes
+//==============================================================================
+class CTimelineTranslationManager;
+
+//=============================================================================
+/**
+ * Binding to a DataModel object of Material type
+ */
+class CPathTimelineItemBinding : public Qt3DSDMTimelineItemBinding
+{
+public: // Construction
+ CPathTimelineItemBinding(CTimelineTranslationManager *inMgr,
+ qt3dsdm::Qt3DSDMInstanceHandle inDataHandle)
+ : Qt3DSDMTimelineItemBinding(inMgr, inDataHandle)
+ {
+ }
+
+ bool IsExternalizeable() override;
+ void Externalize() override;
+ bool IsInternalizeable() override;
+ void Internalize() override;
+};
+
+#endif
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMAssetTimelineKeyframe.cpp b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMAssetTimelineKeyframe.cpp
new file mode 100644
index 00000000..65b0d852
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMAssetTimelineKeyframe.cpp
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "Qt3DSCommonPrecompile.h"
+#include "Qt3DSDMAssetTimelineKeyframe.h"
+#include "Qt3DSDMTimelineItemBinding.h"
+
+using namespace qt3dsdm;
+
+Qt3DSDMAssetTimelineKeyframe::Qt3DSDMAssetTimelineKeyframe(Qt3DSDMTimelineItemBinding *inOwningBinding,
+ long inTime)
+ : m_OwningBinding(inOwningBinding)
+ , m_Time(inTime)
+ , m_Selected(false)
+{
+}
+
+Qt3DSDMAssetTimelineKeyframe::~Qt3DSDMAssetTimelineKeyframe()
+{
+}
+
+Keyframe *Qt3DSDMAssetTimelineKeyframe::getUI()
+{
+ return m_ui;
+}
+
+void Qt3DSDMAssetTimelineKeyframe::setUI(Keyframe *kfUI)
+{
+ m_ui = kfUI;
+}
+
+bool Qt3DSDMAssetTimelineKeyframe::IsSelected() const
+{
+ return m_Selected;
+}
+
+long Qt3DSDMAssetTimelineKeyframe::GetTime() const
+{
+ return m_Time;
+}
+
+void Qt3DSDMAssetTimelineKeyframe::SetTime(const long inNewTime)
+{
+ Q_UNUSED(inNewTime);
+ // note: this is not used. because setting time is currently only done through offsetting by
+ // moving keyframes OR using the edit time dialog.
+ Q_ASSERT(0);
+}
+
+void Qt3DSDMAssetTimelineKeyframe::SetDynamic(bool inIsDynamic)
+{
+ m_OwningBinding->SetDynamicKeyframes(m_Time, inIsDynamic);
+}
+
+bool Qt3DSDMAssetTimelineKeyframe::IsDynamic() const
+{
+ // return true if any of its property keyframes is dynamic
+ return m_OwningBinding->HasDynamicKeyframes(m_Time);
+}
+
+void Qt3DSDMAssetTimelineKeyframe::SetSelected(bool inSelected)
+{
+ m_Selected = inSelected;
+}
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMAssetTimelineKeyframe.h b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMAssetTimelineKeyframe.h
new file mode 100644
index 00000000..cf99cf8c
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMAssetTimelineKeyframe.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QT3DSDM_ASSET_KEYFRAME_H
+#define QT3DSDM_ASSET_KEYFRAME_H 1
+
+#pragma once
+
+#include "IKeyframe.h"
+
+// Data model specific
+#include "Qt3DSDMHandles.h"
+
+class Qt3DSDMTimelineItemBinding;
+
+//==============================================================================
+/**
+ * Represents a keyframe displayed for a Asset( e.g. material ), for all keyframes (of the
+ *animated properties) at time t.
+ */
+//==============================================================================
+class Qt3DSDMAssetTimelineKeyframe : public IKeyframe
+{
+protected:
+ Qt3DSDMTimelineItemBinding *m_OwningBinding;
+ long m_Time;
+ bool m_Selected;
+
+public:
+ Qt3DSDMAssetTimelineKeyframe(Qt3DSDMTimelineItemBinding *inOwningBinding, long inTime);
+ virtual ~Qt3DSDMAssetTimelineKeyframe();
+
+ // IKeyframe
+ bool IsSelected() const override;
+ long GetTime() const override;
+ void SetTime(const long inNewTime) override;
+ void SetDynamic(bool inIsDynamic) override;
+ Keyframe *getUI() override;
+ void setUI(Keyframe *kfUI) override;
+ bool IsDynamic() const override;
+
+ void SetSelected(bool inSelected);
+ void UpdateTime(const long inTime) { m_Time = inTime; }
+
+private:
+ Keyframe *m_ui;
+};
+
+#endif // QT3DSDM_ASSET_KEYFRAME_H
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimeline.h b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimeline.h
new file mode 100644
index 00000000..18624897
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimeline.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DSDM_TIMELINE_H
+#define QT3DSDM_TIMELINE_H 1
+
+#pragma once
+
+enum ETimelineKeyframeTransaction {
+ ETimelineKeyframeTransaction_Add,
+ ETimelineKeyframeTransaction_Delete,
+ ETimelineKeyframeTransaction_Update,
+ ETimelineKeyframeTransaction_DynamicChanged,
+};
+
+#endif
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.cpp b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.cpp
new file mode 100644
index 00000000..d71ef582
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.cpp
@@ -0,0 +1,1164 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "Qt3DSCommonPrecompile.h"
+#include "Qt3DSDMTimelineItemBinding.h"
+#include "TimelineTranslationManager.h"
+#include "TimeEditDlg.h"
+#include "EmptyTimelineTimebar.h"
+#include "Qt3DSDMTimelineTimebar.h"
+#include "StudioApp.h"
+#include "Core.h"
+#include "Dialogs.h"
+#include "GraphUtils.h"
+#include "Qt3DSDMDataCore.h"
+#include "DropTarget.h"
+
+// Data model specific
+#include "IDoc.h"
+#include "ClientDataModelBridge.h"
+#include "Dispatch.h"
+#include "DropSource.h"
+#include "Qt3DSDMTimelineItemProperty.h"
+#include "Qt3DSDMSlides.h"
+#include "Qt3DSDMStudioSystem.h"
+#include "Qt3DSDMSlideGraphCore.h"
+#include "Qt3DSDMActionCore.h"
+#include "Qt3DSDMAnimation.h"
+#include "CmdDataModelChangeKeyframe.h"
+#include "RelativePathTools.h"
+#include "IDocumentEditor.h"
+#include "Qt3DSFileTools.h"
+#include "ImportUtils.h"
+
+#include <QtWidgets/qmessagebox.h>
+
+using namespace qt3dsdm;
+
+Qt3DSDMTimelineItemBinding::Qt3DSDMTimelineItemBinding(CTimelineTranslationManager *inMgr,
+ Qt3DSDMInstanceHandle inDataHandle)
+ : m_TransMgr(inMgr)
+ , m_DataHandle(inDataHandle)
+ , m_Parent(nullptr)
+ , m_TimelineTimebar(nullptr)
+
+{
+ m_StudioSystem = m_TransMgr->GetStudioSystem();
+}
+
+Qt3DSDMTimelineItemBinding::Qt3DSDMTimelineItemBinding(CTimelineTranslationManager *inMgr)
+ : m_TransMgr(inMgr)
+ , m_DataHandle(0)
+ , m_Parent(nullptr)
+ , m_TimelineTimebar(nullptr)
+{
+ m_StudioSystem = m_TransMgr->GetStudioSystem();
+}
+
+Qt3DSDMTimelineItemBinding::~Qt3DSDMTimelineItemBinding()
+{
+ RemoveAllPropertyBindings();
+ delete m_TimelineTimebar;
+}
+
+// helpers
+bool Qt3DSDMTimelineItemBinding::GetBoolean(qt3dsdm::Qt3DSDMPropertyHandle inProperty) const
+{
+ qt3dsdm::IPropertySystem *thePropertySystem = m_StudioSystem->GetPropertySystem();
+ SValue theValue;
+ thePropertySystem->GetInstancePropertyValue(m_DataHandle, inProperty, theValue);
+ return qt3dsdm::get<bool>(theValue);
+}
+
+void Qt3DSDMTimelineItemBinding::SetBoolean(qt3dsdm::Qt3DSDMPropertyHandle inProperty,
+ bool inValue, const QString &inNiceText) const
+{
+ CDoc *theDoc = dynamic_cast<CDoc *>(g_StudioApp.GetCore()->GetDoc());
+ Q3DStudio::SCOPED_DOCUMENT_EDITOR(*theDoc, inNiceText)
+ ->SetInstancePropertyValue(m_DataHandle, inProperty, inValue);
+}
+
+void Qt3DSDMTimelineItemBinding::SetInstanceHandle(qt3dsdm::Qt3DSDMInstanceHandle inDataHandle)
+{
+ m_DataHandle = inDataHandle;
+}
+
+EStudioObjectType Qt3DSDMTimelineItemBinding::GetObjectType() const
+{
+ return m_StudioSystem->GetClientDataModelBridge()->GetObjectType(m_DataHandle);
+}
+
+bool Qt3DSDMTimelineItemBinding::IsMaster() const
+{
+ CDoc *theDoc = dynamic_cast<CDoc *>(g_StudioApp.GetCore()->GetDoc());
+ Q3DStudio::IDocumentReader &theReader(theDoc->GetDocumentReader());
+ if (GetObjectType() == OBJTYPE_IMAGE) {
+ CClientDataModelBridge *theBridge = m_StudioSystem->GetClientDataModelBridge();
+ Qt3DSDMInstanceHandle theParent;
+ Qt3DSDMPropertyHandle theProperty;
+ bool isPropertyLinked;
+
+ theBridge->GetMaterialFromImageInstance(GetInstance(), theParent, theProperty);
+ isPropertyLinked = theReader.IsPropertyLinked(theParent, theProperty);
+
+ // Also check light probe
+ if (!isPropertyLinked) {
+ theBridge->GetLayerFromImageProbeInstance(GetInstance(), theParent, theProperty);
+ isPropertyLinked = theReader.IsPropertyLinked(theParent, theProperty);
+ }
+
+ return isPropertyLinked;
+ }
+ Qt3DSDMInstanceHandle theQueryHandle(m_DataHandle);
+ if (GetObjectType() == OBJTYPE_PATHANCHORPOINT)
+ theQueryHandle = theReader.GetParent(m_DataHandle);
+
+ // logic: you can't unlink name, so if name is linked then, this is master.
+ Qt3DSDMPropertyHandle theNamePropHandle =
+ m_StudioSystem->GetPropertySystem()->GetAggregateInstancePropertyByName(theQueryHandle,
+ L"name");
+ return theReader.IsPropertyLinked(theQueryHandle, theNamePropHandle);
+}
+
+bool Qt3DSDMTimelineItemBinding::IsShy() const
+{
+ return GetBoolean(m_StudioSystem->GetClientDataModelBridge()->GetSceneAsset().m_Shy);
+}
+void Qt3DSDMTimelineItemBinding::SetShy(bool inShy)
+{
+ SetBoolean(m_StudioSystem->GetClientDataModelBridge()->GetSceneAsset().m_Shy, inShy,
+ QObject::tr("Shy Toggle"));
+}
+bool Qt3DSDMTimelineItemBinding::IsLocked() const
+{
+ return GetBoolean(m_StudioSystem->GetClientDataModelBridge()->GetSceneAsset().m_Locked);
+}
+
+bool Qt3DSDMTimelineItemBinding::IsVisibilityControlled() const
+{
+ if (!m_StudioSystem->IsInstance(m_DataHandle))
+ return false;
+
+ Qt3DSDMPropertyHandle theNamePropHandle =
+ m_StudioSystem->GetPropertySystem()->GetAggregateInstancePropertyByName(
+ m_DataHandle, L"controlledproperty");
+
+ if (!theNamePropHandle)
+ return false;
+ SValue theNameValue;
+ m_StudioSystem->GetPropertySystem()->GetInstancePropertyValue(m_DataHandle, theNamePropHandle,
+ theNameValue);
+ TDataStrPtr theName = qt3dsdm::get<TDataStrPtr>(theNameValue);
+
+ return (wcsstr(theName->GetData(), L"eyeball"));
+}
+
+void ToggleChildrenLock(Q3DStudio::ScopedDocumentEditor &scopedDocEditor,
+ Qt3DSDMTimelineItemBinding *inTimelineItemBinding,
+ SDataModelSceneAsset inSceneAsset, bool inLocked)
+{
+ scopedDocEditor->SetInstancePropertyValue(inTimelineItemBinding->GetInstanceHandle(),
+ inSceneAsset.m_Locked, inLocked);
+ const QList<ITimelineItemBinding *> children = inTimelineItemBinding->GetChildren();
+ for (auto child : children) {
+ ToggleChildrenLock(scopedDocEditor, static_cast<Qt3DSDMTimelineItemBinding *>(child),
+ inSceneAsset, inLocked);
+ }
+}
+
+void Qt3DSDMTimelineItemBinding::SetLocked(bool inLocked)
+{
+ CDoc *theDoc = dynamic_cast<CDoc *>(g_StudioApp.GetCore()->GetDoc());
+ Q3DStudio::ScopedDocumentEditor scopedDocEditor(*theDoc, QObject::tr("SetLock"), __FILE__,
+ __LINE__);
+
+ SDataModelSceneAsset sceneAsset = m_StudioSystem->GetClientDataModelBridge()->GetSceneAsset();
+ ToggleChildrenLock(scopedDocEditor, this, sceneAsset, inLocked);
+
+ if (inLocked)
+ g_StudioApp.GetCore()->GetDoc()->NotifySelectionChanged();
+}
+
+bool Qt3DSDMTimelineItemBinding::IsVisible() const
+{
+ return GetBoolean(m_StudioSystem->GetClientDataModelBridge()->GetSceneAsset().m_Eyeball);
+}
+
+void Qt3DSDMTimelineItemBinding::SetVisible(bool inVisible)
+{
+ SetBoolean(m_StudioSystem->GetClientDataModelBridge()->GetSceneAsset().m_Eyeball,
+ inVisible, QObject::tr("Visibility Toggle"));
+}
+
+bool Qt3DSDMTimelineItemBinding::HasAction(bool inMaster)
+{
+ TActionHandleList theActions;
+ CDoc *theDoc = g_StudioApp.GetCore()->GetDoc();
+
+ Qt3DSDMSlideHandle theSlide = theDoc->GetActiveSlide();
+ qt3dsdm::ISlideCore &theSlideCore(*m_StudioSystem->GetSlideCore());
+ if (theSlideCore.IsSlide(theSlide)) {
+ if (inMaster) {
+ theSlide =
+ m_StudioSystem->GetSlideSystem()->GetMasterSlide(theSlide); // use the master slide
+ }
+
+ m_StudioSystem->GetActionCore()->GetActions(theSlide, m_DataHandle, theActions);
+ }
+ return theActions.size() > 0;
+}
+
+bool Qt3DSDMTimelineItemBinding::ChildrenHasAction(bool inMaster)
+{
+ // Get all the instances in this slidegraph
+ // check whehter it's an action instance and is in the slide of interst
+ // check also it's owner is a descendent of the viewed instances
+ CDoc *theDoc = g_StudioApp.GetCore()->GetDoc();
+ IActionCore *theActionCore(m_StudioSystem->GetActionCore());
+ CClientDataModelBridge *theBridge(m_StudioSystem->GetClientDataModelBridge());
+
+ Qt3DSDMSlideHandle theSlide = theDoc->GetActiveSlide();
+ qt3dsdm::ISlideCore &theSlideCore(*m_StudioSystem->GetSlideCore());
+ if (theSlideCore.IsSlide(theSlide)) {
+ if (inMaster) {
+ theSlide =
+ m_StudioSystem->GetSlideSystem()->GetMasterSlide(theSlide); // use the master slide
+ }
+
+ TSlideInstancePairList theGraphInstances;
+ m_StudioSystem->GetSlideSystem()->GetAssociatedInstances(theSlide, theGraphInstances);
+
+ qt3dsdm::Qt3DSDMInstanceHandle theObservedInstance = GetInstance();
+ if (theObservedInstance.Valid()) {
+ for (TSlideInstancePairList::const_iterator theIter = theGraphInstances.begin();
+ theIter != theGraphInstances.end(); ++theIter) {
+ if (theIter->first == theSlide && theBridge->IsActionInstance(theIter->second)) {
+ Qt3DSDMActionHandle theAction =
+ theActionCore->GetActionByInstance(theIter->second);
+ SActionInfo theActionInfo = theActionCore->GetActionInfo(theAction);
+ Qt3DSDMInstanceHandle theAcionOwner = theActionInfo.m_Owner;
+ if (theAcionOwner.Valid()
+ && IsAscendant(theAcionOwner, theObservedInstance, theDoc->GetAssetGraph()))
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+bool Qt3DSDMTimelineItemBinding::ComponentHasAction(bool inMaster)
+{
+ // Get all the instances in this component slidegraph
+ // check whether the instance is an action instance
+ // if inMaster is true, we only interest with those that are in the master slide, else we want
+ // those that are not in the master slide
+ CClientDataModelBridge *theBridge(m_StudioSystem->GetClientDataModelBridge());
+ if (!theBridge->IsComponentInstance(m_DataHandle))
+ return false;
+
+ Q3DStudio::CId theAssetId = theBridge->GetGUID(m_DataHandle);
+ Qt3DSDMSlideHandle theMasterSlide =
+ m_StudioSystem->GetSlideSystem()->GetMasterSlideByComponentGuid(GuidtoSLong4(theAssetId));
+
+ TSlideInstancePairList theGraphInstances;
+ m_StudioSystem->GetSlideSystem()->GetAssociatedInstances(theMasterSlide, theGraphInstances);
+
+ for (TSlideInstancePairList::const_iterator theIter = theGraphInstances.begin();
+ theIter != theGraphInstances.end(); ++theIter) {
+ if (((inMaster && theIter->first == theMasterSlide)
+ || (!inMaster && theIter->first != theMasterSlide))
+ && theBridge->IsActionInstance(theIter->second)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool Qt3DSDMTimelineItemBinding::hasSubpresentation() const
+{
+ CClientDataModelBridge *bridge(m_StudioSystem->GetClientDataModelBridge());
+ IPropertySystem *propSystem = m_StudioSystem->GetPropertySystem();
+ EStudioObjectType objType = GetObjectType();
+
+ if (objType == OBJTYPE_LAYER) {
+ SValue sourcePathValue;
+ propSystem->GetInstancePropertyValue(m_DataHandle, bridge->GetSourcePathProperty(),
+ sourcePathValue);
+ return get<TDataStrPtr>(sourcePathValue)->GetLength() > 0;
+ } else if (objType == OBJTYPE_IMAGE) {
+ SValue subPresValue;
+ propSystem->GetInstancePropertyValue(m_DataHandle,
+ bridge->GetSceneImage().m_SubPresentation,
+ subPresValue);
+ return get<TDataStrPtr>(subPresValue)->GetLength() > 0;
+ }
+
+ return false;
+}
+
+ITimelineTimebar *Qt3DSDMTimelineItemBinding::GetTimebar()
+{
+ if (!m_TimelineTimebar)
+ m_TimelineTimebar = CreateTimelineTimebar();
+ return m_TimelineTimebar;
+}
+
+Q3DStudio::CString Qt3DSDMTimelineItemBinding::GetName() const
+{
+ if (m_StudioSystem->IsInstance(m_DataHandle) == false)
+ return L"";
+ Qt3DSDMPropertyHandle theNamePropHandle =
+ m_StudioSystem->GetPropertySystem()->GetAggregateInstancePropertyByName(m_DataHandle,
+ L"name");
+ SValue theNameValue;
+ m_StudioSystem->GetPropertySystem()->GetInstancePropertyValue(m_DataHandle, theNamePropHandle,
+ theNameValue);
+ TDataStrPtr theName = qt3dsdm::get<TDataStrPtr>(theNameValue);
+
+ return (theName) ? Q3DStudio::CString(theName->GetData()) : "";
+}
+
+void Qt3DSDMTimelineItemBinding::SetName(const Q3DStudio::CString &inName)
+{
+ // Ignore if setting the name to what it currently is to avoid duplicate undo points
+ if (inName == GetName())
+ return;
+
+ // Display warning dialog if user tried to enter an empty string
+ if (inName.IsEmpty()) {
+ QString theTitle = QObject::tr("Rename Object Error");
+ QString theString = QObject::tr("Object name cannot be an empty string.");
+ g_StudioApp.GetDialogs()->DisplayMessageBox(theTitle, theString,
+ Qt3DSMessageBox::ICON_ERROR, false);
+
+ return;
+ }
+
+ CClientDataModelBridge *theBridge = m_StudioSystem->GetClientDataModelBridge();
+ const auto doc = g_StudioApp.GetCore()->GetDoc();
+
+ // Display warning if the name and path are the same as the material container
+ if (theBridge->GetParentInstance(m_DataHandle) == doc->GetSceneInstance()
+ && inName.toQString() == theBridge->getMaterialContainerName()) {
+ QString theTitle = QObject::tr("Rename Object Error");
+ QString theString = theBridge->getMaterialContainerName()
+ + QObject::tr(" is a reserved name.");
+ g_StudioApp.GetDialogs()->DisplayMessageBox(theTitle, theString,
+ Qt3DSMessageBox::ICON_ERROR, false);
+ // The timeline still shows the new name so refresh the name property
+ m_StudioSystem->GetFullSystemSignalSender()->SendInstancePropertyValue(
+ m_DataHandle, theBridge->GetNameProperty());
+ return;
+ }
+
+ // Display warning if we had to modify the user-given name to make it unique
+ if (!theBridge->CheckNameUnique(theBridge->GetParentInstance(m_DataHandle),
+ m_DataHandle, inName)) {
+ // Find unique name based on the input string
+ Q3DStudio::SCOPED_DOCUMENT_EDITOR(
+ *m_TransMgr->GetDoc(), QObject::tr("Set Name"))->SetName(m_DataHandle, inName, true);
+
+ g_StudioApp.GetDialogs()->DisplayObjectRenamed(
+ inName.toQString(), theBridge->GetName(m_DataHandle).toQString());
+ return;
+ }
+
+ Q3DStudio::SCOPED_DOCUMENT_EDITOR(
+ *m_TransMgr->GetDoc(), QObject::tr("Set Name"))->SetName(m_DataHandle, inName, true);
+}
+
+ITimelineItem *Qt3DSDMTimelineItemBinding::GetTimelineItem()
+{
+ return this;
+}
+
+RowTree *Qt3DSDMTimelineItemBinding::getRowTree() const
+{
+ return m_rowTree;
+}
+
+void Qt3DSDMTimelineItemBinding::setRowTree(RowTree *row)
+{
+ m_rowTree = row;
+}
+
+void Qt3DSDMTimelineItemBinding::SetSelected(bool inMultiSelect)
+{
+ if (!inMultiSelect)
+ g_StudioApp.GetCore()->GetDoc()->SelectDataModelObject(m_DataHandle);
+ else
+ g_StudioApp.GetCore()->GetDoc()->ToggleDataModelObjectToSelection(m_DataHandle);
+}
+
+void Qt3DSDMTimelineItemBinding::OnCollapsed()
+{
+ // Preserves legacy behavior where collapsing a tree will select that root, if any of its
+ // descendant was selected
+ // TODO: This won't work for Image (because Image is Material's property, not child)
+ qt3dsdm::Qt3DSDMInstanceHandle theInstance = GetInstance();
+ if (theInstance.Valid()) {
+ CDoc *theDoc = m_TransMgr->GetDoc();
+ qt3dsdm::Qt3DSDMInstanceHandle theSelectedInstance = theDoc->GetSelectedInstance();
+ if (theSelectedInstance.Valid()
+ && IsAscendant(theSelectedInstance, theInstance, theDoc->GetAssetGraph()))
+ SetSelected(false);
+ }
+}
+
+bool Qt3DSDMTimelineItemBinding::OpenAssociatedEditor()
+{
+ return false; // nothing to do by default
+}
+
+inline qt3dsdm::Qt3DSDMInstanceHandle Qt3DSDMTimelineItemBinding::GetInstance() const
+{
+ return m_DataHandle;
+}
+
+void Qt3DSDMTimelineItemBinding::SetDropTarget(CDropTarget *inTarget)
+{
+ qt3dsdm::Qt3DSDMInstanceHandle theInstance = GetInstance();
+ inTarget->SetInstance(theInstance);
+}
+
+long Qt3DSDMTimelineItemBinding::GetChildrenCount()
+{
+ qt3dsdm::Qt3DSDMInstanceHandle theInstance = GetInstance();
+ if (theInstance.Valid()) {
+ Q3DStudio::CGraphIterator theChildren;
+ Qt3DSDMSlideHandle theActiveSlide = m_TransMgr->GetDoc()->GetActiveSlide();
+ GetAssetChildrenInTimeParent(theInstance, m_TransMgr->GetDoc(), AmITimeParent(),
+ theChildren, theActiveSlide);
+ return (long)theChildren.GetCount();
+ }
+ return 0;
+}
+
+ITimelineItemBinding *Qt3DSDMTimelineItemBinding::GetChild(long inIndex)
+{
+ qt3dsdm::Qt3DSDMInstanceHandle theInstance = GetInstance();
+ if (theInstance.Valid()) {
+ Q3DStudio::CGraphIterator theChildren;
+ Qt3DSDMSlideHandle theActiveSlide = m_TransMgr->GetDoc()->GetActiveSlide();
+ GetAssetChildrenInTimeParent(theInstance, m_TransMgr->GetDoc(), AmITimeParent(),
+ theChildren, theActiveSlide);
+ theChildren += inIndex;
+
+ qt3dsdm::Qt3DSDMInstanceHandle theChildInstance = theChildren.GetCurrent();
+ if (theChildInstance.Valid())
+ return m_TransMgr->GetOrCreate(theChildInstance);
+ }
+ return nullptr;
+}
+
+QList<ITimelineItemBinding *> Qt3DSDMTimelineItemBinding::GetChildren()
+{
+ QList<ITimelineItemBinding *> retlist;
+ qt3dsdm::Qt3DSDMInstanceHandle theInstance = GetInstance();
+ if (theInstance.Valid()) {
+ Q3DStudio::CGraphIterator theChildren;
+ Qt3DSDMSlideHandle theActiveSlide = m_TransMgr->GetDoc()->GetActiveSlide();
+ GetAssetChildrenInTimeParent(theInstance, m_TransMgr->GetDoc(), AmITimeParent(),
+ theChildren, theActiveSlide);
+ int childCount = int(theChildren.GetCount());
+ retlist.reserve(childCount);
+
+ for (int i = 0; i < childCount; ++i) {
+ qt3dsdm::Qt3DSDMInstanceHandle theChildInstance = theChildren.GetCurrent();
+ if (theChildInstance.Valid())
+ retlist.append(m_TransMgr->GetOrCreate(theChildInstance));
+ ++theChildren;
+ }
+ }
+
+ return retlist;
+}
+
+ITimelineItemBinding *Qt3DSDMTimelineItemBinding::GetParent()
+{
+ return m_Parent;
+}
+void Qt3DSDMTimelineItemBinding::SetParent(ITimelineItemBinding *parent)
+{
+ if (parent != m_Parent) {
+ ASSERT(parent == nullptr || m_Parent == nullptr);
+ m_Parent = parent;
+ }
+}
+
+long Qt3DSDMTimelineItemBinding::GetPropertyCount()
+{
+ long theCount = 0;
+ if (m_StudioSystem->IsInstance(m_DataHandle)) {
+ TPropertyHandleList theProperties;
+ m_StudioSystem->GetPropertySystem()->GetAggregateInstanceProperties(m_DataHandle,
+ theProperties);
+ for (size_t thePropertyIndex = 0; thePropertyIndex < theProperties.size();
+ ++thePropertyIndex) {
+ if (m_StudioSystem->GetAnimationSystem()->IsPropertyAnimated(
+ m_DataHandle, theProperties[thePropertyIndex])) {
+ ++theCount;
+ }
+ }
+ }
+ return theCount;
+}
+
+ITimelineItemProperty *Qt3DSDMTimelineItemBinding::GetProperty(long inIndex)
+{
+ TPropertyHandleList theProperties;
+ m_StudioSystem->GetPropertySystem()->GetAggregateInstanceProperties(m_DataHandle,
+ theProperties);
+ long theIndex = -1;
+ size_t thePropertyIndex = 0;
+ for (; thePropertyIndex < theProperties.size(); ++thePropertyIndex) {
+ if (m_StudioSystem->GetAnimationSystem()->IsPropertyAnimated(
+ m_DataHandle, theProperties[thePropertyIndex])) {
+ ++theIndex;
+ if (theIndex == inIndex)
+ break;
+ }
+ }
+ ASSERT(thePropertyIndex < theProperties.size()); // no reason why this would be out of range!!
+ return GetOrCreatePropertyBinding(theProperties[thePropertyIndex]);
+}
+
+bool Qt3DSDMTimelineItemBinding::ShowToggleControls() const
+{
+ return true;
+}
+
+bool Qt3DSDMTimelineItemBinding::IsLockedEnabled() const
+{
+ return IsLocked();
+}
+
+bool Qt3DSDMTimelineItemBinding::IsVisibleEnabled() const
+{
+ // You can only toggle visible if you aren't on the master slide.
+ return m_StudioSystem->GetSlideSystem()->GetSlideIndex(m_TransMgr->GetDoc()->GetActiveSlide())
+ != 0;
+}
+
+bool Qt3DSDMTimelineItemBinding::IsValidTransaction(EUserTransaction inTransaction)
+{
+ qt3dsdm::Qt3DSDMInstanceHandle theInstance = GetInstance();
+ const auto bridge = m_StudioSystem->GetClientDataModelBridge();
+ switch (inTransaction) {
+ case EUserTransaction_Rename:
+ return (GetObjectType() != OBJTYPE_SCENE && GetObjectType() != OBJTYPE_IMAGE
+ && (bridge->GetObjectType(theInstance) != OBJTYPE_REFERENCEDMATERIAL
+ || bridge->GetSourcePath(theInstance).isEmpty()));
+
+ case EUserTransaction_Duplicate:
+ if (theInstance.Valid())
+ return m_StudioSystem->GetClientDataModelBridge()->IsDuplicateable(theInstance);
+ break;
+
+ case EUserTransaction_Cut:
+ return g_StudioApp.CanCut();
+
+ case EUserTransaction_Copy:
+ return g_StudioApp.CanCopy();
+
+ case EUserTransaction_Paste:
+ return m_TransMgr->GetDoc()->canPasteObjects();
+
+ case EUserTransaction_Delete:
+ if (theInstance.Valid())
+ return m_StudioSystem->GetClientDataModelBridge()->CanDelete(theInstance);
+ break;
+
+ case EUserTransaction_MakeComponent: {
+ bool theCanMakeFlag = false;
+ if (theInstance.Valid()) {
+ CClientDataModelBridge *theBridge = m_StudioSystem->GetClientDataModelBridge();
+ EStudioObjectType theObjectType = theBridge->GetObjectType(theInstance);
+
+ if (!IsLocked()) {
+ // Any assets that are attached to the Scene directly must not be wrapped in a
+ // component.
+ // This may include behavior assets which may be directly attached to the Scene.
+ // This is because by principal, components cannot exist on the Scene directly.
+ qt3dsdm::Qt3DSDMInstanceHandle theParentInstance =
+ theBridge->GetParentInstance(theInstance);
+ if (theObjectType != OBJTYPE_LAYER && theObjectType != OBJTYPE_SCENE
+ && theObjectType != OBJTYPE_MATERIAL && theObjectType != OBJTYPE_IMAGE
+ && theObjectType != OBJTYPE_EFFECT && theObjectType != OBJTYPE_COMPONENT
+ && (theParentInstance.Valid()
+ && theBridge->GetObjectType(theParentInstance)
+ != OBJTYPE_SCENE)) // This checks if the object is
+ // AttachedToSceneDirectly
+ {
+ theCanMakeFlag = true;
+ }
+ }
+ }
+ return theCanMakeFlag;
+ }
+
+ case EUserTransaction_EditComponent:
+ return (GetObjectType() == OBJTYPE_COMPONENT);
+
+ case EUserTransaction_MakeAnimatable:
+ if (theInstance.Valid()) {
+ CClientDataModelBridge *bridge = m_StudioSystem->GetClientDataModelBridge();
+ EStudioObjectType type = bridge->GetObjectType(theInstance);
+ return !IsLocked() && type == OBJTYPE_REFERENCEDMATERIAL;
+ }
+ return false;
+
+ case EUserTransaction_Group:
+ return g_StudioApp.canGroupSelectedObjects();
+
+ case EUserTransaction_Ungroup:
+ return g_StudioApp.canUngroupSelectedObjects();
+
+ case EUserTransaction_AddLayer:
+ return (GetObjectType() == OBJTYPE_SCENE);
+
+ default: // not handled
+ break;
+ }
+
+ return false;
+}
+
+using namespace Q3DStudio;
+
+inline void DoCut(CDoc &inDoc, const qt3dsdm::TInstanceHandleList &inInstances)
+{
+ inDoc.DeselectAllKeyframes();
+ inDoc.CutObject(inInstances);
+}
+
+inline void DoDelete(CDoc &inDoc, const qt3dsdm::TInstanceHandleList &inInstances)
+{
+ inDoc.DeselectAllKeyframes();
+ inDoc.DeleteObject(inInstances);
+}
+
+inline void DoMakeComponent(CDoc &inDoc, const qt3dsdm::TInstanceHandleList &inInstances)
+{
+ SCOPED_DOCUMENT_EDITOR(inDoc, QObject::tr("Make Component"))->MakeComponent(inInstances);
+}
+
+inline void doMakeAnimatable(CDoc &doc, const qt3dsdm::TInstanceHandleList &instances)
+{
+ SCOPED_DOCUMENT_EDITOR(doc, QObject::tr("Make Animatable"))->makeAnimatable(instances);
+}
+
+inline void DoGroupObjects(CDoc &inDoc, const qt3dsdm::TInstanceHandleList &inInstances)
+{
+ g_StudioApp.groupSelectedObjects();
+}
+
+inline void DoUngroupObjects(CDoc &inDoc, const qt3dsdm::TInstanceHandleList &inInstances)
+{
+ g_StudioApp.ungroupSelectedObjects();
+}
+
+inline void doAddLayer(CDoc &inDoc, const qt3dsdm::TInstanceHandleList &inInstances)
+{
+ qt3dsdm::Qt3DSDMSlideHandle slide = inDoc.GetActiveSlide();
+ qt3dsdm::Qt3DSDMInstanceHandle parent = inDoc.GetActiveLayer();
+
+ SCOPED_DOCUMENT_EDITOR(inDoc, QObject::tr("Add Layer"))
+ ->CreateSceneGraphInstance(qt3dsdm::ComposerObjectTypes::Layer, parent, slide,
+ DocumentEditorInsertType::PreviousSibling,
+ CPt(), PRIMITIVETYPE_UNKNOWN, -1);
+}
+
+void Qt3DSDMTimelineItemBinding::PerformTransaction(EUserTransaction inTransaction)
+{
+ CDoc *theDoc = m_TransMgr->GetDoc();
+ qt3dsdm::TInstanceHandleList theInstances = theDoc->GetSelectedValue().GetSelectedInstances();
+ if (theInstances.empty())
+ return;
+ CDispatch &theDispatch(*theDoc->GetCore()->GetDispatch());
+
+ // Transactions that could result in *this* object being deleted need to be executed
+ // via postmessage, not in this context because it could result in the currently
+ // active timeline row being deleted while in its own mouse handler.
+ switch (inTransaction) {
+ case EUserTransaction_Duplicate: {
+ theDoc->DeselectAllKeyframes();
+ SCOPED_DOCUMENT_EDITOR(*theDoc,
+ QObject::tr("Duplicate Object"))->DuplicateInstances(theInstances);
+ } break;
+ case EUserTransaction_Cut: {
+ theDispatch.FireOnAsynchronousCommand(
+ std::bind(DoCut, std::ref(*theDoc), theInstances));
+ } break;
+ case EUserTransaction_Copy: {
+ theDoc->DeselectAllKeyframes();
+ theDoc->CopyObject(theInstances);
+ } break;
+ case EUserTransaction_Paste: {
+ theDoc->DeselectAllKeyframes();
+ theDoc->PasteObject(theDoc->getPasteTarget(GetInstance()));
+ } break;
+ case EUserTransaction_Delete: {
+ theDispatch.FireOnAsynchronousCommand(
+ std::bind(DoDelete, std::ref(*theDoc), theInstances));
+ } break;
+ case EUserTransaction_MakeComponent: {
+ theDispatch.FireOnAsynchronousCommand(
+ std::bind(DoMakeComponent, std::ref(*theDoc), theInstances));
+ } break;
+ case EUserTransaction_MakeAnimatable: {
+ theDispatch.FireOnAsynchronousCommand(
+ std::bind(doMakeAnimatable, std::ref(*theDoc), theInstances));
+ } break;
+ case EUserTransaction_Group: {
+ theDispatch.FireOnAsynchronousCommand(
+ std::bind(DoGroupObjects, std::ref(*theDoc), theInstances));
+ } break;
+ case EUserTransaction_Ungroup: {
+ theDispatch.FireOnAsynchronousCommand(
+ std::bind(DoUngroupObjects, std::ref(*theDoc), theInstances));
+ } break;
+ case EUserTransaction_AddLayer: {
+ theDispatch.FireOnAsynchronousCommand(
+ std::bind(doAddLayer, std::ref(*theDoc), theInstances));
+ } break;
+ default: // not handled
+ break;
+ }
+}
+
+Q3DStudio::CString Qt3DSDMTimelineItemBinding::GetObjectPath()
+{
+ CDoc *theDoc = m_TransMgr->GetDoc();
+ // Because we are getting absolute path, the base id doesn't matter.
+ return CRelativePathTools::BuildAbsoluteReferenceString(m_DataHandle, theDoc);
+}
+
+int Qt3DSDMTimelineItemBinding::getAnimatedPropertyIndex(int propertyHandle) const
+{
+ TPropertyHandleList theProperties;
+ m_StudioSystem->GetPropertySystem()->GetAggregateInstanceProperties(m_DataHandle,
+ theProperties);
+ int index = -1;
+ for (size_t i = 0; i < theProperties.size(); ++i) {
+ if (m_StudioSystem->GetAnimationSystem()->IsPropertyAnimated(
+ m_DataHandle, theProperties[i])) {
+ index++;
+ }
+ if (theProperties[i].GetHandleValue() == propertyHandle)
+ return index;
+ }
+
+ return -1;
+}
+
+void Qt3DSDMTimelineItemBinding::getTimeContextIndices(const QSet<int> &children,
+ QMap<int, int> &indexMap)
+{
+ qt3dsdm::Qt3DSDMInstanceHandle instance = GetInstance();
+ if (instance.Valid()) {
+ Q3DStudio::CGraphIterator graphChildren;
+ Qt3DSDMSlideHandle activeSlide = m_TransMgr->GetDoc()->GetActiveSlide();
+ GetAssetChildrenInTimeParent(instance, m_TransMgr->GetDoc(), AmITimeParent(),
+ graphChildren, activeSlide);
+ const size_t count = graphChildren.GetCount();
+ for (size_t current = 0; current < count; ++current) {
+ auto handle = graphChildren.GetResult(current);
+ if (children.contains(handle))
+ indexMap.insert(int(current), int(handle));
+ }
+ }
+}
+
+void Qt3DSDMTimelineItemBinding::InsertKeyframe()
+{
+ if (m_PropertyBindingMap.empty())
+ return;
+
+ TPropertyBindingMap::const_iterator theIter = m_PropertyBindingMap.begin();
+ ScopedDocumentEditor editor(*g_StudioApp.GetCore()->GetDoc(), QObject::tr("Insert Keyframe"),
+ __FILE__, __LINE__);
+ for (; theIter != m_PropertyBindingMap.end(); ++theIter)
+ editor->KeyframeProperty(m_DataHandle, theIter->first, false);
+}
+
+void Qt3DSDMTimelineItemBinding::DeleteAllChannelKeyframes()
+{
+ if (m_PropertyBindingMap.empty())
+ return;
+
+ CDoc *theDoc = m_TransMgr->GetDoc();
+ Q3DStudio::ScopedDocumentEditor editor(*theDoc, QObject::tr("Delete Channel Keyframes"),
+ __FILE__, __LINE__);
+ for (auto &kv : m_PropertyBindingMap)
+ kv.second->DeleteAllKeys();
+}
+
+IKeyframe *Qt3DSDMTimelineItemBinding::GetKeyframeByTime(long inTime) const
+{
+ TAssetKeyframeList::const_iterator theIter = m_Keyframes.begin();
+ for (; theIter != m_Keyframes.end(); ++theIter) {
+ if ((*theIter).GetTime() == inTime)
+ return const_cast<Qt3DSDMAssetTimelineKeyframe *>(&(*theIter));
+ }
+ return nullptr;
+}
+
+Qt3DSDMInstanceHandle Qt3DSDMTimelineItemBinding::GetInstanceHandle() const
+{
+ return m_DataHandle;
+}
+
+long Qt3DSDMTimelineItemBinding::GetFlavor() const
+{
+ return QT3DS_FLAVOR_ASSET_TL;
+}
+
+ITimelineTimebar *Qt3DSDMTimelineItemBinding::CreateTimelineTimebar()
+{
+ return new Qt3DSDMTimelineTimebar(m_TransMgr, m_DataHandle);
+}
+
+ITimelineItemProperty *
+Qt3DSDMTimelineItemBinding::GetPropertyBinding(Qt3DSDMPropertyHandle inPropertyHandle)
+{
+ TPropertyBindingMap::iterator theIter = m_PropertyBindingMap.find(inPropertyHandle);
+ // check if it already exists
+ if (theIter != m_PropertyBindingMap.end())
+ return theIter->second;
+ return nullptr;
+}
+
+bool Qt3DSDMTimelineItemBinding::isRootComponent() const
+{
+ auto bridge = g_StudioApp.GetCore()->GetDoc()->GetStudioSystem()->GetClientDataModelBridge();
+ return bridge->IsActiveComponent(m_DataHandle);
+}
+
+bool Qt3DSDMTimelineItemBinding::isDefaultMaterial() const
+{
+ auto bridge = g_StudioApp.GetCore()->GetDoc()->GetStudioSystem()->GetClientDataModelBridge();
+ return bridge->isDefaultMaterial(m_DataHandle);
+}
+
+ITimelineItemProperty *
+Qt3DSDMTimelineItemBinding::GetOrCreatePropertyBinding(Qt3DSDMPropertyHandle inPropertyHandle)
+{
+ ITimelineItemProperty *theProperty = GetPropertyBinding(inPropertyHandle);
+ // check if it already exists
+ if (theProperty)
+ return theProperty;
+
+ // Create
+ Qt3DSDMTimelineItemProperty *theTimelineProperty =
+ new Qt3DSDMTimelineItemProperty(m_TransMgr, inPropertyHandle, m_DataHandle);
+ m_PropertyBindingMap.insert(std::make_pair(inPropertyHandle, theTimelineProperty));
+
+ return theTimelineProperty;
+}
+
+//=============================================================================
+/**
+ * Add a new property row for this property.
+ * @param inAppend true to skip the check to find where to insert. ( true if this is a
+ * loading/initializing step, where the call is already done in order )
+ */
+void Qt3DSDMTimelineItemBinding::AddPropertyRow(Qt3DSDMPropertyHandle inPropertyHandle,
+ bool inAppend /*= false */)
+{
+ ITimelineItemProperty *theTimelineProperty = GetPropertyBinding(inPropertyHandle);
+ if (theTimelineProperty) // if created, bail
+ return;
+
+ if (!theTimelineProperty)
+ theTimelineProperty = GetOrCreatePropertyBinding(inPropertyHandle);
+
+ // Find the row to insert this new property, if any, this preserves the order the property rows
+ // is displayed in the timeline.
+ ITimelineItemProperty *theNextProperty = nullptr;
+ if (!inAppend) {
+ TPropertyHandleList theProperties;
+ m_StudioSystem->GetPropertySystem()->GetAggregateInstanceProperties(m_DataHandle,
+ theProperties);
+ size_t thePropertyIndex = 0;
+ size_t thePropertyCount = theProperties.size();
+ for (; thePropertyIndex < thePropertyCount; ++thePropertyIndex) {
+ if (theProperties[thePropertyIndex] == inPropertyHandle) {
+ ++thePropertyIndex;
+ break;
+ }
+ }
+ // Not all properties are displayed, so another loop to search for the first one that maps
+ // to a existing propertyrow
+ for (; thePropertyIndex < thePropertyCount; ++thePropertyIndex) {
+ TPropertyBindingMap::iterator theNextPropIter =
+ m_PropertyBindingMap.find(theProperties[thePropertyIndex]);
+ if (theNextPropIter != m_PropertyBindingMap.end()) {
+ theNextProperty = theNextPropIter->second;
+ break;
+ }
+ }
+ }
+
+ // Update keyframes
+ AddKeyframes(theTimelineProperty);
+}
+
+void Qt3DSDMTimelineItemBinding::RemovePropertyRow(Qt3DSDMPropertyHandle inPropertyHandle)
+{
+ TPropertyBindingMap::iterator theIter = m_PropertyBindingMap.find(inPropertyHandle);
+ if (theIter != m_PropertyBindingMap.end()) {
+ ITimelineItemProperty *thePropertyBinding = theIter->second;
+
+ DeleteAssetKeyframesWhereApplicable(thePropertyBinding);
+ m_PropertyBindingMap.erase(theIter);
+ }
+}
+
+// called when a keyframe is inserted, deleted or updated in the data model
+void Qt3DSDMTimelineItemBinding::RefreshPropertyKeyframe(
+ qt3dsdm::Qt3DSDMPropertyHandle inPropertyHandle, qt3dsdm::Qt3DSDMKeyframeHandle inKeyframe,
+ ETimelineKeyframeTransaction inTransaction)
+{
+ TPropertyBindingMap::iterator theIter = m_PropertyBindingMap.find(inPropertyHandle);
+ if (theIter != m_PropertyBindingMap.end()) {
+ Qt3DSDMTimelineItemProperty *theProperty = theIter->second;
+ if (theProperty) {
+ if (theProperty->RefreshKeyframe(inKeyframe, inTransaction)) {
+ // Update asset keyframes
+ UpdateKeyframe(theProperty->GetKeyframeByHandle(inKeyframe), inTransaction);
+ }
+ }
+ }
+}
+
+void Qt3DSDMTimelineItemBinding::OnPropertyChanged(Qt3DSDMPropertyHandle inPropertyHandle)
+{
+}
+
+void Qt3DSDMTimelineItemBinding::OnPropertyLinked(Qt3DSDMPropertyHandle inPropertyHandle)
+{
+ if (m_StudioSystem->GetAnimationSystem()->IsPropertyAnimated(m_DataHandle, inPropertyHandle)) {
+ // Refresh property row by delete and recreate
+ RemovePropertyRow(inPropertyHandle);
+ AddPropertyRow(inPropertyHandle);
+ }
+}
+
+bool Qt3DSDMTimelineItemBinding::HasDynamicKeyframes(long inTime)
+{
+ if (inTime == -1) {
+ if (GetPropertyCount() == 0)
+ return false;
+
+ for (long i = 0; i < GetPropertyCount(); ++i) {
+ ITimelineItemProperty *theTimelineItemProperty = GetProperty(i);
+ if (!theTimelineItemProperty->IsDynamicAnimation())
+ return false;
+ }
+ return true;
+ } else {
+ TPropertyBindingMap::const_iterator theIter = m_PropertyBindingMap.begin();
+ for (; theIter != m_PropertyBindingMap.end(); ++theIter) {
+ IKeyframe *theKeyframe = theIter->second->GetKeyframeByTime(inTime);
+ if (theKeyframe && theKeyframe->IsDynamic())
+ return true;
+ }
+ }
+ return false;
+}
+
+void Qt3DSDMTimelineItemBinding::SetDynamicKeyframes(long inTime, bool inDynamic)
+{
+ TPropertyBindingMap::const_iterator theIter = m_PropertyBindingMap.begin();
+ for (; theIter != m_PropertyBindingMap.end(); ++theIter) {
+ IKeyframe *theKeyframe = theIter->second->GetKeyframeByTime(inTime);
+ if (theKeyframe)
+ theKeyframe->SetDynamic(inDynamic); // TODO: we want this in 1 batch command
+ }
+}
+
+Q3DStudio::CId Qt3DSDMTimelineItemBinding::GetGuid() const
+{
+ CClientDataModelBridge *theClientBridge = m_StudioSystem->GetClientDataModelBridge();
+ qt3dsdm::IPropertySystem *thePropertySystem = m_StudioSystem->GetPropertySystem();
+ SValue theValue;
+ if (thePropertySystem->GetInstancePropertyValue(m_DataHandle, theClientBridge->GetIdProperty(),
+ theValue)) {
+ SLong4 theLong4 = qt3dsdm::get<SLong4>(theValue);
+ return Q3DStudio::CId(theLong4.m_Longs[0], theLong4.m_Longs[1], theLong4.m_Longs[2],
+ theLong4.m_Longs[3]);
+ }
+ return Q3DStudio::CId();
+}
+
+// Delete asset keyframes at time t if no property keyframes exist at time t
+//@param inSkipPropertyBinding property that to skip, e.g. in cases where property is deleted
+//@return true if there are asset keyframes deleted.
+bool Qt3DSDMTimelineItemBinding::DeleteAssetKeyframesWhereApplicable(
+ ITimelineItemProperty *inSkipPropertyBinding /*= nullptr */)
+{
+ // iterate through m_Keyframes because we cannot obtain time information from the Animation
+ // keyframes anymore, since they are deleted.
+ std::vector<long> theDeleteIndicesList;
+ for (size_t theIndex = 0; theIndex < m_Keyframes.size(); ++theIndex) {
+ TPropertyBindingMap::iterator theIter = m_PropertyBindingMap.begin();
+ for (; theIter != m_PropertyBindingMap.end(); ++theIter) {
+ if ((!inSkipPropertyBinding || theIter->second != inSkipPropertyBinding)
+ && theIter->second->GetKeyframeByTime(m_Keyframes[theIndex].GetTime())) {
+ // done!
+ break;
+ }
+ }
+ if (theIter == m_PropertyBindingMap.end())
+ theDeleteIndicesList.push_back((long)theIndex);
+ }
+ // start with the last item, so that the indices remain valid.
+ for (long i = (long)theDeleteIndicesList.size() - 1; i >= 0; --i) {
+ TAssetKeyframeList::iterator theKeyIter = m_Keyframes.begin();
+ std::advance(theKeyIter, theDeleteIndicesList[i]);
+ m_Keyframes.erase(theKeyIter);
+ }
+
+ return !theDeleteIndicesList.empty();
+}
+
+void Qt3DSDMTimelineItemBinding::RemoveAllPropertyBindings()
+{
+ TPropertyBindingMap::iterator theIter = m_PropertyBindingMap.begin();
+ for (; theIter != m_PropertyBindingMap.end(); ++theIter)
+ delete theIter->second;
+ m_PropertyBindingMap.clear();
+}
+
+void Qt3DSDMTimelineItemBinding::AddKeyframes(ITimelineItemProperty *inPropertyBinding)
+{
+ for (long i = 0; i < inPropertyBinding->GetKeyframeCount(); ++i)
+ UpdateKeyframe(inPropertyBinding->GetKeyframeByIndex(i), ETimelineKeyframeTransaction_Add);
+}
+
+// Update the asset keyframes based on the properties' keyframes.
+void Qt3DSDMTimelineItemBinding::UpdateKeyframe(IKeyframe *inKeyframe,
+ ETimelineKeyframeTransaction inTransaction)
+{
+ bool theDoAddFlag = (inTransaction == ETimelineKeyframeTransaction_Add);
+ bool theDoDeleteFlag = (inTransaction == ETimelineKeyframeTransaction_Delete);
+
+ // For update, if there isn't already a asset keyframe at the associated time, create one
+ if (inTransaction == ETimelineKeyframeTransaction_Update) {
+ theDoAddFlag = inKeyframe && !GetKeyframeByTime(inKeyframe->GetTime());
+ theDoDeleteFlag = true; // plus, since we don't keep track of indiviual property keyframes
+ // here, iterate and make sure list is correct.
+ }
+
+ if (theDoDeleteFlag)
+ DeleteAssetKeyframesWhereApplicable();
+
+ // Add when a new keyframe is added or MAYBE when a keyframe is moved
+ if (theDoAddFlag && inKeyframe) {
+ long theKeyframeTime = inKeyframe->GetTime();
+ if (theKeyframeTime >= 0) {
+ bool theAppend = true;
+ // insert this in the order that it should be. and we trust the
+ TAssetKeyframeList::iterator theIter = m_Keyframes.begin();
+ for (; theIter != m_Keyframes.end(); ++theIter) {
+ long theTime = (*theIter).GetTime();
+ if (theTime == theKeyframeTime) {
+ theAppend = false;
+ break; // already exists, we are done. Because we only need 1 to represent ALL
+ // properties
+ }
+ }
+ if (theAppend)
+ m_Keyframes.push_back(Qt3DSDMAssetTimelineKeyframe(this, theKeyframeTime));
+ }
+ }
+}
+
+void Qt3DSDMTimelineItemBinding::OnAddChild(Qt3DSDMInstanceHandle inInstance)
+{
+ CDoc *theDoc = m_TransMgr->GetDoc();
+ CClientDataModelBridge *theBridge = m_StudioSystem->GetClientDataModelBridge();
+ ISlideSystem *theSlideSystem = m_StudioSystem->GetSlideSystem();
+
+ qt3dsdm::Qt3DSDMSlideHandle theSlide = theSlideSystem->GetAssociatedSlide(inInstance);
+ if (theBridge->IsInActiveComponent(inInstance)
+ && (theSlideSystem->IsMasterSlide(theSlide) || theSlide == theDoc->GetActiveSlide())) {
+ // Only add if the asset is in the current active component, and it's a master asset or in
+ // the current slide
+ ITimelineItemBinding *theNextItem = nullptr;
+ qt3dsdm::Qt3DSDMInstanceHandle theParentInstance = GetInstance();
+ // Figure out where to insert this row, if applicable.
+ // CAsset has a list of children, and not necessarily all are active in this slide (e.g.
+ // non-master children)
+ Q3DStudio::TIdentifier theNextChild = 0;
+ if (theParentInstance.Valid()) {
+ // Get the next prioritized child in the same slide
+ Q3DStudio::CGraphIterator theChildren;
+ GetAssetChildrenInSlide(theDoc, theParentInstance, theDoc->GetActiveSlide(),
+ theChildren);
+ theNextChild = GetSibling(inInstance, true, theChildren);
+ }
+
+ if (theNextChild != 0)
+ theNextItem = m_TransMgr->GetOrCreate(theNextChild);
+ }
+}
+
+void Qt3DSDMTimelineItemBinding::OnDeleteChild(Qt3DSDMInstanceHandle inInstance)
+{
+}
+
+void Qt3DSDMTimelineItemBinding::UpdateActionStatus()
+{
+}
+
+//=============================================================================
+/**
+ * Open the associated item as though it was double-clicked in explorer
+ * Respective subclasses (for example Image and Behavior) can call this function
+ */
+bool Qt3DSDMTimelineItemBinding::OpenSourcePathFile()
+{
+ // Get source path property value
+ CClientDataModelBridge *theClientBridge = m_StudioSystem->GetClientDataModelBridge();
+ qt3dsdm::IPropertySystem *thePropertySystem = m_StudioSystem->GetPropertySystem();
+ SValue theValue;
+ if (thePropertySystem->GetInstancePropertyValue(
+ m_DataHandle, theClientBridge->GetSourcePathProperty(), theValue)) {
+ // Open the respective file
+ Q3DStudio::CFilePath theSourcePath(qt3dsdm::get<qt3dsdm::TDataStrPtr>(theValue)->GetData());
+ Qt3DSFile theFile(m_TransMgr->GetDoc()->GetResolvedPathToDoc(theSourcePath));
+ theFile.Execute();
+ return true;
+ }
+ return false;
+}
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.h b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.h
new file mode 100644
index 00000000..39c81c6d
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.h
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//==============================================================================
+// Prefix
+//==============================================================================
+#ifndef INCLUDED_QT3DSDM_TIMELINEITEM_BINDING_H
+#define INCLUDED_QT3DSDM_TIMELINEITEM_BINDING_H 1
+
+#pragma once
+
+#include "ITimelineItemBinding.h"
+#include "ITimelineItem.h"
+
+// Data model
+#include "Qt3DSDMHandles.h"
+#include "IDragable.h"
+#include "Qt3DSDMAssetTimelineKeyframe.h"
+#include "OffsetKeyframesCommandHelper.h"
+#include "Qt3DSDMTimeline.h"
+#include "Qt3DSDMSignals.h"
+#include "DispatchListeners.h"
+
+//==============================================================================
+// Classes
+//==============================================================================
+class CTimelineTranslationManager;
+class Qt3DSDMTimelineItemProperty;
+class CCmdDataModelSetKeyframeTime;
+class RowTree;
+
+namespace qt3dsdm {
+class CStudioSystem;
+}
+
+//=============================================================================
+/**
+ * Binding to generic DataModel object
+ */
+class Qt3DSDMTimelineItemBinding : public ITimelineItemBinding,
+ public ITimelineItem,
+ public IDragable
+
+{
+protected: // Typedef
+ typedef std::map<qt3dsdm::Qt3DSDMPropertyHandle, Qt3DSDMTimelineItemProperty *> TPropertyBindingMap;
+ typedef std::vector<Qt3DSDMAssetTimelineKeyframe> TAssetKeyframeList;
+
+protected:
+ RowTree *m_rowTree = nullptr;
+ CTimelineTranslationManager *m_TransMgr;
+ qt3dsdm::Qt3DSDMInstanceHandle m_DataHandle;
+ ITimelineItemBinding *m_Parent;
+ ITimelineTimebar *m_TimelineTimebar;
+ TPropertyBindingMap m_PropertyBindingMap;
+ TAssetKeyframeList m_Keyframes; /// Sorted (by time) list of keyframes
+ qt3dsdm::CStudioSystem *m_StudioSystem;
+
+ qt3dsdm::TSignalConnectionPtr m_StartTimeConnection;
+ qt3dsdm::TSignalConnectionPtr m_EndTimeConnection;
+
+public:
+ Qt3DSDMTimelineItemBinding(CTimelineTranslationManager *inMgr,
+ qt3dsdm::Qt3DSDMInstanceHandle inDataHandle);
+ Qt3DSDMTimelineItemBinding(CTimelineTranslationManager *inMgr);
+ virtual ~Qt3DSDMTimelineItemBinding();
+
+protected:
+ bool GetBoolean(qt3dsdm::Qt3DSDMPropertyHandle inProperty) const;
+ void SetBoolean(qt3dsdm::Qt3DSDMPropertyHandle inProperty, bool inValue,
+ const QString &inNiceText) const;
+ void SetInstanceHandle(qt3dsdm::Qt3DSDMInstanceHandle inDataHandle);
+
+public:
+ // ITimelineItem
+ EStudioObjectType GetObjectType() const override;
+ bool IsMaster() const override;
+ bool IsShy() const override;
+ void SetShy(bool) override;
+ bool IsLocked() const override;
+ void SetLocked(bool) override;
+ bool IsVisible() const override;
+ void SetVisible(bool) override;
+ bool HasAction(bool inMaster) override;
+ bool IsVisibilityControlled() const override;
+ bool ChildrenHasAction(bool inMaster) override;
+ bool ComponentHasAction(bool inMaster) override;
+ bool hasSubpresentation() const override;
+ ITimelineTimebar *GetTimebar() override;
+
+ // INamable
+ Q3DStudio::CString GetName() const override;
+ void SetName(const Q3DStudio::CString &inName) override;
+
+ // ITimelineItemBinding
+ ITimelineItem *GetTimelineItem() override;
+ RowTree *getRowTree() const override;
+ void setRowTree(RowTree *row) override;
+ void SetSelected(bool inMultiSelect) override;
+ void OnCollapsed() override;
+ bool OpenAssociatedEditor() override;
+ void SetDropTarget(CDropTarget *inTarget) override;
+ // Hierarchy
+ long GetChildrenCount() override;
+ ITimelineItemBinding *GetChild(long inIndex) override;
+ QList<ITimelineItemBinding *> GetChildren() override;
+ ITimelineItemBinding *GetParent() override;
+ void SetParent(ITimelineItemBinding *parent) override;
+ // Properties
+ long GetPropertyCount() override;
+ ITimelineItemProperty *GetProperty(long inIndex) override;
+ // Eye/Lock toggles
+ bool ShowToggleControls() const override;
+ bool IsLockedEnabled() const override;
+ bool IsVisibleEnabled() const override;
+ // ContextMenu
+ bool IsValidTransaction(EUserTransaction inTransaction) override;
+ void PerformTransaction(EUserTransaction inTransaction) override;
+ Q3DStudio::CString GetObjectPath() override;
+
+ // ITimelineItemKeyframesHolder
+ void InsertKeyframe() override;
+ void DeleteAllChannelKeyframes() override;
+ IKeyframe *GetKeyframeByTime(long inTime) const override;
+
+ // IUICDMSelectable
+ virtual qt3dsdm::Qt3DSDMInstanceHandle GetInstanceHandle() const;
+
+ // IDragable
+ long GetFlavor() const override;
+
+ virtual void AddPropertyRow(qt3dsdm::Qt3DSDMPropertyHandle inPropertyHandle,
+ bool inAppend = false);
+ virtual void RemovePropertyRow(qt3dsdm::Qt3DSDMPropertyHandle inPropertyHandle);
+ virtual void RefreshPropertyKeyframe(qt3dsdm::Qt3DSDMPropertyHandle inPropertyHandle,
+ qt3dsdm::Qt3DSDMKeyframeHandle,
+ ETimelineKeyframeTransaction inTransaction);
+ virtual void OnPropertyChanged(qt3dsdm::Qt3DSDMPropertyHandle inPropertyHandle);
+ virtual void OnPropertyLinked(qt3dsdm::Qt3DSDMPropertyHandle inPropertyHandle);
+
+ // Keyframe manipulation
+ virtual bool HasDynamicKeyframes(long inTime);
+ virtual void SetDynamicKeyframes(long inTime, bool inDynamic);
+
+ virtual void OnAddChild(qt3dsdm::Qt3DSDMInstanceHandle inInstance);
+ virtual void OnDeleteChild(qt3dsdm::Qt3DSDMInstanceHandle inInstance);
+
+ void UpdateActionStatus();
+
+ Q3DStudio::CId GetGuid() const;
+
+ // Bridge between asset & DataModel. Ideally we should be fully DataModel
+ virtual qt3dsdm::Qt3DSDMInstanceHandle GetInstance() const;
+
+ int getAnimatedPropertyIndex(int propertyHandle) const;
+ void getTimeContextIndices(const QSet<int> &children, QMap<int ,int> &indexMap);
+
+ ITimelineItemProperty *GetOrCreatePropertyBinding(qt3dsdm::Qt3DSDMPropertyHandle inPropertyHandle);
+ ITimelineItemProperty *GetPropertyBinding(qt3dsdm::Qt3DSDMPropertyHandle inPropertyHandle);
+
+ bool isRootComponent() const;
+ bool isDefaultMaterial() const;
+
+protected:
+ virtual ITimelineTimebar *CreateTimelineTimebar();
+ void RemoveAllPropertyBindings();
+ void AddKeyframes(ITimelineItemProperty *inPropertyBinding);
+ bool
+ DeleteAssetKeyframesWhereApplicable(ITimelineItemProperty *inTriggerPropertyBinding = nullptr);
+ void UpdateKeyframe(IKeyframe *inKeyframe, ETimelineKeyframeTransaction inTransaction);
+
+ // For iterating through children
+ virtual bool AmITimeParent() const { return false; }
+
+ // subclasses can call this method to open referenced files
+ virtual bool OpenSourcePathFile();
+};
+
+#endif // INCLUDED_QT3DSDM_TIMELINEITEM_BINDING_H
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemProperty.cpp b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemProperty.cpp
new file mode 100644
index 00000000..d89fcc98
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemProperty.cpp
@@ -0,0 +1,470 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "Qt3DSCommonPrecompile.h"
+#include "Qt3DSDMTimelineItemProperty.h"
+#include "TimelineTranslationManager.h"
+#include "ITimelineItemBinding.h"
+#include "Qt3DSDMTimelineItemBinding.h"
+#include "Qt3DSDMTimelineKeyframe.h"
+#include "CmdDataModelChangeKeyframe.h"
+#include "CmdDataModelRemoveKeyframe.h"
+#include "StudioApp.h"
+#include "Core.h"
+#include "RowTree.h"
+
+// Link to data model
+#include "TimeEditDlg.h"
+#include "ClientDataModelBridge.h"
+#include "Qt3DSDMSlides.h"
+#include "Qt3DSDMStudioSystem.h"
+#include "Qt3DSDMAnimation.h"
+#include "Qt3DSDMMetaData.h"
+#include "Qt3DSDMPropertyDefinition.h"
+#include "Qt3DSDMDataCore.h"
+#include "StudioFullSystem.h"
+using namespace qt3dsdm;
+
+bool SortKeyframeByTime(const Qt3DSDMTimelineKeyframe *inLHS, const Qt3DSDMTimelineKeyframe *inRHS)
+{
+ 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)
+ : m_InstanceHandle(inInstance)
+ , m_PropertyHandle(inPropertyHandle)
+ , m_TransMgr(inTransMgr)
+ , m_SetKeyframeValueCommand(nullptr)
+{
+ // Cache all the animation handles because we need them for any keyframes manipulation.
+ // the assumption is that all associated handles are created all at once (i.e. we do not need to
+ // add or delete from this list )
+ CreateKeyframes();
+ InitializeCachedVariables(inInstance);
+ m_Signals.push_back(
+ m_TransMgr->GetStudioSystem()->GetFullSystem()->GetSignalProvider()->ConnectPropertyLinked(
+ std::bind(&Qt3DSDMTimelineItemProperty::OnPropertyLinkStatusChanged, this,
+ std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
+
+ m_Signals.push_back(
+ m_TransMgr->GetStudioSystem()
+ ->GetFullSystem()
+ ->GetSignalProvider()
+ ->ConnectPropertyUnlinked(std::bind(
+ &Qt3DSDMTimelineItemProperty::OnPropertyLinkStatusChanged, this,
+ std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
+}
+
+Qt3DSDMTimelineItemProperty::~Qt3DSDMTimelineItemProperty()
+{
+ ReleaseKeyframes();
+}
+
+void Qt3DSDMTimelineItemProperty::CreateKeyframes()
+{
+ // Cache all the animation handles because we need them for any keyframes manipulation.
+ // the assumption is that all associated handles are created all at once (i.e. we do not need to
+ // add or delete from this list )
+ qt3dsdm::IPropertySystem *thePropertySystem = m_TransMgr->GetStudioSystem()->GetPropertySystem();
+ DataModelDataType::Value theDataType = thePropertySystem->GetDataType(m_PropertyHandle);
+ IStudioAnimationSystem *theAnimationSystem =
+ m_TransMgr->GetStudioSystem()->GetAnimationSystem();
+ std::tuple<bool, size_t> theArity = GetDatatypeAnimatableAndArity(theDataType);
+ for (size_t i = 0; i < std::get<1>(theArity); ++i) {
+ Qt3DSDMAnimationHandle theAnimationHandle =
+ theAnimationSystem->GetControllingAnimation(m_InstanceHandle, m_PropertyHandle, i);
+ if (theAnimationHandle.Valid())
+ m_AnimationHandles.push_back(theAnimationHandle);
+ }
+ if (!m_AnimationHandles.empty()) { // update wrappers for keyframes
+ IAnimationCore *theAnimationCore = m_TransMgr->GetStudioSystem()->GetAnimationCore();
+ TKeyframeHandleList theKeyframes;
+ // all channels have keyframes at the same time
+ theAnimationCore->GetKeyframes(m_AnimationHandles[0], theKeyframes);
+ for (size_t i = 0; i < theKeyframes.size(); ++i)
+ CreateKeyframeIfNonExistent(theKeyframes[i], m_AnimationHandles[0]);
+ }
+}
+
+void Qt3DSDMTimelineItemProperty::ReleaseKeyframes()
+{
+ m_Keyframes.clear();
+ m_AnimationHandles.clear();
+}
+
+qt3dsdm::Qt3DSDMPropertyHandle Qt3DSDMTimelineItemProperty::getPropertyHandle() const
+{
+ return m_PropertyHandle;
+}
+
+// Type doesn't change and due to the logic required to figure this out, cache it.
+void Qt3DSDMTimelineItemProperty::InitializeCachedVariables(qt3dsdm::Qt3DSDMInstanceHandle inInstance)
+{
+ using namespace Q3DStudio;
+ qt3dsdm::IPropertySystem *thePropertySystem = m_TransMgr->GetStudioSystem()->GetPropertySystem();
+
+ m_Type.first = thePropertySystem->GetDataType(m_PropertyHandle);
+ m_Type.second = thePropertySystem->GetAdditionalMetaDataType(inInstance, m_PropertyHandle);
+
+ // Name doesn't change either.
+ TCharStr theFormalName = thePropertySystem->GetFormalName(inInstance, m_PropertyHandle);
+
+ if (theFormalName.empty()) // fallback on property name
+ theFormalName = thePropertySystem->GetName(m_PropertyHandle);
+ m_Name = theFormalName.c_str();
+}
+
+Q3DStudio::CString Qt3DSDMTimelineItemProperty::GetName() const
+{
+ return m_Name;
+}
+
+// Helper function to retrieve the parent binding class.
+inline ITimelineItemBinding *GetParentBinding(RowTree *inRow)
+{
+ ITimelineItemBinding *theParentBinding = nullptr;
+ if (inRow) {
+ RowTree *theParentRow = inRow->parentRow();
+ if (theParentRow) {
+ theParentBinding = theParentRow->getBinding();
+ Q_ASSERT(theParentBinding);
+ }
+ }
+ return theParentBinding;
+}
+
+bool Qt3DSDMTimelineItemProperty::IsMaster() const
+{
+ if (m_rowTree) {
+ if (Qt3DSDMTimelineItemBinding *theParentBinding =
+ static_cast<Qt3DSDMTimelineItemBinding *>(GetParentBinding(m_rowTree)))
+ return m_TransMgr->GetDoc()->GetDocumentReader().IsPropertyLinked(
+ theParentBinding->GetInstanceHandle(), m_PropertyHandle);
+ }
+ return false;
+}
+
+qt3dsdm::TDataTypePair Qt3DSDMTimelineItemProperty::GetType() const
+{
+ return m_Type;
+}
+
+void CompareAndSet(const Qt3DSDMTimelineKeyframe *inKeyframe, float &outRetValue, bool inGreaterThan)
+{
+ float theValue = (inGreaterThan) ? inKeyframe->GetMaxValue() : inKeyframe->GetMinValue();
+ if ((inGreaterThan && theValue > outRetValue) || (!inGreaterThan && theValue < outRetValue))
+ outRetValue = theValue;
+}
+
+// return the max value of the current set of keyframes
+float Qt3DSDMTimelineItemProperty::GetMaximumValue() const
+{
+ float theRetVal = FLT_MIN;
+ do_all(m_Keyframes, std::bind(CompareAndSet, std::placeholders::_1, std::ref(theRetVal), true));
+ if (m_Type.first == DataModelDataType::Float4 && m_Type.second == AdditionalMetaDataType::Color)
+ theRetVal = DataModelToColor(theRetVal);
+ return theRetVal;
+}
+
+// return the min value of the current set of keyframes
+float Qt3DSDMTimelineItemProperty::GetMinimumValue() const
+{
+ float theRetVal = FLT_MAX;
+ do_all(m_Keyframes, std::bind(CompareAndSet, std::placeholders::_1, std::ref(theRetVal), false));
+ if (m_Type.first == DataModelDataType::Float4 && m_Type.second == AdditionalMetaDataType::Color)
+ theRetVal = DataModelToColor(theRetVal);
+ return theRetVal;
+}
+
+RowTree *Qt3DSDMTimelineItemProperty::getRowTree() const
+{
+ return m_rowTree;
+}
+
+// Ensures the object that owns this property is selected.
+void Qt3DSDMTimelineItemProperty::SetSelected()
+{
+ if (m_rowTree) {
+ ITimelineItemBinding *theParentBinding = GetParentBinding(m_rowTree);
+ if (theParentBinding)
+ theParentBinding->SetSelected(false);
+ }
+}
+
+void Qt3DSDMTimelineItemProperty::DeleteAllKeys()
+{
+ if (m_Keyframes.empty())
+ return;
+
+ using namespace Q3DStudio;
+
+ ScopedDocumentEditor editor(*m_TransMgr->GetDoc(), QObject::tr("Delete All Keyframes"),
+ __FILE__, __LINE__);
+ for (size_t idx = 0, end = m_AnimationHandles.size(); idx < end; ++idx)
+ editor->DeleteAllKeyframes(m_AnimationHandles[idx]);
+}
+
+IKeyframe *Qt3DSDMTimelineItemProperty::GetKeyframeByTime(long inTime) const
+{
+ std::vector<long> theTest;
+ TKeyframeList::const_iterator theIter = m_Keyframes.begin();
+ for (; theIter != m_Keyframes.end(); ++theIter) {
+ if ((*theIter)->GetTime() == inTime)
+ return (*theIter);
+
+ theTest.push_back((*theIter)->GetTime());
+ }
+ // if key had been deleted, this returns nullptr
+ return nullptr;
+}
+
+IKeyframe *Qt3DSDMTimelineItemProperty::GetKeyframeByIndex(long inIndex) const
+{
+ if (inIndex >= 0 && inIndex < (long)m_Keyframes.size())
+ return m_Keyframes[inIndex];
+
+ Q_ASSERT(0); // should not happen
+ return nullptr;
+}
+
+long Qt3DSDMTimelineItemProperty::GetKeyframeCount() const
+{
+ // this list is updated in constructor and when keyframes are added or deleted.
+ return (long)m_Keyframes.size();
+}
+
+long Qt3DSDMTimelineItemProperty::GetChannelCount() const
+{
+ return (long)m_AnimationHandles.size();
+}
+
+float Qt3DSDMTimelineItemProperty::GetChannelValueAtTime(long inChannelIndex, long inTime)
+{
+ // 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();
+ thePropertySystem->GetInstancePropertyValue(theParentBinding->GetInstanceHandle(),
+ 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]);
+ }
+ break;
+ }
+ case DataModelDataType::Float3: {
+
+ SFloat3 theFloat3 = qt3dsdm::get<SFloat3>(theValue);
+ if (inChannelIndex >= 0 && inChannelIndex < 3)
+ return theFloat3[inChannelIndex];
+ break;
+ }
+ case DataModelDataType::Float2: {
+ SFloat2 theFloat2 = qt3dsdm::get<SFloat2>(theValue);
+ if (inChannelIndex >= 0 && inChannelIndex < 2)
+ return theFloat2[inChannelIndex];
+ 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);
+ }
+ }
+}
+
+void Qt3DSDMTimelineItemProperty::setRowTree(RowTree *rowTree)
+{
+ m_rowTree = rowTree;
+}
+
+bool Qt3DSDMTimelineItemProperty::IsDynamicAnimation()
+{
+ return m_Keyframes.size() > 0 && m_Keyframes[0]->IsDynamic();
+}
+
+//=============================================================================
+/**
+ * For updating the UI when keyframes are added/updated/deleted.
+ */
+bool Qt3DSDMTimelineItemProperty::RefreshKeyframe(qt3dsdm::Qt3DSDMKeyframeHandle inKeyframe,
+ ETimelineKeyframeTransaction inTransaction)
+{
+ bool theHandled = false;
+ switch (inTransaction) {
+ case ETimelineKeyframeTransaction_Delete: {
+ TKeyframeList::iterator theIter = m_Keyframes.begin();
+ for (; theIter != m_Keyframes.end(); ++theIter) {
+ Qt3DSDMTimelineKeyframe *theKeyframe = *theIter;
+ if (theKeyframe->HasKeyframeHandle(inKeyframe)) {
+ m_Keyframes.erase(theIter);
+ theHandled = true;
+ break;
+ }
+ }
+ } break;
+ case ETimelineKeyframeTransaction_Add: {
+ Q_ASSERT(!m_AnimationHandles.empty());
+ IAnimationCore *theAnimationCore = m_TransMgr->GetStudioSystem()->GetAnimationCore();
+ Qt3DSDMAnimationHandle theAnimationHandle =
+ theAnimationCore->GetAnimationForKeyframe(inKeyframe);
+ // only create for the first animation handle.
+ if (theAnimationHandle == m_AnimationHandles[0]) { // for undo/redo, the keyframes can be
+ // added in reverse, hence the need to
+ // sort
+ if (CreateKeyframeIfNonExistent(inKeyframe, theAnimationHandle))
+ std::stable_sort(m_Keyframes.begin(), m_Keyframes.end(), SortKeyframeByTime);
+ theHandled = true;
+ }
+ } break;
+ case ETimelineKeyframeTransaction_Update:
+ case ETimelineKeyframeTransaction_DynamicChanged:
+ theHandled = true;
+ break;
+ default:
+ return false;
+ }
+
+ return theHandled;
+}
+
+IKeyframe *Qt3DSDMTimelineItemProperty::GetKeyframeByHandle(qt3dsdm::Qt3DSDMKeyframeHandle inKeyframe)
+{
+ TKeyframeList::iterator theIter = m_Keyframes.begin();
+ for (; theIter != m_Keyframes.end(); ++theIter) {
+ Qt3DSDMTimelineKeyframe *theKeyframe = *theIter;
+ if (theKeyframe->HasKeyframeHandle(inKeyframe))
+ return *theIter;
+ }
+ return nullptr;
+}
+
+/**
+ * Create a wrapper for this keyframe if doesn't exists.
+ * @return true if created, false if already exists.
+ */
+bool Qt3DSDMTimelineItemProperty::CreateKeyframeIfNonExistent(
+ qt3dsdm::Qt3DSDMKeyframeHandle inKeyframeHandle, Qt3DSDMAnimationHandle inOwningAnimation)
+{
+ TKeyframeList::iterator theIter = m_Keyframes.begin();
+ for (; theIter != m_Keyframes.end(); ++theIter) {
+ Qt3DSDMTimelineKeyframe *theKeyframe = *theIter;
+ if (theKeyframe->HasKeyframeHandle(inKeyframeHandle))
+ return false;
+ }
+ // check for multiple channels => only create 1 Qt3DSDMTimelineKeyframe
+ Qt3DSDMTimelineKeyframe *theNewKeyframe =
+ new Qt3DSDMTimelineKeyframe(g_StudioApp.GetCore()->GetDoc());
+ theNewKeyframe->AddKeyframeHandle(inKeyframeHandle);
+ if (m_AnimationHandles.size()
+ > 1) { // assert assumption that is only called for the first handle
+ Q_ASSERT(m_AnimationHandles[0] == inOwningAnimation);
+ IAnimationCore *theAnimationCore = m_TransMgr->GetStudioSystem()->GetAnimationCore();
+ float theKeyframeTime = KeyframeTime(theAnimationCore->GetKeyframeData(inKeyframeHandle));
+ for (size_t i = 1; i < m_AnimationHandles.size(); ++i) {
+ TKeyframeHandleList theKeyframes;
+ theAnimationCore->GetKeyframes(m_AnimationHandles[i], theKeyframes);
+ // the data model ensures that there is only 1 keyframe created for a given time
+ for (size_t theKeyIndex = 0; theKeyIndex < theKeyframes.size(); ++theKeyIndex) {
+ float theValue =
+ KeyframeTime(theAnimationCore->GetKeyframeData(theKeyframes[theKeyIndex]));
+ if (theValue == theKeyframeTime) {
+ theNewKeyframe->AddKeyframeHandle(theKeyframes[theKeyIndex]);
+ break;
+ }
+ }
+ }
+ }
+ m_Keyframes.push_back(theNewKeyframe);
+ return true;
+}
+
+void Qt3DSDMTimelineItemProperty::OnPropertyLinkStatusChanged(qt3dsdm::Qt3DSDMSlideHandle inSlide,
+ qt3dsdm::Qt3DSDMInstanceHandle inInstance,
+ qt3dsdm::Qt3DSDMPropertyHandle inProperty)
+{
+ if (inInstance == m_InstanceHandle && inProperty == m_PropertyHandle) {
+ // Re-bind to keyframes because the ones we should be pointing to will have changed.
+ ReleaseKeyframes();
+ CreateKeyframes();
+ }
+}
+
+void Qt3DSDMTimelineItemProperty::RefreshKeyFrames(void)
+{
+ std::stable_sort(m_Keyframes.begin(), m_Keyframes.end(), SortKeyframeByTime);
+}
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemProperty.h b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemProperty.h
new file mode 100644
index 00000000..1b1524e4
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemProperty.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DSDM_TIMELINE_ITEM_PROPERTY_H
+#define QT3DSDM_TIMELINE_ITEM_PROPERTY_H 1
+
+#pragma once
+
+#include "ITimelineItemProperty.h"
+#include "Qt3DSDMTimelineKeyframe.h"
+#include "Qt3DSDMTimeline.h"
+#include "Qt3DSDMPropertyDefinition.h"
+
+class RowTree;
+class CTimelineTranslationManager;
+class CCmdDataModelSetKeyframeValue;
+class Qt3DSDMTimelineItemBinding;
+
+//=============================================================================
+/**
+ * A data model item's property.
+ * Typically only animated properties show up in the Timeline.
+ */
+//=============================================================================
+class Qt3DSDMTimelineItemProperty : public ITimelineItemProperty
+{
+public:
+ Qt3DSDMTimelineItemProperty(CTimelineTranslationManager *inTransMgr,
+ qt3dsdm::Qt3DSDMPropertyHandle inPropertyHandle,
+ qt3dsdm::Qt3DSDMInstanceHandle inInstance);
+ virtual ~Qt3DSDMTimelineItemProperty();
+
+ // ITimelineProperty
+ Q3DStudio::CString GetName() const override;
+ bool IsMaster() const override;
+ qt3dsdm::TDataTypePair GetType() const override;
+ float GetMaximumValue() const override;
+ float GetMinimumValue() const override;
+ void SetSelected() override;
+ void DeleteAllKeys() override;
+ IKeyframe *GetKeyframeByTime(long inTime) const override;
+ IKeyframe *GetKeyframeByIndex(long inIndex) const override;
+ long GetKeyframeCount() const override;
+ long GetChannelCount() const override;
+ float GetChannelValueAtTime(long inChannelIndex, long inTime) override;
+ void SetChannelValueAtTime(long inChannelIndex, long inTime, float inValue) override;
+ bool IsDynamicAnimation() override;
+
+ void setRowTree(RowTree *rowTree) override;
+ RowTree *getRowTree() const override;
+
+ bool RefreshKeyframe(qt3dsdm::Qt3DSDMKeyframeHandle inKeyframe,
+ ETimelineKeyframeTransaction inTransaction);
+ IKeyframe *GetKeyframeByHandle(qt3dsdm::Qt3DSDMKeyframeHandle inKeyframe);
+
+ void RefreshKeyFrames(void);
+
+ qt3dsdm::Qt3DSDMPropertyHandle getPropertyHandle() const;
+
+protected:
+ void InitializeCachedVariables(qt3dsdm::Qt3DSDMInstanceHandle inInstance);
+ bool CreateKeyframeIfNonExistent(qt3dsdm::Qt3DSDMKeyframeHandle inKeyframe,
+ qt3dsdm::Qt3DSDMAnimationHandle inOwningAnimation);
+ void OnPropertyLinkStatusChanged(qt3dsdm::Qt3DSDMSlideHandle inSlide,
+ qt3dsdm::Qt3DSDMInstanceHandle inInstance,
+ qt3dsdm::Qt3DSDMPropertyHandle inProperty);
+ void CreateKeyframes();
+ void ReleaseKeyframes();
+
+protected:
+ typedef std::vector<Qt3DSDMTimelineKeyframe *> TKeyframeList;
+
+ qt3dsdm::Qt3DSDMInstanceHandle m_InstanceHandle;
+ qt3dsdm::Qt3DSDMPropertyHandle m_PropertyHandle;
+ CTimelineTranslationManager *m_TransMgr;
+ std::vector<qt3dsdm::Qt3DSDMAnimationHandle> m_AnimationHandles;
+ TKeyframeList m_Keyframes;
+ CCmdDataModelSetKeyframeValue
+ *m_SetKeyframeValueCommand; // for merging modifying keyframe values via graph
+ qt3dsdm::TDataTypePair m_Type;
+ Q3DStudio::CString m_Name;
+ std::vector<std::shared_ptr<qt3dsdm::ISignalConnection>> m_Signals;
+
+private:
+ RowTree *m_rowTree = nullptr;
+};
+
+#endif // QT3DSDM_TIMELINE_ITEM_PROPERTY_H
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineKeyframe.cpp b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineKeyframe.cpp
new file mode 100644
index 00000000..ae7e2035
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineKeyframe.cpp
@@ -0,0 +1,223 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "Qt3DSCommonPrecompile.h"
+#include "Qt3DSDMTimelineKeyframe.h"
+#include "Qt3DSDMAnimation.h"
+#include "CmdDataModelChangeKeyframe.h"
+#include "CmdBatch.h"
+#include "Qt3DSDMStudioSystem.h"
+#include "OffsetKeyframesCommandHelper.h"
+
+#include "Doc.h"
+#include "StudioApp.h"
+#include "Core.h"
+
+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)
+{
+}
+
+Qt3DSDMTimelineKeyframe::~Qt3DSDMTimelineKeyframe()
+{
+}
+
+bool Qt3DSDMTimelineKeyframe::IsSelected() const
+{
+ return m_Selected;
+}
+
+float my_roundf(float r)
+{
+ return (r > 0.0f) ? floorf(r + 0.5f) : ceilf(r - 0.5f);
+}
+
+long Qt3DSDMTimelineKeyframe::GetTime() const
+{
+ if (!m_KeyframeHandles.empty()) {
+ IAnimationCore *theAnimationCore = m_Doc->GetStudioSystem()->GetAnimationCore();
+ Qt3DSDMKeyframeHandle theKeyframeHandle = *m_KeyframeHandles.begin();
+ if (theAnimationCore->KeyframeValid(theKeyframeHandle)) {
+ float theTimeinSecs =
+ KeyframeTime(theAnimationCore->GetKeyframeData(theKeyframeHandle));
+ // We always convert back and forth between between long and float.
+ // This causes especially issues when we do comparisons
+ return (long)my_roundf(theTimeinSecs * 1000);
+ }
+ }
+ return -1; // keyframe was deleted, and data cannot be retrieved.
+}
+
+float Qt3DSDMTimelineKeyframe::GetTimeInSecs(long inTime)
+{
+ float theTimeinSecs = static_cast<float>(inTime) / 1000.f;
+ // round off to 4 decimal place to workaround precision issues
+ // TODO: fix this, either all talk float OR long. choose one.
+ theTimeinSecs = (float)(((theTimeinSecs + 0.00005) * 10000.0) / 10000.0f);
+ return theTimeinSecs;
+}
+
+void Qt3DSDMTimelineKeyframe::SetTime(const long inNewTime)
+{
+ float theTimeinSecs = GetTimeInSecs(inNewTime);
+ CCmd *theCmd = nullptr;
+ if (m_KeyframeHandles.size() == 1) {
+ theCmd = new CCmdDataModelSetKeyframeTime(m_Doc, m_KeyframeHandles.front(), theTimeinSecs);
+ } else { // more than 1 channel
+ CCmdBatch *theBatch = new CCmdBatch(m_Doc);
+ TKeyframeHandleList::iterator theIter = m_KeyframeHandles.begin();
+ for (; theIter != m_KeyframeHandles.end(); ++theIter)
+ theBatch->AddCommand(new CCmdDataModelSetKeyframeTime(m_Doc, *theIter, theTimeinSecs));
+ theCmd = theBatch;
+ }
+ if (theCmd)
+ m_Doc->GetCore()->ExecuteCommand(theCmd);
+
+#ifdef _DEBUG
+ // we have a precision issue from converting from long to float..
+ IAnimationCore *theAnimationCore = m_Doc->GetStudioSystem()->GetAnimationCore();
+ long theTest = static_cast<long>(
+ KeyframeTime(theAnimationCore->GetKeyframeData(*m_KeyframeHandles.begin())) * 1000);
+ Q_ASSERT(inNewTime == theTest);
+#endif
+}
+
+inline Qt3DSDMAnimationHandle GetAnimationHandle(qt3dsdm::IAnimationCore *inAnimationCore,
+ const TKeyframeHandleList &inKeyframes)
+{
+ if (!inKeyframes.empty())
+ return inAnimationCore->GetAnimationForKeyframe(inKeyframes[0]);
+ return 0;
+}
+
+void Qt3DSDMTimelineKeyframe::SetDynamic(bool inIsDynamic)
+{
+ if (!m_KeyframeHandles.empty()) {
+ Qt3DSDMAnimationHandle theAnimation =
+ GetAnimationHandle(m_Doc->GetStudioSystem()->GetAnimationCore(), m_KeyframeHandles);
+ if (theAnimation.Valid())
+ m_Doc->GetCore()->ExecuteCommand(
+ new CCmdDataModelChangeDynamicKeyframe(m_Doc, theAnimation, inIsDynamic));
+ }
+}
+
+Keyframe *Qt3DSDMTimelineKeyframe::getUI()
+{
+ return m_ui;
+}
+
+void Qt3DSDMTimelineKeyframe::setUI(Keyframe *kfUI)
+{
+ m_ui = kfUI;
+}
+
+// Only the first key of a track can be dynamic.
+bool Qt3DSDMTimelineKeyframe::IsDynamic() const
+{
+ qt3dsdm::IAnimationCore *theAnimationCore = m_Doc->GetStudioSystem()->GetAnimationCore();
+ Qt3DSDMAnimationHandle theAnimation = GetAnimationHandle(theAnimationCore, m_KeyframeHandles);
+ if (theAnimation.Valid()) {
+ SAnimationInfo theInfo = theAnimationCore->GetAnimationInfo(theAnimation);
+ if (theInfo.m_DynamicFirstKeyframe) {
+ TKeyframeHandleList theKeyframes;
+ theAnimationCore->GetKeyframes(theAnimation, theKeyframes);
+ if (!theKeyframes.empty()) // only true if track is dynamic and this is the first
+ // keyframe. Might have to optimize because this is so
+ // clunky.
+ return (theKeyframes[0] == m_KeyframeHandles[0]);
+ }
+ }
+ return false;
+}
+
+void Qt3DSDMTimelineKeyframe::AddKeyframeHandle(qt3dsdm::Qt3DSDMKeyframeHandle inHandle)
+{
+ m_KeyframeHandles.push_back(inHandle);
+}
+
+bool Qt3DSDMTimelineKeyframe::HasKeyframeHandle(qt3dsdm::Qt3DSDMKeyframeHandle inHandle) const
+{
+ TKeyframeHandleList::const_iterator theIter = m_KeyframeHandles.begin();
+ for (; theIter != m_KeyframeHandles.end(); ++theIter) {
+ if (*theIter == inHandle)
+ return true;
+ }
+ return false;
+}
+
+void Qt3DSDMTimelineKeyframe::SetSelected(bool inSelected)
+{
+ m_Selected = inSelected;
+}
+
+// For colors, there would be 3 keyframe handles
+void Qt3DSDMTimelineKeyframe::UpdateKeyframesTime(COffsetKeyframesCommandHelper *inCommandHelper,
+ long inTime)
+{
+ for (size_t i = 0; i < m_KeyframeHandles.size(); ++i)
+ inCommandHelper->SetCommandTime(m_KeyframeHandles[i], inTime);
+}
+
+void Qt3DSDMTimelineKeyframe::GetKeyframeHandles(TKeyframeHandleList &outList) const
+{
+ outList = m_KeyframeHandles;
+}
+
+void CompareAndSet(Qt3DSDMKeyframeHandle inKeyframe, IAnimationCore *inAnimationCore,
+ float &outRetValue, bool inGreaterThan)
+{
+ TKeyframe theKeyframeData = inAnimationCore->GetKeyframeData(inKeyframe);
+ float theValue = KeyframeValueValue(theKeyframeData);
+ if ((inGreaterThan && theValue > outRetValue) || (!inGreaterThan && theValue < outRetValue))
+ outRetValue = theValue;
+}
+
+float Qt3DSDMTimelineKeyframe::GetMaxValue() const
+{
+ IAnimationCore *theAnimationCore = m_Doc->GetStudioSystem()->GetAnimationCore();
+ float theRetVal = FLT_MIN;
+ do_all(m_KeyframeHandles,
+ std::bind(CompareAndSet, std::placeholders::_1, theAnimationCore,
+ std::ref(theRetVal), true));
+ return theRetVal;
+}
+
+float Qt3DSDMTimelineKeyframe::GetMinValue() const
+{
+ IAnimationCore *theAnimationCore = m_Doc->GetStudioSystem()->GetAnimationCore();
+ float theRetVal = FLT_MAX;
+ do_all(m_KeyframeHandles,
+ std::bind(CompareAndSet, std::placeholders::_1, theAnimationCore,
+ std::ref(theRetVal), false));
+ return theRetVal;
+}
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineKeyframe.h b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineKeyframe.h
new file mode 100644
index 00000000..7799cc0d
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineKeyframe.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QT3DSDM_KEYFRAME_H
+#define QT3DSDM_KEYFRAME_H 1
+
+#pragma once
+
+#include "IKeyframe.h"
+
+// Data model specific
+#include "Qt3DSDMHandles.h"
+
+class IDoc;
+class CDoc;
+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();
+
+ // IKeyframe
+ bool IsSelected() const override;
+ long GetTime() const override;
+ void SetTime(const long inNewTime) override;
+ void SetDynamic(bool inIsDynamic) override;
+ Keyframe *getUI() override;
+ void setUI(Keyframe *kfUI) override;
+ bool IsDynamic() const override;
+
+ void AddKeyframeHandle(qt3dsdm::Qt3DSDMKeyframeHandle inHandle);
+ bool HasKeyframeHandle(qt3dsdm::Qt3DSDMKeyframeHandle inHandle) const;
+ void SetSelected(bool inSelected);
+ void UpdateKeyframesTime(COffsetKeyframesCommandHelper *inCommandHelper, long inTime);
+ void GetKeyframeHandles(TKeyframeHandleList &outList) const;
+
+ // support drawing graphs
+ float GetMaxValue() const;
+ float GetMinValue() const;
+
+ static float GetTimeInSecs(long inTime);
+};
+
+#endif // QT3DSDM_KEYFRAME_H
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineTimebar.cpp b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineTimebar.cpp
new file mode 100644
index 00000000..0ecefefd
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineTimebar.cpp
@@ -0,0 +1,222 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "Qt3DSCommonPrecompile.h"
+#include "Qt3DSDMTimelineTimebar.h"
+#include "Qt3DSDMStudioSystem.h"
+#include "Qt3DSDMDataCore.h"
+#include "Qt3DSDMDataTypes.h"
+#include "ClientDataModelBridge.h"
+#include "TimelineTranslationManager.h"
+#include "Doc.h"
+#include "Dispatch.h"
+#include "Core.h"
+#include "IDocumentEditor.h"
+#include "StudioFullSystem.h"
+#include "StudioPreferences.h"
+#include "ITimelineItemBinding.h"
+#include "RowTree.h"
+#include "RowTimeline.h"
+#include "StudioApp.h"
+#include "Dialogs.h"
+
+Qt3DSDMTimelineTimebar::Qt3DSDMTimelineTimebar(
+ CTimelineTranslationManager *inTimelineTranslationManager,
+ qt3dsdm::Qt3DSDMInstanceHandle inDataHandle)
+ : Q3DStudio::CUpdateableDocumentEditor(*inTimelineTranslationManager->GetDoc())
+ , m_TimelineTranslationManager(inTimelineTranslationManager)
+ , m_PropertySystem(inTimelineTranslationManager->GetStudioSystem()->GetPropertySystem())
+ , m_DataHandle(inDataHandle)
+{
+ CClientDataModelBridge *theClientDataModelBridge =
+ inTimelineTranslationManager->GetStudioSystem()->GetClientDataModelBridge();
+ m_StartTime = theClientDataModelBridge->GetSceneAsset().m_StartTime;
+ m_EndTime = theClientDataModelBridge->GetSceneAsset().m_EndTime;
+ qt3dsdm::SValue theValue;
+ if (m_PropertySystem->GetInstancePropertyValue(
+ m_DataHandle, theClientDataModelBridge->GetSceneAsset().m_TimebarColor, theValue)) {
+ qt3dsdm::SFloat4 theTimebarColor = qt3dsdm::get<qt3dsdm::SFloat4>(theValue);
+
+ m_Color.SetRGB(static_cast<int>(theTimebarColor.m_Floats[0] * 255.0f),
+ static_cast<int>(theTimebarColor.m_Floats[1] * 255.0f),
+ static_cast<int>(theTimebarColor.m_Floats[2] * 255.0f));
+ }
+ qt3dsdm::IStudioFullSystemSignalProvider *theProvider =
+ inTimelineTranslationManager->GetStudioSystem()->GetFullSystem()->GetSignalProvider();
+ m_PropertyChangedSignal = theProvider->ConnectInstancePropertyValue(
+ std::bind(&Qt3DSDMTimelineTimebar::OnPropertyChanged, this,
+ std::placeholders::_1, std::placeholders::_2));
+
+ OnPropertyChanged(m_DataHandle, theClientDataModelBridge->GetSceneAsset().m_TimebarColor);
+ OnPropertyChanged(m_DataHandle, theClientDataModelBridge->GetSceneAsset().m_TimebarText);
+}
+
+void Qt3DSDMTimelineTimebar::OnPropertyChanged(qt3dsdm::Qt3DSDMInstanceHandle inInstance,
+ qt3dsdm::Qt3DSDMPropertyHandle inProperty)
+{
+ if (m_DataHandle == inInstance) {
+ bool needsInvalidate = false;
+ qt3dsdm::SValue theValue;
+ CClientDataModelBridge *theClientDataModelBridge =
+ m_TimelineTranslationManager->GetStudioSystem()->GetClientDataModelBridge();
+ if (inProperty == theClientDataModelBridge->GetSceneAsset().m_TimebarColor) {
+
+ if (m_PropertySystem->GetInstancePropertyValue(
+ m_DataHandle, theClientDataModelBridge->GetSceneAsset().m_TimebarColor,
+ theValue)) {
+ qt3dsdm::SFloat4 theTimebarColor = qt3dsdm::get<qt3dsdm::SFloat4>(theValue);
+
+ m_Color.SetRGB(static_cast<int>(theTimebarColor.m_Floats[0] * 255.0f),
+ static_cast<int>(theTimebarColor.m_Floats[1] * 255.0f),
+ static_cast<int>(theTimebarColor.m_Floats[2] * 255.0f));
+ } else {
+ switch (theClientDataModelBridge->GetObjectType(inInstance)) {
+ case OBJTYPE_LAYER:
+ m_Color = CStudioPreferences::GetLayerTimebarColor();
+ break;
+ default:
+ m_Color = CStudioPreferences::GetObjectTimebarColor();
+ break;
+ }
+ }
+ needsInvalidate = true;
+ } else if (inProperty == theClientDataModelBridge->GetSceneAsset().m_TimebarText) {
+ if (m_PropertySystem->GetInstancePropertyValue(
+ m_DataHandle, theClientDataModelBridge->GetSceneAsset().m_TimebarText,
+ theValue)) {
+ m_Comment = qt3dsdm::get<qt3dsdm::TDataStrPtr>(theValue)->toQString();
+ } else {
+ m_Comment.clear();
+ }
+ needsInvalidate = true;
+ }
+ if (needsInvalidate) {
+ ITimelineItemBinding *theBinding =
+ m_TimelineTranslationManager->GetOrCreate(inInstance);
+ if (theBinding) {
+ RowTree *rowTree = theBinding->getRowTree();
+ if (rowTree)
+ rowTree->rowTimeline()->setBarColor(m_Color);
+ }
+ }
+ }
+}
+
+Qt3DSDMTimelineTimebar::~Qt3DSDMTimelineTimebar()
+{
+}
+
+// TODO: Can we put this on IInstancePropertyCore?
+template <typename T>
+T GetInstancePropertyValue(qt3dsdm::IPropertySystem *inPropertySystem,
+ qt3dsdm::Qt3DSDMInstanceHandle inInstanceHandle,
+ qt3dsdm::Qt3DSDMPropertyHandle inProperty)
+{
+ qt3dsdm::SValue theValue;
+ inPropertySystem->GetInstancePropertyValue(inInstanceHandle, inProperty, theValue);
+ return qt3dsdm::get<T>(theValue);
+}
+
+long Qt3DSDMTimelineTimebar::GetStartTime() const
+{
+ return GetInstancePropertyValue<qt3ds::QT3DSI32>(m_PropertySystem, m_DataHandle, m_StartTime);
+}
+
+long Qt3DSDMTimelineTimebar::GetEndTime() const
+{
+ return GetInstancePropertyValue<qt3ds::QT3DSI32>(m_PropertySystem, m_DataHandle, m_EndTime);
+}
+
+long Qt3DSDMTimelineTimebar::GetDuration() const
+{
+ auto theStartTime = GetInstancePropertyValue<qt3ds::QT3DSI32>(m_PropertySystem, m_DataHandle, m_StartTime);
+ auto theEndTime = GetInstancePropertyValue<qt3ds::QT3DSI32>(m_PropertySystem, m_DataHandle, m_EndTime);
+
+ return theEndTime - theStartTime;
+}
+
+bool Qt3DSDMTimelineTimebar::ShowHandleBars() const
+{
+ return true;
+}
+
+void Qt3DSDMTimelineTimebar::OnBeginDrag()
+{ // Really? TODO: Figure out why this is here.
+ // ASSERT(0);
+}
+
+void Qt3DSDMTimelineTimebar::OffsetTime(long inDiff)
+{
+ if (m_DataHandle.Valid()) {
+ ENSURE_EDITOR(QObject::tr("Time Bar Move")).OffsetTimeRange(m_DataHandle, inDiff);
+ m_TimelineTranslationManager->GetDoc()
+ ->GetCore()
+ ->GetDispatch()
+ ->FireImmediateRefreshInstance(m_DataHandle);
+ }
+}
+
+void Qt3DSDMTimelineTimebar::ChangeTime(long inTime, bool inSetStart)
+{
+ if (m_DataHandle.Valid()) {
+ ENSURE_EDITOR(QObject::tr("Time Bar Resize")).ResizeTimeRange(m_DataHandle, inTime,
+ inSetStart);
+ m_TimelineTranslationManager->GetDoc()
+ ->GetCore()
+ ->GetDispatch()
+ ->FireImmediateRefreshInstance(m_DataHandle);
+ }
+}
+
+void Qt3DSDMTimelineTimebar::CommitTimeChange()
+{
+ CommitEditor();
+}
+
+void Qt3DSDMTimelineTimebar::RollbackTimeChange()
+{
+ RollbackEditor();
+}
+
+void Qt3DSDMTimelineTimebar::SetTimebarComment(const QString &inComment)
+{
+ using namespace Q3DStudio;
+ if (inComment != m_Comment) {
+ qt3dsdm::Qt3DSDMInstanceHandle theHandle = m_DataHandle;
+ SCOPED_DOCUMENT_EDITOR(*m_TimelineTranslationManager->GetDoc(),
+ QObject::tr("Set Time Bar Text"))
+ ->SetTimebarText(theHandle, inComment);
+ }
+}
+
+void Qt3DSDMTimelineTimebar::SetTimebarTime(ITimeChangeCallback *inCallback /*= nullptr*/)
+{
+ g_StudioApp.GetDialogs()->asyncDisplayDurationEditDialog(GetStartTime(), GetEndTime(),
+ inCallback);
+}
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineTimebar.h b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineTimebar.h
new file mode 100644
index 00000000..33e3f22d
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/Qt3DSDMTimelineTimebar.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#pragma once
+
+///////////////////////////////////////////////////////////////////////////////
+// Includes
+#include "ITimelineTimebar.h"
+#include "Qt3DSDMHandles.h"
+#include "IDocumentEditor.h"
+
+///////////////////////////////////////////////////////////////////////////////
+// Forwards
+class CTimelineTranslationManager;
+
+namespace Q3DStudio {
+class IDocumentEditor;
+}
+
+namespace qt3dsdm {
+class IPropertySystem;
+class ISignalConnection;
+}
+
+//=============================================================================
+/**
+ * General timebar implementation for DataModel objects
+ */
+class Qt3DSDMTimelineTimebar : public ITimelineTimebar, public Q3DStudio::CUpdateableDocumentEditor
+{
+public:
+ Qt3DSDMTimelineTimebar(CTimelineTranslationManager *inTimelineTranslationManager,
+ qt3dsdm::Qt3DSDMInstanceHandle inDataHandle);
+ virtual ~Qt3DSDMTimelineTimebar();
+
+protected:
+ CTimelineTranslationManager *m_TimelineTranslationManager;
+ qt3dsdm::IPropertySystem *m_PropertySystem;
+ qt3dsdm::Qt3DSDMInstanceHandle m_DataHandle; // The Instance Handle for this Timeline Timeber.
+ qt3dsdm::Qt3DSDMPropertyHandle m_StartTime;
+ qt3dsdm::Qt3DSDMPropertyHandle m_EndTime;
+ ::CColor m_Color; // Timebar color
+
+ QString m_Comment; // Timebar comment text
+ std::shared_ptr<qt3dsdm::ISignalConnection> m_PropertyChangedSignal;
+ void OnPropertyChanged(qt3dsdm::Qt3DSDMInstanceHandle inInstance,
+ qt3dsdm::Qt3DSDMPropertyHandle inProperty);
+
+public:
+ // ITimelineTimebar
+ long GetStartTime() const override;
+ long GetEndTime() const override;
+ long GetDuration() const override;
+ bool ShowHandleBars() const override;
+ void OnBeginDrag() override;
+ void OffsetTime(long inDiff) override;
+ void ChangeTime(long inTime, bool inSetStart) override;
+ void CommitTimeChange() override;
+ void RollbackTimeChange() override;
+ ::CColor GetTimebarColor() override { return m_Color; }
+ QString GetTimebarComment() const override { return m_Comment; }
+ void SetTimebarComment(const QString &inComment) override;
+ void SetTimebarTime(ITimeChangeCallback *inCallback = nullptr) override;
+};
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/SlideTimelineItemBinding.cpp b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/SlideTimelineItemBinding.cpp
new file mode 100644
index 00000000..6707f717
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/SlideTimelineItemBinding.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "Qt3DSCommonPrecompile.h"
+#include "SlideTimelineItemBinding.h"
+
+// Data model specific
+#include "Doc.h"
+#include "CmdGeneric.h"
+#include "EmptyTimelineTimebar.h"
+
+#include "Qt3DSDMStudioSystem.h"
+#include "Qt3DSDMSlides.h"
+#include "ClientDataModelBridge.h"
+
+using namespace qt3dsdm;
+
+CSlideTimelineItemBinding::CSlideTimelineItemBinding(CTimelineTranslationManager *inMgr,
+ Qt3DSDMInstanceHandle inDataHandle)
+ : Qt3DSDMTimelineItemBinding(inMgr)
+{
+ qt3dsdm::Qt3DSDMSlideHandle theSlideHandle =
+ m_StudioSystem->GetSlideSystem()->GetSlideByInstance(inDataHandle);
+
+ // Get the owning component of m_SlideHandle.
+ // This should return CAsset OBJTYPE_SCENE or OBJTYPE_COMPONENT.
+ qt3dsdm::Qt3DSDMInstanceHandle theInstance =
+ m_StudioSystem->GetClientDataModelBridge()->GetOwningComponentInstance(theSlideHandle);
+ SetInstanceHandle(theInstance);
+
+ // Listen to change on Asset name
+ IStudioFullSystemSignalProvider *theEngine = m_StudioSystem->GetFullSystemSignalProvider();
+ std::function<void(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle)> theSetter(
+ std::bind(&CSlideTimelineItemBinding::OnPropertyChanged, this, std::placeholders::_2));
+ m_Connection = theEngine->ConnectInstancePropertyValue(
+ std::bind(qt3dsdm::MaybackCallbackInstancePropertyValue<std::function<void(
+ Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle)>>,
+ std::placeholders::_1, std::placeholders::_2, theInstance,
+ m_StudioSystem->GetClientDataModelBridge()->GetNameProperty(), theSetter));
+}
+
+ITimelineTimebar *CSlideTimelineItemBinding::GetTimebar()
+{ // No timebars on slides
+ return new CEmptyTimelineTimebar();
+}
+
+void CSlideTimelineItemBinding::SetName(const Q3DStudio::CString & /*inName*/)
+{
+ // Do nothing because name is read only
+}
+
+bool CSlideTimelineItemBinding::IsValidTransaction(EUserTransaction inTransaction)
+{
+ qt3dsdm::Qt3DSDMInstanceHandle theInstance = GetInstance();
+ switch (inTransaction) {
+ // Disable the following context menus
+ case EUserTransaction_Rename:
+ case EUserTransaction_MakeComponent:
+ case EUserTransaction_EditComponent:
+ return false;
+ default:
+ break;
+ }
+
+ return Qt3DSDMTimelineItemBinding::IsValidTransaction(inTransaction);
+}
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/SlideTimelineItemBinding.h b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/SlideTimelineItemBinding.h
new file mode 100644
index 00000000..54f01ce5
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/SlideTimelineItemBinding.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//==============================================================================
+// Prefix
+//==============================================================================
+#ifndef INCLUDED_SLIDE_TIMELINEITEM_BINDING_H
+#define INCLUDED_SLIDE_TIMELINEITEM_BINDING_H 1
+
+#pragma once
+
+#include "Qt3DSDMTimelineItemBinding.h"
+
+//==============================================================================
+// Classes
+//==============================================================================
+class ITimelineItem;
+class CTimelineTranslationManager;
+
+//=============================================================================
+/**
+ * Binding to a DataModel object of Slide type
+ */
+class CSlideTimelineItemBinding : public Qt3DSDMTimelineItemBinding
+{
+public:
+ CSlideTimelineItemBinding(CTimelineTranslationManager *inMgr,
+ qt3dsdm::Qt3DSDMInstanceHandle inDataHandle);
+ ~CSlideTimelineItemBinding() {}
+
+ // Qt3DSDMTimelineItemBinding
+ ITimelineTimebar *GetTimebar() override;
+ void SetName(const Q3DStudio::CString &inName) override;
+ bool IsValidTransaction(EUserTransaction inTransaction) override;
+
+ // No properties
+ long GetPropertyCount() override { return 0; }
+ ITimelineItemProperty *GetProperty(long) override { return nullptr; }
+
+ // Eye/Lock toggles are not applicable
+ bool ShowToggleControls() const override { return false; }
+ bool IsLockedEnabled() const override { return false; }
+ bool IsVisibleEnabled() const override { return false; }
+
+ // Shy, Locked, Visible are not applicable
+ bool IsShy() const override { return false; }
+ void SetShy(bool) override {}
+ bool IsLocked() const override { return false; }
+ void SetLocked(bool) override {}
+ bool IsVisible() const override { return true; }
+ void SetVisible(bool) override {}
+ bool IsVisibilityControlled() const override { return false; }
+
+ // Keyframes, not applicable to a Slide
+ void InsertKeyframe() override {}
+ void DeleteAllChannelKeyframes() override {}
+ IKeyframe *GetKeyframeByTime(long) const override { return nullptr; }
+
+ // Keyframe manipulation, not applicable
+ bool HasDynamicKeyframes(long inTime) override
+ {
+ Q_UNUSED(inTime);
+ return false;
+ }
+ void SetDynamicKeyframes(long inTime, bool inDynamic) override
+ {
+ Q_UNUSED(inTime);
+ Q_UNUSED(inDynamic);
+ }
+
+protected:
+ std::shared_ptr<qt3dsdm::ISignalConnection>
+ m_Connection; // Callback when the Asset name changes
+
+ bool AmITimeParent() const override { return true; }
+};
+
+#endif // INCLUDED_SLIDE_TIMELINEITEM_BINDING_H
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/TimelineBreadCrumbProvider.cpp b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/TimelineBreadCrumbProvider.cpp
new file mode 100644
index 00000000..ff7077aa
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/TimelineBreadCrumbProvider.cpp
@@ -0,0 +1,241 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "Qt3DSCommonPrecompile.h"
+#include "TimelineBreadCrumbProvider.h"
+#include "Core.h"
+
+// Link to data model
+#include "Doc.h"
+#include "StudioApp.h"
+#include "Cmd.h"
+#include "ResourceCache.h"
+#include "CColor.h"
+
+#include "ClientDataModelBridge.h"
+#include "Qt3DSDMStudioSystem.h"
+#include "Qt3DSDMSlides.h"
+#include "CmdActivateSlide.h"
+
+using namespace qt3dsdm;
+
+//=============================================================================
+/**
+ * Constructor
+ */
+CTimelineBreadCrumbProvider::CTimelineBreadCrumbProvider(CDoc *inDoc)
+ : m_Doc(inDoc)
+{
+}
+
+//=============================================================================
+/**
+ */
+CTimelineBreadCrumbProvider::~CTimelineBreadCrumbProvider()
+{
+}
+
+//=============================================================================
+/**
+ * determine the color and text string for this breadcrumb
+ */
+static inline void FillBreadCrumb(SBreadCrumb &outBreadCrumb,
+ qt3dsdm::Qt3DSDMInstanceHandle inInstance, CDoc *inDoc)
+{
+ // Get the MasterSlide Handle associated with inAsset
+ CClientDataModelBridge *theBridge = inDoc->GetStudioSystem()->GetClientDataModelBridge();
+ ISlideSystem *theSlideSystem = inDoc->GetStudioSystem()->GetSlideSystem();
+ Q3DStudio::CId theId = theBridge->GetGUID(inInstance);
+ qt3dsdm::Qt3DSDMSlideHandle theMasterSlide =
+ theSlideSystem->GetMasterSlideByComponentGuid(GuidtoSLong4(theId));
+ Q_ASSERT(theMasterSlide.Valid()); // it should be valid because inAsset should be OBJTYPE_SCENE or
+ // non-library OBJTYPE_COMPONENT
+
+ // Get the active slide index of the master slide. Master Slide always has index 0
+ long theActiveIndex = theSlideSystem->GetActiveSlideIndex(theMasterSlide);
+ bool theIsMaster = (theActiveIndex == 0);
+
+ // Determine the color
+ outBreadCrumb.m_Color =
+ theIsMaster ? CColor(0, 0, 255) : CColor(0, 0, 0); // blue for master, black otherwise
+
+ // Determine the text string
+ outBreadCrumb.m_String = theBridge->GetName(inInstance).toQString();
+ outBreadCrumb.m_String += " (";
+ if (theIsMaster) {
+ outBreadCrumb.m_String += QObject::tr("Master");
+ } else {
+ Qt3DSDMSlideHandle theActiveSlide =
+ theSlideSystem->GetSlideByIndex(theMasterSlide, theActiveIndex);
+ Qt3DSDMInstanceHandle theInstanceHandle = theSlideSystem->GetSlideInstance(theActiveSlide);
+ Q_ASSERT(theInstanceHandle.Valid());
+ outBreadCrumb.m_String += theBridge->GetName(theInstanceHandle).toQString();
+ }
+ outBreadCrumb.m_String += ")";
+}
+
+//=============================================================================
+/**
+ * return the trail of breadcrumb.
+ * This constructs a list of the "time context tree" from Scene down to the current active time
+ * context.
+ * @param inRefresh true to refresh the list, false to get existing.
+ */
+CTimelineBreadCrumbProvider::TTrailList
+CTimelineBreadCrumbProvider::GetTrail(bool inRefresh /*= true */)
+{
+ if (inRefresh)
+ RefreshSlideList();
+
+ TTrailList theList;
+ for (size_t theIndex = 0; theIndex < m_BreadCrumbList.size(); ++theIndex) {
+ SBreadCrumb theBreadCrumb;
+ FillBreadCrumb(theBreadCrumb, m_BreadCrumbList[theIndex], m_Doc);
+ theList.push_back(theBreadCrumb);
+ }
+ return theList;
+}
+
+//=============================================================================
+/**
+ * switch current time context to the one 'represented' by the breadcrumbs.
+ * @param inTrailIndex index into the trail list
+ */
+void CTimelineBreadCrumbProvider::OnBreadCrumbClicked(long inTrailIndex)
+{
+ if (inTrailIndex >= 0 && inTrailIndex < (long)m_BreadCrumbList.size()) {
+ CCmdActivateSlide *theCmd = new CCmdActivateSlide(m_Doc, m_BreadCrumbList[inTrailIndex]);
+ theCmd->SetForceRefresh(false);
+ m_Doc->GetCore()->ExecuteCommand(theCmd, false);
+ }
+}
+
+QPixmap CTimelineBreadCrumbProvider::GetRootImage() const
+{
+ return CResourceCache::GetInstance()->GetBitmap("breadcrumb_component_scene.png");
+}
+
+QPixmap CTimelineBreadCrumbProvider::GetBreadCrumbImage() const
+{
+ return CResourceCache::GetInstance()->GetBitmap("breadcrumb_component_button.png");
+}
+
+QPixmap CTimelineBreadCrumbProvider::GetSeparatorImage() const
+{
+ return CResourceCache::GetInstance()->GetBitmap("breadcrumb_component_colon_button.png");
+}
+
+QPixmap CTimelineBreadCrumbProvider::GetActiveBreadCrumbImage() const
+{
+ return CResourceCache::GetInstance()->GetBitmap("breadcrumb_component_grey_button.png");
+}
+
+//=============================================================================
+/**
+ * Called when active time context is changed.
+ */
+void CTimelineBreadCrumbProvider::RefreshSlideList()
+{
+ ClearSlideList();
+
+ qt3dsdm::Qt3DSDMInstanceHandle theActiveRoot = m_Doc->GetActiveRootInstance();
+ if (!theActiveRoot.Valid())
+ return;
+ FillSlideList(theActiveRoot);
+}
+
+//=============================================================================
+/**
+ * Callback that inAsset has its name changed, fire off a signal to the UI control.
+ * All the assets' signals are connected to this object and we'll let the UI control check iterate
+ * through the list for changes and refresh.
+ * Alternative we can set up additional classes that listens to specific assets and only the asset
+ * affected refreshed. the former is easier for now.
+ */
+void CTimelineBreadCrumbProvider::OnNameDirty()
+{
+ Q_EMIT SigBreadCrumbUpdate();
+}
+
+void CTimelineBreadCrumbProvider::ClearSlideList()
+{
+ m_Connections.clear();
+ m_BreadCrumbList.clear();
+}
+
+//=============================================================================
+/**
+ * This will recurse up the time context tree, so that we can fill the list in a top-down (i.e
+ * Scene) first manner
+ */
+void CTimelineBreadCrumbProvider::FillSlideList(qt3dsdm::Qt3DSDMInstanceHandle inInstance)
+{
+ if (!inInstance.Valid())
+ return;
+
+ CClientDataModelBridge *theBridge = m_Doc->GetStudioSystem()->GetClientDataModelBridge();
+ ISlideSystem *theSlideSystem = m_Doc->GetStudioSystem()->GetSlideSystem();
+ Q3DStudio::CId theId = theBridge->GetGUID(inInstance);
+
+ // Recurse
+ FillSlideList(theBridge->GetParentComponent(inInstance));
+
+ m_BreadCrumbList.push_back(inInstance);
+
+ Qt3DSDMPropertyHandle theNameProp =
+ m_Doc->GetStudioSystem()->GetClientDataModelBridge()->GetNameProperty();
+ IStudioFullSystemSignalProvider *theEngine =
+ m_Doc->GetStudioSystem()->GetFullSystemSignalProvider();
+ std::function<void(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle)> theSetter(
+ std::bind(&CTimelineBreadCrumbProvider::OnNameDirty, this));
+
+ // Listen to name changes on the Asset
+ m_Connections.push_back(
+ theEngine->ConnectInstancePropertyValue(
+ std::bind(qt3dsdm::MaybackCallbackInstancePropertyValue<std::function<void(
+ Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle)>>,
+ std::placeholders::_1, std::placeholders::_2, inInstance,
+ theNameProp, theSetter)));
+
+ // Listen to name changes on the non-master Slides
+ qt3dsdm::Qt3DSDMSlideHandle theMasterSlide =
+ theSlideSystem->GetMasterSlideByComponentGuid(GuidtoSLong4(theId));
+ long theSlideCount = (long)theSlideSystem->GetSlideCount(theMasterSlide);
+
+ for (long theIndex = 1; theIndex < theSlideCount; ++theIndex) {
+ Qt3DSDMSlideHandle theSlide = theSlideSystem->GetSlideByIndex(theMasterSlide, theIndex);
+ Qt3DSDMInstanceHandle theSlideInstance = theSlideSystem->GetSlideInstance(theSlide);
+ m_Connections.push_back(
+ theEngine->ConnectInstancePropertyValue(
+ std::bind(qt3dsdm::MaybackCallbackInstancePropertyValue<std::function<void(
+ Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle)>>,
+ std::placeholders::_1, std::placeholders::_2, theSlideInstance,
+ theNameProp, theSetter)));
+ }
+}
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/TimelineBreadCrumbProvider.h b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/TimelineBreadCrumbProvider.h
new file mode 100644
index 00000000..acc7be07
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/TimelineBreadCrumbProvider.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef INCLUDED_BREADCRUMBPROVIDER_H
+#define INCLUDED_BREADCRUMBPROVIDER_H 1
+
+#pragma once
+
+#include "IBreadCrumbProvider.h"
+#include "Qt3DSDMSignals.h"
+
+// Link to data model
+class CDoc;
+class CTimelineBreadCrumbProvider;
+
+//=============================================================================
+/**
+ * Bread crumb provider for displaying a trail of time contexts
+ */
+class CTimelineBreadCrumbProvider : public IBreadCrumbProvider
+{
+public:
+ CTimelineBreadCrumbProvider(CDoc *inDoc);
+ virtual ~CTimelineBreadCrumbProvider();
+
+ TTrailList GetTrail(bool inRefresh = true) override;
+ void OnBreadCrumbClicked(long inTrailIndex) override;
+
+ QPixmap GetRootImage() const override;
+ QPixmap GetBreadCrumbImage() const override;
+ QPixmap GetSeparatorImage() const override;
+ QPixmap GetActiveBreadCrumbImage() const override;
+
+ void RefreshSlideList();
+ void OnNameDirty();
+
+protected:
+ void ClearSlideList();
+ void FillSlideList(qt3dsdm::Qt3DSDMInstanceHandle inInstance);
+
+protected:
+ std::vector<qt3dsdm::Qt3DSDMInstanceHandle> m_BreadCrumbList;
+ CDoc *m_Doc;
+ // connections to the DataModel
+ std::vector<std::shared_ptr<qt3dsdm::ISignalConnection>> m_Connections;
+};
+
+#endif // INCLUDED_BREADCRUMBPROVIDER_H
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/TimelineTranslationManager.cpp b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/TimelineTranslationManager.cpp
new file mode 100644
index 00000000..c03867a7
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/TimelineTranslationManager.cpp
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "TimelineTranslationManager.h"
+#include "SlideTimelineItemBinding.h"
+#include "GroupTimelineItemBinding.h"
+#include "BehaviorTimelineItemBinding.h"
+#include "MaterialTimelineItemBinding.h"
+#include "ImageTimelineItemBinding.h"
+#include "PathAnchorPointTimelineItemBinding.h"
+#include "PathTimelineItemBinding.h"
+#include "LayerTimelineItemBinding.h"
+#include "Qt3DSDMStudioSystem.h"
+#include "StudioObjectTypes.h"
+#include "StudioApp.h"
+#include "Core.h"
+#include "Doc.h"
+#include "ClientDataModelBridge.h"
+
+using namespace qt3dsdm;
+
+CTimelineTranslationManager::CTimelineTranslationManager()
+{
+}
+
+CTimelineTranslationManager::~CTimelineTranslationManager()
+{
+ // clean up all bindings
+ Clear();
+}
+
+ITimelineItemBinding *CTimelineTranslationManager::GetOrCreate(Qt3DSDMInstanceHandle inInstance)
+{
+ ITimelineItemBinding *theBinding = GetBinding(inInstance);
+ if (!theBinding) {
+ Qt3DSDMTimelineItemBinding *theReturn = nullptr;
+
+ EStudioObjectType objType = g_StudioApp.GetCore()->GetDoc()->GetStudioSystem()
+ ->GetClientDataModelBridge()->GetObjectType(inInstance);
+
+ if (objType & OBJTYPE_IS_MATERIAL) {
+ theReturn = new CMaterialTimelineItemBinding(this, inInstance);
+ } else if (objType == OBJTYPE_IMAGE) {
+ theReturn = new CImageTimelineItemBinding(this, inInstance);
+ } else if (objType & (OBJTYPE_GROUP | OBJTYPE_COMPONENT)) {
+ theReturn = new CGroupTimelineItemBinding(this, inInstance);
+ } else if (objType == OBJTYPE_BEHAVIOR) {
+ theReturn = new CBehaviorTimelineItemBinding(this, inInstance);
+ } else if (objType == OBJTYPE_SLIDE) {
+ theReturn = new CSlideTimelineItemBinding(this, inInstance);
+ } else if (objType == OBJTYPE_PATHANCHORPOINT) {
+ theReturn = new CPathAnchorPointTimelineItemBinding(this, inInstance);
+ } else if (objType == OBJTYPE_PATH) {
+ theReturn = new CPathTimelineItemBinding(this, inInstance);
+ } else if (objType == OBJTYPE_LAYER) {
+ theReturn = new CLayerTimelineItemBinding(this, inInstance);
+ } else if (objType & (OBJTYPE_MODEL | OBJTYPE_TEXT | OBJTYPE_CAMERA | OBJTYPE_EFFECT
+ | OBJTYPE_LIGHT | OBJTYPE_RENDERPLUGIN | OBJTYPE_ALIAS
+ | OBJTYPE_SUBPATH))
+ theReturn = new Qt3DSDMTimelineItemBinding(this, inInstance);
+ else {
+ // Add support for additional DataModel types here.
+ Q_ASSERT(0);
+ }
+
+ m_InstanceBindingMap.insert({theReturn->GetInstanceHandle(), theReturn});
+ theBinding = theReturn;
+ }
+
+ return theBinding;
+}
+
+/**
+ * Clear all bindings, typically when a presentation is closed.
+ */
+void CTimelineTranslationManager::Clear()
+{
+ // clean up all bindings
+ m_InstanceBindingMap.clear();
+}
+
+/**
+ * @return the Binding object that corresponds to this instance.
+ */
+Qt3DSDMTimelineItemBinding *
+CTimelineTranslationManager::GetBinding(Qt3DSDMInstanceHandle inHandle) const
+{
+ auto it = m_InstanceBindingMap.find(inHandle);
+ if (it != m_InstanceBindingMap.end())
+ return it->second;
+
+ return nullptr;
+}
+
+CDoc *CTimelineTranslationManager::GetDoc() const
+{
+ return dynamic_cast<CDoc *>(g_StudioApp.GetCore()->GetDoc());
+}
+
+CStudioSystem *CTimelineTranslationManager::GetStudioSystem() const
+{
+ return GetDoc()->GetStudioSystem();
+}
+
diff --git a/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/TimelineTranslationManager.h b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/TimelineTranslationManager.h
new file mode 100644
index 00000000..bbb3fa81
--- /dev/null
+++ b/src/Authoring/Qt3DStudio/Palettes/Timeline/Bindings/TimelineTranslationManager.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TIMELINE_TRANSLATIONMANAGER_H
+#define TIMELINE_TRANSLATIONMANAGER_H
+
+#include "Qt3DSDMHandles.h"
+
+class ITimelineItemBinding;
+class Qt3DSDMTimelineItemBinding;
+class CDoc;
+
+namespace qt3dsdm {
+class CStudioSystem;
+}
+
+class CTimelineTranslationManager
+{
+public:
+ CTimelineTranslationManager();
+ ~CTimelineTranslationManager();
+
+ ITimelineItemBinding *GetOrCreate(qt3dsdm::Qt3DSDMInstanceHandle inInstance);
+ void Clear();
+
+ Qt3DSDMTimelineItemBinding *GetBinding(qt3dsdm::Qt3DSDMInstanceHandle inHandle) const;
+
+ qt3dsdm::CStudioSystem *GetStudioSystem() const;
+ CDoc *GetDoc() const;
+
+private:
+ std::map<qt3dsdm::Qt3DSDMInstanceHandle, Qt3DSDMTimelineItemBinding *> m_InstanceBindingMap;
+};
+
+#endif // INCLUDED_TIMELINE_TRANSLATIONMANAGER_H