1 /*
2 * Copyright (c) 2022-2023 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/base/view_abstract_model_ng.h"
17
18 #include <utility>
19
20 #include "base/geometry/ng/offset_t.h"
21 #include "base/memory/ace_type.h"
22 #include "base/memory/referenced.h"
23 #include "base/thread/task_executor.h"
24 #include "base/utils/utils.h"
25 #include "core/common/ace_engine.h"
26 #include "core/common/container.h"
27 #include "core/common/container_scope.h"
28 #include "core/components/common/properties/placement.h"
29 #include "core/components_ng/base/frame_node.h"
30 #include "core/components_ng/base/view_abstract.h"
31 #include "core/components_ng/event/focus_hub.h"
32 #include "core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.h"
33 #include "core/components_ng/pattern/navrouter/navdestination_pattern.h"
34 #include "core/components_ng/pattern/overlay/overlay_manager.h"
35 #include "core/components_ng/pattern/overlay/sheet_manager.h"
36 #include "core/components_ng/pattern/overlay/sheet_presentation_pattern.h"
37 #include "core/components_ng/pattern/overlay/sheet_style.h"
38 #include "core/components_ng/pattern/stage/page_pattern.h"
39 #ifdef WINDOW_SCENE_SUPPORTED
40 #include "core/components_ng/pattern/window_scene/scene/system_window_scene.h"
41 #endif
42 #include "core/components_v2/inspector/inspector_constants.h"
43 #include "core/event/mouse_event.h"
44 #include "core/pipeline_ng/pipeline_context.h"
45
46 namespace OHOS::Ace::NG {
47 namespace {
48 constexpr int32_t LONG_PRESS_DURATION = 800;
49 constexpr int32_t HOVER_IMAGE_LONG_PRESS_DURATION = 250;
50 constexpr char KEY_CONTEXT_MENU[] = "ContextMenu";
51 constexpr char KEY_MENU[] = "Menu";
52 } // namespace
53
BindMenuGesture(std::vector<NG::OptionParam> && params,std::function<void ()> && buildFunc,const MenuParam & menuParam)54 void ViewAbstractModelNG::BindMenuGesture(
55 std::vector<NG::OptionParam>&& params, std::function<void()>&& buildFunc, const MenuParam& menuParam)
56 {
57 auto targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
58 CHECK_NULL_VOID(targetNode);
59 GestureEventFunc showMenu;
60 auto weakTarget = AceType::WeakClaim(targetNode);
61 if (!params.empty()) {
62 showMenu = [params, weakTarget, menuParam](GestureEvent& info) mutable {
63 auto targetNode = weakTarget.Upgrade();
64 CHECK_NULL_VOID(targetNode);
65 NG::OffsetF menuPosition { info.GetGlobalLocation().GetX() + menuParam.positionOffset.GetX(),
66 info.GetGlobalLocation().GetY() + menuParam.positionOffset.GetY() };
67 NG::ViewAbstract::BindMenuWithItems(std::move(params), targetNode, menuPosition, menuParam);
68 };
69 } else if (buildFunc) {
70 showMenu = [builderFunc = std::move(buildFunc), weakTarget, menuParam](const GestureEvent& info) mutable {
71 auto targetNode = weakTarget.Upgrade();
72 CHECK_NULL_VOID(targetNode);
73 NG::OffsetF menuPosition { info.GetGlobalLocation().GetX() + menuParam.positionOffset.GetX(),
74 info.GetGlobalLocation().GetY() + menuParam.positionOffset.GetY() };
75 std::function<void()> previewBuildFunc;
76 NG::ViewAbstract::BindMenuWithCustomNode(
77 std::move(builderFunc), targetNode, menuPosition, menuParam, std::move(previewBuildFunc));
78 };
79 } else {
80 return;
81 }
82 auto gestureHub = targetNode->GetOrCreateGestureEventHub();
83 gestureHub->BindMenu(std::move(showMenu));
84 }
85
BindMenu(std::vector<NG::OptionParam> && params,std::function<void ()> && buildFunc,const MenuParam & menuParam)86 void ViewAbstractModelNG::BindMenu(
87 std::vector<NG::OptionParam>&& params, std::function<void()>&& buildFunc, const MenuParam& menuParam)
88 {
89 auto targetNode = AceType::Claim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
90 CHECK_NULL_VOID(targetNode);
91 auto targetId = targetNode->GetId();
92 ACE_UPDATE_LAYOUT_PROPERTY(LayoutProperty, IsBindOverlay, true);
93 auto pipelineContext = NG::PipelineContext::GetCurrentContext();
94 CHECK_NULL_VOID(pipelineContext);
95 auto overlayManager = pipelineContext->GetOverlayManager();
96 CHECK_NULL_VOID(overlayManager);
97 auto menuNode = overlayManager->GetMenuNode(targetId);
98 if (menuNode) {
99 TAG_LOGI(AceLogTag::ACE_OVERLAY, "menuNode already exist");
100 auto wrapperPattern = menuNode->GetPattern<MenuWrapperPattern>();
101 if (wrapperPattern->IsShow() && menuParam.setShow && !menuParam.isShow) {
102 overlayManager->HideMenu(menuNode, targetId, false);
103 }
104 } else if (menuParam.isShow) {
105 if (!params.empty()) {
106 NG::ViewAbstract::BindMenuWithItems(std::move(params), targetNode, menuParam.positionOffset, menuParam);
107 } else if (buildFunc) {
108 std::function<void()> previewBuildFunc;
109 NG::ViewAbstract::BindMenuWithCustomNode(
110 std::move(buildFunc), targetNode, menuParam.positionOffset, menuParam, std::move(previewBuildFunc));
111 }
112 }
113 if (!menuParam.setShow) {
114 BindMenuGesture(std::move(params), std::move(buildFunc), menuParam);
115 }
116 // delete menu when target node destroy
117 auto pipeline = PipelineBase::GetCurrentContext();
118 CHECK_NULL_VOID(pipeline);
119 auto theme = pipeline->GetTheme<SelectTheme>();
120 CHECK_NULL_VOID(theme);
121 auto expandDisplay = theme->GetExpandDisplay();
122 if (!menuParam.isShowInSubWindow && expandDisplay) {
123 expandDisplay = false;
124 }
125 if (!expandDisplay) {
126 auto destructor = [id = targetNode->GetId(), params]() mutable {
127 params.clear();
128 auto pipeline = NG::PipelineContext::GetCurrentContext();
129 CHECK_NULL_VOID(pipeline);
130 auto overlayManager = pipeline->GetOverlayManager();
131 CHECK_NULL_VOID(overlayManager);
132 overlayManager->DeleteMenu(id);
133 };
134 targetNode->PushDestroyCallbackWithTag(destructor, KEY_MENU);
135 } else {
136 auto destructor = [id = targetNode->GetId(), containerId = Container::CurrentId(), params]() mutable {
137 params.clear();
138 auto subwindow = SubwindowManager::GetInstance()->GetSubwindow(containerId);
139 CHECK_NULL_VOID(subwindow);
140 auto childContainerId = subwindow->GetChildContainerId();
141 auto childContainer = AceEngine::Get().GetContainer(childContainerId);
142 CHECK_NULL_VOID(childContainer);
143 auto pipeline = AceType::DynamicCast<NG::PipelineContext>(childContainer->GetPipelineContext());
144 CHECK_NULL_VOID(pipeline);
145 auto overlayManager = pipeline->GetOverlayManager();
146 CHECK_NULL_VOID(overlayManager);
147 overlayManager->DeleteMenu(id);
148 };
149 targetNode->PushDestroyCallbackWithTag(destructor, KEY_MENU);
150 }
151 }
152
CreateCustomMenuWithPreview(std::function<void ()> & buildFunc,const MenuParam & menuParam,std::function<void ()> & previewBuildFunc)153 void CreateCustomMenuWithPreview(
154 std::function<void()>& buildFunc, const MenuParam& menuParam, std::function<void()>& previewBuildFunc)
155 {
156 auto targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
157 CHECK_NULL_VOID(targetNode);
158 if (menuParam.previewMode == MenuPreviewMode::IMAGE) {
159 auto context = targetNode->GetRenderContext();
160 CHECK_NULL_VOID(context);
161 auto gestureHub = targetNode->GetEventHub<EventHub>()->GetGestureEventHub();
162 CHECK_NULL_VOID(gestureHub);
163 auto pixelMap = context->GetThumbnailPixelMap();
164 gestureHub->SetPixelMap(pixelMap);
165 }
166 auto refTargetNode = AceType::Claim<NG::FrameNode>(targetNode);
167 NG::ViewAbstract::BindMenuWithCustomNode(
168 std::move(buildFunc), refTargetNode, menuParam.positionOffset, menuParam, std::move(previewBuildFunc));
169 }
170
UpdateIsShowStatusForMenu(int32_t targetId,bool isShow)171 void UpdateIsShowStatusForMenu(int32_t targetId, bool isShow)
172 {
173 auto subwindow = SubwindowManager::GetInstance()->GetSubwindow(Container::CurrentId());
174 CHECK_NULL_VOID(subwindow);
175 auto overlayManager = subwindow->GetOverlayManager();
176 CHECK_NULL_VOID(overlayManager);
177 auto menuNode = overlayManager->GetMenuNode(targetId);
178 CHECK_NULL_VOID(menuNode);
179 auto wrapperPattern = menuNode->GetPattern<MenuWrapperPattern>();
180 CHECK_NULL_VOID(wrapperPattern);
181 wrapperPattern->SetIsShowFromUser(isShow);
182 }
183
BindContextMenuSingle(std::function<void ()> & buildFunc,const MenuParam & menuParam,std::function<void ()> & previewBuildFunc)184 void BindContextMenuSingle(
185 std::function<void()>& buildFunc, const MenuParam& menuParam, std::function<void()>& previewBuildFunc)
186 {
187 auto targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
188 CHECK_NULL_VOID(targetNode);
189 ACE_UPDATE_LAYOUT_PROPERTY(LayoutProperty, IsBindOverlay, true);
190 auto targetId = targetNode->GetId();
191 auto subwindow = SubwindowManager::GetInstance()->GetSubwindow(Container::CurrentId());
192 if (subwindow) {
193 auto childContainerId = subwindow->GetChildContainerId();
194 auto childContainer = AceEngine::Get().GetContainer(childContainerId);
195 CHECK_NULL_VOID(childContainer);
196 auto pipeline = AceType::DynamicCast<NG::PipelineContext>(childContainer->GetPipelineContext());
197 CHECK_NULL_VOID(pipeline);
198 auto overlayManager = pipeline->GetOverlayManager();
199 CHECK_NULL_VOID(overlayManager);
200 auto menuNode = overlayManager->GetMenuNode(targetId);
201 if (menuNode) {
202 TAG_LOGI(AceLogTag::ACE_OVERLAY, "menuNode already exist");
203 auto wrapperPattern = menuNode->GetPattern<MenuWrapperPattern>();
204 CHECK_NULL_VOID(wrapperPattern);
205 // If menu is shown or in show animation, set isShow to false will close menu. If menu is not shown or
206 // in close animation, wrapperPattern->IsShow() is false, set isShow to false will not trigger close again.
207 if (wrapperPattern->IsShow() && !menuParam.isShow) {
208 SubwindowManager::GetInstance()->HideMenuNG(menuNode, targetId);
209 UpdateIsShowStatusForMenu(targetId, false);
210 } else if (!wrapperPattern->IsShow() && menuParam.isShow &&
211 wrapperPattern->GetIsShowFromUser() != menuParam.isShow) {
212 // If click outside to close menu during show animation, and isShow is always true without changing,
213 // then show new menu will result in an incorrect isShow state because onDisappear not be triggered.
214 // The menu only show if isShow is manually set from false to true.
215 CreateCustomMenuWithPreview(buildFunc, menuParam, previewBuildFunc);
216 UpdateIsShowStatusForMenu(targetId, true);
217 }
218 } else if (menuParam.isShow && buildFunc) {
219 CreateCustomMenuWithPreview(buildFunc, menuParam, previewBuildFunc);
220 UpdateIsShowStatusForMenu(targetId, true);
221 }
222 } else {
223 // first response for build subwindow and menu
224 if (menuParam.isShow && buildFunc) {
225 CreateCustomMenuWithPreview(buildFunc, menuParam, previewBuildFunc);
226 UpdateIsShowStatusForMenu(targetId, true);
227 }
228 }
229 }
230
BindContextMenu(ResponseType type,std::function<void ()> & buildFunc,const MenuParam & menuParam,std::function<void ()> & previewBuildFunc)231 void ViewAbstractModelNG::BindContextMenu(ResponseType type, std::function<void()>& buildFunc,
232 const MenuParam& menuParam, std::function<void()>& previewBuildFunc)
233 {
234 auto targetNode = AceType::Claim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
235 CHECK_NULL_VOID(targetNode);
236 auto targetId = targetNode->GetId();
237 auto subwindow = SubwindowManager::GetInstance()->GetSubwindow(Container::CurrentId());
238 if (subwindow) {
239 auto childContainerId = subwindow->GetChildContainerId();
240 auto childContainer = AceEngine::Get().GetContainer(childContainerId);
241 CHECK_NULL_VOID(childContainer);
242 auto pipeline = AceType::DynamicCast<NG::PipelineContext>(childContainer->GetPipelineContext());
243 CHECK_NULL_VOID(pipeline);
244 auto overlayManager = pipeline->GetOverlayManager();
245 CHECK_NULL_VOID(overlayManager);
246 auto menuNode = overlayManager->GetMenuNode(targetId);
247 if (menuNode) {
248 TAG_LOGI(AceLogTag::ACE_OVERLAY, "menuNode already exist");
249 auto menuWrapperPattern = menuNode->GetPattern<NG::MenuWrapperPattern>();
250 CHECK_NULL_VOID(menuWrapperPattern);
251 menuWrapperPattern->SetMenuTransitionEffect(menuNode, menuParam);
252 }
253 }
254 if (menuParam.contextMenuRegisterType == ContextMenuRegisterType::CUSTOM_TYPE) {
255 BindContextMenuSingle(buildFunc, menuParam, previewBuildFunc);
256 } else {
257 auto hub = targetNode->GetOrCreateGestureEventHub();
258 CHECK_NULL_VOID(hub);
259 auto weakTarget = AceType::WeakClaim(AceType::RawPtr(targetNode));
260 if (type == ResponseType::RIGHT_CLICK) {
261 OnMouseEventFunc event = [builderF = buildFunc, weakTarget, menuParam](MouseInfo& info) mutable {
262 TAG_LOGI(AceLogTag::ACE_MENU, "Execute rightClick task for menu");
263 auto containerId = Container::CurrentId();
264 auto taskExecutor = Container::CurrentTaskExecutor();
265 CHECK_NULL_VOID(taskExecutor);
266 if (info.GetButton() == MouseButton::RIGHT_BUTTON && info.GetAction() == MouseAction::RELEASE) {
267 info.SetStopPropagation(true);
268 }
269 taskExecutor->PostTask(
270 [containerId, builder = builderF, weakTarget, menuParam, info]() mutable {
271 auto targetNode = weakTarget.Upgrade();
272 CHECK_NULL_VOID(targetNode);
273 NG::OffsetF menuPosition { info.GetGlobalLocation().GetX() + menuParam.positionOffset.GetX(),
274 info.GetGlobalLocation().GetY() + menuParam.positionOffset.GetY() };
275 auto pipelineContext = NG::PipelineContext::GetCurrentContext();
276 CHECK_NULL_VOID(pipelineContext);
277 auto windowRect = pipelineContext->GetDisplayWindowRectInfo();
278 menuPosition += NG::OffsetF { windowRect.Left(), windowRect.Top() };
279 if (info.GetButton() == MouseButton::RIGHT_BUTTON && info.GetAction() == MouseAction::RELEASE) {
280 std::function<void()> previewBuildFunc;
281 NG::ViewAbstract::BindMenuWithCustomNode(
282 std::move(builder), targetNode, menuPosition, menuParam, std::move(previewBuildFunc));
283 }
284 },
285 TaskExecutor::TaskType::PLATFORM, "ArkUIRightClickCreateCustomMenu");
286 };
287 auto inputHub = targetNode->GetOrCreateInputEventHub();
288 CHECK_NULL_VOID(inputHub);
289 inputHub->BindContextMenu(std::move(event));
290 } else if (type == ResponseType::LONG_PRESS) {
291 auto gestureHub = targetNode->GetEventHub<EventHub>()->GetGestureEventHub();
292 CHECK_NULL_VOID(gestureHub);
293 gestureHub->SetPreviewMode(menuParam.previewMode);
294 // create or show menu on long press
295 auto event =
296 [builderF = buildFunc, weakTarget, menuParam, previewBuildFunc](const GestureEvent& info) mutable {
297 TAG_LOGI(AceLogTag::ACE_MENU, "Trigger longPress event for menu");
298 auto taskExecutor = Container::CurrentTaskExecutor();
299 CHECK_NULL_VOID(taskExecutor);
300 taskExecutor->PostTask(
301 [builder = builderF, weakTarget, menuParam, previewBuildFunc, info]() mutable {
302 TAG_LOGI(AceLogTag::ACE_MENU, "Execute longPress task for menu");
303 auto targetNode = weakTarget.Upgrade();
304 CHECK_NULL_VOID(targetNode);
305 auto pipelineContext = NG::PipelineContext::GetCurrentContext();
306 CHECK_NULL_VOID(pipelineContext);
307 auto dragDropManager = pipelineContext->GetDragDropManager();
308 CHECK_NULL_VOID(dragDropManager);
309 if (dragDropManager->IsAboutToPreview() || dragDropManager->IsDragging()) {
310 TAG_LOGI(AceLogTag::ACE_DRAG, "Drag is in progress, return");
311 return;
312 }
313 if (menuParam.previewMode == MenuPreviewMode::IMAGE || menuParam.isShowHoverImage) {
314 auto context = targetNode->GetRenderContext();
315 CHECK_NULL_VOID(context);
316 auto gestureHub = targetNode->GetEventHub<EventHub>()->GetGestureEventHub();
317 CHECK_NULL_VOID(gestureHub);
318 auto pixelMap = context->GetThumbnailPixelMap();
319 gestureHub->SetPixelMap(pixelMap);
320 }
321 NG::OffsetF menuPosition { info.GetGlobalLocation().GetX() + menuParam.positionOffset.GetX(),
322 info.GetGlobalLocation().GetY() + menuParam.positionOffset.GetY() };
323 auto windowRect = pipelineContext->GetDisplayWindowRectInfo();
324 menuPosition += NG::OffsetF { windowRect.Left(), windowRect.Top() };
325 NG::ViewAbstract::BindMenuWithCustomNode(
326 std::move(builder), targetNode, menuPosition, menuParam, std::move(previewBuildFunc));
327 },
328 TaskExecutor::TaskType::PLATFORM, "ArkUILongPressCreateCustomMenu");
329 };
330 auto longPress = AceType::MakeRefPtr<NG::LongPressEvent>(std::move(event));
331 ACE_UPDATE_LAYOUT_PROPERTY(LayoutProperty, IsBindOverlay, true);
332 auto longPressDuration = menuParam.isShowHoverImage ? HOVER_IMAGE_LONG_PRESS_DURATION : LONG_PRESS_DURATION;
333 hub->SetLongPressEvent(longPress, false, true, longPressDuration);
334 } else {
335 return;
336 }
337 RegisterContextMenuKeyEvent(targetNode, buildFunc, menuParam);
338 }
339
340 // delete menu when target node destroy
341 auto destructor = [id = targetNode->GetId(), containerId = Container::CurrentId()]() {
342 auto subwindow = SubwindowManager::GetInstance()->GetSubwindow(containerId);
343 CHECK_NULL_VOID(subwindow);
344 auto childContainerId = subwindow->GetChildContainerId();
345 auto childContainer = AceEngine::Get().GetContainer(childContainerId);
346 CHECK_NULL_VOID(childContainer);
347 auto pipeline = AceType::DynamicCast<NG::PipelineContext>(childContainer->GetPipelineContext());
348 CHECK_NULL_VOID(pipeline);
349 auto overlayManager = pipeline->GetOverlayManager();
350 CHECK_NULL_VOID(overlayManager);
351 overlayManager->DeleteMenu(id);
352 };
353 targetNode->PushDestroyCallbackWithTag(destructor, KEY_CONTEXT_MENU);
354 }
355
BindDragWithContextMenuParams(const NG::MenuParam & menuParam)356 void ViewAbstractModelNG::BindDragWithContextMenuParams(const NG::MenuParam& menuParam)
357 {
358 auto targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
359 CHECK_NULL_VOID(targetNode);
360
361 auto gestureHub = targetNode->GetOrCreateGestureEventHub();
362 if (gestureHub) {
363 if (menuParam.contextMenuRegisterType == ContextMenuRegisterType::CUSTOM_TYPE) {
364 gestureHub->SetBindMenuStatus(true, menuParam.isShow, menuParam.previewMode);
365 } else if (menuParam.menuBindType == MenuBindingType::LONG_PRESS) {
366 gestureHub->SetBindMenuStatus(false, false, menuParam.previewMode);
367 }
368 gestureHub->SetPreviewMode(menuParam.previewMode);
369 gestureHub->SetContextMenuShowStatus(menuParam.isShow);
370 gestureHub->SetMenuBindingType(menuParam.menuBindType);
371 // set menu preview scale to drag.
372 if (menuParam.menuBindType != MenuBindingType::RIGHT_CLICK) {
373 auto menuPreviewScale = LessOrEqual(menuParam.previewAnimationOptions.scaleTo, 0.0)
374 ? DEFALUT_DRAG_PPIXELMAP_SCALE
375 : menuParam.previewAnimationOptions.scaleTo;
376 gestureHub->SetMenuPreviewScale(menuPreviewScale);
377 }
378 } else {
379 TAG_LOGW(AceLogTag::ACE_DRAG, "Can not get gestureEventHub!");
380 }
381 }
BindBackground(std::function<void ()> && buildFunc,const Alignment & align)382 void ViewAbstractModelNG::BindBackground(std::function<void()>&& buildFunc, const Alignment& align)
383 {
384 auto buildNodeFunc = [buildFunc = std::move(buildFunc)]() -> RefPtr<UINode> {
385 NG::ScopedViewStackProcessor builderViewStackProcessor;
386 buildFunc();
387 auto customNode = NG::ViewStackProcessor::GetInstance()->Finish();
388 return customNode;
389 };
390 auto targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
391 CHECK_NULL_VOID(targetNode);
392 targetNode->SetBackgroundFunction(std::move(buildNodeFunc));
393 NG::ViewAbstract::SetBackgroundAlign(align);
394 }
395
SetPivot(const Dimension & x,const Dimension & y,const Dimension & z)396 void ViewAbstractModelNG::SetPivot(const Dimension& x, const Dimension& y, const Dimension& z)
397 {
398 DimensionOffset center(x, y);
399 if (!NearZero(z.Value())) {
400 center.SetZ(z);
401 }
402 ViewAbstract::SetPivot(center);
403 }
404
SetScale(float x,float y,float z)405 void ViewAbstractModelNG::SetScale(float x, float y, float z)
406 {
407 VectorF scale(x, y);
408 ViewAbstract::SetScale(scale);
409 }
410
BindContentCover(bool isShow,std::function<void (const std::string &)> && callback,std::function<void ()> && buildFunc,NG::ModalStyle & modalStyle,std::function<void ()> && onAppear,std::function<void ()> && onDisappear,std::function<void ()> && onWillAppear,std::function<void ()> && onWillDisappear,const NG::ContentCoverParam & contentCoverParam)411 void ViewAbstractModelNG::BindContentCover(bool isShow, std::function<void(const std::string&)>&& callback,
412 std::function<void()>&& buildFunc, NG::ModalStyle& modalStyle, std::function<void()>&& onAppear,
413 std::function<void()>&& onDisappear, std::function<void()>&& onWillAppear, std::function<void()>&& onWillDisappear,
414 const NG::ContentCoverParam& contentCoverParam)
415 {
416 auto targetNode = AceType::Claim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
417 CHECK_NULL_VOID(targetNode);
418 auto buildNodeFunc = [buildFunc]() -> RefPtr<UINode> {
419 NG::ScopedViewStackProcessor builderViewStackProcessor;
420 buildFunc();
421 auto customNode = NG::ViewStackProcessor::GetInstance()->Finish();
422 return customNode;
423 };
424 auto context = PipelineContext::GetCurrentContext();
425 CHECK_NULL_VOID(context);
426 auto overlayManager = context->GetOverlayManager();
427 CHECK_NULL_VOID(overlayManager);
428
429 // delete full screen modal when target node destroy
430 auto destructor = [id = targetNode->GetId()]() {
431 auto pipeline = NG::PipelineContext::GetCurrentContext();
432 CHECK_NULL_VOID(pipeline);
433 auto overlayManager = pipeline->GetOverlayManager();
434 CHECK_NULL_VOID(overlayManager);
435 overlayManager->DeleteModal(id);
436 };
437 targetNode->PushDestroyCallback(destructor);
438
439 overlayManager->BindContentCover(isShow, std::move(callback), std::move(buildNodeFunc), modalStyle,
440 std::move(onAppear), std::move(onDisappear), std::move(onWillAppear), std::move(onWillDisappear),
441 contentCoverParam, targetNode);
442 }
443
RegisterContextMenuKeyEvent(const RefPtr<FrameNode> & targetNode,std::function<void ()> & buildFunc,const MenuParam & menuParam)444 void ViewAbstractModelNG::RegisterContextMenuKeyEvent(
445 const RefPtr<FrameNode>& targetNode, std::function<void()>& buildFunc, const MenuParam& menuParam)
446 {
447 auto focusHub = targetNode->GetOrCreateFocusHub();
448 CHECK_NULL_VOID(focusHub);
449 auto onKeyEvent = [wp = AceType::WeakClaim(AceType::RawPtr(targetNode)), builder = buildFunc, param = menuParam](
450 const KeyEvent& event) mutable -> bool {
451 if (event.action != KeyAction::DOWN) {
452 return false;
453 }
454 if (event.code == KeyCode::KEY_MENU || event.keyIntention == KeyIntention::INTENTION_MENU) {
455 auto targetNode = wp.Upgrade();
456 CHECK_NULL_RETURN(targetNode, false);
457 if (!param.placement.has_value()) {
458 param.placement = Placement::BOTTOM_LEFT;
459 }
460 std::function<void()> previewBuildFunc = nullptr;
461 NG::ViewAbstract::BindMenuWithCustomNode(
462 std::move(builder), targetNode, OffsetF(), param, std::move(previewBuildFunc));
463 return true;
464 }
465 return false;
466 };
467 focusHub->SetOnKeyEventInternal(std::move(onKeyEvent), OnKeyEventType::CONTEXT_MENU);
468 }
469
GetSheetContext(NG::SheetStyle & sheetStyle)470 RefPtr<PipelineContext> ViewAbstractModelNG::GetSheetContext(NG::SheetStyle& sheetStyle)
471 {
472 RefPtr<PipelineContext> context;
473 if (sheetStyle.instanceId.has_value()) {
474 TAG_LOGD(AceLogTag::ACE_SHEET, "Sheet uiContext id is: %{public}d", sheetStyle.instanceId.value());
475 auto container = AceEngine::Get().GetContainer(sheetStyle.instanceId.value());
476 CHECK_NULL_RETURN(container, nullptr);
477 auto contextBase = container->GetPipelineContext();
478 CHECK_NULL_RETURN(contextBase, nullptr);
479 context = AceType::DynamicCast<PipelineContext>(contextBase);
480 } else {
481 context = PipelineContext::GetCurrentContext();
482 }
483 return context;
484 }
485
BindSheet(bool isShow,std::function<void (const std::string &)> && callback,std::function<void ()> && buildFunc,std::function<void ()> && titleBuildFunc,NG::SheetStyle & sheetStyle,std::function<void ()> && onAppear,std::function<void ()> && onDisappear,std::function<void ()> && shouldDismiss,std::function<void (const int32_t info)> && onWillDismiss,std::function<void ()> && onWillAppear,std::function<void ()> && onWillDisappear,std::function<void (const float)> && onHeightDidChange,std::function<void (const float)> && onDetentsDidChange,std::function<void (const float)> && onWidthDidChange,std::function<void (const float)> && onTypeDidChange,std::function<void ()> && sheetSpringBack)486 void ViewAbstractModelNG::BindSheet(bool isShow, std::function<void(const std::string&)>&& callback,
487 std::function<void()>&& buildFunc, std::function<void()>&& titleBuildFunc, NG::SheetStyle& sheetStyle,
488 std::function<void()>&& onAppear, std::function<void()>&& onDisappear, std::function<void()>&& shouldDismiss,
489 std::function<void(const int32_t info)>&& onWillDismiss, std::function<void()>&& onWillAppear,
490 std::function<void()>&& onWillDisappear, std::function<void(const float)>&& onHeightDidChange,
491 std::function<void(const float)>&& onDetentsDidChange, std::function<void(const float)>&& onWidthDidChange,
492 std::function<void(const float)>&& onTypeDidChange, std::function<void()>&& sheetSpringBack)
493 {
494 auto targetNode = AceType::Claim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
495 CHECK_NULL_VOID(targetNode);
496 auto instanceId = sheetStyle.instanceId.has_value() ? sheetStyle.instanceId.value() : Container::CurrentId();
497 auto buildNodeFunc = [buildFunc, instanceId]() -> RefPtr<UINode> {
498 NG::ScopedViewStackProcessor builderViewStackProcess(instanceId);
499 buildFunc();
500 auto customNode = NG::ViewStackProcessor::GetInstance()->Finish();
501 return customNode;
502 };
503 auto buildTitleNodeFunc = [titleBuildFunc, instanceId]() -> RefPtr<UINode> {
504 CHECK_NULL_RETURN(titleBuildFunc, nullptr);
505 NG::ScopedViewStackProcessor builderViewStackProcess(instanceId);
506 titleBuildFunc();
507 auto customNode = NG::ViewStackProcessor::GetInstance()->Finish();
508 return customNode;
509 };
510 auto context = GetSheetContext(sheetStyle);
511 CHECK_NULL_VOID(context);
512 auto overlayManager = context->GetOverlayManager();
513 if (sheetStyle.showInPage.value_or(false)) {
514 overlayManager = SheetManager::FindPageNodeOverlay(targetNode, isShow);
515 }
516 CHECK_NULL_VOID(overlayManager);
517
518 // delete Sheet when target node destroy
519 auto destructor = [id = targetNode->GetId(), rootNodeId = targetNode->GetRootNodeId(),
520 rootNodeType = targetNode->GetRootNodeType(),
521 showInPage = sheetStyle.showInPage.value_or(false), instanceId]() {
522 ContainerScope scope(instanceId);
523 auto pipeline = NG::PipelineContext::GetCurrentContext();
524 CHECK_NULL_VOID(pipeline);
525 auto overlayManager = pipeline->GetOverlayManager();
526 if (showInPage) {
527 TAG_LOGD(AceLogTag::ACE_SHEET, "To showInPage, get overlayManager from GetOverlayFromPage");
528 overlayManager = SheetManager::GetOverlayFromPage(rootNodeId, rootNodeType);
529 }
530 CHECK_NULL_VOID(overlayManager);
531 overlayManager->DeleteModal(id);
532 SheetManager::GetInstance().DeleteOverlayForWindowScene(rootNodeId, rootNodeType);
533 };
534 targetNode->PushDestroyCallback(destructor);
535
536 overlayManager->BindSheet(isShow, std::move(callback), std::move(buildNodeFunc), std::move(buildTitleNodeFunc),
537 sheetStyle, std::move(onAppear), std::move(onDisappear), std::move(shouldDismiss), std::move(onWillDismiss),
538 std::move(onWillAppear), std::move(onWillDisappear), std::move(onHeightDidChange),
539 std::move(onDetentsDidChange), std::move(onWidthDidChange), std::move(onTypeDidChange),
540 std::move(sheetSpringBack), targetNode);
541 }
542
DismissSheet()543 void ViewAbstractModelNG::DismissSheet()
544 {
545 auto sheetId = SheetManager::GetInstance().GetDismissSheet();
546 if (sheetId == -1) {
547 TAG_LOGE(AceLogTag::ACE_SHEET, "Sheet Dismiss Id Invalid");
548 return;
549 }
550 auto sheet = FrameNode::GetFrameNode(V2::SHEET_PAGE_TAG, sheetId);
551 CHECK_NULL_VOID(sheet);
552 auto sheetPattern = sheet->GetPattern<SheetPresentationPattern>();
553 CHECK_NULL_VOID(sheetPattern);
554 sheetPattern->OverlayDismissSheet();
555 }
556
DismissContentCover()557 void ViewAbstractModelNG::DismissContentCover()
558 {
559 auto context = PipelineContext::GetCurrentContext();
560 CHECK_NULL_VOID(context);
561 auto overlayManager = context->GetOverlayManager();
562 CHECK_NULL_VOID(overlayManager);
563 overlayManager->DismissContentCover();
564 }
565
SheetSpringBack()566 void ViewAbstractModelNG::SheetSpringBack()
567 {
568 auto sheetId = SheetManager::GetInstance().GetDismissSheet();
569 if (sheetId == -1) {
570 TAG_LOGE(AceLogTag::ACE_SHEET, "Sheet SpringBack Id Invalid");
571 return;
572 }
573 auto sheet = FrameNode::GetFrameNode(V2::SHEET_PAGE_TAG, sheetId);
574 CHECK_NULL_VOID(sheet);
575 auto sheetPattern = sheet->GetPattern<SheetPresentationPattern>();
576 CHECK_NULL_VOID(sheetPattern);
577 sheetPattern->OverlaySheetSpringBack();
578 }
579
SetAccessibilityGroup(bool accessible)580 void ViewAbstractModelNG::SetAccessibilityGroup(bool accessible)
581 {
582 auto frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
583 CHECK_NULL_VOID(frameNode);
584 auto accessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
585 CHECK_NULL_VOID(accessibilityProperty);
586 accessibilityProperty->SetAccessibilityGroup(accessible);
587 }
588
SetAccessibilityTextPreferred(bool accessibilityTextPreferred)589 void ViewAbstractModelNG::SetAccessibilityTextPreferred(bool accessibilityTextPreferred)
590 {
591 auto frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
592 CHECK_NULL_VOID(frameNode);
593 auto accessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
594 CHECK_NULL_VOID(accessibilityProperty);
595 accessibilityProperty->SetAccessibilityTextPreferred(accessibilityTextPreferred);
596 }
597
SetAccessibilityText(const std::string & text)598 void ViewAbstractModelNG::SetAccessibilityText(const std::string& text)
599 {
600 auto frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
601 CHECK_NULL_VOID(frameNode);
602 auto accessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
603 CHECK_NULL_VOID(accessibilityProperty);
604 accessibilityProperty->SetAccessibilityTextWithEvent(text);
605 }
606
SetAccessibilityTextHint(const std::string & text)607 void ViewAbstractModelNG::SetAccessibilityTextHint(const std::string& text)
608 {
609 auto frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
610 CHECK_NULL_VOID(frameNode);
611 auto accessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
612 CHECK_NULL_VOID(accessibilityProperty);
613 accessibilityProperty->SetAccessibilityTextHint(text);
614 }
615
SetAccessibilityDescription(const std::string & description)616 void ViewAbstractModelNG::SetAccessibilityDescription(const std::string& description)
617 {
618 auto frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
619 CHECK_NULL_VOID(frameNode);
620 auto accessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
621 CHECK_NULL_VOID(accessibilityProperty);
622 accessibilityProperty->SetAccessibilityDescriptionWithEvent(description);
623 }
624
SetAccessibilityImportance(const std::string & importance)625 void ViewAbstractModelNG::SetAccessibilityImportance(const std::string& importance)
626 {
627 auto frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
628 CHECK_NULL_VOID(frameNode);
629 auto accessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
630 CHECK_NULL_VOID(accessibilityProperty);
631 accessibilityProperty->SetAccessibilityLevel(importance);
632 }
633
SetAccessibilityText(FrameNode * frameNode,const std::string & text)634 void ViewAbstractModelNG::SetAccessibilityText(FrameNode* frameNode, const std::string& text)
635 {
636 CHECK_NULL_VOID(frameNode);
637 auto accessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
638 CHECK_NULL_VOID(accessibilityProperty);
639 accessibilityProperty->SetAccessibilityTextWithEvent(text);
640 }
641
SetAccessibilityImportance(FrameNode * frameNode,const std::string & importance)642 void ViewAbstractModelNG::SetAccessibilityImportance(FrameNode* frameNode, const std::string& importance)
643 {
644 CHECK_NULL_VOID(frameNode);
645 auto accessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
646 CHECK_NULL_VOID(accessibilityProperty);
647 accessibilityProperty->SetAccessibilityLevel(importance);
648 }
649
SetAccessibilityVirtualNode(std::function<void ()> && buildFunc)650 void ViewAbstractModelNG::SetAccessibilityVirtualNode(std::function<void()>&& buildFunc)
651 {
652 auto buildNodeFunc = [buildFunc = std::move(buildFunc)]() -> RefPtr<UINode> {
653 NG::ScopedViewStackProcessor builderViewStackProcessor;
654 buildFunc();
655 auto customNode = NG::ViewStackProcessor::GetInstance()->Finish();
656 return customNode;
657 };
658 auto frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
659 CHECK_NULL_VOID(frameNode);
660 auto virtualNode = buildNodeFunc();
661 auto accessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
662 CHECK_NULL_VOID(accessibilityProperty);
663 auto virtualFrameNode = AceType::DynamicCast<NG::FrameNode>(virtualNode);
664 CHECK_NULL_VOID(virtualFrameNode);
665 virtualFrameNode->SetAccessibilityNodeVirtual();
666 virtualFrameNode->SetAccessibilityVirtualNodeParent(AceType::Claim(AceType::DynamicCast<NG::UINode>(frameNode)));
667 virtualFrameNode->SetFirstAccessibilityVirtualNode();
668 frameNode->HasAccessibilityVirtualNode(true);
669 accessibilityProperty->SaveAccessibilityVirtualNode(virtualNode);
670 }
671
SetAccessibilitySelected(bool selected,bool resetValue)672 void ViewAbstractModelNG::SetAccessibilitySelected(bool selected, bool resetValue)
673 {
674 auto frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
675 CHECK_NULL_VOID(frameNode);
676 auto accessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
677 CHECK_NULL_VOID(accessibilityProperty);
678 if (resetValue == true) {
679 accessibilityProperty->ResetUserSelected();
680 } else {
681 accessibilityProperty->SetUserSelected(selected);
682 }
683 }
684
SetAccessibilityChecked(bool checked,bool resetValue)685 void ViewAbstractModelNG::SetAccessibilityChecked(bool checked, bool resetValue)
686 {
687 auto frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
688 CHECK_NULL_VOID(frameNode);
689 auto accessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
690 CHECK_NULL_VOID(accessibilityProperty);
691 if (resetValue == true) {
692 accessibilityProperty->ResetUserCheckedType();
693 accessibilityProperty->ResetUserCheckable();
694 } else {
695 accessibilityProperty->SetUserCheckedType(checked);
696 accessibilityProperty->SetUserCheckable(true);
697 }
698 }
699
SetAccessibilityDescription(FrameNode * frameNode,const std::string & description)700 void ViewAbstractModelNG::SetAccessibilityDescription(FrameNode* frameNode, const std::string& description)
701 {
702 CHECK_NULL_VOID(frameNode);
703 auto accessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
704 CHECK_NULL_VOID(accessibilityProperty);
705 accessibilityProperty->SetAccessibilityDescriptionWithEvent(description);
706 }
707
SetAccessibilityGroup(FrameNode * frameNode,bool accessible)708 void ViewAbstractModelNG::SetAccessibilityGroup(FrameNode* frameNode, bool accessible)
709 {
710 CHECK_NULL_VOID(frameNode);
711 auto accessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
712 CHECK_NULL_VOID(accessibilityProperty);
713 accessibilityProperty->SetAccessibilityGroup(accessible);
714 }
715
SetAccessibilityTextPreferred(FrameNode * frameNode,bool accessibilityTextPreferred)716 void ViewAbstractModelNG::SetAccessibilityTextPreferred(FrameNode* frameNode, bool accessibilityTextPreferred)
717 {
718 CHECK_NULL_VOID(frameNode);
719 auto accessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
720 CHECK_NULL_VOID(accessibilityProperty);
721 accessibilityProperty->SetAccessibilityTextPreferred(accessibilityTextPreferred);
722 }
723
GetAccessibilityGroup(FrameNode * frameNode)724 bool ViewAbstractModelNG::GetAccessibilityGroup(FrameNode* frameNode)
725 {
726 CHECK_NULL_RETURN(frameNode, false);
727 auto accessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
728 CHECK_NULL_RETURN(accessibilityProperty, false);
729 return accessibilityProperty->IsAccessibilityGroup();
730 }
731
GetAccessibilityText(FrameNode * frameNode)732 std::string ViewAbstractModelNG::GetAccessibilityText(FrameNode* frameNode)
733 {
734 CHECK_NULL_RETURN(frameNode, "");
735 auto accessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
736 CHECK_NULL_RETURN(accessibilityProperty, "");
737 return accessibilityProperty->GetAccessibilityText();
738 }
739
GetAccessibilityDescription(FrameNode * frameNode)740 std::string ViewAbstractModelNG::GetAccessibilityDescription(FrameNode* frameNode)
741 {
742 CHECK_NULL_RETURN(frameNode, "");
743 auto accessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
744 CHECK_NULL_RETURN(accessibilityProperty, "");
745 return accessibilityProperty->GetAccessibilityDescription();
746 }
747
GetAccessibilityImportance(FrameNode * frameNode)748 std::string ViewAbstractModelNG::GetAccessibilityImportance(FrameNode* frameNode)
749 {
750 CHECK_NULL_RETURN(frameNode, "");
751 auto accessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
752 CHECK_NULL_RETURN(accessibilityProperty, "");
753 return accessibilityProperty->GetAccessibilityLevel();
754 }
755
SetAccessibilitySelected(FrameNode * frameNode,bool selected,bool resetValue)756 void ViewAbstractModelNG::SetAccessibilitySelected(FrameNode* frameNode, bool selected, bool resetValue)
757 {
758 CHECK_NULL_VOID(frameNode);
759 auto accessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
760 CHECK_NULL_VOID(accessibilityProperty);
761 if (resetValue == true) {
762 accessibilityProperty->ResetUserSelected();
763 } else {
764 accessibilityProperty->SetUserSelected(selected);
765 }
766 }
767
SetAccessibilityChecked(FrameNode * frameNode,bool checked,bool resetValue)768 void ViewAbstractModelNG::SetAccessibilityChecked(FrameNode* frameNode, bool checked, bool resetValue)
769 {
770 CHECK_NULL_VOID(frameNode);
771 auto accessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
772 CHECK_NULL_VOID(accessibilityProperty);
773 if (resetValue == true) {
774 accessibilityProperty->ResetUserCheckedType();
775 accessibilityProperty->ResetUserCheckable();
776 } else {
777 accessibilityProperty->SetUserCheckedType(checked);
778 accessibilityProperty->SetUserCheckable(true);
779 }
780 }
781
782 } // namespace OHOS::Ace::NG
783