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