1 /*
2 * Copyright (c) 2021 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/common/focus_animation_manager.h"
17
18 #include "core/components/focus_animation/render_focus_animation.h"
19 #include "core/components/shadow/render_shadow.h"
20 #include "core/components/shadow/shadow_element.h"
21 #include "core/components/stack/stack_element.h"
22
23 namespace OHOS::Ace {
24
SetFocusAnimationProperties(const RRect & rrect,const Color & color,const Offset & offset,bool isIndented) const25 void FocusAnimationManager::SetFocusAnimationProperties(
26 const RRect& rrect, const Color& color, const Offset& offset, bool isIndented) const
27 {
28 if (focusAnimationStack_.empty() || (useRoot_ && rootFocusAnimationStack_.empty())) {
29 LOGD("focus animation stack is empty");
30 return;
31 }
32 auto focusAnimation = useRoot_ ? rootFocusAnimationStack_.top().Upgrade() : focusAnimationStack_.top().Upgrade();
33 if (!focusAnimation) {
34 LOGE("focusAnimation get failed");
35 return;
36 }
37 if (useRoot_) {
38 auto renderFocusAnimation = focusAnimationStack_.top().Upgrade();
39 if (renderFocusAnimation) {
40 renderFocusAnimation->CancelFocusAnimation();
41 }
42 }
43 focusAnimation->SetFocusAnimationProperties(rrect, color, offset, isIndented);
44 }
45
SetAvailableRect(const Rect & paintRect)46 void FocusAnimationManager::SetAvailableRect(const Rect& paintRect)
47 {
48 availableRect_ = paintRect;
49 }
50
CancelFocusAnimation() const51 void FocusAnimationManager::CancelFocusAnimation() const
52 {
53 if (focusAnimationStack_.empty() || (useRoot_ && rootFocusAnimationStack_.empty())) {
54 LOGD("focus animation stack is empty");
55 return;
56 }
57 auto focusAnimation = useRoot_ ? rootFocusAnimationStack_.top().Upgrade() : focusAnimationStack_.top().Upgrade();
58 if (!focusAnimation) {
59 LOGE("focusAnimation get failed");
60 return;
61 }
62 focusAnimation->CancelFocusAnimation();
63 }
64
PushFocusAnimationElement(const RefPtr<Element> & element)65 void FocusAnimationManager::PushFocusAnimationElement(const RefPtr<Element>& element)
66 {
67 auto focusElement = AceType::DynamicCast<FocusAnimationElement>(element);
68 if (!focusElement) {
69 LOGE("fail to get FocusAnimationElement");
70 return;
71 }
72 auto renderFocus = AceType::DynamicCast<RenderFocusAnimation>(focusElement->GetRenderNode());
73 if (!renderFocus) {
74 LOGE("fail to get RenderFocusAnimation");
75 return;
76 }
77 renderFocus->SetPaintRect(availableRect_);
78 if (focusElement->IsRoot()) {
79 if (!rootFocusAnimationStack_.empty()) {
80 auto focusAnimation = rootFocusAnimationStack_.top().Upgrade();
81 if (focusAnimation) {
82 focusAnimation->CancelFocusAnimation();
83 }
84 }
85 rootFocusAnimationStack_.push(renderFocus);
86 } else {
87 if (!focusAnimationStack_.empty()) {
88 auto focusAnimation = focusAnimationStack_.top().Upgrade();
89 if (focusAnimation) {
90 focusAnimation->CancelFocusAnimation();
91 }
92 }
93 focusAnimationStack_.push(renderFocus);
94 }
95 }
96
PopFocusAnimationElement()97 void FocusAnimationManager::PopFocusAnimationElement()
98 {
99 if (focusAnimationStack_.empty()) {
100 LOGD("focus animation stack is empty");
101 return;
102 }
103 focusAnimationStack_.pop();
104 if (!focusAnimationStack_.empty()) {
105 auto focusAnimation = focusAnimationStack_.top().Upgrade();
106 if (!useRoot_ && focusAnimation) {
107 focusAnimation->StartFocusAnimation();
108 }
109 }
110 }
111
PopRootFocusAnimationElement()112 void FocusAnimationManager::PopRootFocusAnimationElement()
113 {
114 if (rootFocusAnimationStack_.empty()) {
115 LOGD("focus animation stack is empty");
116 return;
117 }
118 rootFocusAnimationStack_.pop();
119 }
120
StartFocusAnimation() const121 void FocusAnimationManager::StartFocusAnimation() const
122 {
123 if (focusAnimationStack_.empty()) {
124 LOGD("focus animation stack is empty");
125 return;
126 }
127 auto focusAnimation = focusAnimationStack_.top().Upgrade();
128 if (!focusAnimation) {
129 LOGE("focusAnimation get failed");
130 return;
131 }
132 focusAnimation->StartFocusAnimation();
133 }
134
StopFocusAnimation() const135 void FocusAnimationManager::StopFocusAnimation() const
136 {
137 if (focusAnimationStack_.empty()) {
138 LOGD("focus animation stack is empty");
139 return;
140 }
141 auto focusAnimation = focusAnimationStack_.top().Upgrade();
142 if (!focusAnimation) {
143 LOGE("focusAnimation get failed");
144 return;
145 }
146 focusAnimation->StopFocusAnimation();
147 }
148
SetFocusAnimationProperties(const RRect & rrect,const Color & color,const Offset & offset,const Rect & clipRect) const149 void FocusAnimationManager::SetFocusAnimationProperties(
150 const RRect& rrect, const Color& color, const Offset& offset, const Rect& clipRect) const
151 {
152 if (focusAnimationStack_.empty()) {
153 LOGD("focus animation stack is empty");
154 return;
155 }
156 auto focusAnimation = focusAnimationStack_.top().Upgrade();
157 if (!focusAnimation) {
158 LOGE("focusAnimation get failed");
159 return;
160 }
161 focusAnimation->SetFocusAnimationProperties(rrect, color, offset, clipRect);
162 }
163
PushShadow(const RefPtr<Element> & element)164 void FocusAnimationManager::PushShadow(const RefPtr<Element>& element)
165 {
166 auto shadowElement = AceType::DynamicCast<ShadowElement>(element);
167 if (!shadowElement) {
168 LOGE("fail to get shadowElement");
169 return;
170 }
171 auto renderShadow = AceType::DynamicCast<RenderShadow>(shadowElement->GetRenderNode());
172 if (!renderShadow) {
173 LOGE("fail to get renderShadow");
174 return;
175 }
176 shadowStack_.push(renderShadow);
177 }
178
PopShadow()179 void FocusAnimationManager::PopShadow()
180 {
181 if (shadowStack_.empty()) {
182 LOGE("shadow stack is empty");
183 return;
184 }
185 shadowStack_.pop();
186 }
187
SetShadowProperties(const RRect & rrect,const Offset & offset)188 void FocusAnimationManager::SetShadowProperties(const RRect& rrect, const Offset& offset)
189 {
190 if (shadowStack_.empty()) {
191 LOGE("shadow stack is empty");
192 return;
193 }
194 auto shadow = shadowStack_.top().Upgrade();
195 if (!shadow) {
196 LOGE("shadow get failed");
197 return;
198 }
199 shadow->SetShadowProperties(rrect, offset);
200 }
201
SetShadowProperties(const RRect & rrect,const Offset & offset,const Rect & clipRect)202 void FocusAnimationManager::SetShadowProperties(const RRect& rrect, const Offset& offset, const Rect& clipRect)
203 {
204 if (shadowStack_.empty()) {
205 LOGE("shadow stack is empty");
206 return;
207 }
208 auto shadow = shadowStack_.top().Upgrade();
209 if (!shadow) {
210 LOGE("shadow get failed");
211 return;
212 }
213 shadow->SetShadowProperties(rrect, offset, clipRect);
214 }
215
CancelShadow() const216 void FocusAnimationManager::CancelShadow() const
217 {
218 if (shadowStack_.empty()) {
219 LOGE("shadow stack is empty");
220 return;
221 }
222 auto shadow = shadowStack_.top().Upgrade();
223 if (!shadow) {
224 LOGE("shadow get failed");
225 return;
226 }
227 shadow->CancelShadow();
228 }
229
GetRenderFocusAnimation() const230 RefPtr<RenderFocusAnimation> FocusAnimationManager::GetRenderFocusAnimation() const
231 {
232 if (focusAnimationStack_.empty() || (useRoot_ && rootFocusAnimationStack_.empty())) {
233 return nullptr;
234 }
235 auto focusAnimation = useRoot_ ? rootFocusAnimationStack_.top().Upgrade() : focusAnimationStack_.top().Upgrade();
236 if (!focusAnimation) {
237 LOGE("focusAnimation get failed");
238 return nullptr;
239 }
240 return focusAnimation;
241 }
242
SetUseRoot(bool useRoot)243 void FocusAnimationManager::SetUseRoot(bool useRoot)
244 {
245 useRoot_ = useRoot;
246 if (!useRoot_ && !rootFocusAnimationStack_.empty()) {
247 auto focusAnimation = rootFocusAnimationStack_.top().Upgrade();
248 if (focusAnimation) {
249 focusAnimation->CancelFocusAnimation();
250 }
251 }
252 }
253
SetIsKeyEvent(bool isKeyEvent)254 void FocusAnimationManager::SetIsKeyEvent(bool isKeyEvent)
255 {
256 if (focusAnimationStack_.empty() || (useRoot_ && rootFocusAnimationStack_.empty())) {
257 LOGD("focus animation stack is empty");
258 return;
259 }
260 auto focusAnimation = useRoot_ ? rootFocusAnimationStack_.top().Upgrade() : focusAnimationStack_.top().Upgrade();
261 if (!focusAnimation) {
262 LOGE("focusAnimation get failed");
263 return;
264 }
265 focusAnimation->SetIsKeyEvent(isKeyEvent);
266 }
267
268 } // namespace OHOS::Ace