1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "xfa/fwl/cfwl_widgetmgr.h"
8
9 #include <utility>
10
11 #include "third_party/base/ptr_util.h"
12 #include "xfa/fwl/cfwl_app.h"
13 #include "xfa/fwl/cfwl_form.h"
14 #include "xfa/fwl/cfwl_notedriver.h"
15 #include "xfa/fxfa/cxfa_ffapp.h"
16 #include "xfa/fxfa/cxfa_fwladapterwidgetmgr.h"
17
18 namespace {
19
20 const int kNeedRepaintHitPoints = 12;
21 const int kNeedRepaintHitPiece = 3;
22
23 struct FWL_NEEDREPAINTHITDATA {
24 CFX_PointF hitPoint;
25 bool bNotNeedRepaint;
26 bool bNotContainByDirty;
27 };
28
29 } // namespace
30
CFWL_WidgetMgr(CXFA_FFApp * pAdapterNative)31 CFWL_WidgetMgr::CFWL_WidgetMgr(CXFA_FFApp* pAdapterNative)
32 : m_dwCapability(FWL_WGTMGR_DisableForm),
33 m_pAdapter(pAdapterNative->GetFWLAdapterWidgetMgr()) {
34 ASSERT(m_pAdapter);
35 m_mapWidgetItem[nullptr] = pdfium::MakeUnique<Item>();
36 #if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
37 m_rtScreen.Reset();
38 #endif // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
39 }
40
~CFWL_WidgetMgr()41 CFWL_WidgetMgr::~CFWL_WidgetMgr() {}
42
GetParentWidget(CFWL_Widget * pWidget) const43 CFWL_Widget* CFWL_WidgetMgr::GetParentWidget(CFWL_Widget* pWidget) const {
44 Item* pItem = GetWidgetMgrItem(pWidget);
45 return pItem && pItem->pParent ? pItem->pParent->pWidget : nullptr;
46 }
47
GetOwnerWidget(CFWL_Widget * pWidget) const48 CFWL_Widget* CFWL_WidgetMgr::GetOwnerWidget(CFWL_Widget* pWidget) const {
49 Item* pItem = GetWidgetMgrItem(pWidget);
50 return pItem && pItem->pOwner ? pItem->pOwner->pWidget : nullptr;
51 }
52
GetFirstSiblingWidget(CFWL_Widget * pWidget) const53 CFWL_Widget* CFWL_WidgetMgr::GetFirstSiblingWidget(CFWL_Widget* pWidget) const {
54 Item* pItem = GetWidgetMgrItem(pWidget);
55 if (!pItem)
56 return nullptr;
57
58 pItem = pItem->pPrevious;
59 while (pItem && pItem->pPrevious)
60 pItem = pItem->pPrevious;
61 return pItem ? pItem->pWidget : nullptr;
62 }
63
GetPriorSiblingWidget(CFWL_Widget * pWidget) const64 CFWL_Widget* CFWL_WidgetMgr::GetPriorSiblingWidget(CFWL_Widget* pWidget) const {
65 Item* pItem = GetWidgetMgrItem(pWidget);
66 return pItem && pItem->pPrevious ? pItem->pPrevious->pWidget : nullptr;
67 }
68
GetNextSiblingWidget(CFWL_Widget * pWidget) const69 CFWL_Widget* CFWL_WidgetMgr::GetNextSiblingWidget(CFWL_Widget* pWidget) const {
70 Item* pItem = GetWidgetMgrItem(pWidget);
71 return pItem && pItem->pNext ? pItem->pNext->pWidget : nullptr;
72 }
73
GetFirstChildWidget(CFWL_Widget * pWidget) const74 CFWL_Widget* CFWL_WidgetMgr::GetFirstChildWidget(CFWL_Widget* pWidget) const {
75 Item* pItem = GetWidgetMgrItem(pWidget);
76 return pItem && pItem->pChild ? pItem->pChild->pWidget : nullptr;
77 }
78
GetLastChildWidget(CFWL_Widget * pWidget) const79 CFWL_Widget* CFWL_WidgetMgr::GetLastChildWidget(CFWL_Widget* pWidget) const {
80 Item* pItem = GetWidgetMgrItem(pWidget);
81 if (!pItem)
82 return nullptr;
83
84 pItem = pItem->pChild;
85 while (pItem && pItem->pNext)
86 pItem = pItem->pNext;
87 return pItem ? pItem->pWidget : nullptr;
88 }
89
GetSystemFormWidget(CFWL_Widget * pWidget) const90 CFWL_Widget* CFWL_WidgetMgr::GetSystemFormWidget(CFWL_Widget* pWidget) const {
91 Item* pItem = GetWidgetMgrItem(pWidget);
92 while (pItem) {
93 if (IsAbleNative(pItem->pWidget))
94 return pItem->pWidget;
95 pItem = pItem->pParent;
96 }
97 return nullptr;
98 }
99
AppendWidget(CFWL_Widget * pWidget)100 void CFWL_WidgetMgr::AppendWidget(CFWL_Widget* pWidget) {
101 Item* pItem = GetWidgetMgrItem(pWidget);
102 if (!pItem)
103 return;
104 if (!pItem->pParent)
105 return;
106
107 Item* pChild = pItem->pParent->pChild;
108 int32_t i = 0;
109 while (pChild) {
110 if (pChild == pItem) {
111 if (pChild->pPrevious)
112 pChild->pPrevious->pNext = pChild->pNext;
113 if (pChild->pNext)
114 pChild->pNext->pPrevious = pChild->pPrevious;
115 if (pItem->pParent->pChild == pItem)
116 pItem->pParent->pChild = pItem->pNext;
117
118 pItem->pNext = nullptr;
119 pItem->pPrevious = nullptr;
120 break;
121 }
122 if (!pChild->pNext)
123 break;
124
125 pChild = pChild->pNext;
126 ++i;
127 }
128
129 pChild = pItem->pParent->pChild;
130 if (pChild) {
131 while (pChild->pNext)
132 pChild = pChild->pNext;
133
134 pChild->pNext = pItem;
135 pItem->pPrevious = pChild;
136 } else {
137 pItem->pParent->pChild = pItem;
138 pItem->pPrevious = nullptr;
139 }
140 pItem->pNext = nullptr;
141 }
142
RepaintWidget(CFWL_Widget * pWidget,const CFX_RectF & rect)143 void CFWL_WidgetMgr::RepaintWidget(CFWL_Widget* pWidget,
144 const CFX_RectF& rect) {
145 if (!m_pAdapter)
146 return;
147
148 CFWL_Widget* pNative = pWidget;
149 CFX_RectF transformedRect = rect;
150 if (IsFormDisabled()) {
151 CFWL_Widget* pOuter = pWidget->GetOuter();
152 while (pOuter) {
153 CFX_RectF rtTemp = pNative->GetWidgetRect();
154 transformedRect.left += rtTemp.left;
155 transformedRect.top += rtTemp.top;
156 pNative = pOuter;
157 pOuter = pOuter->GetOuter();
158 }
159 } else if (!IsAbleNative(pWidget)) {
160 pNative = GetSystemFormWidget(pWidget);
161 if (!pNative)
162 return;
163
164 CFX_PointF pos = pWidget->TransformTo(
165 pNative, CFX_PointF(transformedRect.left, transformedRect.top));
166 transformedRect.left = pos.x;
167 transformedRect.top = pos.y;
168 }
169 AddRedrawCounts(pNative);
170 m_pAdapter->RepaintWidget(pNative);
171 }
172
InsertWidget(CFWL_Widget * pParent,CFWL_Widget * pChild)173 void CFWL_WidgetMgr::InsertWidget(CFWL_Widget* pParent, CFWL_Widget* pChild) {
174 Item* pParentItem = GetWidgetMgrItem(pParent);
175 if (!pParentItem) {
176 auto item = pdfium::MakeUnique<Item>(pParent);
177 pParentItem = item.get();
178 m_mapWidgetItem[pParent] = std::move(item);
179
180 pParentItem->pParent = GetWidgetMgrItem(nullptr);
181 AppendWidget(pParent);
182 }
183
184 Item* pItem = GetWidgetMgrItem(pChild);
185 if (!pItem) {
186 auto item = pdfium::MakeUnique<Item>(pChild);
187 pItem = item.get();
188 m_mapWidgetItem[pChild] = std::move(item);
189 }
190 if (pItem->pParent && pItem->pParent != pParentItem) {
191 if (pItem->pPrevious)
192 pItem->pPrevious->pNext = pItem->pNext;
193 if (pItem->pNext)
194 pItem->pNext->pPrevious = pItem->pPrevious;
195 if (pItem->pParent->pChild == pItem)
196 pItem->pParent->pChild = pItem->pNext;
197 }
198 pItem->pParent = pParentItem;
199 AppendWidget(pChild);
200 }
201
RemoveWidget(CFWL_Widget * pWidget)202 void CFWL_WidgetMgr::RemoveWidget(CFWL_Widget* pWidget) {
203 Item* pItem = GetWidgetMgrItem(pWidget);
204 if (!pItem)
205 return;
206 if (pItem->pPrevious)
207 pItem->pPrevious->pNext = pItem->pNext;
208 if (pItem->pNext)
209 pItem->pNext->pPrevious = pItem->pPrevious;
210 if (pItem->pParent && pItem->pParent->pChild == pItem)
211 pItem->pParent->pChild = pItem->pNext;
212
213 Item* pChild = pItem->pChild;
214 while (pChild) {
215 Item* pNext = pChild->pNext;
216 RemoveWidget(pChild->pWidget);
217 pChild = pNext;
218 }
219 m_mapWidgetItem.erase(pWidget);
220 }
221
SetOwner(CFWL_Widget * pOwner,CFWL_Widget * pOwned)222 void CFWL_WidgetMgr::SetOwner(CFWL_Widget* pOwner, CFWL_Widget* pOwned) {
223 Item* pParentItem = GetWidgetMgrItem(pOwner);
224 if (!pParentItem) {
225 auto item = pdfium::MakeUnique<Item>(pOwner);
226 pParentItem = item.get();
227 m_mapWidgetItem[pOwner] = std::move(item);
228
229 pParentItem->pParent = GetWidgetMgrItem(nullptr);
230 AppendWidget(pOwner);
231 }
232
233 Item* pItem = GetWidgetMgrItem(pOwned);
234 if (!pItem) {
235 auto item = pdfium::MakeUnique<Item>(pOwned);
236 pItem = item.get();
237 m_mapWidgetItem[pOwned] = std::move(item);
238 }
239 pItem->pOwner = pParentItem;
240 }
SetParent(CFWL_Widget * pParent,CFWL_Widget * pChild)241 void CFWL_WidgetMgr::SetParent(CFWL_Widget* pParent, CFWL_Widget* pChild) {
242 Item* pParentItem = GetWidgetMgrItem(pParent);
243 Item* pItem = GetWidgetMgrItem(pChild);
244 if (!pItem)
245 return;
246 if (pItem->pParent && pItem->pParent != pParentItem) {
247 if (pItem->pPrevious)
248 pItem->pPrevious->pNext = pItem->pNext;
249 if (pItem->pNext)
250 pItem->pNext->pPrevious = pItem->pPrevious;
251 if (pItem->pParent->pChild == pItem)
252 pItem->pParent->pChild = pItem->pNext;
253
254 pItem->pNext = nullptr;
255 pItem->pPrevious = nullptr;
256 }
257 pItem->pParent = pParentItem;
258 AppendWidget(pChild);
259 }
260
GetWidgetAtPoint(CFWL_Widget * parent,const CFX_PointF & point) const261 CFWL_Widget* CFWL_WidgetMgr::GetWidgetAtPoint(CFWL_Widget* parent,
262 const CFX_PointF& point) const {
263 if (!parent)
264 return nullptr;
265
266 CFX_PointF pos;
267 CFWL_Widget* child = GetLastChildWidget(parent);
268 while (child) {
269 if ((child->GetStates() & FWL_WGTSTATE_Invisible) == 0) {
270 pos = parent->GetMatrix().GetInverse().Transform(point);
271
272 CFX_RectF bounds = child->GetWidgetRect();
273 if (bounds.Contains(pos)) {
274 pos -= bounds.TopLeft();
275 return GetWidgetAtPoint(child, pos);
276 }
277 }
278 child = GetPriorSiblingWidget(child);
279 }
280 return parent;
281 }
282
NextTab(CFWL_Widget * parent,CFWL_Widget * focus,bool & bFind)283 CFWL_Widget* CFWL_WidgetMgr::NextTab(CFWL_Widget* parent,
284 CFWL_Widget* focus,
285 bool& bFind) {
286 CFWL_WidgetMgr* pMgr = parent->GetOwnerApp()->GetWidgetMgr();
287 CFWL_Widget* child = pMgr->GetFirstChildWidget(parent);
288 while (child) {
289 if (focus == child)
290 bFind = true;
291
292 CFWL_Widget* bRet = NextTab(child, focus, bFind);
293 if (bRet)
294 return bRet;
295
296 child = pMgr->GetNextSiblingWidget(child);
297 }
298 return nullptr;
299 }
300
CountRadioButtonGroup(CFWL_Widget * pFirst) const301 int32_t CFWL_WidgetMgr::CountRadioButtonGroup(CFWL_Widget* pFirst) const {
302 int32_t iRet = 0;
303 CFWL_Widget* pChild = pFirst;
304 while (pChild) {
305 pChild = GetNextSiblingWidget(pChild);
306 ++iRet;
307 }
308 return iRet;
309 }
310
GetRadioButtonGroupHeader(CFWL_Widget * pRadioButton) const311 CFWL_Widget* CFWL_WidgetMgr::GetRadioButtonGroupHeader(
312 CFWL_Widget* pRadioButton) const {
313 CFWL_Widget* pNext = pRadioButton;
314 if (pNext && (pNext->GetStyles() & FWL_WGTSTYLE_Group))
315 return pNext;
316 return nullptr;
317 }
318
GetSameGroupRadioButton(CFWL_Widget * pRadioButton) const319 std::vector<CFWL_Widget*> CFWL_WidgetMgr::GetSameGroupRadioButton(
320 CFWL_Widget* pRadioButton) const {
321 CFWL_Widget* pFirst = GetFirstSiblingWidget(pRadioButton);
322 if (!pFirst)
323 pFirst = pRadioButton;
324
325 if (CountRadioButtonGroup(pFirst) < 2)
326 return std::vector<CFWL_Widget*>();
327
328 std::vector<CFWL_Widget*> group;
329 group.push_back(GetRadioButtonGroupHeader(pRadioButton));
330 return group;
331 }
332
GetDefaultButton(CFWL_Widget * pParent) const333 CFWL_Widget* CFWL_WidgetMgr::GetDefaultButton(CFWL_Widget* pParent) const {
334 if ((pParent->GetClassID() == FWL_Type::PushButton) &&
335 (pParent->GetStates() & (1 << (FWL_WGTSTATE_MAX + 2)))) {
336 return pParent;
337 }
338
339 CFWL_Widget* child =
340 pParent->GetOwnerApp()->GetWidgetMgr()->GetFirstChildWidget(pParent);
341 while (child) {
342 if ((child->GetClassID() == FWL_Type::PushButton) &&
343 (child->GetStates() & (1 << (FWL_WGTSTATE_MAX + 2)))) {
344 return child;
345 }
346 if (CFWL_Widget* find = GetDefaultButton(child))
347 return find;
348
349 child = child->GetOwnerApp()->GetWidgetMgr()->GetNextSiblingWidget(child);
350 }
351 return nullptr;
352 }
353
AddRedrawCounts(CFWL_Widget * pWidget)354 void CFWL_WidgetMgr::AddRedrawCounts(CFWL_Widget* pWidget) {
355 GetWidgetMgrItem(pWidget)->iRedrawCounter++;
356 }
357
ResetRedrawCounts(CFWL_Widget * pWidget)358 void CFWL_WidgetMgr::ResetRedrawCounts(CFWL_Widget* pWidget) {
359 GetWidgetMgrItem(pWidget)->iRedrawCounter = 0;
360 }
361
GetWidgetMgrItem(CFWL_Widget * pWidget) const362 CFWL_WidgetMgr::Item* CFWL_WidgetMgr::GetWidgetMgrItem(
363 CFWL_Widget* pWidget) const {
364 auto it = m_mapWidgetItem.find(pWidget);
365 return it != m_mapWidgetItem.end() ? static_cast<Item*>(it->second.get())
366 : nullptr;
367 }
368
IsAbleNative(CFWL_Widget * pWidget) const369 bool CFWL_WidgetMgr::IsAbleNative(CFWL_Widget* pWidget) const {
370 if (!pWidget)
371 return false;
372 if (!pWidget->IsInstance(FWL_CLASS_Form))
373 return false;
374
375 uint32_t dwStyles = pWidget->GetStyles();
376 return ((dwStyles & FWL_WGTSTYLE_WindowTypeMask) ==
377 FWL_WGTSTYLE_OverLapper) ||
378 (dwStyles & FWL_WGTSTYLE_Popup);
379 }
380
GetAdapterPopupPos(CFWL_Widget * pWidget,float fMinHeight,float fMaxHeight,const CFX_RectF & rtAnchor,CFX_RectF & rtPopup) const381 void CFWL_WidgetMgr::GetAdapterPopupPos(CFWL_Widget* pWidget,
382 float fMinHeight,
383 float fMaxHeight,
384 const CFX_RectF& rtAnchor,
385 CFX_RectF& rtPopup) const {
386 m_pAdapter->GetPopupPos(pWidget, fMinHeight, fMaxHeight, rtAnchor, rtPopup);
387 }
388
OnProcessMessageToForm(CFWL_Message * pMessage)389 void CFWL_WidgetMgr::OnProcessMessageToForm(CFWL_Message* pMessage) {
390 if (!pMessage)
391 return;
392 if (!pMessage->m_pDstTarget)
393 return;
394
395 CFWL_Widget* pDstWidget = pMessage->m_pDstTarget;
396 const CFWL_App* pApp = pDstWidget->GetOwnerApp();
397 if (!pApp)
398 return;
399
400 CFWL_NoteDriver* pNoteDriver =
401 static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver());
402 if (!pNoteDriver)
403 return;
404
405 if (IsFormDisabled())
406 pNoteDriver->ProcessMessage(pMessage->Clone());
407 else
408 pNoteDriver->QueueMessage(pMessage->Clone());
409
410 #if (_FX_OS_ == _FX_OS_MACOSX_)
411 CFWL_NoteLoop* pTopLoop = pNoteDriver->GetTopLoop();
412 if (pTopLoop)
413 pNoteDriver->UnqueueMessageAndProcess(pTopLoop);
414 #endif
415 }
416
OnDrawWidget(CFWL_Widget * pWidget,CXFA_Graphics * pGraphics,const CFX_Matrix & matrix)417 void CFWL_WidgetMgr::OnDrawWidget(CFWL_Widget* pWidget,
418 CXFA_Graphics* pGraphics,
419 const CFX_Matrix& matrix) {
420 if (!pWidget || !pGraphics)
421 return;
422
423 CFX_RectF clipCopy(0, 0, pWidget->GetWidgetRect().Size());
424 CFX_RectF clipBounds;
425
426 #if _FX_OS_ == _FX_OS_MACOSX_
427 if (IsFormDisabled()) {
428 #endif // _FX_OS_ == _FX_OS_MACOSX_
429
430 pWidget->GetDelegate()->OnDrawWidget(pGraphics, matrix);
431 clipBounds = pGraphics->GetClipRect();
432 clipCopy = clipBounds;
433
434 #if _FX_OS_ == _FX_OS_MACOSX_
435 } else {
436 clipBounds = CFX_RectF(matrix.a, matrix.b, matrix.c, matrix.d);
437 // FIXME: const cast
438 CFX_Matrix* pMatrixHack = const_cast<CFX_Matrix*>(&matrix);
439 pMatrixHack->SetIdentity();
440 pWidget->GetDelegate()->OnDrawWidget(pGraphics, *pMatrixHack);
441 }
442 #endif // _FX_OS_ == _FX_OS_MACOSX_
443
444 if (!IsFormDisabled())
445 clipBounds.Intersect(pWidget->GetClientRect());
446 if (!clipBounds.IsEmpty())
447 DrawChild(pWidget, clipBounds, pGraphics, &matrix);
448
449 GetWidgetMgrItem(pWidget)->iRedrawCounter = 0;
450 ResetRedrawCounts(pWidget);
451 }
452
DrawChild(CFWL_Widget * parent,const CFX_RectF & rtClip,CXFA_Graphics * pGraphics,const CFX_Matrix * pMatrix)453 void CFWL_WidgetMgr::DrawChild(CFWL_Widget* parent,
454 const CFX_RectF& rtClip,
455 CXFA_Graphics* pGraphics,
456 const CFX_Matrix* pMatrix) {
457 if (!parent)
458 return;
459
460 bool bFormDisable = IsFormDisabled();
461 CFWL_Widget* pNextChild = GetFirstChildWidget(parent);
462 while (pNextChild) {
463 CFWL_Widget* child = pNextChild;
464 pNextChild = GetNextSiblingWidget(child);
465 if (child->GetStates() & FWL_WGTSTATE_Invisible)
466 continue;
467
468 CFX_RectF rtWidget = child->GetWidgetRect();
469 if (rtWidget.IsEmpty())
470 continue;
471
472 CFX_Matrix widgetMatrix;
473 CFX_RectF clipBounds(rtWidget);
474 if (!bFormDisable)
475 widgetMatrix = child->GetMatrix();
476 if (pMatrix)
477 widgetMatrix.Concat(*pMatrix);
478
479 if (!bFormDisable) {
480 CFX_PointF pos = widgetMatrix.Transform(clipBounds.TopLeft());
481 clipBounds.left = pos.x;
482 clipBounds.top = pos.y;
483 clipBounds.Intersect(rtClip);
484 if (clipBounds.IsEmpty())
485 continue;
486
487 pGraphics->SaveGraphState();
488 pGraphics->SetClipRect(clipBounds);
489 }
490 widgetMatrix.Translate(rtWidget.left, rtWidget.top, true);
491
492 if (IFWL_WidgetDelegate* pDelegate = child->GetDelegate()) {
493 if (IsFormDisabled() || IsNeedRepaint(child, &widgetMatrix, rtClip))
494 pDelegate->OnDrawWidget(pGraphics, widgetMatrix);
495 }
496 if (!bFormDisable)
497 pGraphics->RestoreGraphState();
498
499 DrawChild(child, clipBounds, pGraphics,
500 bFormDisable ? &widgetMatrix : pMatrix);
501 child = GetNextSiblingWidget(child);
502 }
503 }
504
IsNeedRepaint(CFWL_Widget * pWidget,CFX_Matrix * pMatrix,const CFX_RectF & rtDirty)505 bool CFWL_WidgetMgr::IsNeedRepaint(CFWL_Widget* pWidget,
506 CFX_Matrix* pMatrix,
507 const CFX_RectF& rtDirty) {
508 Item* pItem = GetWidgetMgrItem(pWidget);
509 if (pItem && pItem->iRedrawCounter > 0) {
510 pItem->iRedrawCounter = 0;
511 return true;
512 }
513
514 CFX_RectF rtWidget =
515 pMatrix->TransformRect(CFX_RectF(0, 0, pWidget->GetWidgetRect().Size()));
516 if (!rtWidget.IntersectWith(rtDirty))
517 return false;
518
519 CFWL_Widget* pChild =
520 pWidget->GetOwnerApp()->GetWidgetMgr()->GetFirstChildWidget(pWidget);
521 if (!pChild)
522 return true;
523
524 CFX_RectF rtChilds;
525 bool bChildIntersectWithDirty = false;
526 bool bOrginPtIntersectWidthChild = false;
527 bool bOrginPtIntersectWidthDirty = rtDirty.Contains(rtWidget.TopLeft());
528 static FWL_NEEDREPAINTHITDATA hitPoint[kNeedRepaintHitPoints];
529 memset(hitPoint, 0, sizeof(hitPoint));
530 float fxPiece = rtWidget.width / kNeedRepaintHitPiece;
531 float fyPiece = rtWidget.height / kNeedRepaintHitPiece;
532 hitPoint[2].hitPoint.x = hitPoint[6].hitPoint.x = rtWidget.left;
533 hitPoint[0].hitPoint.x = hitPoint[3].hitPoint.x = hitPoint[7].hitPoint.x =
534 hitPoint[10].hitPoint.x = fxPiece + rtWidget.left;
535 hitPoint[1].hitPoint.x = hitPoint[4].hitPoint.x = hitPoint[8].hitPoint.x =
536 hitPoint[11].hitPoint.x = fxPiece * 2 + rtWidget.left;
537 hitPoint[5].hitPoint.x = hitPoint[9].hitPoint.x =
538 rtWidget.width + rtWidget.left;
539 hitPoint[0].hitPoint.y = hitPoint[1].hitPoint.y = rtWidget.top;
540 hitPoint[2].hitPoint.y = hitPoint[3].hitPoint.y = hitPoint[4].hitPoint.y =
541 hitPoint[5].hitPoint.y = fyPiece + rtWidget.top;
542 hitPoint[6].hitPoint.y = hitPoint[7].hitPoint.y = hitPoint[8].hitPoint.y =
543 hitPoint[9].hitPoint.y = fyPiece * 2 + rtWidget.top;
544 hitPoint[10].hitPoint.y = hitPoint[11].hitPoint.y =
545 rtWidget.height + rtWidget.top;
546 do {
547 CFX_RectF rect = pChild->GetWidgetRect();
548 CFX_RectF r(rect.left + rtWidget.left, rect.top + rtWidget.top, rect.width,
549 rect.height);
550 if (r.IsEmpty())
551 continue;
552 if (r.Contains(rtDirty))
553 return false;
554 if (!bChildIntersectWithDirty && r.IntersectWith(rtDirty))
555 bChildIntersectWithDirty = true;
556 if (bOrginPtIntersectWidthDirty && !bOrginPtIntersectWidthChild)
557 bOrginPtIntersectWidthChild = rect.Contains(CFX_PointF(0, 0));
558
559 if (rtChilds.IsEmpty())
560 rtChilds = rect;
561 else if (!(pChild->GetStates() & FWL_WGTSTATE_Invisible))
562 rtChilds.Union(rect);
563
564 for (int32_t i = 0; i < kNeedRepaintHitPoints; i++) {
565 if (hitPoint[i].bNotContainByDirty || hitPoint[i].bNotNeedRepaint)
566 continue;
567 if (!rtDirty.Contains(hitPoint[i].hitPoint)) {
568 hitPoint[i].bNotContainByDirty = true;
569 continue;
570 }
571 if (r.Contains(hitPoint[i].hitPoint))
572 hitPoint[i].bNotNeedRepaint = true;
573 }
574 pChild =
575 pChild->GetOwnerApp()->GetWidgetMgr()->GetNextSiblingWidget(pChild);
576 } while (pChild);
577
578 if (!bChildIntersectWithDirty)
579 return true;
580 if (bOrginPtIntersectWidthDirty && !bOrginPtIntersectWidthChild)
581 return true;
582 if (rtChilds.IsEmpty())
583 return true;
584
585 int32_t repaintPoint = kNeedRepaintHitPoints;
586 for (int32_t i = 0; i < kNeedRepaintHitPoints; i++) {
587 if (hitPoint[i].bNotNeedRepaint)
588 repaintPoint--;
589 }
590 if (repaintPoint > 0)
591 return true;
592
593 rtChilds = pMatrix->TransformRect(rtChilds);
594 if (rtChilds.Contains(rtDirty) || rtChilds.Contains(rtWidget))
595 return false;
596 return true;
597 }
598
Item()599 CFWL_WidgetMgr::Item::Item() : CFWL_WidgetMgr::Item(nullptr) {}
600
Item(CFWL_Widget * widget)601 CFWL_WidgetMgr::Item::Item(CFWL_Widget* widget)
602 : pParent(nullptr),
603 pOwner(nullptr),
604 pChild(nullptr),
605 pPrevious(nullptr),
606 pNext(nullptr),
607 pWidget(widget),
608 iRedrawCounter(0)
609 #if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
610 ,
611 bOutsideChanged(false)
612 #endif // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
613 {
614 }
615
~Item()616 CFWL_WidgetMgr::Item::~Item() {}
617