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 "fpdfsdk/include/pdfwindow/PWL_ScrollBar.h"
10 #include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
11 #include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"
12
GetPWLTimeMap()13 static std::map<int32_t, CPWL_Timer*>& GetPWLTimeMap() {
14 // Leak the object at shutdown.
15 static auto timeMap = new std::map<int32_t, CPWL_Timer*>;
16 return *timeMap;
17 }
18
CPWL_Timer(CPWL_TimerHandler * pAttached,IFX_SystemHandler * pSystemHandler)19 CPWL_Timer::CPWL_Timer(CPWL_TimerHandler* pAttached,
20 IFX_SystemHandler* pSystemHandler)
21 : m_nTimerID(0), m_pAttached(pAttached), m_pSystemHandler(pSystemHandler) {
22 ASSERT(m_pAttached);
23 ASSERT(m_pSystemHandler);
24 }
25
~CPWL_Timer()26 CPWL_Timer::~CPWL_Timer() {
27 KillPWLTimer();
28 }
29
SetPWLTimer(int32_t nElapse)30 int32_t CPWL_Timer::SetPWLTimer(int32_t nElapse) {
31 if (m_nTimerID != 0)
32 KillPWLTimer();
33 m_nTimerID = m_pSystemHandler->SetTimer(nElapse, TimerProc);
34
35 GetPWLTimeMap()[m_nTimerID] = this;
36 return m_nTimerID;
37 }
38
KillPWLTimer()39 void CPWL_Timer::KillPWLTimer() {
40 if (m_nTimerID == 0)
41 return;
42
43 m_pSystemHandler->KillTimer(m_nTimerID);
44 GetPWLTimeMap().erase(m_nTimerID);
45 m_nTimerID = 0;
46 }
47
TimerProc(int32_t idEvent)48 void CPWL_Timer::TimerProc(int32_t idEvent) {
49 auto it = GetPWLTimeMap().find(idEvent);
50 if (it == GetPWLTimeMap().end())
51 return;
52
53 CPWL_Timer* pTimer = it->second;
54 if (pTimer->m_pAttached)
55 pTimer->m_pAttached->TimerProc();
56 }
57
CPWL_TimerHandler()58 CPWL_TimerHandler::CPWL_TimerHandler() : m_pTimer(NULL) {}
59
~CPWL_TimerHandler()60 CPWL_TimerHandler::~CPWL_TimerHandler() {
61 delete m_pTimer;
62 }
63
BeginTimer(int32_t nElapse)64 void CPWL_TimerHandler::BeginTimer(int32_t nElapse) {
65 if (!m_pTimer)
66 m_pTimer = new CPWL_Timer(this, GetSystemHandler());
67
68 if (m_pTimer)
69 m_pTimer->SetPWLTimer(nElapse);
70 }
71
EndTimer()72 void CPWL_TimerHandler::EndTimer() {
73 if (m_pTimer)
74 m_pTimer->KillPWLTimer();
75 }
76
TimerProc()77 void CPWL_TimerHandler::TimerProc() {}
78
79 class CPWL_MsgControl {
80 friend class CPWL_Wnd;
81
82 public:
CPWL_MsgControl(CPWL_Wnd * pWnd)83 explicit CPWL_MsgControl(CPWL_Wnd* pWnd) {
84 m_pCreatedWnd = pWnd;
85 Default();
86 }
87
~CPWL_MsgControl()88 ~CPWL_MsgControl() {
89 Default();
90 }
91
Default()92 void Default() {
93 m_aMousePath.RemoveAll();
94 m_aKeyboardPath.RemoveAll();
95 m_pMainMouseWnd = NULL;
96 m_pMainKeyboardWnd = NULL;
97 }
98
IsWndCreated(const CPWL_Wnd * pWnd) const99 FX_BOOL IsWndCreated(const CPWL_Wnd* pWnd) const {
100 return m_pCreatedWnd == pWnd;
101 }
102
IsMainCaptureMouse(const CPWL_Wnd * pWnd) const103 FX_BOOL IsMainCaptureMouse(const CPWL_Wnd* pWnd) const {
104 return pWnd == m_pMainMouseWnd;
105 }
106
IsWndCaptureMouse(const CPWL_Wnd * pWnd) const107 FX_BOOL IsWndCaptureMouse(const CPWL_Wnd* pWnd) const {
108 if (pWnd) {
109 for (int32_t i = 0, sz = m_aMousePath.GetSize(); i < sz; i++) {
110 if (m_aMousePath.GetAt(i) == pWnd)
111 return TRUE;
112 }
113 }
114
115 return FALSE;
116 }
117
IsMainCaptureKeyboard(const CPWL_Wnd * pWnd) const118 FX_BOOL IsMainCaptureKeyboard(const CPWL_Wnd* pWnd) const {
119 return pWnd == m_pMainKeyboardWnd;
120 }
121
IsWndCaptureKeyboard(const CPWL_Wnd * pWnd) const122 FX_BOOL IsWndCaptureKeyboard(const CPWL_Wnd* pWnd) const {
123 if (pWnd) {
124 for (int32_t i = 0, sz = m_aKeyboardPath.GetSize(); i < sz; i++) {
125 if (m_aKeyboardPath.GetAt(i) == pWnd)
126 return TRUE;
127 }
128 }
129
130 return FALSE;
131 }
132
SetFocus(CPWL_Wnd * pWnd)133 void SetFocus(CPWL_Wnd* pWnd) {
134 m_aKeyboardPath.RemoveAll();
135
136 if (pWnd) {
137 m_pMainKeyboardWnd = pWnd;
138
139 CPWL_Wnd* pParent = pWnd;
140 while (pParent) {
141 m_aKeyboardPath.Add(pParent);
142 pParent = pParent->GetParentWindow();
143 }
144
145 pWnd->OnSetFocus();
146 }
147 }
148
KillFocus()149 void KillFocus() {
150 if (m_aKeyboardPath.GetSize() > 0)
151 if (CPWL_Wnd* pWnd = m_aKeyboardPath.GetAt(0))
152 pWnd->OnKillFocus();
153
154 m_pMainKeyboardWnd = NULL;
155 m_aKeyboardPath.RemoveAll();
156 }
157
SetCapture(CPWL_Wnd * pWnd)158 void SetCapture(CPWL_Wnd* pWnd) {
159 m_aMousePath.RemoveAll();
160
161 if (pWnd) {
162 m_pMainMouseWnd = pWnd;
163
164 CPWL_Wnd* pParent = pWnd;
165 while (pParent) {
166 m_aMousePath.Add(pParent);
167 pParent = pParent->GetParentWindow();
168 }
169 }
170 }
171
ReleaseCapture()172 void ReleaseCapture() {
173 m_pMainMouseWnd = NULL;
174 m_aMousePath.RemoveAll();
175 }
176
177 private:
178 CFX_ArrayTemplate<CPWL_Wnd*> m_aMousePath;
179 CFX_ArrayTemplate<CPWL_Wnd*> m_aKeyboardPath;
180 CPWL_Wnd* m_pCreatedWnd;
181 CPWL_Wnd* m_pMainMouseWnd;
182 CPWL_Wnd* m_pMainKeyboardWnd;
183 };
184
CPWL_Wnd()185 CPWL_Wnd::CPWL_Wnd()
186 : m_pVScrollBar(NULL),
187 m_rcWindow(),
188 m_rcClip(),
189 m_bCreated(FALSE),
190 m_bVisible(FALSE),
191 m_bNotifying(FALSE),
192 m_bEnabled(TRUE) {}
193
~CPWL_Wnd()194 CPWL_Wnd::~CPWL_Wnd() {
195 ASSERT(m_bCreated == FALSE);
196 }
197
GetClassName() const198 CFX_ByteString CPWL_Wnd::GetClassName() const {
199 return "CPWL_Wnd";
200 }
201
Create(const PWL_CREATEPARAM & cp)202 void CPWL_Wnd::Create(const PWL_CREATEPARAM& cp) {
203 if (!IsValid()) {
204 m_sPrivateParam = cp;
205
206 OnCreate(m_sPrivateParam);
207
208 m_sPrivateParam.rcRectWnd.Normalize();
209 m_rcWindow = m_sPrivateParam.rcRectWnd;
210 m_rcClip = CPWL_Utils::InflateRect(m_rcWindow, 1.0f);
211
212 CreateMsgControl();
213
214 if (m_sPrivateParam.pParentWnd)
215 m_sPrivateParam.pParentWnd->OnNotify(this, PNM_ADDCHILD);
216
217 PWL_CREATEPARAM ccp = m_sPrivateParam;
218
219 ccp.dwFlags &= 0xFFFF0000L; // remove sub styles
220 ccp.mtChild = CFX_Matrix(1, 0, 0, 1, 0, 0);
221
222 CreateScrollBar(ccp);
223 CreateChildWnd(ccp);
224
225 m_bVisible = HasFlag(PWS_VISIBLE);
226
227 OnCreated();
228
229 RePosChildWnd();
230 m_bCreated = TRUE;
231 }
232 }
233
OnCreate(PWL_CREATEPARAM & cp)234 void CPWL_Wnd::OnCreate(PWL_CREATEPARAM& cp) {}
235
OnCreated()236 void CPWL_Wnd::OnCreated() {}
237
OnDestroy()238 void CPWL_Wnd::OnDestroy() {}
239
InvalidateFocusHandler(IPWL_FocusHandler * handler)240 void CPWL_Wnd::InvalidateFocusHandler(IPWL_FocusHandler* handler) {
241 if (m_sPrivateParam.pFocusHandler == handler)
242 m_sPrivateParam.pFocusHandler = nullptr;
243 }
244
InvalidateProvider(IPWL_Provider * provider)245 void CPWL_Wnd::InvalidateProvider(IPWL_Provider* provider) {
246 if (m_sPrivateParam.pProvider == provider)
247 m_sPrivateParam.pProvider = nullptr;
248 }
249
Destroy()250 void CPWL_Wnd::Destroy() {
251 KillFocus();
252
253 OnDestroy();
254
255 if (m_bCreated) {
256 for (int32_t i = m_aChildren.GetSize() - 1; i >= 0; i--) {
257 if (CPWL_Wnd* pChild = m_aChildren[i]) {
258 pChild->Destroy();
259 delete pChild;
260 pChild = NULL;
261 }
262 }
263
264 if (m_sPrivateParam.pParentWnd)
265 m_sPrivateParam.pParentWnd->OnNotify(this, PNM_REMOVECHILD);
266 m_bCreated = FALSE;
267 }
268
269 DestroyMsgControl();
270
271 FXSYS_memset(&m_sPrivateParam, 0, sizeof(PWL_CREATEPARAM));
272 m_aChildren.RemoveAll();
273 m_pVScrollBar = NULL;
274 }
275
Move(const CPDF_Rect & rcNew,FX_BOOL bReset,FX_BOOL bRefresh)276 void CPWL_Wnd::Move(const CPDF_Rect& rcNew, FX_BOOL bReset, FX_BOOL bRefresh) {
277 if (IsValid()) {
278 CPDF_Rect rcOld = GetWindowRect();
279
280 m_rcWindow = rcNew;
281 m_rcWindow.Normalize();
282
283 if (rcOld.left != rcNew.left || rcOld.right != rcNew.right ||
284 rcOld.top != rcNew.top || rcOld.bottom != rcNew.bottom) {
285 if (bReset) {
286 RePosChildWnd();
287 }
288 }
289 if (bRefresh) {
290 InvalidateRectMove(rcOld, rcNew);
291 }
292
293 m_sPrivateParam.rcRectWnd = m_rcWindow;
294 }
295 }
296
InvalidateRectMove(const CPDF_Rect & rcOld,const CPDF_Rect & rcNew)297 void CPWL_Wnd::InvalidateRectMove(const CPDF_Rect& rcOld,
298 const CPDF_Rect& rcNew) {
299 CPDF_Rect rcUnion = rcOld;
300 rcUnion.Union(rcNew);
301
302 InvalidateRect(&rcUnion);
303 }
304
GetAppearanceStream(CFX_ByteTextBuf & sAppStream)305 void CPWL_Wnd::GetAppearanceStream(CFX_ByteTextBuf& sAppStream) {
306 if (IsValid() && IsVisible()) {
307 GetThisAppearanceStream(sAppStream);
308 GetChildAppearanceStream(sAppStream);
309 }
310 }
311
312 // if don't set,Get default apperance stream
GetThisAppearanceStream(CFX_ByteTextBuf & sAppStream)313 void CPWL_Wnd::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) {
314 CPDF_Rect rectWnd = GetWindowRect();
315 if (!rectWnd.IsEmpty()) {
316 CFX_ByteTextBuf sThis;
317
318 if (HasFlag(PWS_BACKGROUND))
319 sThis << CPWL_Utils::GetRectFillAppStream(rectWnd, GetBackgroundColor());
320
321 if (HasFlag(PWS_BORDER)) {
322 sThis << CPWL_Utils::GetBorderAppStream(
323 rectWnd, (FX_FLOAT)GetBorderWidth(), GetBorderColor(),
324 GetBorderLeftTopColor(GetBorderStyle()),
325 GetBorderRightBottomColor(GetBorderStyle()), GetBorderStyle(),
326 GetBorderDash());
327 }
328
329 sAppStream << sThis;
330 }
331 }
332
GetChildAppearanceStream(CFX_ByteTextBuf & sAppStream)333 void CPWL_Wnd::GetChildAppearanceStream(CFX_ByteTextBuf& sAppStream) {
334 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
335 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
336 pChild->GetAppearanceStream(sAppStream);
337 }
338 }
339 }
340
DrawAppearance(CFX_RenderDevice * pDevice,CFX_Matrix * pUser2Device)341 void CPWL_Wnd::DrawAppearance(CFX_RenderDevice* pDevice,
342 CFX_Matrix* pUser2Device) {
343 if (IsValid() && IsVisible()) {
344 DrawThisAppearance(pDevice, pUser2Device);
345 DrawChildAppearance(pDevice, pUser2Device);
346 }
347 }
348
DrawThisAppearance(CFX_RenderDevice * pDevice,CFX_Matrix * pUser2Device)349 void CPWL_Wnd::DrawThisAppearance(CFX_RenderDevice* pDevice,
350 CFX_Matrix* pUser2Device) {
351 CPDF_Rect rectWnd = GetWindowRect();
352 if (!rectWnd.IsEmpty()) {
353 if (HasFlag(PWS_BACKGROUND)) {
354 CPDF_Rect rcClient = CPWL_Utils::DeflateRect(
355 rectWnd, (FX_FLOAT)(GetBorderWidth() + GetInnerBorderWidth()));
356 CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcClient,
357 GetBackgroundColor(), GetTransparency());
358 }
359
360 if (HasFlag(PWS_BORDER))
361 CPWL_Utils::DrawBorder(pDevice, pUser2Device, rectWnd,
362 (FX_FLOAT)GetBorderWidth(), GetBorderColor(),
363 GetBorderLeftTopColor(GetBorderStyle()),
364 GetBorderRightBottomColor(GetBorderStyle()),
365 GetBorderStyle(), GetTransparency());
366 }
367 }
368
DrawChildAppearance(CFX_RenderDevice * pDevice,CFX_Matrix * pUser2Device)369 void CPWL_Wnd::DrawChildAppearance(CFX_RenderDevice* pDevice,
370 CFX_Matrix* pUser2Device) {
371 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
372 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
373 CFX_Matrix mt = pChild->GetChildMatrix();
374 if (mt.IsIdentity()) {
375 pChild->DrawAppearance(pDevice, pUser2Device);
376 } else {
377 mt.Concat(*pUser2Device);
378 pChild->DrawAppearance(pDevice, &mt);
379 }
380 }
381 }
382 }
383
InvalidateRect(CPDF_Rect * pRect)384 void CPWL_Wnd::InvalidateRect(CPDF_Rect* pRect) {
385 if (IsValid()) {
386 CPDF_Rect rcRefresh = pRect ? *pRect : GetWindowRect();
387
388 if (!HasFlag(PWS_NOREFRESHCLIP)) {
389 CPDF_Rect rcClip = GetClipRect();
390 if (!rcClip.IsEmpty()) {
391 rcRefresh.Intersect(rcClip);
392 }
393 }
394
395 FX_RECT rcWin = PWLtoWnd(rcRefresh);
396 rcWin.left -= PWL_INVALIDATE_INFLATE;
397 rcWin.top -= PWL_INVALIDATE_INFLATE;
398 rcWin.right += PWL_INVALIDATE_INFLATE;
399 rcWin.bottom += PWL_INVALIDATE_INFLATE;
400
401 if (IFX_SystemHandler* pSH = GetSystemHandler()) {
402 if (FX_HWND hWnd = GetAttachedHWnd()) {
403 pSH->InvalidateRect(hWnd, rcWin);
404 }
405 }
406 }
407 }
408
409 #define PWL_IMPLEMENT_KEY_METHOD(key_method_name) \
410 FX_BOOL CPWL_Wnd::key_method_name(FX_WORD nChar, FX_DWORD nFlag) { \
411 if (IsValid() && IsVisible() && IsEnabled()) { \
412 if (IsWndCaptureKeyboard(this)) { \
413 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { \
414 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { \
415 if (IsWndCaptureKeyboard(pChild)) { \
416 return pChild->key_method_name(nChar, nFlag); \
417 } \
418 } \
419 } \
420 } \
421 } \
422 return FALSE; \
423 }
424
425 #define PWL_IMPLEMENT_MOUSE_METHOD(mouse_method_name) \
426 FX_BOOL CPWL_Wnd::mouse_method_name(const CPDF_Point& point, \
427 FX_DWORD nFlag) { \
428 if (IsValid() && IsVisible() && IsEnabled()) { \
429 if (IsWndCaptureMouse(this)) { \
430 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { \
431 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { \
432 if (IsWndCaptureMouse(pChild)) { \
433 return pChild->mouse_method_name(pChild->ParentToChild(point), \
434 nFlag); \
435 } \
436 } \
437 } \
438 SetCursor(); \
439 } else { \
440 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { \
441 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { \
442 if (pChild->WndHitTest(pChild->ParentToChild(point))) { \
443 return pChild->mouse_method_name(pChild->ParentToChild(point), \
444 nFlag); \
445 } \
446 } \
447 } \
448 if (WndHitTest(point)) \
449 SetCursor(); \
450 } \
451 } \
452 return FALSE; \
453 }
454
455 PWL_IMPLEMENT_KEY_METHOD(OnKeyDown)
PWL_IMPLEMENT_KEY_METHOD(OnKeyUp)456 PWL_IMPLEMENT_KEY_METHOD(OnKeyUp)
457 PWL_IMPLEMENT_KEY_METHOD(OnChar)
458
459 PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonDblClk)
460 PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonDown)
461 PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonUp)
462 PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonDblClk)
463 PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonDown)
464 PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonUp)
465 PWL_IMPLEMENT_MOUSE_METHOD(OnRButtonDown)
466 PWL_IMPLEMENT_MOUSE_METHOD(OnRButtonUp)
467 PWL_IMPLEMENT_MOUSE_METHOD(OnMouseMove)
468
469 FX_BOOL CPWL_Wnd::OnMouseWheel(short zDelta,
470 const CPDF_Point& point,
471 FX_DWORD nFlag) {
472 if (IsValid() && IsVisible() && IsEnabled()) {
473 SetCursor();
474 if (IsWndCaptureKeyboard(this)) {
475 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
476 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
477 if (IsWndCaptureKeyboard(pChild)) {
478 return pChild->OnMouseWheel(zDelta, pChild->ParentToChild(point),
479 nFlag);
480 }
481 }
482 }
483 }
484 }
485 return FALSE;
486 }
487
AddChild(CPWL_Wnd * pWnd)488 void CPWL_Wnd::AddChild(CPWL_Wnd* pWnd) {
489 m_aChildren.Add(pWnd);
490 }
491
RemoveChild(CPWL_Wnd * pWnd)492 void CPWL_Wnd::RemoveChild(CPWL_Wnd* pWnd) {
493 for (int32_t i = m_aChildren.GetSize() - 1; i >= 0; i--) {
494 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
495 if (pChild == pWnd) {
496 m_aChildren.RemoveAt(i);
497 break;
498 }
499 }
500 }
501 }
502
OnNotify(CPWL_Wnd * pWnd,FX_DWORD msg,intptr_t wParam,intptr_t lParam)503 void CPWL_Wnd::OnNotify(CPWL_Wnd* pWnd,
504 FX_DWORD msg,
505 intptr_t wParam,
506 intptr_t lParam) {
507 switch (msg) {
508 case PNM_ADDCHILD:
509 AddChild(pWnd);
510 break;
511 case PNM_REMOVECHILD:
512 RemoveChild(pWnd);
513 break;
514 default:
515 break;
516 }
517 }
518
IsValid() const519 FX_BOOL CPWL_Wnd::IsValid() const {
520 return m_bCreated;
521 }
522
GetCreationParam() const523 const PWL_CREATEPARAM& CPWL_Wnd::GetCreationParam() const {
524 return m_sPrivateParam;
525 }
526
GetParentWindow() const527 CPWL_Wnd* CPWL_Wnd::GetParentWindow() const {
528 return m_sPrivateParam.pParentWnd;
529 }
530
GetWindowRect() const531 CPDF_Rect CPWL_Wnd::GetWindowRect() const {
532 return m_rcWindow;
533 }
534
GetClientRect() const535 CPDF_Rect CPWL_Wnd::GetClientRect() const {
536 CPDF_Rect rcWindow = GetWindowRect();
537 CPDF_Rect rcClient = CPWL_Utils::DeflateRect(
538 rcWindow, (FX_FLOAT)(GetBorderWidth() + GetInnerBorderWidth()));
539 if (CPWL_ScrollBar* pVSB = GetVScrollBar())
540 rcClient.right -= pVSB->GetScrollBarWidth();
541
542 rcClient.Normalize();
543 return rcWindow.Contains(rcClient) ? rcClient : CPDF_Rect();
544 }
545
GetCenterPoint() const546 CPDF_Point CPWL_Wnd::GetCenterPoint() const {
547 CPDF_Rect rcClient = GetClientRect();
548 return CPDF_Point((rcClient.left + rcClient.right) * 0.5f,
549 (rcClient.top + rcClient.bottom) * 0.5f);
550 }
551
HasFlag(FX_DWORD dwFlags) const552 FX_BOOL CPWL_Wnd::HasFlag(FX_DWORD dwFlags) const {
553 return (m_sPrivateParam.dwFlags & dwFlags) != 0;
554 }
555
RemoveFlag(FX_DWORD dwFlags)556 void CPWL_Wnd::RemoveFlag(FX_DWORD dwFlags) {
557 m_sPrivateParam.dwFlags &= ~dwFlags;
558 }
559
AddFlag(FX_DWORD dwFlags)560 void CPWL_Wnd::AddFlag(FX_DWORD dwFlags) {
561 m_sPrivateParam.dwFlags |= dwFlags;
562 }
563
GetBackgroundColor() const564 CPWL_Color CPWL_Wnd::GetBackgroundColor() const {
565 return m_sPrivateParam.sBackgroundColor;
566 }
567
SetBackgroundColor(const CPWL_Color & color)568 void CPWL_Wnd::SetBackgroundColor(const CPWL_Color& color) {
569 m_sPrivateParam.sBackgroundColor = color;
570 }
571
SetTextColor(const CPWL_Color & color)572 void CPWL_Wnd::SetTextColor(const CPWL_Color& color) {
573 m_sPrivateParam.sTextColor = color;
574 }
575
SetTextStrokeColor(const CPWL_Color & color)576 void CPWL_Wnd::SetTextStrokeColor(const CPWL_Color& color) {
577 m_sPrivateParam.sTextStrokeColor = color;
578 }
579
GetTextColor() const580 CPWL_Color CPWL_Wnd::GetTextColor() const {
581 return m_sPrivateParam.sTextColor;
582 }
583
GetTextStrokeColor() const584 CPWL_Color CPWL_Wnd::GetTextStrokeColor() const {
585 return m_sPrivateParam.sTextStrokeColor;
586 }
587
GetBorderStyle() const588 int32_t CPWL_Wnd::GetBorderStyle() const {
589 return m_sPrivateParam.nBorderStyle;
590 }
591
SetBorderStyle(int32_t nBorderStyle)592 void CPWL_Wnd::SetBorderStyle(int32_t nBorderStyle) {
593 if (HasFlag(PWS_BORDER))
594 m_sPrivateParam.nBorderStyle = nBorderStyle;
595 }
596
GetBorderWidth() const597 int32_t CPWL_Wnd::GetBorderWidth() const {
598 if (HasFlag(PWS_BORDER))
599 return m_sPrivateParam.dwBorderWidth;
600
601 return 0;
602 }
603
GetInnerBorderWidth() const604 int32_t CPWL_Wnd::GetInnerBorderWidth() const {
605 return 0;
606 }
607
GetBorderColor() const608 CPWL_Color CPWL_Wnd::GetBorderColor() const {
609 if (HasFlag(PWS_BORDER))
610 return m_sPrivateParam.sBorderColor;
611
612 return CPWL_Color();
613 }
614
GetBorderDash() const615 const CPWL_Dash& CPWL_Wnd::GetBorderDash() const {
616 return m_sPrivateParam.sDash;
617 }
618
GetAttachedData() const619 void* CPWL_Wnd::GetAttachedData() const {
620 return m_sPrivateParam.pAttachedData;
621 }
622
GetVScrollBar() const623 CPWL_ScrollBar* CPWL_Wnd::GetVScrollBar() const {
624 if (HasFlag(PWS_VSCROLL))
625 return m_pVScrollBar;
626
627 return NULL;
628 }
629
CreateScrollBar(const PWL_CREATEPARAM & cp)630 void CPWL_Wnd::CreateScrollBar(const PWL_CREATEPARAM& cp) {
631 CreateVScrollBar(cp);
632 }
633
CreateVScrollBar(const PWL_CREATEPARAM & cp)634 void CPWL_Wnd::CreateVScrollBar(const PWL_CREATEPARAM& cp) {
635 if (!m_pVScrollBar && HasFlag(PWS_VSCROLL)) {
636 PWL_CREATEPARAM scp = cp;
637
638 // flags
639 scp.dwFlags =
640 PWS_CHILD | PWS_BACKGROUND | PWS_AUTOTRANSPARENT | PWS_NOREFRESHCLIP;
641
642 scp.pParentWnd = this;
643 scp.sBackgroundColor = PWL_DEFAULT_WHITECOLOR;
644 scp.eCursorType = FXCT_ARROW;
645 scp.nTransparency = PWL_SCROLLBAR_TRANSPARANCY;
646
647 m_pVScrollBar = new CPWL_ScrollBar(SBT_VSCROLL);
648 m_pVScrollBar->Create(scp);
649 }
650 }
651
SetCapture()652 void CPWL_Wnd::SetCapture() {
653 if (CPWL_MsgControl* pMsgCtrl = GetMsgControl())
654 pMsgCtrl->SetCapture(this);
655 }
656
ReleaseCapture()657 void CPWL_Wnd::ReleaseCapture() {
658 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++)
659 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i))
660 pChild->ReleaseCapture();
661
662 if (CPWL_MsgControl* pMsgCtrl = GetMsgControl())
663 pMsgCtrl->ReleaseCapture();
664 }
665
SetFocus()666 void CPWL_Wnd::SetFocus() {
667 if (CPWL_MsgControl* pMsgCtrl = GetMsgControl()) {
668 if (!pMsgCtrl->IsMainCaptureKeyboard(this))
669 pMsgCtrl->KillFocus();
670 pMsgCtrl->SetFocus(this);
671 }
672 }
673
KillFocus()674 void CPWL_Wnd::KillFocus() {
675 if (CPWL_MsgControl* pMsgCtrl = GetMsgControl()) {
676 if (pMsgCtrl->IsWndCaptureKeyboard(this))
677 pMsgCtrl->KillFocus();
678 }
679 }
680
OnSetFocus()681 void CPWL_Wnd::OnSetFocus() {}
682
OnKillFocus()683 void CPWL_Wnd::OnKillFocus() {}
684
WndHitTest(const CPDF_Point & point) const685 FX_BOOL CPWL_Wnd::WndHitTest(const CPDF_Point& point) const {
686 return IsValid() && IsVisible() && GetWindowRect().Contains(point.x, point.y);
687 }
688
ClientHitTest(const CPDF_Point & point) const689 FX_BOOL CPWL_Wnd::ClientHitTest(const CPDF_Point& point) const {
690 return IsValid() && IsVisible() && GetClientRect().Contains(point.x, point.y);
691 }
692
GetRootWnd() const693 const CPWL_Wnd* CPWL_Wnd::GetRootWnd() const {
694 if (m_sPrivateParam.pParentWnd)
695 return m_sPrivateParam.pParentWnd->GetRootWnd();
696
697 return this;
698 }
699
SetVisible(FX_BOOL bVisible)700 void CPWL_Wnd::SetVisible(FX_BOOL bVisible) {
701 if (IsValid()) {
702 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
703 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
704 pChild->SetVisible(bVisible);
705 }
706 }
707
708 if (bVisible != m_bVisible) {
709 m_bVisible = bVisible;
710 RePosChildWnd();
711 InvalidateRect();
712 }
713 }
714 }
715
SetClipRect(const CPDF_Rect & rect)716 void CPWL_Wnd::SetClipRect(const CPDF_Rect& rect) {
717 m_rcClip = rect;
718 m_rcClip.Normalize();
719 }
720
GetClipRect() const721 const CPDF_Rect& CPWL_Wnd::GetClipRect() const {
722 return m_rcClip;
723 }
724
IsReadOnly() const725 FX_BOOL CPWL_Wnd::IsReadOnly() const {
726 return HasFlag(PWS_READONLY);
727 }
728
RePosChildWnd()729 void CPWL_Wnd::RePosChildWnd() {
730 CPDF_Rect rcContent = CPWL_Utils::DeflateRect(
731 GetWindowRect(), (FX_FLOAT)(GetBorderWidth() + GetInnerBorderWidth()));
732
733 CPWL_ScrollBar* pVSB = GetVScrollBar();
734
735 CPDF_Rect rcVScroll =
736 CPDF_Rect(rcContent.right - PWL_SCROLLBAR_WIDTH, rcContent.bottom,
737 rcContent.right - 1.0f, rcContent.top);
738
739 if (pVSB)
740 pVSB->Move(rcVScroll, TRUE, FALSE);
741 }
742
CreateChildWnd(const PWL_CREATEPARAM & cp)743 void CPWL_Wnd::CreateChildWnd(const PWL_CREATEPARAM& cp) {}
744
SetCursor()745 void CPWL_Wnd::SetCursor() {
746 if (IsValid()) {
747 if (IFX_SystemHandler* pSH = GetSystemHandler()) {
748 int32_t nCursorType = GetCreationParam().eCursorType;
749 pSH->SetCursor(nCursorType);
750 }
751 }
752 }
753
CreateMsgControl()754 void CPWL_Wnd::CreateMsgControl() {
755 if (!m_sPrivateParam.pMsgControl)
756 m_sPrivateParam.pMsgControl = new CPWL_MsgControl(this);
757 }
758
DestroyMsgControl()759 void CPWL_Wnd::DestroyMsgControl() {
760 if (CPWL_MsgControl* pMsgControl = GetMsgControl())
761 if (pMsgControl->IsWndCreated(this))
762 delete pMsgControl;
763 }
764
GetMsgControl() const765 CPWL_MsgControl* CPWL_Wnd::GetMsgControl() const {
766 return m_sPrivateParam.pMsgControl;
767 }
768
IsCaptureMouse() const769 FX_BOOL CPWL_Wnd::IsCaptureMouse() const {
770 return IsWndCaptureMouse(this);
771 }
772
IsWndCaptureMouse(const CPWL_Wnd * pWnd) const773 FX_BOOL CPWL_Wnd::IsWndCaptureMouse(const CPWL_Wnd* pWnd) const {
774 if (CPWL_MsgControl* pCtrl = GetMsgControl())
775 return pCtrl->IsWndCaptureMouse(pWnd);
776
777 return FALSE;
778 }
779
IsWndCaptureKeyboard(const CPWL_Wnd * pWnd) const780 FX_BOOL CPWL_Wnd::IsWndCaptureKeyboard(const CPWL_Wnd* pWnd) const {
781 if (CPWL_MsgControl* pCtrl = GetMsgControl())
782 return pCtrl->IsWndCaptureKeyboard(pWnd);
783
784 return FALSE;
785 }
786
IsFocused() const787 FX_BOOL CPWL_Wnd::IsFocused() const {
788 if (CPWL_MsgControl* pCtrl = GetMsgControl())
789 return pCtrl->IsMainCaptureKeyboard(this);
790
791 return FALSE;
792 }
793
GetFocusRect() const794 CPDF_Rect CPWL_Wnd::GetFocusRect() const {
795 return CPWL_Utils::InflateRect(GetWindowRect(), 1);
796 }
797
GetFontSize() const798 FX_FLOAT CPWL_Wnd::GetFontSize() const {
799 return m_sPrivateParam.fFontSize;
800 }
801
SetFontSize(FX_FLOAT fFontSize)802 void CPWL_Wnd::SetFontSize(FX_FLOAT fFontSize) {
803 m_sPrivateParam.fFontSize = fFontSize;
804 }
805
GetSystemHandler() const806 IFX_SystemHandler* CPWL_Wnd::GetSystemHandler() const {
807 return m_sPrivateParam.pSystemHandler;
808 }
809
GetFocusHandler() const810 IPWL_FocusHandler* CPWL_Wnd::GetFocusHandler() const {
811 return m_sPrivateParam.pFocusHandler;
812 }
813
GetProvider() const814 IPWL_Provider* CPWL_Wnd::GetProvider() const {
815 return m_sPrivateParam.pProvider;
816 }
817
GetFontMap() const818 IFX_Edit_FontMap* CPWL_Wnd::GetFontMap() const {
819 return m_sPrivateParam.pFontMap;
820 }
821
GetBorderLeftTopColor(int32_t nBorderStyle) const822 CPWL_Color CPWL_Wnd::GetBorderLeftTopColor(int32_t nBorderStyle) const {
823 CPWL_Color color;
824
825 switch (nBorderStyle) {
826 case PBS_SOLID:
827 break;
828 case PBS_DASH:
829 break;
830 case PBS_BEVELED:
831 color = CPWL_Color(COLORTYPE_GRAY, 1);
832 break;
833 case PBS_INSET:
834 color = CPWL_Color(COLORTYPE_GRAY, 0.5f);
835 break;
836 case PBS_UNDERLINED:
837 break;
838 }
839
840 return color;
841 }
842
GetBorderRightBottomColor(int32_t nBorderStyle) const843 CPWL_Color CPWL_Wnd::GetBorderRightBottomColor(int32_t nBorderStyle) const {
844 CPWL_Color color;
845
846 switch (nBorderStyle) {
847 case PBS_SOLID:
848 break;
849 case PBS_DASH:
850 break;
851 case PBS_BEVELED:
852 color = CPWL_Utils::DevideColor(GetBackgroundColor(), 2);
853 break;
854 case PBS_INSET:
855 color = CPWL_Color(COLORTYPE_GRAY, 0.75f);
856 break;
857 case PBS_UNDERLINED:
858 break;
859 }
860
861 return color;
862 }
863
GetTransparency()864 int32_t CPWL_Wnd::GetTransparency() {
865 return m_sPrivateParam.nTransparency;
866 }
867
SetTransparency(int32_t nTransparency)868 void CPWL_Wnd::SetTransparency(int32_t nTransparency) {
869 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
870 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
871 pChild->SetTransparency(nTransparency);
872 }
873 }
874
875 m_sPrivateParam.nTransparency = nTransparency;
876 }
877
GetWindowMatrix() const878 CFX_Matrix CPWL_Wnd::GetWindowMatrix() const {
879 CFX_Matrix mt = GetChildToRoot();
880
881 if (IPWL_Provider* pProvider = GetProvider()) {
882 mt.Concat(pProvider->GetWindowMatrix(GetAttachedData()));
883 return mt;
884 }
885
886 return mt;
887 }
888
PWLtoWnd(const CPDF_Point & point,int32_t & x,int32_t & y) const889 void CPWL_Wnd::PWLtoWnd(const CPDF_Point& point, int32_t& x, int32_t& y) const {
890 CFX_Matrix mt = GetWindowMatrix();
891 CPDF_Point pt = point;
892 mt.Transform(pt.x, pt.y);
893 x = (int32_t)(pt.x + 0.5);
894 y = (int32_t)(pt.y + 0.5);
895 }
896
PWLtoWnd(const CPDF_Rect & rect) const897 FX_RECT CPWL_Wnd::PWLtoWnd(const CPDF_Rect& rect) const {
898 CPDF_Rect rcTemp = rect;
899 CFX_Matrix mt = GetWindowMatrix();
900 mt.TransformRect(rcTemp);
901 return FX_RECT((int32_t)(rcTemp.left + 0.5), (int32_t)(rcTemp.bottom + 0.5),
902 (int32_t)(rcTemp.right + 0.5), (int32_t)(rcTemp.top + 0.5));
903 }
904
GetAttachedHWnd() const905 FX_HWND CPWL_Wnd::GetAttachedHWnd() const {
906 return m_sPrivateParam.hAttachedWnd;
907 }
908
ChildToParent(const CPDF_Point & point) const909 CPDF_Point CPWL_Wnd::ChildToParent(const CPDF_Point& point) const {
910 CFX_Matrix mt = GetChildMatrix();
911 if (mt.IsIdentity())
912 return point;
913
914 CPDF_Point pt = point;
915 mt.Transform(pt.x, pt.y);
916 return pt;
917 }
918
ChildToParent(const CPDF_Rect & rect) const919 CPDF_Rect CPWL_Wnd::ChildToParent(const CPDF_Rect& rect) const {
920 CFX_Matrix mt = GetChildMatrix();
921 if (mt.IsIdentity())
922 return rect;
923
924 CPDF_Rect rc = rect;
925 mt.TransformRect(rc);
926 return rc;
927 }
928
ParentToChild(const CPDF_Point & point) const929 CPDF_Point CPWL_Wnd::ParentToChild(const CPDF_Point& point) const {
930 CFX_Matrix mt = GetChildMatrix();
931 if (mt.IsIdentity())
932 return point;
933
934 mt.SetReverse(mt);
935 CPDF_Point pt = point;
936 mt.Transform(pt.x, pt.y);
937 return pt;
938 }
939
ParentToChild(const CPDF_Rect & rect) const940 CPDF_Rect CPWL_Wnd::ParentToChild(const CPDF_Rect& rect) const {
941 CFX_Matrix mt = GetChildMatrix();
942 if (mt.IsIdentity())
943 return rect;
944
945 mt.SetReverse(mt);
946 CPDF_Rect rc = rect;
947 mt.TransformRect(rc);
948 return rc;
949 }
950
GetChildToRoot() const951 CFX_Matrix CPWL_Wnd::GetChildToRoot() const {
952 CFX_Matrix mt(1, 0, 0, 1, 0, 0);
953 if (HasFlag(PWS_CHILD)) {
954 const CPWL_Wnd* pParent = this;
955 while (pParent) {
956 mt.Concat(pParent->GetChildMatrix());
957 pParent = pParent->GetParentWindow();
958 }
959 }
960 return mt;
961 }
962
GetChildMatrix() const963 CFX_Matrix CPWL_Wnd::GetChildMatrix() const {
964 if (HasFlag(PWS_CHILD))
965 return m_sPrivateParam.mtChild;
966
967 return CFX_Matrix(1, 0, 0, 1, 0, 0);
968 }
969
SetChildMatrix(const CFX_Matrix & mt)970 void CPWL_Wnd::SetChildMatrix(const CFX_Matrix& mt) {
971 m_sPrivateParam.mtChild = mt;
972 }
973
GetFocused() const974 const CPWL_Wnd* CPWL_Wnd::GetFocused() const {
975 if (CPWL_MsgControl* pMsgCtrl = GetMsgControl()) {
976 return pMsgCtrl->m_pMainKeyboardWnd;
977 }
978
979 return NULL;
980 }
981
EnableWindow(FX_BOOL bEnable)982 void CPWL_Wnd::EnableWindow(FX_BOOL bEnable) {
983 if (m_bEnabled != bEnable) {
984 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
985 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
986 pChild->EnableWindow(bEnable);
987 }
988 }
989
990 m_bEnabled = bEnable;
991
992 if (bEnable)
993 OnEnabled();
994 else
995 OnDisabled();
996 }
997 }
998
IsEnabled()999 FX_BOOL CPWL_Wnd::IsEnabled() {
1000 return m_bEnabled;
1001 }
1002
OnEnabled()1003 void CPWL_Wnd::OnEnabled() {}
1004
OnDisabled()1005 void CPWL_Wnd::OnDisabled() {}
1006
IsCTRLpressed(FX_DWORD nFlag) const1007 FX_BOOL CPWL_Wnd::IsCTRLpressed(FX_DWORD nFlag) const {
1008 if (IFX_SystemHandler* pSystemHandler = GetSystemHandler()) {
1009 return pSystemHandler->IsCTRLKeyDown(nFlag);
1010 }
1011
1012 return FALSE;
1013 }
1014
IsSHIFTpressed(FX_DWORD nFlag) const1015 FX_BOOL CPWL_Wnd::IsSHIFTpressed(FX_DWORD nFlag) const {
1016 if (IFX_SystemHandler* pSystemHandler = GetSystemHandler()) {
1017 return pSystemHandler->IsSHIFTKeyDown(nFlag);
1018 }
1019
1020 return FALSE;
1021 }
1022
IsALTpressed(FX_DWORD nFlag) const1023 FX_BOOL CPWL_Wnd::IsALTpressed(FX_DWORD nFlag) const {
1024 if (IFX_SystemHandler* pSystemHandler = GetSystemHandler()) {
1025 return pSystemHandler->IsALTKeyDown(nFlag);
1026 }
1027
1028 return FALSE;
1029 }
1030
IsINSERTpressed(FX_DWORD nFlag) const1031 FX_BOOL CPWL_Wnd::IsINSERTpressed(FX_DWORD nFlag) const {
1032 if (IFX_SystemHandler* pSystemHandler = GetSystemHandler()) {
1033 return pSystemHandler->IsINSERTKeyDown(nFlag);
1034 }
1035
1036 return FALSE;
1037 }
1038