Cleanup: Get this rid of "this->" in fpdfsdk/
[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 = GetWindowRect();
324
325                 m_rcWindow = rcNew;
326                 m_rcWindow.Normalize();
327
328                 if (rcOld.left != rcNew.left || rcOld.right != rcNew.right ||
329                         rcOld.top != rcNew.top || rcOld.bottom != rcNew.bottom)
330                 {
331                         if (bReset)
332                         {
333                                 RePosChildWnd();
334                         }
335
336                 }
337                 if (bRefresh)
338                 {
339                         InvalidateRectMove(rcOld,rcNew);
340                 }
341
342                 m_sPrivateParam.rcRectWnd = m_rcWindow;
343         }
344 }
345
346 void  CPWL_Wnd::InvalidateRectMove(const CPDF_Rect & rcOld, const CPDF_Rect & rcNew)
347 {
348         CPDF_Rect rcUnion = rcOld;
349         rcUnion.Union(rcNew);
350
351         InvalidateRect(&rcUnion);
352 }
353
354 void CPWL_Wnd::GetAppearanceStream(CFX_ByteString & sAppStream)
355 {
356         if (IsValid())
357         {
358                 CFX_ByteTextBuf sTextBuf;
359                 GetAppearanceStream(sTextBuf);
360                 sAppStream += sTextBuf.GetByteString();
361         }
362 }
363
364 void CPWL_Wnd::GetAppearanceStream(CFX_ByteTextBuf & sAppStream)
365 {
366         if (IsValid() && IsVisible())
367         {
368                 GetThisAppearanceStream(sAppStream);
369                 GetChildAppearanceStream(sAppStream);
370         }
371 }
372
373 //if don't set,Get default apperance stream
374 void CPWL_Wnd::GetThisAppearanceStream(CFX_ByteTextBuf & sAppStream)
375 {
376     CPDF_Rect rectWnd = GetWindowRect();
377     if (!rectWnd.IsEmpty()) {
378         CFX_ByteTextBuf sThis;
379
380         if (HasFlag(PWS_BACKGROUND))
381             sThis << CPWL_Utils::GetRectFillAppStream(rectWnd, GetBackgroundColor());
382
383         if (HasFlag(PWS_BORDER)) {
384             sThis << CPWL_Utils::GetBorderAppStream(
385                 rectWnd,
386                 (FX_FLOAT)GetBorderWidth(),
387                 GetBorderColor(),
388                 GetBorderLeftTopColor(GetBorderStyle()),
389                 GetBorderRightBottomColor(GetBorderStyle()),
390                 GetBorderStyle(),
391                 GetBorderDash());
392         }
393
394         sAppStream << sThis;
395     }
396 }
397
398 void CPWL_Wnd::GetChildAppearanceStream(CFX_ByteTextBuf & sAppStream)
399 {
400         for (int32_t i=0,sz=m_aChildren.GetSize(); i<sz; i++)
401         {
402                 if (CPWL_Wnd * pChild = m_aChildren.GetAt(i))
403                 {
404                         pChild->GetAppearanceStream(sAppStream);
405                 }
406         }
407 }
408
409 void CPWL_Wnd::DrawAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device)
410 {
411         if (IsValid() && IsVisible())
412         {
413                 DrawThisAppearance(pDevice,pUser2Device);
414                 DrawChildAppearance(pDevice,pUser2Device);
415         }
416 }
417
418 void CPWL_Wnd::DrawThisAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device)
419 {
420         CPDF_Rect rectWnd = GetWindowRect();
421         if (!rectWnd.IsEmpty())
422         {
423                 if (HasFlag(PWS_BACKGROUND))
424                 {
425                         CPDF_Rect rcClient = CPWL_Utils::DeflateRect(rectWnd,(FX_FLOAT)(GetBorderWidth()+GetInnerBorderWidth()));
426                         CPWL_Utils::DrawFillRect(pDevice,pUser2Device,rcClient, GetBackgroundColor(), GetTransparency());
427                 }
428
429                 if (HasFlag(PWS_BORDER))
430                         CPWL_Utils::DrawBorder(pDevice,
431                                                                 pUser2Device,
432                                                                 rectWnd,
433                                                                 (FX_FLOAT)GetBorderWidth(),
434                                                                 GetBorderColor(),
435                                                                 GetBorderLeftTopColor(GetBorderStyle()),
436                                                                 GetBorderRightBottomColor(GetBorderStyle()),
437                                                                 GetBorderStyle(),
438                                                                 GetBorderDash(),
439                                                                 GetTransparency());
440         }
441 }
442
443 void CPWL_Wnd::DrawChildAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device)
444 {
445         for (int32_t i=0,sz=m_aChildren.GetSize(); i<sz; i++)
446         {
447                 if (CPWL_Wnd * pChild = m_aChildren.GetAt(i))
448                 {
449                         CPDF_Matrix mt = pChild->GetChildMatrix();
450                         if (mt.IsIdentity())
451                         {
452                                 pChild->DrawAppearance(pDevice,pUser2Device);
453                         }
454                         else
455                         {
456                                 mt.Concat(*pUser2Device);
457                                 pChild->DrawAppearance(pDevice,&mt);
458                         }
459                 }
460         }
461 }
462
463 void CPWL_Wnd::InvalidateRect(CPDF_Rect* pRect)
464 {
465         if (IsValid())
466         {
467                 CPDF_Rect rcRefresh = pRect ? *pRect : GetWindowRect();
468
469                 if (!HasFlag(PWS_NOREFRESHCLIP))
470                 {
471                         CPDF_Rect rcClip = GetClipRect();
472                         if (!rcClip.IsEmpty())
473                         {
474                                 rcRefresh.Intersect(rcClip);
475                         }
476                 }
477
478                 FX_RECT rcWin = PWLtoWnd(rcRefresh);
479                 rcWin.left -= PWL_INVALIDATE_INFLATE;
480                 rcWin.top -= PWL_INVALIDATE_INFLATE;
481                 rcWin.right += PWL_INVALIDATE_INFLATE;
482                 rcWin.bottom += PWL_INVALIDATE_INFLATE;
483
484                 if (IFX_SystemHandler* pSH = GetSystemHandler())
485                 {
486                         if (FX_HWND hWnd = GetAttachedHWnd())
487                         {
488                                 pSH->InvalidateRect(hWnd, rcWin);
489                         }
490                 }
491         }
492 }
493
494 #define PWL_IMPLEMENT_KEY_METHOD(key_method_name)\
495 FX_BOOL CPWL_Wnd::key_method_name(FX_WORD nChar, FX_DWORD nFlag)\
496 {\
497         if (IsValid() && IsVisible() && IsEnabled())\
498         {\
499                 if (IsWndCaptureKeyboard(this))\
500                 {\
501                         for (int32_t i=0,sz=m_aChildren.GetSize(); i<sz; i++)\
502                         {\
503                                 if (CPWL_Wnd * pChild = m_aChildren.GetAt(i))\
504                                 {\
505                                         if (IsWndCaptureKeyboard(pChild))\
506                                         {\
507                                                 return pChild->key_method_name(nChar,nFlag);\
508                                         }\
509                                 }\
510                         }\
511                 }\
512         }\
513         return FALSE;\
514 }
515
516 #define PWL_IMPLEMENT_MOUSE_METHOD(mouse_method_name)\
517 FX_BOOL CPWL_Wnd::mouse_method_name(const CPDF_Point & point, FX_DWORD nFlag)\
518 {\
519         if (IsValid() && IsVisible() && IsEnabled())\
520         {\
521                 if (IsWndCaptureMouse(this))\
522                 {\
523                         for (int32_t i=0,sz=m_aChildren.GetSize(); i<sz; i++)\
524                         {\
525                                 if (CPWL_Wnd * pChild = m_aChildren.GetAt(i))\
526                                 {\
527                                         if (IsWndCaptureMouse(pChild))\
528                                         {\
529                                                 return pChild->mouse_method_name(pChild->ParentToChild(point),nFlag);\
530                                         }\
531                                 }\
532                         }\
533                         SetCursor();\
534                 }\
535                 else\
536                 {\
537                         for (int32_t i=0,sz=m_aChildren.GetSize(); i<sz; i++)\
538                         {\
539                                 if (CPWL_Wnd * pChild = m_aChildren.GetAt(i))\
540                                 {\
541                                         if (pChild->WndHitTest(pChild->ParentToChild(point)))\
542                                         {\
543                                                 return pChild->mouse_method_name(pChild->ParentToChild(point),nFlag);\
544                                         }\
545                                 }\
546                         }\
547                         if (WndHitTest(point))\
548                                 SetCursor();\
549                 }\
550         }\
551         return FALSE;\
552 }
553
554 PWL_IMPLEMENT_KEY_METHOD(OnKeyDown)
555 PWL_IMPLEMENT_KEY_METHOD(OnKeyUp)
556 PWL_IMPLEMENT_KEY_METHOD(OnChar)
557
558 PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonDblClk)
559 PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonDown)
560 PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonUp)
561 PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonDblClk)
562 PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonDown)
563 PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonUp)
564 PWL_IMPLEMENT_MOUSE_METHOD(OnRButtonDblClk)
565 PWL_IMPLEMENT_MOUSE_METHOD(OnRButtonDown)
566 PWL_IMPLEMENT_MOUSE_METHOD(OnRButtonUp)
567 PWL_IMPLEMENT_MOUSE_METHOD(OnMouseMove)
568
569 FX_BOOL CPWL_Wnd::OnMouseWheel(short zDelta, const CPDF_Point & point, FX_DWORD nFlag)
570 {
571         if (IsValid() && IsVisible() && IsEnabled())
572         {
573                 SetCursor();
574                 if (IsWndCaptureKeyboard(this))
575                 {
576                         for (int32_t i=0,sz=m_aChildren.GetSize(); i<sz; i++)
577                         {
578                                 if (CPWL_Wnd * pChild = m_aChildren.GetAt(i))
579                                 {
580                                         if (IsWndCaptureKeyboard(pChild))
581                                         {
582                                                 return pChild->OnMouseWheel(zDelta,pChild->ParentToChild(point), nFlag);
583                                         }
584                                 }
585                         }
586                 }
587         }
588         return FALSE;
589 }
590
591 void CPWL_Wnd::AddChild(CPWL_Wnd * pWnd)
592 {
593         m_aChildren.Add(pWnd);
594 }
595
596 void CPWL_Wnd::RemoveChild(CPWL_Wnd * pWnd)
597 {
598         for (int32_t i = m_aChildren.GetSize()-1; i >= 0; i --)
599         {
600                 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i))
601                 {
602                         if (pChild == pWnd)
603                         {
604                                 m_aChildren.RemoveAt(i);
605                                 break;
606                         }
607                 }
608         }
609 }
610
611 void CPWL_Wnd::OnNotify(CPWL_Wnd* pWnd, FX_DWORD msg, intptr_t wParam, intptr_t lParam)
612 {
613         switch (msg)
614         {
615         case PNM_ADDCHILD:
616                 AddChild(pWnd);
617                 break;
618         case PNM_REMOVECHILD:
619                 RemoveChild(pWnd);
620                 break;
621         default:
622                 break;
623         }
624 }
625
626 FX_BOOL CPWL_Wnd::IsValid() const
627 {
628         return m_bCreated;
629 }
630
631 PWL_CREATEPARAM CPWL_Wnd::GetCreationParam() const
632 {
633         return m_sPrivateParam;
634 }
635
636 CPWL_Wnd* CPWL_Wnd::GetParentWindow() const
637 {
638         return m_sPrivateParam.pParentWnd;
639 }
640
641 CPDF_Rect CPWL_Wnd::GetOriginWindowRect() const
642 {
643         return m_sPrivateParam.rcRectWnd;
644 }
645
646 CPDF_Rect CPWL_Wnd::GetWindowRect() const
647 {
648         return m_rcWindow;
649 }
650
651 CPDF_Rect CPWL_Wnd::GetClientRect() const
652 {
653         CPDF_Rect rcWindow = GetWindowRect();
654         CPDF_Rect rcClient = CPWL_Utils::DeflateRect(rcWindow,(FX_FLOAT)(GetBorderWidth()+GetInnerBorderWidth()));
655
656         if (CPWL_ScrollBar * pVSB = GetVScrollBar())
657                 rcClient.right -= pVSB->GetScrollBarWidth();
658
659         rcClient.Normalize();
660
661         if (rcWindow.Contains(rcClient))
662                 return rcClient;
663         else
664                 return CPDF_Rect();
665 }
666
667 CPDF_Point CPWL_Wnd::GetCenterPoint() const
668 {
669         CPDF_Rect rcClient = GetClientRect();
670
671         return CPDF_Point((rcClient.left + rcClient.right) * 0.5f,
672                 (rcClient.top + rcClient.bottom) * 0.5f);
673 }
674
675 CPDF_Rect CPWL_Wnd::GetClientCenterSquare() const
676 {
677         return CPWL_Utils::GetCenterSquare(GetClientRect());
678 }
679
680 CPDF_Rect CPWL_Wnd::GetWindowCenterSquare() const
681 {
682         return CPWL_Utils::GetCenterSquare(CPWL_Utils::DeflateRect(GetWindowRect(),0.1f));
683 }
684
685 FX_BOOL CPWL_Wnd::HasFlag(FX_DWORD dwFlags) const
686 {
687         return (m_sPrivateParam.dwFlags & dwFlags) != 0;
688 }
689
690 void CPWL_Wnd::RemoveFlag(FX_DWORD dwFlags)
691 {
692         m_sPrivateParam.dwFlags &= ~dwFlags;
693 }
694
695 void CPWL_Wnd::AddFlag(FX_DWORD dwFlags)
696 {
697         m_sPrivateParam.dwFlags |= dwFlags;
698 }
699
700 CPWL_Color CPWL_Wnd::GetBackgroundColor() const
701 {
702         return m_sPrivateParam.sBackgroundColor;
703 }
704
705 void CPWL_Wnd::SetBackgroundColor(const CPWL_Color & color)
706 {
707         m_sPrivateParam.sBackgroundColor = color;
708 }
709
710 void CPWL_Wnd::SetTextColor(const CPWL_Color & color)
711 {
712         m_sPrivateParam.sTextColor = color;
713 }
714
715 void CPWL_Wnd::SetTextStrokeColor(const CPWL_Color & color)
716 {
717         m_sPrivateParam.sTextStrokeColor = color;
718 }
719
720 CPWL_Color CPWL_Wnd::GetTextColor() const
721 {
722         return m_sPrivateParam.sTextColor;
723 }
724
725 CPWL_Color CPWL_Wnd::GetTextStrokeColor() const
726 {
727         return m_sPrivateParam.sTextStrokeColor;
728 }
729
730 int32_t CPWL_Wnd::GetBorderStyle() const
731 {
732         return m_sPrivateParam.nBorderStyle;
733 }
734
735 void CPWL_Wnd::SetBorderStyle(int32_t nBorderStyle)
736 {
737         if (HasFlag(PWS_BORDER))
738                 m_sPrivateParam.nBorderStyle = nBorderStyle;
739 }
740
741 int32_t CPWL_Wnd::GetBorderWidth() const
742 {
743         if (HasFlag(PWS_BORDER))
744                 return m_sPrivateParam.dwBorderWidth;
745
746         return 0;
747 }
748
749 int32_t CPWL_Wnd::GetInnerBorderWidth() const
750 {
751         /*
752         switch (GetBorderStyle())
753         {
754         case PBS_BEVELED:
755         case PBS_INSET:
756                 return GetBorderWidth() / 2;
757         }
758         */
759         return 0;
760 }
761
762 void CPWL_Wnd::SetBorderWidth(int32_t nBorderWidth)
763 {
764         if (HasFlag(PWS_BORDER))
765                 m_sPrivateParam.dwBorderWidth = nBorderWidth;
766 }
767
768 CPWL_Color CPWL_Wnd::GetBorderColor() const
769 {
770         if (HasFlag(PWS_BORDER))
771                 return m_sPrivateParam.sBorderColor;
772
773         return CPWL_Color();
774 }
775
776 void CPWL_Wnd::SetBorderColor(const CPWL_Color & color)
777 {
778         if (HasFlag(PWS_BORDER))
779                 m_sPrivateParam.sBorderColor = color;
780 }
781
782 CPWL_Dash CPWL_Wnd::GetBorderDash() const
783 {
784         return m_sPrivateParam.sDash;
785 }
786
787 void* CPWL_Wnd::GetAttachedData() const
788 {
789         return m_sPrivateParam.pAttachedData;
790 }
791
792 void CPWL_Wnd::SetBorderDash(const CPWL_Dash & sDash)
793 {
794         if (HasFlag(PWS_BORDER))
795                 m_sPrivateParam.sDash = sDash;
796 }
797
798 CPWL_ScrollBar* CPWL_Wnd::GetVScrollBar() const
799 {
800         if (HasFlag(PWS_VSCROLL))
801                 return m_pVScrollBar;
802
803         return NULL;
804 }
805
806 void CPWL_Wnd::CreateScrollBar(const PWL_CREATEPARAM & cp)
807 {
808         CreateVScrollBar(cp);
809 }
810
811 void CPWL_Wnd::CreateVScrollBar(const PWL_CREATEPARAM & cp)
812 {
813         if (!m_pVScrollBar && HasFlag(PWS_VSCROLL))
814         {
815                 PWL_CREATEPARAM scp = cp;
816
817                 //flags
818                 scp.dwFlags = PWS_CHILD| PWS_BACKGROUND | PWS_AUTOTRANSPARENT | PWS_NOREFRESHCLIP;
819
820                 scp.pParentWnd = this;
821                 scp.sBackgroundColor = PWL_DEFAULT_WHITECOLOR;
822                 scp.eCursorType = FXCT_ARROW;
823                 scp.nTransparency = PWL_SCROLLBAR_TRANSPARANCY;
824
825                 if ((m_pVScrollBar = new CPWL_ScrollBar(SBT_VSCROLL)))
826                         m_pVScrollBar->Create(scp);
827         }
828 }
829
830 void CPWL_Wnd::SetCapture()
831 {
832         if (CPWL_MsgControl * pMsgCtrl = GetMsgControl())
833                 pMsgCtrl->SetCapture(this);
834 }
835
836 void CPWL_Wnd::ReleaseCapture()
837 {
838         for (int32_t i=0,sz=m_aChildren.GetSize(); i<sz; i++)
839                 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i))
840                         pChild->ReleaseCapture();
841
842         if (CPWL_MsgControl * pMsgCtrl = GetMsgControl())
843                 pMsgCtrl->ReleaseCapture();
844 }
845
846 void CPWL_Wnd::SetFocus()
847 {
848         if (CPWL_MsgControl * pMsgCtrl = GetMsgControl())
849         {
850                 if (!pMsgCtrl->IsMainCaptureKeyboard(this))
851                         pMsgCtrl->KillFocus();
852                 pMsgCtrl->SetFocus(this);
853         }
854 }
855
856 void CPWL_Wnd::KillFocus()
857 {
858         if (CPWL_MsgControl * pMsgCtrl = GetMsgControl())
859         {
860                 if (pMsgCtrl->IsWndCaptureKeyboard(this))
861                         pMsgCtrl->KillFocus();
862         }
863 }
864
865 void CPWL_Wnd::OnSetFocus()
866 {
867 }
868
869 void CPWL_Wnd::OnKillFocus()
870 {
871 }
872
873 FX_BOOL CPWL_Wnd::WndHitTest(const CPDF_Point & point) const
874 {
875         return IsValid() && IsVisible() && GetWindowRect().Contains(point.x,point.y);
876 }
877
878 FX_BOOL CPWL_Wnd::ClientHitTest(const CPDF_Point & point) const
879 {
880         return IsValid() && IsVisible() && GetClientRect().Contains(point.x,point.y);
881 }
882
883 const CPWL_Wnd * CPWL_Wnd::GetRootWnd() const
884 {
885         if (m_sPrivateParam.pParentWnd)
886                 return m_sPrivateParam.pParentWnd->GetRootWnd();
887         else
888                 return this;
889 }
890
891 void CPWL_Wnd::SetVisible(FX_BOOL bVisible)
892 {
893         if (IsValid())
894         {
895                 for (int32_t i=0,sz=m_aChildren.GetSize(); i<sz; i++)
896                 {
897                         if (CPWL_Wnd* pChild = m_aChildren.GetAt(i))
898                         {
899                                 pChild->SetVisible(bVisible);
900                         }
901                 }
902
903                 if (bVisible != m_bVisible)
904                 {
905                         m_bVisible = bVisible;
906                         RePosChildWnd();
907                         InvalidateRect();
908                 }
909         }
910 }
911
912 void CPWL_Wnd::SetClipRect(const CPDF_Rect & rect)
913 {
914         m_rcClip = rect;
915         m_rcClip.Normalize();
916 }
917
918 CPDF_Rect CPWL_Wnd::GetClipRect() const
919 {
920         return m_rcClip;
921 }
922
923 FX_BOOL CPWL_Wnd::IsReadOnly() const
924 {
925         return HasFlag(PWS_READONLY);
926 }
927
928 void CPWL_Wnd::RePosChildWnd()
929 {
930         CPDF_Rect rcContent = CPWL_Utils::DeflateRect(GetWindowRect(),(FX_FLOAT)(GetBorderWidth()+GetInnerBorderWidth()));
931
932         CPWL_ScrollBar * pVSB = GetVScrollBar();
933
934         CPDF_Rect rcVScroll = CPDF_Rect(rcContent.right - PWL_SCROLLBAR_WIDTH,
935                                                         rcContent.bottom,
936                                                         rcContent.right-1.0f,
937                                                         rcContent.top);
938
939         if (pVSB) pVSB->Move(rcVScroll,TRUE,FALSE);
940 }
941
942 void CPWL_Wnd::CreateChildWnd(const PWL_CREATEPARAM & cp)
943 {
944 }
945
946 void CPWL_Wnd::SetCursor()
947 {
948         if (IsValid())
949         {
950                 if (IFX_SystemHandler* pSH = GetSystemHandler())
951                 {
952                         int32_t nCursorType = GetCreationParam().eCursorType;
953                         pSH->SetCursor(nCursorType);
954                 }
955         }
956 }
957
958 void CPWL_Wnd::CreateMsgControl()
959 {
960         if (!m_sPrivateParam.pMsgControl)
961                 m_sPrivateParam.pMsgControl = new CPWL_MsgControl(this);
962 }
963
964 void CPWL_Wnd::DestroyMsgControl()
965 {
966         if (CPWL_MsgControl* pMsgControl = GetMsgControl())
967                 if (pMsgControl->IsWndCreated(this))
968                         delete pMsgControl;
969 }
970
971 CPWL_MsgControl* CPWL_Wnd::GetMsgControl() const
972 {
973         return m_sPrivateParam.pMsgControl;
974 }
975
976 FX_BOOL CPWL_Wnd::IsCaptureMouse() const
977 {
978         return IsWndCaptureMouse(this);
979 }
980
981 FX_BOOL CPWL_Wnd::IsWndCaptureMouse(const CPWL_Wnd * pWnd) const
982 {
983         if (CPWL_MsgControl * pCtrl = GetMsgControl())
984                 return pCtrl->IsWndCaptureMouse(pWnd);
985
986         return FALSE;
987 }
988
989 FX_BOOL CPWL_Wnd::IsWndCaptureKeyboard(const CPWL_Wnd * pWnd) const
990 {
991         if (CPWL_MsgControl * pCtrl = GetMsgControl())
992                 return pCtrl->IsWndCaptureKeyboard(pWnd);
993
994         return FALSE;
995 }
996
997 FX_BOOL CPWL_Wnd::IsFocused() const
998 {
999         if (CPWL_MsgControl * pCtrl = GetMsgControl())
1000                 return pCtrl->IsMainCaptureKeyboard(this);
1001
1002         return FALSE;
1003 }
1004
1005 CPDF_Rect CPWL_Wnd::GetFocusRect() const
1006 {
1007         return CPWL_Utils::InflateRect(GetWindowRect(),1);
1008 }
1009
1010 FX_FLOAT CPWL_Wnd::GetFontSize() const
1011 {
1012         return m_sPrivateParam.fFontSize;
1013 }
1014
1015 void CPWL_Wnd::SetFontSize(FX_FLOAT fFontSize)
1016 {
1017         m_sPrivateParam.fFontSize = fFontSize;
1018 }
1019
1020 IFX_SystemHandler* CPWL_Wnd::GetSystemHandler() const
1021 {
1022         return m_sPrivateParam.pSystemHandler;
1023 }
1024
1025 IPWL_FocusHandler* CPWL_Wnd::GetFocusHandler() const
1026 {
1027         return m_sPrivateParam.pFocusHandler;
1028 }
1029
1030 IPWL_Provider* CPWL_Wnd::GetProvider() const
1031 {
1032         return m_sPrivateParam.pProvider;
1033 }
1034
1035 IFX_Edit_FontMap* CPWL_Wnd::GetFontMap() const
1036 {
1037         return m_sPrivateParam.pFontMap;
1038 }
1039
1040 CPWL_Color CPWL_Wnd::GetBorderLeftTopColor(int32_t nBorderStyle) const
1041 {
1042         CPWL_Color color;
1043
1044         switch (nBorderStyle)
1045         {
1046                 case PBS_SOLID:
1047                         break;
1048                 case PBS_DASH:
1049                         break;
1050                 case PBS_BEVELED:
1051                         color = CPWL_Color(COLORTYPE_GRAY,1);
1052                         break;
1053                 case PBS_INSET:
1054                         color = CPWL_Color(COLORTYPE_GRAY,0.5f);
1055                         break;
1056                 case PBS_UNDERLINED:
1057                         break;
1058         }
1059
1060         return color;
1061 }
1062
1063 CPWL_Color CPWL_Wnd::GetBorderRightBottomColor(int32_t nBorderStyle) const
1064 {
1065         CPWL_Color color;
1066
1067         switch (nBorderStyle)
1068         {
1069                 case PBS_SOLID:
1070                         break;
1071                 case PBS_DASH:
1072                         break;
1073                 case PBS_BEVELED:
1074                         color = CPWL_Utils::DevideColor(GetBackgroundColor(),2);
1075                         break;
1076                 case PBS_INSET:
1077                         color = CPWL_Color(COLORTYPE_GRAY,0.75f);
1078                         break;
1079                 case PBS_UNDERLINED:
1080                         break;
1081         }
1082
1083         return color;
1084 }
1085
1086 /* ----------------------------------------------------------------- */
1087
1088 int32_t CPWL_Wnd::GetTransparency()
1089 {
1090         return m_sPrivateParam.nTransparency;
1091 }
1092
1093 void CPWL_Wnd::SetTransparency(int32_t nTransparency)
1094 {
1095         for (int32_t i=0,sz=m_aChildren.GetSize(); i<sz; i++)
1096         {
1097                 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i))
1098                 {
1099                         pChild->SetTransparency(nTransparency);
1100                 }
1101         }
1102
1103         m_sPrivateParam.nTransparency = nTransparency;
1104 }
1105
1106 CPDF_Matrix     CPWL_Wnd::GetWindowMatrix() const
1107 {
1108         CPDF_Matrix mt = GetChildToRoot();
1109
1110         if (IPWL_Provider* pProvider = GetProvider())
1111         {
1112                 mt.Concat(pProvider->GetWindowMatrix(GetAttachedData()));
1113                 return mt;
1114         }
1115
1116         return mt;
1117 }
1118
1119 void CPWL_Wnd::PWLtoWnd(const CPDF_Point& point, int32_t& x, int32_t& y) const
1120 {
1121         CPDF_Matrix mt = GetWindowMatrix();
1122         CPDF_Point pt = point;
1123         mt.Transform(pt.x,pt.y);
1124         x = (int32_t)(pt.x+0.5);
1125         y = (int32_t)(pt.y+0.5);
1126 }
1127
1128 FX_RECT CPWL_Wnd::PWLtoWnd(const CPDF_Rect & rect) const
1129 {
1130         CPDF_Rect rcTemp = rect;
1131         CPDF_Matrix mt = GetWindowMatrix();
1132         mt.TransformRect(rcTemp);
1133         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));
1134 }
1135
1136 FX_HWND CPWL_Wnd::GetAttachedHWnd() const
1137 {
1138         return m_sPrivateParam.hAttachedWnd;
1139 }
1140
1141 CPDF_Point CPWL_Wnd::ChildToParent(const CPDF_Point& point) const
1142 {
1143         CPDF_Matrix mt = GetChildMatrix();
1144         if (mt.IsIdentity())
1145                 return point;
1146         else
1147         {
1148                 CPDF_Point pt = point;
1149                 mt.Transform(pt.x,pt.y);
1150                 return pt;
1151         }
1152 }
1153
1154 CPDF_Rect CPWL_Wnd::ChildToParent(const CPDF_Rect& rect) const
1155 {
1156         CPDF_Matrix mt = GetChildMatrix();
1157         if (mt.IsIdentity())
1158                 return rect;
1159         else
1160         {
1161                 CPDF_Rect rc = rect;
1162                 mt.TransformRect(rc);
1163                 return rc;
1164         }
1165 }
1166
1167 CPDF_Point CPWL_Wnd::ParentToChild(const CPDF_Point& point) const
1168 {
1169         CPDF_Matrix mt = GetChildMatrix();
1170         if (mt.IsIdentity())
1171                 return point;
1172         else
1173         {
1174                 mt.SetReverse(mt);
1175                 CPDF_Point pt = point;
1176                 mt.Transform(pt.x,pt.y);
1177                 return pt;
1178         }
1179 }
1180
1181 CPDF_Rect CPWL_Wnd::ParentToChild(const CPDF_Rect& rect) const
1182 {
1183         CPDF_Matrix mt = GetChildMatrix();
1184         if (mt.IsIdentity())
1185                 return rect;
1186         else
1187         {
1188                 mt.SetReverse(mt);
1189                 CPDF_Rect rc = rect;
1190                 mt.TransformRect(rc);
1191                 return rc;
1192         }
1193 }
1194
1195 CPDF_Matrix CPWL_Wnd::GetChildToRoot() const
1196 {
1197         CPDF_Matrix mt(1,0,0,1,0,0);
1198
1199         if (HasFlag(PWS_CHILD))
1200         {
1201                 const CPWL_Wnd* pParent = this;
1202                 while (pParent)
1203                 {
1204                         mt.Concat(pParent->GetChildMatrix());
1205                         pParent = pParent->GetParentWindow();
1206                 }
1207         }
1208
1209         return mt;
1210 }
1211
1212 CPDF_Matrix CPWL_Wnd::GetChildMatrix() const
1213 {
1214         if (HasFlag(PWS_CHILD))
1215                 return m_sPrivateParam.mtChild;
1216
1217         return CPDF_Matrix(1,0,0,1,0,0);
1218 }
1219
1220 void CPWL_Wnd::SetChildMatrix(const CPDF_Matrix& mt)
1221 {
1222         m_sPrivateParam.mtChild = mt;
1223 }
1224
1225 const CPWL_Wnd* CPWL_Wnd::GetFocused() const
1226 {
1227         if (CPWL_MsgControl * pMsgCtrl = GetMsgControl())
1228         {
1229                 return pMsgCtrl->m_pMainKeyboardWnd;
1230         }
1231
1232         return NULL;
1233 }
1234
1235 void CPWL_Wnd::EnableWindow(FX_BOOL bEnable)
1236 {
1237         if (m_bEnabled != bEnable)
1238         {
1239                 for (int32_t i=0,sz=m_aChildren.GetSize(); i<sz; i++)
1240                 {
1241                         if (CPWL_Wnd* pChild = m_aChildren.GetAt(i))
1242                         {
1243                                 pChild->EnableWindow(bEnable);
1244                         }
1245                 }
1246
1247                 m_bEnabled = bEnable;
1248
1249                 if (bEnable)
1250                         OnEnabled();
1251                 else
1252                         OnDisabled();
1253         }
1254 }
1255
1256 FX_BOOL CPWL_Wnd::IsEnabled()
1257 {
1258         return m_bEnabled;
1259 }
1260
1261 void CPWL_Wnd::OnEnabled()
1262 {
1263 }
1264
1265 void CPWL_Wnd::OnDisabled()
1266 {
1267 }
1268
1269 FX_BOOL CPWL_Wnd::IsCTRLpressed(FX_DWORD nFlag) const
1270 {
1271         if (IFX_SystemHandler* pSystemHandler = GetSystemHandler())
1272         {
1273                 return pSystemHandler->IsCTRLKeyDown(nFlag);
1274         }
1275
1276         return FALSE;
1277 }
1278
1279 FX_BOOL CPWL_Wnd::IsSHIFTpressed(FX_DWORD nFlag) const
1280 {
1281         if (IFX_SystemHandler* pSystemHandler = GetSystemHandler())
1282         {
1283                 return pSystemHandler->IsSHIFTKeyDown(nFlag);
1284         }
1285
1286         return FALSE;
1287 }
1288
1289 FX_BOOL CPWL_Wnd::IsALTpressed(FX_DWORD nFlag) const
1290 {
1291         if (IFX_SystemHandler* pSystemHandler = GetSystemHandler())
1292         {
1293                 return pSystemHandler->IsALTKeyDown(nFlag);
1294         }
1295
1296         return FALSE;
1297 }
1298
1299 FX_BOOL CPWL_Wnd::IsINSERTpressed(FX_DWORD nFlag) const
1300 {
1301         if (IFX_SystemHandler* pSystemHandler = GetSystemHandler())
1302         {
1303                 return pSystemHandler->IsINSERTKeyDown(nFlag);
1304         }
1305
1306         return FALSE;
1307 }
1308