Update the rest of the UI on property changes and update properties on node transform
This commit is contained in:
parent
2e6024b413
commit
c7d448225c
|
@ -344,11 +344,6 @@ bool CScriptTemplate::HasInGameModel(CPropertyStruct *pProperties)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool CScriptTemplate::HasPosition()
|
||||
{
|
||||
return (!mPositionIDString.IsEmpty());
|
||||
}
|
||||
|
||||
// ************ OBJECT TRACKING ************
|
||||
u32 CScriptTemplate::NumObjects() const
|
||||
{
|
||||
|
|
|
@ -116,7 +116,12 @@ public:
|
|||
CTexture* FindBillboardTexture(CPropertyStruct *pProperties);
|
||||
CCollisionMeshGroup* FindCollision(CPropertyStruct *pProperties);
|
||||
bool HasInGameModel(CPropertyStruct *pProperties);
|
||||
bool HasPosition();
|
||||
|
||||
inline bool HasName() const { return !mNameIDString.IsEmpty(); }
|
||||
inline bool HasPosition() const { return !mPositionIDString.IsEmpty(); }
|
||||
inline bool HasRotation() const { return !mRotationIDString.IsEmpty(); }
|
||||
inline bool HasScale() const { return !mScaleIDString.IsEmpty(); }
|
||||
inline bool HasActive() const { return !mActiveIDString.IsEmpty(); }
|
||||
|
||||
// Object Tracking
|
||||
u32 NumObjects() const;
|
||||
|
|
|
@ -8,8 +8,6 @@
|
|||
#include <Math/CTransform4f.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <gtc/quaternion.hpp>
|
||||
#include <gtx/transform.hpp>
|
||||
|
||||
u32 CSceneNode::smNumNodes = 0;
|
||||
CColor CSceneNode::skSelectionTint = CColor::Integral(39, 154, 167);
|
||||
|
|
|
@ -54,11 +54,12 @@ public:
|
|||
explicit CSceneNode(CScene *pScene, CSceneNode *pParent = 0);
|
||||
virtual ~CSceneNode();
|
||||
virtual ENodeType NodeType() = 0;
|
||||
virtual void PostLoad() {}
|
||||
virtual void OnTransformed() {}
|
||||
virtual void AddToRenderer(CRenderer* /*pRenderer*/, const SViewInfo& /*ViewInfo*/) {}
|
||||
virtual void DrawSelection();
|
||||
virtual void RayAABoxIntersectTest(CRayCollisionTester& Tester, const SViewInfo& ViewInfo);
|
||||
virtual SRayIntersection RayNodeIntersectTest(const CRay& Ray, u32 AssetID, const SViewInfo& ViewInfo) = 0;
|
||||
virtual void PostLoad() {}
|
||||
virtual bool AllowsTranslate() const { return true; }
|
||||
virtual bool AllowsRotate() const { return true; }
|
||||
virtual bool AllowsScale() const { return true; }
|
||||
|
|
|
@ -18,7 +18,7 @@ CScriptNode::CScriptNode(CScene *pScene, CSceneNode *pParent, CScriptObject *pOb
|
|||
|
||||
// Evaluate instance
|
||||
mpInstance = pObject;
|
||||
mpActiveModel = nullptr;
|
||||
SetActiveModel(nullptr);
|
||||
mpBillboard = nullptr;
|
||||
mpCollisionNode = new CCollisionNode(pScene, this);
|
||||
mpCollisionNode->SetInheritance(true, true, false);
|
||||
|
@ -37,7 +37,7 @@ CScriptNode::CScriptNode(CScene *pScene, CSceneNode *pParent, CScriptObject *pOb
|
|||
SetName("[" + pTemp->Name() + "] " + mpInstance->InstanceName());
|
||||
|
||||
// Determine display assets
|
||||
mpActiveModel = mpInstance->GetDisplayModel();
|
||||
SetActiveModel(mpInstance->GetDisplayModel());
|
||||
mpBillboard = mpInstance->GetBillboard();
|
||||
mpCollisionNode->SetCollision(mpInstance->GetCollision());
|
||||
|
||||
|
@ -66,11 +66,6 @@ CScriptNode::CScriptNode(CScene *pScene, CSceneNode *pParent, CScriptObject *pOb
|
|||
SetName("ScriptNode - NO INSTANCE");
|
||||
}
|
||||
|
||||
if (mpActiveModel)
|
||||
mLocalAABox = mpActiveModel->AABox();
|
||||
else
|
||||
mLocalAABox = CAABox::skOne;
|
||||
|
||||
mpExtra = CScriptExtra::CreateExtra(this);
|
||||
}
|
||||
|
||||
|
@ -79,6 +74,26 @@ ENodeType CScriptNode::NodeType()
|
|||
return eScriptNode;
|
||||
}
|
||||
|
||||
void CScriptNode::OnTransformed()
|
||||
{
|
||||
if (mpExtra)
|
||||
mpExtra->OnTransformed();
|
||||
|
||||
if (mpInstance)
|
||||
{
|
||||
CScriptTemplate *pTemplate = Template();
|
||||
|
||||
if (pTemplate->HasPosition() && LocalPosition() != mpInstance->Position())
|
||||
mpInstance->SetPosition(LocalPosition());
|
||||
|
||||
if (pTemplate->HasRotation() && LocalRotation().ToEuler() != mpInstance->Rotation())
|
||||
mpInstance->SetRotation(LocalRotation().ToEuler());
|
||||
|
||||
if (pTemplate->HasScale() && LocalScale() != mpInstance->Scale())
|
||||
mpInstance->SetScale(LocalScale());
|
||||
}
|
||||
}
|
||||
|
||||
void CScriptNode::AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo)
|
||||
{
|
||||
if (!mpInstance) return;
|
||||
|
@ -389,7 +404,7 @@ void CScriptNode::PropertyModified(IProperty *pProp)
|
|||
if (pProp->Type() == eCharacterProperty)
|
||||
{
|
||||
mpInstance->EvaluateDisplayModel();
|
||||
mpActiveModel = mpInstance->GetDisplayModel();
|
||||
SetActiveModel(mpInstance->GetDisplayModel());
|
||||
}
|
||||
else if (pProp->Type() == eFileProperty)
|
||||
{
|
||||
|
@ -398,7 +413,7 @@ void CScriptNode::PropertyModified(IProperty *pProp)
|
|||
if (pFile->AcceptsExtension("CMDL") || pFile->AcceptsExtension("ANCS") || pFile->AcceptsExtension("CHAR"))
|
||||
{
|
||||
mpInstance->EvaluateDisplayModel();
|
||||
mpActiveModel = mpInstance->GetDisplayModel();
|
||||
SetActiveModel(mpInstance->GetDisplayModel());
|
||||
}
|
||||
else if (pFile->AcceptsExtension("TXTR"))
|
||||
{
|
||||
|
@ -415,10 +430,20 @@ void CScriptNode::PropertyModified(IProperty *pProp)
|
|||
// Update other editor properties
|
||||
if (mpInstance->IsEditorProperty(pProp))
|
||||
{
|
||||
SetName("[" + mpInstance->Template()->Name() + "] " + mpInstance->InstanceName());
|
||||
mPosition = mpInstance->Position();
|
||||
mRotation = CQuaternion::FromEuler(mpInstance->Rotation());
|
||||
mScale = mpInstance->Scale();
|
||||
CScriptTemplate *pTemplate = Template();
|
||||
|
||||
if (pTemplate->HasName())
|
||||
SetName("[" + mpInstance->Template()->Name() + "] " + mpInstance->InstanceName());
|
||||
|
||||
if (pTemplate->HasPosition())
|
||||
mPosition = mpInstance->Position();
|
||||
|
||||
if (pTemplate->HasRotation())
|
||||
mRotation = CQuaternion::FromEuler(mpInstance->Rotation());
|
||||
|
||||
if (pTemplate->HasScale())
|
||||
mScale = mpInstance->Scale();
|
||||
|
||||
MarkTransformChanged();
|
||||
|
||||
SetLightLayerIndex(mpLightParameters->LightLayerIndex());
|
||||
|
@ -460,7 +485,7 @@ void CScriptNode::UpdatePreviewVolume()
|
|||
|
||||
void CScriptNode::GeneratePosition()
|
||||
{
|
||||
if (!mHasValidPosition)
|
||||
if (!mHasValidPosition)
|
||||
{
|
||||
// Default to center of the active area; this is to preven recursion issues
|
||||
CTransform4f& AreaTransform = mpScene->GetActiveArea()->GetTransform();
|
||||
|
@ -569,6 +594,13 @@ CVector2f CScriptNode::BillboardScale() const
|
|||
}
|
||||
|
||||
// ************ PROTECTED ************
|
||||
void CScriptNode::SetActiveModel(CModel *pModel)
|
||||
{
|
||||
mpActiveModel = pModel;
|
||||
mLocalAABox = (pModel ? pModel->AABox() : CAABox::skOne);
|
||||
MarkTransformChanged();
|
||||
}
|
||||
|
||||
void CScriptNode::CalculateTransform(CTransform4f& rOut) const
|
||||
{
|
||||
CScriptTemplate *pTemp = Template();
|
||||
|
|
|
@ -27,6 +27,7 @@ class CScriptNode : public CSceneNode
|
|||
public:
|
||||
CScriptNode(CScene *pScene, CSceneNode *pParent = 0, CScriptObject *pObject = 0);
|
||||
ENodeType NodeType();
|
||||
void OnTransformed();
|
||||
void AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo);
|
||||
void Draw(FRenderOptions Options, int ComponentIndex, const SViewInfo& ViewInfo);
|
||||
void DrawSelection();
|
||||
|
@ -51,6 +52,7 @@ public:
|
|||
CVector2f BillboardScale() const;
|
||||
|
||||
protected:
|
||||
void SetActiveModel(CModel *pModel);
|
||||
void CalculateTransform(CTransform4f& rOut) const;
|
||||
};
|
||||
|
||||
|
|
|
@ -53,7 +53,6 @@ INodeEditor::INodeEditor(QWidget *pParent)
|
|||
connect(mGizmoActions[2], SIGNAL(triggered()), this, SLOT(OnRotateTriggered()));
|
||||
connect(mGizmoActions[3], SIGNAL(triggered()), this, SLOT(OnScaleTriggered()));
|
||||
connect(mpTransformCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(OnTransformSpaceChanged(int)));
|
||||
connect(this, SIGNAL(SelectionModified()), this, SLOT(OnSelectionModified()));
|
||||
}
|
||||
|
||||
INodeEditor::~INodeEditor()
|
||||
|
@ -232,6 +231,20 @@ void INodeEditor::ExitPickMode()
|
|||
}
|
||||
}
|
||||
|
||||
void INodeEditor::NotifySelectionModified()
|
||||
{
|
||||
UpdateSelectionUI();
|
||||
emit SelectionModified();
|
||||
}
|
||||
|
||||
void INodeEditor::NotifySelectionTransformed()
|
||||
{
|
||||
foreach (CSceneNode *pNode, mSelection)
|
||||
pNode->OnTransformed();
|
||||
|
||||
emit SelectionTransformed();
|
||||
}
|
||||
|
||||
// ************ PUBLIC SLOTS ************
|
||||
void INodeEditor::OnGizmoMoved()
|
||||
{
|
||||
|
@ -302,8 +315,6 @@ void INodeEditor::OnViewportClick(const SRayIntersection& rkRayIntersect, QMouse
|
|||
ClearSelection();
|
||||
}
|
||||
}
|
||||
|
||||
UpdateSelectionUI();
|
||||
}
|
||||
|
||||
// In pick mode: process node pick
|
||||
|
@ -445,9 +456,3 @@ void INodeEditor::OnTransformSpaceChanged(int spaceIndex)
|
|||
|
||||
mGizmo.SetTransformSpace(space);
|
||||
}
|
||||
|
||||
void INodeEditor::OnSelectionModified()
|
||||
{
|
||||
UpdateTransformActionsEnabled();
|
||||
UpdateSelectionUI();
|
||||
}
|
||||
|
|
|
@ -77,6 +77,9 @@ public:
|
|||
void EnterPickMode(FNodeFlags AllowedNodes, bool ExitOnInvalidPick, bool EmitOnInvalidPick, bool EmitHoverOnButtonPress, QCursor Cursor = Qt::CrossCursor);
|
||||
void ExitPickMode();
|
||||
|
||||
void NotifySelectionModified();
|
||||
void NotifySelectionTransformed();
|
||||
|
||||
signals:
|
||||
void SelectionModified();
|
||||
void SelectionTransformed();
|
||||
|
@ -107,7 +110,6 @@ private slots:
|
|||
void OnRotateTriggered();
|
||||
void OnScaleTriggered();
|
||||
void OnTransformSpaceChanged(int spaceIndex);
|
||||
void OnSelectionModified();
|
||||
};
|
||||
|
||||
#endif // INODEEDITOR_H
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
CPropertyDelegate::CPropertyDelegate(QObject *pParent /*= 0*/)
|
||||
: QStyledItemDelegate(pParent)
|
||||
, mpModel(nullptr)
|
||||
, mRelaysBlocked(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -181,6 +182,8 @@ QWidget* CPropertyDelegate::createEditor(QWidget *pParent, const QStyleOptionVie
|
|||
|
||||
void CPropertyDelegate::setEditorData(QWidget *pEditor, const QModelIndex &rkIndex) const
|
||||
{
|
||||
BlockRelays(true);
|
||||
|
||||
if (pEditor)
|
||||
{
|
||||
// Set editor data for regular property
|
||||
|
@ -322,6 +325,8 @@ void CPropertyDelegate::setEditorData(QWidget *pEditor, const QModelIndex &rkInd
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
BlockRelays(false);
|
||||
}
|
||||
|
||||
void CPropertyDelegate::setModelData(QWidget *pEditor, QAbstractItemModel* /*pModel*/, const QModelIndex &rkIndex) const
|
||||
|
@ -402,6 +407,14 @@ void CPropertyDelegate::setModelData(QWidget *pEditor, QAbstractItemModel* /*pMo
|
|||
break;
|
||||
}
|
||||
|
||||
case eFileProperty:
|
||||
{
|
||||
WResourceSelector *pSelector = static_cast<WResourceSelector*>(pEditor);
|
||||
TFileProperty *pFile = static_cast<TFileProperty*>(pProp);
|
||||
pFile->Set(pSelector->GetResourceInfo());
|
||||
break;
|
||||
}
|
||||
|
||||
case eArrayProperty:
|
||||
{
|
||||
WIntegralSpinBox *pSpinBox = static_cast<WIntegralSpinBox*>(pEditor);
|
||||
|
@ -544,7 +557,7 @@ void CPropertyDelegate::SetCharacterEditorData(QWidget *pEditor, const QModelInd
|
|||
|
||||
if (Type == eFileProperty)
|
||||
{
|
||||
static_cast<WResourceSelector*>(pEditor)->SetResource(Params.AnimSet());
|
||||
static_cast<WResourceSelector*>(pEditor)->SetResource(Params.AnimSet());
|
||||
}
|
||||
|
||||
else if (Type == eEnumProperty)
|
||||
|
@ -569,6 +582,10 @@ void CPropertyDelegate::SetCharacterModelData(QWidget *pEditor, const QModelInde
|
|||
if (Type == eFileProperty)
|
||||
{
|
||||
Params.SetResource( static_cast<WResourceSelector*>(pEditor)->GetResource() );
|
||||
// Reset all other parameters to 0
|
||||
Params.SetNodeIndex(0);
|
||||
for (u32 iUnk = 0; iUnk < 4; iUnk++)
|
||||
Params.SetUnknown(iUnk, 0);
|
||||
}
|
||||
|
||||
else if (Type == eEnumProperty)
|
||||
|
@ -583,6 +600,14 @@ void CPropertyDelegate::SetCharacterModelData(QWidget *pEditor, const QModelInde
|
|||
}
|
||||
|
||||
pProp->Set(Params);
|
||||
|
||||
// If we just updated the resource, make sure all the sub-properties of the character are flagged as changed.
|
||||
// We want to do this -after- updating the anim params on the property, which is why we have a second type check.
|
||||
if (Type == eFileProperty)
|
||||
{
|
||||
QModelIndex ParentIndex = rkIndex.parent();
|
||||
mpModel->dataChanged(mpModel->index(1, 1, ParentIndex), mpModel->index(mpModel->rowCount(ParentIndex) - 1, 1, ParentIndex));
|
||||
}
|
||||
}
|
||||
|
||||
EPropertyType CPropertyDelegate::DetermineCharacterPropType(EGame Game, const QModelIndex& rkIndex) const
|
||||
|
@ -611,5 +636,6 @@ void CPropertyDelegate::WidgetEdited(QWidget *pWidget, const QModelIndex& rkInde
|
|||
{
|
||||
// This slot is used to update property values as they're being updated so changes can be
|
||||
// reflected in realtime in other parts of the application.
|
||||
setModelData(pWidget, mpModel, rkIndex);
|
||||
if (!mRelaysBlocked)
|
||||
setModelData(pWidget, mpModel, rkIndex);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ class CPropertyDelegate : public QStyledItemDelegate
|
|||
Q_OBJECT
|
||||
|
||||
CPropertyModel *mpModel;
|
||||
mutable bool mRelaysBlocked;
|
||||
|
||||
public:
|
||||
CPropertyDelegate(QObject *pParent = 0);
|
||||
|
@ -26,6 +27,9 @@ public:
|
|||
public slots:
|
||||
void WidgetEdited(QWidget *pWidget, const QModelIndex& rkIndex);
|
||||
|
||||
protected:
|
||||
void BlockRelays(bool Block) const { mRelaysBlocked = Block; }
|
||||
|
||||
signals:
|
||||
void PropertyEdited(const QModelIndex& rkIndex, bool IsDone) const;
|
||||
};
|
||||
|
|
|
@ -284,9 +284,18 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const
|
|||
{
|
||||
if (!(rkIndex.internalId() & 0x1))
|
||||
{
|
||||
// Add name
|
||||
IProperty *pProp = PropertyForIndex(rkIndex, false);
|
||||
QString DisplayText = data(rkIndex, Qt::DisplayRole).toString();
|
||||
QString Text = QString("<b>%1</b> <i>(%2)</i>").arg(DisplayText).arg(TO_QSTRING(PropEnumToPropString(pProp->Type())));
|
||||
|
||||
// Add uncooked notification
|
||||
if (pProp->Template()->CookPreference() == eNeverCook)
|
||||
{
|
||||
Text += "<br/><b>This is an uncooked property.</b>";
|
||||
}
|
||||
|
||||
// Add description
|
||||
TString Desc = pProp->Template()->Description();
|
||||
if (!Desc.IsEmpty()) Text += "<br/>" + TO_QSTRING(Desc);
|
||||
return Text;
|
||||
|
|
|
@ -16,7 +16,7 @@ CPropertyView::CPropertyView(QWidget *pParent)
|
|||
|
||||
connect(mpModel, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(SetPersistentEditors(QModelIndex)));
|
||||
connect(this, SIGNAL(expanded(QModelIndex)), this, SLOT(SetPersistentEditors(QModelIndex)));
|
||||
connect(mpDelegate, SIGNAL(PropertyEdited(QModelIndex,bool)), this, SIGNAL(PropertyModified(QModelIndex,bool)));
|
||||
connect(mpDelegate, SIGNAL(PropertyEdited(QModelIndex,bool)), this, SLOT(OnPropertyModified(QModelIndex,bool)));
|
||||
}
|
||||
|
||||
void CPropertyView::setModel(QAbstractItemModel *pModel)
|
||||
|
@ -38,30 +38,33 @@ bool CPropertyView::event(QEvent *pEvent)
|
|||
{
|
||||
if (pEvent->type() == QEvent::ToolTip)
|
||||
{
|
||||
QPoint MousePos = mapFromGlobal(QCursor::pos());
|
||||
QModelIndex Index = indexAt(MousePos);
|
||||
QString Desc = mpModel->data(Index, Qt::ToolTipRole).toString();
|
||||
QPoint MousePos = QCursor::pos();
|
||||
QModelIndex Index = indexAt(viewport()->mapFromGlobal(MousePos));
|
||||
|
||||
if (!Desc.isEmpty())
|
||||
if (Index.isValid())
|
||||
{
|
||||
QToolTip::showText(MousePos, Desc, this);
|
||||
pEvent->accept();
|
||||
}
|
||||
else
|
||||
{
|
||||
QToolTip::hideText();
|
||||
pEvent->ignore();
|
||||
QString Desc = mpModel->data(Index, Qt::ToolTipRole).toString();
|
||||
|
||||
if (!Desc.isEmpty())
|
||||
{
|
||||
QToolTip::showText(MousePos, Desc, this);
|
||||
pEvent->accept();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
QToolTip::hideText();
|
||||
pEvent->ignore();
|
||||
return true;
|
||||
}
|
||||
|
||||
else return QTreeView::event(pEvent);
|
||||
}
|
||||
|
||||
void CPropertyView::SetBaseStruct(CPropertyStruct *pStruct)
|
||||
void CPropertyView::SetObject(CScriptObject *pObj)
|
||||
{
|
||||
mpModel->SetBaseStruct(pStruct);
|
||||
mpObject = pObj;
|
||||
mpModel->SetBaseStruct(pObj ? pObj->Properties() : nullptr);
|
||||
SetPersistentEditors(QModelIndex());
|
||||
|
||||
// Auto-expand EditorProperties
|
||||
|
@ -71,6 +74,42 @@ void CPropertyView::SetBaseStruct(CPropertyStruct *pStruct)
|
|||
expand(Index);
|
||||
}
|
||||
|
||||
void CPropertyView::UpdateEditorProperties(const QModelIndex& rkParent)
|
||||
{
|
||||
// Iterate over all properties and update if they're an editor property. Ignore structs unless they're EditorProperties or a single struct.
|
||||
for (int iRow = 0; iRow < mpModel->rowCount(rkParent); iRow++)
|
||||
{
|
||||
QModelIndex Index0 = mpModel->index(iRow, 0, rkParent);
|
||||
QModelIndex Index1 = mpModel->index(iRow, 1, rkParent);
|
||||
IProperty *pProp = mpModel->PropertyForIndex(Index0, false);
|
||||
|
||||
if (pProp)
|
||||
{
|
||||
if (pProp->Type() == eStructProperty)
|
||||
{
|
||||
CStructTemplate *pStruct = static_cast<CStructTemplate*>(pProp->Template());
|
||||
|
||||
if (pStruct->IsSingleProperty() || pStruct->PropertyID() == 0x255A4580)
|
||||
UpdateEditorProperties(Index0);
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
else if (mpObject->IsEditorProperty(pProp))
|
||||
{
|
||||
mpModel->dataChanged(Index1, Index1);
|
||||
|
||||
if (mpModel->rowCount(Index0) != 0)
|
||||
{
|
||||
QModelIndex SubIndexA = mpModel->index(0, 1, Index0);
|
||||
QModelIndex SubIndexB = mpModel->index(mpModel->rowCount(Index0) - 1, 1, Index0);
|
||||
mpModel->dataChanged(SubIndexA, SubIndexB);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPropertyView::SetPersistentEditors(const QModelIndex& rkParent)
|
||||
{
|
||||
u32 NumChildren = mpModel->rowCount(rkParent);
|
||||
|
@ -96,6 +135,7 @@ void CPropertyView::SetPersistentEditors(const QModelIndex& rkParent)
|
|||
Type = eBoolProperty;
|
||||
}
|
||||
|
||||
|
||||
switch (Type)
|
||||
{
|
||||
case eBoolProperty:
|
||||
|
@ -114,3 +154,37 @@ void CPropertyView::SetPersistentEditors(const QModelIndex& rkParent)
|
|||
}
|
||||
}
|
||||
|
||||
void CPropertyView::ClosePersistentEditors(const QModelIndex& rkIndex)
|
||||
{
|
||||
u32 NumChildren = mpModel->rowCount(rkIndex);
|
||||
|
||||
for (u32 iChild = 0; iChild < NumChildren; iChild++)
|
||||
{
|
||||
QModelIndex ChildIndex = rkIndex.child(iChild, 1);
|
||||
closePersistentEditor(ChildIndex);
|
||||
|
||||
if (mpModel->rowCount(ChildIndex) != 0)
|
||||
ClosePersistentEditors(ChildIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void CPropertyView::OnPropertyModified(const QModelIndex &rkIndex, bool IsDone)
|
||||
{
|
||||
// Check for a resource being changed on a character property. If that's the case we need to remake the persistent editors.
|
||||
if (rkIndex.internalId() & 0x1)
|
||||
{
|
||||
if (mpModel->PropertyForIndex(rkIndex, true)->Type() == eCharacterProperty)
|
||||
{
|
||||
EGame Game = static_cast<TCharacterProperty*>(mpModel->PropertyForIndex(rkIndex, true))->Get().Version();
|
||||
|
||||
if (mpDelegate->DetermineCharacterPropType(Game, rkIndex) == eFileProperty)
|
||||
{
|
||||
QModelIndex Parent = rkIndex.parent();
|
||||
ClosePersistentEditors(Parent);
|
||||
SetPersistentEditors(Parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
emit PropertyModified(rkIndex, IsDone);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "CPropertyModel.h"
|
||||
#include "CPropertyDelegate.h"
|
||||
#include <Core/Resource/Script/CScriptObject.h>
|
||||
#include <QTreeView>
|
||||
|
||||
class CPropertyView : public QTreeView
|
||||
|
@ -11,20 +12,24 @@ class CPropertyView : public QTreeView
|
|||
|
||||
CPropertyModel *mpModel;
|
||||
CPropertyDelegate *mpDelegate;
|
||||
CScriptObject *mpObject;
|
||||
|
||||
public:
|
||||
CPropertyView(QWidget *pParent = 0);
|
||||
void setModel(QAbstractItemModel *pModel);
|
||||
bool event(QEvent *pEvent);
|
||||
void SetBaseStruct(CPropertyStruct *pStruct);
|
||||
void SetObject(CScriptObject *pObj);
|
||||
void UpdateEditorProperties(const QModelIndex& rkParent);
|
||||
|
||||
inline CPropertyModel* PropertyModel() const { return mpModel; }
|
||||
|
||||
public slots:
|
||||
void SetPersistentEditors(const QModelIndex& rkIndex);
|
||||
void ClosePersistentEditors(const QModelIndex& rkIndex);
|
||||
void OnPropertyModified(const QModelIndex& rkIndex, bool IsDone);
|
||||
|
||||
signals:
|
||||
void PropertyModified(const QModelIndex& rkIndex, bool IsDone);
|
||||
void PropertyModified(const QModelIndex &rkIndex, bool IsDone);
|
||||
};
|
||||
|
||||
#endif // CPROPERTYVIEW_H
|
||||
|
|
|
@ -17,13 +17,13 @@ TestDialog::TestDialog(QWidget *parent) :
|
|||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
CTemplateLoader::LoadGameTemplates(eCorruption);
|
||||
/*CTemplateLoader::LoadGameTemplates(eCorruption);
|
||||
CMasterTemplate *pMaster = CMasterTemplate::GetMasterForGame(eCorruption);
|
||||
CScriptTemplate *pTemp = pMaster->TemplateByID("PCKP");
|
||||
|
||||
CPropertyStruct *pBase = static_cast<CPropertyStruct*>(pTemp->BaseStruct()->InstantiateProperty(nullptr));
|
||||
ui->treeView->setItemDelegate(new CPropertyDelegate(ui->treeView));
|
||||
ui->treeView->SetBaseStruct(pBase);
|
||||
ui->treeView->SetObject(pBase);*/
|
||||
}
|
||||
|
||||
TestDialog::~TestDialog()
|
||||
|
|
|
@ -27,7 +27,7 @@ void CClearSelectionCommand::undo()
|
|||
}
|
||||
|
||||
mpEditor->RecalculateSelectionBounds();
|
||||
mpEditor->SelectionModified();
|
||||
mpEditor->NotifySelectionModified();
|
||||
}
|
||||
|
||||
void CClearSelectionCommand::redo()
|
||||
|
@ -38,5 +38,5 @@ void CClearSelectionCommand::redo()
|
|||
|
||||
mpSelection->clear();
|
||||
mpEditor->RecalculateSelectionBounds();
|
||||
mpEditor->SelectionModified();
|
||||
mpEditor->NotifySelectionModified();
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ void CDeselectNodeCommand::undo()
|
|||
}
|
||||
|
||||
mpEditor->ExpandSelectionBounds(mpNode);
|
||||
mpEditor->SelectionModified();
|
||||
mpEditor->NotifySelectionModified();
|
||||
}
|
||||
|
||||
void CDeselectNodeCommand::redo()
|
||||
|
@ -38,5 +38,5 @@ void CDeselectNodeCommand::redo()
|
|||
}
|
||||
|
||||
mpEditor->RecalculateSelectionBounds();
|
||||
mpEditor->SelectionModified();
|
||||
mpEditor->NotifySelectionModified();
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ void CInvertSelectionCommand::undo()
|
|||
|
||||
// Update editor
|
||||
mpEditor->RecalculateSelectionBounds();
|
||||
mpEditor->SelectionModified();
|
||||
mpEditor->NotifySelectionModified();
|
||||
}
|
||||
|
||||
void CInvertSelectionCommand::redo()
|
||||
|
@ -52,5 +52,5 @@ void CInvertSelectionCommand::redo()
|
|||
|
||||
// Update editor
|
||||
mpEditor->RecalculateSelectionBounds();
|
||||
mpEditor->SelectionModified();
|
||||
mpEditor->NotifySelectionModified();
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ CRotateNodeCommand::CRotateNodeCommand(INodeEditor *pEditor, const QList<CSceneN
|
|||
mNodeList.push_back(rotate);
|
||||
}
|
||||
|
||||
mpEditor->SelectionTransformed();
|
||||
mpEditor->NotifySelectionTransformed();
|
||||
}
|
||||
|
||||
CRotateNodeCommand::~CRotateNodeCommand()
|
||||
|
@ -80,7 +80,7 @@ void CRotateNodeCommand::undo()
|
|||
}
|
||||
|
||||
mpEditor->RecalculateSelectionBounds();
|
||||
mpEditor->SelectionTransformed();
|
||||
mpEditor->NotifySelectionTransformed();
|
||||
mpEditor->UpdateGizmoUI();
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ void CRotateNodeCommand::redo()
|
|||
}
|
||||
|
||||
mpEditor->RecalculateSelectionBounds();
|
||||
mpEditor->SelectionTransformed();
|
||||
mpEditor->NotifySelectionTransformed();
|
||||
mpEditor->UpdateGizmoUI();
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ CScaleNodeCommand::CScaleNodeCommand(INodeEditor *pEditor, const QList<CSceneNod
|
|||
mNodeList.push_back(scale);
|
||||
}
|
||||
|
||||
mpEditor->SelectionTransformed();
|
||||
mpEditor->NotifySelectionTransformed();
|
||||
}
|
||||
|
||||
CScaleNodeCommand::~CScaleNodeCommand()
|
||||
|
@ -80,7 +80,7 @@ void CScaleNodeCommand::undo()
|
|||
}
|
||||
|
||||
mpEditor->RecalculateSelectionBounds();
|
||||
mpEditor->SelectionTransformed();
|
||||
mpEditor->NotifySelectionTransformed();
|
||||
mpEditor->UpdateGizmoUI();
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ void CScaleNodeCommand::redo()
|
|||
}
|
||||
|
||||
mpEditor->RecalculateSelectionBounds();
|
||||
mpEditor->SelectionTransformed();
|
||||
mpEditor->NotifySelectionTransformed();
|
||||
mpEditor->UpdateGizmoUI();
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ void CSelectAllCommand::undo()
|
|||
|
||||
// Update editor
|
||||
mpEditor->RecalculateSelectionBounds();
|
||||
mpEditor->SelectionModified();
|
||||
mpEditor->NotifySelectionModified();
|
||||
}
|
||||
|
||||
void CSelectAllCommand::redo()
|
||||
|
@ -52,5 +52,5 @@ void CSelectAllCommand::redo()
|
|||
|
||||
// Update editor
|
||||
mpEditor->RecalculateSelectionBounds();
|
||||
mpEditor->SelectionModified();
|
||||
mpEditor->NotifySelectionModified();
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ void CSelectNodeCommand::undo()
|
|||
}
|
||||
|
||||
mpEditor->RecalculateSelectionBounds();
|
||||
mpEditor->SelectionModified();
|
||||
mpEditor->NotifySelectionModified();
|
||||
}
|
||||
|
||||
void CSelectNodeCommand::redo()
|
||||
|
@ -38,5 +38,5 @@ void CSelectNodeCommand::redo()
|
|||
}
|
||||
|
||||
mpEditor->ExpandSelectionBounds(mpNode);
|
||||
mpEditor->SelectionModified();
|
||||
mpEditor->NotifySelectionModified();
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ CTranslateNodeCommand::CTranslateNodeCommand(INodeEditor *pEditor, const QList<C
|
|||
mNodeList.push_back(translate);
|
||||
}
|
||||
|
||||
mpEditor->SelectionTransformed();
|
||||
mpEditor->NotifySelectionTransformed();
|
||||
}
|
||||
|
||||
CTranslateNodeCommand::~CTranslateNodeCommand()
|
||||
|
@ -72,7 +72,7 @@ void CTranslateNodeCommand::undo()
|
|||
translate.pNode->SetPosition(translate.initialPos);
|
||||
|
||||
mpEditor->RecalculateSelectionBounds();
|
||||
mpEditor->SelectionTransformed();
|
||||
mpEditor->NotifySelectionTransformed();
|
||||
mpEditor->UpdateGizmoUI();
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,7 @@ void CTranslateNodeCommand::redo()
|
|||
translate.pNode->SetPosition(translate.newPos);
|
||||
|
||||
mpEditor->RecalculateSelectionBounds();
|
||||
mpEditor->SelectionTransformed();
|
||||
mpEditor->NotifySelectionTransformed();
|
||||
mpEditor->UpdateGizmoUI();
|
||||
}
|
||||
|
||||
|
|
|
@ -107,6 +107,11 @@ bool WResourceSelector::HasSupportedExtension(const CResourceInfo& rkRes)
|
|||
}
|
||||
|
||||
// ************ GETTERS ************
|
||||
CResourceInfo WResourceSelector::GetResourceInfo()
|
||||
{
|
||||
return mResource;
|
||||
}
|
||||
|
||||
CResource* WResourceSelector::GetResource()
|
||||
{
|
||||
return mResource.Load();
|
||||
|
@ -137,7 +142,7 @@ bool WResourceSelector::IsPreviewPanelEnabled()
|
|||
void WResourceSelector::SetResource(CResource *pRes)
|
||||
{
|
||||
if (pRes)
|
||||
SetResource(CResourceInfo(pRes->ResID(), CFourCC(pRes->Source().GetFileExtension())));
|
||||
SetResource(CResourceInfo(pRes->FullSource()));
|
||||
else
|
||||
SetResource(CResourceInfo());
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ public:
|
|||
bool HasSupportedExtension(const CResourceInfo& rkRes);
|
||||
|
||||
// Getters
|
||||
CResourceInfo GetResourceInfo();
|
||||
CResource* GetResource();
|
||||
QString GetText();
|
||||
bool IsEditButtonEnabled();
|
||||
|
|
|
@ -248,7 +248,9 @@ void CWorldEditor::UpdateSelectionUI()
|
|||
|
||||
QFontMetrics Metrics(ui->SelectionInfoLabel->font());
|
||||
SelectionText = Metrics.elidedText(SelectionText, Qt::ElideRight, ui->SelectionInfoFrame->width() - 10);
|
||||
ui->SelectionInfoLabel->setText(SelectionText);
|
||||
|
||||
if (ui->SelectionInfoLabel->text() != SelectionText)
|
||||
ui->SelectionInfoLabel->setText(SelectionText);
|
||||
|
||||
// Update gizmo stuff
|
||||
UpdateGizmoUI();
|
||||
|
|
|
@ -41,27 +41,30 @@ WModifyTab::~WModifyTab()
|
|||
void WModifyTab::SetEditor(CWorldEditor *pEditor)
|
||||
{
|
||||
mpWorldEditor = pEditor;
|
||||
connect(mpWorldEditor, SIGNAL(SelectionTransformed()), this, SLOT(OnWorldSelectionTransformed()));
|
||||
}
|
||||
|
||||
void WModifyTab::GenerateUI(QList<CSceneNode*>& Selection)
|
||||
{
|
||||
ClearUI();
|
||||
|
||||
if (Selection.size() == 1)
|
||||
{
|
||||
mpSelectedNode = Selection.front();
|
||||
|
||||
// todo: set up editing UI for Light Nodes
|
||||
if (mpSelectedNode->NodeType() == eScriptNode)
|
||||
if (mpSelectedNode != Selection.front())
|
||||
{
|
||||
ui->ObjectsTabWidget->show();
|
||||
CScriptNode *pScriptNode = static_cast<CScriptNode*>(mpSelectedNode);
|
||||
CScriptObject *pObj = pScriptNode->Object();
|
||||
mpSelectedNode = Selection.front();
|
||||
|
||||
// Set up UI
|
||||
ui->PropertyView->SetBaseStruct(pObj->Properties());
|
||||
mpInLinkModel->SetObject(pObj);
|
||||
mpOutLinkModel->SetObject(pObj);
|
||||
// todo: set up editing UI for Light Nodes
|
||||
if (mpSelectedNode->NodeType() == eScriptNode)
|
||||
{
|
||||
ui->ObjectsTabWidget->show();
|
||||
CScriptNode *pScriptNode = static_cast<CScriptNode*>(mpSelectedNode);
|
||||
CScriptObject *pObj = pScriptNode->Object();
|
||||
|
||||
// Set up UI
|
||||
ui->PropertyView->SetObject(pObj);
|
||||
mpInLinkModel->SetObject(pObj);
|
||||
mpOutLinkModel->SetObject(pObj);
|
||||
ui->LightGroupBox->hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,8 +75,14 @@ void WModifyTab::GenerateUI(QList<CSceneNode*>& Selection)
|
|||
void WModifyTab::ClearUI()
|
||||
{
|
||||
ui->ObjectsTabWidget->hide();
|
||||
ui->PropertyView->SetBaseStruct(nullptr);
|
||||
ui->PropertyView->SetObject(nullptr);
|
||||
ui->LightGroupBox->hide();
|
||||
mpSelectedNode = nullptr;
|
||||
}
|
||||
|
||||
void WModifyTab::OnWorldSelectionTransformed()
|
||||
{
|
||||
ui->PropertyView->UpdateEditorProperties(QModelIndex());
|
||||
}
|
||||
|
||||
void WModifyTab::OnPropertyModified(const QModelIndex& rkIndex, bool /*IsDone*/)
|
||||
|
@ -83,6 +92,10 @@ void WModifyTab::OnPropertyModified(const QModelIndex& rkIndex, bool /*IsDone*/)
|
|||
CScriptNode *pNode = static_cast<CScriptNode*>(mpSelectedNode);
|
||||
IProperty *pProperty = ui->PropertyView->PropertyModel()->PropertyForIndex(rkIndex, true);
|
||||
pNode->PropertyModified(pProperty);
|
||||
|
||||
// If this is the instance name property, then other parts of the UI need to be updated to reflect the new name.
|
||||
if (pNode->Object()->IsEditorProperty(pProperty) && pProperty->Type() == eStringProperty)
|
||||
mpWorldEditor->UpdateSelectionUI();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ public:
|
|||
void ClearUI();
|
||||
|
||||
public slots:
|
||||
void OnWorldSelectionTransformed();
|
||||
void OnPropertyModified(const QModelIndex& rkIndex, bool IsDone);
|
||||
|
||||
private:
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
<object ID="0x1C" template="Script/CameraShaker.xml"/>
|
||||
<object ID="0x1D" template="Script/ActorKeyframe.xml"/>
|
||||
<object ID="0x20" template="Script/Water.xml"/>
|
||||
<object ID="0x21" template="Script/Warwasp.xml"/>
|
||||
<object ID="0x21" template="Script/WarWasp.xml"/>
|
||||
<object ID="0x24" template="Script/SpacePirate.xml"/>
|
||||
<object ID="0x25" template="Script/FlyingPirate.xml"/>
|
||||
<object ID="0x26" template="Script/ElitePirate.xml"/>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ScriptTemplate version="4">
|
||||
<name>Warwasp</name>
|
||||
<name>WarWasp</name>
|
||||
<properties>
|
||||
<property ID="0x00" name="Name" type="string"/>
|
||||
<property ID="0x01" name="Unknown 1" type="long"/>
|
||||
|
|
Loading…
Reference in New Issue