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
Create(const CFWL_WidgetImpProperties & properties,IFWL_Widget * pOuter)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
Create(const CFWL_WidgetImpProperties & properties,IFWL_Widget * pOuter)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
Create(const CFWL_WidgetImpProperties & properties,IFWL_Widget * pOuter)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
Create(const CFWL_WidgetImpProperties & properties,IFWL_Widget * pOuter)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
IFWL_DateTimePicker()68 IFWL_DateTimePicker::IFWL_DateTimePicker() {
69 }
CountSelRanges()70 int32_t IFWL_DateTimePicker::CountSelRanges() {
71 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())
72 ->GetDataTimeEdit()
73 ->CountSelRanges();
74 }
GetSelRange(int32_t nIndex,int32_t & nStart)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 }
GetCurSel(int32_t & iYear,int32_t & iMonth,int32_t & iDay)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 }
SetCurSel(int32_t iYear,int32_t iMonth,int32_t iDay)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 }
SetEditText(const CFX_WideString & wsText)92 FWL_ERR IFWL_DateTimePicker::SetEditText(const CFX_WideString& wsText) {
93 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->SetEditText(wsText);
94 }
GetEditText(CFX_WideString & wsText,int32_t nStart,int32_t nCount) const95 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 }
CanUndo()101 FX_BOOL IFWL_DateTimePicker::CanUndo() {
102 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->CanUndo();
103 }
CanRedo()104 FX_BOOL IFWL_DateTimePicker::CanRedo() {
105 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->CanRedo();
106 }
Undo()107 FX_BOOL IFWL_DateTimePicker::Undo() {
108 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->Undo();
109 }
Redo()110 FX_BOOL IFWL_DateTimePicker::Redo() {
111 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->Redo();
112 }
CanCopy()113 FX_BOOL IFWL_DateTimePicker::CanCopy() {
114 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->CanCopy();
115 }
CanCut()116 FX_BOOL IFWL_DateTimePicker::CanCut() {
117 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->CanCut();
118 }
CanSelectAll()119 FX_BOOL IFWL_DateTimePicker::CanSelectAll() {
120 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->CanSelectAll();
121 }
Copy(CFX_WideString & wsCopy)122 FX_BOOL IFWL_DateTimePicker::Copy(CFX_WideString& wsCopy) {
123 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->Copy(wsCopy);
124 }
Cut(CFX_WideString & wsCut)125 FX_BOOL IFWL_DateTimePicker::Cut(CFX_WideString& wsCut) {
126 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->Cut(wsCut);
127 }
Paste(const CFX_WideString & wsPaste)128 FX_BOOL IFWL_DateTimePicker::Paste(const CFX_WideString& wsPaste) {
129 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->Paste(wsPaste);
130 }
SelectAll()131 FX_BOOL IFWL_DateTimePicker::SelectAll() {
132 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->SelectAll();
133 }
Delete()134 FX_BOOL IFWL_DateTimePicker::Delete() {
135 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->Delete();
136 }
DeSelect()137 FX_BOOL IFWL_DateTimePicker::DeSelect() {
138 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->DeSelect();
139 }
GetBBox(CFX_RectF & rect)140 FWL_ERR IFWL_DateTimePicker::GetBBox(CFX_RectF& rect) {
141 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->GetBBox(rect);
142 }
SetEditLimit(int32_t nLimit)143 FWL_ERR IFWL_DateTimePicker::SetEditLimit(int32_t nLimit) {
144 return static_cast<CFWL_DateTimePickerImp*>(GetImpl())->SetEditLimit(nLimit);
145 }
ModifyEditStylesEx(FX_DWORD dwStylesExAdded,FX_DWORD dwStylesExRemoved)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 }
CFWL_DateTimeEdit(const CFWL_WidgetImpProperties & properties,IFWL_Widget * pOuter)151 CFWL_DateTimeEdit::CFWL_DateTimeEdit(const CFWL_WidgetImpProperties& properties,
152 IFWL_Widget* pOuter)
153 : CFWL_EditImp(properties, pOuter) {}
Initialize()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 }
Finalize()160 FWL_ERR CFWL_DateTimeEdit::Finalize() {
161 delete m_pDelegate;
162 m_pDelegate = nullptr;
163 return CFWL_EditImp::Finalize();
164 }
CFWL_DateTimeEditImpDelegate(CFWL_DateTimeEdit * pOwner)165 CFWL_DateTimeEditImpDelegate::CFWL_DateTimeEditImpDelegate(
166 CFWL_DateTimeEdit* pOwner)
167 : CFWL_EditImpDelegate(pOwner), m_pOwner(pOwner) {
168 }
OnProcessMessage(CFWL_Message * pMessage)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 }
DisForm_OnProcessMessage(CFWL_Message * pMessage)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 }
CFWL_DateTimeCalendar(const CFWL_WidgetImpProperties & properties,IFWL_Widget * pOuter)209 CFWL_DateTimeCalendar::CFWL_DateTimeCalendar(
210 const CFWL_WidgetImpProperties& properties,
211 IFWL_Widget* pOuter)
212 : CFWL_MonthCalendarImp(properties, pOuter) {}
Initialize()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 }
Finalize()220 FWL_ERR CFWL_DateTimeCalendar::Finalize() {
221 delete m_pDelegate;
222 m_pDelegate = nullptr;
223 return CFWL_MonthCalendarImp::Finalize();
224 }
CFWL_DateTimeCalendarImpDelegate(CFWL_DateTimeCalendar * pOwner)225 CFWL_DateTimeCalendarImpDelegate::CFWL_DateTimeCalendarImpDelegate(
226 CFWL_DateTimeCalendar* pOwner)
227 : CFWL_MonthCalendarImpDelegate(pOwner), m_pOwner(pOwner) {
228 m_bFlag = FALSE;
229 }
OnProcessMessage(CFWL_Message * pMessage)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 }
OnLButtonDownEx(CFWL_MsgMouse * pMsg)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 }
OnLButtonUpEx(CFWL_MsgMouse * pMsg)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 }
OnMouseMoveEx(CFWL_MsgMouse * pMsg)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 }
DisForm_OnProcessMessage(CFWL_Message * pMessage)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 }
DisForm_OnLButtonUpEx(CFWL_MsgMouse * pMsg)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 }
CFWL_DateTimePickerImp(const CFWL_WidgetImpProperties & properties,IFWL_Widget * pOuter)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 }
~CFWL_DateTimePickerImp()426 CFWL_DateTimePickerImp::~CFWL_DateTimePickerImp() {
427 }
GetClassName(CFX_WideString & wsClass) const428 FWL_ERR CFWL_DateTimePickerImp::GetClassName(CFX_WideString& wsClass) const {
429 wsClass = FWL_CLASS_DateTimePicker;
430 return FWL_ERR_Succeeded;
431 }
GetClassID() const432 FX_DWORD CFWL_DateTimePickerImp::GetClassID() const {
433 return FWL_CLASSHASH_DateTimePicker;
434 }
Initialize()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 }
Finalize()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 }
GetWidgetRect(CFX_RectF & rect,FX_BOOL bAutoSize)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 }
Update()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 }
HitTest(FX_FLOAT fx,FX_FLOAT fy)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 }
DrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)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 }
SetThemeProvider(IFWL_ThemeProvider * pTP)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 }
GetCurSel(int32_t & iYear,int32_t & iMonth,int32_t & iDay)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 }
SetCurSel(int32_t iYear,int32_t iMonth,int32_t iDay)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 }
SetEditText(const CFX_WideString & wsText)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 }
GetEditText(CFX_WideString & wsText,int32_t nStart,int32_t nCount) const607 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 }
CanUndo()615 FX_BOOL CFWL_DateTimePickerImp::CanUndo() {
616 return m_pEdit->CanUndo();
617 }
CanRedo()618 FX_BOOL CFWL_DateTimePickerImp::CanRedo() {
619 return m_pEdit->CanRedo();
620 }
Undo()621 FX_BOOL CFWL_DateTimePickerImp::Undo() {
622 return m_pEdit->Undo();
623 }
Redo()624 FX_BOOL CFWL_DateTimePickerImp::Redo() {
625 return m_pEdit->Redo();
626 }
CanCopy()627 FX_BOOL CFWL_DateTimePickerImp::CanCopy() {
628 int32_t nCount = m_pEdit->CountSelRanges();
629 return nCount > 0;
630 }
CanCut()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 }
CanSelectAll()638 FX_BOOL CFWL_DateTimePickerImp::CanSelectAll() {
639 return m_pEdit->GetTextLength() > 0;
640 }
Copy(CFX_WideString & wsCopy)641 FX_BOOL CFWL_DateTimePickerImp::Copy(CFX_WideString& wsCopy) {
642 return m_pEdit->Copy(wsCopy);
643 }
Cut(CFX_WideString & wsCut)644 FX_BOOL CFWL_DateTimePickerImp::Cut(CFX_WideString& wsCut) {
645 return m_pEdit->Cut(wsCut);
646 }
Paste(const CFX_WideString & wsPaste)647 FX_BOOL CFWL_DateTimePickerImp::Paste(const CFX_WideString& wsPaste) {
648 return m_pEdit->Paste(wsPaste);
649 }
SelectAll()650 FX_BOOL CFWL_DateTimePickerImp::SelectAll() {
651 return m_pEdit->AddSelRange(0) == FWL_ERR_Succeeded;
652 }
Delete()653 FX_BOOL CFWL_DateTimePickerImp::Delete() {
654 return m_pEdit->ClearText() == FWL_ERR_Succeeded;
655 }
DeSelect()656 FX_BOOL CFWL_DateTimePickerImp::DeSelect() {
657 return m_pEdit->ClearSelections() == FWL_ERR_Succeeded;
658 }
GetBBox(CFX_RectF & rect)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 }
SetEditLimit(int32_t nLimit)673 FWL_ERR CFWL_DateTimePickerImp::SetEditLimit(int32_t nLimit) {
674 return m_pEdit->SetLimit(nLimit);
675 }
ModifyEditStylesEx(FX_DWORD dwStylesExAdded,FX_DWORD dwStylesExRemoved)676 FWL_ERR CFWL_DateTimePickerImp::ModifyEditStylesEx(FX_DWORD dwStylesExAdded,
677 FX_DWORD dwStylesExRemoved) {
678 return m_pEdit->ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
679 }
DrawDropDownButton(CFX_Graphics * pGraphics,IFWL_ThemeProvider * pTheme,const CFX_Matrix * pMatrix)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 }
FormatDateString(int32_t iYear,int32_t iMonth,int32_t iDay,CFX_WideString & wsText)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 }
ShowMonthCalendar(FX_BOOL bActivate)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 }
IsMonthCalendarShowed()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 }
ReSetEditAlignment()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 }
ProcessSelChanged(int32_t iYear,int32_t iMonth,int32_t iDay)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 }
InitProxyForm()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 }
GetDataTimeEdit()821 IFWL_DateTimeEdit* CFWL_DateTimePickerImp::GetDataTimeEdit() {
822 return m_pEdit.get();
823 }
DisForm_Initialize()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 }
DisForm_InitDateTimeCalendar()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 }
DisForm_InitDateTimeEdit()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 }
DisForm_IsMonthCalendarShowed()860 FX_BOOL CFWL_DateTimePickerImp::DisForm_IsMonthCalendarShowed() {
861 if (!m_pMonthCal)
862 return FALSE;
863 return !(m_pMonthCal->GetStates() & FWL_WGTSTATE_Invisible);
864 }
DisForm_ShowMonthCalendar(FX_BOOL bActivate)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 }
DisForm_HitTest(FX_FLOAT fx,FX_FLOAT fy)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 }
DisForm_IsNeedShowButton()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 }
DisForm_Update()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 }
DisForm_GetWidgetRect(CFX_RectF & rect,FX_BOOL bAutoSize)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 }
DisForm_GetBBox(CFX_RectF & rect)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 }
DisForm_DrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)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 }
CFWL_DateTimePickerImpDelegate(CFWL_DateTimePickerImp * pOwner)1012 CFWL_DateTimePickerImpDelegate::CFWL_DateTimePickerImpDelegate(
1013 CFWL_DateTimePickerImp* pOwner)
1014 : m_pOwner(pOwner) {}
OnProcessMessage(CFWL_Message * pMessage)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 }
OnDrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)1060 FWL_ERR CFWL_DateTimePickerImpDelegate::OnDrawWidget(
1061 CFX_Graphics* pGraphics,
1062 const CFX_Matrix* pMatrix) {
1063 return m_pOwner->DrawWidget(pGraphics, pMatrix);
1064 }
OnFocusChanged(CFWL_Message * pMsg,FX_BOOL bSet)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 }
OnLButtonDown(CFWL_MsgMouse * pMsg)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 }
OnLButtonUp(CFWL_MsgMouse * pMsg)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 }
OnMouseMove(CFWL_MsgMouse * pMsg)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 }
OnMouseLeave(CFWL_MsgMouse * pMsg)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 }
DisForm_OnFocusChanged(CFWL_Message * pMsg,FX_BOOL bSet)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