summaryrefslogtreecommitdiff
path: root/xfa/fwl/core
diff options
context:
space:
mode:
authordsinclair <dsinclair@chromium.org>2016-11-23 16:17:20 -0800
committerCommit bot <commit-bot@chromium.org>2016-11-23 16:17:21 -0800
commit2c489cc41023a40648dfde988d11b8ec2b66c7d0 (patch)
tree78255c80c547a5954ed5778f1a809d3166a5f3e2 /xfa/fwl/core
parent0ce11eef157b791c661d7e82e1c5641605b9f03d (diff)
downloadpdfium-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')
-rw-r--r--xfa/fwl/core/cfwl_app.cpp2
-rw-r--r--xfa/fwl/core/cfwl_app.h2
-rw-r--r--xfa/fwl/core/cfwl_barcode.cpp229
-rw-r--r--xfa/fwl/core/cfwl_barcode.h65
-rw-r--r--xfa/fwl/core/cfwl_caret.cpp4
-rw-r--r--xfa/fwl/core/cfwl_caret.h10
-rw-r--r--xfa/fwl/core/cfwl_checkbox.cpp474
-rw-r--r--xfa/fwl/core/cfwl_checkbox.h73
-rw-r--r--xfa/fwl/core/cfwl_combobox.cpp1118
-rw-r--r--xfa/fwl/core/cfwl_combobox.h165
-rw-r--r--xfa/fwl/core/cfwl_comboboxproxy.cpp8
-rw-r--r--xfa/fwl/core/cfwl_comboboxproxy.h8
-rw-r--r--xfa/fwl/core/cfwl_comboedit.cpp10
-rw-r--r--xfa/fwl/core/cfwl_comboedit.h14
-rw-r--r--xfa/fwl/core/cfwl_combolist.cpp24
-rw-r--r--xfa/fwl/core/cfwl_combolist.h10
-rw-r--r--xfa/fwl/core/cfwl_datetimeedit.cpp16
-rw-r--r--xfa/fwl/core/cfwl_datetimeedit.h10
-rw-r--r--xfa/fwl/core/cfwl_datetimepicker.cpp644
-rw-r--r--xfa/fwl/core/cfwl_datetimepicker.h102
-rw-r--r--xfa/fwl/core/cfwl_edit.cpp1633
-rw-r--r--xfa/fwl/core/cfwl_edit.h168
-rw-r--r--xfa/fwl/core/cfwl_event.h6
-rw-r--r--xfa/fwl/core/cfwl_eventtarget.cpp6
-rw-r--r--xfa/fwl/core/cfwl_eventtarget.h10
-rw-r--r--xfa/fwl/core/cfwl_evtkillfocus.h2
-rw-r--r--xfa/fwl/core/cfwl_evtsetfocus.h2
-rw-r--r--xfa/fwl/core/cfwl_evtsizechanged.h2
-rw-r--r--xfa/fwl/core/cfwl_evtvalidate.h2
-rw-r--r--xfa/fwl/core/cfwl_form.cpp8
-rw-r--r--xfa/fwl/core/cfwl_form.h18
-rw-r--r--xfa/fwl/core/cfwl_formproxy.cpp2
-rw-r--r--xfa/fwl/core/cfwl_formproxy.h4
-rw-r--r--xfa/fwl/core/cfwl_listbox.cpp1123
-rw-r--r--xfa/fwl/core/cfwl_listbox.h145
-rw-r--r--xfa/fwl/core/cfwl_message.h6
-rw-r--r--xfa/fwl/core/cfwl_monthcalendar.cpp18
-rw-r--r--xfa/fwl/core/cfwl_monthcalendar.h8
-rw-r--r--xfa/fwl/core/cfwl_msgkillfocus.h2
-rw-r--r--xfa/fwl/core/cfwl_msgsetfocus.h2
-rw-r--r--xfa/fwl/core/cfwl_notedriver.cpp64
-rw-r--r--xfa/fwl/core/cfwl_notedriver.h46
-rw-r--r--xfa/fwl/core/cfwl_noteloop.h8
-rw-r--r--xfa/fwl/core/cfwl_picturebox.cpp50
-rw-r--r--xfa/fwl/core/cfwl_picturebox.h36
-rw-r--r--xfa/fwl/core/cfwl_pushbutton.cpp301
-rw-r--r--xfa/fwl/core/cfwl_pushbutton.h54
-rw-r--r--xfa/fwl/core/cfwl_scrollbar.cpp6
-rw-r--r--xfa/fwl/core/cfwl_scrollbar.h10
-rw-r--r--xfa/fwl/core/cfwl_spinbutton.cpp6
-rw-r--r--xfa/fwl/core/cfwl_spinbutton.h6
-rw-r--r--xfa/fwl/core/cfwl_themepart.h4
-rw-r--r--xfa/fwl/core/cfwl_timer.cpp2
-rw-r--r--xfa/fwl/core/cfwl_timer.h6
-rw-r--r--xfa/fwl/core/cfwl_widget.cpp784
-rw-r--r--xfa/fwl/core/cfwl_widget.h194
-rw-r--r--xfa/fwl/core/cfwl_widgetmgr.cpp106
-rw-r--r--xfa/fwl/core/cfwl_widgetmgr.h82
-rw-r--r--xfa/fwl/core/cfwl_widgetproperties.h8
-rw-r--r--xfa/fwl/core/ifwl_barcode.cpp175
-rw-r--r--xfa/fwl/core/ifwl_barcode.h92
-rw-r--r--xfa/fwl/core/ifwl_checkbox.cpp483
-rw-r--r--xfa/fwl/core/ifwl_checkbox.h100
-rw-r--r--xfa/fwl/core/ifwl_combobox.cpp1130
-rw-r--r--xfa/fwl/core/ifwl_combobox.h176
-rw-r--r--xfa/fwl/core/ifwl_datetimepicker.cpp661
-rw-r--r--xfa/fwl/core/ifwl_datetimepicker.h120
-rw-r--r--xfa/fwl/core/ifwl_edit.cpp1661
-rw-r--r--xfa/fwl/core/ifwl_edit.h197
-rw-r--r--xfa/fwl/core/ifwl_listbox.cpp1126
-rw-r--r--xfa/fwl/core/ifwl_listbox.h168
-rw-r--r--xfa/fwl/core/ifwl_picturebox.cpp68
-rw-r--r--xfa/fwl/core/ifwl_picturebox.h54
-rw-r--r--xfa/fwl/core/ifwl_pushbutton.cpp316
-rw-r--r--xfa/fwl/core/ifwl_pushbutton.h72
-rw-r--r--xfa/fwl/core/ifwl_themeprovider.h2
-rw-r--r--xfa/fwl/core/ifwl_widget.cpp803
-rw-r--r--xfa/fwl/core/ifwl_widget.h217
-rw-r--r--xfa/fwl/core/ifwl_widgetmgrdelegate.h6
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(&param);
+
+ param.m_iPart = CFWL_Part::CheckBox;
+ param.m_rtPart = m_rtBox;
+ pTheme->DrawBackground(&param);
+
+ 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(&param);
+
+ 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(&param);
}
-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(&param);
}
-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(&param);
+ }
+ 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(&param);
+}
+
+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(&param);
+
+ 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(&param);
+}
+
+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(&param);
+ }
+
+ 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(&param);
+ }
+ 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(&param);
+}
+
+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(&param);
+ }
+ }
+
+ 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(&param);
+ }
+
+ 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(&param);
+}
+
+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(&param);
+}
+
+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(&param);
}
-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(&param);
}
-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(&param);
-
- param.m_iPart = CFWL_Part::CheckBox;
- param.m_rtPart = m_rtBox;
- pTheme->DrawBackground(&param);
-
- 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(&param);
-
- 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(&param);
-}
-
-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(&param);
-}
-
-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(&param);
- }
- 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(&param);
-}
-
-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(&param);
-
- 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(&param);
-}
-
-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(&param);
- }
-
- 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(&param);
- }
- 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(&param);
-}
-
-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(&param);
- }
- }
-
- 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(&param);
- }
-
- 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(&param);
-}
-
-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(&param);
-}
-
-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(&param);
-}
-
-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(&param);
-}
-
-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;
};