Fixed array property display on UI (they still can't be resized)
This commit is contained in:
parent
4faadbda61
commit
641cf81dd8
|
@ -213,7 +213,7 @@ void CScriptCooker::WriteProperty(IOutputStream& rOut, IPropertyNew* pProperty,
|
||||||
for (u32 ElementIdx = 0; ElementIdx < pArray->ArrayCount(pData); ElementIdx++)
|
for (u32 ElementIdx = 0; ElementIdx < pArray->ArrayCount(pData); ElementIdx++)
|
||||||
{
|
{
|
||||||
mpArrayItemData = pArray->ItemPointer(pData, ElementIdx);
|
mpArrayItemData = pArray->ItemPointer(pData, ElementIdx);
|
||||||
WriteProperty(rOut, pArray->ArchetypeProperty(), true);
|
WriteProperty(rOut, pArray->ItemArchetype(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
mpArrayItemData = pOldItemData;
|
mpArrayItemData = pOldItemData;
|
||||||
|
|
|
@ -219,7 +219,7 @@ void CScriptLoader::ReadProperty(IPropertyNew *pProp, u32 Size, IInputStream& rS
|
||||||
|
|
||||||
// Make sure the array archetype is atomic... non-atomic array archetypes is not supported
|
// Make sure the array archetype is atomic... non-atomic array archetypes is not supported
|
||||||
// because arrays can only have one possible archetype so having property IDs here wouldn't make sense
|
// because arrays can only have one possible archetype so having property IDs here wouldn't make sense
|
||||||
ASSERT(pArray->ArchetypeProperty()->IsAtomic());
|
ASSERT(pArray->ItemArchetype()->IsAtomic());
|
||||||
|
|
||||||
for (int ElementIdx = 0; ElementIdx < Count; ElementIdx++)
|
for (int ElementIdx = 0; ElementIdx < Count; ElementIdx++)
|
||||||
{
|
{
|
||||||
|
@ -236,7 +236,7 @@ void CScriptLoader::ReadProperty(IPropertyNew *pProp, u32 Size, IInputStream& rS
|
||||||
* things to make this cleaner
|
* things to make this cleaner
|
||||||
*/
|
*/
|
||||||
mpArrayItemData = pArray->ItemPointer(pData, ElementIdx);
|
mpArrayItemData = pArray->ItemPointer(pData, ElementIdx);
|
||||||
ReadProperty(pArray->ArchetypeProperty(), 0, rSCLY);
|
ReadProperty(pArray->ItemArchetype(), 0, rSCLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
mpArrayItemData = pOldArrayItemData;
|
mpArrayItemData = pOldArrayItemData;
|
||||||
|
|
|
@ -333,18 +333,22 @@ IPropertyNew* CTemplateLoader::LoadProperty(XMLElement* pElem, CScriptTemplate*
|
||||||
{
|
{
|
||||||
CArrayProperty* pArray = TPropCast<CArrayProperty>(pProp);
|
CArrayProperty* pArray = TPropCast<CArrayProperty>(pProp);
|
||||||
|
|
||||||
if (pArray->mpArchetype != nullptr)
|
if (pArray->mpItemArchetype != nullptr)
|
||||||
{
|
{
|
||||||
ASSERT(pArray->mpArchetype->Type() == EPropertyTypeNew::Struct);
|
ASSERT(pArray->mpItemArchetype->Type() == EPropertyTypeNew::Struct);
|
||||||
pStruct = TPropCast<CStructPropertyNew>(pArray->mpArchetype);
|
pStruct = TPropCast<CStructPropertyNew>(pArray->mpItemArchetype);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pArray->mpArchetype = IPropertyNew::Create(EPropertyTypeNew::Struct, pArray, mpMaster, pScript, false);
|
pArray->mpItemArchetype = IPropertyNew::Create(EPropertyTypeNew::Struct, pArray, mpMaster, pScript, false);
|
||||||
pStruct = TPropCast<CStructPropertyNew>(pArray->mpArchetype);
|
pStruct = TPropCast<CStructPropertyNew>(pArray->mpItemArchetype);
|
||||||
pStruct->mFlags = EPropertyFlag::IsAtomic | EPropertyFlag::IsArrayArchetype;
|
pStruct->mFlags = EPropertyFlag::IsAtomic | EPropertyFlag::IsArrayArchetype;
|
||||||
}
|
}
|
||||||
pStruct = TPropCast<CStructPropertyNew>(pArray->mpArchetype);
|
|
||||||
|
XMLElement* pItemNameElem = pElem->FirstChildElement("element_name");
|
||||||
|
|
||||||
|
if (pItemNameElem)
|
||||||
|
pStruct->mName = pItemNameElem->GetText();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load parameter overrides
|
// Load parameter overrides
|
||||||
|
|
|
@ -152,10 +152,8 @@ TString IPropertyNew::GetTemplateFileName()
|
||||||
void* IPropertyNew::RawValuePtr(void* pData) const
|
void* IPropertyNew::RawValuePtr(void* pData) const
|
||||||
{
|
{
|
||||||
// For array archetypes, the caller needs to provide the pointer to the correct array item
|
// For array archetypes, the caller needs to provide the pointer to the correct array item
|
||||||
if (IsArrayArchetype())
|
// Array archetypes can't store their index in the array so it's impossible to determine the correct pointer.
|
||||||
return pData;
|
void* pBasePtr = (mpPointerParent && !IsArrayArchetype() ? mpPointerParent->GetChildDataPointer(pData) : pData);
|
||||||
|
|
||||||
void* pBasePtr = (mpPointerParent ? mpPointerParent->GetChildDataPointer(pData) : pData);
|
|
||||||
void* pValuePtr = ((char*)pBasePtr + mOffset);
|
void* pValuePtr = ((char*)pBasePtr + mOffset);
|
||||||
return pValuePtr;
|
return pValuePtr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,7 @@ inline const char* PropEnumToHashableTypeName(EPropertyTypeNew Type)
|
||||||
{
|
{
|
||||||
switch (Type)
|
switch (Type)
|
||||||
{
|
{
|
||||||
|
// these names are required to generate accurate property ID hashes
|
||||||
case EPropertyTypeNew::Bool: return "bool";
|
case EPropertyTypeNew::Bool: return "bool";
|
||||||
case EPropertyTypeNew::Int: return "int";
|
case EPropertyTypeNew::Int: return "int";
|
||||||
case EPropertyTypeNew::Float: return "float";
|
case EPropertyTypeNew::Float: return "float";
|
||||||
|
@ -85,6 +86,14 @@ inline const char* PropEnumToHashableTypeName(EPropertyTypeNew Type)
|
||||||
case EPropertyTypeNew::Sound: return "sound";
|
case EPropertyTypeNew::Sound: return "sound";
|
||||||
case EPropertyTypeNew::Spline: return "spline";
|
case EPropertyTypeNew::Spline: return "spline";
|
||||||
case EPropertyTypeNew::Guid: return "guid";
|
case EPropertyTypeNew::Guid: return "guid";
|
||||||
|
// unknown hashable types - used in hashes but these names are inaccurate
|
||||||
|
case EPropertyTypeNew::Animation: return "animation"; // hashable but real name unknown
|
||||||
|
case EPropertyTypeNew::Sequence: return "sequence";
|
||||||
|
// non hashable types - not used in ID hashes but still displayed on the UI
|
||||||
|
case EPropertyTypeNew::Byte: return "byte";
|
||||||
|
case EPropertyTypeNew::Short: return "short";
|
||||||
|
case EPropertyTypeNew::Array: return "array";
|
||||||
|
// fallback
|
||||||
default: return "";
|
default: return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,11 @@ public:
|
||||||
{
|
{
|
||||||
Value(pData).Serialize(Arc);
|
Value(pData).Serialize(Arc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual const char* HashableTypeName() const
|
||||||
|
{
|
||||||
|
return (Game() <= eEchoes ? "AnimationSet" : "CharacterAnimationSet");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CANIMATIONSETPROPERTY_H
|
#endif // CANIMATIONSETPROPERTY_H
|
||||||
|
|
|
@ -22,7 +22,9 @@ struct SScriptArray
|
||||||
/** @todo proper support of default values for arrays (this would be used for prefabs) */
|
/** @todo proper support of default values for arrays (this would be used for prefabs) */
|
||||||
class CArrayProperty : public TTypedPropertyNew<int, EPropertyTypeNew::Array>
|
class CArrayProperty : public TTypedPropertyNew<int, EPropertyTypeNew::Array>
|
||||||
{
|
{
|
||||||
|
friend class IPropertyNew;
|
||||||
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 (the first member of SScriptArray). Outside users can edit this
|
* count value (the first member of SScriptArray). Outside users can edit this
|
||||||
* value and we respond by updating the allocated space, handling item destruction
|
* value and we respond by updating the allocated space, handling item destruction
|
||||||
|
@ -42,6 +44,12 @@ class CArrayProperty : public TTypedPropertyNew<int, EPropertyTypeNew::Array>
|
||||||
return rArray.size() / ItemSize();
|
return rArray.size() / ItemSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
CArrayProperty()
|
||||||
|
: TTypedPropertyNew()
|
||||||
|
, mpItemArchetype(nullptr)
|
||||||
|
{}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual u32 DataSize() const
|
virtual u32 DataSize() const
|
||||||
{
|
{
|
||||||
|
@ -110,7 +118,7 @@ public:
|
||||||
if (Arc.ParamBegin("ArrayElement"))
|
if (Arc.ParamBegin("ArrayElement"))
|
||||||
{
|
{
|
||||||
void* pItemData = ItemPointer(pData, ItemIdx);
|
void* pItemData = ItemPointer(pData, ItemIdx);
|
||||||
mpArchetype->SerializeValue(pItemData, Arc);
|
mpItemArchetype->SerializeValue(pItemData, Arc);
|
||||||
Arc.ParamEnd();
|
Arc.ParamEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,6 +156,7 @@ public:
|
||||||
|
|
||||||
u32 NewSize = NewCount * ItemSize();
|
u32 NewSize = NewCount * ItemSize();
|
||||||
rArray.Array.resize(NewSize);
|
rArray.Array.resize(NewSize);
|
||||||
|
rArray.Count = NewCount;
|
||||||
|
|
||||||
// Handle construction of new elements
|
// Handle construction of new elements
|
||||||
if (NewCount > OldCount)
|
if (NewCount > OldCount)
|
||||||
|
@ -163,7 +172,7 @@ public:
|
||||||
|
|
||||||
void* ItemPointer(void* pPropertyData, u32 ItemIndex) const
|
void* ItemPointer(void* pPropertyData, u32 ItemIndex) const
|
||||||
{
|
{
|
||||||
ASSERT(ArrayCount(pPropertyData) > ItemIndex);
|
ASSERT(_InternalArrayCount(pPropertyData) > ItemIndex);
|
||||||
std::vector<char>& rArray = _GetInternalArray(pPropertyData).Array;
|
std::vector<char>& rArray = _GetInternalArray(pPropertyData).Array;
|
||||||
u32 MyItemSize = ItemSize();
|
u32 MyItemSize = ItemSize();
|
||||||
ASSERT(rArray.size() >= (MyItemSize * (ItemIndex+1)));
|
ASSERT(rArray.size() >= (MyItemSize * (ItemIndex+1)));
|
||||||
|
@ -178,7 +187,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Accessors */
|
/** Accessors */
|
||||||
IPropertyNew* ArchetypeProperty() const { return mpArchetype; }
|
IPropertyNew* ItemArchetype() const { return mpItemArchetype; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CARRAYPROPERTY_H
|
#endif // CARRAYPROPERTY_H
|
||||||
|
|
|
@ -18,7 +18,7 @@ public:
|
||||||
Arc.SerializePrimitive( (u8&) ValueRef(pData) );
|
Arc.SerializePrimitive( (u8&) ValueRef(pData) );
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual TString ValueAsString(void* pData)
|
virtual TString ValueAsString(void* pData) const
|
||||||
{
|
{
|
||||||
return TString::FromInt32( (s32) Value(pData), 0, 10 );
|
return TString::FromInt32( (s32) Value(pData), 0, 10 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ public:
|
||||||
Arc.SerializePrimitive( (u16&) ValueRef(pData) );
|
Arc.SerializePrimitive( (u16&) ValueRef(pData) );
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual TString ValueAsString(void* pData)
|
virtual TString ValueAsString(void* pData) const
|
||||||
{
|
{
|
||||||
return TString::FromInt32( (s32) Value(pData), 0, 10 );
|
return TString::FromInt32( (s32) Value(pData), 0, 10 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,12 +81,10 @@ public:
|
||||||
|
|
||||||
virtual const char* HashableTypeName() const
|
virtual const char* HashableTypeName() const
|
||||||
{
|
{
|
||||||
ASSERT(IsArchetype() || mpArchetype != nullptr);
|
if (IsArchetype() || !mpArchetype)
|
||||||
|
|
||||||
if (IsArchetype())
|
|
||||||
return *mName;
|
return *mName;
|
||||||
else
|
else
|
||||||
return *mpArchetype->Name();
|
return mpArchetype->HashableTypeName();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
|
@ -201,7 +201,7 @@ void CPropertyDelegate::setEditorData(QWidget *pEditor, const QModelIndex &rkInd
|
||||||
{
|
{
|
||||||
// Set editor data for regular property
|
// Set editor data for regular property
|
||||||
IPropertyNew *pProp = mpModel->PropertyForIndex(rkIndex, false);
|
IPropertyNew *pProp = mpModel->PropertyForIndex(rkIndex, false);
|
||||||
void* pData = mpModel->GetPropertyData();
|
void* pData = mpModel->DataPointerForIndex(rkIndex);
|
||||||
|
|
||||||
if (pProp)
|
if (pProp)
|
||||||
{
|
{
|
||||||
|
@ -356,7 +356,7 @@ void CPropertyDelegate::setModelData(QWidget *pEditor, QAbstractItemModel* /*pMo
|
||||||
|
|
||||||
IEditPropertyCommand* pCommand = nullptr;
|
IEditPropertyCommand* pCommand = nullptr;
|
||||||
IPropertyNew *pProp = mpModel->PropertyForIndex(rkIndex, true);
|
IPropertyNew *pProp = mpModel->PropertyForIndex(rkIndex, true);
|
||||||
void* pData = mpModel->GetPropertyData();
|
void* pData = mpModel->DataPointerForIndex(rkIndex);
|
||||||
|
|
||||||
if (pProp)
|
if (pProp)
|
||||||
{
|
{
|
||||||
|
@ -540,7 +540,7 @@ bool CPropertyDelegate::eventFilter(QObject *pObject, QEvent *pEvent)
|
||||||
QWidget* CPropertyDelegate::CreateCharacterEditor(QWidget *pParent, const QModelIndex& rkIndex) const
|
QWidget* CPropertyDelegate::CreateCharacterEditor(QWidget *pParent, const QModelIndex& rkIndex) const
|
||||||
{
|
{
|
||||||
CAnimationSetProperty* pAnimSetProp = TPropCast<CAnimationSetProperty>(mpModel->PropertyForIndex(rkIndex, true));
|
CAnimationSetProperty* pAnimSetProp = TPropCast<CAnimationSetProperty>(mpModel->PropertyForIndex(rkIndex, true));
|
||||||
CAnimationParameters Params = pAnimSetProp->Value(mpModel->GetPropertyData());
|
CAnimationParameters Params = pAnimSetProp->Value(mpModel->DataPointerForIndex(rkIndex));
|
||||||
|
|
||||||
// Determine property type
|
// Determine property type
|
||||||
EPropertyTypeNew Type = DetermineCharacterPropType(Params.Version(), rkIndex);
|
EPropertyTypeNew Type = DetermineCharacterPropType(Params.Version(), rkIndex);
|
||||||
|
@ -588,7 +588,7 @@ QWidget* CPropertyDelegate::CreateCharacterEditor(QWidget *pParent, const QModel
|
||||||
void CPropertyDelegate::SetCharacterEditorData(QWidget *pEditor, const QModelIndex& rkIndex) const
|
void CPropertyDelegate::SetCharacterEditorData(QWidget *pEditor, const QModelIndex& rkIndex) const
|
||||||
{
|
{
|
||||||
CAnimationSetProperty* pAnimSetProp = TPropCast<CAnimationSetProperty>(mpModel->PropertyForIndex(rkIndex, true));
|
CAnimationSetProperty* pAnimSetProp = TPropCast<CAnimationSetProperty>(mpModel->PropertyForIndex(rkIndex, true));
|
||||||
CAnimationParameters Params = pAnimSetProp->Value(mpModel->GetPropertyData());
|
CAnimationParameters Params = pAnimSetProp->Value(mpModel->DataPointerForIndex(rkIndex));
|
||||||
EPropertyTypeNew Type = DetermineCharacterPropType(Params.Version(), rkIndex);
|
EPropertyTypeNew Type = DetermineCharacterPropType(Params.Version(), rkIndex);
|
||||||
|
|
||||||
if (Type == EPropertyTypeNew::Asset)
|
if (Type == EPropertyTypeNew::Asset)
|
||||||
|
@ -612,7 +612,7 @@ void CPropertyDelegate::SetCharacterEditorData(QWidget *pEditor, const QModelInd
|
||||||
void CPropertyDelegate::SetCharacterModelData(QWidget *pEditor, const QModelIndex& rkIndex) const
|
void CPropertyDelegate::SetCharacterModelData(QWidget *pEditor, const QModelIndex& rkIndex) const
|
||||||
{
|
{
|
||||||
CAnimationSetProperty* pAnimSetProp = TPropCast<CAnimationSetProperty>(mpModel->PropertyForIndex(rkIndex, true));
|
CAnimationSetProperty* pAnimSetProp = TPropCast<CAnimationSetProperty>(mpModel->PropertyForIndex(rkIndex, true));
|
||||||
CAnimationParameters Params = pAnimSetProp->Value(mpModel->GetPropertyData());
|
CAnimationParameters Params = pAnimSetProp->Value(mpModel->DataPointerForIndex(rkIndex));
|
||||||
EPropertyTypeNew Type = DetermineCharacterPropType(Params.Version(), rkIndex);
|
EPropertyTypeNew Type = DetermineCharacterPropType(Params.Version(), rkIndex);
|
||||||
|
|
||||||
if (Type == EPropertyTypeNew::Asset)
|
if (Type == EPropertyTypeNew::Asset)
|
||||||
|
@ -632,7 +632,7 @@ void CPropertyDelegate::SetCharacterModelData(QWidget *pEditor, const QModelInde
|
||||||
Params.SetUnknown(UnkIndex, static_cast<WIntegralSpinBox*>(pEditor)->value() );
|
Params.SetUnknown(UnkIndex, static_cast<WIntegralSpinBox*>(pEditor)->value() );
|
||||||
}
|
}
|
||||||
|
|
||||||
pAnimSetProp->ValueRef(mpModel->GetPropertyData()) = Params;
|
pAnimSetProp->ValueRef(mpModel->DataPointerForIndex(rkIndex)) = 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.
|
||||||
|
|
|
@ -30,12 +30,17 @@ int CPropertyModel::RecursiveBuildArrays(IPropertyNew* pProperty, int ParentID)
|
||||||
if (pProperty->Type() == EPropertyTypeNew::Array)
|
if (pProperty->Type() == EPropertyTypeNew::Array)
|
||||||
{
|
{
|
||||||
CArrayProperty* pArray = TPropCast<CArrayProperty>(pProperty);
|
CArrayProperty* pArray = TPropCast<CArrayProperty>(pProperty);
|
||||||
|
u32 ArrayCount = pArray->ArrayCount(mpPropertyData);
|
||||||
|
void* pOldData = mpPropertyData;
|
||||||
|
|
||||||
for (u32 ElementIdx = 0; ElementIdx < pArray->ArrayCount(mpPropertyData); ElementIdx++)
|
for (u32 ElementIdx = 0; ElementIdx < ArrayCount; ElementIdx++)
|
||||||
{
|
{
|
||||||
int NewChildID = RecursiveBuildArrays( pArray->Archetype(), MyID );
|
mpPropertyData = pArray->ItemPointer(pOldData, ElementIdx);
|
||||||
|
int NewChildID = RecursiveBuildArrays( pArray->ItemArchetype(), MyID );
|
||||||
mProperties[MyID].ChildIDs.push_back(NewChildID);
|
mProperties[MyID].ChildIDs.push_back(NewChildID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mpPropertyData = pOldData;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -115,6 +120,50 @@ QModelIndex CPropertyModel::IndexForProperty(IPropertyNew *pProp) const
|
||||||
return mProperties[ID].Index;
|
return mProperties[ID].Index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* CPropertyModel::DataPointerForIndex(const QModelIndex& rkIndex) const
|
||||||
|
{
|
||||||
|
// Going to be the base pointer in 99% of cases, but we need to account for arrays in some cases
|
||||||
|
int ID = rkIndex.internalId();
|
||||||
|
|
||||||
|
if (!mProperties[ID].pProperty->IsArrayArchetype())
|
||||||
|
return mpPropertyData;
|
||||||
|
|
||||||
|
// Head up the hierarchy until we find a non-array property, keeping track of array indices along the way
|
||||||
|
// Static arrays to avoid memory allocations, we never have more than 2 nested arrays
|
||||||
|
CArrayProperty* ArrayProperties[2];
|
||||||
|
int ArrayIndices[2];
|
||||||
|
int MaxIndex = -1;
|
||||||
|
|
||||||
|
IPropertyNew* pProperty = mProperties[ID].pProperty;
|
||||||
|
|
||||||
|
while (pProperty->IsArrayArchetype())
|
||||||
|
{
|
||||||
|
CArrayProperty* pArray = TPropCast<CArrayProperty>(pProperty->Parent());
|
||||||
|
|
||||||
|
if (pArray)
|
||||||
|
{
|
||||||
|
MaxIndex++;
|
||||||
|
ArrayProperties[MaxIndex] = pArray;
|
||||||
|
ArrayIndices[MaxIndex] = mProperties[ID].Index.row();
|
||||||
|
}
|
||||||
|
|
||||||
|
ID = mProperties[ID].ParentID;
|
||||||
|
pProperty = pProperty->Parent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now fetch the correct pointer from the array properties
|
||||||
|
void* pOutData = mpPropertyData;
|
||||||
|
|
||||||
|
for (int i = MaxIndex; i >= 0; i--)
|
||||||
|
{
|
||||||
|
CArrayProperty* pArray = ArrayProperties[i];
|
||||||
|
int ArrayIndex = ArrayIndices[i];
|
||||||
|
pOutData = pArray->ItemPointer(pOutData, ArrayIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pOutData;
|
||||||
|
}
|
||||||
|
|
||||||
int CPropertyModel::columnCount(const QModelIndex& /*rkParent*/) const
|
int CPropertyModel::columnCount(const QModelIndex& /*rkParent*/) const
|
||||||
{
|
{
|
||||||
return 2;
|
return 2;
|
||||||
|
@ -128,7 +177,7 @@ int CPropertyModel::rowCount(const QModelIndex& rkParent) const
|
||||||
if (rkParent.internalId() & 0x80000000) return 0;
|
if (rkParent.internalId() & 0x80000000) return 0;
|
||||||
|
|
||||||
IPropertyNew *pProp = PropertyForIndex(rkParent, false);
|
IPropertyNew *pProp = PropertyForIndex(rkParent, false);
|
||||||
int ID = mPropertyToIDMap[pProp];
|
int ID = rkParent.internalId();
|
||||||
|
|
||||||
switch (pProp->Type())
|
switch (pProp->Type())
|
||||||
{
|
{
|
||||||
|
@ -137,7 +186,8 @@ int CPropertyModel::rowCount(const QModelIndex& rkParent) const
|
||||||
|
|
||||||
case EPropertyTypeNew::AnimationSet:
|
case EPropertyTypeNew::AnimationSet:
|
||||||
{
|
{
|
||||||
CAnimationParameters Params = TPropCast<CAnimationSetProperty>(pProp)->Value(mpPropertyData);
|
void* pData = DataPointerForIndex(rkParent);
|
||||||
|
CAnimationParameters Params = TPropCast<CAnimationSetProperty>(pProp)->Value(pData);
|
||||||
|
|
||||||
if (Params.Version() <= eEchoes) return 3;
|
if (Params.Version() <= eEchoes) return 3;
|
||||||
if (Params.Version() <= eCorruption) return 2;
|
if (Params.Version() <= eCorruption) return 2;
|
||||||
|
@ -183,14 +233,15 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const
|
||||||
if (Role == Qt::DisplayRole)
|
if (Role == Qt::DisplayRole)
|
||||||
return "";
|
return "";
|
||||||
else
|
else
|
||||||
return TO_QSTRING(TString::HexString( pFlags->FlagMask(rkIndex.row())));
|
return TO_QSTRING(TString::HexString( pFlags->FlagMask(rkIndex.row()) ));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (Type == EPropertyTypeNew::AnimationSet)
|
else if (Type == EPropertyTypeNew::AnimationSet)
|
||||||
{
|
{
|
||||||
|
void* pData = DataPointerForIndex(rkIndex);
|
||||||
CAnimationSetProperty* pAnimSet = TPropCast<CAnimationSetProperty>(pProp);
|
CAnimationSetProperty* pAnimSet = TPropCast<CAnimationSetProperty>(pProp);
|
||||||
CAnimationParameters Params = pAnimSet->Value(mpPropertyData);
|
CAnimationParameters Params = pAnimSet->Value(pData);
|
||||||
|
|
||||||
// There are three different layouts for this property - one for MP1/2, one for MP3, and one for DKCR
|
// There are three different layouts for this property - one for MP1/2, one for MP3, and one for DKCR
|
||||||
if (Params.Version() <= eEchoes)
|
if (Params.Version() <= eEchoes)
|
||||||
|
@ -247,7 +298,7 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const
|
||||||
if (pParent && pParent->Type() == EPropertyTypeNew::Array)
|
if (pParent && pParent->Type() == EPropertyTypeNew::Array)
|
||||||
{
|
{
|
||||||
// For direct array sub-properties, display the element index after the name
|
// For direct array sub-properties, display the element index after the name
|
||||||
TString ElementName = pParent->Name();
|
TString ElementName = pProp->Name();
|
||||||
return QString("%1 %2").arg( TO_QSTRING(ElementName) ).arg(rkIndex.row() + 1);
|
return QString("%1 %2").arg( TO_QSTRING(ElementName) ).arg(rkIndex.row() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,12 +308,14 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const
|
||||||
|
|
||||||
if (rkIndex.column() == 1)
|
if (rkIndex.column() == 1)
|
||||||
{
|
{
|
||||||
|
void* pData = DataPointerForIndex(rkIndex);
|
||||||
|
|
||||||
switch (pProp->Type())
|
switch (pProp->Type())
|
||||||
{
|
{
|
||||||
// Enclose vector property text in parentheses
|
// Enclose vector property text in parentheses
|
||||||
case EPropertyTypeNew::Vector:
|
case EPropertyTypeNew::Vector:
|
||||||
{
|
{
|
||||||
CVector3f Value = TPropCast<CVectorProperty>(pProp)->Value(mpPropertyData);
|
CVector3f Value = TPropCast<CVectorProperty>(pProp)->Value(pData);
|
||||||
return TO_QSTRING("(" + Value.ToString() + ")");
|
return TO_QSTRING("(" + Value.ToString() + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,7 +323,7 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const
|
||||||
case EPropertyTypeNew::Sound:
|
case EPropertyTypeNew::Sound:
|
||||||
{
|
{
|
||||||
CSoundProperty* pSound = TPropCast<CSoundProperty>(pProp);
|
CSoundProperty* pSound = TPropCast<CSoundProperty>(pProp);
|
||||||
u32 SoundID = pSound->Value(mpPropertyData);
|
u32 SoundID = pSound->Value(pData);
|
||||||
if (SoundID == -1) return "[None]";
|
if (SoundID == -1) return "[None]";
|
||||||
|
|
||||||
SSoundInfo SoundInfo = mpProject->AudioManager()->GetSoundInfo(SoundID);
|
SSoundInfo SoundInfo = mpProject->AudioManager()->GetSoundInfo(SoundID);
|
||||||
|
@ -294,7 +347,7 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const
|
||||||
|
|
||||||
// Display character name for characters
|
// Display character name for characters
|
||||||
case EPropertyTypeNew::AnimationSet:
|
case EPropertyTypeNew::AnimationSet:
|
||||||
return TO_QSTRING(TPropCast<CAnimationSetProperty>(pProp)->Value(mpPropertyData).GetCurrentCharacterName());
|
return TO_QSTRING(TPropCast<CAnimationSetProperty>(pProp)->Value(pData).GetCurrentCharacterName());
|
||||||
|
|
||||||
// Display enumerator name for enums (but only on ToolTipRole)
|
// Display enumerator name for enums (but only on ToolTipRole)
|
||||||
case EPropertyTypeNew::Choice:
|
case EPropertyTypeNew::Choice:
|
||||||
|
@ -302,7 +355,7 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const
|
||||||
if (Role == Qt::ToolTipRole)
|
if (Role == Qt::ToolTipRole)
|
||||||
{
|
{
|
||||||
CEnumProperty *pEnum = TPropCast<CEnumProperty>(pProp);
|
CEnumProperty *pEnum = TPropCast<CEnumProperty>(pProp);
|
||||||
u32 ValueID = pEnum->Value(mpPropertyData);
|
u32 ValueID = pEnum->Value(pData);
|
||||||
u32 ValueIndex = pEnum->ValueIndex(ValueID);
|
u32 ValueIndex = pEnum->ValueIndex(ValueID);
|
||||||
return TO_QSTRING( pEnum->ValueName(ValueIndex) );
|
return TO_QSTRING( pEnum->ValueName(ValueIndex) );
|
||||||
}
|
}
|
||||||
|
@ -311,7 +364,7 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const
|
||||||
// Display the element count for arrays
|
// Display the element count for arrays
|
||||||
case EPropertyTypeNew::Array:
|
case EPropertyTypeNew::Array:
|
||||||
{
|
{
|
||||||
u32 Count = TPropCast<CArrayProperty>(pProp)->Value(mpPropertyData);
|
u32 Count = TPropCast<CArrayProperty>(pProp)->Value(pData);
|
||||||
return QString("%1 element%2").arg(Count).arg(Count != 1 ? "s" : "");
|
return QString("%1 element%2").arg(Count).arg(Count != 1 ? "s" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,7 +381,7 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const
|
||||||
// fall through
|
// fall through
|
||||||
// Display property value to string for everything else
|
// Display property value to string for everything else
|
||||||
default:
|
default:
|
||||||
return TO_QSTRING(pProp->ValueAsString(mpPropertyData) + pProp->Suffix());
|
return TO_QSTRING(pProp->ValueAsString(pData) + pProp->Suffix());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -341,7 +394,8 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const
|
||||||
// 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(pProp->HashableTypeName());
|
QString TypeName = pProp->HashableTypeName();
|
||||||
|
QString Text = QString("<b>%1</b> <i>(%2)</i>").arg(DisplayText).arg(TypeName);
|
||||||
|
|
||||||
// Add uncooked notification
|
// Add uncooked notification
|
||||||
if (pProp->CookPreference() == ECookPreferenceNew::Never)
|
if (pProp->CookPreference() == ECookPreferenceNew::Never)
|
||||||
|
@ -392,7 +446,7 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const
|
||||||
IPropertyNew *pProp = PropertyForIndex(rkIndex, true);
|
IPropertyNew *pProp = PropertyForIndex(rkIndex, true);
|
||||||
|
|
||||||
// Don't highlight the name of the root property
|
// Don't highlight the name of the root property
|
||||||
if (pProp && pProp->Parent() != nullptr && !pProp->IsArrayArchetype())
|
if (pProp && pProp->Parent() != nullptr)
|
||||||
{
|
{
|
||||||
static const QColor skRightColor = QColor(128, 255, 128);
|
static const QColor skRightColor = QColor(128, 255, 128);
|
||||||
static const QColor skWrongColor = QColor(255, 128, 128);
|
static const QColor skWrongColor = QColor(255, 128, 128);
|
||||||
|
@ -413,7 +467,7 @@ QModelIndex CPropertyModel::index(int Row, int Column, const QModelIndex& rkPare
|
||||||
// Check property for children
|
// Check property for children
|
||||||
IPropertyNew* pParent = (rkParent.isValid() ? PropertyForIndex(rkParent, false) : mpRootProperty);
|
IPropertyNew* pParent = (rkParent.isValid() ? PropertyForIndex(rkParent, false) : mpRootProperty);
|
||||||
EPropertyTypeNew ParentType = pParent->Type();
|
EPropertyTypeNew ParentType = pParent->Type();
|
||||||
int ParentID = mPropertyToIDMap[pParent];
|
int ParentID = rkParent.internalId();
|
||||||
|
|
||||||
if (ParentType == EPropertyTypeNew::Flags || ParentType == EPropertyTypeNew::AnimationSet)
|
if (ParentType == EPropertyTypeNew::Flags || ParentType == EPropertyTypeNew::AnimationSet)
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,6 +36,7 @@ public:
|
||||||
void ConfigureScript(CGameProject* pProject, IPropertyNew* pRootProperty, CScriptObject* pObject);
|
void ConfigureScript(CGameProject* pProject, IPropertyNew* pRootProperty, CScriptObject* pObject);
|
||||||
IPropertyNew* PropertyForIndex(const QModelIndex& rkIndex, bool HandleFlaggedIndices) const;
|
IPropertyNew* PropertyForIndex(const QModelIndex& rkIndex, bool HandleFlaggedIndices) const;
|
||||||
QModelIndex IndexForProperty(IPropertyNew *pProp) const;
|
QModelIndex IndexForProperty(IPropertyNew *pProp) const;
|
||||||
|
void* DataPointerForIndex(const QModelIndex& rkIndex) const;
|
||||||
|
|
||||||
int columnCount(const QModelIndex& rkParent) const;
|
int columnCount(const QModelIndex& rkParent) const;
|
||||||
int rowCount(const QModelIndex& rkParent) const;
|
int rowCount(const QModelIndex& rkParent) const;
|
||||||
|
@ -53,7 +54,6 @@ public:
|
||||||
|
|
||||||
inline void SetFont(QFont Font) { mFont = Font; }
|
inline void SetFont(QFont Font) { mFont = Font; }
|
||||||
inline void SetBoldModifiedProperties(bool Enable) { mBoldModifiedProperties = Enable; }
|
inline void SetBoldModifiedProperties(bool Enable) { mBoldModifiedProperties = Enable; }
|
||||||
inline void* GetPropertyData() const { return mpPropertyData; }
|
|
||||||
inline CScriptObject* GetScriptObject() const { return mpObject; }
|
inline CScriptObject* GetScriptObject() const { return mpObject; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
<default>0</default>
|
<default>0</default>
|
||||||
</property>
|
</property>
|
||||||
<array ID="0x01" name="Activation Times">
|
<array ID="0x01" name="Activation Times">
|
||||||
|
<element_name>Activation Time</element_name>
|
||||||
<properties>
|
<properties>
|
||||||
<property ID="0x00" name="Time" type="float">
|
<property ID="0x00" name="Time" type="float">
|
||||||
<default>0.0</default>
|
<default>0.0</default>
|
||||||
|
|
Loading…
Reference in New Issue