| OLD | NEW |
| (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/src/fwl/core/fwl_widgetmgrimp.h" | |
| 8 | |
| 9 #include "xfa/include/fwl/adapter/fwl_adapternative.h" | |
| 10 #include "xfa/include/fwl/adapter/fwl_adapterwidgetmgr.h" | |
| 11 #include "xfa/include/fwl/core/fwl_app.h" | |
| 12 #include "xfa/include/fwl/core/fwl_form.h" | |
| 13 #include "xfa/src/fwl/core/fwl_appimp.h" | |
| 14 #include "xfa/src/fwl/core/fwl_noteimp.h" | |
| 15 #include "xfa/src/fwl/core/fwl_targetimp.h" | |
| 16 #include "xfa/src/fwl/core/fwl_threadimp.h" | |
| 17 #include "xfa/src/fwl/core/fwl_widgetimp.h" | |
| 18 | |
| 19 FX_BOOL FWL_UseOffscreen(IFWL_Widget* pWidget) { | |
| 20 #if (_FX_OS_ == _FX_MACOSX_) | |
| 21 return FALSE; | |
| 22 #else | |
| 23 return pWidget->GetStyles() & FWL_WGTSTYLE_Offscreen; | |
| 24 #endif | |
| 25 } | |
| 26 IFWL_WidgetMgr* FWL_GetWidgetMgr() { | |
| 27 IFWL_App* pApp = FWL_GetApp(); | |
| 28 if (!pApp) | |
| 29 return NULL; | |
| 30 return pApp->GetWidgetMgr(); | |
| 31 } | |
| 32 CFWL_WidgetMgr::CFWL_WidgetMgr(IFWL_AdapterNative* pAdapterNative) | |
| 33 : m_dwCapability(0) { | |
| 34 m_pDelegate = new CFWL_WidgetMgrDelegate(this); | |
| 35 m_pAdapter = pAdapterNative->GetWidgetMgr(m_pDelegate); | |
| 36 FXSYS_assert(m_pAdapter); | |
| 37 CFWL_WidgetMgrItem* pRoot = new CFWL_WidgetMgrItem; | |
| 38 m_mapWidgetItem.SetAt(NULL, pRoot); | |
| 39 #if (_FX_OS_ == _FX_WIN32_DESKTOP_) || (_FX_OS_ == _FX_WIN64_) | |
| 40 m_rtScreen.Reset(); | |
| 41 #endif | |
| 42 } | |
| 43 CFWL_WidgetMgr::~CFWL_WidgetMgr() { | |
| 44 FX_POSITION ps = m_mapWidgetItem.GetStartPosition(); | |
| 45 while (ps) { | |
| 46 void* pWidget; | |
| 47 CFWL_WidgetMgrItem* pItem; | |
| 48 m_mapWidgetItem.GetNextAssoc(ps, pWidget, (void*&)pItem); | |
| 49 delete pItem; | |
| 50 } | |
| 51 m_mapWidgetItem.RemoveAll(); | |
| 52 if (m_pDelegate) { | |
| 53 delete m_pDelegate; | |
| 54 m_pDelegate = NULL; | |
| 55 } | |
| 56 } | |
| 57 int32_t CFWL_WidgetMgr::CountWidgets(IFWL_Widget* pParent) { | |
| 58 CFWL_WidgetMgrItem* pParentItem = GetWidgetMgrItem(pParent); | |
| 59 return TravelWidgetMgr(pParentItem, NULL, NULL); | |
| 60 } | |
| 61 IFWL_Widget* CFWL_WidgetMgr::GetWidget(int32_t nIndex, IFWL_Widget* pParent) { | |
| 62 CFWL_WidgetMgrItem* pParentItem = GetWidgetMgrItem(pParent); | |
| 63 IFWL_Widget* pWidget = NULL; | |
| 64 TravelWidgetMgr(pParentItem, &nIndex, NULL, &pWidget); | |
| 65 return pWidget; | |
| 66 } | |
| 67 IFWL_Widget* CFWL_WidgetMgr::GetWidget(IFWL_Widget* pWidget, | |
| 68 FWL_WGTRELATION eRelation) { | |
| 69 CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget); | |
| 70 if (!pItem) { | |
| 71 return NULL; | |
| 72 } | |
| 73 IFWL_Widget* pRet = NULL; | |
| 74 switch (eRelation) { | |
| 75 case FWL_WGTRELATION_Parent: { | |
| 76 pRet = pItem->pParent ? pItem->pParent->pWidget : NULL; | |
| 77 break; | |
| 78 } | |
| 79 case FWL_WGTRELATION_Owner: { | |
| 80 pRet = pItem->pOwner ? pItem->pOwner->pWidget : NULL; | |
| 81 break; | |
| 82 } | |
| 83 case FWL_WGTRELATION_FirstSibling: { | |
| 84 pItem = pItem->pPrevious; | |
| 85 while (pItem && pItem->pPrevious) { | |
| 86 pItem = pItem->pPrevious; | |
| 87 } | |
| 88 pRet = pItem ? pItem->pWidget : NULL; | |
| 89 break; | |
| 90 } | |
| 91 case FWL_WGTRELATION_PriorSibling: { | |
| 92 pRet = pItem->pPrevious ? pItem->pPrevious->pWidget : NULL; | |
| 93 break; | |
| 94 } | |
| 95 case FWL_WGTRELATION_NextSibling: { | |
| 96 pRet = pItem->pNext ? pItem->pNext->pWidget : NULL; | |
| 97 break; | |
| 98 } | |
| 99 case FWL_WGTRELATION_LastSibling: { | |
| 100 pItem = pItem->pNext; | |
| 101 while (pItem && pItem->pNext) { | |
| 102 pItem = pItem->pNext; | |
| 103 } | |
| 104 pRet = pItem ? pItem->pWidget : NULL; | |
| 105 break; | |
| 106 } | |
| 107 case FWL_WGTRELATION_FirstChild: { | |
| 108 pRet = pItem->pChild ? pItem->pChild->pWidget : NULL; | |
| 109 break; | |
| 110 } | |
| 111 case FWL_WGTRELATION_LastChild: { | |
| 112 pItem = pItem->pChild; | |
| 113 while (pItem && pItem->pNext) { | |
| 114 pItem = pItem->pNext; | |
| 115 } | |
| 116 pRet = pItem ? pItem->pWidget : NULL; | |
| 117 break; | |
| 118 } | |
| 119 case FWL_WGTRELATION_SystemForm: { | |
| 120 while (pItem) { | |
| 121 if (IsAbleNative(pItem->pWidget)) { | |
| 122 pRet = pItem->pWidget; | |
| 123 break; | |
| 124 } | |
| 125 pItem = pItem->pParent; | |
| 126 } | |
| 127 break; | |
| 128 } | |
| 129 default: {} | |
| 130 } | |
| 131 return pRet; | |
| 132 } | |
| 133 int32_t CFWL_WidgetMgr::GetWidgetIndex(IFWL_Widget* pWidget) { | |
| 134 CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget); | |
| 135 if (!pItem) | |
| 136 return -1; | |
| 137 return TravelWidgetMgr(pItem->pParent, NULL, pItem); | |
| 138 } | |
| 139 FX_BOOL CFWL_WidgetMgr::SetWidgetIndex(IFWL_Widget* pWidget, int32_t nIndex) { | |
| 140 CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget); | |
| 141 if (!pItem) | |
| 142 return FALSE; | |
| 143 if (!pItem->pParent) | |
| 144 return FALSE; | |
| 145 CFWL_WidgetMgrItem* pChild = pItem->pParent->pChild; | |
| 146 int32_t i = 0; | |
| 147 while (pChild) { | |
| 148 if (pChild == pItem) { | |
| 149 if (i == nIndex) { | |
| 150 return TRUE; | |
| 151 } | |
| 152 if (pChild->pPrevious) { | |
| 153 pChild->pPrevious->pNext = pChild->pNext; | |
| 154 } | |
| 155 if (pChild->pNext) { | |
| 156 pChild->pNext->pPrevious = pChild->pPrevious; | |
| 157 } | |
| 158 if (pItem->pParent->pChild == pItem) { | |
| 159 pItem->pParent->pChild = pItem->pNext; | |
| 160 } | |
| 161 pItem->pNext = NULL; | |
| 162 pItem->pPrevious = NULL; | |
| 163 break; | |
| 164 } | |
| 165 if (!pChild->pNext) { | |
| 166 break; | |
| 167 } | |
| 168 pChild = pChild->pNext; | |
| 169 ++i; | |
| 170 } | |
| 171 pChild = pItem->pParent->pChild; | |
| 172 if (pChild) { | |
| 173 if (nIndex < 0) { | |
| 174 while (pChild->pNext) { | |
| 175 pChild = pChild->pNext; | |
| 176 } | |
| 177 pChild->pNext = pItem; | |
| 178 pItem->pPrevious = pChild; | |
| 179 pItem->pNext = NULL; | |
| 180 return TRUE; | |
| 181 } | |
| 182 i = 0; | |
| 183 while (i < nIndex && pChild->pNext) { | |
| 184 pChild = pChild->pNext; | |
| 185 ++i; | |
| 186 } | |
| 187 if (!pChild->pNext) { | |
| 188 pChild->pNext = pItem; | |
| 189 pItem->pPrevious = pChild; | |
| 190 pItem->pNext = NULL; | |
| 191 return TRUE; | |
| 192 } | |
| 193 if (pChild->pPrevious) { | |
| 194 pItem->pPrevious = pChild->pPrevious; | |
| 195 pChild->pPrevious->pNext = pItem; | |
| 196 } | |
| 197 pChild->pPrevious = pItem; | |
| 198 pItem->pNext = pChild; | |
| 199 if (pItem->pParent->pChild == pChild) { | |
| 200 pItem->pParent->pChild = pItem; | |
| 201 } | |
| 202 } else { | |
| 203 pItem->pParent->pChild = pItem; | |
| 204 pItem->pPrevious = NULL; | |
| 205 pItem->pNext = NULL; | |
| 206 } | |
| 207 return TRUE; | |
| 208 } | |
| 209 FWL_ERR CFWL_WidgetMgr::RepaintWidget(IFWL_Widget* pWidget, | |
| 210 const CFX_RectF* pRect) { | |
| 211 if (!m_pAdapter) | |
| 212 return FWL_ERR_Indefinite; | |
| 213 IFWL_Widget* pNative = pWidget; | |
| 214 CFX_RectF rect(*pRect); | |
| 215 if (IsFormDisabled()) { | |
| 216 IFWL_Widget* pOuter = pWidget->GetOuter(); | |
| 217 while (pOuter) { | |
| 218 CFX_RectF rtTemp; | |
| 219 pNative->GetWidgetRect(rtTemp); | |
| 220 rect.left += rtTemp.left; | |
| 221 rect.top += rtTemp.top; | |
| 222 pNative = pOuter; | |
| 223 pOuter = pOuter->GetOuter(); | |
| 224 } | |
| 225 } else if (!IsAbleNative(pWidget)) { | |
| 226 pNative = GetWidget(pWidget, FWL_WGTRELATION_SystemForm); | |
| 227 if (!pNative) | |
| 228 return FWL_ERR_Indefinite; | |
| 229 pWidget->TransformTo(pNative, rect.left, rect.top); | |
| 230 } | |
| 231 AddRedrawCounts(pNative); | |
| 232 return m_pAdapter->RepaintWidget(pNative, &rect); | |
| 233 } | |
| 234 void CFWL_WidgetMgr::AddWidget(IFWL_Widget* pWidget) { | |
| 235 CFWL_WidgetMgrItem* pParentItem = GetWidgetMgrItem(NULL); | |
| 236 CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget); | |
| 237 if (!pItem) { | |
| 238 pItem = new CFWL_WidgetMgrItem; | |
| 239 pItem->pWidget = pWidget; | |
| 240 m_mapWidgetItem.SetAt(pWidget, pItem); | |
| 241 } | |
| 242 if (pItem->pParent && pItem->pParent != pParentItem) { | |
| 243 if (pItem->pPrevious) { | |
| 244 pItem->pPrevious->pNext = pItem->pNext; | |
| 245 } | |
| 246 if (pItem->pNext) { | |
| 247 pItem->pNext->pPrevious = pItem->pPrevious; | |
| 248 } | |
| 249 if (pItem->pParent->pChild == pItem) { | |
| 250 pItem->pParent->pChild = pItem->pNext; | |
| 251 } | |
| 252 } | |
| 253 pItem->pParent = pParentItem; | |
| 254 SetWidgetIndex(pWidget, -1); | |
| 255 } | |
| 256 void CFWL_WidgetMgr::InsertWidget(IFWL_Widget* pParent, | |
| 257 IFWL_Widget* pChild, | |
| 258 int32_t nIndex) { | |
| 259 CFWL_WidgetMgrItem* pParentItem = GetWidgetMgrItem(pParent); | |
| 260 if (!pParentItem) { | |
| 261 pParentItem = new CFWL_WidgetMgrItem; | |
| 262 pParentItem->pWidget = pParent; | |
| 263 m_mapWidgetItem.SetAt(pParent, pParentItem); | |
| 264 CFWL_WidgetMgrItem* pRoot = GetWidgetMgrItem(NULL); | |
| 265 pParentItem->pParent = pRoot; | |
| 266 SetWidgetIndex(pParent, -1); | |
| 267 } | |
| 268 CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pChild); | |
| 269 if (!pItem) { | |
| 270 pItem = new CFWL_WidgetMgrItem; | |
| 271 pItem->pWidget = pChild; | |
| 272 m_mapWidgetItem.SetAt(pChild, pItem); | |
| 273 } | |
| 274 if (pItem->pParent && pItem->pParent != pParentItem) { | |
| 275 if (pItem->pPrevious) { | |
| 276 pItem->pPrevious->pNext = pItem->pNext; | |
| 277 } | |
| 278 if (pItem->pNext) { | |
| 279 pItem->pNext->pPrevious = pItem->pPrevious; | |
| 280 } | |
| 281 if (pItem->pParent->pChild == pItem) { | |
| 282 pItem->pParent->pChild = pItem->pNext; | |
| 283 } | |
| 284 } | |
| 285 pItem->pParent = pParentItem; | |
| 286 SetWidgetIndex(pChild, nIndex); | |
| 287 } | |
| 288 void CFWL_WidgetMgr::RemoveWidget(IFWL_Widget* pWidget) { | |
| 289 CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget); | |
| 290 if (!pItem) { | |
| 291 return; | |
| 292 } | |
| 293 if (pItem->pPrevious) { | |
| 294 pItem->pPrevious->pNext = pItem->pNext; | |
| 295 } | |
| 296 if (pItem->pNext) { | |
| 297 pItem->pNext->pPrevious = pItem->pPrevious; | |
| 298 } | |
| 299 if (pItem->pParent && pItem->pParent->pChild == pItem) { | |
| 300 pItem->pParent->pChild = pItem->pNext; | |
| 301 } | |
| 302 CFWL_WidgetMgrItem* pChild = pItem->pChild; | |
| 303 while (pChild) { | |
| 304 CFWL_WidgetMgrItem* pNext = pChild->pNext; | |
| 305 RemoveWidget(pChild->pWidget); | |
| 306 pChild = pNext; | |
| 307 } | |
| 308 m_mapWidgetItem.RemoveKey(pWidget); | |
| 309 delete pItem; | |
| 310 } | |
| 311 void CFWL_WidgetMgr::SetOwner(IFWL_Widget* pOwner, IFWL_Widget* pOwned) { | |
| 312 CFWL_WidgetMgrItem* pParentItem = GetWidgetMgrItem(pOwner); | |
| 313 if (!pParentItem) { | |
| 314 pParentItem = new CFWL_WidgetMgrItem; | |
| 315 pParentItem->pWidget = pOwner; | |
| 316 m_mapWidgetItem.SetAt(pOwner, pParentItem); | |
| 317 CFWL_WidgetMgrItem* pRoot = GetWidgetMgrItem(NULL); | |
| 318 pParentItem->pParent = pRoot; | |
| 319 SetWidgetIndex(pOwner, -1); | |
| 320 } | |
| 321 CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pOwned); | |
| 322 if (!pItem) { | |
| 323 pItem = new CFWL_WidgetMgrItem; | |
| 324 pItem->pWidget = pOwned; | |
| 325 m_mapWidgetItem.SetAt(pOwned, pItem); | |
| 326 } | |
| 327 pItem->pOwner = pParentItem; | |
| 328 } | |
| 329 void CFWL_WidgetMgr::SetParent(IFWL_Widget* pParent, IFWL_Widget* pChild) { | |
| 330 CFWL_WidgetMgrItem* pParentItem = GetWidgetMgrItem(pParent); | |
| 331 CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pChild); | |
| 332 if (!pItem) | |
| 333 return; | |
| 334 if (pItem->pParent && pItem->pParent != pParentItem) { | |
| 335 if (pItem->pPrevious) { | |
| 336 pItem->pPrevious->pNext = pItem->pNext; | |
| 337 } | |
| 338 if (pItem->pNext) { | |
| 339 pItem->pNext->pPrevious = pItem->pPrevious; | |
| 340 } | |
| 341 if (pItem->pParent->pChild == pItem) { | |
| 342 pItem->pParent->pChild = pItem->pNext; | |
| 343 } | |
| 344 pItem->pNext = NULL; | |
| 345 pItem->pPrevious = NULL; | |
| 346 } | |
| 347 pItem->pParent = pParentItem; | |
| 348 SetWidgetIndex(pChild, -1); | |
| 349 if (!m_pAdapter) | |
| 350 return; | |
| 351 m_pAdapter->SetParentWidget(pChild, pParent); | |
| 352 } | |
| 353 FX_BOOL CFWL_WidgetMgr::IsChild(IFWL_Widget* pChild, IFWL_Widget* pParent) { | |
| 354 IFWL_Widget* pTemp = pChild; | |
| 355 do { | |
| 356 if (pTemp == pParent) { | |
| 357 return TRUE; | |
| 358 } | |
| 359 pTemp = GetWidget(pTemp, FWL_WGTRELATION_Parent); | |
| 360 } while (pTemp); | |
| 361 return FALSE; | |
| 362 } | |
| 363 FWL_ERR CFWL_WidgetMgr::CreateWidget_Native(IFWL_Widget* pWidget) { | |
| 364 if (!IsAbleNative(pWidget)) { | |
| 365 return FWL_ERR_Succeeded; | |
| 366 } | |
| 367 return m_pAdapter->CreateWidget(pWidget, pWidget->GetOwner()); | |
| 368 } | |
| 369 FWL_ERR CFWL_WidgetMgr::DestroyWidget_Native(IFWL_Widget* pWidget) { | |
| 370 if (!IsAbleNative(pWidget)) { | |
| 371 return FWL_ERR_Succeeded; | |
| 372 } | |
| 373 return m_pAdapter->DestroyWidget(pWidget); | |
| 374 } | |
| 375 FWL_ERR CFWL_WidgetMgr::GetWidgetRect_Native(IFWL_Widget* pWidget, | |
| 376 CFX_RectF& rect) { | |
| 377 if (!IsAbleNative(pWidget)) { | |
| 378 return FWL_ERR_Succeeded; | |
| 379 } | |
| 380 return m_pAdapter->GetWidgetRect(pWidget, rect); | |
| 381 } | |
| 382 FWL_ERR CFWL_WidgetMgr::SetWidgetRect_Native(IFWL_Widget* pWidget, | |
| 383 const CFX_RectF& rect) { | |
| 384 if (FWL_UseOffscreen(pWidget)) { | |
| 385 CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget); | |
| 386 pItem->iRedrawCounter++; | |
| 387 if (pItem->pOffscreen) { | |
| 388 CFX_RenderDevice* pDevice = pItem->pOffscreen->GetRenderDevice(); | |
| 389 if (pDevice && pDevice->GetBitmap()) { | |
| 390 CFX_DIBitmap* pBitmap = pDevice->GetBitmap(); | |
| 391 if (pBitmap->GetWidth() - rect.width > 1 || | |
| 392 pBitmap->GetHeight() - rect.height > 1) { | |
| 393 delete pItem->pOffscreen; | |
| 394 pItem->pOffscreen = NULL; | |
| 395 } | |
| 396 } | |
| 397 } | |
| 398 #if (_FX_OS_ == _FX_WIN32_DESKTOP_) || (_FX_OS_ == _FX_WIN64_) | |
| 399 pItem->bOutsideChanged = !m_rtScreen.Contains(rect); | |
| 400 #endif | |
| 401 } | |
| 402 return m_pAdapter->SetWidgetRect(pWidget, rect); | |
| 403 } | |
| 404 FWL_ERR CFWL_WidgetMgr::SetWidgetPosition_Native(IFWL_Widget* pWidget, | |
| 405 FX_FLOAT fx, | |
| 406 FX_FLOAT fy) { | |
| 407 return m_pAdapter->SetWidgetPosition(pWidget, fx, fy); | |
| 408 } | |
| 409 FWL_ERR CFWL_WidgetMgr::SetWidgetIcon_Native(IFWL_Widget* pWidget, | |
| 410 const CFX_DIBitmap* pIcon, | |
| 411 FX_BOOL bBig) { | |
| 412 return m_pAdapter->SetWidgetIcon(pWidget, pIcon, bBig); | |
| 413 } | |
| 414 FWL_ERR CFWL_WidgetMgr::SetWidgetCaption_Native( | |
| 415 IFWL_Widget* pWidget, | |
| 416 const CFX_WideStringC& wsCaption) { | |
| 417 return m_pAdapter->SetWidgetCaption(pWidget, wsCaption); | |
| 418 } | |
| 419 FWL_ERR CFWL_WidgetMgr::SetBorderRegion_Native(IFWL_Widget* pWidget, | |
| 420 CFX_Path* pPath) { | |
| 421 return m_pAdapter->SetBorderRegion(pWidget, pPath); | |
| 422 } | |
| 423 FWL_ERR CFWL_WidgetMgr::ShowWidget_Native(IFWL_Widget* pWidget) { | |
| 424 return m_pAdapter->ShowWidget(pWidget); | |
| 425 } | |
| 426 FWL_ERR CFWL_WidgetMgr::HideWidget_Native(IFWL_Widget* pWidget) { | |
| 427 return m_pAdapter->HideWidget(pWidget); | |
| 428 } | |
| 429 FWL_ERR CFWL_WidgetMgr::SetNormal_Native(IFWL_Widget* pWidget) { | |
| 430 return m_pAdapter->SetNormal(pWidget); | |
| 431 } | |
| 432 FWL_ERR CFWL_WidgetMgr::SetMaximize_Native(IFWL_Widget* pWidget) { | |
| 433 return m_pAdapter->SetMaximize(pWidget); | |
| 434 } | |
| 435 FWL_ERR CFWL_WidgetMgr::SetMinimize_Native(IFWL_Widget* pWidget) { | |
| 436 return m_pAdapter->SetMinimize(pWidget); | |
| 437 } | |
| 438 FX_BOOL CFWL_WidgetMgr::CheckMessage_Native() { | |
| 439 return m_pAdapter->CheckMessage(); | |
| 440 } | |
| 441 FWL_ERR CFWL_WidgetMgr::DispatchMessage_Native() { | |
| 442 return m_pAdapter->DispatchMessage(); | |
| 443 } | |
| 444 FX_BOOL CFWL_WidgetMgr::IsIdleMessage_Native() { | |
| 445 return m_pAdapter->IsIdleMessage(); | |
| 446 } | |
| 447 FWL_ERR CFWL_WidgetMgr::Exit_Native(int32_t iExitCode) { | |
| 448 return m_pAdapter->Exit(iExitCode); | |
| 449 } | |
| 450 FWL_ERR CFWL_WidgetMgr::CreateWidgetWithNativeId_Native(IFWL_Widget* pWidget, | |
| 451 void* vp) { | |
| 452 return m_pAdapter->CreateWidgetWithNativeId(pWidget, vp); | |
| 453 } | |
| 454 IFWL_Widget* CFWL_WidgetMgr::GetWidgetAtPoint(IFWL_Widget* parent, | |
| 455 FX_FLOAT x, | |
| 456 FX_FLOAT y) { | |
| 457 if (!parent) | |
| 458 return NULL; | |
| 459 FX_FLOAT x1; | |
| 460 FX_FLOAT y1; | |
| 461 IFWL_Widget* child = GetWidget(parent, FWL_WGTRELATION_LastChild); | |
| 462 while (child) { | |
| 463 if ((child->GetStates() & FWL_WGTSTATE_Invisible) == 0) { | |
| 464 x1 = x; | |
| 465 y1 = y; | |
| 466 CFX_Matrix matrixOnParent; | |
| 467 child->GetMatrix(matrixOnParent); | |
| 468 CFX_Matrix m; | |
| 469 m.SetIdentity(); | |
| 470 m.SetReverse(matrixOnParent); | |
| 471 m.TransformPoint(x1, y1); | |
| 472 CFX_RectF bounds; | |
| 473 child->GetWidgetRect(bounds); | |
| 474 if (bounds.Contains(x1, y1)) { | |
| 475 x1 -= bounds.left; | |
| 476 y1 -= bounds.top; | |
| 477 return GetWidgetAtPoint(child, x1, y1); | |
| 478 } | |
| 479 } | |
| 480 child = GetWidget(child, FWL_WGTRELATION_PriorSibling); | |
| 481 } | |
| 482 return parent; | |
| 483 } | |
| 484 void CFWL_WidgetMgr::NotifySizeChanged(IFWL_Widget* pForm, | |
| 485 FX_FLOAT fx, | |
| 486 FX_FLOAT fy) { | |
| 487 if (!FWL_UseOffscreen(pForm)) { | |
| 488 return; | |
| 489 } | |
| 490 CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pForm); | |
| 491 if (pItem->pOffscreen) { | |
| 492 delete pItem->pOffscreen; | |
| 493 pItem->pOffscreen = NULL; | |
| 494 } | |
| 495 } | |
| 496 IFWL_Widget* CFWL_WidgetMgr::nextTab(IFWL_Widget* parent, | |
| 497 IFWL_Widget* focus, | |
| 498 FX_BOOL& bFind) { | |
| 499 IFWL_Widget* child = | |
| 500 FWL_GetWidgetMgr()->GetWidget(parent, FWL_WGTRELATION_FirstChild); | |
| 501 while (child) { | |
| 502 if (focus == child) { | |
| 503 bFind = TRUE; | |
| 504 } | |
| 505 if ((child->GetStyles() & FWL_WGTSTYLE_TabStop) && | |
| 506 (!focus || (focus != child && bFind))) { | |
| 507 return child; | |
| 508 } | |
| 509 IFWL_Widget* bRet = nextTab(child, focus, bFind); | |
| 510 if (bRet) { | |
| 511 return bRet; | |
| 512 } | |
| 513 child = FWL_GetWidgetMgr()->GetWidget(child, FWL_WGTRELATION_NextSibling); | |
| 514 } | |
| 515 return NULL; | |
| 516 } | |
| 517 int32_t CFWL_WidgetMgr::CountRadioButtonGroup(IFWL_Widget* pFirst) { | |
| 518 int32_t iRet = 0; | |
| 519 IFWL_Widget* pChild = pFirst; | |
| 520 while (pChild) { | |
| 521 if ((pChild->GetStyles() & FWL_WGTSTYLE_Group) && | |
| 522 pChild->GetClassID() == 3811304691) { | |
| 523 iRet++; | |
| 524 } | |
| 525 pChild = GetWidget(pChild, FWL_WGTRELATION_NextSibling); | |
| 526 } | |
| 527 return iRet; | |
| 528 } | |
| 529 IFWL_Widget* CFWL_WidgetMgr::GetSiblingRadioButton(IFWL_Widget* pWidget, | |
| 530 FX_BOOL bNext) { | |
| 531 while ((pWidget = GetWidget(pWidget, bNext ? FWL_WGTRELATION_NextSibling | |
| 532 : FWL_WGTRELATION_PriorSibling)) != | |
| 533 NULL) { | |
| 534 if (pWidget->GetClassID() == 3811304691) { | |
| 535 return pWidget; | |
| 536 } | |
| 537 } | |
| 538 return NULL; | |
| 539 } | |
| 540 IFWL_Widget* CFWL_WidgetMgr::GetRadioButtonGroupHeader( | |
| 541 IFWL_Widget* pRadioButton) { | |
| 542 if (pRadioButton->GetStyles() & FWL_WGTSTYLE_Group) { | |
| 543 return pRadioButton; | |
| 544 } | |
| 545 IFWL_Widget* pNext = pRadioButton; | |
| 546 while ((pNext = GetSiblingRadioButton(pNext, FALSE)) != NULL) { | |
| 547 if (pNext->GetStyles() & FWL_WGTSTYLE_Group) { | |
| 548 return pNext; | |
| 549 } | |
| 550 } | |
| 551 pNext = GetWidget(pRadioButton, FWL_WGTRELATION_LastSibling); | |
| 552 if ((pNext->GetStyles() & FWL_WGTSTYLE_Group) && | |
| 553 pNext->GetClassID() == 3811304691) { | |
| 554 return pNext; | |
| 555 } | |
| 556 while ((pNext = GetSiblingRadioButton(pNext, FALSE)) && pNext && | |
| 557 pNext != pRadioButton) { | |
| 558 if (pNext->GetStyles() & FWL_WGTSTYLE_Group) { | |
| 559 return pNext; | |
| 560 } | |
| 561 } | |
| 562 pNext = GetWidget(pRadioButton, FWL_WGTRELATION_FirstSibling); | |
| 563 if (pNext && (pNext->GetStyles() == FWL_WGTSTYLE_Group) && | |
| 564 pNext->GetClassID() == 3811304691) { | |
| 565 return pNext; | |
| 566 } | |
| 567 return GetSiblingRadioButton(pNext, TRUE); | |
| 568 } | |
| 569 void CFWL_WidgetMgr::GetSameGroupRadioButton(IFWL_Widget* pRadioButton, | |
| 570 CFX_PtrArray& group) { | |
| 571 IFWL_Widget* pFirst = GetWidget(pRadioButton, FWL_WGTRELATION_FirstSibling); | |
| 572 if (!pFirst) { | |
| 573 pFirst = pRadioButton; | |
| 574 } | |
| 575 int32_t iGroup = CountRadioButtonGroup(pFirst); | |
| 576 if (iGroup < 2) { | |
| 577 if (pFirst->GetClassID() == 3811304691) { | |
| 578 group.Add(pFirst); | |
| 579 } | |
| 580 IFWL_Widget* pNext = pFirst; | |
| 581 while ((pNext = GetSiblingRadioButton(pNext, TRUE)) != NULL) { | |
| 582 group.Add(pNext); | |
| 583 } | |
| 584 return; | |
| 585 } | |
| 586 IFWL_Widget* pNext = GetRadioButtonGroupHeader(pRadioButton); | |
| 587 do { | |
| 588 group.Add(pNext); | |
| 589 pNext = GetSiblingRadioButton(pNext, TRUE); | |
| 590 if (!pNext) { | |
| 591 if (pFirst->GetClassID() == 3811304691) { | |
| 592 pNext = pFirst; | |
| 593 } else { | |
| 594 pNext = GetSiblingRadioButton(pFirst, TRUE); | |
| 595 } | |
| 596 } | |
| 597 } while (pNext && ((pNext->GetStyles() & FWL_WGTSTYLE_Group) == 0)); | |
| 598 } | |
| 599 IFWL_Widget* CFWL_WidgetMgr::GetDefaultButton(IFWL_Widget* pParent) { | |
| 600 if ((pParent->GetClassID() == 3521614244) && | |
| 601 (pParent->GetStates() & (1 << (FWL_WGTSTATE_MAX + 2)))) { | |
| 602 return pParent; | |
| 603 } | |
| 604 IFWL_Widget* child = | |
| 605 FWL_GetWidgetMgr()->GetWidget(pParent, FWL_WGTRELATION_FirstChild); | |
| 606 while (child) { | |
| 607 if ((child->GetClassID() == 3521614244) && | |
| 608 (child->GetStates() & (1 << (FWL_WGTSTATE_MAX + 2)))) { | |
| 609 return child; | |
| 610 } | |
| 611 IFWL_Widget* find = GetDefaultButton(child); | |
| 612 if (find) { | |
| 613 return find; | |
| 614 } | |
| 615 child = FWL_GetWidgetMgr()->GetWidget(child, FWL_WGTRELATION_NextSibling); | |
| 616 } | |
| 617 return NULL; | |
| 618 } | |
| 619 void CFWL_WidgetMgr::AddRedrawCounts(IFWL_Widget* pWidget) { | |
| 620 CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget); | |
| 621 (pItem->iRedrawCounter)++; | |
| 622 } | |
| 623 void CFWL_WidgetMgr::ResetRedrawCounts(IFWL_Widget* pWidget) { | |
| 624 CFWL_WidgetMgrItem* pItem = GetWidgetMgrItem(pWidget); | |
| 625 pItem->iRedrawCounter = 0; | |
| 626 } | |
| 627 CFWL_WidgetMgrItem* CFWL_WidgetMgr::GetWidgetMgrItem(IFWL_Widget* pWidget) { | |
| 628 return static_cast<CFWL_WidgetMgrItem*>(m_mapWidgetItem.GetValueAt(pWidget)); | |
| 629 } | |
| 630 int32_t CFWL_WidgetMgr::TravelWidgetMgr(CFWL_WidgetMgrItem* pParent, | |
| 631 int32_t* pIndex, | |
| 632 CFWL_WidgetMgrItem* pItem, | |
| 633 IFWL_Widget** pWidget) { | |
| 634 if (!pParent) { | |
| 635 return 0; | |
| 636 } | |
| 637 int32_t iCount = 0; | |
| 638 CFWL_WidgetMgrItem* pChild = pParent->pChild; | |
| 639 while (pChild) { | |
| 640 iCount++; | |
| 641 if (pIndex) { | |
| 642 if (*pIndex == 0) { | |
| 643 *pWidget = pChild->pWidget; | |
| 644 return iCount; | |
| 645 } | |
| 646 pIndex--; | |
| 647 } | |
| 648 if (pItem && pItem == pChild) { | |
| 649 return iCount - 1; | |
| 650 } | |
| 651 pChild = pChild->pNext; | |
| 652 } | |
| 653 if (pIndex) { | |
| 654 return 0; | |
| 655 } else if (pItem) { | |
| 656 return -1; | |
| 657 } | |
| 658 return iCount - 1; | |
| 659 } | |
| 660 FX_BOOL CFWL_WidgetMgr::IsAbleNative(IFWL_Widget* pWidget) { | |
| 661 if (!pWidget) | |
| 662 return FALSE; | |
| 663 if (!pWidget->IsInstance(FX_WSTRC(FWL_CLASS_Form))) { | |
| 664 return FALSE; | |
| 665 } | |
| 666 FX_DWORD dwStyles = pWidget->GetStyles(); | |
| 667 return ((dwStyles & FWL_WGTSTYLE_WindowTypeMask) == | |
| 668 FWL_WGTSTYLE_OverLapper) || | |
| 669 (dwStyles & FWL_WGTSTYLE_Popup); | |
| 670 } | |
| 671 FX_BOOL CFWL_WidgetMgr::IsThreadEnabled() { | |
| 672 return !(m_dwCapability & FWL_WGTMGR_DisableThread); | |
| 673 } | |
| 674 FX_BOOL CFWL_WidgetMgr::IsFormDisabled() { | |
| 675 return m_dwCapability & FWL_WGTMGR_DisableForm; | |
| 676 } | |
| 677 FX_BOOL CFWL_WidgetMgr::GetAdapterPopupPos(IFWL_Widget* pWidget, | |
| 678 FX_FLOAT fMinHeight, | |
| 679 FX_FLOAT fMaxHeight, | |
| 680 const CFX_RectF& rtAnchor, | |
| 681 CFX_RectF& rtPopup) { | |
| 682 IFWL_AdapterWidgetMgr* pSDApapter = GetAdapterWidgetMgr(); | |
| 683 return pSDApapter->GetPopupPos(pWidget, fMinHeight, fMaxHeight, rtAnchor, | |
| 684 rtPopup); | |
| 685 } | |
| 686 CFWL_WidgetMgrDelegate::CFWL_WidgetMgrDelegate(CFWL_WidgetMgr* pWidgetMgr) | |
| 687 : m_pWidgetMgr(pWidgetMgr) {} | |
| 688 FWL_ERR CFWL_WidgetMgrDelegate::OnSetCapability(FX_DWORD dwCapability) { | |
| 689 m_pWidgetMgr->m_dwCapability = dwCapability; | |
| 690 return FWL_ERR_Succeeded; | |
| 691 } | |
| 692 int32_t CFWL_WidgetMgrDelegate::OnProcessMessageToForm(CFWL_Message* pMessage) { | |
| 693 if (!pMessage) | |
| 694 return 0; | |
| 695 if (!pMessage->m_pDstTarget) | |
| 696 return 0; | |
| 697 IFWL_Widget* pDstWidget = pMessage->m_pDstTarget; | |
| 698 IFWL_NoteThread* pNoteThread = pDstWidget->GetOwnerThread(); | |
| 699 if (!pNoteThread) | |
| 700 return 0; | |
| 701 CFWL_NoteDriver* pNoteDriver = | |
| 702 static_cast<CFWL_NoteDriver*>(pNoteThread->GetNoteDriver()); | |
| 703 if (!pNoteDriver) | |
| 704 return 0; | |
| 705 if (m_pWidgetMgr->IsThreadEnabled()) { | |
| 706 pMessage = static_cast<CFWL_Message*>(pMessage->Clone()); | |
| 707 } | |
| 708 if (m_pWidgetMgr->IsFormDisabled()) { | |
| 709 pNoteDriver->ProcessMessage(pMessage); | |
| 710 } else { | |
| 711 pNoteDriver->QueueMessage(pMessage); | |
| 712 } | |
| 713 #if (_FX_OS_ == _FX_MACOSX_) | |
| 714 CFWL_NoteLoop* pTopLoop = pNoteDriver->GetTopLoop(); | |
| 715 if (pTopLoop) { | |
| 716 pNoteDriver->UnqueueMessage(pTopLoop); | |
| 717 } | |
| 718 #endif | |
| 719 if (m_pWidgetMgr->IsThreadEnabled()) { | |
| 720 pMessage->Release(); | |
| 721 } | |
| 722 return FWL_ERR_Succeeded; | |
| 723 } | |
| 724 FWL_ERR CFWL_WidgetMgrDelegate::OnDrawWidget(IFWL_Widget* pWidget, | |
| 725 CFX_Graphics* pGraphics, | |
| 726 const CFX_Matrix* pMatrix) { | |
| 727 if (!pWidget) | |
| 728 return FWL_ERR_Indefinite; | |
| 729 if (!pGraphics) | |
| 730 return FWL_ERR_Indefinite; | |
| 731 CFX_Graphics* pTemp = DrawWidgetBefore(pWidget, pGraphics, pMatrix); | |
| 732 CFX_RectF clipCopy; | |
| 733 pWidget->GetWidgetRect(clipCopy); | |
| 734 clipCopy.left = clipCopy.top = 0; | |
| 735 if (bUseOffscreenDirect(pWidget)) { | |
| 736 DrawWidgetAfter(pWidget, pGraphics, clipCopy, pMatrix); | |
| 737 return FWL_ERR_Succeeded; | |
| 738 } | |
| 739 CFX_RectF clipBounds; | |
| 740 #if (_FX_OS_ == _FX_WIN32_DESKTOP_) || (_FX_OS_ == _FX_WIN64_) || \ | |
| 741 (_FX_OS_ == _FX_LINUX_DESKTOP_) || (_FX_OS_ == _FX_ANDROID_) | |
| 742 IFWL_WidgetDelegate* pDelegate = pWidget->SetDelegate(NULL); | |
| 743 pDelegate->OnDrawWidget(pTemp, pMatrix); | |
| 744 pGraphics->GetClipRect(clipBounds); | |
| 745 clipCopy = clipBounds; | |
| 746 #elif(_FX_OS_ == _FX_MACOSX_) | |
| 747 if (m_pWidgetMgr->IsFormDisabled()) { | |
| 748 IFWL_WidgetDelegate* pDelegate = pWidget->SetDelegate(NULL); | |
| 749 pDelegate->OnDrawWidget(pTemp, pMatrix); | |
| 750 pGraphics->GetClipRect(clipBounds); | |
| 751 clipCopy = clipBounds; | |
| 752 } else { | |
| 753 clipBounds.Set(pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d); | |
| 754 const_cast<CFX_Matrix*>(pMatrix)->SetIdentity(); // FIXME: const cast. | |
| 755 #ifdef FWL_UseMacSystemBorder | |
| 756 #else | |
| 757 #endif | |
| 758 { | |
| 759 IFWL_WidgetDelegate* pDelegate = pWidget->SetDelegate(NULL); | |
| 760 pDelegate->OnDrawWidget(pTemp, pMatrix); | |
| 761 } | |
| 762 } | |
| 763 #endif | |
| 764 if (!m_pWidgetMgr->IsFormDisabled()) { | |
| 765 CFX_RectF rtClient; | |
| 766 pWidget->GetClientRect(rtClient); | |
| 767 clipBounds.Intersect(rtClient); | |
| 768 } | |
| 769 if (!clipBounds.IsEmpty()) { | |
| 770 DrawChild(pWidget, clipBounds, pTemp, pMatrix); | |
| 771 } | |
| 772 DrawWidgetAfter(pWidget, pGraphics, clipCopy, pMatrix); | |
| 773 m_pWidgetMgr->ResetRedrawCounts(pWidget); | |
| 774 return FWL_ERR_Succeeded; | |
| 775 } | |
| 776 void CFWL_WidgetMgrDelegate::DrawChild(IFWL_Widget* parent, | |
| 777 const CFX_RectF& rtClip, | |
| 778 CFX_Graphics* pGraphics, | |
| 779 const CFX_Matrix* pMatrix) { | |
| 780 if (!parent) | |
| 781 return; | |
| 782 FX_BOOL bFormDisable = m_pWidgetMgr->IsFormDisabled(); | |
| 783 IFWL_Widget* pNextChild = | |
| 784 m_pWidgetMgr->GetWidget(parent, FWL_WGTRELATION_FirstChild); | |
| 785 while (pNextChild) { | |
| 786 IFWL_Widget* child = pNextChild; | |
| 787 pNextChild = m_pWidgetMgr->GetWidget(child, FWL_WGTRELATION_NextSibling); | |
| 788 if (child->GetStates() & FWL_WGTSTATE_Invisible) { | |
| 789 continue; | |
| 790 } | |
| 791 CFX_RectF rtWidget; | |
| 792 child->GetWidgetRect(rtWidget); | |
| 793 if (rtWidget.IsEmpty()) { | |
| 794 continue; | |
| 795 } | |
| 796 CFX_Matrix widgetMatrix; | |
| 797 CFX_RectF clipBounds(rtWidget); | |
| 798 if (!bFormDisable) { | |
| 799 child->GetMatrix(widgetMatrix, TRUE); | |
| 800 } | |
| 801 if (pMatrix) { | |
| 802 widgetMatrix.Concat(*pMatrix); | |
| 803 } | |
| 804 if (!bFormDisable) { | |
| 805 widgetMatrix.TransformPoint(clipBounds.left, clipBounds.top); | |
| 806 clipBounds.Intersect(rtClip); | |
| 807 if (clipBounds.IsEmpty()) { | |
| 808 continue; | |
| 809 } | |
| 810 pGraphics->SaveGraphState(); | |
| 811 pGraphics->SetClipRect(clipBounds); | |
| 812 } | |
| 813 widgetMatrix.Translate(rtWidget.left, rtWidget.top, TRUE); | |
| 814 IFWL_WidgetDelegate* pDelegate = child->SetDelegate(NULL); | |
| 815 if (pDelegate) { | |
| 816 if (m_pWidgetMgr->IsFormDisabled() || | |
| 817 IsNeedRepaint(child, &widgetMatrix, rtClip)) { | |
| 818 pDelegate->OnDrawWidget(pGraphics, &widgetMatrix); | |
| 819 } | |
| 820 } | |
| 821 if (!bFormDisable) { | |
| 822 pGraphics->RestoreGraphState(); | |
| 823 } | |
| 824 DrawChild(child, clipBounds, pGraphics, | |
| 825 bFormDisable ? &widgetMatrix : pMatrix); | |
| 826 child = m_pWidgetMgr->GetWidget(child, FWL_WGTRELATION_NextSibling); | |
| 827 } | |
| 828 } | |
| 829 CFX_Graphics* CFWL_WidgetMgrDelegate::DrawWidgetBefore( | |
| 830 IFWL_Widget* pWidget, | |
| 831 CFX_Graphics* pGraphics, | |
| 832 const CFX_Matrix* pMatrix) { | |
| 833 if (!FWL_UseOffscreen(pWidget)) { | |
| 834 return pGraphics; | |
| 835 } | |
| 836 CFWL_WidgetMgrItem* pItem = m_pWidgetMgr->GetWidgetMgrItem(pWidget); | |
| 837 if (!pItem->pOffscreen) { | |
| 838 pItem->pOffscreen = new CFX_Graphics; | |
| 839 CFX_RectF rect; | |
| 840 pWidget->GetWidgetRect(rect); | |
| 841 pItem->pOffscreen->Create((int32_t)rect.width, (int32_t)rect.height, | |
| 842 FXDIB_Argb); | |
| 843 } | |
| 844 CFX_RectF rect; | |
| 845 pGraphics->GetClipRect(rect); | |
| 846 pItem->pOffscreen->SetClipRect(rect); | |
| 847 return pItem->pOffscreen; | |
| 848 } | |
| 849 void CFWL_WidgetMgrDelegate::DrawWidgetAfter(IFWL_Widget* pWidget, | |
| 850 CFX_Graphics* pGraphics, | |
| 851 CFX_RectF& rtClip, | |
| 852 const CFX_Matrix* pMatrix) { | |
| 853 if (FWL_UseOffscreen(pWidget)) { | |
| 854 CFWL_WidgetMgrItem* pItem = m_pWidgetMgr->GetWidgetMgrItem(pWidget); | |
| 855 pGraphics->Transfer(pItem->pOffscreen, rtClip.left, rtClip.top, rtClip, | |
| 856 pMatrix); | |
| 857 #ifdef _WIN32 | |
| 858 pItem->pOffscreen->ClearClip(); | |
| 859 #endif | |
| 860 } | |
| 861 CFWL_WidgetMgrItem* pItem = m_pWidgetMgr->GetWidgetMgrItem(pWidget); | |
| 862 pItem->iRedrawCounter = 0; | |
| 863 } | |
| 864 | |
| 865 #define FWL_NEEDREPAINTHIT_Point 12 | |
| 866 #define FWL_NEEDREPAINTHIT_Piece 3 | |
| 867 struct FWL_NEEDREPAINTHITDATA { | |
| 868 CFX_PointF hitPoint; | |
| 869 FX_BOOL bNotNeedRepaint; | |
| 870 FX_BOOL bNotContainByDirty; | |
| 871 }; | |
| 872 | |
| 873 FX_BOOL CFWL_WidgetMgrDelegate::IsNeedRepaint(IFWL_Widget* pWidget, | |
| 874 CFX_Matrix* pMatrix, | |
| 875 const CFX_RectF& rtDirty) { | |
| 876 CFWL_WidgetMgrItem* pItem = m_pWidgetMgr->GetWidgetMgrItem(pWidget); | |
| 877 if (pItem && pItem->iRedrawCounter > 0) { | |
| 878 pItem->iRedrawCounter = 0; | |
| 879 return TRUE; | |
| 880 } | |
| 881 CFX_RectF rtWidget; | |
| 882 pWidget->GetWidgetRect(rtWidget); | |
| 883 rtWidget.left = rtWidget.top = 0; | |
| 884 pMatrix->TransformRect(rtWidget); | |
| 885 if (!rtWidget.IntersectWith(rtDirty)) { | |
| 886 return FALSE; | |
| 887 } | |
| 888 IFWL_Widget* pChild = | |
| 889 FWL_GetWidgetMgr()->GetWidget(pWidget, FWL_WGTRELATION_FirstChild); | |
| 890 if (!pChild) { | |
| 891 return TRUE; | |
| 892 } | |
| 893 if (pChild->GetClassID() == 3150298670) { | |
| 894 CFX_RectF rtTemp; | |
| 895 pChild->GetWidgetRect(rtTemp); | |
| 896 if (rtTemp.width >= rtWidget.width && rtTemp.height >= rtWidget.height) { | |
| 897 pChild = | |
| 898 FWL_GetWidgetMgr()->GetWidget(pChild, FWL_WGTRELATION_FirstChild); | |
| 899 if (!pChild) { | |
| 900 return TRUE; | |
| 901 } | |
| 902 } | |
| 903 } | |
| 904 CFX_RectF rtChilds; | |
| 905 rtChilds.Empty(); | |
| 906 FX_BOOL bChildIntersectWithDirty = FALSE; | |
| 907 FX_BOOL bOrginPtIntersectWidthChild = FALSE; | |
| 908 FX_BOOL bOrginPtIntersectWidthDirty = | |
| 909 rtDirty.Contains(rtWidget.left, rtWidget.top); | |
| 910 static FWL_NEEDREPAINTHITDATA hitPoint[FWL_NEEDREPAINTHIT_Point]; | |
| 911 int32_t iSize = sizeof(FWL_NEEDREPAINTHITDATA); | |
| 912 FXSYS_memset(hitPoint, 0, iSize); | |
| 913 FX_FLOAT fxPiece = rtWidget.width / FWL_NEEDREPAINTHIT_Piece; | |
| 914 FX_FLOAT fyPiece = rtWidget.height / FWL_NEEDREPAINTHIT_Piece; | |
| 915 hitPoint[2].hitPoint.x = hitPoint[6].hitPoint.x = rtWidget.left; | |
| 916 hitPoint[0].hitPoint.x = hitPoint[3].hitPoint.x = hitPoint[7].hitPoint.x = | |
| 917 hitPoint[10].hitPoint.x = fxPiece + rtWidget.left; | |
| 918 hitPoint[1].hitPoint.x = hitPoint[4].hitPoint.x = hitPoint[8].hitPoint.x = | |
| 919 hitPoint[11].hitPoint.x = fxPiece * 2 + rtWidget.left; | |
| 920 hitPoint[5].hitPoint.x = hitPoint[9].hitPoint.x = | |
| 921 rtWidget.width + rtWidget.left; | |
| 922 hitPoint[0].hitPoint.y = hitPoint[1].hitPoint.y = rtWidget.top; | |
| 923 hitPoint[2].hitPoint.y = hitPoint[3].hitPoint.y = hitPoint[4].hitPoint.y = | |
| 924 hitPoint[5].hitPoint.y = fyPiece + rtWidget.top; | |
| 925 hitPoint[6].hitPoint.y = hitPoint[7].hitPoint.y = hitPoint[8].hitPoint.y = | |
| 926 hitPoint[9].hitPoint.y = fyPiece * 2 + rtWidget.top; | |
| 927 hitPoint[10].hitPoint.y = hitPoint[11].hitPoint.y = | |
| 928 rtWidget.height + rtWidget.top; | |
| 929 do { | |
| 930 CFX_RectF rect; | |
| 931 pChild->GetWidgetRect(rect); | |
| 932 CFX_RectF r = rect; | |
| 933 r.left += rtWidget.left; | |
| 934 r.top += rtWidget.top; | |
| 935 if (r.IsEmpty()) { | |
| 936 continue; | |
| 937 } | |
| 938 if (r.Contains(rtDirty)) { | |
| 939 return FALSE; | |
| 940 } | |
| 941 if (!bChildIntersectWithDirty && r.IntersectWith(rtDirty)) { | |
| 942 bChildIntersectWithDirty = TRUE; | |
| 943 } | |
| 944 if (bOrginPtIntersectWidthDirty && !bOrginPtIntersectWidthChild) { | |
| 945 bOrginPtIntersectWidthChild = rect.Contains(0, 0); | |
| 946 } | |
| 947 if (rtChilds.IsEmpty()) { | |
| 948 rtChilds = rect; | |
| 949 } else if (!(pChild->GetStates() & FWL_WGTSTATE_Invisible)) { | |
| 950 rtChilds.Union(rect); | |
| 951 } | |
| 952 for (int32_t i = 0; i < FWL_NEEDREPAINTHIT_Point; i++) { | |
| 953 if (hitPoint[i].bNotContainByDirty || hitPoint[i].bNotNeedRepaint) { | |
| 954 continue; | |
| 955 } | |
| 956 if (!rtDirty.Contains(hitPoint[i].hitPoint)) { | |
| 957 hitPoint[i].bNotContainByDirty = TRUE; | |
| 958 continue; | |
| 959 } | |
| 960 if (r.Contains(hitPoint[i].hitPoint)) { | |
| 961 hitPoint[i].bNotNeedRepaint = TRUE; | |
| 962 } | |
| 963 } | |
| 964 } while ((pChild = FWL_GetWidgetMgr()->GetWidget( | |
| 965 pChild, FWL_WGTRELATION_NextSibling)) != NULL); | |
| 966 if (!bChildIntersectWithDirty) { | |
| 967 return TRUE; | |
| 968 } | |
| 969 if (bOrginPtIntersectWidthDirty && !bOrginPtIntersectWidthChild) { | |
| 970 return TRUE; | |
| 971 } | |
| 972 if (rtChilds.IsEmpty()) { | |
| 973 return TRUE; | |
| 974 } | |
| 975 int32_t repaintPoint = FWL_NEEDREPAINTHIT_Point; | |
| 976 for (int32_t i = 0; i < FWL_NEEDREPAINTHIT_Point; i++) { | |
| 977 if (hitPoint[i].bNotNeedRepaint) { | |
| 978 repaintPoint--; | |
| 979 } | |
| 980 } | |
| 981 if (repaintPoint > 0) { | |
| 982 return TRUE; | |
| 983 } | |
| 984 pMatrix->TransformRect(rtChilds); | |
| 985 if (rtChilds.Contains(rtDirty) || rtChilds.Contains(rtWidget)) { | |
| 986 return FALSE; | |
| 987 } | |
| 988 return TRUE; | |
| 989 } | |
| 990 FX_BOOL CFWL_WidgetMgrDelegate::bUseOffscreenDirect(IFWL_Widget* pWidget) { | |
| 991 CFWL_WidgetMgrItem* pItem = m_pWidgetMgr->GetWidgetMgrItem(pWidget); | |
| 992 if (!FWL_UseOffscreen(pWidget) || !(pItem->pOffscreen)) { | |
| 993 return FALSE; | |
| 994 } | |
| 995 #if (_FX_OS_ == _FX_WIN32_DESKTOP_) || (_FX_OS_ == _FX_WIN64_) | |
| 996 if (pItem->bOutsideChanged) { | |
| 997 CFX_RectF r; | |
| 998 pWidget->GetWidgetRect(r); | |
| 999 CFX_RectF temp(m_pWidgetMgr->m_rtScreen); | |
| 1000 temp.Deflate(50, 50); | |
| 1001 if (!temp.Contains(r)) { | |
| 1002 return FALSE; | |
| 1003 } | |
| 1004 pItem->bOutsideChanged = FALSE; | |
| 1005 } | |
| 1006 #endif | |
| 1007 return pItem->iRedrawCounter == 0; | |
| 1008 } | |
| 1009 static void FWL_WriteBMP(CFX_DIBitmap* pBitmap, const FX_CHAR* filename) { | |
| 1010 FILE* file = fopen(filename, "wb"); | |
| 1011 if (file == NULL) { | |
| 1012 return; | |
| 1013 } | |
| 1014 int size = 14 + 40 + pBitmap->GetPitch() * pBitmap->GetHeight(); | |
| 1015 unsigned char buffer[40]; | |
| 1016 buffer[0] = 'B'; | |
| 1017 buffer[1] = 'M'; | |
| 1018 buffer[2] = (unsigned char)size; | |
| 1019 buffer[3] = (unsigned char)(size >> 8); | |
| 1020 buffer[4] = (unsigned char)(size >> 16); | |
| 1021 buffer[5] = (unsigned char)(size >> 24); | |
| 1022 buffer[6] = buffer[7] = buffer[8] = buffer[9] = 0; | |
| 1023 buffer[10] = 54; | |
| 1024 buffer[11] = buffer[12] = buffer[13] = 0; | |
| 1025 fwrite(buffer, 14, 1, file); | |
| 1026 memset(buffer, 0, 40); | |
| 1027 buffer[0] = 40; | |
| 1028 buffer[4] = (unsigned char)pBitmap->GetWidth(); | |
| 1029 buffer[5] = (unsigned char)(pBitmap->GetWidth() >> 8); | |
| 1030 buffer[6] = (unsigned char)(pBitmap->GetWidth() >> 16); | |
| 1031 buffer[7] = (unsigned char)(pBitmap->GetWidth() >> 24); | |
| 1032 buffer[8] = (unsigned char)(-pBitmap->GetHeight()); | |
| 1033 buffer[9] = (unsigned char)((-pBitmap->GetHeight()) >> 8); | |
| 1034 buffer[10] = (unsigned char)((-pBitmap->GetHeight()) >> 16); | |
| 1035 buffer[11] = (unsigned char)((-pBitmap->GetHeight()) >> 24); | |
| 1036 buffer[12] = 1; | |
| 1037 buffer[14] = pBitmap->GetBPP(); | |
| 1038 fwrite(buffer, 40, 1, file); | |
| 1039 for (int row = 0; row < pBitmap->GetHeight(); row++) { | |
| 1040 uint8_t* scan_line = pBitmap->GetBuffer() + row * pBitmap->GetPitch(); | |
| 1041 fwrite(scan_line, pBitmap->GetPitch(), 1, file); | |
| 1042 } | |
| 1043 fclose(file); | |
| 1044 } | |
| 1045 FWL_ERR FWL_WidgetMgrSnapshot(IFWL_Widget* pWidget, | |
| 1046 const CFX_WideString* saveFile, | |
| 1047 const CFX_Matrix* pMatrix) { | |
| 1048 CFX_RectF r; | |
| 1049 pWidget->GetWidgetRect(r); | |
| 1050 CFX_Graphics gs; | |
| 1051 gs.Create((int32_t)r.width, (int32_t)r.height, FXDIB_Argb); | |
| 1052 CFWL_WidgetMgr* widgetMgr = static_cast<CFWL_WidgetMgr*>(FWL_GetWidgetMgr()); | |
| 1053 CFWL_WidgetMgrDelegate* delegate = widgetMgr->GetDelegate(); | |
| 1054 delegate->OnDrawWidget(pWidget, &gs, pMatrix); | |
| 1055 CFX_DIBitmap* dib = gs.GetRenderDevice()->GetBitmap(); | |
| 1056 FWL_WriteBMP(dib, saveFile->UTF8Encode()); | |
| 1057 return FWL_ERR_Succeeded; | |
| 1058 } | |
| 1059 FX_BOOL FWL_WidgetIsChild(IFWL_Widget* parent, IFWL_Widget* find) { | |
| 1060 if (!find) { | |
| 1061 return FALSE; | |
| 1062 } | |
| 1063 IFWL_Widget* child = | |
| 1064 FWL_GetWidgetMgr()->GetWidget(parent, FWL_WGTRELATION_FirstChild); | |
| 1065 while (child) { | |
| 1066 if (child == find) { | |
| 1067 return TRUE; | |
| 1068 } | |
| 1069 if (FWL_WidgetIsChild(child, find)) { | |
| 1070 return TRUE; | |
| 1071 } | |
| 1072 child = FWL_GetWidgetMgr()->GetWidget(child, FWL_WGTRELATION_NextSibling); | |
| 1073 } | |
| 1074 return FALSE; | |
| 1075 } | |
| OLD | NEW |