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