Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 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 | |
dsinclair | 447b1f3 | 2016-12-08 10:06:32 -0800 | [diff] [blame] | 9 | #include "xfa/fwl/cfwl_notedriver.h" |
| 10 | #include "xfa/fwl/cfwl_pushbutton.h" |
| 11 | #include "xfa/fwl/cfwl_widgetmgr.h" |
Dan Sinclair | 1f5d498 | 2017-01-10 16:37:32 -0500 | [diff] [blame] | 12 | #include "xfa/fxfa/app/cxfa_textlayout.h" |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 13 | #include "xfa/fxfa/app/xfa_fffield.h" |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 14 | #include "xfa/fxfa/app/xfa_ffwidgetacc.h" |
dsinclair | 5b49309 | 2016-09-29 20:20:24 -0700 | [diff] [blame] | 15 | #include "xfa/fxfa/xfa_ffapp.h" |
| 16 | #include "xfa/fxfa/xfa_ffpageview.h" |
| 17 | #include "xfa/fxfa/xfa_ffwidget.h" |
Dan Sinclair | 811b8a4 | 2016-03-17 08:59:42 -0400 | [diff] [blame] | 18 | #include "xfa/fxgraphics/cfx_color.h" |
| 19 | #include "xfa/fxgraphics/cfx_path.h" |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 20 | |
dan sinclair | aaf0bdc | 2017-02-04 10:16:21 -0500 | [diff] [blame] | 21 | CXFA_FFPushButton::CXFA_FFPushButton(CXFA_WidgetAcc* pDataAcc) |
| 22 | : CXFA_FFField(pDataAcc), |
dsinclair | 85d1f2c | 2016-06-23 12:40:16 -0700 | [diff] [blame] | 23 | m_pRolloverTextLayout(nullptr), |
| 24 | m_pDownTextLayout(nullptr), |
| 25 | m_pDownProvider(nullptr), |
| 26 | m_pRollProvider(nullptr), |
| 27 | m_pOldDelegate(nullptr) {} |
dan sinclair | aaf0bdc | 2017-02-04 10:16:21 -0500 | [diff] [blame] | 28 | |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 29 | CXFA_FFPushButton::~CXFA_FFPushButton() { |
| 30 | CXFA_FFPushButton::UnloadWidget(); |
| 31 | } |
dan sinclair | aaf0bdc | 2017-02-04 10:16:21 -0500 | [diff] [blame] | 32 | |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 33 | void CXFA_FFPushButton::RenderWidget(CFX_Graphics* pGS, |
| 34 | CFX_Matrix* pMatrix, |
dsinclair | 9d6ca99 | 2016-06-16 10:51:56 -0700 | [diff] [blame] | 35 | uint32_t dwStatus) { |
Dan Sinclair | 1b08df1 | 2017-02-09 09:17:20 -0500 | [diff] [blame] | 36 | if (!IsMatchVisibleStatus(dwStatus)) |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 37 | return; |
Dan Sinclair | 1b08df1 | 2017-02-09 09:17:20 -0500 | [diff] [blame] | 38 | |
| 39 | CFX_Matrix mtRotate = GetRotateMatrix(); |
| 40 | if (pMatrix) |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 41 | mtRotate.Concat(*pMatrix); |
Dan Sinclair | 1b08df1 | 2017-02-09 09:17:20 -0500 | [diff] [blame] | 42 | |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 43 | CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus); |
| 44 | RenderHighlightCaption(pGS, &mtRotate); |
Dan Sinclair | bba2a7c | 2017-02-07 16:36:39 -0500 | [diff] [blame] | 45 | |
Dan Sinclair | 1b08df1 | 2017-02-09 09:17:20 -0500 | [diff] [blame] | 46 | CFX_RectF rtWidget = GetRectWithoutRotate(); |
Dan Sinclair | bba2a7c | 2017-02-07 16:36:39 -0500 | [diff] [blame] | 47 | CFX_Matrix mt(1, 0, 0, 1, rtWidget.left, rtWidget.top); |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 48 | mt.Concat(mtRotate); |
dsinclair | 2c489cc | 2016-11-23 16:17:20 -0800 | [diff] [blame] | 49 | GetApp()->GetWidgetMgrDelegate()->OnDrawWidget(m_pNormalWidget, pGS, &mt); |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 50 | } |
Dan Sinclair | 1b08df1 | 2017-02-09 09:17:20 -0500 | [diff] [blame] | 51 | |
tsepez | d19e912 | 2016-11-02 15:43:18 -0700 | [diff] [blame] | 52 | bool CXFA_FFPushButton::LoadWidget() { |
dsinclair | 7322343 | 2016-04-28 10:51:13 -0700 | [diff] [blame] | 53 | ASSERT(!m_pNormalWidget); |
dsinclair | 2085538 | 2016-10-31 07:29:34 -0700 | [diff] [blame] | 54 | CFWL_PushButton* pPushButton = new CFWL_PushButton(GetFWLApp()); |
dsinclair | 3b3ce1a | 2016-11-02 14:51:25 -0700 | [diff] [blame] | 55 | m_pOldDelegate = pPushButton->GetDelegate(); |
| 56 | pPushButton->SetDelegate(this); |
dsinclair | 9ec2217 | 2016-11-01 08:33:02 -0700 | [diff] [blame] | 57 | |
tsepez | 20d6b76 | 2016-06-09 11:46:16 -0700 | [diff] [blame] | 58 | m_pNormalWidget = pPushButton; |
tsepez | 54ab234 | 2016-05-26 17:35:54 -0700 | [diff] [blame] | 59 | m_pNormalWidget->SetLayoutItem(this); |
dsinclair | 2c489cc | 2016-11-23 16:17:20 -0800 | [diff] [blame] | 60 | |
| 61 | CFWL_NoteDriver* pNoteDriver = |
| 62 | m_pNormalWidget->GetOwnerApp()->GetNoteDriver(); |
| 63 | pNoteDriver->RegisterEventTarget(m_pNormalWidget, m_pNormalWidget); |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 64 | m_pNormalWidget->LockUpdate(); |
| 65 | UpdateWidgetProperty(); |
| 66 | LoadHighlightCaption(); |
| 67 | m_pNormalWidget->UnlockUpdate(); |
| 68 | return CXFA_FFField::LoadWidget(); |
| 69 | } |
| 70 | void CXFA_FFPushButton::UpdateWidgetProperty() { |
tsepez | 736f28a | 2016-03-25 14:19:51 -0700 | [diff] [blame] | 71 | uint32_t dwStyleEx = 0; |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 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 | } |
thestig | 495bda1 | 2016-04-28 17:29:19 -0700 | [diff] [blame] | 87 | |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 88 | void CXFA_FFPushButton::UnloadWidget() { |
thestig | 495bda1 | 2016-04-28 17:29:19 -0700 | [diff] [blame] | 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; |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 97 | CXFA_FFField::UnloadWidget(); |
| 98 | } |
thestig | 495bda1 | 2016-04-28 17:29:19 -0700 | [diff] [blame] | 99 | |
tsepez | d19e912 | 2016-11-02 15:43:18 -0700 | [diff] [blame] | 100 | bool CXFA_FFPushButton::PerformLayout() { |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 101 | CXFA_FFWidget::PerformLayout(); |
Dan Sinclair | 1b08df1 | 2017-02-09 09:17:20 -0500 | [diff] [blame] | 102 | CFX_RectF rtWidget = GetRectWithoutRotate(); |
Dan Sinclair | bba2a7c | 2017-02-07 16:36:39 -0500 | [diff] [blame] | 103 | |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 104 | m_rtUI = rtWidget; |
Dan Sinclair | bba2a7c | 2017-02-07 16:36:39 -0500 | [diff] [blame] | 105 | if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 106 | XFA_RectWidthoutMargin(rtWidget, mgWidget); |
Dan Sinclair | bba2a7c | 2017-02-07 16:36:39 -0500 | [diff] [blame] | 107 | |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 108 | CXFA_Caption caption = m_pDataAcc->GetCaption(); |
Dan Sinclair | bba2a7c | 2017-02-07 16:36:39 -0500 | [diff] [blame] | 109 | m_rtCaption = rtWidget; |
| 110 | if (CXFA_Margin mgCap = caption.GetMargin()) |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 111 | XFA_RectWidthoutMargin(m_rtCaption, mgCap); |
Dan Sinclair | bba2a7c | 2017-02-07 16:36:39 -0500 | [diff] [blame] | 112 | |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 113 | LayoutHighlightCaption(); |
| 114 | SetFWLRect(); |
Dan Sinclair | bba2a7c | 2017-02-07 16:36:39 -0500 | [diff] [blame] | 115 | if (m_pNormalWidget) |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 116 | m_pNormalWidget->Update(); |
Dan Sinclair | bba2a7c | 2017-02-07 16:36:39 -0500 | [diff] [blame] | 117 | |
tsepez | d19e912 | 2016-11-02 15:43:18 -0700 | [diff] [blame] | 118 | return true; |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 119 | } |
| 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 | } |
| 128 | FX_ARGB CXFA_FFPushButton::GetLineColor() { |
| 129 | return 0xFF000000; |
| 130 | } |
| 131 | FX_ARGB CXFA_FFPushButton::GetFillColor() { |
| 132 | return 0xFFFFFFFF; |
| 133 | } |
| 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; |
tsepez | d19e912 | 2016-11-02 15:43:18 -0700 | [diff] [blame] | 139 | bool bRichText; |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 140 | if (m_pDataAcc->GetButtonRollover(wsRollover, bRichText)) { |
dsinclair | 85d1f2c | 2016-06-23 12:40:16 -0700 | [diff] [blame] | 141 | if (!m_pRollProvider) { |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 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)) { |
dsinclair | 85d1f2c | 2016-06-23 12:40:16 -0700 | [diff] [blame] | 149 | if (!m_pDownProvider) { |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 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 | } |
| 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 | } |
| 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(); |
Dan Sinclair | 1b08df1 | 2017-02-09 09:17:20 -0500 | [diff] [blame] | 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); |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 182 | } |
Dan Sinclair | 1b08df1 | 2017-02-09 09:17:20 -0500 | [diff] [blame] | 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); |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 196 | } |
dsinclair | c777f48 | 2016-05-04 17:57:03 -0700 | [diff] [blame] | 197 | |
| 198 | void CXFA_FFPushButton::OnProcessMessage(CFWL_Message* pMessage) { |
| 199 | m_pOldDelegate->OnProcessMessage(pMessage); |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 200 | } |
dsinclair | c777f48 | 2016-05-04 17:57:03 -0700 | [diff] [blame] | 201 | |
| 202 | void CXFA_FFPushButton::OnProcessEvent(CFWL_Event* pEvent) { |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 203 | m_pOldDelegate->OnProcessEvent(pEvent); |
dsinclair | c777f48 | 2016-05-04 17:57:03 -0700 | [diff] [blame] | 204 | CXFA_FFField::OnProcessEvent(pEvent); |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 205 | } |
dsinclair | c777f48 | 2016-05-04 17:57:03 -0700 | [diff] [blame] | 206 | |
| 207 | void CXFA_FFPushButton::OnDrawWidget(CFX_Graphics* pGraphics, |
| 208 | const CFX_Matrix* pMatrix) { |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 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)) { |
Dan Sinclair | bba2a7c | 2017-02-07 16:36:39 -0500 | [diff] [blame] | 212 | CFX_RectF rtFill(0, 0, m_pNormalWidget->GetWidgetRect().Size()); |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 213 | FX_FLOAT fLineWith = GetLineWidth(); |
| 214 | rtFill.Deflate(fLineWith, fLineWith); |
| 215 | CFX_Color cr(FXARGB_MAKE(128, 128, 255, 255)); |
| 216 | pGraphics->SetFillColor(&cr); |
Dan Sinclair | efcf362 | 2017-02-23 13:29:56 -0500 | [diff] [blame] | 217 | |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 218 | CFX_Path path; |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 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); |
dsinclair | da911bc | 2016-12-07 18:47:00 -0800 | [diff] [blame] | 230 | |
Dan Sinclair | efcf362 | 2017-02-23 13:29:56 -0500 | [diff] [blame] | 231 | CFX_Path path; |
dsinclair | da911bc | 2016-12-07 18:47:00 -0800 | [diff] [blame] | 232 | CFX_RectF rect = m_pNormalWidget->GetWidgetRect(); |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 233 | path.AddRectangle(0, 0, rect.width, rect.height); |
| 234 | pGraphics->StrokePath(&path, (CFX_Matrix*)pMatrix); |
| 235 | } |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 236 | } |
Dan Sinclair | 1770c02 | 2016-03-14 14:14:16 -0400 | [diff] [blame] | 237 | } |