Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(94)

Side by Side Diff: xfa/fwl/core/fwl_noteimp.cpp

Issue 2520063002: Split fwl/core class pt II. (Closed)
Patch Set: Rebase to master Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « xfa/fwl/core/fwl_noteimp.h ('k') | xfa/fwl/core/ifwl_adaptertimermgr.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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/fwl/core/fwl_noteimp.h"
8
9 #include <utility>
10
11 #include "core/fxcrt/fx_ext.h"
12 #include "third_party/base/ptr_util.h"
13 #include "third_party/base/stl_util.h"
14 #include "xfa/fwl/core/cfwl_msgkey.h"
15 #include "xfa/fwl/core/cfwl_msgkillfocus.h"
16 #include "xfa/fwl/core/cfwl_msgmouse.h"
17 #include "xfa/fwl/core/cfwl_msgmousewheel.h"
18 #include "xfa/fwl/core/cfwl_msgsetfocus.h"
19 #include "xfa/fwl/core/cfwl_widgetmgr.h"
20 #include "xfa/fwl/core/ifwl_app.h"
21 #include "xfa/fwl/core/ifwl_tooltip.h"
22
23 CFWL_NoteLoop::CFWL_NoteLoop() : m_bContinueModal(true) {}
24
25 CFWL_NoteDriver::CFWL_NoteDriver()
26 : m_pHover(nullptr),
27 m_pFocus(nullptr),
28 m_pGrab(nullptr),
29 m_pNoteLoop(pdfium::MakeUnique<CFWL_NoteLoop>()) {
30 PushNoteLoop(m_pNoteLoop.get());
31 }
32
33 CFWL_NoteDriver::~CFWL_NoteDriver() {
34 ClearEventTargets(true);
35 }
36
37 void CFWL_NoteDriver::SendEvent(CFWL_Event* pNote) {
38 if (m_eventTargets.empty())
39 return;
40
41 for (const auto& pair : m_eventTargets) {
42 CFWL_EventTarget* pEventTarget = pair.second;
43 if (pEventTarget && !pEventTarget->IsInvalid())
44 pEventTarget->ProcessEvent(pNote);
45 }
46 }
47
48 void CFWL_NoteDriver::RegisterEventTarget(IFWL_Widget* pListener,
49 IFWL_Widget* pEventSource,
50 uint32_t dwFilter) {
51 uint32_t key = pListener->GetEventKey();
52 if (key == 0) {
53 do {
54 key = rand();
55 } while (key == 0 || pdfium::ContainsKey(m_eventTargets, key));
56 pListener->SetEventKey(key);
57 }
58 if (!m_eventTargets[key])
59 m_eventTargets[key] = new CFWL_EventTarget(pListener);
60
61 m_eventTargets[key]->SetEventSource(pEventSource, dwFilter);
62 }
63
64 void CFWL_NoteDriver::UnregisterEventTarget(IFWL_Widget* pListener) {
65 uint32_t key = pListener->GetEventKey();
66 if (key == 0)
67 return;
68
69 auto it = m_eventTargets.find(key);
70 if (it != m_eventTargets.end())
71 it->second->FlagInvalid();
72 }
73
74 void CFWL_NoteDriver::PushNoteLoop(CFWL_NoteLoop* pNoteLoop) {
75 m_noteLoopQueue.Add(pNoteLoop);
76 }
77
78 CFWL_NoteLoop* CFWL_NoteDriver::PopNoteLoop() {
79 int32_t pos = m_noteLoopQueue.GetSize();
80 if (pos <= 0)
81 return nullptr;
82
83 CFWL_NoteLoop* p = m_noteLoopQueue.GetAt(pos - 1);
84 m_noteLoopQueue.RemoveAt(pos - 1);
85 return p;
86 }
87
88 bool CFWL_NoteDriver::SetFocus(IFWL_Widget* pFocus, bool bNotify) {
89 if (m_pFocus == pFocus)
90 return true;
91
92 IFWL_Widget* pPrev = m_pFocus;
93 m_pFocus = pFocus;
94 if (pPrev) {
95 CFWL_MsgKillFocus ms;
96 ms.m_pDstTarget = pPrev;
97 ms.m_pSrcTarget = pPrev;
98 if (bNotify)
99 ms.m_dwExtend = 1;
100
101 if (IFWL_WidgetDelegate* pDelegate = pPrev->GetDelegate())
102 pDelegate->OnProcessMessage(&ms);
103 }
104 if (pFocus) {
105 IFWL_Widget* pWidget =
106 pFocus->GetOwnerApp()->GetWidgetMgr()->GetSystemFormWidget(pFocus);
107 IFWL_Form* pForm = static_cast<IFWL_Form*>(pWidget);
108 if (pForm)
109 pForm->SetSubFocus(pFocus);
110
111 CFWL_MsgSetFocus ms;
112 ms.m_pDstTarget = pFocus;
113 if (bNotify)
114 ms.m_dwExtend = 1;
115 if (IFWL_WidgetDelegate* pDelegate = pFocus->GetDelegate())
116 pDelegate->OnProcessMessage(&ms);
117 }
118 return true;
119 }
120
121 void CFWL_NoteDriver::Run() {
122 #if (_FX_OS_ == _FX_LINUX_DESKTOP_ || _FX_OS_ == _FX_WIN32_DESKTOP_ || \
123 _FX_OS_ == _FX_WIN64_)
124 for (;;) {
125 CFWL_NoteLoop* pTopLoop = GetTopLoop();
126 if (!pTopLoop || !pTopLoop->ContinueModal())
127 break;
128 UnqueueMessage(pTopLoop);
129 }
130 #endif
131 }
132
133 void CFWL_NoteDriver::NotifyTargetHide(IFWL_Widget* pNoteTarget) {
134 if (m_pFocus == pNoteTarget)
135 m_pFocus = nullptr;
136 if (m_pHover == pNoteTarget)
137 m_pHover = nullptr;
138 if (m_pGrab == pNoteTarget)
139 m_pGrab = nullptr;
140 }
141
142 void CFWL_NoteDriver::NotifyTargetDestroy(IFWL_Widget* pNoteTarget) {
143 if (m_pFocus == pNoteTarget)
144 m_pFocus = nullptr;
145 if (m_pHover == pNoteTarget)
146 m_pHover = nullptr;
147 if (m_pGrab == pNoteTarget)
148 m_pGrab = nullptr;
149
150 UnregisterEventTarget(pNoteTarget);
151
152 for (int32_t nIndex = 0; nIndex < m_forms.GetSize(); nIndex++) {
153 IFWL_Form* pForm = static_cast<IFWL_Form*>(m_forms[nIndex]);
154 if (!pForm)
155 continue;
156
157 IFWL_Widget* pSubFocus = pForm->GetSubFocus();
158 if (!pSubFocus)
159 return;
160 if (pSubFocus == pNoteTarget)
161 pForm->SetSubFocus(nullptr);
162 }
163 }
164
165 void CFWL_NoteDriver::RegisterForm(IFWL_Widget* pForm) {
166 if (!pForm || m_forms.Find(pForm) >= 0)
167 return;
168
169 m_forms.Add(pForm);
170 if (m_forms.GetSize() != 1)
171 return;
172
173 CFWL_NoteLoop* pLoop = m_noteLoopQueue.GetAt(0);
174 if (!pLoop)
175 return;
176
177 pLoop->SetMainForm(pForm);
178 }
179
180 void CFWL_NoteDriver::UnRegisterForm(IFWL_Widget* pForm) {
181 if (!pForm)
182 return;
183
184 int32_t nIndex = m_forms.Find(pForm);
185 if (nIndex < 0)
186 return;
187
188 m_forms.RemoveAt(nIndex);
189 }
190
191 void CFWL_NoteDriver::QueueMessage(std::unique_ptr<CFWL_Message> pMessage) {
192 m_noteQueue.push_back(std::move(pMessage));
193 }
194
195 void CFWL_NoteDriver::UnqueueMessage(CFWL_NoteLoop* pNoteLoop) {
196 if (m_noteQueue.empty())
197 return;
198
199 std::unique_ptr<CFWL_Message> pMessage = std::move(m_noteQueue[0]);
200 m_noteQueue.pop_front();
201
202 if (!IsValidMessage(pMessage.get()))
203 return;
204
205 ProcessMessage(pMessage.get());
206 }
207
208 CFWL_NoteLoop* CFWL_NoteDriver::GetTopLoop() const {
209 int32_t size = m_noteLoopQueue.GetSize();
210 if (size <= 0)
211 return nullptr;
212 return m_noteLoopQueue[size - 1];
213 }
214
215 void CFWL_NoteDriver::ProcessMessage(CFWL_Message* pMessage) {
216 CFWL_WidgetMgr* pWidgetMgr =
217 pMessage->m_pDstTarget->GetOwnerApp()->GetWidgetMgr();
218 IFWL_Widget* pMessageForm = pWidgetMgr->IsFormDisabled()
219 ? pMessage->m_pDstTarget
220 : GetMessageForm(pMessage->m_pDstTarget);
221 if (!pMessageForm)
222 return;
223 if (!DispatchMessage(pMessage, pMessageForm))
224 return;
225
226 if (pMessage->GetClassID() == CFWL_MessageType::Mouse)
227 MouseSecondary(pMessage);
228 }
229
230 bool CFWL_NoteDriver::DispatchMessage(CFWL_Message* pMessage,
231 IFWL_Widget* pMessageForm) {
232 switch (pMessage->GetClassID()) {
233 case CFWL_MessageType::SetFocus: {
234 if (!DoSetFocus(pMessage, pMessageForm))
235 return false;
236 break;
237 }
238 case CFWL_MessageType::KillFocus: {
239 if (!DoKillFocus(pMessage, pMessageForm))
240 return false;
241 break;
242 }
243 case CFWL_MessageType::Key: {
244 if (!DoKey(pMessage, pMessageForm))
245 return false;
246 break;
247 }
248 case CFWL_MessageType::Mouse: {
249 if (!DoMouse(pMessage, pMessageForm))
250 return false;
251 break;
252 }
253 case CFWL_MessageType::MouseWheel: {
254 if (!DoWheel(pMessage, pMessageForm))
255 return false;
256 break;
257 }
258 default:
259 break;
260 }
261 if (IFWL_WidgetDelegate* pDelegate = pMessage->m_pDstTarget->GetDelegate())
262 pDelegate->OnProcessMessage(pMessage);
263
264 return true;
265 }
266
267 bool CFWL_NoteDriver::DoSetFocus(CFWL_Message* pMessage,
268 IFWL_Widget* pMessageForm) {
269 CFWL_WidgetMgr* pWidgetMgr = pMessageForm->GetOwnerApp()->GetWidgetMgr();
270 if (pWidgetMgr->IsFormDisabled()) {
271 m_pFocus = pMessage->m_pDstTarget;
272 return true;
273 }
274
275 IFWL_Widget* pWidget = pMessage->m_pDstTarget;
276 if (!pWidget)
277 return false;
278
279 IFWL_Form* pForm = static_cast<IFWL_Form*>(pWidget);
280 IFWL_Widget* pSubFocus = pForm->GetSubFocus();
281 if (pSubFocus && ((pSubFocus->GetStates() & FWL_WGTSTATE_Focused) == 0)) {
282 pMessage->m_pDstTarget = pSubFocus;
283 if (m_pFocus != pMessage->m_pDstTarget) {
284 m_pFocus = pMessage->m_pDstTarget;
285 return true;
286 }
287 }
288 return false;
289 }
290
291 bool CFWL_NoteDriver::DoKillFocus(CFWL_Message* pMessage,
292 IFWL_Widget* pMessageForm) {
293 CFWL_WidgetMgr* pWidgetMgr = pMessageForm->GetOwnerApp()->GetWidgetMgr();
294 if (pWidgetMgr->IsFormDisabled()) {
295 if (m_pFocus == pMessage->m_pDstTarget)
296 m_pFocus = nullptr;
297 return true;
298 }
299
300 IFWL_Form* pForm = static_cast<IFWL_Form*>(pMessage->m_pDstTarget);
301 if (!pForm)
302 return false;
303
304 IFWL_Widget* pSubFocus = pForm->GetSubFocus();
305 if (pSubFocus && (pSubFocus->GetStates() & FWL_WGTSTATE_Focused)) {
306 pMessage->m_pDstTarget = pSubFocus;
307 if (m_pFocus == pMessage->m_pDstTarget) {
308 m_pFocus = nullptr;
309 return true;
310 }
311 }
312 return false;
313 }
314
315 bool CFWL_NoteDriver::DoKey(CFWL_Message* pMessage, IFWL_Widget* pMessageForm) {
316 CFWL_MsgKey* pMsg = static_cast<CFWL_MsgKey*>(pMessage);
317 #if (_FX_OS_ != _FX_MACOSX_)
318 if (pMsg->m_dwCmd == FWL_KeyCommand::KeyDown &&
319 pMsg->m_dwKeyCode == FWL_VKEY_Tab) {
320 CFWL_WidgetMgr* pWidgetMgr = pMessageForm->GetOwnerApp()->GetWidgetMgr();
321 IFWL_Widget* pForm = GetMessageForm(pMsg->m_pDstTarget);
322 IFWL_Widget* pFocus = m_pFocus;
323 if (m_pFocus && pWidgetMgr->GetSystemFormWidget(m_pFocus) != pForm)
324 pFocus = nullptr;
325
326 bool bFind = false;
327 IFWL_Widget* pNextTabStop = pWidgetMgr->NextTab(pForm, pFocus, bFind);
328 if (!pNextTabStop) {
329 bFind = false;
330 pNextTabStop = pWidgetMgr->NextTab(pForm, nullptr, bFind);
331 }
332 if (pNextTabStop == pFocus)
333 return true;
334 if (pNextTabStop)
335 SetFocus(pNextTabStop);
336 return true;
337 }
338 #endif
339
340 if (!m_pFocus) {
341 if (pMsg->m_dwCmd == FWL_KeyCommand::KeyDown &&
342 pMsg->m_dwKeyCode == FWL_VKEY_Return) {
343 CFWL_WidgetMgr* pWidgetMgr = pMessageForm->GetOwnerApp()->GetWidgetMgr();
344 IFWL_Widget* defButton = pWidgetMgr->GetDefaultButton(pMessageForm);
345 if (defButton) {
346 pMsg->m_pDstTarget = defButton;
347 return true;
348 }
349 }
350 return false;
351 }
352 pMsg->m_pDstTarget = m_pFocus;
353 return true;
354 }
355
356 bool CFWL_NoteDriver::DoMouse(CFWL_Message* pMessage,
357 IFWL_Widget* pMessageForm) {
358 CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage);
359 if (pMsg->m_dwCmd == FWL_MouseCommand::Leave ||
360 pMsg->m_dwCmd == FWL_MouseCommand::Hover ||
361 pMsg->m_dwCmd == FWL_MouseCommand::Enter) {
362 return !!pMsg->m_pDstTarget;
363 }
364 if (pMsg->m_pDstTarget != pMessageForm)
365 pMsg->m_pDstTarget->TransformTo(pMessageForm, pMsg->m_fx, pMsg->m_fy);
366 if (!DoMouseEx(pMsg, pMessageForm))
367 pMsg->m_pDstTarget = pMessageForm;
368 return true;
369 }
370
371 bool CFWL_NoteDriver::DoWheel(CFWL_Message* pMessage,
372 IFWL_Widget* pMessageForm) {
373 CFWL_WidgetMgr* pWidgetMgr = pMessageForm->GetOwnerApp()->GetWidgetMgr();
374 if (!pWidgetMgr)
375 return false;
376
377 CFWL_MsgMouseWheel* pMsg = static_cast<CFWL_MsgMouseWheel*>(pMessage);
378 IFWL_Widget* pDst =
379 pWidgetMgr->GetWidgetAtPoint(pMessageForm, pMsg->m_fx, pMsg->m_fy);
380 if (!pDst)
381 return false;
382
383 pMessageForm->TransformTo(pDst, pMsg->m_fx, pMsg->m_fy);
384 pMsg->m_pDstTarget = pDst;
385 return true;
386 }
387
388 bool CFWL_NoteDriver::DoMouseEx(CFWL_Message* pMessage,
389 IFWL_Widget* pMessageForm) {
390 CFWL_WidgetMgr* pWidgetMgr = pMessageForm->GetOwnerApp()->GetWidgetMgr();
391 if (!pWidgetMgr)
392 return false;
393 IFWL_Widget* pTarget = nullptr;
394 if (m_pGrab)
395 pTarget = m_pGrab;
396
397 CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage);
398 if (!pTarget) {
399 pTarget =
400 pWidgetMgr->GetWidgetAtPoint(pMessageForm, pMsg->m_fx, pMsg->m_fy);
401 }
402 if (pTarget) {
403 if (pMessageForm != pTarget)
404 pMessageForm->TransformTo(pTarget, pMsg->m_fx, pMsg->m_fy);
405 }
406 if (!pTarget)
407 return false;
408
409 pMsg->m_pDstTarget = pTarget;
410 return true;
411 }
412
413 void CFWL_NoteDriver::MouseSecondary(CFWL_Message* pMessage) {
414 IFWL_Widget* pTarget = pMessage->m_pDstTarget;
415 if (pTarget == m_pHover)
416 return;
417
418 CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage);
419 if (m_pHover) {
420 CFWL_MsgMouse msLeave;
421 msLeave.m_pDstTarget = m_pHover;
422 msLeave.m_fx = pMsg->m_fx;
423 msLeave.m_fy = pMsg->m_fy;
424 pTarget->TransformTo(m_pHover, msLeave.m_fx, msLeave.m_fy);
425
426 msLeave.m_dwFlags = 0;
427 msLeave.m_dwCmd = FWL_MouseCommand::Leave;
428 DispatchMessage(&msLeave, nullptr);
429 }
430 if (pTarget->GetClassID() == FWL_Type::Form) {
431 m_pHover = nullptr;
432 return;
433 }
434 m_pHover = pTarget;
435
436 CFWL_MsgMouse msHover;
437 msHover.m_pDstTarget = pTarget;
438 msHover.m_fx = pMsg->m_fx;
439 msHover.m_fy = pMsg->m_fy;
440 msHover.m_dwFlags = 0;
441 msHover.m_dwCmd = FWL_MouseCommand::Hover;
442 DispatchMessage(&msHover, nullptr);
443 }
444
445 bool CFWL_NoteDriver::IsValidMessage(CFWL_Message* pMessage) {
446 for (int32_t i = 0; i < m_noteLoopQueue.GetSize(); i++) {
447 CFWL_NoteLoop* pNoteLoop = m_noteLoopQueue[i];
448 IFWL_Widget* pForm = pNoteLoop->GetForm();
449 if (pForm && (pForm == pMessage->m_pDstTarget))
450 return true;
451 }
452
453 for (int32_t j = 0; j < m_forms.GetSize(); j++) {
454 IFWL_Form* pForm = static_cast<IFWL_Form*>(m_forms[j]);
455 if (pForm == pMessage->m_pDstTarget)
456 return true;
457 }
458 return false;
459 }
460
461 IFWL_Widget* CFWL_NoteDriver::GetMessageForm(IFWL_Widget* pDstTarget) {
462 int32_t iTrackLoop = m_noteLoopQueue.GetSize();
463 if (iTrackLoop <= 0)
464 return nullptr;
465
466 IFWL_Widget* pMessageForm = nullptr;
467 if (iTrackLoop > 1)
468 pMessageForm = m_noteLoopQueue[iTrackLoop - 1]->GetForm();
469 else if (m_forms.Find(pDstTarget) < 0)
470 pMessageForm = pDstTarget;
471 if (!pMessageForm && pDstTarget) {
472 CFWL_WidgetMgr* pWidgetMgr = pDstTarget->GetOwnerApp()->GetWidgetMgr();
473 if (!pWidgetMgr)
474 return nullptr;
475 pMessageForm = pWidgetMgr->GetSystemFormWidget(pDstTarget);
476 }
477 return pMessageForm;
478 }
479
480 void CFWL_NoteDriver::ClearEventTargets(bool bRemoveAll) {
481 auto it = m_eventTargets.begin();
482 while (it != m_eventTargets.end()) {
483 auto old = it++;
484 if (old->second && (bRemoveAll || old->second->IsInvalid())) {
485 delete old->second;
486 m_eventTargets.erase(old);
487 }
488 }
489 }
490
491 CFWL_EventTarget::CFWL_EventTarget(IFWL_Widget* pListener)
492 : m_pListener(pListener), m_bInvalid(false) {}
493
494 CFWL_EventTarget::~CFWL_EventTarget() {
495 m_eventSources.RemoveAll();
496 }
497
498 int32_t CFWL_EventTarget::SetEventSource(IFWL_Widget* pSource,
499 uint32_t dwFilter) {
500 if (pSource) {
501 m_eventSources.SetAt(pSource, dwFilter);
502 return m_eventSources.GetCount();
503 }
504 return 1;
505 }
506
507 bool CFWL_EventTarget::ProcessEvent(CFWL_Event* pEvent) {
508 IFWL_WidgetDelegate* pDelegate = m_pListener->GetDelegate();
509 if (!pDelegate)
510 return false;
511 if (m_eventSources.GetCount() == 0) {
512 pDelegate->OnProcessEvent(pEvent);
513 return true;
514 }
515
516 FX_POSITION pos = m_eventSources.GetStartPosition();
517 while (pos) {
518 IFWL_Widget* pSource = nullptr;
519 uint32_t dwFilter = 0;
520 m_eventSources.GetNextAssoc(pos, (void*&)pSource, dwFilter);
521 if (pSource == pEvent->m_pSrcTarget) {
522 if (IsFilterEvent(pEvent, dwFilter)) {
523 pDelegate->OnProcessEvent(pEvent);
524 return true;
525 }
526 }
527 }
528 return false;
529 }
530
531 bool CFWL_EventTarget::IsFilterEvent(CFWL_Event* pEvent,
532 uint32_t dwFilter) const {
533 if (dwFilter == FWL_EVENT_ALL_MASK)
534 return true;
535
536 switch (pEvent->GetClassID()) {
537 case CFWL_EventType::Mouse:
538 return !!(dwFilter & FWL_EVENT_MOUSE_MASK);
539 case CFWL_EventType::MouseWheel:
540 return !!(dwFilter & FWL_EVENT_MOUSEWHEEL_MASK);
541 case CFWL_EventType::Key:
542 return !!(dwFilter & FWL_EVENT_KEY_MASK);
543 case CFWL_EventType::SetFocus:
544 case CFWL_EventType::KillFocus:
545 return !!(dwFilter & FWL_EVENT_FOCUSCHANGED_MASK);
546 case CFWL_EventType::Close:
547 return !!(dwFilter & FWL_EVENT_CLOSE_MASK);
548 case CFWL_EventType::SizeChanged:
549 return !!(dwFilter & FWL_EVENT_SIZECHANGED_MASK);
550 default:
551 return !!(dwFilter & FWL_EVENT_CONTROL_MASK);
552 }
553 }
OLDNEW
« no previous file with comments | « xfa/fwl/core/fwl_noteimp.h ('k') | xfa/fwl/core/ifwl_adaptertimermgr.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698