1 /*
2 * Copyright (c) 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 #include "core/components_ng/pattern/dialog/custom_dialog_controller_model_ng.h"
16
17 #include "base/memory/ace_type.h"
18 #include "base/subwindow/subwindow_manager.h"
19 #include "base/thread/task_executor.h"
20 #include "core/common/container_scope.h"
21
22 namespace OHOS::Ace::NG {
SetOpenDialog(DialogProperties & dialogProperties,const WeakPtr<AceType> & controller,std::vector<WeakPtr<AceType>> & dialogs,bool & pending,bool & isShown,std::function<void ()> && cancelTask,std::function<void ()> && buildFunc,RefPtr<AceType> & dialogComponent,RefPtr<AceType> & customDialog,std::list<DialogOperation> & dialogOperation)23 void CustomDialogControllerModelNG::SetOpenDialog(DialogProperties& dialogProperties,
24 const WeakPtr<AceType>& controller, std::vector<WeakPtr<AceType>>& dialogs,
25 bool& pending, bool& isShown, std::function<void()>&& cancelTask, std::function<void()>&& buildFunc,
26 RefPtr<AceType>& dialogComponent, RefPtr<AceType>& customDialog, std::list<DialogOperation>& dialogOperation)
27 {
28 auto container = Container::Current();
29 auto currentId = Container::CurrentId();
30 CHECK_NULL_VOID(container);
31 if (container->IsSubContainer() && !dialogProperties.isShowInSubWindow) {
32 currentId = SubwindowManager::GetInstance()->GetParentContainerId(Container::CurrentId());
33 container = AceEngine::Get().GetContainer(currentId);
34 CHECK_NULL_VOID(container);
35 }
36 ContainerScope scope(currentId);
37 auto pipelineContext = container->GetPipelineContext();
38 CHECK_NULL_VOID(pipelineContext);
39 auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
40 CHECK_NULL_VOID(context);
41 auto overlayManager = context->GetOverlayManager();
42 CHECK_NULL_VOID(overlayManager);
43
44 dialogProperties.onStatusChanged = [&isShown](bool isShownStatus) {
45 if (!isShownStatus) {
46 isShown = isShownStatus;
47 }
48 };
49
50 auto executor = context->GetTaskExecutor();
51 if (!executor) {
52 TAG_LOGE(AceLogTag::ACE_DIALOG, "Task executor is null.");
53 return;
54 }
55 auto task = [currentId, controller, &dialogProperties, &dialogs, func = std::move(buildFunc),
56 weakOverlayManager = AceType::WeakClaim(AceType::RawPtr(overlayManager))]() mutable {
57 ContainerScope scope(currentId);
58 RefPtr<NG::FrameNode> dialog;
59 auto overlayManager = weakOverlayManager.Upgrade();
60 CHECK_NULL_VOID(overlayManager);
61 auto controllerPtr = controller.Upgrade();
62 CHECK_NULL_VOID(controllerPtr);
63 auto container = Container::Current();
64 CHECK_NULL_VOID(container);
65 if (dialogProperties.isShowInSubWindow) {
66 dialog = SubwindowManager::GetInstance()->ShowDialogNG(dialogProperties, std::move(func));
67 CHECK_NULL_VOID(dialog);
68 if (dialogProperties.isModal && !dialogProperties.isScenceBoardDialog &&
69 !container->IsUIExtensionWindow()) {
70 auto mask = overlayManager->SetDialogMask(dialogProperties);
71 CHECK_NULL_VOID(mask);
72 overlayManager->SetMaskNodeId(dialog->GetId(), mask->GetId());
73 }
74 } else {
75 dialog = overlayManager->ShowDialog(dialogProperties, std::move(func), false);
76 }
77 CHECK_NULL_VOID(dialog);
78 dialogs.emplace_back(dialog);
79 };
80 executor->PostTask(task, TaskExecutor::TaskType::UI, "ArkUIDialogShowCustomDialog");
81 }
82
SetOpenDialogWithNode(DialogProperties & dialogProperties,const RefPtr<UINode> & customNode)83 RefPtr<UINode> CustomDialogControllerModelNG::SetOpenDialogWithNode(DialogProperties& dialogProperties,
84 const RefPtr<UINode>& customNode)
85 {
86 ContainerScope scope(Container::CurrentIdSafely());
87 auto container = Container::Current();
88 CHECK_NULL_RETURN(container, nullptr);
89 if (container->IsSubContainer() && !dialogProperties.isShowInSubWindow) {
90 auto currentId = SubwindowManager::GetInstance()->GetParentContainerId(Container::CurrentId());
91 container = AceEngine::Get().GetContainer(currentId);
92 CHECK_NULL_RETURN(container, nullptr);
93 }
94 auto pipelineContext = container->GetPipelineContext();
95 CHECK_NULL_RETURN(pipelineContext, nullptr);
96 auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
97 CHECK_NULL_RETURN(context, nullptr);
98 auto overlayManager = context->GetOverlayManager();
99 CHECK_NULL_RETURN(overlayManager, nullptr);
100 RefPtr<NG::FrameNode> dialog;
101 if (dialogProperties.isShowInSubWindow) {
102 dialog = SubwindowManager::GetInstance()->ShowDialogNGWithNode(dialogProperties, customNode);
103 if (dialogProperties.isModal && !dialogProperties.isScenceBoardDialog && !container->IsUIExtensionWindow()) {
104 DialogProperties Maskarg;
105 Maskarg.isMask = true;
106 Maskarg.autoCancel = dialogProperties.autoCancel;
107 Maskarg.maskColor = dialogProperties.maskColor;
108 auto mask = overlayManager->ShowDialogWithNode(Maskarg, nullptr, false);
109 CHECK_NULL_RETURN(mask, dialog);
110 overlayManager->SetMaskNodeId(dialog->GetId(), mask->GetId());
111 }
112 } else {
113 dialog = overlayManager->ShowDialogWithNode(dialogProperties, customNode, false);
114 }
115 return dialog;
116 }
117
SetCloseDialog(DialogProperties & dialogProperties,const WeakPtr<AceType> & controller,std::vector<WeakPtr<AceType>> & dialogs,bool & pending,bool & isShown,std::function<void ()> && cancelTask,RefPtr<AceType> & dialogComponent,RefPtr<AceType> & customDialog,std::list<DialogOperation> & dialogOperation)118 void CustomDialogControllerModelNG::SetCloseDialog(DialogProperties& dialogProperties,
119 const WeakPtr<AceType>& controller, std::vector<WeakPtr<AceType>>& dialogs,
120 bool& pending, bool& isShown, std::function<void()>&& cancelTask, RefPtr<AceType>& dialogComponent,
121 RefPtr<AceType>& customDialog, std::list<DialogOperation>& dialogOperation)
122 {
123 auto container = Container::Current();
124 auto currentId = Container::CurrentId();
125 CHECK_NULL_VOID(container);
126 if (container->IsSubContainer() && !dialogProperties.isShowInSubWindow) {
127 currentId = SubwindowManager::GetInstance()->GetParentContainerId(Container::CurrentId());
128 container = AceEngine::Get().GetContainer(currentId);
129 CHECK_NULL_VOID(container);
130 }
131 ContainerScope scope(currentId);
132 auto pipelineContext = container->GetPipelineContext();
133 CHECK_NULL_VOID(pipelineContext);
134 auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
135 CHECK_NULL_VOID(context);
136 auto overlayManager = context->GetOverlayManager();
137 CHECK_NULL_VOID(overlayManager);
138 auto executor = context->GetTaskExecutor();
139 CHECK_NULL_VOID(executor);
140 auto task = [controller, &dialogs, &dialogProperties,
141 weakOverlayManager = AceType::WeakClaim(AceType::RawPtr(overlayManager))]() {
142 auto overlayManager = weakOverlayManager.Upgrade();
143 CHECK_NULL_VOID(overlayManager);
144 auto controllerPtr = controller.Upgrade();
145 CHECK_NULL_VOID(controllerPtr);
146 RefPtr<NG::FrameNode> dialog;
147 while (!dialogs.empty()) {
148 dialog = AceType::DynamicCast<NG::FrameNode>(dialogs.back().Upgrade());
149 if (dialog && !dialog->IsRemoving()) {
150 // get the dialog not removed currently
151 break;
152 }
153 dialogs.pop_back();
154 }
155 if (dialogs.empty()) {
156 return;
157 }
158 CHECK_NULL_VOID(dialog);
159 if (dialogProperties.isShowInSubWindow) {
160 SubwindowManager::GetInstance()->CloseDialogNG(dialog);
161 dialogs.pop_back();
162 } else {
163 overlayManager->CloseDialog(dialog);
164 }
165 };
166 executor->PostTask(task, TaskExecutor::TaskType::UI, "ArkUIDialogCloseCustomDialog");
167 }
168
SetCloseDialogForNDK(FrameNode * dialogNode)169 void CustomDialogControllerModelNG::SetCloseDialogForNDK(FrameNode* dialogNode)
170 {
171 CHECK_NULL_VOID(dialogNode);
172 ContainerScope scope(Container::CurrentIdSafely());
173 auto container = Container::Current();
174 dialogNode->SetIsUseTransitionAnimator(true);
175 CHECK_NULL_VOID(container);
176 auto pipelineContext = container->GetPipelineContext();
177 CHECK_NULL_VOID(pipelineContext);
178 auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
179 CHECK_NULL_VOID(context);
180 auto overlayManager = context->GetOverlayManager();
181 CHECK_NULL_VOID(overlayManager);
182 auto dialogRef = AceType::Claim(dialogNode);
183 overlayManager->CloseDialog(dialogRef);
184 }
185 } // namespace OHOS::Ace::NG
186