1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "core/components/popup/popup_element.h"
17
18 #include "base/subwindow/subwindow_manager.h"
19 #include "base/utils/string_utils.h"
20 #include "core/components/box/render_box.h"
21 #include "core/components/bubble/bubble_component.h"
22 #include "core/components/common/properties/shadow_config.h"
23 #include "core/components/popup/popup_theme.h"
24 #include "core/components/stack/stack_element.h"
25 #include "core/components/tween/tween_component.h"
26
27 namespace OHOS::Ace {
28
PerformBuild()29 void PopupElement::PerformBuild()
30 {
31 RefPtr<PopupComponent> popupComponent = AceType::DynamicCast<PopupComponent>(component_);
32 if (!popupComponent) {
33 return;
34 }
35 popup_ = popupComponent;
36 const auto& popupController = popupComponent->GetPopupController();
37 if (!popupController) {
38 return;
39 }
40 popupController->SetShowPopupImpl([weak = WeakClaim(this)]() {
41 auto popupElement = weak.Upgrade();
42 if (popupElement) {
43 popupElement->ShowPopup();
44 }
45 });
46 popupController->SetCancelPopupImpl([weak = WeakClaim(this)]() {
47 auto popupElement = weak.Upgrade();
48 if (popupElement) {
49 popupElement->CancelPopup(popupElement->GetId());
50 }
51 });
52 }
53
ShowPopupInSubWindow()54 bool PopupElement::ShowPopupInSubWindow()
55 {
56 const auto context = context_.Upgrade();
57 if (!context) {
58 return false;
59 }
60
61 if (!popup_ || popup_->GetPopupParam()->GetTargetId().empty()) {
62 return false;
63 }
64
65 if (!GetThemeManager() || !GetThemeManager()->GetTheme<PopupTheme>()) {
66 return false;
67 }
68
69 auto theme = GetThemeManager()->GetTheme<PopupTheme>();
70 auto showAlphaAnimation = AceType::MakeRefPtr<CurveAnimation<float>>(0.0f, 1.0f, Curves::FAST_OUT_SLOW_IN);
71
72 TweenOption showOption;
73 showOption.SetDuration(theme->GetShowTime());
74 showOption.SetOpacityAnimation(showAlphaAnimation);
75 RefPtr<TweenComponent> tween = AceType::MakeRefPtr<TweenComponent>(popup_->GetId(), popup_->GetId());
76 tween->SetShadow(ShadowConfig::DefaultShadowM);
77 tween->SetIsFirstFrameShow(false);
78 tween->SetAnimationOperation(AnimationOperation::PLAY);
79 tween->SetTweenOption(showOption);
80
81 RefPtr<BubbleComponent> bubble = AceType::MakeRefPtr<BubbleComponent>(popup_->GetChild());
82 bubble->SetPopupParam(popup_->GetPopupParam());
83 bubble->SetId(popup_->GetId());
84 bubble->SetDisabledStatus(popup_->IsDisabledStatus());
85 bubble->SetStateChangeEvent([weak = WeakClaim(this)](bool isVisible) {
86 auto popup = weak.Upgrade();
87 if (popup) {
88 popup->OnStateChange(isVisible);
89 }
90 });
91 tween->SetChild(bubble);
92 SubwindowManager::GetInstance()->ShowPopup(tween, false);
93 weakStack_ = bubble->GetWeakStack();
94 auto stackElement = weakStack_.Upgrade();
95 if (!stackElement) {
96 return false;
97 }
98 return true;
99 }
100
CancelPopupInSubWindow(const ComposeId & id)101 bool PopupElement::CancelPopupInSubWindow(const ComposeId& id)
102 {
103 return SubwindowManager::GetInstance()->CancelPopup(id);
104 }
105
ShowPopup()106 bool PopupElement::ShowPopup()
107 {
108 const auto context = context_.Upgrade();
109 if (!context) {
110 return false;
111 }
112
113 if (!popup_ || popup_->GetPopupParam()->GetTargetId().empty()) {
114 return false;
115 }
116
117 if (!GetThemeManager() || !GetThemeManager()->GetTheme<PopupTheme>()) {
118 return false;
119 }
120
121 auto theme = GetThemeManager()->GetTheme<PopupTheme>();
122 auto showAlphaAnimation = AceType::MakeRefPtr<CurveAnimation<float>>(0.0f, 1.0f, Curves::FAST_OUT_SLOW_IN);
123
124 TweenOption showOption;
125 showOption.SetDuration(theme->GetShowTime());
126 showOption.SetOpacityAnimation(showAlphaAnimation);
127 RefPtr<TweenComponent> tween = AceType::MakeRefPtr<TweenComponent>(popup_->GetId(), popup_->GetId());
128 tween->SetShadow(ShadowConfig::DefaultShadowM);
129 tween->SetIsFirstFrameShow(false);
130 tween->SetAnimationOperation(AnimationOperation::PLAY);
131 tween->SetTweenOption(showOption);
132
133 RefPtr<BubbleComponent> bubble = AceType::MakeRefPtr<BubbleComponent>(popup_->GetChild());
134 bubble->SetPopupParam(popup_->GetPopupParam());
135 bubble->SetId(popup_->GetId());
136 bubble->SetDisabledStatus(popup_->IsDisabledStatus());
137 bubble->SetStateChangeEvent([weak = WeakClaim(this)](bool isVisible) {
138 auto popup = weak.Upgrade();
139 if (popup) {
140 popup->OnStateChange(isVisible);
141 }
142 });
143
144 auto stackElement = context->GetLastStack();
145 if (!stackElement) {
146 return false;
147 }
148 weakStack_ = WeakClaim(RawPtr(stackElement));
149 bubble->SetWeakStack(weakStack_);
150 tween->SetChild(bubble);
151
152 stackElement->PushComponent(tween, false);
153 #if defined(PREVIEW)
154 auto manager = context->GetAccessibilityManager();
155 if (manager) {
156 auto node = manager->GetAccessibilityNodeById(StringUtils::StringToInt(popup_->GetId()));
157 if (!node) {
158 return true;
159 }
160 node->SetZIndexToChild(stackElement->GetChildrenSize());
161 manager->ClearNodeRectInfo(node, false);
162 auto children = node->GetChildList();
163 for (auto& child : children) {
164 child->SetVisible(true);
165 }
166 }
167 #endif
168 return true;
169 }
170
CancelPopup(const ComposeId & id)171 bool PopupElement::CancelPopup(const ComposeId& id)
172 {
173 auto stackElement = weakStack_.Upgrade();
174 if (!stackElement) {
175 return false;
176 }
177 stackElement->PopPopup(id);
178
179 auto context = context_.Upgrade();
180 if (context) {
181 const auto& accessibilityManager = context->GetAccessibilityManager();
182 if (accessibilityManager) {
183 #if !defined(PREVIEW)
184 accessibilityManager->RemoveAccessibilityNodeById(StringUtils::StringToInt(popup_->GetId()));
185 #else
186 auto node = accessibilityManager->GetAccessibilityNodeById(StringUtils::StringToInt(popup_->GetId()));
187 if (!node) {
188 return true;
189 }
190 node->SetZIndexToChild(0);
191 accessibilityManager->ClearNodeRectInfo(node, true);
192 auto children = node->GetChildList();
193 for (auto& child : children) {
194 child->SetVisible(true);
195 }
196 #endif
197 }
198 }
199 return true;
200 }
201
202 } // namespace OHOS::Ace