1 /* 2 * Copyright (c) 2023 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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_NAVIGATION_TRANSITION_PROXY_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_NAVIGATION_TRANSITION_PROXY_H 18 19 #include "base/memory/ace_type.h" 20 #include "frameworks/core/components_ng/pattern/navigation/navigation_declaration.h" 21 #include "frameworks/core/components_ng/pattern/navrouter/navdestination_group_node.h" 22 #include "frameworks/core/components_ng/pattern/navrouter/navdestination_pattern.h" 23 namespace OHOS::Ace::NG { 24 25 namespace { 26 std::atomic<uint64_t> g_proxyNextAutoGenId = 0; 27 } 28 29 using namespace Framework; 30 class NavigationTransitionProxy : public AceType { 31 DECLARE_ACE_TYPE(NavigationTransitionProxy, AceType); 32 33 public: NavigationTransitionProxy()34 NavigationTransitionProxy() 35 { 36 proxyId_ = g_proxyNextAutoGenId.fetch_add(1); 37 } 38 ~NavigationTransitionProxy() = default; 39 GetPreDestinationContext()40 RefPtr<NG::NavDestinationContext> GetPreDestinationContext() const 41 { 42 return preContext_; 43 } 44 GetTopDestinationContext()45 RefPtr<NG::NavDestinationContext> GetTopDestinationContext() const 46 { 47 return topContext_; 48 } 49 SetPreDestination(const RefPtr<NavDestinationGroupNode> & preDestination)50 void SetPreDestination(const RefPtr<NavDestinationGroupNode>& preDestination) 51 { 52 CHECK_NULL_VOID(preDestination); 53 auto pattern = AceType::DynamicCast<NavDestinationPattern>(preDestination->GetPattern()); 54 CHECK_NULL_VOID(pattern); 55 preContext_ = pattern->GetNavDestinationContext(); 56 CHECK_NULL_VOID(preContext_); 57 preContext_->SetNavPathInfo(pattern->GetNavPathInfo()); 58 } 59 SetTopDestination(const RefPtr<NavDestinationGroupNode> & topDestination)60 void SetTopDestination(const RefPtr<NavDestinationGroupNode>& topDestination) 61 { 62 CHECK_NULL_VOID(topDestination); 63 auto pattern = AceType::DynamicCast<NavDestinationPattern>(topDestination->GetPattern()); 64 CHECK_NULL_VOID(pattern); 65 topContext_ = pattern->GetNavDestinationContext(); 66 CHECK_NULL_VOID(topContext_); 67 topContext_->SetNavPathInfo(pattern->GetNavPathInfo()); 68 } 69 SetFinishTransitionEvent(std::function<void ()> && event)70 void SetFinishTransitionEvent(std::function<void()>&& event) 71 { 72 finishCallback_ = std::move(event); 73 } 74 FireFinishCallback()75 void FireFinishCallback() 76 { 77 if (interactive_) { 78 FinishInteractiveAnimation(); 79 return; 80 } 81 if (hasFinished_ || !finishCallback_) { 82 TAG_LOGE(AceLogTag::ACE_NAVIGATION, "not support to finish custom animation more than once"); 83 return; 84 } 85 hasFinished_ = true; 86 finishCallback_(); 87 if (endCallback_) { 88 endCallback_(true); 89 } 90 } 91 SetIsSuccess(bool isSuccess)92 void SetIsSuccess(bool isSuccess) 93 { 94 isSuccess_ = isSuccess; 95 } 96 SetIsFinished(bool isFinished)97 void SetIsFinished(bool isFinished) 98 { 99 hasFinished_ = isFinished; 100 } 101 GetIsFinished()102 bool GetIsFinished() const 103 { 104 return hasFinished_; 105 } 106 SetCancelAnimationCallback(std::function<void ()> && cancelAnimation)107 void SetCancelAnimationCallback(std::function<void()>&& cancelAnimation) 108 { 109 cancelAnimation_ = std::move(cancelAnimation); 110 } 111 FireCancelAnimation()112 void FireCancelAnimation() 113 { 114 if (!cancelAnimation_ || hasFinished_ || !interactive_) { 115 return; 116 } 117 cancelAnimation_(); 118 } 119 SetInteractive(bool interactive)120 void SetInteractive(bool interactive) 121 { 122 interactive_ = interactive; 123 } 124 GetInteractive()125 bool GetInteractive() const 126 { 127 return interactive_; 128 } 129 SetEndCallback(std::function<void (bool)> && callback)130 void SetEndCallback(std::function<void(bool)>&& callback) 131 { 132 endCallback_ = std::move(callback); 133 } 134 FireEndCallback()135 void FireEndCallback() 136 { 137 if (endCallback_) { 138 endCallback_(isSuccess_); 139 } 140 } 141 GetIsSuccess()142 bool GetIsSuccess() 143 { 144 return isSuccess_; 145 } 146 SetInteractiveAnimation(std::shared_ptr<AnimationUtils::InteractiveAnimation> interactiveAnimation,const std::function<void ()> & finishCallback)147 void SetInteractiveAnimation( 148 std::shared_ptr<AnimationUtils::InteractiveAnimation> interactiveAnimation, 149 const std::function<void()>& finishCallback) 150 { 151 interactiveAnimation_ = interactiveAnimation; 152 interactiveFinishCallback_ = finishCallback; 153 } 154 StartAnimation()155 void StartAnimation() 156 { 157 if (!interactiveAnimation_) { 158 return; 159 } 160 // if error code is 0, start interactive success 161 int32_t errorCode = AnimationUtils::StartInteractiveAnimation(interactiveAnimation_); 162 TAG_LOGI(AceLogTag::ACE_NAVIGATION, "update start interactive animation code is %{public}d", errorCode); 163 isStartAnimation_ = errorCode == 0; 164 } 165 UpdateTransition(float progress)166 void UpdateTransition(float progress) 167 { 168 if (!interactive_ || hasFinished_) { 169 return; 170 } 171 AnimationUtils::UpdateInteractiveAnimation(interactiveAnimation_, progress); 172 } 173 FinishInteractiveAnimation()174 void FinishInteractiveAnimation() 175 { 176 if (!interactive_ || hasFinished_) { 177 TAG_LOGE(AceLogTag::ACE_NAVIGATION, "not support to finish interactive animation more than once"); 178 return; 179 } 180 hasFinished_ = true; 181 isSuccess_ = true; 182 if (!isStartAnimation_) { 183 interactiveFinishCallback_(); 184 if (endCallback_) { 185 endCallback_(true); 186 } 187 return; 188 } 189 AnimationUtils::ContinueInteractiveAnimation(interactiveAnimation_); 190 } 191 CancelInteractiveAnimation()192 void CancelInteractiveAnimation() 193 { 194 if (!interactive_ || hasFinished_) { 195 TAG_LOGE(AceLogTag::ACE_NAVIGATION, "not support to cancel interactive animation more than once"); 196 return; 197 } 198 hasFinished_ = true; 199 isSuccess_ = false; 200 if (!isStartAnimation_) { 201 interactiveFinishCallback_(); 202 if (endCallback_) { 203 endCallback_(false); 204 } 205 return; 206 } 207 AnimationUtils::ReverseInteractiveAnimation(interactiveAnimation_); 208 } 209 AddInteractiveAnimation(const std::function<void ()> & callback)210 void AddInteractiveAnimation(const std::function<void()>& callback) 211 { 212 if (!interactive_) { 213 return; 214 } 215 AnimationUtils::AddInteractiveAnimation(interactiveAnimation_, callback); 216 } 217 GetProxyId()218 uint64_t GetProxyId() const 219 { 220 return proxyId_; 221 } 222 223 private: 224 uint64_t proxyId_ = 0; 225 RefPtr<NavDestinationContext> preContext_; 226 RefPtr<NavDestinationContext> topContext_; 227 std::function<void()> finishCallback_; // finish transition callback to continue animation 228 std::function<void()> cancelAnimation_; // cancel transition callback to reverse animation 229 std::function<void(bool)> endCallback_; 230 std::function<void()> interactiveFinishCallback_; 231 std::shared_ptr<AnimationUtils::InteractiveAnimation> interactiveAnimation_; 232 bool hasFinished_ = false; // current transition is finish or not 233 bool isSuccess_ = true; // set current custom transition is start success or not 234 bool interactive_ = false; // set current interactive animation 235 bool isStartAnimation_ = false; 236 }; 237 238 struct NavigationTransition { 239 int32_t timeout = 1000; 240 std::function<void(const RefPtr<NavigationTransitionProxy>&)> transition; 241 std::function<void(bool)> endCallback; 242 bool isValid = true; 243 bool interactive = false; 244 }; 245 } // namespace OHOS::Ace::NG 246 #endif