OLD | NEW |
| (Empty) |
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 | |
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 | |
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 | |
26 CPWL_Timer::~CPWL_Timer() { | |
27 KillPWLTimer(); | |
28 } | |
29 | |
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 | |
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 | |
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 | |
58 CPWL_TimerHandler::CPWL_TimerHandler() : m_pTimer(NULL) {} | |
59 | |
60 CPWL_TimerHandler::~CPWL_TimerHandler() { | |
61 delete m_pTimer; | |
62 } | |
63 | |
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 | |
72 void CPWL_TimerHandler::EndTimer() { | |
73 if (m_pTimer) | |
74 m_pTimer->KillPWLTimer(); | |
75 } | |
76 | |
77 void CPWL_TimerHandler::TimerProc() {} | |
78 | |
79 class CPWL_MsgControl { | |
80 friend class CPWL_Wnd; | |
81 | |
82 public: | |
83 explicit CPWL_MsgControl(CPWL_Wnd* pWnd) { | |
84 m_pCreatedWnd = pWnd; | |
85 Default(); | |
86 } | |
87 | |
88 ~CPWL_MsgControl() { | |
89 Default(); | |
90 } | |
91 | |
92 void Default() { | |
93 m_aMousePath.RemoveAll(); | |
94 m_aKeyboardPath.RemoveAll(); | |
95 m_pMainMouseWnd = NULL; | |
96 m_pMainKeyboardWnd = NULL; | |
97 } | |
98 | |
99 FX_BOOL IsWndCreated(const CPWL_Wnd* pWnd) const { | |
100 return m_pCreatedWnd == pWnd; | |
101 } | |
102 | |
103 FX_BOOL IsMainCaptureMouse(const CPWL_Wnd* pWnd) const { | |
104 return pWnd == m_pMainMouseWnd; | |
105 } | |
106 | |
107 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 | |
118 FX_BOOL IsMainCaptureKeyboard(const CPWL_Wnd* pWnd) const { | |
119 return pWnd == m_pMainKeyboardWnd; | |
120 } | |
121 | |
122 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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
194 CPWL_Wnd::~CPWL_Wnd() { | |
195 ASSERT(m_bCreated == FALSE); | |
196 } | |
197 | |
198 CFX_ByteString CPWL_Wnd::GetClassName() const { | |
199 return "CPWL_Wnd"; | |
200 } | |
201 | |
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 | |
234 void CPWL_Wnd::OnCreate(PWL_CREATEPARAM& cp) {} | |
235 | |
236 void CPWL_Wnd::OnCreated() {} | |
237 | |
238 void CPWL_Wnd::OnDestroy() {} | |
239 | |
240 void CPWL_Wnd::InvalidateFocusHandler(IPWL_FocusHandler* handler) { | |
241 if (m_sPrivateParam.pFocusHandler == handler) | |
242 m_sPrivateParam.pFocusHandler = nullptr; | |
243 } | |
244 | |
245 void CPWL_Wnd::InvalidateProvider(IPWL_Provider* provider) { | |
246 if (m_sPrivateParam.pProvider == provider) | |
247 m_sPrivateParam.pProvider = nullptr; | |
248 } | |
249 | |
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 | |
276 void CPWL_Wnd::Move(const CFX_FloatRect& rcNew, | |
277 FX_BOOL bReset, | |
278 FX_BOOL bRefresh) { | |
279 if (IsValid()) { | |
280 CFX_FloatRect rcOld = GetWindowRect(); | |
281 | |
282 m_rcWindow = rcNew; | |
283 m_rcWindow.Normalize(); | |
284 | |
285 if (rcOld.left != rcNew.left || rcOld.right != rcNew.right || | |
286 rcOld.top != rcNew.top || rcOld.bottom != rcNew.bottom) { | |
287 if (bReset) { | |
288 RePosChildWnd(); | |
289 } | |
290 } | |
291 if (bRefresh) { | |
292 InvalidateRectMove(rcOld, rcNew); | |
293 } | |
294 | |
295 m_sPrivateParam.rcRectWnd = m_rcWindow; | |
296 } | |
297 } | |
298 | |
299 void CPWL_Wnd::InvalidateRectMove(const CFX_FloatRect& rcOld, | |
300 const CFX_FloatRect& rcNew) { | |
301 CFX_FloatRect rcUnion = rcOld; | |
302 rcUnion.Union(rcNew); | |
303 | |
304 InvalidateRect(&rcUnion); | |
305 } | |
306 | |
307 void CPWL_Wnd::GetAppearanceStream(CFX_ByteTextBuf& sAppStream) { | |
308 if (IsValid() && IsVisible()) { | |
309 GetThisAppearanceStream(sAppStream); | |
310 GetChildAppearanceStream(sAppStream); | |
311 } | |
312 } | |
313 | |
314 // if don't set,Get default apperance stream | |
315 void CPWL_Wnd::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) { | |
316 CFX_FloatRect rectWnd = GetWindowRect(); | |
317 if (!rectWnd.IsEmpty()) { | |
318 CFX_ByteTextBuf sThis; | |
319 | |
320 if (HasFlag(PWS_BACKGROUND)) | |
321 sThis << CPWL_Utils::GetRectFillAppStream(rectWnd, GetBackgroundColor()); | |
322 | |
323 if (HasFlag(PWS_BORDER)) { | |
324 sThis << CPWL_Utils::GetBorderAppStream( | |
325 rectWnd, (FX_FLOAT)GetBorderWidth(), GetBorderColor(), | |
326 GetBorderLeftTopColor(GetBorderStyle()), | |
327 GetBorderRightBottomColor(GetBorderStyle()), GetBorderStyle(), | |
328 GetBorderDash()); | |
329 } | |
330 | |
331 sAppStream << sThis; | |
332 } | |
333 } | |
334 | |
335 void CPWL_Wnd::GetChildAppearanceStream(CFX_ByteTextBuf& sAppStream) { | |
336 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { | |
337 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { | |
338 pChild->GetAppearanceStream(sAppStream); | |
339 } | |
340 } | |
341 } | |
342 | |
343 void CPWL_Wnd::DrawAppearance(CFX_RenderDevice* pDevice, | |
344 CFX_Matrix* pUser2Device) { | |
345 if (IsValid() && IsVisible()) { | |
346 DrawThisAppearance(pDevice, pUser2Device); | |
347 DrawChildAppearance(pDevice, pUser2Device); | |
348 } | |
349 } | |
350 | |
351 void CPWL_Wnd::DrawThisAppearance(CFX_RenderDevice* pDevice, | |
352 CFX_Matrix* pUser2Device) { | |
353 CFX_FloatRect rectWnd = GetWindowRect(); | |
354 if (!rectWnd.IsEmpty()) { | |
355 if (HasFlag(PWS_BACKGROUND)) { | |
356 CFX_FloatRect rcClient = CPWL_Utils::DeflateRect( | |
357 rectWnd, (FX_FLOAT)(GetBorderWidth() + GetInnerBorderWidth())); | |
358 CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcClient, | |
359 GetBackgroundColor(), GetTransparency()); | |
360 } | |
361 | |
362 if (HasFlag(PWS_BORDER)) | |
363 CPWL_Utils::DrawBorder(pDevice, pUser2Device, rectWnd, | |
364 (FX_FLOAT)GetBorderWidth(), GetBorderColor(), | |
365 GetBorderLeftTopColor(GetBorderStyle()), | |
366 GetBorderRightBottomColor(GetBorderStyle()), | |
367 GetBorderStyle(), GetTransparency()); | |
368 } | |
369 } | |
370 | |
371 void CPWL_Wnd::DrawChildAppearance(CFX_RenderDevice* pDevice, | |
372 CFX_Matrix* pUser2Device) { | |
373 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { | |
374 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { | |
375 CFX_Matrix mt = pChild->GetChildMatrix(); | |
376 if (mt.IsIdentity()) { | |
377 pChild->DrawAppearance(pDevice, pUser2Device); | |
378 } else { | |
379 mt.Concat(*pUser2Device); | |
380 pChild->DrawAppearance(pDevice, &mt); | |
381 } | |
382 } | |
383 } | |
384 } | |
385 | |
386 void CPWL_Wnd::InvalidateRect(CFX_FloatRect* pRect) { | |
387 if (IsValid()) { | |
388 CFX_FloatRect rcRefresh = pRect ? *pRect : GetWindowRect(); | |
389 | |
390 if (!HasFlag(PWS_NOREFRESHCLIP)) { | |
391 CFX_FloatRect rcClip = GetClipRect(); | |
392 if (!rcClip.IsEmpty()) { | |
393 rcRefresh.Intersect(rcClip); | |
394 } | |
395 } | |
396 | |
397 FX_RECT rcWin = PWLtoWnd(rcRefresh); | |
398 rcWin.left -= PWL_INVALIDATE_INFLATE; | |
399 rcWin.top -= PWL_INVALIDATE_INFLATE; | |
400 rcWin.right += PWL_INVALIDATE_INFLATE; | |
401 rcWin.bottom += PWL_INVALIDATE_INFLATE; | |
402 | |
403 if (IFX_SystemHandler* pSH = GetSystemHandler()) { | |
404 if (FX_HWND hWnd = GetAttachedHWnd()) { | |
405 pSH->InvalidateRect(hWnd, rcWin); | |
406 } | |
407 } | |
408 } | |
409 } | |
410 | |
411 #define PWL_IMPLEMENT_KEY_METHOD(key_method_name) \ | |
412 FX_BOOL CPWL_Wnd::key_method_name(FX_WORD nChar, FX_DWORD nFlag) { \ | |
413 if (IsValid() && IsVisible() && IsEnabled()) { \ | |
414 if (IsWndCaptureKeyboard(this)) { \ | |
415 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { \ | |
416 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { \ | |
417 if (IsWndCaptureKeyboard(pChild)) { \ | |
418 return pChild->key_method_name(nChar, nFlag); \ | |
419 } \ | |
420 } \ | |
421 } \ | |
422 } \ | |
423 } \ | |
424 return FALSE; \ | |
425 } | |
426 | |
427 #define PWL_IMPLEMENT_MOUSE_METHOD(mouse_method_name) \ | |
428 FX_BOOL CPWL_Wnd::mouse_method_name(const CFX_FloatPoint& point, \ | |
429 FX_DWORD nFlag) { \ | |
430 if (IsValid() && IsVisible() && IsEnabled()) { \ | |
431 if (IsWndCaptureMouse(this)) { \ | |
432 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { \ | |
433 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { \ | |
434 if (IsWndCaptureMouse(pChild)) { \ | |
435 return pChild->mouse_method_name(pChild->ParentToChild(point), \ | |
436 nFlag); \ | |
437 } \ | |
438 } \ | |
439 } \ | |
440 SetCursor(); \ | |
441 } else { \ | |
442 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { \ | |
443 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { \ | |
444 if (pChild->WndHitTest(pChild->ParentToChild(point))) { \ | |
445 return pChild->mouse_method_name(pChild->ParentToChild(point), \ | |
446 nFlag); \ | |
447 } \ | |
448 } \ | |
449 } \ | |
450 if (WndHitTest(point)) \ | |
451 SetCursor(); \ | |
452 } \ | |
453 } \ | |
454 return FALSE; \ | |
455 } | |
456 | |
457 PWL_IMPLEMENT_KEY_METHOD(OnKeyDown) | |
458 PWL_IMPLEMENT_KEY_METHOD(OnKeyUp) | |
459 PWL_IMPLEMENT_KEY_METHOD(OnChar) | |
460 | |
461 PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonDblClk) | |
462 PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonDown) | |
463 PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonUp) | |
464 PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonDblClk) | |
465 PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonDown) | |
466 PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonUp) | |
467 PWL_IMPLEMENT_MOUSE_METHOD(OnRButtonDown) | |
468 PWL_IMPLEMENT_MOUSE_METHOD(OnRButtonUp) | |
469 PWL_IMPLEMENT_MOUSE_METHOD(OnMouseMove) | |
470 | |
471 FX_BOOL CPWL_Wnd::OnMouseWheel(short zDelta, | |
472 const CFX_FloatPoint& point, | |
473 FX_DWORD nFlag) { | |
474 if (IsValid() && IsVisible() && IsEnabled()) { | |
475 SetCursor(); | |
476 if (IsWndCaptureKeyboard(this)) { | |
477 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { | |
478 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { | |
479 if (IsWndCaptureKeyboard(pChild)) { | |
480 return pChild->OnMouseWheel(zDelta, pChild->ParentToChild(point), | |
481 nFlag); | |
482 } | |
483 } | |
484 } | |
485 } | |
486 } | |
487 return FALSE; | |
488 } | |
489 | |
490 void CPWL_Wnd::AddChild(CPWL_Wnd* pWnd) { | |
491 m_aChildren.Add(pWnd); | |
492 } | |
493 | |
494 void CPWL_Wnd::RemoveChild(CPWL_Wnd* pWnd) { | |
495 for (int32_t i = m_aChildren.GetSize() - 1; i >= 0; i--) { | |
496 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { | |
497 if (pChild == pWnd) { | |
498 m_aChildren.RemoveAt(i); | |
499 break; | |
500 } | |
501 } | |
502 } | |
503 } | |
504 | |
505 void CPWL_Wnd::OnNotify(CPWL_Wnd* pWnd, | |
506 FX_DWORD msg, | |
507 intptr_t wParam, | |
508 intptr_t lParam) { | |
509 switch (msg) { | |
510 case PNM_ADDCHILD: | |
511 AddChild(pWnd); | |
512 break; | |
513 case PNM_REMOVECHILD: | |
514 RemoveChild(pWnd); | |
515 break; | |
516 default: | |
517 break; | |
518 } | |
519 } | |
520 | |
521 FX_BOOL CPWL_Wnd::IsValid() const { | |
522 return m_bCreated; | |
523 } | |
524 | |
525 const PWL_CREATEPARAM& CPWL_Wnd::GetCreationParam() const { | |
526 return m_sPrivateParam; | |
527 } | |
528 | |
529 CPWL_Wnd* CPWL_Wnd::GetParentWindow() const { | |
530 return m_sPrivateParam.pParentWnd; | |
531 } | |
532 | |
533 CFX_FloatRect CPWL_Wnd::GetWindowRect() const { | |
534 return m_rcWindow; | |
535 } | |
536 | |
537 CFX_FloatRect CPWL_Wnd::GetClientRect() const { | |
538 CFX_FloatRect rcWindow = GetWindowRect(); | |
539 CFX_FloatRect rcClient = CPWL_Utils::DeflateRect( | |
540 rcWindow, (FX_FLOAT)(GetBorderWidth() + GetInnerBorderWidth())); | |
541 if (CPWL_ScrollBar* pVSB = GetVScrollBar()) | |
542 rcClient.right -= pVSB->GetScrollBarWidth(); | |
543 | |
544 rcClient.Normalize(); | |
545 return rcWindow.Contains(rcClient) ? rcClient : CFX_FloatRect(); | |
546 } | |
547 | |
548 CFX_FloatPoint CPWL_Wnd::GetCenterPoint() const { | |
549 CFX_FloatRect rcClient = GetClientRect(); | |
550 return CFX_FloatPoint((rcClient.left + rcClient.right) * 0.5f, | |
551 (rcClient.top + rcClient.bottom) * 0.5f); | |
552 } | |
553 | |
554 FX_BOOL CPWL_Wnd::HasFlag(FX_DWORD dwFlags) const { | |
555 return (m_sPrivateParam.dwFlags & dwFlags) != 0; | |
556 } | |
557 | |
558 void CPWL_Wnd::RemoveFlag(FX_DWORD dwFlags) { | |
559 m_sPrivateParam.dwFlags &= ~dwFlags; | |
560 } | |
561 | |
562 void CPWL_Wnd::AddFlag(FX_DWORD dwFlags) { | |
563 m_sPrivateParam.dwFlags |= dwFlags; | |
564 } | |
565 | |
566 CPWL_Color CPWL_Wnd::GetBackgroundColor() const { | |
567 return m_sPrivateParam.sBackgroundColor; | |
568 } | |
569 | |
570 void CPWL_Wnd::SetBackgroundColor(const CPWL_Color& color) { | |
571 m_sPrivateParam.sBackgroundColor = color; | |
572 } | |
573 | |
574 void CPWL_Wnd::SetTextColor(const CPWL_Color& color) { | |
575 m_sPrivateParam.sTextColor = color; | |
576 } | |
577 | |
578 void CPWL_Wnd::SetTextStrokeColor(const CPWL_Color& color) { | |
579 m_sPrivateParam.sTextStrokeColor = color; | |
580 } | |
581 | |
582 CPWL_Color CPWL_Wnd::GetTextColor() const { | |
583 return m_sPrivateParam.sTextColor; | |
584 } | |
585 | |
586 CPWL_Color CPWL_Wnd::GetTextStrokeColor() const { | |
587 return m_sPrivateParam.sTextStrokeColor; | |
588 } | |
589 | |
590 int32_t CPWL_Wnd::GetBorderStyle() const { | |
591 return m_sPrivateParam.nBorderStyle; | |
592 } | |
593 | |
594 void CPWL_Wnd::SetBorderStyle(int32_t nBorderStyle) { | |
595 if (HasFlag(PWS_BORDER)) | |
596 m_sPrivateParam.nBorderStyle = nBorderStyle; | |
597 } | |
598 | |
599 int32_t CPWL_Wnd::GetBorderWidth() const { | |
600 if (HasFlag(PWS_BORDER)) | |
601 return m_sPrivateParam.dwBorderWidth; | |
602 | |
603 return 0; | |
604 } | |
605 | |
606 int32_t CPWL_Wnd::GetInnerBorderWidth() const { | |
607 return 0; | |
608 } | |
609 | |
610 CPWL_Color CPWL_Wnd::GetBorderColor() const { | |
611 if (HasFlag(PWS_BORDER)) | |
612 return m_sPrivateParam.sBorderColor; | |
613 | |
614 return CPWL_Color(); | |
615 } | |
616 | |
617 const CPWL_Dash& CPWL_Wnd::GetBorderDash() const { | |
618 return m_sPrivateParam.sDash; | |
619 } | |
620 | |
621 void* CPWL_Wnd::GetAttachedData() const { | |
622 return m_sPrivateParam.pAttachedData; | |
623 } | |
624 | |
625 CPWL_ScrollBar* CPWL_Wnd::GetVScrollBar() const { | |
626 if (HasFlag(PWS_VSCROLL)) | |
627 return m_pVScrollBar; | |
628 | |
629 return NULL; | |
630 } | |
631 | |
632 void CPWL_Wnd::CreateScrollBar(const PWL_CREATEPARAM& cp) { | |
633 CreateVScrollBar(cp); | |
634 } | |
635 | |
636 void CPWL_Wnd::CreateVScrollBar(const PWL_CREATEPARAM& cp) { | |
637 if (!m_pVScrollBar && HasFlag(PWS_VSCROLL)) { | |
638 PWL_CREATEPARAM scp = cp; | |
639 | |
640 // flags | |
641 scp.dwFlags = | |
642 PWS_CHILD | PWS_BACKGROUND | PWS_AUTOTRANSPARENT | PWS_NOREFRESHCLIP; | |
643 | |
644 scp.pParentWnd = this; | |
645 scp.sBackgroundColor = PWL_DEFAULT_WHITECOLOR; | |
646 scp.eCursorType = FXCT_ARROW; | |
647 scp.nTransparency = PWL_SCROLLBAR_TRANSPARANCY; | |
648 | |
649 m_pVScrollBar = new CPWL_ScrollBar(SBT_VSCROLL); | |
650 m_pVScrollBar->Create(scp); | |
651 } | |
652 } | |
653 | |
654 void CPWL_Wnd::SetCapture() { | |
655 if (CPWL_MsgControl* pMsgCtrl = GetMsgControl()) | |
656 pMsgCtrl->SetCapture(this); | |
657 } | |
658 | |
659 void CPWL_Wnd::ReleaseCapture() { | |
660 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) | |
661 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) | |
662 pChild->ReleaseCapture(); | |
663 | |
664 if (CPWL_MsgControl* pMsgCtrl = GetMsgControl()) | |
665 pMsgCtrl->ReleaseCapture(); | |
666 } | |
667 | |
668 void CPWL_Wnd::SetFocus() { | |
669 if (CPWL_MsgControl* pMsgCtrl = GetMsgControl()) { | |
670 if (!pMsgCtrl->IsMainCaptureKeyboard(this)) | |
671 pMsgCtrl->KillFocus(); | |
672 pMsgCtrl->SetFocus(this); | |
673 } | |
674 } | |
675 | |
676 void CPWL_Wnd::KillFocus() { | |
677 if (CPWL_MsgControl* pMsgCtrl = GetMsgControl()) { | |
678 if (pMsgCtrl->IsWndCaptureKeyboard(this)) | |
679 pMsgCtrl->KillFocus(); | |
680 } | |
681 } | |
682 | |
683 void CPWL_Wnd::OnSetFocus() {} | |
684 | |
685 void CPWL_Wnd::OnKillFocus() {} | |
686 | |
687 FX_BOOL CPWL_Wnd::WndHitTest(const CFX_FloatPoint& point) const { | |
688 return IsValid() && IsVisible() && GetWindowRect().Contains(point.x, point.y); | |
689 } | |
690 | |
691 FX_BOOL CPWL_Wnd::ClientHitTest(const CFX_FloatPoint& point) const { | |
692 return IsValid() && IsVisible() && GetClientRect().Contains(point.x, point.y); | |
693 } | |
694 | |
695 const CPWL_Wnd* CPWL_Wnd::GetRootWnd() const { | |
696 if (m_sPrivateParam.pParentWnd) | |
697 return m_sPrivateParam.pParentWnd->GetRootWnd(); | |
698 | |
699 return this; | |
700 } | |
701 | |
702 void CPWL_Wnd::SetVisible(FX_BOOL bVisible) { | |
703 if (IsValid()) { | |
704 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { | |
705 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { | |
706 pChild->SetVisible(bVisible); | |
707 } | |
708 } | |
709 | |
710 if (bVisible != m_bVisible) { | |
711 m_bVisible = bVisible; | |
712 RePosChildWnd(); | |
713 InvalidateRect(); | |
714 } | |
715 } | |
716 } | |
717 | |
718 void CPWL_Wnd::SetClipRect(const CFX_FloatRect& rect) { | |
719 m_rcClip = rect; | |
720 m_rcClip.Normalize(); | |
721 } | |
722 | |
723 const CFX_FloatRect& CPWL_Wnd::GetClipRect() const { | |
724 return m_rcClip; | |
725 } | |
726 | |
727 FX_BOOL CPWL_Wnd::IsReadOnly() const { | |
728 return HasFlag(PWS_READONLY); | |
729 } | |
730 | |
731 void CPWL_Wnd::RePosChildWnd() { | |
732 CFX_FloatRect rcContent = CPWL_Utils::DeflateRect( | |
733 GetWindowRect(), (FX_FLOAT)(GetBorderWidth() + GetInnerBorderWidth())); | |
734 | |
735 CPWL_ScrollBar* pVSB = GetVScrollBar(); | |
736 | |
737 CFX_FloatRect rcVScroll = | |
738 CFX_FloatRect(rcContent.right - PWL_SCROLLBAR_WIDTH, rcContent.bottom, | |
739 rcContent.right - 1.0f, rcContent.top); | |
740 | |
741 if (pVSB) | |
742 pVSB->Move(rcVScroll, TRUE, FALSE); | |
743 } | |
744 | |
745 void CPWL_Wnd::CreateChildWnd(const PWL_CREATEPARAM& cp) {} | |
746 | |
747 void CPWL_Wnd::SetCursor() { | |
748 if (IsValid()) { | |
749 if (IFX_SystemHandler* pSH = GetSystemHandler()) { | |
750 int32_t nCursorType = GetCreationParam().eCursorType; | |
751 pSH->SetCursor(nCursorType); | |
752 } | |
753 } | |
754 } | |
755 | |
756 void CPWL_Wnd::CreateMsgControl() { | |
757 if (!m_sPrivateParam.pMsgControl) | |
758 m_sPrivateParam.pMsgControl = new CPWL_MsgControl(this); | |
759 } | |
760 | |
761 void CPWL_Wnd::DestroyMsgControl() { | |
762 if (CPWL_MsgControl* pMsgControl = GetMsgControl()) | |
763 if (pMsgControl->IsWndCreated(this)) | |
764 delete pMsgControl; | |
765 } | |
766 | |
767 CPWL_MsgControl* CPWL_Wnd::GetMsgControl() const { | |
768 return m_sPrivateParam.pMsgControl; | |
769 } | |
770 | |
771 FX_BOOL CPWL_Wnd::IsCaptureMouse() const { | |
772 return IsWndCaptureMouse(this); | |
773 } | |
774 | |
775 FX_BOOL CPWL_Wnd::IsWndCaptureMouse(const CPWL_Wnd* pWnd) const { | |
776 if (CPWL_MsgControl* pCtrl = GetMsgControl()) | |
777 return pCtrl->IsWndCaptureMouse(pWnd); | |
778 | |
779 return FALSE; | |
780 } | |
781 | |
782 FX_BOOL CPWL_Wnd::IsWndCaptureKeyboard(const CPWL_Wnd* pWnd) const { | |
783 if (CPWL_MsgControl* pCtrl = GetMsgControl()) | |
784 return pCtrl->IsWndCaptureKeyboard(pWnd); | |
785 | |
786 return FALSE; | |
787 } | |
788 | |
789 FX_BOOL CPWL_Wnd::IsFocused() const { | |
790 if (CPWL_MsgControl* pCtrl = GetMsgControl()) | |
791 return pCtrl->IsMainCaptureKeyboard(this); | |
792 | |
793 return FALSE; | |
794 } | |
795 | |
796 CFX_FloatRect CPWL_Wnd::GetFocusRect() const { | |
797 return CPWL_Utils::InflateRect(GetWindowRect(), 1); | |
798 } | |
799 | |
800 FX_FLOAT CPWL_Wnd::GetFontSize() const { | |
801 return m_sPrivateParam.fFontSize; | |
802 } | |
803 | |
804 void CPWL_Wnd::SetFontSize(FX_FLOAT fFontSize) { | |
805 m_sPrivateParam.fFontSize = fFontSize; | |
806 } | |
807 | |
808 IFX_SystemHandler* CPWL_Wnd::GetSystemHandler() const { | |
809 return m_sPrivateParam.pSystemHandler; | |
810 } | |
811 | |
812 IPWL_FocusHandler* CPWL_Wnd::GetFocusHandler() const { | |
813 return m_sPrivateParam.pFocusHandler; | |
814 } | |
815 | |
816 IPWL_Provider* CPWL_Wnd::GetProvider() const { | |
817 return m_sPrivateParam.pProvider; | |
818 } | |
819 | |
820 IFX_Edit_FontMap* CPWL_Wnd::GetFontMap() const { | |
821 return m_sPrivateParam.pFontMap; | |
822 } | |
823 | |
824 CPWL_Color CPWL_Wnd::GetBorderLeftTopColor(int32_t nBorderStyle) const { | |
825 CPWL_Color color; | |
826 | |
827 switch (nBorderStyle) { | |
828 case PBS_SOLID: | |
829 break; | |
830 case PBS_DASH: | |
831 break; | |
832 case PBS_BEVELED: | |
833 color = CPWL_Color(COLORTYPE_GRAY, 1); | |
834 break; | |
835 case PBS_INSET: | |
836 color = CPWL_Color(COLORTYPE_GRAY, 0.5f); | |
837 break; | |
838 case PBS_UNDERLINED: | |
839 break; | |
840 } | |
841 | |
842 return color; | |
843 } | |
844 | |
845 CPWL_Color CPWL_Wnd::GetBorderRightBottomColor(int32_t nBorderStyle) const { | |
846 CPWL_Color color; | |
847 | |
848 switch (nBorderStyle) { | |
849 case PBS_SOLID: | |
850 break; | |
851 case PBS_DASH: | |
852 break; | |
853 case PBS_BEVELED: | |
854 color = CPWL_Utils::DevideColor(GetBackgroundColor(), 2); | |
855 break; | |
856 case PBS_INSET: | |
857 color = CPWL_Color(COLORTYPE_GRAY, 0.75f); | |
858 break; | |
859 case PBS_UNDERLINED: | |
860 break; | |
861 } | |
862 | |
863 return color; | |
864 } | |
865 | |
866 int32_t CPWL_Wnd::GetTransparency() { | |
867 return m_sPrivateParam.nTransparency; | |
868 } | |
869 | |
870 void CPWL_Wnd::SetTransparency(int32_t nTransparency) { | |
871 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { | |
872 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { | |
873 pChild->SetTransparency(nTransparency); | |
874 } | |
875 } | |
876 | |
877 m_sPrivateParam.nTransparency = nTransparency; | |
878 } | |
879 | |
880 CFX_Matrix CPWL_Wnd::GetWindowMatrix() const { | |
881 CFX_Matrix mt = GetChildToRoot(); | |
882 | |
883 if (IPWL_Provider* pProvider = GetProvider()) { | |
884 mt.Concat(pProvider->GetWindowMatrix(GetAttachedData())); | |
885 return mt; | |
886 } | |
887 | |
888 return mt; | |
889 } | |
890 | |
891 void CPWL_Wnd::PWLtoWnd(const CFX_FloatPoint& point, | |
892 int32_t& x, | |
893 int32_t& y) const { | |
894 CFX_Matrix mt = GetWindowMatrix(); | |
895 CFX_FloatPoint pt = point; | |
896 mt.Transform(pt.x, pt.y); | |
897 x = (int32_t)(pt.x + 0.5); | |
898 y = (int32_t)(pt.y + 0.5); | |
899 } | |
900 | |
901 FX_RECT CPWL_Wnd::PWLtoWnd(const CFX_FloatRect& rect) const { | |
902 CFX_FloatRect rcTemp = rect; | |
903 CFX_Matrix mt = GetWindowMatrix(); | |
904 mt.TransformRect(rcTemp); | |
905 return FX_RECT((int32_t)(rcTemp.left + 0.5), (int32_t)(rcTemp.bottom + 0.5), | |
906 (int32_t)(rcTemp.right + 0.5), (int32_t)(rcTemp.top + 0.5)); | |
907 } | |
908 | |
909 FX_HWND CPWL_Wnd::GetAttachedHWnd() const { | |
910 return m_sPrivateParam.hAttachedWnd; | |
911 } | |
912 | |
913 CFX_FloatPoint CPWL_Wnd::ChildToParent(const CFX_FloatPoint& point) const { | |
914 CFX_Matrix mt = GetChildMatrix(); | |
915 if (mt.IsIdentity()) | |
916 return point; | |
917 | |
918 CFX_FloatPoint pt = point; | |
919 mt.Transform(pt.x, pt.y); | |
920 return pt; | |
921 } | |
922 | |
923 CFX_FloatRect CPWL_Wnd::ChildToParent(const CFX_FloatRect& rect) const { | |
924 CFX_Matrix mt = GetChildMatrix(); | |
925 if (mt.IsIdentity()) | |
926 return rect; | |
927 | |
928 CFX_FloatRect rc = rect; | |
929 mt.TransformRect(rc); | |
930 return rc; | |
931 } | |
932 | |
933 CFX_FloatPoint CPWL_Wnd::ParentToChild(const CFX_FloatPoint& point) const { | |
934 CFX_Matrix mt = GetChildMatrix(); | |
935 if (mt.IsIdentity()) | |
936 return point; | |
937 | |
938 mt.SetReverse(mt); | |
939 CFX_FloatPoint pt = point; | |
940 mt.Transform(pt.x, pt.y); | |
941 return pt; | |
942 } | |
943 | |
944 CFX_FloatRect CPWL_Wnd::ParentToChild(const CFX_FloatRect& rect) const { | |
945 CFX_Matrix mt = GetChildMatrix(); | |
946 if (mt.IsIdentity()) | |
947 return rect; | |
948 | |
949 mt.SetReverse(mt); | |
950 CFX_FloatRect rc = rect; | |
951 mt.TransformRect(rc); | |
952 return rc; | |
953 } | |
954 | |
955 CFX_Matrix CPWL_Wnd::GetChildToRoot() const { | |
956 CFX_Matrix mt(1, 0, 0, 1, 0, 0); | |
957 if (HasFlag(PWS_CHILD)) { | |
958 const CPWL_Wnd* pParent = this; | |
959 while (pParent) { | |
960 mt.Concat(pParent->GetChildMatrix()); | |
961 pParent = pParent->GetParentWindow(); | |
962 } | |
963 } | |
964 return mt; | |
965 } | |
966 | |
967 CFX_Matrix CPWL_Wnd::GetChildMatrix() const { | |
968 if (HasFlag(PWS_CHILD)) | |
969 return m_sPrivateParam.mtChild; | |
970 | |
971 return CFX_Matrix(1, 0, 0, 1, 0, 0); | |
972 } | |
973 | |
974 void CPWL_Wnd::SetChildMatrix(const CFX_Matrix& mt) { | |
975 m_sPrivateParam.mtChild = mt; | |
976 } | |
977 | |
978 const CPWL_Wnd* CPWL_Wnd::GetFocused() const { | |
979 if (CPWL_MsgControl* pMsgCtrl = GetMsgControl()) { | |
980 return pMsgCtrl->m_pMainKeyboardWnd; | |
981 } | |
982 | |
983 return NULL; | |
984 } | |
985 | |
986 void CPWL_Wnd::EnableWindow(FX_BOOL bEnable) { | |
987 if (m_bEnabled != bEnable) { | |
988 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { | |
989 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { | |
990 pChild->EnableWindow(bEnable); | |
991 } | |
992 } | |
993 | |
994 m_bEnabled = bEnable; | |
995 | |
996 if (bEnable) | |
997 OnEnabled(); | |
998 else | |
999 OnDisabled(); | |
1000 } | |
1001 } | |
1002 | |
1003 FX_BOOL CPWL_Wnd::IsEnabled() { | |
1004 return m_bEnabled; | |
1005 } | |
1006 | |
1007 void CPWL_Wnd::OnEnabled() {} | |
1008 | |
1009 void CPWL_Wnd::OnDisabled() {} | |
1010 | |
1011 FX_BOOL CPWL_Wnd::IsCTRLpressed(FX_DWORD nFlag) const { | |
1012 if (IFX_SystemHandler* pSystemHandler = GetSystemHandler()) { | |
1013 return pSystemHandler->IsCTRLKeyDown(nFlag); | |
1014 } | |
1015 | |
1016 return FALSE; | |
1017 } | |
1018 | |
1019 FX_BOOL CPWL_Wnd::IsSHIFTpressed(FX_DWORD nFlag) const { | |
1020 if (IFX_SystemHandler* pSystemHandler = GetSystemHandler()) { | |
1021 return pSystemHandler->IsSHIFTKeyDown(nFlag); | |
1022 } | |
1023 | |
1024 return FALSE; | |
1025 } | |
1026 | |
1027 FX_BOOL CPWL_Wnd::IsALTpressed(FX_DWORD nFlag) const { | |
1028 if (IFX_SystemHandler* pSystemHandler = GetSystemHandler()) { | |
1029 return pSystemHandler->IsALTKeyDown(nFlag); | |
1030 } | |
1031 | |
1032 return FALSE; | |
1033 } | |
1034 | |
1035 FX_BOOL CPWL_Wnd::IsINSERTpressed(FX_DWORD nFlag) const { | |
1036 if (IFX_SystemHandler* pSystemHandler = GetSystemHandler()) { | |
1037 return pSystemHandler->IsINSERTKeyDown(nFlag); | |
1038 } | |
1039 | |
1040 return FALSE; | |
1041 } | |
OLD | NEW |