Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
cfwl_notedriver.cpp
Go to the documentation of this file.
1// Copyright 2014 The PDFium Authors
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/cfwl_notedriver.h"
8
9#include <algorithm>
10#include <utility>
11
12#include "build/build_config.h"
13#include "core/fxcrt/fx_extension.h"
14#include "fxjs/gc/container_trace.h"
15#include "xfa/fwl/cfwl_app.h"
16#include "xfa/fwl/cfwl_event.h"
17#include "xfa/fwl/cfwl_messagekey.h"
18#include "xfa/fwl/cfwl_messagekillfocus.h"
19#include "xfa/fwl/cfwl_messagemouse.h"
20#include "xfa/fwl/cfwl_messagemousewheel.h"
21#include "xfa/fwl/cfwl_messagesetfocus.h"
22#include "xfa/fwl/cfwl_widgetmgr.h"
23#include "xfa/fwl/fwl_widgetdef.h"
24
25namespace {
26
27uint64_t g_next_listener_key = 1;
28
29} // namespace
30
31CFWL_NoteDriver::CFWL_NoteDriver(CFWL_App* pApp) : m_pApp(pApp) {}
32
33CFWL_NoteDriver::~CFWL_NoteDriver() = default;
34
35void CFWL_NoteDriver::Trace(cppgc::Visitor* visitor) const {
36 visitor->Trace(m_pApp);
37 visitor->Trace(m_pHover);
38 visitor->Trace(m_pFocus);
39 visitor->Trace(m_pGrab);
40 ContainerTrace(visitor, m_eventTargets);
41}
42
43void CFWL_NoteDriver::SendEvent(CFWL_Event* pNote) {
44 for (const auto& pair : m_eventTargets) {
45 if (pair.second->IsValid())
46 pair.second->ProcessEvent(pNote);
47 }
48}
49
50void CFWL_NoteDriver::RegisterEventTarget(CFWL_Widget* pListener,
51 CFWL_Widget* pEventSource) {
52 uint64_t key = pListener->GetEventKey();
53 if (key == 0) {
54 key = g_next_listener_key++;
55 pListener->SetEventKey(key);
56 }
57 if (!m_eventTargets[key]) {
58 m_eventTargets[key] = cppgc::MakeGarbageCollected<Target>(
59 m_pApp->GetHeap()->GetAllocationHandle(), pListener);
60 }
61 m_eventTargets[key]->SetEventSource(pEventSource);
62}
63
64void CFWL_NoteDriver::UnregisterEventTarget(CFWL_Widget* pListener) {
65 uint64_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->Invalidate();
72}
73
74void CFWL_NoteDriver::NotifyTargetHide(CFWL_Widget* pNoteTarget) {
75 if (m_pFocus == pNoteTarget)
76 m_pFocus = nullptr;
77 if (m_pHover == pNoteTarget)
78 m_pHover = nullptr;
79 if (m_pGrab == pNoteTarget)
80 m_pGrab = nullptr;
81}
82
83void CFWL_NoteDriver::NotifyTargetDestroy(CFWL_Widget* pNoteTarget) {
84 if (m_pFocus == pNoteTarget)
85 m_pFocus = nullptr;
86 if (m_pHover == pNoteTarget)
87 m_pHover = nullptr;
88 if (m_pGrab == pNoteTarget)
89 m_pGrab = nullptr;
90
91 UnregisterEventTarget(pNoteTarget);
92}
93
94void CFWL_NoteDriver::ProcessMessage(CFWL_Message* pMessage) {
95 CFWL_Widget* pMessageForm = pMessage->GetDstTarget();
96 if (!pMessageForm)
97 return;
98
99 if (!DispatchMessage(pMessage, pMessageForm))
100 return;
101
103 MouseSecondary(pMessage);
104}
105
106bool CFWL_NoteDriver::DispatchMessage(CFWL_Message* pMessage,
107 CFWL_Widget* pMessageForm) {
108 switch (pMessage->GetType()) {
110 if (!DoSetFocus(pMessage, pMessageForm))
111 return false;
112 break;
113 }
115 if (!DoKillFocus(pMessage, pMessageForm))
116 return false;
117 break;
118 }
120 if (!DoKey(pMessage, pMessageForm))
121 return false;
122 break;
123 }
125 if (!DoMouse(pMessage, pMessageForm))
126 return false;
127 break;
128 }
130 if (!DoWheel(pMessage, pMessageForm))
131 return false;
132 break;
133 }
134 }
136 if (pDelegate)
137 pDelegate->OnProcessMessage(pMessage);
138
139 return true;
140}
141
142bool CFWL_NoteDriver::DoSetFocus(CFWL_Message* pMessage,
143 CFWL_Widget* pMessageForm) {
144 m_pFocus = pMessage->GetDstTarget();
145 return true;
146}
147
148bool CFWL_NoteDriver::DoKillFocus(CFWL_Message* pMessage,
149 CFWL_Widget* pMessageForm) {
150 if (m_pFocus == pMessage->GetDstTarget())
151 m_pFocus = nullptr;
152 return true;
153}
154
155bool CFWL_NoteDriver::DoKey(CFWL_Message* pMessage, CFWL_Widget* pMessageForm) {
156 CFWL_MessageKey* pMsg = static_cast<CFWL_MessageKey*>(pMessage);
157#if !BUILDFLAG(IS_APPLE)
158 if (pMsg->m_dwCmd == CFWL_MessageKey::KeyCommand::kKeyDown &&
159 pMsg->m_dwKeyCodeOrChar == XFA_FWL_VKEY_Tab) {
160 return true;
161 }
162#endif
163
164 if (m_pFocus) {
165 pMsg->SetDstTarget(m_pFocus.Get());
166 return true;
167 }
168
169 if (pMsg->m_dwCmd == CFWL_MessageKey::KeyCommand::kKeyDown &&
171 CFWL_WidgetMgr* pWidgetMgr = pMessageForm->GetFWLApp()->GetWidgetMgr();
172 CFWL_Widget* pDefButton = pWidgetMgr->GetDefaultButton(pMessageForm);
173 if (pDefButton) {
174 pMsg->SetDstTarget(pDefButton);
175 return true;
176 }
177 }
178 return false;
179}
180
181bool CFWL_NoteDriver::DoMouse(CFWL_Message* pMessage,
182 CFWL_Widget* pMessageForm) {
183 CFWL_MessageMouse* pMsg = static_cast<CFWL_MessageMouse*>(pMessage);
184 if (pMsg->m_dwCmd == CFWL_MessageMouse::MouseCommand::kLeave ||
185 pMsg->m_dwCmd == CFWL_MessageMouse::MouseCommand::kHover ||
186 pMsg->m_dwCmd == CFWL_MessageMouse::MouseCommand::kEnter) {
187 return !!pMsg->GetDstTarget();
188 }
189 if (pMsg->GetDstTarget() != pMessageForm)
190 pMsg->m_pos = pMsg->GetDstTarget()->TransformTo(pMessageForm, pMsg->m_pos);
191 if (!DoMouseEx(pMsg, pMessageForm))
192 pMsg->SetDstTarget(pMessageForm);
193 return true;
194}
195
196bool CFWL_NoteDriver::DoWheel(CFWL_Message* pMessage,
197 CFWL_Widget* pMessageForm) {
198 CFWL_WidgetMgr* pWidgetMgr = pMessageForm->GetFWLApp()->GetWidgetMgr();
199 CFWL_MessageMouseWheel* pMsg = static_cast<CFWL_MessageMouseWheel*>(pMessage);
200 CFWL_Widget* pDst = pWidgetMgr->GetWidgetAtPoint(pMessageForm, pMsg->pos());
201 if (!pDst)
202 return false;
203
204 pMsg->set_pos(pMessageForm->TransformTo(pDst, pMsg->pos()));
205 pMsg->SetDstTarget(pDst);
206 return true;
207}
208
209bool CFWL_NoteDriver::DoMouseEx(CFWL_Message* pMessage,
210 CFWL_Widget* pMessageForm) {
211 CFWL_WidgetMgr* pWidgetMgr = pMessageForm->GetFWLApp()->GetWidgetMgr();
212 CFWL_Widget* pTarget = nullptr;
213 if (m_pGrab)
214 pTarget = m_pGrab.Get();
215
216 CFWL_MessageMouse* pMsg = static_cast<CFWL_MessageMouse*>(pMessage);
217 if (!pTarget)
218 pTarget = pWidgetMgr->GetWidgetAtPoint(pMessageForm, pMsg->m_pos);
219 if (!pTarget)
220 return false;
221 if (pTarget && pMessageForm != pTarget)
222 pMsg->m_pos = pMessageForm->TransformTo(pTarget, pMsg->m_pos);
223
224 pMsg->SetDstTarget(pTarget);
225 return true;
226}
227
228void CFWL_NoteDriver::MouseSecondary(CFWL_Message* pMessage) {
229 CFWL_Widget* pTarget = pMessage->GetDstTarget();
230 if (pTarget == m_pHover)
231 return;
232
233 CFWL_MessageMouse* pMsg = static_cast<CFWL_MessageMouse*>(pMessage);
234 if (m_pHover) {
235 CFWL_MessageMouse msLeave(
236 m_pHover.Get(), CFWL_MessageMouse::MouseCommand::kLeave,
237 Mask<XFA_FWL_KeyFlag>(),
238 pTarget->TransformTo(m_pHover.Get(), pMsg->m_pos));
239 DispatchMessage(&msLeave, nullptr);
240 }
241 if (pTarget->GetClassID() == FWL_Type::Form) {
242 m_pHover = nullptr;
243 return;
244 }
245 m_pHover = pTarget;
246
247 CFWL_MessageMouse msHover(pTarget, CFWL_MessageMouse::MouseCommand::kHover,
248 Mask<XFA_FWL_KeyFlag>(), pMsg->m_pos);
249 DispatchMessage(&msHover, nullptr);
250}
251
252CFWL_NoteDriver::Target::Target(CFWL_Widget* pListener)
253 : m_pListener(pListener) {}
254
255CFWL_NoteDriver::Target::~Target() = default;
256
257void CFWL_NoteDriver::Target::Trace(cppgc::Visitor* visitor) const {
258 visitor->Trace(m_pListener);
259 for (auto& widget : m_widgets)
260 visitor->Trace(widget);
261}
262
263void CFWL_NoteDriver::Target::SetEventSource(CFWL_Widget* pSource) {
264 if (pSource)
265 m_widgets.insert(pSource);
266}
267
268bool CFWL_NoteDriver::Target::ProcessEvent(CFWL_Event* pEvent) {
269 IFWL_WidgetDelegate* pDelegate = m_pListener->GetDelegate();
270 if (!pDelegate)
271 return false;
272 if (!m_widgets.empty() && m_widgets.count(pEvent->GetSrcTarget()) == 0)
273 return false;
274 pDelegate->OnProcessEvent(pEvent);
275 return true;
276}
FWL_Type
Definition cfwl_widget.h:46
CFWL_WidgetMgr * GetWidgetMgr() const
Definition cfwl_app.h:46
const KeyCommand m_dwCmd
const uint32_t m_dwKeyCodeOrChar
const CFX_PointF & pos() const
void set_pos(const CFX_PointF &pos)
const MouseCommand m_dwCmd
Type GetType() const
CFWL_Widget * GetDstTarget() const
void SetDstTarget(CFWL_Widget *pWidget)
void NotifyTargetHide(CFWL_Widget *pNoteTarget)
void SendEvent(CFWL_Event *pNote)
void ProcessMessage(CFWL_Message *pMessage)
void UnregisterEventTarget(CFWL_Widget *pListener)
void NotifyTargetDestroy(CFWL_Widget *pNoteTarget)
void Trace(cppgc::Visitor *visitor) const
void RegisterEventTarget(CFWL_Widget *pListener, CFWL_Widget *pEventSource)
CFWL_Widget * GetWidgetAtPoint(CFWL_Widget *pParent, const CFX_PointF &point) const
CFWL_Widget * GetDefaultButton(CFWL_Widget *pParent) const
CFX_PointF TransformTo(CFWL_Widget *pWidget, const CFX_PointF &point)
void SetEventKey(uint64_t key)
virtual FWL_Type GetClassID() const =0
uint64_t GetEventKey() const
CFWL_App * GetFWLApp() const
IFWL_WidgetDelegate * GetDelegate()
virtual void OnProcessEvent(CFWL_Event *pEvent)=0
virtual void OnProcessMessage(CFWL_Message *pMessage)=0
@ XFA_FWL_VKEY_Return