127 lines
3.5 KiB
C++
127 lines
3.5 KiB
C++
/*
|
|
* 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): <PropertyInfo[RetrievalIndex]> <LogOp> <Value>
|
|
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<PropertySheet>(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<Cond*>* _pdaSharedCond;
|
|
bool _fImmutable;
|
|
};
|
|
|
|
} // namespace DirectUI
|
|
|
|
#endif // DUI_CORE_SHEET_H_INCLUDED
|