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