summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMahmoud Badri <mahmoud.badri@qt.io>2018-02-27 14:37:41 +0200
committerMahmoud Badri <mahmoud.badri@qt.io>2018-03-19 09:03:27 +0000
commit089ab17e462646dcd9edf785aa6850ad92b3a8e0 (patch)
treea58f0c08022bb2ca1a0dae672ff796dd1a7a62ac
parent6741e0b808aef4992c81df1128b8db0f8113f49f (diff)
Continue timeline work
Split timeline and tree views, implement layer locking, filter rows, start connection to the app data mode. Task-number: QT3DS-1262 Change-Id: I54fb659e5c4f1103b8cf792b04bcaf012779cf1a Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
-rw-r--r--src/Authoring/Client/Code/Core/Commands/CmdDataModelRemoveKeyframe.h14
-rw-r--r--src/Authoring/Client/Code/Core/Doc/IKeyframe.h3
-rw-r--r--src/Authoring/Studio/Palettes/Timeline/Bindings/ITimelineItemBinding.h5
-rw-r--r--src/Authoring/Studio/Palettes/Timeline/Bindings/ITimelineItemProperty.h5
-rw-r--r--src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMAssetTimelineKeyframe.cpp7
-rw-r--r--src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMAssetTimelineKeyframe.h4
-rw-r--r--src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.cpp41
-rw-r--r--src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.h12
-rw-r--r--src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemProperty.cpp15
-rw-r--r--src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemProperty.h10
-rw-r--r--src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineKeyframe.cpp5
-rw-r--r--src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineKeyframe.h3
-rw-r--r--src/Authoring/Studio/Palettes/Timeline/Bindings/TimelineTranslationManager.cpp38
-rw-r--r--src/Authoring/Studio/Palettes/Timeline/Bindings/TimelineTranslationManager.h1
-rw-r--r--src/Authoring/Studio/Palettes/Timeline/TimelineObjectModel.cpp5
-rw-r--r--src/Authoring/Studio/Palettes/Timeline/TimelineView.cpp3
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/Keyframe.h6
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/KeyframeManager.cpp203
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/KeyframeManager.h7
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/RowManager.cpp245
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/RowManager.h26
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/RowMover.cpp21
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/RowTypes.h36
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineConstants.h57
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp284
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.h24
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineSplitter.cpp (renamed from src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineViewGV.cpp)21
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineSplitter.h (renamed from src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineViewGV.h)20
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineWidget.cpp420
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineWidget.h60
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/PlayHead.cpp10
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTimeline.cpp68
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTimeline.h29
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTree.cpp367
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTree.h40
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/Ruler.cpp2
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/Separator.cpp67
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/Separator.h50
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/TimelineItem.h3
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/TimelineToolbar.cpp8
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/TreeHeader.cpp68
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/TreeHeader.h18
-rw-r--r--src/Authoring/Studio/Qt3DStudio.pro4
-rw-r--r--src/Authoring/Studio/style.qss21
44 files changed, 1472 insertions, 884 deletions
diff --git a/src/Authoring/Client/Code/Core/Commands/CmdDataModelRemoveKeyframe.h b/src/Authoring/Client/Code/Core/Commands/CmdDataModelRemoveKeyframe.h
index 3677f4f8..696f1d9e 100644
--- a/src/Authoring/Client/Code/Core/Commands/CmdDataModelRemoveKeyframe.h
+++ b/src/Authoring/Client/Code/Core/Commands/CmdDataModelRemoveKeyframe.h
@@ -42,6 +42,7 @@
#include "Qt3DSDMAnimation.h"
#include "CmdDataModelBase.h"
#include "Qt3DSDMStudioSystem.h"
+#include "Bindings/Qt3DSDMTimelineKeyframe.h"
class CCmdDataModelRemoveKeyframe : public CCmd, public qt3dsdm::CmdDataModel
{
@@ -51,11 +52,12 @@ protected: // Members
public: // Construction
//@param inTime is in secs
- CCmdDataModelRemoveKeyframe(CDoc *inDoc, qt3dsdm::Qt3DSDMKeyframeHandle inKeyframe)
+ CCmdDataModelRemoveKeyframe(CDoc *inDoc, qt3dsdm::Qt3DSDMKeyframeHandle inKeyframe = 0)
: qt3dsdm::CmdDataModel(*inDoc)
, m_Doc(inDoc)
{
- AddKeyframeHandle(inKeyframe);
+ if (inKeyframe)
+ AddKeyframeHandle(inKeyframe);
}
~CCmdDataModelRemoveKeyframe() {}
@@ -64,6 +66,14 @@ public: // Construction
m_Keyframes.push_back(inKeyframe);
}
+ void addKeyframeHandles(Qt3DSDMTimelineKeyframe *binding)
+ {
+ Qt3DSDMTimelineKeyframe::TKeyframeHandleList kfHandles;
+ binding->GetKeyframeHandles(kfHandles);
+ for (auto &&handle : qAsConst(kfHandles))
+ m_Keyframes.push_back(handle);
+ }
+
//======================================================================
// Do/Redo
//======================================================================
diff --git a/src/Authoring/Client/Code/Core/Doc/IKeyframe.h b/src/Authoring/Client/Code/Core/Doc/IKeyframe.h
index 52c21264..0c10644d 100644
--- a/src/Authoring/Client/Code/Core/Doc/IKeyframe.h
+++ b/src/Authoring/Client/Code/Core/Doc/IKeyframe.h
@@ -31,6 +31,8 @@
#pragma once
+struct Keyframe;
+
//==============================================================================
/**
* Abstraction of a animation keyframe.
@@ -51,6 +53,7 @@ public:
*/
virtual void SetTime(const long inNewTime) = 0;
virtual void SetDynamic(bool inIsDynamic) = 0;
+ virtual void setUI(Keyframe *kfUI) = 0;
virtual bool IsDynamic() const = 0;
};
diff --git a/src/Authoring/Studio/Palettes/Timeline/Bindings/ITimelineItemBinding.h b/src/Authoring/Studio/Palettes/Timeline/Bindings/ITimelineItemBinding.h
index bac7136c..9469981d 100644
--- a/src/Authoring/Studio/Palettes/Timeline/Bindings/ITimelineItemBinding.h
+++ b/src/Authoring/Studio/Palettes/Timeline/Bindings/ITimelineItemBinding.h
@@ -37,6 +37,7 @@
#include "SIterator.h"
class CBaseStateRow;
+class RowTree;
class CControlWindowListener;
class ITimelineKeyframesManager;
@@ -83,7 +84,9 @@ public:
virtual ~ITimelineItemBinding() {}
virtual ITimelineItem *GetTimelineItem() = 0;
- virtual CBaseStateRow *GetRow() = 0;
+ virtual CBaseStateRow *GetRow() = 0; // Mahmoud_TODO: remove after timeline is complete
+ virtual RowTree *getRowTree() const = 0; // UI
+ virtual void setRowTree(RowTree *row) = 0;
// Events
virtual void SetSelected(bool multiSelect) = 0;
diff --git a/src/Authoring/Studio/Palettes/Timeline/Bindings/ITimelineItemProperty.h b/src/Authoring/Studio/Palettes/Timeline/Bindings/ITimelineItemProperty.h
index f8ee3fa3..26b00c09 100644
--- a/src/Authoring/Studio/Palettes/Timeline/Bindings/ITimelineItemProperty.h
+++ b/src/Authoring/Studio/Palettes/Timeline/Bindings/ITimelineItemProperty.h
@@ -36,6 +36,7 @@
#include "Qt3DSDMMetaData.h"
#include "Qt3DSString.h"
+class RowTree;
class CPropertyRow;
class IKeyframe;
class ITimelineKeyframesManager;
@@ -62,7 +63,9 @@ public:
virtual void Bind(CPropertyRow *inRow) = 0;
virtual void Release() = 0;
- virtual CPropertyRow *GetRow() = 0;
+ virtual void setRowTree(RowTree *row) = 0;
+ virtual RowTree *getRowTree() const = 0;
+ virtual CPropertyRow *GetRow() = 0; // Mahmoud_TODO: delete after new timeline is done
// Keyframes
virtual ITimelineKeyframesManager *GetKeyframesManager() const = 0;
diff --git a/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMAssetTimelineKeyframe.cpp b/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMAssetTimelineKeyframe.cpp
index 51fd2377..4626545c 100644
--- a/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMAssetTimelineKeyframe.cpp
+++ b/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMAssetTimelineKeyframe.cpp
@@ -45,6 +45,11 @@ Qt3DSDMAssetTimelineKeyframe::~Qt3DSDMAssetTimelineKeyframe()
{
}
+void Qt3DSDMAssetTimelineKeyframe::setUI(Keyframe *kfUI)
+{
+ m_ui = kfUI;
+}
+
bool Qt3DSDMAssetTimelineKeyframe::IsSelected() const
{
return m_Selected;
@@ -77,4 +82,4 @@ bool Qt3DSDMAssetTimelineKeyframe::IsDynamic() const
void Qt3DSDMAssetTimelineKeyframe::SetSelected(bool inSelected)
{
m_Selected = inSelected;
-} \ No newline at end of file
+}
diff --git a/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMAssetTimelineKeyframe.h b/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMAssetTimelineKeyframe.h
index c57837da..fc22302c 100644
--- a/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMAssetTimelineKeyframe.h
+++ b/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMAssetTimelineKeyframe.h
@@ -60,10 +60,14 @@ public:
long GetTime() const override;
void SetTime(const long inNewTime) override;
void SetDynamic(bool inIsDynamic) 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/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.cpp b/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.cpp
index 02ff7c58..eefe295a 100644
--- a/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.cpp
+++ b/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.cpp
@@ -375,11 +375,22 @@ ITimelineItem *Qt3DSDMTimelineItemBinding::GetTimelineItem()
return this;
}
+// Mahmoud_TODO: remove after finishing the new timeline
CBaseStateRow *Qt3DSDMTimelineItemBinding::GetRow()
{
return m_Row;
}
+RowTree *Qt3DSDMTimelineItemBinding::getRowTree() const
+{
+ return m_rowTree;
+}
+
+void Qt3DSDMTimelineItemBinding::setRowTree(RowTree *row)
+{
+ m_rowTree = row;
+}
+
void Qt3DSDMTimelineItemBinding::SetSelected(bool inMultiSelect)
{
if (!inMultiSelect)
@@ -880,12 +891,12 @@ Qt3DSDMTimelineItemBinding::GetOrCreatePropertyBinding(Qt3DSDMPropertyHandle inP
* @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 )
*/
-CPropertyRow *Qt3DSDMTimelineItemBinding::AddPropertyRow(Qt3DSDMPropertyHandle inPropertyHandle,
+void Qt3DSDMTimelineItemBinding::AddPropertyRow(Qt3DSDMPropertyHandle inPropertyHandle,
bool inAppend /*= false */)
{
ITimelineItemProperty *theTimelineProperty = GetPropertyBinding(inPropertyHandle);
if (theTimelineProperty && theTimelineProperty->GetRow()) // if created, bail
- return {};
+ return;
if (!theTimelineProperty)
theTimelineProperty = GetOrCreatePropertyBinding(inPropertyHandle);
@@ -917,21 +928,8 @@ CPropertyRow *Qt3DSDMTimelineItemBinding::AddPropertyRow(Qt3DSDMPropertyHandle i
}
}
- CPropertyRow *propertyRow = nullptr;
- // Create a new property row
- if (m_createUIRow) {
- propertyRow = m_TransMgr->CreateNewPropertyRow(theTimelineProperty, m_Row,
- theNextProperty ? theNextProperty->GetRow() : nullptr);
- } else {
- propertyRow = new CPropertyRow(theTimelineProperty, m_Row);
- m_Row->AddPropertyRow(propertyRow, theNextProperty ? theNextProperty->GetRow() : nullptr);
- theTimelineProperty->Bind(propertyRow);
- }
-
// Update keyframes
AddKeyframes(theTimelineProperty);
-
- return propertyRow;
}
void Qt3DSDMTimelineItemBinding::RemovePropertyRow(Qt3DSDMPropertyHandle inPropertyHandle)
@@ -940,16 +938,8 @@ void Qt3DSDMTimelineItemBinding::RemovePropertyRow(Qt3DSDMPropertyHandle inPrope
if (theIter != m_PropertyBindingMap.end()) {
ITimelineItemProperty *thePropertyBinding = theIter->second;
- bool theUpdateUI = DeleteAssetKeyframesWhereApplicable(thePropertyBinding);
-
- m_TransMgr->RemovePropertyRow(thePropertyBinding);
+ DeleteAssetKeyframesWhereApplicable(thePropertyBinding);
m_PropertyBindingMap.erase(theIter);
-
- // UI must update
- if (m_Row && theUpdateUI) {
- m_Row->ForceEmitChildrenChanged();
- m_Row->setDirty(true);
- }
}
}
@@ -1243,7 +1233,8 @@ void Qt3DSDMTimelineItemBinding::OnAddChild(Qt3DSDMInstanceHandle inInstance)
if (theNextChild != 0)
theNextItem = m_TransMgr->GetOrCreate(theNextChild);
- m_Row->AddChildRow(m_TransMgr->GetOrCreate(inInstance), theNextItem);
+ // Mahmoud_TODO: remove
+// m_Row->AddChildRow(m_TransMgr->GetOrCreate(inInstance), theNextItem);
}
}
diff --git a/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.h b/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.h
index 81e0df0b..9b6a5b84 100644
--- a/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.h
+++ b/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.h
@@ -54,6 +54,7 @@ class CTimelineTranslationManager;
class CBaseStateRow;
class Qt3DSDMTimelineItemProperty;
class CCmdDataModelSetKeyframeTime;
+class RowTree;
namespace qt3dsdm {
class CStudioSystem;
@@ -74,7 +75,8 @@ protected: // Typedef
typedef std::vector<Qt3DSDMAssetTimelineKeyframe> TAssetKeyframeList;
protected:
- CBaseStateRow *m_Row;
+ CBaseStateRow *m_Row; // TODO: remove after finishing the new timeline
+ RowTree *m_rowTree = nullptr;
CTimelineTranslationManager *m_TransMgr;
qt3dsdm::Qt3DSDMInstanceHandle m_DataHandle;
ITimelineItemBinding *m_Parent;
@@ -121,7 +123,9 @@ public:
// ITimelineItemBinding
ITimelineItem *GetTimelineItem() override;
- CBaseStateRow *GetRow() override;
+ CBaseStateRow *GetRow() override; // Mahmoud_TODO: remove after finishing the new timeline
+ RowTree *getRowTree() const override;
+ void setRowTree(RowTree *row) override;
void SetSelected(bool inMultiSelect) override;
void OnCollapsed() override;
void ClearKeySelection() override;
@@ -179,8 +183,8 @@ public:
long inInstanceCount) override;
void RefreshStateRow(bool inRefreshChildren = false);
- virtual CPropertyRow* AddPropertyRow(qt3dsdm::Qt3DSDMPropertyHandle inPropertyHandle,
- bool inAppend = false);
+ virtual void AddPropertyRow(qt3dsdm::Qt3DSDMPropertyHandle inPropertyHandle,
+ bool inAppend = false);
virtual void RemovePropertyRow(qt3dsdm::Qt3DSDMPropertyHandle inPropertyHandle);
virtual void RefreshPropertyKeyframe(qt3dsdm::Qt3DSDMPropertyHandle inPropertyHandle,
qt3dsdm::Qt3DSDMKeyframeHandle,
diff --git a/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemProperty.cpp b/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemProperty.cpp
index eb6f4864..b6e79d5b 100644
--- a/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemProperty.cpp
+++ b/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemProperty.cpp
@@ -143,6 +143,11 @@ void Qt3DSDMTimelineItemProperty::ReleaseKeyframes()
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)
{
@@ -230,6 +235,11 @@ void Qt3DSDMTimelineItemProperty::Bind(CPropertyRow *inRow)
m_Row = inRow;
}
+RowTree *Qt3DSDMTimelineItemProperty::getRowTree() const
+{
+ return m_rowTree;
+}
+
void Qt3DSDMTimelineItemProperty::Release()
{
m_Row = nullptr;
@@ -408,6 +418,11 @@ void Qt3DSDMTimelineItemProperty::SelectKeyframes(bool inSelected, long inTime /
DoSelectKeyframes(inSelected, inTime, false, theParent);
}
+void Qt3DSDMTimelineItemProperty::setRowTree(RowTree *rowTree)
+{
+ m_rowTree = rowTree;
+}
+
CPropertyRow *Qt3DSDMTimelineItemProperty::GetRow()
{
return m_Row;
diff --git a/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemProperty.h b/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemProperty.h
index 29ba585d..9f304167 100644
--- a/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemProperty.h
+++ b/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemProperty.h
@@ -37,6 +37,7 @@
#include "Qt3DSDMTimeline.h"
#include "Qt3DSDMPropertyDefinition.h"
+class RowTree;
class CTimelineTranslationManager;
class CCmdDataModelSetKeyframeValue;
class Qt3DSDMTimelineItemBinding;
@@ -78,9 +79,11 @@ public:
// IKeyframeSelector
void SelectKeyframes(bool inSelected, long inTime = -1) override;
+ void setRowTree(RowTree *rowTree) override;
void Bind(CPropertyRow *inRow) override;
+ RowTree *getRowTree() const override;
void Release() override;
- CPropertyRow *GetRow() override;
+ CPropertyRow *GetRow() override; // Mahmoud_TODO: delete
bool RefreshKeyframe(qt3dsdm::Qt3DSDMKeyframeHandle inKeyframe,
ETimelineKeyframeTransaction inTransaction);
@@ -90,6 +93,8 @@ public:
void RefreshKeyFrames(void);
+ qt3dsdm::Qt3DSDMPropertyHandle getPropertyHandle() const;
+
protected:
void InitializeCachedVariables(qt3dsdm::Qt3DSDMInstanceHandle inInstance);
bool CreateKeyframeIfNonExistent(qt3dsdm::Qt3DSDMKeyframeHandle inKeyframe,
@@ -114,6 +119,9 @@ protected:
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/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineKeyframe.cpp b/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineKeyframe.cpp
index b97261fc..072fe8d9 100644
--- a/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineKeyframe.cpp
+++ b/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineKeyframe.cpp
@@ -131,6 +131,11 @@ void Qt3DSDMTimelineKeyframe::SetDynamic(bool inIsDynamic)
}
}
+void Qt3DSDMTimelineKeyframe::setUI(Keyframe *kfUI)
+{
+ m_ui = kfUI;
+}
+
// Only the first key of a track can be dynamic.
bool Qt3DSDMTimelineKeyframe::IsDynamic() const
{
diff --git a/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineKeyframe.h b/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineKeyframe.h
index ccec6ef0..1d6d410e 100644
--- a/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineKeyframe.h
+++ b/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineKeyframe.h
@@ -40,6 +40,7 @@ class IDoc;
class CDoc;
class CCmdBatch;
class COffsetKeyframesCommandHelper;
+struct Keyframe;
//==============================================================================
/**
@@ -56,6 +57,7 @@ protected:
m_KeyframeHandles; ///< no. corresponds to the channels the animated property has.
CDoc *m_Doc;
bool m_Selected;
+ Keyframe *m_ui;
public:
Qt3DSDMTimelineKeyframe(IDoc *inDoc);
@@ -66,6 +68,7 @@ public:
long GetTime() const override;
void SetTime(const long inNewTime) override;
void SetDynamic(bool inIsDynamic) override;
+ void setUI(Keyframe *kfUI) override;
bool IsDynamic() const override;
void AddKeyframeHandle(qt3dsdm::Qt3DSDMKeyframeHandle inHandle);
diff --git a/src/Authoring/Studio/Palettes/Timeline/Bindings/TimelineTranslationManager.cpp b/src/Authoring/Studio/Palettes/Timeline/Bindings/TimelineTranslationManager.cpp
index bc10a373..c97a046f 100644
--- a/src/Authoring/Studio/Palettes/Timeline/Bindings/TimelineTranslationManager.cpp
+++ b/src/Authoring/Studio/Palettes/Timeline/Bindings/TimelineTranslationManager.cpp
@@ -320,25 +320,6 @@ void CTimelineTranslationManager::OnNewPresentation()
}
//==============================================================================
-/**
- * Selection events on the old data model was triggered via signals on the actual objects.
- * For the new data model, it would be via this OnSelectionChange event.
- */
-void CTimelineTranslationManager::OnSelectionChange(Q3DStudio::SSelectedValue inNewSelectable)
-{
- // Deselect all items
- TInstanceHandleBindingMap::const_iterator theIter = m_InstanceHandleBindingMap.begin();
- for (; theIter != m_InstanceHandleBindingMap.end(); ++theIter) {
- ITimelineItemBinding *theBinding = theIter->second;
- CBaseStateRow *theRow = theBinding->GetRow();
- if (theRow)
- theRow->OnSelected(false);
- }
-
- // Select new
- if (inNewSelectable)
- SetSelected(inNewSelectable, true);
-}
CDoc *CTimelineTranslationManager::GetDoc() const
{
@@ -523,25 +504,6 @@ void CTimelineTranslationManager::ClearBindingsKeyframeSelection()
}
//==============================================================================
-/**
- * Helper function to find the binding that corresponds to inSelectable and set its selection state
- */
-void CTimelineTranslationManager::SetSelected(Q3DStudio::SSelectedValue inSelectable,
- bool inSelected)
-{
- qt3dsdm::TInstanceHandleList theInstances = inSelectable.GetSelectedInstances();
- for (size_t idx = 0, end = theInstances.size(); idx < end; ++idx) {
- Qt3DSDMInstanceHandle theInstance(theInstances[idx]);
- if (GetStudioSystem()->IsInstance(theInstance)) {
- ITimelineItemBinding *theBinding = EnsureLoaded(theInstance);
- if (theBinding) {
- CBaseStateRow *theRow = theBinding->GetRow();
- if (theRow)
- theRow->OnSelected(inSelected);
- }
- }
- }
-}
ITimelineItemBinding *CTimelineTranslationManager::EnsureLoaded(Qt3DSDMInstanceHandle inHandle)
{
diff --git a/src/Authoring/Studio/Palettes/Timeline/Bindings/TimelineTranslationManager.h b/src/Authoring/Studio/Palettes/Timeline/Bindings/TimelineTranslationManager.h
index 14e34f4b..83443c2c 100644
--- a/src/Authoring/Studio/Palettes/Timeline/Bindings/TimelineTranslationManager.h
+++ b/src/Authoring/Studio/Palettes/Timeline/Bindings/TimelineTranslationManager.h
@@ -110,7 +110,6 @@ public:
void ClearKeyframeSelection();
void OnNewPresentation();
- void OnSelectionChange(Q3DStudio::SSelectedValue inNewSelectable);
qt3dsdm::CStudioSystem *GetStudioSystem() const;
diff --git a/src/Authoring/Studio/Palettes/Timeline/TimelineObjectModel.cpp b/src/Authoring/Studio/Palettes/Timeline/TimelineObjectModel.cpp
index 1ff8ee6f..0f908aa9 100644
--- a/src/Authoring/Studio/Palettes/Timeline/TimelineObjectModel.cpp
+++ b/src/Authoring/Studio/Palettes/Timeline/TimelineObjectModel.cpp
@@ -376,8 +376,9 @@ CTimelineRow* TimelineObjectModel::timelineRowForIndex(const QModelIndex &index)
if (auto propertyBinding = binding->GetPropertyBinding(handle))
propertyRow = propertyBinding->GetRow();
- if (propertyRow == nullptr)
- propertyRow = binding->AddPropertyRow(handle);
+ // Mahmoud_TODO: this whole class will be removed
+// if (propertyRow == nullptr)
+// propertyRow = binding->AddPropertyRow(handle);
Q_ASSERT(propertyRow);
diff --git a/src/Authoring/Studio/Palettes/Timeline/TimelineView.cpp b/src/Authoring/Studio/Palettes/Timeline/TimelineView.cpp
index b1821235..25ce1bcd 100644
--- a/src/Authoring/Studio/Palettes/Timeline/TimelineView.cpp
+++ b/src/Authoring/Studio/Palettes/Timeline/TimelineView.cpp
@@ -143,7 +143,6 @@ void TimelineView::OnSelectionChange(Q3DStudio::SSelectedValue inNewSelectable)
m_model->expandTo(QModelIndex(), index);
}
}
- m_translationManager->OnSelectionChange(inNewSelectable);
}
void TimelineView::OnTimeChanged(long inTime)
@@ -269,7 +268,7 @@ void TimelineView::OnActiveSlide(const qt3dsdm::Qt3DSDMSlideHandle &inMaster, in
m_translationManager->Clear();
m_activeSlide = inSlide;
- qDebug() << "OnActiveSlide";
+
auto *theSlideSystem = GetDoc()->GetStudioSystem()->GetSlideSystem();
auto theSlideInstance = theSlideSystem->GetSlideInstance(inSlide);
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/Keyframe.h b/src/Authoring/Studio/Palettes/TimelineGraphicsView/Keyframe.h
index 99ad423e..16751183 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/Keyframe.h
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/Keyframe.h
@@ -29,8 +29,9 @@
#ifndef KEYFRAME_H
#define KEYFRAME_H
+#include "Bindings/Qt3DSDMTimelineKeyframe.h"
+
class RowTimeline;
-enum class PropertyType;
struct Keyframe
{
@@ -45,9 +46,10 @@ struct Keyframe
double time;
double value;
bool selected = false;
- PropertyType propertyType;
+ QString propertyType;
RowTimeline *rowProperty;
RowTimeline *rowMaster;
+ Qt3DSDMTimelineKeyframe *binding;
};
#endif // KEYFRAME_H
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/KeyframeManager.cpp b/src/Authoring/Studio/Palettes/TimelineGraphicsView/KeyframeManager.cpp
index 8912f84b..09ff2f62 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/KeyframeManager.cpp
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/KeyframeManager.cpp
@@ -36,11 +36,29 @@
#include "PlayHead.h"
#include "RowManager.h"
#include "TimelineGraphicsScene.h"
+#include "StudioObjectTypes.h"
+#include "StudioApp.h"
+#include "Core.h"
+#include "Doc.h"
+#include "CmdDataModelRemoveKeyframe.h"
+#include "CmdDataModelInsertKeyframe.h"
+#include "Bindings/ITimelineItemBinding.h"
+#include "Bindings/KeyframesManager.h"
+#include "Bindings/Qt3DSDMTimelineKeyframe.h"
#include <qglobal.h>
#include <QtCore/qhash.h>
#include <QtCore/qdebug.h>
+// Mahmmoud_TODO: This function is copied from old timeline code. It should be removed after the
+// new timeline is done (during cleanup of old timeline)
+// legacy stuff that we have to support for animation tracks in the old data model to work
+inline void PostExecuteCommand(IDoc *inDoc)
+{
+ CDoc *theDoc = dynamic_cast<CDoc *>(inDoc);
+ theDoc->GetCore()->CommitCurrentCommand();
+}
+
KeyframeManager::KeyframeManager(TimelineGraphicsScene *scene) : m_scene(scene)
{
}
@@ -50,10 +68,10 @@ QList<Keyframe *> KeyframeManager::insertKeyframe(RowTimeline *row, double time,
{
QList<Keyframe *> addedKeyframes;
QList<RowTimeline *> propRows;
- if (row->rowTree()->rowType() != RowType::Property) {
+ if (!row->rowTree()->isProperty()) {
const auto childRows = row->rowTree()->childRows();
for (const auto r : childRows) {
- if (r->rowType() == RowType::Property)
+ if (r->isProperty())
propRows.append(r->rowTimeline());
}
} else {
@@ -89,6 +107,8 @@ void KeyframeManager::selectKeyframe(Keyframe *keyframe)
keyframe->rowMaster->putSelectedKeyframesOnTop();
keyframe->rowMaster->updateKeyframes();
+
+ keyframe->binding->SetSelected(true);
}
}
@@ -103,8 +123,10 @@ void KeyframeManager::selectKeyframes(const QList<Keyframe *> &keyframes)
}
}
- for (auto keyframe : qAsConst(m_selectedKeyframes))
+ for (auto keyframe : qAsConst(m_selectedKeyframes)) {
keyframe->selected = true;
+ keyframe->binding->SetSelected(true);
+ }
for (auto row : qAsConst(m_selectedKeyframesMasterRows)) {
row->putSelectedKeyframesOnTop();
@@ -112,6 +134,13 @@ void KeyframeManager::selectKeyframes(const QList<Keyframe *> &keyframes)
}
}
+// update bindings after selected keyframes are moved
+void KeyframeManager::commitMoveSelectedKeyframes()
+{
+ for (auto keyframe : qAsConst(m_selectedKeyframes))
+ keyframe->binding->SetTime(keyframe->time * 1000);
+}
+
void KeyframeManager::selectKeyframesInRect(const QRectF &rect)
{
deselectAllKeyframes();
@@ -122,9 +151,6 @@ void KeyframeManager::selectKeyframesInRect(const QRectF &rect)
m_scene->rowManager()->clampIndex(idx1);
m_scene->rowManager()->clampIndex(idx2);
- // TODO: remove
- qDebug() << "idx1=" << idx1 << ", idx2=" << idx2;
-
RowTimeline *rowTimeline;
for (int i = idx1; i <= idx2; ++i) {
rowTimeline = m_scene->rowManager()->rowTimelineAt(i);
@@ -142,8 +168,10 @@ void KeyframeManager::selectKeyframesInRect(const QRectF &rect)
}
}
- for (auto keyframe : qAsConst(m_selectedKeyframes))
+ for (auto keyframe : qAsConst(m_selectedKeyframes)) {
keyframe->selected = true;
+ keyframe->binding->SetSelected(true);
+ }
for (auto row : qAsConst(m_selectedKeyframesMasterRows)) {
row->putSelectedKeyframesOnTop();
@@ -158,13 +186,17 @@ void KeyframeManager::deselectKeyframe(Keyframe *keyframe)
m_selectedKeyframes.removeAll(keyframe);
keyframe->rowMaster->updateKeyframes();
m_selectedKeyframesMasterRows.removeAll(keyframe->rowMaster);
+
+ keyframe->binding->SetSelected(false);
}
}
void KeyframeManager::deselectAllKeyframes()
{
- for (auto keyframe : qAsConst(m_selectedKeyframes))
+ for (auto keyframe : qAsConst(m_selectedKeyframes)) {
keyframe->selected = false;
+ keyframe->binding->SetSelected(false);
+ }
for (auto row : qAsConst(m_selectedKeyframesMasterRows))
row->updateKeyframes();
@@ -176,7 +208,11 @@ void KeyframeManager::deselectAllKeyframes()
void KeyframeManager::deleteSelectedKeyframes()
{
if (!m_selectedKeyframes.empty()) {
+ CDoc *theDoc = g_StudioApp.GetCore()->GetDoc();
+ CCmdDataModelRemoveKeyframe *cmd = new CCmdDataModelRemoveKeyframe(theDoc);
for (auto keyframe : qAsConst(m_selectedKeyframes)) {
+ cmd->addKeyframeHandles(keyframe->binding);
+
keyframe->rowMaster->removeKeyframe(keyframe);
keyframe->rowProperty->removeKeyframe(keyframe);
@@ -188,6 +224,9 @@ void KeyframeManager::deleteSelectedKeyframes()
m_selectedKeyframes.clear();
m_selectedKeyframesMasterRows.clear();
+
+ g_StudioApp.GetCore()->ExecuteCommand(cmd);
+ PostExecuteCommand(theDoc);
}
}
@@ -236,7 +275,7 @@ void KeyframeManager::pasteKeyframes(RowTimeline *row)
if (row == nullptr)
return;
- if (row->rowTree()->rowType() == RowType::Property)
+ if (row->rowTree()->isProperty())
row = row->parentRow();
if (!m_copiedKeyframes.empty()) {
@@ -262,8 +301,8 @@ void KeyframeManager::pasteKeyframes(RowTimeline *row)
RowTree *propRow;
QList<Keyframe *> addedKeyframes;
for (auto keyframe : filteredKeyframes) {
- propRow = m_scene->rowManager()->getOrCreatePropertyRow(keyframe->propertyType,
- row->rowTree());
+ propRow = m_scene->rowManager()->getOrCreatePropertyRow(row->rowTree(),
+ keyframe->propertyType);
addedKeyframes.append(insertKeyframe(propRow->rowTimeline(), keyframe->time + dt,
keyframe->value, false));
}
@@ -335,83 +374,83 @@ bool KeyframeManager::hasCopiedKeyframes() const
return !m_copiedKeyframes.empty();
}
-const QHash<RowType, QList<PropertyType>> KeyframeManager::SUPPORTED_ROW_PROPS {
- { RowType::Layer, {
- PropertyType::Left,
- PropertyType::Width,
- PropertyType::Top,
- PropertyType::Height,
- PropertyType::AO,
- PropertyType::AODistance,
- PropertyType::AOSoftness,
- PropertyType::AOThreshold,
- PropertyType::AOSamplingRate,
- PropertyType::IBLBrightness,
- PropertyType::IBLHorizonCutoff,
- PropertyType::IBLFOVAngle }
+const QHash<int, QList<QString>> KeyframeManager::SUPPORTED_ROW_PROPS = {
+ { OBJTYPE_LAYER, {
+ "Left",
+ "Width",
+ "Top",
+ "Height",
+ "Ambient Occulusion",
+ "AO Distance",
+ "AO Softness",
+ "AO Threshold",
+ "AO Sampling Rate",
+ "IBL Brightness",
+ "IBL Horizon Cutoff",
+ "IBL FOV Angle" }
},
- { RowType::Camera, {
- PropertyType::Position,
- PropertyType::Rotation,
- PropertyType::Scale,
- PropertyType::Pivot,
- PropertyType::FieldOfView,
- PropertyType::ClippingStart,
- PropertyType::ClippingEnd }
+ { OBJTYPE_CAMERA, {
+ "Position",
+ "Rotation",
+ "Scale",
+ "Pivot",
+ "FieldOfView",
+ "ClippingStart",
+ "ClippingEnd" }
},
- { RowType::Light, {
- PropertyType::Position,
- PropertyType::Rotation,
- PropertyType::Scale,
- PropertyType::Pivot,
- PropertyType::LightColor,
- PropertyType::SpecularColor,
- PropertyType::AmbientColor,
- PropertyType::Brightness,
- PropertyType::ShadowDarkness,
- PropertyType::ShadowSoftness,
- PropertyType::ShadowDepthBias,
- PropertyType::ShadowFarClip,
- PropertyType::ShadowFOV }
+ { OBJTYPE_LIGHT, {
+ "Position",
+ "Rotation",
+ "Scale",
+ "Pivot",
+ "LightColor",
+ "SpecularColor",
+ "AmbientColor",
+ "Brightness",
+ "ShadowDarkness",
+ "ShadowSoftness",
+ "ShadowDepthBias",
+ "ShadowFarClip",
+ "ShadowFOV" }
},
- { RowType::Object, {
- PropertyType::Position,
- PropertyType::Rotation,
- PropertyType::Scale,
- PropertyType::Pivot,
- PropertyType::Opacity,
- PropertyType::EdgeTessellation,
- PropertyType::InnerTessellation }
+ { OBJTYPE_MODEL, {
+ "Position",
+ "Rotation",
+ "Scale",
+ "Pivot",
+ "Opacity",
+ "EdgeTessellation",
+ "InnerTessellation" }
},
- { RowType::Text, {
- PropertyType::Position,
- PropertyType::Rotation,
- PropertyType::Scale,
- PropertyType::Pivot,
- PropertyType::Opacity,
- PropertyType::TextColor,
- PropertyType::Leading,
- PropertyType::Tracking }
+ { OBJTYPE_TEXT, {
+ "Position",
+ "Rotation",
+ "Scale",
+ "Pivot",
+ "Opacity",
+ "TextColor",
+ "Leading",
+ "Tracking" }
},
- { RowType::Alias, {
- PropertyType::Position,
- PropertyType::Rotation,
- PropertyType::Scale,
- PropertyType::Pivot,
- PropertyType::Opacity }
+ { OBJTYPE_ALIAS, {
+ "Position",
+ "Rotation",
+ "Scale",
+ "Pivot",
+ "Opacity" }
},
- { RowType::Group, {
- PropertyType::Position,
- PropertyType::Rotation,
- PropertyType::Scale,
- PropertyType::Pivot,
- PropertyType::Opacity }
+ { OBJTYPE_GROUP, {
+ "Position",
+ "Rotation",
+ "Scale",
+ "Pivot",
+ "Opacity" }
},
- { RowType::Component, {
- PropertyType::Position,
- PropertyType::Rotation,
- PropertyType::Scale,
- PropertyType::Pivot,
- PropertyType::Opacity }
+ { OBJTYPE_COMPONENT, {
+ "Position",
+ "Rotation",
+ "Scale",
+ "Pivot",
+ "Opacity" }
}
};
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/KeyframeManager.h b/src/Authoring/Studio/Palettes/TimelineGraphicsView/KeyframeManager.h
index 251f5f91..dc78f5e1 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/KeyframeManager.h
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/KeyframeManager.h
@@ -30,11 +30,10 @@
#define KEYFRAMEMANAGER_H
#include <QtCore/qlist.h>
+#include <StudioObjectTypes.h>
class RowTimeline;
class TimelineGraphicsScene;
-enum class RowType;
-enum class PropertyType;
struct Keyframe;
QT_FORWARD_DECLARE_CLASS(QGraphicsSceneContextMenuEvent)
@@ -57,6 +56,7 @@ public:
void copySelectedKeyframes();
void pasteKeyframes(RowTimeline *row);
void moveSelectedKeyframes(double dx);
+ void commitMoveSelectedKeyframes();
bool oneMasterRowSelected() const;
bool hasSelectedKeyframes() const;
bool hasCopiedKeyframes() const;
@@ -67,9 +67,8 @@ public:
QList<Keyframe *> m_copiedKeyframes; // for copy, cut, paste
QList<RowTimeline *> m_selectedKeyframesMasterRows;
-
private:
- static const QHash<RowType, QList<PropertyType>> SUPPORTED_ROW_PROPS;
+ static const QHash<int, QList<QString>> SUPPORTED_ROW_PROPS;
QList<Keyframe *> filterKeyframesForRow(RowTimeline *row, const QList<Keyframe *> &keyframes);
};
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowManager.cpp b/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowManager.cpp
index 93227365..5ea10f1f 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowManager.cpp
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowManager.cpp
@@ -30,21 +30,101 @@
#include "RowTree.h"
#include "TimelineGraphicsScene.h"
#include "Ruler.h"
+#include "TreeHeader.h"
#include "KeyframeManager.h"
+#include "Keyframe.h"
+#include "StudioObjectTypes.h"
+#include "Bindings/ITimelineItemBinding.h"
+#include "Bindings/Qt3DSDMTimelineItemBinding.h"
+#include "Bindings/ITimelineTimebar.h"
+#include "Bindings/Qt3DSDMTimelineKeyframe.h"
+#include "StudioApp.h"
+#include "Core.h"
+#include "Doc.h"
#include <QtWidgets/qgraphicslinearlayout.h>
-#include <QtCore/qdebug.h>
RowManager::RowManager(TimelineGraphicsScene *scene, QGraphicsLinearLayout *layoutLabels,
QGraphicsLinearLayout *layoutTimeline)
: m_scene(scene)
- , m_layoutLabels(layoutLabels)
+ , m_layoutTree(layoutLabels)
, m_layoutTimeline(layoutTimeline)
{
}
-RowTree *RowManager::getOrCreatePropertyRow(PropertyType propType, RowTree *masterRow)
+void RowManager::recreateRowsFromBinding(ITimelineItemBinding *rootBinding)
+{
+ removeAllRows();
+ createRowsFromBindingRecursive(rootBinding);
+}
+
+void RowManager::removeAllRows()
+{
+ m_scene->keyframeManager()->deselectAllKeyframes();
+ clearSelection();
+
+ // delete rows
+ RowTree *row_i;
+ for (int i = m_layoutTree->count() - 1; i >= 1; --i) {
+ row_i = static_cast<RowTree *>(m_layoutTree->itemAt(i)->graphicsItem());
+ m_layoutTree->removeAt(i);
+ m_layoutTimeline->removeAt(i);
+ delete row_i; // this will also delete the timeline row
+ }
+}
+
+RowTree *RowManager::createRowFromBinding(ITimelineItemBinding *binding, RowTree *parentRow)
+{
+ RowTree *newRow = createRow(binding->GetTimelineItem()->GetObjectType(), parentRow,
+ binding->GetTimelineItem()->GetName().toQString());
+
+ // connect the new row and its binding
+ binding->setRowTree(newRow);
+ newRow->setBinding(binding);
+
+ // set row start/end time
+ ITimelineTimebar *timebar = binding->GetTimelineItem()->GetTimebar();
+ newRow->rowTimeline()->setStartTime(timebar->GetStartTime() * .001);
+ newRow->rowTimeline()->setEndTime(timebar->GetEndTime() * .001);
+
+ // create property rows
+ for (int i = 0; i < binding->GetPropertyCount(); i++) {
+ ITimelineItemProperty *prop_i = binding->GetProperty(i);
+ RowTree *propRow = getOrCreatePropertyRow(newRow, prop_i->GetName().toQString());
+
+ // connect the property row and its binding
+ prop_i->setRowTree(propRow);
+ propRow->setPropBinding(prop_i);
+
+ // add keyframes
+ for (int j = 0; j < prop_i->GetKeyframeCount(); j++) {
+ Qt3DSDMTimelineKeyframe *kf =
+ static_cast<Qt3DSDMTimelineKeyframe *>(prop_i->GetKeyframeByIndex(j));
+
+ QList<Keyframe *> addedKeyframes =
+ m_scene->keyframeManager()->insertKeyframe(propRow->rowTimeline(),
+ static_cast<double>(kf->GetTime()) * .001, 0, false);
+
+ Keyframe *kfUI = addedKeyframes.at(0);
+ kf->setUI(kfUI);
+ kfUI->binding = kf;
+ }
+ }
+
+ return newRow;
+}
+
+void RowManager::createRowsFromBindingRecursive(ITimelineItemBinding *binding, RowTree *parentRow)
+{
+ RowTree *newRow = createRowFromBinding(binding, parentRow);
+
+ // create child rows recursively
+ for (int i = 0; i < binding->GetChildrenCount(); i++)
+ createRowsFromBindingRecursive(binding->GetChild(i), newRow);
+}
+
+RowTree *RowManager::getOrCreatePropertyRow(RowTree *masterRow, const QString &propType)
{
if (masterRow->hasPropertyChildren()) {
const auto childRows = masterRow->childRows();
@@ -54,50 +134,60 @@ RowTree *RowManager::getOrCreatePropertyRow(PropertyType propType, RowTree *mast
}
}
- return createRow(RowType::Property, masterRow, 0, propType);
+ return createRow(OBJTYPE_UNKNOWN, masterRow, 0, propType);
}
-RowTree *RowManager::createRow(RowType rowType, RowTree *parentRow, const QString &label,
- PropertyType propType)
+RowTree *RowManager::createRow(EStudioObjectType rowType, RowTree *parentRow, const QString &label,
+ const QString &propType)
{
- if (parentRow == nullptr && rowType != RowType::Scene) {
- qWarning() << __FUNCTION__ << "Invalid parent. Row must have a valid parent row."
- " No row added.";
- } else if (parentRow != nullptr && parentRow->rowType() == RowType::Property) {
+ if (parentRow != nullptr && parentRow->isProperty()) {
qWarning() << __FUNCTION__ << "Property row cannot have children. No row added.";
} else {
- RowTree *rowLabel = nullptr;
+ // If the row doesnt have a parent, insert it under the scene (first row is the tree header)
+ if (parentRow == nullptr && rowType != OBJTYPE_SCENE && m_layoutTree->count() > 1)
+ parentRow = static_cast<RowTree *>(m_layoutTree->itemAt(1));
- if (propType != PropertyType::None)
- rowLabel = new RowTree(m_scene->ruler(), propType);
+ RowTree *rowTree = nullptr;
+
+ if (!propType.isEmpty()) // property row
+ rowTree = new RowTree(m_scene, propType);
else
- rowLabel = new RowTree(m_scene->ruler(), rowType, label);
+ rowTree = new RowTree(m_scene, rowType, label);
if (parentRow != nullptr)
- parentRow->addChild(rowLabel);
-
- rowLabel->rowTimeline()->setStartTime(0);
- rowLabel->rowTimeline()->setEndTime(qMin(10.0, m_scene->ruler()->duration()));
+ parentRow->addChild(rowTree);
- int index = getRowIndex(parentRow) + 1;
- if (index == 0)
+ int index = getLastChildIndex(parentRow) + 1;
+ if (index < 1)
index = 1;
- m_layoutLabels->insertItem(index, rowLabel);
- m_layoutTimeline->insertItem(index, rowLabel->rowTimeline());
+ m_layoutTree->insertItem(index, rowTree);
+ m_layoutTimeline->insertItem(index, rowTree->rowTimeline());
- return rowLabel;
+ return rowTree;
}
return nullptr;
}
+void RowManager::reorderPropertiesFromBinding(Qt3DSDMTimelineItemBinding *binding)
+{
+ int index = getRowIndex(binding->getRowTree()) + 1;
+ if (index > 1) {
+ for (int i = binding->GetPropertyCount() - 1; i >= 0; i--) {
+ RowTree *rowToMove = binding->GetProperty(i)->getRowTree();
+ m_layoutTree->insertItem(index, rowToMove);
+ m_layoutTimeline->insertItem(index, rowToMove->rowTimeline());
+ }
+ }
+}
+
RowTree *RowManager::getRowAbove(RowTree *row)
{
int rowIndex = getRowIndex(row);
if (rowIndex > 1) {
- RowTree *rowAbove = static_cast<RowTree *>(m_layoutLabels->itemAt(rowIndex - 1));
+ RowTree *rowAbove = static_cast<RowTree *>(m_layoutTree->itemAt(rowIndex - 1));
if (rowAbove != nullptr) {
while (rowAbove != nullptr && rowAbove->depth() > row->depth())
@@ -115,7 +205,7 @@ RowTree *RowManager::rowAt(int idx)
correctIndex(idx);
if (idx != -1)
- return static_cast<RowTree *>(m_layoutTimeline->itemAt(idx)->graphicsItem());
+ return static_cast<RowTree *>(m_layoutTree->itemAt(idx)->graphicsItem());
return nullptr;
}
@@ -132,18 +222,64 @@ RowTimeline *RowManager::rowTimelineAt(int idx)
void RowManager::selectRow(RowTree *row)
{
- if (row != nullptr && row != m_selectedRow && row->rowType() != RowType::Property) {
- if (m_selectedRow != nullptr)
- m_selectedRow->setState(InteractiveTimelineItem::Normal);
-
+ if (row != nullptr && row != m_selectedRow && !row->isProperty()) {
+ clearSelection();
row->setState(InteractiveTimelineItem::Selected);
m_selectedRow = row;
+
+ Qt3DSDMTimelineItemBinding *binding =
+ static_cast<Qt3DSDMTimelineItemBinding *>(row->getBinding());
+ g_StudioApp.GetCore()->GetDoc()->SelectDataModelObject(binding->GetInstance());
}
}
+void RowManager::clearSelection()
+{
+ if (m_selectedRow != nullptr) {
+ m_selectedRow->setState(InteractiveTimelineItem::Normal);
+ m_selectedRow = nullptr;
+ }
+}
+
+void RowManager::updateFiltering(RowTree *row)
+{
+ if (row == nullptr) { // update all rows
+ RowTree *row_i;
+ for (int i = 1; i < m_layoutTree->count(); ++i) {
+ row_i = static_cast<RowTree *>(m_layoutTree->itemAt(i)->graphicsItem());
+ updateRowFilter(row_i);
+ }
+ } else {
+ updateRowFilterRecursive(row);
+ }
+}
+
+void RowManager::updateRowFilterRecursive(RowTree *row)
+{
+ updateRowFilter(row);
+
+ if (!row->empty()) {
+ const auto childRows = row->childRows();
+ for (auto child : childRows)
+ updateRowFilterRecursive(child);
+ }
+}
+
+void RowManager::updateRowFilter(RowTree *row)
+{
+ bool parentOk = row->parentRow() == nullptr || (row->parentRow()->expanded()
+ && row->parentRow()->isVisible());
+ bool shyOk = !row->shy() || !m_scene->treeHeader()->filterShy();
+ bool visibleOk = row->visible() || !m_scene->treeHeader()->filterHidden();
+ bool lockOk = !row->locked() || !m_scene->treeHeader()->filterLocked();
+
+ row->setVisible(parentOk && shyOk && visibleOk && lockOk);
+ row->rowTimeline()->setVisible(row->isVisible());
+}
+
void RowManager::deleteRow(RowTree *row)
{
- if (row != nullptr && row->rowType() != RowType::Scene) {
+ if (row != nullptr && row->rowType() != OBJTYPE_SCENE) {
if (m_selectedRow == row)
selectRow(getRowAbove(row));
@@ -154,7 +290,8 @@ void RowManager::deleteRow(RowTree *row)
void RowManager::deleteRowRecursive(RowTree *row)
{
if (!row->childRows().empty()) {
- for (auto child : row->childRows())
+ const auto childRows = row->childRows();
+ for (auto child : childRows)
deleteRowRecursive(child);
}
@@ -167,8 +304,7 @@ void RowManager::deleteRowRecursive(RowTree *row)
m_scene->keyframeManager()->deleteKeyframes(row->rowTimeline());
m_layoutTimeline->removeItem(row->rowTimeline());
- m_layoutLabels->removeItem(row);
- delete row->rowTimeline();
+ m_layoutTree->removeItem(row);
delete row;
}
@@ -180,8 +316,8 @@ RowTree *RowManager::selectedRow() const
int RowManager::getRowIndex(RowTree *row)
{
if (row != nullptr) {
- for (int i = 1; i < m_layoutLabels->count(); ++i) {
- if (row == m_layoutLabels->itemAt(i)->graphicsItem())
+ for (int i = 1; i < m_layoutTree->count(); ++i) {
+ if (row == m_layoutTree->itemAt(i)->graphicsItem())
return i;
}
}
@@ -189,18 +325,49 @@ int RowManager::getRowIndex(RowTree *row)
return -1;
}
+bool RowManager::hasProperties(RowTree *row)
+{
+ if (row != nullptr && !row->empty()) {
+ int index = getRowIndex(row);
+ if (index != -1 && index < m_layoutTree->count() - 1) {
+ RowTree *nextRow = static_cast<RowTree *>(m_layoutTree->itemAt(index + 1)
+ ->graphicsItem());
+ return nextRow->isProperty();
+ }
+ }
+
+ return false;
+}
+
+int RowManager::getLastChildIndex(RowTree *row)
+{
+ int index = getRowIndex(row);
+ if (index != -1) {
+ for (int i = index + 1; i < m_layoutTree->count(); ++i) {
+ if (static_cast<RowTree *>(m_layoutTree->itemAt(i)->graphicsItem())->depth()
+ <= row->depth()) {
+ return i - 1;
+ }
+ }
+
+ return m_layoutTree->count() - 1; // last row
+ }
+
+ return -1;
+}
+
void RowManager::clampIndex(int &idx)
{
if (idx < 1)
idx = 1;
- else if (idx > m_layoutLabels->count() - 1)
- idx = m_layoutLabels->count() - 1;
+ else if (idx > m_layoutTree->count() - 1)
+ idx = m_layoutTree->count() - 1;
}
// Index within rows indices bounds
bool RowManager::validIndex(int idx) const
{
- return idx > 0 && idx < m_layoutLabels->count();
+ return idx > 0 && idx < m_layoutTree->count();
}
// Adjust index to point to the correct row taking into consideration collaped rows
@@ -211,7 +378,7 @@ void RowManager::correctIndex(int &idx)
return;
}
- // adjust for collapsed items (invisible)
+ // adjust for collapsed and filtered items (invisible)
for (int i = 1; i <= idx; ++i) {
if (!m_layoutTimeline->itemAt(i)->graphicsItem()->isVisible()) {
if (++idx > m_layoutTimeline->count() - 1) {
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowManager.h b/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowManager.h
index 929a8ecf..534a36b9 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowManager.h
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowManager.h
@@ -31,10 +31,13 @@
#include "RowTypes.h"
#include <QtCore/qstring.h>
+#include <StudioObjectTypes.h>
class TimelineGraphicsScene;
class RowTree;
class RowTimeline;
+class ITimelineItemBinding;
+class Qt3DSDMTimelineItemBinding;
QT_FORWARD_DECLARE_CLASS(QGraphicsLinearLayout)
@@ -44,27 +47,38 @@ public:
RowManager(TimelineGraphicsScene *scene, QGraphicsLinearLayout *layoutLabels,
QGraphicsLinearLayout *layoutTimeline);
+ void recreateRowsFromBinding(ITimelineItemBinding *rootBinding);
void clampIndex(int &idx);
void correctIndex(int &idx);
void selectRow(RowTree *row);
void deleteRow(RowTree *row);
- RowTree *getOrCreatePropertyRow(PropertyType propType, RowTree *masterRow);
- RowTree *createRow(RowType rowType, RowTree *parentRow = nullptr, const QString &label = {},
- PropertyType propType = PropertyType::None);
+ void clearSelection();
+ void updateFiltering(RowTree *rowTree = nullptr);
+ void reorderPropertiesFromBinding(Qt3DSDMTimelineItemBinding *binding);
+ bool hasProperties(RowTree *row);
+ RowTree *createRowFromBinding(ITimelineItemBinding *binding, RowTree *parentRow = nullptr);
+ RowTree *getOrCreatePropertyRow(RowTree *masterRow, const QString &propType);
+ RowTree *createRow(EStudioObjectType rowType, RowTree *parentRow = nullptr,
+ const QString &label = QString(), const QString &propType = QString());
RowTree *rowAt(int idx);
RowTree *getRowAbove(RowTree *row);
- RowTimeline *rowTimelineAt(int idx);
-
RowTree *selectedRow() const;
+ RowTimeline *rowTimelineAt(int idx);
private:
int getRowIndex(RowTree *row);
+ int getLastChildIndex(RowTree *row);
bool validIndex(int idx) const;
void deleteRowRecursive(RowTree *row);
+ void updateRowFilter(RowTree *row);
+ void updateRowFilterRecursive(RowTree *row);
+ void createRowsFromBindingRecursive(ITimelineItemBinding *binding,
+ RowTree *parentRow = nullptr);
+ void removeAllRows();
RowTree *m_selectedRow = nullptr;
TimelineGraphicsScene *m_scene;
- QGraphicsLinearLayout *m_layoutLabels;
+ QGraphicsLinearLayout *m_layoutTree;
QGraphicsLinearLayout *m_layoutTimeline;
};
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowMover.cpp b/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowMover.cpp
index ed447bb7..44a521dd 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowMover.cpp
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowMover.cpp
@@ -37,14 +37,20 @@
RowMover::RowMover() : QGraphicsRectItem()
{
setZValue(99);
- setRect(0, -2, 20, 2);
+ setRect(0, -5, TimelineConstants::TREE_MAX_W, 10);
}
void RowMover::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
+ painter->save();
+
+ painter->setPen(QPen(QColor(TimelineConstants::ROW_MOVER_COLOR), 1));
+ painter->drawLine(0, -1, TimelineConstants::TREE_BOUND_W, -1);
+
painter->setPen(QPen(QColor(TimelineConstants::ROW_MOVER_COLOR), 4));
- painter->drawLine(0, -.5, 10, -.5);
- painter->fillRect(0, -2.5, rect().width() - x(), 2, QColor(TimelineConstants::ROW_MOVER_COLOR));
+ painter->drawLine(0, -2, 5, -2);
+
+ painter->restore();
}
RowTree *RowMover::insertionParent() const
@@ -123,7 +129,7 @@ void RowMover::updateState(int index, int depth, int rawIndex)
{
m_targetIndex = index;
- setPos(20 + depth * 15, (rawIndex + 1) * TimelineConstants::ROW_H);
+ setPos(25 + depth * 15, (rawIndex + 1) * TimelineConstants::ROW_H);
setVisible(true);
}
@@ -135,10 +141,9 @@ bool RowMover::isValidMove(int index, RowTree *rowAtIndex)
//index != m_currentIndex &&
// not moving an ancestor into a decendent
- !rowAtIndex->isDecendentOf(m_sourceRow) &&
+ !rowAtIndex->isDecendentOf(m_sourceRow)
// not at the top of an expanded object with property children
- (rowAtIndex->childRows().empty()
- || rowAtIndex->childRows().first()->rowType() != RowType::Property
- || !rowAtIndex->expanded());
+ && (rowAtIndex->childRows().empty() || !rowAtIndex->childRows().first()->isProperty()
+ || !rowAtIndex->expanded());
}
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowTypes.h b/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowTypes.h
index f666c3c2..36f59fc8 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowTypes.h
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowTypes.h
@@ -31,23 +31,9 @@
#include <qglobal.h>
-//namespace timeline {
-
-enum class RowType {
- Scene = 90,
- Layer,
- Camera,
- Light,
- Object,
- Text,
- Alias,
- Group,
- Component,
- Property
-};
-
+// Mahmoud_TODO: to be removed
enum class PropertyType {
- None = 540,
+ None = 200,
Position,
Rotation,
Scale,
@@ -85,8 +71,20 @@ enum class PropertyType {
ProbeCrossfade, // Layer
};
-inline uint qHash(RowType key) {
- return static_cast<uint>(key);
-}
+enum class TimelineControlType {
+ None = 300,
+ KeyFrame,
+ Duration,
+ StartHandle,
+ EndHandle
+};
+
+enum class TreeControlType {
+ None = 400,
+ Arrow,
+ Shy,
+ Hide,
+ Lock
+};
#endif // ROWTYPES_H
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineConstants.h b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineConstants.h
index 22494a5a..5d034ba5 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineConstants.h
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineConstants.h
@@ -34,36 +34,39 @@ namespace TimelineConstants
// Dimensions
const int ROW_H = 20;
const int ROW_SPACING = 2;
- const int RULER_SEC_W = 30; // width of 1 second section (at scale 1)
- const int RULER_SEC_DIV = 10; // second divisions
- const int RULER_DIV_H1 = 5; // height of main divisions
- const int RULER_DIV_H2 = 2; // height of secondary divisions
- const int RULER_BASE_Y = 18; // baseline Y
- const int RULER_EDGE_OFFSET = 15;
- const double LABELS_MIN_W = 160;
- const double LABELS_MAX_W = 600;
- const int LABELS_DEFAULT_W = 250;
- const int SEPARATOR_W = 8;
+ const int RULER_SEC_W = 30; // width of 1 second section (at scale 1)
+ const int RULER_SEC_DIV = 10; // second divisions
+ const int RULER_DIV_H1 = 5; // height of main divisions
+ const int RULER_DIV_H2 = 2; // height of secondary divisions
+ const int RULER_BASE_Y = 18; // baseline Y
+ const double RULER_EDGE_OFFSET = 15;
+ const double TREE_MIN_W = 160;
+ const double TREE_MAX_W = 600;
+ const double TREE_DEFAULT_W = 250;
+ const double TREE_BOUND_W = 10000; // real width of the row (> max possible visible tree area)
+ const int SPLITTER_W = 8;
const int PLAYHEAD_W = 14;
- const int DURATION_HANDLE_W = 14; // width of duration end handles in a timeline row
+ const int DURATION_HANDLE_W = 14; // width of duration end handles in a timeline row
// Colors
- const char ROW_COLOR_NORMAL[] = "#404040";
- const char ROW_COLOR_NORMAL_PROP[] = "#373737";
- const char ROW_COLOR_OVER[] = "#4d4d4d";
- const char ROW_COLOR_SELECTED[] = "#336699";
- const char ROW_COLOR_DURATION[] = "#66CCFF";
- const char ROW_COLOR_DURATION_OFF1[] = "#3388B3";
- const char ROW_COLOR_DURATION_OFF2[] = "#222222";
- const char ROW_COLOR_DURATION_EDGE[] = "#000000";
- const char ROW_COLOR_DURATION_SELECTED[] = "#4D99CC";
- const char ROW_COLOR_MOVE_SRC[] = "#464600";
- const char ROW_TEXT_COLOR[] = "#bbbbbb";
- const char PLAYHEAD_COLOR[] = "#ff0066";
- const char RULER_COLOR[] = "#666666";
- const char ROW_MOVER_COLOR[] = "#ffff00";
- const char WIDGET_BG_COLOR[] = "#222222";
- const char PLAYHEAD_LINE_COLOR[] = "#b20808";
+ const char ROW_COLOR_NORMAL[] = "#404040";
+ const char ROW_COLOR_NORMAL_PROP[] = "#373737";
+ const char ROW_COLOR_OVER[] = "#4d4d4d";
+ const char ROW_COLOR_SELECTED[] = "#336699";
+ const char ROW_COLOR_DURATION[] = "#66CCFF";
+ const char ROW_COLOR_DURATION_OFF1[] = "#3388B3"; // duration off ancestors' bounds color1
+ const char ROW_COLOR_DURATION_OFF2[] = "#222222"; // duration off ancestors' bounds color2
+ const char ROW_COLOR_DURATION_EDGE[] = "#000000"; // duration left and right edge lines
+ const char ROW_COLOR_DURATION_SELECTED[] = "#4D99CC";
+ const char ROW_COLOR_MOVE_SRC[] = "#464600";
+ const char ROW_TEXT_COLOR[] = "#bbbbbb";
+ const char ROW_TEXT_COLOR_DISABLED[] = "#888888";
+ const char PLAYHEAD_COLOR[] = "#ff0066";
+ const char RULER_COLOR[] = "#666666";
+ const char ROW_MOVER_COLOR[] = "#ffff00";
+ const char WIDGET_BG_COLOR[] = "#222222";
+ const char PLAYHEAD_LINE_COLOR[] = "#b20808";
+ const char FILTER_BUTTON_SELECTED_COLOR[] = "#000000";
// TODO: move the colors (and maybe dimensions) to StudioPreferences.
}
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp
index 05b7c840..2e30e0eb 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp
@@ -30,18 +30,20 @@
#include "TimelineItem.h"
#include "TreeHeader.h"
#include "Ruler.h"
-#include "Separator.h"
#include "PlayHead.h"
#include "RowTree.h"
#include "RowMover.h"
#include "RowTimeline.h"
-#include "Separator.h"
#include "TimelineConstants.h"
#include "TimelineToolbar.h"
#include "SelectionRect.h"
#include "RowManager.h"
#include "KeyframeManager.h"
#include "Keyframe.h"
+#include "StudioApp.h"
+#include "Core.h"
+#include "Doc.h"
+#include "Bindings/Qt3DSDMTimelineItemBinding.h"
#include <QtWidgets/qcombobox.h>
#include <QtWidgets/qgraphicssceneevent.h>
@@ -50,106 +52,62 @@
#include <QtWidgets/qgraphicsview.h>
#include <QtWidgets/qscrollbar.h>
#include <QtWidgets/qmenu.h>
+#include <QtWidgets/qaction.h>
#include <QtGui/qevent.h>
#include <QtCore/qtimer.h>
#include <QtCore/qglobal.h>
#include <QtCore/qdebug.h>
#include <QtWidgets/qaction.h>
-TimelineGraphicsScene::TimelineGraphicsScene(QGraphicsView *viewTimelineContent,
- TimelineWidget *parent)
- : QGraphicsScene (parent)
+TimelineGraphicsScene::TimelineGraphicsScene(TimelineWidget *timelineWidget)
+ : QGraphicsScene(timelineWidget)
, m_layoutRoot(new QGraphicsLinearLayout)
- , m_layoutLabels(new QGraphicsLinearLayout(Qt::Vertical))
+ , m_layoutTree(new QGraphicsLinearLayout(Qt::Vertical))
, m_layoutTimeline(new QGraphicsLinearLayout(Qt::Vertical))
- , m_separator(new Separator)
, m_ruler(new Ruler)
, m_playHead(new PlayHead(m_ruler))
, m_selectionRect(new SelectionRect(m_ruler))
, m_rowMover(new RowMover)
- , m_widget(parent)
- , m_viewTimelineContent(viewTimelineContent)
+ , m_widgetTimeline(timelineWidget)
, m_widgetRoot(new QGraphicsWidget)
- , m_rowManager(new RowManager(this, m_layoutLabels, m_layoutTimeline))
+ , m_rowManager(new RowManager(this, m_layoutTree, m_layoutTimeline))
, m_keyframeManager(new KeyframeManager(this))
{
addItem(m_playHead);
addItem(m_selectionRect);
addItem(m_rowMover);
+ addItem(m_widgetRoot);
m_rowMover->setVisible(false);
- m_rowMover->setRect(0, 0, TimelineConstants::LABELS_MIN_W, TimelineConstants::ROW_H-1);
-
- // TODO: remove
-// m_widgetRoot->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding);
- addItem(m_widgetRoot);
m_layoutRoot->setSpacing(0);
m_layoutRoot->setContentsMargins(0, 0, 0, 0);
m_layoutRoot->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
m_widgetRoot->setLayout(m_layoutRoot);
- m_layoutLabels->setSpacing(0);
- m_layoutLabels->setContentsMargins(0, 0, 0, 0);
- m_layoutLabels->setMinimumWidth(TimelineConstants::LABELS_DEFAULT_W);
- m_layoutLabels->setMaximumWidth(TimelineConstants::LABELS_DEFAULT_W);
- m_layoutLabels->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
+ m_layoutTree->setSpacing(0);
+ m_layoutTree->setContentsMargins(0, 0, 0, 0);
+ m_layoutTree->setMinimumWidth(TimelineConstants::TREE_BOUND_W);
+ m_layoutTree->setMaximumWidth(TimelineConstants::TREE_BOUND_W);
+ m_layoutTree->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
setTimelineScale(m_ruler->timelineScale()); // refresh timeline width
m_layoutTimeline->setSpacing(0);
m_layoutTimeline->setContentsMargins(0, 0, 0, 0);
m_layoutTimeline->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
- m_layoutRoot->addItem(m_layoutLabels);
- m_layoutRoot->addItem(m_separator);
+ m_layoutRoot->addItem(m_layoutTree);
m_layoutRoot->addItem(m_layoutTimeline);
- m_layoutLabels->addItem(new TreeHeader);
+ m_treeHeader = new TreeHeader;
+
+ m_layoutTree->addItem(m_treeHeader);
m_layoutTimeline->addItem(m_ruler);
QTimer::singleShot(0, this, [this]() {
m_playHead->setPosition(0);
+ m_widgetTimeline->viewTreeContent()->horizontalScrollBar()->setValue(0);
});
-
- connect(m_ruler, &Ruler::rulerClicked, [this](const double &posX) {
- m_playHead->setPosition(posX);
- m_widget->toolbar()->setTime(m_playHead->time());
- });
-
- m_sceneRow = m_rowManager->createRow(RowType::Scene);
-
-// add some test rows
- // TODO: remove after connecting the view to the app data model
- RowTree *layer1 = m_rowManager->createRow(RowType::Layer, m_sceneRow, tr("layer 1"));
- RowTree *layer2 = m_rowManager->createRow(RowType::Layer, m_sceneRow, tr("layer 2"));
-
- RowTree *obj1 = m_rowManager->createRow(RowType::Object, layer1, tr("Cone"));
- RowTree *group1= m_rowManager->createRow(RowType::Group, layer1, tr("group 1"));
- RowTree *cam = m_rowManager->createRow(RowType::Camera, layer1, tr("cam 1"));
- RowTree *light = m_rowManager->createRow(RowType::Light, layer2);
- RowTree *obj2 = m_rowManager->createRow(RowType::Object, layer1, tr("Cube"));
-
- RowTree *alias = m_rowManager->createRow(RowType::Alias, layer2);
- RowTree *comp = m_rowManager->createRow(RowType::Component, layer2);
- RowTree *group2= m_rowManager->createRow(RowType::Group, comp, tr("group 2"));
- RowTree *obj3 = m_rowManager->createRow(RowType::Object, comp, tr("Sphere"));
- RowTree *cam2 = m_rowManager->createRow(RowType::Camera, group2, tr("cam 2"));
- RowTree *obj4 = m_rowManager->createRow(RowType::Object, group2, tr("Cylinder"));
- RowTree *text = m_rowManager->createRow(RowType::Text, group2);
-
- // properties
- RowTree *prop1 = m_rowManager->getOrCreatePropertyRow(PropertyType::Scale, cam);
- RowTree *prop2 = m_rowManager->getOrCreatePropertyRow(PropertyType::Opacity, obj2);
- RowTree *prop3 = m_rowManager->getOrCreatePropertyRow(PropertyType::Position, obj3);
- RowTree *prop4 = m_rowManager->getOrCreatePropertyRow(PropertyType::Rotation, obj3);
- RowTree *prop5 = m_rowManager->getOrCreatePropertyRow(PropertyType::Rotation, obj3);
-
- // keyframes
- m_keyframeManager->insertKeyframe(prop1->rowTimeline(), 5, 7);
- m_keyframeManager->insertKeyframe(prop1->rowTimeline(), 3, 52);
- m_keyframeManager->insertKeyframe(prop2->rowTimeline(), 12, 34);
- m_keyframeManager->insertKeyframe(prop3->rowTimeline(), 4.5, 6);
- m_keyframeManager->deselectAllKeyframes();
}
void TimelineGraphicsScene::setTimelineScale(int scl)
@@ -157,10 +115,10 @@ void TimelineGraphicsScene::setTimelineScale(int scl)
m_ruler->setTimelineScale(scl);
m_playHead->updatePosition();
- m_layoutTimeline->setMinimumWidth(TimelineConstants::RULER_EDGE_OFFSET * 2
- + m_ruler->duration() * TimelineConstants::RULER_SEC_W * scl);
- m_layoutTimeline->setMaximumWidth(TimelineConstants::RULER_EDGE_OFFSET * 2
- + m_ruler->duration() * TimelineConstants::RULER_SEC_W * scl);
+ double timelineWidth = TimelineConstants::RULER_EDGE_OFFSET * 2
+ + m_ruler->duration() * TimelineConstants::RULER_SEC_W * scl;
+ m_layoutTimeline->setMinimumWidth(timelineWidth);
+ m_layoutTimeline->setMaximumWidth(timelineWidth);
for (int i = 1; i < m_layoutTimeline->count(); i++)
static_cast<RowTimeline *>(m_layoutTimeline->itemAt(i)->graphicsItem())->updatePosition();
@@ -168,12 +126,12 @@ void TimelineGraphicsScene::setTimelineScale(int scl)
void TimelineGraphicsScene::addNewLayer()
{
- RowTree *newLayer = m_rowManager->createRow(RowType::Layer, m_sceneRow);
-
- m_rowManager->selectRow(newLayer);
+ // TODO: get the update from the data model
+// RowTree *newLayer = m_rowManager->createRow(OBJTYPE_LAYER, m_sceneRow);
+// m_rowManager->selectRow(newLayer);
// scroll to top
- m_viewTimelineContent->verticalScrollBar()->setValue(0);
+ m_widgetTimeline->viewTimelineContent()->verticalScrollBar()->setValue(0);
}
// TODO: test function, to be removed
@@ -188,18 +146,7 @@ void debugPrintRows(RowTree *row)
}
void TimelineGraphicsScene::deleteSelectedRow() {
- // TODO: test code, to be removed
-// MainRowLabel *row_i = nullptr;
-// for (int i = 1; i < m_layoutLabels->count(); ++i)
-// {
-// row_i = static_cast<MainRowLabel *>(m_layoutLabels->itemAt(i)->graphicsItem());
-// qDebug().noquote().nospace() << "|" << QString("-").repeated(row_i->depth()) << row_i->label();
-// }
-// qDebug() << "------------------------------";
-
- debugPrintRows(m_sceneRow);
-
-// m_rowManager->deleteRow(m_rowManager->selectedRow());
+ m_rowManager->deleteRow(m_rowManager->selectedRow());
}
void TimelineGraphicsScene::commitMoveRows()
@@ -214,14 +161,15 @@ void TimelineGraphicsScene::commitMoveRows()
return;
}
- // TODO: remove
-// qDebug() << "sourceIndex=" << sourceIndex << ", targetIndex=" << targetIndex << ", rowSrcDepth=" << rowSrcDepth;
+ // TODO: remove
+// qDebug() << "sourceIndex=" << sourceIndex << ", targetIndex=" << targetIndex
+// << ", rowSrcDepth=" << rowSrcDepth;
// gather the rows to be moved
RowTree *row_i = nullptr;
QList<RowTree *> itemsToMove { m_rowMover->sourceRow() };
- for (int i = sourceIndex + 1; i < m_layoutLabels->count();) {
- row_i = static_cast<RowTree *>(m_layoutLabels->itemAt(i)->graphicsItem());
+ for (int i = sourceIndex + 1; i < m_layoutTree->count();) {
+ row_i = static_cast<RowTree *>(m_layoutTree->itemAt(i)->graphicsItem());
// TODO: remove
// qDebug() << "i=" << i << ", row_i->depth()=" << row_i->depth();
@@ -229,7 +177,7 @@ void TimelineGraphicsScene::commitMoveRows()
if (row_i->depth() <= rowSrcDepth)
break;
- m_layoutLabels->removeAt(i);
+ m_layoutTree->removeAt(i);
m_layoutTimeline->removeAt(i);
itemsToMove.append(row_i);
}
@@ -245,7 +193,7 @@ void TimelineGraphicsScene::commitMoveRows()
for (auto child : qAsConst(itemsToMove)) {
++targetIndex;
- m_layoutLabels->insertItem(targetIndex, child);
+ m_layoutTree->insertItem(targetIndex, child);
m_layoutTimeline->insertItem(targetIndex, child->rowTimeline());
}
}
@@ -256,8 +204,8 @@ void TimelineGraphicsScene::getLastChildRow(RowTree *row, int index, RowTree *ou
if (row != nullptr) {
RowTree *row_i = nullptr;
RowTree *row_i_prev = nullptr;
- for (int i = index + 1; i < m_layoutLabels->count() - 1; ++i) {
- row_i = static_cast<RowTree *>(m_layoutLabels->itemAt(i)->graphicsItem());
+ for (int i = index + 1; i < m_layoutTree->count() - 1; ++i) {
+ row_i = static_cast<RowTree *>(m_layoutTree->itemAt(i)->graphicsItem());
if (row_i->depth() <= row->depth()) {
outLastChild = row_i_prev;
@@ -285,31 +233,44 @@ bool TimelineGraphicsScene::lastRowInAParent(RowTree *rowAtIndex, int index)
// not used except in lastRowInAParent()
int TimelineGraphicsScene::nextRowDepth(int index) {
- if (index < m_layoutLabels->count() - 1)
+ if (index < m_layoutTree->count() - 1)
index ++;
- return static_cast<RowTree *>(m_layoutLabels->itemAt(index)->graphicsItem())->depth();
+ return static_cast<RowTree *>(m_layoutTree->itemAt(index)->graphicsItem())->depth();
}
bool TimelineGraphicsScene::validLayerMove(RowTree *rowAtIndex, RowTree *nextRowAtIndex)
{
// we don't care about non-layers in this method
- if (m_rowMover->sourceRow()->rowType() != RowType::Layer)
+ if (m_rowMover->sourceRow()->rowType() != OBJTYPE_LAYER)
return true;
- if (rowAtIndex->rowType() == RowType::Scene)
+ if (rowAtIndex->rowType() == OBJTYPE_SCENE)
return true;
- if (rowAtIndex->rowType() == RowType::Layer)
+ if (rowAtIndex->rowType() == OBJTYPE_LAYER)
return rowAtIndex->empty() || !rowAtIndex->expanded();
if (nextRowAtIndex == nullptr || (nextRowAtIndex->depth() <= rowAtIndex->depth()
- && nextRowAtIndex->depth() == 2))
+ && nextRowAtIndex->depth() == 2))
return true;
return false;
}
+void TimelineGraphicsScene::updateTreeWidth(double treeWidth)
+{
+ m_treeWidth = treeWidth;
+
+ m_treeHeader->setWidth(treeWidth);
+
+ RowTree *row_i;
+ for (int i = 1; i < m_layoutTree->count(); ++i) {
+ row_i = static_cast<RowTree *>(m_layoutTree->itemAt(i)->graphicsItem());
+ row_i->setTreeWidth(treeWidth);
+ }
+}
+
void TimelineGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
@@ -321,23 +282,26 @@ void TimelineGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
if (item->type() == TimelineItem::TypePlayHead)
item = items(m_pressPos).at(1);
- if (item->type() == TimelineItem::TypeSeparator) {
- m_separatorPressed = true;
- } else if (item->type() == TimelineItem::TypeRuler) {
+ if (item->type() == TimelineItem::TypeRuler) {
m_rulerPressed = true;
+ double time = m_ruler->distanceToTime(event->scenePos().x()
+ - m_ruler->durationStartX()) * 1000;
+ g_StudioApp.GetCore()->GetDoc()->NotifyTimeChanged(time);
+ } else if (item->type() == TimelineItem::TypeTreeHeader) {
+ if (m_treeHeader->handleButtonsClick(m_pressPos) != TreeControlType::None)
+ m_rowManager->updateFiltering();
} else if (item->type() == TimelineItem::TypeRowTree) {
- RowTree *rowLabel = static_cast<RowTree *>(item);
-
- if (rowLabel->rowType() != RowType::Property) {
- if (!rowLabel->handleButtonsClick(event)) {
- // dragging layers to reorder
+ RowTree *rowTree = static_cast<RowTree *>(item);
+ if (!rowTree->isProperty()) {
+ m_clickedTreeControlType = rowTree->getClickedControl(m_pressPos);
+ if (m_clickedTreeControlType != TreeControlType::None) {
+ m_rowManager->updateFiltering(rowTree);
+ } else if (!rowTree->locked()) { // dragging layers to reorder
int index = event->scenePos().y() / TimelineConstants::ROW_H;
m_rowManager->correctIndex(index);
- if (rowLabel->rowType() != RowType::Scene
- && rowLabel->rowType() != RowType::Property) {
- m_rowMover->start(rowLabel, index);
- }
+ if (rowTree->rowType() != OBJTYPE_SCENE && !rowTree->isProperty())
+ m_rowMover->start(rowTree, index);
}
}
} else if (item->type() == TimelineItem::TypeRowTimeline) {
@@ -361,12 +325,14 @@ void TimelineGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
m_editedTimelineRow->getClickedControl(m_pressPos);
// clicked an empty spot on a timeline row, start selection rect.
- if (m_editedTimelineRow->getClickedControl(m_pressPos) == RowTimeline::TypeNone)
+ if (m_clickedTimelineControlType == TimelineControlType::None)
m_selectionRect->start(m_pressPos);
}
}
} else {
- if (m_pressPos.x() > m_separator->x() && m_pressPos.y() > TimelineConstants::ROW_H)
+ m_keyframeManager->deselectAllKeyframes();
+
+ if (m_pressPos.x() > m_ruler->x() && m_pressPos.y() > TimelineConstants::ROW_H)
m_selectionRect->start(m_pressPos);
}
}
@@ -381,24 +347,17 @@ void TimelineGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
m_dragging = true;
if (m_rulerPressed) {
- m_playHead->setPosition(event->scenePos().x() - m_ruler->pos().x());
- m_widget->toolbar()->setTime(m_playHead->time());
+ double time = m_ruler->distanceToTime(event->scenePos().x() - m_ruler->durationStartX())
+ * 1000;
+ g_StudioApp.GetCore()->GetDoc()->NotifyTimeChanged(time);
} else if (m_dragging) {
- if (m_separatorPressed) { // resizing labels part
- double x = event->scenePos().x() - m_separator->size().width() * .5;
- x = qBound(TimelineConstants::LABELS_MIN_W, x, TimelineConstants::LABELS_MAX_W);
- m_layoutLabels->setMinimumWidth(x);
- m_layoutLabels->setMaximumWidth(x);
- m_rowMover->setRect(0, -5, x, 10);
-
- m_playHead->updatePosition();
- } else if (m_clickedTimelineControlType == RowTimeline::TypeStartHandle) {
+ if (m_clickedTimelineControlType == TimelineControlType::StartHandle) {
// resizing layer timline duration from left
m_editedTimelineRow->setStartX(event->scenePos().x() - m_ruler->pos().x());
- } else if (m_clickedTimelineControlType == RowTimeline::TypeEndHandle) {
+ } else if (m_clickedTimelineControlType == TimelineControlType::EndHandle) {
// resizing layer timline duration from right
m_editedTimelineRow->setEndX(event->scenePos().x() - m_ruler->pos().x());
- } else if (m_clickedTimelineControlType == RowTimeline::TypeDuration) {
+ } else if (m_clickedTimelineControlType == TimelineControlType::Duration) {
// moving layer timline duration
m_editedTimelineRow->moveDurationBy(event->scenePos().x() - m_pressPos.x());
m_pressPos = event->scenePos();
@@ -418,9 +377,9 @@ void TimelineGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
RowTree *lastChildAtIndex; // so far not used
if (valid) { // valid row index
- rowAtIndex = static_cast<RowTree *>(m_layoutLabels->itemAt(index)->graphicsItem());
- nextRowAtIndex = index > m_layoutLabels->count() - 2 ? nullptr :
- static_cast<RowTree *>(m_layoutLabels->itemAt(index + 1)->graphicsItem());
+ rowAtIndex = static_cast<RowTree *>(m_layoutTree->itemAt(index)->graphicsItem());
+ nextRowAtIndex = index > m_layoutTree->count() - 2 ? nullptr :
+ static_cast<RowTree *>(m_layoutTree->itemAt(index + 1)->graphicsItem());
if (!rowAtIndex->expanded())
getLastChildRow(rowAtIndex, index, lastChildAtIndex, nextRowAtIndex, index);
@@ -429,15 +388,14 @@ void TimelineGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
valid = !rowAtIndex->isDecendentOf(m_rowMover->sourceRow())
// not inserting next to property rows
- && !(nextRowAtIndex != nullptr
- && nextRowAtIndex->rowType() == RowType::Property)
+ && !(nextRowAtIndex != nullptr && nextRowAtIndex->isProperty())
// not inserting as a first child of self
&& !(rowAtIndex == m_rowMover->sourceRow() && !rowAtIndex->empty())
// not inserting non-layer under the scene
- && !(m_rowMover->sourceRow()->rowType() != RowType::Layer
- && rowAtIndex->rowType() == RowType::Scene)
+ && !(m_rowMover->sourceRow()->rowType() != OBJTYPE_LAYER
+ && rowAtIndex->rowType() == OBJTYPE_SCENE)
// Layer cases
&& validLayerMove(rowAtIndex, nextRowAtIndex);
@@ -452,14 +410,14 @@ void TimelineGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
if (rowAtIndex->isContainer() && rowAtIndex->expanded()
&& rowAtIndex != m_rowMover->sourceRow()) {
depth++; // Container: allow insertion as a child
- } else if (rowAtIndex->rowType() == RowType::Property) {
+ } else if (rowAtIndex->isProperty()) {
depth--; // Property: prevent insertion as a sibling
}
depthBasedOnX = qMax(depthBasedOnX, depthNextRow);
depth = qBound(3, depth, depthBasedOnX);
- if (m_rowMover->sourceRow()->rowType() == RowType::Layer)
+ if (m_rowMover->sourceRow()->rowType() == OBJTYPE_LAYER)
depth = 2;
// calc insertion parent
@@ -497,25 +455,33 @@ void TimelineGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
if (event->button() == Qt::LeftButton) {
QGraphicsItem *item = itemAt(event->scenePos(), QTransform());
- if (item != nullptr && !m_dragging && (item->type() == TimelineItem::TypeRowTree
- || item->type() == TimelineItem::TypeRowTimeline)) {
- // select row
+ if (item != nullptr && !m_dragging) {
+ // select pressed row
+ RowTree *rowTree = nullptr;
if (item->type() == TimelineItem::TypeRowTree)
- m_rowManager->selectRow( static_cast<RowTree *>(item) );
+ rowTree = static_cast<RowTree *>(item);
else if (item->type() == TimelineItem::TypeRowTimeline)
- m_rowManager->selectRow( static_cast<RowTimeline *>(item)->rowTree() );
+ rowTree = static_cast<RowTimeline *>(item)->rowTree();
+
+ if (rowTree != nullptr && m_clickedTreeControlType == TreeControlType::None
+ && !rowTree->locked()) {
+ m_rowManager->selectRow(rowTree);
+ }
+
} else if (m_rowMover->isActive()) { // moving rows (reorder/reparent)
if (m_rowMover->insertionParent() != nullptr) // valid row move, commit it
commitMoveRows();
+ } else if (m_keyframePressed) {
+ // update keyframe movement (time) to binding
+ m_keyframeManager->commitMoveSelectedKeyframes();
}
// reset mouse drag params
m_selectionRect->end();
m_rowMover->end();
- m_separatorPressed = false;
m_rulerPressed = false;
m_dragging = false;
- m_clickedTimelineControlType = RowTimeline::TypeNone;
+ m_clickedTimelineControlType = TimelineControlType::None;
m_keyframePressed = false;
m_editedTimelineRow = nullptr;
}
@@ -559,13 +525,15 @@ void TimelineGraphicsScene::contextMenuEvent(QGraphicsSceneContextMenuEvent *eve
QMenu contextMenu;
int index = event->scenePos().y() / TimelineConstants::ROW_H;
+ RowTree *row = m_rowManager->rowAt(index);
- RowTimeline *row = rowManager()->rowTimelineAt(index);
+ if (row == nullptr)
+ return;
- if (row != nullptr) { // timeline context menu
- Keyframe *keyframe = row->getClickedKeyframe(event->scenePos());
- bool propRow = row->rowTree()->rowType() == RowType::Property;
- bool hasPropRows = row->rowTree()->hasPropertyChildren();
+ if (event->scenePos().x() > TimelineConstants::TREE_BOUND_W) { // timeline context menu
+ Keyframe *keyframe = row->rowTimeline()->getClickedKeyframe(event->scenePos());
+ bool propRow = row->isProperty();
+ bool hasPropRows = row->hasPropertyChildren();
bool ctrlPressed = event->modifiers() & Qt::ControlModifier;
//TODO: remove
@@ -601,11 +569,12 @@ void TimelineGraphicsScene::contextMenuEvent(QGraphicsSceneContextMenuEvent *eve
actionCopySelectedKeyframes ->setEnabled(m_keyframeManager->oneMasterRowSelected());
actionPasteKeyframes ->setEnabled(m_keyframeManager->hasCopiedKeyframes());
actionDeleteSelectedKeyframes->setEnabled(m_keyframeManager->hasSelectedKeyframes());
- actionDeleteRowKeyframes ->setEnabled(!row->keyframes().empty());
+ actionDeleteRowKeyframes ->setEnabled(!row->rowTimeline()->keyframes().empty());
// connections
connect(actionInsertKeyframe, &QAction::triggered, this, [=]() {
- m_keyframeManager->insertKeyframe(row, m_playHead->time(), 0);
+ row->getBinding()->InsertKeyframe();
+ m_keyframeManager->insertKeyframe(row->rowTimeline(), m_playHead->time(), 0, false);
});
connect(actionCutSelectedKeyframes, &QAction::triggered, this, [=]() {
@@ -618,7 +587,7 @@ void TimelineGraphicsScene::contextMenuEvent(QGraphicsSceneContextMenuEvent *eve
});
connect(actionPasteKeyframes, &QAction::triggered, this, [=]() {
- m_keyframeManager->pasteKeyframes(row);
+ m_keyframeManager->pasteKeyframes(row->rowTimeline());
});
connect(actionDeleteSelectedKeyframes, &QAction::triggered, this, [=]() {
@@ -626,10 +595,13 @@ void TimelineGraphicsScene::contextMenuEvent(QGraphicsSceneContextMenuEvent *eve
});
connect(actionDeleteRowKeyframes, &QAction::triggered, this, [=]() {
- m_keyframeManager->deleteKeyframes(row);
+ m_keyframeManager->deleteKeyframes(row->rowTimeline());
});
+ } else { // tree context menu
+ // Mahmoud_TODO: implement tree section context menu
}
+
contextMenu.exec(event->screenPos());
}
@@ -649,9 +621,11 @@ bool TimelineGraphicsScene::event(QEvent *event)
}
}
-Ruler *TimelineGraphicsScene::ruler() const { return m_ruler; }
-PlayHead *TimelineGraphicsScene::playHead() const { return m_playHead; }
-Separator *TimelineGraphicsScene::separator() const { return m_separator; }
-RowManager *TimelineGraphicsScene::rowManager() const { return m_rowManager; }
-QGraphicsWidget *TimelineGraphicsScene::widgetRoot() const { return m_widgetRoot; }
-KeyframeManager *TimelineGraphicsScene::keyframeManager() const { return m_keyframeManager; }
+// Getters
+Ruler *TimelineGraphicsScene::ruler() const { return m_ruler; }
+PlayHead *TimelineGraphicsScene::playHead() const { return m_playHead; }
+TreeHeader *TimelineGraphicsScene::treeHeader() const { return m_treeHeader; }
+RowManager *TimelineGraphicsScene::rowManager() const { return m_rowManager; }
+QGraphicsWidget *TimelineGraphicsScene::widgetRoot() const { return m_widgetRoot; }
+KeyframeManager *TimelineGraphicsScene::keyframeManager() const { return m_keyframeManager; }
+QGraphicsLinearLayout *TimelineGraphicsScene::layoutTree() const { return m_layoutTree; }
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.h b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.h
index a50e2bbd..09f72db0 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.h
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.h
@@ -32,13 +32,13 @@
#include "TimelineWidget.h"
#include "RowTimeline.h"
#include "RowTypes.h"
+#include "TimelineConstants.h"
#include <QtWidgets/qgraphicsscene.h>
-class Separator;
class Ruler;
class PlayHead;
-class TimelineItem;
+class TreeHeader;
class RowTree;
class SelectionRect;
class RowMover;
@@ -54,17 +54,19 @@ class TimelineGraphicsScene : public QGraphicsScene
Q_OBJECT
public:
- explicit TimelineGraphicsScene(QGraphicsView *viewTimelineContent, TimelineWidget *parent);
+ explicit TimelineGraphicsScene(TimelineWidget *timelineWidget);
void setTimelineScale(int scale);
void addNewLayer();
void deleteSelectedRow();
Ruler *ruler() const;
PlayHead *playHead() const;
- Separator *separator() const;
RowManager *rowManager() const;
QGraphicsWidget *widgetRoot() const;
KeyframeManager *keyframeManager() const;
+ QGraphicsLinearLayout *layoutTree() const;
+ TreeHeader *treeHeader() const;
+ void updateTreeWidth(double x);
protected:
bool event(QEvent *event) override;
@@ -87,29 +89,27 @@ private:
bool validLayerMove(RowTree *rowAtIndex, RowTree *nextRowAtIndex);
QGraphicsLinearLayout *m_layoutRoot;
- QGraphicsLinearLayout *m_layoutLabels;
+ QGraphicsLinearLayout *m_layoutTree;
QGraphicsLinearLayout *m_layoutTimeline;
- Separator *m_separator;
+ TreeHeader *m_treeHeader;
Ruler *m_ruler;
PlayHead *m_playHead;
- TimelineWidget *m_widget;
+ TimelineWidget *m_widgetTimeline;
QGraphicsWidget *m_widgetRoot;
- QGraphicsView *m_viewTimelineContent;
RowMover *m_rowMover = nullptr;
- RowTree *m_sceneRow = nullptr;
RowTimeline *m_editedTimelineRow = nullptr;
SelectionRect *m_selectionRect;
RowManager *m_rowManager = nullptr;
KeyframeManager *m_keyframeManager = nullptr;
QPointF m_pressPos;
- bool m_separatorPressed = false;
bool m_rulerPressed = false;
bool m_keyframePressed = false;
bool m_dragging = false;
- int m_clickedTimelineControlType = RowTimeline::TypeNone;
-
+ TimelineControlType m_clickedTimelineControlType = TimelineControlType::None;
+ TreeControlType m_clickedTreeControlType = TreeControlType::None;
+ double m_treeWidth = TimelineConstants::TREE_DEFAULT_W;
};
#endif // TIMELINEGRAPHICSSCENE_H
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineViewGV.cpp b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineSplitter.cpp
index 08dc3984..b8c71f26 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineViewGV.cpp
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineSplitter.cpp
@@ -26,14 +26,27 @@
**
****************************************************************************/
-#include "TimelineViewGV.h"
+#include "TimelineSplitter.h"
+#include "TimelineConstants.h"
-TimelineViewGV::TimelineViewGV(QWidget *parent)
+#include <QtGui/qevent.h>
+#include <QtWidgets/qapplication.h>
+
+TimelineSplitter::TimelineSplitter(QWidget *parent) : QWidget(parent)
{
- // TODO: to be deleted, not really useful
+ setFixedWidth(TimelineConstants::SPLITTER_W);
+ setAttribute(Qt::WA_Hover, true);
}
-TimelineViewGV::~TimelineViewGV()
+void TimelineSplitter::enterEvent(QEvent *event)
{
+ qApp->setOverrideCursor(Qt::SplitHCursor);
+ QWidget::enterEvent(event);
+}
+void TimelineSplitter::leaveEvent(QEvent *event)
+{
+ qApp->changeOverrideCursor(Qt::ArrowCursor);
+ qApp->restoreOverrideCursor();
+ QWidget::leaveEvent(event);
}
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineViewGV.h b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineSplitter.h
index 1beedcf4..1be64967 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineViewGV.h
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineSplitter.h
@@ -26,21 +26,23 @@
**
****************************************************************************/
-#ifndef TIMELINEVIEWGV_H
-#define TIMELINEVIEWGV_H
+#ifndef TIMELINESPLITTER_H
+#define TIMELINESPLITTER_H
-#include "TimelineWidget.h"
+#include <QtWidgets/qwidget.h>
-class TimelineViewGV : public QObject
+QT_FORWARD_DECLARE_CLASS(QEvent)
+
+class TimelineSplitter : public QWidget
{
Q_OBJECT
public:
- explicit TimelineViewGV(QWidget *parent = nullptr);
- ~TimelineViewGV();
+ explicit TimelineSplitter(QWidget *parent = nullptr);
-private:
- TimelineWidget *m_timelineWidget = nullptr;
+ protected:
+ void enterEvent(QEvent *event) override;
+ void leaveEvent(QEvent *event) override;
};
-#endif // TIMELINEVIEWGV_H
+#endif // TIMELINESPLITTER_H
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineWidget.cpp b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineWidget.cpp
index 152f40b0..407946fd 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineWidget.cpp
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineWidget.cpp
@@ -30,27 +30,86 @@
#include "TimelineGraphicsScene.h"
#include "TimelineConstants.h"
#include "TimelineToolbar.h"
+#include "RowManager.h"
+#include "KeyframeManager.h"
+#include "RowTree.h"
#include "PlayHead.h"
#include "Ruler.h"
-#include "Separator.h"
+#include "TimelineSplitter.h"
#include "StudioApp.h"
#include "Core.h"
#include "Doc.h"
-
-#include <QtWidgets/qgraphicssceneevent.h>
+#include "Dispatch.h"
+#include "Qt3DSDMStudioSystem.h"
+#include "Qt3DSDMSlides.h"
+#include "ClientDataModelBridge.h"
+#include "Bindings/TimelineTranslationManager.h"
+#include "Bindings/ITimelineItemBinding.h"
+#include "Bindings/Qt3DSDMTimelineItemBinding.h"
+#include "Bindings/Qt3DSDMTimelineItemProperty.h"
+
+#include <QtGui/qevent.h>
#include <QtWidgets/qgraphicslinearlayout.h>
#include <QtWidgets/qgraphicsview.h>
#include <QtWidgets/qboxlayout.h>
#include <QtWidgets/qscrollbar.h>
#include <QtWidgets/qslider.h>
-#include <QtWidgets/qsplitter.h>
#include <QtWidgets/qlabel.h>
-class Eventfilter : public QObject {
+// Mahmoud_TODO: debug func, to be removed
+void printBinding(ITimelineItemBinding *binding, QString padding = " ")
+{
+ qDebug().noquote().nospace()
+ << "\x1b[42m \x1b[1m" << __FUNCTION__
+ << padding
+ << binding->GetTimelineItem()->GetName().toQString()
+ << " (" << static_cast<Qt3DSDMTimelineItemBinding *>(binding)->GetInstance() << ")"
+ << "\x1b[m";
+
+
+ for (int i = 0; i < binding->GetPropertyCount(); i++) {
+ ITimelineItemProperty *property = binding->GetProperty(i);
+ qDebug().noquote().nospace()
+ << "\x1b[42m \x1b[1m" << __FUNCTION__
+ << padding
+ << "[" << property->GetName().toQString() << "]"
+ << " (" << static_cast<Qt3DSDMTimelineItemProperty*>(property)->getPropertyHandle() << ")"
+ << "\x1b[m";
+
+ for (int j = 0; j < property->GetKeyframeCount(); j++) {
+ IKeyframe *kf = property->GetKeyframeByIndex(j);
+ qDebug().noquote().nospace()
+ << "\x1b[42m \x1b[1m" << __FUNCTION__
+ << padding
+ << " {KF: " << kf->GetTime() << ", selected: " << kf->IsSelected() << "}"
+ << "\x1b[m";
+ }
+ }
+ padding = padding.append("-");
+
+ // create child rows recursively
+ for (int i = 0; i < binding->GetChildrenCount(); i++)
+ printBinding(binding->GetChild(i), padding);
+}
+
+// Mahmoud_TODO: debug func, to be removed
+void printHandlesMap(std::map<qt3dsdm::Qt3DSDMInstanceHandle, RowTree *> theBindingMap)
+{
+ for (auto& kv : theBindingMap)
+ qDebug().noquote().nospace()
+ << "\x1b[42m \x1b[1m" << __FUNCTION__
+ << ", k=" << kv.first
+ << ", v=" << (kv.second == nullptr ? "--" : kv.second->label())
+ << "\x1b[m";
+}
+
+class Eventfilter : public QObject
+{
public:
Eventfilter(QObject *parent) : QObject(parent) {}
- bool eventFilter(QObject *, QEvent *event) override {
+ bool eventFilter(QObject *, QEvent *event) override
+ {
if (event->type() == QEvent::Wheel) {
event->accept();
return true;
@@ -67,48 +126,51 @@ TimelineWidget::TimelineWidget(QWidget *parent)
, m_viewTreeContent(new QGraphicsView(this))
, m_viewTimelineHeader(new QGraphicsView(this))
, m_viewTimelineContent(new QGraphicsView(this))
- , m_graphicsScene(new TimelineGraphicsScene(m_viewTimelineContent, this)) {
+ , m_graphicsScene(new TimelineGraphicsScene(this))
+{
+ m_translationManager = new CTimelineTranslationManager();
+
setWindowTitle(tr("Timeline", "Title of timeline view"));
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
- QSizePolicy sizePolicy1(QSizePolicy::Expanding, QSizePolicy::Expanding);
- sizePolicy1.setHorizontalStretch(0);
- sizePolicy1.setVerticalStretch(0);
- sizePolicy1.setHeightForWidth(m_viewTimelineContent->sizePolicy().hasHeightForWidth());
-
- m_viewTimelineHeader->setScene(m_graphicsScene);
- m_viewTimelineHeader->setFixedHeight(TimelineConstants::ROW_H);
- m_viewTimelineHeader->setAlignment(Qt::AlignLeft | Qt::AlignTop);
- m_viewTimelineHeader->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- m_viewTimelineHeader->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- m_viewTimelineHeader->viewport()->installEventFilter(new Eventfilter(this));
- m_viewTimelineHeader->viewport()->setFocusPolicy(Qt::NoFocus);
-
- m_viewTimelineContent->setScene(m_graphicsScene);
- m_viewTimelineContent->setSizePolicy(sizePolicy1);
- m_viewTimelineContent->setAlignment(Qt::AlignLeft | Qt::AlignTop);
- m_viewTimelineContent->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
-
m_viewTreeHeader->setScene(m_graphicsScene);
m_viewTreeHeader->setFixedHeight(TimelineConstants::ROW_H);
m_viewTreeHeader->setAlignment(Qt::AlignLeft | Qt::AlignTop);
- m_viewTreeHeader->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_viewTreeHeader->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ m_viewTreeHeader->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_viewTreeHeader->viewport()->installEventFilter(new Eventfilter(this));
m_viewTreeHeader->viewport()->setFocusPolicy(Qt::NoFocus);
+ m_viewTreeHeader->setFixedWidth(TimelineConstants::TREE_DEFAULT_W);
m_viewTreeContent->setScene(m_graphicsScene);
m_viewTreeContent->setAlignment(Qt::AlignLeft | Qt::AlignTop);
+ m_viewTreeContent->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
+ m_viewTreeContent->horizontalScrollBar()->hide();
m_viewTreeContent->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- m_viewTreeContent->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ m_viewTreeContent->setFixedWidth(TimelineConstants::TREE_DEFAULT_W);
+
+ m_viewTimelineHeader->setScene(m_graphicsScene);
+ m_viewTimelineHeader->setFixedHeight(TimelineConstants::ROW_H);
+ m_viewTimelineHeader->setAlignment(Qt::AlignLeft | Qt::AlignTop);
+ m_viewTimelineHeader->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ m_viewTimelineHeader->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
+ m_viewTimelineHeader->verticalScrollBar()->hide();
+ m_viewTimelineHeader->viewport()->installEventFilter(new Eventfilter(this));
+ m_viewTimelineHeader->viewport()->setFocusPolicy(Qt::NoFocus);
- setStyleSheet(QStringLiteral("background-color:%1;").arg(TimelineConstants::WIDGET_BG_COLOR));
+ m_viewTimelineContent->setScene(m_graphicsScene);
+ m_viewTimelineContent->setAlignment(Qt::AlignLeft | Qt::AlignTop);
+ m_viewTimelineContent->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
+ m_viewTimelineContent->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
+ m_viewTimelineContent->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
auto *layoutTree = new QVBoxLayout;
layoutTree->setContentsMargins(QMargins(0, 0, 0, 0));
layoutTree->addWidget(m_viewTreeHeader);
layoutTree->addWidget(m_viewTreeContent);
+ m_splitter = new TimelineSplitter(this);
+
auto *layoutTimeline = new QVBoxLayout;
layoutTimeline->setContentsMargins(QMargins(0, 0, 0, 0));
layoutTimeline->addWidget(m_viewTimelineHeader);
@@ -117,35 +179,33 @@ TimelineWidget::TimelineWidget(QWidget *parent)
auto *layoutContent = new QHBoxLayout;
layoutContent->setContentsMargins(QMargins(0, 0, 0, 10));
layoutContent->addLayout(layoutTree);
+ layoutContent->addWidget(m_splitter);
layoutContent->addLayout(layoutTimeline);
- auto *widgetLayout = new QVBoxLayout;
- widgetLayout->setContentsMargins(0, 0, 0, 0);
- widgetLayout->setSpacing(0);
- widgetLayout->addLayout(layoutContent);
- widgetLayout->addWidget(m_toolbar);
- setLayout(widgetLayout);
+ auto *layoutRoot = new QVBoxLayout;
+ layoutRoot->setContentsMargins(0, 0, 0, 0);
+ layoutRoot->setSpacing(0);
+ layoutRoot->addLayout(layoutContent);
+ layoutRoot->addWidget(m_toolbar);
+ setLayout(layoutRoot);
- // connections
+ // connect graphics scene geometryChanged
connect(m_graphicsScene->widgetRoot(), &QGraphicsWidget::geometryChanged, this, [this]() {
- // TODO: work in progress
- qDebug() << "geometryChanged";
- qDebug() << m_graphicsScene->widgetRoot()->rect();
- m_viewTimelineHeader->setSceneRect(m_graphicsScene->widgetRoot()->rect().adjusted(
- m_graphicsScene->ruler()->x(), 0, 0, 0));
+ const QRectF rect = m_graphicsScene->widgetRoot()->rect();
- m_viewTimelineContent->setSceneRect(m_graphicsScene->widgetRoot()->rect().adjusted(
- m_graphicsScene->ruler()->x(),
- TimelineConstants::ROW_H, 0, 0));
+ m_viewTreeContent->setSceneRect(QRectF(0, TimelineConstants::ROW_H,
+ TimelineConstants::TREE_MAX_W, rect.height()));
- m_viewTreeContent->setSceneRect(QRectF(
- 0, TimelineConstants::ROW_H,
- m_graphicsScene->ruler()->x(), 0));
+ m_viewTimelineHeader->setSceneRect(QRectF(TimelineConstants::TREE_BOUND_W, 0,
+ rect.width() - TimelineConstants::TREE_BOUND_W,
+ TimelineConstants::ROW_H));
- m_graphicsScene->playHead()->setHeight(m_graphicsScene->widgetRoot()->geometry().height());
+ m_viewTimelineContent->setSceneRect(QRectF(TimelineConstants::TREE_BOUND_W,
+ TimelineConstants::ROW_H,
+ rect.width() - TimelineConstants::TREE_BOUND_W,
+ rect.height()));
- m_viewTreeHeader->setFixedWidth(m_graphicsScene->ruler()->x());
- m_viewTreeContent->setFixedWidth(m_graphicsScene->ruler()->x());
+ m_graphicsScene->playHead()->setHeight(m_graphicsScene->widgetRoot()->geometry().height());
});
// connect timeline and ruler horizontalScrollBars
@@ -173,20 +233,22 @@ TimelineWidget::TimelineWidget(QWidget *parent)
});
connect(m_toolbar, &TimelineToolbar::newLayerTriggered, this, [this]() {
- m_graphicsScene->addNewLayer();
+ // Mahmoud_TODO: debug code, remove
+ printHandlesMap(m_handlesMap);
+// m_graphicsScene->addNewLayer();
});
connect(m_toolbar, &TimelineToolbar::deleteLayerTriggered, this, [this]() {
- m_graphicsScene->deleteSelectedRow();
+ // Mahmoud_TODO: debug code, remove
+ printBinding(m_binding);
+// m_graphicsScene->deleteSelectedRow();
});
connect(m_toolbar, &TimelineToolbar::gotoTimeTriggered, this, [this]() {
- // TODO: implement
+ // Mahmoud_TODO: implement
});
connect(m_toolbar, &TimelineToolbar::firstFrameTriggered, this, [this]() {
- m_graphicsScene->playHead()->setTime(0);
- m_toolbar->setTime(0);
g_StudioApp.GetCore()->GetDoc()->NotifyTimeChanged(0);
});
@@ -199,15 +261,259 @@ TimelineWidget::TimelineWidget(QWidget *parent)
});
connect(m_toolbar, &TimelineToolbar::lastFrameTriggered, this, [this]() {
- double dur = m_graphicsScene->ruler()->duration();
- m_graphicsScene->playHead()->setTime(dur);
- m_toolbar->setTime(dur);
+ double dur = m_graphicsScene->ruler()->duration() * 1000;
g_StudioApp.GetCore()->GetDoc()->NotifyTimeChanged(dur);
});
connect(m_toolbar, &TimelineToolbar::timelineScaleChanged, this, [this](int scale) {
m_graphicsScene->setTimelineScale(scale);
});
+
+ // data model listeners
+ g_StudioApp.GetCore()->GetDispatch()->AddPresentationChangeListener(this);
+ g_StudioApp.GetCore()->GetDispatch()->AddClientPlayChangeListener(this);
+}
+
+void TimelineWidget::OnNewPresentation()
+{
+ // Register callbacks
+ qt3dsdm::IStudioFullSystemSignalProvider *theSignalProvider =
+ g_StudioApp.GetCore()->GetDoc()->GetStudioSystem()->GetFullSystemSignalProvider();
+
+ m_connections.push_back(theSignalProvider->ConnectActiveSlide(
+ std::bind(&TimelineWidget::OnActiveSlide, this, std::placeholders::_1,
+ std::placeholders::_2, std::placeholders::_3)));
+
+ CDispatch *theDispatch = g_StudioApp.GetCore()->GetDispatch();
+
+ m_connections.push_back(theDispatch->ConnectSelectionChange(
+ std::bind(&TimelineWidget::OnSelectionChange, this, std::placeholders::_1)));
+
+ // object created/deleted
+ m_connections.push_back(theSignalProvider->ConnectInstanceCreated(
+ std::bind(&TimelineWidget::OnAssetCreated, this, std::placeholders::_1)));
+ m_connections.push_back(theSignalProvider->ConnectInstanceDeleted(
+ std::bind(&TimelineWidget::OnAssetDeleted, this, std::placeholders::_1)));
+
+ // animation created/deleted
+ m_connections.push_back(theSignalProvider->ConnectAnimationCreated(
+ std::bind(&TimelineWidget::OnAnimationCreated, this,
+ std::placeholders::_2, std::placeholders::_3)));
+ m_connections.push_back(theSignalProvider->ConnectAnimationDeleted(
+ std::bind(&TimelineWidget::OnAnimationDeleted, this,
+ std::placeholders::_2, std::placeholders::_3)));
+
+ // action created/deleted
+ m_connections.push_back(theSignalProvider->ConnectActionCreated(
+ std::bind(&TimelineWidget::OnActionEvent, this,
+ std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
+ m_connections.push_back(theSignalProvider->ConnectActionDeleted(
+ std::bind(&TimelineWidget::OnActionEvent, this,
+ std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
+}
+
+void TimelineWidget::OnClosingPresentation()
+{
+ m_connections.clear();
+}
+
+void TimelineWidget::OnTimeChanged(long inTime)
+{
+ m_graphicsScene->playHead()->setTime(inTime * .001);
+ m_toolbar->setTime(inTime);
+}
+
+void TimelineWidget::OnActiveSlide(const qt3dsdm::Qt3DSDMSlideHandle &inMaster, int inIndex,
+ const qt3dsdm::Qt3DSDMSlideHandle &inSlide)
+{
+ Q_UNUSED(inMaster);
+ Q_UNUSED(inIndex);
+
+ if (m_activeSlide == inSlide)
+ return;
+
+ m_translationManager->Clear();
+ m_activeSlide = inSlide;
+
+ auto *theSlideSystem = g_StudioApp.GetCore()->GetDoc()->GetStudioSystem()->GetSlideSystem();
+ auto theSlideInstance = theSlideSystem->GetSlideInstance(inSlide);
+
+ m_binding = static_cast<Qt3DSDMTimelineItemBinding *>(
+ m_translationManager->GetOrCreate(theSlideInstance));
+
+ m_graphicsScene->rowManager()->recreateRowsFromBinding(m_binding);
+ m_handlesMap.clear();
+ insertToHandlesMapRecursive(m_binding);
+}
+
+void TimelineWidget::insertToHandlesMapRecursive(Qt3DSDMTimelineItemBinding *binding)
+{
+ if (binding->GetObjectType() != OBJTYPE_MATERIAL) {
+ m_handlesMap.insert(std::make_pair(binding->GetInstance(), binding->getRowTree()));
+
+ for (int i = 0; i < binding->GetChildrenCount(); i++) {
+ insertToHandlesMapRecursive(
+ static_cast<Qt3DSDMTimelineItemBinding *>(binding->GetChild(i)));
+ }
+ }
+}
+
+void TimelineWidget::OnSelectionChange(Q3DStudio::SSelectedValue inNewSelectable)
+{
+ qt3dsdm::TInstanceHandleList theInstances = inNewSelectable.GetSelectedInstances();
+ for (size_t idx = 0, end = theInstances.size(); idx < end; ++idx) {
+ qt3dsdm::Qt3DSDMInstanceHandle theInstance(theInstances[idx]);
+ if (g_StudioApp.GetCore()->GetDoc()->GetStudioSystem()->IsInstance(theInstance)) {
+ // Mahmoud_TODO: remove debug
+ qDebug() << "\x1b[42m \x1b[1m" << __FUNCTION__
+ << theInstance
+ << "\x1b[m";
+ Qt3DSDMTimelineItemBinding *selectedBinding = getBindingForHandle(theInstance,
+ m_binding);
+ m_graphicsScene->rowManager()->selectRow(selectedBinding->getRowTree());
+ }
+ }
+
+ // Mahmoud_TODO: Expand the tree so the selection is visible
+}
+
+void TimelineWidget::OnAssetCreated(qt3dsdm::Qt3DSDMInstanceHandle inInstance)
+{
+ CClientDataModelBridge *theDataModelBridge = g_StudioApp.GetCore()->GetDoc()
+ ->GetStudioSystem()->GetClientDataModelBridge();
+
+ if (theDataModelBridge->IsSceneGraphInstance(inInstance)) {
+ Qt3DSDMTimelineItemBinding *binding = getBindingForHandle(inInstance, m_binding);
+ Qt3DSDMTimelineItemBinding *bindingParent = getBindingForHandle(theDataModelBridge
+ ->GetParentInstance(inInstance), m_binding);
+ // Mahmoud_TODO: remove debug
+ qDebug() << "\x1b[42m \x1b[1m" << __FUNCTION__
+ << ", binding=" << binding->GetName().toQString()
+ << ", bindingParent=" << bindingParent->GetName().toQString()
+ << "\x1b[m";
+ RowTree *newRow = m_graphicsScene->rowManager()
+ ->createRowFromBinding(binding, bindingParent->getRowTree());
+
+ m_handlesMap.insert(std::make_pair(inInstance, newRow));
+ }
+}
+
+void TimelineWidget::OnAssetDeleted(qt3dsdm::Qt3DSDMInstanceHandle inInstance)
+{
+ THandleMap::const_iterator it = m_handlesMap.find(inInstance);
+
+ if (it != m_handlesMap.end()) { // scene object exists
+ m_graphicsScene->rowManager()->deleteRow(it->second);
+ m_handlesMap.erase(it);
+ }
+}
+
+void TimelineWidget::OnAnimationCreated(qt3dsdm::Qt3DSDMInstanceHandle parentInstance,
+ qt3dsdm::Qt3DSDMPropertyHandle property)
+{
+ Qt3DSDMTimelineItemBinding *binding = getBindingForHandle(parentInstance, m_binding);
+ ITimelineItemProperty *propBinding = binding->GetPropertyBinding(property);
+
+ // create the binding if doesn't exist
+ if (propBinding == nullptr) {
+ propBinding = binding->GetOrCreatePropertyBinding(property);
+
+ // create the property UI row
+ RowTree *propRow = m_graphicsScene->rowManager()
+ ->getOrCreatePropertyRow(binding->getRowTree(), propBinding->GetName().toQString());
+
+ // connect the row and binding
+ propBinding->setRowTree(propRow);
+ propRow->setPropBinding(propBinding);
+
+ // add keyframes
+ for (int i = 0; i < propBinding->GetKeyframeCount(); i++) {
+ IKeyframe *kf = propBinding->GetKeyframeByIndex(i);
+ m_graphicsScene->keyframeManager()->insertKeyframe(propRow->rowTimeline(),
+ static_cast<double>(kf->GetTime()) * .001, 0, false);
+ }
+
+ propRow->update();
+ }
+
+ // make sure the property rows are in the same order as in the binding
+ m_graphicsScene->rowManager()->reorderPropertiesFromBinding(binding);
+}
+
+void TimelineWidget::OnAnimationDeleted(qt3dsdm::Qt3DSDMInstanceHandle parentInstance,
+ qt3dsdm::Qt3DSDMPropertyHandle property)
+{
+ Qt3DSDMTimelineItemBinding *binding = getBindingForHandle(parentInstance, m_binding);
+ ITimelineItemProperty *propBinding = binding->GetPropertyBinding(property);
+
+ if (propBinding != nullptr) {
+ m_graphicsScene->rowManager()->deleteRow(propBinding->getRowTree());
+
+ if (binding)
+ binding->RemovePropertyRow(property);
+ }
+}
+
+void TimelineWidget::OnActionEvent(qt3dsdm::Qt3DSDMActionHandle inAction,
+ qt3dsdm::Qt3DSDMSlideHandle inSlide,
+ qt3dsdm::Qt3DSDMInstanceHandle inOwner)
+{
+ Q_UNUSED(inAction);
+ Q_UNUSED(inSlide);
+ Q_UNUSED(inOwner);
+
+ // Mahmoud_TODO: implement
+ qDebug() << "\x1b[42m \x1b[1m" << __FUNCTION__ << "\x1b[m";
+}
+
+Qt3DSDMTimelineItemBinding *TimelineWidget::getBindingForHandle(int handle,
+ Qt3DSDMTimelineItemBinding *binding) const
+{
+ if (binding->GetInstance().GetHandleValue() == handle)
+ return binding;
+
+ for (int i = 0; i < binding->GetChildrenCount(); i++) {
+ Qt3DSDMTimelineItemBinding *b = getBindingForHandle(handle,
+ static_cast<Qt3DSDMTimelineItemBinding *>(binding->GetChild(i)));
+
+ if (b != nullptr)
+ return b;
+ }
+
+ return nullptr;
+}
+
+void TimelineWidget::mousePressEvent(QMouseEvent *event)
+{
+ if (childAt(event->pos()) == m_splitter)
+ m_splitterPressed = true;
+}
+
+void TimelineWidget::mouseMoveEvent(QMouseEvent *event)
+{
+ if (m_splitterPressed) {
+ double treeWidth = event->pos().x() - m_splitter->size().width() * .5;
+ treeWidth = qBound(TimelineConstants::TREE_MIN_W, treeWidth, TimelineConstants::TREE_MAX_W);
+
+ m_viewTreeHeader->setFixedWidth(treeWidth);
+ m_viewTreeContent->setFixedWidth(treeWidth);
+ m_graphicsScene->updateTreeWidth(treeWidth);
+ }
+}
+
+void TimelineWidget::mouseReleaseEvent(QMouseEvent *event)
+{
+ m_splitterPressed = false;
+}
+
+QGraphicsView *TimelineWidget::viewTimelineContent() const
+{
+ return m_viewTimelineContent;
+}
+
+QGraphicsView *TimelineWidget::viewTreeContent() const
+{
+ return m_viewTreeContent;
}
TimelineToolbar *TimelineWidget::toolbar() const
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineWidget.h b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineWidget.h
index 6ed3fe87..0ae48cd0 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineWidget.h
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineWidget.h
@@ -30,13 +30,26 @@
#define TIMELINEWIDGET_H
#include <QtWidgets/qwidget.h>
+#include "DispatchListeners.h"
+#include "ObjectListModel.h"
+#include "Qt3DSDMHandles.h"
+#include "Qt3DSDMSignals.h"
+#include "SelectedValueImpl.h"
+#include "TimelineObjectModel.h"
-class TimelineGraphicsScene;
+class RowTree;
class TimelineToolbar;
+class TimelineSplitter;
+class TimelineGraphicsScene;
+class CTimelineTranslationManager;
+class Qt3DSDMTimelineItemBinding;
+QT_FORWARD_DECLARE_CLASS(QMouseEvent)
QT_FORWARD_DECLARE_CLASS(QGraphicsView)
-class TimelineWidget : public QWidget
+class TimelineWidget : public QWidget,
+ public CPresentationChangeListener,
+ public CClientPlayChangeListener
{
Q_OBJECT
@@ -44,14 +57,57 @@ public:
explicit TimelineWidget(QWidget *parent = nullptr);
TimelineToolbar *toolbar() const;
+ QGraphicsView *viewTimelineContent() const;
+ QGraphicsView *viewTreeContent() const;
+
+ // Presentation Change Listener
+ void OnNewPresentation() override;
+ void OnClosingPresentation() override;
+ void OnSelectionChange(Q3DStudio::SSelectedValue inNewSelectable);
+
+ //CClientPlayChangeListener
+ void OnTimeChanged(long inTime) override;
+
+protected:
+ // DataModel callbacks
+ virtual void OnActiveSlide(const qt3dsdm::Qt3DSDMSlideHandle &inMaster, int inIndex,
+ const qt3dsdm::Qt3DSDMSlideHandle &inSlide);
+ void OnAssetCreated(qt3dsdm::Qt3DSDMInstanceHandle inInstance);
+ void OnAssetDeleted(qt3dsdm::Qt3DSDMInstanceHandle inInstance);
+ void OnAnimationCreated(qt3dsdm::Qt3DSDMInstanceHandle parentInstance,
+ qt3dsdm::Qt3DSDMPropertyHandle property);
+ void OnAnimationDeleted(qt3dsdm::Qt3DSDMInstanceHandle parentInstance,
+ qt3dsdm::Qt3DSDMPropertyHandle property);
+ void OnActionEvent(qt3dsdm::Qt3DSDMActionHandle inAction, qt3dsdm::Qt3DSDMSlideHandle inSlide,
+ qt3dsdm::Qt3DSDMInstanceHandle inOwner);
+
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
private:
+ typedef std::map<qt3dsdm::Qt3DSDMInstanceHandle, RowTree *> THandleMap;
+
+ Qt3DSDMTimelineItemBinding *getBindingForHandle(int handle,
+ Qt3DSDMTimelineItemBinding *binding) const;
+ void insertToHandlesMapRecursive(Qt3DSDMTimelineItemBinding *binding);
QGraphicsView *m_viewTreeHeader = nullptr;
QGraphicsView *m_viewTreeContent = nullptr;
QGraphicsView *m_viewTimelineHeader = nullptr;
QGraphicsView *m_viewTimelineContent = nullptr;
TimelineToolbar *m_toolbar = nullptr;
TimelineGraphicsScene *m_graphicsScene;
+ TimelineSplitter *m_splitter = nullptr;
+ CTimelineTranslationManager *m_translationManager = nullptr;
+ TimelineObjectModel *m_objectListModel = nullptr;
+ FlatObjectListModel *m_model = nullptr;
+ Qt3DSDMTimelineItemBinding *m_binding;
+ bool m_splitterPressed = false;
+
+ // data model connection
+ std::vector<std::shared_ptr<qt3dsdm::ISignalConnection>> m_connections;
+ qt3dsdm::Qt3DSDMSlideHandle m_activeSlide;
+ THandleMap m_handlesMap;
};
#endif // TIMELINEWIDGET_H
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/PlayHead.cpp b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/PlayHead.cpp
index e3bda369..95057c83 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/PlayHead.cpp
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/PlayHead.cpp
@@ -72,13 +72,9 @@ void PlayHead::setTime(double time)
void PlayHead::setPosition(double posX)
{
- if (posX < TimelineConstants::RULER_EDGE_OFFSET) {
- posX = TimelineConstants::RULER_EDGE_OFFSET;
- } else if (posX > m_ruler->duration() * TimelineConstants::RULER_SEC_W
- * m_ruler->timelineScale() + TimelineConstants::RULER_EDGE_OFFSET) {
- posX = m_ruler->duration() * TimelineConstants::RULER_SEC_W * m_ruler->timelineScale()
- + TimelineConstants::RULER_EDGE_OFFSET;
- }
+ posX = qBound(TimelineConstants::RULER_EDGE_OFFSET, posX, m_ruler->duration()
+ * TimelineConstants::RULER_SEC_W * m_ruler->timelineScale()
+ + TimelineConstants::RULER_EDGE_OFFSET);
setX(m_ruler->x() + posX);
m_time = (posX - TimelineConstants::RULER_EDGE_OFFSET)
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTimeline.cpp b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTimeline.cpp
index ae2fba7c..ac04e4bf 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTimeline.cpp
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTimeline.cpp
@@ -35,28 +35,38 @@
#include <QtGui/qpainter.h>
#include <QtWidgets/qgraphicssceneevent.h>
-RowTimeline::RowTimeline(Ruler *ruler)
+RowTimeline::RowTimeline()
: InteractiveTimelineItem()
- , m_ruler(ruler)
{
}
+RowTimeline::~RowTimeline()
+{
+ // remove keyframes
+ if (!m_keyframes.empty()) {
+ if (m_isProperty) // non-property rows use the same keyframes from property rows.
+ qDeleteAll(m_keyframes);
+
+ m_keyframes.clear();
+ }
+}
+
void RowTimeline::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
// Background
QColor bgColor;
- if (m_state == Selected)
+ if (m_rowTree->isProperty())
+ bgColor = TimelineConstants::ROW_COLOR_NORMAL_PROP;
+ else if (m_state == Selected)
bgColor = TimelineConstants::ROW_COLOR_SELECTED;
- else if (m_state == Hovered)
+ else if (m_state == Hovered && !m_rowTree->m_locked)
bgColor = TimelineConstants::ROW_COLOR_OVER;
- else if (m_rowTree->rowType() == RowType::Property)
- bgColor = TimelineConstants::ROW_COLOR_NORMAL_PROP;
else
bgColor = TimelineConstants::ROW_COLOR_NORMAL;
- painter->fillRect(QRect(0, 0, size().width(), size().height() - 1), bgColor);
+ painter->fillRect(QRect(0, 0, 10000, size().height() - 1), bgColor);
// Duration
- if (m_rowTree->rowType() != RowType::Property) {
+ if (!m_rowTree->isProperty() && m_rowTree->rowType() != OBJTYPE_SCENE) {
painter->save();
// fully outside ancestors' limits, draw fully hashed
@@ -121,7 +131,7 @@ void RowTimeline::paint(QPainter *painter, const QStyleOptionGraphicsItem *optio
painter->drawPixmap(timeToX(keyframe->time) - 8.5, 2, keyframe->selected
? pixKeyframeMasterSelected : pixKeyframeMasterNormal);
}
- } else if (m_rowTree->rowType() == RowType::Property) {
+ } else if (m_rowTree->isProperty()) {
static const QPixmap pixKeyframePropertyNormal
= QPixmap(":/images/Keyframe-Property-Normal.png");
static const QPixmap pixKeyframePropertySelected
@@ -171,7 +181,7 @@ QList<Keyframe *> RowTimeline::getKeyframesInRange(const double left, const doub
if (m_rowTree->hasPropertyChildren()) {
const auto childRows = m_rowTree->childRows();
for (auto child : childRows) {
- if (child->rowType() == RowType::Property)
+ if (child->isProperty())
keyframes.append(child->rowTimeline()->m_keyframes);
}
} else {
@@ -228,23 +238,23 @@ void RowTimeline::updateKeyframes()
}
}
-int RowTimeline::getClickedControl(const QPointF &scenePos)
+TimelineControlType RowTimeline::getClickedControl(const QPointF &scenePos) const
{
- if (m_rowTree->rowType() == RowType::Property)
- return TypeNone;
+ if (m_rowTree->isProperty())
+ return TimelineControlType::None;
QPointF p = mapFromScene(scenePos.x(), scenePos.y());
if (p.x() > m_startX - TimelineConstants::DURATION_HANDLE_W * .5
&& p.x() < m_startX + TimelineConstants::DURATION_HANDLE_W * .5) {
- return TypeStartHandle;
+ return TimelineControlType::StartHandle;
} else if (p.x() > m_endX - TimelineConstants::DURATION_HANDLE_W * .5
&& p.x() < m_endX + TimelineConstants::DURATION_HANDLE_W * .5) {
- return TypeEndHandle;
- } else if (p.x() > m_startX && p.x() < m_endX) {
- return TypeDuration;
+ return TimelineControlType::EndHandle;
+ } else if (p.x() > m_startX && p.x() < m_endX && !rowTree()->locked()) {
+ return TimelineControlType::Duration;
}
- return TypeNone;
+ return TimelineControlType::None;
}
// move the duration area (start/end x)
@@ -258,8 +268,8 @@ void RowTimeline::moveDurationBy(double dx)
if (m_startX < TimelineConstants::RULER_EDGE_OFFSET) {
m_startX = TimelineConstants::RULER_EDGE_OFFSET;
m_endX = m_startX + dur;
- } else if (m_endX > timeToX(m_ruler->duration())) {
- m_endX = timeToX(m_ruler->duration());
+ } else if (m_endX > timeToX(rowTree()->m_scene->ruler()->duration())) {
+ m_endX = timeToX(rowTree()->m_scene->ruler()->duration());
m_startX = m_endX - dur;
}
@@ -280,15 +290,15 @@ void RowTimeline::moveDurationBy(double dx)
// convert time values to x
double RowTimeline::timeToX(double time)
{
- return TimelineConstants::RULER_EDGE_OFFSET
- + time * TimelineConstants::RULER_SEC_W * m_ruler->timelineScale();
+ return TimelineConstants::RULER_EDGE_OFFSET + time * TimelineConstants::RULER_SEC_W
+ * rowTree()->m_scene->ruler()->timelineScale();
}
// convert x values to time
double RowTimeline::xToTime(double xPos)
{
return (xPos - TimelineConstants::RULER_EDGE_OFFSET)
- / (TimelineConstants::RULER_SEC_W * m_ruler->timelineScale());
+ / (TimelineConstants::RULER_SEC_W * rowTree()->m_scene->ruler()->timelineScale());
}
// called after timeline scale is changed to update duration star/end positions
@@ -309,7 +319,7 @@ void RowTimeline::setStartX(double startX)
m_startX = startX;
m_startTime = xToTime(startX);
- if (m_rowTree->parentRow() == nullptr)
+ if (m_rowTree->parentRow() == nullptr || m_rowTree->parentRow()->rowType() == OBJTYPE_SCENE)
m_minStartX = m_startX;
updateChildrenMinStartXRecursive(m_rowTree);
@@ -321,13 +331,13 @@ void RowTimeline::setEndX(double endX)
{
if (endX < m_startX + 1)
endX = m_startX + 1;
- else if (endX > timeToX(m_ruler->duration()))
- endX = timeToX(m_ruler->duration());
+ else if (endX > timeToX(rowTree()->m_scene->ruler()->duration()))
+ endX = timeToX(rowTree()->m_scene->ruler()->duration());
m_endX = endX;
m_endTime = xToTime(endX);
- if (m_rowTree->parentRow() == nullptr)
+ if (m_rowTree->parentRow() == nullptr || m_rowTree->parentRow()->rowType() == OBJTYPE_SCENE)
m_maxEndX = m_endX;
updateChildrenMaxEndXRecursive(m_rowTree);
@@ -367,7 +377,7 @@ void RowTimeline::setStartTime(double startTime)
m_startTime = startTime;
m_startX = timeToX(startTime);
- if (m_rowTree->parentRow() == nullptr)
+ if (m_rowTree->parentRow() == nullptr || m_rowTree->parentRow()->rowType() == OBJTYPE_SCENE)
m_minStartX = m_startX;
updateChildrenMinStartXRecursive(m_rowTree);
@@ -379,7 +389,7 @@ void RowTimeline::setEndTime(double endTime)
m_endTime = endTime;
m_endX = timeToX(endTime);
- if (m_rowTree->parentRow() == nullptr)
+ if (m_rowTree->parentRow() == nullptr || m_rowTree->parentRow()->rowType() == OBJTYPE_SCENE)
m_maxEndX = m_endX;
updateChildrenMaxEndXRecursive(m_rowTree);
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTimeline.h b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTimeline.h
index 50b95838..bcfe8e96 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTimeline.h
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTimeline.h
@@ -30,9 +30,9 @@
#define ROWTIMELINE_H
#include "InteractiveTimelineItem.h"
+#include "RowTypes.h"
class RowTree;
-class Ruler;
struct Keyframe;
class RowTimeline : public InteractiveTimelineItem
@@ -40,15 +40,8 @@ class RowTimeline : public InteractiveTimelineItem
Q_OBJECT
public:
- enum ControlType {
- TypeNone,
- TypeKeyFrame,
- TypeDuration,
- TypeStartHandle,
- TypeEndHandle
- };
-
- explicit RowTimeline(Ruler *ruler);
+ explicit RowTimeline();
+ ~RowTimeline();
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget = nullptr) override;
@@ -64,7 +57,7 @@ public:
void updateKeyframes();
void insertKeyframe(Keyframe *keyframe);
void removeKeyframe(Keyframe *keyframe);
- int getClickedControl(const QPointF &scenePos);
+ TimelineControlType getClickedControl(const QPointF &scenePos) const;
double getStartTime() const;
double getEndTime() const;
int type() const;
@@ -81,13 +74,13 @@ private:
double xToTime(double xPos);
RowTree *m_rowTree;
- Ruler *m_ruler;
- double m_startTime;
- double m_endTime;
- double m_startX;
- double m_endX;
- double m_minStartX;
- double m_maxEndX;
+ double m_startTime = 0;
+ double m_endTime = 0;
+ double m_startX = 0;
+ double m_endX = 0;
+ double m_minStartX = 0;
+ double m_maxEndX = 0;
+ bool m_isProperty = false; // used in the destructor
QList<Keyframe *> m_keyframes;
friend class RowTree;
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTree.cpp b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTree.cpp
index ef6b67ea..12888471 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTree.cpp
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTree.cpp
@@ -28,32 +28,56 @@
#include "RowTree.h"
#include "RowTimeline.h"
+#include "RowManager.h"
#include "TimelineConstants.h"
+#include "StudioObjectTypes.h"
+#include "Bindings/ITimelineItemBinding.h"
#include <QtGui/qpainter.h>
+#include <QtWidgets/qgraphicslinearlayout.h>
#include <QtWidgets/qgraphicssceneevent.h>
-RowTree::RowTree(Ruler *ruler, RowType rowType, const QString &label)
+// object row constructor
+RowTree::RowTree(TimelineGraphicsScene *timelineScene, EStudioObjectType rowType,
+ const QString &label)
: InteractiveTimelineItem()
- , m_rowTimeline(new RowTimeline(ruler))
+ , m_rowTimeline(new RowTimeline())
{
+ m_scene = timelineScene;
m_rowType = rowType;
m_label = label;
setTimelineRow(m_rowTimeline);
m_rowTimeline->setRowTree(this);
+
+ if (m_rowType == OBJTYPE_MATERIAL)
+ m_isProperty = true;
+}
+
+RowTree::~RowTree()
+{
+ delete m_rowTimeline; // this will also delete the keyframes
+}
+
+ITimelineItemBinding *RowTree::getBinding() const
+{
+ return m_binding;
}
-RowTree::RowTree(Ruler *ruler, PropertyType propType)
+// property row constructor
+RowTree::RowTree(TimelineGraphicsScene *timelineScene, const QString &propType)
: InteractiveTimelineItem()
- , m_rowTimeline(new RowTimeline(ruler))
+ , m_rowTimeline(new RowTimeline())
{
- m_rowType = RowType::Property;
+ m_scene = timelineScene;
+ m_label = propType;
m_propertyType = propType;
- updatePropertyLabel();
setTimelineRow(m_rowTimeline);
m_rowTimeline->setRowTree(this);
+
+ m_isProperty = true;
+ m_rowTimeline->m_isProperty = true;
}
void RowTree::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
@@ -62,20 +86,20 @@ void RowTree::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, Q
// update button bounds rects
m_rectArrow .setRect(offset, size().height() * .5 - 8, 16, 16);
- m_rectShy .setRect(size().width() - 16 * 3.3, size().height() * .5 - 8, 16, 16);
- m_rectVisible.setRect(size().width() - 16 * 2.2, size().height() * .5 - 8, 16, 16);
- m_rectLocked .setRect(size().width() - 16 * 1.1, size().height() * .5 - 8, 16, 16);
+ m_rectShy .setRect(m_treeWidth - 16 * 3.3, size().height() * .5 - 8, 16, 16);
+ m_rectVisible.setRect(m_treeWidth - 16 * 2.2, size().height() * .5 - 8, 16, 16);
+ m_rectLocked .setRect(m_treeWidth - 16 * 1.1, size().height() * .5 - 8, 16, 16);
// Background
QColor bgColor;
if (m_moveSource)
bgColor = TimelineConstants::ROW_COLOR_MOVE_SRC;
+ else if (m_isProperty)
+ bgColor = TimelineConstants::ROW_COLOR_NORMAL_PROP;
else if (m_state == Selected)
bgColor = TimelineConstants::ROW_COLOR_SELECTED;
- else if (m_state == Hovered)
+ else if (m_state == Hovered && !m_locked)
bgColor = TimelineConstants::ROW_COLOR_OVER;
- else if (m_rowType == RowType::Property)
- bgColor = TimelineConstants::ROW_COLOR_NORMAL_PROP;
else
bgColor = TimelineConstants::ROW_COLOR_NORMAL;
@@ -93,84 +117,101 @@ void RowTree::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, Q
painter->drawPixmap(m_rectArrow, m_expanded ? pixArrowDown : pixArrow);
// Row type icon
- static const QPixmap pixScene = QPixmap(":/images/Objects-Scene-Normal.png");
- static const QPixmap pixLayer = QPixmap(":/images/Asset-Layer-Normal.png");
- static const QPixmap pixObject = QPixmap(":/images/Asset-Cube-Normal.png");
- static const QPixmap pixLight = QPixmap(":/images/Asset-Light-Normal.png");
- static const QPixmap pixCamera = QPixmap(":/images/Asset-Camera-Normal.png");
- static const QPixmap pixText = QPixmap(":/images/Asset-Text-Normal.png");
- static const QPixmap pixAlias = QPixmap(":/images/Asset-Alias-Normal.png");
- static const QPixmap pixGroup = QPixmap(":/images/Asset-Group-Normal.png");
- static const QPixmap pixComponent = QPixmap(":/images/Asset-Component-Normal.png");
- static const QPixmap pixProperty = QPixmap(":/images/Objects-Property-Normal.png");
+ static const QPixmap pixSceneNormal = QPixmap(":/images/Objects-Scene-Normal.png");
+ static const QPixmap pixLayerNormal = QPixmap(":/images/Objects-Layer-Normal.png");
+ static const QPixmap pixObjectNormal = QPixmap(":/images/Objects-Model-Normal.png");
+ static const QPixmap pixLightNormal = QPixmap(":/images/Objects-Light-Normal.png");
+ static const QPixmap pixCameraNormal = QPixmap(":/images/Objects-Camera-Normal.png");
+ static const QPixmap pixTextNormal = QPixmap(":/images/Objects-Text-Normal.png");
+ static const QPixmap pixAliasNormal = QPixmap(":/images/Objects-Alias-Normal.png");
+ static const QPixmap pixGroupNormal = QPixmap(":/images/Objects-Group-Normal.png");
+ static const QPixmap pixComponentNormal = QPixmap(":/images/Objects-Component-Normal.png");
+ static const QPixmap pixMaterialNormal = QPixmap(":/images/Objects-Material-Normal.png");
+ static const QPixmap pixPropertyNormal = QPixmap(":/images/Objects-Property-Normal.png");
+
+ static const QPixmap pixSceneDisabled = QPixmap(":/images/Objects-Scene-Disabled.png");
+ static const QPixmap pixLayerDisabled = QPixmap(":/images/Objects-Layer-Disabled.png");
+ static const QPixmap pixObjectDisabled = QPixmap(":/images/Objects-Model-Disabled.png");
+ static const QPixmap pixLightDisabled = QPixmap(":/images/Objects-Light-Disabled.png");
+ static const QPixmap pixCameraDisabled = QPixmap(":/images/Objects-Camera-Disabled.png");
+ static const QPixmap pixTextDisabled = QPixmap(":/images/Objects-Text-Disabled.png");
+ static const QPixmap pixAliasDisabled = QPixmap(":/images/Objects-Alias-Disabled.png");
+ static const QPixmap pixGroupDisabled = QPixmap(":/images/Objects-Group-Disabled.png");
+ static const QPixmap pixComponentDisabled = QPixmap(":/images/Objects-Component-Disabled.png");
+ static const QPixmap pixMaterialDisabled = QPixmap(":/images/Objects-Material-Disabled.png");
+ static const QPixmap pixPropertyDisabled = QPixmap(":/images/Objects-Property-Disabled.png");
QPixmap pixRowType;
QString rowLabel;
switch (m_rowType) {
- case RowType::Scene:
- pixRowType = pixScene;
+ case OBJTYPE_SCENE:
+ pixRowType = m_locked ? pixSceneDisabled : pixSceneNormal;
rowLabel = tr("Scene");
break;
- case RowType::Layer:
- pixRowType = pixLayer;
+ case OBJTYPE_LAYER:
+ pixRowType = m_locked ? pixLayerDisabled : pixLayerNormal;
rowLabel = tr("Layer");
break;
- case RowType::Object:
- pixRowType = pixObject;
+ case OBJTYPE_MODEL:
+ pixRowType = m_locked ? pixObjectDisabled : pixObjectNormal;
rowLabel = tr("Object");
break;
- case RowType::Light:
- pixRowType = pixLight;
+ case OBJTYPE_LIGHT:
+ pixRowType = m_locked ? pixLightDisabled : pixLightNormal;
rowLabel = tr("Light");
break;
- case RowType::Camera:
- pixRowType = pixCamera;
+ case OBJTYPE_CAMERA:
+ pixRowType = m_locked ? pixCameraDisabled : pixCameraNormal;
rowLabel = tr("Camera");
break;
- case RowType::Text:
- pixRowType = pixText;
+ case OBJTYPE_TEXT:
+ pixRowType = m_locked ? pixTextDisabled : pixTextNormal;
rowLabel = tr("Text");
break;
- case RowType::Alias:
- pixRowType = pixAlias;
+ case OBJTYPE_ALIAS:
+ pixRowType = m_locked ? pixAliasDisabled : pixAliasNormal;
rowLabel = tr("Alias");
break;
- case RowType::Group:
- pixRowType = pixGroup;
+ case OBJTYPE_GROUP:
+ pixRowType = m_locked ? pixGroupDisabled : pixGroupNormal;
rowLabel = tr("Group");
break;
- case RowType::Component:
- pixRowType = pixComponent;
+ case OBJTYPE_COMPONENT:
+ pixRowType = m_locked ? pixComponentDisabled : pixComponentNormal;
rowLabel = tr("Component");
break;
- case RowType::Property:
- pixRowType = pixProperty;
- rowLabel = tr("Property");
+ case OBJTYPE_MATERIAL:
+ pixRowType = m_locked ? pixMaterialDisabled : pixMaterialNormal;
+ rowLabel = tr("Default");
break;
default:
- pixRowType = pixLayer;
- rowLabel = tr("Layer");
+ break;
}
- if (m_label == 0)
+ if (m_isProperty && m_rowType != OBJTYPE_MATERIAL)
+ pixRowType = m_locked ? pixPropertyDisabled : pixPropertyNormal;
+
+ if (m_label.isEmpty())
m_label = rowLabel;
y = (size().height() - 16) * .5;
+
painter->drawPixmap(offset + 15, y, 16, 16, pixRowType);
// Label
- painter->setPen(QColor(TimelineConstants::ROW_TEXT_COLOR));
+ painter->setPen(QColor(m_locked ? TimelineConstants::ROW_TEXT_COLOR_DISABLED
+ : TimelineConstants::ROW_TEXT_COLOR));
painter->drawText(offset + 35, size().height() * .5 + 4, tr("%1").arg(m_label));
// Shy, eye, lock BG (to hide the label when overlapping)
- painter->fillRect(QRect(size().width() - 53, 0, 53, size().height() - 1), bgColor);
+ painter->fillRect(QRect(m_treeWidth - 53, 0, 53, size().height() - 1), bgColor);
// Shy, eye, lock
static const QPixmap pixEmpty = QPixmap(":/images/Toggle-Empty.png");
static const QPixmap pixShy = QPixmap(":/images/Toggle-Shy.png");
static const QPixmap pixHide = QPixmap(":/images/Toggle-HideShow.png");
static const QPixmap pixLock = QPixmap(":/images/Toggle-Lock.png");
- if (m_rowType != RowType::Property) {
+ if (!m_isProperty && m_rowType != OBJTYPE_SCENE) {
painter->drawPixmap(m_rectShy , m_shy ? pixShy : pixEmpty);
painter->drawPixmap(m_rectVisible, m_visible ? pixHide : pixEmpty);
painter->drawPixmap(m_rectLocked , m_locked ? pixLock : pixEmpty);
@@ -179,115 +220,29 @@ void RowTree::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, Q
// Candidate parent of a dragged row
if (m_moveTarget) {
painter->setPen(QPen(QColor(TimelineConstants::ROW_MOVER_COLOR), 1));
- painter->drawRect(QRect(1, 1, size().width()-2, size().height() - 3));
+ painter->drawRect(QRect(1, 1, m_treeWidth - 2, size().height() - 3));
}
}
-void RowTree::updatePropertyLabel()
+void RowTree::setTreeWidth(double w)
{
- switch (m_propertyType) {
- case PropertyType::Position:
- m_label = tr("Position");
- break;
- case PropertyType::Rotation:
- m_label = tr("Rotation");
- break;
- case PropertyType::Scale:
- m_label = tr("Scale");
- break;
- case PropertyType::Pivot:
- m_label = tr("Pivot");
- break;
- case PropertyType::Opacity:
- m_label = tr("Opacity");
- break;
- case PropertyType::EdgeTessellation:
- m_label = tr("Edge Tessellation");
- break;
- case PropertyType::InnerTessellation:
- m_label = tr("Inner Tessellation");
- break;
- case PropertyType::TextColor:
- m_label = tr("Text Color");
- break;
- case PropertyType::Leading:
- m_label = tr("Leading");
- break;
- case PropertyType::Tracking:
- m_label = tr("Tracking");
- break;
- case PropertyType::LightColor:
- m_label = tr("Light Color");
- break;
- case PropertyType::SpecularColor:
- m_label = tr("Specular Color");
- break;
- case PropertyType::AmbientColor:
- m_label = tr("Ambient Color");
- break;
- case PropertyType::Brightness:
- m_label = tr("Brightness");
- break;
- case PropertyType::ShadowDarkness:
- m_label = tr("Shadow Darkness");
- break;
- case PropertyType::ShadowSoftness:
- m_label = tr("Shadow Softness");
- break;
- case PropertyType::ShadowDepthBias:
- m_label = tr("Shadow Depth Bias");
- break;
- case PropertyType::FieldOfView:
- m_label = tr("Field Of View");
- break;
- case PropertyType::ClippingStart:
- m_label = tr("Clipping Start");
- break;
- case PropertyType::ClippingEnd:
- m_label = tr("Clipping End");
- break;
- case PropertyType::Left:
- m_label = tr("Left");
- break;
- case PropertyType::Top:
- m_label = tr("Top");
- break;
- case PropertyType::Width:
- m_label = tr("Width");
- break;
- case PropertyType::Height:
- m_label = tr("Height");
- break;
- case PropertyType::AO:
- m_label = tr("Ambient Occlusion");
- break;
- case PropertyType::AODistance:
- m_label = tr("AO Distance");
- break;
- case PropertyType::AOSoftness:
- m_label = tr("AO Softness");
- break;
- case PropertyType::AOThreshold:
- m_label = tr("AO Threshold");
- break;
- case PropertyType::AOSamplingRate:
- m_label = tr("AO Sampling Rate");
- break;
- case PropertyType::IBLBrightness:
- m_label = tr("IBL Brightness");
- break;
- case PropertyType::IBLHorizonCutoff:
- m_label = tr("IBL Horizon Cutoff");
- break;
- case PropertyType::IBLFOVAngle:
- m_label = tr("IBL FOV Angle");
- break;
- case PropertyType::ProbeCrossfade:
- m_label = tr("Probe Crossfade");
- break;
- default:
- m_label = tr("Unnamed Property");
- }
+ m_treeWidth = w;
+ update();
+}
+
+void RowTree::setBinding(ITimelineItemBinding *binding)
+{
+ m_binding = binding;
+
+ // update view (shy, visible, locked)
+ m_shy = m_binding->GetTimelineItem()->IsShy();
+ m_visible = m_binding->GetTimelineItem()->IsVisible();
+ m_locked = m_binding->GetTimelineItem()->IsLocked();
+}
+
+void RowTree::setPropBinding(ITimelineItemProperty *binding)
+{
+ m_PropBinding = binding;
}
void RowTree::setState(State state)
@@ -314,12 +269,12 @@ int RowTree::depth() const
return m_depth;
}
-RowType RowTree::rowType() const
+EStudioObjectType RowTree::rowType() const
{
return m_rowType;
}
-PropertyType RowTree::propertyType() const
+QString RowTree::propertyType() const
{
return m_propertyType;
}
@@ -378,36 +333,48 @@ void RowTree::removeChild(RowTree *child)
bool RowTree::hasPropertyChildren()
{
- return !m_childRows.empty() && m_childRows.first()->rowType() == RowType::Property;
+ return m_scene->rowManager()->hasProperties(this);
}
-bool RowTree::handleButtonsClick(QGraphicsSceneMouseEvent *event)
+// handle clicked control and return its type
+TreeControlType RowTree::getClickedControl(const QPointF &scenePos)
{
- if (rowType() == RowType::Property)
- return false;
-
- QPointF p = mapFromScene(event->scenePos().x(), event->scenePos().y());
+ if (m_isProperty || m_rowType == OBJTYPE_SCENE)
+ return TreeControlType::None;
- if (m_rectArrow.contains(p.x(), p.y())) {
+ QPointF p = mapFromScene(scenePos.x(), scenePos.y());
+ if (m_rectArrow.contains(p.x(), p.y()) && !m_locked) {
m_expanded = !m_expanded;
updateExpandStatus(m_expanded, true);
update();
- return true;
+ return TreeControlType::Arrow;
} else if (m_rectShy.contains(p.x(), p.y())) {
m_shy = !m_shy;
update();
- return true;
+
+ m_binding->GetTimelineItem()->SetShy(m_shy);
+
+ return TreeControlType::Shy;
} else if (m_rectVisible.contains(p.x(), p.y())) {
m_visible = !m_visible;
update();
- return true;
+
+ m_binding->GetTimelineItem()->SetVisible(m_visible);
+
+
+ return TreeControlType::Hide;
} else if (m_rectLocked.contains(p.x(), p.y())) {
- m_locked = !m_locked;
- update();
- return true;
+ updateLockRecursive(!m_locked);
+
+ m_binding->GetTimelineItem()->SetLocked(m_locked);
+
+ if (m_locked && selected())
+ m_scene->rowManager()->clearSelection();
+
+ return TreeControlType::Lock;
}
- return false;
+ return TreeControlType::None;
}
void RowTree::updateExpandStatus(bool expand, bool childrenOnly)
@@ -423,6 +390,17 @@ void RowTree::updateExpandStatus(bool expand, bool childrenOnly)
}
}
+void RowTree::updateLockRecursive(bool state)
+{
+ m_locked = state;
+ update();
+
+ if (!m_childRows.empty()) {
+ for (auto child : qAsConst(m_childRows))
+ child->updateLockRecursive(m_locked);
+ }
+}
+
bool RowTree::expanded() const
{
return m_expanded;
@@ -454,28 +432,59 @@ void RowTree::setMoveSourceRecursive(bool value)
bool RowTree::isContainer() const
{
- return m_rowType == RowType::Scene
- || m_rowType == RowType::Layer
- || m_rowType == RowType::Group
- || m_rowType == RowType::Component;
+ return m_rowType == OBJTYPE_SCENE
+ || m_rowType == OBJTYPE_LAYER
+ || m_rowType == OBJTYPE_GROUP
+ || m_rowType == OBJTYPE_COMPONENT;
+}
+
+bool RowTree::isProperty() const
+{
+ return m_isProperty;
}
-bool RowTree::empty() const {
+bool RowTree::empty() const
+{
return m_childRows.empty();
}
-void RowTree::setMoveTarget(bool value) {
+bool RowTree::selected() const
+{
+ return m_state == Selected;
+}
+
+void RowTree::setMoveTarget(bool value)
+{
m_moveTarget = value;
+ update();
}
-QList<RowTree *> RowTree::childRows() const {
+QList<RowTree *> RowTree::childRows() const
+{
return m_childRows;
}
-RowTimeline *RowTree::rowTimeline() const {
+RowTimeline *RowTree::rowTimeline() const
+{
return m_rowTimeline;
}
-QString RowTree::label() const {
+QString RowTree::label() const
+{
return m_label;
}
+
+bool RowTree::shy() const
+{
+ return m_shy;
+}
+
+bool RowTree::visible() const
+{
+ return m_visible;
+}
+
+bool RowTree::locked() const
+{
+ return m_locked;
+}
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTree.h b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTree.h
index 4b89a02a..cf2a5ab9 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTree.h
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTree.h
@@ -30,18 +30,25 @@
#define ROWTREE_H
#include "InteractiveTimelineItem.h"
+#include "TimelineGraphicsScene.h"
+#include "TimelineConstants.h"
#include "RowTypes.h"
+#include "StudioObjectTypes.h"
class RowTimeline;
class Ruler;
+class ITimelineItemBinding;
class RowTree : public InteractiveTimelineItem
{
Q_OBJECT
public:
- explicit RowTree(Ruler *ruler, RowType rowType = RowType::Layer, const QString &label = {});
- explicit RowTree(Ruler *ruler, PropertyType propType); // property row constructor
+ explicit RowTree(TimelineGraphicsScene *timelineScene,
+ EStudioObjectType rowType = OBJTYPE_UNKNOWN, const QString &label = {});
+ // property row constructor
+ explicit RowTree(TimelineGraphicsScene *timelineScene, const QString &propType);
+ ~RowTree();
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget = nullptr) override;
@@ -53,8 +60,10 @@ public:
void removeChild(RowTree *child);
void setMoveSourceRecursive(bool value);
void setMoveTarget(bool value);
-
- bool handleButtonsClick(QGraphicsSceneMouseEvent *event);
+ void setTreeWidth(double w);
+ void setBinding(ITimelineItemBinding *binding);
+ void setPropBinding(ITimelineItemProperty *binding); // for property rows
+ TreeControlType getClickedControl(const QPointF &scenePos);
bool hasPropertyChildren();
bool shy() const;
bool visible() const;
@@ -62,36 +71,43 @@ public:
bool expanded() const;
bool isDecendentOf(RowTree *row) const;
bool isContainer() const;
+ bool isProperty() const;
bool empty() const;
-
+ bool selected() const;
int depth() const;
int type() const;
- RowType rowType() const;
- PropertyType propertyType() const;
-
+ EStudioObjectType rowType() const;
+ QString propertyType() const;
RowTree *parentRow() const;
QList<RowTree *> childRows() const;
RowTimeline *rowTimeline() const;
QString label() const;
+ ITimelineItemBinding *getBinding() const;
+
private:
void updateExpandStatus(bool expand, bool childrenOnly = false);
void updateDepthRecursive();
- void updatePropertyLabel();
+ void updateLockRecursive(bool state);
RowTree *m_parentRow = nullptr;
RowTimeline *m_rowTimeline = nullptr;
int m_depth = 1;
+ int m_treeWidth = TimelineConstants::TREE_DEFAULT_W;
bool m_shy = false;
bool m_visible = true;
bool m_locked = false;
bool m_expanded = true;
bool m_moveSource = false;
bool m_moveTarget = false;
- RowType m_rowType = RowType::Layer;
- PropertyType m_propertyType = PropertyType::None; // for property rows
- QString m_label = 0;
+ bool m_isProperty = false;
+ TimelineGraphicsScene *m_scene;
+ EStudioObjectType m_rowType = OBJTYPE_UNKNOWN;
+ QString m_propertyType; // for property rows
+ QString m_label;
QList<RowTree *> m_childRows;
+ ITimelineItemBinding *m_binding;
+ ITimelineItemProperty *m_PropBinding; // for property rows
QRect m_rectArrow;
QRect m_rectShy;
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/Ruler.cpp b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/Ruler.cpp
index 17f26637..884f5fcd 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/Ruler.cpp
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/Ruler.cpp
@@ -33,7 +33,7 @@
Ruler::Ruler(TimelineItem *parent) : TimelineItem(parent)
{
- setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
}
void Ruler::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/Separator.cpp b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/Separator.cpp
deleted file mode 100644
index d76949b1..00000000
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/Separator.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 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 "Separator.h"
-#include "TimelineConstants.h"
-
-#include <QtGui/qpainter.h>
-#include <QtGui/qcursor.h>
-#include <QtWidgets/qapplication.h>
-
-Separator::Separator(TimelineItem *parent) : TimelineItem(parent)
-{
- setMinimumWidth(TimelineConstants::SEPARATOR_W);
- setMaximumWidth(TimelineConstants::SEPARATOR_W);
- setMaximumHeight(10000);
- // TODO: remove
-// setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
- setAcceptHoverEvents(true);
-}
-
-void Separator::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
-{
- // TODO: remove
-// painter->fillRect(0, 0, size().width(), size().height(), QColor("#666666"));
-}
-
-void Separator::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
-{
- qApp->setOverrideCursor(Qt::SplitHCursor);
-}
-
-void Separator::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
-{
- qApp->changeOverrideCursor(Qt::ArrowCursor);
- qApp->restoreOverrideCursor();
-}
-
-int Separator::type() const
-{
- // Enable the use of qgraphicsitem_cast with this item.
- return TypeSeparator;
-}
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/Separator.h b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/Separator.h
deleted file mode 100644
index e74fe0c5..00000000
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/Separator.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 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 SEPARATOR_H
-#define SEPARATOR_H
-
-#include "TimelineItem.h"
-
-class Separator : public TimelineItem
-{
- Q_OBJECT
-
-public:
- explicit Separator(TimelineItem *parent = nullptr);
-
- void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
- QWidget *widget = nullptr) override;
- int type() const;
-
- protected:
- void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
- void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override;
-};
-
-#endif // SEPARATOR_H
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/TimelineItem.h b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/TimelineItem.h
index 184795b7..bfbc42f1 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/TimelineItem.h
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/TimelineItem.h
@@ -45,8 +45,7 @@ public:
TypeRowTree,
TypeRowTimeline,
TypePlayHead,
- TypeRuler,
- TypeSeparator
+ TypeRuler
};
int type() const;
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/TimelineToolbar.cpp b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/TimelineToolbar.cpp
index 3855fb4a..3e9e6a05 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/TimelineToolbar.cpp
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/TimelineToolbar.cpp
@@ -46,7 +46,7 @@ TimelineToolbar::TimelineToolbar() : QToolBar()
// create actions
QAction *actionNewLayer = new QAction(iconLayer, tr("Add New Layer"));
QAction *actionDeleteLayer = new QAction(iconDelete, tr("Delete Layer"));
- m_actionTime = new QAction("0:00.000");
+ m_actionTime = new QAction(tr("0:00.000"));
QAction *actionFirst = new QAction(iconFirst, tr("Go to Timeline Start"));
QAction *actionStop = new QAction(iconStop, tr("Stop Playing"));
QAction *actionPlay = new QAction(iconPlay, tr("Start Playing"));
@@ -54,15 +54,13 @@ TimelineToolbar::TimelineToolbar() : QToolBar()
m_scaleSlider = new QSlider();
m_scaleSlider->setOrientation(Qt::Horizontal);
- m_scaleSlider->setMaximumWidth(200);
- m_scaleSlider->setMinimumWidth(100);
+ m_scaleSlider->setFixedWidth(100);
m_scaleSlider->setMinimum(1);
m_scaleSlider->setMaximum(8);
m_scaleSlider->setPageStep(.1);
m_scaleSlider->setValue(2);
- m_scaleSlider->setStyleSheet("background-color:0,0,0,0;");
- m_actionDuration = new QAction("0:20");
+ m_actionDuration = new QAction(tr("0:20"));
// connections
connect(actionNewLayer , &QAction::triggered, this, &TimelineToolbar::newLayerTriggered);
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/TreeHeader.cpp b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/TreeHeader.cpp
index 8766ff12..d65fc603 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/TreeHeader.cpp
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/TreeHeader.cpp
@@ -39,15 +39,69 @@ TreeHeader::TreeHeader(TimelineItem *parent) : TimelineItem(parent)
void TreeHeader::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
- static const QPixmap pixShy = QPixmap(":/images/Toggle-Shy.png");
- static const QPixmap pixHide = QPixmap(":/images/Toggle-HideShow.png");
- static const QPixmap pixLock = QPixmap(":/images/Toggle-Lock.png");
+ m_rectShy .setRect(m_treeWidth - 16 * 3.3, size().height() * .5 - 8, 16, 16);
+ m_rectVisible.setRect(m_treeWidth - 16 * 2.2, size().height() * .5 - 8, 16, 16);
+ m_rectLock .setRect(m_treeWidth - 16 * 1.1, size().height() * .5 - 8, 16, 16);
- double y = (size().height() - pixHide.height()) * .5;
+ static const QPixmap pixShy = QPixmap(":/images/Toggle-Shy.png");
+ static const QPixmap pixVisible = QPixmap(":/images/Toggle-HideShow.png");
+ static const QPixmap pixLock = QPixmap(":/images/Toggle-Lock.png");
- painter->drawPixmap(size().width() - pixHide.width() * 1.1 * 3, y, pixShy);
- painter->drawPixmap(size().width() - pixHide.width() * 1.1 * 2, y, pixHide);
- painter->drawPixmap(size().width() - pixHide.width() * 1.1 , y, pixLock);
+ QColor selectedColor = QColor(TimelineConstants::FILTER_BUTTON_SELECTED_COLOR);
+ if (m_shy)
+ painter->fillRect(m_rectShy, selectedColor);
+
+ if (m_visible)
+ painter->fillRect(m_rectVisible, selectedColor);
+
+ if (m_lock)
+ painter->fillRect(m_rectLock, selectedColor);
+
+ painter->drawPixmap(m_rectShy , pixShy);
+ painter->drawPixmap(m_rectVisible, pixVisible);
+ painter->drawPixmap(m_rectLock , pixLock);
+}
+
+void TreeHeader::setWidth(double w)
+{
+ m_treeWidth = w;
+ update();
+}
+
+TreeControlType TreeHeader::handleButtonsClick(const QPointF &scenePos)
+{
+ QPointF p = mapFromScene(scenePos.x(), scenePos.y());
+
+ if (m_rectShy.contains(p.x(), p.y())) {
+ m_shy = !m_shy;
+ update();
+ return TreeControlType::Shy;
+ } else if (m_rectVisible.contains(p.x(), p.y())) {
+ m_visible = !m_visible;
+ update();
+ return TreeControlType::Hide;
+ } else if (m_rectLock.contains(p.x(), p.y())) {
+ m_lock = !m_lock;
+ update();
+ return TreeControlType::Lock;
+ }
+
+ return TreeControlType::None;
+}
+
+bool TreeHeader::filterShy() const
+{
+ return m_shy;
+}
+
+bool TreeHeader::filterHidden() const
+{
+ return m_visible;
+}
+
+bool TreeHeader::filterLocked() const
+{
+ return m_lock;
}
int TreeHeader::type() const
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/TreeHeader.h b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/TreeHeader.h
index 2f90b8fc..1c2d703f 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/TreeHeader.h
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/TreeHeader.h
@@ -30,6 +30,8 @@
#define TREEHEADER_H
#include "TimelineItem.h"
+#include "TimelineConstants.h"
+#include "RowTypes.h"
class RowTimeline;
@@ -42,8 +44,22 @@ public:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget = nullptr) override;
-
+ void setWidth(double w);
+ TreeControlType handleButtonsClick(const QPointF &scenePos);
+ bool filterShy() const;
+ bool filterHidden() const;
+ bool filterLocked() const;
int type() const;
+
+ int m_treeWidth = TimelineConstants::TREE_DEFAULT_W;
+
+private:
+ bool m_shy = false;
+ bool m_visible = false;
+ bool m_lock = false;
+ QRect m_rectShy;
+ QRect m_rectVisible;
+ QRect m_rectLock;
};
#endif // TREEHEADER_H
diff --git a/src/Authoring/Studio/Qt3DStudio.pro b/src/Authoring/Studio/Qt3DStudio.pro
index 0add9a50..d4948a92 100644
--- a/src/Authoring/Studio/Qt3DStudio.pro
+++ b/src/Authoring/Studio/Qt3DStudio.pro
@@ -160,9 +160,9 @@ HEADERS += \
Application/DataInputSelectDlg.h \
Palettes/TimelineGraphicsView/TimelineWidget.h \
Palettes/TimelineGraphicsView/TimelineGraphicsScene.h \
+ Palettes/TimelineGraphicsView/TimelineSplitter.h \
Palettes/TimelineGraphicsView/ui/TimelineItem.h \
Palettes/TimelineGraphicsView/ui/InteractiveTimelineItem.h \
- Palettes/TimelineGraphicsView/ui/Separator.h \
Palettes/TimelineGraphicsView/ui/Ruler.h \
Palettes/TimelineGraphicsView/ui/PlayHead.h \
Palettes/TimelineGraphicsView/TimelineConstants.h \
@@ -381,9 +381,9 @@ SOURCES += \
Application/DataInputSelectDlg.cpp \
Palettes/TimelineGraphicsView/TimelineWidget.cpp \
Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp \
+ Palettes/TimelineGraphicsView/TimelineSplitter.cpp \
Palettes/TimelineGraphicsView/ui/TimelineItem.cpp \
Palettes/TimelineGraphicsView/ui/InteractiveTimelineItem.cpp \
- Palettes/TimelineGraphicsView/ui/Separator.cpp \
Palettes/TimelineGraphicsView/ui/PlayHead.cpp \
Palettes/TimelineGraphicsView/ui/Ruler.cpp \
Palettes/TimelineGraphicsView/ui/TimelineToolbar.cpp \
diff --git a/src/Authoring/Studio/style.qss b/src/Authoring/Studio/style.qss
index 3d567508..29e76ed2 100644
--- a/src/Authoring/Studio/style.qss
+++ b/src/Authoring/Studio/style.qss
@@ -361,3 +361,24 @@ DataInputSelectDlg::item:selected {
DataInputSelectDlg::item:hover {
background: #23516d;
}
+
+/* QSlider horizontal */
+QSlider {
+ background: transparent;
+}
+
+QSlider::groove:horizontal {
+ background: #dddddd;
+ height: 1px;
+}
+
+QSlider::handle:horizontal {
+ background: #999A9B;
+ width: 12px;
+ margin: -5px 0;
+ border-radius: 4px;
+}
+
+QSlider::handle:horizontal:hover {
+ background: #cccccc;
+}