Home | History | Annotate | Download | only in app
      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 
     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 
     29 CXFA_FFPushButton::~CXFA_FFPushButton() {
     30   CXFA_FFPushButton::UnloadWidget();
     31 }
     32 
     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 
     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 }
     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 
     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 
    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 }
    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;
    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 }
    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();
    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 
    198 void CXFA_FFPushButton::OnProcessMessage(CFWL_Message* pMessage) {
    199   m_pOldDelegate->OnProcessMessage(pMessage);
    200 }
    201 
    202 void CXFA_FFPushButton::OnProcessEvent(CFWL_Event* pEvent) {
    203   m_pOldDelegate->OnProcessEvent(pEvent);
    204   CXFA_FFField::OnProcessEvent(pEvent);
    205 }
    206 
    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