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

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

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

Powered by Google App Engine
This is Rietveld 408576698