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