|
|
/*
* Value */
#ifndef DUI_CORE_VALUE_H_INCLUDED
#define DUI_CORE_VALUE_H_INCLUDED
#pragma once
namespace DirectUI {
////////////////////////////////////////////////////////
// Value
/*
* Value Multithreading * * Values are immutable and are a process-wide resource. A value created in one thread can be * used in any thread. Access to them are synchronized (thread-safe) and they do not have * thread-affinity. * * TODO: Impl thread-safety for Values */
// Forward declarations
class Element; class Layout; class PropertySheet; class Expression; typedef DynamicArray<Element*> ElementList;
// Value will maintain the lifetime of ElementLists, Layouts, PropertySheets, and Expressions after
// a new Value is created with a pointer to the object (these objects are created externally). When
// the reference count goes to zero, these objects will be deleted.
#define DUIV_UNAVAILABLE -2
#define DUIV_UNSET -1
#define DUIV_NULL 0
#define DUIV_INT 1
#define DUIV_BOOL 2
#define DUIV_ELEMENTREF 3
#define DUIV_ELLIST 4 // List deleted on Value destruction and made immutable on create (Value only object holding external created ElementList)
#define DUIV_STRING 5 // String duplicated on creation and freed on destruction (Value creates new internal instance)
#define DUIV_POINT 6
#define DUIV_SIZE 7
#define DUIV_RECT 8
#define DUIV_FILL 9
#define DUIV_LAYOUT 10 // Layout object destroyed on Value destruction (Value only object holding external created Layout)
#define DUIV_GRAPHIC 11 // Bitmap handle freed on Value destruction (Value creates new internal instance)
#define DUIV_SHEET 12 // PropertySheet object destroyed on Value destruction and made immutable on create (Value only object holding external created PropertySheet)
#define DUIV_EXPR 13 // Expression object destroyed on Value destruction (Value only object holding external created Expression)
#define DUIV_ATOM 14
#define DUIV_CURSOR 15 // Will not destroy cursor handle upon value destruction
// Value structures and macros
#define FILLTYPE_HGradient ((BYTE)0)
#define FILLTYPE_VGradient ((BYTE)1)
#define FILLTYPE_Solid ((BYTE)2)
#define FILLTYPE_TriHGradient ((BYTE)3)
#define FILLTYPE_TriVGradient ((BYTE)4)
#define FILLTYPE_DrawFrameControl ((BYTE)5) // DrawFrameControl fill
#define FILLTYPE_DrawThemeBackground ((BYTE)6) // DrawThemeBackground fill
struct Fill // Solid colors and fills
{ BYTE dType; union { struct { COLORREF cr; COLORREF cr2; COLORREF cr3; } ref;
struct { UINT uType; UINT uState; } fillDFC;
struct { HTHEME hTheme; int iPartId; int iStateId; } fillDTB; }; };
// Graphic
// Graphic objects may either have an Alpha channel applied to the entire bitmap,
// may have full alpha transparency of a particular color in the bitmap (with the
// option of an auto-color pick (upper left corner)), or neither
#define GRAPHICTYPE_Bitmap ((BYTE)0)
#define GRAPHICTYPE_Icon ((BYTE)1)
#define GRAPHICTYPE_EnhMetaFile ((BYTE)2)
#ifdef GADGET_ENABLE_GDIPLUS
#define GRAPHICTYPE_GpBitmap ((BYTE)3)
#endif
// Valid modes for Bitmaps (Alpha or RGB used depending on mode), meaning based on context of use
#define GRAPHIC_NoBlend ((BYTE)0)
#define GRAPHIC_AlphaConst ((BYTE)1)
#define GRAPHIC_AlphaConstPerPix ((BYTE)2)
#define GRAPHIC_TransColor ((BYTE)3)
#define GRAPHIC_Stretch ((BYTE)4)
#define GRAPHIC_NineGrid ((BYTE)5)
#define GRAPHIC_NineGridTransColor ((BYTE)6)
#define GRAPHIC_NineGridAlphaConstPerPix ((BYTE)7)
struct Graphic { HANDLE hImage; // Will hold hBitmap, hIcon, hEnhMetaFile or Gdiplus::Bitmap
HANDLE hAltImage; USHORT cx; USHORT cy; struct { BYTE dImgType : 2; BYTE dMode : 3; bool bFlip : 1; bool bRTLGraphic: 1; bool bFreehImage: 1; union { BYTE dAlpha; struct { BYTE r: 8; BYTE g: 8; BYTE b: 8; } rgbTrans; }; } BlendMode; };
struct Cursor { HCURSOR hCursor; };
// Compile-time static version of the Value class
struct _StaticValue { BYTE _fReserved0; BYTE _fReserved1; short _dType; int _cRef; int _val0; int _val1; int _val2; int _val3; };
struct _StaticValueColor { BYTE _fReserved0; BYTE _fReserved1; short _dType; int _cRef; BYTE dType; COLORREF cr; COLORREF crSec; USHORT x; USHORT y; };
struct _StaticValuePtr { BYTE _fReserved0; BYTE _fReserved1; short _dType; int _cRef; void* _ptr; };
// Value class (24-bytes)
class Value { private: BYTE _fReserved0; // Reserved for small block allocator
BYTE _fReserved1; // Data alignment padding
short _dType; int _cRef; union { int _intVal; bool _boolVal; Element* _peVal; ElementList* _peListVal; LPWSTR _pszVal; POINT _ptVal; SIZE _sizeVal; RECT _rectVal; Fill _fillVal; Layout* _plVal; Graphic _graphicVal; PropertySheet* _ppsVal; Expression* _pexVal; ATOM _atomVal; Cursor _cursorVal; };
void _ZeroRelease();
public:
#if DBG
bool IsZeroRef() { return !_cRef; } #endif
// Value creation methods
static Value* CreateInt(int dValue); static Value* CreateBool(bool bValue); static Value* CreateElementRef(Element* peValue); static Value* CreateElementList(ElementList* peListValue); static Value* CreateString(LPCWSTR pszValue, HINSTANCE hResLoad = NULL); static Value* CreatePoint(int x, int y); static Value* CreateSize(int cx, int cy); static Value* CreateRect(int left, int top, int right, int bottom); static Value* CreateColor(COLORREF cr); static Value* CreateColor(COLORREF cr0, COLORREF cr1, BYTE dType = FILLTYPE_HGradient); static Value* CreateColor(COLORREF cr0, COLORREF cr1, COLORREF cr2, BYTE dType = FILLTYPE_TriHGradient); static Value* CreateFill(const Fill & clrSrc); static Value* CreateDFCFill(UINT uType, UINT uState); static Value* CreateDTBFill(HTHEME hTheme, int iPartId, int iStateId); static Value* CreateLayout(Layout* plValue); static Value* CreateGraphic(HBITMAP hBitmap, BYTE dBlendMode = GRAPHIC_TransColor, UINT dBlendValue = (UINT)-1, bool bFlip = false, bool bRTL = false); #ifdef GADGET_ENABLE_GDIPLUS
static Value* CreateGraphic(Gdiplus::Bitmap * pgpbmp, BYTE dBlendMode = GRAPHIC_TransColor, UINT dBlendValue = (UINT)-1, bool bFlip = false, bool bRTL = false); #endif
static Value* CreateGraphic(HICON hIcon, bool bFlip = false, bool bRTL = false); static Value* CreateGraphic(LPCWSTR pszBMP, BYTE dBlendMode = GRAPHIC_TransColor, UINT dBlendValue = (UINT)-1, USHORT cx = 0, USHORT cy = 0, HINSTANCE hResLoad = NULL, bool bFlip = false, bool bRTL = false); static Value* CreateGraphic(LPCWSTR pszICO, USHORT cxDesired, USHORT cyDesired, HINSTANCE hResLoad = NULL, bool bFlip = false, bool bRTL = false); static Value* CreateGraphic(HENHMETAFILE hEnhMetaFile, HENHMETAFILE hAltEnhMetaFile = NULL); static Value* CreatePropertySheet(PropertySheet* ppsValue); static Value* CreateExpression(Expression* pexValue); static Value* CreateAtom(LPCWSTR pszValue); static Value* CreateCursor(LPCWSTR pszValue); static Value* CreateCursor(HCURSOR hValue);
// Reference count methods
void AddRef() { if (_cRef != -1) _cRef++; } // -1 is static value
void Release() { if (_cRef != -1 && !--_cRef) _ZeroRelease(); } // -1 is static value
int GetRefCount() { return _cRef; }
// Accessors
int GetType(); LPVOID GetImage(bool bGetRTL); int GetInt(); bool GetBool(); Element* GetElement(); ElementList* GetElementList(); // Invalid if released (object referred to destroyed)
const LPWSTR GetString(); // Invalid if released (object referred to destroyed)
const POINT* GetPoint(); // Invalid if released
const SIZE* GetSize(); // Invalid if released
const RECT* GetRect(); // Invalid if released
const Fill* GetFill(); // Invalid if released
Layout* GetLayout(); // Invalid if released (object referred to destroyed)
Graphic* GetGraphic(); // Invalid if released (object indirectly referred to destroyed)
PropertySheet* GetPropertySheet(); // Invalid if released (object referred to destroyed)
Expression* GetExpression(); // Invalid if released (object referred to destroyed)
ATOM GetAtom(); // Invalid if released
Cursor* GetCursor(); // Invalid if released
// Equality
bool IsEqual(Value* pv);
// Conversion
LPWSTR ToString(LPWSTR psz, UINT c);
// Common values
static Value* pvUnavailable; static Value* pvNull; static Value* pvUnset; static Value* pvElementNull; static Value* pvElListNull; static Value* pvBoolTrue; static Value* pvBoolFalse; static Value* pvStringNull; static Value* pvPointZero; static Value* pvSizeZero; static Value* pvRectZero; static Value* pvIntZero; static Value* pvLayoutNull; static Value* pvGraphicNull; static Value* pvSheetNull; static Value* pvExprNull; static Value* pvAtomZero; static Value* pvCursorNull; static Value* pvColorTrans; };
//LPVOID GetImage(Graphic *pg, bool bGetRTL);
#define GethBitmap(pv, bGetRTL) ((HBITMAP)pv->GetImage(bGetRTL))
#define GethIcon(pv, bGetRTL) ((HICON)pv->GetImage(bGetRTL))
#define GethEnhMetaFile(pv, bGetRTL) ((HENHMETAFILE)pv->GetImage(bGetRTL))
#define GetGpBitmap(pv, bGetRTL) ((Gdiplus::Bitmap *)pv->GetImage(bGetRTL))
#define StaticValue(name, type, val0) static _StaticValue name = { 0, 0, type, -1, val0, 0, 0, 0 }
#define StaticValue2(name, type, val0, val1) static _StaticValue name = { 0, 0, type, -1, val0, val1, 0, 0 }
#define StaticValue4(name, type, val0, val1, val2, val3) static _StaticValue name = { 0, 0, type, -1, val0, val1, val2, val3 }
#define StaticValueColorSolid(name, cr) static _StaticValueColor name = { 0, 0, DUIV_FILL, -1, FILLTYPE_Solid, cr, 0, 0, 0 }
#define StaticValuePtr(name, type, ptr) static _StaticValuePtr name = { 0, 0, type, -1, ptr }
// Accessors
inline int Value::GetType() { return _dType; }
inline int Value::GetInt() // Copy passed out
{ DUIAssert(_dType == DUIV_INT, "Invalid value type");
return _intVal; }
inline bool Value::GetBool() // Copy passed out
{ DUIAssert(_dType == DUIV_BOOL, "Invalid value type");
return _boolVal; }
inline Element * Value::GetElement() // Copy passed out
{ DUIAssert(_dType == DUIV_ELEMENTREF, "Invalid value type");
return _peVal; }
inline ElementList * Value::GetElementList() // Copy passed out, invalid (destroyed) if value released
{ DUIAssert(_dType == DUIV_ELLIST, "Invalid value type");
return _peListVal; }
inline const LPWSTR Value::GetString() // Copy passed out, invalid (destroyed) if value released
{ DUIAssert(_dType == DUIV_STRING, "Invalid value type");
return _pszVal; }
inline const POINT * Value::GetPoint() // Pointer to internal structure, invalid if value released
{ DUIAssert(_dType == DUIV_POINT, "Invalid value type");
return &_ptVal; }
inline const SIZE * Value::GetSize() // Pointer to internal structure, invalid if value released
{ DUIAssert(_dType == DUIV_SIZE, "Invalid value type");
return &_sizeVal; }
inline const RECT * Value::GetRect() // Pointer to internal structure, invalid if value released
{ DUIAssert(_dType == DUIV_RECT, "Invalid value type");
return &_rectVal; }
inline const Fill * Value::GetFill() // Pointer to internal structure, invalid if value released
{ DUIAssert(_dType == DUIV_FILL, "Invalid value type");
return &_fillVal; }
inline Layout * Value::GetLayout() // Copy passed out, invalid (destroyed) if value released
{ DUIAssert(_dType == DUIV_LAYOUT, "Invalid value type"); return _plVal; }
inline Graphic * Value::GetGraphic() // Pointer to internal structure, invalid if value released
{ DUIAssert(_dType == DUIV_GRAPHIC, "Invalid value type"); return &_graphicVal; }
inline PropertySheet * Value::GetPropertySheet() // Copy passed out, invalid (destroyed) if value released
{ DUIAssert(_dType == DUIV_SHEET, "Invalid value type");
return _ppsVal; }
inline Expression * Value::GetExpression() // Copy passed out, invalid (destroyed) if value released
{ DUIAssert(_dType == DUIV_EXPR, "Invalid value type"); return _pexVal; }
inline ATOM Value::GetAtom() // Copy passed out
{ DUIAssert(_dType == DUIV_ATOM, "Invalid value type"); return _atomVal; }
inline Cursor * Value::GetCursor() // Pointer to internal structure, invalid if value released
{ DUIAssert(_dType == DUIV_CURSOR, "Invalid value type"); return &_cursorVal; }
} // namespace DirectUI
#endif // DUI_CORE_VALUE_H_INCLUDED
|