mirror of
https://github.com/AxioDL/PrimeWorldEditor.git
synced 2025-05-25 16:51:38 +00:00
Fixed a lot of property bugs, fixed more various VS2017 compiler errors, property editor works correctly now
This commit is contained in:
parent
6cbc2a3208
commit
4faadbda61
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
class CVectorOutStream : public IOutputStream
|
class CVectorOutStream : public IOutputStream
|
||||||
{
|
{
|
||||||
static const u32 skAllocSize = 1024; // must be power of 2
|
static const u32 skAllocSize = 1; // must be 1 or a power of 2
|
||||||
|
|
||||||
std::vector<char> *mpVector;
|
std::vector<char> *mpVector;
|
||||||
bool mOwnsVector;
|
bool mOwnsVector;
|
||||||
|
@ -932,7 +932,46 @@ public:
|
|||||||
|
|
||||||
static _TString FromFloat(float Value, int MinDecimals = 1)
|
static _TString FromFloat(float Value, int MinDecimals = 1)
|
||||||
{
|
{
|
||||||
return Format("%f.*", Value, MinDecimals);
|
// Initial float -> string conversion
|
||||||
|
std::basic_stringstream<CharType> SStream;
|
||||||
|
if (MinDecimals > 0) SStream.setf(std::ios_base::showpoint);
|
||||||
|
SStream.setf(std::ios_base::fixed, std::ios_base::floatfield);
|
||||||
|
SStream << Value;
|
||||||
|
_TString Out = SStream.str();
|
||||||
|
|
||||||
|
// Make sure we have the right number of decimals
|
||||||
|
int DecIdx = Out.IndexOf(CHAR_LITERAL('.'));
|
||||||
|
|
||||||
|
if (DecIdx == -1 && MinDecimals > 0)
|
||||||
|
{
|
||||||
|
DecIdx = Out.Size();
|
||||||
|
Out.Append(CHAR_LITERAL('.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
int NumZeroes = (DecIdx == -1 ? 0 : Out.Size() - (DecIdx + 1));
|
||||||
|
|
||||||
|
// Add extra zeroes to meet the minimum decimal count
|
||||||
|
if (NumZeroes < MinDecimals)
|
||||||
|
{
|
||||||
|
for (int iDec = 0; iDec < (MinDecimals - NumZeroes); iDec++)
|
||||||
|
Out.Append(CHAR_LITERAL('.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove unnecessary trailing zeroes from the end of the string
|
||||||
|
else if (NumZeroes > MinDecimals)
|
||||||
|
{
|
||||||
|
while (Out.Back() == CHAR_LITERAL('0') && NumZeroes > MinDecimals && NumZeroes > 0)
|
||||||
|
{
|
||||||
|
Out = Out.ChopBack(1);
|
||||||
|
NumZeroes--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove decimal point
|
||||||
|
if (NumZeroes == 0)
|
||||||
|
Out = Out.ChopBack(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Out;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _TString FileSizeString(u64 Size, u32 NumDecimals = 2)
|
static _TString FileSizeString(u64 Size, u32 NumDecimals = 2)
|
||||||
|
@ -112,7 +112,7 @@ public:
|
|||||||
inline void SetOptions(FMaterialOptions Options) { mOptions = Options; Update(); }
|
inline void SetOptions(FMaterialOptions Options) { mOptions = Options; Update(); }
|
||||||
inline void SetVertexDescription(FVertexDescription Desc) { mVtxDesc = Desc; Update(); }
|
inline void SetVertexDescription(FVertexDescription Desc) { mVtxDesc = Desc; Update(); }
|
||||||
inline void SetBlendMode(GLenum SrcFac, GLenum DstFac) { mBlendSrcFac = SrcFac; mBlendDstFac = DstFac; mRecalcHash = true; }
|
inline void SetBlendMode(GLenum SrcFac, GLenum DstFac) { mBlendSrcFac = SrcFac; mBlendDstFac = DstFac; mRecalcHash = true; }
|
||||||
inline void SetKonst(CColor& Konst, u32 KIndex) { mKonstColors[KIndex] = Konst; Update(); }
|
inline void SetKonst(const CColor& Konst, u32 KIndex) { mKonstColors[KIndex] = Konst; Update(); }
|
||||||
inline void SetIndTexture(CTexture *pTex) { mpIndirectTexture = pTex; }
|
inline void SetIndTexture(CTexture *pTex) { mpIndirectTexture = pTex; }
|
||||||
inline void SetLightingEnabled(bool Enabled) { mLightingEnabled = Enabled; Update(); }
|
inline void SetLightingEnabled(bool Enabled) { mLightingEnabled = Enabled; Update(); }
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ public:
|
|||||||
|
|
||||||
CVertex() {}
|
CVertex() {}
|
||||||
|
|
||||||
CVertex(CVector3f& rPos)
|
CVertex(const CVector3f& rPos)
|
||||||
{
|
{
|
||||||
Position = rPos;
|
Position = rPos;
|
||||||
}
|
}
|
||||||
|
@ -88,6 +88,9 @@ bool CScriptObject::IsEditorProperty(IPropertyNew *pProp)
|
|||||||
(pProp == mScale.Property()) ||
|
(pProp == mScale.Property()) ||
|
||||||
(pProp == mActive.Property()) ||
|
(pProp == mActive.Property()) ||
|
||||||
(pProp == mLightParameters.Property()) ||
|
(pProp == mLightParameters.Property()) ||
|
||||||
|
(pProp->Parent() == mPosition.Property()) ||
|
||||||
|
(pProp->Parent() == mRotation.Property()) ||
|
||||||
|
(pProp->Parent() == mScale.Property()) ||
|
||||||
(pProp->Parent() == mLightParameters.Property())
|
(pProp->Parent() == mLightParameters.Property())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -55,11 +55,6 @@ void IPropertyNew::_CalcOffset()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 IPropertyNew::_GetOffset() const
|
|
||||||
{
|
|
||||||
return mOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
void IPropertyNew::_ClearChildren()
|
void IPropertyNew::_ClearChildren()
|
||||||
{
|
{
|
||||||
for (int ChildIdx = 0; ChildIdx < mChildren.size(); ChildIdx++)
|
for (int ChildIdx = 0; ChildIdx < mChildren.size(); ChildIdx++)
|
||||||
@ -118,7 +113,7 @@ void IPropertyNew::InitFromArchetype(IPropertyNew* pOther)
|
|||||||
{
|
{
|
||||||
//@todo maybe somehow use Serialize for this instead?
|
//@todo maybe somehow use Serialize for this instead?
|
||||||
mpArchetype = pOther;
|
mpArchetype = pOther;
|
||||||
mFlags = pOther->mFlags & ~EPropertyFlag::ArchetypeCopyFlags;
|
mFlags = pOther->mFlags & EPropertyFlag::ArchetypeCopyFlags;
|
||||||
mID = pOther->mID;
|
mID = pOther->mID;
|
||||||
mName = pOther->mName;
|
mName = pOther->mName;
|
||||||
mDescription = pOther->mDescription;
|
mDescription = pOther->mDescription;
|
||||||
@ -161,7 +156,8 @@ void* IPropertyNew::RawValuePtr(void* pData) const
|
|||||||
return pData;
|
return pData;
|
||||||
|
|
||||||
void* pBasePtr = (mpPointerParent ? mpPointerParent->GetChildDataPointer(pData) : pData);
|
void* pBasePtr = (mpPointerParent ? mpPointerParent->GetChildDataPointer(pData) : pData);
|
||||||
return ((char*)pBasePtr + mOffset);
|
void* pValuePtr = ((char*)pBasePtr + mOffset);
|
||||||
|
return pValuePtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
IPropertyNew* IPropertyNew::ChildByID(u32 ID) const
|
IPropertyNew* IPropertyNew::ChildByID(u32 ID) const
|
||||||
@ -342,8 +338,7 @@ IPropertyNew* IPropertyNew::Create(EPropertyTypeNew Type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
IPropertyNew* IPropertyNew::CreateCopy(IPropertyNew* pArchetype,
|
IPropertyNew* IPropertyNew::CreateCopy(IPropertyNew* pArchetype,
|
||||||
IPropertyNew* pParent,
|
IPropertyNew* pParent)
|
||||||
bool CallPostInit /*= true*/)
|
|
||||||
{
|
{
|
||||||
// Note this is mainly going to be used to create copies from struct/enum/flag archetype properties.
|
// Note this is mainly going to be used to create copies from struct/enum/flag archetype properties.
|
||||||
// Properties that have archetypes will never be the root property of a script template, and there
|
// Properties that have archetypes will never be the root property of a script template, and there
|
||||||
@ -354,11 +349,5 @@ IPropertyNew* IPropertyNew::CreateCopy(IPropertyNew* pArchetype,
|
|||||||
IPropertyNew* pOut = Create(pArchetype->Type(), pParent, pParent->mpMasterTemplate, pParent->mpScriptTemplate, false);
|
IPropertyNew* pOut = Create(pArchetype->Type(), pParent, pParent->mpMasterTemplate, pParent->mpScriptTemplate, false);
|
||||||
pOut->InitFromArchetype(pArchetype);
|
pOut->InitFromArchetype(pArchetype);
|
||||||
pArchetype->mSubInstances.push_back(pOut);
|
pArchetype->mSubInstances.push_back(pOut);
|
||||||
|
|
||||||
if (CallPostInit)
|
|
||||||
{
|
|
||||||
pOut->PostInitialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
return pOut;
|
return pOut;
|
||||||
}
|
}
|
||||||
|
@ -157,7 +157,6 @@ protected:
|
|||||||
/** Private constructor - use static methods to instantiate */
|
/** Private constructor - use static methods to instantiate */
|
||||||
IPropertyNew();
|
IPropertyNew();
|
||||||
void _CalcOffset();
|
void _CalcOffset();
|
||||||
u32 _GetOffset() const;
|
|
||||||
void _ClearChildren();
|
void _ClearChildren();
|
||||||
|
|
||||||
/** Called after property is created and fully initialized */
|
/** Called after property is created and fully initialized */
|
||||||
@ -213,6 +212,7 @@ public:
|
|||||||
inline TString Description() const;
|
inline TString Description() const;
|
||||||
inline TString Suffix() const;
|
inline TString Suffix() const;
|
||||||
inline TIDString IDString(bool FullyQualified) const;
|
inline TIDString IDString(bool FullyQualified) const;
|
||||||
|
inline u32 Offset() const;
|
||||||
inline u32 ID() const;
|
inline u32 ID() const;
|
||||||
|
|
||||||
inline bool IsArchetype() const { return mFlags.HasFlag(EPropertyFlag::IsArchetype); }
|
inline bool IsArchetype() const { return mFlags.HasFlag(EPropertyFlag::IsArchetype); }
|
||||||
@ -227,8 +227,7 @@ public:
|
|||||||
bool CallPostInit = true);
|
bool CallPostInit = true);
|
||||||
|
|
||||||
static IPropertyNew* CreateCopy(IPropertyNew* pArchetype,
|
static IPropertyNew* CreateCopy(IPropertyNew* pArchetype,
|
||||||
IPropertyNew* pParent,
|
IPropertyNew* pParent);
|
||||||
bool CallPostInit = true);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline ECookPreferenceNew IPropertyNew::CookPreference() const
|
inline ECookPreferenceNew IPropertyNew::CookPreference() const
|
||||||
@ -298,12 +297,17 @@ inline TString IPropertyNew::Suffix() const
|
|||||||
|
|
||||||
inline TString IPropertyNew::IDString(bool FullyQualified) const
|
inline TString IPropertyNew::IDString(bool FullyQualified) const
|
||||||
{
|
{
|
||||||
if (FullyQualified && mpParent != nullptr)
|
if (FullyQualified && mpParent != nullptr && mpParent->Parent() != nullptr)
|
||||||
return mpParent->IDString(FullyQualified) + ":" + TString::HexString(mID);
|
return mpParent->IDString(FullyQualified) + ":" + TString::HexString(mID);
|
||||||
else
|
else
|
||||||
return TString::HexString(mID);
|
return TString::HexString(mID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline u32 IPropertyNew::Offset() const
|
||||||
|
{
|
||||||
|
return mOffset;
|
||||||
|
}
|
||||||
|
|
||||||
inline u32 IPropertyNew::ID() const
|
inline u32 IPropertyNew::ID() const
|
||||||
{
|
{
|
||||||
return mID;
|
return mID;
|
||||||
|
@ -24,8 +24,9 @@ class CArrayProperty : public TTypedPropertyNew<int, EPropertyTypeNew::Array>
|
|||||||
{
|
{
|
||||||
friend class CTemplateLoader;
|
friend class CTemplateLoader;
|
||||||
/** This class inherits from TTypedPropertyNew<int> in order to expose the array
|
/** This class inherits from TTypedPropertyNew<int> in order to expose the array
|
||||||
* count value. Outside users can edit this value and we respond by updating the
|
* count value (the first member of SScriptArray). Outside users can edit this
|
||||||
* allocated space, handling destruction/construction, etc.
|
* value and we respond by updating the allocated space, handling item destruction
|
||||||
|
* and construction, etc.
|
||||||
*/
|
*/
|
||||||
IPropertyNew* mpItemArchetype;
|
IPropertyNew* mpItemArchetype;
|
||||||
|
|
||||||
@ -99,7 +100,7 @@ public:
|
|||||||
virtual void SerializeValue(void* pData, IArchive& Arc) const
|
virtual void SerializeValue(void* pData, IArchive& Arc) const
|
||||||
{
|
{
|
||||||
u32 Count = ArrayCount(pData);
|
u32 Count = ArrayCount(pData);
|
||||||
Arc.SerializePrimitive(Count);
|
Arc.SerializeContainerSize(Count, "ArrayElement");
|
||||||
|
|
||||||
if (Arc.IsReader())
|
if (Arc.IsReader())
|
||||||
Resize(pData, Count);
|
Resize(pData, Count);
|
||||||
@ -115,6 +116,13 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void InitFromArchetype(IPropertyNew* pOther)
|
||||||
|
{
|
||||||
|
TTypedPropertyNew::InitFromArchetype(pOther);
|
||||||
|
CArrayProperty* pOtherArray = static_cast<CArrayProperty*>(pOther);
|
||||||
|
mpItemArchetype = IPropertyNew::CreateCopy(pOtherArray->mpItemArchetype, this);
|
||||||
|
}
|
||||||
|
|
||||||
u32 ArrayCount(void* pPropertyData) const
|
u32 ArrayCount(void* pPropertyData) const
|
||||||
{
|
{
|
||||||
return ValueRef(pPropertyData);
|
return ValueRef(pPropertyData);
|
||||||
|
@ -18,6 +18,12 @@ public:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
virtual void InitFromArchetype(IPropertyNew* pOther)
|
||||||
|
{
|
||||||
|
TTypedPropertyNew::InitFromArchetype(pOther);
|
||||||
|
mTypeFilter = static_cast<CAssetProperty*>(pOther)->mTypeFilter;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void SerializeValue(void* pData, IArchive& Arc) const
|
virtual void SerializeValue(void* pData, IArchive& Arc) const
|
||||||
{
|
{
|
||||||
Arc.SerializePrimitive( ValueRef(pData) );
|
Arc.SerializePrimitive( ValueRef(pData) );
|
||||||
|
@ -46,6 +46,13 @@ public:
|
|||||||
Arc.SerializePrimitive( (u32&) ValueRef(pData) );
|
Arc.SerializePrimitive( (u32&) ValueRef(pData) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void InitFromArchetype(IPropertyNew* pOther)
|
||||||
|
{
|
||||||
|
TTypedPropertyNew::InitFromArchetype(pOther);
|
||||||
|
TEnumPropertyBase* pOtherEnum = static_cast<TEnumPropertyBase*>(pOther);
|
||||||
|
mValues = pOtherEnum->mValues;
|
||||||
|
}
|
||||||
|
|
||||||
virtual TString GetTemplateFileName()
|
virtual TString GetTemplateFileName()
|
||||||
{
|
{
|
||||||
ASSERT(IsArchetype() || mpArchetype);
|
ASSERT(IsArchetype() || mpArchetype);
|
||||||
|
@ -75,11 +75,30 @@ public:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
virtual void PostInitialize()
|
||||||
|
{
|
||||||
|
TTypedPropertyNew::PostInitialize();
|
||||||
|
|
||||||
|
// Create AllFlags mask
|
||||||
|
mAllFlags = 0;
|
||||||
|
|
||||||
|
for (int FlagIdx = 0; FlagIdx < mBitFlags.size(); FlagIdx++)
|
||||||
|
mAllFlags |= mBitFlags[FlagIdx].Mask;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void SerializeValue(void* pData, IArchive& rArc) const
|
virtual void SerializeValue(void* pData, IArchive& rArc) const
|
||||||
{
|
{
|
||||||
rArc.SerializeHexPrimitive( (u32&) ValueRef(pData) );
|
rArc.SerializeHexPrimitive( (u32&) ValueRef(pData) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void InitFromArchetype(IPropertyNew* pOther)
|
||||||
|
{
|
||||||
|
TTypedPropertyNew::InitFromArchetype(pOther);
|
||||||
|
CFlagsProperty* pOtherFlags = static_cast<CFlagsProperty*>(pOther);
|
||||||
|
mBitFlags = pOtherFlags->mBitFlags;
|
||||||
|
mAllFlags = pOtherFlags->mAllFlags;
|
||||||
|
}
|
||||||
|
|
||||||
virtual TString GetTemplateFileName()
|
virtual TString GetTemplateFileName()
|
||||||
{
|
{
|
||||||
ASSERT(IsArchetype() || mpArchetype);
|
ASSERT(IsArchetype() || mpArchetype);
|
||||||
|
@ -18,7 +18,7 @@ public:
|
|||||||
Arc.SerializePrimitive( (float&) ValueRef(pData) );
|
Arc.SerializePrimitive( (float&) ValueRef(pData) );
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual TString ValueAsString(void* pData)
|
virtual TString ValueAsString(void* pData) const
|
||||||
{
|
{
|
||||||
return TString::FromFloat( Value(pData) );
|
return TString::FromFloat( Value(pData) );
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ public:
|
|||||||
Arc.SerializePrimitive( (u32&) ValueRef(pData) );
|
Arc.SerializePrimitive( (u32&) ValueRef(pData) );
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual TString ValueAsString(void* pData)
|
virtual TString ValueAsString(void* pData) const
|
||||||
{
|
{
|
||||||
return TString::FromInt32( Value(pData), 0, 10 );
|
return TString::FromInt32( Value(pData), 0, 10 );
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ public:
|
|||||||
if (!mChildren.empty())
|
if (!mChildren.empty())
|
||||||
{
|
{
|
||||||
IPropertyNew* pLastChild = mChildren.back();
|
IPropertyNew* pLastChild = mChildren.back();
|
||||||
return _GetOffset() + pLastChild->DataSize();
|
return (pLastChild->Offset() - Offset()) + pLastChild->DataSize();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -36,7 +36,11 @@ public:
|
|||||||
|
|
||||||
virtual u32 DataAlignment() const
|
virtual u32 DataAlignment() const
|
||||||
{
|
{
|
||||||
return (mChildren.empty() ? 1 : mChildren[0]->DataAlignment());
|
// TODO. Should be aligned with the first child, but this function is called before children are loaded.
|
||||||
|
// So for now just use 8 to ensure correct alignment for all child types, but this is wasteful...
|
||||||
|
return 8;
|
||||||
|
|
||||||
|
//return (mChildren.empty() ? 1 : mChildren[0]->DataAlignment());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Construct(void* pData) const
|
virtual void Construct(void* pData) const
|
||||||
|
@ -50,7 +50,7 @@ public:
|
|||||||
/** Accessors */
|
/** Accessors */
|
||||||
inline CScriptObject* Object() const { return mpObject; }
|
inline CScriptObject* Object() const { return mpObject; }
|
||||||
inline PropertyClass* Property() const { return mpProperty; }
|
inline PropertyClass* Property() const { return mpProperty; }
|
||||||
inline ValueType Get() const { ASSERT(IsValid()); return *((ValueType*) mpProperty->RawValuePtr( mpObject->PropertyData() )); }
|
inline ValueType Get() const { return IsValid() ? *((ValueType*) mpProperty->RawValuePtr( mpObject->PropertyData() )) : ValueType(); }
|
||||||
inline void Set(const ValueType& kIn) const { if (IsValid()) *((ValueType*) mpProperty->RawValuePtr( mpObject->PropertyData() )) = kIn; }
|
inline void Set(const ValueType& kIn) const { if (IsValid()) *((ValueType*) mpProperty->RawValuePtr( mpObject->PropertyData() )) = kIn; }
|
||||||
inline bool IsValid() const { return mpObject != nullptr && mpProperty != nullptr; }
|
inline bool IsValid() const { return mpObject != nullptr && mpProperty != nullptr; }
|
||||||
|
|
||||||
|
@ -496,13 +496,13 @@ void CScriptNode::PropertyModified(IPropertyNew* pProp)
|
|||||||
if (pProp == pTemplate->NameProperty())
|
if (pProp == pTemplate->NameProperty())
|
||||||
SetName("[" + mpInstance->Template()->Name() + "] " + mpInstance->InstanceName());
|
SetName("[" + mpInstance->Template()->Name() + "] " + mpInstance->InstanceName());
|
||||||
|
|
||||||
else if (pProp == pTemplate->PositionProperty())
|
else if (pProp == pTemplate->PositionProperty() || pProp->Parent() == pTemplate->PositionProperty())
|
||||||
mPosition = mpInstance->Position();
|
mPosition = mpInstance->Position();
|
||||||
|
|
||||||
else if (pProp == pTemplate->RotationProperty())
|
else if (pProp == pTemplate->RotationProperty() || pProp->Parent() == pTemplate->RotationProperty())
|
||||||
mRotation = CQuaternion::FromEuler(mpInstance->Rotation());
|
mRotation = CQuaternion::FromEuler(mpInstance->Rotation());
|
||||||
|
|
||||||
else if (pProp == pTemplate->ScaleProperty())
|
else if (pProp == pTemplate->ScaleProperty() || pProp->Parent() == pTemplate->ScaleProperty())
|
||||||
mScale = mpInstance->Scale();
|
mScale = mpInstance->Scale();
|
||||||
|
|
||||||
MarkTransformChanged();
|
MarkTransformChanged();
|
||||||
@ -560,7 +560,7 @@ void CScriptNode::GeneratePosition()
|
|||||||
if (!mHasValidPosition)
|
if (!mHasValidPosition)
|
||||||
{
|
{
|
||||||
// Default to center of the active area; this is to prevent recursion issues
|
// Default to center of the active area; this is to prevent recursion issues
|
||||||
CTransform4f& AreaTransform = mpScene->ActiveArea()->Transform();
|
CTransform4f AreaTransform = mpScene->ActiveArea()->Transform();
|
||||||
mPosition = CVector3f(AreaTransform[0][3], AreaTransform[1][3], AreaTransform[2][3]);
|
mPosition = CVector3f(AreaTransform[0][3], AreaTransform[1][3], AreaTransform[2][3]);
|
||||||
mHasValidPosition = true;
|
mHasValidPosition = true;
|
||||||
MarkTransformChanged();
|
MarkTransformChanged();
|
||||||
|
@ -764,9 +764,10 @@ void CModelEditorWindow::ConvertToDDS()
|
|||||||
if (Input.isEmpty()) return;
|
if (Input.isEmpty()) return;
|
||||||
|
|
||||||
TString TexFilename = TO_TSTRING(Input);
|
TString TexFilename = TO_TSTRING(Input);
|
||||||
CTexture *pTex = CTextureDecoder::LoadDDS( CFileInStream(TexFilename, IOUtil::eLittleEndian), nullptr );
|
CFileInStream InTextureFile(TexFilename, IOUtil::eLittleEndian);
|
||||||
TString OutName = TexFilename.GetFilePathWithoutExtension() + ".dds";
|
CTexture *pTex = CTextureDecoder::LoadTXTR( InTextureFile, nullptr );
|
||||||
|
|
||||||
|
TString OutName = TexFilename.GetFilePathWithoutExtension() + ".dds";
|
||||||
CFileOutStream Out(OutName, IOUtil::eLittleEndian);
|
CFileOutStream Out(OutName, IOUtil::eLittleEndian);
|
||||||
if (!Out.IsValid()) QMessageBox::warning(this, "Error", "Couldn't open output DDS!");
|
if (!Out.IsValid()) QMessageBox::warning(this, "Error", "Couldn't open output DDS!");
|
||||||
|
|
||||||
@ -786,7 +787,8 @@ void CModelEditorWindow::ConvertToTXTR()
|
|||||||
if (Input.isEmpty()) return;
|
if (Input.isEmpty()) return;
|
||||||
|
|
||||||
TString TexFilename = TO_TSTRING(Input);
|
TString TexFilename = TO_TSTRING(Input);
|
||||||
CTexture *pTex = CTextureDecoder::LoadDDS(CFileInStream(TexFilename, IOUtil::eLittleEndian), nullptr);
|
CFileInStream InTextureFile = CFileInStream(TexFilename, IOUtil::eLittleEndian);
|
||||||
|
CTexture *pTex = CTextureDecoder::LoadDDS(InTextureFile, nullptr);
|
||||||
TString OutName = TexFilename.GetFilePathWithoutExtension() + ".txtr";
|
TString OutName = TexFilename.GetFilePathWithoutExtension() + ".txtr";
|
||||||
|
|
||||||
if ((pTex->TexelFormat() != eDXT1) || (pTex->NumMipMaps() > 1))
|
if ((pTex->TexelFormat() != eDXT1) || (pTex->NumMipMaps() > 1))
|
||||||
|
@ -354,16 +354,40 @@ void CPropertyDelegate::setModelData(QWidget *pEditor, QAbstractItemModel* /*pMo
|
|||||||
if (!mpModel) return;
|
if (!mpModel) return;
|
||||||
if (!pEditor) return;
|
if (!pEditor) return;
|
||||||
|
|
||||||
//FIXME
|
IEditPropertyCommand* pCommand = nullptr;
|
||||||
/* IPropertyNew *pProp = mpModel->PropertyForIndex(rkIndex, false);
|
IPropertyNew *pProp = mpModel->PropertyForIndex(rkIndex, true);
|
||||||
bool HadEditInProgress = mEditInProgress;
|
void* pData = mpModel->GetPropertyData();
|
||||||
mEditInProgress = mInRelayWidgetEdit && (pEditor->hasFocus() || pProp->Type() == EPropertyTypeNew::Color);
|
|
||||||
bool EditJustFinished = (!mEditInProgress && HadEditInProgress);
|
|
||||||
|
|
||||||
bool Matches = false;
|
|
||||||
IUndoCommand* pCommand = nullptr;
|
|
||||||
|
|
||||||
if (pProp)
|
if (pProp)
|
||||||
|
{
|
||||||
|
EPropertyTypeNew Type = pProp->Type();
|
||||||
|
|
||||||
|
if (Type != EPropertyTypeNew::Array)
|
||||||
|
{
|
||||||
|
// TODO: support this for non script object properties
|
||||||
|
pCommand = new CEditScriptPropertyCommand(mpEditor, mpModel->GetScriptObject(), pProp);
|
||||||
|
pCommand->SaveOldData();
|
||||||
|
|
||||||
|
// Handle sub-properties of flags and animation sets
|
||||||
|
if (rkIndex.internalId() & 0x80000000)
|
||||||
|
{
|
||||||
|
if (pProp->Type() == EPropertyTypeNew::AnimationSet)
|
||||||
|
SetCharacterModelData(pEditor, rkIndex);
|
||||||
|
|
||||||
|
else if (pProp->Type() == EPropertyTypeNew::Flags)
|
||||||
|
{
|
||||||
|
QCheckBox* pCheckBox = static_cast<QCheckBox*>(pEditor);
|
||||||
|
CFlagsProperty* pFlags = static_cast<CFlagsProperty*>(pProp);
|
||||||
|
u32 Mask = pFlags->FlagMask(rkIndex.row());
|
||||||
|
|
||||||
|
int Flags = pFlags->Value(pData);
|
||||||
|
if (pCheckBox->isChecked()) Flags |= Mask;
|
||||||
|
else Flags &= ~Mask;
|
||||||
|
pFlags->ValueRef(pData) = Flags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
{
|
{
|
||||||
switch (pProp->Type())
|
switch (pProp->Type())
|
||||||
{
|
{
|
||||||
@ -371,80 +395,93 @@ void CPropertyDelegate::setModelData(QWidget *pEditor, QAbstractItemModel* /*pMo
|
|||||||
case EPropertyTypeNew::Bool:
|
case EPropertyTypeNew::Bool:
|
||||||
{
|
{
|
||||||
QCheckBox *pCheckBox = static_cast<QCheckBox*>(pEditor);
|
QCheckBox *pCheckBox = static_cast<QCheckBox*>(pEditor);
|
||||||
bool NewValue =
|
CBoolProperty* pBool = static_cast<CBoolProperty*>(pProp);
|
||||||
pCommand = new TEditScriptPropertyCommand<CBoolProperty>(pProp, mpModel->GetScriptObject(), mpEditor, pCheckBox->isChecked(),
|
pBool->ValueRef(pData) = pCheckBox->isChecked();
|
||||||
bool NewValue = TEditScriptPropertyCommand<CBoolProperty>(pProp,
|
|
||||||
TBoolProperty *pBool = static_cast<TBoolProperty*>(pProp);
|
|
||||||
pBool->Set(pCheckBox->isChecked());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case eShortProperty:
|
case EPropertyTypeNew::Short:
|
||||||
{
|
{
|
||||||
WIntegralSpinBox *pSpinBox = static_cast<WIntegralSpinBox*>(pEditor);
|
WIntegralSpinBox* pSpinBox = static_cast<WIntegralSpinBox*>(pEditor);
|
||||||
TShortProperty *pShort = static_cast<TShortProperty*>(pProp);
|
CShortProperty* pShort = static_cast<CShortProperty*>(pProp);
|
||||||
pShort->Set(pSpinBox->value());
|
pShort->ValueRef(pData) = pSpinBox->value();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case eLongProperty:
|
case EPropertyTypeNew::Int:
|
||||||
case eSoundProperty:
|
|
||||||
{
|
{
|
||||||
WIntegralSpinBox *pSpinBox = static_cast<WIntegralSpinBox*>(pEditor);
|
WIntegralSpinBox* pSpinBox = static_cast<WIntegralSpinBox*>(pEditor);
|
||||||
TLongProperty *pLong = static_cast<TLongProperty*>(pProp);
|
CIntProperty* pInt = static_cast<CIntProperty*>(pProp);
|
||||||
pLong->Set(pSpinBox->value());
|
pInt->ValueRef(pData) = pSpinBox->value();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case eFloatProperty:
|
case EPropertyTypeNew::Sound:
|
||||||
{
|
{
|
||||||
WDraggableSpinBox *pSpinBox = static_cast<WDraggableSpinBox*>(pEditor);
|
WIntegralSpinBox* pSpinBox = static_cast<WIntegralSpinBox*>(pEditor);
|
||||||
TFloatProperty *pFloat = static_cast<TFloatProperty*>(pProp);
|
CSoundProperty* pSound = static_cast<CSoundProperty*>(pProp);
|
||||||
pFloat->Set((float) pSpinBox->value());
|
pSound->ValueRef(pData) = pSpinBox->value();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case eColorProperty:
|
case EPropertyTypeNew::Float:
|
||||||
{
|
{
|
||||||
WColorPicker *pColorPicker = static_cast<WColorPicker*>(pEditor);
|
WDraggableSpinBox* pSpinBox = static_cast<WDraggableSpinBox*>(pEditor);
|
||||||
TColorProperty *pColor = static_cast<TColorProperty*>(pProp);
|
CFloatProperty* pFloat = static_cast<CFloatProperty*>(pProp);
|
||||||
|
pFloat->ValueRef(pData) = (float) pSpinBox->value();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case EPropertyTypeNew::Color:
|
||||||
|
{
|
||||||
|
WColorPicker* pColorPicker = static_cast<WColorPicker*>(pEditor);
|
||||||
|
CColorProperty* pColor = static_cast<CColorProperty*>(pProp);
|
||||||
|
|
||||||
QColor Color = pColorPicker->Color();
|
QColor Color = pColorPicker->Color();
|
||||||
pColor->Set(TO_CCOLOR(Color));
|
pColor->ValueRef(pData) = TO_CCOLOR(Color);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case eStringProperty:
|
case EPropertyTypeNew::String:
|
||||||
{
|
{
|
||||||
QLineEdit *pLineEdit = static_cast<QLineEdit*>(pEditor);
|
QLineEdit* pLineEdit = static_cast<QLineEdit*>(pEditor);
|
||||||
TStringProperty *pString = static_cast<TStringProperty*>(pProp);
|
CStringProperty* pString = static_cast<CStringProperty*>(pProp);
|
||||||
pString->Set(TO_TSTRING(pLineEdit->text()));
|
pString->ValueRef(pData) = TO_TSTRING(pLineEdit->text());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case eEnumProperty:
|
case EPropertyTypeNew::Enum:
|
||||||
|
case EPropertyTypeNew::Choice:
|
||||||
{
|
{
|
||||||
QComboBox *pComboBox = static_cast<QComboBox*>(pEditor);
|
QComboBox* pComboBox = static_cast<QComboBox*>(pEditor);
|
||||||
TEnumProperty *pEnum = static_cast<TEnumProperty*>(pProp);
|
CEnumProperty* pEnum = static_cast<CEnumProperty*>(pProp);
|
||||||
CEnumTemplate *pTemp = static_cast<CEnumTemplate*>(pProp->Template());
|
pEnum->ValueRef(pData) = pEnum->ValueID(pComboBox->currentIndex());
|
||||||
pEnum->Set(pTemp->EnumeratorID(pComboBox->currentIndex()));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case eAssetProperty:
|
case EPropertyTypeNew::Asset:
|
||||||
{
|
{
|
||||||
CResourceSelector *pSelector = static_cast<CResourceSelector*>(pEditor);
|
CResourceSelector* pSelector = static_cast<CResourceSelector*>(pEditor);
|
||||||
CResourceEntry *pEntry = pSelector->Entry();
|
CResourceEntry* pEntry = pSelector->Entry();
|
||||||
|
|
||||||
TAssetProperty *pAsset = static_cast<TAssetProperty*>(pProp);
|
CAssetProperty* pAsset = static_cast<CAssetProperty*>(pProp);
|
||||||
pAsset->Set(pEntry ? pEntry->ID() : CAssetID::InvalidID(mpEditor->CurrentGame()));
|
pAsset->ValueRef(pData) = (pEntry ? pEntry->ID() : CAssetID::InvalidID(pAsset->Game()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case eArrayProperty:
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pCommand->SaveNewData();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Array
|
||||||
|
else
|
||||||
{
|
{
|
||||||
WIntegralSpinBox *pSpinBox = static_cast<WIntegralSpinBox*>(pEditor);
|
//FIXME
|
||||||
CArrayProperty *pArray = static_cast<CArrayProperty*>(pProp);
|
/*
|
||||||
|
WIntegralSpinBox* pSpinBox = static_cast<WIntegralSpinBox*>(pEditor);
|
||||||
|
CArrayProperty* pArray = static_cast<CArrayProperty*>(pProp);
|
||||||
int NewCount = pSpinBox->value();
|
int NewCount = pSpinBox->value();
|
||||||
|
|
||||||
if (pArray->Count() != NewCount)
|
if (pArray->Count() != NewCount)
|
||||||
@ -452,91 +489,35 @@ void CPropertyDelegate::setModelData(QWidget *pEditor, QAbstractItemModel* /*pMo
|
|||||||
CResizeScriptArrayCommand *pCmd = new CResizeScriptArrayCommand(pProp, mpEditor, mpModel, NewCount);
|
CResizeScriptArrayCommand *pCmd = new CResizeScriptArrayCommand(pProp, mpEditor, mpModel, NewCount);
|
||||||
mpEditor->UndoStack()->push(pCmd);
|
mpEditor->UndoStack()->push(pCmd);
|
||||||
}
|
}
|
||||||
break;
|
*/
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for character/bitfield/vector/color sub-properties
|
if (pCommand)
|
||||||
else if (rkIndex.internalId() & 0x1)
|
|
||||||
{
|
|
||||||
pProp = mpModel->PropertyForIndex(rkIndex, true);
|
|
||||||
|
|
||||||
IPropertyValue *pRawValue = pProp->RawValue();
|
|
||||||
pOldValue = pRawValue ? pRawValue->Clone() : nullptr;
|
|
||||||
|
|
||||||
if (pProp->Type() == eCharacterProperty)
|
|
||||||
SetCharacterModelData(pEditor, rkIndex);
|
|
||||||
|
|
||||||
else if (pProp->Type() == eBitfieldProperty)
|
|
||||||
{
|
|
||||||
QCheckBox *pCheckBox = static_cast<QCheckBox*>(pEditor);
|
|
||||||
TBitfieldProperty *pBitfield = static_cast<TBitfieldProperty*>(pProp);
|
|
||||||
u32 Mask = static_cast<CBitfieldTemplate*>(pProp->Template())->FlagMask(rkIndex.row());
|
|
||||||
|
|
||||||
int Flags = pBitfield->Get();
|
|
||||||
if (pCheckBox->isChecked()) Flags |= Mask;
|
|
||||||
else Flags &= ~Mask;
|
|
||||||
pBitfield->Set(Flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WDraggableSpinBox *pSpinBox = static_cast<WDraggableSpinBox*>(pEditor);
|
|
||||||
|
|
||||||
if (pProp->Type() == eVector3Property)
|
|
||||||
{
|
|
||||||
TVector3Property *pVector = static_cast<TVector3Property*>(pProp);
|
|
||||||
CVector3f Value = pVector->Get();
|
|
||||||
|
|
||||||
if (rkIndex.row() == 0) Value.X = (float) pSpinBox->value();
|
|
||||||
if (rkIndex.row() == 1) Value.Y = (float) pSpinBox->value();
|
|
||||||
if (rkIndex.row() == 2) Value.Z = (float) pSpinBox->value();
|
|
||||||
|
|
||||||
pVector->Set(Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (pProp->Type() == eColorProperty)
|
|
||||||
{
|
|
||||||
TColorProperty *pColor = static_cast<TColorProperty*>(pProp);
|
|
||||||
CColor Value = pColor->Get();
|
|
||||||
|
|
||||||
if (rkIndex.row() == 0) Value.R = (float) pSpinBox->value();
|
|
||||||
if (rkIndex.row() == 1) Value.G = (float) pSpinBox->value();
|
|
||||||
if (rkIndex.row() == 2) Value.B = (float) pSpinBox->value();
|
|
||||||
if (rkIndex.row() == 3) Value.A = (float) pSpinBox->value();
|
|
||||||
|
|
||||||
pColor->Set(Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pProp && pOldValue)
|
|
||||||
{
|
{
|
||||||
// Check for edit in progress
|
// Check for edit in progress
|
||||||
bool Matches = pOldValue->Matches(pProp->RawValue());
|
bool DataChanged = pCommand->IsNewDataDifferent();
|
||||||
|
|
||||||
if (!Matches && mInRelayWidgetEdit && (pEditor->hasFocus() || pProp->Type() == eColorProperty))
|
if (DataChanged && mInRelayWidgetEdit && (pEditor->hasFocus() || pProp->Type() == EPropertyTypeNew::Color))
|
||||||
mEditInProgress = true;
|
mEditInProgress = true;
|
||||||
|
|
||||||
bool EditInProgress = mEditInProgress;
|
bool EditWasInProgress = mEditInProgress;
|
||||||
|
|
||||||
// Check for edit finished
|
// Check for edit finished
|
||||||
if (!mInRelayWidgetEdit || (!pEditor->hasFocus() && pProp->Type() != eColorProperty))
|
if (!mInRelayWidgetEdit || (!pEditor->hasFocus() && pProp->Type() != EPropertyTypeNew::Color))
|
||||||
mEditInProgress = false;
|
mEditInProgress = false;
|
||||||
|
|
||||||
// Create undo command
|
// Push undo command
|
||||||
if (!Matches || EditInProgress)
|
if (DataChanged || EditWasInProgress)
|
||||||
{
|
{
|
||||||
// Always consider the edit done for bool properties
|
// Always consider the edit done for bool properties
|
||||||
CEditScriptPropertyCommand *pCommand = new CEditScriptPropertyCommand(pProp, mpEditor, pOldValue, (!mEditInProgress || pProp->Type() == eBoolProperty));
|
pCommand->SetEditComplete(!mEditInProgress || pProp->Type() == EPropertyTypeNew::Bool);
|
||||||
mpEditor->UndoStack()->push(pCommand);
|
mpEditor->UndoStack()->push(pCommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
delete pOldValue;
|
delete pCommand;
|
||||||
}*/
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CPropertyDelegate::eventFilter(QObject *pObject, QEvent *pEvent)
|
bool CPropertyDelegate::eventFilter(QObject *pObject, QEvent *pEvent)
|
||||||
@ -558,18 +539,16 @@ bool CPropertyDelegate::eventFilter(QObject *pObject, QEvent *pEvent)
|
|||||||
// Character properties have separate functions because they're somewhat complicated - they have different layouts in different games
|
// Character properties have separate functions because they're somewhat complicated - they have different layouts in different games
|
||||||
QWidget* CPropertyDelegate::CreateCharacterEditor(QWidget *pParent, const QModelIndex& rkIndex) const
|
QWidget* CPropertyDelegate::CreateCharacterEditor(QWidget *pParent, const QModelIndex& rkIndex) const
|
||||||
{
|
{
|
||||||
//FIXME
|
CAnimationSetProperty* pAnimSetProp = TPropCast<CAnimationSetProperty>(mpModel->PropertyForIndex(rkIndex, true));
|
||||||
/* TCharacterProperty *pProp = static_cast<TCharacterProperty*>(mpModel->PropertyForIndex(rkIndex, true));
|
CAnimationParameters Params = pAnimSetProp->Value(mpModel->GetPropertyData());
|
||||||
CAnimationParameters Params = pProp->Get();
|
|
||||||
|
|
||||||
// Determine property type
|
// Determine property type
|
||||||
EPropertyType Type = DetermineCharacterPropType(Params.Version(), rkIndex);
|
EPropertyTypeNew Type = DetermineCharacterPropType(Params.Version(), rkIndex);
|
||||||
if (Type == eUnknownProperty) return nullptr;
|
|
||||||
|
|
||||||
// Create widget
|
// Create widget
|
||||||
if (Type == eAssetProperty)
|
if (Type == EPropertyTypeNew::Asset)
|
||||||
{
|
{
|
||||||
CResourceSelector *pSelector = new CResourceSelector(pParent);
|
CResourceSelector* pSelector = new CResourceSelector(pParent);
|
||||||
pSelector->SetFrameVisible(false);
|
pSelector->SetFrameVisible(false);
|
||||||
|
|
||||||
if (Params.Version() <= eEchoes)
|
if (Params.Version() <= eEchoes)
|
||||||
@ -581,94 +560,87 @@ QWidget* CPropertyDelegate::CreateCharacterEditor(QWidget *pParent, const QModel
|
|||||||
return pSelector;
|
return pSelector;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Type == eEnumProperty)
|
else if (Type == EPropertyTypeNew::Enum || Type == EPropertyTypeNew::Choice)
|
||||||
{
|
{
|
||||||
QComboBox *pComboBox = new QComboBox(pParent);
|
QComboBox* pComboBox = new QComboBox(pParent);
|
||||||
|
CAnimSet* pAnimSet = Params.AnimSet();
|
||||||
CAnimSet *pAnimSet = Params.AnimSet();
|
|
||||||
|
|
||||||
if (pAnimSet)
|
if (pAnimSet)
|
||||||
{
|
{
|
||||||
for (u32 iChr = 0; iChr < pAnimSet->NumCharacters(); iChr++)
|
for (u32 CharIdx = 0; CharIdx < pAnimSet->NumCharacters(); CharIdx++)
|
||||||
pComboBox->addItem(TO_QSTRING(pAnimSet->Character(iChr)->Name));
|
pComboBox->addItem(TO_QSTRING(pAnimSet->Character(CharIdx)->Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
CONNECT_RELAY(pComboBox, rkIndex, currentIndexChanged(int));
|
CONNECT_RELAY(pComboBox, rkIndex, currentIndexChanged(int));
|
||||||
return pComboBox;
|
return pComboBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Type == eLongProperty)
|
else if (Type == EPropertyTypeNew::Int)
|
||||||
{
|
{
|
||||||
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;
|
||||||
}*/
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPropertyDelegate::SetCharacterEditorData(QWidget *pEditor, const QModelIndex& rkIndex) const
|
void CPropertyDelegate::SetCharacterEditorData(QWidget *pEditor, const QModelIndex& rkIndex) const
|
||||||
{
|
{
|
||||||
//FIXME
|
CAnimationSetProperty* pAnimSetProp = TPropCast<CAnimationSetProperty>(mpModel->PropertyForIndex(rkIndex, true));
|
||||||
/*
|
CAnimationParameters Params = pAnimSetProp->Value(mpModel->GetPropertyData());
|
||||||
TCharacterProperty *pProp = static_cast<TCharacterProperty*>(mpModel->PropertyForIndex(rkIndex, true));
|
EPropertyTypeNew Type = DetermineCharacterPropType(Params.Version(), rkIndex);
|
||||||
CAnimationParameters Params = pProp->Get();
|
|
||||||
EPropertyType Type = DetermineCharacterPropType(Params.Version(), rkIndex);
|
|
||||||
|
|
||||||
if (Type == eAssetProperty)
|
if (Type == EPropertyTypeNew::Asset)
|
||||||
{
|
{
|
||||||
static_cast<CResourceSelector*>(pEditor)->SetResource(Params.AnimSet());
|
static_cast<CResourceSelector*>(pEditor)->SetResource(Params.AnimSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (Type == eEnumProperty)
|
else if (Type == EPropertyTypeNew::Enum || Type == EPropertyTypeNew::Choice)
|
||||||
{
|
{
|
||||||
static_cast<QComboBox*>(pEditor)->setCurrentIndex(Params.CharacterIndex());
|
static_cast<QComboBox*>(pEditor)->setCurrentIndex(Params.CharacterIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (Type == eLongProperty && !pEditor->hasFocus())
|
else if (Type == EPropertyTypeNew::Int && !pEditor->hasFocus())
|
||||||
{
|
{
|
||||||
int UnkIndex = (Params.Version() <= eEchoes ? rkIndex.row() - 2 : rkIndex.row() - 1);
|
int UnkIndex = (Params.Version() <= eEchoes ? rkIndex.row() - 2 : rkIndex.row() - 1);
|
||||||
u32 Value = Params.Unknown(UnkIndex);
|
u32 Value = Params.Unknown(UnkIndex);
|
||||||
static_cast<WIntegralSpinBox*>(pEditor)->setValue(Value);
|
static_cast<WIntegralSpinBox*>(pEditor)->setValue(Value);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPropertyDelegate::SetCharacterModelData(QWidget *pEditor, const QModelIndex& rkIndex) const
|
void CPropertyDelegate::SetCharacterModelData(QWidget *pEditor, const QModelIndex& rkIndex) const
|
||||||
{
|
{
|
||||||
//FIXME
|
CAnimationSetProperty* pAnimSetProp = TPropCast<CAnimationSetProperty>(mpModel->PropertyForIndex(rkIndex, true));
|
||||||
/*
|
CAnimationParameters Params = pAnimSetProp->Value(mpModel->GetPropertyData());
|
||||||
CAnimationSetProperty* pAnimSet = TPropCast<CAnimationSetProperty>(mpModel->PropertyForIndex(rkIndex, true));
|
EPropertyTypeNew Type = DetermineCharacterPropType(Params.Version(), rkIndex);
|
||||||
CAnimationParameters Params = pAnimSet->Get();
|
|
||||||
EPropertyType Type = DetermineCharacterPropType(Params.Version(), rkIndex);
|
|
||||||
|
|
||||||
if (Type == eAssetProperty)
|
if (Type == EPropertyTypeNew::Asset)
|
||||||
{
|
{
|
||||||
CResourceEntry *pEntry = static_cast<CResourceSelector*>(pEditor)->Entry();
|
CResourceEntry *pEntry = static_cast<CResourceSelector*>(pEditor)->Entry();
|
||||||
Params.SetResource( pEntry ? pEntry->ID() : CAssetID::InvalidID(mpEditor->CurrentGame()) );
|
Params.SetResource( pEntry ? pEntry->ID() : CAssetID::InvalidID(mpEditor->CurrentGame()) );
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (Type == eEnumProperty)
|
else if (Type == EPropertyTypeNew::Enum || Type == EPropertyTypeNew::Choice)
|
||||||
{
|
{
|
||||||
Params.SetCharIndex( static_cast<QComboBox*>(pEditor)->currentIndex() );
|
Params.SetCharIndex( static_cast<QComboBox*>(pEditor)->currentIndex() );
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (Type == eLongProperty)
|
else if (Type == EPropertyTypeNew::Int)
|
||||||
{
|
{
|
||||||
int UnkIndex = (Params.Version() <= eEchoes ? rkIndex.row() - 2 : rkIndex.row() - 1);
|
int UnkIndex = (Params.Version() <= eEchoes ? rkIndex.row() - 2 : rkIndex.row() - 1);
|
||||||
Params.SetUnknown(UnkIndex, static_cast<WIntegralSpinBox*>(pEditor)->value() );
|
Params.SetUnknown(UnkIndex, static_cast<WIntegralSpinBox*>(pEditor)->value() );
|
||||||
}
|
}
|
||||||
|
|
||||||
pProp->Set(Params);
|
pAnimSetProp->ValueRef(mpModel->GetPropertyData()) = Params;
|
||||||
|
|
||||||
// If we just updated the resource, make sure all the sub-properties of the character are flagged as changed.
|
// If we just updated the resource, make sure all the sub-properties of the character are flagged as changed.
|
||||||
// We want to do this -after- updating the anim params on the property, which is why we have a second type check.
|
// We want to do this -after- updating the anim params on the property, which is why we have a second type check.
|
||||||
if (Type == eAssetProperty)
|
if (Type == EPropertyTypeNew::Asset)
|
||||||
{
|
{
|
||||||
QModelIndex ParentIndex = rkIndex.parent();
|
QModelIndex ParentIndex = rkIndex.parent();
|
||||||
mpModel->dataChanged(mpModel->index(1, 1, ParentIndex), mpModel->index(mpModel->rowCount(ParentIndex) - 1, 1, ParentIndex));
|
mpModel->dataChanged(mpModel->index(1, 1, ParentIndex), mpModel->index(mpModel->rowCount(ParentIndex) - 1, 1, ParentIndex));
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EPropertyTypeNew CPropertyDelegate::DetermineCharacterPropType(EGame Game, const QModelIndex& rkIndex) const
|
EPropertyTypeNew CPropertyDelegate::DetermineCharacterPropType(EGame Game, const QModelIndex& rkIndex) const
|
||||||
|
@ -18,14 +18,14 @@ CPropertyModel::CPropertyModel(QObject *pParent /*= 0*/)
|
|||||||
|
|
||||||
int CPropertyModel::RecursiveBuildArrays(IPropertyNew* pProperty, int ParentID)
|
int CPropertyModel::RecursiveBuildArrays(IPropertyNew* pProperty, int ParentID)
|
||||||
{
|
{
|
||||||
|
int MyID = mProperties.size();
|
||||||
mProperties << SProperty();
|
mProperties << SProperty();
|
||||||
SProperty& Property = mProperties.back();
|
|
||||||
Property.pProperty = pProperty;
|
|
||||||
Property.ParentID = ParentID;
|
|
||||||
|
|
||||||
int MyID = mProperties.size() - 1;
|
mProperties[MyID].pProperty = pProperty;
|
||||||
|
mProperties[MyID].ParentID = ParentID;
|
||||||
|
|
||||||
int RowNumber = (ParentID >= 0 ? mProperties[ParentID].ChildIDs.size() : 0);
|
int RowNumber = (ParentID >= 0 ? mProperties[ParentID].ChildIDs.size() : 0);
|
||||||
Property.Index = createIndex(RowNumber, 0, pProperty);
|
mProperties[MyID].Index = createIndex(RowNumber, 0, MyID);
|
||||||
|
|
||||||
if (pProperty->Type() == EPropertyTypeNew::Array)
|
if (pProperty->Type() == EPropertyTypeNew::Array)
|
||||||
{
|
{
|
||||||
@ -34,7 +34,7 @@ int CPropertyModel::RecursiveBuildArrays(IPropertyNew* pProperty, int ParentID)
|
|||||||
for (u32 ElementIdx = 0; ElementIdx < pArray->ArrayCount(mpPropertyData); ElementIdx++)
|
for (u32 ElementIdx = 0; ElementIdx < pArray->ArrayCount(mpPropertyData); ElementIdx++)
|
||||||
{
|
{
|
||||||
int NewChildID = RecursiveBuildArrays( pArray->Archetype(), MyID );
|
int NewChildID = RecursiveBuildArrays( pArray->Archetype(), MyID );
|
||||||
Property.ChildIDs.push_back(NewChildID);
|
mProperties[MyID].ChildIDs.push_back(NewChildID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -42,7 +42,7 @@ int CPropertyModel::RecursiveBuildArrays(IPropertyNew* pProperty, int ParentID)
|
|||||||
for (u32 ChildIdx = 0; ChildIdx < pProperty->NumChildren(); ChildIdx++)
|
for (u32 ChildIdx = 0; ChildIdx < pProperty->NumChildren(); ChildIdx++)
|
||||||
{
|
{
|
||||||
int NewChildID = RecursiveBuildArrays( pProperty->ChildByIndex(ChildIdx), MyID );
|
int NewChildID = RecursiveBuildArrays( pProperty->ChildByIndex(ChildIdx), MyID );
|
||||||
Property.ChildIDs.push_back(NewChildID);
|
mProperties[MyID].ChildIDs.push_back(NewChildID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ void CPropertyModel::ConfigureIntrinsic(CGameProject* pProject, IPropertyNew* pR
|
|||||||
|
|
||||||
void CPropertyModel::ConfigureScript(CGameProject* pProject, IPropertyNew* pRootProperty, CScriptObject* pObject)
|
void CPropertyModel::ConfigureScript(CGameProject* pProject, IPropertyNew* pRootProperty, CScriptObject* pObject)
|
||||||
{
|
{
|
||||||
ConfigureIntrinsic(pProject, pRootProperty, pObject);
|
ConfigureIntrinsic(pProject, pRootProperty, pObject ? pObject->PropertyData() : nullptr);
|
||||||
mpObject = pObject;
|
mpObject = pObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,7 +166,7 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const
|
|||||||
|
|
||||||
if (Role == Qt::DisplayRole || (Role == Qt::ToolTipRole && rkIndex.column() == 1) )
|
if (Role == Qt::DisplayRole || (Role == Qt::ToolTipRole && rkIndex.column() == 1) )
|
||||||
{
|
{
|
||||||
if (rkIndex.internalId() & 0x1)
|
if (rkIndex.internalId() & 0x80000000)
|
||||||
{
|
{
|
||||||
IPropertyNew *pProp = PropertyForIndex(rkIndex, true);
|
IPropertyNew *pProp = PropertyForIndex(rkIndex, true);
|
||||||
EPropertyTypeNew Type = pProp->Type();
|
EPropertyTypeNew Type = pProp->Type();
|
||||||
@ -321,11 +321,6 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const
|
|||||||
|
|
||||||
// No display text on properties with persistent editors
|
// No display text on properties with persistent editors
|
||||||
case EPropertyTypeNew::Bool:
|
case EPropertyTypeNew::Bool:
|
||||||
if (Role == Qt::DisplayRole)
|
|
||||||
return TPropCast<CBoolProperty>(pProp)->Value(mpPropertyData) ? "True" : "False";
|
|
||||||
else
|
|
||||||
return "";
|
|
||||||
|
|
||||||
case EPropertyTypeNew::Asset:
|
case EPropertyTypeNew::Asset:
|
||||||
case EPropertyTypeNew::Color:
|
case EPropertyTypeNew::Color:
|
||||||
if (Role == Qt::DisplayRole)
|
if (Role == Qt::DisplayRole)
|
||||||
@ -341,12 +336,12 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const
|
|||||||
|
|
||||||
if (Role == Qt::ToolTipRole && rkIndex.column() == 0)
|
if (Role == Qt::ToolTipRole && rkIndex.column() == 0)
|
||||||
{
|
{
|
||||||
if (!(rkIndex.internalId() & 0x1))
|
if (!(rkIndex.internalId() & 0x80000000))
|
||||||
{
|
{
|
||||||
// Add name
|
// Add name
|
||||||
IPropertyNew *pProp = PropertyForIndex(rkIndex, false);
|
IPropertyNew *pProp = PropertyForIndex(rkIndex, false);
|
||||||
QString DisplayText = data(rkIndex, Qt::DisplayRole).toString();
|
QString DisplayText = data(rkIndex, Qt::DisplayRole).toString();
|
||||||
QString Text = QString("<b>%1</b> <i>(%2)</i>").arg(DisplayText).arg(TO_QSTRING(PropEnumToPropString(pProp->Type())));
|
QString Text = QString("<b>%1</b> <i>(%2)</i>").arg(DisplayText).arg(pProp->HashableTypeName());
|
||||||
|
|
||||||
// Add uncooked notification
|
// Add uncooked notification
|
||||||
if (pProp->CookPreference() == ECookPreferenceNew::Never)
|
if (pProp->CookPreference() == ECookPreferenceNew::Never)
|
||||||
@ -444,7 +439,10 @@ QModelIndex CPropertyModel::parent(const QModelIndex& rkChild) const
|
|||||||
else
|
else
|
||||||
ID = mProperties[ID].ParentID;
|
ID = mProperties[ID].ParentID;
|
||||||
|
|
||||||
|
if (ID >= 0)
|
||||||
return mProperties[ID].Index;
|
return mProperties[ID].Index;
|
||||||
|
else
|
||||||
|
return QModelIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
Qt::ItemFlags CPropertyModel::flags(const QModelIndex& rkIndex) const
|
Qt::ItemFlags CPropertyModel::flags(const QModelIndex& rkIndex) const
|
||||||
|
@ -81,7 +81,7 @@ void CPropertyView::SetEditor(CWorldEditor *pEditor)
|
|||||||
{
|
{
|
||||||
mpEditor = pEditor;
|
mpEditor = pEditor;
|
||||||
mpDelegate->SetEditor(pEditor);
|
mpDelegate->SetEditor(pEditor);
|
||||||
connect(mpEditor, SIGNAL(PropertyModified(CScriptObject*,IProperty*)), mpModel, SLOT(NotifyPropertyModified(CScriptObject*,IProperty*)));
|
connect(mpEditor, SIGNAL(PropertyModified(CScriptObject*,IPropertyNew*)), mpModel, SLOT(NotifyPropertyModified(CScriptObject*,IPropertyNew*)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPropertyView::SetInstance(CScriptObject *pObj)
|
void CPropertyView::SetInstance(CScriptObject *pObj)
|
||||||
|
@ -63,6 +63,7 @@ CResourceBrowser::CResourceBrowser(QWidget *pParent)
|
|||||||
mpProxyModel = new CResourceProxyModel(this);
|
mpProxyModel = new CResourceProxyModel(this);
|
||||||
mpProxyModel->setSourceModel(mpModel);
|
mpProxyModel->setSourceModel(mpModel);
|
||||||
mpUI->ResourceTableView->setModel(mpProxyModel);
|
mpUI->ResourceTableView->setModel(mpProxyModel);
|
||||||
|
mpUI->ResourceTableView->resizeRowsToContents();
|
||||||
|
|
||||||
QHeaderView *pHeader = mpUI->ResourceTableView->horizontalHeader();
|
QHeaderView *pHeader = mpUI->ResourceTableView->horizontalHeader();
|
||||||
pHeader->setSectionResizeMode(0, QHeaderView::Stretch);
|
pHeader->setSectionResizeMode(0, QHeaderView::Stretch);
|
||||||
@ -158,6 +159,7 @@ CResourceBrowser::CResourceBrowser(QWidget *pParent)
|
|||||||
connect(mpUI->ResourceTableView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(OnResourceSelectionChanged(QModelIndex)));
|
connect(mpUI->ResourceTableView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(OnResourceSelectionChanged(QModelIndex)));
|
||||||
connect(mpProxyModel, SIGNAL(rowsInserted(QModelIndex,int,int)), mpUI->ResourceTableView, SLOT(resizeRowsToContents()));
|
connect(mpProxyModel, SIGNAL(rowsInserted(QModelIndex,int,int)), mpUI->ResourceTableView, SLOT(resizeRowsToContents()));
|
||||||
connect(mpProxyModel, SIGNAL(layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)), mpUI->ResourceTableView, SLOT(resizeRowsToContents()));
|
connect(mpProxyModel, SIGNAL(layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)), mpUI->ResourceTableView, SLOT(resizeRowsToContents()));
|
||||||
|
connect(mpProxyModel, SIGNAL(modelReset()), mpUI->ResourceTableView, SLOT(resizeRowsToContents()));
|
||||||
connect(mpFilterAllBox, SIGNAL(toggled(bool)), this, SLOT(OnFilterTypeBoxTicked(bool)));
|
connect(mpFilterAllBox, SIGNAL(toggled(bool)), this, SLOT(OnFilterTypeBoxTicked(bool)));
|
||||||
connect(gpEdApp, SIGNAL(ActiveProjectChanged(CGameProject*)), this, SLOT(UpdateStore()));
|
connect(gpEdApp, SIGNAL(ActiveProjectChanged(CGameProject*)), this, SLOT(UpdateStore()));
|
||||||
}
|
}
|
||||||
@ -874,6 +876,9 @@ void CResourceBrowser::UpdateFilter()
|
|||||||
UpdateDescriptionLabel();
|
UpdateDescriptionLabel();
|
||||||
mpProxyModel->SetSearchString( TO_TSTRING(mpUI->SearchBar->text()) );
|
mpProxyModel->SetSearchString( TO_TSTRING(mpUI->SearchBar->text()) );
|
||||||
mpProxyModel->invalidate();
|
mpProxyModel->invalidate();
|
||||||
|
|
||||||
|
// not sure why I need to do this here? but the resize mode seems to get reset otherwise
|
||||||
|
mpUI->ResourceTableView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CResourceBrowser::UpdateUndoActionStates()
|
void CResourceBrowser::UpdateUndoActionStates()
|
||||||
|
@ -7,29 +7,83 @@
|
|||||||
#include "Editor/PropertyEdit/CPropertyModel.h"
|
#include "Editor/PropertyEdit/CPropertyModel.h"
|
||||||
#include "Editor/WorldEditor/CWorldEditor.h"
|
#include "Editor/WorldEditor/CWorldEditor.h"
|
||||||
|
|
||||||
template<class PropertyClass>
|
class IEditPropertyCommand : public IUndoCommand
|
||||||
class TEditScriptPropertyCommand : public IUndoCommand
|
|
||||||
{
|
{
|
||||||
typedef typename PropertyClass::ValueType ValueType;
|
std::vector<char> mOldData;
|
||||||
|
std::vector<char> mNewData;
|
||||||
|
|
||||||
CWorldEditor *mpEditor;
|
protected:
|
||||||
CInstancePtr mpInstance;
|
IPropertyNew* mpProperty;
|
||||||
PropertyClass* mpProperty;
|
|
||||||
ValueType mOldValue;
|
|
||||||
ValueType mNewValue;
|
|
||||||
bool mCommandEnded;
|
bool mCommandEnded;
|
||||||
|
bool mSavedOldData;
|
||||||
|
bool mSavedNewData;
|
||||||
|
|
||||||
|
/** Save the current state of the object properties to the given data buffer */
|
||||||
|
void SaveObjectStateToArray(std::vector<char>& rVector)
|
||||||
|
{
|
||||||
|
CVectorOutStream MemStream(&rVector, IOUtil::kSystemEndianness);
|
||||||
|
CBasicBinaryWriter Writer(&MemStream, CSerialVersion(IArchive::skCurrentArchiveVersion, 0, mpProperty->Game()));
|
||||||
|
|
||||||
|
std::vector<void*> DataPointers;
|
||||||
|
GetObjectDataPointers(DataPointers);
|
||||||
|
|
||||||
|
for (int PtrIdx = 0; PtrIdx < DataPointers.size(); PtrIdx++)
|
||||||
|
{
|
||||||
|
void* pData = DataPointers[PtrIdx];
|
||||||
|
mpProperty->SerializeValue(pData, Writer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Restore the state of the object properties from the given data buffer */
|
||||||
|
void RestoreObjectStateFromArray(std::vector<char>& rArray)
|
||||||
|
{
|
||||||
|
CBasicBinaryReader Reader(rArray.data(), rArray.size(), CSerialVersion(IArchive::skCurrentArchiveVersion, 0, mpProperty->Game()));
|
||||||
|
|
||||||
|
std::vector<void*> DataPointers;
|
||||||
|
GetObjectDataPointers(DataPointers);
|
||||||
|
|
||||||
|
for (int PtrIdx = 0; PtrIdx < DataPointers.size(); PtrIdx++)
|
||||||
|
{
|
||||||
|
void* pData = DataPointers[PtrIdx];
|
||||||
|
mpProperty->SerializeValue(pData, Reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TEditScriptPropertyCommand(PropertyClass* pProp, CScriptObject* pInstance, CWorldEditor* pEditor, ValueType NewValue, bool IsDone, const QString& rkCommandName = "Edit Property")
|
IEditPropertyCommand(IPropertyNew* pProperty, const QString& rkCommandName = "Edit Property")
|
||||||
: IUndoCommand(rkCommandName)
|
: IUndoCommand(rkCommandName)
|
||||||
, mpEditor(pEditor)
|
, mpProperty(pProperty)
|
||||||
, mpInstance(pInstance)
|
, mSavedOldData(false)
|
||||||
, mpProperty(pProp)
|
, mSavedNewData(false)
|
||||||
, mOldValue(pProp->Value(pInstance->PropertyData()))
|
|
||||||
, mNewValue(NewValue)
|
|
||||||
, mCommandEnded(IsDone)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
void SaveOldData()
|
||||||
|
{
|
||||||
|
SaveObjectStateToArray(mOldData);
|
||||||
|
mSavedOldData = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SaveNewData()
|
||||||
|
{
|
||||||
|
SaveObjectStateToArray(mNewData);
|
||||||
|
mSavedNewData = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsNewDataDifferent()
|
||||||
|
{
|
||||||
|
if (mOldData.size() != mNewData.size()) return false;
|
||||||
|
return memcmp(mOldData.data(), mNewData.data(), mNewData.size()) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetEditComplete(bool IsComplete)
|
||||||
|
{
|
||||||
|
mCommandEnded = IsComplete;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Interface */
|
||||||
|
virtual void GetObjectDataPointers(std::vector<void*>& rOutPointers) const = 0;
|
||||||
|
|
||||||
|
/** IUndoCommand/QUndoCommand interface */
|
||||||
int id() const
|
int id() const
|
||||||
{
|
{
|
||||||
return eEditScriptPropertyCmd;
|
return eEditScriptPropertyCmd;
|
||||||
@ -39,32 +93,46 @@ public:
|
|||||||
{
|
{
|
||||||
if (!mCommandEnded)
|
if (!mCommandEnded)
|
||||||
{
|
{
|
||||||
TEditScriptPropertyCommand* pkCmd = dynamic_cast<TEditScriptPropertyCommand>(pkOther);
|
const IEditPropertyCommand* pkCmd = dynamic_cast<const IEditPropertyCommand*>(pkOther);
|
||||||
|
|
||||||
if (pkCmd && pkCmd->mpProperty == mpProperty && pkCmd->mpInstance == mpInstance)
|
if (pkCmd && pkCmd->mpProperty == mpProperty)
|
||||||
{
|
{
|
||||||
mNewValue = pkCmd->mNewValue;
|
std::vector<void*> MyPointers;
|
||||||
|
GetObjectDataPointers(MyPointers);
|
||||||
|
|
||||||
|
std::vector<void*> TheirPointers;
|
||||||
|
pkCmd->GetObjectDataPointers(TheirPointers);
|
||||||
|
|
||||||
|
if (TheirPointers.size() == MyPointers.size())
|
||||||
|
{
|
||||||
|
for (int PtrIdx = 0; PtrIdx < MyPointers.size(); PtrIdx++)
|
||||||
|
{
|
||||||
|
if (MyPointers[PtrIdx] != TheirPointers[PtrIdx])
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Match
|
||||||
|
mNewData = pkCmd->mNewData;
|
||||||
mCommandEnded = pkCmd->mCommandEnded;
|
mCommandEnded = pkCmd->mCommandEnded;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void undo()
|
void undo()
|
||||||
{
|
{
|
||||||
void* pData = mpInstance->PropertyData();
|
ASSERT(mSavedOldData && mSavedNewData);
|
||||||
mpProperty->ValueRef(pData) = mOldValue;
|
RestoreObjectStateFromArray(mOldData);
|
||||||
mpEditor->OnPropertyModified(mpProperty);
|
|
||||||
mCommandEnded = true;
|
mCommandEnded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void redo()
|
void redo()
|
||||||
{
|
{
|
||||||
void* pData = mpInstance->PropertyData();
|
ASSERT(mSavedOldData && mSavedNewData);
|
||||||
mpProperty->ValueRef(pData) = mNewValue;
|
RestoreObjectStateFromArray(mNewData);
|
||||||
mpEditor->OnPropertyModified(mpProperty);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AffectsCleanState() const
|
bool AffectsCleanState() const
|
||||||
@ -73,22 +141,46 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*class CEditScriptPropertyCommand : public IUndoCommand
|
class CEditScriptPropertyCommand : public IEditPropertyCommand
|
||||||
{
|
{
|
||||||
CWorldEditor *mpEditor;
|
std::vector<CInstancePtr> mInstances;
|
||||||
CPropertyPtr mpProp;
|
CWorldEditor* mpEditor;
|
||||||
IPropertyValue *mpOldValue;
|
|
||||||
IPropertyValue *mpNewValue;
|
|
||||||
bool mCommandEnded;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CEditScriptPropertyCommand(IProperty *pProp, CWorldEditor *pEditor, IPropertyValue *pOldValue, bool IsDone, const QString& rkCommandName = "Edit Property");
|
CEditScriptPropertyCommand(CWorldEditor* pEditor, CScriptObject* pInstance, IPropertyNew* pProperty, const QString& rkCommandName = "Edit Property")
|
||||||
~CEditScriptPropertyCommand();
|
: IEditPropertyCommand(pProperty, rkCommandName)
|
||||||
int id() const;
|
, mpEditor(pEditor)
|
||||||
bool mergeWith(const QUndoCommand *pkOther);
|
{
|
||||||
void undo();
|
mInstances.push_back( CInstancePtr(pInstance) );
|
||||||
void redo();
|
}
|
||||||
bool AffectsCleanState() const { return true; }
|
|
||||||
};*/
|
virtual void GetObjectDataPointers(std::vector<void*>& rOutPointers) const override
|
||||||
|
{
|
||||||
|
rOutPointers.resize(mInstances.size());
|
||||||
|
|
||||||
|
for (int InstanceIdx = 0; InstanceIdx < mInstances.size(); InstanceIdx++)
|
||||||
|
{
|
||||||
|
rOutPointers[InstanceIdx] = mInstances[InstanceIdx]->PropertyData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void undo() override
|
||||||
|
{
|
||||||
|
IEditPropertyCommand::undo();
|
||||||
|
NotifyWorldEditor();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void redo() override
|
||||||
|
{
|
||||||
|
IEditPropertyCommand::redo();
|
||||||
|
NotifyWorldEditor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotifyWorldEditor()
|
||||||
|
{
|
||||||
|
for (int InstanceIdx = 0; InstanceIdx < mInstances.size(); InstanceIdx++)
|
||||||
|
mpEditor->OnPropertyModified(*mInstances[InstanceIdx], mpProperty);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#endif // CEDITSCRIPTPROPERTYCOMMAND_H
|
#endif // CEDITSCRIPTPROPERTYCOMMAND_H
|
||||||
|
@ -34,8 +34,10 @@ protected slots:
|
|||||||
|
|
||||||
if ( mpSoftValidator )
|
if ( mpSoftValidator )
|
||||||
{
|
{
|
||||||
|
QString Text = text();
|
||||||
int DummyPos;
|
int DummyPos;
|
||||||
if ( mpSoftValidator->validate(text(), DummyPos) == QValidator::Acceptable )
|
|
||||||
|
if ( mpSoftValidator->validate(Text, DummyPos) == QValidator::Acceptable )
|
||||||
{
|
{
|
||||||
NewValidity = true;
|
NewValidity = true;
|
||||||
setStyleSheet("border: 1px solid green");
|
setStyleSheet("border: 1px solid green");
|
||||||
|
@ -569,11 +569,12 @@ void CWorldEditor::OnLinksModified(const QList<CScriptObject*>& rkInstances)
|
|||||||
emit InstanceLinksModified(rkInstances);
|
emit InstanceLinksModified(rkInstances);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWorldEditor::OnPropertyModified(IPropertyNew *pProp)
|
void CWorldEditor::OnPropertyModified(CScriptObject* pObject, IPropertyNew *pProp)
|
||||||
{
|
{
|
||||||
if (!mpSelection->IsEmpty() && mpSelection->Front()->NodeType() == eScriptNode)
|
CScriptNode *pScript = mScene.NodeForInstance(pObject);
|
||||||
|
|
||||||
|
if (pScript)
|
||||||
{
|
{
|
||||||
CScriptNode *pScript = static_cast<CScriptNode*>(mpSelection->Front());
|
|
||||||
pScript->PropertyModified(pProp);
|
pScript->PropertyModified(pProp);
|
||||||
|
|
||||||
// If this is an editor property, update other parts of the UI to reflect the new value.
|
// If this is an editor property, update other parts of the UI to reflect the new value.
|
||||||
@ -581,6 +582,8 @@ void CWorldEditor::OnPropertyModified(IPropertyNew *pProp)
|
|||||||
{
|
{
|
||||||
UpdateStatusBar();
|
UpdateStatusBar();
|
||||||
UpdateSelectionUI();
|
UpdateSelectionUI();
|
||||||
|
mpSelection->UpdateBounds();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 this is a model/character, then we'll treat this as a modified selection. This is to make sure the selection bounds updates.
|
||||||
@ -596,8 +599,7 @@ void CWorldEditor::OnPropertyModified(IPropertyNew *pProp)
|
|||||||
SelectionModified();
|
SelectionModified();
|
||||||
|
|
||||||
// Emit signal so other widgets can react to the property change
|
// Emit signal so other widgets can react to the property change
|
||||||
emit PropertyModified(pScript->Instance(), pProp);
|
emit PropertyModified(pObject, pProp);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWorldEditor::SetSelectionActive(bool Active)
|
void CWorldEditor::SetSelectionActive(bool Active)
|
||||||
|
@ -122,7 +122,7 @@ public slots:
|
|||||||
|
|
||||||
void OnActiveProjectChanged(CGameProject *pProj);
|
void OnActiveProjectChanged(CGameProject *pProj);
|
||||||
void OnLinksModified(const QList<CScriptObject*>& rkInstances);
|
void OnLinksModified(const QList<CScriptObject*>& rkInstances);
|
||||||
void OnPropertyModified(IPropertyNew *pProp);
|
void OnPropertyModified(CScriptObject* pObject, IPropertyNew *pProp);
|
||||||
void SetSelectionActive(bool Active);
|
void SetSelectionActive(bool Active);
|
||||||
void SetSelectionInstanceNames(const QString& rkNewName, bool IsDone);
|
void SetSelectionInstanceNames(const QString& rkNewName, bool IsDone);
|
||||||
void SetSelectionLayer(CScriptLayer *pLayer);
|
void SetSelectionLayer(CScriptLayer *pLayer);
|
||||||
|
@ -65,7 +65,7 @@ void WEditorProperties::SyncToEditor(CWorldEditor *pEditor)
|
|||||||
connect(mpEditor, SIGNAL(SelectionModified()), this, SLOT(OnSelectionModified()));
|
connect(mpEditor, SIGNAL(SelectionModified()), this, SLOT(OnSelectionModified()));
|
||||||
connect(mpEditor, SIGNAL(LayersModified()), this, SLOT(OnLayersModified()));
|
connect(mpEditor, SIGNAL(LayersModified()), this, SLOT(OnLayersModified()));
|
||||||
connect(mpEditor, SIGNAL(InstancesLayerChanged(QList<CScriptNode*>)), this, SLOT(OnInstancesLayerChanged(QList<CScriptNode*>)));
|
connect(mpEditor, SIGNAL(InstancesLayerChanged(QList<CScriptNode*>)), this, SLOT(OnInstancesLayerChanged(QList<CScriptNode*>)));
|
||||||
connect(mpEditor, SIGNAL(PropertyModified(CScriptObject*,IProperty*)), this, SLOT(OnPropertyModified(CScriptObject*,IProperty*)));
|
connect(mpEditor, SIGNAL(PropertyModified(CScriptObject*,IPropertyNew*)), this, SLOT(OnPropertyModified(CScriptObject*,IPropertyNew*)));
|
||||||
|
|
||||||
OnLayersModified();
|
OnLayersModified();
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
// Load templates
|
// Load templates
|
||||||
CTemplateLoader::LoadGameList();
|
CTemplateLoader::LoadGameList();
|
||||||
CTemplateLoader::LoadAllGames();
|
//CTemplateLoader::LoadAllGames();
|
||||||
//CTemplateWriter::SaveAllTemplates();
|
//CTemplateWriter::SaveAllTemplates();
|
||||||
|
|
||||||
// Execute application
|
// Execute application
|
||||||
|
@ -139,16 +139,6 @@ float CMatrix4f::Determinant() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ************ OPERATORS ************
|
// ************ OPERATORS ************
|
||||||
inline float* CMatrix4f::operator[](long Index)
|
|
||||||
{
|
|
||||||
return m[Index];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const float* CMatrix4f::operator[](long Index) const
|
|
||||||
{
|
|
||||||
return m[Index];
|
|
||||||
}
|
|
||||||
|
|
||||||
CVector3f CMatrix4f::operator*(const CVector3f& rkVec) const
|
CVector3f CMatrix4f::operator*(const CVector3f& rkVec) const
|
||||||
{
|
{
|
||||||
// For vec3 multiplication, the vector w component is considered to be 1.0
|
// For vec3 multiplication, the vector w component is considered to be 1.0
|
||||||
|
@ -42,4 +42,14 @@ public:
|
|||||||
static const CMatrix4f skIdentity;
|
static const CMatrix4f skIdentity;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline float* CMatrix4f::operator[](long Index)
|
||||||
|
{
|
||||||
|
return m[Index];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const float* CMatrix4f::operator[](long Index) const
|
||||||
|
{
|
||||||
|
return m[Index];
|
||||||
|
}
|
||||||
|
|
||||||
#endif // CMATRIX4_H
|
#endif // CMATRIX4_H
|
||||||
|
@ -43,7 +43,7 @@ void CVector3f::Serialize(IArchive& rArc)
|
|||||||
|
|
||||||
TString CVector3f::ToString() const
|
TString CVector3f::ToString() const
|
||||||
{
|
{
|
||||||
return TString::Format("%f.1, %f.1, %f.1", X, Y, Z);
|
return TString::Format("%.1f, %.1f, %.1f", X, Y, Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ SWIZZLE ************
|
// ************ SWIZZLE ************
|
||||||
|
Loading…
x
Reference in New Issue
Block a user