Merge to XFA: Use stdint.h types throughout PDFium.
[pdfium.git] / xfa / src / fwl / src / basewidget / fwl_monthcalendarimp.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.\r
2 // Use of this source code is governed by a BSD-style license that can be\r
3 // found in the LICENSE file.\r
4 \r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
6 \r
7 #include "../../../foxitlib.h"\r
8 #include "../core/include/fwl_targetimp.h"\r
9 #include "../core/include/fwl_noteimp.h"\r
10 #include "../core/include/fwl_widgetimp.h"\r
11 #include "include/fwl_monthcalendarimp.h"\r
12 #define MONTHCAL_HSEP_HEIGHT                    1\r
13 #define MONTHCAL_VSEP_WIDTH                             1\r
14 #define MONTHCAL_HMARGIN                                3\r
15 #define MONTHCAL_VMARGIN                                2\r
16 #define MONTHCAL_ROWS                                   9\r
17 #define MONTHCAL_COLUMNS                                7\r
18 #define MONTHCAL_HEADER_BTN_VMARGIN             7\r
19 #define MONTHCAL_HEADER_BTN_HMARGIN             5\r
20 IFWL_MonthCalendar* IFWL_MonthCalendar::Create()\r
21 {\r
22     return new IFWL_MonthCalendar;\r
23 }\r
24 IFWL_MonthCalendar::IFWL_MonthCalendar()\r
25 {\r
26     m_pData = NULL;\r
27 }\r
28 IFWL_MonthCalendar::~IFWL_MonthCalendar()\r
29 {\r
30     if (m_pData) {\r
31         delete (CFWL_MonthCalendarImp*)m_pData;\r
32         m_pData = NULL;\r
33     }\r
34 }\r
35 FWL_ERR IFWL_MonthCalendar::Initialize(IFWL_Widget *pOuter)\r
36 {\r
37     m_pData = FX_NEW CFWL_MonthCalendarImp(pOuter);\r
38     ((CFWL_MonthCalendarImp*)m_pData)->SetInterface(this);\r
39     return ((CFWL_MonthCalendarImp*)m_pData)->Initialize();\r
40 }\r
41 FWL_ERR IFWL_MonthCalendar::Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)\r
42 {\r
43     m_pData = FX_NEW CFWL_MonthCalendarImp(properties, pOuter);\r
44     ((CFWL_MonthCalendarImp*)m_pData)->SetInterface(this);\r
45     return ((CFWL_MonthCalendarImp*)m_pData)->Initialize();\r
46 }\r
47 int32_t IFWL_MonthCalendar::CountSelect()\r
48 {\r
49     return ((CFWL_MonthCalendarImp*)m_pData)->CountSelect();\r
50 }\r
51 FX_BOOL IFWL_MonthCalendar::GetSelect(int32_t &iYear, int32_t &iMonth, int32_t &iDay, int32_t nIndex)\r
52 {\r
53     return ((CFWL_MonthCalendarImp*)m_pData)->GetSelect(iYear, iMonth, iDay, nIndex);\r
54 }\r
55 FX_BOOL IFWL_MonthCalendar::SetSelect(int32_t iYear, int32_t iMonth, int32_t iDay)\r
56 {\r
57     return ((CFWL_MonthCalendarImp*)m_pData)->SetSelect(iYear, iMonth, iDay);\r
58 }\r
59 CFWL_MonthCalendarImp::CFWL_MonthCalendarImp(IFWL_Widget *pOuter )\r
60     : CFWL_WidgetImp(pOuter)\r
61     , m_iLBtnPartStates(FWL_PARTSTATE_MCD_Normal)\r
62     , m_iRBtnPartStates(FWL_PARTSTATE_MCD_Normal)\r
63     , m_iCurMonth(1)\r
64     , m_iCurYear(2011)\r
65     , m_iYear(2011)\r
66     , m_iMonth(1)\r
67     , m_iDay(1)\r
68     , m_iHovered(-1)\r
69 {\r
70     m_rtHead.Reset();\r
71     m_rtWeek.Reset();\r
72     m_rtLBtn.Reset();\r
73     m_rtRBtn.Reset();\r
74     m_rtDates.Reset();\r
75     m_rtHSep.Reset();\r
76     m_rtHeadText.Reset();\r
77     m_rtToday.Reset();\r
78     m_rtTodayFlag.Reset();\r
79     m_rtClient.Reset();\r
80     m_rtWeekNum.Reset();\r
81     m_rtWeekNumSep.Reset();\r
82     m_szHead.Reset();\r
83     m_szCell.Reset();\r
84     m_szToday.Reset();\r
85     m_pDateTime = new CFX_DateTime;\r
86     m_bInit = FALSE;\r
87     m_iMaxSel = 1;\r
88 }\r
89 CFWL_MonthCalendarImp::CFWL_MonthCalendarImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)\r
90     : CFWL_WidgetImp(properties, pOuter)\r
91     , m_iLBtnPartStates(FWL_PARTSTATE_MCD_Normal)\r
92     , m_iRBtnPartStates(FWL_PARTSTATE_MCD_Normal)\r
93     , m_iCurMonth(1)\r
94     , m_iCurYear(2011)\r
95     , m_iYear(2011)\r
96     , m_iMonth(1)\r
97     , m_iDay(1)\r
98     , m_iHovered(-1)\r
99 {\r
100     m_rtHead.Reset();\r
101     m_rtWeek.Reset();\r
102     m_rtLBtn.Reset();\r
103     m_rtRBtn.Reset();\r
104     m_rtDates.Reset();\r
105     m_rtHSep.Reset();\r
106     m_rtHeadText.Reset();\r
107     m_rtToday.Reset();\r
108     m_rtTodayFlag.Reset();\r
109     m_rtClient.Reset();\r
110     m_rtWeekNum.Reset();\r
111     m_rtWeekNumSep.Reset();\r
112     m_szHead.Reset();\r
113     m_szCell.Reset();\r
114     m_szToday.Reset();\r
115     m_pDateTime = new CFX_DateTime;\r
116     m_bInit = FALSE;\r
117     m_iMaxSel = 1;\r
118 }\r
119 CFWL_MonthCalendarImp::~CFWL_MonthCalendarImp()\r
120 {\r
121     ClearDateItem();\r
122     delete m_pDateTime;\r
123     m_arrSelDays.RemoveAll();\r
124 }\r
125 FWL_ERR CFWL_MonthCalendarImp::GetClassName(CFX_WideString &wsClass) const\r
126 {\r
127     wsClass = FWL_CLASS_MonthCalendar;\r
128     return FWL_ERR_Succeeded;\r
129 }\r
130 FX_DWORD CFWL_MonthCalendarImp::GetClassID() const\r
131 {\r
132     return FWL_CLASSHASH_MonthCalendar;\r
133 }\r
134 FWL_ERR CFWL_MonthCalendarImp::Initialize()\r
135 {\r
136     _FWL_ERR_CHECK_RETURN_VALUE_IF_FAIL(CFWL_WidgetImp::Initialize(), FWL_ERR_Indefinite);\r
137     m_pDelegate = (IFWL_WidgetDelegate*)FX_NEW CFWL_MonthCalendarImpDelegate(this);\r
138     return FWL_ERR_Succeeded;\r
139 }\r
140 FWL_ERR CFWL_MonthCalendarImp::Finalize()\r
141 {\r
142     if ( m_pDelegate) {\r
143         delete (CFWL_MonthCalendarImpDelegate*)m_pDelegate;\r
144         m_pDelegate = NULL;\r
145     }\r
146     return CFWL_WidgetImp::Finalize();\r
147 }\r
148 FWL_ERR CFWL_MonthCalendarImp::GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize )\r
149 {\r
150     if (bAutoSize) {\r
151         CFX_SizeF fs = CalcSize(TRUE);\r
152         rect.Set(0, 0, fs.x, fs.y);\r
153         CFWL_WidgetImp::GetWidgetRect(rect, TRUE);\r
154     } else {\r
155         rect = m_pProperties->m_rtWidget;\r
156     }\r
157     return FWL_ERR_Succeeded;\r
158 }\r
159 FWL_ERR CFWL_MonthCalendarImp::Update()\r
160 {\r
161     if (IsLocked()) {\r
162         return FWL_ERR_Indefinite;\r
163     }\r
164     if (!m_pProperties->m_pThemeProvider) {\r
165         m_pProperties->m_pThemeProvider = GetAvailableTheme();\r
166     }\r
167     GetCapValue();\r
168     if (!m_bInit) {\r
169         m_bInit = InitDate();\r
170     }\r
171     ClearDateItem();\r
172     ReSetDateItem();\r
173     LayOut();\r
174     return FWL_ERR_Succeeded;\r
175 }\r
176 FWL_ERR CFWL_MonthCalendarImp::DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )\r
177 {\r
178     _FWL_RETURN_VALUE_IF_FAIL(pGraphics, FWL_ERR_Indefinite);\r
179     if (m_pProperties->m_pThemeProvider == NULL) {\r
180         m_pProperties->m_pThemeProvider = GetAvailableTheme();\r
181     }\r
182     IFWL_ThemeProvider *pTheme = m_pProperties->m_pThemeProvider;\r
183     if (HasBorder()) {\r
184         DrawBorder(pGraphics, FWL_PART_MCD_Border, pTheme, pMatrix);\r
185     }\r
186     if (HasEdge()) {\r
187         DrawEdge(pGraphics, FWL_PART_MCD_Edge, pTheme, pMatrix);\r
188     }\r
189     DrawBkground(pGraphics, pTheme, pMatrix);\r
190     DrawHeadBK(pGraphics, pTheme, pMatrix);\r
191     DrawLButton(pGraphics, pTheme, pMatrix);\r
192     DrawRButton(pGraphics, pTheme, pMatrix);\r
193     DrawSeperator(pGraphics, pTheme, pMatrix);\r
194     DrawDatesInBK(pGraphics, pTheme, pMatrix);\r
195     DrawDatesInCircle(pGraphics, pTheme, pMatrix);\r
196     DrawCaption(pGraphics, pTheme, pMatrix);\r
197     DrawWeek(pGraphics, pTheme, pMatrix);\r
198     DrawDatesIn(pGraphics, pTheme, pMatrix);\r
199     DrawDatesOut(pGraphics, pTheme, pMatrix);\r
200     DrawToday(pGraphics, pTheme, pMatrix);\r
201     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_WeekNumbers) {\r
202         DrawWeekNumberSep(pGraphics, pTheme, pMatrix);\r
203         DrawWeekNumber(pGraphics, pTheme, pMatrix);\r
204     }\r
205     return FWL_ERR_Succeeded;\r
206 }\r
207 int32_t CFWL_MonthCalendarImp::CountSelect()\r
208 {\r
209     return m_arrSelDays.GetSize();\r
210 }\r
211 FX_BOOL CFWL_MonthCalendarImp::GetSelect(int32_t &iYear, int32_t &iMonth, int32_t &iDay, int32_t nIndex )\r
212 {\r
213     if (nIndex >= m_arrSelDays.GetSize()) {\r
214         return FALSE;\r
215     }\r
216     iYear = m_iCurYear;\r
217     iMonth = m_iCurMonth;\r
218     iDay = m_arrSelDays[nIndex];\r
219     return TRUE;\r
220 }\r
221 FX_BOOL CFWL_MonthCalendarImp::SetSelect(int32_t iYear, int32_t iMonth, int32_t iDay)\r
222 {\r
223     ChangeToMonth(iYear, iMonth);\r
224     return AddSelDay(iDay);\r
225 }\r
226 void CFWL_MonthCalendarImp::DrawBkground(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)\r
227 {\r
228     CFWL_ThemeBackground params;\r
229     params.m_pWidget = m_pInterface;\r
230     params.m_iPart = FWL_PART_MCD_Background;\r
231     params.m_pGraphics = pGraphics;\r
232     params.m_dwStates = FWL_PARTSTATE_MCD_Normal;\r
233     params.m_rtPart = m_rtClient;\r
234     if (pMatrix) {\r
235         params.m_matrix.Concat(*pMatrix);\r
236     }\r
237     pTheme->DrawBackground(&params);\r
238 }\r
239 void CFWL_MonthCalendarImp::DrawHeadBK(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)\r
240 {\r
241     CFWL_ThemeBackground params;\r
242     params.m_pWidget = m_pInterface;\r
243     params.m_iPart = FWL_PART_MCD_Header;\r
244     params.m_pGraphics = pGraphics;\r
245     params.m_dwStates = FWL_PARTSTATE_MCD_Normal;\r
246     params.m_rtPart = m_rtHead;\r
247     if (pMatrix) {\r
248         params.m_matrix.Concat(*pMatrix);\r
249     }\r
250     pTheme->DrawBackground(&params);\r
251 }\r
252 void CFWL_MonthCalendarImp::DrawLButton(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)\r
253 {\r
254     CFWL_ThemeBackground params;\r
255     params.m_pWidget = m_pInterface;\r
256     params.m_iPart = FWL_PART_MCD_LBtn;\r
257     params.m_pGraphics = pGraphics;\r
258     params.m_dwStates = m_iLBtnPartStates;\r
259     params.m_rtPart = m_rtLBtn;\r
260     if (pMatrix) {\r
261         params.m_matrix.Concat(*pMatrix);\r
262     }\r
263     pTheme->DrawBackground(&params);\r
264 }\r
265 void CFWL_MonthCalendarImp::DrawRButton(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)\r
266 {\r
267     CFWL_ThemeBackground params;\r
268     params.m_pWidget = m_pInterface;\r
269     params.m_iPart = FWL_PART_MCD_RBtn;\r
270     params.m_pGraphics = pGraphics;\r
271     params.m_dwStates = m_iRBtnPartStates;\r
272     params.m_rtPart = m_rtRBtn;\r
273     if (pMatrix) {\r
274         params.m_matrix.Concat(*pMatrix);\r
275     }\r
276     pTheme->DrawBackground(&params);\r
277 }\r
278 void CFWL_MonthCalendarImp::DrawCaption(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)\r
279 {\r
280     CFWL_ThemeText textParam;\r
281     textParam.m_pWidget = m_pInterface;\r
282     textParam.m_iPart = FWL_PART_MCD_Caption;\r
283     textParam.m_dwStates = FWL_PARTSTATE_MCD_Normal;\r
284     textParam.m_pGraphics = pGraphics;\r
285     int32_t iYear;\r
286     int32_t iMonth;\r
287     iYear = m_iCurYear;\r
288     iMonth = m_iCurMonth;\r
289     CFX_WideString wsCation;\r
290     GetHeadText(iYear, iMonth, wsCation);\r
291     textParam.m_wsText = wsCation;\r
292     m_szHead = CalcTextSize(textParam.m_wsText, m_pProperties->m_pThemeProvider);\r
293     CalcHeadSize();\r
294     textParam.m_rtPart = m_rtHeadText;\r
295     textParam.m_dwTTOStyles = FDE_TTOSTYLE_SingleLine;\r
296     textParam.m_iTTOAlign = FDE_TTOALIGNMENT_Center;\r
297     if (pMatrix) {\r
298         textParam.m_matrix.Concat(*pMatrix);\r
299     }\r
300     pTheme->DrawText(&textParam);\r
301 }\r
302 void CFWL_MonthCalendarImp::DrawSeperator(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)\r
303 {\r
304     CFWL_ThemeBackground params;\r
305     params.m_pWidget = m_pInterface;\r
306     params.m_iPart = FWL_PART_MCD_HSeparator;\r
307     params.m_pGraphics = pGraphics;\r
308     params.m_dwStates = FWL_PARTSTATE_MCD_Normal;\r
309     params.m_rtPart = m_rtHSep;\r
310     if (pMatrix) {\r
311         params.m_matrix.Concat(*pMatrix);\r
312     }\r
313     pTheme->DrawBackground(&params);\r
314 }\r
315 void CFWL_MonthCalendarImp::DrawDatesInBK(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)\r
316 {\r
317     CFWL_ThemeBackground params;\r
318     params.m_pWidget = m_pInterface;\r
319     params.m_iPart = FWL_PART_MCD_DateInBK;\r
320     params.m_pGraphics = pGraphics;\r
321     if (pMatrix) {\r
322         params.m_matrix.Concat(*pMatrix);\r
323     }\r
324     int32_t iCount = m_arrDates.GetSize();\r
325     for (int32_t j = 0; j < iCount; j ++) {\r
326         LPDATEINFO pDataInfo = (LPDATEINFO)m_arrDates.GetAt(j);\r
327         if (pDataInfo->dwStates & FWL_ITEMSTATE_MCD_Selected) {\r
328             params.m_dwStates |= FWL_PARTSTATE_MCD_Selected;\r
329             if (((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_NoTodayCircle) == 0) && pDataInfo->dwStates & FWL_ITEMSTATE_MCD_Flag) {\r
330                 params.m_dwStates |= FWL_PARTSTATE_MCD_Flagged;\r
331             }\r
332             if (pDataInfo->dwStates & FWL_ITEMSTATE_MCD_Focused) {\r
333                 params.m_dwStates |= FWL_PARTSTATE_MCD_Focused;\r
334             }\r
335         } else if (j == m_iHovered - 1) {\r
336             params.m_dwStates |= FWL_PARTSTATE_MCD_Hovered;\r
337         } else if (pDataInfo->dwStates & FWL_ITEMSTATE_MCD_Flag) {\r
338             params.m_dwStates = FWL_PARTSTATE_MCD_Flagged;\r
339             pTheme->DrawBackground(&params);\r
340         }\r
341         params.m_rtPart = pDataInfo->rect;\r
342         pTheme->DrawBackground(&params);\r
343         params.m_dwStates = 0;\r
344     }\r
345 }\r
346 void CFWL_MonthCalendarImp::DrawWeek(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)\r
347 {\r
348     CFWL_ThemeText params;\r
349     params.m_pWidget = m_pInterface;\r
350     params.m_iPart = FWL_PART_MCD_Week;\r
351     params.m_pGraphics = pGraphics;\r
352     params.m_dwStates = FWL_PARTSTATE_MCD_Normal;\r
353     params.m_iTTOAlign = FDE_TTOALIGNMENT_Center;\r
354     int32_t iWeek;\r
355     iWeek = m_pDateTime->GetDayOfWeek();\r
356     CFX_RectF rtDayOfWeek;\r
357     const FX_WCHAR* pWeekDay[] = {\r
358         (FX_WCHAR *)L"Sun", (FX_WCHAR *)L"Mon", (FX_WCHAR *)L"Tue",\r
359         (FX_WCHAR *)L"Wed", (FX_WCHAR *)L"Thu", (FX_WCHAR *)L"Fri", (FX_WCHAR *)L"Sat"\r
360     };\r
361     if (pMatrix) {\r
362         params.m_matrix.Concat(*pMatrix);\r
363     }\r
364     for (int32_t i = 0; i < 7; i++) {\r
365         rtDayOfWeek.Set(m_rtWeek.left + i * (m_szCell.x + MONTHCAL_HMARGIN * 2),\r
366                         m_rtWeek.top,\r
367                         m_szCell.x,\r
368                         m_szCell.y);\r
369         CFX_WideString *wsWeekDay = NULL;\r
370         wsWeekDay = (CFX_WideString *)pTheme->GetCapacity(&params, i + FWL_MCCAPACITY_Sun);\r
371         params.m_rtPart = rtDayOfWeek;\r
372         params.m_wsText = *wsWeekDay;\r
373         params.m_dwTTOStyles = FDE_TTOSTYLE_SingleLine;\r
374         pTheme->DrawText(&params);\r
375     }\r
376 }\r
377 void CFWL_MonthCalendarImp::DrawWeekNumber(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)\r
378 {\r
379     CFWL_ThemeText params;\r
380     params.m_pWidget = m_pInterface;\r
381     params.m_iPart = FWL_PART_MCD_WeekNum;\r
382     params.m_pGraphics = pGraphics;\r
383     params.m_dwStates = FWL_PARTSTATE_MCD_Normal;\r
384     params.m_iTTOAlign = FDE_TTOALIGNMENT_CenterLeft;\r
385     CFX_WideString wsWeekNum;\r
386     params.m_dwTTOStyles = FDE_TTOSTYLE_SingleLine;\r
387     params.m_iTTOAlign = FDE_TTOALIGNMENT_Center;\r
388     if (pMatrix) {\r
389         params.m_matrix.Concat(*pMatrix);\r
390     }\r
391     int32_t iWeekNum = 0;\r
392     int32_t iMonthNum = m_pDateTime->GetMonth();\r
393     int32_t iDayNum = FX_DaysInMonth(m_iCurYear, iMonthNum);\r
394     int32_t iTemp = 0;\r
395     FX_FLOAT fVStartPos = m_rtClient.top + m_fHeadHei + m_fHSepHei;\r
396     FX_FLOAT fHStartPos = m_rtClient.left;\r
397     for (int32_t i = 1; i <= iDayNum; i += 7) {\r
398         iTemp ++;\r
399         iWeekNum = CalWeekNumber(m_iCurYear, iMonthNum, i);\r
400         m_rtWeekNum.Set(fHStartPos, fVStartPos + m_fDateCellHei * iTemp, m_fWeekNumWid, m_fDateCellHei);\r
401         wsWeekNum.Format(FX_LPCWSTR(L"%d"), iWeekNum);\r
402         params.m_wsText = wsWeekNum;\r
403         params.m_rtPart = m_rtWeekNum;\r
404         pTheme->DrawText(&params);\r
405     }\r
406 }\r
407 void CFWL_MonthCalendarImp::DrawWeekNumberSep(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)\r
408 {\r
409     CFWL_ThemeBackground params;\r
410     params.m_pWidget = m_pInterface;\r
411     params.m_iPart = FWL_PART_MCD_WeekNumSep;\r
412     params.m_pGraphics = pGraphics;\r
413     params.m_dwStates = FWL_PARTSTATE_MCD_Normal;\r
414     params.m_rtPart = m_rtWeekNumSep;\r
415     if (pMatrix) {\r
416         params.m_matrix.Concat(*pMatrix);\r
417     }\r
418     pTheme->DrawBackground(&params);\r
419 }\r
420 void CFWL_MonthCalendarImp::DrawToday(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)\r
421 {\r
422     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_NoToday) {\r
423         return;\r
424     }\r
425     CFWL_ThemeText params;\r
426     params.m_pWidget = m_pInterface;\r
427     params.m_iPart = FWL_PART_MCD_Today;\r
428     params.m_pGraphics = pGraphics;\r
429     params.m_dwStates = FWL_PARTSTATE_MCD_Normal;\r
430     params.m_iTTOAlign = FDE_TTOALIGNMENT_CenterLeft;\r
431     CFX_WideString *wsDay = NULL;\r
432     wsDay = (CFX_WideString *)pTheme->GetCapacity(&params, FWL_MCCAPACITY_Today);\r
433     CFX_WideString wsText;\r
434     GetTodayText(m_iYear, m_iMonth, m_iDay, wsText);\r
435     params.m_wsText = *wsDay + wsText;\r
436     m_szToday = CalcTextSize(params.m_wsText, m_pProperties->m_pThemeProvider);\r
437     CalcTodaySize();\r
438     params.m_rtPart = m_rtToday;\r
439     params.m_dwTTOStyles = FDE_TTOSTYLE_SingleLine;\r
440     if (pMatrix) {\r
441         params.m_matrix.Concat(*pMatrix);\r
442     }\r
443     pTheme->DrawText(&params);\r
444 }\r
445 void CFWL_MonthCalendarImp::DrawDatesIn(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)\r
446 {\r
447     CFWL_ThemeText params;\r
448     params.m_pWidget = m_pInterface;\r
449     params.m_iPart = FWL_PART_MCD_DatesIn;\r
450     params.m_pGraphics = pGraphics;\r
451     params.m_dwStates = FWL_PARTSTATE_MCD_Normal;\r
452     params.m_iTTOAlign = FDE_TTOALIGNMENT_Center;\r
453     if (pMatrix) {\r
454         params.m_matrix.Concat(*pMatrix);\r
455     }\r
456     int32_t iCount = m_arrDates.GetSize();\r
457     for (int32_t j = 0; j < iCount; j ++) {\r
458         LPDATEINFO pDataInfo = (LPDATEINFO)m_arrDates.GetAt(j);\r
459         params.m_wsText = pDataInfo->wsDay;\r
460         params.m_rtPart = pDataInfo->rect;\r
461         params.m_dwStates = pDataInfo->dwStates;\r
462         if (j + 1 == m_iHovered) {\r
463             params.m_dwStates |= FWL_PARTSTATE_MCD_Hovered;\r
464         }\r
465         params.m_dwTTOStyles = FDE_TTOSTYLE_SingleLine;\r
466         pTheme->DrawText(&params);\r
467     }\r
468 }\r
469 void CFWL_MonthCalendarImp::DrawDatesOut(CFX_Graphics *pGraphics, IFWL_ThemeProvider* pTheme, const CFX_Matrix *pMatrix)\r
470 {\r
471     CFWL_ThemeText params;\r
472     params.m_pWidget = m_pInterface;\r
473     params.m_iPart = FWL_PART_MCD_DatesOut;\r
474     params.m_pGraphics = pGraphics;\r
475     params.m_dwStates = FWL_PARTSTATE_MCD_Normal;\r
476     params.m_iTTOAlign = FDE_TTOALIGNMENT_Center;\r
477     if (pMatrix) {\r
478         params.m_matrix.Concat(*pMatrix);\r
479     }\r
480     pTheme->DrawText(&params);\r
481 }\r
482 void CFWL_MonthCalendarImp::DrawDatesInCircle(CFX_Graphics *pGraphics, IFWL_ThemeProvider* pTheme, const CFX_Matrix *pMatrix)\r
483 {\r
484     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_NoTodayCircle) {\r
485         return;\r
486     }\r
487     if (m_iMonth != m_iCurMonth || m_iYear != m_iCurYear) {\r
488         return;\r
489     }\r
490     if (m_iDay < 1 || m_iDay > m_arrDates.GetSize()) {\r
491         return;\r
492     }\r
493     LPDATEINFO pDate = (LPDATEINFO)m_arrDates[m_iDay - 1];\r
494     _FWL_RETURN_IF_FAIL(pDate);\r
495     CFWL_ThemeBackground params;\r
496     params.m_pWidget = m_pInterface;\r
497     params.m_iPart = FWL_PART_MCD_DateInCircle;\r
498     params.m_pGraphics = pGraphics;\r
499     params.m_rtPart = pDate->rect;\r
500     params.m_dwStates = FWL_PARTSTATE_MCD_Normal;\r
501     if (pMatrix) {\r
502         params.m_matrix.Concat(*pMatrix);\r
503     }\r
504     pTheme->DrawBackground(&params);\r
505 }\r
506 void CFWL_MonthCalendarImp::DrawTodayCircle(CFX_Graphics *pGraphics, IFWL_ThemeProvider* pTheme, const CFX_Matrix *pMatrix)\r
507 {\r
508     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_NoToday) {\r
509         return;\r
510     }\r
511     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_NoTodayCircle) {\r
512         return;\r
513     }\r
514     CFWL_ThemeBackground params;\r
515     params.m_pWidget = m_pInterface;\r
516     params.m_iPart = FWL_PART_MCD_TodayCircle;\r
517     params.m_pGraphics = pGraphics;\r
518     params.m_dwStates = FWL_PARTSTATE_MCD_Normal;\r
519     params.m_rtPart = m_rtTodayFlag;\r
520     if (pMatrix) {\r
521         params.m_matrix.Concat(*pMatrix);\r
522     }\r
523     pTheme->DrawBackground(&params);\r
524 }\r
525 CFX_SizeF CFWL_MonthCalendarImp::CalcSize(FX_BOOL bAutoSize)\r
526 {\r
527     CFX_SizeF fs;\r
528     fs.Set(0, 0);\r
529     _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pThemeProvider, fs);\r
530     if (bAutoSize) {\r
531         CFWL_ThemePart params;\r
532         params.m_pWidget = m_pInterface;\r
533         IFWL_ThemeProvider *pTheme = m_pProperties->m_pThemeProvider;\r
534         CFX_WideString *wsText = NULL;\r
535         FX_FLOAT fMaxWeekW = 0.0f;\r
536         FX_FLOAT fMaxWeekH = 0.0f;\r
537         for (FX_DWORD week = FWL_MCCAPACITY_Sun; week <= FWL_MCCAPACITY_Sat; week++) {\r
538             wsText = (CFX_WideString *)pTheme->GetCapacity(&params, week);\r
539             CFX_SizeF sz = CalcTextSize(*wsText, m_pProperties->m_pThemeProvider);\r
540             fMaxWeekW = (fMaxWeekW >= sz.x) ? fMaxWeekW : sz.x;\r
541             fMaxWeekH = (fMaxWeekH >= sz.y) ? fMaxWeekH : sz.y;\r
542         }\r
543         FX_FLOAT fDayMaxW = 0.0f;\r
544         FX_FLOAT fDayMaxH = 0.0f;\r
545         for (int day = 10; day <= 31; day++) {\r
546             CFX_WideString wsDay;\r
547             wsDay.Format(L"%d", day);\r
548             CFX_SizeF sz = CalcTextSize(wsDay, m_pProperties->m_pThemeProvider);\r
549             fDayMaxW = (fDayMaxW >= sz.x) ? fDayMaxW : sz.x;\r
550             fDayMaxH = (fDayMaxH >= sz.y) ? fDayMaxH : sz.y;\r
551         }\r
552         m_szCell.x = FX_FLOAT((fMaxWeekW >= fDayMaxW) ? (int)(fMaxWeekW + 0.5) : (int)(fDayMaxW + 0.5));\r
553         m_szCell.y = (fMaxWeekH >= fDayMaxH) ? fMaxWeekH : fDayMaxH;\r
554         fs.x = m_szCell.x * MONTHCAL_COLUMNS + MONTHCAL_HMARGIN * MONTHCAL_COLUMNS * 2 + MONTHCAL_HEADER_BTN_HMARGIN * 2;\r
555         FX_FLOAT fMonthMaxW = 0.0f;\r
556         FX_FLOAT fMonthMaxH = 0.0f;\r
557         for (FX_DWORD month = FWL_MCCAPACITY_January; month <= FWL_MCCAPACITY_December; month++) {\r
558             wsText = (CFX_WideString *)pTheme->GetCapacity(&params, month);\r
559             CFX_SizeF sz = CalcTextSize(*wsText, m_pProperties->m_pThemeProvider);\r
560             fMonthMaxW = (fMonthMaxW >= sz.x) ? fMonthMaxW : sz.x;\r
561             fMonthMaxH = (fMonthMaxH >= sz.y) ? fMonthMaxH : sz.y;\r
562         }\r
563         CFX_WideString wsYear;\r
564         GetHeadText(m_iYear, m_iMonth, wsYear);\r
565         CFX_SizeF szYear = CalcTextSize(wsYear, m_pProperties->m_pThemeProvider);\r
566         fMonthMaxH = (fMonthMaxH >= szYear.y) ? fMonthMaxH : szYear.y;\r
567         m_szHead.Set(fMonthMaxW + szYear.x, fMonthMaxH);\r
568         fMonthMaxW = m_szHead.x + MONTHCAL_HEADER_BTN_HMARGIN * 2 + m_szCell.x * 2;\r
569         fs.x = (fs.x >= fMonthMaxW) ? fs.x : fMonthMaxW;\r
570         CFX_WideString wsToday;\r
571         GetTodayText(m_iYear, m_iMonth, m_iDay, wsToday);\r
572         wsText = (CFX_WideString *)pTheme->GetCapacity(&params, FWL_MCCAPACITY_Today);\r
573         m_wsToday = *wsText + wsToday;\r
574         m_szToday = CalcTextSize(wsToday, m_pProperties->m_pThemeProvider);\r
575         m_szToday.y = (m_szToday.y >= m_szCell.y) ? m_szToday.y : m_szCell.y;\r
576         fs.y = m_szCell.x + m_szCell.y * (MONTHCAL_ROWS - 2) + m_szToday.y + MONTHCAL_VMARGIN * MONTHCAL_ROWS * 2 + MONTHCAL_HEADER_BTN_VMARGIN * 4;\r
577     } else {\r
578         GetClientRect(m_rtClient);\r
579         fs.Set(m_rtClient.width, m_rtClient.height);\r
580     }\r
581     return fs;\r
582 }\r
583 void CFWL_MonthCalendarImp::CalcHeadSize()\r
584 {\r
585     FX_FLOAT fHeadHMargin = (m_rtClient.width - m_szHead.x) / 2;\r
586     FX_FLOAT fHeadVMargin = (m_szCell.x - m_szHead.y) / 2;\r
587     m_rtHeadText.Set(m_rtClient.left + fHeadHMargin,\r
588                      m_rtClient.top + MONTHCAL_HEADER_BTN_VMARGIN + MONTHCAL_VMARGIN + fHeadVMargin,\r
589                      m_szHead.x,\r
590                      m_szHead.y);\r
591 }\r
592 void CFWL_MonthCalendarImp::CalcTodaySize()\r
593 {\r
594     m_rtTodayFlag.Set(m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN + MONTHCAL_HMARGIN,\r
595                       m_rtDates.bottom() + MONTHCAL_HEADER_BTN_VMARGIN + MONTHCAL_VMARGIN,\r
596                       m_szCell.x,\r
597                       m_szToday.y);\r
598     m_rtToday.Set(m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN + m_szCell.x + MONTHCAL_HMARGIN * 2 ,\r
599                   m_rtDates.bottom() + MONTHCAL_HEADER_BTN_VMARGIN + MONTHCAL_VMARGIN,\r
600                   m_szToday.x,\r
601                   m_szToday.y);\r
602 }\r
603 void CFWL_MonthCalendarImp::LayOut()\r
604 {\r
605     GetClientRect(m_rtClient);\r
606     {\r
607         m_rtHead.Set(m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN,\r
608                      m_rtClient.top,\r
609                      m_rtClient.width - MONTHCAL_HEADER_BTN_HMARGIN * 2,\r
610                      m_szCell.x + (MONTHCAL_HEADER_BTN_VMARGIN + MONTHCAL_VMARGIN) * 2);\r
611         m_rtWeek.Set(m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN,\r
612                      m_rtHead.bottom(),\r
613                      m_rtClient.width - MONTHCAL_HEADER_BTN_HMARGIN * 2,\r
614                      m_szCell.y + MONTHCAL_VMARGIN * 2);\r
615         m_rtLBtn.Set(m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN,\r
616                      m_rtClient.top + MONTHCAL_HEADER_BTN_VMARGIN,\r
617                      m_szCell.x,\r
618                      m_szCell.x);\r
619         m_rtRBtn.Set(m_rtClient.left + m_rtClient.width - MONTHCAL_HEADER_BTN_HMARGIN - m_szCell.x,\r
620                      m_rtClient.top + MONTHCAL_HEADER_BTN_VMARGIN,\r
621                      m_szCell.x,\r
622                      m_szCell.x);\r
623         m_rtHSep.Set(m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN + MONTHCAL_HMARGIN,\r
624                      m_rtWeek.bottom() - MONTHCAL_VMARGIN,\r
625                      m_rtClient.width - (MONTHCAL_HEADER_BTN_HMARGIN + MONTHCAL_HMARGIN) * 2,\r
626                      MONTHCAL_HSEP_HEIGHT);\r
627         m_rtDates.Set(m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN,\r
628                       m_rtWeek.bottom(),\r
629                       m_rtClient.width - MONTHCAL_HEADER_BTN_HMARGIN * 2,\r
630                       m_szCell.y * (MONTHCAL_ROWS - 3) + MONTHCAL_VMARGIN * (MONTHCAL_ROWS - 3) * 2);\r
631     }\r
632     CalDateItem();\r
633 }\r
634 void CFWL_MonthCalendarImp::CalDateItem()\r
635 {\r
636     FX_BOOL bNewWeek = FALSE;\r
637     int32_t iWeekOfMonth = 0;\r
638     FX_FLOAT fLeft = m_rtDates.left;\r
639     FX_FLOAT fTop = m_rtDates.top;\r
640     int32_t iCount = m_arrDates.GetSize();\r
641     for (int32_t i = 0; i < iCount; i ++) {\r
642         LPDATEINFO pDateInfo = (LPDATEINFO)m_arrDates.GetAt(i);\r
643         if (bNewWeek) {\r
644             iWeekOfMonth ++;\r
645             bNewWeek = FALSE;\r
646         }\r
647         pDateInfo->rect.Set(fLeft + pDateInfo->iDayOfWeek * (m_szCell.x + (MONTHCAL_HMARGIN * 2)),\r
648                             fTop + iWeekOfMonth * (m_szCell.y + (MONTHCAL_VMARGIN * 2)),\r
649                             m_szCell.x + (MONTHCAL_HMARGIN * 2),\r
650                             m_szCell.y + (MONTHCAL_VMARGIN * 2));\r
651         if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_WeekNumbers) {\r
652             pDateInfo->rect.Offset(m_fWeekNumWid, 0);\r
653         }\r
654         if (pDateInfo->iDayOfWeek >= 6) {\r
655             bNewWeek = TRUE;\r
656         }\r
657     }\r
658 }\r
659 void CFWL_MonthCalendarImp::GetCapValue()\r
660 {\r
661     if (!m_pProperties->m_pThemeProvider) {\r
662         m_pProperties->m_pThemeProvider = GetAvailableTheme();\r
663     }\r
664     IFWL_ThemeProvider *pTheme = m_pProperties->m_pThemeProvider;\r
665     CFWL_ThemePart part;\r
666     part.m_pWidget = m_pInterface;\r
667     m_fHeadWid = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_HEADER_WIDTH);\r
668     m_fHeadHei = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_HEADER_Height);\r
669     m_fHeadBtnWid = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_HEADER_BTN_WIDTH);\r
670     m_fHeadBtnHei = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_HEADER_BTN_HEIGHT);\r
671     m_fHeadBtnHMargin = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_HEADER_BTN_HMARGIN);\r
672     m_fHeadBtnVMargin = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_HEADER_BTN_VMARGIN);\r
673     m_fHeadTextWid = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_HEADER_TEXTWIDHT);\r
674     m_fHeadTextHei = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_HEADER_TEXTHEIGHT);\r
675     m_fHeadTextHMargin = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_HEADER_TEXT_HMARGIN);\r
676     m_fHeadTextVMargin = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_HEADER_TEXT_VMARGIN);\r
677     m_fHSepWid = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_HSEP_WIDTH);\r
678     m_fHSepHei = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_HSEP_HEIGHT);\r
679     m_fWeekNumWid = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_WEEKNUM_WIDTH);\r
680     m_fSepDOffset = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_SEP_DOFFSET);\r
681     m_fSepX = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_SEP_X);\r
682     m_fSepY = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_SEP_Y);\r
683     m_fWeekNumHeigh = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_WEEKNUM_HEIGHT);\r
684     m_fWeekWid = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_WEEK_WIDTH);\r
685     m_fWeekHei = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_WEEK_HEIGHT);\r
686     m_fDateCellWid = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_DATES_CELL_WIDTH);\r
687     m_fDateCellHei = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_DATES_CELL_HEIGHT);\r
688     m_fTodayWid = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_TODAY_WIDHT);\r
689     m_fTodayHei = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_TODAY_HEIGHT);\r
690     m_fTodayFlagWid = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_TODAY_FLAG_WIDHT);\r
691     m_fMCWid = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_WIDTH);\r
692     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_WeekNumbers) {\r
693         m_fMCWid += m_fWeekNumWid;\r
694     }\r
695     m_fMCHei = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_HEIGHT);\r
696 }\r
697 int32_t CFWL_MonthCalendarImp::CalWeekNumber(int32_t iYear, int32_t iMonth, int32_t iDay)\r
698 {\r
699     return 0;\r
700 }\r
701 FX_BOOL CFWL_MonthCalendarImp::GetMinDate(int32_t &iYear, int32_t &iMonth, int32_t &iDay)\r
702 {\r
703     iYear = m_dtMin.iYear;\r
704     iMonth = m_dtMin.iMonth;\r
705     iDay = m_dtMin.iDay;\r
706     return TRUE;\r
707 }\r
708 FX_BOOL CFWL_MonthCalendarImp::SetMinDate(int32_t iYear, int32_t iMonth, int32_t iDay)\r
709 {\r
710     m_dtMin = DATE(iYear, iMonth, iDay);\r
711     return TRUE;\r
712 }\r
713 FX_BOOL CFWL_MonthCalendarImp::GetMaxDate(int32_t &iYear, int32_t &iMonth, int32_t &iDay)\r
714 {\r
715     iYear = m_dtMax.iYear;\r
716     iMonth = m_dtMax.iMonth;\r
717     iDay = m_dtMax.iDay;\r
718     return TRUE;\r
719 }\r
720 FX_BOOL CFWL_MonthCalendarImp::SetMaxDate(int32_t iYear, int32_t iMonth, int32_t iDay)\r
721 {\r
722     m_dtMax = DATE(iYear, iMonth, iDay);\r
723     return TRUE;\r
724 }\r
725 FX_BOOL CFWL_MonthCalendarImp::InitDate()\r
726 {\r
727     if (m_pProperties->m_pDataProvider) {\r
728         IFWL_MonthCalendarDP *pDateProv = (IFWL_MonthCalendarDP*)(m_pProperties->m_pDataProvider);\r
729         m_iYear = pDateProv->GetCurYear(m_pInterface);\r
730         m_iMonth = pDateProv->GetCurMonth(m_pInterface);\r
731         m_iDay = pDateProv->GetCurDay(m_pInterface);\r
732         m_iCurYear = m_iYear;\r
733         m_iCurMonth = m_iMonth;\r
734     } else {\r
735         m_iDay = 1;\r
736         m_iMonth = 1;\r
737         m_iYear = 1;\r
738         m_iCurYear = m_iYear;\r
739         m_iCurMonth = m_iMonth;\r
740     }\r
741     GetTodayText(m_iYear, m_iMonth, m_iDay, m_wsToday);\r
742     GetHeadText(m_iCurYear, m_iCurMonth, m_wsHead);\r
743     {\r
744         m_dtMin = DATE(1500, 12, 1);\r
745         m_dtMax = DATE(2200, 1, 1);\r
746     }\r
747     return TRUE;\r
748 }\r
749 void CFWL_MonthCalendarImp::ClearDateItem()\r
750 {\r
751     int32_t iCount = m_arrDates.GetSize();\r
752     for (int32_t i = 0; i < iCount; i ++) {\r
753         LPDATEINFO pData = (LPDATEINFO)m_arrDates.GetAt(i);\r
754         delete pData;\r
755     }\r
756     m_arrDates.RemoveAll();\r
757 }\r
758 void CFWL_MonthCalendarImp::ReSetDateItem()\r
759 {\r
760     m_pDateTime->Set(m_iCurYear, m_iCurMonth, 1);\r
761     int32_t iDays = FX_DaysInMonth(m_iCurYear, m_iCurMonth);\r
762     int32_t iDayOfWeek = m_pDateTime->GetDayOfWeek();\r
763     for (int32_t i = 0; i < iDays; i ++) {\r
764         if (iDayOfWeek >= 7) {\r
765             iDayOfWeek = 0;\r
766         }\r
767         CFX_WideString wsDay;\r
768         wsDay.Format(FX_LPCWSTR(L"%d"), i + 1);\r
769         FX_DWORD dwStates = 0;\r
770         if (m_iYear == m_iCurYear && m_iMonth == m_iCurMonth && m_iDay == (i + 1)) {\r
771             dwStates |= FWL_ITEMSTATE_MCD_Flag;\r
772         }\r
773         if (m_arrSelDays.Find(i + 1) != -1) {\r
774             dwStates |= FWL_ITEMSTATE_MCD_Selected;\r
775         }\r
776         CFX_RectF rtDate;\r
777         rtDate.Set(0, 0, 0, 0);\r
778         LPDATEINFO pData = new DATEINFO(i + 1, iDayOfWeek, dwStates, rtDate, wsDay);\r
779         m_arrDates.Add(pData);\r
780         iDayOfWeek++;\r
781     }\r
782 }\r
783 FX_BOOL CFWL_MonthCalendarImp::NextMonth()\r
784 {\r
785     int32_t iYear = m_iCurYear, iMonth = m_iCurMonth;\r
786     if (iMonth >= 12) {\r
787         iMonth = 1;\r
788         iYear++;\r
789     } else {\r
790         iMonth ++;\r
791     }\r
792     DATE dt(m_iCurYear, m_iCurMonth, 1);\r
793     if (!(dt < m_dtMax)) {\r
794         return FALSE;\r
795     }\r
796     m_iCurYear = iYear, m_iCurMonth = iMonth;\r
797     ChangeToMonth(m_iCurYear, m_iCurMonth);\r
798     return TRUE;\r
799 }\r
800 FX_BOOL CFWL_MonthCalendarImp::PrevMonth()\r
801 {\r
802     int32_t iYear = m_iCurYear, iMonth = m_iCurMonth;\r
803     if (iMonth <= 1) {\r
804         iMonth = 12;\r
805         iYear --;\r
806     } else {\r
807         iMonth --;\r
808     }\r
809     DATE dt(m_iCurYear, m_iCurMonth, 1);\r
810     if (!(dt > m_dtMin)) {\r
811         return FALSE;\r
812     }\r
813     m_iCurYear = iYear, m_iCurMonth = iMonth;\r
814     ChangeToMonth(m_iCurYear, m_iCurMonth);\r
815     return TRUE;\r
816 }\r
817 void CFWL_MonthCalendarImp::ChangeToMonth(int32_t iYear, int32_t iMonth)\r
818 {\r
819     m_iCurYear = iYear;\r
820     m_iCurMonth = iMonth;\r
821     m_iHovered = -1;\r
822     ClearDateItem();\r
823     ReSetDateItem();\r
824     CalDateItem();\r
825     GetHeadText(m_iCurYear, m_iCurMonth, m_wsHead);\r
826 }\r
827 FX_BOOL CFWL_MonthCalendarImp::RemoveSelDay(int32_t iDay, FX_BOOL bAll)\r
828 {\r
829     if (iDay == -1 && !bAll) {\r
830         return FALSE;\r
831     }\r
832     if (bAll) {\r
833         int32_t iCount = m_arrSelDays.GetSize();\r
834         int32_t iDatesCount = m_arrDates.GetSize();\r
835         for (int32_t i = 0; i < iCount; i ++) {\r
836             int32_t iSelDay = m_arrSelDays.GetAt(i);\r
837             if (iSelDay <= iDatesCount) {\r
838                 LPDATEINFO pDateInfo = (LPDATEINFO)m_arrDates.GetAt(iSelDay - 1);\r
839                 pDateInfo->dwStates &= ~FWL_ITEMSTATE_MCD_Selected;\r
840             }\r
841         }\r
842         m_arrSelDays.RemoveAll();\r
843     } else {\r
844         int32_t index = m_arrSelDays.Find(iDay);\r
845         if (index == -1) {\r
846             return FALSE;\r
847         }\r
848         int32_t iSelDay = m_arrSelDays.GetAt(iDay);\r
849         int32_t iDatesCount = m_arrDates.GetSize();\r
850         if (iSelDay <= iDatesCount) {\r
851             LPDATEINFO pDateInfo = (LPDATEINFO)m_arrDates.GetAt(iSelDay - 1);\r
852             pDateInfo->dwStates &= ~FWL_ITEMSTATE_MCD_Selected;\r
853         }\r
854         m_arrSelDays.RemoveAt(index);\r
855     }\r
856     return TRUE;\r
857 }\r
858 FX_BOOL CFWL_MonthCalendarImp::AddSelDay(int32_t iDay)\r
859 {\r
860     FXSYS_assert(iDay > 0);\r
861     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_MultiSelect) {\r
862     } else {\r
863         if (m_arrSelDays.Find(iDay) == -1) {\r
864             RemoveSelDay(-1, TRUE);\r
865             if (iDay <= m_arrDates.GetSize()) {\r
866                 LPDATEINFO pDateInfo = (LPDATEINFO)m_arrDates.GetAt(iDay - 1);\r
867                 pDateInfo->dwStates |= FWL_ITEMSTATE_MCD_Selected;\r
868             }\r
869             m_arrSelDays.Add(iDay);\r
870         }\r
871     }\r
872     return TRUE;\r
873 }\r
874 FX_BOOL CFWL_MonthCalendarImp::JumpToToday()\r
875 {\r
876     if (m_iYear != m_iCurYear || m_iMonth != m_iCurMonth) {\r
877         m_iCurYear = m_iYear;\r
878         m_iCurMonth = m_iMonth;\r
879         ChangeToMonth(m_iYear, m_iMonth);\r
880         AddSelDay(m_iDay);\r
881     } else {\r
882         if (m_arrSelDays.Find(m_iDay) == -1) {\r
883             AddSelDay(m_iDay);\r
884         }\r
885     }\r
886     return TRUE;\r
887 }\r
888 void CFWL_MonthCalendarImp::GetHeadText(int32_t iYear, int32_t iMonth, CFX_WideString &wsHead)\r
889 {\r
890     FXSYS_assert(iMonth > 0 && iMonth < 13);\r
891     static FX_LPWSTR pMonth[] = {\r
892         FX_LPWSTR(L"January"),\r
893         FX_LPWSTR(L"February"),\r
894         FX_LPWSTR(L"March"),\r
895         FX_LPWSTR(L"April"),\r
896         FX_LPWSTR(L"May"),\r
897         FX_LPWSTR(L"June"),\r
898         FX_LPWSTR(L"July"),\r
899         FX_LPWSTR(L"August"),\r
900         FX_LPWSTR(L"September"),\r
901         FX_LPWSTR(L"October"),\r
902         FX_LPWSTR(L"November"),\r
903         FX_LPWSTR(L"December")\r
904     };\r
905     wsHead.Format(FX_LPCWSTR(L"%s, %d"), pMonth[iMonth - 1], iYear);\r
906 }\r
907 void CFWL_MonthCalendarImp::GetTodayText(int32_t iYear, int32_t iMonth, int32_t iDay, CFX_WideString &wsToday)\r
908 {\r
909     wsToday.Format(FX_LPCWSTR(L", %d/%d/%d"), iDay, iMonth, iYear);\r
910 }\r
911 int32_t CFWL_MonthCalendarImp::GetDayAtPoint(FX_FLOAT x, FX_FLOAT y)\r
912 {\r
913     int32_t iCount = m_arrDates.GetSize();\r
914     for (int32_t i = 0; i < iCount; i++) {\r
915         LPDATEINFO pDateInfo = (LPDATEINFO)m_arrDates.GetAt(i);\r
916         if (pDateInfo->rect.Contains(x, y)) {\r
917             return ++i;\r
918         }\r
919     }\r
920     return -1;\r
921 }\r
922 FX_BOOL CFWL_MonthCalendarImp::GetDayRect(int32_t iDay, CFX_RectF &rtDay)\r
923 {\r
924     if (iDay <= 0 || iDay > m_arrDates.GetSize()) {\r
925         return FALSE;\r
926     }\r
927     LPDATEINFO pDateInfo = (LPDATEINFO)m_arrDates[iDay - 1];\r
928     _FWL_RETURN_VALUE_IF_FAIL(pDateInfo, FALSE);\r
929     rtDay = pDateInfo->rect;\r
930     return TRUE;\r
931 }\r
932 CFWL_MonthCalendarImpDelegate::CFWL_MonthCalendarImpDelegate(CFWL_MonthCalendarImp *pOwner)\r
933     : m_pOwner(pOwner)\r
934 {\r
935 }\r
936 int32_t CFWL_MonthCalendarImpDelegate::OnProcessMessage(CFWL_Message *pMessage)\r
937 {\r
938     _FWL_RETURN_VALUE_IF_FAIL(pMessage, 0);\r
939     FX_DWORD dwMsgCode = pMessage->GetClassID();\r
940     int32_t iRet = 1;\r
941     switch (dwMsgCode) {\r
942         case FWL_MSGHASH_SetFocus:\r
943         case FWL_MSGHASH_KillFocus: {\r
944                 OnFocusChanged(pMessage, dwMsgCode == FWL_MSGHASH_SetFocus);\r
945                 break;\r
946             }\r
947         case FWL_MSGHASH_Key: {\r
948                 break;\r
949             }\r
950         case FWL_MSGHASH_Mouse: {\r
951                 CFWL_MsgMouse* pMouse = (CFWL_MsgMouse*)pMessage;\r
952                 FX_DWORD dwCmd = pMouse->m_dwCmd;\r
953                 switch(dwCmd) {\r
954                     case FWL_MSGMOUSECMD_LButtonDown: {\r
955                             OnLButtonDown(pMouse);\r
956                             break;\r
957                         }\r
958                     case FWL_MSGMOUSECMD_LButtonUp: {\r
959                             OnLButtonUp(pMouse);\r
960                             break;\r
961                         }\r
962                     case FWL_MSGMOUSECMD_MouseMove: {\r
963                             OnMouseMove((CFWL_MsgMouse*)pMouse);\r
964                             break;\r
965                         }\r
966                     case FWL_MSGMOUSECMD_MouseLeave: {\r
967                             OnMouseLeave((CFWL_MsgMouse*)pMouse);\r
968                             break;\r
969                         }\r
970                     default: {\r
971                             break;\r
972                         }\r
973                 }\r
974                 break;\r
975             }\r
976         default: {\r
977                 iRet = 0;\r
978                 break;\r
979             }\r
980     }\r
981     CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);\r
982     return iRet;\r
983 }\r
984 FWL_ERR CFWL_MonthCalendarImpDelegate::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix)\r
985 {\r
986     return m_pOwner->DrawWidget(pGraphics, pMatrix);\r
987 }\r
988 void CFWL_MonthCalendarImpDelegate::OnActivate(CFWL_Message *pMsg)\r
989 {\r
990     return;\r
991 }\r
992 void CFWL_MonthCalendarImpDelegate::OnFocusChanged(CFWL_Message *pMsg, FX_BOOL bSet)\r
993 {\r
994     if (bSet) {\r
995         m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;\r
996     } else {\r
997         m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;\r
998     }\r
999     m_pOwner->Repaint(&m_pOwner->m_rtClient);\r
1000 }\r
1001 void CFWL_MonthCalendarImpDelegate::OnLButtonDown(CFWL_MsgMouse *pMsg)\r
1002 {\r
1003     if (m_pOwner->m_rtLBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {\r
1004         m_pOwner->m_iLBtnPartStates = FWL_PARTSTATE_MCD_Pressed;\r
1005         m_pOwner->PrevMonth();\r
1006         m_pOwner->Repaint(&m_pOwner->m_rtClient);\r
1007     } else if (m_pOwner->m_rtRBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {\r
1008         m_pOwner->m_iRBtnPartStates |= FWL_PARTSTATE_MCD_Pressed;\r
1009         m_pOwner->NextMonth();\r
1010         m_pOwner->Repaint(&m_pOwner->m_rtClient);\r
1011     } else if (m_pOwner->m_rtToday.Contains(pMsg->m_fx, pMsg->m_fy)) {\r
1012         if ((m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_NoToday ) == 0) {\r
1013             m_pOwner->JumpToToday();\r
1014             m_pOwner->Repaint(&m_pOwner->m_rtClient);\r
1015         }\r
1016     } else {\r
1017         if (m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_MultiSelect) {\r
1018         } else {\r
1019             int32_t iOldSel = 0;\r
1020             if (m_pOwner->m_arrSelDays.GetSize() > 0) {\r
1021                 iOldSel = m_pOwner->m_arrSelDays[0];\r
1022             } else {\r
1023                 return;\r
1024             }\r
1025             int32_t iCurSel = m_pOwner->GetDayAtPoint(pMsg->m_fx, pMsg->m_fy);\r
1026             FX_BOOL bSelChanged = iCurSel > 0 && iCurSel != iOldSel;\r
1027             if (bSelChanged) {\r
1028                 LPDATEINFO lpDatesInfo = (LPDATEINFO)m_pOwner->m_arrDates.GetAt(iCurSel - 1);\r
1029                 CFX_RectF rtInvalidate(lpDatesInfo->rect);\r
1030                 if (iOldSel > 0) {\r
1031                     lpDatesInfo = (LPDATEINFO)m_pOwner->m_arrDates.GetAt(iOldSel - 1);\r
1032                     rtInvalidate.Union(lpDatesInfo->rect);\r
1033                 }\r
1034                 m_pOwner->AddSelDay(iCurSel);\r
1035                 CFWL_EvtClick wmClick;\r
1036                 wmClick.m_pSrcTarget = m_pOwner->m_pInterface;\r
1037                 m_pOwner->DispatchEvent(&wmClick);\r
1038                 CFWL_EventMcdDateChanged wmDateSelected;\r
1039                 wmDateSelected.m_iStartDay = iCurSel;\r
1040                 wmDateSelected.m_iEndDay = iCurSel;\r
1041                 wmDateSelected.m_iOldMonth = m_pOwner->m_iCurMonth;\r
1042                 wmDateSelected.m_iOldYear = m_pOwner->m_iCurYear;\r
1043                 wmDateSelected.m_pSrcTarget = (IFWL_MonthCalendar *)m_pOwner->m_pInterface;\r
1044                 m_pOwner->DispatchEvent(&wmDateSelected);\r
1045                 m_pOwner->Repaint(&rtInvalidate);\r
1046             }\r
1047         }\r
1048     }\r
1049 }\r
1050 void CFWL_MonthCalendarImpDelegate::OnLButtonUp(CFWL_MsgMouse *pMsg)\r
1051 {\r
1052     if (m_pOwner->m_rtLBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {\r
1053         m_pOwner->m_iLBtnPartStates = 0;\r
1054         m_pOwner->Repaint(&m_pOwner->m_rtLBtn);\r
1055     } else if (m_pOwner->m_rtRBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {\r
1056         m_pOwner->m_iRBtnPartStates = 0;\r
1057         m_pOwner->Repaint(&m_pOwner->m_rtRBtn);\r
1058     } else if (m_pOwner->m_rtDates.Contains(pMsg->m_fx, pMsg->m_fy)) {\r
1059         int32_t iDay = m_pOwner->GetDayAtPoint(pMsg->m_fx, pMsg->m_fy);\r
1060         if (iDay !=     -1) {\r
1061             m_pOwner->AddSelDay(iDay);\r
1062         }\r
1063     }\r
1064 }\r
1065 void CFWL_MonthCalendarImpDelegate::OnMouseMove(CFWL_MsgMouse *pMsg)\r
1066 {\r
1067     if (m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_MultiSelect) {\r
1068         return;\r
1069     }\r
1070     FX_BOOL bRepaint = FALSE;\r
1071     CFX_RectF rtInvalidate;\r
1072     rtInvalidate.Set(0, 0, 0, 0);\r
1073     if (m_pOwner->m_rtDates.Contains(pMsg->m_fx, pMsg->m_fy)) {\r
1074         int32_t iHover = m_pOwner->GetDayAtPoint(pMsg->m_fx, pMsg->m_fy);\r
1075         bRepaint = m_pOwner->m_iHovered != iHover;\r
1076         if (bRepaint) {\r
1077             if (m_pOwner->m_iHovered > 0) {\r
1078                 m_pOwner->GetDayRect(m_pOwner->m_iHovered, rtInvalidate);\r
1079             }\r
1080             if (iHover > 0) {\r
1081                 CFX_RectF rtDay;\r
1082                 m_pOwner->GetDayRect(iHover, rtDay);\r
1083                 if (rtInvalidate.IsEmpty()) {\r
1084                     rtInvalidate = rtDay;\r
1085                 } else {\r
1086                     rtInvalidate.Union(rtDay);\r
1087                 }\r
1088             }\r
1089         }\r
1090         m_pOwner->m_iHovered = iHover;\r
1091     } else {\r
1092         bRepaint = m_pOwner->m_iHovered > 0;\r
1093         if (bRepaint) {\r
1094             m_pOwner->GetDayRect(m_pOwner->m_iHovered, rtInvalidate);\r
1095         }\r
1096         m_pOwner->m_iHovered = -1;\r
1097     }\r
1098     if (bRepaint && !rtInvalidate.IsEmpty()) {\r
1099         m_pOwner->Repaint(&rtInvalidate);\r
1100     }\r
1101 }\r
1102 void CFWL_MonthCalendarImpDelegate::OnMouseLeave(CFWL_MsgMouse *pMsg)\r
1103 {\r
1104     if (m_pOwner->m_iHovered > 0) {\r
1105         CFX_RectF rtInvalidate;\r
1106         rtInvalidate.Set(0, 0, 0, 0);\r
1107         m_pOwner->GetDayRect(m_pOwner->m_iHovered, rtInvalidate);\r
1108         m_pOwner->m_iHovered = -1;\r
1109         if (!rtInvalidate.IsEmpty()) {\r
1110             m_pOwner->Repaint(&rtInvalidate);\r
1111         }\r
1112     }\r
1113 }\r