Added a bunch of new functionality to the property classes, set up property view to bold property names if the property has been modified from its default value

This commit is contained in:
parax0 2016-02-10 04:55:05 -07:00
parent d9b5895074
commit e13868921c
17 changed files with 1016 additions and 230 deletions

View File

@ -406,12 +406,12 @@ public:
if (Size() < str.Size()) return false;
_TString checkStr(caseSensitive ? *this : ToUpper());
if (!caseSensitive) str = str.ToUpper();
if (caseSensitive) str = str.ToUpper();
int latestPossibleStart = Size() - str.Size();
int match = 0;
u32 latestPossibleStart = Size() - str.Size();
u32 match = 0;
for (int iChr = 0; iChr < latestPossibleStart; iChr++)
for (u32 iChr = 0; iChr < Size() && iChr < str.Size(); iChr++)
{
// If the current character matches, increment match
if (checkStr.At(iChr) == str.At(match))
@ -426,6 +426,9 @@ public:
iChr--;
match = 0;
if (iChr > latestPossibleStart)
break;
}
// If we've matched the entire string, then we can return true

View File

@ -15,7 +15,7 @@ class CResourceInfo
public:
CResourceInfo()
: mPath(""), mIsPath(false), mIsValidPath(false) {}
: mPath("FFFFFFFFFFFFFFFF"), mIsPath(false), mIsValidPath(false) {}
CResourceInfo(const TString& rkPath)
: mPath(rkPath), mIsPath(true)

View File

