diff options
Diffstat (limited to 'xfa/fxfa/app/cxfa_ffpushbutton.cpp')
-rw-r--r-- | xfa/fxfa/app/cxfa_ffpushbutton.cpp | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/xfa/fxfa/app/cxfa_ffpushbutton.cpp b/xfa/fxfa/app/cxfa_ffpushbutton.cpp new file mode 100644 index 0000000000..1e784a496e --- /dev/null +++ b/xfa/fxfa/app/cxfa_ffpushbutton.cpp @@ -0,0 +1,240 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "xfa/fxfa/app/cxfa_ffpushbutton.h" + +#include <utility> + +#include "third_party/base/ptr_util.h" +#include "xfa/fwl/cfwl_notedriver.h" +#include "xfa/fwl/cfwl_pushbutton.h" +#include "xfa/fwl/cfwl_widgetmgr.h" +#include "xfa/fxfa/app/cxfa_fffield.h" +#include "xfa/fxfa/app/cxfa_textlayout.h" +#include "xfa/fxfa/app/cxfa_textprovider.h" +#include "xfa/fxfa/cxfa_ffapp.h" +#include "xfa/fxfa/cxfa_ffpageview.h" +#include "xfa/fxfa/cxfa_ffwidget.h" +#include "xfa/fxgraphics/cfx_color.h" +#include "xfa/fxgraphics/cfx_path.h" + +CXFA_FFPushButton::CXFA_FFPushButton(CXFA_WidgetAcc* pDataAcc) + : CXFA_FFField(pDataAcc), m_pOldDelegate(nullptr) {} + +CXFA_FFPushButton::~CXFA_FFPushButton() { + CXFA_FFPushButton::UnloadWidget(); +} + +void CXFA_FFPushButton::RenderWidget(CFX_Graphics* pGS, + CFX_Matrix* pMatrix, + uint32_t dwStatus) { + if (!IsMatchVisibleStatus(dwStatus)) + return; + + CFX_Matrix mtRotate = GetRotateMatrix(); + if (pMatrix) + mtRotate.Concat(*pMatrix); + + CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus); + RenderHighlightCaption(pGS, &mtRotate); + + CFX_RectF rtWidget = GetRectWithoutRotate(); + CFX_Matrix mt(1, 0, 0, 1, rtWidget.left, rtWidget.top); + mt.Concat(mtRotate); + GetApp()->GetWidgetMgrDelegate()->OnDrawWidget(m_pNormalWidget.get(), pGS, + &mt); +} + +bool CXFA_FFPushButton::LoadWidget() { + ASSERT(!m_pNormalWidget); + auto pNew = pdfium::MakeUnique<CFWL_PushButton>(GetFWLApp()); + CFWL_PushButton* pPushButton = pNew.get(); + m_pOldDelegate = pPushButton->GetDelegate(); + pPushButton->SetDelegate(this); + m_pNormalWidget = std::move(pNew); + m_pNormalWidget->SetLayoutItem(this); + + CFWL_NoteDriver* pNoteDriver = + m_pNormalWidget->GetOwnerApp()->GetNoteDriver(); + pNoteDriver->RegisterEventTarget(m_pNormalWidget.get(), + m_pNormalWidget.get()); + m_pNormalWidget->LockUpdate(); + UpdateWidgetProperty(); + LoadHighlightCaption(); + m_pNormalWidget->UnlockUpdate(); + return CXFA_FFField::LoadWidget(); +} + +void CXFA_FFPushButton::UpdateWidgetProperty() { + uint32_t dwStyleEx = 0; + switch (m_pDataAcc->GetButtonHighlight()) { + case XFA_ATTRIBUTEENUM_Inverted: + dwStyleEx = XFA_FWL_PSBSTYLEEXT_HiliteInverted; + break; + case XFA_ATTRIBUTEENUM_Outline: + dwStyleEx = XFA_FWL_PSBSTYLEEXT_HiliteOutLine; + break; + case XFA_ATTRIBUTEENUM_Push: + dwStyleEx = XFA_FWL_PSBSTYLEEXT_HilitePush; + break; + default: + break; + } + m_pNormalWidget->ModifyStylesEx(dwStyleEx, 0xFFFFFFFF); +} + +void CXFA_FFPushButton::UnloadWidget() { + m_pRolloverTextLayout.reset(); + m_pDownTextLayout.reset(); + m_pRollProvider.reset(); + m_pDownProvider.reset(); + CXFA_FFField::UnloadWidget(); +} + +bool CXFA_FFPushButton::PerformLayout() { + CXFA_FFWidget::PerformLayout(); + CFX_RectF rtWidget = GetRectWithoutRotate(); + + m_rtUI = rtWidget; + if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) + XFA_RectWidthoutMargin(rtWidget, mgWidget); + + CXFA_Caption caption = m_pDataAcc->GetCaption(); + m_rtCaption = rtWidget; + if (CXFA_Margin mgCap = caption.GetMargin()) + XFA_RectWidthoutMargin(m_rtCaption, mgCap); + + LayoutHighlightCaption(); + SetFWLRect(); + if (m_pNormalWidget) + m_pNormalWidget->Update(); + + return true; +} +float CXFA_FFPushButton::GetLineWidth() { + CXFA_Border border = m_pDataAcc->GetBorder(false); + if (border && border.GetPresence() == XFA_ATTRIBUTEENUM_Visible) { + CXFA_Edge edge = border.GetEdge(0); + return edge.GetThickness(); + } + return 0; +} + +FX_ARGB CXFA_FFPushButton::GetLineColor() { + return 0xFF000000; +} + +FX_ARGB CXFA_FFPushButton::GetFillColor() { + return 0xFFFFFFFF; +} + +void CXFA_FFPushButton::LoadHighlightCaption() { + CXFA_Caption caption = m_pDataAcc->GetCaption(); + if (!caption || caption.GetPresence() == XFA_ATTRIBUTEENUM_Hidden) + return; + + bool bRichText; + CFX_WideString wsRollover; + if (m_pDataAcc->GetButtonRollover(wsRollover, bRichText)) { + if (!m_pRollProvider) { + m_pRollProvider = pdfium::MakeUnique<CXFA_TextProvider>( + m_pDataAcc.Get(), XFA_TEXTPROVIDERTYPE_Rollover); + } + m_pRolloverTextLayout = + pdfium::MakeUnique<CXFA_TextLayout>(m_pRollProvider.get()); + } + CFX_WideString wsDown; + if (m_pDataAcc->GetButtonDown(wsDown, bRichText)) { + if (!m_pDownProvider) { + m_pDownProvider = pdfium::MakeUnique<CXFA_TextProvider>( + m_pDataAcc.Get(), XFA_TEXTPROVIDERTYPE_Down); + } + m_pDownTextLayout = + pdfium::MakeUnique<CXFA_TextLayout>(m_pDownProvider.get()); + } +} + +void CXFA_FFPushButton::LayoutHighlightCaption() { + CFX_SizeF sz(m_rtCaption.width, m_rtCaption.height); + LayoutCaption(); + if (m_pRolloverTextLayout) + m_pRolloverTextLayout->Layout(sz); + if (m_pDownTextLayout) + m_pDownTextLayout->Layout(sz); +} + +void CXFA_FFPushButton::RenderHighlightCaption(CFX_Graphics* pGS, + CFX_Matrix* pMatrix) { + CXFA_TextLayout* pCapTextLayout = m_pDataAcc->GetCaptionTextLayout(); + CXFA_Caption caption = m_pDataAcc->GetCaption(); + if (!caption || caption.GetPresence() != XFA_ATTRIBUTEENUM_Visible) + return; + + CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice(); + CFX_RectF rtClip = m_rtCaption; + rtClip.Intersect(GetRectWithoutRotate()); + CFX_Matrix mt(1, 0, 0, 1, m_rtCaption.left, m_rtCaption.top); + if (pMatrix) { + pMatrix->TransformRect(rtClip); + mt.Concat(*pMatrix); + } + + uint32_t dwState = m_pNormalWidget->GetStates(); + if (m_pDownTextLayout && (dwState & FWL_STATE_PSB_Pressed) && + (dwState & FWL_STATE_PSB_Hovered)) { + if (m_pDownTextLayout->DrawString(pRenderDevice, mt, rtClip)) + return; + } else if (m_pRolloverTextLayout && (dwState & FWL_STATE_PSB_Hovered)) { + if (m_pRolloverTextLayout->DrawString(pRenderDevice, mt, rtClip)) + return; + } + + if (pCapTextLayout) + pCapTextLayout->DrawString(pRenderDevice, mt, rtClip); +} + +void CXFA_FFPushButton::OnProcessMessage(CFWL_Message* pMessage) { + m_pOldDelegate->OnProcessMessage(pMessage); +} + +void CXFA_FFPushButton::OnProcessEvent(CFWL_Event* pEvent) { + m_pOldDelegate->OnProcessEvent(pEvent); + CXFA_FFField::OnProcessEvent(pEvent); +} + +void CXFA_FFPushButton::OnDrawWidget(CFX_Graphics* pGraphics, + const CFX_Matrix* pMatrix) { + if (m_pNormalWidget->GetStylesEx() & XFA_FWL_PSBSTYLEEXT_HiliteInverted) { + if ((m_pNormalWidget->GetStates() & FWL_STATE_PSB_Pressed) && + (m_pNormalWidget->GetStates() & FWL_STATE_PSB_Hovered)) { + CFX_RectF rtFill(0, 0, m_pNormalWidget->GetWidgetRect().Size()); + float fLineWith = GetLineWidth(); + rtFill.Deflate(fLineWith, fLineWith); + CFX_Color cr(FXARGB_MAKE(128, 128, 255, 255)); + pGraphics->SetFillColor(&cr); + + CFX_Path path; + path.AddRectangle(rtFill.left, rtFill.top, rtFill.width, rtFill.height); + pGraphics->FillPath(&path, FXFILL_WINDING, (CFX_Matrix*)pMatrix); + } + return; + } + + if (m_pNormalWidget->GetStylesEx() & XFA_FWL_PSBSTYLEEXT_HiliteOutLine) { + if ((m_pNormalWidget->GetStates() & FWL_STATE_PSB_Pressed) && + (m_pNormalWidget->GetStates() & FWL_STATE_PSB_Hovered)) { + float fLineWidth = GetLineWidth(); + CFX_Color cr(FXARGB_MAKE(255, 128, 255, 255)); + pGraphics->SetStrokeColor(&cr); + pGraphics->SetLineWidth(fLineWidth); + + CFX_Path path; + CFX_RectF rect = m_pNormalWidget->GetWidgetRect(); + path.AddRectangle(0, 0, rect.width, rect.height); + pGraphics->StrokePath(&path, (CFX_Matrix*)pMatrix); + } + } +} |