blob: 7b6be8203565a21131c7c1ff64415323b3572237 [file] [log] [blame]
Dan Sinclair1770c022016-03-14 14:14:16 -04001// 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
dsinclair447b1f32016-12-08 10:06:32 -08009#include "xfa/fwl/cfwl_notedriver.h"
10#include "xfa/fwl/cfwl_pushbutton.h"
11#include "xfa/fwl/cfwl_widgetmgr.h"
Dan Sinclair1f5d4982017-01-10 16:37:32 -050012#include "xfa/fxfa/app/cxfa_textlayout.h"
Dan Sinclair1770c022016-03-14 14:14:16 -040013#include "xfa/fxfa/app/xfa_fffield.h"
Dan Sinclair1770c022016-03-14 14:14:16 -040014#include "xfa/fxfa/app/xfa_ffwidgetacc.h"
dsinclair5b493092016-09-29 20:20:24 -070015#include "xfa/fxfa/xfa_ffapp.h"
16#include "xfa/fxfa/xfa_ffpageview.h"
17#include "xfa/fxfa/xfa_ffwidget.h"
Dan Sinclair811b8a42016-03-17 08:59:42 -040018#include "xfa/fxgraphics/cfx_color.h"
19#include "xfa/fxgraphics/cfx_path.h"
Dan Sinclair1770c022016-03-14 14:14:16 -040020
dan sinclairaaf0bdc2017-02-04 10:16:21 -050021CXFA_FFPushButton::CXFA_FFPushButton(CXFA_WidgetAcc* pDataAcc)
22 : CXFA_FFField(pDataAcc),
dsinclair85d1f2c2016-06-23 12:40:16 -070023 m_pRolloverTextLayout(nullptr),
24 m_pDownTextLayout(nullptr),
25 m_pDownProvider(nullptr),
26 m_pRollProvider(nullptr),
27 m_pOldDelegate(nullptr) {}
dan sinclairaaf0bdc2017-02-04 10:16:21 -050028
Dan Sinclair1770c022016-03-14 14:14:16 -040029CXFA_FFPushButton::~CXFA_FFPushButton() {
30 CXFA_FFPushButton::UnloadWidget();
31}
dan sinclairaaf0bdc2017-02-04 10:16:21 -050032
Dan Sinclair1770c022016-03-14 14:14:16 -040033void CXFA_FFPushButton::RenderWidget(CFX_Graphics* pGS,
34 CFX_Matrix* pMatrix,
dsinclair9d6ca992016-06-16 10:51:56 -070035 uint32_t dwStatus) {
Dan Sinclair1b08df12017-02-09 09:17:20 -050036 if (!IsMatchVisibleStatus(dwStatus))
Dan Sinclair1770c022016-03-14 14:14:16 -040037 return;
Dan Sinclair1b08df12017-02-09 09:17:20 -050038
39 CFX_Matrix mtRotate = GetRotateMatrix();
40 if (pMatrix)
Dan Sinclair1770c022016-03-14 14:14:16 -040041 mtRotate.Concat(*pMatrix);
Dan Sinclair1b08df12017-02-09 09:17:20 -050042
Dan Sinclair1770c022016-03-14 14:14:16 -040043 CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
44 RenderHighlightCaption(pGS, &mtRotate);
Dan Sinclairbba2a7c2017-02-07 16:36:39 -050045
Dan Sinclair1b08df12017-02-09 09:17:20 -050046 CFX_RectF rtWidget = GetRectWithoutRotate();
Dan Sinclairbba2a7c2017-02-07 16:36:39 -050047 CFX_Matrix mt(1, 0, 0, 1, rtWidget.left, rtWidget.top);
Dan Sinclair1770c022016-03-14 14:14:16 -040048 mt.Concat(mtRotate);
dsinclair2c489cc2016-11-23 16:17:20 -080049 GetApp()->GetWidgetMgrDelegate()->OnDrawWidget(m_pNormalWidget, pGS, &mt);
Dan Sinclair1770c022016-03-14 14:14:16 -040050}
Dan Sinclair1b08df12017-02-09 09:17:20 -050051
tsepezd19e9122016-11-02 15:43:18 -070052bool CXFA_FFPushButton::LoadWidget() {
dsinclair73223432016-04-28 10:51:13 -070053 ASSERT(!m_pNormalWidget);
dsinclair20855382016-10-31 07:29:34 -070054 CFWL_PushButton* pPushButton = new CFWL_PushButton(GetFWLApp());
dsinclair3b3ce1a2016-11-02 14:51:25 -070055 m_pOldDelegate = pPushButton->GetDelegate();
56 pPushButton->SetDelegate(this);
dsinclair9ec22172016-11-01 08:33:02 -070057
tsepez20d6b762016-06-09 11:46:16 -070058 m_pNormalWidget = pPushButton;
tsepez54ab2342016-05-26 17:35:54 -070059 m_pNormalWidget->SetLayoutItem(this);
dsinclair2c489cc2016-11-23 16:17:20 -080060
61 CFWL_NoteDriver* pNoteDriver =
62 m_pNormalWidget->GetOwnerApp()->GetNoteDriver();
63 pNoteDriver->RegisterEventTarget(m_pNormalWidget, m_pNormalWidget);
Dan Sinclair1770c022016-03-14 14:14:16 -040064 m_pNormalWidget->LockUpdate();
65 UpdateWidgetProperty();
66 LoadHighlightCaption();
67 m_pNormalWidget->UnlockUpdate();
68 return CXFA_FFField::LoadWidget();
69}
70void CXFA_FFPushButton::UpdateWidgetProperty() {
tsepez736f28a2016-03-25 14:19:51 -070071 uint32_t dwStyleEx = 0;
Dan Sinclair1770c022016-03-14 14:14:16 -040072 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}
thestig495bda12016-04-28 17:29:19 -070087
Dan Sinclair1770c022016-03-14 14:14:16 -040088void CXFA_FFPushButton::UnloadWidget() {
thestig495bda12016-04-28 17:29:19 -070089 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;
Dan Sinclair1770c022016-03-14 14:14:16 -040097 CXFA_FFField::UnloadWidget();
98}
thestig495bda12016-04-28 17:29:19 -070099
tsepezd19e9122016-11-02 15:43:18 -0700100bool CXFA_FFPushButton::PerformLayout() {
Dan Sinclair1770c022016-03-14 14:14:16 -0400101 CXFA_FFWidget::PerformLayout();
Dan Sinclair1b08df12017-02-09 09:17:20 -0500102 CFX_RectF rtWidget = GetRectWithoutRotate();
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500103
Dan Sinclair1770c022016-03-14 14:14:16 -0400104 m_rtUI = rtWidget;
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500105 if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin())
Dan Sinclair1770c022016-03-14 14:14:16 -0400106 XFA_RectWidthoutMargin(rtWidget, mgWidget);
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500107
Dan Sinclair1770c022016-03-14 14:14:16 -0400108 CXFA_Caption caption = m_pDataAcc->GetCaption();
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500109 m_rtCaption = rtWidget;
110 if (CXFA_Margin mgCap = caption.GetMargin())
Dan Sinclair1770c022016-03-14 14:14:16 -0400111 XFA_RectWidthoutMargin(m_rtCaption, mgCap);
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500112
Dan Sinclair1770c022016-03-14 14:14:16 -0400113 LayoutHighlightCaption();
114 SetFWLRect();
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500115 if (m_pNormalWidget)
Dan Sinclair1770c022016-03-14 14:14:16 -0400116 m_pNormalWidget->Update();
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500117
tsepezd19e9122016-11-02 15:43:18 -0700118 return true;
Dan Sinclair1770c022016-03-14 14:14:16 -0400119}
120FX_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}
128FX_ARGB CXFA_FFPushButton::GetLineColor() {
129 return 0xFF000000;
130}
131FX_ARGB CXFA_FFPushButton::GetFillColor() {
132 return 0xFFFFFFFF;
133}
134void CXFA_FFPushButton::LoadHighlightCaption() {
135 CXFA_Caption caption = m_pDataAcc->GetCaption();
136 if (caption && caption.GetPresence() != XFA_ATTRIBUTEENUM_Hidden) {
137 {
138 CFX_WideString wsRollover;
tsepezd19e9122016-11-02 15:43:18 -0700139 bool bRichText;
Dan Sinclair1770c022016-03-14 14:14:16 -0400140 if (m_pDataAcc->GetButtonRollover(wsRollover, bRichText)) {
dsinclair85d1f2c2016-06-23 12:40:16 -0700141 if (!m_pRollProvider) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400142 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)) {
dsinclair85d1f2c2016-06-23 12:40:16 -0700149 if (!m_pDownProvider) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400150 m_pDownProvider =
151 new CXFA_TextProvider(m_pDataAcc, XFA_TEXTPROVIDERTYPE_Down);
152 }
153 m_pDownTextLayout = new CXFA_TextLayout(m_pDownProvider);
154 }
155 }
156 }
157}
158void 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}
168void CXFA_FFPushButton::RenderHighlightCaption(CFX_Graphics* pGS,
169 CFX_Matrix* pMatrix) {
170 CXFA_TextLayout* pCapTextLayout = m_pDataAcc->GetCaptionTextLayout();
171 CXFA_Caption caption = m_pDataAcc->GetCaption();
Dan Sinclair1b08df12017-02-09 09:17:20 -0500172 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);
Dan Sinclair1770c022016-03-14 14:14:16 -0400182 }
Dan Sinclair1b08df12017-02-09 09:17:20 -0500183
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);
Dan Sinclair1770c022016-03-14 14:14:16 -0400196}
dsinclairc777f482016-05-04 17:57:03 -0700197
198void CXFA_FFPushButton::OnProcessMessage(CFWL_Message* pMessage) {
199 m_pOldDelegate->OnProcessMessage(pMessage);
Dan Sinclair1770c022016-03-14 14:14:16 -0400200}
dsinclairc777f482016-05-04 17:57:03 -0700201
202void CXFA_FFPushButton::OnProcessEvent(CFWL_Event* pEvent) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400203 m_pOldDelegate->OnProcessEvent(pEvent);
dsinclairc777f482016-05-04 17:57:03 -0700204 CXFA_FFField::OnProcessEvent(pEvent);
Dan Sinclair1770c022016-03-14 14:14:16 -0400205}
dsinclairc777f482016-05-04 17:57:03 -0700206
207void CXFA_FFPushButton::OnDrawWidget(CFX_Graphics* pGraphics,
208 const CFX_Matrix* pMatrix) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400209 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)) {
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500212 CFX_RectF rtFill(0, 0, m_pNormalWidget->GetWidgetRect().Size());
Dan Sinclair1770c022016-03-14 14:14:16 -0400213 FX_FLOAT fLineWith = GetLineWidth();
214 rtFill.Deflate(fLineWith, fLineWith);
215 CFX_Color cr(FXARGB_MAKE(128, 128, 255, 255));
216 pGraphics->SetFillColor(&cr);
Dan Sinclairefcf3622017-02-23 13:29:56 -0500217
Dan Sinclair1770c022016-03-14 14:14:16 -0400218 CFX_Path path;
Dan Sinclair1770c022016-03-14 14:14:16 -0400219 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);
dsinclairda911bc2016-12-07 18:47:00 -0800230
Dan Sinclairefcf3622017-02-23 13:29:56 -0500231 CFX_Path path;
dsinclairda911bc2016-12-07 18:47:00 -0800232 CFX_RectF rect = m_pNormalWidget->GetWidgetRect();
Dan Sinclair1770c022016-03-14 14:14:16 -0400233 path.AddRectangle(0, 0, rect.width, rect.height);
234 pGraphics->StrokePath(&path, (CFX_Matrix*)pMatrix);
235 }
Dan Sinclair1770c022016-03-14 14:14:16 -0400236 }
Dan Sinclair1770c022016-03-14 14:14:16 -0400237}