summaryrefslogtreecommitdiff
path: root/xfa/fxfa/cxfa_ffcheckbutton.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xfa/fxfa/cxfa_ffcheckbutton.cpp')
-rw-r--r--xfa/fxfa/cxfa_ffcheckbutton.cpp345
1 files changed, 345 insertions, 0 deletions
diff --git a/xfa/fxfa/cxfa_ffcheckbutton.cpp b/xfa/fxfa/cxfa_ffcheckbutton.cpp
new file mode 100644
index 0000000000..c1dae57df8
--- /dev/null
+++ b/xfa/fxfa/cxfa_ffcheckbutton.cpp
@@ -0,0 +1,345 @@
+// 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/fxfa/cxfa_ffcheckbutton.h"
+
+#include <utility>
+#include "third_party/base/ptr_util.h"
+#include "xfa/fwl/cfwl_checkbox.h"
+#include "xfa/fwl/cfwl_messagemouse.h"
+#include "xfa/fwl/cfwl_notedriver.h"
+#include "xfa/fwl/cfwl_widgetmgr.h"
+#include "xfa/fxfa/cxfa_ffapp.h"
+#include "xfa/fxfa/cxfa_ffdoc.h"
+#include "xfa/fxfa/cxfa_ffdocview.h"
+#include "xfa/fxfa/cxfa_ffexclgroup.h"
+#include "xfa/fxfa/cxfa_fffield.h"
+#include "xfa/fxfa/cxfa_ffpageview.h"
+#include "xfa/fxfa/cxfa_ffwidget.h"
+
+CXFA_FFCheckButton::CXFA_FFCheckButton(CXFA_WidgetAcc* pDataAcc)
+ : CXFA_FFField(pDataAcc), m_pOldDelegate(nullptr) {}
+
+CXFA_FFCheckButton::~CXFA_FFCheckButton() {}
+
+bool CXFA_FFCheckButton::LoadWidget() {
+ auto pNew = pdfium::MakeUnique<CFWL_CheckBox>(GetFWLApp());
+ CFWL_CheckBox* pCheckBox = pNew.get();
+ m_pNormalWidget = std::move(pNew);
+ m_pNormalWidget->SetLayoutItem(this);
+
+ CFWL_NoteDriver* pNoteDriver =
+ m_pNormalWidget->GetOwnerApp()->GetNoteDriver();
+ pNoteDriver->RegisterEventTarget(m_pNormalWidget.get(),
+ m_pNormalWidget.get());
+ m_pOldDelegate = m_pNormalWidget->GetDelegate();
+ m_pNormalWidget->SetDelegate(this);
+ if (m_pDataAcc->IsRadioButton())
+ pCheckBox->ModifyStylesEx(FWL_STYLEEXT_CKB_RadioButton, 0xFFFFFFFF);
+
+ m_pNormalWidget->LockUpdate();
+ UpdateWidgetProperty();
+ SetFWLCheckState(m_pDataAcc->GetCheckState());
+ m_pNormalWidget->UnlockUpdate();
+ return CXFA_FFField::LoadWidget();
+}
+
+void CXFA_FFCheckButton::UpdateWidgetProperty() {
+ auto* pCheckBox = static_cast<CFWL_CheckBox*>(m_pNormalWidget.get());
+ if (!pCheckBox)
+ return;
+
+ pCheckBox->SetBoxSize(m_pDataAcc->GetCheckButtonSize());
+ uint32_t dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCross;
+ int32_t iCheckMark = m_pDataAcc->GetCheckButtonMark();
+ switch (iCheckMark) {
+ case XFA_ATTRIBUTEENUM_Check:
+ dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCheck;
+ break;
+ case XFA_ATTRIBUTEENUM_Circle:
+ dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCircle;
+ break;
+ case XFA_ATTRIBUTEENUM_Cross:
+ break;
+ case XFA_ATTRIBUTEENUM_Diamond:
+ dwStyleEx = FWL_STYLEEXT_CKB_SignShapeDiamond;
+ break;
+ case XFA_ATTRIBUTEENUM_Square:
+ dwStyleEx = FWL_STYLEEXT_CKB_SignShapeSquare;
+ break;
+ case XFA_ATTRIBUTEENUM_Star:
+ dwStyleEx = FWL_STYLEEXT_CKB_SignShapeStar;
+ break;
+ default: {
+ int32_t iShape = m_pDataAcc->GetCheckButtonShape();
+ if (iShape == XFA_ATTRIBUTEENUM_Round) {
+ dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCircle;
+ }
+ } break;
+ }
+ if (m_pDataAcc->IsAllowNeutral())
+ dwStyleEx |= FWL_STYLEEXT_CKB_3State;
+
+ pCheckBox->ModifyStylesEx(
+ dwStyleEx, FWL_STYLEEXT_CKB_SignShapeMask | FWL_STYLEEXT_CKB_3State);
+}
+
+bool CXFA_FFCheckButton::PerformLayout() {
+ CXFA_FFWidget::PerformLayout();
+
+ float fCheckSize = m_pDataAcc->GetCheckButtonSize();
+ CXFA_Margin mgWidget = m_pDataAcc->GetMargin();
+ CFX_RectF rtWidget = GetRectWithoutRotate();
+ if (mgWidget)
+ XFA_RectWidthoutMargin(rtWidget, mgWidget);
+
+ int32_t iCapPlacement = -1;
+ float fCapReserve = 0;
+ CXFA_Caption caption = m_pDataAcc->GetCaption();
+ if (caption && caption.GetPresence()) {
+ m_rtCaption = rtWidget;
+ iCapPlacement = caption.GetPlacementType();
+ fCapReserve = caption.GetReserve();
+ if (fCapReserve <= 0) {
+ if (iCapPlacement == XFA_ATTRIBUTEENUM_Top ||
+ iCapPlacement == XFA_ATTRIBUTEENUM_Bottom) {
+ fCapReserve = rtWidget.height - fCheckSize;
+ } else {
+ fCapReserve = rtWidget.width - fCheckSize;
+ }
+ }
+ }
+
+ int32_t iHorzAlign = XFA_ATTRIBUTEENUM_Left;
+ int32_t iVertAlign = XFA_ATTRIBUTEENUM_Top;
+ if (CXFA_Para para = m_pDataAcc->GetPara()) {
+ iHorzAlign = para.GetHorizontalAlign();
+ iVertAlign = para.GetVerticalAlign();
+ }
+
+ m_rtUI = rtWidget;
+ CXFA_Margin mgCap = caption.GetMargin();
+ switch (iCapPlacement) {
+ case XFA_ATTRIBUTEENUM_Left: {
+ m_rtCaption.width = fCapReserve;
+ CapLeftRightPlacement(mgCap);
+ m_rtUI.width -= fCapReserve;
+ m_rtUI.left += fCapReserve;
+ break;
+ }
+ case XFA_ATTRIBUTEENUM_Top: {
+ m_rtCaption.height = fCapReserve;
+ XFA_RectWidthoutMargin(m_rtCaption, mgCap);
+ m_rtUI.height -= fCapReserve;
+ m_rtUI.top += fCapReserve;
+ break;
+ }
+ case XFA_ATTRIBUTEENUM_Right: {
+ m_rtCaption.left = m_rtCaption.right() - fCapReserve;
+ m_rtCaption.width = fCapReserve;
+ CapLeftRightPlacement(mgCap);
+ m_rtUI.width -= fCapReserve;
+ break;
+ }
+ case XFA_ATTRIBUTEENUM_Bottom: {
+ m_rtCaption.top = m_rtCaption.bottom() - fCapReserve;
+ m_rtCaption.height = fCapReserve;
+ XFA_RectWidthoutMargin(m_rtCaption, mgCap);
+ m_rtUI.height -= fCapReserve;
+ break;
+ }
+ case XFA_ATTRIBUTEENUM_Inline:
+ break;
+ default:
+ iHorzAlign = XFA_ATTRIBUTEENUM_Right;
+ break;
+ }
+
+ if (iHorzAlign == XFA_ATTRIBUTEENUM_Center)
+ m_rtUI.left += (m_rtUI.width - fCheckSize) / 2;
+ else if (iHorzAlign == XFA_ATTRIBUTEENUM_Right)
+ m_rtUI.left = m_rtUI.right() - fCheckSize;
+
+ if (iVertAlign == XFA_ATTRIBUTEENUM_Middle)
+ m_rtUI.top += (m_rtUI.height - fCheckSize) / 2;
+ else if (iVertAlign == XFA_ATTRIBUTEENUM_Bottom)
+ m_rtUI.top = m_rtUI.bottom() - fCheckSize;
+
+ m_rtUI.width = fCheckSize;
+ m_rtUI.height = fCheckSize;
+ AddUIMargin(iCapPlacement);
+ m_rtCheckBox = m_rtUI;
+ CXFA_Border borderUI = m_pDataAcc->GetUIBorder();
+ if (borderUI) {
+ CXFA_Margin margin = borderUI.GetMargin();
+ if (margin)
+ XFA_RectWidthoutMargin(m_rtUI, margin);
+ }
+
+ m_rtUI.Normalize();
+ LayoutCaption();
+ SetFWLRect();
+ if (m_pNormalWidget)
+ m_pNormalWidget->Update();
+
+ return true;
+}
+
+void CXFA_FFCheckButton::CapLeftRightPlacement(CXFA_Margin mgCap) {
+ XFA_RectWidthoutMargin(m_rtCaption, mgCap);
+ if (m_rtCaption.height < 0)
+ m_rtCaption.top += m_rtCaption.height;
+ if (m_rtCaption.width < 0) {
+ m_rtCaption.left += m_rtCaption.width;
+ m_rtCaption.width = -m_rtCaption.width;
+ }
+}
+
+void CXFA_FFCheckButton::AddUIMargin(int32_t iCapPlacement) {
+ CFX_RectF rtUIMargin = m_pDataAcc->GetUIMargin();
+ m_rtUI.top -= rtUIMargin.top / 2 - rtUIMargin.height / 2;
+
+ float fLeftAddRight = rtUIMargin.left + rtUIMargin.width;
+ float fTopAddBottom = rtUIMargin.top + rtUIMargin.height;
+ if (m_rtUI.width < fLeftAddRight) {
+ if (iCapPlacement == XFA_ATTRIBUTEENUM_Right ||
+ iCapPlacement == XFA_ATTRIBUTEENUM_Left) {
+ m_rtUI.left -= fLeftAddRight - m_rtUI.width;
+ } else {
+ m_rtUI.left -= 2 * (fLeftAddRight - m_rtUI.width);
+ }
+ m_rtUI.width += 2 * (fLeftAddRight - m_rtUI.width);
+ }
+ if (m_rtUI.height < fTopAddBottom) {
+ if (iCapPlacement == XFA_ATTRIBUTEENUM_Right)
+ m_rtUI.left -= fTopAddBottom - m_rtUI.height;
+
+ m_rtUI.top -= fTopAddBottom - m_rtUI.height;
+ m_rtUI.height += 2 * (fTopAddBottom - m_rtUI.height);
+ }
+}
+
+void CXFA_FFCheckButton::RenderWidget(CXFA_Graphics* pGS,
+ CFX_Matrix* pMatrix,
+ uint32_t dwStatus) {
+ if (!IsMatchVisibleStatus(dwStatus))
+ return;
+
+ CFX_Matrix mtRotate = GetRotateMatrix();
+ if (pMatrix)
+ mtRotate.Concat(*pMatrix);
+
+ CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
+ CXFA_Border borderUI = m_pDataAcc->GetUIBorder();
+ DrawBorder(pGS, borderUI, m_rtUI, &mtRotate,
+ m_pDataAcc->GetCheckButtonShape() == XFA_ATTRIBUTEENUM_Round
+ ? XFA_DRAWBOX_ForceRound
+ : 0);
+ RenderCaption(pGS, &mtRotate);
+ DrawHighlight(pGS, &mtRotate, dwStatus,
+ m_pDataAcc->GetCheckButtonShape() == XFA_ATTRIBUTEENUM_Round);
+ CFX_Matrix mt(1, 0, 0, 1, m_rtCheckBox.left, m_rtCheckBox.top);
+ mt.Concat(mtRotate);
+ GetApp()->GetWidgetMgrDelegate()->OnDrawWidget(m_pNormalWidget.get(), pGS,
+ &mt);
+}
+
+bool CXFA_FFCheckButton::OnLButtonUp(uint32_t dwFlags,
+ const CFX_PointF& point) {
+ if (!m_pNormalWidget || !IsButtonDown())
+ return false;
+
+ SetButtonDown(false);
+ CFWL_MessageMouse ms(nullptr, m_pNormalWidget.get());
+ ms.m_dwCmd = FWL_MouseCommand::LeftButtonUp;
+ ms.m_dwFlags = dwFlags;
+ ms.m_pos = FWLToClient(point);
+ TranslateFWLMessage(&ms);
+ return true;
+}
+
+XFA_CHECKSTATE CXFA_FFCheckButton::FWLState2XFAState() {
+ uint32_t dwState = m_pNormalWidget->GetStates();
+ if (dwState & FWL_STATE_CKB_Checked)
+ return XFA_CHECKSTATE_On;
+ if (dwState & FWL_STATE_CKB_Neutral)
+ return XFA_CHECKSTATE_Neutral;
+ return XFA_CHECKSTATE_Off;
+}
+
+bool CXFA_FFCheckButton::CommitData() {
+ XFA_CHECKSTATE eCheckState = FWLState2XFAState();
+ m_pDataAcc->SetCheckState(eCheckState, true);
+ return true;
+}
+
+bool CXFA_FFCheckButton::IsDataChanged() {
+ XFA_CHECKSTATE eCheckState = FWLState2XFAState();
+ return m_pDataAcc->GetCheckState() != eCheckState;
+}
+
+void CXFA_FFCheckButton::SetFWLCheckState(XFA_CHECKSTATE eCheckState) {
+ if (eCheckState == XFA_CHECKSTATE_Neutral)
+ m_pNormalWidget->SetStates(FWL_STATE_CKB_Neutral);
+ else if (eCheckState == XFA_CHECKSTATE_On)
+ m_pNormalWidget->SetStates(FWL_STATE_CKB_Checked);
+ else
+ m_pNormalWidget->RemoveStates(FWL_STATE_CKB_Checked);
+}
+
+bool CXFA_FFCheckButton::UpdateFWLData() {
+ if (!m_pNormalWidget)
+ return false;
+
+ XFA_CHECKSTATE eState = m_pDataAcc->GetCheckState();
+ SetFWLCheckState(eState);
+ m_pNormalWidget->Update();
+ return true;
+}
+
+void CXFA_FFCheckButton::OnProcessMessage(CFWL_Message* pMessage) {
+ m_pOldDelegate->OnProcessMessage(pMessage);
+}
+
+void CXFA_FFCheckButton::OnProcessEvent(CFWL_Event* pEvent) {
+ CXFA_FFField::OnProcessEvent(pEvent);
+ switch (pEvent->GetType()) {
+ case CFWL_Event::Type::CheckStateChanged: {
+ CXFA_EventParam eParam;
+ eParam.m_eType = XFA_EVENT_Change;
+ m_pDataAcc->GetValue(eParam.m_wsNewText, XFA_VALUEPICTURE_Raw);
+
+ CXFA_WidgetAcc* pFFExclGroup = m_pDataAcc->GetExclGroup();
+ if (ProcessCommittedData()) {
+ eParam.m_pTarget = pFFExclGroup;
+ if (pFFExclGroup) {
+ m_pDocView->AddValidateWidget(pFFExclGroup);
+ m_pDocView->AddCalculateWidgetAcc(pFFExclGroup);
+ pFFExclGroup->ProcessEvent(XFA_ATTRIBUTEENUM_Change, &eParam);
+ }
+ eParam.m_pTarget = m_pDataAcc.Get();
+ m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Change, &eParam);
+ } else {
+ SetFWLCheckState(m_pDataAcc->GetCheckState());
+ }
+ if (pFFExclGroup) {
+ eParam.m_pTarget = pFFExclGroup;
+ pFFExclGroup->ProcessEvent(XFA_ATTRIBUTEENUM_Click, &eParam);
+ }
+ eParam.m_pTarget = m_pDataAcc.Get();
+ m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Click, &eParam);
+ break;
+ }
+ default:
+ break;
+ }
+ m_pOldDelegate->OnProcessEvent(pEvent);
+}
+
+void CXFA_FFCheckButton::OnDrawWidget(CXFA_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix) {
+ m_pOldDelegate->OnDrawWidget(pGraphics, pMatrix);
+}