1 /*
2 * Copyright (c) 2024 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/pattern/ui_extension/platform_pattern.h"
17
18 #include <optional>
19
20 #include "core/event/key_event.h"
21 #include "core/event/pointer_event.h"
22
23 #include "adapter/ohos/entrance/ace_container.h"
24 #include "adapter/ohos/entrance/ace_extra_input_data.h"
25 #include "adapter/ohos/entrance/mmi_event_convertor.h"
26 #include "base/geometry/offset.h"
27 #include "base/utils/utils.h"
28 #include "core/common/container.h"
29 #include "core/components_ng/event/event_hub.h"
30 #include "core/components_ng/pattern/ui_extension/ui_extension_layout_algorithm.h"
31 #include "core/components_ng/pattern/window_scene/scene/window_pattern.h"
32 #include "core/components_ng/render/adapter/rosen_render_context.h"
33 #include "core/components_ng/render/adapter/rosen_window.h"
34 #include "core/event/ace_events.h"
35 #include "core/event/mouse_event.h"
36 #include "core/event/touch_event.h"
37 #include "core/pipeline/pipeline_context.h"
38 #include "core/pipeline_ng/pipeline_context.h"
39
40 namespace OHOS::Ace::NG {
PlatformPattern(AceLogTag tag,int32_t platformId)41 PlatformPattern::PlatformPattern(AceLogTag tag, int32_t platformId)
42 : tag_(tag), platformId_(platformId)
43 {
44 PLATFORM_LOGI("The PlatformPattern is created");
45 }
46
~PlatformPattern()47 PlatformPattern::~PlatformPattern()
48 {
49 PLATFORM_LOGI("The PlatformPattern is destroyed");
50 }
51
CreateLayoutAlgorithm()52 RefPtr<LayoutAlgorithm> PlatformPattern::CreateLayoutAlgorithm()
53 {
54 return MakeRefPtr<UIExtensionLayoutAlgorithm>();
55 }
56
GetFocusPattern() const57 FocusPattern PlatformPattern::GetFocusPattern() const
58 {
59 return { FocusType::NODE, true, FocusStyleType::FORCE_NONE };
60 }
61
OnModifyDone()62 void PlatformPattern::OnModifyDone()
63 {
64 Pattern::OnModifyDone();
65 auto host = GetHost();
66 CHECK_NULL_VOID(host);
67 auto hub = host->GetEventHub<EventHub>();
68 CHECK_NULL_VOID(hub);
69 auto gestureHub = hub->GetOrCreateGestureEventHub();
70 CHECK_NULL_VOID(gestureHub);
71 InitTouchEvent(gestureHub);
72 auto inputHub = hub->GetOrCreateInputEventHub();
73 CHECK_NULL_VOID(inputHub);
74 InitMouseEvent(inputHub);
75 InitHoverEvent(inputHub);
76 auto focusHub = host->GetFocusHub();
77 CHECK_NULL_VOID(focusHub);
78 InitKeyEvent(focusHub);
79 }
80
InitKeyEvent(const RefPtr<FocusHub> & focusHub)81 void PlatformPattern::InitKeyEvent(const RefPtr<FocusHub>& focusHub)
82 {
83 focusHub->SetOnFocusInternal([weak = WeakClaim(this)]() {
84 auto pattern = weak.Upgrade();
85 if (pattern) {
86 pattern->HandleFocusEvent();
87 }
88 });
89
90 focusHub->SetOnBlurInternal([weak = WeakClaim(this)]() {
91 auto pattern = weak.Upgrade();
92 if (pattern) {
93 pattern->HandleBlurEvent();
94 }
95 });
96
97 focusHub->SetOnClearFocusStateInternal([weak = WeakClaim(this)]() {
98 auto pattern = weak.Upgrade();
99 if (pattern) {
100 pattern->DispatchFocusActiveEvent(false);
101 }
102 });
103
104 focusHub->SetOnPaintFocusStateInternal([weak = WeakClaim(this)]() -> bool {
105 auto pattern = weak.Upgrade();
106 if (pattern) {
107 pattern->DispatchFocusActiveEvent(true);
108 return true;
109 }
110 return false;
111 });
112
113 focusHub->SetOnKeyEventInternal([wp = WeakClaim(this)](const KeyEvent& event) -> bool {
114 auto pattern = wp.Upgrade();
115 if (pattern) {
116 return pattern->HandleKeyEvent(event);
117 }
118 return false;
119 });
120 }
121
InitTouchEvent(const RefPtr<GestureEventHub> & gestureHub)122 void PlatformPattern::InitTouchEvent(const RefPtr<GestureEventHub>& gestureHub)
123 {
124 if (touchEvent_) {
125 return;
126 }
127 auto callback = [weak = WeakClaim(this)](const TouchEventInfo& info) {
128 auto pattern = weak.Upgrade();
129 if (pattern) {
130 pattern->HandleTouchEvent(info);
131 }
132 };
133 if (touchEvent_) {
134 gestureHub->RemoveTouchEvent(touchEvent_);
135 }
136 touchEvent_ = MakeRefPtr<TouchEventImpl>(std::move(callback));
137 gestureHub->AddTouchEvent(touchEvent_);
138 }
139
InitMouseEvent(const RefPtr<InputEventHub> & inputHub)140 void PlatformPattern::InitMouseEvent(const RefPtr<InputEventHub>& inputHub)
141 {
142 if (mouseEvent_) {
143 return;
144 }
145 auto callback = [weak = WeakClaim(this)](MouseInfo& info) {
146 auto pattern = weak.Upgrade();
147 if (pattern) {
148 pattern->HandleMouseEvent(info);
149 }
150 };
151 if (mouseEvent_) {
152 inputHub->RemoveOnMouseEvent(mouseEvent_);
153 }
154 mouseEvent_ = MakeRefPtr<InputEvent>(std::move(callback));
155 inputHub->AddOnMouseEvent(mouseEvent_);
156 }
157
InitHoverEvent(const RefPtr<InputEventHub> & inputHub)158 void PlatformPattern::InitHoverEvent(const RefPtr<InputEventHub>& inputHub)
159 {
160 if (hoverEvent_) {
161 return;
162 }
163 auto callback = [weak = WeakClaim(this)](bool isHover) {
164 auto pattern = weak.Upgrade();
165 if (pattern) {
166 pattern->HandleHoverEvent(isHover);
167 }
168 };
169 if (hoverEvent_) {
170 inputHub->RemoveOnHoverEvent(hoverEvent_);
171 }
172 hoverEvent_ = MakeRefPtr<InputEvent>(std::move(callback));
173 inputHub->AddOnHoverEvent(hoverEvent_);
174 }
175
HandleKeyEvent(const KeyEvent & event)176 bool PlatformPattern::HandleKeyEvent(const KeyEvent& event)
177 {
178 return false;
179 }
180
HandleFocusEvent()181 void PlatformPattern::HandleFocusEvent()
182 {}
183
HandleBlurEvent()184 void PlatformPattern::HandleBlurEvent()
185 {}
186
HandleTouchEvent(const TouchEventInfo & info)187 void PlatformPattern::HandleTouchEvent(const TouchEventInfo& info)
188 {
189 if (info.GetSourceDevice() != SourceType::TOUCH) {
190 return;
191 }
192 const auto pointerEvent = info.GetPointerEvent();
193 CHECK_NULL_VOID(pointerEvent);
194 auto host = GetHost();
195 CHECK_NULL_VOID(host);
196 auto pipeline = PipelineBase::GetCurrentContext();
197 CHECK_NULL_VOID(pipeline);
198 Platform::CalculatePointerEvent(pointerEvent, host);
199 AceExtraInputData::InsertInterpolatePoints(info);
200 auto focusHub = host->GetFocusHub();
201 CHECK_NULL_VOID(focusHub);
202 focusHub->RequestFocusImmediately();
203 DispatchPointerEvent(pointerEvent);
204 }
205
HandleMouseEvent(const MouseInfo & info)206 void PlatformPattern::HandleMouseEvent(const MouseInfo& info)
207 {
208 if (info.GetSourceDevice() != SourceType::MOUSE) {
209 return;
210 }
211 const auto pointerEvent = info.GetPointerEvent();
212 CHECK_NULL_VOID(pointerEvent);
213 lastPointerEvent_ = pointerEvent;
214 auto host = GetHost();
215 CHECK_NULL_VOID(host);
216 Platform::CalculatePointerEvent(pointerEvent, host);
217 if (info.GetAction() == MouseAction::PRESS) {
218 auto hub = host->GetFocusHub();
219 CHECK_NULL_VOID(hub);
220 hub->RequestFocusImmediately();
221 }
222 DispatchPointerEvent(pointerEvent);
223 }
224
HandleHoverEvent(bool isHover)225 void PlatformPattern::HandleHoverEvent(bool isHover)
226 {
227 if (isHover) {
228 return;
229 }
230 CHECK_NULL_VOID(lastPointerEvent_);
231 lastPointerEvent_->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW);
232 DispatchPointerEvent(lastPointerEvent_);
233 }
234
HandleDragEvent(const PointerEvent & info)235 void PlatformPattern::HandleDragEvent(const PointerEvent& info)
236 {
237 const auto pointerEvent = info.rawPointerEvent;
238 CHECK_NULL_VOID(pointerEvent);
239 auto host = GetHost();
240 CHECK_NULL_VOID(host);
241 auto pipeline = PipelineBase::GetCurrentContext();
242 CHECK_NULL_VOID(pipeline);
243 Platform::CalculatePointerEvent(pointerEvent, host, true);
244 DispatchPointerEvent(pointerEvent);
245 }
246
SetOnErrorCallback(const std::function<void (int32_t code,const std::string & name,const std::string & message)> && callback)247 void PlatformPattern::SetOnErrorCallback(
248 const std::function<void(int32_t code, const std::string& name, const std::string& message)>&& callback)
249 {
250 onErrorCallback_ = std::move(callback);
251 if (lastError_.code != 0) {
252 ErrorMsg error;
253 std::swap(lastError_, error);
254 FireOnErrorCallback(error.code, error.name, error.message);
255 }
256 }
257
FireOnErrorCallback(int32_t code,const std::string & name,const std::string & message)258 void PlatformPattern::FireOnErrorCallback(
259 int32_t code, const std::string& name, const std::string& message)
260 {
261 PLATFORM_LOGI("FireOnError code: %{public}d, name: %{public}s, message: %{public}s",
262 code, name.c_str(), message.c_str());
263 if (onErrorCallback_) {
264 ContainerScope scope(instanceId_);
265 onErrorCallback_(code, name, message);
266 return;
267 }
268
269 lastError_ = { code, name, message };
270 }
271
OnMountToParentDone()272 void PlatformPattern::OnMountToParentDone()
273 {
274 auto frameNode = frameNode_.Upgrade();
275 CHECK_NULL_VOID(frameNode);
276 if (frameNode->GetNodeStatus() == NodeStatus::NORMAL_NODE) {
277 PLATFORM_LOGW("Frame node status is normal.");
278 return;
279 }
280 }
281
GetNodeId()282 int32_t PlatformPattern::GetNodeId()
283 {
284 auto host = GetHost();
285 return host ? host->GetId() : -1;
286 }
287
GetInstanceId()288 int32_t PlatformPattern::GetInstanceId()
289 {
290 return instanceId_;
291 }
292 } // namespace OHOS::Ace::NG
293