764 lines
No EOL
40 KiB
C++
764 lines
No EOL
40 KiB
C++
// OXTaskPanel.cpp : implementation file
|
||
//
|
||
|
||
#include "stdafx.h"
|
||
#include "OXTaskPanel.h"
|
||
|
||
//Theme API wrapper declarations
|
||
|
||
HMODULE g_huxtheme = NULL;
|
||
|
||
bool G_LoadThemeLibrary()
|
||
{
|
||
if (!g_huxtheme)
|
||
g_huxtheme = ::LoadLibrary(_T("uxtheme.dll"));
|
||
return (g_huxtheme != NULL);
|
||
}
|
||
|
||
HTHEME G_OpenThemeData(HWND hwnd, LPCTSTR pszClassList)
|
||
{
|
||
G_LoadThemeLibrary();
|
||
OPENTHEMEDATA pOpenThemeData = (OPENTHEMEDATA)GetProcAddress(g_huxtheme, "OpenThemeData");
|
||
if (pOpenThemeData != NULL)
|
||
return (*pOpenThemeData)(hwnd, pszClassList);
|
||
else
|
||
return NULL;
|
||
}
|
||
|
||
HRESULT G_CloseThemeData(HTHEME hTheme)
|
||
{
|
||
G_LoadThemeLibrary();
|
||
CLOSETHEMEDATA pCloseThemeData = (CLOSETHEMEDATA)GetProcAddress(g_huxtheme, "CloseThemeData");
|
||
if (pCloseThemeData != NULL)
|
||
return (*pCloseThemeData)(hTheme);
|
||
else
|
||
return E_FAIL;
|
||
}
|
||
|
||
HRESULT G_DrawThemeBackground(HTHEME hTheme, HDC hdc,
|
||
int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect)
|
||
{
|
||
G_LoadThemeLibrary();
|
||
DRAWTHEMEBACKGROUND pDrawThemeBackground =
|
||
(DRAWTHEMEBACKGROUND)GetProcAddress(g_huxtheme, "DrawThemeBackground");
|
||
if (pDrawThemeBackground != NULL)
|
||
return (*pDrawThemeBackground)(hTheme, hdc, iPartId, iStateId, pRect, pClipRect);
|
||
else
|
||
return E_FAIL;
|
||
}
|
||
|
||
HRESULT G_DrawThemeText(HTHEME hTheme, HDC hdc, int iPartId,
|
||
int iStateId, LPCWSTR pszText, int iCharCount, DWORD dwTextFlags,
|
||
DWORD dwTextFlags2, const RECT *pRect)
|
||
{
|
||
G_LoadThemeLibrary();
|
||
DRAWTHEMETEXT pDrawThemeText = (DRAWTHEMETEXT)GetProcAddress(g_huxtheme, "DrawThemeText");
|
||
if (pDrawThemeText != NULL)
|
||
return (*pDrawThemeText)(hTheme, hdc, iPartId, iStateId, pszText, iCharCount, dwTextFlags, dwTextFlags2, pRect);
|
||
else
|
||
return E_FAIL;
|
||
}
|
||
|
||
HRESULT G_DrawThemeEdge(HTHEME hTheme, HDC hdc, int iPartId, int iStateId,
|
||
const RECT *pDestRect, UINT uEdge, UINT uFlags, OPTIONAL OUT RECT *pContentRect)
|
||
{
|
||
G_LoadThemeLibrary();
|
||
DRAWTHEMEEDGE pDrawThemeEdge = (DRAWTHEMEEDGE)GetProcAddress(g_huxtheme, "DrawThemeEdge");
|
||
if (pDrawThemeEdge != NULL)
|
||
return (*pDrawThemeEdge)(hTheme, hdc, iPartId, iStateId, pDestRect, uEdge, uFlags, pContentRect);
|
||
else
|
||
return E_FAIL;
|
||
}
|
||
|
||
HRESULT G_GetThemeColor(HTHEME hTheme, int iPartId,
|
||
int iStateId, int iPropId, OUT COLORREF *pColor)
|
||
{
|
||
G_LoadThemeLibrary();
|
||
GETTHEMECOLOR pGetThemeColor = (GETTHEMECOLOR)GetProcAddress(g_huxtheme, "GetThemeColor");
|
||
if (pGetThemeColor != NULL)
|
||
return (*pGetThemeColor)(hTheme, iPartId, iStateId, iPropId, pColor);
|
||
else
|
||
return E_FAIL;
|
||
}
|
||
|
||
HRESULT G_GetThemeFont(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId,
|
||
int iStateId, int iPropId, OUT LOGFONT *pFont)
|
||
{
|
||
G_LoadThemeLibrary();
|
||
GETTHEMEFONT pGetThemeFont = (GETTHEMEFONT)GetProcAddress(g_huxtheme, "GetThemeFont");
|
||
if (pGetThemeFont != NULL)
|
||
return (*pGetThemeFont)(hTheme, hdc, iPartId, iStateId, iPropId, pFont);
|
||
else
|
||
return E_FAIL;
|
||
}
|
||
|
||
// COXTaskPanel
|
||
|
||
IMPLEMENT_DYNAMIC(COXTaskPanel, CWnd)
|
||
|
||
COXTaskPanel::COXTaskPanel():m_hTheme(NULL),m_bLastHover(false),
|
||
m_ActiveItem(NULL),m_bMouseOnControl(false),pOldFocus(NULL),
|
||
m_bIgnoreButtonUp(false),m_nAnimSteps(0)
|
||
{
|
||
|
||
}
|
||
|
||
COXTaskPanel::~COXTaskPanel()
|
||
{
|
||
}
|
||
|
||
|
||
BEGIN_MESSAGE_MAP(COXTaskPanel, CWnd)
|
||
ON_WM_CREATE()
|
||
ON_WM_CLOSE()
|
||
ON_WM_PAINT()
|
||
ON_WM_MOUSEMOVE()
|
||
ON_WM_ERASEBKGND()
|
||
ON_WM_LBUTTONDOWN()
|
||
ON_WM_LBUTTONUP()
|
||
ON_WM_VSCROLL()
|
||
ON_WM_MOUSEWHEEL()
|
||
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
|
||
ON_MESSAGE(WM_THEMECHANGED, OnThemeChanged)
|
||
ON_WM_TIMER()
|
||
END_MESSAGE_MAP()
|
||
|
||
// COXTaskPanel message handlers
|
||
|
||
BOOL COXTaskPanel::Create(RECT rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
|
||
{
|
||
rect.right = rect.left + PDPanelFixedWidth;
|
||
return CWnd::Create(NULL, _T("Panel"), WS_VISIBLE|WS_CHILD|WS_VSCROLL, rect, pParentWnd, nID, pContext);
|
||
}
|
||
|
||
int COXTaskPanel::OnCreate(LPCREATESTRUCT lpCreateStruct)
|
||
{
|
||
if (CWnd::OnCreate(lpCreateStruct) == -1)
|
||
return -1;
|
||
|
||
m_hTheme = G_OpenThemeData(m_hWnd, _T("EXPLORERBAR"));
|
||
|
||
return 0;
|
||
}
|
||
|
||
void COXTaskPanel::OnClose()
|
||
{
|
||
G_CloseThemeData(m_hTheme);
|
||
|
||
CWnd::OnClose();
|
||
}
|
||
|
||
void COXTaskPanel::OnPaint()
|
||
{
|
||
CPaintDC dc(this);
|
||
|
||
int yPos = (GetWindowLong(m_hWnd, GWL_STYLE) & WS_VSCROLL) ? GetScrollPos(SB_VERT) : 0;
|
||
dc.SetWindowOrg(0, yPos);
|
||
|
||
CRect rect;
|
||
GetClientRect(&rect);
|
||
rect.bottom += yPos;
|
||
|
||
CDC memdc;
|
||
memdc.CreateCompatibleDC(&dc);
|
||
|
||
CBitmap bmap;
|
||
bmap.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height());
|
||
|
||
CBitmap* pOldBitmap = memdc.SelectObject(&bmap);
|
||
|
||
if(COXTaskPanel::IsThemed())
|
||
G_DrawThemeBackground(m_hTheme, memdc.m_hDC, 1, 0,rect, NULL);
|
||
else
|
||
memdc.FillSolidRect(rect,GetSysColor(COLOR_WINDOW));
|
||
|
||
DrawGroups(memdc.m_hDC);
|
||
|
||
dc.BitBlt(0, 0, rect.Width(), rect.Height(), &memdc, 0, 0, SRCCOPY);
|
||
|
||
memdc.SelectObject(pOldBitmap);
|
||
}
|
||
|
||
BOOL COXTaskPanel::OnEraseBkgnd(CDC* /*pDC*/)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
LRESULT COXTaskPanel::OnThemeChanged(WPARAM /*wParam*/, LPARAM /*lParam*/)
|
||
{
|
||
G_CloseThemeData(m_hTheme);
|
||
m_hTheme = G_OpenThemeData(m_hWnd, _T("EXPLORERBAR"));
|
||
return 1;
|
||
}
|
||
|
||
void COXTaskPanel::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* /*pScrollBar*/)
|
||
{
|
||
switch(nSBCode)
|
||
{
|
||
case SB_LINEDOWN:
|
||
nPos = GetScrollPos(SB_VERT) + 1;
|
||
break;
|
||
case SB_LINEUP:
|
||
nPos = GetScrollPos(SB_VERT) - 1;
|
||
break;
|
||
case SB_PAGEDOWN:
|
||
nPos = GetScrollPos(SB_VERT) + MulDiv(GetSystemMetrics(SM_CYMENU), 9, 8);
|
||
break;
|
||
case SB_PAGEUP:
|
||
nPos = GetScrollPos(SB_VERT) - MulDiv(GetSystemMetrics(SM_CYMENU), 9, 8);
|
||
break;
|
||
case SB_TOP:
|
||
nPos = 0;
|
||
break;
|
||
case SB_BOTTOM:
|
||
nPos = GetScrollLimit(SB_VERT);
|
||
break;
|
||
case SB_ENDSCROLL:
|
||
return;
|
||
}
|
||
SetScrollPos(SB_VERT, nPos, TRUE);
|
||
Invalidate();
|
||
}
|
||
|
||
BOOL COXTaskPanel::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
|
||
{
|
||
if(GetWindowLong(m_hWnd, GWL_STYLE) & WS_VSCROLL)
|
||
{
|
||
OnVScroll(zDelta > 0 ? SB_PAGEUP : SB_PAGEDOWN, 0, NULL);
|
||
return TRUE;
|
||
}
|
||
return CWnd::OnMouseWheel(nFlags, zDelta, pt);
|
||
}
|
||
|
||
void COXTaskPanel::OnMouseMove(UINT nFlags, CPoint point)
|
||
{
|
||
if(!m_bMouseOnControl)
|
||
{
|
||
m_bMouseOnControl = true;
|
||
TRACKMOUSEEVENT tme = {0};
|
||
tme.cbSize = sizeof TRACKMOUSEEVENT;
|
||
tme.dwFlags = TME_LEAVE;
|
||
tme.hwndTrack = m_hWnd;
|
||
TrackMouseEvent(&tme);
|
||
pOldFocus = SetFocus();
|
||
}
|
||
|
||
int yPos = (GetWindowLong(m_hWnd, GWL_STYLE) & WS_VSCROLL) ? GetScrollPos(SB_VERT) : 0;
|
||
point.y += yPos;
|
||
|
||
bool bFoundHover = false;
|
||
for(vector<TaskGroup>::iterator it = m_vecGroups.begin();
|
||
it != m_vecGroups.end(); it++)
|
||
{
|
||
if(it->m_HeaderRect.PtInRect(point) )
|
||
{
|
||
SetCursor(AfxGetApp()->LoadOEMCursor(OCR_HAND));
|
||
if(!it->m_bIsMouseHovered)
|
||
{
|
||
it->m_bIsMouseHovered = true;
|
||
Invalidate();
|
||
}
|
||
bFoundHover = true;
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
Item* pItem = NULL;
|
||
pItem = it->FindItemWithPt(point);
|
||
if(!it->m_bIsCollapsed && (pItem) )
|
||
{
|
||
InvalidateRect(m_ActiveItem->m_ItemRect);
|
||
m_ActiveItem = pItem;
|
||
Invalidate();
|
||
SetCursor(AfxGetApp()->LoadOEMCursor(OCR_HAND));
|
||
}
|
||
it->m_bIsMouseHovered = false;
|
||
}
|
||
}
|
||
if(!bFoundHover)
|
||
{
|
||
if(m_bLastHover)
|
||
{
|
||
Invalidate();
|
||
m_bLastHover = false;
|
||
}
|
||
}
|
||
|
||
point.y -= yPos;
|
||
CWnd::OnMouseMove(nFlags, point);
|
||
}
|
||
|
||
LRESULT COXTaskPanel::OnMouseLeave(WPARAM /* wParam */, LPARAM /* lParam */)
|
||
{
|
||
m_bMouseOnControl = false;
|
||
if(pOldFocus)
|
||
{
|
||
pOldFocus->SetFocus();
|
||
pOldFocus = NULL;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
void COXTaskPanel::OnLButtonDown(UINT nFlags, CPoint point)
|
||
{
|
||
int yPos = (GetWindowLong(m_hWnd, GWL_STYLE) & WS_VSCROLL) ? GetScrollPos(SB_VERT) : 0;
|
||
point.y += yPos;
|
||
|
||
for(vector<TaskGroup>::iterator it = m_vecGroups.begin();
|
||
it != m_vecGroups.end(); it++)
|
||
{
|
||
// Check to see if an animation is already active for this task group
|
||
if(it->m_bAnimationEnabled)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
if(it->m_HeaderRect.PtInRect(point))
|
||
{
|
||
if(it->m_bIsCollapsed)
|
||
{
|
||
SetTimer(ANIMATIONTIMERID, ANIMATIONINTERVAL, NULL);
|
||
m_nAnimSteps = NUMANIMSTEPS;
|
||
}
|
||
else
|
||
{
|
||
SetTimer(REVANIMATIONTIMERID, ANIMATIONINTERVAL, NULL);
|
||
m_nAnimSteps = -NUMANIMSTEPS;
|
||
}
|
||
|
||
it->m_bAnimationEnabled = true;
|
||
it->m_bIsCollapsed = !it->m_bIsCollapsed;
|
||
Invalidate();
|
||
m_bIgnoreButtonUp = true;
|
||
break;
|
||
}
|
||
}
|
||
point.y -= yPos;
|
||
CWnd::OnLButtonDown(nFlags, point);
|
||
}
|
||
|
||
void COXTaskPanel::OnLButtonUp(UINT nFlags, CPoint point)
|
||
{
|
||
if(!m_bIgnoreButtonUp)
|
||
{
|
||
int yPos = (GetWindowLong(m_hWnd, GWL_STYLE) & WS_VSCROLL) ? GetScrollPos(SB_VERT) : 0;
|
||
point.y += yPos;
|
||
|
||
for(vector<TaskGroup>::iterator it = m_vecGroups.begin();
|
||
it != m_vecGroups.end(); it++)
|
||
{
|
||
Item* pItem = NULL;
|
||
bool bItemValid = false;
|
||
pItem = it->FindItemWithPt(point);
|
||
bItemValid = !it->m_bIsCollapsed;
|
||
if( it->m_HeaderRect.PtInRect(point) || (bItemValid && pItem ) )
|
||
{
|
||
if(bItemValid && pItem->m_strCmd.GetLength())
|
||
{
|
||
OnMouseLeave(0,0);
|
||
ShellExecute(m_hWnd,_T("open"),pItem->m_strCmd,
|
||
NULL,NULL,SW_SHOW);
|
||
}
|
||
SetCursor(AfxGetApp()->LoadOEMCursor(OCR_HAND));
|
||
}
|
||
}
|
||
point.y -= yPos;
|
||
}
|
||
else
|
||
{
|
||
m_bIgnoreButtonUp = false;
|
||
}
|
||
|
||
CWnd::OnLButtonUp(nFlags, point);
|
||
}
|
||
|
||
void COXTaskPanel::OnTimer(UINT_PTR nIDEvent)
|
||
{
|
||
if(nIDEvent == ANIMATIONTIMERID)
|
||
{
|
||
if(m_nAnimSteps--)
|
||
Invalidate();
|
||
else
|
||
{
|
||
m_nAnimSteps = 0;
|
||
KillTimer(ANIMATIONTIMERID);
|
||
}
|
||
}
|
||
if(nIDEvent == REVANIMATIONTIMERID)
|
||
{
|
||
if(m_nAnimSteps++)
|
||
Invalidate();
|
||
else
|
||
{
|
||
m_nAnimSteps = 0;
|
||
KillTimer(REVANIMATIONTIMERID);
|
||
}
|
||
}
|
||
CWnd::OnTimer(nIDEvent);
|
||
}
|
||
|
||
bool COXTaskPanel::IsThemed()
|
||
{
|
||
bool ret = false;
|
||
OSVERSIONINFO ovi = {0};
|
||
ovi.dwOSVersionInfoSize = sizeof ovi;
|
||
GetVersionEx(&ovi);
|
||
if( (ovi.dwMajorVersion==5 && ovi.dwMinorVersion>=1) || (ovi.dwMajorVersion>5) )
|
||
{
|
||
//Windows XP or later detected
|
||
typedef BOOL WINAPI ISAPPTHEMED();
|
||
typedef BOOL WINAPI ISTHEMEACTIVE();
|
||
ISAPPTHEMED* pISAPPTHEMED = NULL;
|
||
ISTHEMEACTIVE* pISTHEMEACTIVE = NULL;
|
||
HMODULE hMod = LoadLibrary(_T("uxtheme.dll"));
|
||
if(hMod)
|
||
{
|
||
pISAPPTHEMED = reinterpret_cast<ISAPPTHEMED*>(GetProcAddress(hMod,"IsAppThemed"));
|
||
pISTHEMEACTIVE = reinterpret_cast<ISTHEMEACTIVE*>(GetProcAddress(hMod,"IsThemeActive"));
|
||
if(pISAPPTHEMED && pISTHEMEACTIVE)
|
||
{
|
||
if(pISAPPTHEMED() && pISTHEMEACTIVE())
|
||
{
|
||
typedef HRESULT CALLBACK DLLGETVERSION(DLLVERSIONINFO*);
|
||
DLLGETVERSION* pDLLGETVERSION = NULL;
|
||
|
||
HMODULE hModComCtl = LoadLibrary(_T("comctl32.dll"));
|
||
if(hModComCtl)
|
||
{
|
||
pDLLGETVERSION = reinterpret_cast<DLLGETVERSION*>(
|
||
GetProcAddress(hModComCtl,"DllGetVersion"));
|
||
if(pDLLGETVERSION)
|
||
{
|
||
DLLVERSIONINFO dvi = {0};
|
||
dvi.cbSize = sizeof dvi;
|
||
if(pDLLGETVERSION(&dvi) == NOERROR )
|
||
{
|
||
ret = dvi.dwMajorVersion >= 6;
|
||
}
|
||
}
|
||
FreeLibrary(hModComCtl);
|
||
}
|
||
}
|
||
}
|
||
FreeLibrary(hMod);
|
||
}
|
||
}
|
||
return ret;
|
||
}
|
||
TaskGroup* COXTaskPanel::AddGroup(LPCTSTR szGroupName)
|
||
{
|
||
m_vecGroups.push_back(TaskGroup(szGroupName));
|
||
return &(*(m_vecGroups.end() - 1));
|
||
}
|
||
|
||
void COXTaskPanel::DrawGroupItem(HDC hDC, const CRect& recGroupItem, vector<Item>::iterator it2)
|
||
{
|
||
it2->m_ItemRect = recGroupItem;
|
||
HICON hIcon = (HICON)LoadImage(AfxGetInstanceHandle(),
|
||
MAKEINTRESOURCE(it2->m_nIconID), IMAGE_ICON,16,16,LR_DEFAULTCOLOR);
|
||
DrawIconEx(hDC,recGroupItem.left - (PDGroupItemLeftMargin-PDGroupIconLeftMargin),
|
||
recGroupItem.top + PDGroupIconVerticalDisplacement, hIcon, 16, 16,0, NULL,DI_NORMAL);
|
||
DestroyIcon(hIcon);
|
||
|
||
if(&(*it2) == m_ActiveItem)
|
||
{
|
||
m_ActiveItem = NULL;
|
||
TCHAR buff[128];
|
||
_tcscpy_s(buff,it2->m_strText);
|
||
int oldMode = SetBkMode(hDC, TRANSPARENT);
|
||
COLORREF color;
|
||
if(COXTaskPanel::IsThemed())
|
||
{
|
||
G_GetThemeColor(m_hTheme,5,0,TMT_TEXTCOLOR,&color);
|
||
int shift = 48;
|
||
color = RGB(min(255,GetRValue(color) + shift),
|
||
min(255,GetGValue(color) + shift), min(255,GetBValue(color) + shift));
|
||
}
|
||
else
|
||
{
|
||
color = GetSysColor(COLOR_HOTLIGHT);
|
||
}
|
||
|
||
COLORREF oldcolor = SetTextColor(hDC, color);
|
||
LOGFONT font;
|
||
G_GetThemeFont(m_hTheme, hDC,5,0,TMT_FONT,&font);
|
||
font.lfUnderline = TRUE;
|
||
HFONT hFont = NULL;
|
||
|
||
if(COXTaskPanel::IsThemed())
|
||
hFont = CreateFontIndirect(&font);
|
||
else
|
||
hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
|
||
|
||
HFONT hFontOld = (HFONT)SelectObject(hDC, hFont);
|
||
|
||
DrawTextEx(hDC,buff,it2->m_strText.GetLength(),
|
||
(LPRECT)&recGroupItem,DT_LEFT|DT_VCENTER|DT_SINGLELINE,NULL);
|
||
|
||
SetTextColor(hDC, oldcolor);
|
||
if(oldMode)
|
||
SetBkMode(hDC, oldMode);
|
||
SelectObject(hDC,hFontOld);
|
||
DeleteObject(hFont);
|
||
}
|
||
else
|
||
{
|
||
if(COXTaskPanel::IsThemed())
|
||
{
|
||
G_DrawThemeText(m_hTheme, hDC, 5, 0, it2->m_strText, it2->m_strText.GetLength(),
|
||
DT_LEFT|DT_VCENTER|DT_SINGLELINE,NULL,recGroupItem);
|
||
}
|
||
else
|
||
{
|
||
HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
|
||
LOGFONT lf = {0};
|
||
GetObject(hFont, sizeof(lf), &lf);
|
||
DeleteObject(hFont);
|
||
hFont = CreateFontIndirect(&lf);
|
||
HFONT hFontOld = (HFONT)SelectObject(hDC, hFont);
|
||
int oldMode = SetBkMode(hDC, TRANSPARENT);
|
||
DrawText(hDC,it2->m_strText,it2->m_strText.GetLength(),
|
||
(RECT*)&recGroupItem,DT_LEFT|DT_VCENTER|DT_SINGLELINE);
|
||
if(oldMode)
|
||
SetBkMode(hDC, oldMode);
|
||
SelectObject(hDC,hFontOld);
|
||
DeleteObject(hFont);
|
||
}
|
||
}
|
||
}
|
||
|
||
void COXTaskPanel::DrawGroupHeader(HDC hDC, const CRect& recGroupHeader, vector<TaskGroup>::iterator it)
|
||
{
|
||
if(COXTaskPanel::IsThemed())
|
||
{
|
||
G_DrawThemeBackground(m_hTheme, hDC, 8, 0, recGroupHeader, NULL);
|
||
G_DrawThemeEdge(m_hTheme, hDC, 8, 0, recGroupHeader,EDGE_SUNKEN,BF_FLAT,NULL);
|
||
}
|
||
else
|
||
FillRect(hDC,recGroupHeader,(HBRUSH)(COLOR_3DFACE + 1));
|
||
|
||
CString grpText = *it;
|
||
CRect recGroupText(recGroupHeader);
|
||
recGroupText.MoveToX(recGroupText.left + PDHeaderTextDisplacement);
|
||
if(COXTaskPanel::IsThemed())
|
||
G_DrawThemeText(m_hTheme, hDC, 8, 0, grpText, grpText.GetLength(),
|
||
DT_LEFT|DT_VCENTER|DT_SINGLELINE,NULL,recGroupText);
|
||
else
|
||
{
|
||
HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
|
||
LOGFONT lf = {0};
|
||
GetObject(hFont, sizeof(lf), &lf);
|
||
DeleteObject(hFont);
|
||
lf.lfWeight = FW_BOLD;
|
||
hFont = CreateFontIndirect(&lf);
|
||
HFONT hFontOld = (HFONT)SelectObject(hDC, hFont);
|
||
int oldMode = SetBkMode(hDC, TRANSPARENT);
|
||
DrawText(hDC,grpText,grpText.GetLength(),recGroupText,DT_VCENTER|DT_SINGLELINE);
|
||
if(oldMode)
|
||
SetBkMode(hDC, oldMode);
|
||
SelectObject(hDC,hFontOld);
|
||
DeleteObject(hFont);
|
||
}
|
||
|
||
CRect recGroupIcon(recGroupHeader.left + PDHeaderIconDisplacement,
|
||
recGroupHeader.top, recGroupHeader.right, recGroupHeader.bottom);
|
||
int iPart = 0;
|
||
if(it->m_bIsCollapsed)
|
||
iPart = 7;
|
||
else
|
||
iPart = 6;
|
||
if(it->m_bIsMouseHovered)
|
||
{
|
||
if(COXTaskPanel::IsThemed())
|
||
G_DrawThemeBackground(m_hTheme, hDC, iPart, 2, recGroupIcon, NULL);
|
||
else
|
||
{
|
||
CDC pDC;
|
||
pDC.Attach(hDC);
|
||
pDC.Draw3dRect(recGroupIcon,GetSysColor(COLOR_3DHILIGHT), GetSysColor(COLOR_3DSHADOW));
|
||
pDC.Detach();
|
||
if(it->m_bIsCollapsed)
|
||
{
|
||
DrawDownArrow(hDC, recGroupIcon);
|
||
}
|
||
else
|
||
{
|
||
DrawUpArrow(hDC, recGroupIcon);
|
||
}
|
||
}
|
||
m_bLastHover = true;
|
||
}
|
||
else
|
||
{
|
||
if(COXTaskPanel::IsThemed())
|
||
G_DrawThemeBackground(m_hTheme, hDC, iPart, 0, recGroupIcon, NULL);
|
||
else
|
||
{
|
||
if(it->m_bIsCollapsed)
|
||
{
|
||
DrawDownArrow(hDC, recGroupIcon);
|
||
}
|
||
else
|
||
{
|
||
DrawUpArrow(hDC, recGroupIcon);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void COXTaskPanel::DrawDownArrow(HDC hDC, const CRect& recGroupIcon)
|
||
{
|
||
LOGFONT lf = {0};
|
||
_tcscpy_s(lf.lfFaceName,LF_FACESIZE, _T("Marlett"));
|
||
lf.lfCharSet = DEFAULT_CHARSET;
|
||
HFONT hFont = CreateFontIndirect(&lf);
|
||
HFONT hFontOld = (HFONT)SelectObject(hDC, hFont);
|
||
int oldMode = SetBkMode(hDC, TRANSPARENT);
|
||
DrawText(hDC,_T("6"),1,(RECT*)&recGroupIcon,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
|
||
if(oldMode)
|
||
SetBkMode(hDC, oldMode);
|
||
SelectObject(hDC,hFontOld);
|
||
DeleteObject(hFont);
|
||
}
|
||
|
||
void COXTaskPanel::DrawUpArrow(HDC hDC, const CRect& recGroupIcon)
|
||
{
|
||
LOGFONT lf = {0};
|
||
_tcscpy_s(lf.lfFaceName,LF_FACESIZE,_T("Marlett"));
|
||
lf.lfCharSet = DEFAULT_CHARSET;
|
||
HFONT hFont = CreateFontIndirect(&lf);
|
||
HFONT hFontOld = (HFONT)SelectObject(hDC, hFont);
|
||
int oldMode = SetBkMode(hDC, TRANSPARENT);
|
||
DrawText(hDC,_T("5"),1,(RECT*)&recGroupIcon,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
|
||
if(oldMode)
|
||
SetBkMode(hDC, oldMode);
|
||
SelectObject(hDC,hFontOld);
|
||
DeleteObject(hFont);
|
||
}
|
||
|
||
void COXTaskPanel::DrawGroups(HDC hDC)
|
||
{
|
||
CRect recGroupHeader(PDLeftMargin, PDTopMargin,PDLeftMargin + PDHeaderWidth,PDTopMargin + PDHeaderHeight);
|
||
for(vector<TaskGroup>::iterator it = m_vecGroups.begin(); it != m_vecGroups.end(); it++)
|
||
{
|
||
it->m_HeaderRect = recGroupHeader;
|
||
DrawGroupHeader(hDC, recGroupHeader, it);
|
||
|
||
int sz = 0;
|
||
|
||
if((!it->m_bIsCollapsed) || (it->m_bIsCollapsed && it->m_bAnimationEnabled))
|
||
{
|
||
sz = (int)it->m_vecItems.size();
|
||
|
||
CRect recGroupBodySource(recGroupHeader.left, recGroupHeader.bottom,
|
||
recGroupHeader.right, recGroupHeader.bottom + (sz * PDGroupItemHeight));
|
||
|
||
if(it->m_bAnimationEnabled)
|
||
{
|
||
if(m_nAnimSteps == 0)
|
||
it->m_bAnimationEnabled = false;
|
||
else
|
||
{
|
||
if(m_nAnimSteps>0)
|
||
sz = (int) ((float)sz / (float)max(m_nAnimSteps,1));
|
||
else
|
||
sz = (int) ((float)sz / (float)max(NUMANIMSTEPS + m_nAnimSteps,1));
|
||
}
|
||
}
|
||
|
||
CRect recGroupBodyTarget(recGroupHeader.left, recGroupHeader.bottom,
|
||
recGroupHeader.right, recGroupHeader.bottom + (sz * PDGroupItemHeight));
|
||
|
||
HDC hDrawDC = hDC;
|
||
HDC tmpDC = NULL;
|
||
HBITMAP hbmap = NULL;
|
||
HBITMAP oldbmap = NULL;
|
||
|
||
CRect rect;
|
||
GetClientRect(&rect);
|
||
|
||
if(it->m_bAnimationEnabled)
|
||
{
|
||
tmpDC = CreateCompatibleDC(hDC);
|
||
hbmap = CreateCompatibleBitmap(hDC, rect.Width(), rect.Height());
|
||
oldbmap = (HBITMAP)SelectObject(tmpDC,hbmap);
|
||
hDrawDC = tmpDC;
|
||
}
|
||
|
||
if(!(it->m_bIsCollapsed && !it->m_bAnimationEnabled))
|
||
{
|
||
if(COXTaskPanel::IsThemed())
|
||
G_DrawThemeBackground(m_hTheme, hDrawDC, 5, 0, recGroupBodySource, NULL);
|
||
else
|
||
{
|
||
FillRect(hDrawDC,recGroupBodySource,(HBRUSH)(COLOR_WINDOW + 1));
|
||
HBRUSH hBrushFrame = (HBRUSH)GetSysColorBrush(COLOR_BTNFACE);
|
||
FrameRect(hDrawDC,recGroupBodySource,hBrushFrame);
|
||
}
|
||
|
||
CRect recGroupItem(recGroupBodySource.left + PDGroupItemLeftMargin,
|
||
recGroupBodySource.top,recGroupBodySource.right, recGroupBodySource.top + PDGroupItemHeight);
|
||
|
||
for(vector<Item>::iterator it2 = it->m_vecItems.begin();
|
||
it2 != it->m_vecItems.end(); it2++)
|
||
{
|
||
if(!recGroupBodyTarget.PtInRect(CPoint(recGroupItem.left,recGroupItem.top)))
|
||
break;
|
||
|
||
DrawGroupItem(hDrawDC,recGroupItem, it2);
|
||
recGroupItem.MoveToY(recGroupItem.bottom);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
sz = 0;
|
||
}
|
||
|
||
if(it->m_bAnimationEnabled)
|
||
{
|
||
RenderAlphaBlend(hDC, tmpDC, recGroupBodyTarget, recGroupBodySource);
|
||
SelectObject(tmpDC,oldbmap);
|
||
DeleteObject(hbmap);
|
||
DeleteDC(tmpDC);
|
||
}
|
||
}
|
||
recGroupHeader.MoveToY(recGroupHeader.top + PDGroupSeparatorWidth + (sz * PDGroupItemHeight));
|
||
}
|
||
|
||
AdjustScrollBars(recGroupHeader);
|
||
}
|
||
|
||
void COXTaskPanel::AdjustScrollBars(CRect recGroupHeader)
|
||
{
|
||
CRect rect;
|
||
GetClientRect(&rect);
|
||
|
||
if(!(recGroupHeader.top + PDHeaderHeight < rect.bottom))
|
||
{
|
||
ShowScrollBar(SB_VERT,TRUE);
|
||
SCROLLINFO si = {0};
|
||
si.cbSize = sizeof SCROLLBARINFO;
|
||
si.fMask = SIF_PAGE|SIF_RANGE;
|
||
si.nMin = 0;
|
||
si.nMax = recGroupHeader.top;
|
||
si.nPage = rect.Height();
|
||
SetScrollInfo(SB_VERT, &si, TRUE);
|
||
}
|
||
else
|
||
ShowScrollBar(SB_VERT,FALSE);
|
||
}
|
||
|
||
bool COXTaskPanel::RenderAlphaBlend(HDC hDC, HDC tmpDC, CRect recGroupBodyTarget, CRect recGroupBodySource)
|
||
{
|
||
BLENDFUNCTION bf = {0};
|
||
bf.BlendOp = AC_SRC_OVER;
|
||
if(m_nAnimSteps>0)
|
||
bf.SourceConstantAlpha = (BYTE)((float)255 * (float)(NUMANIMSTEPS-m_nAnimSteps)/(float)NUMANIMSTEPS);
|
||
else
|
||
bf.SourceConstantAlpha = (BYTE)((float)255 * (float)(-m_nAnimSteps)/(float)NUMANIMSTEPS);
|
||
bf.SourceConstantAlpha = min(bf.SourceConstantAlpha, 128);
|
||
return !(FALSE == AlphaBlend(hDC,recGroupBodyTarget.left,recGroupBodyTarget.top,
|
||
recGroupBodyTarget.Width(),recGroupBodyTarget.Height(),
|
||
tmpDC,recGroupBodySource.left,recGroupBodySource.top,
|
||
recGroupBodySource.Width(),recGroupBodySource.Height(),bf));
|
||
} |