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_widget.h"
8
9 #include <algorithm>
10 #include <utility>
11 #include <vector>
12
13 #include "third_party/base/stl_util.h"
14 #include "xfa/fde/cfde_textout.h"
15 #include "xfa/fwl/cfwl_app.h"
16 #include "xfa/fwl/cfwl_combobox.h"
17 #include "xfa/fwl/cfwl_event.h"
18 #include "xfa/fwl/cfwl_eventmouse.h"
19 #include "xfa/fwl/cfwl_form.h"
20 #include "xfa/fwl/cfwl_messagekey.h"
21 #include "xfa/fwl/cfwl_messagekillfocus.h"
22 #include "xfa/fwl/cfwl_messagemouse.h"
23 #include "xfa/fwl/cfwl_messagemousewheel.h"
24 #include "xfa/fwl/cfwl_messagesetfocus.h"
25 #include "xfa/fwl/cfwl_notedriver.h"
26 #include "xfa/fwl/cfwl_themebackground.h"
27 #include "xfa/fwl/cfwl_themepart.h"
28 #include "xfa/fwl/cfwl_themetext.h"
29 #include "xfa/fwl/cfwl_widgetmgr.h"
30 #include "xfa/fwl/ifwl_themeprovider.h"
31 #include "xfa/fxfa/cxfa_ffapp.h"
32
33 #define FWL_STYLEEXT_MNU_Vert (1L << 0)
34 #define FWL_WGT_CalcHeight 2048
35 #define FWL_WGT_CalcWidth 2048
36 #define FWL_WGT_CalcMultiLineDefWidth 120.0f
37
CFWL_Widget(const CFWL_App * app,std::unique_ptr<CFWL_WidgetProperties> properties,CFWL_Widget * pOuter)38 CFWL_Widget::CFWL_Widget(const CFWL_App* app,
39 std::unique_ptr<CFWL_WidgetProperties> properties,
40 CFWL_Widget* pOuter)
41 : m_pOwnerApp(app),
42 m_pWidgetMgr(app->GetWidgetMgr()),
43 m_pProperties(std::move(properties)),
44 m_pOuter(pOuter),
45 m_iLock(0),
46 m_pLayoutItem(nullptr),
47 m_nEventKey(0),
48 m_pDelegate(nullptr) {
49 ASSERT(m_pWidgetMgr);
50
51 CFWL_Widget* pParent = m_pProperties->m_pParent;
52 m_pWidgetMgr->InsertWidget(pParent, this);
53 if (IsChild())
54 return;
55
56 CFWL_Widget* pOwner = m_pProperties->m_pOwner;
57 if (pOwner)
58 m_pWidgetMgr->SetOwner(pOwner, this);
59 }
60
~CFWL_Widget()61 CFWL_Widget::~CFWL_Widget() {
62 NotifyDriver();
63 m_pWidgetMgr->RemoveWidget(this);
64 }
65
IsInstance(const WideStringView & wsClass) const66 bool CFWL_Widget::IsInstance(const WideStringView& wsClass) const {
67 return false;
68 }
69
GetAutosizedWidgetRect()70 CFX_RectF CFWL_Widget::GetAutosizedWidgetRect() {
71 return CFX_RectF();
72 }
73
GetWidgetRect()74 CFX_RectF CFWL_Widget::GetWidgetRect() {
75 return m_pProperties->m_rtWidget;
76 }
77
InflateWidgetRect(CFX_RectF & rect)78 void CFWL_Widget::InflateWidgetRect(CFX_RectF& rect) {
79 if (HasBorder()) {
80 float fBorder = GetBorderSize(true);
81 rect.Inflate(fBorder, fBorder);
82 }
83 }
84
SetWidgetRect(const CFX_RectF & rect)85 void CFWL_Widget::SetWidgetRect(const CFX_RectF& rect) {
86 m_pProperties->m_rtWidget = rect;
87 }
88
GetClientRect()89 CFX_RectF CFWL_Widget::GetClientRect() {
90 return GetEdgeRect();
91 }
92
SetParent(CFWL_Widget * pParent)93 void CFWL_Widget::SetParent(CFWL_Widget* pParent) {
94 m_pProperties->m_pParent = pParent;
95 m_pWidgetMgr->SetParent(pParent, this);
96 }
97
GetStyles() const98 uint32_t CFWL_Widget::GetStyles() const {
99 return m_pProperties->m_dwStyles;
100 }
101
ModifyStyles(uint32_t dwStylesAdded,uint32_t dwStylesRemoved)102 void CFWL_Widget::ModifyStyles(uint32_t dwStylesAdded,
103 uint32_t dwStylesRemoved) {
104 m_pProperties->m_dwStyles =
105 (m_pProperties->m_dwStyles & ~dwStylesRemoved) | dwStylesAdded;
106 }
107
GetStylesEx() const108 uint32_t CFWL_Widget::GetStylesEx() const {
109 return m_pProperties->m_dwStyleExes;
110 }
GetStates() const111 uint32_t CFWL_Widget::GetStates() const {
112 return m_pProperties->m_dwStates;
113 }
114
ModifyStylesEx(uint32_t dwStylesExAdded,uint32_t dwStylesExRemoved)115 void CFWL_Widget::ModifyStylesEx(uint32_t dwStylesExAdded,
116 uint32_t dwStylesExRemoved) {
117 m_pProperties->m_dwStyleExes =
118 (m_pProperties->m_dwStyleExes & ~dwStylesExRemoved) | dwStylesExAdded;
119 }
120
NotifyHideChildWidget(CFWL_WidgetMgr * widgetMgr,CFWL_Widget * widget,CFWL_NoteDriver * noteDriver)121 static void NotifyHideChildWidget(CFWL_WidgetMgr* widgetMgr,
122 CFWL_Widget* widget,
123 CFWL_NoteDriver* noteDriver) {
124 CFWL_Widget* child = widgetMgr->GetFirstChildWidget(widget);
125 while (child) {
126 noteDriver->NotifyTargetHide(child);
127 NotifyHideChildWidget(widgetMgr, child, noteDriver);
128 child = widgetMgr->GetNextSiblingWidget(child);
129 }
130 }
131
SetStates(uint32_t dwStates)132 void CFWL_Widget::SetStates(uint32_t dwStates) {
133 m_pProperties->m_dwStates |= dwStates;
134 if (!(dwStates & FWL_WGTSTATE_Invisible))
135 return;
136
137 CFWL_NoteDriver* noteDriver =
138 static_cast<CFWL_NoteDriver*>(GetOwnerApp()->GetNoteDriver());
139 CFWL_WidgetMgr* widgetMgr = GetOwnerApp()->GetWidgetMgr();
140 noteDriver->NotifyTargetHide(this);
141 CFWL_Widget* child = widgetMgr->GetFirstChildWidget(this);
142 while (child) {
143 noteDriver->NotifyTargetHide(child);
144 NotifyHideChildWidget(widgetMgr, child, noteDriver);
145 child = widgetMgr->GetNextSiblingWidget(child);
146 }
147 return;
148 }
149
RemoveStates(uint32_t dwStates)150 void CFWL_Widget::RemoveStates(uint32_t dwStates) {
151 m_pProperties->m_dwStates &= ~dwStates;
152 }
153
HitTest(const CFX_PointF & point)154 FWL_WidgetHit CFWL_Widget::HitTest(const CFX_PointF& point) {
155 if (GetClientRect().Contains(point))
156 return FWL_WidgetHit::Client;
157 if (HasBorder() && GetRelativeRect().Contains(point))
158 return FWL_WidgetHit::Border;
159 return FWL_WidgetHit::Unknown;
160 }
161
TransformTo(CFWL_Widget * pWidget,const CFX_PointF & point)162 CFX_PointF CFWL_Widget::TransformTo(CFWL_Widget* pWidget,
163 const CFX_PointF& point) {
164 if (m_pWidgetMgr->IsFormDisabled()) {
165 CFX_SizeF szOffset;
166 if (IsParent(pWidget)) {
167 szOffset = GetOffsetFromParent(pWidget);
168 } else {
169 szOffset = pWidget->GetOffsetFromParent(this);
170 szOffset.width = -szOffset.width;
171 szOffset.height = -szOffset.height;
172 }
173 return point + CFX_PointF(szOffset.width, szOffset.height);
174 }
175
176 CFX_PointF ret = point;
177 CFWL_Widget* parent = GetParent();
178 if (parent)
179 ret = GetMatrix().Transform(ret + GetWidgetRect().TopLeft());
180
181 CFWL_Widget* form1 = m_pWidgetMgr->GetSystemFormWidget(this);
182 if (!form1)
183 return ret;
184
185 if (!pWidget)
186 return ret + form1->GetWidgetRect().TopLeft();
187
188 CFWL_Widget* form2 = m_pWidgetMgr->GetSystemFormWidget(pWidget);
189 if (!form2)
190 return ret;
191 if (form1 != form2) {
192 ret += form1->GetWidgetRect().TopLeft();
193 ret -= form2->GetWidgetRect().TopLeft();
194 }
195
196 parent = pWidget->GetParent();
197 if (!parent)
198 return ret;
199
200 return pWidget->GetMatrix().GetInverse().Transform(ret) -
201 pWidget->GetWidgetRect().TopLeft();
202 }
203
GetMatrix()204 CFX_Matrix CFWL_Widget::GetMatrix() {
205 if (!m_pProperties)
206 return CFX_Matrix();
207
208 CFWL_Widget* parent = GetParent();
209 std::vector<CFWL_Widget*> parents;
210 while (parent) {
211 parents.push_back(parent);
212 parent = parent->GetParent();
213 }
214
215 CFX_Matrix matrix;
216 CFX_Matrix ctmOnParent;
217 CFX_RectF rect;
218 int32_t count = pdfium::CollectionSize<int32_t>(parents);
219 for (int32_t i = count - 2; i >= 0; i--) {
220 parent = parents[i];
221 if (parent->m_pProperties)
222 ctmOnParent.SetIdentity();
223 rect = parent->GetWidgetRect();
224 matrix.Concat(ctmOnParent, true);
225 matrix.Translate(rect.left, rect.top, true);
226 }
227 CFX_Matrix m;
228 m.SetIdentity();
229 matrix.Concat(m, true);
230 parents.clear();
231 return matrix;
232 }
233
GetThemeProvider() const234 IFWL_ThemeProvider* CFWL_Widget::GetThemeProvider() const {
235 return m_pProperties->m_pThemeProvider;
236 }
237
SetThemeProvider(IFWL_ThemeProvider * pThemeProvider)238 void CFWL_Widget::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) {
239 m_pProperties->m_pThemeProvider = pThemeProvider;
240 }
241
IsEnabled() const242 bool CFWL_Widget::IsEnabled() const {
243 return (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) == 0;
244 }
245
HasBorder() const246 bool CFWL_Widget::HasBorder() const {
247 return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Border);
248 }
249
IsVisible() const250 bool CFWL_Widget::IsVisible() const {
251 return (m_pProperties->m_dwStates & FWL_WGTSTATE_Invisible) == 0;
252 }
253
IsOverLapper() const254 bool CFWL_Widget::IsOverLapper() const {
255 return (m_pProperties->m_dwStyles & FWL_WGTSTYLE_WindowTypeMask) ==
256 FWL_WGTSTYLE_OverLapper;
257 }
258
IsPopup() const259 bool CFWL_Widget::IsPopup() const {
260 return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Popup);
261 }
262
IsChild() const263 bool CFWL_Widget::IsChild() const {
264 return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Child);
265 }
266
GetEdgeRect()267 CFX_RectF CFWL_Widget::GetEdgeRect() {
268 CFX_RectF rtEdge(0, 0, m_pProperties->m_rtWidget.width,
269 m_pProperties->m_rtWidget.height);
270 if (HasBorder()) {
271 float fCX = GetBorderSize(true);
272 float fCY = GetBorderSize(false);
273 rtEdge.Deflate(fCX, fCY);
274 }
275 return rtEdge;
276 }
277
GetBorderSize(bool bCX)278 float CFWL_Widget::GetBorderSize(bool bCX) {
279 IFWL_ThemeProvider* theme = GetAvailableTheme();
280 if (!theme)
281 return 0.0f;
282 return bCX ? theme->GetCXBorderSize() : theme->GetCYBorderSize();
283 }
284
GetRelativeRect()285 CFX_RectF CFWL_Widget::GetRelativeRect() {
286 return CFX_RectF(0, 0, m_pProperties->m_rtWidget.width,
287 m_pProperties->m_rtWidget.height);
288 }
289
GetAvailableTheme()290 IFWL_ThemeProvider* CFWL_Widget::GetAvailableTheme() {
291 if (m_pProperties->m_pThemeProvider)
292 return m_pProperties->m_pThemeProvider;
293
294 CFWL_Widget* pUp = this;
295 do {
296 pUp = (pUp->GetStyles() & FWL_WGTSTYLE_Popup)
297 ? m_pWidgetMgr->GetOwnerWidget(pUp)
298 : m_pWidgetMgr->GetParentWidget(pUp);
299 if (pUp) {
300 IFWL_ThemeProvider* pRet = pUp->GetThemeProvider();
301 if (pRet)
302 return pRet;
303 }
304 } while (pUp);
305 return nullptr;
306 }
307
GetRootOuter()308 CFWL_Widget* CFWL_Widget::GetRootOuter() {
309 CFWL_Widget* pRet = m_pOuter;
310 if (!pRet)
311 return nullptr;
312
313 while (CFWL_Widget* pOuter = pRet->GetOuter())
314 pRet = pOuter;
315 return pRet;
316 }
317
CalcTextSize(const WideString & wsText,IFWL_ThemeProvider * pTheme,bool bMultiLine)318 CFX_SizeF CFWL_Widget::CalcTextSize(const WideString& wsText,
319 IFWL_ThemeProvider* pTheme,
320 bool bMultiLine) {
321 if (!pTheme)
322 return CFX_SizeF();
323
324 CFWL_ThemeText calPart;
325 calPart.m_pWidget = this;
326 calPart.m_wsText = wsText;
327 if (bMultiLine)
328 calPart.m_dwTTOStyles.line_wrap_ = true;
329 else
330 calPart.m_dwTTOStyles.single_line_ = true;
331
332 calPart.m_iTTOAlign = FDE_TextAlignment::kTopLeft;
333 float fWidth = bMultiLine ? FWL_WGT_CalcMultiLineDefWidth : FWL_WGT_CalcWidth;
334 CFX_RectF rect(0, 0, fWidth, FWL_WGT_CalcHeight);
335 pTheme->CalcTextRect(&calPart, rect);
336 return CFX_SizeF(rect.width, rect.height);
337 }
338
CalcTextRect(const WideString & wsText,IFWL_ThemeProvider * pTheme,const FDE_TextStyle & dwTTOStyles,FDE_TextAlignment iTTOAlign,CFX_RectF & rect)339 void CFWL_Widget::CalcTextRect(const WideString& wsText,
340 IFWL_ThemeProvider* pTheme,
341 const FDE_TextStyle& dwTTOStyles,
342 FDE_TextAlignment iTTOAlign,
343 CFX_RectF& rect) {
344 CFWL_ThemeText calPart;
345 calPart.m_pWidget = this;
346 calPart.m_wsText = wsText;
347 calPart.m_dwTTOStyles = dwTTOStyles;
348 calPart.m_iTTOAlign = iTTOAlign;
349 pTheme->CalcTextRect(&calPart, rect);
350 }
351
SetFocus(bool bFocus)352 void CFWL_Widget::SetFocus(bool bFocus) {
353 if (m_pWidgetMgr->IsFormDisabled())
354 return;
355
356 const CFWL_App* pApp = GetOwnerApp();
357 if (!pApp)
358 return;
359
360 CFWL_NoteDriver* pDriver =
361 static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver());
362 if (!pDriver)
363 return;
364
365 CFWL_Widget* curFocus = pDriver->GetFocus();
366 if (bFocus && curFocus != this)
367 pDriver->SetFocus(this);
368 else if (!bFocus && curFocus == this)
369 pDriver->SetFocus(nullptr);
370 }
371
SetGrab(bool bSet)372 void CFWL_Widget::SetGrab(bool bSet) {
373 const CFWL_App* pApp = GetOwnerApp();
374 if (!pApp)
375 return;
376
377 CFWL_NoteDriver* pDriver =
378 static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver());
379 pDriver->SetGrab(this, bSet);
380 }
381
GetPopupPos(float fMinHeight,float fMaxHeight,const CFX_RectF & rtAnchor,CFX_RectF & rtPopup)382 void CFWL_Widget::GetPopupPos(float fMinHeight,
383 float fMaxHeight,
384 const CFX_RectF& rtAnchor,
385 CFX_RectF& rtPopup) {
386 if (GetClassID() == FWL_Type::ComboBox) {
387 if (m_pWidgetMgr->IsFormDisabled()) {
388 m_pWidgetMgr->GetAdapterPopupPos(this, fMinHeight, fMaxHeight, rtAnchor,
389 rtPopup);
390 return;
391 }
392 GetPopupPosComboBox(fMinHeight, fMaxHeight, rtAnchor, rtPopup);
393 return;
394 }
395 if (GetClassID() == FWL_Type::DateTimePicker &&
396 m_pWidgetMgr->IsFormDisabled()) {
397 m_pWidgetMgr->GetAdapterPopupPos(this, fMinHeight, fMaxHeight, rtAnchor,
398 rtPopup);
399 return;
400 }
401 GetPopupPosGeneral(fMinHeight, fMaxHeight, rtAnchor, rtPopup);
402 }
403
GetPopupPosMenu(float fMinHeight,float fMaxHeight,const CFX_RectF & rtAnchor,CFX_RectF & rtPopup)404 bool CFWL_Widget::GetPopupPosMenu(float fMinHeight,
405 float fMaxHeight,
406 const CFX_RectF& rtAnchor,
407 CFX_RectF& rtPopup) {
408 if (GetStylesEx() & FWL_STYLEEXT_MNU_Vert) {
409 bool bLeft = m_pProperties->m_rtWidget.left < 0;
410 float fRight = rtAnchor.right() + rtPopup.width;
411 CFX_PointF point = TransformTo(nullptr, CFX_PointF());
412 if (fRight + point.x > 0.0f || bLeft) {
413 rtPopup = CFX_RectF(rtAnchor.left - rtPopup.width, rtAnchor.top,
414 rtPopup.width, rtPopup.height);
415 } else {
416 rtPopup = CFX_RectF(rtAnchor.right(), rtAnchor.top, rtPopup.width,
417 rtPopup.height);
418 }
419 rtPopup.Offset(point.x, point.y);
420 return true;
421 }
422
423 float fBottom = rtAnchor.bottom() + rtPopup.height;
424 CFX_PointF point = TransformTo(nullptr, point);
425 if (fBottom + point.y > 0.0f) {
426 rtPopup = CFX_RectF(rtAnchor.left, rtAnchor.top - rtPopup.height,
427 rtPopup.width, rtPopup.height);
428 } else {
429 rtPopup = CFX_RectF(rtAnchor.left, rtAnchor.bottom(), rtPopup.width,
430 rtPopup.height);
431 }
432 rtPopup.Offset(point.x, point.y);
433 return true;
434 }
435
GetPopupPosComboBox(float fMinHeight,float fMaxHeight,const CFX_RectF & rtAnchor,CFX_RectF & rtPopup)436 bool CFWL_Widget::GetPopupPosComboBox(float fMinHeight,
437 float fMaxHeight,
438 const CFX_RectF& rtAnchor,
439 CFX_RectF& rtPopup) {
440 float fPopHeight = rtPopup.height;
441 if (rtPopup.height > fMaxHeight)
442 fPopHeight = fMaxHeight;
443 else if (rtPopup.height < fMinHeight)
444 fPopHeight = fMinHeight;
445
446 float fWidth = std::max(rtAnchor.width, rtPopup.width);
447 float fBottom = rtAnchor.bottom() + fPopHeight;
448 CFX_PointF point = TransformTo(nullptr, CFX_PointF());
449 if (fBottom + point.y > 0.0f) {
450 rtPopup =
451 CFX_RectF(rtAnchor.left, rtAnchor.top - fPopHeight, fWidth, fPopHeight);
452 } else {
453 rtPopup = CFX_RectF(rtAnchor.left, rtAnchor.bottom(), fWidth, fPopHeight);
454 }
455
456 rtPopup.Offset(point.x, point.y);
457 return true;
458 }
459
GetPopupPosGeneral(float fMinHeight,float fMaxHeight,const CFX_RectF & rtAnchor,CFX_RectF & rtPopup)460 bool CFWL_Widget::GetPopupPosGeneral(float fMinHeight,
461 float fMaxHeight,
462 const CFX_RectF& rtAnchor,
463 CFX_RectF& rtPopup) {
464 CFX_PointF point = TransformTo(nullptr, CFX_PointF());
465 if (rtAnchor.bottom() + point.y > 0.0f) {
466 rtPopup = CFX_RectF(rtAnchor.left, rtAnchor.top - rtPopup.height,
467 rtPopup.width, rtPopup.height);
468 } else {
469 rtPopup = CFX_RectF(rtAnchor.left, rtAnchor.bottom(), rtPopup.width,
470 rtPopup.height);
471 }
472 rtPopup.Offset(point.x, point.y);
473 return true;
474 }
475
RegisterEventTarget(CFWL_Widget * pEventSource)476 void CFWL_Widget::RegisterEventTarget(CFWL_Widget* pEventSource) {
477 const CFWL_App* pApp = GetOwnerApp();
478 if (!pApp)
479 return;
480
481 CFWL_NoteDriver* pNoteDriver = pApp->GetNoteDriver();
482 if (!pNoteDriver)
483 return;
484
485 pNoteDriver->RegisterEventTarget(this, pEventSource);
486 }
487
UnregisterEventTarget()488 void CFWL_Widget::UnregisterEventTarget() {
489 const CFWL_App* pApp = GetOwnerApp();
490 if (!pApp)
491 return;
492
493 CFWL_NoteDriver* pNoteDriver = pApp->GetNoteDriver();
494 if (!pNoteDriver)
495 return;
496
497 pNoteDriver->UnregisterEventTarget(this);
498 }
499
DispatchEvent(CFWL_Event * pEvent)500 void CFWL_Widget::DispatchEvent(CFWL_Event* pEvent) {
501 if (m_pOuter) {
502 m_pOuter->GetDelegate()->OnProcessEvent(pEvent);
503 return;
504 }
505 const CFWL_App* pApp = GetOwnerApp();
506 if (!pApp)
507 return;
508
509 CFWL_NoteDriver* pNoteDriver = pApp->GetNoteDriver();
510 if (!pNoteDriver)
511 return;
512 pNoteDriver->SendEvent(pEvent);
513 }
514
Repaint()515 void CFWL_Widget::Repaint() {
516 RepaintRect(CFX_RectF(0, 0, m_pProperties->m_rtWidget.width,
517 m_pProperties->m_rtWidget.height));
518 }
519
RepaintRect(const CFX_RectF & pRect)520 void CFWL_Widget::RepaintRect(const CFX_RectF& pRect) {
521 m_pWidgetMgr->RepaintWidget(this, pRect);
522 }
523
DrawBackground(CXFA_Graphics * pGraphics,CFWL_Part iPartBk,IFWL_ThemeProvider * pTheme,const CFX_Matrix * pMatrix)524 void CFWL_Widget::DrawBackground(CXFA_Graphics* pGraphics,
525 CFWL_Part iPartBk,
526 IFWL_ThemeProvider* pTheme,
527 const CFX_Matrix* pMatrix) {
528 CFWL_ThemeBackground param;
529 param.m_pWidget = this;
530 param.m_iPart = iPartBk;
531 param.m_pGraphics = pGraphics;
532 if (pMatrix)
533 param.m_matrix.Concat(*pMatrix, true);
534 param.m_rtPart = GetRelativeRect();
535 pTheme->DrawBackground(¶m);
536 }
537
DrawBorder(CXFA_Graphics * pGraphics,CFWL_Part iPartBorder,IFWL_ThemeProvider * pTheme,const CFX_Matrix & matrix)538 void CFWL_Widget::DrawBorder(CXFA_Graphics* pGraphics,
539 CFWL_Part iPartBorder,
540 IFWL_ThemeProvider* pTheme,
541 const CFX_Matrix& matrix) {
542 CFWL_ThemeBackground param;
543 param.m_pWidget = this;
544 param.m_iPart = iPartBorder;
545 param.m_pGraphics = pGraphics;
546 param.m_matrix.Concat(matrix, true);
547 param.m_rtPart = GetRelativeRect();
548 pTheme->DrawBackground(¶m);
549 }
550
NotifyDriver()551 void CFWL_Widget::NotifyDriver() {
552 const CFWL_App* pApp = GetOwnerApp();
553 if (!pApp)
554 return;
555
556 CFWL_NoteDriver* pDriver =
557 static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver());
558 if (!pDriver)
559 return;
560
561 pDriver->NotifyTargetDestroy(this);
562 }
563
GetOffsetFromParent(CFWL_Widget * pParent)564 CFX_SizeF CFWL_Widget::GetOffsetFromParent(CFWL_Widget* pParent) {
565 if (pParent == this)
566 return CFX_SizeF();
567
568 CFWL_WidgetMgr* pWidgetMgr = GetOwnerApp()->GetWidgetMgr();
569 if (!pWidgetMgr)
570 return CFX_SizeF();
571
572 CFX_SizeF szRet(m_pProperties->m_rtWidget.left,
573 m_pProperties->m_rtWidget.top);
574
575 CFWL_Widget* pDstWidget = GetParent();
576 while (pDstWidget && pDstWidget != pParent) {
577 CFX_RectF rtDst = pDstWidget->GetWidgetRect();
578 szRet += CFX_SizeF(rtDst.left, rtDst.top);
579 pDstWidget = pWidgetMgr->GetParentWidget(pDstWidget);
580 }
581 return szRet;
582 }
583
IsParent(CFWL_Widget * pParent)584 bool CFWL_Widget::IsParent(CFWL_Widget* pParent) {
585 CFWL_Widget* pUpWidget = GetParent();
586 while (pUpWidget) {
587 if (pUpWidget == pParent)
588 return true;
589 pUpWidget = pUpWidget->GetParent();
590 }
591 return false;
592 }
593
OnProcessMessage(CFWL_Message * pMessage)594 void CFWL_Widget::OnProcessMessage(CFWL_Message* pMessage) {
595 if (!pMessage->m_pDstTarget)
596 return;
597
598 CFWL_Widget* pWidget = pMessage->m_pDstTarget;
599 switch (pMessage->GetType()) {
600 case CFWL_Message::Type::Mouse: {
601 CFWL_MessageMouse* pMsgMouse = static_cast<CFWL_MessageMouse*>(pMessage);
602
603 CFWL_EventMouse evt(pWidget, pWidget);
604 evt.m_dwCmd = pMsgMouse->m_dwCmd;
605 pWidget->DispatchEvent(&evt);
606 break;
607 }
608 default:
609 break;
610 }
611 }
612
OnProcessEvent(CFWL_Event * pEvent)613 void CFWL_Widget::OnProcessEvent(CFWL_Event* pEvent) {}
614
OnDrawWidget(CXFA_Graphics * pGraphics,const CFX_Matrix & matrix)615 void CFWL_Widget::OnDrawWidget(CXFA_Graphics* pGraphics,
616 const CFX_Matrix& matrix) {}
617