#ifndef TPROPERTY_INCLUDED #define TPROPERTY_INCLUDED #include "tconvert.h" #undef DVAPI #undef DVVAR #ifdef TNZCORE_EXPORTS #define DVAPI DV_EXPORT_API #define DVVAR DV_EXPORT_VAR #else #define DVAPI DV_IMPORT_API #define DVVAR DV_IMPORT_VAR #endif #ifdef WIN32 #pragma warning(push) #pragma warning(disable : 4251) #endif template class TRangeProperty; typedef TRangeProperty TIntProperty; typedef TRangeProperty TDoubleProperty; class DVAPI TBoolProperty; class DVAPI TStringProperty; class DVAPI TEnumProperty; class DVAPI TDoublePairProperty; class DVAPI TIntPairProperty; class DVAPI TStyleIndexProperty; class DVAPI TPointerProperty; class TIStream; class TOStream; //--------------------------------------------------------- class DVAPI TProperty { public: class Visitor { public: virtual void visit(TDoubleProperty *p) = 0; virtual void visit(TIntProperty *p) = 0; virtual void visit(TBoolProperty *p) = 0; virtual void visit(TStringProperty *p) = 0; virtual void visit(TEnumProperty *p) = 0; virtual void visit(TDoublePairProperty *p) = 0; virtual void visit(TIntPairProperty *p) = 0; virtual void visit(TStyleIndexProperty *p) = 0; virtual void visit(TPointerProperty *p) = 0; virtual ~Visitor() {} }; class Listener { public: virtual void onPropertyChanged() = 0; virtual ~Listener() {} }; // eccezioni class TypeError { }; class RangeError { }; TProperty(string name) : m_name(name) { m_qstringName = QString::fromStdString(name); } virtual ~TProperty() {} virtual TProperty *clone() const = 0; // Used only for translation in Qt QString getQStringName() const { return m_qstringName; } void setQStringName(const QString &str) { m_qstringName = str; } string getName() const { return m_name; } virtual string getValueAsString() = 0; virtual void accept(Visitor &v) = 0; void addListener(Listener *listener); void removeListener(Listener *listener); void notifyListeners() const; string getId() const { return m_id; } void setId(string id) { m_id = id; } private: string m_name; QString m_qstringName; string m_id; std::vector m_listeners; }; //--------------------------------------------------------- template class TRangeProperty : public TProperty { public: typedef std::pair Range; TRangeProperty( string name, T minValue, T maxValue, T value, bool isMaxRangeLimited = true) : TProperty(name), m_range(minValue, maxValue), m_value(minValue), m_isMaxRangeLimited(isMaxRangeLimited) { setValue(value); } TProperty *clone() const { return new TRangeProperty(*this); } Range getRange() const { return m_range; } void setValue(T v, bool cropEnabled = false) { if (cropEnabled && m_isMaxRangeLimited) v = tcrop(v, m_range.first, m_range.second); if (cropEnabled && !m_isMaxRangeLimited) v = v < m_range.first ? m_range.first : v; if (v < m_range.first || (v > m_range.second && m_isMaxRangeLimited)) throw RangeError(); m_value = v; } T getValue() const { return m_value; } string getValueAsString() { return toString(m_value); } void accept(Visitor &v) { v.visit(this); } bool isMaxRangeLimited() const { return m_isMaxRangeLimited; } private: Range m_range; T m_value; bool m_isMaxRangeLimited; }; //--------------------------------------------------------- #ifdef WIN32 template class DVAPI TRangeProperty; template class DVAPI TRangeProperty; #endif //--------------------------------------------------------- class TDoublePairProperty : public TProperty { public: typedef std::pair Range; typedef std::pair Value; TDoublePairProperty( string name, double minValue, double maxValue, double v0, double v1, bool isMaxRangeLimited = true) : TProperty(name), m_range(Range(minValue, maxValue)), m_isMaxRangeLimited(isMaxRangeLimited) { setValue(Value(v0, v1)); } TProperty *clone() const { return new TDoublePairProperty(*this); } Range getRange() const { return m_range; } bool isMaxRangeLimited() const { return m_isMaxRangeLimited; } void setValue(const Value &value) { if (value.first < m_range.first || (m_isMaxRangeLimited && value.first > m_range.second) || value.second < m_range.first || (m_isMaxRangeLimited && value.second > m_range.second)) throw RangeError(); m_value = value; } Value getValue() const { return m_value; } string getValueAsString() { return toString(m_value.first) + "," + toString(m_value.second); } void accept(Visitor &v) { v.visit(this); }; private: Range m_range; Value m_value; bool m_isMaxRangeLimited; }; //--------------------------------------------------------- class TIntPairProperty : public TProperty { public: typedef std::pair Range; typedef std::pair Value; TIntPairProperty( string name, int minValue, int maxValue, int v0, int v1, bool isMaxRangeLimited = true) : TProperty(name), m_range(minValue, maxValue), m_isMaxRangeLimited(isMaxRangeLimited) { setValue(Value(v0, v1)); } TProperty *clone() const { return new TIntPairProperty(*this); } Range getRange() const { return m_range; } bool isMaxRangeLimited() const { return m_isMaxRangeLimited; } void setValue(const Value &value) { if (value.first < m_range.first || (m_isMaxRangeLimited && value.first > m_range.second) || value.second < m_range.first || (m_isMaxRangeLimited && value.second > m_range.second)) throw RangeError(); m_value = value; } Value getValue() const { return m_value; } string getValueAsString() { return toString(m_value.first) + "," + toString(m_value.second); } void accept(Visitor &v) { v.visit(this); }; private: Range m_range; Value m_value; bool m_isMaxRangeLimited; }; //--------------------------------------------------------- class DVAPI TBoolProperty : public TProperty { public: TBoolProperty(string name, bool value) : TProperty(name), m_value(value) { } TProperty *clone() const { return new TBoolProperty(*this); } void setValue(bool v) { m_value = v; } bool getValue() const { return m_value; } string getValueAsString() { return toString(m_value); } void accept(Visitor &v) { v.visit(this); }; private: bool m_value; }; //--------------------------------------------------------- class DVAPI TStringProperty : public TProperty { public: TStringProperty(string name, wstring value) : TProperty(name), m_value(value) { } TProperty *clone() const { return new TStringProperty(*this); } void setValue(wstring v) { m_value = v; } wstring getValue() const { return m_value; } string getValueAsString() { return toString(m_value); } void accept(Visitor &v) { v.visit(this); }; private: wstring m_value; }; //--------------------------------------------------------- class DVAPI TStyleIndexProperty : public TProperty { public: TStyleIndexProperty(string name, wstring value) : TProperty(name), m_value(value) { } TProperty *clone() const { return new TStyleIndexProperty(*this); } void setValue(wstring v) { m_value = v; } wstring getValue() const { return m_value; } string getValueAsString() { return toString(m_value); } void accept(Visitor &v) { v.visit(this); }; private: wstring m_value; }; //------------------------------------------------------------------ class DVAPI TPointerProperty : public TProperty { public: TPointerProperty(string name, void *value) : TProperty(name), m_value(value) { } TProperty *clone() const { return new TPointerProperty(*this); } void setValue(void *v) { m_value = v; } void *getValue() const { return m_value; } string getValueAsString() { return toString((unsigned long long)m_value); } void accept(Visitor &v) { v.visit(this); }; private: void *m_value; }; //--------------------------------------------------------- class DVAPI TEnumProperty : public TProperty { public: typedef std::vector Range; TEnumProperty(const string &name) : TProperty(name), m_index(-1) {} TEnumProperty(const string &name, const Range &range, const wstring &v) : TProperty(name), m_range(range), m_index(indexOf(v)) { if (m_index < 0) throw RangeError(); } TEnumProperty(const string &name, Range::const_iterator i0, Range::const_iterator i1, const wstring &v) : TProperty(name), m_range(i0, i1), m_index(indexOf(v)) { if (m_index < 0) throw RangeError(); } TProperty *clone() const { return new TEnumProperty(*this); } int indexOf(const wstring &value) { Range::const_iterator it = std::find(m_range.begin(), m_range.end(), value); return (it == m_range.end()) ? -1 : it - m_range.begin(); } bool isValue(const wstring &value) { bool ret = std::find(m_range.begin(), m_range.end(), value) != m_range.end(); return ret; } void addValue(wstring value) { if (m_index == -1) m_index = 0; m_range.push_back(value); } void deleteAllValues() { m_range.clear(); m_index = -1; } void setIndex(int index) { if (index < 0 || index >= (int)m_range.size()) throw RangeError(); m_index = index; } void setValue(const wstring &value) { int idx = indexOf(value); if (idx < 0) throw RangeError(); m_index = idx; } const Range &getRange() const { return m_range; } wstring getValue() const { return (m_index < 0) ? L"" : m_range[m_index]; } string getValueAsString() { return toString(m_range[m_index]); } int getIndex() const { return m_index; } void accept(Visitor &v) { v.visit(this); } static void enableRangeSaving(bool on); static bool isRangeSavingEnabled(); private: Range m_range; int m_index; }; //--------------------------------------------------------- class DVAPI TPropertyGroup { public: typedef std::vector> PropertyVector; typedef std::map PropertyTable; // exception class PropertyNotFoundError { }; TPropertyGroup(); virtual ~TPropertyGroup(); virtual TPropertyGroup *clone() const; //! get ownership void add(TProperty *p); //! don't get ownership void bind(TProperty &p); //! returns 0 if the property doesn't exist TProperty *getProperty(string name); TProperty *getProperty(int i) { return (i >= (int)m_properties.size()) ? 0 : m_properties[i].first; } void setProperties(TPropertyGroup *g); void accept(TProperty::Visitor &v); int getPropertyCount() const { return (int)m_properties.size(); } void loadData(TIStream &is); void saveData(TOStream &os) const; void clear(); private: PropertyTable m_table; PropertyVector m_properties; private: // not implemented TPropertyGroup(const TPropertyGroup &); TPropertyGroup &operator=(const TPropertyGroup &); }; //--------------------------------------------------------- #ifdef WIN32 #pragma warning(pop) #endif #endif