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