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