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" 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) {} 24 CXFA_FFPushButton::~CXFA_FFPushButton() { 25 CXFA_FFPushButton::UnloadWidget(); 26 } 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 } 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 } 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 } 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 } 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 } 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 } 132 FX_ARGB CXFA_FFPushButton::GetLineColor() { 133 return 0xFF000000; 134 } 135 FX_ARGB CXFA_FFPushButton::GetFillColor() { 136 return 0xFFFFFFFF; 137 } 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 } 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 } 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 } 209 int32_t CXFA_FFPushButton::OnProcessMessage(CFWL_Message* pMessage) { 210 return m_pOldDelegate->OnProcessMessage(pMessage); 211 } 212 FWL_ERR CXFA_FFPushButton::OnProcessEvent(CFWL_Event* pEvent) { 213 m_pOldDelegate->OnProcessEvent(pEvent); 214 return CXFA_FFField::OnProcessEvent(pEvent); 215 } 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