cfwl_form.cpp revision 4d3acf4ec42bf6e838f9060103aff98fbf170794
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/fwl/cfwl_form.h" 8 9#include <utility> 10 11#include "third_party/base/ptr_util.h" 12#include "xfa/fde/tto/fde_textout.h" 13#include "xfa/fwl/cfwl_app.h" 14#include "xfa/fwl/cfwl_event.h" 15#include "xfa/fwl/cfwl_formproxy.h" 16#include "xfa/fwl/cfwl_messagemouse.h" 17#include "xfa/fwl/cfwl_notedriver.h" 18#include "xfa/fwl/cfwl_noteloop.h" 19#include "xfa/fwl/cfwl_themebackground.h" 20#include "xfa/fwl/cfwl_themepart.h" 21#include "xfa/fwl/cfwl_themetext.h" 22#include "xfa/fwl/cfwl_widgetmgr.h" 23#include "xfa/fwl/ifwl_themeprovider.h" 24#include "xfa/fwl/theme/cfwl_widgettp.h" 25 26CFWL_Form::CFWL_Form(const CFWL_App* app, 27 std::unique_ptr<CFWL_WidgetProperties> properties, 28 CFWL_Widget* pOuter) 29 : CFWL_Widget(app, std::move(properties), pOuter), 30 m_pSubFocus(nullptr), 31 m_fCXBorder(0), 32 m_fCYBorder(0) { 33 m_rtRelative.Reset(); 34 m_rtRestore.Reset(); 35 36 RegisterForm(); 37 RegisterEventTarget(nullptr); 38} 39 40CFWL_Form::~CFWL_Form() { 41 UnregisterEventTarget(); 42 UnRegisterForm(); 43} 44 45FWL_Type CFWL_Form::GetClassID() const { 46 return FWL_Type::Form; 47} 48 49bool CFWL_Form::IsInstance(const CFX_WideStringC& wsClass) const { 50 if (wsClass == CFX_WideStringC(FWL_CLASS_Form)) 51 return true; 52 return CFWL_Widget::IsInstance(wsClass); 53} 54 55CFX_RectF CFWL_Form::GetClientRect() { 56 CFX_RectF rect = m_pProperties->m_rtWidget; 57 rect.Offset(-rect.left, -rect.top); 58 return rect; 59} 60 61void CFWL_Form::Update() { 62 if (m_iLock > 0) 63 return; 64 if (!m_pProperties->m_pThemeProvider) 65 m_pProperties->m_pThemeProvider = GetAvailableTheme(); 66 67 Layout(); 68} 69 70FWL_WidgetHit CFWL_Form::HitTest(FX_FLOAT fx, FX_FLOAT fy) { 71 GetAvailableTheme(); 72 73 CFX_RectF rtCap; 74 rtCap.Set(m_fCYBorder, m_fCXBorder, -2 * m_fCYBorder, 0 - m_fCXBorder); 75 return rtCap.Contains(fx, fy) ? FWL_WidgetHit::Titlebar 76 : FWL_WidgetHit::Client; 77} 78 79void CFWL_Form::DrawWidget(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix) { 80 if (!pGraphics) 81 return; 82 if (!m_pProperties->m_pThemeProvider) 83 return; 84 85 IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider; 86 DrawBackground(pGraphics, pTheme); 87 88#ifdef FWL_UseMacSystemBorder 89 return; 90#endif 91 CFWL_ThemeBackground param; 92 param.m_pWidget = this; 93 param.m_dwStates = CFWL_PartState_Normal; 94 param.m_pGraphics = pGraphics; 95 param.m_rtPart = m_rtRelative; 96 if (pMatrix) 97 param.m_matrix.Concat(*pMatrix); 98 if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_Border) { 99 param.m_iPart = CFWL_Part::Border; 100 pTheme->DrawBackground(¶m); 101 } 102} 103 104CFWL_Widget* CFWL_Form::DoModal() { 105 const CFWL_App* pApp = GetOwnerApp(); 106 if (!pApp) 107 return nullptr; 108 109 CFWL_NoteDriver* pDriver = pApp->GetNoteDriver(); 110 if (!pDriver) 111 return nullptr; 112 113 m_pNoteLoop = pdfium::MakeUnique<CFWL_NoteLoop>(); 114 m_pNoteLoop->SetMainForm(this); 115 116 pDriver->PushNoteLoop(m_pNoteLoop.get()); 117 RemoveStates(FWL_WGTSTATE_Invisible); 118 pDriver->Run(); 119 120#if _FX_OS_ != _FX_MACOSX_ 121 pDriver->PopNoteLoop(); 122#endif 123 124 m_pNoteLoop.reset(); 125 return nullptr; 126} 127 128void CFWL_Form::EndDoModal() { 129 if (!m_pNoteLoop) 130 return; 131 132#if (_FX_OS_ == _FX_MACOSX_) 133 m_pNoteLoop->EndModalLoop(); 134 const CFWL_App* pApp = GetOwnerApp(); 135 if (!pApp) 136 return; 137 138 CFWL_NoteDriver* pDriver = 139 static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver()); 140 if (!pDriver) 141 return; 142 143 pDriver->PopNoteLoop(); 144 SetStates(FWL_WGTSTATE_Invisible); 145#else 146 SetStates(FWL_WGTSTATE_Invisible); 147 m_pNoteLoop->EndModalLoop(); 148#endif 149} 150 151void CFWL_Form::DrawBackground(CFX_Graphics* pGraphics, 152 IFWL_ThemeProvider* pTheme) { 153 CFWL_ThemeBackground param; 154 param.m_pWidget = this; 155 param.m_iPart = CFWL_Part::Background; 156 param.m_pGraphics = pGraphics; 157 param.m_rtPart = m_rtRelative; 158 param.m_rtPart.Deflate(m_fCYBorder, m_fCXBorder, m_fCYBorder, m_fCXBorder); 159 pTheme->DrawBackground(¶m); 160} 161 162CFX_RectF CFWL_Form::GetEdgeRect() { 163 CFX_RectF rtEdge = m_rtRelative; 164 if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_Border) { 165 FX_FLOAT fCX = GetBorderSize(true); 166 FX_FLOAT fCY = GetBorderSize(false); 167 rtEdge.Deflate(fCX, fCY, fCX, fCY); 168 } 169 return rtEdge; 170} 171 172void CFWL_Form::SetWorkAreaRect() { 173 m_rtRestore = m_pProperties->m_rtWidget; 174 CFWL_WidgetMgr* pWidgetMgr = GetOwnerApp()->GetWidgetMgr(); 175 if (!pWidgetMgr) 176 return; 177 RepaintRect(m_rtRelative); 178} 179 180void CFWL_Form::Layout() { 181 m_rtRelative = GetRelativeRect(); 182 183#ifndef FWL_UseMacSystemBorder 184 IFWL_ThemeProvider* theme = GetAvailableTheme(); 185 m_fCXBorder = theme ? theme->GetCXBorderSize() : 0.0f; 186 m_fCYBorder = theme ? theme->GetCYBorderSize() : 0.0f; 187#endif 188} 189 190void CFWL_Form::RegisterForm() { 191 const CFWL_App* pApp = GetOwnerApp(); 192 if (!pApp) 193 return; 194 195 CFWL_NoteDriver* pDriver = 196 static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver()); 197 if (!pDriver) 198 return; 199 200 pDriver->RegisterForm(this); 201} 202 203void CFWL_Form::UnRegisterForm() { 204 const CFWL_App* pApp = GetOwnerApp(); 205 if (!pApp) 206 return; 207 208 CFWL_NoteDriver* pDriver = 209 static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver()); 210 if (!pDriver) 211 return; 212 213 pDriver->UnRegisterForm(this); 214} 215 216void CFWL_Form::OnProcessMessage(CFWL_Message* pMessage) { 217#ifndef FWL_UseMacSystemBorder 218 if (!pMessage) 219 return; 220 221 switch (pMessage->GetType()) { 222 case CFWL_Message::Type::Mouse: { 223 CFWL_MessageMouse* pMsg = static_cast<CFWL_MessageMouse*>(pMessage); 224 switch (pMsg->m_dwCmd) { 225 case FWL_MouseCommand::LeftButtonDown: 226 OnLButtonDown(pMsg); 227 break; 228 case FWL_MouseCommand::LeftButtonUp: 229 OnLButtonUp(pMsg); 230 break; 231 default: 232 break; 233 } 234 break; 235 } 236 default: 237 break; 238 } 239#endif // FWL_UseMacSystemBorder 240} 241 242void CFWL_Form::OnDrawWidget(CFX_Graphics* pGraphics, 243 const CFX_Matrix* pMatrix) { 244 DrawWidget(pGraphics, pMatrix); 245} 246 247void CFWL_Form::OnLButtonDown(CFWL_MessageMouse* pMsg) { 248 SetGrab(true); 249} 250 251void CFWL_Form::OnLButtonUp(CFWL_MessageMouse* pMsg) { 252 SetGrab(false); 253} 254