@ -2,6 +2,19 @@
#include "IPropertyTemplate.h"
// ************ IProperty ************
bool IProperty::IsInArray() const
{
CPropertyStruct *pParent = mpParent;
while (pParent)
{
if (pParent->Type() == eArrayProperty) return true;
pParent = pParent->Parent();
}
return false;
}
CPropertyStruct* IProperty::RootStruct()
{
return (mpParent ? mpParent->RootStruct() : Type() == eStructProperty ? static_cast<CPropertyStruct*>(this) : nullptr);
@ -24,9 +37,18 @@ u32 IProperty::ID() const
TIDString IProperty::IDString(bool FullPath) const
{
// todo: since this function just returns the template ID string, it doesn't correctly account for array properties;
return mpTemplate->IDString(FullPath);
}
bool IProperty::MatchesDefault()
{
const IPropertyValue *pkValue = RawValue();
const IPropertyValue *pkDefault = mpTemplate->RawDefaultValue();
if (!pkValue || !pkDefault) return false;
else return pkValue->Matches(pkDefault);
}
// ************ CPropertyStruct ************
void CPropertyStruct::Copy(const IProperty *pkProp)
{

View File

@ -43,10 +43,12 @@ public:
virtual IPropertyValue* RawValue() { return nullptr; }
virtual void Copy(const IProperty *pkProp) = 0;
virtual IProperty* Clone(CPropertyStruct *pParent = 0) const = 0;
virtual bool Matches(const IProperty *pkProp) const = 0;
inline CPropertyStruct* Parent() const { return mpParent; }
inline void SetParent(CPropertyStruct *pParent) { mpParent = pParent; }
bool IsInArray() const;
CPropertyStruct* RootStruct();
// These functions can't be in the header to avoid circular includes with IPropertyTemplate.h
@ -54,6 +56,7 @@ public:
TString Name() const;
u32 ID() const;
TIDString IDString(bool FullPath) const;
virtual bool MatchesDefault();
};
/*
@ -68,8 +71,8 @@ public:
TTypedProperty(IPropertyTemplate *pTemp, CPropertyStruct *pParent)
: IProperty(pTemp, pParent) {}
TTypedProperty(IPropertyTemplate *pTemp, PropType v)
: IProperty(pTemp), mValue(v) {}
TTypedProperty(IPropertyTemplate *pTemp, CPropertyStruct *pParent, PropType v)
: IProperty(pTemp, pParent), mValue(v) {}
~TTypedProperty() {}
virtual EPropertyType Type() const { return TypeEnum; }
@ -93,6 +96,13 @@ public:
return pOut;
}
virtual bool Matches(const IProperty *pkProp) const
{
const TTypedProperty *pkTyped = static_cast<const TTypedProperty*>(pkProp);
return ( (Type() == pkTyped->Type()) &&
mValue.Matches(&pkTyped->mValue) );
}
inline PropType Get() const { return mValue.Get(); }
inline void Set(PropType v) { mValue.Set(v); }
};
@ -106,10 +116,41 @@ typedef TTypedProperty<float, eFloatProperty, CFloatValue>
typedef TTypedProperty<TString, eStringProperty, CStringValue> TStringProperty;
typedef TTypedProperty<CVector3f, eVector3Property, CVector3Value> TVector3Property;
typedef TTypedProperty<CColor, eColorProperty, CColorValue> TColorProperty;
typedef TTypedProperty<CResourceInfo, eFileProperty, CFileValue> TFileProperty;
typedef TTypedProperty<CAnimationParameters, eCharacterProperty, CCharacterValue> TCharacterProperty;
typedef TTypedProperty<std::vector<u8>, eUnknownProperty, CUnknownValue> TUnknownProperty;
/*
* TFileProperty and TCharacterProperty get little subclasses in order to override MatchesDefault.
*/
class TFileProperty : public TTypedProperty<CResourceInfo, eFileProperty, CFileValue>
{
public:
TFileProperty(IPropertyTemplate *pTemp, CPropertyStruct *pParent)
: TTypedProperty(pTemp, pParent) {}
TFileProperty(IPropertyTemplate *pTemp, CPropertyStruct *pParent, CResourceInfo v)
: TTypedProperty(pTemp, pParent, v) {}
virtual bool MatchesDefault()
{
return !Get().IsValid();
}
};
class TCharacterProperty : public TTypedProperty<CAnimationParameters, eCharacterProperty, CCharacterValue>
{
public:
TCharacterProperty(IPropertyTemplate *pTemp, CPropertyStruct *pParent)
: TTypedProperty(pTemp, pParent) {}
TCharacterProperty(IPropertyTemplate *pTemp, CPropertyStruct *pParent, CAnimationParameters v)
: TTypedProperty(pTemp, pParent, v) {}
virtual bool MatchesDefault()
{
return Get().AnimSet() == nullptr;
}
};
/*
* CPropertyStruct is for defining structs of properties.
*/
@ -140,6 +181,36 @@ public:
return pOut;
}
virtual bool Matches(const IProperty *pkProp) const
{
const CPropertyStruct *pkStruct = static_cast<const CPropertyStruct*>(pkProp);
if ( (Type() == pkStruct->Type()) &&
(mProperties.size() == pkStruct->mProperties.size()) )
{
for (u32 iProp = 0; iProp < mProperties.size(); iProp++)
{
if (!mProperties[iProp]->Matches(pkStruct->mProperties[iProp]))
return false;
}
return true;
}
return false;
}
virtual bool MatchesDefault()
{
for (u32 iProp = 0; iProp < mProperties.size(); iProp++)
{
if (!mProperties[iProp]->MatchesDefault())
return false;
}
return true;
}
// Inline
inline u32 Count() const { return mProperties.size(); }
inline void AddSubProperty(IProperty *pProp) { mProperties.push_back(pProp); }
@ -176,6 +247,8 @@ public:
return pOut;
}
virtual bool MatchesDefault() { return mProperties.empty(); }
// Inline
inline void Reserve(u32 amount) { mProperties.reserve(amount); }

View File

