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 <algorithm>
8 
9 #include "xfa/src/foxitlib.h"
10 #include "xfa/src/fwl/src/core/include/fwl_targetimp.h"
11 #include "xfa/src/fwl/src/core/include/fwl_noteimp.h"
12 #include "xfa/src/fwl/src/core/include/fwl_threadimp.h"
13 #include "xfa/src/fwl/src/core/include/fwl_appimp.h"
14 #include "xfa/src/fwl/src/core/include/fwl_widgetmgrimp.h"
15 #include "xfa/src/fwl/src/core/include/fwl_widgetimp.h"
GetWidgetRect(CFX_RectF & rect,FX_BOOL bAutoSize)16 FWL_ERR IFWL_Widget::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
17   return static_cast<CFWL_WidgetImp*>(GetImpl())
18       ->GetWidgetRect(rect, bAutoSize);
19 }
GetGlobalRect(CFX_RectF & rect)20 FWL_ERR IFWL_Widget::GetGlobalRect(CFX_RectF& rect) {
21   return static_cast<CFWL_WidgetImp*>(GetImpl())->GetGlobalRect(rect);
22 }
SetWidgetRect(const CFX_RectF & rect)23 FWL_ERR IFWL_Widget::SetWidgetRect(const CFX_RectF& rect) {
24   return static_cast<CFWL_WidgetImp*>(GetImpl())->SetWidgetRect(rect);
25 }
GetClientRect(CFX_RectF & rect)26 FWL_ERR IFWL_Widget::GetClientRect(CFX_RectF& rect) {
27   return static_cast<CFWL_WidgetImp*>(GetImpl())->GetClientRect(rect);
28 }
GetParent()29 IFWL_Widget* IFWL_Widget::GetParent() {
30   return static_cast<CFWL_WidgetImp*>(GetImpl())->GetParent();
31 }
SetParent(IFWL_Widget * pParent)32 FWL_ERR IFWL_Widget::SetParent(IFWL_Widget* pParent) {
33   return static_cast<CFWL_WidgetImp*>(GetImpl())->SetParent(pParent);
34 }
GetOwner()35 IFWL_Widget* IFWL_Widget::GetOwner() {
36   return static_cast<CFWL_WidgetImp*>(GetImpl())->GetOwner();
37 }
SetOwner(IFWL_Widget * pOwner)38 FWL_ERR IFWL_Widget::SetOwner(IFWL_Widget* pOwner) {
39   return static_cast<CFWL_WidgetImp*>(GetImpl())->SetOwner(pOwner);
40 }
GetOuter()41 IFWL_Widget* IFWL_Widget::GetOuter() {
42   return static_cast<CFWL_WidgetImp*>(GetImpl())->GetOuter();
43 }
GetStyles()44 FX_DWORD IFWL_Widget::GetStyles() {
45   return static_cast<CFWL_WidgetImp*>(GetImpl())->GetStyles();
46 }
ModifyStyles(FX_DWORD dwStylesAdded,FX_DWORD dwStylesRemoved)47 FWL_ERR IFWL_Widget::ModifyStyles(FX_DWORD dwStylesAdded,
48                                   FX_DWORD dwStylesRemoved) {
49   return static_cast<CFWL_WidgetImp*>(GetImpl())
50       ->ModifyStyles(dwStylesAdded, dwStylesRemoved);
51 }
GetStylesEx()52 FX_DWORD IFWL_Widget::GetStylesEx() {
53   return static_cast<CFWL_WidgetImp*>(GetImpl())->GetStylesEx();
54 }
ModifyStylesEx(FX_DWORD dwStylesExAdded,FX_DWORD dwStylesExRemoved)55 FWL_ERR IFWL_Widget::ModifyStylesEx(FX_DWORD dwStylesExAdded,
56                                     FX_DWORD dwStylesExRemoved) {
57   return static_cast<CFWL_WidgetImp*>(GetImpl())
58       ->ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
59 }
GetStates()60 FX_DWORD IFWL_Widget::GetStates() {
61   return static_cast<CFWL_WidgetImp*>(GetImpl())->GetStates();
62 }
SetStates(FX_DWORD dwStates,FX_BOOL bSet)63 FWL_ERR IFWL_Widget::SetStates(FX_DWORD dwStates, FX_BOOL bSet) {
64   return static_cast<CFWL_WidgetImp*>(GetImpl())->SetStates(dwStates, bSet);
65 }
SetPrivateData(void * module_id,void * pData,PD_CALLBACK_FREEDATA callback)66 FWL_ERR IFWL_Widget::SetPrivateData(void* module_id,
67                                     void* pData,
68                                     PD_CALLBACK_FREEDATA callback) {
69   return static_cast<CFWL_WidgetImp*>(GetImpl())
70       ->SetPrivateData(module_id, pData, callback);
71 }
GetPrivateData(void * module_id)72 void* IFWL_Widget::GetPrivateData(void* module_id) {
73   return static_cast<CFWL_WidgetImp*>(GetImpl())->GetPrivateData(module_id);
74 }
Update()75 FWL_ERR IFWL_Widget::Update() {
76   return static_cast<CFWL_WidgetImp*>(GetImpl())->Update();
77 }
LockUpdate()78 FWL_ERR IFWL_Widget::LockUpdate() {
79   return static_cast<CFWL_WidgetImp*>(GetImpl())->LockUpdate();
80 }
UnlockUpdate()81 FWL_ERR IFWL_Widget::UnlockUpdate() {
82   return static_cast<CFWL_WidgetImp*>(GetImpl())->UnlockUpdate();
83 }
HitTest(FX_FLOAT fx,FX_FLOAT fy)84 FX_DWORD IFWL_Widget::HitTest(FX_FLOAT fx, FX_FLOAT fy) {
85   return static_cast<CFWL_WidgetImp*>(GetImpl())->HitTest(fx, fy);
86 }
TransformTo(IFWL_Widget * pWidget,FX_FLOAT & fx,FX_FLOAT & fy)87 FWL_ERR IFWL_Widget::TransformTo(IFWL_Widget* pWidget,
88                                  FX_FLOAT& fx,
89                                  FX_FLOAT& fy) {
90   return static_cast<CFWL_WidgetImp*>(GetImpl())->TransformTo(pWidget, fx, fy);
91 }
TransformTo(IFWL_Widget * pWidget,CFX_RectF & rt)92 FWL_ERR IFWL_Widget::TransformTo(IFWL_Widget* pWidget, CFX_RectF& rt) {
93   return static_cast<CFWL_WidgetImp*>(GetImpl())->TransformTo(pWidget, rt);
94 }
GetMatrix(CFX_Matrix & matrix,FX_BOOL bGlobal)95 FWL_ERR IFWL_Widget::GetMatrix(CFX_Matrix& matrix, FX_BOOL bGlobal) {
96   return static_cast<CFWL_WidgetImp*>(GetImpl())->GetMatrix(matrix, bGlobal);
97 }
SetMatrix(const CFX_Matrix & matrix)98 FWL_ERR IFWL_Widget::SetMatrix(const CFX_Matrix& matrix) {
99   return static_cast<CFWL_WidgetImp*>(GetImpl())->SetMatrix(matrix);
100 }
DrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)101 FWL_ERR IFWL_Widget::DrawWidget(CFX_Graphics* pGraphics,
102                                 const CFX_Matrix* pMatrix) {
103   return static_cast<CFWL_WidgetImp*>(GetImpl())
104       ->DrawWidget(pGraphics, pMatrix);
105 }
GetThemeProvider()106 IFWL_ThemeProvider* IFWL_Widget::GetThemeProvider() {
107   return static_cast<CFWL_WidgetImp*>(GetImpl())->GetThemeProvider();
108 }
SetThemeProvider(IFWL_ThemeProvider * pThemeProvider)109 FWL_ERR IFWL_Widget::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) {
110   return static_cast<CFWL_WidgetImp*>(GetImpl())
111       ->SetThemeProvider(pThemeProvider);
112 }
SetDataProvider(IFWL_DataProvider * pDataProvider)113 FWL_ERR IFWL_Widget::SetDataProvider(IFWL_DataProvider* pDataProvider) {
114   return static_cast<CFWL_WidgetImp*>(GetImpl())
115       ->SetDataProvider(pDataProvider);
116 }
SetDelegate(IFWL_WidgetDelegate * pDelegate)117 IFWL_WidgetDelegate* IFWL_Widget::SetDelegate(IFWL_WidgetDelegate* pDelegate) {
118   return static_cast<CFWL_WidgetImp*>(GetImpl())->SetDelegate(pDelegate);
119 }
GetOwnerThread() const120 IFWL_NoteThread* IFWL_Widget::GetOwnerThread() const {
121   return static_cast<CFWL_WidgetImp*>(GetImpl())->GetOwnerThread();
122 }
GetOffsetFromParent(IFWL_Widget * pParent)123 CFX_SizeF IFWL_Widget::GetOffsetFromParent(IFWL_Widget* pParent) {
124   return static_cast<CFWL_WidgetImp*>(GetImpl())->GetOffsetFromParent(pParent);
125 }
Initialize()126 FWL_ERR CFWL_WidgetImp::Initialize() {
127   IFWL_App* pApp = FWL_GetApp();
128   if (!pApp)
129     return FWL_ERR_Indefinite;
130   IFWL_AdapterNative* pAdapter = pApp->GetAdapterNative();
131   if (!pAdapter)
132     return FWL_ERR_Indefinite;
133   IFWL_AdapterThreadMgr* pAdapterThread = pAdapter->GetThreadMgr();
134   if (!pAdapterThread)
135     return FWL_ERR_Indefinite;
136   SetOwnerThread(static_cast<CFWL_NoteThreadImp*>(
137       pAdapterThread->GetCurrentThread()->GetImpl()));
138   IFWL_Widget* pParent = m_pProperties->m_pParent;
139   m_pWidgetMgr->InsertWidget(pParent, m_pInterface);
140   if (!IsChild()) {
141     {
142       IFWL_Widget* pOwner = m_pProperties->m_pOwner;
143       if (pOwner) {
144         m_pWidgetMgr->SetOwner(pOwner, m_pInterface);
145       }
146     }
147     m_pWidgetMgr->CreateWidget_Native(m_pInterface);
148   }
149   return FWL_ERR_Succeeded;
150 }
Finalize()151 FWL_ERR CFWL_WidgetImp::Finalize() {
152   NotifyDriver();
153   IFWL_Form* pForm = static_cast<IFWL_Form*>(
154       FWL_GetWidgetMgr()->GetWidget(m_pInterface, FWL_WGTRELATION_SystemForm));
155   if (pForm && pForm != m_pInterface) {
156     IFWL_Content* pContent = pForm->GetContent();
157     if (pContent) {
158       pContent->RemoveWidget(m_pInterface);
159     }
160   }
161   if (!IsChild()) {
162     m_pWidgetMgr->DestroyWidget_Native(m_pInterface);
163   }
164   m_pWidgetMgr->RemoveWidget(m_pInterface);
165   return FWL_ERR_Succeeded;
166 }
GetWidgetRect(CFX_RectF & rect,FX_BOOL bAutoSize)167 FWL_ERR CFWL_WidgetImp::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
168   if (bAutoSize) {
169     if (HasEdge()) {
170       FX_FLOAT fEdge = GetEdgeWidth();
171       rect.Inflate(fEdge, fEdge);
172     }
173     if (HasBorder()) {
174       FX_FLOAT fBorder = GetBorderSize();
175       rect.Inflate(fBorder, fBorder);
176     }
177   } else {
178     rect = m_pProperties->m_rtWidget;
179   }
180   return FWL_ERR_Succeeded;
181 }
GetGlobalRect(CFX_RectF & rect)182 FWL_ERR CFWL_WidgetImp::GetGlobalRect(CFX_RectF& rect) {
183   IFWL_Widget* pForm =
184       m_pWidgetMgr->GetWidget(m_pInterface, FWL_WGTRELATION_SystemForm);
185   if (!pForm)
186     return FWL_ERR_Indefinite;
187   rect.Set(0, 0, m_pProperties->m_rtWidget.width,
188            m_pProperties->m_rtWidget.height);
189   if (pForm == m_pInterface) {
190     return FWL_ERR_Succeeded;
191   }
192   return TransformTo(pForm, rect);
193 }
SetWidgetRect(const CFX_RectF & rect)194 FWL_ERR CFWL_WidgetImp::SetWidgetRect(const CFX_RectF& rect) {
195   CFX_RectF rtOld = m_pProperties->m_rtWidget;
196   m_pProperties->m_rtWidget = rect;
197   if (IsChild()) {
198     if (FXSYS_fabs(rtOld.width - rect.width) > 0.5f ||
199         FXSYS_fabs(rtOld.height - rect.height) > 0.5f) {
200       CFWL_EvtSizeChanged ev;
201       ev.m_pSrcTarget = m_pInterface;
202       ev.m_rtOld = rtOld;
203       ev.m_rtNew = rect;
204       IFWL_WidgetDelegate* pDelegate = SetDelegate(NULL);
205       if (pDelegate) {
206         pDelegate->OnProcessEvent(&ev);
207       }
208     }
209     return FWL_ERR_Succeeded;
210   }
211   m_pWidgetMgr->SetWidgetRect_Native(m_pInterface, rect);
212   return FWL_ERR_Succeeded;
213 }
GetClientRect(CFX_RectF & rect)214 FWL_ERR CFWL_WidgetImp::GetClientRect(CFX_RectF& rect) {
215   GetEdgeRect(rect);
216   if (HasEdge()) {
217     FX_FLOAT fEdge = GetEdgeWidth();
218     rect.Deflate(fEdge, fEdge);
219   }
220   return FWL_ERR_Succeeded;
221 }
GetParent()222 IFWL_Widget* CFWL_WidgetImp::GetParent() {
223   return m_pWidgetMgr->GetWidget(m_pInterface, FWL_WGTRELATION_Parent);
224 }
SetParent(IFWL_Widget * pParent)225 FWL_ERR CFWL_WidgetImp::SetParent(IFWL_Widget* pParent) {
226   m_pProperties->m_pParent = pParent;
227   m_pWidgetMgr->SetParent(pParent, m_pInterface);
228   return FWL_ERR_Succeeded;
229 }
GetOwner()230 IFWL_Widget* CFWL_WidgetImp::GetOwner() {
231   return m_pWidgetMgr->GetWidget(m_pInterface, FWL_WGTRELATION_Owner);
232 }
SetOwner(IFWL_Widget * pOwner)233 FWL_ERR CFWL_WidgetImp::SetOwner(IFWL_Widget* pOwner) {
234   m_pProperties->m_pOwner = pOwner;
235   m_pWidgetMgr->SetOwner(pOwner, m_pInterface);
236   return FWL_ERR_Succeeded;
237 }
GetOuter()238 IFWL_Widget* CFWL_WidgetImp::GetOuter() {
239   return m_pOuter;
240 }
GetStyles()241 FX_DWORD CFWL_WidgetImp::GetStyles() {
242   return m_pProperties->m_dwStyles;
243 }
ModifyStyles(FX_DWORD dwStylesAdded,FX_DWORD dwStylesRemoved)244 FWL_ERR CFWL_WidgetImp::ModifyStyles(FX_DWORD dwStylesAdded,
245                                      FX_DWORD dwStylesRemoved) {
246   m_pProperties->m_dwStyles =
247       (m_pProperties->m_dwStyles & ~dwStylesRemoved) | dwStylesAdded;
248   return FWL_ERR_Succeeded;
249 }
GetStylesEx()250 FX_DWORD CFWL_WidgetImp::GetStylesEx() {
251   return m_pProperties->m_dwStyleExes;
252 }
ModifyStylesEx(FX_DWORD dwStylesExAdded,FX_DWORD dwStylesExRemoved)253 FWL_ERR CFWL_WidgetImp::ModifyStylesEx(FX_DWORD dwStylesExAdded,
254                                        FX_DWORD dwStylesExRemoved) {
255   m_pProperties->m_dwStyleExes =
256       (m_pProperties->m_dwStyleExes & ~dwStylesExRemoved) | dwStylesExAdded;
257   return FWL_ERR_Succeeded;
258 }
GetStates()259 FX_DWORD CFWL_WidgetImp::GetStates() {
260   return m_pProperties->m_dwStates;
261 }
NotifyHideChildWidget(IFWL_WidgetMgr * widgetMgr,IFWL_Widget * widget,CFWL_NoteDriver * noteDriver)262 static void NotifyHideChildWidget(IFWL_WidgetMgr* widgetMgr,
263                                   IFWL_Widget* widget,
264                                   CFWL_NoteDriver* noteDriver) {
265   IFWL_Widget* child = widgetMgr->GetWidget(widget, FWL_WGTRELATION_FirstChild);
266   while (child) {
267     noteDriver->NotifyTargetHide(child);
268     NotifyHideChildWidget(widgetMgr, child, noteDriver);
269     child = widgetMgr->GetWidget(child, FWL_WGTRELATION_NextSibling);
270   }
271 }
SetStates(FX_DWORD dwStates,FX_BOOL bSet)272 FWL_ERR CFWL_WidgetImp::SetStates(FX_DWORD dwStates, FX_BOOL bSet) {
273   bSet ? (m_pProperties->m_dwStates |= dwStates)
274        : (m_pProperties->m_dwStates &= ~dwStates);
275   FWL_ERR ret = FWL_ERR_Succeeded;
276   if (dwStates & FWL_WGTSTATE_Invisible) {
277     if (bSet) {
278       ret = m_pWidgetMgr->HideWidget_Native(m_pInterface);
279       CFWL_NoteDriver* noteDriver =
280           static_cast<CFWL_NoteDriver*>(GetOwnerThread()->GetNoteDriver());
281       IFWL_WidgetMgr* widgetMgr = FWL_GetWidgetMgr();
282       noteDriver->NotifyTargetHide(m_pInterface);
283       IFWL_Widget* child =
284           widgetMgr->GetWidget(m_pInterface, FWL_WGTRELATION_FirstChild);
285       while (child) {
286         noteDriver->NotifyTargetHide(child);
287         NotifyHideChildWidget(widgetMgr, child, noteDriver);
288         child = widgetMgr->GetWidget(child, FWL_WGTRELATION_NextSibling);
289       }
290     } else {
291       ret = m_pWidgetMgr->ShowWidget_Native(m_pInterface);
292     }
293   }
294   return ret;
295 }
SetPrivateData(void * module_id,void * pData,PD_CALLBACK_FREEDATA callback)296 FWL_ERR CFWL_WidgetImp::SetPrivateData(void* module_id,
297                                        void* pData,
298                                        PD_CALLBACK_FREEDATA callback) {
299   if (!m_pPrivateData) {
300     m_pPrivateData = new CFX_PrivateData;
301   }
302   m_pPrivateData->SetPrivateData(module_id, pData, callback);
303   return FWL_ERR_Succeeded;
304 }
GetPrivateData(void * module_id)305 void* CFWL_WidgetImp::GetPrivateData(void* module_id) {
306   if (!m_pPrivateData)
307     return NULL;
308   return m_pPrivateData->GetPrivateData(module_id);
309 }
Update()310 FWL_ERR CFWL_WidgetImp::Update() {
311   return FWL_ERR_Succeeded;
312 }
LockUpdate()313 FWL_ERR CFWL_WidgetImp::LockUpdate() {
314   m_iLock++;
315   return FWL_ERR_Succeeded;
316 }
UnlockUpdate()317 FWL_ERR CFWL_WidgetImp::UnlockUpdate() {
318   if (IsLocked()) {
319     m_iLock--;
320   }
321   return FWL_ERR_Succeeded;
322 }
HitTest(FX_FLOAT fx,FX_FLOAT fy)323 FX_DWORD CFWL_WidgetImp::HitTest(FX_FLOAT fx, FX_FLOAT fy) {
324   CFX_RectF rtClient;
325   GetClientRect(rtClient);
326   if (rtClient.Contains(fx, fy)) {
327     return FWL_WGTHITTEST_Client;
328   }
329   if (HasEdge()) {
330     CFX_RectF rtEdge;
331     GetEdgeRect(rtEdge);
332     if (rtEdge.Contains(fx, fy)) {
333       return FWL_WGTHITTEST_Edge;
334     }
335   }
336   if (HasBorder()) {
337     CFX_RectF rtRelative;
338     GetRelativeRect(rtRelative);
339     if (rtRelative.Contains(fx, fy)) {
340       return FWL_WGTHITTEST_Border;
341     }
342   }
343   return FWL_WGTHITTEST_Unknown;
344 }
TransformTo(IFWL_Widget * pWidget,FX_FLOAT & fx,FX_FLOAT & fy)345 FWL_ERR CFWL_WidgetImp::TransformTo(IFWL_Widget* pWidget,
346                                     FX_FLOAT& fx,
347                                     FX_FLOAT& fy) {
348   if (m_pWidgetMgr->IsFormDisabled()) {
349     CFX_SizeF szOffset;
350     if (IsParent(pWidget)) {
351       szOffset = GetOffsetFromParent(pWidget);
352     } else {
353       szOffset = pWidget->GetOffsetFromParent(m_pInterface);
354       szOffset.x = -szOffset.x;
355       szOffset.y = -szOffset.y;
356     }
357     fx += szOffset.x;
358     fy += szOffset.y;
359     return FWL_ERR_Succeeded;
360   }
361   CFX_RectF r;
362   CFX_Matrix m;
363   IFWL_Widget* parent = GetParent();
364   if (parent) {
365     GetWidgetRect(r);
366     fx += r.left;
367     fy += r.top;
368     GetMatrix(m, TRUE);
369     m.TransformPoint(fx, fy);
370   }
371   IFWL_Widget* form1 =
372       m_pWidgetMgr->GetWidget(m_pInterface, FWL_WGTRELATION_SystemForm);
373   if (!form1)
374     return FWL_ERR_Indefinite;
375   if (!pWidget) {
376     form1->GetWidgetRect(r);
377     fx += r.left;
378     fy += r.top;
379 #ifdef FWL_UseMacSystemBorder
380     if (form1->GetStyles() & FWL_WGTSTYLE_Caption) {
381       FX_FLOAT l, t, r, b;
382       l = t = r = b = 0;
383       FWL_GetAdapterWidgetMgr()->GetSystemBorder(l, t, r, b);
384       fy += t;
385     }
386 #endif
387     return FWL_ERR_Succeeded;
388   }
389   IFWL_Widget* form2 =
390       m_pWidgetMgr->GetWidget(pWidget, FWL_WGTRELATION_SystemForm);
391   if (!form2)
392     return FWL_ERR_Indefinite;
393   if (form1 != form2) {
394     form1->GetWidgetRect(r);
395     fx += r.left;
396     fy += r.top;
397     form2->GetWidgetRect(r);
398     fx -= r.left;
399     fy -= r.top;
400 #ifdef FWL_UseMacSystemBorder
401     if ((form1->GetStyles() & FWL_WGTSTYLE_Caption) !=
402         (form2->GetStyles() & FWL_WGTSTYLE_Caption)) {
403       FX_FLOAT l, t, r, b;
404       l = t = r = b = 0;
405       FWL_GetAdapterWidgetMgr()->GetSystemBorder(l, t, r, b);
406       (form1->GetStyles() & FWL_WGTSTYLE_Caption) ? (fy += t) : (fy -= t);
407     }
408 #endif
409   }
410   parent = pWidget->GetParent();
411   if (parent) {
412     pWidget->GetMatrix(m, TRUE);
413     CFX_Matrix m1;
414     m1.SetIdentity();
415     m1.SetReverse(m);
416     m1.TransformPoint(fx, fy);
417     pWidget->GetWidgetRect(r);
418     fx -= r.left;
419     fy -= r.top;
420   }
421   return FWL_ERR_Succeeded;
422 }
TransformTo(IFWL_Widget * pWidget,CFX_RectF & rt)423 FWL_ERR CFWL_WidgetImp::TransformTo(IFWL_Widget* pWidget, CFX_RectF& rt) {
424   return TransformTo(pWidget, rt.left, rt.top);
425 }
GetMatrix(CFX_Matrix & matrix,FX_BOOL bGlobal)426 FWL_ERR CFWL_WidgetImp::GetMatrix(CFX_Matrix& matrix, FX_BOOL bGlobal) {
427   if (!m_pProperties)
428     return FWL_ERR_Indefinite;
429   if (bGlobal) {
430     IFWL_Widget* parent = GetParent();
431     CFX_PtrArray parents;
432     while (parent) {
433       parents.Add(parent);
434       parent = parent->GetParent();
435     }
436     matrix.SetIdentity();
437     CFX_Matrix ctmOnParent;
438     CFX_RectF rect;
439     int32_t count = parents.GetSize();
440     for (int32_t i = count - 2; i >= 0; i--) {
441       parent = static_cast<IFWL_Widget*>(parents.GetAt(i));
442       parent->GetMatrix(ctmOnParent, FALSE);
443       parent->GetWidgetRect(rect);
444       matrix.Concat(ctmOnParent, TRUE);
445       matrix.Translate(rect.left, rect.top, TRUE);
446     }
447     matrix.Concat(m_pProperties->m_ctmOnParent, TRUE);
448     parents.RemoveAll();
449   } else {
450     matrix = m_pProperties->m_ctmOnParent;
451   }
452   return FWL_ERR_Succeeded;
453 }
SetMatrix(const CFX_Matrix & matrix)454 FWL_ERR CFWL_WidgetImp::SetMatrix(const CFX_Matrix& matrix) {
455   if (!m_pProperties)
456     return FWL_ERR_Indefinite;
457   IFWL_Widget* parent = GetParent();
458   if (!parent) {
459     return FWL_ERR_Indefinite;
460   }
461   m_pProperties->m_ctmOnParent = matrix;
462   return FWL_ERR_Succeeded;
463 }
DrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)464 FWL_ERR CFWL_WidgetImp::DrawWidget(CFX_Graphics* pGraphics,
465                                    const CFX_Matrix* pMatrix) {
466   return FWL_ERR_Indefinite;
467 }
GetThemeProvider()468 IFWL_ThemeProvider* CFWL_WidgetImp::GetThemeProvider() {
469   return m_pProperties->m_pThemeProvider;
470 }
SetThemeProvider(IFWL_ThemeProvider * pThemeProvider)471 FWL_ERR CFWL_WidgetImp::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) {
472   m_pProperties->m_pThemeProvider = pThemeProvider;
473   return FWL_ERR_Succeeded;
474 }
SetDataProvider(IFWL_DataProvider * pDataProvider)475 FWL_ERR CFWL_WidgetImp::SetDataProvider(IFWL_DataProvider* pDataProvider) {
476   m_pProperties->m_pDataProvider = pDataProvider;
477   return FWL_ERR_Succeeded;
478 }
SetDelegate(IFWL_WidgetDelegate * pDelegate)479 IFWL_WidgetDelegate* CFWL_WidgetImp::SetDelegate(
480     IFWL_WidgetDelegate* pDelegate) {
481   if (!m_pCurDelegate) {
482     m_pCurDelegate = m_pDelegate;
483   }
484   if (!pDelegate) {
485     return m_pCurDelegate;
486   }
487   IFWL_WidgetDelegate* pOldDelegate = m_pCurDelegate;
488   m_pCurDelegate = pDelegate;
489   return pOldDelegate;
490 }
GetOwnerThread() const491 IFWL_NoteThread* CFWL_WidgetImp::GetOwnerThread() const {
492   return static_cast<IFWL_NoteThread*>(m_pOwnerThread->GetInterface());
493 }
SetOwnerThread(CFWL_NoteThreadImp * pOwnerThread)494 FWL_ERR CFWL_WidgetImp::SetOwnerThread(CFWL_NoteThreadImp* pOwnerThread) {
495   m_pOwnerThread = pOwnerThread;
496   return FWL_ERR_Succeeded;
497 }
GetInterface() const498 IFWL_Widget* CFWL_WidgetImp::GetInterface() const {
499   return m_pInterface;
500 }
SetInterface(IFWL_Widget * pInterface)501 void CFWL_WidgetImp::SetInterface(IFWL_Widget* pInterface) {
502   m_pInterface = pInterface;
503 }
CFWL_WidgetImp(const CFWL_WidgetImpProperties & properties,IFWL_Widget * pOuter)504 CFWL_WidgetImp::CFWL_WidgetImp(const CFWL_WidgetImpProperties& properties,
505                                IFWL_Widget* pOuter)
506     : m_pProperties(new CFWL_WidgetImpProperties),
507       m_pPrivateData(NULL),
508       m_pDelegate(NULL),
509       m_pCurDelegate(NULL),
510       m_pOuter(pOuter),
511       m_pInterface(NULL),
512       m_iLock(0) {
513   *m_pProperties = properties;
514   m_pWidgetMgr = static_cast<CFWL_WidgetMgr*>(FWL_GetWidgetMgr());
515   FXSYS_assert(m_pWidgetMgr != NULL);
516 }
~CFWL_WidgetImp()517 CFWL_WidgetImp::~CFWL_WidgetImp() {
518   if (m_pPrivateData) {
519     delete m_pPrivateData;
520     m_pPrivateData = NULL;
521   }
522   if (m_pProperties) {
523     delete m_pProperties;
524     m_pProperties = NULL;
525   }
526 }
IsEnabled() const527 FX_BOOL CFWL_WidgetImp::IsEnabled() const {
528   return (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) == 0;
529 }
IsVisible() const530 FX_BOOL CFWL_WidgetImp::IsVisible() const {
531   return (m_pProperties->m_dwStates & FWL_WGTSTATE_Invisible) == 0;
532 }
IsActive() const533 FX_BOOL CFWL_WidgetImp::IsActive() const {
534   return (m_pProperties->m_dwStates & FWL_WGTSTATE_Deactivated) == 0;
535 }
IsOverLapper() const536 FX_BOOL CFWL_WidgetImp::IsOverLapper() const {
537   return (m_pProperties->m_dwStyles & FWL_WGTSTYLE_WindowTypeMask) ==
538          FWL_WGTSTYLE_OverLapper;
539 }
IsPopup() const540 FX_BOOL CFWL_WidgetImp::IsPopup() const {
541   return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Popup);
542 }
IsChild() const543 FX_BOOL CFWL_WidgetImp::IsChild() const {
544   return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Child);
545 }
IsLocked() const546 FX_BOOL CFWL_WidgetImp::IsLocked() const {
547   return m_iLock > 0;
548 }
IsOffscreen() const549 FX_BOOL CFWL_WidgetImp::IsOffscreen() const {
550   return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Offscreen);
551 }
HasBorder() const552 FX_BOOL CFWL_WidgetImp::HasBorder() const {
553   return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Border);
554 }
HasEdge() const555 FX_BOOL CFWL_WidgetImp::HasEdge() const {
556   return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_EdgeMask);
557 }
GetEdgeRect(CFX_RectF & rtEdge)558 void CFWL_WidgetImp::GetEdgeRect(CFX_RectF& rtEdge) {
559   rtEdge = m_pProperties->m_rtWidget;
560   rtEdge.left = rtEdge.top = 0;
561   if (HasBorder()) {
562     FX_FLOAT fCX = GetBorderSize();
563     FX_FLOAT fCY = GetBorderSize(FALSE);
564     rtEdge.Deflate(fCX, fCY);
565   }
566 }
GetBorderSize(FX_BOOL bCX)567 FX_FLOAT CFWL_WidgetImp::GetBorderSize(FX_BOOL bCX) {
568   FX_FLOAT* pfBorder = static_cast<FX_FLOAT*>(GetThemeCapacity(
569       bCX ? FWL_WGTCAPACITY_CXBorder : FWL_WGTCAPACITY_CYBorder));
570   if (!pfBorder)
571     return 0;
572   return *pfBorder;
573 }
GetEdgeWidth()574 FX_FLOAT CFWL_WidgetImp::GetEdgeWidth() {
575   FX_DWORD dwCapacity = 0;
576   switch (m_pProperties->m_dwStyles & FWL_WGTSTYLE_EdgeMask) {
577     case FWL_WGTSTYLE_EdgeFlat: {
578       dwCapacity = FWL_WGTCAPACITY_EdgeFlat;
579       break;
580     }
581     case FWL_WGTSTYLE_EdgeRaised: {
582       dwCapacity = FWL_WGTCAPACITY_EdgeRaised;
583       break;
584     }
585     case FWL_WGTSTYLE_EdgeSunken: {
586       dwCapacity = FWL_WGTCAPACITY_EdgeSunken;
587       break;
588     }
589   }
590   if (dwCapacity > 0) {
591     FX_FLOAT* fRet = static_cast<FX_FLOAT*>(GetThemeCapacity(dwCapacity));
592     return fRet ? *fRet : 0;
593   }
594   return 0;
595 }
GetRelativeRect(CFX_RectF & rect)596 void CFWL_WidgetImp::GetRelativeRect(CFX_RectF& rect) {
597   rect = m_pProperties->m_rtWidget;
598   rect.left = rect.top = 0;
599 }
GetThemeCapacity(FX_DWORD dwCapacity)600 void* CFWL_WidgetImp::GetThemeCapacity(FX_DWORD dwCapacity) {
601   IFWL_ThemeProvider* pTheme = GetAvailableTheme();
602   if (!pTheme)
603     return NULL;
604   CFWL_ThemePart part;
605   part.m_pWidget = m_pInterface;
606   return pTheme->GetCapacity(&part, dwCapacity);
607 }
GetAvailableTheme()608 IFWL_ThemeProvider* CFWL_WidgetImp::GetAvailableTheme() {
609   if (m_pProperties->m_pThemeProvider) {
610     return m_pProperties->m_pThemeProvider;
611   }
612   IFWL_Widget* pUp = m_pInterface;
613   do {
614     FWL_WGTRELATION relation = (pUp->GetStyles() & FWL_WGTSTYLE_Popup)
615                                    ? FWL_WGTRELATION_Owner
616                                    : FWL_WGTRELATION_Parent;
617     pUp = m_pWidgetMgr->GetWidget(pUp, relation);
618     if (pUp) {
619       IFWL_ThemeProvider* pRet = pUp->GetThemeProvider();
620       if (pRet && pRet->IsValidWidget(m_pInterface)) {
621         return pRet;
622       }
623     }
624   } while (pUp);
625   return FWL_GetApp()->GetThemeProvider();
626 }
GetRootOuter()627 CFWL_WidgetImp* CFWL_WidgetImp::GetRootOuter() {
628   IFWL_Widget* pRet = m_pOuter;
629   if (!pRet)
630     return nullptr;
631   while (IFWL_Widget* pOuter = pRet->GetOuter()) {
632     pRet = pOuter;
633   }
634   return static_cast<CFWL_WidgetImp*>(pRet->GetImpl());
635 }
636 #define FWL_WGT_CalcHeight 2048
637 #define FWL_WGT_CalcWidth 2048
638 #define FWL_WGT_CalcMultiLineDefWidth 120.0f
CalcTextSize(const CFX_WideString & wsText,IFWL_ThemeProvider * pTheme,FX_BOOL bMultiLine,int32_t iLineWidth)639 CFX_SizeF CFWL_WidgetImp::CalcTextSize(const CFX_WideString& wsText,
640                                        IFWL_ThemeProvider* pTheme,
641                                        FX_BOOL bMultiLine,
642                                        int32_t iLineWidth) {
643   CFX_SizeF sz;
644   sz.Set(0, 0);
645   if (!pTheme)
646     return sz;
647   CFWL_ThemeText calPart;
648   calPart.m_pWidget = m_pInterface;
649   calPart.m_wsText = wsText;
650   calPart.m_dwTTOStyles =
651       bMultiLine ? FDE_TTOSTYLE_LineWrap : FDE_TTOSTYLE_SingleLine;
652   calPart.m_iTTOAlign = FDE_TTOALIGNMENT_TopLeft;
653   CFX_RectF rect;
654   FX_FLOAT fWidth = bMultiLine
655                         ? (iLineWidth > 0 ? (FX_FLOAT)iLineWidth
656                                           : FWL_WGT_CalcMultiLineDefWidth)
657                         : FWL_WGT_CalcWidth;
658   rect.Set(0, 0, fWidth, FWL_WGT_CalcHeight);
659   pTheme->CalcTextRect(&calPart, rect);
660   sz.x = rect.width;
661   sz.y = rect.height;
662   return sz;
663 }
CalcTextRect(const CFX_WideString & wsText,IFWL_ThemeProvider * pTheme,FX_DWORD dwTTOStyles,int32_t iTTOAlign,CFX_RectF & rect)664 void CFWL_WidgetImp::CalcTextRect(const CFX_WideString& wsText,
665                                   IFWL_ThemeProvider* pTheme,
666                                   FX_DWORD dwTTOStyles,
667                                   int32_t iTTOAlign,
668                                   CFX_RectF& rect) {
669   CFWL_ThemeText calPart;
670   calPart.m_pWidget = m_pInterface;
671   calPart.m_wsText = wsText;
672   calPart.m_dwTTOStyles = dwTTOStyles;
673   calPart.m_iTTOAlign = iTTOAlign;
674   pTheme->CalcTextRect(&calPart, rect);
675 }
SetFocus(FX_BOOL bFocus)676 void CFWL_WidgetImp::SetFocus(FX_BOOL bFocus) {
677   if (m_pWidgetMgr->IsFormDisabled())
678     return;
679   IFWL_NoteThread* pThread = GetOwnerThread();
680   if (!pThread)
681     return;
682   CFWL_NoteDriver* pDriver =
683       static_cast<CFWL_NoteDriver*>(pThread->GetNoteDriver());
684   if (!pDriver)
685     return;
686   IFWL_Widget* curFocus = pDriver->GetFocus();
687   if (bFocus && curFocus != m_pInterface) {
688     pDriver->SetFocus(m_pInterface);
689   } else if (!bFocus && curFocus == m_pInterface) {
690     pDriver->SetFocus(NULL);
691   }
692 }
SetGrab(FX_BOOL bSet)693 void CFWL_WidgetImp::SetGrab(FX_BOOL bSet) {
694   IFWL_NoteThread* pThread = GetOwnerThread();
695   if (!pThread)
696     return;
697   CFWL_NoteDriver* pDriver =
698       static_cast<CFWL_NoteDriver*>(pThread->GetNoteDriver());
699   pDriver->SetGrab(m_pInterface, bSet);
700 }
GetPopupPos(FX_FLOAT fMinHeight,FX_FLOAT fMaxHeight,const CFX_RectF & rtAnchor,CFX_RectF & rtPopup)701 FX_BOOL CFWL_WidgetImp::GetPopupPos(FX_FLOAT fMinHeight,
702                                     FX_FLOAT fMaxHeight,
703                                     const CFX_RectF& rtAnchor,
704                                     CFX_RectF& rtPopup) {
705   if (GetClassID() == FWL_CLASSHASH_Menu) {
706     return GetPopupPosMenu(fMinHeight, fMaxHeight, rtAnchor, rtPopup);
707   } else {
708     if (GetClassID() == FWL_CLASSHASH_ComboBox) {
709       if (m_pWidgetMgr->IsFormDisabled()) {
710         return m_pWidgetMgr->GetAdapterPopupPos(m_pInterface, fMinHeight,
711                                                 fMaxHeight, rtAnchor, rtPopup);
712       } else {
713         return GetPopupPosComboBox(fMinHeight, fMaxHeight, rtAnchor, rtPopup);
714       }
715     } else if (GetClassID() == FWL_CLASSHASH_DateTimePicker &&
716                m_pWidgetMgr->IsFormDisabled()) {
717       return m_pWidgetMgr->GetAdapterPopupPos(m_pInterface, fMinHeight,
718                                               fMaxHeight, rtAnchor, rtPopup);
719     } else {
720       return GetPopupPosGeneral(fMinHeight, fMaxHeight, rtAnchor, rtPopup);
721     }
722   }
723   return FALSE;
724 }
GetPopupPosMenu(FX_FLOAT fMinHeight,FX_FLOAT fMaxHeight,const CFX_RectF & rtAnchor,CFX_RectF & rtPopup)725 FX_BOOL CFWL_WidgetImp::GetPopupPosMenu(FX_FLOAT fMinHeight,
726                                         FX_FLOAT fMaxHeight,
727                                         const CFX_RectF& rtAnchor,
728                                         CFX_RectF& rtPopup) {
729   FX_FLOAT fx = 0;
730   FX_FLOAT fy = 0;
731   FX_FLOAT fScreenWidth = 0;
732   FX_FLOAT fScreenHeight = 0;
733   GetScreenSize(fScreenWidth, fScreenHeight);
734   if (GetStylesEx() & FWL_STYLEEXT_MNU_Vert) {
735     FX_BOOL bLeft = m_pProperties->m_rtWidget.left < 0;
736     FX_FLOAT fRight = rtAnchor.right() + rtPopup.width;
737     TransformTo(NULL, fx, fy);
738     if (fRight + fx > fScreenWidth || bLeft) {
739       rtPopup.Set(rtAnchor.left - rtPopup.width, rtAnchor.top, rtPopup.width,
740                   rtPopup.height);
741     } else {
742       rtPopup.Set(rtAnchor.right(), rtAnchor.top, rtPopup.width,
743                   rtPopup.height);
744     }
745   } else {
746     FX_FLOAT fBottom = rtAnchor.bottom() + rtPopup.height;
747     TransformTo(NULL, fx, fy);
748     if (fBottom + fy > fScreenHeight) {
749       rtPopup.Set(rtAnchor.left, rtAnchor.top - rtPopup.height, rtPopup.width,
750                   rtPopup.height);
751     } else {
752       rtPopup.Set(rtAnchor.left, rtAnchor.bottom(), rtPopup.width,
753                   rtPopup.height);
754     }
755   }
756   rtPopup.Offset(fx, fy);
757   return TRUE;
758 }
GetPopupPosComboBox(FX_FLOAT fMinHeight,FX_FLOAT fMaxHeight,const CFX_RectF & rtAnchor,CFX_RectF & rtPopup)759 FX_BOOL CFWL_WidgetImp::GetPopupPosComboBox(FX_FLOAT fMinHeight,
760                                             FX_FLOAT fMaxHeight,
761                                             const CFX_RectF& rtAnchor,
762                                             CFX_RectF& rtPopup) {
763   FX_FLOAT fx = 0;
764   FX_FLOAT fy = 0;
765   FX_FLOAT fScreenWidth = 0;
766   FX_FLOAT fScreenHeight = 0;
767   GetScreenSize(fScreenWidth, fScreenHeight);
768   FX_FLOAT fPopHeight = rtPopup.height;
769   if (rtPopup.height > fMaxHeight) {
770     fPopHeight = fMaxHeight;
771   } else if (rtPopup.height < fMinHeight) {
772     fPopHeight = fMinHeight;
773   }
774   FX_FLOAT fWidth = std::max(rtAnchor.width, rtPopup.width);
775   FX_FLOAT fBottom = rtAnchor.bottom() + fPopHeight;
776   TransformTo(NULL, fx, fy);
777   if (fBottom + fy > fScreenHeight) {
778     rtPopup.Set(rtAnchor.left, rtAnchor.top - fPopHeight, fWidth, fPopHeight);
779   } else {
780     rtPopup.Set(rtAnchor.left, rtAnchor.bottom(), fWidth, fPopHeight);
781   }
782   rtPopup.Offset(fx, fy);
783   return TRUE;
784 }
GetPopupPosGeneral(FX_FLOAT fMinHeight,FX_FLOAT fMaxHeight,const CFX_RectF & rtAnchor,CFX_RectF & rtPopup)785 FX_BOOL CFWL_WidgetImp::GetPopupPosGeneral(FX_FLOAT fMinHeight,
786                                            FX_FLOAT fMaxHeight,
787                                            const CFX_RectF& rtAnchor,
788                                            CFX_RectF& rtPopup) {
789   FX_FLOAT fx = 0;
790   FX_FLOAT fy = 0;
791   FX_FLOAT fScreenWidth = 0;
792   FX_FLOAT fScreenHeight = 0;
793   GetScreenSize(fScreenWidth, fScreenHeight);
794   TransformTo(NULL, fx, fy);
795   if (rtAnchor.bottom() + fy > fScreenHeight) {
796     rtPopup.Set(rtAnchor.left, rtAnchor.top - rtPopup.height, rtPopup.width,
797                 rtPopup.height);
798   } else {
799     rtPopup.Set(rtAnchor.left, rtAnchor.bottom(), rtPopup.width,
800                 rtPopup.height);
801   }
802   rtPopup.Offset(fx, fy);
803   return TRUE;
804 }
GetScreenSize(FX_FLOAT & fx,FX_FLOAT & fy)805 FX_BOOL CFWL_WidgetImp::GetScreenSize(FX_FLOAT& fx, FX_FLOAT& fy) {
806   IFWL_AdapterNative* pNative = FWL_GetAdapterNative();
807   IFWL_AdapterMonitorMgr* pMonitorMgr = pNative->GetMonitorMgr();
808   if (!pMonitorMgr)
809     return FALSE;
810   FWL_HMONITOR hMonitor = pMonitorMgr->GetMonitorByPoint(fx, fy);
811   pMonitorMgr->GetMonitorSize(hMonitor, fx, fy);
812   return TRUE;
813 }
RegisterEventTarget(IFWL_Widget * pEventSource,FX_DWORD dwFilter)814 void CFWL_WidgetImp::RegisterEventTarget(IFWL_Widget* pEventSource,
815                                          FX_DWORD dwFilter) {
816   IFWL_NoteThread* pThread = GetOwnerThread();
817   if (!pThread)
818     return;
819   IFWL_NoteDriver* pNoteDriver = pThread->GetNoteDriver();
820   if (!pNoteDriver)
821     return;
822   pNoteDriver->RegisterEventTarget(m_pInterface, pEventSource, dwFilter);
823 }
UnregisterEventTarget()824 void CFWL_WidgetImp::UnregisterEventTarget() {
825   IFWL_NoteThread* pThread = GetOwnerThread();
826   if (!pThread)
827     return;
828   IFWL_NoteDriver* pNoteDriver = pThread->GetNoteDriver();
829   if (!pNoteDriver)
830     return;
831   pNoteDriver->UnregisterEventTarget(m_pInterface);
832 }
DispatchKeyEvent(CFWL_MsgKey * pNote)833 void CFWL_WidgetImp::DispatchKeyEvent(CFWL_MsgKey* pNote) {
834   if (!pNote)
835     return;
836   CFWL_EvtKey* pEvent = new CFWL_EvtKey;
837   pEvent->m_pSrcTarget = m_pInterface;
838   pEvent->m_dwCmd = pNote->m_dwCmd;
839   pEvent->m_dwKeyCode = pNote->m_dwKeyCode;
840   pEvent->m_dwFlags = pNote->m_dwFlags;
841   DispatchEvent(pEvent);
842   pEvent->Release();
843 }
DispatchEvent(CFWL_Event * pEvent)844 void CFWL_WidgetImp::DispatchEvent(CFWL_Event* pEvent) {
845   if (m_pOuter) {
846     IFWL_WidgetDelegate* pDelegate = m_pOuter->SetDelegate(NULL);
847     pDelegate->OnProcessEvent(pEvent);
848     return;
849   }
850   IFWL_NoteThread* pThread = GetOwnerThread();
851   if (!pThread)
852     return;
853   IFWL_NoteDriver* pNoteDriver = pThread->GetNoteDriver();
854   if (!pNoteDriver)
855     return;
856   pNoteDriver->SendNote(pEvent);
857 }
Repaint(const CFX_RectF * pRect)858 void CFWL_WidgetImp::Repaint(const CFX_RectF* pRect) {
859   if (pRect) {
860     m_pWidgetMgr->RepaintWidget(m_pInterface, pRect);
861     return;
862   }
863   CFX_RectF rect;
864   rect = m_pProperties->m_rtWidget;
865   rect.left = rect.top = 0;
866   m_pWidgetMgr->RepaintWidget(m_pInterface, &rect);
867 }
DrawBackground(CFX_Graphics * pGraphics,int32_t iPartBk,IFWL_ThemeProvider * pTheme,const CFX_Matrix * pMatrix)868 void CFWL_WidgetImp::DrawBackground(CFX_Graphics* pGraphics,
869                                     int32_t iPartBk,
870                                     IFWL_ThemeProvider* pTheme,
871                                     const CFX_Matrix* pMatrix) {
872   CFX_RectF rtRelative;
873   GetRelativeRect(rtRelative);
874   CFWL_ThemeBackground param;
875   param.m_pWidget = m_pInterface;
876   param.m_iPart = iPartBk;
877   param.m_pGraphics = pGraphics;
878   if (pMatrix) {
879     param.m_matrix.Concat(*pMatrix, TRUE);
880   }
881   param.m_rtPart = rtRelative;
882   pTheme->DrawBackground(&param);
883 }
DrawBorder(CFX_Graphics * pGraphics,int32_t iPartBorder,IFWL_ThemeProvider * pTheme,const CFX_Matrix * pMatrix)884 void CFWL_WidgetImp::DrawBorder(CFX_Graphics* pGraphics,
885                                 int32_t iPartBorder,
886                                 IFWL_ThemeProvider* pTheme,
887                                 const CFX_Matrix* pMatrix) {
888   CFX_RectF rtRelative;
889   GetRelativeRect(rtRelative);
890   CFWL_ThemeBackground param;
891   param.m_pWidget = m_pInterface;
892   param.m_iPart = iPartBorder;
893   param.m_pGraphics = pGraphics;
894   if (pMatrix) {
895     param.m_matrix.Concat(*pMatrix, TRUE);
896   }
897   param.m_rtPart = rtRelative;
898   pTheme->DrawBackground(&param);
899 }
DrawEdge(CFX_Graphics * pGraphics,int32_t iPartEdge,IFWL_ThemeProvider * pTheme,const CFX_Matrix * pMatrix)900 void CFWL_WidgetImp::DrawEdge(CFX_Graphics* pGraphics,
901                               int32_t iPartEdge,
902                               IFWL_ThemeProvider* pTheme,
903                               const CFX_Matrix* pMatrix) {
904   CFX_RectF rtEdge;
905   GetEdgeRect(rtEdge);
906   CFWL_ThemeBackground param;
907   param.m_pWidget = m_pInterface;
908   param.m_iPart = iPartEdge;
909   param.m_pGraphics = pGraphics;
910   if (pMatrix) {
911     param.m_matrix.Concat(*pMatrix, TRUE);
912   }
913   param.m_rtPart = rtEdge;
914   pTheme->DrawBackground(&param);
915 }
NotifyDriver()916 void CFWL_WidgetImp::NotifyDriver() {
917   IFWL_NoteThread* pThread = GetOwnerThread();
918   if (!pThread)
919     return;
920   CFWL_NoteDriver* pDriver =
921       static_cast<CFWL_NoteDriver*>(pThread->GetNoteDriver());
922   if (!pDriver)
923     return;
924   pDriver->NotifyTargetDestroy(m_pInterface);
925 }
GetOffsetFromParent(IFWL_Widget * pParent)926 CFX_SizeF CFWL_WidgetImp::GetOffsetFromParent(IFWL_Widget* pParent) {
927   CFX_SizeF szRet;
928   szRet.Set(0, 0);
929   if (pParent == GetInterface()) {
930     return szRet;
931   }
932   IFWL_WidgetMgr* pWidgetMgr = FWL_GetWidgetMgr();
933   if (!pWidgetMgr)
934     return szRet;
935   szRet.x += m_pProperties->m_rtWidget.left;
936   szRet.y += m_pProperties->m_rtWidget.top;
937   IFWL_Widget* pDstWidget = GetParent();
938   while (pDstWidget && pDstWidget != pParent) {
939     CFX_RectF rtDst;
940     pDstWidget->GetWidgetRect(rtDst);
941     szRet.x += rtDst.left;
942     szRet.y += rtDst.top;
943     pDstWidget = pWidgetMgr->GetWidget(pDstWidget, FWL_WGTRELATION_Parent);
944   }
945   return szRet;
946 }
IsParent(IFWL_Widget * pParent)947 FX_BOOL CFWL_WidgetImp::IsParent(IFWL_Widget* pParent) {
948   IFWL_Widget* pUpWidget = GetParent();
949   while (pUpWidget) {
950     if (pUpWidget == pParent)
951       return TRUE;
952     pUpWidget = pUpWidget->GetParent();
953   }
954   return FALSE;
955 }
CFWL_WidgetImpDelegate()956 CFWL_WidgetImpDelegate::CFWL_WidgetImpDelegate() {}
OnProcessMessage(CFWL_Message * pMessage)957 int32_t CFWL_WidgetImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
958   if (!pMessage->m_pDstTarget)
959     return 0;
960   CFWL_WidgetImp* pWidget =
961       static_cast<CFWL_WidgetImp*>(pMessage->m_pDstTarget->GetImpl());
962   FX_DWORD dwMsgCode = pMessage->GetClassID();
963   switch (dwMsgCode) {
964     case FWL_MSGHASH_Mouse: {
965       CFWL_MsgMouse* pMsgMouse = static_cast<CFWL_MsgMouse*>(pMessage);
966       CFWL_EvtMouse evt;
967       evt.m_pSrcTarget = pWidget->m_pInterface;
968       evt.m_pDstTarget = pWidget->m_pInterface;
969       evt.m_dwCmd = pMsgMouse->m_dwCmd;
970       evt.m_dwFlags = pMsgMouse->m_dwFlags;
971       evt.m_fx = pMsgMouse->m_fx;
972       evt.m_fy = pMsgMouse->m_fy;
973       pWidget->DispatchEvent(&evt);
974       break;
975     }
976     case FWL_MSGHASH_MouseWheel: {
977       CFWL_MsgMouseWheel* pMsgMouseWheel =
978           static_cast<CFWL_MsgMouseWheel*>(pMessage);
979       CFWL_EvtMouseWheel evt;
980       evt.m_pSrcTarget = pWidget->m_pInterface;
981       evt.m_pDstTarget = pWidget->m_pInterface;
982       evt.m_dwFlags = pMsgMouseWheel->m_dwFlags;
983       evt.m_fDeltaX = pMsgMouseWheel->m_fDeltaX;
984       evt.m_fDeltaY = pMsgMouseWheel->m_fDeltaY;
985       evt.m_fx = pMsgMouseWheel->m_fx;
986       evt.m_fy = pMsgMouseWheel->m_fy;
987       pWidget->DispatchEvent(&evt);
988       break;
989     }
990     case FWL_MSGHASH_Key: {
991       CFWL_MsgKey* pMsgKey = static_cast<CFWL_MsgKey*>(pMessage);
992       CFWL_EvtKey evt;
993       evt.m_pSrcTarget = pWidget->m_pInterface;
994       evt.m_pDstTarget = pWidget->m_pInterface;
995       evt.m_dwKeyCode = pMsgKey->m_dwKeyCode;
996       evt.m_dwFlags = pMsgKey->m_dwFlags;
997       evt.m_dwCmd = pMsgKey->m_dwCmd;
998       pWidget->DispatchEvent(&evt);
999       break;
1000     }
1001     case FWL_MSGHASH_SetFocus: {
1002       CFWL_MsgSetFocus* pMsgSetFocus = static_cast<CFWL_MsgSetFocus*>(pMessage);
1003       CFWL_EvtSetFocus evt;
1004       evt.m_pSrcTarget = pMsgSetFocus->m_pDstTarget;
1005       evt.m_pDstTarget = pMsgSetFocus->m_pDstTarget;
1006       evt.m_pSetFocus = pWidget->m_pInterface;
1007       pWidget->DispatchEvent(&evt);
1008       break;
1009     }
1010     case FWL_MSGHASH_KillFocus: {
1011       CFWL_MsgKillFocus* pMsgKillFocus =
1012           static_cast<CFWL_MsgKillFocus*>(pMessage);
1013       CFWL_EvtKillFocus evt;
1014       evt.m_pSrcTarget = pMsgKillFocus->m_pDstTarget;
1015       evt.m_pDstTarget = pMsgKillFocus->m_pDstTarget;
1016       evt.m_pKillFocus = pWidget->m_pInterface;
1017       pWidget->DispatchEvent(&evt);
1018       break;
1019     }
1020     default: {}
1021   }
1022   return 1;
1023 }
OnProcessEvent(CFWL_Event * pEvent)1024 FWL_ERR CFWL_WidgetImpDelegate::OnProcessEvent(CFWL_Event* pEvent) {
1025   return FWL_ERR_Succeeded;
1026 }
OnDrawWidget(CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)1027 FWL_ERR CFWL_WidgetImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics,
1028                                              const CFX_Matrix* pMatrix) {
1029   CFWL_EvtDraw evt;
1030   evt.m_pGraphics = pGraphics;
1031   return FWL_ERR_Succeeded;
1032 }
1033 class CFWL_CustomImp : public CFWL_WidgetImp {
1034  public:
1035   CFWL_CustomImp(const CFWL_WidgetImpProperties& properties,
1036                  IFWL_Widget* pOuter);
1037   virtual FWL_ERR GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize = FALSE);
1038   virtual FWL_ERR Update();
1039   virtual FWL_ERR SetProxy(IFWL_Proxy* pProxy);
1040 
1041  protected:
1042   IFWL_Proxy* m_pProxy;
1043 };
CFWL_CustomImp(const CFWL_WidgetImpProperties & properties,IFWL_Widget * pOuter)1044 CFWL_CustomImp::CFWL_CustomImp(const CFWL_WidgetImpProperties& properties,
1045                                IFWL_Widget* pOuter)
1046     : CFWL_WidgetImp(properties, pOuter), m_pProxy(NULL) {}
GetWidgetRect(CFX_RectF & rect,FX_BOOL bAutoSize)1047 FWL_ERR CFWL_CustomImp::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
1048   if (m_pProxy &&
1049       (m_pProxy->GetWidgetRect(rect, bAutoSize) == FWL_ERR_Succeeded)) {
1050     return FWL_ERR_Succeeded;
1051   }
1052   return CFWL_WidgetImp::GetWidgetRect(rect, bAutoSize);
1053 }
Update()1054 FWL_ERR CFWL_CustomImp::Update() {
1055   if (m_pProxy) {
1056     return m_pProxy->Update();
1057   }
1058   return CFWL_WidgetImp::Update();
1059 }
SetProxy(IFWL_Proxy * pProxy)1060 FWL_ERR CFWL_CustomImp::SetProxy(IFWL_Proxy* pProxy) {
1061   m_pProxy = pProxy;
1062   return FWL_ERR_Succeeded;
1063 }
1064 
1065 // static
Create(const CFWL_WidgetImpProperties & properties,IFWL_Widget * pOuter)1066 IFWL_Custom* IFWL_Custom::Create(const CFWL_WidgetImpProperties& properties,
1067                                  IFWL_Widget* pOuter) {
1068   IFWL_Custom* pCustom = new IFWL_Custom;
1069   CFWL_CustomImp* pCustomImpl = new CFWL_CustomImp(properties, pOuter);
1070   pCustom->SetImpl(pCustomImpl);
1071   pCustomImpl->SetInterface(pCustom);
1072   return pCustom;
1073 }
IFWL_Custom()1074 IFWL_Custom::IFWL_Custom() {}
SetProxy(IFWL_Proxy * pProxy)1075 FWL_ERR IFWL_Custom::SetProxy(IFWL_Proxy* pProxy) {
1076   return static_cast<CFWL_CustomImp*>(GetImpl())->SetProxy(pProxy);
1077 }
FWL_SetWidgetRect(IFWL_Widget * widget,const CFX_RectF & rect)1078 void FWL_SetWidgetRect(IFWL_Widget* widget, const CFX_RectF& rect) {
1079   static_cast<CFWL_WidgetImp*>(widget->GetImpl())->m_pProperties->m_rtWidget =
1080       rect;
1081 }
FWL_SetWidgetStates(IFWL_Widget * widget,FX_DWORD dwStates)1082 void FWL_SetWidgetStates(IFWL_Widget* widget, FX_DWORD dwStates) {
1083   static_cast<CFWL_WidgetImp*>(widget->GetImpl())->m_pProperties->m_dwStates =
1084       dwStates;
1085 }
FWL_SetWidgetStyles(IFWL_Widget * widget,FX_DWORD dwStyles)1086 void FWL_SetWidgetStyles(IFWL_Widget* widget, FX_DWORD dwStyles) {
1087   static_cast<CFWL_WidgetImp*>(widget->GetImpl())->m_pProperties->m_dwStyles =
1088       dwStyles;
1089 }
FWL_EnabelWidget(IFWL_Widget * widget,FX_BOOL bEnable)1090 FWL_ERR FWL_EnabelWidget(IFWL_Widget* widget, FX_BOOL bEnable) {
1091   widget->SetStates(FWL_WGTSTATE_Disabled, !bEnable);
1092   IFWL_WidgetMgr* widgetMgr = FWL_GetWidgetMgr();
1093   IFWL_Widget* child = widgetMgr->GetWidget(widget, FWL_WGTRELATION_FirstChild);
1094   while (child) {
1095     FWL_EnabelWidget(child, bEnable);
1096     child = widgetMgr->GetWidget(child, FWL_WGTRELATION_NextSibling);
1097   }
1098   return FWL_ERR_Succeeded;
1099 }
1100