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
CFWL_Form(const CFWL_App * app,std::unique_ptr<CFWL_WidgetProperties> properties,CFWL_Widget * pOuter)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
~CFWL_Form()39 CFWL_Form::~CFWL_Form() {
40 UnregisterEventTarget();
41 UnRegisterForm();
42 }
43
GetClassID() const44 FWL_Type CFWL_Form::GetClassID() const {
45 return FWL_Type::Form;
46 }
47
IsInstance(const WideStringView & wsClass) const48 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
GetClientRect()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
Update()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
HitTest(const CFX_PointF & point)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
DrawWidget(CXFA_Graphics * pGraphics,const CFX_Matrix & matrix)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
DoModal()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
EndDoModal()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
DrawBackground(CXFA_Graphics * pGraphics,IFWL_ThemeProvider * pTheme)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
GetEdgeRect()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
SetWorkAreaRect()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
Layout()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
RegisterForm()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
UnRegisterForm()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
OnProcessMessage(CFWL_Message * pMessage)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
OnDrawWidget(CXFA_Graphics * pGraphics,const CFX_Matrix & matrix)239 void CFWL_Form::OnDrawWidget(CXFA_Graphics* pGraphics,
240 const CFX_Matrix& matrix) {
241 DrawWidget(pGraphics, matrix);
242 }
243
OnLButtonDown(CFWL_MessageMouse * pMsg)244 void CFWL_Form::OnLButtonDown(CFWL_MessageMouse* pMsg) {
245 SetGrab(true);
246 }
247
OnLButtonUp(CFWL_MessageMouse * pMsg)248 void CFWL_Form::OnLButtonUp(CFWL_MessageMouse* pMsg) {
249 SetGrab(false);
250 }
251