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/cfwl_datetimepicker.h"
8
9 #include <memory>
10 #include <utility>
11
12 #include "third_party/base/ptr_util.h"
13 #include "xfa/fwl/cfwl_event.h"
14 #include "xfa/fwl/cfwl_eventselectchanged.h"
15 #include "xfa/fwl/cfwl_formproxy.h"
16 #include "xfa/fwl/cfwl_messagemouse.h"
17 #include "xfa/fwl/cfwl_messagesetfocus.h"
18 #include "xfa/fwl/cfwl_notedriver.h"
19 #include "xfa/fwl/cfwl_spinbutton.h"
20 #include "xfa/fwl/cfwl_themebackground.h"
21 #include "xfa/fwl/cfwl_widgetmgr.h"
22 #include "xfa/fwl/ifwl_themeprovider.h"
23
24 namespace {
25
26 const int kDateTimePickerHeight = 20;
27
28 } // namespace
CFWL_DateTimePicker(const CFWL_App * app)29 CFWL_DateTimePicker::CFWL_DateTimePicker(const CFWL_App* app)
30 : CFWL_Widget(app, pdfium::MakeUnique<CFWL_WidgetProperties>(), nullptr),
31 m_iBtnState(1),
32 m_iYear(-1),
33 m_iMonth(-1),
34 m_iDay(-1),
35 m_bLBtnDown(false) {
36 m_pProperties->m_dwStyleExes = FWL_STYLEEXT_DTP_ShortDateFormat;
37
38 auto monthProp = pdfium::MakeUnique<CFWL_WidgetProperties>();
39 monthProp->m_dwStyles = FWL_WGTSTYLE_Popup | FWL_WGTSTYLE_Border;
40 monthProp->m_dwStates = FWL_WGTSTATE_Invisible;
41 monthProp->m_pParent = this;
42 monthProp->m_pThemeProvider = m_pProperties->m_pThemeProvider;
43 m_pMonthCal.reset(
44 new CFWL_MonthCalendar(m_pOwnerApp, std::move(monthProp), this));
45
46 m_pMonthCal->SetWidgetRect(
47 CFX_RectF(0, 0, m_pMonthCal->GetAutosizedWidgetRect().Size()));
48
49 auto editProp = pdfium::MakeUnique<CFWL_WidgetProperties>();
50 editProp->m_pParent = this;
51 editProp->m_pThemeProvider = m_pProperties->m_pThemeProvider;
52
53 m_pEdit = pdfium::MakeUnique<CFWL_DateTimeEdit>(m_pOwnerApp,
54 std::move(editProp), this);
55 RegisterEventTarget(m_pMonthCal.get());
56 RegisterEventTarget(m_pEdit.get());
57 }
58
~CFWL_DateTimePicker()59 CFWL_DateTimePicker::~CFWL_DateTimePicker() {
60 UnregisterEventTarget();
61 }
62
GetClassID() const63 FWL_Type CFWL_DateTimePicker::GetClassID() const {
64 return FWL_Type::DateTimePicker;
65 }
66
Update()67 void CFWL_DateTimePicker::Update() {
68 if (m_pWidgetMgr->IsFormDisabled()) {
69 DisForm_Update();
70 return;
71 }
72 if (m_iLock)
73 return;
74 if (!m_pProperties->m_pThemeProvider)
75 m_pProperties->m_pThemeProvider = GetAvailableTheme();
76
77 m_pEdit->SetThemeProvider(m_pProperties->m_pThemeProvider);
78 m_rtClient = GetClientRect();
79
80 IFWL_ThemeProvider* theme = GetAvailableTheme();
81 if (!theme)
82 return;
83
84 FX_FLOAT fBtn = theme->GetScrollBarWidth();
85 m_rtBtn = CFX_RectF(m_rtClient.right() - fBtn, m_rtClient.top, fBtn - 1,
86 m_rtClient.height - 1);
87
88 CFX_RectF rtEdit(m_rtClient.left, m_rtClient.top, m_rtClient.width - fBtn,
89 m_rtClient.height);
90 m_pEdit->SetWidgetRect(rtEdit);
91 ResetEditAlignment();
92 m_pEdit->Update();
93 if (!(m_pMonthCal->GetThemeProvider()))
94 m_pMonthCal->SetThemeProvider(m_pProperties->m_pThemeProvider);
95
96 CFX_RectF rtMonthCal = m_pMonthCal->GetAutosizedWidgetRect();
97 CFX_RectF rtPopUp(rtMonthCal.left, rtMonthCal.top + kDateTimePickerHeight,
98 rtMonthCal.width, rtMonthCal.height);
99 m_pMonthCal->SetWidgetRect(rtPopUp);
100 m_pMonthCal->Update();
101 return;
102 }
103
HitTest(const CFX_PointF & point)104 FWL_WidgetHit CFWL_DateTimePicker::HitTest(const CFX_PointF& point) {
105 if (m_pWidgetMgr->IsFormDisabled())
106 return DisForm_HitTest(point);
107 if (m_rtClient.Contains(point))
108 return FWL_WidgetHit::Client;
109 if (IsMonthCalendarVisible()) {
110 CFX_RectF rect = m_pMonthCal->GetWidgetRect();
111 if (rect.Contains(point))
112 return FWL_WidgetHit::Client;
113 }
114 return FWL_WidgetHit::Unknown;
115 }
116
DrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)117 void CFWL_DateTimePicker::DrawWidget(CFX_Graphics* pGraphics,
118 const CFX_Matrix* pMatrix) {
119 if (!pGraphics)
120 return;
121 if (!m_pProperties->m_pThemeProvider)
122 return;
123
124 IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
125 if (HasBorder())
126 DrawBorder(pGraphics, CFWL_Part::Border, pTheme, pMatrix);
127 if (!m_rtBtn.IsEmpty())
128 DrawDropDownButton(pGraphics, pTheme, pMatrix);
129 if (m_pWidgetMgr->IsFormDisabled()) {
130 DisForm_DrawWidget(pGraphics, pMatrix);
131 return;
132 }
133 }
134
SetThemeProvider(IFWL_ThemeProvider * pTP)135 void CFWL_DateTimePicker::SetThemeProvider(IFWL_ThemeProvider* pTP) {
136 m_pProperties->m_pThemeProvider = pTP;
137 m_pMonthCal->SetThemeProvider(pTP);
138 }
139
GetCurSel(int32_t & iYear,int32_t & iMonth,int32_t & iDay)140 void CFWL_DateTimePicker::GetCurSel(int32_t& iYear,
141 int32_t& iMonth,
142 int32_t& iDay) {
143 iYear = m_iYear;
144 iMonth = m_iMonth;
145 iDay = m_iDay;
146 }
147
SetCurSel(int32_t iYear,int32_t iMonth,int32_t iDay)148 void CFWL_DateTimePicker::SetCurSel(int32_t iYear,
149 int32_t iMonth,
150 int32_t iDay) {
151 if (iYear <= 0 || iYear >= 3000)
152 return;
153 if (iMonth <= 0 || iMonth >= 13)
154 return;
155 if (iDay <= 0 || iDay >= 32)
156 return;
157
158 m_iYear = iYear;
159 m_iMonth = iMonth;
160 m_iDay = iDay;
161 m_pMonthCal->SetSelect(iYear, iMonth, iDay);
162 }
163
SetEditText(const CFX_WideString & wsText)164 void CFWL_DateTimePicker::SetEditText(const CFX_WideString& wsText) {
165 if (!m_pEdit)
166 return;
167
168 m_pEdit->SetText(wsText);
169 RepaintRect(m_rtClient);
170
171 CFWL_Event ev(CFWL_Event::Type::EditChanged);
172 DispatchEvent(&ev);
173 }
174
GetEditText() const175 CFX_WideString CFWL_DateTimePicker::GetEditText() const {
176 return m_pEdit ? m_pEdit->GetText() : L"";
177 }
178
GetBBox() const179 CFX_RectF CFWL_DateTimePicker::GetBBox() const {
180 if (m_pWidgetMgr->IsFormDisabled())
181 return DisForm_GetBBox();
182
183 CFX_RectF rect = m_pProperties->m_rtWidget;
184 if (!IsMonthCalendarVisible())
185 return rect;
186
187 CFX_RectF rtMonth = m_pMonthCal->GetWidgetRect();
188 rtMonth.Offset(m_pProperties->m_rtWidget.left, m_pProperties->m_rtWidget.top);
189 rect.Union(rtMonth);
190 return rect;
191 }
192
ModifyEditStylesEx(uint32_t dwStylesExAdded,uint32_t dwStylesExRemoved)193 void CFWL_DateTimePicker::ModifyEditStylesEx(uint32_t dwStylesExAdded,
194 uint32_t dwStylesExRemoved) {
195 m_pEdit->ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
196 }
197
DrawDropDownButton(CFX_Graphics * pGraphics,IFWL_ThemeProvider * pTheme,const CFX_Matrix * pMatrix)198 void CFWL_DateTimePicker::DrawDropDownButton(CFX_Graphics* pGraphics,
199 IFWL_ThemeProvider* pTheme,
200 const CFX_Matrix* pMatrix) {
201 CFWL_ThemeBackground param;
202 param.m_pWidget = this;
203 param.m_iPart = CFWL_Part::DropDownButton;
204 param.m_dwStates = m_iBtnState;
205 param.m_pGraphics = pGraphics;
206 param.m_rtPart = m_rtBtn;
207 if (pMatrix)
208 param.m_matrix.Concat(*pMatrix);
209 pTheme->DrawBackground(¶m);
210 }
211
FormatDateString(int32_t iYear,int32_t iMonth,int32_t iDay,CFX_WideString & wsText)212 void CFWL_DateTimePicker::FormatDateString(int32_t iYear,
213 int32_t iMonth,
214 int32_t iDay,
215 CFX_WideString& wsText) {
216 if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_ShortDateFormat) ==
217 FWL_STYLEEXT_DTP_ShortDateFormat) {
218 wsText.Format(L"%d-%d-%d", iYear, iMonth, iDay);
219 } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_LongDateFormat) ==
220 FWL_STYLEEXT_DTP_LongDateFormat) {
221 wsText.Format(L"%d Year %d Month %d Day", iYear, iMonth, iDay);
222 }
223 }
224
ShowMonthCalendar(bool bActivate)225 void CFWL_DateTimePicker::ShowMonthCalendar(bool bActivate) {
226 if (m_pWidgetMgr->IsFormDisabled())
227 return DisForm_ShowMonthCalendar(bActivate);
228 if (IsMonthCalendarVisible() == bActivate)
229 return;
230 if (!m_pForm)
231 InitProxyForm();
232
233 if (!bActivate) {
234 m_pForm->EndDoModal();
235 return;
236 }
237
238 CFX_RectF rtMonth = m_pMonthCal->GetWidgetRect();
239
240 CFX_RectF rtAnchor(0, 0, m_pProperties->m_rtWidget.width,
241 m_pProperties->m_rtWidget.height);
242 GetPopupPos(0, rtMonth.height, rtAnchor, rtMonth);
243 m_pForm->SetWidgetRect(rtMonth);
244
245 rtMonth.left = rtMonth.top = 0;
246 if (bActivate)
247 m_pMonthCal->RemoveStates(FWL_WGTSTATE_Invisible);
248 else
249 m_pMonthCal->SetStates(FWL_WGTSTATE_Invisible);
250 m_pMonthCal->SetWidgetRect(rtMonth);
251 m_pMonthCal->Update();
252 m_pForm->DoModal();
253 }
254
IsMonthCalendarVisible() const255 bool CFWL_DateTimePicker::IsMonthCalendarVisible() const {
256 if (m_pWidgetMgr->IsFormDisabled())
257 return DisForm_IsMonthCalendarVisible();
258 if (!m_pForm)
259 return false;
260 return !(m_pForm->GetStates() & FWL_WGTSTATE_Invisible);
261 }
262
ResetEditAlignment()263 void CFWL_DateTimePicker::ResetEditAlignment() {
264 if (!m_pEdit)
265 return;
266
267 uint32_t dwAdd = 0;
268 switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_EditHAlignMask) {
269 case FWL_STYLEEXT_DTP_EditHCenter: {
270 dwAdd |= FWL_STYLEEXT_EDT_HCenter;
271 break;
272 }
273 case FWL_STYLEEXT_DTP_EditHFar: {
274 dwAdd |= FWL_STYLEEXT_EDT_HFar;
275 break;
276 }
277 default: {
278 dwAdd |= FWL_STYLEEXT_EDT_HNear;
279 break;
280 }
281 }
282 switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_EditVAlignMask) {
283 case FWL_STYLEEXT_DTP_EditVCenter: {
284 dwAdd |= FWL_STYLEEXT_EDT_VCenter;
285 break;
286 }
287 case FWL_STYLEEXT_DTP_EditVFar: {
288 dwAdd |= FWL_STYLEEXT_EDT_VFar;
289 break;
290 }
291 default: {
292 dwAdd |= FWL_STYLEEXT_EDT_VNear;
293 break;
294 }
295 }
296 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_EditJustified)
297 dwAdd |= FWL_STYLEEXT_EDT_Justified;
298
299 m_pEdit->ModifyStylesEx(dwAdd, FWL_STYLEEXT_EDT_HAlignMask |
300 FWL_STYLEEXT_EDT_HAlignModeMask |
301 FWL_STYLEEXT_EDT_VAlignMask);
302 }
303
ProcessSelChanged(int32_t iYear,int32_t iMonth,int32_t iDay)304 void CFWL_DateTimePicker::ProcessSelChanged(int32_t iYear,
305 int32_t iMonth,
306 int32_t iDay) {
307 m_iYear = iYear;
308 m_iMonth = iMonth;
309 m_iDay = iDay;
310
311 CFX_WideString wsText;
312 FormatDateString(m_iYear, m_iMonth, m_iDay, wsText);
313 m_pEdit->SetText(wsText);
314 m_pEdit->Update();
315 RepaintRect(m_rtClient);
316
317 CFWL_EventSelectChanged ev(this);
318 ev.iYear = m_iYear;
319 ev.iMonth = m_iMonth;
320 ev.iDay = m_iDay;
321 DispatchEvent(&ev);
322 }
323
InitProxyForm()324 void CFWL_DateTimePicker::InitProxyForm() {
325 if (m_pForm)
326 return;
327 if (!m_pMonthCal)
328 return;
329
330 auto prop = pdfium::MakeUnique<CFWL_WidgetProperties>();
331 prop->m_dwStyles = FWL_WGTSTYLE_Popup;
332 prop->m_dwStates = FWL_WGTSTATE_Invisible;
333 prop->m_pOwner = this;
334
335 m_pForm = pdfium::MakeUnique<CFWL_FormProxy>(m_pOwnerApp, std::move(prop),
336 m_pMonthCal.get());
337 m_pMonthCal->SetParent(m_pForm.get());
338 }
339
DisForm_IsMonthCalendarVisible() const340 bool CFWL_DateTimePicker::DisForm_IsMonthCalendarVisible() const {
341 if (!m_pMonthCal)
342 return false;
343 return !(m_pMonthCal->GetStates() & FWL_WGTSTATE_Invisible);
344 }
345
DisForm_ShowMonthCalendar(bool bActivate)346 void CFWL_DateTimePicker::DisForm_ShowMonthCalendar(bool bActivate) {
347 if (IsMonthCalendarVisible() == bActivate)
348 return;
349
350 if (bActivate) {
351 CFX_RectF rtMonthCal = m_pMonthCal->GetAutosizedWidgetRect();
352 FX_FLOAT fPopupMin = rtMonthCal.height;
353 FX_FLOAT fPopupMax = rtMonthCal.height;
354 CFX_RectF rtAnchor(m_pProperties->m_rtWidget);
355 rtAnchor.width = rtMonthCal.width;
356 rtMonthCal.left = m_rtClient.left;
357 rtMonthCal.top = rtAnchor.Height();
358 GetPopupPos(fPopupMin, fPopupMax, rtAnchor, rtMonthCal);
359 m_pMonthCal->SetWidgetRect(rtMonthCal);
360 if (m_iYear > 0 && m_iMonth > 0 && m_iDay > 0)
361 m_pMonthCal->SetSelect(m_iYear, m_iMonth, m_iDay);
362 m_pMonthCal->Update();
363 }
364 if (bActivate)
365 m_pMonthCal->RemoveStates(FWL_WGTSTATE_Invisible);
366 else
367 m_pMonthCal->SetStates(FWL_WGTSTATE_Invisible);
368
369 if (bActivate) {
370 CFWL_MessageSetFocus msg(m_pEdit.get(), m_pMonthCal.get());
371 m_pEdit->GetDelegate()->OnProcessMessage(&msg);
372 }
373
374 CFX_RectF rtInvalidate(0, 0, m_pProperties->m_rtWidget.width,
375 m_pProperties->m_rtWidget.height);
376
377 CFX_RectF rtCal = m_pMonthCal->GetWidgetRect();
378 rtInvalidate.Union(rtCal);
379 rtInvalidate.Inflate(2, 2);
380 RepaintRect(rtInvalidate);
381 }
382
DisForm_HitTest(const CFX_PointF & point) const383 FWL_WidgetHit CFWL_DateTimePicker::DisForm_HitTest(
384 const CFX_PointF& point) const {
385 CFX_RectF rect(0, 0, m_pProperties->m_rtWidget.width,
386 m_pProperties->m_rtWidget.height);
387 if (rect.Contains(point))
388 return FWL_WidgetHit::Edit;
389 if (DisForm_IsNeedShowButton())
390 rect.width += m_fBtn;
391 if (rect.Contains(point))
392 return FWL_WidgetHit::Client;
393 if (IsMonthCalendarVisible()) {
394 if (m_pMonthCal->GetWidgetRect().Contains(point))
395 return FWL_WidgetHit::Client;
396 }
397 return FWL_WidgetHit::Unknown;
398 }
399
DisForm_IsNeedShowButton() const400 bool CFWL_DateTimePicker::DisForm_IsNeedShowButton() const {
401 return m_pProperties->m_dwStates & FWL_WGTSTATE_Focused ||
402 m_pMonthCal->GetStates() & FWL_WGTSTATE_Focused ||
403 m_pEdit->GetStates() & FWL_WGTSTATE_Focused;
404 }
405
DisForm_Update()406 void CFWL_DateTimePicker::DisForm_Update() {
407 if (m_iLock)
408 return;
409 if (!m_pProperties->m_pThemeProvider)
410 m_pProperties->m_pThemeProvider = GetAvailableTheme();
411
412 m_pEdit->SetThemeProvider(m_pProperties->m_pThemeProvider);
413 m_rtClient = GetClientRect();
414 m_pEdit->SetWidgetRect(m_rtClient);
415 ResetEditAlignment();
416 m_pEdit->Update();
417
418 if (!m_pMonthCal->GetThemeProvider())
419 m_pMonthCal->SetThemeProvider(m_pProperties->m_pThemeProvider);
420
421 IFWL_ThemeProvider* theme = GetAvailableTheme();
422 if (!theme)
423 return;
424
425 m_fBtn = theme->GetScrollBarWidth();
426 CFX_RectF rtMonthCal = m_pMonthCal->GetAutosizedWidgetRect();
427 CFX_RectF rtPopUp(rtMonthCal.left, rtMonthCal.top + kDateTimePickerHeight,
428 rtMonthCal.width, rtMonthCal.height);
429 m_pMonthCal->SetWidgetRect(rtPopUp);
430 m_pMonthCal->Update();
431 }
432
DisForm_GetBBox() const433 CFX_RectF CFWL_DateTimePicker::DisForm_GetBBox() const {
434 CFX_RectF rect = m_pProperties->m_rtWidget;
435 if (DisForm_IsNeedShowButton())
436 rect.width += m_fBtn;
437 if (!IsMonthCalendarVisible())
438 return rect;
439
440 CFX_RectF rtMonth = m_pMonthCal->GetWidgetRect();
441 rtMonth.Offset(m_pProperties->m_rtWidget.left, m_pProperties->m_rtWidget.top);
442 rect.Union(rtMonth);
443 return rect;
444 }
445
DisForm_DrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)446 void CFWL_DateTimePicker::DisForm_DrawWidget(CFX_Graphics* pGraphics,
447 const CFX_Matrix* pMatrix) {
448 if (!pGraphics)
449 return;
450 if (m_pEdit) {
451 CFX_RectF rtEdit = m_pEdit->GetWidgetRect();
452
453 CFX_Matrix mt(1, 0, 0, 1, rtEdit.left, rtEdit.top);
454 if (pMatrix)
455 mt.Concat(*pMatrix);
456 m_pEdit->DrawWidget(pGraphics, &mt);
457 }
458 if (!IsMonthCalendarVisible())
459 return;
460
461 CFX_RectF rtMonth = m_pMonthCal->GetWidgetRect();
462 CFX_Matrix mt(1, 0, 0, 1, rtMonth.left, rtMonth.top);
463 if (pMatrix)
464 mt.Concat(*pMatrix);
465 m_pMonthCal->DrawWidget(pGraphics, &mt);
466 }
467
OnProcessMessage(CFWL_Message * pMessage)468 void CFWL_DateTimePicker::OnProcessMessage(CFWL_Message* pMessage) {
469 if (!pMessage)
470 return;
471
472 switch (pMessage->GetType()) {
473 case CFWL_Message::Type::SetFocus:
474 OnFocusChanged(pMessage, true);
475 break;
476 case CFWL_Message::Type::KillFocus:
477 OnFocusChanged(pMessage, false);
478 break;
479 case CFWL_Message::Type::Mouse: {
480 CFWL_MessageMouse* pMouse = static_cast<CFWL_MessageMouse*>(pMessage);
481 switch (pMouse->m_dwCmd) {
482 case FWL_MouseCommand::LeftButtonDown:
483 OnLButtonDown(pMouse);
484 break;
485 case FWL_MouseCommand::LeftButtonUp:
486 OnLButtonUp(pMouse);
487 break;
488 case FWL_MouseCommand::Move:
489 OnMouseMove(pMouse);
490 break;
491 case FWL_MouseCommand::Leave:
492 OnMouseLeave(pMouse);
493 break;
494 default:
495 break;
496 }
497 break;
498 }
499 case CFWL_Message::Type::Key: {
500 if (m_pEdit->GetStates() & FWL_WGTSTATE_Focused) {
501 m_pEdit->GetDelegate()->OnProcessMessage(pMessage);
502 return;
503 }
504 break;
505 }
506 default:
507 break;
508 }
509
510 CFWL_Widget::OnProcessMessage(pMessage);
511 }
512
OnDrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)513 void CFWL_DateTimePicker::OnDrawWidget(CFX_Graphics* pGraphics,
514 const CFX_Matrix* pMatrix) {
515 DrawWidget(pGraphics, pMatrix);
516 }
517
OnFocusChanged(CFWL_Message * pMsg,bool bSet)518 void CFWL_DateTimePicker::OnFocusChanged(CFWL_Message* pMsg, bool bSet) {
519 if (!pMsg)
520 return;
521 if (m_pWidgetMgr->IsFormDisabled())
522 return DisForm_OnFocusChanged(pMsg, bSet);
523
524 if (bSet) {
525 m_pProperties->m_dwStates |= (FWL_WGTSTATE_Focused);
526 RepaintRect(m_rtClient);
527 } else {
528 m_pProperties->m_dwStates &= ~(FWL_WGTSTATE_Focused);
529 RepaintRect(m_rtClient);
530 }
531 if (pMsg->m_pSrcTarget == m_pMonthCal.get() && IsMonthCalendarVisible()) {
532 ShowMonthCalendar(false);
533 }
534 RepaintRect(m_rtClient);
535 }
536
OnLButtonDown(CFWL_MessageMouse * pMsg)537 void CFWL_DateTimePicker::OnLButtonDown(CFWL_MessageMouse* pMsg) {
538 if (!pMsg)
539 return;
540 if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0)
541 SetFocus(true);
542 if (!m_rtBtn.Contains(pMsg->m_pos))
543 return;
544
545 if (IsMonthCalendarVisible()) {
546 ShowMonthCalendar(false);
547 return;
548 }
549 ShowMonthCalendar(true);
550
551 m_bLBtnDown = true;
552 RepaintRect(m_rtClient);
553 }
554
OnLButtonUp(CFWL_MessageMouse * pMsg)555 void CFWL_DateTimePicker::OnLButtonUp(CFWL_MessageMouse* pMsg) {
556 if (!pMsg)
557 return;
558
559 m_bLBtnDown = false;
560 if (m_rtBtn.Contains(pMsg->m_pos))
561 m_iBtnState = CFWL_PartState_Hovered;
562 else
563 m_iBtnState = CFWL_PartState_Normal;
564 RepaintRect(m_rtBtn);
565 }
566
OnMouseMove(CFWL_MessageMouse * pMsg)567 void CFWL_DateTimePicker::OnMouseMove(CFWL_MessageMouse* pMsg) {
568 if (!m_rtBtn.Contains(pMsg->m_pos))
569 m_iBtnState = CFWL_PartState_Normal;
570 RepaintRect(m_rtBtn);
571 }
572
OnMouseLeave(CFWL_MessageMouse * pMsg)573 void CFWL_DateTimePicker::OnMouseLeave(CFWL_MessageMouse* pMsg) {
574 if (!pMsg)
575 return;
576 m_iBtnState = CFWL_PartState_Normal;
577 RepaintRect(m_rtBtn);
578 }
579
DisForm_OnFocusChanged(CFWL_Message * pMsg,bool bSet)580 void CFWL_DateTimePicker::DisForm_OnFocusChanged(CFWL_Message* pMsg,
581 bool bSet) {
582 CFX_RectF rtInvalidate(m_rtBtn);
583 if (bSet) {
584 m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
585 if (m_pEdit && !(m_pEdit->GetStylesEx() & FWL_STYLEEXT_EDT_ReadOnly)) {
586 m_rtBtn = CFX_RectF(m_pProperties->m_rtWidget.width, 0, m_fBtn,
587 m_pProperties->m_rtWidget.height - 1);
588 }
589 rtInvalidate = m_rtBtn;
590 pMsg->m_pDstTarget = m_pEdit.get();
591 m_pEdit->GetDelegate()->OnProcessMessage(pMsg);
592 } else {
593 m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
594 m_rtBtn.Reset();
595
596 if (DisForm_IsMonthCalendarVisible())
597 ShowMonthCalendar(false);
598 if (m_pEdit->GetStates() & FWL_WGTSTATE_Focused) {
599 pMsg->m_pSrcTarget = m_pEdit.get();
600 m_pEdit->GetDelegate()->OnProcessMessage(pMsg);
601 }
602 }
603 rtInvalidate.Inflate(2, 2);
604 RepaintRect(rtInvalidate);
605 }
606