diff options
Diffstat (limited to 'src/Authoring/Qt3DStudio/Palettes/Timeline')
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 |