• 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_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(&param);
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(&param);
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