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/src/foxitlib.h"
8 #include "xfa/src/fwl/src/core/include/fwl_targetimp.h"
9 #include "xfa/src/fwl/src/core/include/fwl_noteimp.h"
10 #include "xfa/src/fwl/src/core/include/fwl_widgetmgrimp.h"
11 #include "xfa/src/fwl/src/core/include/fwl_threadimp.h"
12 #include "xfa/src/fwl/src/core/include/fwl_appimp.h"
13
FWL_UseOffscreen(IFWL_Widget * pWidget)14 FX_BOOL FWL_UseOffscreen(IFWL_Widget* pWidget) {
15 #if (_FX_OS_ == _FX_MACOSX_)
16 return FALSE;
17 #else
18 return pWidget->GetStyles() & FWL_WGTSTYLE_Offscreen;
19 #endif
20 }
FWL_GetWidgetMgr()21 IFWL_WidgetMgr* FWL_GetWidgetMgr() {
22 IFWL_App* pApp = FWL_GetApp();
23 if (!pApp)
24 return NULL;
25 return pApp->GetWidgetMgr();
26 }
CFWL_WidgetMgr(IFWL_AdapterNative * pAdapterNative)27 CFWL_WidgetMgr::CFWL_WidgetMgr(IFWL_AdapterNative* pAdapterNative)
28 : m_dwCapability(0) {
29 m_pDelegate = new CFWL_WidgetMgrDelegate(this);
30 m_pAdapter = pAdapterNative->GetWidgetMgr(m_pDelegate);
31 FXSYS_assert(m_pAdapter);
32 CFWL_WidgetMgrItem* pRoot = new CFWL_WidgetMgrItem;
33 m_mapWidgetItem.SetAt(NULL, pRoot);
34 #if (_FX_OS_ == _FX_WIN32_DESKTOP_) || (_FX_OS_ == _FX_WIN64_)
35 m_rtScreen.Reset();
36 IFWL_AdapterMonitorMgr* pMonitorMgr = pAdapterNative->GetMonitorMgr();
37 if (pMonitorMgr) {
38 FWL_HMONITOR monitor = pMonitorMgr->GetCurrentMonitor();
39 if (monitor) {
40 pMonitorMgr->GetMonitorSize(monitor, m_rtScreen.width, m_rtScreen.height);
41 }
42 }
43 #endif
44 }
~CFWL_WidgetMgr()45 CFWL_WidgetMgr::~CFWL_WidgetMgr() {
46 FX_POSITION ps = m_mapWidgetItem.GetStartPosition();
47 while (ps) {
48 void* pWidget;
49 CFWL_WidgetMgrItem* pItem;
50 m_mapWidgetItem.GetNextAssoc(ps, pWidget, (void*&)pItem);
51 delete pItem;
52 }
53 m_mapWidgetItem.RemoveAll();
54 if (m_pDelegate) {
55 delete m_pDelegate;
56 m_pDelegate = NULL;
57 }
58 }
CountWidgets(IFWL_Widget * pParent)59 int32_t CFWL_WidgetMgr::CountWidgets(IFWL_Widget* pParent) {
60 CFWL_WidgetMgrItem* pParentItem = GetWidgetMgrItem(pParent);
61 return TravelWidgetMgr(pParentItem, NULL, NULL);
62 }
GetWidget(int32_t nIndex,IFWL_Widget * pParent)63 IFWL_Widget* CFWL_WidgetMgr::GetWidget(int32_t nIndex, IFWL_Widget* pParent) {
64 CFWL_WidgetMgrItem* pParentItem = GetWidgetMgrItem(pParent);
65 IFWL_Widget* pWidget = NULL;
66 TravelWidgetMgr(pParentItem, &nIndex, NULL, &pWidget);
67 return pWidget;
68 }
GetWidget(IFWL_Widget * pWidget,FWL_WGTRELATION eRelation)69 IFWL_Widget* CFWL_WidgetMgr::GetWidget(IFWL_Widget* pWidget,
70 FWL_WGTRELATION eRelation) {
71 CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget);
72 if (!pItem) {
73 return NULL;
74 }
75 IFWL_Widget* pRet = NULL;
76 switch (eRelation) {
77 case FWL_WGTRELATION_Parent: {
78 pRet = pItem->pParent ? pItem->pParent->pWidget : NULL;
79 break;
80 }
81 case FWL_WGTRELATION_Owner: {
82 pRet = pItem->pOwner ? pItem->pOwner->pWidget : NULL;
83 break;
84 }
85 case FWL_WGTRELATION_FirstSibling: {
86 pItem = pItem->pPrevious;
87 while (pItem && pItem->pPrevious) {
88 pItem = pItem->pPrevious;
89 }
90 pRet = pItem ? pItem->pWidget : NULL;
91 break;
92 }
93 case FWL_WGTRELATION_PriorSibling: {
94 pRet = pItem->pPrevious ? pItem->pPrevious->pWidget : NULL;
95 break;
96 }
97 case FWL_WGTRELATION_NextSibling: {
98 pRet = pItem->pNext ? pItem->pNext->pWidget : NULL;
99 break;
100 }
101 case FWL_WGTRELATION_LastSibling: {
102 pItem = pItem->pNext;
103 while (pItem && pItem->pNext) {
104 pItem = pItem->pNext;
105 }
106 pRet = pItem ? pItem->pWidget : NULL;
107 break;
108 }
109 case FWL_WGTRELATION_FirstChild: {
110 pRet = pItem->pChild ? pItem->pChild->pWidget : NULL;
111 break;
112 }
113 case FWL_WGTRELATION_LastChild: {
114 pItem = pItem->pChild;
115 while (pItem && pItem->pNext) {
116 pItem = pItem->pNext;
117 }
118 pRet = pItem ? pItem->pWidget : NULL;
119 break;
120 }
121 case FWL_WGTRELATION_SystemForm: {
122 while (pItem) {
123 if (IsAbleNative(pItem->pWidget)) {
124 pRet = pItem->pWidget;
125 break;
126 }
127 pItem = pItem->pParent;
128 }
129 break;
130 }
131 default: {}
132 }
133 return pRet;
134 }
GetWidgetIndex(IFWL_Widget * pWidget)135 int32_t CFWL_WidgetMgr::GetWidgetIndex(IFWL_Widget* pWidget) {
136 CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget);
137 if (!pItem)
138 return -1;
139 return TravelWidgetMgr(pItem->pParent, NULL, pItem);
140 }
SetWidgetIndex(IFWL_Widget * pWidget,int32_t nIndex)141 FX_BOOL CFWL_WidgetMgr::SetWidgetIndex(IFWL_Widget* pWidget, int32_t nIndex) {
142 CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget);
143 if (!pItem)
144 return FALSE;
145 if (!pItem->pParent)
146 return FALSE;
147 CFWL_WidgetMgrItem* pChild = pItem->pParent->pChild;
148 int32_t i = 0;
149 while (pChild) {
150 if (pChild == pItem) {
151 if (i == nIndex) {
152 return TRUE;
153 }
154 if (pChild->pPrevious) {
155 pChild->pPrevious->pNext = pChild->pNext;
156 }
157 if (pChild->pNext) {
158 pChild->pNext->pPrevious = pChild->pPrevious;
159 }
160 if (pItem->pParent->pChild == pItem) {
161 pItem->pParent->pChild = pItem->pNext;
162 }
163 pItem->pNext = NULL;
164 pItem->pPrevious = NULL;
165 break;
166 }
167 if (!pChild->pNext) {
168 break;
169 }
170 pChild = pChild->pNext;
171 ++i;
172 }
173 pChild = pItem->pParent->pChild;
174 if (pChild) {
175 if (nIndex < 0) {
176 while (pChild->pNext) {
177 pChild = pChild->pNext;
178 }
179 pChild->pNext = pItem;
180 pItem->pPrevious = pChild;
181 pItem->pNext = NULL;
182 return TRUE;
183 }
184 i = 0;
185 while (i < nIndex && pChild->pNext) {
186 pChild = pChild->pNext;
187 ++i;
188 }
189 if (!pChild->pNext) {
190 pChild->pNext = pItem;
191 pItem->pPrevious = pChild;
192 pItem->pNext = NULL;
193 return TRUE;
194 }
195 if (pChild->pPrevious) {
196 pItem->pPrevious = pChild->pPrevious;
197 pChild->pPrevious->pNext = pItem;
198 }
199 pChild->pPrevious = pItem;
200 pItem->pNext = pChild;
201 if (pItem->pParent->pChild == pChild) {
202 pItem->pParent->pChild = pItem;
203 }
204 } else {
205 pItem->pParent->pChild = pItem;
206 pItem->pPrevious = NULL;
207 pItem->pNext = NULL;
208 }
209 return TRUE;
210 }
RepaintWidget(IFWL_Widget * pWidget,const CFX_RectF * pRect)211 FWL_ERR CFWL_WidgetMgr::RepaintWidget(IFWL_Widget* pWidget,
212 const CFX_RectF* pRect) {
213 if (!m_pAdapter)
214 return FWL_ERR_Indefinite;
215 IFWL_Widget* pNative = pWidget;
216 CFX_RectF rect(*pRect);
217 if (IsFormDisabled()) {
218 IFWL_Widget* pOuter = pWidget->GetOuter();
219 while (pOuter) {
220 CFX_RectF rtTemp;
221 pNative->GetWidgetRect(rtTemp);
222 rect.left += rtTemp.left;
223 rect.top += rtTemp.top;
224 pNative = pOuter;
225 pOuter = pOuter->GetOuter();
226 }
227 } else if (!IsAbleNative(pWidget)) {
228 pNative = GetWidget(pWidget, FWL_WGTRELATION_SystemForm);
229 if (!pNative)
230 return FWL_ERR_Indefinite;
231 pWidget->TransformTo(pNative, rect.left, rect.top);
232 }
233 AddRedrawCounts(pNative);
234 return m_pAdapter->RepaintWidget(pNative, &rect);
235 }
AddWidget(IFWL_Widget * pWidget)236 void CFWL_WidgetMgr::AddWidget(IFWL_Widget* pWidget) {
237 CFWL_WidgetMgrItem* pParentItem = GetWidgetMgrItem(NULL);
238 CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget);
239 if (!pItem) {
240 pItem = new CFWL_WidgetMgrItem;
241 pItem->pWidget = pWidget;
242 m_mapWidgetItem.SetAt(pWidget, pItem);
243 }
244 if (pItem->pParent && pItem->pParent != pParentItem) {
245 if (pItem->pPrevious) {
246 pItem->pPrevious->pNext = pItem->pNext;
247 }
248 if (pItem->pNext) {
249 pItem->pNext->pPrevious = pItem->pPrevious;
250 }
251 if (pItem->pParent->pChild == pItem) {
252 pItem->pParent->pChild = pItem->pNext;
253 }
254 }
255 pItem->pParent = pParentItem;
256 SetWidgetIndex(pWidget, -1);
257 }
InsertWidget(IFWL_Widget * pParent,IFWL_Widget * pChild,int32_t nIndex)258 void CFWL_WidgetMgr::InsertWidget(IFWL_Widget* pParent,
259 IFWL_Widget* pChild,
260 int32_t nIndex) {
261 CFWL_WidgetMgrItem* pParentItem = GetWidgetMgrItem(pParent);
262 if (!pParentItem) {
263 pParentItem = new CFWL_WidgetMgrItem;
264 pParentItem->pWidget = pParent;
265 m_mapWidgetItem.SetAt(pParent, pParentItem);
266 CFWL_WidgetMgrItem* pRoot = GetWidgetMgrItem(NULL);
267 pParentItem->pParent = pRoot;
268 SetWidgetIndex(pParent, -1);
269 }
270 CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pChild);
271 if (!pItem) {
272 pItem = new CFWL_WidgetMgrItem;
273 pItem->pWidget = pChild;
274 m_mapWidgetItem.SetAt(pChild, pItem);
275 }
276 if (pItem->pParent && pItem->pParent != pParentItem) {
277 if (pItem->pPrevious) {
278 pItem->pPrevious->pNext = pItem->pNext;
279 }
280 if (pItem->pNext) {
281 pItem->pNext->pPrevious = pItem->pPrevious;
282 }
283 if (pItem->pParent->pChild == pItem) {
284 pItem->pParent->pChild = pItem->pNext;
285 }
286 }
287 pItem->pParent = pParentItem;
288 SetWidgetIndex(pChild, nIndex);
289 }
RemoveWidget(IFWL_Widget * pWidget)290 void CFWL_WidgetMgr::RemoveWidget(IFWL_Widget* pWidget) {
291 CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget);
292 if (!pItem) {
293 return;
294 }
295 if (pItem->pPrevious) {
296 pItem->pPrevious->pNext = pItem->pNext;
297 }
298 if (pItem->pNext) {
299 pItem->pNext->pPrevious = pItem->pPrevious;
300 }
301 if (pItem->pParent && pItem->pParent->pChild == pItem) {
302 pItem->pParent->pChild = pItem->pNext;
303 }
304 CFWL_WidgetMgrItem* pChild = pItem->pChild;
305 while (pChild) {
306 CFWL_WidgetMgrItem* pNext = pChild->pNext;
307 RemoveWidget(pChild->pWidget);
308 pChild = pNext;
309 }
310 m_mapWidgetItem.RemoveKey(pWidget);
311 delete pItem;
312 }
SetOwner(IFWL_Widget * pOwner,IFWL_Widget * pOwned)313 void CFWL_WidgetMgr::SetOwner(IFWL_Widget* pOwner, IFWL_Widget* pOwned) {
314 CFWL_WidgetMgrItem* pParentItem = GetWidgetMgrItem(pOwner);
315 if (!pParentItem) {
316 pParentItem = new CFWL_WidgetMgrItem;
317 pParentItem->pWidget = pOwner;
318 m_mapWidgetItem.SetAt(pOwner, pParentItem);
319 CFWL_WidgetMgrItem* pRoot = GetWidgetMgrItem(NULL);
320 pParentItem->pParent = pRoot;
321 SetWidgetIndex(pOwner, -1);
322 }
323 CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pOwned);
324 if (!pItem) {
325 pItem = new CFWL_WidgetMgrItem;
326 pItem->pWidget = pOwned;
327 m_mapWidgetItem.SetAt(pOwned, pItem);
328 }
329 pItem->pOwner = pParentItem;
330 }
SetParent(IFWL_Widget * pParent,IFWL_Widget * pChild)331 void CFWL_WidgetMgr::SetParent(IFWL_Widget* pParent, IFWL_Widget* pChild) {
332 CFWL_WidgetMgrItem* pParentItem = GetWidgetMgrItem(pParent);
333 CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pChild);
334 if (!pItem)
335 return;
336 if (pItem->pParent && pItem->pParent != pParentItem) {
337 if (pItem->pPrevious) {
338 pItem->pPrevious->pNext = pItem->pNext;
339 }
340 if (pItem->pNext) {
341 pItem->pNext->pPrevious = pItem->pPrevious;
342 }
343 if (pItem->pParent->pChild == pItem) {
344 pItem->pParent->pChild = pItem->pNext;
345 }
346 pItem->pNext = NULL;
347 pItem->pPrevious = NULL;
348 }
349 pItem->pParent = pParentItem;
350 SetWidgetIndex(pChild, -1);
351 if (!m_pAdapter)
352 return;
353 m_pAdapter->SetParentWidget(pChild, pParent);
354 }
IsChild(IFWL_Widget * pChild,IFWL_Widget * pParent)355 FX_BOOL CFWL_WidgetMgr::IsChild(IFWL_Widget* pChild, IFWL_Widget* pParent) {
356 IFWL_Widget* pTemp = pChild;
357 do {
358 if (pTemp == pParent) {
359 return TRUE;
360 }
361 pTemp = GetWidget(pTemp, FWL_WGTRELATION_Parent);
362 } while (pTemp);
363 return FALSE;
364 }
CreateWidget_Native(IFWL_Widget * pWidget)365 FWL_ERR CFWL_WidgetMgr::CreateWidget_Native(IFWL_Widget* pWidget) {
366 if (!IsAbleNative(pWidget)) {
367 return FWL_ERR_Succeeded;
368 }
369 return m_pAdapter->CreateWidget(pWidget, pWidget->GetOwner());
370 }
DestroyWidget_Native(IFWL_Widget * pWidget)371 FWL_ERR CFWL_WidgetMgr::DestroyWidget_Native(IFWL_Widget* pWidget) {
372 if (!IsAbleNative(pWidget)) {
373 return FWL_ERR_Succeeded;
374 }
375 return m_pAdapter->DestroyWidget(pWidget);
376 }
GetWidgetRect_Native(IFWL_Widget * pWidget,CFX_RectF & rect)377 FWL_ERR CFWL_WidgetMgr::GetWidgetRect_Native(IFWL_Widget* pWidget,
378 CFX_RectF& rect) {
379 if (!IsAbleNative(pWidget)) {
380 return FWL_ERR_Succeeded;
381 }
382 return m_pAdapter->GetWidgetRect(pWidget, rect);
383 }
SetWidgetRect_Native(IFWL_Widget * pWidget,const CFX_RectF & rect)384 FWL_ERR CFWL_WidgetMgr::SetWidgetRect_Native(IFWL_Widget* pWidget,
385 const CFX_RectF& rect) {
386 if (FWL_UseOffscreen(pWidget)) {
387 CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget);
388 pItem->iRedrawCounter++;
389 if (pItem->pOffscreen) {
390 CFX_RenderDevice* pDevice = pItem->pOffscreen->GetRenderDevice();
391 if (pDevice && pDevice->GetBitmap()) {
392 CFX_DIBitmap* pBitmap = pDevice->GetBitmap();
393 if (pBitmap->GetWidth() - rect.width > 1 ||
394 pBitmap->GetHeight() - rect.height > 1) {
395 delete pItem->pOffscreen;
396 pItem->pOffscreen = NULL;
397 }
398 }
399 }
400 #if (_FX_OS_ == _FX_WIN32_DESKTOP_) || (_FX_OS_ == _FX_WIN64_)
401 pItem->bOutsideChanged = !m_rtScreen.Contains(rect);
402 #endif
403 }
404 return m_pAdapter->SetWidgetRect(pWidget, rect);
405 }
SetWidgetPosition_Native(IFWL_Widget * pWidget,FX_FLOAT fx,FX_FLOAT fy)406 FWL_ERR CFWL_WidgetMgr::SetWidgetPosition_Native(IFWL_Widget* pWidget,
407 FX_FLOAT fx,
408 FX_FLOAT fy) {
409 return m_pAdapter->SetWidgetPosition(pWidget, fx, fy);
410 }
SetWidgetIcon_Native(IFWL_Widget * pWidget,const CFX_DIBitmap * pIcon,FX_BOOL bBig)411 FWL_ERR CFWL_WidgetMgr::SetWidgetIcon_Native(IFWL_Widget* pWidget,
412 const CFX_DIBitmap* pIcon,
413 FX_BOOL bBig) {
414 return m_pAdapter->SetWidgetIcon(pWidget, pIcon, bBig);
415 }
SetWidgetCaption_Native(IFWL_Widget * pWidget,const CFX_WideStringC & wsCaption)416 FWL_ERR CFWL_WidgetMgr::SetWidgetCaption_Native(
417 IFWL_Widget* pWidget,
418 const CFX_WideStringC& wsCaption) {
419 return m_pAdapter->SetWidgetCaption(pWidget, wsCaption);
420 }
SetBorderRegion_Native(IFWL_Widget * pWidget,CFX_Path * pPath)421 FWL_ERR CFWL_WidgetMgr::SetBorderRegion_Native(IFWL_Widget* pWidget,
422 CFX_Path* pPath) {
423 return m_pAdapter->SetBorderRegion(pWidget, pPath);
424 }
ShowWidget_Native(IFWL_Widget * pWidget)425 FWL_ERR CFWL_WidgetMgr::ShowWidget_Native(IFWL_Widget* pWidget) {
426 return m_pAdapter->ShowWidget(pWidget);
427 }
HideWidget_Native(IFWL_Widget * pWidget)428 FWL_ERR CFWL_WidgetMgr::HideWidget_Native(IFWL_Widget* pWidget) {
429 return m_pAdapter->HideWidget(pWidget);
430 }
SetNormal_Native(IFWL_Widget * pWidget)431 FWL_ERR CFWL_WidgetMgr::SetNormal_Native(IFWL_Widget* pWidget) {
432 return m_pAdapter->SetNormal(pWidget);
433 }
SetMaximize_Native(IFWL_Widget * pWidget)434 FWL_ERR CFWL_WidgetMgr::SetMaximize_Native(IFWL_Widget* pWidget) {
435 return m_pAdapter->SetMaximize(pWidget);
436 }
SetMinimize_Native(IFWL_Widget * pWidget)437 FWL_ERR CFWL_WidgetMgr::SetMinimize_Native(IFWL_Widget* pWidget) {
438 return m_pAdapter->SetMinimize(pWidget);
439 }
CheckMessage_Native()440 FX_BOOL CFWL_WidgetMgr::CheckMessage_Native() {
441 return m_pAdapter->CheckMessage();
442 }
DispatchMessage_Native()443 FWL_ERR CFWL_WidgetMgr::DispatchMessage_Native() {
444 return m_pAdapter->DispatchMessage();
445 }
IsIdleMessage_Native()446 FX_BOOL CFWL_WidgetMgr::IsIdleMessage_Native() {
447 return m_pAdapter->IsIdleMessage();
448 }
Exit_Native(int32_t iExitCode)449 FWL_ERR CFWL_WidgetMgr::Exit_Native(int32_t iExitCode) {
450 return m_pAdapter->Exit(iExitCode);
451 }
CreateWidgetWithNativeId_Native(IFWL_Widget * pWidget,void * vp)452 FWL_ERR CFWL_WidgetMgr::CreateWidgetWithNativeId_Native(IFWL_Widget* pWidget,
453 void* vp) {
454 return m_pAdapter->CreateWidgetWithNativeId(pWidget, vp);
455 }
GetWidgetAtPoint(IFWL_Widget * parent,FX_FLOAT x,FX_FLOAT y)456 IFWL_Widget* CFWL_WidgetMgr::GetWidgetAtPoint(IFWL_Widget* parent,
457 FX_FLOAT x,
458 FX_FLOAT y) {
459 if (!parent)
460 return NULL;
461 FX_FLOAT x1;
462 FX_FLOAT y1;
463 IFWL_Widget* child = GetWidget(parent, FWL_WGTRELATION_LastChild);
464 while (child) {
465 if ((child->GetStates() & FWL_WGTSTATE_Invisible) == 0) {
466 x1 = x;
467 y1 = y;
468 CFX_Matrix matrixOnParent;
469 child->GetMatrix(matrixOnParent);
470 CFX_Matrix m;
471 m.SetIdentity();
472 m.SetReverse(matrixOnParent);
473 m.TransformPoint(x1, y1);
474 CFX_RectF bounds;
475 child->GetWidgetRect(bounds);
476 if (bounds.Contains(x1, y1)) {
477 x1 -= bounds.left;
478 y1 -= bounds.top;
479 return GetWidgetAtPoint(child, x1, y1);
480 }
481 }
482 child = GetWidget(child, FWL_WGTRELATION_PriorSibling);
483 }
484 return parent;
485 }
NotifySizeChanged(IFWL_Widget * pForm,FX_FLOAT fx,FX_FLOAT fy)486 void CFWL_WidgetMgr::NotifySizeChanged(IFWL_Widget* pForm,
487 FX_FLOAT fx,
488 FX_FLOAT fy) {
489 if (!FWL_UseOffscreen(pForm)) {
490 return;
491 }
492 CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pForm);
493 if (pItem->pOffscreen) {
494 delete pItem->pOffscreen;
495 pItem->pOffscreen = NULL;
496 }
497 }
nextTab(IFWL_Widget * parent,IFWL_Widget * focus,FX_BOOL & bFind)498 IFWL_Widget* CFWL_WidgetMgr::nextTab(IFWL_Widget* parent,
499 IFWL_Widget* focus,
500 FX_BOOL& bFind) {
501 IFWL_Widget* child =
502 FWL_GetWidgetMgr()->GetWidget(parent, FWL_WGTRELATION_FirstChild);
503 while (child) {
504 if (focus == child) {
505 bFind = TRUE;
506 }
507 if ((child->GetStyles() & FWL_WGTSTYLE_TabStop) &&
508 (!focus || (focus != child && bFind))) {
509 return child;
510 }
511 IFWL_Widget* bRet = nextTab(child, focus, bFind);
512 if (bRet) {
513 return bRet;
514 }
515 child = FWL_GetWidgetMgr()->GetWidget(child, FWL_WGTRELATION_NextSibling);
516 }
517 return NULL;
518 }
CountRadioButtonGroup(IFWL_Widget * pFirst)519 int32_t CFWL_WidgetMgr::CountRadioButtonGroup(IFWL_Widget* pFirst) {
520 int32_t iRet = 0;
521 IFWL_Widget* pChild = pFirst;
522 while (pChild) {
523 if ((pChild->GetStyles() & FWL_WGTSTYLE_Group) &&
524 pChild->GetClassID() == 3811304691) {
525 iRet++;
526 }
527 pChild = GetWidget(pChild, FWL_WGTRELATION_NextSibling);
528 }
529 return iRet;
530 }
GetSiblingRadioButton(IFWL_Widget * pWidget,FX_BOOL bNext)531 IFWL_Widget* CFWL_WidgetMgr::GetSiblingRadioButton(IFWL_Widget* pWidget,
532 FX_BOOL bNext) {
533 while ((pWidget = GetWidget(pWidget, bNext ? FWL_WGTRELATION_NextSibling
534 : FWL_WGTRELATION_PriorSibling)) !=
535 NULL) {
536 if (pWidget->GetClassID() == 3811304691) {
537 return pWidget;
538 }
539 }
540 return NULL;
541 }
GetRadioButtonGroupHeader(IFWL_Widget * pRadioButton)542 IFWL_Widget* CFWL_WidgetMgr::GetRadioButtonGroupHeader(
543 IFWL_Widget* pRadioButton) {
544 if (pRadioButton->GetStyles() & FWL_WGTSTYLE_Group) {
545 return pRadioButton;
546 }
547 IFWL_Widget* pNext = pRadioButton;
548 while ((pNext = GetSiblingRadioButton(pNext, FALSE)) != NULL) {
549 if (pNext->GetStyles() & FWL_WGTSTYLE_Group) {
550 return pNext;
551 }
552 }
553 pNext = GetWidget(pRadioButton, FWL_WGTRELATION_LastSibling);
554 if ((pNext->GetStyles() & FWL_WGTSTYLE_Group) &&
555 pNext->GetClassID() == 3811304691) {
556 return pNext;
557 }
558 while ((pNext = GetSiblingRadioButton(pNext, FALSE)) && pNext &&
559 pNext != pRadioButton) {
560 if (pNext->GetStyles() & FWL_WGTSTYLE_Group) {
561 return pNext;
562 }
563 }
564 pNext = GetWidget(pRadioButton, FWL_WGTRELATION_FirstSibling);
565 if (pNext && (pNext->GetStyles() == FWL_WGTSTYLE_Group) &&
566 pNext->GetClassID() == 3811304691) {
567 return pNext;
568 }
569 return GetSiblingRadioButton(pNext, TRUE);
570 }
GetSameGroupRadioButton(IFWL_Widget * pRadioButton,CFX_PtrArray & group)571 void CFWL_WidgetMgr::GetSameGroupRadioButton(IFWL_Widget* pRadioButton,
572 CFX_PtrArray& group) {
573 IFWL_Widget* pFirst = GetWidget(pRadioButton, FWL_WGTRELATION_FirstSibling);
574 if (!pFirst) {
575 pFirst = pRadioButton;
576 }
577 int32_t iGroup = CountRadioButtonGroup(pFirst);
578 if (iGroup < 2) {
579 if (pFirst->GetClassID() == 3811304691) {
580 group.Add(pFirst);
581 }
582 IFWL_Widget* pNext = pFirst;
583 while ((pNext = GetSiblingRadioButton(pNext, TRUE)) != NULL) {
584 group.Add(pNext);
585 }
586 return;
587 }
588 IFWL_Widget* pNext = GetRadioButtonGroupHeader(pRadioButton);
589 do {
590 group.Add(pNext);
591 pNext = GetSiblingRadioButton(pNext, TRUE);
592 if (!pNext) {
593 if (pFirst->GetClassID() == 3811304691) {
594 pNext = pFirst;
595 } else {
596 pNext = GetSiblingRadioButton(pFirst, TRUE);
597 }
598 }
599 } while (pNext && ((pNext->GetStyles() & FWL_WGTSTYLE_Group) == 0));
600 }
GetDefaultButton(IFWL_Widget * pParent)601 IFWL_Widget* CFWL_WidgetMgr::GetDefaultButton(IFWL_Widget* pParent) {
602 if ((pParent->GetClassID() == 3521614244) &&
603 (pParent->GetStates() & (1 << (FWL_WGTSTATE_MAX + 2)))) {
604 return pParent;
605 }
606 IFWL_Widget* child =
607 FWL_GetWidgetMgr()->GetWidget(pParent, FWL_WGTRELATION_FirstChild);
608 while (child) {
609 if ((child->GetClassID() == 3521614244) &&
610 (child->GetStates() & (1 << (FWL_WGTSTATE_MAX + 2)))) {
611 return child;
612 }
613 IFWL_Widget* find = GetDefaultButton(child);
614 if (find) {
615 return find;
616 }
617 child = FWL_GetWidgetMgr()->GetWidget(child, FWL_WGTRELATION_NextSibling);
618 }
619 return NULL;
620 }
AddRedrawCounts(IFWL_Widget * pWidget)621 void CFWL_WidgetMgr::AddRedrawCounts(IFWL_Widget* pWidget) {
622 CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget);
623 (pItem->iRedrawCounter)++;
624 }
ResetRedrawCounts(IFWL_Widget * pWidget)625 void CFWL_WidgetMgr::ResetRedrawCounts(IFWL_Widget* pWidget) {
626 CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget);
627 pItem->iRedrawCounter = 0;
628 }
GetWidgetMgrItem(IFWL_Widget * pWidget)629 CFWL_WidgetMgrItem* CFWL_WidgetMgr::GetWidgetMgrItem(IFWL_Widget* pWidget) {
630 return static_cast<CFWL_WidgetMgrItem*>(m_mapWidgetItem.GetValueAt(pWidget));
631 }
TravelWidgetMgr(CFWL_WidgetMgrItem * pParent,int32_t * pIndex,CFWL_WidgetMgrItem * pItem,IFWL_Widget ** pWidget)632 int32_t CFWL_WidgetMgr::TravelWidgetMgr(CFWL_WidgetMgrItem* pParent,
633 int32_t* pIndex,
634 CFWL_WidgetMgrItem* pItem,
635 IFWL_Widget** pWidget) {
636 if (!pParent) {
637 return 0;
638 }
639 int32_t iCount = 0;
640 CFWL_WidgetMgrItem* pChild = pParent->pChild;
641 while (pChild) {
642 iCount++;
643 if (pIndex) {
644 if (*pIndex == 0) {
645 *pWidget = pChild->pWidget;
646 return iCount;
647 }
648 pIndex--;
649 }
650 if (pItem && pItem == pChild) {
651 return iCount - 1;
652 }
653 pChild = pChild->pNext;
654 }
655 if (pIndex) {
656 return 0;
657 } else if (pItem) {
658 return -1;
659 }
660 return iCount - 1;
661 }
IsAbleNative(IFWL_Widget * pWidget)662 FX_BOOL CFWL_WidgetMgr::IsAbleNative(IFWL_Widget* pWidget) {
663 if (!pWidget)
664 return FALSE;
665 if (!pWidget->IsInstance(FX_WSTRC(FWL_CLASS_Form))) {
666 return FALSE;
667 }
668 FX_DWORD dwStyles = pWidget->GetStyles();
669 return ((dwStyles & FWL_WGTSTYLE_WindowTypeMask) ==
670 FWL_WGTSTYLE_OverLapper) ||
671 (dwStyles & FWL_WGTSTYLE_Popup);
672 }
IsThreadEnabled()673 FX_BOOL CFWL_WidgetMgr::IsThreadEnabled() {
674 return !(m_dwCapability & FWL_WGTMGR_DisableThread);
675 }
IsFormDisabled()676 FX_BOOL CFWL_WidgetMgr::IsFormDisabled() {
677 return m_dwCapability & FWL_WGTMGR_DisableForm;
678 }
GetAdapterPopupPos(IFWL_Widget * pWidget,FX_FLOAT fMinHeight,FX_FLOAT fMaxHeight,const CFX_RectF & rtAnchor,CFX_RectF & rtPopup)679 FX_BOOL CFWL_WidgetMgr::GetAdapterPopupPos(IFWL_Widget* pWidget,
680 FX_FLOAT fMinHeight,
681 FX_FLOAT fMaxHeight,
682 const CFX_RectF& rtAnchor,
683 CFX_RectF& rtPopup) {
684 IFWL_AdapterWidgetMgr* pSDApapter = GetAdapterWidgetMgr();
685 return pSDApapter->GetPopupPos(pWidget, fMinHeight, fMaxHeight, rtAnchor,
686 rtPopup);
687 }
CFWL_WidgetMgrDelegate(CFWL_WidgetMgr * pWidgetMgr)688 CFWL_WidgetMgrDelegate::CFWL_WidgetMgrDelegate(CFWL_WidgetMgr* pWidgetMgr)
689 : m_pWidgetMgr(pWidgetMgr) {}
OnSetCapability(FX_DWORD dwCapability)690 FWL_ERR CFWL_WidgetMgrDelegate::OnSetCapability(FX_DWORD dwCapability) {
691 m_pWidgetMgr->m_dwCapability = dwCapability;
692 return FWL_ERR_Succeeded;
693 }
OnProcessMessageToForm(CFWL_Message * pMessage)694 int32_t CFWL_WidgetMgrDelegate::OnProcessMessageToForm(CFWL_Message* pMessage) {
695 if (!pMessage)
696 return 0;
697 if (!pMessage->m_pDstTarget)
698 return 0;
699 IFWL_Widget* pDstWidget = pMessage->m_pDstTarget;
700 IFWL_NoteThread* pNoteThread = pDstWidget->GetOwnerThread();
701 if (!pNoteThread)
702 return 0;
703 CFWL_NoteDriver* pNoteDriver =
704 static_cast<CFWL_NoteDriver*>(pNoteThread->GetNoteDriver());
705 if (!pNoteDriver)
706 return 0;
707 if (m_pWidgetMgr->IsThreadEnabled()) {
708 pMessage = static_cast<CFWL_Message*>(pMessage->Clone());
709 }
710 if (m_pWidgetMgr->IsFormDisabled()) {
711 pNoteDriver->ProcessMessage(pMessage);
712 } else {
713 pNoteDriver->QueueMessage(pMessage);
714 }
715 #if (_FX_OS_ == _FX_MACOSX_)
716 CFWL_NoteLoop* pTopLoop = pNoteDriver->GetTopLoop();
717 if (pTopLoop) {
718 pNoteDriver->UnqueueMessage(pTopLoop);
719 }
720 #endif
721 if (m_pWidgetMgr->IsThreadEnabled()) {
722 pMessage->Release();
723 }
724 return FWL_ERR_Succeeded;
725 }
OnDrawWidget(IFWL_Widget * pWidget,CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)726 FWL_ERR CFWL_WidgetMgrDelegate::OnDrawWidget(IFWL_Widget* pWidget,
727 CFX_Graphics* pGraphics,
728 const CFX_Matrix* pMatrix) {
729 if (!pWidget)
730 return FWL_ERR_Indefinite;
731 if (!pGraphics)
732 return FWL_ERR_Indefinite;
733 CFX_Graphics* pTemp = DrawWidgetBefore(pWidget, pGraphics, pMatrix);
734 CFX_RectF clipCopy;
735 pWidget->GetWidgetRect(clipCopy);
736 clipCopy.left = clipCopy.top = 0;
737 if (bUseOffscreenDirect(pWidget)) {
738 DrawWidgetAfter(pWidget, pGraphics, clipCopy, pMatrix);
739 return FWL_ERR_Succeeded;
740 }
741 CFX_RectF clipBounds;
742 #if (_FX_OS_ == _FX_WIN32_DESKTOP_) || (_FX_OS_ == _FX_WIN64_) || \
743 (_FX_OS_ == _FX_LINUX_DESKTOP_) || (_FX_OS_ == _FX_ANDROID_)
744 IFWL_WidgetDelegate* pDelegate = pWidget->SetDelegate(NULL);
745 pDelegate->OnDrawWidget(pTemp, pMatrix);
746 pGraphics->GetClipRect(clipBounds);
747 clipCopy = clipBounds;
748 #elif(_FX_OS_ == _FX_MACOSX_)
749 if (m_pWidgetMgr->IsFormDisabled()) {
750 IFWL_WidgetDelegate* pDelegate = pWidget->SetDelegate(NULL);
751 pDelegate->OnDrawWidget(pTemp, pMatrix);
752 pGraphics->GetClipRect(clipBounds);
753 clipCopy = clipBounds;
754 } else {
755 clipBounds.Set(pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d);
756 const_cast<CFX_Matrix*>(pMatrix)->SetIdentity(); // FIXME: const cast.
757 #ifdef FWL_UseMacSystemBorder
758 #else
759 #endif
760 {
761 IFWL_WidgetDelegate* pDelegate = pWidget->SetDelegate(NULL);
762 pDelegate->OnDrawWidget(pTemp, pMatrix);
763 }
764 }
765 #endif
766 if (!m_pWidgetMgr->IsFormDisabled()) {
767 CFX_RectF rtClient;
768 pWidget->GetClientRect(rtClient);
769 clipBounds.Intersect(rtClient);
770 }
771 if (!clipBounds.IsEmpty()) {
772 DrawChild(pWidget, clipBounds, pTemp, pMatrix);
773 }
774 DrawWidgetAfter(pWidget, pGraphics, clipCopy, pMatrix);
775 m_pWidgetMgr->ResetRedrawCounts(pWidget);
776 return FWL_ERR_Succeeded;
777 }
DrawChild(IFWL_Widget * parent,const CFX_RectF & rtClip,CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)778 void CFWL_WidgetMgrDelegate::DrawChild(IFWL_Widget* parent,
779 const CFX_RectF& rtClip,
780 CFX_Graphics* pGraphics,
781 const CFX_Matrix* pMatrix) {
782 if (!parent)
783 return;
784 FX_BOOL bFormDisable = m_pWidgetMgr->IsFormDisabled();
785 IFWL_Widget* pNextChild =
786 m_pWidgetMgr->GetWidget(parent, FWL_WGTRELATION_FirstChild);
787 while (pNextChild) {
788 IFWL_Widget* child = pNextChild;
789 pNextChild = m_pWidgetMgr->GetWidget(child, FWL_WGTRELATION_NextSibling);
790 if (child->GetStates() & FWL_WGTSTATE_Invisible) {
791 continue;
792 }
793 CFX_RectF rtWidget;
794 child->GetWidgetRect(rtWidget);
795 if (rtWidget.IsEmpty()) {
796 continue;
797 }
798 CFX_Matrix widgetMatrix;
799 CFX_RectF clipBounds(rtWidget);
800 if (!bFormDisable) {
801 child->GetMatrix(widgetMatrix, TRUE);
802 }
803 if (pMatrix) {
804 widgetMatrix.Concat(*pMatrix);
805 }
806 if (!bFormDisable) {
807 widgetMatrix.TransformPoint(clipBounds.left, clipBounds.top);
808 clipBounds.Intersect(rtClip);
809 if (clipBounds.IsEmpty()) {
810 continue;
811 }
812 pGraphics->SaveGraphState();
813 pGraphics->SetClipRect(clipBounds);
814 }
815 widgetMatrix.Translate(rtWidget.left, rtWidget.top, TRUE);
816 IFWL_WidgetDelegate* pDelegate = child->SetDelegate(NULL);
817 if (pDelegate) {
818 if (m_pWidgetMgr->IsFormDisabled() ||
819 IsNeedRepaint(child, &widgetMatrix, rtClip)) {
820 pDelegate->OnDrawWidget(pGraphics, &widgetMatrix);
821 }
822 }
823 if (!bFormDisable) {
824 pGraphics->RestoreGraphState();
825 }
826 DrawChild(child, clipBounds, pGraphics,
827 bFormDisable ? &widgetMatrix : pMatrix);
828 child = m_pWidgetMgr->GetWidget(child, FWL_WGTRELATION_NextSibling);
829 }
830 }
DrawWidgetBefore(IFWL_Widget * pWidget,CFX_Graphics * pGraphics,const CFX_Matrix * pMatrix)831 CFX_Graphics* CFWL_WidgetMgrDelegate::DrawWidgetBefore(
832 IFWL_Widget* pWidget,
833 CFX_Graphics* pGraphics,
834 const CFX_Matrix* pMatrix) {
835 if (!FWL_UseOffscreen(pWidget)) {
836 return pGraphics;
837 }
838 CFWL_WidgetMgrItem* pItem = m_pWidgetMgr->GetWidgetMgrItem(pWidget);
839 if (!pItem->pOffscreen) {
840 pItem->pOffscreen = new CFX_Graphics;
841 CFX_RectF rect;
842 pWidget->GetWidgetRect(rect);
843 pItem->pOffscreen->Create((int32_t)rect.width, (int32_t)rect.height,
844 FXDIB_Argb);
845 }
846 CFX_RectF rect;
847 pGraphics->GetClipRect(rect);
848 pItem->pOffscreen->SetClipRect(rect);
849 return pItem->pOffscreen;
850 }
DrawWidgetAfter(IFWL_Widget * pWidget,CFX_Graphics * pGraphics,CFX_RectF & rtClip,const CFX_Matrix * pMatrix)851 void CFWL_WidgetMgrDelegate::DrawWidgetAfter(IFWL_Widget* pWidget,
852 CFX_Graphics* pGraphics,
853 CFX_RectF& rtClip,
854 const CFX_Matrix* pMatrix) {
855 if (FWL_UseOffscreen(pWidget)) {
856 CFWL_WidgetMgrItem* pItem = m_pWidgetMgr->GetWidgetMgrItem(pWidget);
857 pGraphics->Transfer(pItem->pOffscreen, rtClip.left, rtClip.top, rtClip,
858 pMatrix);
859 #ifdef _WIN32
860 pItem->pOffscreen->ClearClip();
861 #endif
862 }
863 CFWL_WidgetMgrItem* pItem = m_pWidgetMgr->GetWidgetMgrItem(pWidget);
864 pItem->iRedrawCounter = 0;
865 }
866 #define FWL_NEEDREPAINTHIT_Point 12
867 #define FWL_NEEDREPAINTHIT_Piece 3
868 typedef struct _FWL_NeedRepaintHitData {
869 CFX_PointF hitPoint;
870 FX_BOOL bNotNeedRepaint;
871 FX_BOOL bNotContainByDirty;
872 } FWL_NeedRepaintHitData;
IsNeedRepaint(IFWL_Widget * pWidget,CFX_Matrix * pMatrix,const CFX_RectF & rtDirty)873 FX_BOOL CFWL_WidgetMgrDelegate::IsNeedRepaint(IFWL_Widget* pWidget,
874 CFX_Matrix* pMatrix,
875 const CFX_RectF& rtDirty) {
876 CFWL_WidgetMgrItem* pItem = m_pWidgetMgr->GetWidgetMgrItem(pWidget);
877 if (pItem && pItem->iRedrawCounter > 0) {
878 pItem->iRedrawCounter = 0;
879 return TRUE;
880 }
881 CFX_RectF rtWidget;
882 pWidget->GetWidgetRect(rtWidget);
883 rtWidget.left = rtWidget.top = 0;
884 pMatrix->TransformRect(rtWidget);
885 if (!rtWidget.IntersectWith(rtDirty)) {
886 return FALSE;
887 }
888 IFWL_Widget* pChild =
889 FWL_GetWidgetMgr()->GetWidget(pWidget, FWL_WGTRELATION_FirstChild);
890 if (!pChild) {
891 return TRUE;
892 }
893 if (pChild->GetClassID() == 3150298670) {
894 CFX_RectF rtTemp;
895 pChild->GetWidgetRect(rtTemp);
896 if (rtTemp.width >= rtWidget.width && rtTemp.height >= rtWidget.height) {
897 pChild =
898 FWL_GetWidgetMgr()->GetWidget(pChild, FWL_WGTRELATION_FirstChild);
899 if (!pChild) {
900 return TRUE;
901 }
902 }
903 }
904 CFX_RectF rtChilds;
905 rtChilds.Empty();
906 FX_BOOL bChildIntersectWithDirty = FALSE;
907 FX_BOOL bOrginPtIntersectWidthChild = FALSE;
908 FX_BOOL bOrginPtIntersectWidthDirty =
909 rtDirty.Contains(rtWidget.left, rtWidget.top);
910 static FWL_NeedRepaintHitData hitPoint[FWL_NEEDREPAINTHIT_Point];
911 static int32_t iSize = sizeof(FWL_NeedRepaintHitData);
912 FXSYS_memset(hitPoint, 0, iSize);
913 FX_FLOAT fxPiece = rtWidget.width / FWL_NEEDREPAINTHIT_Piece;
914 FX_FLOAT fyPiece = rtWidget.height / FWL_NEEDREPAINTHIT_Piece;
915 hitPoint[2].hitPoint.x = hitPoint[6].hitPoint.x = rtWidget.left;
916 hitPoint[0].hitPoint.x = hitPoint[3].hitPoint.x = hitPoint[7].hitPoint.x =
917 hitPoint[10].hitPoint.x = fxPiece + rtWidget.left;
918 hitPoint[1].hitPoint.x = hitPoint[4].hitPoint.x = hitPoint[8].hitPoint.x =
919 hitPoint[11].hitPoint.x = fxPiece * 2 + rtWidget.left;
920 hitPoint[5].hitPoint.x = hitPoint[9].hitPoint.x =
921 rtWidget.width + rtWidget.left;
922 hitPoint[0].hitPoint.y = hitPoint[1].hitPoint.y = rtWidget.top;
923 hitPoint[2].hitPoint.y = hitPoint[3].hitPoint.y = hitPoint[4].hitPoint.y =
924 hitPoint[5].hitPoint.y = fyPiece + rtWidget.top;
925 hitPoint[6].hitPoint.y = hitPoint[7].hitPoint.y = hitPoint[8].hitPoint.y =
926 hitPoint[9].hitPoint.y = fyPiece * 2 + rtWidget.top;
927 hitPoint[10].hitPoint.y = hitPoint[11].hitPoint.y =
928 rtWidget.height + rtWidget.top;
929 do {
930 CFX_RectF rect;
931 pChild->GetWidgetRect(rect);
932 CFX_RectF r = rect;
933 r.left += rtWidget.left;
934 r.top += rtWidget.top;
935 if (r.IsEmpty()) {
936 continue;
937 }
938 if (r.Contains(rtDirty)) {
939 return FALSE;
940 }
941 if (!bChildIntersectWithDirty && r.IntersectWith(rtDirty)) {
942 bChildIntersectWithDirty = TRUE;
943 }
944 if (bOrginPtIntersectWidthDirty && !bOrginPtIntersectWidthChild) {
945 bOrginPtIntersectWidthChild = rect.Contains(0, 0);
946 }
947 if (rtChilds.IsEmpty()) {
948 rtChilds = rect;
949 } else if (!(pChild->GetStates() & FWL_WGTSTATE_Invisible)) {
950 rtChilds.Union(rect);
951 }
952 for (int32_t i = 0; i < FWL_NEEDREPAINTHIT_Point; i++) {
953 if (hitPoint[i].bNotContainByDirty || hitPoint[i].bNotNeedRepaint) {
954 continue;
955 }
956 if (!rtDirty.Contains(hitPoint[i].hitPoint)) {
957 hitPoint[i].bNotContainByDirty = TRUE;
958 continue;
959 }
960 if (r.Contains(hitPoint[i].hitPoint)) {
961 hitPoint[i].bNotNeedRepaint = TRUE;
962 }
963 }
964 } while ((pChild = FWL_GetWidgetMgr()->GetWidget(
965 pChild, FWL_WGTRELATION_NextSibling)) != NULL);
966 if (!bChildIntersectWithDirty) {
967 return TRUE;
968 }
969 if (bOrginPtIntersectWidthDirty && !bOrginPtIntersectWidthChild) {
970 return TRUE;
971 }
972 if (rtChilds.IsEmpty()) {
973 return TRUE;
974 }
975 int32_t repaintPoint = FWL_NEEDREPAINTHIT_Point;
976 for (int32_t i = 0; i < FWL_NEEDREPAINTHIT_Point; i++) {
977 if (hitPoint[i].bNotNeedRepaint) {
978 repaintPoint--;
979 }
980 }
981 if (repaintPoint > 0) {
982 return TRUE;
983 }
984 pMatrix->TransformRect(rtChilds);
985 if (rtChilds.Contains(rtDirty) || rtChilds.Contains(rtWidget)) {
986 return FALSE;
987 }
988 return TRUE;
989 }
bUseOffscreenDirect(IFWL_Widget * pWidget)990 FX_BOOL CFWL_WidgetMgrDelegate::bUseOffscreenDirect(IFWL_Widget* pWidget) {
991 CFWL_WidgetMgrItem* pItem = m_pWidgetMgr->GetWidgetMgrItem(pWidget);
992 if (!FWL_UseOffscreen(pWidget) || !(pItem->pOffscreen)) {
993 return FALSE;
994 }
995 #if (_FX_OS_ == _FX_WIN32_DESKTOP_) || (_FX_OS_ == _FX_WIN64_)
996 if (pItem->bOutsideChanged) {
997 CFX_RectF r;
998 pWidget->GetWidgetRect(r);
999 CFX_RectF temp(m_pWidgetMgr->m_rtScreen);
1000 temp.Deflate(50, 50);
1001 if (!temp.Contains(r)) {
1002 return FALSE;
1003 }
1004 pItem->bOutsideChanged = FALSE;
1005 }
1006 #endif
1007 return pItem->iRedrawCounter == 0;
1008 }
FWL_WriteBMP(CFX_DIBitmap * pBitmap,const FX_CHAR * filename)1009 static void FWL_WriteBMP(CFX_DIBitmap* pBitmap, const FX_CHAR* filename) {
1010 FILE* file = fopen(filename, "wb");
1011 if (file == NULL) {
1012 return;
1013 }
1014 int size = 14 + 40 + pBitmap->GetPitch() * pBitmap->GetHeight();
1015 unsigned char buffer[40];
1016 buffer[0] = 'B';
1017 buffer[1] = 'M';
1018 buffer[2] = (unsigned char)size;
1019 buffer[3] = (unsigned char)(size >> 8);
1020 buffer[4] = (unsigned char)(size >> 16);
1021 buffer[5] = (unsigned char)(size >> 24);
1022 buffer[6] = buffer[7] = buffer[8] = buffer[9] = 0;
1023 buffer[10] = 54;
1024 buffer[11] = buffer[12] = buffer[13] = 0;
1025 fwrite(buffer, 14, 1, file);
1026 memset(buffer, 0, 40);
1027 buffer[0] = 40;
1028 buffer[4] = (unsigned char)pBitmap->GetWidth();
1029 buffer[5] = (unsigned char)(pBitmap->GetWidth() >> 8);
1030 buffer[6] = (unsigned char)(pBitmap->GetWidth() >> 16);
1031 buffer[7] = (unsigned char)(pBitmap->GetWidth() >> 24);
1032 buffer[8] = (unsigned char)(-pBitmap->GetHeight());
1033 buffer[9] = (unsigned char)((-pBitmap->GetHeight()) >> 8);
1034 buffer[10] = (unsigned char)((-pBitmap->GetHeight()) >> 16);
1035 buffer[11] = (unsigned char)((-pBitmap->GetHeight()) >> 24);
1036 buffer[12] = 1;
1037 buffer[14] = pBitmap->GetBPP();
1038 fwrite(buffer, 40, 1, file);
1039 for (int row = 0; row < pBitmap->GetHeight(); row++) {
1040 uint8_t* scan_line = pBitmap->GetBuffer() + row * pBitmap->GetPitch();
1041 fwrite(scan_line, pBitmap->GetPitch(), 1, file);
1042 }
1043 fclose(file);
1044 }
FWL_WidgetMgrSnapshot(IFWL_Widget * pWidget,const CFX_WideString * saveFile,const CFX_Matrix * pMatrix)1045 FWL_ERR FWL_WidgetMgrSnapshot(IFWL_Widget* pWidget,
1046 const CFX_WideString* saveFile,
1047 const CFX_Matrix* pMatrix) {
1048 CFX_RectF r;
1049 pWidget->GetWidgetRect(r);
1050 CFX_Graphics gs;
1051 gs.Create((int32_t)r.width, (int32_t)r.height, FXDIB_Argb);
1052 CFWL_WidgetMgr* widgetMgr = static_cast<CFWL_WidgetMgr*>(FWL_GetWidgetMgr());
1053 CFWL_WidgetMgrDelegate* delegate = widgetMgr->GetDelegate();
1054 delegate->OnDrawWidget(pWidget, &gs, pMatrix);
1055 CFX_DIBitmap* dib = gs.GetRenderDevice()->GetBitmap();
1056 FWL_WriteBMP(dib, saveFile->UTF8Encode());
1057 return FWL_ERR_Succeeded;
1058 }
FWL_WidgetIsChild(IFWL_Widget * parent,IFWL_Widget * find)1059 FX_BOOL FWL_WidgetIsChild(IFWL_Widget* parent, IFWL_Widget* find) {
1060 if (!find) {
1061 return FALSE;
1062 }
1063 IFWL_Widget* child =
1064 FWL_GetWidgetMgr()->GetWidget(parent, FWL_WGTRELATION_FirstChild);
1065 while (child) {
1066 if (child == find) {
1067 return TRUE;
1068 }
1069 if (FWL_WidgetIsChild(child, find)) {
1070 return TRUE;
1071 }
1072 child = FWL_GetWidgetMgr()->GetWidget(child, FWL_WGTRELATION_NextSibling);
1073 }
1074 return FALSE;
1075 }
1076