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/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