/* * PropertySheet */ #ifndef DUI_CORE_SHEET_H_INCLUDED #define DUI_CORE_SHEET_H_INCLUDED #pragma once namespace DirectUI { /* * PropertySheets are used as extensions to the unchangeable value expression used * for Specified value retrieval on Elements. They provide three main services: * * * The ability to describe conditional relationships (dependencies) on a per-class level * * Values can be overridden by setting a local value on the Element * * They can be described declaratively using a CSS-like grammar * * PropertySheets are a type of value expression (but limited). Thus, they provide * a way to change values of properties based on other property changes without hard coding * the logic within a derived class of Element (using OnPropertyChanged). * * Only properties with the "Cascade" flag may be placed in the body of a Rule. Properties * that should be marked as cascadable are those that need to be updated based on changes * of other properties, but shouldn't be assumed at compile-time what these relationships * are. Such properties include any property that drives painting code directly (color, * fonts, padding, etc.). */ // Foreward declarations class Value; struct PropertyInfo; class Element; struct IClassInfo; struct DepRecs; class DeferCycle; //////////////////////////////////////////////////////// // Rule addition structures // Declaration PropertyInfo/Value tuple struct Decl { PropertyInfo* ppi; // Implicit index of Specified Value* pv; }; // Single rule conditional (l-operand op r-operand): struct Cond { PropertyInfo* ppi; // Implicit index of Retrieval index UINT nLogOp; Value* pv; }; // PropertySheet Logical operations (nLogOp) #define PSLO_Equal 0 #define PSLO_NotEqual 1 //////////////////////////////////////////////////////// // Internal database structures // Conditional to value map struct CondMap { Cond* pConds; // NULL terminated Value* pv; UINT uSpecif; }; // Dependent list, used for sheet scope and propertyinfo data (conditionals/dependencies) struct DepList { PropertyInfo** pDeps; // Implicit index of Specified UINT cDeps; }; // Storage for property-specific information struct PIData : DepList { // Used for PropertyInfo[Specified] lookups. The PropertyInfo will have // a list of conditionals (sorted by specificity) CondMap* pCMaps; UINT cCMaps; }; // Stored by _pDB, one record per class type struct Record { DepList ss; // Sheet scope PIData* ppid; // 0th property data }; //////////////////////////////////////////////////////// // PropertySheet class PropertySheet { public: static HRESULT Create(OUT PropertySheet** ppSheet); void Destroy() { HDelete(this); } HRESULT AddRule(IClassInfo* pci, Cond* pConds, Decl* pDecls); // Conds and Decls must be NULL or NULL-terminating void MakeImmutable(); Value* GetSheetValue(Element* pe, PropertyInfo* ppi); void GetSheetDependencies(Element* pe, PropertyInfo* ppi, DepRecs* pdr, DeferCycle* pdc, HRESULT* phr); void GetSheetScope(Element* pe, DepRecs* pdr, DeferCycle* pdc, HRESULT* phr); PropertySheet() { } HRESULT Initialize(); virtual ~PropertySheet(); private: Record* _pDB; // Array of per-class data IClassInfo** _pCIIdxMap; // Map _pDB indicies to actual IClassInfo UINT _uRuleId; DynamicArray* _pdaSharedCond; bool _fImmutable; }; } // namespace DirectUI #endif // DUI_CORE_SHEET_H_INCLUDED