@ -57,11 +57,34 @@ public:
virtual EPropertyType Type() const = 0;
virtual bool CanHaveDefault() const = 0;
virtual bool IsNumerical() const = 0;
virtual IProperty* InstantiateProperty(CPropertyStruct *pParent) = 0;
virtual IPropertyTemplate* Clone(CStructTemplate *pParent = 0) const = 0;
virtual bool HasValidRange() const { return false; }
virtual TString DefaultToString() const { return ""; }
virtual TString RangeToString() const { return ""; }
virtual TString Suffix() const { return ""; }
virtual void Copy(const IPropertyTemplate *pkTemp)
{
mName = pkTemp->mName;
mDescription = pkTemp->mDescription;
mID = pkTemp->mID;
mCookPreference = pkTemp->mCookPreference;
mAllowedVersions = pkTemp->mAllowedVersions;
}
virtual bool Matches(const IPropertyTemplate *pkTemp) const
{
return ( (pkTemp != nullptr) &&
(mName == pkTemp->mName) &&
(mDescription == pkTemp->mDescription) &&
(mID == pkTemp->mID) &&
(mCookPreference == pkTemp->mCookPreference) &&
(mAllowedVersions == pkTemp->mAllowedVersions) &&
(Type() == pkTemp->Type()) );
}
virtual TString DefaultToString() const { return ""; }
virtual const IPropertyValue* RawDefaultValue() const { return nullptr; }
virtual bool HasValidRange() const { return false; }
virtual TString RangeToString() const { return ""; }
virtual TString Suffix() const { return ""; }
virtual void SetParam(const TString& rkParamName, const TString& rkValue)
{
@ -81,48 +104,30 @@ public:
mDescription = rkValue;
}
virtual IProperty* InstantiateProperty(CPropertyStruct *pParent) = 0;
inline TString Name() const
{
return mName;
}
inline TString Description() const
{
return mDescription;
}
inline u32 PropertyID() const
{
return mID;
}
inline ECookPreference CookPreference() const
{
return mCookPreference;
}
inline void SetName(const TString& rkName)
{
mName = rkName;
}
inline void SetDescription(const TString& rkDesc)
{
mDescription = rkDesc;
}
inline CStructTemplate* Parent() const
{
return mpParent;
}
bool IsInVersion(u32 Version) const;
TIDString IDString(bool FullPath) const;
CStructTemplate* RootStruct();
// Inline Accessors
inline TString Name() const { return mName; }
inline TString Description() const { return mDescription; }
inline u32 PropertyID() const { return mID; }
inline ECookPreference CookPreference() const { return mCookPreference; }
inline CStructTemplate* Parent() const { return mpParent; }
inline void SetName(const TString& rkName) { mName = rkName; }
inline void SetDescription(const TString& rkDesc) { mDescription = rkDesc; }
};
// Macro for defining reimplementations of IPropertyTemplate::Clone(), which are usually identical to each other aside from the class being instantiated
#define DEFINE_TEMPLATE_CLONE(ClassName) \
virtual IPropertyTemplate* Clone(CStructTemplate *pParent = 0) const \
{ \
if (!pParent) pParent = mpParent; \
ClassName *pTemp = new ClassName(mID, pParent); \
pTemp->Copy(this); \
return pTemp; \
}
// TTypedPropertyTemplate - Template property class that allows for tracking
// a default value. Typedefs are set up for a bunch of property types.
template<typename PropType, EPropertyType PropTypeEnum, class ValueClass>
@ -145,11 +150,41 @@ public:
virtual bool CanHaveDefault() const { return true; }
virtual bool IsNumerical() const { return false; }
virtual IProperty* InstantiateProperty(CPropertyStruct *pParent)
{
typedef TTypedProperty<PropType, PropTypeEnum, ValueClass> TPropertyType;
TPropertyType *pOut = new TPropertyType(this, pParent);
pOut->Set(GetDefaultValue());
return pOut;
}
DEFINE_TEMPLATE_CLONE(TTypedPropertyTemplate)
virtual void Copy(const IPropertyTemplate *pkTemp)
{
IPropertyTemplate::Copy(pkTemp);
mDefaultValue.Copy(&static_cast<const TTypedPropertyTemplate*>(pkTemp)->mDefaultValue);
}
virtual bool Matches(const IPropertyTemplate *pkTemp) const
{
const TTypedPropertyTemplate *pkTyped = static_cast<const TTypedPropertyTemplate*>(pkTemp);
return ( (IPropertyTemplate::Matches(pkTemp)) &&
(mDefaultValue.Matches(&pkTyped->mDefaultValue)) );
}
virtual TString DefaultToString() const
{
return mDefaultValue.ToString();
}
virtual const IPropertyValue* RawDefaultValue() const
{
return &mDefaultValue;
}
virtual void SetParam(const TString& rkParamName, const TString& rkValue)
{
IPropertyTemplate::SetParam(rkParamName, rkValue);
@ -158,24 +193,8 @@ public:
mDefaultValue.FromString(rkValue.ToLower());
}
virtual IProperty* InstantiateProperty(CPropertyStruct *pParent)
{
typedef TTypedProperty<PropType, PropTypeEnum, ValueClass> TPropertyType;
TPropertyType *pOut = new TPropertyType(this, pParent);
pOut->Set(GetDefaultValue());
return pOut;
}
inline PropType GetDefaultValue() const
{
return mDefaultValue.Get();
}
inline void SetDefaultValue(const PropType& rkIn)
{
mDefaultValue.Set(rkIn);
}
inline PropType GetDefaultValue() const { return mDefaultValue.Get(); }
inline void SetDefaultValue(const PropType& rkIn) { mDefaultValue.Set(rkIn); }
};
// TNumericalPropertyTemplate - Subclass of TTypedPropertyTemplate for numerical
@ -201,11 +220,29 @@ public:
, mMax(0)
{}
virtual bool IsNumerical() const { return true; }
virtual bool IsNumerical() const { return true; }
virtual bool HasValidRange() const { return (mMin != 0 || mMax != 0); }
virtual bool HasValidRange() const
DEFINE_TEMPLATE_CLONE(TNumericalPropertyTemplate)
virtual void Copy(const IPropertyTemplate *pkTemp)
{
return (mMin != 0 || mMax != 0);
TTypedPropertyTemplate::Copy(pkTemp);
const TNumericalPropertyTemplate *pkNumerical = static_cast<const TNumericalPropertyTemplate*>(pkTemp);
mMin.Copy(&pkNumerical->mMin);
mMax.Copy(&pkNumerical->mMax);
mSuffix = pkNumerical->mSuffix;
}
virtual bool Matches(const IPropertyTemplate *pkTemp) const
{
const TNumericalPropertyTemplate *pkNumerical = static_cast<const TNumericalPropertyTemplate*>(pkTemp);
return ( (TTypedPropertyTemplate::Matches(pkTemp)) &&
(mMin.Matches(&pkNumerical->mMin)) &&
(mMax.Matches(&pkNumerical->mMax)) &&
(mSuffix == pkNumerical->mSuffix) );
}
virtual TString RangeToString() const
@ -234,20 +271,9 @@ public:
}
}
virtual TString Suffix() const
{
return mSuffix;
}
inline PropType GetMin() const
{
return mMin.Get();
}
inline PropType GetMax() const
{
return mMax.Get();
}
virtual TString Suffix() const { return mSuffix; }
inline PropType GetMin() const { return mMin.Get(); }
inline PropType GetMax() const { return mMax.Get(); }
inline void SetRange(const PropType& rkMin, const PropType& rkMax)
{
@ -295,9 +321,20 @@ public:
return new TFileProperty(this, pParent);
}
void SetAllowedExtensions(const TStringList& rkExtensions)
DEFINE_TEMPLATE_CLONE(CFileTemplate)
virtual void Copy(const IPropertyTemplate *pkTemp)
{
mAcceptedExtensions = rkExtensions;
IPropertyTemplate::Copy(pkTemp);
mAcceptedExtensions = static_cast<const CFileTemplate*>(pkTemp)->mAcceptedExtensions;
}
virtual bool Matches(const IPropertyTemplate *pkTemp) const
{
const CFileTemplate *pkFile = static_cast<const CFileTemplate*>(pkTemp);
return ( (IPropertyTemplate::Matches(pkTemp)) &&
(mAcceptedExtensions == pkFile->mAcceptedExtensions) );
}
bool AcceptsExtension(const TString& rkExtension)
@ -307,10 +344,8 @@ public:
return false;
}
const TStringList& Extensions() const
{
return mAcceptedExtensions;
}
void SetAllowedExtensions(const TStringList& rkExtensions) { mAcceptedExtensions = rkExtensions; }
const TStringList& Extensions() const { return mAcceptedExtensions; }
};
// CCharacterTemplate - Typed property that doesn't allow default values.
@ -332,6 +367,13 @@ public:
{
return false;
}
IProperty* InstantiateProperty(CPropertyStruct *pParent)
{
return new TCharacterProperty(this, pParent);
}
DEFINE_TEMPLATE_CLONE(CCharacterTemplate)
};
// CEnumTemplate - Property template for enums. Tracks a list of possible values (enumerators).
@ -347,6 +389,11 @@ class CEnumTemplate : public TLongTemplate
SEnumerator(const TString& rkName, u32 _ID)
: Name(rkName), ID(_ID) {}
bool operator==(const SEnumerator& rkOther) const
{
return ( (Name == rkOther.Name) && (ID == rkOther.ID) );
}
};
std::vector<SEnumerator> mEnumerators;
TString mSourceFile;
@ -374,12 +421,32 @@ public:
return pEnum;
}
u32 NumEnumerators()
DEFINE_TEMPLATE_CLONE(CEnumTemplate)
virtual void Copy(const IPropertyTemplate *pkTemp)
{
TLongTemplate::Copy(pkTemp);
const CEnumTemplate *pkEnum = static_cast<const CEnumTemplate*>(pkTemp);
mEnumerators = pkEnum->mEnumerators;
mSourceFile = pkEnum->mSourceFile;
}
virtual bool Matches(const IPropertyTemplate *pkTemp) const
{
const CEnumTemplate *pkEnum = static_cast<const CEnumTemplate*>(pkTemp);
return ( (TLongTemplate::Matches(pkTemp)) &&
(mEnumerators == pkEnum->mEnumerators) &&
(mSourceFile == pkEnum->mSourceFile) );
}
inline u32 NumEnumerators() const
{
return mEnumerators.size();
}
u32 EnumeratorIndex(u32 enumID)
u32 EnumeratorIndex(u32 enumID) const
{
for (u32 iEnum = 0; iEnum < mEnumerators.size(); iEnum++)
{
@ -389,7 +456,7 @@ public:
return -1;
}
u32 EnumeratorID(u32 enumIndex)
u32 EnumeratorID(u32 enumIndex) const
{
if (mEnumerators.size() > enumIndex)
return mEnumerators[enumIndex].ID;
@ -397,7 +464,7 @@ public:
else return -1;
}
TString EnumeratorName(u32 enumIndex)
TString EnumeratorName(u32 enumIndex) const
{
if (mEnumerators.size() > enumIndex)
return mEnumerators[enumIndex].Name;
@ -420,6 +487,11 @@ class CBitfieldTemplate : public TTypedPropertyTemplate<u32, eBitfieldProperty,
SBitFlag(const TString& _name, u32 _mask)
: Name(_name), Mask(_mask) {}
bool operator==(const SBitFlag& rkOther) const
{
return ( (Name == rkOther.Name) && (Mask == rkOther.Mask) );
}
};
std::vector<SBitFlag> mBitFlags;
TString mSourceFile;
@ -446,20 +518,29 @@ public:
return pBitfield;
}
u32 NumFlags()
DEFINE_TEMPLATE_CLONE(CBitfieldTemplate)
virtual void Copy(const IPropertyTemplate *pkTemp)
{
return mBitFlags.size();
TTypedPropertyTemplate::Copy(pkTemp);
const CBitfieldTemplate *pkBitfield = static_cast<const CBitfieldTemplate*>(pkTemp);
mBitFlags = pkBitfield->mBitFlags;
mSourceFile = pkBitfield->mSourceFile;
}
TString FlagName(u32 index)
virtual bool Matches(const IPropertyTemplate *pkTemp) const
{
return mBitFlags[index].Name;
const CBitfieldTemplate *pkBitfield = static_cast<const CBitfieldTemplate*>(pkTemp);
return ( (TTypedPropertyTemplate::Matches(pkTemp)) &&
(mBitFlags == pkBitfield->mBitFlags) &&
(mSourceFile == pkBitfield->mSourceFile) );
}
u32 FlagMask(u32 index)
{
return mBitFlags[index].Mask;
}
u32 NumFlags() const { return mBitFlags.size(); }
TString FlagName(u32 index) const { return mBitFlags[index].Name; }
u32 FlagMask(u32 index) const { return mBitFlags[index].Mask; }
};
// CStructTemplate - Defines structs composed of multiple sub-properties.
@ -507,6 +588,45 @@ public:
return pStruct;
}
DEFINE_TEMPLATE_CLONE(CStructTemplate)
virtual void Copy(const IPropertyTemplate *pkTemp)
{
IPropertyTemplate::Copy(pkTemp);
const CStructTemplate *pkStruct = static_cast<const CStructTemplate*>(pkTemp);
mVersionPropertyCounts = pkStruct->mVersionPropertyCounts;
mIsSingleProperty = pkStruct->mIsSingleProperty;
mSourceFile = pkStruct->mSourceFile;
mSubProperties.resize(pkStruct->mSubProperties.size());
for (u32 iSub = 0; iSub < pkStruct->mSubProperties.size(); iSub++)
mSubProperties[iSub] = pkStruct->mSubProperties[iSub]->Clone(this);
}
virtual bool Matches(const IPropertyTemplate *pkTemp) const
{
const CStructTemplate *pkStruct = static_cast<const CStructTemplate*>(pkTemp);
if ( (IPropertyTemplate::Matches(pkTemp)) &&
(mVersionPropertyCounts == pkStruct->mVersionPropertyCounts) &&
(mIsSingleProperty == pkStruct->mIsSingleProperty) &&
(mSourceFile == pkStruct->mSourceFile) &&
(mSubProperties.size() == pkStruct->mSubProperties.size()) )
{
for (u32 iSub = 0; iSub < mSubProperties.size(); iSub++)
{
if (!mSubProperties[iSub]->Matches(pkStruct->mSubProperties[iSub]))
return false;
}
return true;
}
return false;
}
bool IsSingleProperty() const;
u32 Count() const;
u32 NumVersions();
@ -545,6 +665,27 @@ public:
EPropertyType Type() const { return eArrayProperty; }
IProperty* InstantiateProperty(CPropertyStruct *pParent)
{
return new CArrayProperty(this, pParent);
}
DEFINE_TEMPLATE_CLONE(CArrayTemplate)
virtual void Copy(const IPropertyTemplate *pkTemp)
{
CStructTemplate::Copy(pkTemp);
mElementName = static_cast<const CArrayTemplate*>(pkTemp)->mElementName;
}
virtual bool Matches(const IPropertyTemplate *pkTemp) const
{
const CArrayTemplate *pkArray = static_cast<const CArrayTemplate*>(pkTemp);
return ( (mElementName == pkArray->mElementName) &
(CStructTemplate::Matches(pkTemp)) );
}
void SetParam(const TString& rkParamName, const TString& rkValue)
{
if (rkParamName == "element_name")
@ -553,11 +694,6 @@ public:
CStructTemplate::SetParam(rkParamName, rkValue);
}
IProperty* InstantiateProperty(CPropertyStruct *pParent)
{
return new CArrayProperty(this, pParent);
}
TString ElementName() const { return mElementName; }
void SetElementName(const TString& rkName) { mElementName = rkName; }

