diff options
author | dsinclair <dsinclair@chromium.org> | 2016-10-20 06:44:03 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-10-20 06:44:03 -0700 |
commit | fb5055947efd78e0e7f8a2bfd5b754c63dbb6076 (patch) | |
tree | 10511c1cb9b341e901a7f619a2bf6c2a74bb7f89 /xfa/fwl/core/ifwl_datetimepicker.cpp | |
parent | dadea5f87d35f8a692b659dbff54cc8780d48ef8 (diff) | |
download | pdfium-fb5055947efd78e0e7f8a2bfd5b754c63dbb6076.tar.xz |
Merge the CFWL_*Imp classes into the IFWL_* classes.
This Cl merges the implementation classes up into the IFWL classes as the
intermediate classes were just acting as proxies.
Review-Url: https://chromiumcodereview.appspot.com/2432423002
Diffstat (limited to 'xfa/fwl/core/ifwl_datetimepicker.cpp')
-rw-r--r-- | xfa/fwl/core/ifwl_datetimepicker.cpp | 873 |
1 files changed, 873 insertions, 0 deletions
diff --git a/xfa/fwl/core/ifwl_datetimepicker.cpp b/xfa/fwl/core/ifwl_datetimepicker.cpp new file mode 100644 index 0000000000..ce5f28bf08 --- /dev/null +++ b/xfa/fwl/core/ifwl_datetimepicker.cpp @@ -0,0 +1,873 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "xfa/fwl/core/ifwl_datetimepicker.h" + +#include "xfa/fwl/core/cfwl_message.h" +#include "xfa/fwl/core/cfwl_themebackground.h" +#include "xfa/fwl/core/cfwl_widgetmgr.h" +#include "xfa/fwl/core/fwl_noteimp.h" +#include "xfa/fwl/core/ifwl_datetimecalendar.h" +#include "xfa/fwl/core/ifwl_datetimeedit.h" +#include "xfa/fwl/core/ifwl_formproxy.h" +#include "xfa/fwl/core/ifwl_spinbutton.h" +#include "xfa/fwl/core/ifwl_themeprovider.h" + +namespace { + +const int kDateTimePickerWidth = 100; +const int kDateTimePickerHeight = 20; + +} // namespace + +// static +IFWL_DateTimePicker* IFWL_DateTimePicker::Create( + const CFWL_WidgetImpProperties& properties, + IFWL_Widget* pOuter) { + return new IFWL_DateTimePicker(properties, pOuter); +} + +IFWL_DateTimePicker::IFWL_DateTimePicker( + const CFWL_WidgetImpProperties& properties, + IFWL_Widget* pOuter) + : IFWL_Widget(properties, pOuter), + m_iBtnState(1), + m_iYear(-1), + m_iMonth(-1), + m_iDay(-1), + m_bLBtnDown(FALSE) { + m_rtBtn.Set(0, 0, 0, 0); +} + +IFWL_DateTimePicker::~IFWL_DateTimePicker() {} + +FWL_Error IFWL_DateTimePicker::GetClassName(CFX_WideString& wsClass) const { + wsClass = FWL_CLASS_DateTimePicker; + return FWL_Error::Succeeded; +} + +FWL_Type IFWL_DateTimePicker::GetClassID() const { + return FWL_Type::DateTimePicker; +} + +FWL_Error IFWL_DateTimePicker::Initialize() { + if (IFWL_Widget::Initialize() != FWL_Error::Succeeded) + return FWL_Error::Indefinite; + + m_pDelegate = new CFWL_DateTimePickerImpDelegate(this); + m_pProperties->m_dwStyleExes = FWL_STYLEEXT_DTP_ShortDateFormat; + CFWL_WidgetImpProperties propMonth; + propMonth.m_dwStyles = FWL_WGTSTYLE_Popup | FWL_WGTSTYLE_Border; + propMonth.m_dwStates = FWL_WGTSTATE_Invisible; + propMonth.m_pDataProvider = &m_MonthCalendarDP; + propMonth.m_pParent = this; + propMonth.m_pThemeProvider = m_pProperties->m_pThemeProvider; + m_pMonthCal.reset(IFWL_DateTimeCalendar::Create(propMonth, this)); + m_pMonthCal->Initialize(); + CFX_RectF rtMonthCal; + m_pMonthCal->GetWidgetRect(rtMonthCal, TRUE); + rtMonthCal.Set(0, 0, rtMonthCal.width, rtMonthCal.height); + m_pMonthCal->SetWidgetRect(rtMonthCal); + CFWL_WidgetImpProperties propEdit; + propEdit.m_pParent = this; + propEdit.m_pThemeProvider = m_pProperties->m_pThemeProvider; + m_pEdit.reset(IFWL_DateTimeEdit::Create(propEdit, this)); + m_pEdit->Initialize(); + RegisterEventTarget(m_pMonthCal.get()); + RegisterEventTarget(m_pEdit.get()); + return FWL_Error::Succeeded; +} + +FWL_Error IFWL_DateTimePicker::Finalize() { + if (m_pEdit) { + m_pEdit->Finalize(); + } + if (m_pMonthCal) { + m_pMonthCal->Finalize(); + } + if (m_pForm) { + m_pForm->Finalize(); + } + UnregisterEventTarget(); + delete m_pDelegate; + m_pDelegate = nullptr; + return IFWL_Widget::Finalize(); +} + +FWL_Error IFWL_DateTimePicker::GetWidgetRect(CFX_RectF& rect, + FX_BOOL bAutoSize) { + if (m_pWidgetMgr->IsFormDisabled()) { + return DisForm_GetWidgetRect(rect, bAutoSize); + } + if (bAutoSize) { + rect.Set(0, 0, kDateTimePickerWidth, kDateTimePickerHeight); + IFWL_Widget::GetWidgetRect(rect, TRUE); + } else { + rect = m_pProperties->m_rtWidget; + } + return FWL_Error::Succeeded; +} + +FWL_Error IFWL_DateTimePicker::Update() { + if (m_pWidgetMgr->IsFormDisabled()) { + return DisForm_Update(); + } + if (m_iLock) { + return FWL_Error::Indefinite; + } + if (!m_pProperties->m_pThemeProvider) { + m_pProperties->m_pThemeProvider = GetAvailableTheme(); + } + m_pEdit->SetThemeProvider(m_pProperties->m_pThemeProvider); + GetClientRect(m_rtClient); + FX_FLOAT* pFWidth = static_cast<FX_FLOAT*>( + GetThemeCapacity(CFWL_WidgetCapacity::ScrollBarWidth)); + if (!pFWidth) + return FWL_Error::Indefinite; + FX_FLOAT fBtn = *pFWidth; + m_rtBtn.Set(m_rtClient.right() - fBtn, m_rtClient.top, fBtn - 1, + m_rtClient.height - 1); + CFX_RectF rtEdit; + rtEdit.Set(m_rtClient.left, m_rtClient.top, m_rtClient.width - fBtn, + m_rtClient.height); + m_pEdit->SetWidgetRect(rtEdit); + ReSetEditAlignment(); + m_pEdit->Update(); + if (!(m_pMonthCal->GetThemeProvider())) { + m_pMonthCal->SetThemeProvider(m_pProperties->m_pThemeProvider); + } + if (m_pProperties->m_pDataProvider) { + IFWL_DateTimePickerDP* pData = + static_cast<IFWL_DateTimePickerDP*>(m_pProperties->m_pDataProvider); + pData->GetToday(this, m_MonthCalendarDP.m_iCurYear, + m_MonthCalendarDP.m_iCurMonth, m_MonthCalendarDP.m_iCurDay); + } + CFX_RectF rtMonthCal; + m_pMonthCal->GetWidgetRect(rtMonthCal, TRUE); + CFX_RectF rtPopUp; + rtPopUp.Set(rtMonthCal.left, rtMonthCal.top + kDateTimePickerHeight, + rtMonthCal.width, rtMonthCal.height); + m_pMonthCal->SetWidgetRect(rtPopUp); + m_pMonthCal->Update(); + return FWL_Error::Succeeded; +} + +int32_t IFWL_DateTimePicker::CountSelRanges() { + return GetDataTimeEdit()->CountSelRanges(); +} + +int32_t IFWL_DateTimePicker::GetSelRange(int32_t nIndex, int32_t& nStart) { + return GetDataTimeEdit()->GetSelRange(nIndex, nStart); +} + +FWL_WidgetHit IFWL_DateTimePicker::HitTest(FX_FLOAT fx, FX_FLOAT fy) { + if (m_pWidgetMgr->IsFormDisabled()) + return DisForm_HitTest(fx, fy); + if (m_rtClient.Contains(fx, fy)) + return FWL_WidgetHit::Client; + if (IsMonthCalendarShowed()) { + CFX_RectF rect; + m_pMonthCal->GetWidgetRect(rect); + if (rect.Contains(fx, fy)) + return FWL_WidgetHit::Client; + } + return FWL_WidgetHit::Unknown; +} + +FWL_Error IFWL_DateTimePicker::DrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) { + if (!pGraphics) + return FWL_Error::Indefinite; + if (!m_pProperties->m_pThemeProvider) + return FWL_Error::Indefinite; + IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider; + if (HasBorder()) { + DrawBorder(pGraphics, CFWL_Part::Border, pTheme, pMatrix); + } + if (HasEdge()) { + DrawEdge(pGraphics, CFWL_Part::Edge, pTheme, pMatrix); + } + if (!m_rtBtn.IsEmpty()) { + DrawDropDownButton(pGraphics, pTheme, pMatrix); + } + if (m_pWidgetMgr->IsFormDisabled()) { + return DisForm_DrawWidget(pGraphics, pMatrix); + } + return FWL_Error::Succeeded; +} + +FWL_Error IFWL_DateTimePicker::SetThemeProvider(IFWL_ThemeProvider* pTP) { + m_pProperties->m_pThemeProvider = pTP; + m_pMonthCal->SetThemeProvider(pTP); + return FWL_Error::Succeeded; +} + +FWL_Error IFWL_DateTimePicker::GetCurSel(int32_t& iYear, + int32_t& iMonth, + int32_t& iDay) { + iYear = m_iYear; + iMonth = m_iMonth; + iDay = m_iDay; + return FWL_Error::Succeeded; +} + +FWL_Error IFWL_DateTimePicker::SetCurSel(int32_t iYear, + int32_t iMonth, + int32_t iDay) { + if (iYear <= 0 || iYear >= 3000) + return FWL_Error::Indefinite; + if (iMonth <= 0 || iMonth >= 13) + return FWL_Error::Indefinite; + if (iDay <= 0 || iDay >= 32) + return FWL_Error::Indefinite; + m_iYear = iYear; + m_iMonth = iMonth; + m_iDay = iDay; + m_pMonthCal->SetSelect(iYear, iMonth, iDay); + return FWL_Error::Succeeded; +} + +FWL_Error IFWL_DateTimePicker::SetEditText(const CFX_WideString& wsText) { + if (!m_pEdit) + return FWL_Error::Indefinite; + + FWL_Error iRet = m_pEdit->SetText(wsText); + Repaint(&m_rtClient); + CFWL_Event_DtpEditChanged ev; + ev.m_wsText = wsText; + DispatchEvent(&ev); + return iRet; +} + +FWL_Error IFWL_DateTimePicker::GetEditText(CFX_WideString& wsText, + int32_t nStart, + int32_t nCount) const { + if (m_pEdit) { + return m_pEdit->GetText(wsText, nStart, nCount); + } + return FWL_Error::Indefinite; +} + +FX_BOOL IFWL_DateTimePicker::CanUndo() { + return m_pEdit->CanUndo(); +} + +FX_BOOL IFWL_DateTimePicker::CanRedo() { + return m_pEdit->CanRedo(); +} + +FX_BOOL IFWL_DateTimePicker::Undo() { + return m_pEdit->Undo(); +} + +FX_BOOL IFWL_DateTimePicker::Redo() { + return m_pEdit->Redo(); +} + +FX_BOOL IFWL_DateTimePicker::CanCopy() { + int32_t nCount = m_pEdit->CountSelRanges(); + return nCount > 0; +} + +FX_BOOL IFWL_DateTimePicker::CanCut() { + if (m_pEdit->GetStylesEx() & FWL_STYLEEXT_EDT_ReadOnly) { + return FALSE; + } + int32_t nCount = m_pEdit->CountSelRanges(); + return nCount > 0; +} + +FX_BOOL IFWL_DateTimePicker::CanSelectAll() { + return m_pEdit->GetTextLength() > 0; +} + +FX_BOOL IFWL_DateTimePicker::Copy(CFX_WideString& wsCopy) { + return m_pEdit->Copy(wsCopy); +} + +FX_BOOL IFWL_DateTimePicker::Cut(CFX_WideString& wsCut) { + return m_pEdit->Cut(wsCut); +} + +FX_BOOL IFWL_DateTimePicker::Paste(const CFX_WideString& wsPaste) { + return m_pEdit->Paste(wsPaste); +} + +FX_BOOL IFWL_DateTimePicker::SelectAll() { + return m_pEdit->AddSelRange(0) == FWL_Error::Succeeded; +} + +FX_BOOL IFWL_DateTimePicker::Delete() { + return m_pEdit->ClearText() == FWL_Error::Succeeded; +} + +FX_BOOL IFWL_DateTimePicker::DeSelect() { + return m_pEdit->ClearSelections() == FWL_Error::Succeeded; +} + +FWL_Error IFWL_DateTimePicker::GetBBox(CFX_RectF& rect) { + if (m_pWidgetMgr->IsFormDisabled()) { + return DisForm_GetBBox(rect); + } + rect = m_pProperties->m_rtWidget; + if (IsMonthCalendarShowed()) { + CFX_RectF rtMonth; + m_pMonthCal->GetWidgetRect(rtMonth); + rtMonth.Offset(m_pProperties->m_rtWidget.left, + m_pProperties->m_rtWidget.top); + rect.Union(rtMonth); + } + return FWL_Error::Succeeded; +} + +FWL_Error IFWL_DateTimePicker::SetEditLimit(int32_t nLimit) { + return m_pEdit->SetLimit(nLimit); +} + +FWL_Error IFWL_DateTimePicker::ModifyEditStylesEx(uint32_t dwStylesExAdded, + uint32_t dwStylesExRemoved) { + return m_pEdit->ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved); +} + +void IFWL_DateTimePicker::DrawDropDownButton(CFX_Graphics* pGraphics, + IFWL_ThemeProvider* pTheme, + const CFX_Matrix* pMatrix) { + if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_Spin) == + FWL_STYLEEXT_DTP_Spin) { + CFWL_WidgetImpProperties prop; + prop.m_dwStyleExes |= FWL_STYLEEXE_SPB_Vert; + prop.m_pParent = this; + prop.m_rtWidget = m_rtBtn; + IFWL_SpinButton* pSpin = IFWL_SpinButton::Create(prop, this); + pSpin->Initialize(); + } else { + CFWL_ThemeBackground param; + param.m_pWidget = this; + param.m_iPart = CFWL_Part::DropDownButton; + param.m_dwStates = m_iBtnState; + param.m_pGraphics = pGraphics; + param.m_rtPart = m_rtBtn; + if (pMatrix) { + param.m_matrix.Concat(*pMatrix); + } + pTheme->DrawBackground(¶m); + } +} + +void IFWL_DateTimePicker::FormatDateString(int32_t iYear, + int32_t iMonth, + int32_t iDay, + CFX_WideString& wsText) { + if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_ShortDateFormat) == + FWL_STYLEEXT_DTP_ShortDateFormat) { + wsText.Format(L"%d-%d-%d", iYear, iMonth, iDay); + } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_LongDateFormat) == + FWL_STYLEEXT_DTP_LongDateFormat) { + wsText.Format(L"%d Year %d Month %d Day", iYear, iMonth, iDay); + } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_TimeFormat) == + FWL_STYLEEXT_DTP_TimeFormat) { + } +} + +void IFWL_DateTimePicker::ShowMonthCalendar(FX_BOOL bActivate) { + if (m_pWidgetMgr->IsFormDisabled()) { + return DisForm_ShowMonthCalendar(bActivate); + } + if (IsMonthCalendarShowed() == bActivate) { + return; + } + if (!m_pForm) { + InitProxyForm(); + } + if (bActivate) { + CFX_RectF rtMonth; + m_pMonthCal->GetWidgetRect(rtMonth); + CFX_RectF rtAnchor; + rtAnchor.Set(0, 0, m_pProperties->m_rtWidget.width, + m_pProperties->m_rtWidget.height); + GetPopupPos(0, rtMonth.height, rtAnchor, rtMonth); + m_pForm->SetWidgetRect(rtMonth); + rtMonth.left = rtMonth.top = 0; + m_pMonthCal->SetStates(FWL_WGTSTATE_Invisible, !bActivate); + m_pMonthCal->SetWidgetRect(rtMonth); + m_pMonthCal->Update(); + m_pForm->DoModal(); + } else { + m_pForm->EndDoModal(); + } +} + +FX_BOOL IFWL_DateTimePicker::IsMonthCalendarShowed() { + if (m_pWidgetMgr->IsFormDisabled()) { + return DisForm_IsMonthCalendarShowed(); + } + if (!m_pForm) + return FALSE; + return !(m_pForm->GetStates() & FWL_WGTSTATE_Invisible); +} + +void IFWL_DateTimePicker::ReSetEditAlignment() { + if (!m_pEdit) + return; + uint32_t dwStylExes = m_pProperties->m_dwStyleExes; + uint32_t dwAdd = 0; + switch (dwStylExes & FWL_STYLEEXT_DTP_EditHAlignMask) { + case FWL_STYLEEXT_DTP_EditHCenter: { + dwAdd |= FWL_STYLEEXT_EDT_HCenter; + break; + } + case FWL_STYLEEXT_DTP_EditHFar: { + dwAdd |= FWL_STYLEEXT_EDT_HFar; + break; + } + default: { dwAdd |= FWL_STYLEEXT_EDT_HNear; } + } + switch (dwStylExes & FWL_STYLEEXT_DTP_EditVAlignMask) { + case FWL_STYLEEXT_DTP_EditVCenter: { + dwAdd |= FWL_STYLEEXT_EDT_VCenter; + break; + } + case FWL_STYLEEXT_DTP_EditVFar: { + dwAdd |= FWL_STYLEEXT_EDT_VFar; + break; + } + default: { dwAdd |= FWL_STYLEEXT_EDT_VNear; } + } + if (dwStylExes & FWL_STYLEEXT_DTP_EditJustified) { + dwAdd |= FWL_STYLEEXT_EDT_Justified; + } + if (dwStylExes & FWL_STYLEEXT_DTP_EditDistributed) { + dwAdd |= FWL_STYLEEXT_EDT_Distributed; + } + m_pEdit->ModifyStylesEx(dwAdd, FWL_STYLEEXT_EDT_HAlignMask | + FWL_STYLEEXT_EDT_HAlignModeMask | + FWL_STYLEEXT_EDT_VAlignMask); +} + +void IFWL_DateTimePicker::ProcessSelChanged(int32_t iYear, + int32_t iMonth, + int32_t iDay) { + m_iYear = iYear; + m_iMonth = iMonth; + m_iDay = iDay; + CFX_WideString wsText; + FormatDateString(m_iYear, m_iMonth, m_iDay, wsText); + m_pEdit->SetText(wsText); + m_pEdit->Update(); + Repaint(&m_rtClient); + CFWL_Event_DtpSelectChanged ev; + ev.m_pSrcTarget = this; + ev.iYear = m_iYear; + ev.iMonth = m_iMonth; + ev.iDay = m_iDay; + DispatchEvent(&ev); +} + +void IFWL_DateTimePicker::InitProxyForm() { + if (m_pForm) + return; + if (!m_pMonthCal) + return; + CFWL_WidgetImpProperties propForm; + propForm.m_dwStyles = FWL_WGTSTYLE_Popup; + propForm.m_dwStates = FWL_WGTSTATE_Invisible; + propForm.m_pOwner = this; + m_pForm.reset(IFWL_FormProxy::Create(propForm, m_pMonthCal.get())); + m_pForm->Initialize(); + m_pMonthCal->SetParent(m_pForm.get()); +} + +IFWL_DateTimeEdit* IFWL_DateTimePicker::GetDataTimeEdit() { + return m_pEdit.get(); +} + +FWL_Error IFWL_DateTimePicker::DisForm_Initialize() { + m_pProperties->m_dwStyleExes = FWL_STYLEEXT_DTP_ShortDateFormat; + DisForm_InitDateTimeCalendar(); + DisForm_InitDateTimeEdit(); + RegisterEventTarget(m_pMonthCal.get()); + RegisterEventTarget(m_pEdit.get()); + return FWL_Error::Succeeded; +} + +void IFWL_DateTimePicker::DisForm_InitDateTimeCalendar() { + if (m_pMonthCal) { + return; + } + CFWL_WidgetImpProperties propMonth; + propMonth.m_dwStyles = + FWL_WGTSTYLE_Popup | FWL_WGTSTYLE_Border | FWL_WGTSTYLE_EdgeSunken; + propMonth.m_dwStates = FWL_WGTSTATE_Invisible; + propMonth.m_pParent = this; + propMonth.m_pDataProvider = &m_MonthCalendarDP; + propMonth.m_pThemeProvider = m_pProperties->m_pThemeProvider; + m_pMonthCal.reset(IFWL_DateTimeCalendar::Create(propMonth, this)); + m_pMonthCal->Initialize(); + CFX_RectF rtMonthCal; + m_pMonthCal->GetWidgetRect(rtMonthCal, TRUE); + rtMonthCal.Set(0, 0, rtMonthCal.width, rtMonthCal.height); + m_pMonthCal->SetWidgetRect(rtMonthCal); +} + +void IFWL_DateTimePicker::DisForm_InitDateTimeEdit() { + if (m_pEdit) { + return; + } + CFWL_WidgetImpProperties propEdit; + propEdit.m_pParent = this; + propEdit.m_pThemeProvider = m_pProperties->m_pThemeProvider; + m_pEdit.reset(IFWL_DateTimeEdit::Create(propEdit, this)); + m_pEdit->Initialize(); +} + +FX_BOOL IFWL_DateTimePicker::DisForm_IsMonthCalendarShowed() { + if (!m_pMonthCal) + return FALSE; + return !(m_pMonthCal->GetStates() & FWL_WGTSTATE_Invisible); +} + +void IFWL_DateTimePicker::DisForm_ShowMonthCalendar(FX_BOOL bActivate) { + FX_BOOL bShowed = IsMonthCalendarShowed(); + if (bShowed == bActivate) { + return; + } + if (bActivate) { + CFX_RectF rtMonthCal; + m_pMonthCal->GetWidgetRect(rtMonthCal, TRUE); + FX_FLOAT fPopupMin = rtMonthCal.height; + FX_FLOAT fPopupMax = rtMonthCal.height; + CFX_RectF rtAnchor(m_pProperties->m_rtWidget); + rtAnchor.width = rtMonthCal.width; + rtMonthCal.left = m_rtClient.left; + rtMonthCal.top = rtAnchor.Height(); + GetPopupPos(fPopupMin, fPopupMax, rtAnchor, rtMonthCal); + m_pMonthCal->SetWidgetRect(rtMonthCal); + if (m_iYear > 0 && m_iMonth > 0 && m_iDay > 0) { + m_pMonthCal->SetSelect(m_iYear, m_iMonth, m_iDay); + } + m_pMonthCal->Update(); + } + m_pMonthCal->SetStates(FWL_WGTSTATE_Invisible, !bActivate); + if (bActivate) { + CFWL_MsgSetFocus msg; + msg.m_pDstTarget = m_pMonthCal.get(); + msg.m_pSrcTarget = m_pEdit.get(); + IFWL_WidgetDelegate* pDelegate = m_pEdit->SetDelegate(nullptr); + pDelegate->OnProcessMessage(&msg); + } + CFX_RectF rtInvalidate, rtCal; + rtInvalidate.Set(0, 0, m_pProperties->m_rtWidget.width, + m_pProperties->m_rtWidget.height); + m_pMonthCal->GetWidgetRect(rtCal); + rtInvalidate.Union(rtCal); + rtInvalidate.Inflate(2, 2); + Repaint(&rtInvalidate); +} + +FWL_WidgetHit IFWL_DateTimePicker::DisForm_HitTest(FX_FLOAT fx, FX_FLOAT fy) { + CFX_RectF rect; + rect.Set(0, 0, m_pProperties->m_rtWidget.width, + m_pProperties->m_rtWidget.height); + if (rect.Contains(fx, fy)) + return FWL_WidgetHit::Edit; + if (DisForm_IsNeedShowButton()) + rect.width += m_fBtn; + if (rect.Contains(fx, fy)) + return FWL_WidgetHit::Client; + if (IsMonthCalendarShowed()) { + m_pMonthCal->GetWidgetRect(rect); + if (rect.Contains(fx, fy)) + return FWL_WidgetHit::Client; + } + return FWL_WidgetHit::Unknown; +} + +FX_BOOL IFWL_DateTimePicker::DisForm_IsNeedShowButton() { + FX_BOOL bFocus = m_pProperties->m_dwStates & FWL_WGTSTATE_Focused || + m_pMonthCal->GetStates() & FWL_WGTSTATE_Focused || + m_pEdit->GetStates() & FWL_WGTSTATE_Focused; + return bFocus; +} + +FWL_Error IFWL_DateTimePicker::DisForm_Update() { + if (m_iLock) + return FWL_Error::Indefinite; + if (!m_pProperties->m_pThemeProvider) + m_pProperties->m_pThemeProvider = GetAvailableTheme(); + + m_pEdit->SetThemeProvider(m_pProperties->m_pThemeProvider); + GetClientRect(m_rtClient); + m_pEdit->SetWidgetRect(m_rtClient); + ReSetEditAlignment(); + m_pEdit->Update(); + if (!m_pMonthCal->GetThemeProvider()) + m_pMonthCal->SetThemeProvider(m_pProperties->m_pThemeProvider); + + if (m_pProperties->m_pDataProvider) { + IFWL_DateTimePickerDP* pData = + static_cast<IFWL_DateTimePickerDP*>(m_pProperties->m_pDataProvider); + pData->GetToday(this, m_MonthCalendarDP.m_iCurYear, + m_MonthCalendarDP.m_iCurMonth, m_MonthCalendarDP.m_iCurDay); + } + FX_FLOAT* pWidth = static_cast<FX_FLOAT*>( + GetThemeCapacity(CFWL_WidgetCapacity::ScrollBarWidth)); + if (!pWidth) + return FWL_Error::Succeeded; + + m_fBtn = *pWidth; + CFX_RectF rtMonthCal; + m_pMonthCal->GetWidgetRect(rtMonthCal, TRUE); + CFX_RectF rtPopUp; + rtPopUp.Set(rtMonthCal.left, rtMonthCal.top + kDateTimePickerHeight, + rtMonthCal.width, rtMonthCal.height); + m_pMonthCal->SetWidgetRect(rtPopUp); + m_pMonthCal->Update(); + return FWL_Error::Succeeded; +} + +FWL_Error IFWL_DateTimePicker::DisForm_GetWidgetRect(CFX_RectF& rect, + FX_BOOL bAutoSize) { + rect = m_pProperties->m_rtWidget; + if (DisForm_IsNeedShowButton()) { + rect.width += m_fBtn; + } + return FWL_Error::Succeeded; +} + +FWL_Error IFWL_DateTimePicker::DisForm_GetBBox(CFX_RectF& rect) { + rect = m_pProperties->m_rtWidget; + if (DisForm_IsNeedShowButton()) { + rect.width += m_fBtn; + } + if (IsMonthCalendarShowed()) { + CFX_RectF rtMonth; + m_pMonthCal->GetWidgetRect(rtMonth); + rtMonth.Offset(m_pProperties->m_rtWidget.left, + m_pProperties->m_rtWidget.top); + rect.Union(rtMonth); + } + return FWL_Error::Succeeded; +} + +FWL_Error IFWL_DateTimePicker::DisForm_DrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) { + if (!pGraphics) + return FWL_Error::Indefinite; + if (m_pEdit) { + CFX_RectF rtEdit; + m_pEdit->GetWidgetRect(rtEdit); + CFX_Matrix mt; + mt.Set(1, 0, 0, 1, rtEdit.left, rtEdit.top); + if (pMatrix) { + mt.Concat(*pMatrix); + } + m_pEdit->DrawWidget(pGraphics, &mt); + } + if (IsMonthCalendarShowed()) { + CFX_RectF rtMonth; + m_pMonthCal->GetWidgetRect(rtMonth); + CFX_Matrix mt; + mt.Set(1, 0, 0, 1, rtMonth.left, rtMonth.top); + if (pMatrix) { + mt.Concat(*pMatrix); + } + m_pMonthCal->DrawWidget(pGraphics, &mt); + } + return FWL_Error::Succeeded; +} + +CFWL_DateTimePickerImpDelegate::CFWL_DateTimePickerImpDelegate( + IFWL_DateTimePicker* pOwner) + : m_pOwner(pOwner) {} + +void CFWL_DateTimePickerImpDelegate::OnProcessMessage(CFWL_Message* pMessage) { + if (!pMessage) + return; + + switch (pMessage->GetClassID()) { + case CFWL_MessageType::SetFocus: { + OnFocusChanged(pMessage, TRUE); + break; + } + case CFWL_MessageType::KillFocus: { + OnFocusChanged(pMessage, FALSE); + break; + } + case CFWL_MessageType::Mouse: { + CFWL_MsgMouse* pMouse = static_cast<CFWL_MsgMouse*>(pMessage); + switch (pMouse->m_dwCmd) { + case FWL_MouseCommand::LeftButtonDown: { + OnLButtonDown(pMouse); + break; + } + case FWL_MouseCommand::LeftButtonUp: { + OnLButtonUp(pMouse); + break; + } + case FWL_MouseCommand::Move: { + OnMouseMove(pMouse); + break; + } + case FWL_MouseCommand::Leave: { + OnMouseLeave(pMouse); + break; + } + default: + break; + } + break; + } + case CFWL_MessageType::Key: { + if (m_pOwner->m_pEdit->GetStates() & FWL_WGTSTATE_Focused) { + IFWL_WidgetDelegate* pDelegate = + m_pOwner->m_pEdit->SetDelegate(nullptr); + pDelegate->OnProcessMessage(pMessage); + return; + } + break; + } + default: + break; + } + + CFWL_WidgetImpDelegate::OnProcessMessage(pMessage); +} + +void CFWL_DateTimePickerImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) { + m_pOwner->DrawWidget(pGraphics, pMatrix); +} + +void CFWL_DateTimePickerImpDelegate::OnFocusChanged(CFWL_Message* pMsg, + FX_BOOL bSet) { + if (!pMsg) + return; + if (m_pOwner->m_pWidgetMgr->IsFormDisabled()) { + return DisForm_OnFocusChanged(pMsg, bSet); + } + if (bSet) { + m_pOwner->m_pProperties->m_dwStates |= (FWL_WGTSTATE_Focused); + m_pOwner->Repaint(&m_pOwner->m_rtClient); + } else { + m_pOwner->m_pProperties->m_dwStates &= ~(FWL_WGTSTATE_Focused); + m_pOwner->Repaint(&m_pOwner->m_rtClient); + } + if (pMsg->m_pSrcTarget == m_pOwner->m_pMonthCal.get() && + m_pOwner->IsMonthCalendarShowed()) { + m_pOwner->ShowMonthCalendar(FALSE); + } + m_pOwner->Repaint(&m_pOwner->m_rtClient); +} + +void CFWL_DateTimePickerImpDelegate::OnLButtonDown(CFWL_MsgMouse* pMsg) { + if (!pMsg) + return; + if ((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) { + m_pOwner->SetFocus(TRUE); + } + if (m_pOwner->m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) { + if (m_pOwner->IsMonthCalendarShowed()) { + m_pOwner->ShowMonthCalendar(FALSE); + CFWL_Event_DtpCloseUp ev; + m_pOwner->DispatchEvent(&ev); + } else { + if (!(m_pOwner->m_pProperties->m_dwStyleExes & + FWL_STYLEEXT_DTP_TimeFormat)) { + m_pOwner->ShowMonthCalendar(TRUE); + CFWL_Event_DtpDropDown ev; + m_pOwner->DispatchEvent(&ev); + } else { + } + m_pOwner->m_bLBtnDown = TRUE; + m_pOwner->Repaint(&m_pOwner->m_rtClient); + } + } +} + +void CFWL_DateTimePickerImpDelegate::OnLButtonUp(CFWL_MsgMouse* pMsg) { + if (!pMsg) + return; + m_pOwner->m_bLBtnDown = FALSE; + if (m_pOwner->m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) { + m_pOwner->m_iBtnState = CFWL_PartState_Hovered; + } else { + m_pOwner->m_iBtnState = CFWL_PartState_Normal; + } + m_pOwner->Repaint(&m_pOwner->m_rtBtn); +} + +void CFWL_DateTimePickerImpDelegate::OnMouseMove(CFWL_MsgMouse* pMsg) { + if (m_pOwner->m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) { + } else { + m_pOwner->m_iBtnState = CFWL_PartState_Normal; + } + m_pOwner->Repaint(&m_pOwner->m_rtBtn); +} + +void CFWL_DateTimePickerImpDelegate::OnMouseLeave(CFWL_MsgMouse* pMsg) { + if (!pMsg) + return; + m_pOwner->m_iBtnState = CFWL_PartState_Normal; + m_pOwner->Repaint(&m_pOwner->m_rtBtn); +} + +void CFWL_DateTimePickerImpDelegate::DisForm_OnFocusChanged(CFWL_Message* pMsg, + FX_BOOL bSet) { + CFX_RectF rtInvalidate(m_pOwner->m_rtBtn); + if (bSet) { + m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused; + if (m_pOwner->m_pEdit && + !(m_pOwner->m_pEdit->GetStylesEx() & FWL_STYLEEXT_EDT_ReadOnly)) { + m_pOwner->m_rtBtn.Set(m_pOwner->m_pProperties->m_rtWidget.width, 0, + m_pOwner->m_fBtn, + m_pOwner->m_pProperties->m_rtWidget.height - 1); + } + rtInvalidate = m_pOwner->m_rtBtn; + pMsg->m_pDstTarget = m_pOwner->m_pEdit.get(); + IFWL_WidgetDelegate* pDelegate = m_pOwner->m_pEdit->SetDelegate(nullptr); + pDelegate->OnProcessMessage(pMsg); + } else { + m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused; + m_pOwner->m_rtBtn.Set(0, 0, 0, 0); + if (m_pOwner->DisForm_IsMonthCalendarShowed()) { + m_pOwner->ShowMonthCalendar(FALSE); + } + if (m_pOwner->m_pEdit->GetStates() & FWL_WGTSTATE_Focused) { + pMsg->m_pSrcTarget = m_pOwner->m_pEdit.get(); + IFWL_WidgetDelegate* pDelegate = m_pOwner->m_pEdit->SetDelegate(nullptr); + pDelegate->OnProcessMessage(pMsg); + } + } + rtInvalidate.Inflate(2, 2); + m_pOwner->Repaint(&rtInvalidate); +} + +IFWL_DateTimePicker::CFWL_MonthCalendarImpDP::CFWL_MonthCalendarImpDP() { + m_iCurYear = 2010; + m_iCurMonth = 3; + m_iCurDay = 29; +} + +FWL_Error IFWL_DateTimePicker::CFWL_MonthCalendarImpDP::GetCaption( + IFWL_Widget* pWidget, + CFX_WideString& wsCaption) { + return FWL_Error::Succeeded; +} + +int32_t IFWL_DateTimePicker::CFWL_MonthCalendarImpDP::GetCurDay( + IFWL_Widget* pWidget) { + return m_iCurDay; +} + +int32_t IFWL_DateTimePicker::CFWL_MonthCalendarImpDP::GetCurMonth( + IFWL_Widget* pWidget) { + return m_iCurMonth; +} + +int32_t IFWL_DateTimePicker::CFWL_MonthCalendarImpDP::GetCurYear( + IFWL_Widget* pWidget) { + return m_iCurYear; +} |