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/core/include/fwl_panelimp.h" 12 #include "xfa/src/fwl/src/core/include/fwl_formimp.h" 13 #include "xfa/src/fwl/src/core/include/fwl_widgetmgrimp.h" 14 #include "xfa/src/fwl/src/basewidget/include/fwl_formproxyimp.h" 15 #include "xfa/src/fwl/src/basewidget/include/fwl_editimp.h" 16 #include "xfa/src/fwl/src/basewidget/include/fwl_monthcalendarimp.h" 17 #include "xfa/src/fwl/src/basewidget/include/fwl_datetimepickerimp.h" 18 #define FWL_DTP_WIDTH 100 19 #define FWL_DTP_HEIGHT 20 20 21 // static 22 IFWL_DateTimePicker* IFWL_DateTimePicker::Create( 23 const CFWL_WidgetImpProperties& properties, 24 IFWL_Widget* pOuter) { 25 IFWL_DateTimePicker* pDateTimePicker = new IFWL_DateTimePicker; 26 CFWL_DateTimePickerImp* pDateTimePickerImpl = 27 new CFWL_DateTimePickerImp(properties, pOuter); 28 pDateTimePicker->SetImpl(pDateTimePickerImpl); 29 pDateTimePickerImpl->SetInterface(pDateTimePicker); 30 return pDateTimePicker; 31 } 32 33 // Static 34 IFWL_DateTimeForm* IFWL_DateTimeForm::Create( 35 const CFWL_WidgetImpProperties& properties, 36 IFWL_Widget* pOuter) { 37 IFWL_DateTimeForm* pDateTimeForm = new IFWL_DateTimeForm; 38 CFWL_FormProxyImp* pFormProxyImpl = new CFWL_FormProxyImp(properties, pOuter); 39 pDateTimeForm->SetImpl(pFormProxyImpl); 40 pFormProxyImpl->SetInterface(pDateTimeForm); 41 return pDateTimeForm; 42 } 43 44 // static 45 IFWL_DateTimeCalender* IFWL_DateTimeCalender::Create( 46 const CFWL_WidgetImpProperties& properties, 47 IFWL_Widget* pOuter) { 48 IFWL_DateTimeCalender* pDateTimeCalendar = new IFWL_DateTimeCalender; 49 CFWL_DateTimeCalendar* pDateTimeCalendarImpl = 50 new CFWL_DateTimeCalendar(properties, pOuter); 51 pDateTimeCalendar->SetImpl(pDateTimeCalendarImpl); 52 pDateTimeCalendarImpl->SetInterface(pDateTimeCalendar); 53 return pDateTimeCalendar; 54 } 55 56 // static 57 IFWL_DateTimeEdit* IFWL_DateTimeEdit::Create( 58 const CFWL_WidgetImpProperties& properties, 59 IFWL_Widget* pOuter) { 60 IFWL_DateTimeEdit* pDateTimeEdit = new IFWL_DateTimeEdit; 61 CFWL_DateTimeEdit* pDateTimeEditImpl = 62 new CFWL_DateTimeEdit(properties, pOuter); 63 pDateTimeEdit->SetImpl(pDateTimeEditImpl); 64 pDateTimeEditImpl->SetInterface(pDateTimeEdit); 65 return pDateTimeEdit; 66 } 67 68 IFWL_DateTimePicker::IFWL_DateTimePicker() { 69 } 70 int32_t IFWL_DateTimePicker::CountSelRanges() { 71 return static_cast<CFWL_DateTimePickerImp*>(GetImpl()) 72 ->GetDataTimeEdit() 73 ->CountSelRanges(); 74 } 75 int32_t IFWL_DateTimePicker::GetSelRange(int32_t nIndex, int32_t& nStart) { 76 return static_cast<CFWL_DateTimePickerImp*>(GetImpl()) 77 ->GetDataTimeEdit() 78 ->GetSelRange(nIndex, nStart); 79 } 80 FWL_ERR IFWL_DateTimePicker::GetCurSel(int32_t& iYear, 81 int32_t& iMonth, 82 int32_t& iDay) { 83 return static_cast<CFWL_DateTimePickerImp*>(GetImpl()) 84 ->GetCurSel(iYear, iMonth, iDay); 85 } 86 FWL_ERR IFWL_DateTimePicker::SetCurSel(int32_t iYear, 87 int32_t iMonth, 88 int32_t iDay) { 89 return static_cast<CFWL_DateTimePickerImp*>(GetImpl()) 90 ->SetCurSel(iYear, iMonth, iDay); 91 } 92 FWL_ERR IFWL_DateTimePicker::SetEditText(const CFX_WideString& wsText) { 93 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->SetEditText(wsText); 94 } 95 FWL_ERR IFWL_DateTimePicker::GetEditText(CFX_WideString& wsText, 96 int32_t nStart, 97 int32_t nCount) const { 98 return static_cast<CFWL_DateTimePickerImp*>(GetImpl()) 99 ->GetEditText(wsText, nStart, nCount); 100 } 101 FX_BOOL IFWL_DateTimePicker::CanUndo() { 102 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->CanUndo(); 103 } 104 FX_BOOL IFWL_DateTimePicker::CanRedo() { 105 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->CanRedo(); 106 } 107 FX_BOOL IFWL_DateTimePicker::Undo() { 108 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->Undo(); 109 } 110 FX_BOOL IFWL_DateTimePicker::Redo() { 111 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->Redo(); 112 } 113 FX_BOOL IFWL_DateTimePicker::CanCopy() { 114 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->CanCopy(); 115 } 116 FX_BOOL IFWL_DateTimePicker::CanCut() { 117 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->CanCut(); 118 } 119 FX_BOOL IFWL_DateTimePicker::CanSelectAll() { 120 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->CanSelectAll(); 121 } 122 FX_BOOL IFWL_DateTimePicker::Copy(CFX_WideString& wsCopy) { 123 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->Copy(wsCopy); 124 } 125 FX_BOOL IFWL_DateTimePicker::Cut(CFX_WideString& wsCut) { 126 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->Cut(wsCut); 127 } 128 FX_BOOL IFWL_DateTimePicker::Paste(const CFX_WideString& wsPaste) { 129 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->Paste(wsPaste); 130 } 131 FX_BOOL IFWL_DateTimePicker::SelectAll() { 132 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->SelectAll(); 133 } 134 FX_BOOL IFWL_DateTimePicker::Delete() { 135 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->Delete(); 136 } 137 FX_BOOL IFWL_DateTimePicker::DeSelect() { 138 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->DeSelect(); 139 } 140 FWL_ERR IFWL_DateTimePicker::GetBBox(CFX_RectF& rect) { 141 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->GetBBox(rect); 142 } 143 FWL_ERR IFWL_DateTimePicker::SetEditLimit(int32_t nLimit) { 144 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->SetEditLimit(nLimit); 145 } 146 FWL_ERR IFWL_DateTimePicker::ModifyEditStylesEx(FX_DWORD dwStylesExAdded, 147 FX_DWORD dwStylesExRemoved) { 148 return static_cast<CFWL_DateTimePickerImp*>(GetImpl()) 149 ->ModifyEditStylesEx(dwStylesExAdded, dwStylesExRemoved); 150 } 151 CFWL_DateTimeEdit::CFWL_DateTimeEdit(const CFWL_WidgetImpProperties& properties, 152 IFWL_Widget* pOuter) 153 : CFWL_EditImp(properties, pOuter) {} 154 FWL_ERR CFWL_DateTimeEdit::Initialize() { 155 m_pDelegate = new CFWL_DateTimeEditImpDelegate(this); 156 if (CFWL_EditImp::Initialize() != FWL_ERR_Succeeded) 157 return FWL_ERR_Indefinite; 158 return FWL_ERR_Succeeded; 159 } 160 FWL_ERR CFWL_DateTimeEdit::Finalize() { 161 delete m_pDelegate; 162 m_pDelegate = nullptr; 163 return CFWL_EditImp::Finalize(); 164 } 165 CFWL_DateTimeEditImpDelegate::CFWL_DateTimeEditImpDelegate( 166 CFWL_DateTimeEdit* pOwner) 167 : CFWL_EditImpDelegate(pOwner), m_pOwner(pOwner) { 168 } 169 int32_t CFWL_DateTimeEditImpDelegate::OnProcessMessage(CFWL_Message* pMessage) { 170 if (m_pOwner->m_pWidgetMgr->IsFormDisabled()) { 171 return DisForm_OnProcessMessage(pMessage); 172 } 173 FX_DWORD dwHashCode = pMessage->GetClassID(); 174 if (dwHashCode == FWL_MSGHASH_SetFocus || 175 dwHashCode == FWL_MSGHASH_KillFocus) { 176 IFWL_Widget* pOuter = m_pOwner->GetOuter(); 177 IFWL_WidgetDelegate* pDelegate = pOuter->SetDelegate(NULL); 178 pDelegate->OnProcessMessage(pMessage); 179 } 180 return 1; 181 } 182 int32_t CFWL_DateTimeEditImpDelegate::DisForm_OnProcessMessage( 183 CFWL_Message* pMessage) { 184 FX_DWORD dwHashCode = pMessage->GetClassID(); 185 if (m_pOwner->m_pWidgetMgr->IsFormDisabled()) { 186 if (dwHashCode == FWL_MSGHASH_Mouse) { 187 CFWL_MsgMouse* pMouse = static_cast<CFWL_MsgMouse*>(pMessage); 188 if (pMouse->m_dwCmd == FWL_MSGMOUSECMD_LButtonDown || 189 pMouse->m_dwCmd == FWL_MSGMOUSECMD_RButtonDown) { 190 if ((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) { 191 m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused; 192 } 193 CFWL_DateTimePickerImp* pDateTime = 194 static_cast<CFWL_DateTimePickerImp*>(m_pOwner->m_pOuter->GetImpl()); 195 if (pDateTime->IsMonthCalendarShowed()) { 196 CFX_RectF rtInvalidate; 197 pDateTime->GetWidgetRect(rtInvalidate); 198 pDateTime->ShowMonthCalendar(FALSE); 199 rtInvalidate.Offset(-rtInvalidate.left, -rtInvalidate.top); 200 pDateTime->Repaint(&rtInvalidate); 201 } 202 } 203 } else if (dwHashCode == FWL_MSGHASH_Key) { 204 return CFWL_EditImpDelegate::OnProcessMessage(pMessage); 205 } 206 } 207 return CFWL_EditImpDelegate::OnProcessMessage(pMessage); 208 } 209 CFWL_DateTimeCalendar::CFWL_DateTimeCalendar( 210 const CFWL_WidgetImpProperties& properties, 211 IFWL_Widget* pOuter) 212 : CFWL_MonthCalendarImp(properties, pOuter) {} 213 FWL_ERR CFWL_DateTimeCalendar::Initialize() { 214 if (CFWL_MonthCalendarImp::Initialize() != FWL_ERR_Succeeded) 215 return FWL_ERR_Indefinite; 216 delete m_pDelegate; 217 m_pDelegate = new CFWL_DateTimeCalendarImpDelegate(this); 218 return FWL_ERR_Succeeded; 219 } 220 FWL_ERR CFWL_DateTimeCalendar::Finalize() { 221 delete m_pDelegate; 222 m_pDelegate = nullptr; 223 return CFWL_MonthCalendarImp::Finalize(); 224 } 225 CFWL_DateTimeCalendarImpDelegate::CFWL_DateTimeCalendarImpDelegate( 226 CFWL_DateTimeCalendar* pOwner) 227 : CFWL_MonthCalendarImpDelegate(pOwner), m_pOwner(pOwner) { 228 m_bFlag = FALSE; 229 } 230 int32_t CFWL_DateTimeCalendarImpDelegate::OnProcessMessage( 231 CFWL_Message* pMessage) { 232 FX_DWORD dwCode = pMessage->GetClassID(); 233 if (dwCode == FWL_MSGHASH_SetFocus || dwCode == FWL_MSGHASH_KillFocus) { 234 IFWL_Widget* pOuter = m_pOwner->GetOuter(); 235 IFWL_WidgetDelegate* pDelegate = pOuter->SetDelegate(NULL); 236 return pDelegate->OnProcessMessage(pMessage); 237 } else if (dwCode == FWL_MSGHASH_Mouse) { 238 CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage); 239 if (pMsg->m_dwCmd == FWL_MSGMOUSECMD_LButtonDown) { 240 OnLButtonDownEx(pMsg); 241 return 1; 242 } else if (pMsg->m_dwCmd == FWL_MSGMOUSECMD_LButtonUp) { 243 OnLButtonUpEx(pMsg); 244 return 1; 245 } 246 } 247 return CFWL_MonthCalendarImpDelegate::OnProcessMessage(pMessage); 248 } 249 void CFWL_DateTimeCalendarImpDelegate::OnLButtonDownEx(CFWL_MsgMouse* pMsg) { 250 if (m_pOwner->m_rtLBtn.Contains(pMsg->m_fx, pMsg->m_fy)) { 251 m_pOwner->m_iLBtnPartStates = FWL_PARTSTATE_MCD_Pressed; 252 m_pOwner->PrevMonth(); 253 m_pOwner->Repaint(&m_pOwner->m_rtClient); 254 } else if (m_pOwner->m_rtRBtn.Contains(pMsg->m_fx, pMsg->m_fy)) { 255 m_pOwner->m_iRBtnPartStates |= FWL_PARTSTATE_MCD_Pressed; 256 m_pOwner->NextMonth(); 257 m_pOwner->Repaint(&m_pOwner->m_rtClient); 258 } else if (m_pOwner->m_rtToday.Contains(pMsg->m_fx, pMsg->m_fy)) { 259 if ((m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_NoToday) == 260 0) { 261 m_pOwner->JumpToToday(); 262 m_pOwner->Repaint(&m_pOwner->m_rtClient); 263 } 264 } else { 265 IFWL_DateTimePicker* pIPicker = 266 static_cast<IFWL_DateTimePicker*>(m_pOwner->m_pOuter); 267 CFWL_DateTimePickerImp* pPicker = 268 static_cast<CFWL_DateTimePickerImp*>(pIPicker->GetImpl()); 269 if (pPicker->IsMonthCalendarShowed()) { 270 m_bFlag = 1; 271 } 272 } 273 } 274 void CFWL_DateTimeCalendarImpDelegate::OnLButtonUpEx(CFWL_MsgMouse* pMsg) { 275 if (m_pOwner->m_pWidgetMgr->IsFormDisabled()) { 276 return DisForm_OnLButtonUpEx(pMsg); 277 } 278 if (m_pOwner->m_rtLBtn.Contains(pMsg->m_fx, pMsg->m_fy)) { 279 m_pOwner->m_iLBtnPartStates = 0; 280 m_pOwner->Repaint(&m_pOwner->m_rtLBtn); 281 return; 282 } 283 if (m_pOwner->m_rtRBtn.Contains(pMsg->m_fx, pMsg->m_fy)) { 284 m_pOwner->m_iRBtnPartStates = 0; 285 m_pOwner->Repaint(&m_pOwner->m_rtRBtn); 286 return; 287 } 288 if (m_pOwner->m_rtToday.Contains(pMsg->m_fx, pMsg->m_fy)) { 289 return; 290 } 291 int32_t iOldSel = 0; 292 if (m_pOwner->m_arrSelDays.GetSize() > 0) { 293 iOldSel = m_pOwner->m_arrSelDays[0]; 294 } 295 int32_t iCurSel = m_pOwner->GetDayAtPoint(pMsg->m_fx, pMsg->m_fy); 296 CFX_RectF rt; 297 IFWL_DateTimePicker* pIPicker = 298 static_cast<IFWL_DateTimePicker*>(m_pOwner->m_pOuter); 299 CFWL_DateTimePickerImp* pPicker = 300 static_cast<CFWL_DateTimePickerImp*>(pIPicker->GetImpl()); 301 pPicker->m_pForm->GetWidgetRect(rt); 302 rt.Set(0, 0, rt.width, rt.height); 303 if (iCurSel > 0) { 304 LPDATEINFO lpDatesInfo = 305 (LPDATEINFO)m_pOwner->m_arrDates.GetAt(iCurSel - 1); 306 CFX_RectF rtInvalidate(lpDatesInfo->rect); 307 if (iOldSel > 0 && iOldSel <= m_pOwner->m_arrDates.GetSize()) { 308 lpDatesInfo = (LPDATEINFO)m_pOwner->m_arrDates.GetAt(iOldSel - 1); 309 rtInvalidate.Union(lpDatesInfo->rect); 310 } 311 m_pOwner->AddSelDay(iCurSel); 312 if (!m_pOwner->m_pOuter) 313 return; 314 pPicker->ProcessSelChanged(m_pOwner->m_iCurYear, m_pOwner->m_iCurMonth, 315 iCurSel); 316 pPicker->ShowMonthCalendar(FALSE); 317 } else if (m_bFlag && (!rt.Contains(pMsg->m_fx, pMsg->m_fy))) { 318 IFWL_DateTimePicker* pIPicker = 319 static_cast<IFWL_DateTimePicker*>(m_pOwner->m_pOuter); 320 CFWL_DateTimePickerImp* pPicker = 321 static_cast<CFWL_DateTimePickerImp*>(pIPicker->GetImpl()); 322 pPicker->ShowMonthCalendar(FALSE); 323 } 324 m_bFlag = 0; 325 } 326 void CFWL_DateTimeCalendarImpDelegate::OnMouseMoveEx(CFWL_MsgMouse* pMsg) { 327 if (m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_MultiSelect) { 328 return; 329 } 330 FX_BOOL bRepaint = FALSE; 331 CFX_RectF rtInvalidate; 332 rtInvalidate.Set(0, 0, 0, 0); 333 if (m_pOwner->m_rtDates.Contains(pMsg->m_fx, pMsg->m_fy)) { 334 int32_t iHover = m_pOwner->GetDayAtPoint(pMsg->m_fx, pMsg->m_fy); 335 bRepaint = m_pOwner->m_iHovered != iHover; 336 if (bRepaint) { 337 if (m_pOwner->m_iHovered > 0) { 338 m_pOwner->GetDayRect(m_pOwner->m_iHovered, rtInvalidate); 339 } 340 if (iHover > 0) { 341 CFX_RectF rtDay; 342 m_pOwner->GetDayRect(iHover, rtDay); 343 if (rtInvalidate.IsEmpty()) { 344 rtInvalidate = rtDay; 345 } else { 346 rtInvalidate.Union(rtDay); 347 } 348 } 349 } 350 m_pOwner->m_iHovered = iHover; 351 CFWL_Event_DtpHoverChanged ev; 352 ev.hoverday = iHover; 353 m_pOwner->DispatchEvent(&ev); 354 } else { 355 bRepaint = m_pOwner->m_iHovered > 0; 356 if (bRepaint) { 357 m_pOwner->GetDayRect(m_pOwner->m_iHovered, rtInvalidate); 358 } 359 m_pOwner->m_iHovered = -1; 360 } 361 if (bRepaint && !rtInvalidate.IsEmpty()) { 362 m_pOwner->Repaint(&rtInvalidate); 363 } 364 } 365 int32_t CFWL_DateTimeCalendarImpDelegate::DisForm_OnProcessMessage( 366 CFWL_Message* pMessage) { 367 if (pMessage->GetClassID() == FWL_MSGHASH_Mouse) { 368 CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage); 369 if (pMsg->m_dwCmd == FWL_MSGMOUSECMD_LButtonUp) { 370 DisForm_OnLButtonUpEx(pMsg); 371 return 1; 372 } 373 } 374 return CFWL_MonthCalendarImpDelegate::OnProcessMessage(pMessage); 375 } 376 void CFWL_DateTimeCalendarImpDelegate::DisForm_OnLButtonUpEx( 377 CFWL_MsgMouse* pMsg) { 378 if (m_pOwner->m_rtLBtn.Contains(pMsg->m_fx, pMsg->m_fy)) { 379 m_pOwner->m_iLBtnPartStates = 0; 380 m_pOwner->Repaint(&(m_pOwner->m_rtLBtn)); 381 return; 382 } 383 if (m_pOwner->m_rtRBtn.Contains(pMsg->m_fx, pMsg->m_fy)) { 384 m_pOwner->m_iRBtnPartStates = 0; 385 m_pOwner->Repaint(&(m_pOwner->m_rtRBtn)); 386 return; 387 } 388 if (m_pOwner->m_rtToday.Contains(pMsg->m_fx, pMsg->m_fy)) { 389 return; 390 } 391 int32_t iOldSel = 0; 392 if (m_pOwner->m_arrSelDays.GetSize() > 0) { 393 iOldSel = m_pOwner->m_arrSelDays[0]; 394 } 395 int32_t iCurSel = m_pOwner->GetDayAtPoint(pMsg->m_fx, pMsg->m_fy); 396 if (iCurSel > 0) { 397 LPDATEINFO lpDatesInfo = 398 (LPDATEINFO)m_pOwner->m_arrDates.GetAt(iCurSel - 1); 399 CFX_RectF rtInvalidate(lpDatesInfo->rect); 400 if (iOldSel > 0 && iOldSel <= m_pOwner->m_arrDates.GetSize()) { 401 lpDatesInfo = (LPDATEINFO)m_pOwner->m_arrDates.GetAt(iOldSel - 1); 402 rtInvalidate.Union(lpDatesInfo->rect); 403 } 404 m_pOwner->AddSelDay(iCurSel); 405 CFWL_DateTimePickerImp* pDateTime = 406 static_cast<CFWL_DateTimePickerImp*>(m_pOwner->m_pOuter->GetImpl()); 407 pDateTime->ProcessSelChanged(m_pOwner->m_iCurYear, m_pOwner->m_iCurMonth, 408 iCurSel); 409 pDateTime->ShowMonthCalendar(FALSE); 410 } 411 } 412 CFWL_DateTimePickerImp::CFWL_DateTimePickerImp( 413 const CFWL_WidgetImpProperties& properties, 414 IFWL_Widget* pOuter) 415 : CFWL_WidgetImp(properties, pOuter), 416 m_iBtnState(1), 417 m_iYear(-1), 418 m_iMonth(-1), 419 m_iDay(-1), 420 m_bLBtnDown(FALSE), 421 m_pEdit(nullptr), 422 m_pMonthCal(nullptr), 423 m_pForm(nullptr) { 424 m_rtBtn.Set(0, 0, 0, 0); 425 } 426 CFWL_DateTimePickerImp::~CFWL_DateTimePickerImp() { 427 } 428 FWL_ERR CFWL_DateTimePickerImp::GetClassName(CFX_WideString& wsClass) const { 429 wsClass = FWL_CLASS_DateTimePicker; 430 return FWL_ERR_Succeeded; 431 } 432 FX_DWORD CFWL_DateTimePickerImp::GetClassID() const { 433 return FWL_CLASSHASH_DateTimePicker; 434 } 435 FWL_ERR CFWL_DateTimePickerImp::Initialize() { 436 if (CFWL_WidgetImp::Initialize() != FWL_ERR_Succeeded) 437 return FWL_ERR_Indefinite; 438 m_pDelegate = new CFWL_DateTimePickerImpDelegate(this); 439 m_pProperties->m_dwStyleExes = FWL_STYLEEXT_DTP_ShortDateFormat; 440 CFWL_WidgetImpProperties propMonth; 441 propMonth.m_dwStyles = FWL_WGTSTYLE_Popup | FWL_WGTSTYLE_Border; 442 propMonth.m_dwStates = FWL_WGTSTATE_Invisible; 443 propMonth.m_pDataProvider = &m_MonthCalendarDP; 444 propMonth.m_pParent = m_pInterface; 445 propMonth.m_pThemeProvider = m_pProperties->m_pThemeProvider; 446 m_pMonthCal.reset(IFWL_DateTimeCalender::Create(propMonth, m_pInterface)); 447 m_pMonthCal->Initialize(); 448 CFX_RectF rtMonthCal; 449 m_pMonthCal->GetWidgetRect(rtMonthCal, TRUE); 450 rtMonthCal.Set(0, 0, rtMonthCal.width, rtMonthCal.height); 451 m_pMonthCal->SetWidgetRect(rtMonthCal); 452 CFWL_WidgetImpProperties propEdit; 453 propEdit.m_pParent = m_pInterface; 454 propEdit.m_pThemeProvider = m_pProperties->m_pThemeProvider; 455 m_pEdit.reset(IFWL_DateTimeEdit::Create(propEdit, m_pInterface)); 456 m_pEdit->Initialize(); 457 RegisterEventTarget(m_pMonthCal.get()); 458 RegisterEventTarget(m_pEdit.get()); 459 return FWL_ERR_Succeeded; 460 } 461 FWL_ERR CFWL_DateTimePickerImp::Finalize() { 462 if (m_pEdit) { 463 m_pEdit->Finalize(); 464 } 465 if (m_pMonthCal) { 466 m_pMonthCal->Finalize(); 467 } 468 if (m_pForm) { 469 m_pForm->Finalize(); 470 } 471 UnregisterEventTarget(); 472 delete m_pDelegate; 473 m_pDelegate = nullptr; 474 return CFWL_WidgetImp::Finalize(); 475 } 476 FWL_ERR CFWL_DateTimePickerImp::GetWidgetRect(CFX_RectF& rect, 477 FX_BOOL bAutoSize) { 478 if (m_pWidgetMgr->IsFormDisabled()) { 479 return DisForm_GetWidgetRect(rect, bAutoSize); 480 } 481 if (bAutoSize) { 482 rect.Set(0, 0, FWL_DTP_WIDTH, FWL_DTP_HEIGHT); 483 CFWL_WidgetImp::GetWidgetRect(rect, TRUE); 484 } else { 485 rect = m_pProperties->m_rtWidget; 486 } 487 return FWL_ERR_Succeeded; 488 } 489 FWL_ERR CFWL_DateTimePickerImp::Update() { 490 if (m_pWidgetMgr->IsFormDisabled()) { 491 return DisForm_Update(); 492 } 493 if (m_iLock) { 494 return FWL_ERR_Indefinite; 495 } 496 if (!m_pProperties->m_pThemeProvider) { 497 m_pProperties->m_pThemeProvider = GetAvailableTheme(); 498 } 499 m_pEdit->SetThemeProvider(m_pProperties->m_pThemeProvider); 500 GetClientRect(m_rtClient); 501 FX_FLOAT* pFWidth = 502 static_cast<FX_FLOAT*>(GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth)); 503 if (!pFWidth) 504 return FWL_ERR_Indefinite; 505 FX_FLOAT fBtn = *pFWidth; 506 m_rtBtn.Set(m_rtClient.right() - fBtn, m_rtClient.top, fBtn - 1, 507 m_rtClient.height - 1); 508 CFX_RectF rtEdit; 509 rtEdit.Set(m_rtClient.left, m_rtClient.top, m_rtClient.width - fBtn, 510 m_rtClient.height); 511 m_pEdit->SetWidgetRect(rtEdit); 512 ReSetEditAlignment(); 513 m_pEdit->Update(); 514 if (!(m_pMonthCal->GetThemeProvider())) { 515 m_pMonthCal->SetThemeProvider(m_pProperties->m_pThemeProvider); 516 } 517 if (m_pProperties->m_pDataProvider) { 518 IFWL_DateTimePickerDP* pData = 519 static_cast<IFWL_DateTimePickerDP*>(m_pProperties->m_pDataProvider); 520 pData->GetToday(m_pInterface, m_MonthCalendarDP.m_iCurYear, 521 m_MonthCalendarDP.m_iCurMonth, m_MonthCalendarDP.m_iCurDay); 522 } 523 CFX_RectF rtMonthCal; 524 m_pMonthCal->GetWidgetRect(rtMonthCal, TRUE); 525 CFX_RectF rtPopUp; 526 rtPopUp.Set(rtMonthCal.left, rtMonthCal.top + FWL_DTP_HEIGHT, 527 rtMonthCal.width, rtMonthCal.height); 528 m_pMonthCal->SetWidgetRect(rtPopUp); 529 m_pMonthCal->Update(); 530 return FWL_ERR_Succeeded; 531 } 532 FX_DWORD CFWL_DateTimePickerImp::HitTest(FX_FLOAT fx, FX_FLOAT fy) { 533 if (m_pWidgetMgr->IsFormDisabled()) { 534 return DisForm_HitTest(fx, fy); 535 } 536 if (m_rtClient.Contains(fx, fy)) { 537 return FWL_WGTHITTEST_Client; 538 } 539 if (IsMonthCalendarShowed()) { 540 CFX_RectF rect; 541 m_pMonthCal->GetWidgetRect(rect); 542 if (rect.Contains(fx, fy)) { 543 return FWL_WGTHITTEST_Client; 544 } 545 } 546 return FWL_WGTHITTEST_Unknown; 547 } 548 FWL_ERR CFWL_DateTimePickerImp::DrawWidget(CFX_Graphics* pGraphics, 549 const CFX_Matrix* pMatrix) { 550 if (!pGraphics) 551 return FWL_ERR_Indefinite; 552 if (!m_pProperties->m_pThemeProvider) 553 return FWL_ERR_Indefinite; 554 IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider; 555 if (HasBorder()) { 556 DrawBorder(pGraphics, FWL_PART_DTP_Border, pTheme, pMatrix); 557 } 558 if (HasEdge()) { 559 DrawEdge(pGraphics, FWL_PART_DTP_Edge, pTheme, pMatrix); 560 } 561 if (!m_rtBtn.IsEmpty()) { 562 DrawDropDownButton(pGraphics, pTheme, pMatrix); 563 } 564 if (m_pWidgetMgr->IsFormDisabled()) { 565 return DisForm_DrawWidget(pGraphics, pMatrix); 566 } 567 return FWL_ERR_Succeeded; 568 } 569 FWL_ERR CFWL_DateTimePickerImp::SetThemeProvider(IFWL_ThemeProvider* pTP) { 570 m_pProperties->m_pThemeProvider = pTP; 571 m_pMonthCal->SetThemeProvider(pTP); 572 return FWL_ERR_Succeeded; 573 } 574 FWL_ERR CFWL_DateTimePickerImp::GetCurSel(int32_t& iYear, 575 int32_t& iMonth, 576 int32_t& iDay) { 577 iYear = m_iYear; 578 iMonth = m_iMonth; 579 iDay = m_iDay; 580 return FWL_ERR_Succeeded; 581 } 582 FWL_ERR CFWL_DateTimePickerImp::SetCurSel(int32_t iYear, 583 int32_t iMonth, 584 int32_t iDay) { 585 if (iYear <= 0 || iYear >= 3000) 586 return FWL_ERR_Indefinite; 587 if (iMonth <= 0 || iMonth >= 13) 588 return FWL_ERR_Indefinite; 589 if (iDay <= 0 || iDay >= 32) 590 return FWL_ERR_Indefinite; 591 m_iYear = iYear; 592 m_iMonth = iMonth; 593 m_iDay = iDay; 594 m_pMonthCal->SetSelect(iYear, iMonth, iDay); 595 return FWL_ERR_Succeeded; 596 } 597 FWL_ERR CFWL_DateTimePickerImp::SetEditText(const CFX_WideString& wsText) { 598 if (!m_pEdit) 599 return FWL_ERR_Indefinite; 600 int32_t iRet = m_pEdit->SetText(wsText); 601 Repaint(&m_rtClient); 602 CFWL_Event_DtpEditChanged ev; 603 ev.m_wsText = wsText; 604 DispatchEvent(&ev); 605 return iRet; 606 } 607 FWL_ERR CFWL_DateTimePickerImp::GetEditText(CFX_WideString& wsText, 608 int32_t nStart, 609 int32_t nCount) const { 610 if (m_pEdit) { 611 return m_pEdit->GetText(wsText, nStart, nCount); 612 } 613 return FWL_ERR_Indefinite; 614 } 615 FX_BOOL CFWL_DateTimePickerImp::CanUndo() { 616 return m_pEdit->CanUndo(); 617 } 618 FX_BOOL CFWL_DateTimePickerImp::CanRedo() { 619 return m_pEdit->CanRedo(); 620 } 621 FX_BOOL CFWL_DateTimePickerImp::Undo() { 622 return m_pEdit->Undo(); 623 } 624 FX_BOOL CFWL_DateTimePickerImp::Redo() { 625 return m_pEdit->Redo(); 626 } 627 FX_BOOL CFWL_DateTimePickerImp::CanCopy() { 628 int32_t nCount = m_pEdit->CountSelRanges(); 629 return nCount > 0; 630 } 631 FX_BOOL CFWL_DateTimePickerImp::CanCut() { 632 if (m_pEdit->GetStylesEx() & FWL_STYLEEXT_EDT_ReadOnly) { 633 return FALSE; 634 } 635 int32_t nCount = m_pEdit->CountSelRanges(); 636 return nCount > 0; 637 } 638 FX_BOOL CFWL_DateTimePickerImp::CanSelectAll() { 639 return m_pEdit->GetTextLength() > 0; 640 } 641 FX_BOOL CFWL_DateTimePickerImp::Copy(CFX_WideString& wsCopy) { 642 return m_pEdit->Copy(wsCopy); 643 } 644 FX_BOOL CFWL_DateTimePickerImp::Cut(CFX_WideString& wsCut) { 645 return m_pEdit->Cut(wsCut); 646 } 647 FX_BOOL CFWL_DateTimePickerImp::Paste(const CFX_WideString& wsPaste) { 648 return m_pEdit->Paste(wsPaste); 649 } 650 FX_BOOL CFWL_DateTimePickerImp::SelectAll() { 651 return m_pEdit->AddSelRange(0) == FWL_ERR_Succeeded; 652 } 653 FX_BOOL CFWL_DateTimePickerImp::Delete() { 654 return m_pEdit->ClearText() == FWL_ERR_Succeeded; 655 } 656 FX_BOOL CFWL_DateTimePickerImp::DeSelect() { 657 return m_pEdit->ClearSelections() == FWL_ERR_Succeeded; 658 } 659 FWL_ERR CFWL_DateTimePickerImp::GetBBox(CFX_RectF& rect) { 660 if (m_pWidgetMgr->IsFormDisabled()) { 661 return DisForm_GetBBox(rect); 662 } 663 rect = m_pProperties->m_rtWidget; 664 if (IsMonthCalendarShowed()) { 665 CFX_RectF rtMonth; 666 m_pMonthCal->GetWidgetRect(rtMonth); 667 rtMonth.Offset(m_pProperties->m_rtWidget.left, 668 m_pProperties->m_rtWidget.top); 669 rect.Union(rtMonth); 670 } 671 return FWL_ERR_Succeeded; 672 } 673 FWL_ERR CFWL_DateTimePickerImp::SetEditLimit(int32_t nLimit) { 674 return m_pEdit->SetLimit(nLimit); 675 } 676 FWL_ERR CFWL_DateTimePickerImp::ModifyEditStylesEx(FX_DWORD dwStylesExAdded, 677 FX_DWORD dwStylesExRemoved) { 678 return m_pEdit->ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved); 679 } 680 void CFWL_DateTimePickerImp::DrawDropDownButton(CFX_Graphics* pGraphics, 681 IFWL_ThemeProvider* pTheme, 682 const CFX_Matrix* pMatrix) { 683 if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_Spin) == 684 FWL_STYLEEXT_DTP_Spin) { 685 CFWL_WidgetImpProperties prop; 686 prop.m_dwStyleExes |= FWL_STYLEEXE_SPB_Vert; 687 prop.m_pParent = m_pInterface; 688 prop.m_rtWidget = m_rtBtn; 689 IFWL_SpinButton* pSpin = IFWL_SpinButton::Create(prop, m_pInterface); 690 pSpin->Initialize(); 691 } else { 692 CFWL_ThemeBackground param; 693 param.m_pWidget = m_pInterface; 694 param.m_iPart = FWL_PART_DTP_DropDownButton; 695 param.m_dwStates = m_iBtnState; 696 param.m_pGraphics = pGraphics; 697 param.m_rtPart = m_rtBtn; 698 if (pMatrix) { 699 param.m_matrix.Concat(*pMatrix); 700 } 701 pTheme->DrawBackground(¶m); 702 } 703 } 704 void CFWL_DateTimePickerImp::FormatDateString(int32_t iYear, 705 int32_t iMonth, 706 int32_t iDay, 707 CFX_WideString& wsText) { 708 if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_ShortDateFormat) == 709 FWL_STYLEEXT_DTP_ShortDateFormat) { 710 wsText.Format(L"%d-%d-%d", iYear, iMonth, iDay); 711 } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_LongDateFormat) == 712 FWL_STYLEEXT_DTP_LongDateFormat) { 713 wsText.Format(L"%d Year %d Month %d Day", iYear, iMonth, iDay); 714 } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_TimeFormat) == 715 FWL_STYLEEXT_DTP_TimeFormat) { 716 } 717 } 718 void CFWL_DateTimePickerImp::ShowMonthCalendar(FX_BOOL bActivate) { 719 if (m_pWidgetMgr->IsFormDisabled()) { 720 return DisForm_ShowMonthCalendar(bActivate); 721 } 722 if (IsMonthCalendarShowed() == bActivate) { 723 return; 724 } 725 if (!m_pForm) { 726 InitProxyForm(); 727 } 728 if (bActivate) { 729 CFX_RectF rtMonth; 730 m_pMonthCal->GetWidgetRect(rtMonth); 731 CFX_RectF rtAnchor; 732 rtAnchor.Set(0, 0, m_pProperties->m_rtWidget.width, 733 m_pProperties->m_rtWidget.height); 734 GetPopupPos(0, rtMonth.height, rtAnchor, rtMonth); 735 m_pForm->SetWidgetRect(rtMonth); 736 rtMonth.left = rtMonth.top = 0; 737 m_pMonthCal->SetStates(FWL_WGTSTATE_Invisible, !bActivate); 738 m_pMonthCal->SetWidgetRect(rtMonth); 739 m_pMonthCal->Update(); 740 m_pForm->DoModal(); 741 } else { 742 m_pForm->EndDoModal(); 743 } 744 } 745 FX_BOOL CFWL_DateTimePickerImp::IsMonthCalendarShowed() { 746 if (m_pWidgetMgr->IsFormDisabled()) { 747 return DisForm_IsMonthCalendarShowed(); 748 } 749 if (!m_pForm) 750 return FALSE; 751 return !(m_pForm->GetStates() & FWL_WGTSTATE_Invisible); 752 } 753 void CFWL_DateTimePickerImp::ReSetEditAlignment() { 754 if (!m_pEdit) 755 return; 756 FX_DWORD dwStylExes = m_pProperties->m_dwStyleExes; 757 FX_DWORD dwAdd = 0; 758 switch (dwStylExes & FWL_STYLEEXT_DTP_EditHAlignMask) { 759 case FWL_STYLEEXT_DTP_EditHCenter: { 760 dwAdd |= FWL_STYLEEXT_EDT_HCenter; 761 break; 762 } 763 case FWL_STYLEEXT_DTP_EditHFar: { 764 dwAdd |= FWL_STYLEEXT_EDT_HFar; 765 break; 766 } 767 default: { dwAdd |= FWL_STYLEEXT_EDT_HNear; } 768 } 769 switch (dwStylExes & FWL_STYLEEXT_DTP_EditVAlignMask) { 770 case FWL_STYLEEXT_DTP_EditVCenter: { 771 dwAdd |= FWL_STYLEEXT_EDT_VCenter; 772 break; 773 } 774 case FWL_STYLEEXT_DTP_EditVFar: { 775 dwAdd |= FWL_STYLEEXT_EDT_VFar; 776 break; 777 } 778 default: { dwAdd |= FWL_STYLEEXT_EDT_VNear; } 779 } 780 if (dwStylExes & FWL_STYLEEXT_DTP_EditJustified) { 781 dwAdd |= FWL_STYLEEXT_EDT_Justified; 782 } 783 if (dwStylExes & FWL_STYLEEXT_DTP_EditDistributed) { 784 dwAdd |= FWL_STYLEEXT_EDT_Distributed; 785 } 786 m_pEdit->ModifyStylesEx(dwAdd, FWL_STYLEEXT_EDT_HAlignMask | 787 FWL_STYLEEXT_EDT_HAlignModeMask | 788 FWL_STYLEEXT_EDT_VAlignMask); 789 } 790 void CFWL_DateTimePickerImp::ProcessSelChanged(int32_t iYear, 791 int32_t iMonth, 792 int32_t iDay) { 793 m_iYear = iYear; 794 m_iMonth = iMonth; 795 m_iDay = iDay; 796 CFX_WideString wsText; 797 FormatDateString(m_iYear, m_iMonth, m_iDay, wsText); 798 m_pEdit->SetText(wsText); 799 m_pEdit->Update(); 800 Repaint(&m_rtClient); 801 CFWL_Event_DtpSelectChanged ev; 802 ev.m_pSrcTarget = m_pInterface; 803 ev.iYear = m_iYear; 804 ev.iMonth = m_iMonth; 805 ev.iDay = m_iDay; 806 DispatchEvent(&ev); 807 } 808 void CFWL_DateTimePickerImp::InitProxyForm() { 809 if (m_pForm) 810 return; 811 if (!m_pMonthCal) 812 return; 813 CFWL_WidgetImpProperties propForm; 814 propForm.m_dwStyles = FWL_WGTSTYLE_Popup; 815 propForm.m_dwStates = FWL_WGTSTATE_Invisible; 816 propForm.m_pOwner = m_pInterface; 817 m_pForm.reset(IFWL_DateTimeForm::Create(propForm, m_pMonthCal.get())); 818 m_pForm->Initialize(); 819 m_pMonthCal->SetParent(m_pForm.get()); 820 } 821 IFWL_DateTimeEdit* CFWL_DateTimePickerImp::GetDataTimeEdit() { 822 return m_pEdit.get(); 823 } 824 FWL_ERR CFWL_DateTimePickerImp::DisForm_Initialize() { 825 m_pProperties->m_dwStyleExes = FWL_STYLEEXT_DTP_ShortDateFormat; 826 DisForm_InitDateTimeCalendar(); 827 DisForm_InitDateTimeEdit(); 828 RegisterEventTarget(m_pMonthCal.get()); 829 RegisterEventTarget(m_pEdit.get()); 830 return FWL_ERR_Succeeded; 831 } 832 void CFWL_DateTimePickerImp::DisForm_InitDateTimeCalendar() { 833 if (m_pMonthCal) { 834 return; 835 } 836 CFWL_WidgetImpProperties propMonth; 837 propMonth.m_dwStyles = 838 FWL_WGTSTYLE_Popup | FWL_WGTSTYLE_Border | FWL_WGTSTYLE_EdgeSunken; 839 propMonth.m_dwStates = FWL_WGTSTATE_Invisible; 840 propMonth.m_pParent = m_pInterface; 841 propMonth.m_pDataProvider = &m_MonthCalendarDP; 842 propMonth.m_pThemeProvider = m_pProperties->m_pThemeProvider; 843 m_pMonthCal.reset(IFWL_DateTimeCalender::Create(propMonth, m_pInterface)); 844 m_pMonthCal->Initialize(); 845 CFX_RectF rtMonthCal; 846 m_pMonthCal->GetWidgetRect(rtMonthCal, TRUE); 847 rtMonthCal.Set(0, 0, rtMonthCal.width, rtMonthCal.height); 848 m_pMonthCal->SetWidgetRect(rtMonthCal); 849 } 850 void CFWL_DateTimePickerImp::DisForm_InitDateTimeEdit() { 851 if (m_pEdit) { 852 return; 853 } 854 CFWL_WidgetImpProperties propEdit; 855 propEdit.m_pParent = m_pInterface; 856 propEdit.m_pThemeProvider = m_pProperties->m_pThemeProvider; 857 m_pEdit.reset(IFWL_DateTimeEdit::Create(propEdit, m_pInterface)); 858 m_pEdit->Initialize(); 859 } 860 FX_BOOL CFWL_DateTimePickerImp::DisForm_IsMonthCalendarShowed() { 861 if (!m_pMonthCal) 862 return FALSE; 863 return !(m_pMonthCal->GetStates() & FWL_WGTSTATE_Invisible); 864 } 865 void CFWL_DateTimePickerImp::DisForm_ShowMonthCalendar(FX_BOOL bActivate) { 866 FX_BOOL bShowed = IsMonthCalendarShowed(); 867 if (bShowed == bActivate) { 868 return; 869 } 870 if (bActivate) { 871 CFX_RectF rtMonthCal; 872 m_pMonthCal->GetWidgetRect(rtMonthCal, TRUE); 873 FX_FLOAT fPopupMin = rtMonthCal.height; 874 FX_FLOAT fPopupMax = rtMonthCal.height; 875 CFX_RectF rtAnchor(m_pProperties->m_rtWidget); 876 rtAnchor.width = rtMonthCal.width; 877 rtMonthCal.left = m_rtClient.left; 878 rtMonthCal.top = rtAnchor.Height(); 879 GetPopupPos(fPopupMin, fPopupMax, rtAnchor, rtMonthCal); 880 m_pMonthCal->SetWidgetRect(rtMonthCal); 881 if (m_iYear > 0 && m_iMonth > 0 && m_iDay > 0) { 882 m_pMonthCal->SetSelect(m_iYear, m_iMonth, m_iDay); 883 } 884 m_pMonthCal->Update(); 885 } 886 m_pMonthCal->SetStates(FWL_WGTSTATE_Invisible, !bActivate); 887 if (bActivate) { 888 CFWL_MsgSetFocus msg; 889 msg.m_pDstTarget = m_pMonthCal.get(); 890 msg.m_pSrcTarget = m_pEdit.get(); 891 IFWL_WidgetDelegate* pDelegate = m_pEdit->SetDelegate(NULL); 892 pDelegate->OnProcessMessage(&msg); 893 } 894 CFX_RectF rtInvalidate, rtCal; 895 rtInvalidate.Set(0, 0, m_pProperties->m_rtWidget.width, 896 m_pProperties->m_rtWidget.height); 897 m_pMonthCal->GetWidgetRect(rtCal); 898 rtInvalidate.Union(rtCal); 899 rtInvalidate.Inflate(2, 2); 900 Repaint(&rtInvalidate); 901 } 902 FX_DWORD CFWL_DateTimePickerImp::DisForm_HitTest(FX_FLOAT fx, FX_FLOAT fy) { 903 CFX_RectF rect; 904 rect.Set(0, 0, m_pProperties->m_rtWidget.width, 905 m_pProperties->m_rtWidget.height); 906 if (rect.Contains(fx, fy)) { 907 return FWL_WGTHITTEST_Edit; 908 } 909 if (DisForm_IsNeedShowButton()) { 910 rect.width += m_fBtn; 911 } 912 if (rect.Contains(fx, fy)) { 913 return FWL_WGTHITTEST_Client; 914 } 915 if (IsMonthCalendarShowed()) { 916 m_pMonthCal->GetWidgetRect(rect); 917 if (rect.Contains(fx, fy)) { 918 return FWL_WGTHITTEST_Client; 919 } 920 } 921 return FWL_WGTHITTEST_Unknown; 922 } 923 FX_BOOL CFWL_DateTimePickerImp::DisForm_IsNeedShowButton() { 924 FX_BOOL bFocus = m_pProperties->m_dwStates & FWL_WGTSTATE_Focused || 925 m_pMonthCal->GetStates() & FWL_WGTSTATE_Focused || 926 m_pEdit->GetStates() & FWL_WGTSTATE_Focused; 927 return bFocus; 928 } 929 FWL_ERR CFWL_DateTimePickerImp::DisForm_Update() { 930 if (m_iLock) { 931 return FWL_ERR_Indefinite; 932 } 933 if (!m_pProperties->m_pThemeProvider) { 934 m_pProperties->m_pThemeProvider = GetAvailableTheme(); 935 } 936 m_pEdit->SetThemeProvider(m_pProperties->m_pThemeProvider); 937 GetClientRect(m_rtClient); 938 m_pEdit->SetWidgetRect(m_rtClient); 939 ReSetEditAlignment(); 940 m_pEdit->Update(); 941 if (m_pMonthCal->GetThemeProvider() == NULL) { 942 m_pMonthCal->SetThemeProvider(m_pProperties->m_pThemeProvider); 943 } 944 if (m_pProperties->m_pDataProvider) { 945 IFWL_DateTimePickerDP* pData = 946 static_cast<IFWL_DateTimePickerDP*>(m_pProperties->m_pDataProvider); 947 pData->GetToday(m_pInterface, m_MonthCalendarDP.m_iCurYear, 948 m_MonthCalendarDP.m_iCurMonth, m_MonthCalendarDP.m_iCurDay); 949 } 950 FX_FLOAT* pWidth = 951 static_cast<FX_FLOAT*>(GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth)); 952 if (!pWidth) 953 return 0; 954 m_fBtn = *pWidth; 955 CFX_RectF rtMonthCal; 956 m_pMonthCal->GetWidgetRect(rtMonthCal, TRUE); 957 CFX_RectF rtPopUp; 958 rtPopUp.Set(rtMonthCal.left, rtMonthCal.top + FWL_DTP_HEIGHT, 959 rtMonthCal.width, rtMonthCal.height); 960 m_pMonthCal->SetWidgetRect(rtPopUp); 961 m_pMonthCal->Update(); 962 return FWL_ERR_Succeeded; 963 } 964 FWL_ERR CFWL_DateTimePickerImp::DisForm_GetWidgetRect(CFX_RectF& rect, 965 FX_BOOL bAutoSize) { 966 rect = m_pProperties->m_rtWidget; 967 if (DisForm_IsNeedShowButton()) { 968 rect.width += m_fBtn; 969 } 970 return FWL_ERR_Succeeded; 971 } 972 FWL_ERR CFWL_DateTimePickerImp::DisForm_GetBBox(CFX_RectF& rect) { 973 rect = m_pProperties->m_rtWidget; 974 if (DisForm_IsNeedShowButton()) { 975 rect.width += m_fBtn; 976 } 977 if (IsMonthCalendarShowed()) { 978 CFX_RectF rtMonth; 979 m_pMonthCal->GetWidgetRect(rtMonth); 980 rtMonth.Offset(m_pProperties->m_rtWidget.left, 981 m_pProperties->m_rtWidget.top); 982 rect.Union(rtMonth); 983 } 984 return FWL_ERR_Succeeded; 985 } 986 FWL_ERR CFWL_DateTimePickerImp::DisForm_DrawWidget(CFX_Graphics* pGraphics, 987 const CFX_Matrix* pMatrix) { 988 if (!pGraphics) 989 return FWL_ERR_Indefinite; 990 if (m_pEdit) { 991 CFX_RectF rtEdit; 992 m_pEdit->GetWidgetRect(rtEdit); 993 CFX_Matrix mt; 994 mt.Set(1, 0, 0, 1, rtEdit.left, rtEdit.top); 995 if (pMatrix) { 996 mt.Concat(*pMatrix); 997 } 998 m_pEdit->DrawWidget(pGraphics, &mt); 999 } 1000 if (IsMonthCalendarShowed()) { 1001 CFX_RectF rtMonth; 1002 m_pMonthCal->GetWidgetRect(rtMonth); 1003 CFX_Matrix mt; 1004 mt.Set(1, 0, 0, 1, rtMonth.left, rtMonth.top); 1005 if (pMatrix) { 1006 mt.Concat(*pMatrix); 1007 } 1008 m_pMonthCal->DrawWidget(pGraphics, &mt); 1009 } 1010 return FWL_ERR_Succeeded; 1011 } 1012 CFWL_DateTimePickerImpDelegate::CFWL_DateTimePickerImpDelegate( 1013 CFWL_DateTimePickerImp* pOwner) 1014 : m_pOwner(pOwner) {} 1015 int32_t CFWL_DateTimePickerImpDelegate::OnProcessMessage( 1016 CFWL_Message* pMessage) { 1017 if (!pMessage) 1018 return 0; 1019 FX_DWORD dwMsgCode = pMessage->GetClassID(); 1020 int32_t iRet = 1; 1021 switch (dwMsgCode) { 1022 case FWL_MSGHASH_SetFocus: 1023 case FWL_MSGHASH_KillFocus: { 1024 OnFocusChanged(pMessage, dwMsgCode == FWL_MSGHASH_SetFocus); 1025 break; 1026 } 1027 case FWL_MSGHASH_Mouse: { 1028 CFWL_MsgMouse* pMouse = static_cast<CFWL_MsgMouse*>(pMessage); 1029 FX_DWORD dwCmd = pMouse->m_dwCmd; 1030 switch (dwCmd) { 1031 case FWL_MSGMOUSECMD_LButtonDown: { 1032 OnLButtonDown(pMouse); 1033 break; 1034 } 1035 case FWL_MSGMOUSECMD_LButtonUp: { 1036 OnLButtonUp(pMouse); 1037 break; 1038 } 1039 case FWL_MSGMOUSECMD_MouseMove: { 1040 OnMouseMove(pMouse); 1041 break; 1042 } 1043 case FWL_MSGMOUSECMD_MouseLeave: { 1044 OnMouseLeave(pMouse); 1045 break; 1046 } 1047 default: {} 1048 } 1049 break; 1050 } 1051 default: { iRet = 0; } 1052 } 1053 if (dwMsgCode == FWL_MSGHASH_Key && 1054 m_pOwner->m_pEdit->GetStates() & FWL_WGTSTATE_Focused) { 1055 IFWL_WidgetDelegate* pDelegate = m_pOwner->m_pEdit->SetDelegate(NULL); 1056 return pDelegate->OnProcessMessage(pMessage); 1057 } 1058 return CFWL_WidgetImpDelegate::OnProcessMessage(pMessage); 1059 } 1060 FWL_ERR CFWL_DateTimePickerImpDelegate::OnDrawWidget( 1061 CFX_Graphics* pGraphics, 1062 const CFX_Matrix* pMatrix) { 1063 return m_pOwner->DrawWidget(pGraphics, pMatrix); 1064 } 1065 void CFWL_DateTimePickerImpDelegate::OnFocusChanged(CFWL_Message* pMsg, 1066 FX_BOOL bSet) { 1067 if (!pMsg) 1068 return; 1069 if (m_pOwner->m_pWidgetMgr->IsFormDisabled()) { 1070 return DisForm_OnFocusChanged(pMsg, bSet); 1071 } 1072 if (bSet) { 1073 m_pOwner->m_pProperties->m_dwStates |= (FWL_WGTSTATE_Focused); 1074 m_pOwner->Repaint(&m_pOwner->m_rtClient); 1075 } else { 1076 m_pOwner->m_pProperties->m_dwStates &= ~(FWL_WGTSTATE_Focused); 1077 m_pOwner->Repaint(&m_pOwner->m_rtClient); 1078 } 1079 if (pMsg->m_pSrcTarget == m_pOwner->m_pMonthCal.get() && 1080 m_pOwner->IsMonthCalendarShowed()) { 1081 m_pOwner->ShowMonthCalendar(FALSE); 1082 } 1083 m_pOwner->Repaint(&m_pOwner->m_rtClient); 1084 } 1085 void CFWL_DateTimePickerImpDelegate::OnLButtonDown(CFWL_MsgMouse* pMsg) { 1086 if (!pMsg) 1087 return; 1088 if ((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) { 1089 m_pOwner->SetFocus(TRUE); 1090 } 1091 if (m_pOwner->m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) { 1092 if (m_pOwner->IsMonthCalendarShowed()) { 1093 m_pOwner->ShowMonthCalendar(FALSE); 1094 CFWL_Event_DtpCloseUp ev; 1095 m_pOwner->DispatchEvent(&ev); 1096 } else { 1097 if (!(m_pOwner->m_pProperties->m_dwStyleExes & 1098 FWL_STYLEEXT_DTP_TimeFormat)) { 1099 m_pOwner->ShowMonthCalendar(TRUE); 1100 CFWL_Event_DtpDropDown ev; 1101 m_pOwner->DispatchEvent(&ev); 1102 } else { 1103 } 1104 m_pOwner->m_bLBtnDown = TRUE; 1105 m_pOwner->Repaint(&m_pOwner->m_rtClient); 1106 } 1107 } 1108 } 1109 void CFWL_DateTimePickerImpDelegate::OnLButtonUp(CFWL_MsgMouse* pMsg) { 1110 if (!pMsg) 1111 return; 1112 m_pOwner->m_bLBtnDown = FALSE; 1113 if (m_pOwner->m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) { 1114 m_pOwner->m_iBtnState = FWL_PARTSTATE_DTP_Hovered; 1115 } else { 1116 m_pOwner->m_iBtnState = FWL_PARTSTATE_DTP_Normal; 1117 } 1118 m_pOwner->Repaint(&m_pOwner->m_rtBtn); 1119 } 1120 void CFWL_DateTimePickerImpDelegate::OnMouseMove(CFWL_MsgMouse* pMsg) { 1121 if (m_pOwner->m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) { 1122 } else { 1123 m_pOwner->m_iBtnState = FWL_PARTSTATE_DTP_Normal; 1124 } 1125 m_pOwner->Repaint(&m_pOwner->m_rtBtn); 1126 } 1127 void CFWL_DateTimePickerImpDelegate::OnMouseLeave(CFWL_MsgMouse* pMsg) { 1128 if (!pMsg) 1129 return; 1130 m_pOwner->m_iBtnState = FWL_PARTSTATE_DTP_Normal; 1131 m_pOwner->Repaint(&m_pOwner->m_rtBtn); 1132 } 1133 void CFWL_DateTimePickerImpDelegate::DisForm_OnFocusChanged(CFWL_Message* pMsg, 1134 FX_BOOL bSet) { 1135 CFX_RectF rtInvalidate(m_pOwner->m_rtBtn); 1136 if (bSet) { 1137 m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused; 1138 if (m_pOwner->m_pEdit && 1139 !(m_pOwner->m_pEdit->GetStylesEx() & FWL_STYLEEXT_EDT_ReadOnly)) { 1140 m_pOwner->m_rtBtn.Set(m_pOwner->m_pProperties->m_rtWidget.width, 0, 1141 m_pOwner->m_fBtn, 1142 m_pOwner->m_pProperties->m_rtWidget.height - 1); 1143 } 1144 rtInvalidate = m_pOwner->m_rtBtn; 1145 pMsg->m_pDstTarget = m_pOwner->m_pEdit.get(); 1146 IFWL_WidgetDelegate* pDelegate = m_pOwner->m_pEdit->SetDelegate(NULL); 1147 pDelegate->OnProcessMessage(pMsg); 1148 } else { 1149 m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused; 1150 m_pOwner->m_rtBtn.Set(0, 0, 0, 0); 1151 if (m_pOwner->DisForm_IsMonthCalendarShowed()) { 1152 m_pOwner->ShowMonthCalendar(FALSE); 1153 } 1154 if (m_pOwner->m_pEdit->GetStates() & FWL_WGTSTATE_Focused) { 1155 pMsg->m_pSrcTarget = m_pOwner->m_pEdit.get(); 1156 IFWL_WidgetDelegate* pDelegate = m_pOwner->m_pEdit->SetDelegate(NULL); 1157 pDelegate->OnProcessMessage(pMsg); 1158 } 1159 } 1160 rtInvalidate.Inflate(2, 2); 1161 m_pOwner->Repaint(&rtInvalidate); 1162 } 1163