View File

@ -18,8 +18,8 @@ public:
virtual TString ToString() const = 0;
virtual void FromString(const TString& rkString) = 0;
virtual IPropertyValue* Clone() const = 0;
virtual void Copy(IPropertyValue *pValue) = 0;
virtual bool Matches(IPropertyValue *pValue) const = 0;
virtual void Copy(const IPropertyValue *pkValue) = 0;
virtual bool Matches(const IPropertyValue *pkValue) const = 0;
};
template<typename PropType>
@ -34,16 +34,16 @@ public:
TTypedPropertyValue(PropType rkVal)
: mValue(rkVal) {}
virtual void Copy(IPropertyValue *pValue)
virtual void Copy(const IPropertyValue *pkValue)
{
TTypedPropertyValue *pOther = static_cast<TTypedPropertyValue*>(pValue);
mValue = pOther->mValue;
const TTypedPropertyValue *pkOther = static_cast<const TTypedPropertyValue*>(pkValue);
mValue = pkOther->mValue;
}
virtual bool Matches(IPropertyValue *pValue) const
virtual bool Matches(const IPropertyValue *pkValue) const
{
TTypedPropertyValue *pOther = static_cast<TTypedPropertyValue*>(pValue);
return (mValue == pOther->mValue);
const TTypedPropertyValue *pkOther = static_cast<const TTypedPropertyValue*>(pkValue);
return ((pkValue != nullptr) && (mValue == pkOther->mValue));
}
PropType Get() const

