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