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->SetVisibleAreaChangeTriggerReason(VisibleAreaChangeTriggerReason::DETACH_FROM_MAINTREE);
52 host->TriggerVisibleAreaChangeCallback(0, true);
53 context->RemoveVisibleAreaChangeNode(host->GetId());
54 }
55 }
56
GetFrameNode() const57 RefPtr<FrameNode> EventHub::GetFrameNode() const
58 {
59 return host_.Upgrade();
60 }
61
AddSupportedState(UIState state)62 void EventHub::AddSupportedState(UIState state)
63 {
64 if (!stateStyleMgr_) {
65 stateStyleMgr_ = MakeRefPtr<StateStyleManager>(host_);
66 }
67 stateStyleMgr_->AddSupportedState(state);
68 }
69
SetSupportedStates(UIState state)70 void EventHub::SetSupportedStates(UIState state)
71 {
72 if (!stateStyleMgr_) {
73 stateStyleMgr_ = MakeRefPtr<StateStyleManager>(host_);
74 }
75 stateStyleMgr_->SetSupportedStates(state);
76 }
77
SetCurrentUIState(UIState state,bool flag)78 void EventHub::SetCurrentUIState(UIState state, bool flag)
79 {
80 if (!stateStyleMgr_) {
81 stateStyleMgr_ = MakeRefPtr<StateStyleManager>(host_);
82 }
83 stateStyleMgr_->SetCurrentUIState(state, flag);
84 }
85
IsCurrentStateOn(UIState state)86 bool EventHub::IsCurrentStateOn(UIState state)
87 {
88 if (!stateStyleMgr_) {
89 return false;
90 }
91 return stateStyleMgr_->IsCurrentStateOn(state);
92 }
93
CreateGetEventTargetImpl() const94 GetEventTargetImpl EventHub::CreateGetEventTargetImpl() const
95 {
96 auto impl = [weak = host_]() -> std::optional<EventTarget> {
97 auto host = weak.Upgrade();
98 CHECK_NULL_RETURN(host, std::nullopt);
99 EventTarget eventTarget;
100 eventTarget.id = std::to_string(host->GetId());
101 eventTarget.type = host->GetTag();
102 auto geometryNode = host->GetGeometryNode();
103 auto offset = geometryNode->GetFrameOffset();
104 auto size = geometryNode->GetFrameSize();
105 eventTarget.area.SetOffset(DimensionOffset(offset));
106 eventTarget.area.SetHeight(Dimension(size.Height()));
107 eventTarget.area.SetWidth(Dimension(size.Width()));
108 eventTarget.origin = DimensionOffset(host->GetOffsetRelativeToWindow() - offset);
109 return eventTarget;
110 };
111 return impl;
112 }
113
PostEnabledTask()114 void EventHub::PostEnabledTask()
115 {
116 auto pipeline = PipelineBase::GetCurrentContext();
117 CHECK_NULL_VOID(pipeline);
118 auto taskExecutor = pipeline->GetTaskExecutor();
119 CHECK_NULL_VOID(taskExecutor);
120 taskExecutor->PostTask(
121 [weak = WeakClaim(this)]() {
122 auto eventHub = weak.Upgrade();
123 CHECK_NULL_VOID(eventHub);
124 eventHub->UpdateCurrentUIState(UI_STATE_DISABLED);
125 }, TaskExecutor::TaskType::UI, "ArkUIUpdateCurrentUIState");
126 }
127
MarkModifyDone()128 void EventHub::MarkModifyDone()
129 {
130 if (stateStyleMgr_) {
131 // focused style is managered in focus event hub.
132 if (stateStyleMgr_->HasStateStyle(UI_STATE_PRESSED)) {
133 GetOrCreateGestureEventHub()->AddTouchEvent(stateStyleMgr_->GetPressedListener());
134 }
135 if (stateStyleMgr_->HasStateStyle(UI_STATE_DISABLED)) {
136 if (enabled_) {
137 stateStyleMgr_->ResetCurrentUIState(UI_STATE_DISABLED);
138 } else {
139 PostEnabledTask();
140 }
141 }
142 }
143
144 if (gestureEventHub_) {
145 gestureEventHub_->OnModifyDone();
146 }
147 OnModifyDone();
148 }
149
SetCustomerOnDragFunc(DragFuncType dragFuncType,OnDragFunc && onDragFunc)150 void EventHub::SetCustomerOnDragFunc(DragFuncType dragFuncType, OnDragFunc&& onDragFunc)
151 {
152 switch (dragFuncType) {
153 case DragFuncType::DRAG_ENTER:
154 customerOnDragEnter_ = std::move(onDragFunc);
155 break;
156 case DragFuncType::DRAG_LEAVE:
157 customerOnDragLeave_ = std::move(onDragFunc);
158 break;
159 case DragFuncType::DRAG_MOVE:
160 customerOnDragMove_ = std::move(onDragFunc);
161 break;
162 case DragFuncType::DRAG_DROP:
163 customerOnDrop_ = std::move(onDragFunc);
164 break;
165 default:
166 LOGW("unsuport dragFuncType");
167 break;
168 }
169 }
170
SetCustomerOnDragFunc(DragFuncType dragFuncType,OnNewDragFunc && onDragEnd)171 void EventHub::SetCustomerOnDragFunc(DragFuncType dragFuncType, OnNewDragFunc&& onDragEnd)
172 {
173 if (dragFuncType != DragFuncType::DRAG_END) {
174 return;
175 }
176 customerOnDragEnd_ = std::move(onDragEnd);
177 }
178
FireCustomerOnDragFunc(DragFuncType dragFuncType,const RefPtr<OHOS::Ace::DragEvent> & info,const std::string & extraParams)179 void EventHub::FireCustomerOnDragFunc(DragFuncType dragFuncType, const RefPtr<OHOS::Ace::DragEvent>& info,
180 const std::string& extraParams)
181 {
182 switch (dragFuncType) {
183 case DragFuncType::DRAG_ENTER: {
184 if (customerOnDragEnter_ != nullptr) {
185 auto customerDragEnter = customerOnDragEnter_;
186 customerDragEnter(info, extraParams);
187 }
188 break;
189 }
190 case DragFuncType::DRAG_LEAVE: {
191 if (customerOnDragLeave_ != nullptr) {
192 auto customerOnDragLeave = customerOnDragLeave_;
193 customerOnDragLeave(info, extraParams);
194 }
195 break;
196 }
197 case DragFuncType::DRAG_MOVE: {
198 if (customerOnDragMove_ != nullptr) {
199 auto customerOnDragMove = customerOnDragMove_;
200 customerOnDragMove(info, extraParams);
201 }
202 break;
203 }
204 case DragFuncType::DRAG_DROP: {
205 if (customerOnDrop_ != nullptr) {
206 auto customerOnDrop = customerOnDrop_;
207 customerOnDrop(info, extraParams);
208 }
209 break;
210 }
211 case DragFuncType::DRAG_END: {
212 if (customerOnDragEnd_ != nullptr) {
213 auto customerOnDragEnd = customerOnDragEnd_;
214 customerOnDragEnd(info);
215 }
216 break;
217 }
218 default:
219 LOGW("unsuport DragFuncType");
220 break;
221 }
222 }
223
FireOnDragEnter(const RefPtr<OHOS::Ace::DragEvent> & info,const std::string & extraParams)224 void EventHub::FireOnDragEnter(const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams)
225 {
226 if (SystemProperties::GetDebugEnabled()) {
227 TAG_LOGD(AceLogTag::ACE_DRAG, "DragDropManager fire onDragEnter");
228 }
229 if (onDragEnter_) {
230 // callback may be overwritten in its invoke so we copy it first
231 auto onDragEnter = onDragEnter_;
232 onDragEnter(info, extraParams);
233 }
234 }
235
FireOnDragLeave(const RefPtr<OHOS::Ace::DragEvent> & info,const std::string & extraParams)236 void EventHub::FireOnDragLeave(const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams)
237 {
238 if (SystemProperties::GetDebugEnabled()) {
239 TAG_LOGD(AceLogTag::ACE_DRAG, "DragDropManager fire onDragLeave");
240 }
241 if (onDragLeave_) {
242 // callback may be overwritten in its invoke so we copy it first
243 auto onDragLeave = onDragLeave_;
244 onDragLeave(info, extraParams);
245 }
246 }
247
FireOnDragMove(const RefPtr<OHOS::Ace::DragEvent> & info,const std::string & extraParams)248 void EventHub::FireOnDragMove(const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams)
249 {
250 if (SystemProperties::GetDebugEnabled()) {
251 TAG_LOGD(AceLogTag::ACE_DRAG, "DragDropManager fire onDragMove");
252 }
253 if (onDragMove_) {
254 // callback may be overwritten in its invoke so we copy it first
255 auto onDragMove = onDragMove_;
256 onDragMove(info, extraParams);
257 }
258 }
259
FireOnDrop(const RefPtr<OHOS::Ace::DragEvent> & info,const std::string & extraParams)260 void EventHub::FireOnDrop(const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams)
261 {
262 if (SystemProperties::GetDebugEnabled()) {
263 TAG_LOGD(AceLogTag::ACE_DRAG, "DragDropManager fire onDrop");
264 }
265 if (onDrop_) {
266 // callback may be overwritten in its invoke so we copy it first
267 auto onDrop = onDrop_;
268 onDrop(info, extraParams);
269 }
270 }
271
IsFireOnDrop(const RefPtr<OHOS::Ace::DragEvent> & info)272 bool EventHub::IsFireOnDrop(const RefPtr<OHOS::Ace::DragEvent>& info)
273 {
274 return !HasCustomerOnDrop()
275 || info->GetResult() == DragRet::DRAG_DEFAULT
276 || info->GetResult() == DragRet::ENABLE_DROP
277 || info->GetResult() == DragRet::DISABLE_DROP;
278 }
279
HandleInternalOnDrop(const RefPtr<OHOS::Ace::DragEvent> & info,const std::string & extraParams)280 void EventHub::HandleInternalOnDrop(const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams)
281 {
282 if (IsFireOnDrop(info)) {
283 FireOnDrop(info, extraParams);
284 }
285 }
286
AddInnerOnAreaChangedCallback(int32_t id,OnAreaChangedFunc && callback)287 void EventHub::AddInnerOnAreaChangedCallback(int32_t id, OnAreaChangedFunc&& callback)
288 {
289 auto pipeline = PipelineContext::GetCurrentContext();
290 CHECK_NULL_VOID(pipeline);
291 auto frameNode = GetFrameNode();
292 CHECK_NULL_VOID(frameNode);
293 pipeline->AddOnAreaChangeNode(frameNode->GetId());
294 frameNode->InitLastArea();
295 onAreaChangedInnerCallbacks_[id] = std::move(callback);
296 }
297
RemoveInnerOnAreaChangedCallback(int32_t id)298 void EventHub::RemoveInnerOnAreaChangedCallback(int32_t id)
299 {
300 CHECK_RUN_ON(UI);
301 onAreaChangedInnerCallbacks_.erase(id);
302 }
303
ClearCustomerOnDragStart()304 void EventHub::ClearCustomerOnDragStart()
305 {
306 onDragStart_ = nullptr;
307 }
308
ClearCustomerOnDragEnter()309 void EventHub::ClearCustomerOnDragEnter()
310 {
311 customerOnDragEnter_ = nullptr;
312 }
313
ClearCustomerOnDragMove()314 void EventHub::ClearCustomerOnDragMove()
315 {
316 customerOnDragMove_ = nullptr;
317 }
318
ClearCustomerOnDragLeave()319 void EventHub::ClearCustomerOnDragLeave()
320 {
321 customerOnDragLeave_ = nullptr;
322 }
323
ClearCustomerOnDrop()324 void EventHub::ClearCustomerOnDrop()
325 {
326 customerOnDrop_ = nullptr;
327 }
328
ClearCustomerOnDragEnd()329 void EventHub::ClearCustomerOnDragEnd()
330 {
331 customerOnDragEnd_ = nullptr;
332 }
333
SetOnSizeChanged(OnSizeChangedFunc && onSizeChanged)334 void EventHub::SetOnSizeChanged(OnSizeChangedFunc&& onSizeChanged)
335 {
336 onSizeChanged_ = std::move(onSizeChanged);
337 }
338
FireOnSizeChanged(const RectF & oldRect,const RectF & rect)339 void EventHub::FireOnSizeChanged(const RectF& oldRect, const RectF& rect)
340 {
341 if (onSizeChanged_) {
342 // callback may be overwritten in its invoke so we copy it first
343 auto onSizeChanged = onSizeChanged_;
344 onSizeChanged(oldRect, rect);
345 }
346 }
347
SetJSFrameNodeOnSizeChangeCallback(OnSizeChangedFunc && onSizeChanged)348 void EventHub::SetJSFrameNodeOnSizeChangeCallback(OnSizeChangedFunc&& onSizeChanged)
349 {
350 onJsFrameNodeSizeChanged_ = std::move(onSizeChanged);
351 }
352
FireJSFrameNodeOnSizeChanged(const RectF & oldRect,const RectF & rect)353 void EventHub::FireJSFrameNodeOnSizeChanged(const RectF& oldRect, const RectF& rect)
354 {
355 if (onJsFrameNodeSizeChanged_) {
356 // callback may be overwritten in its invoke so we copy it first
357 auto onSizeChanged = onJsFrameNodeSizeChanged_;
358 onSizeChanged(oldRect, rect);
359 }
360 }
361
ClearJSFrameNodeOnSizeChange()362 void EventHub::ClearJSFrameNodeOnSizeChange()
363 {
364 if (onJsFrameNodeSizeChanged_) {
365 onJsFrameNodeSizeChanged_ = nullptr;
366 }
367 }
368
HasOnSizeChanged() const369 bool EventHub::HasOnSizeChanged() const
370 {
371 return static_cast<bool>(onSizeChanged_) || static_cast<bool>(onJsFrameNodeSizeChanged_);
372 }
373
HasImmediatelyVisibleCallback()374 bool EventHub::HasImmediatelyVisibleCallback()
375 {
376 return visibleAreaUserCallback_.callback || visibleAreaInnerCallback_.callback;
377 }
378
ClearOnAreaChangedInnerCallbacks()379 void EventHub::ClearOnAreaChangedInnerCallbacks()
380 {
381 onAreaChangedInnerCallbacks_.clear();
382 }
383
ClearCustomerOnDragFunc()384 void EventHub::ClearCustomerOnDragFunc()
385 {
386 onDragStart_ = nullptr;
387 customerOnDragEnter_ = nullptr;
388 customerOnDragLeave_ = nullptr;
389 customerOnDragMove_ = nullptr;
390 customerOnDrop_ = nullptr;
391 customerOnDragEnd_ = nullptr;
392 }
393
SetJSFrameNodeOnAppear(std::function<void ()> && onAppear)394 void EventHub::SetJSFrameNodeOnAppear(std::function<void()>&& onAppear)
395 {
396 onJSFrameNodeAppear_ = std::move(onAppear);
397 }
398
ClearJSFrameNodeOnAppear()399 void EventHub::ClearJSFrameNodeOnAppear()
400 {
401 if (onJSFrameNodeAppear_) {
402 onJSFrameNodeAppear_ = nullptr;
403 }
404 }
405
SetJSFrameNodeOnDisappear(std::function<void ()> && onDisappear)406 void EventHub::SetJSFrameNodeOnDisappear(std::function<void()>&& onDisappear)
407 {
408 onJSFrameNodeDisappear_ = std::move(onDisappear);
409 }
410
ClearJSFrameNodeOnDisappear()411 void EventHub::ClearJSFrameNodeOnDisappear()
412 {
413 if (onJSFrameNodeDisappear_) {
414 onJSFrameNodeDisappear_ = nullptr;
415 }
416 }
417
FireOnAppear()418 void EventHub::FireOnAppear()
419 {
420 if (onAppear_ || onJSFrameNodeAppear_) {
421 auto pipeline = PipelineBase::GetCurrentContextSafely();
422 CHECK_NULL_VOID(pipeline);
423 auto taskScheduler = pipeline->GetTaskExecutor();
424 CHECK_NULL_VOID(taskScheduler);
425 taskScheduler->PostTask(
426 [weak = WeakClaim(this)]() {
427 auto eventHub = weak.Upgrade();
428 CHECK_NULL_VOID(eventHub);
429 if (eventHub->onAppear_) {
430 // callback may be overwritten in its invoke so we copy it first
431 auto onAppear = eventHub->onAppear_;
432 onAppear();
433 }
434 if (eventHub->onJSFrameNodeAppear_) {
435 // callback may be overwritten in its invoke so we copy it first
436 auto onJSFrameNodeAppear = eventHub->onJSFrameNodeAppear_;
437 onJSFrameNodeAppear();
438 }
439 },
440 TaskExecutor::TaskType::UI, "ArkUIFrameNodeAppearEvent");
441 }
442 }
443
FireOnDisappear()444 void EventHub::FireOnDisappear()
445 {
446 if (onDisappear_) {
447 // callback may be overwritten in its invoke so we copy it first
448 auto onDisappear = onDisappear_;
449 onDisappear();
450 }
451 if (onJSFrameNodeDisappear_) {
452 // callback may be overwritten in its invoke so we copy it first
453 auto onJSFrameNodeDisappear = onJSFrameNodeDisappear_;
454 onJSFrameNodeDisappear();
455 }
456 }
457
AddInnerOnSizeChanged(int32_t id,OnSizeChangedFunc && callback)458 void EventHub::AddInnerOnSizeChanged(int32_t id, OnSizeChangedFunc&& callback)
459 {
460 onSizeChangedInnerCallbacks_[id] = std::move(callback);
461 }
462
FireInnerOnSizeChanged(const RectF & oldRect,const RectF & rect)463 void EventHub::FireInnerOnSizeChanged(const RectF& oldRect, const RectF& rect)
464 {
465 for (auto& innerCallbackInfo : onSizeChangedInnerCallbacks_) {
466 if (innerCallbackInfo.second) {
467 auto innerOnSizeCallback = innerCallbackInfo.second;
468 innerOnSizeCallback(oldRect, rect);
469 }
470 }
471 }
472
HasInnerOnSizeChanged() const473 bool EventHub::HasInnerOnSizeChanged() const
474 {
475 return !onSizeChangedInnerCallbacks_.empty();
476 }
477
ClearInnerOnSizeChanged()478 void EventHub::ClearInnerOnSizeChanged()
479 {
480 onSizeChangedInnerCallbacks_.clear();
481 }
482
SetOnAttach(std::function<void ()> && onAttach)483 void EventHub::SetOnAttach(std::function<void()>&& onAttach)
484 {
485 onAttach_ = std::move(onAttach);
486 }
487
ClearOnAttach()488 void EventHub::ClearOnAttach()
489 {
490 onAttach_ = nullptr;
491 }
492
FireOnAttach()493 void EventHub::FireOnAttach()
494 {
495 if (onAttach_) {
496 auto onAttach = onAttach_;
497 onAttach();
498 }
499 }
500
SetOnDetach(std::function<void ()> && onDetach)501 void EventHub::SetOnDetach(std::function<void()>&& onDetach)
502 {
503 onDetach_ = std::move(onDetach);
504 }
505
ClearOnDetach()506 void EventHub::ClearOnDetach()
507 {
508 onDetach_ = nullptr;
509 }
510
FireOnDetach()511 void EventHub::FireOnDetach()
512 {
513 if (onDetach_) {
514 auto onDetach = onDetach_;
515 onDetach();
516 }
517 }
518
ClearStateStyle()519 void EventHub::ClearStateStyle()
520 {
521 if (stateStyleMgr_) {
522 stateStyleMgr_->ClearStateStyleTask();
523 }
524 }
525
OnDetachClear()526 void EventHub::OnDetachClear()
527 {
528 FireOnDetach();
529 FireOnDisappear();
530 ClearStateStyle();
531 }
532
SetEnabled(bool enabled)533 void EventHub::SetEnabled(bool enabled)
534 {
535 auto host = GetFrameNode();
536 if (enabled_ != enabled && host) {
537 auto accessibilityProperty = host->GetAccessibilityProperty<NG::AccessibilityProperty>();
538 if (accessibilityProperty) {
539 accessibilityProperty->NotifyComponentChangeEvent(AccessibilityEventType::ELEMENT_INFO_CHANGE);
540 }
541 }
542 enabled_ = enabled;
543 developerEnabled_ = enabled;
544 }
545 } // namespace OHOS::Ace::NG
546