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