// 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" 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 WideStringView& wsClass) const { if (wsClass == WideStringView(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& matrix) { if (!pGraphics) return; if (!m_pProperties->m_pThemeProvider) return; IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider; DrawBackground(pGraphics, pTheme); #if _FX_OS_ == _FX_OS_MACOSX_ return; #endif CFWL_ThemeBackground param; param.m_pWidget = this; param.m_dwStates = CFWL_PartState_Normal; param.m_pGraphics = pGraphics; param.m_rtPart = m_rtRelative; param.m_matrix.Concat(matrix); 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_OS_MACOSX_ pDriver->PopNoteLoop(); #endif m_pNoteLoop.reset(); return nullptr; } void CFWL_Form::EndDoModal() { if (!m_pNoteLoop) return; #if (_FX_OS_ == _FX_OS_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(); #if _FX_OS_ == _FX_OS_MACOSX_ 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) { #if _FX_OS_ == _FX_OS_MACOSX_ 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 // _FX_OS_ == _FX_OS_MACOSX_ } void CFWL_Form::OnDrawWidget(CXFA_Graphics* pGraphics, const CFX_Matrix& matrix) { DrawWidget(pGraphics, matrix); } void CFWL_Form::OnLButtonDown(CFWL_MessageMouse* pMsg) { SetGrab(true); } void CFWL_Form::OnLButtonUp(CFWL_MessageMouse* pMsg) { SetGrab(false); }