diff options
author | dsinclair <dsinclair@chromium.org> | 2016-11-23 16:17:20 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-11-23 16:17:21 -0800 |
commit | 2c489cc41023a40648dfde988d11b8ec2b66c7d0 (patch) | |
tree | 78255c80c547a5954ed5778f1a809d3166a5f3e2 /xfa/fwl/core | |
parent | 0ce11eef157b791c661d7e82e1c5641605b9f03d (diff) | |
download | pdfium-2c489cc41023a40648dfde988d11b8ec2b66c7d0.tar.xz |
Merge IFWL and CFWL classes.
This CL merges the IFWL hierarchy into the CFWL hierachy. All CFWL proxy methods
have been replaced by the IFWL implementations.
Review-Url: https://codereview.chromium.org/2524173002
Diffstat (limited to 'xfa/fwl/core')
79 files changed, 7241 insertions, 8314 deletions
diff --git a/xfa/fwl/core/cfwl_app.cpp b/xfa/fwl/core/cfwl_app.cpp index 4905e2335f..fd4bb0816b 100644 --- a/xfa/fwl/core/cfwl_app.cpp +++ b/xfa/fwl/core/cfwl_app.cpp @@ -8,8 +8,8 @@ #include "third_party/base/ptr_util.h" #include "xfa/fwl/core/cfwl_notedriver.h" +#include "xfa/fwl/core/cfwl_widget.h" #include "xfa/fwl/core/cfwl_widgetmgr.h" -#include "xfa/fwl/core/ifwl_widget.h" #include "xfa/fxfa/app/xfa_fwladapter.h" CFWL_App::CFWL_App(CXFA_FFApp* pAdapter) diff --git a/xfa/fwl/core/cfwl_app.h b/xfa/fwl/core/cfwl_app.h index 28ed8a46c2..26b514aca7 100644 --- a/xfa/fwl/core/cfwl_app.h +++ b/xfa/fwl/core/cfwl_app.h @@ -15,7 +15,7 @@ class CFWL_NoteDriver; class CFWL_WidgetMgr; class CXFA_FFApp; class CXFA_FWLAdapterWidgetMgr; -class IFWL_Widget; +class CFWL_Widget; enum FWL_KeyFlag { FWL_KEYFLAG_Ctrl = 1 << 0, diff --git a/xfa/fwl/core/cfwl_barcode.cpp b/xfa/fwl/core/cfwl_barcode.cpp index 49e417ea9c..18cf71ebba 100644 --- a/xfa/fwl/core/cfwl_barcode.cpp +++ b/xfa/fwl/core/cfwl_barcode.cpp @@ -6,33 +6,93 @@ #include "xfa/fwl/core/cfwl_barcode.h" -#include <memory> #include <utility> #include "third_party/base/ptr_util.h" +#include "xfa/fgas/font/cfgas_gefont.h" +#include "xfa/fwl/core/cfwl_notedriver.h" +#include "xfa/fwl/core/cfwl_themepart.h" +#include "xfa/fwl/core/cfx_barcode.h" +#include "xfa/fwl/core/ifwl_themeprovider.h" -namespace { +CFWL_Barcode::CFWL_Barcode(const CFWL_App* app) + : CFWL_Edit(app, pdfium::MakeUnique<CFWL_WidgetProperties>(), nullptr), + m_dwStatus(0), + m_type(BC_UNKNOWN), + m_dwAttributeMask(FWL_BCDATTRIBUTE_NONE) {} + +CFWL_Barcode::~CFWL_Barcode() {} -IFWL_Barcode* ToBarcode(IFWL_Widget* widget) { - return static_cast<IFWL_Barcode*>(widget); +FWL_Type CFWL_Barcode::GetClassID() const { + return FWL_Type::Barcode; } -} // namespace +void CFWL_Barcode::Update() { + if (IsLocked()) + return; -CFWL_Barcode::CFWL_Barcode(const CFWL_App* app) - : CFWL_Edit(app), m_dwAttributeMask(FWL_BCDATTRIBUTE_NONE) {} + CFWL_Edit::Update(); + GenerateBarcodeImageCache(); +} -CFWL_Barcode::~CFWL_Barcode() {} +void CFWL_Barcode::DrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) { + if (!pGraphics) + return; + if (!m_pProperties->m_pThemeProvider) + return; + if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) { + GenerateBarcodeImageCache(); + if (!m_pBarcodeEngine || (m_dwStatus & XFA_BCS_EncodeSuccess) == 0) + return; + + CFX_Matrix mt; + mt.e = GetRTClient().left; + mt.f = GetRTClient().top; + if (pMatrix) + mt.Concat(*pMatrix); + + int32_t errorCode = 0; + m_pBarcodeEngine->RenderDevice(pGraphics->GetRenderDevice(), pMatrix, + errorCode); + return; + } + CFWL_Edit::DrawWidget(pGraphics, pMatrix); +} + +void CFWL_Barcode::SetType(BC_TYPE type) { + if (m_type == type) + return; + + m_pBarcodeEngine.reset(); + m_type = type; + m_dwStatus = XFA_BCS_NeedUpdate; +} + +void CFWL_Barcode::SetText(const CFX_WideString& wsText) { + m_pBarcodeEngine.reset(); + m_dwStatus = XFA_BCS_NeedUpdate; + CFWL_Edit::SetText(wsText); +} -void CFWL_Barcode::Initialize() { - ASSERT(!m_pIface); +bool CFWL_Barcode::IsProtectedType() const { + if (!m_pBarcodeEngine) + return true; - auto iface = pdfium::MakeUnique<IFWL_Barcode>( - m_pApp, pdfium::MakeUnique<CFWL_WidgetProperties>()); - iface->SetDataProvider(this); - m_pIface = std::move(iface); + BC_TYPE tEngineType = m_pBarcodeEngine->GetType(); + if (tEngineType == BC_QR_CODE || tEngineType == BC_PDF417 || + tEngineType == BC_DATAMATRIX) { + return true; + } + return false; +} - CFWL_Widget::Initialize(); +void CFWL_Barcode::OnProcessEvent(CFWL_Event* pEvent) { + if (pEvent->GetClassID() == CFWL_EventType::TextChanged) { + m_pBarcodeEngine.reset(); + m_dwStatus = XFA_BCS_NeedUpdate; + } + CFWL_Edit::OnProcessEvent(pEvent); } void CFWL_Barcode::SetCharEncoding(BC_CHAR_ENCODING encoding) { @@ -53,7 +113,7 @@ void CFWL_Barcode::SetModuleWidth(int32_t width) { void CFWL_Barcode::SetDataLength(int32_t dataLength) { m_dwAttributeMask |= FWL_BCDATTRIBUTE_DATALENGTH; m_nDataLength = dataLength; - ToBarcode(GetWidget())->SetLimit(dataLength); + SetLimit(dataLength); } void CFWL_Barcode::SetCalChecksum(bool calChecksum) { @@ -96,67 +156,78 @@ void CFWL_Barcode::SetTruncated(bool truncated) { m_bTruncated = truncated; } -void CFWL_Barcode::SetType(BC_TYPE type) { - if (GetWidget()) - ToBarcode(GetWidget())->SetType(type); -} - -bool CFWL_Barcode::IsProtectedType() { - return GetWidget() ? ToBarcode(GetWidget())->IsProtectedType() : false; -} - -BC_CHAR_ENCODING CFWL_Barcode::GetCharEncoding() const { - return m_eCharEncoding; -} - -int32_t CFWL_Barcode::GetModuleHeight() const { - return m_nModuleHeight; -} - -int32_t CFWL_Barcode::GetModuleWidth() const { - return m_nModuleWidth; -} - -int32_t CFWL_Barcode::GetDataLength() const { - return m_nDataLength; -} - -bool CFWL_Barcode::GetCalChecksum() const { - return m_bCalChecksum; -} - -bool CFWL_Barcode::GetPrintChecksum() const { - return m_bPrintChecksum; -} - -BC_TEXT_LOC CFWL_Barcode::GetTextLocation() const { - return m_eTextLocation; -} - -int32_t CFWL_Barcode::GetWideNarrowRatio() const { - return m_nWideNarrowRatio; -} - -FX_CHAR CFWL_Barcode::GetStartChar() const { - return m_cStartChar; -} - -FX_CHAR CFWL_Barcode::GetEndChar() const { - return m_cEndChar; -} - -int32_t CFWL_Barcode::GetVersion() const { - return 0; -} - -int32_t CFWL_Barcode::GetErrorCorrectionLevel() const { - return m_nECLevel; -} - -bool CFWL_Barcode::GetTruncated() const { - return m_bTruncated; -} - -uint32_t CFWL_Barcode::GetBarcodeAttributeMask() const { - return m_dwAttributeMask; +void CFWL_Barcode::GenerateBarcodeImageCache() { + if ((m_dwStatus & XFA_BCS_NeedUpdate) == 0) + return; + + m_dwStatus = 0; + CreateBarcodeEngine(); + if (!m_pBarcodeEngine) + return; + + CFX_WideString wsText; + GetText(wsText); + + CFWL_ThemePart part; + part.m_pWidget = this; + + IFWL_ThemeProvider* pTheme = GetAvailableTheme(); + CFGAS_GEFont* pFont = static_cast<CFGAS_GEFont*>( + pTheme->GetCapacity(&part, CFWL_WidgetCapacity::Font)); + CFX_Font* pCXFont = pFont ? pFont->GetDevFont() : nullptr; + if (pCXFont) + m_pBarcodeEngine->SetFont(pCXFont); + + FX_FLOAT* pFontSize = static_cast<FX_FLOAT*>( + pTheme->GetCapacity(&part, CFWL_WidgetCapacity::FontSize)); + if (pFontSize) + m_pBarcodeEngine->SetFontSize(*pFontSize); + + FX_ARGB* pFontColor = static_cast<FX_ARGB*>( + pTheme->GetCapacity(&part, CFWL_WidgetCapacity::TextColor)); + if (pFontColor) + m_pBarcodeEngine->SetFontColor(*pFontColor); + + m_pBarcodeEngine->SetHeight(int32_t(GetRTClient().height)); + m_pBarcodeEngine->SetWidth(int32_t(GetRTClient().width)); + if (m_dwAttributeMask & FWL_BCDATTRIBUTE_CHARENCODING) + m_pBarcodeEngine->SetCharEncoding(m_eCharEncoding); + if (m_dwAttributeMask & FWL_BCDATTRIBUTE_MODULEHEIGHT) + m_pBarcodeEngine->SetModuleHeight(m_nModuleHeight); + if (m_dwAttributeMask & FWL_BCDATTRIBUTE_MODULEWIDTH) + m_pBarcodeEngine->SetModuleWidth(m_nModuleWidth); + if (m_dwAttributeMask & FWL_BCDATTRIBUTE_DATALENGTH) + m_pBarcodeEngine->SetDataLength(m_nDataLength); + if (m_dwAttributeMask & FWL_BCDATTRIBUTE_CALCHECKSUM) + m_pBarcodeEngine->SetCalChecksum(m_bCalChecksum); + if (m_dwAttributeMask & FWL_BCDATTRIBUTE_PRINTCHECKSUM) + m_pBarcodeEngine->SetPrintChecksum(m_bPrintChecksum); + if (m_dwAttributeMask & FWL_BCDATTRIBUTE_TEXTLOCATION) + m_pBarcodeEngine->SetTextLocation(m_eTextLocation); + if (m_dwAttributeMask & FWL_BCDATTRIBUTE_WIDENARROWRATIO) + m_pBarcodeEngine->SetWideNarrowRatio(m_nWideNarrowRatio); + if (m_dwAttributeMask & FWL_BCDATTRIBUTE_STARTCHAR) + m_pBarcodeEngine->SetStartChar(m_cStartChar); + if (m_dwAttributeMask & FWL_BCDATTRIBUTE_ENDCHAR) + m_pBarcodeEngine->SetEndChar(m_cEndChar); + if (m_dwAttributeMask & FWL_BCDATTRIBUTE_VERSION) + m_pBarcodeEngine->SetVersion(0); + if (m_dwAttributeMask & FWL_BCDATTRIBUTE_ECLEVEL) + m_pBarcodeEngine->SetErrorCorrectionLevel(m_nECLevel); + if (m_dwAttributeMask & FWL_BCDATTRIBUTE_TRUNCATED) + m_pBarcodeEngine->SetTruncated(m_bTruncated); + + int32_t errorCode = 0; + m_dwStatus = m_pBarcodeEngine->Encode(wsText.AsStringC(), true, errorCode) + ? XFA_BCS_EncodeSuccess + : 0; +} + +void CFWL_Barcode::CreateBarcodeEngine() { + if (m_pBarcodeEngine || m_type == BC_UNKNOWN) + return; + + std::unique_ptr<CFX_Barcode> pBarcode(new CFX_Barcode); + if (pBarcode->Create(m_type)) + m_pBarcodeEngine = std::move(pBarcode); } diff --git a/xfa/fwl/core/cfwl_barcode.h b/xfa/fwl/core/cfwl_barcode.h index 90dfdcaebd..05c2375c7c 100644 --- a/xfa/fwl/core/cfwl_barcode.h +++ b/xfa/fwl/core/cfwl_barcode.h @@ -7,35 +7,54 @@ #ifndef XFA_FWL_CORE_CFWL_BARCODE_H_ #define XFA_FWL_CORE_CFWL_BARCODE_H_ +#include <memory> + #include "xfa/fwl/core/cfwl_edit.h" -#include "xfa/fwl/core/fwl_error.h" -#include "xfa/fwl/core/ifwl_barcode.h" +#include "xfa/fwl/core/cfwl_scrollbar.h" +#include "xfa/fwl/core/cfwl_widget.h" +#include "xfa/fxbarcode/BC_Library.h" + +class CFWL_WidgetProperties; +class CFX_Barcode; +class CFWL_Widget; + +#define XFA_BCS_NeedUpdate 0x0001 +#define XFA_BCS_EncodeSuccess 0x0002 -class CFWL_Barcode : public CFWL_Edit, public IFWL_Barcode::DataProvider { +enum FWL_BCDAttribute { + FWL_BCDATTRIBUTE_NONE = 0, + FWL_BCDATTRIBUTE_CHARENCODING = 1 << 0, + FWL_BCDATTRIBUTE_MODULEHEIGHT = 1 << 1, + FWL_BCDATTRIBUTE_MODULEWIDTH = 1 << 2, + FWL_BCDATTRIBUTE_DATALENGTH = 1 << 3, + FWL_BCDATTRIBUTE_CALCHECKSUM = 1 << 4, + FWL_BCDATTRIBUTE_PRINTCHECKSUM = 1 << 5, + FWL_BCDATTRIBUTE_TEXTLOCATION = 1 << 6, + FWL_BCDATTRIBUTE_WIDENARROWRATIO = 1 << 7, + FWL_BCDATTRIBUTE_STARTCHAR = 1 << 8, + FWL_BCDATTRIBUTE_ENDCHAR = 1 << 9, + FWL_BCDATTRIBUTE_VERSION = 1 << 10, + FWL_BCDATTRIBUTE_ECLEVEL = 1 << 11, + FWL_BCDATTRIBUTE_TRUNCATED = 1 << 12 +}; + +class CFWL_Barcode : public CFWL_Edit { public: explicit CFWL_Barcode(const CFWL_App* pApp); ~CFWL_Barcode() override; - void Initialize(); + // CFWL_Widget + FWL_Type GetClassID() const override; + void Update() override; + void DrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix = nullptr) override; + void OnProcessEvent(CFWL_Event* pEvent) override; - // IFWL_Barcode::DataProvider - BC_CHAR_ENCODING GetCharEncoding() const override; - int32_t GetModuleHeight() const override; - int32_t GetModuleWidth() const override; - int32_t GetDataLength() const override; - bool GetCalChecksum() const override; - bool GetPrintChecksum() const override; - BC_TEXT_LOC GetTextLocation() const override; - int32_t GetWideNarrowRatio() const override; - FX_CHAR GetStartChar() const override; - FX_CHAR GetEndChar() const override; - int32_t GetVersion() const override; - int32_t GetErrorCorrectionLevel() const override; - bool GetTruncated() const override; - uint32_t GetBarcodeAttributeMask() const override; + // CFWL_Edit + void SetText(const CFX_WideString& wsText) override; void SetType(BC_TYPE type); - bool IsProtectedType(); + bool IsProtectedType() const; void SetCharEncoding(BC_CHAR_ENCODING encoding); void SetModuleHeight(int32_t height); @@ -51,6 +70,12 @@ class CFWL_Barcode : public CFWL_Edit, public IFWL_Barcode::DataProvider { void SetTruncated(bool truncated); private: + void GenerateBarcodeImageCache(); + void CreateBarcodeEngine(); + + std::unique_ptr<CFX_Barcode> m_pBarcodeEngine; + uint32_t m_dwStatus; + BC_TYPE m_type; BC_CHAR_ENCODING m_eCharEncoding; int32_t m_nModuleHeight; int32_t m_nModuleWidth; diff --git a/xfa/fwl/core/cfwl_caret.cpp b/xfa/fwl/core/cfwl_caret.cpp index 97cf1e9682..b4ebf2cec8 100644 --- a/xfa/fwl/core/cfwl_caret.cpp +++ b/xfa/fwl/core/cfwl_caret.cpp @@ -23,8 +23,8 @@ const uint32_t kFrequency = 400; CFWL_Caret::CFWL_Caret(const CFWL_App* app, std::unique_ptr<CFWL_WidgetProperties> properties, - IFWL_Widget* pOuter) - : IFWL_Widget(app, std::move(properties), pOuter), + CFWL_Widget* pOuter) + : CFWL_Widget(app, std::move(properties), pOuter), m_pTimer(new CFWL_Caret::Timer(this)), m_pTimerInfo(nullptr) { SetStates(FWL_STATE_CAT_HightLight); diff --git a/xfa/fwl/core/cfwl_caret.h b/xfa/fwl/core/cfwl_caret.h index 9e68cdf09d..ad38f7a3ed 100644 --- a/xfa/fwl/core/cfwl_caret.h +++ b/xfa/fwl/core/cfwl_caret.h @@ -10,22 +10,22 @@ #include <memory> #include "xfa/fwl/core/cfwl_timer.h" -#include "xfa/fwl/core/ifwl_widget.h" +#include "xfa/fwl/core/cfwl_widget.h" #include "xfa/fxgraphics/cfx_color.h" class CFWL_WidgetProperties; -class IFWL_Widget; +class CFWL_Widget; #define FWL_STATE_CAT_HightLight 1 -class CFWL_Caret : public IFWL_Widget { +class CFWL_Caret : public CFWL_Widget { public: CFWL_Caret(const CFWL_App* app, std::unique_ptr<CFWL_WidgetProperties> properties, - IFWL_Widget* pOuter); + CFWL_Widget* pOuter); ~CFWL_Caret() override; - // IFWL_Widget + // CFWL_Widget FWL_Type GetClassID() const override; void DrawWidget(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix = nullptr) override; diff --git a/xfa/fwl/core/cfwl_checkbox.cpp b/xfa/fwl/core/cfwl_checkbox.cpp index 5053d2f934..cdd8211b60 100644 --- a/xfa/fwl/core/cfwl_checkbox.cpp +++ b/xfa/fwl/core/cfwl_checkbox.cpp @@ -6,32 +6,480 @@ #include "xfa/fwl/core/cfwl_checkbox.h" +#include <algorithm> #include <memory> #include <utility> #include "third_party/base/ptr_util.h" -#include "xfa/fwl/core/fwl_error.h" +#include "xfa/fde/tto/fde_textout.h" +#include "xfa/fwl/core/cfwl_app.h" +#include "xfa/fwl/core/cfwl_evtcheckstatechanged.h" +#include "xfa/fwl/core/cfwl_msgkey.h" +#include "xfa/fwl/core/cfwl_msgmouse.h" +#include "xfa/fwl/core/cfwl_notedriver.h" +#include "xfa/fwl/core/cfwl_themebackground.h" +#include "xfa/fwl/core/cfwl_themetext.h" +#include "xfa/fwl/core/cfwl_widgetmgr.h" +#include "xfa/fwl/core/ifwl_themeprovider.h" -CFWL_CheckBox::CFWL_CheckBox(const CFWL_App* app) - : CFWL_Widget(app), m_fBoxHeight(16.0f) {} +namespace { -CFWL_CheckBox::~CFWL_CheckBox() {} +const int kCaptionMargin = 5; -void CFWL_CheckBox::Initialize() { - ASSERT(!m_pIface); +} // namespace + +CFWL_CheckBox::CFWL_CheckBox(const CFWL_App* app) + : CFWL_Widget(app, pdfium::MakeUnique<CFWL_WidgetProperties>(), nullptr), + m_dwTTOStyles(FDE_TTOSTYLE_SingleLine), + m_iTTOAlign(FDE_TTOALIGNMENT_Center), + m_bBtnDown(false), + m_fBoxHeight(16.0f) { + m_rtClient.Reset(); + m_rtBox.Reset(); + m_rtCaption.Reset(); + m_rtFocus.Reset(); +} - auto iface = pdfium::MakeUnique<IFWL_CheckBox>( - m_pApp, pdfium::MakeUnique<CFWL_WidgetProperties>()); - iface->SetDataProvider(this); - m_pIface = std::move(iface); +CFWL_CheckBox::~CFWL_CheckBox() {} - CFWL_Widget::Initialize(); +FWL_Type CFWL_CheckBox::GetClassID() const { + return FWL_Type::CheckBox; } void CFWL_CheckBox::SetBoxSize(FX_FLOAT fHeight) { m_fBoxHeight = fHeight; } -FX_FLOAT CFWL_CheckBox::GetBoxSize(IFWL_Widget* pWidget) { - return m_fBoxHeight; +void CFWL_CheckBox::GetWidgetRect(CFX_RectF& rect, bool bAutoSize) { + if (!bAutoSize) { + rect = m_pProperties->m_rtWidget; + return; + } + + rect.Set(0, 0, 0, 0); + if (!m_pProperties->m_pThemeProvider) + m_pProperties->m_pThemeProvider = GetAvailableTheme(); + if (!m_pProperties->m_pThemeProvider) + return; + + CFX_SizeF sz = CalcTextSize( + L"Check box", m_pProperties->m_pThemeProvider, + !!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_MultiLine)); + rect.Set(0, 0, sz.x, sz.y); + rect.Inflate(kCaptionMargin, kCaptionMargin); + + rect.width += m_fBoxHeight; + rect.height = std::max(rect.height, m_fBoxHeight); + CFWL_Widget::GetWidgetRect(rect, true); +} + +void CFWL_CheckBox::Update() { + if (IsLocked()) + return; + if (!m_pProperties->m_pThemeProvider) + m_pProperties->m_pThemeProvider = GetAvailableTheme(); + + UpdateTextOutStyles(); + Layout(); +} + +void CFWL_CheckBox::DrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) { + if (!pGraphics) + return; + if (!m_pProperties->m_pThemeProvider) + return; + + IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider; + if (HasBorder()) { + DrawBorder(pGraphics, CFWL_Part::Border, m_pProperties->m_pThemeProvider, + pMatrix); + } + if (HasEdge()) + DrawEdge(pGraphics, CFWL_Part::Edge, pTheme, pMatrix); + + int32_t dwStates = GetPartStates(); + + CFWL_ThemeBackground param; + param.m_pWidget = this; + param.m_iPart = CFWL_Part::Background; + param.m_dwStates = dwStates; + param.m_pGraphics = pGraphics; + if (pMatrix) + param.m_matrix.Concat(*pMatrix); + param.m_rtPart = m_rtClient; + if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) + param.m_pData = &m_rtFocus; + pTheme->DrawBackground(¶m); + + param.m_iPart = CFWL_Part::CheckBox; + param.m_rtPart = m_rtBox; + pTheme->DrawBackground(¶m); + + CFWL_ThemeText textParam; + textParam.m_pWidget = this; + textParam.m_iPart = CFWL_Part::Caption; + textParam.m_dwStates = dwStates; + textParam.m_pGraphics = pGraphics; + if (pMatrix) + textParam.m_matrix.Concat(*pMatrix); + textParam.m_rtPart = m_rtCaption; + textParam.m_wsText = L"Check box"; + textParam.m_dwTTOStyles = m_dwTTOStyles; + textParam.m_iTTOAlign = m_iTTOAlign; + pTheme->DrawText(&textParam); +} + +void CFWL_CheckBox::SetCheckState(int32_t iCheck) { + m_pProperties->m_dwStates &= ~FWL_STATE_CKB_CheckMask; + switch (iCheck) { + case 1: + m_pProperties->m_dwStates |= FWL_STATE_CKB_Checked; + break; + case 2: + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_3State) + m_pProperties->m_dwStates |= FWL_STATE_CKB_Neutral; + break; + default: + break; + } + Repaint(&m_rtClient); +} + +void CFWL_CheckBox::Layout() { + m_pProperties->m_rtWidget.width = + FXSYS_round(m_pProperties->m_rtWidget.width); + m_pProperties->m_rtWidget.height = + FXSYS_round(m_pProperties->m_rtWidget.height); + GetClientRect(m_rtClient); + + FX_FLOAT fBoxTop = m_rtClient.top; + FX_FLOAT fClientBottom = m_rtClient.bottom(); + + switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_VLayoutMask) { + case FWL_STYLEEXT_CKB_Top: + break; + case FWL_STYLEEXT_CKB_Bottom: { + fBoxTop = fClientBottom - m_fBoxHeight; + break; + } + case FWL_STYLEEXT_CKB_VCenter: + default: { + fBoxTop = m_rtClient.top + (m_rtClient.height - m_fBoxHeight) / 2; + fBoxTop = FXSYS_floor(fBoxTop); + break; + } + } + + FX_FLOAT fBoxLeft = m_rtClient.left; + FX_FLOAT fTextLeft = 0.0; + FX_FLOAT fTextRight = 0.0; + FX_FLOAT fClientRight = m_rtClient.right(); + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_LeftText) { + fBoxLeft = fClientRight - m_fBoxHeight; + fTextLeft = m_rtClient.left; + fTextRight = fBoxLeft; + } else { + fTextLeft = fBoxLeft + m_fBoxHeight; + fTextRight = fClientRight; + } + m_rtBox.Set(fBoxLeft, fBoxTop, m_fBoxHeight, m_fBoxHeight); + m_rtCaption.Set(fTextLeft, m_rtClient.top, fTextRight - fTextLeft, + m_rtClient.height); + m_rtCaption.Inflate(-kCaptionMargin, -kCaptionMargin); + + CFX_RectF rtFocus; + rtFocus.Set(m_rtCaption.left, m_rtCaption.top, m_rtCaption.width, + m_rtCaption.height); + + CalcTextRect(L"Check box", m_pProperties->m_pThemeProvider, m_dwTTOStyles, + m_iTTOAlign, rtFocus); + if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_MultiLine) == 0) { + FX_FLOAT fWidth = std::max(m_rtCaption.width, rtFocus.width); + FX_FLOAT fHeight = std::min(m_rtCaption.height, rtFocus.height); + FX_FLOAT fLeft = m_rtCaption.left; + FX_FLOAT fTop = m_rtCaption.top; + if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_HLayoutMask) == + FWL_STYLEEXT_CKB_Center) { + fLeft = m_rtCaption.left + (m_rtCaption.width - fWidth) / 2; + } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_HLayoutMask) == + FWL_STYLEEXT_CKB_Right) { + fLeft = m_rtCaption.right() - fWidth; + } + if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_VLayoutMask) == + FWL_STYLEEXT_CKB_VCenter) { + fTop = m_rtCaption.top + (m_rtCaption.height - fHeight) / 2; + } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_VLayoutMask) == + FWL_STYLEEXT_CKB_Bottom) { + fTop = m_rtCaption.bottom() - fHeight; + } + m_rtFocus.Set(fLeft, fTop, fWidth, fHeight); + } else { + m_rtFocus.Set(rtFocus.left, rtFocus.top, rtFocus.width, rtFocus.height); + } + m_rtFocus.Inflate(1, 1); +} + +uint32_t CFWL_CheckBox::GetPartStates() const { + int32_t dwStates = CFWL_PartState_Normal; + if ((m_pProperties->m_dwStates & FWL_STATE_CKB_CheckMask) == + FWL_STATE_CKB_Neutral) { + dwStates = CFWL_PartState_Neutral; + } else if ((m_pProperties->m_dwStates & FWL_STATE_CKB_CheckMask) == + FWL_STATE_CKB_Checked) { + dwStates = CFWL_PartState_Checked; + } + if (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) + dwStates |= CFWL_PartState_Disabled; + else if (m_pProperties->m_dwStates & FWL_STATE_CKB_Hovered) + dwStates |= CFWL_PartState_Hovered; + else if (m_pProperties->m_dwStates & FWL_STATE_CKB_Pressed) + dwStates |= CFWL_PartState_Pressed; + else + dwStates |= CFWL_PartState_Normal; + if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) + dwStates |= CFWL_PartState_Focused; + return dwStates; +} + +void CFWL_CheckBox::UpdateTextOutStyles() { + switch (m_pProperties->m_dwStyleExes & + (FWL_STYLEEXT_CKB_HLayoutMask | FWL_STYLEEXT_CKB_VLayoutMask)) { + case FWL_STYLEEXT_CKB_Left | FWL_STYLEEXT_CKB_Top: { + m_iTTOAlign = FDE_TTOALIGNMENT_TopLeft; + break; + } + case FWL_STYLEEXT_CKB_Center | FWL_STYLEEXT_CKB_Top: { + m_iTTOAlign = FDE_TTOALIGNMENT_TopCenter; + break; + } + case FWL_STYLEEXT_CKB_Right | FWL_STYLEEXT_CKB_Top: { + m_iTTOAlign = FDE_TTOALIGNMENT_TopRight; + break; + } + case FWL_STYLEEXT_CKB_Left | FWL_STYLEEXT_CKB_VCenter: { + m_iTTOAlign = FDE_TTOALIGNMENT_CenterLeft; + break; + } + case FWL_STYLEEXT_CKB_Right | FWL_STYLEEXT_CKB_VCenter: { + m_iTTOAlign = FDE_TTOALIGNMENT_CenterRight; + break; + } + case FWL_STYLEEXT_CKB_Left | FWL_STYLEEXT_CKB_Bottom: { + m_iTTOAlign = FDE_TTOALIGNMENT_BottomLeft; + break; + } + case FWL_STYLEEXT_CKB_Center | FWL_STYLEEXT_CKB_Bottom: { + m_iTTOAlign = FDE_TTOALIGNMENT_BottomCenter; + break; + } + case FWL_STYLEEXT_CKB_Right | FWL_STYLEEXT_CKB_Bottom: { + m_iTTOAlign = FDE_TTOALIGNMENT_BottomRight; + break; + } + case FWL_STYLEEXT_CKB_Center | FWL_STYLEEXT_CKB_VCenter: + default: { + m_iTTOAlign = FDE_TTOALIGNMENT_Center; + break; + } + } + m_dwTTOStyles = 0; + if (m_pProperties->m_dwStyleExes & FWL_WGTSTYLE_RTLReading) + m_dwTTOStyles |= FDE_TTOSTYLE_RTL; + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_MultiLine) + m_dwTTOStyles |= FDE_TTOSTYLE_LineWrap; + else + m_dwTTOStyles |= FDE_TTOSTYLE_SingleLine; +} + +void CFWL_CheckBox::NextStates() { + uint32_t dwFirststate = m_pProperties->m_dwStates; + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_RadioButton) { + if ((m_pProperties->m_dwStates & FWL_STATE_CKB_CheckMask) == + FWL_STATE_CKB_Unchecked) { + CFWL_WidgetMgr* pWidgetMgr = GetOwnerApp()->GetWidgetMgr(); + if (!pWidgetMgr->IsFormDisabled()) { + CFX_ArrayTemplate<CFWL_Widget*> radioarr; + pWidgetMgr->GetSameGroupRadioButton(this, radioarr); + CFWL_CheckBox* pCheckBox = nullptr; + int32_t iCount = radioarr.GetSize(); + for (int32_t i = 0; i < iCount; i++) { + pCheckBox = static_cast<CFWL_CheckBox*>(radioarr[i]); + if (pCheckBox != this && + pCheckBox->GetStates() & FWL_STATE_CKB_Checked) { + pCheckBox->SetCheckState(0); + CFX_RectF rt; + pCheckBox->GetWidgetRect(rt); + rt.left = rt.top = 0; + m_pWidgetMgr->RepaintWidget(pCheckBox, &rt); + break; + } + } + } + m_pProperties->m_dwStates |= FWL_STATE_CKB_Checked; + } + } else { + if ((m_pProperties->m_dwStates & FWL_STATE_CKB_CheckMask) == + FWL_STATE_CKB_Neutral) { + m_pProperties->m_dwStates &= ~FWL_STATE_CKB_CheckMask; + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_3State) + m_pProperties->m_dwStates |= FWL_STATE_CKB_Checked; + } else if ((m_pProperties->m_dwStates & FWL_STATE_CKB_CheckMask) == + FWL_STATE_CKB_Checked) { + m_pProperties->m_dwStates &= ~FWL_STATE_CKB_CheckMask; + } else { + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_3State) + m_pProperties->m_dwStates |= FWL_STATE_CKB_Neutral; + else + m_pProperties->m_dwStates |= FWL_STATE_CKB_Checked; + } + } + + Repaint(&m_rtClient); + if (dwFirststate == m_pProperties->m_dwStates) + return; + + CFWL_EvtCheckStateChanged wmCheckBoxState; + wmCheckBoxState.m_pSrcTarget = this; + DispatchEvent(&wmCheckBoxState); +} + +void CFWL_CheckBox::OnProcessMessage(CFWL_Message* pMessage) { + if (!pMessage) + return; + + switch (pMessage->GetClassID()) { + case CFWL_MessageType::SetFocus: + OnFocusChanged(true); + break; + case CFWL_MessageType::KillFocus: + OnFocusChanged(false); + break; + case CFWL_MessageType::Mouse: { + CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage); + switch (pMsg->m_dwCmd) { + case FWL_MouseCommand::LeftButtonDown: + OnLButtonDown(); + break; + case FWL_MouseCommand::LeftButtonUp: + OnLButtonUp(pMsg); + break; + case FWL_MouseCommand::Move: + OnMouseMove(pMsg); + break; + case FWL_MouseCommand::Leave: + OnMouseLeave(); + break; + default: + break; + } + break; + } + case CFWL_MessageType::Key: { + CFWL_MsgKey* pKey = static_cast<CFWL_MsgKey*>(pMessage); + if (pKey->m_dwCmd == FWL_KeyCommand::KeyDown) + OnKeyDown(pKey); + break; + } + default: + break; + } + + CFWL_Widget::OnProcessMessage(pMessage); +} + +void CFWL_CheckBox::OnDrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) { + DrawWidget(pGraphics, pMatrix); +} + +void CFWL_CheckBox::OnFocusChanged(bool bSet) { + if (bSet) + m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused; + else + m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused; + + Repaint(&m_rtClient); +} + +void CFWL_CheckBox::OnLButtonDown() { + if (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) + return; + if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) + SetFocus(true); + + m_bBtnDown = true; + m_pProperties->m_dwStates &= ~FWL_STATE_CKB_Hovered; + m_pProperties->m_dwStates |= FWL_STATE_CKB_Pressed; + Repaint(&m_rtClient); +} + +void CFWL_CheckBox::OnLButtonUp(CFWL_MsgMouse* pMsg) { + if (!m_bBtnDown) + return; + + m_bBtnDown = false; + if (!m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) + return; + + m_pProperties->m_dwStates |= FWL_STATE_CKB_Hovered; + m_pProperties->m_dwStates &= ~FWL_STATE_CKB_Pressed; + NextStates(); +} + +void CFWL_CheckBox::OnMouseMove(CFWL_MsgMouse* pMsg) { + if (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) + return; + + bool bRepaint = false; + if (m_bBtnDown) { + if (m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) { + if ((m_pProperties->m_dwStates & FWL_STATE_CKB_Pressed) == 0) { + bRepaint = true; + m_pProperties->m_dwStates |= FWL_STATE_CKB_Pressed; + } + if ((m_pProperties->m_dwStates & FWL_STATE_CKB_Hovered)) { + bRepaint = true; + m_pProperties->m_dwStates &= ~FWL_STATE_CKB_Hovered; + } + } else { + if (m_pProperties->m_dwStates & FWL_STATE_CKB_Pressed) { + bRepaint = true; + m_pProperties->m_dwStates &= ~FWL_STATE_CKB_Pressed; + } + if ((m_pProperties->m_dwStates & FWL_STATE_CKB_Hovered) == 0) { + bRepaint = true; + m_pProperties->m_dwStates |= FWL_STATE_CKB_Hovered; + } + } + } else { + if (m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) { + if ((m_pProperties->m_dwStates & FWL_STATE_CKB_Hovered) == 0) { + bRepaint = true; + m_pProperties->m_dwStates |= FWL_STATE_CKB_Hovered; + } + } + } + if (bRepaint) + Repaint(&m_rtBox); +} + +void CFWL_CheckBox::OnMouseLeave() { + if (m_bBtnDown) + m_pProperties->m_dwStates |= FWL_STATE_CKB_Hovered; + else + m_pProperties->m_dwStates &= ~FWL_STATE_CKB_Hovered; + + Repaint(&m_rtBox); +} + +void CFWL_CheckBox::OnKeyDown(CFWL_MsgKey* pMsg) { + if (pMsg->m_dwKeyCode == FWL_VKEY_Tab) { + DispatchKeyEvent(pMsg); + return; + } + if (pMsg->m_dwKeyCode == FWL_VKEY_Return || + pMsg->m_dwKeyCode == FWL_VKEY_Space) { + NextStates(); + } } diff --git a/xfa/fwl/core/cfwl_checkbox.h b/xfa/fwl/core/cfwl_checkbox.h index dd1db68b32..71497a3fe4 100644 --- a/xfa/fwl/core/cfwl_checkbox.h +++ b/xfa/fwl/core/cfwl_checkbox.h @@ -7,22 +7,85 @@ #ifndef XFA_FWL_CORE_CFWL_CHECKBOX_H_ #define XFA_FWL_CORE_CFWL_CHECKBOX_H_ +#include <memory> + +#include "xfa/fwl/core/cfwl_event.h" #include "xfa/fwl/core/cfwl_widget.h" -#include "xfa/fwl/core/ifwl_checkbox.h" +#include "xfa/fwl/core/cfwl_widgetproperties.h" + +#define FWL_STYLEEXT_CKB_Left (0L << 0) +#define FWL_STYLEEXT_CKB_Center (1L << 0) +#define FWL_STYLEEXT_CKB_Right (2L << 0) +#define FWL_STYLEEXT_CKB_Top (0L << 2) +#define FWL_STYLEEXT_CKB_VCenter (1L << 2) +#define FWL_STYLEEXT_CKB_Bottom (2L << 2) +#define FWL_STYLEEXT_CKB_LeftText (1L << 4) +#define FWL_STYLEEXT_CKB_MultiLine (1L << 5) +#define FWL_STYLEEXT_CKB_3State (1L << 6) +#define FWL_STYLEEXT_CKB_RadioButton (1L << 7) +#define FWL_STYLEEXT_CKB_ShapeSolidSquare (0L << 8) +#define FWL_STYLEEXT_CKB_ShapeSunkenSquare (1L << 8) +#define FWL_STYLEEXT_CKB_ShapeSolidCircle (2L << 8) +#define FWL_STYLEEXT_CKB_ShapeSunkenCircle (3L << 8) +#define FWL_STYLEEXT_CKB_SignShapeCheck (0L << 10) +#define FWL_STYLEEXT_CKB_SignShapeCircle (1L << 10) +#define FWL_STYLEEXT_CKB_SignShapeCross (2L << 10) +#define FWL_STYLEEXT_CKB_SignShapeDiamond (3L << 10) +#define FWL_STYLEEXT_CKB_SignShapeSquare (4L << 10) +#define FWL_STYLEEXT_CKB_SignShapeStar (5L << 10) +#define FWL_STYLEEXT_CKB_HLayoutMask (3L << 0) +#define FWL_STYLEEXT_CKB_VLayoutMask (3L << 2) +#define FWL_STYLEEXT_CKB_ShapeMask (3L << 8) +#define FWL_STYLEEXT_CKB_SignShapeMask (7L << 10) +#define FWL_STATE_CKB_Hovered (1 << FWL_WGTSTATE_MAX) +#define FWL_STATE_CKB_Pressed (1 << (FWL_WGTSTATE_MAX + 1)) +#define FWL_STATE_CKB_Unchecked (0 << (FWL_WGTSTATE_MAX + 2)) +#define FWL_STATE_CKB_Checked (1 << (FWL_WGTSTATE_MAX + 2)) +#define FWL_STATE_CKB_Neutral (2 << (FWL_WGTSTATE_MAX + 2)) +#define FWL_STATE_CKB_CheckMask (3L << (FWL_WGTSTATE_MAX + 2)) -class CFWL_CheckBox : public CFWL_Widget, public IFWL_CheckBox::DataProvider { +class CFWL_MsgMouse; +class CFWL_WidgetProperties; +class CFWL_Widget; + +class CFWL_CheckBox : public CFWL_Widget { public: explicit CFWL_CheckBox(const CFWL_App* pApp); ~CFWL_CheckBox() override; - void Initialize(); + // CFWL_Widget + FWL_Type GetClassID() const override; + void GetWidgetRect(CFX_RectF& rect, bool bAutoSize = false) override; + void Update() override; + void DrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix = nullptr) override; - // IFWL_CheckBox::DataProvider - FX_FLOAT GetBoxSize(IFWL_Widget* pWidget) override; + void OnProcessMessage(CFWL_Message* pMessage) override; + void OnDrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) override; void SetBoxSize(FX_FLOAT fHeight); private: + void SetCheckState(int32_t iCheck); + void Layout(); + uint32_t GetPartStates() const; + void UpdateTextOutStyles(); + void NextStates(); + void OnFocusChanged(bool bSet); + void OnLButtonDown(); + void OnLButtonUp(CFWL_MsgMouse* pMsg); + void OnMouseMove(CFWL_MsgMouse* pMsg); + void OnMouseLeave(); + void OnKeyDown(CFWL_MsgKey* pMsg); + + CFX_RectF m_rtClient; + CFX_RectF m_rtBox; + CFX_RectF m_rtCaption; + CFX_RectF m_rtFocus; + uint32_t m_dwTTOStyles; + int32_t m_iTTOAlign; + bool m_bBtnDown; FX_FLOAT m_fBoxHeight; }; diff --git a/xfa/fwl/core/cfwl_combobox.cpp b/xfa/fwl/core/cfwl_combobox.cpp index 532f49fdd2..b7be67d1bd 100644 --- a/xfa/fwl/core/cfwl_combobox.cpp +++ b/xfa/fwl/core/cfwl_combobox.cpp @@ -6,144 +6,1124 @@ #include "xfa/fwl/core/cfwl_combobox.h" +#include <algorithm> +#include <memory> #include <utility> #include "third_party/base/ptr_util.h" -#include "xfa/fwl/core/fwl_error.h" -#include "xfa/fwl/core/ifwl_combobox.h" -#include "xfa/fwl/core/ifwl_widget.h" +#include "xfa/fde/cfde_txtedtengine.h" +#include "xfa/fde/tto/fde_textout.h" +#include "xfa/fwl/core/cfwl_app.h" +#include "xfa/fwl/core/cfwl_evteditchanged.h" +#include "xfa/fwl/core/cfwl_evtpostdropdown.h" +#include "xfa/fwl/core/cfwl_evtpredropdown.h" +#include "xfa/fwl/core/cfwl_evtselectchanged.h" +#include "xfa/fwl/core/cfwl_evttextchanged.h" +#include "xfa/fwl/core/cfwl_formproxy.h" +#include "xfa/fwl/core/cfwl_listbox.h" +#include "xfa/fwl/core/cfwl_msgkey.h" +#include "xfa/fwl/core/cfwl_msgkillfocus.h" +#include "xfa/fwl/core/cfwl_msgmouse.h" +#include "xfa/fwl/core/cfwl_msgsetfocus.h" +#include "xfa/fwl/core/cfwl_notedriver.h" +#include "xfa/fwl/core/cfwl_themebackground.h" +#include "xfa/fwl/core/cfwl_themepart.h" +#include "xfa/fwl/core/cfwl_themetext.h" +#include "xfa/fwl/core/cfwl_widgetmgr.h" +#include "xfa/fwl/core/ifwl_themeprovider.h" -namespace { +CFWL_ComboBox::CFWL_ComboBox(const CFWL_App* app) + : CFWL_Widget(app, pdfium::MakeUnique<CFWL_WidgetProperties>(), nullptr), + m_pComboBoxProxy(nullptr), + m_bLButtonDown(false), + m_iCurSel(-1), + m_iBtnState(CFWL_PartState_Normal), + m_fComboFormHandler(0) { + m_rtClient.Reset(); + m_rtBtn.Reset(); + m_rtHandler.Reset(); -IFWL_ComboBox* ToComboBox(IFWL_Widget* widget) { - return static_cast<IFWL_ComboBox*>(widget); -} + if (m_pWidgetMgr->IsFormDisabled()) { + DisForm_InitComboList(); + DisForm_InitComboEdit(); + return; + } + + auto prop = pdfium::MakeUnique<CFWL_WidgetProperties>(); + prop->m_pThemeProvider = m_pProperties->m_pThemeProvider; + prop->m_dwStyles |= FWL_WGTSTYLE_Border | FWL_WGTSTYLE_VScroll; + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_ListItemIconText) + prop->m_dwStyleExes |= FWL_STYLEEXT_LTB_Icon; + m_pListBox = + pdfium::MakeUnique<CFWL_ComboList>(m_pOwnerApp, std::move(prop), this); -} // namespace + if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_DropDown) && !m_pEdit) { + m_pEdit.reset(new CFWL_ComboEdit( + m_pOwnerApp, pdfium::MakeUnique<CFWL_WidgetProperties>(), this)); + m_pEdit->SetOuter(this); + } + if (m_pEdit) + m_pEdit->SetParent(this); -CFWL_ComboBox::CFWL_ComboBox(const CFWL_App* app) : CFWL_Widget(app) {} + SetStates(m_pProperties->m_dwStates); +} CFWL_ComboBox::~CFWL_ComboBox() {} -void CFWL_ComboBox::Initialize() { - ASSERT(!m_pIface); +FWL_Type CFWL_ComboBox::GetClassID() const { + return FWL_Type::ComboBox; +} - m_pIface = pdfium::MakeUnique<IFWL_ComboBox>( - m_pApp, pdfium::MakeUnique<CFWL_WidgetProperties>()); +void CFWL_ComboBox::GetWidgetRect(CFX_RectF& rect, bool bAutoSize) { + if (!bAutoSize) { + rect = m_pProperties->m_rtWidget; + return; + } + + rect.Reset(); + if (IsDropDownStyle() && m_pEdit) { + m_pEdit->GetWidgetRect(rect, true); + } else { + rect.width = 100; + rect.height = 16; + } + if (!m_pProperties->m_pThemeProvider) + ResetTheme(); - CFWL_Widget::Initialize(); + FX_FLOAT* pFWidth = static_cast<FX_FLOAT*>( + GetThemeCapacity(CFWL_WidgetCapacity::ScrollBarWidth)); + if (!pFWidth) + return; + + rect.Inflate(0, 0, *pFWidth, 0); + CFWL_Widget::GetWidgetRect(rect, true); } void CFWL_ComboBox::AddString(const CFX_WideStringC& wsText) { - if (GetWidget()) - ToComboBox(GetWidget())->AddString(wsText); + m_pListBox->AddString(wsText); } bool CFWL_ComboBox::RemoveAt(int32_t iIndex) { - return GetWidget() && ToComboBox(GetWidget())->RemoveAt(iIndex); + return m_pListBox->RemoveAt(iIndex); } void CFWL_ComboBox::RemoveAll() { - if (GetWidget()) - ToComboBox(GetWidget())->RemoveAll(); + m_pListBox->DeleteAll(); } -void CFWL_ComboBox::GetTextByIndex(int32_t iIndex, - CFX_WideString& wsText) const { - if (!GetWidget()) +void CFWL_ComboBox::ModifyStylesEx(uint32_t dwStylesExAdded, + uint32_t dwStylesExRemoved) { + if (m_pWidgetMgr->IsFormDisabled()) { + DisForm_ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved); + return; + } + + bool bAddDropDown = !!(dwStylesExAdded & FWL_STYLEEXT_CMB_DropDown); + bool bRemoveDropDown = !!(dwStylesExRemoved & FWL_STYLEEXT_CMB_DropDown); + if (bAddDropDown && !m_pEdit) { + m_pEdit = pdfium::MakeUnique<CFWL_ComboEdit>( + m_pOwnerApp, pdfium::MakeUnique<CFWL_WidgetProperties>(), nullptr); + m_pEdit->SetOuter(this); + m_pEdit->SetParent(this); + } else if (bRemoveDropDown && m_pEdit) { + m_pEdit->SetStates(FWL_WGTSTATE_Invisible, true); + } + CFWL_Widget::ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved); +} + +void CFWL_ComboBox::Update() { + if (m_pWidgetMgr->IsFormDisabled()) { + DisForm_Update(); + return; + } + if (IsLocked()) + return; + + ResetTheme(); + if (IsDropDownStyle() && m_pEdit) + ResetEditAlignment(); + if (!m_pProperties->m_pThemeProvider) + m_pProperties->m_pThemeProvider = GetAvailableTheme(); + + Layout(); + CFWL_ThemePart part; + part.m_pWidget = this; + m_fComboFormHandler = + *static_cast<FX_FLOAT*>(m_pProperties->m_pThemeProvider->GetCapacity( + &part, CFWL_WidgetCapacity::ComboFormHandler)); +} + +FWL_WidgetHit CFWL_ComboBox::HitTest(FX_FLOAT fx, FX_FLOAT fy) { + if (m_pWidgetMgr->IsFormDisabled()) + return DisForm_HitTest(fx, fy); + return CFWL_Widget::HitTest(fx, fy); +} + +void CFWL_ComboBox::DrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) { + if (m_pWidgetMgr->IsFormDisabled()) { + DisForm_DrawWidget(pGraphics, pMatrix); + return; + } + + if (!pGraphics) return; - ToComboBox(GetWidget())->GetTextByIndex(iIndex, wsText); + if (!m_pProperties->m_pThemeProvider) + return; + + 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 (!IsDropDownStyle()) { + CFX_RectF rtTextBk(m_rtClient); + rtTextBk.width -= m_rtBtn.width; + + CFWL_ThemeBackground param; + param.m_pWidget = this; + param.m_iPart = CFWL_Part::Background; + param.m_pGraphics = pGraphics; + if (pMatrix) + param.m_matrix.Concat(*pMatrix); + param.m_rtPart = rtTextBk; + + if (m_iCurSel >= 0) { + if (void* p = m_pListBox->GetItemData( + m_pListBox.get(), + m_pListBox->GetItem(m_pListBox.get(), m_iCurSel))) { + param.m_pData = p; + } + } + + if (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) { + param.m_dwStates = CFWL_PartState_Disabled; + } else if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) && + (m_iCurSel >= 0)) { + param.m_dwStates = CFWL_PartState_Selected; + } else { + param.m_dwStates = CFWL_PartState_Normal; + } + pTheme->DrawBackground(¶m); + + if (m_iCurSel >= 0) { + if (!m_pListBox) + return; + + CFX_WideString wsText; + CFWL_ListItem* hItem = m_pListBox->GetItem(this, m_iCurSel); + m_pListBox->GetDataProviderItemText(hItem, wsText); + + CFWL_ThemeText theme_text; + theme_text.m_pWidget = this; + theme_text.m_iPart = CFWL_Part::Caption; + theme_text.m_dwStates = m_iBtnState; + theme_text.m_pGraphics = pGraphics; + theme_text.m_matrix.Concat(*pMatrix); + theme_text.m_rtPart = rtTextBk; + theme_text.m_dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) + ? CFWL_PartState_Selected + : CFWL_PartState_Normal; + theme_text.m_wsText = wsText; + theme_text.m_dwTTOStyles = FDE_TTOSTYLE_SingleLine; + theme_text.m_iTTOAlign = FDE_TTOALIGNMENT_CenterLeft; + pTheme->DrawText(&theme_text); + } + } + + CFWL_ThemeBackground param; + param.m_pWidget = this; + param.m_iPart = CFWL_Part::DropDownButton; + param.m_dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) + ? CFWL_PartState_Disabled + : m_iBtnState; + param.m_pGraphics = pGraphics; + param.m_matrix.Concat(*pMatrix); + param.m_rtPart = m_rtBtn; + pTheme->DrawBackground(¶m); } -int32_t CFWL_ComboBox::GetCurSel() const { - return GetWidget() ? ToComboBox(GetWidget())->GetCurSel() : -1; +void CFWL_ComboBox::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) { + if (!pThemeProvider) + return; + + m_pProperties->m_pThemeProvider = pThemeProvider; + if (m_pListBox) + m_pListBox->SetThemeProvider(pThemeProvider); + if (m_pEdit) + m_pEdit->SetThemeProvider(pThemeProvider); +} + +void CFWL_ComboBox::GetTextByIndex(int32_t iIndex, + CFX_WideString& wsText) const { + CFWL_ListItem* pItem = static_cast<CFWL_ListItem*>( + m_pListBox->GetItem(m_pListBox.get(), iIndex)); + if (pItem) + wsText = pItem->m_wsText; } void CFWL_ComboBox::SetCurSel(int32_t iSel) { - if (GetWidget()) - ToComboBox(GetWidget())->SetCurSel(iSel); + int32_t iCount = m_pListBox->CountItems(nullptr); + bool bClearSel = iSel < 0 || iSel >= iCount; + if (IsDropDownStyle() && m_pEdit) { + if (bClearSel) { + m_pEdit->SetText(CFX_WideString()); + } else { + CFX_WideString wsText; + CFWL_ListItem* hItem = m_pListBox->GetItem(this, iSel); + m_pListBox->GetDataProviderItemText(hItem, wsText); + m_pEdit->SetText(wsText); + } + m_pEdit->Update(); + } + m_iCurSel = bClearSel ? -1 : iSel; +} + +void CFWL_ComboBox::SetStates(uint32_t dwStates, bool bSet) { + if (IsDropDownStyle() && m_pEdit) + m_pEdit->SetStates(dwStates, bSet); + if (m_pListBox) + m_pListBox->SetStates(dwStates, bSet); + CFWL_Widget::SetStates(dwStates, bSet); } void CFWL_ComboBox::SetEditText(const CFX_WideString& wsText) { - if (GetWidget()) - ToComboBox(GetWidget())->SetEditText(wsText); + if (!m_pEdit) + return; + + m_pEdit->SetText(wsText); + m_pEdit->Update(); } void CFWL_ComboBox::GetEditText(CFX_WideString& wsText, int32_t nStart, int32_t nCount) const { - if (GetWidget()) - ToComboBox(GetWidget())->GetEditText(wsText, nStart, nCount); + if (m_pEdit) { + m_pEdit->GetText(wsText, nStart, nCount); + return; + } + if (!m_pListBox) + return; + + CFWL_ListItem* hItem = m_pListBox->GetItem(this, m_iCurSel); + m_pListBox->GetDataProviderItemText(hItem, wsText); } void CFWL_ComboBox::OpenDropDownList(bool bActivate) { - ToComboBox(GetWidget())->OpenDropDownList(bActivate); + ShowDropList(bActivate); } -bool CFWL_ComboBox::EditCanUndo() { - return GetWidget() ? ToComboBox(GetWidget())->EditCanUndo() : false; +void CFWL_ComboBox::GetBBox(CFX_RectF& rect) const { + if (m_pWidgetMgr->IsFormDisabled()) { + DisForm_GetBBox(rect); + return; + } + + rect = m_pProperties->m_rtWidget; + if (!m_pListBox || !IsDropListVisible()) + return; + + CFX_RectF rtList; + m_pListBox->GetWidgetRect(rtList); + rtList.Offset(rect.left, rect.top); + rect.Union(rtList); } -bool CFWL_ComboBox::EditCanRedo() { - return GetWidget() ? ToComboBox(GetWidget())->EditCanRedo() : false; +void CFWL_ComboBox::EditModifyStylesEx(uint32_t dwStylesExAdded, + uint32_t dwStylesExRemoved) { + if (m_pEdit) + m_pEdit->ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved); } -bool CFWL_ComboBox::EditUndo() { - return GetWidget() ? ToComboBox(GetWidget())->EditUndo() : false; +void CFWL_ComboBox::DrawStretchHandler(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) { + CFWL_ThemeBackground param; + param.m_pGraphics = pGraphics; + param.m_iPart = CFWL_Part::StretchHandler; + param.m_dwStates = CFWL_PartState_Normal; + param.m_pWidget = this; + if (pMatrix) + param.m_matrix.Concat(*pMatrix); + param.m_rtPart = m_rtHandler; + m_pProperties->m_pThemeProvider->DrawBackground(¶m); } -bool CFWL_ComboBox::EditRedo() { - return GetWidget() ? ToComboBox(GetWidget())->EditRedo() : false; +void CFWL_ComboBox::ShowDropList(bool bActivate) { + if (m_pWidgetMgr->IsFormDisabled()) + return DisForm_ShowDropList(bActivate); + if (IsDropListVisible() == bActivate) + return; + if (!m_pComboBoxProxy) + InitProxyForm(); + + m_pComboBoxProxy->Reset(); + if (!bActivate) { + m_pComboBoxProxy->EndDoModal(); + + m_bLButtonDown = false; + m_pListBox->SetNotifyOwner(true); + SetFocus(true); + return; + } + + m_pListBox->ChangeSelected(m_iCurSel); + ResetListItemAlignment(); + + uint32_t dwStyleAdd = m_pProperties->m_dwStyleExes & + (FWL_STYLEEXT_CMB_Sort | FWL_STYLEEXT_CMB_OwnerDraw); + m_pListBox->ModifyStylesEx(dwStyleAdd, 0); + m_pListBox->GetWidgetRect(m_rtList, true); + + CFX_RectF rtAnchor; + rtAnchor.Set(0, 0, m_pProperties->m_rtWidget.width, + m_pProperties->m_rtWidget.height); + + m_rtList.width = std::max(m_rtList.width, m_rtClient.width); + m_rtProxy = m_rtList; + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_ListDrag) + m_rtProxy.height += m_fComboFormHandler; + + GetPopupPos(0, m_rtProxy.height, rtAnchor, m_rtProxy); + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_ListDrag) { + FX_FLOAT fx = 0; + FX_FLOAT fy = m_rtClient.top + m_rtClient.height / 2; + TransformTo(nullptr, fx, fy); + + m_bUpFormHandler = fy > m_rtProxy.top; + if (m_bUpFormHandler) { + m_rtHandler.Set(0, 0, m_rtList.width, m_fComboFormHandler); + m_rtList.top = m_fComboFormHandler; + } else { + m_rtHandler.Set(0, m_rtList.height, m_rtList.width, m_fComboFormHandler); + } + } + m_pComboBoxProxy->SetWidgetRect(m_rtProxy); + m_pComboBoxProxy->Update(); + m_pListBox->SetWidgetRect(m_rtList); + m_pListBox->Update(); + + CFWL_EvtPreDropDown ev; + ev.m_pSrcTarget = this; + DispatchEvent(&ev); + + m_fItemHeight = m_pListBox->GetItemHeight(); + m_pListBox->SetFocus(true); + m_pComboBoxProxy->DoModal(); + m_pListBox->SetFocus(false); } -bool CFWL_ComboBox::EditCanCopy() { - return GetWidget() ? ToComboBox(GetWidget())->EditCanCopy() : false; +void CFWL_ComboBox::MatchEditText() { + CFX_WideString wsText; + m_pEdit->GetText(wsText); + int32_t iMatch = m_pListBox->MatchItem(wsText); + if (iMatch != m_iCurSel) { + m_pListBox->ChangeSelected(iMatch); + if (iMatch >= 0) + SyncEditText(iMatch); + } else if (iMatch >= 0) { + m_pEdit->SetSelected(); + } + m_iCurSel = iMatch; } -bool CFWL_ComboBox::EditCanCut() { - return GetWidget() ? ToComboBox(GetWidget())->EditCanCut() : false; +void CFWL_ComboBox::SyncEditText(int32_t iListItem) { + CFX_WideString wsText; + CFWL_ListItem* hItem = m_pListBox->GetItem(this, iListItem); + m_pListBox->GetDataProviderItemText(hItem, wsText); + m_pEdit->SetText(wsText); + m_pEdit->Update(); + m_pEdit->SetSelected(); } -bool CFWL_ComboBox::EditCanSelectAll() { - return GetWidget() ? ToComboBox(GetWidget())->EditCanSelectAll() : false; +void CFWL_ComboBox::Layout() { + if (m_pWidgetMgr->IsFormDisabled()) + return DisForm_Layout(); + + GetClientRect(m_rtClient); + FX_FLOAT* pFWidth = static_cast<FX_FLOAT*>( + GetThemeCapacity(CFWL_WidgetCapacity::ScrollBarWidth)); + if (!pFWidth) + return; + + FX_FLOAT fBtn = *pFWidth; + m_rtBtn.Set(m_rtClient.right() - fBtn, m_rtClient.top, fBtn, + m_rtClient.height); + if (!IsDropDownStyle() || !m_pEdit) + return; + + CFX_RectF rtEdit; + rtEdit.Set(m_rtClient.left, m_rtClient.top, m_rtClient.width - fBtn, + m_rtClient.height); + m_pEdit->SetWidgetRect(rtEdit); + + if (m_iCurSel >= 0) { + CFX_WideString wsText; + CFWL_ListItem* hItem = m_pListBox->GetItem(this, m_iCurSel); + m_pListBox->GetDataProviderItemText(hItem, wsText); + m_pEdit->LockUpdate(); + m_pEdit->SetText(wsText); + m_pEdit->UnlockUpdate(); + } + m_pEdit->Update(); } -bool CFWL_ComboBox::EditCopy(CFX_WideString& wsCopy) { - return GetWidget() ? ToComboBox(GetWidget())->EditCopy(wsCopy) : false; +void CFWL_ComboBox::ResetTheme() { + IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider; + if (!pTheme) { + pTheme = GetAvailableTheme(); + m_pProperties->m_pThemeProvider = pTheme; + } + if (m_pListBox && !m_pListBox->GetThemeProvider()) + m_pListBox->SetThemeProvider(pTheme); + if (m_pEdit && !m_pEdit->GetThemeProvider()) + m_pEdit->SetThemeProvider(pTheme); } -bool CFWL_ComboBox::EditCut(CFX_WideString& wsCut) { - return GetWidget() ? ToComboBox(GetWidget())->EditCut(wsCut) : false; +void CFWL_ComboBox::ResetEditAlignment() { + if (!m_pEdit) + return; + + uint32_t dwAdd = 0; + switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_EditHAlignMask) { + case FWL_STYLEEXT_CMB_EditHCenter: { + dwAdd |= FWL_STYLEEXT_EDT_HCenter; + break; + } + case FWL_STYLEEXT_CMB_EditHFar: { + dwAdd |= FWL_STYLEEXT_EDT_HFar; + break; + } + default: { dwAdd |= FWL_STYLEEXT_EDT_HNear; } + } + switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_EditVAlignMask) { + case FWL_STYLEEXT_CMB_EditVCenter: { + dwAdd |= FWL_STYLEEXT_EDT_VCenter; + break; + } + case FWL_STYLEEXT_CMB_EditVFar: { + dwAdd |= FWL_STYLEEXT_EDT_VFar; + break; + } + default: { + dwAdd |= FWL_STYLEEXT_EDT_VNear; + break; + } + } + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_EditJustified) + dwAdd |= FWL_STYLEEXT_EDT_Justified; + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_EditDistributed) + dwAdd |= FWL_STYLEEXT_EDT_Distributed; + + m_pEdit->ModifyStylesEx(dwAdd, FWL_STYLEEXT_EDT_HAlignMask | + FWL_STYLEEXT_EDT_HAlignModeMask | + FWL_STYLEEXT_EDT_VAlignMask); } -bool CFWL_ComboBox::EditPaste(const CFX_WideString& wsPaste) { - return GetWidget() ? ToComboBox(GetWidget())->EditPaste(wsPaste) : false; +void CFWL_ComboBox::ResetListItemAlignment() { + if (!m_pListBox) + return; + + uint32_t dwAdd = 0; + switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_ListItemAlignMask) { + case FWL_STYLEEXT_CMB_ListItemCenterAlign: { + dwAdd |= FWL_STYLEEXT_LTB_CenterAlign; + break; + } + case FWL_STYLEEXT_CMB_ListItemRightAlign: { + dwAdd |= FWL_STYLEEXT_LTB_RightAlign; + break; + } + default: { + dwAdd |= FWL_STYLEEXT_LTB_LeftAlign; + break; + } + } + m_pListBox->ModifyStylesEx(dwAdd, FWL_STYLEEXT_CMB_ListItemAlignMask); } -void CFWL_ComboBox::EditSelectAll() { - if (GetWidget()) - ToComboBox(GetWidget())->EditSelectAll(); +void CFWL_ComboBox::ProcessSelChanged(bool bLButtonUp) { + m_iCurSel = m_pListBox->GetItemIndex(this, m_pListBox->GetSelItem(0)); + if (!IsDropDownStyle()) { + Repaint(&m_rtClient); + return; + } + + CFWL_ListItem* hItem = m_pListBox->GetItem(this, m_iCurSel); + if (!hItem) + return; + + CFX_WideString wsText; + m_pListBox->GetItemText(this, hItem, wsText); + if (m_pEdit) { + m_pEdit->SetText(wsText); + m_pEdit->Update(); + m_pEdit->SetSelected(); + } + + CFWL_EvtSelectChanged ev; + ev.bLButtonUp = bLButtonUp; + ev.m_pSrcTarget = this; + DispatchEvent(&ev); } -void CFWL_ComboBox::EditDelete() { - if (GetWidget()) - ToComboBox(GetWidget())->EditDelete(); +void CFWL_ComboBox::InitProxyForm() { + if (m_pComboBoxProxy) + return; + if (!m_pListBox) + return; + + auto prop = pdfium::MakeUnique<CFWL_WidgetProperties>(); + prop->m_pOwner = this; + prop->m_dwStyles = FWL_WGTSTYLE_Popup; + prop->m_dwStates = FWL_WGTSTATE_Invisible; + + // TODO(dsinclair): Does this leak? I don't see a delete, but I'm not sure + // if the SetParent call is going to transfer ownership. + m_pComboBoxProxy = new CFWL_ComboBoxProxy(this, m_pOwnerApp, std::move(prop), + m_pListBox.get()); + m_pListBox->SetParent(m_pComboBoxProxy); } -void CFWL_ComboBox::EditDeSelect() { - if (GetWidget()) - ToComboBox(GetWidget())->EditDeSelect(); +void CFWL_ComboBox::DisForm_InitComboList() { + if (m_pListBox) + return; + + auto prop = pdfium::MakeUnique<CFWL_WidgetProperties>(); + prop->m_pParent = this; + prop->m_dwStyles = FWL_WGTSTYLE_Border | FWL_WGTSTYLE_VScroll; + prop->m_dwStates = FWL_WGTSTATE_Invisible; + prop->m_pThemeProvider = m_pProperties->m_pThemeProvider; + m_pListBox = + pdfium::MakeUnique<CFWL_ComboList>(m_pOwnerApp, std::move(prop), this); } -void CFWL_ComboBox::GetBBox(CFX_RectF& rect) { - if (GetWidget()) - ToComboBox(GetWidget())->GetBBox(rect); +void CFWL_ComboBox::DisForm_InitComboEdit() { + if (m_pEdit) + return; + + auto prop = pdfium::MakeUnique<CFWL_WidgetProperties>(); + prop->m_pParent = this; + prop->m_pThemeProvider = m_pProperties->m_pThemeProvider; + + m_pEdit = + pdfium::MakeUnique<CFWL_ComboEdit>(m_pOwnerApp, std::move(prop), this); + m_pEdit->SetOuter(this); } -void CFWL_ComboBox::EditModifyStylesEx(uint32_t dwStylesExAdded, - uint32_t dwStylesExRemoved) { - if (GetWidget()) { - ToComboBox(GetWidget()) - ->EditModifyStylesEx(dwStylesExAdded, dwStylesExRemoved); +void CFWL_ComboBox::DisForm_ShowDropList(bool bActivate) { + if (DisForm_IsDropListVisible() == bActivate) + return; + + if (bActivate) { + CFWL_EvtPreDropDown preEvent; + preEvent.m_pSrcTarget = this; + DispatchEvent(&preEvent); + + CFWL_ComboList* pComboList = m_pListBox.get(); + int32_t iItems = pComboList->CountItems(nullptr); + if (iItems < 1) + return; + + ResetListItemAlignment(); + pComboList->ChangeSelected(m_iCurSel); + + FX_FLOAT fItemHeight = pComboList->CalcItemHeight(); + FX_FLOAT fBorder = GetBorderSize(); + FX_FLOAT fPopupMin = 0.0f; + if (iItems > 3) + fPopupMin = fItemHeight * 3 + fBorder * 2; + + FX_FLOAT fPopupMax = fItemHeight * iItems + fBorder * 2; + CFX_RectF rtList; + rtList.left = m_rtClient.left; + rtList.width = m_pProperties->m_rtWidget.width; + rtList.top = 0; + rtList.height = 0; + GetPopupPos(fPopupMin, fPopupMax, m_pProperties->m_rtWidget, rtList); + + m_pListBox->SetWidgetRect(rtList); + m_pListBox->Update(); + } else { + SetFocus(true); + } + + m_pListBox->SetStates(FWL_WGTSTATE_Invisible, !bActivate); + if (bActivate) { + CFWL_EvtPostDropDown postEvent; + postEvent.m_pSrcTarget = this; + DispatchEvent(&postEvent); + } + + CFX_RectF rect; + m_pListBox->GetWidgetRect(rect); + rect.Inflate(2, 2); + Repaint(&rect); +} + +void CFWL_ComboBox::DisForm_ModifyStylesEx(uint32_t dwStylesExAdded, + uint32_t dwStylesExRemoved) { + if (!m_pEdit) + DisForm_InitComboEdit(); + + bool bAddDropDown = !!(dwStylesExAdded & FWL_STYLEEXT_CMB_DropDown); + bool bDelDropDown = !!(dwStylesExRemoved & FWL_STYLEEXT_CMB_DropDown); + + dwStylesExRemoved &= ~FWL_STYLEEXT_CMB_DropDown; + m_pProperties->m_dwStyleExes |= FWL_STYLEEXT_CMB_DropDown; + + if (bAddDropDown) + m_pEdit->ModifyStylesEx(0, FWL_STYLEEXT_EDT_ReadOnly); + else if (bDelDropDown) + m_pEdit->ModifyStylesEx(FWL_STYLEEXT_EDT_ReadOnly, 0); + CFWL_Widget::ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved); +} + +void CFWL_ComboBox::DisForm_Update() { + if (m_iLock) + return; + if (m_pEdit) + ResetEditAlignment(); + ResetTheme(); + Layout(); +} + +FWL_WidgetHit CFWL_ComboBox::DisForm_HitTest(FX_FLOAT fx, FX_FLOAT fy) { + CFX_RectF rect; + rect.Set(0, 0, m_pProperties->m_rtWidget.width - m_rtBtn.width, + m_pProperties->m_rtWidget.height); + if (rect.Contains(fx, fy)) + return FWL_WidgetHit::Edit; + if (m_rtBtn.Contains(fx, fy)) + return FWL_WidgetHit::Client; + if (DisForm_IsDropListVisible()) { + m_pListBox->GetWidgetRect(rect); + if (rect.Contains(fx, fy)) + return FWL_WidgetHit::Client; + } + return FWL_WidgetHit::Unknown; +} + +void CFWL_ComboBox::DisForm_DrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) { + IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider; + CFX_Matrix mtOrg; + mtOrg.Set(1, 0, 0, 1, 0, 0); + if (pMatrix) + mtOrg = *pMatrix; + + pGraphics->SaveGraphState(); + pGraphics->ConcatMatrix(&mtOrg); + if (!m_rtBtn.IsEmpty(0.1f)) { + 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; + pTheme->DrawBackground(¶m); + } + pGraphics->RestoreGraphState(); + + if (m_pEdit) { + CFX_RectF rtEdit; + m_pEdit->GetWidgetRect(rtEdit); + CFX_Matrix mt; + mt.Set(1, 0, 0, 1, rtEdit.left, rtEdit.top); + mt.Concat(mtOrg); + m_pEdit->DrawWidget(pGraphics, &mt); + } + if (m_pListBox && DisForm_IsDropListVisible()) { + CFX_RectF rtList; + m_pListBox->GetWidgetRect(rtList); + CFX_Matrix mt; + mt.Set(1, 0, 0, 1, rtList.left, rtList.top); + mt.Concat(mtOrg); + m_pListBox->DrawWidget(pGraphics, &mt); + } +} + +void CFWL_ComboBox::DisForm_GetBBox(CFX_RectF& rect) const { + rect = m_pProperties->m_rtWidget; + if (!m_pListBox || !DisForm_IsDropListVisible()) + return; + + CFX_RectF rtList; + m_pListBox->GetWidgetRect(rtList); + rtList.Offset(rect.left, rect.top); + rect.Union(rtList); +} + +void CFWL_ComboBox::DisForm_Layout() { + GetClientRect(m_rtClient); + m_rtContent = m_rtClient; + FX_FLOAT* pFWidth = static_cast<FX_FLOAT*>( + GetThemeCapacity(CFWL_WidgetCapacity::ScrollBarWidth)); + if (!pFWidth) + return; + + FX_FLOAT borderWidth = 1; + FX_FLOAT fBtn = *pFWidth; + if (!(GetStylesEx() & FWL_STYLEEXT_CMB_ReadOnly)) { + m_rtBtn.Set(m_rtClient.right() - fBtn, m_rtClient.top + borderWidth, + fBtn - borderWidth, m_rtClient.height - 2 * borderWidth); + } + + CFX_RectF* pUIMargin = + static_cast<CFX_RectF*>(GetThemeCapacity(CFWL_WidgetCapacity::UIMargin)); + if (pUIMargin) { + m_rtContent.Deflate(pUIMargin->left, pUIMargin->top, pUIMargin->width, + pUIMargin->height); + } + + if (!IsDropDownStyle() || !m_pEdit) + return; + + CFX_RectF rtEdit; + rtEdit.Set(m_rtContent.left, m_rtContent.top, m_rtContent.width - fBtn, + m_rtContent.height); + m_pEdit->SetWidgetRect(rtEdit); + + if (m_iCurSel >= 0) { + CFX_WideString wsText; + CFWL_ListItem* hItem = m_pListBox->GetItem(this, m_iCurSel); + m_pListBox->GetDataProviderItemText(hItem, wsText); + m_pEdit->LockUpdate(); + m_pEdit->SetText(wsText); + m_pEdit->UnlockUpdate(); + } + m_pEdit->Update(); +} + +void CFWL_ComboBox::OnProcessMessage(CFWL_Message* pMessage) { + if (m_pWidgetMgr->IsFormDisabled()) { + DisForm_OnProcessMessage(pMessage); + return; + } + 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* pMsg = static_cast<CFWL_MsgMouse*>(pMessage); + switch (pMsg->m_dwCmd) { + case FWL_MouseCommand::LeftButtonDown: + OnLButtonDown(pMsg); + break; + case FWL_MouseCommand::LeftButtonUp: + OnLButtonUp(pMsg); + break; + case FWL_MouseCommand::Move: + OnMouseMove(pMsg); + break; + case FWL_MouseCommand::Leave: + OnMouseLeave(pMsg); + break; + default: + break; + } + break; + } + case CFWL_MessageType::Key: + OnKey(static_cast<CFWL_MsgKey*>(pMessage)); + break; + default: + break; + } + + CFWL_Widget::OnProcessMessage(pMessage); +} + +void CFWL_ComboBox::OnProcessEvent(CFWL_Event* pEvent) { + CFWL_EventType dwFlag = pEvent->GetClassID(); + if (dwFlag == CFWL_EventType::Scroll) { + CFWL_EvtScroll* pScrollEvent = static_cast<CFWL_EvtScroll*>(pEvent); + CFWL_EvtScroll pScrollEv; + pScrollEv.m_pSrcTarget = this; + pScrollEv.m_iScrollCode = pScrollEvent->m_iScrollCode; + pScrollEv.m_fPos = pScrollEvent->m_fPos; + DispatchEvent(&pScrollEv); + } else if (dwFlag == CFWL_EventType::TextChanged) { + CFWL_EvtEditChanged pTemp; + pTemp.m_pSrcTarget = this; + DispatchEvent(&pTemp); + } +} + +void CFWL_ComboBox::OnDrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) { + DrawWidget(pGraphics, pMatrix); +} + +void CFWL_ComboBox::OnFocusChanged(CFWL_Message* pMsg, bool bSet) { + if (bSet) { + m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused; + if (IsDropDownStyle() && pMsg->m_pSrcTarget != m_pListBox.get()) { + if (!m_pEdit) + return; + m_pEdit->SetSelected(); + return; + } + + Repaint(&m_rtClient); + return; + } + + m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused; + if (!IsDropDownStyle() || pMsg->m_pDstTarget == m_pListBox.get()) { + Repaint(&m_rtClient); + return; + } + if (!m_pEdit) + return; + + m_pEdit->FlagFocus(false); + m_pEdit->ClearSelected(); +} + +void CFWL_ComboBox::OnLButtonDown(CFWL_MsgMouse* pMsg) { + if (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) + return; + + CFX_RectF& rtBtn = IsDropDownStyle() ? m_rtBtn : m_rtClient; + if (!rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) + return; + + if (IsDropDownStyle() && m_pEdit) + MatchEditText(); + + m_bLButtonDown = true; + m_iBtnState = CFWL_PartState_Pressed; + Repaint(&m_rtClient); + + ShowDropList(true); + m_iBtnState = CFWL_PartState_Normal; + Repaint(&m_rtClient); +} + +void CFWL_ComboBox::OnLButtonUp(CFWL_MsgMouse* pMsg) { + m_bLButtonDown = false; + if (m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) + m_iBtnState = CFWL_PartState_Hovered; + else + m_iBtnState = CFWL_PartState_Normal; + + Repaint(&m_rtBtn); +} + +void CFWL_ComboBox::OnMouseMove(CFWL_MsgMouse* pMsg) { + int32_t iOldState = m_iBtnState; + if (m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) { + m_iBtnState = + m_bLButtonDown ? CFWL_PartState_Pressed : CFWL_PartState_Hovered; + } else { + m_iBtnState = CFWL_PartState_Normal; + } + if ((iOldState != m_iBtnState) && + !((m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) == + FWL_WGTSTATE_Disabled)) { + Repaint(&m_rtBtn); + } +} + +void CFWL_ComboBox::OnMouseLeave(CFWL_MsgMouse* pMsg) { + if (!IsDropListVisible() && + !((m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) == + FWL_WGTSTATE_Disabled)) { + m_iBtnState = CFWL_PartState_Normal; + Repaint(&m_rtBtn); + } +} + +void CFWL_ComboBox::OnKey(CFWL_MsgKey* pMsg) { + uint32_t dwKeyCode = pMsg->m_dwKeyCode; + if (dwKeyCode == FWL_VKEY_Tab) { + DispatchKeyEvent(pMsg); + return; + } + if (pMsg->m_pDstTarget == this) + DoSubCtrlKey(pMsg); +} + +void CFWL_ComboBox::DoSubCtrlKey(CFWL_MsgKey* pMsg) { + uint32_t dwKeyCode = pMsg->m_dwKeyCode; + const bool bUp = dwKeyCode == FWL_VKEY_Up; + const bool bDown = dwKeyCode == FWL_VKEY_Down; + if (bUp || bDown) { + int32_t iCount = m_pListBox->CountItems(nullptr); + if (iCount < 1) + return; + + bool bMatchEqual = false; + int32_t iCurSel = m_iCurSel; + bool bDropDown = IsDropDownStyle(); + if (bDropDown && m_pEdit) { + CFX_WideString wsText; + m_pEdit->GetText(wsText); + iCurSel = m_pListBox->MatchItem(wsText); + if (iCurSel >= 0) { + CFX_WideString wsTemp; + CFWL_ListItem* hItem = m_pListBox->GetItem(this, iCurSel); + m_pListBox->GetDataProviderItemText(hItem, wsTemp); + bMatchEqual = wsText == wsTemp; + } + } + if (iCurSel < 0) { + iCurSel = 0; + } else if (!bDropDown || bMatchEqual) { + if ((bUp && iCurSel == 0) || (bDown && iCurSel == iCount - 1)) + return; + if (bUp) + iCurSel--; + else + iCurSel++; + } + m_iCurSel = iCurSel; + if (bDropDown && m_pEdit) + SyncEditText(m_iCurSel); + else + Repaint(&m_rtClient); + return; + } + + if (IsDropDownStyle()) + m_pEdit->GetDelegate()->OnProcessMessage(pMsg); +} + +void CFWL_ComboBox::DisForm_OnProcessMessage(CFWL_Message* pMessage) { + if (!pMessage) + return; + + bool backDefault = true; + switch (pMessage->GetClassID()) { + case CFWL_MessageType::SetFocus: { + backDefault = false; + DisForm_OnFocusChanged(pMessage, true); + break; + } + case CFWL_MessageType::KillFocus: { + backDefault = false; + DisForm_OnFocusChanged(pMessage, false); + break; + } + case CFWL_MessageType::Mouse: { + backDefault = false; + CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage); + switch (pMsg->m_dwCmd) { + case FWL_MouseCommand::LeftButtonDown: + DisForm_OnLButtonDown(pMsg); + break; + case FWL_MouseCommand::LeftButtonUp: + OnLButtonUp(pMsg); + break; + default: + break; + } + break; + } + case CFWL_MessageType::Key: { + backDefault = false; + CFWL_MsgKey* pKey = static_cast<CFWL_MsgKey*>(pMessage); + if (pKey->m_dwCmd == FWL_KeyCommand::KeyUp) + break; + if (DisForm_IsDropListVisible() && + pKey->m_dwCmd == FWL_KeyCommand::KeyDown) { + bool bListKey = pKey->m_dwKeyCode == FWL_VKEY_Up || + pKey->m_dwKeyCode == FWL_VKEY_Down || + pKey->m_dwKeyCode == FWL_VKEY_Return || + pKey->m_dwKeyCode == FWL_VKEY_Escape; + if (bListKey) { + m_pListBox->GetDelegate()->OnProcessMessage(pMessage); + break; + } + } + DisForm_OnKey(pKey); + break; + } + default: + break; + } + if (backDefault) + CFWL_Widget::OnProcessMessage(pMessage); +} + +void CFWL_ComboBox::DisForm_OnLButtonDown(CFWL_MsgMouse* pMsg) { + bool bDropDown = DisForm_IsDropListVisible(); + CFX_RectF& rtBtn = bDropDown ? m_rtBtn : m_rtClient; + if (!rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) + return; + + if (DisForm_IsDropListVisible()) { + DisForm_ShowDropList(false); + return; + } + if (m_pEdit) + MatchEditText(); + DisForm_ShowDropList(true); +} + +void CFWL_ComboBox::DisForm_OnFocusChanged(CFWL_Message* pMsg, bool bSet) { + if (bSet) { + m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused; + if ((m_pEdit->GetStates() & FWL_WGTSTATE_Focused) == 0) { + CFWL_MsgSetFocus msg; + msg.m_pDstTarget = m_pEdit.get(); + msg.m_pSrcTarget = nullptr; + m_pEdit->GetDelegate()->OnProcessMessage(&msg); + } + } else { + m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused; + DisForm_ShowDropList(false); + CFWL_MsgKillFocus msg; + msg.m_pDstTarget = nullptr; + msg.m_pSrcTarget = m_pEdit.get(); + m_pEdit->GetDelegate()->OnProcessMessage(&msg); + } +} + +void CFWL_ComboBox::DisForm_OnKey(CFWL_MsgKey* pMsg) { + uint32_t dwKeyCode = pMsg->m_dwKeyCode; + const bool bUp = dwKeyCode == FWL_VKEY_Up; + const bool bDown = dwKeyCode == FWL_VKEY_Down; + if (bUp || bDown) { + CFWL_ComboList* pComboList = m_pListBox.get(); + int32_t iCount = pComboList->CountItems(nullptr); + if (iCount < 1) + return; + + bool bMatchEqual = false; + int32_t iCurSel = m_iCurSel; + if (m_pEdit) { + CFX_WideString wsText; + m_pEdit->GetText(wsText); + iCurSel = pComboList->MatchItem(wsText); + if (iCurSel >= 0) { + CFX_WideString wsTemp; + CFWL_ListItem* item = m_pListBox->GetSelItem(iCurSel); + m_pListBox->GetDataProviderItemText(item, wsTemp); + bMatchEqual = wsText == wsTemp; + } + } + if (iCurSel < 0) { + iCurSel = 0; + } else if (bMatchEqual) { + if ((bUp && iCurSel == 0) || (bDown && iCurSel == iCount - 1)) + return; + if (bUp) + iCurSel--; + else + iCurSel++; + } + m_iCurSel = iCurSel; + SyncEditText(m_iCurSel); + return; } + if (m_pEdit) + m_pEdit->GetDelegate()->OnProcessMessage(pMsg); } diff --git a/xfa/fwl/core/cfwl_combobox.h b/xfa/fwl/core/cfwl_combobox.h index 7b6f43419b..a4545198b4 100644 --- a/xfa/fwl/core/cfwl_combobox.h +++ b/xfa/fwl/core/cfwl_combobox.h @@ -8,26 +8,74 @@ #define XFA_FWL_CORE_CFWL_COMBOBOX_H_ #include <memory> -#include <vector> -#include "xfa/fwl/core/cfwl_widget.h" -#include "xfa/fwl/core/ifwl_combobox.h" +#include "xfa/fwl/core/cfwl_comboboxproxy.h" +#include "xfa/fwl/core/cfwl_comboedit.h" +#include "xfa/fwl/core/cfwl_combolist.h" +#include "xfa/fwl/core/cfwl_form.h" +#include "xfa/fwl/core/cfwl_listbox.h" +#include "xfa/fxgraphics/cfx_graphics.h" + +class CFWL_WidgetProperties; +class CFWL_ComboBox; +class CFWL_ComboBoxProxy; +class CFWL_FormProxy; +class CFWL_ListBox; +class CFWL_Widget; + +#define FWL_STYLEEXT_CMB_DropList (0L << 0) +#define FWL_STYLEEXT_CMB_DropDown (1L << 0) +#define FWL_STYLEEXT_CMB_Sort (1L << 1) +#define FWL_STYLEEXT_CMB_ListDrag (1L << 2) +#define FWL_STYLEEXT_CMB_OwnerDraw (1L << 3) +#define FWL_STYLEEXT_CMB_EditHNear (0L << 4) +#define FWL_STYLEEXT_CMB_EditHCenter (1L << 4) +#define FWL_STYLEEXT_CMB_EditHFar (2L << 4) +#define FWL_STYLEEXT_CMB_EditVNear (0L << 6) +#define FWL_STYLEEXT_CMB_EditVCenter (1L << 6) +#define FWL_STYLEEXT_CMB_EditVFar (2L << 6) +#define FWL_STYLEEXT_CMB_EditJustified (1L << 8) +#define FWL_STYLEEXT_CMB_EditDistributed (2L << 8) +#define FWL_STYLEEXT_CMB_EditHAlignMask (3L << 4) +#define FWL_STYLEEXT_CMB_EditVAlignMask (3L << 6) +#define FWL_STYLEEXT_CMB_EditHAlignModeMask (3L << 8) +#define FWL_STYLEEXT_CMB_ListItemLeftAlign (0L << 10) +#define FWL_STYLEEXT_CMB_ListItemCenterAlign (1L << 10) +#define FWL_STYLEEXT_CMB_ListItemRightAlign (2L << 10) +#define FWL_STYLEEXT_CMB_ListItemAlignMask (3L << 10) +#define FWL_STYLEEXT_CMB_ListItemText (0L << 12) +#define FWL_STYLEEXT_CMB_ListItemIconText (1L << 12) +#define FWL_STYLEEXT_CMB_ReadOnly (1L << 13) class CFWL_ComboBox : public CFWL_Widget { public: explicit CFWL_ComboBox(const CFWL_App* pApp); ~CFWL_ComboBox() override; - void Initialize(); + // CFWL_Widget + FWL_Type GetClassID() const override; + void GetWidgetRect(CFX_RectF& rect, bool bAutoSize = false) override; + void ModifyStylesEx(uint32_t dwStylesExAdded, + uint32_t dwStylesExRemoved) override; + void SetStates(uint32_t dwStates, bool bSet = true) override; + void Update() override; + FWL_WidgetHit HitTest(FX_FLOAT fx, FX_FLOAT fy) override; + void DrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix = nullptr) override; + void SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) override; + void OnProcessMessage(CFWL_Message* pMessage) override; + void OnProcessEvent(CFWL_Event* pEvent) override; + void OnDrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) override; + + void GetTextByIndex(int32_t iIndex, CFX_WideString& wsText) const; + int32_t GetCurSel() const { return m_iCurSel; } + void SetCurSel(int32_t iSel); void AddString(const CFX_WideStringC& wsText); bool RemoveAt(int32_t iIndex); // Returns false iff |iIndex| out of range. void RemoveAll(); - void GetTextByIndex(int32_t iIndex, CFX_WideString& wsText) const; - int32_t GetCurSel() const; - void SetCurSel(int32_t iSel); - void SetEditText(const CFX_WideString& wsText); void GetEditText(CFX_WideString& wsText, int32_t nStart = 0, @@ -35,22 +83,93 @@ class CFWL_ComboBox : public CFWL_Widget { void OpenDropDownList(bool bActivate); - bool EditCanUndo(); - bool EditCanRedo(); - bool EditUndo(); - bool EditRedo(); - bool EditCanCopy(); - bool EditCanCut(); - bool EditCanSelectAll(); - bool EditCopy(CFX_WideString& wsCopy); - bool EditCut(CFX_WideString& wsCut); - bool EditPaste(const CFX_WideString& wsPaste); - void EditSelectAll(); - void EditDelete(); - void EditDeSelect(); - - void GetBBox(CFX_RectF& rect); + bool EditCanUndo() const { return m_pEdit->CanUndo(); } + bool EditCanRedo() const { return m_pEdit->CanRedo(); } + bool EditUndo() { return m_pEdit->Undo(); } + bool EditRedo() { return m_pEdit->Redo(); } + bool EditCanCopy() const { return m_pEdit->CountSelRanges() > 0; } + bool EditCanCut() const { + if (m_pEdit->GetStylesEx() & FWL_STYLEEXT_EDT_ReadOnly) + return false; + return EditCanCopy(); + } + bool EditCanSelectAll() const { return m_pEdit->GetTextLength() > 0; } + bool EditCopy(CFX_WideString& wsCopy) const { return m_pEdit->Copy(wsCopy); } + bool EditCut(CFX_WideString& wsCut) { return m_pEdit->Cut(wsCut); } + bool EditPaste(const CFX_WideString& wsPaste) { + return m_pEdit->Paste(wsPaste); + } + void EditSelectAll() { m_pEdit->AddSelRange(0); } + void EditDelete() { m_pEdit->ClearText(); } + void EditDeSelect() { m_pEdit->ClearSelections(); } + + void GetBBox(CFX_RectF& rect) const; void EditModifyStylesEx(uint32_t dwStylesExAdded, uint32_t dwStylesExRemoved); + + void DrawStretchHandler(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix); + bool IsDropListVisible() const { + return m_pComboBoxProxy && + !(m_pComboBoxProxy->GetStates() & FWL_WGTSTATE_Invisible); + } + void ShowDropList(bool bActivate); + + CFWL_ComboEdit* GetComboEdit() const { return m_pEdit.get(); } + + void ProcessSelChanged(bool bLButtonUp); + int32_t GetCurrentSelection() const { return m_iCurSel; } + + private: + bool IsDropDownStyle() const { + return !!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_DropDown); + } + void MatchEditText(); + void SyncEditText(int32_t iListItem); + void Layout(); + void ResetTheme(); + void ResetEditAlignment(); + void ResetListItemAlignment(); + void InitProxyForm(); + void DisForm_InitComboList(); + void DisForm_InitComboEdit(); + void DisForm_ShowDropList(bool bActivate); + bool DisForm_IsDropListVisible() const { + return !(m_pListBox->GetStates() & FWL_WGTSTATE_Invisible); + } + void DisForm_ModifyStylesEx(uint32_t dwStylesExAdded, + uint32_t dwStylesExRemoved); + void DisForm_Update(); + FWL_WidgetHit DisForm_HitTest(FX_FLOAT fx, FX_FLOAT fy); + void DisForm_DrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix = nullptr); + void DisForm_GetBBox(CFX_RectF& rect) const; + void DisForm_Layout(); + void OnFocusChanged(CFWL_Message* pMsg, bool bSet = true); + void OnLButtonDown(CFWL_MsgMouse* pMsg); + void OnLButtonUp(CFWL_MsgMouse* pMsg); + void OnMouseMove(CFWL_MsgMouse* pMsg); + void OnMouseLeave(CFWL_MsgMouse* pMsg); + void OnKey(CFWL_MsgKey* pMsg); + void DoSubCtrlKey(CFWL_MsgKey* pMsg); + void DisForm_OnProcessMessage(CFWL_Message* pMessage); + void DisForm_OnLButtonDown(CFWL_MsgMouse* pMsg); + void DisForm_OnFocusChanged(CFWL_Message* pMsg, bool bSet = true); + void DisForm_OnKey(CFWL_MsgKey* pMsg); + + CFX_RectF m_rtClient; + CFX_RectF m_rtContent; + CFX_RectF m_rtBtn; + CFX_RectF m_rtList; + CFX_RectF m_rtProxy; + CFX_RectF m_rtHandler; + std::unique_ptr<CFWL_ComboEdit> m_pEdit; + std::unique_ptr<CFWL_ComboList> m_pListBox; + CFWL_ComboBoxProxy* m_pComboBoxProxy; // Can this be a unique_ptr? + bool m_bLButtonDown; + bool m_bUpFormHandler; + int32_t m_iCurSel; + int32_t m_iBtnState; + FX_FLOAT m_fComboFormHandler; + FX_FLOAT m_fItemHeight; }; #endif // XFA_FWL_CORE_CFWL_COMBOBOX_H_ diff --git a/xfa/fwl/core/cfwl_comboboxproxy.cpp b/xfa/fwl/core/cfwl_comboboxproxy.cpp index c367eefb9c..4ad358d723 100644 --- a/xfa/fwl/core/cfwl_comboboxproxy.cpp +++ b/xfa/fwl/core/cfwl_comboboxproxy.cpp @@ -10,16 +10,16 @@ #include <utility> #include "xfa/fwl/core/cfwl_app.h" +#include "xfa/fwl/core/cfwl_combobox.h" #include "xfa/fwl/core/cfwl_msgkillfocus.h" #include "xfa/fwl/core/cfwl_msgmouse.h" #include "xfa/fwl/core/cfwl_notedriver.h" -#include "xfa/fwl/core/ifwl_combobox.h" CFWL_ComboBoxProxy::CFWL_ComboBoxProxy( - IFWL_ComboBox* pComboBox, + CFWL_ComboBox* pComboBox, const CFWL_App* app, std::unique_ptr<CFWL_WidgetProperties> properties, - IFWL_Widget* pOuter) + CFWL_Widget* pOuter) : CFWL_FormProxy(app, std::move(properties), pOuter), m_bLButtonDown(false), m_bLButtonUpSelf(false), @@ -55,7 +55,7 @@ void CFWL_ComboBoxProxy::OnProcessMessage(CFWL_Message* pMessage) { default: break; } - IFWL_Widget::OnProcessMessage(pMessage); + CFWL_Widget::OnProcessMessage(pMessage); } void CFWL_ComboBoxProxy::OnDrawWidget(CFX_Graphics* pGraphics, diff --git a/xfa/fwl/core/cfwl_comboboxproxy.h b/xfa/fwl/core/cfwl_comboboxproxy.h index 33f5a82e79..11fb364cdc 100644 --- a/xfa/fwl/core/cfwl_comboboxproxy.h +++ b/xfa/fwl/core/cfwl_comboboxproxy.h @@ -11,14 +11,14 @@ #include "xfa/fwl/core/cfwl_formproxy.h" -class IFWL_ComboBox; +class CFWL_ComboBox; class CFWL_ComboBoxProxy : public CFWL_FormProxy { public: - CFWL_ComboBoxProxy(IFWL_ComboBox* pCombobBox, + CFWL_ComboBoxProxy(CFWL_ComboBox* pCombobBox, const CFWL_App* app, std::unique_ptr<CFWL_WidgetProperties> properties, - IFWL_Widget* pOuter); + CFWL_Widget* pOuter); ~CFWL_ComboBoxProxy() override; // CFWL_FormProxy @@ -35,7 +35,7 @@ class CFWL_ComboBoxProxy : public CFWL_FormProxy { bool m_bLButtonDown; bool m_bLButtonUpSelf; - IFWL_ComboBox* m_pComboBox; + CFWL_ComboBox* m_pComboBox; }; #endif // XFA_FWL_CORE_CFWL_COMBOBOXPROXY_H_ diff --git a/xfa/fwl/core/cfwl_comboedit.cpp b/xfa/fwl/core/cfwl_comboedit.cpp index 2051daa786..af5c2a74b6 100644 --- a/xfa/fwl/core/cfwl_comboedit.cpp +++ b/xfa/fwl/core/cfwl_comboedit.cpp @@ -10,15 +10,15 @@ #include <utility> #include "xfa/fde/cfde_txtedtengine.h" +#include "xfa/fwl/core/cfwl_combobox.h" #include "xfa/fwl/core/cfwl_msgmouse.h" -#include "xfa/fwl/core/ifwl_combobox.h" CFWL_ComboEdit::CFWL_ComboEdit( const CFWL_App* app, std::unique_ptr<CFWL_WidgetProperties> properties, - IFWL_Widget* pOuter) - : IFWL_Edit(app, std::move(properties), pOuter) { - m_pOuter = static_cast<IFWL_ComboBox*>(pOuter); + CFWL_Widget* pOuter) + : CFWL_Edit(app, std::move(properties), pOuter) { + m_pOuter = static_cast<CFWL_ComboBox*>(pOuter); } void CFWL_ComboEdit::ClearSelected() { @@ -71,5 +71,5 @@ void CFWL_ComboEdit::OnProcessMessage(CFWL_Message* pMessage) { break; } if (backDefault) - IFWL_Edit::OnProcessMessage(pMessage); + CFWL_Edit::OnProcessMessage(pMessage); } diff --git a/xfa/fwl/core/cfwl_comboedit.h b/xfa/fwl/core/cfwl_comboedit.h index 30c5e85ad1..5ac6082a50 100644 --- a/xfa/fwl/core/cfwl_comboedit.h +++ b/xfa/fwl/core/cfwl_comboedit.h @@ -9,19 +9,19 @@ #include <memory> +#include "xfa/fwl/core/cfwl_edit.h" +#include "xfa/fwl/core/cfwl_widget.h" #include "xfa/fwl/core/cfwl_widgetproperties.h" -#include "xfa/fwl/core/ifwl_edit.h" -#include "xfa/fwl/core/ifwl_widget.h" -class IFWL_ComboBox; +class CFWL_ComboBox; -class CFWL_ComboEdit : public IFWL_Edit { +class CFWL_ComboEdit : public CFWL_Edit { public: CFWL_ComboEdit(const CFWL_App* app, std::unique_ptr<CFWL_WidgetProperties> properties, - IFWL_Widget* pOuter); + CFWL_Widget* pOuter); - // IFWL_Edit. + // CFWL_Edit. void OnProcessMessage(CFWL_Message* pMessage) override; void ClearSelected(); @@ -29,7 +29,7 @@ class CFWL_ComboEdit : public IFWL_Edit { void FlagFocus(bool bSet); private: - IFWL_ComboBox* m_pOuter; + CFWL_ComboBox* m_pOuter; }; #endif // XFA_FWL_CORE_CFWL_COMBOEDIT_H_ diff --git a/xfa/fwl/core/cfwl_combolist.cpp b/xfa/fwl/core/cfwl_combolist.cpp index e98f38e81a..0476498388 100644 --- a/xfa/fwl/core/cfwl_combolist.cpp +++ b/xfa/fwl/core/cfwl_combolist.cpp @@ -10,18 +10,18 @@ #include <utility> #include "third_party/base/ptr_util.h" +#include "xfa/fwl/core/cfwl_combobox.h" #include "xfa/fwl/core/cfwl_comboedit.h" +#include "xfa/fwl/core/cfwl_listbox.h" #include "xfa/fwl/core/cfwl_msgkey.h" #include "xfa/fwl/core/cfwl_msgkillfocus.h" #include "xfa/fwl/core/cfwl_msgmouse.h" -#include "xfa/fwl/core/ifwl_combobox.h" -#include "xfa/fwl/core/ifwl_listbox.h" CFWL_ComboList::CFWL_ComboList( const CFWL_App* app, std::unique_ptr<CFWL_WidgetProperties> properties, - IFWL_Widget* pOuter) - : IFWL_ListBox(app, std::move(properties), pOuter), m_bNotifyOwner(true) { + CFWL_Widget* pOuter) + : CFWL_ListBox(app, std::move(properties), pOuter), m_bNotifyOwner(true) { ASSERT(pOuter); } @@ -68,7 +68,7 @@ void CFWL_ComboList::ChangeSelected(int32_t iSel) { void CFWL_ComboList::ClientToOuter(FX_FLOAT& fx, FX_FLOAT& fy) { fx += m_pProperties->m_rtWidget.left, fy += m_pProperties->m_rtWidget.top; - IFWL_Widget* pOwner = GetOwner(); + CFWL_Widget* pOwner = GetOwner(); if (!pOwner) return; pOwner->TransformTo(m_pOuter, fx, fy); @@ -119,7 +119,7 @@ void CFWL_ComboList::OnProcessMessage(CFWL_Message* pMessage) { backDefault = !OnDropListKey(static_cast<CFWL_MsgKey*>(pMessage)); } if (backDefault) - IFWL_ListBox::OnProcessMessage(pMessage); + CFWL_ListBox::OnProcessMessage(pMessage); } void CFWL_ComboList::OnDropListFocusChanged(CFWL_Message* pMsg, bool bSet) { @@ -127,7 +127,7 @@ void CFWL_ComboList::OnDropListFocusChanged(CFWL_Message* pMsg, bool bSet) { return; CFWL_MsgKillFocus* pKill = static_cast<CFWL_MsgKillFocus*>(pMsg); - IFWL_ComboBox* pOuter = static_cast<IFWL_ComboBox*>(m_pOuter); + CFWL_ComboBox* pOuter = static_cast<CFWL_ComboBox*>(m_pOuter); if (pKill->m_pSetFocus == m_pOuter || pKill->m_pSetFocus == pOuter->GetComboEdit()) { pOuter->ShowDropList(false); @@ -154,7 +154,7 @@ void CFWL_ComboList::OnDropListMouseMove(CFWL_MsgMouse* pMsg) { ChangeSelected(GetItemIndex(this, hItem)); } else if (m_bNotifyOwner) { ClientToOuter(pMsg->m_fx, pMsg->m_fy); - IFWL_ComboBox* pOuter = static_cast<IFWL_ComboBox*>(m_pOuter); + CFWL_ComboBox* pOuter = static_cast<CFWL_ComboBox*>(m_pOuter); pOuter->GetDelegate()->OnProcessMessage(pMsg); } } @@ -163,12 +163,12 @@ void CFWL_ComboList::OnDropListLButtonDown(CFWL_MsgMouse* pMsg) { if (GetRTClient().Contains(pMsg->m_fx, pMsg->m_fy)) return; - IFWL_ComboBox* pOuter = static_cast<IFWL_ComboBox*>(m_pOuter); + CFWL_ComboBox* pOuter = static_cast<CFWL_ComboBox*>(m_pOuter); pOuter->ShowDropList(false); } void CFWL_ComboList::OnDropListLButtonUp(CFWL_MsgMouse* pMsg) { - IFWL_ComboBox* pOuter = static_cast<IFWL_ComboBox*>(m_pOuter); + CFWL_ComboBox* pOuter = static_cast<CFWL_ComboBox*>(m_pOuter); if (m_bNotifyOwner) { ClientToOuter(pMsg->m_fx, pMsg->m_fy); pOuter->GetDelegate()->OnProcessMessage(pMsg); @@ -190,7 +190,7 @@ void CFWL_ComboList::OnDropListLButtonUp(CFWL_MsgMouse* pMsg) { } bool CFWL_ComboList::OnDropListKey(CFWL_MsgKey* pKey) { - IFWL_ComboBox* pOuter = static_cast<IFWL_ComboBox*>(m_pOuter); + CFWL_ComboBox* pOuter = static_cast<CFWL_ComboBox*>(m_pOuter); bool bPropagate = false; if (pKey->m_dwCmd == FWL_KeyCommand::KeyDown) { uint32_t dwKeyCode = pKey->m_dwKeyCode; @@ -229,7 +229,7 @@ void CFWL_ComboList::OnDropListKeyDown(CFWL_MsgKey* pKey) { case FWL_VKEY_Down: case FWL_VKEY_Home: case FWL_VKEY_End: { - IFWL_ComboBox* pOuter = static_cast<IFWL_ComboBox*>(m_pOuter); + CFWL_ComboBox* pOuter = static_cast<CFWL_ComboBox*>(m_pOuter); CFWL_ListItem* hItem = GetItem(this, pOuter->GetCurrentSelection()); hItem = GetListItem(hItem, dwKeyCode); if (!hItem) diff --git a/xfa/fwl/core/cfwl_combolist.h b/xfa/fwl/core/cfwl_combolist.h index ad97b5bed7..0c1cd579b0 100644 --- a/xfa/fwl/core/cfwl_combolist.h +++ b/xfa/fwl/core/cfwl_combolist.h @@ -9,17 +9,17 @@ #include <memory> +#include "xfa/fwl/core/cfwl_listbox.h" +#include "xfa/fwl/core/cfwl_widget.h" #include "xfa/fwl/core/cfwl_widgetproperties.h" -#include "xfa/fwl/core/ifwl_listbox.h" -#include "xfa/fwl/core/ifwl_widget.h" -class CFWL_ComboList : public IFWL_ListBox { +class CFWL_ComboList : public CFWL_ListBox { public: CFWL_ComboList(const CFWL_App* app, std::unique_ptr<CFWL_WidgetProperties> properties, - IFWL_Widget* pOuter); + CFWL_Widget* pOuter); - // IFWL_ListBox. + // CFWL_ListBox. void OnProcessMessage(CFWL_Message* pMessage) override; int32_t MatchItem(const CFX_WideString& wsMatch); diff --git a/xfa/fwl/core/cfwl_datetimeedit.cpp b/xfa/fwl/core/cfwl_datetimeedit.cpp index 16ebb3c8cf..b74efb1284 100644 --- a/xfa/fwl/core/cfwl_datetimeedit.cpp +++ b/xfa/fwl/core/cfwl_datetimeedit.cpp @@ -10,15 +10,15 @@ #include <utility> #include "third_party/base/ptr_util.h" +#include "xfa/fwl/core/cfwl_datetimepicker.h" #include "xfa/fwl/core/cfwl_msgmouse.h" #include "xfa/fwl/core/cfwl_widgetmgr.h" -#include "xfa/fwl/core/ifwl_datetimepicker.h" CFWL_DateTimeEdit::CFWL_DateTimeEdit( const CFWL_App* app, std::unique_ptr<CFWL_WidgetProperties> properties, - IFWL_Widget* pOuter) - : IFWL_Edit(app, std::move(properties), pOuter) {} + CFWL_Widget* pOuter) + : CFWL_Edit(app, std::move(properties), pOuter) {} void CFWL_DateTimeEdit::OnProcessMessage(CFWL_Message* pMessage) { if (m_pWidgetMgr->IsFormDisabled()) { @@ -29,7 +29,7 @@ void CFWL_DateTimeEdit::OnProcessMessage(CFWL_Message* pMessage) { CFWL_MessageType dwHashCode = pMessage->GetClassID(); if (dwHashCode == CFWL_MessageType::SetFocus || dwHashCode == CFWL_MessageType::KillFocus) { - IFWL_Widget* pOuter = GetOuter(); + CFWL_Widget* pOuter = GetOuter(); pOuter->GetDelegate()->OnProcessMessage(pMessage); } } @@ -38,7 +38,7 @@ void CFWL_DateTimeEdit::DisForm_OnProcessMessage(CFWL_Message* pMessage) { CFWL_MessageType dwHashCode = pMessage->GetClassID(); if (!m_pWidgetMgr->IsFormDisabled() || dwHashCode != CFWL_MessageType::Mouse) { - IFWL_Edit::OnProcessMessage(pMessage); + CFWL_Edit::OnProcessMessage(pMessage); return; } @@ -48,8 +48,8 @@ void CFWL_DateTimeEdit::DisForm_OnProcessMessage(CFWL_Message* pMessage) { if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused; - IFWL_DateTimePicker* pDateTime = - static_cast<IFWL_DateTimePicker*>(m_pOuter); + CFWL_DateTimePicker* pDateTime = + static_cast<CFWL_DateTimePicker*>(m_pOuter); if (pDateTime->IsMonthCalendarVisible()) { CFX_RectF rtInvalidate; pDateTime->GetWidgetRect(rtInvalidate); @@ -58,5 +58,5 @@ void CFWL_DateTimeEdit::DisForm_OnProcessMessage(CFWL_Message* pMessage) { pDateTime->Repaint(&rtInvalidate); } } - IFWL_Edit::OnProcessMessage(pMessage); + CFWL_Edit::OnProcessMessage(pMessage); } diff --git a/xfa/fwl/core/cfwl_datetimeedit.h b/xfa/fwl/core/cfwl_datetimeedit.h index 68efd2e13a..15fea74286 100644 --- a/xfa/fwl/core/cfwl_datetimeedit.h +++ b/xfa/fwl/core/cfwl_datetimeedit.h @@ -9,18 +9,18 @@ #include <memory> +#include "xfa/fwl/core/cfwl_edit.h" +#include "xfa/fwl/core/cfwl_widget.h" #include "xfa/fwl/core/cfwl_widgetproperties.h" #include "xfa/fwl/core/fwl_error.h" -#include "xfa/fwl/core/ifwl_edit.h" -#include "xfa/fwl/core/ifwl_widget.h" -class CFWL_DateTimeEdit : public IFWL_Edit { +class CFWL_DateTimeEdit : public CFWL_Edit { public: CFWL_DateTimeEdit(const CFWL_App* app, std::unique_ptr<CFWL_WidgetProperties> properties, - IFWL_Widget* pOuter); + CFWL_Widget* pOuter); - // IFWL_Edit. + // CFWL_Edit. void OnProcessMessage(CFWL_Message* pMessage) override; private: diff --git a/xfa/fwl/core/cfwl_datetimepicker.cpp b/xfa/fwl/core/cfwl_datetimepicker.cpp index 98aae94fc3..142daf5fe4 100644 --- a/xfa/fwl/core/cfwl_datetimepicker.cpp +++ b/xfa/fwl/core/cfwl_datetimepicker.cpp @@ -7,66 +7,652 @@ #include "xfa/fwl/core/cfwl_datetimepicker.h" #include <memory> +#include <utility> #include "third_party/base/ptr_util.h" -#include "xfa/fwl/core/fwl_error.h" -#include "xfa/fwl/core/ifwl_datetimepicker.h" -#include "xfa/fwl/core/ifwl_widget.h" +#include "xfa/fwl/core/cfwl_evteditchanged.h" +#include "xfa/fwl/core/cfwl_evtselectchanged.h" +#include "xfa/fwl/core/cfwl_formproxy.h" +#include "xfa/fwl/core/cfwl_msgmouse.h" +#include "xfa/fwl/core/cfwl_msgsetfocus.h" +#include "xfa/fwl/core/cfwl_notedriver.h" +#include "xfa/fwl/core/cfwl_spinbutton.h" +#include "xfa/fwl/core/cfwl_themebackground.h" +#include "xfa/fwl/core/cfwl_widgetmgr.h" +#include "xfa/fwl/core/ifwl_themeprovider.h" namespace { -IFWL_DateTimePicker* ToDateTimePicker(IFWL_Widget* widget) { - return static_cast<IFWL_DateTimePicker*>(widget); -} +const int kDateTimePickerWidth = 100; +const int kDateTimePickerHeight = 20; } // namespace - CFWL_DateTimePicker::CFWL_DateTimePicker(const CFWL_App* app) - : CFWL_Widget(app) {} + : CFWL_Widget(app, pdfium::MakeUnique<CFWL_WidgetProperties>(), nullptr), + m_iBtnState(1), + m_iYear(-1), + m_iMonth(-1), + m_iDay(-1), + m_bLBtnDown(false) { + m_rtBtn.Set(0, 0, 0, 0); -CFWL_DateTimePicker::~CFWL_DateTimePicker() {} + m_pProperties->m_dwStyleExes = FWL_STYLEEXT_DTP_ShortDateFormat; -void CFWL_DateTimePicker::Initialize() { - ASSERT(!m_pIface); + auto monthProp = pdfium::MakeUnique<CFWL_WidgetProperties>(); + monthProp->m_dwStyles = FWL_WGTSTYLE_Popup | FWL_WGTSTYLE_Border; + monthProp->m_dwStates = FWL_WGTSTATE_Invisible; + monthProp->m_pParent = this; + monthProp->m_pThemeProvider = m_pProperties->m_pThemeProvider; + m_pMonthCal.reset( + new CFWL_MonthCalendar(m_pOwnerApp, std::move(monthProp), this)); - m_pIface = pdfium::MakeUnique<IFWL_DateTimePicker>( - m_pApp, pdfium::MakeUnique<CFWL_WidgetProperties>()); + CFX_RectF rtMonthCal; + m_pMonthCal->GetWidgetRect(rtMonthCal, true); + rtMonthCal.Set(0, 0, rtMonthCal.width, rtMonthCal.height); + m_pMonthCal->SetWidgetRect(rtMonthCal); - CFWL_Widget::Initialize(); + auto editProp = pdfium::MakeUnique<CFWL_WidgetProperties>(); + editProp->m_pParent = this; + editProp->m_pThemeProvider = m_pProperties->m_pThemeProvider; + + m_pEdit.reset(new CFWL_DateTimeEdit(m_pOwnerApp, std::move(editProp), this)); + RegisterEventTarget(m_pMonthCal.get()); + RegisterEventTarget(m_pEdit.get()); } -int32_t CFWL_DateTimePicker::CountSelRanges() { - return ToDateTimePicker(GetWidget())->CountSelRanges(); +CFWL_DateTimePicker::~CFWL_DateTimePicker() { + UnregisterEventTarget(); } -int32_t CFWL_DateTimePicker::GetSelRange(int32_t nIndex, int32_t& nStart) { - return ToDateTimePicker(GetWidget())->GetSelRange(nIndex, nStart); +FWL_Type CFWL_DateTimePicker::GetClassID() const { + return FWL_Type::DateTimePicker; } -void CFWL_DateTimePicker::GetEditText(CFX_WideString& wsText) { - ToDateTimePicker(GetWidget())->GetEditText(wsText); +void CFWL_DateTimePicker::GetWidgetRect(CFX_RectF& rect, bool bAutoSize) { + if (m_pWidgetMgr->IsFormDisabled()) { + DisForm_GetWidgetRect(rect, bAutoSize); + return; + } + if (!bAutoSize) { + rect = m_pProperties->m_rtWidget; + return; + } + + rect.Set(0, 0, kDateTimePickerWidth, kDateTimePickerHeight); + CFWL_Widget::GetWidgetRect(rect, true); } -void CFWL_DateTimePicker::SetEditText(const CFX_WideString& wsText) { - ToDateTimePicker(GetWidget())->SetEditText(wsText); +void CFWL_DateTimePicker::Update() { + if (m_pWidgetMgr->IsFormDisabled()) { + DisForm_Update(); + return; + } + if (m_iLock) + return; + 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; + + 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); + + 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_WidgetHit CFWL_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 (IsMonthCalendarVisible()) { + CFX_RectF rect; + m_pMonthCal->GetWidgetRect(rect); + if (rect.Contains(fx, fy)) + return FWL_WidgetHit::Client; + } + return FWL_WidgetHit::Unknown; +} + +void CFWL_DateTimePicker::DrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) { + if (!pGraphics) + return; + if (!m_pProperties->m_pThemeProvider) + return; + + 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()) { + DisForm_DrawWidget(pGraphics, pMatrix); + return; + } +} + +void CFWL_DateTimePicker::SetThemeProvider(IFWL_ThemeProvider* pTP) { + m_pProperties->m_pThemeProvider = pTP; + m_pMonthCal->SetThemeProvider(pTP); +} + +void CFWL_DateTimePicker::GetCurSel(int32_t& iYear, + int32_t& iMonth, + int32_t& iDay) { + iYear = m_iYear; + iMonth = m_iMonth; + iDay = m_iDay; } void CFWL_DateTimePicker::SetCurSel(int32_t iYear, int32_t iMonth, int32_t iDay) { - ToDateTimePicker(GetWidget())->SetCurSel(iYear, iMonth, iDay); + if (iYear <= 0 || iYear >= 3000) + return; + if (iMonth <= 0 || iMonth >= 13) + return; + if (iDay <= 0 || iDay >= 32) + return; + + m_iYear = iYear; + m_iMonth = iMonth; + m_iDay = iDay; + m_pMonthCal->SetSelect(iYear, iMonth, iDay); } -void CFWL_DateTimePicker::GetBBox(CFX_RectF& rect) { - ToDateTimePicker(GetWidget())->GetBBox(rect); +void CFWL_DateTimePicker::SetEditText(const CFX_WideString& wsText) { + if (!m_pEdit) + return; + + m_pEdit->SetText(wsText); + Repaint(&m_rtClient); + + CFWL_EvtEditChanged ev; + DispatchEvent(&ev); } -void CFWL_DateTimePicker::SetEditLimit(int32_t nLimit) { - ToDateTimePicker(GetWidget())->SetEditLimit(nLimit); +void CFWL_DateTimePicker::GetEditText(CFX_WideString& wsText, + int32_t nStart, + int32_t nCount) const { + if (m_pEdit) + m_pEdit->GetText(wsText, nStart, nCount); +} + +void CFWL_DateTimePicker::GetBBox(CFX_RectF& rect) const { + if (m_pWidgetMgr->IsFormDisabled()) { + DisForm_GetBBox(rect); + return; + } + + rect = m_pProperties->m_rtWidget; + if (IsMonthCalendarVisible()) { + CFX_RectF rtMonth; + m_pMonthCal->GetWidgetRect(rtMonth); + rtMonth.Offset(m_pProperties->m_rtWidget.left, + m_pProperties->m_rtWidget.top); + rect.Union(rtMonth); + } } void CFWL_DateTimePicker::ModifyEditStylesEx(uint32_t dwStylesExAdded, uint32_t dwStylesExRemoved) { - ToDateTimePicker(GetWidget()) - ->ModifyEditStylesEx(dwStylesExAdded, dwStylesExRemoved); + m_pEdit->ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved); +} + +void CFWL_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) { + return; + } + + 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 CFWL_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); + } +} + +void CFWL_DateTimePicker::ShowMonthCalendar(bool bActivate) { + if (m_pWidgetMgr->IsFormDisabled()) + return DisForm_ShowMonthCalendar(bActivate); + if (IsMonthCalendarVisible() == bActivate) + return; + if (!m_pForm) + InitProxyForm(); + + if (!bActivate) { + m_pForm->EndDoModal(); + return; + } + + 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(); +} + +bool CFWL_DateTimePicker::IsMonthCalendarVisible() const { + if (m_pWidgetMgr->IsFormDisabled()) + return DisForm_IsMonthCalendarVisible(); + if (!m_pForm) + return false; + return !(m_pForm->GetStates() & FWL_WGTSTATE_Invisible); +} + +void CFWL_DateTimePicker::ResetEditAlignment() { + if (!m_pEdit) + return; + + uint32_t dwAdd = 0; + switch (m_pProperties->m_dwStyleExes & 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; + break; + } + } + switch (m_pProperties->m_dwStyleExes & 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; + break; + } + } + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_EditJustified) + dwAdd |= FWL_STYLEEXT_EDT_Justified; + if (m_pProperties->m_dwStyleExes & 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 CFWL_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_EvtSelectChanged ev; + ev.m_pSrcTarget = this; + ev.iYear = m_iYear; + ev.iMonth = m_iMonth; + ev.iDay = m_iDay; + DispatchEvent(&ev); +} + +void CFWL_DateTimePicker::InitProxyForm() { + if (m_pForm) + return; + if (!m_pMonthCal) + return; + + auto prop = pdfium::MakeUnique<CFWL_WidgetProperties>(); + prop->m_dwStyles = FWL_WGTSTYLE_Popup; + prop->m_dwStates = FWL_WGTSTATE_Invisible; + prop->m_pOwner = this; + + m_pForm = pdfium::MakeUnique<CFWL_FormProxy>(m_pOwnerApp, std::move(prop), + m_pMonthCal.get()); + m_pMonthCal->SetParent(m_pForm.get()); +} + +bool CFWL_DateTimePicker::DisForm_IsMonthCalendarVisible() const { + if (!m_pMonthCal) + return false; + return !(m_pMonthCal->GetStates() & FWL_WGTSTATE_Invisible); +} + +void CFWL_DateTimePicker::DisForm_ShowMonthCalendar(bool bActivate) { + if (IsMonthCalendarVisible() == 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(); + m_pEdit->GetDelegate()->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 CFWL_DateTimePicker::DisForm_HitTest(FX_FLOAT fx, + FX_FLOAT fy) const { + 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 (IsMonthCalendarVisible()) { + m_pMonthCal->GetWidgetRect(rect); + if (rect.Contains(fx, fy)) + return FWL_WidgetHit::Client; + } + return FWL_WidgetHit::Unknown; +} + +bool CFWL_DateTimePicker::DisForm_IsNeedShowButton() const { + return m_pProperties->m_dwStates & FWL_WGTSTATE_Focused || + m_pMonthCal->GetStates() & FWL_WGTSTATE_Focused || + m_pEdit->GetStates() & FWL_WGTSTATE_Focused; +} + +void CFWL_DateTimePicker::DisForm_Update() { + if (m_iLock) + return; + 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); + + FX_FLOAT* pWidth = static_cast<FX_FLOAT*>( + GetThemeCapacity(CFWL_WidgetCapacity::ScrollBarWidth)); + if (!pWidth) + return; + + 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(); +} + +void CFWL_DateTimePicker::DisForm_GetWidgetRect(CFX_RectF& rect, + bool bAutoSize) { + rect = m_pProperties->m_rtWidget; + if (DisForm_IsNeedShowButton()) + rect.width += m_fBtn; +} + +void CFWL_DateTimePicker::DisForm_GetBBox(CFX_RectF& rect) const { + rect = m_pProperties->m_rtWidget; + if (DisForm_IsNeedShowButton()) + rect.width += m_fBtn; + if (!IsMonthCalendarVisible()) + return; + + CFX_RectF rtMonth; + m_pMonthCal->GetWidgetRect(rtMonth); + rtMonth.Offset(m_pProperties->m_rtWidget.left, m_pProperties->m_rtWidget.top); + rect.Union(rtMonth); +} + +void CFWL_DateTimePicker::DisForm_DrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) { + if (!pGraphics) + return; + 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 (!IsMonthCalendarVisible()) + return; + + 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); +} + +void CFWL_DateTimePicker::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_pEdit->GetStates() & FWL_WGTSTATE_Focused) { + m_pEdit->GetDelegate()->OnProcessMessage(pMessage); + return; + } + break; + } + default: + break; + } + + CFWL_Widget::OnProcessMessage(pMessage); +} + +void CFWL_DateTimePicker::OnDrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) { + DrawWidget(pGraphics, pMatrix); +} + +void CFWL_DateTimePicker::OnFocusChanged(CFWL_Message* pMsg, bool bSet) { + if (!pMsg) + return; + if (m_pWidgetMgr->IsFormDisabled()) + return DisForm_OnFocusChanged(pMsg, bSet); + + if (bSet) { + m_pProperties->m_dwStates |= (FWL_WGTSTATE_Focused); + Repaint(&m_rtClient); + } else { + m_pProperties->m_dwStates &= ~(FWL_WGTSTATE_Focused); + Repaint(&m_rtClient); + } + if (pMsg->m_pSrcTarget == m_pMonthCal.get() && IsMonthCalendarVisible()) { + ShowMonthCalendar(false); + } + Repaint(&m_rtClient); +} + +void CFWL_DateTimePicker::OnLButtonDown(CFWL_MsgMouse* pMsg) { + if (!pMsg) + return; + if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) + SetFocus(true); + if (!m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) + return; + + if (IsMonthCalendarVisible()) { + ShowMonthCalendar(false); + return; + } + if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_TimeFormat)) + ShowMonthCalendar(true); + + m_bLBtnDown = true; + Repaint(&m_rtClient); +} + +void CFWL_DateTimePicker::OnLButtonUp(CFWL_MsgMouse* pMsg) { + if (!pMsg) + return; + + m_bLBtnDown = false; + if (m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) + m_iBtnState = CFWL_PartState_Hovered; + else + m_iBtnState = CFWL_PartState_Normal; + Repaint(&m_rtBtn); +} + +void CFWL_DateTimePicker::OnMouseMove(CFWL_MsgMouse* pMsg) { + if (!m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) + m_iBtnState = CFWL_PartState_Normal; + Repaint(&m_rtBtn); +} + +void CFWL_DateTimePicker::OnMouseLeave(CFWL_MsgMouse* pMsg) { + if (!pMsg) + return; + m_iBtnState = CFWL_PartState_Normal; + Repaint(&m_rtBtn); +} + +void CFWL_DateTimePicker::DisForm_OnFocusChanged(CFWL_Message* pMsg, + bool bSet) { + CFX_RectF rtInvalidate(m_rtBtn); + if (bSet) { + m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused; + if (m_pEdit && !(m_pEdit->GetStylesEx() & FWL_STYLEEXT_EDT_ReadOnly)) { + m_rtBtn.Set(m_pProperties->m_rtWidget.width, 0, m_fBtn, + m_pProperties->m_rtWidget.height - 1); + } + rtInvalidate = m_rtBtn; + pMsg->m_pDstTarget = m_pEdit.get(); + m_pEdit->GetDelegate()->OnProcessMessage(pMsg); + } else { + m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused; + m_rtBtn.Set(0, 0, 0, 0); + if (DisForm_IsMonthCalendarVisible()) + ShowMonthCalendar(false); + if (m_pEdit->GetStates() & FWL_WGTSTATE_Focused) { + pMsg->m_pSrcTarget = m_pEdit.get(); + m_pEdit->GetDelegate()->OnProcessMessage(pMsg); + } + } + rtInvalidate.Inflate(2, 2); + Repaint(&rtInvalidate); } diff --git a/xfa/fwl/core/cfwl_datetimepicker.h b/xfa/fwl/core/cfwl_datetimepicker.h index 08e092e12a..c5dd0ae45c 100644 --- a/xfa/fwl/core/cfwl_datetimepicker.h +++ b/xfa/fwl/core/cfwl_datetimepicker.h @@ -7,26 +7,112 @@ #ifndef XFA_FWL_CORE_CFWL_DATETIMEPICKER_H_ #define XFA_FWL_CORE_CFWL_DATETIMEPICKER_H_ +#include <memory> + +#include "xfa/fwl/core/cfwl_datetimeedit.h" +#include "xfa/fwl/core/cfwl_event.h" +#include "xfa/fwl/core/cfwl_monthcalendar.h" #include "xfa/fwl/core/cfwl_widget.h" -#include "xfa/fwl/core/ifwl_datetimepicker.h" +#include "xfa/fwl/core/cfwl_widgetproperties.h" + +#define FWL_STYLEEXT_DTP_AllowEdit (1L << 0) +#define FWL_STYLEEXT_DTP_LongDateFormat (0L << 1) +#define FWL_STYLEEXT_DTP_ShortDateFormat (1L << 1) +#define FWL_STYLEEXT_DTP_TimeFormat (2L << 1) +#define FWL_STYLEEXT_DTP_Spin (1L << 3) +#define FWL_STYLEEXT_DTP_EditHNear (0L << 4) +#define FWL_STYLEEXT_DTP_EditHCenter (1L << 4) +#define FWL_STYLEEXT_DTP_EditHFar (2L << 4) +#define FWL_STYLEEXT_DTP_EditVNear (0L << 6) +#define FWL_STYLEEXT_DTP_EditVCenter (1L << 6) +#define FWL_STYLEEXT_DTP_EditVFar (2L << 6) +#define FWL_STYLEEXT_DTP_EditJustified (1L << 8) +#define FWL_STYLEEXT_DTP_EditDistributed (2L << 8) +#define FWL_STYLEEXT_DTP_EditHAlignMask (3L << 4) +#define FWL_STYLEEXT_DTP_EditVAlignMask (3L << 6) +#define FWL_STYLEEXT_DTP_EditHAlignModeMask (3L << 8) + +class CFWL_DateTimeEdit; +class CFWL_FormProxy; class CFWL_DateTimePicker : public CFWL_Widget { public: explicit CFWL_DateTimePicker(const CFWL_App* pApp); ~CFWL_DateTimePicker() override; - void Initialize(); + // CFWL_Widget + FWL_Type GetClassID() const override; + void GetWidgetRect(CFX_RectF& rect, bool bAutoSize = false) override; + void Update() override; + FWL_WidgetHit HitTest(FX_FLOAT fx, FX_FLOAT fy) override; + void DrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix = nullptr) override; + void SetThemeProvider(IFWL_ThemeProvider* pTP) override; + void OnProcessMessage(CFWL_Message* pMessage) override; + void OnDrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) override; + + void GetCurSel(int32_t& iYear, int32_t& iMonth, int32_t& iDay); + void SetCurSel(int32_t iYear, int32_t iMonth, int32_t iDay); - void GetEditText(CFX_WideString& wsText); void SetEditText(const CFX_WideString& wsText); + void GetEditText(CFX_WideString& wsText, + int32_t nStart = 0, + int32_t nCount = -1) const; - int32_t CountSelRanges(); - int32_t GetSelRange(int32_t nIndex, int32_t& nStart); + int32_t CountSelRanges() const { return m_pEdit->CountSelRanges(); } + int32_t GetSelRange(int32_t nIndex, int32_t& nStart) const { + return m_pEdit->GetSelRange(nIndex, nStart); + } - void SetCurSel(int32_t iYear, int32_t iMonth, int32_t iDay); - void GetBBox(CFX_RectF& rect); - void SetEditLimit(int32_t nLimit); + void GetBBox(CFX_RectF& rect) const; + void SetEditLimit(int32_t nLimit) { m_pEdit->SetLimit(nLimit); } void ModifyEditStylesEx(uint32_t dwStylesExAdded, uint32_t dwStylesExRemoved); + + bool IsMonthCalendarVisible() const; + void ShowMonthCalendar(bool bActivate); + void ProcessSelChanged(int32_t iYear, int32_t iMonth, int32_t iDay); + + CFWL_FormProxy* GetFormProxy() const { return m_pForm.get(); } + + private: + void DrawDropDownButton(CFX_Graphics* pGraphics, + IFWL_ThemeProvider* pTheme, + const CFX_Matrix* pMatrix); + void FormatDateString(int32_t iYear, + int32_t iMonth, + int32_t iDay, + CFX_WideString& wsText); + void ResetEditAlignment(); + void InitProxyForm(); + + bool DisForm_IsMonthCalendarVisible() const; + void DisForm_ShowMonthCalendar(bool bActivate); + FWL_WidgetHit DisForm_HitTest(FX_FLOAT fx, FX_FLOAT fy) const; + bool DisForm_IsNeedShowButton() const; + void DisForm_Update(); + void DisForm_GetWidgetRect(CFX_RectF& rect, bool bAutoSize = false); + void DisForm_GetBBox(CFX_RectF& rect) const; + void DisForm_DrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix = nullptr); + void DisForm_OnFocusChanged(CFWL_Message* pMsg, bool bSet); + void OnFocusChanged(CFWL_Message* pMsg, bool bSet); + void OnLButtonDown(CFWL_MsgMouse* pMsg); + void OnLButtonUp(CFWL_MsgMouse* pMsg); + void OnMouseMove(CFWL_MsgMouse* pMsg); + void OnMouseLeave(CFWL_MsgMouse* pMsg); + + CFX_RectF m_rtBtn; + CFX_RectF m_rtClient; + int32_t m_iBtnState; + int32_t m_iYear; + int32_t m_iMonth; + int32_t m_iDay; + bool m_bLBtnDown; + std::unique_ptr<CFWL_DateTimeEdit> m_pEdit; + std::unique_ptr<CFWL_MonthCalendar> m_pMonthCal; + std::unique_ptr<CFWL_FormProxy> m_pForm; + FX_FLOAT m_fBtn; }; #endif // XFA_FWL_CORE_CFWL_DATETIMEPICKER_H_ diff --git a/xfa/fwl/core/cfwl_edit.cpp b/xfa/fwl/core/cfwl_edit.cpp index e404b1de6a..99cac68d57 100644 --- a/xfa/fwl/core/cfwl_edit.cpp +++ b/xfa/fwl/core/cfwl_edit.cpp @@ -6,67 +6,1656 @@ #include "xfa/fwl/core/cfwl_edit.h" +#include <algorithm> #include <memory> +#include <utility> #include <vector> #include "third_party/base/ptr_util.h" +#include "third_party/base/stl_util.h" +#include "xfa/fde/cfde_txtedtengine.h" +#include "xfa/fde/fde_gedevice.h" +#include "xfa/fde/fde_render.h" +#include "xfa/fde/ifde_txtedtpage.h" +#include "xfa/fgas/font/cfgas_gefont.h" +#include "xfa/fwl/core/cfwl_app.h" +#include "xfa/fwl/core/cfwl_caret.h" +#include "xfa/fwl/core/cfwl_evtcheckword.h" +#include "xfa/fwl/core/cfwl_evttextchanged.h" +#include "xfa/fwl/core/cfwl_evttextfull.h" +#include "xfa/fwl/core/cfwl_evtvalidate.h" +#include "xfa/fwl/core/cfwl_msgkey.h" +#include "xfa/fwl/core/cfwl_msgmouse.h" +#include "xfa/fwl/core/cfwl_themebackground.h" +#include "xfa/fwl/core/cfwl_themepart.h" +#include "xfa/fwl/core/cfwl_widgetmgr.h" +#include "xfa/fwl/core/ifwl_themeprovider.h" +#include "xfa/fxfa/xfa_ffdoc.h" +#include "xfa/fxfa/xfa_ffwidget.h" +#include "xfa/fxgraphics/cfx_path.h" namespace { -IFWL_Edit* ToEdit(IFWL_Widget* widget) { - return static_cast<IFWL_Edit*>(widget); +const int kEditMargin = 3; + +bool FX_EDIT_ISLATINWORD(FX_WCHAR c) { + return c == 0x2D || (c <= 0x005A && c >= 0x0041) || + (c <= 0x007A && c >= 0x0061) || (c <= 0x02AF && c >= 0x00C0) || + c == 0x0027; +} + +void AddSquigglyPath(CFX_Path* pPathData, + FX_FLOAT fStartX, + FX_FLOAT fEndX, + FX_FLOAT fY, + FX_FLOAT fStep) { + pPathData->MoveTo(fStartX, fY); + int i = 1; + for (FX_FLOAT fx = fStartX + fStep; fx < fEndX; fx += fStep, ++i) + pPathData->LineTo(fx, fY + (i & 1) * fStep); } } // namespace -CFWL_Edit::CFWL_Edit(const CFWL_App* app) : CFWL_Widget(app) {} +CFWL_Edit::CFWL_Edit(const CFWL_App* app, + std::unique_ptr<CFWL_WidgetProperties> properties, + CFWL_Widget* pOuter) + : CFWL_Widget(app, std::move(properties), pOuter), + m_fVAlignOffset(0.0f), + m_fScrollOffsetX(0.0f), + m_fScrollOffsetY(0.0f), + m_bLButtonDown(false), + m_nSelStart(0), + m_nLimit(-1), + m_fFontSize(0), + m_bSetRange(false), + m_iMax(0xFFFFFFF), + m_iCurRecord(-1), + m_iMaxRecord(128) { + m_rtClient.Reset(); + m_rtEngine.Reset(); + m_rtStatic.Reset(); + + InitCaret(); +} + +CFWL_Edit::~CFWL_Edit() { + if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) + ShowCaret(false); + ClearRecord(); +} + +FWL_Type CFWL_Edit::GetClassID() const { + return FWL_Type::Edit; +} + +void CFWL_Edit::GetWidgetRect(CFX_RectF& rect, bool bAutoSize) { + if (!bAutoSize) { + rect = m_pProperties->m_rtWidget; + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) { + if (IsShowScrollBar(true)) { + FX_FLOAT* pfWidth = static_cast<FX_FLOAT*>( + GetThemeCapacity(CFWL_WidgetCapacity::ScrollBarWidth)); + rect.width += *pfWidth; + rect.width += kEditMargin; + } + if (IsShowScrollBar(false)) { + FX_FLOAT* pfWidth = static_cast<FX_FLOAT*>( + GetThemeCapacity(CFWL_WidgetCapacity::ScrollBarWidth)); + rect.height += *pfWidth; + rect.height += kEditMargin; + } + } + return; + } + + rect.Set(0, 0, 0, 0); + + int32_t iTextLen = m_EdtEngine.GetTextLength(); + if (iTextLen > 0) { + CFX_WideString wsText; + m_EdtEngine.GetText(wsText, 0); + CFX_SizeF sz = CalcTextSize( + wsText, m_pProperties->m_pThemeProvider, + !!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine)); + rect.Set(0, 0, sz.x, sz.y); + } + CFWL_Widget::GetWidgetRect(rect, true); +} + +void CFWL_Edit::SetStates(uint32_t dwStates, bool bSet) { + if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Invisible) || + (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) { + ShowCaret(false); + } + CFWL_Widget::SetStates(dwStates, bSet); +} + +void CFWL_Edit::Update() { + if (IsLocked()) + return; + if (!m_pProperties->m_pThemeProvider) + m_pProperties->m_pThemeProvider = GetAvailableTheme(); + + Layout(); + if (m_rtClient.IsEmpty()) + return; + + UpdateEditEngine(); + UpdateVAlignment(); + UpdateScroll(); + InitCaret(); +} + +FWL_WidgetHit CFWL_Edit::HitTest(FX_FLOAT fx, FX_FLOAT fy) { + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) { + if (IsShowScrollBar(true)) { + CFX_RectF rect; + m_pVertScrollBar->GetWidgetRect(rect); + if (rect.Contains(fx, fy)) + return FWL_WidgetHit::VScrollBar; + } + if (IsShowScrollBar(false)) { + CFX_RectF rect; + m_pHorzScrollBar->GetWidgetRect(rect); + if (rect.Contains(fx, fy)) + return FWL_WidgetHit::HScrollBar; + } + } + if (m_rtClient.Contains(fx, fy)) + return FWL_WidgetHit::Edit; + return FWL_WidgetHit::Unknown; +} + +void CFWL_Edit::AddSpellCheckObj(CFX_Path& PathData, + int32_t nStart, + int32_t nCount, + FX_FLOAT fOffSetX, + FX_FLOAT fOffSetY) { + FX_FLOAT fStartX = 0.0f; + FX_FLOAT fEndX = 0.0f; + FX_FLOAT fY = 0.0f; + FX_FLOAT fStep = 0.0f; + IFDE_TxtEdtPage* pPage = m_EdtEngine.GetPage(0); + CFX_RectFArray rectArray; + CFX_RectF rectText; + const FDE_TXTEDTPARAMS* txtEdtParams = m_EdtEngine.GetEditParams(); + FX_FLOAT fAsent = static_cast<FX_FLOAT>(txtEdtParams->pFont->GetAscent()) * + txtEdtParams->fFontSize / 1000; + pPage->CalcRangeRectArray(nStart, nCount, rectArray); + + for (int i = 0; i < rectArray.GetSize(); i++) { + rectText = rectArray.GetAt(i); + fY = rectText.top + fAsent + fOffSetY; + fStep = txtEdtParams->fFontSize / 16.0f; + fStartX = rectText.left + fOffSetX; + fEndX = fStartX + rectText.Width(); + AddSquigglyPath(&PathData, fStartX, fEndX, fY, fStep); + } +} + +void CFWL_Edit::DrawSpellCheck(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) { + pGraphics->SaveGraphState(); + if (pMatrix) + pGraphics->ConcatMatrix(const_cast<CFX_Matrix*>(pMatrix)); + + CFX_Color crLine(0xFFFF0000); + CFWL_EvtCheckWord checkWordEvent; + checkWordEvent.m_pSrcTarget = this; + + CFX_ByteString sLatinWord; + CFX_Path pathSpell; + pathSpell.Create(); + + int32_t nStart = 0; + FX_FLOAT fOffSetX = m_rtEngine.left - m_fScrollOffsetX; + FX_FLOAT fOffSetY = m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset; + + CFX_WideString wsSpell; + GetText(wsSpell); + int32_t nContentLen = wsSpell.GetLength(); + for (int i = 0; i < nContentLen; i++) { + if (FX_EDIT_ISLATINWORD(wsSpell[i])) { + if (sLatinWord.IsEmpty()) + nStart = i; + sLatinWord += (FX_CHAR)wsSpell[i]; + continue; + } + checkWordEvent.bsWord = sLatinWord; + checkWordEvent.bCheckWord = true; + DispatchEvent(&checkWordEvent); -CFWL_Edit::~CFWL_Edit() {} + if (!sLatinWord.IsEmpty() && !checkWordEvent.bCheckWord) { + AddSpellCheckObj(pathSpell, nStart, sLatinWord.GetLength(), fOffSetX, + fOffSetY); + } + sLatinWord.clear(); + } -void CFWL_Edit::Initialize() { - ASSERT(!m_pIface); + checkWordEvent.bsWord = sLatinWord; + checkWordEvent.bCheckWord = true; + DispatchEvent(&checkWordEvent); - m_pIface = pdfium::MakeUnique<IFWL_Edit>( - m_pApp, pdfium::MakeUnique<CFWL_WidgetProperties>(), nullptr); + if (!sLatinWord.IsEmpty() && !checkWordEvent.bCheckWord) { + AddSpellCheckObj(pathSpell, nStart, sLatinWord.GetLength(), fOffSetX, + fOffSetY); + } + if (!pathSpell.IsEmpty()) { + CFX_RectF rtClip = m_rtEngine; + CFX_Matrix mt; + mt.Set(1, 0, 0, 1, fOffSetX, fOffSetY); + if (pMatrix) { + pMatrix->TransformRect(rtClip); + mt.Concat(*pMatrix); + } + pGraphics->SetClipRect(rtClip); + pGraphics->SetStrokeColor(&crLine); + pGraphics->SetLineWidth(0); + pGraphics->StrokePath(&pathSpell, nullptr); + } + pGraphics->RestoreGraphState(); +} + +void CFWL_Edit::DrawWidget(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix) { + if (!pGraphics) + return; + if (!m_pProperties->m_pThemeProvider) + return; + if (m_rtClient.IsEmpty()) + return; + + IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider; + if (!m_pWidgetMgr->IsFormDisabled()) + DrawTextBk(pGraphics, pTheme, pMatrix); + DrawContent(pGraphics, pTheme, pMatrix); + + if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) && + !(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly)) { + DrawSpellCheck(pGraphics, pMatrix); + } + if (HasBorder()) + DrawBorder(pGraphics, CFWL_Part::Border, pTheme, pMatrix); + if (HasEdge()) + DrawEdge(pGraphics, CFWL_Part::Edge, pTheme, pMatrix); +} - CFWL_Widget::Initialize(); +void CFWL_Edit::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) { + if (!pThemeProvider) + return; + if (m_pHorzScrollBar) + m_pHorzScrollBar->SetThemeProvider(pThemeProvider); + if (m_pVertScrollBar) + m_pVertScrollBar->SetThemeProvider(pThemeProvider); + if (m_pCaret) + m_pCaret->SetThemeProvider(pThemeProvider); + m_pProperties->m_pThemeProvider = pThemeProvider; } void CFWL_Edit::SetText(const CFX_WideString& wsText) { - if (GetWidget()) - ToEdit(GetWidget())->SetText(wsText); + m_EdtEngine.SetText(wsText); +} + +int32_t CFWL_Edit::GetTextLength() const { + return m_EdtEngine.GetTextLength(); } void CFWL_Edit::GetText(CFX_WideString& wsText, int32_t nStart, int32_t nCount) const { - if (GetWidget()) - ToEdit(GetWidget())->GetText(wsText, nStart, nCount); + m_EdtEngine.GetText(wsText, nStart, nCount); +} + +void CFWL_Edit::ClearText() { + m_EdtEngine.ClearText(); +} + +void CFWL_Edit::AddSelRange(int32_t nStart, int32_t nCount) { + m_EdtEngine.AddSelRange(nStart, nCount); } int32_t CFWL_Edit::CountSelRanges() const { - return GetWidget() ? ToEdit(GetWidget())->CountSelRanges() : 0; + return m_EdtEngine.CountSelRanges(); } int32_t CFWL_Edit::GetSelRange(int32_t nIndex, int32_t& nStart) const { - return GetWidget() ? ToEdit(GetWidget())->GetSelRange(nIndex, nStart) : 0; + return m_EdtEngine.GetSelRange(nIndex, nStart); +} + +void CFWL_Edit::ClearSelections() { + m_EdtEngine.ClearSelection(); } int32_t CFWL_Edit::GetLimit() const { - return GetWidget() ? ToEdit(GetWidget())->GetLimit() : -1; + return m_nLimit; } void CFWL_Edit::SetLimit(int32_t nLimit) { - if (GetWidget()) - ToEdit(GetWidget())->SetLimit(nLimit); + m_nLimit = nLimit; + m_EdtEngine.SetLimit(nLimit); } void CFWL_Edit::SetAliasChar(FX_WCHAR wAlias) { - if (GetWidget()) - ToEdit(GetWidget())->SetAliasChar(wAlias); + m_EdtEngine.SetAliasChar(wAlias); +} + +bool CFWL_Edit::Copy(CFX_WideString& wsCopy) { + int32_t nCount = m_EdtEngine.CountSelRanges(); + if (nCount == 0) + return false; + + wsCopy.clear(); + CFX_WideString wsTemp; + int32_t nStart, nLength; + for (int32_t i = 0; i < nCount; i++) { + nLength = m_EdtEngine.GetSelRange(i, nStart); + m_EdtEngine.GetText(wsTemp, nStart, nLength); + wsCopy += wsTemp; + wsTemp.clear(); + } + return true; +} + +bool CFWL_Edit::Cut(CFX_WideString& wsCut) { + int32_t nCount = m_EdtEngine.CountSelRanges(); + if (nCount == 0) + return false; + + wsCut.clear(); + CFX_WideString wsTemp; + int32_t nStart, nLength; + for (int32_t i = 0; i < nCount; i++) { + nLength = m_EdtEngine.GetSelRange(i, nStart); + m_EdtEngine.GetText(wsTemp, nStart, nLength); + wsCut += wsTemp; + wsTemp.clear(); + } + m_EdtEngine.Delete(0); + return true; +} + +bool CFWL_Edit::Paste(const CFX_WideString& wsPaste) { + int32_t nCaret = m_EdtEngine.GetCaretPos(); + int32_t iError = + m_EdtEngine.Insert(nCaret, wsPaste.c_str(), wsPaste.GetLength()); + if (iError < 0) { + ProcessInsertError(iError); + return false; + } + return true; +} + +bool CFWL_Edit::Redo(const IFDE_TxtEdtDoRecord* pRecord) { + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_NoRedoUndo) + return true; + return m_EdtEngine.Redo(pRecord); +} + +bool CFWL_Edit::Undo(const IFDE_TxtEdtDoRecord* pRecord) { + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_NoRedoUndo) + return true; + return m_EdtEngine.Undo(pRecord); +} + +bool CFWL_Edit::Undo() { + if (!CanUndo()) + return false; + return Undo(m_DoRecords[m_iCurRecord--].get()); +} + +bool CFWL_Edit::Redo() { + if (!CanRedo()) + return false; + return Redo(m_DoRecords[++m_iCurRecord].get()); +} + +bool CFWL_Edit::CanUndo() { + return m_iCurRecord >= 0; +} + +bool CFWL_Edit::CanRedo() { + return m_iCurRecord < pdfium::CollectionSize<int32_t>(m_DoRecords) - 1; +} + +void CFWL_Edit::SetOuter(CFWL_Widget* pOuter) { + m_pOuter = pOuter; +} + +void CFWL_Edit::On_CaretChanged(CFDE_TxtEdtEngine* pEdit, + int32_t nPage, + bool bVisible) { + if (m_rtEngine.IsEmpty()) + return; + if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) + return; + + bool bRepaintContent = UpdateOffset(); + UpdateCaret(); + CFX_RectF rtInvalid; + rtInvalid.Set(0, 0, 0, 0); + bool bRepaintScroll = false; + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine) { + CFWL_ScrollBar* pScroll = UpdateScroll(); + if (pScroll) { + pScroll->GetWidgetRect(rtInvalid); + bRepaintScroll = true; + } + } + if (bRepaintContent || bRepaintScroll) { + if (bRepaintContent) + rtInvalid.Union(m_rtEngine); + Repaint(&rtInvalid); + } +} + +void CFWL_Edit::On_TextChanged(CFDE_TxtEdtEngine* pEdit, + FDE_TXTEDT_TEXTCHANGE_INFO& ChangeInfo) { + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VAlignMask) + UpdateVAlignment(); + + CFX_RectF rtTemp; + GetClientRect(rtTemp); + + CFWL_EvtTextChanged event; + event.m_pSrcTarget = this; + event.nChangeType = ChangeInfo.nChangeType; + event.wsInsert = ChangeInfo.wsInsert; + event.wsDelete = ChangeInfo.wsDelete; + event.wsPrevText = ChangeInfo.wsPrevText; + DispatchEvent(&event); + + LayoutScrollBar(); + Repaint(&rtTemp); +} + +void CFWL_Edit::On_SelChanged(CFDE_TxtEdtEngine* pEdit) { + CFX_RectF rtTemp; + GetClientRect(rtTemp); + Repaint(&rtTemp); +} + +bool CFWL_Edit::On_PageLoad(CFDE_TxtEdtEngine* pEdit, + int32_t nPageIndex, + int32_t nPurpose) { + IFDE_TxtEdtPage* pPage = m_EdtEngine.GetPage(nPageIndex); + if (!pPage) + return false; + + pPage->LoadPage(nullptr, nullptr); + return true; +} + +bool CFWL_Edit::On_PageUnload(CFDE_TxtEdtEngine* pEdit, + int32_t nPageIndex, + int32_t nPurpose) { + IFDE_TxtEdtPage* pPage = m_EdtEngine.GetPage(nPageIndex); + if (!pPage) + return false; + + pPage->UnloadPage(nullptr); + return true; +} + +void CFWL_Edit::On_AddDoRecord(CFDE_TxtEdtEngine* pEdit, + IFDE_TxtEdtDoRecord* pRecord) { + AddDoRecord(pRecord); +} + +bool CFWL_Edit::On_Validate(CFDE_TxtEdtEngine* pEdit, CFX_WideString& wsText) { + CFWL_Widget* pDst = GetOuter(); + if (!pDst) + pDst = this; + + CFWL_EvtValidate event; + event.pDstWidget = pDst; + event.m_pSrcTarget = this; + event.wsInsert = wsText; + event.bValidate = true; + DispatchEvent(&event); + return event.bValidate; } void CFWL_Edit::SetScrollOffset(FX_FLOAT fScrollOffset) { - if (GetWidget()) - ToEdit(GetWidget())->SetScrollOffset(fScrollOffset); + m_fScrollOffsetY = fScrollOffset; +} + +void CFWL_Edit::DrawTextBk(CFX_Graphics* pGraphics, + IFWL_ThemeProvider* pTheme, + const CFX_Matrix* pMatrix) { + CFWL_ThemeBackground param; + param.m_pWidget = this; + param.m_iPart = CFWL_Part::Background; + param.m_bStaticBackground = false; + param.m_dwStates = m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly + ? CFWL_PartState_ReadOnly + : CFWL_PartState_Normal; + uint32_t dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled); + if (dwStates) + param.m_dwStates = CFWL_PartState_Disabled; + param.m_pGraphics = pGraphics; + param.m_matrix = *pMatrix; + param.m_rtPart = m_rtClient; + pTheme->DrawBackground(¶m); + + if (!IsShowScrollBar(true) || !IsShowScrollBar(false)) + return; + + CFX_RectF rtScorll; + m_pHorzScrollBar->GetWidgetRect(rtScorll); + + CFX_RectF rtStatic; + rtStatic.Set(m_rtClient.right() - rtScorll.height, + m_rtClient.bottom() - rtScorll.height, rtScorll.height, + rtScorll.height); + param.m_bStaticBackground = true; + param.m_bMaximize = true; + param.m_rtPart = rtStatic; + pTheme->DrawBackground(¶m); +} + +void CFWL_Edit::DrawContent(CFX_Graphics* pGraphics, + IFWL_ThemeProvider* pTheme, + const CFX_Matrix* pMatrix) { + IFDE_TxtEdtPage* pPage = m_EdtEngine.GetPage(0); + if (!pPage) + return; + + pGraphics->SaveGraphState(); + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_CombText) + pGraphics->SaveGraphState(); + + CFX_RectF rtClip = m_rtEngine; + FX_FLOAT fOffSetX = m_rtEngine.left - m_fScrollOffsetX; + FX_FLOAT fOffSetY = m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset; + CFX_Matrix mt; + mt.Set(1, 0, 0, 1, fOffSetX, fOffSetY); + if (pMatrix) { + pMatrix->TransformRect(rtClip); + mt.Concat(*pMatrix); + } + + bool bShowSel = (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_NoHideSel) || + (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused); + if (bShowSel) { + CFWL_Widget* pForm = m_pWidgetMgr->GetSystemFormWidget(this); + if (pForm) { + bShowSel = (pForm->GetStates() & FWL_WGTSTATE_Deactivated) != + FWL_WGTSTATE_Deactivated; + } + } + + int32_t nSelCount = m_EdtEngine.CountSelRanges(); + if (bShowSel && nSelCount > 0) { + int32_t nPageCharStart = pPage->GetCharStart(); + int32_t nPageCharCount = pPage->GetCharCount(); + int32_t nPageCharEnd = nPageCharStart + nPageCharCount - 1; + int32_t nCharCount; + int32_t nCharStart; + CFX_RectFArray rectArr; + int32_t i = 0; + for (i = 0; i < nSelCount; i++) { + nCharCount = m_EdtEngine.GetSelRange(i, nCharStart); + int32_t nCharEnd = nCharStart + nCharCount - 1; + if (nCharEnd < nPageCharStart || nCharStart > nPageCharEnd) + continue; + + int32_t nBgn = std::max(nCharStart, nPageCharStart); + int32_t nEnd = std::min(nCharEnd, nPageCharEnd); + pPage->CalcRangeRectArray(nBgn - nPageCharStart, nEnd - nBgn + 1, + rectArr); + } + + int32_t nCount = rectArr.GetSize(); + CFX_Path path; + path.Create(); + for (i = 0; i < nCount; i++) { + rectArr[i].left += fOffSetX; + rectArr[i].top += fOffSetY; + path.AddRectangle(rectArr[i].left, rectArr[i].top, rectArr[i].width, + rectArr[i].height); + } + pGraphics->SetClipRect(rtClip); + + CFWL_ThemeBackground param; + param.m_pGraphics = pGraphics; + param.m_matrix = *pMatrix; + param.m_pWidget = this; + param.m_iPart = CFWL_Part::Background; + param.m_pPath = &path; + pTheme->DrawBackground(¶m); + } + + CFX_RenderDevice* pRenderDev = pGraphics->GetRenderDevice(); + if (!pRenderDev) + return; + + std::unique_ptr<CFDE_RenderDevice> pRenderDevice( + new CFDE_RenderDevice(pRenderDev, false)); + std::unique_ptr<CFDE_RenderContext> pRenderContext(new CFDE_RenderContext); + pRenderDevice->SetClipRect(rtClip); + pRenderContext->StartRender(pRenderDevice.get(), pPage, mt); + pRenderContext->DoRender(nullptr); + + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_CombText) { + pGraphics->RestoreGraphState(); + CFX_Path path; + path.Create(); + int32_t iLimit = m_nLimit > 0 ? m_nLimit : 1; + FX_FLOAT fStep = m_rtEngine.width / iLimit; + FX_FLOAT fLeft = m_rtEngine.left + 1; + for (int32_t i = 1; i < iLimit; i++) { + fLeft += fStep; + path.AddLine(fLeft, m_rtClient.top, fLeft, m_rtClient.bottom()); + } + + CFWL_ThemeBackground param; + param.m_pGraphics = pGraphics; + param.m_matrix = *pMatrix; + param.m_pWidget = this; + param.m_iPart = CFWL_Part::CombTextLine; + param.m_pPath = &path; + pTheme->DrawBackground(¶m); + } + pGraphics->RestoreGraphState(); +} + +void CFWL_Edit::UpdateEditEngine() { + UpdateEditParams(); + UpdateEditLayout(); + if (m_nLimit > -1) + m_EdtEngine.SetLimit(m_nLimit); +} + +void CFWL_Edit::UpdateEditParams() { + FDE_TXTEDTPARAMS params; + params.nHorzScale = 100; + params.fPlateWidth = m_rtEngine.width; + params.fPlateHeight = m_rtEngine.height; + if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_RTLLayout) + params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_RTL; + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VerticalLayout) + params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_DocVertical; + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VerticalChars) + params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_CharVertial; + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReverseLine) + params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_LineReserve; + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ArabicShapes) + params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_ArabicShapes; + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ExpandTab) + params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_ExpandTab; + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_CombText) + params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_CombText; + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_LastLineHeight) + params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_LastLineHeight; + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_Validate) + params.dwMode |= FDE_TEXTEDITMODE_Validate; + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_Password) + params.dwMode |= FDE_TEXTEDITMODE_Password; + + switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HAlignMask) { + case FWL_STYLEEXT_EDT_HNear: { + params.dwAlignment |= FDE_TEXTEDITALIGN_Left; + break; + } + case FWL_STYLEEXT_EDT_HCenter: { + params.dwAlignment |= FDE_TEXTEDITALIGN_Center; + break; + } + case FWL_STYLEEXT_EDT_HFar: { + params.dwAlignment |= FDE_TEXTEDITALIGN_Right; + break; + } + default: + break; + } + switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HAlignModeMask) { + case FWL_STYLEEXT_EDT_Justified: { + params.dwAlignment |= FDE_TEXTEDITALIGN_Justified; + break; + } + case FWL_STYLEEXT_EDT_Distributed: { + params.dwAlignment |= FDE_TEXTEDITALIGN_Distributed; + break; + } + default: { + params.dwAlignment |= FDE_TEXTEDITALIGN_Normal; + break; + } + } + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine) { + params.dwMode |= FDE_TEXTEDITMODE_MultiLines; + if ((m_pProperties->m_dwStyles & FWL_WGTSTYLE_HScroll) == 0 && + (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_AutoHScroll) == 0) { + params.dwMode |= + FDE_TEXTEDITMODE_AutoLineWrap | FDE_TEXTEDITMODE_LimitArea_Horz; + } + if ((m_pProperties->m_dwStyles & FWL_WGTSTYLE_VScroll) == 0 && + (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_AutoVScroll) == 0) { + params.dwMode |= FDE_TEXTEDITMODE_LimitArea_Vert; + } else { + params.fPlateHeight = 0x00FFFFFF; + } + } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_AutoHScroll) == + 0) { + params.dwMode |= FDE_TEXTEDITMODE_LimitArea_Horz; + } + if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly) || + (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) { + params.dwMode |= FDE_TEXTEDITMODE_ReadOnly; + } + + FX_FLOAT* pFontSize = + static_cast<FX_FLOAT*>(GetThemeCapacity(CFWL_WidgetCapacity::FontSize)); + if (!pFontSize) + return; + + m_fFontSize = *pFontSize; + uint32_t* pFontColor = + static_cast<uint32_t*>(GetThemeCapacity(CFWL_WidgetCapacity::TextColor)); + if (!pFontColor) + return; + + params.dwFontColor = *pFontColor; + FX_FLOAT* pLineHeight = + static_cast<FX_FLOAT*>(GetThemeCapacity(CFWL_WidgetCapacity::LineHeight)); + if (!pLineHeight) + return; + + params.fLineSpace = *pLineHeight; + CFGAS_GEFont* pFont = + static_cast<CFGAS_GEFont*>(GetThemeCapacity(CFWL_WidgetCapacity::Font)); + if (!pFont) + return; + + params.pFont = pFont; + params.fFontSize = m_fFontSize; + params.nLineCount = (int32_t)(params.fPlateHeight / params.fLineSpace); + if (params.nLineCount <= 0) + params.nLineCount = 1; + params.fTabWidth = params.fFontSize * 1; + params.bTabEquidistant = true; + params.wLineBreakChar = L'\n'; + params.nCharRotation = 0; + params.pEventSink = this; + m_EdtEngine.SetEditParams(params); +} + +void CFWL_Edit::UpdateEditLayout() { + if (m_EdtEngine.GetTextLength() <= 0) + m_EdtEngine.SetTextByStream(nullptr); + + IFDE_TxtEdtPage* pPage = m_EdtEngine.GetPage(0); + if (pPage) + pPage->UnloadPage(nullptr); + + m_EdtEngine.StartLayout(); + m_EdtEngine.DoLayout(nullptr); + m_EdtEngine.EndLayout(); + pPage = m_EdtEngine.GetPage(0); + if (pPage) + pPage->LoadPage(nullptr, nullptr); +} + +bool CFWL_Edit::UpdateOffset() { + CFX_RectF rtCaret; + m_EdtEngine.GetCaretRect(rtCaret); + FX_FLOAT fOffSetX = m_rtEngine.left - m_fScrollOffsetX; + FX_FLOAT fOffSetY = m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset; + rtCaret.Offset(fOffSetX, fOffSetY); + const CFX_RectF& rtEidt = m_rtEngine; + if (rtEidt.Contains(rtCaret)) { + IFDE_TxtEdtPage* pPage = m_EdtEngine.GetPage(0); + if (!pPage) + return false; + + CFX_RectF rtFDE = pPage->GetContentsBox(); + rtFDE.Offset(fOffSetX, fOffSetY); + if (rtFDE.right() < rtEidt.right() && m_fScrollOffsetX > 0) { + m_fScrollOffsetX += rtFDE.right() - rtEidt.right(); + m_fScrollOffsetX = std::max(m_fScrollOffsetX, 0.0f); + } + if (rtFDE.bottom() < rtEidt.bottom() && m_fScrollOffsetY > 0) { + m_fScrollOffsetY += rtFDE.bottom() - rtEidt.bottom(); + m_fScrollOffsetY = std::max(m_fScrollOffsetY, 0.0f); + } + return false; + } + + FX_FLOAT offsetX = 0.0; + FX_FLOAT offsetY = 0.0; + if (rtCaret.left < rtEidt.left) + offsetX = rtCaret.left - rtEidt.left; + if (rtCaret.right() > rtEidt.right()) + offsetX = rtCaret.right() - rtEidt.right(); + if (rtCaret.top < rtEidt.top) + offsetY = rtCaret.top - rtEidt.top; + if (rtCaret.bottom() > rtEidt.bottom()) + offsetY = rtCaret.bottom() - rtEidt.bottom(); + m_fScrollOffsetX += offsetX; + m_fScrollOffsetY += offsetY; + if (m_fFontSize > m_rtEngine.height) + m_fScrollOffsetY = 0; + return true; +} + +bool CFWL_Edit::UpdateOffset(CFWL_ScrollBar* pScrollBar, FX_FLOAT fPosChanged) { + if (pScrollBar == m_pHorzScrollBar.get()) + m_fScrollOffsetX += fPosChanged; + else + m_fScrollOffsetY += fPosChanged; + return true; +} + +void CFWL_Edit::UpdateVAlignment() { + IFDE_TxtEdtPage* pPage = m_EdtEngine.GetPage(0); + if (!pPage) + return; + + const CFX_RectF& rtFDE = pPage->GetContentsBox(); + FX_FLOAT fOffsetY = 0.0f; + FX_FLOAT fSpaceAbove = 0.0f; + FX_FLOAT fSpaceBelow = 0.0f; + CFX_SizeF* pSpace = static_cast<CFX_SizeF*>( + GetThemeCapacity(CFWL_WidgetCapacity::SpaceAboveBelow)); + if (pSpace) { + fSpaceAbove = pSpace->x; + fSpaceBelow = pSpace->y; + } + if (fSpaceAbove < 0.1f) + fSpaceAbove = 0; + if (fSpaceBelow < 0.1f) + fSpaceBelow = 0; + + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VCenter) { + fOffsetY = (m_rtEngine.height - rtFDE.height) / 2; + if (fOffsetY < (fSpaceAbove + fSpaceBelow) / 2 && + fSpaceAbove < fSpaceBelow) { + return; + } + fOffsetY += (fSpaceAbove - fSpaceBelow) / 2; + } else if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VFar) { + fOffsetY = (m_rtEngine.height - rtFDE.height); + fOffsetY -= fSpaceBelow; + } else { + fOffsetY += fSpaceAbove; + } + m_fVAlignOffset = std::max(fOffsetY, 0.0f); +} + +void CFWL_Edit::UpdateCaret() { + CFX_RectF rtFDE; + m_EdtEngine.GetCaretRect(rtFDE); + + rtFDE.Offset(m_rtEngine.left - m_fScrollOffsetX, + m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset); + CFX_RectF rtCaret; + rtCaret.Set(rtFDE.left, rtFDE.top, rtFDE.width, rtFDE.height); + + CFX_RectF rtClient; + GetClientRect(rtClient); + rtCaret.Intersect(rtClient); + + if (rtCaret.left > rtClient.right()) { + FX_FLOAT right = rtCaret.right(); + rtCaret.left = rtClient.right() - 1; + rtCaret.width = right - rtCaret.left; + } + + bool bShow = + m_pProperties->m_dwStates & FWL_WGTSTATE_Focused && !rtCaret.IsEmpty(); + ShowCaret(bShow, &rtCaret); +} + +CFWL_ScrollBar* CFWL_Edit::UpdateScroll() { + bool bShowHorz = + m_pHorzScrollBar && + ((m_pHorzScrollBar->GetStates() & FWL_WGTSTATE_Invisible) == 0); + bool bShowVert = + m_pVertScrollBar && + ((m_pVertScrollBar->GetStates() & FWL_WGTSTATE_Invisible) == 0); + if (!bShowHorz && !bShowVert) + return nullptr; + + IFDE_TxtEdtPage* pPage = m_EdtEngine.GetPage(0); + if (!pPage) + return nullptr; + + const CFX_RectF& rtFDE = pPage->GetContentsBox(); + CFWL_ScrollBar* pRepaint = nullptr; + if (bShowHorz) { + CFX_RectF rtScroll; + m_pHorzScrollBar->GetWidgetRect(rtScroll); + if (rtScroll.width < rtFDE.width) { + m_pHorzScrollBar->LockUpdate(); + FX_FLOAT fRange = rtFDE.width - rtScroll.width; + m_pHorzScrollBar->SetRange(0.0f, fRange); + + FX_FLOAT fPos = std::min(std::max(m_fScrollOffsetX, 0.0f), fRange); + m_pHorzScrollBar->SetPos(fPos); + m_pHorzScrollBar->SetTrackPos(fPos); + m_pHorzScrollBar->SetPageSize(rtScroll.width); + m_pHorzScrollBar->SetStepSize(rtScroll.width / 10); + m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Disabled, false); + m_pHorzScrollBar->UnlockUpdate(); + m_pHorzScrollBar->Update(); + pRepaint = m_pHorzScrollBar.get(); + } else if ((m_pHorzScrollBar->GetStates() & FWL_WGTSTATE_Disabled) == 0) { + m_pHorzScrollBar->LockUpdate(); + m_pHorzScrollBar->SetRange(0, -1); + m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Disabled, true); + m_pHorzScrollBar->UnlockUpdate(); + m_pHorzScrollBar->Update(); + pRepaint = m_pHorzScrollBar.get(); + } + } + + if (bShowVert) { + CFX_RectF rtScroll; + m_pVertScrollBar->GetWidgetRect(rtScroll); + if (rtScroll.height < rtFDE.height) { + m_pVertScrollBar->LockUpdate(); + FX_FLOAT fStep = m_EdtEngine.GetEditParams()->fLineSpace; + FX_FLOAT fRange = std::max(rtFDE.height - m_rtEngine.height, fStep); + + m_pVertScrollBar->SetRange(0.0f, fRange); + FX_FLOAT fPos = std::min(std::max(m_fScrollOffsetY, 0.0f), fRange); + m_pVertScrollBar->SetPos(fPos); + m_pVertScrollBar->SetTrackPos(fPos); + m_pVertScrollBar->SetPageSize(rtScroll.height); + m_pVertScrollBar->SetStepSize(fStep); + m_pVertScrollBar->SetStates(FWL_WGTSTATE_Disabled, false); + m_pVertScrollBar->UnlockUpdate(); + m_pVertScrollBar->Update(); + pRepaint = m_pVertScrollBar.get(); + } else if ((m_pVertScrollBar->GetStates() & FWL_WGTSTATE_Disabled) == 0) { + m_pVertScrollBar->LockUpdate(); + m_pVertScrollBar->SetRange(0, -1); + m_pVertScrollBar->SetStates(FWL_WGTSTATE_Disabled, true); + m_pVertScrollBar->UnlockUpdate(); + m_pVertScrollBar->Update(); + pRepaint = m_pVertScrollBar.get(); + } + } + return pRepaint; +} + +bool CFWL_Edit::IsShowScrollBar(bool bVert) { + bool bShow = + (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ShowScrollbarFocus) + ? (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == + FWL_WGTSTATE_Focused + : true; + if (bVert) { + return bShow && (m_pProperties->m_dwStyles & FWL_WGTSTYLE_VScroll) && + (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine) && + IsContentHeightOverflow(); + } + return bShow && (m_pProperties->m_dwStyles & FWL_WGTSTYLE_HScroll) && + (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine); +} + +bool CFWL_Edit::IsContentHeightOverflow() { + IFDE_TxtEdtPage* pPage = m_EdtEngine.GetPage(0); + if (!pPage) + return false; + return pPage->GetContentsBox().height > m_rtEngine.height + 1.0f; +} + +int32_t CFWL_Edit::AddDoRecord(IFDE_TxtEdtDoRecord* pRecord) { + int32_t nCount = pdfium::CollectionSize<int32_t>(m_DoRecords); + if (m_iCurRecord == nCount - 1) { + if (nCount == m_iMaxRecord) { + m_DoRecords.pop_front(); + m_iCurRecord--; + } + } else { + m_DoRecords.erase(m_DoRecords.begin() + m_iCurRecord + 1, + m_DoRecords.end()); + } + + m_DoRecords.push_back(std::unique_ptr<IFDE_TxtEdtDoRecord>(pRecord)); + m_iCurRecord = pdfium::CollectionSize<int32_t>(m_DoRecords) - 1; + return m_iCurRecord; +} + +void CFWL_Edit::Layout() { + GetClientRect(m_rtClient); + m_rtEngine = m_rtClient; + FX_FLOAT* pfWidth = static_cast<FX_FLOAT*>( + GetThemeCapacity(CFWL_WidgetCapacity::ScrollBarWidth)); + if (!pfWidth) + return; + + FX_FLOAT fWidth = *pfWidth; + if (!m_pOuter) { + CFX_RectF* pUIMargin = static_cast<CFX_RectF*>( + GetThemeCapacity(CFWL_WidgetCapacity::UIMargin)); + if (pUIMargin) { + m_rtEngine.Deflate(pUIMargin->left, pUIMargin->top, pUIMargin->width, + pUIMargin->height); + } + } else if (m_pOuter->GetClassID() == FWL_Type::DateTimePicker) { + CFWL_ThemePart part; + part.m_pWidget = m_pOuter; + CFX_RectF* pUIMargin = + static_cast<CFX_RectF*>(m_pOuter->GetThemeProvider()->GetCapacity( + &part, CFWL_WidgetCapacity::UIMargin)); + if (pUIMargin) { + m_rtEngine.Deflate(pUIMargin->left, pUIMargin->top, pUIMargin->width, + pUIMargin->height); + } + } + + bool bShowVertScrollbar = IsShowScrollBar(true); + bool bShowHorzScrollbar = IsShowScrollBar(false); + if (bShowVertScrollbar) { + InitScrollBar(); + + CFX_RectF rtVertScr; + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) { + rtVertScr.Set(m_rtClient.right() + kEditMargin, m_rtClient.top, fWidth, + m_rtClient.height); + } else { + rtVertScr.Set(m_rtClient.right() - fWidth, m_rtClient.top, fWidth, + m_rtClient.height); + if (bShowHorzScrollbar) + rtVertScr.height -= fWidth; + m_rtEngine.width -= fWidth; + } + + m_pVertScrollBar->SetWidgetRect(rtVertScr); + m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, false); + m_pVertScrollBar->Update(); + } else if (m_pVertScrollBar) { + m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, true); + } + + if (bShowHorzScrollbar) { + InitScrollBar(false); + + CFX_RectF rtHoriScr; + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) { + rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() + kEditMargin, + m_rtClient.width, fWidth); + } else { + rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() - fWidth, + m_rtClient.width, fWidth); + if (bShowVertScrollbar) + rtHoriScr.width -= fWidth; + m_rtEngine.height -= fWidth; + } + m_pHorzScrollBar->SetWidgetRect(rtHoriScr); + m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, false); + m_pHorzScrollBar->Update(); + } else if (m_pHorzScrollBar) { + m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, true); + } +} + +void CFWL_Edit::LayoutScrollBar() { + if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ShowScrollbarFocus) == + 0) { + return; + } + + FX_FLOAT* pfWidth = nullptr; + bool bShowVertScrollbar = IsShowScrollBar(true); + bool bShowHorzScrollbar = IsShowScrollBar(false); + if (bShowVertScrollbar) { + if (!m_pVertScrollBar) { + pfWidth = static_cast<FX_FLOAT*>( + GetThemeCapacity(CFWL_WidgetCapacity::ScrollBarWidth)); + FX_FLOAT fWidth = pfWidth ? *pfWidth : 0; + InitScrollBar(); + CFX_RectF rtVertScr; + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) { + rtVertScr.Set(m_rtClient.right() + kEditMargin, m_rtClient.top, fWidth, + m_rtClient.height); + } else { + rtVertScr.Set(m_rtClient.right() - fWidth, m_rtClient.top, fWidth, + m_rtClient.height); + if (bShowHorzScrollbar) + rtVertScr.height -= fWidth; + } + m_pVertScrollBar->SetWidgetRect(rtVertScr); + m_pVertScrollBar->Update(); + } + m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, false); + } else if (m_pVertScrollBar) { + m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, true); + } + + if (bShowHorzScrollbar) { + if (!m_pHorzScrollBar) { + if (!pfWidth) { + pfWidth = static_cast<FX_FLOAT*>( + GetThemeCapacity(CFWL_WidgetCapacity::ScrollBarWidth)); + } + + FX_FLOAT fWidth = pfWidth ? *pfWidth : 0; + InitScrollBar(false); + CFX_RectF rtHoriScr; + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) { + rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() + kEditMargin, + m_rtClient.width, fWidth); + } else { + rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() - fWidth, + m_rtClient.width, fWidth); + if (bShowVertScrollbar) + rtHoriScr.width -= (fWidth); + } + m_pHorzScrollBar->SetWidgetRect(rtHoriScr); + m_pHorzScrollBar->Update(); + } + m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, false); + } else if (m_pHorzScrollBar) { + m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, true); + } + if (bShowVertScrollbar || bShowHorzScrollbar) + UpdateScroll(); +} + +void CFWL_Edit::DeviceToEngine(CFX_PointF& pt) { + pt.x += m_fScrollOffsetX - m_rtEngine.left; + pt.y += m_fScrollOffsetY - m_rtEngine.top - m_fVAlignOffset; +} + +void CFWL_Edit::InitScrollBar(bool bVert) { + if ((bVert && m_pVertScrollBar) || (!bVert && m_pHorzScrollBar)) + return; + + auto prop = pdfium::MakeUnique<CFWL_WidgetProperties>(); + prop->m_dwStyleExes = bVert ? FWL_STYLEEXT_SCB_Vert : FWL_STYLEEXT_SCB_Horz; + prop->m_dwStates = FWL_WGTSTATE_Disabled | FWL_WGTSTATE_Invisible; + prop->m_pParent = this; + prop->m_pThemeProvider = m_pProperties->m_pThemeProvider; + + CFWL_ScrollBar* sb = new CFWL_ScrollBar(m_pOwnerApp, std::move(prop), this); + if (bVert) + m_pVertScrollBar.reset(sb); + else + m_pHorzScrollBar.reset(sb); +} + +bool FWL_ShowCaret(CFWL_Widget* pWidget, + bool bVisible, + const CFX_RectF* pRtAnchor) { + CXFA_FFWidget* pXFAWidget = + static_cast<CXFA_FFWidget*>(pWidget->GetLayoutItem()); + if (!pXFAWidget) + return false; + + IXFA_DocEnvironment* pDocEnvironment = + pXFAWidget->GetDoc()->GetDocEnvironment(); + if (!pDocEnvironment) + return false; + + if (bVisible) { + CFX_Matrix mt; + pXFAWidget->GetRotateMatrix(mt); + CFX_RectF rt(*pRtAnchor); + mt.TransformRect(rt); + pDocEnvironment->DisplayCaret(pXFAWidget, bVisible, &rt); + return true; + } + + pDocEnvironment->DisplayCaret(pXFAWidget, bVisible, pRtAnchor); + return true; +} + +void CFWL_Edit::ShowCaret(bool bVisible, CFX_RectF* pRect) { + if (m_pCaret) { + m_pCaret->ShowCaret(bVisible); + if (bVisible && !pRect->IsEmpty()) + m_pCaret->SetWidgetRect(*pRect); + Repaint(&m_rtEngine); + return; + } + + CFWL_Widget* pOuter = this; + if (bVisible) { + pRect->Offset(m_pProperties->m_rtWidget.left, + m_pProperties->m_rtWidget.top); + } + while (pOuter->GetOuter()) { + pOuter = pOuter->GetOuter(); + if (bVisible) { + CFX_RectF rtOuter; + pOuter->GetWidgetRect(rtOuter); + pRect->Offset(rtOuter.left, rtOuter.top); + } + } + FWL_ShowCaret(pOuter, bVisible, pRect); +} + +bool CFWL_Edit::ValidateNumberChar(FX_WCHAR cNum) { + if (!m_bSetRange) + return true; + + CFX_WideString wsOld, wsText; + m_EdtEngine.GetText(wsText, 0); + if (wsText.IsEmpty()) { + if (cNum == L'0') + return false; + return true; + } + + int32_t caretPos = m_EdtEngine.GetCaretPos(); + if (CountSelRanges() == 0) { + if (cNum == L'0' && caretPos == 0) + return false; + + int32_t nLen = wsText.GetLength(); + CFX_WideString l = wsText.Mid(0, caretPos); + CFX_WideString r = wsText.Mid(caretPos, nLen - caretPos); + CFX_WideString wsNew = l + cNum + r; + if (wsNew.GetInteger() <= m_iMax) + return true; + return false; + } + + if (wsText.GetInteger() <= m_iMax) + return true; + return false; +} + +void CFWL_Edit::InitCaret() { + if (!m_pCaret) { + if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_InnerCaret)) { + m_pCaret.reset(new CFWL_Caret( + m_pOwnerApp, pdfium::MakeUnique<CFWL_WidgetProperties>(), this)); + m_pCaret->SetParent(this); + m_pCaret->SetStates(m_pProperties->m_dwStates); + } + } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_InnerCaret) == + 0) { + m_pCaret.reset(); + } +} + +void CFWL_Edit::ClearRecord() { + m_iCurRecord = -1; + m_DoRecords.clear(); +} + +void CFWL_Edit::ProcessInsertError(int32_t iError) { + if (iError != -2) + return; + + CFWL_EvtTextFull textFullEvent; + textFullEvent.m_pSrcTarget = this; + DispatchEvent(&textFullEvent); +} + +void CFWL_Edit::OnProcessMessage(CFWL_Message* pMessage) { + if (!pMessage) + return; + + CFWL_MessageType dwMsgCode = pMessage->GetClassID(); + switch (dwMsgCode) { + case CFWL_MessageType::SetFocus: + case CFWL_MessageType::KillFocus: + OnFocusChanged(pMessage, dwMsgCode == CFWL_MessageType::SetFocus); + break; + case CFWL_MessageType::Mouse: { + CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage); + switch (pMsg->m_dwCmd) { + case FWL_MouseCommand::LeftButtonDown: + OnLButtonDown(pMsg); + break; + case FWL_MouseCommand::LeftButtonUp: + OnLButtonUp(pMsg); + break; + case FWL_MouseCommand::LeftButtonDblClk: + OnButtonDblClk(pMsg); + break; + case FWL_MouseCommand::Move: + OnMouseMove(pMsg); + break; + case FWL_MouseCommand::RightButtonDown: + DoButtonDown(pMsg); + break; + default: + break; + } + break; + } + case CFWL_MessageType::Key: { + CFWL_MsgKey* pKey = static_cast<CFWL_MsgKey*>(pMessage); + if (pKey->m_dwCmd == FWL_KeyCommand::KeyDown) + OnKeyDown(pKey); + else if (pKey->m_dwCmd == FWL_KeyCommand::Char) + OnChar(pKey); + break; + } + default: + break; + } + CFWL_Widget::OnProcessMessage(pMessage); +} + +void CFWL_Edit::OnProcessEvent(CFWL_Event* pEvent) { + if (!pEvent) + return; + if (pEvent->GetClassID() != CFWL_EventType::Scroll) + return; + + CFWL_Widget* pSrcTarget = pEvent->m_pSrcTarget; + if ((pSrcTarget == m_pVertScrollBar.get() && m_pVertScrollBar) || + (pSrcTarget == m_pHorzScrollBar.get() && m_pHorzScrollBar)) { + CFWL_EvtScroll* pScrollEvent = static_cast<CFWL_EvtScroll*>(pEvent); + OnScroll(static_cast<CFWL_ScrollBar*>(pSrcTarget), + pScrollEvent->m_iScrollCode, pScrollEvent->m_fPos); + } +} + +void CFWL_Edit::OnDrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) { + DrawWidget(pGraphics, pMatrix); +} + +void CFWL_Edit::DoButtonDown(CFWL_MsgMouse* pMsg) { + if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) + SetFocus(true); + + IFDE_TxtEdtPage* pPage = m_EdtEngine.GetPage(0); + if (!pPage) + return; + + CFX_PointF pt(pMsg->m_fx, pMsg->m_fy); + DeviceToEngine(pt); + bool bBefore = true; + int32_t nIndex = pPage->GetCharIndex(pt, bBefore); + if (nIndex < 0) + nIndex = 0; + + m_EdtEngine.SetCaretPos(nIndex, bBefore); +} + +void CFWL_Edit::OnFocusChanged(CFWL_Message* pMsg, bool bSet) { + uint32_t dwStyleEx = GetStylesEx(); + bool bRepaint = !!(dwStyleEx & FWL_STYLEEXT_EDT_InnerCaret); + if (bSet) { + m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused; + + UpdateVAlignment(); + UpdateOffset(); + UpdateCaret(); + } else if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) { + m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused; + ShowCaret(false); + if ((dwStyleEx & FWL_STYLEEXT_EDT_NoHideSel) == 0) { + int32_t nSel = CountSelRanges(); + if (nSel > 0) { + ClearSelections(); + bRepaint = true; + } + m_EdtEngine.SetCaretPos(0, true); + UpdateOffset(); + } + ClearRecord(); + } + + LayoutScrollBar(); + if (!bRepaint) + return; + + CFX_RectF rtInvalidate; + rtInvalidate.Set(0, 0, m_pProperties->m_rtWidget.width, + m_pProperties->m_rtWidget.height); + Repaint(&rtInvalidate); +} + +void CFWL_Edit::OnLButtonDown(CFWL_MsgMouse* pMsg) { + if (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) + return; + + m_bLButtonDown = true; + SetGrab(true); + DoButtonDown(pMsg); + int32_t nIndex = m_EdtEngine.GetCaretPos(); + bool bRepaint = false; + if (m_EdtEngine.CountSelRanges() > 0) { + m_EdtEngine.ClearSelection(); + bRepaint = true; + } + + if ((pMsg->m_dwFlags & FWL_KEYFLAG_Shift) && m_nSelStart != nIndex) { + int32_t iStart = std::min(m_nSelStart, nIndex); + int32_t iEnd = std::max(m_nSelStart, nIndex); + m_EdtEngine.AddSelRange(iStart, iEnd - iStart); + bRepaint = true; + } else { + m_nSelStart = nIndex; + } + if (bRepaint) + Repaint(&m_rtEngine); +} + +void CFWL_Edit::OnLButtonUp(CFWL_MsgMouse* pMsg) { + m_bLButtonDown = false; + SetGrab(false); +} + +void CFWL_Edit::OnButtonDblClk(CFWL_MsgMouse* pMsg) { + IFDE_TxtEdtPage* pPage = m_EdtEngine.GetPage(0); + if (!pPage) + return; + + CFX_PointF pt(pMsg->m_fx, pMsg->m_fy); + DeviceToEngine(pt); + int32_t nCount = 0; + int32_t nIndex = pPage->SelectWord(pt, nCount); + if (nIndex < 0) + return; + + m_EdtEngine.AddSelRange(nIndex, nCount); + m_EdtEngine.SetCaretPos(nIndex + nCount - 1, false); + Repaint(&m_rtEngine); +} + +void CFWL_Edit::OnMouseMove(CFWL_MsgMouse* pMsg) { + if (m_nSelStart == -1 || !m_bLButtonDown) + return; + + IFDE_TxtEdtPage* pPage = m_EdtEngine.GetPage(0); + if (!pPage) + return; + + CFX_PointF pt(pMsg->m_fx, pMsg->m_fy); + DeviceToEngine(pt); + bool bBefore = true; + int32_t nIndex = pPage->GetCharIndex(pt, bBefore); + m_EdtEngine.SetCaretPos(nIndex, bBefore); + nIndex = m_EdtEngine.GetCaretPos(); + m_EdtEngine.ClearSelection(); + + if (nIndex == m_nSelStart) + return; + + int32_t nLen = m_EdtEngine.GetTextLength(); + if (m_nSelStart >= nLen) + m_nSelStart = nLen; + + m_EdtEngine.AddSelRange(std::min(m_nSelStart, nIndex), + FXSYS_abs(nIndex - m_nSelStart)); +} + +void CFWL_Edit::OnKeyDown(CFWL_MsgKey* pMsg) { + FDE_TXTEDTMOVECARET MoveCaret = MC_MoveNone; + bool bShift = !!(pMsg->m_dwFlags & FWL_KEYFLAG_Shift); + bool bCtrl = !!(pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl); + uint32_t dwKeyCode = pMsg->m_dwKeyCode; + switch (dwKeyCode) { + case FWL_VKEY_Left: { + MoveCaret = MC_Left; + break; + } + case FWL_VKEY_Right: { + MoveCaret = MC_Right; + break; + } + case FWL_VKEY_Up: { + MoveCaret = MC_Up; + break; + } + case FWL_VKEY_Down: { + MoveCaret = MC_Down; + break; + } + case FWL_VKEY_Home: { + MoveCaret = bCtrl ? MC_Home : MC_LineStart; + break; + } + case FWL_VKEY_End: { + MoveCaret = bCtrl ? MC_End : MC_LineEnd; + break; + } + case FWL_VKEY_Insert: + break; + case FWL_VKEY_Delete: { + if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly) || + (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) { + break; + } + int32_t nCaret = m_EdtEngine.GetCaretPos(); +#if (_FX_OS_ == _FX_MACOSX_) + m_EdtEngine.Delete(nCaret, true); +#else + m_EdtEngine.Delete(nCaret); +#endif + break; + } + case FWL_VKEY_F2: + break; + case FWL_VKEY_Tab: { + DispatchKeyEvent(pMsg); + break; + } + default: + break; + } + if (MoveCaret != MC_MoveNone) + m_EdtEngine.MoveCaretPos(MoveCaret, bShift, bCtrl); +} + +void CFWL_Edit::OnChar(CFWL_MsgKey* pMsg) { + if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly) || + (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) { + return; + } + + int32_t iError = 0; + FX_WCHAR c = static_cast<FX_WCHAR>(pMsg->m_dwKeyCode); + int32_t nCaret = m_EdtEngine.GetCaretPos(); + switch (c) { + case FWL_VKEY_Back: + m_EdtEngine.Delete(nCaret, true); + break; + case FWL_VKEY_NewLine: + case FWL_VKEY_Escape: + break; + case FWL_VKEY_Tab: { + iError = m_EdtEngine.Insert(nCaret, L"\t", 1); + break; + } + case FWL_VKEY_Return: { + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_WantReturn) { + iError = m_EdtEngine.Insert(nCaret, L"\n", 1); + } + break; + } + default: { + if (!m_pWidgetMgr->IsFormDisabled()) { + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_Number) { + if (((pMsg->m_dwKeyCode < FWL_VKEY_0) && + (pMsg->m_dwKeyCode != 0x2E && pMsg->m_dwKeyCode != 0x2D)) || + pMsg->m_dwKeyCode > FWL_VKEY_9) { + break; + } + if (!ValidateNumberChar(c)) + break; + } + } +#if (_FX_OS_ == _FX_MACOSX_) + if (pMsg->m_dwFlags & FWL_KEYFLAG_Command) +#else + if (pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl) +#endif + { + break; + } + iError = m_EdtEngine.Insert(nCaret, &c, 1); + break; + } + } + if (iError < 0) + ProcessInsertError(iError); +} + +bool CFWL_Edit::OnScroll(CFWL_ScrollBar* pScrollBar, + FWL_SCBCODE dwCode, + FX_FLOAT fPos) { + CFX_SizeF fs; + pScrollBar->GetRange(&fs.x, &fs.y); + FX_FLOAT iCurPos = pScrollBar->GetPos(); + FX_FLOAT fStep = pScrollBar->GetStepSize(); + switch (dwCode) { + case FWL_SCBCODE::Min: { + fPos = fs.x; + break; + } + case FWL_SCBCODE::Max: { + fPos = fs.y; + break; + } + case FWL_SCBCODE::StepBackward: { + fPos -= fStep; + if (fPos < fs.x + fStep / 2) { + fPos = fs.x; + } + break; + } + case FWL_SCBCODE::StepForward: { + fPos += fStep; + if (fPos > fs.y - fStep / 2) { + fPos = fs.y; + } + break; + } + case FWL_SCBCODE::PageBackward: { + fPos -= pScrollBar->GetPageSize(); + if (fPos < fs.x) { + fPos = fs.x; + } + break; + } + case FWL_SCBCODE::PageForward: { + fPos += pScrollBar->GetPageSize(); + if (fPos > fs.y) { + fPos = fs.y; + } + break; + } + case FWL_SCBCODE::Pos: + case FWL_SCBCODE::TrackPos: + case FWL_SCBCODE::None: + break; + case FWL_SCBCODE::EndScroll: + return false; + } + if (iCurPos == fPos) + return true; + + pScrollBar->SetPos(fPos); + pScrollBar->SetTrackPos(fPos); + UpdateOffset(pScrollBar, fPos - iCurPos); + UpdateCaret(); + + CFX_RectF rect; + GetWidgetRect(rect); + CFX_RectF rtInvalidate; + rtInvalidate.Set(0, 0, rect.width + 2, rect.height + 2); + Repaint(&rtInvalidate); + return true; } diff --git a/xfa/fwl/core/cfwl_edit.h b/xfa/fwl/core/cfwl_edit.h index 4570d57f6e..3c4c80759f 100644 --- a/xfa/fwl/core/cfwl_edit.h +++ b/xfa/fwl/core/cfwl_edit.h @@ -7,34 +7,190 @@ #ifndef XFA_FWL_CORE_CFWL_EDIT_H_ #define XFA_FWL_CORE_CFWL_EDIT_H_ +#include <deque> +#include <memory> #include <vector> +#include "xfa/fde/cfde_txtedtengine.h" +#include "xfa/fde/ifde_txtedtdorecord.h" +#include "xfa/fwl/core/cfwl_event.h" +#include "xfa/fwl/core/cfwl_scrollbar.h" #include "xfa/fwl/core/cfwl_widget.h" -#include "xfa/fwl/core/ifwl_edit.h" +#include "xfa/fxgraphics/cfx_path.h" + +#define FWL_STYLEEXT_EDT_ReadOnly (1L << 0) +#define FWL_STYLEEXT_EDT_MultiLine (1L << 1) +#define FWL_STYLEEXT_EDT_WantReturn (1L << 2) +#define FWL_STYLEEXT_EDT_NoHideSel (1L << 3) +#define FWL_STYLEEXT_EDT_AutoHScroll (1L << 4) +#define FWL_STYLEEXT_EDT_AutoVScroll (1L << 5) +#define FWL_STYLEEXT_EDT_NoRedoUndo (1L << 6) +#define FWL_STYLEEXT_EDT_Validate (1L << 7) +#define FWL_STYLEEXT_EDT_Password (1L << 8) +#define FWL_STYLEEXT_EDT_Number (1L << 9) +#define FWL_STYLEEXT_EDT_VerticalLayout (1L << 12) +#define FWL_STYLEEXT_EDT_VerticalChars (1L << 13) +#define FWL_STYLEEXT_EDT_ReverseLine (1L << 14) +#define FWL_STYLEEXT_EDT_ArabicShapes (1L << 15) +#define FWL_STYLEEXT_EDT_ExpandTab (1L << 16) +#define FWL_STYLEEXT_EDT_CombText (1L << 17) +#define FWL_STYLEEXT_EDT_HNear (0L << 18) +#define FWL_STYLEEXT_EDT_HCenter (1L << 18) +#define FWL_STYLEEXT_EDT_HFar (2L << 18) +#define FWL_STYLEEXT_EDT_VNear (0L << 20) +#define FWL_STYLEEXT_EDT_VCenter (1L << 20) +#define FWL_STYLEEXT_EDT_VFar (2L << 20) +#define FWL_STYLEEXT_EDT_Justified (1L << 22) +#define FWL_STYLEEXT_EDT_Distributed (2L << 22) +#define FWL_STYLEEXT_EDT_HAlignMask (3L << 18) +#define FWL_STYLEEXT_EDT_VAlignMask (3L << 20) +#define FWL_STYLEEXT_EDT_HAlignModeMask (3L << 22) +#define FWL_STYLEEXT_EDT_InnerCaret (1L << 24) +#define FWL_STYLEEXT_EDT_ShowScrollbarFocus (1L << 25) +#define FWL_STYLEEXT_EDT_OuterScrollbar (1L << 26) +#define FWL_STYLEEXT_EDT_LastLineHeight (1L << 27) class IFDE_TxtEdtDoRecord; +class CFWL_Edit; +class CFWL_MsgMouse; +class CFWL_WidgetProperties; +class CFWL_Caret; class CFWL_Edit : public CFWL_Widget { public: - explicit CFWL_Edit(const CFWL_App*); + CFWL_Edit(const CFWL_App* app, + std::unique_ptr<CFWL_WidgetProperties> properties, + CFWL_Widget* pOuter); ~CFWL_Edit() override; - void Initialize(); + // CFWL_Widget: + FWL_Type GetClassID() const override; + void GetWidgetRect(CFX_RectF& rect, bool bAutoSize = false) override; + void Update() override; + FWL_WidgetHit HitTest(FX_FLOAT fx, FX_FLOAT fy) override; + void SetStates(uint32_t dwStates, bool bSet = true) override; + void DrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix = nullptr) override; + void SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) override; + void OnProcessMessage(CFWL_Message* pMessage) override; + void OnProcessEvent(CFWL_Event* pEvent) override; + void OnDrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) override; + + virtual void SetText(const CFX_WideString& wsText); - void SetText(const CFX_WideString& wsText); + int32_t GetTextLength() const; void GetText(CFX_WideString& wsText, int32_t nStart = 0, int32_t nCount = -1) const; + void ClearText(); + void AddSelRange(int32_t nStart, int32_t nCount = -1); int32_t CountSelRanges() const; int32_t GetSelRange(int32_t nIndex, int32_t& nStart) const; - + void ClearSelections(); int32_t GetLimit() const; void SetLimit(int32_t nLimit); - void SetAliasChar(FX_WCHAR wAlias); + bool Copy(CFX_WideString& wsCopy); + bool Cut(CFX_WideString& wsCut); + bool Paste(const CFX_WideString& wsPaste); + bool Redo(const IFDE_TxtEdtDoRecord* pRecord); + bool Undo(const IFDE_TxtEdtDoRecord* pRecord); + bool Undo(); + bool Redo(); + bool CanUndo(); + bool CanRedo(); + + void SetOuter(CFWL_Widget* pOuter); + void On_CaretChanged(CFDE_TxtEdtEngine* pEdit, + int32_t nPage, + bool bVisible = true); + void On_TextChanged(CFDE_TxtEdtEngine* pEdit, + FDE_TXTEDT_TEXTCHANGE_INFO& ChangeInfo); + void On_SelChanged(CFDE_TxtEdtEngine* pEdit); + bool On_PageLoad(CFDE_TxtEdtEngine* pEdit, + int32_t nPageIndex, + int32_t nPurpose); + bool On_PageUnload(CFDE_TxtEdtEngine* pEdit, + int32_t nPageIndex, + int32_t nPurpose); + void On_AddDoRecord(CFDE_TxtEdtEngine* pEdit, IFDE_TxtEdtDoRecord* pRecord); + bool On_Validate(CFDE_TxtEdtEngine* pEdit, CFX_WideString& wsText); void SetScrollOffset(FX_FLOAT fScrollOffset); + + protected: + void ShowCaret(bool bVisible, CFX_RectF* pRect = nullptr); + const CFX_RectF& GetRTClient() const { return m_rtClient; } + CFDE_TxtEdtEngine* GetTxtEdtEngine() { return &m_EdtEngine; } + + private: + void DrawTextBk(CFX_Graphics* pGraphics, + IFWL_ThemeProvider* pTheme, + const CFX_Matrix* pMatrix = nullptr); + void DrawContent(CFX_Graphics* pGraphics, + IFWL_ThemeProvider* pTheme, + const CFX_Matrix* pMatrix = nullptr); + void UpdateEditEngine(); + void UpdateEditParams(); + void UpdateEditLayout(); + bool UpdateOffset(); + bool UpdateOffset(CFWL_ScrollBar* pScrollBar, FX_FLOAT fPosChanged); + void UpdateVAlignment(); + void UpdateCaret(); + CFWL_ScrollBar* UpdateScroll(); + void Layout(); + void LayoutScrollBar(); + void DeviceToEngine(CFX_PointF& pt); + void InitScrollBar(bool bVert = true); + void InitEngine(); + bool ValidateNumberChar(FX_WCHAR cNum); + void InitCaret(); + void ClearRecord(); + bool IsShowScrollBar(bool bVert); + bool IsContentHeightOverflow(); + int32_t AddDoRecord(IFDE_TxtEdtDoRecord* pRecord); + void ProcessInsertError(int32_t iError); + + void DrawSpellCheck(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix = nullptr); + void AddSpellCheckObj(CFX_Path& PathData, + int32_t nStart, + int32_t nCount, + FX_FLOAT fOffSetX, + FX_FLOAT fOffSetY); + void DoButtonDown(CFWL_MsgMouse* pMsg); + void OnFocusChanged(CFWL_Message* pMsg, bool bSet); + void OnLButtonDown(CFWL_MsgMouse* pMsg); + void OnLButtonUp(CFWL_MsgMouse* pMsg); + void OnButtonDblClk(CFWL_MsgMouse* pMsg); + void OnMouseMove(CFWL_MsgMouse* pMsg); + void OnKeyDown(CFWL_MsgKey* pMsg); + void OnChar(CFWL_MsgKey* pMsg); + bool OnScroll(CFWL_ScrollBar* pScrollBar, FWL_SCBCODE dwCode, FX_FLOAT fPos); + + CFX_RectF m_rtClient; + CFX_RectF m_rtEngine; + CFX_RectF m_rtStatic; + FX_FLOAT m_fVAlignOffset; + FX_FLOAT m_fScrollOffsetX; + FX_FLOAT m_fScrollOffsetY; + CFDE_TxtEdtEngine m_EdtEngine; + bool m_bLButtonDown; + int32_t m_nSelStart; + int32_t m_nLimit; + FX_FLOAT m_fFontSize; + bool m_bSetRange; + int32_t m_iMax; + std::unique_ptr<CFWL_ScrollBar> m_pVertScrollBar; + std::unique_ptr<CFWL_ScrollBar> m_pHorzScrollBar; + std::unique_ptr<CFWL_Caret> m_pCaret; + CFX_WideString m_wsCache; + CFX_WideString m_wsFont; + std::deque<std::unique_ptr<IFDE_TxtEdtDoRecord>> m_DoRecords; + int32_t m_iCurRecord; + int32_t m_iMaxRecord; }; #endif // XFA_FWL_CORE_CFWL_EDIT_H_ diff --git a/xfa/fwl/core/cfwl_event.h b/xfa/fwl/core/cfwl_event.h index 550457a6bd..fe8e1b37f0 100644 --- a/xfa/fwl/core/cfwl_event.h +++ b/xfa/fwl/core/cfwl_event.h @@ -38,7 +38,7 @@ enum class CFWL_EventType { }; class CFX_Graphics; -class IFWL_Widget; +class CFWL_Widget; class CFWL_Event { public: @@ -47,8 +47,8 @@ class CFWL_Event { virtual CFWL_EventType GetClassID() const; - IFWL_Widget* m_pSrcTarget; - IFWL_Widget* m_pDstTarget; + CFWL_Widget* m_pSrcTarget; + CFWL_Widget* m_pDstTarget; }; #endif // XFA_FWL_CORE_CFWL_EVENT_H_ diff --git a/xfa/fwl/core/cfwl_eventtarget.cpp b/xfa/fwl/core/cfwl_eventtarget.cpp index 836a7ed34d..34377c2d73 100644 --- a/xfa/fwl/core/cfwl_eventtarget.cpp +++ b/xfa/fwl/core/cfwl_eventtarget.cpp @@ -6,15 +6,15 @@ #include "xfa/fwl/core/cfwl_eventtarget.h" -#include "xfa/fwl/core/ifwl_widget.h" +#include "xfa/fwl/core/cfwl_widget.h" #include "xfa/fwl/core/ifwl_widgetdelegate.h" -CFWL_EventTarget::CFWL_EventTarget(IFWL_Widget* pListener) +CFWL_EventTarget::CFWL_EventTarget(CFWL_Widget* pListener) : m_pListener(pListener), m_bInvalid(false) {} CFWL_EventTarget::~CFWL_EventTarget() {} -void CFWL_EventTarget::SetEventSource(IFWL_Widget* pSource) { +void CFWL_EventTarget::SetEventSource(CFWL_Widget* pSource) { if (pSource) m_widgets.insert(pSource); } diff --git a/xfa/fwl/core/cfwl_eventtarget.h b/xfa/fwl/core/cfwl_eventtarget.h index 3ed8e9a4b7..5f0ee35b9b 100644 --- a/xfa/fwl/core/cfwl_eventtarget.h +++ b/xfa/fwl/core/cfwl_eventtarget.h @@ -13,22 +13,22 @@ #include "xfa/fwl/core/cfwl_event.h" class CFWL_Event; -class IFWL_Widget; +class CFWL_Widget; class CFWL_EventTarget { public: - explicit CFWL_EventTarget(IFWL_Widget* pListener); + explicit CFWL_EventTarget(CFWL_Widget* pListener); ~CFWL_EventTarget(); - void SetEventSource(IFWL_Widget* pSource); + void SetEventSource(CFWL_Widget* pSource); bool ProcessEvent(CFWL_Event* pEvent); bool IsInvalid() const { return m_bInvalid; } void FlagInvalid() { m_bInvalid = true; } private: - std::set<IFWL_Widget*> m_widgets; - IFWL_Widget* m_pListener; + std::set<CFWL_Widget*> m_widgets; + CFWL_Widget* m_pListener; bool m_bInvalid; }; diff --git a/xfa/fwl/core/cfwl_evtkillfocus.h b/xfa/fwl/core/cfwl_evtkillfocus.h index 5a9d292af8..737053bc3d 100644 --- a/xfa/fwl/core/cfwl_evtkillfocus.h +++ b/xfa/fwl/core/cfwl_evtkillfocus.h @@ -16,7 +16,7 @@ class CFWL_EvtKillFocus : public CFWL_Event { CFWL_EventType GetClassID() const override; - IFWL_Widget* m_pKillFocus; + CFWL_Widget* m_pKillFocus; }; #endif // XFA_FWL_CORE_CFWL_EVTKILLFOCUS_H_ diff --git a/xfa/fwl/core/cfwl_evtsetfocus.h b/xfa/fwl/core/cfwl_evtsetfocus.h index b1ff43d6e3..0232b59576 100644 --- a/xfa/fwl/core/cfwl_evtsetfocus.h +++ b/xfa/fwl/core/cfwl_evtsetfocus.h @@ -16,7 +16,7 @@ class CFWL_EvtSetFocus : public CFWL_Event { CFWL_EventType GetClassID() const override; - IFWL_Widget* m_pSetFocus; + CFWL_Widget* m_pSetFocus; }; #endif // XFA_FWL_CORE_CFWL_EVTSETFOCUS_H_ diff --git a/xfa/fwl/core/cfwl_evtsizechanged.h b/xfa/fwl/core/cfwl_evtsizechanged.h index fe2dc6f5e5..33d526751f 100644 --- a/xfa/fwl/core/cfwl_evtsizechanged.h +++ b/xfa/fwl/core/cfwl_evtsizechanged.h @@ -16,7 +16,7 @@ class CFWL_EvtSizeChanged : public CFWL_Event { CFWL_EventType GetClassID() const override; - IFWL_Widget* m_pWidget; + CFWL_Widget* m_pWidget; CFX_RectF m_rtOld; CFX_RectF m_rtNew; }; diff --git a/xfa/fwl/core/cfwl_evtvalidate.h b/xfa/fwl/core/cfwl_evtvalidate.h index be9fd5642e..fae20b845b 100644 --- a/xfa/fwl/core/cfwl_evtvalidate.h +++ b/xfa/fwl/core/cfwl_evtvalidate.h @@ -16,7 +16,7 @@ class CFWL_EvtValidate : public CFWL_Event { CFWL_EventType GetClassID() const override; - IFWL_Widget* pDstWidget; + CFWL_Widget* pDstWidget; CFX_WideString wsInsert; bool bValidate; }; diff --git a/xfa/fwl/core/cfwl_form.cpp b/xfa/fwl/core/cfwl_form.cpp index d2fe14993e..4eec163900 100644 --- a/xfa/fwl/core/cfwl_form.cpp +++ b/xfa/fwl/core/cfwl_form.cpp @@ -40,8 +40,8 @@ const uint8_t kCornerEnlarge = 10; CFWL_Form::CFWL_Form(const CFWL_App* app, std::unique_ptr<CFWL_WidgetProperties> properties, - IFWL_Widget* pOuter) - : IFWL_Widget(app, std::move(properties), pOuter), + CFWL_Widget* pOuter) + : CFWL_Widget(app, std::move(properties), pOuter), #if (_FX_OS_ == _FX_MACOSX_) m_bMouseIn(false), #endif @@ -77,7 +77,7 @@ FWL_Type CFWL_Form::GetClassID() const { bool CFWL_Form::IsInstance(const CFX_WideStringC& wsClass) const { if (wsClass == CFX_WideStringC(FWL_CLASS_Form)) return true; - return IFWL_Widget::IsInstance(wsClass); + return CFWL_Widget::IsInstance(wsClass); } void CFWL_Form::GetWidgetRect(CFX_RectF& rect, bool bAutoSize) { @@ -267,7 +267,7 @@ void CFWL_Form::DrawWidget(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix) { #endif } -IFWL_Widget* CFWL_Form::DoModal() { +CFWL_Widget* CFWL_Form::DoModal() { const CFWL_App* pApp = GetOwnerApp(); if (!pApp) return nullptr; diff --git a/xfa/fwl/core/cfwl_form.h b/xfa/fwl/core/cfwl_form.h index cb01c5b7a8..db09c66bb8 100644 --- a/xfa/fwl/core/cfwl_form.h +++ b/xfa/fwl/core/cfwl_form.h @@ -10,8 +10,8 @@ #include <memory> #include "core/fxcrt/fx_system.h" +#include "xfa/fwl/core/cfwl_widget.h" #include "xfa/fwl/core/cfwl_widgetproperties.h" -#include "xfa/fwl/core/ifwl_widget.h" #define FWL_CLASS_Form L"FWL_FORM" #define FWL_CLASS_FormProxy L"FWL_FORMPROXY" @@ -29,18 +29,18 @@ class CFWL_MsgMouse; class CFWL_NoteLoop; -class IFWL_Widget; +class CFWL_Widget; class IFWL_ThemeProvider; class CFWL_SysBtn; -class CFWL_Form : public IFWL_Widget { +class CFWL_Form : public CFWL_Widget { public: CFWL_Form(const CFWL_App* app, std::unique_ptr<CFWL_WidgetProperties> properties, - IFWL_Widget* pOuter); + CFWL_Widget* pOuter); ~CFWL_Form() override; - // IFWL_Widget + // CFWL_Widget FWL_Type GetClassID() const override; bool IsInstance(const CFX_WideStringC& wsClass) const override; void GetWidgetRect(CFX_RectF& rect, bool bAutoSize = false) override; @@ -53,11 +53,11 @@ class CFWL_Form : public IFWL_Widget { void OnDrawWidget(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix) override; - IFWL_Widget* DoModal(); + CFWL_Widget* DoModal(); void EndDoModal(); - IFWL_Widget* GetSubFocus() const { return m_pSubFocus; } - void SetSubFocus(IFWL_Widget* pWidget) { m_pSubFocus = pWidget; } + CFWL_Widget* GetSubFocus() const { return m_pSubFocus; } + void SetSubFocus(CFWL_Widget* pWidget) { m_pSubFocus = pWidget; } private: void DrawBackground(CFX_Graphics* pGraphics, IFWL_ThemeProvider* pTheme); @@ -87,7 +87,7 @@ class CFWL_Form : public IFWL_Widget { CFWL_SysBtn* m_pMinBox; CFWL_SysBtn* m_pMaxBox; std::unique_ptr<CFWL_NoteLoop> m_pNoteLoop; - IFWL_Widget* m_pSubFocus; + CFWL_Widget* m_pSubFocus; FX_FLOAT m_fCXBorder; FX_FLOAT m_fCYBorder; int32_t m_iCaptureBtn; diff --git a/xfa/fwl/core/cfwl_formproxy.cpp b/xfa/fwl/core/cfwl_formproxy.cpp index ef325c4fdd..c6d667f40e 100644 --- a/xfa/fwl/core/cfwl_formproxy.cpp +++ b/xfa/fwl/core/cfwl_formproxy.cpp @@ -15,7 +15,7 @@ CFWL_FormProxy::CFWL_FormProxy( const CFWL_App* app, std::unique_ptr<CFWL_WidgetProperties> properties, - IFWL_Widget* pOuter) + CFWL_Widget* pOuter) : CFWL_Form(app, std::move(properties), pOuter) {} CFWL_FormProxy::~CFWL_FormProxy() {} diff --git a/xfa/fwl/core/cfwl_formproxy.h b/xfa/fwl/core/cfwl_formproxy.h index 80e0980d0e..db8323bf64 100644 --- a/xfa/fwl/core/cfwl_formproxy.h +++ b/xfa/fwl/core/cfwl_formproxy.h @@ -17,10 +17,10 @@ class CFWL_FormProxy : public CFWL_Form { public: CFWL_FormProxy(const CFWL_App* app, std::unique_ptr<CFWL_WidgetProperties> properties, - IFWL_Widget* pOuter); + CFWL_Widget* pOuter); ~CFWL_FormProxy() override; - // IFWL_Widget + // CFWL_Widget FWL_Type GetClassID() const override; bool IsInstance(const CFX_WideStringC& wsClass) const override; void Update() override; diff --git a/xfa/fwl/core/cfwl_listbox.cpp b/xfa/fwl/core/cfwl_listbox.cpp index 784bf24de8..f2345858ef 100644 --- a/xfa/fwl/core/cfwl_listbox.cpp +++ b/xfa/fwl/core/cfwl_listbox.cpp @@ -6,60 +6,1123 @@ #include "xfa/fwl/core/cfwl_listbox.h" +#include <algorithm> #include <memory> #include <utility> #include "third_party/base/ptr_util.h" #include "third_party/base/stl_util.h" -#include "xfa/fwl/core/ifwl_listbox.h" +#include "xfa/fde/tto/fde_textout.h" +#include "xfa/fwl/core/cfwl_app.h" +#include "xfa/fwl/core/cfwl_msgkey.h" +#include "xfa/fwl/core/cfwl_msgmouse.h" +#include "xfa/fwl/core/cfwl_msgmousewheel.h" +#include "xfa/fwl/core/cfwl_themebackground.h" +#include "xfa/fwl/core/cfwl_themepart.h" +#include "xfa/fwl/core/cfwl_themetext.h" +#include "xfa/fwl/core/ifwl_themeprovider.h" namespace { -IFWL_ListBox* ToListBox(IFWL_Widget* widget) { - return static_cast<IFWL_ListBox*>(widget); -} +const int kItemTextMargin = 2; } // namespace -CFWL_ListBox::CFWL_ListBox(const CFWL_App* app) : CFWL_Widget(app) {} +CFWL_ListBox::CFWL_ListBox(const CFWL_App* app, + std::unique_ptr<CFWL_WidgetProperties> properties, + CFWL_Widget* pOuter) + : CFWL_Widget(app, std::move(properties), pOuter), + m_dwTTOStyles(0), + m_iTTOAligns(0), + m_hAnchor(nullptr), + m_fScorllBarWidth(0), + m_bLButtonDown(false), + m_pScrollBarTP(nullptr) { + m_rtClient.Reset(); + m_rtConent.Reset(); + m_rtStatic.Reset(); +} CFWL_ListBox::~CFWL_ListBox() {} -void CFWL_ListBox::Initialize() { - ASSERT(!m_pIface); +FWL_Type CFWL_ListBox::GetClassID() const { + return FWL_Type::ListBox; +} + +void CFWL_ListBox::GetWidgetRect(CFX_RectF& rect, bool bAutoSize) { + if (!bAutoSize) { + rect = m_pProperties->m_rtWidget; + return; + } - m_pIface = pdfium::MakeUnique<IFWL_ListBox>( - m_pApp, pdfium::MakeUnique<CFWL_WidgetProperties>(), nullptr); + rect.Set(0, 0, 0, 0); + if (!m_pProperties->m_pThemeProvider) + m_pProperties->m_pThemeProvider = GetAvailableTheme(); - CFWL_Widget::Initialize(); + CFX_SizeF fs = CalcSize(true); + rect.Set(0, 0, fs.x, fs.y); + CFWL_Widget::GetWidgetRect(rect, true); } -CFWL_ListItem* CFWL_ListBox::GetItem(const IFWL_Widget* pWidget, - int32_t nIndex) const { - return GetWidget() ? ToListBox(GetWidget())->GetItem(pWidget, nIndex) - : nullptr; +void CFWL_ListBox::Update() { + if (IsLocked()) + return; + if (!m_pProperties->m_pThemeProvider) + m_pProperties->m_pThemeProvider = GetAvailableTheme(); + + switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_AlignMask) { + case FWL_STYLEEXT_LTB_LeftAlign: { + m_iTTOAligns = FDE_TTOALIGNMENT_CenterLeft; + break; + } + case FWL_STYLEEXT_LTB_RightAlign: { + m_iTTOAligns = FDE_TTOALIGNMENT_CenterRight; + break; + } + case FWL_STYLEEXT_LTB_CenterAlign: + default: { + m_iTTOAligns = FDE_TTOALIGNMENT_Center; + break; + } + } + if (m_pProperties->m_dwStyleExes & FWL_WGTSTYLE_RTLReading) + m_dwTTOStyles |= FDE_TTOSTYLE_RTL; + + m_dwTTOStyles |= FDE_TTOSTYLE_SingleLine; + m_fScorllBarWidth = GetScrollWidth(); + CalcSize(); +} + +FWL_WidgetHit CFWL_ListBox::HitTest(FX_FLOAT fx, FX_FLOAT fy) { + if (IsShowScrollBar(false)) { + CFX_RectF rect; + m_pHorzScrollBar->GetWidgetRect(rect); + if (rect.Contains(fx, fy)) + return FWL_WidgetHit::HScrollBar; + } + if (IsShowScrollBar(true)) { + CFX_RectF rect; + m_pVertScrollBar->GetWidgetRect(rect); + if (rect.Contains(fx, fy)) + return FWL_WidgetHit::VScrollBar; + } + if (m_rtClient.Contains(fx, fy)) + return FWL_WidgetHit::Client; + return FWL_WidgetHit::Unknown; +} + +void CFWL_ListBox::DrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) { + if (!pGraphics) + return; + if (!m_pProperties->m_pThemeProvider) + return; + + IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider; + pGraphics->SaveGraphState(); + if (HasBorder()) + DrawBorder(pGraphics, CFWL_Part::Border, pTheme, pMatrix); + if (HasEdge()) + DrawEdge(pGraphics, CFWL_Part::Edge, pTheme, pMatrix); + + CFX_RectF rtClip(m_rtConent); + if (IsShowScrollBar(false)) + rtClip.height -= m_fScorllBarWidth; + if (IsShowScrollBar(true)) + rtClip.width -= m_fScorllBarWidth; + if (pMatrix) + pMatrix->TransformRect(rtClip); + + pGraphics->SetClipRect(rtClip); + if ((m_pProperties->m_dwStyles & FWL_WGTSTYLE_NoBackground) == 0) + DrawBkground(pGraphics, pTheme, pMatrix); + + DrawItems(pGraphics, pTheme, pMatrix); + pGraphics->RestoreGraphState(); +} + +void CFWL_ListBox::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) { + if (pThemeProvider) + m_pProperties->m_pThemeProvider = pThemeProvider; +} + +int32_t CFWL_ListBox::CountSelItems() { + int32_t iRet = 0; + int32_t iCount = CountItems(this); + for (int32_t i = 0; i < iCount; i++) { + CFWL_ListItem* pItem = GetItem(this, i); + if (!pItem) + continue; + + uint32_t dwStyle = GetItemStyles(this, pItem); + if (dwStyle & FWL_ITEMSTATE_LTB_Selected) + iRet++; + } + return iRet; +} + +CFWL_ListItem* CFWL_ListBox::GetSelItem(int32_t nIndexSel) { + int32_t idx = GetSelIndex(nIndexSel); + if (idx < 0) + return nullptr; + return GetItem(this, idx); +} + +int32_t CFWL_ListBox::GetSelIndex(int32_t nIndex) { + int32_t index = 0; + int32_t iCount = CountItems(this); + for (int32_t i = 0; i < iCount; i++) { + CFWL_ListItem* pItem = GetItem(this, i); + if (!pItem) + return -1; + + uint32_t dwStyle = GetItemStyles(this, pItem); + if (dwStyle & FWL_ITEMSTATE_LTB_Selected) { + if (index == nIndex) + return i; + index++; + } + } + return -1; +} + +void CFWL_ListBox::SetSelItem(CFWL_ListItem* pItem, bool bSelect) { + if (!pItem) { + if (bSelect) { + SelectAll(); + } else { + ClearSelection(); + SetFocusItem(nullptr); + } + return; + } + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiSelection) + SetSelectionDirect(pItem, bSelect); + else + SetSelection(pItem, pItem, bSelect); +} + +void CFWL_ListBox::GetDataProviderItemText(CFWL_ListItem* pItem, + CFX_WideString& wsText) { + if (!pItem) + return; + GetItemText(this, pItem, wsText); +} + +CFWL_ListItem* CFWL_ListBox::GetListItem(CFWL_ListItem* pItem, + uint32_t dwKeyCode) { + CFWL_ListItem* hRet = nullptr; + switch (dwKeyCode) { + case FWL_VKEY_Up: + case FWL_VKEY_Down: + case FWL_VKEY_Home: + case FWL_VKEY_End: { + const bool bUp = dwKeyCode == FWL_VKEY_Up; + const bool bDown = dwKeyCode == FWL_VKEY_Down; + const bool bHome = dwKeyCode == FWL_VKEY_Home; + int32_t iDstItem = -1; + if (bUp || bDown) { + int32_t index = GetItemIndex(this, pItem); + iDstItem = dwKeyCode == FWL_VKEY_Up ? index - 1 : index + 1; + } else if (bHome) { + iDstItem = 0; + } else { + int32_t iCount = CountItems(this); + iDstItem = iCount - 1; + } + hRet = GetItem(this, iDstItem); + break; + } + default: + break; + } + return hRet; +} + +void CFWL_ListBox::SetSelection(CFWL_ListItem* hStart, + CFWL_ListItem* hEnd, + bool bSelected) { + int32_t iStart = GetItemIndex(this, hStart); + int32_t iEnd = GetItemIndex(this, hEnd); + if (iStart > iEnd) { + int32_t iTemp = iStart; + iStart = iEnd; + iEnd = iTemp; + } + if (bSelected) { + int32_t iCount = CountItems(this); + for (int32_t i = 0; i < iCount; i++) { + CFWL_ListItem* pItem = GetItem(this, i); + SetSelectionDirect(pItem, false); + } + } + for (; iStart <= iEnd; iStart++) { + CFWL_ListItem* pItem = GetItem(this, iStart); + SetSelectionDirect(pItem, bSelected); + } +} + +void CFWL_ListBox::SetSelectionDirect(CFWL_ListItem* pItem, bool bSelect) { + uint32_t dwOldStyle = GetItemStyles(this, pItem); + bSelect ? dwOldStyle |= FWL_ITEMSTATE_LTB_Selected + : dwOldStyle &= ~FWL_ITEMSTATE_LTB_Selected; + SetItemStyles(this, pItem, dwOldStyle); +} + +bool CFWL_ListBox::IsItemSelected(CFWL_ListItem* pItem) { + uint32_t dwState = GetItemStyles(this, pItem); + return (dwState & FWL_ITEMSTATE_LTB_Selected) != 0; +} + +void CFWL_ListBox::ClearSelection() { + bool bMulti = m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiSelection; + int32_t iCount = CountItems(this); + for (int32_t i = 0; i < iCount; i++) { + CFWL_ListItem* pItem = GetItem(this, i); + uint32_t dwState = GetItemStyles(this, pItem); + if (!(dwState & FWL_ITEMSTATE_LTB_Selected)) + continue; + SetSelectionDirect(pItem, false); + if (!bMulti) + return; + } +} + +void CFWL_ListBox::SelectAll() { + if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiSelection)) + return; + + int32_t iCount = CountItems(this); + if (iCount <= 0) + return; + + CFWL_ListItem* pItemStart = GetItem(this, 0); + CFWL_ListItem* pItemEnd = GetItem(this, iCount - 1); + SetSelection(pItemStart, pItemEnd, false); +} + +CFWL_ListItem* CFWL_ListBox::GetFocusedItem() { + int32_t iCount = CountItems(this); + for (int32_t i = 0; i < iCount; i++) { + CFWL_ListItem* pItem = GetItem(this, i); + if (!pItem) + return nullptr; + if (GetItemStyles(this, pItem) & FWL_ITEMSTATE_LTB_Focused) + return pItem; + } + return nullptr; } -void CFWL_ListBox::GetItemText(IFWL_Widget* pWidget, +void CFWL_ListBox::SetFocusItem(CFWL_ListItem* pItem) { + CFWL_ListItem* hFocus = GetFocusedItem(); + if (pItem == hFocus) + return; + + if (hFocus) { + uint32_t dwStyle = GetItemStyles(this, hFocus); + dwStyle &= ~FWL_ITEMSTATE_LTB_Focused; + SetItemStyles(this, hFocus, dwStyle); + } + if (pItem) { + uint32_t dwStyle = GetItemStyles(this, pItem); + dwStyle |= FWL_ITEMSTATE_LTB_Focused; + SetItemStyles(this, pItem, dwStyle); + } +} + +CFWL_ListItem* CFWL_ListBox::GetItemAtPoint(FX_FLOAT fx, FX_FLOAT fy) { + fx -= m_rtConent.left, fy -= m_rtConent.top; + FX_FLOAT fPosX = 0.0f; + if (m_pHorzScrollBar) + fPosX = m_pHorzScrollBar->GetPos(); + + FX_FLOAT fPosY = 0.0; + if (m_pVertScrollBar) + fPosY = m_pVertScrollBar->GetPos(); + + int32_t nCount = CountItems(this); + for (int32_t i = 0; i < nCount; i++) { + CFWL_ListItem* pItem = GetItem(this, i); + if (!pItem) + continue; + + CFX_RectF rtItem; + GetItemRect(this, pItem, rtItem); + rtItem.Offset(-fPosX, -fPosY); + if (rtItem.Contains(fx, fy)) + return pItem; + } + return nullptr; +} + +bool CFWL_ListBox::GetItemCheckRectInternal(CFWL_ListItem* pItem, + CFX_RectF& rtCheck) { + if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_Check)) + return false; + GetItemCheckRect(this, pItem, rtCheck); + return true; +} + +bool CFWL_ListBox::GetItemChecked(CFWL_ListItem* pItem) { + if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_Check)) + return false; + return !!(GetItemCheckState(this, pItem) & FWL_ITEMSTATE_LTB_Checked); +} + +bool CFWL_ListBox::SetItemChecked(CFWL_ListItem* pItem, bool bChecked) { + if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_Check)) + return false; + + SetItemCheckState(this, pItem, bChecked ? FWL_ITEMSTATE_LTB_Checked : 0); + return true; +} + +bool CFWL_ListBox::ScrollToVisible(CFWL_ListItem* pItem) { + if (!m_pVertScrollBar) + return false; + + CFX_RectF rtItem; + GetItemRect(this, pItem, rtItem); + + bool bScroll = false; + FX_FLOAT fPosY = m_pVertScrollBar->GetPos(); + rtItem.Offset(0, -fPosY + m_rtConent.top); + if (rtItem.top < m_rtConent.top) { + fPosY += rtItem.top - m_rtConent.top; + bScroll = true; + } else if (rtItem.bottom() > m_rtConent.bottom()) { + fPosY += rtItem.bottom() - m_rtConent.bottom(); + bScroll = true; + } + if (!bScroll) + return false; + + m_pVertScrollBar->SetPos(fPosY); + m_pVertScrollBar->SetTrackPos(fPosY); + Repaint(&m_rtClient); + return true; +} + +void CFWL_ListBox::DrawBkground(CFX_Graphics* pGraphics, + IFWL_ThemeProvider* pTheme, + const CFX_Matrix* pMatrix) { + if (!pGraphics) + return; + if (!pTheme) + return; + + CFWL_ThemeBackground param; + param.m_pWidget = this; + param.m_iPart = CFWL_Part::Background; + param.m_dwStates = 0; + param.m_pGraphics = pGraphics; + param.m_matrix.Concat(*pMatrix); + param.m_rtPart = m_rtClient; + if (IsShowScrollBar(false) && IsShowScrollBar(true)) + param.m_pData = &m_rtStatic; + if (!IsEnabled()) + param.m_dwStates = CFWL_PartState_Disabled; + + pTheme->DrawBackground(¶m); +} + +void CFWL_ListBox::DrawItems(CFX_Graphics* pGraphics, + IFWL_ThemeProvider* pTheme, + const CFX_Matrix* pMatrix) { + FX_FLOAT fPosX = 0.0f; + if (m_pHorzScrollBar) + fPosX = m_pHorzScrollBar->GetPos(); + + FX_FLOAT fPosY = 0.0f; + if (m_pVertScrollBar) + fPosY = m_pVertScrollBar->GetPos(); + + CFX_RectF rtView(m_rtConent); + if (m_pHorzScrollBar) + rtView.height -= m_fScorllBarWidth; + if (m_pVertScrollBar) + rtView.width -= m_fScorllBarWidth; + + bool bMultiCol = + !!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiColumn); + int32_t iCount = CountItems(this); + for (int32_t i = 0; i < iCount; i++) { + CFWL_ListItem* pItem = GetItem(this, i); + if (!pItem) + continue; + + CFX_RectF rtItem; + GetItemRect(this, pItem, rtItem); + rtItem.Offset(m_rtConent.left - fPosX, m_rtConent.top - fPosY); + if (rtItem.bottom() < m_rtConent.top) + continue; + if (rtItem.top >= m_rtConent.bottom()) + break; + if (bMultiCol && rtItem.left > m_rtConent.right()) + break; + + if (!(GetStylesEx() & FWL_STYLEEXT_LTB_OwnerDraw)) + DrawItem(pGraphics, pTheme, pItem, i, rtItem, pMatrix); + } +} + +void CFWL_ListBox::DrawItem(CFX_Graphics* pGraphics, + IFWL_ThemeProvider* pTheme, + CFWL_ListItem* pItem, + int32_t Index, + const CFX_RectF& rtItem, + const CFX_Matrix* pMatrix) { + uint32_t dwItemStyles = GetItemStyles(this, pItem); + uint32_t dwPartStates = CFWL_PartState_Normal; + if (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) + dwPartStates = CFWL_PartState_Disabled; + else if (dwItemStyles & FWL_ITEMSTATE_LTB_Selected) + dwPartStates = CFWL_PartState_Selected; + + if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused && + dwItemStyles & FWL_ITEMSTATE_LTB_Focused) { + dwPartStates |= CFWL_PartState_Focused; + } + + CFWL_ThemeBackground bg_param; + bg_param.m_pWidget = this; + bg_param.m_iPart = CFWL_Part::ListItem; + bg_param.m_dwStates = dwPartStates; + bg_param.m_pGraphics = pGraphics; + bg_param.m_matrix.Concat(*pMatrix); + bg_param.m_rtPart = rtItem; + bg_param.m_bMaximize = true; + CFX_RectF rtFocus(rtItem); + bg_param.m_pData = &rtFocus; + if (m_pVertScrollBar && !m_pHorzScrollBar && + (dwPartStates & CFWL_PartState_Focused)) { + bg_param.m_rtPart.left += 1; + bg_param.m_rtPart.width -= (m_fScorllBarWidth + 1); + rtFocus.Deflate(0.5, 0.5, 1 + m_fScorllBarWidth, 1); + } + pTheme->DrawBackground(&bg_param); + + bool bHasIcon = !!(GetStylesEx() & FWL_STYLEEXT_LTB_Icon); + if (bHasIcon) { + CFX_RectF rtDIB; + CFX_DIBitmap* pDib = GetItemIcon(this, pItem); + rtDIB.Set(rtItem.left, rtItem.top, rtItem.height, rtItem.height); + if (pDib) { + CFWL_ThemeBackground param; + param.m_pWidget = this; + param.m_iPart = CFWL_Part::Icon; + param.m_pGraphics = pGraphics; + param.m_matrix.Concat(*pMatrix); + param.m_rtPart = rtDIB; + param.m_bMaximize = true; + param.m_pImage = pDib; + pTheme->DrawBackground(¶m); + } + } + + bool bHasCheck = !!(GetStylesEx() & FWL_STYLEEXT_LTB_Check); + if (bHasCheck) { + CFX_RectF rtCheck; + rtCheck.Set(rtItem.left, rtItem.top, rtItem.height, rtItem.height); + rtCheck.Deflate(2, 2, 2, 2); + SetItemCheckRect(this, pItem, rtCheck); + CFWL_ThemeBackground param; + param.m_pWidget = this; + param.m_iPart = CFWL_Part::Check; + param.m_pGraphics = pGraphics; + if (GetItemChecked(pItem)) + param.m_dwStates = CFWL_PartState_Checked; + else + param.m_dwStates = CFWL_PartState_Normal; + param.m_matrix.Concat(*pMatrix); + param.m_rtPart = rtCheck; + param.m_bMaximize = true; + pTheme->DrawBackground(¶m); + } + + CFX_WideString wsText; + GetItemText(this, pItem, wsText); + if (wsText.GetLength() <= 0) + return; + + CFX_RectF rtText(rtItem); + rtText.Deflate(kItemTextMargin, kItemTextMargin); + if (bHasIcon || bHasCheck) + rtText.Deflate(rtItem.height, 0, 0, 0); + + CFWL_ThemeText textParam; + textParam.m_pWidget = this; + textParam.m_iPart = CFWL_Part::ListItem; + textParam.m_dwStates = dwPartStates; + textParam.m_pGraphics = pGraphics; + textParam.m_matrix.Concat(*pMatrix); + textParam.m_rtPart = rtText; + textParam.m_wsText = wsText; + textParam.m_dwTTOStyles = m_dwTTOStyles; + textParam.m_iTTOAlign = m_iTTOAligns; + textParam.m_bMaximize = true; + pTheme->DrawText(&textParam); +} + +CFX_SizeF CFWL_ListBox::CalcSize(bool bAutoSize) { + CFX_SizeF fs; + if (!m_pProperties->m_pThemeProvider) + return fs; + + GetClientRect(m_rtClient); + m_rtConent = m_rtClient; + CFX_RectF rtUIMargin; + rtUIMargin.Set(0, 0, 0, 0); + if (!m_pOuter) { + CFX_RectF* pUIMargin = static_cast<CFX_RectF*>( + GetThemeCapacity(CFWL_WidgetCapacity::UIMargin)); + if (pUIMargin) { + m_rtConent.Deflate(pUIMargin->left, pUIMargin->top, pUIMargin->width, + pUIMargin->height); + } + } + + FX_FLOAT fWidth = GetMaxTextWidth(); + fWidth += 2 * kItemTextMargin; + if (!bAutoSize) { + FX_FLOAT fActualWidth = + m_rtClient.width - rtUIMargin.left - rtUIMargin.width; + fWidth = std::max(fWidth, fActualWidth); + } + + m_fItemHeight = CalcItemHeight(); + if ((GetStylesEx() & FWL_STYLEEXT_LTB_Icon)) + fWidth += m_fItemHeight; + + int32_t iCount = CountItems(this); + for (int32_t i = 0; i < iCount; i++) { + CFWL_ListItem* htem = GetItem(this, i); + GetItemSize(fs, htem, fWidth, m_fItemHeight, bAutoSize); + } + if (bAutoSize) + return fs; + + FX_FLOAT iWidth = m_rtClient.width - rtUIMargin.left - rtUIMargin.width; + FX_FLOAT iHeight = m_rtClient.height; + bool bShowVertScr = + (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_ShowScrollBarAlaways) && + (m_pProperties->m_dwStyles & FWL_WGTSTYLE_VScroll); + bool bShowHorzScr = + (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_ShowScrollBarAlaways) && + (m_pProperties->m_dwStyles & FWL_WGTSTYLE_HScroll); + if (!bShowVertScr && m_pProperties->m_dwStyles & FWL_WGTSTYLE_VScroll && + (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiColumn) == 0) { + bShowVertScr = (fs.y > iHeight); + } + if (!bShowHorzScr && m_pProperties->m_dwStyles & FWL_WGTSTYLE_HScroll) + bShowHorzScr = (fs.x > iWidth); + + CFX_SizeF szRange; + if (bShowVertScr) { + if (!m_pVertScrollBar) + InitScrollBar(); + + CFX_RectF rtScrollBar; + rtScrollBar.Set(m_rtClient.right() - m_fScorllBarWidth, m_rtClient.top, + m_fScorllBarWidth, m_rtClient.height - 1); + if (bShowHorzScr) + rtScrollBar.height -= m_fScorllBarWidth; + + m_pVertScrollBar->SetWidgetRect(rtScrollBar); + szRange.x = 0, szRange.y = fs.y - m_rtConent.height; + szRange.y = std::max(szRange.y, m_fItemHeight); + + m_pVertScrollBar->SetRange(szRange.x, szRange.y); + m_pVertScrollBar->SetPageSize(rtScrollBar.height * 9 / 10); + m_pVertScrollBar->SetStepSize(m_fItemHeight); + + FX_FLOAT fPos = + std::min(std::max(m_pVertScrollBar->GetPos(), 0.f), szRange.y); + m_pVertScrollBar->SetPos(fPos); + m_pVertScrollBar->SetTrackPos(fPos); + if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_ShowScrollBarFocus) == + 0 || + (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused)) { + m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, false); + } + m_pVertScrollBar->Update(); + } else if (m_pVertScrollBar) { + m_pVertScrollBar->SetPos(0); + m_pVertScrollBar->SetTrackPos(0); + m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, true); + } + if (bShowHorzScr) { + if (!m_pHorzScrollBar) + InitScrollBar(false); + + CFX_RectF rtScrollBar; + rtScrollBar.Set(m_rtClient.left, m_rtClient.bottom() - m_fScorllBarWidth, + m_rtClient.width, m_fScorllBarWidth); + if (bShowVertScr) + rtScrollBar.width -= m_fScorllBarWidth; + + m_pHorzScrollBar->SetWidgetRect(rtScrollBar); + szRange.x = 0, szRange.y = fs.x - rtScrollBar.width; + m_pHorzScrollBar->SetRange(szRange.x, szRange.y); + m_pHorzScrollBar->SetPageSize(fWidth * 9 / 10); + m_pHorzScrollBar->SetStepSize(fWidth / 10); + + FX_FLOAT fPos = + std::min(std::max(m_pHorzScrollBar->GetPos(), 0.f), szRange.y); + m_pHorzScrollBar->SetPos(fPos); + m_pHorzScrollBar->SetTrackPos(fPos); + if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_ShowScrollBarFocus) == + 0 || + (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused)) { + m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, false); + } + m_pHorzScrollBar->Update(); + } else if (m_pHorzScrollBar) { + m_pHorzScrollBar->SetPos(0); + m_pHorzScrollBar->SetTrackPos(0); + m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, true); + } + if (bShowVertScr && bShowHorzScr) { + m_rtStatic.Set(m_rtClient.right() - m_fScorllBarWidth, + m_rtClient.bottom() - m_fScorllBarWidth, m_fScorllBarWidth, + m_fScorllBarWidth); + } + return fs; +} + +void CFWL_ListBox::GetItemSize(CFX_SizeF& size, + CFWL_ListItem* pItem, + FX_FLOAT fWidth, + FX_FLOAT fItemHeight, + bool bAutoSize) { + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiColumn) + return; + + if (!bAutoSize) { + CFX_RectF rtItem; + rtItem.Set(0, size.y, fWidth, fItemHeight); + SetItemRect(this, pItem, rtItem); + } + size.x = fWidth; + size.y += fItemHeight; +} + +FX_FLOAT CFWL_ListBox::GetMaxTextWidth() { + FX_FLOAT fRet = 0.0f; + int32_t iCount = CountItems(this); + for (int32_t i = 0; i < iCount; i++) { + CFWL_ListItem* pItem = GetItem(this, i); + if (!pItem) + continue; + + CFX_WideString wsText; + GetItemText(this, pItem, wsText); + CFX_SizeF sz = CalcTextSize(wsText, m_pProperties->m_pThemeProvider); + fRet = std::max(fRet, sz.x); + } + return fRet; +} + +FX_FLOAT CFWL_ListBox::GetScrollWidth() { + FX_FLOAT* pfWidth = static_cast<FX_FLOAT*>( + GetThemeCapacity(CFWL_WidgetCapacity::ScrollBarWidth)); + if (!pfWidth) + return 0; + return *pfWidth; +} + +FX_FLOAT CFWL_ListBox::CalcItemHeight() { + FX_FLOAT* pfFont = + static_cast<FX_FLOAT*>(GetThemeCapacity(CFWL_WidgetCapacity::FontSize)); + if (!pfFont) + return 20; + return *pfFont + 2 * kItemTextMargin; +} + +void CFWL_ListBox::InitScrollBar(bool bVert) { + if ((bVert && m_pVertScrollBar) || (!bVert && m_pHorzScrollBar)) + return; + + auto prop = pdfium::MakeUnique<CFWL_WidgetProperties>(); + prop->m_dwStyleExes = bVert ? FWL_STYLEEXT_SCB_Vert : FWL_STYLEEXT_SCB_Horz; + prop->m_dwStates = FWL_WGTSTATE_Invisible; + prop->m_pParent = this; + prop->m_pThemeProvider = m_pScrollBarTP; + CFWL_ScrollBar* sb = new CFWL_ScrollBar(m_pOwnerApp, std::move(prop), this); + if (bVert) + m_pVertScrollBar.reset(sb); + else + m_pHorzScrollBar.reset(sb); +} + +bool CFWL_ListBox::IsShowScrollBar(bool bVert) { + CFWL_ScrollBar* pScrollbar = + bVert ? m_pVertScrollBar.get() : m_pHorzScrollBar.get(); + if (!pScrollbar || (pScrollbar->GetStates() & FWL_WGTSTATE_Invisible)) + return false; + return !(m_pProperties->m_dwStyleExes & + FWL_STYLEEXT_LTB_ShowScrollBarFocus) || + (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused); +} + +void CFWL_ListBox::OnProcessMessage(CFWL_Message* pMessage) { + if (!pMessage) + return; + if (!IsEnabled()) + return; + + CFWL_MessageType dwMsgCode = pMessage->GetClassID(); + switch (dwMsgCode) { + case CFWL_MessageType::SetFocus: + OnFocusChanged(pMessage, true); + break; + case CFWL_MessageType::KillFocus: + OnFocusChanged(pMessage, false); + break; + case CFWL_MessageType::Mouse: { + CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage); + switch (pMsg->m_dwCmd) { + case FWL_MouseCommand::LeftButtonDown: + OnLButtonDown(pMsg); + break; + case FWL_MouseCommand::LeftButtonUp: + OnLButtonUp(pMsg); + break; + default: + break; + } + break; + } + case CFWL_MessageType::MouseWheel: + OnMouseWheel(static_cast<CFWL_MsgMouseWheel*>(pMessage)); + break; + case CFWL_MessageType::Key: { + CFWL_MsgKey* pMsg = static_cast<CFWL_MsgKey*>(pMessage); + if (pMsg->m_dwCmd == FWL_KeyCommand::KeyDown) + OnKeyDown(pMsg); + break; + } + default: + break; + } + CFWL_Widget::OnProcessMessage(pMessage); +} + +void CFWL_ListBox::OnProcessEvent(CFWL_Event* pEvent) { + if (!pEvent) + return; + if (pEvent->GetClassID() != CFWL_EventType::Scroll) + return; + + CFWL_Widget* pSrcTarget = pEvent->m_pSrcTarget; + if ((pSrcTarget == m_pVertScrollBar.get() && m_pVertScrollBar) || + (pSrcTarget == m_pHorzScrollBar.get() && m_pHorzScrollBar)) { + CFWL_EvtScroll* pScrollEvent = static_cast<CFWL_EvtScroll*>(pEvent); + OnScroll(static_cast<CFWL_ScrollBar*>(pSrcTarget), + pScrollEvent->m_iScrollCode, pScrollEvent->m_fPos); + } +} + +void CFWL_ListBox::OnDrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) { + DrawWidget(pGraphics, pMatrix); +} + +void CFWL_ListBox::OnFocusChanged(CFWL_Message* pMsg, bool bSet) { + if (GetStylesEx() & FWL_STYLEEXT_LTB_ShowScrollBarFocus) { + if (m_pVertScrollBar) + m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, !bSet); + if (m_pHorzScrollBar) + m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, !bSet); + } + if (bSet) + m_pProperties->m_dwStates |= (FWL_WGTSTATE_Focused); + else + m_pProperties->m_dwStates &= ~(FWL_WGTSTATE_Focused); + + Repaint(&m_rtClient); +} + +void CFWL_ListBox::OnLButtonDown(CFWL_MsgMouse* pMsg) { + m_bLButtonDown = true; + if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) + SetFocus(true); + + CFWL_ListItem* pItem = GetItemAtPoint(pMsg->m_fx, pMsg->m_fy); + if (!pItem) + return; + + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiSelection) { + if (pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl) { + bool bSelected = IsItemSelected(pItem); + SetSelectionDirect(pItem, !bSelected); + m_hAnchor = pItem; + } else if (pMsg->m_dwFlags & FWL_KEYFLAG_Shift) { + if (m_hAnchor) + SetSelection(m_hAnchor, pItem, true); + else + SetSelectionDirect(pItem, true); + } else { + SetSelection(pItem, pItem, true); + m_hAnchor = pItem; + } + } else { + SetSelection(pItem, pItem, true); + } + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_Check) { + CFWL_ListItem* hSelectedItem = GetItemAtPoint(pMsg->m_fx, pMsg->m_fy); + CFX_RectF rtCheck; + GetItemCheckRectInternal(hSelectedItem, rtCheck); + bool bChecked = GetItemChecked(pItem); + if (rtCheck.Contains(pMsg->m_fx, pMsg->m_fy)) { + SetItemChecked(pItem, !bChecked); + Update(); + } + } + SetFocusItem(pItem); + ScrollToVisible(pItem); + SetGrab(true); + Repaint(&m_rtClient); +} + +void CFWL_ListBox::OnLButtonUp(CFWL_MsgMouse* pMsg) { + if (!m_bLButtonDown) + return; + + m_bLButtonDown = false; + SetGrab(false); +} + +void CFWL_ListBox::OnMouseWheel(CFWL_MsgMouseWheel* pMsg) { + if (IsShowScrollBar(true)) + m_pVertScrollBar->GetDelegate()->OnProcessMessage(pMsg); +} + +void CFWL_ListBox::OnKeyDown(CFWL_MsgKey* pMsg) { + uint32_t dwKeyCode = pMsg->m_dwKeyCode; + switch (dwKeyCode) { + case FWL_VKEY_Tab: + case FWL_VKEY_Up: + case FWL_VKEY_Down: + case FWL_VKEY_Home: + case FWL_VKEY_End: { + CFWL_ListItem* pItem = GetFocusedItem(); + pItem = GetListItem(pItem, dwKeyCode); + bool bShift = !!(pMsg->m_dwFlags & FWL_KEYFLAG_Shift); + bool bCtrl = !!(pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl); + OnVK(pItem, bShift, bCtrl); + break; + } + default: + break; + } +} + +void CFWL_ListBox::OnVK(CFWL_ListItem* pItem, bool bShift, bool bCtrl) { + if (!pItem) + return; + + if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiSelection) { + if (bCtrl) { + // Do nothing. + } else if (bShift) { + if (m_hAnchor) + SetSelection(m_hAnchor, pItem, true); + else + SetSelectionDirect(pItem, true); + } else { + SetSelection(pItem, pItem, true); + m_hAnchor = pItem; + } + } else { + SetSelection(pItem, pItem, true); + } + + SetFocusItem(pItem); + ScrollToVisible(pItem); + + CFX_RectF rtInvalidate; + rtInvalidate.Set(0, 0, m_pProperties->m_rtWidget.width, + m_pProperties->m_rtWidget.height); + Repaint(&rtInvalidate); +} + +bool CFWL_ListBox::OnScroll(CFWL_ScrollBar* pScrollBar, + FWL_SCBCODE dwCode, + FX_FLOAT fPos) { + CFX_SizeF fs; + pScrollBar->GetRange(&fs.x, &fs.y); + FX_FLOAT iCurPos = pScrollBar->GetPos(); + FX_FLOAT fStep = pScrollBar->GetStepSize(); + switch (dwCode) { + case FWL_SCBCODE::Min: { + fPos = fs.x; + break; + } + case FWL_SCBCODE::Max: { + fPos = fs.y; + break; + } + case FWL_SCBCODE::StepBackward: { + fPos -= fStep; + if (fPos < fs.x + fStep / 2) + fPos = fs.x; + break; + } + case FWL_SCBCODE::StepForward: { + fPos += fStep; + if (fPos > fs.y - fStep / 2) + fPos = fs.y; + break; + } + case FWL_SCBCODE::PageBackward: { + fPos -= pScrollBar->GetPageSize(); + if (fPos < fs.x) + fPos = fs.x; + break; + } + case FWL_SCBCODE::PageForward: { + fPos += pScrollBar->GetPageSize(); + if (fPos > fs.y) + fPos = fs.y; + break; + } + case FWL_SCBCODE::Pos: + case FWL_SCBCODE::TrackPos: + case FWL_SCBCODE::None: + break; + case FWL_SCBCODE::EndScroll: + return false; + } + if (iCurPos != fPos) { + pScrollBar->SetPos(fPos); + pScrollBar->SetTrackPos(fPos); + Repaint(&m_rtClient); + } + return true; +} + +void CFWL_ListBox::GetItemText(CFWL_Widget* pWidget, CFWL_ListItem* pItem, CFX_WideString& wsText) { - if (GetWidget()) - ToListBox(GetWidget())->GetItemText(pWidget, pItem, wsText); + if (pItem) + wsText = static_cast<CFWL_ListItem*>(pItem)->m_wsText; +} + +int32_t CFWL_ListBox::CountItems(const CFWL_Widget* pWidget) const { + return pdfium::CollectionSize<int32_t>(m_ItemArray); +} + +CFWL_ListItem* CFWL_ListBox::GetItem(const CFWL_Widget* pWidget, + int32_t nIndex) const { + if (nIndex < 0 || nIndex >= CountItems(pWidget)) + return nullptr; + return m_ItemArray[nIndex].get(); +} + +int32_t CFWL_ListBox::GetItemIndex(CFWL_Widget* pWidget, CFWL_ListItem* pItem) { + auto it = std::find_if( + m_ItemArray.begin(), m_ItemArray.end(), + [pItem](const std::unique_ptr<CFWL_ListItem>& candidate) { + return candidate.get() == static_cast<CFWL_ListItem*>(pItem); + }); + return it != m_ItemArray.end() ? it - m_ItemArray.begin() : -1; +} + +uint32_t CFWL_ListBox::GetItemStyles(CFWL_Widget* pWidget, + CFWL_ListItem* pItem) { + return pItem ? static_cast<CFWL_ListItem*>(pItem)->m_dwStates : 0; +} + +void CFWL_ListBox::GetItemRect(CFWL_Widget* pWidget, + CFWL_ListItem* pItem, + CFX_RectF& rtItem) { + if (pItem) + rtItem = static_cast<CFWL_ListItem*>(pItem)->m_rtItem; +} + +void* CFWL_ListBox::GetItemData(CFWL_Widget* pWidget, CFWL_ListItem* pItem) { + return pItem ? static_cast<CFWL_ListItem*>(pItem)->m_pData : nullptr; +} + +void CFWL_ListBox::SetItemStyles(CFWL_Widget* pWidget, + CFWL_ListItem* pItem, + uint32_t dwStyle) { + if (pItem) + static_cast<CFWL_ListItem*>(pItem)->m_dwStates = dwStyle; +} + +void CFWL_ListBox::SetItemRect(CFWL_Widget* pWidget, + CFWL_ListItem* pItem, + const CFX_RectF& rtItem) { + if (pItem) + static_cast<CFWL_ListItem*>(pItem)->m_rtItem = rtItem; +} + +CFX_DIBitmap* CFWL_ListBox::GetItemIcon(CFWL_Widget* pWidget, + CFWL_ListItem* pItem) { + return static_cast<CFWL_ListItem*>(pItem)->m_pDIB; +} + +void CFWL_ListBox::GetItemCheckRect(CFWL_Widget* pWidget, + CFWL_ListItem* pItem, + CFX_RectF& rtCheck) { + rtCheck = static_cast<CFWL_ListItem*>(pItem)->m_rtCheckBox; +} + +void CFWL_ListBox::SetItemCheckRect(CFWL_Widget* pWidget, + CFWL_ListItem* pItem, + const CFX_RectF& rtCheck) { + static_cast<CFWL_ListItem*>(pItem)->m_rtCheckBox = rtCheck; +} + +uint32_t CFWL_ListBox::GetItemCheckState(CFWL_Widget* pWidget, + CFWL_ListItem* pItem) { + return static_cast<CFWL_ListItem*>(pItem)->m_dwCheckState; +} + +void CFWL_ListBox::SetItemCheckState(CFWL_Widget* pWidget, + CFWL_ListItem* pItem, + uint32_t dwCheckState) { + static_cast<CFWL_ListItem*>(pItem)->m_dwCheckState = dwCheckState; } CFWL_ListItem* CFWL_ListBox::AddString(const CFX_WideStringC& wsAdd, bool bSelect) { - return GetWidget() ? ToListBox(GetWidget())->AddString(wsAdd, bSelect) - : nullptr; + auto pItem = pdfium::MakeUnique<CFWL_ListItem>(); + pItem->m_dwStates = 0; + pItem->m_wsText = wsAdd; + pItem->m_dwStates = bSelect ? FWL_ITEMSTATE_LTB_Selected : 0; + m_ItemArray.push_back(std::move(pItem)); + return m_ItemArray.back().get(); +} + +bool CFWL_ListBox::RemoveAt(int32_t iIndex) { + if (iIndex < 0 || static_cast<size_t>(iIndex) >= m_ItemArray.size()) + return false; + + m_ItemArray.erase(m_ItemArray.begin() + iIndex); + return true; } bool CFWL_ListBox::DeleteString(CFWL_ListItem* pItem) { - return GetWidget() && ToListBox(GetWidget())->DeleteString(pItem); + int32_t nIndex = GetItemIndex(this, pItem); + if (nIndex < 0 || static_cast<size_t>(nIndex) >= m_ItemArray.size()) + return false; + + int32_t iSel = nIndex + 1; + if (iSel >= CountItems(this)) + iSel = nIndex - 1; + if (iSel >= 0) { + CFWL_ListItem* pSel = static_cast<CFWL_ListItem*>(GetItem(this, iSel)); + pSel->m_dwStates |= FWL_ITEMSTATE_LTB_Selected; + } + m_ItemArray.erase(m_ItemArray.begin() + nIndex); + return true; } void CFWL_ListBox::DeleteAll() { - if (GetWidget()) - ToListBox(GetWidget())->DeleteAll(); + m_ItemArray.clear(); } uint32_t CFWL_ListBox::GetItemStates(CFWL_ListItem* pItem) { @@ -68,19 +1131,3 @@ uint32_t CFWL_ListBox::GetItemStates(CFWL_ListItem* pItem) { return pItem->m_dwStates | pItem->m_dwCheckState; } -int32_t CFWL_ListBox::CountSelItems() { - return GetWidget() ? ToListBox(GetWidget())->CountSelItems() : 0; -} - -CFWL_ListItem* CFWL_ListBox::GetSelItem(int32_t nIndexSel) { - return GetWidget() ? ToListBox(GetWidget())->GetSelItem(nIndexSel) : nullptr; -} - -int32_t CFWL_ListBox::GetSelIndex(int32_t nIndex) { - return GetWidget() ? ToListBox(GetWidget())->GetSelIndex(nIndex) : 0; -} - -void CFWL_ListBox::SetSelItem(CFWL_ListItem* pItem, bool bSelect) { - if (GetWidget()) - ToListBox(GetWidget())->SetSelItem(pItem, bSelect); -} diff --git a/xfa/fwl/core/cfwl_listbox.h b/xfa/fwl/core/cfwl_listbox.h index 36d13bd2ce..a758e196ea 100644 --- a/xfa/fwl/core/cfwl_listbox.h +++ b/xfa/fwl/core/cfwl_listbox.h @@ -10,31 +10,160 @@ #include <memory> #include <vector> +#include "xfa/fwl/core/cfwl_edit.h" +#include "xfa/fwl/core/cfwl_event.h" +#include "xfa/fwl/core/cfwl_listbox.h" #include "xfa/fwl/core/cfwl_listitem.h" #include "xfa/fwl/core/cfwl_widget.h" -#include "xfa/fwl/core/fwl_error.h" +#include "xfa/fwl/core/cfwl_widgetproperties.h" + +#define FWL_STYLEEXT_LTB_MultiSelection (1L << 0) +#define FWL_STYLEEXT_LTB_ShowScrollBarAlaways (1L << 2) +#define FWL_STYLEEXT_LTB_MultiColumn (1L << 3) +#define FWL_STYLEEXT_LTB_LeftAlign (0L << 4) +#define FWL_STYLEEXT_LTB_CenterAlign (1L << 4) +#define FWL_STYLEEXT_LTB_RightAlign (2L << 4) +#define FWL_STYLEEXT_LTB_MultiLine (1L << 6) +#define FWL_STYLEEXT_LTB_OwnerDraw (1L << 7) +#define FWL_STYLEEXT_LTB_Icon (1L << 8) +#define FWL_STYLEEXT_LTB_Check (1L << 9) +#define FWL_STYLEEXT_LTB_AlignMask (3L << 4) +#define FWL_STYLEEXT_LTB_ShowScrollBarFocus (1L << 10) +#define FWL_ITEMSTATE_LTB_Selected (1L << 0) +#define FWL_ITEMSTATE_LTB_Focused (1L << 1) +#define FWL_ITEMSTATE_LTB_Checked (1L << 2) + +class CFWL_MsgKillFocus; +class CFWL_MsgMouse; +class CFWL_MsgMouseWheel; +class CFX_DIBitmap; class CFWL_ListBox : public CFWL_Widget { public: - explicit CFWL_ListBox(const CFWL_App* pApp); + explicit CFWL_ListBox(const CFWL_App* pApp, + std::unique_ptr<CFWL_WidgetProperties> properties, + CFWL_Widget* pOuter); ~CFWL_ListBox() override; - void Initialize(); + // CFWL_Widget + FWL_Type GetClassID() const override; + void GetWidgetRect(CFX_RectF& rect, bool bAutoSize = false) override; + void Update() override; + FWL_WidgetHit HitTest(FX_FLOAT fx, FX_FLOAT fy) override; + void DrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix = nullptr) override; + void SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) override; + void OnProcessMessage(CFWL_Message* pMessage) override; + void OnProcessEvent(CFWL_Event* pEvent) override; + void OnDrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) override; - CFWL_ListItem* GetItem(const IFWL_Widget* pWidget, int32_t nIndex) const; - void GetItemText(IFWL_Widget* pWidget, + int32_t CountItems(const CFWL_Widget* pWidget) const; + CFWL_ListItem* GetItem(const CFWL_Widget* pWidget, int32_t nIndex) const; + int32_t GetItemIndex(CFWL_Widget* pWidget, CFWL_ListItem* pItem); + uint32_t GetItemStyles(CFWL_Widget* pWidget, CFWL_ListItem* pItem); + uint32_t GetItemStates(CFWL_ListItem* pItem); + void GetItemText(CFWL_Widget* pWidget, CFWL_ListItem* pItem, CFX_WideString& wsText); - + void GetItemRect(CFWL_Widget* pWidget, + CFWL_ListItem* pItem, + CFX_RectF& rtItem); + void* GetItemData(CFWL_Widget* pWidget, CFWL_ListItem* pItem); + void SetItemStyles(CFWL_Widget* pWidget, + CFWL_ListItem* pItem, + uint32_t dwStyle); + void SetItemRect(CFWL_Widget* pWidget, + CFWL_ListItem* pItem, + const CFX_RectF& rtItem); + CFX_DIBitmap* GetItemIcon(CFWL_Widget* pWidget, CFWL_ListItem* pItem); + void GetItemCheckRect(CFWL_Widget* pWidget, + CFWL_ListItem* pItem, + CFX_RectF& rtCheck); + void SetItemCheckRect(CFWL_Widget* pWidget, + CFWL_ListItem* pItem, + const CFX_RectF& rtCheck); + uint32_t GetItemCheckState(CFWL_Widget* pWidget, CFWL_ListItem* pItem); + void SetItemCheckState(CFWL_Widget* pWidget, + CFWL_ListItem* pItem, + uint32_t dwCheckState); CFWL_ListItem* AddString(const CFX_WideStringC& wsAdd, bool bSelect = false); + bool RemoveAt(int32_t iIndex); bool DeleteString(CFWL_ListItem* pItem); void DeleteAll(); + int32_t CountSelItems(); - void SetSelItem(CFWL_ListItem* pItem, bool bSelect = true); CFWL_ListItem* GetSelItem(int32_t nIndexSel); int32_t GetSelIndex(int32_t nIndex); + void SetSelItem(CFWL_ListItem* hItem, bool bSelect = true); + void GetDataProviderItemText(CFWL_ListItem* hItem, CFX_WideString& wsText); - uint32_t GetItemStates(CFWL_ListItem* pItem); + FX_FLOAT GetItemHeight() const { return m_fItemHeight; } + FX_FLOAT CalcItemHeight(); + + protected: + CFWL_ListItem* GetListItem(CFWL_ListItem* hItem, uint32_t dwKeyCode); + void SetSelection(CFWL_ListItem* hStart, CFWL_ListItem* hEnd, bool bSelected); + CFWL_ListItem* GetItemAtPoint(FX_FLOAT fx, FX_FLOAT fy); + bool ScrollToVisible(CFWL_ListItem* hItem); + void InitScrollBar(bool bVert = true); + bool IsShowScrollBar(bool bVert); + CFWL_ScrollBar* GetVertScrollBar() const { return m_pVertScrollBar.get(); } + const CFX_RectF& GetRTClient() const { return m_rtClient; } + + private: + void SetSelectionDirect(CFWL_ListItem* hItem, bool bSelect); + bool IsItemSelected(CFWL_ListItem* hItem); + void ClearSelection(); + void SelectAll(); + CFWL_ListItem* GetFocusedItem(); + void SetFocusItem(CFWL_ListItem* hItem); + bool GetItemCheckRectInternal(CFWL_ListItem* hItem, CFX_RectF& rtCheck); + bool SetItemChecked(CFWL_ListItem* hItem, bool bChecked); + bool GetItemChecked(CFWL_ListItem* hItem); + void DrawBkground(CFX_Graphics* pGraphics, + IFWL_ThemeProvider* pTheme, + const CFX_Matrix* pMatrix = nullptr); + void DrawItems(CFX_Graphics* pGraphics, + IFWL_ThemeProvider* pTheme, + const CFX_Matrix* pMatrix = nullptr); + void DrawItem(CFX_Graphics* pGraphics, + IFWL_ThemeProvider* pTheme, + CFWL_ListItem* hItem, + int32_t Index, + const CFX_RectF& rtItem, + const CFX_Matrix* pMatrix = nullptr); + void DrawStatic(CFX_Graphics* pGraphics, IFWL_ThemeProvider* pTheme); + CFX_SizeF CalcSize(bool bAutoSize = false); + void GetItemSize(CFX_SizeF& size, + CFWL_ListItem* hItem, + FX_FLOAT fWidth, + FX_FLOAT fHeight, + bool bAutoSize = false); + FX_FLOAT GetMaxTextWidth(); + FX_FLOAT GetScrollWidth(); + + void OnFocusChanged(CFWL_Message* pMsg, bool bSet = true); + void OnLButtonDown(CFWL_MsgMouse* pMsg); + void OnLButtonUp(CFWL_MsgMouse* pMsg); + void OnMouseWheel(CFWL_MsgMouseWheel* pMsg); + void OnKeyDown(CFWL_MsgKey* pMsg); + void OnVK(CFWL_ListItem* hItem, bool bShift, bool bCtrl); + bool OnScroll(CFWL_ScrollBar* pScrollBar, FWL_SCBCODE dwCode, FX_FLOAT fPos); + + CFX_RectF m_rtClient; + CFX_RectF m_rtStatic; + CFX_RectF m_rtConent; + std::unique_ptr<CFWL_ScrollBar> m_pHorzScrollBar; + std::unique_ptr<CFWL_ScrollBar> m_pVertScrollBar; + uint32_t m_dwTTOStyles; + int32_t m_iTTOAligns; + CFWL_ListItem* m_hAnchor; + FX_FLOAT m_fItemHeight; + FX_FLOAT m_fScorllBarWidth; + bool m_bLButtonDown; + IFWL_ThemeProvider* m_pScrollBarTP; + std::vector<std::unique_ptr<CFWL_ListItem>> m_ItemArray; }; #endif // XFA_FWL_CORE_CFWL_LISTBOX_H_ diff --git a/xfa/fwl/core/cfwl_message.h b/xfa/fwl/core/cfwl_message.h index 1ad43a6d89..827b4181e3 100644 --- a/xfa/fwl/core/cfwl_message.h +++ b/xfa/fwl/core/cfwl_message.h @@ -23,7 +23,7 @@ enum class CFWL_MessageType { SetFocus }; -class IFWL_Widget; +class CFWL_Widget; class CFWL_Message { public: @@ -33,8 +33,8 @@ class CFWL_Message { virtual std::unique_ptr<CFWL_Message> Clone(); virtual CFWL_MessageType GetClassID() const; - IFWL_Widget* m_pSrcTarget; - IFWL_Widget* m_pDstTarget; + CFWL_Widget* m_pSrcTarget; + CFWL_Widget* m_pDstTarget; uint32_t m_dwExtend; }; diff --git a/xfa/fwl/core/cfwl_monthcalendar.cpp b/xfa/fwl/core/cfwl_monthcalendar.cpp index 4f7cff0322..9d22b13509 100644 --- a/xfa/fwl/core/cfwl_monthcalendar.cpp +++ b/xfa/fwl/core/cfwl_monthcalendar.cpp @@ -12,12 +12,12 @@ #include "third_party/base/ptr_util.h" #include "xfa/fde/tto/fde_textout.h" +#include "xfa/fwl/core/cfwl_datetimepicker.h" #include "xfa/fwl/core/cfwl_formproxy.h" #include "xfa/fwl/core/cfwl_msgmouse.h" #include "xfa/fwl/core/cfwl_notedriver.h" #include "xfa/fwl/core/cfwl_themebackground.h" #include "xfa/fwl/core/cfwl_themetext.h" -#include "xfa/fwl/core/ifwl_datetimepicker.h" #include "xfa/fwl/core/ifwl_themeprovider.h" #define MONTHCAL_HSEP_HEIGHT 1 @@ -124,8 +124,8 @@ CFX_WideString* GetCapacityForMonth(IFWL_ThemeProvider* pTheme, CFWL_MonthCalendar::CFWL_MonthCalendar( const CFWL_App* app, std::unique_ptr<CFWL_WidgetProperties> properties, - IFWL_Widget* pOuter) - : IFWL_Widget(app, std::move(properties), pOuter), + CFWL_Widget* pOuter) + : CFWL_Widget(app, std::move(properties), pOuter), m_bInitialized(false), m_pDateTime(new CFX_DateTime), m_iCurYear(2011), @@ -168,7 +168,7 @@ void CFWL_MonthCalendar::GetWidgetRect(CFX_RectF& rect, bool bAutoSize) { CFX_SizeF fs = CalcSize(true); rect.Set(0, 0, fs.x, fs.y); - IFWL_Widget::GetWidgetRect(rect, true); + CFWL_Widget::GetWidgetRect(rect, true); } void CFWL_MonthCalendar::Update() { @@ -943,7 +943,7 @@ void CFWL_MonthCalendar::OnProcessMessage(CFWL_Message* pMessage) { default: break; } - IFWL_Widget::OnProcessMessage(pMessage); + CFWL_Widget::OnProcessMessage(pMessage); } void CFWL_MonthCalendar::OnDrawWidget(CFX_Graphics* pGraphics, @@ -966,7 +966,7 @@ void CFWL_MonthCalendar::OnLButtonDown(CFWL_MsgMouse* pMsg) { Repaint(&m_rtClient); } } else { - IFWL_DateTimePicker* pIPicker = static_cast<IFWL_DateTimePicker*>(m_pOuter); + CFWL_DateTimePicker* pIPicker = static_cast<CFWL_DateTimePicker*>(m_pOuter); if (pIPicker->IsMonthCalendarVisible()) m_bFlag = 1; } @@ -995,7 +995,7 @@ void CFWL_MonthCalendar::OnLButtonUp(CFWL_MsgMouse* pMsg) { int32_t iCurSel = GetDayAtPoint(pMsg->m_fx, pMsg->m_fy); CFX_RectF rt; - IFWL_DateTimePicker* pIPicker = static_cast<IFWL_DateTimePicker*>(m_pOuter); + CFWL_DateTimePicker* pIPicker = static_cast<CFWL_DateTimePicker*>(m_pOuter); pIPicker->GetFormProxy()->GetWidgetRect(rt); rt.Set(0, 0, rt.width, rt.height); if (iCurSel > 0) { @@ -1044,8 +1044,8 @@ void CFWL_MonthCalendar::DisForm_OnLButtonUp(CFWL_MsgMouse* pMsg) { rtInvalidate.Union(lpDatesInfo->rect); } AddSelDay(iCurSel); - IFWL_DateTimePicker* pDateTime = - static_cast<IFWL_DateTimePicker*>(m_pOuter); + CFWL_DateTimePicker* pDateTime = + static_cast<CFWL_DateTimePicker*>(m_pOuter); pDateTime->ProcessSelChanged(m_iCurYear, m_iCurMonth, iCurSel); pDateTime->ShowMonthCalendar(false); } diff --git a/xfa/fwl/core/cfwl_monthcalendar.h b/xfa/fwl/core/cfwl_monthcalendar.h index 1acdf5c977..6c004aa236 100644 --- a/xfa/fwl/core/cfwl_monthcalendar.h +++ b/xfa/fwl/core/cfwl_monthcalendar.h @@ -11,8 +11,8 @@ #include "xfa/fgas/localization/fgas_datetime.h" #include "xfa/fwl/core/cfwl_event.h" +#include "xfa/fwl/core/cfwl_widget.h" #include "xfa/fwl/core/cfwl_widgetproperties.h" -#include "xfa/fwl/core/ifwl_widget.h" #define FWL_STYLEEXT_MCD_MultiSelect (1L << 0) #define FWL_STYLEEXT_MCD_NoToday (1L << 1) @@ -24,13 +24,13 @@ #define FWL_ITEMSTATE_MCD_Focused (1L << 2) class CFWL_MsgMouse; -class IFWL_Widget; +class CFWL_Widget; -class CFWL_MonthCalendar : public IFWL_Widget { +class CFWL_MonthCalendar : public CFWL_Widget { public: CFWL_MonthCalendar(const CFWL_App* app, std::unique_ptr<CFWL_WidgetProperties> properties, - IFWL_Widget* pOuter); + CFWL_Widget* pOuter); ~CFWL_MonthCalendar() override; // FWL_WidgetImp diff --git a/xfa/fwl/core/cfwl_msgkillfocus.h b/xfa/fwl/core/cfwl_msgkillfocus.h index 71c52d90c7..ef687524f9 100644 --- a/xfa/fwl/core/cfwl_msgkillfocus.h +++ b/xfa/fwl/core/cfwl_msgkillfocus.h @@ -20,7 +20,7 @@ class CFWL_MsgKillFocus : public CFWL_Message { std::unique_ptr<CFWL_Message> Clone() override; CFWL_MessageType GetClassID() const override; - IFWL_Widget* m_pSetFocus; + CFWL_Widget* m_pSetFocus; }; #endif // XFA_FWL_CORE_CFWL_MSGKILLFOCUS_H_ diff --git a/xfa/fwl/core/cfwl_msgsetfocus.h b/xfa/fwl/core/cfwl_msgsetfocus.h index 47eab2a12a..42f14ede77 100644 --- a/xfa/fwl/core/cfwl_msgsetfocus.h +++ b/xfa/fwl/core/cfwl_msgsetfocus.h @@ -20,7 +20,7 @@ class CFWL_MsgSetFocus : public CFWL_Message { std::unique_ptr<CFWL_Message> Clone() override; CFWL_MessageType GetClassID() const override; - IFWL_Widget* m_pKillFocus; + CFWL_Widget* m_pKillFocus; }; #endif // XFA_FWL_CORE_CFWL_MSGSETFOCUS_H_ diff --git a/xfa/fwl/core/cfwl_notedriver.cpp b/xfa/fwl/core/cfwl_notedriver.cpp index c12882a47e..06d8fd5df9 100644 --- a/xfa/fwl/core/cfwl_notedriver.cpp +++ b/xfa/fwl/core/cfwl_notedriver.cpp @@ -45,8 +45,8 @@ void CFWL_NoteDriver::SendEvent(CFWL_Event* pNote) { } } -void CFWL_NoteDriver::RegisterEventTarget(IFWL_Widget* pListener, - IFWL_Widget* pEventSource) { +void CFWL_NoteDriver::RegisterEventTarget(CFWL_Widget* pListener, + CFWL_Widget* pEventSource) { uint32_t key = pListener->GetEventKey(); if (key == 0) { do { @@ -60,7 +60,7 @@ void CFWL_NoteDriver::RegisterEventTarget(IFWL_Widget* pListener, m_eventTargets[key]->SetEventSource(pEventSource); } -void CFWL_NoteDriver::UnregisterEventTarget(IFWL_Widget* pListener) { +void CFWL_NoteDriver::UnregisterEventTarget(CFWL_Widget* pListener) { uint32_t key = pListener->GetEventKey(); if (key == 0) return; @@ -84,11 +84,11 @@ CFWL_NoteLoop* CFWL_NoteDriver::PopNoteLoop() { return p; } -bool CFWL_NoteDriver::SetFocus(IFWL_Widget* pFocus, bool bNotify) { +bool CFWL_NoteDriver::SetFocus(CFWL_Widget* pFocus, bool bNotify) { if (m_pFocus == pFocus) return true; - IFWL_Widget* pPrev = m_pFocus; + CFWL_Widget* pPrev = m_pFocus; m_pFocus = pFocus; if (pPrev) { CFWL_MsgKillFocus ms; @@ -101,7 +101,7 @@ bool CFWL_NoteDriver::SetFocus(IFWL_Widget* pFocus, bool bNotify) { pDelegate->OnProcessMessage(&ms); } if (pFocus) { - IFWL_Widget* pWidget = + CFWL_Widget* pWidget = pFocus->GetOwnerApp()->GetWidgetMgr()->GetSystemFormWidget(pFocus); CFWL_Form* pForm = static_cast<CFWL_Form*>(pWidget); if (pForm) @@ -129,7 +129,7 @@ void CFWL_NoteDriver::Run() { #endif } -void CFWL_NoteDriver::NotifyTargetHide(IFWL_Widget* pNoteTarget) { +void CFWL_NoteDriver::NotifyTargetHide(CFWL_Widget* pNoteTarget) { if (m_pFocus == pNoteTarget) m_pFocus = nullptr; if (m_pHover == pNoteTarget) @@ -138,7 +138,7 @@ void CFWL_NoteDriver::NotifyTargetHide(IFWL_Widget* pNoteTarget) { m_pGrab = nullptr; } -void CFWL_NoteDriver::NotifyTargetDestroy(IFWL_Widget* pNoteTarget) { +void CFWL_NoteDriver::NotifyTargetDestroy(CFWL_Widget* pNoteTarget) { if (m_pFocus == pNoteTarget) m_pFocus = nullptr; if (m_pHover == pNoteTarget) @@ -153,7 +153,7 @@ void CFWL_NoteDriver::NotifyTargetDestroy(IFWL_Widget* pNoteTarget) { if (!pForm) continue; - IFWL_Widget* pSubFocus = pForm->GetSubFocus(); + CFWL_Widget* pSubFocus = pForm->GetSubFocus(); if (!pSubFocus) return; if (pSubFocus == pNoteTarget) @@ -161,7 +161,7 @@ void CFWL_NoteDriver::NotifyTargetDestroy(IFWL_Widget* pNoteTarget) { } } -void CFWL_NoteDriver::RegisterForm(IFWL_Widget* pForm) { +void CFWL_NoteDriver::RegisterForm(CFWL_Widget* pForm) { if (!pForm || m_forms.Find(pForm) >= 0) return; @@ -176,7 +176,7 @@ void CFWL_NoteDriver::RegisterForm(IFWL_Widget* pForm) { pLoop->SetMainForm(pForm); } -void CFWL_NoteDriver::UnRegisterForm(IFWL_Widget* pForm) { +void CFWL_NoteDriver::UnRegisterForm(CFWL_Widget* pForm) { if (!pForm) return; @@ -214,7 +214,7 @@ CFWL_NoteLoop* CFWL_NoteDriver::GetTopLoop() const { void CFWL_NoteDriver::ProcessMessage(CFWL_Message* pMessage) { CFWL_WidgetMgr* pWidgetMgr = pMessage->m_pDstTarget->GetOwnerApp()->GetWidgetMgr(); - IFWL_Widget* pMessageForm = pWidgetMgr->IsFormDisabled() + CFWL_Widget* pMessageForm = pWidgetMgr->IsFormDisabled() ? pMessage->m_pDstTarget : GetMessageForm(pMessage->m_pDstTarget); if (!pMessageForm) @@ -227,7 +227,7 @@ void CFWL_NoteDriver::ProcessMessage(CFWL_Message* pMessage) { } bool CFWL_NoteDriver::DispatchMessage(CFWL_Message* pMessage, - IFWL_Widget* pMessageForm) { + CFWL_Widget* pMessageForm) { switch (pMessage->GetClassID()) { case CFWL_MessageType::SetFocus: { if (!DoSetFocus(pMessage, pMessageForm)) @@ -264,19 +264,19 @@ bool CFWL_NoteDriver::DispatchMessage(CFWL_Message* pMessage, } bool CFWL_NoteDriver::DoSetFocus(CFWL_Message* pMessage, - IFWL_Widget* pMessageForm) { + CFWL_Widget* pMessageForm) { CFWL_WidgetMgr* pWidgetMgr = pMessageForm->GetOwnerApp()->GetWidgetMgr(); if (pWidgetMgr->IsFormDisabled()) { m_pFocus = pMessage->m_pDstTarget; return true; } - IFWL_Widget* pWidget = pMessage->m_pDstTarget; + CFWL_Widget* pWidget = pMessage->m_pDstTarget; if (!pWidget) return false; CFWL_Form* pForm = static_cast<CFWL_Form*>(pWidget); - IFWL_Widget* pSubFocus = pForm->GetSubFocus(); + CFWL_Widget* pSubFocus = pForm->GetSubFocus(); if (pSubFocus && ((pSubFocus->GetStates() & FWL_WGTSTATE_Focused) == 0)) { pMessage->m_pDstTarget = pSubFocus; if (m_pFocus != pMessage->m_pDstTarget) { @@ -288,7 +288,7 @@ bool CFWL_NoteDriver::DoSetFocus(CFWL_Message* pMessage, } bool CFWL_NoteDriver::DoKillFocus(CFWL_Message* pMessage, - IFWL_Widget* pMessageForm) { + CFWL_Widget* pMessageForm) { CFWL_WidgetMgr* pWidgetMgr = pMessageForm->GetOwnerApp()->GetWidgetMgr(); if (pWidgetMgr->IsFormDisabled()) { if (m_pFocus == pMessage->m_pDstTarget) @@ -300,7 +300,7 @@ bool CFWL_NoteDriver::DoKillFocus(CFWL_Message* pMessage, if (!pForm) return false; - IFWL_Widget* pSubFocus = pForm->GetSubFocus(); + CFWL_Widget* pSubFocus = pForm->GetSubFocus(); if (pSubFocus && (pSubFocus->GetStates() & FWL_WGTSTATE_Focused)) { pMessage->m_pDstTarget = pSubFocus; if (m_pFocus == pMessage->m_pDstTarget) { @@ -311,19 +311,19 @@ bool CFWL_NoteDriver::DoKillFocus(CFWL_Message* pMessage, return false; } -bool CFWL_NoteDriver::DoKey(CFWL_Message* pMessage, IFWL_Widget* pMessageForm) { +bool CFWL_NoteDriver::DoKey(CFWL_Message* pMessage, CFWL_Widget* pMessageForm) { CFWL_MsgKey* pMsg = static_cast<CFWL_MsgKey*>(pMessage); #if (_FX_OS_ != _FX_MACOSX_) if (pMsg->m_dwCmd == FWL_KeyCommand::KeyDown && pMsg->m_dwKeyCode == FWL_VKEY_Tab) { CFWL_WidgetMgr* pWidgetMgr = pMessageForm->GetOwnerApp()->GetWidgetMgr(); - IFWL_Widget* pForm = GetMessageForm(pMsg->m_pDstTarget); - IFWL_Widget* pFocus = m_pFocus; + CFWL_Widget* pForm = GetMessageForm(pMsg->m_pDstTarget); + CFWL_Widget* pFocus = m_pFocus; if (m_pFocus && pWidgetMgr->GetSystemFormWidget(m_pFocus) != pForm) pFocus = nullptr; bool bFind = false; - IFWL_Widget* pNextTabStop = pWidgetMgr->NextTab(pForm, pFocus, bFind); + CFWL_Widget* pNextTabStop = pWidgetMgr->NextTab(pForm, pFocus, bFind); if (!pNextTabStop) { bFind = false; pNextTabStop = pWidgetMgr->NextTab(pForm, nullptr, bFind); @@ -340,7 +340,7 @@ bool CFWL_NoteDriver::DoKey(CFWL_Message* pMessage, IFWL_Widget* pMessageForm) { if (pMsg->m_dwCmd == FWL_KeyCommand::KeyDown && pMsg->m_dwKeyCode == FWL_VKEY_Return) { CFWL_WidgetMgr* pWidgetMgr = pMessageForm->GetOwnerApp()->GetWidgetMgr(); - IFWL_Widget* defButton = pWidgetMgr->GetDefaultButton(pMessageForm); + CFWL_Widget* defButton = pWidgetMgr->GetDefaultButton(pMessageForm); if (defButton) { pMsg->m_pDstTarget = defButton; return true; @@ -353,7 +353,7 @@ bool CFWL_NoteDriver::DoKey(CFWL_Message* pMessage, IFWL_Widget* pMessageForm) { } bool CFWL_NoteDriver::DoMouse(CFWL_Message* pMessage, - IFWL_Widget* pMessageForm) { + CFWL_Widget* pMessageForm) { CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage); if (pMsg->m_dwCmd == FWL_MouseCommand::Leave || pMsg->m_dwCmd == FWL_MouseCommand::Hover || @@ -368,13 +368,13 @@ bool CFWL_NoteDriver::DoMouse(CFWL_Message* pMessage, } bool CFWL_NoteDriver::DoWheel(CFWL_Message* pMessage, - IFWL_Widget* pMessageForm) { + CFWL_Widget* pMessageForm) { CFWL_WidgetMgr* pWidgetMgr = pMessageForm->GetOwnerApp()->GetWidgetMgr(); if (!pWidgetMgr) return false; CFWL_MsgMouseWheel* pMsg = static_cast<CFWL_MsgMouseWheel*>(pMessage); - IFWL_Widget* pDst = + CFWL_Widget* pDst = pWidgetMgr->GetWidgetAtPoint(pMessageForm, pMsg->m_fx, pMsg->m_fy); if (!pDst) return false; @@ -385,11 +385,11 @@ bool CFWL_NoteDriver::DoWheel(CFWL_Message* pMessage, } bool CFWL_NoteDriver::DoMouseEx(CFWL_Message* pMessage, - IFWL_Widget* pMessageForm) { + CFWL_Widget* pMessageForm) { CFWL_WidgetMgr* pWidgetMgr = pMessageForm->GetOwnerApp()->GetWidgetMgr(); if (!pWidgetMgr) return false; - IFWL_Widget* pTarget = nullptr; + CFWL_Widget* pTarget = nullptr; if (m_pGrab) pTarget = m_pGrab; @@ -410,7 +410,7 @@ bool CFWL_NoteDriver::DoMouseEx(CFWL_Message* pMessage, } void CFWL_NoteDriver::MouseSecondary(CFWL_Message* pMessage) { - IFWL_Widget* pTarget = pMessage->m_pDstTarget; + CFWL_Widget* pTarget = pMessage->m_pDstTarget; if (pTarget == m_pHover) return; @@ -444,7 +444,7 @@ void CFWL_NoteDriver::MouseSecondary(CFWL_Message* pMessage) { bool CFWL_NoteDriver::IsValidMessage(CFWL_Message* pMessage) { for (int32_t i = 0; i < m_noteLoopQueue.GetSize(); i++) { CFWL_NoteLoop* pNoteLoop = m_noteLoopQueue[i]; - IFWL_Widget* pForm = pNoteLoop->GetForm(); + CFWL_Widget* pForm = pNoteLoop->GetForm(); if (pForm && (pForm == pMessage->m_pDstTarget)) return true; } @@ -457,12 +457,12 @@ bool CFWL_NoteDriver::IsValidMessage(CFWL_Message* pMessage) { return false; } -IFWL_Widget* CFWL_NoteDriver::GetMessageForm(IFWL_Widget* pDstTarget) { +CFWL_Widget* CFWL_NoteDriver::GetMessageForm(CFWL_Widget* pDstTarget) { int32_t iTrackLoop = m_noteLoopQueue.GetSize(); if (iTrackLoop <= 0) return nullptr; - IFWL_Widget* pMessageForm = nullptr; + CFWL_Widget* pMessageForm = nullptr; if (iTrackLoop > 1) pMessageForm = m_noteLoopQueue[iTrackLoop - 1]->GetForm(); else if (m_forms.Find(pDstTarget) < 0) diff --git a/xfa/fwl/core/cfwl_notedriver.h b/xfa/fwl/core/cfwl_notedriver.h index ee9b384e7a..9fdb3427ab 100644 --- a/xfa/fwl/core/cfwl_notedriver.h +++ b/xfa/fwl/core/cfwl_notedriver.h @@ -12,13 +12,13 @@ #include <unordered_map> #include "xfa/fwl/core/cfwl_event.h" -#include "xfa/fwl/core/ifwl_widget.h" +#include "xfa/fwl/core/cfwl_widget.h" #include "xfa/fxgraphics/cfx_graphics.h" class CFWL_EventTarget; class CFWL_NoteLoop; class CFWL_TargetImp; -class IFWL_Widget; +class CFWL_Widget; class CFWL_NoteDriver { public: @@ -27,51 +27,51 @@ class CFWL_NoteDriver { void SendEvent(CFWL_Event* pNote); - void RegisterEventTarget(IFWL_Widget* pListener, IFWL_Widget* pEventSource); - void UnregisterEventTarget(IFWL_Widget* pListener); + void RegisterEventTarget(CFWL_Widget* pListener, CFWL_Widget* pEventSource); + void UnregisterEventTarget(CFWL_Widget* pListener); void ClearEventTargets(bool bRemoveAll); CFWL_NoteLoop* GetTopLoop() const; void PushNoteLoop(CFWL_NoteLoop* pNoteLoop); CFWL_NoteLoop* PopNoteLoop(); - IFWL_Widget* GetFocus() const { return m_pFocus; } - bool SetFocus(IFWL_Widget* pFocus, bool bNotify = false); - void SetGrab(IFWL_Widget* pGrab, bool bSet) { + CFWL_Widget* GetFocus() const { return m_pFocus; } + bool SetFocus(CFWL_Widget* pFocus, bool bNotify = false); + void SetGrab(CFWL_Widget* pGrab, bool bSet) { m_pGrab = bSet ? pGrab : nullptr; } void Run(); - void NotifyTargetHide(IFWL_Widget* pNoteTarget); - void NotifyTargetDestroy(IFWL_Widget* pNoteTarget); + void NotifyTargetHide(CFWL_Widget* pNoteTarget); + void NotifyTargetDestroy(CFWL_Widget* pNoteTarget); - void RegisterForm(IFWL_Widget* pForm); - void UnRegisterForm(IFWL_Widget* pForm); + void RegisterForm(CFWL_Widget* pForm); + void UnRegisterForm(CFWL_Widget* pForm); void QueueMessage(std::unique_ptr<CFWL_Message> pMessage); void UnqueueMessage(CFWL_NoteLoop* pNoteLoop); void ProcessMessage(CFWL_Message* pMessage); private: - bool DispatchMessage(CFWL_Message* pMessage, IFWL_Widget* pMessageForm); - bool DoSetFocus(CFWL_Message* pMsg, IFWL_Widget* pMessageForm); - bool DoKillFocus(CFWL_Message* pMsg, IFWL_Widget* pMessageForm); - bool DoKey(CFWL_Message* pMsg, IFWL_Widget* pMessageForm); - bool DoMouse(CFWL_Message* pMsg, IFWL_Widget* pMessageForm); - bool DoWheel(CFWL_Message* pMsg, IFWL_Widget* pMessageForm); - bool DoMouseEx(CFWL_Message* pMsg, IFWL_Widget* pMessageForm); + bool DispatchMessage(CFWL_Message* pMessage, CFWL_Widget* pMessageForm); + bool DoSetFocus(CFWL_Message* pMsg, CFWL_Widget* pMessageForm); + bool DoKillFocus(CFWL_Message* pMsg, CFWL_Widget* pMessageForm); + bool DoKey(CFWL_Message* pMsg, CFWL_Widget* pMessageForm); + bool DoMouse(CFWL_Message* pMsg, CFWL_Widget* pMessageForm); + bool DoWheel(CFWL_Message* pMsg, CFWL_Widget* pMessageForm); + bool DoMouseEx(CFWL_Message* pMsg, CFWL_Widget* pMessageForm); void MouseSecondary(CFWL_Message* pMsg); bool IsValidMessage(CFWL_Message* pMessage); - IFWL_Widget* GetMessageForm(IFWL_Widget* pDstTarget); + CFWL_Widget* GetMessageForm(CFWL_Widget* pDstTarget); - CFX_ArrayTemplate<IFWL_Widget*> m_forms; + CFX_ArrayTemplate<CFWL_Widget*> m_forms; std::deque<std::unique_ptr<CFWL_Message>> m_noteQueue; CFX_ArrayTemplate<CFWL_NoteLoop*> m_noteLoopQueue; std::unordered_map<uint32_t, CFWL_EventTarget*> m_eventTargets; - IFWL_Widget* m_pHover; - IFWL_Widget* m_pFocus; - IFWL_Widget* m_pGrab; + CFWL_Widget* m_pHover; + CFWL_Widget* m_pFocus; + CFWL_Widget* m_pGrab; std::unique_ptr<CFWL_NoteLoop> m_pNoteLoop; }; diff --git a/xfa/fwl/core/cfwl_noteloop.h b/xfa/fwl/core/cfwl_noteloop.h index f07bdc56a4..20bc03f560 100644 --- a/xfa/fwl/core/cfwl_noteloop.h +++ b/xfa/fwl/core/cfwl_noteloop.h @@ -7,20 +7,20 @@ #ifndef XFA_FWL_CORE_CFWL_NOTELOOP_H_ #define XFA_FWL_CORE_CFWL_NOTELOOP_H_ -class IFWL_Widget; +class CFWL_Widget; class CFWL_NoteLoop { public: CFWL_NoteLoop(); ~CFWL_NoteLoop() {} - IFWL_Widget* GetForm() const { return m_pForm; } + CFWL_Widget* GetForm() const { return m_pForm; } bool ContinueModal() const { return m_bContinueModal; } void EndModalLoop() { m_bContinueModal = false; } - void SetMainForm(IFWL_Widget* pForm) { m_pForm = pForm; } + void SetMainForm(CFWL_Widget* pForm) { m_pForm = pForm; } private: - IFWL_Widget* m_pForm; + CFWL_Widget* m_pForm; bool m_bContinueModal; }; diff --git a/xfa/fwl/core/cfwl_picturebox.cpp b/xfa/fwl/core/cfwl_picturebox.cpp index af0cb86514..cb4cff35d1 100644 --- a/xfa/fwl/core/cfwl_picturebox.cpp +++ b/xfa/fwl/core/cfwl_picturebox.cpp @@ -10,16 +10,54 @@ #include "third_party/base/ptr_util.h" -CFWL_PictureBox::CFWL_PictureBox(const CFWL_App* app) : CFWL_Widget(app) {} +CFWL_PictureBox::CFWL_PictureBox(const CFWL_App* app) + : CFWL_Widget(app, pdfium::MakeUnique<CFWL_WidgetProperties>(), nullptr) { + m_rtClient.Reset(); + m_rtImage.Reset(); + m_matrix.SetIdentity(); +} CFWL_PictureBox::~CFWL_PictureBox() {} -void CFWL_PictureBox::Initialize() { - ASSERT(!m_pIface); +FWL_Type CFWL_PictureBox::GetClassID() const { + return FWL_Type::PictureBox; +} + +void CFWL_PictureBox::GetWidgetRect(CFX_RectF& rect, bool bAutoSize) { + if (!bAutoSize) { + rect = m_pProperties->m_rtWidget; + return; + } - m_pIface = pdfium::MakeUnique<IFWL_PictureBox>( - m_pApp, pdfium::MakeUnique<CFWL_WidgetProperties>()); + rect.Set(0, 0, 0, 0); - CFWL_Widget::Initialize(); + CFWL_Widget::GetWidgetRect(rect, true); } +void CFWL_PictureBox::Update() { + if (IsLocked()) + return; + if (!m_pProperties->m_pThemeProvider) + m_pProperties->m_pThemeProvider = GetAvailableTheme(); + + GetClientRect(m_rtClient); +} + +void CFWL_PictureBox::DrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) { + if (!pGraphics) + return; + if (!m_pProperties->m_pThemeProvider) + return; + + IFWL_ThemeProvider* pTheme = GetAvailableTheme(); + if (HasBorder()) + DrawBorder(pGraphics, CFWL_Part::Border, pTheme, pMatrix); + if (HasEdge()) + DrawEdge(pGraphics, CFWL_Part::Edge, pTheme, pMatrix); +} + +void CFWL_PictureBox::OnDrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) { + DrawWidget(pGraphics, pMatrix); +} diff --git a/xfa/fwl/core/cfwl_picturebox.h b/xfa/fwl/core/cfwl_picturebox.h index a7b3f1ff9d..f4097336fa 100644 --- a/xfa/fwl/core/cfwl_picturebox.h +++ b/xfa/fwl/core/cfwl_picturebox.h @@ -7,15 +7,47 @@ #ifndef XFA_FWL_CORE_CFWL_PICTUREBOX_H_ #define XFA_FWL_CORE_CFWL_PICTUREBOX_H_ +#include <memory> + #include "xfa/fwl/core/cfwl_widget.h" -#include "xfa/fwl/core/ifwl_picturebox.h" +#include "xfa/fwl/core/cfwl_widgetproperties.h" + +#define FWL_STYLEEXT_PTB_Left 0L << 0 +#define FWL_STYLEEXT_PTB_Center 1L << 0 +#define FWL_STYLEEXT_PTB_Right 2L << 0 +#define FWL_STYLEEXT_PTB_Top 0L << 2 +#define FWL_STYLEEXT_PTB_Vcenter 1L << 2 +#define FWL_STYLEEXT_PTB_Bottom 2L << 2 +#define FWL_STYLEEXT_PTB_Normal 0L << 4 +#define FWL_STYLEEXT_PTB_AutoSize 1L << 4 +#define FWL_STYLEEXT_PTB_StretchImage 2L << 4 +#define FWL_STYLEEXT_PTB_StretchHImage 3L << 4 +#define FWL_STYLEEXT_PTB_StretchVImage 4L << 4 +#define FWL_STYLEEXT_PTB_HAlignMask 3L << 0 +#define FWL_STYLEEXT_PTB_VAlignMask 3L << 2 +#define FWL_STYLEEXT_PTB_StretchAlignMask 7L << 4 + +class CFX_DIBitmap; +class CFWL_Widget; class CFWL_PictureBox : public CFWL_Widget { public: explicit CFWL_PictureBox(const CFWL_App* pApp); ~CFWL_PictureBox() override; - void Initialize(); + // CFWL_Widget + FWL_Type GetClassID() const override; + void GetWidgetRect(CFX_RectF& rect, bool bAutoSize = false) override; + void Update() override; + void DrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix = nullptr) override; + void OnDrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) override; + + private: + CFX_RectF m_rtClient; + CFX_RectF m_rtImage; + CFX_Matrix m_matrix; }; #endif // XFA_FWL_CORE_CFWL_PICTUREBOX_H_ diff --git a/xfa/fwl/core/cfwl_pushbutton.cpp b/xfa/fwl/core/cfwl_pushbutton.cpp index 5fddff0c64..15e98fc4a5 100644 --- a/xfa/fwl/core/cfwl_pushbutton.cpp +++ b/xfa/fwl/core/cfwl_pushbutton.cpp @@ -7,19 +7,308 @@ #include "xfa/fwl/core/cfwl_pushbutton.h" #include <memory> +#include <utility> #include "third_party/base/ptr_util.h" +#include "xfa/fde/tto/fde_textout.h" +#include "xfa/fwl/core/cfwl_evtclick.h" +#include "xfa/fwl/core/cfwl_evtmouse.h" +#include "xfa/fwl/core/cfwl_msgkey.h" +#include "xfa/fwl/core/cfwl_msgmouse.h" +#include "xfa/fwl/core/cfwl_notedriver.h" +#include "xfa/fwl/core/cfwl_themebackground.h" +#include "xfa/fwl/core/cfwl_themetext.h" +#include "xfa/fwl/core/ifwl_themeprovider.h" -CFWL_PushButton::CFWL_PushButton(const CFWL_App* app) : CFWL_Widget(app) {} +CFWL_PushButton::CFWL_PushButton(const CFWL_App* app) + : CFWL_Widget(app, pdfium::MakeUnique<CFWL_WidgetProperties>(), nullptr), + m_bBtnDown(false), + m_dwTTOStyles(FDE_TTOSTYLE_SingleLine), + m_iTTOAlign(FDE_TTOALIGNMENT_Center) { + m_rtClient.Set(0, 0, 0, 0); + m_rtCaption.Set(0, 0, 0, 0); +} CFWL_PushButton::~CFWL_PushButton() {} -void CFWL_PushButton::Initialize() { - ASSERT(!m_pIface); +FWL_Type CFWL_PushButton::GetClassID() const { + return FWL_Type::PushButton; +} + +void CFWL_PushButton::GetWidgetRect(CFX_RectF& rect, bool bAutoSize) { + if (!bAutoSize) { + rect = m_pProperties->m_rtWidget; + return; + } + + rect.Set(0, 0, 0, 0); + if (!m_pProperties->m_pThemeProvider) + m_pProperties->m_pThemeProvider = GetAvailableTheme(); + + FX_FLOAT* fcaption = + static_cast<FX_FLOAT*>(GetThemeCapacity(CFWL_WidgetCapacity::Margin)); + rect.Inflate(*fcaption, *fcaption); + CFWL_Widget::GetWidgetRect(rect, true); +} + +void CFWL_PushButton::SetStates(uint32_t dwStates, bool bSet) { + if ((dwStates & FWL_WGTSTATE_Disabled) && bSet) { + m_pProperties->m_dwStates = FWL_WGTSTATE_Disabled; + return; + } + CFWL_Widget::SetStates(dwStates, bSet); +} + +void CFWL_PushButton::Update() { + if (IsLocked()) + return; + if (!m_pProperties->m_pThemeProvider) + m_pProperties->m_pThemeProvider = GetAvailableTheme(); + + UpdateTextOutStyles(); + GetClientRect(m_rtClient); + m_rtCaption = m_rtClient; + FX_FLOAT* fcaption = + static_cast<FX_FLOAT*>(GetThemeCapacity(CFWL_WidgetCapacity::Margin)); + m_rtCaption.Inflate(-*fcaption, -*fcaption); +} + +void CFWL_PushButton::DrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) { + if (!pGraphics) + return; + if (!m_pProperties->m_pThemeProvider) + return; + + if (HasBorder()) { + DrawBorder(pGraphics, CFWL_Part::Border, m_pProperties->m_pThemeProvider, + pMatrix); + } + if (HasEdge()) { + DrawEdge(pGraphics, CFWL_Part::Edge, m_pProperties->m_pThemeProvider, + pMatrix); + } + DrawBkground(pGraphics, m_pProperties->m_pThemeProvider, pMatrix); +} + +void CFWL_PushButton::DrawBkground(CFX_Graphics* pGraphics, + IFWL_ThemeProvider* pTheme, + const CFX_Matrix* pMatrix) { + CFWL_ThemeBackground param; + param.m_pWidget = this; + param.m_iPart = CFWL_Part::Background; + param.m_dwStates = GetPartStates(); + param.m_pGraphics = pGraphics; + if (pMatrix) + param.m_matrix.Concat(*pMatrix); + param.m_rtPart = m_rtClient; + if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) + param.m_pData = &m_rtCaption; + pTheme->DrawBackground(¶m); +} + +uint32_t CFWL_PushButton::GetPartStates() { + uint32_t dwStates = CFWL_PartState_Normal; + if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) + dwStates |= CFWL_PartState_Focused; + if (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) + dwStates = CFWL_PartState_Disabled; + else if (m_pProperties->m_dwStates & FWL_STATE_PSB_Pressed) + dwStates |= CFWL_PartState_Pressed; + else if (m_pProperties->m_dwStates & FWL_STATE_PSB_Hovered) + dwStates |= CFWL_PartState_Hovered; + else if (m_pProperties->m_dwStates & FWL_STATE_PSB_Default) + dwStates |= CFWL_PartState_Default; + return dwStates; +} + +void CFWL_PushButton::UpdateTextOutStyles() { + switch (m_pProperties->m_dwStyleExes & + (FWL_STYLEEXT_PSB_HLayoutMask | FWL_STYLEEXT_PSB_VLayoutMask)) { + case FWL_STYLEEXT_PSB_Left | FWL_STYLEEXT_PSB_Top: { + m_iTTOAlign = FDE_TTOALIGNMENT_TopLeft; + break; + } + case FWL_STYLEEXT_PSB_Center | FWL_STYLEEXT_PSB_Top: { + m_iTTOAlign = FDE_TTOALIGNMENT_TopCenter; + break; + } + case FWL_STYLEEXT_PSB_Right | FWL_STYLEEXT_PSB_Top: { + m_iTTOAlign = FDE_TTOALIGNMENT_TopRight; + break; + } + case FWL_STYLEEXT_PSB_Left | FWL_STYLEEXT_PSB_VCenter: { + m_iTTOAlign = FDE_TTOALIGNMENT_CenterLeft; + break; + } + case FWL_STYLEEXT_PSB_Right | FWL_STYLEEXT_PSB_VCenter: { + m_iTTOAlign = FDE_TTOALIGNMENT_CenterRight; + break; + } + case FWL_STYLEEXT_PSB_Left | FWL_STYLEEXT_PSB_Bottom: { + m_iTTOAlign = FDE_TTOALIGNMENT_BottomLeft; + break; + } + case FWL_STYLEEXT_PSB_Center | FWL_STYLEEXT_PSB_Bottom: { + m_iTTOAlign = FDE_TTOALIGNMENT_BottomCenter; + break; + } + case FWL_STYLEEXT_PSB_Right | FWL_STYLEEXT_PSB_Bottom: { + m_iTTOAlign = FDE_TTOALIGNMENT_BottomRight; + break; + } + case FWL_STYLEEXT_PSB_Center | FWL_STYLEEXT_PSB_VCenter: + default: { + m_iTTOAlign = FDE_TTOALIGNMENT_Center; + break; + } + } + m_dwTTOStyles = FDE_TTOSTYLE_SingleLine; + if (m_pProperties->m_dwStyleExes & FWL_WGTSTYLE_RTLReading) + m_dwTTOStyles |= FDE_TTOSTYLE_RTL; +} + +void CFWL_PushButton::OnProcessMessage(CFWL_Message* pMessage) { + if (!pMessage) + return; + if (!IsEnabled()) + return; + + CFWL_MessageType dwMsgCode = pMessage->GetClassID(); + switch (dwMsgCode) { + case CFWL_MessageType::SetFocus: + OnFocusChanged(pMessage, true); + break; + case CFWL_MessageType::KillFocus: + OnFocusChanged(pMessage, false); + break; + case CFWL_MessageType::Mouse: { + CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage); + switch (pMsg->m_dwCmd) { + case FWL_MouseCommand::LeftButtonDown: + OnLButtonDown(pMsg); + break; + case FWL_MouseCommand::LeftButtonUp: + OnLButtonUp(pMsg); + break; + case FWL_MouseCommand::Move: + OnMouseMove(pMsg); + break; + case FWL_MouseCommand::Leave: + OnMouseLeave(pMsg); + break; + default: + break; + } + break; + } + case CFWL_MessageType::Key: { + CFWL_MsgKey* pKey = static_cast<CFWL_MsgKey*>(pMessage); + if (pKey->m_dwCmd == FWL_KeyCommand::KeyDown) + OnKeyDown(pKey); + break; + } + default: + break; + } + CFWL_Widget::OnProcessMessage(pMessage); +} + +void CFWL_PushButton::OnDrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) { + DrawWidget(pGraphics, pMatrix); +} + +void CFWL_PushButton::OnFocusChanged(CFWL_Message* pMsg, bool bSet) { + if (bSet) + m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused; + else + m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused; + + Repaint(&m_rtClient); +} + +void CFWL_PushButton::OnLButtonDown(CFWL_MsgMouse* pMsg) { + if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) + SetFocus(true); - m_pIface = pdfium::MakeUnique<IFWL_PushButton>( - m_pApp, pdfium::MakeUnique<CFWL_WidgetProperties>()); + m_bBtnDown = true; + m_pProperties->m_dwStates |= FWL_STATE_PSB_Hovered; + m_pProperties->m_dwStates |= FWL_STATE_PSB_Pressed; + Repaint(&m_rtClient); +} + +void CFWL_PushButton::OnLButtonUp(CFWL_MsgMouse* pMsg) { + m_bBtnDown = false; + if (m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) { + m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Pressed; + m_pProperties->m_dwStates |= FWL_STATE_PSB_Hovered; + } else { + m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Hovered; + m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Pressed; + } + if (m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) { + CFWL_EvtClick wmClick; + wmClick.m_pSrcTarget = this; + DispatchEvent(&wmClick); + } + Repaint(&m_rtClient); +} - CFWL_Widget::Initialize(); +void CFWL_PushButton::OnMouseMove(CFWL_MsgMouse* pMsg) { + bool bRepaint = false; + if (m_bBtnDown) { + if (m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) { + if ((m_pProperties->m_dwStates & FWL_STATE_PSB_Pressed) == 0) { + m_pProperties->m_dwStates |= FWL_STATE_PSB_Pressed; + bRepaint = true; + } + if (m_pProperties->m_dwStates & FWL_STATE_PSB_Hovered) { + m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Hovered; + bRepaint = true; + } + } else { + if (m_pProperties->m_dwStates & FWL_STATE_PSB_Pressed) { + m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Pressed; + bRepaint = true; + } + if ((m_pProperties->m_dwStates & FWL_STATE_PSB_Hovered) == 0) { + m_pProperties->m_dwStates |= FWL_STATE_PSB_Hovered; + bRepaint = true; + } + } + } else { + if (!m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) + return; + if ((m_pProperties->m_dwStates & FWL_STATE_PSB_Hovered) == 0) { + m_pProperties->m_dwStates |= FWL_STATE_PSB_Hovered; + bRepaint = true; + } + } + if (bRepaint) + Repaint(&m_rtClient); } +void CFWL_PushButton::OnMouseLeave(CFWL_MsgMouse* pMsg) { + m_bBtnDown = false; + m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Hovered; + m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Pressed; + Repaint(&m_rtClient); +} + +void CFWL_PushButton::OnKeyDown(CFWL_MsgKey* pMsg) { + if (pMsg->m_dwKeyCode == FWL_VKEY_Return) { + CFWL_EvtMouse wmMouse; + wmMouse.m_pSrcTarget = this; + wmMouse.m_dwCmd = FWL_MouseCommand::LeftButtonUp; + DispatchEvent(&wmMouse); + CFWL_EvtClick wmClick; + wmClick.m_pSrcTarget = this; + DispatchEvent(&wmClick); + return; + } + if (pMsg->m_dwKeyCode != FWL_VKEY_Tab) + return; + + DispatchKeyEvent(pMsg); +} diff --git a/xfa/fwl/core/cfwl_pushbutton.h b/xfa/fwl/core/cfwl_pushbutton.h index 66fa406fe9..3bfae6c42b 100644 --- a/xfa/fwl/core/cfwl_pushbutton.h +++ b/xfa/fwl/core/cfwl_pushbutton.h @@ -7,15 +7,65 @@ #ifndef XFA_FWL_CORE_CFWL_PUSHBUTTON_H_ #define XFA_FWL_CORE_CFWL_PUSHBUTTON_H_ +#include <memory> + #include "xfa/fwl/core/cfwl_widget.h" -#include "xfa/fwl/core/ifwl_pushbutton.h" +#include "xfa/fwl/core/cfwl_widgetproperties.h" + +#define FWL_STYLEEXT_PSB_Left (0L << 0) +#define FWL_STYLEEXT_PSB_Center (1L << 0) +#define FWL_STYLEEXT_PSB_Right (2L << 0) +#define FWL_STYLEEXT_PSB_Top (0L << 2) +#define FWL_STYLEEXT_PSB_VCenter (1L << 2) +#define FWL_STYLEEXT_PSB_Bottom (2L << 2) +#define FWL_STYLEEXT_PSB_TextOnly (0L << 4) +#define FWL_STYLEEXT_PSB_IconOnly (1L << 4) +#define FWL_STYLEEXT_PSB_TextIcon (2L << 4) +#define FWL_STYLEEXT_PSB_HLayoutMask (3L << 0) +#define FWL_STYLEEXT_PSB_VLayoutMask (3L << 2) +#define FWL_STYLEEXT_PSB_ModeMask (3L << 4) +#define FWL_STATE_PSB_Hovered (1 << FWL_WGTSTATE_MAX) +#define FWL_STATE_PSB_Pressed (1 << (FWL_WGTSTATE_MAX + 1)) +#define FWL_STATE_PSB_Default (1 << (FWL_WGTSTATE_MAX + 2)) + +class CFWL_MsgMouse; +class CFX_DIBitmap; +class CFWL_Widget; class CFWL_PushButton : public CFWL_Widget { public: explicit CFWL_PushButton(const CFWL_App*); ~CFWL_PushButton() override; - void Initialize(); + // CFWL_Widget + FWL_Type GetClassID() const override; + void GetWidgetRect(CFX_RectF& rect, bool bAutoSize = false) override; + void SetStates(uint32_t dwStates, bool bSet = true) override; + void Update() override; + void DrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix = nullptr) override; + void OnProcessMessage(CFWL_Message* pMessage) override; + void OnDrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) override; + + private: + void DrawBkground(CFX_Graphics* pGraphics, + IFWL_ThemeProvider* pTheme, + const CFX_Matrix* pMatrix); + uint32_t GetPartStates(); + void UpdateTextOutStyles(); + void OnFocusChanged(CFWL_Message* pMsg, bool bSet); + void OnLButtonDown(CFWL_MsgMouse* pMsg); + void OnLButtonUp(CFWL_MsgMouse* pMsg); + void OnMouseMove(CFWL_MsgMouse* pMsg); + void OnMouseLeave(CFWL_MsgMouse* pMsg); + void OnKeyDown(CFWL_MsgKey* pMsg); + + CFX_RectF m_rtClient; + CFX_RectF m_rtCaption; + bool m_bBtnDown; + uint32_t m_dwTTOStyles; + int32_t m_iTTOAlign; }; #endif // XFA_FWL_CORE_CFWL_PUSHBUTTON_H_ diff --git a/xfa/fwl/core/cfwl_scrollbar.cpp b/xfa/fwl/core/cfwl_scrollbar.cpp index 85ab271258..6647350ef2 100644 --- a/xfa/fwl/core/cfwl_scrollbar.cpp +++ b/xfa/fwl/core/cfwl_scrollbar.cpp @@ -25,8 +25,8 @@ CFWL_ScrollBar::CFWL_ScrollBar( const CFWL_App* app, std::unique_ptr<CFWL_WidgetProperties> properties, - IFWL_Widget* pOuter) - : IFWL_Widget(app, std::move(properties), pOuter), + CFWL_Widget* pOuter) + : CFWL_Widget(app, std::move(properties), pOuter), m_pTimerInfo(nullptr), m_fRangeMin(0), m_fRangeMax(-1), @@ -77,7 +77,7 @@ void CFWL_ScrollBar::GetWidgetRect(CFX_RectF& rect, bool bAutoSize) { rect.Set(0, 0, (*pfMinWidth), (*pfMinWidth) * 3); else rect.Set(0, 0, (*pfMinWidth) * 3, (*pfMinWidth)); - IFWL_Widget::GetWidgetRect(rect, true); + CFWL_Widget::GetWidgetRect(rect, true); } void CFWL_ScrollBar::Update() { diff --git a/xfa/fwl/core/cfwl_scrollbar.h b/xfa/fwl/core/cfwl_scrollbar.h index 69f362d531..800df51a41 100644 --- a/xfa/fwl/core/cfwl_scrollbar.h +++ b/xfa/fwl/core/cfwl_scrollbar.h @@ -12,22 +12,22 @@ #include "core/fxcrt/fx_system.h" #include "xfa/fwl/core/cfwl_evtscroll.h" #include "xfa/fwl/core/cfwl_timer.h" +#include "xfa/fwl/core/cfwl_widget.h" #include "xfa/fwl/core/cfwl_widgetproperties.h" -#include "xfa/fwl/core/ifwl_widget.h" -class IFWL_Widget; +class CFWL_Widget; #define FWL_STYLEEXT_SCB_Horz (0L << 0) #define FWL_STYLEEXT_SCB_Vert (1L << 0) -class CFWL_ScrollBar : public IFWL_Widget { +class CFWL_ScrollBar : public CFWL_Widget { public: CFWL_ScrollBar(const CFWL_App* app, std::unique_ptr<CFWL_WidgetProperties> properties, - IFWL_Widget* pOuter); + CFWL_Widget* pOuter); ~CFWL_ScrollBar() override; - // IFWL_Widget + // CFWL_Widget FWL_Type GetClassID() const override; void GetWidgetRect(CFX_RectF& rect, bool bAutoSize = false) override; void Update() override; diff --git a/xfa/fwl/core/cfwl_spinbutton.cpp b/xfa/fwl/core/cfwl_spinbutton.cpp index 2afbc8297c..71ed3b05d2 100644 --- a/xfa/fwl/core/cfwl_spinbutton.cpp +++ b/xfa/fwl/core/cfwl_spinbutton.cpp @@ -30,7 +30,7 @@ const int kElapseTime = 200; CFWL_SpinButton::CFWL_SpinButton( const CFWL_App* app, std::unique_ptr<CFWL_WidgetProperties> properties) - : IFWL_Widget(app, std::move(properties), nullptr), + : CFWL_Widget(app, std::move(properties), nullptr), m_dwUpState(CFWL_PartState_Normal), m_dwDnState(CFWL_PartState_Normal), m_iButtonIndex(0), @@ -56,7 +56,7 @@ void CFWL_SpinButton::GetWidgetRect(CFX_RectF& rect, bool bAutoSize) { } rect.Set(0, 0, kMinWidth, kMinHeight); - IFWL_Widget::GetWidgetRect(rect, true); + CFWL_Widget::GetWidgetRect(rect, true); } void CFWL_SpinButton::Update() { @@ -200,7 +200,7 @@ void CFWL_SpinButton::OnProcessMessage(CFWL_Message* pMessage) { default: break; } - IFWL_Widget::OnProcessMessage(pMessage); + CFWL_Widget::OnProcessMessage(pMessage); } void CFWL_SpinButton::OnDrawWidget(CFX_Graphics* pGraphics, diff --git a/xfa/fwl/core/cfwl_spinbutton.h b/xfa/fwl/core/cfwl_spinbutton.h index 87cf16727c..6b53e68a90 100644 --- a/xfa/fwl/core/cfwl_spinbutton.h +++ b/xfa/fwl/core/cfwl_spinbutton.h @@ -11,7 +11,7 @@ #include "xfa/fwl/core/cfwl_event.h" #include "xfa/fwl/core/cfwl_timer.h" -#include "xfa/fwl/core/ifwl_widget.h" +#include "xfa/fwl/core/cfwl_widget.h" #include "xfa/fxfa/cxfa_eventparam.h" #define FWL_STYLEEXE_SPB_Vert (1L << 0) @@ -19,13 +19,13 @@ class CFWL_MsgMouse; class CFWL_WidgetProperties; -class CFWL_SpinButton : public IFWL_Widget { +class CFWL_SpinButton : public CFWL_Widget { public: CFWL_SpinButton(const CFWL_App* app, std::unique_ptr<CFWL_WidgetProperties> properties); ~CFWL_SpinButton() override; - // IFWL_Widget + // CFWL_Widget FWL_Type GetClassID() const override; void GetWidgetRect(CFX_RectF& rect, bool bAutoSize = false) override; void Update() override; diff --git a/xfa/fwl/core/cfwl_themepart.h b/xfa/fwl/core/cfwl_themepart.h index 93565e91f5..f80bb8e07a 100644 --- a/xfa/fwl/core/cfwl_themepart.h +++ b/xfa/fwl/core/cfwl_themepart.h @@ -77,7 +77,7 @@ enum CFWL_PartState { CFWL_PartState_Selected = 1 << 14 }; -class IFWL_Widget; +class CFWL_Widget; class CFWL_ThemePart { public: @@ -85,7 +85,7 @@ class CFWL_ThemePart { CFX_Matrix m_matrix; CFX_RectF m_rtPart; - IFWL_Widget* m_pWidget; + CFWL_Widget* m_pWidget; CFWL_Part m_iPart; uint32_t m_dwStates; bool m_bMaximize; diff --git a/xfa/fwl/core/cfwl_timer.cpp b/xfa/fwl/core/cfwl_timer.cpp index 2d92e6d61f..c909afcc49 100644 --- a/xfa/fwl/core/cfwl_timer.cpp +++ b/xfa/fwl/core/cfwl_timer.cpp @@ -8,8 +8,8 @@ #include "xfa/fwl/core/cfwl_app.h" #include "xfa/fwl/core/cfwl_timerinfo.h" +#include "xfa/fwl/core/cfwl_widget.h" #include "xfa/fwl/core/ifwl_adaptertimermgr.h" -#include "xfa/fwl/core/ifwl_widget.h" #include "xfa/fxfa/xfa_ffapp.h" CFWL_TimerInfo* CFWL_Timer::StartTimer(uint32_t dwElapse, bool bImmediately) { diff --git a/xfa/fwl/core/cfwl_timer.h b/xfa/fwl/core/cfwl_timer.h index 2f91e783c8..7b36c3eb49 100644 --- a/xfa/fwl/core/cfwl_timer.h +++ b/xfa/fwl/core/cfwl_timer.h @@ -10,18 +10,18 @@ #include "core/fxcrt/fx_system.h" class CFWL_TimerInfo; -class IFWL_Widget; +class CFWL_Widget; class CFWL_Timer { public: - explicit CFWL_Timer(IFWL_Widget* parent) : m_pWidget(parent) {} + explicit CFWL_Timer(CFWL_Widget* parent) : m_pWidget(parent) {} virtual ~CFWL_Timer() {} virtual void Run(CFWL_TimerInfo* hTimer) = 0; CFWL_TimerInfo* StartTimer(uint32_t dwElapse, bool bImmediately); protected: - IFWL_Widget* m_pWidget; // Not owned. + CFWL_Widget* m_pWidget; // Not owned. }; #endif // XFA_FWL_CORE_CFWL_TIMER_H_ diff --git a/xfa/fwl/core/cfwl_widget.cpp b/xfa/fwl/core/cfwl_widget.cpp index 5914ce58ec..e2de866817 100644 --- a/xfa/fwl/core/cfwl_widget.cpp +++ b/xfa/fwl/core/cfwl_widget.cpp @@ -6,97 +6,797 @@ #include "xfa/fwl/core/cfwl_widget.h" +#include <algorithm> +#include <utility> + #include "xfa/fde/tto/fde_textout.h" #include "xfa/fwl/core/cfwl_app.h" +#include "xfa/fwl/core/cfwl_combobox.h" +#include "xfa/fwl/core/cfwl_evtkey.h" +#include "xfa/fwl/core/cfwl_evtkillfocus.h" +#include "xfa/fwl/core/cfwl_evtmouse.h" +#include "xfa/fwl/core/cfwl_evtmousewheel.h" +#include "xfa/fwl/core/cfwl_evtsetfocus.h" +#include "xfa/fwl/core/cfwl_evtsizechanged.h" +#include "xfa/fwl/core/cfwl_form.h" +#include "xfa/fwl/core/cfwl_msgkey.h" +#include "xfa/fwl/core/cfwl_msgkillfocus.h" +#include "xfa/fwl/core/cfwl_msgmouse.h" +#include "xfa/fwl/core/cfwl_msgmousewheel.h" +#include "xfa/fwl/core/cfwl_msgsetfocus.h" #include "xfa/fwl/core/cfwl_notedriver.h" +#include "xfa/fwl/core/cfwl_themebackground.h" +#include "xfa/fwl/core/cfwl_themepart.h" #include "xfa/fwl/core/cfwl_themetext.h" #include "xfa/fwl/core/cfwl_widgetmgr.h" #include "xfa/fwl/core/ifwl_themeprovider.h" +#include "xfa/fxfa/xfa_ffapp.h" +#define FWL_STYLEEXT_MNU_Vert (1L << 0) #define FWL_WGT_CalcHeight 2048 #define FWL_WGT_CalcWidth 2048 #define FWL_WGT_CalcMultiLineDefWidth 120.0f -CFWL_Widget::CFWL_Widget(const CFWL_App* app) : m_pApp(app) {} +CFWL_Widget::CFWL_Widget(const CFWL_App* app, + std::unique_ptr<CFWL_WidgetProperties> properties, + CFWL_Widget* pOuter) + : m_pOwnerApp(app), + m_pWidgetMgr(app->GetWidgetMgr()), + m_pProperties(std::move(properties)), + m_pOuter(pOuter), + m_iLock(0), + m_pLayoutItem(nullptr), + m_nEventKey(0), + m_pDelegate(nullptr) { + ASSERT(m_pWidgetMgr); + + CFWL_Widget* pParent = m_pProperties->m_pParent; + m_pWidgetMgr->InsertWidget(pParent, this); + if (IsChild()) + return; -CFWL_Widget::~CFWL_Widget() {} + CFWL_Widget* pOwner = m_pProperties->m_pOwner; + if (pOwner) + m_pWidgetMgr->SetOwner(pOwner, this); +} -void CFWL_Widget::Initialize() { - ASSERT(m_pIface); - m_pIface->SetAssociateWidget(this); +CFWL_Widget::~CFWL_Widget() { + NotifyDriver(); + m_pWidgetMgr->RemoveWidget(this); +} + +bool CFWL_Widget::IsInstance(const CFX_WideStringC& wsClass) const { + return false; } void CFWL_Widget::GetWidgetRect(CFX_RectF& rect, bool bAutoSize) { - if (m_pIface) - m_pIface->GetWidgetRect(rect, bAutoSize); + if (!bAutoSize) { + rect = m_pProperties->m_rtWidget; + return; + } + + if (HasEdge()) { + FX_FLOAT fEdge = GetEdgeWidth(); + rect.Inflate(fEdge, fEdge); + } + if (HasBorder()) { + FX_FLOAT fBorder = GetBorderSize(); + rect.Inflate(fBorder, fBorder); + } } void CFWL_Widget::SetWidgetRect(const CFX_RectF& rect) { - if (m_pIface) - m_pIface->SetWidgetRect(rect); + CFX_RectF rtOld = m_pProperties->m_rtWidget; + m_pProperties->m_rtWidget = rect; + if (IsChild()) { + if (FXSYS_fabs(rtOld.width - rect.width) > 0.5f || + FXSYS_fabs(rtOld.height - rect.height) > 0.5f) { + CFWL_EvtSizeChanged ev; + ev.m_pSrcTarget = this; + ev.m_rtOld = rtOld; + ev.m_rtNew = rect; + + if (IFWL_WidgetDelegate* pDelegate = GetDelegate()) + pDelegate->OnProcessEvent(&ev); + } + return; + } + m_pWidgetMgr->SetWidgetRect_Native(this, rect); +} + +void CFWL_Widget::GetClientRect(CFX_RectF& rect) { + GetEdgeRect(rect); + if (HasEdge()) { + FX_FLOAT fEdge = GetEdgeWidth(); + rect.Deflate(fEdge, fEdge); + } +} + +void CFWL_Widget::SetParent(CFWL_Widget* pParent) { + m_pProperties->m_pParent = pParent; + m_pWidgetMgr->SetParent(pParent, this); +} + +uint32_t CFWL_Widget::GetStyles() const { + return m_pProperties->m_dwStyles; } void CFWL_Widget::ModifyStyles(uint32_t dwStylesAdded, uint32_t dwStylesRemoved) { - if (m_pIface) - m_pIface->ModifyStyles(dwStylesAdded, dwStylesRemoved); + m_pProperties->m_dwStyles = + (m_pProperties->m_dwStyles & ~dwStylesRemoved) | dwStylesAdded; } -uint32_t CFWL_Widget::GetStylesEx() { - return m_pIface ? m_pIface->GetStylesEx() : 0; +uint32_t CFWL_Widget::GetStylesEx() const { + return m_pProperties->m_dwStyleExes; +} +uint32_t CFWL_Widget::GetStates() const { + return m_pProperties->m_dwStates; } void CFWL_Widget::ModifyStylesEx(uint32_t dwStylesExAdded, uint32_t dwStylesExRemoved) { - m_pIface->ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved); + m_pProperties->m_dwStyleExes = + (m_pProperties->m_dwStyleExes & ~dwStylesExRemoved) | dwStylesExAdded; } -uint32_t CFWL_Widget::GetStates() { - return m_pIface ? m_pIface->GetStates() : 0; +static void NotifyHideChildWidget(CFWL_WidgetMgr* widgetMgr, + CFWL_Widget* widget, + CFWL_NoteDriver* noteDriver) { + CFWL_Widget* child = widgetMgr->GetFirstChildWidget(widget); + while (child) { + noteDriver->NotifyTargetHide(child); + NotifyHideChildWidget(widgetMgr, child, noteDriver); + child = widgetMgr->GetNextSiblingWidget(child); + } } void CFWL_Widget::SetStates(uint32_t dwStates, bool bSet) { - if (m_pIface) - m_pIface->SetStates(dwStates, bSet); + bSet ? (m_pProperties->m_dwStates |= dwStates) + : (m_pProperties->m_dwStates &= ~dwStates); + if (!(dwStates & FWL_WGTSTATE_Invisible) || !bSet) + return; + + CFWL_NoteDriver* noteDriver = + static_cast<CFWL_NoteDriver*>(GetOwnerApp()->GetNoteDriver()); + CFWL_WidgetMgr* widgetMgr = GetOwnerApp()->GetWidgetMgr(); + noteDriver->NotifyTargetHide(this); + CFWL_Widget* child = widgetMgr->GetFirstChildWidget(this); + while (child) { + noteDriver->NotifyTargetHide(child); + NotifyHideChildWidget(widgetMgr, child, noteDriver); + child = widgetMgr->GetNextSiblingWidget(child); + } + return; } -void CFWL_Widget::SetLayoutItem(void* pItem) { - if (m_pIface) - m_pIface->SetLayoutItem(pItem); +FWL_WidgetHit CFWL_Widget::HitTest(FX_FLOAT fx, FX_FLOAT fy) { + CFX_RectF rtClient; + GetClientRect(rtClient); + if (rtClient.Contains(fx, fy)) + return FWL_WidgetHit::Client; + if (HasEdge()) { + CFX_RectF rtEdge; + GetEdgeRect(rtEdge); + if (rtEdge.Contains(fx, fy)) + return FWL_WidgetHit::Edge; + } + if (HasBorder()) { + CFX_RectF rtRelative; + GetRelativeRect(rtRelative); + if (rtRelative.Contains(fx, fy)) + return FWL_WidgetHit::Border; + } + return FWL_WidgetHit::Unknown; } -void CFWL_Widget::Update() { - if (m_pIface) - m_pIface->Update(); +void CFWL_Widget::TransformTo(CFWL_Widget* pWidget, + FX_FLOAT& fx, + FX_FLOAT& fy) { + if (m_pWidgetMgr->IsFormDisabled()) { + CFX_SizeF szOffset; + if (IsParent(pWidget)) { + szOffset = GetOffsetFromParent(pWidget); + } else { + szOffset = pWidget->GetOffsetFromParent(this); + szOffset.x = -szOffset.x; + szOffset.y = -szOffset.y; + } + fx += szOffset.x; + fy += szOffset.y; + return; + } + CFX_RectF r; + CFX_Matrix m; + CFWL_Widget* parent = GetParent(); + if (parent) { + GetWidgetRect(r); + fx += r.left; + fy += r.top; + GetMatrix(m, true); + m.TransformPoint(fx, fy); + } + CFWL_Widget* form1 = m_pWidgetMgr->GetSystemFormWidget(this); + if (!form1) + return; + if (!pWidget) { + form1->GetWidgetRect(r); + fx += r.left; + fy += r.top; + return; + } + CFWL_Widget* form2 = m_pWidgetMgr->GetSystemFormWidget(pWidget); + if (!form2) + return; + if (form1 != form2) { + form1->GetWidgetRect(r); + fx += r.left; + fy += r.top; + form2->GetWidgetRect(r); + fx -= r.left; + fy -= r.top; + } + parent = pWidget->GetParent(); + if (parent) { + pWidget->GetMatrix(m, true); + CFX_Matrix m1; + m1.SetIdentity(); + m1.SetReverse(m); + m1.TransformPoint(fx, fy); + pWidget->GetWidgetRect(r); + fx -= r.left; + fy -= r.top; + } } -void CFWL_Widget::LockUpdate() { - if (m_pIface) - m_pIface->LockUpdate(); +void CFWL_Widget::GetMatrix(CFX_Matrix& matrix, bool bGlobal) { + if (!m_pProperties) + return; + if (!bGlobal) { + matrix.SetIdentity(); + return; + } + + CFWL_Widget* parent = GetParent(); + CFX_ArrayTemplate<CFWL_Widget*> parents; + while (parent) { + parents.Add(parent); + parent = parent->GetParent(); + } + matrix.SetIdentity(); + CFX_Matrix ctmOnParent; + CFX_RectF rect; + int32_t count = parents.GetSize(); + for (int32_t i = count - 2; i >= 0; i--) { + parent = parents.GetAt(i); + parent->GetMatrix(ctmOnParent, false); + parent->GetWidgetRect(rect); + matrix.Concat(ctmOnParent, true); + matrix.Translate(rect.left, rect.top, true); + } + CFX_Matrix m; + m.SetIdentity(); + matrix.Concat(m, true); + parents.RemoveAll(); } -void CFWL_Widget::UnlockUpdate() { - if (m_pIface) - m_pIface->UnlockUpdate(); +IFWL_ThemeProvider* CFWL_Widget::GetThemeProvider() const { + return m_pProperties->m_pThemeProvider; } -FWL_WidgetHit CFWL_Widget::HitTest(FX_FLOAT fx, FX_FLOAT fy) { - if (!m_pIface) - return FWL_WidgetHit::Unknown; - return m_pIface->HitTest(fx, fy); +void CFWL_Widget::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) { + m_pProperties->m_pThemeProvider = pThemeProvider; +} + +bool CFWL_Widget::IsEnabled() const { + return (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) == 0; +} + +bool CFWL_Widget::IsActive() const { + return (m_pProperties->m_dwStates & FWL_WGTSTATE_Deactivated) == 0; +} + +bool CFWL_Widget::HasBorder() const { + return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Border); +} + +bool CFWL_Widget::HasEdge() const { + return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_EdgeMask); +} + +bool CFWL_Widget::IsVisible() const { + return (m_pProperties->m_dwStates & FWL_WGTSTATE_Invisible) == 0; +} + +bool CFWL_Widget::IsOverLapper() const { + return (m_pProperties->m_dwStyles & FWL_WGTSTYLE_WindowTypeMask) == + FWL_WGTSTYLE_OverLapper; +} + +bool CFWL_Widget::IsPopup() const { + return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Popup); +} + +bool CFWL_Widget::IsChild() const { + return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Child); +} + +bool CFWL_Widget::IsOffscreen() const { + return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Offscreen); +} + +void CFWL_Widget::GetEdgeRect(CFX_RectF& rtEdge) { + rtEdge = m_pProperties->m_rtWidget; + rtEdge.left = rtEdge.top = 0; + if (HasBorder()) { + FX_FLOAT fCX = GetBorderSize(); + FX_FLOAT fCY = GetBorderSize(false); + rtEdge.Deflate(fCX, fCY); + } +} + +FX_FLOAT CFWL_Widget::GetBorderSize(bool bCX) { + FX_FLOAT* pfBorder = static_cast<FX_FLOAT*>(GetThemeCapacity( + bCX ? CFWL_WidgetCapacity::CXBorder : CFWL_WidgetCapacity::CYBorder)); + if (!pfBorder) + return 0; + return *pfBorder; +} + +FX_FLOAT CFWL_Widget::GetEdgeWidth() { + CFWL_WidgetCapacity dwCapacity = CFWL_WidgetCapacity::None; + switch (m_pProperties->m_dwStyles & FWL_WGTSTYLE_EdgeMask) { + case FWL_WGTSTYLE_EdgeFlat: { + dwCapacity = CFWL_WidgetCapacity::EdgeFlat; + break; + } + case FWL_WGTSTYLE_EdgeRaised: { + dwCapacity = CFWL_WidgetCapacity::EdgeRaised; + break; + } + case FWL_WGTSTYLE_EdgeSunken: { + dwCapacity = CFWL_WidgetCapacity::EdgeSunken; + break; + } + } + if (dwCapacity != CFWL_WidgetCapacity::None) { + FX_FLOAT* fRet = static_cast<FX_FLOAT*>(GetThemeCapacity(dwCapacity)); + return fRet ? *fRet : 0; + } + return 0; +} + +void CFWL_Widget::GetRelativeRect(CFX_RectF& rect) { + rect = m_pProperties->m_rtWidget; + rect.left = rect.top = 0; +} + +void* CFWL_Widget::GetThemeCapacity(CFWL_WidgetCapacity dwCapacity) { + IFWL_ThemeProvider* pTheme = GetAvailableTheme(); + if (!pTheme) + return nullptr; + + CFWL_ThemePart part; + part.m_pWidget = this; + return pTheme->GetCapacity(&part, dwCapacity); +} + +IFWL_ThemeProvider* CFWL_Widget::GetAvailableTheme() { + if (m_pProperties->m_pThemeProvider) + return m_pProperties->m_pThemeProvider; + + CFWL_Widget* pUp = this; + do { + pUp = (pUp->GetStyles() & FWL_WGTSTYLE_Popup) + ? m_pWidgetMgr->GetOwnerWidget(pUp) + : m_pWidgetMgr->GetParentWidget(pUp); + if (pUp) { + IFWL_ThemeProvider* pRet = pUp->GetThemeProvider(); + if (pRet) + return pRet; + } + } while (pUp); + return nullptr; +} + +CFWL_Widget* CFWL_Widget::GetRootOuter() { + CFWL_Widget* pRet = m_pOuter; + if (!pRet) + return nullptr; + + while (CFWL_Widget* pOuter = pRet->GetOuter()) + pRet = pOuter; + return pRet; +} + +CFX_SizeF CFWL_Widget::CalcTextSize(const CFX_WideString& wsText, + IFWL_ThemeProvider* pTheme, + bool bMultiLine, + int32_t iLineWidth) { + if (!pTheme) + return CFX_SizeF(); + + CFWL_ThemeText calPart; + calPart.m_pWidget = this; + calPart.m_wsText = wsText; + calPart.m_dwTTOStyles = + bMultiLine ? FDE_TTOSTYLE_LineWrap : FDE_TTOSTYLE_SingleLine; + calPart.m_iTTOAlign = FDE_TTOALIGNMENT_TopLeft; + CFX_RectF rect; + FX_FLOAT fWidth = bMultiLine + ? (iLineWidth > 0 ? (FX_FLOAT)iLineWidth + : FWL_WGT_CalcMultiLineDefWidth) + : FWL_WGT_CalcWidth; + rect.Set(0, 0, fWidth, FWL_WGT_CalcHeight); + pTheme->CalcTextRect(&calPart, rect); + return CFX_SizeF(rect.width, rect.height); } -void CFWL_Widget::DrawWidget(CFX_Graphics* pGraphics, +void CFWL_Widget::CalcTextRect(const CFX_WideString& wsText, + IFWL_ThemeProvider* pTheme, + uint32_t dwTTOStyles, + int32_t iTTOAlign, + CFX_RectF& rect) { + CFWL_ThemeText calPart; + calPart.m_pWidget = this; + calPart.m_wsText = wsText; + calPart.m_dwTTOStyles = dwTTOStyles; + calPart.m_iTTOAlign = iTTOAlign; + pTheme->CalcTextRect(&calPart, rect); +} + +void CFWL_Widget::SetFocus(bool bFocus) { + if (m_pWidgetMgr->IsFormDisabled()) + return; + + const CFWL_App* pApp = GetOwnerApp(); + if (!pApp) + return; + + CFWL_NoteDriver* pDriver = + static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver()); + if (!pDriver) + return; + + CFWL_Widget* curFocus = pDriver->GetFocus(); + if (bFocus && curFocus != this) + pDriver->SetFocus(this); + else if (!bFocus && curFocus == this) + pDriver->SetFocus(nullptr); +} + +void CFWL_Widget::SetGrab(bool bSet) { + const CFWL_App* pApp = GetOwnerApp(); + if (!pApp) + return; + + CFWL_NoteDriver* pDriver = + static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver()); + pDriver->SetGrab(this, bSet); +} + +void CFWL_Widget::GetPopupPos(FX_FLOAT fMinHeight, + FX_FLOAT fMaxHeight, + const CFX_RectF& rtAnchor, + CFX_RectF& rtPopup) { + if (GetClassID() == FWL_Type::ComboBox) { + if (m_pWidgetMgr->IsFormDisabled()) { + m_pWidgetMgr->GetAdapterPopupPos(this, fMinHeight, fMaxHeight, rtAnchor, + rtPopup); + return; + } + GetPopupPosComboBox(fMinHeight, fMaxHeight, rtAnchor, rtPopup); + return; + } + if (GetClassID() == FWL_Type::DateTimePicker && + m_pWidgetMgr->IsFormDisabled()) { + m_pWidgetMgr->GetAdapterPopupPos(this, fMinHeight, fMaxHeight, rtAnchor, + rtPopup); + return; + } + GetPopupPosGeneral(fMinHeight, fMaxHeight, rtAnchor, rtPopup); +} + +bool CFWL_Widget::GetPopupPosMenu(FX_FLOAT fMinHeight, + FX_FLOAT fMaxHeight, + const CFX_RectF& rtAnchor, + CFX_RectF& rtPopup) { + FX_FLOAT fx = 0; + FX_FLOAT fy = 0; + + if (GetStylesEx() & FWL_STYLEEXT_MNU_Vert) { + bool bLeft = m_pProperties->m_rtWidget.left < 0; + FX_FLOAT fRight = rtAnchor.right() + rtPopup.width; + TransformTo(nullptr, fx, fy); + if (fRight + fx > 0.0f || bLeft) { + rtPopup.Set(rtAnchor.left - rtPopup.width, rtAnchor.top, rtPopup.width, + rtPopup.height); + } else { + rtPopup.Set(rtAnchor.right(), rtAnchor.top, rtPopup.width, + rtPopup.height); + } + } else { + FX_FLOAT fBottom = rtAnchor.bottom() + rtPopup.height; + TransformTo(nullptr, fx, fy); + if (fBottom + fy > 0.0f) { + rtPopup.Set(rtAnchor.left, rtAnchor.top - rtPopup.height, rtPopup.width, + rtPopup.height); + } else { + rtPopup.Set(rtAnchor.left, rtAnchor.bottom(), rtPopup.width, + rtPopup.height); + } + } + rtPopup.Offset(fx, fy); + return true; +} + +bool CFWL_Widget::GetPopupPosComboBox(FX_FLOAT fMinHeight, + FX_FLOAT fMaxHeight, + const CFX_RectF& rtAnchor, + CFX_RectF& rtPopup) { + FX_FLOAT fx = 0; + FX_FLOAT fy = 0; + + FX_FLOAT fPopHeight = rtPopup.height; + if (rtPopup.height > fMaxHeight) + fPopHeight = fMaxHeight; + else if (rtPopup.height < fMinHeight) + fPopHeight = fMinHeight; + + FX_FLOAT fWidth = std::max(rtAnchor.width, rtPopup.width); + FX_FLOAT fBottom = rtAnchor.bottom() + fPopHeight; + TransformTo(nullptr, fx, fy); + if (fBottom + fy > 0.0f) + rtPopup.Set(rtAnchor.left, rtAnchor.top - fPopHeight, fWidth, fPopHeight); + else + rtPopup.Set(rtAnchor.left, rtAnchor.bottom(), fWidth, fPopHeight); + + rtPopup.Offset(fx, fy); + return true; +} + +bool CFWL_Widget::GetPopupPosGeneral(FX_FLOAT fMinHeight, + FX_FLOAT fMaxHeight, + const CFX_RectF& rtAnchor, + CFX_RectF& rtPopup) { + FX_FLOAT fx = 0; + FX_FLOAT fy = 0; + + TransformTo(nullptr, fx, fy); + if (rtAnchor.bottom() + fy > 0.0f) { + rtPopup.Set(rtAnchor.left, rtAnchor.top - rtPopup.height, rtPopup.width, + rtPopup.height); + } else { + rtPopup.Set(rtAnchor.left, rtAnchor.bottom(), rtPopup.width, + rtPopup.height); + } + rtPopup.Offset(fx, fy); + return true; +} + +void CFWL_Widget::RegisterEventTarget(CFWL_Widget* pEventSource) { + const CFWL_App* pApp = GetOwnerApp(); + if (!pApp) + return; + + CFWL_NoteDriver* pNoteDriver = pApp->GetNoteDriver(); + if (!pNoteDriver) + return; + + pNoteDriver->RegisterEventTarget(this, pEventSource); +} + +void CFWL_Widget::UnregisterEventTarget() { + const CFWL_App* pApp = GetOwnerApp(); + if (!pApp) + return; + + CFWL_NoteDriver* pNoteDriver = pApp->GetNoteDriver(); + if (!pNoteDriver) + return; + + pNoteDriver->UnregisterEventTarget(this); +} + +void CFWL_Widget::DispatchKeyEvent(CFWL_MsgKey* pNote) { + if (!pNote) + return; + + auto pEvent = pdfium::MakeUnique<CFWL_EvtKey>(); + pEvent->m_pSrcTarget = this; + pEvent->m_dwCmd = pNote->m_dwCmd; + pEvent->m_dwKeyCode = pNote->m_dwKeyCode; + pEvent->m_dwFlags = pNote->m_dwFlags; + DispatchEvent(pEvent.get()); +} + +void CFWL_Widget::DispatchEvent(CFWL_Event* pEvent) { + if (m_pOuter) { + m_pOuter->GetDelegate()->OnProcessEvent(pEvent); + return; + } + const CFWL_App* pApp = GetOwnerApp(); + if (!pApp) + return; + + CFWL_NoteDriver* pNoteDriver = pApp->GetNoteDriver(); + if (!pNoteDriver) + return; + pNoteDriver->SendEvent(pEvent); +} + +void CFWL_Widget::Repaint(const CFX_RectF* pRect) { + if (pRect) { + m_pWidgetMgr->RepaintWidget(this, pRect); + return; + } + CFX_RectF rect; + rect = m_pProperties->m_rtWidget; + rect.left = rect.top = 0; + m_pWidgetMgr->RepaintWidget(this, &rect); +} + +void CFWL_Widget::DrawBackground(CFX_Graphics* pGraphics, + CFWL_Part iPartBk, + IFWL_ThemeProvider* pTheme, + const CFX_Matrix* pMatrix) { + CFX_RectF rtRelative; + GetRelativeRect(rtRelative); + CFWL_ThemeBackground param; + param.m_pWidget = this; + param.m_iPart = iPartBk; + param.m_pGraphics = pGraphics; + if (pMatrix) + param.m_matrix.Concat(*pMatrix, true); + param.m_rtPart = rtRelative; + pTheme->DrawBackground(¶m); +} + +void CFWL_Widget::DrawBorder(CFX_Graphics* pGraphics, + CFWL_Part iPartBorder, + IFWL_ThemeProvider* pTheme, const CFX_Matrix* pMatrix) { - if (m_pIface) - m_pIface->DrawWidget(pGraphics, pMatrix); + CFX_RectF rtRelative; + GetRelativeRect(rtRelative); + CFWL_ThemeBackground param; + param.m_pWidget = this; + param.m_iPart = iPartBorder; + param.m_pGraphics = pGraphics; + if (pMatrix) + param.m_matrix.Concat(*pMatrix, true); + param.m_rtPart = rtRelative; + pTheme->DrawBackground(¶m); } -IFWL_WidgetDelegate* CFWL_Widget::GetDelegate() const { - return m_pIface ? m_pIface->GetDelegate() : nullptr; +void CFWL_Widget::DrawEdge(CFX_Graphics* pGraphics, + CFWL_Part iPartEdge, + IFWL_ThemeProvider* pTheme, + const CFX_Matrix* pMatrix) { + CFX_RectF rtEdge; + GetEdgeRect(rtEdge); + CFWL_ThemeBackground param; + param.m_pWidget = this; + param.m_iPart = iPartEdge; + param.m_pGraphics = pGraphics; + if (pMatrix) + param.m_matrix.Concat(*pMatrix, true); + param.m_rtPart = rtEdge; + pTheme->DrawBackground(¶m); } -void CFWL_Widget::SetDelegate(IFWL_WidgetDelegate* pDelegate) { - if (m_pIface) - m_pIface->SetDelegate(pDelegate); +void CFWL_Widget::NotifyDriver() { + const CFWL_App* pApp = GetOwnerApp(); + if (!pApp) + return; + + CFWL_NoteDriver* pDriver = + static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver()); + if (!pDriver) + return; + + pDriver->NotifyTargetDestroy(this); } + +CFX_SizeF CFWL_Widget::GetOffsetFromParent(CFWL_Widget* pParent) { + if (pParent == this) + return CFX_SizeF(); + + CFWL_WidgetMgr* pWidgetMgr = GetOwnerApp()->GetWidgetMgr(); + if (!pWidgetMgr) + return CFX_SizeF(); + + CFX_SizeF szRet(m_pProperties->m_rtWidget.left, + m_pProperties->m_rtWidget.top); + + CFWL_Widget* pDstWidget = GetParent(); + while (pDstWidget && pDstWidget != pParent) { + CFX_RectF rtDst; + pDstWidget->GetWidgetRect(rtDst); + szRet += CFX_SizeF(rtDst.left, rtDst.top); + pDstWidget = pWidgetMgr->GetParentWidget(pDstWidget); + } + return szRet; +} + +bool CFWL_Widget::IsParent(CFWL_Widget* pParent) { + CFWL_Widget* pUpWidget = GetParent(); + while (pUpWidget) { + if (pUpWidget == pParent) + return true; + pUpWidget = pUpWidget->GetParent(); + } + return false; +} + +void CFWL_Widget::OnProcessMessage(CFWL_Message* pMessage) { + if (!pMessage->m_pDstTarget) + return; + + CFWL_Widget* pWidget = pMessage->m_pDstTarget; + CFWL_MessageType dwMsgCode = pMessage->GetClassID(); + switch (dwMsgCode) { + case CFWL_MessageType::Mouse: { + CFWL_MsgMouse* pMsgMouse = static_cast<CFWL_MsgMouse*>(pMessage); + CFWL_EvtMouse evt; + evt.m_pSrcTarget = pWidget; + evt.m_pDstTarget = pWidget; + evt.m_dwCmd = pMsgMouse->m_dwCmd; + evt.m_dwFlags = pMsgMouse->m_dwFlags; + evt.m_fx = pMsgMouse->m_fx; + evt.m_fy = pMsgMouse->m_fy; + pWidget->DispatchEvent(&evt); + break; + } + case CFWL_MessageType::MouseWheel: { + CFWL_MsgMouseWheel* pMsgMouseWheel = + static_cast<CFWL_MsgMouseWheel*>(pMessage); + CFWL_EvtMouseWheel evt; + evt.m_pSrcTarget = pWidget; + evt.m_pDstTarget = pWidget; + evt.m_dwFlags = pMsgMouseWheel->m_dwFlags; + evt.m_fDeltaX = pMsgMouseWheel->m_fDeltaX; + evt.m_fDeltaY = pMsgMouseWheel->m_fDeltaY; + evt.m_fx = pMsgMouseWheel->m_fx; + evt.m_fy = pMsgMouseWheel->m_fy; + pWidget->DispatchEvent(&evt); + break; + } + case CFWL_MessageType::Key: { + CFWL_MsgKey* pMsgKey = static_cast<CFWL_MsgKey*>(pMessage); + CFWL_EvtKey evt; + evt.m_pSrcTarget = pWidget; + evt.m_pDstTarget = pWidget; + evt.m_dwKeyCode = pMsgKey->m_dwKeyCode; + evt.m_dwFlags = pMsgKey->m_dwFlags; + evt.m_dwCmd = pMsgKey->m_dwCmd; + pWidget->DispatchEvent(&evt); + break; + } + case CFWL_MessageType::SetFocus: { + CFWL_MsgSetFocus* pMsgSetFocus = static_cast<CFWL_MsgSetFocus*>(pMessage); + CFWL_EvtSetFocus evt; + evt.m_pSrcTarget = pMsgSetFocus->m_pDstTarget; + evt.m_pDstTarget = pMsgSetFocus->m_pDstTarget; + evt.m_pSetFocus = pWidget; + pWidget->DispatchEvent(&evt); + break; + } + case CFWL_MessageType::KillFocus: { + CFWL_MsgKillFocus* pMsgKillFocus = + static_cast<CFWL_MsgKillFocus*>(pMessage); + CFWL_EvtKillFocus evt; + evt.m_pSrcTarget = pMsgKillFocus->m_pDstTarget; + evt.m_pDstTarget = pMsgKillFocus->m_pDstTarget; + evt.m_pKillFocus = pWidget; + pWidget->DispatchEvent(&evt); + break; + } + default: + break; + } +} + +void CFWL_Widget::OnProcessEvent(CFWL_Event* pEvent) {} + +void CFWL_Widget::OnDrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) {} diff --git a/xfa/fwl/core/cfwl_widget.h b/xfa/fwl/core/cfwl_widget.h index abb8d549bd..7a993e5e22 100644 --- a/xfa/fwl/core/cfwl_widget.h +++ b/xfa/fwl/core/cfwl_widget.h @@ -6,52 +6,190 @@ #ifndef XFA_FWL_CORE_CFWL_WIDGET_H_ #define XFA_FWL_CORE_CFWL_WIDGET_H_ - #include <memory> +#include "core/fxcrt/fx_coordinates.h" +#include "core/fxcrt/fx_system.h" #include "xfa/fwl/core/cfwl_event.h" -#include "xfa/fwl/core/ifwl_widget.h" +#include "xfa/fwl/core/cfwl_themepart.h" +#include "xfa/fwl/core/cfwl_widgetmgr.h" +#include "xfa/fwl/core/fwl_widgethit.h" +#include "xfa/fwl/core/ifwl_widgetdelegate.h" +#include "xfa/fwl/theme/cfwl_widgettp.h" + +enum class FWL_Type { + Unknown = 0, + + Barcode, + Caret, + CheckBox, + ComboBox, + DateTimePicker, + Edit, + Form, + FormProxy, + ListBox, + MonthCalendar, + PictureBox, + PushButton, + ScrollBar, + SpinButton, + ToolTip +}; -class CFWL_Event; -class CFWL_Message; +class CFWL_App; +class CFWL_AppImp; +class CFWL_MsgKey; class CFWL_Widget; -class CFWL_WidgetDelegate; class CFWL_WidgetMgr; +class CFWL_WidgetProperties; +class IFWL_ThemeProvider; -class CFWL_Widget { +class CFWL_Widget : public IFWL_WidgetDelegate { public: - explicit CFWL_Widget(const CFWL_App*); - virtual ~CFWL_Widget(); + ~CFWL_Widget() override; + + virtual FWL_Type GetClassID() const = 0; + virtual bool IsInstance(const CFX_WideStringC& wsClass) const; + virtual void GetWidgetRect(CFX_RectF& rect, bool bAutoSize = false); + virtual void GetClientRect(CFX_RectF& rect); + virtual void ModifyStylesEx(uint32_t dwStylesExAdded, + uint32_t dwStylesExRemoved); + virtual void SetStates(uint32_t dwStates, bool bSet = true); + virtual void Update() = 0; + virtual FWL_WidgetHit HitTest(FX_FLOAT fx, FX_FLOAT fy); + virtual void DrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix = nullptr) = 0; + virtual void SetThemeProvider(IFWL_ThemeProvider* pThemeProvider); + + // IFWL_WidgetDelegate. + void OnProcessMessage(CFWL_Message* pMessage) override; + void OnProcessEvent(CFWL_Event* pEvent) override; + void OnDrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix = nullptr) override; - IFWL_Widget* GetWidget() { return m_pIface.get(); } - IFWL_Widget* GetWidget() const { return m_pIface.get(); } - - void GetWidgetRect(CFX_RectF& rect, bool bAutoSize = false); void SetWidgetRect(const CFX_RectF& rect); + void SetParent(CFWL_Widget* pParent); + + CFWL_Widget* GetOwner() { return m_pWidgetMgr->GetOwnerWidget(this); } + CFWL_Widget* GetOuter() const { return m_pOuter; } + + uint32_t GetStyles() const; void ModifyStyles(uint32_t dwStylesAdded, uint32_t dwStylesRemoved); - uint32_t GetStylesEx(); - void ModifyStylesEx(uint32_t dwStylesExAdded, uint32_t dwStylesExRemoved); + uint32_t GetStylesEx() const; + uint32_t GetStates() const; - uint32_t GetStates(); - void SetStates(uint32_t dwStates, bool bSet = true); - void SetLayoutItem(void* pItem); + void LockUpdate() { m_iLock++; } + void UnlockUpdate() { + if (IsLocked()) + m_iLock--; + } - void Update(); - void LockUpdate(); - void UnlockUpdate(); + void TransformTo(CFWL_Widget* pWidget, FX_FLOAT& fx, FX_FLOAT& fy); + void GetMatrix(CFX_Matrix& matrix, bool bGlobal = false); + IFWL_ThemeProvider* GetThemeProvider() const; - FWL_WidgetHit HitTest(FX_FLOAT fx, FX_FLOAT fy); - void DrawWidget(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix = nullptr); + void SetDelegate(IFWL_WidgetDelegate* delegate) { m_pDelegate = delegate; } + IFWL_WidgetDelegate* GetDelegate() { + return m_pDelegate ? m_pDelegate : this; + } + const IFWL_WidgetDelegate* GetDelegate() const { + return m_pDelegate ? m_pDelegate : this; + } - IFWL_WidgetDelegate* GetDelegate() const; - void SetDelegate(IFWL_WidgetDelegate*); + const CFWL_App* GetOwnerApp() const { return m_pOwnerApp; } + uint32_t GetEventKey() const { return m_nEventKey; } + void SetEventKey(uint32_t key) { m_nEventKey = key; } - protected: - void Initialize(); + void* GetLayoutItem() const { return m_pLayoutItem; } + void SetLayoutItem(void* pItem) { m_pLayoutItem = pItem; } - const CFWL_App* m_pApp; - std::unique_ptr<IFWL_Widget> m_pIface; + void SetFocus(bool bFocus); + void Repaint(const CFX_RectF* pRect = nullptr); + + protected: + CFWL_Widget(const CFWL_App* app, + std::unique_ptr<CFWL_WidgetProperties> properties, + CFWL_Widget* pOuter); + + bool IsEnabled() const; + bool IsActive() const; + bool IsLocked() const { return m_iLock > 0; } + bool HasBorder() const; + bool HasEdge() const; + void GetEdgeRect(CFX_RectF& rtEdge); + FX_FLOAT GetBorderSize(bool bCX = true); + FX_FLOAT GetEdgeWidth(); + void GetRelativeRect(CFX_RectF& rect); + void* GetThemeCapacity(CFWL_WidgetCapacity dwCapacity); + IFWL_ThemeProvider* GetAvailableTheme(); + CFX_SizeF CalcTextSize(const CFX_WideString& wsText, + IFWL_ThemeProvider* pTheme, + bool bMultiLine = false, + int32_t iLineWidth = -1); + void CalcTextRect(const CFX_WideString& wsText, + IFWL_ThemeProvider* pTheme, + uint32_t dwTTOStyles, + int32_t iTTOAlign, + CFX_RectF& rect); + void SetGrab(bool bSet); + void GetPopupPos(FX_FLOAT fMinHeight, + FX_FLOAT fMaxHeight, + const CFX_RectF& rtAnchor, + CFX_RectF& rtPopup); + void RegisterEventTarget(CFWL_Widget* pEventSource); + void UnregisterEventTarget(); + void DispatchKeyEvent(CFWL_MsgKey* pNote); + void DispatchEvent(CFWL_Event* pEvent); + void DrawBorder(CFX_Graphics* pGraphics, + CFWL_Part iPartBorder, + IFWL_ThemeProvider* pTheme, + const CFX_Matrix* pMatrix = nullptr); + void DrawEdge(CFX_Graphics* pGraphics, + CFWL_Part iPartEdge, + IFWL_ThemeProvider* pTheme, + const CFX_Matrix* pMatrix = nullptr); + + const CFWL_App* const m_pOwnerApp; + CFWL_WidgetMgr* const m_pWidgetMgr; + std::unique_ptr<CFWL_WidgetProperties> m_pProperties; + CFWL_Widget* m_pOuter; + int32_t m_iLock; + + private: + CFWL_Widget* GetParent() { return m_pWidgetMgr->GetParentWidget(this); } + CFX_SizeF GetOffsetFromParent(CFWL_Widget* pParent); + + bool IsVisible() const; + bool IsOverLapper() const; + bool IsPopup() const; + bool IsChild() const; + bool IsOffscreen() const; + CFWL_Widget* GetRootOuter(); + bool GetPopupPosMenu(FX_FLOAT fMinHeight, + FX_FLOAT fMaxHeight, + const CFX_RectF& rtAnchor, + CFX_RectF& rtPopup); + bool GetPopupPosComboBox(FX_FLOAT fMinHeight, + FX_FLOAT fMaxHeight, + const CFX_RectF& rtAnchor, + CFX_RectF& rtPopup); + bool GetPopupPosGeneral(FX_FLOAT fMinHeight, + FX_FLOAT fMaxHeight, + const CFX_RectF& rtAnchor, + CFX_RectF& rtPopup); + bool GetScreenSize(FX_FLOAT& fx, FX_FLOAT& fy); + void DrawBackground(CFX_Graphics* pGraphics, + CFWL_Part iPartBk, + IFWL_ThemeProvider* pTheme, + const CFX_Matrix* pMatrix = nullptr); + void NotifyDriver(); + bool IsParent(CFWL_Widget* pParent); + + void* m_pLayoutItem; + uint32_t m_nEventKey; + IFWL_WidgetDelegate* m_pDelegate; // Not owned. }; #endif // XFA_FWL_CORE_CFWL_WIDGET_H_ diff --git a/xfa/fwl/core/cfwl_widgetmgr.cpp b/xfa/fwl/core/cfwl_widgetmgr.cpp index 8a658b5e6e..1514aeedff 100644 --- a/xfa/fwl/core/cfwl_widgetmgr.cpp +++ b/xfa/fwl/core/cfwl_widgetmgr.cpp @@ -28,7 +28,7 @@ struct FWL_NEEDREPAINTHITDATA { } // namespace -bool FWL_UseOffscreen(IFWL_Widget* pWidget) { +bool FWL_UseOffscreen(CFWL_Widget* pWidget) { #if (_FX_OS_ == _FX_MACOSX_) return false; #else @@ -47,17 +47,17 @@ CFWL_WidgetMgr::CFWL_WidgetMgr(CXFA_FFApp* pAdapterNative) CFWL_WidgetMgr::~CFWL_WidgetMgr() {} -IFWL_Widget* CFWL_WidgetMgr::GetParentWidget(IFWL_Widget* pWidget) const { +CFWL_Widget* CFWL_WidgetMgr::GetParentWidget(CFWL_Widget* pWidget) const { Item* pItem = GetWidgetMgrItem(pWidget); return pItem && pItem->pParent ? pItem->pParent->pWidget : nullptr; } -IFWL_Widget* CFWL_WidgetMgr::GetOwnerWidget(IFWL_Widget* pWidget) const { +CFWL_Widget* CFWL_WidgetMgr::GetOwnerWidget(CFWL_Widget* pWidget) const { Item* pItem = GetWidgetMgrItem(pWidget); return pItem && pItem->pOwner ? pItem->pOwner->pWidget : nullptr; } -IFWL_Widget* CFWL_WidgetMgr::GetFirstSiblingWidget(IFWL_Widget* pWidget) const { +CFWL_Widget* CFWL_WidgetMgr::GetFirstSiblingWidget(CFWL_Widget* pWidget) const { Item* pItem = GetWidgetMgrItem(pWidget); if (!pItem) return nullptr; @@ -68,22 +68,22 @@ IFWL_Widget* CFWL_WidgetMgr::GetFirstSiblingWidget(IFWL_Widget* pWidget) const { return pItem ? pItem->pWidget : nullptr; } -IFWL_Widget* CFWL_WidgetMgr::GetPriorSiblingWidget(IFWL_Widget* pWidget) const { +CFWL_Widget* CFWL_WidgetMgr::GetPriorSiblingWidget(CFWL_Widget* pWidget) const { Item* pItem = GetWidgetMgrItem(pWidget); return pItem && pItem->pPrevious ? pItem->pPrevious->pWidget : nullptr; } -IFWL_Widget* CFWL_WidgetMgr::GetNextSiblingWidget(IFWL_Widget* pWidget) const { +CFWL_Widget* CFWL_WidgetMgr::GetNextSiblingWidget(CFWL_Widget* pWidget) const { Item* pItem = GetWidgetMgrItem(pWidget); return pItem && pItem->pNext ? pItem->pNext->pWidget : nullptr; } -IFWL_Widget* CFWL_WidgetMgr::GetFirstChildWidget(IFWL_Widget* pWidget) const { +CFWL_Widget* CFWL_WidgetMgr::GetFirstChildWidget(CFWL_Widget* pWidget) const { Item* pItem = GetWidgetMgrItem(pWidget); return pItem && pItem->pChild ? pItem->pChild->pWidget : nullptr; } -IFWL_Widget* CFWL_WidgetMgr::GetLastChildWidget(IFWL_Widget* pWidget) const { +CFWL_Widget* CFWL_WidgetMgr::GetLastChildWidget(CFWL_Widget* pWidget) const { Item* pItem = GetWidgetMgrItem(pWidget); if (!pItem) return nullptr; @@ -94,7 +94,7 @@ IFWL_Widget* CFWL_WidgetMgr::GetLastChildWidget(IFWL_Widget* pWidget) const { return pItem ? pItem->pWidget : nullptr; } -IFWL_Widget* CFWL_WidgetMgr::GetSystemFormWidget(IFWL_Widget* pWidget) const { +CFWL_Widget* CFWL_WidgetMgr::GetSystemFormWidget(CFWL_Widget* pWidget) const { Item* pItem = GetWidgetMgrItem(pWidget); while (pItem) { if (IsAbleNative(pItem->pWidget)) @@ -104,7 +104,7 @@ IFWL_Widget* CFWL_WidgetMgr::GetSystemFormWidget(IFWL_Widget* pWidget) const { return nullptr; } -void CFWL_WidgetMgr::SetWidgetIndex(IFWL_Widget* pWidget, int32_t nIndex) { +void CFWL_WidgetMgr::SetWidgetIndex(CFWL_Widget* pWidget, int32_t nIndex) { Item* pItem = GetWidgetMgrItem(pWidget); if (!pItem) return; @@ -173,15 +173,15 @@ void CFWL_WidgetMgr::SetWidgetIndex(IFWL_Widget* pWidget, int32_t nIndex) { } } -void CFWL_WidgetMgr::RepaintWidget(IFWL_Widget* pWidget, +void CFWL_WidgetMgr::RepaintWidget(CFWL_Widget* pWidget, const CFX_RectF* pRect) { if (!m_pAdapter) return; - IFWL_Widget* pNative = pWidget; + CFWL_Widget* pNative = pWidget; CFX_RectF rect(*pRect); if (IsFormDisabled()) { - IFWL_Widget* pOuter = pWidget->GetOuter(); + CFWL_Widget* pOuter = pWidget->GetOuter(); while (pOuter) { CFX_RectF rtTemp; pNative->GetWidgetRect(rtTemp); @@ -201,8 +201,8 @@ void CFWL_WidgetMgr::RepaintWidget(IFWL_Widget* pWidget, m_pAdapter->RepaintWidget(pNative, &rect); } -void CFWL_WidgetMgr::InsertWidget(IFWL_Widget* pParent, - IFWL_Widget* pChild, +void CFWL_WidgetMgr::InsertWidget(CFWL_Widget* pParent, + CFWL_Widget* pChild, int32_t nIndex) { Item* pParentItem = GetWidgetMgrItem(pParent); if (!pParentItem) { @@ -232,7 +232,7 @@ void CFWL_WidgetMgr::InsertWidget(IFWL_Widget* pParent, SetWidgetIndex(pChild, nIndex); } -void CFWL_WidgetMgr::RemoveWidget(IFWL_Widget* pWidget) { +void CFWL_WidgetMgr::RemoveWidget(CFWL_Widget* pWidget) { Item* pItem = GetWidgetMgrItem(pWidget); if (!pItem) return; @@ -252,7 +252,7 @@ void CFWL_WidgetMgr::RemoveWidget(IFWL_Widget* pWidget) { m_mapWidgetItem.erase(pWidget); } -void CFWL_WidgetMgr::SetOwner(IFWL_Widget* pOwner, IFWL_Widget* pOwned) { +void CFWL_WidgetMgr::SetOwner(CFWL_Widget* pOwner, CFWL_Widget* pOwned) { Item* pParentItem = GetWidgetMgrItem(pOwner); if (!pParentItem) { auto item = pdfium::MakeUnique<Item>(pOwner); @@ -271,7 +271,7 @@ void CFWL_WidgetMgr::SetOwner(IFWL_Widget* pOwner, IFWL_Widget* pOwned) { } pItem->pOwner = pParentItem; } -void CFWL_WidgetMgr::SetParent(IFWL_Widget* pParent, IFWL_Widget* pChild) { +void CFWL_WidgetMgr::SetParent(CFWL_Widget* pParent, CFWL_Widget* pChild) { Item* pParentItem = GetWidgetMgrItem(pParent); Item* pItem = GetWidgetMgrItem(pChild); if (!pItem) @@ -291,7 +291,7 @@ void CFWL_WidgetMgr::SetParent(IFWL_Widget* pParent, IFWL_Widget* pChild) { SetWidgetIndex(pChild, -1); } -void CFWL_WidgetMgr::SetWidgetRect_Native(IFWL_Widget* pWidget, +void CFWL_WidgetMgr::SetWidgetRect_Native(CFWL_Widget* pWidget, const CFX_RectF& rect) { if (!FWL_UseOffscreen(pWidget)) return; @@ -313,7 +313,7 @@ void CFWL_WidgetMgr::SetWidgetRect_Native(IFWL_Widget* pWidget, #endif } -IFWL_Widget* CFWL_WidgetMgr::GetWidgetAtPoint(IFWL_Widget* parent, +CFWL_Widget* CFWL_WidgetMgr::GetWidgetAtPoint(CFWL_Widget* parent, FX_FLOAT x, FX_FLOAT y) { if (!parent) @@ -321,7 +321,7 @@ IFWL_Widget* CFWL_WidgetMgr::GetWidgetAtPoint(IFWL_Widget* parent, FX_FLOAT x1; FX_FLOAT y1; - IFWL_Widget* child = GetLastChildWidget(parent); + CFWL_Widget* child = GetLastChildWidget(parent); while (child) { if ((child->GetStates() & FWL_WGTSTATE_Invisible) == 0) { x1 = x; @@ -345,18 +345,18 @@ IFWL_Widget* CFWL_WidgetMgr::GetWidgetAtPoint(IFWL_Widget* parent, return parent; } -void CFWL_WidgetMgr::NotifySizeChanged(IFWL_Widget* pForm, +void CFWL_WidgetMgr::NotifySizeChanged(CFWL_Widget* pForm, FX_FLOAT fx, FX_FLOAT fy) { if (FWL_UseOffscreen(pForm)) GetWidgetMgrItem(pForm)->pOffscreen.reset(); } -IFWL_Widget* CFWL_WidgetMgr::NextTab(IFWL_Widget* parent, - IFWL_Widget* focus, +CFWL_Widget* CFWL_WidgetMgr::NextTab(CFWL_Widget* parent, + CFWL_Widget* focus, bool& bFind) { CFWL_WidgetMgr* pMgr = parent->GetOwnerApp()->GetWidgetMgr(); - IFWL_Widget* child = pMgr->GetFirstChildWidget(parent); + CFWL_Widget* child = pMgr->GetFirstChildWidget(parent); while (child) { if (focus == child) bFind = true; @@ -365,7 +365,7 @@ IFWL_Widget* CFWL_WidgetMgr::NextTab(IFWL_Widget* parent, (!focus || (focus != child && bFind))) { return child; } - IFWL_Widget* bRet = NextTab(child, focus, bFind); + CFWL_Widget* bRet = NextTab(child, focus, bFind); if (bRet) return bRet; @@ -374,9 +374,9 @@ IFWL_Widget* CFWL_WidgetMgr::NextTab(IFWL_Widget* parent, return nullptr; } -int32_t CFWL_WidgetMgr::CountRadioButtonGroup(IFWL_Widget* pFirst) const { +int32_t CFWL_WidgetMgr::CountRadioButtonGroup(CFWL_Widget* pFirst) const { int32_t iRet = 0; - IFWL_Widget* pChild = pFirst; + CFWL_Widget* pChild = pFirst; while (pChild) { pChild = GetNextSiblingWidget(pChild); ++iRet; @@ -384,18 +384,18 @@ int32_t CFWL_WidgetMgr::CountRadioButtonGroup(IFWL_Widget* pFirst) const { return iRet; } -IFWL_Widget* CFWL_WidgetMgr::GetRadioButtonGroupHeader( - IFWL_Widget* pRadioButton) const { - IFWL_Widget* pNext = pRadioButton; +CFWL_Widget* CFWL_WidgetMgr::GetRadioButtonGroupHeader( + CFWL_Widget* pRadioButton) const { + CFWL_Widget* pNext = pRadioButton; if (pNext && (pNext->GetStyles() & FWL_WGTSTYLE_Group)) return pNext; return nullptr; } void CFWL_WidgetMgr::GetSameGroupRadioButton( - IFWL_Widget* pRadioButton, - CFX_ArrayTemplate<IFWL_Widget*>& group) const { - IFWL_Widget* pFirst = GetFirstSiblingWidget(pRadioButton); + CFWL_Widget* pRadioButton, + CFX_ArrayTemplate<CFWL_Widget*>& group) const { + CFWL_Widget* pFirst = GetFirstSiblingWidget(pRadioButton); if (!pFirst) pFirst = pRadioButton; @@ -405,20 +405,20 @@ void CFWL_WidgetMgr::GetSameGroupRadioButton( group.Add(GetRadioButtonGroupHeader(pRadioButton)); } -IFWL_Widget* CFWL_WidgetMgr::GetDefaultButton(IFWL_Widget* pParent) const { +CFWL_Widget* CFWL_WidgetMgr::GetDefaultButton(CFWL_Widget* pParent) const { if ((pParent->GetClassID() == FWL_Type::PushButton) && (pParent->GetStates() & (1 << (FWL_WGTSTATE_MAX + 2)))) { return pParent; } - IFWL_Widget* child = + CFWL_Widget* child = pParent->GetOwnerApp()->GetWidgetMgr()->GetFirstChildWidget(pParent); while (child) { if ((child->GetClassID() == FWL_Type::PushButton) && (child->GetStates() & (1 << (FWL_WGTSTATE_MAX + 2)))) { return child; } - if (IFWL_Widget* find = GetDefaultButton(child)) + if (CFWL_Widget* find = GetDefaultButton(child)) return find; child = child->GetOwnerApp()->GetWidgetMgr()->GetNextSiblingWidget(child); @@ -426,22 +426,22 @@ IFWL_Widget* CFWL_WidgetMgr::GetDefaultButton(IFWL_Widget* pParent) const { return nullptr; } -void CFWL_WidgetMgr::AddRedrawCounts(IFWL_Widget* pWidget) { +void CFWL_WidgetMgr::AddRedrawCounts(CFWL_Widget* pWidget) { GetWidgetMgrItem(pWidget)->iRedrawCounter++; } -void CFWL_WidgetMgr::ResetRedrawCounts(IFWL_Widget* pWidget) { +void CFWL_WidgetMgr::ResetRedrawCounts(CFWL_Widget* pWidget) { GetWidgetMgrItem(pWidget)->iRedrawCounter = 0; } CFWL_WidgetMgr::Item* CFWL_WidgetMgr::GetWidgetMgrItem( - IFWL_Widget* pWidget) const { + CFWL_Widget* pWidget) const { auto it = m_mapWidgetItem.find(pWidget); return it != m_mapWidgetItem.end() ? static_cast<Item*>(it->second.get()) : nullptr; } -bool CFWL_WidgetMgr::IsAbleNative(IFWL_Widget* pWidget) const { +bool CFWL_WidgetMgr::IsAbleNative(CFWL_Widget* pWidget) const { if (!pWidget) return false; if (!pWidget->IsInstance(FX_WSTRC(FWL_CLASS_Form))) @@ -453,7 +453,7 @@ bool CFWL_WidgetMgr::IsAbleNative(IFWL_Widget* pWidget) const { (dwStyles & FWL_WGTSTYLE_Popup); } -void CFWL_WidgetMgr::GetAdapterPopupPos(IFWL_Widget* pWidget, +void CFWL_WidgetMgr::GetAdapterPopupPos(CFWL_Widget* pWidget, FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight, const CFX_RectF& rtAnchor, @@ -471,7 +471,7 @@ void CFWL_WidgetMgr::OnProcessMessageToForm(CFWL_Message* pMessage) { if (!pMessage->m_pDstTarget) return; - IFWL_Widget* pDstWidget = pMessage->m_pDstTarget; + CFWL_Widget* pDstWidget = pMessage->m_pDstTarget; const CFWL_App* pApp = pDstWidget->GetOwnerApp(); if (!pApp) return; @@ -494,7 +494,7 @@ void CFWL_WidgetMgr::OnProcessMessageToForm(CFWL_Message* pMessage) { #endif } -void CFWL_WidgetMgr::OnDrawWidget(IFWL_Widget* pWidget, +void CFWL_WidgetMgr::OnDrawWidget(CFWL_Widget* pWidget, CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix) { if (!pWidget || !pGraphics) @@ -540,7 +540,7 @@ void CFWL_WidgetMgr::OnDrawWidget(IFWL_Widget* pWidget, ResetRedrawCounts(pWidget); } -void CFWL_WidgetMgr::DrawChild(IFWL_Widget* parent, +void CFWL_WidgetMgr::DrawChild(CFWL_Widget* parent, const CFX_RectF& rtClip, CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix) { @@ -548,9 +548,9 @@ void CFWL_WidgetMgr::DrawChild(IFWL_Widget* parent, return; bool bFormDisable = IsFormDisabled(); - IFWL_Widget* pNextChild = GetFirstChildWidget(parent); + CFWL_Widget* pNextChild = GetFirstChildWidget(parent); while (pNextChild) { - IFWL_Widget* child = pNextChild; + CFWL_Widget* child = pNextChild; pNextChild = GetNextSiblingWidget(child); if (child->GetStates() & FWL_WGTSTATE_Invisible) continue; @@ -591,7 +591,7 @@ void CFWL_WidgetMgr::DrawChild(IFWL_Widget* parent, } } -CFX_Graphics* CFWL_WidgetMgr::DrawWidgetBefore(IFWL_Widget* pWidget, +CFX_Graphics* CFWL_WidgetMgr::DrawWidgetBefore(CFWL_Widget* pWidget, CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix) { if (!FWL_UseOffscreen(pWidget)) @@ -611,7 +611,7 @@ CFX_Graphics* CFWL_WidgetMgr::DrawWidgetBefore(IFWL_Widget* pWidget, return pItem->pOffscreen.get(); } -void CFWL_WidgetMgr::DrawWidgetAfter(IFWL_Widget* pWidget, +void CFWL_WidgetMgr::DrawWidgetAfter(CFWL_Widget* pWidget, CFX_Graphics* pGraphics, CFX_RectF& rtClip, const CFX_Matrix* pMatrix) { @@ -627,7 +627,7 @@ void CFWL_WidgetMgr::DrawWidgetAfter(IFWL_Widget* pWidget, pItem->iRedrawCounter = 0; } -bool CFWL_WidgetMgr::IsNeedRepaint(IFWL_Widget* pWidget, +bool CFWL_WidgetMgr::IsNeedRepaint(CFWL_Widget* pWidget, CFX_Matrix* pMatrix, const CFX_RectF& rtDirty) { Item* pItem = GetWidgetMgrItem(pWidget); @@ -643,7 +643,7 @@ bool CFWL_WidgetMgr::IsNeedRepaint(IFWL_Widget* pWidget, if (!rtWidget.IntersectWith(rtDirty)) return false; - IFWL_Widget* pChild = + CFWL_Widget* pChild = pWidget->GetOwnerApp()->GetWidgetMgr()->GetFirstChildWidget(pWidget); if (!pChild) return true; @@ -727,7 +727,7 @@ bool CFWL_WidgetMgr::IsNeedRepaint(IFWL_Widget* pWidget, return true; } -bool CFWL_WidgetMgr::UseOffscreenDirect(IFWL_Widget* pWidget) const { +bool CFWL_WidgetMgr::UseOffscreenDirect(CFWL_Widget* pWidget) const { Item* pItem = GetWidgetMgrItem(pWidget); if (!FWL_UseOffscreen(pWidget) || !(pItem->pOffscreen)) return false; @@ -750,7 +750,7 @@ bool CFWL_WidgetMgr::UseOffscreenDirect(IFWL_Widget* pWidget) const { CFWL_WidgetMgr::Item::Item() : CFWL_WidgetMgr::Item(nullptr) {} -CFWL_WidgetMgr::Item::Item(IFWL_Widget* widget) +CFWL_WidgetMgr::Item::Item(CFWL_Widget* widget) : pParent(nullptr), pOwner(nullptr), pChild(nullptr), diff --git a/xfa/fwl/core/cfwl_widgetmgr.h b/xfa/fwl/core/cfwl_widgetmgr.h index 0c6a184871..70d8b7ec7c 100644 --- a/xfa/fwl/core/cfwl_widgetmgr.h +++ b/xfa/fwl/core/cfwl_widgetmgr.h @@ -22,53 +22,53 @@ class CXFA_FFApp; class CXFA_FWLAdapterWidgetMgr; class CFX_Graphics; class CFX_Matrix; -class IFWL_Widget; +class CFWL_Widget; -class CFWL_WidgetMgr : public IFWL_WidgetMgrDelegate { +class CFWL_WidgetMgr : public CFWL_WidgetMgrDelegate { public: explicit CFWL_WidgetMgr(CXFA_FFApp* pAdapterNative); ~CFWL_WidgetMgr(); - // IFWL_WidgetMgrDelegate + // CFWL_WidgetMgrDelegate void OnSetCapability(uint32_t dwCapability) override; void OnProcessMessageToForm(CFWL_Message* pMessage) override; - void OnDrawWidget(IFWL_Widget* pWidget, + void OnDrawWidget(CFWL_Widget* pWidget, CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix) override; - IFWL_Widget* GetParentWidget(IFWL_Widget* pWidget) const; - IFWL_Widget* GetOwnerWidget(IFWL_Widget* pWidget) const; - IFWL_Widget* GetNextSiblingWidget(IFWL_Widget* pWidget) const; - IFWL_Widget* GetFirstChildWidget(IFWL_Widget* pWidget) const; - IFWL_Widget* GetSystemFormWidget(IFWL_Widget* pWidget) const; + CFWL_Widget* GetParentWidget(CFWL_Widget* pWidget) const; + CFWL_Widget* GetOwnerWidget(CFWL_Widget* pWidget) const; + CFWL_Widget* GetNextSiblingWidget(CFWL_Widget* pWidget) const; + CFWL_Widget* GetFirstChildWidget(CFWL_Widget* pWidget) const; + CFWL_Widget* GetSystemFormWidget(CFWL_Widget* pWidget) const; - void RepaintWidget(IFWL_Widget* pWidget, const CFX_RectF* pRect = nullptr); + void RepaintWidget(CFWL_Widget* pWidget, const CFX_RectF* pRect = nullptr); - void InsertWidget(IFWL_Widget* pParent, - IFWL_Widget* pChild, + void InsertWidget(CFWL_Widget* pParent, + CFWL_Widget* pChild, int32_t nIndex = -1); - void RemoveWidget(IFWL_Widget* pWidget); - void SetOwner(IFWL_Widget* pOwner, IFWL_Widget* pOwned); - void SetParent(IFWL_Widget* pParent, IFWL_Widget* pChild); + void RemoveWidget(CFWL_Widget* pWidget); + void SetOwner(CFWL_Widget* pOwner, CFWL_Widget* pOwned); + void SetParent(CFWL_Widget* pParent, CFWL_Widget* pChild); - void SetWidgetRect_Native(IFWL_Widget* pWidget, const CFX_RectF& rect); + void SetWidgetRect_Native(CFWL_Widget* pWidget, const CFX_RectF& rect); - IFWL_Widget* GetWidgetAtPoint(IFWL_Widget* pParent, FX_FLOAT fx, FX_FLOAT fy); + CFWL_Widget* GetWidgetAtPoint(CFWL_Widget* pParent, FX_FLOAT fx, FX_FLOAT fy); - void NotifySizeChanged(IFWL_Widget* pForm, FX_FLOAT fx, FX_FLOAT fy); + void NotifySizeChanged(CFWL_Widget* pForm, FX_FLOAT fx, FX_FLOAT fy); - IFWL_Widget* NextTab(IFWL_Widget* parent, IFWL_Widget* focus, bool& bFind); + CFWL_Widget* NextTab(CFWL_Widget* parent, CFWL_Widget* focus, bool& bFind); - void GetSameGroupRadioButton(IFWL_Widget* pRadioButton, - CFX_ArrayTemplate<IFWL_Widget*>& group) const; - IFWL_Widget* GetDefaultButton(IFWL_Widget* pParent) const; - void AddRedrawCounts(IFWL_Widget* pWidget); + void GetSameGroupRadioButton(CFWL_Widget* pRadioButton, + CFX_ArrayTemplate<CFWL_Widget*>& group) const; + CFWL_Widget* GetDefaultButton(CFWL_Widget* pParent) const; + void AddRedrawCounts(CFWL_Widget* pWidget); bool IsFormDisabled() const { return !!(m_dwCapability & FWL_WGTMGR_DisableForm); } - void GetAdapterPopupPos(IFWL_Widget* pWidget, + void GetAdapterPopupPos(CFWL_Widget* pWidget, FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight, const CFX_RectF& rtAnchor, @@ -78,7 +78,7 @@ class CFWL_WidgetMgr : public IFWL_WidgetMgrDelegate { class Item { public: Item(); - explicit Item(IFWL_Widget* widget); + explicit Item(CFWL_Widget* widget); ~Item(); Item* pParent; @@ -86,7 +86,7 @@ class CFWL_WidgetMgr : public IFWL_WidgetMgrDelegate { Item* pChild; Item* pPrevious; Item* pNext; - IFWL_Widget* const pWidget; + CFWL_Widget* const pWidget; std::unique_ptr<CFX_Graphics> pOffscreen; int32_t iRedrawCounter; #if (_FX_OS_ == _FX_WIN32_DESKTOP_) || (_FX_OS_ == _FX_WIN64_) @@ -94,38 +94,38 @@ class CFWL_WidgetMgr : public IFWL_WidgetMgrDelegate { #endif }; - IFWL_Widget* GetFirstSiblingWidget(IFWL_Widget* pWidget) const; - IFWL_Widget* GetPriorSiblingWidget(IFWL_Widget* pWidget) const; - IFWL_Widget* GetLastChildWidget(IFWL_Widget* pWidget) const; - Item* GetWidgetMgrItem(IFWL_Widget* pWidget) const; + CFWL_Widget* GetFirstSiblingWidget(CFWL_Widget* pWidget) const; + CFWL_Widget* GetPriorSiblingWidget(CFWL_Widget* pWidget) const; + CFWL_Widget* GetLastChildWidget(CFWL_Widget* pWidget) const; + Item* GetWidgetMgrItem(CFWL_Widget* pWidget) const; - void SetWidgetIndex(IFWL_Widget* pWidget, int32_t nIndex); + void SetWidgetIndex(CFWL_Widget* pWidget, int32_t nIndex); - int32_t CountRadioButtonGroup(IFWL_Widget* pFirst) const; - IFWL_Widget* GetRadioButtonGroupHeader(IFWL_Widget* pRadioButton) const; + int32_t CountRadioButtonGroup(CFWL_Widget* pFirst) const; + CFWL_Widget* GetRadioButtonGroupHeader(CFWL_Widget* pRadioButton) const; - void ResetRedrawCounts(IFWL_Widget* pWidget); + void ResetRedrawCounts(CFWL_Widget* pWidget); - void DrawChild(IFWL_Widget* pParent, + void DrawChild(CFWL_Widget* pParent, const CFX_RectF& rtClip, CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix); - CFX_Graphics* DrawWidgetBefore(IFWL_Widget* pWidget, + CFX_Graphics* DrawWidgetBefore(CFWL_Widget* pWidget, CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix); - void DrawWidgetAfter(IFWL_Widget* pWidget, + void DrawWidgetAfter(CFWL_Widget* pWidget, CFX_Graphics* pGraphics, CFX_RectF& rtClip, const CFX_Matrix* pMatrix); - bool IsNeedRepaint(IFWL_Widget* pWidget, + bool IsNeedRepaint(CFWL_Widget* pWidget, CFX_Matrix* pMatrix, const CFX_RectF& rtDirty); - bool UseOffscreenDirect(IFWL_Widget* pWidget) const; + bool UseOffscreenDirect(CFWL_Widget* pWidget) const; - bool IsAbleNative(IFWL_Widget* pWidget) const; + bool IsAbleNative(CFWL_Widget* pWidget) const; uint32_t m_dwCapability; - std::map<IFWL_Widget*, std::unique_ptr<Item>> m_mapWidgetItem; + std::map<CFWL_Widget*, std::unique_ptr<Item>> m_mapWidgetItem; CXFA_FWLAdapterWidgetMgr* const m_pAdapter; #if (_FX_OS_ == _FX_WIN32_DESKTOP_) || (_FX_OS_ == _FX_WIN64_) CFX_RectF m_rtScreen; diff --git a/xfa/fwl/core/cfwl_widgetproperties.h b/xfa/fwl/core/cfwl_widgetproperties.h index c8746f57d8..d7bf72e9f9 100644 --- a/xfa/fwl/core/cfwl_widgetproperties.h +++ b/xfa/fwl/core/cfwl_widgetproperties.h @@ -9,11 +9,11 @@ #include "core/fxcrt/fx_coordinates.h" #include "core/fxcrt/fx_system.h" +#include "xfa/fwl/core/cfwl_widget.h" #include "xfa/fwl/core/fwl_widgetdef.h" -#include "xfa/fwl/core/ifwl_widget.h" class IFWL_ThemeProvider; -class IFWL_Widget; +class CFWL_Widget; class CFWL_WidgetProperties { public: @@ -25,8 +25,8 @@ class CFWL_WidgetProperties { uint32_t m_dwStyleExes; uint32_t m_dwStates; IFWL_ThemeProvider* m_pThemeProvider; - IFWL_Widget* m_pParent; - IFWL_Widget* m_pOwner; + CFWL_Widget* m_pParent; + CFWL_Widget* m_pOwner; }; #endif // XFA_FWL_CORE_CFWL_WIDGETPROPERTIES_H_ diff --git a/xfa/fwl/core/ifwl_barcode.cpp b/xfa/fwl/core/ifwl_barcode.cpp deleted file mode 100644 index b4cd13a6c1..0000000000 --- a/xfa/fwl/core/ifwl_barcode.cpp +++ /dev/null @@ -1,175 +0,0 @@ -// 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_barcode.h" - -#include <utility> - -#include "third_party/base/ptr_util.h" -#include "xfa/fgas/font/cfgas_gefont.h" -#include "xfa/fwl/core/cfwl_notedriver.h" -#include "xfa/fwl/core/cfwl_themepart.h" -#include "xfa/fwl/core/cfx_barcode.h" -#include "xfa/fwl/core/ifwl_themeprovider.h" - -IFWL_Barcode::IFWL_Barcode(const CFWL_App* app, - std::unique_ptr<CFWL_WidgetProperties> properties) - : IFWL_Edit(app, std::move(properties), nullptr), - m_dwStatus(0), - m_type(BC_UNKNOWN) {} - -IFWL_Barcode::~IFWL_Barcode() {} - -FWL_Type IFWL_Barcode::GetClassID() const { - return FWL_Type::Barcode; -} - -void IFWL_Barcode::Update() { - if (IsLocked()) - return; - - IFWL_Edit::Update(); - GenerateBarcodeImageCache(); -} - -void IFWL_Barcode::DrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix) { - if (!pGraphics) - return; - if (!m_pProperties->m_pThemeProvider) - return; - if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) { - GenerateBarcodeImageCache(); - if (!m_pBarcodeEngine || (m_dwStatus & XFA_BCS_EncodeSuccess) == 0) - return; - - CFX_Matrix mt; - mt.e = GetRTClient().left; - mt.f = GetRTClient().top; - if (pMatrix) - mt.Concat(*pMatrix); - - int32_t errorCode = 0; - m_pBarcodeEngine->RenderDevice(pGraphics->GetRenderDevice(), pMatrix, - errorCode); - return; - } - IFWL_Edit::DrawWidget(pGraphics, pMatrix); -} - -void IFWL_Barcode::GenerateBarcodeImageCache() { - if ((m_dwStatus & XFA_BCS_NeedUpdate) == 0) - return; - - m_dwStatus = 0; - CreateBarcodeEngine(); - if (!m_pBarcodeEngine) - return; - - CFX_WideString wsText; - GetText(wsText); - - CFWL_ThemePart part; - part.m_pWidget = this; - - IFWL_ThemeProvider* pTheme = GetAvailableTheme(); - CFGAS_GEFont* pFont = static_cast<CFGAS_GEFont*>( - pTheme->GetCapacity(&part, CFWL_WidgetCapacity::Font)); - CFX_Font* pCXFont = pFont ? pFont->GetDevFont() : nullptr; - if (pCXFont) - m_pBarcodeEngine->SetFont(pCXFont); - - FX_FLOAT* pFontSize = static_cast<FX_FLOAT*>( - pTheme->GetCapacity(&part, CFWL_WidgetCapacity::FontSize)); - if (pFontSize) - m_pBarcodeEngine->SetFontSize(*pFontSize); - - FX_ARGB* pFontColor = static_cast<FX_ARGB*>( - pTheme->GetCapacity(&part, CFWL_WidgetCapacity::TextColor)); - if (pFontColor) - m_pBarcodeEngine->SetFontColor(*pFontColor); - - m_pBarcodeEngine->SetHeight(int32_t(GetRTClient().height)); - m_pBarcodeEngine->SetWidth(int32_t(GetRTClient().width)); - uint32_t dwAttributeMask = m_pDataProvider->GetBarcodeAttributeMask(); - if (dwAttributeMask & FWL_BCDATTRIBUTE_CHARENCODING) - m_pBarcodeEngine->SetCharEncoding(m_pDataProvider->GetCharEncoding()); - if (dwAttributeMask & FWL_BCDATTRIBUTE_MODULEHEIGHT) - m_pBarcodeEngine->SetModuleHeight(m_pDataProvider->GetModuleHeight()); - if (dwAttributeMask & FWL_BCDATTRIBUTE_MODULEWIDTH) - m_pBarcodeEngine->SetModuleWidth(m_pDataProvider->GetModuleWidth()); - if (dwAttributeMask & FWL_BCDATTRIBUTE_DATALENGTH) - m_pBarcodeEngine->SetDataLength(m_pDataProvider->GetDataLength()); - if (dwAttributeMask & FWL_BCDATTRIBUTE_CALCHECKSUM) - m_pBarcodeEngine->SetCalChecksum(m_pDataProvider->GetCalChecksum()); - if (dwAttributeMask & FWL_BCDATTRIBUTE_PRINTCHECKSUM) - m_pBarcodeEngine->SetPrintChecksum(m_pDataProvider->GetPrintChecksum()); - if (dwAttributeMask & FWL_BCDATTRIBUTE_TEXTLOCATION) - m_pBarcodeEngine->SetTextLocation(m_pDataProvider->GetTextLocation()); - if (dwAttributeMask & FWL_BCDATTRIBUTE_WIDENARROWRATIO) - m_pBarcodeEngine->SetWideNarrowRatio(m_pDataProvider->GetWideNarrowRatio()); - if (dwAttributeMask & FWL_BCDATTRIBUTE_STARTCHAR) - m_pBarcodeEngine->SetStartChar(m_pDataProvider->GetStartChar()); - if (dwAttributeMask & FWL_BCDATTRIBUTE_ENDCHAR) - m_pBarcodeEngine->SetEndChar(m_pDataProvider->GetEndChar()); - if (dwAttributeMask & FWL_BCDATTRIBUTE_VERSION) - m_pBarcodeEngine->SetVersion(m_pDataProvider->GetVersion()); - if (dwAttributeMask & FWL_BCDATTRIBUTE_ECLEVEL) { - m_pBarcodeEngine->SetErrorCorrectionLevel( - m_pDataProvider->GetErrorCorrectionLevel()); - } - if (dwAttributeMask & FWL_BCDATTRIBUTE_TRUNCATED) - m_pBarcodeEngine->SetTruncated(m_pDataProvider->GetTruncated()); - - int32_t errorCode = 0; - m_dwStatus = m_pBarcodeEngine->Encode(wsText.AsStringC(), true, errorCode) - ? XFA_BCS_EncodeSuccess - : 0; -} - -void IFWL_Barcode::CreateBarcodeEngine() { - if (m_pBarcodeEngine || m_type == BC_UNKNOWN) - return; - - std::unique_ptr<CFX_Barcode> pBarcode(new CFX_Barcode); - if (pBarcode->Create(m_type)) - m_pBarcodeEngine = std::move(pBarcode); -} - -void IFWL_Barcode::SetType(BC_TYPE type) { - if (m_type == type) - return; - - m_pBarcodeEngine.reset(); - m_type = type; - m_dwStatus = XFA_BCS_NeedUpdate; -} - -void IFWL_Barcode::SetText(const CFX_WideString& wsText) { - m_pBarcodeEngine.reset(); - m_dwStatus = XFA_BCS_NeedUpdate; - IFWL_Edit::SetText(wsText); -} - -bool IFWL_Barcode::IsProtectedType() const { - if (!m_pBarcodeEngine) - return true; - - BC_TYPE tEngineType = m_pBarcodeEngine->GetType(); - if (tEngineType == BC_QR_CODE || tEngineType == BC_PDF417 || - tEngineType == BC_DATAMATRIX) { - return true; - } - return false; -} - -void IFWL_Barcode::OnProcessEvent(CFWL_Event* pEvent) { - if (pEvent->GetClassID() == CFWL_EventType::TextChanged) { - m_pBarcodeEngine.reset(); - m_dwStatus = XFA_BCS_NeedUpdate; - } - IFWL_Edit::OnProcessEvent(pEvent); -} diff --git a/xfa/fwl/core/ifwl_barcode.h b/xfa/fwl/core/ifwl_barcode.h deleted file mode 100644 index 38f798fe16..0000000000 --- a/xfa/fwl/core/ifwl_barcode.h +++ /dev/null @@ -1,92 +0,0 @@ -// 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 - -#ifndef XFA_FWL_CORE_IFWL_BARCODE_H_ -#define XFA_FWL_CORE_IFWL_BARCODE_H_ - -#include <memory> - -#include "xfa/fwl/core/cfwl_scrollbar.h" -#include "xfa/fwl/core/ifwl_edit.h" -#include "xfa/fwl/core/ifwl_widget.h" -#include "xfa/fxbarcode/BC_Library.h" - -class CFWL_WidgetProperties; -class CFX_Barcode; -class IFWL_Widget; - -#define XFA_BCS_NeedUpdate 0x0001 -#define XFA_BCS_EncodeSuccess 0x0002 - -enum FWL_BCDAttribute { - FWL_BCDATTRIBUTE_NONE = 0, - FWL_BCDATTRIBUTE_CHARENCODING = 1 << 0, - FWL_BCDATTRIBUTE_MODULEHEIGHT = 1 << 1, - FWL_BCDATTRIBUTE_MODULEWIDTH = 1 << 2, - FWL_BCDATTRIBUTE_DATALENGTH = 1 << 3, - FWL_BCDATTRIBUTE_CALCHECKSUM = 1 << 4, - FWL_BCDATTRIBUTE_PRINTCHECKSUM = 1 << 5, - FWL_BCDATTRIBUTE_TEXTLOCATION = 1 << 6, - FWL_BCDATTRIBUTE_WIDENARROWRATIO = 1 << 7, - FWL_BCDATTRIBUTE_STARTCHAR = 1 << 8, - FWL_BCDATTRIBUTE_ENDCHAR = 1 << 9, - FWL_BCDATTRIBUTE_VERSION = 1 << 10, - FWL_BCDATTRIBUTE_ECLEVEL = 1 << 11, - FWL_BCDATTRIBUTE_TRUNCATED = 1 << 12 -}; - -class IFWL_Barcode : public IFWL_Edit { - public: - class DataProvider { - public: - virtual BC_CHAR_ENCODING GetCharEncoding() const = 0; - virtual int32_t GetModuleHeight() const = 0; - virtual int32_t GetModuleWidth() const = 0; - virtual int32_t GetDataLength() const = 0; - virtual bool GetCalChecksum() const = 0; - virtual bool GetPrintChecksum() const = 0; - virtual BC_TEXT_LOC GetTextLocation() const = 0; - virtual int32_t GetWideNarrowRatio() const = 0; - virtual FX_CHAR GetStartChar() const = 0; - virtual FX_CHAR GetEndChar() const = 0; - virtual int32_t GetVersion() const = 0; - virtual int32_t GetErrorCorrectionLevel() const = 0; - virtual bool GetTruncated() const = 0; - virtual uint32_t GetBarcodeAttributeMask() const = 0; - }; - - IFWL_Barcode(const CFWL_App* app, - std::unique_ptr<CFWL_WidgetProperties> properties); - ~IFWL_Barcode() override; - - // IFWL_Widget - FWL_Type GetClassID() const override; - void Update() override; - void DrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix = nullptr) override; - void OnProcessEvent(CFWL_Event* pEvent) override; - - // IFWL_Edit - void SetText(const CFX_WideString& wsText) override; - - void SetType(BC_TYPE type); - bool IsProtectedType() const; - - void SetDataProvider(IFWL_Barcode::DataProvider* provider) { - m_pDataProvider = provider; - } - - private: - void GenerateBarcodeImageCache(); - void CreateBarcodeEngine(); - - std::unique_ptr<CFX_Barcode> m_pBarcodeEngine; - IFWL_Barcode::DataProvider* m_pDataProvider; // Not owned. - uint32_t m_dwStatus; - BC_TYPE m_type; -}; - -#endif // XFA_FWL_CORE_IFWL_BARCODE_H_ diff --git a/xfa/fwl/core/ifwl_checkbox.cpp b/xfa/fwl/core/ifwl_checkbox.cpp deleted file mode 100644 index b33eaa6559..0000000000 --- a/xfa/fwl/core/ifwl_checkbox.cpp +++ /dev/null @@ -1,483 +0,0 @@ -// 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_checkbox.h" - -#include <algorithm> -#include <memory> -#include <utility> - -#include "third_party/base/ptr_util.h" -#include "xfa/fde/tto/fde_textout.h" -#include "xfa/fwl/core/cfwl_app.h" -#include "xfa/fwl/core/cfwl_evtcheckstatechanged.h" -#include "xfa/fwl/core/cfwl_msgkey.h" -#include "xfa/fwl/core/cfwl_msgmouse.h" -#include "xfa/fwl/core/cfwl_notedriver.h" -#include "xfa/fwl/core/cfwl_themebackground.h" -#include "xfa/fwl/core/cfwl_themetext.h" -#include "xfa/fwl/core/cfwl_widgetmgr.h" -#include "xfa/fwl/core/ifwl_themeprovider.h" - -namespace { - -const int kCaptionMargin = 5; - -} // namespace - -IFWL_CheckBox::IFWL_CheckBox(const CFWL_App* app, - std::unique_ptr<CFWL_WidgetProperties> properties) - : IFWL_Widget(app, std::move(properties), nullptr), - m_dwTTOStyles(FDE_TTOSTYLE_SingleLine), - m_iTTOAlign(FDE_TTOALIGNMENT_Center), - m_bBtnDown(false) { - m_rtClient.Reset(); - m_rtBox.Reset(); - m_rtCaption.Reset(); - m_rtFocus.Reset(); -} - -IFWL_CheckBox::~IFWL_CheckBox() {} - -FWL_Type IFWL_CheckBox::GetClassID() const { - return FWL_Type::CheckBox; -} - -void IFWL_CheckBox::GetWidgetRect(CFX_RectF& rect, bool bAutoSize) { - if (!bAutoSize) { - rect = m_pProperties->m_rtWidget; - return; - } - - rect.Set(0, 0, 0, 0); - if (!m_pProperties->m_pThemeProvider) - m_pProperties->m_pThemeProvider = GetAvailableTheme(); - if (!m_pProperties->m_pThemeProvider) - return; - - CFX_SizeF sz = CalcTextSize( - L"Check box", m_pProperties->m_pThemeProvider, - !!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_MultiLine)); - rect.Set(0, 0, sz.x, sz.y); - rect.Inflate(kCaptionMargin, kCaptionMargin); - - FX_FLOAT fCheckBox = m_pDataProvider->GetBoxSize(this); - rect.width += fCheckBox; - rect.height = std::max(rect.height, fCheckBox); - IFWL_Widget::GetWidgetRect(rect, true); -} - -void IFWL_CheckBox::Update() { - if (IsLocked()) - return; - if (!m_pProperties->m_pThemeProvider) - m_pProperties->m_pThemeProvider = GetAvailableTheme(); - - UpdateTextOutStyles(); - Layout(); -} - -void IFWL_CheckBox::DrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix) { - if (!pGraphics) - return; - if (!m_pProperties->m_pThemeProvider) - return; - - IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider; - if (HasBorder()) { - DrawBorder(pGraphics, CFWL_Part::Border, m_pProperties->m_pThemeProvider, - pMatrix); - } - if (HasEdge()) - DrawEdge(pGraphics, CFWL_Part::Edge, pTheme, pMatrix); - - int32_t dwStates = GetPartStates(); - - CFWL_ThemeBackground param; - param.m_pWidget = this; - param.m_iPart = CFWL_Part::Background; - param.m_dwStates = dwStates; - param.m_pGraphics = pGraphics; - if (pMatrix) - param.m_matrix.Concat(*pMatrix); - param.m_rtPart = m_rtClient; - if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) - param.m_pData = &m_rtFocus; - pTheme->DrawBackground(¶m); - - param.m_iPart = CFWL_Part::CheckBox; - param.m_rtPart = m_rtBox; - pTheme->DrawBackground(¶m); - - CFWL_ThemeText textParam; - textParam.m_pWidget = this; - textParam.m_iPart = CFWL_Part::Caption; - textParam.m_dwStates = dwStates; - textParam.m_pGraphics = pGraphics; - if (pMatrix) - textParam.m_matrix.Concat(*pMatrix); - textParam.m_rtPart = m_rtCaption; - textParam.m_wsText = L"Check box"; - textParam.m_dwTTOStyles = m_dwTTOStyles; - textParam.m_iTTOAlign = m_iTTOAlign; - pTheme->DrawText(&textParam); -} - -void IFWL_CheckBox::SetCheckState(int32_t iCheck) { - m_pProperties->m_dwStates &= ~FWL_STATE_CKB_CheckMask; - switch (iCheck) { - case 1: - m_pProperties->m_dwStates |= FWL_STATE_CKB_Checked; - break; - case 2: - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_3State) - m_pProperties->m_dwStates |= FWL_STATE_CKB_Neutral; - break; - default: - break; - } - Repaint(&m_rtClient); -} - -void IFWL_CheckBox::Layout() { - m_pProperties->m_rtWidget.width = - FXSYS_round(m_pProperties->m_rtWidget.width); - m_pProperties->m_rtWidget.height = - FXSYS_round(m_pProperties->m_rtWidget.height); - GetClientRect(m_rtClient); - - FX_FLOAT fBoxTop = m_rtClient.top; - FX_FLOAT fClientBottom = m_rtClient.bottom(); - - FX_FLOAT fCheckBox = m_pDataProvider->GetBoxSize(this); - switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_VLayoutMask) { - case FWL_STYLEEXT_CKB_Top: - break; - case FWL_STYLEEXT_CKB_Bottom: { - fBoxTop = fClientBottom - fCheckBox; - break; - } - case FWL_STYLEEXT_CKB_VCenter: - default: { - fBoxTop = m_rtClient.top + (m_rtClient.height - fCheckBox) / 2; - fBoxTop = FXSYS_floor(fBoxTop); - break; - } - } - - FX_FLOAT fBoxLeft = m_rtClient.left; - FX_FLOAT fTextLeft = 0.0; - FX_FLOAT fTextRight = 0.0; - FX_FLOAT fClientRight = m_rtClient.right(); - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_LeftText) { - fBoxLeft = fClientRight - fCheckBox; - fTextLeft = m_rtClient.left; - fTextRight = fBoxLeft; - } else { - fTextLeft = fBoxLeft + fCheckBox; - fTextRight = fClientRight; - } - m_rtBox.Set(fBoxLeft, fBoxTop, fCheckBox, fCheckBox); - m_rtCaption.Set(fTextLeft, m_rtClient.top, fTextRight - fTextLeft, - m_rtClient.height); - m_rtCaption.Inflate(-kCaptionMargin, -kCaptionMargin); - - CFX_RectF rtFocus; - rtFocus.Set(m_rtCaption.left, m_rtCaption.top, m_rtCaption.width, - m_rtCaption.height); - - CalcTextRect(L"Check box", m_pProperties->m_pThemeProvider, m_dwTTOStyles, - m_iTTOAlign, rtFocus); - if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_MultiLine) == 0) { - FX_FLOAT fWidth = std::max(m_rtCaption.width, rtFocus.width); - FX_FLOAT fHeight = std::min(m_rtCaption.height, rtFocus.height); - FX_FLOAT fLeft = m_rtCaption.left; - FX_FLOAT fTop = m_rtCaption.top; - if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_HLayoutMask) == - FWL_STYLEEXT_CKB_Center) { - fLeft = m_rtCaption.left + (m_rtCaption.width - fWidth) / 2; - } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_HLayoutMask) == - FWL_STYLEEXT_CKB_Right) { - fLeft = m_rtCaption.right() - fWidth; - } - if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_VLayoutMask) == - FWL_STYLEEXT_CKB_VCenter) { - fTop = m_rtCaption.top + (m_rtCaption.height - fHeight) / 2; - } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_VLayoutMask) == - FWL_STYLEEXT_CKB_Bottom) { - fTop = m_rtCaption.bottom() - fHeight; - } - m_rtFocus.Set(fLeft, fTop, fWidth, fHeight); - } else { - m_rtFocus.Set(rtFocus.left, rtFocus.top, rtFocus.width, rtFocus.height); - } - m_rtFocus.Inflate(1, 1); -} - -uint32_t IFWL_CheckBox::GetPartStates() const { - int32_t dwStates = CFWL_PartState_Normal; - if ((m_pProperties->m_dwStates & FWL_STATE_CKB_CheckMask) == - FWL_STATE_CKB_Neutral) { - dwStates = CFWL_PartState_Neutral; - } else if ((m_pProperties->m_dwStates & FWL_STATE_CKB_CheckMask) == - FWL_STATE_CKB_Checked) { - dwStates = CFWL_PartState_Checked; - } - if (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) - dwStates |= CFWL_PartState_Disabled; - else if (m_pProperties->m_dwStates & FWL_STATE_CKB_Hovered) - dwStates |= CFWL_PartState_Hovered; - else if (m_pProperties->m_dwStates & FWL_STATE_CKB_Pressed) - dwStates |= CFWL_PartState_Pressed; - else - dwStates |= CFWL_PartState_Normal; - if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) - dwStates |= CFWL_PartState_Focused; - return dwStates; -} - -void IFWL_CheckBox::UpdateTextOutStyles() { - switch (m_pProperties->m_dwStyleExes & - (FWL_STYLEEXT_CKB_HLayoutMask | FWL_STYLEEXT_CKB_VLayoutMask)) { - case FWL_STYLEEXT_CKB_Left | FWL_STYLEEXT_CKB_Top: { - m_iTTOAlign = FDE_TTOALIGNMENT_TopLeft; - break; - } - case FWL_STYLEEXT_CKB_Center | FWL_STYLEEXT_CKB_Top: { - m_iTTOAlign = FDE_TTOALIGNMENT_TopCenter; - break; - } - case FWL_STYLEEXT_CKB_Right | FWL_STYLEEXT_CKB_Top: { - m_iTTOAlign = FDE_TTOALIGNMENT_TopRight; - break; - } - case FWL_STYLEEXT_CKB_Left | FWL_STYLEEXT_CKB_VCenter: { - m_iTTOAlign = FDE_TTOALIGNMENT_CenterLeft; - break; - } - case FWL_STYLEEXT_CKB_Right | FWL_STYLEEXT_CKB_VCenter: { - m_iTTOAlign = FDE_TTOALIGNMENT_CenterRight; - break; - } - case FWL_STYLEEXT_CKB_Left | FWL_STYLEEXT_CKB_Bottom: { - m_iTTOAlign = FDE_TTOALIGNMENT_BottomLeft; - break; - } - case FWL_STYLEEXT_CKB_Center | FWL_STYLEEXT_CKB_Bottom: { - m_iTTOAlign = FDE_TTOALIGNMENT_BottomCenter; - break; - } - case FWL_STYLEEXT_CKB_Right | FWL_STYLEEXT_CKB_Bottom: { - m_iTTOAlign = FDE_TTOALIGNMENT_BottomRight; - break; - } - case FWL_STYLEEXT_CKB_Center | FWL_STYLEEXT_CKB_VCenter: - default: { - m_iTTOAlign = FDE_TTOALIGNMENT_Center; - break; - } - } - m_dwTTOStyles = 0; - if (m_pProperties->m_dwStyleExes & FWL_WGTSTYLE_RTLReading) - m_dwTTOStyles |= FDE_TTOSTYLE_RTL; - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_MultiLine) - m_dwTTOStyles |= FDE_TTOSTYLE_LineWrap; - else - m_dwTTOStyles |= FDE_TTOSTYLE_SingleLine; -} - -void IFWL_CheckBox::NextStates() { - uint32_t dwFirststate = m_pProperties->m_dwStates; - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_RadioButton) { - if ((m_pProperties->m_dwStates & FWL_STATE_CKB_CheckMask) == - FWL_STATE_CKB_Unchecked) { - CFWL_WidgetMgr* pWidgetMgr = GetOwnerApp()->GetWidgetMgr(); - if (!pWidgetMgr->IsFormDisabled()) { - CFX_ArrayTemplate<IFWL_Widget*> radioarr; - pWidgetMgr->GetSameGroupRadioButton(this, radioarr); - IFWL_CheckBox* pCheckBox = nullptr; - int32_t iCount = radioarr.GetSize(); - for (int32_t i = 0; i < iCount; i++) { - pCheckBox = static_cast<IFWL_CheckBox*>(radioarr[i]); - if (pCheckBox != this && - pCheckBox->GetStates() & FWL_STATE_CKB_Checked) { - pCheckBox->SetCheckState(0); - CFX_RectF rt; - pCheckBox->GetWidgetRect(rt); - rt.left = rt.top = 0; - m_pWidgetMgr->RepaintWidget(pCheckBox, &rt); - break; - } - } - } - m_pProperties->m_dwStates |= FWL_STATE_CKB_Checked; - } - } else { - if ((m_pProperties->m_dwStates & FWL_STATE_CKB_CheckMask) == - FWL_STATE_CKB_Neutral) { - m_pProperties->m_dwStates &= ~FWL_STATE_CKB_CheckMask; - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_3State) - m_pProperties->m_dwStates |= FWL_STATE_CKB_Checked; - } else if ((m_pProperties->m_dwStates & FWL_STATE_CKB_CheckMask) == - FWL_STATE_CKB_Checked) { - m_pProperties->m_dwStates &= ~FWL_STATE_CKB_CheckMask; - } else { - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_3State) - m_pProperties->m_dwStates |= FWL_STATE_CKB_Neutral; - else - m_pProperties->m_dwStates |= FWL_STATE_CKB_Checked; - } - } - - Repaint(&m_rtClient); - if (dwFirststate == m_pProperties->m_dwStates) - return; - - CFWL_EvtCheckStateChanged wmCheckBoxState; - wmCheckBoxState.m_pSrcTarget = this; - DispatchEvent(&wmCheckBoxState); -} - -void IFWL_CheckBox::OnProcessMessage(CFWL_Message* pMessage) { - if (!pMessage) - return; - - switch (pMessage->GetClassID()) { - case CFWL_MessageType::SetFocus: - OnFocusChanged(true); - break; - case CFWL_MessageType::KillFocus: - OnFocusChanged(false); - break; - case CFWL_MessageType::Mouse: { - CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage); - switch (pMsg->m_dwCmd) { - case FWL_MouseCommand::LeftButtonDown: - OnLButtonDown(); - break; - case FWL_MouseCommand::LeftButtonUp: - OnLButtonUp(pMsg); - break; - case FWL_MouseCommand::Move: - OnMouseMove(pMsg); - break; - case FWL_MouseCommand::Leave: - OnMouseLeave(); - break; - default: - break; - } - break; - } - case CFWL_MessageType::Key: { - CFWL_MsgKey* pKey = static_cast<CFWL_MsgKey*>(pMessage); - if (pKey->m_dwCmd == FWL_KeyCommand::KeyDown) - OnKeyDown(pKey); - break; - } - default: - break; - } - - IFWL_Widget::OnProcessMessage(pMessage); -} - -void IFWL_CheckBox::OnDrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix) { - DrawWidget(pGraphics, pMatrix); -} - -void IFWL_CheckBox::OnFocusChanged(bool bSet) { - if (bSet) - m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused; - else - m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused; - - Repaint(&m_rtClient); -} - -void IFWL_CheckBox::OnLButtonDown() { - if (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) - return; - if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) - SetFocus(true); - - m_bBtnDown = true; - m_pProperties->m_dwStates &= ~FWL_STATE_CKB_Hovered; - m_pProperties->m_dwStates |= FWL_STATE_CKB_Pressed; - Repaint(&m_rtClient); -} - -void IFWL_CheckBox::OnLButtonUp(CFWL_MsgMouse* pMsg) { - if (!m_bBtnDown) - return; - - m_bBtnDown = false; - if (!m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) - return; - - m_pProperties->m_dwStates |= FWL_STATE_CKB_Hovered; - m_pProperties->m_dwStates &= ~FWL_STATE_CKB_Pressed; - NextStates(); -} - -void IFWL_CheckBox::OnMouseMove(CFWL_MsgMouse* pMsg) { - if (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) - return; - - bool bRepaint = false; - if (m_bBtnDown) { - if (m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) { - if ((m_pProperties->m_dwStates & FWL_STATE_CKB_Pressed) == 0) { - bRepaint = true; - m_pProperties->m_dwStates |= FWL_STATE_CKB_Pressed; - } - if ((m_pProperties->m_dwStates & FWL_STATE_CKB_Hovered)) { - bRepaint = true; - m_pProperties->m_dwStates &= ~FWL_STATE_CKB_Hovered; - } - } else { - if (m_pProperties->m_dwStates & FWL_STATE_CKB_Pressed) { - bRepaint = true; - m_pProperties->m_dwStates &= ~FWL_STATE_CKB_Pressed; - } - if ((m_pProperties->m_dwStates & FWL_STATE_CKB_Hovered) == 0) { - bRepaint = true; - m_pProperties->m_dwStates |= FWL_STATE_CKB_Hovered; - } - } - } else { - if (m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) { - if ((m_pProperties->m_dwStates & FWL_STATE_CKB_Hovered) == 0) { - bRepaint = true; - m_pProperties->m_dwStates |= FWL_STATE_CKB_Hovered; - } - } - } - if (bRepaint) - Repaint(&m_rtBox); -} - -void IFWL_CheckBox::OnMouseLeave() { - if (m_bBtnDown) - m_pProperties->m_dwStates |= FWL_STATE_CKB_Hovered; - else - m_pProperties->m_dwStates &= ~FWL_STATE_CKB_Hovered; - - Repaint(&m_rtBox); -} - -void IFWL_CheckBox::OnKeyDown(CFWL_MsgKey* pMsg) { - if (pMsg->m_dwKeyCode == FWL_VKEY_Tab) { - DispatchKeyEvent(pMsg); - return; - } - if (pMsg->m_dwKeyCode == FWL_VKEY_Return || - pMsg->m_dwKeyCode == FWL_VKEY_Space) { - NextStates(); - } -} diff --git a/xfa/fwl/core/ifwl_checkbox.h b/xfa/fwl/core/ifwl_checkbox.h deleted file mode 100644 index 3a5b83cb5b..0000000000 --- a/xfa/fwl/core/ifwl_checkbox.h +++ /dev/null @@ -1,100 +0,0 @@ -// 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 - -#ifndef XFA_FWL_CORE_IFWL_CHECKBOX_H_ -#define XFA_FWL_CORE_IFWL_CHECKBOX_H_ - -#include <memory> - -#include "xfa/fwl/core/cfwl_event.h" -#include "xfa/fwl/core/cfwl_widgetproperties.h" -#include "xfa/fwl/core/ifwl_widget.h" - -#define FWL_STYLEEXT_CKB_Left (0L << 0) -#define FWL_STYLEEXT_CKB_Center (1L << 0) -#define FWL_STYLEEXT_CKB_Right (2L << 0) -#define FWL_STYLEEXT_CKB_Top (0L << 2) -#define FWL_STYLEEXT_CKB_VCenter (1L << 2) -#define FWL_STYLEEXT_CKB_Bottom (2L << 2) -#define FWL_STYLEEXT_CKB_LeftText (1L << 4) -#define FWL_STYLEEXT_CKB_MultiLine (1L << 5) -#define FWL_STYLEEXT_CKB_3State (1L << 6) -#define FWL_STYLEEXT_CKB_RadioButton (1L << 7) -#define FWL_STYLEEXT_CKB_ShapeSolidSquare (0L << 8) -#define FWL_STYLEEXT_CKB_ShapeSunkenSquare (1L << 8) -#define FWL_STYLEEXT_CKB_ShapeSolidCircle (2L << 8) -#define FWL_STYLEEXT_CKB_ShapeSunkenCircle (3L << 8) -#define FWL_STYLEEXT_CKB_SignShapeCheck (0L << 10) -#define FWL_STYLEEXT_CKB_SignShapeCircle (1L << 10) -#define FWL_STYLEEXT_CKB_SignShapeCross (2L << 10) -#define FWL_STYLEEXT_CKB_SignShapeDiamond (3L << 10) -#define FWL_STYLEEXT_CKB_SignShapeSquare (4L << 10) -#define FWL_STYLEEXT_CKB_SignShapeStar (5L << 10) -#define FWL_STYLEEXT_CKB_HLayoutMask (3L << 0) -#define FWL_STYLEEXT_CKB_VLayoutMask (3L << 2) -#define FWL_STYLEEXT_CKB_ShapeMask (3L << 8) -#define FWL_STYLEEXT_CKB_SignShapeMask (7L << 10) -#define FWL_STATE_CKB_Hovered (1 << FWL_WGTSTATE_MAX) -#define FWL_STATE_CKB_Pressed (1 << (FWL_WGTSTATE_MAX + 1)) -#define FWL_STATE_CKB_Unchecked (0 << (FWL_WGTSTATE_MAX + 2)) -#define FWL_STATE_CKB_Checked (1 << (FWL_WGTSTATE_MAX + 2)) -#define FWL_STATE_CKB_Neutral (2 << (FWL_WGTSTATE_MAX + 2)) -#define FWL_STATE_CKB_CheckMask (3L << (FWL_WGTSTATE_MAX + 2)) - -class CFWL_MsgMouse; -class CFWL_WidgetProperties; -class IFWL_Widget; - -class IFWL_CheckBox : public IFWL_Widget { - public: - class DataProvider { - public: - virtual FX_FLOAT GetBoxSize(IFWL_Widget* pWidget) = 0; - }; - - IFWL_CheckBox(const CFWL_App* app, - std::unique_ptr<CFWL_WidgetProperties> properties); - ~IFWL_CheckBox() override; - - // IFWL_Widget - FWL_Type GetClassID() const override; - void GetWidgetRect(CFX_RectF& rect, bool bAutoSize = false) override; - void Update() override; - void DrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix = nullptr) override; - - void OnProcessMessage(CFWL_Message* pMessage) override; - void OnDrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix) override; - - void SetDataProvider(IFWL_CheckBox::DataProvider* pProvider) { - m_pDataProvider = pProvider; - } - - private: - void SetCheckState(int32_t iCheck); - void Layout(); - uint32_t GetPartStates() const; - void UpdateTextOutStyles(); - void NextStates(); - void OnFocusChanged(bool bSet); - void OnLButtonDown(); - void OnLButtonUp(CFWL_MsgMouse* pMsg); - void OnMouseMove(CFWL_MsgMouse* pMsg); - void OnMouseLeave(); - void OnKeyDown(CFWL_MsgKey* pMsg); - - IFWL_CheckBox::DataProvider* m_pDataProvider; // Not owned. - CFX_RectF m_rtClient; - CFX_RectF m_rtBox; - CFX_RectF m_rtCaption; - CFX_RectF m_rtFocus; - uint32_t m_dwTTOStyles; - int32_t m_iTTOAlign; - bool m_bBtnDown; -}; - -#endif // XFA_FWL_CORE_IFWL_CHECKBOX_H_ diff --git a/xfa/fwl/core/ifwl_combobox.cpp b/xfa/fwl/core/ifwl_combobox.cpp deleted file mode 100644 index 07fa64c43a..0000000000 --- a/xfa/fwl/core/ifwl_combobox.cpp +++ /dev/null @@ -1,1130 +0,0 @@ -// 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_combobox.h" - -#include <algorithm> -#include <memory> -#include <utility> - -#include "third_party/base/ptr_util.h" -#include "xfa/fde/cfde_txtedtengine.h" -#include "xfa/fde/tto/fde_textout.h" -#include "xfa/fwl/core/cfwl_app.h" -#include "xfa/fwl/core/cfwl_evteditchanged.h" -#include "xfa/fwl/core/cfwl_evtpostdropdown.h" -#include "xfa/fwl/core/cfwl_evtpredropdown.h" -#include "xfa/fwl/core/cfwl_evtselectchanged.h" -#include "xfa/fwl/core/cfwl_evttextchanged.h" -#include "xfa/fwl/core/cfwl_formproxy.h" -#include "xfa/fwl/core/cfwl_msgkey.h" -#include "xfa/fwl/core/cfwl_msgkillfocus.h" -#include "xfa/fwl/core/cfwl_msgmouse.h" -#include "xfa/fwl/core/cfwl_msgsetfocus.h" -#include "xfa/fwl/core/cfwl_notedriver.h" -#include "xfa/fwl/core/cfwl_themebackground.h" -#include "xfa/fwl/core/cfwl_themepart.h" -#include "xfa/fwl/core/cfwl_themetext.h" -#include "xfa/fwl/core/cfwl_widgetmgr.h" -#include "xfa/fwl/core/ifwl_listbox.h" -#include "xfa/fwl/core/ifwl_themeprovider.h" - -IFWL_ComboBox::IFWL_ComboBox(const CFWL_App* app, - std::unique_ptr<CFWL_WidgetProperties> properties) - : IFWL_Widget(app, std::move(properties), nullptr), - m_pComboBoxProxy(nullptr), - m_bLButtonDown(false), - m_iCurSel(-1), - m_iBtnState(CFWL_PartState_Normal), - m_fComboFormHandler(0) { - m_rtClient.Reset(); - m_rtBtn.Reset(); - m_rtHandler.Reset(); - - if (m_pWidgetMgr->IsFormDisabled()) { - DisForm_InitComboList(); - DisForm_InitComboEdit(); - return; - } - - auto prop = pdfium::MakeUnique<CFWL_WidgetProperties>(); - prop->m_pThemeProvider = m_pProperties->m_pThemeProvider; - prop->m_dwStyles |= FWL_WGTSTYLE_Border | FWL_WGTSTYLE_VScroll; - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_ListItemIconText) - prop->m_dwStyleExes |= FWL_STYLEEXT_LTB_Icon; - m_pListBox = - pdfium::MakeUnique<CFWL_ComboList>(m_pOwnerApp, std::move(prop), this); - - if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_DropDown) && !m_pEdit) { - m_pEdit.reset(new CFWL_ComboEdit( - m_pOwnerApp, pdfium::MakeUnique<CFWL_WidgetProperties>(), this)); - m_pEdit->SetOuter(this); - } - if (m_pEdit) - m_pEdit->SetParent(this); - - SetStates(m_pProperties->m_dwStates); -} - -IFWL_ComboBox::~IFWL_ComboBox() {} - -FWL_Type IFWL_ComboBox::GetClassID() const { - return FWL_Type::ComboBox; -} - -void IFWL_ComboBox::GetWidgetRect(CFX_RectF& rect, bool bAutoSize) { - if (!bAutoSize) { - rect = m_pProperties->m_rtWidget; - return; - } - - rect.Reset(); - if (IsDropDownStyle() && m_pEdit) { - m_pEdit->GetWidgetRect(rect, true); - } else { - rect.width = 100; - rect.height = 16; - } - if (!m_pProperties->m_pThemeProvider) - ResetTheme(); - - FX_FLOAT* pFWidth = static_cast<FX_FLOAT*>( - GetThemeCapacity(CFWL_WidgetCapacity::ScrollBarWidth)); - if (!pFWidth) - return; - - rect.Inflate(0, 0, *pFWidth, 0); - IFWL_Widget::GetWidgetRect(rect, true); -} - -void IFWL_ComboBox::AddString(const CFX_WideStringC& wsText) { - m_pListBox->AddString(wsText); -} - -bool IFWL_ComboBox::RemoveAt(int32_t iIndex) { - return m_pListBox->RemoveAt(iIndex); -} - -void IFWL_ComboBox::RemoveAll() { - m_pListBox->DeleteAll(); -} - -void IFWL_ComboBox::ModifyStylesEx(uint32_t dwStylesExAdded, - uint32_t dwStylesExRemoved) { - if (m_pWidgetMgr->IsFormDisabled()) { - DisForm_ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved); - return; - } - - bool bAddDropDown = !!(dwStylesExAdded & FWL_STYLEEXT_CMB_DropDown); - bool bRemoveDropDown = !!(dwStylesExRemoved & FWL_STYLEEXT_CMB_DropDown); - if (bAddDropDown && !m_pEdit) { - m_pEdit = pdfium::MakeUnique<CFWL_ComboEdit>( - m_pOwnerApp, pdfium::MakeUnique<CFWL_WidgetProperties>(), nullptr); - m_pEdit->SetOuter(this); - m_pEdit->SetParent(this); - } else if (bRemoveDropDown && m_pEdit) { - m_pEdit->SetStates(FWL_WGTSTATE_Invisible, true); - } - IFWL_Widget::ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved); -} - -void IFWL_ComboBox::Update() { - if (m_pWidgetMgr->IsFormDisabled()) { - DisForm_Update(); - return; - } - if (IsLocked()) - return; - - ResetTheme(); - if (IsDropDownStyle() && m_pEdit) - ResetEditAlignment(); - if (!m_pProperties->m_pThemeProvider) - m_pProperties->m_pThemeProvider = GetAvailableTheme(); - - Layout(); - CFWL_ThemePart part; - part.m_pWidget = this; - m_fComboFormHandler = - *static_cast<FX_FLOAT*>(m_pProperties->m_pThemeProvider->GetCapacity( - &part, CFWL_WidgetCapacity::ComboFormHandler)); -} - -FWL_WidgetHit IFWL_ComboBox::HitTest(FX_FLOAT fx, FX_FLOAT fy) { - if (m_pWidgetMgr->IsFormDisabled()) - return DisForm_HitTest(fx, fy); - return IFWL_Widget::HitTest(fx, fy); -} - -void IFWL_ComboBox::DrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix) { - if (m_pWidgetMgr->IsFormDisabled()) { - DisForm_DrawWidget(pGraphics, pMatrix); - return; - } - - if (!pGraphics) - return; - if (!m_pProperties->m_pThemeProvider) - return; - - 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 (!IsDropDownStyle()) { - CFX_RectF rtTextBk(m_rtClient); - rtTextBk.width -= m_rtBtn.width; - - CFWL_ThemeBackground param; - param.m_pWidget = this; - param.m_iPart = CFWL_Part::Background; - param.m_pGraphics = pGraphics; - if (pMatrix) - param.m_matrix.Concat(*pMatrix); - param.m_rtPart = rtTextBk; - - if (m_iCurSel >= 0) { - if (void* p = m_pListBox->GetItemData( - m_pListBox.get(), - m_pListBox->GetItem(m_pListBox.get(), m_iCurSel))) { - param.m_pData = p; - } - } - - if (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) { - param.m_dwStates = CFWL_PartState_Disabled; - } else if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) && - (m_iCurSel >= 0)) { - param.m_dwStates = CFWL_PartState_Selected; - } else { - param.m_dwStates = CFWL_PartState_Normal; - } - pTheme->DrawBackground(¶m); - - if (m_iCurSel >= 0) { - if (!m_pListBox) - return; - - CFX_WideString wsText; - CFWL_ListItem* hItem = m_pListBox->GetItem(this, m_iCurSel); - m_pListBox->GetDataProviderItemText(hItem, wsText); - - CFWL_ThemeText theme_text; - theme_text.m_pWidget = this; - theme_text.m_iPart = CFWL_Part::Caption; - theme_text.m_dwStates = m_iBtnState; - theme_text.m_pGraphics = pGraphics; - theme_text.m_matrix.Concat(*pMatrix); - theme_text.m_rtPart = rtTextBk; - theme_text.m_dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) - ? CFWL_PartState_Selected - : CFWL_PartState_Normal; - theme_text.m_wsText = wsText; - theme_text.m_dwTTOStyles = FDE_TTOSTYLE_SingleLine; - theme_text.m_iTTOAlign = FDE_TTOALIGNMENT_CenterLeft; - pTheme->DrawText(&theme_text); - } - } - - CFWL_ThemeBackground param; - param.m_pWidget = this; - param.m_iPart = CFWL_Part::DropDownButton; - param.m_dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) - ? CFWL_PartState_Disabled - : m_iBtnState; - param.m_pGraphics = pGraphics; - param.m_matrix.Concat(*pMatrix); - param.m_rtPart = m_rtBtn; - pTheme->DrawBackground(¶m); -} - -void IFWL_ComboBox::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) { - if (!pThemeProvider) - return; - - m_pProperties->m_pThemeProvider = pThemeProvider; - if (m_pListBox) - m_pListBox->SetThemeProvider(pThemeProvider); - if (m_pEdit) - m_pEdit->SetThemeProvider(pThemeProvider); -} - -void IFWL_ComboBox::GetTextByIndex(int32_t iIndex, - CFX_WideString& wsText) const { - CFWL_ListItem* pItem = static_cast<CFWL_ListItem*>( - m_pListBox->GetItem(m_pListBox.get(), iIndex)); - if (pItem) - wsText = pItem->m_wsText; -} - -void IFWL_ComboBox::SetCurSel(int32_t iSel) { - int32_t iCount = m_pListBox->CountItems(nullptr); - bool bClearSel = iSel < 0 || iSel >= iCount; - if (IsDropDownStyle() && m_pEdit) { - if (bClearSel) { - m_pEdit->SetText(CFX_WideString()); - } else { - CFX_WideString wsText; - CFWL_ListItem* hItem = m_pListBox->GetItem(this, iSel); - m_pListBox->GetDataProviderItemText(hItem, wsText); - m_pEdit->SetText(wsText); - } - m_pEdit->Update(); - } - m_iCurSel = bClearSel ? -1 : iSel; -} - -void IFWL_ComboBox::SetStates(uint32_t dwStates, bool bSet) { - if (IsDropDownStyle() && m_pEdit) - m_pEdit->SetStates(dwStates, bSet); - if (m_pListBox) - m_pListBox->SetStates(dwStates, bSet); - IFWL_Widget::SetStates(dwStates, bSet); -} - -void IFWL_ComboBox::SetEditText(const CFX_WideString& wsText) { - if (!m_pEdit) - return; - - m_pEdit->SetText(wsText); - m_pEdit->Update(); -} - -void IFWL_ComboBox::GetEditText(CFX_WideString& wsText, - int32_t nStart, - int32_t nCount) const { - if (m_pEdit) { - m_pEdit->GetText(wsText, nStart, nCount); - return; - } - if (!m_pListBox) - return; - - CFWL_ListItem* hItem = m_pListBox->GetItem(this, m_iCurSel); - m_pListBox->GetDataProviderItemText(hItem, wsText); -} - -void IFWL_ComboBox::OpenDropDownList(bool bActivate) { - ShowDropList(bActivate); -} - -void IFWL_ComboBox::GetBBox(CFX_RectF& rect) const { - if (m_pWidgetMgr->IsFormDisabled()) { - DisForm_GetBBox(rect); - return; - } - - rect = m_pProperties->m_rtWidget; - if (!m_pListBox || !IsDropListVisible()) - return; - - CFX_RectF rtList; - m_pListBox->GetWidgetRect(rtList); - rtList.Offset(rect.left, rect.top); - rect.Union(rtList); -} - -void IFWL_ComboBox::EditModifyStylesEx(uint32_t dwStylesExAdded, - uint32_t dwStylesExRemoved) { - if (m_pEdit) - m_pEdit->ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved); -} - -void IFWL_ComboBox::DrawStretchHandler(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix) { - CFWL_ThemeBackground param; - param.m_pGraphics = pGraphics; - param.m_iPart = CFWL_Part::StretchHandler; - param.m_dwStates = CFWL_PartState_Normal; - param.m_pWidget = this; - if (pMatrix) - param.m_matrix.Concat(*pMatrix); - param.m_rtPart = m_rtHandler; - m_pProperties->m_pThemeProvider->DrawBackground(¶m); -} - -void IFWL_ComboBox::ShowDropList(bool bActivate) { - if (m_pWidgetMgr->IsFormDisabled()) - return DisForm_ShowDropList(bActivate); - if (IsDropListVisible() == bActivate) - return; - if (!m_pComboBoxProxy) - InitProxyForm(); - - m_pComboBoxProxy->Reset(); - if (!bActivate) { - m_pComboBoxProxy->EndDoModal(); - - m_bLButtonDown = false; - m_pListBox->SetNotifyOwner(true); - SetFocus(true); - return; - } - - m_pListBox->ChangeSelected(m_iCurSel); - ResetListItemAlignment(); - - uint32_t dwStyleAdd = m_pProperties->m_dwStyleExes & - (FWL_STYLEEXT_CMB_Sort | FWL_STYLEEXT_CMB_OwnerDraw); - m_pListBox->ModifyStylesEx(dwStyleAdd, 0); - m_pListBox->GetWidgetRect(m_rtList, true); - - CFX_RectF rtAnchor; - rtAnchor.Set(0, 0, m_pProperties->m_rtWidget.width, - m_pProperties->m_rtWidget.height); - - m_rtList.width = std::max(m_rtList.width, m_rtClient.width); - m_rtProxy = m_rtList; - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_ListDrag) - m_rtProxy.height += m_fComboFormHandler; - - GetPopupPos(0, m_rtProxy.height, rtAnchor, m_rtProxy); - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_ListDrag) { - FX_FLOAT fx = 0; - FX_FLOAT fy = m_rtClient.top + m_rtClient.height / 2; - TransformTo(nullptr, fx, fy); - - m_bUpFormHandler = fy > m_rtProxy.top; - if (m_bUpFormHandler) { - m_rtHandler.Set(0, 0, m_rtList.width, m_fComboFormHandler); - m_rtList.top = m_fComboFormHandler; - } else { - m_rtHandler.Set(0, m_rtList.height, m_rtList.width, m_fComboFormHandler); - } - } - m_pComboBoxProxy->SetWidgetRect(m_rtProxy); - m_pComboBoxProxy->Update(); - m_pListBox->SetWidgetRect(m_rtList); - m_pListBox->Update(); - - CFWL_EvtPreDropDown ev; - ev.m_pSrcTarget = this; - DispatchEvent(&ev); - - m_fItemHeight = m_pListBox->GetItemHeight(); - m_pListBox->SetFocus(true); - m_pComboBoxProxy->DoModal(); - m_pListBox->SetFocus(false); -} - -void IFWL_ComboBox::MatchEditText() { - CFX_WideString wsText; - m_pEdit->GetText(wsText); - int32_t iMatch = m_pListBox->MatchItem(wsText); - if (iMatch != m_iCurSel) { - m_pListBox->ChangeSelected(iMatch); - if (iMatch >= 0) - SyncEditText(iMatch); - } else if (iMatch >= 0) { - m_pEdit->SetSelected(); - } - m_iCurSel = iMatch; -} - -void IFWL_ComboBox::SyncEditText(int32_t iListItem) { - CFX_WideString wsText; - CFWL_ListItem* hItem = m_pListBox->GetItem(this, iListItem); - m_pListBox->GetDataProviderItemText(hItem, wsText); - m_pEdit->SetText(wsText); - m_pEdit->Update(); - m_pEdit->SetSelected(); -} - -void IFWL_ComboBox::Layout() { - if (m_pWidgetMgr->IsFormDisabled()) - return DisForm_Layout(); - - GetClientRect(m_rtClient); - FX_FLOAT* pFWidth = static_cast<FX_FLOAT*>( - GetThemeCapacity(CFWL_WidgetCapacity::ScrollBarWidth)); - if (!pFWidth) - return; - - FX_FLOAT fBtn = *pFWidth; - m_rtBtn.Set(m_rtClient.right() - fBtn, m_rtClient.top, fBtn, - m_rtClient.height); - if (!IsDropDownStyle() || !m_pEdit) - return; - - CFX_RectF rtEdit; - rtEdit.Set(m_rtClient.left, m_rtClient.top, m_rtClient.width - fBtn, - m_rtClient.height); - m_pEdit->SetWidgetRect(rtEdit); - - if (m_iCurSel >= 0) { - CFX_WideString wsText; - CFWL_ListItem* hItem = m_pListBox->GetItem(this, m_iCurSel); - m_pListBox->GetDataProviderItemText(hItem, wsText); - m_pEdit->LockUpdate(); - m_pEdit->SetText(wsText); - m_pEdit->UnlockUpdate(); - } - m_pEdit->Update(); -} - -void IFWL_ComboBox::ResetTheme() { - IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider; - if (!pTheme) { - pTheme = GetAvailableTheme(); - m_pProperties->m_pThemeProvider = pTheme; - } - if (m_pListBox && !m_pListBox->GetThemeProvider()) - m_pListBox->SetThemeProvider(pTheme); - if (m_pEdit && !m_pEdit->GetThemeProvider()) - m_pEdit->SetThemeProvider(pTheme); -} - -void IFWL_ComboBox::ResetEditAlignment() { - if (!m_pEdit) - return; - - uint32_t dwAdd = 0; - switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_EditHAlignMask) { - case FWL_STYLEEXT_CMB_EditHCenter: { - dwAdd |= FWL_STYLEEXT_EDT_HCenter; - break; - } - case FWL_STYLEEXT_CMB_EditHFar: { - dwAdd |= FWL_STYLEEXT_EDT_HFar; - break; - } - default: { dwAdd |= FWL_STYLEEXT_EDT_HNear; } - } - switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_EditVAlignMask) { - case FWL_STYLEEXT_CMB_EditVCenter: { - dwAdd |= FWL_STYLEEXT_EDT_VCenter; - break; - } - case FWL_STYLEEXT_CMB_EditVFar: { - dwAdd |= FWL_STYLEEXT_EDT_VFar; - break; - } - default: { - dwAdd |= FWL_STYLEEXT_EDT_VNear; - break; - } - } - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_EditJustified) - dwAdd |= FWL_STYLEEXT_EDT_Justified; - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_EditDistributed) - dwAdd |= FWL_STYLEEXT_EDT_Distributed; - - m_pEdit->ModifyStylesEx(dwAdd, FWL_STYLEEXT_EDT_HAlignMask | - FWL_STYLEEXT_EDT_HAlignModeMask | - FWL_STYLEEXT_EDT_VAlignMask); -} - -void IFWL_ComboBox::ResetListItemAlignment() { - if (!m_pListBox) - return; - - uint32_t dwAdd = 0; - switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_ListItemAlignMask) { - case FWL_STYLEEXT_CMB_ListItemCenterAlign: { - dwAdd |= FWL_STYLEEXT_LTB_CenterAlign; - break; - } - case FWL_STYLEEXT_CMB_ListItemRightAlign: { - dwAdd |= FWL_STYLEEXT_LTB_RightAlign; - break; - } - default: { - dwAdd |= FWL_STYLEEXT_LTB_LeftAlign; - break; - } - } - m_pListBox->ModifyStylesEx(dwAdd, FWL_STYLEEXT_CMB_ListItemAlignMask); -} - -void IFWL_ComboBox::ProcessSelChanged(bool bLButtonUp) { - m_iCurSel = m_pListBox->GetItemIndex(this, m_pListBox->GetSelItem(0)); - if (!IsDropDownStyle()) { - Repaint(&m_rtClient); - return; - } - - CFWL_ListItem* hItem = m_pListBox->GetItem(this, m_iCurSel); - if (!hItem) - return; - - CFX_WideString wsText; - m_pListBox->GetItemText(this, hItem, wsText); - if (m_pEdit) { - m_pEdit->SetText(wsText); - m_pEdit->Update(); - m_pEdit->SetSelected(); - } - - CFWL_EvtSelectChanged ev; - ev.bLButtonUp = bLButtonUp; - ev.m_pSrcTarget = this; - DispatchEvent(&ev); -} - -void IFWL_ComboBox::InitProxyForm() { - if (m_pComboBoxProxy) - return; - if (!m_pListBox) - return; - - auto prop = pdfium::MakeUnique<CFWL_WidgetProperties>(); - prop->m_pOwner = this; - prop->m_dwStyles = FWL_WGTSTYLE_Popup; - prop->m_dwStates = FWL_WGTSTATE_Invisible; - - // TODO(dsinclair): Does this leak? I don't see a delete, but I'm not sure - // if the SetParent call is going to transfer ownership. - m_pComboBoxProxy = new CFWL_ComboBoxProxy(this, m_pOwnerApp, std::move(prop), - m_pListBox.get()); - m_pListBox->SetParent(m_pComboBoxProxy); -} - -void IFWL_ComboBox::DisForm_InitComboList() { - if (m_pListBox) - return; - - auto prop = pdfium::MakeUnique<CFWL_WidgetProperties>(); - prop->m_pParent = this; - prop->m_dwStyles = FWL_WGTSTYLE_Border | FWL_WGTSTYLE_VScroll; - prop->m_dwStates = FWL_WGTSTATE_Invisible; - prop->m_pThemeProvider = m_pProperties->m_pThemeProvider; - m_pListBox = - pdfium::MakeUnique<CFWL_ComboList>(m_pOwnerApp, std::move(prop), this); -} - -void IFWL_ComboBox::DisForm_InitComboEdit() { - if (m_pEdit) - return; - - auto prop = pdfium::MakeUnique<CFWL_WidgetProperties>(); - prop->m_pParent = this; - prop->m_pThemeProvider = m_pProperties->m_pThemeProvider; - - m_pEdit = - pdfium::MakeUnique<CFWL_ComboEdit>(m_pOwnerApp, std::move(prop), this); - m_pEdit->SetOuter(this); -} - -void IFWL_ComboBox::DisForm_ShowDropList(bool bActivate) { - if (DisForm_IsDropListVisible() == bActivate) - return; - - if (bActivate) { - CFWL_EvtPreDropDown preEvent; - preEvent.m_pSrcTarget = this; - DispatchEvent(&preEvent); - - CFWL_ComboList* pComboList = m_pListBox.get(); - int32_t iItems = pComboList->CountItems(nullptr); - if (iItems < 1) - return; - - ResetListItemAlignment(); - pComboList->ChangeSelected(m_iCurSel); - - FX_FLOAT fItemHeight = pComboList->CalcItemHeight(); - FX_FLOAT fBorder = GetBorderSize(); - FX_FLOAT fPopupMin = 0.0f; - if (iItems > 3) - fPopupMin = fItemHeight * 3 + fBorder * 2; - - FX_FLOAT fPopupMax = fItemHeight * iItems + fBorder * 2; - CFX_RectF rtList; - rtList.left = m_rtClient.left; - rtList.width = m_pProperties->m_rtWidget.width; - rtList.top = 0; - rtList.height = 0; - GetPopupPos(fPopupMin, fPopupMax, m_pProperties->m_rtWidget, rtList); - - m_pListBox->SetWidgetRect(rtList); - m_pListBox->Update(); - } else { - SetFocus(true); - } - - m_pListBox->SetStates(FWL_WGTSTATE_Invisible, !bActivate); - if (bActivate) { - CFWL_EvtPostDropDown postEvent; - postEvent.m_pSrcTarget = this; - DispatchEvent(&postEvent); - } - - CFX_RectF rect; - m_pListBox->GetWidgetRect(rect); - rect.Inflate(2, 2); - Repaint(&rect); -} - -void IFWL_ComboBox::DisForm_ModifyStylesEx(uint32_t dwStylesExAdded, - uint32_t dwStylesExRemoved) { - if (!m_pEdit) - DisForm_InitComboEdit(); - - bool bAddDropDown = !!(dwStylesExAdded & FWL_STYLEEXT_CMB_DropDown); - bool bDelDropDown = !!(dwStylesExRemoved & FWL_STYLEEXT_CMB_DropDown); - - dwStylesExRemoved &= ~FWL_STYLEEXT_CMB_DropDown; - m_pProperties->m_dwStyleExes |= FWL_STYLEEXT_CMB_DropDown; - - if (bAddDropDown) - m_pEdit->ModifyStylesEx(0, FWL_STYLEEXT_EDT_ReadOnly); - else if (bDelDropDown) - m_pEdit->ModifyStylesEx(FWL_STYLEEXT_EDT_ReadOnly, 0); - IFWL_Widget::ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved); -} - -void IFWL_ComboBox::DisForm_Update() { - if (m_iLock) - return; - if (m_pEdit) - ResetEditAlignment(); - ResetTheme(); - Layout(); -} - -FWL_WidgetHit IFWL_ComboBox::DisForm_HitTest(FX_FLOAT fx, FX_FLOAT fy) { - CFX_RectF rect; - rect.Set(0, 0, m_pProperties->m_rtWidget.width - m_rtBtn.width, - m_pProperties->m_rtWidget.height); - if (rect.Contains(fx, fy)) - return FWL_WidgetHit::Edit; - if (m_rtBtn.Contains(fx, fy)) - return FWL_WidgetHit::Client; - if (DisForm_IsDropListVisible()) { - m_pListBox->GetWidgetRect(rect); - if (rect.Contains(fx, fy)) - return FWL_WidgetHit::Client; - } - return FWL_WidgetHit::Unknown; -} - -void IFWL_ComboBox::DisForm_DrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix) { - IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider; - CFX_Matrix mtOrg; - mtOrg.Set(1, 0, 0, 1, 0, 0); - if (pMatrix) - mtOrg = *pMatrix; - - pGraphics->SaveGraphState(); - pGraphics->ConcatMatrix(&mtOrg); - if (!m_rtBtn.IsEmpty(0.1f)) { - 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; - pTheme->DrawBackground(¶m); - } - pGraphics->RestoreGraphState(); - - if (m_pEdit) { - CFX_RectF rtEdit; - m_pEdit->GetWidgetRect(rtEdit); - CFX_Matrix mt; - mt.Set(1, 0, 0, 1, rtEdit.left, rtEdit.top); - mt.Concat(mtOrg); - m_pEdit->DrawWidget(pGraphics, &mt); - } - if (m_pListBox && DisForm_IsDropListVisible()) { - CFX_RectF rtList; - m_pListBox->GetWidgetRect(rtList); - CFX_Matrix mt; - mt.Set(1, 0, 0, 1, rtList.left, rtList.top); - mt.Concat(mtOrg); - m_pListBox->DrawWidget(pGraphics, &mt); - } -} - -void IFWL_ComboBox::DisForm_GetBBox(CFX_RectF& rect) const { - rect = m_pProperties->m_rtWidget; - if (!m_pListBox || !DisForm_IsDropListVisible()) - return; - - CFX_RectF rtList; - m_pListBox->GetWidgetRect(rtList); - rtList.Offset(rect.left, rect.top); - rect.Union(rtList); -} - -void IFWL_ComboBox::DisForm_Layout() { - GetClientRect(m_rtClient); - m_rtContent = m_rtClient; - FX_FLOAT* pFWidth = static_cast<FX_FLOAT*>( - GetThemeCapacity(CFWL_WidgetCapacity::ScrollBarWidth)); - if (!pFWidth) - return; - - FX_FLOAT borderWidth = 1; - FX_FLOAT fBtn = *pFWidth; - if (!(GetStylesEx() & FWL_STYLEEXT_CMB_ReadOnly)) { - m_rtBtn.Set(m_rtClient.right() - fBtn, m_rtClient.top + borderWidth, - fBtn - borderWidth, m_rtClient.height - 2 * borderWidth); - } - - CFX_RectF* pUIMargin = - static_cast<CFX_RectF*>(GetThemeCapacity(CFWL_WidgetCapacity::UIMargin)); - if (pUIMargin) { - m_rtContent.Deflate(pUIMargin->left, pUIMargin->top, pUIMargin->width, - pUIMargin->height); - } - - if (!IsDropDownStyle() || !m_pEdit) - return; - - CFX_RectF rtEdit; - rtEdit.Set(m_rtContent.left, m_rtContent.top, m_rtContent.width - fBtn, - m_rtContent.height); - m_pEdit->SetWidgetRect(rtEdit); - - if (m_iCurSel >= 0) { - CFX_WideString wsText; - CFWL_ListItem* hItem = m_pListBox->GetItem(this, m_iCurSel); - m_pListBox->GetDataProviderItemText(hItem, wsText); - m_pEdit->LockUpdate(); - m_pEdit->SetText(wsText); - m_pEdit->UnlockUpdate(); - } - m_pEdit->Update(); -} - -void IFWL_ComboBox::OnProcessMessage(CFWL_Message* pMessage) { - if (m_pWidgetMgr->IsFormDisabled()) { - DisForm_OnProcessMessage(pMessage); - return; - } - 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* pMsg = static_cast<CFWL_MsgMouse*>(pMessage); - switch (pMsg->m_dwCmd) { - case FWL_MouseCommand::LeftButtonDown: - OnLButtonDown(pMsg); - break; - case FWL_MouseCommand::LeftButtonUp: - OnLButtonUp(pMsg); - break; - case FWL_MouseCommand::Move: - OnMouseMove(pMsg); - break; - case FWL_MouseCommand::Leave: - OnMouseLeave(pMsg); - break; - default: - break; - } - break; - } - case CFWL_MessageType::Key: - OnKey(static_cast<CFWL_MsgKey*>(pMessage)); - break; - default: - break; - } - - IFWL_Widget::OnProcessMessage(pMessage); -} - -void IFWL_ComboBox::OnProcessEvent(CFWL_Event* pEvent) { - CFWL_EventType dwFlag = pEvent->GetClassID(); - if (dwFlag == CFWL_EventType::Scroll) { - CFWL_EvtScroll* pScrollEvent = static_cast<CFWL_EvtScroll*>(pEvent); - CFWL_EvtScroll pScrollEv; - pScrollEv.m_pSrcTarget = this; - pScrollEv.m_iScrollCode = pScrollEvent->m_iScrollCode; - pScrollEv.m_fPos = pScrollEvent->m_fPos; - DispatchEvent(&pScrollEv); - } else if (dwFlag == CFWL_EventType::TextChanged) { - CFWL_EvtEditChanged pTemp; - pTemp.m_pSrcTarget = this; - DispatchEvent(&pTemp); - } -} - -void IFWL_ComboBox::OnDrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix) { - DrawWidget(pGraphics, pMatrix); -} - -void IFWL_ComboBox::OnFocusChanged(CFWL_Message* pMsg, bool bSet) { - if (bSet) { - m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused; - if (IsDropDownStyle() && pMsg->m_pSrcTarget != m_pListBox.get()) { - if (!m_pEdit) - return; - m_pEdit->SetSelected(); - return; - } - - Repaint(&m_rtClient); - return; - } - - m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused; - if (!IsDropDownStyle() || pMsg->m_pDstTarget == m_pListBox.get()) { - Repaint(&m_rtClient); - return; - } - if (!m_pEdit) - return; - - m_pEdit->FlagFocus(false); - m_pEdit->ClearSelected(); -} - -void IFWL_ComboBox::OnLButtonDown(CFWL_MsgMouse* pMsg) { - if (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) - return; - - CFX_RectF& rtBtn = IsDropDownStyle() ? m_rtBtn : m_rtClient; - if (!rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) - return; - - if (IsDropDownStyle() && m_pEdit) - MatchEditText(); - - m_bLButtonDown = true; - m_iBtnState = CFWL_PartState_Pressed; - Repaint(&m_rtClient); - - ShowDropList(true); - m_iBtnState = CFWL_PartState_Normal; - Repaint(&m_rtClient); -} - -void IFWL_ComboBox::OnLButtonUp(CFWL_MsgMouse* pMsg) { - m_bLButtonDown = false; - if (m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) - m_iBtnState = CFWL_PartState_Hovered; - else - m_iBtnState = CFWL_PartState_Normal; - - Repaint(&m_rtBtn); -} - -void IFWL_ComboBox::OnMouseMove(CFWL_MsgMouse* pMsg) { - int32_t iOldState = m_iBtnState; - if (m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) { - m_iBtnState = - m_bLButtonDown ? CFWL_PartState_Pressed : CFWL_PartState_Hovered; - } else { - m_iBtnState = CFWL_PartState_Normal; - } - if ((iOldState != m_iBtnState) && - !((m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) == - FWL_WGTSTATE_Disabled)) { - Repaint(&m_rtBtn); - } -} - -void IFWL_ComboBox::OnMouseLeave(CFWL_MsgMouse* pMsg) { - if (!IsDropListVisible() && - !((m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) == - FWL_WGTSTATE_Disabled)) { - m_iBtnState = CFWL_PartState_Normal; - Repaint(&m_rtBtn); - } -} - -void IFWL_ComboBox::OnKey(CFWL_MsgKey* pMsg) { - uint32_t dwKeyCode = pMsg->m_dwKeyCode; - if (dwKeyCode == FWL_VKEY_Tab) { - DispatchKeyEvent(pMsg); - return; - } - if (pMsg->m_pDstTarget == this) - DoSubCtrlKey(pMsg); -} - -void IFWL_ComboBox::DoSubCtrlKey(CFWL_MsgKey* pMsg) { - uint32_t dwKeyCode = pMsg->m_dwKeyCode; - const bool bUp = dwKeyCode == FWL_VKEY_Up; - const bool bDown = dwKeyCode == FWL_VKEY_Down; - if (bUp || bDown) { - int32_t iCount = m_pListBox->CountItems(nullptr); - if (iCount < 1) - return; - - bool bMatchEqual = false; - int32_t iCurSel = m_iCurSel; - bool bDropDown = IsDropDownStyle(); - if (bDropDown && m_pEdit) { - CFX_WideString wsText; - m_pEdit->GetText(wsText); - iCurSel = m_pListBox->MatchItem(wsText); - if (iCurSel >= 0) { - CFX_WideString wsTemp; - CFWL_ListItem* hItem = m_pListBox->GetItem(this, iCurSel); - m_pListBox->GetDataProviderItemText(hItem, wsTemp); - bMatchEqual = wsText == wsTemp; - } - } - if (iCurSel < 0) { - iCurSel = 0; - } else if (!bDropDown || bMatchEqual) { - if ((bUp && iCurSel == 0) || (bDown && iCurSel == iCount - 1)) - return; - if (bUp) - iCurSel--; - else - iCurSel++; - } - m_iCurSel = iCurSel; - if (bDropDown && m_pEdit) - SyncEditText(m_iCurSel); - else - Repaint(&m_rtClient); - return; - } - - if (IsDropDownStyle()) - m_pEdit->GetDelegate()->OnProcessMessage(pMsg); -} - -void IFWL_ComboBox::DisForm_OnProcessMessage(CFWL_Message* pMessage) { - if (!pMessage) - return; - - bool backDefault = true; - switch (pMessage->GetClassID()) { - case CFWL_MessageType::SetFocus: { - backDefault = false; - DisForm_OnFocusChanged(pMessage, true); - break; - } - case CFWL_MessageType::KillFocus: { - backDefault = false; - DisForm_OnFocusChanged(pMessage, false); - break; - } - case CFWL_MessageType::Mouse: { - backDefault = false; - CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage); - switch (pMsg->m_dwCmd) { - case FWL_MouseCommand::LeftButtonDown: - DisForm_OnLButtonDown(pMsg); - break; - case FWL_MouseCommand::LeftButtonUp: - OnLButtonUp(pMsg); - break; - default: - break; - } - break; - } - case CFWL_MessageType::Key: { - backDefault = false; - CFWL_MsgKey* pKey = static_cast<CFWL_MsgKey*>(pMessage); - if (pKey->m_dwCmd == FWL_KeyCommand::KeyUp) - break; - if (DisForm_IsDropListVisible() && - pKey->m_dwCmd == FWL_KeyCommand::KeyDown) { - bool bListKey = pKey->m_dwKeyCode == FWL_VKEY_Up || - pKey->m_dwKeyCode == FWL_VKEY_Down || - pKey->m_dwKeyCode == FWL_VKEY_Return || - pKey->m_dwKeyCode == FWL_VKEY_Escape; - if (bListKey) { - m_pListBox->GetDelegate()->OnProcessMessage(pMessage); - break; - } - } - DisForm_OnKey(pKey); - break; - } - default: - break; - } - if (backDefault) - IFWL_Widget::OnProcessMessage(pMessage); -} - -void IFWL_ComboBox::DisForm_OnLButtonDown(CFWL_MsgMouse* pMsg) { - bool bDropDown = DisForm_IsDropListVisible(); - CFX_RectF& rtBtn = bDropDown ? m_rtBtn : m_rtClient; - if (!rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) - return; - - if (DisForm_IsDropListVisible()) { - DisForm_ShowDropList(false); - return; - } - if (m_pEdit) - MatchEditText(); - DisForm_ShowDropList(true); -} - -void IFWL_ComboBox::DisForm_OnFocusChanged(CFWL_Message* pMsg, bool bSet) { - if (bSet) { - m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused; - if ((m_pEdit->GetStates() & FWL_WGTSTATE_Focused) == 0) { - CFWL_MsgSetFocus msg; - msg.m_pDstTarget = m_pEdit.get(); - msg.m_pSrcTarget = nullptr; - m_pEdit->GetDelegate()->OnProcessMessage(&msg); - } - } else { - m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused; - DisForm_ShowDropList(false); - CFWL_MsgKillFocus msg; - msg.m_pDstTarget = nullptr; - msg.m_pSrcTarget = m_pEdit.get(); - m_pEdit->GetDelegate()->OnProcessMessage(&msg); - } -} - -void IFWL_ComboBox::DisForm_OnKey(CFWL_MsgKey* pMsg) { - uint32_t dwKeyCode = pMsg->m_dwKeyCode; - const bool bUp = dwKeyCode == FWL_VKEY_Up; - const bool bDown = dwKeyCode == FWL_VKEY_Down; - if (bUp || bDown) { - CFWL_ComboList* pComboList = m_pListBox.get(); - int32_t iCount = pComboList->CountItems(nullptr); - if (iCount < 1) - return; - - bool bMatchEqual = false; - int32_t iCurSel = m_iCurSel; - if (m_pEdit) { - CFX_WideString wsText; - m_pEdit->GetText(wsText); - iCurSel = pComboList->MatchItem(wsText); - if (iCurSel >= 0) { - CFX_WideString wsTemp; - CFWL_ListItem* item = m_pListBox->GetSelItem(iCurSel); - m_pListBox->GetDataProviderItemText(item, wsTemp); - bMatchEqual = wsText == wsTemp; - } - } - if (iCurSel < 0) { - iCurSel = 0; - } else if (bMatchEqual) { - if ((bUp && iCurSel == 0) || (bDown && iCurSel == iCount - 1)) - return; - if (bUp) - iCurSel--; - else - iCurSel++; - } - m_iCurSel = iCurSel; - SyncEditText(m_iCurSel); - return; - } - if (m_pEdit) - m_pEdit->GetDelegate()->OnProcessMessage(pMsg); -} diff --git a/xfa/fwl/core/ifwl_combobox.h b/xfa/fwl/core/ifwl_combobox.h deleted file mode 100644 index 26d0c0f1b8..0000000000 --- a/xfa/fwl/core/ifwl_combobox.h +++ /dev/null @@ -1,176 +0,0 @@ -// 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 - -#ifndef XFA_FWL_CORE_IFWL_COMBOBOX_H_ -#define XFA_FWL_CORE_IFWL_COMBOBOX_H_ - -#include <memory> - -#include "xfa/fwl/core/cfwl_comboboxproxy.h" -#include "xfa/fwl/core/cfwl_comboedit.h" -#include "xfa/fwl/core/cfwl_combolist.h" -#include "xfa/fwl/core/cfwl_form.h" -#include "xfa/fwl/core/ifwl_listbox.h" -#include "xfa/fxgraphics/cfx_graphics.h" - -class CFWL_WidgetProperties; -class IFWL_ComboBox; -class CFWL_ComboBoxProxy; -class CFWL_FormProxy; -class IFWL_ListBox; -class IFWL_Widget; - -#define FWL_STYLEEXT_CMB_DropList (0L << 0) -#define FWL_STYLEEXT_CMB_DropDown (1L << 0) -#define FWL_STYLEEXT_CMB_Sort (1L << 1) -#define FWL_STYLEEXT_CMB_ListDrag (1L << 2) -#define FWL_STYLEEXT_CMB_OwnerDraw (1L << 3) -#define FWL_STYLEEXT_CMB_EditHNear (0L << 4) -#define FWL_STYLEEXT_CMB_EditHCenter (1L << 4) -#define FWL_STYLEEXT_CMB_EditHFar (2L << 4) -#define FWL_STYLEEXT_CMB_EditVNear (0L << 6) -#define FWL_STYLEEXT_CMB_EditVCenter (1L << 6) -#define FWL_STYLEEXT_CMB_EditVFar (2L << 6) -#define FWL_STYLEEXT_CMB_EditJustified (1L << 8) -#define FWL_STYLEEXT_CMB_EditDistributed (2L << 8) -#define FWL_STYLEEXT_CMB_EditHAlignMask (3L << 4) -#define FWL_STYLEEXT_CMB_EditVAlignMask (3L << 6) -#define FWL_STYLEEXT_CMB_EditHAlignModeMask (3L << 8) -#define FWL_STYLEEXT_CMB_ListItemLeftAlign (0L << 10) -#define FWL_STYLEEXT_CMB_ListItemCenterAlign (1L << 10) -#define FWL_STYLEEXT_CMB_ListItemRightAlign (2L << 10) -#define FWL_STYLEEXT_CMB_ListItemAlignMask (3L << 10) -#define FWL_STYLEEXT_CMB_ListItemText (0L << 12) -#define FWL_STYLEEXT_CMB_ListItemIconText (1L << 12) -#define FWL_STYLEEXT_CMB_ReadOnly (1L << 13) - -class IFWL_ComboBox : public IFWL_Widget { - public: - explicit IFWL_ComboBox(const CFWL_App* app, - std::unique_ptr<CFWL_WidgetProperties> properties); - ~IFWL_ComboBox() override; - - // IFWL_Widget - FWL_Type GetClassID() const override; - void GetWidgetRect(CFX_RectF& rect, bool bAutoSize = false) override; - void ModifyStylesEx(uint32_t dwStylesExAdded, - uint32_t dwStylesExRemoved) override; - void SetStates(uint32_t dwStates, bool bSet = true) override; - void Update() override; - FWL_WidgetHit HitTest(FX_FLOAT fx, FX_FLOAT fy) override; - void DrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix = nullptr) override; - void SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) override; - void OnProcessMessage(CFWL_Message* pMessage) override; - void OnProcessEvent(CFWL_Event* pEvent) override; - void OnDrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix) override; - - void GetTextByIndex(int32_t iIndex, CFX_WideString& wsText) const; - int32_t GetCurSel() const { return m_iCurSel; } - void SetCurSel(int32_t iSel); - - void AddString(const CFX_WideStringC& wsText); - bool RemoveAt(int32_t iIndex); // Returns false iff |iIndex| out of range. - void RemoveAll(); - - void SetEditText(const CFX_WideString& wsText); - void GetEditText(CFX_WideString& wsText, - int32_t nStart = 0, - int32_t nCount = -1) const; - - void OpenDropDownList(bool bActivate); - - bool EditCanUndo() const { return m_pEdit->CanUndo(); } - bool EditCanRedo() const { return m_pEdit->CanRedo(); } - bool EditUndo() { return m_pEdit->Undo(); } - bool EditRedo() { return m_pEdit->Redo(); } - bool EditCanCopy() const { return m_pEdit->CountSelRanges() > 0; } - bool EditCanCut() const { - if (m_pEdit->GetStylesEx() & FWL_STYLEEXT_EDT_ReadOnly) - return false; - return EditCanCopy(); - } - bool EditCanSelectAll() const { return m_pEdit->GetTextLength() > 0; } - bool EditCopy(CFX_WideString& wsCopy) const { return m_pEdit->Copy(wsCopy); } - bool EditCut(CFX_WideString& wsCut) { return m_pEdit->Cut(wsCut); } - bool EditPaste(const CFX_WideString& wsPaste) { - return m_pEdit->Paste(wsPaste); - } - void EditSelectAll() { m_pEdit->AddSelRange(0); } - void EditDelete() { m_pEdit->ClearText(); } - void EditDeSelect() { m_pEdit->ClearSelections(); } - - void GetBBox(CFX_RectF& rect) const; - void EditModifyStylesEx(uint32_t dwStylesExAdded, uint32_t dwStylesExRemoved); - - void DrawStretchHandler(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix); - bool IsDropListVisible() const { - return m_pComboBoxProxy && - !(m_pComboBoxProxy->GetStates() & FWL_WGTSTATE_Invisible); - } - void ShowDropList(bool bActivate); - - CFWL_ComboEdit* GetComboEdit() const { return m_pEdit.get(); } - - void ProcessSelChanged(bool bLButtonUp); - int32_t GetCurrentSelection() const { return m_iCurSel; } - - private: - bool IsDropDownStyle() const { - return !!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_DropDown); - } - void MatchEditText(); - void SyncEditText(int32_t iListItem); - void Layout(); - void ResetTheme(); - void ResetEditAlignment(); - void ResetListItemAlignment(); - void InitProxyForm(); - void DisForm_InitComboList(); - void DisForm_InitComboEdit(); - void DisForm_ShowDropList(bool bActivate); - bool DisForm_IsDropListVisible() const { - return !(m_pListBox->GetStates() & FWL_WGTSTATE_Invisible); - } - void DisForm_ModifyStylesEx(uint32_t dwStylesExAdded, - uint32_t dwStylesExRemoved); - void DisForm_Update(); - FWL_WidgetHit DisForm_HitTest(FX_FLOAT fx, FX_FLOAT fy); - void DisForm_DrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix = nullptr); - void DisForm_GetBBox(CFX_RectF& rect) const; - void DisForm_Layout(); - void OnFocusChanged(CFWL_Message* pMsg, bool bSet = true); - void OnLButtonDown(CFWL_MsgMouse* pMsg); - void OnLButtonUp(CFWL_MsgMouse* pMsg); - void OnMouseMove(CFWL_MsgMouse* pMsg); - void OnMouseLeave(CFWL_MsgMouse* pMsg); - void OnKey(CFWL_MsgKey* pMsg); - void DoSubCtrlKey(CFWL_MsgKey* pMsg); - void DisForm_OnProcessMessage(CFWL_Message* pMessage); - void DisForm_OnLButtonDown(CFWL_MsgMouse* pMsg); - void DisForm_OnFocusChanged(CFWL_Message* pMsg, bool bSet = true); - void DisForm_OnKey(CFWL_MsgKey* pMsg); - - CFX_RectF m_rtClient; - CFX_RectF m_rtContent; - CFX_RectF m_rtBtn; - CFX_RectF m_rtList; - CFX_RectF m_rtProxy; - CFX_RectF m_rtHandler; - std::unique_ptr<CFWL_ComboEdit> m_pEdit; - std::unique_ptr<CFWL_ComboList> m_pListBox; - CFWL_ComboBoxProxy* m_pComboBoxProxy; // Can this be a unique_ptr? - bool m_bLButtonDown; - bool m_bUpFormHandler; - int32_t m_iCurSel; - int32_t m_iBtnState; - FX_FLOAT m_fComboFormHandler; - FX_FLOAT m_fItemHeight; -}; - -#endif // XFA_FWL_CORE_IFWL_COMBOBOX_H_ diff --git a/xfa/fwl/core/ifwl_datetimepicker.cpp b/xfa/fwl/core/ifwl_datetimepicker.cpp deleted file mode 100644 index 787be0cb9b..0000000000 --- a/xfa/fwl/core/ifwl_datetimepicker.cpp +++ /dev/null @@ -1,661 +0,0 @@ -// 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 <memory> -#include <utility> - -#include "third_party/base/ptr_util.h" -#include "xfa/fwl/core/cfwl_evteditchanged.h" -#include "xfa/fwl/core/cfwl_evtselectchanged.h" -#include "xfa/fwl/core/cfwl_formproxy.h" -#include "xfa/fwl/core/cfwl_msgmouse.h" -#include "xfa/fwl/core/cfwl_msgsetfocus.h" -#include "xfa/fwl/core/cfwl_notedriver.h" -#include "xfa/fwl/core/cfwl_spinbutton.h" -#include "xfa/fwl/core/cfwl_themebackground.h" -#include "xfa/fwl/core/cfwl_widgetmgr.h" -#include "xfa/fwl/core/ifwl_themeprovider.h" - -namespace { - -const int kDateTimePickerWidth = 100; -const int kDateTimePickerHeight = 20; - -} // namespace - -IFWL_DateTimePicker::IFWL_DateTimePicker( - const CFWL_App* app, - std::unique_ptr<CFWL_WidgetProperties> properties) - : IFWL_Widget(app, std::move(properties), nullptr), - m_iBtnState(1), - m_iYear(-1), - m_iMonth(-1), - m_iDay(-1), - m_bLBtnDown(false) { - m_rtBtn.Set(0, 0, 0, 0); - - m_pProperties->m_dwStyleExes = FWL_STYLEEXT_DTP_ShortDateFormat; - - auto monthProp = pdfium::MakeUnique<CFWL_WidgetProperties>(); - monthProp->m_dwStyles = FWL_WGTSTYLE_Popup | FWL_WGTSTYLE_Border; - monthProp->m_dwStates = FWL_WGTSTATE_Invisible; - monthProp->m_pParent = this; - monthProp->m_pThemeProvider = m_pProperties->m_pThemeProvider; - m_pMonthCal.reset( - new CFWL_MonthCalendar(m_pOwnerApp, std::move(monthProp), this)); - - CFX_RectF rtMonthCal; - m_pMonthCal->GetWidgetRect(rtMonthCal, true); - rtMonthCal.Set(0, 0, rtMonthCal.width, rtMonthCal.height); - m_pMonthCal->SetWidgetRect(rtMonthCal); - - auto editProp = pdfium::MakeUnique<CFWL_WidgetProperties>(); - editProp->m_pParent = this; - editProp->m_pThemeProvider = m_pProperties->m_pThemeProvider; - - m_pEdit.reset(new CFWL_DateTimeEdit(m_pOwnerApp, std::move(editProp), this)); - RegisterEventTarget(m_pMonthCal.get()); - RegisterEventTarget(m_pEdit.get()); -} - -IFWL_DateTimePicker::~IFWL_DateTimePicker() { - UnregisterEventTarget(); -} - -FWL_Type IFWL_DateTimePicker::GetClassID() const { - return FWL_Type::DateTimePicker; -} - -void IFWL_DateTimePicker::GetWidgetRect(CFX_RectF& rect, bool bAutoSize) { - if (m_pWidgetMgr->IsFormDisabled()) { - DisForm_GetWidgetRect(rect, bAutoSize); - return; - } - if (!bAutoSize) { - rect = m_pProperties->m_rtWidget; - return; - } - - rect.Set(0, 0, kDateTimePickerWidth, kDateTimePickerHeight); - IFWL_Widget::GetWidgetRect(rect, true); -} - -void IFWL_DateTimePicker::Update() { - if (m_pWidgetMgr->IsFormDisabled()) { - DisForm_Update(); - return; - } - if (m_iLock) - return; - 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; - - 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); - - 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_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 (IsMonthCalendarVisible()) { - CFX_RectF rect; - m_pMonthCal->GetWidgetRect(rect); - if (rect.Contains(fx, fy)) - return FWL_WidgetHit::Client; - } - return FWL_WidgetHit::Unknown; -} - -void IFWL_DateTimePicker::DrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix) { - if (!pGraphics) - return; - if (!m_pProperties->m_pThemeProvider) - return; - - 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()) { - DisForm_DrawWidget(pGraphics, pMatrix); - return; - } -} - -void IFWL_DateTimePicker::SetThemeProvider(IFWL_ThemeProvider* pTP) { - m_pProperties->m_pThemeProvider = pTP; - m_pMonthCal->SetThemeProvider(pTP); -} - -void IFWL_DateTimePicker::GetCurSel(int32_t& iYear, - int32_t& iMonth, - int32_t& iDay) { - iYear = m_iYear; - iMonth = m_iMonth; - iDay = m_iDay; -} - -void IFWL_DateTimePicker::SetCurSel(int32_t iYear, - int32_t iMonth, - int32_t iDay) { - if (iYear <= 0 || iYear >= 3000) - return; - if (iMonth <= 0 || iMonth >= 13) - return; - if (iDay <= 0 || iDay >= 32) - return; - - m_iYear = iYear; - m_iMonth = iMonth; - m_iDay = iDay; - m_pMonthCal->SetSelect(iYear, iMonth, iDay); -} - -void IFWL_DateTimePicker::SetEditText(const CFX_WideString& wsText) { - if (!m_pEdit) - return; - - m_pEdit->SetText(wsText); - Repaint(&m_rtClient); - - CFWL_EvtEditChanged ev; - DispatchEvent(&ev); -} - -void IFWL_DateTimePicker::GetEditText(CFX_WideString& wsText, - int32_t nStart, - int32_t nCount) const { - if (m_pEdit) - m_pEdit->GetText(wsText, nStart, nCount); -} - -void IFWL_DateTimePicker::GetBBox(CFX_RectF& rect) const { - if (m_pWidgetMgr->IsFormDisabled()) { - DisForm_GetBBox(rect); - return; - } - - rect = m_pProperties->m_rtWidget; - if (IsMonthCalendarVisible()) { - CFX_RectF rtMonth; - m_pMonthCal->GetWidgetRect(rtMonth); - rtMonth.Offset(m_pProperties->m_rtWidget.left, - m_pProperties->m_rtWidget.top); - rect.Union(rtMonth); - } -} - -void IFWL_DateTimePicker::ModifyEditStylesEx(uint32_t dwStylesExAdded, - uint32_t dwStylesExRemoved) { - 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) { - return; - } - - 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); - } -} - -void IFWL_DateTimePicker::ShowMonthCalendar(bool bActivate) { - if (m_pWidgetMgr->IsFormDisabled()) - return DisForm_ShowMonthCalendar(bActivate); - if (IsMonthCalendarVisible() == bActivate) - return; - if (!m_pForm) - InitProxyForm(); - - if (!bActivate) { - m_pForm->EndDoModal(); - return; - } - - 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(); -} - -bool IFWL_DateTimePicker::IsMonthCalendarVisible() const { - if (m_pWidgetMgr->IsFormDisabled()) - return DisForm_IsMonthCalendarVisible(); - if (!m_pForm) - return false; - return !(m_pForm->GetStates() & FWL_WGTSTATE_Invisible); -} - -void IFWL_DateTimePicker::ResetEditAlignment() { - if (!m_pEdit) - return; - - uint32_t dwAdd = 0; - switch (m_pProperties->m_dwStyleExes & 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; - break; - } - } - switch (m_pProperties->m_dwStyleExes & 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; - break; - } - } - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_EditJustified) - dwAdd |= FWL_STYLEEXT_EDT_Justified; - if (m_pProperties->m_dwStyleExes & 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_EvtSelectChanged 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; - - auto prop = pdfium::MakeUnique<CFWL_WidgetProperties>(); - prop->m_dwStyles = FWL_WGTSTYLE_Popup; - prop->m_dwStates = FWL_WGTSTATE_Invisible; - prop->m_pOwner = this; - - m_pForm = pdfium::MakeUnique<CFWL_FormProxy>(m_pOwnerApp, std::move(prop), - m_pMonthCal.get()); - m_pMonthCal->SetParent(m_pForm.get()); -} - -bool IFWL_DateTimePicker::DisForm_IsMonthCalendarVisible() const { - if (!m_pMonthCal) - return false; - return !(m_pMonthCal->GetStates() & FWL_WGTSTATE_Invisible); -} - -void IFWL_DateTimePicker::DisForm_ShowMonthCalendar(bool bActivate) { - if (IsMonthCalendarVisible() == 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(); - m_pEdit->GetDelegate()->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) const { - 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 (IsMonthCalendarVisible()) { - m_pMonthCal->GetWidgetRect(rect); - if (rect.Contains(fx, fy)) - return FWL_WidgetHit::Client; - } - return FWL_WidgetHit::Unknown; -} - -bool IFWL_DateTimePicker::DisForm_IsNeedShowButton() const { - return m_pProperties->m_dwStates & FWL_WGTSTATE_Focused || - m_pMonthCal->GetStates() & FWL_WGTSTATE_Focused || - m_pEdit->GetStates() & FWL_WGTSTATE_Focused; -} - -void IFWL_DateTimePicker::DisForm_Update() { - if (m_iLock) - return; - 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); - - FX_FLOAT* pWidth = static_cast<FX_FLOAT*>( - GetThemeCapacity(CFWL_WidgetCapacity::ScrollBarWidth)); - if (!pWidth) - return; - - 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(); -} - -void IFWL_DateTimePicker::DisForm_GetWidgetRect(CFX_RectF& rect, - bool bAutoSize) { - rect = m_pProperties->m_rtWidget; - if (DisForm_IsNeedShowButton()) - rect.width += m_fBtn; -} - -void IFWL_DateTimePicker::DisForm_GetBBox(CFX_RectF& rect) const { - rect = m_pProperties->m_rtWidget; - if (DisForm_IsNeedShowButton()) - rect.width += m_fBtn; - if (!IsMonthCalendarVisible()) - return; - - CFX_RectF rtMonth; - m_pMonthCal->GetWidgetRect(rtMonth); - rtMonth.Offset(m_pProperties->m_rtWidget.left, m_pProperties->m_rtWidget.top); - rect.Union(rtMonth); -} - -void IFWL_DateTimePicker::DisForm_DrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix) { - if (!pGraphics) - return; - 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 (!IsMonthCalendarVisible()) - return; - - 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); -} - -void IFWL_DateTimePicker::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_pEdit->GetStates() & FWL_WGTSTATE_Focused) { - m_pEdit->GetDelegate()->OnProcessMessage(pMessage); - return; - } - break; - } - default: - break; - } - - IFWL_Widget::OnProcessMessage(pMessage); -} - -void IFWL_DateTimePicker::OnDrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix) { - DrawWidget(pGraphics, pMatrix); -} - -void IFWL_DateTimePicker::OnFocusChanged(CFWL_Message* pMsg, bool bSet) { - if (!pMsg) - return; - if (m_pWidgetMgr->IsFormDisabled()) - return DisForm_OnFocusChanged(pMsg, bSet); - - if (bSet) { - m_pProperties->m_dwStates |= (FWL_WGTSTATE_Focused); - Repaint(&m_rtClient); - } else { - m_pProperties->m_dwStates &= ~(FWL_WGTSTATE_Focused); - Repaint(&m_rtClient); - } - if (pMsg->m_pSrcTarget == m_pMonthCal.get() && IsMonthCalendarVisible()) { - ShowMonthCalendar(false); - } - Repaint(&m_rtClient); -} - -void IFWL_DateTimePicker::OnLButtonDown(CFWL_MsgMouse* pMsg) { - if (!pMsg) - return; - if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) - SetFocus(true); - if (!m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) - return; - - if (IsMonthCalendarVisible()) { - ShowMonthCalendar(false); - return; - } - if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_TimeFormat)) - ShowMonthCalendar(true); - - m_bLBtnDown = true; - Repaint(&m_rtClient); -} - -void IFWL_DateTimePicker::OnLButtonUp(CFWL_MsgMouse* pMsg) { - if (!pMsg) - return; - - m_bLBtnDown = false; - if (m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) - m_iBtnState = CFWL_PartState_Hovered; - else - m_iBtnState = CFWL_PartState_Normal; - Repaint(&m_rtBtn); -} - -void IFWL_DateTimePicker::OnMouseMove(CFWL_MsgMouse* pMsg) { - if (!m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) - m_iBtnState = CFWL_PartState_Normal; - Repaint(&m_rtBtn); -} - -void IFWL_DateTimePicker::OnMouseLeave(CFWL_MsgMouse* pMsg) { - if (!pMsg) - return; - m_iBtnState = CFWL_PartState_Normal; - Repaint(&m_rtBtn); -} - -void IFWL_DateTimePicker::DisForm_OnFocusChanged(CFWL_Message* pMsg, - bool bSet) { - CFX_RectF rtInvalidate(m_rtBtn); - if (bSet) { - m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused; - if (m_pEdit && !(m_pEdit->GetStylesEx() & FWL_STYLEEXT_EDT_ReadOnly)) { - m_rtBtn.Set(m_pProperties->m_rtWidget.width, 0, m_fBtn, - m_pProperties->m_rtWidget.height - 1); - } - rtInvalidate = m_rtBtn; - pMsg->m_pDstTarget = m_pEdit.get(); - m_pEdit->GetDelegate()->OnProcessMessage(pMsg); - } else { - m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused; - m_rtBtn.Set(0, 0, 0, 0); - if (DisForm_IsMonthCalendarVisible()) - ShowMonthCalendar(false); - if (m_pEdit->GetStates() & FWL_WGTSTATE_Focused) { - pMsg->m_pSrcTarget = m_pEdit.get(); - m_pEdit->GetDelegate()->OnProcessMessage(pMsg); - } - } - rtInvalidate.Inflate(2, 2); - Repaint(&rtInvalidate); -} diff --git a/xfa/fwl/core/ifwl_datetimepicker.h b/xfa/fwl/core/ifwl_datetimepicker.h deleted file mode 100644 index b8bec96d9a..0000000000 --- a/xfa/fwl/core/ifwl_datetimepicker.h +++ /dev/null @@ -1,120 +0,0 @@ -// 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 - -#ifndef XFA_FWL_CORE_IFWL_DATETIMEPICKER_H_ -#define XFA_FWL_CORE_IFWL_DATETIMEPICKER_H_ - -#include <memory> - -#include "xfa/fwl/core/cfwl_datetimeedit.h" -#include "xfa/fwl/core/cfwl_event.h" -#include "xfa/fwl/core/cfwl_monthcalendar.h" -#include "xfa/fwl/core/cfwl_widgetproperties.h" -#include "xfa/fwl/core/ifwl_widget.h" - -#define FWL_STYLEEXT_DTP_AllowEdit (1L << 0) -#define FWL_STYLEEXT_DTP_LongDateFormat (0L << 1) -#define FWL_STYLEEXT_DTP_ShortDateFormat (1L << 1) -#define FWL_STYLEEXT_DTP_TimeFormat (2L << 1) -#define FWL_STYLEEXT_DTP_Spin (1L << 3) -#define FWL_STYLEEXT_DTP_EditHNear (0L << 4) -#define FWL_STYLEEXT_DTP_EditHCenter (1L << 4) -#define FWL_STYLEEXT_DTP_EditHFar (2L << 4) -#define FWL_STYLEEXT_DTP_EditVNear (0L << 6) -#define FWL_STYLEEXT_DTP_EditVCenter (1L << 6) -#define FWL_STYLEEXT_DTP_EditVFar (2L << 6) -#define FWL_STYLEEXT_DTP_EditJustified (1L << 8) -#define FWL_STYLEEXT_DTP_EditDistributed (2L << 8) -#define FWL_STYLEEXT_DTP_EditHAlignMask (3L << 4) -#define FWL_STYLEEXT_DTP_EditVAlignMask (3L << 6) -#define FWL_STYLEEXT_DTP_EditHAlignModeMask (3L << 8) - -class CFWL_DateTimeEdit; -class CFWL_FormProxy; - -class IFWL_DateTimePicker : public IFWL_Widget { - public: - explicit IFWL_DateTimePicker( - const CFWL_App* app, - std::unique_ptr<CFWL_WidgetProperties> properties); - ~IFWL_DateTimePicker() override; - - // IFWL_Widget - FWL_Type GetClassID() const override; - void GetWidgetRect(CFX_RectF& rect, bool bAutoSize = false) override; - void Update() override; - FWL_WidgetHit HitTest(FX_FLOAT fx, FX_FLOAT fy) override; - void DrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix = nullptr) override; - void SetThemeProvider(IFWL_ThemeProvider* pTP) override; - void OnProcessMessage(CFWL_Message* pMessage) override; - void OnDrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix) override; - - void GetCurSel(int32_t& iYear, int32_t& iMonth, int32_t& iDay); - void SetCurSel(int32_t iYear, int32_t iMonth, int32_t iDay); - - void SetEditText(const CFX_WideString& wsText); - void GetEditText(CFX_WideString& wsText, - int32_t nStart = 0, - int32_t nCount = -1) const; - - int32_t CountSelRanges() const { return m_pEdit->CountSelRanges(); } - int32_t GetSelRange(int32_t nIndex, int32_t& nStart) const { - return m_pEdit->GetSelRange(nIndex, nStart); - } - - void GetBBox(CFX_RectF& rect) const; - void SetEditLimit(int32_t nLimit) { m_pEdit->SetLimit(nLimit); } - void ModifyEditStylesEx(uint32_t dwStylesExAdded, uint32_t dwStylesExRemoved); - - bool IsMonthCalendarVisible() const; - void ShowMonthCalendar(bool bActivate); - void ProcessSelChanged(int32_t iYear, int32_t iMonth, int32_t iDay); - - CFWL_FormProxy* GetFormProxy() const { return m_pForm.get(); } - - private: - void DrawDropDownButton(CFX_Graphics* pGraphics, - IFWL_ThemeProvider* pTheme, - const CFX_Matrix* pMatrix); - void FormatDateString(int32_t iYear, - int32_t iMonth, - int32_t iDay, - CFX_WideString& wsText); - void ResetEditAlignment(); - void InitProxyForm(); - - bool DisForm_IsMonthCalendarVisible() const; - void DisForm_ShowMonthCalendar(bool bActivate); - FWL_WidgetHit DisForm_HitTest(FX_FLOAT fx, FX_FLOAT fy) const; - bool DisForm_IsNeedShowButton() const; - void DisForm_Update(); - void DisForm_GetWidgetRect(CFX_RectF& rect, bool bAutoSize = false); - void DisForm_GetBBox(CFX_RectF& rect) const; - void DisForm_DrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix = nullptr); - void DisForm_OnFocusChanged(CFWL_Message* pMsg, bool bSet); - void OnFocusChanged(CFWL_Message* pMsg, bool bSet); - void OnLButtonDown(CFWL_MsgMouse* pMsg); - void OnLButtonUp(CFWL_MsgMouse* pMsg); - void OnMouseMove(CFWL_MsgMouse* pMsg); - void OnMouseLeave(CFWL_MsgMouse* pMsg); - - CFX_RectF m_rtBtn; - CFX_RectF m_rtClient; - int32_t m_iBtnState; - int32_t m_iYear; - int32_t m_iMonth; - int32_t m_iDay; - bool m_bLBtnDown; - std::unique_ptr<CFWL_DateTimeEdit> m_pEdit; - std::unique_ptr<CFWL_MonthCalendar> m_pMonthCal; - std::unique_ptr<CFWL_FormProxy> m_pForm; - FX_FLOAT m_fBtn; -}; - -#endif // XFA_FWL_CORE_IFWL_DATETIMEPICKER_H_ diff --git a/xfa/fwl/core/ifwl_edit.cpp b/xfa/fwl/core/ifwl_edit.cpp deleted file mode 100644 index af29745b5c..0000000000 --- a/xfa/fwl/core/ifwl_edit.cpp +++ /dev/null @@ -1,1661 +0,0 @@ -// 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_edit.h" - -#include <algorithm> -#include <memory> -#include <utility> -#include <vector> - -#include "third_party/base/ptr_util.h" -#include "third_party/base/stl_util.h" -#include "xfa/fde/cfde_txtedtengine.h" -#include "xfa/fde/fde_gedevice.h" -#include "xfa/fde/fde_render.h" -#include "xfa/fde/ifde_txtedtpage.h" -#include "xfa/fgas/font/cfgas_gefont.h" -#include "xfa/fwl/core/cfwl_app.h" -#include "xfa/fwl/core/cfwl_caret.h" -#include "xfa/fwl/core/cfwl_evtcheckword.h" -#include "xfa/fwl/core/cfwl_evttextchanged.h" -#include "xfa/fwl/core/cfwl_evttextfull.h" -#include "xfa/fwl/core/cfwl_evtvalidate.h" -#include "xfa/fwl/core/cfwl_msgkey.h" -#include "xfa/fwl/core/cfwl_msgmouse.h" -#include "xfa/fwl/core/cfwl_themebackground.h" -#include "xfa/fwl/core/cfwl_themepart.h" -#include "xfa/fwl/core/cfwl_widgetmgr.h" -#include "xfa/fwl/core/ifwl_themeprovider.h" -#include "xfa/fxfa/xfa_ffdoc.h" -#include "xfa/fxfa/xfa_ffwidget.h" -#include "xfa/fxgraphics/cfx_path.h" - -namespace { - -const int kEditMargin = 3; - -bool FX_EDIT_ISLATINWORD(FX_WCHAR c) { - return c == 0x2D || (c <= 0x005A && c >= 0x0041) || - (c <= 0x007A && c >= 0x0061) || (c <= 0x02AF && c >= 0x00C0) || - c == 0x0027; -} - -void AddSquigglyPath(CFX_Path* pPathData, - FX_FLOAT fStartX, - FX_FLOAT fEndX, - FX_FLOAT fY, - FX_FLOAT fStep) { - pPathData->MoveTo(fStartX, fY); - int i = 1; - for (FX_FLOAT fx = fStartX + fStep; fx < fEndX; fx += fStep, ++i) - pPathData->LineTo(fx, fY + (i & 1) * fStep); -} - -} // namespace - -IFWL_Edit::IFWL_Edit(const CFWL_App* app, - std::unique_ptr<CFWL_WidgetProperties> properties, - IFWL_Widget* pOuter) - : IFWL_Widget(app, std::move(properties), pOuter), - m_fVAlignOffset(0.0f), - m_fScrollOffsetX(0.0f), - m_fScrollOffsetY(0.0f), - m_bLButtonDown(false), - m_nSelStart(0), - m_nLimit(-1), - m_fFontSize(0), - m_bSetRange(false), - m_iMax(0xFFFFFFF), - m_iCurRecord(-1), - m_iMaxRecord(128) { - m_rtClient.Reset(); - m_rtEngine.Reset(); - m_rtStatic.Reset(); - - InitCaret(); -} - -IFWL_Edit::~IFWL_Edit() { - if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) - ShowCaret(false); - ClearRecord(); -} - -FWL_Type IFWL_Edit::GetClassID() const { - return FWL_Type::Edit; -} - -void IFWL_Edit::GetWidgetRect(CFX_RectF& rect, bool bAutoSize) { - if (!bAutoSize) { - rect = m_pProperties->m_rtWidget; - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) { - if (IsShowScrollBar(true)) { - FX_FLOAT* pfWidth = static_cast<FX_FLOAT*>( - GetThemeCapacity(CFWL_WidgetCapacity::ScrollBarWidth)); - rect.width += *pfWidth; - rect.width += kEditMargin; - } - if (IsShowScrollBar(false)) { - FX_FLOAT* pfWidth = static_cast<FX_FLOAT*>( - GetThemeCapacity(CFWL_WidgetCapacity::ScrollBarWidth)); - rect.height += *pfWidth; - rect.height += kEditMargin; - } - } - return; - } - - rect.Set(0, 0, 0, 0); - - int32_t iTextLen = m_EdtEngine.GetTextLength(); - if (iTextLen > 0) { - CFX_WideString wsText; - m_EdtEngine.GetText(wsText, 0); - CFX_SizeF sz = CalcTextSize( - wsText, m_pProperties->m_pThemeProvider, - !!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine)); - rect.Set(0, 0, sz.x, sz.y); - } - IFWL_Widget::GetWidgetRect(rect, true); -} - -void IFWL_Edit::SetStates(uint32_t dwStates, bool bSet) { - if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Invisible) || - (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) { - ShowCaret(false); - } - IFWL_Widget::SetStates(dwStates, bSet); -} - -void IFWL_Edit::Update() { - if (IsLocked()) - return; - if (!m_pProperties->m_pThemeProvider) - m_pProperties->m_pThemeProvider = GetAvailableTheme(); - - Layout(); - if (m_rtClient.IsEmpty()) - return; - - UpdateEditEngine(); - UpdateVAlignment(); - UpdateScroll(); - InitCaret(); -} - -FWL_WidgetHit IFWL_Edit::HitTest(FX_FLOAT fx, FX_FLOAT fy) { - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) { - if (IsShowScrollBar(true)) { - CFX_RectF rect; - m_pVertScrollBar->GetWidgetRect(rect); - if (rect.Contains(fx, fy)) - return FWL_WidgetHit::VScrollBar; - } - if (IsShowScrollBar(false)) { - CFX_RectF rect; - m_pHorzScrollBar->GetWidgetRect(rect); - if (rect.Contains(fx, fy)) - return FWL_WidgetHit::HScrollBar; - } - } - if (m_rtClient.Contains(fx, fy)) - return FWL_WidgetHit::Edit; - return FWL_WidgetHit::Unknown; -} - -void IFWL_Edit::AddSpellCheckObj(CFX_Path& PathData, - int32_t nStart, - int32_t nCount, - FX_FLOAT fOffSetX, - FX_FLOAT fOffSetY) { - FX_FLOAT fStartX = 0.0f; - FX_FLOAT fEndX = 0.0f; - FX_FLOAT fY = 0.0f; - FX_FLOAT fStep = 0.0f; - IFDE_TxtEdtPage* pPage = m_EdtEngine.GetPage(0); - CFX_RectFArray rectArray; - CFX_RectF rectText; - const FDE_TXTEDTPARAMS* txtEdtParams = m_EdtEngine.GetEditParams(); - FX_FLOAT fAsent = static_cast<FX_FLOAT>(txtEdtParams->pFont->GetAscent()) * - txtEdtParams->fFontSize / 1000; - pPage->CalcRangeRectArray(nStart, nCount, rectArray); - - for (int i = 0; i < rectArray.GetSize(); i++) { - rectText = rectArray.GetAt(i); - fY = rectText.top + fAsent + fOffSetY; - fStep = txtEdtParams->fFontSize / 16.0f; - fStartX = rectText.left + fOffSetX; - fEndX = fStartX + rectText.Width(); - AddSquigglyPath(&PathData, fStartX, fEndX, fY, fStep); - } -} - -void IFWL_Edit::DrawSpellCheck(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix) { - pGraphics->SaveGraphState(); - if (pMatrix) - pGraphics->ConcatMatrix(const_cast<CFX_Matrix*>(pMatrix)); - - CFX_Color crLine(0xFFFF0000); - CFWL_EvtCheckWord checkWordEvent; - checkWordEvent.m_pSrcTarget = this; - - CFX_ByteString sLatinWord; - CFX_Path pathSpell; - pathSpell.Create(); - - int32_t nStart = 0; - FX_FLOAT fOffSetX = m_rtEngine.left - m_fScrollOffsetX; - FX_FLOAT fOffSetY = m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset; - - CFX_WideString wsSpell; - GetText(wsSpell); - int32_t nContentLen = wsSpell.GetLength(); - for (int i = 0; i < nContentLen; i++) { - if (FX_EDIT_ISLATINWORD(wsSpell[i])) { - if (sLatinWord.IsEmpty()) - nStart = i; - sLatinWord += (FX_CHAR)wsSpell[i]; - continue; - } - checkWordEvent.bsWord = sLatinWord; - checkWordEvent.bCheckWord = true; - DispatchEvent(&checkWordEvent); - - if (!sLatinWord.IsEmpty() && !checkWordEvent.bCheckWord) { - AddSpellCheckObj(pathSpell, nStart, sLatinWord.GetLength(), fOffSetX, - fOffSetY); - } - sLatinWord.clear(); - } - - checkWordEvent.bsWord = sLatinWord; - checkWordEvent.bCheckWord = true; - DispatchEvent(&checkWordEvent); - - if (!sLatinWord.IsEmpty() && !checkWordEvent.bCheckWord) { - AddSpellCheckObj(pathSpell, nStart, sLatinWord.GetLength(), fOffSetX, - fOffSetY); - } - if (!pathSpell.IsEmpty()) { - CFX_RectF rtClip = m_rtEngine; - CFX_Matrix mt; - mt.Set(1, 0, 0, 1, fOffSetX, fOffSetY); - if (pMatrix) { - pMatrix->TransformRect(rtClip); - mt.Concat(*pMatrix); - } - pGraphics->SetClipRect(rtClip); - pGraphics->SetStrokeColor(&crLine); - pGraphics->SetLineWidth(0); - pGraphics->StrokePath(&pathSpell, nullptr); - } - pGraphics->RestoreGraphState(); -} - -void IFWL_Edit::DrawWidget(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix) { - if (!pGraphics) - return; - if (!m_pProperties->m_pThemeProvider) - return; - if (m_rtClient.IsEmpty()) - return; - - IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider; - if (!m_pWidgetMgr->IsFormDisabled()) - DrawTextBk(pGraphics, pTheme, pMatrix); - DrawContent(pGraphics, pTheme, pMatrix); - - if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) && - !(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly)) { - DrawSpellCheck(pGraphics, pMatrix); - } - if (HasBorder()) - DrawBorder(pGraphics, CFWL_Part::Border, pTheme, pMatrix); - if (HasEdge()) - DrawEdge(pGraphics, CFWL_Part::Edge, pTheme, pMatrix); -} - -void IFWL_Edit::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) { - if (!pThemeProvider) - return; - if (m_pHorzScrollBar) - m_pHorzScrollBar->SetThemeProvider(pThemeProvider); - if (m_pVertScrollBar) - m_pVertScrollBar->SetThemeProvider(pThemeProvider); - if (m_pCaret) - m_pCaret->SetThemeProvider(pThemeProvider); - m_pProperties->m_pThemeProvider = pThemeProvider; -} - -void IFWL_Edit::SetText(const CFX_WideString& wsText) { - m_EdtEngine.SetText(wsText); -} - -int32_t IFWL_Edit::GetTextLength() const { - return m_EdtEngine.GetTextLength(); -} - -void IFWL_Edit::GetText(CFX_WideString& wsText, - int32_t nStart, - int32_t nCount) const { - m_EdtEngine.GetText(wsText, nStart, nCount); -} - -void IFWL_Edit::ClearText() { - m_EdtEngine.ClearText(); -} - -void IFWL_Edit::AddSelRange(int32_t nStart, int32_t nCount) { - m_EdtEngine.AddSelRange(nStart, nCount); -} - -int32_t IFWL_Edit::CountSelRanges() const { - return m_EdtEngine.CountSelRanges(); -} - -int32_t IFWL_Edit::GetSelRange(int32_t nIndex, int32_t& nStart) const { - return m_EdtEngine.GetSelRange(nIndex, nStart); -} - -void IFWL_Edit::ClearSelections() { - m_EdtEngine.ClearSelection(); -} - -int32_t IFWL_Edit::GetLimit() const { - return m_nLimit; -} - -void IFWL_Edit::SetLimit(int32_t nLimit) { - m_nLimit = nLimit; - m_EdtEngine.SetLimit(nLimit); -} - -void IFWL_Edit::SetAliasChar(FX_WCHAR wAlias) { - m_EdtEngine.SetAliasChar(wAlias); -} - -bool IFWL_Edit::Copy(CFX_WideString& wsCopy) { - int32_t nCount = m_EdtEngine.CountSelRanges(); - if (nCount == 0) - return false; - - wsCopy.clear(); - CFX_WideString wsTemp; - int32_t nStart, nLength; - for (int32_t i = 0; i < nCount; i++) { - nLength = m_EdtEngine.GetSelRange(i, nStart); - m_EdtEngine.GetText(wsTemp, nStart, nLength); - wsCopy += wsTemp; - wsTemp.clear(); - } - return true; -} - -bool IFWL_Edit::Cut(CFX_WideString& wsCut) { - int32_t nCount = m_EdtEngine.CountSelRanges(); - if (nCount == 0) - return false; - - wsCut.clear(); - CFX_WideString wsTemp; - int32_t nStart, nLength; - for (int32_t i = 0; i < nCount; i++) { - nLength = m_EdtEngine.GetSelRange(i, nStart); - m_EdtEngine.GetText(wsTemp, nStart, nLength); - wsCut += wsTemp; - wsTemp.clear(); - } - m_EdtEngine.Delete(0); - return true; -} - -bool IFWL_Edit::Paste(const CFX_WideString& wsPaste) { - int32_t nCaret = m_EdtEngine.GetCaretPos(); - int32_t iError = - m_EdtEngine.Insert(nCaret, wsPaste.c_str(), wsPaste.GetLength()); - if (iError < 0) { - ProcessInsertError(iError); - return false; - } - return true; -} - -bool IFWL_Edit::Redo(const IFDE_TxtEdtDoRecord* pRecord) { - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_NoRedoUndo) - return true; - return m_EdtEngine.Redo(pRecord); -} - -bool IFWL_Edit::Undo(const IFDE_TxtEdtDoRecord* pRecord) { - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_NoRedoUndo) - return true; - return m_EdtEngine.Undo(pRecord); -} - -bool IFWL_Edit::Undo() { - if (!CanUndo()) - return false; - return Undo(m_DoRecords[m_iCurRecord--].get()); -} - -bool IFWL_Edit::Redo() { - if (!CanRedo()) - return false; - return Redo(m_DoRecords[++m_iCurRecord].get()); -} - -bool IFWL_Edit::CanUndo() { - return m_iCurRecord >= 0; -} - -bool IFWL_Edit::CanRedo() { - return m_iCurRecord < pdfium::CollectionSize<int32_t>(m_DoRecords) - 1; -} - -void IFWL_Edit::SetOuter(IFWL_Widget* pOuter) { - m_pOuter = pOuter; -} - -void IFWL_Edit::On_CaretChanged(CFDE_TxtEdtEngine* pEdit, - int32_t nPage, - bool bVisible) { - if (m_rtEngine.IsEmpty()) - return; - if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) - return; - - bool bRepaintContent = UpdateOffset(); - UpdateCaret(); - CFX_RectF rtInvalid; - rtInvalid.Set(0, 0, 0, 0); - bool bRepaintScroll = false; - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine) { - CFWL_ScrollBar* pScroll = UpdateScroll(); - if (pScroll) { - pScroll->GetWidgetRect(rtInvalid); - bRepaintScroll = true; - } - } - if (bRepaintContent || bRepaintScroll) { - if (bRepaintContent) - rtInvalid.Union(m_rtEngine); - Repaint(&rtInvalid); - } -} - -void IFWL_Edit::On_TextChanged(CFDE_TxtEdtEngine* pEdit, - FDE_TXTEDT_TEXTCHANGE_INFO& ChangeInfo) { - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VAlignMask) - UpdateVAlignment(); - - CFX_RectF rtTemp; - GetClientRect(rtTemp); - - CFWL_EvtTextChanged event; - event.m_pSrcTarget = this; - event.nChangeType = ChangeInfo.nChangeType; - event.wsInsert = ChangeInfo.wsInsert; - event.wsDelete = ChangeInfo.wsDelete; - event.wsPrevText = ChangeInfo.wsPrevText; - DispatchEvent(&event); - - LayoutScrollBar(); - Repaint(&rtTemp); -} - -void IFWL_Edit::On_SelChanged(CFDE_TxtEdtEngine* pEdit) { - CFX_RectF rtTemp; - GetClientRect(rtTemp); - Repaint(&rtTemp); -} - -bool IFWL_Edit::On_PageLoad(CFDE_TxtEdtEngine* pEdit, - int32_t nPageIndex, - int32_t nPurpose) { - IFDE_TxtEdtPage* pPage = m_EdtEngine.GetPage(nPageIndex); - if (!pPage) - return false; - - pPage->LoadPage(nullptr, nullptr); - return true; -} - -bool IFWL_Edit::On_PageUnload(CFDE_TxtEdtEngine* pEdit, - int32_t nPageIndex, - int32_t nPurpose) { - IFDE_TxtEdtPage* pPage = m_EdtEngine.GetPage(nPageIndex); - if (!pPage) - return false; - - pPage->UnloadPage(nullptr); - return true; -} - -void IFWL_Edit::On_AddDoRecord(CFDE_TxtEdtEngine* pEdit, - IFDE_TxtEdtDoRecord* pRecord) { - AddDoRecord(pRecord); -} - -bool IFWL_Edit::On_Validate(CFDE_TxtEdtEngine* pEdit, CFX_WideString& wsText) { - IFWL_Widget* pDst = GetOuter(); - if (!pDst) - pDst = this; - - CFWL_EvtValidate event; - event.pDstWidget = pDst; - event.m_pSrcTarget = this; - event.wsInsert = wsText; - event.bValidate = true; - DispatchEvent(&event); - return event.bValidate; -} - -void IFWL_Edit::SetScrollOffset(FX_FLOAT fScrollOffset) { - m_fScrollOffsetY = fScrollOffset; -} - -void IFWL_Edit::DrawTextBk(CFX_Graphics* pGraphics, - IFWL_ThemeProvider* pTheme, - const CFX_Matrix* pMatrix) { - CFWL_ThemeBackground param; - param.m_pWidget = this; - param.m_iPart = CFWL_Part::Background; - param.m_bStaticBackground = false; - param.m_dwStates = m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly - ? CFWL_PartState_ReadOnly - : CFWL_PartState_Normal; - uint32_t dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled); - if (dwStates) - param.m_dwStates = CFWL_PartState_Disabled; - param.m_pGraphics = pGraphics; - param.m_matrix = *pMatrix; - param.m_rtPart = m_rtClient; - pTheme->DrawBackground(¶m); - - if (!IsShowScrollBar(true) || !IsShowScrollBar(false)) - return; - - CFX_RectF rtScorll; - m_pHorzScrollBar->GetWidgetRect(rtScorll); - - CFX_RectF rtStatic; - rtStatic.Set(m_rtClient.right() - rtScorll.height, - m_rtClient.bottom() - rtScorll.height, rtScorll.height, - rtScorll.height); - param.m_bStaticBackground = true; - param.m_bMaximize = true; - param.m_rtPart = rtStatic; - pTheme->DrawBackground(¶m); -} - -void IFWL_Edit::DrawContent(CFX_Graphics* pGraphics, - IFWL_ThemeProvider* pTheme, - const CFX_Matrix* pMatrix) { - IFDE_TxtEdtPage* pPage = m_EdtEngine.GetPage(0); - if (!pPage) - return; - - pGraphics->SaveGraphState(); - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_CombText) - pGraphics->SaveGraphState(); - - CFX_RectF rtClip = m_rtEngine; - FX_FLOAT fOffSetX = m_rtEngine.left - m_fScrollOffsetX; - FX_FLOAT fOffSetY = m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset; - CFX_Matrix mt; - mt.Set(1, 0, 0, 1, fOffSetX, fOffSetY); - if (pMatrix) { - pMatrix->TransformRect(rtClip); - mt.Concat(*pMatrix); - } - - bool bShowSel = (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_NoHideSel) || - (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused); - if (bShowSel) { - IFWL_Widget* pForm = m_pWidgetMgr->GetSystemFormWidget(this); - if (pForm) { - bShowSel = (pForm->GetStates() & FWL_WGTSTATE_Deactivated) != - FWL_WGTSTATE_Deactivated; - } - } - - int32_t nSelCount = m_EdtEngine.CountSelRanges(); - if (bShowSel && nSelCount > 0) { - int32_t nPageCharStart = pPage->GetCharStart(); - int32_t nPageCharCount = pPage->GetCharCount(); - int32_t nPageCharEnd = nPageCharStart + nPageCharCount - 1; - int32_t nCharCount; - int32_t nCharStart; - CFX_RectFArray rectArr; - int32_t i = 0; - for (i = 0; i < nSelCount; i++) { - nCharCount = m_EdtEngine.GetSelRange(i, nCharStart); - int32_t nCharEnd = nCharStart + nCharCount - 1; - if (nCharEnd < nPageCharStart || nCharStart > nPageCharEnd) - continue; - - int32_t nBgn = std::max(nCharStart, nPageCharStart); - int32_t nEnd = std::min(nCharEnd, nPageCharEnd); - pPage->CalcRangeRectArray(nBgn - nPageCharStart, nEnd - nBgn + 1, - rectArr); - } - - int32_t nCount = rectArr.GetSize(); - CFX_Path path; - path.Create(); - for (i = 0; i < nCount; i++) { - rectArr[i].left += fOffSetX; - rectArr[i].top += fOffSetY; - path.AddRectangle(rectArr[i].left, rectArr[i].top, rectArr[i].width, - rectArr[i].height); - } - pGraphics->SetClipRect(rtClip); - - CFWL_ThemeBackground param; - param.m_pGraphics = pGraphics; - param.m_matrix = *pMatrix; - param.m_pWidget = this; - param.m_iPart = CFWL_Part::Background; - param.m_pPath = &path; - pTheme->DrawBackground(¶m); - } - - CFX_RenderDevice* pRenderDev = pGraphics->GetRenderDevice(); - if (!pRenderDev) - return; - - std::unique_ptr<CFDE_RenderDevice> pRenderDevice( - new CFDE_RenderDevice(pRenderDev, false)); - std::unique_ptr<CFDE_RenderContext> pRenderContext(new CFDE_RenderContext); - pRenderDevice->SetClipRect(rtClip); - pRenderContext->StartRender(pRenderDevice.get(), pPage, mt); - pRenderContext->DoRender(nullptr); - - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_CombText) { - pGraphics->RestoreGraphState(); - CFX_Path path; - path.Create(); - int32_t iLimit = m_nLimit > 0 ? m_nLimit : 1; - FX_FLOAT fStep = m_rtEngine.width / iLimit; - FX_FLOAT fLeft = m_rtEngine.left + 1; - for (int32_t i = 1; i < iLimit; i++) { - fLeft += fStep; - path.AddLine(fLeft, m_rtClient.top, fLeft, m_rtClient.bottom()); - } - - CFWL_ThemeBackground param; - param.m_pGraphics = pGraphics; - param.m_matrix = *pMatrix; - param.m_pWidget = this; - param.m_iPart = CFWL_Part::CombTextLine; - param.m_pPath = &path; - pTheme->DrawBackground(¶m); - } - pGraphics->RestoreGraphState(); -} - -void IFWL_Edit::UpdateEditEngine() { - UpdateEditParams(); - UpdateEditLayout(); - if (m_nLimit > -1) - m_EdtEngine.SetLimit(m_nLimit); -} - -void IFWL_Edit::UpdateEditParams() { - FDE_TXTEDTPARAMS params; - params.nHorzScale = 100; - params.fPlateWidth = m_rtEngine.width; - params.fPlateHeight = m_rtEngine.height; - if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_RTLLayout) - params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_RTL; - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VerticalLayout) - params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_DocVertical; - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VerticalChars) - params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_CharVertial; - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReverseLine) - params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_LineReserve; - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ArabicShapes) - params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_ArabicShapes; - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ExpandTab) - params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_ExpandTab; - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_CombText) - params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_CombText; - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_LastLineHeight) - params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_LastLineHeight; - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_Validate) - params.dwMode |= FDE_TEXTEDITMODE_Validate; - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_Password) - params.dwMode |= FDE_TEXTEDITMODE_Password; - - switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HAlignMask) { - case FWL_STYLEEXT_EDT_HNear: { - params.dwAlignment |= FDE_TEXTEDITALIGN_Left; - break; - } - case FWL_STYLEEXT_EDT_HCenter: { - params.dwAlignment |= FDE_TEXTEDITALIGN_Center; - break; - } - case FWL_STYLEEXT_EDT_HFar: { - params.dwAlignment |= FDE_TEXTEDITALIGN_Right; - break; - } - default: - break; - } - switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HAlignModeMask) { - case FWL_STYLEEXT_EDT_Justified: { - params.dwAlignment |= FDE_TEXTEDITALIGN_Justified; - break; - } - case FWL_STYLEEXT_EDT_Distributed: { - params.dwAlignment |= FDE_TEXTEDITALIGN_Distributed; - break; - } - default: { - params.dwAlignment |= FDE_TEXTEDITALIGN_Normal; - break; - } - } - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine) { - params.dwMode |= FDE_TEXTEDITMODE_MultiLines; - if ((m_pProperties->m_dwStyles & FWL_WGTSTYLE_HScroll) == 0 && - (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_AutoHScroll) == 0) { - params.dwMode |= - FDE_TEXTEDITMODE_AutoLineWrap | FDE_TEXTEDITMODE_LimitArea_Horz; - } - if ((m_pProperties->m_dwStyles & FWL_WGTSTYLE_VScroll) == 0 && - (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_AutoVScroll) == 0) { - params.dwMode |= FDE_TEXTEDITMODE_LimitArea_Vert; - } else { - params.fPlateHeight = 0x00FFFFFF; - } - } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_AutoHScroll) == - 0) { - params.dwMode |= FDE_TEXTEDITMODE_LimitArea_Horz; - } - if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly) || - (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) { - params.dwMode |= FDE_TEXTEDITMODE_ReadOnly; - } - - FX_FLOAT* pFontSize = - static_cast<FX_FLOAT*>(GetThemeCapacity(CFWL_WidgetCapacity::FontSize)); - if (!pFontSize) - return; - - m_fFontSize = *pFontSize; - uint32_t* pFontColor = - static_cast<uint32_t*>(GetThemeCapacity(CFWL_WidgetCapacity::TextColor)); - if (!pFontColor) - return; - - params.dwFontColor = *pFontColor; - FX_FLOAT* pLineHeight = - static_cast<FX_FLOAT*>(GetThemeCapacity(CFWL_WidgetCapacity::LineHeight)); - if (!pLineHeight) - return; - - params.fLineSpace = *pLineHeight; - CFGAS_GEFont* pFont = - static_cast<CFGAS_GEFont*>(GetThemeCapacity(CFWL_WidgetCapacity::Font)); - if (!pFont) - return; - - params.pFont = pFont; - params.fFontSize = m_fFontSize; - params.nLineCount = (int32_t)(params.fPlateHeight / params.fLineSpace); - if (params.nLineCount <= 0) - params.nLineCount = 1; - params.fTabWidth = params.fFontSize * 1; - params.bTabEquidistant = true; - params.wLineBreakChar = L'\n'; - params.nCharRotation = 0; - params.pEventSink = this; - m_EdtEngine.SetEditParams(params); -} - -void IFWL_Edit::UpdateEditLayout() { - if (m_EdtEngine.GetTextLength() <= 0) - m_EdtEngine.SetTextByStream(nullptr); - - IFDE_TxtEdtPage* pPage = m_EdtEngine.GetPage(0); - if (pPage) - pPage->UnloadPage(nullptr); - - m_EdtEngine.StartLayout(); - m_EdtEngine.DoLayout(nullptr); - m_EdtEngine.EndLayout(); - pPage = m_EdtEngine.GetPage(0); - if (pPage) - pPage->LoadPage(nullptr, nullptr); -} - -bool IFWL_Edit::UpdateOffset() { - CFX_RectF rtCaret; - m_EdtEngine.GetCaretRect(rtCaret); - FX_FLOAT fOffSetX = m_rtEngine.left - m_fScrollOffsetX; - FX_FLOAT fOffSetY = m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset; - rtCaret.Offset(fOffSetX, fOffSetY); - const CFX_RectF& rtEidt = m_rtEngine; - if (rtEidt.Contains(rtCaret)) { - IFDE_TxtEdtPage* pPage = m_EdtEngine.GetPage(0); - if (!pPage) - return false; - - CFX_RectF rtFDE = pPage->GetContentsBox(); - rtFDE.Offset(fOffSetX, fOffSetY); - if (rtFDE.right() < rtEidt.right() && m_fScrollOffsetX > 0) { - m_fScrollOffsetX += rtFDE.right() - rtEidt.right(); - m_fScrollOffsetX = std::max(m_fScrollOffsetX, 0.0f); - } - if (rtFDE.bottom() < rtEidt.bottom() && m_fScrollOffsetY > 0) { - m_fScrollOffsetY += rtFDE.bottom() - rtEidt.bottom(); - m_fScrollOffsetY = std::max(m_fScrollOffsetY, 0.0f); - } - return false; - } - - FX_FLOAT offsetX = 0.0; - FX_FLOAT offsetY = 0.0; - if (rtCaret.left < rtEidt.left) - offsetX = rtCaret.left - rtEidt.left; - if (rtCaret.right() > rtEidt.right()) - offsetX = rtCaret.right() - rtEidt.right(); - if (rtCaret.top < rtEidt.top) - offsetY = rtCaret.top - rtEidt.top; - if (rtCaret.bottom() > rtEidt.bottom()) - offsetY = rtCaret.bottom() - rtEidt.bottom(); - m_fScrollOffsetX += offsetX; - m_fScrollOffsetY += offsetY; - if (m_fFontSize > m_rtEngine.height) - m_fScrollOffsetY = 0; - return true; -} - -bool IFWL_Edit::UpdateOffset(CFWL_ScrollBar* pScrollBar, FX_FLOAT fPosChanged) { - if (pScrollBar == m_pHorzScrollBar.get()) - m_fScrollOffsetX += fPosChanged; - else - m_fScrollOffsetY += fPosChanged; - return true; -} - -void IFWL_Edit::UpdateVAlignment() { - IFDE_TxtEdtPage* pPage = m_EdtEngine.GetPage(0); - if (!pPage) - return; - - const CFX_RectF& rtFDE = pPage->GetContentsBox(); - FX_FLOAT fOffsetY = 0.0f; - FX_FLOAT fSpaceAbove = 0.0f; - FX_FLOAT fSpaceBelow = 0.0f; - CFX_SizeF* pSpace = static_cast<CFX_SizeF*>( - GetThemeCapacity(CFWL_WidgetCapacity::SpaceAboveBelow)); - if (pSpace) { - fSpaceAbove = pSpace->x; - fSpaceBelow = pSpace->y; - } - if (fSpaceAbove < 0.1f) - fSpaceAbove = 0; - if (fSpaceBelow < 0.1f) - fSpaceBelow = 0; - - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VCenter) { - fOffsetY = (m_rtEngine.height - rtFDE.height) / 2; - if (fOffsetY < (fSpaceAbove + fSpaceBelow) / 2 && - fSpaceAbove < fSpaceBelow) { - return; - } - fOffsetY += (fSpaceAbove - fSpaceBelow) / 2; - } else if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VFar) { - fOffsetY = (m_rtEngine.height - rtFDE.height); - fOffsetY -= fSpaceBelow; - } else { - fOffsetY += fSpaceAbove; - } - m_fVAlignOffset = std::max(fOffsetY, 0.0f); -} - -void IFWL_Edit::UpdateCaret() { - CFX_RectF rtFDE; - m_EdtEngine.GetCaretRect(rtFDE); - - rtFDE.Offset(m_rtEngine.left - m_fScrollOffsetX, - m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset); - CFX_RectF rtCaret; - rtCaret.Set(rtFDE.left, rtFDE.top, rtFDE.width, rtFDE.height); - - CFX_RectF rtClient; - GetClientRect(rtClient); - rtCaret.Intersect(rtClient); - - if (rtCaret.left > rtClient.right()) { - FX_FLOAT right = rtCaret.right(); - rtCaret.left = rtClient.right() - 1; - rtCaret.width = right - rtCaret.left; - } - - bool bShow = - m_pProperties->m_dwStates & FWL_WGTSTATE_Focused && !rtCaret.IsEmpty(); - ShowCaret(bShow, &rtCaret); -} - -CFWL_ScrollBar* IFWL_Edit::UpdateScroll() { - bool bShowHorz = - m_pHorzScrollBar && - ((m_pHorzScrollBar->GetStates() & FWL_WGTSTATE_Invisible) == 0); - bool bShowVert = - m_pVertScrollBar && - ((m_pVertScrollBar->GetStates() & FWL_WGTSTATE_Invisible) == 0); - if (!bShowHorz && !bShowVert) - return nullptr; - - IFDE_TxtEdtPage* pPage = m_EdtEngine.GetPage(0); - if (!pPage) - return nullptr; - - const CFX_RectF& rtFDE = pPage->GetContentsBox(); - CFWL_ScrollBar* pRepaint = nullptr; - if (bShowHorz) { - CFX_RectF rtScroll; - m_pHorzScrollBar->GetWidgetRect(rtScroll); - if (rtScroll.width < rtFDE.width) { - m_pHorzScrollBar->LockUpdate(); - FX_FLOAT fRange = rtFDE.width - rtScroll.width; - m_pHorzScrollBar->SetRange(0.0f, fRange); - - FX_FLOAT fPos = std::min(std::max(m_fScrollOffsetX, 0.0f), fRange); - m_pHorzScrollBar->SetPos(fPos); - m_pHorzScrollBar->SetTrackPos(fPos); - m_pHorzScrollBar->SetPageSize(rtScroll.width); - m_pHorzScrollBar->SetStepSize(rtScroll.width / 10); - m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Disabled, false); - m_pHorzScrollBar->UnlockUpdate(); - m_pHorzScrollBar->Update(); - pRepaint = m_pHorzScrollBar.get(); - } else if ((m_pHorzScrollBar->GetStates() & FWL_WGTSTATE_Disabled) == 0) { - m_pHorzScrollBar->LockUpdate(); - m_pHorzScrollBar->SetRange(0, -1); - m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Disabled, true); - m_pHorzScrollBar->UnlockUpdate(); - m_pHorzScrollBar->Update(); - pRepaint = m_pHorzScrollBar.get(); - } - } - - if (bShowVert) { - CFX_RectF rtScroll; - m_pVertScrollBar->GetWidgetRect(rtScroll); - if (rtScroll.height < rtFDE.height) { - m_pVertScrollBar->LockUpdate(); - FX_FLOAT fStep = m_EdtEngine.GetEditParams()->fLineSpace; - FX_FLOAT fRange = std::max(rtFDE.height - m_rtEngine.height, fStep); - - m_pVertScrollBar->SetRange(0.0f, fRange); - FX_FLOAT fPos = std::min(std::max(m_fScrollOffsetY, 0.0f), fRange); - m_pVertScrollBar->SetPos(fPos); - m_pVertScrollBar->SetTrackPos(fPos); - m_pVertScrollBar->SetPageSize(rtScroll.height); - m_pVertScrollBar->SetStepSize(fStep); - m_pVertScrollBar->SetStates(FWL_WGTSTATE_Disabled, false); - m_pVertScrollBar->UnlockUpdate(); - m_pVertScrollBar->Update(); - pRepaint = m_pVertScrollBar.get(); - } else if ((m_pVertScrollBar->GetStates() & FWL_WGTSTATE_Disabled) == 0) { - m_pVertScrollBar->LockUpdate(); - m_pVertScrollBar->SetRange(0, -1); - m_pVertScrollBar->SetStates(FWL_WGTSTATE_Disabled, true); - m_pVertScrollBar->UnlockUpdate(); - m_pVertScrollBar->Update(); - pRepaint = m_pVertScrollBar.get(); - } - } - return pRepaint; -} - -bool IFWL_Edit::IsShowScrollBar(bool bVert) { - bool bShow = - (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ShowScrollbarFocus) - ? (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == - FWL_WGTSTATE_Focused - : true; - if (bVert) { - return bShow && (m_pProperties->m_dwStyles & FWL_WGTSTYLE_VScroll) && - (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine) && - IsContentHeightOverflow(); - } - return bShow && (m_pProperties->m_dwStyles & FWL_WGTSTYLE_HScroll) && - (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine); -} - -bool IFWL_Edit::IsContentHeightOverflow() { - IFDE_TxtEdtPage* pPage = m_EdtEngine.GetPage(0); - if (!pPage) - return false; - return pPage->GetContentsBox().height > m_rtEngine.height + 1.0f; -} - -int32_t IFWL_Edit::AddDoRecord(IFDE_TxtEdtDoRecord* pRecord) { - int32_t nCount = pdfium::CollectionSize<int32_t>(m_DoRecords); - if (m_iCurRecord == nCount - 1) { - if (nCount == m_iMaxRecord) { - m_DoRecords.pop_front(); - m_iCurRecord--; - } - } else { - m_DoRecords.erase(m_DoRecords.begin() + m_iCurRecord + 1, - m_DoRecords.end()); - } - - m_DoRecords.push_back(std::unique_ptr<IFDE_TxtEdtDoRecord>(pRecord)); - m_iCurRecord = pdfium::CollectionSize<int32_t>(m_DoRecords) - 1; - return m_iCurRecord; -} - -void IFWL_Edit::Layout() { - GetClientRect(m_rtClient); - m_rtEngine = m_rtClient; - FX_FLOAT* pfWidth = static_cast<FX_FLOAT*>( - GetThemeCapacity(CFWL_WidgetCapacity::ScrollBarWidth)); - if (!pfWidth) - return; - - FX_FLOAT fWidth = *pfWidth; - if (!m_pOuter) { - CFX_RectF* pUIMargin = static_cast<CFX_RectF*>( - GetThemeCapacity(CFWL_WidgetCapacity::UIMargin)); - if (pUIMargin) { - m_rtEngine.Deflate(pUIMargin->left, pUIMargin->top, pUIMargin->width, - pUIMargin->height); - } - } else if (m_pOuter->GetClassID() == FWL_Type::DateTimePicker) { - CFWL_ThemePart part; - part.m_pWidget = m_pOuter; - CFX_RectF* pUIMargin = - static_cast<CFX_RectF*>(m_pOuter->GetThemeProvider()->GetCapacity( - &part, CFWL_WidgetCapacity::UIMargin)); - if (pUIMargin) { - m_rtEngine.Deflate(pUIMargin->left, pUIMargin->top, pUIMargin->width, - pUIMargin->height); - } - } - - bool bShowVertScrollbar = IsShowScrollBar(true); - bool bShowHorzScrollbar = IsShowScrollBar(false); - if (bShowVertScrollbar) { - InitScrollBar(); - - CFX_RectF rtVertScr; - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) { - rtVertScr.Set(m_rtClient.right() + kEditMargin, m_rtClient.top, fWidth, - m_rtClient.height); - } else { - rtVertScr.Set(m_rtClient.right() - fWidth, m_rtClient.top, fWidth, - m_rtClient.height); - if (bShowHorzScrollbar) - rtVertScr.height -= fWidth; - m_rtEngine.width -= fWidth; - } - - m_pVertScrollBar->SetWidgetRect(rtVertScr); - m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, false); - m_pVertScrollBar->Update(); - } else if (m_pVertScrollBar) { - m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, true); - } - - if (bShowHorzScrollbar) { - InitScrollBar(false); - - CFX_RectF rtHoriScr; - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) { - rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() + kEditMargin, - m_rtClient.width, fWidth); - } else { - rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() - fWidth, - m_rtClient.width, fWidth); - if (bShowVertScrollbar) - rtHoriScr.width -= fWidth; - m_rtEngine.height -= fWidth; - } - m_pHorzScrollBar->SetWidgetRect(rtHoriScr); - m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, false); - m_pHorzScrollBar->Update(); - } else if (m_pHorzScrollBar) { - m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, true); - } -} - -void IFWL_Edit::LayoutScrollBar() { - if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ShowScrollbarFocus) == - 0) { - return; - } - - FX_FLOAT* pfWidth = nullptr; - bool bShowVertScrollbar = IsShowScrollBar(true); - bool bShowHorzScrollbar = IsShowScrollBar(false); - if (bShowVertScrollbar) { - if (!m_pVertScrollBar) { - pfWidth = static_cast<FX_FLOAT*>( - GetThemeCapacity(CFWL_WidgetCapacity::ScrollBarWidth)); - FX_FLOAT fWidth = pfWidth ? *pfWidth : 0; - InitScrollBar(); - CFX_RectF rtVertScr; - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) { - rtVertScr.Set(m_rtClient.right() + kEditMargin, m_rtClient.top, fWidth, - m_rtClient.height); - } else { - rtVertScr.Set(m_rtClient.right() - fWidth, m_rtClient.top, fWidth, - m_rtClient.height); - if (bShowHorzScrollbar) - rtVertScr.height -= fWidth; - } - m_pVertScrollBar->SetWidgetRect(rtVertScr); - m_pVertScrollBar->Update(); - } - m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, false); - } else if (m_pVertScrollBar) { - m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, true); - } - - if (bShowHorzScrollbar) { - if (!m_pHorzScrollBar) { - if (!pfWidth) { - pfWidth = static_cast<FX_FLOAT*>( - GetThemeCapacity(CFWL_WidgetCapacity::ScrollBarWidth)); - } - - FX_FLOAT fWidth = pfWidth ? *pfWidth : 0; - InitScrollBar(false); - CFX_RectF rtHoriScr; - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) { - rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() + kEditMargin, - m_rtClient.width, fWidth); - } else { - rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() - fWidth, - m_rtClient.width, fWidth); - if (bShowVertScrollbar) - rtHoriScr.width -= (fWidth); - } - m_pHorzScrollBar->SetWidgetRect(rtHoriScr); - m_pHorzScrollBar->Update(); - } - m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, false); - } else if (m_pHorzScrollBar) { - m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, true); - } - if (bShowVertScrollbar || bShowHorzScrollbar) - UpdateScroll(); -} - -void IFWL_Edit::DeviceToEngine(CFX_PointF& pt) { - pt.x += m_fScrollOffsetX - m_rtEngine.left; - pt.y += m_fScrollOffsetY - m_rtEngine.top - m_fVAlignOffset; -} - -void IFWL_Edit::InitScrollBar(bool bVert) { - if ((bVert && m_pVertScrollBar) || (!bVert && m_pHorzScrollBar)) - return; - - auto prop = pdfium::MakeUnique<CFWL_WidgetProperties>(); - prop->m_dwStyleExes = bVert ? FWL_STYLEEXT_SCB_Vert : FWL_STYLEEXT_SCB_Horz; - prop->m_dwStates = FWL_WGTSTATE_Disabled | FWL_WGTSTATE_Invisible; - prop->m_pParent = this; - prop->m_pThemeProvider = m_pProperties->m_pThemeProvider; - - CFWL_ScrollBar* sb = new CFWL_ScrollBar(m_pOwnerApp, std::move(prop), this); - if (bVert) - m_pVertScrollBar.reset(sb); - else - m_pHorzScrollBar.reset(sb); -} - -bool FWL_ShowCaret(IFWL_Widget* pWidget, - bool bVisible, - const CFX_RectF* pRtAnchor) { - CXFA_FFWidget* pXFAWidget = - static_cast<CXFA_FFWidget*>(pWidget->GetLayoutItem()); - if (!pXFAWidget) - return false; - - IXFA_DocEnvironment* pDocEnvironment = - pXFAWidget->GetDoc()->GetDocEnvironment(); - if (!pDocEnvironment) - return false; - - if (bVisible) { - CFX_Matrix mt; - pXFAWidget->GetRotateMatrix(mt); - CFX_RectF rt(*pRtAnchor); - mt.TransformRect(rt); - pDocEnvironment->DisplayCaret(pXFAWidget, bVisible, &rt); - return true; - } - - pDocEnvironment->DisplayCaret(pXFAWidget, bVisible, pRtAnchor); - return true; -} - -void IFWL_Edit::ShowCaret(bool bVisible, CFX_RectF* pRect) { - if (m_pCaret) { - m_pCaret->ShowCaret(bVisible); - if (bVisible && !pRect->IsEmpty()) - m_pCaret->SetWidgetRect(*pRect); - Repaint(&m_rtEngine); - return; - } - - IFWL_Widget* pOuter = this; - if (bVisible) { - pRect->Offset(m_pProperties->m_rtWidget.left, - m_pProperties->m_rtWidget.top); - } - while (pOuter->GetOuter()) { - pOuter = pOuter->GetOuter(); - if (bVisible) { - CFX_RectF rtOuter; - pOuter->GetWidgetRect(rtOuter); - pRect->Offset(rtOuter.left, rtOuter.top); - } - } - FWL_ShowCaret(pOuter, bVisible, pRect); -} - -bool IFWL_Edit::ValidateNumberChar(FX_WCHAR cNum) { - if (!m_bSetRange) - return true; - - CFX_WideString wsOld, wsText; - m_EdtEngine.GetText(wsText, 0); - if (wsText.IsEmpty()) { - if (cNum == L'0') - return false; - return true; - } - - int32_t caretPos = m_EdtEngine.GetCaretPos(); - if (CountSelRanges() == 0) { - if (cNum == L'0' && caretPos == 0) - return false; - - int32_t nLen = wsText.GetLength(); - CFX_WideString l = wsText.Mid(0, caretPos); - CFX_WideString r = wsText.Mid(caretPos, nLen - caretPos); - CFX_WideString wsNew = l + cNum + r; - if (wsNew.GetInteger() <= m_iMax) - return true; - return false; - } - - if (wsText.GetInteger() <= m_iMax) - return true; - return false; -} - -void IFWL_Edit::InitCaret() { - if (!m_pCaret) { - if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_InnerCaret)) { - m_pCaret.reset(new CFWL_Caret( - m_pOwnerApp, pdfium::MakeUnique<CFWL_WidgetProperties>(), this)); - m_pCaret->SetParent(this); - m_pCaret->SetStates(m_pProperties->m_dwStates); - } - } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_InnerCaret) == - 0) { - m_pCaret.reset(); - } -} - -void IFWL_Edit::ClearRecord() { - m_iCurRecord = -1; - m_DoRecords.clear(); -} - -void IFWL_Edit::ProcessInsertError(int32_t iError) { - if (iError != -2) - return; - - CFWL_EvtTextFull textFullEvent; - textFullEvent.m_pSrcTarget = this; - DispatchEvent(&textFullEvent); -} - -void IFWL_Edit::OnProcessMessage(CFWL_Message* pMessage) { - if (!pMessage) - return; - - CFWL_MessageType dwMsgCode = pMessage->GetClassID(); - switch (dwMsgCode) { - case CFWL_MessageType::SetFocus: - case CFWL_MessageType::KillFocus: - OnFocusChanged(pMessage, dwMsgCode == CFWL_MessageType::SetFocus); - break; - case CFWL_MessageType::Mouse: { - CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage); - switch (pMsg->m_dwCmd) { - case FWL_MouseCommand::LeftButtonDown: - OnLButtonDown(pMsg); - break; - case FWL_MouseCommand::LeftButtonUp: - OnLButtonUp(pMsg); - break; - case FWL_MouseCommand::LeftButtonDblClk: - OnButtonDblClk(pMsg); - break; - case FWL_MouseCommand::Move: - OnMouseMove(pMsg); - break; - case FWL_MouseCommand::RightButtonDown: - DoButtonDown(pMsg); - break; - default: - break; - } - break; - } - case CFWL_MessageType::Key: { - CFWL_MsgKey* pKey = static_cast<CFWL_MsgKey*>(pMessage); - if (pKey->m_dwCmd == FWL_KeyCommand::KeyDown) - OnKeyDown(pKey); - else if (pKey->m_dwCmd == FWL_KeyCommand::Char) - OnChar(pKey); - break; - } - default: - break; - } - IFWL_Widget::OnProcessMessage(pMessage); -} - -void IFWL_Edit::OnProcessEvent(CFWL_Event* pEvent) { - if (!pEvent) - return; - if (pEvent->GetClassID() != CFWL_EventType::Scroll) - return; - - IFWL_Widget* pSrcTarget = pEvent->m_pSrcTarget; - if ((pSrcTarget == m_pVertScrollBar.get() && m_pVertScrollBar) || - (pSrcTarget == m_pHorzScrollBar.get() && m_pHorzScrollBar)) { - CFWL_EvtScroll* pScrollEvent = static_cast<CFWL_EvtScroll*>(pEvent); - OnScroll(static_cast<CFWL_ScrollBar*>(pSrcTarget), - pScrollEvent->m_iScrollCode, pScrollEvent->m_fPos); - } -} - -void IFWL_Edit::OnDrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix) { - DrawWidget(pGraphics, pMatrix); -} - -void IFWL_Edit::DoButtonDown(CFWL_MsgMouse* pMsg) { - if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) - SetFocus(true); - - IFDE_TxtEdtPage* pPage = m_EdtEngine.GetPage(0); - if (!pPage) - return; - - CFX_PointF pt(pMsg->m_fx, pMsg->m_fy); - DeviceToEngine(pt); - bool bBefore = true; - int32_t nIndex = pPage->GetCharIndex(pt, bBefore); - if (nIndex < 0) - nIndex = 0; - - m_EdtEngine.SetCaretPos(nIndex, bBefore); -} - -void IFWL_Edit::OnFocusChanged(CFWL_Message* pMsg, bool bSet) { - uint32_t dwStyleEx = GetStylesEx(); - bool bRepaint = !!(dwStyleEx & FWL_STYLEEXT_EDT_InnerCaret); - if (bSet) { - m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused; - - UpdateVAlignment(); - UpdateOffset(); - UpdateCaret(); - } else if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) { - m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused; - ShowCaret(false); - if ((dwStyleEx & FWL_STYLEEXT_EDT_NoHideSel) == 0) { - int32_t nSel = CountSelRanges(); - if (nSel > 0) { - ClearSelections(); - bRepaint = true; - } - m_EdtEngine.SetCaretPos(0, true); - UpdateOffset(); - } - ClearRecord(); - } - - LayoutScrollBar(); - if (!bRepaint) - return; - - CFX_RectF rtInvalidate; - rtInvalidate.Set(0, 0, m_pProperties->m_rtWidget.width, - m_pProperties->m_rtWidget.height); - Repaint(&rtInvalidate); -} - -void IFWL_Edit::OnLButtonDown(CFWL_MsgMouse* pMsg) { - if (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) - return; - - m_bLButtonDown = true; - SetGrab(true); - DoButtonDown(pMsg); - int32_t nIndex = m_EdtEngine.GetCaretPos(); - bool bRepaint = false; - if (m_EdtEngine.CountSelRanges() > 0) { - m_EdtEngine.ClearSelection(); - bRepaint = true; - } - - if ((pMsg->m_dwFlags & FWL_KEYFLAG_Shift) && m_nSelStart != nIndex) { - int32_t iStart = std::min(m_nSelStart, nIndex); - int32_t iEnd = std::max(m_nSelStart, nIndex); - m_EdtEngine.AddSelRange(iStart, iEnd - iStart); - bRepaint = true; - } else { - m_nSelStart = nIndex; - } - if (bRepaint) - Repaint(&m_rtEngine); -} - -void IFWL_Edit::OnLButtonUp(CFWL_MsgMouse* pMsg) { - m_bLButtonDown = false; - SetGrab(false); -} - -void IFWL_Edit::OnButtonDblClk(CFWL_MsgMouse* pMsg) { - IFDE_TxtEdtPage* pPage = m_EdtEngine.GetPage(0); - if (!pPage) - return; - - CFX_PointF pt(pMsg->m_fx, pMsg->m_fy); - DeviceToEngine(pt); - int32_t nCount = 0; - int32_t nIndex = pPage->SelectWord(pt, nCount); - if (nIndex < 0) - return; - - m_EdtEngine.AddSelRange(nIndex, nCount); - m_EdtEngine.SetCaretPos(nIndex + nCount - 1, false); - Repaint(&m_rtEngine); -} - -void IFWL_Edit::OnMouseMove(CFWL_MsgMouse* pMsg) { - if (m_nSelStart == -1 || !m_bLButtonDown) - return; - - IFDE_TxtEdtPage* pPage = m_EdtEngine.GetPage(0); - if (!pPage) - return; - - CFX_PointF pt(pMsg->m_fx, pMsg->m_fy); - DeviceToEngine(pt); - bool bBefore = true; - int32_t nIndex = pPage->GetCharIndex(pt, bBefore); - m_EdtEngine.SetCaretPos(nIndex, bBefore); - nIndex = m_EdtEngine.GetCaretPos(); - m_EdtEngine.ClearSelection(); - - if (nIndex == m_nSelStart) - return; - - int32_t nLen = m_EdtEngine.GetTextLength(); - if (m_nSelStart >= nLen) - m_nSelStart = nLen; - - m_EdtEngine.AddSelRange(std::min(m_nSelStart, nIndex), - FXSYS_abs(nIndex - m_nSelStart)); -} - -void IFWL_Edit::OnKeyDown(CFWL_MsgKey* pMsg) { - FDE_TXTEDTMOVECARET MoveCaret = MC_MoveNone; - bool bShift = !!(pMsg->m_dwFlags & FWL_KEYFLAG_Shift); - bool bCtrl = !!(pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl); - uint32_t dwKeyCode = pMsg->m_dwKeyCode; - switch (dwKeyCode) { - case FWL_VKEY_Left: { - MoveCaret = MC_Left; - break; - } - case FWL_VKEY_Right: { - MoveCaret = MC_Right; - break; - } - case FWL_VKEY_Up: { - MoveCaret = MC_Up; - break; - } - case FWL_VKEY_Down: { - MoveCaret = MC_Down; - break; - } - case FWL_VKEY_Home: { - MoveCaret = bCtrl ? MC_Home : MC_LineStart; - break; - } - case FWL_VKEY_End: { - MoveCaret = bCtrl ? MC_End : MC_LineEnd; - break; - } - case FWL_VKEY_Insert: - break; - case FWL_VKEY_Delete: { - if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly) || - (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) { - break; - } - int32_t nCaret = m_EdtEngine.GetCaretPos(); -#if (_FX_OS_ == _FX_MACOSX_) - m_EdtEngine.Delete(nCaret, true); -#else - m_EdtEngine.Delete(nCaret); -#endif - break; - } - case FWL_VKEY_F2: - break; - case FWL_VKEY_Tab: { - DispatchKeyEvent(pMsg); - break; - } - default: - break; - } - if (MoveCaret != MC_MoveNone) - m_EdtEngine.MoveCaretPos(MoveCaret, bShift, bCtrl); -} - -void IFWL_Edit::OnChar(CFWL_MsgKey* pMsg) { - if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly) || - (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) { - return; - } - - int32_t iError = 0; - FX_WCHAR c = static_cast<FX_WCHAR>(pMsg->m_dwKeyCode); - int32_t nCaret = m_EdtEngine.GetCaretPos(); - switch (c) { - case FWL_VKEY_Back: - m_EdtEngine.Delete(nCaret, true); - break; - case FWL_VKEY_NewLine: - case FWL_VKEY_Escape: - break; - case FWL_VKEY_Tab: { - iError = m_EdtEngine.Insert(nCaret, L"\t", 1); - break; - } - case FWL_VKEY_Return: { - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_WantReturn) { - iError = m_EdtEngine.Insert(nCaret, L"\n", 1); - } - break; - } - default: { - if (!m_pWidgetMgr->IsFormDisabled()) { - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_Number) { - if (((pMsg->m_dwKeyCode < FWL_VKEY_0) && - (pMsg->m_dwKeyCode != 0x2E && pMsg->m_dwKeyCode != 0x2D)) || - pMsg->m_dwKeyCode > FWL_VKEY_9) { - break; - } - if (!ValidateNumberChar(c)) - break; - } - } -#if (_FX_OS_ == _FX_MACOSX_) - if (pMsg->m_dwFlags & FWL_KEYFLAG_Command) -#else - if (pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl) -#endif - { - break; - } - iError = m_EdtEngine.Insert(nCaret, &c, 1); - break; - } - } - if (iError < 0) - ProcessInsertError(iError); -} - -bool IFWL_Edit::OnScroll(CFWL_ScrollBar* pScrollBar, - FWL_SCBCODE dwCode, - FX_FLOAT fPos) { - CFX_SizeF fs; - pScrollBar->GetRange(&fs.x, &fs.y); - FX_FLOAT iCurPos = pScrollBar->GetPos(); - FX_FLOAT fStep = pScrollBar->GetStepSize(); - switch (dwCode) { - case FWL_SCBCODE::Min: { - fPos = fs.x; - break; - } - case FWL_SCBCODE::Max: { - fPos = fs.y; - break; - } - case FWL_SCBCODE::StepBackward: { - fPos -= fStep; - if (fPos < fs.x + fStep / 2) { - fPos = fs.x; - } - break; - } - case FWL_SCBCODE::StepForward: { - fPos += fStep; - if (fPos > fs.y - fStep / 2) { - fPos = fs.y; - } - break; - } - case FWL_SCBCODE::PageBackward: { - fPos -= pScrollBar->GetPageSize(); - if (fPos < fs.x) { - fPos = fs.x; - } - break; - } - case FWL_SCBCODE::PageForward: { - fPos += pScrollBar->GetPageSize(); - if (fPos > fs.y) { - fPos = fs.y; - } - break; - } - case FWL_SCBCODE::Pos: - case FWL_SCBCODE::TrackPos: - case FWL_SCBCODE::None: - break; - case FWL_SCBCODE::EndScroll: - return false; - } - if (iCurPos == fPos) - return true; - - pScrollBar->SetPos(fPos); - pScrollBar->SetTrackPos(fPos); - UpdateOffset(pScrollBar, fPos - iCurPos); - UpdateCaret(); - - CFX_RectF rect; - GetWidgetRect(rect); - CFX_RectF rtInvalidate; - rtInvalidate.Set(0, 0, rect.width + 2, rect.height + 2); - Repaint(&rtInvalidate); - return true; -} diff --git a/xfa/fwl/core/ifwl_edit.h b/xfa/fwl/core/ifwl_edit.h deleted file mode 100644 index 8b217fa45d..0000000000 --- a/xfa/fwl/core/ifwl_edit.h +++ /dev/null @@ -1,197 +0,0 @@ -// 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 - -#ifndef XFA_FWL_CORE_IFWL_EDIT_H_ -#define XFA_FWL_CORE_IFWL_EDIT_H_ - -#include <deque> -#include <memory> -#include <vector> - -#include "xfa/fde/cfde_txtedtengine.h" -#include "xfa/fde/ifde_txtedtdorecord.h" -#include "xfa/fwl/core/cfwl_event.h" -#include "xfa/fwl/core/cfwl_scrollbar.h" -#include "xfa/fwl/core/cfwl_widget.h" -#include "xfa/fwl/core/ifwl_widget.h" -#include "xfa/fxgraphics/cfx_path.h" - -#define FWL_STYLEEXT_EDT_ReadOnly (1L << 0) -#define FWL_STYLEEXT_EDT_MultiLine (1L << 1) -#define FWL_STYLEEXT_EDT_WantReturn (1L << 2) -#define FWL_STYLEEXT_EDT_NoHideSel (1L << 3) -#define FWL_STYLEEXT_EDT_AutoHScroll (1L << 4) -#define FWL_STYLEEXT_EDT_AutoVScroll (1L << 5) -#define FWL_STYLEEXT_EDT_NoRedoUndo (1L << 6) -#define FWL_STYLEEXT_EDT_Validate (1L << 7) -#define FWL_STYLEEXT_EDT_Password (1L << 8) -#define FWL_STYLEEXT_EDT_Number (1L << 9) -#define FWL_STYLEEXT_EDT_VerticalLayout (1L << 12) -#define FWL_STYLEEXT_EDT_VerticalChars (1L << 13) -#define FWL_STYLEEXT_EDT_ReverseLine (1L << 14) -#define FWL_STYLEEXT_EDT_ArabicShapes (1L << 15) -#define FWL_STYLEEXT_EDT_ExpandTab (1L << 16) -#define FWL_STYLEEXT_EDT_CombText (1L << 17) -#define FWL_STYLEEXT_EDT_HNear (0L << 18) -#define FWL_STYLEEXT_EDT_HCenter (1L << 18) -#define FWL_STYLEEXT_EDT_HFar (2L << 18) -#define FWL_STYLEEXT_EDT_VNear (0L << 20) -#define FWL_STYLEEXT_EDT_VCenter (1L << 20) -#define FWL_STYLEEXT_EDT_VFar (2L << 20) -#define FWL_STYLEEXT_EDT_Justified (1L << 22) -#define FWL_STYLEEXT_EDT_Distributed (2L << 22) -#define FWL_STYLEEXT_EDT_HAlignMask (3L << 18) -#define FWL_STYLEEXT_EDT_VAlignMask (3L << 20) -#define FWL_STYLEEXT_EDT_HAlignModeMask (3L << 22) -#define FWL_STYLEEXT_EDT_InnerCaret (1L << 24) -#define FWL_STYLEEXT_EDT_ShowScrollbarFocus (1L << 25) -#define FWL_STYLEEXT_EDT_OuterScrollbar (1L << 26) -#define FWL_STYLEEXT_EDT_LastLineHeight (1L << 27) - -class IFDE_TxtEdtDoRecord; -class IFWL_Edit; -class CFWL_MsgMouse; -class CFWL_WidgetProperties; -class CFWL_Caret; - -class IFWL_Edit : public IFWL_Widget { - public: - IFWL_Edit(const CFWL_App* app, - std::unique_ptr<CFWL_WidgetProperties> properties, - IFWL_Widget* pOuter); - ~IFWL_Edit() override; - - // IFWL_Widget: - FWL_Type GetClassID() const override; - void GetWidgetRect(CFX_RectF& rect, bool bAutoSize = false) override; - void Update() override; - FWL_WidgetHit HitTest(FX_FLOAT fx, FX_FLOAT fy) override; - void SetStates(uint32_t dwStates, bool bSet = true) override; - void DrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix = nullptr) override; - void SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) override; - void OnProcessMessage(CFWL_Message* pMessage) override; - void OnProcessEvent(CFWL_Event* pEvent) override; - void OnDrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix) override; - - virtual void SetText(const CFX_WideString& wsText); - - int32_t GetTextLength() const; - void GetText(CFX_WideString& wsText, - int32_t nStart = 0, - int32_t nCount = -1) const; - void ClearText(); - - void AddSelRange(int32_t nStart, int32_t nCount = -1); - int32_t CountSelRanges() const; - int32_t GetSelRange(int32_t nIndex, int32_t& nStart) const; - void ClearSelections(); - int32_t GetLimit() const; - void SetLimit(int32_t nLimit); - void SetAliasChar(FX_WCHAR wAlias); - bool Copy(CFX_WideString& wsCopy); - bool Cut(CFX_WideString& wsCut); - bool Paste(const CFX_WideString& wsPaste); - bool Redo(const IFDE_TxtEdtDoRecord* pRecord); - bool Undo(const IFDE_TxtEdtDoRecord* pRecord); - bool Undo(); - bool Redo(); - bool CanUndo(); - bool CanRedo(); - - void SetOuter(IFWL_Widget* pOuter); - - void On_CaretChanged(CFDE_TxtEdtEngine* pEdit, - int32_t nPage, - bool bVisible = true); - void On_TextChanged(CFDE_TxtEdtEngine* pEdit, - FDE_TXTEDT_TEXTCHANGE_INFO& ChangeInfo); - void On_SelChanged(CFDE_TxtEdtEngine* pEdit); - bool On_PageLoad(CFDE_TxtEdtEngine* pEdit, - int32_t nPageIndex, - int32_t nPurpose); - bool On_PageUnload(CFDE_TxtEdtEngine* pEdit, - int32_t nPageIndex, - int32_t nPurpose); - void On_AddDoRecord(CFDE_TxtEdtEngine* pEdit, IFDE_TxtEdtDoRecord* pRecord); - bool On_Validate(CFDE_TxtEdtEngine* pEdit, CFX_WideString& wsText); - void SetScrollOffset(FX_FLOAT fScrollOffset); - - protected: - void ShowCaret(bool bVisible, CFX_RectF* pRect = nullptr); - const CFX_RectF& GetRTClient() const { return m_rtClient; } - CFDE_TxtEdtEngine* GetTxtEdtEngine() { return &m_EdtEngine; } - - private: - void DrawTextBk(CFX_Graphics* pGraphics, - IFWL_ThemeProvider* pTheme, - const CFX_Matrix* pMatrix = nullptr); - void DrawContent(CFX_Graphics* pGraphics, - IFWL_ThemeProvider* pTheme, - const CFX_Matrix* pMatrix = nullptr); - void UpdateEditEngine(); - void UpdateEditParams(); - void UpdateEditLayout(); - bool UpdateOffset(); - bool UpdateOffset(CFWL_ScrollBar* pScrollBar, FX_FLOAT fPosChanged); - void UpdateVAlignment(); - void UpdateCaret(); - CFWL_ScrollBar* UpdateScroll(); - void Layout(); - void LayoutScrollBar(); - void DeviceToEngine(CFX_PointF& pt); - void InitScrollBar(bool bVert = true); - void InitEngine(); - bool ValidateNumberChar(FX_WCHAR cNum); - void InitCaret(); - void ClearRecord(); - bool IsShowScrollBar(bool bVert); - bool IsContentHeightOverflow(); - int32_t AddDoRecord(IFDE_TxtEdtDoRecord* pRecord); - void ProcessInsertError(int32_t iError); - - void DrawSpellCheck(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix = nullptr); - void AddSpellCheckObj(CFX_Path& PathData, - int32_t nStart, - int32_t nCount, - FX_FLOAT fOffSetX, - FX_FLOAT fOffSetY); - void DoButtonDown(CFWL_MsgMouse* pMsg); - void OnFocusChanged(CFWL_Message* pMsg, bool bSet); - void OnLButtonDown(CFWL_MsgMouse* pMsg); - void OnLButtonUp(CFWL_MsgMouse* pMsg); - void OnButtonDblClk(CFWL_MsgMouse* pMsg); - void OnMouseMove(CFWL_MsgMouse* pMsg); - void OnKeyDown(CFWL_MsgKey* pMsg); - void OnChar(CFWL_MsgKey* pMsg); - bool OnScroll(CFWL_ScrollBar* pScrollBar, FWL_SCBCODE dwCode, FX_FLOAT fPos); - - CFX_RectF m_rtClient; - CFX_RectF m_rtEngine; - CFX_RectF m_rtStatic; - FX_FLOAT m_fVAlignOffset; - FX_FLOAT m_fScrollOffsetX; - FX_FLOAT m_fScrollOffsetY; - CFDE_TxtEdtEngine m_EdtEngine; - bool m_bLButtonDown; - int32_t m_nSelStart; - int32_t m_nLimit; - FX_FLOAT m_fFontSize; - bool m_bSetRange; - int32_t m_iMax; - std::unique_ptr<CFWL_ScrollBar> m_pVertScrollBar; - std::unique_ptr<CFWL_ScrollBar> m_pHorzScrollBar; - std::unique_ptr<CFWL_Caret> m_pCaret; - CFX_WideString m_wsCache; - CFX_WideString m_wsFont; - std::deque<std::unique_ptr<IFDE_TxtEdtDoRecord>> m_DoRecords; - int32_t m_iCurRecord; - int32_t m_iMaxRecord; -}; - -#endif // XFA_FWL_CORE_IFWL_EDIT_H_ diff --git a/xfa/fwl/core/ifwl_listbox.cpp b/xfa/fwl/core/ifwl_listbox.cpp deleted file mode 100644 index 6186e64a4b..0000000000 --- a/xfa/fwl/core/ifwl_listbox.cpp +++ /dev/null @@ -1,1126 +0,0 @@ -// 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_listbox.h" - -#include <algorithm> -#include <memory> -#include <utility> - -#include "third_party/base/ptr_util.h" -#include "third_party/base/stl_util.h" -#include "xfa/fde/tto/fde_textout.h" -#include "xfa/fwl/core/cfwl_app.h" -#include "xfa/fwl/core/cfwl_msgkey.h" -#include "xfa/fwl/core/cfwl_msgmouse.h" -#include "xfa/fwl/core/cfwl_msgmousewheel.h" -#include "xfa/fwl/core/cfwl_themebackground.h" -#include "xfa/fwl/core/cfwl_themepart.h" -#include "xfa/fwl/core/cfwl_themetext.h" -#include "xfa/fwl/core/ifwl_themeprovider.h" - -namespace { - -const int kItemTextMargin = 2; - -} // namespace - -IFWL_ListBox::IFWL_ListBox(const CFWL_App* app, - std::unique_ptr<CFWL_WidgetProperties> properties, - IFWL_Widget* pOuter) - : IFWL_Widget(app, std::move(properties), pOuter), - m_dwTTOStyles(0), - m_iTTOAligns(0), - m_hAnchor(nullptr), - m_fScorllBarWidth(0), - m_bLButtonDown(false), - m_pScrollBarTP(nullptr) { - m_rtClient.Reset(); - m_rtConent.Reset(); - m_rtStatic.Reset(); -} - -IFWL_ListBox::~IFWL_ListBox() {} - -FWL_Type IFWL_ListBox::GetClassID() const { - return FWL_Type::ListBox; -} - -void IFWL_ListBox::GetWidgetRect(CFX_RectF& rect, bool bAutoSize) { - if (!bAutoSize) { - rect = m_pProperties->m_rtWidget; - return; - } - - rect.Set(0, 0, 0, 0); - if (!m_pProperties->m_pThemeProvider) - m_pProperties->m_pThemeProvider = GetAvailableTheme(); - - CFX_SizeF fs = CalcSize(true); - rect.Set(0, 0, fs.x, fs.y); - IFWL_Widget::GetWidgetRect(rect, true); -} - -void IFWL_ListBox::Update() { - if (IsLocked()) - return; - if (!m_pProperties->m_pThemeProvider) - m_pProperties->m_pThemeProvider = GetAvailableTheme(); - - switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_AlignMask) { - case FWL_STYLEEXT_LTB_LeftAlign: { - m_iTTOAligns = FDE_TTOALIGNMENT_CenterLeft; - break; - } - case FWL_STYLEEXT_LTB_RightAlign: { - m_iTTOAligns = FDE_TTOALIGNMENT_CenterRight; - break; - } - case FWL_STYLEEXT_LTB_CenterAlign: - default: { - m_iTTOAligns = FDE_TTOALIGNMENT_Center; - break; - } - } - if (m_pProperties->m_dwStyleExes & FWL_WGTSTYLE_RTLReading) - m_dwTTOStyles |= FDE_TTOSTYLE_RTL; - - m_dwTTOStyles |= FDE_TTOSTYLE_SingleLine; - m_fScorllBarWidth = GetScrollWidth(); - CalcSize(); -} - -FWL_WidgetHit IFWL_ListBox::HitTest(FX_FLOAT fx, FX_FLOAT fy) { - if (IsShowScrollBar(false)) { - CFX_RectF rect; - m_pHorzScrollBar->GetWidgetRect(rect); - if (rect.Contains(fx, fy)) - return FWL_WidgetHit::HScrollBar; - } - if (IsShowScrollBar(true)) { - CFX_RectF rect; - m_pVertScrollBar->GetWidgetRect(rect); - if (rect.Contains(fx, fy)) - return FWL_WidgetHit::VScrollBar; - } - if (m_rtClient.Contains(fx, fy)) - return FWL_WidgetHit::Client; - return FWL_WidgetHit::Unknown; -} - -void IFWL_ListBox::DrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix) { - if (!pGraphics) - return; - if (!m_pProperties->m_pThemeProvider) - return; - - IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider; - pGraphics->SaveGraphState(); - if (HasBorder()) - DrawBorder(pGraphics, CFWL_Part::Border, pTheme, pMatrix); - if (HasEdge()) - DrawEdge(pGraphics, CFWL_Part::Edge, pTheme, pMatrix); - - CFX_RectF rtClip(m_rtConent); - if (IsShowScrollBar(false)) - rtClip.height -= m_fScorllBarWidth; - if (IsShowScrollBar(true)) - rtClip.width -= m_fScorllBarWidth; - if (pMatrix) - pMatrix->TransformRect(rtClip); - - pGraphics->SetClipRect(rtClip); - if ((m_pProperties->m_dwStyles & FWL_WGTSTYLE_NoBackground) == 0) - DrawBkground(pGraphics, pTheme, pMatrix); - - DrawItems(pGraphics, pTheme, pMatrix); - pGraphics->RestoreGraphState(); -} - -void IFWL_ListBox::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) { - if (pThemeProvider) - m_pProperties->m_pThemeProvider = pThemeProvider; -} - -int32_t IFWL_ListBox::CountSelItems() { - int32_t iRet = 0; - int32_t iCount = CountItems(this); - for (int32_t i = 0; i < iCount; i++) { - CFWL_ListItem* pItem = GetItem(this, i); - if (!pItem) - continue; - - uint32_t dwStyle = GetItemStyles(this, pItem); - if (dwStyle & FWL_ITEMSTATE_LTB_Selected) - iRet++; - } - return iRet; -} - -CFWL_ListItem* IFWL_ListBox::GetSelItem(int32_t nIndexSel) { - int32_t idx = GetSelIndex(nIndexSel); - if (idx < 0) - return nullptr; - return GetItem(this, idx); -} - -int32_t IFWL_ListBox::GetSelIndex(int32_t nIndex) { - int32_t index = 0; - int32_t iCount = CountItems(this); - for (int32_t i = 0; i < iCount; i++) { - CFWL_ListItem* pItem = GetItem(this, i); - if (!pItem) - return -1; - - uint32_t dwStyle = GetItemStyles(this, pItem); - if (dwStyle & FWL_ITEMSTATE_LTB_Selected) { - if (index == nIndex) - return i; - index++; - } - } - return -1; -} - -void IFWL_ListBox::SetSelItem(CFWL_ListItem* pItem, bool bSelect) { - if (!pItem) { - if (bSelect) { - SelectAll(); - } else { - ClearSelection(); - SetFocusItem(nullptr); - } - return; - } - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiSelection) - SetSelectionDirect(pItem, bSelect); - else - SetSelection(pItem, pItem, bSelect); -} - -void IFWL_ListBox::GetDataProviderItemText(CFWL_ListItem* pItem, - CFX_WideString& wsText) { - if (!pItem) - return; - GetItemText(this, pItem, wsText); -} - -CFWL_ListItem* IFWL_ListBox::GetListItem(CFWL_ListItem* pItem, - uint32_t dwKeyCode) { - CFWL_ListItem* hRet = nullptr; - switch (dwKeyCode) { - case FWL_VKEY_Up: - case FWL_VKEY_Down: - case FWL_VKEY_Home: - case FWL_VKEY_End: { - const bool bUp = dwKeyCode == FWL_VKEY_Up; - const bool bDown = dwKeyCode == FWL_VKEY_Down; - const bool bHome = dwKeyCode == FWL_VKEY_Home; - int32_t iDstItem = -1; - if (bUp || bDown) { - int32_t index = GetItemIndex(this, pItem); - iDstItem = dwKeyCode == FWL_VKEY_Up ? index - 1 : index + 1; - } else if (bHome) { - iDstItem = 0; - } else { - int32_t iCount = CountItems(this); - iDstItem = iCount - 1; - } - hRet = GetItem(this, iDstItem); - break; - } - default: - break; - } - return hRet; -} - -void IFWL_ListBox::SetSelection(CFWL_ListItem* hStart, - CFWL_ListItem* hEnd, - bool bSelected) { - int32_t iStart = GetItemIndex(this, hStart); - int32_t iEnd = GetItemIndex(this, hEnd); - if (iStart > iEnd) { - int32_t iTemp = iStart; - iStart = iEnd; - iEnd = iTemp; - } - if (bSelected) { - int32_t iCount = CountItems(this); - for (int32_t i = 0; i < iCount; i++) { - CFWL_ListItem* pItem = GetItem(this, i); - SetSelectionDirect(pItem, false); - } - } - for (; iStart <= iEnd; iStart++) { - CFWL_ListItem* pItem = GetItem(this, iStart); - SetSelectionDirect(pItem, bSelected); - } -} - -void IFWL_ListBox::SetSelectionDirect(CFWL_ListItem* pItem, bool bSelect) { - uint32_t dwOldStyle = GetItemStyles(this, pItem); - bSelect ? dwOldStyle |= FWL_ITEMSTATE_LTB_Selected - : dwOldStyle &= ~FWL_ITEMSTATE_LTB_Selected; - SetItemStyles(this, pItem, dwOldStyle); -} - -bool IFWL_ListBox::IsItemSelected(CFWL_ListItem* pItem) { - uint32_t dwState = GetItemStyles(this, pItem); - return (dwState & FWL_ITEMSTATE_LTB_Selected) != 0; -} - -void IFWL_ListBox::ClearSelection() { - bool bMulti = m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiSelection; - int32_t iCount = CountItems(this); - for (int32_t i = 0; i < iCount; i++) { - CFWL_ListItem* pItem = GetItem(this, i); - uint32_t dwState = GetItemStyles(this, pItem); - if (!(dwState & FWL_ITEMSTATE_LTB_Selected)) - continue; - SetSelectionDirect(pItem, false); - if (!bMulti) - return; - } -} - -void IFWL_ListBox::SelectAll() { - if (!m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiSelection) - return; - - int32_t iCount = CountItems(this); - if (iCount <= 0) - return; - - CFWL_ListItem* pItemStart = GetItem(this, 0); - CFWL_ListItem* pItemEnd = GetItem(this, iCount - 1); - SetSelection(pItemStart, pItemEnd, false); -} - -CFWL_ListItem* IFWL_ListBox::GetFocusedItem() { - int32_t iCount = CountItems(this); - for (int32_t i = 0; i < iCount; i++) { - CFWL_ListItem* pItem = GetItem(this, i); - if (!pItem) - return nullptr; - if (GetItemStyles(this, pItem) & FWL_ITEMSTATE_LTB_Focused) - return pItem; - } - return nullptr; -} - -void IFWL_ListBox::SetFocusItem(CFWL_ListItem* pItem) { - CFWL_ListItem* hFocus = GetFocusedItem(); - if (pItem == hFocus) - return; - - if (hFocus) { - uint32_t dwStyle = GetItemStyles(this, hFocus); - dwStyle &= ~FWL_ITEMSTATE_LTB_Focused; - SetItemStyles(this, hFocus, dwStyle); - } - if (pItem) { - uint32_t dwStyle = GetItemStyles(this, pItem); - dwStyle |= FWL_ITEMSTATE_LTB_Focused; - SetItemStyles(this, pItem, dwStyle); - } -} - -CFWL_ListItem* IFWL_ListBox::GetItemAtPoint(FX_FLOAT fx, FX_FLOAT fy) { - fx -= m_rtConent.left, fy -= m_rtConent.top; - FX_FLOAT fPosX = 0.0f; - if (m_pHorzScrollBar) - fPosX = m_pHorzScrollBar->GetPos(); - - FX_FLOAT fPosY = 0.0; - if (m_pVertScrollBar) - fPosY = m_pVertScrollBar->GetPos(); - - int32_t nCount = CountItems(this); - for (int32_t i = 0; i < nCount; i++) { - CFWL_ListItem* pItem = GetItem(this, i); - if (!pItem) - continue; - - CFX_RectF rtItem; - GetItemRect(this, pItem, rtItem); - rtItem.Offset(-fPosX, -fPosY); - if (rtItem.Contains(fx, fy)) - return pItem; - } - return nullptr; -} - -bool IFWL_ListBox::GetItemCheckRectInternal(CFWL_ListItem* pItem, - CFX_RectF& rtCheck) { - if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_Check)) - return false; - GetItemCheckRect(this, pItem, rtCheck); - return true; -} - -bool IFWL_ListBox::GetItemChecked(CFWL_ListItem* pItem) { - if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_Check)) - return false; - return !!(GetItemCheckState(this, pItem) & FWL_ITEMSTATE_LTB_Checked); -} - -bool IFWL_ListBox::SetItemChecked(CFWL_ListItem* pItem, bool bChecked) { - if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_Check)) - return false; - - SetItemCheckState(this, pItem, bChecked ? FWL_ITEMSTATE_LTB_Checked : 0); - return true; -} - -bool IFWL_ListBox::ScrollToVisible(CFWL_ListItem* pItem) { - if (!m_pVertScrollBar) - return false; - - CFX_RectF rtItem; - GetItemRect(this, pItem, rtItem); - - bool bScroll = false; - FX_FLOAT fPosY = m_pVertScrollBar->GetPos(); - rtItem.Offset(0, -fPosY + m_rtConent.top); - if (rtItem.top < m_rtConent.top) { - fPosY += rtItem.top - m_rtConent.top; - bScroll = true; - } else if (rtItem.bottom() > m_rtConent.bottom()) { - fPosY += rtItem.bottom() - m_rtConent.bottom(); - bScroll = true; - } - if (!bScroll) - return false; - - m_pVertScrollBar->SetPos(fPosY); - m_pVertScrollBar->SetTrackPos(fPosY); - Repaint(&m_rtClient); - return true; -} - -void IFWL_ListBox::DrawBkground(CFX_Graphics* pGraphics, - IFWL_ThemeProvider* pTheme, - const CFX_Matrix* pMatrix) { - if (!pGraphics) - return; - if (!pTheme) - return; - - CFWL_ThemeBackground param; - param.m_pWidget = this; - param.m_iPart = CFWL_Part::Background; - param.m_dwStates = 0; - param.m_pGraphics = pGraphics; - param.m_matrix.Concat(*pMatrix); - param.m_rtPart = m_rtClient; - if (IsShowScrollBar(false) && IsShowScrollBar(true)) - param.m_pData = &m_rtStatic; - if (!IsEnabled()) - param.m_dwStates = CFWL_PartState_Disabled; - - pTheme->DrawBackground(¶m); -} - -void IFWL_ListBox::DrawItems(CFX_Graphics* pGraphics, - IFWL_ThemeProvider* pTheme, - const CFX_Matrix* pMatrix) { - FX_FLOAT fPosX = 0.0f; - if (m_pHorzScrollBar) - fPosX = m_pHorzScrollBar->GetPos(); - - FX_FLOAT fPosY = 0.0f; - if (m_pVertScrollBar) - fPosY = m_pVertScrollBar->GetPos(); - - CFX_RectF rtView(m_rtConent); - if (m_pHorzScrollBar) - rtView.height -= m_fScorllBarWidth; - if (m_pVertScrollBar) - rtView.width -= m_fScorllBarWidth; - - bool bMultiCol = - !!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiColumn); - int32_t iCount = CountItems(this); - for (int32_t i = 0; i < iCount; i++) { - CFWL_ListItem* pItem = GetItem(this, i); - if (!pItem) - continue; - - CFX_RectF rtItem; - GetItemRect(this, pItem, rtItem); - rtItem.Offset(m_rtConent.left - fPosX, m_rtConent.top - fPosY); - if (rtItem.bottom() < m_rtConent.top) - continue; - if (rtItem.top >= m_rtConent.bottom()) - break; - if (bMultiCol && rtItem.left > m_rtConent.right()) - break; - - if (!(GetStylesEx() & FWL_STYLEEXT_LTB_OwnerDraw)) - DrawItem(pGraphics, pTheme, pItem, i, rtItem, pMatrix); - } -} - -void IFWL_ListBox::DrawItem(CFX_Graphics* pGraphics, - IFWL_ThemeProvider* pTheme, - CFWL_ListItem* pItem, - int32_t Index, - const CFX_RectF& rtItem, - const CFX_Matrix* pMatrix) { - uint32_t dwItemStyles = GetItemStyles(this, pItem); - uint32_t dwPartStates = CFWL_PartState_Normal; - if (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) - dwPartStates = CFWL_PartState_Disabled; - else if (dwItemStyles & FWL_ITEMSTATE_LTB_Selected) - dwPartStates = CFWL_PartState_Selected; - - if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused && - dwItemStyles & FWL_ITEMSTATE_LTB_Focused) { - dwPartStates |= CFWL_PartState_Focused; - } - - CFWL_ThemeBackground bg_param; - bg_param.m_pWidget = this; - bg_param.m_iPart = CFWL_Part::ListItem; - bg_param.m_dwStates = dwPartStates; - bg_param.m_pGraphics = pGraphics; - bg_param.m_matrix.Concat(*pMatrix); - bg_param.m_rtPart = rtItem; - bg_param.m_bMaximize = true; - CFX_RectF rtFocus(rtItem); - bg_param.m_pData = &rtFocus; - if (m_pVertScrollBar && !m_pHorzScrollBar && - (dwPartStates & CFWL_PartState_Focused)) { - bg_param.m_rtPart.left += 1; - bg_param.m_rtPart.width -= (m_fScorllBarWidth + 1); - rtFocus.Deflate(0.5, 0.5, 1 + m_fScorllBarWidth, 1); - } - pTheme->DrawBackground(&bg_param); - - bool bHasIcon = !!(GetStylesEx() & FWL_STYLEEXT_LTB_Icon); - if (bHasIcon) { - CFX_RectF rtDIB; - CFX_DIBitmap* pDib = GetItemIcon(this, pItem); - rtDIB.Set(rtItem.left, rtItem.top, rtItem.height, rtItem.height); - if (pDib) { - CFWL_ThemeBackground param; - param.m_pWidget = this; - param.m_iPart = CFWL_Part::Icon; - param.m_pGraphics = pGraphics; - param.m_matrix.Concat(*pMatrix); - param.m_rtPart = rtDIB; - param.m_bMaximize = true; - param.m_pImage = pDib; - pTheme->DrawBackground(¶m); - } - } - - bool bHasCheck = !!(GetStylesEx() & FWL_STYLEEXT_LTB_Check); - if (bHasCheck) { - CFX_RectF rtCheck; - rtCheck.Set(rtItem.left, rtItem.top, rtItem.height, rtItem.height); - rtCheck.Deflate(2, 2, 2, 2); - SetItemCheckRect(this, pItem, rtCheck); - CFWL_ThemeBackground param; - param.m_pWidget = this; - param.m_iPart = CFWL_Part::Check; - param.m_pGraphics = pGraphics; - if (GetItemChecked(pItem)) - param.m_dwStates = CFWL_PartState_Checked; - else - param.m_dwStates = CFWL_PartState_Normal; - param.m_matrix.Concat(*pMatrix); - param.m_rtPart = rtCheck; - param.m_bMaximize = true; - pTheme->DrawBackground(¶m); - } - - CFX_WideString wsText; - GetItemText(this, pItem, wsText); - if (wsText.GetLength() <= 0) - return; - - CFX_RectF rtText(rtItem); - rtText.Deflate(kItemTextMargin, kItemTextMargin); - if (bHasIcon || bHasCheck) - rtText.Deflate(rtItem.height, 0, 0, 0); - - CFWL_ThemeText textParam; - textParam.m_pWidget = this; - textParam.m_iPart = CFWL_Part::ListItem; - textParam.m_dwStates = dwPartStates; - textParam.m_pGraphics = pGraphics; - textParam.m_matrix.Concat(*pMatrix); - textParam.m_rtPart = rtText; - textParam.m_wsText = wsText; - textParam.m_dwTTOStyles = m_dwTTOStyles; - textParam.m_iTTOAlign = m_iTTOAligns; - textParam.m_bMaximize = true; - pTheme->DrawText(&textParam); -} - -CFX_SizeF IFWL_ListBox::CalcSize(bool bAutoSize) { - CFX_SizeF fs; - if (!m_pProperties->m_pThemeProvider) - return fs; - - GetClientRect(m_rtClient); - m_rtConent = m_rtClient; - CFX_RectF rtUIMargin; - rtUIMargin.Set(0, 0, 0, 0); - if (!m_pOuter) { - CFX_RectF* pUIMargin = static_cast<CFX_RectF*>( - GetThemeCapacity(CFWL_WidgetCapacity::UIMargin)); - if (pUIMargin) { - m_rtConent.Deflate(pUIMargin->left, pUIMargin->top, pUIMargin->width, - pUIMargin->height); - } - } - - FX_FLOAT fWidth = GetMaxTextWidth(); - fWidth += 2 * kItemTextMargin; - if (!bAutoSize) { - FX_FLOAT fActualWidth = - m_rtClient.width - rtUIMargin.left - rtUIMargin.width; - fWidth = std::max(fWidth, fActualWidth); - } - - m_fItemHeight = CalcItemHeight(); - if ((GetStylesEx() & FWL_STYLEEXT_LTB_Icon)) - fWidth += m_fItemHeight; - - int32_t iCount = CountItems(this); - for (int32_t i = 0; i < iCount; i++) { - CFWL_ListItem* htem = GetItem(this, i); - GetItemSize(fs, htem, fWidth, m_fItemHeight, bAutoSize); - } - if (bAutoSize) - return fs; - - FX_FLOAT iWidth = m_rtClient.width - rtUIMargin.left - rtUIMargin.width; - FX_FLOAT iHeight = m_rtClient.height; - bool bShowVertScr = - (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_ShowScrollBarAlaways) && - (m_pProperties->m_dwStyles & FWL_WGTSTYLE_VScroll); - bool bShowHorzScr = - (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_ShowScrollBarAlaways) && - (m_pProperties->m_dwStyles & FWL_WGTSTYLE_HScroll); - if (!bShowVertScr && m_pProperties->m_dwStyles & FWL_WGTSTYLE_VScroll && - (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiColumn) == 0) { - bShowVertScr = (fs.y > iHeight); - } - if (!bShowHorzScr && m_pProperties->m_dwStyles & FWL_WGTSTYLE_HScroll) - bShowHorzScr = (fs.x > iWidth); - - CFX_SizeF szRange; - if (bShowVertScr) { - if (!m_pVertScrollBar) - InitScrollBar(); - - CFX_RectF rtScrollBar; - rtScrollBar.Set(m_rtClient.right() - m_fScorllBarWidth, m_rtClient.top, - m_fScorllBarWidth, m_rtClient.height - 1); - if (bShowHorzScr) - rtScrollBar.height -= m_fScorllBarWidth; - - m_pVertScrollBar->SetWidgetRect(rtScrollBar); - szRange.x = 0, szRange.y = fs.y - m_rtConent.height; - szRange.y = std::max(szRange.y, m_fItemHeight); - - m_pVertScrollBar->SetRange(szRange.x, szRange.y); - m_pVertScrollBar->SetPageSize(rtScrollBar.height * 9 / 10); - m_pVertScrollBar->SetStepSize(m_fItemHeight); - - FX_FLOAT fPos = - std::min(std::max(m_pVertScrollBar->GetPos(), 0.f), szRange.y); - m_pVertScrollBar->SetPos(fPos); - m_pVertScrollBar->SetTrackPos(fPos); - if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_ShowScrollBarFocus) == - 0 || - (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused)) { - m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, false); - } - m_pVertScrollBar->Update(); - } else if (m_pVertScrollBar) { - m_pVertScrollBar->SetPos(0); - m_pVertScrollBar->SetTrackPos(0); - m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, true); - } - if (bShowHorzScr) { - if (!m_pHorzScrollBar) - InitScrollBar(false); - - CFX_RectF rtScrollBar; - rtScrollBar.Set(m_rtClient.left, m_rtClient.bottom() - m_fScorllBarWidth, - m_rtClient.width, m_fScorllBarWidth); - if (bShowVertScr) - rtScrollBar.width -= m_fScorllBarWidth; - - m_pHorzScrollBar->SetWidgetRect(rtScrollBar); - szRange.x = 0, szRange.y = fs.x - rtScrollBar.width; - m_pHorzScrollBar->SetRange(szRange.x, szRange.y); - m_pHorzScrollBar->SetPageSize(fWidth * 9 / 10); - m_pHorzScrollBar->SetStepSize(fWidth / 10); - - FX_FLOAT fPos = - std::min(std::max(m_pHorzScrollBar->GetPos(), 0.f), szRange.y); - m_pHorzScrollBar->SetPos(fPos); - m_pHorzScrollBar->SetTrackPos(fPos); - if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_ShowScrollBarFocus) == - 0 || - (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused)) { - m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, false); - } - m_pHorzScrollBar->Update(); - } else if (m_pHorzScrollBar) { - m_pHorzScrollBar->SetPos(0); - m_pHorzScrollBar->SetTrackPos(0); - m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, true); - } - if (bShowVertScr && bShowHorzScr) { - m_rtStatic.Set(m_rtClient.right() - m_fScorllBarWidth, - m_rtClient.bottom() - m_fScorllBarWidth, m_fScorllBarWidth, - m_fScorllBarWidth); - } - return fs; -} - -void IFWL_ListBox::GetItemSize(CFX_SizeF& size, - CFWL_ListItem* pItem, - FX_FLOAT fWidth, - FX_FLOAT fItemHeight, - bool bAutoSize) { - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiColumn) - return; - - if (!bAutoSize) { - CFX_RectF rtItem; - rtItem.Set(0, size.y, fWidth, fItemHeight); - SetItemRect(this, pItem, rtItem); - } - size.x = fWidth; - size.y += fItemHeight; -} - -FX_FLOAT IFWL_ListBox::GetMaxTextWidth() { - FX_FLOAT fRet = 0.0f; - int32_t iCount = CountItems(this); - for (int32_t i = 0; i < iCount; i++) { - CFWL_ListItem* pItem = GetItem(this, i); - if (!pItem) - continue; - - CFX_WideString wsText; - GetItemText(this, pItem, wsText); - CFX_SizeF sz = CalcTextSize(wsText, m_pProperties->m_pThemeProvider); - fRet = std::max(fRet, sz.x); - } - return fRet; -} - -FX_FLOAT IFWL_ListBox::GetScrollWidth() { - FX_FLOAT* pfWidth = static_cast<FX_FLOAT*>( - GetThemeCapacity(CFWL_WidgetCapacity::ScrollBarWidth)); - if (!pfWidth) - return 0; - return *pfWidth; -} - -FX_FLOAT IFWL_ListBox::CalcItemHeight() { - FX_FLOAT* pfFont = - static_cast<FX_FLOAT*>(GetThemeCapacity(CFWL_WidgetCapacity::FontSize)); - if (!pfFont) - return 20; - return *pfFont + 2 * kItemTextMargin; -} - -void IFWL_ListBox::InitScrollBar(bool bVert) { - if ((bVert && m_pVertScrollBar) || (!bVert && m_pHorzScrollBar)) - return; - - auto prop = pdfium::MakeUnique<CFWL_WidgetProperties>(); - prop->m_dwStyleExes = bVert ? FWL_STYLEEXT_SCB_Vert : FWL_STYLEEXT_SCB_Horz; - prop->m_dwStates = FWL_WGTSTATE_Invisible; - prop->m_pParent = this; - prop->m_pThemeProvider = m_pScrollBarTP; - CFWL_ScrollBar* sb = new CFWL_ScrollBar(m_pOwnerApp, std::move(prop), this); - if (bVert) - m_pVertScrollBar.reset(sb); - else - m_pHorzScrollBar.reset(sb); -} - -bool IFWL_ListBox::IsShowScrollBar(bool bVert) { - CFWL_ScrollBar* pScrollbar = - bVert ? m_pVertScrollBar.get() : m_pHorzScrollBar.get(); - if (!pScrollbar || (pScrollbar->GetStates() & FWL_WGTSTATE_Invisible)) - return false; - return !(m_pProperties->m_dwStyleExes & - FWL_STYLEEXT_LTB_ShowScrollBarFocus) || - (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused); -} - -void IFWL_ListBox::OnProcessMessage(CFWL_Message* pMessage) { - if (!pMessage) - return; - if (!IsEnabled()) - return; - - CFWL_MessageType dwMsgCode = pMessage->GetClassID(); - switch (dwMsgCode) { - case CFWL_MessageType::SetFocus: - OnFocusChanged(pMessage, true); - break; - case CFWL_MessageType::KillFocus: - OnFocusChanged(pMessage, false); - break; - case CFWL_MessageType::Mouse: { - CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage); - switch (pMsg->m_dwCmd) { - case FWL_MouseCommand::LeftButtonDown: - OnLButtonDown(pMsg); - break; - case FWL_MouseCommand::LeftButtonUp: - OnLButtonUp(pMsg); - break; - default: - break; - } - break; - } - case CFWL_MessageType::MouseWheel: - OnMouseWheel(static_cast<CFWL_MsgMouseWheel*>(pMessage)); - break; - case CFWL_MessageType::Key: { - CFWL_MsgKey* pMsg = static_cast<CFWL_MsgKey*>(pMessage); - if (pMsg->m_dwCmd == FWL_KeyCommand::KeyDown) - OnKeyDown(pMsg); - break; - } - default: - break; - } - IFWL_Widget::OnProcessMessage(pMessage); -} - -void IFWL_ListBox::OnProcessEvent(CFWL_Event* pEvent) { - if (!pEvent) - return; - if (pEvent->GetClassID() != CFWL_EventType::Scroll) - return; - - IFWL_Widget* pSrcTarget = pEvent->m_pSrcTarget; - if ((pSrcTarget == m_pVertScrollBar.get() && m_pVertScrollBar) || - (pSrcTarget == m_pHorzScrollBar.get() && m_pHorzScrollBar)) { - CFWL_EvtScroll* pScrollEvent = static_cast<CFWL_EvtScroll*>(pEvent); - OnScroll(static_cast<CFWL_ScrollBar*>(pSrcTarget), - pScrollEvent->m_iScrollCode, pScrollEvent->m_fPos); - } -} - -void IFWL_ListBox::OnDrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix) { - DrawWidget(pGraphics, pMatrix); -} - -void IFWL_ListBox::OnFocusChanged(CFWL_Message* pMsg, bool bSet) { - if (GetStylesEx() & FWL_STYLEEXT_LTB_ShowScrollBarFocus) { - if (m_pVertScrollBar) - m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, !bSet); - if (m_pHorzScrollBar) - m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, !bSet); - } - if (bSet) - m_pProperties->m_dwStates |= (FWL_WGTSTATE_Focused); - else - m_pProperties->m_dwStates &= ~(FWL_WGTSTATE_Focused); - - Repaint(&m_rtClient); -} - -void IFWL_ListBox::OnLButtonDown(CFWL_MsgMouse* pMsg) { - m_bLButtonDown = true; - if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) - SetFocus(true); - - CFWL_ListItem* pItem = GetItemAtPoint(pMsg->m_fx, pMsg->m_fy); - if (!pItem) - return; - - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiSelection) { - if (pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl) { - bool bSelected = IsItemSelected(pItem); - SetSelectionDirect(pItem, !bSelected); - m_hAnchor = pItem; - } else if (pMsg->m_dwFlags & FWL_KEYFLAG_Shift) { - if (m_hAnchor) - SetSelection(m_hAnchor, pItem, true); - else - SetSelectionDirect(pItem, true); - } else { - SetSelection(pItem, pItem, true); - m_hAnchor = pItem; - } - } else { - SetSelection(pItem, pItem, true); - } - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_Check) { - CFWL_ListItem* hSelectedItem = GetItemAtPoint(pMsg->m_fx, pMsg->m_fy); - CFX_RectF rtCheck; - GetItemCheckRectInternal(hSelectedItem, rtCheck); - bool bChecked = GetItemChecked(pItem); - if (rtCheck.Contains(pMsg->m_fx, pMsg->m_fy)) { - SetItemChecked(pItem, !bChecked); - Update(); - } - } - SetFocusItem(pItem); - ScrollToVisible(pItem); - SetGrab(true); - Repaint(&m_rtClient); -} - -void IFWL_ListBox::OnLButtonUp(CFWL_MsgMouse* pMsg) { - if (!m_bLButtonDown) - return; - - m_bLButtonDown = false; - SetGrab(false); -} - -void IFWL_ListBox::OnMouseWheel(CFWL_MsgMouseWheel* pMsg) { - if (IsShowScrollBar(true)) - m_pVertScrollBar->GetDelegate()->OnProcessMessage(pMsg); -} - -void IFWL_ListBox::OnKeyDown(CFWL_MsgKey* pMsg) { - uint32_t dwKeyCode = pMsg->m_dwKeyCode; - switch (dwKeyCode) { - case FWL_VKEY_Tab: - case FWL_VKEY_Up: - case FWL_VKEY_Down: - case FWL_VKEY_Home: - case FWL_VKEY_End: { - CFWL_ListItem* pItem = GetFocusedItem(); - pItem = GetListItem(pItem, dwKeyCode); - bool bShift = !!(pMsg->m_dwFlags & FWL_KEYFLAG_Shift); - bool bCtrl = !!(pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl); - OnVK(pItem, bShift, bCtrl); - break; - } - default: - break; - } -} - -void IFWL_ListBox::OnVK(CFWL_ListItem* pItem, bool bShift, bool bCtrl) { - if (!pItem) - return; - - if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiSelection) { - if (bCtrl) { - // Do nothing. - } else if (bShift) { - if (m_hAnchor) - SetSelection(m_hAnchor, pItem, true); - else - SetSelectionDirect(pItem, true); - } else { - SetSelection(pItem, pItem, true); - m_hAnchor = pItem; - } - } else { - SetSelection(pItem, pItem, true); - } - - SetFocusItem(pItem); - ScrollToVisible(pItem); - - CFX_RectF rtInvalidate; - rtInvalidate.Set(0, 0, m_pProperties->m_rtWidget.width, - m_pProperties->m_rtWidget.height); - Repaint(&rtInvalidate); -} - -bool IFWL_ListBox::OnScroll(CFWL_ScrollBar* pScrollBar, - FWL_SCBCODE dwCode, - FX_FLOAT fPos) { - CFX_SizeF fs; - pScrollBar->GetRange(&fs.x, &fs.y); - FX_FLOAT iCurPos = pScrollBar->GetPos(); - FX_FLOAT fStep = pScrollBar->GetStepSize(); - switch (dwCode) { - case FWL_SCBCODE::Min: { - fPos = fs.x; - break; - } - case FWL_SCBCODE::Max: { - fPos = fs.y; - break; - } - case FWL_SCBCODE::StepBackward: { - fPos -= fStep; - if (fPos < fs.x + fStep / 2) - fPos = fs.x; - break; - } - case FWL_SCBCODE::StepForward: { - fPos += fStep; - if (fPos > fs.y - fStep / 2) - fPos = fs.y; - break; - } - case FWL_SCBCODE::PageBackward: { - fPos -= pScrollBar->GetPageSize(); - if (fPos < fs.x) - fPos = fs.x; - break; - } - case FWL_SCBCODE::PageForward: { - fPos += pScrollBar->GetPageSize(); - if (fPos > fs.y) - fPos = fs.y; - break; - } - case FWL_SCBCODE::Pos: - case FWL_SCBCODE::TrackPos: - case FWL_SCBCODE::None: - break; - case FWL_SCBCODE::EndScroll: - return false; - } - if (iCurPos != fPos) { - pScrollBar->SetPos(fPos); - pScrollBar->SetTrackPos(fPos); - Repaint(&m_rtClient); - } - return true; -} - -void IFWL_ListBox::GetItemText(IFWL_Widget* pWidget, - CFWL_ListItem* pItem, - CFX_WideString& wsText) { - if (pItem) - wsText = static_cast<CFWL_ListItem*>(pItem)->m_wsText; -} - -int32_t IFWL_ListBox::CountItems(const IFWL_Widget* pWidget) const { - return pdfium::CollectionSize<int32_t>(m_ItemArray); -} - -CFWL_ListItem* IFWL_ListBox::GetItem(const IFWL_Widget* pWidget, - int32_t nIndex) const { - if (nIndex < 0 || nIndex >= CountItems(pWidget)) - return nullptr; - return m_ItemArray[nIndex].get(); -} - -int32_t IFWL_ListBox::GetItemIndex(IFWL_Widget* pWidget, CFWL_ListItem* pItem) { - auto it = std::find_if( - m_ItemArray.begin(), m_ItemArray.end(), - [pItem](const std::unique_ptr<CFWL_ListItem>& candidate) { - return candidate.get() == static_cast<CFWL_ListItem*>(pItem); - }); - return it != m_ItemArray.end() ? it - m_ItemArray.begin() : -1; -} - -uint32_t IFWL_ListBox::GetItemStyles(IFWL_Widget* pWidget, - CFWL_ListItem* pItem) { - return pItem ? static_cast<CFWL_ListItem*>(pItem)->m_dwStates : 0; -} - -void IFWL_ListBox::GetItemRect(IFWL_Widget* pWidget, - CFWL_ListItem* pItem, - CFX_RectF& rtItem) { - if (pItem) - rtItem = static_cast<CFWL_ListItem*>(pItem)->m_rtItem; -} - -void* IFWL_ListBox::GetItemData(IFWL_Widget* pWidget, CFWL_ListItem* pItem) { - return pItem ? static_cast<CFWL_ListItem*>(pItem)->m_pData : nullptr; -} - -void IFWL_ListBox::SetItemStyles(IFWL_Widget* pWidget, - CFWL_ListItem* pItem, - uint32_t dwStyle) { - if (pItem) - static_cast<CFWL_ListItem*>(pItem)->m_dwStates = dwStyle; -} - -void IFWL_ListBox::SetItemRect(IFWL_Widget* pWidget, - CFWL_ListItem* pItem, - const CFX_RectF& rtItem) { - if (pItem) - static_cast<CFWL_ListItem*>(pItem)->m_rtItem = rtItem; -} - -CFX_DIBitmap* IFWL_ListBox::GetItemIcon(IFWL_Widget* pWidget, - CFWL_ListItem* pItem) { - return static_cast<CFWL_ListItem*>(pItem)->m_pDIB; -} - -void IFWL_ListBox::GetItemCheckRect(IFWL_Widget* pWidget, - CFWL_ListItem* pItem, - CFX_RectF& rtCheck) { - rtCheck = static_cast<CFWL_ListItem*>(pItem)->m_rtCheckBox; -} - -void IFWL_ListBox::SetItemCheckRect(IFWL_Widget* pWidget, - CFWL_ListItem* pItem, - const CFX_RectF& rtCheck) { - static_cast<CFWL_ListItem*>(pItem)->m_rtCheckBox = rtCheck; -} - -uint32_t IFWL_ListBox::GetItemCheckState(IFWL_Widget* pWidget, - CFWL_ListItem* pItem) { - return static_cast<CFWL_ListItem*>(pItem)->m_dwCheckState; -} - -void IFWL_ListBox::SetItemCheckState(IFWL_Widget* pWidget, - CFWL_ListItem* pItem, - uint32_t dwCheckState) { - static_cast<CFWL_ListItem*>(pItem)->m_dwCheckState = dwCheckState; -} - -CFWL_ListItem* IFWL_ListBox::AddString(const CFX_WideStringC& wsAdd, - bool bSelect) { - auto pItem = pdfium::MakeUnique<CFWL_ListItem>(); - pItem->m_dwStates = 0; - pItem->m_wsText = wsAdd; - pItem->m_dwStates = bSelect ? FWL_ITEMSTATE_LTB_Selected : 0; - m_ItemArray.push_back(std::move(pItem)); - return m_ItemArray.back().get(); -} - -bool IFWL_ListBox::RemoveAt(int32_t iIndex) { - if (iIndex < 0 || static_cast<size_t>(iIndex) >= m_ItemArray.size()) - return false; - - m_ItemArray.erase(m_ItemArray.begin() + iIndex); - return true; -} - -bool IFWL_ListBox::DeleteString(CFWL_ListItem* pItem) { - int32_t nIndex = GetItemIndex(this, pItem); - if (nIndex < 0 || static_cast<size_t>(nIndex) >= m_ItemArray.size()) - return false; - - int32_t iSel = nIndex + 1; - if (iSel >= CountItems(this)) - iSel = nIndex - 1; - if (iSel >= 0) { - CFWL_ListItem* pSel = static_cast<CFWL_ListItem*>(GetItem(this, iSel)); - pSel->m_dwStates |= FWL_ITEMSTATE_LTB_Selected; - } - m_ItemArray.erase(m_ItemArray.begin() + nIndex); - return true; -} - -void IFWL_ListBox::DeleteAll() { - m_ItemArray.clear(); -} diff --git a/xfa/fwl/core/ifwl_listbox.h b/xfa/fwl/core/ifwl_listbox.h deleted file mode 100644 index a8638eb3b6..0000000000 --- a/xfa/fwl/core/ifwl_listbox.h +++ /dev/null @@ -1,168 +0,0 @@ -// 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 - -#ifndef XFA_FWL_CORE_IFWL_LISTBOX_H_ -#define XFA_FWL_CORE_IFWL_LISTBOX_H_ - -#include <memory> -#include <vector> - -#include "xfa/fwl/core/cfwl_event.h" -#include "xfa/fwl/core/cfwl_listitem.h" -#include "xfa/fwl/core/cfwl_widgetproperties.h" -#include "xfa/fwl/core/ifwl_edit.h" -#include "xfa/fwl/core/ifwl_listbox.h" -#include "xfa/fwl/core/ifwl_widget.h" - -#define FWL_STYLEEXT_LTB_MultiSelection (1L << 0) -#define FWL_STYLEEXT_LTB_ShowScrollBarAlaways (1L << 2) -#define FWL_STYLEEXT_LTB_MultiColumn (1L << 3) -#define FWL_STYLEEXT_LTB_LeftAlign (0L << 4) -#define FWL_STYLEEXT_LTB_CenterAlign (1L << 4) -#define FWL_STYLEEXT_LTB_RightAlign (2L << 4) -#define FWL_STYLEEXT_LTB_MultiLine (1L << 6) -#define FWL_STYLEEXT_LTB_OwnerDraw (1L << 7) -#define FWL_STYLEEXT_LTB_Icon (1L << 8) -#define FWL_STYLEEXT_LTB_Check (1L << 9) -#define FWL_STYLEEXT_LTB_AlignMask (3L << 4) -#define FWL_STYLEEXT_LTB_ShowScrollBarFocus (1L << 10) -#define FWL_ITEMSTATE_LTB_Selected (1L << 0) -#define FWL_ITEMSTATE_LTB_Focused (1L << 1) -#define FWL_ITEMSTATE_LTB_Checked (1L << 2) - -class CFWL_MsgKillFocus; -class CFWL_MsgMouse; -class CFWL_MsgMouseWheel; -class CFX_DIBitmap; - -class IFWL_ListBox : public IFWL_Widget { - public: - IFWL_ListBox(const CFWL_App* app, - std::unique_ptr<CFWL_WidgetProperties> properties, - IFWL_Widget* pOuter); - ~IFWL_ListBox() override; - - // IFWL_Widget - FWL_Type GetClassID() const override; - void GetWidgetRect(CFX_RectF& rect, bool bAutoSize = false) override; - void Update() override; - FWL_WidgetHit HitTest(FX_FLOAT fx, FX_FLOAT fy) override; - void DrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix = nullptr) override; - void SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) override; - void OnProcessMessage(CFWL_Message* pMessage) override; - void OnProcessEvent(CFWL_Event* pEvent) override; - void OnDrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix) override; - - int32_t CountItems(const IFWL_Widget* pWidget) const; - CFWL_ListItem* GetItem(const IFWL_Widget* pWidget, int32_t nIndex) const; - int32_t GetItemIndex(IFWL_Widget* pWidget, CFWL_ListItem* pItem); - uint32_t GetItemStyles(IFWL_Widget* pWidget, CFWL_ListItem* pItem); - void GetItemText(IFWL_Widget* pWidget, - CFWL_ListItem* pItem, - CFX_WideString& wsText); - void GetItemRect(IFWL_Widget* pWidget, - CFWL_ListItem* pItem, - CFX_RectF& rtItem); - void* GetItemData(IFWL_Widget* pWidget, CFWL_ListItem* pItem); - void SetItemStyles(IFWL_Widget* pWidget, - CFWL_ListItem* pItem, - uint32_t dwStyle); - void SetItemRect(IFWL_Widget* pWidget, - CFWL_ListItem* pItem, - const CFX_RectF& rtItem); - CFX_DIBitmap* GetItemIcon(IFWL_Widget* pWidget, CFWL_ListItem* pItem); - void GetItemCheckRect(IFWL_Widget* pWidget, - CFWL_ListItem* pItem, - CFX_RectF& rtCheck); - void SetItemCheckRect(IFWL_Widget* pWidget, - CFWL_ListItem* pItem, - const CFX_RectF& rtCheck); - uint32_t GetItemCheckState(IFWL_Widget* pWidget, CFWL_ListItem* pItem); - void SetItemCheckState(IFWL_Widget* pWidget, - CFWL_ListItem* pItem, - uint32_t dwCheckState); - CFWL_ListItem* AddString(const CFX_WideStringC& wsAdd, bool bSelect = false); - bool RemoveAt(int32_t iIndex); - bool DeleteString(CFWL_ListItem* pItem); - void DeleteAll(); - - int32_t CountSelItems(); - CFWL_ListItem* GetSelItem(int32_t nIndexSel); - int32_t GetSelIndex(int32_t nIndex); - void SetSelItem(CFWL_ListItem* hItem, bool bSelect = true); - void GetDataProviderItemText(CFWL_ListItem* hItem, CFX_WideString& wsText); - - FX_FLOAT GetItemHeight() const { return m_fItemHeight; } - FX_FLOAT CalcItemHeight(); - - protected: - CFWL_ListItem* GetListItem(CFWL_ListItem* hItem, uint32_t dwKeyCode); - void SetSelection(CFWL_ListItem* hStart, CFWL_ListItem* hEnd, bool bSelected); - CFWL_ListItem* GetItemAtPoint(FX_FLOAT fx, FX_FLOAT fy); - bool ScrollToVisible(CFWL_ListItem* hItem); - void InitScrollBar(bool bVert = true); - bool IsShowScrollBar(bool bVert); - CFWL_ScrollBar* GetVertScrollBar() const { return m_pVertScrollBar.get(); } - const CFX_RectF& GetRTClient() const { return m_rtClient; } - - private: - void SetSelectionDirect(CFWL_ListItem* hItem, bool bSelect); - bool IsItemSelected(CFWL_ListItem* hItem); - void ClearSelection(); - void SelectAll(); - CFWL_ListItem* GetFocusedItem(); - void SetFocusItem(CFWL_ListItem* hItem); - bool GetItemCheckRectInternal(CFWL_ListItem* hItem, CFX_RectF& rtCheck); - bool SetItemChecked(CFWL_ListItem* hItem, bool bChecked); - bool GetItemChecked(CFWL_ListItem* hItem); - void DrawBkground(CFX_Graphics* pGraphics, - IFWL_ThemeProvider* pTheme, - const CFX_Matrix* pMatrix = nullptr); - void DrawItems(CFX_Graphics* pGraphics, - IFWL_ThemeProvider* pTheme, - const CFX_Matrix* pMatrix = nullptr); - void DrawItem(CFX_Graphics* pGraphics, - IFWL_ThemeProvider* pTheme, - CFWL_ListItem* hItem, - int32_t Index, - const CFX_RectF& rtItem, - const CFX_Matrix* pMatrix = nullptr); - void DrawStatic(CFX_Graphics* pGraphics, IFWL_ThemeProvider* pTheme); - CFX_SizeF CalcSize(bool bAutoSize = false); - void GetItemSize(CFX_SizeF& size, - CFWL_ListItem* hItem, - FX_FLOAT fWidth, - FX_FLOAT fHeight, - bool bAutoSize = false); - FX_FLOAT GetMaxTextWidth(); - FX_FLOAT GetScrollWidth(); - - void OnFocusChanged(CFWL_Message* pMsg, bool bSet = true); - void OnLButtonDown(CFWL_MsgMouse* pMsg); - void OnLButtonUp(CFWL_MsgMouse* pMsg); - void OnMouseWheel(CFWL_MsgMouseWheel* pMsg); - void OnKeyDown(CFWL_MsgKey* pMsg); - void OnVK(CFWL_ListItem* hItem, bool bShift, bool bCtrl); - bool OnScroll(CFWL_ScrollBar* pScrollBar, FWL_SCBCODE dwCode, FX_FLOAT fPos); - - CFX_RectF m_rtClient; - CFX_RectF m_rtStatic; - CFX_RectF m_rtConent; - std::unique_ptr<CFWL_ScrollBar> m_pHorzScrollBar; - std::unique_ptr<CFWL_ScrollBar> m_pVertScrollBar; - uint32_t m_dwTTOStyles; - int32_t m_iTTOAligns; - CFWL_ListItem* m_hAnchor; - FX_FLOAT m_fItemHeight; - FX_FLOAT m_fScorllBarWidth; - bool m_bLButtonDown; - IFWL_ThemeProvider* m_pScrollBarTP; - std::vector<std::unique_ptr<CFWL_ListItem>> m_ItemArray; -}; - -#endif // XFA_FWL_CORE_IFWL_LISTBOX_H_ diff --git a/xfa/fwl/core/ifwl_picturebox.cpp b/xfa/fwl/core/ifwl_picturebox.cpp deleted file mode 100644 index 9a3fbf3067..0000000000 --- a/xfa/fwl/core/ifwl_picturebox.cpp +++ /dev/null @@ -1,68 +0,0 @@ -// 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_picturebox.h" - -#include <memory> -#include <utility> - -#include "third_party/base/ptr_util.h" -#include "xfa/fwl/core/cfwl_notedriver.h" -#include "xfa/fwl/core/cfwl_picturebox.h" - -IFWL_PictureBox::IFWL_PictureBox( - const CFWL_App* app, - std::unique_ptr<CFWL_WidgetProperties> properties) - : IFWL_Widget(app, std::move(properties), nullptr) { - m_rtClient.Reset(); - m_rtImage.Reset(); - m_matrix.SetIdentity(); -} - -IFWL_PictureBox::~IFWL_PictureBox() {} - -FWL_Type IFWL_PictureBox::GetClassID() const { - return FWL_Type::PictureBox; -} - -void IFWL_PictureBox::GetWidgetRect(CFX_RectF& rect, bool bAutoSize) { - if (!bAutoSize) { - rect = m_pProperties->m_rtWidget; - return; - } - - rect.Set(0, 0, 0, 0); - - IFWL_Widget::GetWidgetRect(rect, true); -} - -void IFWL_PictureBox::Update() { - if (IsLocked()) - return; - if (!m_pProperties->m_pThemeProvider) - m_pProperties->m_pThemeProvider = GetAvailableTheme(); - - GetClientRect(m_rtClient); -} - -void IFWL_PictureBox::DrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix) { - if (!pGraphics) - return; - if (!m_pProperties->m_pThemeProvider) - return; - - IFWL_ThemeProvider* pTheme = GetAvailableTheme(); - if (HasBorder()) - DrawBorder(pGraphics, CFWL_Part::Border, pTheme, pMatrix); - if (HasEdge()) - DrawEdge(pGraphics, CFWL_Part::Edge, pTheme, pMatrix); -} - -void IFWL_PictureBox::OnDrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix) { - DrawWidget(pGraphics, pMatrix); -} diff --git a/xfa/fwl/core/ifwl_picturebox.h b/xfa/fwl/core/ifwl_picturebox.h deleted file mode 100644 index 510ab9a026..0000000000 --- a/xfa/fwl/core/ifwl_picturebox.h +++ /dev/null @@ -1,54 +0,0 @@ -// 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 - -#ifndef XFA_FWL_CORE_IFWL_PICTUREBOX_H_ -#define XFA_FWL_CORE_IFWL_PICTUREBOX_H_ - -#include <memory> - -#include "xfa/fwl/core/cfwl_widgetproperties.h" -#include "xfa/fwl/core/ifwl_widget.h" - -#define FWL_STYLEEXT_PTB_Left 0L << 0 -#define FWL_STYLEEXT_PTB_Center 1L << 0 -#define FWL_STYLEEXT_PTB_Right 2L << 0 -#define FWL_STYLEEXT_PTB_Top 0L << 2 -#define FWL_STYLEEXT_PTB_Vcenter 1L << 2 -#define FWL_STYLEEXT_PTB_Bottom 2L << 2 -#define FWL_STYLEEXT_PTB_Normal 0L << 4 -#define FWL_STYLEEXT_PTB_AutoSize 1L << 4 -#define FWL_STYLEEXT_PTB_StretchImage 2L << 4 -#define FWL_STYLEEXT_PTB_StretchHImage 3L << 4 -#define FWL_STYLEEXT_PTB_StretchVImage 4L << 4 -#define FWL_STYLEEXT_PTB_HAlignMask 3L << 0 -#define FWL_STYLEEXT_PTB_VAlignMask 3L << 2 -#define FWL_STYLEEXT_PTB_StretchAlignMask 7L << 4 - -class CFX_DIBitmap; -class IFWL_Widget; - -class IFWL_PictureBox : public IFWL_Widget { - public: - explicit IFWL_PictureBox(const CFWL_App* app, - std::unique_ptr<CFWL_WidgetProperties> properties); - ~IFWL_PictureBox() override; - - // IFWL_Widget - FWL_Type GetClassID() const override; - void GetWidgetRect(CFX_RectF& rect, bool bAutoSize = false) override; - void Update() override; - void DrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix = nullptr) override; - void OnDrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix) override; - - private: - CFX_RectF m_rtClient; - CFX_RectF m_rtImage; - CFX_Matrix m_matrix; -}; - -#endif // XFA_FWL_CORE_IFWL_PICTUREBOX_H_ diff --git a/xfa/fwl/core/ifwl_pushbutton.cpp b/xfa/fwl/core/ifwl_pushbutton.cpp deleted file mode 100644 index 7eb84129e1..0000000000 --- a/xfa/fwl/core/ifwl_pushbutton.cpp +++ /dev/null @@ -1,316 +0,0 @@ -// 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_pushbutton.h" - -#include <memory> -#include <utility> - -#include "third_party/base/ptr_util.h" -#include "xfa/fde/tto/fde_textout.h" -#include "xfa/fwl/core/cfwl_evtclick.h" -#include "xfa/fwl/core/cfwl_evtmouse.h" -#include "xfa/fwl/core/cfwl_msgkey.h" -#include "xfa/fwl/core/cfwl_msgmouse.h" -#include "xfa/fwl/core/cfwl_notedriver.h" -#include "xfa/fwl/core/cfwl_themebackground.h" -#include "xfa/fwl/core/cfwl_themetext.h" -#include "xfa/fwl/core/ifwl_themeprovider.h" - -IFWL_PushButton::IFWL_PushButton( - const CFWL_App* app, - std::unique_ptr<CFWL_WidgetProperties> properties) - : IFWL_Widget(app, std::move(properties), nullptr), - m_bBtnDown(false), - m_dwTTOStyles(FDE_TTOSTYLE_SingleLine), - m_iTTOAlign(FDE_TTOALIGNMENT_Center) { - m_rtClient.Set(0, 0, 0, 0); - m_rtCaption.Set(0, 0, 0, 0); -} - -IFWL_PushButton::~IFWL_PushButton() {} - -FWL_Type IFWL_PushButton::GetClassID() const { - return FWL_Type::PushButton; -} - -void IFWL_PushButton::GetWidgetRect(CFX_RectF& rect, bool bAutoSize) { - if (!bAutoSize) { - rect = m_pProperties->m_rtWidget; - return; - } - - rect.Set(0, 0, 0, 0); - if (!m_pProperties->m_pThemeProvider) - m_pProperties->m_pThemeProvider = GetAvailableTheme(); - - FX_FLOAT* fcaption = - static_cast<FX_FLOAT*>(GetThemeCapacity(CFWL_WidgetCapacity::Margin)); - rect.Inflate(*fcaption, *fcaption); - IFWL_Widget::GetWidgetRect(rect, true); -} - -void IFWL_PushButton::SetStates(uint32_t dwStates, bool bSet) { - if ((dwStates & FWL_WGTSTATE_Disabled) && bSet) { - m_pProperties->m_dwStates = FWL_WGTSTATE_Disabled; - return; - } - IFWL_Widget::SetStates(dwStates, bSet); -} - -void IFWL_PushButton::Update() { - if (IsLocked()) - return; - if (!m_pProperties->m_pThemeProvider) - m_pProperties->m_pThemeProvider = GetAvailableTheme(); - - UpdateTextOutStyles(); - GetClientRect(m_rtClient); - m_rtCaption = m_rtClient; - FX_FLOAT* fcaption = - static_cast<FX_FLOAT*>(GetThemeCapacity(CFWL_WidgetCapacity::Margin)); - m_rtCaption.Inflate(-*fcaption, -*fcaption); -} - -void IFWL_PushButton::DrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix) { - if (!pGraphics) - return; - if (!m_pProperties->m_pThemeProvider) - return; - - if (HasBorder()) { - DrawBorder(pGraphics, CFWL_Part::Border, m_pProperties->m_pThemeProvider, - pMatrix); - } - if (HasEdge()) { - DrawEdge(pGraphics, CFWL_Part::Edge, m_pProperties->m_pThemeProvider, - pMatrix); - } - DrawBkground(pGraphics, m_pProperties->m_pThemeProvider, pMatrix); -} - -void IFWL_PushButton::DrawBkground(CFX_Graphics* pGraphics, - IFWL_ThemeProvider* pTheme, - const CFX_Matrix* pMatrix) { - CFWL_ThemeBackground param; - param.m_pWidget = this; - param.m_iPart = CFWL_Part::Background; - param.m_dwStates = GetPartStates(); - param.m_pGraphics = pGraphics; - if (pMatrix) - param.m_matrix.Concat(*pMatrix); - param.m_rtPart = m_rtClient; - if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) - param.m_pData = &m_rtCaption; - pTheme->DrawBackground(¶m); -} - -uint32_t IFWL_PushButton::GetPartStates() { - uint32_t dwStates = CFWL_PartState_Normal; - if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) - dwStates |= CFWL_PartState_Focused; - if (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) - dwStates = CFWL_PartState_Disabled; - else if (m_pProperties->m_dwStates & FWL_STATE_PSB_Pressed) - dwStates |= CFWL_PartState_Pressed; - else if (m_pProperties->m_dwStates & FWL_STATE_PSB_Hovered) - dwStates |= CFWL_PartState_Hovered; - else if (m_pProperties->m_dwStates & FWL_STATE_PSB_Default) - dwStates |= CFWL_PartState_Default; - return dwStates; -} - -void IFWL_PushButton::UpdateTextOutStyles() { - switch (m_pProperties->m_dwStyleExes & - (FWL_STYLEEXT_PSB_HLayoutMask | FWL_STYLEEXT_PSB_VLayoutMask)) { - case FWL_STYLEEXT_PSB_Left | FWL_STYLEEXT_PSB_Top: { - m_iTTOAlign = FDE_TTOALIGNMENT_TopLeft; - break; - } - case FWL_STYLEEXT_PSB_Center | FWL_STYLEEXT_PSB_Top: { - m_iTTOAlign = FDE_TTOALIGNMENT_TopCenter; - break; - } - case FWL_STYLEEXT_PSB_Right | FWL_STYLEEXT_PSB_Top: { - m_iTTOAlign = FDE_TTOALIGNMENT_TopRight; - break; - } - case FWL_STYLEEXT_PSB_Left | FWL_STYLEEXT_PSB_VCenter: { - m_iTTOAlign = FDE_TTOALIGNMENT_CenterLeft; - break; - } - case FWL_STYLEEXT_PSB_Right | FWL_STYLEEXT_PSB_VCenter: { - m_iTTOAlign = FDE_TTOALIGNMENT_CenterRight; - break; - } - case FWL_STYLEEXT_PSB_Left | FWL_STYLEEXT_PSB_Bottom: { - m_iTTOAlign = FDE_TTOALIGNMENT_BottomLeft; - break; - } - case FWL_STYLEEXT_PSB_Center | FWL_STYLEEXT_PSB_Bottom: { - m_iTTOAlign = FDE_TTOALIGNMENT_BottomCenter; - break; - } - case FWL_STYLEEXT_PSB_Right | FWL_STYLEEXT_PSB_Bottom: { - m_iTTOAlign = FDE_TTOALIGNMENT_BottomRight; - break; - } - case FWL_STYLEEXT_PSB_Center | FWL_STYLEEXT_PSB_VCenter: - default: { - m_iTTOAlign = FDE_TTOALIGNMENT_Center; - break; - } - } - m_dwTTOStyles = FDE_TTOSTYLE_SingleLine; - if (m_pProperties->m_dwStyleExes & FWL_WGTSTYLE_RTLReading) - m_dwTTOStyles |= FDE_TTOSTYLE_RTL; -} - -void IFWL_PushButton::OnProcessMessage(CFWL_Message* pMessage) { - if (!pMessage) - return; - if (!IsEnabled()) - return; - - CFWL_MessageType dwMsgCode = pMessage->GetClassID(); - switch (dwMsgCode) { - case CFWL_MessageType::SetFocus: - OnFocusChanged(pMessage, true); - break; - case CFWL_MessageType::KillFocus: - OnFocusChanged(pMessage, false); - break; - case CFWL_MessageType::Mouse: { - CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage); - switch (pMsg->m_dwCmd) { - case FWL_MouseCommand::LeftButtonDown: - OnLButtonDown(pMsg); - break; - case FWL_MouseCommand::LeftButtonUp: - OnLButtonUp(pMsg); - break; - case FWL_MouseCommand::Move: - OnMouseMove(pMsg); - break; - case FWL_MouseCommand::Leave: - OnMouseLeave(pMsg); - break; - default: - break; - } - break; - } - case CFWL_MessageType::Key: { - CFWL_MsgKey* pKey = static_cast<CFWL_MsgKey*>(pMessage); - if (pKey->m_dwCmd == FWL_KeyCommand::KeyDown) - OnKeyDown(pKey); - break; - } - default: - break; - } - IFWL_Widget::OnProcessMessage(pMessage); -} - -void IFWL_PushButton::OnDrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix) { - DrawWidget(pGraphics, pMatrix); -} - -void IFWL_PushButton::OnFocusChanged(CFWL_Message* pMsg, bool bSet) { - if (bSet) - m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused; - else - m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused; - - Repaint(&m_rtClient); -} - -void IFWL_PushButton::OnLButtonDown(CFWL_MsgMouse* pMsg) { - if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) - SetFocus(true); - - m_bBtnDown = true; - m_pProperties->m_dwStates |= FWL_STATE_PSB_Hovered; - m_pProperties->m_dwStates |= FWL_STATE_PSB_Pressed; - Repaint(&m_rtClient); -} - -void IFWL_PushButton::OnLButtonUp(CFWL_MsgMouse* pMsg) { - m_bBtnDown = false; - if (m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) { - m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Pressed; - m_pProperties->m_dwStates |= FWL_STATE_PSB_Hovered; - } else { - m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Hovered; - m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Pressed; - } - if (m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) { - CFWL_EvtClick wmClick; - wmClick.m_pSrcTarget = this; - DispatchEvent(&wmClick); - } - Repaint(&m_rtClient); -} - -void IFWL_PushButton::OnMouseMove(CFWL_MsgMouse* pMsg) { - bool bRepaint = false; - if (m_bBtnDown) { - if (m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) { - if ((m_pProperties->m_dwStates & FWL_STATE_PSB_Pressed) == 0) { - m_pProperties->m_dwStates |= FWL_STATE_PSB_Pressed; - bRepaint = true; - } - if (m_pProperties->m_dwStates & FWL_STATE_PSB_Hovered) { - m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Hovered; - bRepaint = true; - } - } else { - if (m_pProperties->m_dwStates & FWL_STATE_PSB_Pressed) { - m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Pressed; - bRepaint = true; - } - if ((m_pProperties->m_dwStates & FWL_STATE_PSB_Hovered) == 0) { - m_pProperties->m_dwStates |= FWL_STATE_PSB_Hovered; - bRepaint = true; - } - } - } else { - if (!m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) - return; - if ((m_pProperties->m_dwStates & FWL_STATE_PSB_Hovered) == 0) { - m_pProperties->m_dwStates |= FWL_STATE_PSB_Hovered; - bRepaint = true; - } - } - if (bRepaint) - Repaint(&m_rtClient); -} - -void IFWL_PushButton::OnMouseLeave(CFWL_MsgMouse* pMsg) { - m_bBtnDown = false; - m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Hovered; - m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Pressed; - Repaint(&m_rtClient); -} - -void IFWL_PushButton::OnKeyDown(CFWL_MsgKey* pMsg) { - if (pMsg->m_dwKeyCode == FWL_VKEY_Return) { - CFWL_EvtMouse wmMouse; - wmMouse.m_pSrcTarget = this; - wmMouse.m_dwCmd = FWL_MouseCommand::LeftButtonUp; - DispatchEvent(&wmMouse); - CFWL_EvtClick wmClick; - wmClick.m_pSrcTarget = this; - DispatchEvent(&wmClick); - return; - } - if (pMsg->m_dwKeyCode != FWL_VKEY_Tab) - return; - - DispatchKeyEvent(pMsg); -} diff --git a/xfa/fwl/core/ifwl_pushbutton.h b/xfa/fwl/core/ifwl_pushbutton.h deleted file mode 100644 index 9a142130d7..0000000000 --- a/xfa/fwl/core/ifwl_pushbutton.h +++ /dev/null @@ -1,72 +0,0 @@ -// 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 - -#ifndef XFA_FWL_CORE_IFWL_PUSHBUTTON_H_ -#define XFA_FWL_CORE_IFWL_PUSHBUTTON_H_ - -#include <memory> - -#include "xfa/fwl/core/cfwl_widgetproperties.h" -#include "xfa/fwl/core/ifwl_widget.h" - -#define FWL_STYLEEXT_PSB_Left (0L << 0) -#define FWL_STYLEEXT_PSB_Center (1L << 0) -#define FWL_STYLEEXT_PSB_Right (2L << 0) -#define FWL_STYLEEXT_PSB_Top (0L << 2) -#define FWL_STYLEEXT_PSB_VCenter (1L << 2) -#define FWL_STYLEEXT_PSB_Bottom (2L << 2) -#define FWL_STYLEEXT_PSB_TextOnly (0L << 4) -#define FWL_STYLEEXT_PSB_IconOnly (1L << 4) -#define FWL_STYLEEXT_PSB_TextIcon (2L << 4) -#define FWL_STYLEEXT_PSB_HLayoutMask (3L << 0) -#define FWL_STYLEEXT_PSB_VLayoutMask (3L << 2) -#define FWL_STYLEEXT_PSB_ModeMask (3L << 4) -#define FWL_STATE_PSB_Hovered (1 << FWL_WGTSTATE_MAX) -#define FWL_STATE_PSB_Pressed (1 << (FWL_WGTSTATE_MAX + 1)) -#define FWL_STATE_PSB_Default (1 << (FWL_WGTSTATE_MAX + 2)) - -class CFWL_MsgMouse; -class CFX_DIBitmap; -class IFWL_Widget; - -class IFWL_PushButton : public IFWL_Widget { - public: - IFWL_PushButton(const CFWL_App* app, - std::unique_ptr<CFWL_WidgetProperties> properties); - ~IFWL_PushButton() override; - - // IFWL_Widget - FWL_Type GetClassID() const override; - void GetWidgetRect(CFX_RectF& rect, bool bAutoSize = false) override; - void SetStates(uint32_t dwStates, bool bSet = true) override; - void Update() override; - void DrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix = nullptr) override; - void OnProcessMessage(CFWL_Message* pMessage) override; - void OnDrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix) override; - - private: - void DrawBkground(CFX_Graphics* pGraphics, - IFWL_ThemeProvider* pTheme, - const CFX_Matrix* pMatrix); - uint32_t GetPartStates(); - void UpdateTextOutStyles(); - void OnFocusChanged(CFWL_Message* pMsg, bool bSet); - void OnLButtonDown(CFWL_MsgMouse* pMsg); - void OnLButtonUp(CFWL_MsgMouse* pMsg); - void OnMouseMove(CFWL_MsgMouse* pMsg); - void OnMouseLeave(CFWL_MsgMouse* pMsg); - void OnKeyDown(CFWL_MsgKey* pMsg); - - CFX_RectF m_rtClient; - CFX_RectF m_rtCaption; - bool m_bBtnDown; - uint32_t m_dwTTOStyles; - int32_t m_iTTOAlign; -}; - -#endif // XFA_FWL_CORE_IFWL_PUSHBUTTON_H_ diff --git a/xfa/fwl/core/ifwl_themeprovider.h b/xfa/fwl/core/ifwl_themeprovider.h index cc55fa30ee..e376cb1eea 100644 --- a/xfa/fwl/core/ifwl_themeprovider.h +++ b/xfa/fwl/core/ifwl_themeprovider.h @@ -13,7 +13,7 @@ class CFWL_ThemeBackground; class CFWL_ThemePart; class CFWL_ThemeText; -class IFWL_Widget; +class CFWL_Widget; class IFWL_ThemeProvider { public: diff --git a/xfa/fwl/core/ifwl_widget.cpp b/xfa/fwl/core/ifwl_widget.cpp deleted file mode 100644 index 9a37cc89ca..0000000000 --- a/xfa/fwl/core/ifwl_widget.cpp +++ /dev/null @@ -1,803 +0,0 @@ -// 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_widget.h" - -#include <algorithm> -#include <utility> - -#include "xfa/fde/tto/fde_textout.h" -#include "xfa/fwl/core/cfwl_app.h" -#include "xfa/fwl/core/cfwl_evtkey.h" -#include "xfa/fwl/core/cfwl_evtkillfocus.h" -#include "xfa/fwl/core/cfwl_evtmouse.h" -#include "xfa/fwl/core/cfwl_evtmousewheel.h" -#include "xfa/fwl/core/cfwl_evtsetfocus.h" -#include "xfa/fwl/core/cfwl_evtsizechanged.h" -#include "xfa/fwl/core/cfwl_form.h" -#include "xfa/fwl/core/cfwl_msgkey.h" -#include "xfa/fwl/core/cfwl_msgkillfocus.h" -#include "xfa/fwl/core/cfwl_msgmouse.h" -#include "xfa/fwl/core/cfwl_msgmousewheel.h" -#include "xfa/fwl/core/cfwl_msgsetfocus.h" -#include "xfa/fwl/core/cfwl_notedriver.h" -#include "xfa/fwl/core/cfwl_themebackground.h" -#include "xfa/fwl/core/cfwl_themepart.h" -#include "xfa/fwl/core/cfwl_themetext.h" -#include "xfa/fwl/core/cfwl_widgetmgr.h" -#include "xfa/fwl/core/ifwl_combobox.h" -#include "xfa/fwl/core/ifwl_themeprovider.h" -#include "xfa/fxfa/xfa_ffapp.h" - -#define FWL_STYLEEXT_MNU_Vert (1L << 0) -#define FWL_WGT_CalcHeight 2048 -#define FWL_WGT_CalcWidth 2048 -#define FWL_WGT_CalcMultiLineDefWidth 120.0f - -IFWL_Widget::IFWL_Widget(const CFWL_App* app, - std::unique_ptr<CFWL_WidgetProperties> properties, - IFWL_Widget* pOuter) - : m_pOwnerApp(app), - m_pWidgetMgr(app->GetWidgetMgr()), - m_pProperties(std::move(properties)), - m_pOuter(pOuter), - m_iLock(0), - m_pLayoutItem(nullptr), - m_pAssociate(nullptr), - m_nEventKey(0), - m_pDelegate(nullptr) { - ASSERT(m_pWidgetMgr); - - IFWL_Widget* pParent = m_pProperties->m_pParent; - m_pWidgetMgr->InsertWidget(pParent, this); - if (IsChild()) - return; - - IFWL_Widget* pOwner = m_pProperties->m_pOwner; - if (pOwner) - m_pWidgetMgr->SetOwner(pOwner, this); -} - -IFWL_Widget::~IFWL_Widget() { - NotifyDriver(); - m_pWidgetMgr->RemoveWidget(this); -} - -bool IFWL_Widget::IsInstance(const CFX_WideStringC& wsClass) const { - return false; -} - -void IFWL_Widget::GetWidgetRect(CFX_RectF& rect, bool bAutoSize) { - if (!bAutoSize) { - rect = m_pProperties->m_rtWidget; - return; - } - - if (HasEdge()) { - FX_FLOAT fEdge = GetEdgeWidth(); - rect.Inflate(fEdge, fEdge); - } - if (HasBorder()) { - FX_FLOAT fBorder = GetBorderSize(); - rect.Inflate(fBorder, fBorder); - } -} - -void IFWL_Widget::SetWidgetRect(const CFX_RectF& rect) { - CFX_RectF rtOld = m_pProperties->m_rtWidget; - m_pProperties->m_rtWidget = rect; - if (IsChild()) { - if (FXSYS_fabs(rtOld.width - rect.width) > 0.5f || - FXSYS_fabs(rtOld.height - rect.height) > 0.5f) { - CFWL_EvtSizeChanged ev; - ev.m_pSrcTarget = this; - ev.m_rtOld = rtOld; - ev.m_rtNew = rect; - - if (IFWL_WidgetDelegate* pDelegate = GetDelegate()) - pDelegate->OnProcessEvent(&ev); - } - return; - } - m_pWidgetMgr->SetWidgetRect_Native(this, rect); -} - -void IFWL_Widget::GetClientRect(CFX_RectF& rect) { - GetEdgeRect(rect); - if (HasEdge()) { - FX_FLOAT fEdge = GetEdgeWidth(); - rect.Deflate(fEdge, fEdge); - } -} - -void IFWL_Widget::SetParent(IFWL_Widget* pParent) { - m_pProperties->m_pParent = pParent; - m_pWidgetMgr->SetParent(pParent, this); -} - -uint32_t IFWL_Widget::GetStyles() const { - return m_pProperties->m_dwStyles; -} - -void IFWL_Widget::ModifyStyles(uint32_t dwStylesAdded, - uint32_t dwStylesRemoved) { - m_pProperties->m_dwStyles = - (m_pProperties->m_dwStyles & ~dwStylesRemoved) | dwStylesAdded; -} - -uint32_t IFWL_Widget::GetStylesEx() const { - return m_pProperties->m_dwStyleExes; -} -uint32_t IFWL_Widget::GetStates() const { - return m_pProperties->m_dwStates; -} - -void IFWL_Widget::ModifyStylesEx(uint32_t dwStylesExAdded, - uint32_t dwStylesExRemoved) { - m_pProperties->m_dwStyleExes = - (m_pProperties->m_dwStyleExes & ~dwStylesExRemoved) | dwStylesExAdded; -} - -static void NotifyHideChildWidget(CFWL_WidgetMgr* widgetMgr, - IFWL_Widget* widget, - CFWL_NoteDriver* noteDriver) { - IFWL_Widget* child = widgetMgr->GetFirstChildWidget(widget); - while (child) { - noteDriver->NotifyTargetHide(child); - NotifyHideChildWidget(widgetMgr, child, noteDriver); - child = widgetMgr->GetNextSiblingWidget(child); - } -} - -void IFWL_Widget::SetStates(uint32_t dwStates, bool bSet) { - bSet ? (m_pProperties->m_dwStates |= dwStates) - : (m_pProperties->m_dwStates &= ~dwStates); - if (!(dwStates & FWL_WGTSTATE_Invisible) || !bSet) - return; - - CFWL_NoteDriver* noteDriver = - static_cast<CFWL_NoteDriver*>(GetOwnerApp()->GetNoteDriver()); - CFWL_WidgetMgr* widgetMgr = GetOwnerApp()->GetWidgetMgr(); - noteDriver->NotifyTargetHide(this); - IFWL_Widget* child = widgetMgr->GetFirstChildWidget(this); - while (child) { - noteDriver->NotifyTargetHide(child); - NotifyHideChildWidget(widgetMgr, child, noteDriver); - child = widgetMgr->GetNextSiblingWidget(child); - } - return; -} - -FWL_WidgetHit IFWL_Widget::HitTest(FX_FLOAT fx, FX_FLOAT fy) { - CFX_RectF rtClient; - GetClientRect(rtClient); - if (rtClient.Contains(fx, fy)) - return FWL_WidgetHit::Client; - if (HasEdge()) { - CFX_RectF rtEdge; - GetEdgeRect(rtEdge); - if (rtEdge.Contains(fx, fy)) - return FWL_WidgetHit::Edge; - } - if (HasBorder()) { - CFX_RectF rtRelative; - GetRelativeRect(rtRelative); - if (rtRelative.Contains(fx, fy)) - return FWL_WidgetHit::Border; - } - return FWL_WidgetHit::Unknown; -} - -void IFWL_Widget::TransformTo(IFWL_Widget* pWidget, - FX_FLOAT& fx, - FX_FLOAT& fy) { - if (m_pWidgetMgr->IsFormDisabled()) { - CFX_SizeF szOffset; - if (IsParent(pWidget)) { - szOffset = GetOffsetFromParent(pWidget); - } else { - szOffset = pWidget->GetOffsetFromParent(this); - szOffset.x = -szOffset.x; - szOffset.y = -szOffset.y; - } - fx += szOffset.x; - fy += szOffset.y; - return; - } - CFX_RectF r; - CFX_Matrix m; - IFWL_Widget* parent = GetParent(); - if (parent) { - GetWidgetRect(r); - fx += r.left; - fy += r.top; - GetMatrix(m, true); - m.TransformPoint(fx, fy); - } - IFWL_Widget* form1 = m_pWidgetMgr->GetSystemFormWidget(this); - if (!form1) - return; - if (!pWidget) { - form1->GetWidgetRect(r); - fx += r.left; - fy += r.top; - return; - } - IFWL_Widget* form2 = m_pWidgetMgr->GetSystemFormWidget(pWidget); - if (!form2) - return; - if (form1 != form2) { - form1->GetWidgetRect(r); - fx += r.left; - fy += r.top; - form2->GetWidgetRect(r); - fx -= r.left; - fy -= r.top; - } - parent = pWidget->GetParent(); - if (parent) { - pWidget->GetMatrix(m, true); - CFX_Matrix m1; - m1.SetIdentity(); - m1.SetReverse(m); - m1.TransformPoint(fx, fy); - pWidget->GetWidgetRect(r); - fx -= r.left; - fy -= r.top; - } -} - -void IFWL_Widget::GetMatrix(CFX_Matrix& matrix, bool bGlobal) { - if (!m_pProperties) - return; - if (!bGlobal) { - matrix.SetIdentity(); - return; - } - - IFWL_Widget* parent = GetParent(); - CFX_ArrayTemplate<IFWL_Widget*> parents; - while (parent) { - parents.Add(parent); - parent = parent->GetParent(); - } - matrix.SetIdentity(); - CFX_Matrix ctmOnParent; - CFX_RectF rect; - int32_t count = parents.GetSize(); - for (int32_t i = count - 2; i >= 0; i--) { - parent = parents.GetAt(i); - parent->GetMatrix(ctmOnParent, false); - parent->GetWidgetRect(rect); - matrix.Concat(ctmOnParent, true); - matrix.Translate(rect.left, rect.top, true); - } - CFX_Matrix m; - m.SetIdentity(); - matrix.Concat(m, true); - parents.RemoveAll(); -} - -IFWL_ThemeProvider* IFWL_Widget::GetThemeProvider() const { - return m_pProperties->m_pThemeProvider; -} - -void IFWL_Widget::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) { - m_pProperties->m_pThemeProvider = pThemeProvider; -} - -bool IFWL_Widget::IsEnabled() const { - return (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) == 0; -} - -bool IFWL_Widget::IsActive() const { - return (m_pProperties->m_dwStates & FWL_WGTSTATE_Deactivated) == 0; -} - -bool IFWL_Widget::HasBorder() const { - return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Border); -} - -bool IFWL_Widget::HasEdge() const { - return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_EdgeMask); -} - -bool IFWL_Widget::IsVisible() const { - return (m_pProperties->m_dwStates & FWL_WGTSTATE_Invisible) == 0; -} - -bool IFWL_Widget::IsOverLapper() const { - return (m_pProperties->m_dwStyles & FWL_WGTSTYLE_WindowTypeMask) == - FWL_WGTSTYLE_OverLapper; -} - -bool IFWL_Widget::IsPopup() const { - return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Popup); -} - -bool IFWL_Widget::IsChild() const { - return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Child); -} - -bool IFWL_Widget::IsOffscreen() const { - return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Offscreen); -} - -void IFWL_Widget::GetEdgeRect(CFX_RectF& rtEdge) { - rtEdge = m_pProperties->m_rtWidget; - rtEdge.left = rtEdge.top = 0; - if (HasBorder()) { - FX_FLOAT fCX = GetBorderSize(); - FX_FLOAT fCY = GetBorderSize(false); - rtEdge.Deflate(fCX, fCY); - } -} - -FX_FLOAT IFWL_Widget::GetBorderSize(bool bCX) { - FX_FLOAT* pfBorder = static_cast<FX_FLOAT*>(GetThemeCapacity( - bCX ? CFWL_WidgetCapacity::CXBorder : CFWL_WidgetCapacity::CYBorder)); - if (!pfBorder) - return 0; - return *pfBorder; -} - -FX_FLOAT IFWL_Widget::GetEdgeWidth() { - CFWL_WidgetCapacity dwCapacity = CFWL_WidgetCapacity::None; - switch (m_pProperties->m_dwStyles & FWL_WGTSTYLE_EdgeMask) { - case FWL_WGTSTYLE_EdgeFlat: { - dwCapacity = CFWL_WidgetCapacity::EdgeFlat; - break; - } - case FWL_WGTSTYLE_EdgeRaised: { - dwCapacity = CFWL_WidgetCapacity::EdgeRaised; - break; - } - case FWL_WGTSTYLE_EdgeSunken: { - dwCapacity = CFWL_WidgetCapacity::EdgeSunken; - break; - } - } - if (dwCapacity != CFWL_WidgetCapacity::None) { - FX_FLOAT* fRet = static_cast<FX_FLOAT*>(GetThemeCapacity(dwCapacity)); - return fRet ? *fRet : 0; - } - return 0; -} - -void IFWL_Widget::GetRelativeRect(CFX_RectF& rect) { - rect = m_pProperties->m_rtWidget; - rect.left = rect.top = 0; -} - -void* IFWL_Widget::GetThemeCapacity(CFWL_WidgetCapacity dwCapacity) { - IFWL_ThemeProvider* pTheme = GetAvailableTheme(); - if (!pTheme) - return nullptr; - - CFWL_ThemePart part; - part.m_pWidget = this; - return pTheme->GetCapacity(&part, dwCapacity); -} - -IFWL_ThemeProvider* IFWL_Widget::GetAvailableTheme() { - if (m_pProperties->m_pThemeProvider) - return m_pProperties->m_pThemeProvider; - - IFWL_Widget* pUp = this; - do { - pUp = (pUp->GetStyles() & FWL_WGTSTYLE_Popup) - ? m_pWidgetMgr->GetOwnerWidget(pUp) - : m_pWidgetMgr->GetParentWidget(pUp); - if (pUp) { - IFWL_ThemeProvider* pRet = pUp->GetThemeProvider(); - if (pRet) - return pRet; - } - } while (pUp); - return nullptr; -} - -IFWL_Widget* IFWL_Widget::GetRootOuter() { - IFWL_Widget* pRet = m_pOuter; - if (!pRet) - return nullptr; - - while (IFWL_Widget* pOuter = pRet->GetOuter()) - pRet = pOuter; - return pRet; -} - -CFX_SizeF IFWL_Widget::CalcTextSize(const CFX_WideString& wsText, - IFWL_ThemeProvider* pTheme, - bool bMultiLine, - int32_t iLineWidth) { - if (!pTheme) - return CFX_SizeF(); - - CFWL_ThemeText calPart; - calPart.m_pWidget = this; - calPart.m_wsText = wsText; - calPart.m_dwTTOStyles = - bMultiLine ? FDE_TTOSTYLE_LineWrap : FDE_TTOSTYLE_SingleLine; - calPart.m_iTTOAlign = FDE_TTOALIGNMENT_TopLeft; - CFX_RectF rect; - FX_FLOAT fWidth = bMultiLine - ? (iLineWidth > 0 ? (FX_FLOAT)iLineWidth - : FWL_WGT_CalcMultiLineDefWidth) - : FWL_WGT_CalcWidth; - rect.Set(0, 0, fWidth, FWL_WGT_CalcHeight); - pTheme->CalcTextRect(&calPart, rect); - return CFX_SizeF(rect.width, rect.height); -} - -void IFWL_Widget::CalcTextRect(const CFX_WideString& wsText, - IFWL_ThemeProvider* pTheme, - uint32_t dwTTOStyles, - int32_t iTTOAlign, - CFX_RectF& rect) { - CFWL_ThemeText calPart; - calPart.m_pWidget = this; - calPart.m_wsText = wsText; - calPart.m_dwTTOStyles = dwTTOStyles; - calPart.m_iTTOAlign = iTTOAlign; - pTheme->CalcTextRect(&calPart, rect); -} - -void IFWL_Widget::SetFocus(bool bFocus) { - if (m_pWidgetMgr->IsFormDisabled()) - return; - - const CFWL_App* pApp = GetOwnerApp(); - if (!pApp) - return; - - CFWL_NoteDriver* pDriver = - static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver()); - if (!pDriver) - return; - - IFWL_Widget* curFocus = pDriver->GetFocus(); - if (bFocus && curFocus != this) - pDriver->SetFocus(this); - else if (!bFocus && curFocus == this) - pDriver->SetFocus(nullptr); -} - -void IFWL_Widget::SetGrab(bool bSet) { - const CFWL_App* pApp = GetOwnerApp(); - if (!pApp) - return; - - CFWL_NoteDriver* pDriver = - static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver()); - pDriver->SetGrab(this, bSet); -} - -void IFWL_Widget::GetPopupPos(FX_FLOAT fMinHeight, - FX_FLOAT fMaxHeight, - const CFX_RectF& rtAnchor, - CFX_RectF& rtPopup) { - if (GetClassID() == FWL_Type::ComboBox) { - if (m_pWidgetMgr->IsFormDisabled()) { - m_pWidgetMgr->GetAdapterPopupPos(this, fMinHeight, fMaxHeight, rtAnchor, - rtPopup); - return; - } - GetPopupPosComboBox(fMinHeight, fMaxHeight, rtAnchor, rtPopup); - return; - } - if (GetClassID() == FWL_Type::DateTimePicker && - m_pWidgetMgr->IsFormDisabled()) { - m_pWidgetMgr->GetAdapterPopupPos(this, fMinHeight, fMaxHeight, rtAnchor, - rtPopup); - return; - } - GetPopupPosGeneral(fMinHeight, fMaxHeight, rtAnchor, rtPopup); -} - -bool IFWL_Widget::GetPopupPosMenu(FX_FLOAT fMinHeight, - FX_FLOAT fMaxHeight, - const CFX_RectF& rtAnchor, - CFX_RectF& rtPopup) { - FX_FLOAT fx = 0; - FX_FLOAT fy = 0; - - if (GetStylesEx() & FWL_STYLEEXT_MNU_Vert) { - bool bLeft = m_pProperties->m_rtWidget.left < 0; - FX_FLOAT fRight = rtAnchor.right() + rtPopup.width; - TransformTo(nullptr, fx, fy); - if (fRight + fx > 0.0f || bLeft) { - rtPopup.Set(rtAnchor.left - rtPopup.width, rtAnchor.top, rtPopup.width, - rtPopup.height); - } else { - rtPopup.Set(rtAnchor.right(), rtAnchor.top, rtPopup.width, - rtPopup.height); - } - } else { - FX_FLOAT fBottom = rtAnchor.bottom() + rtPopup.height; - TransformTo(nullptr, fx, fy); - if (fBottom + fy > 0.0f) { - rtPopup.Set(rtAnchor.left, rtAnchor.top - rtPopup.height, rtPopup.width, - rtPopup.height); - } else { - rtPopup.Set(rtAnchor.left, rtAnchor.bottom(), rtPopup.width, - rtPopup.height); - } - } - rtPopup.Offset(fx, fy); - return true; -} - -bool IFWL_Widget::GetPopupPosComboBox(FX_FLOAT fMinHeight, - FX_FLOAT fMaxHeight, - const CFX_RectF& rtAnchor, - CFX_RectF& rtPopup) { - FX_FLOAT fx = 0; - FX_FLOAT fy = 0; - - FX_FLOAT fPopHeight = rtPopup.height; - if (rtPopup.height > fMaxHeight) - fPopHeight = fMaxHeight; - else if (rtPopup.height < fMinHeight) - fPopHeight = fMinHeight; - - FX_FLOAT fWidth = std::max(rtAnchor.width, rtPopup.width); - FX_FLOAT fBottom = rtAnchor.bottom() + fPopHeight; - TransformTo(nullptr, fx, fy); - if (fBottom + fy > 0.0f) - rtPopup.Set(rtAnchor.left, rtAnchor.top - fPopHeight, fWidth, fPopHeight); - else - rtPopup.Set(rtAnchor.left, rtAnchor.bottom(), fWidth, fPopHeight); - - rtPopup.Offset(fx, fy); - return true; -} - -bool IFWL_Widget::GetPopupPosGeneral(FX_FLOAT fMinHeight, - FX_FLOAT fMaxHeight, - const CFX_RectF& rtAnchor, - CFX_RectF& rtPopup) { - FX_FLOAT fx = 0; - FX_FLOAT fy = 0; - - TransformTo(nullptr, fx, fy); - if (rtAnchor.bottom() + fy > 0.0f) { - rtPopup.Set(rtAnchor.left, rtAnchor.top - rtPopup.height, rtPopup.width, - rtPopup.height); - } else { - rtPopup.Set(rtAnchor.left, rtAnchor.bottom(), rtPopup.width, - rtPopup.height); - } - rtPopup.Offset(fx, fy); - return true; -} - -void IFWL_Widget::RegisterEventTarget(IFWL_Widget* pEventSource) { - const CFWL_App* pApp = GetOwnerApp(); - if (!pApp) - return; - - CFWL_NoteDriver* pNoteDriver = pApp->GetNoteDriver(); - if (!pNoteDriver) - return; - - pNoteDriver->RegisterEventTarget(this, pEventSource); -} - -void IFWL_Widget::UnregisterEventTarget() { - const CFWL_App* pApp = GetOwnerApp(); - if (!pApp) - return; - - CFWL_NoteDriver* pNoteDriver = pApp->GetNoteDriver(); - if (!pNoteDriver) - return; - - pNoteDriver->UnregisterEventTarget(this); -} - -void IFWL_Widget::DispatchKeyEvent(CFWL_MsgKey* pNote) { - if (!pNote) - return; - - auto pEvent = pdfium::MakeUnique<CFWL_EvtKey>(); - pEvent->m_pSrcTarget = this; - pEvent->m_dwCmd = pNote->m_dwCmd; - pEvent->m_dwKeyCode = pNote->m_dwKeyCode; - pEvent->m_dwFlags = pNote->m_dwFlags; - DispatchEvent(pEvent.get()); -} - -void IFWL_Widget::DispatchEvent(CFWL_Event* pEvent) { - if (m_pOuter) { - m_pOuter->GetDelegate()->OnProcessEvent(pEvent); - return; - } - const CFWL_App* pApp = GetOwnerApp(); - if (!pApp) - return; - - CFWL_NoteDriver* pNoteDriver = pApp->GetNoteDriver(); - if (!pNoteDriver) - return; - pNoteDriver->SendEvent(pEvent); -} - -void IFWL_Widget::Repaint(const CFX_RectF* pRect) { - if (pRect) { - m_pWidgetMgr->RepaintWidget(this, pRect); - return; - } - CFX_RectF rect; - rect = m_pProperties->m_rtWidget; - rect.left = rect.top = 0; - m_pWidgetMgr->RepaintWidget(this, &rect); -} - -void IFWL_Widget::DrawBackground(CFX_Graphics* pGraphics, - CFWL_Part iPartBk, - IFWL_ThemeProvider* pTheme, - const CFX_Matrix* pMatrix) { - CFX_RectF rtRelative; - GetRelativeRect(rtRelative); - CFWL_ThemeBackground param; - param.m_pWidget = this; - param.m_iPart = iPartBk; - param.m_pGraphics = pGraphics; - if (pMatrix) - param.m_matrix.Concat(*pMatrix, true); - param.m_rtPart = rtRelative; - pTheme->DrawBackground(¶m); -} - -void IFWL_Widget::DrawBorder(CFX_Graphics* pGraphics, - CFWL_Part iPartBorder, - IFWL_ThemeProvider* pTheme, - const CFX_Matrix* pMatrix) { - CFX_RectF rtRelative; - GetRelativeRect(rtRelative); - CFWL_ThemeBackground param; - param.m_pWidget = this; - param.m_iPart = iPartBorder; - param.m_pGraphics = pGraphics; - if (pMatrix) - param.m_matrix.Concat(*pMatrix, true); - param.m_rtPart = rtRelative; - pTheme->DrawBackground(¶m); -} - -void IFWL_Widget::DrawEdge(CFX_Graphics* pGraphics, - CFWL_Part iPartEdge, - IFWL_ThemeProvider* pTheme, - const CFX_Matrix* pMatrix) { - CFX_RectF rtEdge; - GetEdgeRect(rtEdge); - CFWL_ThemeBackground param; - param.m_pWidget = this; - param.m_iPart = iPartEdge; - param.m_pGraphics = pGraphics; - if (pMatrix) - param.m_matrix.Concat(*pMatrix, true); - param.m_rtPart = rtEdge; - pTheme->DrawBackground(¶m); -} - -void IFWL_Widget::NotifyDriver() { - const CFWL_App* pApp = GetOwnerApp(); - if (!pApp) - return; - - CFWL_NoteDriver* pDriver = - static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver()); - if (!pDriver) - return; - - pDriver->NotifyTargetDestroy(this); -} - -CFX_SizeF IFWL_Widget::GetOffsetFromParent(IFWL_Widget* pParent) { - if (pParent == this) - return CFX_SizeF(); - - CFWL_WidgetMgr* pWidgetMgr = GetOwnerApp()->GetWidgetMgr(); - if (!pWidgetMgr) - return CFX_SizeF(); - - CFX_SizeF szRet(m_pProperties->m_rtWidget.left, - m_pProperties->m_rtWidget.top); - - IFWL_Widget* pDstWidget = GetParent(); - while (pDstWidget && pDstWidget != pParent) { - CFX_RectF rtDst; - pDstWidget->GetWidgetRect(rtDst); - szRet += CFX_SizeF(rtDst.left, rtDst.top); - pDstWidget = pWidgetMgr->GetParentWidget(pDstWidget); - } - return szRet; -} - -bool IFWL_Widget::IsParent(IFWL_Widget* pParent) { - IFWL_Widget* pUpWidget = GetParent(); - while (pUpWidget) { - if (pUpWidget == pParent) - return true; - pUpWidget = pUpWidget->GetParent(); - } - return false; -} - -void IFWL_Widget::OnProcessMessage(CFWL_Message* pMessage) { - if (!pMessage->m_pDstTarget) - return; - - IFWL_Widget* pWidget = pMessage->m_pDstTarget; - CFWL_MessageType dwMsgCode = pMessage->GetClassID(); - switch (dwMsgCode) { - case CFWL_MessageType::Mouse: { - CFWL_MsgMouse* pMsgMouse = static_cast<CFWL_MsgMouse*>(pMessage); - CFWL_EvtMouse evt; - evt.m_pSrcTarget = pWidget; - evt.m_pDstTarget = pWidget; - evt.m_dwCmd = pMsgMouse->m_dwCmd; - evt.m_dwFlags = pMsgMouse->m_dwFlags; - evt.m_fx = pMsgMouse->m_fx; - evt.m_fy = pMsgMouse->m_fy; - pWidget->DispatchEvent(&evt); - break; - } - case CFWL_MessageType::MouseWheel: { - CFWL_MsgMouseWheel* pMsgMouseWheel = - static_cast<CFWL_MsgMouseWheel*>(pMessage); - CFWL_EvtMouseWheel evt; - evt.m_pSrcTarget = pWidget; - evt.m_pDstTarget = pWidget; - evt.m_dwFlags = pMsgMouseWheel->m_dwFlags; - evt.m_fDeltaX = pMsgMouseWheel->m_fDeltaX; - evt.m_fDeltaY = pMsgMouseWheel->m_fDeltaY; - evt.m_fx = pMsgMouseWheel->m_fx; - evt.m_fy = pMsgMouseWheel->m_fy; - pWidget->DispatchEvent(&evt); - break; - } - case CFWL_MessageType::Key: { - CFWL_MsgKey* pMsgKey = static_cast<CFWL_MsgKey*>(pMessage); - CFWL_EvtKey evt; - evt.m_pSrcTarget = pWidget; - evt.m_pDstTarget = pWidget; - evt.m_dwKeyCode = pMsgKey->m_dwKeyCode; - evt.m_dwFlags = pMsgKey->m_dwFlags; - evt.m_dwCmd = pMsgKey->m_dwCmd; - pWidget->DispatchEvent(&evt); - break; - } - case CFWL_MessageType::SetFocus: { - CFWL_MsgSetFocus* pMsgSetFocus = static_cast<CFWL_MsgSetFocus*>(pMessage); - CFWL_EvtSetFocus evt; - evt.m_pSrcTarget = pMsgSetFocus->m_pDstTarget; - evt.m_pDstTarget = pMsgSetFocus->m_pDstTarget; - evt.m_pSetFocus = pWidget; - pWidget->DispatchEvent(&evt); - break; - } - case CFWL_MessageType::KillFocus: { - CFWL_MsgKillFocus* pMsgKillFocus = - static_cast<CFWL_MsgKillFocus*>(pMessage); - CFWL_EvtKillFocus evt; - evt.m_pSrcTarget = pMsgKillFocus->m_pDstTarget; - evt.m_pDstTarget = pMsgKillFocus->m_pDstTarget; - evt.m_pKillFocus = pWidget; - pWidget->DispatchEvent(&evt); - break; - } - default: - break; - } -} - -void IFWL_Widget::OnProcessEvent(CFWL_Event* pEvent) {} - -void IFWL_Widget::OnDrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix) {} diff --git a/xfa/fwl/core/ifwl_widget.h b/xfa/fwl/core/ifwl_widget.h deleted file mode 100644 index 056a0c861e..0000000000 --- a/xfa/fwl/core/ifwl_widget.h +++ /dev/null @@ -1,217 +0,0 @@ -// 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 - -#ifndef XFA_FWL_CORE_IFWL_WIDGET_H_ -#define XFA_FWL_CORE_IFWL_WIDGET_H_ - -#include <memory> - -#include "core/fxcrt/fx_coordinates.h" -#include "core/fxcrt/fx_system.h" -#include "xfa/fwl/core/cfwl_event.h" -#include "xfa/fwl/core/cfwl_themepart.h" -#include "xfa/fwl/core/cfwl_widgetmgr.h" -#include "xfa/fwl/core/fwl_widgethit.h" -#include "xfa/fwl/core/ifwl_widgetdelegate.h" -#include "xfa/fwl/theme/cfwl_widgettp.h" - -// FWL contains two parallel inheritance hierarchies, which reference each -// other via pointers as follows: -// -// m_pAssociate -// <---------- -// CFWL_Widget ----------> IFWL_Widget -// | m_pIface | -// A A -// | | -// CFWL_... IFWL_... -// -// TODO(tsepez): Collapse these into a single hierarchy. -// - -enum class FWL_Type { - Unknown = 0, - - Barcode, - Caret, - CheckBox, - ComboBox, - DateTimePicker, - Edit, - Form, - FormProxy, - ListBox, - MonthCalendar, - PictureBox, - PushButton, - ScrollBar, - SpinButton, - ToolTip -}; - -class CFWL_AppImp; -class CFWL_MsgKey; -class CFWL_Widget; -class CFWL_WidgetProperties; -class CFWL_WidgetMgr; -class CFWL_App; -class IFWL_ThemeProvider; -class IFWL_Widget; -enum class FWL_Type; - -class IFWL_Widget : public IFWL_WidgetDelegate { - public: - ~IFWL_Widget() override; - - virtual FWL_Type GetClassID() const = 0; - virtual bool IsInstance(const CFX_WideStringC& wsClass) const; - virtual void GetWidgetRect(CFX_RectF& rect, bool bAutoSize = false); - virtual void GetClientRect(CFX_RectF& rect); - virtual void ModifyStylesEx(uint32_t dwStylesExAdded, - uint32_t dwStylesExRemoved); - virtual void SetStates(uint32_t dwStates, bool bSet = true); - virtual void Update() = 0; - virtual FWL_WidgetHit HitTest(FX_FLOAT fx, FX_FLOAT fy); - virtual void DrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix = nullptr) = 0; - virtual void SetThemeProvider(IFWL_ThemeProvider* pThemeProvider); - - // IFWL_WidgetDelegate. - void OnProcessMessage(CFWL_Message* pMessage) override; - void OnProcessEvent(CFWL_Event* pEvent) override; - void OnDrawWidget(CFX_Graphics* pGraphics, - const CFX_Matrix* pMatrix = nullptr) override; - - void SetWidgetRect(const CFX_RectF& rect); - - void SetParent(IFWL_Widget* pParent); - - IFWL_Widget* GetOwner() { return m_pWidgetMgr->GetOwnerWidget(this); } - IFWL_Widget* GetOuter() const { return m_pOuter; } - - uint32_t GetStyles() const; - void ModifyStyles(uint32_t dwStylesAdded, uint32_t dwStylesRemoved); - uint32_t GetStylesEx() const; - uint32_t GetStates() const; - - void LockUpdate() { m_iLock++; } - void UnlockUpdate() { - if (IsLocked()) - m_iLock--; - } - - void TransformTo(IFWL_Widget* pWidget, FX_FLOAT& fx, FX_FLOAT& fy); - void GetMatrix(CFX_Matrix& matrix, bool bGlobal = false); - IFWL_ThemeProvider* GetThemeProvider() const; - - void SetDelegate(IFWL_WidgetDelegate* delegate) { m_pDelegate = delegate; } - IFWL_WidgetDelegate* GetDelegate() { - return m_pDelegate ? m_pDelegate : this; - } - const IFWL_WidgetDelegate* GetDelegate() const { - return m_pDelegate ? m_pDelegate : this; - } - - const CFWL_App* GetOwnerApp() const { return m_pOwnerApp; } - uint32_t GetEventKey() const { return m_nEventKey; } - void SetEventKey(uint32_t key) { m_nEventKey = key; } - - void* GetLayoutItem() const { return m_pLayoutItem; } - void SetLayoutItem(void* pItem) { m_pLayoutItem = pItem; } - - void SetAssociateWidget(CFWL_Widget* pAssociate) { - m_pAssociate = pAssociate; - } - - void SetFocus(bool bFocus); - void Repaint(const CFX_RectF* pRect = nullptr); - - protected: - IFWL_Widget(const CFWL_App* app, - std::unique_ptr<CFWL_WidgetProperties> properties, - IFWL_Widget* pOuter); - - bool IsEnabled() const; - bool IsActive() const; - bool IsLocked() const { return m_iLock > 0; } - bool HasBorder() const; - bool HasEdge() const; - void GetEdgeRect(CFX_RectF& rtEdge); - FX_FLOAT GetBorderSize(bool bCX = true); - FX_FLOAT GetEdgeWidth(); - void GetRelativeRect(CFX_RectF& rect); - void* GetThemeCapacity(CFWL_WidgetCapacity dwCapacity); - IFWL_ThemeProvider* GetAvailableTheme(); - CFX_SizeF CalcTextSize(const CFX_WideString& wsText, - IFWL_ThemeProvider* pTheme, - bool bMultiLine = false, - int32_t iLineWidth = -1); - void CalcTextRect(const CFX_WideString& wsText, - IFWL_ThemeProvider* pTheme, - uint32_t dwTTOStyles, - int32_t iTTOAlign, - CFX_RectF& rect); - void SetGrab(bool bSet); - void GetPopupPos(FX_FLOAT fMinHeight, - FX_FLOAT fMaxHeight, - const CFX_RectF& rtAnchor, - CFX_RectF& rtPopup); - void RegisterEventTarget(IFWL_Widget* pEventSource); - void UnregisterEventTarget(); - void DispatchKeyEvent(CFWL_MsgKey* pNote); - void DispatchEvent(CFWL_Event* pEvent); - void DrawBorder(CFX_Graphics* pGraphics, - CFWL_Part iPartBorder, - IFWL_ThemeProvider* pTheme, - const CFX_Matrix* pMatrix = nullptr); - void DrawEdge(CFX_Graphics* pGraphics, - CFWL_Part iPartEdge, - IFWL_ThemeProvider* pTheme, - const CFX_Matrix* pMatrix = nullptr); - - const CFWL_App* const m_pOwnerApp; - CFWL_WidgetMgr* const m_pWidgetMgr; - std::unique_ptr<CFWL_WidgetProperties> m_pProperties; - IFWL_Widget* m_pOuter; - int32_t m_iLock; - - private: - IFWL_Widget* GetParent() { return m_pWidgetMgr->GetParentWidget(this); } - CFX_SizeF GetOffsetFromParent(IFWL_Widget* pParent); - - bool IsVisible() const; - bool IsOverLapper() const; - bool IsPopup() const; - bool IsChild() const; - bool IsOffscreen() const; - IFWL_Widget* GetRootOuter(); - bool GetPopupPosMenu(FX_FLOAT fMinHeight, - FX_FLOAT fMaxHeight, - const CFX_RectF& rtAnchor, - CFX_RectF& rtPopup); - bool GetPopupPosComboBox(FX_FLOAT fMinHeight, - FX_FLOAT fMaxHeight, - const CFX_RectF& rtAnchor, - CFX_RectF& rtPopup); - bool GetPopupPosGeneral(FX_FLOAT fMinHeight, - FX_FLOAT fMaxHeight, - const CFX_RectF& rtAnchor, - CFX_RectF& rtPopup); - bool GetScreenSize(FX_FLOAT& fx, FX_FLOAT& fy); - void DrawBackground(CFX_Graphics* pGraphics, - CFWL_Part iPartBk, - IFWL_ThemeProvider* pTheme, - const CFX_Matrix* pMatrix = nullptr); - void NotifyDriver(); - bool IsParent(IFWL_Widget* pParent); - - void* m_pLayoutItem; - CFWL_Widget* m_pAssociate; - uint32_t m_nEventKey; - IFWL_WidgetDelegate* m_pDelegate; // Not owned. -}; - -#endif // XFA_FWL_CORE_IFWL_WIDGET_H_ diff --git a/xfa/fwl/core/ifwl_widgetmgrdelegate.h b/xfa/fwl/core/ifwl_widgetmgrdelegate.h index c832692314..67f73d3315 100644 --- a/xfa/fwl/core/ifwl_widgetmgrdelegate.h +++ b/xfa/fwl/core/ifwl_widgetmgrdelegate.h @@ -10,13 +10,13 @@ class CFWL_Message; class CFX_Graphics; class CFX_Matrix; -class IFWL_Widget; +class CFWL_Widget; -class IFWL_WidgetMgrDelegate { +class CFWL_WidgetMgrDelegate { public: virtual void OnSetCapability(uint32_t dwCapability) = 0; virtual void OnProcessMessageToForm(CFWL_Message* pMessage) = 0; - virtual void OnDrawWidget(IFWL_Widget* pWidget, + virtual void OnDrawWidget(CFWL_Widget* pWidget, CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix) = 0; }; |