DragonNest/Third/XTToolkitPro/Source/Calendar/XTPCalendarPaintManager.cpp
2024-12-19 09:48:26 +08:00

2496 lines
67 KiB
C++

// XTPCalendarPaintManager.cpp : implementation file
//
// This file is a part of the XTREME CALENDAR MFC class library.
// (c)1998-2008 Codejock Software, All Rights Reserved.
//
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
// CONSENT OF CODEJOCK SOFTWARE.
//
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
// SINGLE COMPUTER.
//
// CONTACT INFORMATION:
// support@codejock.com
// http://www.codejock.com
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <math.h>
#include "Resource.h"
#include "Common/XTPVC50Helpers.h"
#include "Common/XTPVC80Helpers.h"
#include "Common/XTPResourceManager.h"
#include "XTPCalendarControl.h"
#include "XTPCalendarPaintManager.h"
#include "XTPCalendarDayViewEvent.h"
#include "XTPCalendarEvent.h"
#include "XTPCalendarEventLabel.h"
#include "XTPCalendarDayView.h"
#include "XTPCalendarWeekView.h"
#include "XTPCalendarMonthView.h"
#include "XTPCalendarData.h"
#include "XTPCalendarDayViewTimeScale.h"
static const double dXTPMaxAlpha2003 = 75.;
static const LPCTSTR cszGlyphsFontName = _T("MS Outlook");
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
void CXTPCalendarPaintManager::CDayViewEventPart::OnDraw(CDC* pDC, CXTPCalendarDayViewEvent* pViewEvent)
{
if (!pDC || !pViewEvent || !pViewEvent->GetEvent() || !m_pPaintManager)
{
ASSERT(FALSE);
return;
}
CRect rcEvent(pViewEvent->GetEventRect());
if (rcEvent.IsRectEmpty())
{
return;
}
// fill event background
CXTPCalendarEventLabel* ptrLabel = pViewEvent->GetEvent()->GetLabel();
COLORREF crBackground = ptrLabel ? ptrLabel->m_clrColor : GetBackgroundColor();
BOOL bSelected = pViewEvent->IsSelected();
int nMDEFlags = pViewEvent->GetMultiDayEventFlags();
BOOL bMultiDay = (nMDEFlags & xtpCalendarMultiDayFMLmask) != 0;
DWORD dwAdditionalOpt = XTP_SAFE_GET3(pViewEvent, GetCalendarControl(), GetCalendarOptions(), dwAdditionalOptions, 0);
CString strLoc = pViewEvent->GetItemTextLocation();
CString strText = pViewEvent->GetItemTextSubject();
if (strLoc.GetLength() > 0)
{
if (dwAdditionalOpt & xtpCalendarOptDayViewNoWordBreak)
{
strText += _T("\n(") + strLoc + _T(")");
}
else
{
strText += _T(" (") + strLoc + _T(")");
}
}
CString strTime;
if (!bMultiDay)
{
COleDateTime dtStart = pViewEvent->GetEvent()->GetStartTime();
COleDateTime dtEnd = pViewEvent->GetEvent()->GetEndTime();
DWORD dwTimeFlags = xtpCalendarItemText_EventStartTimeText;
if (!CXTPCalendarUtils::IsEqual(dtStart, dtEnd))
dwTimeFlags = dwTimeFlags | xtpCalendarItemText_EventEndTimeText;
strTime = pViewEvent->GetItemText(dwTimeFlags, pViewEvent->HideEventTime() ? _T("") : NULL);
}
CRect rcBorder(rcEvent);
rcBorder.left += 1;
pDC->FillSolidRect(rcBorder, crBackground);
pDC->FillSolidRect(rcBorder.left, rcBorder.top, rcBorder.Width(), 1, m_pPaintManager->m_clrWindowText);
pDC->FillSolidRect(rcBorder.left - 1, rcBorder.bottom - (bMultiDay ? 1 : 0),
rcBorder.Width() + 1, 1, m_pPaintManager->m_clrWindowText);
if (!bMultiDay)
{
pDC->FillSolidRect(rcBorder.right, rcBorder.top, 1, rcBorder.Height()+1, m_pPaintManager->m_clrWindowText);
}
if (bSelected && bMultiDay)
{
pDC->FillSolidRect(rcEvent.left, rcEvent.top + 1, rcEvent.Width(), rcEvent.Height() - 2, m_pPaintManager->m_clrButtonFace);
pDC->FillSolidRect(rcEvent.left, rcEvent.top - 1, rcEvent.Width()+1, 1, m_pPaintManager->m_clrWindowText);
pDC->FillSolidRect(rcEvent.left, rcEvent.bottom, rcEvent.Width()+1, 1, m_pPaintManager->m_clrWindowText);
}
if (nMDEFlags & xtpCalendarMultiDayFirst)
{
pDC->FillSolidRect(rcEvent.left, rcEvent.top, 1, rcEvent.Height(), m_pPaintManager->m_clrWindowText);
rcEvent.left++;
if (pViewEvent->GetFirstClockRect().Width() > 0)
{
m_pPaintManager->DrawClock(
pDC,
pViewEvent->GetEvent()->GetStartTime(),
pViewEvent->GetFirstClockRect(),
crBackground,
xtpCalendarClockAlignLeft);
}
}
if (nMDEFlags & xtpCalendarMultiDayLast)
{
pDC->FillSolidRect(rcEvent.right, rcEvent.top, 1, rcEvent.Height(), m_pPaintManager->m_clrWindowText);
rcEvent.right -= 2;
if (pViewEvent->GetLastClockRect().Width() > 0)
{
m_pPaintManager->DrawClock(
pDC,
pViewEvent->GetEvent()->GetEndTime(),
pViewEvent->GetLastClockRect(),
crBackground,
xtpCalendarClockAlignLeft);
}
}
UINT uAlign = 0;
UINT uAlignWordBreak = 0;
CRect rcText(pViewEvent->GetTextRect());
CRect rcTime(rcText);
BOOL bTimeOutOfBorders = FALSE;
// draw busy border
if (!bMultiDay)
{
rcText.top += min(2, rcText.Height());
rcTime.top = rcText.top;
int nBusyStatus = pViewEvent->GetEvent()->GetBusyStatus();
// fill busy area
CRect rcBusyArea(rcEvent);
// draw border
rcBusyArea.right = rcBusyArea.left + 7;
//rcText.left = rcBusyArea.right + 3;
pDC->FillSolidRect(rcBusyArea, m_pPaintManager->m_clrWindowText);
// draw background
rcBusyArea.DeflateRect(1, 1, 1, 0);
pDC->FillSolidRect(rcBusyArea, m_pPaintManager->m_clrWindow);
if (pViewEvent->GetTimeframeRect().top == LONG_MAX ||
pViewEvent->GetTimeframeRect().bottom == LONG_MAX)
{
POINT arBusyPoints[] =
{
{rcEvent.left, rcEvent.top},
{rcEvent.left + 7, rcEvent.top},
{rcEvent.left + 7, rcEvent.top + 7},
{rcEvent.left, rcEvent.top}
};
const int cBPCount = sizeof(arBusyPoints) / sizeof(arBusyPoints[0]);
CRgn rgnBusy;
BOOL bRgn = rgnBusy.CreatePolygonRgn(arBusyPoints, cBPCount, ALTERNATE);
ASSERT(bRgn);
if (bRgn)
{
m_pPaintManager->DrawBusyStatus(pDC, rgnBusy, nBusyStatus);
}
}
else
{
// draw busy border
rcBusyArea.top = pViewEvent->GetTimeframeRect().top;
rcBusyArea.bottom = pViewEvent->GetTimeframeRect().bottom;
pDC->FillSolidRect(rcBusyArea, m_pPaintManager->m_clrWindowText);
// draw busy color
rcBusyArea.DeflateRect(0, 1, 0, 1);
m_pPaintManager->DrawBusyStatus(pDC, rcBusyArea, nBusyStatus);
}
// draw shadow
if (!bSelected)
m_pPaintManager->DrawShadow(pDC, pViewEvent->GetEventRect());
// draw border
if (bSelected)
{
CBrush brushBorder(m_pPaintManager->m_clrWindowText);
CRect rcBorder2(pViewEvent->GetEventRect());
rcBorder2.right += 1;
CRect rcBorderTop(rcBorder2);
rcBorderTop.bottom = rcBorderTop.top + 1;
rcBorderTop.top -= 5;
m_pPaintManager->DrawBusyStatus(pDC, rcBorderTop, nBusyStatus);
pDC->FrameRect(&rcBorderTop, &brushBorder);
CRect rcBorderBottom(rcBorder2);
rcBorderBottom.top = rcBorderBottom.bottom;
rcBorderBottom.bottom += 6;
m_pPaintManager->DrawBusyStatus(pDC, rcBorderBottom, nBusyStatus);
pDC->FrameRect(&rcBorderBottom, &brushBorder);
}
rcText.right -= 4;
uAlignWordBreak = (dwAdditionalOpt & xtpCalendarOptDayViewNoWordBreak) ? DT_WORD_ELLIPSIS : DT_WORDBREAK;
uAlign |= DT_LEFT | uAlignWordBreak | DT_EDITCONTROL;
//---------------------------------------------------------------------------
if (!strTime.IsEmpty())
{
CString strTest = strTime;
if (dwAdditionalOpt & xtpCalendarOptDayViewNoWordBreak)
strTest += _T(" W...");
CSize szTime = GetTextExtent(pDC, strTest);
if (szTime.cx <= rcText.Width())
{
strText = strTime + _T(" ") + strText;
strTime.Empty();
}
else
{
bTimeOutOfBorders = TRUE;
rcTime.bottom = rcTime.top + szTime.cy;
rcText.top = rcTime.bottom;
}
}
}
else
{
rcText.left += 3;
CSize szText = GetTextExtent(pDC, strText);
if (pViewEvent->IsMultyDayTextAlign() || szText.cx + 2 > rcText.Width())
{
uAlign |= DT_LEFT;
}
else
{
uAlign |= DT_CENTER;
}
uAlign |= DT_SINGLELINE;
}
m_pPaintManager->DrawIcons(pDC, pViewEvent);
// draw event time, if need
if (!strTime.IsEmpty())
{
DrawText(pDC, strTime, rcTime, DT_LEFT | DT_SINGLELINE | DT_VCENTER);
}
// draw event text
DrawText(pDC, strText, rcText, uAlign | DT_VCENTER);
// update OutOfBorders flag
int nX_need = 0, nY_need = 0;
if (uAlign & DT_SINGLELINE)
{
CSize szText = GetTextExtent(pDC, strText);
nX_need = szText.cx;
}
else
{
CRect rcNeeded(0, 0, rcText.Width(), 0);
DrawText(pDC, strText, rcNeeded, DT_CALCRECT | uAlignWordBreak);
nY_need = rcNeeded.Height();
}
BOOL bOutOfBorders = nY_need > rcText.Height() ||
nX_need > rcText.Width() ||
bTimeOutOfBorders;
pViewEvent->SetTextOutOfBorders(bOutOfBorders);
}
//////////////////////////////////////////////////////////////////////////
CXTPCalendarPaintManager::CXTPShadowDrawer::CXTPShadowDrawer(CDC* pDC, double dMaxAlpha)
: m_pDC(pDC), m_dMaxAlpha(dMaxAlpha)
{
ASSERT(m_pDC);
}
CXTPCalendarPaintManager::CXTPShadowDrawer::~CXTPShadowDrawer()
{
}
int CXTPCalendarPaintManager::CXTPShadowDrawer::CheckValue(int iValue)
{
return ((iValue > 255) ? 255 : ((iValue < 0) ? 0 : iValue));
}
COLORREF CXTPCalendarPaintManager::CXTPShadowDrawer::AlphaPixel(const COLORREF crPixel, const UINT i)
{
return RGB(
CheckValue(GetRValue(crPixel)-i),
CheckValue(GetGValue(crPixel)-i),
CheckValue(GetBValue(crPixel)-i));
}
void CXTPCalendarPaintManager::DrawShadow(CDC* pDC, const CRect& rcRect)
{
ASSERT(pDC);
if (!pDC || pDC->IsPrinting())
{
return;
}
CXTPShadowDrawer oShadow(pDC, dXTPMaxAlpha2003);
CRect rcVShadow(rcRect);
rcVShadow.left = rcVShadow.right;
rcVShadow.right += 5;
rcVShadow.top += 5;
oShadow.DrawShadowRectPart(rcVShadow, CXTPShadowDrawer::xtpShadowLR);
CRect rcHShadow(rcRect);
rcHShadow.left += 7;
rcHShadow.top = rcHShadow.bottom + 1;
rcHShadow.bottom += 6;
oShadow.DrawShadowRectPart(rcHShadow, CXTPShadowDrawer::xtpShadowTB);
CRect rcTRShadow(rcVShadow);
rcTRShadow.bottom = rcTRShadow.top;
rcTRShadow.top -= 5;
oShadow.DrawShadowRectPart(rcTRShadow, CXTPShadowDrawer::xtpShadowBR);
CRect rcBRShadow(rcVShadow);
rcBRShadow.top = rcBRShadow.bottom;
rcBRShadow.bottom += 5;
oShadow.DrawShadowRectPart(rcBRShadow, CXTPShadowDrawer::xtpShadowTR);
CRect rcBLShadow(rcRect);
rcBLShadow.right = rcBLShadow.left + 7;
rcBLShadow.top = rcBLShadow.bottom + 1;
rcBLShadow.bottom += 6;
oShadow.DrawShadowRectPart(rcBLShadow, CXTPShadowDrawer::xtpShadowBL);
}
void CXTPCalendarPaintManager::CXTPShadowDrawer::DrawShadowRectPart(const CRect& rcShadow, const XTPShadowPart part)
{
ASSERT(m_pDC);
if (!m_pDC || !m_pDC->GetSafeHdc())
{
return;
}
// start processing
HDC hdc; // handle of the DC we will create
HBITMAP hbitmap; // bitmap handle
BITMAPINFO bmi; // bitmap header
ULONG ulBitmapWidth, ulBitmapHeight; // bitmap width/height
VOID *pvBits; // pointer to DIB section
// create a DC for our bitmap -- the source DC for AlphaBlend
hdc = ::CreateCompatibleDC(m_pDC->GetSafeHdc());
if (!hdc)
return;
// setup bitmap info
// zero the memory for the bitmap info
ZeroMemory(&bmi, sizeof(BITMAPINFO));
// set the bitmap width and height. Later on, the blending will occur in the center of each of the three areas.
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = ulBitmapWidth = max(rcShadow.Width(), 0);
bmi.bmiHeader.biHeight = ulBitmapHeight = max(rcShadow.Height(), 0);
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32; // four 8-bit components
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = ulBitmapWidth * ulBitmapHeight * 4;
// create our DIB section and select the bitmap into the dc
if ((ulBitmapWidth > 0) && (ulBitmapHeight > 0))
{
hbitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, &pvBits, NULL, 0x0);
if (hbitmap)
{
HGDIOBJ hOld = SelectObject(hdc, hbitmap);
// Copy old picture values to the created bitmap
if (::BitBlt(hdc, 0, 0, ulBitmapWidth, ulBitmapHeight,
m_pDC->GetSafeHdc(), rcShadow.left, rcShadow.top, SRCCOPY))
{
// Adjust all pixels of the picture
switch (part)
{
case xtpShadowLR:
ApplyShadowLR((UINT*)pvBits, ulBitmapWidth, ulBitmapHeight);
break;
case xtpShadowTB:
ApplyShadowTB((UINT*)pvBits, ulBitmapWidth, ulBitmapHeight);
break;
case xtpShadowTR:
ApplyShadowTR((UINT*)pvBits, ulBitmapWidth, ulBitmapHeight);
break;
case xtpShadowBR:
ApplyShadowBR((UINT*)pvBits, ulBitmapWidth, ulBitmapHeight);
break;
case xtpShadowBL:
ApplyShadowBL((UINT*)pvBits, ulBitmapWidth, ulBitmapHeight);
break;
case xtpShadow2007Right:
ApplyShadow2007Right((UINT*)pvBits, ulBitmapWidth, ulBitmapHeight);
break;
case xtpShadow2007Bottom:
ApplyShadow2007Bottom((UINT*)pvBits, ulBitmapWidth, ulBitmapHeight);
break;
case xtpShadow2007TopRight:
ApplyShadow2007TR((UINT*)pvBits, ulBitmapWidth, ulBitmapHeight);
break;
case xtpShadow2007BottomLeft:
ApplyShadow2007BL((UINT*)pvBits, ulBitmapWidth, ulBitmapHeight);
break;
case xtpShadow2007BottomRight:
ApplyShadow2007BR((UINT*)pvBits, ulBitmapWidth, ulBitmapHeight);
break;
default:
break;
}
// Copy modified picture to the old DC
if (pvBits)
{
m_pDC->BitBlt(rcShadow.left, rcShadow.top, ulBitmapWidth, ulBitmapHeight, CDC::FromHandle(hdc), 0, 0, SRCCOPY);
}
}
// do cleanup
SelectObject(hdc, hOld);
DeleteObject(hbitmap);
}
}
// do cleanup
DeleteDC(hdc);
}
void CXTPCalendarPaintManager::CXTPShadowDrawer::ApplyShadowLR(UINT* pBitmap, const ULONG ulBitmapWidth, const ULONG ulBitmapHeight)
{
if (!pBitmap)
return;
UINT nAlpha = 0;
const double dPercentsPerPixel = m_dMaxAlpha / (double)ulBitmapWidth;
double dAlpha = m_dMaxAlpha;
for (ULONG x = 0; x < ulBitmapWidth; x++)
{
nAlpha = (UINT)dAlpha;
if (nAlpha != 0)
{
for (ULONG y = 0; y < ulBitmapHeight; y++)
{
UINT uiPixel = pBitmap[x + y * ulBitmapWidth];
pBitmap[x + y * ulBitmapWidth] = AlphaPixel(uiPixel, nAlpha);
}
}
dAlpha -= dPercentsPerPixel;
}
}
void CXTPCalendarPaintManager::CXTPShadowDrawer::ApplyShadowTB(UINT* pBitmap, const ULONG ulBitmapWidth, const ULONG ulBitmapHeight)
{
if (!pBitmap)
return;
UINT nAlpha = 0;
const double dPercentsPerPixel = m_dMaxAlpha / (double)ulBitmapHeight;
double dAlpha = 0;
for (ULONG y = 0; y < ulBitmapHeight; y++)
{
nAlpha = (UINT)(dAlpha);
if (nAlpha != 0)
{
for (ULONG x = 0; x < ulBitmapWidth; x++)
{
UINT uiPixel = pBitmap[x + y * ulBitmapWidth];
pBitmap[x + y * ulBitmapWidth] = AlphaPixel(uiPixel, nAlpha);
}
}
dAlpha += dPercentsPerPixel;
}
}
void CXTPCalendarPaintManager::CXTPShadowDrawer::ApplyShadowTR(UINT* pBitmap, const ULONG ulBitmapWidth, const ULONG ulBitmapHeight)
{
if (!pBitmap)
return;
UINT nAlpha = 0;
const double dPercentsPerPixel = m_dMaxAlpha / (double)min(ulBitmapWidth, ulBitmapHeight);
for (ULONG y = 0; y < ulBitmapHeight; y++)
{
for (ULONG x = 0; x < ulBitmapWidth; x++)
{
nAlpha = (UINT)(m_dMaxAlpha - sqrt((double)(ulBitmapHeight - y)*(x)) * dPercentsPerPixel);
nAlpha = min(nAlpha, (UINT)((ulBitmapWidth - x) * dPercentsPerPixel));
nAlpha = min(nAlpha, (UINT)((y + 1) * dPercentsPerPixel));
if (nAlpha != 0)
{
UINT uiPixel = pBitmap[x + y * ulBitmapWidth];
pBitmap[x + y * ulBitmapWidth] = AlphaPixel(uiPixel, nAlpha);
}
}
}
}
void CXTPCalendarPaintManager::CXTPShadowDrawer::ApplyShadow2007Right(UINT* pBitmap, const ULONG ulBitmapWidth, const ULONG ulBitmapHeight)
{
if (!pBitmap)
return;
ASSERT(5 == ulBitmapWidth); // ToDo: make shadow rect more than 5x? pixels
static const UINT uiShadow[5] = {38, 34, 30, 27, 25};
UINT nAlpha = 0;
for (ULONG y = 0; y < ulBitmapHeight; y++)
{
for (ULONG x = 0; x < ulBitmapWidth; x++)
{
nAlpha = uiShadow[x];
if (nAlpha != 0)
{
UINT uiPixel = pBitmap[x + y * ulBitmapWidth];
pBitmap[x + y * ulBitmapWidth] = AlphaPixel(uiPixel, nAlpha);
}
}
}
}
void CXTPCalendarPaintManager::CXTPShadowDrawer::ApplyShadow2007Bottom(UINT* pBitmap, const ULONG ulBitmapWidth, const ULONG ulBitmapHeight)
{
if (!pBitmap)
return;
static const UINT uiShadow[3] = {50, 40, 25};
UINT nAlpha = 0;
for (ULONG y = 0; y < ulBitmapHeight; y++)
{
if (0 == y)
nAlpha = uiShadow[2];
else if (1 == y)
nAlpha = uiShadow[1];
else
nAlpha = uiShadow[0];
for (ULONG x = 0; x < ulBitmapWidth; x++)
{
if (nAlpha != 0)
{
UINT uiPixel = pBitmap[x + y * ulBitmapWidth];
pBitmap[x + y * ulBitmapWidth] = AlphaPixel(uiPixel, nAlpha);
}
}
}
}
void CXTPCalendarPaintManager::CXTPShadowDrawer::ApplyShadow2007TR(UINT* pBitmap, const ULONG ulBitmapWidth, const ULONG ulBitmapHeight)
{
if (!pBitmap)
return;
ASSERT(5 == ulBitmapWidth); // ToDo: make shadow rect more than 5x6 pixels
ASSERT(6 == ulBitmapHeight);
static const UINT nShadowTR[6][5] =
{
{22, 17, 7, 0, 0},
{31, 33, 35, 15, 0},
{32, 30, 28, 34, 10},
{35, 32, 29, 30, 21},
{37, 33, 30, 27, 25},
{38, 34, 30, 27, 25}
};
UINT nAlpha = 0;
for (ULONG y = 0; y < ulBitmapHeight; y++)
{
for (ULONG x = 0; x < ulBitmapWidth; x++)
{
nAlpha = nShadowTR[5-y][x];
if (nAlpha != 0)
{
UINT uiPixel = pBitmap[x + y * ulBitmapWidth];
pBitmap[x + y * ulBitmapWidth] = AlphaPixel(uiPixel, nAlpha);
}
}
}
}
void CXTPCalendarPaintManager::CXTPShadowDrawer::ApplyShadow2007BL(UINT* pBitmap, const ULONG ulBitmapWidth, const ULONG ulBitmapHeight)
{
if (!pBitmap)
return;
ASSERT(5 == ulBitmapHeight); // ToDo: make shadow rect more than 5x6 pixels
ASSERT(5 == ulBitmapWidth);
static const UINT uiShadowBL[5][5] =
{
{33, 30, 34, 44, 50},
{19, 33, 33, 40, 50},
{10, 35, 30, 35, 43},
{ 0, 18, 35, 30, 33},
{ 0, 0, 11, 24, 25}
};
UINT nAlpha = 0;
for (ULONG y = 0; y < ulBitmapHeight; y++)
{
for (ULONG x = 0; x < ulBitmapWidth; x++)
{
nAlpha = uiShadowBL[4-y][x];
if (nAlpha != 0)
{
UINT uiPixel = pBitmap[x + y * ulBitmapWidth];
pBitmap[x + y * ulBitmapWidth] = AlphaPixel(uiPixel, nAlpha);
}
}
}
}
void CXTPCalendarPaintManager::CXTPShadowDrawer::ApplyShadow2007BR(UINT* pBitmap, const ULONG ulBitmapWidth, const ULONG ulBitmapHeight)
{
if (!pBitmap)
return;
ASSERT(3+5 == ulBitmapHeight); // ToDo: make shadow rect more than 5x6 pixels
ASSERT(3+5 == ulBitmapWidth);
static const UINT uiShadowBL[8][8] =
{
{255,255,200,255,255,255,255,255},
{255,255,200,255,255,255,255,255},
{200,200,205,255,255,255,255,255},
{255,255,255,213,215,219,224,230},
{255,255,255,217,219,223,224,233},
{255,255,255,219,221,225,221,241},
{255,255,255,226,226,221,236,254},
{255,255,255,230,231,241,254,255}
};
UINT nAlpha = 0;
for (ULONG y = 0; y < ulBitmapHeight; y++)
{
for (ULONG x = 0; x < ulBitmapWidth; x++)
{
nAlpha = 255 - uiShadowBL[7-y][x];
if (nAlpha != 0)
{
UINT uiPixel = pBitmap[x + y * ulBitmapWidth];
pBitmap[x + y * ulBitmapWidth] = AlphaPixel(uiPixel, nAlpha);
}
}
}
}
void CXTPCalendarPaintManager::CXTPShadowDrawer::ApplyShadowBR(UINT* pBitmap, const ULONG ulBitmapWidth, const ULONG ulBitmapHeight)
{
if (!pBitmap)
return;
UINT nAlpha = 0;
const double dPercentsPerPixel = m_dMaxAlpha / (double)min(ulBitmapHeight, ulBitmapWidth);
for (ULONG y = 0; y < ulBitmapHeight; y++)
{
for (ULONG x = 0; x < ulBitmapWidth; x++)
{
nAlpha = (UINT)(m_dMaxAlpha - sqrt((double)y * x) * dPercentsPerPixel);
nAlpha = min(nAlpha, (UINT)((ulBitmapWidth - x) * dPercentsPerPixel));
nAlpha = min(nAlpha, (UINT)((ulBitmapHeight - y) * dPercentsPerPixel));
if (nAlpha != 0)
{
UINT uiPixel = pBitmap[x + y * ulBitmapWidth];
pBitmap[x + y * ulBitmapWidth] = AlphaPixel(uiPixel, nAlpha);
}
}
}
}
void CXTPCalendarPaintManager::CXTPShadowDrawer::ApplyShadowBL(UINT* pBitmap, const ULONG ulBitmapWidth, const ULONG ulBitmapHeight)
{
if (!pBitmap)
return;
UINT nAlpha = 0;
const double dPercentsPerPixel = m_dMaxAlpha / (double)min(ulBitmapHeight, ulBitmapWidth);
for (ULONG y = 0; y < ulBitmapHeight; y++)
{
for (ULONG x = 0; x < ulBitmapWidth; x++)
{
nAlpha = (UINT)(m_dMaxAlpha - sqrt((double)(ulBitmapHeight - y)*(ulBitmapWidth - x)) * dPercentsPerPixel);
nAlpha = min(nAlpha, (UINT)(x * dPercentsPerPixel));
nAlpha = min(nAlpha, (UINT)((y) * dPercentsPerPixel));
if (nAlpha != 0)
{
UINT uiPixel = pBitmap[x + y * ulBitmapWidth];
pBitmap[x + y * ulBitmapWidth] = AlphaPixel(uiPixel, nAlpha);
}
}
}
}
void CXTPCalendarPaintManager::CDayViewTimeScaleCellPart::RefreshMetrics()
{
m_nHourWidth = m_nMinWidth = 0;
LOGFONT lfIcon;
VERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfIcon), &lfIcon, 0));
STRCPY_S(lfIcon.lfFaceName, LF_FACESIZE, _T("Tahoma"));
m_fntTimeText.SetStandardValue(&lfIcon);
}
void CXTPCalendarPaintManager::CDayViewTimeScaleCellPart::CalcWidth(CDC* pDC,
const CString& strHour, const CString& strMin,
int nHourHeight, int& nWidth)
{
ASSERT(pDC);
if (!pDC || !m_pPaintManager)
return;
CSize szMin(0, 0), szHour(0, 0);
{
CXTPFontDC fnt(pDC, &GetTextFont());
szMin = pDC->GetTextExtent(strMin);
}
{
CRect rcDefaultCell(0, 0, 100, nHourHeight);
AdjustTimeFont(pDC, rcDefaultCell);
CXTPFontDC fnt(pDC, m_fntTimeText);
szHour = pDC->GetTextExtent(strHour);
// check also widest hours number
CSize szHour2 = pDC->GetTextExtent(_T("88"), 2);
if (szHour2.cx > szHour.cx)
{
szHour = szHour2;
}
}
m_nHourWidth = szHour.cx;
m_nMinWidth = szMin.cx;
nWidth = max(42, szHour.cx + szMin.cx + 17);
}
void CXTPCalendarPaintManager::CDayViewTimeScaleCellPart::AdjustTimeFont(CDC* pDC, CRect rcCell)
{
ASSERT(pDC);
if (!pDC)
{
return;
}
rcCell.DeflateRect(5, 6, 1, 7);
LOGFONT lfIcon;
((CFont*)m_fntTimeText)->GetLogFont(&lfIcon);
CSize szText;
{
CXTPFontDC fontBig(pDC, m_fntTimeText);
szText = pDC->GetTextExtent(_T("88"), 2);
}
int nParam1 = rcCell.Width() * szText.cy;
int nParam2 = rcCell.Height() * szText.cx;
if (nParam1 > nParam2)
{
lfIcon.lfHeight = ::MulDiv(lfIcon.lfHeight, rcCell.Height(), szText.cy);
}
else
{
lfIcon.lfHeight = ::MulDiv(lfIcon.lfHeight, rcCell.Width(), szText.cx);
}
m_fntTimeText.SetStandardValue(&lfIcon);
}
void CXTPCalendarPaintManager::CDayViewTimeScaleCellPart::DrawHourCell(CDC* pDC, CRect rc, CString strText, BOOL bFillBackground)
{
if (!pDC || !m_pPaintManager)
{
ASSERT(FALSE);
return;
}
if (bFillBackground)
pDC->FillSolidRect(rc, GetBackgroundColor());
pDC->FillSolidRect(rc.right - 1, rc.top, 1, rc.Height(), m_pPaintManager->m_clr3DShadow);
rc.DeflateRect(0, 0, 4, 0);
DrawText(pDC, strText, rc, DT_VCENTER | DT_RIGHT | DT_SINGLELINE);
rc.DeflateRect(5, 0, 0, 0);
pDC->FillSolidRect(rc.left, rc.bottom - 1, rc.Width(), 1, m_pPaintManager->m_clr3DShadow);
}
void CXTPCalendarPaintManager::CDayViewTimeScaleCellPart::DrawBigHourCell(CDC* pDC, CRect rc, CString strHour, CString strMin, int nRowPerHour, BOOL bFillBackground)
{
if (!pDC || !m_pPaintManager)
{
ASSERT(FALSE);
return;
}
// Fill background
if (bFillBackground)
pDC->FillSolidRect(rc, GetBackgroundColor());
pDC->FillSolidRect(rc.right - 1, rc.top, 1, rc.Height(), m_pPaintManager->m_clr3DShadow);
// Calculate coordinates
CRect rcMinutesText(rc);
rcMinutesText.bottom = rcMinutesText.top + rc.Height() / nRowPerHour;
rcMinutesText.left += m_nHourWidth + 10;
CRect rcHoursText(rc);
rcHoursText.right = rcMinutesText.left;
rcHoursText.DeflateRect(0, 4, 4, 7);
// Draw hours text
CXTPFontDC fontBig(pDC, m_fntTimeText, GetTextColor());
pDC->DrawText(strHour, rcHoursText, DT_TOP | DT_RIGHT | DT_SINGLELINE | DT_NOCLIP);
// draw minutes text
DrawText(pDC, strMin, rcMinutesText, DT_VCENTER | DT_LEFT | DT_SINGLELINE | DT_NOCLIP);
// draw small lines
if (nRowPerHour > 2)
{
BOOL bShowMinutes = XTP_SAFE_GET3(m_pPaintManager, m_pControl, GetCalendarOptions(), bDayView_TimeScaleShowMinutes, FALSE);
CString strMinEx;
for (int i = 1; i < nRowPerHour; i++)
{
int y = rc.top + i * rc.Height() / nRowPerHour;
pDC->FillSolidRect(rcMinutesText.left, y - 1, rcMinutesText.Width(), 1, m_pPaintManager->m_clr3DShadow);
//------------------------------------------
if (bShowMinutes)
{
int nMinEx = 60 / nRowPerHour * i;
strMinEx.Format(_T("%02d"), nMinEx);
CRect rcMinEx = rcMinutesText;
rcMinEx.top = y;
rcMinEx.bottom = y + rc.Height();
DrawText(pDC, strMinEx, rcMinEx, DT_TOP | DT_LEFT | DT_SINGLELINE | DT_NOCLIP);
}
}
}
// draw line below
rc.DeflateRect(5, 0, 4, 0);
pDC->FillSolidRect(rc.left, rc.bottom - 1, rc.Width(), 1, m_pPaintManager->m_clr3DShadow);
}
void CXTPCalendarPaintManager::CDayViewTimeScaleHeaderPart::OnDraw(CDC* pDC, CXTPCalendarDayView* /*pView*/, CRect rc, CString strText)
{
if (!pDC || !m_pPaintManager)
{
ASSERT(FALSE);
return;
}
pDC->FillSolidRect(rc, GetBackgroundColor());
pDC->FillSolidRect(rc.right - 1, rc.top, 1, rc.Height(), m_pPaintManager->m_clr3DShadow);
rc.DeflateRect(1, 0, 4, 0);
pDC->FillSolidRect(rc.left, rc.bottom - 1, rc.Width(), 1, m_pPaintManager->m_clr3DShadow);
rc.DeflateRect(1, 2);
DrawText(pDC, strText, rc, DT_BOTTOM | DT_LEFT | DT_SINGLELINE);
}
void CXTPCalendarPaintManager::CDayViewTimeScaleHeaderPart::DrawNowLine(CDC* pDC,
CXTPCalendarDayView* pView, CRect rc, int y, BOOL bDrawBk)
{
if (!pDC || !pView || !m_pPaintManager)
{
ASSERT(FALSE);
return;
}
int nHeight = GETTOTAL_MINUTES_DTS(pView->GetScaleInterval()) >= 60 ? 5 : 10;
CRect rcNowLine = rc;
rcNowLine.top = y - nHeight;
rcNowLine.bottom = y + 1;
rcNowLine.left += 5;
rcNowLine.right -= 1;
BOOL bXPTheme = m_pPaintManager->GetCurrentSystemTheme() != xtpSystemThemeUnknown;
if (bDrawBk)
{
if (bXPTheme)
{
XTPDrawHelpers()->GradientFill(pDC, &rcNowLine, m_pPaintManager->m_grclrToday, FALSE);
}
}
else
{
rcNowLine.top = rcNowLine.bottom - 1;
pDC->FillSolidRect(&rcNowLine, m_pPaintManager->m_clrUnderLineHdr);
}
}
void CXTPCalendarPaintManager::CDayViewTimeScaleHeaderPart::DrawExpandSigns(CDC* pDC,
CXTPCalendarDayView* pView, const CRect& rcTSHours)
{
if (!pDC || !pView || !m_pPaintManager)
{
ASSERT(FALSE);
return;
}
// draw expand signs
CRect rcSignUp(rcTSHours);
CRect rcSignDown(rcTSHours);
CSize szSign(m_pPaintManager->GetExpandSignSize());
rcSignUp.left = rcTSHours.right - szSign.cx;
rcSignDown.left = rcTSHours.right - szSign.cx;
rcSignDown.top = rcSignDown.bottom - szSign.cy;
CImageList* pilExpSgn = &m_pPaintManager->m_ilExpandSigns;
if (pView->IsExpandUp())
{
m_pPaintManager->DrawBitmap(pilExpSgn, pDC, rcSignUp,
CXTPCalendarPaintManager::idxExpandSignUp);
}
if (pView->IsExpandDown())
{
m_pPaintManager->DrawBitmap(pilExpSgn, pDC, rcSignDown,
CXTPCalendarPaintManager::idxExpandSignDown);
}
}
void CXTPCalendarPaintManager::CDayViewCellPart::GetParams(CXTPCalendarDayViewGroup* pViewGroup,
XTP_CALENDAR_DAYVIEWCELL_PARAMS& rCellParams)
{
if (!pViewGroup || !m_pPaintManager)
{
ASSERT(FALSE);
return;
}
rCellParams.clrBackgroundColor = rCellParams.bSelected ? m_pPaintManager->m_clrHighlight : GetBackgroundColor();
}
void CXTPCalendarPaintManager::CDayViewCellPart::OnDraw(CDC* pDC,
CXTPCalendarDayViewGroup* pViewGroup, CRect rc,
const XTP_CALENDAR_DAYVIEWCELL_PARAMS& cellParams)
{
if (!pDC || !pViewGroup || !m_pPaintManager)
{
ASSERT(FALSE);
return;
}
COleDateTime dtTime = cellParams.dtBeginTime;
CRect rcBusyStatus(rc);
rcBusyStatus.right = rcBusyStatus.left + 6;
pDC->FillSolidRect(&rcBusyStatus, m_pPaintManager->m_clrWindow);
int nDayBusyStatus = pViewGroup->GetBusyStatus(dtTime);
if (nDayBusyStatus != xtpCalendarBusyStatusUnknown)
{
m_pPaintManager->DrawBusyStatus(pDC, rcBusyStatus, nDayBusyStatus);
}
if (XTP_SAFE_GET2(pViewGroup, GetViewDay(), GetDayIndex(), 0) != 0 ||
pViewGroup->GetGroupIndex() != 0)
{
pDC->FillSolidRect(rc.left, rc.top, 1, rc.Height(), m_pPaintManager->m_clrWindowText);
}
int nDayDeviderX = 0;//pViewGroup->GetGroupIndex() ? -2 : 0;
pDC->FillSolidRect(rc.left + 6 + nDayDeviderX, rc.top, 1, rc.Height(), m_pPaintManager->m_clrWindowText);
rc.left += 7 + nDayDeviderX;
if (m_pPaintManager->GetPaintTheme() >= xtpCalendarThemeOffice2003 ||
cellParams.bSelected)
{
pDC->FillSolidRect(rc, cellParams.clrBackgroundColor);
}
else
{
WORD arBits[2] = {0xAA, 0x55};
// Use the bit pattern to create a bitmap.
CBitmap bm;
bm.CreateBitmap(8,2,1,1, arBits);
CBrush brush;
brush.CreatePatternBrush(&bm);
COLORREF clrTxt0 = pDC->SetTextColor(cellParams.clrBackgroundColor);
COLORREF clrBk0 = pDC->SetBkColor(m_clrBackgroundSlave);
pDC->FillRect(rc, &brush);
pDC->SetTextColor(clrTxt0);
pDC->SetBkColor(clrBk0);
}
if (dtTime.GetMinute() == 0 && dtTime.GetHour() != 0)
{
pDC->FillSolidRect(rc.left, rc.top - 1, rc.Width(), 1, m_clrHour);
}
pDC->FillSolidRect(rc.left, rc.bottom - 1, rc.Width(), 1, m_clrShadow);
}
void CXTPCalendarPaintManager::CDayViewAllDayEventsPart::OnDraw(CDC* pDC,
CXTPCalendarDayViewGroup* pViewGroup, CRect rc, BOOL bSelected)
{
if (!pDC || !pViewGroup || !pViewGroup->GetViewDay() || !m_pPaintManager)
{
ASSERT(FALSE);
return;
}
if (bSelected)
{
pDC->FillSolidRect(rc, m_pPaintManager->m_clrWindow);
pDC->FillSolidRect(rc.left, rc.top, rc.Width(), 1, m_pPaintManager->m_clr3DShadow);
pDC->FillSolidRect(rc.left, rc.bottom - 1, rc.Width(), 1, m_pPaintManager->m_clr3DShadow);
}
else
{
pDC->FillSolidRect(rc, GetBackgroundColor());
}
if (pViewGroup->GetViewDay()->GetDayIndex() || pViewGroup->GetGroupIndex())
{
pDC->FillSolidRect(rc.left, rc.top + 1, 1, rc.Height() - 2, 0);
}
}
void CXTPCalendarPaintManager::CDayViewHeaderPart::OnDraw(CDC* pDC,
CXTPCalendarDayViewDay* pViewDay, CRect rc, CString strText)
{
if (!pDC || !pViewDay || !pViewDay->GetView() || !m_pPaintManager)
{
ASSERT(FALSE);
return;
}
BOOL bIsCurrent = FALSE;
COleDateTime dtCurrent = CXTPCalendarUtils::GetCurrentTime();
dtCurrent = CXTPCalendarUtils::ResetTime(dtCurrent);
COleDateTime dtDay;
bIsCurrent = pViewDay->GetDayDate() == dtCurrent;
pDC->FillSolidRect(rc, GetBackgroundColor());
CRect rcHeader(rc);
m_pPaintManager->DrawHeader(pDC, rcHeader, FALSE, bIsCurrent);
BOOL bFirstDay = pViewDay->GetDayIndex() == 0;
BOOL bLastDay = pViewDay->GetDayIndex() == pViewDay->GetView()->GetViewDayCount() - 1;
pDC->FillSolidRect(rc.left, rc.top, rc.Width(), 1, m_clrTopLeftBorder);
pDC->FillSolidRect(rc.left, rc.top + (bFirstDay ? 0: 2), 1, rc.Height() - (bFirstDay ? 0 : 3), m_clrTopLeftBorder);
pDC->FillSolidRect(rc.right - 1, rc.top + (bLastDay ? 0: 2), 1, rc.Height() - (bLastDay ? 0 : 3), m_pPaintManager->m_clr3DShadow);
rc.DeflateRect(2, 0, 2, 0);
DrawLine_CenterLR(pDC, strText, rc, DT_VCENTER);
}
void CXTPCalendarPaintManager::CDayViewGroupHeaderPart::OnDraw(CDC* pDC,
CXTPCalendarDayViewGroup* pViewGroup, CRect rc, CString strText)
{
if (!pDC || !pViewGroup || !pViewGroup->GetViewDay() || !m_pPaintManager)
{
ASSERT(FALSE);
return;
}
pDC->FillSolidRect(rc, GetBackgroundColor());
CRect rcHeader(rc);
m_pPaintManager->DrawHeader(pDC, rcHeader, FALSE, FALSE);
CXTPCalendarDayViewDay* pViewDay = pViewGroup->GetViewDay();
BOOL bFirstGroup = pViewDay->GetDayIndex() == 0 &&
pViewGroup->GetGroupIndex() == 0;
BOOL bLastGroup = pViewDay->GetDayIndex() == pViewDay->GetView()->GetViewDayCount() - 1 &&
pViewGroup->GetGroupIndex() == pViewDay->GetViewGroupsCount() - 1; ;
pDC->FillSolidRect(rc.left, rc.top, rc.Width(), 1, m_clrTopLeftBorder);
pDC->FillSolidRect(rc.left, rc.top + (bFirstGroup ? 0: 2), 1, rc.Height() - (bFirstGroup ? 0 : 3), m_clrTopLeftBorder);
pDC->FillSolidRect(rc.right - 1, rc.top + (bLastGroup ? 0: 2), 1, rc.Height() - (bLastGroup ? 0 : 3), m_pPaintManager->m_clr3DShadow);
rc.DeflateRect(2, 0, 2, 0);
DrawLine_CenterLR(pDC, strText, rc, DT_VCENTER);
}
void CXTPCalendarPaintManager::DrawHeader(CDC* pDC, CRect& rcHeader,
BOOL bIsSelected, BOOL bIsCurrent)
{
DrawHeader(pDC, rcHeader, bIsSelected, bIsCurrent, m_grclrToday,
m_clrUnderLineHdr);
}
void CXTPCalendarPaintManager::DrawHeader(CDC* pDC, CRect& rcHeader,
BOOL bIsSelected, BOOL bIsCurrent, const CXTPPaintManagerColorGradient& grclr, COLORREF clrUnderLineHdr)
{
ASSERT(pDC);
if (!pDC)
{
return;
}
if (!bIsSelected)
pDC->FillSolidRect(rcHeader, m_clrButtonFace);
if (bIsCurrent)
{
if (grclr.clrDark != grclr.clrLight)
{
XTPDrawHelpers()->GradientFill(pDC, &rcHeader, grclr, FALSE);
}
else
{
pDC->FillSolidRect(rcHeader, grclr.clrDark);
}
pDC->FillSolidRect(rcHeader.left, rcHeader.bottom -1 ,
rcHeader.Width(), 1, clrUnderLineHdr);
}
if (bIsSelected)
{
pDC->FillSolidRect(rcHeader, m_clrHighlight);
}
}
void CXTPCalendarPaintManager::CWeekViewPart::DrawDayHeader(CDC* pDC,
CRect rcDay, int nHeaderHeight,
CString strHeader, BOOL bIsCurrent, BOOL bIsSelected)
{
if (!pDC || !m_pPaintManager)
{
ASSERT(FALSE);
return;
}
if (m_pPaintManager->GetPaintTheme() != xtpCalendarThemeOffice2003)
{
bIsCurrent = FALSE;
}
CRect rcHeader(rcDay);
// draw header top line
m_pPaintManager->DrawHorizontalLine(pDC, rcDay.left + 1, rcDay.top,
rcDay.Width()+1);
rcHeader.DeflateRect(2, 2, 1, rcHeader.Height() - nHeaderHeight - 1);
CRect rcText(rcHeader);
rcText.DeflateRect(1, 0, 3, 1);
// draw header contents
CRect rcHeader2(rcHeader);
rcHeader2.bottom -= 1;
if (bIsCurrent && bIsSelected)
{
m_pPaintManager->DrawHeader(pDC, rcHeader2, FALSE, bIsCurrent);
CRect rcSel = CRect(rcHeader2);
CSize szText = GetTextExtent(pDC, strHeader);
rcSel.left = rcSel.right - (szText.cx + 7);
rcSel.bottom--;
m_pPaintManager->DrawHeader(pDC, rcSel, bIsSelected, FALSE);
}
else
{
m_pPaintManager->DrawHeader(pDC, rcHeader2, bIsSelected, bIsCurrent);
}
// draw header bottom line
if (!bIsCurrent)
{
CRect rcBottomLine(rcHeader);
rcBottomLine.top = --rcBottomLine.bottom - 1;
if (!bIsSelected)
rcBottomLine.DeflateRect(2, 0, 2, 0);
pDC->FillSolidRect(rcBottomLine, m_clrHeaderBottomLine);
}
// draw header text
pDC->SetBkMode(TRANSPARENT);
SetTextColor(bIsSelected ? m_clrTextHighLightColor : m_clrTextNormalColor);
DrawText(pDC, strHeader, rcText, DT_VCENTER | DT_RIGHT | DT_SINGLELINE);
}
void CXTPCalendarPaintManager::CWeekViewPart::OnDraw(CDC* pDC, CXTPCalendarWeekView* pWeekView)
{
if (!pDC || !pWeekView || !m_pPaintManager)
{
ASSERT(FALSE);
return;
}
CRect rcView(pWeekView->GetViewRect());
pDC->FillSolidRect(rcView, m_clrBackground);
//draw grid
int nDayWidth = pWeekView->GetDayWidth();
m_pPaintManager->DrawVerticalLine(pDC, rcView.left + nDayWidth - 1, rcView.top, rcView.bottom);
// draw headers
BOOL bIsSelected = FALSE;
BOOL bIsCurrent = FALSE;
COleDateTime dtCurrent = CXTPCalendarUtils::ResetTime(COleDateTime::GetCurrentTime());
COleDateTime dtDay;
int nDayHeaderHeight = pWeekView->GetDayHeaderHeight();
for (int nDay = 0; nDay < 7; nDay++)
{
CXTPCalendarWeekViewDay* pWDay = pWeekView->GetViewDay(nDay);
ASSERT(pWDay);
if (!pWDay)
{
continue;
}
CString strDate = pWDay->GetCaption();
dtDay = pWDay->GetDayDate();
bIsSelected = pWDay->IsSelected();
bIsCurrent = CXTPCalendarUtils::IsEqual(dtDay, dtCurrent);
//-------------------------------------------------------------
DrawDayHeader(pDC, pWDay->GetDayRect(), nDayHeaderHeight,
strDate, bIsCurrent, bIsSelected);
}
}
void CXTPCalendarPaintManager::CWeekViewEventPart::DrawBorder(CDC* pDC,
CRect rcView, CXTPCalendarWeekViewEvent* pWeekViewEvent)
{
if (!pDC || !pWeekViewEvent || !pWeekViewEvent->GetEvent() || !m_pPaintManager)
{
ASSERT(FALSE);
return;
}
int nBorderWidth = pWeekViewEvent->IsSelected() ? 2 : 1;
int nMDEFlags = pWeekViewEvent->GetMultiDayEventFlags();
BOOL bAllDay = pWeekViewEvent->GetEvent()->IsAllDayEvent();
if (pWeekViewEvent->IsSelected() &&
(nMDEFlags & xtpCalendarMultiDayFirst ||
nMDEFlags & xtpCalendarMultiDayLast ||
nMDEFlags & xtpCalendarMultiDayMiddle)
)
{
rcView.top--;
rcView.bottom++;
}
if (bAllDay ||
nMDEFlags & xtpCalendarMultiDayFirst ||
nMDEFlags & xtpCalendarMultiDayLast ||
nMDEFlags & xtpCalendarMultiDayMiddle)
{
pDC->FillSolidRect(rcView.left, rcView.top , rcView.Width(), nBorderWidth, m_clrTextNormalColor);
pDC->FillSolidRect(rcView.left, rcView.bottom - nBorderWidth, rcView.Width(), nBorderWidth, m_clrTextNormalColor);
}
if (nMDEFlags & xtpCalendarMultiDayFirst)
{
pDC->FillSolidRect(rcView.left, rcView.top, 1, rcView.Height(), m_clrTextNormalColor);
}
if (nMDEFlags & xtpCalendarMultiDayLast)
{
pDC->FillSolidRect(rcView.right, rcView.top, 1, rcView.Height(), m_clrTextNormalColor);
}
}
int CXTPCalendarPaintManager::CWeekViewEventPart::DrawTimes(CDC* pDC, CXTPCalendarWeekViewEvent* pWeekViewEvent)
{
if (!pDC || !pWeekViewEvent || !pWeekViewEvent->GetEvent() || !m_pPaintManager)
{
ASSERT(FALSE);
return 0;
}
COLORREF clrBackground = pWeekViewEvent->IsSelected() ? m_pPaintManager->m_clrHighlight : m_clrBackground;
CXTPCalendarEventLabel* ptrLabel = pWeekViewEvent->GetEvent()->GetLabel();
COLORREF clrLabel = ptrLabel ? ptrLabel->m_clrColor : clrBackground;
clrBackground = clrLabel;
CRect rcStart(pWeekViewEvent->GetStartTimeRect());
CRect rcEnd(pWeekViewEvent->GetEndTimeRect());
COleDateTime dtStart(pWeekViewEvent->GetEvent()->GetStartTime());
if (pWeekViewEvent->IsTimeAsClock())
{
m_pPaintManager->DrawClock(pDC, dtStart, rcStart, clrBackground, xtpCalendarClockAlignCenter);
}
else
{
CString strStartTime = pWeekViewEvent->GetItemTextStartTime();
DrawLineEx(pDC, strStartTime, &rcStart, DT_RIGHT | DT_VCENTER, DT_LEFT | DT_VCENTER);
}
if (pWeekViewEvent->IsShowEndTime())
{
COleDateTime dtEnd(pWeekViewEvent->GetEvent()->GetEndTime());
if (pWeekViewEvent->IsTimeAsClock())
{
m_pPaintManager->DrawClock(pDC, dtEnd, rcEnd, clrBackground, xtpCalendarClockAlignCenter);
}
else
{
CString strEndTime = pWeekViewEvent->GetItemTextEndTime();
DrawLineEx(pDC, strEndTime, &rcEnd, DT_RIGHT | DT_VCENTER, DT_LEFT | DT_VCENTER);
}
}
return 0;
}
void CXTPCalendarPaintManager::CWeekViewEventPart::DrawSubj(CDC* pDC,
CXTPCalendarWeekViewEvent* pWeekViewEvent)
{
if (!pDC || !pWeekViewEvent || !pWeekViewEvent->GetEvent() || !m_pPaintManager)
{
ASSERT(FALSE);
return;
}
CRect rcText(pWeekViewEvent->GetTextRect());
CString strLoc = pWeekViewEvent->GetItemTextLocation();
CString strEventText = pWeekViewEvent->GetItemTextSubject();
if (strLoc.GetLength() > 0)
{
strEventText += _T(" (") + strLoc + _T(")");
}
int nDayEventFlags = pWeekViewEvent->GetMultiDayEventFlags();
int nAlign = DT_CENTER;
if (pWeekViewEvent->IsMultyDayTextAlign() || GetTextExtent(pDC, strEventText).cx >= rcText.Width())
nAlign = DT_LEFT;
//nAlign
if (pWeekViewEvent->GetEvent()->IsAllDayEvent() ||
nDayEventFlags & xtpCalendarMultiDayFirst ||
nDayEventFlags & xtpCalendarMultiDayMiddle ||
nDayEventFlags & xtpCalendarMultiDayLast
)
DrawText(pDC, strEventText, &rcText, nAlign | DT_VCENTER | DT_SINGLELINE);
else
DrawText(pDC, strEventText, &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
}
void CXTPCalendarPaintManager::CWeekViewEventPart::OnDraw(CDC* pDC,
CXTPCalendarWeekViewEvent* pWeekViewEvent)
{
if (!pDC || !pWeekViewEvent || !pWeekViewEvent->GetEvent() || !m_pPaintManager)
{
ASSERT(FALSE);
return;
}
CRect rcView(pWeekViewEvent->GetViewEventRect());
CRect rcViewMax(rcView);
CString strEventText;
BOOL bSelected = pWeekViewEvent->IsSelected();
int nDayEventFlags = pWeekViewEvent->GetMultiDayEventFlags();
BOOL bMday = (nDayEventFlags & xtpCalendarMultiDayFMLmask) != 0;
BOOL bAllDay = pWeekViewEvent->GetEvent()->IsAllDayEvent();
CXTPCalendarEventLabel* ptrLabel = pWeekViewEvent->GetEvent()->GetLabel();
BOOL bLabel = (ptrLabel && ptrLabel->m_nLabelID != XTP_CALENDAR_NONE_LABEL_ID);
COLORREF clrBackground = m_clrBackground;
SetTextColor(m_clrTextNormalColor);
if (bMday || bAllDay)
clrBackground = RGB(255, 255, 255);
if (bLabel && ptrLabel)
clrBackground = ptrLabel->m_clrColor;
if (bSelected)
{
rcViewMax.CopyRect(pWeekViewEvent->GetViewEventRectMax());
clrBackground = m_pPaintManager->m_clrHighlight;
SetTextColor(m_clrTextHighLightColor);
}
if (bMday || bAllDay)
pDC->FillSolidRect(rcView, clrBackground);
else
pDC->FillSolidRect(rcViewMax, clrBackground);
// Draw border for long event
DrawBorder(pDC, rcView, pWeekViewEvent);
// Draw Clock for Long Events
if (nDayEventFlags & xtpCalendarMultiDayFirst)
{
m_pPaintManager->DrawClock(pDC,
pWeekViewEvent->GetEvent()->GetStartTime(),
pWeekViewEvent->GetFirstClockRect(),
clrBackground,
xtpCalendarClockAlignLeft);
}
else if (nDayEventFlags & xtpCalendarMultiDayLast)
{
m_pPaintManager->DrawClock(pDC,
pWeekViewEvent->GetEvent()->GetEndTime(),
pWeekViewEvent->GetLastClockRect(),
clrBackground,
xtpCalendarClockAlignRight);
}
// 3 Draw time start/end and icons
clrBackground = bSelected ? m_pPaintManager->m_clrHighlight : m_clrBackground;
if (!bMday && !bAllDay)
{
DrawTimes(pDC, pWeekViewEvent);
}
m_pPaintManager->DrawIcons(pDC, pWeekViewEvent);
// 5 Draw Text
DrawSubj(pDC, pWeekViewEvent);
}
void CXTPCalendarPaintManager::CMonthViewGridPart::OnDrawGrid(CDC* pDC,
CXTPCalendarMonthView* pMonthView)
{
if (!pDC || !pMonthView || !pMonthView->GetGrid() ||
!pMonthView->GetCalendarControl() || !m_pPaintManager)
{
ASSERT(FALSE);
return;
}
COLORREF clrGridLine = RGB(0, 0, 0);
BOOL bCompressWeD = pMonthView->GetCalendarControl()->MonthView_IsCompressWeekendDays();
int nWeeksCount = pMonthView->GetGrid()->GetWeeksCount();
COleDateTime dtNow = CXTPCalendarUtils::GetCurrentTime();
int nCurrentMonth = dtNow.GetMonth();
int nWhiteMonthColorIdx = nCurrentMonth % 2;
for (int nWeek = 0; nWeek < nWeeksCount; nWeek++)
{
for (int nDayIdx = 0; nDayIdx < 7; nDayIdx++)
{
COleDateTime dtDay = pMonthView->GetGrid()->GetDayDate(nWeek, nDayIdx);
CRect rcB = pMonthView->GetGrid()->GetDayRect(nWeek, nDayIdx, TRUE);
//Draw Grid lines
if (nWeek > 0)
{
pDC->FillSolidRect(rcB.left, rcB.top, rcB.Width(), 1, clrGridLine);
}
if (nWeek < nWeeksCount-1)
{
pDC->FillSolidRect(rcB.left, rcB.bottom, rcB.Width(), 1, clrGridLine);
}
int nWDay = dtDay.GetDayOfWeek();
BOOL bCompressedCol_Su = bCompressWeD && nDayIdx == 1 && nWDay == 1;
if (nDayIdx > 0 && !bCompressedCol_Su)
{
pDC->FillSolidRect(rcB.left, rcB.top, 1, rcB.Height(), clrGridLine);
}
//Fill Grid cells background
CRect rcDay = pMonthView->GetGrid()->GetDayRect(nWeek, nDayIdx, FALSE);
int nMonth = dtDay.GetMonth();
COLORREF clrBackground = nMonth % 2 == nWhiteMonthColorIdx ? m_clrBackground : m_clrBackground2;
if (nDayIdx == 0)
{
rcDay.left--;
}
pDC->FillSolidRect(&rcDay, clrBackground);
}
}
}
void CXTPCalendarPaintManager::CMonthViewHeaderPart::OnDraw(CDC* pDC,
CXTPCalendarMonthView* pMonthView, CRect rc,
int nCollIndex, CString strText)
{
if (!pDC || !pMonthView || !pMonthView->GetGrid() || !m_pPaintManager)
{
ASSERT(FALSE);
return;
}
pDC->FillSolidRect(rc, GetBackgroundColor());
BOOL bFirstDay = nCollIndex == 0;
BOOL bLastDay = nCollIndex == pMonthView->GetGrid()->GetColsCount() - 1;
pDC->FillSolidRect(rc.left, rc.top, rc.Width(), 1, m_clrTopLeftBorder);
pDC->FillSolidRect(rc.left, rc.top + (bFirstDay ? 0: 2), 1, rc.Height() - (bFirstDay ? 1 : 3), m_clrTopLeftBorder);
pDC->FillSolidRect(rc.right - 1, rc.top + (bLastDay ? 0: 2), 1, rc.Height() - (bLastDay ? 1 : 3), m_pPaintManager->m_clr3DShadow);
pDC->FillSolidRect(rc.left, rc.bottom, rc.Width(), 1, m_pPaintManager->m_clr3DShadow);
rc.DeflateRect(2, 0, 2, 0);
DrawLine_CenterLR(pDC, strText, rc, DT_VCENTER);
}
void CXTPCalendarPaintManager::CMonthViewEventPart::OnDrawDayDate(CDC* pDC,
CRect rc, BOOL bToday,
BOOL bSelected, CString strText)
{
if (!pDC || !m_pPaintManager)
{
ASSERT(FALSE);
return;
}
rc.DeflateRect(1, 1, 1, 1);
BOOL bXPTheme = m_pPaintManager->GetCurrentSystemTheme() != xtpSystemThemeUnknown;
if (m_pPaintManager->GetPaintTheme() != xtpCalendarThemeOffice2003)
{
bXPTheme = bToday = FALSE;
}
if (bSelected && bToday)
{
CRect rcSel = CRect(rc);
CRect rcUnSel = CRect(rc);
CSize szText = GetTextExtent(pDC, strText);
rcSel.left = rcSel.right - (szText.cx + 7);
rcUnSel.right = rcUnSel.left + rcUnSel.Width() - (szText.cx + 7);
if (bXPTheme)
m_pPaintManager->DrawHeader(pDC, rcUnSel, FALSE, bToday);
else
m_pPaintManager->DrawHeader(pDC, rcUnSel, FALSE, bToday,
m_grclrClassicSelDay, m_clrClassicUnderline);
m_pPaintManager->DrawHeader(pDC, rcSel, bSelected, FALSE);
}
else
if (bSelected || bToday)
{
if (bXPTheme)
m_pPaintManager->DrawHeader(pDC, rc, bSelected, bToday);
else
m_pPaintManager->DrawHeader(pDC, rc, bSelected, bToday,
m_grclrClassicSelDay, m_clrClassicUnderline);
}
if (bSelected)
{
SetTextColor(m_clrTextHighLightColor);
}
rc.DeflateRect(0, 0, 5, 0);
DrawText(pDC, strText, rc, DT_VCENTER | DT_RIGHT | DT_SINGLELINE);
m_clrTextColor.SetDefaultValue();
}
void CXTPCalendarPaintManager::CMonthViewEventPart::OnDrawEvent(CDC* pDC,
CXTPCalendarMonthViewEvent* pViewEvent)
{
if (!pDC || !pViewEvent || !pViewEvent->GetEvent() || !m_pPaintManager)
{
ASSERT(FALSE);
return;
}
CRect rcEvent = pViewEvent->GetEventRect();
CRect rcText = pViewEvent->GetTextRect();
CXTPCalendarEvent* prtEvent = pViewEvent->GetEvent();
BOOL bSelected = pViewEvent->IsSelected();
int nMDEFlags = pViewEvent->GetMultiDayEventFlags();
CRect rcClockFirst(0, 0, 0, 0);
CRect rcClockLast(0, 0, 0, 0);
COleDateTime dtClockFirst;
COleDateTime dtClockLast;
COLORREF clrBackground;
if (nMDEFlags & xtpCalendarMultiDayFirst)
{
rcClockFirst.CopyRect(pViewEvent->GetFirstClockRect());
dtClockFirst = pViewEvent->GetEvent()->GetStartTime();
}
if (nMDEFlags & xtpCalendarMultiDayLast)
{
rcClockLast.CopyRect(pViewEvent->GetLastClockRect());
dtClockLast = pViewEvent->GetEvent()->GetEndTime();
}
if (bSelected)
{
if (nMDEFlags & xtpCalendarMultiDayFMLmask)
{
rcEvent.top--;
rcEvent.bottom++;
}
else
{
rcEvent.left = pViewEvent->m_rcEventMax.left + 2;
rcEvent.right = pViewEvent->m_rcEventMax.right - 2;
}
SetTextColor(m_clrTextHighLightColor);
clrBackground = m_pPaintManager->m_clrHighlight;
pDC->FillSolidRect(&rcEvent, m_pPaintManager->m_clrHighlight);
clrBackground = m_pPaintManager->m_clrHighlight;
}
else
{
CXTPCalendarEventLabel* ptrLabel = pViewEvent->GetEvent()->GetLabel();
COLORREF clrLabel = ptrLabel ? ptrLabel->m_clrColor : RGB(255, 255, 255);
BOOL bNoneLabel = ptrLabel ? (ptrLabel->m_nLabelID == XTP_CALENDAR_NONE_LABEL_ID) : TRUE;
clrBackground = clrLabel;
if (nMDEFlags & xtpCalendarMultiDayFMLmask || !bNoneLabel)
{
pDC->FillSolidRect(&rcEvent, clrLabel);
}
}
UINT uAlign = DT_LEFT;
CString strLoc = pViewEvent->GetItemTextLocation();
CString strText = pViewEvent->GetItemTextSubject();
if (strLoc.GetLength() > 0)
{
strText += _T(" (") + strLoc + _T(")");
}
if (nMDEFlags & xtpCalendarMultiDayFMLmask)
{
int nBY = bSelected ? 2 : 1;
pDC->FillSolidRect(rcEvent.left, rcEvent.top, rcEvent.Width(), nBY, m_clrMultiDayEventFrameColor);
pDC->FillSolidRect(rcEvent.left, rcEvent.bottom - nBY, rcEvent.Width(), nBY, m_clrMultiDayEventFrameColor);
if (nMDEFlags & xtpCalendarMultiDayFirst)
{
pDC->FillSolidRect(rcEvent.left, rcEvent.top, 1, rcEvent.Height(), m_clrMultiDayEventFrameColor);
}
if (nMDEFlags & xtpCalendarMultiDayLast)
{
pDC->FillSolidRect(rcEvent.right, rcEvent.top, 1, rcEvent.Height(), m_clrMultiDayEventFrameColor);
}
//CSize szSpace = GetTextExtent(pDC, _T(" "));
rcText.left += 1;//min(1, szSpace.cx/2);
rcText.right -= 1;
CSize szText = GetTextExtent(pDC, strText);
if (pViewEvent->IsMultyDayTextAlign() || szText.cx > rcText.Width())
uAlign = DT_LEFT;
else
uAlign = DT_CENTER;
}
// draw clocks for multyday events
if ((nMDEFlags & xtpCalendarMultiDayFirst) || (nMDEFlags & xtpCalendarMultiDayLast))
{
if (rcClockFirst.Width() > 0)
m_pPaintManager->DrawClock(
pDC,
dtClockFirst,
rcClockFirst,
clrBackground,
xtpCalendarClockAlignLeft);
if (rcClockLast.Width() > 0)
m_pPaintManager->DrawClock(
pDC,
dtClockLast,
rcClockLast,
clrBackground,
xtpCalendarClockAlignLeft);
}
//CRect rcText = pViewEvent->GetTextRect();
if (nMDEFlags & xtpCalendarMultiDayNoMultiDay)
{
//IsTimeAsClock()
COleDateTime dtStart(prtEvent->GetStartTime());
COleDateTime dtEnd(prtEvent->GetEndTime());
CString strStartTime = pViewEvent->GetItemTextStartTime();
CString strEndTime = pViewEvent->GetItemTextEndTime();
CRect rcStart(pViewEvent->GetStartTimeRect());
CRect rcEnd(pViewEvent->GetEndTimeRect());
if (pViewEvent->IsTimeAsClock())
{
m_pPaintManager->DrawClock(pDC, dtStart, rcStart, clrBackground, xtpCalendarClockAlignCenter);
m_pPaintManager->DrawClock(pDC, dtEnd, rcEnd, clrBackground, xtpCalendarClockAlignCenter);
}
else
{
DrawLineEx(pDC, strStartTime, rcStart, DT_RIGHT | DT_VCENTER, DT_LEFT | DT_VCENTER );
DrawLineEx(pDC, strEndTime, rcEnd, DT_RIGHT | DT_VCENTER, DT_LEFT | DT_VCENTER );
}
}
DrawText(pDC, strText, rcText, uAlign | DT_VCENTER | DT_SINGLELINE);
m_pPaintManager->DrawIcons(pDC, pViewEvent);
m_clrTextColor.SetDefaultValue();
}
/////////////////////////////////////////////////////////////////////////////
// CXTPCalendarPaintManager
#define ADDVIEWPART(theClass, parent)\
m_p##theClass = (C##theClass*)AddViewPart(new C##theClass(m_p##parent));
CXTPCalendarPaintManager::CXTPCalendarPaintManager()
{
m_pGlyphsFont = NULL;
m_szClockRect.cx = 15;
m_szClockRect.cy = 15;
m_szExpandSign.cx = m_szExpandSign.cy = 0;
m_pControl = NULL;
m_bEnableTheme = TRUE;
m_dwAskItemTextFlags = 0;
m_pControlPart = (CControlPart*)AddViewPart(new CControlPart());
ADDVIEWPART(DayViewTimeScaleHeaderPart, ControlPart);
ADDVIEWPART(DayViewTimeScaleCellPart, DayViewTimeScaleHeaderPart);
ADDVIEWPART(DayViewCellPart, ControlPart);
ADDVIEWPART(DayViewWorkCellPart, DayViewCellPart);
ADDVIEWPART(DayViewNonworkCellPart, DayViewCellPart);
ADDVIEWPART(DayViewHeaderPart, ControlPart);
ADDVIEWPART(DayViewGroupHeaderPart, ControlPart);
ADDVIEWPART(DayViewAllDayEventsPart, ControlPart);
ADDVIEWPART(DayViewEventPart, ControlPart);
ADDVIEWPART(WeekViewPart, ControlPart);
ADDVIEWPART(WeekViewEventPart, ControlPart);
ADDVIEWPART(MonthViewGridPart, ControlPart);
ADDVIEWPART(MonthViewHeaderPart, ControlPart);
ADDVIEWPART(MonthViewEventPart, ControlPart);
//-----------------------------------------------------------------------
CBitmap bmpSignUp, bmpSignDown;
VERIFY(XTPResourceManager()->LoadBitmap(&bmpSignUp, XTP_IDB_CALENDAR_EXPANDSIGNUP) );
VERIFY(XTPResourceManager()->LoadBitmap(&bmpSignDown, XTP_IDB_CALENDAR_EXPANDSIGNDOWN) );
CSize szSexpandSign = GetExpandSignSize();
VERIFY(m_ilExpandSigns.Create(szSexpandSign.cx, szSexpandSign.cy, ILC_COLOR24 | ILC_MASK, 0, 1));
COLORREF clrMask = RGB(255, 0, 255);
m_ilExpandSigns.Add(&bmpSignUp, clrMask);
m_ilExpandSigns.Add(&bmpSignDown, clrMask);
//-----------------------------------------------------------------------
VERIFY(m_ilGlyphs.Create(16, 11, ILC_COLOR24 | ILC_MASK, 0, 1));
CBitmap bmp;
VERIFY(XTPResourceManager()->LoadBitmap(&bmp, XTP_IDB_CALENDAR_EVENT_GLYPHS));
m_ilGlyphs.Add(&bmp, RGB(255, 0, 255));
m_CurrSystemTheme = xtpSystemThemeUnknown;
m_nPaintTheme = xtpCalendarThemeOffice2003;
RefreshMetrics();
}
CXTPCalendarPaintManager::~CXTPCalendarPaintManager()
{
while (!m_lstViewParts.IsEmpty())
{
delete m_lstViewParts.RemoveHead();
}
SAFE_DELETE(m_pGlyphsFont);
}
void CXTPCalendarPaintManager::RefreshMetrics()
{
RefreshXtremeColors();
m_clrButtonFace.SetStandardValue(GetSysColor(COLOR_BTNFACE));
m_clrButtonFaceText.SetStandardValue(GetSysColor(COLOR_BTNTEXT));
m_clrWindow.SetStandardValue(GetSysColor(COLOR_WINDOW));
m_clrWindowText.SetStandardValue(GetSysColor(COLOR_WINDOWTEXT));
m_clr3DShadow.SetStandardValue(GetSysColor(COLOR_3DSHADOW));
m_clrHighlight.SetStandardValue(GetSysColor(COLOR_HIGHLIGHT));
InitBusyStatusDefaultColors();
POSITION pos = m_lstViewParts.GetHeadPosition();
while (pos)
{
CXTPCalendarViewPart* pPart = m_lstViewParts.GetNext(pos);
ASSERT(pPart);
if (pPart)
{
pPart->RefreshMetrics();
}
}
m_grclrToday.SetStandardValue(m_clrButtonFace, m_clrButtonFace);
m_clrUnderLineHdr = m_clrHighlight;
if (m_nPaintTheme >= xtpCalendarThemeOffice2003)
{
m_CurrSystemTheme = xtpSystemThemeUnknown;
if (m_bEnableTheme && !XTPColorManager()->IsLunaColorsDisabled())
{
m_CurrSystemTheme = XTPColorManager()->GetCurrentSystemTheme();
if (m_CurrSystemTheme != xtpSystemThemeUnknown)
{
m_grclrToday.SetStandardValue(m_clrButtonFace, RGB(250, 203, 91));
m_clrUnderLineHdr = RGB(187, 85, 3);
}
}
}
//-----------------------------------------------------------------------
SAFE_DELETE(m_pGlyphsFont);
BOOL bFontExists = XTPDrawHelpers()->FontExists(cszGlyphsFontName);
if (bFontExists)
{
m_pGlyphsFont = new CFont();
if (m_pGlyphsFont)
{
LOGFONT lfGlupth;
::ZeroMemory(&lfGlupth, sizeof(lfGlupth));
STRCPY_S(lfGlupth.lfFaceName, LF_FACESIZE, cszGlyphsFontName);
lfGlupth.lfCharSet = SYMBOL_CHARSET;
lfGlupth.lfHeight = -11;
lfGlupth.lfWeight = FW_NORMAL;
if (!m_pGlyphsFont->CreateFontIndirect(&lfGlupth))
{
SAFE_DELETE(m_pGlyphsFont);
}
}
}
if (!m_pGlyphsFont)
{
TRACE(_T("WARNING! Calendar PaintManeger: cannot create 'MS Outlook' font. Standard bitmaps are used. \n"));
}
}
void CXTPCalendarPaintManager::CDayViewWorkCellPart::RefreshMetrics()
{
if (m_pPaintManager->GetPaintTheme() <= xtpCalendarThemeOffice2000 ||
m_pPaintManager->GetPaintTheme() == xtpCalendarThemeOfficeXP)
{
if (m_pPaintManager->GetPaintTheme() <= xtpCalendarThemeOffice2000)
m_clrBackground.SetStandardValue(RGB(255, 255, 255));
else
m_clrBackground.SetStandardValue(RGB(255, 255, 0));
m_clrBackgroundSlave.SetStandardValue(RGB(255, 255, 255));
m_clrShadow.SetStandardValue(RGB(128, 128, 128));
m_clrHour.SetStandardValue(RGB(128, 128, 128));
}
else if (m_pPaintManager->GetPaintTheme() >= xtpCalendarThemeOffice2003)
{
m_clrBackground.SetStandardValue(RGB(255, 255, 213));
m_clrShadow.SetStandardValue(RGB(243, 228, 177));
m_clrHour.SetStandardValue(RGB(234, 208, 152));
}
else {
ASSERT(FALSE);
}
}
void CXTPCalendarPaintManager::CDayViewNonworkCellPart::RefreshMetrics()
{
if (m_pPaintManager->GetPaintTheme() <= xtpCalendarThemeOffice2000 ||
m_pPaintManager->GetPaintTheme() == xtpCalendarThemeOfficeXP)
{
m_clrBackground.SetStandardValue(RGB(255, 255, 0));
m_clrBackgroundSlave.SetStandardValue(RGB(128, 128, 128));
if (m_pPaintManager->GetPaintTheme() <= xtpCalendarThemeOffice2000)
{
m_clrBackground.SetStandardValue(RGB(212, 208, 200));
m_clrBackgroundSlave.SetStandardValue(RGB(212, 208, 200));
}
m_clrShadow.SetStandardValue(RGB(128, 128, 128));
m_clrHour.SetStandardValue(RGB(128, 128, 128));
}
else if (m_pPaintManager->GetPaintTheme() >= xtpCalendarThemeOffice2003)
{
m_clrBackground.SetStandardValue(RGB(255, 244, 188));
m_clrBackgroundSlave.SetStandardValue(RGB(255, 244, 188));
m_clrShadow.SetStandardValue(RGB(243, 228, 177));
m_clrHour.SetStandardValue(RGB(234, 208, 152));
}
else {
ASSERT(FALSE);
}
}
void CXTPCalendarPaintManager::CMonthViewGridPart::RefreshMetrics()
{
if (m_pPaintManager->GetPaintTheme() <= xtpCalendarThemeOffice2000 ||
m_pPaintManager->GetPaintTheme() == xtpCalendarThemeOfficeXP)
{
m_clrBackground.SetStandardValue(RGB(255, 255, 255));
m_clrBackground2.SetStandardValue(RGB(215, 211, 203));
}
else if (m_pPaintManager->GetPaintTheme() >= xtpCalendarThemeOffice2003)
{
m_clrBackground.SetStandardValue(RGB(255, 255, 213));
m_clrBackground2.SetStandardValue(RGB(255, 244, 188));
}
else {
ASSERT(FALSE);
}
}
void CXTPCalendarPaintManager::CWeekViewPart::RefreshMetrics()
{
m_clrTextColor.SetStandardValue(m_pPaintManager->m_clrButtonFaceText);
m_clrTextHighLightColor = RGB(255, 255, 255);
m_clrTextNormalColor = m_pPaintManager->m_clrButtonFaceText;
m_clrHeaderBottomLine = m_pPaintManager->m_clr3DShadow;
LOGFONT lfIcon;
VERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfIcon), &lfIcon, 0));
m_fntText.SetStandardValue(&lfIcon);
if (m_pPaintManager->GetPaintTheme() <= xtpCalendarThemeOffice2000 ||
m_pPaintManager->GetPaintTheme() == xtpCalendarThemeOfficeXP)
{
m_clrBackground.SetStandardValue(RGB(255, 255, 255));
}
else if (m_pPaintManager->GetPaintTheme() >= xtpCalendarThemeOffice2003)
{
m_clrBackground.SetStandardValue(RGB(255, 255, 213));
}
else {
ASSERT(FALSE);
}
}
CXTPCalendarViewPart* CXTPCalendarPaintManager::AddViewPart(CXTPCalendarViewPart* pPart)
{
ASSERT(pPart);
if (pPart)
{
m_lstViewParts.AddTail(pPart);
pPart->m_pPaintManager = this;
}
return pPart;
}
void CXTPCalendarPaintManager::DrawLine(CDC* pDC, int x, int y, int cx, int cy)
{
ASSERT(pDC);
if (!pDC)
{
return;
}
pDC->MoveTo(x, y);
pDC->LineTo(x + cx, y + cy);
}
void CXTPCalendarPaintManager::DrawHorizontalLine(CDC* pDC, int x, int y, int cx)
{
DrawLine(pDC, x, y, cx, 0);
}
void CXTPCalendarPaintManager::DrawVerticalLine(CDC* pDC, int x, int y, int cy)
{
DrawLine(pDC, x, y, 0, cy);
}
int CXTPCalendarPaintManager::DrawBitmap(CImageList* pImageList, CDC* pDC,
CRect rcView, int iIcon, UINT uFlags)
{
ASSERT(pImageList && pDC);
if (!pImageList || !pDC)
{
return 0;
}
int nImageBound = rcView.left;
if (rcView.left >= rcView.right - 2)
return nImageBound;
POINT ptIcon;
IMAGEINFO imgInf;
if (!pImageList->GetImageInfo(iIcon, &imgInf))
return nImageBound;
CSize szImage(imgInf.rcImage.right - imgInf.rcImage.left, imgInf.rcImage.bottom - imgInf.rcImage.top);
CSize szView(rcView.Size());
ptIcon.x = rcView.left;
ptIcon.y = rcView.top;
szImage.cx = min(szImage.cx, szView.cx);
if (uFlags & DT_VCENTER)
{
ptIcon.y = rcView.top + (szView.cy - szImage.cy) /2 + 1;
}
IMAGELISTDRAWINDIRECT_S(pImageList, pDC, iIcon, ptIcon, szImage);
return szImage.cx;
}
int CXTPCalendarPaintManager::DrawBitmap(UINT nIDResource, CDC* pDC, CRect rcBitmap)
{
ASSERT(pDC);
if (!pDC)
{
return 0;
}
CBitmap bmpIcon;
if (!XTPResourceManager()->LoadBitmap(&bmpIcon, nIDResource))
return 0;
BITMAP bmpInfo;
bmpIcon.GetBitmap(&bmpInfo);
CImageList ilBitmap;
VERIFY(ilBitmap.Create(bmpInfo.bmWidth, bmpInfo.bmHeight, ILC_COLOR24 | ILC_MASK, 0, 1));
ilBitmap.Add(&bmpIcon, RGB(255, 0 , 255));
CRect rcBitmap2 = rcBitmap;
rcBitmap2.bottom = rcBitmap2.top + bmpInfo.bmHeight;
DrawBitmap(&ilBitmap, pDC, rcBitmap2, 0);
return bmpInfo.bmWidth;
}
CSize CXTPCalendarPaintManager::GetBitmapSize(UINT nIDResource)
{
CBitmap bmpIcon;
VERIFY(XTPResourceManager()->LoadBitmap(&bmpIcon, nIDResource));
BITMAP bmpInfo;
bmpIcon.GetBitmap(&bmpInfo);
CSize szIcon(bmpInfo.bmWidth, bmpInfo.bmHeight);
return szIcon;
}
const CSize CXTPCalendarPaintManager::GetExpandSignSize()
{
// if sign size is not initialized, initialize it
if (!(m_szExpandSign.cx | m_szExpandSign.cy))
{
m_szExpandSign = GetBitmapSize(XTP_IDB_CALENDAR_EXPANDSIGNDOWN);
}
return m_szExpandSign;
}
int CXTPCalendarPaintManager::DrawClock(CDC* pDC, COleDateTime dtClockTime,
CRect rcView, COLORREF clrBackground, XTPCalendarClockAlignFlags cafAlign)
{
ASSERT(pDC);
if (!pDC)
{
return 0;
}
static const CPoint arrHours[] =
{
CPoint(0, -6),
CPoint(3, -5),
CPoint(5, -3),
CPoint(6, 0),
CPoint(5, 3),
CPoint(3, 5),
CPoint(0, 6),
CPoint(-3, 5),
CPoint(-5, 3),
CPoint(-6, 0),
CPoint(-5, -3),
CPoint(-3, -5),
CPoint(0, -6)
};
static const CPoint arrHalfHours[] =
{
CPoint(1, -5),
CPoint(3, -3),
CPoint(4, -1),
CPoint(5, 1),
CPoint(3, 3),
CPoint(1, 5),
CPoint(-1, 5),
CPoint(-3, 3),
CPoint(-5, 1),
CPoint(-5, -1),
CPoint(-3, -3),
CPoint(-1, -5),
CPoint(1, -5)
};
if (rcView.Width() < m_szClockRect.cx || rcView.Height() < m_szClockRect.cy)
return 0;
CPoint ptClock(rcView.left, rcView.top);
if (cafAlign == xtpCalendarClockAlignLeft)
ptClock.Offset(1, (rcView.Height() - m_szClockRect.cy)/2 + 1);
else if (cafAlign == xtpCalendarClockAlignRight)
ptClock.Offset(rcView.Width() - m_szClockRect.cx - 1,
(rcView.Height() - m_szClockRect.cy)/2 + 1);
else if (cafAlign == xtpCalendarClockAlignCenter)
ptClock.Offset((rcView.Width() - m_szClockRect.cx)/2,
(rcView.Height() - m_szClockRect.cy)/2 + 1);
CRect rcClock(0, 0, 0, 0);
rcClock.SetRect(ptClock.x, ptClock.y,
ptClock.x + m_szClockRect.cx,
ptClock.y + m_szClockRect.cy);
int nHour = dtClockTime.GetHour();
int nMin = dtClockTime.GetMinute() /5;
COLORREF clrFill;
COLORREF clrItems;
if (nHour >= 12)
{
clrFill = RGB(0, 0, 0);
clrItems = clrBackground;
}
else
{
clrFill = clrBackground;
clrItems = RGB(0, 0, 0);
}
nHour = nHour > 12 ? nHour - 12 : nHour;
CXTPBrushDC brushClock(pDC->m_hDC, clrFill);
CPoint ptCenter(rcClock.CenterPoint());
pDC->Ellipse(rcClock);
CXTPPenDC penItems(pDC->m_hDC, clrItems);
int x = 0;
int y = 0;
for (int i = 0; i <= 12; i++)
{
pDC->SetPixel(ptCenter.x + arrHours[i].x,
ptCenter.y + arrHours[i].y, clrItems);
if (nHour == i)
{
if (nMin >= 6)
{
x = arrHalfHours[i].x;
y = arrHalfHours[i].y;
}
else
{
x = arrHours[i].x;
y = arrHours[i].y;
x = x > 0 ? x -1 : x == 0 ? 0 : x + 1;
y = y > 0 ? y -1 : y == 0 ? 0 : y + 1;
}
pDC->MoveTo(ptCenter);
pDC->LineTo(ptCenter.x+ x, ptCenter.y + y);
}
if (nMin == i)
{
pDC->MoveTo(ptCenter);
pDC->LineTo(ptCenter.x + arrHours[i].x,
ptCenter.y + arrHours[i].y);
}
}
return m_szClockRect.cx;
}
void CXTPCalendarPaintManager::SetControl(CXTPCalendarControl* pControl)
{
m_pControl = pControl;
}
int CXTPCalendarPaintManager::DrawIconChar(CDC* pDC, CRect rc, TCHAR ch)
{
if (!pDC || !m_pGlyphsFont || !m_pGlyphsFont->m_hObject)
{
ASSERT(FALSE);
return 0;
}
CFont* pPrevFnt = pDC->SelectObject(m_pGlyphsFont);
pDC->SetTextColor(GetControlPart()->GetTextColor());
TCHAR cszCh[2] = {ch, 0};
UINT uFlags = DT_VCENTER | DT_LEFT; // DT_CENTER;
//CSize szChar = pDC->GetTextExtent(szCh, 1);
CRect rcNeed = rc;
pDC->DrawText(cszCh, 1, rcNeed, uFlags | DT_CALCRECT);
rc.bottom = rc.top + rcNeed.Height();
pDC->DrawText(cszCh, 1, rc, uFlags);
pDC->SelectObject(pPrevFnt);
//return szChar.cx;
return rcNeed.Width();
}
int CXTPCalendarPaintManager::DrawIcons(CDC* pDC, CXTPCalendarViewEvent* pViewEvent)
{
if (!pViewEvent || !pViewEvent->GetEvent())
{
ASSERT(FALSE);
return 0;
}
BOOL bUseFont = XTP_SAFE_GET3(pViewEvent, GetCalendarControl(),
GetCalendarOptions(), bUseOutlookFontGlyphs, FALSE);
bUseFont = bUseFont && m_pGlyphsFont;
int nWidth = 0;
if (pViewEvent->GetEvent()->IsReminder() &&
!pViewEvent->GetReminderGlyphRect().IsRectEmpty())
{
if (bUseFont)
{
nWidth += DrawIconChar(pDC, pViewEvent->GetReminderGlyphRect(), 0x41);
}
else
{
nWidth += DrawBitmap(&m_ilGlyphs, pDC,
pViewEvent->GetReminderGlyphRect(), 0, DT_VCENTER);
}
}
int nRecurrenceState = pViewEvent->GetEvent()->GetRecurrenceState();
if (!pViewEvent->GetRecurrenceGlyphRect().IsRectEmpty())
{
if ((nRecurrenceState == xtpCalendarRecurrenceMaster) || (nRecurrenceState == xtpCalendarRecurrenceOccurrence))
{
if (bUseFont)
{
nWidth += DrawIconChar(pDC, pViewEvent->GetRecurrenceGlyphRect(), 0x43);
}
else
{
nWidth += DrawBitmap(&m_ilGlyphs, pDC,
pViewEvent->GetRecurrenceGlyphRect(), 1, DT_VCENTER);
}
}
else if (nRecurrenceState == xtpCalendarRecurrenceException)
{
if (bUseFont)
{
nWidth += DrawIconChar(pDC, pViewEvent->GetRecurrenceGlyphRect(), 0x44);
}
else
{
nWidth += DrawBitmap(&m_ilGlyphs, pDC,
pViewEvent->GetRecurrenceGlyphRect(), 2, DT_VCENTER);
}
}
}
if (pViewEvent->GetEvent()->IsMeeting() &&
!pViewEvent->GetMeetingGlyphRect().IsRectEmpty())
{
if (bUseFont)
{
nWidth += DrawIconChar(pDC, pViewEvent->GetMeetingGlyphRect(), 0x45);
}
else
{
nWidth += DrawBitmap(&m_ilGlyphs, pDC,
pViewEvent->GetMeetingGlyphRect(), 3, DT_VCENTER);
}
}
if (pViewEvent->GetEvent()->IsPrivate() &&
!pViewEvent->GetPrivateGlyphRect().IsRectEmpty())
{
if (bUseFont)
{
nWidth += DrawIconChar(pDC, pViewEvent->GetPrivateGlyphRect(), 0x42);
}
else
{
nWidth += DrawBitmap(&m_ilGlyphs, pDC,
pViewEvent->GetPrivateGlyphRect(), 4, DT_VCENTER);
}
}
return nWidth;
}
void CXTPCalendarPaintManager::InitBusyStatusDefaultColors()
{
m_brushTentative.DeleteObject();
m_bmpTentativePattern.DeleteObject();
VERIFY(XTPResourceManager()->LoadBitmap(&m_bmpTentativePattern, XTP_IDB_CALENDAR_TENATIVE_PATTERN));
VERIFY(m_brushTentative.CreatePatternBrush(&m_bmpTentativePattern));
CXTPCalendarViewPartBrushValue* pBVal_Free = _GetAtGrow_BusyStatusBrushValue(xtpCalendarBusyStatusFree, TRUE);
CXTPCalendarViewPartBrushValue* pBVal_Tentative = _GetAtGrow_BusyStatusBrushValue(xtpCalendarBusyStatusTentative, TRUE);
CXTPCalendarViewPartBrushValue* pBVal_Busy = _GetAtGrow_BusyStatusBrushValue(xtpCalendarBusyStatusBusy, TRUE);
CXTPCalendarViewPartBrushValue* pBVal_OutOO = _GetAtGrow_BusyStatusBrushValue(xtpCalendarBusyStatusOutOfOffice, TRUE);
if (pBVal_Free)
{
pBVal_Free->SetStandardValue(new CBrush(RGB(0xFF, 0xFF, 0xFF)), TRUE);
}
if (pBVal_Tentative)
{
pBVal_Tentative->SetStandardValue(&m_brushTentative, FALSE);
}
if (pBVal_Busy)
{
pBVal_Busy->SetStandardValue(new CBrush(RGB(0, 0, 0xFF)), TRUE);
}
if (pBVal_OutOO)
{
pBVal_OutOO->SetStandardValue(new CBrush(RGB(132, 0, 132)), TRUE);
}
}
void CXTPCalendarPaintManager::SetBusyStatusBrush(int eBusyStatus, CBrush* pBrush, BOOL bAutodeleteBrush)
{
if (eBusyStatus < 0 || !pBrush)
{
ASSERT(FALSE);
return;
}
CXTPCalendarViewPartBrushValue* pBVal = _GetAtGrow_BusyStatusBrushValue(eBusyStatus, TRUE);
ASSERT(pBVal);
if (pBVal)
{
pBVal->SetCustomValue(pBrush, bAutodeleteBrush);
}
}
CBrush* CXTPCalendarPaintManager::GetBusyStatusBrush(int nBusyStatus)
{
CXTPCalendarViewPartBrushValue* pBVal = _GetAtGrow_BusyStatusBrushValue(nBusyStatus, TRUE);
ASSERT(pBVal);
if (pBVal)
{
CBrush* pBrush = pBVal->GetValue();
return pBrush;
}
return NULL;
}
CXTPCalendarViewPartBrushValue* CXTPCalendarPaintManager::_GetAtGrow_BusyStatusBrushValue(
int nBusyStatus, BOOL bGrow)
{
if (nBusyStatus < 0)
{
//ASSERT(FALSE);
nBusyStatus = 0;
}
int nCount = (int)m_arBusyStatusBrushes.GetSize();
if (nBusyStatus >= nCount || m_arBusyStatusBrushes[nBusyStatus] == NULL)
{
if (!bGrow)
{
return NULL;
}
m_arBusyStatusBrushes.SetAtGrow(nBusyStatus, new CXTPCalendarViewPartBrushValue);
}
CXTPCalendarViewPartBrushValue* pBVal = m_arBusyStatusBrushes[nBusyStatus];
return pBVal;
}
void CXTPCalendarPaintManager::DrawBusyStatus(CDC* pDC, CRect& rcRect, int eBusyStatus)
{
CBrush* pBrush = GetBusyStatusBrush(eBusyStatus);
if (!pBrush || !pDC)
{
ASSERT(FALSE);
return;
}
pDC->FillRect(&rcRect, pBrush);
}
void CXTPCalendarPaintManager::DrawBusyStatus(CDC* pDC, CRgn& rgnBusy, int eBusyStatus)
{
CBrush* pBrush = GetBusyStatusBrush(eBusyStatus);
if (!pBrush || !pDC)
{
ASSERT(FALSE);
return;
}
CBrush brBorder(m_clrWindowText);
VERIFY(pDC->FillRgn(&rgnBusy, pBrush));
VERIFY(pDC->FrameRgn(&rgnBusy, &brBorder, 1, 1));
}
//////////////////////////////////////////////////////////////////////////