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