| // 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/fwl/cfwl_form.h" |
| |
| #include <utility> |
| |
| #include "third_party/base/ptr_util.h" |
| #include "xfa/fde/cfde_textout.h" |
| #include "xfa/fwl/cfwl_app.h" |
| #include "xfa/fwl/cfwl_event.h" |
| #include "xfa/fwl/cfwl_formproxy.h" |
| #include "xfa/fwl/cfwl_messagemouse.h" |
| #include "xfa/fwl/cfwl_notedriver.h" |
| #include "xfa/fwl/cfwl_noteloop.h" |
| #include "xfa/fwl/cfwl_themebackground.h" |
| #include "xfa/fwl/cfwl_themepart.h" |
| #include "xfa/fwl/cfwl_themetext.h" |
| #include "xfa/fwl/cfwl_widgetmgr.h" |
| #include "xfa/fwl/ifwl_themeprovider.h" |
| #include "xfa/fwl/theme/cfwl_widgettp.h" |
| |
| CFWL_Form::CFWL_Form(const CFWL_App* app, |
| std::unique_ptr<CFWL_WidgetProperties> properties, |
| CFWL_Widget* pOuter) |
| : CFWL_Widget(app, std::move(properties), pOuter), |
| m_pSubFocus(nullptr), |
| m_fCXBorder(0), |
| m_fCYBorder(0) { |
| m_rtRelative.Reset(); |
| m_rtRestore.Reset(); |
| |
| RegisterForm(); |
| RegisterEventTarget(nullptr); |
| } |
| |
| CFWL_Form::~CFWL_Form() { |
| UnregisterEventTarget(); |
| UnRegisterForm(); |
| } |
| |
| FWL_Type CFWL_Form::GetClassID() const { |
| return FWL_Type::Form; |
| } |
| |
| bool CFWL_Form::IsInstance(const CFX_WideStringC& wsClass) const { |
| if (wsClass == CFX_WideStringC(FWL_CLASS_Form)) |
| return true; |
| return CFWL_Widget::IsInstance(wsClass); |
| } |
| |
| CFX_RectF CFWL_Form::GetClientRect() { |
| CFX_RectF rect = m_pProperties->m_rtWidget; |
| rect.Offset(-rect.left, -rect.top); |
| return rect; |
| } |
| |
| void CFWL_Form::Update() { |
| if (m_iLock > 0) |
| return; |
| if (!m_pProperties->m_pThemeProvider) |
| m_pProperties->m_pThemeProvider = GetAvailableTheme(); |
| |
| Layout(); |
| } |
| |
| FWL_WidgetHit CFWL_Form::HitTest(const CFX_PointF& point) { |
| GetAvailableTheme(); |
| |
| CFX_RectF rtCap(m_fCYBorder, m_fCXBorder, -2 * m_fCYBorder, 0 - m_fCXBorder); |
| return rtCap.Contains(point) ? FWL_WidgetHit::Titlebar |
| : FWL_WidgetHit::Client; |
| } |
| |
| void CFWL_Form::DrawWidget(CXFA_Graphics* pGraphics, |
| const CFX_Matrix* pMatrix) { |
| if (!pGraphics) |
| return; |
| if (!m_pProperties->m_pThemeProvider) |
| return; |
| |
| IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider; |
| DrawBackground(pGraphics, pTheme); |
| |
| #ifdef FWL_UseMacSystemBorder |
| return; |
| #endif |
| CFWL_ThemeBackground param; |
| param.m_pWidget = this; |
| param.m_dwStates = CFWL_PartState_Normal; |
| param.m_pGraphics = pGraphics; |
| param.m_rtPart = m_rtRelative; |
| if (pMatrix) |
| param.m_matrix.Concat(*pMatrix); |
| if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_Border) { |
| param.m_iPart = CFWL_Part::Border; |
| pTheme->DrawBackground(¶m); |
| } |
| } |
| |
| CFWL_Widget* CFWL_Form::DoModal() { |
| const CFWL_App* pApp = GetOwnerApp(); |
| if (!pApp) |
| return nullptr; |
| |
| CFWL_NoteDriver* pDriver = pApp->GetNoteDriver(); |
| if (!pDriver) |
| return nullptr; |
| |
| m_pNoteLoop = pdfium::MakeUnique<CFWL_NoteLoop>(); |
| m_pNoteLoop->SetMainForm(this); |
| |
| pDriver->PushNoteLoop(m_pNoteLoop.get()); |
| RemoveStates(FWL_WGTSTATE_Invisible); |
| pDriver->Run(); |
| |
| #if _FX_OS_ != _FX_MACOSX_ |
| pDriver->PopNoteLoop(); |
| #endif |
| |
| m_pNoteLoop.reset(); |
| return nullptr; |
| } |
| |
| void CFWL_Form::EndDoModal() { |
| if (!m_pNoteLoop) |
| return; |
| |
| #if (_FX_OS_ == _FX_MACOSX_) |
| m_pNoteLoop->EndModalLoop(); |
| const CFWL_App* pApp = GetOwnerApp(); |
| if (!pApp) |
| return; |
| |
| CFWL_NoteDriver* pDriver = |
| static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver()); |
| if (!pDriver) |
| return; |
| |
| pDriver->PopNoteLoop(); |
| SetStates(FWL_WGTSTATE_Invisible); |
| #else |
| SetStates(FWL_WGTSTATE_Invisible); |
| m_pNoteLoop->EndModalLoop(); |
| #endif |
| } |
| |
| void CFWL_Form::DrawBackground(CXFA_Graphics* pGraphics, |
| IFWL_ThemeProvider* pTheme) { |
| CFWL_ThemeBackground param; |
| param.m_pWidget = this; |
| param.m_iPart = CFWL_Part::Background; |
| param.m_pGraphics = pGraphics; |
| param.m_rtPart = m_rtRelative; |
| param.m_rtPart.Deflate(m_fCYBorder, m_fCXBorder, m_fCYBorder, m_fCXBorder); |
| pTheme->DrawBackground(¶m); |
| } |
| |
| CFX_RectF CFWL_Form::GetEdgeRect() { |
| CFX_RectF rtEdge = m_rtRelative; |
| if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_Border) { |
| float fCX = GetBorderSize(true); |
| float fCY = GetBorderSize(false); |
| rtEdge.Deflate(fCX, fCY, fCX, fCY); |
| } |
| return rtEdge; |
| } |
| |
| void CFWL_Form::SetWorkAreaRect() { |
| m_rtRestore = m_pProperties->m_rtWidget; |
| CFWL_WidgetMgr* pWidgetMgr = GetOwnerApp()->GetWidgetMgr(); |
| if (!pWidgetMgr) |
| return; |
| RepaintRect(m_rtRelative); |
| } |
| |
| void CFWL_Form::Layout() { |
| m_rtRelative = GetRelativeRect(); |
| |
| #ifndef FWL_UseMacSystemBorder |
| IFWL_ThemeProvider* theme = GetAvailableTheme(); |
| m_fCXBorder = theme ? theme->GetCXBorderSize() : 0.0f; |
| m_fCYBorder = theme ? theme->GetCYBorderSize() : 0.0f; |
| #endif |
| } |
| |
| void CFWL_Form::RegisterForm() { |
| const CFWL_App* pApp = GetOwnerApp(); |
| if (!pApp) |
| return; |
| |
| CFWL_NoteDriver* pDriver = |
| static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver()); |
| if (!pDriver) |
| return; |
| |
| pDriver->RegisterForm(this); |
| } |
| |
| void CFWL_Form::UnRegisterForm() { |
| const CFWL_App* pApp = GetOwnerApp(); |
| if (!pApp) |
| return; |
| |
| CFWL_NoteDriver* pDriver = |
| static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver()); |
| if (!pDriver) |
| return; |
| |
| pDriver->UnRegisterForm(this); |
| } |
| |
| void CFWL_Form::OnProcessMessage(CFWL_Message* pMessage) { |
| #ifndef FWL_UseMacSystemBorder |
| if (!pMessage) |
| return; |
| |
| switch (pMessage->GetType()) { |
| case CFWL_Message::Type::Mouse: { |
| CFWL_MessageMouse* pMsg = static_cast<CFWL_MessageMouse*>(pMessage); |
| switch (pMsg->m_dwCmd) { |
| case FWL_MouseCommand::LeftButtonDown: |
| OnLButtonDown(pMsg); |
| break; |
| case FWL_MouseCommand::LeftButtonUp: |
| OnLButtonUp(pMsg); |
| break; |
| default: |
| break; |
| } |
| break; |
| } |
| default: |
| break; |
| } |
| #endif // FWL_UseMacSystemBorder |
| } |
| |
| void CFWL_Form::OnDrawWidget(CXFA_Graphics* pGraphics, |
| const CFX_Matrix* pMatrix) { |
| DrawWidget(pGraphics, pMatrix); |
| } |
| |
| void CFWL_Form::OnLButtonDown(CFWL_MessageMouse* pMsg) { |
| SetGrab(true); |
| } |
| |
| void CFWL_Form::OnLButtonUp(CFWL_MessageMouse* pMsg) { |
| SetGrab(false); |
| } |