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/SSurface.cpp \
|
||||
Resource/Script/CMasterTemplate.cpp \
|
||||
Resource/Script/CScriptLayer.cpp \
|
||||
Resource/Script/CScriptObject.cpp \
|
||||
Resource/Script/CScriptTemplate.cpp \
|
||||
Resource/CAnimationParameters.cpp \
|
||||
|
|
|
@ -116,11 +116,11 @@ void CScriptCooker::WriteLayerMP1(CScriptLayer *pLayer)
|
|||
{
|
||||
u32 LayerStart = mpSCLY->Tell();
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -572,7 +572,7 @@ void CAreaLoader::SetUpObjects()
|
|||
if (!pLayer) break;
|
||||
}
|
||||
|
||||
for (u32 iObj = 0; iObj < pLayer->GetNumObjects(); iObj++)
|
||||
for (u32 iObj = 0; iObj < pLayer->NumInstances(); iObj++)
|
||||
{
|
||||
// Add object to object map
|
||||
CScriptObject *pObj = (*pLayer)[iObj];
|
||||
|
|
|
@ -123,11 +123,11 @@ void CScriptLoader::ReadProperty(IProperty *pProp, u32 Size, IInputStream& SCLY)
|
|||
|
||||
case eArrayProperty: {
|
||||
CArrayProperty *pArrayCast = static_cast<CArrayProperty*>(pProp);
|
||||
u32 Size = SCLY.ReadLong();
|
||||
int Size = SCLY.ReadLong();
|
||||
|
||||
pArrayCast->Resize(Size);
|
||||
|
||||
for (u32 iElem = 0; iElem < Size; iElem++)
|
||||
for (int iElem = 0; iElem < Size; iElem++)
|
||||
{
|
||||
if (mVersion < eEchoesDemo)
|
||||
LoadStructMP1(SCLY, static_cast<CPropertyStruct*>(pArrayCast->PropertyByIndex(iElem)), pArrayCast->SubStructTemplate());
|
||||
|
@ -243,7 +243,7 @@ CScriptLayer* CScriptLoader::LoadLayerMP1(IInputStream &SCLY)
|
|||
{
|
||||
CScriptObject *pObj = LoadObjectMP1(SCLY);
|
||||
if (pObj)
|
||||
mpLayer->AddObject(pObj);
|
||||
mpLayer->AddInstance(pObj);
|
||||
}
|
||||
|
||||
// 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);
|
||||
if (pObj)
|
||||
mpLayer->AddObject(pObj);
|
||||
mpLayer->AddInstance(pObj);
|
||||
}
|
||||
|
||||
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
|
||||
#define SSCRIPTLAYER_H
|
||||
#ifndef CSCRIPTLAYER_H
|
||||
#define CSCRIPTLAYER_H
|
||||
|
||||
#include "CScriptObject.h"
|
||||
#include <Common/types.h>
|
||||
|
@ -11,38 +11,85 @@ class CScriptLayer
|
|||
TString mLayerName;
|
||||
bool mActive;
|
||||
bool mVisible;
|
||||
std::vector<CScriptObject*> mObjects;
|
||||
std::vector<CScriptObject*> mInstances;
|
||||
public:
|
||||
CScriptLayer();
|
||||
~CScriptLayer();
|
||||
CScriptLayer()
|
||||
: mLayerName("New Layer")
|
||||
, mActive(true)
|
||||
, mVisible(true)
|
||||
{
|
||||
}
|
||||
|
||||
~CScriptLayer()
|
||||
{
|
||||
for (auto it = mInstances.begin(); it != mInstances.end(); it++)
|
||||
delete *it;
|
||||
}
|
||||
|
||||
// Data Manipulation
|
||||
void AddObject(CScriptObject* object);
|
||||
void DeleteObjectByIndex(u32 index);
|
||||
void DeleteObjectByID(u32 ID);
|
||||
void Reserve(u32 amount);
|
||||
void AddInstance(CScriptObject *pObject)
|
||||
{
|
||||
mInstances.push_back(pObject);
|
||||
}
|
||||
|
||||
// Getters and Setters
|
||||
TString Name();
|
||||
bool IsActive();
|
||||
bool IsVisible();
|
||||
u32 GetNumObjects();
|
||||
CScriptObject* ObjectByIndex(u32 index);
|
||||
CScriptObject* ObjectByID(u32 ID);
|
||||
void RemoveInstance(CScriptObject *pInstance)
|
||||
{
|
||||
for (auto it = mInstances.begin(); it != mInstances.end(); it++)
|
||||
{
|
||||
if (*it == pInstance)
|
||||
{
|
||||
mInstances.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetName(const TString& name);
|
||||
void SetActive(bool active);
|
||||
void SetVisible(bool visible);
|
||||
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);
|
||||
CScriptObject* operator[](u32 Index) { return InstanceByIndex(Index); }
|
||||
};
|
||||
|
||||
// ************* INLINE FUNCTIONS *************
|
||||
inline CScriptObject* CScriptLayer::operator[](u32 index)
|
||||
{
|
||||
return mObjects[index];
|
||||
}
|
||||
|
||||
|
||||
#endif // SSCRIPTLAYER_H
|
||||
#endif // CSCRIPTLAYER_H
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "CScriptObject.h"
|
||||
#include "CScriptLayer.h"
|
||||
#include "CMasterTemplate.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 ************
|
||||
IProperty* CScriptObject::PropertyByIndex(u32 index) const
|
||||
{
|
||||
|
|
|
@ -50,6 +50,7 @@ public:
|
|||
void EvaluateCollisionModel();
|
||||
void EvaluateVolume();
|
||||
bool IsEditorProperty(IProperty *pProp);
|
||||
void SetLayer(CScriptLayer *pLayer);
|
||||
|
||||
CScriptTemplate* Template() const;
|
||||
CMasterTemplate* MasterTemplate() const;
|
||||
|
@ -84,6 +85,12 @@ public:
|
|||
CCollisionMeshGroup* GetCollision() const;
|
||||
EVolumeShape VolumeShape() 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
|
||||
|
|
|
@ -2,6 +2,11 @@
|
|||
#include "IPropertyTemplate.h"
|
||||
|
||||
// ************ IProperty ************
|
||||
CPropertyStruct* IProperty::RootStruct()
|
||||
{
|
||||
return (mpParent ? mpParent->RootStruct() : Type() == eStructProperty ? static_cast<CPropertyStruct*>(this) : nullptr);
|
||||
}
|
||||
|
||||
IPropertyTemplate* IProperty::Template() const
|
||||
{
|
||||
return mpTemplate;
|
||||
|
@ -111,23 +116,23 @@ CPropertyStruct* CPropertyStruct::StructByIDString(const TIDString& rkStr) const
|
|||
}
|
||||
|
||||
// ************ CArrayProperty ************
|
||||
void CArrayProperty::Resize(u32 Size)
|
||||
void CArrayProperty::Resize(int Size)
|
||||
{
|
||||
u32 OldSize = mProperties.size();
|
||||
int OldSize = mProperties.size();
|
||||
if (OldSize == Size) return;
|
||||
|
||||
if (Size < OldSize)
|
||||
{
|
||||
for (u32 i = mProperties.size() - 1; i >= Size; i--)
|
||||
delete mProperties[i];
|
||||
for (int iProp = mProperties.size() - 1; iProp >= Size; iProp--)
|
||||
delete mProperties[iProp];
|
||||
}
|
||||
|
||||
mProperties.resize(Size);
|
||||
|
||||
if (Size > OldSize)
|
||||
{
|
||||
for (u32 i = OldSize; i < Size; i++)
|
||||
mProperties[i] = static_cast<CArrayTemplate*>(mpTemplate)->CreateSubStruct(this);
|
||||
for (int iProp = OldSize; iProp < Size; iProp++)
|
||||
mProperties[iProp] = static_cast<CArrayTemplate*>(mpTemplate)->CreateSubStruct(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,8 @@ public:
|
|||
inline CPropertyStruct* Parent() const { return mpParent; }
|
||||
inline void SetParent(CPropertyStruct *pParent) { mpParent = pParent; }
|
||||
|
||||
CPropertyStruct* RootStruct();
|
||||
|
||||
// These functions can't be in the header to avoid circular includes with IPropertyTemplate.h
|
||||
IPropertyTemplate* Template() const;
|
||||
TString Name() const;
|
||||
|
@ -178,7 +180,7 @@ public:
|
|||
inline void Reserve(u32 amount) { mProperties.reserve(amount); }
|
||||
|
||||
// Functions
|
||||
void Resize(u32 Size);
|
||||
void Resize(int Size);
|
||||
CStructTemplate* SubStructTemplate() const;
|
||||
TString ElementName() const;
|
||||
};
|
||||
|
|
|
@ -116,12 +116,12 @@ void CScene::SetActiveArea(CGameArea *pArea)
|
|||
for (u32 iLyr = 0; iLyr < NumLayers; iLyr++)
|
||||
{
|
||||
CScriptLayer *pLayer = mpArea->GetScriptLayer(iLyr);
|
||||
u32 NumObjects = pLayer->GetNumObjects();
|
||||
u32 NumObjects = pLayer->NumInstances();
|
||||
mNodes[eScriptNode].reserve(mNodes[eScriptNode].size() + NumObjects);
|
||||
|
||||
for (u32 iObj = 0; iObj < NumObjects; iObj++)
|
||||
{
|
||||
CScriptObject *pObj = pLayer->ObjectByIndex(iObj);
|
||||
CScriptObject *pObj = pLayer->InstanceByIndex(iObj);
|
||||
CScriptNode *pNode = CreateScriptNode(pObj);
|
||||
pNode->BuildLightList(mpArea);
|
||||
|
||||
|
@ -142,9 +142,9 @@ void CScene::SetActiveArea(CGameArea *pArea)
|
|||
CScriptLayer *pGenLayer = mpArea->GetGeneratorLayer();
|
||||
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);
|
||||
|
||||
// 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);
|
||||
glDepthMask(GL_TRUE);
|
||||
CGraphics::UpdateVertexBlock();
|
||||
CGraphics::UpdatePixelBlock();
|
||||
CDrawUtil::DrawShadedCube(CColor::skTransparentPurple * TintColor(ViewInfo));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -137,7 +137,9 @@ HEADERS += \
|
|||
Undo/CEditScriptPropertyCommand.h \
|
||||
Undo/CResizeScriptArrayCommand.h \
|
||||
Undo/CBasicPropertyCommand.h \
|
||||
Undo/IUndoCommand.h
|
||||
Undo/IUndoCommand.h \
|
||||
WorldEditor/WEditorProperties.h \
|
||||
Undo/CChangeLayerCommand.h
|
||||
|
||||
# Source Files
|
||||
SOURCES += \
|
||||
|
@ -191,7 +193,9 @@ SOURCES += \
|
|||
WorldEditor/CInstancesModel.cpp \
|
||||
Undo/CEditScriptPropertyCommand.cpp \
|
||||
Undo/CResizeScriptArrayCommand.cpp \
|
||||
Undo/CBasicPropertyCommand.cpp
|
||||
Undo/CBasicPropertyCommand.cpp \
|
||||
WorldEditor/WEditorProperties.cpp \
|
||||
Undo/CChangeLayerCommand.cpp
|
||||
|
||||
# UI Files
|
||||
FORMS += \
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#define CONNECT_RELAY(Widget, Index, Signal) \
|
||||
CPropertyRelay *pRelay = new CPropertyRelay(Widget, Index); \
|
||||
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*/)
|
||||
: QStyledItemDelegate(pParent)
|
||||
|
@ -57,7 +57,7 @@ QWidget* CPropertyDelegate::createEditor(QWidget *pParent, const QStyleOptionVie
|
|||
case eBoolProperty:
|
||||
{
|
||||
QCheckBox *pCheckBox = new QCheckBox(pParent);
|
||||
CONNECT_RELAY(pCheckBox, rkIndex, toggled(bool))
|
||||
CONNECT_RELAY(pCheckBox, rkIndex, toggled(bool));
|
||||
pOut = pCheckBox;
|
||||
break;
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ QWidget* CPropertyDelegate::createEditor(QWidget *pParent, const QStyleOptionVie
|
|||
WIntegralSpinBox *pSpinBox = new WIntegralSpinBox(pParent);
|
||||
pSpinBox->setMinimum(INT16_MIN);
|
||||
pSpinBox->setMaximum(INT16_MAX);
|
||||
CONNECT_RELAY(pSpinBox, rkIndex, valueChanged(int))
|
||||
CONNECT_RELAY(pSpinBox, rkIndex, valueChanged(int));
|
||||
pOut = pSpinBox;
|
||||
break;
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ QWidget* CPropertyDelegate::createEditor(QWidget *pParent, const QStyleOptionVie
|
|||
WIntegralSpinBox *pSpinBox = new WIntegralSpinBox(pParent);
|
||||
pSpinBox->setMinimum(INT32_MIN);
|
||||
pSpinBox->setMaximum(INT32_MAX);
|
||||
CONNECT_RELAY(pSpinBox, rkIndex, valueChanged(int))
|
||||
CONNECT_RELAY(pSpinBox, rkIndex, valueChanged(int));
|
||||
pOut = pSpinBox;
|
||||
break;
|
||||
}
|
||||
|
@ -86,15 +86,15 @@ QWidget* CPropertyDelegate::createEditor(QWidget *pParent, const QStyleOptionVie
|
|||
{
|
||||
WDraggableSpinBox *pSpinBox = new WDraggableSpinBox(pParent);
|
||||
pSpinBox->setSingleStep(0.1);
|
||||
CONNECT_RELAY(pSpinBox, rkIndex, valueChanged(double));
|
||||
pOut = pSpinBox;
|
||||
CONNECT_RELAY(pSpinBox, rkIndex, valueChanged(double))
|
||||
break;
|
||||
}
|
||||
|
||||
case eColorProperty:
|
||||
{
|
||||
WColorPicker *pColorPicker = new WColorPicker(pParent);
|
||||
CONNECT_RELAY(pColorPicker, rkIndex, colorChanged(QColor))
|
||||
CONNECT_RELAY(pColorPicker, rkIndex, colorChanged(QColor));
|
||||
pOut = pColorPicker;
|
||||
break;
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ QWidget* CPropertyDelegate::createEditor(QWidget *pParent, const QStyleOptionVie
|
|||
case eStringProperty:
|
||||
{
|
||||
QLineEdit *pLineEdit = new QLineEdit(pParent);
|
||||
CONNECT_RELAY(pLineEdit, rkIndex, textEdited(QString))
|
||||
CONNECT_RELAY(pLineEdit, rkIndex, textEdited(QString));
|
||||
pOut = pLineEdit;
|
||||
break;
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ QWidget* CPropertyDelegate::createEditor(QWidget *pParent, const QStyleOptionVie
|
|||
for (u32 iEnum = 0; iEnum < pTemp->NumEnumerators(); iEnum++)
|
||||
pComboBox->addItem(TO_QSTRING(pTemp->EnumeratorName(iEnum)));
|
||||
|
||||
CONNECT_RELAY(pComboBox, rkIndex, currentIndexChanged(int))
|
||||
CONNECT_RELAY(pComboBox, rkIndex, currentIndexChanged(int));
|
||||
pOut = pComboBox;
|
||||
break;
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ QWidget* CPropertyDelegate::createEditor(QWidget *pParent, const QStyleOptionVie
|
|||
pSelector->SetAllowedExtensions(pTemp->Extensions());
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ QWidget* CPropertyDelegate::createEditor(QWidget *pParent, const QStyleOptionVie
|
|||
else if (pProp->Type() == eBitfieldProperty)
|
||||
{
|
||||
QCheckBox *pCheckBox = new QCheckBox(pParent);
|
||||
CONNECT_RELAY(pCheckBox, rkIndex, toggled(bool))
|
||||
CONNECT_RELAY(pCheckBox, rkIndex, toggled(bool));
|
||||
pOut = pCheckBox;
|
||||
}
|
||||
|
||||
|
@ -178,7 +178,7 @@ QWidget* CPropertyDelegate::createEditor(QWidget *pParent, const QStyleOptionVie
|
|||
pSpinBox->setMaximum(1.0);
|
||||
}
|
||||
|
||||
CONNECT_RELAY(pSpinBox, rkIndex, valueChanged(double))
|
||||
CONNECT_RELAY(pSpinBox, rkIndex, valueChanged(double));
|
||||
pOut = pSpinBox;
|
||||
}
|
||||
}
|
||||
|
@ -194,6 +194,7 @@ QWidget* CPropertyDelegate::createEditor(QWidget *pParent, const QStyleOptionVie
|
|||
void CPropertyDelegate::setEditorData(QWidget *pEditor, const QModelIndex &rkIndex) const
|
||||
{
|
||||
BlockRelays(true);
|
||||
mEditInProgress = false; // fixes case where user does undo mid-edit
|
||||
|
||||
if (pEditor)
|
||||
{
|
||||
|
@ -433,11 +434,11 @@ void CPropertyDelegate::setModelData(QWidget *pEditor, QAbstractItemModel* /*pMo
|
|||
{
|
||||
WIntegralSpinBox *pSpinBox = static_cast<WIntegralSpinBox*>(pEditor);
|
||||
CArrayProperty *pArray = static_cast<CArrayProperty*>(pProp);
|
||||
u32 NewCount = pSpinBox->value();
|
||||
int NewCount = pSpinBox->value();
|
||||
|
||||
if (pArray->Count() != NewCount)
|
||||
{
|
||||
CResizeScriptArrayCommand *pCmd = new CResizeScriptArrayCommand(mpModel, rkIndex, NewCount);
|
||||
CResizeScriptArrayCommand *pCmd = new CResizeScriptArrayCommand(pProp, mpEditor, mpModel, NewCount);
|
||||
mpEditor->UndoStack()->push(pCmd);
|
||||
}
|
||||
break;
|
||||
|
@ -517,7 +518,8 @@ void CPropertyDelegate::setModelData(QWidget *pEditor, QAbstractItemModel* /*pMo
|
|||
// Create undo command
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -563,7 +565,7 @@ QWidget* CPropertyDelegate::CreateCharacterEditor(QWidget *pParent, const QModel
|
|||
else
|
||||
pSelector->SetAllowedExtensions("CHAR");
|
||||
|
||||
CONNECT_RELAY(pSelector, rkIndex, ResourceChanged(QString))
|
||||
CONNECT_RELAY(pSelector, rkIndex, ResourceChanged(QString));
|
||||
return pSelector;
|
||||
}
|
||||
|
||||
|
@ -579,14 +581,14 @@ QWidget* CPropertyDelegate::CreateCharacterEditor(QWidget *pParent, const QModel
|
|||
pComboBox->addItem(TO_QSTRING(pAnimSet->getNodeName(iChr)));
|
||||
}
|
||||
|
||||
CONNECT_RELAY(pComboBox, rkIndex, currentIndexChanged(int))
|
||||
CONNECT_RELAY(pComboBox, rkIndex, currentIndexChanged(int));
|
||||
return pComboBox;
|
||||
}
|
||||
|
||||
if (Type == eLongProperty)
|
||||
{
|
||||
WIntegralSpinBox *pSpinBox = new WIntegralSpinBox(pParent);
|
||||
CONNECT_RELAY(pSpinBox, rkIndex, valueChanged(int))
|
||||
CONNECT_RELAY(pSpinBox, rkIndex, valueChanged(int));
|
||||
return pSpinBox;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,48 @@ IProperty* CPropertyModel::PropertyForIndex(const QModelIndex& rkIndex, bool Han
|
|||
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
|
||||
{
|
||||
return 2;
|
||||
|
@ -393,6 +435,11 @@ Qt::ItemFlags CPropertyModel::flags(const QModelIndex& rkIndex) const
|
|||
else return (Qt::ItemIsEnabled | Qt::ItemIsEditable);
|
||||
}
|
||||
|
||||
void CPropertyModel::NotifyPropertyModified(IProperty *pProp)
|
||||
{
|
||||
NotifyPropertyModified(IndexForProperty(pProp));
|
||||
}
|
||||
|
||||
void CPropertyModel::NotifyPropertyModified(const QModelIndex& rkIndex)
|
||||
{
|
||||
if (rowCount(rkIndex) != 0)
|
||||
|
@ -405,7 +452,9 @@ void CPropertyModel::NotifyPropertyModified(const QModelIndex& rkIndex)
|
|||
emit dataChanged(Parent, Parent);
|
||||
}
|
||||
|
||||
emit dataChanged(rkIndex, rkIndex);
|
||||
QModelIndex IndexC1 = rkIndex.sibling(rkIndex.row(), 1);
|
||||
emit dataChanged(IndexC1, IndexC1);
|
||||
|
||||
emit PropertyModified(rkIndex);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ public:
|
|||
CPropertyModel(QObject *pParent = 0);
|
||||
void SetBaseStruct(CPropertyStruct *pBaseStruct);
|
||||
IProperty* PropertyForIndex(const QModelIndex& rkIndex, bool HandleFlaggedPointers) const;
|
||||
QModelIndex IndexForProperty(IProperty *pProp) const;
|
||||
|
||||
int columnCount(const QModelIndex& rkParent) const;
|
||||
int rowCount(const QModelIndex& rkParent) const;
|
||||
|
@ -23,10 +24,14 @@ public:
|
|||
QModelIndex parent(const QModelIndex& rkChild) const;
|
||||
Qt::ItemFlags flags(const QModelIndex& rkIndex) const;
|
||||
|
||||
void NotifyPropertyModified(const QModelIndex& rkIndex);
|
||||
void ArrayAboutToBeResized(const QModelIndex& rkIndex, u32 NewSize);
|
||||
void ArrayResized(const QModelIndex& rkIndex, u32 OldSize);
|
||||
void ResizeArray(const QModelIndex& rkIndex, u32 NewSize);
|
||||
|
||||
public slots:
|
||||
void NotifyPropertyModified(IProperty *pProp);
|
||||
void NotifyPropertyModified(const QModelIndex& rkIndex);
|
||||
|
||||
signals:
|
||||
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(clicked(QModelIndex)), this, SLOT(edit(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)
|
||||
|
@ -66,6 +66,7 @@ void CPropertyView::SetEditor(CWorldEditor *pEditor)
|
|||
{
|
||||
mpEditor = pEditor;
|
||||
mpDelegate->SetEditor(pEditor);
|
||||
connect(mpEditor, SIGNAL(PropertyModified(IProperty*,bool)), mpModel, SLOT(NotifyPropertyModified(IProperty*)));
|
||||
}
|
||||
|
||||
void CPropertyView::SetInstance(CScriptObject *pObj)
|
||||
|
@ -83,7 +84,10 @@ void CPropertyView::SetInstance(CScriptObject *pObj)
|
|||
|
||||
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++)
|
||||
{
|
||||
QModelIndex Index0 = mpModel->index(iRow, 0, rkParent);
|
||||
|
@ -92,11 +96,15 @@ void CPropertyView::UpdateEditorProperties(const QModelIndex& rkParent)
|
|||
|
||||
if (pProp)
|
||||
{
|
||||
// For structs, update sub-properties.
|
||||
if (pProp->Type() == eStructProperty)
|
||||
{
|
||||
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);
|
||||
else
|
||||
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.
|
||||
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();
|
||||
|
||||
if (mpDelegate->DetermineCharacterPropType(Game, rkIndex) == eFileProperty)
|
||||
{
|
||||
ClosePersistentEditors(rkIndex.parent());
|
||||
SetPersistentEditors(rkIndex.parent());
|
||||
}
|
||||
ClosePersistentEditors(rkIndex);
|
||||
SetPersistentEditors(rkIndex);
|
||||
}
|
||||
|
||||
emit PropertyModified(pProp);
|
||||
}
|
||||
|
|
|
@ -29,9 +29,6 @@ public slots:
|
|||
void SetPersistentEditors(const QModelIndex& rkIndex);
|
||||
void ClosePersistentEditors(const QModelIndex& rkIndex);
|
||||
void OnPropertyModified(const QModelIndex& rkIndex);
|
||||
|
||||
signals:
|
||||
void PropertyModified(IProperty *pProperty);
|
||||
};
|
||||
|
||||
#endif // CPROPERTYVIEW_H
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
#include "CBasicPropertyCommand.h"
|
||||
#include <Core/Resource/Script/IPropertyTemplate.h>
|
||||
|
||||
CBasicPropertyCommand::CBasicPropertyCommand(CPropertyModel *pModel, const QModelIndex& rkIndex)
|
||||
: IUndoCommand("Edit Property")
|
||||
, mpModel(pModel)
|
||||
, mpProperty(pModel->PropertyForIndex(rkIndex, true))
|
||||
CBasicPropertyCommand::CBasicPropertyCommand(IProperty *pProp, CWorldEditor *pEditor, const QString& rkCommandName /*="Edit Property"*/)
|
||||
: IUndoCommand(rkCommandName)
|
||||
, mpProperty(pProp)
|
||||
, mpTemplate(mpProperty->Template())
|
||||
, mIndex(rkIndex)
|
||||
, mpBaseStruct(pProp->RootStruct())
|
||||
, mpEditor(pEditor)
|
||||
, mIsInArray(false)
|
||||
{
|
||||
// Check for array
|
||||
IProperty *pProp = mpProperty;
|
||||
IProperty *pChild = mpProperty;
|
||||
IProperty *pParent = mpProperty->Parent();
|
||||
|
||||
while (pParent)
|
||||
|
@ -24,31 +24,28 @@ CBasicPropertyCommand::CBasicPropertyCommand(CPropertyModel *pModel, const QMode
|
|||
|
||||
for (u32 iSub = 0; iSub < pArray->Count(); iSub++)
|
||||
{
|
||||
if (pArray->PropertyByIndex(iSub) == pProp)
|
||||
if (pArray->PropertyByIndex(iSub) == pChild)
|
||||
{
|
||||
mArrayIndices << iSub;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
pProp = pParent;
|
||||
pChild = pParent;
|
||||
pParent = pParent->Parent();
|
||||
}
|
||||
}
|
||||
|
||||
void CBasicPropertyCommand::UpdateArraySubProperty()
|
||||
{
|
||||
// If an array has been sized down and then back up, then we might have an index 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.
|
||||
// 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 pointer is still valid, we'll use the template to find the corresponding property.
|
||||
IPropertyTemplate *pTemp = mpTemplate;
|
||||
CStructTemplate *pParent = mpTemplate->Parent();
|
||||
|
||||
QVector<u32> SubIndices;
|
||||
int IndexIndex = 0;
|
||||
|
||||
if (mIndex.internalId() & 0x1)
|
||||
SubIndices << mIndex.row();
|
||||
|
||||
while (pParent)
|
||||
{
|
||||
if (pParent->Type() != eArrayProperty || static_cast<CArrayTemplate*>(pParent)->Count() > 1)
|
||||
|
@ -62,6 +59,8 @@ void CBasicPropertyCommand::UpdateArraySubProperty()
|
|||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
SubIndices << 0;
|
||||
|
||||
if (pParent->Type() == eArrayProperty)
|
||||
{
|
||||
|
@ -73,15 +72,9 @@ void CBasicPropertyCommand::UpdateArraySubProperty()
|
|||
pParent = pParent->Parent();
|
||||
}
|
||||
|
||||
// Find corresponding index
|
||||
QModelIndex Index = QModelIndex();
|
||||
// Find corresponding property
|
||||
mpProperty = mpBaseStruct;
|
||||
|
||||
for (int iSub = SubIndices.size() - 1; iSub >= 0; iSub--)
|
||||
Index = mpModel->index(SubIndices[iSub], 0, Index);
|
||||
|
||||
Index = Index.sibling(Index.row(), 1);
|
||||
|
||||
// Get property
|
||||
mpProperty = mpModel->PropertyForIndex(Index, true);
|
||||
mIndex = Index;
|
||||
for (int iChild = SubIndices.size() - 1; iChild >= 0; iChild--)
|
||||
mpProperty = static_cast<CPropertyStruct*>(mpProperty)->PropertyByIndex(SubIndices[iChild]);
|
||||
}
|
||||
|
|
|
@ -3,20 +3,21 @@
|
|||
|
||||
#include "IUndoCommand.h"
|
||||
#include "Editor/PropertyEdit/CPropertyModel.h"
|
||||
#include "Editor/WorldEditor/CWorldEditor.h"
|
||||
|
||||
class CBasicPropertyCommand : public IUndoCommand
|
||||
{
|
||||
protected:
|
||||
CPropertyModel *mpModel;
|
||||
IProperty *mpProperty;
|
||||
IPropertyTemplate *mpTemplate;
|
||||
QModelIndex mIndex;
|
||||
CPropertyStruct *mpBaseStruct;
|
||||
CWorldEditor *mpEditor;
|
||||
|
||||
bool mIsInArray;
|
||||
QVector<u32> mArrayIndices;
|
||||
|
||||
public:
|
||||
CBasicPropertyCommand(CPropertyModel *pModel, const QModelIndex& rkIndex);
|
||||
CBasicPropertyCommand(IProperty *pProp, CWorldEditor *pEditor, const QString& rkCommandName = "Edit Property");
|
||||
virtual void UpdateArraySubProperty();
|
||||
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 "EUndoCommand.h"
|
||||
|
||||
CEditScriptPropertyCommand::CEditScriptPropertyCommand(CPropertyModel *pModel, const QModelIndex& rkIndex, IPropertyValue *pOldValue, bool IsDone)
|
||||
: CBasicPropertyCommand(pModel, rkIndex)
|
||||
CEditScriptPropertyCommand::CEditScriptPropertyCommand(IProperty *pProp, CWorldEditor *pEditor, IPropertyValue *pOldValue, bool IsDone, const QString& rkCommandName /*= "Edit Property"*/)
|
||||
: CBasicPropertyCommand(pProp, pEditor, rkCommandName)
|
||||
, mCommandEnded(IsDone)
|
||||
{
|
||||
mpOldValue = pOldValue;
|
||||
|
@ -41,12 +41,13 @@ void CEditScriptPropertyCommand::undo()
|
|||
{
|
||||
if (mIsInArray) UpdateArraySubProperty();
|
||||
mpProperty->RawValue()->Copy(mpOldValue);
|
||||
mpModel->NotifyPropertyModified(mIndex);
|
||||
mpEditor->OnPropertyModified(mpProperty);
|
||||
mCommandEnded = true;
|
||||
}
|
||||
|
||||
void CEditScriptPropertyCommand::redo()
|
||||
{
|
||||
if (mIsInArray) UpdateArraySubProperty();
|
||||
mpProperty->RawValue()->Copy(mpNewValue);
|
||||
mpModel->NotifyPropertyModified(mIndex);
|
||||
mpEditor->OnPropertyModified(mpProperty);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include "CBasicPropertyCommand.h"
|
||||
#include "Editor/PropertyEdit/CPropertyModel.h"
|
||||
#include <QUndoCommand>
|
||||
|
||||
class CEditScriptPropertyCommand : public CBasicPropertyCommand
|
||||
{
|
||||
|
@ -12,7 +11,7 @@ class CEditScriptPropertyCommand : public CBasicPropertyCommand
|
|||
bool mCommandEnded;
|
||||
|
||||
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();
|
||||
int id() const;
|
||||
bool mergeWith(const QUndoCommand *pkOther);
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
#include "CResizeScriptArrayCommand.h"
|
||||
|
||||
CResizeScriptArrayCommand::CResizeScriptArrayCommand(CPropertyModel *pModel, const QModelIndex& rkIndex, u32 NewSize)
|
||||
: CBasicPropertyCommand(pModel, rkIndex)
|
||||
CResizeScriptArrayCommand::CResizeScriptArrayCommand(IProperty *pProp, CWorldEditor *pEditor, CPropertyModel *pModel, int NewSize)
|
||||
: CBasicPropertyCommand(pProp, pEditor)
|
||||
, mpArray(static_cast<CArrayProperty*>(mpProperty))
|
||||
, mpModel(pModel)
|
||||
, mOldSize(mpArray->Count())
|
||||
, mNewSize(NewSize)
|
||||
{
|
||||
|
@ -10,7 +11,7 @@ CResizeScriptArrayCommand::CResizeScriptArrayCommand(CPropertyModel *pModel, con
|
|||
|
||||
if (!mNewSizeLarger)
|
||||
{
|
||||
for (u32 iSub = mNewSize; iSub < mOldSize; iSub++)
|
||||
for (int iSub = mNewSize; iSub < mOldSize; iSub++)
|
||||
{
|
||||
mDeletedProperties << mpArray->PropertyByIndex(iSub)->Clone();
|
||||
}
|
||||
|
@ -29,21 +30,22 @@ void CResizeScriptArrayCommand::undo()
|
|||
{
|
||||
if (mIsInArray) UpdateArraySubProperty();
|
||||
|
||||
mpModel->ArrayAboutToBeResized(mIndex, mOldSize);
|
||||
QModelIndex Index = mpModel->IndexForProperty(mpProperty);
|
||||
mpModel->ArrayAboutToBeResized(Index, (u32) mOldSize);
|
||||
mpArray->Resize(mOldSize);
|
||||
|
||||
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;
|
||||
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();
|
||||
|
||||
mpModel->ArrayAboutToBeResized(mIndex, mNewSize);
|
||||
QModelIndex Index = mpModel->IndexForProperty(mpProperty);
|
||||
mpModel->ArrayAboutToBeResized(Index, (u32) mNewSize);
|
||||
mpArray->Resize(mNewSize);
|
||||
mpModel->ArrayResized(mIndex, mOldSize);
|
||||
mpModel->ArrayResized(Index, (u32) mOldSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,13 +9,14 @@ class CResizeScriptArrayCommand : public CBasicPropertyCommand
|
|||
{
|
||||
CArrayProperty *mpArray;
|
||||
QVector<IProperty*> mDeletedProperties;
|
||||
CPropertyModel *mpModel;
|
||||
|
||||
u32 mOldSize;
|
||||
u32 mNewSize;
|
||||
int mOldSize;
|
||||
int mNewSize;
|
||||
bool mNewSizeLarger;
|
||||
|
||||
public:
|
||||
CResizeScriptArrayCommand(CPropertyModel *pModel, const QModelIndex& rkIndex, u32 NewSize);
|
||||
CResizeScriptArrayCommand(IProperty *pProp, CWorldEditor *pEditor, CPropertyModel *pModel, int NewSize);
|
||||
~CResizeScriptArrayCommand();
|
||||
void undo();
|
||||
void redo();
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef 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
|
||||
{
|
||||
eTranslateNodeCmd,
|
||||
|
|
|
@ -4,13 +4,17 @@
|
|||
#include "CTranslateNodeCommand.h"
|
||||
#include "CRotateNodeCommand.h"
|
||||
#include "CScaleNodeCommand.h"
|
||||
|
||||
#include "CSelectNodeCommand.h"
|
||||
#include "CDeselectNodeCommand.h"
|
||||
#include "CClearSelectionCommand.h"
|
||||
#include "CSelectAllCommand.h"
|
||||
#include "CInvertSelectionCommand.h"
|
||||
|
||||
#include "CEditScriptPropertyCommand.h"
|
||||
#include "CResizeScriptArrayCommand.h"
|
||||
#include "CChangeLayerCommand.h"
|
||||
|
||||
#include "EUndoCommand.h"
|
||||
|
||||
#endif // UNDOCOMMANDS
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
#include <QApplication>
|
||||
#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
|
||||
* 2. Object Type (Actor, Platform, SpawnPoint, etc) - represented with flags
|
||||
* 3. Instance - represented with pointer to instance (0x1 bit is guaranteed to be clear)
|
||||
|
@ -15,6 +16,8 @@
|
|||
* A: Row index
|
||||
* B: Node type row index
|
||||
* 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_NODE_TYPE_MASK 0x0000001E
|
||||
|
@ -87,7 +90,7 @@ QModelIndex CInstancesModel::index(int row, int column, const QModelIndex &paren
|
|||
if (mModelType == eLayers)
|
||||
{
|
||||
CScriptLayer *pLayer = mpArea->GetScriptLayer(parent.row());
|
||||
if ((u32) row >= pLayer->GetNumObjects())
|
||||
if ((u32) row >= pLayer->NumInstances())
|
||||
return QModelIndex();
|
||||
else
|
||||
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);
|
||||
if (mModelType == eLayers)
|
||||
return (mpArea ? mpArea->GetScriptLayer(RowIndex)->GetNumObjects() : 0);
|
||||
return (mpArea ? mpArea->GetScriptLayer(RowIndex)->NumInstances() : 0);
|
||||
else
|
||||
return mTemplateList[RowIndex]->NumObjects();
|
||||
}
|
||||
|
@ -310,8 +313,13 @@ QVariant CInstancesModel::data(const QModelIndex &index, int role) const
|
|||
|
||||
void CInstancesModel::SetEditor(CWorldEditor *pEditor)
|
||||
{
|
||||
if (mpEditor)
|
||||
disconnect(mpEditor, 0, this, 0);
|
||||
|
||||
mpEditor = pEditor;
|
||||
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)
|
||||
|
@ -404,6 +412,46 @@ CScriptObject* CInstancesModel::IndexObject(const QModelIndex& index) const
|
|||
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 ************
|
||||
CInstancesModel::EIndexType CInstancesModel::IndexType(const QModelIndex& index)
|
||||
{
|
||||
|
|
|
@ -56,6 +56,10 @@ public:
|
|||
CScriptTemplate* IndexTemplate(const QModelIndex& index) const;
|
||||
CScriptObject* IndexObject(const QModelIndex& index) const;
|
||||
|
||||
public slots:
|
||||
void InstancesLayerPreChange();
|
||||
void InstancesLayerPostChange(const QList<CScriptNode*>& rkInstanceList);
|
||||
|
||||
// Static
|
||||
static EIndexType IndexType(const QModelIndex& index);
|
||||
static ENodeType IndexNodeType(const QModelIndex& index);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "WInstancesTab.h"
|
||||
|
||||
#include "Editor/CBasicViewport.h"
|
||||
#include "Editor/PropertyEdit/CPropertyView.h"
|
||||
#include "Editor/Widgets/WDraggableSpinBox.h"
|
||||
#include "Editor/Widgets/WVectorEditor.h"
|
||||
#include "Editor/Undo/UndoCommands.h"
|
||||
|
@ -80,6 +81,12 @@ CWorldEditor::CWorldEditor(QWidget *parent) :
|
|||
connect(&mUndoStack, SIGNAL(indexChanged(int)), this, SLOT(OnUndoStackIndexChanged()));
|
||||
|
||||
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()
|
||||
|
@ -172,18 +179,24 @@ void CWorldEditor::SetArea(CWorld *pWorld, CGameArea *pArea, u32 AreaIndex)
|
|||
CStringTable *pWorldNameTable = mpWorld->GetWorldName();
|
||||
TWideString WorldName = pWorldNameTable ? pWorldNameTable->GetString("ENGL", 0) : "[Untitled World]";
|
||||
|
||||
CStringTable *pAreaNameTable = mpWorld->GetAreaName(AreaIndex);
|
||||
TWideString AreaName = pAreaNameTable ? pAreaNameTable->GetString("ENGL", 0) : (TWideString("!") + mpWorld->GetAreaInternalName(AreaIndex).ToUTF16());
|
||||
if (CurrentGame() < eReturns)
|
||||
{
|
||||
CStringTable *pAreaNameTable = mpWorld->GetAreaName(AreaIndex);
|
||||
TWideString AreaName = pAreaNameTable ? pAreaNameTable->GetString("ENGL", 0) : (TWideString("!") + mpWorld->GetAreaInternalName(AreaIndex).ToUTF16());
|
||||
|
||||
if (AreaName.IsEmpty())
|
||||
AreaName = "[Untitled Area]";
|
||||
if (AreaName.IsEmpty())
|
||||
AreaName = "[Untitled Area]";
|
||||
|
||||
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()
|
||||
{
|
||||
return mpArea;
|
||||
else
|
||||
{
|
||||
setWindowTitle(QString("Prime World Editor - %1[*]").arg(TO_QSTRING(WorldName)));
|
||||
}
|
||||
|
||||
// Emit signals
|
||||
emit LayersModified();
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
// 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);
|
||||
|
||||
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++)
|
||||
{
|
||||
|
@ -382,14 +505,6 @@ void CWorldEditor::OnUndoStackIndexChanged()
|
|||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
const IUndoCommand *pkCmd = static_cast<const IUndoCommand*>(pkQCmd);
|
||||
|
||||
if (pkCmd->AffectsCleanState())
|
||||
IsClean = false;
|
||||
}
|
||||
|
||||
if (!IsClean) break;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,11 +43,17 @@ public:
|
|||
void closeEvent(QCloseEvent *pEvent);
|
||||
bool eventFilter(QObject *pObj, QEvent *pEvent);
|
||||
void SetArea(CWorld *pWorld, CGameArea *pArea, u32 AreaIndex);
|
||||
CGameArea* ActiveArea();
|
||||
bool CheckUnsavedChanges();
|
||||
|
||||
inline CGameArea* ActiveArea() const { return mpArea; }
|
||||
inline EGame CurrentGame() const { return mpArea->Version(); }
|
||||
|
||||
public slots:
|
||||
bool Save();
|
||||
void OnPropertyModified(IProperty *pProp);
|
||||
void SetSelectionActive(bool Active);
|
||||
void SetSelectionInstanceNames(const QString& rkNewName, bool IsDone);
|
||||
void SetSelectionLayer(CScriptLayer *pLayer);
|
||||
|
||||
void UpdateStatusBar();
|
||||
void UpdateGizmoUI();
|
||||
|
@ -89,6 +95,12 @@ private slots:
|
|||
void on_ActionSelectAll_triggered();
|
||||
void on_ActionInvertSelection_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
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QWidget" name="">
|
||||
<widget class="QWidget" name="layoutWidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="CSceneViewport" name="MainViewport" native="true">
|
||||
|
@ -251,19 +251,7 @@
|
|||
<attribute name="toolTip">
|
||||
<string>Create</string>
|
||||
</attribute>
|
||||
</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">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
|
@ -277,7 +265,62 @@
|
|||
<number>0</number>
|
||||
</property>
|
||||
<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>
|
||||
</layout>
|
||||
</widget>
|
||||
|
@ -292,7 +335,7 @@
|
|||
<attribute name="toolTip">
|
||||
<string>Instances</string>
|
||||
</attribute>
|
||||
<layout class="QHBoxLayout" name="InstancesTabLayout">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
|
@ -306,7 +349,24 @@
|
|||
<number>0</number>
|
||||
</property>
|
||||
<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>
|
||||
</layout>
|
||||
</widget>
|
||||
|
@ -321,6 +381,36 @@
|
|||
<attribute name="toolTip">
|
||||
<string>Display</string>
|
||||
</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 class="QWidget" name="WorldTab">
|
||||
<attribute name="icon">
|
||||
|
@ -333,6 +423,36 @@
|
|||
<attribute name="toolTip">
|
||||
<string>World</string>
|
||||
</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>
|
||||
|
@ -771,6 +891,12 @@
|
|||
<header>Editor/CSceneViewport.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>WEditorProperties</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>Editor/WorldEditor/WEditorProperties.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<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(1, PropViewWidth * 0.3);
|
||||
ui->PropertyView->header()->setSectionResizeMode(1, QHeaderView::Fixed);
|
||||
connect(ui->PropertyView, SIGNAL(PropertyModified(IProperty*)), this, SLOT(OnPropertyModified(IProperty*)));
|
||||
|
||||
mpInLinkModel = new CLinkModel(this);
|
||||
mpInLinkModel->SetConnectionType(CLinkModel::eIncoming);
|
||||
|
@ -86,30 +85,7 @@ void WModifyTab::OnWorldSelectionTransformed()
|
|||
ui->PropertyView->UpdateEditorProperties(QModelIndex());
|
||||
}
|
||||
|
||||
void WModifyTab::OnPropertyModified(IProperty *pProp)
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
// ************ PRIVATE SLOTS ************
|
||||
void WModifyTab::OnLinkTableDoubleClick(QModelIndex Index)
|
||||
{
|
||||
if (Index.column() == 0)
|
||||
|
|
|
@ -36,7 +36,6 @@ public:
|
|||
|
||||
public slots:
|
||||
void OnWorldSelectionTransformed();
|
||||
void OnPropertyModified(IProperty *pProp);
|
||||
|
||||
private:
|
||||
Ui::WModifyTab *ui;
|
||||
|
|
|
@ -13,7 +13,10 @@
|
|||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="MainLayout">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<property name="spacing">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
|
@ -105,7 +108,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>276</width>
|
||||
<height>457</height>
|
||||
<height>460</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
<property name="Active" ID="0x255A4580:0x41435456"/>
|
||||
</properties>
|
||||
<assets/>
|
||||
<preview_scale>0.5</preview_scale>
|
||||
<rotation_type>enabled</rotation_type>
|
||||
<scale_type>enabled</scale_type>
|
||||
</editor>
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
<assets>
|
||||
<model source="file">script/common/CameraWaypoint.cmdl</model>
|
||||
</assets>
|
||||
<preview_scale>0.5</preview_scale>
|
||||
<rotation_type>enabled</rotation_type>
|
||||
<scale_type>enabled</scale_type>
|
||||
</editor>
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
<assets>
|
||||
<model source="file">script/common/CameraWaypoint.cmdl</model>
|
||||
</assets>
|
||||
<preview_scale>0.5</preview_scale>
|
||||
<rotation_type>enabled</rotation_type>
|
||||
<scale_type>enabled</scale_type>
|
||||
</editor>
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
<assets>
|
||||
<model source="file">script/common/SpiderBallWaypoint.cmdl</model>
|
||||
</assets>
|
||||
<preview_scale>0.5</preview_scale>
|
||||
<rotation_type>enabled</rotation_type>
|
||||
<scale_type>enabled</scale_type>
|
||||
</editor>
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
<assets>
|
||||
<model source="file">script/common/Waypoint.CMDL</model>
|
||||
</assets>
|
||||
<preview_scale>0.5</preview_scale>
|
||||
<rotation_type>enabled</rotation_type>
|
||||
<scale_type>enabled</scale_type>
|
||||
</editor>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ScriptTemplate version="4">
|
||||
<name>AIHint</name>
|
||||
<properties>
|
||||
|
@ -30,7 +30,6 @@
|
|||
<property name="Active" ID="0x255A4580:0x41435456"/>
|
||||
</properties>
|
||||
<assets/>
|
||||
<preview_scale>0.5</preview_scale>
|
||||
<rotation_type>enabled</rotation_type>
|
||||
<scale_type>enabled</scale_type>
|
||||
</editor>
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
<property name="Active" ID="0x255A4580:0x41435456"/>
|
||||
</properties>
|
||||
<assets/>
|
||||
<preview_scale>0.5</preview_scale>
|
||||
<rotation_type>enabled</rotation_type>
|
||||
<scale_type>enabled</scale_type>
|
||||
</editor>
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
<property name="Active" ID="0x255A4580:0x41435456"/>
|
||||
</properties>
|
||||
<assets/>
|
||||
<preview_scale>0.5</preview_scale>
|
||||
<rotation_type>enabled</rotation_type>
|
||||
<scale_type>enabled</scale_type>
|
||||
</editor>
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
<property name="Active" ID="0x255A4580:0x41435456"/>
|
||||
</properties>
|
||||
<assets/>
|
||||
<preview_scale>0.5</preview_scale>
|
||||
<rotation_type>enabled</rotation_type>
|
||||
<scale_type>enabled</scale_type>
|
||||
</editor>
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
<property name="Active" ID="0x255A4580:0x41435456"/>
|
||||
</properties>
|
||||
<assets/>
|
||||
<preview_scale>0.5</preview_scale>
|
||||
<rotation_type>enabled</rotation_type>
|
||||
<scale_type>enabled</scale_type>
|
||||
</editor>
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
<property name="Active" ID="0x255A4580:0x41435456"/>
|
||||
</properties>
|
||||
<assets/>
|
||||
<preview_scale>0.5</preview_scale>
|
||||
<rotation_type>enabled</rotation_type>
|
||||
<scale_type>enabled</scale_type>
|
||||
</editor>
|
||||
|
|
Loading…
Reference in New Issue