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 "base/utils/utils.h"
19 #include "core/components/focus_animation/render_focus_animation.h"
20 #include "core/components/shadow/render_shadow.h"
21 #include "core/components/shadow/shadow_element.h"
22 #include "core/components/stack/stack_element.h"
23
24 namespace OHOS::Ace {
25
SetFocusAnimationProperties(const RRect & rrect,const Color & color,const Offset & offset,bool isIndented) const26 void FocusAnimationManager::SetFocusAnimationProperties(
27 const RRect& rrect, const Color& color, const Offset& offset, bool isIndented) const
28 {
29 if (focusAnimationStack_.empty() || (useRoot_ && rootFocusAnimationStack_.empty())) {
30 LOGD("focus animation stack is empty");
31 return;
32 }
33 auto focusAnimation = useRoot_ ? rootFocusAnimationStack_.top().Upgrade() : focusAnimationStack_.top().Upgrade();
34 CHECK_NULL_VOID(focusAnimation);
35 if (useRoot_) {
36 auto renderFocusAnimation = focusAnimationStack_.top().Upgrade();
37 if (renderFocusAnimation) {
38 renderFocusAnimation->CancelFocusAnimation();
39 }
40 }
41 focusAnimation->SetFocusAnimationProperties(rrect, color, offset, isIndented);
42 }
43
SetAvailableRect(const Rect & paintRect)44 void FocusAnimationManager::SetAvailableRect(const Rect& paintRect)
45 {
46 availableRect_ = paintRect;
47 }
48
CancelFocusAnimation() const49 void FocusAnimationManager::CancelFocusAnimation() const
50 {
51 if (focusAnimationStack_.empty() || (useRoot_ && rootFocusAnimationStack_.empty())) {
52 LOGD("focus animation stack is empty");
53 return;
54 }
55 auto focusAnimation = useRoot_ ? rootFocusAnimationStack_.top().Upgrade() : focusAnimationStack_.top().Upgrade();
56 CHECK_NULL_VOID(focusAnimation);
57 focusAnimation->CancelFocusAnimation();
58 }
59
PushFocusAnimationElement(const RefPtr<Element> & element)60 void FocusAnimationManager::PushFocusAnimationElement(const RefPtr<Element>& element)
61 {
62 auto focusElement = AceType::DynamicCast<FocusAnimationElement>(element);
63 CHECK_NULL_VOID(focusElement);
64 auto renderFocus = AceType::DynamicCast<RenderFocusAnimation>(focusElement->GetRenderNode());
65 CHECK_NULL_VOID(renderFocus);
66 renderFocus->SetPaintRect(availableRect_);
67 if (focusElement->IsRoot()) {
68 if (!rootFocusAnimationStack_.empty()) {
69 auto focusAnimation = rootFocusAnimationStack_.top().Upgrade();
70 if (focusAnimation) {
71 focusAnimation->CancelFocusAnimation();
72 }
73 }
74 rootFocusAnimationStack_.push(renderFocus);
75 } else {
76 if (!focusAnimationStack_.empty()) {
77 auto focusAnimation = focusAnimationStack_.top().Upgrade();
78 if (focusAnimation) {
79 focusAnimation->CancelFocusAnimation();
80 }
81 }
82 focusAnimationStack_.push(renderFocus);
83 }
84 }
85
PopFocusAnimationElement()86 void FocusAnimationManager::PopFocusAnimationElement()
87 {
88 if (focusAnimationStack_.empty()) {
89 LOGD("focus animation stack is empty");
90 return;
91 }
92 focusAnimationStack_.pop();
93 if (!focusAnimationStack_.empty()) {
94 auto focusAnimation = focusAnimationStack_.top().Upgrade();
95 if (!useRoot_ && focusAnimation) {
96 focusAnimation->StartFocusAnimation();
97 }
98 }
99 }
100
PopRootFocusAnimationElement()101 void FocusAnimationManager::PopRootFocusAnimationElement()
102 {
103 if (rootFocusAnimationStack_.empty()) {
104 LOGD("focus animation stack is empty");
105 return;
106 }
107 rootFocusAnimationStack_.pop();
108 }
109
StartFocusAnimation() const110 void FocusAnimationManager::StartFocusAnimation() const
111 {
112 if (focusAnimationStack_.empty()) {
113 LOGD("focus animation stack is empty");
114 return;
115 }
116 auto focusAnimation = focusAnimationStack_.top().Upgrade();
117 CHECK_NULL_VOID(focusAnimation);
118 focusAnimation->StartFocusAnimation();
119 }
120
StopFocusAnimation() const121 void FocusAnimationManager::StopFocusAnimation() const
122 {
123 if (focusAnimationStack_.empty()) {
124 LOGD("focus animation stack is empty");
125 return;
126 }
127 auto focusAnimation = focusAnimationStack_.top().Upgrade();
128 CHECK_NULL_VOID(focusAnimation);
129 focusAnimation->StopFocusAnimation();
130 }
131
SetFocusAnimationProperties(const RRect & rrect,const Color & color,const Offset & offset,const Rect & clipRect) const132 void FocusAnimationManager::SetFocusAnimationProperties(
133 const RRect& rrect, const Color& color, const Offset& offset, const Rect& clipRect) const
134 {
135 if (focusAnimationStack_.empty()) {
136 LOGD("focus animation stack is empty");
137 return;
138 }
139 auto focusAnimation = focusAnimationStack_.top().Upgrade();
140 CHECK_NULL_VOID(focusAnimation);
141 focusAnimation->SetFocusAnimationProperties(rrect, color, offset, clipRect);
142 }
143
PushShadow(const RefPtr<Element> & element)144 void FocusAnimationManager::PushShadow(const RefPtr<Element>& element)
145 {
146 auto shadowElement = AceType::DynamicCast<ShadowElement>(element);
147 CHECK_NULL_VOID(shadowElement);
148 auto renderShadow = AceType::DynamicCast<RenderShadow>(shadowElement->GetRenderNode());
149 CHECK_NULL_VOID(renderShadow);
150 shadowStack_.push(renderShadow);
151 }
152
PopShadow()153 void FocusAnimationManager::PopShadow()
154 {
155 if (shadowStack_.empty()) {
156 LOGE("shadow stack is empty");
157 return;
158 }
159 shadowStack_.pop();
160 }
161
SetShadowProperties(const RRect & rrect,const Offset & offset)162 void FocusAnimationManager::SetShadowProperties(const RRect& rrect, const Offset& offset)
163 {
164 if (shadowStack_.empty()) {
165 LOGE("shadow stack is empty");
166 return;
167 }
168 auto shadow = shadowStack_.top().Upgrade();
169 CHECK_NULL_VOID(shadow);
170 shadow->SetShadowProperties(rrect, offset);
171 }
172
SetShadowProperties(const RRect & rrect,const Offset & offset,const Rect & clipRect)173 void FocusAnimationManager::SetShadowProperties(const RRect& rrect, const Offset& offset, const Rect& clipRect)
174 {
175 if (shadowStack_.empty()) {
176 LOGE("shadow stack is empty");
177 return;
178 }
179 auto shadow = shadowStack_.top().Upgrade();
180 CHECK_NULL_VOID(shadow);
181 shadow->SetShadowProperties(rrect, offset, clipRect);
182 }
183
CancelShadow() const184 void FocusAnimationManager::CancelShadow() const
185 {
186 if (shadowStack_.empty()) {
187 LOGE("shadow stack is empty");
188 return;
189 }
190 auto shadow = shadowStack_.top().Upgrade();
191 CHECK_NULL_VOID(shadow);
192 shadow->CancelShadow();
193 }
194
GetRenderFocusAnimation() const195 RefPtr<RenderFocusAnimation> FocusAnimationManager::GetRenderFocusAnimation() const
196 {
197 if (focusAnimationStack_.empty() || (useRoot_ && rootFocusAnimationStack_.empty())) {
198 return nullptr;
199 }
200 auto focusAnimation = useRoot_ ? rootFocusAnimationStack_.top().Upgrade() : focusAnimationStack_.top().Upgrade();
201 CHECK_NULL_RETURN(focusAnimation, nullptr);
202 return focusAnimation;
203 }
204
SetUseRoot(bool useRoot)205 void FocusAnimationManager::SetUseRoot(bool useRoot)
206 {
207 useRoot_ = useRoot;
208 if (!useRoot_ && !rootFocusAnimationStack_.empty()) {
209 auto focusAnimation = rootFocusAnimationStack_.top().Upgrade();
210 if (focusAnimation) {
211 focusAnimation->CancelFocusAnimation();
212 }
213 }
214 }
215
SetIsKeyEvent(bool isKeyEvent)216 void FocusAnimationManager::SetIsKeyEvent(bool isKeyEvent)
217 {
218 if (focusAnimationStack_.empty() || (useRoot_ && rootFocusAnimationStack_.empty())) {
219 LOGD("focus animation stack is empty");
220 return;
221 }
222 auto focusAnimation = useRoot_ ? rootFocusAnimationStack_.top().Upgrade() : focusAnimationStack_.top().Upgrade();
223 CHECK_NULL_VOID(focusAnimation);
224 focusAnimation->SetIsKeyEvent(isKeyEvent);
225 }
226
227 } // namespace OHOS::Ace