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