• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
CFWL_Form(const CFWL_App * app,std::unique_ptr<CFWL_WidgetProperties> properties,CFWL_Widget * pOuter)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 
~CFWL_Form()40 CFWL_Form::~CFWL_Form() {
41   UnregisterEventTarget();
42   UnRegisterForm();
43 }
44 
GetClassID() const45 FWL_Type CFWL_Form::GetClassID() const {
46   return FWL_Type::Form;
47 }
48 
IsInstance(const CFX_WideStringC & wsClass) const49 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 
GetClientRect()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 
Update()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 
HitTest(const CFX_PointF & point)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 
DrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)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(&param);
100   }
101 }
102 
DoModal()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 
EndDoModal()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 
DrawBackground(CFX_Graphics * pGraphics,IFWL_ThemeProvider * pTheme)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(&param);
159 }
160 
GetEdgeRect()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 
SetWorkAreaRect()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 
Layout()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 
RegisterForm()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 
UnRegisterForm()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 
OnProcessMessage(CFWL_Message * pMessage)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 
OnDrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)241 void CFWL_Form::OnDrawWidget(CFX_Graphics* pGraphics,
242                              const CFX_Matrix* pMatrix) {
243   DrawWidget(pGraphics, pMatrix);
244 }
245 
OnLButtonDown(CFWL_MessageMouse * pMsg)246 void CFWL_Form::OnLButtonDown(CFWL_MessageMouse* pMsg) {
247   SetGrab(true);
248 }
249 
OnLButtonUp(CFWL_MessageMouse * pMsg)250 void CFWL_Form::OnLButtonUp(CFWL_MessageMouse* pMsg) {
251   SetGrab(false);
252 }
253