1 // Copyright 2014 PDFium Authors. All rights reserved.
\r
2 // Use of this source code is governed by a BSD-style license that can be
\r
3 // found in the LICENSE file.
\r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
\r
7 #include "../../../foxitlib.h"
\r
8 #include "include/fwl_targetimp.h"
\r
9 #include "include/fwl_noteimp.h"
\r
10 #include "include/fwl_widgetmgrimp.h"
\r
11 #include "include/fwl_threadimp.h"
\r
12 #include "include/fwl_appimp.h"
\r
13 #define FWL_NORMALMATRIX
\r
14 FX_BOOL FWL_UseOffscreen(IFWL_Widget * pWidget)
\r
16 #if (_FX_OS_==_FX_MACOSX_)
\r
19 return pWidget->GetStyles() & FWL_WGTSTYLE_Offscreen;
\r
22 IFWL_WidgetMgr* FWL_GetWidgetMgr()
\r
24 IFWL_App *pApp = FWL_GetApp();
\r
25 _FWL_RETURN_VALUE_IF_FAIL(pApp, NULL);
\r
26 return pApp->GetWidgetMgr();
\r
28 CFWL_WidgetMgr::CFWL_WidgetMgr(IFWL_AdapterNative *pAdapterNative)
\r
31 m_pDelegate = FX_NEW CFWL_WidgetMgrDelegate(this);
\r
32 m_pAdapter = pAdapterNative->GetWidgetMgr((IFWL_WidgetMgrDelegate*)m_pDelegate);
\r
33 FXSYS_assert(m_pAdapter);
\r
34 CFWL_WidgetMgrItem *pRoot = FX_NEW CFWL_WidgetMgrItem;
\r
35 m_mapWidgetItem.SetAt(NULL, pRoot);
\r
36 #if (_FX_OS_==_FX_WIN32_DESKTOP_) || (_FX_OS_==_FX_WIN64_)
\r
38 IFWL_AdapterMonitorMgr* pMonitorMgr = pAdapterNative->GetMonitorMgr();
\r
40 FWL_HMONITOR monitor = pMonitorMgr->GetCurrentMonitor();
\r
42 pMonitorMgr->GetMonitorSize(monitor, m_rtScreen.width, m_rtScreen.height);
\r
47 CFWL_WidgetMgr::~CFWL_WidgetMgr()
\r
49 FX_POSITION ps = m_mapWidgetItem.GetStartPosition();
\r
52 CFWL_WidgetMgrItem *pItem;
\r
53 m_mapWidgetItem.GetNextAssoc(ps, pWidget, (void*&)pItem);
\r
56 m_mapWidgetItem.RemoveAll();
\r
62 FX_INT32 CFWL_WidgetMgr::CountWidgets(IFWL_Widget *pParent )
\r
64 CFWL_WidgetMgrItem *pParentItem = GetWidgetMgrItem(pParent);
\r
65 return TravelWidgetMgr(pParentItem, NULL, NULL);
\r
67 IFWL_Widget* CFWL_WidgetMgr::GetWidget(FX_INT32 nIndex, IFWL_Widget *pParent )
\r
69 CFWL_WidgetMgrItem *pParentItem = GetWidgetMgrItem(pParent);
\r
70 IFWL_Widget *pWidget = NULL;
\r
71 TravelWidgetMgr(pParentItem, &nIndex, NULL, &pWidget);
\r
74 IFWL_Widget* CFWL_WidgetMgr::GetWidget(IFWL_Widget *pWidget, FWL_WGTRELATION eRelation)
\r
76 CFWL_WidgetMgrItem *pItem = GetWidgetMgrItem(pWidget);
\r
80 IFWL_Widget *pRet = NULL;
\r
81 switch (eRelation) {
\r
82 case FWL_WGTRELATION_Parent: {
\r
83 pRet = pItem->pParent ? pItem->pParent->pWidget : NULL;
\r
86 case FWL_WGTRELATION_Owner: {
\r
87 pRet = pItem->pOwner ? pItem->pOwner->pWidget : NULL;
\r
90 case FWL_WGTRELATION_FirstSibling: {
\r
91 pItem = pItem->pPrevious;
\r
92 while (pItem && pItem->pPrevious) {
\r
93 pItem = pItem->pPrevious;
\r
95 pRet = pItem ? pItem->pWidget : NULL;
\r
98 case FWL_WGTRELATION_PriorSibling: {
\r
99 pRet = pItem->pPrevious ? pItem->pPrevious->pWidget : NULL;
\r
102 case FWL_WGTRELATION_NextSibling: {
\r
103 pRet = pItem->pNext ? pItem->pNext->pWidget : NULL;
\r
106 case FWL_WGTRELATION_LastSibling: {
\r
107 pItem = pItem->pNext;
\r
108 while (pItem && pItem->pNext) {
\r
109 pItem = pItem->pNext;
\r
111 pRet = pItem ? pItem->pWidget : NULL;
\r
114 case FWL_WGTRELATION_FirstChild: {
\r
115 pRet = pItem->pChild ? pItem->pChild->pWidget : NULL;
\r
118 case FWL_WGTRELATION_LastChild: {
\r
119 pItem = pItem->pChild;
\r
120 while (pItem && pItem->pNext) {
\r
121 pItem = pItem->pNext;
\r
123 pRet = pItem ? pItem->pWidget : NULL;
\r
126 case FWL_WGTRELATION_SystemForm: {
\r
128 if (IsAbleNative(pItem->pWidget)) {
\r
129 pRet = pItem->pWidget;
\r
132 pItem = pItem->pParent;
\r
141 FX_INT32 CFWL_WidgetMgr::GetWidgetIndex(IFWL_Widget *pWidget)
\r
143 CFWL_WidgetMgrItem *pItem = GetWidgetMgrItem(pWidget);
\r
144 _FWL_RETURN_VALUE_IF_FAIL(pItem, -1);
\r
145 return TravelWidgetMgr(pItem->pParent, NULL, pItem);
\r
147 FX_BOOL CFWL_WidgetMgr::SetWidgetIndex(IFWL_Widget *pWidget, FX_INT32 nIndex)
\r
149 CFWL_WidgetMgrItem *pItem = GetWidgetMgrItem(pWidget);
\r
150 _FWL_RETURN_VALUE_IF_FAIL(pItem, FALSE);
\r
151 _FWL_RETURN_VALUE_IF_FAIL(pItem->pParent, FALSE);
\r
152 CFWL_WidgetMgrItem *pChild = pItem->pParent->pChild;
\r
155 if (pChild == pItem) {
\r
159 if (pChild->pPrevious) {
\r
160 pChild->pPrevious->pNext = pChild->pNext;
\r
162 if (pChild->pNext) {
\r
163 pChild->pNext->pPrevious = pChild->pPrevious;
\r
165 if (pItem->pParent->pChild == pItem) {
\r
166 pItem->pParent->pChild = pItem->pNext;
\r
168 pItem->pNext = NULL;
\r
169 pItem->pPrevious = NULL;
\r
172 if(!pChild->pNext) {
\r
175 pChild = pChild->pNext;
\r
178 pChild = pItem->pParent->pChild;
\r
181 while(pChild->pNext) {
\r
182 pChild = pChild->pNext;
\r
184 pChild->pNext = pItem;
\r
185 pItem->pPrevious = pChild;
\r
186 pItem->pNext = NULL;
\r
190 while(i < nIndex && pChild->pNext ) {
\r
191 pChild = pChild->pNext;
\r
194 if (!pChild->pNext) {
\r
195 pChild->pNext = pItem;
\r
196 pItem->pPrevious = pChild;
\r
197 pItem->pNext = NULL;
\r
200 if (pChild->pPrevious) {
\r
201 pItem->pPrevious = pChild->pPrevious;
\r
202 pChild->pPrevious->pNext = pItem;
\r
204 pChild->pPrevious = pItem;
\r
205 pItem->pNext = pChild;
\r
206 if (pItem->pParent->pChild == pChild) {
\r
207 pItem->pParent->pChild = pItem;
\r
210 pItem->pParent->pChild = pItem;
\r
211 pItem->pPrevious = NULL;
\r
212 pItem->pNext = NULL;
\r
216 FX_BOOL CFWL_WidgetMgr::IsWidget(FX_LPVOID pObj)
\r
218 _FWL_RETURN_VALUE_IF_FAIL(pObj, FALSE);
\r
219 return GetWidgetMgrItem((IFWL_Widget*)pObj) != NULL;
\r
221 FWL_ERR CFWL_WidgetMgr::RepaintWidget(IFWL_Widget *pWidget, const CFX_RectF *pRect )
\r
223 _FWL_RETURN_VALUE_IF_FAIL(m_pAdapter, FWL_ERR_Indefinite);
\r
224 IFWL_Widget *pNative = pWidget;
\r
225 CFX_RectF rect(*pRect);
\r
226 if (IsFormDisabled()) {
\r
227 IFWL_Widget *pOuter = pWidget->GetOuter();
\r
230 pNative->GetWidgetRect(rtTemp);
\r
231 rect.left += rtTemp.left;
\r
232 rect.top += rtTemp.top;
\r
234 pOuter = pOuter->GetOuter();
\r
236 } else if (!IsAbleNative(pWidget)) {
\r
237 pNative = GetWidget(pWidget, FWL_WGTRELATION_SystemForm);
\r
238 _FWL_RETURN_VALUE_IF_FAIL(pNative, FWL_ERR_Indefinite);
\r
239 pWidget->TransformTo(pNative, rect.left, rect.top);
\r
241 AddRedrawCounts(pNative);
\r
242 return m_pAdapter->RepaintWidget(pNative, &rect);
\r
244 void CFWL_WidgetMgr::AddWidget(IFWL_Widget *pWidget)
\r
246 CFWL_WidgetMgrItem *pParentItem = GetWidgetMgrItem(NULL);
\r
247 CFWL_WidgetMgrItem *pItem = GetWidgetMgrItem(pWidget);
\r
249 pItem = FX_NEW CFWL_WidgetMgrItem;
\r
250 pItem->pWidget = pWidget;
\r
251 m_mapWidgetItem.SetAt(pWidget, pItem);
\r
253 if (pItem->pParent && pItem->pParent != pParentItem) {
\r
254 if (pItem->pPrevious) {
\r
255 pItem->pPrevious->pNext = pItem->pNext;
\r
257 if (pItem->pNext) {
\r
258 pItem->pNext->pPrevious = pItem->pPrevious;
\r
260 if (pItem->pParent->pChild == pItem) {
\r
261 pItem->pParent->pChild = pItem->pNext;
\r
264 pItem->pParent = pParentItem;
\r
265 SetWidgetIndex(pWidget, -1);
\r
267 void CFWL_WidgetMgr::InsertWidget(IFWL_Widget *pParent, IFWL_Widget *pChild, FX_INT32 nIndex )
\r
269 CFWL_WidgetMgrItem *pParentItem = GetWidgetMgrItem(pParent);
\r
270 if (!pParentItem) {
\r
271 pParentItem = FX_NEW CFWL_WidgetMgrItem;
\r
272 pParentItem->pWidget = pParent;
\r
273 m_mapWidgetItem.SetAt(pParent, pParentItem);
\r
274 CFWL_WidgetMgrItem *pRoot = GetWidgetMgrItem(NULL);
\r
275 pParentItem->pParent = pRoot;
\r
276 SetWidgetIndex(pParent, -1);
\r
278 CFWL_WidgetMgrItem *pItem = GetWidgetMgrItem(pChild);
\r
280 pItem = FX_NEW CFWL_WidgetMgrItem;
\r
281 pItem->pWidget = pChild;
\r
282 m_mapWidgetItem.SetAt(pChild, pItem);
\r
284 if (pItem->pParent && pItem->pParent != pParentItem) {
\r
285 if (pItem->pPrevious) {
\r
286 pItem->pPrevious->pNext = pItem->pNext;
\r
288 if (pItem->pNext) {
\r
289 pItem->pNext->pPrevious = pItem->pPrevious;
\r
291 if (pItem->pParent->pChild == pItem) {
\r
292 pItem->pParent->pChild = pItem->pNext;
\r
295 pItem->pParent = pParentItem;
\r
296 SetWidgetIndex(pChild, nIndex);
\r
298 void CFWL_WidgetMgr::RemoveWidget(IFWL_Widget *pWidget)
\r
300 CFWL_WidgetMgrItem *pItem = GetWidgetMgrItem(pWidget);
\r
304 if (pItem->pPrevious) {
\r
305 pItem->pPrevious->pNext = pItem->pNext;
\r
307 if (pItem->pNext) {
\r
308 pItem->pNext->pPrevious = pItem->pPrevious;
\r
310 if (pItem->pParent && pItem->pParent->pChild == pItem) {
\r
311 pItem->pParent->pChild = pItem->pNext;
\r
313 CFWL_WidgetMgrItem *pChild = pItem->pChild;
\r
315 CFWL_WidgetMgrItem *pNext = pChild->pNext;
\r
316 RemoveWidget(pChild->pWidget);
\r
319 m_mapWidgetItem.RemoveKey(pWidget);
\r
322 void CFWL_WidgetMgr::SetOwner(IFWL_Widget *pOwner, IFWL_Widget *pOwned)
\r
324 CFWL_WidgetMgrItem *pParentItem = GetWidgetMgrItem(pOwner);
\r
325 if (!pParentItem) {
\r
326 pParentItem = FX_NEW CFWL_WidgetMgrItem;
\r
327 pParentItem->pWidget = pOwner;
\r
328 m_mapWidgetItem.SetAt(pOwner, pParentItem);
\r
329 CFWL_WidgetMgrItem *pRoot = GetWidgetMgrItem(NULL);
\r
330 pParentItem->pParent = pRoot;
\r
331 SetWidgetIndex(pOwner, -1);
\r
333 CFWL_WidgetMgrItem *pItem = GetWidgetMgrItem(pOwned);
\r
335 pItem = FX_NEW CFWL_WidgetMgrItem;
\r
336 pItem->pWidget = pOwned;
\r
337 m_mapWidgetItem.SetAt(pOwned, pItem);
\r
339 pItem->pOwner = pParentItem;
\r
341 void CFWL_WidgetMgr::SetParent(IFWL_Widget *pParent, IFWL_Widget *pChild)
\r
343 CFWL_WidgetMgrItem *pParentItem = GetWidgetMgrItem(pParent);
\r
344 CFWL_WidgetMgrItem *pItem = GetWidgetMgrItem(pChild);
\r
345 _FWL_RETURN_IF_FAIL(pItem);
\r
346 if (pItem->pParent && pItem->pParent != pParentItem) {
\r
347 if (pItem->pPrevious) {
\r
348 pItem->pPrevious->pNext = pItem->pNext;
\r
350 if (pItem->pNext) {
\r
351 pItem->pNext->pPrevious = pItem->pPrevious;
\r
353 if (pItem->pParent->pChild == pItem) {
\r
354 pItem->pParent->pChild = pItem->pNext;
\r
356 pItem->pNext = NULL;
\r
357 pItem->pPrevious = NULL;
\r
359 pItem->pParent = pParentItem;
\r
360 SetWidgetIndex(pChild, -1);
\r
361 _FWL_RETURN_IF_FAIL(m_pAdapter);
\r
362 m_pAdapter->SetParentWidget(pChild, pParent);
\r
364 FX_BOOL CFWL_WidgetMgr::IsChild(IFWL_Widget *pChild, IFWL_Widget *pParent)
\r
366 IFWL_Widget *pTemp = pChild;
\r
368 if (pTemp == pParent) {
\r
371 pTemp = GetWidget(pTemp, FWL_WGTRELATION_Parent);
\r
375 FWL_ERR CFWL_WidgetMgr::CreateWidget_Native(IFWL_Widget *pWidget)
\r
377 if (!IsAbleNative(pWidget)) {
\r
378 return FWL_ERR_Succeeded;
\r
380 return m_pAdapter->CreateWidget(pWidget, pWidget->GetOwner());
\r
382 FWL_ERR CFWL_WidgetMgr::DestroyWidget_Native(IFWL_Widget *pWidget)
\r
384 if (!IsAbleNative(pWidget)) {
\r
385 return FWL_ERR_Succeeded;
\r
387 return m_pAdapter->DestroyWidget(pWidget);
\r
389 FWL_ERR CFWL_WidgetMgr::GetWidgetRect_Native(IFWL_Widget *pWidget, CFX_RectF &rect)
\r
391 if (!IsAbleNative(pWidget)) {
\r
392 return FWL_ERR_Succeeded;
\r
394 return m_pAdapter->GetWidgetRect(pWidget, rect);
\r
396 FWL_ERR CFWL_WidgetMgr::SetWidgetRect_Native(IFWL_Widget *pWidget, const CFX_RectF &rect)
\r
398 if (FWL_UseOffscreen(pWidget)) {
\r
399 CFWL_WidgetMgrItem *pItem = GetWidgetMgrItem(pWidget);
\r
400 pItem->iRedrawCounter ++;
\r
401 if (pItem->pOffscreen) {
\r
402 CFX_RenderDevice *pDevice = pItem->pOffscreen->GetRenderDevice();
\r
403 if (pDevice && pDevice->GetBitmap()) {
\r
404 CFX_DIBitmap *pBitmap = pDevice->GetBitmap();
\r
405 if (pBitmap->GetWidth() - rect.width > 1 || pBitmap->GetHeight() - rect.height > 1) {
\r
406 delete pItem->pOffscreen;
\r
407 pItem->pOffscreen = NULL;
\r
411 #if (_FX_OS_==_FX_WIN32_DESKTOP_) || (_FX_OS_==_FX_WIN64_)
\r
412 pItem->bOutsideChanged = !m_rtScreen.Contains(rect);
\r
415 return m_pAdapter->SetWidgetRect(pWidget, rect);
\r
417 FWL_ERR CFWL_WidgetMgr::SetWidgetPosition_Native(IFWL_Widget *pWidget, FX_FLOAT fx, FX_FLOAT fy)
\r
419 return m_pAdapter->SetWidgetPosition(pWidget, fx, fy);
\r
421 FWL_ERR CFWL_WidgetMgr::SetWidgetIcon_Native(IFWL_Widget *pWidget, const CFX_DIBitmap *pIcon, FX_BOOL bBig)
\r
423 return m_pAdapter->SetWidgetIcon(pWidget, pIcon, bBig);
\r
425 FWL_ERR CFWL_WidgetMgr::SetWidgetCaption_Native(IFWL_Widget *pWidget, FX_WSTR wsCaption)
\r
427 return m_pAdapter->SetWidgetCaption(pWidget, wsCaption);
\r
429 FWL_ERR CFWL_WidgetMgr::SetBorderRegion_Native(IFWL_Widget *pWidget, CFX_Path *pPath)
\r
431 return m_pAdapter->SetBorderRegion(pWidget, pPath);
\r
433 FWL_ERR CFWL_WidgetMgr::ShowWidget_Native(IFWL_Widget *pWidget)
\r
435 return m_pAdapter->ShowWidget(pWidget);
\r
437 FWL_ERR CFWL_WidgetMgr::HideWidget_Native(IFWL_Widget *pWidget)
\r
439 return m_pAdapter->HideWidget(pWidget);
\r
441 FWL_ERR CFWL_WidgetMgr::SetNormal_Native(IFWL_Widget *pWidget)
\r
443 return m_pAdapter->SetNormal(pWidget);
\r
445 FWL_ERR CFWL_WidgetMgr::SetMaximize_Native(IFWL_Widget *pWidget)
\r
447 return m_pAdapter->SetMaximize(pWidget);
\r
449 FWL_ERR CFWL_WidgetMgr::SetMinimize_Native(IFWL_Widget *pWidget)
\r
451 return m_pAdapter->SetMinimize(pWidget);
\r
453 FX_BOOL CFWL_WidgetMgr::CheckMessage_Native()
\r
455 return m_pAdapter->CheckMessage();
\r
457 FWL_ERR CFWL_WidgetMgr::DispatchMessage_Native()
\r
459 return m_pAdapter->DispatchMessage();
\r
461 FX_BOOL CFWL_WidgetMgr::IsIdleMessage_Native()
\r
463 return m_pAdapter->IsIdleMessage();
\r
465 FWL_ERR CFWL_WidgetMgr::Exit_Native(FX_INT32 iExitCode)
\r
467 return m_pAdapter->Exit(iExitCode);
\r
469 FWL_ERR CFWL_WidgetMgr::CreateWidgetWithNativeId_Native(IFWL_Widget *pWidget, void *vp)
\r
471 return m_pAdapter->CreateWidgetWithNativeId(pWidget, vp);
\r
473 IFWL_Widget* CFWL_WidgetMgr::GetWidgetAtPoint(IFWL_Widget * parent, FX_FLOAT x, FX_FLOAT y)
\r
475 _FWL_RETURN_VALUE_IF_FAIL(parent, NULL);
\r
478 IFWL_Widget * child = GetWidget(parent, FWL_WGTRELATION_LastChild);
\r
480 if ((child->GetStates() & FWL_WGTSTATE_Invisible) == 0) {
\r
483 CFX_Matrix matrixOnParent;
\r
484 child->GetMatrix(matrixOnParent);
\r
487 m.SetReverse(matrixOnParent);
\r
488 m.TransformPoint(x1, y1);
\r
490 child->GetWidgetRect(bounds);
\r
491 if (bounds.Contains(x1, y1)) {
\r
494 return GetWidgetAtPoint(child, x1, y1);
\r
497 child = GetWidget(child, FWL_WGTRELATION_PriorSibling);
\r
501 void CFWL_WidgetMgr::NotifySizeChanged(IFWL_Widget *pForm, FX_FLOAT fx, FX_FLOAT fy)
\r
503 if (!FWL_UseOffscreen(pForm)) {
\r
506 CFWL_WidgetMgrItem *pItem = GetWidgetMgrItem(pForm);
\r
507 if (pItem->pOffscreen) {
\r
508 delete pItem->pOffscreen;
\r
509 pItem->pOffscreen = NULL;
\r
512 IFWL_Widget* CFWL_WidgetMgr::nextTab(IFWL_Widget *parent, IFWL_Widget *focus, FX_BOOL &bFind)
\r
514 IFWL_Widget *child = FWL_GetWidgetMgr()->GetWidget(parent, FWL_WGTRELATION_FirstChild);
\r
516 if (focus == child) {
\r
519 if ((child->GetStyles() & FWL_WGTSTYLE_TabStop) && (!focus || (focus != child && bFind))) {
\r
522 IFWL_Widget *bRet = nextTab(child, focus, bFind);
\r
526 child = FWL_GetWidgetMgr()->GetWidget(child, FWL_WGTRELATION_NextSibling);
\r
530 FX_INT32 CFWL_WidgetMgr::CountRadioButtonGroup(IFWL_Widget *pFirst)
\r
533 IFWL_Widget *pChild = pFirst;
\r
535 if ((pChild->GetStyles() & FWL_WGTSTYLE_Group) && pChild->GetClassID() == 3811304691) {
\r
538 pChild = GetWidget(pChild, FWL_WGTRELATION_NextSibling);
\r
542 IFWL_Widget* CFWL_WidgetMgr::GetSiblingRadioButton(IFWL_Widget *pWidget, FX_BOOL bNext)
\r
544 while ((pWidget = GetWidget(pWidget, bNext ? FWL_WGTRELATION_NextSibling : FWL_WGTRELATION_PriorSibling)) != NULL) {
\r
545 if (pWidget->GetClassID() == 3811304691) {
\r
551 IFWL_Widget* CFWL_WidgetMgr::GetRadioButtonGroupHeader(IFWL_Widget *pRadioButton)
\r
553 if (pRadioButton->GetStyles() & FWL_WGTSTYLE_Group) {
\r
554 return pRadioButton;
\r
556 IFWL_Widget *pNext = pRadioButton;
\r
557 while ((pNext = GetSiblingRadioButton(pNext, FALSE)) != NULL) {
\r
558 if (pNext->GetStyles() & FWL_WGTSTYLE_Group) {
\r
562 pNext = GetWidget(pRadioButton, FWL_WGTRELATION_LastSibling);
\r
563 if ((pNext->GetStyles() & FWL_WGTSTYLE_Group) && pNext->GetClassID() == 3811304691) {
\r
566 while ((pNext = GetSiblingRadioButton(pNext, FALSE)) && pNext && pNext != pRadioButton) {
\r
567 if (pNext->GetStyles() & FWL_WGTSTYLE_Group) {
\r
571 pNext = GetWidget(pRadioButton, FWL_WGTRELATION_FirstSibling);
\r
572 if (pNext && (pNext->GetStyles() == FWL_WGTSTYLE_Group) && pNext->GetClassID() == 3811304691) {
\r
575 return GetSiblingRadioButton(pNext, TRUE);
\r
577 void CFWL_WidgetMgr::GetSameGroupRadioButton(IFWL_Widget *pRadioButton, CFX_PtrArray &group)
\r
579 IFWL_Widget *pFirst = GetWidget(pRadioButton, FWL_WGTRELATION_FirstSibling);
\r
581 pFirst = pRadioButton;
\r
583 FX_INT32 iGroup = CountRadioButtonGroup(pFirst);
\r
585 if (pFirst->GetClassID() == 3811304691) {
\r
588 IFWL_Widget *pNext = pFirst;
\r
589 while ((pNext = GetSiblingRadioButton(pNext, TRUE)) != NULL) {
\r
594 IFWL_Widget *pNext = GetRadioButtonGroupHeader(pRadioButton);
\r
597 pNext = GetSiblingRadioButton(pNext, TRUE);
\r
599 if (pFirst->GetClassID() == 3811304691) {
\r
602 pNext = GetSiblingRadioButton(pFirst, TRUE);
\r
605 } while (pNext && ((pNext->GetStyles() & FWL_WGTSTYLE_Group) == 0));
\r
607 IFWL_Widget* CFWL_WidgetMgr::GetDefaultButton(IFWL_Widget *pParent)
\r
609 if ((pParent->GetClassID() == 3521614244) && (pParent->GetStates() & (1 << (FWL_WGTSTATE_MAX + 2)))) {
\r
612 IFWL_Widget *child = FWL_GetWidgetMgr()->GetWidget(pParent, FWL_WGTRELATION_FirstChild);
\r
614 if ((child->GetClassID() == 3521614244) && (child->GetStates() & (1 << (FWL_WGTSTATE_MAX + 2)))) {
\r
617 IFWL_Widget *find = GetDefaultButton(child);
\r
621 child = FWL_GetWidgetMgr()->GetWidget(child, FWL_WGTRELATION_NextSibling);
\r
625 void CFWL_WidgetMgr::AddRedrawCounts(IFWL_Widget *pWidget)
\r
627 CFWL_WidgetMgrItem *pItem = GetWidgetMgrItem(pWidget);
\r
628 (pItem->iRedrawCounter)++;
\r
630 void CFWL_WidgetMgr::ResetRedrawCounts(IFWL_Widget *pWidget)
\r
632 CFWL_WidgetMgrItem *pItem = GetWidgetMgrItem(pWidget);
\r
633 pItem->iRedrawCounter = 0;
\r
635 CFWL_WidgetMgrItem* CFWL_WidgetMgr::GetWidgetMgrItem(IFWL_Widget *pWidget)
\r
637 return (CFWL_WidgetMgrItem*)m_mapWidgetItem.GetValueAt(pWidget);
\r
639 FX_INT32 CFWL_WidgetMgr::TravelWidgetMgr(CFWL_WidgetMgrItem *pParent, FX_INT32 *pIndex, CFWL_WidgetMgrItem *pItem, IFWL_Widget **pWidget )
\r
644 FX_INT32 iCount = 0;
\r
645 CFWL_WidgetMgrItem *pChild = pParent->pChild;
\r
649 if (*pIndex == 0) {
\r
650 *pWidget = pChild->pWidget;
\r
655 if (pItem && pItem == pChild) {
\r
658 pChild = pChild->pNext;
\r
662 } else if (pItem) {
\r
667 FX_BOOL CFWL_WidgetMgr::IsAbleNative(IFWL_Widget *pWidget)
\r
669 _FWL_RETURN_VALUE_IF_FAIL(pWidget, FALSE);
\r
670 if (!pWidget->IsInstance(FX_WSTRC(FWL_CLASS_Form))) {
\r
673 FX_DWORD dwStyles = pWidget->GetStyles();
\r
674 return ((dwStyles & FWL_WGTSTYLE_WindowTypeMask) == FWL_WGTSTYLE_OverLapper) || (dwStyles & FWL_WGTSTYLE_Popup);
\r
676 FX_BOOL CFWL_WidgetMgr::IsThreadEnabled()
\r
678 return !(m_dwCapability & FWL_WGTMGR_DisableThread);
\r
680 FX_BOOL CFWL_WidgetMgr::IsFormDisabled()
\r
682 return m_dwCapability & FWL_WGTMGR_DisableForm;
\r
684 FX_BOOL CFWL_WidgetMgr::GetAdapterPopupPos(IFWL_Widget* pWidget, FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight, const CFX_RectF &rtAnchor, CFX_RectF &rtPopup)
\r
686 IFWL_AdapterWidgetMgr* pSDApapter = GetAdapterWidgetMgr();
\r
687 return pSDApapter->GetPopupPos(pWidget, fMinHeight, fMaxHeight, rtAnchor, rtPopup);
\r
689 CFWL_WidgetMgrDelegate::CFWL_WidgetMgrDelegate(CFWL_WidgetMgr *pWidgetMgr)
\r
690 : m_pWidgetMgr(pWidgetMgr)
\r
693 FWL_ERR CFWL_WidgetMgrDelegate::OnSetCapability(FX_DWORD dwCapability )
\r
695 m_pWidgetMgr->m_dwCapability = dwCapability;
\r
696 return FWL_ERR_Succeeded;
\r
698 FX_INT32 CFWL_WidgetMgrDelegate::OnProcessMessageToForm(CFWL_Message *pMessage)
\r
700 _FWL_RETURN_VALUE_IF_FAIL(pMessage, 0);
\r
701 _FWL_RETURN_VALUE_IF_FAIL(pMessage->m_pDstTarget, 0);
\r
702 IFWL_Widget *pDstWidget = (IFWL_Widget*)pMessage->m_pDstTarget;
\r
703 IFWL_NoteThread *pNoteThread = pDstWidget->GetOwnerThread();
\r
704 _FWL_RETURN_VALUE_IF_FAIL(pNoteThread, 0);
\r
705 CFWL_NoteDriver *pNoteDriver = (CFWL_NoteDriver*)pNoteThread->GetNoteDriver();
\r
706 _FWL_RETURN_VALUE_IF_FAIL(pNoteDriver, 0);
\r
707 if (m_pWidgetMgr->IsThreadEnabled()) {
\r
708 pMessage = (CFWL_Message*)pMessage->Clone();
\r
710 if (m_pWidgetMgr->IsFormDisabled()) {
\r
711 pNoteDriver->ProcessMessage(pMessage);
\r
713 pNoteDriver->QueueMessage(pMessage);
\r
715 #if (_FX_OS_==_FX_MACOSX_)
\r
716 CFWL_NoteLoop *pTopLoop = pNoteDriver->GetTopLoop();
\r
718 pNoteDriver->UnqueueMessage(pTopLoop);
\r
721 if (m_pWidgetMgr->IsThreadEnabled()) {
\r
722 pMessage->Release();
\r
724 return FWL_ERR_Succeeded;
\r
726 FWL_ERR CFWL_WidgetMgrDelegate::OnDrawWidget(IFWL_Widget * pWidget,
\r
727 CFX_Graphics * pGraphics,
\r
728 const CFX_Matrix * pMatrix )
\r
730 _FWL_RETURN_VALUE_IF_FAIL(pWidget, FWL_ERR_Indefinite);
\r
731 _FWL_RETURN_VALUE_IF_FAIL(pGraphics, FWL_ERR_Indefinite);
\r
732 CFX_Graphics *pTemp = DrawWidgetBefore(pWidget, pGraphics, pMatrix);
\r
733 CFX_RectF clipCopy;
\r
734 pWidget->GetWidgetRect(clipCopy);
\r
735 clipCopy.left = clipCopy.top = 0;
\r
736 if (bUseOffscreenDirect(pWidget)) {
\r
737 DrawWidgetAfter(pWidget, pGraphics, clipCopy, pMatrix);
\r
738 return FWL_ERR_Succeeded;
\r
740 CFX_RectF clipBounds;
\r
741 #if (_FX_OS_==_FX_WIN32_DESKTOP_) || (_FX_OS_==_FX_WIN64_) || (_FX_OS_ == _FX_LINUX_DESKTOP_) || (_FX_OS_ == _FX_ANDROID_)
\r
742 IFWL_WidgetDelegate *pDelegate = pWidget->SetDelegate(NULL);
\r
743 pDelegate->OnDrawWidget(pTemp, pMatrix);
\r
744 pGraphics->GetClipRect(clipBounds);
\r
745 clipCopy = clipBounds;
\r
746 #elif (_FX_OS_==_FX_MACOSX_)
\r
747 if (m_pWidgetMgr->IsFormDisabled()) {
\r
748 IFWL_WidgetDelegate *pDelegate = pWidget->SetDelegate(NULL);
\r
749 pDelegate->OnDrawWidget(pTemp, pMatrix);
\r
750 pGraphics->GetClipRect(clipBounds);
\r
751 clipCopy = clipBounds;
\r
753 clipBounds.Set(pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d);
\r
754 ((CFX_Matrix*)pMatrix)->Reset();
\r
755 #ifdef FWL_UseMacSystemBorder
\r
759 IFWL_WidgetDelegate *pDelegate = pWidget->SetDelegate(NULL);
\r
760 pDelegate->OnDrawWidget(pTemp, pMatrix);
\r
764 if (!m_pWidgetMgr->IsFormDisabled()) {
\r
765 CFX_RectF rtClient;
\r
766 pWidget->GetClientRect(rtClient);
\r
767 clipBounds.Intersect(rtClient);
\r
769 if (!clipBounds.IsEmpty()) {
\r
770 DrawChild(pWidget, clipBounds, pTemp, pMatrix);
\r
772 DrawWidgetAfter(pWidget, pGraphics, clipCopy, pMatrix);
\r
773 m_pWidgetMgr->ResetRedrawCounts(pWidget);
\r
774 return FWL_ERR_Succeeded;
\r
776 void CFWL_WidgetMgrDelegate::DrawChild(IFWL_Widget* parent,
\r
777 const CFX_RectF& rtClip,
\r
778 CFX_Graphics* pGraphics,
\r
779 const CFX_Matrix* pMatrix )
\r
781 _FWL_RETURN_IF_FAIL(parent);
\r
782 FX_BOOL bFormDisable = m_pWidgetMgr->IsFormDisabled();
\r
783 IFWL_Widget* pNextChild = m_pWidgetMgr->GetWidget(parent, FWL_WGTRELATION_FirstChild);
\r
784 while (pNextChild) {
\r
785 IFWL_Widget* child = pNextChild;
\r
786 pNextChild = m_pWidgetMgr->GetWidget(child, FWL_WGTRELATION_NextSibling);
\r
787 if (child->GetStates() & FWL_WGTSTATE_Invisible) {
\r
790 CFX_RectF rtWidget;
\r
791 child->GetWidgetRect(rtWidget);
\r
792 if (rtWidget.IsEmpty()) {
\r
795 CFX_Matrix widgetMatrix;
\r
796 CFX_RectF clipBounds(rtWidget);
\r
797 if(!bFormDisable) {
\r
798 child->GetMatrix(widgetMatrix, TRUE);
\r
801 widgetMatrix.Concat(*pMatrix);
\r
803 if (!bFormDisable) {
\r
804 widgetMatrix.TransformPoint(clipBounds.left, clipBounds.top);
\r
805 clipBounds.Intersect(rtClip);
\r
806 if (clipBounds.IsEmpty()) {
\r
809 pGraphics->SaveGraphState();
\r
810 pGraphics->SetClipRect(clipBounds);
\r
812 widgetMatrix.Translate(rtWidget.left, rtWidget.top, TRUE);
\r
813 IFWL_WidgetDelegate *pDelegate = child->SetDelegate(NULL);
\r
815 if (m_pWidgetMgr->IsFormDisabled() || IsNeedRepaint(child, &widgetMatrix, rtClip)) {
\r
816 pDelegate->OnDrawWidget(pGraphics, &widgetMatrix);
\r
819 if (!bFormDisable) {
\r
820 pGraphics->RestoreGraphState();
\r
822 DrawChild(child, clipBounds, pGraphics, bFormDisable ? &widgetMatrix : pMatrix);
\r
823 child = m_pWidgetMgr->GetWidget(child, FWL_WGTRELATION_NextSibling);
\r
826 CFX_Graphics* CFWL_WidgetMgrDelegate::DrawWidgetBefore(IFWL_Widget *pWidget, CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix)
\r
828 if (!FWL_UseOffscreen(pWidget)) {
\r
831 CFWL_WidgetMgrItem *pItem = m_pWidgetMgr->GetWidgetMgrItem(pWidget);
\r
832 if (!pItem->pOffscreen) {
\r
833 pItem->pOffscreen = FX_NEW CFX_Graphics;
\r
835 pWidget->GetWidgetRect(rect);
\r
836 pItem->pOffscreen->Create((FX_INT32)rect.width, (FX_INT32)rect.height, FXDIB_Argb);
\r
839 pGraphics->GetClipRect(rect);
\r
840 pItem->pOffscreen->SetClipRect(rect);
\r
841 return pItem->pOffscreen;
\r
843 void CFWL_WidgetMgrDelegate::DrawWidgetAfter(IFWL_Widget *pWidget, CFX_Graphics *pGraphics, CFX_RectF &rtClip, const CFX_Matrix *pMatrix)
\r
845 if (FWL_UseOffscreen(pWidget)) {
\r
846 CFWL_WidgetMgrItem *pItem = m_pWidgetMgr->GetWidgetMgrItem(pWidget);
\r
847 pGraphics->Transfer(pItem->pOffscreen, rtClip.left, rtClip.top, rtClip, (CFX_Matrix*)pMatrix);
\r
849 pItem->pOffscreen->ClearClip();
\r
852 CFWL_WidgetMgrItem *pItem = m_pWidgetMgr->GetWidgetMgrItem(pWidget);
\r
853 pItem->iRedrawCounter = 0;
\r
855 #define FWL_NEEDREPAINTHIT_Point 12
\r
856 #define FWL_NEEDREPAINTHIT_Piece 3
\r
857 typedef struct _FWL_NeedRepaintHitData {
\r
858 CFX_PointF hitPoint;
\r
859 FX_BOOL bNotNeedRepaint;
\r
860 FX_BOOL bNotContainByDirty;
\r
861 } FWL_NeedRepaintHitData;
\r
862 FX_BOOL CFWL_WidgetMgrDelegate::IsNeedRepaint(IFWL_Widget *pWidget, CFX_Matrix *pMatrix, const CFX_RectF &rtDirty)
\r
864 CFWL_WidgetMgrItem * pItem = m_pWidgetMgr->GetWidgetMgrItem(pWidget);
\r
865 if (pItem && pItem->iRedrawCounter > 0) {
\r
866 pItem->iRedrawCounter = 0;
\r
869 CFX_RectF rtWidget;
\r
870 pWidget->GetWidgetRect(rtWidget);
\r
871 rtWidget.left = rtWidget.top = 0;
\r
872 pMatrix->TransformRect(rtWidget);
\r
873 if (!rtWidget.IntersectWith(rtDirty)) {
\r
876 IFWL_Widget * pChild = FWL_GetWidgetMgr()->GetWidget(pWidget, FWL_WGTRELATION_FirstChild);
\r
880 if (pChild->GetClassID() == 3150298670) {
\r
882 pChild->GetWidgetRect(rtTemp);
\r
883 if (rtTemp.width >= rtWidget.width && rtTemp.height >= rtWidget.height) {
\r
884 pChild = FWL_GetWidgetMgr()->GetWidget(pChild, FWL_WGTRELATION_FirstChild);
\r
890 CFX_RectF rtChilds;
\r
892 FX_BOOL bChildIntersectWithDirty = FALSE;
\r
893 FX_BOOL bOrginPtIntersectWidthChild = FALSE;
\r
894 FX_BOOL bOrginPtIntersectWidthDirty = rtDirty.Contains(rtWidget.left, rtWidget.top);
\r
895 static FWL_NeedRepaintHitData hitPoint[FWL_NEEDREPAINTHIT_Point];
\r
896 static FX_INT32 iSize = sizeof(FWL_NeedRepaintHitData);
\r
897 FXSYS_memset(hitPoint, 0, iSize);
\r
898 FX_FLOAT fxPiece = rtWidget.width / FWL_NEEDREPAINTHIT_Piece;
\r
899 FX_FLOAT fyPiece = rtWidget.height / FWL_NEEDREPAINTHIT_Piece;
\r
900 hitPoint[2].hitPoint.x = hitPoint[6].hitPoint.x = rtWidget.left;
\r
901 hitPoint[0].hitPoint.x = hitPoint[3].hitPoint.x = hitPoint[7].hitPoint.x = hitPoint[10].hitPoint.x = fxPiece + rtWidget.left;
\r
902 hitPoint[1].hitPoint.x = hitPoint[4].hitPoint.x = hitPoint[8].hitPoint.x = hitPoint[11].hitPoint.x = fxPiece * 2 + rtWidget.left;
\r
903 hitPoint[5].hitPoint.x = hitPoint[9].hitPoint.x = rtWidget.width + rtWidget.left;
\r
904 hitPoint[0].hitPoint.y = hitPoint[1].hitPoint.y = rtWidget.top;
\r
905 hitPoint[2].hitPoint.y = hitPoint[3].hitPoint.y = hitPoint[4].hitPoint.y = hitPoint[5].hitPoint.y = fyPiece + rtWidget.top;
\r
906 hitPoint[6].hitPoint.y = hitPoint[7].hitPoint.y = hitPoint[8].hitPoint.y = hitPoint[9].hitPoint.y = fyPiece * 2 + rtWidget.top;
\r
907 hitPoint[10].hitPoint.y = hitPoint[11].hitPoint.y = rtWidget.height + rtWidget.top;
\r
910 pChild->GetWidgetRect(rect);
\r
911 CFX_RectF r = rect;
\r
912 r.left += rtWidget.left;
\r
913 r.top += rtWidget.top;
\r
917 if (r.Contains(rtDirty)) {
\r
920 if (!bChildIntersectWithDirty && r.IntersectWith(rtDirty)) {
\r
921 bChildIntersectWithDirty = TRUE;
\r
923 if (bOrginPtIntersectWidthDirty && !bOrginPtIntersectWidthChild) {
\r
924 bOrginPtIntersectWidthChild = rect.Contains(0, 0);
\r
926 if (rtChilds.IsEmpty()) {
\r
928 } else if (!(pChild->GetStates() & FWL_WGTSTATE_Invisible)) {
\r
929 rtChilds.Union(rect);
\r
931 for (FX_INT32 i = 0; i < FWL_NEEDREPAINTHIT_Point; i ++) {
\r
932 if (hitPoint[i].bNotContainByDirty || hitPoint[i].bNotNeedRepaint) {
\r
935 if (!rtDirty.Contains(hitPoint[i].hitPoint)) {
\r
936 hitPoint[i].bNotContainByDirty = TRUE;
\r
939 if (r.Contains(hitPoint[i].hitPoint)) {
\r
940 hitPoint[i].bNotNeedRepaint = TRUE;
\r
943 } while ((pChild = FWL_GetWidgetMgr()->GetWidget(pChild, FWL_WGTRELATION_NextSibling)) != NULL);
\r
944 if (!bChildIntersectWithDirty) {
\r
947 if (bOrginPtIntersectWidthDirty && !bOrginPtIntersectWidthChild) {
\r
950 if (rtChilds.IsEmpty()) {
\r
953 FX_INT32 repaintPoint = FWL_NEEDREPAINTHIT_Point;
\r
954 for (FX_INT32 i = 0; i < FWL_NEEDREPAINTHIT_Point; i ++) {
\r
955 if (hitPoint[i].bNotNeedRepaint) {
\r
959 if (repaintPoint > 0) {
\r
962 pMatrix->TransformRect(rtChilds);
\r
963 if (rtChilds.Contains(rtDirty) || rtChilds.Contains(rtWidget)) {
\r
968 FX_BOOL CFWL_WidgetMgrDelegate::bUseOffscreenDirect(IFWL_Widget *pWidget)
\r
970 CFWL_WidgetMgrItem *pItem = m_pWidgetMgr->GetWidgetMgrItem(pWidget);
\r
971 if (!FWL_UseOffscreen(pWidget) || !(pItem->pOffscreen)) {
\r
974 #if (_FX_OS_==_FX_WIN32_DESKTOP_) || (_FX_OS_==_FX_WIN64_)
\r
975 if (pItem->bOutsideChanged) {
\r
977 pWidget->GetWidgetRect(r);
\r
978 CFX_RectF temp(m_pWidgetMgr->m_rtScreen);
\r
979 temp.Deflate(50, 50);
\r
980 if (!temp.Contains(r)) {
\r
983 pItem->bOutsideChanged = FALSE;
\r
986 return pItem->iRedrawCounter == 0;
\r
988 static void FWL_WriteBMP(CFX_DIBitmap* pBitmap, FX_LPCSTR filename)
\r
990 FILE* file = fopen(filename, "wb");
\r
991 if (file == NULL) {
\r
994 int size = 14 + 40 + pBitmap->GetPitch() * pBitmap->GetHeight();
\r
995 unsigned char buffer[40];
\r
998 buffer[2] = (unsigned char)size;
\r
999 buffer[3] = (unsigned char)(size >> 8);
\r
1000 buffer[4] = (unsigned char)(size >> 16);
\r
1001 buffer[5] = (unsigned char)(size >> 24);
\r
1002 buffer[6] = buffer[7] = buffer[8] = buffer[9] = 0;
\r
1004 buffer[11] = buffer[12] = buffer[13] = 0;
\r
1005 fwrite(buffer, 14, 1, file);
\r
1006 memset(buffer, 0, 40);
\r
1008 buffer[4] = (unsigned char)pBitmap->GetWidth();
\r
1009 buffer[5] = (unsigned char)(pBitmap->GetWidth() >> 8);
\r
1010 buffer[6] = (unsigned char)(pBitmap->GetWidth() >> 16);
\r
1011 buffer[7] = (unsigned char)(pBitmap->GetWidth() >> 24);
\r
1012 buffer[8] = (unsigned char)(-pBitmap->GetHeight());
\r
1013 buffer[9] = (unsigned char)((-pBitmap->GetHeight()) >> 8);
\r
1014 buffer[10] = (unsigned char)((-pBitmap->GetHeight()) >> 16);
\r
1015 buffer[11] = (unsigned char)((-pBitmap->GetHeight()) >> 24);
\r
1017 buffer[14] = pBitmap->GetBPP();
\r
1018 fwrite(buffer, 40, 1, file);
\r
1019 for (int row = 0; row < pBitmap->GetHeight(); row ++) {
\r
1020 FX_LPBYTE scan_line = pBitmap->GetBuffer() + row * pBitmap->GetPitch();
\r
1021 fwrite(scan_line, pBitmap->GetPitch(), 1, file);
\r
1025 FWL_ERR FWL_WidgetMgrSnapshot(IFWL_Widget *pWidget, const CFX_WideString *saveFile, const CFX_Matrix *pMatrix)
\r
1028 pWidget->GetWidgetRect(r);
\r
1030 gs.Create((FX_INT32)r.width, (FX_INT32)r.height, FXDIB_Argb);
\r
1031 CFWL_WidgetMgr *widgetMgr = (CFWL_WidgetMgr*)FWL_GetWidgetMgr();
\r
1032 CFWL_WidgetMgrDelegate *delegate = widgetMgr->GetDelegate();
\r
1033 delegate->OnDrawWidget(pWidget, &gs, pMatrix);
\r
1034 CFX_DIBitmap *dib = gs.GetRenderDevice()->GetBitmap();
\r
1035 FWL_WriteBMP(dib, saveFile->UTF8Encode());
\r
1036 return FWL_ERR_Succeeded;
\r
1038 FX_BOOL FWL_WidgetIsChild(IFWL_Widget *parent, IFWL_Widget *find)
\r
1043 IFWL_Widget *child = FWL_GetWidgetMgr()->GetWidget(parent, FWL_WGTRELATION_FirstChild);
\r
1045 if (child == find) {
\r
1048 if (FWL_WidgetIsChild(child, find)) {
\r
1051 child = FWL_GetWidgetMgr()->GetWidget(child, FWL_WGTRELATION_NextSibling);
\r