• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "xfa/src/foxitlib.h"
8 #include "xfa/src/fwl/src/core/include/fwl_targetimp.h"
9 #include "xfa/src/fwl/src/core/include/fwl_widgetimp.h"
10 #include "xfa/src/fwl/src/core/include/fwl_widgetmgrimp.h"
11 #include "xfa/src/fwl/src/core/include/fwl_panelimp.h"
12 #include "xfa/src/fwl/src/core/include/fwl_formimp.h"
13 #include "xfa/src/fwl/src/core/include/fwl_noteimp.h"
14 #include "xfa/src/fwl/src/core/include/fwl_threadimp.h"
15 #include "xfa/src/fwl/src/core/include/fwl_appimp.h"
16 #include "xfa/src/fwl/src/basewidget/include/fwl_tooltipctrlimp.h"
CFWL_NoteLoop(CFWL_WidgetImp * pForm)17 CFWL_NoteLoop::CFWL_NoteLoop(CFWL_WidgetImp* pForm)
18     : m_pForm(pForm), m_bContinueModal(TRUE) {}
PreProcessMessage(CFWL_Message * pMessage)19 FX_BOOL CFWL_NoteLoop::PreProcessMessage(CFWL_Message* pMessage) {
20   if (!m_pForm) {
21     return FALSE;
22   }
23   return TranslateAccelerator(pMessage);
24 }
Idle(int32_t count)25 FWL_ERR CFWL_NoteLoop::Idle(int32_t count) {
26 #if (_FX_OS_ == _FX_WIN32_DESKTOP_)
27   if (count <= 0)
28 #endif
29   {
30     CFWL_EvtIdle ev;
31     IFWL_App* pApp = FWL_GetApp();
32     if (!pApp)
33       return FWL_ERR_Indefinite;
34     IFWL_NoteDriver* pDriver = pApp->GetNoteDriver();
35     if (!pDriver)
36       return FWL_ERR_Indefinite;
37     pDriver->SendNote(&ev);
38   }
39   return FWL_ERR_Indefinite;
40 }
GetForm()41 CFWL_WidgetImp* CFWL_NoteLoop::GetForm() {
42   return m_pForm;
43 }
ContinueModal()44 FX_BOOL CFWL_NoteLoop::ContinueModal() {
45   return m_bContinueModal;
46 }
EndModalLoop()47 FWL_ERR CFWL_NoteLoop::EndModalLoop() {
48   m_bContinueModal = FALSE;
49 #if (_FX_OS_ == _FX_MACOSX_)
50   CFWL_WidgetMgr* pWidgetMgr = static_cast<CFWL_WidgetMgr*>(FWL_GetWidgetMgr());
51   IFWL_AdapterWidgetMgr* adapterWidgetMgr = pWidgetMgr->GetAdapterWidgetMgr();
52   adapterWidgetMgr->EndLoop();
53 #endif
54   return FWL_ERR_Succeeded;
55 }
TranslateAccelerator(CFWL_Message * pMessage)56 FX_BOOL CFWL_NoteLoop::TranslateAccelerator(CFWL_Message* pMessage) {
57   if (pMessage->GetClassID() != FWL_MSGHASH_Key) {
58     return FALSE;
59   }
60   CFWL_MsgKey* pMsgKey = static_cast<CFWL_MsgKey*>(pMessage);
61   if (pMsgKey->m_dwCmd != FWL_MSGKEYCMD_KeyDown) {
62     return FALSE;
63   }
64   CFX_MapAccelerators& accel =
65       static_cast<CFWL_FormImp*>(m_pForm)->GetAccelerator();
66   FX_POSITION pos = accel.GetStartPosition();
67   if (!pos) {
68     return FALSE;
69   }
70   FX_DWORD vrKey, rValue;
71   while (pos) {
72     accel.GetNextAssoc(pos, vrKey, rValue);
73     FX_DWORD dwFlags = (vrKey & 0xFF00) >> 8;
74     FX_DWORD m_dwKeyCode = vrKey & 0x00FF;
75     if (pMsgKey->m_dwFlags == dwFlags && pMsgKey->m_dwKeyCode == m_dwKeyCode) {
76       GenerateCommondEvent(rValue);
77       return TRUE;
78     }
79   }
80   return FALSE;
81 }
SetMainForm(CFWL_WidgetImp * pForm)82 FWL_ERR CFWL_NoteLoop::SetMainForm(CFWL_WidgetImp* pForm) {
83   m_pForm = pForm;
84   return FWL_ERR_Succeeded;
85 }
GenerateCommondEvent(FX_DWORD dwCommand)86 void CFWL_NoteLoop::GenerateCommondEvent(FX_DWORD dwCommand) {
87   CFWL_EvtMenuCommand ev;
88   ev.m_iCommand = dwCommand;
89   IFWL_NoteThread* pThread = m_pForm->GetOwnerThread();
90   if (!pThread)
91     return;
92   IFWL_NoteDriver* pDriver = pThread->GetNoteDriver();
93   if (!pDriver)
94     return;
95   pDriver->SendNote(&ev);
96 }
CFWL_NoteDriver()97 CFWL_NoteDriver::CFWL_NoteDriver()
98     : m_sendEventCalled(0),
99       m_maxSize(500),
100       m_bFullScreen(FALSE),
101       m_pHover(nullptr),
102       m_pFocus(nullptr),
103       m_pGrab(nullptr),
104       m_hook(nullptr) {
105   m_pNoteLoop = new CFWL_NoteLoop;
106   PushNoteLoop(m_pNoteLoop);
107 }
~CFWL_NoteDriver()108 CFWL_NoteDriver::~CFWL_NoteDriver() {
109   delete m_pNoteLoop;
110   ClearInvalidEventTargets(TRUE);
111 }
SendNote(CFWL_Note * pNote)112 FX_BOOL CFWL_NoteDriver::SendNote(CFWL_Note* pNote) {
113   if (pNote->IsEvent()) {
114     int32_t iCount = m_eventTargets.GetCount();
115     if (iCount < 1) {
116       return TRUE;
117     }
118     if (FWL_EVTHASH_Mouse == static_cast<CFWL_Event*>(pNote)->GetClassID()) {
119       CFWL_EvtMouse* pMouse = static_cast<CFWL_EvtMouse*>(pNote);
120       if (FWL_MSGMOUSECMD_MouseHover == pMouse->m_dwCmd) {
121         if (m_pNoteLoop->GetForm() &&
122             CFWL_ToolTipContainer::getInstance()->ProcessEnter(
123                 pMouse, m_pNoteLoop->GetForm()->GetInterface())) {
124         }
125       } else if (FWL_MSGMOUSECMD_MouseLeave == pMouse->m_dwCmd) {
126         if (CFWL_ToolTipContainer::getInstance()->ProcessLeave(pMouse)) {
127         }
128       } else if ((FWL_MSGMOUSECMD_LButtonDown <= pMouse->m_dwCmd) &&
129                  (FWL_MSGMOUSECMD_MButtonDblClk >= pMouse->m_dwCmd)) {
130         if (CFWL_ToolTipContainer::getInstance()->ProcessLeave(pMouse)) {
131         }
132       }
133     }
134     m_sendEventCalled++;
135     FX_POSITION pos = m_eventTargets.GetStartPosition();
136     while (pos) {
137       void* key = NULL;
138       CFWL_EventTarget* pEventTarget;
139       m_eventTargets.GetNextAssoc(pos, key, (void*&)pEventTarget);
140       if (pEventTarget && !pEventTarget->IsInvalid()) {
141         pEventTarget->ProcessEvent(static_cast<CFWL_Event*>(pNote));
142       }
143     }
144     m_sendEventCalled--;
145   } else {
146     if (!pNote->m_pDstTarget)
147       return FALSE;
148     IFWL_WidgetDelegate* pDelegate = pNote->m_pDstTarget->SetDelegate(NULL);
149     if (pDelegate) {
150       pDelegate->OnProcessMessage(static_cast<CFWL_Message*>(pNote));
151     }
152   }
153   return TRUE;
154 }
155 extern void FWL_PostMessageToMainRoop(CFWL_Message* pMessage);
PostMessage(CFWL_Message * pMessage)156 FX_BOOL CFWL_NoteDriver::PostMessage(CFWL_Message* pMessage) {
157   FWL_PostMessageToMainRoop(pMessage);
158   return TRUE;
159 }
160 #define FWL_NoteDriver_EventKey 1100
RegisterEventTarget(IFWL_Widget * pListener,IFWL_Widget * pEventSource,FX_DWORD dwFilter)161 FWL_ERR CFWL_NoteDriver::RegisterEventTarget(IFWL_Widget* pListener,
162                                              IFWL_Widget* pEventSource,
163                                              FX_DWORD dwFilter) {
164   FX_DWORD dwkey = (FX_DWORD)(uintptr_t)pListener->GetPrivateData(
165       (void*)(uintptr_t)FWL_NoteDriver_EventKey);
166   if (dwkey == 0) {
167     void* random = FX_Random_MT_Start(0);
168     dwkey = rand();
169     FX_Random_MT_Close(random);
170     pListener->SetPrivateData((void*)(uintptr_t)FWL_NoteDriver_EventKey,
171                               (void*)(uintptr_t)dwkey, NULL);
172   }
173   CFWL_EventTarget* value = NULL;
174   if (!m_eventTargets.Lookup((void*)(uintptr_t)dwkey, (void*&)value)) {
175     value = new CFWL_EventTarget(this, pListener);
176     m_eventTargets.SetAt((void*)(uintptr_t)dwkey, value);
177   }
178   value->SetEventSource(pEventSource, dwFilter);
179   return FWL_ERR_Succeeded;
180 }
UnregisterEventTarget(IFWL_Widget * pListener)181 FWL_ERR CFWL_NoteDriver::UnregisterEventTarget(IFWL_Widget* pListener) {
182   FX_DWORD dwkey = (FX_DWORD)(uintptr_t)pListener->GetPrivateData(
183       (void*)(uintptr_t)FWL_NoteDriver_EventKey);
184   if (dwkey == 0) {
185     return FWL_ERR_Indefinite;
186   }
187   CFWL_EventTarget* value = NULL;
188   if (m_eventTargets.Lookup((void*)(uintptr_t)dwkey, (void*&)value)) {
189     value->FlagInvalid();
190   }
191   return FWL_ERR_Succeeded;
192 }
ClearEventTargets(FX_BOOL bRemoveAll)193 void CFWL_NoteDriver::ClearEventTargets(FX_BOOL bRemoveAll) {
194   ClearInvalidEventTargets(bRemoveAll);
195 }
GetQueueMaxSize() const196 int32_t CFWL_NoteDriver::GetQueueMaxSize() const {
197   return m_maxSize;
198 }
SetQueueMaxSize(const int32_t size)199 FWL_ERR CFWL_NoteDriver::SetQueueMaxSize(const int32_t size) {
200   m_maxSize = size;
201   return FWL_ERR_Succeeded;
202 }
GetOwnerThread() const203 IFWL_NoteThread* CFWL_NoteDriver::GetOwnerThread() const {
204   return FWL_GetApp();
205 }
PushNoteLoop(IFWL_NoteLoop * pNoteLoop)206 FWL_ERR CFWL_NoteDriver::PushNoteLoop(IFWL_NoteLoop* pNoteLoop) {
207   m_noteLoopQueue.Add(pNoteLoop);
208   return FWL_ERR_Succeeded;
209 }
PopNoteLoop()210 IFWL_NoteLoop* CFWL_NoteDriver::PopNoteLoop() {
211   int32_t pos = m_noteLoopQueue.GetSize();
212   if (pos <= 0)
213     return NULL;
214   IFWL_NoteLoop* p =
215       static_cast<IFWL_NoteLoop*>(m_noteLoopQueue.GetAt(pos - 1));
216   m_noteLoopQueue.RemoveAt(pos - 1);
217   return p;
218 }
SetFocus(IFWL_Widget * pFocus,FX_BOOL bNotify)219 FX_BOOL CFWL_NoteDriver::SetFocus(IFWL_Widget* pFocus, FX_BOOL bNotify) {
220   if (m_pFocus == pFocus) {
221     return TRUE;
222   }
223   IFWL_Widget* pPrev = m_pFocus;
224   m_pFocus = pFocus;
225   if (pPrev) {
226     CFWL_MsgKillFocus ms;
227     ms.m_pDstTarget = pPrev;
228     ms.m_pSrcTarget = pPrev;
229     if (bNotify) {
230       ms.m_dwExtend = 1;
231     }
232     IFWL_WidgetDelegate* pDelegate = pPrev->SetDelegate(NULL);
233     if (pDelegate) {
234       pDelegate->OnProcessMessage(&ms);
235     }
236   }
237   if (pFocus) {
238     IFWL_Widget* pWidget =
239         FWL_GetWidgetMgr()->GetWidget(pFocus, FWL_WGTRELATION_SystemForm);
240     CFWL_FormImp* pForm =
241         pWidget ? static_cast<CFWL_FormImp*>(pWidget->GetImpl()) : nullptr;
242     if (pForm) {
243       CFWL_WidgetImp* pNewFocus =
244           static_cast<CFWL_WidgetImp*>(pFocus->GetImpl());
245       pForm->SetSubFocus(pNewFocus);
246     }
247     CFWL_MsgSetFocus ms;
248     ms.m_pDstTarget = pFocus;
249     if (bNotify) {
250       ms.m_dwExtend = 1;
251     }
252     IFWL_WidgetDelegate* pDelegate = pFocus->SetDelegate(NULL);
253     if (pDelegate) {
254       pDelegate->OnProcessMessage(&ms);
255     }
256   }
257   return TRUE;
258 }
Run()259 FWL_ERR CFWL_NoteDriver::Run() {
260   CFWL_WidgetMgr* pWidgetMgr = static_cast<CFWL_WidgetMgr*>(FWL_GetWidgetMgr());
261   if (!pWidgetMgr)
262     return FWL_ERR_Indefinite;
263 #if (_FX_OS_ == _FX_MACOSX_)
264   IFWL_AdapterWidgetMgr* adapterWidgetMgr = pWidgetMgr->GetAdapterWidgetMgr();
265   CFWL_NoteLoop* pTopLoop = GetTopLoop();
266   if (pTopLoop) {
267     CFWL_WidgetImp* formImp = pTopLoop->GetForm();
268     if (formImp) {
269       IFWL_Widget* pForm = formImp->GetInterface();
270       adapterWidgetMgr->RunLoop(pForm);
271     }
272   }
273 #elif(_FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_)
274   FX_BOOL bIdle = TRUE;
275   int32_t iIdleCount = 0;
276   CFWL_NoteLoop* pTopLoop = NULL;
277   for (;;) {
278     pTopLoop = GetTopLoop();
279     if (!pTopLoop || !pTopLoop->ContinueModal()) {
280       break;
281     }
282     if (UnqueueMessage(pTopLoop)) {
283       continue;
284     }
285     while (bIdle && !(pWidgetMgr->CheckMessage_Native())) {
286       if (FWL_ERR_Indefinite == pTopLoop->Idle(iIdleCount++)) {
287         bIdle = FALSE;
288       }
289     }
290     do {
291       if (FWL_ERR_Indefinite == pWidgetMgr->DispatchMessage_Native()) {
292         break;
293       }
294       if (pWidgetMgr->IsIdleMessage_Native()) {
295         bIdle = TRUE;
296         iIdleCount = 0;
297       }
298     } while (pWidgetMgr->CheckMessage_Native());
299   }
300 #elif(_FX_OS_ == _FX_LINUX_DESKTOP_)
301   CFWL_NoteLoop* pTopLoop = NULL;
302   for (;;) {
303     pTopLoop = GetTopLoop();
304     if (!pTopLoop || !pTopLoop->ContinueModal()) {
305       break;
306     }
307     if (UnqueueMessage(pTopLoop)) {
308       continue;
309     }
310     if (pWidgetMgr->CheckMessage_Native()) {
311       pWidgetMgr->DispatchMessage_Native();
312     }
313   }
314 #endif
315   return FWL_ERR_Succeeded;
316 }
GetFocus()317 IFWL_Widget* CFWL_NoteDriver::GetFocus() {
318   return m_pFocus;
319 }
GetHover()320 IFWL_Widget* CFWL_NoteDriver::GetHover() {
321   return m_pHover;
322 }
SetHover(IFWL_Widget * pHover)323 void CFWL_NoteDriver::SetHover(IFWL_Widget* pHover) {
324   m_pHover = pHover;
325 }
SetGrab(IFWL_Widget * pGrab,FX_BOOL bSet)326 void CFWL_NoteDriver::SetGrab(IFWL_Widget* pGrab, FX_BOOL bSet) {
327   m_pGrab = bSet ? pGrab : NULL;
328 }
NotifyTargetHide(IFWL_Widget * pNoteTarget)329 void CFWL_NoteDriver::NotifyTargetHide(IFWL_Widget* pNoteTarget) {
330   if (m_pFocus == pNoteTarget) {
331     m_pFocus = NULL;
332   }
333   if (m_pHover == pNoteTarget) {
334     m_pHover = NULL;
335   }
336   if (m_pGrab == pNoteTarget) {
337     m_pGrab = NULL;
338   }
339 }
NotifyTargetDestroy(IFWL_Widget * pNoteTarget)340 void CFWL_NoteDriver::NotifyTargetDestroy(IFWL_Widget* pNoteTarget) {
341   if (m_pFocus == pNoteTarget) {
342     m_pFocus = NULL;
343   }
344   if (m_pHover == pNoteTarget) {
345     m_pHover = NULL;
346   }
347   if (m_pGrab == pNoteTarget) {
348     m_pGrab = NULL;
349   }
350   UnregisterEventTarget(pNoteTarget);
351   int32_t count = m_forms.GetSize();
352   for (int32_t nIndex = 0; nIndex < count; nIndex++) {
353     CFWL_FormImp* pForm = static_cast<CFWL_FormImp*>(m_forms[nIndex]);
354     if (!pForm) {
355       continue;
356     }
357     CFWL_WidgetImp* pSubFocus = pForm->GetSubFocus();
358     if (!pSubFocus)
359       return;
360     if (pSubFocus && pSubFocus->GetInterface() == pNoteTarget) {
361       pForm->SetSubFocus(NULL);
362     }
363   }
364 }
NotifyFullScreenMode(IFWL_Widget * pNoteTarget,FX_BOOL bFullScreen)365 void CFWL_NoteDriver::NotifyFullScreenMode(IFWL_Widget* pNoteTarget,
366                                            FX_BOOL bFullScreen) {
367   m_bFullScreen = bFullScreen;
368 }
RegisterForm(CFWL_WidgetImp * pForm)369 FWL_ERR CFWL_NoteDriver::RegisterForm(CFWL_WidgetImp* pForm) {
370   if (!pForm)
371     return FWL_ERR_Indefinite;
372   if (m_forms.Find(pForm) >= 0) {
373     return FWL_ERR_Indefinite;
374   }
375   m_forms.Add(pForm);
376   if (m_forms.GetSize() == 1) {
377     CFWL_NoteLoop* pLoop =
378         static_cast<CFWL_NoteLoop*>(m_noteLoopQueue.GetAt(0));
379     if (!pLoop)
380       return FWL_ERR_Indefinite;
381     pLoop->SetMainForm(pForm);
382   }
383   return FWL_ERR_Succeeded;
384 }
UnRegisterForm(CFWL_WidgetImp * pForm)385 FWL_ERR CFWL_NoteDriver::UnRegisterForm(CFWL_WidgetImp* pForm) {
386   if (!pForm)
387     return FWL_ERR_Indefinite;
388   int32_t nIndex = m_forms.Find(pForm);
389   if (nIndex < 0) {
390     return FWL_ERR_Indefinite;
391   }
392   m_forms.RemoveAt(nIndex);
393   return FWL_ERR_Succeeded;
394 }
QueueMessage(CFWL_Message * pMessage)395 FX_BOOL CFWL_NoteDriver::QueueMessage(CFWL_Message* pMessage) {
396   pMessage->Retain();
397   m_noteQueue.Add(pMessage);
398   return TRUE;
399 }
UnqueueMessage(CFWL_NoteLoop * pNoteLoop)400 FX_BOOL CFWL_NoteDriver::UnqueueMessage(CFWL_NoteLoop* pNoteLoop) {
401   if (m_noteQueue.GetSize() < 1) {
402     return FALSE;
403   }
404   CFWL_Message* pMessage = static_cast<CFWL_Message*>(m_noteQueue[0]);
405   m_noteQueue.RemoveAt(0);
406   if (!IsValidMessage(pMessage)) {
407     pMessage->Release();
408     return TRUE;
409   }
410   FX_BOOL bHookMessage = FALSE;
411   if (m_hook) {
412     bHookMessage = (*m_hook)(pMessage, m_hookInfo);
413   }
414   if (!bHookMessage && !pNoteLoop->PreProcessMessage(pMessage)) {
415     ProcessMessage(pMessage);
416   }
417   pMessage->Release();
418   return TRUE;
419 }
GetTopLoop()420 CFWL_NoteLoop* CFWL_NoteDriver::GetTopLoop() {
421   int32_t size = m_noteLoopQueue.GetSize();
422   if (size <= 0)
423     return NULL;
424   return static_cast<CFWL_NoteLoop*>(m_noteLoopQueue[size - 1]);
425 }
CountLoop()426 int32_t CFWL_NoteDriver::CountLoop() {
427   return m_noteLoopQueue.GetSize();
428 }
SetHook(FWLMessageHookCallback callback,void * info)429 void CFWL_NoteDriver::SetHook(FWLMessageHookCallback callback, void* info) {
430   m_hook = callback;
431   m_hookInfo = info;
432 }
ProcessMessage(CFWL_Message * pMessage)433 FX_BOOL CFWL_NoteDriver::ProcessMessage(CFWL_Message* pMessage) {
434   CFWL_WidgetMgr* pWidgetMgr = static_cast<CFWL_WidgetMgr*>(FWL_GetWidgetMgr());
435   IFWL_Widget* pMessageForm = pWidgetMgr->IsFormDisabled()
436                                   ? pMessage->m_pDstTarget
437                                   : GetMessageForm(pMessage->m_pDstTarget);
438   if (!pMessageForm)
439     return FALSE;
440   if (DispatchMessage(pMessage, pMessageForm)) {
441     if (pMessage->GetClassID() == FWL_MSGHASH_Mouse) {
442       MouseSecondary(static_cast<CFWL_MsgMouse*>(pMessage));
443     }
444     return TRUE;
445   }
446   return FALSE;
447 }
DispatchMessage(CFWL_Message * pMessage,IFWL_Widget * pMessageForm)448 FX_BOOL CFWL_NoteDriver::DispatchMessage(CFWL_Message* pMessage,
449                                          IFWL_Widget* pMessageForm) {
450   FX_BOOL bRet = FALSE;
451   switch (pMessage->GetClassID()) {
452     case FWL_MSGHASH_Activate: {
453       bRet = DoActivate(static_cast<CFWL_MsgActivate*>(pMessage), pMessageForm);
454       break;
455     }
456     case FWL_MSGHASH_Deactivate: {
457       bRet = DoDeactivate(static_cast<CFWL_MsgDeactivate*>(pMessage),
458                           pMessageForm);
459       break;
460     }
461     case FWL_MSGHASH_SetFocus: {
462       bRet = DoSetFocus(static_cast<CFWL_MsgSetFocus*>(pMessage), pMessageForm);
463       break;
464     }
465     case FWL_MSGHASH_KillFocus: {
466       bRet =
467           DoKillFocus(static_cast<CFWL_MsgKillFocus*>(pMessage), pMessageForm);
468       break;
469     }
470     case FWL_MSGHASH_Key: {
471       bRet = DoKey(static_cast<CFWL_MsgKey*>(pMessage), pMessageForm);
472       break;
473     }
474     case FWL_MSGHASH_Mouse: {
475       bRet = DoMouse(static_cast<CFWL_MsgMouse*>(pMessage), pMessageForm);
476       break;
477     }
478     case FWL_MSGHASH_MouseWheel: {
479       bRet = DoWheel(static_cast<CFWL_MsgMouseWheel*>(pMessage), pMessageForm);
480       break;
481     }
482     case FWL_MSGHASH_Size: {
483       bRet = DoSize(static_cast<CFWL_MsgSize*>(pMessage));
484       break;
485     }
486     case FWL_MSGHASH_Cursor: {
487       bRet = TRUE;
488       break;
489     }
490     case FWL_MSGHASH_WindowMove: {
491       bRet = DoWindowMove(static_cast<CFWL_MsgWindowMove*>(pMessage),
492                           pMessageForm);
493       break;
494     }
495     case FWL_MSGHASH_DropFiles: {
496       bRet =
497           DoDragFiles(static_cast<CFWL_MsgDropFiles*>(pMessage), pMessageForm);
498       break;
499     }
500     default: {
501       bRet = TRUE;
502       break;
503     }
504   }
505   if (bRet) {
506     IFWL_WidgetDelegate* pDelegate = pMessage->m_pDstTarget->SetDelegate(NULL);
507     if (pDelegate) {
508       pDelegate->OnProcessMessage(pMessage);
509     }
510   }
511   return bRet;
512 }
DoActivate(CFWL_MsgActivate * pMsg,IFWL_Widget * pMessageForm)513 FX_BOOL CFWL_NoteDriver::DoActivate(CFWL_MsgActivate* pMsg,
514                                     IFWL_Widget* pMessageForm) {
515   if (m_bFullScreen) {
516     return FALSE;
517   }
518   pMsg->m_pDstTarget = pMessageForm;
519   return (pMsg->m_pDstTarget)->GetStates() & FWL_WGTSTATE_Deactivated;
520 }
DoDeactivate(CFWL_MsgDeactivate * pMsg,IFWL_Widget * pMessageForm)521 FX_BOOL CFWL_NoteDriver::DoDeactivate(CFWL_MsgDeactivate* pMsg,
522                                       IFWL_Widget* pMessageForm) {
523   if (m_bFullScreen) {
524     return FALSE;
525   }
526   int32_t iTrackLoop = m_noteLoopQueue.GetSize();
527   if (iTrackLoop <= 0)
528     return FALSE;
529   if (iTrackLoop == 1) {
530     if (pMessageForm->IsInstance(FX_WSTRC(L"FWL_FORMPROXY"))) {
531       return FALSE;
532     }
533     if (pMsg->m_pSrcTarget &&
534         pMsg->m_pSrcTarget->IsInstance(FX_WSTRC(L"FWL_FORMPROXY"))) {
535       return FALSE;
536     }
537     if (pMsg->m_pSrcTarget && pMsg->m_pSrcTarget->GetClassID() == 1111984755) {
538       return FALSE;
539     }
540     return TRUE;
541   }
542   IFWL_Widget* pDst = pMsg->m_pDstTarget;
543   if (!pDst)
544     return FALSE;
545 #if (_FX_OS_ == _FX_MACOSX_)
546   if (pDst == pMessageForm && pDst->IsInstance(L"FWL_FORMPROXY")) {
547     return TRUE;
548   }
549 #endif
550   return pDst != pMessageForm &&
551          !pDst->IsInstance(FX_WSTRC(L"FWL_FORMPROXY")) &&
552          !pMessageForm->IsInstance(FX_WSTRC(L"FWL_FORMPROXY"));
553 }
DoSetFocus(CFWL_MsgSetFocus * pMsg,IFWL_Widget * pMessageForm)554 FX_BOOL CFWL_NoteDriver::DoSetFocus(CFWL_MsgSetFocus* pMsg,
555                                     IFWL_Widget* pMessageForm) {
556   CFWL_WidgetMgr* pWidgetMgr = static_cast<CFWL_WidgetMgr*>(FWL_GetWidgetMgr());
557   if (pWidgetMgr->IsFormDisabled()) {
558     m_pFocus = pMsg->m_pDstTarget;
559     return TRUE;
560   } else {
561     IFWL_Widget* pWidget = pMsg->m_pDstTarget;
562     CFWL_FormImp* pForm =
563         pWidget ? static_cast<CFWL_FormImp*>(pWidget->GetImpl()) : nullptr;
564     if (pForm) {
565       CFWL_WidgetImp* pSubFocus = pForm->GetSubFocus();
566       if (pSubFocus && ((pSubFocus->GetStates() & FWL_WGTSTATE_Focused) == 0)) {
567         pMsg->m_pDstTarget = pSubFocus->GetInterface();
568         if (m_pFocus != pMsg->m_pDstTarget) {
569           m_pFocus = pMsg->m_pDstTarget;
570           return TRUE;
571         }
572       }
573     }
574   }
575   return FALSE;
576 }
DoKillFocus(CFWL_MsgKillFocus * pMsg,IFWL_Widget * pMessageForm)577 FX_BOOL CFWL_NoteDriver::DoKillFocus(CFWL_MsgKillFocus* pMsg,
578                                      IFWL_Widget* pMessageForm) {
579   CFWL_WidgetMgr* pWidgetMgr = static_cast<CFWL_WidgetMgr*>(FWL_GetWidgetMgr());
580   if (pWidgetMgr->IsFormDisabled()) {
581     if (m_pFocus == pMsg->m_pDstTarget) {
582       m_pFocus = NULL;
583     }
584     return TRUE;
585   }
586   IFWL_Widget* pWidget = pMsg->m_pDstTarget;
587   CFWL_FormImp* pForm =
588       pWidget ? static_cast<CFWL_FormImp*>(pWidget->GetImpl()) : nullptr;
589   if (pForm) {
590     CFWL_WidgetImp* pSubFocus = pForm->GetSubFocus();
591     if (pSubFocus && (pSubFocus->GetStates() & FWL_WGTSTATE_Focused)) {
592       pMsg->m_pDstTarget = pSubFocus->GetInterface();
593       if (m_pFocus == pMsg->m_pDstTarget) {
594         m_pFocus = NULL;
595         return TRUE;
596       }
597     }
598   }
599   return FALSE;
600 }
DoKey(CFWL_MsgKey * pMsg,IFWL_Widget * pMessageForm)601 FX_BOOL CFWL_NoteDriver::DoKey(CFWL_MsgKey* pMsg, IFWL_Widget* pMessageForm) {
602 #if (_FX_OS_ != _FX_MACOSX_)
603   if (pMsg->m_dwCmd == FWL_MSGKEYCMD_KeyDown &&
604       pMsg->m_dwKeyCode == FWL_VKEY_Tab) {
605     CFWL_WidgetMgr* pWidgetMgr =
606         static_cast<CFWL_WidgetMgr*>(FWL_GetWidgetMgr());
607     IFWL_Widget* pForm = GetMessageForm(pMsg->m_pDstTarget);
608     IFWL_Widget* pFocus = m_pFocus;
609     if (m_pFocus) {
610       if (pWidgetMgr->GetWidget(m_pFocus, FWL_WGTRELATION_SystemForm) !=
611           pForm) {
612         pFocus = NULL;
613       }
614     }
615     FX_BOOL bFind = FALSE;
616     IFWL_Widget* pNextTabStop = pWidgetMgr->nextTab(pForm, pFocus, bFind);
617     if (!pNextTabStop) {
618       bFind = FALSE;
619       pNextTabStop = pWidgetMgr->nextTab(pForm, NULL, bFind);
620     }
621     if (pNextTabStop == pFocus) {
622       return TRUE;
623     }
624     if (pNextTabStop) {
625       SetFocus(pNextTabStop);
626     }
627     return TRUE;
628   }
629 #endif
630   if (!m_pFocus) {
631     if (pMsg->m_dwCmd == FWL_MSGKEYCMD_KeyDown &&
632         pMsg->m_dwKeyCode == FWL_VKEY_Return) {
633       CFWL_WidgetMgr* pWidgetMgr =
634           static_cast<CFWL_WidgetMgr*>(FWL_GetWidgetMgr());
635       IFWL_Widget* defButton = pWidgetMgr->GetDefaultButton(pMessageForm);
636       if (defButton) {
637         pMsg->m_pDstTarget = defButton;
638         return TRUE;
639       }
640     }
641     return FALSE;
642   }
643   pMsg->m_pDstTarget = m_pFocus;
644   return TRUE;
645 }
DoMouse(CFWL_MsgMouse * pMsg,IFWL_Widget * pMessageForm)646 FX_BOOL CFWL_NoteDriver::DoMouse(CFWL_MsgMouse* pMsg,
647                                  IFWL_Widget* pMessageForm) {
648   if (pMsg->m_dwCmd == FWL_MSGMOUSECMD_MouseLeave ||
649       pMsg->m_dwCmd == FWL_MSGMOUSECMD_MouseHover ||
650       pMsg->m_dwCmd == FWL_MSGMOUSECMD_MouseEnter) {
651     return pMsg->m_pDstTarget != NULL;
652   }
653   if (pMsg->m_pDstTarget != pMessageForm) {
654     pMsg->m_pDstTarget->TransformTo(pMessageForm, pMsg->m_fx, pMsg->m_fy);
655   }
656   if (!DoMouseEx(pMsg, pMessageForm)) {
657     pMsg->m_pDstTarget = pMessageForm;
658   }
659   return TRUE;
660 }
DoWheel(CFWL_MsgMouseWheel * pMsg,IFWL_Widget * pMessageForm)661 FX_BOOL CFWL_NoteDriver::DoWheel(CFWL_MsgMouseWheel* pMsg,
662                                  IFWL_Widget* pMessageForm) {
663   CFWL_WidgetMgr* pWidgetMgr = static_cast<CFWL_WidgetMgr*>(FWL_GetWidgetMgr());
664   if (!pWidgetMgr)
665     return FALSE;
666   IFWL_Widget* pDst =
667       pWidgetMgr->GetWidgetAtPoint(pMessageForm, pMsg->m_fx, pMsg->m_fy);
668   if (!pDst)
669     return FALSE;
670   while (pDst && pDst->GetClassID() == FWL_CLASSHASH_Grid) {
671     pDst = pDst->GetParent();
672   }
673   pMessageForm->TransformTo(pDst, pMsg->m_fx, pMsg->m_fy);
674   pMsg->m_pDstTarget = pDst;
675   return TRUE;
676 }
DoSize(CFWL_MsgSize * pMsg)677 FX_BOOL CFWL_NoteDriver::DoSize(CFWL_MsgSize* pMsg) {
678   CFWL_WidgetMgr* pWidgetMgr = static_cast<CFWL_WidgetMgr*>(FWL_GetWidgetMgr());
679   if (!pWidgetMgr)
680     return FALSE;
681   pWidgetMgr->NotifySizeChanged(pMsg->m_pDstTarget, (FX_FLOAT)pMsg->m_iWidth,
682                                 (FX_FLOAT)pMsg->m_iHeight);
683   return TRUE;
684 }
DoWindowMove(CFWL_MsgWindowMove * pMsg,IFWL_Widget * pMessageForm)685 FX_BOOL CFWL_NoteDriver::DoWindowMove(CFWL_MsgWindowMove* pMsg,
686                                       IFWL_Widget* pMessageForm) {
687   return pMsg->m_pDstTarget == pMessageForm;
688 }
DoDragFiles(CFWL_MsgDropFiles * pMsg,IFWL_Widget * pMessageForm)689 FX_BOOL CFWL_NoteDriver::DoDragFiles(CFWL_MsgDropFiles* pMsg,
690                                      IFWL_Widget* pMessageForm) {
691   return pMsg->m_pDstTarget == pMessageForm;
692 }
DoMouseEx(CFWL_MsgMouse * pMsg,IFWL_Widget * pMessageForm)693 FX_BOOL CFWL_NoteDriver::DoMouseEx(CFWL_MsgMouse* pMsg,
694                                    IFWL_Widget* pMessageForm) {
695   CFWL_WidgetMgr* pWidgetMgr = static_cast<CFWL_WidgetMgr*>(FWL_GetWidgetMgr());
696   if (!pWidgetMgr)
697     return FALSE;
698   IFWL_Widget* pTarget = NULL;
699   if (m_pGrab)
700     pTarget = m_pGrab;
701   if (!pTarget) {
702     pTarget =
703         pWidgetMgr->GetWidgetAtPoint(pMessageForm, pMsg->m_fx, pMsg->m_fy);
704     while (pTarget && pTarget->GetClassID() == FWL_CLASSHASH_Grid) {
705       pTarget = pTarget->GetParent();
706     }
707   }
708   if (pTarget) {
709     if (pMessageForm != pTarget) {
710       pMessageForm->TransformTo(pTarget, pMsg->m_fx, pMsg->m_fy);
711     }
712   }
713   if (!pTarget)
714     return FALSE;
715   pMsg->m_pDstTarget = pTarget;
716   return TRUE;
717 }
MouseSecondary(CFWL_MsgMouse * pMsg)718 void CFWL_NoteDriver::MouseSecondary(CFWL_MsgMouse* pMsg) {
719   IFWL_Widget* pTarget = pMsg->m_pDstTarget;
720   if (pTarget == m_pHover) {
721     return;
722   }
723   if (m_pHover) {
724     CFWL_MsgMouse msLeave;
725     msLeave.m_pDstTarget = m_pHover;
726     msLeave.m_fx = pMsg->m_fx;
727     msLeave.m_fy = pMsg->m_fy;
728     pTarget->TransformTo(m_pHover, msLeave.m_fx, msLeave.m_fy);
729     msLeave.m_dwFlags = 0;
730     msLeave.m_dwCmd = FWL_MSGMOUSECMD_MouseLeave;
731     DispatchMessage(&msLeave, NULL);
732   }
733   if (pTarget->GetClassID() == FWL_CLASSHASH_Form) {
734     m_pHover = NULL;
735     return;
736   }
737   m_pHover = pTarget;
738   CFWL_MsgMouse msHover;
739   msHover.m_pDstTarget = pTarget;
740   msHover.m_fx = pMsg->m_fx;
741   msHover.m_fy = pMsg->m_fy;
742   msHover.m_dwFlags = 0;
743   msHover.m_dwCmd = FWL_MSGMOUSECMD_MouseHover;
744   DispatchMessage(&msHover, NULL);
745 }
IsValidMessage(CFWL_Message * pMessage)746 FX_BOOL CFWL_NoteDriver::IsValidMessage(CFWL_Message* pMessage) {
747   if (pMessage->GetClassID() == FWL_MSGHASH_Post) {
748     return TRUE;
749   }
750   int32_t iCount = m_noteLoopQueue.GetSize();
751   for (int32_t i = 0; i < iCount; i++) {
752     CFWL_NoteLoop* pNoteLoop = static_cast<CFWL_NoteLoop*>(m_noteLoopQueue[i]);
753     CFWL_WidgetImp* pForm = pNoteLoop->GetForm();
754     if (pForm && (pForm->GetInterface() == pMessage->m_pDstTarget)) {
755       return TRUE;
756     }
757   }
758   iCount = m_forms.GetSize();
759   for (int32_t j = 0; j < iCount; j++) {
760     CFWL_FormImp* pForm = static_cast<CFWL_FormImp*>(m_forms[j]);
761     if (pForm->GetInterface() == pMessage->m_pDstTarget) {
762       return TRUE;
763     }
764   }
765   return FALSE;
766 }
GetMessageForm(IFWL_Widget * pDstTarget)767 IFWL_Widget* CFWL_NoteDriver::GetMessageForm(IFWL_Widget* pDstTarget) {
768   int32_t iTrackLoop = m_noteLoopQueue.GetSize();
769   if (iTrackLoop <= 0)
770     return NULL;
771   IFWL_Widget* pMessageForm = NULL;
772   if (iTrackLoop > 1) {
773     CFWL_NoteLoop* pNootLoop =
774         static_cast<CFWL_NoteLoop*>(m_noteLoopQueue[iTrackLoop - 1]);
775     pMessageForm = pNootLoop->GetForm()->GetInterface();
776   } else {
777     pMessageForm = (m_forms.Find(pDstTarget) < 0) ? NULL : pDstTarget;
778   }
779   if (!pMessageForm && pDstTarget) {
780     CFWL_WidgetMgr* pWidgetMgr =
781         static_cast<CFWL_WidgetMgr*>(FWL_GetWidgetMgr());
782     if (!pWidgetMgr)
783       return NULL;
784     pMessageForm =
785         pWidgetMgr->GetWidget(pDstTarget, FWL_WGTRELATION_SystemForm);
786   }
787   return pMessageForm;
788 }
ClearInvalidEventTargets(FX_BOOL bRemoveAll)789 void CFWL_NoteDriver::ClearInvalidEventTargets(FX_BOOL bRemoveAll) {
790   FX_POSITION pos = m_eventTargets.GetStartPosition();
791   while (pos) {
792     void* key = NULL;
793     CFWL_EventTarget* pEventTarget = NULL;
794     m_eventTargets.GetNextAssoc(pos, key, (void*&)pEventTarget);
795     if (pEventTarget && (bRemoveAll || pEventTarget->IsInvalid())) {
796       m_eventTargets.RemoveKey(key);
797       delete pEventTarget;
798     }
799   }
800 }
801 class CFWL_CoreToopTipDP : public IFWL_ToolTipDP {
802  public:
803   FWL_ERR GetCaption(IFWL_Widget* pWidget, CFX_WideString& wsCaption);
804   int32_t GetInitialDelay(IFWL_Widget* pWidget);
805   int32_t GetAutoPopDelay(IFWL_Widget* pWidget);
806   CFX_DIBitmap* GetToolTipIcon(IFWL_Widget* pWidget);
807   CFX_SizeF GetToolTipIconSize(IFWL_Widget* pWidget);
808   CFX_RectF GetAnchor();
809   CFWL_CoreToopTipDP();
810 
811   CFX_WideString m_wsCaption;
812   int32_t m_nInitDelayTime;
813   int32_t m_nAutoPopDelayTime;
814   CFX_RectF m_fAnchor;
815 };
CFWL_CoreToopTipDP()816 CFWL_CoreToopTipDP::CFWL_CoreToopTipDP() {
817   m_nInitDelayTime = 500;
818   m_nAutoPopDelayTime = 50000;
819   m_fAnchor.Set(0.0, 0.0, 0.0, 0.0);
820 }
GetCaption(IFWL_Widget * pWidget,CFX_WideString & wsCaption)821 FWL_ERR CFWL_CoreToopTipDP::GetCaption(IFWL_Widget* pWidget,
822                                        CFX_WideString& wsCaption) {
823   wsCaption = m_wsCaption;
824   return FWL_ERR_Succeeded;
825 }
GetInitialDelay(IFWL_Widget * pWidget)826 int32_t CFWL_CoreToopTipDP::GetInitialDelay(IFWL_Widget* pWidget) {
827   return m_nInitDelayTime;
828 }
GetAutoPopDelay(IFWL_Widget * pWidget)829 int32_t CFWL_CoreToopTipDP::GetAutoPopDelay(IFWL_Widget* pWidget) {
830   return m_nAutoPopDelayTime;
831 }
GetToolTipIcon(IFWL_Widget * pWidget)832 CFX_DIBitmap* CFWL_CoreToopTipDP::GetToolTipIcon(IFWL_Widget* pWidget) {
833   return NULL;
834 }
GetToolTipIconSize(IFWL_Widget * pWidget)835 CFX_SizeF CFWL_CoreToopTipDP::GetToolTipIconSize(IFWL_Widget* pWidget) {
836   CFX_SizeF sz;
837   sz.Set(0, 0);
838   return sz;
839 }
GetAnchor()840 CFX_RectF CFWL_CoreToopTipDP::GetAnchor() {
841   return m_fAnchor;
842 }
~CFWL_EventTarget()843 CFWL_EventTarget::~CFWL_EventTarget() {
844   m_eventSources.RemoveAll();
845 }
SetEventSource(IFWL_Widget * pSource,FX_DWORD dwFilter)846 int32_t CFWL_EventTarget::SetEventSource(IFWL_Widget* pSource,
847                                          FX_DWORD dwFilter) {
848   if (pSource) {
849     m_eventSources.SetAt(pSource, dwFilter);
850     return m_eventSources.GetCount();
851   }
852   return 1;
853 }
ProcessEvent(CFWL_Event * pEvent)854 FX_BOOL CFWL_EventTarget::ProcessEvent(CFWL_Event* pEvent) {
855   IFWL_WidgetDelegate* pDelegate = m_pListener->SetDelegate(NULL);
856   if (!pDelegate)
857     return FALSE;
858   if (m_eventSources.GetCount() == 0) {
859     pDelegate->OnProcessEvent(pEvent);
860     return TRUE;
861   }
862   FX_POSITION pos = m_eventSources.GetStartPosition();
863   while (pos) {
864     IFWL_Widget* pSource = NULL;
865     FX_DWORD dwFilter = 0;
866     m_eventSources.GetNextAssoc(pos, (void*&)pSource, dwFilter);
867     if (pSource == pEvent->m_pSrcTarget ||
868         pEvent->GetClassID() == FWL_EVTHASH_Idle) {
869       if (IsFilterEvent(pEvent, dwFilter)) {
870         pDelegate->OnProcessEvent(pEvent);
871         return TRUE;
872       }
873     }
874   }
875   return FALSE;
876 }
IsFilterEvent(CFWL_Event * pEvent,FX_DWORD dwFilter)877 FX_BOOL CFWL_EventTarget::IsFilterEvent(CFWL_Event* pEvent, FX_DWORD dwFilter) {
878   if (dwFilter == FWL_EVENT_ALL_MASK) {
879     return TRUE;
880   }
881   FX_BOOL bRet = FALSE;
882   switch (pEvent->GetClassID()) {
883     case FWL_EVTHASH_Mouse: {
884       bRet = dwFilter & FWL_EVENT_MOUSE_MASK;
885       break;
886     }
887     case FWL_EVTHASH_MouseWheel: {
888       bRet = dwFilter & FWL_EVENT_MOUSEWHEEL_MASK;
889       break;
890     }
891     case FWL_EVTHASH_Key: {
892       bRet = dwFilter & FWL_EVENT_KEY_MASK;
893       break;
894     }
895     case FWL_EVTHASH_SetFocus:
896     case FWL_EVTHASH_KillFocus: {
897       bRet = dwFilter & FWL_EVENT_FOCUSCHANGED_MASK;
898       break;
899     }
900     case FWL_EVTHASH_Draw: {
901       bRet = dwFilter & FWL_EVENT_DRAW_MASK;
902       break;
903     }
904     case FWL_EVTHASH_Close: {
905       bRet = dwFilter & FWL_EVENT_CLOSE_MASK;
906       break;
907     }
908     case FWL_EVTHASH_SizeChanged: {
909       bRet = dwFilter & FWL_EVENT_SIZECHANGED_MASK;
910       break;
911     }
912     case FWL_EVTHASH_Idle: {
913       bRet = dwFilter & FWL_EVENT_IDLE_MASK;
914       break;
915     }
916     default: {
917       bRet = dwFilter & FWL_EVENT_CONTROL_MASK;
918       break;
919     }
920   }
921   return bRet;
922 }
923 
924 CFWL_ToolTipContainer* CFWL_ToolTipContainer::s_pInstance = NULL;
925 
CFWL_ToolTipContainer()926 CFWL_ToolTipContainer::CFWL_ToolTipContainer()
927     : pCurTarget(NULL), m_pToolTipImp(NULL) {
928   m_ToolTipDp = new CFWL_CoreToopTipDP;
929   m_ToolTipDp->m_nInitDelayTime = 0;
930   m_ToolTipDp->m_nAutoPopDelayTime = 2000;
931 }
~CFWL_ToolTipContainer()932 CFWL_ToolTipContainer::~CFWL_ToolTipContainer() {
933   if (m_pToolTipImp) {
934     IFWL_ToolTip* pToolTip =
935         static_cast<IFWL_ToolTip*>(m_pToolTipImp->GetInterface());
936     pToolTip->Finalize();
937     delete pToolTip;
938   }
939   delete m_ToolTipDp;
940 }
941 // static
getInstance()942 CFWL_ToolTipContainer* CFWL_ToolTipContainer::getInstance() {
943   if (!s_pInstance) {
944     s_pInstance = new CFWL_ToolTipContainer;
945   }
946   return s_pInstance;
947 }
948 // static
DeleteInstance()949 void CFWL_ToolTipContainer::DeleteInstance() {
950   if (s_pInstance) {
951     delete s_pInstance;
952     s_pInstance = NULL;
953   }
954 }
AddToolTipTarget(IFWL_ToolTipTarget * pTarget)955 FX_ERR CFWL_ToolTipContainer::AddToolTipTarget(IFWL_ToolTipTarget* pTarget) {
956   if (m_arrWidget.Find((void*)pTarget) < 0) {
957     m_arrWidget.Add((void*)pTarget);
958     return FWL_ERR_Succeeded;
959   }
960   return FWL_ERR_Indefinite;
961 }
RemoveToolTipTarget(IFWL_ToolTipTarget * pTarget)962 FX_ERR CFWL_ToolTipContainer::RemoveToolTipTarget(IFWL_ToolTipTarget* pTarget) {
963   int index = m_arrWidget.Find((void*)pTarget);
964   if (index >= 0) {
965     m_arrWidget.RemoveAt(index);
966     return FWL_ERR_Succeeded;
967   }
968   return FWL_ERR_Indefinite;
969 }
HasToolTip(IFWL_Widget * pWedget)970 FX_BOOL CFWL_ToolTipContainer::HasToolTip(IFWL_Widget* pWedget) {
971   int32_t iCount = m_arrWidget.GetSize();
972   for (int32_t i = 0; i < iCount; i++) {
973     IFWL_ToolTipTarget* p = static_cast<IFWL_ToolTipTarget*>(m_arrWidget[i]);
974     if (p->GetWidget() == pWedget) {
975       pCurTarget = p;
976       return TRUE;
977     }
978   }
979   return FALSE;
980 }
ProcessEnter(CFWL_EvtMouse * pEvt,IFWL_Widget * pOwner)981 FX_BOOL CFWL_ToolTipContainer::ProcessEnter(CFWL_EvtMouse* pEvt,
982                                             IFWL_Widget* pOwner) {
983   if (HasToolTip(pEvt->m_pDstTarget)) {
984     if (NULL == m_pToolTipImp) {
985       CFWL_WidgetImpProperties prop;
986       prop.m_pDataProvider = m_ToolTipDp;
987       prop.m_pOwner = pOwner;
988       CFX_RectF rtTooltip;
989       rtTooltip.Set(150, 150, 100, 50);
990       prop.m_rtWidget = rtTooltip;
991       IFWL_ToolTip* pToolTip = IFWL_ToolTip::Create(prop, nullptr);
992       pToolTip->Initialize();
993       m_pToolTipImp = static_cast<CFWL_ToolTipImp*>(pToolTip->GetImpl());
994       m_pToolTipImp->ModifyStylesEx(FWL_STYLEEXT_TTP_Multiline, 0);
995       m_pToolTipImp->SetStates(FWL_WGTSTATE_Invisible, TRUE);
996     }
997     if (pCurTarget->IsShowed()) {
998       CFX_WideString wsCaption;
999       pCurTarget->GetCaption(wsCaption);
1000       if (!wsCaption.IsEmpty()) {
1001         m_ToolTipDp->m_wsCaption = wsCaption;
1002       }
1003       CFX_RectF rt;
1004       rt.Reset();
1005       CFX_SizeF sz;
1006       sz.Reset();
1007       pCurTarget->GetToolTipSize(sz);
1008       if (sz.x > 0 && sz.y > 0) {
1009         rt.width = sz.x;
1010         rt.height = sz.y;
1011       } else {
1012         CFX_RectF r;
1013         m_pToolTipImp->GetWidgetRect(r, TRUE);
1014         rt.width = r.width;
1015         rt.height = r.height;
1016       }
1017       CFX_PointF pt;
1018       pt.Set(pEvt->m_fx, pEvt->m_fy);
1019       if (pCurTarget->GetToolTipPos(pt) == FWL_ERR_Succeeded) {
1020         rt.left = pt.x;
1021         rt.top = pt.y;
1022         m_pToolTipImp->ModifyStylesEx(FWL_STYLEEXT_TTP_NoAnchor, 0);
1023       } else {
1024         CFX_RectF rtAnchor;
1025         pCurTarget->GetWidget()->GetClientRect(rtAnchor);
1026         pCurTarget->GetWidget()->TransformTo(NULL, rtAnchor.left, rtAnchor.top);
1027         m_pToolTipImp->SetAnchor(rtAnchor);
1028         m_pToolTipImp->ModifyStylesEx(0, FWL_STYLEEXT_TTP_NoAnchor);
1029       }
1030       m_pToolTipImp->SetWidgetRect(rt);
1031       m_pToolTipImp->Update();
1032       m_pToolTipImp->Show();
1033     }
1034     return TRUE;
1035   }
1036   return FALSE;
1037 }
ProcessLeave(CFWL_EvtMouse * pEvt)1038 FX_BOOL CFWL_ToolTipContainer::ProcessLeave(CFWL_EvtMouse* pEvt) {
1039   if (HasToolTip(pEvt->m_pDstTarget) && NULL != m_pToolTipImp) {
1040     m_pToolTipImp->Hide();
1041     pCurTarget = NULL;
1042     return TRUE;
1043   }
1044   return FALSE;
1045 }
GetCurrentToolTipTarget()1046 IFWL_ToolTipTarget* CFWL_ToolTipContainer::GetCurrentToolTipTarget() {
1047   return pCurTarget;
1048 }
SetToolTipInitialDelay(int32_t nDelayTime)1049 FX_ERR CFWL_ToolTipContainer::SetToolTipInitialDelay(int32_t nDelayTime) {
1050   m_ToolTipDp->m_nInitDelayTime = nDelayTime;
1051   return FWL_ERR_Succeeded;
1052 }
SetToolTipAutoPopDelay(int32_t nDelayTime)1053 FX_ERR CFWL_ToolTipContainer::SetToolTipAutoPopDelay(int32_t nDelayTime) {
1054   m_ToolTipDp->m_nAutoPopDelayTime = nDelayTime;
1055   return FWL_ERR_Succeeded;
1056 }
FWL_AddToolTipTarget(IFWL_ToolTipTarget * pTarget)1057 FWL_ERR FWL_AddToolTipTarget(IFWL_ToolTipTarget* pTarget) {
1058   return CFWL_ToolTipContainer::getInstance()->AddToolTipTarget(pTarget);
1059 }
FWL_RemoveToolTipTarget(IFWL_ToolTipTarget * pTarget)1060 FWL_ERR FWL_RemoveToolTipTarget(IFWL_ToolTipTarget* pTarget) {
1061   return CFWL_ToolTipContainer::getInstance()->RemoveToolTipTarget(pTarget);
1062 }
FWL_SetToolTipInitialDelay(int32_t nDelayTime)1063 FWL_ERR FWL_SetToolTipInitialDelay(int32_t nDelayTime) {
1064   return CFWL_ToolTipContainer::getInstance()->SetToolTipInitialDelay(
1065       nDelayTime);
1066 }
FWL_SetToolTipAutoPopDelay(int32_t nDelayTime)1067 FWL_ERR FWL_SetToolTipAutoPopDelay(int32_t nDelayTime) {
1068   return CFWL_ToolTipContainer::getInstance()->SetToolTipAutoPopDelay(
1069       nDelayTime);
1070 }
FWL_GetCurrentThreadModalWidget(IFWL_NoteThread * pNoteThread)1071 IFWL_Widget* FWL_GetCurrentThreadModalWidget(IFWL_NoteThread* pNoteThread) {
1072   if (!pNoteThread)
1073     return NULL;
1074   CFWL_NoteDriver* noteDriver =
1075       static_cast<CFWL_NoteDriver*>(pNoteThread->GetNoteDriver());
1076   if (!noteDriver)
1077     return NULL;
1078   if (noteDriver->CountLoop() == 1) {
1079     return NULL;
1080   }
1081   CFWL_NoteLoop* topLoop = noteDriver->GetTopLoop();
1082   if (!topLoop)
1083     return NULL;
1084   CFWL_WidgetImp* widget = topLoop->GetForm();
1085   if (!widget)
1086     return NULL;
1087   return widget->GetInterface();
1088 }
FWL_SetHook(IFWL_NoteDriver * driver,FWLMessageHookCallback callback,void * info)1089 FWL_ERR FWL_SetHook(IFWL_NoteDriver* driver,
1090                     FWLMessageHookCallback callback,
1091                     void* info) {
1092   CFWL_NoteDriver* noteDriver = static_cast<CFWL_NoteDriver*>(driver);
1093   noteDriver->SetHook(callback, info);
1094   return FWL_ERR_Succeeded;
1095 }
1096