OLD | NEW |
| (Empty) |
1 // Copyright 2014 PDFium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | |
6 | |
7 #include "xfa/src/fxfa/app/xfa_ffcheckbutton.h" | |
8 | |
9 #include "xfa/include/fwl/core/fwl_widgetmgr.h" | |
10 #include "xfa/include/fwl/lightwidget/checkbox.h" | |
11 #include "xfa/src/fxfa/app/xfa_ffapp.h" | |
12 #include "xfa/src/fxfa/app/xfa_ffdoc.h" | |
13 #include "xfa/src/fxfa/app/xfa_ffdocview.h" | |
14 #include "xfa/src/fxfa/app/xfa_ffexclgroup.h" | |
15 #include "xfa/src/fxfa/app/xfa_fffield.h" | |
16 #include "xfa/src/fxfa/app/xfa_ffpageview.h" | |
17 #include "xfa/src/fxfa/app/xfa_ffwidget.h" | |
18 | |
19 CXFA_FFCheckButton::CXFA_FFCheckButton(CXFA_FFPageView* pPageView, | |
20 CXFA_WidgetAcc* pDataAcc) | |
21 : CXFA_FFField(pPageView, pDataAcc), m_pOldDelegate(NULL) { | |
22 m_rtCheckBox.Set(0, 0, 0, 0); | |
23 } | |
24 CXFA_FFCheckButton::~CXFA_FFCheckButton() {} | |
25 FX_BOOL CXFA_FFCheckButton::LoadWidget() { | |
26 CFWL_CheckBox* pCheckBox = CFWL_CheckBox::Create(); | |
27 pCheckBox->Initialize(); | |
28 m_pNormalWidget = pCheckBox; | |
29 IFWL_Widget* pWidget = m_pNormalWidget->GetWidget(); | |
30 m_pNormalWidget->SetPrivateData(pWidget, this, NULL); | |
31 IFWL_NoteDriver* pNoteDriver = FWL_GetApp()->GetNoteDriver(); | |
32 pNoteDriver->RegisterEventTarget(pWidget, pWidget); | |
33 m_pOldDelegate = m_pNormalWidget->SetDelegate(this); | |
34 if (m_pDataAcc->IsRadioButton()) { | |
35 pCheckBox->ModifyStylesEx(FWL_STYLEEXT_CKB_RadioButton, 0xFFFFFFFF); | |
36 } | |
37 m_pNormalWidget = (CFWL_Widget*)pCheckBox; | |
38 m_pNormalWidget->SetPrivateData(m_pNormalWidget->GetWidget(), this, NULL); | |
39 m_pNormalWidget->LockUpdate(); | |
40 UpdateWidgetProperty(); | |
41 XFA_CHECKSTATE eState = m_pDataAcc->GetCheckState(); | |
42 SetFWLCheckState(eState); | |
43 m_pNormalWidget->UnlockUpdate(); | |
44 return CXFA_FFField::LoadWidget(); | |
45 } | |
46 void CXFA_FFCheckButton::UpdateWidgetProperty() { | |
47 CFWL_CheckBox* pCheckBox = (CFWL_CheckBox*)m_pNormalWidget; | |
48 if (!m_pNormalWidget) { | |
49 return; | |
50 } | |
51 FX_FLOAT fSize = m_pDataAcc->GetCheckButtonSize(); | |
52 pCheckBox->SetBoxSize(fSize); | |
53 FX_DWORD dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCross; | |
54 int32_t iCheckMark = m_pDataAcc->GetCheckButtonMark(); | |
55 switch (iCheckMark) { | |
56 case XFA_ATTRIBUTEENUM_Check: | |
57 dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCheck; | |
58 break; | |
59 case XFA_ATTRIBUTEENUM_Circle: | |
60 dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCircle; | |
61 break; | |
62 case XFA_ATTRIBUTEENUM_Cross: | |
63 break; | |
64 case XFA_ATTRIBUTEENUM_Diamond: | |
65 dwStyleEx = FWL_STYLEEXT_CKB_SignShapeDiamond; | |
66 break; | |
67 case XFA_ATTRIBUTEENUM_Square: | |
68 dwStyleEx = FWL_STYLEEXT_CKB_SignShapeSquare; | |
69 break; | |
70 case XFA_ATTRIBUTEENUM_Star: | |
71 dwStyleEx = FWL_STYLEEXT_CKB_SignShapeStar; | |
72 break; | |
73 default: { | |
74 int32_t iShape = m_pDataAcc->GetCheckButtonShape(); | |
75 if (iShape == XFA_ATTRIBUTEENUM_Round) { | |
76 dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCircle; | |
77 } | |
78 } break; | |
79 } | |
80 if (m_pDataAcc->IsAllowNeutral()) { | |
81 dwStyleEx |= FWL_STYLEEXT_CKB_3State; | |
82 } | |
83 pCheckBox->ModifyStylesEx( | |
84 dwStyleEx, FWL_STYLEEXT_CKB_SignShapeMask | FWL_STYLEEXT_CKB_3State); | |
85 } | |
86 FX_BOOL CXFA_FFCheckButton::PerformLayout() { | |
87 CXFA_FFWidget::PerformLayout(); | |
88 FX_FLOAT fCheckSize = m_pDataAcc->GetCheckButtonSize(); | |
89 CXFA_Margin mgWidget = m_pDataAcc->GetMargin(); | |
90 CFX_RectF rtWidget; | |
91 GetRectWithoutRotate(rtWidget); | |
92 if (mgWidget) { | |
93 XFA_RectWidthoutMargin(rtWidget, mgWidget); | |
94 } | |
95 int32_t iCapPlacement = -1; | |
96 FX_FLOAT fCapReserve = 0; | |
97 CXFA_Caption caption = m_pDataAcc->GetCaption(); | |
98 if (caption && caption.GetPresence()) { | |
99 m_rtCaption.Set(rtWidget.left, rtWidget.top, rtWidget.width, | |
100 rtWidget.height); | |
101 iCapPlacement = caption.GetPlacementType(); | |
102 fCapReserve = caption.GetReserve(); | |
103 if (fCapReserve <= 0) { | |
104 if (iCapPlacement == XFA_ATTRIBUTEENUM_Top || | |
105 iCapPlacement == XFA_ATTRIBUTEENUM_Bottom) { | |
106 fCapReserve = rtWidget.height - fCheckSize; | |
107 } else { | |
108 fCapReserve = rtWidget.width - fCheckSize; | |
109 } | |
110 } | |
111 } | |
112 int32_t iHorzAlign = XFA_ATTRIBUTEENUM_Left; | |
113 int32_t iVertAlign = XFA_ATTRIBUTEENUM_Top; | |
114 if (CXFA_Para para = m_pDataAcc->GetPara()) { | |
115 iHorzAlign = para.GetHorizontalAlign(); | |
116 iVertAlign = para.GetVerticalAlign(); | |
117 } | |
118 m_rtUI = rtWidget; | |
119 CXFA_Margin mgCap = caption.GetMargin(); | |
120 switch (iCapPlacement) { | |
121 case XFA_ATTRIBUTEENUM_Left: { | |
122 m_rtCaption.width = fCapReserve; | |
123 CapLeftRightPlacement(mgCap); | |
124 m_rtUI.width -= fCapReserve; | |
125 m_rtUI.left += fCapReserve; | |
126 } break; | |
127 case XFA_ATTRIBUTEENUM_Top: { | |
128 m_rtCaption.height = fCapReserve; | |
129 XFA_RectWidthoutMargin(m_rtCaption, mgCap); | |
130 m_rtUI.height -= fCapReserve; | |
131 m_rtUI.top += fCapReserve; | |
132 } break; | |
133 case XFA_ATTRIBUTEENUM_Right: { | |
134 m_rtCaption.left = m_rtCaption.right() - fCapReserve; | |
135 m_rtCaption.width = fCapReserve; | |
136 CapLeftRightPlacement(mgCap); | |
137 m_rtUI.width -= fCapReserve; | |
138 } break; | |
139 case XFA_ATTRIBUTEENUM_Bottom: { | |
140 m_rtCaption.top = m_rtCaption.bottom() - fCapReserve; | |
141 m_rtCaption.height = fCapReserve; | |
142 XFA_RectWidthoutMargin(m_rtCaption, mgCap); | |
143 m_rtUI.height -= fCapReserve; | |
144 } break; | |
145 case XFA_ATTRIBUTEENUM_Inline: | |
146 break; | |
147 default: | |
148 iHorzAlign = XFA_ATTRIBUTEENUM_Right; | |
149 break; | |
150 } | |
151 if (iHorzAlign == XFA_ATTRIBUTEENUM_Center) { | |
152 m_rtUI.left += (m_rtUI.width - fCheckSize) / 2; | |
153 } else if (iHorzAlign == XFA_ATTRIBUTEENUM_Right) { | |
154 m_rtUI.left = m_rtUI.right() - fCheckSize; | |
155 } | |
156 if (iVertAlign == XFA_ATTRIBUTEENUM_Middle) { | |
157 m_rtUI.top += (m_rtUI.height - fCheckSize) / 2; | |
158 } else if (iVertAlign == XFA_ATTRIBUTEENUM_Bottom) { | |
159 m_rtUI.top = m_rtUI.bottom() - fCheckSize; | |
160 } | |
161 m_rtUI.width = fCheckSize; | |
162 m_rtUI.height = fCheckSize; | |
163 AddUIMargin(iCapPlacement); | |
164 m_rtCheckBox = m_rtUI; | |
165 CXFA_Border borderUI = m_pDataAcc->GetUIBorder(); | |
166 if (borderUI) { | |
167 CXFA_Margin margin = borderUI.GetMargin(); | |
168 if (margin) { | |
169 XFA_RectWidthoutMargin(m_rtUI, margin); | |
170 } | |
171 } | |
172 m_rtUI.Normalize(); | |
173 LayoutCaption(); | |
174 SetFWLRect(); | |
175 if (m_pNormalWidget) { | |
176 m_pNormalWidget->Update(); | |
177 } | |
178 return TRUE; | |
179 } | |
180 void CXFA_FFCheckButton::CapLeftRightPlacement(CXFA_Margin mgCap) { | |
181 XFA_RectWidthoutMargin(m_rtCaption, mgCap); | |
182 if (m_rtCaption.height < 0) { | |
183 m_rtCaption.top += m_rtCaption.height; | |
184 } | |
185 if (m_rtCaption.width < 0) { | |
186 m_rtCaption.left += m_rtCaption.width; | |
187 m_rtCaption.width = -m_rtCaption.width; | |
188 } | |
189 } | |
190 void CXFA_FFCheckButton::AddUIMargin(int32_t iCapPlacement) { | |
191 CFX_RectF rtUIMargin; | |
192 m_pDataAcc->GetUIMargin(rtUIMargin); | |
193 m_rtUI.top -= rtUIMargin.top / 2 - rtUIMargin.height / 2; | |
194 FX_FLOAT fLeftAddRight = rtUIMargin.left + rtUIMargin.width; | |
195 FX_FLOAT fTopAddBottom = rtUIMargin.top + rtUIMargin.height; | |
196 if (m_rtUI.width < fLeftAddRight) { | |
197 if (iCapPlacement == XFA_ATTRIBUTEENUM_Right || | |
198 iCapPlacement == XFA_ATTRIBUTEENUM_Left) { | |
199 m_rtUI.left -= fLeftAddRight - m_rtUI.width; | |
200 } else { | |
201 m_rtUI.left -= 2 * (fLeftAddRight - m_rtUI.width); | |
202 } | |
203 m_rtUI.width += 2 * (fLeftAddRight - m_rtUI.width); | |
204 } | |
205 if (m_rtUI.height < fTopAddBottom) { | |
206 if (iCapPlacement == XFA_ATTRIBUTEENUM_Right) { | |
207 m_rtUI.left -= fTopAddBottom - m_rtUI.height; | |
208 } | |
209 m_rtUI.top -= fTopAddBottom - m_rtUI.height; | |
210 m_rtUI.height += 2 * (fTopAddBottom - m_rtUI.height); | |
211 } | |
212 } | |
213 void CXFA_FFCheckButton::RenderWidget(CFX_Graphics* pGS, | |
214 CFX_Matrix* pMatrix, | |
215 FX_DWORD dwStatus, | |
216 int32_t iRotate) { | |
217 if (!IsMatchVisibleStatus(dwStatus)) { | |
218 return; | |
219 } | |
220 CFX_Matrix mtRotate; | |
221 GetRotateMatrix(mtRotate); | |
222 if (pMatrix) { | |
223 mtRotate.Concat(*pMatrix); | |
224 } | |
225 CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus); | |
226 CXFA_Border borderUI = m_pDataAcc->GetUIBorder(); | |
227 DrawBorder(pGS, borderUI, m_rtUI, &mtRotate, | |
228 m_pDataAcc->GetCheckButtonShape() == XFA_ATTRIBUTEENUM_Round | |
229 ? XFA_DRAWBOX_ForceRound | |
230 : 0); | |
231 RenderCaption(pGS, &mtRotate); | |
232 DrawHighlight(pGS, &mtRotate, dwStatus, | |
233 m_pDataAcc->GetCheckButtonShape() == XFA_ATTRIBUTEENUM_Round); | |
234 CFX_Matrix mt; | |
235 mt.Set(1, 0, 0, 1, m_rtCheckBox.left, m_rtCheckBox.top); | |
236 mt.Concat(mtRotate); | |
237 GetApp()->GetWidgetMgrDelegate()->OnDrawWidget(m_pNormalWidget->GetWidget(), | |
238 pGS, &mt); | |
239 } | |
240 FX_BOOL CXFA_FFCheckButton::OnLButtonUp(FX_DWORD dwFlags, | |
241 FX_FLOAT fx, | |
242 FX_FLOAT fy) { | |
243 if (!m_pNormalWidget) { | |
244 return FALSE; | |
245 } | |
246 if (!IsButtonDown()) { | |
247 return FALSE; | |
248 } | |
249 SetButtonDown(FALSE); | |
250 CFWL_MsgMouse ms; | |
251 ms.m_dwCmd = FWL_MSGMOUSECMD_LButtonUp; | |
252 ms.m_dwFlags = dwFlags; | |
253 ms.m_fx = fx; | |
254 ms.m_fy = fy; | |
255 FWLToClient(ms.m_fx, ms.m_fy); | |
256 ms.m_pDstTarget = m_pNormalWidget->m_pIface; | |
257 TranslateFWLMessage(&ms); | |
258 return TRUE; | |
259 } | |
260 XFA_CHECKSTATE CXFA_FFCheckButton::FWLState2XFAState() { | |
261 XFA_CHECKSTATE eCheckState = XFA_CHECKSTATE_Off; | |
262 FX_DWORD dwState = m_pNormalWidget->GetStates(); | |
263 if (dwState & FWL_STATE_CKB_Checked) { | |
264 eCheckState = XFA_CHECKSTATE_On; | |
265 } else if (dwState & FWL_STATE_CKB_Neutral) { | |
266 eCheckState = XFA_CHECKSTATE_Neutral; | |
267 } | |
268 return eCheckState; | |
269 } | |
270 FX_BOOL CXFA_FFCheckButton::CommitData() { | |
271 XFA_CHECKSTATE eCheckState = FWLState2XFAState(); | |
272 m_pDataAcc->SetCheckState(eCheckState, TRUE); | |
273 return TRUE; | |
274 } | |
275 FX_BOOL CXFA_FFCheckButton::IsDataChanged() { | |
276 XFA_CHECKSTATE eCheckState = FWLState2XFAState(); | |
277 return m_pDataAcc->GetCheckState() != eCheckState; | |
278 } | |
279 void CXFA_FFCheckButton::SetFWLCheckState(XFA_CHECKSTATE eCheckState) { | |
280 if (eCheckState == XFA_CHECKSTATE_Neutral) { | |
281 m_pNormalWidget->SetStates(FWL_STATE_CKB_Neutral, TRUE); | |
282 } else { | |
283 m_pNormalWidget->SetStates(FWL_STATE_CKB_Checked, | |
284 eCheckState == XFA_CHECKSTATE_On); | |
285 } | |
286 } | |
287 FX_BOOL CXFA_FFCheckButton::UpdateFWLData() { | |
288 if (!m_pNormalWidget) { | |
289 return FALSE; | |
290 } | |
291 XFA_CHECKSTATE eState = m_pDataAcc->GetCheckState(); | |
292 SetFWLCheckState(eState); | |
293 m_pNormalWidget->Update(); | |
294 return TRUE; | |
295 } | |
296 int32_t CXFA_FFCheckButton::OnProcessMessage(CFWL_Message* pMessage) { | |
297 return m_pOldDelegate->OnProcessMessage(pMessage); | |
298 } | |
299 FWL_ERR CXFA_FFCheckButton::OnProcessEvent(CFWL_Event* pEvent) { | |
300 CXFA_FFField::OnProcessEvent(pEvent); | |
301 FX_DWORD dwEventID = pEvent->GetClassID(); | |
302 switch (dwEventID) { | |
303 case FWL_EVTHASH_CKB_CheckStateChanged: { | |
304 CXFA_EventParam eParam; | |
305 eParam.m_eType = XFA_EVENT_Change; | |
306 m_pDataAcc->GetValue(eParam.m_wsNewText, XFA_VALUEPICTURE_Raw); | |
307 CXFA_WidgetAcc* pFFExclGroup = m_pDataAcc->GetExclGroup(); | |
308 if (ProcessCommittedData()) { | |
309 eParam.m_pTarget = pFFExclGroup; | |
310 if (pFFExclGroup) { | |
311 m_pDocView->AddValidateWidget(pFFExclGroup); | |
312 m_pDocView->AddCalculateWidgetAcc(pFFExclGroup); | |
313 pFFExclGroup->ProcessEvent(XFA_ATTRIBUTEENUM_Change, &eParam); | |
314 } | |
315 eParam.m_pTarget = m_pDataAcc; | |
316 m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Change, &eParam); | |
317 } else { | |
318 SetFWLCheckState(m_pDataAcc->GetCheckState()); | |
319 } | |
320 if (pFFExclGroup) { | |
321 eParam.m_pTarget = pFFExclGroup; | |
322 pFFExclGroup->ProcessEvent(XFA_ATTRIBUTEENUM_Click, &eParam); | |
323 } | |
324 eParam.m_pTarget = m_pDataAcc; | |
325 m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Click, &eParam); | |
326 break; | |
327 } | |
328 default: {} | |
329 } | |
330 return m_pOldDelegate->OnProcessEvent(pEvent); | |
331 } | |
332 FWL_ERR CXFA_FFCheckButton::OnDrawWidget(CFX_Graphics* pGraphics, | |
333 const CFX_Matrix* pMatrix) { | |
334 return m_pOldDelegate->OnDrawWidget(pGraphics, pMatrix); | |
335 } | |
OLD | NEW |