Added Editor Properties widget at the top of every World Editor tab, made tons of backend changes to get it to work properly
This commit is contained in:
parent
8e1b66fa5a
commit
a46cd5446f
|
@ -218,7 +218,6 @@ SOURCES += \
|
||||||
Resource/Model/CStaticModel.cpp \
|
Resource/Model/CStaticModel.cpp \
|
||||||
Resource/Model/SSurface.cpp \
|
Resource/Model/SSurface.cpp \
|
||||||
Resource/Script/CMasterTemplate.cpp \
|
Resource/Script/CMasterTemplate.cpp \
|
||||||
Resource/Script/CScriptLayer.cpp \
|
|
||||||
Resource/Script/CScriptObject.cpp \
|
Resource/Script/CScriptObject.cpp \
|
||||||
Resource/Script/CScriptTemplate.cpp \
|
Resource/Script/CScriptTemplate.cpp \
|
||||||
Resource/CAnimationParameters.cpp \
|
Resource/CAnimationParameters.cpp \
|
||||||
|
|
|
@ -116,11 +116,11 @@ void CScriptCooker::WriteLayerMP1(CScriptLayer *pLayer)
|
||||||
{
|
{
|
||||||
u32 LayerStart = mpSCLY->Tell();
|
u32 LayerStart = mpSCLY->Tell();
|
||||||
mpSCLY->WriteByte(0); // Unknown value
|
mpSCLY->WriteByte(0); // Unknown value
|
||||||
mpSCLY->WriteLong(pLayer->GetNumObjects());
|
mpSCLY->WriteLong(pLayer->NumInstances());
|
||||||
|
|
||||||
for (u32 iInst = 0; iInst < pLayer->GetNumObjects(); iInst++)
|
for (u32 iInst = 0; iInst < pLayer->NumInstances(); iInst++)
|
||||||
{
|
{
|
||||||
CScriptObject *pInstance = pLayer->ObjectByIndex(iInst);
|
CScriptObject *pInstance = pLayer->InstanceByIndex(iInst);
|
||||||
WriteInstanceMP1(pInstance);
|
WriteInstanceMP1(pInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -572,7 +572,7 @@ void CAreaLoader::SetUpObjects()
|
||||||
if (!pLayer) break;
|
if (!pLayer) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u32 iObj = 0; iObj < pLayer->GetNumObjects(); iObj++)
|
for (u32 iObj = 0; iObj < pLayer->NumInstances(); iObj++)
|
||||||
{
|
{
|
||||||
// Add object to object map
|
// Add object to object map
|
||||||
CScriptObject *pObj = (*pLayer)[iObj];
|
CScriptObject *pObj = (*pLayer)[iObj];
|
||||||
|
|
|
@ -123,11 +123,11 @@ void CScriptLoader::ReadProperty(IProperty *pProp, u32 Size, IInputStream& SCLY)
|
||||||
|
|
||||||
case eArrayProperty: {
|
case eArrayProperty: {
|
||||||
CArrayProperty *pArrayCast = static_cast<CArrayProperty*>(pProp);
|
CArrayProperty *pArrayCast = static_cast<CArrayProperty*>(pProp);
|
||||||
u32 Size = SCLY.ReadLong();
|
int Size = SCLY.ReadLong();
|
||||||
|
|
||||||
pArrayCast->Resize(Size);
|
pArrayCast->Resize(Size);
|
||||||
|
|
||||||
for (u32 iElem = 0; iElem < Size; iElem++)
|
for (int iElem = 0; iElem < Size; iElem++)
|
||||||
{
|
{
|
||||||
if (mVersion < eEchoesDemo)
|
if (mVersion < eEchoesDemo)
|
||||||
LoadStructMP1(SCLY, static_cast<CPropertyStruct*>(pArrayCast->PropertyByIndex(iElem)), pArrayCast->SubStructTemplate());
|
LoadStructMP1(SCLY, static_cast<CPropertyStruct*>(pArrayCast->PropertyByIndex(iElem)), pArrayCast->SubStructTemplate());
|
||||||
|
@ -243,7 +243,7 @@ CScriptLayer* CScriptLoader::LoadLayerMP1(IInputStream &SCLY)
|
||||||
{
|
{
|
||||||
CScriptObject *pObj = LoadObjectMP1(SCLY);
|
CScriptObject *pObj = LoadObjectMP1(SCLY);
|
||||||
if (pObj)
|
if (pObj)
|
||||||
mpLayer->AddObject(pObj);
|
mpLayer->AddInstance(pObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Layer sizes are always a multiple of 32 - skip end padding before returning
|
// Layer sizes are always a multiple of 32 - skip end padding before returning
|
||||||
|
@ -391,7 +391,7 @@ CScriptLayer* CScriptLoader::LoadLayerMP2(IInputStream& SCLY)
|
||||||
{
|
{
|
||||||
CScriptObject *pObj = LoadObjectMP2(SCLY);
|
CScriptObject *pObj = LoadObjectMP2(SCLY);
|
||||||
if (pObj)
|
if (pObj)
|
||||||
mpLayer->AddObject(pObj);
|
mpLayer->AddInstance(pObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsSCGN)
|
if (IsSCGN)
|
||||||
|
|
|
@ -1,95 +0,0 @@
|
||||||
#include "CScriptLayer.h"
|
|
||||||
|
|
||||||
CScriptLayer::CScriptLayer()
|
|
||||||
{
|
|
||||||
mLayerName = "New Layer";
|
|
||||||
mActive = true;
|
|
||||||
mVisible = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
CScriptLayer::~CScriptLayer()
|
|
||||||
{
|
|
||||||
for (auto it = mObjects.begin(); it != mObjects.end(); it++)
|
|
||||||
delete *it;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ************* DATA MANIPULATION *************
|
|
||||||
void CScriptLayer::AddObject(CScriptObject* object)
|
|
||||||
{
|
|
||||||
mObjects.push_back(object);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CScriptLayer::DeleteObjectByIndex(u32 index)
|
|
||||||
{
|
|
||||||
delete mObjects[index];
|
|
||||||
mObjects.erase(mObjects.begin() + index, mObjects.begin() + index);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CScriptLayer::DeleteObjectByID(u32 ID)
|
|
||||||
{
|
|
||||||
for (auto it = mObjects.begin(); it != mObjects.end(); it++)
|
|
||||||
{
|
|
||||||
if ((*it)->InstanceID() == ID)
|
|
||||||
{
|
|
||||||
delete *it;
|
|
||||||
mObjects.erase(it, it);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CScriptLayer::Reserve(u32 amount)
|
|
||||||
{
|
|
||||||
mObjects.reserve(amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ************* GETTERS *************
|
|
||||||
TString CScriptLayer::Name()
|
|
||||||
{
|
|
||||||
return mLayerName;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CScriptLayer::IsActive()
|
|
||||||
{
|
|
||||||
return mActive;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CScriptLayer::IsVisible()
|
|
||||||
{
|
|
||||||
return mVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 CScriptLayer::GetNumObjects()
|
|
||||||
{
|
|
||||||
return mObjects.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
CScriptObject* CScriptLayer::ObjectByIndex(u32 index)
|
|
||||||
{
|
|
||||||
return mObjects[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
CScriptObject* CScriptLayer::ObjectByID(u32 ID)
|
|
||||||
{
|
|
||||||
for (auto it = mObjects.begin(); it != mObjects.end(); it++)
|
|
||||||
if ((*it)->InstanceID() == ID)
|
|
||||||
return *it;
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ************* SETTERS *************
|
|
||||||
void CScriptLayer::SetName(const TString& name)
|
|
||||||
{
|
|
||||||
mLayerName = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CScriptLayer::SetActive(bool active)
|
|
||||||
{
|
|
||||||
mActive = active;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CScriptLayer::SetVisible(bool visible)
|
|
||||||
{
|
|
||||||
mVisible = visible;
|
|
||||||
}
|
|
|
@ -1,5 +1,5 @@
|
||||||
#ifndef SSCRIPTLAYER_H
|
#ifndef CSCRIPTLAYER_H
|
||||||
#define SSCRIPTLAYER_H
|
#define CSCRIPTLAYER_H
|
||||||
|
|
||||||
#include "CScriptObject.h"
|
#include "CScriptObject.h"
|
||||||
#include <Common/types.h>
|
#include <Common/types.h>
|
||||||
|
@ -11,38 +11,85 @@ class CScriptLayer
|
||||||
TString mLayerName;
|
TString mLayerName;
|
||||||
bool mActive;
|
bool mActive;
|
||||||
bool mVisible;
|
bool mVisible;
|
||||||
std::vector<CScriptObject*> mObjects;
|
std::vector<CScriptObject*> mInstances;
|
||||||
public:
|
public:
|
||||||
CScriptLayer();
|
CScriptLayer()
|
||||||
~CScriptLayer();
|
: mLayerName("New Layer")
|
||||||
|
, mActive(true)
|
||||||
// Data Manipulation
|
, mVisible(true)
|
||||||
void AddObject(CScriptObject* object);
|
|
||||||
void DeleteObjectByIndex(u32 index);
|
|
||||||
void DeleteObjectByID(u32 ID);
|
|
||||||
void Reserve(u32 amount);
|
|
||||||
|
|
||||||
// Getters and Setters
|
|
||||||
TString Name();
|
|
||||||
bool IsActive();
|
|
||||||
bool IsVisible();
|
|
||||||
u32 GetNumObjects();
|
|
||||||
CScriptObject* ObjectByIndex(u32 index);
|
|
||||||
CScriptObject* ObjectByID(u32 ID);
|
|
||||||
|
|
||||||
void SetName(const TString& name);
|
|
||||||
void SetActive(bool active);
|
|
||||||
void SetVisible(bool visible);
|
|
||||||
|
|
||||||
// Operators
|
|
||||||
CScriptObject* operator[](u32 index);
|
|
||||||
};
|
|
||||||
|
|
||||||
// ************* INLINE FUNCTIONS *************
|
|
||||||
inline CScriptObject* CScriptLayer::operator[](u32 index)
|
|
||||||
{
|
{
|
||||||
return mObjects[index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~CScriptLayer()
|
||||||
|
{
|
||||||
|
for (auto it = mInstances.begin(); it != mInstances.end(); it++)
|
||||||
|
delete *it;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // SSCRIPTLAYER_H
|
// Data Manipulation
|
||||||
|
void AddInstance(CScriptObject *pObject)
|
||||||
|
{
|
||||||
|
mInstances.push_back(pObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveInstance(CScriptObject *pInstance)
|
||||||
|
{
|
||||||
|
for (auto it = mInstances.begin(); it != mInstances.end(); it++)
|
||||||
|
{
|
||||||
|
if (*it == pInstance)
|
||||||
|
{
|
||||||
|
mInstances.erase(it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveInstanceByIndex(u32 Index)
|
||||||
|
{
|
||||||
|
mInstances.erase(mInstances.begin() + Index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveInstanceByID(u32 ID)
|
||||||
|
{
|
||||||
|
for (auto it = mInstances.begin(); it != mInstances.end(); it++)
|
||||||
|
{
|
||||||
|
if ((*it)->InstanceID() == ID)
|
||||||
|
{
|
||||||
|
mInstances.erase(it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reserve(u32 Amount)
|
||||||
|
{
|
||||||
|
mInstances.reserve(Amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accessors
|
||||||
|
inline TString Name() const { return mLayerName; }
|
||||||
|
inline bool IsActive() const { return mActive; }
|
||||||
|
inline bool IsVisible() const { return mVisible; }
|
||||||
|
inline u32 NumInstances() const { return mInstances.size(); }
|
||||||
|
inline CScriptObject* InstanceByIndex(u32 Index) const { return mInstances[Index]; }
|
||||||
|
|
||||||
|
inline CScriptObject* InstanceByID(u32 ID) const
|
||||||
|
{
|
||||||
|
for (auto it = mInstances.begin(); it != mInstances.end(); it++)
|
||||||
|
{
|
||||||
|
if ((*it)->InstanceID() == ID)
|
||||||
|
return *it;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void SetName(const TString& rkName) { mLayerName = rkName; }
|
||||||
|
inline void SetActive(bool Active) { mActive = Active; }
|
||||||
|
inline void SetVisible(bool Visible) { mVisible = Visible; }
|
||||||
|
|
||||||
|
// Operators
|
||||||
|
CScriptObject* operator[](u32 Index) { return InstanceByIndex(Index); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CSCRIPTLAYER_H
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "CScriptObject.h"
|
#include "CScriptObject.h"
|
||||||
|
#include "CScriptLayer.h"
|
||||||
#include "CMasterTemplate.h"
|
#include "CMasterTemplate.h"
|
||||||
#include "Core/Resource/CAnimSet.h"
|
#include "Core/Resource/CAnimSet.h"
|
||||||
|
|
||||||
|
@ -69,6 +70,16 @@ bool CScriptObject::IsEditorProperty(IProperty *pProp)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CScriptObject::SetLayer(CScriptLayer *pLayer)
|
||||||
|
{
|
||||||
|
if (pLayer != mpLayer)
|
||||||
|
{
|
||||||
|
mpLayer->RemoveInstance(this);
|
||||||
|
mpLayer = pLayer;
|
||||||
|
mpLayer->AddInstance(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ************ GETTERS ************
|
// ************ GETTERS ************
|
||||||
IProperty* CScriptObject::PropertyByIndex(u32 index) const
|
IProperty* CScriptObject::PropertyByIndex(u32 index) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -50,6 +50,7 @@ public:
|
||||||
void EvaluateCollisionModel();
|
void EvaluateCollisionModel();
|
||||||
void EvaluateVolume();
|
void EvaluateVolume();
|
||||||
bool IsEditorProperty(IProperty *pProp);
|
bool IsEditorProperty(IProperty *pProp);
|
||||||
|
void SetLayer(CScriptLayer *pLayer);
|
||||||
|
|
||||||
CScriptTemplate* Template() const;
|
CScriptTemplate* Template() const;
|
||||||
CMasterTemplate* MasterTemplate() const;
|
CMasterTemplate* MasterTemplate() const;
|
||||||
|
@ -84,6 +85,12 @@ public:
|
||||||
CCollisionMeshGroup* GetCollision() const;
|
CCollisionMeshGroup* GetCollision() const;
|
||||||
EVolumeShape VolumeShape() const;
|
EVolumeShape VolumeShape() const;
|
||||||
float VolumeScale() const;
|
float VolumeScale() const;
|
||||||
|
|
||||||
|
TStringProperty* InstanceNameProperty() const { return mpInstanceName; }
|
||||||
|
TVector3Property* PositionProperty() const { return mpPosition; }
|
||||||
|
TVector3Property* RotationProperty() const { return mpRotation; }
|
||||||
|
TVector3Property* ScaleProperty() const { return mpScale; }
|
||||||
|
TBoolProperty* ActiveProperty() const { return mpActive; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CSCRIPTOBJECT_H
|
#endif // CSCRIPTOBJECT_H
|
||||||
|
|
|
@ -2,6 +2,11 @@
|
||||||
#include "IPropertyTemplate.h"
|
#include "IPropertyTemplate.h"
|
||||||
|
|
||||||
// ************ IProperty ************
|
// ************ IProperty ************
|
||||||
|
CPropertyStruct* IProperty::RootStruct()
|
||||||
|
{
|
||||||
|
return (mpParent ? mpParent->RootStruct() : Type() == eStructProperty ? static_cast<CPropertyStruct*>(this) : nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
IPropertyTemplate* IProperty::Template() const
|
IPropertyTemplate* IProperty::Template() const
|
||||||
{
|
{
|
||||||
return mpTemplate;
|
return mpTemplate;
|
||||||
|
@ -111,23 +116,23 @@ CPropertyStruct* CPropertyStruct::StructByIDString(const TIDString& rkStr) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ CArrayProperty ************
|
// ************ CArrayProperty ************
|
||||||
void CArrayProperty::Resize(u32 Size)
|
void CArrayProperty::Resize(int Size)
|
||||||
{
|
{
|
||||||
u32 OldSize = mProperties.size();
|
int OldSize = mProperties.size();
|
||||||
if (OldSize == Size) return;
|
if (OldSize == Size) return;
|
||||||
|
|
||||||
if (Size < OldSize)
|
if (Size < OldSize)
|
||||||
{
|
{
|
||||||
for (u32 i = mProperties.size() - 1; i >= Size; i--)
|
for (int iProp = mProperties.size() - 1; iProp >= Size; iProp--)
|
||||||
delete mProperties[i];
|
delete mProperties[iProp];
|
||||||
}
|
}
|
||||||
|
|
||||||
mProperties.resize(Size);
|
mProperties.resize(Size);
|
||||||
|
|
||||||
if (Size > OldSize)
|
if (Size > OldSize)
|
||||||
{
|
{
|
||||||
for (u32 i = OldSize; i < Size; i++)
|
for (int iProp = OldSize; iProp < Size; iProp++)
|
||||||
mProperties[i] = static_cast<CArrayTemplate*>(mpTemplate)->CreateSubStruct(this);
|
mProperties[iProp] = static_cast<CArrayTemplate*>(mpTemplate)->CreateSubStruct(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,8 @@ public:
|
||||||
inline CPropertyStruct* Parent() const { return mpParent; }
|
inline CPropertyStruct* Parent() const { return mpParent; }
|
||||||
inline void SetParent(CPropertyStruct *pParent) { mpParent = pParent; }
|
inline void SetParent(CPropertyStruct *pParent) { mpParent = pParent; }
|
||||||
|
|
||||||
|
CPropertyStruct* RootStruct();
|
||||||
|
|
||||||
// These functions can't be in the header to avoid circular includes with IPropertyTemplate.h
|
// These functions can't be in the header to avoid circular includes with IPropertyTemplate.h
|
||||||
IPropertyTemplate* Template() const;
|
IPropertyTemplate* Template() const;
|
||||||
TString Name() const;
|
TString Name() const;
|
||||||
|
@ -178,7 +180,7 @@ public:
|
||||||
inline void Reserve(u32 amount) { mProperties.reserve(amount); }
|
inline void Reserve(u32 amount) { mProperties.reserve(amount); }
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
void Resize(u32 Size);
|
void Resize(int Size);
|
||||||
CStructTemplate* SubStructTemplate() const;
|
CStructTemplate* SubStructTemplate() const;
|
||||||
TString ElementName() const;
|
TString ElementName() const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -116,12 +116,12 @@ void CScene::SetActiveArea(CGameArea *pArea)
|
||||||
for (u32 iLyr = 0; iLyr < NumLayers; iLyr++)
|
for (u32 iLyr = 0; iLyr < NumLayers; iLyr++)
|
||||||
{
|
{
|
||||||
CScriptLayer *pLayer = mpArea->GetScriptLayer(iLyr);
|
CScriptLayer *pLayer = mpArea->GetScriptLayer(iLyr);
|
||||||
u32 NumObjects = pLayer->GetNumObjects();
|
u32 NumObjects = pLayer->NumInstances();
|
||||||
mNodes[eScriptNode].reserve(mNodes[eScriptNode].size() + NumObjects);
|
mNodes[eScriptNode].reserve(mNodes[eScriptNode].size() + NumObjects);
|
||||||
|
|
||||||
for (u32 iObj = 0; iObj < NumObjects; iObj++)
|
for (u32 iObj = 0; iObj < NumObjects; iObj++)
|
||||||
{
|
{
|
||||||
CScriptObject *pObj = pLayer->ObjectByIndex(iObj);
|
CScriptObject *pObj = pLayer->InstanceByIndex(iObj);
|
||||||
CScriptNode *pNode = CreateScriptNode(pObj);
|
CScriptNode *pNode = CreateScriptNode(pObj);
|
||||||
pNode->BuildLightList(mpArea);
|
pNode->BuildLightList(mpArea);
|
||||||
|
|
||||||
|
@ -142,9 +142,9 @@ void CScene::SetActiveArea(CGameArea *pArea)
|
||||||
CScriptLayer *pGenLayer = mpArea->GetGeneratorLayer();
|
CScriptLayer *pGenLayer = mpArea->GetGeneratorLayer();
|
||||||
if (pGenLayer)
|
if (pGenLayer)
|
||||||
{
|
{
|
||||||
for (u32 iObj = 0; iObj < pGenLayer->GetNumObjects(); iObj++)
|
for (u32 iObj = 0; iObj < pGenLayer->NumInstances(); iObj++)
|
||||||
{
|
{
|
||||||
CScriptObject *pObj = pGenLayer->ObjectByIndex(iObj);
|
CScriptObject *pObj = pGenLayer->InstanceByIndex(iObj);
|
||||||
CScriptNode *pNode = CreateScriptNode(pObj);
|
CScriptNode *pNode = CreateScriptNode(pObj);
|
||||||
|
|
||||||
// Add to map
|
// Add to map
|
||||||
|
|
|
@ -191,6 +191,8 @@ void CScriptNode::Draw(FRenderOptions Options, int ComponentIndex, const SViewIn
|
||||||
{
|
{
|
||||||
glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ZERO, GL_ZERO);
|
glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ZERO, GL_ZERO);
|
||||||
glDepthMask(GL_TRUE);
|
glDepthMask(GL_TRUE);
|
||||||
|
CGraphics::UpdateVertexBlock();
|
||||||
|
CGraphics::UpdatePixelBlock();
|
||||||
CDrawUtil::DrawShadedCube(CColor::skTransparentPurple * TintColor(ViewInfo));
|
CDrawUtil::DrawShadedCube(CColor::skTransparentPurple * TintColor(ViewInfo));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,7 +137,9 @@ HEADERS += \
|
||||||
Undo/CEditScriptPropertyCommand.h \
|
Undo/CEditScriptPropertyCommand.h \
|
||||||
Undo/CResizeScriptArrayCommand.h \
|
Undo/CResizeScriptArrayCommand.h \
|
||||||
Undo/CBasicPropertyCommand.h \
|
Undo/CBasicPropertyCommand.h \
|
||||||
Undo/IUndoCommand.h
|
Undo/IUndoCommand.h \
|
||||||
|
WorldEditor/WEditorProperties.h \
|
||||||
|
Undo/CChangeLayerCommand.h
|
||||||
|
|
||||||
# Source Files
|
# Source Files
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
@ -191,7 +193,9 @@ SOURCES += \
|
||||||
WorldEditor/CInstancesModel.cpp \
|
WorldEditor/CInstancesModel.cpp \
|
||||||
Undo/CEditScriptPropertyCommand.cpp \
|
Undo/CEditScriptPropertyCommand.cpp \
|
||||||
Undo/CResizeScriptArrayCommand.cpp \
|
Undo/CResizeScriptArrayCommand.cpp \
|
||||||
Undo/CBasicPropertyCommand.cpp
|
Undo/CBasicPropertyCommand.cpp \
|
||||||
|
WorldEditor/WEditorProperties.cpp \
|
||||||
|
Undo/CChangeLayerCommand.cpp
|
||||||
|
|
||||||
# UI Files
|
# UI Files
|
||||||
FORMS += \
|
FORMS += \
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#define CONNECT_RELAY(Widget, Index, Signal) \
|
#define CONNECT_RELAY(Widget, Index, Signal) \
|
||||||
CPropertyRelay *pRelay = new CPropertyRelay(Widget, Index); \
|
CPropertyRelay *pRelay = new CPropertyRelay(Widget, Index); \
|
||||||
connect(Widget, SIGNAL(Signal), pRelay, SLOT(OnWidgetEdited())); \
|
connect(Widget, SIGNAL(Signal), pRelay, SLOT(OnWidgetEdited())); \
|
||||||
connect(pRelay, SIGNAL(WidgetEdited(QWidget*, const QModelIndex&)), this, SLOT(WidgetEdited(QWidget*, const QModelIndex&)));
|
connect(pRelay, SIGNAL(WidgetEdited(QWidget*, const QModelIndex&)), this, SLOT(WidgetEdited(QWidget*, const QModelIndex&)))
|
||||||
|
|
||||||
CPropertyDelegate::CPropertyDelegate(QObject *pParent /*= 0*/)
|
CPropertyDelegate::CPropertyDelegate(QObject *pParent /*= 0*/)
|
||||||
: QStyledItemDelegate(pParent)
|
: QStyledItemDelegate(pParent)
|
||||||
|
@ -57,7 +57,7 @@ QWidget* CPropertyDelegate::createEditor(QWidget *pParent, const QStyleOptionVie
|
||||||
case eBoolProperty:
|
case eBoolProperty:
|
||||||
{
|
{
|
||||||
QCheckBox *pCheckBox = new QCheckBox(pParent);
|
QCheckBox *pCheckBox = new QCheckBox(pParent);
|
||||||
CONNECT_RELAY(pCheckBox, rkIndex, toggled(bool))
|
CONNECT_RELAY(pCheckBox, rkIndex, toggled(bool));
|
||||||
pOut = pCheckBox;
|
pOut = pCheckBox;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ QWidget* CPropertyDelegate::createEditor(QWidget *pParent, const QStyleOptionVie
|
||||||
WIntegralSpinBox *pSpinBox = new WIntegralSpinBox(pParent);
|
WIntegralSpinBox *pSpinBox = new WIntegralSpinBox(pParent);
|
||||||
pSpinBox->setMinimum(INT16_MIN);
|
pSpinBox->setMinimum(INT16_MIN);
|
||||||
pSpinBox->setMaximum(INT16_MAX);
|
pSpinBox->setMaximum(INT16_MAX);
|
||||||
CONNECT_RELAY(pSpinBox, rkIndex, valueChanged(int))
|
CONNECT_RELAY(pSpinBox, rkIndex, valueChanged(int));
|
||||||
pOut = pSpinBox;
|
pOut = pSpinBox;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ QWidget* CPropertyDelegate::createEditor(QWidget *pParent, const QStyleOptionVie
|
||||||
WIntegralSpinBox *pSpinBox = new WIntegralSpinBox(pParent);
|
WIntegralSpinBox *pSpinBox = new WIntegralSpinBox(pParent);
|
||||||
pSpinBox->setMinimum(INT32_MIN);
|
pSpinBox->setMinimum(INT32_MIN);
|
||||||
pSpinBox->setMaximum(INT32_MAX);
|
pSpinBox->setMaximum(INT32_MAX);
|
||||||
CONNECT_RELAY(pSpinBox, rkIndex, valueChanged(int))
|
CONNECT_RELAY(pSpinBox, rkIndex, valueChanged(int));
|
||||||
pOut = pSpinBox;
|
pOut = pSpinBox;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -86,15 +86,15 @@ QWidget* CPropertyDelegate::createEditor(QWidget *pParent, const QStyleOptionVie
|
||||||
{
|
{
|
||||||
WDraggableSpinBox *pSpinBox = new WDraggableSpinBox(pParent);
|
WDraggableSpinBox *pSpinBox = new WDraggableSpinBox(pParent);
|
||||||
pSpinBox->setSingleStep(0.1);
|
pSpinBox->setSingleStep(0.1);
|
||||||
|
CONNECT_RELAY(pSpinBox, rkIndex, valueChanged(double));
|
||||||
pOut = pSpinBox;
|
pOut = pSpinBox;
|
||||||
CONNECT_RELAY(pSpinBox, rkIndex, valueChanged(double))
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case eColorProperty:
|
case eColorProperty:
|
||||||
{
|
{
|
||||||
WColorPicker *pColorPicker = new WColorPicker(pParent);
|
WColorPicker *pColorPicker = new WColorPicker(pParent);
|
||||||
CONNECT_RELAY(pColorPicker, rkIndex, colorChanged(QColor))
|
CONNECT_RELAY(pColorPicker, rkIndex, colorChanged(QColor));
|
||||||
pOut = pColorPicker;
|
pOut = pColorPicker;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ QWidget* CPropertyDelegate::createEditor(QWidget *pParent, const QStyleOptionVie
|
||||||
case eStringProperty:
|
case eStringProperty:
|
||||||
{
|
{
|
||||||
QLineEdit *pLineEdit = new QLineEdit(pParent);
|
QLineEdit *pLineEdit = new QLineEdit(pParent);
|
||||||
CONNECT_RELAY(pLineEdit, rkIndex, textEdited(QString))
|
CONNECT_RELAY(pLineEdit, rkIndex, textEdited(QString));
|
||||||
pOut = pLineEdit;
|
pOut = pLineEdit;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,7 @@ QWidget* CPropertyDelegate::createEditor(QWidget *pParent, const QStyleOptionVie
|
||||||
for (u32 iEnum = 0; iEnum < pTemp->NumEnumerators(); iEnum++)
|
for (u32 iEnum = 0; iEnum < pTemp->NumEnumerators(); iEnum++)
|
||||||
pComboBox->addItem(TO_QSTRING(pTemp->EnumeratorName(iEnum)));
|
pComboBox->addItem(TO_QSTRING(pTemp->EnumeratorName(iEnum)));
|
||||||
|
|
||||||
CONNECT_RELAY(pComboBox, rkIndex, currentIndexChanged(int))
|
CONNECT_RELAY(pComboBox, rkIndex, currentIndexChanged(int));
|
||||||
pOut = pComboBox;
|
pOut = pComboBox;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ QWidget* CPropertyDelegate::createEditor(QWidget *pParent, const QStyleOptionVie
|
||||||
pSelector->SetAllowedExtensions(pTemp->Extensions());
|
pSelector->SetAllowedExtensions(pTemp->Extensions());
|
||||||
pSelector->setFont(qobject_cast<QWidget*>(parent())->font()); // bit of a hack to stop the resource selector font from changing
|
pSelector->setFont(qobject_cast<QWidget*>(parent())->font()); // bit of a hack to stop the resource selector font from changing
|
||||||
|
|
||||||
CONNECT_RELAY(pSelector, rkIndex, ResourceChanged(QString))
|
CONNECT_RELAY(pSelector, rkIndex, ResourceChanged(QString));
|
||||||
pOut = pSelector;
|
pOut = pSelector;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -159,7 +159,7 @@ QWidget* CPropertyDelegate::createEditor(QWidget *pParent, const QStyleOptionVie
|
||||||
else if (pProp->Type() == eBitfieldProperty)
|
else if (pProp->Type() == eBitfieldProperty)
|
||||||
{
|
{
|
||||||
QCheckBox *pCheckBox = new QCheckBox(pParent);
|
QCheckBox *pCheckBox = new QCheckBox(pParent);
|
||||||
CONNECT_RELAY(pCheckBox, rkIndex, toggled(bool))
|
CONNECT_RELAY(pCheckBox, rkIndex, toggled(bool));
|
||||||
pOut = pCheckBox;
|
pOut = pCheckBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ QWidget* CPropertyDelegate::createEditor(QWidget *pParent, const QStyleOptionVie
|
||||||
pSpinBox->setMaximum(1.0);
|
pSpinBox->setMaximum(1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
CONNECT_RELAY(pSpinBox, rkIndex, valueChanged(double))
|
CONNECT_RELAY(pSpinBox, rkIndex, valueChanged(double));
|
||||||
pOut = pSpinBox;
|
pOut = pSpinBox;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,6 +194,7 @@ QWidget* CPropertyDelegate::createEditor(QWidget *pParent, const QStyleOptionVie
|
||||||
void CPropertyDelegate::setEditorData(QWidget *pEditor, const QModelIndex &rkIndex) const
|
void CPropertyDelegate::setEditorData(QWidget *pEditor, const QModelIndex &rkIndex) const
|
||||||
{
|
{
|
||||||
BlockRelays(true);
|
BlockRelays(true);
|
||||||
|
mEditInProgress = false; // fixes case where user does undo mid-edit
|
||||||
|
|
||||||
if (pEditor)
|
if (pEditor)
|
||||||
{
|
{
|
||||||
|
@ -433,11 +434,11 @@ void CPropertyDelegate::setModelData(QWidget *pEditor, QAbstractItemModel* /*pMo
|
||||||
{
|
{
|
||||||
WIntegralSpinBox *pSpinBox = static_cast<WIntegralSpinBox*>(pEditor);
|
WIntegralSpinBox *pSpinBox = static_cast<WIntegralSpinBox*>(pEditor);
|
||||||
CArrayProperty *pArray = static_cast<CArrayProperty*>(pProp);
|
CArrayProperty *pArray = static_cast<CArrayProperty*>(pProp);
|
||||||
u32 NewCount = pSpinBox->value();
|
int NewCount = pSpinBox->value();
|
||||||
|
|
||||||
if (pArray->Count() != NewCount)
|
if (pArray->Count() != NewCount)
|
||||||
{
|
{
|
||||||
CResizeScriptArrayCommand *pCmd = new CResizeScriptArrayCommand(mpModel, rkIndex, NewCount);
|
CResizeScriptArrayCommand *pCmd = new CResizeScriptArrayCommand(pProp, mpEditor, mpModel, NewCount);
|
||||||
mpEditor->UndoStack()->push(pCmd);
|
mpEditor->UndoStack()->push(pCmd);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -517,7 +518,8 @@ void CPropertyDelegate::setModelData(QWidget *pEditor, QAbstractItemModel* /*pMo
|
||||||
// Create undo command
|
// Create undo command
|
||||||
if (!Matches || EditInProgress)
|
if (!Matches || EditInProgress)
|
||||||
{
|
{
|
||||||
CEditScriptPropertyCommand *pCommand = new CEditScriptPropertyCommand(mpModel, rkIndex, pOldValue, !mEditInProgress);
|
// Always consider the edit done for bool properties
|
||||||
|
CEditScriptPropertyCommand *pCommand = new CEditScriptPropertyCommand(pProp, mpEditor, pOldValue, (!mEditInProgress || pProp->Type() == eBoolProperty));
|
||||||
mpEditor->UndoStack()->push(pCommand);
|
mpEditor->UndoStack()->push(pCommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -563,7 +565,7 @@ QWidget* CPropertyDelegate::CreateCharacterEditor(QWidget *pParent, const QModel
|
||||||
else
|
else
|
||||||
pSelector->SetAllowedExtensions("CHAR");
|
pSelector->SetAllowedExtensions("CHAR");
|
||||||
|
|
||||||
CONNECT_RELAY(pSelector, rkIndex, ResourceChanged(QString))
|
CONNECT_RELAY(pSelector, rkIndex, ResourceChanged(QString));
|
||||||
return pSelector;
|
return pSelector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -579,14 +581,14 @@ QWidget* CPropertyDelegate::CreateCharacterEditor(QWidget *pParent, const QModel
|
||||||
pComboBox->addItem(TO_QSTRING(pAnimSet->getNodeName(iChr)));
|
pComboBox->addItem(TO_QSTRING(pAnimSet->getNodeName(iChr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
CONNECT_RELAY(pComboBox, rkIndex, currentIndexChanged(int))
|
CONNECT_RELAY(pComboBox, rkIndex, currentIndexChanged(int));
|
||||||
return pComboBox;
|
return pComboBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Type == eLongProperty)
|
if (Type == eLongProperty)
|
||||||
{
|
{
|
||||||
WIntegralSpinBox *pSpinBox = new WIntegralSpinBox(pParent);
|
WIntegralSpinBox *pSpinBox = new WIntegralSpinBox(pParent);
|
||||||
CONNECT_RELAY(pSpinBox, rkIndex, valueChanged(int))
|
CONNECT_RELAY(pSpinBox, rkIndex, valueChanged(int));
|
||||||
return pSpinBox;
|
return pSpinBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,48 @@ IProperty* CPropertyModel::PropertyForIndex(const QModelIndex& rkIndex, bool Han
|
||||||
return static_cast<IProperty*>(rkIndex.internalPointer());
|
return static_cast<IProperty*>(rkIndex.internalPointer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QModelIndex CPropertyModel::IndexForProperty(IProperty *pProp) const
|
||||||
|
{
|
||||||
|
if (pProp == mpBaseStruct) return QModelIndex();
|
||||||
|
|
||||||
|
QVector<u32> RowNumbers;
|
||||||
|
IProperty *pChild = pProp;
|
||||||
|
CPropertyStruct *pParent = pProp->Parent();
|
||||||
|
|
||||||
|
while (pParent)
|
||||||
|
{
|
||||||
|
// Check for array with one sub-property
|
||||||
|
CPropertyStruct *pGrandparent = pParent->Parent();
|
||||||
|
if (pGrandparent && pGrandparent->Type() == eArrayProperty && pParent->Count() == 1)
|
||||||
|
{
|
||||||
|
pChild = pParent;
|
||||||
|
pParent = pGrandparent;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find row index for this child property
|
||||||
|
for (u32 iChild = 0; iChild < pParent->Count(); iChild++)
|
||||||
|
{
|
||||||
|
if (pParent->PropertyByIndex(iChild) == pChild)
|
||||||
|
{
|
||||||
|
RowNumbers << iChild;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pChild = pParent;
|
||||||
|
pParent = pGrandparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the corresponding QModelIndex in the same spot
|
||||||
|
QModelIndex Index = QModelIndex();
|
||||||
|
|
||||||
|
for (int iChild = RowNumbers.size() - 1; iChild >= 0; iChild--)
|
||||||
|
Index = index(RowNumbers[iChild], 0, Index);
|
||||||
|
|
||||||
|
return Index;
|
||||||
|
}
|
||||||
|
|
||||||
int CPropertyModel::columnCount(const QModelIndex& /*rkParent*/) const
|
int CPropertyModel::columnCount(const QModelIndex& /*rkParent*/) const
|
||||||
{
|
{
|
||||||
return 2;
|
return 2;
|
||||||
|
@ -393,6 +435,11 @@ Qt::ItemFlags CPropertyModel::flags(const QModelIndex& rkIndex) const
|
||||||
else return (Qt::ItemIsEnabled | Qt::ItemIsEditable);
|
else return (Qt::ItemIsEnabled | Qt::ItemIsEditable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CPropertyModel::NotifyPropertyModified(IProperty *pProp)
|
||||||
|
{
|
||||||
|
NotifyPropertyModified(IndexForProperty(pProp));
|
||||||
|
}
|
||||||
|
|
||||||
void CPropertyModel::NotifyPropertyModified(const QModelIndex& rkIndex)
|
void CPropertyModel::NotifyPropertyModified(const QModelIndex& rkIndex)
|
||||||
{
|
{
|
||||||
if (rowCount(rkIndex) != 0)
|
if (rowCount(rkIndex) != 0)
|
||||||
|
@ -405,7 +452,9 @@ void CPropertyModel::NotifyPropertyModified(const QModelIndex& rkIndex)
|
||||||
emit dataChanged(Parent, Parent);
|
emit dataChanged(Parent, Parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
emit dataChanged(rkIndex, rkIndex);
|
QModelIndex IndexC1 = rkIndex.sibling(rkIndex.row(), 1);
|
||||||
|
emit dataChanged(IndexC1, IndexC1);
|
||||||
|
|
||||||
emit PropertyModified(rkIndex);
|
emit PropertyModified(rkIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ public:
|
||||||
CPropertyModel(QObject *pParent = 0);
|
CPropertyModel(QObject *pParent = 0);
|
||||||
void SetBaseStruct(CPropertyStruct *pBaseStruct);
|
void SetBaseStruct(CPropertyStruct *pBaseStruct);
|
||||||
IProperty* PropertyForIndex(const QModelIndex& rkIndex, bool HandleFlaggedPointers) const;
|
IProperty* PropertyForIndex(const QModelIndex& rkIndex, bool HandleFlaggedPointers) const;
|
||||||
|
QModelIndex IndexForProperty(IProperty *pProp) const;
|
||||||
|
|
||||||
int columnCount(const QModelIndex& rkParent) const;
|
int columnCount(const QModelIndex& rkParent) const;
|
||||||
int rowCount(const QModelIndex& rkParent) const;
|
int rowCount(const QModelIndex& rkParent) const;
|
||||||
|
@ -23,10 +24,14 @@ public:
|
||||||
QModelIndex parent(const QModelIndex& rkChild) const;
|
QModelIndex parent(const QModelIndex& rkChild) const;
|
||||||
Qt::ItemFlags flags(const QModelIndex& rkIndex) const;
|
Qt::ItemFlags flags(const QModelIndex& rkIndex) const;
|
||||||
|
|
||||||
void NotifyPropertyModified(const QModelIndex& rkIndex);
|
|
||||||
void ArrayAboutToBeResized(const QModelIndex& rkIndex, u32 NewSize);
|
void ArrayAboutToBeResized(const QModelIndex& rkIndex, u32 NewSize);
|
||||||
void ArrayResized(const QModelIndex& rkIndex, u32 OldSize);
|
void ArrayResized(const QModelIndex& rkIndex, u32 OldSize);
|
||||||
void ResizeArray(const QModelIndex& rkIndex, u32 NewSize);
|
void ResizeArray(const QModelIndex& rkIndex, u32 NewSize);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void NotifyPropertyModified(IProperty *pProp);
|
||||||
|
void NotifyPropertyModified(const QModelIndex& rkIndex);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void PropertyModified(const QModelIndex& rkIndex);
|
void PropertyModified(const QModelIndex& rkIndex);
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,7 +17,7 @@ CPropertyView::CPropertyView(QWidget *pParent)
|
||||||
connect(this, SIGNAL(expanded(QModelIndex)), this, SLOT(SetPersistentEditors(QModelIndex)));
|
connect(this, SIGNAL(expanded(QModelIndex)), this, SLOT(SetPersistentEditors(QModelIndex)));
|
||||||
connect(this, SIGNAL(clicked(QModelIndex)), this, SLOT(edit(QModelIndex)));
|
connect(this, SIGNAL(clicked(QModelIndex)), this, SLOT(edit(QModelIndex)));
|
||||||
connect(mpModel, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(SetPersistentEditors(QModelIndex)));
|
connect(mpModel, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(SetPersistentEditors(QModelIndex)));
|
||||||
connect(mpModel, SIGNAL(PropertyModified(QModelIndex)), this, SLOT(OnPropertyModified(QModelIndex)));
|
connect(mpModel, SIGNAL(PropertyModified(const QModelIndex&)), this, SLOT(OnPropertyModified(const QModelIndex&)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPropertyView::setModel(QAbstractItemModel *pModel)
|
void CPropertyView::setModel(QAbstractItemModel *pModel)
|
||||||
|
@ -66,6 +66,7 @@ void CPropertyView::SetEditor(CWorldEditor *pEditor)
|
||||||
{
|
{
|
||||||
mpEditor = pEditor;
|
mpEditor = pEditor;
|
||||||
mpDelegate->SetEditor(pEditor);
|
mpDelegate->SetEditor(pEditor);
|
||||||
|
connect(mpEditor, SIGNAL(PropertyModified(IProperty*,bool)), mpModel, SLOT(NotifyPropertyModified(IProperty*)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPropertyView::SetInstance(CScriptObject *pObj)
|
void CPropertyView::SetInstance(CScriptObject *pObj)
|
||||||
|
@ -83,7 +84,10 @@ void CPropertyView::SetInstance(CScriptObject *pObj)
|
||||||
|
|
||||||
void CPropertyView::UpdateEditorProperties(const QModelIndex& rkParent)
|
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.
|
// Check what game this is
|
||||||
|
EGame Game = mpEditor->ActiveArea()->Version();
|
||||||
|
|
||||||
|
// Iterate over all properties and update if they're an editor property.
|
||||||
for (int iRow = 0; iRow < mpModel->rowCount(rkParent); iRow++)
|
for (int iRow = 0; iRow < mpModel->rowCount(rkParent); iRow++)
|
||||||
{
|
{
|
||||||
QModelIndex Index0 = mpModel->index(iRow, 0, rkParent);
|
QModelIndex Index0 = mpModel->index(iRow, 0, rkParent);
|
||||||
|
@ -92,11 +96,15 @@ void CPropertyView::UpdateEditorProperties(const QModelIndex& rkParent)
|
||||||
|
|
||||||
if (pProp)
|
if (pProp)
|
||||||
{
|
{
|
||||||
|
// For structs, update sub-properties.
|
||||||
if (pProp->Type() == eStructProperty)
|
if (pProp->Type() == eStructProperty)
|
||||||
{
|
{
|
||||||
CStructTemplate *pStruct = static_cast<CStructTemplate*>(pProp->Template());
|
CStructTemplate *pStruct = static_cast<CStructTemplate*>(pProp->Template());
|
||||||
|
|
||||||
if (pStruct->IsSingleProperty() || pStruct->PropertyID() == 0x255A4580)
|
// As an optimization, in MP2+, we don't need to update unless this is a single struct or if
|
||||||
|
// it's EditorProperties, because other structs never have editor properties in them.
|
||||||
|
// In MP1 this isn't the case so we need to update every struct regardless
|
||||||
|
if ((Game <= ePrime) || (pStruct->IsSingleProperty() || pStruct->PropertyID() == 0x255A4580))
|
||||||
UpdateEditorProperties(Index0);
|
UpdateEditorProperties(Index0);
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
|
@ -180,16 +188,9 @@ void CPropertyView::OnPropertyModified(const QModelIndex& rkIndex)
|
||||||
// Check for a character resource being changed. If that's the case we need to remake the persistent editors.
|
// Check for a character resource being changed. If that's the case we need to remake the persistent editors.
|
||||||
IProperty *pProp = mpModel->PropertyForIndex(rkIndex, true);
|
IProperty *pProp = mpModel->PropertyForIndex(rkIndex, true);
|
||||||
|
|
||||||
if (pProp->Type() == eCharacterProperty && rkIndex.internalId() & 0x1)
|
if (pProp->Type() == eCharacterProperty /*&& rkIndex.internalId() & 0x1*/)
|
||||||
{
|
{
|
||||||
EGame Game = static_cast<TCharacterProperty*>(pProp)->Get().Version();
|
ClosePersistentEditors(rkIndex);
|
||||||
|
SetPersistentEditors(rkIndex);
|
||||||
if (mpDelegate->DetermineCharacterPropType(Game, rkIndex) == eFileProperty)
|
|
||||||
{
|
|
||||||
ClosePersistentEditors(rkIndex.parent());
|
|
||||||
SetPersistentEditors(rkIndex.parent());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
emit PropertyModified(pProp);
|
|
||||||
}
|
|
||||||
|
|
|
@ -29,9 +29,6 @@ public slots:
|
||||||
void SetPersistentEditors(const QModelIndex& rkIndex);
|
void SetPersistentEditors(const QModelIndex& rkIndex);
|
||||||
void ClosePersistentEditors(const QModelIndex& rkIndex);
|
void ClosePersistentEditors(const QModelIndex& rkIndex);
|
||||||
void OnPropertyModified(const QModelIndex& rkIndex);
|
void OnPropertyModified(const QModelIndex& rkIndex);
|
||||||
|
|
||||||
signals:
|
|
||||||
void PropertyModified(IProperty *pProperty);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CPROPERTYVIEW_H
|
#endif // CPROPERTYVIEW_H
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
#include "CBasicPropertyCommand.h"
|
#include "CBasicPropertyCommand.h"
|
||||||
#include <Core/Resource/Script/IPropertyTemplate.h>
|
#include <Core/Resource/Script/IPropertyTemplate.h>
|
||||||
|
|
||||||
CBasicPropertyCommand::CBasicPropertyCommand(CPropertyModel *pModel, const QModelIndex& rkIndex)
|
CBasicPropertyCommand::CBasicPropertyCommand(IProperty *pProp, CWorldEditor *pEditor, const QString& rkCommandName /*="Edit Property"*/)
|
||||||
: IUndoCommand("Edit Property")
|
: IUndoCommand(rkCommandName)
|
||||||
, mpModel(pModel)
|
, mpProperty(pProp)
|
||||||
, mpProperty(pModel->PropertyForIndex(rkIndex, true))
|
|
||||||
, mpTemplate(mpProperty->Template())
|
, mpTemplate(mpProperty->Template())
|
||||||
, mIndex(rkIndex)
|
, mpBaseStruct(pProp->RootStruct())
|
||||||
|
, mpEditor(pEditor)
|
||||||
, mIsInArray(false)
|
, mIsInArray(false)
|
||||||
{
|
{
|
||||||
// Check for array
|
// Check for array
|
||||||
IProperty *pProp = mpProperty;
|
IProperty *pChild = mpProperty;
|
||||||
IProperty *pParent = mpProperty->Parent();
|
IProperty *pParent = mpProperty->Parent();
|
||||||
|
|
||||||
while (pParent)
|
while (pParent)
|
||||||
|
@ -24,31 +24,28 @@ CBasicPropertyCommand::CBasicPropertyCommand(CPropertyModel *pModel, const QMode
|
||||||
|
|
||||||
for (u32 iSub = 0; iSub < pArray->Count(); iSub++)
|
for (u32 iSub = 0; iSub < pArray->Count(); iSub++)
|
||||||
{
|
{
|
||||||
if (pArray->PropertyByIndex(iSub) == pProp)
|
if (pArray->PropertyByIndex(iSub) == pChild)
|
||||||
{
|
{
|
||||||
mArrayIndices << iSub;
|
mArrayIndices << iSub;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pProp = pParent;
|
pChild = pParent;
|
||||||
pParent = pParent->Parent();
|
pParent = pParent->Parent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBasicPropertyCommand::UpdateArraySubProperty()
|
void CBasicPropertyCommand::UpdateArraySubProperty()
|
||||||
{
|
{
|
||||||
// If an array has been sized down and then back up, then we might have an index to an invalid property.
|
// If an array has been sized down and then back up, then we might have a pointer to an invalid property.
|
||||||
// Since we can't assume our index is still valid, we'll use the template and the model to find the corresponding property.
|
// Since we can't assume our pointer is still valid, we'll use the template to find the corresponding property.
|
||||||
IPropertyTemplate *pTemp = mpTemplate;
|
IPropertyTemplate *pTemp = mpTemplate;
|
||||||
CStructTemplate *pParent = mpTemplate->Parent();
|
CStructTemplate *pParent = mpTemplate->Parent();
|
||||||
|
|
||||||
QVector<u32> SubIndices;
|
QVector<u32> SubIndices;
|
||||||
int IndexIndex = 0;
|
int IndexIndex = 0;
|
||||||
|
|
||||||
if (mIndex.internalId() & 0x1)
|
|
||||||
SubIndices << mIndex.row();
|
|
||||||
|
|
||||||
while (pParent)
|
while (pParent)
|
||||||
{
|
{
|
||||||
if (pParent->Type() != eArrayProperty || static_cast<CArrayTemplate*>(pParent)->Count() > 1)
|
if (pParent->Type() != eArrayProperty || static_cast<CArrayTemplate*>(pParent)->Count() > 1)
|
||||||
|
@ -62,6 +59,8 @@ void CBasicPropertyCommand::UpdateArraySubProperty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
SubIndices << 0;
|
||||||
|
|
||||||
if (pParent->Type() == eArrayProperty)
|
if (pParent->Type() == eArrayProperty)
|
||||||
{
|
{
|
||||||
|
@ -73,15 +72,9 @@ void CBasicPropertyCommand::UpdateArraySubProperty()
|
||||||
pParent = pParent->Parent();
|
pParent = pParent->Parent();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find corresponding index
|
// Find corresponding property
|
||||||
QModelIndex Index = QModelIndex();
|
mpProperty = mpBaseStruct;
|
||||||
|
|
||||||
for (int iSub = SubIndices.size() - 1; iSub >= 0; iSub--)
|
for (int iChild = SubIndices.size() - 1; iChild >= 0; iChild--)
|
||||||
Index = mpModel->index(SubIndices[iSub], 0, Index);
|
mpProperty = static_cast<CPropertyStruct*>(mpProperty)->PropertyByIndex(SubIndices[iChild]);
|
||||||
|
|
||||||
Index = Index.sibling(Index.row(), 1);
|
|
||||||
|
|
||||||
// Get property
|
|
||||||
mpProperty = mpModel->PropertyForIndex(Index, true);
|
|
||||||
mIndex = Index;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,20 +3,21 @@
|
||||||
|
|
||||||
#include "IUndoCommand.h"
|
#include "IUndoCommand.h"
|
||||||
#include "Editor/PropertyEdit/CPropertyModel.h"
|
#include "Editor/PropertyEdit/CPropertyModel.h"
|
||||||
|
#include "Editor/WorldEditor/CWorldEditor.h"
|
||||||
|
|
||||||
class CBasicPropertyCommand : public IUndoCommand
|
class CBasicPropertyCommand : public IUndoCommand
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
CPropertyModel *mpModel;
|
|
||||||
IProperty *mpProperty;
|
IProperty *mpProperty;
|
||||||
IPropertyTemplate *mpTemplate;
|
IPropertyTemplate *mpTemplate;
|
||||||
QModelIndex mIndex;
|
CPropertyStruct *mpBaseStruct;
|
||||||
|
CWorldEditor *mpEditor;
|
||||||
|
|
||||||
bool mIsInArray;
|
bool mIsInArray;
|
||||||
QVector<u32> mArrayIndices;
|
QVector<u32> mArrayIndices;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CBasicPropertyCommand(CPropertyModel *pModel, const QModelIndex& rkIndex);
|
CBasicPropertyCommand(IProperty *pProp, CWorldEditor *pEditor, const QString& rkCommandName = "Edit Property");
|
||||||
virtual void UpdateArraySubProperty();
|
virtual void UpdateArraySubProperty();
|
||||||
virtual bool AffectsCleanState() const { return true; }
|
virtual bool AffectsCleanState() const { return true; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
#include "CChangeLayerCommand.h"
|
||||||
|
|
||||||
|
CChangeLayerCommand::CChangeLayerCommand(CWorldEditor *pEditor, const QList<CScriptNode*>& rkNodeList, CScriptLayer *pNewLayer)
|
||||||
|
: IUndoCommand("Change Layer")
|
||||||
|
, mNodeList(rkNodeList)
|
||||||
|
, mpNewLayer(pNewLayer)
|
||||||
|
, mpEditor(pEditor)
|
||||||
|
{
|
||||||
|
foreach (CScriptNode *pNode, mNodeList)
|
||||||
|
{
|
||||||
|
CScriptLayer *pLayer = pNode->Object()->Layer();
|
||||||
|
|
||||||
|
if (pLayer == pNewLayer)
|
||||||
|
{
|
||||||
|
mNodeList.removeOne(pNode);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
mOldLayers[pNode] = pLayer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CChangeLayerCommand::undo()
|
||||||
|
{
|
||||||
|
mpEditor->InstancesLayerAboutToChange();
|
||||||
|
|
||||||
|
foreach (CScriptNode *pNode, mNodeList)
|
||||||
|
pNode->Object()->SetLayer(mOldLayers[pNode]);
|
||||||
|
|
||||||
|
mpEditor->InstancesLayerChanged(mNodeList);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CChangeLayerCommand::redo()
|
||||||
|
{
|
||||||
|
mpEditor->InstancesLayerAboutToChange();
|
||||||
|
|
||||||
|
foreach (CScriptNode *pNode, mNodeList)
|
||||||
|
pNode->Object()->SetLayer(mpNewLayer);
|
||||||
|
|
||||||
|
mpEditor->InstancesLayerChanged(mNodeList);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef CCHANGELAYERCOMMAND_H
|
||||||
|
#define CCHANGELAYERCOMMAND_H
|
||||||
|
|
||||||
|
#include "IUndoCommand.h"
|
||||||
|
#include "Editor/WorldEditor/CWorldEditor.h"
|
||||||
|
#include <Core/Scene/CScriptNode.h>
|
||||||
|
|
||||||
|
class CChangeLayerCommand : public IUndoCommand
|
||||||
|
{
|
||||||
|
QList<CScriptNode*> mNodeList;
|
||||||
|
QMap<CScriptNode*, CScriptLayer*> mOldLayers;
|
||||||
|
CScriptLayer *mpNewLayer;
|
||||||
|
CWorldEditor *mpEditor;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CChangeLayerCommand(CWorldEditor *pEditor, const QList<CScriptNode*>& rkNodeList, CScriptLayer *pNewLayer);
|
||||||
|
void undo();
|
||||||
|
void redo();
|
||||||
|
bool AffectsCleanState() const { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CCHANGELAYERCOMMAND_H
|
|
@ -1,8 +1,8 @@
|
||||||
#include "CEditScriptPropertyCommand.h"
|
#include "CEditScriptPropertyCommand.h"
|
||||||
#include "EUndoCommand.h"
|
#include "EUndoCommand.h"
|
||||||
|
|
||||||
CEditScriptPropertyCommand::CEditScriptPropertyCommand(CPropertyModel *pModel, const QModelIndex& rkIndex, IPropertyValue *pOldValue, bool IsDone)
|
CEditScriptPropertyCommand::CEditScriptPropertyCommand(IProperty *pProp, CWorldEditor *pEditor, IPropertyValue *pOldValue, bool IsDone, const QString& rkCommandName /*= "Edit Property"*/)
|
||||||
: CBasicPropertyCommand(pModel, rkIndex)
|
: CBasicPropertyCommand(pProp, pEditor, rkCommandName)
|
||||||
, mCommandEnded(IsDone)
|
, mCommandEnded(IsDone)
|
||||||
{
|
{
|
||||||
mpOldValue = pOldValue;
|
mpOldValue = pOldValue;
|
||||||
|
@ -41,12 +41,13 @@ void CEditScriptPropertyCommand::undo()
|
||||||
{
|
{
|
||||||
if (mIsInArray) UpdateArraySubProperty();
|
if (mIsInArray) UpdateArraySubProperty();
|
||||||
mpProperty->RawValue()->Copy(mpOldValue);
|
mpProperty->RawValue()->Copy(mpOldValue);
|
||||||
mpModel->NotifyPropertyModified(mIndex);
|
mpEditor->OnPropertyModified(mpProperty);
|
||||||
|
mCommandEnded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CEditScriptPropertyCommand::redo()
|
void CEditScriptPropertyCommand::redo()
|
||||||
{
|
{
|
||||||
if (mIsInArray) UpdateArraySubProperty();
|
if (mIsInArray) UpdateArraySubProperty();
|
||||||
mpProperty->RawValue()->Copy(mpNewValue);
|
mpProperty->RawValue()->Copy(mpNewValue);
|
||||||
mpModel->NotifyPropertyModified(mIndex);
|
mpEditor->OnPropertyModified(mpProperty);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
#include "CBasicPropertyCommand.h"
|
#include "CBasicPropertyCommand.h"
|
||||||
#include "Editor/PropertyEdit/CPropertyModel.h"
|
#include "Editor/PropertyEdit/CPropertyModel.h"
|
||||||
#include <QUndoCommand>
|
|
||||||
|
|
||||||
class CEditScriptPropertyCommand : public CBasicPropertyCommand
|
class CEditScriptPropertyCommand : public CBasicPropertyCommand
|
||||||
{
|
{
|
||||||
|
@ -12,7 +11,7 @@ class CEditScriptPropertyCommand : public CBasicPropertyCommand
|
||||||
bool mCommandEnded;
|
bool mCommandEnded;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CEditScriptPropertyCommand(CPropertyModel *pModel, const QModelIndex& rkIndex, IPropertyValue *pOldValue, bool IsDone);
|
CEditScriptPropertyCommand(IProperty *pProp, CWorldEditor *pEditor, IPropertyValue *pOldValue, bool IsDone, const QString& rkCommandName = "Edit Property");
|
||||||
~CEditScriptPropertyCommand();
|
~CEditScriptPropertyCommand();
|
||||||
int id() const;
|
int id() const;
|
||||||
bool mergeWith(const QUndoCommand *pkOther);
|
bool mergeWith(const QUndoCommand *pkOther);
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
#include "CResizeScriptArrayCommand.h"
|
#include "CResizeScriptArrayCommand.h"
|
||||||
|
|
||||||
CResizeScriptArrayCommand::CResizeScriptArrayCommand(CPropertyModel *pModel, const QModelIndex& rkIndex, u32 NewSize)
|
CResizeScriptArrayCommand::CResizeScriptArrayCommand(IProperty *pProp, CWorldEditor *pEditor, CPropertyModel *pModel, int NewSize)
|
||||||
: CBasicPropertyCommand(pModel, rkIndex)
|
: CBasicPropertyCommand(pProp, pEditor)
|
||||||
, mpArray(static_cast<CArrayProperty*>(mpProperty))
|
, mpArray(static_cast<CArrayProperty*>(mpProperty))
|
||||||
|
, mpModel(pModel)
|
||||||
, mOldSize(mpArray->Count())
|
, mOldSize(mpArray->Count())
|
||||||
, mNewSize(NewSize)
|
, mNewSize(NewSize)
|
||||||
{
|
{
|
||||||
|
@ -10,7 +11,7 @@ CResizeScriptArrayCommand::CResizeScriptArrayCommand(CPropertyModel *pModel, con
|
||||||
|
|
||||||
if (!mNewSizeLarger)
|
if (!mNewSizeLarger)
|
||||||
{
|
{
|
||||||
for (u32 iSub = mNewSize; iSub < mOldSize; iSub++)
|
for (int iSub = mNewSize; iSub < mOldSize; iSub++)
|
||||||
{
|
{
|
||||||
mDeletedProperties << mpArray->PropertyByIndex(iSub)->Clone();
|
mDeletedProperties << mpArray->PropertyByIndex(iSub)->Clone();
|
||||||
}
|
}
|
||||||
|
@ -29,21 +30,22 @@ void CResizeScriptArrayCommand::undo()
|
||||||
{
|
{
|
||||||
if (mIsInArray) UpdateArraySubProperty();
|
if (mIsInArray) UpdateArraySubProperty();
|
||||||
|
|
||||||
mpModel->ArrayAboutToBeResized(mIndex, mOldSize);
|
QModelIndex Index = mpModel->IndexForProperty(mpProperty);
|
||||||
|
mpModel->ArrayAboutToBeResized(Index, (u32) mOldSize);
|
||||||
mpArray->Resize(mOldSize);
|
mpArray->Resize(mOldSize);
|
||||||
|
|
||||||
if (!mNewSizeLarger)
|
if (!mNewSizeLarger)
|
||||||
{
|
{
|
||||||
u32 NumNewElements = mOldSize - mNewSize;
|
int NumNewElements = mOldSize - mNewSize;
|
||||||
|
|
||||||
for (u32 iSub = 0; iSub < NumNewElements; iSub++)
|
for (int iSub = 0; iSub < NumNewElements; iSub++)
|
||||||
{
|
{
|
||||||
u32 Idx = iSub + mNewSize;
|
u32 Idx = iSub + mNewSize;
|
||||||
mpArray->PropertyByIndex(Idx)->Copy(mDeletedProperties[iSub]);
|
mpArray->PropertyByIndex(Idx)->Copy(mDeletedProperties[iSub]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mpModel->ArrayResized(mIndex, mNewSize);
|
mpModel->ArrayResized(Index, (u32) mNewSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,9 +56,10 @@ void CResizeScriptArrayCommand::redo()
|
||||||
{
|
{
|
||||||
if (mIsInArray) UpdateArraySubProperty();
|
if (mIsInArray) UpdateArraySubProperty();
|
||||||
|
|
||||||
mpModel->ArrayAboutToBeResized(mIndex, mNewSize);
|
QModelIndex Index = mpModel->IndexForProperty(mpProperty);
|
||||||
|
mpModel->ArrayAboutToBeResized(Index, (u32) mNewSize);
|
||||||
mpArray->Resize(mNewSize);
|
mpArray->Resize(mNewSize);
|
||||||
mpModel->ArrayResized(mIndex, mOldSize);
|
mpModel->ArrayResized(Index, (u32) mOldSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,13 +9,14 @@ class CResizeScriptArrayCommand : public CBasicPropertyCommand
|
||||||
{
|
{
|
||||||
CArrayProperty *mpArray;
|
CArrayProperty *mpArray;
|
||||||
QVector<IProperty*> mDeletedProperties;
|
QVector<IProperty*> mDeletedProperties;
|
||||||
|
CPropertyModel *mpModel;
|
||||||
|
|
||||||
u32 mOldSize;
|
int mOldSize;
|
||||||
u32 mNewSize;
|
int mNewSize;
|
||||||
bool mNewSizeLarger;
|
bool mNewSizeLarger;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CResizeScriptArrayCommand(CPropertyModel *pModel, const QModelIndex& rkIndex, u32 NewSize);
|
CResizeScriptArrayCommand(IProperty *pProp, CWorldEditor *pEditor, CPropertyModel *pModel, int NewSize);
|
||||||
~CResizeScriptArrayCommand();
|
~CResizeScriptArrayCommand();
|
||||||
void undo();
|
void undo();
|
||||||
void redo();
|
void redo();
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef EUNDOCOMMAND
|
#ifndef EUNDOCOMMAND
|
||||||
#define EUNDOCOMMAND
|
#define EUNDOCOMMAND
|
||||||
|
|
||||||
|
// This enum is used as an ID for merging undo commands.
|
||||||
|
// If a command can't merge, then it doesn't have to be listed here.
|
||||||
enum EUndoCommand
|
enum EUndoCommand
|
||||||
{
|
{
|
||||||
eTranslateNodeCmd,
|
eTranslateNodeCmd,
|
||||||
|
|
|
@ -4,13 +4,17 @@
|
||||||
#include "CTranslateNodeCommand.h"
|
#include "CTranslateNodeCommand.h"
|
||||||
#include "CRotateNodeCommand.h"
|
#include "CRotateNodeCommand.h"
|
||||||
#include "CScaleNodeCommand.h"
|
#include "CScaleNodeCommand.h"
|
||||||
|
|
||||||
#include "CSelectNodeCommand.h"
|
#include "CSelectNodeCommand.h"
|
||||||
#include "CDeselectNodeCommand.h"
|
#include "CDeselectNodeCommand.h"
|
||||||
#include "CClearSelectionCommand.h"
|
#include "CClearSelectionCommand.h"
|
||||||
#include "CSelectAllCommand.h"
|
#include "CSelectAllCommand.h"
|
||||||
#include "CInvertSelectionCommand.h"
|
#include "CInvertSelectionCommand.h"
|
||||||
|
|
||||||
#include "CEditScriptPropertyCommand.h"
|
#include "CEditScriptPropertyCommand.h"
|
||||||
#include "CResizeScriptArrayCommand.h"
|
#include "CResizeScriptArrayCommand.h"
|
||||||
|
#include "CChangeLayerCommand.h"
|
||||||
|
|
||||||
#include "EUndoCommand.h"
|
#include "EUndoCommand.h"
|
||||||
|
|
||||||
#endif // UNDOCOMMANDS
|
#endif // UNDOCOMMANDS
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
|
|
||||||
/* The tree has 3 levels:
|
/*
|
||||||
|
* The tree has 3 levels:
|
||||||
* 1. Node Type (Script Object, Light, World Mesh, etc) - represented with ID of 0
|
* 1. Node Type (Script Object, Light, World Mesh, etc) - represented with ID of 0
|
||||||
* 2. Object Type (Actor, Platform, SpawnPoint, etc) - represented with flags
|
* 2. Object Type (Actor, Platform, SpawnPoint, etc) - represented with flags
|
||||||
* 3. Instance - represented with pointer to instance (0x1 bit is guaranteed to be clear)
|
* 3. Instance - represented with pointer to instance (0x1 bit is guaranteed to be clear)
|
||||||
|
@ -15,6 +16,8 @@
|
||||||
* A: Row index
|
* A: Row index
|
||||||
* B: Node type row index
|
* B: Node type row index
|
||||||
* C: Item type (ObjType, Instance)
|
* C: Item type (ObjType, Instance)
|
||||||
|
*
|
||||||
|
* Also this class is kind of a mess, it would be nice to rewrite it at some point
|
||||||
*/
|
*/
|
||||||
#define TYPES_ROW_INDEX_MASK 0xFFFFFFE0
|
#define TYPES_ROW_INDEX_MASK 0xFFFFFFE0
|
||||||
#define TYPES_NODE_TYPE_MASK 0x0000001E
|
#define TYPES_NODE_TYPE_MASK 0x0000001E
|
||||||
|
@ -87,7 +90,7 @@ QModelIndex CInstancesModel::index(int row, int column, const QModelIndex &paren
|
||||||
if (mModelType == eLayers)
|
if (mModelType == eLayers)
|
||||||
{
|
{
|
||||||
CScriptLayer *pLayer = mpArea->GetScriptLayer(parent.row());
|
CScriptLayer *pLayer = mpArea->GetScriptLayer(parent.row());
|
||||||
if ((u32) row >= pLayer->GetNumObjects())
|
if ((u32) row >= pLayer->NumInstances())
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
else
|
else
|
||||||
return createIndex(row, column, (*pLayer)[row]);
|
return createIndex(row, column, (*pLayer)[row]);
|
||||||
|
@ -185,7 +188,7 @@ int CInstancesModel::rowCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
u32 RowIndex = ((parent.internalId() & TYPES_ROW_INDEX_MASK) >> TYPES_ROW_INDEX_SHIFT);
|
u32 RowIndex = ((parent.internalId() & TYPES_ROW_INDEX_MASK) >> TYPES_ROW_INDEX_SHIFT);
|
||||||
if (mModelType == eLayers)
|
if (mModelType == eLayers)
|
||||||
return (mpArea ? mpArea->GetScriptLayer(RowIndex)->GetNumObjects() : 0);
|
return (mpArea ? mpArea->GetScriptLayer(RowIndex)->NumInstances() : 0);
|
||||||
else
|
else
|
||||||
return mTemplateList[RowIndex]->NumObjects();
|
return mTemplateList[RowIndex]->NumObjects();
|
||||||
}
|
}
|
||||||
|
@ -310,8 +313,13 @@ QVariant CInstancesModel::data(const QModelIndex &index, int role) const
|
||||||
|
|
||||||
void CInstancesModel::SetEditor(CWorldEditor *pEditor)
|
void CInstancesModel::SetEditor(CWorldEditor *pEditor)
|
||||||
{
|
{
|
||||||
|
if (mpEditor)
|
||||||
|
disconnect(mpEditor, 0, this, 0);
|
||||||
|
|
||||||
mpEditor = pEditor;
|
mpEditor = pEditor;
|
||||||
mpScene = (pEditor ? pEditor->Scene() : nullptr);
|
mpScene = (pEditor ? pEditor->Scene() : nullptr);
|
||||||
|
connect(mpEditor, SIGNAL(InstancesLayerAboutToChange()), this, SLOT(InstancesLayerPreChange()));
|
||||||
|
connect(mpEditor, SIGNAL(InstancesLayerChanged(QList<CScriptNode*>)), this, SLOT(InstancesLayerPostChange(QList<CScriptNode*>)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CInstancesModel::SetMaster(CMasterTemplate *pMaster)
|
void CInstancesModel::SetMaster(CMasterTemplate *pMaster)
|
||||||
|
@ -404,6 +412,46 @@ CScriptObject* CInstancesModel::IndexObject(const QModelIndex& index) const
|
||||||
return static_cast<CScriptObject*>(index.internalPointer());
|
return static_cast<CScriptObject*>(index.internalPointer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ************ PUBLIC SLOTS ************
|
||||||
|
void CInstancesModel::InstancesLayerPreChange()
|
||||||
|
{
|
||||||
|
// This is only really needed on layers, which have rows moved.
|
||||||
|
// Types just need to update column 1 so we can handle that when the change is finished.
|
||||||
|
if (mModelType == eLayers)
|
||||||
|
emit layoutAboutToBeChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInstancesModel::InstancesLayerPostChange(const QList<CScriptNode*>& rkInstanceList)
|
||||||
|
{
|
||||||
|
QList<CScriptObject*> InstanceList;
|
||||||
|
foreach (CScriptNode *pNode, rkInstanceList)
|
||||||
|
InstanceList << pNode->Object();
|
||||||
|
|
||||||
|
QModelIndex ScriptIdx = index(0, 0, QModelIndex());
|
||||||
|
|
||||||
|
// For types, just find the instances that have changed layers and emit dataChanged for column 1.
|
||||||
|
if (mModelType == eTypes)
|
||||||
|
{
|
||||||
|
for (int iType = 0; iType < rowCount(ScriptIdx); iType++)
|
||||||
|
{
|
||||||
|
QModelIndex TypeIdx = index(iType, 0, ScriptIdx);
|
||||||
|
|
||||||
|
for (int iInst = 0; iInst < rowCount(TypeIdx); iInst++)
|
||||||
|
{
|
||||||
|
QModelIndex InstIdx = index(iInst, 1, TypeIdx);
|
||||||
|
CScriptObject *pInst = IndexObject(InstIdx);
|
||||||
|
|
||||||
|
if (InstanceList.contains(pInst))
|
||||||
|
emit dataChanged(InstIdx, InstIdx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For layers we just need to emit layoutChanged() and done
|
||||||
|
else
|
||||||
|
emit layoutChanged();
|
||||||
|
}
|
||||||
|
|
||||||
// ************ STATIC ************
|
// ************ STATIC ************
|
||||||
CInstancesModel::EIndexType CInstancesModel::IndexType(const QModelIndex& index)
|
CInstancesModel::EIndexType CInstancesModel::IndexType(const QModelIndex& index)
|
||||||
{
|
{
|
||||||
|
|
|
@ -56,6 +56,10 @@ public:
|
||||||
CScriptTemplate* IndexTemplate(const QModelIndex& index) const;
|
CScriptTemplate* IndexTemplate(const QModelIndex& index) const;
|
||||||
CScriptObject* IndexObject(const QModelIndex& index) const;
|
CScriptObject* IndexObject(const QModelIndex& index) const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void InstancesLayerPreChange();
|
||||||
|
void InstancesLayerPostChange(const QList<CScriptNode*>& rkInstanceList);
|
||||||
|
|
||||||
// Static
|
// Static
|
||||||
static EIndexType IndexType(const QModelIndex& index);
|
static EIndexType IndexType(const QModelIndex& index);
|
||||||
static ENodeType IndexNodeType(const QModelIndex& index);
|
static ENodeType IndexNodeType(const QModelIndex& index);
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "WInstancesTab.h"
|
#include "WInstancesTab.h"
|
||||||
|
|
||||||
#include "Editor/CBasicViewport.h"
|
#include "Editor/CBasicViewport.h"
|
||||||
|
#include "Editor/PropertyEdit/CPropertyView.h"
|
||||||
#include "Editor/Widgets/WDraggableSpinBox.h"
|
#include "Editor/Widgets/WDraggableSpinBox.h"
|
||||||
#include "Editor/Widgets/WVectorEditor.h"
|
#include "Editor/Widgets/WVectorEditor.h"
|
||||||
#include "Editor/Undo/UndoCommands.h"
|
#include "Editor/Undo/UndoCommands.h"
|
||||||
|
@ -80,6 +81,12 @@ CWorldEditor::CWorldEditor(QWidget *parent) :
|
||||||
connect(&mUndoStack, SIGNAL(indexChanged(int)), this, SLOT(OnUndoStackIndexChanged()));
|
connect(&mUndoStack, SIGNAL(indexChanged(int)), this, SLOT(OnUndoStackIndexChanged()));
|
||||||
|
|
||||||
connect(ui->ActionSave, SIGNAL(triggered()), this, SLOT(Save()));
|
connect(ui->ActionSave, SIGNAL(triggered()), this, SLOT(Save()));
|
||||||
|
|
||||||
|
ui->CreateTabEditorProperties->SyncToEditor(this);
|
||||||
|
ui->ModifyTabEditorProperties->SyncToEditor(this);
|
||||||
|
ui->InstancesTabEditorProperties->SyncToEditor(this);
|
||||||
|
ui->DisplayTabEditorProperties->SyncToEditor(this);
|
||||||
|
ui->WorldTabEditorProperties->SyncToEditor(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
CWorldEditor::~CWorldEditor()
|
CWorldEditor::~CWorldEditor()
|
||||||
|
@ -172,6 +179,8 @@ void CWorldEditor::SetArea(CWorld *pWorld, CGameArea *pArea, u32 AreaIndex)
|
||||||
CStringTable *pWorldNameTable = mpWorld->GetWorldName();
|
CStringTable *pWorldNameTable = mpWorld->GetWorldName();
|
||||||
TWideString WorldName = pWorldNameTable ? pWorldNameTable->GetString("ENGL", 0) : "[Untitled World]";
|
TWideString WorldName = pWorldNameTable ? pWorldNameTable->GetString("ENGL", 0) : "[Untitled World]";
|
||||||
|
|
||||||
|
if (CurrentGame() < eReturns)
|
||||||
|
{
|
||||||
CStringTable *pAreaNameTable = mpWorld->GetAreaName(AreaIndex);
|
CStringTable *pAreaNameTable = mpWorld->GetAreaName(AreaIndex);
|
||||||
TWideString AreaName = pAreaNameTable ? pAreaNameTable->GetString("ENGL", 0) : (TWideString("!") + mpWorld->GetAreaInternalName(AreaIndex).ToUTF16());
|
TWideString AreaName = pAreaNameTable ? pAreaNameTable->GetString("ENGL", 0) : (TWideString("!") + mpWorld->GetAreaInternalName(AreaIndex).ToUTF16());
|
||||||
|
|
||||||
|
@ -181,9 +190,13 @@ void CWorldEditor::SetArea(CWorld *pWorld, CGameArea *pArea, u32 AreaIndex)
|
||||||
setWindowTitle(QString("Prime World Editor - %1 - %2[*]").arg(TO_QSTRING(WorldName)).arg(TO_QSTRING(AreaName)));
|
setWindowTitle(QString("Prime World Editor - %1 - %2[*]").arg(TO_QSTRING(WorldName)).arg(TO_QSTRING(AreaName)));
|
||||||
}
|
}
|
||||||
|
|
||||||
CGameArea* CWorldEditor::ActiveArea()
|
else
|
||||||
{
|
{
|
||||||
return mpArea;
|
setWindowTitle(QString("Prime World Editor - %1[*]").arg(TO_QSTRING(WorldName)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Emit signals
|
||||||
|
emit LayersModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWorldEditor::CheckUnsavedChanges()
|
bool CWorldEditor::CheckUnsavedChanges()
|
||||||
|
@ -228,6 +241,110 @@ bool CWorldEditor::Save()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CWorldEditor::OnPropertyModified(IProperty *pProp)
|
||||||
|
{
|
||||||
|
bool EditorProperty = false;
|
||||||
|
|
||||||
|
if (!mSelection.isEmpty() && mSelection.front()->NodeType() == eScriptNode)
|
||||||
|
{
|
||||||
|
CScriptNode *pScript = static_cast<CScriptNode*>(mSelection.front());
|
||||||
|
pScript->PropertyModified(pProp);
|
||||||
|
|
||||||
|
// Check editor property
|
||||||
|
if (pScript->Object()->IsEditorProperty(pProp))
|
||||||
|
EditorProperty = true;
|
||||||
|
|
||||||
|
// If this is an editor property, update other parts of the UI to reflect the new value.
|
||||||
|
if (EditorProperty)
|
||||||
|
{
|
||||||
|
UpdateStatusBar();
|
||||||
|
UpdateSelectionUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this is a model/character, then we'll treat this as a modified selection. This is to make sure the selection bounds updates.
|
||||||
|
if (pProp->Type() == eFileProperty)
|
||||||
|
{
|
||||||
|
CFileTemplate *pFile = static_cast<CFileTemplate*>(pProp->Template());
|
||||||
|
|
||||||
|
if (pFile->AcceptsExtension("CMDL") || pFile->AcceptsExtension("ANCS") || pFile->AcceptsExtension("CHAR"))
|
||||||
|
NotifySelectionModified();
|
||||||
|
}
|
||||||
|
else if (pProp->Type() == eCharacterProperty)
|
||||||
|
NotifySelectionModified();
|
||||||
|
|
||||||
|
// Emit signal so other widgets can react to the property change
|
||||||
|
emit PropertyModified(pProp, EditorProperty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWorldEditor::SetSelectionActive(bool Active)
|
||||||
|
{
|
||||||
|
// Gather list of selected objects that actually have Active properties
|
||||||
|
QVector<CScriptObject*> Objects;
|
||||||
|
|
||||||
|
foreach (CSceneNode *pNode, mSelection)
|
||||||
|
{
|
||||||
|
if (pNode->NodeType() == eScriptNode)
|
||||||
|
{
|
||||||
|
CScriptNode *pScript = static_cast<CScriptNode*>(pNode);
|
||||||
|
CScriptObject *pInst = pScript->Object();
|
||||||
|
IProperty *pActive = pInst->ActiveProperty();
|
||||||
|
|
||||||
|
if (pActive)
|
||||||
|
Objects << pInst;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Objects.isEmpty())
|
||||||
|
{
|
||||||
|
mUndoStack.beginMacro("Toggle Active");
|
||||||
|
|
||||||
|
foreach (CScriptObject *pInst, Objects)
|
||||||
|
{
|
||||||
|
IProperty *pActive = pInst->ActiveProperty();
|
||||||
|
IPropertyValue *pOld = pActive->RawValue()->Clone();
|
||||||
|
pInst->SetActive(Active);
|
||||||
|
mUndoStack.push(new CEditScriptPropertyCommand(pActive, this, pOld, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
mUndoStack.endMacro();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWorldEditor::SetSelectionInstanceNames(const QString& rkNewName, bool IsDone)
|
||||||
|
{
|
||||||
|
// todo: this only supports one node at a time because a macro prevents us from merging undo commands
|
||||||
|
// this is fine right now because this function is only ever called with a selection of one node, but probably want to fix in the future
|
||||||
|
if (mSelection.size() == 1 && mSelection.front()->NodeType() == eScriptNode)
|
||||||
|
{
|
||||||
|
CScriptNode *pNode = static_cast<CScriptNode*>(mSelection.front());
|
||||||
|
CScriptObject *pInst = pNode->Object();
|
||||||
|
IProperty *pName = pInst->InstanceNameProperty();
|
||||||
|
|
||||||
|
if (pName)
|
||||||
|
{
|
||||||
|
TString NewName = TO_TSTRING(rkNewName);
|
||||||
|
IPropertyValue *pOld = pName->RawValue()->Clone();
|
||||||
|
pInst->SetName(NewName);
|
||||||
|
mUndoStack.push(new CEditScriptPropertyCommand(pName, this, pOld, IsDone, "Edit Instance Name"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWorldEditor::SetSelectionLayer(CScriptLayer *pLayer)
|
||||||
|
{
|
||||||
|
QList<CScriptNode*> ScriptNodes;
|
||||||
|
|
||||||
|
foreach (CSceneNode *pNode, mSelection)
|
||||||
|
{
|
||||||
|
if (pNode->NodeType() == eScriptNode)
|
||||||
|
ScriptNodes << static_cast<CScriptNode*>(pNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ScriptNodes.isEmpty())
|
||||||
|
mUndoStack.push(new CChangeLayerCommand(this, ScriptNodes, pLayer));
|
||||||
|
}
|
||||||
|
|
||||||
void CWorldEditor::UpdateStatusBar()
|
void CWorldEditor::UpdateStatusBar()
|
||||||
{
|
{
|
||||||
// Would be cool to do more frequent status bar updates with more info. Unfortunately, this causes lag.
|
// Would be cool to do more frequent status bar updates with more info. Unfortunately, this causes lag.
|
||||||
|
@ -368,7 +485,13 @@ void CWorldEditor::OnUndoStackIndexChanged()
|
||||||
{
|
{
|
||||||
const QUndoCommand *pkQCmd = mUndoStack.command(iIdx);
|
const QUndoCommand *pkQCmd = mUndoStack.command(iIdx);
|
||||||
|
|
||||||
if (pkQCmd->childCount() > 0)
|
if (const IUndoCommand *pkCmd = dynamic_cast<const IUndoCommand*>(pkQCmd))
|
||||||
|
{
|
||||||
|
if (pkCmd->AffectsCleanState())
|
||||||
|
IsClean = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (pkQCmd->childCount() > 0)
|
||||||
{
|
{
|
||||||
for (int iChild = 0; iChild < pkQCmd->childCount(); iChild++)
|
for (int iChild = 0; iChild < pkQCmd->childCount(); iChild++)
|
||||||
{
|
{
|
||||||
|
@ -382,14 +505,6 @@ void CWorldEditor::OnUndoStackIndexChanged()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const IUndoCommand *pkCmd = static_cast<const IUndoCommand*>(pkQCmd);
|
|
||||||
|
|
||||||
if (pkCmd->AffectsCleanState())
|
|
||||||
IsClean = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!IsClean) break;
|
if (!IsClean) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,11 +43,17 @@ public:
|
||||||
void closeEvent(QCloseEvent *pEvent);
|
void closeEvent(QCloseEvent *pEvent);
|
||||||
bool eventFilter(QObject *pObj, QEvent *pEvent);
|
bool eventFilter(QObject *pObj, QEvent *pEvent);
|
||||||
void SetArea(CWorld *pWorld, CGameArea *pArea, u32 AreaIndex);
|
void SetArea(CWorld *pWorld, CGameArea *pArea, u32 AreaIndex);
|
||||||
CGameArea* ActiveArea();
|
|
||||||
bool CheckUnsavedChanges();
|
bool CheckUnsavedChanges();
|
||||||
|
|
||||||
|
inline CGameArea* ActiveArea() const { return mpArea; }
|
||||||
|
inline EGame CurrentGame() const { return mpArea->Version(); }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
bool Save();
|
bool Save();
|
||||||
|
void OnPropertyModified(IProperty *pProp);
|
||||||
|
void SetSelectionActive(bool Active);
|
||||||
|
void SetSelectionInstanceNames(const QString& rkNewName, bool IsDone);
|
||||||
|
void SetSelectionLayer(CScriptLayer *pLayer);
|
||||||
|
|
||||||
void UpdateStatusBar();
|
void UpdateStatusBar();
|
||||||
void UpdateGizmoUI();
|
void UpdateGizmoUI();
|
||||||
|
@ -89,6 +95,12 @@ private slots:
|
||||||
void on_ActionSelectAll_triggered();
|
void on_ActionSelectAll_triggered();
|
||||||
void on_ActionInvertSelection_triggered();
|
void on_ActionInvertSelection_triggered();
|
||||||
void on_ActionEditPoiToWorldMap_triggered();
|
void on_ActionEditPoiToWorldMap_triggered();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void LayersModified();
|
||||||
|
void InstancesLayerAboutToChange();
|
||||||
|
void InstancesLayerChanged(const QList<CScriptNode*>& rkInstanceList);
|
||||||
|
void PropertyModified(IProperty *pProp, bool IsEditorProperty);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CWORLDEDITOR_H
|
#endif // CWORLDEDITOR_H
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="">
|
<widget class="QWidget" name="layoutWidget">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
<item>
|
<item>
|
||||||
<widget class="CSceneViewport" name="MainViewport" native="true">
|
<widget class="CSceneViewport" name="MainViewport" native="true">
|
||||||
|
@ -251,19 +251,7 @@
|
||||||
<attribute name="toolTip">
|
<attribute name="toolTip">
|
||||||
<string>Create</string>
|
<string>Create</string>
|
||||||
</attribute>
|
</attribute>
|
||||||
</widget>
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
<widget class="QWidget" name="ModifyTab">
|
|
||||||
<attribute name="icon">
|
|
||||||
<iconset resource="../Icons.qrc">
|
|
||||||
<normaloff>:/icons/Modify.png</normaloff>:/icons/Modify.png</iconset>
|
|
||||||
</attribute>
|
|
||||||
<attribute name="title">
|
|
||||||
<string/>
|
|
||||||
</attribute>
|
|
||||||
<attribute name="toolTip">
|
|
||||||
<string>Modify</string>
|
|
||||||
</attribute>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
|
@ -277,7 +265,62 @@
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="WModifyTab" name="ModifyTabContents" native="true"/>
|
<widget class="WEditorProperties" name="CreateTabEditorProperties" native="true"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="ModifyTab">
|
||||||
|
<attribute name="icon">
|
||||||
|
<iconset resource="../Icons.qrc">
|
||||||
|
<normaloff>:/icons/Modify.png</normaloff>:/icons/Modify.png</iconset>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="title">
|
||||||
|
<string/>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="toolTip">
|
||||||
|
<string>Modify</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="WEditorProperties" name="ModifyTabEditorProperties" native="true"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="WModifyTab" name="ModifyTabContents" native="true">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -292,7 +335,7 @@
|
||||||
<attribute name="toolTip">
|
<attribute name="toolTip">
|
||||||
<string>Instances</string>
|
<string>Instances</string>
|
||||||
</attribute>
|
</attribute>
|
||||||
<layout class="QHBoxLayout" name="InstancesTabLayout">
|
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
|
@ -306,7 +349,24 @@
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="WInstancesTab" name="InstancesTabContents" native="true"/>
|
<widget class="WEditorProperties" name="InstancesTabEditorProperties" native="true">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="WInstancesTab" name="InstancesTabContents" native="true">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -321,6 +381,36 @@
|
||||||
<attribute name="toolTip">
|
<attribute name="toolTip">
|
||||||
<string>Display</string>
|
<string>Display</string>
|
||||||
</attribute>
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="WEditorProperties" name="DisplayTabEditorProperties" native="true"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="WorldTab">
|
<widget class="QWidget" name="WorldTab">
|
||||||
<attribute name="icon">
|
<attribute name="icon">
|
||||||
|
@ -333,6 +423,36 @@
|
||||||
<attribute name="toolTip">
|
<attribute name="toolTip">
|
||||||
<string>World</string>
|
<string>World</string>
|
||||||
</attribute>
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_8">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="WEditorProperties" name="WorldTabEditorProperties" native="true"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -771,6 +891,12 @@
|
||||||
<header>Editor/CSceneViewport.h</header>
|
<header>Editor/CSceneViewport.h</header>
|
||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>WEditorProperties</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>Editor/WorldEditor/WEditorProperties.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../Icons.qrc"/>
|
<include location="../Icons.qrc"/>
|
||||||
|
|
|
@ -0,0 +1,196 @@
|
||||||
|
#include "WEditorProperties.h"
|
||||||
|
#include "Editor/Undo/CEditScriptPropertyCommand.h"
|
||||||
|
#include <Core/Resource/Script/CScriptLayer.h>
|
||||||
|
|
||||||
|
WEditorProperties::WEditorProperties(QWidget *pParent /*= 0*/)
|
||||||
|
: QWidget(pParent)
|
||||||
|
, mpEditor(nullptr)
|
||||||
|
, mpDisplayNode(nullptr)
|
||||||
|
, mHasEditedName(false)
|
||||||
|
{
|
||||||
|
mpActiveCheckBox = new QCheckBox;
|
||||||
|
mpActiveCheckBox->setToolTip("Active");
|
||||||
|
mpInstanceNameLineEdit = new QLineEdit;
|
||||||
|
mpInstanceNameLineEdit->setToolTip("Instance Name");
|
||||||
|
mpNameLayout = new QHBoxLayout;
|
||||||
|
mpNameLayout->addWidget(mpActiveCheckBox);
|
||||||
|
mpNameLayout->addWidget(mpInstanceNameLineEdit);
|
||||||
|
|
||||||
|
mpLayersLabel = new QLabel;
|
||||||
|
mpLayersLabel->setText("Layer:");
|
||||||
|
mpLayersLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||||
|
mpLayersComboBox = new QComboBox;
|
||||||
|
mpLayersComboBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||||
|
mpLayersLayout = new QHBoxLayout;
|
||||||
|
mpLayersLayout->addWidget(mpLayersLabel);
|
||||||
|
mpLayersLayout->addWidget(mpLayersComboBox);
|
||||||
|
|
||||||
|
mpMainLayout = new QVBoxLayout;
|
||||||
|
mpMainLayout->addLayout(mpNameLayout);
|
||||||
|
mpMainLayout->addLayout(mpLayersLayout);
|
||||||
|
mpMainLayout->setContentsMargins(6, 6, 6, 0);
|
||||||
|
mpMainLayout->setSpacing(3);
|
||||||
|
setLayout(mpMainLayout);
|
||||||
|
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||||
|
|
||||||
|
QFont Font = font();
|
||||||
|
Font.setPointSize(10);
|
||||||
|
setFont(Font);
|
||||||
|
mpInstanceNameLineEdit->setFont(Font);
|
||||||
|
mpLayersLabel->setFont(Font);
|
||||||
|
|
||||||
|
QFont ComboFont = mpLayersComboBox->font();
|
||||||
|
ComboFont.setPointSize(10);
|
||||||
|
mpLayersComboBox->setFont(ComboFont);
|
||||||
|
|
||||||
|
connect(mpActiveCheckBox, SIGNAL(clicked()), this, SLOT(OnActiveChanged()));
|
||||||
|
connect(mpInstanceNameLineEdit, SIGNAL(textEdited(QString)), this, SLOT(OnInstanceNameEdited()));
|
||||||
|
connect(mpInstanceNameLineEdit, SIGNAL(editingFinished()), this, SLOT(OnInstanceNameEditFinished()));
|
||||||
|
connect(mpLayersComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(OnLayerChanged()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void WEditorProperties::SyncToEditor(CWorldEditor *pEditor)
|
||||||
|
{
|
||||||
|
if (mpEditor)
|
||||||
|
disconnect(mpEditor, 0, this, 0);
|
||||||
|
|
||||||
|
mpEditor = pEditor;
|
||||||
|
connect(mpEditor, SIGNAL(SelectionModified()), this, SLOT(OnSelectionModified()));
|
||||||
|
connect(mpEditor, SIGNAL(LayersModified()), this, SLOT(OnLayersModified()));
|
||||||
|
connect(mpEditor, SIGNAL(InstancesLayerChanged(QList<CScriptNode*>)), this, SLOT(OnInstancesLayerChanged(QList<CScriptNode*>)));
|
||||||
|
connect(mpEditor, SIGNAL(PropertyModified(IProperty*,bool)), this, SLOT(OnPropertyModified(IProperty*,bool)));
|
||||||
|
|
||||||
|
OnLayersModified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WEditorProperties::SetLayerComboBox()
|
||||||
|
{
|
||||||
|
mpLayersComboBox->blockSignals(true);
|
||||||
|
|
||||||
|
if (mpDisplayNode && mpDisplayNode->NodeType() == eScriptNode)
|
||||||
|
{
|
||||||
|
CScriptNode *pScript = static_cast<CScriptNode*>(mpDisplayNode);
|
||||||
|
CScriptLayer *pLayer = pScript->Object()->Layer();
|
||||||
|
for (u32 iLyr = 0; iLyr < mpEditor->ActiveArea()->GetScriptLayerCount(); iLyr++)
|
||||||
|
{
|
||||||
|
if (mpEditor->ActiveArea()->GetScriptLayer(iLyr) == pLayer)
|
||||||
|
{
|
||||||
|
mpLayersComboBox->setCurrentIndex(iLyr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mpLayersComboBox->setEnabled(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mpLayersComboBox->setCurrentIndex(-1);
|
||||||
|
mpLayersComboBox->setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
mpLayersComboBox->blockSignals(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************ PUBLIC SLOTS ************
|
||||||
|
void WEditorProperties::OnSelectionModified()
|
||||||
|
{
|
||||||
|
const QList<CSceneNode*>& rkSelection = mpEditor->GetSelection();
|
||||||
|
mpDisplayNode = (rkSelection.size() == 1 ? rkSelection.front() : nullptr);
|
||||||
|
|
||||||
|
if (rkSelection.empty() || rkSelection.size() != 1 || mpDisplayNode->NodeType() != eScriptNode)
|
||||||
|
{
|
||||||
|
mpActiveCheckBox->setChecked(false);
|
||||||
|
mpActiveCheckBox->setEnabled(false);
|
||||||
|
mpInstanceNameLineEdit->setEnabled(false);
|
||||||
|
|
||||||
|
if (rkSelection.empty())
|
||||||
|
mpInstanceNameLineEdit->clear();
|
||||||
|
else if (mpDisplayNode)
|
||||||
|
mpInstanceNameLineEdit->setText(TO_QSTRING(mpDisplayNode->Name()));
|
||||||
|
else
|
||||||
|
mpInstanceNameLineEdit->setText(QString("[%1 objects selected]").arg(rkSelection.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UpdatePropertyValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
SetLayerComboBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WEditorProperties::OnPropertyModified(IProperty* /*pProp*/, bool IsEditorProperty)
|
||||||
|
{
|
||||||
|
if (!mpInstanceNameLineEdit->hasFocus())
|
||||||
|
{
|
||||||
|
if (mpDisplayNode->NodeType() == eScriptNode && IsEditorProperty)
|
||||||
|
UpdatePropertyValues();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WEditorProperties::OnInstancesLayerChanged(const QList<CScriptNode*>& rkNodeList)
|
||||||
|
{
|
||||||
|
if (rkNodeList.contains((CScriptNode*) mpDisplayNode))
|
||||||
|
SetLayerComboBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WEditorProperties::OnLayersModified()
|
||||||
|
{
|
||||||
|
CGameArea *pArea = mpEditor->ActiveArea();
|
||||||
|
mpLayersComboBox->clear();
|
||||||
|
|
||||||
|
if (pArea)
|
||||||
|
{
|
||||||
|
for (u32 iLyr = 0; iLyr < pArea->GetScriptLayerCount(); iLyr++)
|
||||||
|
mpLayersComboBox->addItem(TO_QSTRING(pArea->GetScriptLayer(iLyr)->Name()));
|
||||||
|
}
|
||||||
|
|
||||||
|
SetLayerComboBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WEditorProperties::UpdatePropertyValues()
|
||||||
|
{
|
||||||
|
CScriptNode *pScript = static_cast<CScriptNode*>(mpDisplayNode);
|
||||||
|
CScriptObject *pInst = pScript->Object();
|
||||||
|
|
||||||
|
mpActiveCheckBox->setChecked(pInst->IsActive());
|
||||||
|
mpActiveCheckBox->setEnabled(pInst->ActiveProperty() != nullptr);
|
||||||
|
|
||||||
|
mpInstanceNameLineEdit->blockSignals(true);
|
||||||
|
mpInstanceNameLineEdit->setText(TO_QSTRING(pInst->InstanceName()));
|
||||||
|
mpInstanceNameLineEdit->setEnabled(pInst->InstanceNameProperty() != nullptr);
|
||||||
|
mpInstanceNameLineEdit->blockSignals(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************ PROTECTED SLOTS ************
|
||||||
|
void WEditorProperties::OnActiveChanged()
|
||||||
|
{
|
||||||
|
mpEditor->SetSelectionActive(mpActiveCheckBox->isChecked());
|
||||||
|
}
|
||||||
|
|
||||||
|
void WEditorProperties::OnInstanceNameEdited()
|
||||||
|
{
|
||||||
|
// This function triggers when the user is actively editing the Instance Name line edit.
|
||||||
|
mHasEditedName = true;
|
||||||
|
mpEditor->SetSelectionInstanceNames(mpInstanceNameLineEdit->text(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WEditorProperties::OnInstanceNameEditFinished()
|
||||||
|
{
|
||||||
|
// This function triggers when the user is finished editing the Instance Name line edit.
|
||||||
|
if (mHasEditedName)
|
||||||
|
mpEditor->SetSelectionInstanceNames(mpInstanceNameLineEdit->text(), true);
|
||||||
|
|
||||||
|
mHasEditedName = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WEditorProperties::OnLayerChanged()
|
||||||
|
{
|
||||||
|
int Index = mpLayersComboBox->currentIndex();
|
||||||
|
|
||||||
|
if (Index >= 0)
|
||||||
|
{
|
||||||
|
CScriptLayer *pLayer = mpEditor->ActiveArea()->GetScriptLayer(Index);
|
||||||
|
mpEditor->SetSelectionLayer(pLayer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
#ifndef WEDITORPROPERTIES_H
|
||||||
|
#define WEDITORPROPERTIES_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include "CWorldEditor.h"
|
||||||
|
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
class WEditorProperties : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
CWorldEditor *mpEditor;
|
||||||
|
CSceneNode *mpDisplayNode;
|
||||||
|
|
||||||
|
QVBoxLayout *mpMainLayout;
|
||||||
|
|
||||||
|
QCheckBox *mpActiveCheckBox;
|
||||||
|
QLineEdit *mpInstanceNameLineEdit;
|
||||||
|
QHBoxLayout *mpNameLayout;
|
||||||
|
|
||||||
|
QLabel *mpLayersLabel;
|
||||||
|
QComboBox *mpLayersComboBox;
|
||||||
|
QHBoxLayout *mpLayersLayout;
|
||||||
|
|
||||||
|
bool mHasEditedName;
|
||||||
|
|
||||||
|
public:
|
||||||
|
WEditorProperties(QWidget *pParent = 0);
|
||||||
|
void SyncToEditor(CWorldEditor *pEditor);
|
||||||
|
void SetLayerComboBox();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void OnSelectionModified();
|
||||||
|
void OnPropertyModified(IProperty *pProp, bool IsEditorProperty);
|
||||||
|
void OnInstancesLayerChanged(const QList<CScriptNode*>& rkNodeList);
|
||||||
|
void OnLayersModified();
|
||||||
|
void UpdatePropertyValues();
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
void OnActiveChanged();
|
||||||
|
void OnInstanceNameEdited();
|
||||||
|
void OnInstanceNameEditFinished();
|
||||||
|
void OnLayerChanged();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WEDITORPROPERTIES_H
|
|
@ -16,7 +16,6 @@ WModifyTab::WModifyTab(QWidget *pParent) :
|
||||||
ui->PropertyView->header()->resizeSection(0, PropViewWidth * 0.3);
|
ui->PropertyView->header()->resizeSection(0, PropViewWidth * 0.3);
|
||||||
ui->PropertyView->header()->resizeSection(1, PropViewWidth * 0.3);
|
ui->PropertyView->header()->resizeSection(1, PropViewWidth * 0.3);
|
||||||
ui->PropertyView->header()->setSectionResizeMode(1, QHeaderView::Fixed);
|
ui->PropertyView->header()->setSectionResizeMode(1, QHeaderView::Fixed);
|
||||||
connect(ui->PropertyView, SIGNAL(PropertyModified(IProperty*)), this, SLOT(OnPropertyModified(IProperty*)));
|
|
||||||
|
|
||||||
mpInLinkModel = new CLinkModel(this);
|
mpInLinkModel = new CLinkModel(this);
|
||||||
mpInLinkModel->SetConnectionType(CLinkModel::eIncoming);
|
mpInLinkModel->SetConnectionType(CLinkModel::eIncoming);
|
||||||
|
@ -86,30 +85,7 @@ void WModifyTab::OnWorldSelectionTransformed()
|
||||||
ui->PropertyView->UpdateEditorProperties(QModelIndex());
|
ui->PropertyView->UpdateEditorProperties(QModelIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WModifyTab::OnPropertyModified(IProperty *pProp)
|
// ************ PRIVATE SLOTS ************
|
||||||
{
|
|
||||||
if (mpSelectedNode->NodeType() == eScriptNode)
|
|
||||||
{
|
|
||||||
CScriptNode *pNode = static_cast<CScriptNode*>(mpSelectedNode);
|
|
||||||
pNode->PropertyModified(pProp);
|
|
||||||
|
|
||||||
// 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(pProp) && pProp->Type() == eStringProperty)
|
|
||||||
mpWorldEditor->UpdateSelectionUI();
|
|
||||||
|
|
||||||
// If this is a model/character, then we'll treat it as a modified selection. This is to make sure the selection bounds updates.
|
|
||||||
if (pProp->Type() == eFileProperty)
|
|
||||||
{
|
|
||||||
CFileTemplate *pFile = static_cast<CFileTemplate*>(pProp->Template());
|
|
||||||
|
|
||||||
if (pFile->AcceptsExtension("CMDL") || pFile->AcceptsExtension("ANCS") || pFile->AcceptsExtension("CHAR"))
|
|
||||||
mpWorldEditor->NotifySelectionModified();
|
|
||||||
}
|
|
||||||
else if (pProp->Type() == eCharacterProperty)
|
|
||||||
mpWorldEditor->NotifySelectionModified();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WModifyTab::OnLinkTableDoubleClick(QModelIndex Index)
|
void WModifyTab::OnLinkTableDoubleClick(QModelIndex Index)
|
||||||
{
|
{
|
||||||
if (Index.column() == 0)
|
if (Index.column() == 0)
|
||||||
|
|
|
@ -36,7 +36,6 @@ public:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void OnWorldSelectionTransformed();
|
void OnWorldSelectionTransformed();
|
||||||
void OnPropertyModified(IProperty *pProp);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::WModifyTab *ui;
|
Ui::WModifyTab *ui;
|
||||||
|
|
|
@ -13,7 +13,10 @@
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Form</string>
|
<string>Form</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="MainLayout">
|
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
|
@ -105,7 +108,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>276</width>
|
<width>276</width>
|
||||||
<height>457</height>
|
<height>460</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
<property name="Active" ID="0x255A4580:0x41435456"/>
|
<property name="Active" ID="0x255A4580:0x41435456"/>
|
||||||
</properties>
|
</properties>
|
||||||
<assets/>
|
<assets/>
|
||||||
<preview_scale>0.5</preview_scale>
|
|
||||||
<rotation_type>enabled</rotation_type>
|
<rotation_type>enabled</rotation_type>
|
||||||
<scale_type>enabled</scale_type>
|
<scale_type>enabled</scale_type>
|
||||||
</editor>
|
</editor>
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
<assets>
|
<assets>
|
||||||
<model source="file">script/common/CameraWaypoint.cmdl</model>
|
<model source="file">script/common/CameraWaypoint.cmdl</model>
|
||||||
</assets>
|
</assets>
|
||||||
|
<preview_scale>0.5</preview_scale>
|
||||||
<rotation_type>enabled</rotation_type>
|
<rotation_type>enabled</rotation_type>
|
||||||
<scale_type>enabled</scale_type>
|
<scale_type>enabled</scale_type>
|
||||||
</editor>
|
</editor>
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
<assets>
|
<assets>
|
||||||
<model source="file">script/common/CameraWaypoint.cmdl</model>
|
<model source="file">script/common/CameraWaypoint.cmdl</model>
|
||||||
</assets>
|
</assets>
|
||||||
|
<preview_scale>0.5</preview_scale>
|
||||||
<rotation_type>enabled</rotation_type>
|
<rotation_type>enabled</rotation_type>
|
||||||
<scale_type>enabled</scale_type>
|
<scale_type>enabled</scale_type>
|
||||||
</editor>
|
</editor>
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
<assets>
|
<assets>
|
||||||
<model source="file">script/common/SpiderBallWaypoint.cmdl</model>
|
<model source="file">script/common/SpiderBallWaypoint.cmdl</model>
|
||||||
</assets>
|
</assets>
|
||||||
|
<preview_scale>0.5</preview_scale>
|
||||||
<rotation_type>enabled</rotation_type>
|
<rotation_type>enabled</rotation_type>
|
||||||
<scale_type>enabled</scale_type>
|
<scale_type>enabled</scale_type>
|
||||||
</editor>
|
</editor>
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
<assets>
|
<assets>
|
||||||
<model source="file">script/common/Waypoint.CMDL</model>
|
<model source="file">script/common/Waypoint.CMDL</model>
|
||||||
</assets>
|
</assets>
|
||||||
|
<preview_scale>0.5</preview_scale>
|
||||||
<rotation_type>enabled</rotation_type>
|
<rotation_type>enabled</rotation_type>
|
||||||
<scale_type>enabled</scale_type>
|
<scale_type>enabled</scale_type>
|
||||||
</editor>
|
</editor>
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
<property name="Active" ID="0x255A4580:0x41435456"/>
|
<property name="Active" ID="0x255A4580:0x41435456"/>
|
||||||
</properties>
|
</properties>
|
||||||
<assets/>
|
<assets/>
|
||||||
<preview_scale>0.5</preview_scale>
|
|
||||||
<rotation_type>enabled</rotation_type>
|
<rotation_type>enabled</rotation_type>
|
||||||
<scale_type>enabled</scale_type>
|
<scale_type>enabled</scale_type>
|
||||||
</editor>
|
</editor>
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
<property name="Active" ID="0x255A4580:0x41435456"/>
|
<property name="Active" ID="0x255A4580:0x41435456"/>
|
||||||
</properties>
|
</properties>
|
||||||
<assets/>
|
<assets/>
|
||||||
<preview_scale>0.5</preview_scale>
|
|
||||||
<rotation_type>enabled</rotation_type>
|
<rotation_type>enabled</rotation_type>
|
||||||
<scale_type>enabled</scale_type>
|
<scale_type>enabled</scale_type>
|
||||||
</editor>
|
</editor>
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
<property name="Active" ID="0x255A4580:0x41435456"/>
|
<property name="Active" ID="0x255A4580:0x41435456"/>
|
||||||
</properties>
|
</properties>
|
||||||
<assets/>
|
<assets/>
|
||||||
<preview_scale>0.5</preview_scale>
|
|
||||||
<rotation_type>enabled</rotation_type>
|
<rotation_type>enabled</rotation_type>
|
||||||
<scale_type>enabled</scale_type>
|
<scale_type>enabled</scale_type>
|
||||||
</editor>
|
</editor>
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
<property name="Active" ID="0x255A4580:0x41435456"/>
|
<property name="Active" ID="0x255A4580:0x41435456"/>
|
||||||
</properties>
|
</properties>
|
||||||
<assets/>
|
<assets/>
|
||||||
<preview_scale>0.5</preview_scale>
|
|
||||||
<rotation_type>enabled</rotation_type>
|
<rotation_type>enabled</rotation_type>
|
||||||
<scale_type>enabled</scale_type>
|
<scale_type>enabled</scale_type>
|
||||||
</editor>
|
</editor>
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
<property name="Active" ID="0x255A4580:0x41435456"/>
|
<property name="Active" ID="0x255A4580:0x41435456"/>
|
||||||
</properties>
|
</properties>
|
||||||
<assets/>
|
<assets/>
|
||||||
<preview_scale>0.5</preview_scale>
|
|
||||||
<rotation_type>enabled</rotation_type>
|
<rotation_type>enabled</rotation_type>
|
||||||
<scale_type>enabled</scale_type>
|
<scale_type>enabled</scale_type>
|
||||||
</editor>
|
</editor>
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
<property name="Active" ID="0x255A4580:0x41435456"/>
|
<property name="Active" ID="0x255A4580:0x41435456"/>
|
||||||
</properties>
|
</properties>
|
||||||
<assets/>
|
<assets/>
|
||||||
<preview_scale>0.5</preview_scale>
|
|
||||||
<rotation_type>enabled</rotation_type>
|
<rotation_type>enabled</rotation_type>
|
||||||
<scale_type>enabled</scale_type>
|
<scale_type>enabled</scale_type>
|
||||||
</editor>
|
</editor>
|
||||||
|
|
Loading…
Reference in New Issue