Cleanup: Remove more checks for new returning NULL.
[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
657         if (CPWL_ScrollBar * pVSB = GetVScrollBar())
658                 rcClient.right -= pVSB->GetScrollBarWidth();
659
660         rcClient.Normalize();
661
662         if (rcWindow.Contains(rcClient))
663                 return rcClient;
664         else
665                 return CPDF_Rect();
666 }
667
668 CPDF_Point CPWL_Wnd::GetCenterPoint() const
669 {
670         CPDF_Rect rcClient = GetClientRect();
671
672         return CPDF_Point((rcClient.left + rcClient.right) * 0.5f,
673                 (rcClient.top + rcClient.bottom) * 0.5f);
674 }
675
676 CPDF_Rect CPWL_Wnd::GetClientCenterSquare() const
677 {
678         return CPWL_Utils::GetCenterSquare(GetClientRect());
679 }
680
681 CPDF_Rect CPWL_Wnd::GetWindowCenterSquare() const
682 {
683         return CPWL_Utils::GetCenterSquare(CPWL_Utils::DeflateRect(GetWindowRect(),0.1f));
684 }
685
686 FX_BOOL CPWL_Wnd::HasFlag(FX_DWORD dwFlags) const
687 {
688         return (m_sPrivateParam.dwFlags & dwFlags) != 0;
689 }
690
691 void CPWL_Wnd::RemoveFlag(FX_DWORD dwFlags)
692 {
693         m_sPrivateParam.dwFlags &= ~dwFlags;
694 }
695
696 void CPWL_Wnd::AddFlag(FX_DWORD dwFlags)
697 {
698         m_sPrivateParam.dwFlags |= dwFlags;
699 }
700
701 CPWL_Color CPWL_Wnd::GetBackgroundColor() const
702 {
703         return m_sPrivateParam.sBackgroundColor;
704 }
705
706 void CPWL_Wnd::SetBackgroundColor(const CPWL_Color & color)
707 {
708         m_sPrivateParam.sBackgroundColor = color;
709 }
710
711 void CPWL_Wnd::SetTextColor(const CPWL_Color & color)
712 {
713         m_sPrivateParam.sTextColor = color;
714 }
715
716 void CPWL_Wnd::SetTextStrokeColor(const CPWL_Color & color)
717 {
718         m_sPrivateParam.sTextStrokeColor = color;
719 }
720
721 CPWL_Color CPWL_Wnd::GetTextColor() const
722 {
723         return m_sPrivateParam.sTextColor;
724 }
725
726 CPWL_Color CPWL_Wnd::GetTextStrokeColor() const
727 {
728         return m_sPrivateParam.sTextStrokeColor;
729 }
730
731 int32_t CPWL_Wnd::GetBorderStyle() const
732 {
733         return m_sPrivateParam.nBorderStyle;
734 }
735
736 void CPWL_Wnd::SetBorderStyle(int32_t nBorderStyle)
737 {
738         if (HasFlag(PWS_BORDER))
739                 m_sPrivateParam.nBorderStyle = nBorderStyle;
740 }
741
742 int32_t CPWL_Wnd::GetBorderWidth() const
743 {
744         if (HasFlag(PWS_BORDER))
745                 return m_sPrivateParam.dwBorderWidth;
746
747         return 0;
748 }
749
750 int32_t CPWL_Wnd::GetInnerBorderWidth() const
751 {
752         /*
753         switch (GetBorderStyle())
754         {
755         case PBS_BEVELED:
756         case PBS_INSET:
757                 return GetBorderWidth() / 2;
758         }
759         */
760         return 0;
761 }
762
763 void CPWL_Wnd::SetBorderWidth(int32_t nBorderWidth)
764 {
765         if (HasFlag(PWS_BORDER))
766                 m_sPrivateParam.dwBorderWidth = nBorderWidth;
767 }
768
769 CPWL_Color CPWL_Wnd::GetBorderColor() const
770 {
771         if (HasFlag(PWS_BORDER))
772                 return m_sPrivateParam.sBorderColor;
773
774         return CPWL_Color();
775 }
776
777 void CPWL_Wnd::SetBorderColor(const CPWL_Color & color)
778 {
779         if (HasFlag(PWS_BORDER))
780                 m_sPrivateParam.sBorderColor = color;
781 }
782
783 CPWL_Dash CPWL_Wnd::GetBorderDash() const
784 {
785         return m_sPrivateParam.sDash;
786 }
787
788 void* CPWL_Wnd::GetAttachedData() const
789 {
790         return m_sPrivateParam.pAttachedData;
791 }
792
793 void CPWL_Wnd::SetBorderDash(const CPWL_Dash & sDash)
794 {
795         if (HasFlag(PWS_BORDER))
796                 m_sPrivateParam.sDash = sDash;
797 }
798
799 CPWL_ScrollBar* CPWL_Wnd::GetVScrollBar() const
800 {
801         if (HasFlag(PWS_VSCROLL))
802                 return m_pVScrollBar;
803
804         return NULL;
805 }
806
807 void CPWL_Wnd::CreateScrollBar(const PWL_CREATEPARAM & cp)
808 {
809         CreateVScrollBar(cp);
810 }
811
812 void CPWL_Wnd::CreateVScrollBar(const PWL_CREATEPARAM & cp)
813 {
814         if (!m_pVScrollBar && HasFlag(PWS_VSCROLL))
815         {
816                 PWL_CREATEPARAM scp = cp;
817
818                 //flags
819                 scp.dwFlags = PWS_CHILD| PWS_BACKGROUND | PWS_AUTOTRANSPARENT | PWS_NOREFRESHCLIP;
820
821                 scp.pParentWnd = this;
822                 scp.sBackgroundColor = PWL_DEFAULT_WHITECOLOR;
823                 scp.eCursorType = FXCT_ARROW;
824                 scp.nTransparency = PWL_SCROLLBAR_TRANSPARANCY;
825
826                 if ((m_pVScrollBar = new CPWL_ScrollBar(SBT_VSCROLL)))
827                         m_pVScrollBar->Create(scp);
828         }
829 }
830
831 void CPWL_Wnd::SetCapture()
832 {
833         if (CPWL_MsgControl * pMsgCtrl = GetMsgControl())
834                 pMsgCtrl->SetCapture(this);
835 }
836
837 void CPWL_Wnd::ReleaseCapture()
838 {
839         for (int32_t i=0,sz=m_aChildren.GetSize(); i<sz; i++)
840                 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i))
841                         pChild->ReleaseCapture();
842
843         if (CPWL_MsgControl * pMsgCtrl = GetMsgControl())
844                 pMsgCtrl->ReleaseCapture();
845 }
846
847 void CPWL_Wnd::SetFocus()
848 {
849         if (CPWL_MsgControl * pMsgCtrl = GetMsgControl())
850         {
851                 if (!pMsgCtrl->IsMainCaptureKeyboard(this))
852                         pMsgCtrl->KillFocus();
853                 pMsgCtrl->SetFocus(this);
854         }
855 }
856
857 void CPWL_Wnd::KillFocus()
858 {
859         if (CPWL_MsgControl * pMsgCtrl = GetMsgControl())
860         {
861                 if (pMsgCtrl->IsWndCaptureKeyboard(this))
862                         pMsgCtrl->KillFocus();
863         }
864 }
865
866 void CPWL_Wnd::OnSetFocus()
867 {
868 }
869
870 void CPWL_Wnd::OnKillFocus()
871 {
872 }
873
874 FX_BOOL CPWL_Wnd::WndHitTest(const CPDF_Point & point) const
875 {
876         return IsValid() && IsVisible() && GetWindowRect().Contains(point.x,point.y);
877 }
878
879 FX_BOOL CPWL_Wnd::ClientHitTest(const CPDF_Point & point) const
880 {
881         return IsValid() && IsVisible() && GetClientRect().Contains(point.x,point.y);
882 }
883
884 const CPWL_Wnd * CPWL_Wnd::GetRootWnd() const
885 {
886         if (m_sPrivateParam.pParentWnd)
887                 return m_sPrivateParam.pParentWnd->GetRootWnd();
888         else
889                 return this;
890 }
891
892 void CPWL_Wnd::SetVisible(FX_BOOL bVisible)
893 {
894         if (IsValid())
895         {
896                 for (int32_t i=0,sz=m_aChildren.GetSize(); i<sz; i++)
897                 {
898                         if (CPWL_Wnd* pChild = m_aChildren.GetAt(i))
899                         {
900                                 pChild->SetVisible(bVisible);
901                         }
902                 }
903
904                 if (bVisible != m_bVisible)
905                 {
906                         m_bVisible = bVisible;
907                         RePosChildWnd();
908                         InvalidateRect();
909                 }
910         }
911 }
912
913 void CPWL_Wnd::SetClipRect(const CPDF_Rect & rect)
914 {
915         m_rcClip = rect;
916         m_rcClip.Normalize();
917 }
918
919 CPDF_Rect CPWL_Wnd::GetClipRect() const
920 {
921         return m_rcClip;
922 }
923
924 FX_BOOL CPWL_Wnd::IsReadOnly() const
925 {
926         return HasFlag(PWS_READONLY);
927 }
928
929 void CPWL_Wnd::RePosChildWnd()
930 {
931         CPDF_Rect rcContent = CPWL_Utils::DeflateRect(GetWindowRect(),(FX_FLOAT)(GetBorderWidth()+GetInnerBorderWidth()));
932
933         CPWL_ScrollBar * pVSB = GetVScrollBar();
934
935         CPDF_Rect rcVScroll = CPDF_Rect(rcContent.right - PWL_SCROLLBAR_WIDTH,
936                                                         rcContent.bottom,
937                                                         rcContent.right-1.0f,
938                                                         rcContent.top);
939
940         if (pVSB) pVSB->Move(rcVScroll,TRUE,FALSE);
941 }
942
943 void CPWL_Wnd::CreateChildWnd(const PWL_CREATEPARAM & cp)
944 {
945 }
946
947 void CPWL_Wnd::SetCursor()
948 {
949         if (IsValid())
950         {
951                 if (IFX_SystemHandler* pSH = GetSystemHandler())
952                 {
953                         int32_t nCursorType = GetCreationParam().eCursorType;
954                         pSH->SetCursor(nCursorType);
955                 }
956         }
957 }
958
959 void CPWL_Wnd::CreateMsgControl()
960 {
961         if (!m_sPrivateParam.pMsgControl)
962                 m_sPrivateParam.pMsgControl = new CPWL_MsgControl(this);
963 }
964
965 void CPWL_Wnd::DestroyMsgControl()
966 {
967         if (CPWL_MsgControl* pMsgControl = GetMsgControl())
968                 if (pMsgControl->IsWndCreated(this))
969                         delete pMsgControl;
970 }
971
972 CPWL_MsgControl* CPWL_Wnd::GetMsgControl() const
973 {
974         return m_sPrivateParam.pMsgControl;
975 }
976
977 FX_BOOL CPWL_Wnd::IsCaptureMouse() const
978 {
979         return IsWndCaptureMouse(this);
980 }
981
982 FX_BOOL CPWL_Wnd::IsWndCaptureMouse(const CPWL_Wnd * pWnd) const
983 {
984         if (CPWL_MsgControl * pCtrl = GetMsgControl())
985                 return pCtrl->IsWndCaptureMouse(pWnd);
986
987         return FALSE;
988 }
989
990 FX_BOOL CPWL_Wnd::IsWndCaptureKeyboard(const CPWL_Wnd * pWnd) const
991 {
992         if (CPWL_MsgControl * pCtrl = GetMsgControl())
993                 return pCtrl->IsWndCaptureKeyboard(pWnd);
994
995         return FALSE;
996 }
997
998 FX_BOOL CPWL_Wnd::IsFocused() const
999 {
1000         if (CPWL_MsgControl * pCtrl = GetMsgControl())
1001                 return pCtrl->IsMainCaptureKeyboard(this);
1002
1003         return FALSE;
1004 }
1005
1006 CPDF_Rect CPWL_Wnd::GetFocusRect() const
1007 {
1008         return CPWL_Utils::InflateRect(GetWindowRect(),1);
1009 }
1010
1011 FX_FLOAT CPWL_Wnd::GetFontSize() const
1012 {
1013         return m_sPrivateParam.fFontSize;
1014 }
1015
1016 void CPWL_Wnd::SetFontSize(FX_FLOAT fFontSize)
1017 {
1018         m_sPrivateParam.fFontSize = fFontSize;
1019 }
1020
1021 IFX_SystemHandler* CPWL_Wnd::GetSystemHandler() const
1022 {
1023         return m_sPrivateParam.pSystemHandler;
1024 }
1025
1026 IPWL_FocusHandler* CPWL_Wnd::GetFocusHandler() const
1027 {
1028         return m_sPrivateParam.pFocusHandler;
1029 }
1030
1031 IPWL_Provider* CPWL_Wnd::GetProvider() const
1032 {
1033         return m_sPrivateParam.pProvider;
1034 }
1035
1036 IFX_Edit_FontMap* CPWL_Wnd::GetFontMap() const
1037 {
1038         return m_sPrivateParam.pFontMap;
1039 }
1040
1041 CPWL_Color CPWL_Wnd::GetBorderLeftTopColor(int32_t nBorderStyle) const
1042 {
1043         CPWL_Color color;
1044
1045         switch (nBorderStyle)
1046         {
1047                 case PBS_SOLID:
1048                         break;
1049                 case PBS_DASH:
1050                         break;
1051                 case PBS_BEVELED:
1052                         color = CPWL_Color(COLORTYPE_GRAY,1);
1053                         break;
1054                 case PBS_INSET:
1055                         color = CPWL_Color(COLORTYPE_GRAY,0.5f);
1056                         break;
1057                 case PBS_UNDERLINED:
1058                         break;
1059         }
1060
1061         return color;
1062 }
1063
1064 CPWL_Color CPWL_Wnd::GetBorderRightBottomColor(int32_t nBorderStyle) const
1065 {
1066         CPWL_Color color;
1067
1068         switch (nBorderStyle)
1069         {
1070                 case PBS_SOLID:
1071                         break;
1072                 case PBS_DASH:
1073                         break;
1074                 case PBS_BEVELED:
1075                         color = CPWL_Utils::DevideColor(GetBackgroundColor(),2);
1076                         break;
1077                 case PBS_INSET:
1078                         color = CPWL_Color(COLORTYPE_GRAY,0.75f);
1079                         break;
1080                 case PBS_UNDERLINED:
1081                         break;
1082         }
1083
1084         return color;
1085 }
1086
1087 /* ----------------------------------------------------------------- */
1088
1089 int32_t CPWL_Wnd::GetTransparency()
1090 {
1091         return m_sPrivateParam.nTransparency;
1092 }
1093
1094 void CPWL_Wnd::SetTransparency(int32_t nTransparency)
1095 {
1096         for (int32_t i=0,sz=m_aChildren.GetSize(); i<sz; i++)
1097         {
1098                 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i))
1099                 {
1100                         pChild->SetTransparency(nTransparency);
1101                 }
1102         }
1103
1104         m_sPrivateParam.nTransparency = nTransparency;
1105 }
1106
1107 CPDF_Matrix     CPWL_Wnd::GetWindowMatrix() const
1108 {
1109         CPDF_Matrix mt = GetChildToRoot();
1110
1111         if (IPWL_Provider* pProvider = GetProvider())
1112         {
1113                 mt.Concat(pProvider->GetWindowMatrix(GetAttachedData()));
1114                 return mt;
1115         }
1116
1117         return mt;
1118 }
1119
1120 void CPWL_Wnd::PWLtoWnd(const CPDF_Point& point, int32_t& x, int32_t& y) const
1121 {
1122         CPDF_Matrix mt = GetWindowMatrix();
1123         CPDF_Point pt = point;
1124         mt.Transform(pt.x,pt.y);
1125         x = (int32_t)(pt.x+0.5);
1126         y = (int32_t)(pt.y+0.5);
1127 }
1128
1129 FX_RECT CPWL_Wnd::PWLtoWnd(const CPDF_Rect & rect) const
1130 {
1131         CPDF_Rect rcTemp = rect;
1132         CPDF_Matrix mt = GetWindowMatrix();
1133         mt.TransformRect(rcTemp);
1134         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));
1135 }
1136
1137 FX_HWND CPWL_Wnd::GetAttachedHWnd() const
1138 {
1139         return m_sPrivateParam.hAttachedWnd;
1140 }
1141
1142 CPDF_Point CPWL_Wnd::ChildToParent(const CPDF_Point& point) const
1143 {
1144         CPDF_Matrix mt = GetChildMatrix();
1145         if (mt.IsIdentity())
1146                 return point;
1147         else
1148         {
1149                 CPDF_Point pt = point;
1150                 mt.Transform(pt.x,pt.y);
1151                 return pt;
1152         }
1153 }
1154
1155 CPDF_Rect CPWL_Wnd::ChildToParent(const CPDF_Rect& rect) const
1156 {
1157         CPDF_Matrix mt = GetChildMatrix();
1158         if (mt.IsIdentity())
1159                 return rect;
1160         else
1161         {
1162                 CPDF_Rect rc = rect;
1163                 mt.TransformRect(rc);
1164                 return rc;
1165         }
1166 }
1167
1168 CPDF_Point CPWL_Wnd::ParentToChild(const CPDF_Point& point) const
1169 {
1170         CPDF_Matrix mt = GetChildMatrix();
1171         if (mt.IsIdentity())
1172                 return point;
1173         else
1174         {
1175                 mt.SetReverse(mt);
1176                 CPDF_Point pt = point;
1177                 mt.Transform(pt.x,pt.y);
1178                 return pt;
1179         }
1180 }
1181
1182 CPDF_Rect CPWL_Wnd::ParentToChild(const CPDF_Rect& rect) const
1183 {
1184         CPDF_Matrix mt = GetChildMatrix();
1185         if (mt.IsIdentity())
1186                 return rect;
1187         else
1188         {
1189                 mt.SetReverse(mt);
1190                 CPDF_Rect rc = rect;
1191                 mt.TransformRect(rc);
1192                 return rc;
1193         }
1194 }
1195
1196 CPDF_Matrix CPWL_Wnd::GetChildToRoot() const
1197 {
1198         CPDF_Matrix mt(1,0,0,1,0,0);
1199
1200         if (HasFlag(PWS_CHILD))
1201         {
1202                 const CPWL_Wnd* pParent = this;
1203                 while (pParent)
1204                 {
1205                         mt.Concat(pParent->GetChildMatrix());
1206                         pParent = pParent->GetParentWindow();
1207                 }
1208         }
1209
1210         return mt;
1211 }
1212
1213 CPDF_Matrix CPWL_Wnd::GetChildMatrix() const
1214 {
1215         if (HasFlag(PWS_CHILD))
1216                 return m_sPrivateParam.mtChild;
1217
1218         return CPDF_Matrix(1,0,0,1,0,0);
1219 }
1220
1221 void CPWL_Wnd::SetChildMatrix(const CPDF_Matrix& mt)
1222 {
1223         m_sPrivateParam.mtChild = mt;
1224 }
1225
1226 const CPWL_Wnd* CPWL_Wnd::GetFocused() const
1227 {
1228         if (CPWL_MsgControl * pMsgCtrl = GetMsgControl())
1229         {
1230                 return pMsgCtrl->m_pMainKeyboardWnd;
1231         }
1232
1233         return NULL;
1234 }
1235
1236 void CPWL_Wnd::EnableWindow(FX_BOOL bEnable)
1237 {
1238         if (m_bEnabled != bEnable)
1239         {
1240                 for (int32_t i=0,sz=m_aChildren.GetSize(); i<sz; i++)
1241                 {
1242                         if (CPWL_Wnd* pChild = m_aChildren.GetAt(i))
1243                         {
1244                                 pChild->EnableWindow(bEnable);
1245                         }
1246                 }
1247
1248                 m_bEnabled = bEnable;
1249
1250                 if (bEnable)
1251                         OnEnabled();
1252                 else
1253                         OnDisabled();
1254         }
1255 }
1256
1257 FX_BOOL CPWL_Wnd::IsEnabled()
1258 {
1259         return m_bEnabled;
1260 }
1261
1262 void CPWL_Wnd::OnEnabled()
1263 {
1264 }
1265
1266 void CPWL_Wnd::OnDisabled()
1267 {
1268 }
1269
1270 FX_BOOL CPWL_Wnd::IsCTRLpressed(FX_DWORD nFlag) const
1271 {
1272         if (IFX_SystemHandler* pSystemHandler = GetSystemHandler())
1273         {
1274                 return pSystemHandler->IsCTRLKeyDown(nFlag);
1275         }
1276
1277         return FALSE;
1278 }
1279
1280 FX_BOOL CPWL_Wnd::IsSHIFTpressed(FX_DWORD nFlag) const
1281 {
1282         if (IFX_SystemHandler* pSystemHandler = GetSystemHandler())
1283         {
1284                 return pSystemHandler->IsSHIFTKeyDown(nFlag);
1285         }
1286
1287         return FALSE;
1288 }
1289
1290 FX_BOOL CPWL_Wnd::IsALTpressed(FX_DWORD nFlag) const
1291 {
1292         if (IFX_SystemHandler* pSystemHandler = GetSystemHandler())
1293         {
1294                 return pSystemHandler->IsALTKeyDown(nFlag);
1295         }
1296
1297         return FALSE;
1298 }
1299
1300 FX_BOOL CPWL_Wnd::IsINSERTpressed(FX_DWORD nFlag) const
1301 {
1302         if (IFX_SystemHandler* pSystemHandler = GetSystemHandler())
1303         {
1304                 return pSystemHandler->IsINSERTKeyDown(nFlag);
1305         }
1306
1307         return FALSE;
1308 }
1309