summaryrefslogtreecommitdiff
path: root/xfa/fwl/core
diff options
context:
space:
mode:
Diffstat (limited to 'xfa/fwl/core')
-rw-r--r--xfa/fwl/core/cfwl_message.h1
-rw-r--r--xfa/fwl/core/cfwl_widgetmgr.cpp1
-rw-r--r--xfa/fwl/core/cfx_barcode.cpp338
-rw-r--r--xfa/fwl/core/cfx_barcode.h60
-rw-r--r--xfa/fwl/core/fwl_formimp.h181
-rw-r--r--xfa/fwl/core/fwl_noteimp.cpp64
-rw-r--r--xfa/fwl/core/fwl_noteimp.h20
-rw-r--r--xfa/fwl/core/fwl_widgetimp.h181
-rw-r--r--xfa/fwl/core/ifwl_barcode.cpp208
-rw-r--r--xfa/fwl/core/ifwl_barcode.h97
-rw-r--r--xfa/fwl/core/ifwl_caret.cpp144
-rw-r--r--xfa/fwl/core/ifwl_caret.h78
-rw-r--r--xfa/fwl/core/ifwl_checkbox.cpp574
-rw-r--r--xfa/fwl/core/ifwl_checkbox.h117
-rw-r--r--xfa/fwl/core/ifwl_combobox.cpp1444
-rw-r--r--xfa/fwl/core/ifwl_combobox.h244
-rw-r--r--xfa/fwl/core/ifwl_comboedit.cpp86
-rw-r--r--xfa/fwl/core/ifwl_comboedit.h44
-rw-r--r--xfa/fwl/core/ifwl_combolist.cpp298
-rw-r--r--xfa/fwl/core/ifwl_combolist.h54
-rw-r--r--xfa/fwl/core/ifwl_datetimecalendar.cpp222
-rw-r--r--xfa/fwl/core/ifwl_datetimecalendar.h47
-rw-r--r--xfa/fwl/core/ifwl_datetimeedit.cpp79
-rw-r--r--xfa/fwl/core/ifwl_datetimeedit.h44
-rw-r--r--xfa/fwl/core/ifwl_datetimepicker.cpp873
-rw-r--r--xfa/fwl/core/ifwl_datetimepicker.h200
-rw-r--r--xfa/fwl/core/ifwl_edit.cpp2053
-rw-r--r--xfa/fwl/core/ifwl_edit.h284
-rw-r--r--xfa/fwl/core/ifwl_form.cpp (renamed from xfa/fwl/core/fwl_formimp.cpp)223
-rw-r--r--xfa/fwl/core/ifwl_form.h161
-rw-r--r--xfa/fwl/core/ifwl_formproxy.cpp67
-rw-r--r--xfa/fwl/core/ifwl_formproxy.h47
-rw-r--r--xfa/fwl/core/ifwl_listbox.cpp1218
-rw-r--r--xfa/fwl/core/ifwl_listbox.h210
-rw-r--r--xfa/fwl/core/ifwl_monthcalendar.cpp1232
-rw-r--r--xfa/fwl/core/ifwl_monthcalendar.h280
-rw-r--r--xfa/fwl/core/ifwl_picturebox.cpp154
-rw-r--r--xfa/fwl/core/ifwl_picturebox.h91
-rw-r--r--xfa/fwl/core/ifwl_pushbutton.cpp563
-rw-r--r--xfa/fwl/core/ifwl_pushbutton.h99
-rw-r--r--xfa/fwl/core/ifwl_scrollbar.cpp788
-rw-r--r--xfa/fwl/core/ifwl_scrollbar.h175
-rw-r--r--xfa/fwl/core/ifwl_spinbutton.cpp436
-rw-r--r--xfa/fwl/core/ifwl_spinbutton.h88
-rw-r--r--xfa/fwl/core/ifwl_timer.cpp (renamed from xfa/fwl/core/fwl_timerimp.cpp)0
-rw-r--r--xfa/fwl/core/ifwl_tooltip.cpp286
-rw-r--r--xfa/fwl/core/ifwl_tooltip.h114
-rw-r--r--xfa/fwl/core/ifwl_widget.cpp (renamed from xfa/fwl/core/fwl_widgetimp.cpp)533
-rw-r--r--xfa/fwl/core/ifwl_widget.h218
49 files changed, 14097 insertions, 922 deletions
diff --git a/xfa/fwl/core/cfwl_message.h b/xfa/fwl/core/cfwl_message.h
index 6089fdcf4f..2bffff0007 100644
--- a/xfa/fwl/core/cfwl_message.h
+++ b/xfa/fwl/core/cfwl_message.h
@@ -7,6 +7,7 @@
#ifndef XFA_FWL_CORE_CFWL_MESSAGE_H_
#define XFA_FWL_CORE_CFWL_MESSAGE_H_
+#include "core/fxcrt/fx_basic.h"
#include "core/fxcrt/fx_string.h"
#include "core/fxcrt/fx_system.h"
#include "xfa/fwl/core/fwl_error.h"
diff --git a/xfa/fwl/core/cfwl_widgetmgr.cpp b/xfa/fwl/core/cfwl_widgetmgr.cpp
index 30571c9aed..e7f8b3819c 100644
--- a/xfa/fwl/core/cfwl_widgetmgr.cpp
+++ b/xfa/fwl/core/cfwl_widgetmgr.cpp
@@ -8,7 +8,6 @@
#include "xfa/fwl/core/cfwl_message.h"
#include "xfa/fwl/core/fwl_noteimp.h"
-#include "xfa/fwl/core/fwl_widgetimp.h"
#include "xfa/fwl/core/ifwl_app.h"
#include "xfa/fwl/core/ifwl_form.h"
#include "xfa/fxfa/app/xfa_fwladapter.h"
diff --git a/xfa/fwl/core/cfx_barcode.cpp b/xfa/fwl/core/cfx_barcode.cpp
new file mode 100644
index 0000000000..549f908229
--- /dev/null
+++ b/xfa/fwl/core/cfx_barcode.cpp
@@ -0,0 +1,338 @@
+// 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/cfx_barcode.h"
+
+#include "xfa/fxbarcode/cbc_codabar.h"
+#include "xfa/fxbarcode/cbc_code128.h"
+#include "xfa/fxbarcode/cbc_code39.h"
+#include "xfa/fxbarcode/cbc_codebase.h"
+#include "xfa/fxbarcode/cbc_datamatrix.h"
+#include "xfa/fxbarcode/cbc_ean13.h"
+#include "xfa/fxbarcode/cbc_ean8.h"
+#include "xfa/fxbarcode/cbc_pdf417i.h"
+#include "xfa/fxbarcode/cbc_qrcode.h"
+#include "xfa/fxbarcode/cbc_upca.h"
+#include "xfa/fxbarcode/utils.h"
+
+namespace {
+
+CBC_CodeBase* CreateBarCodeEngineObject(BC_TYPE type) {
+ switch (type) {
+ case BC_CODE39:
+ return new CBC_Code39();
+ case BC_CODABAR:
+ return new CBC_Codabar();
+ case BC_CODE128:
+ return new CBC_Code128(BC_CODE128_B);
+ case BC_CODE128_B:
+ return new CBC_Code128(BC_CODE128_B);
+ case BC_CODE128_C:
+ return new CBC_Code128(BC_CODE128_C);
+ case BC_EAN8:
+ return new CBC_EAN8();
+ case BC_UPCA:
+ return new CBC_UPCA();
+ case BC_EAN13:
+ return new CBC_EAN13();
+ case BC_QR_CODE:
+ return new CBC_QRCode();
+ case BC_PDF417:
+ return new CBC_PDF417I();
+ case BC_DATAMATRIX:
+ return new CBC_DataMatrix();
+ case BC_UNKNOWN:
+ default:
+ return nullptr;
+ }
+}
+
+} // namespace
+
+CFX_Barcode::CFX_Barcode() {}
+
+CFX_Barcode::~CFX_Barcode() {}
+
+FX_BOOL CFX_Barcode::Create(BC_TYPE type) {
+ m_pBCEngine.reset(CreateBarCodeEngineObject(type));
+ return !!m_pBCEngine;
+}
+BC_TYPE CFX_Barcode::GetType() {
+ return m_pBCEngine ? m_pBCEngine->GetType() : BC_UNKNOWN;
+}
+FX_BOOL CFX_Barcode::SetCharEncoding(BC_CHAR_ENCODING encoding) {
+ return m_pBCEngine ? m_pBCEngine->SetCharEncoding(encoding) : FALSE;
+}
+FX_BOOL CFX_Barcode::SetModuleHeight(int32_t moduleHeight) {
+ return m_pBCEngine ? m_pBCEngine->SetModuleHeight(moduleHeight) : FALSE;
+}
+FX_BOOL CFX_Barcode::SetModuleWidth(int32_t moduleWidth) {
+ return m_pBCEngine ? m_pBCEngine->SetModuleWidth(moduleWidth) : FALSE;
+}
+FX_BOOL CFX_Barcode::SetHeight(int32_t height) {
+ return m_pBCEngine ? m_pBCEngine->SetHeight(height) : FALSE;
+}
+FX_BOOL CFX_Barcode::SetWidth(int32_t width) {
+ return m_pBCEngine ? m_pBCEngine->SetWidth(width) : FALSE;
+}
+FX_BOOL CFX_Barcode::CheckContentValidity(const CFX_WideStringC& contents) {
+ switch (GetType()) {
+ case BC_CODE39:
+ case BC_CODABAR:
+ case BC_CODE128:
+ case BC_CODE128_B:
+ case BC_CODE128_C:
+ case BC_EAN8:
+ case BC_EAN13:
+ case BC_UPCA:
+ return m_pBCEngine
+ ? static_cast<CBC_OneCode*>(m_pBCEngine.get())
+ ->CheckContentValidity(contents)
+ : TRUE;
+ default:
+ return TRUE;
+ }
+}
+FX_BOOL CFX_Barcode::SetPrintChecksum(FX_BOOL checksum) {
+ switch (GetType()) {
+ case BC_CODE39:
+ case BC_CODABAR:
+ case BC_CODE128:
+ case BC_CODE128_B:
+ case BC_CODE128_C:
+ case BC_EAN8:
+ case BC_EAN13:
+ case BC_UPCA:
+ return m_pBCEngine ? (static_cast<CBC_OneCode*>(m_pBCEngine.get())
+ ->SetPrintChecksum(checksum),
+ TRUE)
+ : FALSE;
+ default:
+ return FALSE;
+ }
+}
+FX_BOOL CFX_Barcode::SetDataLength(int32_t length) {
+ switch (GetType()) {
+ case BC_CODE39:
+ case BC_CODABAR:
+ case BC_CODE128:
+ case BC_CODE128_B:
+ case BC_CODE128_C:
+ case BC_EAN8:
+ case BC_EAN13:
+ case BC_UPCA:
+ return m_pBCEngine ? (static_cast<CBC_OneCode*>(m_pBCEngine.get())
+ ->SetDataLength(length),
+ TRUE)
+ : FALSE;
+ default:
+ return FALSE;
+ }
+}
+FX_BOOL CFX_Barcode::SetCalChecksum(int32_t state) {
+ switch (GetType()) {
+ case BC_CODE39:
+ case BC_CODABAR:
+ case BC_CODE128:
+ case BC_CODE128_B:
+ case BC_CODE128_C:
+ case BC_EAN8:
+ case BC_EAN13:
+ case BC_UPCA:
+ return m_pBCEngine ? (static_cast<CBC_OneCode*>(m_pBCEngine.get())
+ ->SetCalChecksum(state),
+ TRUE)
+ : FALSE;
+ default:
+ return FALSE;
+ }
+}
+FX_BOOL CFX_Barcode::SetFont(CFX_Font* pFont) {
+ switch (GetType()) {
+ case BC_CODE39:
+ case BC_CODABAR:
+ case BC_CODE128:
+ case BC_CODE128_B:
+ case BC_CODE128_C:
+ case BC_EAN8:
+ case BC_EAN13:
+ case BC_UPCA:
+ return m_pBCEngine
+ ? static_cast<CBC_OneCode*>(m_pBCEngine.get())->SetFont(pFont)
+ : FALSE;
+ default:
+ return FALSE;
+ }
+}
+FX_BOOL CFX_Barcode::SetFontSize(FX_FLOAT size) {
+ switch (GetType()) {
+ case BC_CODE39:
+ case BC_CODABAR:
+ case BC_CODE128:
+ case BC_CODE128_B:
+ case BC_CODE128_C:
+ case BC_EAN8:
+ case BC_EAN13:
+ case BC_UPCA:
+ return m_pBCEngine ? (static_cast<CBC_OneCode*>(m_pBCEngine.get())
+ ->SetFontSize(size),
+ TRUE)
+ : FALSE;
+ default:
+ return FALSE;
+ }
+}
+FX_BOOL CFX_Barcode::SetFontStyle(int32_t style) {
+ switch (GetType()) {
+ case BC_CODE39:
+ case BC_CODABAR:
+ case BC_CODE128:
+ case BC_CODE128_B:
+ case BC_CODE128_C:
+ case BC_EAN8:
+ case BC_EAN13:
+ case BC_UPCA:
+ return m_pBCEngine ? (static_cast<CBC_OneCode*>(m_pBCEngine.get())
+ ->SetFontStyle(style),
+ TRUE)
+ : FALSE;
+ default:
+ return FALSE;
+ }
+}
+FX_BOOL CFX_Barcode::SetFontColor(FX_ARGB color) {
+ switch (GetType()) {
+ case BC_CODE39:
+ case BC_CODABAR:
+ case BC_CODE128:
+ case BC_CODE128_B:
+ case BC_CODE128_C:
+ case BC_EAN8:
+ case BC_EAN13:
+ case BC_UPCA:
+ return m_pBCEngine ? (static_cast<CBC_OneCode*>(m_pBCEngine.get())
+ ->SetFontColor(color),
+ TRUE)
+ : FALSE;
+ default:
+ return FALSE;
+ }
+}
+FX_BOOL CFX_Barcode::SetTextLocation(BC_TEXT_LOC location) {
+ typedef FX_BOOL (CBC_CodeBase::*memptrtype)(BC_TEXT_LOC);
+ memptrtype memptr = nullptr;
+ switch (GetType()) {
+ case BC_CODE39:
+ memptr = (memptrtype)&CBC_Code39::SetTextLocation;
+ break;
+ case BC_CODABAR:
+ memptr = (memptrtype)&CBC_Codabar::SetTextLocation;
+ break;
+ case BC_CODE128:
+ case BC_CODE128_B:
+ case BC_CODE128_C:
+ memptr = (memptrtype)&CBC_Code128::SetTextLocation;
+ break;
+ default:
+ break;
+ }
+ return m_pBCEngine && memptr ? (m_pBCEngine.get()->*memptr)(location) : FALSE;
+}
+FX_BOOL CFX_Barcode::SetWideNarrowRatio(int32_t ratio) {
+ typedef FX_BOOL (CBC_CodeBase::*memptrtype)(int32_t);
+ memptrtype memptr = nullptr;
+ switch (GetType()) {
+ case BC_CODE39:
+ memptr = (memptrtype)&CBC_Code39::SetWideNarrowRatio;
+ break;
+ case BC_CODABAR:
+ memptr = (memptrtype)&CBC_Codabar::SetWideNarrowRatio;
+ break;
+ default:
+ break;
+ }
+ return m_pBCEngine && memptr ? (m_pBCEngine.get()->*memptr)(ratio) : FALSE;
+}
+FX_BOOL CFX_Barcode::SetStartChar(FX_CHAR start) {
+ typedef FX_BOOL (CBC_CodeBase::*memptrtype)(FX_CHAR);
+ memptrtype memptr = nullptr;
+ switch (GetType()) {
+ case BC_CODABAR:
+ memptr = (memptrtype)&CBC_Codabar::SetStartChar;
+ break;
+ default:
+ break;
+ }
+ return m_pBCEngine && memptr ? (m_pBCEngine.get()->*memptr)(start) : FALSE;
+}
+FX_BOOL CFX_Barcode::SetEndChar(FX_CHAR end) {
+ typedef FX_BOOL (CBC_CodeBase::*memptrtype)(FX_CHAR);
+ memptrtype memptr = nullptr;
+ switch (GetType()) {
+ case BC_CODABAR:
+ memptr = (memptrtype)&CBC_Codabar::SetEndChar;
+ break;
+ default:
+ break;
+ }
+ return m_pBCEngine && memptr ? (m_pBCEngine.get()->*memptr)(end) : FALSE;
+}
+FX_BOOL CFX_Barcode::SetVersion(int32_t version) {
+ typedef FX_BOOL (CBC_CodeBase::*memptrtype)(int32_t);
+ memptrtype memptr = nullptr;
+ switch (GetType()) {
+ case BC_QR_CODE:
+ memptr = (memptrtype)&CBC_QRCode::SetVersion;
+ break;
+ default:
+ break;
+ }
+ return m_pBCEngine && memptr ? (m_pBCEngine.get()->*memptr)(version) : FALSE;
+}
+FX_BOOL CFX_Barcode::SetErrorCorrectionLevel(int32_t level) {
+ typedef FX_BOOL (CBC_CodeBase::*memptrtype)(int32_t);
+ memptrtype memptr = nullptr;
+ switch (GetType()) {
+ case BC_QR_CODE:
+ memptr = (memptrtype)&CBC_QRCode::SetErrorCorrectionLevel;
+ break;
+ case BC_PDF417:
+ memptr = (memptrtype)&CBC_PDF417I::SetErrorCorrectionLevel;
+ break;
+ default:
+ return FALSE;
+ }
+ return m_pBCEngine && memptr ? (m_pBCEngine.get()->*memptr)(level) : FALSE;
+}
+FX_BOOL CFX_Barcode::SetTruncated(FX_BOOL truncated) {
+ typedef void (CBC_CodeBase::*memptrtype)(FX_BOOL);
+ memptrtype memptr = nullptr;
+ switch (GetType()) {
+ case BC_PDF417:
+ memptr = (memptrtype)&CBC_PDF417I::SetTruncated;
+ break;
+ default:
+ break;
+ }
+ return m_pBCEngine && memptr ? ((m_pBCEngine.get()->*memptr)(truncated), TRUE)
+ : FALSE;
+}
+
+FX_BOOL CFX_Barcode::Encode(const CFX_WideStringC& contents,
+ FX_BOOL isDevice,
+ int32_t& e) {
+ return m_pBCEngine && m_pBCEngine->Encode(contents, isDevice, e);
+}
+
+FX_BOOL CFX_Barcode::RenderDevice(CFX_RenderDevice* device,
+ const CFX_Matrix* matrix,
+ int32_t& e) {
+ return m_pBCEngine && m_pBCEngine->RenderDevice(device, matrix, e);
+}
+
+FX_BOOL CFX_Barcode::RenderBitmap(CFX_DIBitmap*& pOutBitmap, int32_t& e) {
+ return m_pBCEngine && m_pBCEngine->RenderBitmap(pOutBitmap, e);
+}
diff --git a/xfa/fwl/core/cfx_barcode.h b/xfa/fwl/core/cfx_barcode.h
new file mode 100644
index 0000000000..389ff52042
--- /dev/null
+++ b/xfa/fwl/core/cfx_barcode.h
@@ -0,0 +1,60 @@
+// 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_CFX_BARCODE_H_
+#define XFA_FWL_CORE_CFX_BARCODE_H_
+
+#include <memory>
+
+#include "core/fxcrt/fx_coordinates.h"
+#include "core/fxcrt/fx_string.h"
+#include "core/fxcrt/fx_system.h"
+#include "core/fxge/fx_dib.h"
+#include "xfa/fxbarcode/BC_Library.h"
+
+class CBC_CodeBase;
+class CFX_Font;
+class CFX_RenderDevice;
+class CFX_Matrix;
+
+class CFX_Barcode {
+ public:
+ CFX_Barcode();
+ ~CFX_Barcode();
+
+ FX_BOOL Create(BC_TYPE type);
+ BC_TYPE GetType();
+ FX_BOOL Encode(const CFX_WideStringC& contents, FX_BOOL isDevice, int32_t& e);
+ FX_BOOL RenderDevice(CFX_RenderDevice* device,
+ const CFX_Matrix* matrix,
+ int32_t& e);
+ FX_BOOL RenderBitmap(CFX_DIBitmap*& pOutBitmap, int32_t& e);
+ FX_BOOL SetCharEncoding(BC_CHAR_ENCODING encoding);
+ FX_BOOL SetModuleHeight(int32_t moduleHeight);
+ FX_BOOL SetModuleWidth(int32_t moduleWidth);
+ FX_BOOL SetHeight(int32_t height);
+ FX_BOOL SetWidth(int32_t width);
+ FX_BOOL CheckContentValidity(const CFX_WideStringC& contents);
+ FX_BOOL SetPrintChecksum(FX_BOOL checksum);
+ FX_BOOL SetDataLength(int32_t length);
+ FX_BOOL SetCalChecksum(int32_t state);
+ FX_BOOL SetFont(CFX_Font* pFont);
+ FX_BOOL SetFontSize(FX_FLOAT size);
+ FX_BOOL SetFontStyle(int32_t style);
+ FX_BOOL SetFontColor(FX_ARGB color);
+ FX_BOOL SetTextLocation(BC_TEXT_LOC location);
+ FX_BOOL SetWideNarrowRatio(int32_t ratio);
+ FX_BOOL SetStartChar(FX_CHAR start);
+ FX_BOOL SetEndChar(FX_CHAR end);
+ FX_BOOL SetVersion(int32_t version);
+ FX_BOOL SetErrorCorrectionLevel(int32_t level);
+ FX_BOOL SetTruncated(FX_BOOL truncated);
+
+ protected:
+ std::unique_ptr<CBC_CodeBase> m_pBCEngine;
+};
+
+#endif // XFA_FWL_CORE_CFX_BARCODE_H_
diff --git a/xfa/fwl/core/fwl_formimp.h b/xfa/fwl/core/fwl_formimp.h
deleted file mode 100644
index c88b5e683b..0000000000
--- a/xfa/fwl/core/fwl_formimp.h
+++ /dev/null
@@ -1,181 +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_FWL_FORMIMP_H_
-#define XFA_FWL_CORE_FWL_FORMIMP_H_
-
-#include <memory>
-
-#include "xfa/fwl/core/fwl_widgetimp.h"
-#include "xfa/fwl/core/ifwl_form.h"
-
-class CFWL_MsgMouse;
-class CFWL_MsgClose;
-class CFWL_MsgWindowMove;
-class CFWL_NoteLoop;
-class CFWL_WidgetImpProperties;
-class IFWL_Widget;
-class IFWL_ThemeProvider;
-class CFWL_SysBtn;
-class CFWL_FormImp;
-class CFWL_FormImpDelegate;
-
-#define FWL_SYSBUTTONSTATE_Hover 0x0001
-#define FWL_SYSBUTTONSTATE_Pressed 0x0002
-#define FWL_SYSBUTTONSTATE_Disabled 0x0010
-
-class CFWL_SysBtn {
- public:
- CFWL_SysBtn();
-
- bool IsDisabled() const;
- uint32_t GetPartState() const;
-
- void SetNormal();
- void SetPressed();
- void SetHover();
- void SetDisabled(FX_BOOL bDisabled);
-
- CFX_RectF m_rtBtn;
- uint32_t m_dwState;
-};
-
-enum FORM_RESIZETYPE {
- FORM_RESIZETYPE_None = 0,
- FORM_RESIZETYPE_Cap,
-};
-
-typedef struct RestoreResizeInfo {
- RestoreResizeInfo();
- ~RestoreResizeInfo();
-
- CFX_PointF m_ptStart;
- CFX_SizeF m_szStart;
-} RestoreInfo;
-
-class CFWL_FormImp : public CFWL_WidgetImp {
- public:
- CFWL_FormImp(const CFWL_WidgetImpProperties& properties, IFWL_Widget* pOuter);
- ~CFWL_FormImp() override;
-
- // CFWL_WidgetImp
- FWL_Error GetClassName(CFX_WideString& wsClass) const override;
- FWL_Type GetClassID() const override;
- FX_BOOL IsInstance(const CFX_WideStringC& wsClass) const override;
- FWL_Error Initialize() override;
- FWL_Error Finalize() override;
-
- FWL_Error GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize = FALSE) override;
- FWL_Error GetClientRect(CFX_RectF& rect) override;
- FWL_Error Update() override;
- FWL_WidgetHit HitTest(FX_FLOAT fx, FX_FLOAT fy) override;
- FWL_Error DrawWidget(CFX_Graphics* pGraphics,
- const CFX_Matrix* pMatrix = nullptr) override;
-
- FWL_FORMSIZE GetFormSize();
- FWL_Error SetFormSize(FWL_FORMSIZE eFormSize);
- IFWL_Widget* DoModal();
- IFWL_Widget* DoModal(uint32_t& dwCommandID);
- FWL_Error EndDoModal();
- FWL_Error SetBorderRegion(CFX_Path* pPath);
- void DrawBackground(CFX_Graphics* pGraphics, IFWL_ThemeProvider* pTheme);
- CFWL_WidgetImp* GetSubFocus();
- void SetSubFocus(CFWL_WidgetImp* pWidget);
-
- protected:
- void ShowChildWidget(IFWL_Widget* pParent);
- void RemoveSysButtons();
- void CalcContentRect(CFX_RectF& rtContent);
- CFWL_SysBtn* GetSysBtnAtPoint(FX_FLOAT fx, FX_FLOAT fy);
- CFWL_SysBtn* GetSysBtnByState(uint32_t dwState);
- CFWL_SysBtn* GetSysBtnByIndex(int32_t nIndex);
- int32_t GetSysBtnIndex(CFWL_SysBtn* pBtn);
- FX_FLOAT GetCaptionHeight();
- void DrawCaptionText(CFX_Graphics* pGs,
- IFWL_ThemeProvider* pTheme,
- const CFX_Matrix* pMatrix = nullptr);
- void DrawIconImage(CFX_Graphics* pGs,
- IFWL_ThemeProvider* pTheme,
- const CFX_Matrix* pMatrix = nullptr);
- void GetEdgeRect(CFX_RectF& rtEdge);
- void SetWorkAreaRect();
- void SetCursor(FX_FLOAT fx, FX_FLOAT fy);
- void Layout();
- void ReSetSysBtn();
- void RegisterForm();
- void UnRegisterForm();
- FX_BOOL IsDoModal();
- void SetThemeData();
- FX_BOOL HasIcon();
- void UpdateIcon();
- void UpdateCaption();
- void DoWidthLimit(FX_FLOAT& fLeft,
- FX_FLOAT& fWidth,
- FX_FLOAT fCurX,
- FX_FLOAT fSpace,
- FX_FLOAT fLimitMin,
- FX_FLOAT fLimitMax,
- FX_BOOL bLeft);
- void DoHeightLimit(FX_FLOAT& fTop,
- FX_FLOAT& fHeight,
- FX_FLOAT fCurY,
- FX_FLOAT fSpace,
- FX_FLOAT fLimitMin,
- FX_FLOAT fLimitMax,
- FX_BOOL bTop);
-
- CFX_RectF m_rtRestore;
- CFX_RectF m_rtCaptionText;
- CFX_RectF m_rtRelative;
- CFX_RectF m_rtCaption;
- CFX_RectF m_rtIcon;
- CFWL_SysBtn* m_pCloseBox;
- CFWL_SysBtn* m_pMinBox;
- CFWL_SysBtn* m_pMaxBox;
- CFWL_SysBtn* m_pCaptionBox;
- std::unique_ptr<CFWL_NoteLoop> m_pNoteLoop;
- CFWL_WidgetImp* m_pSubFocus;
- RestoreInfo m_InfoStart;
- FX_FLOAT m_fCXBorder;
- FX_FLOAT m_fCYBorder;
- int32_t m_iCaptureBtn;
- int32_t m_iSysBox;
- int32_t m_eResizeType;
- FX_BOOL m_bLButtonDown;
- bool m_bMaximized;
- FX_BOOL m_bSetMaximize;
- FX_BOOL m_bCustomizeLayout;
- FWL_FORMSIZE m_eFormSize;
- FX_BOOL m_bDoModalFlag;
- FX_FLOAT m_fSmallIconSz;
- FX_FLOAT m_fBigIconSz;
- CFX_DIBitmap* m_pBigIcon;
- CFX_DIBitmap* m_pSmallIcon;
- FX_BOOL m_bMouseIn;
- friend class CFWL_FormImpDelegate;
-};
-
-class CFWL_FormImpDelegate : public CFWL_WidgetImpDelegate {
- public:
- CFWL_FormImpDelegate(CFWL_FormImp* pOwner);
- void OnProcessMessage(CFWL_Message* pMessage) override;
- void OnProcessEvent(CFWL_Event* pEvent) override;
- void OnDrawWidget(CFX_Graphics* pGraphics,
- const CFX_Matrix* pMatrix = nullptr) override;
-
- protected:
- void OnLButtonDown(CFWL_MsgMouse* pMsg);
- void OnLButtonUp(CFWL_MsgMouse* pMsg);
- void OnMouseMove(CFWL_MsgMouse* pMsg);
- void OnMouseHover(CFWL_MsgMouse* pMsg);
- void OnMouseLeave(CFWL_MsgMouse* pMsg);
- void OnLButtonDblClk(CFWL_MsgMouse* pMsg);
- void OnWindowMove(CFWL_MsgWindowMove* pMsg);
- void OnClose(CFWL_MsgClose* pMsg);
- CFWL_FormImp* m_pOwner;
-};
-
-#endif // XFA_FWL_CORE_FWL_FORMIMP_H_
diff --git a/xfa/fwl/core/fwl_noteimp.cpp b/xfa/fwl/core/fwl_noteimp.cpp
index 848cb772ba..f0474bda04 100644
--- a/xfa/fwl/core/fwl_noteimp.cpp
+++ b/xfa/fwl/core/fwl_noteimp.cpp
@@ -8,15 +8,12 @@
#include "core/fxcrt/fx_ext.h"
#include "third_party/base/stl_util.h"
-#include "xfa/fwl/basewidget/fwl_tooltipctrlimp.h"
-#include "xfa/fwl/basewidget/ifwl_tooltip.h"
#include "xfa/fwl/core/cfwl_message.h"
#include "xfa/fwl/core/cfwl_widgetmgr.h"
-#include "xfa/fwl/core/fwl_formimp.h"
-#include "xfa/fwl/core/fwl_widgetimp.h"
#include "xfa/fwl/core/ifwl_app.h"
+#include "xfa/fwl/core/ifwl_tooltip.h"
-CFWL_NoteLoop::CFWL_NoteLoop(CFWL_WidgetImp* pForm)
+CFWL_NoteLoop::CFWL_NoteLoop(IFWL_Widget* pForm)
: m_pForm(pForm), m_bContinueModal(TRUE) {}
FWL_Error CFWL_NoteLoop::Idle(int32_t count) {
@@ -36,7 +33,7 @@ FWL_Error CFWL_NoteLoop::Idle(int32_t count) {
#endif
return FWL_Error::Indefinite;
}
-CFWL_WidgetImp* CFWL_NoteLoop::GetForm() {
+IFWL_Widget* CFWL_NoteLoop::GetForm() {
return m_pForm;
}
FX_BOOL CFWL_NoteLoop::ContinueModal() {
@@ -47,7 +44,7 @@ FWL_Error CFWL_NoteLoop::EndModalLoop() {
return FWL_Error::Succeeded;
}
-FWL_Error CFWL_NoteLoop::SetMainForm(CFWL_WidgetImp* pForm) {
+FWL_Error CFWL_NoteLoop::SetMainForm(IFWL_Widget* pForm) {
m_pForm = pForm;
return FWL_Error::Succeeded;
}
@@ -155,13 +152,10 @@ FX_BOOL CFWL_NoteDriver::SetFocus(IFWL_Widget* pFocus, FX_BOOL bNotify) {
if (pFocus) {
IFWL_Widget* pWidget =
CFWL_WidgetMgr::GetInstance()->GetSystemFormWidget(pFocus);
- CFWL_FormImp* pForm =
- pWidget ? static_cast<CFWL_FormImp*>(pWidget->GetImpl()) : nullptr;
- if (pForm) {
- CFWL_WidgetImp* pNewFocus =
- static_cast<CFWL_WidgetImp*>(pFocus->GetImpl());
- pForm->SetSubFocus(pNewFocus);
- }
+ IFWL_Form* pForm = static_cast<IFWL_Form*>(pWidget);
+ if (pForm)
+ pForm->SetSubFocus(pFocus);
+
CFWL_MsgSetFocus ms;
ms.m_pDstTarget = pFocus;
if (bNotify) {
@@ -230,20 +224,20 @@ void CFWL_NoteDriver::NotifyTargetDestroy(IFWL_Widget* pNoteTarget) {
UnregisterEventTarget(pNoteTarget);
int32_t count = m_forms.GetSize();
for (int32_t nIndex = 0; nIndex < count; nIndex++) {
- CFWL_FormImp* pForm = static_cast<CFWL_FormImp*>(m_forms[nIndex]);
+ IFWL_Form* pForm = static_cast<IFWL_Form*>(m_forms[nIndex]);
if (!pForm) {
continue;
}
- CFWL_WidgetImp* pSubFocus = pForm->GetSubFocus();
+ IFWL_Widget* pSubFocus = pForm->GetSubFocus();
if (!pSubFocus)
return;
- if (pSubFocus && pSubFocus->GetInterface() == pNoteTarget) {
+ if (pSubFocus == pNoteTarget) {
pForm->SetSubFocus(nullptr);
}
}
}
-FWL_Error CFWL_NoteDriver::RegisterForm(CFWL_WidgetImp* pForm) {
+FWL_Error CFWL_NoteDriver::RegisterForm(IFWL_Widget* pForm) {
if (!pForm)
return FWL_Error::Indefinite;
if (m_forms.Find(pForm) >= 0) {
@@ -259,7 +253,7 @@ FWL_Error CFWL_NoteDriver::RegisterForm(CFWL_WidgetImp* pForm) {
}
return FWL_Error::Succeeded;
}
-FWL_Error CFWL_NoteDriver::UnRegisterForm(CFWL_WidgetImp* pForm) {
+FWL_Error CFWL_NoteDriver::UnRegisterForm(IFWL_Widget* pForm) {
if (!pForm)
return FWL_Error::Indefinite;
int32_t nIndex = m_forms.Find(pForm);
@@ -424,12 +418,11 @@ FX_BOOL CFWL_NoteDriver::DoSetFocus(CFWL_MsgSetFocus* pMsg,
return TRUE;
}
IFWL_Widget* pWidget = pMsg->m_pDstTarget;
- CFWL_FormImp* pForm =
- pWidget ? static_cast<CFWL_FormImp*>(pWidget->GetImpl()) : nullptr;
- if (pForm) {
- CFWL_WidgetImp* pSubFocus = pForm->GetSubFocus();
+ if (pWidget) {
+ IFWL_Form* pForm = static_cast<IFWL_Form*>(pWidget);
+ IFWL_Widget* pSubFocus = pForm->GetSubFocus();
if (pSubFocus && ((pSubFocus->GetStates() & FWL_WGTSTATE_Focused) == 0)) {
- pMsg->m_pDstTarget = pSubFocus->GetInterface();
+ pMsg->m_pDstTarget = pSubFocus;
if (m_pFocus != pMsg->m_pDstTarget) {
m_pFocus = pMsg->m_pDstTarget;
return TRUE;
@@ -447,13 +440,11 @@ FX_BOOL CFWL_NoteDriver::DoKillFocus(CFWL_MsgKillFocus* pMsg,
}
return TRUE;
}
- IFWL_Widget* pWidget = pMsg->m_pDstTarget;
- CFWL_FormImp* pForm =
- pWidget ? static_cast<CFWL_FormImp*>(pWidget->GetImpl()) : nullptr;
+ IFWL_Form* pForm = static_cast<IFWL_Form*>(pMsg->m_pDstTarget);
if (pForm) {
- CFWL_WidgetImp* pSubFocus = pForm->GetSubFocus();
+ IFWL_Widget* pSubFocus = pForm->GetSubFocus();
if (pSubFocus && (pSubFocus->GetStates() & FWL_WGTSTATE_Focused)) {
- pMsg->m_pDstTarget = pSubFocus->GetInterface();
+ pMsg->m_pDstTarget = pSubFocus;
if (m_pFocus == pMsg->m_pDstTarget) {
m_pFocus = nullptr;
return TRUE;
@@ -606,14 +597,14 @@ FX_BOOL CFWL_NoteDriver::IsValidMessage(CFWL_Message* pMessage) {
int32_t iCount = m_noteLoopQueue.GetSize();
for (int32_t i = 0; i < iCount; i++) {
CFWL_NoteLoop* pNoteLoop = static_cast<CFWL_NoteLoop*>(m_noteLoopQueue[i]);
- CFWL_WidgetImp* pForm = pNoteLoop->GetForm();
- if (pForm && (pForm->GetInterface() == pMessage->m_pDstTarget))
+ IFWL_Widget* pForm = pNoteLoop->GetForm();
+ if (pForm && (pForm == pMessage->m_pDstTarget))
return TRUE;
}
iCount = m_forms.GetSize();
for (int32_t j = 0; j < iCount; j++) {
- CFWL_FormImp* pForm = static_cast<CFWL_FormImp*>(m_forms[j]);
- if (pForm->GetInterface() == pMessage->m_pDstTarget)
+ IFWL_Form* pForm = static_cast<IFWL_Form*>(m_forms[j]);
+ if (pForm == pMessage->m_pDstTarget)
return TRUE;
}
return FALSE;
@@ -627,8 +618,8 @@ IFWL_Widget* CFWL_NoteDriver::GetMessageForm(IFWL_Widget* pDstTarget) {
if (iTrackLoop > 1) {
CFWL_NoteLoop* pNootLoop =
static_cast<CFWL_NoteLoop*>(m_noteLoopQueue[iTrackLoop - 1]);
- pMessageForm = pNootLoop->GetForm()->GetInterface();
- } else if (m_forms.Find(pDstTarget->GetImpl()) < 0) {
+ pMessageForm = pNootLoop->GetForm();
+ } else if (m_forms.Find(pDstTarget) < 0) {
pMessageForm = pDstTarget;
}
if (!pMessageForm && pDstTarget) {
@@ -777,8 +768,7 @@ CFWL_ToolTipContainer::CFWL_ToolTipContainer()
CFWL_ToolTipContainer::~CFWL_ToolTipContainer() {
if (m_pToolTipImp) {
- IFWL_ToolTip* pToolTip =
- static_cast<IFWL_ToolTip*>(m_pToolTipImp->GetInterface());
+ IFWL_ToolTip* pToolTip = static_cast<IFWL_ToolTip*>(m_pToolTipImp);
pToolTip->Finalize();
delete pToolTip;
}
diff --git a/xfa/fwl/core/fwl_noteimp.h b/xfa/fwl/core/fwl_noteimp.h
index 23b3c991ab..6e587166c0 100644
--- a/xfa/fwl/core/fwl_noteimp.h
+++ b/xfa/fwl/core/fwl_noteimp.h
@@ -29,24 +29,24 @@ class CFWL_MsgSetFocus;
class CFWL_MsgSize;
class CFWL_MsgWindowMove;
class CFWL_TargetImp;
-class CFWL_ToolTipImp;
-class CFWL_WidgetImp;
+class IFWL_ToolTip;
+class IFWL_Widget;
class CFWL_NoteLoop {
public:
- CFWL_NoteLoop(CFWL_WidgetImp* pForm = nullptr);
+ CFWL_NoteLoop(IFWL_Widget* pForm = nullptr);
~CFWL_NoteLoop() {}
FWL_Error Idle(int32_t count);
- CFWL_WidgetImp* GetForm();
+ IFWL_Widget* GetForm();
FX_BOOL ContinueModal();
FWL_Error EndModalLoop();
- FWL_Error SetMainForm(CFWL_WidgetImp* pForm);
+ FWL_Error SetMainForm(IFWL_Widget* pForm);
protected:
void GenerateCommondEvent(uint32_t dwCommand);
- CFWL_WidgetImp* m_pForm;
+ IFWL_Widget* m_pForm;
FX_BOOL m_bContinueModal;
};
@@ -73,8 +73,8 @@ class CFWL_NoteDriver {
void SetHover(IFWL_Widget* pHover);
void NotifyTargetHide(IFWL_Widget* pNoteTarget);
void NotifyTargetDestroy(IFWL_Widget* pNoteTarget);
- FWL_Error RegisterForm(CFWL_WidgetImp* pForm);
- FWL_Error UnRegisterForm(CFWL_WidgetImp* pForm);
+ FWL_Error RegisterForm(IFWL_Widget* pForm);
+ FWL_Error UnRegisterForm(IFWL_Widget* pForm);
FX_BOOL QueueMessage(CFWL_Message* pMessage);
FX_BOOL UnqueueMessage(CFWL_NoteLoop* pNoteLoop);
CFWL_NoteLoop* GetTopLoop();
@@ -99,7 +99,7 @@ class CFWL_NoteDriver {
IFWL_Widget* GetMessageForm(IFWL_Widget* pDstTarget);
void ClearInvalidEventTargets(FX_BOOL bRemoveAll);
- CFX_ArrayTemplate<CFWL_WidgetImp*> m_forms;
+ CFX_ArrayTemplate<IFWL_Widget*> m_forms;
CFX_ArrayTemplate<CFWL_Message*> m_noteQueue;
CFX_ArrayTemplate<CFWL_NoteLoop*> m_noteLoopQueue;
std::unordered_map<uint32_t, CFWL_EventTarget*> m_eventTargets;
@@ -137,7 +137,7 @@ class CFWL_ToolTipContainer final {
CFWL_ToolTipContainer();
~CFWL_ToolTipContainer();
- CFWL_ToolTipImp* m_pToolTipImp;
+ IFWL_ToolTip* m_pToolTipImp;
std::unique_ptr<CFWL_CoreToolTipDP> m_pToolTipDp;
private:
diff --git a/xfa/fwl/core/fwl_widgetimp.h b/xfa/fwl/core/fwl_widgetimp.h
deleted file mode 100644
index 10f7880ba3..0000000000
--- a/xfa/fwl/core/fwl_widgetimp.h
+++ /dev/null
@@ -1,181 +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_FWL_WIDGETIMP_H_
-#define XFA_FWL_CORE_FWL_WIDGETIMP_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/fwl_widgethit.h"
-#include "xfa/fwl/core/ifwl_widgetdelegate.h"
-#include "xfa/fwl/theme/cfwl_widgettp.h"
-
-class CFWL_AppImp;
-class CFWL_MsgKey;
-class CFWL_WidgetImpProperties;
-class CFWL_WidgetMgr;
-class IFWL_App;
-class IFWL_DataProvider;
-class IFWL_ThemeProvider;
-class IFWL_Widget;
-enum class FWL_Type;
-
-class CFWL_WidgetImp {
- public:
- virtual ~CFWL_WidgetImp();
-
- virtual FWL_Error Initialize();
- virtual FWL_Error Finalize();
- virtual FWL_Error GetClassName(CFX_WideString& wsClass) const;
- virtual FWL_Type GetClassID() const = 0;
- virtual FX_BOOL IsInstance(const CFX_WideStringC& wsClass) const;
-
- virtual FWL_Error GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize = FALSE);
- virtual FWL_Error GetGlobalRect(CFX_RectF& rect);
- virtual FWL_Error SetWidgetRect(const CFX_RectF& rect);
- virtual FWL_Error GetClientRect(CFX_RectF& rect);
- virtual IFWL_Widget* GetParent();
- virtual FWL_Error SetParent(IFWL_Widget* pParent);
- virtual IFWL_Widget* GetOwner();
- virtual FWL_Error SetOwner(IFWL_Widget* pOwner);
- virtual IFWL_Widget* GetOuter();
- virtual uint32_t GetStyles();
- virtual FWL_Error ModifyStyles(uint32_t dwStylesAdded,
- uint32_t dwStylesRemoved);
- virtual uint32_t GetStylesEx();
- virtual FWL_Error ModifyStylesEx(uint32_t dwStylesExAdded,
- uint32_t dwStylesExRemoved);
- virtual uint32_t GetStates();
- virtual void SetStates(uint32_t dwStates, FX_BOOL bSet = TRUE);
- virtual FWL_Error Update();
- virtual FWL_Error LockUpdate();
- virtual FWL_Error UnlockUpdate();
- virtual FWL_WidgetHit HitTest(FX_FLOAT fx, FX_FLOAT fy);
- virtual FWL_Error TransformTo(IFWL_Widget* pWidget,
- FX_FLOAT& fx,
- FX_FLOAT& fy);
- virtual FWL_Error TransformTo(IFWL_Widget* pWidget, CFX_RectF& rt);
- virtual FWL_Error GetMatrix(CFX_Matrix& matrix, FX_BOOL bGlobal = FALSE);
- virtual FWL_Error SetMatrix(const CFX_Matrix& matrix);
- virtual FWL_Error DrawWidget(CFX_Graphics* pGraphics,
- const CFX_Matrix* pMatrix = nullptr);
- virtual IFWL_ThemeProvider* GetThemeProvider();
- virtual FWL_Error SetThemeProvider(IFWL_ThemeProvider* pThemeProvider);
- virtual IFWL_WidgetDelegate* SetDelegate(IFWL_WidgetDelegate* pDelegate);
- virtual IFWL_App* GetOwnerApp() const;
-
- FWL_Error SetOwnerApp(IFWL_App* pOwnerApp);
- IFWL_Widget* GetInterface() const;
- void SetInterface(IFWL_Widget* pInterface);
- CFX_SizeF GetOffsetFromParent(IFWL_Widget* pParent);
- uint32_t GetEventKey() const;
- void SetEventKey(uint32_t key);
- void* GetLayoutItem() const;
- void SetLayoutItem(void* pItem);
- void* GetAssociateWidget() const;
- void SetAssociateWidget(void* pAssociate);
-
- protected:
- friend class CFWL_WidgetImpDelegate;
-
- CFWL_WidgetImp(const CFWL_WidgetImpProperties& properties,
- IFWL_Widget* pOuter);
-
- FX_BOOL IsEnabled() const;
- FX_BOOL IsVisible() const;
- FX_BOOL IsActive() const;
- FX_BOOL IsOverLapper() const;
- FX_BOOL IsPopup() const;
- FX_BOOL IsChild() const;
- FX_BOOL IsLocked() const;
- FX_BOOL IsOffscreen() const;
- FX_BOOL HasBorder() const;
- FX_BOOL HasEdge() const;
- void GetEdgeRect(CFX_RectF& rtEdge);
- FX_FLOAT GetBorderSize(FX_BOOL bCX = TRUE);
- FX_FLOAT GetEdgeWidth();
- void GetRelativeRect(CFX_RectF& rect);
- void* GetThemeCapacity(CFWL_WidgetCapacity dwCapacity);
- IFWL_ThemeProvider* GetAvailableTheme();
- CFWL_WidgetImp* GetRootOuter();
- CFX_SizeF CalcTextSize(const CFX_WideString& wsText,
- IFWL_ThemeProvider* pTheme,
- FX_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 SetFocus(FX_BOOL bFocus);
- void SetGrab(FX_BOOL bSet);
- FX_BOOL GetPopupPos(FX_FLOAT fMinHeight,
- FX_FLOAT fMaxHeight,
- const CFX_RectF& rtAnchor,
- CFX_RectF& rtPopup);
- FX_BOOL GetPopupPosMenu(FX_FLOAT fMinHeight,
- FX_FLOAT fMaxHeight,
- const CFX_RectF& rtAnchor,
- CFX_RectF& rtPopup);
- FX_BOOL GetPopupPosComboBox(FX_FLOAT fMinHeight,
- FX_FLOAT fMaxHeight,
- const CFX_RectF& rtAnchor,
- CFX_RectF& rtPopup);
- FX_BOOL GetPopupPosGeneral(FX_FLOAT fMinHeight,
- FX_FLOAT fMaxHeight,
- const CFX_RectF& rtAnchor,
- CFX_RectF& rtPopup);
- FX_BOOL GetScreenSize(FX_FLOAT& fx, FX_FLOAT& fy);
- void RegisterEventTarget(IFWL_Widget* pEventSource = nullptr,
- uint32_t dwFilter = FWL_EVENT_ALL_MASK);
- void UnregisterEventTarget();
- void DispatchKeyEvent(CFWL_MsgKey* pNote);
- void DispatchEvent(CFWL_Event* pEvent);
- void Repaint(const CFX_RectF* pRect = nullptr);
- void DrawBackground(CFX_Graphics* pGraphics,
- CFWL_Part iPartBk,
- IFWL_ThemeProvider* pTheme,
- const CFX_Matrix* pMatrix = nullptr);
- 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);
- void NotifyDriver();
-
- FX_BOOL IsParent(IFWL_Widget* pParent);
-
- CFWL_WidgetMgr* const m_pWidgetMgr;
- IFWL_App* m_pOwnerApp;
- std::unique_ptr<CFWL_WidgetImpProperties> m_pProperties;
- IFWL_WidgetDelegate* m_pDelegate;
- IFWL_WidgetDelegate* m_pCurDelegate;
- IFWL_Widget* m_pOuter;
- IFWL_Widget* m_pInterface;
- void* m_pLayoutItem;
- void* m_pAssociate;
- int32_t m_iLock;
- uint32_t m_nEventKey;
-};
-
-class CFWL_WidgetImpDelegate : public IFWL_WidgetDelegate {
- public:
- CFWL_WidgetImpDelegate();
- ~CFWL_WidgetImpDelegate() override {}
- void OnProcessMessage(CFWL_Message* pMessage) override;
- void OnProcessEvent(CFWL_Event* pEvent) override;
- void OnDrawWidget(CFX_Graphics* pGraphics,
- const CFX_Matrix* pMatrix = nullptr) override;
-};
-
-#endif // XFA_FWL_CORE_FWL_WIDGETIMP_H_
diff --git a/xfa/fwl/core/ifwl_barcode.cpp b/xfa/fwl/core/ifwl_barcode.cpp
new file mode 100644
index 0000000000..76f64facd0
--- /dev/null
+++ b/xfa/fwl/core/ifwl_barcode.cpp
@@ -0,0 +1,208 @@
+// 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 "xfa/fgas/font/fgas_gefont.h"
+#include "xfa/fwl/core/cfwl_themepart.h"
+#include "xfa/fwl/core/cfx_barcode.h"
+#include "xfa/fwl/core/fwl_noteimp.h"
+#include "xfa/fwl/core/ifwl_themeprovider.h"
+
+// static
+IFWL_Barcode* IFWL_Barcode::Create(const CFWL_WidgetImpProperties& properties) {
+ return new IFWL_Barcode(properties, nullptr);
+}
+
+IFWL_Barcode::IFWL_Barcode(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter)
+ : IFWL_Edit(properties, pOuter), m_dwStatus(0), m_type(BC_UNKNOWN) {}
+
+IFWL_Barcode::~IFWL_Barcode() {}
+
+FWL_Error IFWL_Barcode::GetClassName(CFX_WideString& wsClass) const {
+ wsClass = FWL_CLASS_Barcode;
+ return FWL_Error::Succeeded;
+}
+
+FWL_Type IFWL_Barcode::GetClassID() const {
+ return FWL_Type::Barcode;
+}
+
+FWL_Error IFWL_Barcode::Initialize() {
+ if (!m_pDelegate) {
+ m_pDelegate = new CFWL_BarcodeImpDelegate(this);
+ }
+ if (IFWL_Edit::Initialize() != FWL_Error::Succeeded)
+ return FWL_Error::Indefinite;
+ return FWL_Error::Succeeded;
+}
+FWL_Error IFWL_Barcode::Finalize() {
+ delete m_pDelegate;
+ m_pDelegate = nullptr;
+ m_pBarcodeEngine.reset();
+ return IFWL_Edit::Finalize();
+}
+FWL_Error IFWL_Barcode::Update() {
+ if (IsLocked()) {
+ return FWL_Error::Indefinite;
+ }
+ FWL_Error ret = IFWL_Edit::Update();
+ GenerateBarcodeImageCache();
+ return ret;
+}
+FWL_Error IFWL_Barcode::DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ if (!pGraphics)
+ return FWL_Error::Indefinite;
+ if (!m_pProperties->m_pThemeProvider)
+ return FWL_Error::Indefinite;
+ if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) {
+ GenerateBarcodeImageCache();
+ if (!m_pBarcodeEngine || (m_dwStatus & XFA_BCS_EncodeSuccess) == 0) {
+ return FWL_Error::Succeeded;
+ }
+ CFX_Matrix mt;
+ mt.e = m_rtClient.left;
+ mt.f = m_rtClient.top;
+ if (pMatrix) {
+ mt.Concat(*pMatrix);
+ }
+ int32_t errorCode = 0;
+ if (!m_pBarcodeEngine->RenderDevice(pGraphics->GetRenderDevice(), pMatrix,
+ errorCode)) {
+ return FWL_Error::Indefinite;
+ }
+ return FWL_Error::Succeeded;
+ }
+ return IFWL_Edit::DrawWidget(pGraphics, pMatrix);
+}
+void IFWL_Barcode::GenerateBarcodeImageCache() {
+ if ((m_dwStatus & XFA_BCS_NeedUpdate) == 0)
+ return;
+ m_dwStatus = 0;
+ CreateBarcodeEngine();
+ IFWL_BarcodeDP* pData =
+ static_cast<IFWL_BarcodeDP*>(m_pProperties->m_pDataProvider);
+ if (!pData)
+ return;
+ if (!m_pBarcodeEngine)
+ return;
+ CFX_WideString wsText;
+ if (GetText(wsText) != FWL_Error::Succeeded)
+ return;
+ 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(m_rtClient.height));
+ m_pBarcodeEngine->SetWidth(int32_t(m_rtClient.width));
+ uint32_t dwAttributeMask = pData->GetBarcodeAttributeMask();
+ if (dwAttributeMask & FWL_BCDATTRIBUTE_CHARENCODING) {
+ m_pBarcodeEngine->SetCharEncoding(pData->GetCharEncoding());
+ }
+ if (dwAttributeMask & FWL_BCDATTRIBUTE_MODULEHEIGHT) {
+ m_pBarcodeEngine->SetModuleHeight(pData->GetModuleHeight());
+ }
+ if (dwAttributeMask & FWL_BCDATTRIBUTE_MODULEWIDTH) {
+ m_pBarcodeEngine->SetModuleWidth(pData->GetModuleWidth());
+ }
+ if (dwAttributeMask & FWL_BCDATTRIBUTE_DATALENGTH) {
+ m_pBarcodeEngine->SetDataLength(pData->GetDataLength());
+ }
+ if (dwAttributeMask & FWL_BCDATTRIBUTE_CALCHECKSUM) {
+ m_pBarcodeEngine->SetCalChecksum(pData->GetCalChecksum());
+ }
+ if (dwAttributeMask & FWL_BCDATTRIBUTE_PRINTCHECKSUM) {
+ m_pBarcodeEngine->SetPrintChecksum(pData->GetPrintChecksum());
+ }
+ if (dwAttributeMask & FWL_BCDATTRIBUTE_TEXTLOCATION) {
+ m_pBarcodeEngine->SetTextLocation(pData->GetTextLocation());
+ }
+ if (dwAttributeMask & FWL_BCDATTRIBUTE_WIDENARROWRATIO) {
+ m_pBarcodeEngine->SetWideNarrowRatio(pData->GetWideNarrowRatio());
+ }
+ if (dwAttributeMask & FWL_BCDATTRIBUTE_STARTCHAR) {
+ m_pBarcodeEngine->SetStartChar(pData->GetStartChar());
+ }
+ if (dwAttributeMask & FWL_BCDATTRIBUTE_ENDCHAR) {
+ m_pBarcodeEngine->SetEndChar(pData->GetEndChar());
+ }
+ if (dwAttributeMask & FWL_BCDATTRIBUTE_VERSION) {
+ m_pBarcodeEngine->SetVersion(pData->GetVersion());
+ }
+ if (dwAttributeMask & FWL_BCDATTRIBUTE_ECLEVEL) {
+ m_pBarcodeEngine->SetErrorCorrectionLevel(pData->GetErrorCorrectionLevel());
+ }
+ if (dwAttributeMask & FWL_BCDATTRIBUTE_TRUNCATED) {
+ m_pBarcodeEngine->SetTruncated(pData->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;
+}
+FWL_Error IFWL_Barcode::SetText(const CFX_WideString& wsText) {
+ m_pBarcodeEngine.reset();
+ m_dwStatus = XFA_BCS_NeedUpdate;
+ return IFWL_Edit::SetText(wsText);
+}
+FX_BOOL IFWL_Barcode::IsProtectedType() {
+ 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;
+}
+
+CFWL_BarcodeImpDelegate::CFWL_BarcodeImpDelegate(IFWL_Barcode* pOwner)
+ : CFWL_EditImpDelegate(pOwner) {}
+
+void CFWL_BarcodeImpDelegate::OnProcessEvent(CFWL_Event* pEvent) {
+ if (pEvent->GetClassID() == CFWL_EventType::TextChanged) {
+ IFWL_Barcode* pOwner = static_cast<IFWL_Barcode*>(m_pOwner);
+ pOwner->m_pBarcodeEngine.reset();
+ pOwner->m_dwStatus = XFA_BCS_NeedUpdate;
+ }
+ CFWL_EditImpDelegate::OnProcessEvent(pEvent);
+}
diff --git a/xfa/fwl/core/ifwl_barcode.h b/xfa/fwl/core/ifwl_barcode.h
new file mode 100644
index 0000000000..6f58ad1012
--- /dev/null
+++ b/xfa/fwl/core/ifwl_barcode.h
@@ -0,0 +1,97 @@
+// 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/ifwl_edit.h"
+#include "xfa/fwl/core/ifwl_scrollbar.h"
+#include "xfa/fxbarcode/BC_Library.h"
+
+class CFWL_BarcodeImpDelegate;
+class CFWL_WidgetImpProperties;
+class CFX_Barcode;
+class IFWL_Widget;
+
+#define XFA_BCS_NeedUpdate 0x0001
+#define XFA_BCS_EncodeSuccess 0x0002
+#define FWL_CLASS_Barcode L"FWL_BARCODE"
+
+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_BarcodeDP : public IFWL_EditDP {
+ public:
+ virtual BC_CHAR_ENCODING GetCharEncoding() = 0;
+ virtual int32_t GetModuleHeight() = 0;
+ virtual int32_t GetModuleWidth() = 0;
+ virtual int32_t GetDataLength() = 0;
+ virtual int32_t GetCalChecksum() = 0;
+ virtual FX_BOOL GetPrintChecksum() = 0;
+ virtual BC_TEXT_LOC GetTextLocation() = 0;
+ virtual int32_t GetWideNarrowRatio() = 0;
+ virtual FX_CHAR GetStartChar() = 0;
+ virtual FX_CHAR GetEndChar() = 0;
+ virtual int32_t GetVersion() = 0;
+ virtual int32_t GetErrorCorrectionLevel() = 0;
+ virtual FX_BOOL GetTruncated() = 0;
+ virtual uint32_t GetBarcodeAttributeMask() = 0;
+};
+
+class IFWL_Barcode : public IFWL_Edit {
+ public:
+ static IFWL_Barcode* Create(const CFWL_WidgetImpProperties& properties);
+
+ IFWL_Barcode(const CFWL_WidgetImpProperties& properties, IFWL_Widget* pOuter);
+ ~IFWL_Barcode() override;
+
+ // IFWL_Widget
+ FWL_Error GetClassName(CFX_WideString& wsClass) const override;
+ FWL_Type GetClassID() const override;
+ FWL_Error Initialize() override;
+ FWL_Error Finalize() override;
+ FWL_Error Update() override;
+ FWL_Error DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
+ FWL_Error SetText(const CFX_WideString& wsText) override;
+
+ void SetType(BC_TYPE type);
+ FX_BOOL IsProtectedType();
+
+ protected:
+ friend class CFWL_BarcodeImpDelegate;
+
+ void GenerateBarcodeImageCache();
+ void CreateBarcodeEngine();
+
+ std::unique_ptr<CFX_Barcode> m_pBarcodeEngine;
+ uint32_t m_dwStatus;
+ BC_TYPE m_type;
+};
+
+class CFWL_BarcodeImpDelegate : public CFWL_EditImpDelegate {
+ public:
+ explicit CFWL_BarcodeImpDelegate(IFWL_Barcode* pOwner);
+ void OnProcessEvent(CFWL_Event* pEvent) override;
+};
+
+#endif // XFA_FWL_CORE_IFWL_BARCODE_H_
diff --git a/xfa/fwl/core/ifwl_caret.cpp b/xfa/fwl/core/ifwl_caret.cpp
new file mode 100644
index 0000000000..5ece9626eb
--- /dev/null
+++ b/xfa/fwl/core/ifwl_caret.cpp
@@ -0,0 +1,144 @@
+// 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_caret.h"
+
+#include "xfa/fwl/core/cfwl_themebackground.h"
+#include "xfa/fwl/core/cfwl_widgetimpproperties.h"
+#include "xfa/fwl/core/fwl_noteimp.h"
+#include "xfa/fwl/core/ifwl_caret.h"
+#include "xfa/fwl/core/ifwl_themeprovider.h"
+
+// static
+IFWL_Caret* IFWL_Caret::Create(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter) {
+ return new IFWL_Caret(properties, pOuter);
+}
+
+IFWL_Caret::IFWL_Caret(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter)
+ : IFWL_Widget(properties, pOuter),
+ m_pTimer(new CFWL_CaretTimer(this)),
+ m_pTimerInfo(nullptr),
+ m_dwElapse(400),
+ m_bSetColor(FALSE) {
+ SetStates(FWL_STATE_CAT_HightLight);
+}
+
+IFWL_Caret::~IFWL_Caret() {}
+
+FWL_Error IFWL_Caret::GetClassName(CFX_WideString& wsClass) const {
+ wsClass = FWL_CLASS_Caret;
+ return FWL_Error::Succeeded;
+}
+
+FWL_Type IFWL_Caret::GetClassID() const {
+ return FWL_Type::Caret;
+}
+
+FWL_Error IFWL_Caret::Initialize() {
+ if (IFWL_Widget::Initialize() != FWL_Error::Succeeded)
+ return FWL_Error::Indefinite;
+
+ m_pDelegate = new CFWL_CaretImpDelegate(this);
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_Caret::Finalize() {
+ if (m_pTimerInfo) {
+ m_pTimerInfo->StopTimer();
+ m_pTimerInfo = nullptr;
+ }
+ delete m_pDelegate;
+ m_pDelegate = nullptr;
+ return IFWL_Widget::Finalize();
+}
+
+FWL_Error IFWL_Caret::DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ if (!pGraphics)
+ return FWL_Error::Indefinite;
+ if (!m_pProperties->m_pThemeProvider)
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ if (!m_pProperties->m_pThemeProvider)
+ return FWL_Error::Indefinite;
+
+ DrawCaretBK(pGraphics, m_pProperties->m_pThemeProvider, pMatrix);
+ return FWL_Error::Succeeded;
+}
+
+void IFWL_Caret::ShowCaret(FX_BOOL bFlag) {
+ if (m_pTimerInfo) {
+ m_pTimerInfo->StopTimer();
+ m_pTimerInfo = nullptr;
+ }
+ if (bFlag)
+ m_pTimerInfo = m_pTimer->StartTimer(m_dwElapse, true);
+
+ SetStates(FWL_WGTSTATE_Invisible, !bFlag);
+}
+
+FWL_Error IFWL_Caret::GetFrequency(uint32_t& elapse) {
+ elapse = m_dwElapse;
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_Caret::SetFrequency(uint32_t elapse) {
+ m_dwElapse = elapse;
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_Caret::SetColor(CFX_Color crFill) {
+ m_bSetColor = TRUE;
+ m_crFill = crFill;
+ return FWL_Error::Succeeded;
+}
+
+void IFWL_Caret::DrawCaretBK(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix) {
+ CFX_RectF rect;
+ GetWidgetRect(rect);
+ rect.Set(0, 0, rect.width, rect.height);
+ CFWL_ThemeBackground param;
+ param.m_pWidget = this;
+ param.m_pGraphics = pGraphics;
+ param.m_rtPart = rect;
+ if (m_bSetColor)
+ param.m_pData = &m_crFill;
+ if (!(m_pProperties->m_dwStates & FWL_STATE_CAT_HightLight))
+ return;
+
+ param.m_iPart = CFWL_Part::Background;
+ param.m_dwStates = CFWL_PartState_HightLight;
+ if (pMatrix)
+ param.m_matrix.Concat(*pMatrix);
+
+ pTheme->DrawBackground(&param);
+}
+
+IFWL_Caret::CFWL_CaretTimer::CFWL_CaretTimer(IFWL_Caret* pCaret)
+ : m_pCaret(pCaret) {}
+
+void IFWL_Caret::CFWL_CaretTimer::Run(IFWL_TimerInfo* pTimerInfo) {
+ bool toggle = !(m_pCaret->GetStates() & FWL_STATE_CAT_HightLight);
+ m_pCaret->SetStates(FWL_STATE_CAT_HightLight, toggle);
+
+ CFX_RectF rt;
+ m_pCaret->GetWidgetRect(rt);
+ rt.Set(0, 0, rt.width + 1, rt.height);
+ m_pCaret->Repaint(&rt);
+}
+
+CFWL_CaretImpDelegate::CFWL_CaretImpDelegate(IFWL_Caret* pOwner)
+ : m_pOwner(pOwner) {}
+
+void CFWL_CaretImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {}
+
+void CFWL_CaretImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ m_pOwner->DrawWidget(pGraphics, pMatrix);
+}
diff --git a/xfa/fwl/core/ifwl_caret.h b/xfa/fwl/core/ifwl_caret.h
new file mode 100644
index 0000000000..e261fe95c3
--- /dev/null
+++ b/xfa/fwl/core/ifwl_caret.h
@@ -0,0 +1,78 @@
+// 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_CARET_H_
+#define XFA_FWL_CORE_IFWL_CARET_H_
+
+#include <memory>
+
+#include "xfa/fwl/core/ifwl_timer.h"
+#include "xfa/fwl/core/ifwl_widget.h"
+#include "xfa/fxgraphics/cfx_color.h"
+
+class CFWL_WidgetImpProperties;
+class IFWL_Widget;
+class CFWL_CaretImpDelegate;
+
+#define FWL_CLASS_Caret L"FWL_CARET"
+#define FWL_STATE_CAT_HightLight 1
+
+class IFWL_Caret : public IFWL_Widget {
+ public:
+ static IFWL_Caret* Create(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+
+ IFWL_Caret(const CFWL_WidgetImpProperties& properties, IFWL_Widget* pOuter);
+ ~IFWL_Caret() override;
+
+ // IFWL_Widget
+ FWL_Error GetClassName(CFX_WideString& wsClass) const override;
+ FWL_Type GetClassID() const override;
+ FWL_Error Initialize() override;
+ FWL_Error Finalize() override;
+ FWL_Error DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
+
+ void ShowCaret(FX_BOOL bFlag = TRUE);
+ FWL_Error GetFrequency(uint32_t& elapse);
+ FWL_Error SetFrequency(uint32_t elapse);
+ FWL_Error SetColor(CFX_Color crFill);
+
+ protected:
+ friend class CFWL_CaretImpDelegate;
+ friend class CFWL_CaretTimer;
+
+ class CFWL_CaretTimer : public IFWL_Timer {
+ public:
+ explicit CFWL_CaretTimer(IFWL_Caret* pCaret);
+ ~CFWL_CaretTimer() override {}
+ void Run(IFWL_TimerInfo* hTimer) override;
+ IFWL_Caret* const m_pCaret;
+ };
+
+ void DrawCaretBK(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix);
+
+ std::unique_ptr<CFWL_CaretTimer> m_pTimer;
+ IFWL_TimerInfo* m_pTimerInfo; // not owned.
+ uint32_t m_dwElapse;
+ CFX_Color m_crFill;
+ FX_BOOL m_bSetColor;
+};
+
+class CFWL_CaretImpDelegate : public CFWL_WidgetImpDelegate {
+ public:
+ CFWL_CaretImpDelegate(IFWL_Caret* pOwner);
+ void OnProcessMessage(CFWL_Message* pMessage) override;
+ void OnDrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
+
+ protected:
+ IFWL_Caret* m_pOwner;
+};
+
+#endif // XFA_FWL_CORE_IFWL_CARET_H_
diff --git a/xfa/fwl/core/ifwl_checkbox.cpp b/xfa/fwl/core/ifwl_checkbox.cpp
new file mode 100644
index 0000000000..d822d3e820
--- /dev/null
+++ b/xfa/fwl/core/ifwl_checkbox.cpp
@@ -0,0 +1,574 @@
+// 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 "xfa/fde/tto/fde_textout.h"
+#include "xfa/fwl/core/cfwl_message.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/fwl_noteimp.h"
+#include "xfa/fwl/core/ifwl_checkbox.h"
+#include "xfa/fwl/core/ifwl_themeprovider.h"
+
+namespace {
+
+const int kCaptionMargin = 5;
+
+} // namespace
+
+// static
+IFWL_CheckBox* IFWL_CheckBox::Create(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter) {
+ return new IFWL_CheckBox(properties, pOuter);
+}
+
+IFWL_CheckBox::IFWL_CheckBox(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter)
+ : IFWL_Widget(properties, pOuter),
+ 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_Error IFWL_CheckBox::GetClassName(CFX_WideString& wsClass) const {
+ wsClass = FWL_CLASS_CheckBox;
+ return FWL_Error::Succeeded;
+}
+
+FWL_Type IFWL_CheckBox::GetClassID() const {
+ return FWL_Type::CheckBox;
+}
+
+FWL_Error IFWL_CheckBox::Initialize() {
+ if (IFWL_Widget::Initialize() != FWL_Error::Succeeded)
+ return FWL_Error::Indefinite;
+
+ m_pDelegate = new CFWL_CheckBoxImpDelegate(this);
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_CheckBox::Finalize() {
+ delete m_pDelegate;
+ m_pDelegate = nullptr;
+ return IFWL_Widget::Finalize();
+}
+
+FWL_Error IFWL_CheckBox::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
+ if (bAutoSize) {
+ rect.Set(0, 0, 0, 0);
+ if (!m_pProperties->m_pThemeProvider)
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ if (!m_pProperties->m_pThemeProvider)
+ return FWL_Error::Indefinite;
+ if (!m_pProperties->m_pDataProvider)
+ return FWL_Error::Indefinite;
+ CFX_WideString wsCaption;
+ m_pProperties->m_pDataProvider->GetCaption(this, wsCaption);
+ if (wsCaption.GetLength() > 0) {
+ CFX_SizeF sz = CalcTextSize(
+ wsCaption, m_pProperties->m_pThemeProvider,
+ m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_MultiLine);
+ rect.Set(0, 0, sz.x, sz.y);
+ }
+ rect.Inflate(kCaptionMargin, kCaptionMargin);
+ IFWL_CheckBoxDP* pData =
+ static_cast<IFWL_CheckBoxDP*>(m_pProperties->m_pDataProvider);
+ FX_FLOAT fCheckBox = pData->GetBoxSize(this);
+ rect.width += fCheckBox;
+ if (rect.height < fCheckBox) {
+ rect.height = fCheckBox;
+ }
+ IFWL_Widget::GetWidgetRect(rect, TRUE);
+ } else {
+ rect = m_pProperties->m_rtWidget;
+ }
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_CheckBox::Update() {
+ if (IsLocked()) {
+ return FWL_Error::Indefinite;
+ }
+ if (!m_pProperties->m_pThemeProvider) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ UpdateTextOutStyles();
+ Layout();
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_CheckBox::DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ if (!pGraphics)
+ return FWL_Error::Indefinite;
+ if (!m_pProperties->m_pThemeProvider)
+ return FWL_Error::Indefinite;
+ IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
+ if (HasBorder()) {
+ DrawBorder(pGraphics, CFWL_Part::Border, 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);
+ }
+ if (!m_pProperties->m_pDataProvider)
+ return FWL_Error::Indefinite;
+ {
+ CFX_WideString wsCaption;
+ m_pProperties->m_pDataProvider->GetCaption(this, wsCaption);
+ int32_t iLen = wsCaption.GetLength();
+ if (iLen <= 0)
+ return FWL_Error::Indefinite;
+ 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 = wsCaption;
+ textParam.m_dwTTOStyles = m_dwTTOStyles;
+ textParam.m_iTTOAlign = m_iTTOAlign;
+ pTheme->DrawText(&textParam);
+ }
+ return FWL_Error::Succeeded;
+}
+
+int32_t IFWL_CheckBox::GetCheckState() {
+ if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_3State) &&
+ ((m_pProperties->m_dwStates & FWL_STATE_CKB_CheckMask) ==
+ FWL_STATE_CKB_Neutral)) {
+ return 2;
+ }
+ if ((m_pProperties->m_dwStates & FWL_STATE_CKB_CheckMask) ==
+ FWL_STATE_CKB_Checked) {
+ return 1;
+ }
+ return 0;
+}
+
+FWL_Error IFWL_CheckBox::SetCheckState(int32_t iCheck) {
+ m_pProperties->m_dwStates &= ~FWL_STATE_CKB_CheckMask;
+ switch (iCheck) {
+ case 0: {
+ break;
+ }
+ 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: {}
+ }
+ Repaint(&m_rtClient);
+ return FWL_Error::Succeeded;
+}
+
+void IFWL_CheckBox::Layout() {
+ int32_t width = int32_t(m_pProperties->m_rtWidget.width + 0.5f);
+ int32_t height = int32_t(m_pProperties->m_rtWidget.height + 0.5f);
+ m_pProperties->m_rtWidget.width = (FX_FLOAT)width;
+ m_pProperties->m_rtWidget.height = (FX_FLOAT)height;
+ GetClientRect(m_rtClient);
+ FX_FLOAT fBoxTop = m_rtClient.top;
+ FX_FLOAT fBoxLeft = m_rtClient.left;
+ FX_FLOAT fTextLeft = 0.0, fTextRight = 0.0;
+ FX_FLOAT fClientRight = m_rtClient.right();
+ FX_FLOAT fClientBottom = m_rtClient.bottom();
+ if (!m_pProperties->m_pDataProvider)
+ return;
+ IFWL_CheckBoxDP* pData =
+ static_cast<IFWL_CheckBoxDP*>(m_pProperties->m_pDataProvider);
+ FX_FLOAT fCheckBox = pData->GetBoxSize(this);
+ switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_VLayoutMask) {
+ case FWL_STYLEEXT_CKB_Top: {
+ fBoxTop = m_rtClient.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);
+ }
+ }
+ 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);
+ CFX_WideString wsCaption;
+ m_pProperties->m_pDataProvider->GetCaption(this, wsCaption);
+ if (wsCaption.IsEmpty()) {
+ m_rtFocus.Set(0, 0, 0, 0);
+ } else {
+ CalcTextRect(wsCaption, 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() {
+ 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() {
+ m_iTTOAlign = FDE_TTOALIGNMENT_Center;
+ 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_Center | FWL_STYLEEXT_CKB_VCenter: {
+ m_iTTOAlign = FDE_TTOALIGNMENT_Center;
+ 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;
+ }
+ default: {}
+ }
+ 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 = CFWL_WidgetMgr::GetInstance();
+ 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);
+ uint32_t dwLaststate = m_pProperties->m_dwStates;
+ if (dwFirststate != dwLaststate) {
+ CFWL_EvtCkbCheckStateChanged wmCheckBoxState;
+ wmCheckBoxState.m_pSrcTarget = this;
+ DispatchEvent(&wmCheckBoxState);
+ }
+}
+
+CFWL_CheckBoxImpDelegate::CFWL_CheckBoxImpDelegate(IFWL_CheckBox* pOwner)
+ : m_pOwner(pOwner) {}
+
+void CFWL_CheckBoxImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
+ if (!pMessage)
+ return;
+
+ switch (pMessage->GetClassID()) {
+ case CFWL_MessageType::Activate: {
+ OnActivate(pMessage);
+ break;
+ }
+ 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_WidgetImpDelegate::OnProcessMessage(pMessage);
+}
+
+void CFWL_CheckBoxImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ m_pOwner->DrawWidget(pGraphics, pMatrix);
+}
+
+void CFWL_CheckBoxImpDelegate::OnActivate(CFWL_Message* pMsg) {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Deactivated;
+ m_pOwner->Repaint(&(m_pOwner->m_rtClient));
+}
+
+void CFWL_CheckBoxImpDelegate::OnFocusChanged(CFWL_Message* pMsg,
+ FX_BOOL bSet) {
+ if (bSet) {
+ m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
+ } else {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
+ }
+ m_pOwner->Repaint(&(m_pOwner->m_rtClient));
+}
+
+void CFWL_CheckBoxImpDelegate::OnLButtonDown(CFWL_MsgMouse* pMsg) {
+ if (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) {
+ return;
+ }
+ if ((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) {
+ m_pOwner->SetFocus(TRUE);
+ }
+ m_pOwner->m_bBtnDown = TRUE;
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_CKB_Hovered;
+ m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_CKB_Pressed;
+ m_pOwner->Repaint(&(m_pOwner->m_rtClient));
+}
+
+void CFWL_CheckBoxImpDelegate::OnLButtonUp(CFWL_MsgMouse* pMsg) {
+ if (!m_pOwner->m_bBtnDown) {
+ return;
+ }
+ m_pOwner->m_bBtnDown = FALSE;
+ if (!m_pOwner->m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ return;
+ }
+ m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_CKB_Hovered;
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_CKB_Pressed;
+ m_pOwner->NextStates();
+}
+
+void CFWL_CheckBoxImpDelegate::OnMouseMove(CFWL_MsgMouse* pMsg) {
+ if (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) {
+ return;
+ }
+ FX_BOOL bRepaint = FALSE;
+ if (m_pOwner->m_bBtnDown) {
+ if (m_pOwner->m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ if ((m_pOwner->m_pProperties->m_dwStates & FWL_STATE_CKB_Pressed) == 0) {
+ bRepaint = TRUE;
+ m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_CKB_Pressed;
+ }
+ if ((m_pOwner->m_pProperties->m_dwStates & FWL_STATE_CKB_Hovered)) {
+ bRepaint = TRUE;
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_CKB_Hovered;
+ }
+ } else {
+ if (m_pOwner->m_pProperties->m_dwStates & FWL_STATE_CKB_Pressed) {
+ bRepaint = TRUE;
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_CKB_Pressed;
+ }
+ if ((m_pOwner->m_pProperties->m_dwStates & FWL_STATE_CKB_Hovered) == 0) {
+ bRepaint = TRUE;
+ m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_CKB_Hovered;
+ }
+ }
+ } else {
+ if (m_pOwner->m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ if ((m_pOwner->m_pProperties->m_dwStates & FWL_STATE_CKB_Hovered) == 0) {
+ bRepaint = TRUE;
+ m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_CKB_Hovered;
+ }
+ }
+ }
+ if (bRepaint) {
+ m_pOwner->Repaint(&(m_pOwner->m_rtBox));
+ }
+}
+
+void CFWL_CheckBoxImpDelegate::OnMouseLeave(CFWL_MsgMouse* pMsg) {
+ if (m_pOwner->m_bBtnDown) {
+ m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_CKB_Hovered;
+ } else {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_CKB_Hovered;
+ }
+ m_pOwner->Repaint(&(m_pOwner->m_rtBox));
+}
+
+void CFWL_CheckBoxImpDelegate::OnKeyDown(CFWL_MsgKey* pMsg) {
+ if (pMsg->m_dwKeyCode == FWL_VKEY_Tab) {
+ m_pOwner->DispatchKeyEvent(pMsg);
+ return;
+ }
+ if (pMsg->m_dwKeyCode == FWL_VKEY_Return ||
+ pMsg->m_dwKeyCode == FWL_VKEY_Space) {
+ m_pOwner->NextStates();
+ }
+}
diff --git a/xfa/fwl/core/ifwl_checkbox.h b/xfa/fwl/core/ifwl_checkbox.h
new file mode 100644
index 0000000000..237a15b30e
--- /dev/null
+++ b/xfa/fwl/core/ifwl_checkbox.h
@@ -0,0 +1,117 @@
+// 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 "xfa/fwl/core/cfwl_event.h"
+#include "xfa/fwl/core/cfwl_widgetimpproperties.h"
+#include "xfa/fwl/core/ifwl_dataprovider.h"
+#include "xfa/fwl/core/ifwl_widget.h"
+
+#define FWL_CLASS_CheckBox L"FWL_CHECKBOX"
+#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_CheckBoxImpDelegate;
+class CFWL_MsgMouse;
+class CFWL_WidgetImpProperties;
+class IFWL_Widget;
+
+FWL_EVENT_DEF(CFWL_EvtCkbCheckStateChanged, CFWL_EventType::CheckStateChanged)
+
+class IFWL_CheckBoxDP : public IFWL_DataProvider {
+ public:
+ virtual FX_FLOAT GetBoxSize(IFWL_Widget* pWidget) = 0;
+};
+
+class IFWL_CheckBox : public IFWL_Widget {
+ public:
+ static IFWL_CheckBox* Create(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+
+ IFWL_CheckBox(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+ ~IFWL_CheckBox() override;
+
+ // IFWL_Widget
+ FWL_Error GetClassName(CFX_WideString& wsClass) const override;
+ FWL_Type GetClassID() const override;
+ FWL_Error Initialize() override;
+ FWL_Error Finalize() override;
+ FWL_Error GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize = FALSE) override;
+ FWL_Error Update() override;
+ FWL_Error DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
+ int32_t GetCheckState();
+ FWL_Error SetCheckState(int32_t iCheck);
+
+ protected:
+ friend class CFWL_CheckBoxImpDelegate;
+
+ void Layout();
+ uint32_t GetPartStates();
+ void UpdateTextOutStyles();
+ void NextStates();
+
+ CFX_RectF m_rtClient;
+ CFX_RectF m_rtBox;
+ CFX_RectF m_rtCaption;
+ CFX_RectF m_rtFocus;
+ uint32_t m_dwTTOStyles;
+ int32_t m_iTTOAlign;
+ FX_BOOL m_bBtnDown;
+};
+
+class CFWL_CheckBoxImpDelegate : public CFWL_WidgetImpDelegate {
+ public:
+ CFWL_CheckBoxImpDelegate(IFWL_CheckBox* pOwner);
+
+ void OnProcessMessage(CFWL_Message* pMessage) override;
+ void OnDrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
+
+ protected:
+ void OnActivate(CFWL_Message* pMsg);
+ void OnFocusChanged(CFWL_Message* pMsg, FX_BOOL bSet = TRUE);
+ 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);
+
+ IFWL_CheckBox* m_pOwner;
+};
+
+#endif // XFA_FWL_CORE_IFWL_CHECKBOX_H_
diff --git a/xfa/fwl/core/ifwl_combobox.cpp b/xfa/fwl/core/ifwl_combobox.cpp
new file mode 100644
index 0000000000..6a4c13f4a6
--- /dev/null
+++ b/xfa/fwl/core/ifwl_combobox.cpp
@@ -0,0 +1,1444 @@
+// 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 "xfa/fde/cfde_txtedtengine.h"
+#include "xfa/fde/tto/fde_textout.h"
+#include "xfa/fwl/core/cfwl_message.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/fwl_noteimp.h"
+#include "xfa/fwl/core/ifwl_app.h"
+#include "xfa/fwl/core/ifwl_comboedit.h"
+#include "xfa/fwl/core/ifwl_combolist.h"
+#include "xfa/fwl/core/ifwl_formproxy.h"
+#include "xfa/fwl/core/ifwl_themeprovider.h"
+
+// static
+IFWL_ComboBox* IFWL_ComboBox::Create(
+ const CFWL_WidgetImpProperties& properties) {
+ return new IFWL_ComboBox(properties, nullptr);
+}
+
+IFWL_ComboBox::IFWL_ComboBox(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter)
+ : IFWL_Widget(properties, pOuter),
+ m_pForm(nullptr),
+ m_bLButtonDown(FALSE),
+ m_iCurSel(-1),
+ m_iBtnState(CFWL_PartState_Normal),
+ m_fComboFormHandler(0),
+ m_bNeedShowList(FALSE) {
+ m_rtClient.Reset();
+ m_rtBtn.Reset();
+ m_rtHandler.Reset();
+}
+
+IFWL_ComboBox::~IFWL_ComboBox() {}
+
+FWL_Error IFWL_ComboBox::GetClassName(CFX_WideString& wsClass) const {
+ wsClass = FWL_CLASS_ComboBox;
+ return FWL_Error::Succeeded;
+}
+
+FWL_Type IFWL_ComboBox::GetClassID() const {
+ return FWL_Type::ComboBox;
+}
+
+FWL_Error IFWL_ComboBox::Initialize() {
+ if (m_pWidgetMgr->IsFormDisabled())
+ return DisForm_Initialize();
+
+ if (IFWL_Widget::Initialize() != FWL_Error::Succeeded)
+ return FWL_Error::Indefinite;
+
+ m_pDelegate = new CFWL_ComboBoxImpDelegate(this);
+ CFWL_WidgetImpProperties prop;
+ 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;
+
+ prop.m_pDataProvider = m_pProperties->m_pDataProvider;
+ m_pListBox.reset(IFWL_ComboList::Create(prop, this));
+ m_pListBox->Initialize();
+ if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_DropDown) && !m_pEdit) {
+ CFWL_WidgetImpProperties prop2;
+ m_pEdit.reset(IFWL_ComboEdit::Create(prop2, this));
+ m_pEdit->Initialize();
+ m_pEdit->SetOuter(this);
+ }
+ if (m_pEdit)
+ m_pEdit->SetParent(this);
+
+ SetStates(m_pProperties->m_dwStates);
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_ComboBox::Finalize() {
+ if (m_pEdit) {
+ m_pEdit->Finalize();
+ }
+ m_pListBox->Finalize();
+ delete m_pDelegate;
+ m_pDelegate = nullptr;
+ return IFWL_Widget::Finalize();
+}
+
+FWL_Error IFWL_ComboBox::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
+ if (bAutoSize) {
+ rect.Reset();
+ FX_BOOL bIsDropDown = IsDropDownStyle();
+ if (bIsDropDown && 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 FWL_Error::Indefinite;
+ rect.Inflate(0, 0, *pFWidth, 0);
+ IFWL_Widget::GetWidgetRect(rect, TRUE);
+ } else {
+ rect = m_pProperties->m_rtWidget;
+ }
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_ComboBox::ModifyStylesEx(uint32_t dwStylesExAdded,
+ uint32_t dwStylesExRemoved) {
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
+ }
+ bool bAddDropDown = !!(dwStylesExAdded & FWL_STYLEEXT_CMB_DropDown);
+ bool bRemoveDropDown = !!(dwStylesExRemoved & FWL_STYLEEXT_CMB_DropDown);
+ if (bAddDropDown && !m_pEdit) {
+ CFWL_WidgetImpProperties prop;
+ m_pEdit.reset(IFWL_ComboEdit::Create(prop, nullptr));
+ m_pEdit->Initialize();
+ m_pEdit->SetOuter(this);
+ m_pEdit->SetParent(this);
+ } else if (bRemoveDropDown && m_pEdit) {
+ m_pEdit->SetStates(FWL_WGTSTATE_Invisible, TRUE);
+ }
+ return IFWL_Widget::ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
+}
+
+FWL_Error IFWL_ComboBox::Update() {
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_Update();
+ }
+ if (IsLocked()) {
+ return FWL_Error::Indefinite;
+ }
+ ReSetTheme();
+ FX_BOOL bDropDown = IsDropDownStyle();
+ if (bDropDown && 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));
+ return FWL_Error::Succeeded;
+}
+
+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);
+}
+
+FWL_Error IFWL_ComboBox::DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_DrawWidget(pGraphics, pMatrix);
+ }
+ if (!pGraphics)
+ return FWL_Error::Indefinite;
+ if (!m_pProperties->m_pThemeProvider)
+ return FWL_Error::Indefinite;
+ IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
+ FX_BOOL bIsDropDown = IsDropDownStyle();
+ if (HasBorder()) {
+ DrawBorder(pGraphics, CFWL_Part::Border, pTheme, pMatrix);
+ }
+ if (HasEdge()) {
+ DrawEdge(pGraphics, CFWL_Part::Edge, pTheme, pMatrix);
+ }
+ if (!bIsDropDown) {
+ 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) {
+ IFWL_ListBoxDP* pData = static_cast<IFWL_ListBoxDP*>(
+ m_pListBox->m_pProperties->m_pDataProvider);
+ void* p = pData->GetItemData(m_pListBox.get(),
+ pData->GetItem(m_pListBox.get(), m_iCurSel));
+ if (p) {
+ 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 FWL_Error::Indefinite;
+ CFX_WideString wsText;
+ IFWL_ComboBoxDP* pData =
+ static_cast<IFWL_ComboBoxDP*>(m_pProperties->m_pDataProvider);
+ IFWL_ListItem* hItem = pData->GetItem(this, m_iCurSel);
+ m_pListBox->GetItemText(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);
+ }
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_ComboBox::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) {
+ if (!pThemeProvider)
+ return FWL_Error::Indefinite;
+ m_pProperties->m_pThemeProvider = pThemeProvider;
+ if (m_pListBox)
+ m_pListBox->SetThemeProvider(pThemeProvider);
+ if (m_pEdit)
+ m_pEdit->SetThemeProvider(pThemeProvider);
+ return FWL_Error::Succeeded;
+}
+
+int32_t IFWL_ComboBox::GetCurSel() {
+ return m_iCurSel;
+}
+
+FWL_Error IFWL_ComboBox::SetCurSel(int32_t iSel) {
+ int32_t iCount = m_pListBox->CountItems();
+ FX_BOOL bClearSel = iSel < 0 || iSel >= iCount;
+ FX_BOOL bDropDown = IsDropDownStyle();
+ if (bDropDown && m_pEdit) {
+ if (bClearSel) {
+ m_pEdit->SetText(CFX_WideString());
+ } else {
+ CFX_WideString wsText;
+ IFWL_ComboBoxDP* pData =
+ static_cast<IFWL_ComboBoxDP*>(m_pProperties->m_pDataProvider);
+ IFWL_ListItem* hItem = pData->GetItem(this, iSel);
+ m_pListBox->GetItemText(hItem, wsText);
+ m_pEdit->SetText(wsText);
+ }
+ m_pEdit->Update();
+ }
+ m_iCurSel = bClearSel ? -1 : iSel;
+ return FWL_Error::Succeeded;
+}
+
+void IFWL_ComboBox::SetStates(uint32_t dwStates, FX_BOOL bSet) {
+ FX_BOOL bIsDropDown = IsDropDownStyle();
+ if (bIsDropDown && m_pEdit)
+ m_pEdit->SetStates(dwStates, bSet);
+ if (m_pListBox)
+ m_pListBox->SetStates(dwStates, bSet);
+ IFWL_Widget::SetStates(dwStates, bSet);
+}
+
+FWL_Error IFWL_ComboBox::SetEditText(const CFX_WideString& wsText) {
+ if (!m_pEdit)
+ return FWL_Error::Indefinite;
+ m_pEdit->SetText(wsText);
+ return m_pEdit->Update();
+}
+
+int32_t IFWL_ComboBox::GetEditTextLength() const {
+ if (!m_pEdit)
+ return -1;
+ return m_pEdit->GetTextLength();
+}
+
+FWL_Error IFWL_ComboBox::GetEditText(CFX_WideString& wsText,
+ int32_t nStart,
+ int32_t nCount) const {
+ if (m_pEdit) {
+ return m_pEdit->GetText(wsText, nStart, nCount);
+ } else if (m_pListBox) {
+ IFWL_ComboBoxDP* pData =
+ static_cast<IFWL_ComboBoxDP*>(m_pProperties->m_pDataProvider);
+ IFWL_ListItem* hItem = pData->GetItem(this, m_iCurSel);
+ return m_pListBox->GetItemText(hItem, wsText);
+ }
+ return FWL_Error::Indefinite;
+}
+
+FWL_Error IFWL_ComboBox::SetEditSelRange(int32_t nStart, int32_t nCount) {
+ if (!m_pEdit)
+ return FWL_Error::Indefinite;
+ m_pEdit->ClearSelected();
+ m_pEdit->AddSelRange(nStart, nCount);
+ return FWL_Error::Succeeded;
+}
+
+int32_t IFWL_ComboBox::GetEditSelRange(int32_t nIndex, int32_t& nStart) {
+ if (!m_pEdit)
+ return -1;
+ return m_pEdit->GetSelRange(nIndex, nStart);
+}
+
+int32_t IFWL_ComboBox::GetEditLimit() {
+ if (!m_pEdit)
+ return -1;
+ return m_pEdit->GetLimit();
+}
+
+FWL_Error IFWL_ComboBox::SetEditLimit(int32_t nLimit) {
+ if (!m_pEdit)
+ return FWL_Error::Indefinite;
+ return m_pEdit->SetLimit(nLimit);
+}
+
+FWL_Error IFWL_ComboBox::EditDoClipboard(int32_t iCmd) {
+ if (!m_pEdit)
+ return FWL_Error::Indefinite;
+ return m_pEdit->DoClipboard(iCmd);
+}
+
+FX_BOOL IFWL_ComboBox::EditRedo(const IFDE_TxtEdtDoRecord* pRecord) {
+ return m_pEdit && m_pEdit->Redo(pRecord);
+}
+
+FX_BOOL IFWL_ComboBox::EditUndo(const IFDE_TxtEdtDoRecord* pRecord) {
+ return m_pEdit && m_pEdit->Undo(pRecord);
+}
+
+IFWL_ListBox* IFWL_ComboBox::GetListBoxt() {
+ return m_pListBox.get();
+}
+
+FX_BOOL IFWL_ComboBox::AfterFocusShowDropList() {
+ if (!m_bNeedShowList) {
+ return FALSE;
+ }
+ if (m_pEdit) {
+ MatchEditText();
+ }
+ ShowDropList(TRUE);
+ m_bNeedShowList = FALSE;
+ return TRUE;
+}
+
+FWL_Error IFWL_ComboBox::OpenDropDownList(FX_BOOL bActivate) {
+ ShowDropList(bActivate);
+ return FWL_Error::Succeeded;
+}
+
+FX_BOOL IFWL_ComboBox::EditCanUndo() {
+ return m_pEdit->CanUndo();
+}
+
+FX_BOOL IFWL_ComboBox::EditCanRedo() {
+ return m_pEdit->CanRedo();
+}
+
+FX_BOOL IFWL_ComboBox::EditUndo() {
+ return m_pEdit->Undo();
+}
+
+FX_BOOL IFWL_ComboBox::EditRedo() {
+ return m_pEdit->Redo();
+}
+
+FX_BOOL IFWL_ComboBox::EditCanCopy() {
+ return m_pEdit->CountSelRanges() > 0;
+}
+
+FX_BOOL IFWL_ComboBox::EditCanCut() {
+ if (m_pEdit->GetStylesEx() & FWL_STYLEEXT_EDT_ReadOnly) {
+ return FALSE;
+ }
+ return m_pEdit->CountSelRanges() > 0;
+}
+
+FX_BOOL IFWL_ComboBox::EditCanSelectAll() {
+ return m_pEdit->GetTextLength() > 0;
+}
+
+FX_BOOL IFWL_ComboBox::EditCopy(CFX_WideString& wsCopy) {
+ return m_pEdit->Copy(wsCopy);
+}
+
+FX_BOOL IFWL_ComboBox::EditCut(CFX_WideString& wsCut) {
+ return m_pEdit->Cut(wsCut);
+}
+
+FX_BOOL IFWL_ComboBox::EditPaste(const CFX_WideString& wsPaste) {
+ return m_pEdit->Paste(wsPaste);
+}
+
+FX_BOOL IFWL_ComboBox::EditSelectAll() {
+ return m_pEdit->AddSelRange(0) == FWL_Error::Succeeded;
+}
+
+FX_BOOL IFWL_ComboBox::EditDelete() {
+ return m_pEdit->ClearText() == FWL_Error::Succeeded;
+}
+
+FX_BOOL IFWL_ComboBox::EditDeSelect() {
+ return m_pEdit->ClearSelections() == FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_ComboBox::GetBBox(CFX_RectF& rect) {
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_GetBBox(rect);
+ }
+ rect = m_pProperties->m_rtWidget;
+ if (m_pListBox && IsDropListShowed()) {
+ CFX_RectF rtList;
+ m_pListBox->GetWidgetRect(rtList);
+ rtList.Offset(rect.left, rect.top);
+ rect.Union(rtList);
+ }
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_ComboBox::EditModifyStylesEx(uint32_t dwStylesExAdded,
+ uint32_t dwStylesExRemoved) {
+ if (!m_pEdit)
+ return FWL_Error::ParameterInvalid;
+ return m_pEdit->ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
+}
+
+FX_FLOAT IFWL_ComboBox::GetListHeight() {
+ return static_cast<IFWL_ComboBoxDP*>(m_pProperties->m_pDataProvider)
+ ->GetListHeight(this);
+}
+
+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(FX_BOOL bActivate) {
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_ShowDropList(bActivate);
+ }
+ FX_BOOL bDropList = IsDropListShowed();
+ if (bDropList == bActivate) {
+ return;
+ }
+ if (!m_pForm) {
+ InitProxyForm();
+ }
+ m_pListProxyDelegate->Reset();
+ if (bActivate) {
+ 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);
+ FX_FLOAT fHeight = GetListHeight();
+ if (fHeight > 0) {
+ if (m_rtList.height > GetListHeight()) {
+ m_rtList.height = GetListHeight();
+ m_pListBox->ModifyStyles(FWL_WGTSTYLE_VScroll, 0);
+ }
+ }
+ CFX_RectF rtAnchor;
+ rtAnchor.Set(0, 0, m_pProperties->m_rtWidget.width,
+ m_pProperties->m_rtWidget.height);
+ FX_FLOAT fMinHeight = 0;
+ if (m_rtList.width < m_rtClient.width) {
+ 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(fMinHeight, 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_pForm->SetWidgetRect(m_rtProxy);
+ m_pForm->Update();
+ m_pListBox->SetWidgetRect(m_rtList);
+ m_pListBox->Update();
+ CFWL_EvtCmbPreDropDown ev;
+ ev.m_pSrcTarget = this;
+ DispatchEvent(&ev);
+ m_fItemHeight = m_pListBox->m_fItemHeight;
+ m_pListBox->SetFocus(TRUE);
+ m_pForm->DoModal();
+ m_pListBox->SetFocus(FALSE);
+ } else {
+ m_pForm->EndDoModal();
+ CFWL_EvtCmbCloseUp ev;
+ ev.m_pSrcTarget = this;
+ DispatchEvent(&ev);
+ m_bLButtonDown = FALSE;
+ m_pListBox->m_bNotifyOwner = TRUE;
+ SetFocus(TRUE);
+ }
+}
+
+FX_BOOL IFWL_ComboBox::IsDropListShowed() {
+ return m_pForm && !(m_pForm->GetStates() & FWL_WGTSTATE_Invisible);
+}
+
+FX_BOOL IFWL_ComboBox::IsDropDownStyle() const {
+ return m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_DropDown;
+}
+
+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) {
+ SynchrEditText(iMatch);
+ }
+ } else if (iMatch >= 0) {
+ m_pEdit->SetSelected();
+ }
+ m_iCurSel = iMatch;
+}
+
+void IFWL_ComboBox::SynchrEditText(int32_t iListItem) {
+ CFX_WideString wsText;
+ IFWL_ComboBoxDP* pData =
+ static_cast<IFWL_ComboBoxDP*>(m_pProperties->m_pDataProvider);
+ IFWL_ListItem* hItem = pData->GetItem(this, iListItem);
+ m_pListBox->GetItemText(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);
+ FX_BOOL bIsDropDown = IsDropDownStyle();
+ if (bIsDropDown && m_pEdit) {
+ 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;
+ IFWL_ComboBoxDP* pData =
+ static_cast<IFWL_ComboBoxDP*>(m_pProperties->m_pDataProvider);
+ IFWL_ListItem* hItem = pData->GetItem(this, m_iCurSel);
+ m_pListBox->GetItemText(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 dwStylExes = m_pProperties->m_dwStyleExes;
+ uint32_t dwAdd = 0;
+ switch (dwStylExes & 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 (dwStylExes & 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; }
+ }
+ if (dwStylExes & FWL_STYLEEXT_CMB_EditJustified) {
+ dwAdd |= FWL_STYLEEXT_EDT_Justified;
+ }
+ if (dwStylExes & 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 dwStylExes = m_pProperties->m_dwStyleExes;
+ uint32_t dwAdd = 0;
+ switch (dwStylExes & FWL_STYLEEXT_CMB_ListItemAlignMask) {
+ case FWL_STYLEEXT_CMB_ListItemCenterAlign: {
+ dwAdd |= FWL_STYLEEXT_LTB_CenterAlign;
+ }
+ case FWL_STYLEEXT_CMB_ListItemRightAlign: {
+ dwAdd |= FWL_STYLEEXT_LTB_RightAlign;
+ }
+ default: { dwAdd |= FWL_STYLEEXT_LTB_LeftAlign; }
+ }
+ m_pListBox->ModifyStylesEx(dwAdd, FWL_STYLEEXT_CMB_ListItemAlignMask);
+}
+
+void IFWL_ComboBox::ProcessSelChanged(FX_BOOL bLButtonUp) {
+ IFWL_ComboBoxDP* pDatas =
+ static_cast<IFWL_ComboBoxDP*>(m_pProperties->m_pDataProvider);
+ m_iCurSel = pDatas->GetItemIndex(this, m_pListBox->GetSelItem(0));
+ FX_BOOL bDropDown = IsDropDownStyle();
+ if (bDropDown) {
+ IFWL_ComboBoxDP* pData =
+ static_cast<IFWL_ComboBoxDP*>(m_pProperties->m_pDataProvider);
+ IFWL_ListItem* hItem = pData->GetItem(this, m_iCurSel);
+ if (hItem) {
+ CFX_WideString wsText;
+ pData->GetItemText(this, hItem, wsText);
+ if (m_pEdit) {
+ m_pEdit->SetText(wsText);
+ m_pEdit->Update();
+ m_pEdit->SetSelected();
+ }
+ CFWL_EvtCmbSelChanged ev;
+ ev.bLButtonUp = bLButtonUp;
+ ev.m_pSrcTarget = this;
+ ev.iArraySels.Add(m_iCurSel);
+ DispatchEvent(&ev);
+ }
+ } else {
+ Repaint(&m_rtClient);
+ }
+}
+
+void IFWL_ComboBox::InitProxyForm() {
+ if (m_pForm)
+ return;
+ if (!m_pListBox)
+ return;
+
+ CFWL_WidgetImpProperties propForm;
+ propForm.m_pOwner = this;
+ propForm.m_dwStyles = FWL_WGTSTYLE_Popup;
+ propForm.m_dwStates = FWL_WGTSTATE_Invisible;
+ m_pForm = IFWL_FormProxy::Create(propForm, m_pListBox.get());
+ m_pForm->Initialize();
+ m_pListBox->SetParent(m_pForm);
+ m_pListProxyDelegate = new CFWL_ComboProxyImpDelegate(m_pForm, this);
+ m_pForm->SetDelegate(m_pListProxyDelegate);
+}
+
+FWL_Error IFWL_ComboBox::DisForm_Initialize() {
+ if (IFWL_Widget::Initialize() != FWL_Error::Succeeded)
+ return FWL_Error::Indefinite;
+
+ m_pDelegate = new CFWL_ComboBoxImpDelegate(this);
+ DisForm_InitComboList();
+ DisForm_InitComboEdit();
+ return FWL_Error::Succeeded;
+}
+
+void IFWL_ComboBox::DisForm_InitComboList() {
+ if (m_pListBox)
+ return;
+
+ CFWL_WidgetImpProperties prop;
+ prop.m_pParent = this;
+ prop.m_dwStyles = FWL_WGTSTYLE_Border | FWL_WGTSTYLE_VScroll;
+ prop.m_dwStates = FWL_WGTSTATE_Invisible;
+ prop.m_pDataProvider = m_pProperties->m_pDataProvider;
+ prop.m_pThemeProvider = m_pProperties->m_pThemeProvider;
+ m_pListBox.reset(IFWL_ComboList::Create(prop, this));
+ m_pListBox->Initialize();
+}
+
+void IFWL_ComboBox::DisForm_InitComboEdit() {
+ if (m_pEdit) {
+ return;
+ }
+ CFWL_WidgetImpProperties prop;
+ prop.m_pParent = this;
+ prop.m_pThemeProvider = m_pProperties->m_pThemeProvider;
+ m_pEdit.reset(IFWL_ComboEdit::Create(prop, this));
+ m_pEdit->Initialize();
+ m_pEdit->SetOuter(this);
+}
+
+void IFWL_ComboBox::DisForm_ShowDropList(FX_BOOL bActivate) {
+ FX_BOOL bDropList = DisForm_IsDropListShowed();
+ if (bDropList == bActivate) {
+ return;
+ }
+ if (bActivate) {
+ CFWL_EvtCmbPreDropDown preEvent;
+ preEvent.m_pSrcTarget = this;
+ DispatchEvent(&preEvent);
+ IFWL_ComboList* pComboList = m_pListBox.get();
+ int32_t iItems = pComboList->CountItems();
+ if (iItems < 1) {
+ return;
+ }
+ ReSetListItemAlignment();
+ pComboList->ChangeSelected(m_iCurSel);
+ FX_FLOAT fItemHeight = pComboList->GetItemHeigt();
+ 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_EvtCmbPostDropDown postEvent;
+ postEvent.m_pSrcTarget = this;
+ DispatchEvent(&postEvent);
+ }
+ CFX_RectF rect;
+ m_pListBox->GetWidgetRect(rect);
+ rect.Inflate(2, 2);
+ Repaint(&rect);
+}
+
+FX_BOOL IFWL_ComboBox::DisForm_IsDropListShowed() {
+ return !(m_pListBox->GetStates() & FWL_WGTSTATE_Invisible);
+}
+
+FWL_Error 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);
+ }
+ return IFWL_Widget::ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
+}
+
+FWL_Error IFWL_ComboBox::DisForm_Update() {
+ if (m_iLock) {
+ return FWL_Error::Indefinite;
+ }
+ if (m_pEdit) {
+ ReSetEditAlignment();
+ }
+ ReSetTheme();
+ Layout();
+ return FWL_Error::Succeeded;
+}
+
+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_IsDropListShowed()) {
+ m_pListBox->GetWidgetRect(rect);
+ if (rect.Contains(fx, fy))
+ return FWL_WidgetHit::Client;
+ }
+ return FWL_WidgetHit::Unknown;
+}
+
+FWL_Error 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;
+ }
+ FX_BOOL bListShowed = m_pListBox && DisForm_IsDropListShowed();
+ 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 (bListShowed) {
+ 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);
+ }
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_ComboBox::DisForm_GetBBox(CFX_RectF& rect) {
+ rect = m_pProperties->m_rtWidget;
+ if (m_pListBox && DisForm_IsDropListShowed()) {
+ CFX_RectF rtList;
+ m_pListBox->GetWidgetRect(rtList);
+ rtList.Offset(rect.left, rect.top);
+ rect.Union(rtList);
+ }
+ return FWL_Error::Succeeded;
+}
+
+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);
+ }
+ FX_BOOL bIsDropDown = IsDropDownStyle();
+ if (bIsDropDown && m_pEdit) {
+ 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;
+ IFWL_ComboBoxDP* pData =
+ static_cast<IFWL_ComboBoxDP*>(m_pProperties->m_pDataProvider);
+ IFWL_ListItem* hItem = pData->GetItem(this, m_iCurSel);
+ m_pListBox->GetItemText(hItem, wsText);
+ m_pEdit->LockUpdate();
+ m_pEdit->SetText(wsText);
+ m_pEdit->UnlockUpdate();
+ }
+ m_pEdit->Update();
+ }
+}
+
+CFWL_ComboBoxImpDelegate::CFWL_ComboBoxImpDelegate(IFWL_ComboBox* pOwner)
+ : m_pOwner(pOwner) {}
+
+void CFWL_ComboBoxImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
+ if (m_pOwner->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_WidgetImpDelegate::OnProcessMessage(pMessage);
+}
+
+void CFWL_ComboBoxImpDelegate::OnProcessEvent(CFWL_Event* pEvent) {
+ CFWL_EventType dwFlag = pEvent->GetClassID();
+ if (dwFlag == CFWL_EventType::DrawItem) {
+ CFWL_EvtLtbDrawItem* pDrawItemEvent =
+ static_cast<CFWL_EvtLtbDrawItem*>(pEvent);
+ CFWL_EvtCmbDrawItem pTemp;
+ pTemp.m_pSrcTarget = m_pOwner;
+ pTemp.m_pGraphics = pDrawItemEvent->m_pGraphics;
+ pTemp.m_index = pDrawItemEvent->m_index;
+ pTemp.m_rtItem = pDrawItemEvent->m_rect;
+ m_pOwner->DispatchEvent(&pTemp);
+ } else if (dwFlag == CFWL_EventType::Scroll) {
+ CFWL_EvtScroll* pScrollEvent = static_cast<CFWL_EvtScroll*>(pEvent);
+ CFWL_EvtScroll pScrollEv;
+ pScrollEv.m_pSrcTarget = m_pOwner;
+ pScrollEv.m_iScrollCode = pScrollEvent->m_iScrollCode;
+ pScrollEv.m_fPos = pScrollEvent->m_fPos;
+ m_pOwner->DispatchEvent(&pScrollEv);
+ } else if (dwFlag == CFWL_EventType::TextChanged) {
+ CFWL_EvtEdtTextChanged* pTextChangedEvent =
+ static_cast<CFWL_EvtEdtTextChanged*>(pEvent);
+ CFWL_EvtCmbEditChanged pTemp;
+ pTemp.m_pSrcTarget = m_pOwner;
+ pTemp.wsInsert = pTextChangedEvent->wsInsert;
+ pTemp.wsDelete = pTextChangedEvent->wsDelete;
+ pTemp.nChangeType = pTextChangedEvent->nChangeType;
+ m_pOwner->DispatchEvent(&pTemp);
+ }
+}
+
+void CFWL_ComboBoxImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ m_pOwner->DrawWidget(pGraphics, pMatrix);
+}
+
+void CFWL_ComboBoxImpDelegate::OnFocusChanged(CFWL_Message* pMsg,
+ FX_BOOL bSet) {
+ IFWL_Widget* pDstTarget = pMsg->m_pDstTarget;
+ IFWL_Widget* pSrcTarget = pMsg->m_pSrcTarget;
+ FX_BOOL bDropDown = m_pOwner->IsDropDownStyle();
+ if (bSet) {
+ m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
+ if (bDropDown && pSrcTarget != m_pOwner->m_pListBox.get()) {
+ if (!m_pOwner->m_pEdit)
+ return;
+ m_pOwner->m_pEdit->SetSelected();
+ } else {
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ }
+ } else {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
+ if (bDropDown && pDstTarget != m_pOwner->m_pListBox.get()) {
+ if (!m_pOwner->m_pEdit)
+ return;
+ m_pOwner->m_pEdit->FlagFocus(FALSE);
+ m_pOwner->m_pEdit->ClearSelected();
+ } else {
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ }
+ }
+}
+
+void CFWL_ComboBoxImpDelegate::OnLButtonDown(CFWL_MsgMouse* pMsg) {
+ if (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) {
+ return;
+ }
+ FX_BOOL bDropDown = m_pOwner->IsDropDownStyle();
+ CFX_RectF& rtBtn = bDropDown ? m_pOwner->m_rtBtn : m_pOwner->m_rtClient;
+ FX_BOOL bClickBtn = rtBtn.Contains(pMsg->m_fx, pMsg->m_fy);
+ if (bClickBtn) {
+ if (bDropDown && m_pOwner->m_pEdit) {
+ m_pOwner->MatchEditText();
+ }
+ m_pOwner->m_bLButtonDown = TRUE;
+ m_pOwner->m_iBtnState = CFWL_PartState_Pressed;
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ m_pOwner->ShowDropList(TRUE);
+ m_pOwner->m_iBtnState = CFWL_PartState_Normal;
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ }
+}
+
+void CFWL_ComboBoxImpDelegate::OnLButtonUp(CFWL_MsgMouse* pMsg) {
+ m_pOwner->m_bLButtonDown = FALSE;
+ if (m_pOwner->m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_iBtnState = CFWL_PartState_Hovered;
+ } else {
+ m_pOwner->m_iBtnState = CFWL_PartState_Normal;
+ }
+ m_pOwner->Repaint(&m_pOwner->m_rtBtn);
+}
+
+void CFWL_ComboBoxImpDelegate::OnMouseMove(CFWL_MsgMouse* pMsg) {
+ int32_t iOldState = m_pOwner->m_iBtnState;
+ if (m_pOwner->m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_iBtnState = m_pOwner->m_bLButtonDown ? CFWL_PartState_Pressed
+ : CFWL_PartState_Hovered;
+ } else {
+ m_pOwner->m_iBtnState = CFWL_PartState_Normal;
+ }
+ if ((iOldState != m_pOwner->m_iBtnState) &&
+ !((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) ==
+ FWL_WGTSTATE_Disabled)) {
+ m_pOwner->Repaint(&m_pOwner->m_rtBtn);
+ }
+}
+
+void CFWL_ComboBoxImpDelegate::OnMouseLeave(CFWL_MsgMouse* pMsg) {
+ if (!m_pOwner->IsDropListShowed() &&
+ !((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) ==
+ FWL_WGTSTATE_Disabled)) {
+ m_pOwner->m_iBtnState = CFWL_PartState_Normal;
+ m_pOwner->Repaint(&m_pOwner->m_rtBtn);
+ }
+}
+
+void CFWL_ComboBoxImpDelegate::OnKey(CFWL_MsgKey* pMsg) {
+ uint32_t dwKeyCode = pMsg->m_dwKeyCode;
+ if (dwKeyCode == FWL_VKEY_Tab) {
+ m_pOwner->DispatchKeyEvent(pMsg);
+ return;
+ }
+ if (pMsg->m_pDstTarget == m_pOwner)
+ DoSubCtrlKey(pMsg);
+}
+
+void CFWL_ComboBoxImpDelegate::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_pOwner->m_pListBox->CountItems();
+ if (iCount < 1) {
+ return;
+ }
+ FX_BOOL bMatchEqual = FALSE;
+ int32_t iCurSel = m_pOwner->m_iCurSel;
+ FX_BOOL bDropDown = m_pOwner->IsDropDownStyle();
+ if (bDropDown && m_pOwner->m_pEdit) {
+ CFX_WideString wsText;
+ m_pOwner->m_pEdit->GetText(wsText);
+ iCurSel = m_pOwner->m_pListBox->MatchItem(wsText);
+ if (iCurSel >= 0) {
+ CFX_WideString wsTemp;
+ IFWL_ComboBoxDP* pData = static_cast<IFWL_ComboBoxDP*>(
+ m_pOwner->m_pProperties->m_pDataProvider);
+ IFWL_ListItem* hItem = pData->GetItem(m_pOwner, iCurSel);
+ m_pOwner->m_pListBox->GetItemText(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_pOwner->m_iCurSel = iCurSel;
+ if (bDropDown && m_pOwner->m_pEdit) {
+ m_pOwner->SynchrEditText(m_pOwner->m_iCurSel);
+ } else {
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ }
+ return;
+ }
+ FX_BOOL bDropDown = m_pOwner->IsDropDownStyle();
+ if (bDropDown) {
+ IFWL_WidgetDelegate* pDelegate = m_pOwner->m_pEdit->SetDelegate(nullptr);
+ pDelegate->OnProcessMessage(pMsg);
+ }
+}
+
+void CFWL_ComboBoxImpDelegate::DisForm_OnProcessMessage(
+ CFWL_Message* pMessage) {
+ if (!pMessage)
+ return;
+
+ FX_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 (m_pOwner->DisForm_IsDropListShowed() &&
+ pKey->m_dwCmd == FWL_KeyCommand::KeyDown) {
+ FX_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) {
+ IFWL_WidgetDelegate* pDelegate =
+ m_pOwner->m_pListBox->SetDelegate(nullptr);
+ pDelegate->OnProcessMessage(pMessage);
+ break;
+ }
+ }
+ DisForm_OnKey(pKey);
+ break;
+ }
+ default:
+ break;
+ }
+ if (backDefault)
+ CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);
+}
+
+void CFWL_ComboBoxImpDelegate::DisForm_OnLButtonDown(CFWL_MsgMouse* pMsg) {
+ FX_BOOL bDropDown = m_pOwner->DisForm_IsDropListShowed();
+ CFX_RectF& rtBtn = bDropDown ? m_pOwner->m_rtBtn : m_pOwner->m_rtClient;
+ FX_BOOL bClickBtn = rtBtn.Contains(pMsg->m_fx, pMsg->m_fy);
+ if (bClickBtn) {
+ if (m_pOwner->DisForm_IsDropListShowed()) {
+ m_pOwner->DisForm_ShowDropList(FALSE);
+ return;
+ }
+ {
+ if (m_pOwner->m_pEdit) {
+ m_pOwner->MatchEditText();
+ }
+ m_pOwner->DisForm_ShowDropList(TRUE);
+ }
+ }
+}
+
+void CFWL_ComboBoxImpDelegate::DisForm_OnFocusChanged(CFWL_Message* pMsg,
+ FX_BOOL bSet) {
+ if (bSet) {
+ m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
+ if ((m_pOwner->m_pEdit->GetStates() & FWL_WGTSTATE_Focused) == 0) {
+ CFWL_MsgSetFocus msg;
+ msg.m_pDstTarget = m_pOwner->m_pEdit.get();
+ msg.m_pSrcTarget = nullptr;
+ IFWL_WidgetDelegate* pDelegate = m_pOwner->m_pEdit->SetDelegate(nullptr);
+ pDelegate->OnProcessMessage(&msg);
+ }
+ } else {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
+ m_pOwner->DisForm_ShowDropList(FALSE);
+ CFWL_MsgKillFocus msg;
+ msg.m_pDstTarget = nullptr;
+ msg.m_pSrcTarget = m_pOwner->m_pEdit.get();
+ IFWL_WidgetDelegate* pDelegate = m_pOwner->m_pEdit->SetDelegate(nullptr);
+ pDelegate->OnProcessMessage(&msg);
+ }
+}
+
+void CFWL_ComboBoxImpDelegate::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) {
+ IFWL_ComboList* pComboList = m_pOwner->m_pListBox.get();
+ int32_t iCount = pComboList->CountItems();
+ if (iCount < 1) {
+ return;
+ }
+ FX_BOOL bMatchEqual = FALSE;
+ int32_t iCurSel = m_pOwner->m_iCurSel;
+ if (m_pOwner->m_pEdit) {
+ CFX_WideString wsText;
+ m_pOwner->m_pEdit->GetText(wsText);
+ iCurSel = pComboList->MatchItem(wsText);
+ if (iCurSel >= 0) {
+ CFX_WideString wsTemp;
+ IFWL_ListItem* item = m_pOwner->m_pListBox->GetSelItem(iCurSel);
+ m_pOwner->m_pListBox->GetItemText(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_pOwner->m_iCurSel = iCurSel;
+ m_pOwner->SynchrEditText(m_pOwner->m_iCurSel);
+ return;
+ }
+ if (m_pOwner->m_pEdit) {
+ IFWL_WidgetDelegate* pDelegate = m_pOwner->m_pEdit->SetDelegate(nullptr);
+ pDelegate->OnProcessMessage(pMsg);
+ }
+}
+
+CFWL_ComboProxyImpDelegate::CFWL_ComboProxyImpDelegate(IFWL_Form* pForm,
+ IFWL_ComboBox* pComboBox)
+ : m_bLButtonDown(FALSE),
+ m_bLButtonUpSelf(FALSE),
+ m_fStartPos(0),
+ m_pForm(pForm),
+ m_pComboBox(pComboBox) {}
+
+void CFWL_ComboProxyImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
+ if (!pMessage)
+ return;
+
+ switch (pMessage->GetClassID()) {
+ 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;
+ }
+ default:
+ break;
+ }
+ break;
+ }
+ case CFWL_MessageType::Deactivate: {
+ OnDeactive(static_cast<CFWL_MsgDeactivate*>(pMessage));
+ break;
+ }
+ case CFWL_MessageType::KillFocus: {
+ OnFocusChanged(static_cast<CFWL_MsgKillFocus*>(pMessage), FALSE);
+ break;
+ }
+ case CFWL_MessageType::SetFocus: {
+ OnFocusChanged(static_cast<CFWL_MsgKillFocus*>(pMessage), TRUE);
+ break;
+ }
+ default:
+ break;
+ }
+ CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);
+}
+
+void CFWL_ComboProxyImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ m_pComboBox->DrawStretchHandler(pGraphics, pMatrix);
+}
+
+void CFWL_ComboProxyImpDelegate::OnLButtonDown(CFWL_MsgMouse* pMsg) {
+ IFWL_App* pApp = m_pForm->GetOwnerApp();
+ if (!pApp)
+ return;
+
+ CFWL_NoteDriver* pDriver =
+ static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver());
+ CFX_RectF rtWidget;
+ m_pForm->GetWidgetRect(rtWidget);
+ rtWidget.left = rtWidget.top = 0;
+ if (rtWidget.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_bLButtonDown = TRUE;
+ pDriver->SetGrab(m_pForm, TRUE);
+ } else {
+ m_bLButtonDown = FALSE;
+ pDriver->SetGrab(m_pForm, FALSE);
+ m_pComboBox->ShowDropList(FALSE);
+ }
+}
+
+void CFWL_ComboProxyImpDelegate::OnLButtonUp(CFWL_MsgMouse* pMsg) {
+ m_bLButtonDown = FALSE;
+ IFWL_App* pApp = m_pForm->GetOwnerApp();
+ if (!pApp)
+ return;
+
+ CFWL_NoteDriver* pDriver =
+ static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver());
+ pDriver->SetGrab(m_pForm, FALSE);
+ if (m_bLButtonUpSelf) {
+ CFX_RectF rect;
+ m_pForm->GetWidgetRect(rect);
+ rect.left = rect.top = 0;
+ if (!rect.Contains(pMsg->m_fx, pMsg->m_fy) &&
+ m_pComboBox->IsDropListShowed()) {
+ m_pComboBox->ShowDropList(FALSE);
+ }
+ } else {
+ m_bLButtonUpSelf = TRUE;
+ }
+}
+
+void CFWL_ComboProxyImpDelegate::OnMouseMove(CFWL_MsgMouse* pMsg) {}
+
+void CFWL_ComboProxyImpDelegate::OnDeactive(CFWL_MsgDeactivate* pMsg) {
+ m_pComboBox->ShowDropList(FALSE);
+}
+
+void CFWL_ComboProxyImpDelegate::OnFocusChanged(CFWL_MsgKillFocus* pMsg,
+ FX_BOOL bSet) {
+ if (!bSet) {
+ if (!pMsg->m_pSetFocus) {
+ m_pComboBox->ShowDropList(FALSE);
+ }
+ }
+}
diff --git a/xfa/fwl/core/ifwl_combobox.h b/xfa/fwl/core/ifwl_combobox.h
new file mode 100644
index 0000000000..106b7c0c08
--- /dev/null
+++ b/xfa/fwl/core/ifwl_combobox.h
@@ -0,0 +1,244 @@
+// 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 "xfa/fwl/core/ifwl_form.h"
+#include "xfa/fwl/core/ifwl_listbox.h"
+#include "xfa/fxgraphics/cfx_graphics.h"
+
+class CFWL_ComboBoxImpDelegate;
+class CFWL_ComboEditImpDelegate;
+class CFWL_ComboListImpDelegate;
+class CFWL_ComboProxyImpDelegate;
+class CFWL_ListBoxImpDelegate;
+class CFWL_WidgetImpProperties;
+class CFWL_WidgetImpDelegate;
+class IFWL_ComboBox;
+class IFWL_ComboEdit;
+class IFWL_ComboList;
+class IFWL_FormProxy;
+class IFWL_ListBox;
+class IFWL_Widget;
+
+#define FWL_CLASS_ComboBox L"FWL_COMBOBOX"
+#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)
+
+FWL_EVENT_DEF(CFWL_EvtCmbPreDropDown, CFWL_EventType::PreDropDown)
+
+FWL_EVENT_DEF(CFWL_EvtCmbPostDropDown, CFWL_EventType::PostDropDown)
+
+FWL_EVENT_DEF(CFWL_EvtCmbCloseUp, CFWL_EventType::CloseUp)
+
+FWL_EVENT_DEF(CFWL_EvtCmbEditChanged,
+ CFWL_EventType::EditChanged,
+ int32_t nChangeType;
+ CFX_WideString wsInsert;
+ CFX_WideString wsDelete;)
+
+FWL_EVENT_DEF(CFWL_EvtCmbSelChanged,
+ CFWL_EventType::SelectChanged,
+ CFX_Int32Array iArraySels;
+ FX_BOOL bLButtonUp;)
+
+FWL_EVENT_DEF(CFWL_EvtCmbHoverChanged,
+ CFWL_EventType::HoverChanged,
+ int32_t m_iCurHover;)
+
+FWL_EVENT_DEF(CFWL_EvtCmbDrawItem,
+ CFWL_EventType::DrawItem,
+ CFX_Graphics* m_pGraphics;
+ CFX_Matrix m_matrix;
+ int32_t m_index;
+ CFX_RectF m_rtItem;)
+
+class IFWL_ComboBoxDP : public IFWL_ListBoxDP {
+ public:
+ virtual FX_FLOAT GetListHeight(IFWL_Widget* pWidget) = 0;
+};
+
+class IFWL_ComboBox : public IFWL_Widget {
+ public:
+ static IFWL_ComboBox* Create(const CFWL_WidgetImpProperties& properties);
+
+ IFWL_ComboBox(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+ ~IFWL_ComboBox() override;
+
+ // IFWL_Widget
+ FWL_Error GetClassName(CFX_WideString& wsClass) const override;
+ FWL_Type GetClassID() const override;
+ FWL_Error Initialize() override;
+ FWL_Error Finalize() override;
+ FWL_Error GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize = FALSE) override;
+ FWL_Error ModifyStylesEx(uint32_t dwStylesExAdded,
+ uint32_t dwStylesExRemoved) override;
+ void SetStates(uint32_t dwStates, FX_BOOL bSet = TRUE) override;
+ FWL_Error Update() override;
+ FWL_WidgetHit HitTest(FX_FLOAT fx, FX_FLOAT fy) override;
+ FWL_Error DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
+ FWL_Error SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) override;
+
+ int32_t GetCurSel();
+ FWL_Error SetCurSel(int32_t iSel);
+ FWL_Error SetEditText(const CFX_WideString& wsText);
+ int32_t GetEditTextLength() const;
+ FWL_Error GetEditText(CFX_WideString& wsText,
+ int32_t nStart = 0,
+ int32_t nCount = -1) const;
+ FWL_Error SetEditSelRange(int32_t nStart, int32_t nCount = -1);
+ int32_t GetEditSelRange(int32_t nIndex, int32_t& nStart);
+ int32_t GetEditLimit();
+ FWL_Error SetEditLimit(int32_t nLimit);
+ FWL_Error EditDoClipboard(int32_t iCmd);
+ FX_BOOL EditRedo(const IFDE_TxtEdtDoRecord* pRecord);
+ FX_BOOL EditUndo(const IFDE_TxtEdtDoRecord* pRecord);
+ IFWL_ListBox* GetListBoxt();
+ FX_BOOL AfterFocusShowDropList();
+ FWL_Error OpenDropDownList(FX_BOOL bActivate);
+ FX_BOOL EditCanUndo();
+ FX_BOOL EditCanRedo();
+ FX_BOOL EditUndo();
+ FX_BOOL EditRedo();
+ FX_BOOL EditCanCopy();
+ FX_BOOL EditCanCut();
+ FX_BOOL EditCanSelectAll();
+ FX_BOOL EditCopy(CFX_WideString& wsCopy);
+ FX_BOOL EditCut(CFX_WideString& wsCut);
+ FX_BOOL EditPaste(const CFX_WideString& wsPaste);
+ FX_BOOL EditSelectAll();
+ FX_BOOL EditDelete();
+ FX_BOOL EditDeSelect();
+ FWL_Error GetBBox(CFX_RectF& rect);
+ FWL_Error EditModifyStylesEx(uint32_t dwStylesExAdded,
+ uint32_t dwStylesExRemoved);
+
+ protected:
+ friend class CFWL_ComboBoxImpDelegate;
+ friend class CFWL_ComboEditImpDelegate;
+ friend class CFWL_ComboListImpDelegate;
+ friend class CFWL_ComboProxyImpDelegate;
+ friend class IFWL_ComboEdit;
+ friend class IFWL_ComboList;
+
+ void DrawStretchHandler(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix);
+ FX_FLOAT GetListHeight();
+ void ShowDropList(FX_BOOL bActivate);
+ FX_BOOL IsDropListShowed();
+ FX_BOOL IsDropDownStyle() const;
+ void MatchEditText();
+ void SynchrEditText(int32_t iListItem);
+ void Layout();
+ void ReSetTheme();
+ void ReSetEditAlignment();
+ void ReSetListItemAlignment();
+ void ProcessSelChanged(FX_BOOL bLButtonUp);
+ void InitProxyForm();
+ FWL_Error DisForm_Initialize();
+ void DisForm_InitComboList();
+ void DisForm_InitComboEdit();
+ void DisForm_ShowDropList(FX_BOOL bActivate);
+ FX_BOOL DisForm_IsDropListShowed();
+ FWL_Error DisForm_ModifyStylesEx(uint32_t dwStylesExAdded,
+ uint32_t dwStylesExRemoved);
+ FWL_Error DisForm_Update();
+ FWL_WidgetHit DisForm_HitTest(FX_FLOAT fx, FX_FLOAT fy);
+ FWL_Error DisForm_DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr);
+ FWL_Error DisForm_GetBBox(CFX_RectF& rect);
+ void DisForm_Layout();
+
+ 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<IFWL_ComboEdit> m_pEdit;
+ std::unique_ptr<IFWL_ComboList> m_pListBox;
+ IFWL_FormProxy* m_pForm;
+ FX_BOOL m_bLButtonDown;
+ FX_BOOL m_bUpFormHandler;
+ int32_t m_iCurSel;
+ int32_t m_iBtnState;
+ FX_FLOAT m_fComboFormHandler;
+ FX_FLOAT m_fItemHeight;
+ FX_BOOL m_bNeedShowList;
+ CFWL_ComboProxyImpDelegate* m_pListProxyDelegate;
+};
+
+class CFWL_ComboBoxImpDelegate : public CFWL_WidgetImpDelegate {
+ public:
+ CFWL_ComboBoxImpDelegate(IFWL_ComboBox* pOwner);
+ void OnProcessMessage(CFWL_Message* pMessage) override;
+ void OnProcessEvent(CFWL_Event* pEvent) override;
+ void OnDrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
+
+ protected:
+ void OnFocusChanged(CFWL_Message* pMsg, FX_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, FX_BOOL bSet = TRUE);
+ void DisForm_OnKey(CFWL_MsgKey* pMsg);
+
+ IFWL_ComboBox* m_pOwner;
+ friend class CFWL_ComboEditImpDelegate;
+ friend class CFWL_ComboListImpDelegate;
+};
+
+class CFWL_ComboProxyImpDelegate : public CFWL_WidgetImpDelegate {
+ public:
+ CFWL_ComboProxyImpDelegate(IFWL_Form* pForm, IFWL_ComboBox* pComboBox);
+ void OnProcessMessage(CFWL_Message* pMessage) override;
+ void OnDrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
+ void Reset() { m_bLButtonUpSelf = FALSE; }
+
+ protected:
+ void OnLButtonDown(CFWL_MsgMouse* pMsg);
+ void OnLButtonUp(CFWL_MsgMouse* pMsg);
+ void OnMouseMove(CFWL_MsgMouse* pMsg);
+ void OnDeactive(CFWL_MsgDeactivate* pMsg);
+ void OnFocusChanged(CFWL_MsgKillFocus* pMsg, FX_BOOL bSet);
+ FX_BOOL m_bLButtonDown;
+ FX_BOOL m_bLButtonUpSelf;
+ FX_FLOAT m_fStartPos;
+ IFWL_Form* m_pForm;
+ IFWL_ComboBox* m_pComboBox;
+};
+
+#endif // XFA_FWL_CORE_IFWL_COMBOBOX_H_
diff --git a/xfa/fwl/core/ifwl_comboedit.cpp b/xfa/fwl/core/ifwl_comboedit.cpp
new file mode 100644
index 0000000000..f345090fca
--- /dev/null
+++ b/xfa/fwl/core/ifwl_comboedit.cpp
@@ -0,0 +1,86 @@
+// Copyright 2016 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_comboedit.h"
+
+#include "xfa/fde/cfde_txtedtengine.h"
+#include "xfa/fwl/core/ifwl_combobox.h"
+
+// static
+IFWL_ComboEdit* IFWL_ComboEdit::Create(
+ const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter) {
+ return new IFWL_ComboEdit(properties, pOuter);
+}
+
+IFWL_ComboEdit::IFWL_ComboEdit(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter)
+ : IFWL_Edit(properties, pOuter) {
+ m_pOuter = static_cast<IFWL_ComboBox*>(pOuter);
+}
+
+void IFWL_ComboEdit::ClearSelected() {
+ ClearSelections();
+ Repaint(&m_rtClient);
+}
+
+void IFWL_ComboEdit::SetSelected() {
+ FlagFocus(TRUE);
+ EndCaret();
+ AddSelRange(0);
+}
+
+void IFWL_ComboEdit::EndCaret() {
+ m_pEdtEngine->MoveCaretPos(MC_End);
+}
+
+void IFWL_ComboEdit::FlagFocus(FX_BOOL bSet) {
+ if (bSet) {
+ m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
+ } else {
+ m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
+ ShowCaret(FALSE);
+ }
+}
+
+void IFWL_ComboEdit::SetComboBoxFocus(FX_BOOL bSet) {
+ m_pOuter->SetFocus(bSet);
+}
+
+CFWL_ComboEditImpDelegate::CFWL_ComboEditImpDelegate(IFWL_ComboEdit* pOwner)
+ : CFWL_EditImpDelegate(pOwner), m_pOwner(pOwner) {}
+
+void CFWL_ComboEditImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
+ if (!pMessage)
+ return;
+
+ FX_BOOL backDefault = TRUE;
+ switch (pMessage->GetClassID()) {
+ case CFWL_MessageType::SetFocus: {
+ m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
+ backDefault = FALSE;
+ break;
+ }
+ case CFWL_MessageType::KillFocus: {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
+ backDefault = FALSE;
+ break;
+ }
+ case CFWL_MessageType::Mouse: {
+ CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage);
+ if ((pMsg->m_dwCmd == FWL_MouseCommand::LeftButtonDown) &&
+ ((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0)) {
+ m_pOwner->SetSelected();
+ m_pOwner->SetComboBoxFocus(TRUE);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ if (backDefault)
+ CFWL_EditImpDelegate::OnProcessMessage(pMessage);
+}
diff --git a/xfa/fwl/core/ifwl_comboedit.h b/xfa/fwl/core/ifwl_comboedit.h
new file mode 100644
index 0000000000..22c3f01e41
--- /dev/null
+++ b/xfa/fwl/core/ifwl_comboedit.h
@@ -0,0 +1,44 @@
+// Copyright 2016 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_COMBOEDIT_H_
+#define XFA_FWL_CORE_IFWL_COMBOEDIT_H_
+
+#include "xfa/fwl/core/cfwl_widgetimpproperties.h"
+#include "xfa/fwl/core/ifwl_edit.h"
+#include "xfa/fwl/core/ifwl_widget.h"
+
+class IFWL_ComboBox;
+
+class IFWL_ComboEdit : public IFWL_Edit {
+ public:
+ static IFWL_ComboEdit* Create(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+
+ IFWL_ComboEdit(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+
+ void ClearSelected();
+ void SetSelected();
+ void EndCaret();
+ void FlagFocus(FX_BOOL bSet);
+
+ protected:
+ void SetComboBoxFocus(FX_BOOL bSet);
+ IFWL_ComboBox* m_pOuter;
+ friend class CFWL_ComboEditImpDelegate;
+};
+
+class CFWL_ComboEditImpDelegate : public CFWL_EditImpDelegate {
+ public:
+ CFWL_ComboEditImpDelegate(IFWL_ComboEdit* pOwner);
+ void OnProcessMessage(CFWL_Message* pMessage) override;
+
+ protected:
+ IFWL_ComboEdit* m_pOwner;
+};
+
+#endif // XFA_FWL_CORE_IFWL_COMBOEDIT_H_
diff --git a/xfa/fwl/core/ifwl_combolist.cpp b/xfa/fwl/core/ifwl_combolist.cpp
new file mode 100644
index 0000000000..9090622b10
--- /dev/null
+++ b/xfa/fwl/core/ifwl_combolist.cpp
@@ -0,0 +1,298 @@
+// Copyright 2016 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_combolist.h"
+
+#include "xfa/fwl/core/ifwl_combobox.h"
+#include "xfa/fwl/core/ifwl_comboedit.h"
+
+// static
+IFWL_ComboList* IFWL_ComboList::Create(
+ const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter) {
+ return new IFWL_ComboList(properties, pOuter);
+}
+
+IFWL_ComboList::IFWL_ComboList(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter)
+ : IFWL_ListBox(properties, pOuter), m_bNotifyOwner(TRUE) {
+ ASSERT(pOuter);
+}
+
+FWL_Error IFWL_ComboList::Initialize() {
+ if (IFWL_ListBox::Initialize() != FWL_Error::Succeeded)
+ return FWL_Error::Indefinite;
+ delete m_pDelegate;
+ m_pDelegate = new CFWL_ComboListImpDelegate(this);
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_ComboList::Finalize() {
+ delete m_pDelegate;
+ m_pDelegate = nullptr;
+ return IFWL_ListBox::Finalize();
+}
+
+int32_t IFWL_ComboList::MatchItem(const CFX_WideString& wsMatch) {
+ if (wsMatch.IsEmpty()) {
+ return -1;
+ }
+ if (!m_pProperties->m_pDataProvider)
+ return -1;
+ IFWL_ListBoxDP* pData =
+ static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
+ int32_t iCount = pData->CountItems(this);
+ for (int32_t i = 0; i < iCount; i++) {
+ IFWL_ListItem* hItem = pData->GetItem(this, i);
+ CFX_WideString wsText;
+ pData->GetItemText(this, hItem, wsText);
+ FX_STRSIZE pos = wsText.Find(wsMatch.c_str());
+ if (!pos) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+void IFWL_ComboList::ChangeSelected(int32_t iSel) {
+ if (!m_pProperties->m_pDataProvider)
+ return;
+ IFWL_ListBoxDP* pData =
+ static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
+ IFWL_ListItem* hItem = pData->GetItem(this, iSel);
+ CFX_RectF rtInvalidate;
+ rtInvalidate.Reset();
+ IFWL_ListItem* hOld = GetSelItem(0);
+ int32_t iOld = pData->GetItemIndex(this, hOld);
+ if (iOld == iSel) {
+ return;
+ } else if (iOld > -1) {
+ GetItemRect(iOld, rtInvalidate);
+ SetSelItem(hOld, FALSE);
+ }
+ if (hItem) {
+ CFX_RectF rect;
+ GetItemRect(iSel, rect);
+ rtInvalidate.Union(rect);
+ IFWL_ListItem* hSel = pData->GetItem(this, iSel);
+ SetSelItem(hSel, TRUE);
+ }
+ if (!rtInvalidate.IsEmpty()) {
+ Repaint(&rtInvalidate);
+ }
+}
+
+int32_t IFWL_ComboList::CountItems() {
+ IFWL_ListBoxDP* pData =
+ static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
+ return pData ? pData->CountItems(this) : 0;
+}
+
+void IFWL_ComboList::GetItemRect(int32_t nIndex, CFX_RectF& rtItem) {
+ IFWL_ListBoxDP* pData =
+ static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
+ IFWL_ListItem* hItem = pData->GetItem(this, nIndex);
+ pData->GetItemRect(this, hItem, rtItem);
+}
+
+void IFWL_ComboList::ClientToOuter(FX_FLOAT& fx, FX_FLOAT& fy) {
+ fx += m_pProperties->m_rtWidget.left, fy += m_pProperties->m_rtWidget.top;
+ IFWL_Widget* pOwner = GetOwner();
+ if (!pOwner)
+ return;
+ pOwner->TransformTo(m_pOuter, fx, fy);
+}
+
+void IFWL_ComboList::SetFocus(FX_BOOL bSet) {
+ IFWL_Widget::SetFocus(bSet);
+}
+
+CFWL_ComboListImpDelegate::CFWL_ComboListImpDelegate(IFWL_ComboList* pOwner)
+ : CFWL_ListBoxImpDelegate(pOwner), m_pOwner(pOwner) {}
+
+void CFWL_ComboListImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
+ if (!pMessage)
+ return;
+
+ CFWL_MessageType dwHashCode = pMessage->GetClassID();
+ FX_BOOL backDefault = TRUE;
+ if (dwHashCode == CFWL_MessageType::SetFocus ||
+ dwHashCode == CFWL_MessageType::KillFocus) {
+ OnDropListFocusChanged(pMessage, dwHashCode == CFWL_MessageType::SetFocus);
+ } else if (dwHashCode == CFWL_MessageType::Mouse) {
+ CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage);
+ if (m_pOwner->IsShowScrollBar(TRUE) && m_pOwner->m_pVertScrollBar) {
+ CFX_RectF rect;
+ m_pOwner->m_pVertScrollBar->GetWidgetRect(rect);
+ if (rect.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ pMsg->m_fx -= rect.left;
+ pMsg->m_fy -= rect.top;
+ IFWL_WidgetDelegate* pDelegate =
+ m_pOwner->m_pVertScrollBar->SetDelegate(nullptr);
+ pDelegate->OnProcessMessage(pMsg);
+ return;
+ }
+ }
+ switch (pMsg->m_dwCmd) {
+ case FWL_MouseCommand::Move: {
+ backDefault = FALSE;
+ OnDropListMouseMove(pMsg);
+ break;
+ }
+ case FWL_MouseCommand::LeftButtonDown: {
+ backDefault = FALSE;
+ OnDropListLButtonDown(pMsg);
+ break;
+ }
+ case FWL_MouseCommand::LeftButtonUp: {
+ backDefault = FALSE;
+ OnDropListLButtonUp(pMsg);
+ break;
+ }
+ default:
+ break;
+ }
+ } else if (dwHashCode == CFWL_MessageType::Key) {
+ backDefault = !OnDropListKey(static_cast<CFWL_MsgKey*>(pMessage));
+ }
+ if (backDefault)
+ CFWL_ListBoxImpDelegate::OnProcessMessage(pMessage);
+}
+
+void CFWL_ComboListImpDelegate::OnDropListFocusChanged(CFWL_Message* pMsg,
+ FX_BOOL bSet) {
+ if (!bSet) {
+ CFWL_MsgKillFocus* pKill = static_cast<CFWL_MsgKillFocus*>(pMsg);
+ IFWL_ComboBox* pOuter = static_cast<IFWL_ComboBox*>(m_pOwner->m_pOuter);
+ if (pKill->m_pSetFocus == m_pOwner->m_pOuter ||
+ pKill->m_pSetFocus == pOuter->m_pEdit.get()) {
+ pOuter->ShowDropList(FALSE);
+ }
+ }
+}
+
+int32_t CFWL_ComboListImpDelegate::OnDropListMouseMove(CFWL_MsgMouse* pMsg) {
+ if (m_pOwner->m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ if (m_pOwner->m_bNotifyOwner) {
+ m_pOwner->m_bNotifyOwner = FALSE;
+ }
+ if (m_pOwner->IsShowScrollBar(TRUE) && m_pOwner->m_pVertScrollBar) {
+ CFX_RectF rect;
+ m_pOwner->m_pVertScrollBar->GetWidgetRect(rect);
+ if (rect.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ return 1;
+ }
+ }
+ IFWL_ListItem* hItem = m_pOwner->GetItemAtPoint(pMsg->m_fx, pMsg->m_fy);
+ if (hItem) {
+ if (!m_pOwner->m_pProperties->m_pDataProvider)
+ return 0;
+ IFWL_ListBoxDP* pData = static_cast<IFWL_ListBoxDP*>(
+ m_pOwner->m_pProperties->m_pDataProvider);
+ int32_t iSel = pData->GetItemIndex(m_pOwner, hItem);
+ CFWL_EvtCmbHoverChanged event;
+ event.m_pSrcTarget = m_pOwner->m_pOuter;
+ event.m_iCurHover = iSel;
+ m_pOwner->DispatchEvent(&event);
+ m_pOwner->ChangeSelected(iSel);
+ }
+ } else if (m_pOwner->m_bNotifyOwner) {
+ m_pOwner->ClientToOuter(pMsg->m_fx, pMsg->m_fy);
+ IFWL_ComboBox* pOuter = static_cast<IFWL_ComboBox*>(m_pOwner->m_pOuter);
+ pOuter->m_pDelegate->OnProcessMessage(pMsg);
+ }
+ return 1;
+}
+
+int32_t CFWL_ComboListImpDelegate::OnDropListLButtonDown(CFWL_MsgMouse* pMsg) {
+ if (m_pOwner->m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ return 0;
+ }
+ IFWL_ComboBox* pOuter = static_cast<IFWL_ComboBox*>(m_pOwner->m_pOuter);
+ pOuter->ShowDropList(FALSE);
+ return 1;
+}
+
+int32_t CFWL_ComboListImpDelegate::OnDropListLButtonUp(CFWL_MsgMouse* pMsg) {
+ IFWL_ComboBox* pOuter = static_cast<IFWL_ComboBox*>(m_pOwner->m_pOuter);
+ if (m_pOwner->m_bNotifyOwner) {
+ m_pOwner->ClientToOuter(pMsg->m_fx, pMsg->m_fy);
+ pOuter->m_pDelegate->OnProcessMessage(pMsg);
+ } else {
+ if (m_pOwner->IsShowScrollBar(TRUE) && m_pOwner->m_pVertScrollBar) {
+ CFX_RectF rect;
+ m_pOwner->m_pVertScrollBar->GetWidgetRect(rect);
+ if (rect.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ return 1;
+ }
+ }
+ pOuter->ShowDropList(FALSE);
+ IFWL_ListItem* hItem = m_pOwner->GetItemAtPoint(pMsg->m_fx, pMsg->m_fy);
+ if (hItem) {
+ pOuter->ProcessSelChanged(TRUE);
+ }
+ }
+ return 1;
+}
+
+int32_t CFWL_ComboListImpDelegate::OnDropListKey(CFWL_MsgKey* pKey) {
+ IFWL_ComboBox* pOuter = static_cast<IFWL_ComboBox*>(m_pOwner->m_pOuter);
+ FX_BOOL bPropagate = FALSE;
+ if (pKey->m_dwCmd == FWL_KeyCommand::KeyDown) {
+ uint32_t dwKeyCode = pKey->m_dwKeyCode;
+ switch (dwKeyCode) {
+ case FWL_VKEY_Return:
+ case FWL_VKEY_Escape: {
+ pOuter->ShowDropList(FALSE);
+ return 1;
+ }
+ case FWL_VKEY_Up:
+ case FWL_VKEY_Down: {
+ OnDropListKeyDown(pKey);
+ pOuter->SetDelegate(nullptr);
+ pOuter->ProcessSelChanged(FALSE);
+ return 1;
+ }
+ default: { bPropagate = TRUE; }
+ }
+ } else if (pKey->m_dwCmd == FWL_KeyCommand::Char) {
+ bPropagate = TRUE;
+ }
+ if (bPropagate) {
+ pKey->m_pDstTarget = m_pOwner->m_pOuter;
+ pOuter->m_pDelegate->OnProcessMessage(pKey);
+ return 1;
+ }
+ return 0;
+}
+
+void CFWL_ComboListImpDelegate::OnDropListKeyDown(CFWL_MsgKey* pKey) {
+ uint32_t dwKeyCode = pKey->m_dwKeyCode;
+ switch (dwKeyCode) {
+ case FWL_VKEY_Up:
+ case FWL_VKEY_Down:
+ case FWL_VKEY_Home:
+ case FWL_VKEY_End: {
+ IFWL_ComboBox* pOuter = static_cast<IFWL_ComboBox*>(m_pOwner->m_pOuter);
+ IFWL_ListBoxDP* pData = static_cast<IFWL_ListBoxDP*>(
+ m_pOwner->m_pProperties->m_pDataProvider);
+ IFWL_ListItem* hItem = pData->GetItem(m_pOwner, pOuter->m_iCurSel);
+ hItem = m_pOwner->GetItem(hItem, dwKeyCode);
+ if (!hItem) {
+ break;
+ }
+ m_pOwner->SetSelection(hItem, hItem, TRUE);
+ m_pOwner->ScrollToVisible(hItem);
+ CFX_RectF rtInvalidate;
+ rtInvalidate.Set(0, 0, m_pOwner->m_pProperties->m_rtWidget.width,
+ m_pOwner->m_pProperties->m_rtWidget.height);
+ m_pOwner->Repaint(&rtInvalidate);
+ break;
+ }
+ default:
+ break;
+ }
+}
diff --git a/xfa/fwl/core/ifwl_combolist.h b/xfa/fwl/core/ifwl_combolist.h
new file mode 100644
index 0000000000..74e79cd805
--- /dev/null
+++ b/xfa/fwl/core/ifwl_combolist.h
@@ -0,0 +1,54 @@
+// 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_COMBOLIST_H_
+#define XFA_FWL_CORE_IFWL_COMBOLIST_H_
+
+#include "xfa/fwl/core/cfwl_widgetimpproperties.h"
+#include "xfa/fwl/core/ifwl_listbox.h"
+#include "xfa/fwl/core/ifwl_widget.h"
+
+class IFWL_ComboList : public IFWL_ListBox {
+ public:
+ static IFWL_ComboList* Create(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+
+ IFWL_ComboList(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+
+ // IFWL_Widget
+ FWL_Error Initialize() override;
+ FWL_Error Finalize() override;
+
+ int32_t MatchItem(const CFX_WideString& wsMatch);
+ void ChangeSelected(int32_t iSel);
+ int32_t CountItems();
+ void GetItemRect(int32_t nIndex, CFX_RectF& rtItem);
+ void ClientToOuter(FX_FLOAT& fx, FX_FLOAT& fy);
+ void SetFocus(FX_BOOL bSet);
+
+ FX_BOOL m_bNotifyOwner;
+
+ friend class CFWL_ComboListImpDelegate;
+ friend class IFWL_ComboBox;
+};
+
+class CFWL_ComboListImpDelegate : public CFWL_ListBoxImpDelegate {
+ public:
+ CFWL_ComboListImpDelegate(IFWL_ComboList* pOwner);
+ void OnProcessMessage(CFWL_Message* pMessage) override;
+
+ protected:
+ void OnDropListFocusChanged(CFWL_Message* pMsg, FX_BOOL bSet = TRUE);
+ int32_t OnDropListMouseMove(CFWL_MsgMouse* pMsg);
+ int32_t OnDropListLButtonDown(CFWL_MsgMouse* pMsg);
+ int32_t OnDropListLButtonUp(CFWL_MsgMouse* pMsg);
+ int32_t OnDropListKey(CFWL_MsgKey* pKey);
+ void OnDropListKeyDown(CFWL_MsgKey* pKey);
+ IFWL_ComboList* m_pOwner;
+};
+
+#endif // XFA_FWL_CORE_IFWL_COMBOLIST_H_
diff --git a/xfa/fwl/core/ifwl_datetimecalendar.cpp b/xfa/fwl/core/ifwl_datetimecalendar.cpp
new file mode 100644
index 0000000000..26d1f17da9
--- /dev/null
+++ b/xfa/fwl/core/ifwl_datetimecalendar.cpp
@@ -0,0 +1,222 @@
+// 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_datetimecalendar.h"
+
+#include "xfa/fwl/core/cfwl_widgetmgr.h"
+#include "xfa/fwl/core/ifwl_datetimepicker.h"
+#include "xfa/fwl/core/ifwl_formproxy.h"
+
+// static
+IFWL_DateTimeCalendar* IFWL_DateTimeCalendar::Create(
+ const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter) {
+ return new IFWL_DateTimeCalendar(properties, pOuter);
+}
+
+IFWL_DateTimeCalendar::IFWL_DateTimeCalendar(
+ const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter)
+ : IFWL_MonthCalendar(properties, pOuter) {}
+
+FWL_Error IFWL_DateTimeCalendar::Initialize() {
+ if (IFWL_MonthCalendar::Initialize() != FWL_Error::Succeeded)
+ return FWL_Error::Indefinite;
+ delete m_pDelegate;
+ m_pDelegate = new CFWL_DateTimeCalendarImpDelegate(this);
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_DateTimeCalendar::Finalize() {
+ delete m_pDelegate;
+ m_pDelegate = nullptr;
+ return IFWL_MonthCalendar::Finalize();
+}
+
+CFWL_DateTimeCalendarImpDelegate::CFWL_DateTimeCalendarImpDelegate(
+ IFWL_DateTimeCalendar* pOwner)
+ : CFWL_MonthCalendarImpDelegate(pOwner), m_pOwner(pOwner) {
+ m_bFlag = FALSE;
+}
+
+void CFWL_DateTimeCalendarImpDelegate::OnProcessMessage(
+ CFWL_Message* pMessage) {
+ CFWL_MessageType dwCode = pMessage->GetClassID();
+ if (dwCode == CFWL_MessageType::SetFocus ||
+ dwCode == CFWL_MessageType::KillFocus) {
+ IFWL_Widget* pOuter = m_pOwner->GetOuter();
+ IFWL_WidgetDelegate* pDelegate = pOuter->SetDelegate(nullptr);
+ pDelegate->OnProcessMessage(pMessage);
+ return;
+ }
+ if (dwCode == CFWL_MessageType::Mouse) {
+ CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage);
+ if (pMsg->m_dwCmd == FWL_MouseCommand::LeftButtonDown)
+ OnLButtonDownEx(pMsg);
+ else if (pMsg->m_dwCmd == FWL_MouseCommand::LeftButtonUp)
+ OnLButtonUpEx(pMsg);
+ return;
+ }
+ CFWL_MonthCalendarImpDelegate::OnProcessMessage(pMessage);
+}
+
+void CFWL_DateTimeCalendarImpDelegate::OnLButtonDownEx(CFWL_MsgMouse* pMsg) {
+ if (m_pOwner->m_rtLBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_iLBtnPartStates = CFWL_PartState_Pressed;
+ m_pOwner->PrevMonth();
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ } else if (m_pOwner->m_rtRBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_iRBtnPartStates |= CFWL_PartState_Pressed;
+ m_pOwner->NextMonth();
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ } else if (m_pOwner->m_rtToday.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ if ((m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_NoToday) ==
+ 0) {
+ m_pOwner->JumpToToday();
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ }
+ } else {
+ IFWL_DateTimePicker* pIPicker =
+ static_cast<IFWL_DateTimePicker*>(m_pOwner->m_pOuter);
+ if (pIPicker->IsMonthCalendarShowed()) {
+ m_bFlag = 1;
+ }
+ }
+}
+
+void CFWL_DateTimeCalendarImpDelegate::OnLButtonUpEx(CFWL_MsgMouse* pMsg) {
+ if (m_pOwner->m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_OnLButtonUpEx(pMsg);
+ }
+ if (m_pOwner->m_rtLBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_iLBtnPartStates = 0;
+ m_pOwner->Repaint(&m_pOwner->m_rtLBtn);
+ return;
+ }
+ if (m_pOwner->m_rtRBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_iRBtnPartStates = 0;
+ m_pOwner->Repaint(&m_pOwner->m_rtRBtn);
+ return;
+ }
+ if (m_pOwner->m_rtToday.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ return;
+ }
+ int32_t iOldSel = 0;
+ if (m_pOwner->m_arrSelDays.GetSize() > 0) {
+ iOldSel = m_pOwner->m_arrSelDays[0];
+ }
+ int32_t iCurSel = m_pOwner->GetDayAtPoint(pMsg->m_fx, pMsg->m_fy);
+ CFX_RectF rt;
+ IFWL_DateTimePicker* pIPicker =
+ static_cast<IFWL_DateTimePicker*>(m_pOwner->m_pOuter);
+ pIPicker->m_pForm->GetWidgetRect(rt);
+ rt.Set(0, 0, rt.width, rt.height);
+ if (iCurSel > 0) {
+ FWL_DATEINFO* lpDatesInfo = m_pOwner->m_arrDates.GetAt(iCurSel - 1);
+ CFX_RectF rtInvalidate(lpDatesInfo->rect);
+ if (iOldSel > 0 && iOldSel <= m_pOwner->m_arrDates.GetSize()) {
+ lpDatesInfo = m_pOwner->m_arrDates.GetAt(iOldSel - 1);
+ rtInvalidate.Union(lpDatesInfo->rect);
+ }
+ m_pOwner->AddSelDay(iCurSel);
+ if (!m_pOwner->m_pOuter)
+ return;
+ pIPicker->ProcessSelChanged(m_pOwner->m_iCurYear, m_pOwner->m_iCurMonth,
+ iCurSel);
+ pIPicker->ShowMonthCalendar(FALSE);
+ } else if (m_bFlag && (!rt.Contains(pMsg->m_fx, pMsg->m_fy))) {
+ pIPicker->ShowMonthCalendar(FALSE);
+ }
+ m_bFlag = 0;
+}
+
+void CFWL_DateTimeCalendarImpDelegate::OnMouseMoveEx(CFWL_MsgMouse* pMsg) {
+ if (m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_MultiSelect) {
+ return;
+ }
+ FX_BOOL bRepaint = FALSE;
+ CFX_RectF rtInvalidate;
+ rtInvalidate.Set(0, 0, 0, 0);
+ if (m_pOwner->m_rtDates.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ int32_t iHover = m_pOwner->GetDayAtPoint(pMsg->m_fx, pMsg->m_fy);
+ bRepaint = m_pOwner->m_iHovered != iHover;
+ if (bRepaint) {
+ if (m_pOwner->m_iHovered > 0) {
+ m_pOwner->GetDayRect(m_pOwner->m_iHovered, rtInvalidate);
+ }
+ if (iHover > 0) {
+ CFX_RectF rtDay;
+ m_pOwner->GetDayRect(iHover, rtDay);
+ if (rtInvalidate.IsEmpty()) {
+ rtInvalidate = rtDay;
+ } else {
+ rtInvalidate.Union(rtDay);
+ }
+ }
+ }
+ m_pOwner->m_iHovered = iHover;
+ CFWL_Event_DtpHoverChanged ev;
+ ev.hoverday = iHover;
+ m_pOwner->DispatchEvent(&ev);
+ } else {
+ bRepaint = m_pOwner->m_iHovered > 0;
+ if (bRepaint) {
+ m_pOwner->GetDayRect(m_pOwner->m_iHovered, rtInvalidate);
+ }
+ m_pOwner->m_iHovered = -1;
+ }
+ if (bRepaint && !rtInvalidate.IsEmpty()) {
+ m_pOwner->Repaint(&rtInvalidate);
+ }
+}
+
+void CFWL_DateTimeCalendarImpDelegate::DisForm_OnProcessMessage(
+ CFWL_Message* pMessage) {
+ if (pMessage->GetClassID() == CFWL_MessageType::Mouse) {
+ CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage);
+ if (pMsg->m_dwCmd == FWL_MouseCommand::LeftButtonUp) {
+ DisForm_OnLButtonUpEx(pMsg);
+ return;
+ }
+ }
+ CFWL_MonthCalendarImpDelegate::OnProcessMessage(pMessage);
+}
+
+void CFWL_DateTimeCalendarImpDelegate::DisForm_OnLButtonUpEx(
+ CFWL_MsgMouse* pMsg) {
+ if (m_pOwner->m_rtLBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_iLBtnPartStates = 0;
+ m_pOwner->Repaint(&(m_pOwner->m_rtLBtn));
+ return;
+ }
+ if (m_pOwner->m_rtRBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_iRBtnPartStates = 0;
+ m_pOwner->Repaint(&(m_pOwner->m_rtRBtn));
+ return;
+ }
+ if (m_pOwner->m_rtToday.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ return;
+ }
+ int32_t iOldSel = 0;
+ if (m_pOwner->m_arrSelDays.GetSize() > 0) {
+ iOldSel = m_pOwner->m_arrSelDays[0];
+ }
+ int32_t iCurSel = m_pOwner->GetDayAtPoint(pMsg->m_fx, pMsg->m_fy);
+ if (iCurSel > 0) {
+ FWL_DATEINFO* lpDatesInfo = m_pOwner->m_arrDates.GetAt(iCurSel - 1);
+ CFX_RectF rtInvalidate(lpDatesInfo->rect);
+ if (iOldSel > 0 && iOldSel <= m_pOwner->m_arrDates.GetSize()) {
+ lpDatesInfo = m_pOwner->m_arrDates.GetAt(iOldSel - 1);
+ rtInvalidate.Union(lpDatesInfo->rect);
+ }
+ m_pOwner->AddSelDay(iCurSel);
+ IFWL_DateTimePicker* pDateTime =
+ static_cast<IFWL_DateTimePicker*>(m_pOwner->m_pOuter);
+ pDateTime->ProcessSelChanged(m_pOwner->m_iCurYear, m_pOwner->m_iCurMonth,
+ iCurSel);
+ pDateTime->ShowMonthCalendar(FALSE);
+ }
+}
diff --git a/xfa/fwl/core/ifwl_datetimecalendar.h b/xfa/fwl/core/ifwl_datetimecalendar.h
new file mode 100644
index 0000000000..3f29a59820
--- /dev/null
+++ b/xfa/fwl/core/ifwl_datetimecalendar.h
@@ -0,0 +1,47 @@
+// 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_DATETIMECALENDAR_H_
+#define XFA_FWL_CORE_IFWL_DATETIMECALENDAR_H_
+
+#include "xfa/fwl/core/ifwl_monthcalendar.h"
+
+class IFWL_DateTimeCalendar : public IFWL_MonthCalendar {
+ public:
+ static IFWL_DateTimeCalendar* Create(
+ const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+
+ IFWL_DateTimeCalendar(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+
+ // IFWL_MonthCalendar
+ FWL_Error Initialize() override;
+ FWL_Error Finalize() override;
+
+ protected:
+ friend class CFWL_DateTimeCalendarImpDelegate;
+};
+
+class CFWL_DateTimeCalendarImpDelegate : public CFWL_MonthCalendarImpDelegate {
+ public:
+ CFWL_DateTimeCalendarImpDelegate(IFWL_DateTimeCalendar* pOwner);
+ void OnProcessMessage(CFWL_Message* pMessage) override;
+
+ void OnLButtonDownEx(CFWL_MsgMouse* pMsg);
+ void OnLButtonUpEx(CFWL_MsgMouse* pMsg);
+ void OnMouseMoveEx(CFWL_MsgMouse* pMsg);
+
+ protected:
+ IFWL_DateTimeCalendar* m_pOwner;
+ FX_BOOL m_bFlag;
+
+ private:
+ void DisForm_OnProcessMessage(CFWL_Message* pMessage);
+ void DisForm_OnLButtonUpEx(CFWL_MsgMouse* pMsg);
+};
+
+#endif // XFA_FWL_CORE_IFWL_DATETIMECALENDAR_H_
diff --git a/xfa/fwl/core/ifwl_datetimeedit.cpp b/xfa/fwl/core/ifwl_datetimeedit.cpp
new file mode 100644
index 0000000000..a0f473b21e
--- /dev/null
+++ b/xfa/fwl/core/ifwl_datetimeedit.cpp
@@ -0,0 +1,79 @@
+// 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_datetimeedit.h"
+
+#include "xfa/fwl/core/cfwl_widgetmgr.h"
+#include "xfa/fwl/core/ifwl_datetimepicker.h"
+
+// static
+IFWL_DateTimeEdit* IFWL_DateTimeEdit::Create(
+ const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter) {
+ return new IFWL_DateTimeEdit(properties, pOuter);
+}
+
+IFWL_DateTimeEdit::IFWL_DateTimeEdit(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter)
+ : IFWL_Edit(properties, pOuter) {}
+
+FWL_Error IFWL_DateTimeEdit::Initialize() {
+ m_pDelegate = new CFWL_DateTimeEditImpDelegate(this);
+ if (IFWL_Edit::Initialize() != FWL_Error::Succeeded)
+ return FWL_Error::Indefinite;
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_DateTimeEdit::Finalize() {
+ delete m_pDelegate;
+ m_pDelegate = nullptr;
+ return IFWL_Edit::Finalize();
+}
+
+CFWL_DateTimeEditImpDelegate::CFWL_DateTimeEditImpDelegate(
+ IFWL_DateTimeEdit* pOwner)
+ : CFWL_EditImpDelegate(pOwner), m_pOwner(pOwner) {}
+
+void CFWL_DateTimeEditImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
+ if (m_pOwner->m_pWidgetMgr->IsFormDisabled()) {
+ DisForm_OnProcessMessage(pMessage);
+ return;
+ }
+
+ CFWL_MessageType dwHashCode = pMessage->GetClassID();
+ if (dwHashCode == CFWL_MessageType::SetFocus ||
+ dwHashCode == CFWL_MessageType::KillFocus) {
+ IFWL_Widget* pOuter = m_pOwner->GetOuter();
+ IFWL_WidgetDelegate* pDelegate = pOuter->SetDelegate(nullptr);
+ pDelegate->OnProcessMessage(pMessage);
+ }
+}
+
+void CFWL_DateTimeEditImpDelegate::DisForm_OnProcessMessage(
+ CFWL_Message* pMessage) {
+ CFWL_MessageType dwHashCode = pMessage->GetClassID();
+ if (m_pOwner->m_pWidgetMgr->IsFormDisabled()) {
+ if (dwHashCode == CFWL_MessageType::Mouse) {
+ CFWL_MsgMouse* pMouse = static_cast<CFWL_MsgMouse*>(pMessage);
+ if (pMouse->m_dwCmd == FWL_MouseCommand::LeftButtonDown ||
+ pMouse->m_dwCmd == FWL_MouseCommand::RightButtonDown) {
+ if ((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) {
+ m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
+ }
+ IFWL_DateTimePicker* pDateTime =
+ static_cast<IFWL_DateTimePicker*>(m_pOwner->m_pOuter);
+ if (pDateTime->IsMonthCalendarShowed()) {
+ CFX_RectF rtInvalidate;
+ pDateTime->GetWidgetRect(rtInvalidate);
+ pDateTime->ShowMonthCalendar(FALSE);
+ rtInvalidate.Offset(-rtInvalidate.left, -rtInvalidate.top);
+ pDateTime->Repaint(&rtInvalidate);
+ }
+ }
+ }
+ }
+ CFWL_EditImpDelegate::OnProcessMessage(pMessage);
+}
diff --git a/xfa/fwl/core/ifwl_datetimeedit.h b/xfa/fwl/core/ifwl_datetimeedit.h
new file mode 100644
index 0000000000..98b1a364b2
--- /dev/null
+++ b/xfa/fwl/core/ifwl_datetimeedit.h
@@ -0,0 +1,44 @@
+// 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_DATETIMEEDIT_H_
+#define XFA_FWL_CORE_IFWL_DATETIMEEDIT_H_
+
+#include "xfa/fwl/core/cfwl_message.h"
+#include "xfa/fwl/core/cfwl_widgetimpproperties.h"
+#include "xfa/fwl/core/fwl_error.h"
+#include "xfa/fwl/core/ifwl_edit.h"
+#include "xfa/fwl/core/ifwl_widget.h"
+
+class IFWL_DateTimeEdit : public IFWL_Edit {
+ public:
+ static IFWL_DateTimeEdit* Create(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+
+ IFWL_DateTimeEdit(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+
+ // IFWL_Edit
+ FWL_Error Initialize() override;
+ FWL_Error Finalize() override;
+
+ protected:
+ friend class CFWL_DateTimeEditImpDelegate;
+};
+
+class CFWL_DateTimeEditImpDelegate : public CFWL_EditImpDelegate {
+ public:
+ CFWL_DateTimeEditImpDelegate(IFWL_DateTimeEdit* pOwner);
+ void OnProcessMessage(CFWL_Message* pMessage) override;
+
+ protected:
+ IFWL_DateTimeEdit* m_pOwner;
+
+ private:
+ void DisForm_OnProcessMessage(CFWL_Message* pMessage);
+};
+
+#endif // XFA_FWL_CORE_IFWL_DATETIMEEDIT_H_
diff --git a/xfa/fwl/core/ifwl_datetimepicker.cpp b/xfa/fwl/core/ifwl_datetimepicker.cpp
new file mode 100644
index 0000000000..ce5f28bf08
--- /dev/null
+++ b/xfa/fwl/core/ifwl_datetimepicker.cpp
@@ -0,0 +1,873 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fwl/core/ifwl_datetimepicker.h"
+
+#include "xfa/fwl/core/cfwl_message.h"
+#include "xfa/fwl/core/cfwl_themebackground.h"
+#include "xfa/fwl/core/cfwl_widgetmgr.h"
+#include "xfa/fwl/core/fwl_noteimp.h"
+#include "xfa/fwl/core/ifwl_datetimecalendar.h"
+#include "xfa/fwl/core/ifwl_datetimeedit.h"
+#include "xfa/fwl/core/ifwl_formproxy.h"
+#include "xfa/fwl/core/ifwl_spinbutton.h"
+#include "xfa/fwl/core/ifwl_themeprovider.h"
+
+namespace {
+
+const int kDateTimePickerWidth = 100;
+const int kDateTimePickerHeight = 20;
+
+} // namespace
+
+// static
+IFWL_DateTimePicker* IFWL_DateTimePicker::Create(
+ const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter) {
+ return new IFWL_DateTimePicker(properties, pOuter);
+}
+
+IFWL_DateTimePicker::IFWL_DateTimePicker(
+ const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter)
+ : IFWL_Widget(properties, pOuter),
+ m_iBtnState(1),
+ m_iYear(-1),
+ m_iMonth(-1),
+ m_iDay(-1),
+ m_bLBtnDown(FALSE) {
+ m_rtBtn.Set(0, 0, 0, 0);
+}
+
+IFWL_DateTimePicker::~IFWL_DateTimePicker() {}
+
+FWL_Error IFWL_DateTimePicker::GetClassName(CFX_WideString& wsClass) const {
+ wsClass = FWL_CLASS_DateTimePicker;
+ return FWL_Error::Succeeded;
+}
+
+FWL_Type IFWL_DateTimePicker::GetClassID() const {
+ return FWL_Type::DateTimePicker;
+}
+
+FWL_Error IFWL_DateTimePicker::Initialize() {
+ if (IFWL_Widget::Initialize() != FWL_Error::Succeeded)
+ return FWL_Error::Indefinite;
+
+ m_pDelegate = new CFWL_DateTimePickerImpDelegate(this);
+ m_pProperties->m_dwStyleExes = FWL_STYLEEXT_DTP_ShortDateFormat;
+ CFWL_WidgetImpProperties propMonth;
+ propMonth.m_dwStyles = FWL_WGTSTYLE_Popup | FWL_WGTSTYLE_Border;
+ propMonth.m_dwStates = FWL_WGTSTATE_Invisible;
+ propMonth.m_pDataProvider = &m_MonthCalendarDP;
+ propMonth.m_pParent = this;
+ propMonth.m_pThemeProvider = m_pProperties->m_pThemeProvider;
+ m_pMonthCal.reset(IFWL_DateTimeCalendar::Create(propMonth, this));
+ m_pMonthCal->Initialize();
+ CFX_RectF rtMonthCal;
+ m_pMonthCal->GetWidgetRect(rtMonthCal, TRUE);
+ rtMonthCal.Set(0, 0, rtMonthCal.width, rtMonthCal.height);
+ m_pMonthCal->SetWidgetRect(rtMonthCal);
+ CFWL_WidgetImpProperties propEdit;
+ propEdit.m_pParent = this;
+ propEdit.m_pThemeProvider = m_pProperties->m_pThemeProvider;
+ m_pEdit.reset(IFWL_DateTimeEdit::Create(propEdit, this));
+ m_pEdit->Initialize();
+ RegisterEventTarget(m_pMonthCal.get());
+ RegisterEventTarget(m_pEdit.get());
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_DateTimePicker::Finalize() {
+ if (m_pEdit) {
+ m_pEdit->Finalize();
+ }
+ if (m_pMonthCal) {
+ m_pMonthCal->Finalize();
+ }
+ if (m_pForm) {
+ m_pForm->Finalize();
+ }
+ UnregisterEventTarget();
+ delete m_pDelegate;
+ m_pDelegate = nullptr;
+ return IFWL_Widget::Finalize();
+}
+
+FWL_Error IFWL_DateTimePicker::GetWidgetRect(CFX_RectF& rect,
+ FX_BOOL bAutoSize) {
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_GetWidgetRect(rect, bAutoSize);
+ }
+ if (bAutoSize) {
+ rect.Set(0, 0, kDateTimePickerWidth, kDateTimePickerHeight);
+ IFWL_Widget::GetWidgetRect(rect, TRUE);
+ } else {
+ rect = m_pProperties->m_rtWidget;
+ }
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_DateTimePicker::Update() {
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_Update();
+ }
+ if (m_iLock) {
+ return FWL_Error::Indefinite;
+ }
+ if (!m_pProperties->m_pThemeProvider) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ m_pEdit->SetThemeProvider(m_pProperties->m_pThemeProvider);
+ GetClientRect(m_rtClient);
+ FX_FLOAT* pFWidth = static_cast<FX_FLOAT*>(
+ GetThemeCapacity(CFWL_WidgetCapacity::ScrollBarWidth));
+ if (!pFWidth)
+ return FWL_Error::Indefinite;
+ FX_FLOAT fBtn = *pFWidth;
+ m_rtBtn.Set(m_rtClient.right() - fBtn, m_rtClient.top, fBtn - 1,
+ m_rtClient.height - 1);
+ CFX_RectF rtEdit;
+ rtEdit.Set(m_rtClient.left, m_rtClient.top, m_rtClient.width - fBtn,
+ m_rtClient.height);
+ m_pEdit->SetWidgetRect(rtEdit);
+ ReSetEditAlignment();
+ m_pEdit->Update();
+ if (!(m_pMonthCal->GetThemeProvider())) {
+ m_pMonthCal->SetThemeProvider(m_pProperties->m_pThemeProvider);
+ }
+ if (m_pProperties->m_pDataProvider) {
+ IFWL_DateTimePickerDP* pData =
+ static_cast<IFWL_DateTimePickerDP*>(m_pProperties->m_pDataProvider);
+ pData->GetToday(this, m_MonthCalendarDP.m_iCurYear,
+ m_MonthCalendarDP.m_iCurMonth, m_MonthCalendarDP.m_iCurDay);
+ }
+ CFX_RectF rtMonthCal;
+ m_pMonthCal->GetWidgetRect(rtMonthCal, TRUE);
+ CFX_RectF rtPopUp;
+ rtPopUp.Set(rtMonthCal.left, rtMonthCal.top + kDateTimePickerHeight,
+ rtMonthCal.width, rtMonthCal.height);
+ m_pMonthCal->SetWidgetRect(rtPopUp);
+ m_pMonthCal->Update();
+ return FWL_Error::Succeeded;
+}
+
+int32_t IFWL_DateTimePicker::CountSelRanges() {
+ return GetDataTimeEdit()->CountSelRanges();
+}
+
+int32_t IFWL_DateTimePicker::GetSelRange(int32_t nIndex, int32_t& nStart) {
+ return GetDataTimeEdit()->GetSelRange(nIndex, nStart);
+}
+
+FWL_WidgetHit IFWL_DateTimePicker::HitTest(FX_FLOAT fx, FX_FLOAT fy) {
+ if (m_pWidgetMgr->IsFormDisabled())
+ return DisForm_HitTest(fx, fy);
+ if (m_rtClient.Contains(fx, fy))
+ return FWL_WidgetHit::Client;
+ if (IsMonthCalendarShowed()) {
+ CFX_RectF rect;
+ m_pMonthCal->GetWidgetRect(rect);
+ if (rect.Contains(fx, fy))
+ return FWL_WidgetHit::Client;
+ }
+ return FWL_WidgetHit::Unknown;
+}
+
+FWL_Error IFWL_DateTimePicker::DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ if (!pGraphics)
+ return FWL_Error::Indefinite;
+ if (!m_pProperties->m_pThemeProvider)
+ return FWL_Error::Indefinite;
+ IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
+ if (HasBorder()) {
+ DrawBorder(pGraphics, CFWL_Part::Border, pTheme, pMatrix);
+ }
+ if (HasEdge()) {
+ DrawEdge(pGraphics, CFWL_Part::Edge, pTheme, pMatrix);
+ }
+ if (!m_rtBtn.IsEmpty()) {
+ DrawDropDownButton(pGraphics, pTheme, pMatrix);
+ }
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_DrawWidget(pGraphics, pMatrix);
+ }
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_DateTimePicker::SetThemeProvider(IFWL_ThemeProvider* pTP) {
+ m_pProperties->m_pThemeProvider = pTP;
+ m_pMonthCal->SetThemeProvider(pTP);
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_DateTimePicker::GetCurSel(int32_t& iYear,
+ int32_t& iMonth,
+ int32_t& iDay) {
+ iYear = m_iYear;
+ iMonth = m_iMonth;
+ iDay = m_iDay;
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_DateTimePicker::SetCurSel(int32_t iYear,
+ int32_t iMonth,
+ int32_t iDay) {
+ if (iYear <= 0 || iYear >= 3000)
+ return FWL_Error::Indefinite;
+ if (iMonth <= 0 || iMonth >= 13)
+ return FWL_Error::Indefinite;
+ if (iDay <= 0 || iDay >= 32)
+ return FWL_Error::Indefinite;
+ m_iYear = iYear;
+ m_iMonth = iMonth;
+ m_iDay = iDay;
+ m_pMonthCal->SetSelect(iYear, iMonth, iDay);
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_DateTimePicker::SetEditText(const CFX_WideString& wsText) {
+ if (!m_pEdit)
+ return FWL_Error::Indefinite;
+
+ FWL_Error iRet = m_pEdit->SetText(wsText);
+ Repaint(&m_rtClient);
+ CFWL_Event_DtpEditChanged ev;
+ ev.m_wsText = wsText;
+ DispatchEvent(&ev);
+ return iRet;
+}
+
+FWL_Error IFWL_DateTimePicker::GetEditText(CFX_WideString& wsText,
+ int32_t nStart,
+ int32_t nCount) const {
+ if (m_pEdit) {
+ return m_pEdit->GetText(wsText, nStart, nCount);
+ }
+ return FWL_Error::Indefinite;
+}
+
+FX_BOOL IFWL_DateTimePicker::CanUndo() {
+ return m_pEdit->CanUndo();
+}
+
+FX_BOOL IFWL_DateTimePicker::CanRedo() {
+ return m_pEdit->CanRedo();
+}
+
+FX_BOOL IFWL_DateTimePicker::Undo() {
+ return m_pEdit->Undo();
+}
+
+FX_BOOL IFWL_DateTimePicker::Redo() {
+ return m_pEdit->Redo();
+}
+
+FX_BOOL IFWL_DateTimePicker::CanCopy() {
+ int32_t nCount = m_pEdit->CountSelRanges();
+ return nCount > 0;
+}
+
+FX_BOOL IFWL_DateTimePicker::CanCut() {
+ if (m_pEdit->GetStylesEx() & FWL_STYLEEXT_EDT_ReadOnly) {
+ return FALSE;
+ }
+ int32_t nCount = m_pEdit->CountSelRanges();
+ return nCount > 0;
+}
+
+FX_BOOL IFWL_DateTimePicker::CanSelectAll() {
+ return m_pEdit->GetTextLength() > 0;
+}
+
+FX_BOOL IFWL_DateTimePicker::Copy(CFX_WideString& wsCopy) {
+ return m_pEdit->Copy(wsCopy);
+}
+
+FX_BOOL IFWL_DateTimePicker::Cut(CFX_WideString& wsCut) {
+ return m_pEdit->Cut(wsCut);
+}
+
+FX_BOOL IFWL_DateTimePicker::Paste(const CFX_WideString& wsPaste) {
+ return m_pEdit->Paste(wsPaste);
+}
+
+FX_BOOL IFWL_DateTimePicker::SelectAll() {
+ return m_pEdit->AddSelRange(0) == FWL_Error::Succeeded;
+}
+
+FX_BOOL IFWL_DateTimePicker::Delete() {
+ return m_pEdit->ClearText() == FWL_Error::Succeeded;
+}
+
+FX_BOOL IFWL_DateTimePicker::DeSelect() {
+ return m_pEdit->ClearSelections() == FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_DateTimePicker::GetBBox(CFX_RectF& rect) {
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_GetBBox(rect);
+ }
+ rect = m_pProperties->m_rtWidget;
+ if (IsMonthCalendarShowed()) {
+ CFX_RectF rtMonth;
+ m_pMonthCal->GetWidgetRect(rtMonth);
+ rtMonth.Offset(m_pProperties->m_rtWidget.left,
+ m_pProperties->m_rtWidget.top);
+ rect.Union(rtMonth);
+ }
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_DateTimePicker::SetEditLimit(int32_t nLimit) {
+ return m_pEdit->SetLimit(nLimit);
+}
+
+FWL_Error IFWL_DateTimePicker::ModifyEditStylesEx(uint32_t dwStylesExAdded,
+ uint32_t dwStylesExRemoved) {
+ return m_pEdit->ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
+}
+
+void IFWL_DateTimePicker::DrawDropDownButton(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix) {
+ if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_Spin) ==
+ FWL_STYLEEXT_DTP_Spin) {
+ CFWL_WidgetImpProperties prop;
+ prop.m_dwStyleExes |= FWL_STYLEEXE_SPB_Vert;
+ prop.m_pParent = this;
+ prop.m_rtWidget = m_rtBtn;
+ IFWL_SpinButton* pSpin = IFWL_SpinButton::Create(prop, this);
+ pSpin->Initialize();
+ } else {
+ CFWL_ThemeBackground param;
+ param.m_pWidget = this;
+ param.m_iPart = CFWL_Part::DropDownButton;
+ param.m_dwStates = m_iBtnState;
+ param.m_pGraphics = pGraphics;
+ param.m_rtPart = m_rtBtn;
+ if (pMatrix) {
+ param.m_matrix.Concat(*pMatrix);
+ }
+ pTheme->DrawBackground(&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);
+ } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_TimeFormat) ==
+ FWL_STYLEEXT_DTP_TimeFormat) {
+ }
+}
+
+void IFWL_DateTimePicker::ShowMonthCalendar(FX_BOOL bActivate) {
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_ShowMonthCalendar(bActivate);
+ }
+ if (IsMonthCalendarShowed() == bActivate) {
+ return;
+ }
+ if (!m_pForm) {
+ InitProxyForm();
+ }
+ if (bActivate) {
+ CFX_RectF rtMonth;
+ m_pMonthCal->GetWidgetRect(rtMonth);
+ CFX_RectF rtAnchor;
+ rtAnchor.Set(0, 0, m_pProperties->m_rtWidget.width,
+ m_pProperties->m_rtWidget.height);
+ GetPopupPos(0, rtMonth.height, rtAnchor, rtMonth);
+ m_pForm->SetWidgetRect(rtMonth);
+ rtMonth.left = rtMonth.top = 0;
+ m_pMonthCal->SetStates(FWL_WGTSTATE_Invisible, !bActivate);
+ m_pMonthCal->SetWidgetRect(rtMonth);
+ m_pMonthCal->Update();
+ m_pForm->DoModal();
+ } else {
+ m_pForm->EndDoModal();
+ }
+}
+
+FX_BOOL IFWL_DateTimePicker::IsMonthCalendarShowed() {
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_IsMonthCalendarShowed();
+ }
+ if (!m_pForm)
+ return FALSE;
+ return !(m_pForm->GetStates() & FWL_WGTSTATE_Invisible);
+}
+
+void IFWL_DateTimePicker::ReSetEditAlignment() {
+ if (!m_pEdit)
+ return;
+ uint32_t dwStylExes = m_pProperties->m_dwStyleExes;
+ uint32_t dwAdd = 0;
+ switch (dwStylExes & FWL_STYLEEXT_DTP_EditHAlignMask) {
+ case FWL_STYLEEXT_DTP_EditHCenter: {
+ dwAdd |= FWL_STYLEEXT_EDT_HCenter;
+ break;
+ }
+ case FWL_STYLEEXT_DTP_EditHFar: {
+ dwAdd |= FWL_STYLEEXT_EDT_HFar;
+ break;
+ }
+ default: { dwAdd |= FWL_STYLEEXT_EDT_HNear; }
+ }
+ switch (dwStylExes & FWL_STYLEEXT_DTP_EditVAlignMask) {
+ case FWL_STYLEEXT_DTP_EditVCenter: {
+ dwAdd |= FWL_STYLEEXT_EDT_VCenter;
+ break;
+ }
+ case FWL_STYLEEXT_DTP_EditVFar: {
+ dwAdd |= FWL_STYLEEXT_EDT_VFar;
+ break;
+ }
+ default: { dwAdd |= FWL_STYLEEXT_EDT_VNear; }
+ }
+ if (dwStylExes & FWL_STYLEEXT_DTP_EditJustified) {
+ dwAdd |= FWL_STYLEEXT_EDT_Justified;
+ }
+ if (dwStylExes & FWL_STYLEEXT_DTP_EditDistributed) {
+ dwAdd |= FWL_STYLEEXT_EDT_Distributed;
+ }
+ m_pEdit->ModifyStylesEx(dwAdd, FWL_STYLEEXT_EDT_HAlignMask |
+ FWL_STYLEEXT_EDT_HAlignModeMask |
+ FWL_STYLEEXT_EDT_VAlignMask);
+}
+
+void IFWL_DateTimePicker::ProcessSelChanged(int32_t iYear,
+ int32_t iMonth,
+ int32_t iDay) {
+ m_iYear = iYear;
+ m_iMonth = iMonth;
+ m_iDay = iDay;
+ CFX_WideString wsText;
+ FormatDateString(m_iYear, m_iMonth, m_iDay, wsText);
+ m_pEdit->SetText(wsText);
+ m_pEdit->Update();
+ Repaint(&m_rtClient);
+ CFWL_Event_DtpSelectChanged ev;
+ ev.m_pSrcTarget = this;
+ ev.iYear = m_iYear;
+ ev.iMonth = m_iMonth;
+ ev.iDay = m_iDay;
+ DispatchEvent(&ev);
+}
+
+void IFWL_DateTimePicker::InitProxyForm() {
+ if (m_pForm)
+ return;
+ if (!m_pMonthCal)
+ return;
+ CFWL_WidgetImpProperties propForm;
+ propForm.m_dwStyles = FWL_WGTSTYLE_Popup;
+ propForm.m_dwStates = FWL_WGTSTATE_Invisible;
+ propForm.m_pOwner = this;
+ m_pForm.reset(IFWL_FormProxy::Create(propForm, m_pMonthCal.get()));
+ m_pForm->Initialize();
+ m_pMonthCal->SetParent(m_pForm.get());
+}
+
+IFWL_DateTimeEdit* IFWL_DateTimePicker::GetDataTimeEdit() {
+ return m_pEdit.get();
+}
+
+FWL_Error IFWL_DateTimePicker::DisForm_Initialize() {
+ m_pProperties->m_dwStyleExes = FWL_STYLEEXT_DTP_ShortDateFormat;
+ DisForm_InitDateTimeCalendar();
+ DisForm_InitDateTimeEdit();
+ RegisterEventTarget(m_pMonthCal.get());
+ RegisterEventTarget(m_pEdit.get());
+ return FWL_Error::Succeeded;
+}
+
+void IFWL_DateTimePicker::DisForm_InitDateTimeCalendar() {
+ if (m_pMonthCal) {
+ return;
+ }
+ CFWL_WidgetImpProperties propMonth;
+ propMonth.m_dwStyles =
+ FWL_WGTSTYLE_Popup | FWL_WGTSTYLE_Border | FWL_WGTSTYLE_EdgeSunken;
+ propMonth.m_dwStates = FWL_WGTSTATE_Invisible;
+ propMonth.m_pParent = this;
+ propMonth.m_pDataProvider = &m_MonthCalendarDP;
+ propMonth.m_pThemeProvider = m_pProperties->m_pThemeProvider;
+ m_pMonthCal.reset(IFWL_DateTimeCalendar::Create(propMonth, this));
+ m_pMonthCal->Initialize();
+ CFX_RectF rtMonthCal;
+ m_pMonthCal->GetWidgetRect(rtMonthCal, TRUE);
+ rtMonthCal.Set(0, 0, rtMonthCal.width, rtMonthCal.height);
+ m_pMonthCal->SetWidgetRect(rtMonthCal);
+}
+
+void IFWL_DateTimePicker::DisForm_InitDateTimeEdit() {
+ if (m_pEdit) {
+ return;
+ }
+ CFWL_WidgetImpProperties propEdit;
+ propEdit.m_pParent = this;
+ propEdit.m_pThemeProvider = m_pProperties->m_pThemeProvider;
+ m_pEdit.reset(IFWL_DateTimeEdit::Create(propEdit, this));
+ m_pEdit->Initialize();
+}
+
+FX_BOOL IFWL_DateTimePicker::DisForm_IsMonthCalendarShowed() {
+ if (!m_pMonthCal)
+ return FALSE;
+ return !(m_pMonthCal->GetStates() & FWL_WGTSTATE_Invisible);
+}
+
+void IFWL_DateTimePicker::DisForm_ShowMonthCalendar(FX_BOOL bActivate) {
+ FX_BOOL bShowed = IsMonthCalendarShowed();
+ if (bShowed == bActivate) {
+ return;
+ }
+ if (bActivate) {
+ CFX_RectF rtMonthCal;
+ m_pMonthCal->GetWidgetRect(rtMonthCal, TRUE);
+ FX_FLOAT fPopupMin = rtMonthCal.height;
+ FX_FLOAT fPopupMax = rtMonthCal.height;
+ CFX_RectF rtAnchor(m_pProperties->m_rtWidget);
+ rtAnchor.width = rtMonthCal.width;
+ rtMonthCal.left = m_rtClient.left;
+ rtMonthCal.top = rtAnchor.Height();
+ GetPopupPos(fPopupMin, fPopupMax, rtAnchor, rtMonthCal);
+ m_pMonthCal->SetWidgetRect(rtMonthCal);
+ if (m_iYear > 0 && m_iMonth > 0 && m_iDay > 0) {
+ m_pMonthCal->SetSelect(m_iYear, m_iMonth, m_iDay);
+ }
+ m_pMonthCal->Update();
+ }
+ m_pMonthCal->SetStates(FWL_WGTSTATE_Invisible, !bActivate);
+ if (bActivate) {
+ CFWL_MsgSetFocus msg;
+ msg.m_pDstTarget = m_pMonthCal.get();
+ msg.m_pSrcTarget = m_pEdit.get();
+ IFWL_WidgetDelegate* pDelegate = m_pEdit->SetDelegate(nullptr);
+ pDelegate->OnProcessMessage(&msg);
+ }
+ CFX_RectF rtInvalidate, rtCal;
+ rtInvalidate.Set(0, 0, m_pProperties->m_rtWidget.width,
+ m_pProperties->m_rtWidget.height);
+ m_pMonthCal->GetWidgetRect(rtCal);
+ rtInvalidate.Union(rtCal);
+ rtInvalidate.Inflate(2, 2);
+ Repaint(&rtInvalidate);
+}
+
+FWL_WidgetHit IFWL_DateTimePicker::DisForm_HitTest(FX_FLOAT fx, FX_FLOAT fy) {
+ CFX_RectF rect;
+ rect.Set(0, 0, m_pProperties->m_rtWidget.width,
+ m_pProperties->m_rtWidget.height);
+ if (rect.Contains(fx, fy))
+ return FWL_WidgetHit::Edit;
+ if (DisForm_IsNeedShowButton())
+ rect.width += m_fBtn;
+ if (rect.Contains(fx, fy))
+ return FWL_WidgetHit::Client;
+ if (IsMonthCalendarShowed()) {
+ m_pMonthCal->GetWidgetRect(rect);
+ if (rect.Contains(fx, fy))
+ return FWL_WidgetHit::Client;
+ }
+ return FWL_WidgetHit::Unknown;
+}
+
+FX_BOOL IFWL_DateTimePicker::DisForm_IsNeedShowButton() {
+ FX_BOOL bFocus = m_pProperties->m_dwStates & FWL_WGTSTATE_Focused ||
+ m_pMonthCal->GetStates() & FWL_WGTSTATE_Focused ||
+ m_pEdit->GetStates() & FWL_WGTSTATE_Focused;
+ return bFocus;
+}
+
+FWL_Error IFWL_DateTimePicker::DisForm_Update() {
+ if (m_iLock)
+ return FWL_Error::Indefinite;
+ if (!m_pProperties->m_pThemeProvider)
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+
+ m_pEdit->SetThemeProvider(m_pProperties->m_pThemeProvider);
+ GetClientRect(m_rtClient);
+ m_pEdit->SetWidgetRect(m_rtClient);
+ ReSetEditAlignment();
+ m_pEdit->Update();
+ if (!m_pMonthCal->GetThemeProvider())
+ m_pMonthCal->SetThemeProvider(m_pProperties->m_pThemeProvider);
+
+ if (m_pProperties->m_pDataProvider) {
+ IFWL_DateTimePickerDP* pData =
+ static_cast<IFWL_DateTimePickerDP*>(m_pProperties->m_pDataProvider);
+ pData->GetToday(this, m_MonthCalendarDP.m_iCurYear,
+ m_MonthCalendarDP.m_iCurMonth, m_MonthCalendarDP.m_iCurDay);
+ }
+ FX_FLOAT* pWidth = static_cast<FX_FLOAT*>(
+ GetThemeCapacity(CFWL_WidgetCapacity::ScrollBarWidth));
+ if (!pWidth)
+ return FWL_Error::Succeeded;
+
+ m_fBtn = *pWidth;
+ CFX_RectF rtMonthCal;
+ m_pMonthCal->GetWidgetRect(rtMonthCal, TRUE);
+ CFX_RectF rtPopUp;
+ rtPopUp.Set(rtMonthCal.left, rtMonthCal.top + kDateTimePickerHeight,
+ rtMonthCal.width, rtMonthCal.height);
+ m_pMonthCal->SetWidgetRect(rtPopUp);
+ m_pMonthCal->Update();
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_DateTimePicker::DisForm_GetWidgetRect(CFX_RectF& rect,
+ FX_BOOL bAutoSize) {
+ rect = m_pProperties->m_rtWidget;
+ if (DisForm_IsNeedShowButton()) {
+ rect.width += m_fBtn;
+ }
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_DateTimePicker::DisForm_GetBBox(CFX_RectF& rect) {
+ rect = m_pProperties->m_rtWidget;
+ if (DisForm_IsNeedShowButton()) {
+ rect.width += m_fBtn;
+ }
+ if (IsMonthCalendarShowed()) {
+ CFX_RectF rtMonth;
+ m_pMonthCal->GetWidgetRect(rtMonth);
+ rtMonth.Offset(m_pProperties->m_rtWidget.left,
+ m_pProperties->m_rtWidget.top);
+ rect.Union(rtMonth);
+ }
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_DateTimePicker::DisForm_DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ if (!pGraphics)
+ return FWL_Error::Indefinite;
+ if (m_pEdit) {
+ CFX_RectF rtEdit;
+ m_pEdit->GetWidgetRect(rtEdit);
+ CFX_Matrix mt;
+ mt.Set(1, 0, 0, 1, rtEdit.left, rtEdit.top);
+ if (pMatrix) {
+ mt.Concat(*pMatrix);
+ }
+ m_pEdit->DrawWidget(pGraphics, &mt);
+ }
+ if (IsMonthCalendarShowed()) {
+ CFX_RectF rtMonth;
+ m_pMonthCal->GetWidgetRect(rtMonth);
+ CFX_Matrix mt;
+ mt.Set(1, 0, 0, 1, rtMonth.left, rtMonth.top);
+ if (pMatrix) {
+ mt.Concat(*pMatrix);
+ }
+ m_pMonthCal->DrawWidget(pGraphics, &mt);
+ }
+ return FWL_Error::Succeeded;
+}
+
+CFWL_DateTimePickerImpDelegate::CFWL_DateTimePickerImpDelegate(
+ IFWL_DateTimePicker* pOwner)
+ : m_pOwner(pOwner) {}
+
+void CFWL_DateTimePickerImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
+ if (!pMessage)
+ return;
+
+ switch (pMessage->GetClassID()) {
+ case CFWL_MessageType::SetFocus: {
+ OnFocusChanged(pMessage, TRUE);
+ break;
+ }
+ case CFWL_MessageType::KillFocus: {
+ OnFocusChanged(pMessage, FALSE);
+ break;
+ }
+ case CFWL_MessageType::Mouse: {
+ CFWL_MsgMouse* pMouse = static_cast<CFWL_MsgMouse*>(pMessage);
+ switch (pMouse->m_dwCmd) {
+ case FWL_MouseCommand::LeftButtonDown: {
+ OnLButtonDown(pMouse);
+ break;
+ }
+ case FWL_MouseCommand::LeftButtonUp: {
+ OnLButtonUp(pMouse);
+ break;
+ }
+ case FWL_MouseCommand::Move: {
+ OnMouseMove(pMouse);
+ break;
+ }
+ case FWL_MouseCommand::Leave: {
+ OnMouseLeave(pMouse);
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+ }
+ case CFWL_MessageType::Key: {
+ if (m_pOwner->m_pEdit->GetStates() & FWL_WGTSTATE_Focused) {
+ IFWL_WidgetDelegate* pDelegate =
+ m_pOwner->m_pEdit->SetDelegate(nullptr);
+ pDelegate->OnProcessMessage(pMessage);
+ return;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);
+}
+
+void CFWL_DateTimePickerImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ m_pOwner->DrawWidget(pGraphics, pMatrix);
+}
+
+void CFWL_DateTimePickerImpDelegate::OnFocusChanged(CFWL_Message* pMsg,
+ FX_BOOL bSet) {
+ if (!pMsg)
+ return;
+ if (m_pOwner->m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_OnFocusChanged(pMsg, bSet);
+ }
+ if (bSet) {
+ m_pOwner->m_pProperties->m_dwStates |= (FWL_WGTSTATE_Focused);
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ } else {
+ m_pOwner->m_pProperties->m_dwStates &= ~(FWL_WGTSTATE_Focused);
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ }
+ if (pMsg->m_pSrcTarget == m_pOwner->m_pMonthCal.get() &&
+ m_pOwner->IsMonthCalendarShowed()) {
+ m_pOwner->ShowMonthCalendar(FALSE);
+ }
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+}
+
+void CFWL_DateTimePickerImpDelegate::OnLButtonDown(CFWL_MsgMouse* pMsg) {
+ if (!pMsg)
+ return;
+ if ((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) {
+ m_pOwner->SetFocus(TRUE);
+ }
+ if (m_pOwner->m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ if (m_pOwner->IsMonthCalendarShowed()) {
+ m_pOwner->ShowMonthCalendar(FALSE);
+ CFWL_Event_DtpCloseUp ev;
+ m_pOwner->DispatchEvent(&ev);
+ } else {
+ if (!(m_pOwner->m_pProperties->m_dwStyleExes &
+ FWL_STYLEEXT_DTP_TimeFormat)) {
+ m_pOwner->ShowMonthCalendar(TRUE);
+ CFWL_Event_DtpDropDown ev;
+ m_pOwner->DispatchEvent(&ev);
+ } else {
+ }
+ m_pOwner->m_bLBtnDown = TRUE;
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ }
+ }
+}
+
+void CFWL_DateTimePickerImpDelegate::OnLButtonUp(CFWL_MsgMouse* pMsg) {
+ if (!pMsg)
+ return;
+ m_pOwner->m_bLBtnDown = FALSE;
+ if (m_pOwner->m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_iBtnState = CFWL_PartState_Hovered;
+ } else {
+ m_pOwner->m_iBtnState = CFWL_PartState_Normal;
+ }
+ m_pOwner->Repaint(&m_pOwner->m_rtBtn);
+}
+
+void CFWL_DateTimePickerImpDelegate::OnMouseMove(CFWL_MsgMouse* pMsg) {
+ if (m_pOwner->m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ } else {
+ m_pOwner->m_iBtnState = CFWL_PartState_Normal;
+ }
+ m_pOwner->Repaint(&m_pOwner->m_rtBtn);
+}
+
+void CFWL_DateTimePickerImpDelegate::OnMouseLeave(CFWL_MsgMouse* pMsg) {
+ if (!pMsg)
+ return;
+ m_pOwner->m_iBtnState = CFWL_PartState_Normal;
+ m_pOwner->Repaint(&m_pOwner->m_rtBtn);
+}
+
+void CFWL_DateTimePickerImpDelegate::DisForm_OnFocusChanged(CFWL_Message* pMsg,
+ FX_BOOL bSet) {
+ CFX_RectF rtInvalidate(m_pOwner->m_rtBtn);
+ if (bSet) {
+ m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
+ if (m_pOwner->m_pEdit &&
+ !(m_pOwner->m_pEdit->GetStylesEx() & FWL_STYLEEXT_EDT_ReadOnly)) {
+ m_pOwner->m_rtBtn.Set(m_pOwner->m_pProperties->m_rtWidget.width, 0,
+ m_pOwner->m_fBtn,
+ m_pOwner->m_pProperties->m_rtWidget.height - 1);
+ }
+ rtInvalidate = m_pOwner->m_rtBtn;
+ pMsg->m_pDstTarget = m_pOwner->m_pEdit.get();
+ IFWL_WidgetDelegate* pDelegate = m_pOwner->m_pEdit->SetDelegate(nullptr);
+ pDelegate->OnProcessMessage(pMsg);
+ } else {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
+ m_pOwner->m_rtBtn.Set(0, 0, 0, 0);
+ if (m_pOwner->DisForm_IsMonthCalendarShowed()) {
+ m_pOwner->ShowMonthCalendar(FALSE);
+ }
+ if (m_pOwner->m_pEdit->GetStates() & FWL_WGTSTATE_Focused) {
+ pMsg->m_pSrcTarget = m_pOwner->m_pEdit.get();
+ IFWL_WidgetDelegate* pDelegate = m_pOwner->m_pEdit->SetDelegate(nullptr);
+ pDelegate->OnProcessMessage(pMsg);
+ }
+ }
+ rtInvalidate.Inflate(2, 2);
+ m_pOwner->Repaint(&rtInvalidate);
+}
+
+IFWL_DateTimePicker::CFWL_MonthCalendarImpDP::CFWL_MonthCalendarImpDP() {
+ m_iCurYear = 2010;
+ m_iCurMonth = 3;
+ m_iCurDay = 29;
+}
+
+FWL_Error IFWL_DateTimePicker::CFWL_MonthCalendarImpDP::GetCaption(
+ IFWL_Widget* pWidget,
+ CFX_WideString& wsCaption) {
+ return FWL_Error::Succeeded;
+}
+
+int32_t IFWL_DateTimePicker::CFWL_MonthCalendarImpDP::GetCurDay(
+ IFWL_Widget* pWidget) {
+ return m_iCurDay;
+}
+
+int32_t IFWL_DateTimePicker::CFWL_MonthCalendarImpDP::GetCurMonth(
+ IFWL_Widget* pWidget) {
+ return m_iCurMonth;
+}
+
+int32_t IFWL_DateTimePicker::CFWL_MonthCalendarImpDP::GetCurYear(
+ IFWL_Widget* pWidget) {
+ return m_iCurYear;
+}
diff --git a/xfa/fwl/core/ifwl_datetimepicker.h b/xfa/fwl/core/ifwl_datetimepicker.h
new file mode 100644
index 0000000000..e14073df09
--- /dev/null
+++ b/xfa/fwl/core/ifwl_datetimepicker.h
@@ -0,0 +1,200 @@
+// 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 "xfa/fwl/core/cfwl_event.h"
+#include "xfa/fwl/core/cfwl_widgetimpproperties.h"
+#include "xfa/fwl/core/ifwl_dataprovider.h"
+#include "xfa/fwl/core/ifwl_monthcalendar.h"
+#include "xfa/fwl/core/ifwl_widget.h"
+
+#define FWL_CLASS_DateTimePicker L"FWL_DATETIMEPICKER"
+#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 IFWL_DateTimeCalendar;
+class IFWL_DateTimeEdit;
+class IFWL_FormProxy;
+
+FWL_EVENT_DEF(CFWL_Event_DtpDropDown, CFWL_EventType::DropDown)
+
+FWL_EVENT_DEF(CFWL_Event_DtpCloseUp, CFWL_EventType::CloseUp)
+
+FWL_EVENT_DEF(CFWL_Event_DtpEditChanged,
+ CFWL_EventType::EditChanged,
+ CFX_WideString m_wsText;)
+
+FWL_EVENT_DEF(CFWL_Event_DtpHoverChanged,
+ CFWL_EventType::HoverChanged,
+ int32_t hoverday;)
+
+FWL_EVENT_DEF(CFWL_Event_DtpSelectChanged,
+ CFWL_EventType::SelectChanged,
+ int32_t iYear;
+ int32_t iMonth;
+ int32_t iDay;)
+
+class IFWL_DateTimePickerDP : public IFWL_DataProvider {
+ public:
+ virtual FWL_Error GetToday(IFWL_Widget* pWidget,
+ int32_t& iYear,
+ int32_t& iMonth,
+ int32_t& iDay) = 0;
+};
+
+class IFWL_DateTimePicker : public IFWL_Widget {
+ public:
+ static IFWL_DateTimePicker* Create(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+
+ IFWL_DateTimePicker(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+ ~IFWL_DateTimePicker() override;
+
+ // IFWL_Widget
+ FWL_Error GetClassName(CFX_WideString& wsClass) const override;
+ FWL_Type GetClassID() const override;
+ FWL_Error Initialize() override;
+ FWL_Error Finalize() override;
+ FWL_Error GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize = FALSE) override;
+ FWL_Error Update() override;
+ FWL_WidgetHit HitTest(FX_FLOAT fx, FX_FLOAT fy) override;
+ FWL_Error DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
+ FWL_Error SetThemeProvider(IFWL_ThemeProvider* pTP) override;
+
+ FWL_Error GetCurSel(int32_t& iYear, int32_t& iMonth, int32_t& iDay);
+ FWL_Error SetCurSel(int32_t iYear, int32_t iMonth, int32_t iDay);
+ FWL_Error SetEditText(const CFX_WideString& wsText);
+ FWL_Error 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);
+
+ FX_BOOL CanUndo();
+ FX_BOOL CanRedo();
+ FX_BOOL Undo();
+ FX_BOOL Redo();
+ FX_BOOL CanCopy();
+ FX_BOOL CanCut();
+ FX_BOOL CanSelectAll();
+ FX_BOOL Copy(CFX_WideString& wsCopy);
+ FX_BOOL Cut(CFX_WideString& wsCut);
+ FX_BOOL Paste(const CFX_WideString& wsPaste);
+ FX_BOOL SelectAll();
+ FX_BOOL Delete();
+ FX_BOOL DeSelect();
+ FWL_Error GetBBox(CFX_RectF& rect);
+ FWL_Error SetEditLimit(int32_t nLimit);
+ FWL_Error ModifyEditStylesEx(uint32_t dwStylesExAdded,
+ uint32_t dwStylesExRemoved);
+ IFWL_DateTimeEdit* GetDataTimeEdit();
+
+ protected:
+ friend class CFWL_DateTimeEditImpDelegate;
+ friend class IFWL_DateTimeCalendar;
+ friend class CFWL_DateTimeCalendarImpDelegate;
+ friend class CFWL_DateTimePickerImpDelegate;
+
+ class CFWL_MonthCalendarImpDP : public IFWL_MonthCalendarDP {
+ public:
+ CFWL_MonthCalendarImpDP();
+
+ // IFWL_DataProvider
+ FWL_Error GetCaption(IFWL_Widget* pWidget,
+ CFX_WideString& wsCaption) override;
+
+ // IFWL_MonthCalendarDP
+ int32_t GetCurDay(IFWL_Widget* pWidget) override;
+ int32_t GetCurMonth(IFWL_Widget* pWidget) override;
+ int32_t GetCurYear(IFWL_Widget* pWidget) override;
+
+ int32_t m_iCurDay;
+ int32_t m_iCurYear;
+ int32_t m_iCurMonth;
+ };
+
+ 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 ShowMonthCalendar(FX_BOOL bActivate);
+ FX_BOOL IsMonthCalendarShowed();
+ void ReSetEditAlignment();
+ void InitProxyForm();
+ void ProcessSelChanged(int32_t iYear, int32_t iMonth, int32_t iDay);
+
+ CFX_RectF m_rtBtn;
+ CFX_RectF m_rtClient;
+ int32_t m_iBtnState;
+ int32_t m_iYear;
+ int32_t m_iMonth;
+ int32_t m_iDay;
+ FX_BOOL m_bLBtnDown;
+ std::unique_ptr<IFWL_DateTimeEdit> m_pEdit;
+ std::unique_ptr<IFWL_DateTimeCalendar> m_pMonthCal;
+ std::unique_ptr<IFWL_FormProxy> m_pForm;
+ FX_FLOAT m_fBtn;
+ CFWL_MonthCalendarImpDP m_MonthCalendarDP;
+
+ private:
+ FWL_Error DisForm_Initialize();
+ void DisForm_InitDateTimeCalendar();
+ void DisForm_InitDateTimeEdit();
+ FX_BOOL DisForm_IsMonthCalendarShowed();
+ void DisForm_ShowMonthCalendar(FX_BOOL bActivate);
+ FWL_WidgetHit DisForm_HitTest(FX_FLOAT fx, FX_FLOAT fy);
+ FX_BOOL DisForm_IsNeedShowButton();
+ FWL_Error DisForm_Update();
+ FWL_Error DisForm_GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize = FALSE);
+ FWL_Error DisForm_GetBBox(CFX_RectF& rect);
+ FWL_Error DisForm_DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr);
+};
+
+class CFWL_DateTimePickerImpDelegate : public CFWL_WidgetImpDelegate {
+ public:
+ CFWL_DateTimePickerImpDelegate(IFWL_DateTimePicker* pOwner);
+
+ // CFWL_WidgetImpDelegate
+ void OnProcessMessage(CFWL_Message* pMessage) override;
+ void OnDrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
+
+ protected:
+ void OnFocusChanged(CFWL_Message* pMsg, FX_BOOL bSet = TRUE);
+ void OnLButtonDown(CFWL_MsgMouse* pMsg);
+ void OnLButtonUp(CFWL_MsgMouse* pMsg);
+ void OnMouseMove(CFWL_MsgMouse* pMsg);
+ void OnMouseLeave(CFWL_MsgMouse* pMsg);
+
+ IFWL_DateTimePicker* m_pOwner;
+
+ private:
+ void DisForm_OnFocusChanged(CFWL_Message* pMsg, FX_BOOL bSet = TRUE);
+};
+
+#endif // XFA_FWL_CORE_IFWL_DATETIMEPICKER_H_
diff --git a/xfa/fwl/core/ifwl_edit.cpp b/xfa/fwl/core/ifwl_edit.cpp
new file mode 100644
index 0000000000..83c00627c3
--- /dev/null
+++ b/xfa/fwl/core/ifwl_edit.cpp
@@ -0,0 +1,2053 @@
+// 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 <vector>
+
+#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/fgas_gefont.h"
+#include "xfa/fwl/core/cfwl_message.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_app.h"
+#include "xfa/fwl/core/ifwl_caret.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
+
+// static
+IFWL_Edit* IFWL_Edit::Create(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter) {
+ return new IFWL_Edit(properties, pOuter);
+}
+
+IFWL_Edit::IFWL_Edit(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter)
+ : IFWL_Widget(properties, pOuter),
+ m_fVAlignOffset(0.0f),
+ m_fScrollOffsetX(0.0f),
+ m_fScrollOffsetY(0.0f),
+ m_bLButtonDown(FALSE),
+ m_nSelStart(0),
+ m_nLimit(-1),
+ m_fSpaceAbove(0),
+ m_fSpaceBelow(0),
+ m_fFontSize(0),
+ m_bSetRange(FALSE),
+ m_iMin(-1),
+ m_iMax(0xFFFFFFF),
+ m_backColor(0),
+ m_updateBackColor(FALSE),
+ m_iCurRecord(-1),
+ m_iMaxRecord(128) {
+ m_rtClient.Reset();
+ m_rtEngine.Reset();
+ m_rtStatic.Reset();
+}
+
+IFWL_Edit::~IFWL_Edit() {
+ ClearRecord();
+}
+
+FWL_Error IFWL_Edit::GetClassName(CFX_WideString& wsClass) const {
+ wsClass = FWL_CLASS_Edit;
+ return FWL_Error::Succeeded;
+}
+
+FWL_Type IFWL_Edit::GetClassID() const {
+ return FWL_Type::Edit;
+}
+
+FWL_Error IFWL_Edit::Initialize() {
+ if (IFWL_Widget::Initialize() != FWL_Error::Succeeded)
+ return FWL_Error::Indefinite;
+ if (!m_pDelegate)
+ m_pDelegate = new CFWL_EditImpDelegate(this);
+
+ InitCaret();
+ if (!m_pEdtEngine)
+ InitEngine();
+
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_Edit::Finalize() {
+ if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) {
+ ShowCaret(FALSE);
+ }
+ if (m_pHorzScrollBar) {
+ m_pHorzScrollBar->Finalize();
+ }
+ if (m_pVertScrollBar) {
+ m_pVertScrollBar->Finalize();
+ }
+ delete m_pDelegate;
+ m_pDelegate = nullptr;
+ return IFWL_Widget::Finalize();
+}
+FWL_Error IFWL_Edit::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
+ if (bAutoSize) {
+ rect.Set(0, 0, 0, 0);
+ if (m_pEdtEngine) {
+ int32_t iTextLen = m_pEdtEngine->GetTextLength();
+ if (iTextLen > 0) {
+ CFX_WideString wsText;
+ m_pEdtEngine->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);
+ } else {
+ 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 FWL_Error::Succeeded;
+}
+
+void IFWL_Edit::SetStates(uint32_t dwStates, FX_BOOL bSet) {
+ if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Invisible) ||
+ (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
+ ShowCaret(FALSE);
+ }
+ IFWL_Widget::SetStates(dwStates, bSet);
+}
+
+FWL_Error IFWL_Edit::SetWidgetRect(const CFX_RectF& rect) {
+ return IFWL_Widget::SetWidgetRect(rect);
+}
+FWL_Error IFWL_Edit::Update() {
+ if (IsLocked()) {
+ return FWL_Error::Indefinite;
+ }
+ if (!m_pProperties->m_pThemeProvider) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ Layout();
+ if (m_rtClient.IsEmpty()) {
+ return FWL_Error::Indefinite;
+ }
+ UpdateEditEngine();
+ UpdateVAlignment();
+ UpdateScroll();
+ InitCaret();
+ return FWL_Error::Succeeded;
+}
+
+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_pEdtEngine->GetPage(0);
+ CFX_RectFArray rectArray;
+ CFX_RectF rectText;
+ const FDE_TXTEDTPARAMS* txtEdtParams = m_pEdtEngine->GetEditParams();
+ FX_FLOAT fAsent = (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);
+ }
+}
+int32_t IFWL_Edit::GetWordAtPoint(CFX_PointF pointf, int32_t& nCount) {
+ return 0;
+}
+FX_BOOL IFWL_Edit::GetSuggestWords(CFX_PointF pointf,
+ std::vector<CFX_ByteString>& sSuggest) {
+ int32_t nWordCount = 0;
+ int32_t nWordStart = GetWordAtPoint(pointf, nWordCount);
+ if (nWordCount < 1) {
+ return FALSE;
+ }
+ CFX_WideString wsSpell;
+ GetText(wsSpell, nWordStart, nWordCount);
+ CFX_ByteString sLatinWord;
+ for (int i = 0; i < nWordCount; i++) {
+ if (!FX_EDIT_ISLATINWORD(wsSpell[i])) {
+ break;
+ }
+ sLatinWord += (FX_CHAR)wsSpell[i];
+ }
+ if (sLatinWord.IsEmpty()) {
+ return FALSE;
+ }
+ CFWL_EvtEdtCheckWord checkWordEvent;
+ checkWordEvent.m_pSrcTarget = this;
+ checkWordEvent.bsWord = sLatinWord;
+ checkWordEvent.bCheckWord = TRUE;
+ DispatchEvent(&checkWordEvent);
+ if (checkWordEvent.bCheckWord) {
+ return FALSE;
+ }
+ CFWL_EvtEdtGetSuggestWords suggestWordsEvent;
+ suggestWordsEvent.m_pSrcTarget = this;
+ suggestWordsEvent.bsWord = sLatinWord;
+ suggestWordsEvent.bsArraySuggestWords = sSuggest;
+ suggestWordsEvent.bSuggestWords = FALSE;
+ DispatchEvent(&checkWordEvent);
+ return suggestWordsEvent.bSuggestWords;
+}
+FX_BOOL IFWL_Edit::ReplaceSpellCheckWord(CFX_PointF pointf,
+ const CFX_ByteStringC& bsReplace) {
+ int32_t nWordCount = 0;
+ int32_t nWordStart = GetWordAtPoint(pointf, nWordCount);
+ if (nWordCount < 1) {
+ return FALSE;
+ }
+ CFX_WideString wsSpell;
+ GetText(wsSpell, nWordStart, nWordCount);
+ for (int i = 0; i < nWordCount; i++) {
+ if (!FX_EDIT_ISLATINWORD(wsSpell[i])) {
+ nWordCount = i;
+ break;
+ }
+ }
+ int32_t nDestLen = bsReplace.GetLength();
+ CFX_WideString wsDest;
+ FX_WCHAR* pBuffer = wsDest.GetBuffer(nDestLen);
+ for (int32_t i = 0; i < nDestLen; i++) {
+ pBuffer[i] = bsReplace[i];
+ }
+ wsDest.ReleaseBuffer(nDestLen);
+ Replace(nWordStart, nWordCount, wsDest.AsStringC());
+ return TRUE;
+}
+void IFWL_Edit::DrawSpellCheck(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ pGraphics->SaveGraphState();
+ if (pMatrix) {
+ pGraphics->ConcatMatrix(const_cast<CFX_Matrix*>(pMatrix));
+ }
+ FX_ARGB cr = 0xFFFF0000;
+ CFX_Color crLine(cr);
+ CFWL_EvtEdtCheckWord 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];
+ } else {
+ 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();
+}
+FWL_Error IFWL_Edit::DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ if (!pGraphics)
+ return FWL_Error::Indefinite;
+ if (!m_pProperties->m_pThemeProvider)
+ return FWL_Error::Indefinite;
+ if (m_rtClient.IsEmpty()) {
+ return FWL_Error::Indefinite;
+ }
+ IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
+ if (!m_pWidgetMgr->IsFormDisabled()) {
+ DrawTextBk(pGraphics, pTheme, pMatrix);
+ }
+ if (m_pEdtEngine) {
+ 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);
+ }
+ return FWL_Error::Succeeded;
+}
+FWL_Error IFWL_Edit::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) {
+ if (!pThemeProvider)
+ return FWL_Error::Indefinite;
+ 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;
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_Edit::SetText(const CFX_WideString& wsText) {
+ m_pEdtEngine->SetText(wsText);
+ return FWL_Error::Succeeded;
+}
+
+int32_t IFWL_Edit::GetTextLength() const {
+ if (!m_pEdtEngine)
+ return -1;
+ return m_pEdtEngine->GetTextLength();
+}
+
+FWL_Error IFWL_Edit::GetText(CFX_WideString& wsText,
+ int32_t nStart,
+ int32_t nCount) const {
+ if (!m_pEdtEngine)
+ return FWL_Error::Indefinite;
+
+ m_pEdtEngine->GetText(wsText, nStart, nCount);
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_Edit::ClearText() {
+ if (!m_pEdtEngine)
+ return FWL_Error::Indefinite;
+
+ m_pEdtEngine->ClearText();
+ return FWL_Error::Succeeded;
+}
+
+int32_t IFWL_Edit::GetCaretPos() const {
+ if (!m_pEdtEngine)
+ return -1;
+ return m_pEdtEngine->GetCaretPos();
+}
+
+int32_t IFWL_Edit::SetCaretPos(int32_t nIndex, FX_BOOL bBefore) {
+ if (!m_pEdtEngine)
+ return -1;
+ return m_pEdtEngine->SetCaretPos(nIndex, bBefore);
+}
+
+FWL_Error IFWL_Edit::AddSelRange(int32_t nStart, int32_t nCount) {
+ if (!m_pEdtEngine)
+ return FWL_Error::Indefinite;
+
+ m_pEdtEngine->AddSelRange(nStart, nCount);
+ return FWL_Error::Succeeded;
+}
+
+int32_t IFWL_Edit::CountSelRanges() {
+ if (!m_pEdtEngine)
+ return 0;
+ return m_pEdtEngine->CountSelRanges();
+}
+
+int32_t IFWL_Edit::GetSelRange(int32_t nIndex, int32_t& nStart) {
+ if (!m_pEdtEngine)
+ return -1;
+ return m_pEdtEngine->GetSelRange(nIndex, nStart);
+}
+
+FWL_Error IFWL_Edit::ClearSelections() {
+ if (!m_pEdtEngine)
+ return FWL_Error::Indefinite;
+
+ m_pEdtEngine->ClearSelection();
+ return FWL_Error::Succeeded;
+}
+
+int32_t IFWL_Edit::GetLimit() {
+ return m_nLimit;
+}
+
+FWL_Error IFWL_Edit::SetLimit(int32_t nLimit) {
+ m_nLimit = nLimit;
+ if (!m_pEdtEngine)
+ return FWL_Error::Indefinite;
+
+ m_pEdtEngine->SetLimit(nLimit);
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_Edit::SetAliasChar(FX_WCHAR wAlias) {
+ if (!m_pEdtEngine)
+ return FWL_Error::Indefinite;
+
+ m_pEdtEngine->SetAliasChar(wAlias);
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_Edit::Insert(int32_t nStart,
+ const FX_WCHAR* lpText,
+ int32_t nLen) {
+ if (!m_pEdtEngine)
+ return FWL_Error::Indefinite;
+
+ if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly) ||
+ (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
+ return FWL_Error::Indefinite;
+ }
+ m_pEdtEngine->Insert(nStart, lpText, nLen);
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_Edit::DeleteSelections() {
+ if (!m_pEdtEngine)
+ return FWL_Error::Indefinite;
+
+ int32_t iCount = m_pEdtEngine->CountSelRanges();
+ if (iCount > 0)
+ m_pEdtEngine->Delete(-1);
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_Edit::DeleteRange(int32_t nStart, int32_t nCount) {
+ if (!m_pEdtEngine)
+ return FWL_Error::Indefinite;
+
+ m_pEdtEngine->DeleteRange(nStart, nCount);
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_Edit::Replace(int32_t nStart,
+ int32_t nLen,
+ const CFX_WideStringC& wsReplace) {
+ if (!m_pEdtEngine)
+ return FWL_Error::Indefinite;
+
+ m_pEdtEngine->Replace(nStart, nLen, CFX_WideString(wsReplace));
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_Edit::DoClipboard(int32_t iCmd) {
+ if (!m_pEdtEngine)
+ return FWL_Error::Indefinite;
+
+ if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly) ||
+ (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
+ return FWL_Error::Succeeded;
+ }
+ return FWL_Error::Indefinite;
+}
+
+FX_BOOL IFWL_Edit::Copy(CFX_WideString& wsCopy) {
+ if (!m_pEdtEngine)
+ return FALSE;
+
+ int32_t nCount = m_pEdtEngine->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_pEdtEngine->GetSelRange(i, nStart);
+ m_pEdtEngine->GetText(wsTemp, nStart, nLength);
+ wsCopy += wsTemp;
+ wsTemp.clear();
+ }
+ return TRUE;
+}
+
+FX_BOOL IFWL_Edit::Cut(CFX_WideString& wsCut) {
+ if (!m_pEdtEngine)
+ return FALSE;
+
+ int32_t nCount = m_pEdtEngine->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_pEdtEngine->GetSelRange(i, nStart);
+ m_pEdtEngine->GetText(wsTemp, nStart, nLength);
+ wsCut += wsTemp;
+ wsTemp.clear();
+ }
+ m_pEdtEngine->Delete(0);
+ return TRUE;
+}
+
+FX_BOOL IFWL_Edit::Paste(const CFX_WideString& wsPaste) {
+ if (!m_pEdtEngine)
+ return FALSE;
+
+ int32_t nCaret = m_pEdtEngine->GetCaretPos();
+ int32_t iError =
+ m_pEdtEngine->Insert(nCaret, wsPaste.c_str(), wsPaste.GetLength());
+ if (iError < 0) {
+ ProcessInsertError(iError);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+FX_BOOL IFWL_Edit::Delete() {
+ if (!m_pEdtEngine)
+ return FALSE;
+
+ int32_t nCount = m_pEdtEngine->CountSelRanges();
+ if (nCount < 1)
+ return FALSE;
+
+ m_pEdtEngine->Delete(0);
+ return TRUE;
+}
+
+FX_BOOL IFWL_Edit::Redo(const IFDE_TxtEdtDoRecord* pRecord) {
+ if (!m_pEdtEngine)
+ return FALSE;
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_NoRedoUndo)
+ return TRUE;
+ return m_pEdtEngine->Redo(pRecord);
+}
+
+FX_BOOL IFWL_Edit::Undo(const IFDE_TxtEdtDoRecord* pRecord) {
+ if (!m_pEdtEngine)
+ return FALSE;
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_NoRedoUndo)
+ return TRUE;
+ return m_pEdtEngine->Undo(pRecord);
+}
+
+FX_BOOL IFWL_Edit::Undo() {
+ if (!CanUndo())
+ return FALSE;
+ return Undo(m_DoRecords[m_iCurRecord--].get());
+}
+
+FX_BOOL IFWL_Edit::Redo() {
+ if (!CanRedo())
+ return FALSE;
+ return Redo(m_DoRecords[++m_iCurRecord].get());
+}
+
+FX_BOOL IFWL_Edit::CanUndo() {
+ return m_iCurRecord >= 0;
+}
+
+FX_BOOL IFWL_Edit::CanRedo() {
+ return m_iCurRecord < pdfium::CollectionSize<int32_t>(m_DoRecords) - 1;
+}
+
+FWL_Error IFWL_Edit::SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant) {
+ if (!m_pEdtEngine)
+ return FWL_Error::Indefinite;
+
+ FDE_TXTEDTPARAMS* pParams = m_pEdtEngine->GetEditParams();
+ pParams->fTabWidth = fTabWidth;
+ pParams->bTabEquidistant = bEquidistant;
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_Edit::SetOuter(IFWL_Widget* pOuter) {
+ m_pOuter = pOuter;
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_Edit::SetNumberRange(int32_t iMin, int32_t iMax) {
+ m_iMin = iMin;
+ m_iMax = iMax;
+ m_bSetRange = TRUE;
+ return FWL_Error::Succeeded;
+}
+
+void IFWL_Edit::On_CaretChanged(CFDE_TxtEdtEngine* pEdit,
+ int32_t nPage,
+ FX_BOOL bVisible) {
+ if (m_rtEngine.IsEmpty())
+ return;
+ if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0)
+ return;
+
+ FX_BOOL bRepaintContent = UpdateOffset();
+ UpdateCaret();
+ CFX_RectF rtInvalid;
+ rtInvalid.Set(0, 0, 0, 0);
+ FX_BOOL bRepaintScroll = FALSE;
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine) {
+ IFWL_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) {
+ uint32_t dwStyleEx = m_pProperties->m_dwStyleExes;
+ if (dwStyleEx & FWL_STYLEEXT_EDT_VAlignMask)
+ UpdateVAlignment();
+
+ IFDE_TxtEdtPage* page = m_pEdtEngine->GetPage(0);
+ FX_FLOAT fContentWidth = page->GetContentsBox().width;
+ FX_FLOAT fContentHeight = page->GetContentsBox().height;
+ CFX_RectF rtTemp;
+ GetClientRect(rtTemp);
+ FX_BOOL bHSelfAdaption =
+ m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HSelfAdaption;
+ FX_BOOL bVSelfAdaption =
+ m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VSelfAdaption;
+ FX_BOOL bNeedUpdate = FALSE;
+ if (bHSelfAdaption || bVSelfAdaption) {
+ CFWL_EvtEdtPreSelfAdaption evt;
+ evt.m_pSrcTarget = this;
+ evt.bHSelfAdaption = TRUE;
+ evt.bVSelfAdaption = TRUE;
+ FX_FLOAT fWidth;
+ FX_FLOAT fHight;
+ fWidth = bHSelfAdaption ? fContentWidth : m_pProperties->m_rtWidget.width;
+ fHight = bVSelfAdaption ? fContentHeight : m_pProperties->m_rtWidget.height;
+ evt.rtAfterChange.Set(0, 0, fWidth, fHight);
+ DispatchEvent(&evt);
+ if (!evt.bHSelfAdaption) {
+ ModifyStylesEx(
+ 0, FWL_STYLEEXT_EDT_HSelfAdaption | FWL_STYLEEXT_EDT_AutoHScroll);
+ }
+ if (!evt.bVSelfAdaption) {
+ ModifyStylesEx(
+ 0, FWL_STYLEEXT_EDT_VSelfAdaption | FWL_STYLEEXT_EDT_AutoVScroll);
+ }
+ bNeedUpdate = (bHSelfAdaption && !evt.bHSelfAdaption) ||
+ (bVSelfAdaption && !evt.bVSelfAdaption);
+ }
+ FX_FLOAT fContentWidth1 = fContentWidth;
+ FX_FLOAT fContentHeight1 = fContentHeight;
+ if (bNeedUpdate) {
+ UpdateEditParams();
+ UpdateEditLayout();
+ IFDE_TxtEdtPage* page1 = m_pEdtEngine->GetPage(0);
+ fContentWidth1 = page1->GetContentsBox().width;
+ fContentHeight1 = page1->GetContentsBox().height;
+ }
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HSelfAdaption) {
+ rtTemp.width = std::max(m_pProperties->m_rtWidget.width, fContentWidth1);
+ m_pProperties->m_rtWidget.width = fContentWidth1;
+ }
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VSelfAdaption) {
+ rtTemp.height = std::max(m_pProperties->m_rtWidget.height, fContentHeight1);
+ m_pProperties->m_rtWidget.height = fContentHeight1;
+ }
+ CFWL_EvtEdtTextChanged 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);
+}
+
+FX_BOOL IFWL_Edit::On_PageLoad(CFDE_TxtEdtEngine* pEdit,
+ int32_t nPageIndex,
+ int32_t nPurpose) {
+ IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(nPageIndex);
+ if (!pPage)
+ return FALSE;
+ pPage->LoadPage(nullptr, nullptr);
+ return TRUE;
+}
+
+FX_BOOL IFWL_Edit::On_PageUnload(CFDE_TxtEdtEngine* pEdit,
+ int32_t nPageIndex,
+ int32_t nPurpose) {
+ IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(nPageIndex);
+ if (!pPage)
+ return FALSE;
+ pPage->UnloadPage(nullptr);
+ return TRUE;
+}
+
+void IFWL_Edit::On_AddDoRecord(CFDE_TxtEdtEngine* pEdit,
+ IFDE_TxtEdtDoRecord* pRecord) {
+ AddDoRecord(pRecord);
+}
+
+FX_BOOL IFWL_Edit::On_Validate(CFDE_TxtEdtEngine* pEdit,
+ CFX_WideString& wsText) {
+ IFWL_Widget* pDst = GetOuter();
+ if (!pDst) {
+ pDst = this;
+ }
+ CFWL_EvtEdtValidate event;
+ event.pDstWidget = pDst;
+ event.m_pSrcTarget = this;
+ event.wsInsert = wsText;
+ event.bValidate = TRUE;
+ DispatchEvent(&event);
+ return event.bValidate;
+}
+FWL_Error IFWL_Edit::SetBackgroundColor(uint32_t color) {
+ m_backColor = color;
+ m_updateBackColor = TRUE;
+ return FWL_Error::Succeeded;
+}
+FWL_Error IFWL_Edit::SetFont(const CFX_WideString& wsFont, FX_FLOAT fSize) {
+ m_wsFont = wsFont;
+ m_fFontSize = fSize;
+ return FWL_Error::Succeeded;
+}
+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) {
+ if (!m_pEdtEngine)
+ return;
+ IFDE_TxtEdtPage* pPage = m_pEdtEngine->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);
+ }
+ FX_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_pEdtEngine->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_pEdtEngine->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_pEdtEngine->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: {}
+ }
+ 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; }
+ }
+ 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_pEdtEngine->SetEditParams(params);
+}
+
+void IFWL_Edit::UpdateEditLayout() {
+ if (m_pEdtEngine->GetTextLength() <= 0)
+ m_pEdtEngine->SetTextByStream(nullptr);
+
+ IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0);
+ if (pPage)
+ pPage->UnloadPage(nullptr);
+
+ m_pEdtEngine->StartLayout();
+ m_pEdtEngine->DoLayout(nullptr);
+ m_pEdtEngine->EndLayout();
+ pPage = m_pEdtEngine->GetPage(0);
+ if (pPage)
+ pPage->LoadPage(nullptr, nullptr);
+}
+
+FX_BOOL IFWL_Edit::UpdateOffset() {
+ CFX_RectF rtCaret;
+ m_pEdtEngine->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_pEdtEngine->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();
+ if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HSelfAdaption))
+ m_fScrollOffsetX += offsetX;
+ if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VSelfAdaption))
+ m_fScrollOffsetY += offsetY;
+ if (m_fFontSize > m_rtEngine.height)
+ m_fScrollOffsetY = 0;
+ return TRUE;
+}
+
+FX_BOOL IFWL_Edit::UpdateOffset(IFWL_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_pEdtEngine->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 = fOffsetY;
+ if (m_fVAlignOffset < 0) {
+ m_fVAlignOffset = 0;
+ }
+}
+void IFWL_Edit::UpdateCaret() {
+ CFX_RectF rtFDE;
+ m_pEdtEngine->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 temp = rtCaret;
+ 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;
+ }
+ FX_BOOL bIntersect = !rtCaret.IsEmpty();
+ FX_BOOL bShow = TRUE;
+ FX_BOOL bShowWhole = FALSE;
+ if (!(m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) || !bIntersect) {
+ bShow = FALSE;
+ }
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HSelfAdaption &&
+ temp.right() > m_rtEngine.right()) {
+ bShowWhole = TRUE;
+ }
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VSelfAdaption &&
+ temp.bottom() > m_rtEngine.bottom()) {
+ bShowWhole = TRUE;
+ } else {
+ bShow = (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused && bIntersect);
+ }
+ if (bShowWhole) {
+ rtCaret = temp;
+ }
+ ShowCaret(bShow, &rtCaret);
+}
+IFWL_ScrollBar* IFWL_Edit::UpdateScroll() {
+ FX_BOOL bShowHorz =
+ m_pHorzScrollBar &&
+ ((m_pHorzScrollBar->GetStates() & FWL_WGTSTATE_Invisible) == 0);
+ FX_BOOL bShowVert =
+ m_pVertScrollBar &&
+ ((m_pVertScrollBar->GetStates() & FWL_WGTSTATE_Invisible) == 0);
+ if (!bShowHorz && !bShowVert) {
+ return nullptr;
+ }
+ IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0);
+ if (!pPage)
+ return nullptr;
+ const CFX_RectF& rtFDE = pPage->GetContentsBox();
+ IFWL_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 = m_fScrollOffsetX;
+ if (fPos < 0.0f) {
+ fPos = 0.0f;
+ }
+ if (fPos > fRange) {
+ fPos = 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_pEdtEngine->GetEditParams()->fLineSpace;
+ FX_FLOAT fRange = rtFDE.height - m_rtEngine.height;
+ if (fRange < fStep) {
+ fRange = fStep;
+ }
+ m_pVertScrollBar->SetRange(0.0f, fRange);
+ FX_FLOAT fPos = m_fScrollOffsetY;
+ if (fPos < 0.0f) {
+ fPos = 0.0f;
+ }
+ if (fPos > fRange) {
+ fPos = 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;
+}
+FX_BOOL IFWL_Edit::IsShowScrollBar(FX_BOOL bVert) {
+ FX_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);
+}
+FX_BOOL IFWL_Edit::IsContentHeightOverflow() {
+ if (!m_pEdtEngine)
+ return FALSE;
+ IFDE_TxtEdtPage* pPage = m_pEdtEngine->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);
+ }
+ }
+ FX_BOOL bShowVertScrollbar = IsShowScrollBar(TRUE);
+ FX_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;
+ FX_BOOL bShowVertScrollbar = IsShowScrollBar(TRUE);
+ FX_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(FX_BOOL bVert) {
+ if ((bVert && m_pVertScrollBar) || (!bVert && m_pHorzScrollBar)) {
+ return;
+ }
+ CFWL_WidgetImpProperties prop;
+ 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;
+ IFWL_ScrollBar* pScrollBar = IFWL_ScrollBar::Create(prop, this);
+ pScrollBar->Initialize();
+ (bVert ? &m_pVertScrollBar : &m_pHorzScrollBar)->reset(pScrollBar);
+}
+
+void IFWL_Edit::InitEngine() {
+ if (!m_pEdtEngine)
+ m_pEdtEngine.reset(new CFDE_TxtEdtEngine);
+}
+
+FX_BOOL FWL_ShowCaret(IFWL_Widget* pWidget,
+ FX_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(FX_BOOL bVisible, CFX_RectF* pRect) {
+ if (m_pCaret) {
+ m_pCaret->ShowCaret(bVisible);
+ if (bVisible && !pRect->IsEmpty()) {
+ m_pCaret->SetWidgetRect(*pRect);
+ }
+ Repaint(&m_rtEngine);
+ } else {
+ 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);
+ }
+}
+FX_BOOL IFWL_Edit::ValidateNumberChar(FX_WCHAR cNum) {
+ if (!m_pEdtEngine) {
+ return FALSE;
+ }
+ if (!m_bSetRange) {
+ return TRUE;
+ }
+ CFX_WideString wsOld, wsText;
+ m_pEdtEngine->GetText(wsText, 0);
+ if (wsText.IsEmpty()) {
+ if (cNum == L'0') {
+ return FALSE;
+ }
+ return TRUE;
+ }
+ int32_t caretPos = m_pEdtEngine->GetCaretPos();
+ int32_t iSel = CountSelRanges();
+ if (iSel == 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;
+ }
+ } else {
+ 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)) {
+ CFWL_WidgetImpProperties prop;
+ m_pCaret.reset(IFWL_Caret::Create(prop, this));
+ m_pCaret->Initialize();
+ 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) {
+ switch (iError) {
+ case -2: {
+ CFWL_EvtEdtTextFull textFullEvent;
+ textFullEvent.m_pSrcTarget = this;
+ DispatchEvent(&textFullEvent);
+ break;
+ }
+ default: {}
+ }
+}
+
+CFWL_EditImpDelegate::CFWL_EditImpDelegate(IFWL_Edit* pOwner)
+ : m_pOwner(pOwner) {}
+
+void CFWL_EditImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
+ if (!pMessage)
+ return;
+
+ CFWL_MessageType dwMsgCode = pMessage->GetClassID();
+ switch (dwMsgCode) {
+ case CFWL_MessageType::Activate: {
+ DoActivate(static_cast<CFWL_MsgActivate*>(pMessage));
+ break;
+ }
+ case CFWL_MessageType::Deactivate: {
+ DoDeactivate(static_cast<CFWL_MsgDeactivate*>(pMessage));
+ break;
+ }
+ 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_WidgetImpDelegate::OnProcessMessage(pMessage);
+}
+
+void CFWL_EditImpDelegate::OnProcessEvent(CFWL_Event* pEvent) {
+ if (!pEvent)
+ return;
+ if (pEvent->GetClassID() != CFWL_EventType::Scroll)
+ return;
+
+ IFWL_Widget* pSrcTarget = pEvent->m_pSrcTarget;
+ if ((pSrcTarget == m_pOwner->m_pVertScrollBar.get() &&
+ m_pOwner->m_pVertScrollBar) ||
+ (pSrcTarget == m_pOwner->m_pHorzScrollBar.get() &&
+ m_pOwner->m_pHorzScrollBar)) {
+ CFWL_EvtScroll* pScrollEvent = static_cast<CFWL_EvtScroll*>(pEvent);
+ OnScroll(static_cast<IFWL_ScrollBar*>(pSrcTarget),
+ pScrollEvent->m_iScrollCode, pScrollEvent->m_fPos);
+ }
+}
+
+void CFWL_EditImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ m_pOwner->DrawWidget(pGraphics, pMatrix);
+}
+
+void CFWL_EditImpDelegate::DoActivate(CFWL_MsgActivate* pMsg) {
+ m_pOwner->m_pProperties->m_dwStates |= ~FWL_WGTSTATE_Deactivated;
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+}
+void CFWL_EditImpDelegate::DoDeactivate(CFWL_MsgDeactivate* pMsg) {
+ m_pOwner->m_pProperties->m_dwStates &= FWL_WGTSTATE_Deactivated;
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+}
+void CFWL_EditImpDelegate::DoButtonDown(CFWL_MsgMouse* pMsg) {
+ if ((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) {
+ m_pOwner->SetFocus(TRUE);
+ }
+ if (!m_pOwner->m_pEdtEngine) {
+ m_pOwner->UpdateEditEngine();
+ }
+ IFDE_TxtEdtPage* pPage = m_pOwner->m_pEdtEngine->GetPage(0);
+ if (!pPage)
+ return;
+ CFX_PointF pt(pMsg->m_fx, pMsg->m_fy);
+ m_pOwner->DeviceToEngine(pt);
+ FX_BOOL bBefore = TRUE;
+ int32_t nIndex = pPage->GetCharIndex(pt, bBefore);
+ if (nIndex < 0) {
+ nIndex = 0;
+ }
+ m_pOwner->m_pEdtEngine->SetCaretPos(nIndex, bBefore);
+}
+void CFWL_EditImpDelegate::OnFocusChanged(CFWL_Message* pMsg, FX_BOOL bSet) {
+ uint32_t dwStyleEx = m_pOwner->GetStylesEx();
+ bool bRepaint = !!(dwStyleEx & FWL_STYLEEXT_EDT_InnerCaret);
+ if (bSet) {
+ m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
+ if (!m_pOwner->m_pEdtEngine) {
+ m_pOwner->UpdateEditEngine();
+ }
+ m_pOwner->UpdateVAlignment();
+ m_pOwner->UpdateOffset();
+ m_pOwner->UpdateCaret();
+ } else if (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
+ m_pOwner->ShowCaret(FALSE);
+ if (m_pOwner->m_pEdtEngine &&
+ (dwStyleEx & FWL_STYLEEXT_EDT_NoHideSel) == 0) {
+ int32_t nSel = m_pOwner->CountSelRanges();
+ if (nSel > 0) {
+ m_pOwner->ClearSelections();
+ bRepaint = TRUE;
+ }
+ m_pOwner->SetCaretPos(0);
+ m_pOwner->UpdateOffset();
+ }
+ m_pOwner->ClearRecord();
+ }
+ m_pOwner->LayoutScrollBar();
+ if (bRepaint) {
+ CFX_RectF rtInvalidate;
+ rtInvalidate.Set(0, 0, m_pOwner->m_pProperties->m_rtWidget.width,
+ m_pOwner->m_pProperties->m_rtWidget.height);
+ m_pOwner->Repaint(&rtInvalidate);
+ }
+}
+void CFWL_EditImpDelegate::OnLButtonDown(CFWL_MsgMouse* pMsg) {
+ DoCursor(pMsg);
+ if (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) {
+ return;
+ }
+ m_pOwner->m_bLButtonDown = TRUE;
+ m_pOwner->SetGrab(TRUE);
+ DoButtonDown(pMsg);
+ int32_t nIndex = m_pOwner->m_pEdtEngine->GetCaretPos();
+ FX_BOOL bRepaint = FALSE;
+ int32_t iCount = m_pOwner->m_pEdtEngine->CountSelRanges();
+ if (iCount > 0) {
+ m_pOwner->m_pEdtEngine->ClearSelection();
+ bRepaint = TRUE;
+ }
+ FX_BOOL bShift = pMsg->m_dwFlags & FWL_KEYFLAG_Shift;
+ if (bShift && m_pOwner->m_nSelStart != nIndex) {
+ int32_t iStart = std::min(m_pOwner->m_nSelStart, nIndex);
+ int32_t iEnd = std::max(m_pOwner->m_nSelStart, nIndex);
+ m_pOwner->m_pEdtEngine->AddSelRange(iStart, iEnd - iStart);
+ bRepaint = TRUE;
+ } else {
+ m_pOwner->m_nSelStart = nIndex;
+ }
+ if (bRepaint) {
+ m_pOwner->Repaint(&m_pOwner->m_rtEngine);
+ }
+}
+void CFWL_EditImpDelegate::OnLButtonUp(CFWL_MsgMouse* pMsg) {
+ DoCursor(pMsg);
+ m_pOwner->m_bLButtonDown = FALSE;
+ m_pOwner->SetGrab(FALSE);
+}
+void CFWL_EditImpDelegate::OnButtonDblClk(CFWL_MsgMouse* pMsg) {
+ if (!m_pOwner->m_pEdtEngine)
+ return;
+ DoCursor(pMsg);
+ IFDE_TxtEdtPage* pPage = m_pOwner->m_pEdtEngine->GetPage(0);
+ if (!pPage)
+ return;
+ CFX_PointF pt(pMsg->m_fx, pMsg->m_fy);
+ m_pOwner->DeviceToEngine(pt);
+ int32_t nCount = 0;
+ int32_t nIndex = pPage->SelectWord(pt, nCount);
+ if (nIndex < 0) {
+ return;
+ }
+ m_pOwner->m_pEdtEngine->AddSelRange(nIndex, nCount);
+ m_pOwner->m_pEdtEngine->SetCaretPos(nIndex + nCount - 1, FALSE);
+ m_pOwner->Repaint(&m_pOwner->m_rtEngine);
+}
+void CFWL_EditImpDelegate::OnMouseMove(CFWL_MsgMouse* pMsg) {
+ if (!m_pOwner->m_pEdtEngine)
+ return;
+ DoCursor(pMsg);
+ if (m_pOwner->m_nSelStart == -1 || !m_pOwner->m_bLButtonDown) {
+ return;
+ }
+ IFDE_TxtEdtPage* pPage = m_pOwner->m_pEdtEngine->GetPage(0);
+ if (!pPage)
+ return;
+ CFX_PointF pt(pMsg->m_fx, pMsg->m_fy);
+ m_pOwner->DeviceToEngine(pt);
+ FX_BOOL bBefore = TRUE;
+ int32_t nIndex = pPage->GetCharIndex(pt, bBefore);
+ m_pOwner->m_pEdtEngine->SetCaretPos(nIndex, bBefore);
+ nIndex = m_pOwner->m_pEdtEngine->GetCaretPos();
+ m_pOwner->m_pEdtEngine->ClearSelection();
+ if (nIndex != m_pOwner->m_nSelStart) {
+ int32_t nLen = m_pOwner->m_pEdtEngine->GetTextLength();
+ if (m_pOwner->m_nSelStart >= nLen) {
+ m_pOwner->m_nSelStart = nLen;
+ }
+ m_pOwner->m_pEdtEngine->AddSelRange(
+ std::min(m_pOwner->m_nSelStart, nIndex),
+ FXSYS_abs(nIndex - m_pOwner->m_nSelStart));
+ }
+}
+void CFWL_EditImpDelegate::OnKeyDown(CFWL_MsgKey* pMsg) {
+ if (!m_pOwner->m_pEdtEngine)
+ return;
+ FDE_TXTEDTMOVECARET MoveCaret = MC_MoveNone;
+ FX_BOOL bShift = pMsg->m_dwFlags & FWL_KEYFLAG_Shift;
+ FX_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: {
+ if (bCtrl) {
+ MoveCaret = MC_Home;
+ } else {
+ MoveCaret = MC_LineStart;
+ }
+ break;
+ }
+ case FWL_VKEY_End: {
+ if (bCtrl) {
+ MoveCaret = MC_End;
+ } else {
+ MoveCaret = MC_LineEnd;
+ }
+ break;
+ }
+ case FWL_VKEY_Insert: {
+ break;
+ }
+ case FWL_VKEY_Delete: {
+ if ((m_pOwner->m_pProperties->m_dwStyleExes &
+ FWL_STYLEEXT_EDT_ReadOnly) ||
+ (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
+ break;
+ }
+ int32_t nCaret = m_pOwner->m_pEdtEngine->GetCaretPos();
+#if (_FX_OS_ == _FX_MACOSX_)
+ m_pOwner->m_pEdtEngine->Delete(nCaret, TRUE);
+#else
+ m_pOwner->m_pEdtEngine->Delete(nCaret);
+#endif
+ break;
+ }
+ case FWL_VKEY_F2: {
+ break;
+ }
+ case FWL_VKEY_Tab: {
+ m_pOwner->DispatchKeyEvent(pMsg);
+ break;
+ }
+ default: {
+#if (_FX_OS_ == _FX_MACOSX_)
+ if (pMsg->m_dwFlags & FWL_KEYFLAG_Command) {
+#else
+ if (pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl) {
+#endif
+ if (dwKeyCode == 0x43 || dwKeyCode == 0x63) {
+ m_pOwner->DoClipboard(1);
+ return;
+ }
+ if (dwKeyCode == 0x58 || dwKeyCode == 0x78) {
+ m_pOwner->DoClipboard(2);
+ return;
+ }
+ if (dwKeyCode == 0x56 || dwKeyCode == 0x76) {
+ m_pOwner->DoClipboard(3);
+ return;
+ }
+ }
+ }
+ }
+ if (MoveCaret != MC_MoveNone) {
+ m_pOwner->m_pEdtEngine->MoveCaretPos(MoveCaret, bShift, bCtrl);
+ }
+}
+void CFWL_EditImpDelegate::OnChar(CFWL_MsgKey* pMsg) {
+ if ((m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly) ||
+ (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
+ return;
+ }
+ if (!m_pOwner->m_pEdtEngine)
+ return;
+ int32_t iError = 0;
+ FX_WCHAR c = (FX_WCHAR)pMsg->m_dwKeyCode;
+ int32_t nCaret = m_pOwner->m_pEdtEngine->GetCaretPos();
+ switch (c) {
+ case FWL_VKEY_Back: {
+ m_pOwner->m_pEdtEngine->Delete(nCaret, TRUE);
+ break;
+ }
+ case 0x0A: {
+ break;
+ }
+ case FWL_VKEY_Escape: {
+ break;
+ }
+ case FWL_VKEY_Tab: {
+ iError = m_pOwner->m_pEdtEngine->Insert(nCaret, L"\t", 1);
+ break;
+ }
+ case FWL_VKEY_Return: {
+ if (m_pOwner->m_pProperties->m_dwStyleExes &
+ FWL_STYLEEXT_EDT_WantReturn) {
+ iError = m_pOwner->m_pEdtEngine->Insert(nCaret, L"\n", 1);
+ }
+ break;
+ }
+ default: {
+ if (!m_pOwner->m_pWidgetMgr->IsFormDisabled()) {
+ if (m_pOwner->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 (!m_pOwner->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_pOwner->m_pEdtEngine->Insert(nCaret, &c, 1);
+ break;
+ }
+ }
+ if (iError < 0) {
+ m_pOwner->ProcessInsertError(iError);
+ }
+}
+FX_BOOL CFWL_EditImpDelegate::OnScroll(IFWL_ScrollBar* pScrollBar,
+ uint32_t 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: {
+ break;
+ }
+ case FWL_SCBCODE_EndScroll: {
+ return FALSE;
+ }
+ default: {}
+ }
+ if (iCurPos != fPos) {
+ pScrollBar->SetPos(fPos);
+ pScrollBar->SetTrackPos(fPos);
+ m_pOwner->UpdateOffset(pScrollBar, fPos - iCurPos);
+ if (m_pOwner->m_pEdtEngine) {
+ m_pOwner->UpdateCaret();
+ }
+ CFX_RectF rect;
+ m_pOwner->GetWidgetRect(rect);
+ CFX_RectF rtInvalidate;
+ rtInvalidate.Set(0, 0, rect.width + 2, rect.height + 2);
+ m_pOwner->Repaint(&rtInvalidate);
+ }
+ return TRUE;
+}
+void CFWL_EditImpDelegate::DoCursor(CFWL_MsgMouse* pMsg) {}
diff --git a/xfa/fwl/core/ifwl_edit.h b/xfa/fwl/core/ifwl_edit.h
new file mode 100644
index 0000000000..2d65897b8c
--- /dev/null
+++ b/xfa/fwl/core/ifwl_edit.h
@@ -0,0 +1,284 @@
+// 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/ifde_txtedtdorecord.h"
+#include "xfa/fde/ifde_txtedtengine.h"
+#include "xfa/fwl/core/cfwl_event.h"
+#include "xfa/fwl/core/ifwl_dataprovider.h"
+#include "xfa/fwl/core/ifwl_scrollbar.h"
+#include "xfa/fwl/lightwidget/cfwl_widget.h"
+#include "xfa/fxgraphics/cfx_path.h"
+
+#define FWL_CLASS_Edit L"FWL_EDIT"
+#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_HSelfAdaption (1L << 10)
+#define FWL_STYLEEXT_EDT_VSelfAdaption (1L << 11)
+#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)
+
+enum FWL_EDT_TEXTCHANGED {
+ FWL_EDT_TEXTCHANGED_Insert = 0,
+ FWL_EDT_TEXTCHANGED_Delete,
+ FWL_EDT_TEXTCHANGED_Replace,
+};
+
+FWL_EVENT_DEF(CFWL_EvtEdtTextChanged,
+ CFWL_EventType::TextChanged,
+ int32_t nChangeType;
+ CFX_WideString wsInsert;
+ CFX_WideString wsDelete;
+ CFX_WideString wsPrevText;)
+
+FWL_EVENT_DEF(CFWL_EvtEdtTextFull, CFWL_EventType::TextFull)
+
+FWL_EVENT_DEF(CFWL_EvtEdtPreSelfAdaption,
+ CFWL_EventType::PreSelfAdaption,
+ FX_BOOL bHSelfAdaption;
+ FX_BOOL bVSelfAdaption;
+ CFX_RectF rtAfterChange;)
+
+FWL_EVENT_DEF(CFWL_EvtEdtValidate,
+ CFWL_EventType::Validate,
+ IFWL_Widget* pDstWidget;
+ CFX_WideString wsInsert;
+ FX_BOOL bValidate;)
+
+FWL_EVENT_DEF(CFWL_EvtEdtCheckWord,
+ CFWL_EventType::CheckWord,
+ CFX_ByteString bsWord;
+ FX_BOOL bCheckWord;)
+
+FWL_EVENT_DEF(CFWL_EvtEdtGetSuggestWords,
+ CFWL_EventType::GetSuggestedWords,
+ FX_BOOL bSuggestWords;
+ CFX_ByteString bsWord;
+ std::vector<CFX_ByteString> bsArraySuggestWords;)
+
+class CFWL_WidgetImpProperties;
+class IFDE_TxtEdtDoRecord;
+class IFWL_Edit;
+class CFWL_EditImpDelegate;
+class CFWL_MsgActivate;
+class CFWL_MsgDeactivate;
+class CFWL_MsgMouse;
+class CFWL_WidgetImpDelegate;
+class CFWL_WidgetImpProperties;
+class IFWL_Caret;
+
+class IFWL_EditDP : public IFWL_DataProvider {};
+
+class IFWL_Edit : public IFWL_Widget {
+ public:
+ static IFWL_Edit* Create(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+
+ IFWL_Edit(const CFWL_WidgetImpProperties& properties, IFWL_Widget* pOuter);
+ ~IFWL_Edit() override;
+
+ // IFWL_Widget:
+ FWL_Error GetClassName(CFX_WideString& wsClass) const override;
+ FWL_Type GetClassID() const override;
+ FWL_Error Initialize() override;
+ FWL_Error Finalize() override;
+ FWL_Error GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize = FALSE) override;
+ FWL_Error SetWidgetRect(const CFX_RectF& rect) override;
+ FWL_Error Update() override;
+ FWL_WidgetHit HitTest(FX_FLOAT fx, FX_FLOAT fy) override;
+ void SetStates(uint32_t dwStates, FX_BOOL bSet = TRUE) override;
+ FWL_Error DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
+ FWL_Error SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) override;
+
+ virtual FWL_Error SetText(const CFX_WideString& wsText);
+ virtual int32_t GetTextLength() const;
+ virtual FWL_Error GetText(CFX_WideString& wsText,
+ int32_t nStart = 0,
+ int32_t nCount = -1) const;
+ virtual FWL_Error ClearText();
+ virtual int32_t GetCaretPos() const;
+ virtual int32_t SetCaretPos(int32_t nIndex, FX_BOOL bBefore = TRUE);
+ virtual FWL_Error AddSelRange(int32_t nStart, int32_t nCount = -1);
+ virtual int32_t CountSelRanges();
+ virtual int32_t GetSelRange(int32_t nIndex, int32_t& nStart);
+ virtual FWL_Error ClearSelections();
+ virtual int32_t GetLimit();
+ virtual FWL_Error SetLimit(int32_t nLimit);
+ virtual FWL_Error SetAliasChar(FX_WCHAR wAlias);
+ virtual FWL_Error Insert(int32_t nStart,
+ const FX_WCHAR* lpText,
+ int32_t nLen);
+ virtual FWL_Error DeleteSelections();
+ virtual FWL_Error DeleteRange(int32_t nStart, int32_t nCount = -1);
+ virtual FWL_Error Replace(int32_t nStart,
+ int32_t nLen,
+ const CFX_WideStringC& wsReplace);
+ virtual FWL_Error DoClipboard(int32_t iCmd);
+ virtual FX_BOOL Copy(CFX_WideString& wsCopy);
+ virtual FX_BOOL Cut(CFX_WideString& wsCut);
+ virtual FX_BOOL Paste(const CFX_WideString& wsPaste);
+ virtual FX_BOOL Delete();
+ virtual FX_BOOL Redo(const IFDE_TxtEdtDoRecord* pRecord);
+ virtual FX_BOOL Undo(const IFDE_TxtEdtDoRecord* pRecord);
+ virtual FX_BOOL Undo();
+ virtual FX_BOOL Redo();
+ virtual FX_BOOL CanUndo();
+ virtual FX_BOOL CanRedo();
+ virtual FWL_Error SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant);
+ virtual FWL_Error SetOuter(IFWL_Widget* pOuter);
+ virtual FWL_Error SetNumberRange(int32_t iMin, int32_t iMax);
+ virtual FWL_Error SetBackgroundColor(uint32_t color);
+ virtual FWL_Error SetFont(const CFX_WideString& wsFont, FX_FLOAT fSize);
+
+ void On_CaretChanged(CFDE_TxtEdtEngine* pEdit,
+ int32_t nPage,
+ FX_BOOL bVisible = true);
+ void On_TextChanged(CFDE_TxtEdtEngine* pEdit,
+ FDE_TXTEDT_TEXTCHANGE_INFO& ChangeInfo);
+ void On_SelChanged(CFDE_TxtEdtEngine* pEdit);
+ FX_BOOL On_PageLoad(CFDE_TxtEdtEngine* pEdit,
+ int32_t nPageIndex,
+ int32_t nPurpose);
+ FX_BOOL On_PageUnload(CFDE_TxtEdtEngine* pEdit,
+ int32_t nPageIndex,
+ int32_t nPurpose);
+ void On_AddDoRecord(CFDE_TxtEdtEngine* pEdit, IFDE_TxtEdtDoRecord* pRecord);
+ FX_BOOL On_Validate(CFDE_TxtEdtEngine* pEdit, CFX_WideString& wsText);
+ void SetScrollOffset(FX_FLOAT fScrollOffset);
+ FX_BOOL GetSuggestWords(CFX_PointF pointf,
+ std::vector<CFX_ByteString>& sSuggest);
+ FX_BOOL ReplaceSpellCheckWord(CFX_PointF pointf,
+ const CFX_ByteStringC& bsReplace);
+
+ protected:
+ friend class CFWL_TxtEdtEventSink;
+ friend class CFWL_EditImpDelegate;
+
+ 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();
+ FX_BOOL UpdateOffset();
+ FX_BOOL UpdateOffset(IFWL_ScrollBar* pScrollBar, FX_FLOAT fPosChanged);
+ void UpdateVAlignment();
+ void UpdateCaret();
+ IFWL_ScrollBar* UpdateScroll();
+ void Layout();
+ void LayoutScrollBar();
+ void DeviceToEngine(CFX_PointF& pt);
+ void InitScrollBar(FX_BOOL bVert = TRUE);
+ void InitEngine();
+ virtual void ShowCaret(FX_BOOL bVisible, CFX_RectF* pRect = nullptr);
+ FX_BOOL ValidateNumberChar(FX_WCHAR cNum);
+ void InitCaret();
+ void ClearRecord();
+ FX_BOOL IsShowScrollBar(FX_BOOL bVert);
+ FX_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);
+ int32_t GetWordAtPoint(CFX_PointF pointf, int32_t& nCount);
+
+ CFX_RectF m_rtClient;
+ CFX_RectF m_rtEngine;
+ CFX_RectF m_rtStatic;
+ FX_FLOAT m_fVAlignOffset;
+ FX_FLOAT m_fScrollOffsetX;
+ FX_FLOAT m_fScrollOffsetY;
+ std::unique_ptr<CFDE_TxtEdtEngine> m_pEdtEngine;
+ FX_BOOL m_bLButtonDown;
+ int32_t m_nSelStart;
+ int32_t m_nLimit;
+ FX_FLOAT m_fSpaceAbove;
+ FX_FLOAT m_fSpaceBelow;
+ FX_FLOAT m_fFontSize;
+ FX_ARGB m_argbSel;
+ FX_BOOL m_bSetRange;
+ int32_t m_iMin;
+ int32_t m_iMax;
+ std::unique_ptr<IFWL_ScrollBar> m_pVertScrollBar;
+ std::unique_ptr<IFWL_ScrollBar> m_pHorzScrollBar;
+ std::unique_ptr<IFWL_Caret> m_pCaret;
+ CFX_WideString m_wsCache;
+ uint32_t m_backColor;
+ FX_BOOL m_updateBackColor;
+ CFX_WideString m_wsFont;
+ std::deque<std::unique_ptr<IFDE_TxtEdtDoRecord>> m_DoRecords;
+ int32_t m_iCurRecord;
+ int32_t m_iMaxRecord;
+};
+
+class CFWL_EditImpDelegate : public CFWL_WidgetImpDelegate {
+ public:
+ CFWL_EditImpDelegate(IFWL_Edit* pOwner);
+ void OnProcessMessage(CFWL_Message* pMessage) override;
+ void OnProcessEvent(CFWL_Event* pEvent) override;
+ void OnDrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
+
+ protected:
+ void DoActivate(CFWL_MsgActivate* pMsg);
+ void DoDeactivate(CFWL_MsgDeactivate* pMsg);
+ void DoButtonDown(CFWL_MsgMouse* pMsg);
+ void OnFocusChanged(CFWL_Message* pMsg, FX_BOOL bSet = TRUE);
+ 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);
+ FX_BOOL OnScroll(IFWL_ScrollBar* pScrollBar, uint32_t dwCode, FX_FLOAT fPos);
+ void DoCursor(CFWL_MsgMouse* pMsg);
+ IFWL_Edit* m_pOwner;
+};
+
+#endif // XFA_FWL_CORE_IFWL_EDIT_H_
diff --git a/xfa/fwl/core/fwl_formimp.cpp b/xfa/fwl/core/ifwl_form.cpp
index 0f4b89a774..ad78f98cb3 100644
--- a/xfa/fwl/core/fwl_formimp.cpp
+++ b/xfa/fwl/core/ifwl_form.cpp
@@ -4,18 +4,17 @@
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-#include "xfa/fwl/core/fwl_formimp.h"
+#include "xfa/fwl/core/ifwl_form.h"
#include "xfa/fde/tto/fde_textout.h"
-#include "xfa/fwl/basewidget/fwl_formproxyimp.h"
#include "xfa/fwl/core/cfwl_message.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/fwl_noteimp.h"
-#include "xfa/fwl/core/fwl_widgetimp.h"
#include "xfa/fwl/core/ifwl_app.h"
+#include "xfa/fwl/core/ifwl_formproxy.h"
#include "xfa/fwl/core/ifwl_themeprovider.h"
#include "xfa/fwl/theme/cfwl_widgettp.h"
@@ -33,43 +32,13 @@ const uint8_t kCornerEnlarge = 10;
} // namespace
-// static
-IFWL_Form* IFWL_Form::CreateFormProxy(CFWL_WidgetImpProperties& properties,
- CFX_WideString* classname,
- IFWL_Widget* pOuter) {
- IFWL_Form* pForm = new IFWL_Form;
- CFWL_FormProxyImp* pFormProxyImpl = new CFWL_FormProxyImp(properties, pOuter);
- pForm->SetImpl(pFormProxyImpl);
- pFormProxyImpl->SetInterface(pForm);
- return pForm;
-}
-IFWL_Form::IFWL_Form() {}
-FWL_FORMSIZE IFWL_Form::GetFormSize() {
- return static_cast<CFWL_FormImp*>(GetImpl())->GetFormSize();
-}
-FWL_Error IFWL_Form::SetFormSize(FWL_FORMSIZE eFormSize) {
- return static_cast<CFWL_FormImp*>(GetImpl())->SetFormSize(eFormSize);
-}
-IFWL_Widget* IFWL_Form::DoModal() {
- return static_cast<CFWL_FormImp*>(GetImpl())->DoModal();
-}
-IFWL_Widget* IFWL_Form::DoModal(uint32_t& dwCommandID) {
- return static_cast<CFWL_FormImp*>(GetImpl())->DoModal(dwCommandID);
-}
-FWL_Error IFWL_Form::EndDoModal() {
- return static_cast<CFWL_FormImp*>(GetImpl())->EndDoModal();
-}
-FWL_Error IFWL_Form::SetBorderRegion(CFX_Path* pPath) {
- return static_cast<CFWL_FormImp*>(GetImpl())->SetBorderRegion(pPath);
-}
-
-RestoreResizeInfo::RestoreResizeInfo() {}
+RestoreInfo::RestoreInfo() {}
-RestoreResizeInfo::~RestoreResizeInfo() {}
+RestoreInfo::~RestoreInfo() {}
-CFWL_FormImp::CFWL_FormImp(const CFWL_WidgetImpProperties& properties,
- IFWL_Widget* pOuter)
- : CFWL_WidgetImp(properties, pOuter),
+IFWL_Form::IFWL_Form(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter)
+ : IFWL_Widget(properties, pOuter),
m_pCloseBox(nullptr),
m_pMinBox(nullptr),
m_pMaxBox(nullptr),
@@ -96,41 +65,41 @@ CFWL_FormImp::CFWL_FormImp(const CFWL_WidgetImpProperties& properties,
m_rtIcon.Reset();
}
-CFWL_FormImp::~CFWL_FormImp() {
+IFWL_Form::~IFWL_Form() {
RemoveSysButtons();
}
-FWL_Error CFWL_FormImp::GetClassName(CFX_WideString& wsClass) const {
+FWL_Error IFWL_Form::GetClassName(CFX_WideString& wsClass) const {
wsClass = FWL_CLASS_Form;
return FWL_Error::Succeeded;
}
-FWL_Type CFWL_FormImp::GetClassID() const {
+FWL_Type IFWL_Form::GetClassID() const {
return FWL_Type::Form;
}
-FX_BOOL CFWL_FormImp::IsInstance(const CFX_WideStringC& wsClass) const {
+FX_BOOL IFWL_Form::IsInstance(const CFX_WideStringC& wsClass) const {
if (wsClass == CFX_WideStringC(FWL_CLASS_Form))
return TRUE;
- return CFWL_WidgetImp::IsInstance(wsClass);
+ return IFWL_Widget::IsInstance(wsClass);
}
-FWL_Error CFWL_FormImp::Initialize() {
- if (CFWL_WidgetImp::Initialize() != FWL_Error::Succeeded)
+FWL_Error IFWL_Form::Initialize() {
+ if (IFWL_Widget::Initialize() != FWL_Error::Succeeded)
return FWL_Error::Indefinite;
RegisterForm();
RegisterEventTarget();
m_pDelegate = new CFWL_FormImpDelegate(this);
return FWL_Error::Succeeded;
}
-FWL_Error CFWL_FormImp::Finalize() {
+FWL_Error IFWL_Form::Finalize() {
delete m_pDelegate;
m_pDelegate = nullptr;
UnregisterEventTarget();
UnRegisterForm();
- return CFWL_WidgetImp::Finalize();
+ return IFWL_Widget::Finalize();
}
-FWL_Error CFWL_FormImp::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
+FWL_Error IFWL_Form::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
if (bAutoSize) {
rect.Reset();
FX_FLOAT fCapHeight = GetCaptionHeight();
@@ -144,7 +113,7 @@ FWL_Error CFWL_FormImp::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
}
return FWL_Error::Succeeded;
}
-FWL_Error CFWL_FormImp::GetClientRect(CFX_RectF& rect) {
+FWL_Error IFWL_Form::GetClientRect(CFX_RectF& rect) {
if ((m_pProperties->m_dwStyles & FWL_WGTSTYLE_Caption) == 0) {
rect = m_pProperties->m_rtWidget;
rect.Offset(-rect.left, -rect.top);
@@ -166,7 +135,7 @@ FWL_Error CFWL_FormImp::GetClientRect(CFX_RectF& rect) {
IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
if (pTheme) {
CFWL_ThemePart part;
- part.m_pWidget = m_pInterface;
+ part.m_pWidget = this;
x = *static_cast<FX_FLOAT*>(
pTheme->GetCapacity(&part, CFWL_WidgetCapacity::CXBorder));
y = *static_cast<FX_FLOAT*>(
@@ -180,7 +149,7 @@ FWL_Error CFWL_FormImp::GetClientRect(CFX_RectF& rect) {
return FWL_Error::Succeeded;
#endif
}
-FWL_Error CFWL_FormImp::Update() {
+FWL_Error IFWL_Form::Update() {
if (m_iLock > 0) {
return FWL_Error::Succeeded;
}
@@ -198,7 +167,7 @@ FWL_Error CFWL_FormImp::Update() {
Layout();
return FWL_Error::Succeeded;
}
-FWL_WidgetHit CFWL_FormImp::HitTest(FX_FLOAT fx, FX_FLOAT fy) {
+FWL_WidgetHit IFWL_Form::HitTest(FX_FLOAT fx, FX_FLOAT fy) {
GetAvailableTheme();
if (m_pCloseBox && m_pCloseBox->m_rtBtn.Contains(fx, fy))
return FWL_WidgetHit::CloseBox;
@@ -250,8 +219,8 @@ FWL_WidgetHit CFWL_FormImp::HitTest(FX_FLOAT fx, FX_FLOAT fy) {
}
return FWL_WidgetHit::Client;
}
-FWL_Error CFWL_FormImp::DrawWidget(CFX_Graphics* pGraphics,
- const CFX_Matrix* pMatrix) {
+FWL_Error IFWL_Form::DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
if (!pGraphics)
return FWL_Error::Indefinite;
if (!m_pProperties->m_pThemeProvider)
@@ -266,7 +235,7 @@ FWL_Error CFWL_FormImp::DrawWidget(CFX_Graphics* pGraphics,
return FWL_Error::Succeeded;
#endif
CFWL_ThemeBackground param;
- param.m_pWidget = m_pInterface;
+ param.m_pWidget = this;
param.m_dwStates = iState;
param.m_pGraphics = pGraphics;
param.m_rtPart = m_rtRelative;
@@ -369,16 +338,16 @@ FWL_Error CFWL_FormImp::DrawWidget(CFX_Graphics* pGraphics,
return FWL_Error::Succeeded;
}
-FWL_FORMSIZE CFWL_FormImp::GetFormSize() {
+FWL_FORMSIZE IFWL_Form::GetFormSize() {
return m_eFormSize;
}
-FWL_Error CFWL_FormImp::SetFormSize(FWL_FORMSIZE eFormSize) {
+FWL_Error IFWL_Form::SetFormSize(FWL_FORMSIZE eFormSize) {
m_eFormSize = eFormSize;
return FWL_Error::Succeeded;
}
-IFWL_Widget* CFWL_FormImp::DoModal() {
+IFWL_Widget* IFWL_Form::DoModal() {
IFWL_App* pApp = GetOwnerApp();
if (!pApp)
return nullptr;
@@ -400,11 +369,11 @@ IFWL_Widget* CFWL_FormImp::DoModal() {
return nullptr;
}
-IFWL_Widget* CFWL_FormImp::DoModal(uint32_t& dwCommandID) {
+IFWL_Widget* IFWL_Form::DoModal(uint32_t& dwCommandID) {
return DoModal();
}
-FWL_Error CFWL_FormImp::EndDoModal() {
+FWL_Error IFWL_Form::EndDoModal() {
if (!m_pNoteLoop)
return FWL_Error::Indefinite;
m_bDoModalFlag = FALSE;
@@ -428,13 +397,13 @@ FWL_Error CFWL_FormImp::EndDoModal() {
#endif
}
-FWL_Error CFWL_FormImp::SetBorderRegion(CFX_Path* pPath) {
+FWL_Error IFWL_Form::SetBorderRegion(CFX_Path* pPath) {
return FWL_Error::Succeeded;
}
-void CFWL_FormImp::DrawBackground(CFX_Graphics* pGraphics,
- IFWL_ThemeProvider* pTheme) {
+void IFWL_Form::DrawBackground(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme) {
CFWL_ThemeBackground param;
- param.m_pWidget = m_pInterface;
+ param.m_pWidget = this;
param.m_iPart = CFWL_Part::Background;
param.m_pGraphics = pGraphics;
param.m_rtPart = m_rtRelative;
@@ -442,14 +411,14 @@ void CFWL_FormImp::DrawBackground(CFX_Graphics* pGraphics,
m_fCXBorder);
pTheme->DrawBackground(&param);
}
-CFWL_WidgetImp* CFWL_FormImp::GetSubFocus() {
+IFWL_Widget* IFWL_Form::GetSubFocus() {
return m_pSubFocus;
}
-void CFWL_FormImp::SetSubFocus(CFWL_WidgetImp* pWidget) {
+void IFWL_Form::SetSubFocus(IFWL_Widget* pWidget) {
m_pSubFocus = pWidget;
}
-void CFWL_FormImp::ShowChildWidget(IFWL_Widget* pParent) {
+void IFWL_Form::ShowChildWidget(IFWL_Widget* pParent) {
IFWL_App* pApp = FWL_GetApp();
if (!pApp)
return;
@@ -465,7 +434,7 @@ void CFWL_FormImp::ShowChildWidget(IFWL_Widget* pParent) {
}
}
-void CFWL_FormImp::RemoveSysButtons() {
+void IFWL_Form::RemoveSysButtons() {
m_rtCaption.Reset();
delete m_pCloseBox;
m_pCloseBox = nullptr;
@@ -477,7 +446,7 @@ void CFWL_FormImp::RemoveSysButtons() {
m_pCaptionBox = nullptr;
}
-void CFWL_FormImp::CalcContentRect(CFX_RectF& rtContent) {
+void IFWL_Form::CalcContentRect(CFX_RectF& rtContent) {
#ifdef FWL_UseMacSystemBorder
rtContent = m_rtRelative;
#else
@@ -488,7 +457,7 @@ void CFWL_FormImp::CalcContentRect(CFX_RectF& rtContent) {
}
#endif
}
-CFWL_SysBtn* CFWL_FormImp::GetSysBtnAtPoint(FX_FLOAT fx, FX_FLOAT fy) {
+CFWL_SysBtn* IFWL_Form::GetSysBtnAtPoint(FX_FLOAT fx, FX_FLOAT fy) {
if (m_pCloseBox && m_pCloseBox->m_rtBtn.Contains(fx, fy)) {
return m_pCloseBox;
}
@@ -503,7 +472,7 @@ CFWL_SysBtn* CFWL_FormImp::GetSysBtnAtPoint(FX_FLOAT fx, FX_FLOAT fy) {
}
return nullptr;
}
-CFWL_SysBtn* CFWL_FormImp::GetSysBtnByState(uint32_t dwState) {
+CFWL_SysBtn* IFWL_Form::GetSysBtnByState(uint32_t dwState) {
if (m_pCloseBox && (m_pCloseBox->m_dwState & dwState)) {
return m_pCloseBox;
}
@@ -518,7 +487,7 @@ CFWL_SysBtn* CFWL_FormImp::GetSysBtnByState(uint32_t dwState) {
}
return nullptr;
}
-CFWL_SysBtn* CFWL_FormImp::GetSysBtnByIndex(int32_t nIndex) {
+CFWL_SysBtn* IFWL_Form::GetSysBtnByIndex(int32_t nIndex) {
if (nIndex < 0)
return nullptr;
@@ -534,7 +503,7 @@ CFWL_SysBtn* CFWL_FormImp::GetSysBtnByIndex(int32_t nIndex) {
return arrBtn[nIndex];
}
-int32_t CFWL_FormImp::GetSysBtnIndex(CFWL_SysBtn* pBtn) {
+int32_t IFWL_Form::GetSysBtnIndex(CFWL_SysBtn* pBtn) {
CFX_ArrayTemplate<CFWL_SysBtn*> arrBtn;
if (m_pMinBox)
arrBtn.Add(m_pMinBox);
@@ -547,7 +516,7 @@ int32_t CFWL_FormImp::GetSysBtnIndex(CFWL_SysBtn* pBtn) {
return arrBtn.Find(pBtn);
}
-FX_FLOAT CFWL_FormImp::GetCaptionHeight() {
+FX_FLOAT IFWL_Form::GetCaptionHeight() {
CFWL_WidgetCapacity dwCapacity = CFWL_WidgetCapacity::None;
if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_Caption) {
@@ -562,17 +531,17 @@ FX_FLOAT CFWL_FormImp::GetCaptionHeight() {
}
return 0;
}
-void CFWL_FormImp::DrawCaptionText(CFX_Graphics* pGs,
- IFWL_ThemeProvider* pTheme,
- const CFX_Matrix* pMatrix) {
+void IFWL_Form::DrawCaptionText(CFX_Graphics* pGs,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix) {
CFX_WideString wsText;
IFWL_DataProvider* pData = m_pProperties->m_pDataProvider;
- pData->GetCaption(m_pInterface, wsText);
+ pData->GetCaption(this, wsText);
if (wsText.IsEmpty()) {
return;
}
CFWL_ThemeText textParam;
- textParam.m_pWidget = m_pInterface;
+ textParam.m_pWidget = this;
textParam.m_iPart = CFWL_Part::Caption;
textParam.m_dwStates = CFWL_PartState_Normal;
textParam.m_pGraphics = pGs;
@@ -596,23 +565,23 @@ void CFWL_FormImp::DrawCaptionText(CFX_Graphics* pGs,
: FDE_TTOALIGNMENT_CenterLeft;
pTheme->DrawText(&textParam);
}
-void CFWL_FormImp::DrawIconImage(CFX_Graphics* pGs,
- IFWL_ThemeProvider* pTheme,
- const CFX_Matrix* pMatrix) {
+void IFWL_Form::DrawIconImage(CFX_Graphics* pGs,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix) {
IFWL_FormDP* pData =
static_cast<IFWL_FormDP*>(m_pProperties->m_pDataProvider);
CFWL_ThemeBackground param;
- param.m_pWidget = m_pInterface;
+ param.m_pWidget = this;
param.m_iPart = CFWL_Part::Icon;
param.m_pGraphics = pGs;
- param.m_pImage = pData->GetIcon(m_pInterface, FALSE);
+ param.m_pImage = pData->GetIcon(this, FALSE);
param.m_rtPart = m_rtIcon;
if (pMatrix) {
param.m_matrix.Concat(*pMatrix);
}
pTheme->DrawBackground(&param);
}
-void CFWL_FormImp::GetEdgeRect(CFX_RectF& rtEdge) {
+void IFWL_Form::GetEdgeRect(CFX_RectF& rtEdge) {
rtEdge = m_rtRelative;
if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_Border) {
FX_FLOAT fCX = GetBorderSize();
@@ -620,7 +589,7 @@ void CFWL_FormImp::GetEdgeRect(CFX_RectF& rtEdge) {
rtEdge.Deflate(fCX, m_rtCaption.Height(), fCX, fCY);
}
}
-void CFWL_FormImp::SetWorkAreaRect() {
+void IFWL_Form::SetWorkAreaRect() {
m_rtRestore = m_pProperties->m_rtWidget;
CFWL_WidgetMgr* pWidgetMgr = CFWL_WidgetMgr::GetInstance();
if (!pWidgetMgr)
@@ -628,21 +597,21 @@ void CFWL_FormImp::SetWorkAreaRect() {
m_bSetMaximize = TRUE;
Repaint(&m_rtRelative);
}
-void CFWL_FormImp::SetCursor(FX_FLOAT fx, FX_FLOAT fy) {}
-void CFWL_FormImp::Layout() {
+void IFWL_Form::SetCursor(FX_FLOAT fx, FX_FLOAT fy) {}
+void IFWL_Form::Layout() {
GetRelativeRect(m_rtRelative);
#ifndef FWL_UseMacSystemBorder
ReSetSysBtn();
#endif
}
-void CFWL_FormImp::ReSetSysBtn() {
+void IFWL_Form::ReSetSysBtn() {
m_fCXBorder =
*static_cast<FX_FLOAT*>(GetThemeCapacity(CFWL_WidgetCapacity::CXBorder));
m_fCYBorder =
*static_cast<FX_FLOAT*>(GetThemeCapacity(CFWL_WidgetCapacity::CYBorder));
RemoveSysButtons();
IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
- m_bCustomizeLayout = pTheme->IsCustomizedLayout(m_pInterface);
+ m_bCustomizeLayout = pTheme->IsCustomizedLayout(this);
FX_FLOAT fCapHeight = GetCaptionHeight();
if (fCapHeight > 0) {
m_rtCaption = m_rtRelative;
@@ -695,14 +664,14 @@ void CFWL_FormImp::ReSetSysBtn() {
IFWL_FormDP* pData =
static_cast<IFWL_FormDP*>(m_pProperties->m_pDataProvider);
if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_Icon &&
- pData->GetIcon(m_pInterface, FALSE)) {
+ pData->GetIcon(this, FALSE)) {
if (!m_bCustomizeLayout) {
m_rtIcon.Set(5, (m_rtCaption.height - m_fSmallIconSz) / 2, m_fSmallIconSz,
m_fSmallIconSz);
}
}
}
-void CFWL_FormImp::RegisterForm() {
+void IFWL_Form::RegisterForm() {
IFWL_App* pApp = GetOwnerApp();
if (!pApp)
return;
@@ -714,7 +683,7 @@ void CFWL_FormImp::RegisterForm() {
pDriver->RegisterForm(this);
}
-void CFWL_FormImp::UnRegisterForm() {
+void IFWL_Form::UnRegisterForm() {
IFWL_App* pApp = GetOwnerApp();
if (!pApp)
return;
@@ -726,34 +695,34 @@ void CFWL_FormImp::UnRegisterForm() {
pDriver->UnRegisterForm(this);
}
-FX_BOOL CFWL_FormImp::IsDoModal() {
+FX_BOOL IFWL_Form::IsDoModal() {
return m_bDoModalFlag;
}
-void CFWL_FormImp::SetThemeData() {
+void IFWL_Form::SetThemeData() {
m_fSmallIconSz =
*static_cast<FX_FLOAT*>(GetThemeCapacity(CFWL_WidgetCapacity::SmallIcon));
m_fBigIconSz =
*static_cast<FX_FLOAT*>(GetThemeCapacity(CFWL_WidgetCapacity::BigIcon));
}
-FX_BOOL CFWL_FormImp::HasIcon() {
+FX_BOOL IFWL_Form::HasIcon() {
IFWL_FormDP* pData =
static_cast<IFWL_FormDP*>(m_pProperties->m_pDataProvider);
- return !!pData->GetIcon(m_pInterface, FALSE);
+ return !!pData->GetIcon(this, FALSE);
}
-void CFWL_FormImp::UpdateIcon() {
+void IFWL_Form::UpdateIcon() {
CFWL_WidgetMgr* pWidgetMgr = CFWL_WidgetMgr::GetInstance();
if (!pWidgetMgr)
return;
IFWL_FormDP* pData =
static_cast<IFWL_FormDP*>(m_pProperties->m_pDataProvider);
- CFX_DIBitmap* pBigIcon = pData->GetIcon(m_pInterface, TRUE);
- CFX_DIBitmap* pSmallIcon = pData->GetIcon(m_pInterface, FALSE);
+ CFX_DIBitmap* pBigIcon = pData->GetIcon(this, TRUE);
+ CFX_DIBitmap* pSmallIcon = pData->GetIcon(this, FALSE);
if (pBigIcon)
m_pBigIcon = pBigIcon;
if (pSmallIcon)
m_pSmallIcon = pSmallIcon;
}
-void CFWL_FormImp::UpdateCaption() {
+void IFWL_Form::UpdateCaption() {
CFWL_WidgetMgr* pWidgetMgr = CFWL_WidgetMgr::GetInstance();
if (!pWidgetMgr)
return;
@@ -761,15 +730,15 @@ void CFWL_FormImp::UpdateCaption() {
if (!pData)
return;
CFX_WideString text;
- pData->GetCaption(m_pInterface, text);
-}
-void CFWL_FormImp::DoWidthLimit(FX_FLOAT& fLeft,
- FX_FLOAT& fWidth,
- FX_FLOAT fCurX,
- FX_FLOAT fSpace,
- FX_FLOAT fLimitMin,
- FX_FLOAT fLimitMax,
- FX_BOOL bLeft) {
+ pData->GetCaption(this, text);
+}
+void IFWL_Form::DoWidthLimit(FX_FLOAT& fLeft,
+ FX_FLOAT& fWidth,
+ FX_FLOAT fCurX,
+ FX_FLOAT fSpace,
+ FX_FLOAT fLimitMin,
+ FX_FLOAT fLimitMax,
+ FX_BOOL bLeft) {
FX_FLOAT fx = fCurX;
FX_FLOAT fy = 0;
TransformTo(nullptr, fx, fy);
@@ -788,13 +757,13 @@ void CFWL_FormImp::DoWidthLimit(FX_FLOAT& fLeft,
}
}
}
-void CFWL_FormImp::DoHeightLimit(FX_FLOAT& fTop,
- FX_FLOAT& fHeight,
- FX_FLOAT fCurY,
- FX_FLOAT fSpace,
- FX_FLOAT fLimitMin,
- FX_FLOAT fLimitMax,
- FX_BOOL bTop) {
+void IFWL_Form::DoHeightLimit(FX_FLOAT& fTop,
+ FX_FLOAT& fHeight,
+ FX_FLOAT fCurY,
+ FX_FLOAT fSpace,
+ FX_FLOAT fLimitMin,
+ FX_FLOAT fLimitMax,
+ FX_BOOL bTop) {
FX_FLOAT fx = 0;
FX_FLOAT fy = fCurY;
TransformTo(nullptr, fx, fy);
@@ -813,7 +782,7 @@ void CFWL_FormImp::DoHeightLimit(FX_FLOAT& fTop,
}
}
-CFWL_FormImpDelegate::CFWL_FormImpDelegate(CFWL_FormImp* pOwner)
+CFWL_FormImpDelegate::CFWL_FormImpDelegate(IFWL_Form* pOwner)
: m_pOwner(pOwner) {}
#ifdef FWL_UseMacSystemBorder
@@ -847,9 +816,7 @@ void CFWL_FormImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
IFWL_App* pApp = m_pOwner->GetOwnerApp();
CFWL_NoteDriver* pDriver =
static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver());
- CFWL_WidgetImp* pSubFocusImp = m_pOwner->GetSubFocus();
- IFWL_Widget* pSubFocus =
- pSubFocusImp ? pSubFocusImp->GetInterface() : nullptr;
+ IFWL_Widget* pSubFocus = m_pOwner->GetSubFocus();
if (pSubFocus && pSubFocus != pDriver->GetFocus())
pDriver->SetFocus(pSubFocus);
@@ -861,9 +828,7 @@ void CFWL_FormImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
IFWL_App* pApp = m_pOwner->GetOwnerApp();
CFWL_NoteDriver* pDriver =
static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver());
- CFWL_WidgetImp* pSubFocusImp = m_pOwner->GetSubFocus();
- IFWL_Widget* pSubFocus =
- pSubFocusImp ? pSubFocusImp->GetInterface() : nullptr;
+ IFWL_Widget* pSubFocus = m_pOwner->GetSubFocus();
if (pSubFocus) {
if (pSubFocus == pDriver->GetFocus()) {
pDriver->SetFocus(nullptr);
@@ -914,7 +879,7 @@ void CFWL_FormImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
if (!pWidgetMgr)
return;
- pWidgetMgr->AddRedrawCounts(m_pOwner->m_pInterface);
+ pWidgetMgr->AddRedrawCounts(m_pOwner);
if (!m_pOwner->m_bSetMaximize)
break;
@@ -935,9 +900,7 @@ void CFWL_FormImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
OnClose(static_cast<CFWL_MsgClose*>(pMessage));
break;
}
- default: {
- break;
- }
+ default: { break; }
}
}
#endif // FWL_UseMacSystemBorder
@@ -1002,7 +965,7 @@ void CFWL_FormImpDelegate::OnLButtonUp(CFWL_MsgMouse* pMsg) {
m_pOwner->m_bMaximized = !m_pOwner->m_bMaximized;
} else if (pPressedBtn != m_pOwner->m_pMinBox) {
CFWL_EvtClose eClose;
- eClose.m_pSrcTarget = m_pOwner->m_pInterface;
+ eClose.m_pSrcTarget = m_pOwner;
m_pOwner->DispatchEvent(&eClose);
}
}
@@ -1100,7 +1063,7 @@ void CFWL_FormImpDelegate::OnWindowMove(CFWL_MsgWindowMove* pMsg) {
}
void CFWL_FormImpDelegate::OnClose(CFWL_MsgClose* pMsg) {
CFWL_EvtClose eClose;
- eClose.m_pSrcTarget = m_pOwner->m_pInterface;
+ eClose.m_pSrcTarget = m_pOwner;
m_pOwner->DispatchEvent(&eClose);
}
diff --git a/xfa/fwl/core/ifwl_form.h b/xfa/fwl/core/ifwl_form.h
index 860cbd679d..3aa38a00cd 100644
--- a/xfa/fwl/core/ifwl_form.h
+++ b/xfa/fwl/core/ifwl_form.h
@@ -7,6 +7,8 @@
#ifndef XFA_FWL_CORE_IFWL_FORM_H_
#define XFA_FWL_CORE_IFWL_FORM_H_
+#include <memory>
+
#include "core/fxcrt/fx_system.h"
#include "xfa/fwl/core/cfwl_widgetimpproperties.h"
#include "xfa/fwl/core/ifwl_dataprovider.h"
@@ -26,6 +28,10 @@
#define FWL_UseMacSystemBorder
#endif
+#define FWL_SYSBUTTONSTATE_Hover 0x0001
+#define FWL_SYSBUTTONSTATE_Pressed 0x0002
+#define FWL_SYSBUTTONSTATE_Disabled 0x0010
+
enum FWL_FORMSIZE {
FWL_FORMSIZE_Manual = 0,
FWL_FORMSIZE_Width,
@@ -33,11 +39,44 @@ enum FWL_FORMSIZE {
FWL_FORMSIZE_All,
};
-class CFX_DIBitmap;
-class CFX_WideString;
-class CFX_Path;
+class CFWL_SysBtn {
+ public:
+ CFWL_SysBtn();
+
+ bool IsDisabled() const;
+ uint32_t GetPartState() const;
+
+ void SetNormal();
+ void SetPressed();
+ void SetHover();
+ void SetDisabled(FX_BOOL bDisabled);
+
+ CFX_RectF m_rtBtn;
+ uint32_t m_dwState;
+};
+
+enum FORM_RESIZETYPE {
+ FORM_RESIZETYPE_None = 0,
+ FORM_RESIZETYPE_Cap,
+};
+
+struct RestoreInfo {
+ RestoreInfo();
+ ~RestoreInfo();
+
+ CFX_PointF m_ptStart;
+ CFX_SizeF m_szStart;
+};
+
+class CFWL_MsgMouse;
+class CFWL_MsgClose;
+class CFWL_MsgWindowMove;
+class CFWL_NoteLoop;
+class CFWL_WidgetImpProperties;
class IFWL_Widget;
-class IFWL_Form;
+class IFWL_ThemeProvider;
+class CFWL_SysBtn;
+class CFWL_FormImpDelegate;
class IFWL_FormDP : public IFWL_DataProvider {
public:
@@ -46,9 +85,22 @@ class IFWL_FormDP : public IFWL_DataProvider {
class IFWL_Form : public IFWL_Widget {
public:
- static IFWL_Form* CreateFormProxy(CFWL_WidgetImpProperties& properties,
- CFX_WideString* classname,
- IFWL_Widget* pOuter);
+ IFWL_Form(const CFWL_WidgetImpProperties& properties, IFWL_Widget* pOuter);
+ ~IFWL_Form() override;
+
+ // IFWL_Widget
+ FWL_Error GetClassName(CFX_WideString& wsClass) const override;
+ FWL_Type GetClassID() const override;
+ FX_BOOL IsInstance(const CFX_WideStringC& wsClass) const override;
+ FWL_Error Initialize() override;
+ FWL_Error Finalize() override;
+
+ FWL_Error GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize = FALSE) override;
+ FWL_Error GetClientRect(CFX_RectF& rect) override;
+ FWL_Error Update() override;
+ FWL_WidgetHit HitTest(FX_FLOAT fx, FX_FLOAT fy) override;
+ FWL_Error DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
FWL_FORMSIZE GetFormSize();
FWL_Error SetFormSize(FWL_FORMSIZE eFormSize);
@@ -56,9 +108,102 @@ class IFWL_Form : public IFWL_Widget {
IFWL_Widget* DoModal(uint32_t& dwCommandID);
FWL_Error EndDoModal();
FWL_Error SetBorderRegion(CFX_Path* pPath);
+ void DrawBackground(CFX_Graphics* pGraphics, IFWL_ThemeProvider* pTheme);
+ IFWL_Widget* GetSubFocus();
+ void SetSubFocus(IFWL_Widget* pWidget);
+
+ protected:
+ friend class CFWL_FormImpDelegate;
+
+ void ShowChildWidget(IFWL_Widget* pParent);
+ void RemoveSysButtons();
+ void CalcContentRect(CFX_RectF& rtContent);
+ CFWL_SysBtn* GetSysBtnAtPoint(FX_FLOAT fx, FX_FLOAT fy);
+ CFWL_SysBtn* GetSysBtnByState(uint32_t dwState);
+ CFWL_SysBtn* GetSysBtnByIndex(int32_t nIndex);
+ int32_t GetSysBtnIndex(CFWL_SysBtn* pBtn);
+ FX_FLOAT GetCaptionHeight();
+ void DrawCaptionText(CFX_Graphics* pGs,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix = nullptr);
+ void DrawIconImage(CFX_Graphics* pGs,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix = nullptr);
+ void GetEdgeRect(CFX_RectF& rtEdge);
+ void SetWorkAreaRect();
+ void SetCursor(FX_FLOAT fx, FX_FLOAT fy);
+ void Layout();
+ void ReSetSysBtn();
+ void RegisterForm();
+ void UnRegisterForm();
+ FX_BOOL IsDoModal();
+ void SetThemeData();
+ FX_BOOL HasIcon();
+ void UpdateIcon();
+ void UpdateCaption();
+ void DoWidthLimit(FX_FLOAT& fLeft,
+ FX_FLOAT& fWidth,
+ FX_FLOAT fCurX,
+ FX_FLOAT fSpace,
+ FX_FLOAT fLimitMin,
+ FX_FLOAT fLimitMax,
+ FX_BOOL bLeft);
+ void DoHeightLimit(FX_FLOAT& fTop,
+ FX_FLOAT& fHeight,
+ FX_FLOAT fCurY,
+ FX_FLOAT fSpace,
+ FX_FLOAT fLimitMin,
+ FX_FLOAT fLimitMax,
+ FX_BOOL bTop);
+
+ CFX_RectF m_rtRestore;
+ CFX_RectF m_rtCaptionText;
+ CFX_RectF m_rtRelative;
+ CFX_RectF m_rtCaption;
+ CFX_RectF m_rtIcon;
+ CFWL_SysBtn* m_pCloseBox;
+ CFWL_SysBtn* m_pMinBox;
+ CFWL_SysBtn* m_pMaxBox;
+ CFWL_SysBtn* m_pCaptionBox;
+ std::unique_ptr<CFWL_NoteLoop> m_pNoteLoop;
+ IFWL_Widget* m_pSubFocus;
+ RestoreInfo m_InfoStart;
+ FX_FLOAT m_fCXBorder;
+ FX_FLOAT m_fCYBorder;
+ int32_t m_iCaptureBtn;
+ int32_t m_iSysBox;
+ int32_t m_eResizeType;
+ FX_BOOL m_bLButtonDown;
+ bool m_bMaximized;
+ FX_BOOL m_bSetMaximize;
+ FX_BOOL m_bCustomizeLayout;
+ FWL_FORMSIZE m_eFormSize;
+ FX_BOOL m_bDoModalFlag;
+ FX_FLOAT m_fSmallIconSz;
+ FX_FLOAT m_fBigIconSz;
+ CFX_DIBitmap* m_pBigIcon;
+ CFX_DIBitmap* m_pSmallIcon;
+ FX_BOOL m_bMouseIn;
+};
+
+class CFWL_FormImpDelegate : public CFWL_WidgetImpDelegate {
+ public:
+ CFWL_FormImpDelegate(IFWL_Form* pOwner);
+ void OnProcessMessage(CFWL_Message* pMessage) override;
+ void OnProcessEvent(CFWL_Event* pEvent) override;
+ void OnDrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
protected:
- IFWL_Form();
+ void OnLButtonDown(CFWL_MsgMouse* pMsg);
+ void OnLButtonUp(CFWL_MsgMouse* pMsg);
+ void OnMouseMove(CFWL_MsgMouse* pMsg);
+ void OnMouseHover(CFWL_MsgMouse* pMsg);
+ void OnMouseLeave(CFWL_MsgMouse* pMsg);
+ void OnLButtonDblClk(CFWL_MsgMouse* pMsg);
+ void OnWindowMove(CFWL_MsgWindowMove* pMsg);
+ void OnClose(CFWL_MsgClose* pMsg);
+ IFWL_Form* m_pOwner;
};
#endif // XFA_FWL_CORE_IFWL_FORM_H_
diff --git a/xfa/fwl/core/ifwl_formproxy.cpp b/xfa/fwl/core/ifwl_formproxy.cpp
new file mode 100644
index 0000000000..123db79f19
--- /dev/null
+++ b/xfa/fwl/core/ifwl_formproxy.cpp
@@ -0,0 +1,67 @@
+// 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_formproxy.h"
+
+#include "xfa/fwl/core/fwl_noteimp.h"
+
+// static
+IFWL_FormProxy* IFWL_FormProxy::Create(CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter) {
+ return new IFWL_FormProxy(properties, pOuter);
+}
+
+IFWL_FormProxy::IFWL_FormProxy(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter)
+ : IFWL_Form(properties, pOuter) {}
+
+IFWL_FormProxy::~IFWL_FormProxy() {}
+
+FWL_Error IFWL_FormProxy::GetClassName(CFX_WideString& wsClass) const {
+ wsClass = FWL_CLASS_FormProxy;
+ return FWL_Error::Succeeded;
+}
+
+FWL_Type IFWL_FormProxy::GetClassID() const {
+ return FWL_Type::FormProxy;
+}
+
+FX_BOOL IFWL_FormProxy::IsInstance(const CFX_WideStringC& wsClass) const {
+ if (wsClass == CFX_WideStringC(FWL_CLASS_FormProxy)) {
+ return TRUE;
+ }
+ return IFWL_Form::IsInstance(wsClass);
+}
+
+FWL_Error IFWL_FormProxy::Initialize() {
+ if (IFWL_Widget::Initialize() != FWL_Error::Succeeded)
+ return FWL_Error::Indefinite;
+ m_pDelegate = new CFWL_FormProxyImpDelegate(this);
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_FormProxy::Finalize() {
+ delete m_pDelegate;
+ m_pDelegate = nullptr;
+ return IFWL_Widget::Finalize();
+}
+
+FWL_Error IFWL_FormProxy::Update() {
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_FormProxy::DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ return FWL_Error::Succeeded;
+}
+
+CFWL_FormProxyImpDelegate::CFWL_FormProxyImpDelegate(IFWL_FormProxy* pOwner)
+ : m_pOwner(pOwner) {}
+
+void CFWL_FormProxyImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
+ IFWL_WidgetDelegate* pDelegate = m_pOwner->m_pOuter->SetDelegate(nullptr);
+ pDelegate->OnProcessMessage(pMessage);
+}
diff --git a/xfa/fwl/core/ifwl_formproxy.h b/xfa/fwl/core/ifwl_formproxy.h
new file mode 100644
index 0000000000..c188d93a05
--- /dev/null
+++ b/xfa/fwl/core/ifwl_formproxy.h
@@ -0,0 +1,47 @@
+// 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_FORMPROXY_H_
+#define XFA_FWL_CORE_IFWL_FORMPROXY_H_
+
+#include "xfa/fwl/core/ifwl_form.h"
+
+class CFWL_WidgetImpProperties;
+class CFWL_FormProxyImpDelegate;
+
+class IFWL_FormProxy : public IFWL_Form {
+ public:
+ static IFWL_FormProxy* Create(CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+
+ IFWL_FormProxy(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+ ~IFWL_FormProxy() override;
+
+ // IFWL_Widget
+ FWL_Error GetClassName(CFX_WideString& wsClass) const override;
+ FWL_Type GetClassID() const override;
+ FX_BOOL IsInstance(const CFX_WideStringC& wsClass) const override;
+ FWL_Error Initialize() override;
+ FWL_Error Finalize() override;
+ FWL_Error Update() override;
+ FWL_Error DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
+
+ protected:
+ friend class CFWL_FormProxyImpDelegate;
+};
+
+class CFWL_FormProxyImpDelegate : public CFWL_WidgetImpDelegate {
+ public:
+ CFWL_FormProxyImpDelegate(IFWL_FormProxy* pOwner);
+ void OnProcessMessage(CFWL_Message* pMessage) override;
+
+ protected:
+ IFWL_FormProxy* m_pOwner;
+};
+
+#endif // XFA_FWL_CORE_IFWL_FORMPROXY_H_
diff --git a/xfa/fwl/core/ifwl_listbox.cpp b/xfa/fwl/core/ifwl_listbox.cpp
new file mode 100644
index 0000000000..a0a9eacd27
--- /dev/null
+++ b/xfa/fwl/core/ifwl_listbox.cpp
@@ -0,0 +1,1218 @@
+// 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 "xfa/fde/tto/fde_textout.h"
+#include "xfa/fwl/core/cfwl_message.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_app.h"
+#include "xfa/fwl/core/ifwl_themeprovider.h"
+
+namespace {
+
+const int kItemTextMargin = 2;
+
+} // namespace
+
+// static
+IFWL_ListBox* IFWL_ListBox::Create(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter) {
+ return new IFWL_ListBox(properties, pOuter);
+}
+
+IFWL_ListBox::IFWL_ListBox(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter)
+ : IFWL_Widget(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_Error IFWL_ListBox::GetClassName(CFX_WideString& wsClass) const {
+ wsClass = FWL_CLASS_ListBox;
+ return FWL_Error::Succeeded;
+}
+
+FWL_Type IFWL_ListBox::GetClassID() const {
+ return FWL_Type::ListBox;
+}
+
+FWL_Error IFWL_ListBox::Initialize() {
+ if (IFWL_Widget::Initialize() != FWL_Error::Succeeded)
+ return FWL_Error::Indefinite;
+
+ m_pDelegate = new CFWL_ListBoxImpDelegate(this);
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_ListBox::Finalize() {
+ if (m_pVertScrollBar) {
+ m_pVertScrollBar->Finalize();
+ }
+ if (m_pHorzScrollBar) {
+ m_pHorzScrollBar->Finalize();
+ }
+ delete m_pDelegate;
+ m_pDelegate = nullptr;
+ return IFWL_Widget::Finalize();
+}
+
+FWL_Error IFWL_ListBox::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
+ if (bAutoSize) {
+ 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);
+ } else {
+ rect = m_pProperties->m_rtWidget;
+ }
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_ListBox::Update() {
+ if (IsLocked()) {
+ return FWL_Error::Indefinite;
+ }
+ if (!m_pProperties->m_pThemeProvider) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ m_iTTOAligns = FDE_TTOALIGNMENT_Center;
+ 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; }
+ }
+ if (m_pProperties->m_dwStyleExes & FWL_WGTSTYLE_RTLReading) {
+ m_dwTTOStyles |= FDE_TTOSTYLE_RTL;
+ }
+ m_dwTTOStyles |= FDE_TTOSTYLE_SingleLine;
+ m_fScorllBarWidth = GetScrollWidth();
+ CalcSize();
+ return FWL_Error::Succeeded;
+}
+
+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;
+}
+
+FWL_Error IFWL_ListBox::DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ if (!pGraphics)
+ return FWL_Error::Indefinite;
+ if (!m_pProperties->m_pThemeProvider)
+ return FWL_Error::Indefinite;
+ IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
+ 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();
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_ListBox::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) {
+ if (!pThemeProvider)
+ return FWL_Error::Indefinite;
+ m_pProperties->m_pThemeProvider = pThemeProvider;
+ return FWL_Error::Succeeded;
+}
+int32_t IFWL_ListBox::CountSelItems() {
+ if (!m_pProperties->m_pDataProvider)
+ return 0;
+ int32_t iRet = 0;
+ IFWL_ListBoxDP* pData =
+ static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
+ int32_t iCount = pData->CountItems(this);
+ for (int32_t i = 0; i < iCount; i++) {
+ IFWL_ListItem* pItem = pData->GetItem(this, i);
+ if (!pItem) {
+ continue;
+ }
+ uint32_t dwStyle = pData->GetItemStyles(this, pItem);
+ if (dwStyle & FWL_ITEMSTATE_LTB_Selected) {
+ iRet++;
+ }
+ }
+ return iRet;
+}
+
+IFWL_ListItem* IFWL_ListBox::GetSelItem(int32_t nIndexSel) {
+ if (!m_pProperties->m_pDataProvider)
+ return nullptr;
+ int32_t index = 0;
+ IFWL_ListBoxDP* pData =
+ static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
+ int32_t iCount = pData->CountItems(this);
+ for (int32_t i = 0; i < iCount; i++) {
+ IFWL_ListItem* pItem = pData->GetItem(this, i);
+ if (!pItem) {
+ return nullptr;
+ }
+ uint32_t dwStyle = pData->GetItemStyles(this, pItem);
+ if (dwStyle & FWL_ITEMSTATE_LTB_Selected) {
+ if (index == nIndexSel) {
+ return pItem;
+ } else {
+ index++;
+ }
+ }
+ }
+ return nullptr;
+}
+
+int32_t IFWL_ListBox::GetSelIndex(int32_t nIndex) {
+ if (!m_pProperties->m_pDataProvider)
+ return -1;
+ int32_t index = 0;
+ IFWL_ListBoxDP* pData =
+ static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
+ int32_t iCount = pData->CountItems(this);
+ for (int32_t i = 0; i < iCount; i++) {
+ IFWL_ListItem* pItem = pData->GetItem(this, i);
+ if (!pItem) {
+ return -1;
+ }
+ uint32_t dwStyle = pData->GetItemStyles(this, pItem);
+ if (dwStyle & FWL_ITEMSTATE_LTB_Selected) {
+ if (index == nIndex) {
+ return i;
+ } else {
+ index++;
+ }
+ }
+ }
+ return -1;
+}
+
+FWL_Error IFWL_ListBox::SetSelItem(IFWL_ListItem* pItem, FX_BOOL bSelect) {
+ if (!m_pProperties->m_pDataProvider)
+ return FWL_Error::Indefinite;
+ if (!pItem) {
+ if (bSelect) {
+ SelectAll();
+ } else {
+ ClearSelection();
+ SetFocusItem(nullptr);
+ }
+ return FWL_Error::Indefinite;
+ }
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiSelection) {
+ SetSelectionDirect(pItem, bSelect);
+ } else {
+ SetSelection(pItem, pItem, bSelect);
+ }
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_ListBox::GetItemText(IFWL_ListItem* pItem,
+ CFX_WideString& wsText) {
+ if (!m_pProperties->m_pDataProvider)
+ return FWL_Error::Indefinite;
+ IFWL_ListBoxDP* pData =
+ static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
+ if (!pItem)
+ return FWL_Error::Indefinite;
+ pData->GetItemText(this, pItem, wsText);
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_ListBox::GetScrollPos(FX_FLOAT& fPos, FX_BOOL bVert) {
+ if ((bVert && IsShowScrollBar(TRUE)) || (!bVert && IsShowScrollBar(FALSE))) {
+ IFWL_ScrollBar* pScrollBar =
+ bVert ? m_pVertScrollBar.get() : m_pHorzScrollBar.get();
+ fPos = pScrollBar->GetPos();
+ return FWL_Error::Succeeded;
+ }
+ return FWL_Error::Indefinite;
+}
+
+IFWL_ListItem* IFWL_ListBox::GetItem(IFWL_ListItem* pItem, uint32_t dwKeyCode) {
+ IFWL_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;
+ IFWL_ListBoxDP* pData =
+ static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
+ int32_t iDstItem = -1;
+ if (bUp || bDown) {
+ int32_t index = pData->GetItemIndex(this, pItem);
+ iDstItem = dwKeyCode == FWL_VKEY_Up ? index - 1 : index + 1;
+ } else if (bHome) {
+ iDstItem = 0;
+ } else {
+ int32_t iCount = pData->CountItems(this);
+ iDstItem = iCount - 1;
+ }
+ hRet = pData->GetItem(this, iDstItem);
+ break;
+ }
+ default: {}
+ }
+ return hRet;
+}
+
+void IFWL_ListBox::SetSelection(IFWL_ListItem* hStart,
+ IFWL_ListItem* hEnd,
+ FX_BOOL bSelected) {
+ IFWL_ListBoxDP* pData =
+ static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
+ int32_t iStart = pData->GetItemIndex(this, hStart);
+ int32_t iEnd = pData->GetItemIndex(this, hEnd);
+ if (iStart > iEnd) {
+ int32_t iTemp = iStart;
+ iStart = iEnd;
+ iEnd = iTemp;
+ }
+ if (bSelected) {
+ int32_t iCount = pData->CountItems(this);
+ for (int32_t i = 0; i < iCount; i++) {
+ IFWL_ListItem* pItem = pData->GetItem(this, i);
+ SetSelectionDirect(pItem, FALSE);
+ }
+ }
+ for (; iStart <= iEnd; iStart++) {
+ IFWL_ListItem* pItem = pData->GetItem(this, iStart);
+ SetSelectionDirect(pItem, bSelected);
+ }
+}
+
+void IFWL_ListBox::SetSelectionDirect(IFWL_ListItem* pItem, FX_BOOL bSelect) {
+ IFWL_ListBoxDP* pData =
+ static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
+ uint32_t dwOldStyle = pData->GetItemStyles(this, pItem);
+ bSelect ? dwOldStyle |= FWL_ITEMSTATE_LTB_Selected
+ : dwOldStyle &= ~FWL_ITEMSTATE_LTB_Selected;
+ pData->SetItemStyles(this, pItem, dwOldStyle);
+}
+
+FX_BOOL IFWL_ListBox::IsItemSelected(IFWL_ListItem* pItem) {
+ IFWL_ListBoxDP* pData =
+ static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
+ uint32_t dwState = pData->GetItemStyles(this, pItem);
+ return (dwState & FWL_ITEMSTATE_LTB_Selected) != 0;
+}
+
+void IFWL_ListBox::ClearSelection() {
+ FX_BOOL bMulti =
+ m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiSelection;
+ IFWL_ListBoxDP* pData =
+ static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
+ int32_t iCount = pData->CountItems(this);
+ for (int32_t i = 0; i < iCount; i++) {
+ IFWL_ListItem* pItem = pData->GetItem(this, i);
+ uint32_t dwState = pData->GetItemStyles(this, pItem);
+ if (!(dwState & FWL_ITEMSTATE_LTB_Selected))
+ continue;
+ SetSelectionDirect(pItem, FALSE);
+ if (!bMulti)
+ return;
+ }
+}
+
+void IFWL_ListBox::SelectAll() {
+ FX_BOOL bMulti =
+ m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiSelection;
+ if (!bMulti) {
+ return;
+ }
+ IFWL_ListBoxDP* pData =
+ static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
+ int32_t iCount = pData->CountItems(this);
+ if (iCount > 0) {
+ IFWL_ListItem* pItemStart = pData->GetItem(this, 0);
+ IFWL_ListItem* pItemEnd = pData->GetItem(this, iCount - 1);
+ SetSelection(pItemStart, pItemEnd, FALSE);
+ }
+}
+
+IFWL_ListItem* IFWL_ListBox::GetFocusedItem() {
+ IFWL_ListBoxDP* pData =
+ static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
+ int32_t iCount = pData->CountItems(this);
+ for (int32_t i = 0; i < iCount; i++) {
+ IFWL_ListItem* pItem = pData->GetItem(this, i);
+ if (!pItem)
+ return nullptr;
+ if (pData->GetItemStyles(this, pItem) & FWL_ITEMSTATE_LTB_Focused) {
+ return pItem;
+ }
+ }
+ return nullptr;
+}
+
+void IFWL_ListBox::SetFocusItem(IFWL_ListItem* pItem) {
+ IFWL_ListBoxDP* pData =
+ static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
+ IFWL_ListItem* hFocus = GetFocusedItem();
+ if (pItem != hFocus) {
+ if (hFocus) {
+ uint32_t dwStyle = pData->GetItemStyles(this, hFocus);
+ dwStyle &= ~FWL_ITEMSTATE_LTB_Focused;
+ pData->SetItemStyles(this, hFocus, dwStyle);
+ }
+ if (pItem) {
+ uint32_t dwStyle = pData->GetItemStyles(this, pItem);
+ dwStyle |= FWL_ITEMSTATE_LTB_Focused;
+ pData->SetItemStyles(this, pItem, dwStyle);
+ }
+ }
+}
+
+IFWL_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();
+ }
+ IFWL_ListBoxDP* pData =
+ static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
+ int32_t nCount = pData->CountItems(this);
+ for (int32_t i = 0; i < nCount; i++) {
+ IFWL_ListItem* pItem = pData->GetItem(this, i);
+ if (!pItem) {
+ continue;
+ }
+ CFX_RectF rtItem;
+ pData->GetItemRect(this, pItem, rtItem);
+ rtItem.Offset(-fPosX, -fPosY);
+ if (rtItem.Contains(fx, fy)) {
+ return pItem;
+ }
+ }
+ return nullptr;
+}
+
+FX_BOOL IFWL_ListBox::GetItemCheckRect(IFWL_ListItem* pItem,
+ CFX_RectF& rtCheck) {
+ if (!m_pProperties->m_pDataProvider)
+ return FALSE;
+ if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_Check)) {
+ return FALSE;
+ }
+ IFWL_ListBoxDP* pData =
+ static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
+ pData->GetItemCheckRect(this, pItem, rtCheck);
+ return TRUE;
+}
+
+FX_BOOL IFWL_ListBox::GetItemChecked(IFWL_ListItem* pItem) {
+ if (!m_pProperties->m_pDataProvider)
+ return FALSE;
+ if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_Check)) {
+ return FALSE;
+ }
+ IFWL_ListBoxDP* pData =
+ static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
+ return (pData->GetItemCheckState(this, pItem) & FWL_ITEMSTATE_LTB_Checked);
+}
+
+FX_BOOL IFWL_ListBox::SetItemChecked(IFWL_ListItem* pItem, FX_BOOL bChecked) {
+ if (!m_pProperties->m_pDataProvider)
+ return FALSE;
+ if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_Check)) {
+ return FALSE;
+ }
+ IFWL_ListBoxDP* pData =
+ static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
+ pData->SetItemCheckState(this, pItem,
+ bChecked ? FWL_ITEMSTATE_LTB_Checked : 0);
+ return TRUE;
+}
+
+FX_BOOL IFWL_ListBox::ScrollToVisible(IFWL_ListItem* pItem) {
+ if (!m_pVertScrollBar)
+ return FALSE;
+ CFX_RectF rtItem;
+ IFWL_ListBoxDP* pData =
+ static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
+ pData->GetItemRect(this, pItem, rtItem);
+ FX_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;
+ }
+ FX_BOOL bMultiCol =
+ m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiColumn;
+ IFWL_ListBoxDP* pData =
+ static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
+ int32_t iCount = pData->CountItems(this);
+ for (int32_t i = 0; i < iCount; i++) {
+ IFWL_ListItem* pItem = pData->GetItem(this, i);
+ if (!pItem) {
+ continue;
+ }
+ CFX_RectF rtItem;
+ pData->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) {
+ CFWL_EvtLtbDrawItem ev;
+ ev.m_pSrcTarget = this;
+ ev.m_pGraphics = pGraphics;
+ ev.m_matrix = *pMatrix;
+ ev.m_index = i;
+ ev.m_rect = rtItem;
+ DispatchEvent(&ev);
+ } else {
+ DrawItem(pGraphics, pTheme, pItem, i, rtItem, pMatrix);
+ }
+ }
+}
+
+void IFWL_ListBox::DrawItem(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ IFWL_ListItem* pItem,
+ int32_t Index,
+ const CFX_RectF& rtItem,
+ const CFX_Matrix* pMatrix) {
+ IFWL_ListBoxDP* pData =
+ static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
+ uint32_t dwItemStyles = pData->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 param;
+ param.m_pWidget = this;
+ param.m_iPart = CFWL_Part::ListItem;
+ param.m_dwStates = dwPartStates;
+ param.m_pGraphics = pGraphics;
+ param.m_matrix.Concat(*pMatrix);
+ param.m_rtPart = rtItem;
+ param.m_bMaximize = true;
+ CFX_RectF rtFocus(rtItem);
+ param.m_pData = &rtFocus;
+ if (m_pVertScrollBar && !m_pHorzScrollBar &&
+ (dwPartStates & CFWL_PartState_Focused)) {
+ param.m_rtPart.left += 1;
+ param.m_rtPart.width -= (m_fScorllBarWidth + 1);
+ rtFocus.Deflate(0.5, 0.5, 1 + m_fScorllBarWidth, 1);
+ }
+ pTheme->DrawBackground(&param);
+ }
+ {
+ FX_BOOL bHasIcon = GetStylesEx() & FWL_STYLEEXT_LTB_Icon;
+ if (bHasIcon) {
+ CFX_RectF rtDIB;
+ CFX_DIBitmap* pDib = pData->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);
+ }
+ }
+ FX_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);
+ pData->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;
+ pData->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(FX_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 = 0;
+ if (m_pProperties->m_pThemeProvider->IsCustomizedLayout(this)) {
+ IFWL_ListBoxDP* pData =
+ static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
+ int32_t iCount = pData->CountItems(this);
+ for (int32_t i = 0; i < iCount; i++) {
+ IFWL_ListItem* pItem = pData->GetItem(this, i);
+ if (!bAutoSize) {
+ CFX_RectF rtItem;
+ rtItem.Set(m_rtClient.left, m_rtClient.top + fs.y, 0, 0);
+ IFWL_ListBoxDP* pBox =
+ static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
+ pBox->SetItemRect(this, pItem, rtItem);
+ }
+ if (fs.x < 0) {
+ fs.x = 0;
+ fWidth = 0;
+ }
+ }
+ } else {
+ fWidth = GetMaxTextWidth();
+ fWidth += 2 * kItemTextMargin;
+ if (!bAutoSize) {
+ FX_FLOAT fActualWidth =
+ m_rtClient.width - rtUIMargin.left - rtUIMargin.width;
+ if (fWidth < fActualWidth) {
+ fWidth = fActualWidth;
+ }
+ }
+ IFWL_ListBoxDP* pData =
+ static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
+ m_fItemHeight = GetItemHeigt();
+ FX_BOOL bHasIcon;
+ bHasIcon = GetStylesEx() & FWL_STYLEEXT_LTB_Icon;
+ if (bHasIcon) {
+ fWidth += m_fItemHeight;
+ }
+ int32_t iCount = pData->CountItems(this);
+ for (int32_t i = 0; i < iCount; i++) {
+ IFWL_ListItem* htem = pData->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;
+ FX_BOOL bShowVertScr =
+ (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_ShowScrollBarAlaways) &&
+ (m_pProperties->m_dwStyles & FWL_WGTSTYLE_VScroll);
+ FX_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;
+ if (szRange.y < m_fItemHeight) {
+ 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 = m_pVertScrollBar->GetPos();
+ if (fPos < 0) {
+ fPos = 0;
+ }
+ if (fPos > szRange.y) {
+ fPos = 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 = m_pHorzScrollBar->GetPos();
+ if (fPos < 0) {
+ fPos = 0;
+ }
+ if (fPos > szRange.y) {
+ fPos = 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,
+ IFWL_ListItem* pItem,
+ FX_FLOAT fWidth,
+ FX_FLOAT fItemHeight,
+ FX_BOOL bAutoSize) {
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiColumn) {
+ } else {
+ if (!bAutoSize) {
+ CFX_RectF rtItem;
+ rtItem.Set(0, size.y, fWidth, fItemHeight);
+ IFWL_ListBoxDP* pData =
+ static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
+ pData->SetItemRect(this, pItem, rtItem);
+ }
+ size.x = fWidth;
+ size.y += fItemHeight;
+ }
+}
+
+FX_FLOAT IFWL_ListBox::GetMaxTextWidth() {
+ FX_FLOAT fRet = 0.0f;
+ IFWL_ListBoxDP* pData =
+ static_cast<IFWL_ListBoxDP*>(m_pProperties->m_pDataProvider);
+ int32_t iCount = pData->CountItems(this);
+ for (int32_t i = 0; i < iCount; i++) {
+ IFWL_ListItem* pItem = pData->GetItem(this, i);
+ if (!pItem) {
+ continue;
+ }
+ CFX_WideString wsText;
+ pData->GetItemText(this, pItem, wsText);
+ CFX_SizeF sz = CalcTextSize(wsText, m_pProperties->m_pThemeProvider);
+ if (sz.x > fRet) {
+ 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::GetItemHeigt() {
+ FX_FLOAT* pfFont =
+ static_cast<FX_FLOAT*>(GetThemeCapacity(CFWL_WidgetCapacity::FontSize));
+ if (!pfFont)
+ return 20;
+ return *pfFont + 2 * kItemTextMargin;
+}
+
+void IFWL_ListBox::InitScrollBar(FX_BOOL bVert) {
+ if ((bVert && m_pVertScrollBar) || (!bVert && m_pHorzScrollBar)) {
+ return;
+ }
+ CFWL_WidgetImpProperties prop;
+ 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;
+ IFWL_ScrollBar* pScrollBar = IFWL_ScrollBar::Create(prop, this);
+ pScrollBar->Initialize();
+ (bVert ? &m_pVertScrollBar : &m_pHorzScrollBar)->reset(pScrollBar);
+}
+
+FX_BOOL IFWL_ListBox::IsShowScrollBar(FX_BOOL bVert) {
+ IFWL_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::ProcessSelChanged() {
+ CFWL_EvtLtbSelChanged selEvent;
+ selEvent.m_pSrcTarget = this;
+ CFX_Int32Array arrSels;
+ int32_t iCount = CountSelItems();
+ for (int32_t i = 0; i < iCount; i++) {
+ IFWL_ListItem* item = GetSelItem(i);
+ if (!item) {
+ continue;
+ }
+ selEvent.iarraySels.Add(i);
+ }
+ DispatchEvent(&selEvent);
+}
+
+CFWL_ListBoxImpDelegate::CFWL_ListBoxImpDelegate(IFWL_ListBox* pOwner)
+ : m_pOwner(pOwner) {}
+
+void CFWL_ListBoxImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
+ if (!pMessage)
+ return;
+ if (!m_pOwner->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_WidgetImpDelegate::OnProcessMessage(pMessage);
+}
+
+void CFWL_ListBoxImpDelegate::OnProcessEvent(CFWL_Event* pEvent) {
+ if (!pEvent)
+ return;
+ if (pEvent->GetClassID() != CFWL_EventType::Scroll)
+ return;
+
+ IFWL_Widget* pSrcTarget = pEvent->m_pSrcTarget;
+ if ((pSrcTarget == m_pOwner->m_pVertScrollBar.get() &&
+ m_pOwner->m_pVertScrollBar) ||
+ (pSrcTarget == m_pOwner->m_pHorzScrollBar.get() &&
+ m_pOwner->m_pHorzScrollBar)) {
+ CFWL_EvtScroll* pScrollEvent = static_cast<CFWL_EvtScroll*>(pEvent);
+ OnScroll(static_cast<IFWL_ScrollBar*>(pSrcTarget),
+ pScrollEvent->m_iScrollCode, pScrollEvent->m_fPos);
+ }
+}
+
+void CFWL_ListBoxImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ m_pOwner->DrawWidget(pGraphics, pMatrix);
+}
+
+void CFWL_ListBoxImpDelegate::OnFocusChanged(CFWL_Message* pMsg, FX_BOOL bSet) {
+ if (m_pOwner->GetStylesEx() & FWL_STYLEEXT_LTB_ShowScrollBarFocus) {
+ if (m_pOwner->m_pVertScrollBar) {
+ m_pOwner->m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, !bSet);
+ }
+ if (m_pOwner->m_pHorzScrollBar) {
+ m_pOwner->m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, !bSet);
+ }
+ }
+ if (bSet) {
+ m_pOwner->m_pProperties->m_dwStates |= (FWL_WGTSTATE_Focused);
+ } else {
+ m_pOwner->m_pProperties->m_dwStates &= ~(FWL_WGTSTATE_Focused);
+ }
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+}
+
+void CFWL_ListBoxImpDelegate::OnLButtonDown(CFWL_MsgMouse* pMsg) {
+ m_pOwner->m_bLButtonDown = TRUE;
+ if ((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) {
+ m_pOwner->SetFocus(TRUE);
+ }
+ IFWL_ListItem* pItem = m_pOwner->GetItemAtPoint(pMsg->m_fx, pMsg->m_fy);
+ if (!pItem) {
+ return;
+ }
+ if (m_pOwner->m_pProperties->m_dwStyleExes &
+ FWL_STYLEEXT_LTB_MultiSelection) {
+ if (pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl) {
+ FX_BOOL bSelected = m_pOwner->IsItemSelected(pItem);
+ m_pOwner->SetSelectionDirect(pItem, !bSelected);
+ m_pOwner->m_hAnchor = pItem;
+ } else if (pMsg->m_dwFlags & FWL_KEYFLAG_Shift) {
+ if (m_pOwner->m_hAnchor) {
+ m_pOwner->SetSelection(m_pOwner->m_hAnchor, pItem, TRUE);
+ } else {
+ m_pOwner->SetSelectionDirect(pItem, TRUE);
+ }
+ } else {
+ m_pOwner->SetSelection(pItem, pItem, TRUE);
+ m_pOwner->m_hAnchor = pItem;
+ }
+ } else {
+ m_pOwner->SetSelection(pItem, pItem, TRUE);
+ }
+ if (m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_Check) {
+ IFWL_ListItem* hSelectedItem =
+ m_pOwner->GetItemAtPoint(pMsg->m_fx, pMsg->m_fy);
+ CFX_RectF rtCheck;
+ m_pOwner->GetItemCheckRect(hSelectedItem, rtCheck);
+ FX_BOOL bChecked = m_pOwner->GetItemChecked(pItem);
+ if (rtCheck.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ if (bChecked) {
+ m_pOwner->SetItemChecked(pItem, FALSE);
+ } else {
+ m_pOwner->SetItemChecked(pItem, TRUE);
+ }
+ m_pOwner->Update();
+ }
+ }
+ m_pOwner->SetFocusItem(pItem);
+ m_pOwner->ScrollToVisible(pItem);
+ m_pOwner->SetGrab(TRUE);
+ m_pOwner->ProcessSelChanged();
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+}
+
+void CFWL_ListBoxImpDelegate::OnLButtonUp(CFWL_MsgMouse* pMsg) {
+ if (m_pOwner->m_bLButtonDown) {
+ m_pOwner->m_bLButtonDown = FALSE;
+ m_pOwner->SetGrab(FALSE);
+ DispatchSelChangedEv();
+ }
+}
+
+void CFWL_ListBoxImpDelegate::OnMouseWheel(CFWL_MsgMouseWheel* pMsg) {
+ if (!m_pOwner->IsShowScrollBar(TRUE)) {
+ return;
+ }
+ IFWL_WidgetDelegate* pDelegate =
+ m_pOwner->m_pVertScrollBar->SetDelegate(nullptr);
+ pDelegate->OnProcessMessage(pMsg);
+}
+
+void CFWL_ListBoxImpDelegate::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: {
+ IFWL_ListItem* pItem = m_pOwner->GetFocusedItem();
+ pItem = m_pOwner->GetItem(pItem, dwKeyCode);
+ FX_BOOL bShift = pMsg->m_dwFlags & FWL_KEYFLAG_Shift;
+ FX_BOOL bCtrl = pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl;
+ OnVK(pItem, bShift, bCtrl);
+ DispatchSelChangedEv();
+ m_pOwner->ProcessSelChanged();
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+void CFWL_ListBoxImpDelegate::OnVK(IFWL_ListItem* pItem,
+ FX_BOOL bShift,
+ FX_BOOL bCtrl) {
+ if (!pItem) {
+ return;
+ }
+ if (m_pOwner->m_pProperties->m_dwStyleExes &
+ FWL_STYLEEXT_LTB_MultiSelection) {
+ if (bCtrl) {
+ } else if (bShift) {
+ if (m_pOwner->m_hAnchor) {
+ m_pOwner->SetSelection(m_pOwner->m_hAnchor, pItem, TRUE);
+ } else {
+ m_pOwner->SetSelectionDirect(pItem, TRUE);
+ }
+ } else {
+ m_pOwner->SetSelection(pItem, pItem, TRUE);
+ m_pOwner->m_hAnchor = pItem;
+ }
+ } else {
+ m_pOwner->SetSelection(pItem, pItem, TRUE);
+ }
+ m_pOwner->SetFocusItem(pItem);
+ m_pOwner->ScrollToVisible(pItem);
+ {
+ CFX_RectF rtInvalidate;
+ rtInvalidate.Set(0, 0, m_pOwner->m_pProperties->m_rtWidget.width,
+ m_pOwner->m_pProperties->m_rtWidget.height);
+ m_pOwner->Repaint(&rtInvalidate);
+ }
+}
+
+FX_BOOL CFWL_ListBoxImpDelegate::OnScroll(IFWL_ScrollBar* pScrollBar,
+ uint32_t 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:
+ break;
+ case FWL_SCBCODE_EndScroll:
+ return FALSE;
+ }
+ if (iCurPos != fPos) {
+ pScrollBar->SetPos(fPos);
+ pScrollBar->SetTrackPos(fPos);
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ }
+ return TRUE;
+}
+
+void CFWL_ListBoxImpDelegate::DispatchSelChangedEv() {
+ CFWL_EvtLtbSelChanged ev;
+ ev.m_pSrcTarget = m_pOwner;
+ m_pOwner->DispatchEvent(&ev);
+}
diff --git a/xfa/fwl/core/ifwl_listbox.h b/xfa/fwl/core/ifwl_listbox.h
new file mode 100644
index 0000000000..79fb2e94cc
--- /dev/null
+++ b/xfa/fwl/core/ifwl_listbox.h
@@ -0,0 +1,210 @@
+// 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 "xfa/fwl/core/cfwl_event.h"
+#include "xfa/fwl/core/cfwl_widgetimpproperties.h"
+#include "xfa/fwl/core/ifwl_dataprovider.h"
+#include "xfa/fwl/core/ifwl_edit.h"
+#include "xfa/fwl/core/ifwl_listbox.h"
+#include "xfa/fwl/core/ifwl_widget.h"
+
+#define FWL_CLASS_ListBox L"FWL_LISTBOX"
+#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_ListBoxImpDelegate;
+class CFWL_MsgKillFocus;
+class CFWL_MsgMouse;
+class CFWL_MsgMouseWheel;
+class CFX_DIBitmap;
+
+FWL_EVENT_DEF(CFWL_EvtLtbSelChanged,
+ CFWL_EventType::SelectChanged,
+ CFX_Int32Array iarraySels;)
+
+FWL_EVENT_DEF(CFWL_EvtLtbDrawItem,
+ CFWL_EventType::DrawItem,
+ CFX_Graphics* m_pGraphics;
+ CFX_Matrix m_matrix;
+ int32_t m_index;
+ CFX_RectF m_rect;)
+
+class IFWL_ListItem {};
+
+class IFWL_ListBoxDP : public IFWL_DataProvider {
+ public:
+ virtual int32_t CountItems(const IFWL_Widget* pWidget) = 0;
+ virtual IFWL_ListItem* GetItem(const IFWL_Widget* pWidget,
+ int32_t nIndex) = 0;
+ virtual int32_t GetItemIndex(IFWL_Widget* pWidget, IFWL_ListItem* pItem) = 0;
+ virtual FX_BOOL SetItemIndex(IFWL_Widget* pWidget,
+ IFWL_ListItem* pItem,
+ int32_t nIndex) = 0;
+ virtual uint32_t GetItemStyles(IFWL_Widget* pWidget,
+ IFWL_ListItem* pItem) = 0;
+ virtual FWL_Error GetItemText(IFWL_Widget* pWidget,
+ IFWL_ListItem* pItem,
+ CFX_WideString& wsText) = 0;
+ virtual FWL_Error GetItemRect(IFWL_Widget* pWidget,
+ IFWL_ListItem* pItem,
+ CFX_RectF& rtItem) = 0;
+ virtual void* GetItemData(IFWL_Widget* pWidget, IFWL_ListItem* pItem) = 0;
+ virtual FWL_Error SetItemStyles(IFWL_Widget* pWidget,
+ IFWL_ListItem* pItem,
+ uint32_t dwStyle) = 0;
+ virtual FWL_Error SetItemText(IFWL_Widget* pWidget,
+ IFWL_ListItem* pItem,
+ const FX_WCHAR* pszText) = 0;
+ virtual FWL_Error SetItemRect(IFWL_Widget* pWidget,
+ IFWL_ListItem* pItem,
+ const CFX_RectF& rtItem) = 0;
+ virtual FX_FLOAT GetItemHeight(IFWL_Widget* pWidget) = 0;
+ virtual CFX_DIBitmap* GetItemIcon(IFWL_Widget* pWidget,
+ IFWL_ListItem* pItem) = 0;
+ virtual FWL_Error GetItemCheckRect(IFWL_Widget* pWidget,
+ IFWL_ListItem* pItem,
+ CFX_RectF& rtCheck) = 0;
+ virtual FWL_Error SetItemCheckRect(IFWL_Widget* pWidget,
+ IFWL_ListItem* pItem,
+ const CFX_RectF& rtCheck) = 0;
+ virtual uint32_t GetItemCheckState(IFWL_Widget* pWidget,
+ IFWL_ListItem* pItem) = 0;
+ virtual FWL_Error SetItemCheckState(IFWL_Widget* pWidget,
+ IFWL_ListItem* pItem,
+ uint32_t dwCheckState) = 0;
+};
+
+class IFWL_ListBoxCompare {
+ public:
+ virtual ~IFWL_ListBoxCompare() {}
+ virtual int32_t Compare(IFWL_ListItem* hLeft, IFWL_ListItem* hRight) = 0;
+};
+
+class IFWL_ListBox : public IFWL_Widget {
+ public:
+ static IFWL_ListBox* Create(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+
+ IFWL_ListBox(const CFWL_WidgetImpProperties& properties, IFWL_Widget* pOuter);
+ ~IFWL_ListBox() override;
+
+ // IFWL_Widget
+ FWL_Error GetClassName(CFX_WideString& wsClass) const override;
+ FWL_Type GetClassID() const override;
+ FWL_Error Initialize() override;
+ FWL_Error Finalize() override;
+ FWL_Error GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize = FALSE) override;
+ FWL_Error Update() override;
+ FWL_WidgetHit HitTest(FX_FLOAT fx, FX_FLOAT fy) override;
+ FWL_Error DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
+ FWL_Error SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) override;
+
+ int32_t CountSelItems();
+ IFWL_ListItem* GetSelItem(int32_t nIndexSel);
+ int32_t GetSelIndex(int32_t nIndex);
+ FWL_Error SetSelItem(IFWL_ListItem* hItem, FX_BOOL bSelect = TRUE);
+ FWL_Error GetItemText(IFWL_ListItem* hItem, CFX_WideString& wsText);
+ FWL_Error GetScrollPos(FX_FLOAT& fPos, FX_BOOL bVert = TRUE);
+ FWL_Error* Sort(IFWL_ListBoxCompare* pCom);
+
+ protected:
+ friend class CFWL_ListBoxImpDelegate;
+
+ IFWL_ListItem* GetItem(IFWL_ListItem* hItem, uint32_t dwKeyCode);
+ void SetSelection(IFWL_ListItem* hStart,
+ IFWL_ListItem* hEnd,
+ FX_BOOL bSelected);
+ void SetSelectionDirect(IFWL_ListItem* hItem, FX_BOOL bSelect);
+ FX_BOOL IsItemSelected(IFWL_ListItem* hItem);
+ void ClearSelection();
+ void SelectAll();
+ IFWL_ListItem* GetFocusedItem();
+ void SetFocusItem(IFWL_ListItem* hItem);
+ IFWL_ListItem* GetItemAtPoint(FX_FLOAT fx, FX_FLOAT fy);
+ FX_BOOL GetItemCheckRect(IFWL_ListItem* hItem, CFX_RectF& rtCheck);
+ FX_BOOL SetItemChecked(IFWL_ListItem* hItem, FX_BOOL bChecked);
+ FX_BOOL GetItemChecked(IFWL_ListItem* hItem);
+ FX_BOOL ScrollToVisible(IFWL_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,
+ IFWL_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(FX_BOOL bAutoSize = FALSE);
+ void GetItemSize(CFX_SizeF& size,
+ IFWL_ListItem* hItem,
+ FX_FLOAT fWidth,
+ FX_FLOAT fHeight,
+ FX_BOOL bAutoSize = FALSE);
+ FX_FLOAT GetMaxTextWidth();
+ FX_FLOAT GetScrollWidth();
+ FX_FLOAT GetItemHeigt();
+ void InitScrollBar(FX_BOOL bVert = TRUE);
+ FX_BOOL IsShowScrollBar(FX_BOOL bVert);
+ void ProcessSelChanged();
+
+ CFX_RectF m_rtClient;
+ CFX_RectF m_rtStatic;
+ CFX_RectF m_rtConent;
+ std::unique_ptr<IFWL_ScrollBar> m_pHorzScrollBar;
+ std::unique_ptr<IFWL_ScrollBar> m_pVertScrollBar;
+ uint32_t m_dwTTOStyles;
+ int32_t m_iTTOAligns;
+ IFWL_ListItem* m_hAnchor;
+ FX_FLOAT m_fItemHeight;
+ FX_FLOAT m_fScorllBarWidth;
+ FX_BOOL m_bLButtonDown;
+ IFWL_ThemeProvider* m_pScrollBarTP;
+};
+
+class CFWL_ListBoxImpDelegate : public CFWL_WidgetImpDelegate {
+ public:
+ CFWL_ListBoxImpDelegate(IFWL_ListBox* pOwner);
+ void OnProcessMessage(CFWL_Message* pMessage) override;
+ void OnProcessEvent(CFWL_Event* pEvent) override;
+ void OnDrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
+
+ protected:
+ void OnFocusChanged(CFWL_Message* pMsg, FX_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(IFWL_ListItem* hItem, FX_BOOL bShift, FX_BOOL bCtrl);
+ FX_BOOL OnScroll(IFWL_ScrollBar* pScrollBar, uint32_t dwCode, FX_FLOAT fPos);
+ void DispatchSelChangedEv();
+ IFWL_ListBox* m_pOwner;
+};
+
+#endif // XFA_FWL_CORE_IFWL_LISTBOX_H_
diff --git a/xfa/fwl/core/ifwl_monthcalendar.cpp b/xfa/fwl/core/ifwl_monthcalendar.cpp
new file mode 100644
index 0000000000..741c88f606
--- /dev/null
+++ b/xfa/fwl/core/ifwl_monthcalendar.cpp
@@ -0,0 +1,1232 @@
+// 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_monthcalendar.h"
+
+#include <algorithm>
+
+#include "xfa/fde/tto/fde_textout.h"
+#include "xfa/fwl/core/cfwl_message.h"
+#include "xfa/fwl/core/cfwl_themebackground.h"
+#include "xfa/fwl/core/cfwl_themetext.h"
+#include "xfa/fwl/core/fwl_noteimp.h"
+#include "xfa/fwl/core/ifwl_monthcalendar.h"
+#include "xfa/fwl/core/ifwl_themeprovider.h"
+
+#define MONTHCAL_HSEP_HEIGHT 1
+#define MONTHCAL_VSEP_WIDTH 1
+#define MONTHCAL_HMARGIN 3
+#define MONTHCAL_VMARGIN 2
+#define MONTHCAL_ROWS 9
+#define MONTHCAL_COLUMNS 7
+#define MONTHCAL_HEADER_BTN_VMARGIN 7
+#define MONTHCAL_HEADER_BTN_HMARGIN 5
+
+namespace {
+
+CFX_WideString* GetCapacityForDay(IFWL_ThemeProvider* pTheme,
+ CFWL_ThemePart& params,
+ uint32_t day) {
+ ASSERT(day < 7);
+
+ if (day == 0) {
+ return static_cast<CFX_WideString*>(
+ pTheme->GetCapacity(&params, CFWL_WidgetCapacity::Sun));
+ }
+ if (day == 1) {
+ return static_cast<CFX_WideString*>(
+ pTheme->GetCapacity(&params, CFWL_WidgetCapacity::Mon));
+ }
+ if (day == 2) {
+ return static_cast<CFX_WideString*>(
+ pTheme->GetCapacity(&params, CFWL_WidgetCapacity::Tue));
+ }
+ if (day == 3) {
+ return static_cast<CFX_WideString*>(
+ pTheme->GetCapacity(&params, CFWL_WidgetCapacity::Wed));
+ }
+ if (day == 4) {
+ return static_cast<CFX_WideString*>(
+ pTheme->GetCapacity(&params, CFWL_WidgetCapacity::Thu));
+ }
+ if (day == 5) {
+ return static_cast<CFX_WideString*>(
+ pTheme->GetCapacity(&params, CFWL_WidgetCapacity::Fri));
+ }
+
+ return static_cast<CFX_WideString*>(
+ pTheme->GetCapacity(&params, CFWL_WidgetCapacity::Sat));
+}
+
+CFX_WideString* GetCapacityForMonth(IFWL_ThemeProvider* pTheme,
+ CFWL_ThemePart& params,
+ uint32_t month) {
+ ASSERT(month < 12);
+
+ if (month == 0) {
+ return static_cast<CFX_WideString*>(
+ pTheme->GetCapacity(&params, CFWL_WidgetCapacity::January));
+ }
+ if (month == 1) {
+ return static_cast<CFX_WideString*>(
+ pTheme->GetCapacity(&params, CFWL_WidgetCapacity::February));
+ }
+ if (month == 2) {
+ return static_cast<CFX_WideString*>(
+ pTheme->GetCapacity(&params, CFWL_WidgetCapacity::March));
+ }
+ if (month == 3) {
+ return static_cast<CFX_WideString*>(
+ pTheme->GetCapacity(&params, CFWL_WidgetCapacity::April));
+ }
+ if (month == 4) {
+ return static_cast<CFX_WideString*>(
+ pTheme->GetCapacity(&params, CFWL_WidgetCapacity::May));
+ }
+ if (month == 5) {
+ return static_cast<CFX_WideString*>(
+ pTheme->GetCapacity(&params, CFWL_WidgetCapacity::June));
+ }
+ if (month == 6) {
+ return static_cast<CFX_WideString*>(
+ pTheme->GetCapacity(&params, CFWL_WidgetCapacity::July));
+ }
+ if (month == 7) {
+ return static_cast<CFX_WideString*>(
+ pTheme->GetCapacity(&params, CFWL_WidgetCapacity::August));
+ }
+ if (month == 8) {
+ return static_cast<CFX_WideString*>(
+ pTheme->GetCapacity(&params, CFWL_WidgetCapacity::September));
+ }
+ if (month == 9) {
+ return static_cast<CFX_WideString*>(
+ pTheme->GetCapacity(&params, CFWL_WidgetCapacity::October));
+ }
+ if (month == 10) {
+ return static_cast<CFX_WideString*>(
+ pTheme->GetCapacity(&params, CFWL_WidgetCapacity::November));
+ }
+
+ return static_cast<CFX_WideString*>(
+ pTheme->GetCapacity(&params, CFWL_WidgetCapacity::December));
+}
+
+} // namespace
+
+// static
+IFWL_MonthCalendar* IFWL_MonthCalendar::Create(
+ const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter) {
+ return new IFWL_MonthCalendar(properties, pOuter);
+}
+
+IFWL_MonthCalendar::IFWL_MonthCalendar(
+ const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter)
+ : IFWL_Widget(properties, pOuter),
+ m_bInit(FALSE),
+ m_pDateTime(new CFX_DateTime),
+ m_iCurYear(2011),
+ m_iCurMonth(1),
+ m_iYear(2011),
+ m_iMonth(1),
+ m_iDay(1),
+ m_iHovered(-1),
+ m_iLBtnPartStates(CFWL_PartState_Normal),
+ m_iRBtnPartStates(CFWL_PartState_Normal),
+ m_iMaxSel(1) {
+ m_rtHead.Reset();
+ m_rtWeek.Reset();
+ m_rtLBtn.Reset();
+ m_rtRBtn.Reset();
+ m_rtDates.Reset();
+ m_rtHSep.Reset();
+ m_rtHeadText.Reset();
+ m_rtToday.Reset();
+ m_rtTodayFlag.Reset();
+ m_rtClient.Reset();
+ m_rtWeekNum.Reset();
+ m_rtWeekNumSep.Reset();
+}
+
+IFWL_MonthCalendar::~IFWL_MonthCalendar() {
+ ClearDateItem();
+ m_arrSelDays.RemoveAll();
+}
+
+FWL_Error IFWL_MonthCalendar::GetClassName(CFX_WideString& wsClass) const {
+ wsClass = FWL_CLASS_MonthCalendar;
+ return FWL_Error::Succeeded;
+}
+
+FWL_Type IFWL_MonthCalendar::GetClassID() const {
+ return FWL_Type::MonthCalendar;
+}
+
+FWL_Error IFWL_MonthCalendar::Initialize() {
+ if (IFWL_Widget::Initialize() != FWL_Error::Succeeded)
+ return FWL_Error::Indefinite;
+
+ m_pDelegate = new CFWL_MonthCalendarImpDelegate(this);
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_MonthCalendar::Finalize() {
+ delete m_pDelegate;
+ m_pDelegate = nullptr;
+ return IFWL_Widget::Finalize();
+}
+
+FWL_Error IFWL_MonthCalendar::GetWidgetRect(CFX_RectF& rect,
+ FX_BOOL bAutoSize) {
+ if (bAutoSize) {
+ CFX_SizeF fs = CalcSize(TRUE);
+ rect.Set(0, 0, fs.x, fs.y);
+ IFWL_Widget::GetWidgetRect(rect, TRUE);
+ } else {
+ rect = m_pProperties->m_rtWidget;
+ }
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_MonthCalendar::Update() {
+ if (IsLocked()) {
+ return FWL_Error::Indefinite;
+ }
+ if (!m_pProperties->m_pThemeProvider) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ GetCapValue();
+ if (!m_bInit) {
+ m_bInit = InitDate();
+ }
+ ClearDateItem();
+ ReSetDateItem();
+ LayOut();
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_MonthCalendar::DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ if (!pGraphics)
+ return FWL_Error::Indefinite;
+ if (!m_pProperties->m_pThemeProvider) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ 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);
+ }
+ DrawBkground(pGraphics, pTheme, pMatrix);
+ DrawHeadBK(pGraphics, pTheme, pMatrix);
+ DrawLButton(pGraphics, pTheme, pMatrix);
+ DrawRButton(pGraphics, pTheme, pMatrix);
+ DrawSeperator(pGraphics, pTheme, pMatrix);
+ DrawDatesInBK(pGraphics, pTheme, pMatrix);
+ DrawDatesInCircle(pGraphics, pTheme, pMatrix);
+ DrawCaption(pGraphics, pTheme, pMatrix);
+ DrawWeek(pGraphics, pTheme, pMatrix);
+ DrawDatesIn(pGraphics, pTheme, pMatrix);
+ DrawDatesOut(pGraphics, pTheme, pMatrix);
+ DrawToday(pGraphics, pTheme, pMatrix);
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_WeekNumbers) {
+ DrawWeekNumberSep(pGraphics, pTheme, pMatrix);
+ DrawWeekNumber(pGraphics, pTheme, pMatrix);
+ }
+ return FWL_Error::Succeeded;
+}
+
+int32_t IFWL_MonthCalendar::CountSelect() {
+ return m_arrSelDays.GetSize();
+}
+
+FX_BOOL IFWL_MonthCalendar::GetSelect(int32_t& iYear,
+ int32_t& iMonth,
+ int32_t& iDay,
+ int32_t nIndex) {
+ if (nIndex >= m_arrSelDays.GetSize()) {
+ return FALSE;
+ }
+ iYear = m_iCurYear;
+ iMonth = m_iCurMonth;
+ iDay = m_arrSelDays[nIndex];
+ return TRUE;
+}
+
+FX_BOOL IFWL_MonthCalendar::SetSelect(int32_t iYear,
+ int32_t iMonth,
+ int32_t iDay) {
+ ChangeToMonth(iYear, iMonth);
+ return AddSelDay(iDay);
+}
+
+void IFWL_MonthCalendar::DrawBkground(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix) {
+ CFWL_ThemeBackground params;
+ params.m_pWidget = this;
+ params.m_iPart = CFWL_Part::Background;
+ params.m_pGraphics = pGraphics;
+ params.m_dwStates = CFWL_PartState_Normal;
+ params.m_rtPart = m_rtClient;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ pTheme->DrawBackground(&params);
+}
+
+void IFWL_MonthCalendar::DrawHeadBK(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix) {
+ CFWL_ThemeBackground params;
+ params.m_pWidget = this;
+ params.m_iPart = CFWL_Part::Header;
+ params.m_pGraphics = pGraphics;
+ params.m_dwStates = CFWL_PartState_Normal;
+ params.m_rtPart = m_rtHead;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ pTheme->DrawBackground(&params);
+}
+
+void IFWL_MonthCalendar::DrawLButton(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix) {
+ CFWL_ThemeBackground params;
+ params.m_pWidget = this;
+ params.m_iPart = CFWL_Part::LBtn;
+ params.m_pGraphics = pGraphics;
+ params.m_dwStates = m_iLBtnPartStates;
+ params.m_rtPart = m_rtLBtn;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ pTheme->DrawBackground(&params);
+}
+
+void IFWL_MonthCalendar::DrawRButton(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix) {
+ CFWL_ThemeBackground params;
+ params.m_pWidget = this;
+ params.m_iPart = CFWL_Part::RBtn;
+ params.m_pGraphics = pGraphics;
+ params.m_dwStates = m_iRBtnPartStates;
+ params.m_rtPart = m_rtRBtn;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ pTheme->DrawBackground(&params);
+}
+
+void IFWL_MonthCalendar::DrawCaption(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix) {
+ CFWL_ThemeText textParam;
+ textParam.m_pWidget = this;
+ textParam.m_iPart = CFWL_Part::Caption;
+ textParam.m_dwStates = CFWL_PartState_Normal;
+ textParam.m_pGraphics = pGraphics;
+ int32_t iYear;
+ int32_t iMonth;
+ iYear = m_iCurYear;
+ iMonth = m_iCurMonth;
+ CFX_WideString wsCation;
+ GetHeadText(iYear, iMonth, wsCation);
+ textParam.m_wsText = wsCation;
+ m_szHead = CalcTextSize(textParam.m_wsText, m_pProperties->m_pThemeProvider);
+ CalcHeadSize();
+ textParam.m_rtPart = m_rtHeadText;
+ textParam.m_dwTTOStyles = FDE_TTOSTYLE_SingleLine;
+ textParam.m_iTTOAlign = FDE_TTOALIGNMENT_Center;
+ if (pMatrix) {
+ textParam.m_matrix.Concat(*pMatrix);
+ }
+ pTheme->DrawText(&textParam);
+}
+
+void IFWL_MonthCalendar::DrawSeperator(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix) {
+ CFWL_ThemeBackground params;
+ params.m_pWidget = this;
+ params.m_iPart = CFWL_Part::HSeparator;
+ params.m_pGraphics = pGraphics;
+ params.m_dwStates = CFWL_PartState_Normal;
+ params.m_rtPart = m_rtHSep;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ pTheme->DrawBackground(&params);
+}
+
+void IFWL_MonthCalendar::DrawDatesInBK(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix) {
+ CFWL_ThemeBackground params;
+ params.m_pWidget = this;
+ params.m_iPart = CFWL_Part::DateInBK;
+ params.m_pGraphics = pGraphics;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ int32_t iCount = m_arrDates.GetSize();
+ for (int32_t j = 0; j < iCount; j++) {
+ FWL_DATEINFO* pDataInfo = m_arrDates.GetAt(j);
+ if (pDataInfo->dwStates & FWL_ITEMSTATE_MCD_Selected) {
+ params.m_dwStates |= CFWL_PartState_Selected;
+ if (((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_NoTodayCircle) ==
+ 0) &&
+ pDataInfo->dwStates & FWL_ITEMSTATE_MCD_Flag) {
+ params.m_dwStates |= CFWL_PartState_Flagged;
+ }
+ if (pDataInfo->dwStates & FWL_ITEMSTATE_MCD_Focused) {
+ params.m_dwStates |= CFWL_PartState_Focused;
+ }
+ } else if (j == m_iHovered - 1) {
+ params.m_dwStates |= CFWL_PartState_Hovered;
+ } else if (pDataInfo->dwStates & FWL_ITEMSTATE_MCD_Flag) {
+ params.m_dwStates = CFWL_PartState_Flagged;
+ pTheme->DrawBackground(&params);
+ }
+ params.m_rtPart = pDataInfo->rect;
+ pTheme->DrawBackground(&params);
+ params.m_dwStates = 0;
+ }
+}
+
+void IFWL_MonthCalendar::DrawWeek(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix) {
+ CFWL_ThemeText params;
+ params.m_pWidget = this;
+ params.m_iPart = CFWL_Part::Week;
+ params.m_pGraphics = pGraphics;
+ params.m_dwStates = CFWL_PartState_Normal;
+ params.m_iTTOAlign = FDE_TTOALIGNMENT_Center;
+ CFX_RectF rtDayOfWeek;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ for (int32_t i = 0; i < 7; i++) {
+ rtDayOfWeek.Set(m_rtWeek.left + i * (m_szCell.x + MONTHCAL_HMARGIN * 2),
+ m_rtWeek.top, m_szCell.x, m_szCell.y);
+ params.m_rtPart = rtDayOfWeek;
+ params.m_wsText = *GetCapacityForDay(pTheme, params, i);
+ params.m_dwTTOStyles = FDE_TTOSTYLE_SingleLine;
+ pTheme->DrawText(&params);
+ }
+}
+
+void IFWL_MonthCalendar::DrawWeekNumber(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix) {
+ CFWL_ThemeText params;
+ params.m_pWidget = this;
+ params.m_iPart = CFWL_Part::WeekNum;
+ params.m_pGraphics = pGraphics;
+ params.m_dwStates = CFWL_PartState_Normal;
+ params.m_iTTOAlign = FDE_TTOALIGNMENT_CenterLeft;
+ CFX_WideString wsWeekNum;
+ params.m_dwTTOStyles = FDE_TTOSTYLE_SingleLine;
+ params.m_iTTOAlign = FDE_TTOALIGNMENT_Center;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ int32_t iWeekNum = 0;
+ int32_t iMonthNum = m_pDateTime->GetMonth();
+ int32_t iDayNum = FX_DaysInMonth(m_iCurYear, iMonthNum);
+ int32_t iTemp = 0;
+ FX_FLOAT fVStartPos = m_rtClient.top + m_fHeadHei + m_fHSepHei;
+ FX_FLOAT fHStartPos = m_rtClient.left;
+ for (int32_t i = 1; i <= iDayNum; i += 7) {
+ iTemp++;
+ iWeekNum = CalWeekNumber(m_iCurYear, iMonthNum, i);
+ m_rtWeekNum.Set(fHStartPos, fVStartPos + m_fDateCellHei * iTemp,
+ m_fWeekNumWid, m_fDateCellHei);
+ wsWeekNum.Format(L"%d", iWeekNum);
+ params.m_wsText = wsWeekNum;
+ params.m_rtPart = m_rtWeekNum;
+ pTheme->DrawText(&params);
+ }
+}
+
+void IFWL_MonthCalendar::DrawWeekNumberSep(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix) {
+ CFWL_ThemeBackground params;
+ params.m_pWidget = this;
+ params.m_iPart = CFWL_Part::WeekNumSep;
+ params.m_pGraphics = pGraphics;
+ params.m_dwStates = CFWL_PartState_Normal;
+ params.m_rtPart = m_rtWeekNumSep;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ pTheme->DrawBackground(&params);
+}
+
+void IFWL_MonthCalendar::DrawToday(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix) {
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_NoToday) {
+ return;
+ }
+ CFWL_ThemeText params;
+ params.m_pWidget = this;
+ params.m_iPart = CFWL_Part::Today;
+ params.m_pGraphics = pGraphics;
+ params.m_dwStates = CFWL_PartState_Normal;
+ params.m_iTTOAlign = FDE_TTOALIGNMENT_CenterLeft;
+ CFX_WideString* wsDay = static_cast<CFX_WideString*>(
+ pTheme->GetCapacity(&params, CFWL_WidgetCapacity::Today));
+ CFX_WideString wsText;
+ GetTodayText(m_iYear, m_iMonth, m_iDay, wsText);
+ params.m_wsText = *wsDay + wsText;
+ m_szToday = CalcTextSize(params.m_wsText, m_pProperties->m_pThemeProvider);
+ CalcTodaySize();
+ params.m_rtPart = m_rtToday;
+ params.m_dwTTOStyles = FDE_TTOSTYLE_SingleLine;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ pTheme->DrawText(&params);
+}
+
+void IFWL_MonthCalendar::DrawDatesIn(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix) {
+ CFWL_ThemeText params;
+ params.m_pWidget = this;
+ params.m_iPart = CFWL_Part::DatesIn;
+ params.m_pGraphics = pGraphics;
+ params.m_dwStates = CFWL_PartState_Normal;
+ params.m_iTTOAlign = FDE_TTOALIGNMENT_Center;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ int32_t iCount = m_arrDates.GetSize();
+ for (int32_t j = 0; j < iCount; j++) {
+ FWL_DATEINFO* pDataInfo = m_arrDates.GetAt(j);
+ params.m_wsText = pDataInfo->wsDay;
+ params.m_rtPart = pDataInfo->rect;
+ params.m_dwStates = pDataInfo->dwStates;
+ if (j + 1 == m_iHovered) {
+ params.m_dwStates |= CFWL_PartState_Hovered;
+ }
+ params.m_dwTTOStyles = FDE_TTOSTYLE_SingleLine;
+ pTheme->DrawText(&params);
+ }
+}
+
+void IFWL_MonthCalendar::DrawDatesOut(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix) {
+ CFWL_ThemeText params;
+ params.m_pWidget = this;
+ params.m_iPart = CFWL_Part::DatesOut;
+ params.m_pGraphics = pGraphics;
+ params.m_dwStates = CFWL_PartState_Normal;
+ params.m_iTTOAlign = FDE_TTOALIGNMENT_Center;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ pTheme->DrawText(&params);
+}
+
+void IFWL_MonthCalendar::DrawDatesInCircle(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix) {
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_NoTodayCircle) {
+ return;
+ }
+ if (m_iMonth != m_iCurMonth || m_iYear != m_iCurYear) {
+ return;
+ }
+ if (m_iDay < 1 || m_iDay > m_arrDates.GetSize()) {
+ return;
+ }
+ FWL_DATEINFO* pDate = m_arrDates[m_iDay - 1];
+ if (!pDate)
+ return;
+ CFWL_ThemeBackground params;
+ params.m_pWidget = this;
+ params.m_iPart = CFWL_Part::DateInCircle;
+ params.m_pGraphics = pGraphics;
+ params.m_rtPart = pDate->rect;
+ params.m_dwStates = CFWL_PartState_Normal;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ pTheme->DrawBackground(&params);
+}
+
+void IFWL_MonthCalendar::DrawTodayCircle(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix) {
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_NoToday) {
+ return;
+ }
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_NoTodayCircle) {
+ return;
+ }
+ CFWL_ThemeBackground params;
+ params.m_pWidget = this;
+ params.m_iPart = CFWL_Part::TodayCircle;
+ params.m_pGraphics = pGraphics;
+ params.m_dwStates = CFWL_PartState_Normal;
+ params.m_rtPart = m_rtTodayFlag;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ pTheme->DrawBackground(&params);
+}
+
+CFX_SizeF IFWL_MonthCalendar::CalcSize(FX_BOOL bAutoSize) {
+ if (!m_pProperties->m_pThemeProvider)
+ return CFX_SizeF();
+
+ if (!bAutoSize) {
+ GetClientRect(m_rtClient);
+ return CFX_SizeF(m_rtClient.width, m_rtClient.height);
+ }
+
+ CFX_SizeF fs;
+ CFWL_ThemePart params;
+ params.m_pWidget = this;
+ IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
+ FX_FLOAT fMaxWeekW = 0.0f;
+ FX_FLOAT fMaxWeekH = 0.0f;
+
+ for (uint32_t i = 0; i < 7; ++i) {
+ CFX_SizeF sz = CalcTextSize(*GetCapacityForDay(pTheme, params, i),
+ m_pProperties->m_pThemeProvider);
+ fMaxWeekW = (fMaxWeekW >= sz.x) ? fMaxWeekW : sz.x;
+ fMaxWeekH = (fMaxWeekH >= sz.y) ? fMaxWeekH : sz.y;
+ }
+
+ FX_FLOAT fDayMaxW = 0.0f;
+ FX_FLOAT fDayMaxH = 0.0f;
+ for (int day = 10; day <= 31; day++) {
+ CFX_WideString wsDay;
+ wsDay.Format(L"%d", day);
+ CFX_SizeF sz = CalcTextSize(wsDay, m_pProperties->m_pThemeProvider);
+ fDayMaxW = (fDayMaxW >= sz.x) ? fDayMaxW : sz.x;
+ fDayMaxH = (fDayMaxH >= sz.y) ? fDayMaxH : sz.y;
+ }
+ m_szCell.x = FX_FLOAT((fMaxWeekW >= fDayMaxW) ? (int)(fMaxWeekW + 0.5)
+ : (int)(fDayMaxW + 0.5));
+ m_szCell.y = (fMaxWeekH >= fDayMaxH) ? fMaxWeekH : fDayMaxH;
+ fs.x = m_szCell.x * MONTHCAL_COLUMNS +
+ MONTHCAL_HMARGIN * MONTHCAL_COLUMNS * 2 +
+ MONTHCAL_HEADER_BTN_HMARGIN * 2;
+ FX_FLOAT fMonthMaxW = 0.0f;
+ FX_FLOAT fMonthMaxH = 0.0f;
+
+ for (uint32_t i = 0; i < 12; ++i) {
+ CFX_SizeF sz = CalcTextSize(*GetCapacityForMonth(pTheme, params, i),
+ m_pProperties->m_pThemeProvider);
+ fMonthMaxW = (fMonthMaxW >= sz.x) ? fMonthMaxW : sz.x;
+ fMonthMaxH = (fMonthMaxH >= sz.y) ? fMonthMaxH : sz.y;
+ }
+ CFX_WideString wsYear;
+ GetHeadText(m_iYear, m_iMonth, wsYear);
+ CFX_SizeF szYear = CalcTextSize(wsYear, m_pProperties->m_pThemeProvider);
+ fMonthMaxH = std::max(fMonthMaxH, szYear.y);
+ m_szHead = CFX_SizeF(fMonthMaxW + szYear.x, fMonthMaxH);
+ fMonthMaxW = m_szHead.x + MONTHCAL_HEADER_BTN_HMARGIN * 2 + m_szCell.x * 2;
+ fs.x = std::max(fs.x, fMonthMaxW);
+ CFX_WideString wsToday;
+ GetTodayText(m_iYear, m_iMonth, m_iDay, wsToday);
+ CFX_WideString* wsText = static_cast<CFX_WideString*>(
+ pTheme->GetCapacity(&params, CFWL_WidgetCapacity::Today));
+ m_wsToday = *wsText + wsToday;
+ m_szToday = CalcTextSize(wsToday, m_pProperties->m_pThemeProvider);
+ m_szToday.y = (m_szToday.y >= m_szCell.y) ? m_szToday.y : m_szCell.y;
+ fs.y = m_szCell.x + m_szCell.y * (MONTHCAL_ROWS - 2) + m_szToday.y +
+ MONTHCAL_VMARGIN * MONTHCAL_ROWS * 2 + MONTHCAL_HEADER_BTN_VMARGIN * 4;
+ return fs;
+}
+
+void IFWL_MonthCalendar::CalcHeadSize() {
+ FX_FLOAT fHeadHMargin = (m_rtClient.width - m_szHead.x) / 2;
+ FX_FLOAT fHeadVMargin = (m_szCell.x - m_szHead.y) / 2;
+ m_rtHeadText.Set(m_rtClient.left + fHeadHMargin,
+ m_rtClient.top + MONTHCAL_HEADER_BTN_VMARGIN +
+ MONTHCAL_VMARGIN + fHeadVMargin,
+ m_szHead.x, m_szHead.y);
+}
+
+void IFWL_MonthCalendar::CalcTodaySize() {
+ m_rtTodayFlag.Set(
+ m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN + MONTHCAL_HMARGIN,
+ m_rtDates.bottom() + MONTHCAL_HEADER_BTN_VMARGIN + MONTHCAL_VMARGIN,
+ m_szCell.x, m_szToday.y);
+ m_rtToday.Set(
+ m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN + m_szCell.x +
+ MONTHCAL_HMARGIN * 2,
+ m_rtDates.bottom() + MONTHCAL_HEADER_BTN_VMARGIN + MONTHCAL_VMARGIN,
+ m_szToday.x, m_szToday.y);
+}
+
+void IFWL_MonthCalendar::LayOut() {
+ GetClientRect(m_rtClient);
+ {
+ m_rtHead.Set(
+ m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN, m_rtClient.top,
+ m_rtClient.width - MONTHCAL_HEADER_BTN_HMARGIN * 2,
+ m_szCell.x + (MONTHCAL_HEADER_BTN_VMARGIN + MONTHCAL_VMARGIN) * 2);
+ m_rtWeek.Set(m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN,
+ m_rtHead.bottom(),
+ m_rtClient.width - MONTHCAL_HEADER_BTN_HMARGIN * 2,
+ m_szCell.y + MONTHCAL_VMARGIN * 2);
+ m_rtLBtn.Set(m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN,
+ m_rtClient.top + MONTHCAL_HEADER_BTN_VMARGIN, m_szCell.x,
+ m_szCell.x);
+ m_rtRBtn.Set(m_rtClient.left + m_rtClient.width -
+ MONTHCAL_HEADER_BTN_HMARGIN - m_szCell.x,
+ m_rtClient.top + MONTHCAL_HEADER_BTN_VMARGIN, m_szCell.x,
+ m_szCell.x);
+ m_rtHSep.Set(
+ m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN + MONTHCAL_HMARGIN,
+ m_rtWeek.bottom() - MONTHCAL_VMARGIN,
+ m_rtClient.width - (MONTHCAL_HEADER_BTN_HMARGIN + MONTHCAL_HMARGIN) * 2,
+ MONTHCAL_HSEP_HEIGHT);
+ m_rtDates.Set(m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN,
+ m_rtWeek.bottom(),
+ m_rtClient.width - MONTHCAL_HEADER_BTN_HMARGIN * 2,
+ m_szCell.y * (MONTHCAL_ROWS - 3) +
+ MONTHCAL_VMARGIN * (MONTHCAL_ROWS - 3) * 2);
+ }
+ CalDateItem();
+}
+
+void IFWL_MonthCalendar::CalDateItem() {
+ FX_BOOL bNewWeek = FALSE;
+ int32_t iWeekOfMonth = 0;
+ FX_FLOAT fLeft = m_rtDates.left;
+ FX_FLOAT fTop = m_rtDates.top;
+ int32_t iCount = m_arrDates.GetSize();
+ for (int32_t i = 0; i < iCount; i++) {
+ FWL_DATEINFO* pDateInfo = m_arrDates.GetAt(i);
+ if (bNewWeek) {
+ iWeekOfMonth++;
+ bNewWeek = FALSE;
+ }
+ pDateInfo->rect.Set(
+ fLeft + pDateInfo->iDayOfWeek * (m_szCell.x + (MONTHCAL_HMARGIN * 2)),
+ fTop + iWeekOfMonth * (m_szCell.y + (MONTHCAL_VMARGIN * 2)),
+ m_szCell.x + (MONTHCAL_HMARGIN * 2),
+ m_szCell.y + (MONTHCAL_VMARGIN * 2));
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_WeekNumbers) {
+ pDateInfo->rect.Offset(m_fWeekNumWid, 0);
+ }
+ if (pDateInfo->iDayOfWeek >= 6) {
+ bNewWeek = TRUE;
+ }
+ }
+}
+
+void IFWL_MonthCalendar::GetCapValue() {
+ if (!m_pProperties->m_pThemeProvider) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
+ CFWL_ThemePart part;
+ part.m_pWidget = this;
+ m_fHeadWid = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::HeaderWidth));
+ m_fHeadHei = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::HeaderHeight));
+ m_fHeadBtnWid = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::HeaderBtnWidth));
+ m_fHeadBtnHei = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::HeaderBtnHeight));
+ m_fHeadBtnHMargin = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::HeaderBtnHMargin));
+ m_fHeadBtnVMargin = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::HeaderBtnVMargin));
+ m_fHeadTextWid = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::HeaderTextWidth));
+ m_fHeadTextHei = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::HeaderTextHeight));
+ m_fHeadTextHMargin = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::HeaderTextHMargin));
+ m_fHeadTextVMargin = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::HeaderTextVMargin));
+ m_fHSepWid = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::HSepWidth));
+ m_fHSepHei = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::HSepHeight));
+ m_fWeekNumWid = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::WeekNumWidth));
+ m_fSepDOffset = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::SepDOffset));
+ m_fSepX = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::SepX));
+ m_fSepY = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::SepY));
+ m_fWeekNumHeigh = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::WeekNumHeight));
+ m_fWeekWid = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::WeekWidth));
+ m_fWeekHei = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::WeekHeight));
+ m_fDateCellWid = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::DatesCellWidth));
+ m_fDateCellHei = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::DatesCellHeight));
+ m_fTodayWid = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::TodayWidth));
+ m_fTodayHei = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::TodayHeight));
+ m_fTodayFlagWid = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::TodayFlagWidth));
+ m_fMCWid = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::Width));
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_WeekNumbers) {
+ m_fMCWid += m_fWeekNumWid;
+ }
+ m_fMCHei = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::Height));
+}
+
+int32_t IFWL_MonthCalendar::CalWeekNumber(int32_t iYear,
+ int32_t iMonth,
+ int32_t iDay) {
+ return 0;
+}
+
+FX_BOOL IFWL_MonthCalendar::GetMinDate(int32_t& iYear,
+ int32_t& iMonth,
+ int32_t& iDay) {
+ iYear = m_dtMin.iYear;
+ iMonth = m_dtMin.iMonth;
+ iDay = m_dtMin.iDay;
+ return TRUE;
+}
+
+FX_BOOL IFWL_MonthCalendar::SetMinDate(int32_t iYear,
+ int32_t iMonth,
+ int32_t iDay) {
+ m_dtMin = DATE(iYear, iMonth, iDay);
+ return TRUE;
+}
+
+FX_BOOL IFWL_MonthCalendar::GetMaxDate(int32_t& iYear,
+ int32_t& iMonth,
+ int32_t& iDay) {
+ iYear = m_dtMax.iYear;
+ iMonth = m_dtMax.iMonth;
+ iDay = m_dtMax.iDay;
+ return TRUE;
+}
+
+FX_BOOL IFWL_MonthCalendar::SetMaxDate(int32_t iYear,
+ int32_t iMonth,
+ int32_t iDay) {
+ m_dtMax = DATE(iYear, iMonth, iDay);
+ return TRUE;
+}
+
+FX_BOOL IFWL_MonthCalendar::InitDate() {
+ if (m_pProperties->m_pDataProvider) {
+ IFWL_MonthCalendarDP* pDateProv =
+ static_cast<IFWL_MonthCalendarDP*>(m_pProperties->m_pDataProvider);
+ m_iYear = pDateProv->GetCurYear(this);
+ m_iMonth = pDateProv->GetCurMonth(this);
+ m_iDay = pDateProv->GetCurDay(this);
+ m_iCurYear = m_iYear;
+ m_iCurMonth = m_iMonth;
+ } else {
+ m_iDay = 1;
+ m_iMonth = 1;
+ m_iYear = 1;
+ m_iCurYear = m_iYear;
+ m_iCurMonth = m_iMonth;
+ }
+ GetTodayText(m_iYear, m_iMonth, m_iDay, m_wsToday);
+ GetHeadText(m_iCurYear, m_iCurMonth, m_wsHead);
+ m_dtMin = DATE(1500, 12, 1);
+ m_dtMax = DATE(2200, 1, 1);
+ return TRUE;
+}
+
+void IFWL_MonthCalendar::ClearDateItem() {
+ for (int32_t i = 0; i < m_arrDates.GetSize(); i++)
+ delete m_arrDates.GetAt(i);
+
+ m_arrDates.RemoveAll();
+}
+
+void IFWL_MonthCalendar::ReSetDateItem() {
+ m_pDateTime->Set(m_iCurYear, m_iCurMonth, 1);
+ int32_t iDays = FX_DaysInMonth(m_iCurYear, m_iCurMonth);
+ int32_t iDayOfWeek = m_pDateTime->GetDayOfWeek();
+ for (int32_t i = 0; i < iDays; i++) {
+ if (iDayOfWeek >= 7) {
+ iDayOfWeek = 0;
+ }
+ CFX_WideString wsDay;
+ wsDay.Format(L"%d", i + 1);
+ uint32_t dwStates = 0;
+ if (m_iYear == m_iCurYear && m_iMonth == m_iCurMonth && m_iDay == (i + 1)) {
+ dwStates |= FWL_ITEMSTATE_MCD_Flag;
+ }
+ if (m_arrSelDays.Find(i + 1) != -1) {
+ dwStates |= FWL_ITEMSTATE_MCD_Selected;
+ }
+ CFX_RectF rtDate;
+ rtDate.Set(0, 0, 0, 0);
+ m_arrDates.Add(
+ new FWL_DATEINFO(i + 1, iDayOfWeek, dwStates, rtDate, wsDay));
+ iDayOfWeek++;
+ }
+}
+
+FX_BOOL IFWL_MonthCalendar::NextMonth() {
+ int32_t iYear = m_iCurYear, iMonth = m_iCurMonth;
+ if (iMonth >= 12) {
+ iMonth = 1;
+ iYear++;
+ } else {
+ iMonth++;
+ }
+ DATE dt(m_iCurYear, m_iCurMonth, 1);
+ if (!(dt < m_dtMax)) {
+ return FALSE;
+ }
+ m_iCurYear = iYear, m_iCurMonth = iMonth;
+ ChangeToMonth(m_iCurYear, m_iCurMonth);
+ return TRUE;
+}
+
+FX_BOOL IFWL_MonthCalendar::PrevMonth() {
+ int32_t iYear = m_iCurYear, iMonth = m_iCurMonth;
+ if (iMonth <= 1) {
+ iMonth = 12;
+ iYear--;
+ } else {
+ iMonth--;
+ }
+ DATE dt(m_iCurYear, m_iCurMonth, 1);
+ if (!(dt > m_dtMin)) {
+ return FALSE;
+ }
+ m_iCurYear = iYear, m_iCurMonth = iMonth;
+ ChangeToMonth(m_iCurYear, m_iCurMonth);
+ return TRUE;
+}
+
+void IFWL_MonthCalendar::ChangeToMonth(int32_t iYear, int32_t iMonth) {
+ m_iCurYear = iYear;
+ m_iCurMonth = iMonth;
+ m_iHovered = -1;
+ ClearDateItem();
+ ReSetDateItem();
+ CalDateItem();
+ GetHeadText(m_iCurYear, m_iCurMonth, m_wsHead);
+}
+
+FX_BOOL IFWL_MonthCalendar::RemoveSelDay(int32_t iDay, FX_BOOL bAll) {
+ if (iDay == -1 && !bAll) {
+ return FALSE;
+ }
+ if (bAll) {
+ int32_t iCount = m_arrSelDays.GetSize();
+ int32_t iDatesCount = m_arrDates.GetSize();
+ for (int32_t i = 0; i < iCount; i++) {
+ int32_t iSelDay = m_arrSelDays.GetAt(i);
+ if (iSelDay <= iDatesCount) {
+ FWL_DATEINFO* pDateInfo = m_arrDates.GetAt(iSelDay - 1);
+ pDateInfo->dwStates &= ~FWL_ITEMSTATE_MCD_Selected;
+ }
+ }
+ m_arrSelDays.RemoveAll();
+ } else {
+ int32_t index = m_arrSelDays.Find(iDay);
+ if (index == -1) {
+ return FALSE;
+ }
+ int32_t iSelDay = m_arrSelDays.GetAt(iDay);
+ int32_t iDatesCount = m_arrDates.GetSize();
+ if (iSelDay <= iDatesCount) {
+ FWL_DATEINFO* pDateInfo = m_arrDates.GetAt(iSelDay - 1);
+ pDateInfo->dwStates &= ~FWL_ITEMSTATE_MCD_Selected;
+ }
+ m_arrSelDays.RemoveAt(index);
+ }
+ return TRUE;
+}
+
+FX_BOOL IFWL_MonthCalendar::AddSelDay(int32_t iDay) {
+ ASSERT(iDay > 0);
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_MultiSelect) {
+ } else {
+ if (m_arrSelDays.Find(iDay) == -1) {
+ RemoveSelDay(-1, TRUE);
+ if (iDay <= m_arrDates.GetSize()) {
+ FWL_DATEINFO* pDateInfo = m_arrDates.GetAt(iDay - 1);
+ pDateInfo->dwStates |= FWL_ITEMSTATE_MCD_Selected;
+ }
+ m_arrSelDays.Add(iDay);
+ }
+ }
+ return TRUE;
+}
+
+FX_BOOL IFWL_MonthCalendar::JumpToToday() {
+ if (m_iYear != m_iCurYear || m_iMonth != m_iCurMonth) {
+ m_iCurYear = m_iYear;
+ m_iCurMonth = m_iMonth;
+ ChangeToMonth(m_iYear, m_iMonth);
+ AddSelDay(m_iDay);
+ } else {
+ if (m_arrSelDays.Find(m_iDay) == -1) {
+ AddSelDay(m_iDay);
+ }
+ }
+ return TRUE;
+}
+
+void IFWL_MonthCalendar::GetHeadText(int32_t iYear,
+ int32_t iMonth,
+ CFX_WideString& wsHead) {
+ ASSERT(iMonth > 0 && iMonth < 13);
+ static const FX_WCHAR* const pMonth[] = {
+ L"January", L"February", L"March", L"April",
+ L"May", L"June", L"July", L"August",
+ L"September", L"October", L"November", L"December"};
+ wsHead.Format(L"%s, %d", pMonth[iMonth - 1], iYear);
+}
+
+void IFWL_MonthCalendar::GetTodayText(int32_t iYear,
+ int32_t iMonth,
+ int32_t iDay,
+ CFX_WideString& wsToday) {
+ wsToday.Format(L", %d/%d/%d", iDay, iMonth, iYear);
+}
+
+int32_t IFWL_MonthCalendar::GetDayAtPoint(FX_FLOAT x, FX_FLOAT y) {
+ int32_t iCount = m_arrDates.GetSize();
+ for (int32_t i = 0; i < iCount; i++) {
+ FWL_DATEINFO* pDateInfo = m_arrDates.GetAt(i);
+ if (pDateInfo->rect.Contains(x, y)) {
+ return ++i;
+ }
+ }
+ return -1;
+}
+
+FX_BOOL IFWL_MonthCalendar::GetDayRect(int32_t iDay, CFX_RectF& rtDay) {
+ if (iDay <= 0 || iDay > m_arrDates.GetSize()) {
+ return FALSE;
+ }
+ FWL_DATEINFO* pDateInfo = m_arrDates[iDay - 1];
+ if (!pDateInfo)
+ return FALSE;
+ rtDay = pDateInfo->rect;
+ return TRUE;
+}
+
+CFWL_MonthCalendarImpDelegate::CFWL_MonthCalendarImpDelegate(
+ IFWL_MonthCalendar* pOwner)
+ : m_pOwner(pOwner) {}
+
+void CFWL_MonthCalendarImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
+ if (!pMessage)
+ 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::Key: {
+ 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;
+ }
+ default: { break; }
+ }
+ CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);
+}
+
+void CFWL_MonthCalendarImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ m_pOwner->DrawWidget(pGraphics, pMatrix);
+}
+
+void CFWL_MonthCalendarImpDelegate::OnActivate(CFWL_Message* pMsg) {}
+
+void CFWL_MonthCalendarImpDelegate::OnFocusChanged(CFWL_Message* pMsg,
+ FX_BOOL bSet) {
+ if (bSet) {
+ m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
+ } else {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
+ }
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+}
+
+void CFWL_MonthCalendarImpDelegate::OnLButtonDown(CFWL_MsgMouse* pMsg) {
+ if (m_pOwner->m_rtLBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_iLBtnPartStates = CFWL_PartState_Pressed;
+ m_pOwner->PrevMonth();
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ } else if (m_pOwner->m_rtRBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_iRBtnPartStates |= CFWL_PartState_Pressed;
+ m_pOwner->NextMonth();
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ } else if (m_pOwner->m_rtToday.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ if ((m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_NoToday) ==
+ 0) {
+ m_pOwner->JumpToToday();
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ }
+ } else {
+ if (m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_MultiSelect) {
+ } else {
+ int32_t iOldSel = 0;
+ if (m_pOwner->m_arrSelDays.GetSize() > 0) {
+ iOldSel = m_pOwner->m_arrSelDays[0];
+ } else {
+ return;
+ }
+ int32_t iCurSel = m_pOwner->GetDayAtPoint(pMsg->m_fx, pMsg->m_fy);
+ FX_BOOL bSelChanged = iCurSel > 0 && iCurSel != iOldSel;
+ if (bSelChanged) {
+ FWL_DATEINFO* lpDatesInfo = m_pOwner->m_arrDates.GetAt(iCurSel - 1);
+ CFX_RectF rtInvalidate(lpDatesInfo->rect);
+ if (iOldSel > 0) {
+ lpDatesInfo = m_pOwner->m_arrDates.GetAt(iOldSel - 1);
+ rtInvalidate.Union(lpDatesInfo->rect);
+ }
+ m_pOwner->AddSelDay(iCurSel);
+ CFWL_EvtClick wmClick;
+ wmClick.m_pSrcTarget = m_pOwner;
+ m_pOwner->DispatchEvent(&wmClick);
+ CFWL_EventMcdDateChanged wmDateSelected;
+ wmDateSelected.m_iStartDay = iCurSel;
+ wmDateSelected.m_iEndDay = iCurSel;
+ wmDateSelected.m_iOldMonth = m_pOwner->m_iCurMonth;
+ wmDateSelected.m_iOldYear = m_pOwner->m_iCurYear;
+ wmDateSelected.m_pSrcTarget = m_pOwner;
+ m_pOwner->DispatchEvent(&wmDateSelected);
+ m_pOwner->Repaint(&rtInvalidate);
+ }
+ }
+ }
+}
+
+void CFWL_MonthCalendarImpDelegate::OnLButtonUp(CFWL_MsgMouse* pMsg) {
+ if (m_pOwner->m_rtLBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_iLBtnPartStates = 0;
+ m_pOwner->Repaint(&m_pOwner->m_rtLBtn);
+ } else if (m_pOwner->m_rtRBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_iRBtnPartStates = 0;
+ m_pOwner->Repaint(&m_pOwner->m_rtRBtn);
+ } else if (m_pOwner->m_rtDates.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ int32_t iDay = m_pOwner->GetDayAtPoint(pMsg->m_fx, pMsg->m_fy);
+ if (iDay != -1) {
+ m_pOwner->AddSelDay(iDay);
+ }
+ }
+}
+
+void CFWL_MonthCalendarImpDelegate::OnMouseMove(CFWL_MsgMouse* pMsg) {
+ if (m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_MultiSelect) {
+ return;
+ }
+ FX_BOOL bRepaint = FALSE;
+ CFX_RectF rtInvalidate;
+ rtInvalidate.Set(0, 0, 0, 0);
+ if (m_pOwner->m_rtDates.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ int32_t iHover = m_pOwner->GetDayAtPoint(pMsg->m_fx, pMsg->m_fy);
+ bRepaint = m_pOwner->m_iHovered != iHover;
+ if (bRepaint) {
+ if (m_pOwner->m_iHovered > 0) {
+ m_pOwner->GetDayRect(m_pOwner->m_iHovered, rtInvalidate);
+ }
+ if (iHover > 0) {
+ CFX_RectF rtDay;
+ m_pOwner->GetDayRect(iHover, rtDay);
+ if (rtInvalidate.IsEmpty()) {
+ rtInvalidate = rtDay;
+ } else {
+ rtInvalidate.Union(rtDay);
+ }
+ }
+ }
+ m_pOwner->m_iHovered = iHover;
+ } else {
+ bRepaint = m_pOwner->m_iHovered > 0;
+ if (bRepaint) {
+ m_pOwner->GetDayRect(m_pOwner->m_iHovered, rtInvalidate);
+ }
+ m_pOwner->m_iHovered = -1;
+ }
+ if (bRepaint && !rtInvalidate.IsEmpty()) {
+ m_pOwner->Repaint(&rtInvalidate);
+ }
+}
+
+void CFWL_MonthCalendarImpDelegate::OnMouseLeave(CFWL_MsgMouse* pMsg) {
+ if (m_pOwner->m_iHovered > 0) {
+ CFX_RectF rtInvalidate;
+ rtInvalidate.Set(0, 0, 0, 0);
+ m_pOwner->GetDayRect(m_pOwner->m_iHovered, rtInvalidate);
+ m_pOwner->m_iHovered = -1;
+ if (!rtInvalidate.IsEmpty()) {
+ m_pOwner->Repaint(&rtInvalidate);
+ }
+ }
+}
+
+FWL_DATEINFO::FWL_DATEINFO(int32_t day,
+ int32_t dayofweek,
+ uint32_t dwSt,
+ CFX_RectF rc,
+ CFX_WideString& wsday)
+ : iDay(day),
+ iDayOfWeek(dayofweek),
+ dwStates(dwSt),
+ rect(rc),
+ wsDay(wsday) {}
+
+FWL_DATEINFO::~FWL_DATEINFO() {}
diff --git a/xfa/fwl/core/ifwl_monthcalendar.h b/xfa/fwl/core/ifwl_monthcalendar.h
new file mode 100644
index 0000000000..340acf0bcc
--- /dev/null
+++ b/xfa/fwl/core/ifwl_monthcalendar.h
@@ -0,0 +1,280 @@
+// 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_MONTHCALENDAR_H_
+#define XFA_FWL_CORE_IFWL_MONTHCALENDAR_H_
+
+#include "xfa/fgas/localization/fgas_datetime.h"
+#include "xfa/fwl/core/cfwl_event.h"
+#include "xfa/fwl/core/cfwl_widgetimpproperties.h"
+#include "xfa/fwl/core/ifwl_dataprovider.h"
+#include "xfa/fwl/core/ifwl_widget.h"
+
+#define FWL_CLASS_MonthCalendar L"FWL_MONTHCALENDAR"
+#define FWL_STYLEEXT_MCD_MultiSelect (1L << 0)
+#define FWL_STYLEEXT_MCD_NoToday (1L << 1)
+#define FWL_STYLEEXT_MCD_NoTodayCircle (1L << 2)
+#define FWL_STYLEEXT_MCD_WeekNumbers (1L << 3)
+#define FWL_ITEMSTATE_MCD_Nomal (0L << 0)
+#define FWL_ITEMSTATE_MCD_Flag (1L << 0)
+#define FWL_ITEMSTATE_MCD_Selected (1L << 1)
+#define FWL_ITEMSTATE_MCD_Focused (1L << 2)
+
+FWL_EVENT_DEF(CFWL_Event_McdDateSelected,
+ CFWL_EventType::DataSelected,
+ int32_t m_iStartDay;
+ int32_t m_iEndDay;)
+
+FWL_EVENT_DEF(CFWL_EventMcdDateChanged,
+ CFWL_EventType::DateChanged,
+ int32_t m_iOldYear;
+ int32_t m_iOldMonth;
+ int32_t m_iStartDay;
+ int32_t m_iEndDay;)
+
+class CFWL_MonthCalendarImpDelegate;
+class CFWL_MsgMouse;
+class CFWL_WidgetImpProperties;
+class IFWL_Widget;
+
+struct FWL_DATEINFO;
+
+extern uint8_t FX_DaysInMonth(int32_t iYear, uint8_t iMonth);
+
+class IFWL_MonthCalendarDP : public IFWL_DataProvider {
+ public:
+ virtual int32_t GetCurDay(IFWL_Widget* pWidget) = 0;
+ virtual int32_t GetCurMonth(IFWL_Widget* pWidget) = 0;
+ virtual int32_t GetCurYear(IFWL_Widget* pWidget) = 0;
+};
+
+class IFWL_MonthCalendar : public IFWL_Widget {
+ public:
+ static IFWL_MonthCalendar* Create(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+
+ IFWL_MonthCalendar(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+ ~IFWL_MonthCalendar() override;
+
+ // FWL_WidgetImp
+ FWL_Error GetClassName(CFX_WideString& wsClass) const override;
+ FWL_Type GetClassID() const override;
+ FWL_Error Initialize() override;
+ FWL_Error Finalize() override;
+ FWL_Error GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize = FALSE) override;
+ FWL_Error Update() override;
+ FWL_Error DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
+ int32_t CountSelect();
+ FX_BOOL GetSelect(int32_t& iYear,
+ int32_t& iMonth,
+ int32_t& iDay,
+ int32_t nIndex = 0);
+ FX_BOOL SetSelect(int32_t iYear, int32_t iMonth, int32_t iDay);
+
+ protected:
+ struct DATE {
+ DATE() : iYear(0), iMonth(0), iDay(0) {}
+ DATE(int32_t year, int32_t month, int32_t day)
+ : iYear(year), iMonth(month), iDay(day) {}
+ FX_BOOL operator<(const DATE& right) {
+ if (iYear < right.iYear) {
+ return TRUE;
+ } else if (iYear == right.iYear) {
+ if (iMonth < right.iMonth) {
+ return TRUE;
+ } else if (iMonth == right.iMonth) {
+ return iDay < right.iDay;
+ }
+ }
+ return FALSE;
+ }
+ FX_BOOL operator>(const DATE& right) {
+ if (iYear > right.iYear) {
+ return TRUE;
+ } else if (iYear == right.iYear) {
+ if (iMonth > right.iMonth) {
+ return TRUE;
+ } else if (iMonth == right.iMonth) {
+ return iDay > right.iDay;
+ }
+ }
+ return FALSE;
+ }
+ int32_t iYear;
+ int32_t iMonth;
+ int32_t iDay;
+ };
+
+ void DrawBkground(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix);
+ void DrawHeadBK(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix);
+ void DrawLButton(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix);
+ void DrawRButton(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix);
+ void DrawCaption(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix);
+ void DrawSeperator(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix);
+ void DrawDatesInBK(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix);
+ void DrawWeek(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix);
+ void DrawWeekNumber(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix);
+ void DrawWeekNumberSep(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix);
+ void DrawToday(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix);
+ void DrawDatesIn(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix);
+ void DrawDatesOut(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix);
+ void DrawDatesInCircle(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix);
+ void DrawTodayCircle(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix);
+ CFX_SizeF CalcSize(FX_BOOL bAutoSize = FALSE);
+ void LayOut();
+ void CalcHeadSize();
+ void CalcTodaySize();
+ void CalDateItem();
+ void GetCapValue();
+ int32_t CalWeekNumber(int32_t iYear, int32_t iMonth, int32_t iDay);
+ FX_BOOL GetMinDate(int32_t& iYear, int32_t& iMonth, int32_t& iDay);
+ FX_BOOL SetMinDate(int32_t iYear, int32_t iMonth, int32_t iDay);
+ FX_BOOL GetMaxDate(int32_t& iYear, int32_t& iMonth, int32_t& iDay);
+ FX_BOOL SetMaxDate(int32_t iYear, int32_t iMonth, int32_t iDay);
+ FX_BOOL InitDate();
+ void ClearDateItem();
+ void ReSetDateItem();
+ FX_BOOL NextMonth();
+ FX_BOOL PrevMonth();
+ void ChangeToMonth(int32_t iYear, int32_t iMonth);
+ FX_BOOL RemoveSelDay(int32_t iDay, FX_BOOL bAll = FALSE);
+ FX_BOOL AddSelDay(int32_t iDay);
+ FX_BOOL JumpToToday();
+ void GetHeadText(int32_t iYear, int32_t iMonth, CFX_WideString& wsHead);
+ void GetTodayText(int32_t iYear,
+ int32_t iMonth,
+ int32_t iDay,
+ CFX_WideString& wsToday);
+ int32_t GetDayAtPoint(FX_FLOAT x, FX_FLOAT y);
+ FX_BOOL GetDayRect(int32_t iDay, CFX_RectF& rtDay);
+
+ FX_BOOL m_bInit;
+ CFX_RectF m_rtHead;
+ CFX_RectF m_rtWeek;
+ CFX_RectF m_rtLBtn;
+ CFX_RectF m_rtRBtn;
+ CFX_RectF m_rtDates;
+ CFX_RectF m_rtHSep;
+ CFX_RectF m_rtHeadText;
+ CFX_RectF m_rtToday;
+ CFX_RectF m_rtTodayFlag;
+ CFX_RectF m_rtWeekNum;
+ CFX_RectF m_rtWeekNumSep;
+ CFX_RectF m_rtTemp;
+ CFX_WideString m_wsHead;
+ CFX_WideString m_wsToday;
+ std::unique_ptr<CFX_DateTime> m_pDateTime;
+ CFX_ArrayTemplate<FWL_DATEINFO*> m_arrDates;
+ int32_t m_iCurYear;
+ int32_t m_iCurMonth;
+ int32_t m_iYear;
+ int32_t m_iMonth;
+ int32_t m_iDay;
+ int32_t m_iHovered;
+ int32_t m_iLBtnPartStates;
+ int32_t m_iRBtnPartStates;
+ DATE m_dtMin;
+ DATE m_dtMax;
+ CFX_SizeF m_szHead;
+ CFX_SizeF m_szCell;
+ CFX_SizeF m_szToday;
+ CFX_ArrayTemplate<int32_t> m_arrSelDays;
+ int32_t m_iMaxSel;
+ CFX_RectF m_rtClient;
+ FX_FLOAT m_fHeadWid;
+ FX_FLOAT m_fHeadHei;
+ FX_FLOAT m_fHeadBtnWid;
+ FX_FLOAT m_fHeadBtnHei;
+ FX_FLOAT m_fHeadBtnHMargin;
+ FX_FLOAT m_fHeadBtnVMargin;
+ FX_FLOAT m_fHeadTextWid;
+ FX_FLOAT m_fHeadTextHei;
+ FX_FLOAT m_fHeadTextHMargin;
+ FX_FLOAT m_fHeadTextVMargin;
+ FX_FLOAT m_fHSepWid;
+ FX_FLOAT m_fHSepHei;
+ FX_FLOAT m_fWeekNumWid;
+ FX_FLOAT m_fSepDOffset;
+ FX_FLOAT m_fSepX;
+ FX_FLOAT m_fSepY;
+ FX_FLOAT m_fWeekNumHeigh;
+ FX_FLOAT m_fWeekWid;
+ FX_FLOAT m_fWeekHei;
+ FX_FLOAT m_fDateCellWid;
+ FX_FLOAT m_fDateCellHei;
+ FX_FLOAT m_fTodayWid;
+ FX_FLOAT m_fTodayHei;
+ FX_FLOAT m_fTodayFlagWid;
+ FX_FLOAT m_fMCWid;
+ FX_FLOAT m_fMCHei;
+ friend class CFWL_MonthCalendarImpDelegate;
+};
+
+struct FWL_DATEINFO {
+ FWL_DATEINFO(int32_t day,
+ int32_t dayofweek,
+ uint32_t dwSt,
+ CFX_RectF rc,
+ CFX_WideString& wsday);
+ ~FWL_DATEINFO();
+
+ int32_t iDay;
+ int32_t iDayOfWeek;
+ uint32_t dwStates;
+ CFX_RectF rect;
+ CFX_WideString wsDay;
+};
+
+class CFWL_MonthCalendarImpDelegate : public CFWL_WidgetImpDelegate {
+ public:
+ CFWL_MonthCalendarImpDelegate(IFWL_MonthCalendar* pOwner);
+ void OnProcessMessage(CFWL_Message* pMessage) override;
+ void OnDrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
+
+ protected:
+ void OnActivate(CFWL_Message* pMsg);
+ void OnFocusChanged(CFWL_Message* pMsg, FX_BOOL bSet = TRUE);
+ void OnLButtonDown(CFWL_MsgMouse* pMsg);
+ void OnLButtonUp(CFWL_MsgMouse* pMsg);
+ void OnMouseMove(CFWL_MsgMouse* pMsg);
+ void OnMouseLeave(CFWL_MsgMouse* pMsg);
+ IFWL_MonthCalendar* m_pOwner;
+};
+
+#endif // XFA_FWL_CORE_IFWL_MONTHCALENDAR_H_
diff --git a/xfa/fwl/core/ifwl_picturebox.cpp b/xfa/fwl/core/ifwl_picturebox.cpp
new file mode 100644
index 0000000000..12d8713971
--- /dev/null
+++ b/xfa/fwl/core/ifwl_picturebox.cpp
@@ -0,0 +1,154 @@
+// 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 "xfa/fwl/core/fwl_noteimp.h"
+#include "xfa/fwl/lightwidget/cfwl_picturebox.h"
+
+// static
+IFWL_PictureBox* IFWL_PictureBox::Create(
+ const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter) {
+ return new IFWL_PictureBox(properties, pOuter);
+}
+
+IFWL_PictureBox::IFWL_PictureBox(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter)
+ : IFWL_Widget(properties, pOuter),
+ m_bTop(FALSE),
+ m_bVCenter(FALSE),
+ m_bButton(FALSE) {
+ m_rtClient.Reset();
+ m_rtImage.Reset();
+ m_matrix.SetIdentity();
+}
+
+IFWL_PictureBox::~IFWL_PictureBox() {}
+
+FWL_Error IFWL_PictureBox::GetClassName(CFX_WideString& wsClass) const {
+ wsClass = FWL_CLASS_PictureBox;
+ return FWL_Error::Succeeded;
+}
+
+FWL_Type IFWL_PictureBox::GetClassID() const {
+ return FWL_Type::PictureBox;
+}
+
+FWL_Error IFWL_PictureBox::Initialize() {
+ if (IFWL_Widget::Initialize() != FWL_Error::Succeeded)
+ return FWL_Error::Indefinite;
+
+ m_pDelegate = new CFWL_PictureBoxImpDelegate(this);
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_PictureBox::Finalize() {
+ delete m_pDelegate;
+ m_pDelegate = nullptr;
+ return IFWL_Widget::Finalize();
+}
+
+FWL_Error IFWL_PictureBox::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
+ if (bAutoSize) {
+ rect.Set(0, 0, 0, 0);
+ if (!m_pProperties->m_pDataProvider)
+ return FWL_Error::Indefinite;
+ CFX_DIBitmap* pBitmap =
+ static_cast<IFWL_PictureBoxDP*>(m_pProperties->m_pDataProvider)
+ ->GetPicture(this);
+ if (pBitmap) {
+ rect.Set(0, 0, (FX_FLOAT)pBitmap->GetWidth(),
+ (FX_FLOAT)pBitmap->GetHeight());
+ }
+ IFWL_Widget::GetWidgetRect(rect, TRUE);
+ } else {
+ rect = m_pProperties->m_rtWidget;
+ }
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_PictureBox::Update() {
+ if (IsLocked()) {
+ return FWL_Error::Succeeded;
+ }
+ if (!m_pProperties->m_pThemeProvider) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ GetClientRect(m_rtClient);
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_PictureBox::DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ if (!pGraphics)
+ return FWL_Error::Indefinite;
+ if (!m_pProperties->m_pThemeProvider)
+ return FWL_Error::Indefinite;
+ IFWL_ThemeProvider* pTheme = GetAvailableTheme();
+ if (HasBorder()) {
+ DrawBorder(pGraphics, CFWL_Part::Border, pTheme, pMatrix);
+ }
+ if (HasEdge()) {
+ DrawEdge(pGraphics, CFWL_Part::Edge, pTheme, pMatrix);
+ }
+ DrawBkground(pGraphics, pTheme, pMatrix);
+ return FWL_Error::Succeeded;
+}
+
+void IFWL_PictureBox::DrawBkground(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix) {
+ IFWL_PictureBoxDP* pPictureDP =
+ static_cast<IFWL_PictureBoxDP*>(m_pProperties->m_pDataProvider);
+ if (!pPictureDP)
+ return;
+
+ CFX_DIBitmap* pPicture = pPictureDP->GetPicture(this);
+ CFX_Matrix matrix;
+ pPictureDP->GetMatrix(this, matrix);
+ if (!pPicture)
+ return;
+
+ matrix.Concat(*pMatrix);
+ FX_FLOAT fx = (FX_FLOAT)pPicture->GetWidth();
+ FX_FLOAT fy = (FX_FLOAT)pPicture->GetHeight();
+ if (fx > m_rtClient.width) {
+ fx = m_rtClient.width;
+ }
+ if (fy > m_rtClient.height) {
+ fy = m_rtClient.height;
+ }
+ pGraphics->DrawImage(pPicture, CFX_PointF((m_rtClient.width - fx) / 2,
+ (m_rtClient.height - fy) / 2),
+ &matrix);
+}
+
+FX_BOOL IFWL_PictureBox::VStyle(FX_BOOL dwStyle) {
+ switch (dwStyle & FWL_STYLEEXT_PTB_VAlignMask) {
+ case FWL_STYLEEXT_PTB_Top: {
+ return m_bTop = TRUE;
+ break;
+ }
+ case FWL_STYLEEXT_PTB_Vcenter: {
+ return m_bVCenter = TRUE;
+ break;
+ }
+ case FWL_STYLEEXT_PTB_Bottom: {
+ return m_bButton = TRUE;
+ break;
+ }
+ }
+ return FALSE;
+}
+
+CFWL_PictureBoxImpDelegate::CFWL_PictureBoxImpDelegate(IFWL_PictureBox* pOwner)
+ : m_pOwner(pOwner) {}
+
+void CFWL_PictureBoxImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ m_pOwner->DrawWidget(pGraphics, pMatrix);
+}
diff --git a/xfa/fwl/core/ifwl_picturebox.h b/xfa/fwl/core/ifwl_picturebox.h
new file mode 100644
index 0000000000..eb9c70efca
--- /dev/null
+++ b/xfa/fwl/core/ifwl_picturebox.h
@@ -0,0 +1,91 @@
+// 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 "xfa/fwl/core/cfwl_widgetimpproperties.h"
+#include "xfa/fwl/core/fwl_error.h"
+#include "xfa/fwl/core/ifwl_dataprovider.h"
+#include "xfa/fwl/core/ifwl_widget.h"
+
+#define FWL_CLASS_PictureBox L"FWL_PICTUREBOX"
+#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 CFWL_PictureBoxImpDelegate;
+class CFWL_WidgetImpProperties;
+class CFX_DIBitmap;
+class IFWL_Widget;
+
+class IFWL_PictureBoxDP : public IFWL_DataProvider {
+ public:
+ virtual CFX_DIBitmap* GetPicture(IFWL_Widget* pWidget) = 0;
+ virtual CFX_DIBitmap* GetErrorPicture(IFWL_Widget* pWidget) = 0;
+ virtual CFX_DIBitmap* GetInitialPicture(IFWL_Widget* pWidget) = 0;
+ virtual int32_t GetOpacity(IFWL_Widget* pWidget) = 0;
+ virtual int32_t GetFlipMode(IFWL_Widget* pWidget) = 0;
+ virtual FWL_Error GetMatrix(IFWL_Widget* pWidget, CFX_Matrix& matrix) = 0;
+};
+
+class IFWL_PictureBox : public IFWL_Widget {
+ public:
+ static IFWL_PictureBox* Create(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+
+ IFWL_PictureBox(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+ ~IFWL_PictureBox() override;
+
+ // IFWL_Widget
+ FWL_Error GetClassName(CFX_WideString& wsClass) const override;
+ FWL_Type GetClassID() const override;
+ FWL_Error Initialize() override;
+ FWL_Error Finalize() override;
+ FWL_Error GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize = FALSE) override;
+ FWL_Error Update() override;
+ FWL_Error DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
+
+ protected:
+ friend class CFWL_PictureBoxImpDelegate;
+
+ void DrawBkground(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix = nullptr);
+
+ FX_BOOL VStyle(FX_BOOL dwStyle);
+ CFX_RectF m_rtClient;
+ CFX_RectF m_rtImage;
+ CFX_Matrix m_matrix;
+ FX_BOOL m_bTop;
+ FX_BOOL m_bVCenter;
+ FX_BOOL m_bButton;
+};
+
+class CFWL_PictureBoxImpDelegate : public CFWL_WidgetImpDelegate {
+ public:
+ CFWL_PictureBoxImpDelegate(IFWL_PictureBox* pOwner);
+ void OnDrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
+
+ protected:
+ IFWL_PictureBox* m_pOwner;
+};
+
+#endif // XFA_FWL_CORE_IFWL_PICTUREBOX_H_
diff --git a/xfa/fwl/core/ifwl_pushbutton.cpp b/xfa/fwl/core/ifwl_pushbutton.cpp
new file mode 100644
index 0000000000..a3efb10296
--- /dev/null
+++ b/xfa/fwl/core/ifwl_pushbutton.cpp
@@ -0,0 +1,563 @@
+// 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 "xfa/fde/tto/fde_textout.h"
+#include "xfa/fwl/core/cfwl_message.h"
+#include "xfa/fwl/core/cfwl_themebackground.h"
+#include "xfa/fwl/core/cfwl_themetext.h"
+#include "xfa/fwl/core/fwl_noteimp.h"
+#include "xfa/fwl/core/ifwl_pushbutton.h"
+#include "xfa/fwl/core/ifwl_themeprovider.h"
+
+// static
+IFWL_PushButton* IFWL_PushButton::Create(
+ const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter) {
+ return new IFWL_PushButton(properties, pOuter);
+}
+
+IFWL_PushButton::IFWL_PushButton(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter)
+ : IFWL_Widget(properties, pOuter),
+ 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_Error IFWL_PushButton::GetClassName(CFX_WideString& wsClass) const {
+ wsClass = FWL_CLASS_PushButton;
+ return FWL_Error::Succeeded;
+}
+
+FWL_Type IFWL_PushButton::GetClassID() const {
+ return FWL_Type::PushButton;
+}
+
+FWL_Error IFWL_PushButton::Initialize() {
+ if (IFWL_Widget::Initialize() != FWL_Error::Succeeded)
+ return FWL_Error::Indefinite;
+
+ m_pDelegate = new CFWL_PushButtonImpDelegate(this);
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_PushButton::Finalize() {
+ delete m_pDelegate;
+ m_pDelegate = nullptr;
+ return IFWL_Widget::Finalize();
+}
+
+FWL_Error IFWL_PushButton::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
+ if (bAutoSize) {
+ rect.Set(0, 0, 0, 0);
+ if (!m_pProperties->m_pThemeProvider) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ CFX_WideString wsCaption;
+ IFWL_PushButtonDP* pData =
+ static_cast<IFWL_PushButtonDP*>(m_pProperties->m_pDataProvider);
+ if (pData) {
+ pData->GetCaption(this, wsCaption);
+ }
+ int32_t iLen = wsCaption.GetLength();
+ if (iLen > 0) {
+ CFX_SizeF sz = CalcTextSize(wsCaption, m_pProperties->m_pThemeProvider);
+ rect.Set(0, 0, sz.x, sz.y);
+ }
+ FX_FLOAT* fcaption =
+ static_cast<FX_FLOAT*>(GetThemeCapacity(CFWL_WidgetCapacity::Margin));
+ rect.Inflate(*fcaption, *fcaption);
+ IFWL_Widget::GetWidgetRect(rect, TRUE);
+ } else {
+ rect = m_pProperties->m_rtWidget;
+ }
+ return FWL_Error::Succeeded;
+}
+
+void IFWL_PushButton::SetStates(uint32_t dwStates, FX_BOOL bSet) {
+ if ((dwStates & FWL_WGTSTATE_Disabled) && bSet) {
+ m_pProperties->m_dwStates = FWL_WGTSTATE_Disabled;
+ return;
+ }
+ IFWL_Widget::SetStates(dwStates, bSet);
+}
+
+FWL_Error IFWL_PushButton::Update() {
+ if (IsLocked()) {
+ return FWL_Error::Indefinite;
+ }
+ 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);
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_PushButton::DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ if (!pGraphics)
+ return FWL_Error::Indefinite;
+ if (!m_pProperties->m_pThemeProvider)
+ return FWL_Error::Indefinite;
+ IFWL_PushButtonDP* pData =
+ static_cast<IFWL_PushButtonDP*>(m_pProperties->m_pDataProvider);
+ CFX_DIBitmap* pPicture = nullptr;
+ 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, m_pProperties->m_pThemeProvider,
+ pMatrix);
+ }
+ DrawBkground(pGraphics, m_pProperties->m_pThemeProvider, pMatrix);
+ CFX_Matrix matrix;
+ matrix.Concat(*pMatrix);
+ FX_FLOAT iPicwidth = 0;
+ FX_FLOAT ipicheight = 0;
+ CFX_WideString wsCaption;
+ if (pData) {
+ pData->GetCaption(this, wsCaption);
+ }
+ CFX_RectF rtText;
+ rtText.Set(0, 0, 0, 0);
+ if (!wsCaption.IsEmpty()) {
+ CalcTextRect(wsCaption, pTheme, 0, m_iTTOAlign, rtText);
+ }
+ switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_PSB_ModeMask) {
+ case FWL_STYLEEXT_PSB_TextOnly:
+ DrawText(pGraphics, m_pProperties->m_pThemeProvider, &matrix);
+ break;
+ case FWL_STYLEEXT_PSB_IconOnly:
+ if (pData) {
+ pPicture = pData->GetPicture(this);
+ }
+ if (pPicture) {
+ CFX_PointF point;
+ switch (m_iTTOAlign) {
+ case 0: {
+ point.x = m_rtClient.left;
+ point.y = m_rtClient.top;
+ break;
+ }
+ case 1: {
+ point.x = m_rtClient.left +
+ (m_rtClient.width / 2 - pPicture->GetWidth() / 2);
+ point.y = m_rtClient.top;
+ break;
+ }
+ case 2:
+ point.x = m_rtClient.left + m_rtClient.width - pPicture->GetWidth();
+ point.y = m_rtClient.top;
+ break;
+ case 4:
+ point.x = m_rtClient.left;
+ point.y = m_rtClient.top + m_rtClient.height / 2 -
+ pPicture->GetHeight() / 2;
+ break;
+ case 5:
+ point.x = m_rtClient.left +
+ (m_rtClient.width / 2 - pPicture->GetWidth() / 2);
+ point.y = m_rtClient.top + m_rtClient.height / 2 -
+ pPicture->GetHeight() / 2;
+ break;
+ case 6:
+ point.x = m_rtClient.left + m_rtClient.width - pPicture->GetWidth();
+ point.y = m_rtClient.top + m_rtClient.height / 2 -
+ pPicture->GetHeight() / 2;
+ break;
+ case 8:
+ point.x = m_rtClient.left;
+ point.y =
+ m_rtClient.top + m_rtClient.height - pPicture->GetHeight();
+ break;
+ case 9:
+ point.x = m_rtClient.left +
+ (m_rtClient.width / 2 - pPicture->GetWidth() / 2);
+ point.y =
+ m_rtClient.top + m_rtClient.height - pPicture->GetHeight();
+ break;
+ case 10:
+ point.x = m_rtClient.left + m_rtClient.width - pPicture->GetWidth();
+ point.y =
+ m_rtClient.top + m_rtClient.height - pPicture->GetHeight();
+ break;
+ }
+ pGraphics->DrawImage(pPicture, point, &matrix);
+ }
+ break;
+ case FWL_STYLEEXT_PSB_TextIcon:
+ if (pPicture) {
+ CFX_PointF point;
+ switch (m_iTTOAlign) {
+ case 0: {
+ point.x = m_rtClient.left;
+ point.y = m_rtClient.top;
+ iPicwidth = (FX_FLOAT)(pPicture->GetWidth() - 7);
+ ipicheight =
+ pPicture->GetHeight() / 2 - m_rtCaption.top - rtText.height / 2;
+ break;
+ }
+ case 1: {
+ point.x =
+ m_rtClient.left + (m_rtClient.width / 2 -
+ (pPicture->GetWidth() + rtText.width) / 2);
+ point.y = m_rtClient.top;
+ iPicwidth = pPicture->GetWidth() -
+ ((m_rtClient.width) / 2 - rtText.width / 2 - point.x) +
+ rtText.width / 2 - 7;
+ ipicheight =
+ pPicture->GetHeight() / 2 - m_rtCaption.top - rtText.height / 2;
+ break;
+ }
+ case 2:
+ point.x = m_rtClient.left + m_rtClient.width -
+ pPicture->GetWidth() - rtText.width;
+ point.y = m_rtClient.top;
+ iPicwidth = m_rtClient.left + m_rtClient.width - point.x -
+ pPicture->GetWidth() - rtText.width + 7;
+ ipicheight =
+ pPicture->GetHeight() / 2 - m_rtCaption.top - rtText.height / 2;
+ break;
+ case 4:
+ point.x = m_rtClient.left;
+ point.y = m_rtClient.top + m_rtClient.height / 2 -
+ pPicture->GetHeight() / 2;
+ iPicwidth = m_rtClient.left + pPicture->GetWidth() - 7;
+ break;
+ case 5:
+ point.x =
+ m_rtClient.left + (m_rtClient.width / 2 -
+ (pPicture->GetWidth() + rtText.width) / 2);
+ point.y = m_rtClient.top + m_rtClient.height / 2 -
+ pPicture->GetHeight() / 2;
+ iPicwidth = pPicture->GetWidth() -
+ ((m_rtClient.width) / 2 - rtText.width / 2 - point.x) +
+ rtText.width / 2 - 7;
+ break;
+ case 6:
+ point.x = m_rtClient.left + m_rtClient.width -
+ pPicture->GetWidth() - rtText.width;
+ point.y = m_rtClient.top + m_rtClient.height / 2 -
+ pPicture->GetHeight() / 2;
+ iPicwidth = m_rtClient.left + m_rtClient.width - point.x -
+ pPicture->GetWidth() - rtText.width + 7;
+ break;
+ case 8:
+ point.x = m_rtClient.left;
+ point.y =
+ m_rtClient.top + m_rtClient.height - pPicture->GetHeight();
+ iPicwidth = (FX_FLOAT)(pPicture->GetWidth() - 7);
+ ipicheight -= rtText.height / 2;
+ break;
+ case 9:
+ point.x =
+ m_rtClient.left + (m_rtClient.width / 2 -
+ (pPicture->GetWidth() + rtText.width) / 2);
+ point.y =
+ m_rtClient.top + m_rtClient.height - pPicture->GetHeight();
+ iPicwidth = pPicture->GetWidth() -
+ ((m_rtClient.width) / 2 - rtText.width / 2 - point.x) +
+ rtText.width / 2 - 7;
+ ipicheight -= rtText.height / 2;
+ break;
+ case 10:
+ point.x = m_rtClient.left + m_rtClient.width -
+ pPicture->GetWidth() - rtText.width;
+ point.y =
+ m_rtClient.top + m_rtClient.height - pPicture->GetHeight();
+ iPicwidth = m_rtClient.left + m_rtClient.width - point.x -
+ pPicture->GetWidth() - rtText.width + 7;
+ ipicheight -= rtText.height / 2;
+ break;
+ }
+ pGraphics->DrawImage(pPicture, point, &matrix);
+ }
+ matrix.e += m_rtClient.left + iPicwidth;
+ matrix.f += m_rtClient.top + ipicheight;
+ DrawText(pGraphics, m_pProperties->m_pThemeProvider, &matrix);
+ break;
+ }
+ return FWL_Error::Succeeded;
+}
+
+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);
+}
+
+void IFWL_PushButton::DrawText(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix) {
+ if (!m_pProperties->m_pDataProvider)
+ return;
+ CFX_WideString wsCaption;
+ m_pProperties->m_pDataProvider->GetCaption(this, wsCaption);
+ if (wsCaption.IsEmpty()) {
+ return;
+ }
+ CFWL_ThemeText param;
+ param.m_pWidget = this;
+ param.m_iPart = CFWL_Part::Caption;
+ param.m_dwStates = GetPartStates();
+ param.m_pGraphics = pGraphics;
+ if (pMatrix) {
+ param.m_matrix.Concat(*pMatrix);
+ }
+ param.m_rtPart = m_rtCaption;
+ param.m_wsText = wsCaption;
+ param.m_dwTTOStyles = m_dwTTOStyles;
+ param.m_iTTOAlign = m_iTTOAlign;
+ pTheme->DrawText(&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() {
+ m_iTTOAlign = FDE_TTOALIGNMENT_Center;
+ 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_Center | FWL_STYLEEXT_PSB_VCenter: {
+ m_iTTOAlign = FDE_TTOALIGNMENT_Center;
+ 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;
+ }
+ default: {}
+ }
+ m_dwTTOStyles = FDE_TTOSTYLE_SingleLine;
+ if (m_pProperties->m_dwStyleExes & FWL_WGTSTYLE_RTLReading) {
+ m_dwTTOStyles |= FDE_TTOSTYLE_RTL;
+ }
+}
+
+CFWL_PushButtonImpDelegate::CFWL_PushButtonImpDelegate(IFWL_PushButton* pOwner)
+ : m_pOwner(pOwner) {}
+
+void CFWL_PushButtonImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
+ if (!pMessage)
+ return;
+ if (!m_pOwner->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_WidgetImpDelegate::OnProcessMessage(pMessage);
+}
+
+void CFWL_PushButtonImpDelegate::OnProcessEvent(CFWL_Event* pEvent) {}
+
+void CFWL_PushButtonImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ m_pOwner->DrawWidget(pGraphics, pMatrix);
+}
+
+void CFWL_PushButtonImpDelegate::OnFocusChanged(CFWL_Message* pMsg,
+ FX_BOOL bSet) {
+ if (bSet) {
+ m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
+ } else {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
+ }
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+}
+
+void CFWL_PushButtonImpDelegate::OnLButtonDown(CFWL_MsgMouse* pMsg) {
+ if ((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) {
+ m_pOwner->SetFocus(TRUE);
+ }
+ m_pOwner->m_bBtnDown = TRUE;
+ m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_PSB_Hovered;
+ m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_PSB_Pressed;
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+}
+
+void CFWL_PushButtonImpDelegate::OnLButtonUp(CFWL_MsgMouse* pMsg) {
+ m_pOwner->m_bBtnDown = FALSE;
+ if (m_pOwner->m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Pressed;
+ m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_PSB_Hovered;
+ } else {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Hovered;
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Pressed;
+ }
+ if (m_pOwner->m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ CFWL_EvtClick wmClick;
+ wmClick.m_pSrcTarget = m_pOwner;
+ m_pOwner->DispatchEvent(&wmClick);
+ }
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+}
+
+void CFWL_PushButtonImpDelegate::OnMouseMove(CFWL_MsgMouse* pMsg) {
+ FX_BOOL bRepaint = FALSE;
+ if (m_pOwner->m_bBtnDown) {
+ if (m_pOwner->m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ if ((m_pOwner->m_pProperties->m_dwStates & FWL_STATE_PSB_Pressed) == 0) {
+ m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_PSB_Pressed;
+ bRepaint = TRUE;
+ }
+ if (m_pOwner->m_pProperties->m_dwStates & FWL_STATE_PSB_Hovered) {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Hovered;
+ bRepaint = TRUE;
+ }
+ } else {
+ if (m_pOwner->m_pProperties->m_dwStates & FWL_STATE_PSB_Pressed) {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Pressed;
+ bRepaint = TRUE;
+ }
+ if ((m_pOwner->m_pProperties->m_dwStates & FWL_STATE_PSB_Hovered) == 0) {
+ m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_PSB_Hovered;
+ bRepaint = TRUE;
+ }
+ }
+ } else {
+ if (!m_pOwner->m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ return;
+ }
+ if ((m_pOwner->m_pProperties->m_dwStates & FWL_STATE_PSB_Hovered) == 0) {
+ m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_PSB_Hovered;
+ bRepaint = TRUE;
+ }
+ }
+ if (bRepaint) {
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ }
+}
+
+void CFWL_PushButtonImpDelegate::OnMouseLeave(CFWL_MsgMouse* pMsg) {
+ m_pOwner->m_bBtnDown = FALSE;
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Hovered;
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Pressed;
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+}
+
+void CFWL_PushButtonImpDelegate::OnKeyDown(CFWL_MsgKey* pMsg) {
+ if (pMsg->m_dwKeyCode == FWL_VKEY_Return) {
+ CFWL_EvtMouse wmMouse;
+ wmMouse.m_pSrcTarget = m_pOwner;
+ wmMouse.m_dwCmd = FWL_MouseCommand::LeftButtonUp;
+ m_pOwner->DispatchEvent(&wmMouse);
+ CFWL_EvtClick wmClick;
+ wmClick.m_pSrcTarget = m_pOwner;
+ m_pOwner->DispatchEvent(&wmClick);
+ return;
+ }
+ if (pMsg->m_dwKeyCode != FWL_VKEY_Tab) {
+ return;
+ }
+ m_pOwner->DispatchKeyEvent(pMsg);
+}
diff --git a/xfa/fwl/core/ifwl_pushbutton.h b/xfa/fwl/core/ifwl_pushbutton.h
new file mode 100644
index 0000000000..9901c1a44c
--- /dev/null
+++ b/xfa/fwl/core/ifwl_pushbutton.h
@@ -0,0 +1,99 @@
+// 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 "xfa/fwl/core/cfwl_widgetimpproperties.h"
+#include "xfa/fwl/core/ifwl_dataprovider.h"
+#include "xfa/fwl/core/ifwl_widget.h"
+
+#define FWL_CLASS_PushButton L"FWL_PUSHBUTTON"
+#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 CFWL_PushButtonImpDelegate;
+class CFWL_WidgetImpProperties;
+class CFX_DIBitmap;
+class IFWL_Widget;
+
+class IFWL_PushButtonDP : public IFWL_DataProvider {
+ public:
+ virtual CFX_DIBitmap* GetPicture(IFWL_Widget* pWidget) = 0;
+};
+
+class IFWL_PushButton : public IFWL_Widget {
+ public:
+ static IFWL_PushButton* Create(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+
+ IFWL_PushButton(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+ ~IFWL_PushButton() override;
+
+ // IFWL_Widget
+ FWL_Error GetClassName(CFX_WideString& wsClass) const override;
+ FWL_Type GetClassID() const override;
+ FWL_Error Initialize() override;
+ FWL_Error Finalize() override;
+ FWL_Error GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize = FALSE) override;
+ void SetStates(uint32_t dwStates, FX_BOOL bSet = TRUE) override;
+ FWL_Error Update() override;
+ FWL_Error DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
+
+ protected:
+ friend class CFWL_PushButtonImpDelegate;
+
+ void DrawBkground(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix);
+ void DrawText(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix);
+ uint32_t GetPartStates();
+ void UpdateTextOutStyles();
+
+ CFX_RectF m_rtClient;
+ CFX_RectF m_rtCaption;
+ FX_BOOL m_bBtnDown;
+ uint32_t m_dwTTOStyles;
+ int32_t m_iTTOAlign;
+};
+
+class CFWL_PushButtonImpDelegate : public CFWL_WidgetImpDelegate {
+ public:
+ CFWL_PushButtonImpDelegate(IFWL_PushButton* pOwner);
+ void OnProcessMessage(CFWL_Message* pMessage) override;
+ void OnProcessEvent(CFWL_Event* pEvent) override;
+ void OnDrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
+
+ protected:
+ void OnFocusChanged(CFWL_Message* pMsg, FX_BOOL bSet = TRUE);
+ 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);
+ IFWL_PushButton* m_pOwner;
+};
+
+#endif // XFA_FWL_CORE_IFWL_PUSHBUTTON_H_
diff --git a/xfa/fwl/core/ifwl_scrollbar.cpp b/xfa/fwl/core/ifwl_scrollbar.cpp
new file mode 100644
index 0000000000..15478ff092
--- /dev/null
+++ b/xfa/fwl/core/ifwl_scrollbar.cpp
@@ -0,0 +1,788 @@
+// 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_scrollbar.h"
+
+#include "xfa/fwl/core/cfwl_message.h"
+#include "xfa/fwl/core/cfwl_themebackground.h"
+#include "xfa/fwl/core/cfwl_themepart.h"
+#include "xfa/fwl/core/fwl_noteimp.h"
+#include "xfa/fwl/core/ifwl_scrollbar.h"
+#include "xfa/fwl/core/ifwl_themeprovider.h"
+
+#define FWL_SCROLLBAR_Elapse 500
+#define FWL_SCROLLBAR_MinThumb 5
+
+// static
+IFWL_ScrollBar* IFWL_ScrollBar::Create(
+ const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter) {
+ return new IFWL_ScrollBar(properties, pOuter);
+}
+
+IFWL_ScrollBar::IFWL_ScrollBar(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter)
+ : IFWL_Widget(properties, pOuter),
+ m_pTimerInfo(nullptr),
+ m_fRangeMin(0),
+ m_fRangeMax(-1),
+ m_fPageSize(0),
+ m_fStepSize(0),
+ m_fPos(0),
+ m_fTrackPos(0),
+ m_iMinButtonState(CFWL_PartState_Normal),
+ m_iMaxButtonState(CFWL_PartState_Normal),
+ m_iThumbButtonState(CFWL_PartState_Normal),
+ m_iMinTrackState(CFWL_PartState_Normal),
+ m_iMaxTrackState(CFWL_PartState_Normal),
+ m_fLastTrackPos(0),
+ m_cpTrackPointX(0),
+ m_cpTrackPointY(0),
+ m_iMouseWheel(0),
+ m_bTrackMouseLeave(FALSE),
+ m_bMouseHover(FALSE),
+ m_bMouseDown(FALSE),
+ m_bRepaintThumb(FALSE),
+ m_fButtonLen(0),
+ m_bMinSize(FALSE),
+ m_bCustomLayout(FALSE),
+ m_fMinThumb(FWL_SCROLLBAR_MinThumb) {
+ m_rtClient.Reset();
+ m_rtThumb.Reset();
+ m_rtMinBtn.Reset();
+ m_rtMaxBtn.Reset();
+ m_rtMinTrack.Reset();
+ m_rtMaxTrack.Reset();
+}
+
+IFWL_ScrollBar::~IFWL_ScrollBar() {}
+
+FWL_Error IFWL_ScrollBar::GetClassName(CFX_WideString& wsClass) const {
+ wsClass = FWL_CLASS_ScrollBar;
+ return FWL_Error::Succeeded;
+}
+
+FWL_Type IFWL_ScrollBar::GetClassID() const {
+ return FWL_Type::ScrollBar;
+}
+
+FWL_Error IFWL_ScrollBar::Initialize() {
+ if (IFWL_Widget::Initialize() != FWL_Error::Succeeded)
+ return FWL_Error::Indefinite;
+
+ m_pDelegate = new CFWL_ScrollBarImpDelegate(this);
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_ScrollBar::Finalize() {
+ delete m_pDelegate;
+ m_pDelegate = nullptr;
+ return IFWL_Widget::Finalize();
+}
+
+FWL_Error IFWL_ScrollBar::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
+ if (bAutoSize) {
+ rect.Set(0, 0, 0, 0);
+ FX_FLOAT* pfMinWidth = static_cast<FX_FLOAT*>(
+ GetThemeCapacity(CFWL_WidgetCapacity::ScrollBarWidth));
+ if (!pfMinWidth)
+ return FWL_Error::Indefinite;
+ if (IsVertical()) {
+ rect.Set(0, 0, (*pfMinWidth), (*pfMinWidth) * 3);
+ } else {
+ rect.Set(0, 0, (*pfMinWidth) * 3, (*pfMinWidth));
+ }
+ IFWL_Widget::GetWidgetRect(rect, TRUE);
+ } else {
+ rect = m_pProperties->m_rtWidget;
+ }
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_ScrollBar::Update() {
+ if (IsLocked()) {
+ return FWL_Error::Indefinite;
+ }
+ if (!m_pProperties->m_pThemeProvider) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ Layout();
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_ScrollBar::DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ if (!pGraphics)
+ return FWL_Error::Indefinite;
+ if (!m_pProperties->m_pThemeProvider)
+ return FWL_Error::Indefinite;
+ IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
+ if (HasBorder()) {
+ DrawBorder(pGraphics, CFWL_Part::Border, pTheme, pMatrix);
+ }
+ if (HasEdge()) {
+ DrawEdge(pGraphics, CFWL_Part::Edge, pTheme, pMatrix);
+ }
+ DrawTrack(pGraphics, pTheme, TRUE, pMatrix);
+ DrawTrack(pGraphics, pTheme, FALSE, pMatrix);
+ DrawArrowBtn(pGraphics, pTheme, TRUE, pMatrix);
+ DrawArrowBtn(pGraphics, pTheme, FALSE, pMatrix);
+ DrawThumb(pGraphics, pTheme, pMatrix);
+ return FWL_Error::Succeeded;
+}
+
+inline FX_BOOL IFWL_ScrollBar::IsVertical() {
+ return m_pProperties->m_dwStyleExes & FWL_STYLEEXT_SCB_Vert;
+}
+
+FWL_Error IFWL_ScrollBar::GetRange(FX_FLOAT& fMin, FX_FLOAT& fMax) {
+ fMin = m_fRangeMin;
+ fMax = m_fRangeMax;
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_ScrollBar::SetRange(FX_FLOAT fMin, FX_FLOAT fMax) {
+ m_fRangeMin = fMin;
+ m_fRangeMax = fMax;
+ return FWL_Error::Succeeded;
+}
+
+FX_FLOAT IFWL_ScrollBar::GetPageSize() {
+ return m_fPageSize;
+}
+
+FWL_Error IFWL_ScrollBar::SetPageSize(FX_FLOAT fPageSize) {
+ m_fPageSize = fPageSize;
+ return FWL_Error::Succeeded;
+}
+
+FX_FLOAT IFWL_ScrollBar::GetStepSize() {
+ return m_fStepSize;
+}
+
+FWL_Error IFWL_ScrollBar::SetStepSize(FX_FLOAT fStepSize) {
+ m_fStepSize = fStepSize;
+ return FWL_Error::Succeeded;
+}
+
+FX_FLOAT IFWL_ScrollBar::GetPos() {
+ return m_fPos;
+}
+
+FWL_Error IFWL_ScrollBar::SetPos(FX_FLOAT fPos) {
+ m_fPos = fPos;
+ return FWL_Error::Succeeded;
+}
+
+FX_FLOAT IFWL_ScrollBar::GetTrackPos() {
+ return m_fTrackPos;
+}
+
+FWL_Error IFWL_ScrollBar::SetTrackPos(FX_FLOAT fTrackPos) {
+ m_fTrackPos = fTrackPos;
+ CalcThumbButtonRect(m_rtThumb);
+ CalcMinTrackRect(m_rtMinTrack);
+ CalcMaxTrackRect(m_rtMaxTrack);
+ return FWL_Error::Succeeded;
+}
+
+FX_BOOL IFWL_ScrollBar::DoScroll(uint32_t dwCode, FX_FLOAT fPos) {
+ switch (dwCode) {
+ case FWL_SCBCODE_Min:
+ case FWL_SCBCODE_Max:
+ case FWL_SCBCODE_PageBackward:
+ case FWL_SCBCODE_PageForward:
+ case FWL_SCBCODE_StepBackward:
+ break;
+ case FWL_SCBCODE_StepForward:
+ break;
+ case FWL_SCBCODE_Pos:
+ case FWL_SCBCODE_TrackPos:
+ case FWL_SCBCODE_EndScroll:
+ break;
+ default: { return FALSE; }
+ }
+ return OnScroll(dwCode, fPos);
+}
+
+void IFWL_ScrollBar::Run(IFWL_TimerInfo* pTimerInfo) {
+ if (m_pTimerInfo)
+ m_pTimerInfo->StopTimer();
+
+ if (!SendEvent())
+ m_pTimerInfo = StartTimer(0, true);
+}
+
+FWL_Error IFWL_ScrollBar::SetOuter(IFWL_Widget* pOuter) {
+ m_pOuter = pOuter;
+ return FWL_Error::Succeeded;
+}
+
+void IFWL_ScrollBar::DrawTrack(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ FX_BOOL bLower,
+ const CFX_Matrix* pMatrix) {
+ CFWL_ThemeBackground param;
+ param.m_pWidget = this;
+ param.m_iPart = bLower ? CFWL_Part::LowerTrack : CFWL_Part::UpperTrack;
+ param.m_dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)
+ ? CFWL_PartState_Disabled
+ : (bLower ? m_iMinTrackState : m_iMaxTrackState);
+ param.m_pGraphics = pGraphics;
+ param.m_matrix.Concat(*pMatrix);
+ param.m_rtPart = bLower ? m_rtMinTrack : m_rtMaxTrack;
+ pTheme->DrawBackground(&param);
+}
+
+void IFWL_ScrollBar::DrawArrowBtn(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ FX_BOOL bMinBtn,
+ const CFX_Matrix* pMatrix) {
+ CFWL_ThemeBackground param;
+ param.m_pWidget = this;
+ param.m_iPart = bMinBtn ? CFWL_Part::ForeArrow : CFWL_Part::BackArrow;
+ param.m_dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)
+ ? CFWL_PartState_Disabled
+ : (bMinBtn ? m_iMinButtonState : m_iMaxButtonState);
+ param.m_pGraphics = pGraphics;
+ param.m_matrix.Concat(*pMatrix);
+ param.m_rtPart = bMinBtn ? m_rtMinBtn : m_rtMaxBtn;
+ if (param.m_rtPart.height > 0 && param.m_rtPart.width > 0) {
+ pTheme->DrawBackground(&param);
+ }
+}
+
+void IFWL_ScrollBar::DrawThumb(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix) {
+ CFWL_ThemeBackground param;
+ param.m_pWidget = this;
+ param.m_iPart = CFWL_Part::Thumb;
+ param.m_dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)
+ ? CFWL_PartState_Disabled
+ : m_iThumbButtonState;
+ param.m_pGraphics = pGraphics;
+ param.m_matrix.Concat(*pMatrix);
+ param.m_rtPart = m_rtThumb;
+ pTheme->DrawBackground(&param);
+}
+
+void IFWL_ScrollBar::Layout() {
+ IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
+ CFWL_ThemePart part;
+ part.m_pWidget = this;
+ m_fMinThumb = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::Size));
+ m_bCustomLayout = pTheme->IsCustomizedLayout(this);
+ GetClientRect(m_rtClient);
+ CalcButtonLen();
+ CalcMinButtonRect(m_rtMinBtn);
+ CalcMaxButtonRect(m_rtMaxBtn);
+ CalcThumbButtonRect(m_rtThumb);
+ CalcMinTrackRect(m_rtMinTrack);
+ CalcMaxTrackRect(m_rtMaxTrack);
+}
+
+void IFWL_ScrollBar::CalcButtonLen() {
+ m_fButtonLen = IsVertical() ? m_rtClient.width : m_rtClient.height;
+ FX_FLOAT fLength = IsVertical() ? m_rtClient.height : m_rtClient.width;
+ if (fLength < m_fButtonLen * 2) {
+ m_fButtonLen = fLength / 2;
+ m_bMinSize = TRUE;
+ } else {
+ m_bMinSize = FALSE;
+ }
+}
+
+void IFWL_ScrollBar::CalcMinButtonRect(CFX_RectF& rect) {
+ if (m_bCustomLayout)
+ return;
+
+ rect.left = m_rtClient.left;
+ rect.top = m_rtClient.top;
+ rect.width = IsVertical() ? m_rtClient.width : m_fButtonLen;
+ rect.height = IsVertical() ? m_fButtonLen : m_rtClient.height;
+}
+
+void IFWL_ScrollBar::CalcMaxButtonRect(CFX_RectF& rect) {
+ if (m_bCustomLayout)
+ return;
+
+ rect.left =
+ IsVertical() ? m_rtClient.left : m_rtClient.right() - m_fButtonLen;
+ rect.top = IsVertical() ? m_rtClient.bottom() - m_fButtonLen : m_rtClient.top;
+ rect.width = IsVertical() ? m_rtClient.width : m_fButtonLen;
+ rect.height = IsVertical() ? m_fButtonLen : m_rtClient.height;
+}
+
+void IFWL_ScrollBar::CalcThumbButtonRect(CFX_RectF& rect) {
+ if (!IsEnabled()) {
+ m_rtThumb.Reset();
+ return;
+ }
+ if (m_bMinSize) {
+ m_rtThumb.Empty();
+ return;
+ }
+ FX_FLOAT fRange = m_fRangeMax - m_fRangeMin;
+ memset(&rect, 0, sizeof(CFX_Rect));
+ if (fRange < 0) {
+ if (IsVertical()) {
+ rect.Set(m_rtClient.left, m_rtMaxBtn.bottom(), m_rtClient.width, 0);
+ } else {
+ rect.Set(m_rtMaxBtn.right(), m_rtClient.top, 0, m_rtClient.height);
+ }
+ return;
+ }
+ CFX_RectF rtClient = m_rtClient;
+ FX_FLOAT fLength = IsVertical() ? rtClient.height : rtClient.width;
+ FX_FLOAT fSize = m_fButtonLen;
+ if (m_bCustomLayout) {
+ if (IsVertical()) {
+ fLength = fLength - m_rtMinBtn.height - m_rtMaxBtn.height;
+ if (fLength < m_rtMinBtn.height || fLength < m_rtMaxBtn.height) {
+ fLength = 0.0f;
+ }
+ } else {
+ fLength = fLength - m_rtMinBtn.width - m_rtMaxBtn.width;
+ if (fLength < m_rtMinBtn.width || fLength < m_rtMaxBtn.width) {
+ fLength = 0.0f;
+ }
+ }
+ } else {
+ fLength -= fSize * 2.0f;
+ if (fLength < fSize) {
+ fLength = 0.0f;
+ }
+ }
+ FX_FLOAT fThumbSize = fLength * fLength / (fRange + fLength);
+ if (fThumbSize < m_fMinThumb) {
+ fThumbSize = m_fMinThumb;
+ }
+ FX_FLOAT fDiff = fLength - fThumbSize;
+ if (fDiff < 0.0f) {
+ fDiff = 0.0f;
+ }
+ FX_FLOAT fTrackPos = m_fTrackPos;
+ if (fTrackPos > m_fRangeMax) {
+ fTrackPos = m_fRangeMax;
+ }
+ if (fTrackPos < m_fRangeMin) {
+ fTrackPos = m_fRangeMin;
+ }
+ if (!fRange)
+ return;
+ if (m_bCustomLayout) {
+ FX_FLOAT iPos = fDiff * (fTrackPos - m_fRangeMin) / fRange;
+ rect.left = rtClient.left;
+ if (!IsVertical()) {
+ if ((m_rtMinBtn.right() == m_rtMaxBtn.left && m_rtMinBtn.width > 0 &&
+ m_rtMaxBtn.width > 0) ||
+ (0 == m_rtMinBtn.width && 0 == m_rtMaxBtn.width)) {
+ rect.left += iPos;
+ } else {
+ rect.left += m_rtMinBtn.right() + iPos;
+ }
+ }
+ rect.top = rtClient.top;
+ if (IsVertical()) {
+ if ((m_rtMinBtn.bottom() == m_rtMaxBtn.top && m_rtMinBtn.height > 0 &&
+ m_rtMaxBtn.height > 0) ||
+ (0 == m_rtMinBtn.height && 0 == m_rtMaxBtn.height)) {
+ rect.top += iPos;
+ } else {
+ rect.top += m_rtMinBtn.bottom() + iPos;
+ }
+ }
+ rect.width = IsVertical() ? rtClient.width : fThumbSize;
+ rect.height = IsVertical() ? fThumbSize : rtClient.height;
+ } else {
+ FX_FLOAT iPos = fSize + fDiff * (fTrackPos - m_fRangeMin) / fRange;
+ rect.left = rtClient.left;
+ if (!IsVertical()) {
+ rect.left += iPos;
+ }
+ rect.top = rtClient.top;
+ if (IsVertical()) {
+ rect.top += iPos;
+ }
+ rect.width = IsVertical() ? rtClient.width : fThumbSize;
+ rect.height = IsVertical() ? fThumbSize : rtClient.height;
+ }
+}
+
+void IFWL_ScrollBar::CalcMinTrackRect(CFX_RectF& rect) {
+ if (m_bMinSize) {
+ rect.Empty();
+ return;
+ }
+ FX_FLOAT fBottom = m_rtThumb.bottom();
+ FX_FLOAT fRight = m_rtThumb.right();
+ FX_FLOAT ix = (m_rtThumb.left + fRight) / 2;
+ FX_FLOAT iy = (m_rtThumb.top + fBottom) / 2;
+ rect.left = m_rtClient.left;
+ rect.top = m_rtClient.top;
+ FX_BOOL bVertical = IsVertical();
+ rect.width = bVertical ? m_rtClient.width : ix;
+ rect.height = bVertical ? iy : m_rtClient.height;
+ if (m_bCustomLayout) {
+ if (bVertical) {
+ if (0 == m_rtMinBtn.height && 0 == m_rtMaxBtn.height) {
+ rect.top = m_rtClient.top;
+ } else if (m_rtMinBtn.top < m_rtThumb.top) {
+ rect.top = m_rtMinBtn.bottom();
+ rect.height -= (m_rtMinBtn.bottom() - m_rtClient.top);
+ }
+ } else {
+ if (0 == m_rtMinBtn.width && 0 == m_rtMaxBtn.width) {
+ rect.left = m_rtClient.left;
+ } else if (m_rtMinBtn.left < m_rtThumb.left) {
+ rect.left = m_rtMinBtn.right();
+ rect.width -= (m_rtMinBtn.right() - m_rtClient.left);
+ }
+ }
+ }
+}
+
+void IFWL_ScrollBar::CalcMaxTrackRect(CFX_RectF& rect) {
+ if (m_bMinSize) {
+ rect.Empty();
+ return;
+ }
+ FX_FLOAT ix = (m_rtThumb.left + m_rtThumb.right()) / 2;
+ FX_FLOAT iy = (m_rtThumb.top + m_rtThumb.bottom()) / 2;
+ FX_BOOL bVertical = IsVertical();
+ rect.left = bVertical ? m_rtClient.left : ix;
+ rect.top = bVertical ? iy : m_rtClient.top;
+ rect.width = bVertical ? m_rtClient.width : m_rtClient.right() - ix;
+ rect.height = bVertical ? m_rtClient.bottom() - iy : m_rtClient.height;
+ if (m_bCustomLayout) {
+ if (bVertical) {
+ if (m_rtMinBtn.top > m_rtThumb.top && m_rtMinBtn.height > 0 &&
+ m_rtMaxBtn.height > 0) {
+ rect.height -= (m_rtClient.bottom() - m_rtMinBtn.top);
+ } else if (m_rtMinBtn.height > 0 && m_rtMaxBtn.height > 0) {
+ rect.height -= (m_rtClient.bottom() - m_rtMaxBtn.top);
+ }
+ } else {
+ if (m_rtMinBtn.left > m_rtThumb.left && m_rtMinBtn.width > 0 &&
+ m_rtMaxBtn.width > 0) {
+ rect.width -= (m_rtClient.right() - m_rtMinBtn.left);
+ } else if (m_rtMinBtn.width > 0 && m_rtMaxBtn.width > 0) {
+ rect.width -= (m_rtClient.right() - m_rtMaxBtn.left);
+ }
+ }
+ }
+}
+
+FX_FLOAT IFWL_ScrollBar::GetTrackPointPos(FX_FLOAT fx, FX_FLOAT fy) {
+ FX_FLOAT fDiffX = fx - m_cpTrackPointX;
+ FX_FLOAT fDiffY = fy - m_cpTrackPointY;
+ FX_FLOAT fRange = m_fRangeMax - m_fRangeMin;
+ FX_FLOAT fPos;
+ if (m_bCustomLayout) {
+ if (IsVertical()) {
+ if (0 == m_rtMinBtn.height && 0 == m_rtMaxBtn.height) {
+ fPos = fRange * fDiffY / (m_rtClient.height - m_rtThumb.height);
+ } else if (m_rtMinBtn.bottom() == m_rtMaxBtn.top) {
+ fPos = fRange * fDiffY /
+ (m_rtMinBtn.top - m_rtClient.top - m_rtThumb.height);
+ } else {
+ fPos = fRange * fDiffY /
+ (m_rtMaxBtn.top - m_rtMinBtn.bottom() - m_rtThumb.height);
+ }
+ } else {
+ if (0 == m_rtMinBtn.width && 0 == m_rtMaxBtn.width) {
+ fPos = fRange * fDiffX / (m_rtClient.width - m_rtThumb.width);
+ } else if (m_rtMinBtn.right() == m_rtMaxBtn.left) {
+ fPos = fRange * fDiffX /
+ (m_rtMinBtn.left - m_rtClient.left - m_rtThumb.width);
+ } else {
+ fPos = fRange * fDiffX /
+ (m_rtMaxBtn.left - m_rtMinBtn.right() - m_rtThumb.width);
+ }
+ }
+ } else {
+ if (IsVertical()) {
+ fPos = fRange * fDiffY /
+ (m_rtMaxBtn.top - m_rtMinBtn.bottom() - m_rtThumb.height);
+ } else {
+ fPos = fRange * fDiffX /
+ (m_rtMaxBtn.left - m_rtMinBtn.right() - m_rtThumb.width);
+ }
+ }
+ fPos += m_fLastTrackPos;
+ if (fPos < m_fRangeMin) {
+ fPos = m_fRangeMin;
+ }
+ if (fPos > m_fRangeMax) {
+ fPos = m_fRangeMax;
+ }
+ return fPos;
+}
+
+void IFWL_ScrollBar::GetTrackRect(CFX_RectF& rect, FX_BOOL bLower) {
+ FX_BOOL bDisabled = m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled;
+ if (bDisabled || m_bCustomLayout) {
+ rect = bLower ? m_rtMinTrack : m_rtMaxTrack;
+ } else {
+ FX_FLOAT fW = m_rtThumb.width / 2;
+ FX_FLOAT fH = m_rtThumb.height / 2;
+ FX_BOOL bVert = IsVertical();
+ if (bLower) {
+ if (bVert) {
+ FX_FLOAT fMinTrackHeight = m_rtMinTrack.height - fH - m_rtMinBtn.height;
+ fMinTrackHeight = (fMinTrackHeight >= 0.0f) ? fMinTrackHeight : 0.0f;
+ rect.Set(m_rtMinTrack.left, m_rtMinTrack.top + m_rtMinBtn.height,
+ m_rtMinTrack.width, fMinTrackHeight);
+ } else {
+ FX_FLOAT fMinTrackWidth =
+ m_rtMinTrack.width - fW - m_rtMinBtn.width + 2;
+ fMinTrackWidth = (fMinTrackWidth >= 0.0f) ? fMinTrackWidth : 0.0f;
+ rect.Set(m_rtMinTrack.left + m_rtMinBtn.width - 1, m_rtMinTrack.top,
+ fMinTrackWidth, m_rtMinTrack.height);
+ }
+ } else {
+ if (bVert) {
+ FX_FLOAT fMaxTrackHeight = m_rtMaxTrack.height - fH - m_rtMaxBtn.height;
+ fMaxTrackHeight = (fMaxTrackHeight >= 0.0f) ? fMaxTrackHeight : 0.0f;
+ rect.Set(m_rtMaxTrack.left, m_rtMaxTrack.top + fH, m_rtMaxTrack.width,
+ fMaxTrackHeight);
+ } else {
+ FX_FLOAT fMaxTrackWidth =
+ m_rtMaxTrack.width - fW - m_rtMaxBtn.width + 2;
+ fMaxTrackWidth = (fMaxTrackWidth >= 0.0f) ? fMaxTrackWidth : 0.0f;
+ rect.Set(m_rtMaxTrack.left + fW, m_rtMaxTrack.top, fMaxTrackWidth,
+ m_rtMaxTrack.height);
+ }
+ }
+ }
+}
+
+FX_BOOL IFWL_ScrollBar::SendEvent() {
+ if (m_iMinButtonState == CFWL_PartState_Pressed) {
+ DoScroll(FWL_SCBCODE_StepBackward, m_fTrackPos);
+ return FALSE;
+ }
+ if (m_iMaxButtonState == CFWL_PartState_Pressed) {
+ DoScroll(FWL_SCBCODE_StepForward, m_fTrackPos);
+ return FALSE;
+ }
+ if (m_iMinTrackState == CFWL_PartState_Pressed) {
+ DoScroll(FWL_SCBCODE_PageBackward, m_fTrackPos);
+ return m_rtThumb.Contains(m_cpTrackPointX, m_cpTrackPointY);
+ }
+ if (m_iMaxTrackState == CFWL_PartState_Pressed) {
+ DoScroll(FWL_SCBCODE_PageForward, m_fTrackPos);
+ return m_rtThumb.Contains(m_cpTrackPointX, m_cpTrackPointY);
+ }
+ if (m_iMouseWheel) {
+ uint16_t dwCode =
+ m_iMouseWheel < 0 ? FWL_SCBCODE_StepForward : FWL_SCBCODE_StepBackward;
+ DoScroll(dwCode, m_fTrackPos);
+ }
+ return TRUE;
+}
+
+FX_BOOL IFWL_ScrollBar::OnScroll(uint32_t dwCode, FX_FLOAT fPos) {
+ FX_BOOL bRet = TRUE;
+ CFWL_EvtScroll ev;
+ ev.m_iScrollCode = dwCode;
+ ev.m_pSrcTarget = this;
+ ev.m_fPos = fPos;
+ ev.m_pRet = &bRet;
+ DispatchEvent(&ev);
+ return bRet;
+}
+
+CFWL_ScrollBarImpDelegate::CFWL_ScrollBarImpDelegate(IFWL_ScrollBar* pOwner)
+ : m_pOwner(pOwner) {}
+
+void CFWL_ScrollBarImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
+ if (!pMessage)
+ return;
+
+ CFWL_MessageType dwMsgCode = pMessage->GetClassID();
+ if (dwMsgCode == CFWL_MessageType::Mouse) {
+ CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage);
+ switch (pMsg->m_dwCmd) {
+ case FWL_MouseCommand::LeftButtonDown: {
+ OnLButtonDown(pMsg->m_dwFlags, pMsg->m_fx, pMsg->m_fy);
+ break;
+ }
+ case FWL_MouseCommand::LeftButtonUp: {
+ OnLButtonUp(pMsg->m_dwFlags, pMsg->m_fx, pMsg->m_fy);
+ break;
+ }
+ case FWL_MouseCommand::Move: {
+ OnMouseMove(pMsg->m_dwFlags, pMsg->m_fx, pMsg->m_fy);
+ break;
+ }
+ case FWL_MouseCommand::Leave: {
+ OnMouseLeave();
+ break;
+ }
+ default: { break; }
+ }
+ } else if (dwMsgCode == CFWL_MessageType::MouseWheel) {
+ CFWL_MsgMouseWheel* pMsg = static_cast<CFWL_MsgMouseWheel*>(pMessage);
+ OnMouseWheel(pMsg->m_fx, pMsg->m_fy, pMsg->m_dwFlags, pMsg->m_fDeltaX,
+ pMsg->m_fDeltaY);
+ }
+}
+
+void CFWL_ScrollBarImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ m_pOwner->DrawWidget(pGraphics, pMatrix);
+}
+
+void CFWL_ScrollBarImpDelegate::OnLButtonDown(uint32_t dwFlags,
+ FX_FLOAT fx,
+ FX_FLOAT fy) {
+ if (!m_pOwner->IsEnabled()) {
+ return;
+ }
+ m_pOwner->m_bMouseDown = TRUE;
+ m_pOwner->SetGrab(TRUE);
+ m_pOwner->m_cpTrackPointX = fx;
+ m_pOwner->m_cpTrackPointY = fy;
+ m_pOwner->m_fLastTrackPos = m_pOwner->m_fTrackPos;
+ if (m_pOwner->m_rtMinBtn.Contains(fx, fy)) {
+ DoMouseDown(0, m_pOwner->m_rtMinBtn, m_pOwner->m_iMinButtonState, fx, fy);
+ } else {
+ if (m_pOwner->m_rtThumb.Contains(fx, fy)) {
+ DoMouseDown(1, m_pOwner->m_rtThumb, m_pOwner->m_iThumbButtonState, fx,
+ fy);
+ } else {
+ if (m_pOwner->m_rtMaxBtn.Contains(fx, fy)) {
+ DoMouseDown(2, m_pOwner->m_rtMaxBtn, m_pOwner->m_iMaxButtonState, fx,
+ fy);
+ } else {
+ if (m_pOwner->m_rtMinTrack.Contains(fx, fy)) {
+ DoMouseDown(3, m_pOwner->m_rtMinTrack, m_pOwner->m_iMinTrackState, fx,
+ fy);
+ } else {
+ DoMouseDown(4, m_pOwner->m_rtMaxTrack, m_pOwner->m_iMaxTrackState, fx,
+ fy);
+ }
+ }
+ }
+ }
+ if (!m_pOwner->SendEvent())
+ m_pOwner->m_pTimerInfo = m_pOwner->StartTimer(FWL_SCROLLBAR_Elapse, true);
+}
+
+void CFWL_ScrollBarImpDelegate::OnLButtonUp(uint32_t dwFlags,
+ FX_FLOAT fx,
+ FX_FLOAT fy) {
+ m_pOwner->m_pTimerInfo->StopTimer();
+ m_pOwner->m_bMouseDown = FALSE;
+ DoMouseUp(0, m_pOwner->m_rtMinBtn, m_pOwner->m_iMinButtonState, fx, fy);
+ DoMouseUp(1, m_pOwner->m_rtThumb, m_pOwner->m_iThumbButtonState, fx, fy);
+ DoMouseUp(2, m_pOwner->m_rtMaxBtn, m_pOwner->m_iMaxButtonState, fx, fy);
+ DoMouseUp(3, m_pOwner->m_rtMinTrack, m_pOwner->m_iMinTrackState, fx, fy);
+ DoMouseUp(4, m_pOwner->m_rtMaxTrack, m_pOwner->m_iMaxTrackState, fx, fy);
+ m_pOwner->SetGrab(FALSE);
+}
+
+void CFWL_ScrollBarImpDelegate::OnMouseMove(uint32_t dwFlags,
+ FX_FLOAT fx,
+ FX_FLOAT fy) {
+ DoMouseMove(0, m_pOwner->m_rtMinBtn, m_pOwner->m_iMinButtonState, fx, fy);
+ DoMouseMove(1, m_pOwner->m_rtThumb, m_pOwner->m_iThumbButtonState, fx, fy);
+ DoMouseMove(2, m_pOwner->m_rtMaxBtn, m_pOwner->m_iMaxButtonState, fx, fy);
+ DoMouseMove(3, m_pOwner->m_rtMinTrack, m_pOwner->m_iMinTrackState, fx, fy);
+ DoMouseMove(4, m_pOwner->m_rtMaxTrack, m_pOwner->m_iMaxTrackState, fx, fy);
+}
+
+void CFWL_ScrollBarImpDelegate::OnMouseLeave() {
+ DoMouseLeave(0, m_pOwner->m_rtMinBtn, m_pOwner->m_iMinButtonState);
+ DoMouseLeave(1, m_pOwner->m_rtThumb, m_pOwner->m_iThumbButtonState);
+ DoMouseLeave(2, m_pOwner->m_rtMaxBtn, m_pOwner->m_iMaxButtonState);
+ DoMouseLeave(3, m_pOwner->m_rtMinTrack, m_pOwner->m_iMinTrackState);
+ DoMouseLeave(4, m_pOwner->m_rtMaxTrack, m_pOwner->m_iMaxTrackState);
+}
+
+void CFWL_ScrollBarImpDelegate::OnMouseWheel(FX_FLOAT fx,
+ FX_FLOAT fy,
+ uint32_t dwFlags,
+ FX_FLOAT fDeltaX,
+ FX_FLOAT fDeltaY) {
+ m_pOwner->m_iMouseWheel = (int32_t)fDeltaX;
+ m_pOwner->SendEvent();
+ m_pOwner->m_iMouseWheel = 0;
+}
+
+void CFWL_ScrollBarImpDelegate::DoMouseDown(int32_t iItem,
+ const CFX_RectF& rtItem,
+ int32_t& iState,
+ FX_FLOAT fx,
+ FX_FLOAT fy) {
+ if (!rtItem.Contains(fx, fy)) {
+ return;
+ }
+ if (iState == CFWL_PartState_Pressed) {
+ return;
+ }
+ iState = CFWL_PartState_Pressed;
+ m_pOwner->Repaint(&rtItem);
+}
+
+void CFWL_ScrollBarImpDelegate::DoMouseUp(int32_t iItem,
+ const CFX_RectF& rtItem,
+ int32_t& iState,
+ FX_FLOAT fx,
+ FX_FLOAT fy) {
+ int32_t iNewState =
+ rtItem.Contains(fx, fy) ? CFWL_PartState_Hovered : CFWL_PartState_Normal;
+ if (iState == iNewState) {
+ return;
+ }
+ iState = iNewState;
+ m_pOwner->Repaint(&rtItem);
+ m_pOwner->OnScroll(FWL_SCBCODE_EndScroll, m_pOwner->m_fTrackPos);
+}
+
+void CFWL_ScrollBarImpDelegate::DoMouseMove(int32_t iItem,
+ const CFX_RectF& rtItem,
+ int32_t& iState,
+ FX_FLOAT fx,
+ FX_FLOAT fy) {
+ if (!m_pOwner->m_bMouseDown) {
+ int32_t iNewState = rtItem.Contains(fx, fy) ? CFWL_PartState_Hovered
+ : CFWL_PartState_Normal;
+ if (iState == iNewState) {
+ return;
+ }
+ iState = iNewState;
+ m_pOwner->Repaint(&rtItem);
+ } else if ((2 == iItem) &&
+ (m_pOwner->m_iThumbButtonState == CFWL_PartState_Pressed)) {
+ FX_FLOAT fPos = m_pOwner->GetTrackPointPos(fx, fy);
+ m_pOwner->m_fTrackPos = fPos;
+ m_pOwner->OnScroll(FWL_SCBCODE_TrackPos, fPos);
+ }
+}
+
+void CFWL_ScrollBarImpDelegate::DoMouseLeave(int32_t iItem,
+ const CFX_RectF& rtItem,
+ int32_t& iState) {
+ if (iState == CFWL_PartState_Normal) {
+ return;
+ }
+ iState = CFWL_PartState_Normal;
+ m_pOwner->Repaint(&rtItem);
+}
+
+void CFWL_ScrollBarImpDelegate::DoMouseHover(int32_t iItem,
+ const CFX_RectF& rtItem,
+ int32_t& iState) {
+ if (iState == CFWL_PartState_Hovered) {
+ return;
+ }
+ iState = CFWL_PartState_Hovered;
+ m_pOwner->Repaint(&rtItem);
+}
diff --git a/xfa/fwl/core/ifwl_scrollbar.h b/xfa/fwl/core/ifwl_scrollbar.h
new file mode 100644
index 0000000000..2a46e0f33d
--- /dev/null
+++ b/xfa/fwl/core/ifwl_scrollbar.h
@@ -0,0 +1,175 @@
+// 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_SCROLLBAR_H_
+#define XFA_FWL_CORE_IFWL_SCROLLBAR_H_
+
+#include "core/fxcrt/fx_system.h"
+#include "xfa/fwl/core/cfwl_widgetimpproperties.h"
+#include "xfa/fwl/core/fwl_error.h"
+#include "xfa/fwl/core/ifwl_dataprovider.h"
+#include "xfa/fwl/core/ifwl_timer.h"
+#include "xfa/fwl/core/ifwl_widget.h"
+
+class CFWL_ScrollBarImpDelegate;
+class CFWL_WidgetImpProperties;
+class IFWL_Widget;
+
+#define FWL_CLASS_ScrollBar L"FWL_SCROLLBAR"
+#define FWL_STYLEEXT_SCB_Horz (0L << 0)
+#define FWL_STYLEEXT_SCB_Vert (1L << 0)
+
+enum FWL_SCBCODE {
+ FWL_SCBCODE_None = 1,
+ FWL_SCBCODE_Min,
+ FWL_SCBCODE_Max,
+ FWL_SCBCODE_PageBackward,
+ FWL_SCBCODE_PageForward,
+ FWL_SCBCODE_StepBackward,
+ FWL_SCBCODE_StepForward,
+ FWL_SCBCODE_Pos,
+ FWL_SCBCODE_TrackPos,
+ FWL_SCBCODE_EndScroll,
+};
+
+class IFWL_ScrollBarDP : public IFWL_DataProvider {};
+
+class IFWL_ScrollBar : public IFWL_Widget, public IFWL_Timer {
+ public:
+ static IFWL_ScrollBar* Create(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+
+ IFWL_ScrollBar(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+ ~IFWL_ScrollBar() override;
+
+ // IFWL_Widget
+ FWL_Error GetClassName(CFX_WideString& wsClass) const override;
+ FWL_Type GetClassID() const override;
+ FWL_Error Initialize() override;
+ FWL_Error Finalize() override;
+ FWL_Error GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize = FALSE) override;
+ FWL_Error Update() override;
+ FWL_Error DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
+
+ // IFWL_Timer
+ void Run(IFWL_TimerInfo* pTimerInfo) override;
+
+ FX_BOOL IsVertical();
+ FWL_Error GetRange(FX_FLOAT& fMin, FX_FLOAT& fMax);
+ FWL_Error SetRange(FX_FLOAT fMin, FX_FLOAT fMax);
+ FX_FLOAT GetPageSize();
+ FWL_Error SetPageSize(FX_FLOAT fPageSize);
+ FX_FLOAT GetStepSize();
+ FWL_Error SetStepSize(FX_FLOAT fStepSize);
+ FX_FLOAT GetPos();
+ FWL_Error SetPos(FX_FLOAT fPos);
+ FX_FLOAT GetTrackPos();
+ FWL_Error SetTrackPos(FX_FLOAT fTrackPos);
+ FX_BOOL DoScroll(uint32_t dwCode, FX_FLOAT fPos = 0.0f);
+ FWL_Error SetOuter(IFWL_Widget* pOuter);
+
+ protected:
+ friend class CFWL_ScrollBarImpDelegate;
+
+ void DrawTrack(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ FX_BOOL bLower = TRUE,
+ const CFX_Matrix* pMatrix = nullptr);
+ void DrawArrowBtn(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ FX_BOOL bMinBtn = TRUE,
+ const CFX_Matrix* pMatrix = nullptr);
+ void DrawThumb(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix = nullptr);
+ void Layout();
+ void CalcButtonLen();
+ void CalcMinButtonRect(CFX_RectF& rect);
+ void CalcMaxButtonRect(CFX_RectF& rect);
+ void CalcThumbButtonRect(CFX_RectF& rect);
+ void CalcMinTrackRect(CFX_RectF& rect);
+ void CalcMaxTrackRect(CFX_RectF& rect);
+ FX_FLOAT GetTrackPointPos(FX_FLOAT fx, FX_FLOAT fy);
+ void GetTrackRect(CFX_RectF& rect, FX_BOOL bLower = TRUE);
+ FX_BOOL SendEvent();
+ FX_BOOL OnScroll(uint32_t dwCode, FX_FLOAT fPos);
+
+ IFWL_TimerInfo* m_pTimerInfo;
+ FX_FLOAT m_fRangeMin;
+ FX_FLOAT m_fRangeMax;
+ FX_FLOAT m_fPageSize;
+ FX_FLOAT m_fStepSize;
+ FX_FLOAT m_fPos;
+ FX_FLOAT m_fTrackPos;
+ int32_t m_iMinButtonState;
+ int32_t m_iMaxButtonState;
+ int32_t m_iThumbButtonState;
+ int32_t m_iMinTrackState;
+ int32_t m_iMaxTrackState;
+ FX_FLOAT m_fLastTrackPos;
+ FX_FLOAT m_cpTrackPointX;
+ FX_FLOAT m_cpTrackPointY;
+ int32_t m_iMouseWheel;
+ FX_BOOL m_bTrackMouseLeave;
+ FX_BOOL m_bMouseHover;
+ FX_BOOL m_bMouseDown;
+ FX_BOOL m_bRepaintThumb;
+ FX_FLOAT m_fButtonLen;
+ FX_BOOL m_bMinSize;
+ CFX_RectF m_rtClient;
+ CFX_RectF m_rtThumb;
+ CFX_RectF m_rtMinBtn;
+ CFX_RectF m_rtMaxBtn;
+ CFX_RectF m_rtMinTrack;
+ CFX_RectF m_rtMaxTrack;
+ FX_BOOL m_bCustomLayout;
+ FX_FLOAT m_fMinThumb;
+
+ protected:
+ IFWL_ScrollBar();
+};
+
+class CFWL_ScrollBarImpDelegate : public CFWL_WidgetImpDelegate {
+ public:
+ CFWL_ScrollBarImpDelegate(IFWL_ScrollBar* pOwner);
+ void OnProcessMessage(CFWL_Message* pMessage) override;
+ void OnDrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
+
+ protected:
+ void OnLButtonDown(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ void OnLButtonUp(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ void OnMouseMove(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ void OnMouseLeave();
+ void OnMouseWheel(FX_FLOAT fx,
+ FX_FLOAT fy,
+ uint32_t dwFlags,
+ FX_FLOAT fDeltaX,
+ FX_FLOAT fDeltaY);
+ void DoMouseDown(int32_t iItem,
+ const CFX_RectF& rtItem,
+ int32_t& iState,
+ FX_FLOAT fx,
+ FX_FLOAT fy);
+ void DoMouseUp(int32_t iItem,
+ const CFX_RectF& rtItem,
+ int32_t& iState,
+ FX_FLOAT fx,
+ FX_FLOAT fy);
+ void DoMouseMove(int32_t iItem,
+ const CFX_RectF& rtItem,
+ int32_t& iState,
+ FX_FLOAT fx,
+ FX_FLOAT fy);
+ void DoMouseLeave(int32_t iItem, const CFX_RectF& rtItem, int32_t& iState);
+ void DoMouseHover(int32_t iItem, const CFX_RectF& rtItem, int32_t& iState);
+
+ IFWL_ScrollBar* m_pOwner;
+};
+
+#endif // XFA_FWL_CORE_IFWL_SCROLLBAR_H_
diff --git a/xfa/fwl/core/ifwl_spinbutton.cpp b/xfa/fwl/core/ifwl_spinbutton.cpp
new file mode 100644
index 0000000000..dbba2f67f4
--- /dev/null
+++ b/xfa/fwl/core/ifwl_spinbutton.cpp
@@ -0,0 +1,436 @@
+// 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_spinbutton.h"
+
+#include "xfa/fwl/core/cfwl_message.h"
+#include "xfa/fwl/core/cfwl_themebackground.h"
+#include "xfa/fwl/core/cfwl_widgetimpproperties.h"
+#include "xfa/fwl/core/fwl_noteimp.h"
+#include "xfa/fwl/core/ifwl_spinbutton.h"
+#include "xfa/fwl/core/ifwl_themeprovider.h"
+#include "xfa/fwl/core/ifwl_themeprovider.h"
+#include "xfa/fwl/core/ifwl_timer.h"
+
+namespace {
+
+const int kMinWidth = 18;
+const int kMinHeight = 32;
+const int kElapseTime = 200;
+
+} // namespace
+
+// static
+IFWL_SpinButton* IFWL_SpinButton::Create(
+ const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter) {
+ return new IFWL_SpinButton(properties, nullptr);
+}
+
+IFWL_SpinButton::IFWL_SpinButton(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter)
+ : IFWL_Widget(properties, pOuter),
+ m_dwUpState(CFWL_PartState_Normal),
+ m_dwDnState(CFWL_PartState_Normal),
+ m_iButtonIndex(0),
+ m_bLButtonDwn(FALSE),
+ m_pTimerInfo(nullptr) {
+ m_rtClient.Reset();
+ m_rtUpButton.Reset();
+ m_rtDnButton.Reset();
+ m_pProperties->m_dwStyleExes |= FWL_STYLEEXE_SPB_Vert;
+}
+
+IFWL_SpinButton::~IFWL_SpinButton() {}
+
+FWL_Error IFWL_SpinButton::GetClassName(CFX_WideString& wsClass) const {
+ wsClass = FWL_CLASS_SpinButton;
+ return FWL_Error::Succeeded;
+}
+
+FWL_Type IFWL_SpinButton::GetClassID() const {
+ return FWL_Type::SpinButton;
+}
+
+FWL_Error IFWL_SpinButton::Initialize() {
+ if (IFWL_Widget::Initialize() != FWL_Error::Succeeded)
+ return FWL_Error::Indefinite;
+
+ m_pDelegate = new CFWL_SpinButtonImpDelegate(this);
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_SpinButton::Finalize() {
+ delete m_pDelegate;
+ m_pDelegate = nullptr;
+ return IFWL_Widget::Finalize();
+}
+
+FWL_Error IFWL_SpinButton::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
+ if (bAutoSize) {
+ rect.Set(0, 0, kMinWidth, kMinHeight);
+ IFWL_Widget::GetWidgetRect(rect, TRUE);
+ } else {
+ rect = m_pProperties->m_rtWidget;
+ }
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_SpinButton::Update() {
+ if (IsLocked()) {
+ return FWL_Error::Indefinite;
+ }
+ GetClientRect(m_rtClient);
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXE_SPB_Vert) {
+ m_rtUpButton.Set(m_rtClient.top, m_rtClient.left, m_rtClient.width,
+ m_rtClient.height / 2);
+ m_rtDnButton.Set(m_rtClient.left, m_rtClient.top + m_rtClient.height / 2,
+ m_rtClient.width, m_rtClient.height / 2);
+ } else {
+ m_rtUpButton.Set(m_rtClient.left, m_rtClient.top, m_rtClient.width / 2,
+ m_rtClient.height);
+ m_rtDnButton.Set(m_rtClient.left + m_rtClient.width / 2, m_rtClient.top,
+ m_rtClient.width / 2, m_rtClient.height);
+ }
+ return FWL_Error::Succeeded;
+}
+
+FWL_WidgetHit IFWL_SpinButton::HitTest(FX_FLOAT fx, FX_FLOAT fy) {
+ if (m_rtClient.Contains(fx, fy))
+ return FWL_WidgetHit::Client;
+ if (HasBorder() && (m_rtClient.Contains(fx, fy)))
+ return FWL_WidgetHit::Border;
+ if (HasEdge()) {
+ CFX_RectF rtEdge;
+ GetEdgeRect(rtEdge);
+ if (rtEdge.Contains(fx, fy))
+ return FWL_WidgetHit::Left;
+ }
+ if (m_rtUpButton.Contains(fx, fy))
+ return FWL_WidgetHit::UpButton;
+ if (m_rtDnButton.Contains(fx, fy))
+ return FWL_WidgetHit::DownButton;
+ return FWL_WidgetHit::Unknown;
+}
+
+FWL_Error IFWL_SpinButton::DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ if (!pGraphics)
+ return FWL_Error::Indefinite;
+ CFX_RectF rtClip(m_rtClient);
+ if (pMatrix) {
+ pMatrix->TransformRect(rtClip);
+ }
+ IFWL_ThemeProvider* pTheme = GetAvailableTheme();
+ if (HasBorder()) {
+ DrawBorder(pGraphics, CFWL_Part::Border, pTheme, pMatrix);
+ }
+ if (HasEdge()) {
+ DrawEdge(pGraphics, CFWL_Part::Edge, pTheme, pMatrix);
+ }
+ DrawUpButton(pGraphics, pTheme, pMatrix);
+ DrawDownButton(pGraphics, pTheme, pMatrix);
+ return FWL_Error::Succeeded;
+}
+
+void IFWL_SpinButton::Run(IFWL_TimerInfo* pTimerInfo) {
+ if (!m_pTimerInfo)
+ return;
+
+ CFWL_EvtSpbClick wmPosChanged;
+ wmPosChanged.m_pSrcTarget = this;
+ wmPosChanged.m_bUp = m_iButtonIndex == 0;
+ DispatchEvent(&wmPosChanged);
+}
+
+FWL_Error IFWL_SpinButton::EnableButton(FX_BOOL bEnable, FX_BOOL bUp) {
+ if (bUp) {
+ if (bEnable) {
+ m_dwUpState = CFWL_PartState_Normal;
+ } else {
+ m_dwUpState = CFWL_PartState_Disabled;
+ }
+ } else {
+ if (bEnable) {
+ m_dwDnState = CFWL_PartState_Normal;
+ } else {
+ m_dwDnState = CFWL_PartState_Disabled;
+ }
+ }
+ return FWL_Error::Succeeded;
+}
+
+FX_BOOL IFWL_SpinButton::IsButtonEnable(FX_BOOL bUp) {
+ if (bUp) {
+ return (m_dwUpState != CFWL_PartState_Disabled);
+ }
+ return (m_dwDnState != CFWL_PartState_Disabled);
+}
+
+void IFWL_SpinButton::DrawUpButton(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix) {
+ CFWL_ThemeBackground params;
+ params.m_pWidget = this;
+ params.m_iPart = CFWL_Part::UpButton;
+ params.m_pGraphics = pGraphics;
+ params.m_dwStates = m_dwUpState + 1;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ params.m_rtPart = m_rtUpButton;
+ pTheme->DrawBackground(&params);
+}
+
+void IFWL_SpinButton::DrawDownButton(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix) {
+ CFWL_ThemeBackground params;
+ params.m_pWidget = this;
+ params.m_iPart = CFWL_Part::DownButton;
+ params.m_pGraphics = pGraphics;
+ params.m_dwStates = m_dwDnState + 1;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ params.m_rtPart = m_rtDnButton;
+ pTheme->DrawBackground(&params);
+}
+
+CFWL_SpinButtonImpDelegate::CFWL_SpinButtonImpDelegate(IFWL_SpinButton* pOwner)
+ : m_pOwner(pOwner) {}
+
+void CFWL_SpinButtonImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
+ if (!pMessage)
+ 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_WidgetImpDelegate::OnProcessMessage(pMessage);
+}
+
+void CFWL_SpinButtonImpDelegate::OnProcessEvent(CFWL_Event* pEvent) {}
+
+void CFWL_SpinButtonImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ m_pOwner->DrawWidget(pGraphics, pMatrix);
+}
+
+void CFWL_SpinButtonImpDelegate::OnFocusChanged(CFWL_Message* pMsg,
+ FX_BOOL bSet) {
+ if (bSet) {
+ m_pOwner->m_pProperties->m_dwStates |= (FWL_WGTSTATE_Focused);
+ } else {
+ m_pOwner->m_pProperties->m_dwStates &= ~(FWL_WGTSTATE_Focused);
+ }
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+}
+
+void CFWL_SpinButtonImpDelegate::OnLButtonDown(CFWL_MsgMouse* pMsg) {
+ m_pOwner->m_bLButtonDwn = TRUE;
+ m_pOwner->SetGrab(TRUE);
+ m_pOwner->SetFocus(TRUE);
+ if (!m_pOwner->m_pProperties->m_pDataProvider)
+ return;
+ FX_BOOL bUpPress = (m_pOwner->m_rtUpButton.Contains(pMsg->m_fx, pMsg->m_fy) &&
+ m_pOwner->IsButtonEnable(TRUE));
+ FX_BOOL bDnPress = (m_pOwner->m_rtDnButton.Contains(pMsg->m_fx, pMsg->m_fy) &&
+ m_pOwner->IsButtonEnable(FALSE));
+ if (!bUpPress && !bDnPress) {
+ return;
+ }
+ if (bUpPress) {
+ m_pOwner->m_iButtonIndex = 0;
+ m_pOwner->m_dwUpState = CFWL_PartState_Pressed;
+ }
+ if (bDnPress) {
+ m_pOwner->m_iButtonIndex = 1;
+ m_pOwner->m_dwDnState = CFWL_PartState_Pressed;
+ }
+ CFWL_EvtSpbClick wmPosChanged;
+ wmPosChanged.m_pSrcTarget = m_pOwner;
+ wmPosChanged.m_bUp = bUpPress;
+ m_pOwner->DispatchEvent(&wmPosChanged);
+ m_pOwner->Repaint(bUpPress ? &m_pOwner->m_rtUpButton
+ : &m_pOwner->m_rtDnButton);
+ m_pOwner->m_pTimerInfo = m_pOwner->StartTimer(kElapseTime, true);
+}
+
+void CFWL_SpinButtonImpDelegate::OnLButtonUp(CFWL_MsgMouse* pMsg) {
+ if (m_pOwner->m_pProperties->m_dwStates & CFWL_PartState_Disabled) {
+ return;
+ }
+ m_pOwner->m_bLButtonDwn = FALSE;
+ m_pOwner->SetGrab(FALSE);
+ m_pOwner->SetFocus(FALSE);
+ if (m_pOwner->m_pTimerInfo) {
+ m_pOwner->m_pTimerInfo->StopTimer();
+ m_pOwner->m_pTimerInfo = nullptr;
+ }
+ FX_BOOL bRepaint = FALSE;
+ CFX_RectF rtInvalidate;
+ if (m_pOwner->m_dwUpState == CFWL_PartState_Pressed &&
+ m_pOwner->IsButtonEnable(TRUE)) {
+ m_pOwner->m_dwUpState = CFWL_PartState_Normal;
+ bRepaint = TRUE;
+ rtInvalidate = m_pOwner->m_rtUpButton;
+ } else if (m_pOwner->m_dwDnState == CFWL_PartState_Pressed &&
+ m_pOwner->IsButtonEnable(FALSE)) {
+ m_pOwner->m_dwDnState = CFWL_PartState_Normal;
+ bRepaint = TRUE;
+ rtInvalidate = m_pOwner->m_rtDnButton;
+ }
+ if (bRepaint) {
+ m_pOwner->Repaint(&rtInvalidate);
+ }
+}
+
+void CFWL_SpinButtonImpDelegate::OnMouseMove(CFWL_MsgMouse* pMsg) {
+ if (!m_pOwner->m_pProperties->m_pDataProvider)
+ return;
+ if (m_pOwner->m_bLButtonDwn) {
+ return;
+ }
+ FX_BOOL bRepaint = FALSE;
+ CFX_RectF rtInvlidate;
+ rtInvlidate.Reset();
+ if (m_pOwner->m_rtUpButton.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ if (m_pOwner->IsButtonEnable(TRUE)) {
+ if (m_pOwner->m_dwUpState == CFWL_PartState_Hovered) {
+ m_pOwner->m_dwUpState = CFWL_PartState_Hovered;
+ bRepaint = TRUE;
+ rtInvlidate = m_pOwner->m_rtUpButton;
+ }
+ if (m_pOwner->m_dwDnState != CFWL_PartState_Normal &&
+ m_pOwner->IsButtonEnable(FALSE)) {
+ m_pOwner->m_dwDnState = CFWL_PartState_Normal;
+ if (bRepaint) {
+ rtInvlidate.Union(m_pOwner->m_rtDnButton);
+ } else {
+ rtInvlidate = m_pOwner->m_rtDnButton;
+ }
+ bRepaint = TRUE;
+ }
+ }
+ if (!m_pOwner->IsButtonEnable(FALSE)) {
+ m_pOwner->EnableButton(FALSE, FALSE);
+ }
+ } else if (m_pOwner->m_rtDnButton.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ if (m_pOwner->IsButtonEnable(FALSE)) {
+ if (m_pOwner->m_dwDnState != CFWL_PartState_Hovered) {
+ m_pOwner->m_dwDnState = CFWL_PartState_Hovered;
+ bRepaint = TRUE;
+ rtInvlidate = m_pOwner->m_rtDnButton;
+ }
+ if (m_pOwner->m_dwUpState != CFWL_PartState_Normal &&
+ m_pOwner->IsButtonEnable(TRUE)) {
+ m_pOwner->m_dwUpState = CFWL_PartState_Normal;
+ if (bRepaint) {
+ rtInvlidate.Union(m_pOwner->m_rtUpButton);
+ } else {
+ rtInvlidate = m_pOwner->m_rtUpButton;
+ }
+ bRepaint = TRUE;
+ }
+ }
+ } else if (m_pOwner->m_dwUpState != CFWL_PartState_Normal ||
+ m_pOwner->m_dwDnState != CFWL_PartState_Normal) {
+ if (m_pOwner->m_dwUpState != CFWL_PartState_Normal) {
+ m_pOwner->m_dwUpState = CFWL_PartState_Normal;
+ bRepaint = TRUE;
+ rtInvlidate = m_pOwner->m_rtUpButton;
+ }
+ if (m_pOwner->m_dwDnState != CFWL_PartState_Normal) {
+ m_pOwner->m_dwDnState = CFWL_PartState_Normal;
+ if (bRepaint) {
+ rtInvlidate.Union(m_pOwner->m_rtDnButton);
+ } else {
+ rtInvlidate = m_pOwner->m_rtDnButton;
+ }
+ bRepaint = TRUE;
+ }
+ }
+ if (bRepaint) {
+ m_pOwner->Repaint(&rtInvlidate);
+ }
+}
+
+void CFWL_SpinButtonImpDelegate::OnMouseLeave(CFWL_MsgMouse* pMsg) {
+ if (!pMsg)
+ return;
+ if (m_pOwner->m_dwUpState != CFWL_PartState_Normal &&
+ m_pOwner->IsButtonEnable(TRUE)) {
+ m_pOwner->m_dwUpState = CFWL_PartState_Normal;
+ }
+ if (m_pOwner->m_dwDnState != CFWL_PartState_Normal &&
+ m_pOwner->IsButtonEnable(FALSE)) {
+ m_pOwner->m_dwDnState = CFWL_PartState_Normal;
+ }
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+}
+
+void CFWL_SpinButtonImpDelegate::OnKeyDown(CFWL_MsgKey* pMsg) {
+ if (!m_pOwner->m_pProperties->m_pDataProvider)
+ return;
+ FX_BOOL bUp =
+ pMsg->m_dwKeyCode == FWL_VKEY_Up || pMsg->m_dwKeyCode == FWL_VKEY_Left;
+ FX_BOOL bDown =
+ pMsg->m_dwKeyCode == FWL_VKEY_Down || pMsg->m_dwKeyCode == FWL_VKEY_Right;
+ if (!bUp && !bDown) {
+ return;
+ }
+ FX_BOOL bUpEnable = m_pOwner->IsButtonEnable(TRUE);
+ FX_BOOL bDownEnable = m_pOwner->IsButtonEnable(FALSE);
+ if (!bUpEnable && !bDownEnable) {
+ return;
+ }
+ CFWL_EvtSpbClick wmPosChanged;
+ wmPosChanged.m_pSrcTarget = m_pOwner;
+ wmPosChanged.m_bUp = bUpEnable;
+ m_pOwner->DispatchEvent(&wmPosChanged);
+ m_pOwner->Repaint(bUpEnable ? &m_pOwner->m_rtUpButton
+ : &m_pOwner->m_rtDnButton);
+}
diff --git a/xfa/fwl/core/ifwl_spinbutton.h b/xfa/fwl/core/ifwl_spinbutton.h
new file mode 100644
index 0000000000..717ba9f011
--- /dev/null
+++ b/xfa/fwl/core/ifwl_spinbutton.h
@@ -0,0 +1,88 @@
+// 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_SPINBUTTON_H_
+#define XFA_FWL_CORE_IFWL_SPINBUTTON_H_
+
+#include "xfa/fwl/core/cfwl_event.h"
+#include "xfa/fwl/core/ifwl_timer.h"
+#include "xfa/fwl/core/ifwl_widget.h"
+#include "xfa/fxfa/cxfa_eventparam.h"
+
+#define FWL_CLASS_SpinButton L"FWL_SPINBUTTON"
+#define FWL_STYLEEXE_SPB_Vert (1L << 0)
+
+class CFWL_MsgMouse;
+class CFWL_SpinButtonImpDelegate;
+class CFWL_WidgetImpProperties;
+
+FWL_EVENT_DEF(CFWL_EvtSpbClick, CFWL_EventType::Click, FX_BOOL m_bUp;)
+
+class IFWL_SpinButton : public IFWL_Widget, public IFWL_Timer {
+ public:
+ static IFWL_SpinButton* Create(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+
+ IFWL_SpinButton(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+ ~IFWL_SpinButton() override;
+
+ // IFWL_Widget
+ FWL_Error GetClassName(CFX_WideString& wsClass) const override;
+ FWL_Type GetClassID() const override;
+ FWL_Error Initialize() override;
+ FWL_Error Finalize() override;
+ FWL_Error GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize = FALSE) override;
+ FWL_Error Update() override;
+ FWL_WidgetHit HitTest(FX_FLOAT fx, FX_FLOAT fy) override;
+ FWL_Error DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
+
+ // IFWL_Timer
+ void Run(IFWL_TimerInfo* pTimerInfo) override;
+
+ FWL_Error EnableButton(FX_BOOL bEnable, FX_BOOL bUp = TRUE);
+ FX_BOOL IsButtonEnable(FX_BOOL bUp = TRUE);
+
+ protected:
+ friend class CFWL_SpinButtonImpDelegate;
+
+ void DrawUpButton(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix);
+ void DrawDownButton(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix);
+
+ CFX_RectF m_rtClient;
+ CFX_RectF m_rtUpButton;
+ CFX_RectF m_rtDnButton;
+ uint32_t m_dwUpState;
+ uint32_t m_dwDnState;
+ int32_t m_iButtonIndex;
+ FX_BOOL m_bLButtonDwn;
+ IFWL_TimerInfo* m_pTimerInfo;
+};
+
+class CFWL_SpinButtonImpDelegate : public CFWL_WidgetImpDelegate {
+ public:
+ CFWL_SpinButtonImpDelegate(IFWL_SpinButton* pOwner);
+ void OnProcessMessage(CFWL_Message* pMessage) override;
+ void OnProcessEvent(CFWL_Event* pEvent) override;
+ void OnDrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
+
+ protected:
+ void OnFocusChanged(CFWL_Message* pMsg, FX_BOOL bSet = TRUE);
+ 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);
+ IFWL_SpinButton* m_pOwner;
+};
+
+#endif // XFA_FWL_CORE_IFWL_SPINBUTTON_H_
diff --git a/xfa/fwl/core/fwl_timerimp.cpp b/xfa/fwl/core/ifwl_timer.cpp
index 941113e7ca..941113e7ca 100644
--- a/xfa/fwl/core/fwl_timerimp.cpp
+++ b/xfa/fwl/core/ifwl_timer.cpp
diff --git a/xfa/fwl/core/ifwl_tooltip.cpp b/xfa/fwl/core/ifwl_tooltip.cpp
new file mode 100644
index 0000000000..f0c46555a0
--- /dev/null
+++ b/xfa/fwl/core/ifwl_tooltip.cpp
@@ -0,0 +1,286 @@
+// 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_tooltip.h"
+
+#include "xfa/fde/tto/fde_textout.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/fwl_noteimp.h"
+#include "xfa/fwl/core/ifwl_themeprovider.h"
+#include "xfa/fwl/core/ifwl_tooltip.h"
+#include "xfa/fwl/theme/cfwl_widgettp.h"
+
+// static
+IFWL_ToolTip* IFWL_ToolTip::Create(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter) {
+ return new IFWL_ToolTip(properties, pOuter);
+}
+
+IFWL_ToolTip::IFWL_ToolTip(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter)
+ : IFWL_Form(properties, pOuter),
+ m_bBtnDown(FALSE),
+ m_dwTTOStyles(FDE_TTOSTYLE_SingleLine),
+ m_iTTOAlign(FDE_TTOALIGNMENT_Center),
+ m_pTimerInfoShow(nullptr),
+ m_pTimerInfoHide(nullptr) {
+ m_rtClient.Set(0, 0, 0, 0);
+ m_rtCaption.Set(0, 0, 0, 0);
+ m_rtAnchor.Set(0, 0, 0, 0);
+ m_TimerShow.m_pToolTip = this;
+ m_TimerHide.m_pToolTip = this;
+}
+
+IFWL_ToolTip::~IFWL_ToolTip() {}
+
+FWL_Error IFWL_ToolTip::GetClassName(CFX_WideString& wsClass) const {
+ wsClass = FWL_CLASS_ToolTip;
+ return FWL_Error::Succeeded;
+}
+
+FWL_Type IFWL_ToolTip::GetClassID() const {
+ return FWL_Type::ToolTip;
+}
+
+FWL_Error IFWL_ToolTip::Initialize() {
+ m_pProperties->m_dwStyles |= FWL_WGTSTYLE_Popup;
+ m_pProperties->m_dwStyles &= ~FWL_WGTSTYLE_Child;
+ if (IFWL_Widget::Initialize() != FWL_Error::Succeeded)
+ return FWL_Error::Indefinite;
+
+ m_pDelegate = new CFWL_ToolTipImpDelegate(this);
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_ToolTip::Finalize() {
+ delete m_pDelegate;
+ m_pDelegate = nullptr;
+ return IFWL_Widget::Finalize();
+}
+
+FWL_Error IFWL_ToolTip::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
+ if (bAutoSize) {
+ rect.Set(0, 0, 0, 0);
+ if (!m_pProperties->m_pThemeProvider) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ CFX_WideString wsCaption;
+ IFWL_ToolTipDP* pData =
+ static_cast<IFWL_ToolTipDP*>(m_pProperties->m_pDataProvider);
+ if (pData) {
+ pData->GetCaption(this, wsCaption);
+ }
+ int32_t iLen = wsCaption.GetLength();
+ if (iLen > 0) {
+ CFX_SizeF sz = CalcTextSize(wsCaption, m_pProperties->m_pThemeProvider);
+ rect.Set(0, 0, sz.x, sz.y);
+ rect.width += 25;
+ rect.height += 16;
+ }
+ IFWL_Widget::GetWidgetRect(rect, TRUE);
+ } else {
+ rect = m_pProperties->m_rtWidget;
+ }
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_ToolTip::Update() {
+ if (IsLocked()) {
+ return FWL_Error::Indefinite;
+ }
+ if (!m_pProperties->m_pThemeProvider) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ UpdateTextOutStyles();
+ GetClientRect(m_rtClient);
+ m_rtCaption = m_rtClient;
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_ToolTip::GetClientRect(CFX_RectF& rect) {
+ FX_FLOAT x = 0;
+ FX_FLOAT y = 0;
+ FX_FLOAT t = 0;
+ IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
+ if (pTheme) {
+ CFWL_ThemePart part;
+ part.m_pWidget = this;
+ x = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::CXBorder));
+ y = *static_cast<FX_FLOAT*>(
+ pTheme->GetCapacity(&part, CFWL_WidgetCapacity::CYBorder));
+ }
+ rect = m_pProperties->m_rtWidget;
+ rect.Offset(-rect.left, -rect.top);
+ rect.Deflate(x, t, x, y);
+ return FWL_Error::Succeeded;
+}
+
+FWL_Error IFWL_ToolTip::DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ if (!pGraphics || !m_pProperties->m_pThemeProvider)
+ return FWL_Error::Indefinite;
+
+ IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
+ DrawBkground(pGraphics, pTheme, pMatrix);
+ DrawText(pGraphics, pTheme, pMatrix);
+ return FWL_Error::Succeeded;
+}
+
+void IFWL_ToolTip::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 = m_pProperties->m_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_rtCaption;
+ }
+ pTheme->DrawBackground(&param);
+}
+
+void IFWL_ToolTip::DrawText(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix) {
+ if (!m_pProperties->m_pDataProvider)
+ return;
+ CFX_WideString wsCaption;
+ m_pProperties->m_pDataProvider->GetCaption(this, wsCaption);
+ if (wsCaption.IsEmpty()) {
+ return;
+ }
+ CFWL_ThemeText param;
+ param.m_pWidget = this;
+ param.m_iPart = CFWL_Part::Caption;
+ param.m_dwStates = m_pProperties->m_dwStates;
+ param.m_pGraphics = pGraphics;
+ if (pMatrix) {
+ param.m_matrix.Concat(*pMatrix);
+ }
+ param.m_rtPart = m_rtCaption;
+ param.m_wsText = wsCaption;
+ param.m_dwTTOStyles = m_dwTTOStyles;
+ param.m_iTTOAlign = m_iTTOAlign;
+ pTheme->DrawText(&param);
+}
+
+void IFWL_ToolTip::UpdateTextOutStyles() {
+ m_iTTOAlign = FDE_TTOALIGNMENT_Center;
+ m_dwTTOStyles = FDE_TTOSTYLE_SingleLine;
+ if (m_pProperties->m_dwStyleExes & FWL_WGTSTYLE_RTLReading) {
+ m_dwTTOStyles |= FDE_TTOSTYLE_RTL;
+ }
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_TTP_Multiline) {
+ m_dwTTOStyles &= ~FDE_TTOSTYLE_SingleLine;
+ }
+}
+
+void IFWL_ToolTip::SetAnchor(const CFX_RectF& rtAnchor) {
+ m_rtAnchor = rtAnchor;
+}
+
+void IFWL_ToolTip::Show() {
+ IFWL_ToolTipDP* pData =
+ static_cast<IFWL_ToolTipDP*>(m_pProperties->m_pDataProvider);
+ int32_t nInitDelay = pData->GetInitialDelay(this);
+ if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Invisible))
+ m_pTimerInfoShow = m_TimerShow.StartTimer(nInitDelay, false);
+}
+
+void IFWL_ToolTip::Hide() {
+ SetStates(FWL_WGTSTATE_Invisible, TRUE);
+ if (m_pTimerInfoHide) {
+ m_pTimerInfoHide->StopTimer();
+ m_pTimerInfoHide = nullptr;
+ }
+ if (m_pTimerInfoShow) {
+ m_pTimerInfoShow->StopTimer();
+ m_pTimerInfoShow = nullptr;
+ }
+}
+
+void IFWL_ToolTip::SetStates(uint32_t dwStates, FX_BOOL bSet) {
+ if ((dwStates & FWL_WGTSTATE_Invisible) && !bSet) {
+ IFWL_ToolTipDP* pData =
+ static_cast<IFWL_ToolTipDP*>(m_pProperties->m_pDataProvider);
+ int32_t nAutoPopDelay = pData->GetAutoPopDelay(this);
+ m_pTimerInfoHide = m_TimerHide.StartTimer(nAutoPopDelay, false);
+ }
+ IFWL_Widget::SetStates(dwStates, bSet);
+}
+
+void IFWL_ToolTip::RefreshToolTipPos() {
+ if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_TTP_NoAnchor) == 0) {
+ CFX_RectF rtPopup;
+ CFX_RectF rtWidget(m_pProperties->m_rtWidget);
+ CFX_RectF rtAnchor(m_rtAnchor);
+ rtPopup.Set(0, 0, 0, 0);
+ FX_FLOAT fx = rtAnchor.Center().x + 20;
+ FX_FLOAT fy = rtAnchor.Center().y + 20;
+ rtPopup.Set(fx, fy, rtWidget.Width(), rtWidget.Height());
+ FX_FLOAT fScreenWidth = 0;
+ FX_FLOAT fScreenHeight = 0;
+ GetScreenSize(fScreenWidth, fScreenHeight);
+ if (rtPopup.bottom() > fScreenHeight) {
+ rtPopup.Offset(0, fScreenHeight - rtPopup.bottom());
+ }
+ if (rtPopup.right() > fScreenWidth) {
+ rtPopup.Offset(fScreenWidth - rtPopup.right(), 0);
+ }
+ if (rtPopup.left < 0) {
+ rtPopup.Offset(0 - rtPopup.left, 0);
+ }
+ if (rtPopup.top < 0) {
+ rtPopup.Offset(0, 0 - rtPopup.top);
+ }
+ SetWidgetRect(rtPopup);
+ Update();
+ }
+}
+
+IFWL_ToolTip::CFWL_ToolTipTimer::CFWL_ToolTipTimer(IFWL_ToolTip* pToolTip)
+ : m_pToolTip(pToolTip) {}
+
+void IFWL_ToolTip::CFWL_ToolTipTimer::Run(IFWL_TimerInfo* pTimerInfo) {
+ if (m_pToolTip->m_pTimerInfoShow == pTimerInfo &&
+ m_pToolTip->m_pTimerInfoShow) {
+ if (m_pToolTip->GetStates() & FWL_WGTSTATE_Invisible) {
+ m_pToolTip->SetStates(FWL_WGTSTATE_Invisible, FALSE);
+ m_pToolTip->RefreshToolTipPos();
+ m_pToolTip->m_pTimerInfoShow->StopTimer();
+ m_pToolTip->m_pTimerInfoShow = nullptr;
+ return;
+ }
+ }
+ if (m_pToolTip->m_pTimerInfoHide == pTimerInfo &&
+ m_pToolTip->m_pTimerInfoHide) {
+ m_pToolTip->SetStates(FWL_WGTSTATE_Invisible, TRUE);
+ m_pToolTip->m_pTimerInfoHide->StopTimer();
+ m_pToolTip->m_pTimerInfoHide = nullptr;
+ }
+}
+
+CFWL_ToolTipImpDelegate::CFWL_ToolTipImpDelegate(IFWL_ToolTip* pOwner)
+ : m_pOwner(pOwner) {}
+
+void CFWL_ToolTipImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
+ CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);
+}
+
+void CFWL_ToolTipImpDelegate::OnProcessEvent(CFWL_Event* pEvent) {}
+
+void CFWL_ToolTipImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ m_pOwner->DrawWidget(pGraphics, pMatrix);
+}
diff --git a/xfa/fwl/core/ifwl_tooltip.h b/xfa/fwl/core/ifwl_tooltip.h
new file mode 100644
index 0000000000..69f0e13596
--- /dev/null
+++ b/xfa/fwl/core/ifwl_tooltip.h
@@ -0,0 +1,114 @@
+// 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_TOOLTIP_H_
+#define XFA_FWL_CORE_IFWL_TOOLTIP_H_
+
+#include "xfa/fwl/core/ifwl_form.h"
+#include "xfa/fwl/core/ifwl_timer.h"
+
+class CFWL_WidgetImpProperties;
+class IFWL_Widget;
+class CFWL_ToolTipImpDelegate;
+
+#define FWL_CLASS_ToolTip L"FWL_TOOLTIP"
+#define FWL_STYLEEXT_TTP_Rectangle (0L << 3)
+#define FWL_STYLEEXT_TTP_RoundCorner (1L << 3)
+#define FWL_STYLEEXT_TTP_Balloon (1L << 4)
+#define FWL_STYLEEXT_TTP_Multiline (1L << 5)
+#define FWL_STYLEEXT_TTP_NoAnchor (1L << 6)
+
+class IFWL_ToolTipDP : public IFWL_DataProvider {
+ public:
+ // IFWL_DataProvider
+ FWL_Error GetCaption(IFWL_Widget* pWidget,
+ CFX_WideString& wsCaption) override = 0;
+
+ virtual int32_t GetInitialDelay(IFWL_Widget* pWidget) = 0;
+ virtual int32_t GetAutoPopDelay(IFWL_Widget* pWidget) = 0;
+ virtual CFX_DIBitmap* GetToolTipIcon(IFWL_Widget* pWidget) = 0;
+ virtual CFX_SizeF GetToolTipIconSize(IFWL_Widget* pWidget) = 0;
+};
+
+class IFWL_ToolTip : public IFWL_Form {
+ public:
+ static IFWL_ToolTip* Create(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter);
+
+ IFWL_ToolTip(const CFWL_WidgetImpProperties& properties, IFWL_Widget* pOuter);
+ ~IFWL_ToolTip() override;
+
+ // IFWL_Widget
+ FWL_Error GetClassName(CFX_WideString& wsClass) const override;
+ FWL_Type GetClassID() const override;
+ FWL_Error Initialize() override;
+ FWL_Error Finalize() override;
+ FWL_Error GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize = FALSE) override;
+ FWL_Error Update() override;
+ FWL_Error DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
+ void SetStates(uint32_t dwStates, FX_BOOL bSet) override;
+ FWL_Error GetClientRect(CFX_RectF& rect) override;
+
+ void SetAnchor(const CFX_RectF& rtAnchor);
+ void Show();
+ void Hide();
+
+ protected:
+ friend class CFWL_ToolTipImpDelegate;
+ friend class CFWL_ToolTipTimer;
+
+ class CFWL_ToolTipTimer : public IFWL_Timer {
+ public:
+ CFWL_ToolTipTimer() {}
+ explicit CFWL_ToolTipTimer(IFWL_ToolTip* pToolTip);
+ ~CFWL_ToolTipTimer() override {}
+
+ void Run(IFWL_TimerInfo* pTimerInfo) override;
+
+ IFWL_ToolTip* m_pToolTip;
+ };
+
+ void DrawBkground(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix);
+ void DrawText(CFX_Graphics* pGraphics,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix);
+ void UpdateTextOutStyles();
+ void RefreshToolTipPos();
+
+ CFX_RectF m_rtClient;
+ CFX_RectF m_rtCaption;
+ FX_BOOL m_bBtnDown;
+ uint32_t m_dwTTOStyles;
+ int32_t m_iTTOAlign;
+ CFX_RectF m_rtAnchor;
+ IFWL_TimerInfo* m_pTimerInfoShow;
+ IFWL_TimerInfo* m_pTimerInfoHide;
+ CFWL_ToolTipTimer m_TimerShow;
+ CFWL_ToolTipTimer m_TimerHide;
+};
+
+class CFWL_ToolTipImpDelegate : public CFWL_WidgetImpDelegate {
+ public:
+ CFWL_ToolTipImpDelegate(IFWL_ToolTip* pOwner);
+ void OnProcessMessage(CFWL_Message* pMessage) override;
+ void OnProcessEvent(CFWL_Event* pEvent) override;
+ void OnDrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
+
+ protected:
+ void OnFocusChanged(CFWL_Message* pMsg, FX_BOOL bSet = TRUE);
+ 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);
+ IFWL_ToolTip* m_pOwner;
+};
+
+#endif // XFA_FWL_CORE_IFWL_TOOLTIP_H_
diff --git a/xfa/fwl/core/fwl_widgetimp.cpp b/xfa/fwl/core/ifwl_widget.cpp
index 890f0da8af..68755bf24a 100644
--- a/xfa/fwl/core/fwl_widgetimp.cpp
+++ b/xfa/fwl/core/ifwl_widget.cpp
@@ -4,12 +4,11 @@
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-#include "xfa/fwl/core/fwl_widgetimp.h"
+#include "xfa/fwl/core/ifwl_widget.h"
#include <algorithm>
#include "xfa/fde/tto/fde_textout.h"
-#include "xfa/fwl/basewidget/ifwl_combobox.h"
#include "xfa/fwl/core/cfwl_message.h"
#include "xfa/fwl/core/cfwl_themebackground.h"
#include "xfa/fwl/core/cfwl_themepart.h"
@@ -17,6 +16,7 @@
#include "xfa/fwl/core/cfwl_widgetmgr.h"
#include "xfa/fwl/core/fwl_noteimp.h"
#include "xfa/fwl/core/ifwl_app.h"
+#include "xfa/fwl/core/ifwl_combobox.h"
#include "xfa/fwl/core/ifwl_form.h"
#include "xfa/fwl/core/ifwl_themeprovider.h"
#include "xfa/fwl/core/ifwl_widget.h"
@@ -24,149 +24,7 @@
#define FWL_STYLEEXT_MNU_Vert (1L << 0)
-IFWL_Widget::IFWL_Widget() {}
-
-IFWL_Widget::~IFWL_Widget() {}
-
-FWL_Error IFWL_Widget::GetClassName(CFX_WideString& wsClass) const {
- return m_pImpl->GetClassName(wsClass);
-}
-
-FWL_Type IFWL_Widget::GetClassID() const {
- return m_pImpl->GetClassID();
-}
-
-FX_BOOL IFWL_Widget::IsInstance(const CFX_WideStringC& wsClass) const {
- return m_pImpl->IsInstance(wsClass);
-}
-
FWL_Error IFWL_Widget::Initialize() {
- return m_pImpl->Initialize();
-}
-
-FWL_Error IFWL_Widget::Finalize() {
- return m_pImpl->Finalize();
-}
-
-FWL_Error IFWL_Widget::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
- return GetImpl()->GetWidgetRect(rect, bAutoSize);
-}
-FWL_Error IFWL_Widget::GetGlobalRect(CFX_RectF& rect) {
- return GetImpl()->GetGlobalRect(rect);
-}
-FWL_Error IFWL_Widget::SetWidgetRect(const CFX_RectF& rect) {
- return GetImpl()->SetWidgetRect(rect);
-}
-FWL_Error IFWL_Widget::GetClientRect(CFX_RectF& rect) {
- return GetImpl()->GetClientRect(rect);
-}
-IFWL_Widget* IFWL_Widget::GetParent() {
- return GetImpl()->GetParent();
-}
-FWL_Error IFWL_Widget::SetParent(IFWL_Widget* pParent) {
- return GetImpl()->SetParent(pParent);
-}
-IFWL_Widget* IFWL_Widget::GetOwner() {
- return GetImpl()->GetOwner();
-}
-FWL_Error IFWL_Widget::SetOwner(IFWL_Widget* pOwner) {
- return GetImpl()->SetOwner(pOwner);
-}
-IFWL_Widget* IFWL_Widget::GetOuter() {
- return GetImpl()->GetOuter();
-}
-uint32_t IFWL_Widget::GetStyles() {
- return GetImpl()->GetStyles();
-}
-FWL_Error IFWL_Widget::ModifyStyles(uint32_t dwStylesAdded,
- uint32_t dwStylesRemoved) {
- return GetImpl()->ModifyStyles(dwStylesAdded, dwStylesRemoved);
-}
-uint32_t IFWL_Widget::GetStylesEx() {
- return GetImpl()->GetStylesEx();
-}
-FWL_Error IFWL_Widget::ModifyStylesEx(uint32_t dwStylesExAdded,
- uint32_t dwStylesExRemoved) {
- return GetImpl()->ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
-}
-uint32_t IFWL_Widget::GetStates() {
- return GetImpl()->GetStates();
-}
-void IFWL_Widget::SetStates(uint32_t dwStates, FX_BOOL bSet) {
- GetImpl()->SetStates(dwStates, bSet);
-}
-
-uint32_t IFWL_Widget::GetEventKey() const {
- return GetImpl()->GetEventKey();
-}
-
-void IFWL_Widget::SetEventKey(uint32_t key) {
- GetImpl()->SetEventKey(key);
-}
-
-void* IFWL_Widget::GetLayoutItem() const {
- return GetImpl()->GetLayoutItem();
-}
-
-void IFWL_Widget::SetLayoutItem(void* pItem) {
- GetImpl()->SetLayoutItem(pItem);
-}
-
-void* IFWL_Widget::GetAssociateWidget() const {
- return GetImpl()->GetAssociateWidget();
-}
-
-void IFWL_Widget::SetAssociateWidget(void* pAssociate) {
- GetImpl()->SetAssociateWidget(pAssociate);
-}
-
-FWL_Error IFWL_Widget::Update() {
- return GetImpl()->Update();
-}
-FWL_Error IFWL_Widget::LockUpdate() {
- return GetImpl()->LockUpdate();
-}
-FWL_Error IFWL_Widget::UnlockUpdate() {
- return GetImpl()->UnlockUpdate();
-}
-FWL_WidgetHit IFWL_Widget::HitTest(FX_FLOAT fx, FX_FLOAT fy) {
- return GetImpl()->HitTest(fx, fy);
-}
-FWL_Error IFWL_Widget::TransformTo(IFWL_Widget* pWidget,
- FX_FLOAT& fx,
- FX_FLOAT& fy) {
- return GetImpl()->TransformTo(pWidget, fx, fy);
-}
-FWL_Error IFWL_Widget::TransformTo(IFWL_Widget* pWidget, CFX_RectF& rt) {
- return GetImpl()->TransformTo(pWidget, rt);
-}
-FWL_Error IFWL_Widget::GetMatrix(CFX_Matrix& matrix, FX_BOOL bGlobal) {
- return GetImpl()->GetMatrix(matrix, bGlobal);
-}
-FWL_Error IFWL_Widget::SetMatrix(const CFX_Matrix& matrix) {
- return GetImpl()->SetMatrix(matrix);
-}
-FWL_Error IFWL_Widget::DrawWidget(CFX_Graphics* pGraphics,
- const CFX_Matrix* pMatrix) {
- return GetImpl()->DrawWidget(pGraphics, pMatrix);
-}
-IFWL_ThemeProvider* IFWL_Widget::GetThemeProvider() {
- return GetImpl()->GetThemeProvider();
-}
-FWL_Error IFWL_Widget::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) {
- return GetImpl()->SetThemeProvider(pThemeProvider);
-}
-IFWL_WidgetDelegate* IFWL_Widget::SetDelegate(IFWL_WidgetDelegate* pDelegate) {
- return GetImpl()->SetDelegate(pDelegate);
-}
-IFWL_App* IFWL_Widget::GetOwnerApp() const {
- return GetImpl()->GetOwnerApp();
-}
-CFX_SizeF IFWL_Widget::GetOffsetFromParent(IFWL_Widget* pParent) {
- return GetImpl()->GetOffsetFromParent(pParent);
-}
-
-FWL_Error CFWL_WidgetImp::Initialize() {
IFWL_App* pApp = FWL_GetApp();
if (!pApp)
return FWL_Error::Indefinite;
@@ -178,31 +36,31 @@ FWL_Error CFWL_WidgetImp::Initialize() {
SetOwnerApp(FWL_GetApp());
IFWL_Widget* pParent = m_pProperties->m_pParent;
- m_pWidgetMgr->InsertWidget(pParent, m_pInterface);
+ m_pWidgetMgr->InsertWidget(pParent, this);
if (!IsChild()) {
IFWL_Widget* pOwner = m_pProperties->m_pOwner;
if (pOwner)
- m_pWidgetMgr->SetOwner(pOwner, m_pInterface);
+ m_pWidgetMgr->SetOwner(pOwner, this);
}
return FWL_Error::Succeeded;
}
-FWL_Error CFWL_WidgetImp::Finalize() {
+FWL_Error IFWL_Widget::Finalize() {
NotifyDriver();
- m_pWidgetMgr->RemoveWidget(m_pInterface);
+ m_pWidgetMgr->RemoveWidget(this);
return FWL_Error::Succeeded;
}
-FWL_Error CFWL_WidgetImp::GetClassName(CFX_WideString& wsClass) const {
+FWL_Error IFWL_Widget::GetClassName(CFX_WideString& wsClass) const {
wsClass.clear();
return FWL_Error::Succeeded;
}
-FX_BOOL CFWL_WidgetImp::IsInstance(const CFX_WideStringC& wsClass) const {
+FX_BOOL IFWL_Widget::IsInstance(const CFX_WideStringC& wsClass) const {
return FALSE;
}
-FWL_Error CFWL_WidgetImp::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
+FWL_Error IFWL_Widget::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
if (bAutoSize) {
if (HasEdge()) {
FX_FLOAT fEdge = GetEdgeWidth();
@@ -218,27 +76,27 @@ FWL_Error CFWL_WidgetImp::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
return FWL_Error::Succeeded;
}
-FWL_Error CFWL_WidgetImp::GetGlobalRect(CFX_RectF& rect) {
- IFWL_Widget* pForm = m_pWidgetMgr->GetSystemFormWidget(m_pInterface);
+FWL_Error IFWL_Widget::GetGlobalRect(CFX_RectF& rect) {
+ IFWL_Widget* pForm = m_pWidgetMgr->GetSystemFormWidget(this);
if (!pForm)
return FWL_Error::Indefinite;
rect.Set(0, 0, m_pProperties->m_rtWidget.width,
m_pProperties->m_rtWidget.height);
- if (pForm == m_pInterface)
+ if (pForm == this)
return FWL_Error::Succeeded;
return TransformTo(pForm, rect);
}
-FWL_Error CFWL_WidgetImp::SetWidgetRect(const CFX_RectF& rect) {
+FWL_Error 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 = m_pInterface;
+ ev.m_pSrcTarget = this;
ev.m_rtOld = rtOld;
ev.m_rtNew = rect;
IFWL_WidgetDelegate* pDelegate = SetDelegate(nullptr);
@@ -248,10 +106,11 @@ FWL_Error CFWL_WidgetImp::SetWidgetRect(const CFX_RectF& rect) {
}
return FWL_Error::Succeeded;
}
- m_pWidgetMgr->SetWidgetRect_Native(m_pInterface, rect);
+ m_pWidgetMgr->SetWidgetRect_Native(this, rect);
return FWL_Error::Succeeded;
}
-FWL_Error CFWL_WidgetImp::GetClientRect(CFX_RectF& rect) {
+
+FWL_Error IFWL_Widget::GetClientRect(CFX_RectF& rect) {
GetEdgeRect(rect);
if (HasEdge()) {
FX_FLOAT fEdge = GetEdgeWidth();
@@ -259,46 +118,57 @@ FWL_Error CFWL_WidgetImp::GetClientRect(CFX_RectF& rect) {
}
return FWL_Error::Succeeded;
}
-IFWL_Widget* CFWL_WidgetImp::GetParent() {
- return m_pWidgetMgr->GetParentWidget(m_pInterface);
+
+IFWL_Widget* IFWL_Widget::GetParent() {
+ return m_pWidgetMgr->GetParentWidget(this);
}
-FWL_Error CFWL_WidgetImp::SetParent(IFWL_Widget* pParent) {
+
+FWL_Error IFWL_Widget::SetParent(IFWL_Widget* pParent) {
m_pProperties->m_pParent = pParent;
- m_pWidgetMgr->SetParent(pParent, m_pInterface);
+ m_pWidgetMgr->SetParent(pParent, this);
return FWL_Error::Succeeded;
}
-IFWL_Widget* CFWL_WidgetImp::GetOwner() {
- return m_pWidgetMgr->GetOwnerWidget(m_pInterface);
+
+IFWL_Widget* IFWL_Widget::GetOwner() {
+ return m_pWidgetMgr->GetOwnerWidget(this);
}
-FWL_Error CFWL_WidgetImp::SetOwner(IFWL_Widget* pOwner) {
+
+FWL_Error IFWL_Widget::SetOwner(IFWL_Widget* pOwner) {
m_pProperties->m_pOwner = pOwner;
- m_pWidgetMgr->SetOwner(pOwner, m_pInterface);
+ m_pWidgetMgr->SetOwner(pOwner, this);
return FWL_Error::Succeeded;
}
-IFWL_Widget* CFWL_WidgetImp::GetOuter() {
+
+IFWL_Widget* IFWL_Widget::GetOuter() {
return m_pOuter;
}
-uint32_t CFWL_WidgetImp::GetStyles() {
+
+uint32_t IFWL_Widget::GetStyles() {
return m_pProperties->m_dwStyles;
}
-FWL_Error CFWL_WidgetImp::ModifyStyles(uint32_t dwStylesAdded,
- uint32_t dwStylesRemoved) {
+
+FWL_Error IFWL_Widget::ModifyStyles(uint32_t dwStylesAdded,
+ uint32_t dwStylesRemoved) {
m_pProperties->m_dwStyles =
(m_pProperties->m_dwStyles & ~dwStylesRemoved) | dwStylesAdded;
return FWL_Error::Succeeded;
}
-uint32_t CFWL_WidgetImp::GetStylesEx() {
+
+uint32_t IFWL_Widget::GetStylesEx() {
return m_pProperties->m_dwStyleExes;
}
-FWL_Error CFWL_WidgetImp::ModifyStylesEx(uint32_t dwStylesExAdded,
- uint32_t dwStylesExRemoved) {
+
+FWL_Error IFWL_Widget::ModifyStylesEx(uint32_t dwStylesExAdded,
+ uint32_t dwStylesExRemoved) {
m_pProperties->m_dwStyleExes =
(m_pProperties->m_dwStyleExes & ~dwStylesExRemoved) | dwStylesExAdded;
return FWL_Error::Succeeded;
}
-uint32_t CFWL_WidgetImp::GetStates() {
+
+uint32_t IFWL_Widget::GetStates() {
return m_pProperties->m_dwStates;
}
+
static void NotifyHideChildWidget(CFWL_WidgetMgr* widgetMgr,
IFWL_Widget* widget,
CFWL_NoteDriver* noteDriver) {
@@ -310,7 +180,7 @@ static void NotifyHideChildWidget(CFWL_WidgetMgr* widgetMgr,
}
}
-void CFWL_WidgetImp::SetStates(uint32_t dwStates, FX_BOOL bSet) {
+void IFWL_Widget::SetStates(uint32_t dwStates, FX_BOOL bSet) {
bSet ? (m_pProperties->m_dwStates |= dwStates)
: (m_pProperties->m_dwStates &= ~dwStates);
if (!(dwStates & FWL_WGTSTATE_Invisible) || !bSet)
@@ -319,8 +189,8 @@ void CFWL_WidgetImp::SetStates(uint32_t dwStates, FX_BOOL bSet) {
CFWL_NoteDriver* noteDriver =
static_cast<CFWL_NoteDriver*>(GetOwnerApp()->GetNoteDriver());
CFWL_WidgetMgr* widgetMgr = CFWL_WidgetMgr::GetInstance();
- noteDriver->NotifyTargetHide(m_pInterface);
- IFWL_Widget* child = widgetMgr->GetFirstChildWidget(m_pInterface);
+ noteDriver->NotifyTargetHide(this);
+ IFWL_Widget* child = widgetMgr->GetFirstChildWidget(this);
while (child) {
noteDriver->NotifyTargetHide(child);
NotifyHideChildWidget(widgetMgr, child, noteDriver);
@@ -328,20 +198,24 @@ void CFWL_WidgetImp::SetStates(uint32_t dwStates, FX_BOOL bSet) {
}
return;
}
-FWL_Error CFWL_WidgetImp::Update() {
+
+FWL_Error IFWL_Widget::Update() {
return FWL_Error::Succeeded;
}
-FWL_Error CFWL_WidgetImp::LockUpdate() {
+
+FWL_Error IFWL_Widget::LockUpdate() {
m_iLock++;
return FWL_Error::Succeeded;
}
-FWL_Error CFWL_WidgetImp::UnlockUpdate() {
+
+FWL_Error IFWL_Widget::UnlockUpdate() {
if (IsLocked()) {
m_iLock--;
}
return FWL_Error::Succeeded;
}
-FWL_WidgetHit CFWL_WidgetImp::HitTest(FX_FLOAT fx, FX_FLOAT fy) {
+
+FWL_WidgetHit IFWL_Widget::HitTest(FX_FLOAT fx, FX_FLOAT fy) {
CFX_RectF rtClient;
GetClientRect(rtClient);
if (rtClient.Contains(fx, fy))
@@ -360,15 +234,16 @@ FWL_WidgetHit CFWL_WidgetImp::HitTest(FX_FLOAT fx, FX_FLOAT fy) {
}
return FWL_WidgetHit::Unknown;
}
-FWL_Error CFWL_WidgetImp::TransformTo(IFWL_Widget* pWidget,
- FX_FLOAT& fx,
- FX_FLOAT& fy) {
+
+FWL_Error 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(m_pInterface);
+ szOffset = pWidget->GetOffsetFromParent(this);
szOffset.x = -szOffset.x;
szOffset.y = -szOffset.y;
}
@@ -386,7 +261,7 @@ FWL_Error CFWL_WidgetImp::TransformTo(IFWL_Widget* pWidget,
GetMatrix(m, TRUE);
m.TransformPoint(fx, fy);
}
- IFWL_Widget* form1 = m_pWidgetMgr->GetSystemFormWidget(m_pInterface);
+ IFWL_Widget* form1 = m_pWidgetMgr->GetSystemFormWidget(this);
if (!form1)
return FWL_Error::Indefinite;
if (!pWidget) {
@@ -419,10 +294,12 @@ FWL_Error CFWL_WidgetImp::TransformTo(IFWL_Widget* pWidget,
}
return FWL_Error::Succeeded;
}
-FWL_Error CFWL_WidgetImp::TransformTo(IFWL_Widget* pWidget, CFX_RectF& rt) {
+
+FWL_Error IFWL_Widget::TransformTo(IFWL_Widget* pWidget, CFX_RectF& rt) {
return TransformTo(pWidget, rt.left, rt.top);
}
-FWL_Error CFWL_WidgetImp::GetMatrix(CFX_Matrix& matrix, FX_BOOL bGlobal) {
+
+FWL_Error IFWL_Widget::GetMatrix(CFX_Matrix& matrix, FX_BOOL bGlobal) {
if (!m_pProperties)
return FWL_Error::Indefinite;
if (bGlobal) {
@@ -450,7 +327,8 @@ FWL_Error CFWL_WidgetImp::GetMatrix(CFX_Matrix& matrix, FX_BOOL bGlobal) {
}
return FWL_Error::Succeeded;
}
-FWL_Error CFWL_WidgetImp::SetMatrix(const CFX_Matrix& matrix) {
+
+FWL_Error IFWL_Widget::SetMatrix(const CFX_Matrix& matrix) {
if (!m_pProperties)
return FWL_Error::Indefinite;
IFWL_Widget* parent = GetParent();
@@ -460,19 +338,21 @@ FWL_Error CFWL_WidgetImp::SetMatrix(const CFX_Matrix& matrix) {
m_pProperties->m_ctmOnParent = matrix;
return FWL_Error::Succeeded;
}
-FWL_Error CFWL_WidgetImp::DrawWidget(CFX_Graphics* pGraphics,
- const CFX_Matrix* pMatrix) {
+
+FWL_Error IFWL_Widget::DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
return FWL_Error::Indefinite;
}
-IFWL_ThemeProvider* CFWL_WidgetImp::GetThemeProvider() {
+
+IFWL_ThemeProvider* IFWL_Widget::GetThemeProvider() {
return m_pProperties->m_pThemeProvider;
}
-FWL_Error CFWL_WidgetImp::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) {
+FWL_Error IFWL_Widget::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) {
m_pProperties->m_pThemeProvider = pThemeProvider;
return FWL_Error::Succeeded;
}
-IFWL_WidgetDelegate* CFWL_WidgetImp::SetDelegate(
- IFWL_WidgetDelegate* pDelegate) {
+
+IFWL_WidgetDelegate* IFWL_Widget::SetDelegate(IFWL_WidgetDelegate* pDelegate) {
if (!m_pCurDelegate) {
m_pCurDelegate = m_pDelegate;
}
@@ -483,52 +363,47 @@ IFWL_WidgetDelegate* CFWL_WidgetImp::SetDelegate(
m_pCurDelegate = pDelegate;
return pOldDelegate;
}
-IFWL_App* CFWL_WidgetImp::GetOwnerApp() const {
+
+IFWL_App* IFWL_Widget::GetOwnerApp() const {
return m_pOwnerApp;
}
-FWL_Error CFWL_WidgetImp::SetOwnerApp(IFWL_App* pOwnerApp) {
+
+FWL_Error IFWL_Widget::SetOwnerApp(IFWL_App* pOwnerApp) {
m_pOwnerApp = pOwnerApp;
return FWL_Error::Succeeded;
}
-IFWL_Widget* CFWL_WidgetImp::GetInterface() const {
- return m_pInterface;
-}
-void CFWL_WidgetImp::SetInterface(IFWL_Widget* pInterface) {
- m_pInterface = pInterface;
-}
-uint32_t CFWL_WidgetImp::GetEventKey() const {
+uint32_t IFWL_Widget::GetEventKey() const {
return m_nEventKey;
}
-void CFWL_WidgetImp::SetEventKey(uint32_t key) {
+void IFWL_Widget::SetEventKey(uint32_t key) {
m_nEventKey = key;
}
-void* CFWL_WidgetImp::GetLayoutItem() const {
+void* IFWL_Widget::GetLayoutItem() const {
return m_pLayoutItem;
}
-void CFWL_WidgetImp::SetLayoutItem(void* pItem) {
+void IFWL_Widget::SetLayoutItem(void* pItem) {
m_pLayoutItem = pItem;
}
-void* CFWL_WidgetImp::GetAssociateWidget() const {
+CFWL_Widget* IFWL_Widget::GetAssociateWidget() const {
return m_pAssociate;
}
-void CFWL_WidgetImp::SetAssociateWidget(void* pAssociate) {
+void IFWL_Widget::SetAssociateWidget(CFWL_Widget* pAssociate) {
m_pAssociate = pAssociate;
}
-CFWL_WidgetImp::CFWL_WidgetImp(const CFWL_WidgetImpProperties& properties,
- IFWL_Widget* pOuter)
+IFWL_Widget::IFWL_Widget(const CFWL_WidgetImpProperties& properties,
+ IFWL_Widget* pOuter)
: m_pWidgetMgr(CFWL_WidgetMgr::GetInstance()),
m_pProperties(new CFWL_WidgetImpProperties(properties)),
m_pDelegate(nullptr),
m_pCurDelegate(nullptr),
m_pOuter(pOuter),
- m_pInterface(nullptr),
m_pLayoutItem(nullptr),
m_pAssociate(nullptr),
m_iLock(0),
@@ -536,40 +411,50 @@ CFWL_WidgetImp::CFWL_WidgetImp(const CFWL_WidgetImpProperties& properties,
ASSERT(m_pWidgetMgr);
}
-CFWL_WidgetImp::~CFWL_WidgetImp() {}
+IFWL_Widget::~IFWL_Widget() {}
-FX_BOOL CFWL_WidgetImp::IsEnabled() const {
+FX_BOOL IFWL_Widget::IsEnabled() const {
return (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) == 0;
}
-FX_BOOL CFWL_WidgetImp::IsVisible() const {
+
+FX_BOOL IFWL_Widget::IsVisible() const {
return (m_pProperties->m_dwStates & FWL_WGTSTATE_Invisible) == 0;
}
-FX_BOOL CFWL_WidgetImp::IsActive() const {
+
+FX_BOOL IFWL_Widget::IsActive() const {
return (m_pProperties->m_dwStates & FWL_WGTSTATE_Deactivated) == 0;
}
-FX_BOOL CFWL_WidgetImp::IsOverLapper() const {
+
+FX_BOOL IFWL_Widget::IsOverLapper() const {
return (m_pProperties->m_dwStyles & FWL_WGTSTYLE_WindowTypeMask) ==
FWL_WGTSTYLE_OverLapper;
}
-FX_BOOL CFWL_WidgetImp::IsPopup() const {
+
+FX_BOOL IFWL_Widget::IsPopup() const {
return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Popup);
}
-FX_BOOL CFWL_WidgetImp::IsChild() const {
+
+FX_BOOL IFWL_Widget::IsChild() const {
return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Child);
}
-FX_BOOL CFWL_WidgetImp::IsLocked() const {
+
+FX_BOOL IFWL_Widget::IsLocked() const {
return m_iLock > 0;
}
-FX_BOOL CFWL_WidgetImp::IsOffscreen() const {
+
+FX_BOOL IFWL_Widget::IsOffscreen() const {
return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Offscreen);
}
-FX_BOOL CFWL_WidgetImp::HasBorder() const {
+
+FX_BOOL IFWL_Widget::HasBorder() const {
return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Border);
}
-FX_BOOL CFWL_WidgetImp::HasEdge() const {
+
+FX_BOOL IFWL_Widget::HasEdge() const {
return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_EdgeMask);
}
-void CFWL_WidgetImp::GetEdgeRect(CFX_RectF& rtEdge) {
+
+void IFWL_Widget::GetEdgeRect(CFX_RectF& rtEdge) {
rtEdge = m_pProperties->m_rtWidget;
rtEdge.left = rtEdge.top = 0;
if (HasBorder()) {
@@ -578,14 +463,16 @@ void CFWL_WidgetImp::GetEdgeRect(CFX_RectF& rtEdge) {
rtEdge.Deflate(fCX, fCY);
}
}
-FX_FLOAT CFWL_WidgetImp::GetBorderSize(FX_BOOL bCX) {
+
+FX_FLOAT IFWL_Widget::GetBorderSize(FX_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_WidgetImp::GetEdgeWidth() {
+
+FX_FLOAT IFWL_Widget::GetEdgeWidth() {
CFWL_WidgetCapacity dwCapacity = CFWL_WidgetCapacity::None;
switch (m_pProperties->m_dwStyles & FWL_WGTSTYLE_EdgeMask) {
case FWL_WGTSTYLE_EdgeFlat: {
@@ -607,23 +494,26 @@ FX_FLOAT CFWL_WidgetImp::GetEdgeWidth() {
}
return 0;
}
-void CFWL_WidgetImp::GetRelativeRect(CFX_RectF& rect) {
+
+void IFWL_Widget::GetRelativeRect(CFX_RectF& rect) {
rect = m_pProperties->m_rtWidget;
rect.left = rect.top = 0;
}
-void* CFWL_WidgetImp::GetThemeCapacity(CFWL_WidgetCapacity dwCapacity) {
+
+void* IFWL_Widget::GetThemeCapacity(CFWL_WidgetCapacity dwCapacity) {
IFWL_ThemeProvider* pTheme = GetAvailableTheme();
if (!pTheme)
return nullptr;
CFWL_ThemePart part;
- part.m_pWidget = m_pInterface;
+ part.m_pWidget = this;
return pTheme->GetCapacity(&part, dwCapacity);
}
-IFWL_ThemeProvider* CFWL_WidgetImp::GetAvailableTheme() {
+
+IFWL_ThemeProvider* IFWL_Widget::GetAvailableTheme() {
if (m_pProperties->m_pThemeProvider) {
return m_pProperties->m_pThemeProvider;
}
- IFWL_Widget* pUp = m_pInterface;
+ IFWL_Widget* pUp = this;
do {
pUp = (pUp->GetStyles() & FWL_WGTSTYLE_Popup)
? m_pWidgetMgr->GetOwnerWidget(pUp)
@@ -636,27 +526,30 @@ IFWL_ThemeProvider* CFWL_WidgetImp::GetAvailableTheme() {
} while (pUp);
return nullptr;
}
-CFWL_WidgetImp* CFWL_WidgetImp::GetRootOuter() {
+
+IFWL_Widget* IFWL_Widget::GetRootOuter() {
IFWL_Widget* pRet = m_pOuter;
if (!pRet)
return nullptr;
while (IFWL_Widget* pOuter = pRet->GetOuter()) {
pRet = pOuter;
}
- return static_cast<CFWL_WidgetImp*>(pRet->GetImpl());
+ return pRet;
}
+
#define FWL_WGT_CalcHeight 2048
#define FWL_WGT_CalcWidth 2048
#define FWL_WGT_CalcMultiLineDefWidth 120.0f
-CFX_SizeF CFWL_WidgetImp::CalcTextSize(const CFX_WideString& wsText,
- IFWL_ThemeProvider* pTheme,
- FX_BOOL bMultiLine,
- int32_t iLineWidth) {
+
+CFX_SizeF IFWL_Widget::CalcTextSize(const CFX_WideString& wsText,
+ IFWL_ThemeProvider* pTheme,
+ FX_BOOL bMultiLine,
+ int32_t iLineWidth) {
if (!pTheme)
return CFX_SizeF();
CFWL_ThemeText calPart;
- calPart.m_pWidget = m_pInterface;
+ calPart.m_pWidget = this;
calPart.m_wsText = wsText;
calPart.m_dwTTOStyles =
bMultiLine ? FDE_TTOSTYLE_LineWrap : FDE_TTOSTYLE_SingleLine;
@@ -670,19 +563,21 @@ CFX_SizeF CFWL_WidgetImp::CalcTextSize(const CFX_WideString& wsText,
pTheme->CalcTextRect(&calPart, rect);
return CFX_SizeF(rect.width, rect.height);
}
-void CFWL_WidgetImp::CalcTextRect(const CFX_WideString& wsText,
- IFWL_ThemeProvider* pTheme,
- uint32_t dwTTOStyles,
- int32_t iTTOAlign,
- CFX_RectF& rect) {
+
+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 = m_pInterface;
+ calPart.m_pWidget = this;
calPart.m_wsText = wsText;
calPart.m_dwTTOStyles = dwTTOStyles;
calPart.m_iTTOAlign = iTTOAlign;
pTheme->CalcTextRect(&calPart, rect);
}
-void CFWL_WidgetImp::SetFocus(FX_BOOL bFocus) {
+
+void IFWL_Widget::SetFocus(FX_BOOL bFocus) {
if (m_pWidgetMgr->IsFormDisabled())
return;
@@ -696,44 +591,45 @@ void CFWL_WidgetImp::SetFocus(FX_BOOL bFocus) {
return;
IFWL_Widget* curFocus = pDriver->GetFocus();
- if (bFocus && curFocus != m_pInterface) {
- pDriver->SetFocus(m_pInterface);
- } else if (!bFocus && curFocus == m_pInterface) {
+ if (bFocus && curFocus != this) {
+ pDriver->SetFocus(this);
+ } else if (!bFocus && curFocus == this) {
pDriver->SetFocus(nullptr);
}
}
-void CFWL_WidgetImp::SetGrab(FX_BOOL bSet) {
+
+void IFWL_Widget::SetGrab(FX_BOOL bSet) {
IFWL_App* pApp = GetOwnerApp();
if (!pApp)
return;
CFWL_NoteDriver* pDriver =
static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver());
- pDriver->SetGrab(m_pInterface, bSet);
+ pDriver->SetGrab(this, bSet);
}
-FX_BOOL CFWL_WidgetImp::GetPopupPos(FX_FLOAT fMinHeight,
- FX_FLOAT fMaxHeight,
- const CFX_RectF& rtAnchor,
- CFX_RectF& rtPopup) {
+FX_BOOL 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()) {
- return m_pWidgetMgr->GetAdapterPopupPos(m_pInterface, fMinHeight,
- fMaxHeight, rtAnchor, rtPopup);
+ return m_pWidgetMgr->GetAdapterPopupPos(this, fMinHeight, fMaxHeight,
+ rtAnchor, rtPopup);
}
return GetPopupPosComboBox(fMinHeight, fMaxHeight, rtAnchor, rtPopup);
}
if (GetClassID() == FWL_Type::DateTimePicker &&
m_pWidgetMgr->IsFormDisabled()) {
- return m_pWidgetMgr->GetAdapterPopupPos(m_pInterface, fMinHeight,
- fMaxHeight, rtAnchor, rtPopup);
+ return m_pWidgetMgr->GetAdapterPopupPos(this, fMinHeight, fMaxHeight,
+ rtAnchor, rtPopup);
}
return GetPopupPosGeneral(fMinHeight, fMaxHeight, rtAnchor, rtPopup);
}
-FX_BOOL CFWL_WidgetImp::GetPopupPosMenu(FX_FLOAT fMinHeight,
- FX_FLOAT fMaxHeight,
- const CFX_RectF& rtAnchor,
- CFX_RectF& rtPopup) {
+FX_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;
FX_FLOAT fScreenWidth = 0;
@@ -764,10 +660,11 @@ FX_BOOL CFWL_WidgetImp::GetPopupPosMenu(FX_FLOAT fMinHeight,
rtPopup.Offset(fx, fy);
return TRUE;
}
-FX_BOOL CFWL_WidgetImp::GetPopupPosComboBox(FX_FLOAT fMinHeight,
- FX_FLOAT fMaxHeight,
- const CFX_RectF& rtAnchor,
- CFX_RectF& rtPopup) {
+
+FX_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 fScreenWidth = 0;
@@ -790,10 +687,11 @@ FX_BOOL CFWL_WidgetImp::GetPopupPosComboBox(FX_FLOAT fMinHeight,
rtPopup.Offset(fx, fy);
return TRUE;
}
-FX_BOOL CFWL_WidgetImp::GetPopupPosGeneral(FX_FLOAT fMinHeight,
- FX_FLOAT fMaxHeight,
- const CFX_RectF& rtAnchor,
- CFX_RectF& rtPopup) {
+
+FX_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;
FX_FLOAT fScreenWidth = 0;
@@ -810,11 +708,13 @@ FX_BOOL CFWL_WidgetImp::GetPopupPosGeneral(FX_FLOAT fMinHeight,
rtPopup.Offset(fx, fy);
return TRUE;
}
-FX_BOOL CFWL_WidgetImp::GetScreenSize(FX_FLOAT& fx, FX_FLOAT& fy) {
+
+FX_BOOL IFWL_Widget::GetScreenSize(FX_FLOAT& fx, FX_FLOAT& fy) {
return FALSE;
}
-void CFWL_WidgetImp::RegisterEventTarget(IFWL_Widget* pEventSource,
- uint32_t dwFilter) {
+
+void IFWL_Widget::RegisterEventTarget(IFWL_Widget* pEventSource,
+ uint32_t dwFilter) {
IFWL_App* pApp = GetOwnerApp();
if (!pApp)
return;
@@ -823,9 +723,10 @@ void CFWL_WidgetImp::RegisterEventTarget(IFWL_Widget* pEventSource,
if (!pNoteDriver)
return;
- pNoteDriver->RegisterEventTarget(m_pInterface, pEventSource, dwFilter);
+ pNoteDriver->RegisterEventTarget(this, pEventSource, dwFilter);
}
-void CFWL_WidgetImp::UnregisterEventTarget() {
+
+void IFWL_Widget::UnregisterEventTarget() {
IFWL_App* pApp = GetOwnerApp();
if (!pApp)
return;
@@ -834,20 +735,22 @@ void CFWL_WidgetImp::UnregisterEventTarget() {
if (!pNoteDriver)
return;
- pNoteDriver->UnregisterEventTarget(m_pInterface);
+ pNoteDriver->UnregisterEventTarget(this);
}
-void CFWL_WidgetImp::DispatchKeyEvent(CFWL_MsgKey* pNote) {
+
+void IFWL_Widget::DispatchKeyEvent(CFWL_MsgKey* pNote) {
if (!pNote)
return;
CFWL_EvtKey* pEvent = new CFWL_EvtKey;
- pEvent->m_pSrcTarget = m_pInterface;
+ pEvent->m_pSrcTarget = this;
pEvent->m_dwCmd = pNote->m_dwCmd;
pEvent->m_dwKeyCode = pNote->m_dwKeyCode;
pEvent->m_dwFlags = pNote->m_dwFlags;
DispatchEvent(pEvent);
pEvent->Release();
}
-void CFWL_WidgetImp::DispatchEvent(CFWL_Event* pEvent) {
+
+void IFWL_Widget::DispatchEvent(CFWL_Event* pEvent) {
if (m_pOuter) {
IFWL_WidgetDelegate* pDelegate = m_pOuter->SetDelegate(nullptr);
pDelegate->OnProcessEvent(pEvent);
@@ -861,24 +764,26 @@ void CFWL_WidgetImp::DispatchEvent(CFWL_Event* pEvent) {
return;
pNoteDriver->SendEvent(pEvent);
}
-void CFWL_WidgetImp::Repaint(const CFX_RectF* pRect) {
+
+void IFWL_Widget::Repaint(const CFX_RectF* pRect) {
if (pRect) {
- m_pWidgetMgr->RepaintWidget(m_pInterface, pRect);
+ m_pWidgetMgr->RepaintWidget(this, pRect);
return;
}
CFX_RectF rect;
rect = m_pProperties->m_rtWidget;
rect.left = rect.top = 0;
- m_pWidgetMgr->RepaintWidget(m_pInterface, &rect);
+ m_pWidgetMgr->RepaintWidget(this, &rect);
}
-void CFWL_WidgetImp::DrawBackground(CFX_Graphics* pGraphics,
- CFWL_Part iPartBk,
- IFWL_ThemeProvider* pTheme,
- const CFX_Matrix* pMatrix) {
+
+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 = m_pInterface;
+ param.m_pWidget = this;
param.m_iPart = iPartBk;
param.m_pGraphics = pGraphics;
if (pMatrix) {
@@ -887,14 +792,15 @@ void CFWL_WidgetImp::DrawBackground(CFX_Graphics* pGraphics,
param.m_rtPart = rtRelative;
pTheme->DrawBackground(&param);
}
-void CFWL_WidgetImp::DrawBorder(CFX_Graphics* pGraphics,
- CFWL_Part iPartBorder,
- IFWL_ThemeProvider* pTheme,
- const CFX_Matrix* pMatrix) {
+
+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 = m_pInterface;
+ param.m_pWidget = this;
param.m_iPart = iPartBorder;
param.m_pGraphics = pGraphics;
if (pMatrix) {
@@ -903,14 +809,15 @@ void CFWL_WidgetImp::DrawBorder(CFX_Graphics* pGraphics,
param.m_rtPart = rtRelative;
pTheme->DrawBackground(&param);
}
-void CFWL_WidgetImp::DrawEdge(CFX_Graphics* pGraphics,
- CFWL_Part iPartEdge,
- IFWL_ThemeProvider* pTheme,
- const CFX_Matrix* pMatrix) {
+
+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 = m_pInterface;
+ param.m_pWidget = this;
param.m_iPart = iPartEdge;
param.m_pGraphics = pGraphics;
if (pMatrix) {
@@ -919,7 +826,8 @@ void CFWL_WidgetImp::DrawEdge(CFX_Graphics* pGraphics,
param.m_rtPart = rtEdge;
pTheme->DrawBackground(&param);
}
-void CFWL_WidgetImp::NotifyDriver() {
+
+void IFWL_Widget::NotifyDriver() {
IFWL_App* pApp = GetOwnerApp();
if (!pApp)
return;
@@ -929,10 +837,11 @@ void CFWL_WidgetImp::NotifyDriver() {
if (!pDriver)
return;
- pDriver->NotifyTargetDestroy(m_pInterface);
+ pDriver->NotifyTargetDestroy(this);
}
-CFX_SizeF CFWL_WidgetImp::GetOffsetFromParent(IFWL_Widget* pParent) {
- if (pParent == GetInterface())
+
+CFX_SizeF IFWL_Widget::GetOffsetFromParent(IFWL_Widget* pParent) {
+ if (pParent == this)
return CFX_SizeF();
CFWL_WidgetMgr* pWidgetMgr = CFWL_WidgetMgr::GetInstance();
@@ -951,7 +860,8 @@ CFX_SizeF CFWL_WidgetImp::GetOffsetFromParent(IFWL_Widget* pParent) {
}
return szRet;
}
-FX_BOOL CFWL_WidgetImp::IsParent(IFWL_Widget* pParent) {
+
+FX_BOOL IFWL_Widget::IsParent(IFWL_Widget* pParent) {
IFWL_Widget* pUpWidget = GetParent();
while (pUpWidget) {
if (pUpWidget == pParent)
@@ -967,15 +877,14 @@ void CFWL_WidgetImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
if (!pMessage->m_pDstTarget)
return;
- CFWL_WidgetImp* pWidget =
- static_cast<CFWL_WidgetImp*>(pMessage->m_pDstTarget->GetImpl());
+ 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->m_pInterface;
- evt.m_pDstTarget = pWidget->m_pInterface;
+ 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;
@@ -987,8 +896,8 @@ void CFWL_WidgetImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
CFWL_MsgMouseWheel* pMsgMouseWheel =
static_cast<CFWL_MsgMouseWheel*>(pMessage);
CFWL_EvtMouseWheel evt;
- evt.m_pSrcTarget = pWidget->m_pInterface;
- evt.m_pDstTarget = pWidget->m_pInterface;
+ 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;
@@ -1000,8 +909,8 @@ void CFWL_WidgetImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
case CFWL_MessageType::Key: {
CFWL_MsgKey* pMsgKey = static_cast<CFWL_MsgKey*>(pMessage);
CFWL_EvtKey evt;
- evt.m_pSrcTarget = pWidget->m_pInterface;
- evt.m_pDstTarget = pWidget->m_pInterface;
+ 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;
@@ -1013,7 +922,7 @@ void CFWL_WidgetImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
CFWL_EvtSetFocus evt;
evt.m_pSrcTarget = pMsgSetFocus->m_pDstTarget;
evt.m_pDstTarget = pMsgSetFocus->m_pDstTarget;
- evt.m_pSetFocus = pWidget->m_pInterface;
+ evt.m_pSetFocus = pWidget;
pWidget->DispatchEvent(&evt);
break;
}
@@ -1023,7 +932,7 @@ void CFWL_WidgetImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
CFWL_EvtKillFocus evt;
evt.m_pSrcTarget = pMsgKillFocus->m_pDstTarget;
evt.m_pDstTarget = pMsgKillFocus->m_pDstTarget;
- evt.m_pKillFocus = pWidget->m_pInterface;
+ evt.m_pKillFocus = pWidget;
pWidget->DispatchEvent(&evt);
break;
}
diff --git a/xfa/fwl/core/ifwl_widget.h b/xfa/fwl/core/ifwl_widget.h
index 6d7d53c400..9db7a0505a 100644
--- a/xfa/fwl/core/ifwl_widget.h
+++ b/xfa/fwl/core/ifwl_widget.h
@@ -9,22 +9,24 @@
#include <memory>
-#include "core/fxcrt/fx_basic.h"
#include "core/fxcrt/fx_coordinates.h"
#include "core/fxcrt/fx_system.h"
-#include "xfa/fwl/core/fwl_error.h"
-#include "xfa/fwl/core/fwl_widgetimp.h"
+#include "xfa/fwl/core/cfwl_event.h"
+#include "xfa/fwl/core/cfwl_themepart.h"
+#include "xfa/fwl/core/fwl_widgethit.h"
+#include "xfa/fwl/core/ifwl_widgetdelegate.h"
+#include "xfa/fwl/theme/cfwl_widgettp.h"
-// FWL contains three parallel inheritance hierarchies, which reference each
+// FWL contains two parallel inheritance hierarchies, which reference each
// other via pointers as follows:
//
-// m_pAssociate
-// <----------------------------------
-// CFWL_Widget ----------> IFWL_Widget ----------> CFWL_WidgetImp
-// | m_pIface | m_pImpl |
-// A A A
-// | | |
-// CFWL_... IFWL_... CFWL_...Imp
+// m_pAssociate
+// <----------
+// CFWL_Widget ----------> IFWL_Widget
+// | m_pIface |
+// A A
+// | |
+// CFWL_... IFWL_...
//
// TODO(tsepez): Collapse these into a single hierarchy.
//
@@ -49,73 +51,165 @@ enum class FWL_Type {
ToolTip
};
-class CFWL_WidgetImp;
-class CFX_Graphics;
+class CFWL_AppImp;
+class CFWL_MsgKey;
+class CFWL_Widget;
+class CFWL_WidgetImpProperties;
+class CFWL_WidgetMgr;
class IFWL_App;
class IFWL_DataProvider;
-class IFWL_Form;
class IFWL_ThemeProvider;
-class IFWL_WidgetDelegate;
+class IFWL_Widget;
+enum class FWL_Type;
class IFWL_Widget {
public:
- IFWL_Widget();
virtual ~IFWL_Widget();
- FWL_Error GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize = FALSE);
- FWL_Error GetGlobalRect(CFX_RectF& rect);
- FWL_Error SetWidgetRect(const CFX_RectF& rect);
- FWL_Error GetClientRect(CFX_RectF& rect);
- IFWL_Widget* GetParent();
- FWL_Error SetParent(IFWL_Widget* pParent);
- IFWL_Widget* GetOwner();
- FWL_Error SetOwner(IFWL_Widget* pOwner);
- IFWL_Widget* GetOuter();
- uint32_t GetStyles();
- FWL_Error ModifyStyles(uint32_t dwStylesAdded, uint32_t dwStylesRemoved);
- uint32_t GetStylesEx();
- FWL_Error ModifyStylesEx(uint32_t dwStylesExAdded,
- uint32_t dwStylesExRemoved);
- uint32_t GetStates();
- void SetStates(uint32_t dwStates, FX_BOOL bSet = TRUE);
+ virtual FWL_Error Initialize();
+ virtual FWL_Error Finalize();
+ virtual FWL_Error GetClassName(CFX_WideString& wsClass) const;
+ virtual FWL_Type GetClassID() const = 0;
+ virtual FX_BOOL IsInstance(const CFX_WideStringC& wsClass) const;
+
+ virtual FWL_Error GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize = FALSE);
+ virtual FWL_Error GetGlobalRect(CFX_RectF& rect);
+ virtual FWL_Error SetWidgetRect(const CFX_RectF& rect);
+ virtual FWL_Error GetClientRect(CFX_RectF& rect);
+ virtual IFWL_Widget* GetParent();
+ virtual FWL_Error SetParent(IFWL_Widget* pParent);
+ virtual IFWL_Widget* GetOwner();
+ virtual FWL_Error SetOwner(IFWL_Widget* pOwner);
+ virtual IFWL_Widget* GetOuter();
+ virtual uint32_t GetStyles();
+ virtual FWL_Error ModifyStyles(uint32_t dwStylesAdded,
+ uint32_t dwStylesRemoved);
+ virtual uint32_t GetStylesEx();
+ virtual FWL_Error ModifyStylesEx(uint32_t dwStylesExAdded,
+ uint32_t dwStylesExRemoved);
+ virtual uint32_t GetStates();
+ virtual void SetStates(uint32_t dwStates, FX_BOOL bSet = TRUE);
+ virtual FWL_Error Update();
+ virtual FWL_Error LockUpdate();
+ virtual FWL_Error UnlockUpdate();
+ virtual FWL_WidgetHit HitTest(FX_FLOAT fx, FX_FLOAT fy);
+ virtual FWL_Error TransformTo(IFWL_Widget* pWidget,
+ FX_FLOAT& fx,
+ FX_FLOAT& fy);
+ virtual FWL_Error TransformTo(IFWL_Widget* pWidget, CFX_RectF& rt);
+ virtual FWL_Error GetMatrix(CFX_Matrix& matrix, FX_BOOL bGlobal = FALSE);
+ virtual FWL_Error SetMatrix(const CFX_Matrix& matrix);
+ virtual FWL_Error DrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr);
+ virtual IFWL_ThemeProvider* GetThemeProvider();
+ virtual FWL_Error SetThemeProvider(IFWL_ThemeProvider* pThemeProvider);
+ virtual IFWL_WidgetDelegate* SetDelegate(IFWL_WidgetDelegate* pDelegate);
+ virtual IFWL_App* GetOwnerApp() const;
+
+ FWL_Error SetOwnerApp(IFWL_App* pOwnerApp);
+ CFX_SizeF GetOffsetFromParent(IFWL_Widget* pParent);
+
uint32_t GetEventKey() const;
void SetEventKey(uint32_t key);
+
void* GetLayoutItem() const;
void SetLayoutItem(void* pItem);
- void* GetAssociateWidget() const;
- void SetAssociateWidget(void* pAssociate);
- FWL_Error Update();
- FWL_Error LockUpdate();
- FWL_Error UnlockUpdate();
- FWL_WidgetHit HitTest(FX_FLOAT fx, FX_FLOAT fy);
- FWL_Error TransformTo(IFWL_Widget* pWidget, FX_FLOAT& fx, FX_FLOAT& fy);
- FWL_Error TransformTo(IFWL_Widget* pWidget, CFX_RectF& rt);
- FWL_Error GetMatrix(CFX_Matrix& matrix, FX_BOOL bGlobal = FALSE);
- FWL_Error SetMatrix(const CFX_Matrix& matrix);
- FWL_Error DrawWidget(CFX_Graphics* pGraphics,
- const CFX_Matrix* pMatrix = nullptr);
- IFWL_ThemeProvider* GetThemeProvider();
- FWL_Error SetThemeProvider(IFWL_ThemeProvider* pThemeProvider);
- IFWL_WidgetDelegate* SetDelegate(IFWL_WidgetDelegate* pDelegate);
- IFWL_App* GetOwnerApp() const;
- CFX_SizeF GetOffsetFromParent(IFWL_Widget* pParent);
-
- // These call into equivalent polymorphic methods of m_pImpl. There
- // should be no need to override these in subclasses.
- FWL_Error GetClassName(CFX_WideString& wsClass) const;
- FWL_Type GetClassID() const;
- FX_BOOL IsInstance(const CFX_WideStringC& wsClass) const;
- FWL_Error Initialize();
- FWL_Error Finalize();
- CFWL_WidgetImp* GetImpl() const { return m_pImpl.get(); }
+ CFWL_Widget* GetAssociateWidget() const;
+ void SetAssociateWidget(CFWL_Widget* pAssociate);
protected:
- // Takes ownership of |pImpl|.
- void SetImpl(CFWL_WidgetImp* pImpl) { m_pImpl.reset(pImpl); }
+ friend class CFWL_WidgetImpDelegate;
- private:
- std::unique_ptr<CFWL_WidgetImp> m_pImpl;
+ IFWL_Widget(const CFWL_WidgetImpProperties& properties, IFWL_Widget* pOuter);
+
+ FX_BOOL IsEnabled() const;
+ FX_BOOL IsVisible() const;
+ FX_BOOL IsActive() const;
+ FX_BOOL IsOverLapper() const;
+ FX_BOOL IsPopup() const;
+ FX_BOOL IsChild() const;
+ FX_BOOL IsLocked() const;
+ FX_BOOL IsOffscreen() const;
+ FX_BOOL HasBorder() const;
+ FX_BOOL HasEdge() const;
+ void GetEdgeRect(CFX_RectF& rtEdge);
+ FX_FLOAT GetBorderSize(FX_BOOL bCX = TRUE);
+ FX_FLOAT GetEdgeWidth();
+ void GetRelativeRect(CFX_RectF& rect);
+ void* GetThemeCapacity(CFWL_WidgetCapacity dwCapacity);
+ IFWL_ThemeProvider* GetAvailableTheme();
+ IFWL_Widget* GetRootOuter();
+ CFX_SizeF CalcTextSize(const CFX_WideString& wsText,
+ IFWL_ThemeProvider* pTheme,
+ FX_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 SetFocus(FX_BOOL bFocus);
+ void SetGrab(FX_BOOL bSet);
+ FX_BOOL GetPopupPos(FX_FLOAT fMinHeight,
+ FX_FLOAT fMaxHeight,
+ const CFX_RectF& rtAnchor,
+ CFX_RectF& rtPopup);
+ FX_BOOL GetPopupPosMenu(FX_FLOAT fMinHeight,
+ FX_FLOAT fMaxHeight,
+ const CFX_RectF& rtAnchor,
+ CFX_RectF& rtPopup);
+ FX_BOOL GetPopupPosComboBox(FX_FLOAT fMinHeight,
+ FX_FLOAT fMaxHeight,
+ const CFX_RectF& rtAnchor,
+ CFX_RectF& rtPopup);
+ FX_BOOL GetPopupPosGeneral(FX_FLOAT fMinHeight,
+ FX_FLOAT fMaxHeight,
+ const CFX_RectF& rtAnchor,
+ CFX_RectF& rtPopup);
+ FX_BOOL GetScreenSize(FX_FLOAT& fx, FX_FLOAT& fy);
+ void RegisterEventTarget(IFWL_Widget* pEventSource = nullptr,
+ uint32_t dwFilter = FWL_EVENT_ALL_MASK);
+ void UnregisterEventTarget();
+ void DispatchKeyEvent(CFWL_MsgKey* pNote);
+ void DispatchEvent(CFWL_Event* pEvent);
+ void Repaint(const CFX_RectF* pRect = nullptr);
+ void DrawBackground(CFX_Graphics* pGraphics,
+ CFWL_Part iPartBk,
+ IFWL_ThemeProvider* pTheme,
+ const CFX_Matrix* pMatrix = nullptr);
+ 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);
+ void NotifyDriver();
+
+ FX_BOOL IsParent(IFWL_Widget* pParent);
+
+ CFWL_WidgetMgr* const m_pWidgetMgr;
+ IFWL_App* m_pOwnerApp;
+ std::unique_ptr<CFWL_WidgetImpProperties> m_pProperties;
+ IFWL_WidgetDelegate* m_pDelegate;
+ IFWL_WidgetDelegate* m_pCurDelegate;
+ IFWL_Widget* m_pOuter;
+ void* m_pLayoutItem;
+ CFWL_Widget* m_pAssociate;
+ int32_t m_iLock;
+ uint32_t m_nEventKey;
+};
+
+class CFWL_WidgetImpDelegate : public IFWL_WidgetDelegate {
+ public:
+ CFWL_WidgetImpDelegate();
+ ~CFWL_WidgetImpDelegate() override {}
+ void OnProcessMessage(CFWL_Message* pMessage) override;
+ void OnProcessEvent(CFWL_Event* pEvent) override;
+ void OnDrawWidget(CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix = nullptr) override;
};
#endif // XFA_FWL_CORE_IFWL_WIDGET_H_