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