444 lines
13 KiB
C++
444 lines
13 KiB
C++
/*
|
|
* 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
|