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