Merge to XFA: Use stdint.h types throughout PDFium.
[pdfium.git] / fpdfsdk / src / pdfwindow / PWL_Wnd.cpp
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<int32_t, CPWL_Timer*>& GetPWLTimeMap()
15 {
16   // Leak the object at shutdown.
17   static auto timeMap = new CFX_MapPtrTemplate<int32_t, 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 int32_t CPWL_Timer::SetPWLTimer(int32_t 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(int32_t 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(int32_t 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( int32_t 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( int32_t 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 (int32_t 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 (int32_t 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 (int32_t 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 (int32_t 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 (int32_t 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 (int32_t 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 (int32_t 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 (int32_t 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 (int32_t 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 (int32_t 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, intptr_t wParam, intptr_t 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 int32_t CPWL_Wnd::GetBorderStyle() const
757 {
758         return m_sPrivateParam.nBorderStyle;
759 }
760
761 void CPWL_Wnd::SetBorderStyle(int32_t nBorderStyle)
762 {
763         if (HasFlag(PWS_BORDER))
764                 m_sPrivateParam.nBorderStyle = nBorderStyle;
765 }
766
767 int32_t CPWL_Wnd::GetBorderWidth() const
768 {
769         if (HasFlag(PWS_BORDER))
770                 return m_sPrivateParam.dwBorderWidth;
771
772         return 0;
773 }
774
775 int32_t 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(int32_t 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 (int32_t 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 (int32_t 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                         int32_t 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(int32_t 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(int32_t 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 int32_t CPWL_Wnd::GetTransparency()
1115 {
1116         return m_sPrivateParam.nTransparency;
1117 }
1118
1119 void CPWL_Wnd::SetTransparency(int32_t nTransparency)
1120 {
1121         for (int32_t 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, int32_t& x, int32_t& y) const
1159 {
1160         CPDF_Matrix mt = GetWindowMatrix();
1161         CPDF_Point pt = point;
1162         mt.Transform(pt.x,pt.y);
1163         x = (int32_t)(pt.x+0.5);
1164         y = (int32_t)(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((int32_t)(rcTemp.left+0.5), (int32_t)(rcTemp.bottom+0.5), (int32_t)(rcTemp.right+0.5), (int32_t)(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 (int32_t 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