• 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/tto/fde_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/xfa_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 CFX_WideStringC & wsClass) const66 bool CFWL_Widget::IsInstance(const CFX_WideStringC& 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     FX_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   CFX_Matrix m;
201   m.SetReverse(pWidget->GetMatrix());
202   return m.Transform(ret) - pWidget->GetWidgetRect().TopLeft();
203 }
204 
GetMatrix()205 CFX_Matrix CFWL_Widget::GetMatrix() {
206   if (!m_pProperties)
207     return CFX_Matrix();
208 
209   CFWL_Widget* parent = GetParent();
210   std::vector<CFWL_Widget*> parents;
211   while (parent) {
212     parents.push_back(parent);
213     parent = parent->GetParent();
214   }
215 
216   CFX_Matrix matrix;
217   CFX_Matrix ctmOnParent;
218   CFX_RectF rect;
219   int32_t count = pdfium::CollectionSize<int32_t>(parents);
220   for (int32_t i = count - 2; i >= 0; i--) {
221     parent = parents[i];
222     if (parent->m_pProperties)
223       ctmOnParent.SetIdentity();
224     rect = parent->GetWidgetRect();
225     matrix.Concat(ctmOnParent, true);
226     matrix.Translate(rect.left, rect.top, true);
227   }
228   CFX_Matrix m;
229   m.SetIdentity();
230   matrix.Concat(m, true);
231   parents.clear();
232   return matrix;
233 }
234 
GetThemeProvider() const235 IFWL_ThemeProvider* CFWL_Widget::GetThemeProvider() const {
236   return m_pProperties->m_pThemeProvider;
237 }
238 
SetThemeProvider(IFWL_ThemeProvider * pThemeProvider)239 void CFWL_Widget::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) {
240   m_pProperties->m_pThemeProvider = pThemeProvider;
241 }
242 
IsEnabled() const243 bool CFWL_Widget::IsEnabled() const {
244   return (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) == 0;
245 }
246 
HasBorder() const247 bool CFWL_Widget::HasBorder() const {
248   return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Border);
249 }
250 
IsVisible() const251 bool CFWL_Widget::IsVisible() const {
252   return (m_pProperties->m_dwStates & FWL_WGTSTATE_Invisible) == 0;
253 }
254 
IsOverLapper() const255 bool CFWL_Widget::IsOverLapper() const {
256   return (m_pProperties->m_dwStyles & FWL_WGTSTYLE_WindowTypeMask) ==
257          FWL_WGTSTYLE_OverLapper;
258 }
259 
IsPopup() const260 bool CFWL_Widget::IsPopup() const {
261   return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Popup);
262 }
263 
IsChild() const264 bool CFWL_Widget::IsChild() const {
265   return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Child);
266 }
267 
GetEdgeRect()268 CFX_RectF CFWL_Widget::GetEdgeRect() {
269   CFX_RectF rtEdge(0, 0, m_pProperties->m_rtWidget.width,
270                    m_pProperties->m_rtWidget.height);
271   if (HasBorder()) {
272     FX_FLOAT fCX = GetBorderSize(true);
273     FX_FLOAT fCY = GetBorderSize(false);
274     rtEdge.Deflate(fCX, fCY);
275   }
276   return rtEdge;
277 }
278 
GetBorderSize(bool bCX)279 FX_FLOAT CFWL_Widget::GetBorderSize(bool bCX) {
280   IFWL_ThemeProvider* theme = GetAvailableTheme();
281   if (!theme)
282     return 0.0f;
283   return bCX ? theme->GetCXBorderSize() : theme->GetCYBorderSize();
284 }
285 
GetRelativeRect()286 CFX_RectF CFWL_Widget::GetRelativeRect() {
287   return CFX_RectF(0, 0, m_pProperties->m_rtWidget.width,
288                    m_pProperties->m_rtWidget.height);
289 }
290 
GetAvailableTheme()291 IFWL_ThemeProvider* CFWL_Widget::GetAvailableTheme() {
292   if (m_pProperties->m_pThemeProvider)
293     return m_pProperties->m_pThemeProvider;
294 
295   CFWL_Widget* pUp = this;
296   do {
297     pUp = (pUp->GetStyles() & FWL_WGTSTYLE_Popup)
298               ? m_pWidgetMgr->GetOwnerWidget(pUp)
299               : m_pWidgetMgr->GetParentWidget(pUp);
300     if (pUp) {
301       IFWL_ThemeProvider* pRet = pUp->GetThemeProvider();
302       if (pRet)
303         return pRet;
304     }
305   } while (pUp);
306   return nullptr;
307 }
308 
GetRootOuter()309 CFWL_Widget* CFWL_Widget::GetRootOuter() {
310   CFWL_Widget* pRet = m_pOuter;
311   if (!pRet)
312     return nullptr;
313 
314   while (CFWL_Widget* pOuter = pRet->GetOuter())
315     pRet = pOuter;
316   return pRet;
317 }
318 
CalcTextSize(const CFX_WideString & wsText,IFWL_ThemeProvider * pTheme,bool bMultiLine)319 CFX_SizeF CFWL_Widget::CalcTextSize(const CFX_WideString& wsText,
320                                     IFWL_ThemeProvider* pTheme,
321                                     bool bMultiLine) {
322   if (!pTheme)
323     return CFX_SizeF();
324 
325   CFWL_ThemeText calPart;
326   calPart.m_pWidget = this;
327   calPart.m_wsText = wsText;
328   calPart.m_dwTTOStyles =
329       bMultiLine ? FDE_TTOSTYLE_LineWrap : FDE_TTOSTYLE_SingleLine;
330   calPart.m_iTTOAlign = FDE_TTOALIGNMENT_TopLeft;
331   FX_FLOAT fWidth =
332       bMultiLine ? FWL_WGT_CalcMultiLineDefWidth : FWL_WGT_CalcWidth;
333   CFX_RectF rect(0, 0, fWidth, FWL_WGT_CalcHeight);
334   pTheme->CalcTextRect(&calPart, rect);
335   return CFX_SizeF(rect.width, rect.height);
336 }
337 
CalcTextRect(const CFX_WideString & wsText,IFWL_ThemeProvider * pTheme,uint32_t dwTTOStyles,int32_t iTTOAlign,CFX_RectF & rect)338 void CFWL_Widget::CalcTextRect(const CFX_WideString& wsText,
339                                IFWL_ThemeProvider* pTheme,
340                                uint32_t dwTTOStyles,
341                                int32_t iTTOAlign,
342                                CFX_RectF& rect) {
343   CFWL_ThemeText calPart;
344   calPart.m_pWidget = this;
345   calPart.m_wsText = wsText;
346   calPart.m_dwTTOStyles = dwTTOStyles;
347   calPart.m_iTTOAlign = iTTOAlign;
348   pTheme->CalcTextRect(&calPart, rect);
349 }
350 
SetFocus(bool bFocus)351 void CFWL_Widget::SetFocus(bool bFocus) {
352   if (m_pWidgetMgr->IsFormDisabled())
353     return;
354 
355   const CFWL_App* pApp = GetOwnerApp();
356   if (!pApp)
357     return;
358 
359   CFWL_NoteDriver* pDriver =
360       static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver());
361   if (!pDriver)
362     return;
363 
364   CFWL_Widget* curFocus = pDriver->GetFocus();
365   if (bFocus && curFocus != this)
366     pDriver->SetFocus(this);
367   else if (!bFocus && curFocus == this)
368     pDriver->SetFocus(nullptr);
369 }
370 
SetGrab(bool bSet)371 void CFWL_Widget::SetGrab(bool bSet) {
372   const CFWL_App* pApp = GetOwnerApp();
373   if (!pApp)
374     return;
375 
376   CFWL_NoteDriver* pDriver =
377       static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver());
378   pDriver->SetGrab(this, bSet);
379 }
380 
GetPopupPos(FX_FLOAT fMinHeight,FX_FLOAT fMaxHeight,const CFX_RectF & rtAnchor,CFX_RectF & rtPopup)381 void CFWL_Widget::GetPopupPos(FX_FLOAT fMinHeight,
382                               FX_FLOAT fMaxHeight,
383                               const CFX_RectF& rtAnchor,
384                               CFX_RectF& rtPopup) {
385   if (GetClassID() == FWL_Type::ComboBox) {
386     if (m_pWidgetMgr->IsFormDisabled()) {
387       m_pWidgetMgr->GetAdapterPopupPos(this, fMinHeight, fMaxHeight, rtAnchor,
388                                        rtPopup);
389       return;
390     }
391     GetPopupPosComboBox(fMinHeight, fMaxHeight, rtAnchor, rtPopup);
392     return;
393   }
394   if (GetClassID() == FWL_Type::DateTimePicker &&
395       m_pWidgetMgr->IsFormDisabled()) {
396     m_pWidgetMgr->GetAdapterPopupPos(this, fMinHeight, fMaxHeight, rtAnchor,
397                                      rtPopup);
398     return;
399   }
400   GetPopupPosGeneral(fMinHeight, fMaxHeight, rtAnchor, rtPopup);
401 }
402 
GetPopupPosMenu(FX_FLOAT fMinHeight,FX_FLOAT fMaxHeight,const CFX_RectF & rtAnchor,CFX_RectF & rtPopup)403 bool CFWL_Widget::GetPopupPosMenu(FX_FLOAT fMinHeight,
404                                   FX_FLOAT fMaxHeight,
405                                   const CFX_RectF& rtAnchor,
406                                   CFX_RectF& rtPopup) {
407   if (GetStylesEx() & FWL_STYLEEXT_MNU_Vert) {
408     bool bLeft = m_pProperties->m_rtWidget.left < 0;
409     FX_FLOAT fRight = rtAnchor.right() + rtPopup.width;
410     CFX_PointF point = TransformTo(nullptr, CFX_PointF());
411     if (fRight + point.x > 0.0f || bLeft) {
412       rtPopup = CFX_RectF(rtAnchor.left - rtPopup.width, rtAnchor.top,
413                           rtPopup.width, rtPopup.height);
414     } else {
415       rtPopup = CFX_RectF(rtAnchor.right(), rtAnchor.top, rtPopup.width,
416                           rtPopup.height);
417     }
418     rtPopup.Offset(point.x, point.y);
419     return true;
420   }
421 
422   FX_FLOAT fBottom = rtAnchor.bottom() + rtPopup.height;
423   CFX_PointF point = TransformTo(nullptr, point);
424   if (fBottom + point.y > 0.0f) {
425     rtPopup = CFX_RectF(rtAnchor.left, rtAnchor.top - rtPopup.height,
426                         rtPopup.width, rtPopup.height);
427   } else {
428     rtPopup = CFX_RectF(rtAnchor.left, rtAnchor.bottom(), rtPopup.width,
429                         rtPopup.height);
430   }
431   rtPopup.Offset(point.x, point.y);
432   return true;
433 }
434 
GetPopupPosComboBox(FX_FLOAT fMinHeight,FX_FLOAT fMaxHeight,const CFX_RectF & rtAnchor,CFX_RectF & rtPopup)435 bool CFWL_Widget::GetPopupPosComboBox(FX_FLOAT fMinHeight,
436                                       FX_FLOAT fMaxHeight,
437                                       const CFX_RectF& rtAnchor,
438                                       CFX_RectF& rtPopup) {
439   FX_FLOAT fPopHeight = rtPopup.height;
440   if (rtPopup.height > fMaxHeight)
441     fPopHeight = fMaxHeight;
442   else if (rtPopup.height < fMinHeight)
443     fPopHeight = fMinHeight;
444 
445   FX_FLOAT fWidth = std::max(rtAnchor.width, rtPopup.width);
446   FX_FLOAT fBottom = rtAnchor.bottom() + fPopHeight;
447   CFX_PointF point = TransformTo(nullptr, CFX_PointF());
448   if (fBottom + point.y > 0.0f) {
449     rtPopup =
450         CFX_RectF(rtAnchor.left, rtAnchor.top - fPopHeight, fWidth, fPopHeight);
451   } else {
452     rtPopup = CFX_RectF(rtAnchor.left, rtAnchor.bottom(), fWidth, fPopHeight);
453   }
454 
455   rtPopup.Offset(point.x, point.y);
456   return true;
457 }
458 
GetPopupPosGeneral(FX_FLOAT fMinHeight,FX_FLOAT fMaxHeight,const CFX_RectF & rtAnchor,CFX_RectF & rtPopup)459 bool CFWL_Widget::GetPopupPosGeneral(FX_FLOAT fMinHeight,
460                                      FX_FLOAT fMaxHeight,
461                                      const CFX_RectF& rtAnchor,
462                                      CFX_RectF& rtPopup) {
463   CFX_PointF point = TransformTo(nullptr, CFX_PointF());
464   if (rtAnchor.bottom() + point.y > 0.0f) {
465     rtPopup = CFX_RectF(rtAnchor.left, rtAnchor.top - rtPopup.height,
466                         rtPopup.width, rtPopup.height);
467   } else {
468     rtPopup = CFX_RectF(rtAnchor.left, rtAnchor.bottom(), rtPopup.width,
469                         rtPopup.height);
470   }
471   rtPopup.Offset(point.x, point.y);
472   return true;
473 }
474 
RegisterEventTarget(CFWL_Widget * pEventSource)475 void CFWL_Widget::RegisterEventTarget(CFWL_Widget* pEventSource) {
476   const CFWL_App* pApp = GetOwnerApp();
477   if (!pApp)
478     return;
479 
480   CFWL_NoteDriver* pNoteDriver = pApp->GetNoteDriver();
481   if (!pNoteDriver)
482     return;
483 
484   pNoteDriver->RegisterEventTarget(this, pEventSource);
485 }
486 
UnregisterEventTarget()487 void CFWL_Widget::UnregisterEventTarget() {
488   const CFWL_App* pApp = GetOwnerApp();
489   if (!pApp)
490     return;
491 
492   CFWL_NoteDriver* pNoteDriver = pApp->GetNoteDriver();
493   if (!pNoteDriver)
494     return;
495 
496   pNoteDriver->UnregisterEventTarget(this);
497 }
498 
DispatchEvent(CFWL_Event * pEvent)499 void CFWL_Widget::DispatchEvent(CFWL_Event* pEvent) {
500   if (m_pOuter) {
501     m_pOuter->GetDelegate()->OnProcessEvent(pEvent);
502     return;
503   }
504   const CFWL_App* pApp = GetOwnerApp();
505   if (!pApp)
506     return;
507 
508   CFWL_NoteDriver* pNoteDriver = pApp->GetNoteDriver();
509   if (!pNoteDriver)
510     return;
511   pNoteDriver->SendEvent(pEvent);
512 }
513 
Repaint()514 void CFWL_Widget::Repaint() {
515   RepaintRect(CFX_RectF(0, 0, m_pProperties->m_rtWidget.width,
516                         m_pProperties->m_rtWidget.height));
517 }
518 
RepaintRect(const CFX_RectF & pRect)519 void CFWL_Widget::RepaintRect(const CFX_RectF& pRect) {
520   m_pWidgetMgr->RepaintWidget(this, pRect);
521 }
522 
DrawBackground(CFX_Graphics * pGraphics,CFWL_Part iPartBk,IFWL_ThemeProvider * pTheme,const CFX_Matrix * pMatrix)523 void CFWL_Widget::DrawBackground(CFX_Graphics* pGraphics,
524                                  CFWL_Part iPartBk,
525                                  IFWL_ThemeProvider* pTheme,
526                                  const CFX_Matrix* pMatrix) {
527   CFWL_ThemeBackground param;
528   param.m_pWidget = this;
529   param.m_iPart = iPartBk;
530   param.m_pGraphics = pGraphics;
531   if (pMatrix)
532     param.m_matrix.Concat(*pMatrix, true);
533   param.m_rtPart = GetRelativeRect();
534   pTheme->DrawBackground(&param);
535 }
536 
DrawBorder(CFX_Graphics * pGraphics,CFWL_Part iPartBorder,IFWL_ThemeProvider * pTheme,const CFX_Matrix * pMatrix)537 void CFWL_Widget::DrawBorder(CFX_Graphics* pGraphics,
538                              CFWL_Part iPartBorder,
539                              IFWL_ThemeProvider* pTheme,
540                              const CFX_Matrix* pMatrix) {
541   CFWL_ThemeBackground param;
542   param.m_pWidget = this;
543   param.m_iPart = iPartBorder;
544   param.m_pGraphics = pGraphics;
545   if (pMatrix)
546     param.m_matrix.Concat(*pMatrix, 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(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)615 void CFWL_Widget::OnDrawWidget(CFX_Graphics* pGraphics,
616                                const CFX_Matrix* pMatrix) {}
617