View File

@ -2,11 +2,13 @@
#include "Editor/UICommon.h"
#include <Core/Resource/Script/IProperty.h>
#include <Core/Resource/Script/IPropertyTemplate.h>
#include <QFont>
#include <QSize>
CPropertyModel::CPropertyModel(QObject *pParent /*= 0*/)
: QAbstractItemModel(pParent)
, mpBaseStruct(nullptr)
, mBoldModifiedProperties(true)
{
}
@ -344,6 +346,58 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const
}
}
if (Role == Qt::FontRole && rkIndex.column() == 0)
{
QFont Font = mFont;
bool Bold = false;
if (mBoldModifiedProperties)
{
IProperty *pProp = PropertyForIndex(rkIndex, true);
if (!pProp->IsInArray())
{
if (rkIndex.internalId() & 0x1)
{
if (pProp->Type() == eVector3Property)
{
TVector3Property *pVec = static_cast<TVector3Property*>(pProp);
TVector3Template *pTemp = static_cast<TVector3Template*>(pProp->Template());
CVector3f Value = pVec->Get();
CVector3f Default = pTemp->GetDefaultValue();
if (rkIndex.row() == 0) Bold = (Value.x != Default.x);
if (rkIndex.row() == 1) Bold = (Value.y != Default.y);
if (rkIndex.row() == 2) Bold = (Value.z != Default.z);
}
else if (pProp->Type() == eColorProperty)
{
TColorProperty *pColor = static_cast<TColorProperty*>(pProp);
TColorTemplate *pTemp = static_cast<TColorTemplate*>(pProp->Template());
CColor Value = pColor->Get();
CColor Default = pTemp->GetDefaultValue();
if (rkIndex.row() == 0) Bold = (Value.r != Default.r);
if (rkIndex.row() == 1) Bold = (Value.g != Default.g);
if (rkIndex.row() == 2) Bold = (Value.b != Default.b);
if (rkIndex.row() == 3) Bold = (Value.a != Default.a);
}
}
else
{
Bold = !pProp->MatchesDefault();
}
}
}
Font.setBold(Bold);
return Font;
}
if (Role == Qt::SizeHintRole)
{
return QSize(0, 23);
@ -443,17 +497,19 @@ void CPropertyModel::NotifyPropertyModified(IProperty *pProp)
void CPropertyModel::NotifyPropertyModified(const QModelIndex& rkIndex)
{
if (rowCount(rkIndex) != 0)
emit dataChanged( index(0, 1, rkIndex), index(rowCount(rkIndex) - 1, 1, rkIndex));
emit dataChanged( index(0, 0, rkIndex), index(rowCount(rkIndex) - 1, 1, rkIndex));
if (rkIndex.internalId() & 0x1)
{
QModelIndex Parent = rkIndex.parent();
Parent = Parent.sibling(Parent.row(), 1);
emit dataChanged(Parent, Parent);
QModelIndex Col0 = Parent.sibling(Parent.row(), 0);
QModelIndex Col1 = Parent.sibling(Parent.row(), 1);
emit dataChanged(Col0, Col1);
}
QModelIndex IndexC1 = rkIndex.sibling(rkIndex.row(), 1);
emit dataChanged(IndexC1, IndexC1);
QModelIndex IndexCol0 = rkIndex.sibling(rkIndex.row(), 0);
QModelIndex IndexCol1 = rkIndex.sibling(rkIndex.row(), 1);
emit dataChanged(IndexCol0, IndexCol1);
emit PropertyModified(rkIndex);
}

View File

@ -3,12 +3,15 @@
#include <QAbstractItemModel>
#include <Core/Resource/Script/IProperty.h>
#include <QFont>
class CPropertyModel : public QAbstractItemModel
{
Q_OBJECT
CPropertyStruct *mpBaseStruct;
bool mBoldModifiedProperties;
QFont mFont;
public:
CPropertyModel(QObject *pParent = 0);
@ -28,6 +31,9 @@ public:
void ArrayResized(const QModelIndex& rkIndex, u32 OldSize);
void ResizeArray(const QModelIndex& rkIndex, u32 NewSize);
inline void SetFont(QFont Font) { mFont = Font; }
inline void SetBoldModifiedProperties(bool Enable) { mBoldModifiedProperties = Enable; }
public slots:
void NotifyPropertyModified(IProperty *pProp);
void NotifyPropertyModified(const QModelIndex& rkIndex);

View File

@ -7,6 +7,7 @@
CPropertyView::CPropertyView(QWidget *pParent)
: QTreeView(pParent)
, mpEditor(nullptr)
{
mpModel = new CPropertyModel(this);
mpDelegate = new CPropertyDelegate(this);
@ -72,6 +73,7 @@ void CPropertyView::SetEditor(CWorldEditor *pEditor)
void CPropertyView::SetInstance(CScriptObject *pObj)
{
mpObject = pObj;
mpModel->SetBoldModifiedProperties(mpEditor ? (mpEditor->CurrentGame() > ePrime) : true);
mpModel->SetBaseStruct(pObj ? pObj->Properties() : nullptr);
SetPersistentEditors(QModelIndex());

View File

@ -115,8 +115,11 @@ void WResourceSelector::UpdateFrameColor()
{
TString Name = mResource.ToString().GetFileName(false);
if (!Name.IsHexString() || (Name.Size() != 8 && Name.Size() != 16) || mResource.ID().IsValid())
RedFrame = true;
if (!Name.IsEmpty())
{
if (!Name.IsHexString() || (Name.Size() != 8 && Name.Size() != 16) || mResource.ID().IsValid())
RedFrame = true;
}
}
mUI.LineEdit->setStyleSheet(RedFrame ? "border: 1px solid red" : "");
mUI.LineEdit->setFont(font());
@ -187,12 +190,13 @@ void WResourceSelector::SetResource(const CResourceInfo& rkRes)
else
mResourceValid = false;
mUI.LineEdit->setText(TO_QSTRING(mResource.ToString()));
TString ResStr = mResource.ToString();
if (ResStr.Contains("FFFFFFFF", false)) mUI.LineEdit->clear();
else mUI.LineEdit->setText(TO_QSTRING(ResStr));
UpdateFrameColor();
CreatePreviewPanel();
SetButtonsBasedOnResType();
Q_ASSERT(!mUI.LineEdit->text().isEmpty());
emit ResourceChanged(TO_QSTRING(mResource.ToString()));
}
}

View File

@ -46,7 +46,7 @@ public:
bool CheckUnsavedChanges();
inline CGameArea* ActiveArea() const { return mpArea; }
inline EGame CurrentGame() const { return mpArea->Version(); }
inline EGame CurrentGame() const { return mpArea ? mpArea->Version() : eUnknownVersion; }
public slots:
bool Save();

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<struct name="Transform" type="single">
<properties>
<property ID="0x00" name="Position" type="vector3f"/>
<property ID="0x01" name="Rotation" type="vector3f"/>
<property ID="0x02" name="Scale" type="vector3f"/>
<property ID="0x00" name="Position" type="vector3f">
<default>0,0,0</default>
</property>
<property ID="0x01" name="Rotation" type="vector3f">
<default>0,0,0</default>
</property>
<property ID="0x02" name="Scale" type="vector3f">
<default>1,1,1</default>
</property>
</properties>
</struct>

View File

@ -1,8 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<struct name="Transform" type="single">
<properties>
<property ID="0x00" name="Position" type="vector3f"/>
<property ID="0x01" name="Rotation" type="vector3f"/>
<property ID="0x02" name="Scale" type="vector3f"/>
<property ID="0x00" name="Position" type="vector3f">
<default>0,0,0</default>
</property>
<property ID="0x01" name="Rotation" type="vector3f">
<default>0,0,0</default>
</property>
<property ID="0x02" name="Scale" type="vector3f">
<default>1,1,1</default>
</property>
</properties>
</struct>

View File

@ -1,8 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<struct name="Transform" type="single">
<properties>
<property ID="0x00" name="Position" type="vector3f"/>
<property ID="0x01" name="Rotation" type="vector3f"/>
<property ID="0x02" name="Scale" type="vector3f"/>
<property ID="0x00" name="Position" type="vector3f">
<default>0,0,0</default>
</property>
<property ID="0x01" name="Rotation" type="vector3f">
<default>0,0,0</default>
</property>
<property ID="0x02" name="Scale" type="vector3f">
<default>1,1,1</default>
</property>
</properties>
</struct>

View File

@ -1,8 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<struct name="Transform" type="single">
<properties>
<property ID="0x00" name="Position" type="vector3f"/>
<property ID="0x01" name="Rotation" type="vector3f"/>
<property ID="0x02" name="Scale" type="vector3f"/>
<property ID="0x00" name="Position" type="vector3f">
<default>0,0,0</default>
</property>
<property ID="0x01" name="Rotation" type="vector3f">
<default>0,0,0</default>
</property>
<property ID="0x02" name="Scale" type="vector3f">
<default>1,1,1</default>
</property>
</properties>
</struct>

View File

@ -1,8 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<struct name="Transform" type="single">
<properties>
<property ID="0x00" name="Position" type="vector3f"/>
<property ID="0x01" name="Rotation" type="vector3f"/>
<property ID="0x02" name="Scale" type="vector3f"/>
<property ID="0x00" name="Position" type="vector3f">
<default>0,0,0</default>
</property>
<property ID="0x01" name="Rotation" type="vector3f">
<default>0,0,0</default>
</property>
<property ID="0x02" name="Scale" type="vector3f">
<default>1,1,1</default>
</property>
</properties>
</struct>