///////////////////////////////////////////////////////////////////////////////////////// // Miranda NG: the free IM client for Microsoft* Windows* // // Copyright (C) 2012-24 Miranda NG team, // Copyright (c) 2000-09 Miranda ICQ/IM project, // all portions of this codebase are copyrighted to the people // listed in contributors.txt. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // you should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // part of tabSRMM messaging plugin for Miranda. // // (C) 2005-2010 by silvercircle _at_ gmail _dot_ com and contributors // // The class CSkin implements the skinning engine and loads skins from // their skin definition files (.tsk). // // CImageItem implements a single rectangular skin item with an image // and its rendering. #ifndef __THEMES_H #define __THEMES_H class CSideBarButton; struct TSButtonCtrl : public MButtonCtrl { HICON hIconPrivate, overlay; bool bToolbarButton; // is a toolbar button (important for aero background rendering) bool bTitleButton; bool bDimmed; TContainerData *pContainer; CSideBarButton *sitem; }; void CustomizeButton(HWND hwndButton); #define BUTTONSETASDIMMED (BUTTONSETASFLATBTN + 11) #define BUTTONSETCONTAINER (BUTTONSETASFLATBTN + 12) #define BUTTONSETASTITLE (BUTTONSETASFLATBTN + 13) #define BUTTONSETASNORMAL (BUTTONSETASFLATBTN + 14) #define BUTTONGETSTATEID (BUTTONSETASFLATBTN + 15) #define BUTTONSETASTOOLBARBUTTON (BUTTONSETASFLATBTN + 21) #define BUTTONSETASSIDEBARBUTTON (BUTTONSETASFLATBTN + 22) #define BUTTONSETOVERLAYICON (BUTTONSETASFLATBTN + 23) // FLAGS #define CORNER_NONE 0 #define CORNER_ACTIVE 1 #define CORNER_TL 2 #define CORNER_TR 4 #define CORNER_BR 8 #define CORNER_BL 16 #define CORNER_ALL (CORNER_TL | CORNER_TR | CORNER_BR | CORNER_BL | CORNER_ACTIVE) #define GRADIENT_NONE 0 #define GRADIENT_ACTIVE 1 #define GRADIENT_LR 2 #define GRADIENT_RL 4 #define GRADIENT_TB 8 #define GRADIENT_BT 16 #define IMAGE_PERPIXEL_ALPHA 1 #define IMAGE_FLAG_DIVIDED 2 #define IMAGE_FILLSOLID 4 #define IMAGE_GLYPH 8 #define IMAGE_STRETCH_V 1 #define IMAGE_STRETCH_H 2 #define IMAGE_STRETCH_B 4 #define BUTTON_ISINTERNAL 1 #define BUTTON_ISTOGGLE 2 #define BUTTON_ISSERVICE 4 #define BUTTON_ISPROTOSERVICE 8 #define BUTTON_PASSHCONTACTW 16 #define BUTTON_PASSHCONTACTL 32 #define BUTTON_ISDBACTION 64 #define BUTTON_ISCONTACTDBACTION 128 #define BUTTON_DBACTIONONCONTACT 256 #define BUTTON_ISSIDEBAR 512 #define BUTTON_NORMALGLYPHISICON 1024 #define BUTTON_PRESSEDGLYPHISICON 2048 #define BUTTON_HOVERGLYPHISICON 4096 #define BUTTON_HASLABEL 8192 #define CLCDEFAULT_GRADIENT 0 #define CLCDEFAULT_CORNER 0 #define CLCDEFAULT_COLOR 0xd0d0d0 #define CLCDEFAULT_COLOR2 0xd0d0d0 #define CLCDEFAULT_TEXTCOLOR 0x000000 #define CLCDEFAULT_COLOR2_TRANSPARENT 1 #define CLCDEFAULT_ALPHA 100 #define CLCDEFAULT_MRGN_LEFT 0 #define CLCDEFAULT_MRGN_TOP 0 #define CLCDEFAULT_MRGN_RIGHT 0 #define CLCDEFAULT_MRGN_BOTTOM 0 #define CLCDEFAULT_IGNORE 1 struct AeroEffect { wchar_t tszName[40]; uint32_t m_baseColor; uint32_t m_gradientColor; uint8_t m_baseAlpha; uint8_t m_finalAlpha; uint8_t m_cornerType; uint8_t m_gradientType; uint32_t m_cornerRadius; uint32_t m_glowSize; COLORREF m_clrBack, m_clrToolbar, m_clrToolbar2; void (TSAPI *pfnEffectRenderer)(const HDC hdc, const RECT *rc, int iEffectArea); }; /** * CImageItem implementes image-based skin items. These items are loaded * from a skin file definition (.tsk file) and are then linked to one or * more skin items. */ class CImageItem { public: CImageItem() { memset(this, 0, sizeof(CImageItem)); } CImageItem(const CImageItem &From) { *this = From; m_nextItem = nullptr; } CImageItem(const wchar_t *szName) { memset(this, 0, sizeof(CImageItem)); mir_snwprintf(m_szName, szName); m_szName[39] = 0; } CImageItem(uint8_t bottom, uint8_t left, uint8_t top, uint8_t right, HDC hdc, HBITMAP hbm, uint32_t dwFlags, HBRUSH brush, uint8_t alpha, int inner_height, int inner_width, int height, int width) { m_bBottom = bottom; m_bLeft = left; m_bTop = top; m_bRight = right; m_hdc = hdc; m_hbm = hbm; m_dwFlags = dwFlags; m_fillBrush = brush; m_inner_height = inner_height; m_inner_width = inner_width; m_height = height; m_width = width; m_bf.SourceConstantAlpha = alpha; m_bf.AlphaFormat = 0; m_bf.BlendOp = AC_SRC_OVER; m_bf.BlendFlags = 0; } ~CImageItem() { Free(); } void Clear() { m_hdc = nullptr; m_hbm = nullptr; m_hbmOld = nullptr; m_fillBrush = nullptr; } void setBitmap(const HBITMAP hbm) { m_hbm = hbm; } void setAlphaFormat(const uint8_t bFormat, const uint8_t bConstantAlpha) { m_bf.AlphaFormat = bFormat; m_bf.SourceConstantAlpha = bConstantAlpha; } void setMetrics(const LONG width, const LONG height) { m_height = height; m_width = width; m_inner_height = m_height - m_bBottom - m_bTop; m_inner_width = m_width - m_bLeft - m_bRight; if (!(m_dwFlags & IMAGE_FLAG_DIVIDED)) m_bStretch = IMAGE_STRETCH_B; } const BLENDFUNCTION &getBF() const { return m_bf; } void Free(); CImageItem* getNextItem() const { return(m_nextItem); } void setNextItem(CImageItem *item) { m_nextItem = item; } HBITMAP getHbm() const { return(m_hbm); } uint32_t getFlags() const { return(m_dwFlags); } HDC getDC() const { return(m_hdc); } const wchar_t* getName() const { return (m_szName); } wchar_t* Read(const wchar_t *szFilename); void Create(const wchar_t *szImageFile); void __fastcall Render(const HDC hdc, const RECT *rc, bool fIgnoreGlyph) const; static void TSAPI PreMultiply(HBITMAP hBitmap, int mode); static void TSAPI SetBitmap32Alpha(HBITMAP hBitmap, uint8_t bAlpha = 255); static void TSAPI Colorize(HBITMAP hBitmap, uint8_t dr, uint8_t dg, uint8_t db, uint8_t alpha = 0); public: bool m_fValid; // verified item, indicates that all parameters are valid private: wchar_t m_szName[40]; // everything wants a name, an image item doesn't need one though HBITMAP m_hbm; // the bitmap handle uint8_t m_bLeft, m_bRight, m_bTop, m_bBottom; // sizing margins for the outer 8 image parts uint8_t m_alpha; // constant alpha for the entire image, applied via m_bf. sums with perpixel alpha uint32_t m_dwFlags; // flags HDC m_hdc; // *can* hold a pre-created hdc to speed up rendering HBITMAP m_hbmOld; // old bitmap, needs to be selected into m_hdc before destroying it int m_inner_height, m_inner_width; // dimensions of the inner image part int m_width, m_height; // width and height of the image, in pixels uint8_t m_bStretch; // stretch mode (unused in tabSRMM HBRUSH m_fillBrush; // brush to fill the inner part (faster) dwFlags & IMAGE_FILLSOLID must be set LONG m_glyphMetrics[4]; // these coordinates point into the glyph image (if IMAGE_GLYPH is set) CImageItem* m_nextItem; // next item in a set of image items (usually the skin set) BLENDFUNCTION m_bf; // for AlphaBlend() }; struct CSkinItem { wchar_t szName[40]; char szDBname[40]; int statusID; uint8_t GRADIENT; uint8_t CORNER; uint32_t COLOR; uint32_t COLOR2; uint8_t COLOR2_TRANSPARENT; uint32_t TEXTCOLOR; int ALPHA; int MARGIN_LEFT; int MARGIN_TOP; int MARGIN_RIGHT; int MARGIN_BOTTOM; uint8_t IGNORED; uint32_t BORDERSTYLE; CImageItem *imageItem; }; /** * Implements the skinning engine. There is only one instance of this class and * it always holds the currently loaded skin (if any). */ class CSkin { public: enum { AERO_EFFECT_NONE = 0, AERO_EFFECT_MILK = 1, AERO_EFFECT_CARBON = 2, AERO_EFFECT_SOLID = 3, AERO_EFFECT_WHITE = 4, AERO_EFFECT_CUSTOM = 5, AERO_EFFECT_CUSTOM2 = 6, AERO_EFFECT_LAST = 7 }; enum { AERO_EFFECT_AREA_MENUBAR = 0, AERO_EFFECT_AREA_STATUSBAR = 1, AERO_EFFECT_AREA_INFOPANEL = 2, AERO_EFFECT_AREA_TAB_ACTIVE = 3, AERO_EFFECT_AREA_TAB_HOVER = 4, AERO_EFFECT_AREA_TAB_NORMAL = 5, AERO_EFFECT_AREA_SIDEBAR_LEFT = 6, AERO_EFFECT_AREA_SIDEBAR_RIGHT = 7, AERO_EFFECT_AREA_TAB_TOP = 0x1000, AERO_EFFECT_AREA_TAB_BOTTOM = 0x2000 }; enum { DEFAULT_GLOW_SIZE = 10 }; /* * avatar border types (skinned mode only) */ enum { AVBORDER_NONE = 0, AVBORDER_NORMAL = 1, AVBORDER_ROUNDED = 2 }; CSkin() { memset(this, 0, sizeof(CSkin)); m_default_bf.SourceConstantAlpha = 255; m_default_bf.AlphaFormat = AC_SRC_ALPHA; m_default_bf.BlendOp = AC_SRC_OVER; } ~CSkin() { Unload(); } void Init(bool fStartup = false); void Load(void); void Unload(); void UnloadAeroTabs(); void setFileName(); void ReadItem(const int id, const wchar_t *section); void LoadItems(); void LoadIcon(const wchar_t *szSection, const wchar_t *name, HICON &hIcon); void ReadImageItem(const wchar_t *szItemName); void ReadButtonItem(const wchar_t *itemName) const; bool haveGlyphItem() const { return(m_fHaveGlyph); } int getNrIcons() const { return(m_nrSkinIcons); } uint32_t getDwmColor() const { return(m_dwmColor); } const TIconDescW* getIconDesc(const int id) const { return(&m_skinIcons[id]); } /** * get the glyph image item (a single PNG image, containing a number of textures * for the skin. * * @return CImageItem&: reference to the glyph item. Cannot be * modified. * */ const CImageItem* getGlyphItem() const { return(m_fHaveGlyph ? &m_glyphItem : nullptr); } bool warnToClose() const; COLORREF getColorKey() const { return(m_ContainerColorKey); } void setupAeroSkins(); void extractSkinsAndLogo(bool fForceOverwrite = false) const; void setupTabCloseBitmap(bool fDeleteOnly = false); /* * static member functions */ static void TSAPI SkinDrawBGFromDC(HWND hwndClient, HWND hwnd, RECT *rcClient, HDC hdcTarget); static void TSAPI SkinDrawBG(HWND hwndClient, HWND hwnd, TContainerData *pContainer, RECT *rcClient, HDC hdcTarget); static void TSAPI DrawDimmedIcon(HDC hdc, LONG left, LONG top, LONG dx, LONG dy, HICON hIcon, uint8_t alpha); static uint32_t TSAPI HexStringToLong(const wchar_t *szSource); static UINT TSAPI DrawRichEditFrame(HWND hwnd, const CMsgDialog *mwdat, UINT skinID, UINT msg, WPARAM wParam, LPARAM lParam, WNDPROC OldWndProc); static UINT TSAPI NcCalcRichEditFrame(HWND hwnd, const CMsgDialog *mwdat, UINT skinID, UINT msg, WPARAM wParam, LPARAM lParam, WNDPROC OldWndProc); static HBITMAP TSAPI CreateAeroCompatibleBitmap(const RECT &rc, HDC dc); static int TSAPI RenderText(HDC hdc, HANDLE hTheme, const wchar_t *szText, RECT *rc, uint32_t dtFlags, const int iGlowSize = DEFAULT_GLOW_SIZE, COLORREF clr = 0, bool fForceAero = false); static void TSAPI MapClientToParent(HWND hwndClient, HWND hwndParent, RECT &rc); static void TSAPI ApplyAeroEffect(const HDC hdc, const RECT* rc, int iEffectArea); static void TSAPI setAeroEffect(const LRESULT effect); static void TSAPI initAeroEffect(); static HANDLE TSAPI InitiateBufferedPaint(const HDC hdcSrc, RECT& rc, HDC& hdcOut); static void TSAPI FinalizeBufferedPaint(HANDLE hbp, RECT *rc); static bool TSAPI DrawItem(const HDC hdc, const RECT *rc, const CSkinItem *item); static void TSAPI FillBack(const HDC hdc, RECT* rc); static bool TSAPI IsThemed(void); public: static bool m_DisableScrollbars, m_bClipBorder; static char m_SkinnedFrame_left, m_SkinnedFrame_right, m_SkinnedFrame_bottom, m_SkinnedFrame_caption; static char m_realSkinnedFrame_left, m_realSkinnedFrame_right, m_realSkinnedFrame_bottom, m_realSkinnedFrame_caption; static HPEN m_SkinLightShadowPen, m_SkinDarkShadowPen; static int m_titleBarLeftOff, m_titleButtonTopOff, m_captionOffset, m_captionPadding, m_titleBarRightOff, m_sidebarTopOffset, m_sidebarBottomOffset, m_bRoundedCorner; static SIZE m_titleBarButtonSize; static int m_bAvatarBorderType; static COLORREF m_avatarBorderClr, m_tmp_tb_low, m_tmp_tb_high; static COLORREF m_sideBarContainerBG; static COLORREF m_ContainerColorKey, m_DefaultFontColor; static HBRUSH m_ContainerColorKeyBrush, m_MenuBGBrush; static bool m_skinEnabled; static bool m_frameSkins; static HICON m_closeIcon, m_minIcon, m_maxIcon; static BLENDFUNCTION m_default_bf; // general purpose bf, dynamically modified when needed /* * cached bitmap for tab close button */ static HBITMAP m_tabCloseBitmap, m_tabCloseOldBitmap; static HDC m_tabCloseHDC; /* * controls the aero effect. Set by initAeroEffect() */ static UINT m_aeroEffect; // effect id, initAeroEffect() is using it to set the parameters below. static AeroEffect m_aeroEffects[AERO_EFFECT_LAST]; static AeroEffect m_currentAeroEffect; static AeroEffect* m_pCurrentAeroEffect; static uint32_t m_glowSize; static HBRUSH m_BrushBack, m_BrushFill; static COLORREF m_dwmColorRGB; static CImageItem* m_switchBarItem, *m_tabTop, *m_tabBottom, *m_tabGlowTop, *m_tabGlowBottom; static bool m_fAeroSkinsValid; private: wchar_t m_tszFileName[MAX_PATH]; // full path and filename of the currently loaded skin CSkinItem* m_SkinItems; CImageItem* m_ImageItems; // the list of image item objects CImageItem m_glyphItem; bool m_fLoadOnStartup; // load the skin on plugin initialization. bool m_fHaveGlyph; void SkinCalcFrameWidth(); TIconDescW* m_skinIcons; int m_nrSkinIcons; uint32_t m_dwmColor; static void TSAPI AeroEffectCallback_Milk(const HDC hdc, const RECT *rc, int iEffectArea); static void TSAPI AeroEffectCallback_Carbon(const HDC hdc, const RECT *rc, int iEffectArea); static void TSAPI AeroEffectCallback_Solid(const HDC hdc, const RECT *rc, int iEffectArea); }; extern CSkin *Skin; /* * data structs */ struct ButtonItem { wchar_t szName[40]; HWND hWnd; LONG xOff, yOff; LONG width, height; CImageItem *imgNormal, *imgPressed, *imgHover; LONG_PTR normalGlyphMetrics[4]; LONG_PTR hoverGlyphMetrics[4]; LONG_PTR pressedGlyphMetrics[4]; uint32_t dwFlags, dwStockFlags; uint32_t uId; wchar_t szTip[256]; char szService[256]; char szModule[256], szSetting[256]; uint8_t bValuePush[256], bValueRelease[256]; uint32_t type; void (*pfnAction)(ButtonItem *item, HWND hwndDlg, CMsgDialog *dat, HWND hwndItem); void (*pfnCallback)(ButtonItem *item, HWND hwndDlg, CMsgDialog *dat, HWND hwndItem); wchar_t tszLabel[40]; ButtonItem *nextItem; HANDLE hContact; CMsgDialog *dat; }; struct ButtonSet { ButtonItem *items; LONG left, top, right, bottom; // client area offsets, calculated from button layout }; #endif /* __THEMES_H */