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