xref: /aosp_15_r20/external/pdfium/xfa/fwl/cfwl_datetimepicker.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1*3ac0a46fSAndroid Build Coastguard Worker // Copyright 2014 The PDFium Authors
2*3ac0a46fSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*3ac0a46fSAndroid Build Coastguard Worker // found in the LICENSE file.
4*3ac0a46fSAndroid Build Coastguard Worker 
5*3ac0a46fSAndroid Build Coastguard Worker // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6*3ac0a46fSAndroid Build Coastguard Worker 
7*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fwl/cfwl_datetimepicker.h"
8*3ac0a46fSAndroid Build Coastguard Worker 
9*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fwl/cfwl_app.h"
10*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fwl/cfwl_event.h"
11*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fwl/cfwl_eventselectchanged.h"
12*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fwl/cfwl_messagemouse.h"
13*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fwl/cfwl_messagesetfocus.h"
14*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fwl/cfwl_notedriver.h"
15*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fwl/cfwl_themebackground.h"
16*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fwl/cfwl_widgetmgr.h"
17*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fwl/ifwl_themeprovider.h"
18*3ac0a46fSAndroid Build Coastguard Worker 
19*3ac0a46fSAndroid Build Coastguard Worker namespace {
20*3ac0a46fSAndroid Build Coastguard Worker 
21*3ac0a46fSAndroid Build Coastguard Worker constexpr int kDateTimePickerHeight = 20;
22*3ac0a46fSAndroid Build Coastguard Worker 
23*3ac0a46fSAndroid Build Coastguard Worker }  // namespace
24*3ac0a46fSAndroid Build Coastguard Worker 
CFWL_DateTimePicker(CFWL_App * app)25*3ac0a46fSAndroid Build Coastguard Worker CFWL_DateTimePicker::CFWL_DateTimePicker(CFWL_App* app)
26*3ac0a46fSAndroid Build Coastguard Worker     : CFWL_Widget(app,
27*3ac0a46fSAndroid Build Coastguard Worker                   Properties{0, FWL_STYLEEXT_DTP_ShortDateFormat, 0},
28*3ac0a46fSAndroid Build Coastguard Worker                   nullptr),
29*3ac0a46fSAndroid Build Coastguard Worker       m_pEdit(cppgc::MakeGarbageCollected<CFWL_DateTimeEdit>(
30*3ac0a46fSAndroid Build Coastguard Worker           app->GetHeap()->GetAllocationHandle(),
31*3ac0a46fSAndroid Build Coastguard Worker           app,
32*3ac0a46fSAndroid Build Coastguard Worker           Properties(),
33*3ac0a46fSAndroid Build Coastguard Worker           this)),
34*3ac0a46fSAndroid Build Coastguard Worker       m_pMonthCal(cppgc::MakeGarbageCollected<CFWL_MonthCalendar>(
35*3ac0a46fSAndroid Build Coastguard Worker           app->GetHeap()->GetAllocationHandle(),
36*3ac0a46fSAndroid Build Coastguard Worker           app,
37*3ac0a46fSAndroid Build Coastguard Worker           Properties{FWL_STYLE_WGT_Popup | FWL_STYLE_WGT_Border, 0,
38*3ac0a46fSAndroid Build Coastguard Worker                      FWL_STATE_WGT_Invisible},
39*3ac0a46fSAndroid Build Coastguard Worker           this)) {
40*3ac0a46fSAndroid Build Coastguard Worker   m_pMonthCal->SetWidgetRect(
41*3ac0a46fSAndroid Build Coastguard Worker       CFX_RectF(0, 0, m_pMonthCal->GetAutosizedWidgetRect().Size()));
42*3ac0a46fSAndroid Build Coastguard Worker 
43*3ac0a46fSAndroid Build Coastguard Worker   CFWL_NoteDriver* pNoteDriver = GetFWLApp()->GetNoteDriver();
44*3ac0a46fSAndroid Build Coastguard Worker   pNoteDriver->RegisterEventTarget(this, m_pMonthCal);
45*3ac0a46fSAndroid Build Coastguard Worker   pNoteDriver->RegisterEventTarget(this, m_pEdit);
46*3ac0a46fSAndroid Build Coastguard Worker }
47*3ac0a46fSAndroid Build Coastguard Worker 
48*3ac0a46fSAndroid Build Coastguard Worker CFWL_DateTimePicker::~CFWL_DateTimePicker() = default;
49*3ac0a46fSAndroid Build Coastguard Worker 
PreFinalize()50*3ac0a46fSAndroid Build Coastguard Worker void CFWL_DateTimePicker::PreFinalize() {
51*3ac0a46fSAndroid Build Coastguard Worker   UnregisterEventTarget();
52*3ac0a46fSAndroid Build Coastguard Worker   CFWL_Widget::PreFinalize();
53*3ac0a46fSAndroid Build Coastguard Worker }
54*3ac0a46fSAndroid Build Coastguard Worker 
Trace(cppgc::Visitor * visitor) const55*3ac0a46fSAndroid Build Coastguard Worker void CFWL_DateTimePicker::Trace(cppgc::Visitor* visitor) const {
56*3ac0a46fSAndroid Build Coastguard Worker   CFWL_Widget::Trace(visitor);
57*3ac0a46fSAndroid Build Coastguard Worker   visitor->Trace(m_pEdit);
58*3ac0a46fSAndroid Build Coastguard Worker   visitor->Trace(m_pMonthCal);
59*3ac0a46fSAndroid Build Coastguard Worker }
60*3ac0a46fSAndroid Build Coastguard Worker 
GetClassID() const61*3ac0a46fSAndroid Build Coastguard Worker FWL_Type CFWL_DateTimePicker::GetClassID() const {
62*3ac0a46fSAndroid Build Coastguard Worker   return FWL_Type::DateTimePicker;
63*3ac0a46fSAndroid Build Coastguard Worker }
64*3ac0a46fSAndroid Build Coastguard Worker 
Update()65*3ac0a46fSAndroid Build Coastguard Worker void CFWL_DateTimePicker::Update() {
66*3ac0a46fSAndroid Build Coastguard Worker   if (IsLocked())
67*3ac0a46fSAndroid Build Coastguard Worker     return;
68*3ac0a46fSAndroid Build Coastguard Worker 
69*3ac0a46fSAndroid Build Coastguard Worker   m_ClientRect = GetClientRect();
70*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SetWidgetRect(m_ClientRect);
71*3ac0a46fSAndroid Build Coastguard Worker   ResetEditAlignment();
72*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->Update();
73*3ac0a46fSAndroid Build Coastguard Worker 
74*3ac0a46fSAndroid Build Coastguard Worker   m_fBtn = GetThemeProvider()->GetScrollBarWidth();
75*3ac0a46fSAndroid Build Coastguard Worker   CFX_RectF rtMonthCal = m_pMonthCal->GetAutosizedWidgetRect();
76*3ac0a46fSAndroid Build Coastguard Worker   CFX_RectF rtPopUp(rtMonthCal.left, rtMonthCal.top + kDateTimePickerHeight,
77*3ac0a46fSAndroid Build Coastguard Worker                     rtMonthCal.width, rtMonthCal.height);
78*3ac0a46fSAndroid Build Coastguard Worker   m_pMonthCal->SetWidgetRect(rtPopUp);
79*3ac0a46fSAndroid Build Coastguard Worker   m_pMonthCal->Update();
80*3ac0a46fSAndroid Build Coastguard Worker }
81*3ac0a46fSAndroid Build Coastguard Worker 
HitTest(const CFX_PointF & point)82*3ac0a46fSAndroid Build Coastguard Worker FWL_WidgetHit CFWL_DateTimePicker::HitTest(const CFX_PointF& point) {
83*3ac0a46fSAndroid Build Coastguard Worker   CFX_RectF rect(0, 0, m_WidgetRect.width, m_WidgetRect.height);
84*3ac0a46fSAndroid Build Coastguard Worker   if (rect.Contains(point))
85*3ac0a46fSAndroid Build Coastguard Worker     return FWL_WidgetHit::Edit;
86*3ac0a46fSAndroid Build Coastguard Worker   if (NeedsToShowButton())
87*3ac0a46fSAndroid Build Coastguard Worker     rect.width += m_fBtn;
88*3ac0a46fSAndroid Build Coastguard Worker   if (rect.Contains(point))
89*3ac0a46fSAndroid Build Coastguard Worker     return FWL_WidgetHit::Client;
90*3ac0a46fSAndroid Build Coastguard Worker   if (IsMonthCalendarVisible()) {
91*3ac0a46fSAndroid Build Coastguard Worker     if (m_pMonthCal->GetWidgetRect().Contains(point))
92*3ac0a46fSAndroid Build Coastguard Worker       return FWL_WidgetHit::Client;
93*3ac0a46fSAndroid Build Coastguard Worker   }
94*3ac0a46fSAndroid Build Coastguard Worker   return FWL_WidgetHit::Unknown;
95*3ac0a46fSAndroid Build Coastguard Worker }
96*3ac0a46fSAndroid Build Coastguard Worker 
DrawWidget(CFGAS_GEGraphics * pGraphics,const CFX_Matrix & matrix)97*3ac0a46fSAndroid Build Coastguard Worker void CFWL_DateTimePicker::DrawWidget(CFGAS_GEGraphics* pGraphics,
98*3ac0a46fSAndroid Build Coastguard Worker                                      const CFX_Matrix& matrix) {
99*3ac0a46fSAndroid Build Coastguard Worker   if (!pGraphics)
100*3ac0a46fSAndroid Build Coastguard Worker     return;
101*3ac0a46fSAndroid Build Coastguard Worker 
102*3ac0a46fSAndroid Build Coastguard Worker   if (HasBorder())
103*3ac0a46fSAndroid Build Coastguard Worker     DrawBorder(pGraphics, CFWL_ThemePart::Part::kBorder, matrix);
104*3ac0a46fSAndroid Build Coastguard Worker 
105*3ac0a46fSAndroid Build Coastguard Worker   if (!m_BtnRect.IsEmpty())
106*3ac0a46fSAndroid Build Coastguard Worker     DrawDropDownButton(pGraphics, matrix);
107*3ac0a46fSAndroid Build Coastguard Worker 
108*3ac0a46fSAndroid Build Coastguard Worker   if (m_pEdit) {
109*3ac0a46fSAndroid Build Coastguard Worker     CFX_RectF rtEdit = m_pEdit->GetWidgetRect();
110*3ac0a46fSAndroid Build Coastguard Worker     CFX_Matrix mt(1, 0, 0, 1, rtEdit.left, rtEdit.top);
111*3ac0a46fSAndroid Build Coastguard Worker     mt.Concat(matrix);
112*3ac0a46fSAndroid Build Coastguard Worker     m_pEdit->DrawWidget(pGraphics, mt);
113*3ac0a46fSAndroid Build Coastguard Worker   }
114*3ac0a46fSAndroid Build Coastguard Worker   if (!IsMonthCalendarVisible())
115*3ac0a46fSAndroid Build Coastguard Worker     return;
116*3ac0a46fSAndroid Build Coastguard Worker 
117*3ac0a46fSAndroid Build Coastguard Worker   CFX_RectF rtMonth = m_pMonthCal->GetWidgetRect();
118*3ac0a46fSAndroid Build Coastguard Worker   CFX_Matrix mt(1, 0, 0, 1, rtMonth.left, rtMonth.top);
119*3ac0a46fSAndroid Build Coastguard Worker   mt.Concat(matrix);
120*3ac0a46fSAndroid Build Coastguard Worker   m_pMonthCal->DrawWidget(pGraphics, mt);
121*3ac0a46fSAndroid Build Coastguard Worker }
122*3ac0a46fSAndroid Build Coastguard Worker 
GetCurSel(int32_t & iYear,int32_t & iMonth,int32_t & iDay)123*3ac0a46fSAndroid Build Coastguard Worker void CFWL_DateTimePicker::GetCurSel(int32_t& iYear,
124*3ac0a46fSAndroid Build Coastguard Worker                                     int32_t& iMonth,
125*3ac0a46fSAndroid Build Coastguard Worker                                     int32_t& iDay) {
126*3ac0a46fSAndroid Build Coastguard Worker   iYear = m_iYear;
127*3ac0a46fSAndroid Build Coastguard Worker   iMonth = m_iMonth;
128*3ac0a46fSAndroid Build Coastguard Worker   iDay = m_iDay;
129*3ac0a46fSAndroid Build Coastguard Worker }
130*3ac0a46fSAndroid Build Coastguard Worker 
SetCurSel(int32_t iYear,int32_t iMonth,int32_t iDay)131*3ac0a46fSAndroid Build Coastguard Worker void CFWL_DateTimePicker::SetCurSel(int32_t iYear,
132*3ac0a46fSAndroid Build Coastguard Worker                                     int32_t iMonth,
133*3ac0a46fSAndroid Build Coastguard Worker                                     int32_t iDay) {
134*3ac0a46fSAndroid Build Coastguard Worker   if (iYear <= 0 || iYear >= 3000)
135*3ac0a46fSAndroid Build Coastguard Worker     return;
136*3ac0a46fSAndroid Build Coastguard Worker   if (iMonth <= 0 || iMonth >= 13)
137*3ac0a46fSAndroid Build Coastguard Worker     return;
138*3ac0a46fSAndroid Build Coastguard Worker   if (iDay <= 0 || iDay >= 32)
139*3ac0a46fSAndroid Build Coastguard Worker     return;
140*3ac0a46fSAndroid Build Coastguard Worker 
141*3ac0a46fSAndroid Build Coastguard Worker   m_iYear = iYear;
142*3ac0a46fSAndroid Build Coastguard Worker   m_iMonth = iMonth;
143*3ac0a46fSAndroid Build Coastguard Worker   m_iDay = iDay;
144*3ac0a46fSAndroid Build Coastguard Worker   m_pMonthCal->SetSelect(iYear, iMonth, iDay);
145*3ac0a46fSAndroid Build Coastguard Worker }
146*3ac0a46fSAndroid Build Coastguard Worker 
SetEditText(const WideString & wsText)147*3ac0a46fSAndroid Build Coastguard Worker void CFWL_DateTimePicker::SetEditText(const WideString& wsText) {
148*3ac0a46fSAndroid Build Coastguard Worker   if (!m_pEdit)
149*3ac0a46fSAndroid Build Coastguard Worker     return;
150*3ac0a46fSAndroid Build Coastguard Worker 
151*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SetText(wsText);
152*3ac0a46fSAndroid Build Coastguard Worker   RepaintRect(m_ClientRect);
153*3ac0a46fSAndroid Build Coastguard Worker 
154*3ac0a46fSAndroid Build Coastguard Worker   CFWL_Event ev(CFWL_Event::Type::EditChanged);
155*3ac0a46fSAndroid Build Coastguard Worker   DispatchEvent(&ev);
156*3ac0a46fSAndroid Build Coastguard Worker }
157*3ac0a46fSAndroid Build Coastguard Worker 
GetEditText() const158*3ac0a46fSAndroid Build Coastguard Worker WideString CFWL_DateTimePicker::GetEditText() const {
159*3ac0a46fSAndroid Build Coastguard Worker   return m_pEdit ? m_pEdit->GetText() : WideString();
160*3ac0a46fSAndroid Build Coastguard Worker }
161*3ac0a46fSAndroid Build Coastguard Worker 
GetEditTextLength() const162*3ac0a46fSAndroid Build Coastguard Worker size_t CFWL_DateTimePicker::GetEditTextLength() const {
163*3ac0a46fSAndroid Build Coastguard Worker   return m_pEdit ? m_pEdit->GetTextLength() : 0;
164*3ac0a46fSAndroid Build Coastguard Worker }
165*3ac0a46fSAndroid Build Coastguard Worker 
GetBBox() const166*3ac0a46fSAndroid Build Coastguard Worker CFX_RectF CFWL_DateTimePicker::GetBBox() const {
167*3ac0a46fSAndroid Build Coastguard Worker   CFX_RectF rect = m_WidgetRect;
168*3ac0a46fSAndroid Build Coastguard Worker   if (NeedsToShowButton())
169*3ac0a46fSAndroid Build Coastguard Worker     rect.width += m_fBtn;
170*3ac0a46fSAndroid Build Coastguard Worker   if (!IsMonthCalendarVisible())
171*3ac0a46fSAndroid Build Coastguard Worker     return rect;
172*3ac0a46fSAndroid Build Coastguard Worker 
173*3ac0a46fSAndroid Build Coastguard Worker   CFX_RectF rtMonth = m_pMonthCal->GetWidgetRect();
174*3ac0a46fSAndroid Build Coastguard Worker   rtMonth.Offset(m_WidgetRect.left, m_WidgetRect.top);
175*3ac0a46fSAndroid Build Coastguard Worker   rect.Union(rtMonth);
176*3ac0a46fSAndroid Build Coastguard Worker   return rect;
177*3ac0a46fSAndroid Build Coastguard Worker }
178*3ac0a46fSAndroid Build Coastguard Worker 
ModifyEditStyleExts(uint32_t dwStyleExtsAdded,uint32_t dwStyleExtsRemoved)179*3ac0a46fSAndroid Build Coastguard Worker void CFWL_DateTimePicker::ModifyEditStyleExts(uint32_t dwStyleExtsAdded,
180*3ac0a46fSAndroid Build Coastguard Worker                                               uint32_t dwStyleExtsRemoved) {
181*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->ModifyStyleExts(dwStyleExtsAdded, dwStyleExtsRemoved);
182*3ac0a46fSAndroid Build Coastguard Worker }
183*3ac0a46fSAndroid Build Coastguard Worker 
DrawDropDownButton(CFGAS_GEGraphics * pGraphics,const CFX_Matrix & mtMatrix)184*3ac0a46fSAndroid Build Coastguard Worker void CFWL_DateTimePicker::DrawDropDownButton(CFGAS_GEGraphics* pGraphics,
185*3ac0a46fSAndroid Build Coastguard Worker                                              const CFX_Matrix& mtMatrix) {
186*3ac0a46fSAndroid Build Coastguard Worker   CFWL_ThemeBackground param(CFWL_ThemePart::Part::kDropDownButton, this,
187*3ac0a46fSAndroid Build Coastguard Worker                              pGraphics);
188*3ac0a46fSAndroid Build Coastguard Worker   param.m_dwStates = m_iBtnState;
189*3ac0a46fSAndroid Build Coastguard Worker   param.m_PartRect = m_BtnRect;
190*3ac0a46fSAndroid Build Coastguard Worker   param.m_matrix = mtMatrix;
191*3ac0a46fSAndroid Build Coastguard Worker   GetThemeProvider()->DrawBackground(param);
192*3ac0a46fSAndroid Build Coastguard Worker }
193*3ac0a46fSAndroid Build Coastguard Worker 
FormatDateString(int32_t iYear,int32_t iMonth,int32_t iDay)194*3ac0a46fSAndroid Build Coastguard Worker WideString CFWL_DateTimePicker::FormatDateString(int32_t iYear,
195*3ac0a46fSAndroid Build Coastguard Worker                                                  int32_t iMonth,
196*3ac0a46fSAndroid Build Coastguard Worker                                                  int32_t iDay) {
197*3ac0a46fSAndroid Build Coastguard Worker   if (m_Properties.m_dwStyleExts & FWL_STYLEEXT_DTP_ShortDateFormat)
198*3ac0a46fSAndroid Build Coastguard Worker     return WideString::Format(L"%d-%d-%d", iYear, iMonth, iDay);
199*3ac0a46fSAndroid Build Coastguard Worker 
200*3ac0a46fSAndroid Build Coastguard Worker   return WideString::Format(L"%d Year %d Month %d Day", iYear, iMonth, iDay);
201*3ac0a46fSAndroid Build Coastguard Worker }
202*3ac0a46fSAndroid Build Coastguard Worker 
ShowMonthCalendar()203*3ac0a46fSAndroid Build Coastguard Worker void CFWL_DateTimePicker::ShowMonthCalendar() {
204*3ac0a46fSAndroid Build Coastguard Worker   if (IsMonthCalendarVisible())
205*3ac0a46fSAndroid Build Coastguard Worker     return;
206*3ac0a46fSAndroid Build Coastguard Worker 
207*3ac0a46fSAndroid Build Coastguard Worker   CFX_RectF rtMonthCal = m_pMonthCal->GetAutosizedWidgetRect();
208*3ac0a46fSAndroid Build Coastguard Worker   float fPopupMin = rtMonthCal.height;
209*3ac0a46fSAndroid Build Coastguard Worker   float fPopupMax = rtMonthCal.height;
210*3ac0a46fSAndroid Build Coastguard Worker   CFX_RectF rtAnchor = m_WidgetRect;
211*3ac0a46fSAndroid Build Coastguard Worker   rtAnchor.width = rtMonthCal.width;
212*3ac0a46fSAndroid Build Coastguard Worker   rtMonthCal.left = m_ClientRect.left;
213*3ac0a46fSAndroid Build Coastguard Worker   rtMonthCal.top = rtAnchor.Height();
214*3ac0a46fSAndroid Build Coastguard Worker   GetPopupPos(fPopupMin, fPopupMax, rtAnchor, &rtMonthCal);
215*3ac0a46fSAndroid Build Coastguard Worker   m_pMonthCal->SetWidgetRect(rtMonthCal);
216*3ac0a46fSAndroid Build Coastguard Worker   if (m_iYear > 0 && m_iMonth > 0 && m_iDay > 0)
217*3ac0a46fSAndroid Build Coastguard Worker     m_pMonthCal->SetSelect(m_iYear, m_iMonth, m_iDay);
218*3ac0a46fSAndroid Build Coastguard Worker   m_pMonthCal->Update();
219*3ac0a46fSAndroid Build Coastguard Worker   m_pMonthCal->RemoveStates(FWL_STATE_WGT_Invisible);
220*3ac0a46fSAndroid Build Coastguard Worker 
221*3ac0a46fSAndroid Build Coastguard Worker   CFWL_MessageSetFocus msg(m_pMonthCal);
222*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->GetDelegate()->OnProcessMessage(&msg);
223*3ac0a46fSAndroid Build Coastguard Worker   RepaintInflatedMonthCalRect();
224*3ac0a46fSAndroid Build Coastguard Worker }
225*3ac0a46fSAndroid Build Coastguard Worker 
HideMonthCalendar()226*3ac0a46fSAndroid Build Coastguard Worker void CFWL_DateTimePicker::HideMonthCalendar() {
227*3ac0a46fSAndroid Build Coastguard Worker   if (!IsMonthCalendarVisible())
228*3ac0a46fSAndroid Build Coastguard Worker     return;
229*3ac0a46fSAndroid Build Coastguard Worker 
230*3ac0a46fSAndroid Build Coastguard Worker   m_pMonthCal->SetStates(FWL_STATE_WGT_Invisible);
231*3ac0a46fSAndroid Build Coastguard Worker   RepaintInflatedMonthCalRect();
232*3ac0a46fSAndroid Build Coastguard Worker }
233*3ac0a46fSAndroid Build Coastguard Worker 
RepaintInflatedMonthCalRect()234*3ac0a46fSAndroid Build Coastguard Worker void CFWL_DateTimePicker::RepaintInflatedMonthCalRect() {
235*3ac0a46fSAndroid Build Coastguard Worker   CFX_RectF rtInvalidate(0, 0, m_WidgetRect.width, m_WidgetRect.height);
236*3ac0a46fSAndroid Build Coastguard Worker   CFX_RectF rtCal = m_pMonthCal->GetWidgetRect();
237*3ac0a46fSAndroid Build Coastguard Worker   rtInvalidate.Union(rtCal);
238*3ac0a46fSAndroid Build Coastguard Worker   rtInvalidate.Inflate(2, 2);
239*3ac0a46fSAndroid Build Coastguard Worker   RepaintRect(rtInvalidate);
240*3ac0a46fSAndroid Build Coastguard Worker }
241*3ac0a46fSAndroid Build Coastguard Worker 
IsMonthCalendarVisible() const242*3ac0a46fSAndroid Build Coastguard Worker bool CFWL_DateTimePicker::IsMonthCalendarVisible() const {
243*3ac0a46fSAndroid Build Coastguard Worker   return m_pMonthCal && m_pMonthCal->IsVisible();
244*3ac0a46fSAndroid Build Coastguard Worker }
245*3ac0a46fSAndroid Build Coastguard Worker 
ResetEditAlignment()246*3ac0a46fSAndroid Build Coastguard Worker void CFWL_DateTimePicker::ResetEditAlignment() {
247*3ac0a46fSAndroid Build Coastguard Worker   if (!m_pEdit)
248*3ac0a46fSAndroid Build Coastguard Worker     return;
249*3ac0a46fSAndroid Build Coastguard Worker 
250*3ac0a46fSAndroid Build Coastguard Worker   uint32_t dwAdd = 0;
251*3ac0a46fSAndroid Build Coastguard Worker   switch (m_Properties.m_dwStyleExts & FWL_STYLEEXT_DTP_EditHAlignMask) {
252*3ac0a46fSAndroid Build Coastguard Worker     case FWL_STYLEEXT_DTP_EditHCenter: {
253*3ac0a46fSAndroid Build Coastguard Worker       dwAdd |= FWL_STYLEEXT_EDT_HCenter;
254*3ac0a46fSAndroid Build Coastguard Worker       break;
255*3ac0a46fSAndroid Build Coastguard Worker     }
256*3ac0a46fSAndroid Build Coastguard Worker     case FWL_STYLEEXT_DTP_EditHFar: {
257*3ac0a46fSAndroid Build Coastguard Worker       dwAdd |= FWL_STYLEEXT_EDT_HFar;
258*3ac0a46fSAndroid Build Coastguard Worker       break;
259*3ac0a46fSAndroid Build Coastguard Worker     }
260*3ac0a46fSAndroid Build Coastguard Worker     default: {
261*3ac0a46fSAndroid Build Coastguard Worker       dwAdd |= FWL_STYLEEXT_EDT_HNear;
262*3ac0a46fSAndroid Build Coastguard Worker       break;
263*3ac0a46fSAndroid Build Coastguard Worker     }
264*3ac0a46fSAndroid Build Coastguard Worker   }
265*3ac0a46fSAndroid Build Coastguard Worker   switch (m_Properties.m_dwStyleExts & FWL_STYLEEXT_DTP_EditVAlignMask) {
266*3ac0a46fSAndroid Build Coastguard Worker     case FWL_STYLEEXT_DTP_EditVCenter: {
267*3ac0a46fSAndroid Build Coastguard Worker       dwAdd |= FWL_STYLEEXT_EDT_VCenter;
268*3ac0a46fSAndroid Build Coastguard Worker       break;
269*3ac0a46fSAndroid Build Coastguard Worker     }
270*3ac0a46fSAndroid Build Coastguard Worker     case FWL_STYLEEXT_DTP_EditVFar: {
271*3ac0a46fSAndroid Build Coastguard Worker       dwAdd |= FWL_STYLEEXT_EDT_VFar;
272*3ac0a46fSAndroid Build Coastguard Worker       break;
273*3ac0a46fSAndroid Build Coastguard Worker     }
274*3ac0a46fSAndroid Build Coastguard Worker     default: {
275*3ac0a46fSAndroid Build Coastguard Worker       dwAdd |= FWL_STYLEEXT_EDT_VNear;
276*3ac0a46fSAndroid Build Coastguard Worker       break;
277*3ac0a46fSAndroid Build Coastguard Worker     }
278*3ac0a46fSAndroid Build Coastguard Worker   }
279*3ac0a46fSAndroid Build Coastguard Worker   if (m_Properties.m_dwStyleExts & FWL_STYLEEXT_DTP_EditJustified)
280*3ac0a46fSAndroid Build Coastguard Worker     dwAdd |= FWL_STYLEEXT_EDT_Justified;
281*3ac0a46fSAndroid Build Coastguard Worker 
282*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->ModifyStyleExts(dwAdd, FWL_STYLEEXT_EDT_HAlignMask |
283*3ac0a46fSAndroid Build Coastguard Worker                                       FWL_STYLEEXT_EDT_HAlignModeMask |
284*3ac0a46fSAndroid Build Coastguard Worker                                       FWL_STYLEEXT_EDT_VAlignMask);
285*3ac0a46fSAndroid Build Coastguard Worker }
286*3ac0a46fSAndroid Build Coastguard Worker 
ProcessSelChanged(int32_t iYear,int32_t iMonth,int32_t iDay)287*3ac0a46fSAndroid Build Coastguard Worker void CFWL_DateTimePicker::ProcessSelChanged(int32_t iYear,
288*3ac0a46fSAndroid Build Coastguard Worker                                             int32_t iMonth,
289*3ac0a46fSAndroid Build Coastguard Worker                                             int32_t iDay) {
290*3ac0a46fSAndroid Build Coastguard Worker   m_iYear = iYear;
291*3ac0a46fSAndroid Build Coastguard Worker   m_iMonth = iMonth;
292*3ac0a46fSAndroid Build Coastguard Worker   m_iDay = iDay;
293*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SetText(FormatDateString(m_iYear, m_iMonth, m_iDay));
294*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->Update();
295*3ac0a46fSAndroid Build Coastguard Worker   RepaintRect(m_ClientRect);
296*3ac0a46fSAndroid Build Coastguard Worker 
297*3ac0a46fSAndroid Build Coastguard Worker   CFWL_EventSelectChanged ev(this, m_iYear, m_iMonth, m_iDay);
298*3ac0a46fSAndroid Build Coastguard Worker   DispatchEvent(&ev);
299*3ac0a46fSAndroid Build Coastguard Worker }
300*3ac0a46fSAndroid Build Coastguard Worker 
NeedsToShowButton() const301*3ac0a46fSAndroid Build Coastguard Worker bool CFWL_DateTimePicker::NeedsToShowButton() const {
302*3ac0a46fSAndroid Build Coastguard Worker   return m_Properties.m_dwStates & FWL_STATE_WGT_Focused ||
303*3ac0a46fSAndroid Build Coastguard Worker          m_pMonthCal->GetStates() & FWL_STATE_WGT_Focused ||
304*3ac0a46fSAndroid Build Coastguard Worker          m_pEdit->GetStates() & FWL_STATE_WGT_Focused;
305*3ac0a46fSAndroid Build Coastguard Worker }
306*3ac0a46fSAndroid Build Coastguard Worker 
OnProcessMessage(CFWL_Message * pMessage)307*3ac0a46fSAndroid Build Coastguard Worker void CFWL_DateTimePicker::OnProcessMessage(CFWL_Message* pMessage) {
308*3ac0a46fSAndroid Build Coastguard Worker   switch (pMessage->GetType()) {
309*3ac0a46fSAndroid Build Coastguard Worker     case CFWL_Message::Type::kSetFocus:
310*3ac0a46fSAndroid Build Coastguard Worker       OnFocusGained(pMessage);
311*3ac0a46fSAndroid Build Coastguard Worker       break;
312*3ac0a46fSAndroid Build Coastguard Worker     case CFWL_Message::Type::kKillFocus:
313*3ac0a46fSAndroid Build Coastguard Worker       OnFocusLost(pMessage);
314*3ac0a46fSAndroid Build Coastguard Worker       break;
315*3ac0a46fSAndroid Build Coastguard Worker     case CFWL_Message::Type::kMouse: {
316*3ac0a46fSAndroid Build Coastguard Worker       CFWL_MessageMouse* pMouse = static_cast<CFWL_MessageMouse*>(pMessage);
317*3ac0a46fSAndroid Build Coastguard Worker       switch (pMouse->m_dwCmd) {
318*3ac0a46fSAndroid Build Coastguard Worker         case CFWL_MessageMouse::MouseCommand::kLeftButtonDown:
319*3ac0a46fSAndroid Build Coastguard Worker           OnLButtonDown(pMouse);
320*3ac0a46fSAndroid Build Coastguard Worker           break;
321*3ac0a46fSAndroid Build Coastguard Worker         case CFWL_MessageMouse::MouseCommand::kLeftButtonUp:
322*3ac0a46fSAndroid Build Coastguard Worker           OnLButtonUp(pMouse);
323*3ac0a46fSAndroid Build Coastguard Worker           break;
324*3ac0a46fSAndroid Build Coastguard Worker         case CFWL_MessageMouse::MouseCommand::kMove:
325*3ac0a46fSAndroid Build Coastguard Worker           OnMouseMove(pMouse);
326*3ac0a46fSAndroid Build Coastguard Worker           break;
327*3ac0a46fSAndroid Build Coastguard Worker         case CFWL_MessageMouse::MouseCommand::kLeave:
328*3ac0a46fSAndroid Build Coastguard Worker           OnMouseLeave(pMouse);
329*3ac0a46fSAndroid Build Coastguard Worker           break;
330*3ac0a46fSAndroid Build Coastguard Worker         default:
331*3ac0a46fSAndroid Build Coastguard Worker           break;
332*3ac0a46fSAndroid Build Coastguard Worker       }
333*3ac0a46fSAndroid Build Coastguard Worker       break;
334*3ac0a46fSAndroid Build Coastguard Worker     }
335*3ac0a46fSAndroid Build Coastguard Worker     case CFWL_Message::Type::kKey: {
336*3ac0a46fSAndroid Build Coastguard Worker       if (m_pEdit->GetStates() & FWL_STATE_WGT_Focused) {
337*3ac0a46fSAndroid Build Coastguard Worker         m_pEdit->GetDelegate()->OnProcessMessage(pMessage);
338*3ac0a46fSAndroid Build Coastguard Worker         return;
339*3ac0a46fSAndroid Build Coastguard Worker       }
340*3ac0a46fSAndroid Build Coastguard Worker       break;
341*3ac0a46fSAndroid Build Coastguard Worker     }
342*3ac0a46fSAndroid Build Coastguard Worker     default:
343*3ac0a46fSAndroid Build Coastguard Worker       break;
344*3ac0a46fSAndroid Build Coastguard Worker   }
345*3ac0a46fSAndroid Build Coastguard Worker   // Dst target could be |this|, continue only if not destroyed by above.
346*3ac0a46fSAndroid Build Coastguard Worker   if (pMessage->GetDstTarget())
347*3ac0a46fSAndroid Build Coastguard Worker     CFWL_Widget::OnProcessMessage(pMessage);
348*3ac0a46fSAndroid Build Coastguard Worker }
349*3ac0a46fSAndroid Build Coastguard Worker 
OnDrawWidget(CFGAS_GEGraphics * pGraphics,const CFX_Matrix & matrix)350*3ac0a46fSAndroid Build Coastguard Worker void CFWL_DateTimePicker::OnDrawWidget(CFGAS_GEGraphics* pGraphics,
351*3ac0a46fSAndroid Build Coastguard Worker                                        const CFX_Matrix& matrix) {
352*3ac0a46fSAndroid Build Coastguard Worker   DrawWidget(pGraphics, matrix);
353*3ac0a46fSAndroid Build Coastguard Worker }
354*3ac0a46fSAndroid Build Coastguard Worker 
OnFocusGained(CFWL_Message * pMsg)355*3ac0a46fSAndroid Build Coastguard Worker void CFWL_DateTimePicker::OnFocusGained(CFWL_Message* pMsg) {
356*3ac0a46fSAndroid Build Coastguard Worker   m_Properties.m_dwStates |= FWL_STATE_WGT_Focused;
357*3ac0a46fSAndroid Build Coastguard Worker   if (m_pEdit && !(m_pEdit->GetStyleExts() & FWL_STYLEEXT_EDT_ReadOnly)) {
358*3ac0a46fSAndroid Build Coastguard Worker     m_BtnRect =
359*3ac0a46fSAndroid Build Coastguard Worker         CFX_RectF(m_WidgetRect.width, 0, m_fBtn, m_WidgetRect.height - 1);
360*3ac0a46fSAndroid Build Coastguard Worker   }
361*3ac0a46fSAndroid Build Coastguard Worker   CFX_RectF rtInvalidate(m_BtnRect);
362*3ac0a46fSAndroid Build Coastguard Worker   pMsg->SetDstTarget(m_pEdit);
363*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->GetDelegate()->OnProcessMessage(pMsg);
364*3ac0a46fSAndroid Build Coastguard Worker   rtInvalidate.Inflate(2, 2);
365*3ac0a46fSAndroid Build Coastguard Worker   RepaintRect(rtInvalidate);
366*3ac0a46fSAndroid Build Coastguard Worker }
367*3ac0a46fSAndroid Build Coastguard Worker 
OnFocusLost(CFWL_Message * pMsg)368*3ac0a46fSAndroid Build Coastguard Worker void CFWL_DateTimePicker::OnFocusLost(CFWL_Message* pMsg) {
369*3ac0a46fSAndroid Build Coastguard Worker   CFX_RectF rtInvalidate(m_BtnRect);
370*3ac0a46fSAndroid Build Coastguard Worker   m_Properties.m_dwStates &= ~FWL_STATE_WGT_Focused;
371*3ac0a46fSAndroid Build Coastguard Worker   m_BtnRect = CFX_RectF();
372*3ac0a46fSAndroid Build Coastguard Worker   HideMonthCalendar();
373*3ac0a46fSAndroid Build Coastguard Worker   if (m_pEdit->GetStates() & FWL_STATE_WGT_Focused)
374*3ac0a46fSAndroid Build Coastguard Worker     m_pEdit->GetDelegate()->OnProcessMessage(pMsg);
375*3ac0a46fSAndroid Build Coastguard Worker   rtInvalidate.Inflate(2, 2);
376*3ac0a46fSAndroid Build Coastguard Worker   RepaintRect(rtInvalidate);
377*3ac0a46fSAndroid Build Coastguard Worker }
378*3ac0a46fSAndroid Build Coastguard Worker 
OnLButtonDown(CFWL_MessageMouse * pMsg)379*3ac0a46fSAndroid Build Coastguard Worker void CFWL_DateTimePicker::OnLButtonDown(CFWL_MessageMouse* pMsg) {
380*3ac0a46fSAndroid Build Coastguard Worker   if (!pMsg)
381*3ac0a46fSAndroid Build Coastguard Worker     return;
382*3ac0a46fSAndroid Build Coastguard Worker   if (!m_BtnRect.Contains(pMsg->m_pos))
383*3ac0a46fSAndroid Build Coastguard Worker     return;
384*3ac0a46fSAndroid Build Coastguard Worker 
385*3ac0a46fSAndroid Build Coastguard Worker   if (IsMonthCalendarVisible()) {
386*3ac0a46fSAndroid Build Coastguard Worker     HideMonthCalendar();
387*3ac0a46fSAndroid Build Coastguard Worker     return;
388*3ac0a46fSAndroid Build Coastguard Worker   }
389*3ac0a46fSAndroid Build Coastguard Worker   ShowMonthCalendar();
390*3ac0a46fSAndroid Build Coastguard Worker   m_bLBtnDown = true;
391*3ac0a46fSAndroid Build Coastguard Worker   RepaintRect(m_ClientRect);
392*3ac0a46fSAndroid Build Coastguard Worker }
393*3ac0a46fSAndroid Build Coastguard Worker 
OnLButtonUp(CFWL_MessageMouse * pMsg)394*3ac0a46fSAndroid Build Coastguard Worker void CFWL_DateTimePicker::OnLButtonUp(CFWL_MessageMouse* pMsg) {
395*3ac0a46fSAndroid Build Coastguard Worker   if (!pMsg)
396*3ac0a46fSAndroid Build Coastguard Worker     return;
397*3ac0a46fSAndroid Build Coastguard Worker 
398*3ac0a46fSAndroid Build Coastguard Worker   m_bLBtnDown = false;
399*3ac0a46fSAndroid Build Coastguard Worker   if (m_BtnRect.Contains(pMsg->m_pos))
400*3ac0a46fSAndroid Build Coastguard Worker     m_iBtnState = CFWL_PartState::kHovered;
401*3ac0a46fSAndroid Build Coastguard Worker   else
402*3ac0a46fSAndroid Build Coastguard Worker     m_iBtnState = CFWL_PartState::kNormal;
403*3ac0a46fSAndroid Build Coastguard Worker   RepaintRect(m_BtnRect);
404*3ac0a46fSAndroid Build Coastguard Worker }
405*3ac0a46fSAndroid Build Coastguard Worker 
OnMouseMove(CFWL_MessageMouse * pMsg)406*3ac0a46fSAndroid Build Coastguard Worker void CFWL_DateTimePicker::OnMouseMove(CFWL_MessageMouse* pMsg) {
407*3ac0a46fSAndroid Build Coastguard Worker   if (!m_BtnRect.Contains(pMsg->m_pos))
408*3ac0a46fSAndroid Build Coastguard Worker     m_iBtnState = CFWL_PartState::kNormal;
409*3ac0a46fSAndroid Build Coastguard Worker   RepaintRect(m_BtnRect);
410*3ac0a46fSAndroid Build Coastguard Worker }
411*3ac0a46fSAndroid Build Coastguard Worker 
OnMouseLeave(CFWL_MessageMouse * pMsg)412*3ac0a46fSAndroid Build Coastguard Worker void CFWL_DateTimePicker::OnMouseLeave(CFWL_MessageMouse* pMsg) {
413*3ac0a46fSAndroid Build Coastguard Worker   if (!pMsg)
414*3ac0a46fSAndroid Build Coastguard Worker     return;
415*3ac0a46fSAndroid Build Coastguard Worker   m_iBtnState = CFWL_PartState::kNormal;
416*3ac0a46fSAndroid Build Coastguard Worker   RepaintRect(m_BtnRect);
417*3ac0a46fSAndroid Build Coastguard Worker }
418*3ac0a46fSAndroid Build Coastguard Worker 
GetPopupPos(float fMinHeight,float fMaxHeight,const CFX_RectF & rtAnchor,CFX_RectF * pPopupRect)419*3ac0a46fSAndroid Build Coastguard Worker void CFWL_DateTimePicker::GetPopupPos(float fMinHeight,
420*3ac0a46fSAndroid Build Coastguard Worker                                       float fMaxHeight,
421*3ac0a46fSAndroid Build Coastguard Worker                                       const CFX_RectF& rtAnchor,
422*3ac0a46fSAndroid Build Coastguard Worker                                       CFX_RectF* pPopupRect) {
423*3ac0a46fSAndroid Build Coastguard Worker   GetWidgetMgr()->GetAdapterPopupPos(this, fMinHeight, fMaxHeight, rtAnchor,
424*3ac0a46fSAndroid Build Coastguard Worker                                      pPopupRect);
425*3ac0a46fSAndroid Build Coastguard Worker }
426*3ac0a46fSAndroid Build Coastguard Worker 
ClearText()427*3ac0a46fSAndroid Build Coastguard Worker void CFWL_DateTimePicker::ClearText() {
428*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->ClearText();
429*3ac0a46fSAndroid Build Coastguard Worker }
430*3ac0a46fSAndroid Build Coastguard Worker 
SelectAll()431*3ac0a46fSAndroid Build Coastguard Worker void CFWL_DateTimePicker::SelectAll() {
432*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->SelectAll();
433*3ac0a46fSAndroid Build Coastguard Worker }
434*3ac0a46fSAndroid Build Coastguard Worker 
ClearSelection()435*3ac0a46fSAndroid Build Coastguard Worker void CFWL_DateTimePicker::ClearSelection() {
436*3ac0a46fSAndroid Build Coastguard Worker   m_pEdit->ClearSelection();
437*3ac0a46fSAndroid Build Coastguard Worker }
438*3ac0a46fSAndroid Build Coastguard Worker 
Copy()439*3ac0a46fSAndroid Build Coastguard Worker absl::optional<WideString> CFWL_DateTimePicker::Copy() {
440*3ac0a46fSAndroid Build Coastguard Worker   return m_pEdit->Copy();
441*3ac0a46fSAndroid Build Coastguard Worker }
442*3ac0a46fSAndroid Build Coastguard Worker 
Cut()443*3ac0a46fSAndroid Build Coastguard Worker absl::optional<WideString> CFWL_DateTimePicker::Cut() {
444*3ac0a46fSAndroid Build Coastguard Worker   return m_pEdit->Cut();
445*3ac0a46fSAndroid Build Coastguard Worker }
446*3ac0a46fSAndroid Build Coastguard Worker 
Paste(const WideString & wsPaste)447*3ac0a46fSAndroid Build Coastguard Worker bool CFWL_DateTimePicker::Paste(const WideString& wsPaste) {
448*3ac0a46fSAndroid Build Coastguard Worker   return m_pEdit->Paste(wsPaste);
449*3ac0a46fSAndroid Build Coastguard Worker }
450*3ac0a46fSAndroid Build Coastguard Worker 
Undo()451*3ac0a46fSAndroid Build Coastguard Worker bool CFWL_DateTimePicker::Undo() {
452*3ac0a46fSAndroid Build Coastguard Worker   return m_pEdit->Undo();
453*3ac0a46fSAndroid Build Coastguard Worker }
454*3ac0a46fSAndroid Build Coastguard Worker 
Redo()455*3ac0a46fSAndroid Build Coastguard Worker bool CFWL_DateTimePicker::Redo() {
456*3ac0a46fSAndroid Build Coastguard Worker   return m_pEdit->Redo();
457*3ac0a46fSAndroid Build Coastguard Worker }
458*3ac0a46fSAndroid Build Coastguard Worker 
CanUndo()459*3ac0a46fSAndroid Build Coastguard Worker bool CFWL_DateTimePicker::CanUndo() {
460*3ac0a46fSAndroid Build Coastguard Worker   return m_pEdit->CanUndo();
461*3ac0a46fSAndroid Build Coastguard Worker }
462*3ac0a46fSAndroid Build Coastguard Worker 
CanRedo()463*3ac0a46fSAndroid Build Coastguard Worker bool CFWL_DateTimePicker::CanRedo() {
464*3ac0a46fSAndroid Build Coastguard Worker   return m_pEdit->CanRedo();
465*3ac0a46fSAndroid Build Coastguard Worker }
466