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