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/foxitlib.h"
8 #include "xfa/src/fxfa/src/common/xfa_common.h"
9 #include "xfa_ffwidget.h"
10 #include "xfa_ffwidgetacc.h"
11 #include "xfa_fffield.h"
12 #include "xfa_ffpageview.h"
13 #include "xfa_ffpushbutton.h"
14 #include "xfa_textlayout.h"
15 #include "xfa_ffapp.h"
CXFA_FFPushButton(CXFA_FFPageView * pPageView,CXFA_WidgetAcc * pDataAcc)16 CXFA_FFPushButton::CXFA_FFPushButton(CXFA_FFPageView* pPageView,
17 CXFA_WidgetAcc* pDataAcc)
18 : CXFA_FFField(pPageView, pDataAcc),
19 m_pRolloverTextLayout(NULL),
20 m_pDownTextLayout(NULL),
21 m_pDownProvider(NULL),
22 m_pRollProvider(NULL),
23 m_pOldDelegate(NULL) {}
~CXFA_FFPushButton()24 CXFA_FFPushButton::~CXFA_FFPushButton() {
25 CXFA_FFPushButton::UnloadWidget();
26 }
RenderWidget(CFX_Graphics * pGS,CFX_Matrix * pMatrix,FX_DWORD dwStatus,int32_t iRotate)27 void CXFA_FFPushButton::RenderWidget(CFX_Graphics* pGS,
28 CFX_Matrix* pMatrix,
29 FX_DWORD dwStatus,
30 int32_t iRotate) {
31 if (!IsMatchVisibleStatus(dwStatus)) {
32 return;
33 }
34 CFX_Matrix mtRotate;
35 GetRotateMatrix(mtRotate);
36 if (pMatrix) {
37 mtRotate.Concat(*pMatrix);
38 }
39 CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
40 RenderHighlightCaption(pGS, &mtRotate);
41 CFX_RectF rtWidget;
42 GetRectWithoutRotate(rtWidget);
43 CFX_Matrix mt;
44 mt.Set(1, 0, 0, 1, rtWidget.left, rtWidget.top);
45 mt.Concat(mtRotate);
46 GetApp()->GetWidgetMgrDelegate()->OnDrawWidget(m_pNormalWidget->GetWidget(),
47 pGS, &mt);
48 }
LoadWidget()49 FX_BOOL CXFA_FFPushButton::LoadWidget() {
50 FXSYS_assert(m_pNormalWidget == NULL);
51 CFWL_PushButton* pPushButton = CFWL_PushButton::Create();
52 if (pPushButton) {
53 pPushButton->Initialize();
54 }
55 m_pOldDelegate = pPushButton->SetDelegate(this);
56 m_pNormalWidget = (CFWL_Widget*)pPushButton;
57 IFWL_Widget* pWidget = m_pNormalWidget->GetWidget();
58 m_pNormalWidget->SetPrivateData(pWidget, this, NULL);
59 IFWL_NoteDriver* pNoteDriver = FWL_GetApp()->GetNoteDriver();
60 pNoteDriver->RegisterEventTarget(pWidget, pWidget);
61 m_pNormalWidget->LockUpdate();
62 UpdateWidgetProperty();
63 LoadHighlightCaption();
64 m_pNormalWidget->UnlockUpdate();
65 return CXFA_FFField::LoadWidget();
66 }
UpdateWidgetProperty()67 void CXFA_FFPushButton::UpdateWidgetProperty() {
68 FX_DWORD dwStyleEx = 0;
69 switch (m_pDataAcc->GetButtonHighlight()) {
70 case XFA_ATTRIBUTEENUM_Inverted:
71 dwStyleEx = XFA_FWL_PSBSTYLEEXT_HiliteInverted;
72 break;
73 case XFA_ATTRIBUTEENUM_Outline:
74 dwStyleEx = XFA_FWL_PSBSTYLEEXT_HiliteOutLine;
75 break;
76 case XFA_ATTRIBUTEENUM_Push:
77 dwStyleEx = XFA_FWL_PSBSTYLEEXT_HilitePush;
78 break;
79 default:
80 break;
81 }
82 m_pNormalWidget->ModifyStylesEx(dwStyleEx, 0xFFFFFFFF);
83 }
UnloadWidget()84 void CXFA_FFPushButton::UnloadWidget() {
85 if (m_pRolloverTextLayout) {
86 delete m_pRolloverTextLayout;
87 m_pRolloverTextLayout = NULL;
88 }
89 if (m_pDownTextLayout) {
90 delete m_pDownTextLayout;
91 m_pDownTextLayout = NULL;
92 }
93 if (m_pDownProvider) {
94 delete m_pDownProvider;
95 m_pDownProvider = NULL;
96 }
97 if (m_pRollProvider) {
98 delete m_pRollProvider;
99 m_pRollProvider = NULL;
100 }
101 CXFA_FFField::UnloadWidget();
102 }
PerformLayout()103 FX_BOOL CXFA_FFPushButton::PerformLayout() {
104 CXFA_FFWidget::PerformLayout();
105 CFX_RectF rtWidget;
106 GetRectWithoutRotate(rtWidget);
107 m_rtUI = rtWidget;
108 if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) {
109 XFA_RectWidthoutMargin(rtWidget, mgWidget);
110 }
111 CXFA_Caption caption = m_pDataAcc->GetCaption();
112 m_rtCaption.Set(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height);
113 if (CXFA_Margin mgCap = caption.GetMargin()) {
114 XFA_RectWidthoutMargin(m_rtCaption, mgCap);
115 }
116 LayoutHighlightCaption();
117 SetFWLRect();
118 if (m_pNormalWidget) {
119 m_pNormalWidget->Update();
120 }
121 return TRUE;
122 }
GetLineWidth()123 FX_FLOAT CXFA_FFPushButton::GetLineWidth() {
124 CXFA_Border border = m_pDataAcc->GetBorder();
125 if (border.IsExistInXML() &&
126 (border.GetPresence() == XFA_ATTRIBUTEENUM_Visible)) {
127 CXFA_Edge edge = border.GetEdge(0);
128 return edge.GetThickness();
129 }
130 return 0;
131 }
GetLineColor()132 FX_ARGB CXFA_FFPushButton::GetLineColor() {
133 return 0xFF000000;
134 }
GetFillColor()135 FX_ARGB CXFA_FFPushButton::GetFillColor() {
136 return 0xFFFFFFFF;
137 }
LoadHighlightCaption()138 void CXFA_FFPushButton::LoadHighlightCaption() {
139 CXFA_Caption caption = m_pDataAcc->GetCaption();
140 if (caption.IsExistInXML() &&
141 caption.GetPresence() != XFA_ATTRIBUTEENUM_Hidden) {
142 {
143 CFX_WideString wsRollover;
144 FX_BOOL bRichText;
145 if (m_pDataAcc->GetButtonRollover(wsRollover, bRichText)) {
146 if (m_pRollProvider == NULL) {
147 m_pRollProvider =
148 new CXFA_TextProvider(m_pDataAcc, XFA_TEXTPROVIDERTYPE_Rollover);
149 }
150 m_pRolloverTextLayout = new CXFA_TextLayout(m_pRollProvider);
151 }
152 CFX_WideString wsDown;
153 if (m_pDataAcc->GetButtonDown(wsDown, bRichText)) {
154 if (m_pDownProvider == NULL) {
155 m_pDownProvider =
156 new CXFA_TextProvider(m_pDataAcc, XFA_TEXTPROVIDERTYPE_Down);
157 }
158 m_pDownTextLayout = new CXFA_TextLayout(m_pDownProvider);
159 }
160 }
161 }
162 }
LayoutHighlightCaption()163 void CXFA_FFPushButton::LayoutHighlightCaption() {
164 CFX_SizeF sz;
165 sz.Set(m_rtCaption.width, m_rtCaption.height);
166 LayoutCaption();
167 if (m_pRolloverTextLayout) {
168 m_pRolloverTextLayout->Layout(sz);
169 }
170 if (m_pDownTextLayout) {
171 m_pDownTextLayout->Layout(sz);
172 }
173 }
RenderHighlightCaption(CFX_Graphics * pGS,CFX_Matrix * pMatrix)174 void CXFA_FFPushButton::RenderHighlightCaption(CFX_Graphics* pGS,
175 CFX_Matrix* pMatrix) {
176 CXFA_TextLayout* pCapTextLayout = m_pDataAcc->GetCaptionTextLayout();
177 CXFA_Caption caption = m_pDataAcc->GetCaption();
178 if (caption.IsExistInXML() &&
179 caption.GetPresence() == XFA_ATTRIBUTEENUM_Visible) {
180 CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice();
181 CFX_RectF rtWidget;
182 GetRectWithoutRotate(rtWidget);
183 CFX_RectF rtClip = m_rtCaption;
184 rtClip.Intersect(rtWidget);
185 CFX_Matrix mt;
186 mt.Set(1, 0, 0, 1, m_rtCaption.left, m_rtCaption.top);
187 if (pMatrix) {
188 pMatrix->TransformRect(rtClip);
189 mt.Concat(*pMatrix);
190 }
191 {
192 FX_DWORD dwState = m_pNormalWidget->GetStates();
193 if (m_pDownTextLayout && (dwState & FWL_STATE_PSB_Pressed) &&
194 (dwState & FWL_STATE_PSB_Hovered)) {
195 if (m_pDownTextLayout->DrawString(pRenderDevice, mt, rtClip)) {
196 return;
197 }
198 } else if (m_pRolloverTextLayout && (dwState & FWL_STATE_PSB_Hovered)) {
199 if (m_pRolloverTextLayout->DrawString(pRenderDevice, mt, rtClip)) {
200 return;
201 }
202 }
203 }
204 if (pCapTextLayout) {
205 pCapTextLayout->DrawString(pRenderDevice, mt, rtClip);
206 }
207 }
208 }
OnProcessMessage(CFWL_Message * pMessage)209 int32_t CXFA_FFPushButton::OnProcessMessage(CFWL_Message* pMessage) {
210 return m_pOldDelegate->OnProcessMessage(pMessage);
211 }
OnProcessEvent(CFWL_Event * pEvent)212 FWL_ERR CXFA_FFPushButton::OnProcessEvent(CFWL_Event* pEvent) {
213 m_pOldDelegate->OnProcessEvent(pEvent);
214 return CXFA_FFField::OnProcessEvent(pEvent);
215 }
OnDrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)216 FWL_ERR CXFA_FFPushButton::OnDrawWidget(CFX_Graphics* pGraphics,
217 const CFX_Matrix* pMatrix) {
218 if (m_pNormalWidget->GetStylesEx() & XFA_FWL_PSBSTYLEEXT_HiliteInverted) {
219 if ((m_pNormalWidget->GetStates() & FWL_STATE_PSB_Pressed) &&
220 (m_pNormalWidget->GetStates() & FWL_STATE_PSB_Hovered)) {
221 CFX_RectF rtFill;
222 m_pNormalWidget->GetWidgetRect(rtFill);
223 rtFill.left = rtFill.top = 0;
224 FX_FLOAT fLineWith = GetLineWidth();
225 rtFill.Deflate(fLineWith, fLineWith);
226 CFX_Color cr(FXARGB_MAKE(128, 128, 255, 255));
227 pGraphics->SetFillColor(&cr);
228 CFX_Path path;
229 path.Create();
230 path.AddRectangle(rtFill.left, rtFill.top, rtFill.width, rtFill.height);
231 pGraphics->FillPath(&path, FXFILL_WINDING, (CFX_Matrix*)pMatrix);
232 }
233 } else if (m_pNormalWidget->GetStylesEx() &
234 XFA_FWL_PSBSTYLEEXT_HiliteOutLine) {
235 if ((m_pNormalWidget->GetStates() & FWL_STATE_PSB_Pressed) &&
236 (m_pNormalWidget->GetStates() & FWL_STATE_PSB_Hovered)) {
237 FX_FLOAT fLineWidth = GetLineWidth();
238 CFX_Color cr(FXARGB_MAKE(255, 128, 255, 255));
239 pGraphics->SetStrokeColor(&cr);
240 pGraphics->SetLineWidth(fLineWidth);
241 CFX_Path path;
242 path.Create();
243 CFX_RectF rect;
244 m_pNormalWidget->GetWidgetRect(rect);
245 path.AddRectangle(0, 0, rect.width, rect.height);
246 pGraphics->StrokePath(&path, (CFX_Matrix*)pMatrix);
247 }
248 } else if (m_pNormalWidget->GetStylesEx() & XFA_FWL_PSBSTYLEEXT_HilitePush) {
249 }
250 return FWL_ERR_Succeeded;
251 }
252