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