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 <map> 8 9 #include "fpdfsdk/include/pdfwindow/PWL_ScrollBar.h" 10 #include "fpdfsdk/include/pdfwindow/PWL_Utils.h" 11 #include "fpdfsdk/include/pdfwindow/PWL_Wnd.h" 12 13 static std::map<int32_t, CPWL_Timer*>& GetPWLTimeMap() { 14 // Leak the object at shutdown. 15 static auto timeMap = new std::map<int32_t, CPWL_Timer*>; 16 return *timeMap; 17 } 18 19 CPWL_Timer::CPWL_Timer(CPWL_TimerHandler* pAttached, 20 IFX_SystemHandler* pSystemHandler) 21 : m_nTimerID(0), m_pAttached(pAttached), m_pSystemHandler(pSystemHandler) { 22 ASSERT(m_pAttached); 23 ASSERT(m_pSystemHandler); 24 } 25 26 CPWL_Timer::~CPWL_Timer() { 27 KillPWLTimer(); 28 } 29 30 int32_t CPWL_Timer::SetPWLTimer(int32_t nElapse) { 31 if (m_nTimerID != 0) 32 KillPWLTimer(); 33 m_nTimerID = m_pSystemHandler->SetTimer(nElapse, TimerProc); 34 35 GetPWLTimeMap()[m_nTimerID] = this; 36 return m_nTimerID; 37 } 38 39 void CPWL_Timer::KillPWLTimer() { 40 if (m_nTimerID == 0) 41 return; 42 43 m_pSystemHandler->KillTimer(m_nTimerID); 44 GetPWLTimeMap().erase(m_nTimerID); 45 m_nTimerID = 0; 46 } 47 48 void CPWL_Timer::TimerProc(int32_t idEvent) { 49 auto it = GetPWLTimeMap().find(idEvent); 50 if (it == GetPWLTimeMap().end()) 51 return; 52 53 CPWL_Timer* pTimer = it->second; 54 if (pTimer->m_pAttached) 55 pTimer->m_pAttached->TimerProc(); 56 } 57 58 CPWL_TimerHandler::CPWL_TimerHandler() : m_pTimer(NULL) {} 59 60 CPWL_TimerHandler::~CPWL_TimerHandler() { 61 delete m_pTimer; 62 } 63 64 void CPWL_TimerHandler::BeginTimer(int32_t nElapse) { 65 if (!m_pTimer) 66 m_pTimer = new CPWL_Timer(this, GetSystemHandler()); 67 68 if (m_pTimer) 69 m_pTimer->SetPWLTimer(nElapse); 70 } 71 72 void CPWL_TimerHandler::EndTimer() { 73 if (m_pTimer) 74 m_pTimer->KillPWLTimer(); 75 } 76 77 void CPWL_TimerHandler::TimerProc() {} 78 79 class CPWL_MsgControl { 80 friend class CPWL_Wnd; 81 82 public: 83 explicit CPWL_MsgControl(CPWL_Wnd* pWnd) { 84 m_pCreatedWnd = pWnd; 85 Default(); 86 } 87 88 ~CPWL_MsgControl() { 89 Default(); 90 } 91 92 void Default() { 93 m_aMousePath.RemoveAll(); 94 m_aKeyboardPath.RemoveAll(); 95 m_pMainMouseWnd = NULL; 96 m_pMainKeyboardWnd = NULL; 97 } 98 99 FX_BOOL IsWndCreated(const CPWL_Wnd* pWnd) const { 100 return m_pCreatedWnd == pWnd; 101 } 102 103 FX_BOOL IsMainCaptureMouse(const CPWL_Wnd* pWnd) const { 104 return pWnd == m_pMainMouseWnd; 105 } 106 107 FX_BOOL IsWndCaptureMouse(const CPWL_Wnd* pWnd) const { 108 if (pWnd) { 109 for (int32_t i = 0, sz = m_aMousePath.GetSize(); i < sz; i++) { 110 if (m_aMousePath.GetAt(i) == pWnd) 111 return TRUE; 112 } 113 } 114 115 return FALSE; 116 } 117 118 FX_BOOL IsMainCaptureKeyboard(const CPWL_Wnd* pWnd) const { 119 return pWnd == m_pMainKeyboardWnd; 120 } 121 122 FX_BOOL IsWndCaptureKeyboard(const CPWL_Wnd* pWnd) const { 123 if (pWnd) { 124 for (int32_t i = 0, sz = m_aKeyboardPath.GetSize(); i < sz; i++) { 125 if (m_aKeyboardPath.GetAt(i) == pWnd) 126 return TRUE; 127 } 128 } 129 130 return FALSE; 131 } 132 133 void SetFocus(CPWL_Wnd* pWnd) { 134 m_aKeyboardPath.RemoveAll(); 135 136 if (pWnd) { 137 m_pMainKeyboardWnd = pWnd; 138 139 CPWL_Wnd* pParent = pWnd; 140 while (pParent) { 141 m_aKeyboardPath.Add(pParent); 142 pParent = pParent->GetParentWindow(); 143 } 144 145 pWnd->OnSetFocus(); 146 } 147 } 148 149 void KillFocus() { 150 if (m_aKeyboardPath.GetSize() > 0) 151 if (CPWL_Wnd* pWnd = m_aKeyboardPath.GetAt(0)) 152 pWnd->OnKillFocus(); 153 154 m_pMainKeyboardWnd = NULL; 155 m_aKeyboardPath.RemoveAll(); 156 } 157 158 void SetCapture(CPWL_Wnd* pWnd) { 159 m_aMousePath.RemoveAll(); 160 161 if (pWnd) { 162 m_pMainMouseWnd = pWnd; 163 164 CPWL_Wnd* pParent = pWnd; 165 while (pParent) { 166 m_aMousePath.Add(pParent); 167 pParent = pParent->GetParentWindow(); 168 } 169 } 170 } 171 172 void ReleaseCapture() { 173 m_pMainMouseWnd = NULL; 174 m_aMousePath.RemoveAll(); 175 } 176 177 private: 178 CFX_ArrayTemplate<CPWL_Wnd*> m_aMousePath; 179 CFX_ArrayTemplate<CPWL_Wnd*> m_aKeyboardPath; 180 CPWL_Wnd* m_pCreatedWnd; 181 CPWL_Wnd* m_pMainMouseWnd; 182 CPWL_Wnd* m_pMainKeyboardWnd; 183 }; 184 185 CPWL_Wnd::CPWL_Wnd() 186 : m_pVScrollBar(NULL), 187 m_rcWindow(), 188 m_rcClip(), 189 m_bCreated(FALSE), 190 m_bVisible(FALSE), 191 m_bNotifying(FALSE), 192 m_bEnabled(TRUE) {} 193 194 CPWL_Wnd::~CPWL_Wnd() { 195 ASSERT(m_bCreated == FALSE); 196 } 197 198 CFX_ByteString CPWL_Wnd::GetClassName() const { 199 return "CPWL_Wnd"; 200 } 201 202 void CPWL_Wnd::Create(const PWL_CREATEPARAM& cp) { 203 if (!IsValid()) { 204 m_sPrivateParam = cp; 205 206 OnCreate(m_sPrivateParam); 207 208 m_sPrivateParam.rcRectWnd.Normalize(); 209 m_rcWindow = m_sPrivateParam.rcRectWnd; 210 m_rcClip = CPWL_Utils::InflateRect(m_rcWindow, 1.0f); 211 212 CreateMsgControl(); 213 214 if (m_sPrivateParam.pParentWnd) 215 m_sPrivateParam.pParentWnd->OnNotify(this, PNM_ADDCHILD); 216 217 PWL_CREATEPARAM ccp = m_sPrivateParam; 218 219 ccp.dwFlags &= 0xFFFF0000L; // remove sub styles 220 ccp.mtChild = CFX_Matrix(1, 0, 0, 1, 0, 0); 221 222 CreateScrollBar(ccp); 223 CreateChildWnd(ccp); 224 225 m_bVisible = HasFlag(PWS_VISIBLE); 226 227 OnCreated(); 228 229 RePosChildWnd(); 230 m_bCreated = TRUE; 231 } 232 } 233 234 void CPWL_Wnd::OnCreate(PWL_CREATEPARAM& cp) {} 235 236 void CPWL_Wnd::OnCreated() {} 237 238 void CPWL_Wnd::OnDestroy() {} 239 240 void CPWL_Wnd::InvalidateFocusHandler(IPWL_FocusHandler* handler) { 241 if (m_sPrivateParam.pFocusHandler == handler) 242 m_sPrivateParam.pFocusHandler = nullptr; 243 } 244 245 void CPWL_Wnd::InvalidateProvider(IPWL_Provider* provider) { 246 if (m_sPrivateParam.pProvider == provider) 247 m_sPrivateParam.pProvider = nullptr; 248 } 249 250 void CPWL_Wnd::Destroy() { 251 KillFocus(); 252 253 OnDestroy(); 254 255 if (m_bCreated) { 256 for (int32_t i = m_aChildren.GetSize() - 1; i >= 0; i--) { 257 if (CPWL_Wnd* pChild = m_aChildren[i]) { 258 pChild->Destroy(); 259 delete pChild; 260 pChild = NULL; 261 } 262 } 263 264 if (m_sPrivateParam.pParentWnd) 265 m_sPrivateParam.pParentWnd->OnNotify(this, PNM_REMOVECHILD); 266 m_bCreated = FALSE; 267 } 268 269 DestroyMsgControl(); 270 271 FXSYS_memset(&m_sPrivateParam, 0, sizeof(PWL_CREATEPARAM)); 272 m_aChildren.RemoveAll(); 273 m_pVScrollBar = NULL; 274 } 275 276 void CPWL_Wnd::Move(const CPDF_Rect& rcNew, FX_BOOL bReset, FX_BOOL bRefresh) { 277 if (IsValid()) { 278 CPDF_Rect rcOld = GetWindowRect(); 279 280 m_rcWindow = rcNew; 281 m_rcWindow.Normalize(); 282 283 if (rcOld.left != rcNew.left || rcOld.right != rcNew.right || 284 rcOld.top != rcNew.top || rcOld.bottom != rcNew.bottom) { 285 if (bReset) { 286 RePosChildWnd(); 287 } 288 } 289 if (bRefresh) { 290 InvalidateRectMove(rcOld, rcNew); 291 } 292 293 m_sPrivateParam.rcRectWnd = m_rcWindow; 294 } 295 } 296 297 void CPWL_Wnd::InvalidateRectMove(const CPDF_Rect& rcOld, 298 const CPDF_Rect& rcNew) { 299 CPDF_Rect rcUnion = rcOld; 300 rcUnion.Union(rcNew); 301 302 InvalidateRect(&rcUnion); 303 } 304 305 void CPWL_Wnd::GetAppearanceStream(CFX_ByteTextBuf& sAppStream) { 306 if (IsValid() && IsVisible()) { 307 GetThisAppearanceStream(sAppStream); 308 GetChildAppearanceStream(sAppStream); 309 } 310 } 311 312 // if don't set,Get default apperance stream 313 void CPWL_Wnd::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) { 314 CPDF_Rect rectWnd = GetWindowRect(); 315 if (!rectWnd.IsEmpty()) { 316 CFX_ByteTextBuf sThis; 317 318 if (HasFlag(PWS_BACKGROUND)) 319 sThis << CPWL_Utils::GetRectFillAppStream(rectWnd, GetBackgroundColor()); 320 321 if (HasFlag(PWS_BORDER)) { 322 sThis << CPWL_Utils::GetBorderAppStream( 323 rectWnd, (FX_FLOAT)GetBorderWidth(), GetBorderColor(), 324 GetBorderLeftTopColor(GetBorderStyle()), 325 GetBorderRightBottomColor(GetBorderStyle()), GetBorderStyle(), 326 GetBorderDash()); 327 } 328 329 sAppStream << sThis; 330 } 331 } 332 333 void CPWL_Wnd::GetChildAppearanceStream(CFX_ByteTextBuf& sAppStream) { 334 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { 335 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { 336 pChild->GetAppearanceStream(sAppStream); 337 } 338 } 339 } 340 341 void CPWL_Wnd::DrawAppearance(CFX_RenderDevice* pDevice, 342 CFX_Matrix* pUser2Device) { 343 if (IsValid() && IsVisible()) { 344 DrawThisAppearance(pDevice, pUser2Device); 345 DrawChildAppearance(pDevice, pUser2Device); 346 } 347 } 348 349 void CPWL_Wnd::DrawThisAppearance(CFX_RenderDevice* pDevice, 350 CFX_Matrix* pUser2Device) { 351 CPDF_Rect rectWnd = GetWindowRect(); 352 if (!rectWnd.IsEmpty()) { 353 if (HasFlag(PWS_BACKGROUND)) { 354 CPDF_Rect rcClient = CPWL_Utils::DeflateRect( 355 rectWnd, (FX_FLOAT)(GetBorderWidth() + GetInnerBorderWidth())); 356 CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcClient, 357 GetBackgroundColor(), GetTransparency()); 358 } 359 360 if (HasFlag(PWS_BORDER)) 361 CPWL_Utils::DrawBorder(pDevice, pUser2Device, rectWnd, 362 (FX_FLOAT)GetBorderWidth(), GetBorderColor(), 363 GetBorderLeftTopColor(GetBorderStyle()), 364 GetBorderRightBottomColor(GetBorderStyle()), 365 GetBorderStyle(), GetTransparency()); 366 } 367 } 368 369 void CPWL_Wnd::DrawChildAppearance(CFX_RenderDevice* pDevice, 370 CFX_Matrix* pUser2Device) { 371 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { 372 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { 373 CFX_Matrix mt = pChild->GetChildMatrix(); 374 if (mt.IsIdentity()) { 375 pChild->DrawAppearance(pDevice, pUser2Device); 376 } else { 377 mt.Concat(*pUser2Device); 378 pChild->DrawAppearance(pDevice, &mt); 379 } 380 } 381 } 382 } 383 384 void CPWL_Wnd::InvalidateRect(CPDF_Rect* pRect) { 385 if (IsValid()) { 386 CPDF_Rect rcRefresh = pRect ? *pRect : GetWindowRect(); 387 388 if (!HasFlag(PWS_NOREFRESHCLIP)) { 389 CPDF_Rect rcClip = GetClipRect(); 390 if (!rcClip.IsEmpty()) { 391 rcRefresh.Intersect(rcClip); 392 } 393 } 394 395 FX_RECT rcWin = PWLtoWnd(rcRefresh); 396 rcWin.left -= PWL_INVALIDATE_INFLATE; 397 rcWin.top -= PWL_INVALIDATE_INFLATE; 398 rcWin.right += PWL_INVALIDATE_INFLATE; 399 rcWin.bottom += PWL_INVALIDATE_INFLATE; 400 401 if (IFX_SystemHandler* pSH = GetSystemHandler()) { 402 if (FX_HWND hWnd = GetAttachedHWnd()) { 403 pSH->InvalidateRect(hWnd, rcWin); 404 } 405 } 406 } 407 } 408 409 #define PWL_IMPLEMENT_KEY_METHOD(key_method_name) \ 410 FX_BOOL CPWL_Wnd::key_method_name(FX_WORD nChar, FX_DWORD nFlag) { \ 411 if (IsValid() && IsVisible() && IsEnabled()) { \ 412 if (IsWndCaptureKeyboard(this)) { \ 413 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { \ 414 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { \ 415 if (IsWndCaptureKeyboard(pChild)) { \ 416 return pChild->key_method_name(nChar, nFlag); \ 417 } \ 418 } \ 419 } \ 420 } \ 421 } \ 422 return FALSE; \ 423 } 424 425 #define PWL_IMPLEMENT_MOUSE_METHOD(mouse_method_name) \ 426 FX_BOOL CPWL_Wnd::mouse_method_name(const CPDF_Point& point, \ 427 FX_DWORD nFlag) { \ 428 if (IsValid() && IsVisible() && IsEnabled()) { \ 429 if (IsWndCaptureMouse(this)) { \ 430 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { \ 431 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { \ 432 if (IsWndCaptureMouse(pChild)) { \ 433 return pChild->mouse_method_name(pChild->ParentToChild(point), \ 434 nFlag); \ 435 } \ 436 } \ 437 } \ 438 SetCursor(); \ 439 } else { \ 440 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { \ 441 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { \ 442 if (pChild->WndHitTest(pChild->ParentToChild(point))) { \ 443 return pChild->mouse_method_name(pChild->ParentToChild(point), \ 444 nFlag); \ 445 } \ 446 } \ 447 } \ 448 if (WndHitTest(point)) \ 449 SetCursor(); \ 450 } \ 451 } \ 452 return FALSE; \ 453 } 454 455 PWL_IMPLEMENT_KEY_METHOD(OnKeyDown) 456 PWL_IMPLEMENT_KEY_METHOD(OnKeyUp) 457 PWL_IMPLEMENT_KEY_METHOD(OnChar) 458 459 PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonDblClk) 460 PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonDown) 461 PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonUp) 462 PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonDblClk) 463 PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonDown) 464 PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonUp) 465 PWL_IMPLEMENT_MOUSE_METHOD(OnRButtonDown) 466 PWL_IMPLEMENT_MOUSE_METHOD(OnRButtonUp) 467 PWL_IMPLEMENT_MOUSE_METHOD(OnMouseMove) 468 469 FX_BOOL CPWL_Wnd::OnMouseWheel(short zDelta, 470 const CPDF_Point& point, 471 FX_DWORD nFlag) { 472 if (IsValid() && IsVisible() && IsEnabled()) { 473 SetCursor(); 474 if (IsWndCaptureKeyboard(this)) { 475 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { 476 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { 477 if (IsWndCaptureKeyboard(pChild)) { 478 return pChild->OnMouseWheel(zDelta, pChild->ParentToChild(point), 479 nFlag); 480 } 481 } 482 } 483 } 484 } 485 return FALSE; 486 } 487 488 void CPWL_Wnd::AddChild(CPWL_Wnd* pWnd) { 489 m_aChildren.Add(pWnd); 490 } 491 492 void CPWL_Wnd::RemoveChild(CPWL_Wnd* pWnd) { 493 for (int32_t i = m_aChildren.GetSize() - 1; i >= 0; i--) { 494 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { 495 if (pChild == pWnd) { 496 m_aChildren.RemoveAt(i); 497 break; 498 } 499 } 500 } 501 } 502 503 void CPWL_Wnd::OnNotify(CPWL_Wnd* pWnd, 504 FX_DWORD msg, 505 intptr_t wParam, 506 intptr_t lParam) { 507 switch (msg) { 508 case PNM_ADDCHILD: 509 AddChild(pWnd); 510 break; 511 case PNM_REMOVECHILD: 512 RemoveChild(pWnd); 513 break; 514 default: 515 break; 516 } 517 } 518 519 FX_BOOL CPWL_Wnd::IsValid() const { 520 return m_bCreated; 521 } 522 523 const PWL_CREATEPARAM& CPWL_Wnd::GetCreationParam() const { 524 return m_sPrivateParam; 525 } 526 527 CPWL_Wnd* CPWL_Wnd::GetParentWindow() const { 528 return m_sPrivateParam.pParentWnd; 529 } 530 531 CPDF_Rect CPWL_Wnd::GetWindowRect() const { 532 return m_rcWindow; 533 } 534 535 CPDF_Rect CPWL_Wnd::GetClientRect() const { 536 CPDF_Rect rcWindow = GetWindowRect(); 537 CPDF_Rect rcClient = CPWL_Utils::DeflateRect( 538 rcWindow, (FX_FLOAT)(GetBorderWidth() + GetInnerBorderWidth())); 539 if (CPWL_ScrollBar* pVSB = GetVScrollBar()) 540 rcClient.right -= pVSB->GetScrollBarWidth(); 541 542 rcClient.Normalize(); 543 return rcWindow.Contains(rcClient) ? rcClient : CPDF_Rect(); 544 } 545 546 CPDF_Point CPWL_Wnd::GetCenterPoint() const { 547 CPDF_Rect rcClient = GetClientRect(); 548 return CPDF_Point((rcClient.left + rcClient.right) * 0.5f, 549 (rcClient.top + rcClient.bottom) * 0.5f); 550 } 551 552 FX_BOOL CPWL_Wnd::HasFlag(FX_DWORD dwFlags) const { 553 return (m_sPrivateParam.dwFlags & dwFlags) != 0; 554 } 555 556 void CPWL_Wnd::RemoveFlag(FX_DWORD dwFlags) { 557 m_sPrivateParam.dwFlags &= ~dwFlags; 558 } 559 560 void CPWL_Wnd::AddFlag(FX_DWORD dwFlags) { 561 m_sPrivateParam.dwFlags |= dwFlags; 562 } 563 564 CPWL_Color CPWL_Wnd::GetBackgroundColor() const { 565 return m_sPrivateParam.sBackgroundColor; 566 } 567 568 void CPWL_Wnd::SetBackgroundColor(const CPWL_Color& color) { 569 m_sPrivateParam.sBackgroundColor = color; 570 } 571 572 void CPWL_Wnd::SetTextColor(const CPWL_Color& color) { 573 m_sPrivateParam.sTextColor = color; 574 } 575 576 void CPWL_Wnd::SetTextStrokeColor(const CPWL_Color& color) { 577 m_sPrivateParam.sTextStrokeColor = color; 578 } 579 580 CPWL_Color CPWL_Wnd::GetTextColor() const { 581 return m_sPrivateParam.sTextColor; 582 } 583 584 CPWL_Color CPWL_Wnd::GetTextStrokeColor() const { 585 return m_sPrivateParam.sTextStrokeColor; 586 } 587 588 int32_t CPWL_Wnd::GetBorderStyle() const { 589 return m_sPrivateParam.nBorderStyle; 590 } 591 592 void CPWL_Wnd::SetBorderStyle(int32_t nBorderStyle) { 593 if (HasFlag(PWS_BORDER)) 594 m_sPrivateParam.nBorderStyle = nBorderStyle; 595 } 596 597 int32_t CPWL_Wnd::GetBorderWidth() const { 598 if (HasFlag(PWS_BORDER)) 599 return m_sPrivateParam.dwBorderWidth; 600 601 return 0; 602 } 603 604 int32_t CPWL_Wnd::GetInnerBorderWidth() const { 605 return 0; 606 } 607 608 CPWL_Color CPWL_Wnd::GetBorderColor() const { 609 if (HasFlag(PWS_BORDER)) 610 return m_sPrivateParam.sBorderColor; 611 612 return CPWL_Color(); 613 } 614 615 const CPWL_Dash& CPWL_Wnd::GetBorderDash() const { 616 return m_sPrivateParam.sDash; 617 } 618 619 void* CPWL_Wnd::GetAttachedData() const { 620 return m_sPrivateParam.pAttachedData; 621 } 622 623 CPWL_ScrollBar* CPWL_Wnd::GetVScrollBar() const { 624 if (HasFlag(PWS_VSCROLL)) 625 return m_pVScrollBar; 626 627 return NULL; 628 } 629 630 void CPWL_Wnd::CreateScrollBar(const PWL_CREATEPARAM& cp) { 631 CreateVScrollBar(cp); 632 } 633 634 void CPWL_Wnd::CreateVScrollBar(const PWL_CREATEPARAM& cp) { 635 if (!m_pVScrollBar && HasFlag(PWS_VSCROLL)) { 636 PWL_CREATEPARAM scp = cp; 637 638 // flags 639 scp.dwFlags = 640 PWS_CHILD | PWS_BACKGROUND | PWS_AUTOTRANSPARENT | PWS_NOREFRESHCLIP; 641 642 scp.pParentWnd = this; 643 scp.sBackgroundColor = PWL_DEFAULT_WHITECOLOR; 644 scp.eCursorType = FXCT_ARROW; 645 scp.nTransparency = PWL_SCROLLBAR_TRANSPARANCY; 646 647 m_pVScrollBar = new CPWL_ScrollBar(SBT_VSCROLL); 648 m_pVScrollBar->Create(scp); 649 } 650 } 651 652 void CPWL_Wnd::SetCapture() { 653 if (CPWL_MsgControl* pMsgCtrl = GetMsgControl()) 654 pMsgCtrl->SetCapture(this); 655 } 656 657 void CPWL_Wnd::ReleaseCapture() { 658 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) 659 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) 660 pChild->ReleaseCapture(); 661 662 if (CPWL_MsgControl* pMsgCtrl = GetMsgControl()) 663 pMsgCtrl->ReleaseCapture(); 664 } 665 666 void CPWL_Wnd::SetFocus() { 667 if (CPWL_MsgControl* pMsgCtrl = GetMsgControl()) { 668 if (!pMsgCtrl->IsMainCaptureKeyboard(this)) 669 pMsgCtrl->KillFocus(); 670 pMsgCtrl->SetFocus(this); 671 } 672 } 673 674 void CPWL_Wnd::KillFocus() { 675 if (CPWL_MsgControl* pMsgCtrl = GetMsgControl()) { 676 if (pMsgCtrl->IsWndCaptureKeyboard(this)) 677 pMsgCtrl->KillFocus(); 678 } 679 } 680 681 void CPWL_Wnd::OnSetFocus() {} 682 683 void CPWL_Wnd::OnKillFocus() {} 684 685 FX_BOOL CPWL_Wnd::WndHitTest(const CPDF_Point& point) const { 686 return IsValid() && IsVisible() && GetWindowRect().Contains(point.x, point.y); 687 } 688 689 FX_BOOL CPWL_Wnd::ClientHitTest(const CPDF_Point& point) const { 690 return IsValid() && IsVisible() && GetClientRect().Contains(point.x, point.y); 691 } 692 693 const CPWL_Wnd* CPWL_Wnd::GetRootWnd() const { 694 if (m_sPrivateParam.pParentWnd) 695 return m_sPrivateParam.pParentWnd->GetRootWnd(); 696 697 return this; 698 } 699 700 void CPWL_Wnd::SetVisible(FX_BOOL bVisible) { 701 if (IsValid()) { 702 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { 703 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { 704 pChild->SetVisible(bVisible); 705 } 706 } 707 708 if (bVisible != m_bVisible) { 709 m_bVisible = bVisible; 710 RePosChildWnd(); 711 InvalidateRect(); 712 } 713 } 714 } 715 716 void CPWL_Wnd::SetClipRect(const CPDF_Rect& rect) { 717 m_rcClip = rect; 718 m_rcClip.Normalize(); 719 } 720 721 const CPDF_Rect& CPWL_Wnd::GetClipRect() const { 722 return m_rcClip; 723 } 724 725 FX_BOOL CPWL_Wnd::IsReadOnly() const { 726 return HasFlag(PWS_READONLY); 727 } 728 729 void CPWL_Wnd::RePosChildWnd() { 730 CPDF_Rect rcContent = CPWL_Utils::DeflateRect( 731 GetWindowRect(), (FX_FLOAT)(GetBorderWidth() + GetInnerBorderWidth())); 732 733 CPWL_ScrollBar* pVSB = GetVScrollBar(); 734 735 CPDF_Rect rcVScroll = 736 CPDF_Rect(rcContent.right - PWL_SCROLLBAR_WIDTH, rcContent.bottom, 737 rcContent.right - 1.0f, rcContent.top); 738 739 if (pVSB) 740 pVSB->Move(rcVScroll, TRUE, FALSE); 741 } 742 743 void CPWL_Wnd::CreateChildWnd(const PWL_CREATEPARAM& cp) {} 744 745 void CPWL_Wnd::SetCursor() { 746 if (IsValid()) { 747 if (IFX_SystemHandler* pSH = GetSystemHandler()) { 748 int32_t nCursorType = GetCreationParam().eCursorType; 749 pSH->SetCursor(nCursorType); 750 } 751 } 752 } 753 754 void CPWL_Wnd::CreateMsgControl() { 755 if (!m_sPrivateParam.pMsgControl) 756 m_sPrivateParam.pMsgControl = new CPWL_MsgControl(this); 757 } 758 759 void CPWL_Wnd::DestroyMsgControl() { 760 if (CPWL_MsgControl* pMsgControl = GetMsgControl()) 761 if (pMsgControl->IsWndCreated(this)) 762 delete pMsgControl; 763 } 764 765 CPWL_MsgControl* CPWL_Wnd::GetMsgControl() const { 766 return m_sPrivateParam.pMsgControl; 767 } 768 769 FX_BOOL CPWL_Wnd::IsCaptureMouse() const { 770 return IsWndCaptureMouse(this); 771 } 772 773 FX_BOOL CPWL_Wnd::IsWndCaptureMouse(const CPWL_Wnd* pWnd) const { 774 if (CPWL_MsgControl* pCtrl = GetMsgControl()) 775 return pCtrl->IsWndCaptureMouse(pWnd); 776 777 return FALSE; 778 } 779 780 FX_BOOL CPWL_Wnd::IsWndCaptureKeyboard(const CPWL_Wnd* pWnd) const { 781 if (CPWL_MsgControl* pCtrl = GetMsgControl()) 782 return pCtrl->IsWndCaptureKeyboard(pWnd); 783 784 return FALSE; 785 } 786 787 FX_BOOL CPWL_Wnd::IsFocused() const { 788 if (CPWL_MsgControl* pCtrl = GetMsgControl()) 789 return pCtrl->IsMainCaptureKeyboard(this); 790 791 return FALSE; 792 } 793 794 CPDF_Rect CPWL_Wnd::GetFocusRect() const { 795 return CPWL_Utils::InflateRect(GetWindowRect(), 1); 796 } 797 798 FX_FLOAT CPWL_Wnd::GetFontSize() const { 799 return m_sPrivateParam.fFontSize; 800 } 801 802 void CPWL_Wnd::SetFontSize(FX_FLOAT fFontSize) { 803 m_sPrivateParam.fFontSize = fFontSize; 804 } 805 806 IFX_SystemHandler* CPWL_Wnd::GetSystemHandler() const { 807 return m_sPrivateParam.pSystemHandler; 808 } 809 810 IPWL_FocusHandler* CPWL_Wnd::GetFocusHandler() const { 811 return m_sPrivateParam.pFocusHandler; 812 } 813 814 IPWL_Provider* CPWL_Wnd::GetProvider() const { 815 return m_sPrivateParam.pProvider; 816 } 817 818 IFX_Edit_FontMap* CPWL_Wnd::GetFontMap() const { 819 return m_sPrivateParam.pFontMap; 820 } 821 822 CPWL_Color CPWL_Wnd::GetBorderLeftTopColor(int32_t nBorderStyle) const { 823 CPWL_Color color; 824 825 switch (nBorderStyle) { 826 case PBS_SOLID: 827 break; 828 case PBS_DASH: 829 break; 830 case PBS_BEVELED: 831 color = CPWL_Color(COLORTYPE_GRAY, 1); 832 break; 833 case PBS_INSET: 834 color = CPWL_Color(COLORTYPE_GRAY, 0.5f); 835 break; 836 case PBS_UNDERLINED: 837 break; 838 } 839 840 return color; 841 } 842 843 CPWL_Color CPWL_Wnd::GetBorderRightBottomColor(int32_t nBorderStyle) const { 844 CPWL_Color color; 845 846 switch (nBorderStyle) { 847 case PBS_SOLID: 848 break; 849 case PBS_DASH: 850 break; 851 case PBS_BEVELED: 852 color = CPWL_Utils::DevideColor(GetBackgroundColor(), 2); 853 break; 854 case PBS_INSET: 855 color = CPWL_Color(COLORTYPE_GRAY, 0.75f); 856 break; 857 case PBS_UNDERLINED: 858 break; 859 } 860 861 return color; 862 } 863 864 int32_t CPWL_Wnd::GetTransparency() { 865 return m_sPrivateParam.nTransparency; 866 } 867 868 void CPWL_Wnd::SetTransparency(int32_t nTransparency) { 869 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { 870 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { 871 pChild->SetTransparency(nTransparency); 872 } 873 } 874 875 m_sPrivateParam.nTransparency = nTransparency; 876 } 877 878 CFX_Matrix CPWL_Wnd::GetWindowMatrix() const { 879 CFX_Matrix mt = GetChildToRoot(); 880 881 if (IPWL_Provider* pProvider = GetProvider()) { 882 mt.Concat(pProvider->GetWindowMatrix(GetAttachedData())); 883 return mt; 884 } 885 886 return mt; 887 } 888 889 void CPWL_Wnd::PWLtoWnd(const CPDF_Point& point, int32_t& x, int32_t& y) const { 890 CFX_Matrix mt = GetWindowMatrix(); 891 CPDF_Point pt = point; 892 mt.Transform(pt.x, pt.y); 893 x = (int32_t)(pt.x + 0.5); 894 y = (int32_t)(pt.y + 0.5); 895 } 896 897 FX_RECT CPWL_Wnd::PWLtoWnd(const CPDF_Rect& rect) const { 898 CPDF_Rect rcTemp = rect; 899 CFX_Matrix mt = GetWindowMatrix(); 900 mt.TransformRect(rcTemp); 901 return FX_RECT((int32_t)(rcTemp.left + 0.5), (int32_t)(rcTemp.bottom + 0.5), 902 (int32_t)(rcTemp.right + 0.5), (int32_t)(rcTemp.top + 0.5)); 903 } 904 905 FX_HWND CPWL_Wnd::GetAttachedHWnd() const { 906 return m_sPrivateParam.hAttachedWnd; 907 } 908 909 CPDF_Point CPWL_Wnd::ChildToParent(const CPDF_Point& point) const { 910 CFX_Matrix mt = GetChildMatrix(); 911 if (mt.IsIdentity()) 912 return point; 913 914 CPDF_Point pt = point; 915 mt.Transform(pt.x, pt.y); 916 return pt; 917 } 918 919 CPDF_Rect CPWL_Wnd::ChildToParent(const CPDF_Rect& rect) const { 920 CFX_Matrix mt = GetChildMatrix(); 921 if (mt.IsIdentity()) 922 return rect; 923 924 CPDF_Rect rc = rect; 925 mt.TransformRect(rc); 926 return rc; 927 } 928 929 CPDF_Point CPWL_Wnd::ParentToChild(const CPDF_Point& point) const { 930 CFX_Matrix mt = GetChildMatrix(); 931 if (mt.IsIdentity()) 932 return point; 933 934 mt.SetReverse(mt); 935 CPDF_Point pt = point; 936 mt.Transform(pt.x, pt.y); 937 return pt; 938 } 939 940 CPDF_Rect CPWL_Wnd::ParentToChild(const CPDF_Rect& rect) const { 941 CFX_Matrix mt = GetChildMatrix(); 942 if (mt.IsIdentity()) 943 return rect; 944 945 mt.SetReverse(mt); 946 CPDF_Rect rc = rect; 947 mt.TransformRect(rc); 948 return rc; 949 } 950 951 CFX_Matrix CPWL_Wnd::GetChildToRoot() const { 952 CFX_Matrix mt(1, 0, 0, 1, 0, 0); 953 if (HasFlag(PWS_CHILD)) { 954 const CPWL_Wnd* pParent = this; 955 while (pParent) { 956 mt.Concat(pParent->GetChildMatrix()); 957 pParent = pParent->GetParentWindow(); 958 } 959 } 960 return mt; 961 } 962 963 CFX_Matrix CPWL_Wnd::GetChildMatrix() const { 964 if (HasFlag(PWS_CHILD)) 965 return m_sPrivateParam.mtChild; 966 967 return CFX_Matrix(1, 0, 0, 1, 0, 0); 968 } 969 970 void CPWL_Wnd::SetChildMatrix(const CFX_Matrix& mt) { 971 m_sPrivateParam.mtChild = mt; 972 } 973 974 const CPWL_Wnd* CPWL_Wnd::GetFocused() const { 975 if (CPWL_MsgControl* pMsgCtrl = GetMsgControl()) { 976 return pMsgCtrl->m_pMainKeyboardWnd; 977 } 978 979 return NULL; 980 } 981 982 void CPWL_Wnd::EnableWindow(FX_BOOL bEnable) { 983 if (m_bEnabled != bEnable) { 984 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { 985 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { 986 pChild->EnableWindow(bEnable); 987 } 988 } 989 990 m_bEnabled = bEnable; 991 992 if (bEnable) 993 OnEnabled(); 994 else 995 OnDisabled(); 996 } 997 } 998 999 FX_BOOL CPWL_Wnd::IsEnabled() { 1000 return m_bEnabled; 1001 } 1002 1003 void CPWL_Wnd::OnEnabled() {} 1004 1005 void CPWL_Wnd::OnDisabled() {} 1006 1007 FX_BOOL CPWL_Wnd::IsCTRLpressed(FX_DWORD nFlag) const { 1008 if (IFX_SystemHandler* pSystemHandler = GetSystemHandler()) { 1009 return pSystemHandler->IsCTRLKeyDown(nFlag); 1010 } 1011 1012 return FALSE; 1013 } 1014 1015 FX_BOOL CPWL_Wnd::IsSHIFTpressed(FX_DWORD nFlag) const { 1016 if (IFX_SystemHandler* pSystemHandler = GetSystemHandler()) { 1017 return pSystemHandler->IsSHIFTKeyDown(nFlag); 1018 } 1019 1020 return FALSE; 1021 } 1022 1023 FX_BOOL CPWL_Wnd::IsALTpressed(FX_DWORD nFlag) const { 1024 if (IFX_SystemHandler* pSystemHandler = GetSystemHandler()) { 1025 return pSystemHandler->IsALTKeyDown(nFlag); 1026 } 1027 1028 return FALSE; 1029 } 1030 1031 FX_BOOL CPWL_Wnd::IsINSERTpressed(FX_DWORD nFlag) const { 1032 if (IFX_SystemHandler* pSystemHandler = GetSystemHandler()) { 1033 return pSystemHandler->IsINSERTKeyDown(nFlag); 1034 } 1035 1036 return FALSE; 1037 } 1038