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 "../../include/pdfwindow/PDFWindow.h" 8 #include "../../include/pdfwindow/PWL_Wnd.h" 9 #include "../../include/pdfwindow/PWL_Utils.h" 10 #include "../../include/pdfwindow/PWL_ScrollBar.h" 11 12 /* -------------------------- CPWL_Timer -------------------------- */ 13 14 static CFX_MapPtrTemplate<FX_INT32, CPWL_Timer*>& GetPWLTimeMap() 15 { 16 // Leak the object at shutdown. 17 static auto timeMap = new CFX_MapPtrTemplate<FX_INT32, CPWL_Timer*>; 18 return *timeMap; 19 } 20 21 CPWL_Timer::CPWL_Timer(CPWL_TimerHandler* pAttached, IFX_SystemHandler* pSystemHandler) : 22 m_nTimerID(0), 23 m_pAttached(pAttached), 24 m_pSystemHandler(pSystemHandler) 25 { 26 ASSERT(m_pAttached != NULL); 27 ASSERT(m_pSystemHandler != NULL); 28 } 29 30 CPWL_Timer::~CPWL_Timer() 31 { 32 KillPWLTimer(); 33 } 34 35 FX_INT32 CPWL_Timer::SetPWLTimer(FX_INT32 nElapse) 36 { 37 if (m_nTimerID != 0) KillPWLTimer(); 38 m_nTimerID = m_pSystemHandler->SetTimer(nElapse, TimerProc); 39 GetPWLTimeMap().SetAt(m_nTimerID, this); 40 return m_nTimerID; 41 } 42 43 void CPWL_Timer::KillPWLTimer() 44 { 45 if (m_nTimerID != 0) 46 { 47 m_pSystemHandler->KillTimer(m_nTimerID); 48 GetPWLTimeMap().RemoveKey(m_nTimerID); 49 m_nTimerID = 0; 50 } 51 } 52 53 void CPWL_Timer::TimerProc(FX_INT32 idEvent) 54 { 55 CPWL_Timer* pTimer = NULL; 56 if (GetPWLTimeMap().Lookup(idEvent, pTimer)) 57 { 58 if (pTimer) 59 { 60 if (pTimer->m_pAttached) 61 pTimer->m_pAttached->TimerProc(); 62 } 63 } 64 } 65 66 /* -------------------------- CPWL_TimerHandler -------------------------- */ 67 68 CPWL_TimerHandler::CPWL_TimerHandler() : m_pTimer(NULL) 69 { 70 } 71 72 CPWL_TimerHandler::~CPWL_TimerHandler() 73 { 74 if (m_pTimer) delete m_pTimer; 75 } 76 77 void CPWL_TimerHandler::BeginTimer(FX_INT32 nElapse) 78 { 79 if (!m_pTimer) 80 m_pTimer = new CPWL_Timer(this, GetSystemHandler()); 81 82 if (m_pTimer) 83 m_pTimer->SetPWLTimer(nElapse); 84 } 85 86 void CPWL_TimerHandler::EndTimer() 87 { 88 if (m_pTimer) 89 m_pTimer->KillPWLTimer(); 90 } 91 92 void CPWL_TimerHandler::TimerProc() 93 { 94 } 95 96 /* --------------------------- CPWL_MsgControl ---------------------------- */ 97 98 class CPWL_MsgControl 99 { 100 friend class CPWL_Wnd; 101 102 public: 103 CPWL_MsgControl(CPWL_Wnd * pWnd) 104 { 105 // PWL_TRACE("new CPWL_MsgControl\n"); 106 m_pCreatedWnd = pWnd; 107 Default(); 108 } 109 110 ~CPWL_MsgControl() 111 { 112 // PWL_TRACE("~CPWL_MsgControl\n"); 113 Default(); 114 } 115 116 void Default() 117 { 118 m_aMousePath.RemoveAll(); 119 m_aKeyboardPath.RemoveAll(); 120 m_pMainMouseWnd = NULL; 121 m_pMainKeyboardWnd = NULL; 122 } 123 124 FX_BOOL IsWndCreated(const CPWL_Wnd * pWnd) const 125 { 126 return m_pCreatedWnd == pWnd; 127 } 128 129 FX_BOOL IsMainCaptureMouse(const CPWL_Wnd * pWnd) const 130 { 131 return pWnd == m_pMainMouseWnd; 132 } 133 134 FX_BOOL IsWndCaptureMouse(const CPWL_Wnd * pWnd) const 135 { 136 if (pWnd) 137 for( FX_INT32 i=0,sz=m_aMousePath.GetSize(); i<sz; i++) 138 if (m_aMousePath.GetAt(i) == pWnd) 139 return TRUE; 140 141 return FALSE; 142 } 143 144 FX_BOOL IsMainCaptureKeyboard(const CPWL_Wnd * pWnd) const 145 { 146 return pWnd == m_pMainKeyboardWnd; 147 } 148 149 150 FX_BOOL IsWndCaptureKeyboard(const CPWL_Wnd * pWnd) const 151 { 152 if (pWnd) 153 for( FX_INT32 i=0,sz=m_aKeyboardPath.GetSize(); i<sz; i++) 154 if (m_aKeyboardPath.GetAt(i) == pWnd) 155 return TRUE; 156 157 return FALSE; 158 } 159 160 void SetFocus(CPWL_Wnd * pWnd) 161 { 162 m_aKeyboardPath.RemoveAll(); 163 164 if (pWnd) 165 { 166 m_pMainKeyboardWnd = pWnd; 167 168 CPWL_Wnd * pParent = pWnd; 169 while (pParent) 170 { 171 m_aKeyboardPath.Add(pParent); 172 pParent = pParent->GetParentWindow(); 173 } 174 175 pWnd->OnSetFocus(); 176 } 177 } 178 179 void KillFocus() 180 { 181 if (m_aKeyboardPath.GetSize() > 0) 182 if (CPWL_Wnd* pWnd = m_aKeyboardPath.GetAt(0)) 183 pWnd->OnKillFocus(); 184 185 m_pMainKeyboardWnd = NULL; 186 m_aKeyboardPath.RemoveAll(); 187 } 188 189 void SetCapture(CPWL_Wnd * pWnd) 190 { 191 m_aMousePath.RemoveAll(); 192 193 if (pWnd) 194 { 195 m_pMainMouseWnd = pWnd; 196 197 CPWL_Wnd * pParent = pWnd; 198 while (pParent) 199 { 200 m_aMousePath.Add(pParent); 201 pParent = pParent->GetParentWindow(); 202 } 203 } 204 } 205 206 void ReleaseCapture() 207 { 208 m_pMainMouseWnd = NULL; 209 m_aMousePath.RemoveAll(); 210 } 211 212 private: 213 CFX_ArrayTemplate<CPWL_Wnd*> m_aMousePath; 214 CFX_ArrayTemplate<CPWL_Wnd*> m_aKeyboardPath; 215 CPWL_Wnd* m_pCreatedWnd; 216 CPWL_Wnd* m_pMainMouseWnd; 217 CPWL_Wnd* m_pMainKeyboardWnd; 218 }; 219 220 /* --------------------------- CPWL_Wnd ---------------------------- */ 221 222 CPWL_Wnd::CPWL_Wnd() : 223 m_pVScrollBar(NULL), 224 m_rcWindow(), 225 m_rcClip(), 226 m_bCreated(FALSE), 227 m_bVisible(FALSE), 228 m_bNotifying(FALSE), 229 m_bEnabled(TRUE) 230 { 231 } 232 233 CPWL_Wnd::~CPWL_Wnd() 234 { 235 ASSERT(m_bCreated == FALSE); 236 } 237 238 CFX_ByteString CPWL_Wnd::GetClassName() const 239 { 240 return "CPWL_Wnd"; 241 } 242 243 void CPWL_Wnd::Create(const PWL_CREATEPARAM & cp) 244 { 245 if (!IsValid()) 246 { 247 m_sPrivateParam = cp; 248 249 OnCreate(m_sPrivateParam); 250 251 m_sPrivateParam.rcRectWnd.Normalize(); 252 m_rcWindow = m_sPrivateParam.rcRectWnd; 253 m_rcClip = CPWL_Utils::InflateRect(m_rcWindow,1.0f); 254 255 CreateMsgControl(); 256 257 if (m_sPrivateParam.pParentWnd) 258 m_sPrivateParam.pParentWnd->OnNotify(this, PNM_ADDCHILD); 259 260 PWL_CREATEPARAM ccp = m_sPrivateParam; 261 262 ccp.dwFlags &= 0xFFFF0000L; //remove sub styles 263 ccp.mtChild = CPDF_Matrix(1,0,0,1,0,0); 264 265 CreateScrollBar(ccp); 266 CreateChildWnd(ccp); 267 268 m_bVisible = HasFlag(PWS_VISIBLE); 269 270 OnCreated(); 271 272 RePosChildWnd(); 273 m_bCreated = TRUE; 274 } 275 } 276 277 void CPWL_Wnd::OnCreate(PWL_CREATEPARAM & cp) 278 { 279 } 280 281 void CPWL_Wnd::OnCreated() 282 { 283 } 284 285 void CPWL_Wnd::OnDestroy() 286 { 287 } 288 289 void CPWL_Wnd::Destroy() 290 { 291 KillFocus(); 292 293 OnDestroy(); 294 295 if (m_bCreated) 296 { 297 for (FX_INT32 i = m_aChildren.GetSize()-1; i >= 0; i --) 298 { 299 if (CPWL_Wnd * pChild = m_aChildren[i]) 300 { 301 pChild->Destroy(); 302 delete pChild; 303 pChild = NULL; 304 } 305 } 306 307 if (m_sPrivateParam.pParentWnd) 308 m_sPrivateParam.pParentWnd->OnNotify(this, PNM_REMOVECHILD); 309 m_bCreated = FALSE; 310 } 311 312 DestroyMsgControl(); 313 314 FXSYS_memset(&m_sPrivateParam, 0, sizeof(PWL_CREATEPARAM)); 315 m_aChildren.RemoveAll(); 316 m_pVScrollBar = NULL; 317 } 318 319 void CPWL_Wnd::Move(const CPDF_Rect & rcNew, FX_BOOL bReset,FX_BOOL bRefresh) 320 { 321 if (IsValid()) 322 { 323 CPDF_Rect rcOld = this->GetWindowRect(); 324 325 m_rcWindow = rcNew; 326 m_rcWindow.Normalize(); 327 //m_rcClip = CPWL_Utils::InflateRect(m_rcWindow,1.0f); //for special caret 328 329 if (rcOld.left != rcNew.left || rcOld.right != rcNew.right || 330 rcOld.top != rcNew.top || rcOld.bottom != rcNew.bottom) 331 { 332 if (bReset) 333 { 334 RePosChildWnd(); 335 } 336 337 } 338 if (bRefresh) 339 { 340 InvalidateRectMove(rcOld,rcNew); 341 } 342 343 m_sPrivateParam.rcRectWnd = m_rcWindow; 344 } 345 } 346 347 void CPWL_Wnd::InvalidateRectMove(const CPDF_Rect & rcOld, const CPDF_Rect & rcNew) 348 { 349 CPDF_Rect rcUnion = rcOld; 350 rcUnion.Union(rcNew); 351 352 InvalidateRect(&rcUnion); 353 354 /* 355 CPDF_Rect SubArray[4]; 356 357 rcOld.Substract4(rcNew,SubArray); 358 for (FX_INT32 i=0;i<4;i++) 359 { 360 if (SubArray[i].left == 0 && 361 SubArray[i].right == 0 && 362 SubArray[i].top == 0 && 363 SubArray[i].bottom == 0)continue; 364 365 InvalidateRect(&CPWL_Utils::InflateRect(SubArray[i],2)); 366 } 367 368 rcNew.Substract4(rcOld,SubArray); 369 for (FX_INT32 j=0;j<4;j++) 370 { 371 if (SubArray[j].left == 0 && 372 SubArray[j].right == 0 && 373 SubArray[j].top == 0 && 374 SubArray[j].bottom == 0)continue; 375 376 InvalidateRect(&CPWL_Utils::InflateRect(SubArray[j],2)); 377 } 378 */ 379 } 380 381 void CPWL_Wnd::GetAppearanceStream(CFX_ByteString & sAppStream) 382 { 383 if (IsValid()) 384 { 385 CFX_ByteTextBuf sTextBuf; 386 GetAppearanceStream(sTextBuf); 387 sAppStream += sTextBuf.GetByteString(); 388 } 389 } 390 391 void CPWL_Wnd::GetAppearanceStream(CFX_ByteTextBuf & sAppStream) 392 { 393 if (IsValid() && IsVisible()) 394 { 395 GetThisAppearanceStream(sAppStream); 396 GetChildAppearanceStream(sAppStream); 397 } 398 } 399 400 //if don't set,Get default apperance stream 401 void CPWL_Wnd::GetThisAppearanceStream(CFX_ByteTextBuf & sAppStream) 402 { 403 CPDF_Rect rectWnd = GetWindowRect(); 404 if (!rectWnd.IsEmpty()) 405 { 406 CFX_ByteTextBuf sThis; 407 408 if (HasFlag(PWS_BACKGROUND)) 409 sThis << CPWL_Utils::GetRectFillAppStream(rectWnd,this->GetBackgroundColor()); 410 411 if (HasFlag(PWS_BORDER)) 412 sThis << CPWL_Utils::GetBorderAppStream(rectWnd, 413 (FX_FLOAT)GetBorderWidth(), 414 GetBorderColor(), 415 this->GetBorderLeftTopColor(this->GetBorderStyle()), 416 this->GetBorderRightBottomColor(this->GetBorderStyle()), 417 this->GetBorderStyle(), 418 this->GetBorderDash()); 419 420 sAppStream << sThis; 421 } 422 } 423 424 void CPWL_Wnd::GetChildAppearanceStream(CFX_ByteTextBuf & sAppStream) 425 { 426 for (FX_INT32 i=0,sz=m_aChildren.GetSize(); i<sz; i++) 427 { 428 if (CPWL_Wnd * pChild = m_aChildren.GetAt(i)) 429 { 430 pChild->GetAppearanceStream(sAppStream); 431 } 432 } 433 } 434 435 void CPWL_Wnd::DrawAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device) 436 { 437 if (IsValid() && IsVisible()) 438 { 439 DrawThisAppearance(pDevice,pUser2Device); 440 DrawChildAppearance(pDevice,pUser2Device); 441 } 442 } 443 444 void CPWL_Wnd::DrawThisAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device) 445 { 446 CPDF_Rect rectWnd = GetWindowRect(); 447 if (!rectWnd.IsEmpty()) 448 { 449 if (HasFlag(PWS_BACKGROUND)) 450 { 451 CPDF_Rect rcClient = CPWL_Utils::DeflateRect(rectWnd,(FX_FLOAT)(GetBorderWidth()+GetInnerBorderWidth())); 452 CPWL_Utils::DrawFillRect(pDevice,pUser2Device,rcClient,this->GetBackgroundColor(),GetTransparency()); 453 } 454 455 if (HasFlag(PWS_BORDER)) 456 CPWL_Utils::DrawBorder(pDevice, 457 pUser2Device, 458 rectWnd, 459 (FX_FLOAT)GetBorderWidth(), 460 GetBorderColor(), 461 this->GetBorderLeftTopColor(this->GetBorderStyle()), 462 this->GetBorderRightBottomColor(this->GetBorderStyle()), 463 this->GetBorderStyle(), 464 this->GetBorderDash(), 465 GetTransparency()); 466 } 467 } 468 469 void CPWL_Wnd::DrawChildAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device) 470 { 471 for (FX_INT32 i=0,sz=m_aChildren.GetSize(); i<sz; i++) 472 { 473 if (CPWL_Wnd * pChild = m_aChildren.GetAt(i)) 474 { 475 CPDF_Matrix mt = pChild->GetChildMatrix(); 476 if (mt.IsIdentity()) 477 { 478 pChild->DrawAppearance(pDevice,pUser2Device); 479 } 480 else 481 { 482 mt.Concat(*pUser2Device); 483 pChild->DrawAppearance(pDevice,&mt); 484 } 485 } 486 } 487 } 488 489 void CPWL_Wnd::InvalidateRect(CPDF_Rect* pRect) 490 { 491 if (IsValid()) 492 { 493 CPDF_Rect rcRefresh = pRect ? *pRect : GetWindowRect(); 494 495 if (!HasFlag(PWS_NOREFRESHCLIP)) 496 { 497 CPDF_Rect rcClip = GetClipRect(); 498 if (!rcClip.IsEmpty()) 499 { 500 rcRefresh.Intersect(rcClip); 501 } 502 } 503 504 FX_RECT rcWin = PWLtoWnd(rcRefresh); 505 rcWin.left -= PWL_INVALIDATE_INFLATE; 506 rcWin.top -= PWL_INVALIDATE_INFLATE; 507 rcWin.right += PWL_INVALIDATE_INFLATE; 508 rcWin.bottom += PWL_INVALIDATE_INFLATE; 509 510 if (IFX_SystemHandler* pSH = GetSystemHandler()) 511 { 512 if (FX_HWND hWnd = GetAttachedHWnd()) 513 { 514 pSH->InvalidateRect(hWnd, rcWin); 515 } 516 } 517 } 518 } 519 520 #define PWL_IMPLEMENT_KEY_METHOD(key_method_name)\ 521 FX_BOOL CPWL_Wnd::key_method_name(FX_WORD nChar, FX_DWORD nFlag)\ 522 {\ 523 if (IsValid() && IsVisible() && IsEnabled())\ 524 {\ 525 if (IsWndCaptureKeyboard(this))\ 526 {\ 527 for (FX_INT32 i=0,sz=m_aChildren.GetSize(); i<sz; i++)\ 528 {\ 529 if (CPWL_Wnd * pChild = m_aChildren.GetAt(i))\ 530 {\ 531 if (IsWndCaptureKeyboard(pChild))\ 532 {\ 533 return pChild->key_method_name(nChar,nFlag);\ 534 }\ 535 }\ 536 }\ 537 }\ 538 }\ 539 return FALSE;\ 540 } 541 542 #define PWL_IMPLEMENT_MOUSE_METHOD(mouse_method_name)\ 543 FX_BOOL CPWL_Wnd::mouse_method_name(const CPDF_Point & point, FX_DWORD nFlag)\ 544 {\ 545 if (IsValid() && IsVisible() && IsEnabled())\ 546 {\ 547 if (IsWndCaptureMouse(this))\ 548 {\ 549 for (FX_INT32 i=0,sz=m_aChildren.GetSize(); i<sz; i++)\ 550 {\ 551 if (CPWL_Wnd * pChild = m_aChildren.GetAt(i))\ 552 {\ 553 if (IsWndCaptureMouse(pChild))\ 554 {\ 555 return pChild->mouse_method_name(pChild->ParentToChild(point),nFlag);\ 556 }\ 557 }\ 558 }\ 559 SetCursor();\ 560 }\ 561 else\ 562 {\ 563 for (FX_INT32 i=0,sz=m_aChildren.GetSize(); i<sz; i++)\ 564 {\ 565 if (CPWL_Wnd * pChild = m_aChildren.GetAt(i))\ 566 {\ 567 if (pChild->WndHitTest(pChild->ParentToChild(point)))\ 568 {\ 569 return pChild->mouse_method_name(pChild->ParentToChild(point),nFlag);\ 570 }\ 571 }\ 572 }\ 573 if (this->WndHitTest(point))\ 574 SetCursor();\ 575 }\ 576 }\ 577 return FALSE;\ 578 } 579 580 PWL_IMPLEMENT_KEY_METHOD(OnKeyDown) 581 PWL_IMPLEMENT_KEY_METHOD(OnKeyUp) 582 PWL_IMPLEMENT_KEY_METHOD(OnChar) 583 584 PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonDblClk) 585 PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonDown) 586 PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonUp) 587 PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonDblClk) 588 PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonDown) 589 PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonUp) 590 PWL_IMPLEMENT_MOUSE_METHOD(OnRButtonDblClk) 591 PWL_IMPLEMENT_MOUSE_METHOD(OnRButtonDown) 592 PWL_IMPLEMENT_MOUSE_METHOD(OnRButtonUp) 593 PWL_IMPLEMENT_MOUSE_METHOD(OnMouseMove) 594 595 FX_BOOL CPWL_Wnd::OnMouseWheel(short zDelta, const CPDF_Point & point, FX_DWORD nFlag) 596 { 597 if (IsValid() && IsVisible() && IsEnabled()) 598 { 599 SetCursor(); 600 if (IsWndCaptureKeyboard(this)) 601 { 602 for (FX_INT32 i=0,sz=m_aChildren.GetSize(); i<sz; i++) 603 { 604 if (CPWL_Wnd * pChild = m_aChildren.GetAt(i)) 605 { 606 if (IsWndCaptureKeyboard(pChild)) 607 { 608 return pChild->OnMouseWheel(zDelta,pChild->ParentToChild(point), nFlag); 609 } 610 } 611 } 612 } 613 } 614 return FALSE; 615 } 616 617 void CPWL_Wnd::AddChild(CPWL_Wnd * pWnd) 618 { 619 m_aChildren.Add(pWnd); 620 } 621 622 void CPWL_Wnd::RemoveChild(CPWL_Wnd * pWnd) 623 { 624 for (FX_INT32 i = m_aChildren.GetSize()-1; i >= 0; i --) 625 { 626 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) 627 { 628 if (pChild == pWnd) 629 { 630 m_aChildren.RemoveAt(i); 631 break; 632 } 633 } 634 } 635 } 636 637 void CPWL_Wnd::OnNotify(CPWL_Wnd* pWnd, FX_DWORD msg, FX_INTPTR wParam, FX_INTPTR lParam) 638 { 639 switch (msg) 640 { 641 case PNM_ADDCHILD: 642 this->AddChild(pWnd); 643 break; 644 case PNM_REMOVECHILD: 645 this->RemoveChild(pWnd); 646 break; 647 default: 648 break; 649 } 650 } 651 652 FX_BOOL CPWL_Wnd::IsValid() const 653 { 654 return m_bCreated; 655 } 656 657 PWL_CREATEPARAM CPWL_Wnd::GetCreationParam() const 658 { 659 return m_sPrivateParam; 660 } 661 662 CPWL_Wnd* CPWL_Wnd::GetParentWindow() const 663 { 664 return m_sPrivateParam.pParentWnd; 665 } 666 667 CPDF_Rect CPWL_Wnd::GetOriginWindowRect() const 668 { 669 return m_sPrivateParam.rcRectWnd; 670 } 671 672 CPDF_Rect CPWL_Wnd::GetWindowRect() const 673 { 674 return m_rcWindow; 675 } 676 677 CPDF_Rect CPWL_Wnd::GetClientRect() const 678 { 679 CPDF_Rect rcWindow = GetWindowRect(); 680 CPDF_Rect rcClient = CPWL_Utils::DeflateRect(rcWindow,(FX_FLOAT)(GetBorderWidth()+GetInnerBorderWidth())); 681 682 if (CPWL_ScrollBar * pVSB = this->GetVScrollBar()) 683 rcClient.right -= pVSB->GetScrollBarWidth(); 684 685 rcClient.Normalize(); 686 687 if (rcWindow.Contains(rcClient)) 688 return rcClient; 689 else 690 return CPDF_Rect(); 691 } 692 693 CPDF_Point CPWL_Wnd::GetCenterPoint() const 694 { 695 CPDF_Rect rcClient = GetClientRect(); 696 697 return CPDF_Point((rcClient.left + rcClient.right) * 0.5f, 698 (rcClient.top + rcClient.bottom) * 0.5f); 699 } 700 701 CPDF_Rect CPWL_Wnd::GetClientCenterSquare() const 702 { 703 return CPWL_Utils::GetCenterSquare(GetClientRect()); 704 } 705 706 CPDF_Rect CPWL_Wnd::GetWindowCenterSquare() const 707 { 708 return CPWL_Utils::GetCenterSquare(CPWL_Utils::DeflateRect(GetWindowRect(),0.1f)); 709 } 710 711 FX_BOOL CPWL_Wnd::HasFlag(FX_DWORD dwFlags) const 712 { 713 return (m_sPrivateParam.dwFlags & dwFlags) != 0; 714 } 715 716 void CPWL_Wnd::RemoveFlag(FX_DWORD dwFlags) 717 { 718 m_sPrivateParam.dwFlags &= ~dwFlags; 719 } 720 721 void CPWL_Wnd::AddFlag(FX_DWORD dwFlags) 722 { 723 m_sPrivateParam.dwFlags |= dwFlags; 724 } 725 726 CPWL_Color CPWL_Wnd::GetBackgroundColor() const 727 { 728 return m_sPrivateParam.sBackgroundColor; 729 } 730 731 void CPWL_Wnd::SetBackgroundColor(const CPWL_Color & color) 732 { 733 m_sPrivateParam.sBackgroundColor = color; 734 } 735 736 void CPWL_Wnd::SetTextColor(const CPWL_Color & color) 737 { 738 m_sPrivateParam.sTextColor = color; 739 } 740 741 void CPWL_Wnd::SetTextStrokeColor(const CPWL_Color & color) 742 { 743 m_sPrivateParam.sTextStrokeColor = color; 744 } 745 746 CPWL_Color CPWL_Wnd::GetTextColor() const 747 { 748 return m_sPrivateParam.sTextColor; 749 } 750 751 CPWL_Color CPWL_Wnd::GetTextStrokeColor() const 752 { 753 return m_sPrivateParam.sTextStrokeColor; 754 } 755 756 FX_INT32 CPWL_Wnd::GetBorderStyle() const 757 { 758 return m_sPrivateParam.nBorderStyle; 759 } 760 761 void CPWL_Wnd::SetBorderStyle(FX_INT32 nBorderStyle) 762 { 763 if (HasFlag(PWS_BORDER)) 764 m_sPrivateParam.nBorderStyle = nBorderStyle; 765 } 766 767 FX_INT32 CPWL_Wnd::GetBorderWidth() const 768 { 769 if (HasFlag(PWS_BORDER)) 770 return m_sPrivateParam.dwBorderWidth; 771 772 return 0; 773 } 774 775 FX_INT32 CPWL_Wnd::GetInnerBorderWidth() const 776 { 777 /* 778 switch (GetBorderStyle()) 779 { 780 case PBS_BEVELED: 781 case PBS_INSET: 782 return GetBorderWidth() / 2; 783 } 784 */ 785 return 0; 786 } 787 788 void CPWL_Wnd::SetBorderWidth(FX_INT32 nBorderWidth) 789 { 790 if (HasFlag(PWS_BORDER)) 791 m_sPrivateParam.dwBorderWidth = nBorderWidth; 792 } 793 794 CPWL_Color CPWL_Wnd::GetBorderColor() const 795 { 796 if (HasFlag(PWS_BORDER)) 797 return m_sPrivateParam.sBorderColor; 798 799 return CPWL_Color(); 800 } 801 802 void CPWL_Wnd::SetBorderColor(const CPWL_Color & color) 803 { 804 if (HasFlag(PWS_BORDER)) 805 m_sPrivateParam.sBorderColor = color; 806 } 807 808 CPWL_Dash CPWL_Wnd::GetBorderDash() const 809 { 810 return m_sPrivateParam.sDash; 811 } 812 813 void* CPWL_Wnd::GetAttachedData() const 814 { 815 return m_sPrivateParam.pAttachedData; 816 } 817 818 void CPWL_Wnd::SetBorderDash(const CPWL_Dash & sDash) 819 { 820 if (HasFlag(PWS_BORDER)) 821 m_sPrivateParam.sDash = sDash; 822 } 823 824 CPWL_ScrollBar* CPWL_Wnd::GetVScrollBar() const 825 { 826 if (HasFlag(PWS_VSCROLL)) 827 return m_pVScrollBar; 828 829 return NULL; 830 } 831 832 void CPWL_Wnd::CreateScrollBar(const PWL_CREATEPARAM & cp) 833 { 834 CreateVScrollBar(cp); 835 } 836 837 void CPWL_Wnd::CreateVScrollBar(const PWL_CREATEPARAM & cp) 838 { 839 if (!m_pVScrollBar && HasFlag(PWS_VSCROLL)) 840 { 841 PWL_CREATEPARAM scp = cp; 842 843 //flags 844 scp.dwFlags = PWS_CHILD| PWS_BACKGROUND | PWS_AUTOTRANSPARENT | PWS_NOREFRESHCLIP; 845 846 scp.pParentWnd = this; 847 scp.sBackgroundColor = PWL_DEFAULT_WHITECOLOR; 848 scp.eCursorType = FXCT_ARROW; 849 scp.nTransparency = PWL_SCROLLBAR_TRANSPARANCY; 850 851 if ((m_pVScrollBar = new CPWL_ScrollBar(SBT_VSCROLL))) 852 m_pVScrollBar->Create(scp); 853 } 854 } 855 856 void CPWL_Wnd::SetCapture() 857 { 858 if (CPWL_MsgControl * pMsgCtrl = GetMsgControl()) 859 pMsgCtrl->SetCapture(this); 860 } 861 862 void CPWL_Wnd::ReleaseCapture() 863 { 864 for (FX_INT32 i=0,sz=m_aChildren.GetSize(); i<sz; i++) 865 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) 866 pChild->ReleaseCapture(); 867 868 if (CPWL_MsgControl * pMsgCtrl = GetMsgControl()) 869 pMsgCtrl->ReleaseCapture(); 870 } 871 872 void CPWL_Wnd::SetFocus() 873 { 874 if (CPWL_MsgControl * pMsgCtrl = GetMsgControl()) 875 { 876 if (!pMsgCtrl->IsMainCaptureKeyboard(this)) 877 pMsgCtrl->KillFocus(); 878 pMsgCtrl->SetFocus(this); 879 } 880 } 881 882 void CPWL_Wnd::KillFocus() 883 { 884 if (CPWL_MsgControl * pMsgCtrl = GetMsgControl()) 885 { 886 if (pMsgCtrl->IsWndCaptureKeyboard(this)) 887 pMsgCtrl->KillFocus(); 888 } 889 } 890 891 void CPWL_Wnd::OnSetFocus() 892 { 893 } 894 895 void CPWL_Wnd::OnKillFocus() 896 { 897 } 898 899 FX_BOOL CPWL_Wnd::WndHitTest(const CPDF_Point & point) const 900 { 901 return IsValid() && IsVisible() && GetWindowRect().Contains(point.x,point.y); 902 } 903 904 FX_BOOL CPWL_Wnd::ClientHitTest(const CPDF_Point & point) const 905 { 906 return IsValid() && IsVisible() && GetClientRect().Contains(point.x,point.y); 907 } 908 909 const CPWL_Wnd * CPWL_Wnd::GetRootWnd() const 910 { 911 if (m_sPrivateParam.pParentWnd) 912 return m_sPrivateParam.pParentWnd->GetRootWnd(); 913 else 914 return this; 915 } 916 917 void CPWL_Wnd::SetVisible(FX_BOOL bVisible) 918 { 919 if (IsValid()) 920 { 921 for (FX_INT32 i=0,sz=m_aChildren.GetSize(); i<sz; i++) 922 { 923 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) 924 { 925 pChild->SetVisible(bVisible); 926 } 927 } 928 929 if (bVisible != m_bVisible) 930 { 931 m_bVisible = bVisible; 932 RePosChildWnd(); 933 InvalidateRect(); 934 } 935 } 936 } 937 938 void CPWL_Wnd::SetClipRect(const CPDF_Rect & rect) 939 { 940 m_rcClip = rect; 941 m_rcClip.Normalize(); 942 } 943 944 CPDF_Rect CPWL_Wnd::GetClipRect() const 945 { 946 return m_rcClip; 947 } 948 949 FX_BOOL CPWL_Wnd::IsReadOnly() const 950 { 951 return HasFlag(PWS_READONLY); 952 } 953 954 void CPWL_Wnd::RePosChildWnd() 955 { 956 CPDF_Rect rcContent = CPWL_Utils::DeflateRect(GetWindowRect(),(FX_FLOAT)(GetBorderWidth()+GetInnerBorderWidth())); 957 958 CPWL_ScrollBar * pVSB = this->GetVScrollBar(); 959 960 CPDF_Rect rcVScroll = CPDF_Rect(rcContent.right - PWL_SCROLLBAR_WIDTH, 961 rcContent.bottom, 962 rcContent.right-1.0f, 963 rcContent.top); 964 965 if (pVSB) pVSB->Move(rcVScroll,TRUE,FALSE); 966 } 967 968 void CPWL_Wnd::CreateChildWnd(const PWL_CREATEPARAM & cp) 969 { 970 } 971 972 void CPWL_Wnd::SetCursor() 973 { 974 if (IsValid()) 975 { 976 if (IFX_SystemHandler* pSH = GetSystemHandler()) 977 { 978 FX_INT32 nCursorType = this->GetCreationParam().eCursorType; 979 pSH->SetCursor(nCursorType); 980 } 981 } 982 } 983 984 void CPWL_Wnd::CreateMsgControl() 985 { 986 if (!m_sPrivateParam.pMsgControl) 987 m_sPrivateParam.pMsgControl = new CPWL_MsgControl(this); 988 } 989 990 void CPWL_Wnd::DestroyMsgControl() 991 { 992 if (CPWL_MsgControl* pMsgControl = GetMsgControl()) 993 if (pMsgControl->IsWndCreated(this)) 994 delete pMsgControl; 995 } 996 997 CPWL_MsgControl* CPWL_Wnd::GetMsgControl() const 998 { 999 return m_sPrivateParam.pMsgControl; 1000 } 1001 1002 FX_BOOL CPWL_Wnd::IsCaptureMouse() const 1003 { 1004 return IsWndCaptureMouse(this); 1005 } 1006 1007 FX_BOOL CPWL_Wnd::IsWndCaptureMouse(const CPWL_Wnd * pWnd) const 1008 { 1009 if (CPWL_MsgControl * pCtrl = GetMsgControl()) 1010 return pCtrl->IsWndCaptureMouse(pWnd); 1011 1012 return FALSE; 1013 } 1014 1015 FX_BOOL CPWL_Wnd::IsWndCaptureKeyboard(const CPWL_Wnd * pWnd) const 1016 { 1017 if (CPWL_MsgControl * pCtrl = GetMsgControl()) 1018 return pCtrl->IsWndCaptureKeyboard(pWnd); 1019 1020 return FALSE; 1021 } 1022 1023 FX_BOOL CPWL_Wnd::IsFocused() const 1024 { 1025 if (CPWL_MsgControl * pCtrl = GetMsgControl()) 1026 return pCtrl->IsMainCaptureKeyboard(this); 1027 1028 return FALSE; 1029 } 1030 1031 CPDF_Rect CPWL_Wnd::GetFocusRect() const 1032 { 1033 return CPWL_Utils::InflateRect(this->GetWindowRect(),1); 1034 } 1035 1036 FX_FLOAT CPWL_Wnd::GetFontSize() const 1037 { 1038 return this->m_sPrivateParam.fFontSize; 1039 } 1040 1041 void CPWL_Wnd::SetFontSize(FX_FLOAT fFontSize) 1042 { 1043 this->m_sPrivateParam.fFontSize = fFontSize; 1044 } 1045 1046 IFX_SystemHandler* CPWL_Wnd::GetSystemHandler() const 1047 { 1048 return m_sPrivateParam.pSystemHandler; 1049 } 1050 1051 IPWL_FocusHandler* CPWL_Wnd::GetFocusHandler() const 1052 { 1053 return m_sPrivateParam.pFocusHandler; 1054 } 1055 1056 IPWL_Provider* CPWL_Wnd::GetProvider() const 1057 { 1058 return m_sPrivateParam.pProvider; 1059 } 1060 1061 IFX_Edit_FontMap* CPWL_Wnd::GetFontMap() const 1062 { 1063 return m_sPrivateParam.pFontMap; 1064 } 1065 1066 CPWL_Color CPWL_Wnd::GetBorderLeftTopColor(FX_INT32 nBorderStyle) const 1067 { 1068 CPWL_Color color; 1069 1070 switch (nBorderStyle) 1071 { 1072 case PBS_SOLID: 1073 break; 1074 case PBS_DASH: 1075 break; 1076 case PBS_BEVELED: 1077 color = CPWL_Color(COLORTYPE_GRAY,1); 1078 break; 1079 case PBS_INSET: 1080 color = CPWL_Color(COLORTYPE_GRAY,0.5f); 1081 break; 1082 case PBS_UNDERLINED: 1083 break; 1084 } 1085 1086 return color; 1087 } 1088 1089 CPWL_Color CPWL_Wnd::GetBorderRightBottomColor(FX_INT32 nBorderStyle) const 1090 { 1091 CPWL_Color color; 1092 1093 switch (nBorderStyle) 1094 { 1095 case PBS_SOLID: 1096 break; 1097 case PBS_DASH: 1098 break; 1099 case PBS_BEVELED: 1100 color = CPWL_Utils::DevideColor(GetBackgroundColor(),2); 1101 break; 1102 case PBS_INSET: 1103 color = CPWL_Color(COLORTYPE_GRAY,0.75f); 1104 break; 1105 case PBS_UNDERLINED: 1106 break; 1107 } 1108 1109 return color; 1110 } 1111 1112 /* ----------------------------------------------------------------- */ 1113 1114 FX_INT32 CPWL_Wnd::GetTransparency() 1115 { 1116 return m_sPrivateParam.nTransparency; 1117 } 1118 1119 void CPWL_Wnd::SetTransparency(FX_INT32 nTransparency) 1120 { 1121 for (FX_INT32 i=0,sz=m_aChildren.GetSize(); i<sz; i++) 1122 { 1123 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) 1124 { 1125 pChild->SetTransparency(nTransparency); 1126 } 1127 } 1128 1129 m_sPrivateParam.nTransparency = nTransparency; 1130 } 1131 1132 CPDF_Matrix CPWL_Wnd::GetWindowMatrix() const 1133 { 1134 CPDF_Matrix mt = this->GetChildToRoot(); 1135 1136 if (IPWL_Provider* pProvider = GetProvider()) 1137 { 1138 mt.Concat(pProvider->GetWindowMatrix(GetAttachedData())); 1139 return mt; 1140 } 1141 1142 /* 1143 if (CReader_App* pApp = CPWL_Module::GetReaderApp()) 1144 if (CReader_Document* pDocument = pApp->GetCurrentDocument()) 1145 if (CReader_DocView* pDocView = pDocument->GetCurrentDocView()) 1146 { 1147 CPDF_Matrix mtPageView; 1148 pDocView->GetCurrentMatrix(mtPageView); 1149 mt.Concat(mtPageView); 1150 return mt; 1151 } 1152 1153 */ 1154 1155 return mt; 1156 } 1157 1158 void CPWL_Wnd::PWLtoWnd(const CPDF_Point& point, FX_INT32& x, FX_INT32& y) const 1159 { 1160 CPDF_Matrix mt = GetWindowMatrix(); 1161 CPDF_Point pt = point; 1162 mt.Transform(pt.x,pt.y); 1163 x = (FX_INT32)(pt.x+0.5); 1164 y = (FX_INT32)(pt.y+0.5); 1165 } 1166 1167 FX_RECT CPWL_Wnd::PWLtoWnd(const CPDF_Rect & rect) const 1168 { 1169 CPDF_Rect rcTemp = rect; 1170 CPDF_Matrix mt = GetWindowMatrix(); 1171 mt.TransformRect(rcTemp); 1172 return FX_RECT((FX_INT32)(rcTemp.left+0.5), (FX_INT32)(rcTemp.bottom+0.5), (FX_INT32)(rcTemp.right+0.5), (FX_INT32)(rcTemp.top+0.5)); 1173 } 1174 1175 FX_HWND CPWL_Wnd::GetAttachedHWnd() const 1176 { 1177 return m_sPrivateParam.hAttachedWnd; 1178 } 1179 1180 CPDF_Point CPWL_Wnd::ChildToParent(const CPDF_Point& point) const 1181 { 1182 CPDF_Matrix mt = GetChildMatrix(); 1183 if (mt.IsIdentity()) 1184 return point; 1185 else 1186 { 1187 CPDF_Point pt = point; 1188 mt.Transform(pt.x,pt.y); 1189 return pt; 1190 } 1191 } 1192 1193 CPDF_Rect CPWL_Wnd::ChildToParent(const CPDF_Rect& rect) const 1194 { 1195 CPDF_Matrix mt = GetChildMatrix(); 1196 if (mt.IsIdentity()) 1197 return rect; 1198 else 1199 { 1200 CPDF_Rect rc = rect; 1201 mt.TransformRect(rc); 1202 return rc; 1203 } 1204 } 1205 1206 CPDF_Point CPWL_Wnd::ParentToChild(const CPDF_Point& point) const 1207 { 1208 CPDF_Matrix mt = GetChildMatrix(); 1209 if (mt.IsIdentity()) 1210 return point; 1211 else 1212 { 1213 mt.SetReverse(mt); 1214 CPDF_Point pt = point; 1215 mt.Transform(pt.x,pt.y); 1216 return pt; 1217 } 1218 } 1219 1220 CPDF_Rect CPWL_Wnd::ParentToChild(const CPDF_Rect& rect) const 1221 { 1222 CPDF_Matrix mt = GetChildMatrix(); 1223 if (mt.IsIdentity()) 1224 return rect; 1225 else 1226 { 1227 mt.SetReverse(mt); 1228 CPDF_Rect rc = rect; 1229 mt.TransformRect(rc); 1230 return rc; 1231 } 1232 } 1233 1234 CPDF_Matrix CPWL_Wnd::GetChildToRoot() const 1235 { 1236 CPDF_Matrix mt(1,0,0,1,0,0); 1237 1238 if (HasFlag(PWS_CHILD)) 1239 { 1240 const CPWL_Wnd* pParent = this; 1241 while (pParent) 1242 { 1243 mt.Concat(pParent->GetChildMatrix()); 1244 pParent = pParent->GetParentWindow(); 1245 } 1246 } 1247 1248 return mt; 1249 } 1250 1251 CPDF_Matrix CPWL_Wnd::GetChildMatrix() const 1252 { 1253 if (HasFlag(PWS_CHILD)) 1254 return m_sPrivateParam.mtChild; 1255 1256 return CPDF_Matrix(1,0,0,1,0,0); 1257 } 1258 1259 void CPWL_Wnd::SetChildMatrix(const CPDF_Matrix& mt) 1260 { 1261 m_sPrivateParam.mtChild = mt; 1262 } 1263 1264 const CPWL_Wnd* CPWL_Wnd::GetFocused() const 1265 { 1266 if (CPWL_MsgControl * pMsgCtrl = GetMsgControl()) 1267 { 1268 return pMsgCtrl->m_pMainKeyboardWnd; 1269 } 1270 1271 return NULL; 1272 } 1273 1274 void CPWL_Wnd::EnableWindow(FX_BOOL bEnable) 1275 { 1276 if (m_bEnabled != bEnable) 1277 { 1278 for (FX_INT32 i=0,sz=m_aChildren.GetSize(); i<sz; i++) 1279 { 1280 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) 1281 { 1282 pChild->EnableWindow(bEnable); 1283 } 1284 } 1285 1286 this->m_bEnabled = bEnable; 1287 1288 if (bEnable) 1289 this->OnEnabled(); 1290 else 1291 this->OnDisabled(); 1292 } 1293 } 1294 1295 FX_BOOL CPWL_Wnd::IsEnabled() 1296 { 1297 return m_bEnabled; 1298 } 1299 1300 void CPWL_Wnd::OnEnabled() 1301 { 1302 } 1303 1304 void CPWL_Wnd::OnDisabled() 1305 { 1306 } 1307 1308 FX_BOOL CPWL_Wnd::IsCTRLpressed(FX_DWORD nFlag) const 1309 { 1310 if (IFX_SystemHandler* pSystemHandler = GetSystemHandler()) 1311 { 1312 return pSystemHandler->IsCTRLKeyDown(nFlag); 1313 } 1314 1315 return FALSE; 1316 } 1317 1318 FX_BOOL CPWL_Wnd::IsSHIFTpressed(FX_DWORD nFlag) const 1319 { 1320 if (IFX_SystemHandler* pSystemHandler = GetSystemHandler()) 1321 { 1322 return pSystemHandler->IsSHIFTKeyDown(nFlag); 1323 } 1324 1325 return FALSE; 1326 } 1327 1328 FX_BOOL CPWL_Wnd::IsALTpressed(FX_DWORD nFlag) const 1329 { 1330 if (IFX_SystemHandler* pSystemHandler = GetSystemHandler()) 1331 { 1332 return pSystemHandler->IsALTKeyDown(nFlag); 1333 } 1334 1335 return FALSE; 1336 } 1337 1338 FX_BOOL CPWL_Wnd::IsINSERTpressed(FX_DWORD nFlag) const 1339 { 1340 if (IFX_SystemHandler* pSystemHandler = GetSystemHandler()) 1341 { 1342 return pSystemHandler->IsINSERTKeyDown(nFlag); 1343 } 1344 1345 return FALSE; 1346 } 1347 1348