1 // Copyright 2014 PDFium Authors. All rights reserved.
\r
2 // Use of this source code is governed by a BSD-style license that can be
\r
3 // found in the LICENSE file.
\r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
\r
7 #include "../../../foxitlib.h"
\r
8 #include "../common/xfa_common.h"
\r
9 #include "xfa_ffwidget.h"
\r
10 #include "xfa_fffield.h"
\r
11 #include "xfa_ffpageview.h"
\r
12 #include "xfa_ffcheckbutton.h"
\r
13 #include "xfa_ffexclgroup.h"
\r
14 #include "xfa_ffdocview.h"
\r
15 #include "xfa_ffapp.h"
\r
16 #include "xfa_ffdoc.h"
\r
17 CXFA_FFCheckButton::CXFA_FFCheckButton(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
\r
18 : CXFA_FFField(pPageView, pDataAcc)
\r
19 , m_pOldDelegate(NULL)
\r
21 m_rtCheckBox.Set(0, 0, 0, 0);
\r
23 CXFA_FFCheckButton::~CXFA_FFCheckButton()
\r
26 FX_BOOL CXFA_FFCheckButton::LoadWidget()
\r
28 CFWL_CheckBox* pCheckBox = CFWL_CheckBox::Create();
\r
29 pCheckBox->Initialize();
\r
30 m_pNormalWidget = pCheckBox;
\r
31 IFWL_Widget* pWidget = m_pNormalWidget->GetWidget();
\r
32 m_pNormalWidget->SetPrivateData(pWidget, this, NULL);
\r
33 IFWL_NoteDriver *pNoteDriver = FWL_GetApp()->GetNoteDriver();
\r
34 pNoteDriver->RegisterEventTarget(pWidget, pWidget);
\r
35 m_pOldDelegate = m_pNormalWidget->SetDelegate(this);
\r
36 if (m_pDataAcc->IsRadioButton()) {
\r
37 pCheckBox->ModifyStylesEx(FWL_STYLEEXT_CKB_RadioButton, 0xFFFFFFFF);
\r
39 m_pNormalWidget = (CFWL_Widget*)pCheckBox;
\r
40 m_pNormalWidget->SetPrivateData(m_pNormalWidget->GetWidget(), this, NULL);
\r
41 m_pNormalWidget->LockUpdate();
\r
42 UpdateWidgetProperty();
\r
43 XFA_CHECKSTATE eState = m_pDataAcc->GetCheckState();
\r
44 SetFWLCheckState(eState);
\r
45 m_pNormalWidget->UnlockUpdate();
\r
46 return CXFA_FFField::LoadWidget();
\r
48 void CXFA_FFCheckButton::UpdateWidgetProperty()
\r
50 CFWL_CheckBox* pCheckBox = (CFWL_CheckBox*)m_pNormalWidget;
\r
51 if (!m_pNormalWidget) {
\r
54 FX_FLOAT fSize = m_pDataAcc->GetCheckButtonSize();
\r
55 pCheckBox->SetBoxSize(fSize);
\r
56 FX_DWORD dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCross;
\r
57 FX_INT32 iCheckMark = m_pDataAcc->GetCheckButtonMark();
\r
58 switch(iCheckMark) {
\r
59 case XFA_ATTRIBUTEENUM_Check:
\r
60 dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCheck;
\r
62 case XFA_ATTRIBUTEENUM_Circle:
\r
63 dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCircle;
\r
65 case XFA_ATTRIBUTEENUM_Cross:
\r
67 case XFA_ATTRIBUTEENUM_Diamond:
\r
68 dwStyleEx = FWL_STYLEEXT_CKB_SignShapeDiamond;
\r
70 case XFA_ATTRIBUTEENUM_Square:
\r
71 dwStyleEx = FWL_STYLEEXT_CKB_SignShapeSquare;
\r
73 case XFA_ATTRIBUTEENUM_Star:
\r
74 dwStyleEx = FWL_STYLEEXT_CKB_SignShapeStar;
\r
77 FX_INT32 iShape = m_pDataAcc->GetCheckButtonShape();
\r
78 if (iShape == XFA_ATTRIBUTEENUM_Round) {
\r
79 dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCircle;
\r
84 if (m_pDataAcc->IsAllowNeutral()) {
\r
85 dwStyleEx |= FWL_STYLEEXT_CKB_3State;
\r
87 pCheckBox->ModifyStylesEx(dwStyleEx, FWL_STYLEEXT_CKB_SignShapeMask | FWL_STYLEEXT_CKB_3State);
\r
89 FX_BOOL CXFA_FFCheckButton::LayoutWidget()
\r
91 CXFA_FFWidget::LayoutWidget();
\r
92 FX_FLOAT fCheckSize = m_pDataAcc->GetCheckButtonSize();
\r
93 CXFA_Margin mgWidget = m_pDataAcc->GetMargin();
\r
95 GetRectWithoutRotate(rtWidget);
\r
96 if (mgWidget.IsExistInXML()) {
\r
97 XFA_RectWidthoutMargin(rtWidget, mgWidget);
\r
99 FX_INT32 iCapPlacement = -1;
\r
100 FX_FLOAT fCapReserve = 0;
\r
101 CXFA_Caption caption = m_pDataAcc->GetCaption();
\r
102 if (caption.IsExistInXML() && caption.GetPresence()) {
\r
103 m_rtCaption.Set(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height);
\r
104 iCapPlacement = caption.GetPlacementType();
\r
105 fCapReserve = caption.GetReserve();
\r
106 if (fCapReserve <= 0) {
\r
107 if (iCapPlacement == XFA_ATTRIBUTEENUM_Top || iCapPlacement == XFA_ATTRIBUTEENUM_Bottom) {
\r
108 fCapReserve = rtWidget.height - fCheckSize;
\r
110 fCapReserve = rtWidget.width - fCheckSize;
\r
114 FX_INT32 iHorzAlign = XFA_ATTRIBUTEENUM_Left;
\r
115 FX_INT32 iVertAlign = XFA_ATTRIBUTEENUM_Top;
\r
116 if (CXFA_Para para = m_pDataAcc->GetPara()) {
\r
117 iHorzAlign = para.GetHorizontalAlign();
\r
118 iVertAlign = para.GetVerticalAlign();
\r
121 CXFA_Margin mgCap = caption.GetMargin();
\r
122 switch(iCapPlacement) {
\r
123 case XFA_ATTRIBUTEENUM_Left: {
\r
124 m_rtCaption.width = fCapReserve;
\r
125 CapLeftRightPlacement(mgCap);
\r
126 m_rtUI.width -= fCapReserve;
\r
127 m_rtUI.left += fCapReserve;
\r
130 case XFA_ATTRIBUTEENUM_Top: {
\r
131 m_rtCaption.height = fCapReserve;
\r
132 XFA_RectWidthoutMargin(m_rtCaption, mgCap);
\r
133 m_rtUI.height -= fCapReserve;
\r
134 m_rtUI.top += fCapReserve;
\r
137 case XFA_ATTRIBUTEENUM_Right: {
\r
138 m_rtCaption.left = m_rtCaption.right() - fCapReserve;
\r
139 m_rtCaption.width = fCapReserve;
\r
140 CapLeftRightPlacement(mgCap);
\r
141 m_rtUI.width -= fCapReserve;
\r
144 case XFA_ATTRIBUTEENUM_Bottom: {
\r
145 m_rtCaption.top = m_rtCaption.bottom() - fCapReserve;
\r
146 m_rtCaption.height = fCapReserve;
\r
147 XFA_RectWidthoutMargin(m_rtCaption, mgCap);
\r
148 m_rtUI.height -= fCapReserve;
\r
151 case XFA_ATTRIBUTEENUM_Inline:
\r
154 iHorzAlign = XFA_ATTRIBUTEENUM_Right;
\r
157 if (iHorzAlign == XFA_ATTRIBUTEENUM_Center) {
\r
158 m_rtUI.left += (m_rtUI.width - fCheckSize) / 2;
\r
159 } else if (iHorzAlign == XFA_ATTRIBUTEENUM_Right) {
\r
160 m_rtUI.left = m_rtUI.right() - fCheckSize;
\r
162 if (iVertAlign == XFA_ATTRIBUTEENUM_Middle) {
\r
163 m_rtUI.top += (m_rtUI.height - fCheckSize) / 2;
\r
164 } else if (iVertAlign == XFA_ATTRIBUTEENUM_Bottom) {
\r
165 m_rtUI.top = m_rtUI.bottom() - fCheckSize;
\r
167 m_rtUI.width = fCheckSize;
\r
168 m_rtUI.height = fCheckSize;
\r
169 AddUIMargin(iCapPlacement);
\r
170 m_rtCheckBox = m_rtUI;
\r
171 CXFA_Border borderUI = m_pDataAcc->GetUIBorder();
\r
173 CXFA_Margin margin = borderUI.GetMargin();
\r
174 if (margin.IsExistInXML()) {
\r
175 XFA_RectWidthoutMargin(m_rtUI, margin);
\r
178 m_rtUI.Normalize();
\r
181 if (m_pNormalWidget) {
\r
182 m_pNormalWidget->Update();
\r
186 void CXFA_FFCheckButton::CapLeftRightPlacement(CXFA_Margin mgCap)
\r
188 XFA_RectWidthoutMargin(m_rtCaption, mgCap);
\r
189 if (m_rtCaption.height < 0) {
\r
190 m_rtCaption.top += m_rtCaption.height;
\r
192 if (m_rtCaption.width < 0) {
\r
193 m_rtCaption.left += m_rtCaption.width;
\r
194 m_rtCaption.width = -m_rtCaption.width;
\r
197 void CXFA_FFCheckButton::AddUIMargin(FX_INT32 iCapPlacement)
\r
199 CFX_RectF rtUIMargin;
\r
200 m_pDataAcc->GetUIMargin(rtUIMargin);
\r
201 m_rtUI.top -= rtUIMargin.top / 2 - rtUIMargin.height / 2;
\r
202 FX_FLOAT fLeftAddRight = rtUIMargin.left + rtUIMargin.width;
\r
203 FX_FLOAT fTopAddBottom = rtUIMargin.top + rtUIMargin.height;
\r
204 if (m_rtUI.width < fLeftAddRight) {
\r
205 if (iCapPlacement == XFA_ATTRIBUTEENUM_Right || iCapPlacement == XFA_ATTRIBUTEENUM_Left) {
\r
206 m_rtUI.left -= fLeftAddRight - m_rtUI.width;
\r
208 m_rtUI.left -= 2 * (fLeftAddRight - m_rtUI.width);
\r
210 m_rtUI.width += 2 * (fLeftAddRight - m_rtUI.width);
\r
212 if (m_rtUI.height < fTopAddBottom) {
\r
213 if (iCapPlacement == XFA_ATTRIBUTEENUM_Right) {
\r
214 m_rtUI.left -= fTopAddBottom - m_rtUI.height;
\r
216 m_rtUI.top -= fTopAddBottom - m_rtUI.height;
\r
217 m_rtUI.height += 2 * (fTopAddBottom - m_rtUI.height);
\r
220 void CXFA_FFCheckButton::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix , FX_DWORD dwStatus , FX_INT32 iRotate )
\r
222 if (!IsMatchVisibleStatus(dwStatus)) {
\r
225 CFX_Matrix mtRotate;
\r
226 GetRotateMatrix(mtRotate);
\r
228 mtRotate.Concat(*pMatrix);
\r
230 CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
\r
231 CXFA_Border borderUI = m_pDataAcc->GetUIBorder();
\r
232 DrawBorder(pGS, borderUI, m_rtUI, &mtRotate, m_pDataAcc->GetCheckButtonShape() == XFA_ATTRIBUTEENUM_Round ? XFA_DRAWBOX_ForceRound : 0);
\r
233 RenderCaption(pGS, &mtRotate);
\r
234 DrawHighlight(pGS, &mtRotate, dwStatus, m_pDataAcc->GetCheckButtonShape() == XFA_ATTRIBUTEENUM_Round);
\r
236 mt.Set(1, 0, 0, 1, m_rtCheckBox.left, m_rtCheckBox.top);
\r
237 mt.Concat(mtRotate);
\r
238 GetApp()->GetWidgetMgrDelegate()->OnDrawWidget(m_pNormalWidget->GetWidget(), pGS, &mt);
\r
240 FX_BOOL CXFA_FFCheckButton::OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
\r
242 if (!m_pNormalWidget) {
\r
245 if (!IsButtonDown()) {
\r
248 SetButtonDown(FALSE);
\r
250 ms.m_dwCmd = FWL_MSGMOUSECMD_LButtonUp;
\r
251 ms.m_dwFlags = dwFlags;
\r
254 FWLToClient(ms.m_fx, ms.m_fy);
\r
255 ms.m_pDstTarget = m_pNormalWidget->m_pImp;
\r
256 TranslateFWLMessage(&ms);
\r
259 XFA_CHECKSTATE CXFA_FFCheckButton::FWLState2XFAState()
\r
261 XFA_CHECKSTATE eCheckState = XFA_CHECKSTATE_Off;
\r
262 FX_DWORD dwState = m_pNormalWidget->GetStates();
\r
263 if (dwState & FWL_STATE_CKB_Checked) {
\r
264 eCheckState = XFA_CHECKSTATE_On;
\r
265 } else if (dwState & FWL_STATE_CKB_Neutral) {
\r
266 eCheckState = XFA_CHECKSTATE_Neutral;
\r
268 return eCheckState;
\r
270 FX_BOOL CXFA_FFCheckButton::CommitData()
\r
272 XFA_CHECKSTATE eCheckState = FWLState2XFAState();
\r
273 m_pDataAcc->SetCheckState(eCheckState, TRUE);
\r
276 FX_BOOL CXFA_FFCheckButton::IsDataChanged()
\r
278 XFA_CHECKSTATE eCheckState = FWLState2XFAState();
\r
279 return m_pDataAcc->GetCheckState() != eCheckState;
\r
281 void CXFA_FFCheckButton::SetFWLCheckState(XFA_CHECKSTATE eCheckState)
\r
283 if (eCheckState == XFA_CHECKSTATE_Neutral) {
\r
284 m_pNormalWidget->SetStates(FWL_STATE_CKB_Neutral, TRUE);
\r
286 m_pNormalWidget->SetStates(FWL_STATE_CKB_Checked, eCheckState == XFA_CHECKSTATE_On);
\r
289 FX_BOOL CXFA_FFCheckButton::UpdateFWLData()
\r
291 if (!m_pNormalWidget) {
\r
294 XFA_CHECKSTATE eState = m_pDataAcc->GetCheckState();
\r
295 SetFWLCheckState(eState);
\r
296 m_pNormalWidget->Update();
\r
299 FX_INT32 CXFA_FFCheckButton::OnProcessMessage(CFWL_Message *pMessage)
\r
301 return m_pOldDelegate->OnProcessMessage(pMessage);
\r
303 FWL_ERR CXFA_FFCheckButton::OnProcessEvent(CFWL_Event *pEvent)
\r
305 CXFA_FFField::OnProcessEvent(pEvent);
\r
306 FX_DWORD dwEventID = pEvent->GetClassID();
\r
307 switch (dwEventID) {
\r
308 case FWL_EVTHASH_CKB_CheckStateChanged: {
\r
309 CXFA_EventParam eParam;
\r
310 eParam.m_eType = XFA_EVENT_Change;
\r
311 m_pDataAcc->GetValue(eParam.m_wsNewText, XFA_VALUEPICTURE_Raw);
\r
312 CXFA_WidgetAcc* pFFExclGroup = m_pDataAcc->GetExclGroup();
\r
313 if (ProcessCommittedData()) {
\r
314 eParam.m_pTarget = pFFExclGroup;
\r
315 if (pFFExclGroup) {
\r
316 m_pDocView->AddValidateWidget(pFFExclGroup);
\r
317 m_pDocView->AddCalculateWidgetAcc(pFFExclGroup);
\r
318 pFFExclGroup->ProcessEvent(XFA_ATTRIBUTEENUM_Change, &eParam);
\r
320 eParam.m_pTarget = m_pDataAcc;
\r
321 m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Change, &eParam);
\r
323 SetFWLCheckState(m_pDataAcc->GetCheckState());
\r
325 if (pFFExclGroup) {
\r
326 eParam.m_pTarget = pFFExclGroup;
\r
327 pFFExclGroup->ProcessEvent(XFA_ATTRIBUTEENUM_Click, &eParam);
\r
329 eParam.m_pTarget = m_pDataAcc;
\r
330 m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Click, &eParam);
\r
336 return m_pOldDelegate->OnProcessEvent(pEvent);
\r
338 FWL_ERR CXFA_FFCheckButton::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
\r
340 return m_pOldDelegate->OnDrawWidget(pGraphics, pMatrix);
\r