Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(154)

Side by Side Diff: xfa/fwl/core/cfwl_widgetmgr.cpp

Issue 2559173002: Move xfa/fwl/core to xfa/fwl. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « xfa/fwl/core/cfwl_widgetmgr.h ('k') | xfa/fwl/core/cfwl_widgetproperties.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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/fwl/core/cfwl_widgetmgr.h"
8
9 #include <utility>
10
11 #include "third_party/base/ptr_util.h"
12 #include "xfa/fwl/core/cfwl_app.h"
13 #include "xfa/fwl/core/cfwl_form.h"
14 #include "xfa/fwl/core/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
31 bool FWL_UseOffscreen(CFWL_Widget* pWidget) {
32 #if (_FX_OS_ == _FX_MACOSX_)
33 return false;
34 #else
35 return !!(pWidget->GetStyles() & FWL_WGTSTYLE_Offscreen);
36 #endif
37 }
38
39 CFWL_WidgetMgr::CFWL_WidgetMgr(CXFA_FFApp* pAdapterNative)
40 : m_dwCapability(0), m_pAdapter(pAdapterNative->GetWidgetMgr(this)) {
41 ASSERT(m_pAdapter);
42 m_mapWidgetItem[nullptr] = pdfium::MakeUnique<Item>();
43 #if (_FX_OS_ == _FX_WIN32_DESKTOP_) || (_FX_OS_ == _FX_WIN64_)
44 m_rtScreen.Reset();
45 #endif
46 }
47
48 CFWL_WidgetMgr::~CFWL_WidgetMgr() {}
49
50 CFWL_Widget* CFWL_WidgetMgr::GetParentWidget(CFWL_Widget* pWidget) const {
51 Item* pItem = GetWidgetMgrItem(pWidget);
52 return pItem && pItem->pParent ? pItem->pParent->pWidget : nullptr;
53 }
54
55 CFWL_Widget* CFWL_WidgetMgr::GetOwnerWidget(CFWL_Widget* pWidget) const {
56 Item* pItem = GetWidgetMgrItem(pWidget);
57 return pItem && pItem->pOwner ? pItem->pOwner->pWidget : nullptr;
58 }
59
60 CFWL_Widget* CFWL_WidgetMgr::GetFirstSiblingWidget(CFWL_Widget* pWidget) const {
61 Item* pItem = GetWidgetMgrItem(pWidget);
62 if (!pItem)
63 return nullptr;
64
65 pItem = pItem->pPrevious;
66 while (pItem && pItem->pPrevious)
67 pItem = pItem->pPrevious;
68 return pItem ? pItem->pWidget : nullptr;
69 }
70
71 CFWL_Widget* CFWL_WidgetMgr::GetPriorSiblingWidget(CFWL_Widget* pWidget) const {
72 Item* pItem = GetWidgetMgrItem(pWidget);
73 return pItem && pItem->pPrevious ? pItem->pPrevious->pWidget : nullptr;
74 }
75
76 CFWL_Widget* CFWL_WidgetMgr::GetNextSiblingWidget(CFWL_Widget* pWidget) const {
77 Item* pItem = GetWidgetMgrItem(pWidget);
78 return pItem && pItem->pNext ? pItem->pNext->pWidget : nullptr;
79 }
80
81 CFWL_Widget* CFWL_WidgetMgr::GetFirstChildWidget(CFWL_Widget* pWidget) const {
82 Item* pItem = GetWidgetMgrItem(pWidget);
83 return pItem && pItem->pChild ? pItem->pChild->pWidget : nullptr;
84 }
85
86 CFWL_Widget* CFWL_WidgetMgr::GetLastChildWidget(CFWL_Widget* pWidget) const {
87 Item* pItem = GetWidgetMgrItem(pWidget);
88 if (!pItem)
89 return nullptr;
90
91 pItem = pItem->pChild;
92 while (pItem && pItem->pNext)
93 pItem = pItem->pNext;
94 return pItem ? pItem->pWidget : nullptr;
95 }
96
97 CFWL_Widget* CFWL_WidgetMgr::GetSystemFormWidget(CFWL_Widget* pWidget) const {
98 Item* pItem = GetWidgetMgrItem(pWidget);
99 while (pItem) {
100 if (IsAbleNative(pItem->pWidget))
101 return pItem->pWidget;
102 pItem = pItem->pParent;
103 }
104 return nullptr;
105 }
106
107 void CFWL_WidgetMgr::AppendWidget(CFWL_Widget* pWidget) {
108 Item* pItem = GetWidgetMgrItem(pWidget);
109 if (!pItem)
110 return;
111 if (!pItem->pParent)
112 return;
113
114 Item* pChild = pItem->pParent->pChild;
115 int32_t i = 0;
116 while (pChild) {
117 if (pChild == pItem) {
118 if (pChild->pPrevious)
119 pChild->pPrevious->pNext = pChild->pNext;
120 if (pChild->pNext)
121 pChild->pNext->pPrevious = pChild->pPrevious;
122 if (pItem->pParent->pChild == pItem)
123 pItem->pParent->pChild = pItem->pNext;
124
125 pItem->pNext = nullptr;
126 pItem->pPrevious = nullptr;
127 break;
128 }
129 if (!pChild->pNext)
130 break;
131
132 pChild = pChild->pNext;
133 ++i;
134 }
135
136 pChild = pItem->pParent->pChild;
137 if (pChild) {
138 while (pChild->pNext)
139 pChild = pChild->pNext;
140
141 pChild->pNext = pItem;
142 pItem->pPrevious = pChild;
143 } else {
144 pItem->pParent->pChild = pItem;
145 pItem->pPrevious = nullptr;
146 }
147 pItem->pNext = nullptr;
148 }
149
150 void CFWL_WidgetMgr::RepaintWidget(CFWL_Widget* pWidget,
151 const CFX_RectF* pRect) {
152 if (!m_pAdapter)
153 return;
154
155 CFWL_Widget* pNative = pWidget;
156 CFX_RectF rect(*pRect);
157 if (IsFormDisabled()) {
158 CFWL_Widget* pOuter = pWidget->GetOuter();
159 while (pOuter) {
160 CFX_RectF rtTemp = pNative->GetWidgetRect();
161 rect.left += rtTemp.left;
162 rect.top += rtTemp.top;
163 pNative = pOuter;
164 pOuter = pOuter->GetOuter();
165 }
166 } else if (!IsAbleNative(pWidget)) {
167 pNative = GetSystemFormWidget(pWidget);
168 if (!pNative)
169 return;
170
171 pWidget->TransformTo(pNative, rect.left, rect.top);
172 }
173 AddRedrawCounts(pNative);
174 m_pAdapter->RepaintWidget(pNative, &rect);
175 }
176
177 void CFWL_WidgetMgr::InsertWidget(CFWL_Widget* pParent, CFWL_Widget* pChild) {
178 Item* pParentItem = GetWidgetMgrItem(pParent);
179 if (!pParentItem) {
180 auto item = pdfium::MakeUnique<Item>(pParent);
181 pParentItem = item.get();
182 m_mapWidgetItem[pParent] = std::move(item);
183
184 pParentItem->pParent = GetWidgetMgrItem(nullptr);
185 AppendWidget(pParent);
186 }
187
188 Item* pItem = GetWidgetMgrItem(pChild);
189 if (!pItem) {
190 auto item = pdfium::MakeUnique<Item>(pChild);
191 pItem = item.get();
192 m_mapWidgetItem[pChild] = std::move(item);
193 }
194 if (pItem->pParent && pItem->pParent != pParentItem) {
195 if (pItem->pPrevious)
196 pItem->pPrevious->pNext = pItem->pNext;
197 if (pItem->pNext)
198 pItem->pNext->pPrevious = pItem->pPrevious;
199 if (pItem->pParent->pChild == pItem)
200 pItem->pParent->pChild = pItem->pNext;
201 }
202 pItem->pParent = pParentItem;
203 AppendWidget(pChild);
204 }
205
206 void CFWL_WidgetMgr::RemoveWidget(CFWL_Widget* pWidget) {
207 Item* pItem = GetWidgetMgrItem(pWidget);
208 if (!pItem)
209 return;
210 if (pItem->pPrevious)
211 pItem->pPrevious->pNext = pItem->pNext;
212 if (pItem->pNext)
213 pItem->pNext->pPrevious = pItem->pPrevious;
214 if (pItem->pParent && pItem->pParent->pChild == pItem)
215 pItem->pParent->pChild = pItem->pNext;
216
217 Item* pChild = pItem->pChild;
218 while (pChild) {
219 Item* pNext = pChild->pNext;
220 RemoveWidget(pChild->pWidget);
221 pChild = pNext;
222 }
223 m_mapWidgetItem.erase(pWidget);
224 }
225
226 void CFWL_WidgetMgr::SetOwner(CFWL_Widget* pOwner, CFWL_Widget* pOwned) {
227 Item* pParentItem = GetWidgetMgrItem(pOwner);
228 if (!pParentItem) {
229 auto item = pdfium::MakeUnique<Item>(pOwner);
230 pParentItem = item.get();
231 m_mapWidgetItem[pOwner] = std::move(item);
232
233 pParentItem->pParent = GetWidgetMgrItem(nullptr);
234 AppendWidget(pOwner);
235 }
236
237 Item* pItem = GetWidgetMgrItem(pOwned);
238 if (!pItem) {
239 auto item = pdfium::MakeUnique<Item>(pOwned);
240 pItem = item.get();
241 m_mapWidgetItem[pOwned] = std::move(item);
242 }
243 pItem->pOwner = pParentItem;
244 }
245 void CFWL_WidgetMgr::SetParent(CFWL_Widget* pParent, CFWL_Widget* pChild) {
246 Item* pParentItem = GetWidgetMgrItem(pParent);
247 Item* pItem = GetWidgetMgrItem(pChild);
248 if (!pItem)
249 return;
250 if (pItem->pParent && pItem->pParent != pParentItem) {
251 if (pItem->pPrevious)
252 pItem->pPrevious->pNext = pItem->pNext;
253 if (pItem->pNext)
254 pItem->pNext->pPrevious = pItem->pPrevious;
255 if (pItem->pParent->pChild == pItem)
256 pItem->pParent->pChild = pItem->pNext;
257
258 pItem->pNext = nullptr;
259 pItem->pPrevious = nullptr;
260 }
261 pItem->pParent = pParentItem;
262 AppendWidget(pChild);
263 }
264
265 void CFWL_WidgetMgr::SetWidgetRect_Native(CFWL_Widget* pWidget,
266 const CFX_RectF& rect) {
267 if (!FWL_UseOffscreen(pWidget))
268 return;
269
270 Item* pItem = GetWidgetMgrItem(pWidget);
271 pItem->iRedrawCounter++;
272 if (pItem->pOffscreen) {
273 CFX_RenderDevice* pDevice = pItem->pOffscreen->GetRenderDevice();
274 if (pDevice && pDevice->GetBitmap()) {
275 CFX_DIBitmap* pBitmap = pDevice->GetBitmap();
276 if (pBitmap->GetWidth() - rect.width > 1 ||
277 pBitmap->GetHeight() - rect.height > 1) {
278 pItem->pOffscreen.reset();
279 }
280 }
281 }
282 #if (_FX_OS_ == _FX_WIN32_DESKTOP_) || (_FX_OS_ == _FX_WIN64_)
283 pItem->bOutsideChanged = !m_rtScreen.Contains(rect);
284 #endif
285 }
286
287 CFWL_Widget* CFWL_WidgetMgr::GetWidgetAtPoint(CFWL_Widget* parent,
288 FX_FLOAT x,
289 FX_FLOAT y) {
290 if (!parent)
291 return nullptr;
292
293 FX_FLOAT x1;
294 FX_FLOAT y1;
295 CFWL_Widget* child = GetLastChildWidget(parent);
296 while (child) {
297 if ((child->GetStates() & FWL_WGTSTATE_Invisible) == 0) {
298 x1 = x;
299 y1 = y;
300 CFX_Matrix matrixOnParent;
301 child->GetMatrix(matrixOnParent, false);
302 CFX_Matrix m;
303 m.SetIdentity();
304 m.SetReverse(matrixOnParent);
305 m.TransformPoint(x1, y1);
306 CFX_RectF bounds = child->GetWidgetRect();
307 if (bounds.Contains(x1, y1)) {
308 x1 -= bounds.left;
309 y1 -= bounds.top;
310 return GetWidgetAtPoint(child, x1, y1);
311 }
312 }
313 child = GetPriorSiblingWidget(child);
314 }
315 return parent;
316 }
317
318 void CFWL_WidgetMgr::NotifySizeChanged(CFWL_Widget* pForm,
319 FX_FLOAT fx,
320 FX_FLOAT fy) {
321 if (FWL_UseOffscreen(pForm))
322 GetWidgetMgrItem(pForm)->pOffscreen.reset();
323 }
324
325 CFWL_Widget* CFWL_WidgetMgr::NextTab(CFWL_Widget* parent,
326 CFWL_Widget* focus,
327 bool& bFind) {
328 CFWL_WidgetMgr* pMgr = parent->GetOwnerApp()->GetWidgetMgr();
329 CFWL_Widget* child = pMgr->GetFirstChildWidget(parent);
330 while (child) {
331 if (focus == child)
332 bFind = true;
333
334 if ((child->GetStyles() & FWL_WGTSTYLE_TabStop) &&
335 (!focus || (focus != child && bFind))) {
336 return child;
337 }
338 CFWL_Widget* bRet = NextTab(child, focus, bFind);
339 if (bRet)
340 return bRet;
341
342 child = pMgr->GetNextSiblingWidget(child);
343 }
344 return nullptr;
345 }
346
347 int32_t CFWL_WidgetMgr::CountRadioButtonGroup(CFWL_Widget* pFirst) const {
348 int32_t iRet = 0;
349 CFWL_Widget* pChild = pFirst;
350 while (pChild) {
351 pChild = GetNextSiblingWidget(pChild);
352 ++iRet;
353 }
354 return iRet;
355 }
356
357 CFWL_Widget* CFWL_WidgetMgr::GetRadioButtonGroupHeader(
358 CFWL_Widget* pRadioButton) const {
359 CFWL_Widget* pNext = pRadioButton;
360 if (pNext && (pNext->GetStyles() & FWL_WGTSTYLE_Group))
361 return pNext;
362 return nullptr;
363 }
364
365 void CFWL_WidgetMgr::GetSameGroupRadioButton(
366 CFWL_Widget* pRadioButton,
367 CFX_ArrayTemplate<CFWL_Widget*>& group) const {
368 CFWL_Widget* pFirst = GetFirstSiblingWidget(pRadioButton);
369 if (!pFirst)
370 pFirst = pRadioButton;
371
372 int32_t iGroup = CountRadioButtonGroup(pFirst);
373 if (iGroup < 2)
374 return;
375 group.Add(GetRadioButtonGroupHeader(pRadioButton));
376 }
377
378 CFWL_Widget* CFWL_WidgetMgr::GetDefaultButton(CFWL_Widget* pParent) const {
379 if ((pParent->GetClassID() == FWL_Type::PushButton) &&
380 (pParent->GetStates() & (1 << (FWL_WGTSTATE_MAX + 2)))) {
381 return pParent;
382 }
383
384 CFWL_Widget* child =
385 pParent->GetOwnerApp()->GetWidgetMgr()->GetFirstChildWidget(pParent);
386 while (child) {
387 if ((child->GetClassID() == FWL_Type::PushButton) &&
388 (child->GetStates() & (1 << (FWL_WGTSTATE_MAX + 2)))) {
389 return child;
390 }
391 if (CFWL_Widget* find = GetDefaultButton(child))
392 return find;
393
394 child = child->GetOwnerApp()->GetWidgetMgr()->GetNextSiblingWidget(child);
395 }
396 return nullptr;
397 }
398
399 void CFWL_WidgetMgr::AddRedrawCounts(CFWL_Widget* pWidget) {
400 GetWidgetMgrItem(pWidget)->iRedrawCounter++;
401 }
402
403 void CFWL_WidgetMgr::ResetRedrawCounts(CFWL_Widget* pWidget) {
404 GetWidgetMgrItem(pWidget)->iRedrawCounter = 0;
405 }
406
407 CFWL_WidgetMgr::Item* CFWL_WidgetMgr::GetWidgetMgrItem(
408 CFWL_Widget* pWidget) const {
409 auto it = m_mapWidgetItem.find(pWidget);
410 return it != m_mapWidgetItem.end() ? static_cast<Item*>(it->second.get())
411 : nullptr;
412 }
413
414 bool CFWL_WidgetMgr::IsAbleNative(CFWL_Widget* pWidget) const {
415 if (!pWidget)
416 return false;
417 if (!pWidget->IsInstance(FX_WSTRC(FWL_CLASS_Form)))
418 return false;
419
420 uint32_t dwStyles = pWidget->GetStyles();
421 return ((dwStyles & FWL_WGTSTYLE_WindowTypeMask) ==
422 FWL_WGTSTYLE_OverLapper) ||
423 (dwStyles & FWL_WGTSTYLE_Popup);
424 }
425
426 void CFWL_WidgetMgr::GetAdapterPopupPos(CFWL_Widget* pWidget,
427 FX_FLOAT fMinHeight,
428 FX_FLOAT fMaxHeight,
429 const CFX_RectF& rtAnchor,
430 CFX_RectF& rtPopup) const {
431 m_pAdapter->GetPopupPos(pWidget, fMinHeight, fMaxHeight, rtAnchor, rtPopup);
432 }
433
434 void CFWL_WidgetMgr::OnSetCapability(uint32_t dwCapability) {
435 m_dwCapability = dwCapability;
436 }
437
438 void CFWL_WidgetMgr::OnProcessMessageToForm(CFWL_Message* pMessage) {
439 if (!pMessage)
440 return;
441 if (!pMessage->m_pDstTarget)
442 return;
443
444 CFWL_Widget* pDstWidget = pMessage->m_pDstTarget;
445 const CFWL_App* pApp = pDstWidget->GetOwnerApp();
446 if (!pApp)
447 return;
448
449 CFWL_NoteDriver* pNoteDriver =
450 static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver());
451 if (!pNoteDriver)
452 return;
453
454 std::unique_ptr<CFWL_Message> pClonedMessage = pMessage->Clone();
455 if (IsFormDisabled())
456 pNoteDriver->ProcessMessage(pClonedMessage.get());
457 else
458 pNoteDriver->QueueMessage(std::move(pClonedMessage));
459
460 #if (_FX_OS_ == _FX_MACOSX_)
461 CFWL_NoteLoop* pTopLoop = pNoteDriver->GetTopLoop();
462 if (pTopLoop)
463 pNoteDriver->UnqueueMessage(pTopLoop);
464 #endif
465 }
466
467 void CFWL_WidgetMgr::OnDrawWidget(CFWL_Widget* pWidget,
468 CFX_Graphics* pGraphics,
469 const CFX_Matrix* pMatrix) {
470 if (!pWidget || !pGraphics)
471 return;
472
473 CFX_Graphics* pTemp = DrawWidgetBefore(pWidget, pGraphics, pMatrix);
474 CFX_RectF clipCopy = pWidget->GetWidgetRect();
475 clipCopy.left = clipCopy.top = 0;
476
477 if (UseOffscreenDirect(pWidget)) {
478 DrawWidgetAfter(pWidget, pGraphics, clipCopy, pMatrix);
479 return;
480 }
481 CFX_RectF clipBounds;
482
483 #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_ || \
484 _FX_OS_ == _FX_LINUX_DESKTOP_ || _FX_OS_ == _FX_ANDROID_
485 pWidget->GetDelegate()->OnDrawWidget(pTemp, pMatrix);
486 pGraphics->GetClipRect(clipBounds);
487 clipCopy = clipBounds;
488 #elif _FX_OS_ == _FX_MACOSX_
489 if (IsFormDisabled()) {
490 pWidget->GetDelegate()->OnDrawWidget(pTemp, pMatrix);
491 pGraphics->GetClipRect(clipBounds);
492 clipCopy = clipBounds;
493 } else {
494 clipBounds.Set(pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d);
495 const_cast<CFX_Matrix*>(pMatrix)->SetIdentity(); // FIXME: const cast.
496 pWidget->GetDelegate()->OnDrawWidget(pTemp, pMatrix);
497 }
498 #endif // _FX_OS_ == _FX_MACOSX_
499
500 if (!IsFormDisabled()) {
501 CFX_RectF rtClient;
502 pWidget->GetClientRect(rtClient);
503 clipBounds.Intersect(rtClient);
504 }
505 if (!clipBounds.IsEmpty())
506 DrawChild(pWidget, clipBounds, pTemp, pMatrix);
507
508 DrawWidgetAfter(pWidget, pGraphics, clipCopy, pMatrix);
509 ResetRedrawCounts(pWidget);
510 }
511
512 void CFWL_WidgetMgr::DrawChild(CFWL_Widget* parent,
513 const CFX_RectF& rtClip,
514 CFX_Graphics* pGraphics,
515 const CFX_Matrix* pMatrix) {
516 if (!parent)
517 return;
518
519 bool bFormDisable = IsFormDisabled();
520 CFWL_Widget* pNextChild = GetFirstChildWidget(parent);
521 while (pNextChild) {
522 CFWL_Widget* child = pNextChild;
523 pNextChild = GetNextSiblingWidget(child);
524 if (child->GetStates() & FWL_WGTSTATE_Invisible)
525 continue;
526
527 CFX_RectF rtWidget = child->GetWidgetRect();
528 if (rtWidget.IsEmpty())
529 continue;
530
531 CFX_Matrix widgetMatrix;
532 CFX_RectF clipBounds(rtWidget);
533 if (!bFormDisable)
534 child->GetMatrix(widgetMatrix, true);
535 if (pMatrix)
536 widgetMatrix.Concat(*pMatrix);
537
538 if (!bFormDisable) {
539 widgetMatrix.TransformPoint(clipBounds.left, clipBounds.top);
540 clipBounds.Intersect(rtClip);
541 if (clipBounds.IsEmpty())
542 continue;
543
544 pGraphics->SaveGraphState();
545 pGraphics->SetClipRect(clipBounds);
546 }
547 widgetMatrix.Translate(rtWidget.left, rtWidget.top, true);
548
549 if (IFWL_WidgetDelegate* pDelegate = child->GetDelegate()) {
550 if (IsFormDisabled() || IsNeedRepaint(child, &widgetMatrix, rtClip))
551 pDelegate->OnDrawWidget(pGraphics, &widgetMatrix);
552 }
553 if (!bFormDisable)
554 pGraphics->RestoreGraphState();
555
556 DrawChild(child, clipBounds, pGraphics,
557 bFormDisable ? &widgetMatrix : pMatrix);
558 child = GetNextSiblingWidget(child);
559 }
560 }
561
562 CFX_Graphics* CFWL_WidgetMgr::DrawWidgetBefore(CFWL_Widget* pWidget,
563 CFX_Graphics* pGraphics,
564 const CFX_Matrix* pMatrix) {
565 if (!FWL_UseOffscreen(pWidget))
566 return pGraphics;
567
568 Item* pItem = GetWidgetMgrItem(pWidget);
569 if (!pItem->pOffscreen) {
570 pItem->pOffscreen.reset(new CFX_Graphics);
571 CFX_RectF rect = pWidget->GetWidgetRect();
572 pItem->pOffscreen->Create((int32_t)rect.width, (int32_t)rect.height,
573 FXDIB_Argb);
574 }
575 CFX_RectF rect;
576 pGraphics->GetClipRect(rect);
577 pItem->pOffscreen->SetClipRect(rect);
578 return pItem->pOffscreen.get();
579 }
580
581 void CFWL_WidgetMgr::DrawWidgetAfter(CFWL_Widget* pWidget,
582 CFX_Graphics* pGraphics,
583 CFX_RectF& rtClip,
584 const CFX_Matrix* pMatrix) {
585 if (FWL_UseOffscreen(pWidget)) {
586 Item* pItem = GetWidgetMgrItem(pWidget);
587 pGraphics->Transfer(pItem->pOffscreen.get(), rtClip.left, rtClip.top,
588 rtClip, pMatrix);
589 #ifdef _WIN32
590 pItem->pOffscreen->ClearClip();
591 #endif
592 }
593 Item* pItem = GetWidgetMgrItem(pWidget);
594 pItem->iRedrawCounter = 0;
595 }
596
597 bool CFWL_WidgetMgr::IsNeedRepaint(CFWL_Widget* pWidget,
598 CFX_Matrix* pMatrix,
599 const CFX_RectF& rtDirty) {
600 Item* pItem = GetWidgetMgrItem(pWidget);
601 if (pItem && pItem->iRedrawCounter > 0) {
602 pItem->iRedrawCounter = 0;
603 return true;
604 }
605
606 CFX_RectF rtWidget = pWidget->GetWidgetRect();
607 rtWidget.left = rtWidget.top = 0;
608 pMatrix->TransformRect(rtWidget);
609 if (!rtWidget.IntersectWith(rtDirty))
610 return false;
611
612 CFWL_Widget* pChild =
613 pWidget->GetOwnerApp()->GetWidgetMgr()->GetFirstChildWidget(pWidget);
614 if (!pChild)
615 return true;
616
617 CFX_RectF rtChilds;
618 rtChilds.Empty();
619 bool bChildIntersectWithDirty = false;
620 bool bOrginPtIntersectWidthChild = false;
621 bool bOrginPtIntersectWidthDirty =
622 rtDirty.Contains(rtWidget.left, rtWidget.top);
623 static FWL_NEEDREPAINTHITDATA hitPoint[kNeedRepaintHitPoints];
624 FXSYS_memset(hitPoint, 0, sizeof(hitPoint));
625 FX_FLOAT fxPiece = rtWidget.width / kNeedRepaintHitPiece;
626 FX_FLOAT fyPiece = rtWidget.height / kNeedRepaintHitPiece;
627 hitPoint[2].hitPoint.x = hitPoint[6].hitPoint.x = rtWidget.left;
628 hitPoint[0].hitPoint.x = hitPoint[3].hitPoint.x = hitPoint[7].hitPoint.x =
629 hitPoint[10].hitPoint.x = fxPiece + rtWidget.left;
630 hitPoint[1].hitPoint.x = hitPoint[4].hitPoint.x = hitPoint[8].hitPoint.x =
631 hitPoint[11].hitPoint.x = fxPiece * 2 + rtWidget.left;
632 hitPoint[5].hitPoint.x = hitPoint[9].hitPoint.x =
633 rtWidget.width + rtWidget.left;
634 hitPoint[0].hitPoint.y = hitPoint[1].hitPoint.y = rtWidget.top;
635 hitPoint[2].hitPoint.y = hitPoint[3].hitPoint.y = hitPoint[4].hitPoint.y =
636 hitPoint[5].hitPoint.y = fyPiece + rtWidget.top;
637 hitPoint[6].hitPoint.y = hitPoint[7].hitPoint.y = hitPoint[8].hitPoint.y =
638 hitPoint[9].hitPoint.y = fyPiece * 2 + rtWidget.top;
639 hitPoint[10].hitPoint.y = hitPoint[11].hitPoint.y =
640 rtWidget.height + rtWidget.top;
641 do {
642 CFX_RectF rect = pChild->GetWidgetRect();
643 CFX_RectF r = rect;
644 r.left += rtWidget.left;
645 r.top += rtWidget.top;
646 if (r.IsEmpty())
647 continue;
648 if (r.Contains(rtDirty))
649 return false;
650 if (!bChildIntersectWithDirty && r.IntersectWith(rtDirty))
651 bChildIntersectWithDirty = true;
652 if (bOrginPtIntersectWidthDirty && !bOrginPtIntersectWidthChild)
653 bOrginPtIntersectWidthChild = rect.Contains(0, 0);
654
655 if (rtChilds.IsEmpty())
656 rtChilds = rect;
657 else if (!(pChild->GetStates() & FWL_WGTSTATE_Invisible))
658 rtChilds.Union(rect);
659
660 for (int32_t i = 0; i < kNeedRepaintHitPoints; i++) {
661 if (hitPoint[i].bNotContainByDirty || hitPoint[i].bNotNeedRepaint)
662 continue;
663 if (!rtDirty.Contains(hitPoint[i].hitPoint)) {
664 hitPoint[i].bNotContainByDirty = true;
665 continue;
666 }
667 if (r.Contains(hitPoint[i].hitPoint))
668 hitPoint[i].bNotNeedRepaint = true;
669 }
670 pChild =
671 pChild->GetOwnerApp()->GetWidgetMgr()->GetNextSiblingWidget(pChild);
672 } while (pChild);
673
674 if (!bChildIntersectWithDirty)
675 return true;
676 if (bOrginPtIntersectWidthDirty && !bOrginPtIntersectWidthChild)
677 return true;
678 if (rtChilds.IsEmpty())
679 return true;
680
681 int32_t repaintPoint = kNeedRepaintHitPoints;
682 for (int32_t i = 0; i < kNeedRepaintHitPoints; i++) {
683 if (hitPoint[i].bNotNeedRepaint)
684 repaintPoint--;
685 }
686 if (repaintPoint > 0)
687 return true;
688
689 pMatrix->TransformRect(rtChilds);
690 if (rtChilds.Contains(rtDirty) || rtChilds.Contains(rtWidget))
691 return false;
692 return true;
693 }
694
695 bool CFWL_WidgetMgr::UseOffscreenDirect(CFWL_Widget* pWidget) const {
696 Item* pItem = GetWidgetMgrItem(pWidget);
697 if (!FWL_UseOffscreen(pWidget) || !(pItem->pOffscreen))
698 return false;
699
700 #if (_FX_OS_ == _FX_WIN32_DESKTOP_) || (_FX_OS_ == _FX_WIN64_)
701 if (pItem->bOutsideChanged) {
702 CFX_RectF r = pWidget->GetWidgetRect();
703 CFX_RectF temp(m_rtScreen);
704 temp.Deflate(50, 50);
705 if (!temp.Contains(r))
706 return false;
707
708 pItem->bOutsideChanged = false;
709 }
710 #endif
711
712 return pItem->iRedrawCounter == 0;
713 }
714
715 CFWL_WidgetMgr::Item::Item() : CFWL_WidgetMgr::Item(nullptr) {}
716
717 CFWL_WidgetMgr::Item::Item(CFWL_Widget* widget)
718 : pParent(nullptr),
719 pOwner(nullptr),
720 pChild(nullptr),
721 pPrevious(nullptr),
722 pNext(nullptr),
723 pWidget(widget),
724 iRedrawCounter(0)
725 #if (_FX_OS_ == _FX_WIN32_DESKTOP_) || (_FX_OS_ == _FX_WIN64_)
726 ,
727 bOutsideChanged(false)
728 #endif
729 {
730 }
731
732 CFWL_WidgetMgr::Item::~Item() {}
OLDNEW
« no previous file with comments | « xfa/fwl/core/cfwl_widgetmgr.h ('k') | xfa/fwl/core/cfwl_widgetproperties.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698