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 "core/components/bubble/bubble_component.h"
20 #include "core/components/common/properties/shadow_config.h"
21 #include "core/components/popup/popup_theme.h"
22 #include "core/components/stack/stack_element.h"
23 #include "core/components/tween/tween_component.h"
24
25 namespace OHOS::Ace {
26
PerformBuild()27 void PopupElement::PerformBuild()
28 {
29 RefPtr<PopupComponent> popupComponent = AceType::DynamicCast<PopupComponent>(component_);
30 if (!popupComponent) {
31 return;
32 }
33 popup_ = popupComponent;
34 const auto& popupController = popupComponent->GetPopupController();
35 if (!popupController) {
36 return;
37 }
38 popupController->SetShowPopupImpl([weak = WeakClaim(this)]() {
39 auto popupElement = weak.Upgrade();
40 if (popupElement) {
41 popupElement->ShowPopup();
42 }
43 });
44 popupController->SetCancelPopupImpl([weak = WeakClaim(this)]() {
45 auto popupElement = weak.Upgrade();
46 if (popupElement) {
47 popupElement->CancelPopup(popupElement->GetId());
48 }
49 });
50 }
51
ShowPopupInSubWindow()52 bool PopupElement::ShowPopupInSubWindow()
53 {
54 const auto context = context_.Upgrade();
55 if (!context) {
56 return false;
57 }
58
59 if (!popup_ || popup_->GetPopupParam()->GetTargetId().empty()) {
60 return false;
61 }
62
63 if (!GetThemeManager() || !GetThemeManager()->GetTheme<PopupTheme>()) {
64 return false;
65 }
66
67 auto theme = GetThemeManager()->GetTheme<PopupTheme>();
68 auto showAlphaAnimation = AceType::MakeRefPtr<CurveAnimation<float>>(0.0f, 1.0f, Curves::FAST_OUT_SLOW_IN);
69
70 TweenOption showOption;
71 showOption.SetDuration(theme->GetShowTime());
72 showOption.SetOpacityAnimation(showAlphaAnimation);
73 RefPtr<TweenComponent> tween = AceType::MakeRefPtr<TweenComponent>(popup_->GetId(), popup_->GetId());
74 tween->SetShadow(ShadowConfig::DefaultShadowM);
75 tween->SetIsFirstFrameShow(false);
76 tween->SetAnimationOperation(AnimationOperation::PLAY);
77 tween->SetTweenOption(showOption);
78
79 RefPtr<BubbleComponent> bubble = AceType::MakeRefPtr<BubbleComponent>(popup_->GetChild());
80 bubble->SetPopupParam(popup_->GetPopupParam());
81 bubble->SetId(popup_->GetId());
82 bubble->SetDisabledStatus(popup_->IsDisabledStatus());
83 bubble->SetStateChangeEvent([weak = WeakClaim(this)](bool isVisible) {
84 auto popup = weak.Upgrade();
85 if (popup) {
86 popup->OnStateChange(isVisible);
87 }
88 });
89 tween->SetChild(bubble);
90 SubwindowManager::GetInstance()->ShowPopup(tween, false);
91 weakStack_ = bubble->GetWeakStack();
92 auto stackElement = weakStack_.Upgrade();
93 if (!stackElement) {
94 return false;
95 }
96 return true;
97 }
98
CancelPopupInSubWindow(const ComposeId & id)99 bool PopupElement::CancelPopupInSubWindow(const ComposeId& id)
100 {
101 return SubwindowManager::GetInstance()->CancelPopup(id);
102 }
103
ShowPopup()104 bool PopupElement::ShowPopup()
105 {
106 const auto context = context_.Upgrade();
107 if (!context) {
108 return false;
109 }
110
111 if (!popup_ || popup_->GetPopupParam()->GetTargetId().empty()) {
112 return false;
113 }
114
115 if (!GetThemeManager() || !GetThemeManager()->GetTheme<PopupTheme>()) {
116 return false;
117 }
118
119 auto theme = GetThemeManager()->GetTheme<PopupTheme>();
120 auto showAlphaAnimation = AceType::MakeRefPtr<CurveAnimation<float>>(0.0f, 1.0f, Curves::FAST_OUT_SLOW_IN);
121
122 TweenOption showOption;
123 showOption.SetDuration(theme->GetShowTime());
124 showOption.SetOpacityAnimation(showAlphaAnimation);
125 RefPtr<TweenComponent> tween = AceType::MakeRefPtr<TweenComponent>(popup_->GetId(), popup_->GetId());
126 tween->SetShadow(ShadowConfig::DefaultShadowM);
127 tween->SetIsFirstFrameShow(false);
128 tween->SetAnimationOperation(AnimationOperation::PLAY);
129 tween->SetTweenOption(showOption);
130
131 RefPtr<BubbleComponent> bubble = AceType::MakeRefPtr<BubbleComponent>(popup_->GetChild());
132 bubble->SetPopupParam(popup_->GetPopupParam());
133 bubble->SetId(popup_->GetId());
134 bubble->SetDisabledStatus(popup_->IsDisabledStatus());
135 bubble->SetStateChangeEvent([weak = WeakClaim(this)](bool isVisible) {
136 auto popup = weak.Upgrade();
137 if (popup) {
138 popup->OnStateChange(isVisible);
139 }
140 });
141
142 auto stackElement = context->GetLastStack();
143 if (!stackElement) {
144 return false;
145 }
146 weakStack_ = WeakClaim(RawPtr(stackElement));
147 bubble->SetWeakStack(weakStack_);
148 tween->SetChild(bubble);
149
150 stackElement->PushComponent(tween, false);
151 #if defined(PREVIEW)
152 auto manager = context->GetAccessibilityManager();
153 if (manager) {
154 auto node = manager->GetAccessibilityNodeById(StringUtils::StringToInt(popup_->GetId()));
155 if (!node) {
156 return true;
157 }
158 node->SetZIndexToChild(stackElement->GetChildrenSize());
159 manager->ClearNodeRectInfo(node, false);
160 auto children = node->GetChildList();
161 for (auto& child : children) {
162 child->SetVisible(true);
163 }
164 }
165 #endif
166 return true;
167 }
168
CancelPopup(const ComposeId & id)169 bool PopupElement::CancelPopup(const ComposeId& id)
170 {
171 auto stackElement = weakStack_.Upgrade();
172 if (!stackElement) {
173 return false;
174 }
175 stackElement->PopPopup(id);
176
177 auto context = context_.Upgrade();
178 if (context) {
179 const auto& accessibilityManager = context->GetAccessibilityManager();
180 if (accessibilityManager) {
181 #if !defined(PREVIEW)
182 accessibilityManager->RemoveAccessibilityNodeById(StringUtils::StringToInt(popup_->GetId()));
183 #else
184 auto node = accessibilityManager->GetAccessibilityNodeById(StringUtils::StringToInt(popup_->GetId()));
185 if (!node) {
186 return true;
187 }
188 node->SetZIndexToChild(0);
189 accessibilityManager->ClearNodeRectInfo(node, true);
190 auto children = node->GetChildList();
191 for (auto& child : children) {
192 child->SetVisible(true);
193 }
194 #endif
195 }
196 }
197 return true;
198 }
199
200 } // namespace OHOS::Ace