1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "core/components_ng/event/event_hub.h"
17
18 #include "base/utils/utils.h"
19 #include "core/components_ng/base/frame_node.h"
20 #include "core/pipeline_ng/pipeline_context.h"
21
22 namespace OHOS::Ace::NG {
23
AttachHost(const WeakPtr<FrameNode> & host)24 void EventHub::AttachHost(const WeakPtr<FrameNode>& host)
25 {
26 host_ = host;
27 }
28
OnAttachContext(PipelineContext * context)29 void EventHub::OnAttachContext(PipelineContext *context)
30 {
31 auto host = host_.Upgrade();
32 CHECK_NULL_VOID(host);
33 if (HasOnAreaChanged() || HasInnerOnAreaChanged()) {
34 context->AddOnAreaChangeNode(host->GetId());
35 }
36
37 if (HasVisibleAreaCallback(true) || HasVisibleAreaCallback(false)) {
38 context->AddVisibleAreaChangeNode(host->GetId());
39 }
40 }
41
OnDetachContext(PipelineContext * context)42 void EventHub::OnDetachContext(PipelineContext *context)
43 {
44 auto host = host_.Upgrade();
45 CHECK_NULL_VOID(host);
46 if (HasOnAreaChanged() || HasInnerOnAreaChanged()) {
47 context->RemoveOnAreaChangeNode(host->GetId());
48 }
49
50 if (HasVisibleAreaCallback(true) || HasVisibleAreaCallback(false)) {
51 host->TriggerVisibleAreaChangeCallback(0, true);
52 context->RemoveVisibleAreaChangeNode(host->GetId());
53 }
54 }
55
GetFrameNode() const56 RefPtr<FrameNode> EventHub::GetFrameNode() const
57 {
58 return host_.Upgrade();
59 }
60
AddSupportedState(UIState state)61 void EventHub::AddSupportedState(UIState state)
62 {
63 if (!stateStyleMgr_) {
64 stateStyleMgr_ = MakeRefPtr<StateStyleManager>(host_);
65 }
66 stateStyleMgr_->AddSupportedState(state);
67 }
68
SetSupportedStates(UIState state)69 void EventHub::SetSupportedStates(UIState state)
70 {
71 if (!stateStyleMgr_) {
72 stateStyleMgr_ = MakeRefPtr<StateStyleManager>(host_);
73 }
74 stateStyleMgr_->SetSupportedStates(state);
75 }
76
SetCurrentUIState(UIState state,bool flag)77 void EventHub::SetCurrentUIState(UIState state, bool flag)
78 {
79 if (!stateStyleMgr_) {
80 stateStyleMgr_ = MakeRefPtr<StateStyleManager>(host_);
81 }
82 stateStyleMgr_->SetCurrentUIState(state, flag);
83 }
84
IsCurrentStateOn(UIState state)85 bool EventHub::IsCurrentStateOn(UIState state)
86 {
87 if (!stateStyleMgr_) {
88 return false;
89 }
90 return stateStyleMgr_->IsCurrentStateOn(state);
91 }
92
CreateGetEventTargetImpl() const93 GetEventTargetImpl EventHub::CreateGetEventTargetImpl() const
94 {
95 auto impl = [weak = host_]() -> std::optional<EventTarget> {
96 auto host = weak.Upgrade();
97 CHECK_NULL_RETURN(host, std::nullopt);
98 EventTarget eventTarget;
99 eventTarget.id = std::to_string(host->GetId());
100 eventTarget.type = host->GetTag();
101 auto geometryNode = host->GetGeometryNode();
102 auto offset = geometryNode->GetFrameOffset();
103 auto size = geometryNode->GetFrameSize();
104 eventTarget.area.SetOffset(DimensionOffset(offset));
105 eventTarget.area.SetHeight(Dimension(size.Height()));
106 eventTarget.area.SetWidth(Dimension(size.Width()));
107 eventTarget.origin = DimensionOffset(host->GetOffsetRelativeToWindow() - offset);
108 return eventTarget;
109 };
110 return impl;
111 }
112
PostEnabledTask()113 void EventHub::PostEnabledTask()
114 {
115 auto pipeline = PipelineBase::GetCurrentContext();
116 CHECK_NULL_VOID(pipeline);
117 auto taskExecutor = pipeline->GetTaskExecutor();
118 CHECK_NULL_VOID(taskExecutor);
119 taskExecutor->PostTask(
120 [weak = WeakClaim(this)]() {
121 auto eventHub = weak.Upgrade();
122 CHECK_NULL_VOID(eventHub);
123 eventHub->UpdateCurrentUIState(UI_STATE_DISABLED);
124 }, TaskExecutor::TaskType::UI, "ArkUIUpdateCurrentUIState");
125 }
126
MarkModifyDone()127 void EventHub::MarkModifyDone()
128 {
129 if (stateStyleMgr_) {
130 // focused style is managered in focus event hub.
131 if (stateStyleMgr_->HasStateStyle(UI_STATE_PRESSED)) {
132 GetOrCreateGestureEventHub()->AddTouchEvent(stateStyleMgr_->GetPressedListener());
133 }
134 if (stateStyleMgr_->HasStateStyle(UI_STATE_DISABLED)) {
135 if (enabled_) {
136 stateStyleMgr_->ResetCurrentUIState(UI_STATE_DISABLED);
137 } else {
138 PostEnabledTask();
139 }
140 }
141 }
142
143 if (gestureEventHub_) {
144 gestureEventHub_->OnModifyDone();
145 }
146 OnModifyDone();
147 }
148
SetCustomerOnDragFunc(DragFuncType dragFuncType,OnDragFunc && onDragFunc)149 void EventHub::SetCustomerOnDragFunc(DragFuncType dragFuncType, OnDragFunc&& onDragFunc)
150 {
151 switch (dragFuncType) {
152 case DragFuncType::DRAG_ENTER:
153 customerOnDragEnter_ = std::move(onDragFunc);
154 break;
155 case DragFuncType::DRAG_LEAVE:
156 customerOnDragLeave_ = std::move(onDragFunc);
157 break;
158 case DragFuncType::DRAG_MOVE:
159 customerOnDragMove_ = std::move(onDragFunc);
160 break;
161 case DragFuncType::DRAG_DROP:
162 customerOnDrop_ = std::move(onDragFunc);
163 break;
164 default:
165 LOGW("unsuport dragFuncType");
166 break;
167 }
168 }
169
SetCustomerOnDragFunc(DragFuncType dragFuncType,OnNewDragFunc && onDragEnd)170 void EventHub::SetCustomerOnDragFunc(DragFuncType dragFuncType, OnNewDragFunc&& onDragEnd)
171 {
172 if (dragFuncType != DragFuncType::DRAG_END) {
173 return;
174 }
175 customerOnDragEnd_ = std::move(onDragEnd);
176 }
177
FireCustomerOnDragFunc(DragFuncType dragFuncType,const RefPtr<OHOS::Ace::DragEvent> & info,const std::string & extraParams)178 void EventHub::FireCustomerOnDragFunc(DragFuncType dragFuncType, const RefPtr<OHOS::Ace::DragEvent>& info,
179 const std::string& extraParams)
180 {
181 switch (dragFuncType) {
182 case DragFuncType::DRAG_ENTER: {
183 if (customerOnDragEnter_ != nullptr) {
184 auto customerDragEnter = customerOnDragEnter_;
185 customerDragEnter(info, extraParams);
186 }
187 break;
188 }
189 case DragFuncType::DRAG_LEAVE: {
190 if (customerOnDragLeave_ != nullptr) {
191 auto customerOnDragLeave = customerOnDragLeave_;
192 customerOnDragLeave(info, extraParams);
193 }
194 break;
195 }
196 case DragFuncType::DRAG_MOVE: {
197 if (customerOnDragMove_ != nullptr) {
198 auto customerOnDragMove = customerOnDragMove_;
199 customerOnDragMove(info, extraParams);
200 }
201 break;
202 }
203 case DragFuncType::DRAG_DROP: {
204 if (customerOnDrop_ != nullptr) {
205 auto customerOnDrop = customerOnDrop_;
206 customerOnDrop(info, extraParams);
207 }
208 break;
209 }
210 case DragFuncType::DRAG_END: {
211 if (customerOnDragEnd_ != nullptr) {
212 auto customerOnDragEnd = customerOnDragEnd_;
213 customerOnDragEnd(info);
214 }
215 break;
216 }
217 default:
218 LOGW("unsuport DragFuncType");
219 break;
220 }
221 }
222
FireOnDragEnter(const RefPtr<OHOS::Ace::DragEvent> & info,const std::string & extraParams)223 void EventHub::FireOnDragEnter(const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams)
224 {
225 if (SystemProperties::GetDebugEnabled()) {
226 TAG_LOGD(AceLogTag::ACE_DRAG, "DragDropManager fire onDragEnter");
227 }
228 if (onDragEnter_) {
229 // callback may be overwritten in its invoke so we copy it first
230 auto onDragEnter = onDragEnter_;
231 onDragEnter(info, extraParams);
232 }
233 }
234
FireOnDragLeave(const RefPtr<OHOS::Ace::DragEvent> & info,const std::string & extraParams)235 void EventHub::FireOnDragLeave(const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams)
236 {
237 if (SystemProperties::GetDebugEnabled()) {
238 TAG_LOGD(AceLogTag::ACE_DRAG, "DragDropManager fire onDragLeave");
239 }
240 if (onDragLeave_) {
241 // callback may be overwritten in its invoke so we copy it first
242 auto onDragLeave = onDragLeave_;
243 onDragLeave(info, extraParams);
244 }
245 }
246
FireOnDragMove(const RefPtr<OHOS::Ace::DragEvent> & info,const std::string & extraParams)247 void EventHub::FireOnDragMove(const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams)
248 {
249 if (SystemProperties::GetDebugEnabled()) {
250 TAG_LOGD(AceLogTag::ACE_DRAG, "DragDropManager fire onDragMove");
251 }
252 if (onDragMove_) {
253 // callback may be overwritten in its invoke so we copy it first
254 auto onDragMove = onDragMove_;
255 onDragMove(info, extraParams);
256 }
257 }
258
FireOnDrop(const RefPtr<OHOS::Ace::DragEvent> & info,const std::string & extraParams)259 void EventHub::FireOnDrop(const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams)
260 {
261 if (SystemProperties::GetDebugEnabled()) {
262 TAG_LOGD(AceLogTag::ACE_DRAG, "DragDropManager fire onDrop");
263 }
264 if (onDrop_) {
265 // callback may be overwritten in its invoke so we copy it first
266 auto onDrop = onDrop_;
267 onDrop(info, extraParams);
268 }
269 }
270
IsFireOnDrop(const RefPtr<OHOS::Ace::DragEvent> & info)271 bool EventHub::IsFireOnDrop(const RefPtr<OHOS::Ace::DragEvent>& info)
272 {
273 return !HasCustomerOnDrop()
274 || info->GetResult() == DragRet::DRAG_DEFAULT
275 || info->GetResult() == DragRet::ENABLE_DROP
276 || info->GetResult() == DragRet::DISABLE_DROP;
277 }
278
HandleInternalOnDrop(const RefPtr<OHOS::Ace::DragEvent> & info,const std::string & extraParams)279 void EventHub::HandleInternalOnDrop(const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams)
280 {
281 if (IsFireOnDrop(info)) {
282 FireOnDrop(info, extraParams);
283 }
284 }
285
AddInnerOnAreaChangedCallback(int32_t id,OnAreaChangedFunc && callback)286 void EventHub::AddInnerOnAreaChangedCallback(int32_t id, OnAreaChangedFunc&& callback)
287 {
288 auto pipeline = PipelineContext::GetCurrentContext();
289 CHECK_NULL_VOID(pipeline);
290 auto frameNode = GetFrameNode();
291 CHECK_NULL_VOID(frameNode);
292 pipeline->AddOnAreaChangeNode(frameNode->GetId());
293 frameNode->InitLastArea();
294 onAreaChangedInnerCallbacks_[id] = std::move(callback);
295 }
296
RemoveInnerOnAreaChangedCallback(int32_t id)297 void EventHub::RemoveInnerOnAreaChangedCallback(int32_t id)
298 {
299 CHECK_RUN_ON(UI);
300 onAreaChangedInnerCallbacks_.erase(id);
301 }
302
SetOnSizeChanged(OnSizeChangedFunc && onSizeChanged)303 void EventHub::SetOnSizeChanged(OnSizeChangedFunc&& onSizeChanged)
304 {
305 onSizeChanged_ = std::move(onSizeChanged);
306 }
307
FireOnSizeChanged(const RectF & oldRect,const RectF & rect)308 void EventHub::FireOnSizeChanged(const RectF& oldRect, const RectF& rect)
309 {
310 if (onSizeChanged_) {
311 // callback may be overwritten in its invoke so we copy it first
312 auto onSizeChanged = onSizeChanged_;
313 onSizeChanged(oldRect, rect);
314 }
315 }
316
SetJSFrameNodeOnSizeChangeCallback(OnSizeChangedFunc && onSizeChanged)317 void EventHub::SetJSFrameNodeOnSizeChangeCallback(OnSizeChangedFunc&& onSizeChanged)
318 {
319 onJsFrameNodeSizeChanged_ = std::move(onSizeChanged);
320 }
321
FireJSFrameNodeOnSizeChanged(const RectF & oldRect,const RectF & rect)322 void EventHub::FireJSFrameNodeOnSizeChanged(const RectF& oldRect, const RectF& rect)
323 {
324 if (onJsFrameNodeSizeChanged_) {
325 // callback may be overwritten in its invoke so we copy it first
326 auto onSizeChanged = onJsFrameNodeSizeChanged_;
327 onSizeChanged(oldRect, rect);
328 }
329 }
330
ClearJSFrameNodeOnSizeChange()331 void EventHub::ClearJSFrameNodeOnSizeChange()
332 {
333 if (onJsFrameNodeSizeChanged_) {
334 onJsFrameNodeSizeChanged_ = nullptr;
335 }
336 }
337
HasOnSizeChanged() const338 bool EventHub::HasOnSizeChanged() const
339 {
340 return static_cast<bool>(onSizeChanged_) || static_cast<bool>(onJsFrameNodeSizeChanged_);
341 }
342
HasImmediatelyVisibleCallback()343 bool EventHub::HasImmediatelyVisibleCallback()
344 {
345 return visibleAreaUserCallback_.callback || visibleAreaInnerCallback_.callback;
346 }
347
ClearOnAreaChangedInnerCallbacks()348 void EventHub::ClearOnAreaChangedInnerCallbacks()
349 {
350 onAreaChangedInnerCallbacks_.clear();
351 }
352
ClearCustomerOnDragFunc()353 void EventHub::ClearCustomerOnDragFunc()
354 {
355 onDragStart_ = nullptr;
356 customerOnDragEnter_ = nullptr;
357 customerOnDragLeave_ = nullptr;
358 customerOnDragMove_ = nullptr;
359 customerOnDrop_ = nullptr;
360 customerOnDragEnd_ = nullptr;
361 }
362
SetJSFrameNodeOnAppear(std::function<void ()> && onAppear)363 void EventHub::SetJSFrameNodeOnAppear(std::function<void()>&& onAppear)
364 {
365 onJSFrameNodeAppear_ = std::move(onAppear);
366 }
367
ClearJSFrameNodeOnAppear()368 void EventHub::ClearJSFrameNodeOnAppear()
369 {
370 if (onJSFrameNodeAppear_) {
371 onJSFrameNodeAppear_ = nullptr;
372 }
373 }
374
SetJSFrameNodeOnDisappear(std::function<void ()> && onDisappear)375 void EventHub::SetJSFrameNodeOnDisappear(std::function<void()>&& onDisappear)
376 {
377 onJSFrameNodeDisappear_ = std::move(onDisappear);
378 }
379
ClearJSFrameNodeOnDisappear()380 void EventHub::ClearJSFrameNodeOnDisappear()
381 {
382 if (onJSFrameNodeDisappear_) {
383 onJSFrameNodeDisappear_ = nullptr;
384 }
385 }
386
FireOnAppear()387 void EventHub::FireOnAppear()
388 {
389 if (onAppear_ || onJSFrameNodeAppear_) {
390 auto pipeline = PipelineBase::GetCurrentContextSafely();
391 CHECK_NULL_VOID(pipeline);
392 auto taskScheduler = pipeline->GetTaskExecutor();
393 CHECK_NULL_VOID(taskScheduler);
394 taskScheduler->PostTask(
395 [weak = WeakClaim(this)]() {
396 auto eventHub = weak.Upgrade();
397 CHECK_NULL_VOID(eventHub);
398 if (eventHub->onAppear_) {
399 // callback may be overwritten in its invoke so we copy it first
400 auto onAppear = eventHub->onAppear_;
401 onAppear();
402 }
403 if (eventHub->onJSFrameNodeAppear_) {
404 // callback may be overwritten in its invoke so we copy it first
405 auto onJSFrameNodeAppear = eventHub->onJSFrameNodeAppear_;
406 onJSFrameNodeAppear();
407 }
408 },
409 TaskExecutor::TaskType::UI, "ArkUIFrameNodeAppearEvent");
410 }
411 }
412
FireOnDisappear()413 void EventHub::FireOnDisappear()
414 {
415 if (onDisappear_) {
416 // callback may be overwritten in its invoke so we copy it first
417 auto onDisappear = onDisappear_;
418 onDisappear();
419 }
420 if (onJSFrameNodeDisappear_) {
421 // callback may be overwritten in its invoke so we copy it first
422 auto onJSFrameNodeDisappear = onJSFrameNodeDisappear_;
423 onJSFrameNodeDisappear();
424 }
425 }
426
AddInnerOnSizeChanged(int32_t id,OnSizeChangedFunc && callback)427 void EventHub::AddInnerOnSizeChanged(int32_t id, OnSizeChangedFunc&& callback)
428 {
429 onSizeChangedInnerCallbacks_[id] = std::move(callback);
430 }
431
FireInnerOnSizeChanged(const RectF & oldRect,const RectF & rect)432 void EventHub::FireInnerOnSizeChanged(const RectF& oldRect, const RectF& rect)
433 {
434 for (auto& innerCallbackInfo : onSizeChangedInnerCallbacks_) {
435 if (innerCallbackInfo.second) {
436 auto innerOnSizeCallback = innerCallbackInfo.second;
437 innerOnSizeCallback(oldRect, rect);
438 }
439 }
440 }
441
HasInnerOnSizeChanged() const442 bool EventHub::HasInnerOnSizeChanged() const
443 {
444 return !onSizeChangedInnerCallbacks_.empty();
445 }
446
ClearInnerOnSizeChanged()447 void EventHub::ClearInnerOnSizeChanged()
448 {
449 onSizeChangedInnerCallbacks_.clear();
450 }
451
SetOnAttach(std::function<void ()> && onAttach)452 void EventHub::SetOnAttach(std::function<void()>&& onAttach)
453 {
454 onAttach_ = std::move(onAttach);
455 }
456
ClearOnAttach()457 void EventHub::ClearOnAttach()
458 {
459 onAttach_ = nullptr;
460 }
461
FireOnAttach()462 void EventHub::FireOnAttach()
463 {
464 if (onAttach_) {
465 auto onAttach = onAttach_;
466 onAttach();
467 }
468 }
469
SetOnDetach(std::function<void ()> && onDetach)470 void EventHub::SetOnDetach(std::function<void()>&& onDetach)
471 {
472 onDetach_ = std::move(onDetach);
473 }
474
ClearOnDetach()475 void EventHub::ClearOnDetach()
476 {
477 onDetach_ = nullptr;
478 }
479
FireOnDetach()480 void EventHub::FireOnDetach()
481 {
482 if (onDetach_) {
483 auto onDetach = onDetach_;
484 onDetach();
485 }
486 }
487
ClearStateStyle()488 void EventHub::ClearStateStyle()
489 {
490 if (stateStyleMgr_) {
491 stateStyleMgr_->ClearStateStyleTask();
492 }
493 }
494
OnDetachClear()495 void EventHub::OnDetachClear()
496 {
497 FireOnDetach();
498 FireOnDisappear();
499 ClearStateStyle();
500 }
501
SetEnabled(bool enabled)502 void EventHub::SetEnabled(bool enabled)
503 {
504 auto host = GetFrameNode();
505 if (enabled_ != enabled && host) {
506 host->OnAccessibilityEvent(AccessibilityEventType::ELEMENT_INFO_CHANGE);
507 }
508 enabled_ = enabled;
509 developerEnabled_ = enabled;
510 }
511 } // namespace OHOS::Ace::NG
512