From af1cf1f5c720a59f32f9e97731db5ba7d86ec610 Mon Sep 17 00:00:00 2001 From: wangyihui Date: Wed, 31 May 2023 01:36:57 +0000 Subject: [PATCH] =?UTF-8?q?=E8=BF=94=E5=9B=9E=E4=BA=8B=E4=BB=B6=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E8=BF=81=E7=A7=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: wangyihui Change-Id: I4aeb5914986c275df9fa9b733d393ed405b76c7a --- .../navigation/navigation_group_node.cpp | 658 ++++++++++++++++- .../navigation/navigation_group_node.h | 31 +- .../pattern/navigation/navigation_pattern.cpp | 2 +- .../navrouter/navrouter_group_node.cpp | 686 +----------------- .../pattern/navrouter/navrouter_group_node.h | 23 - 5 files changed, 697 insertions(+), 703 deletions(-) diff --git a/frameworks/core/components_ng/pattern/navigation/navigation_group_node.cpp b/frameworks/core/components_ng/pattern/navigation/navigation_group_node.cpp index 496e0bef7fc..df6d0f21e84 100644 --- a/frameworks/core/components_ng/pattern/navigation/navigation_group_node.cpp +++ b/frameworks/core/components_ng/pattern/navigation/navigation_group_node.cpp @@ -17,13 +17,19 @@ #include "base/memory/ace_type.h" #include "base/memory/referenced.h" +#include "core/common/container.h" #include "core/components_ng/base/view_stack_processor.h" +#include "core/components_ng/pattern/image/image_layout_property.h" #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h" #include "core/components_ng/pattern/navigation/nav_bar_node.h" #include "core/components_ng/pattern/navigation/navigation_declaration.h" #include "core/components_ng/pattern/navigation/navigation_pattern.h" +#include "core/components_ng/pattern/navigation/title_bar_layout_property.h" #include "core/components_ng/pattern/navigation/title_bar_node.h" +#include "core/components_ng/pattern/navrouter/navdestination_event_hub.h" #include "core/components_ng/pattern/navrouter/navdestination_group_node.h" +#include "core/components_ng/pattern/navrouter/navdestination_layout_property.h" +#include "core/components_ng/pattern/navrouter/navdestination_pattern.h" #include "core/components_ng/pattern/navrouter/navrouter_event_hub.h" #include "core/components_ng/pattern/navrouter/navrouter_group_node.h" #include "core/components_ng/pattern/stack/stack_layout_property.h" @@ -34,7 +40,23 @@ #include "core/components_v2/inspector/inspector_constants.h" namespace OHOS::Ace::NG { - +namespace { +constexpr double HALF = 0.5; +constexpr double PARENT_PAGE_OFFSET = 0.2; +constexpr double PARENT_TITLE_OFFSET = 0.02; +constexpr int32_t MASK_DURATION = 350; +constexpr int32_t OPACITY_TITLE_OUT_DELAY = 17; +constexpr int32_t OPACITY_TITLE_IN_DELAY = 33; +constexpr int32_t OPACITY_TITLE_DURATION = 150; +constexpr int32_t OPACITY_BACKBUTTON_IN_DELAY = 150; +constexpr int32_t OPACITY_BACKBUTTON_IN_DURATION = 200; +constexpr int32_t OPACITY_BACKBUTTON_OUT_DURATION = 67; +constexpr int32_t DEFAULT_ANIMATION_DURATION = 400; +const Color MASK_COLOR = Color::FromARGB(25, 0, 0, 0); +const Color DEFAULT_MASK_COLOR = Color::FromARGB(0, 0, 0, 0); +const RefPtr interpolatingSpringCurve = + AceType::MakeRefPtr(0.0f, 1.0f, 342.0f, 37.0f); +} // namespace RefPtr NavigationGroupNode::GetOrCreateGroupNode( const std::string& tag, int32_t nodeId, const std::function(void)>& patternCreator) { @@ -66,13 +88,12 @@ void NavigationGroupNode::AddChildToGroup(const RefPtr& child, int32_t s contentNode->AddChild(child); } -void NavigationGroupNode::AddNavDestinationToNavigation(const RefPtr& parent) +void NavigationGroupNode::AddNavDestinationToNavigation() { auto pattern = AceType::DynamicCast(GetPattern()); CHECK_NULL_VOID(pattern); auto navDestinationNodes = pattern->GetAllNavDestinationNodes(); - auto navigationNode = AceType::DynamicCast(parent); - CHECK_NULL_VOID(navigationNode); + auto navigationNode = AceType::WeakClaim(this).Upgrade(); auto navigationContentNode = AceType::DynamicCast(navigationNode->GetContentNode()); CHECK_NULL_VOID(navigationContentNode); auto navigationStack = pattern->GetNavigationStack(); @@ -116,4 +137,633 @@ RefPtr NavigationGroupNode::GetNavDestinationNode(RefPtr uiNode) uiNode = AceType::DynamicCast(frameNode); return uiNode; } + +void NavigationGroupNode::AddBackButtonIconToNavDestination(const RefPtr& navDestinationNode) +{ + auto navigationNode = AceType::WeakClaim(this).Upgrade(); + auto navigationLayoutProperty = GetLayoutProperty(); + CHECK_NULL_VOID(navigationLayoutProperty); + auto navDestination = AceType::DynamicCast(navDestinationNode); + auto navDestinationLayoutProperty = navDestination->GetLayoutProperty(); + CHECK_NULL_VOID(navDestinationLayoutProperty); + + // back button icon + if (navigationLayoutProperty->HasNoPixMap()) { + if (navigationLayoutProperty->HasImageSource()) { + navDestinationLayoutProperty->UpdateImageSource(navigationLayoutProperty->GetImageSourceValue()); + } + if (navigationLayoutProperty->HasPixelMap()) { + navDestinationLayoutProperty->UpdatePixelMap(navigationLayoutProperty->GetPixelMapValue()); + } + navDestinationLayoutProperty->UpdateNoPixMap(navigationLayoutProperty->GetNoPixMapValue()); + navDestination->MarkModifyDone(); + } +} + +void NavigationGroupNode::SetBackButtonVisible(const RefPtr& navDestinationNode) +{ + auto navDestination = AceType::DynamicCast(navDestinationNode); + CHECK_NULL_VOID(navDestination); + auto titleBarNode = AceType::DynamicCast(navDestination->GetTitleBarNode()); + CHECK_NULL_VOID(titleBarNode); + auto titleBarLayoutProperty = titleBarNode->GetLayoutProperty(); + CHECK_NULL_VOID(titleBarLayoutProperty); + auto backButtonNode = AceType::DynamicCast(titleBarNode->GetBackButton()); + CHECK_NULL_VOID(backButtonNode); + auto backButtonLayoutProperty = backButtonNode->GetLayoutProperty(); + CHECK_NULL_VOID(backButtonLayoutProperty); + backButtonLayoutProperty->UpdateVisibility(VisibleType::VISIBLE); + backButtonNode->MarkModifyDone(); +} + +void NavigationGroupNode::SetBackButtonEvent( + const RefPtr& navDestinationNode, const RefPtr& navRouterPattern) +{ + auto navigationNode = AceType::WeakClaim(this).Upgrade(); + CHECK_NULL_VOID(navigationNode); + auto navDestination = AceType::DynamicCast(navDestinationNode); + AddBackButtonIconToNavDestination(navDestination); + auto titleBarNode = AceType::DynamicCast(navDestination->GetTitleBarNode()); + CHECK_NULL_VOID(titleBarNode); + auto backButtonNode = AceType::DynamicCast(titleBarNode->GetBackButton()); + CHECK_NULL_VOID(backButtonNode); + auto backButtonEventHub = backButtonNode->GetEventHub(); + CHECK_NULL_VOID(backButtonEventHub); + auto onBackButtonEvent = [navDestination, navigation = navigationNode, navRouterPattern](GestureEvent& /*info*/) { + // the one before navdestination in the stack + auto eventHub = navDestination->GetEventHub(); + CHECK_NULL_VOID(eventHub); + auto onBackPressed = eventHub->GetOnBackPressedEvent(); + bool isOverride = false; + if (onBackPressed != nullptr) { + isOverride = eventHub->FireOnBackPressedEvent(); + } + auto destinationContent = navDestination->GetContentNode(); + auto navDestinationPattern = navDestination->GetPattern(); + CHECK_NULL_VOID(navDestinationPattern); + NavRouteMode mode = NavRouteMode::PUSH; + if (navRouterPattern) { + mode = navRouterPattern->GetNavRouteMode(); + } + if (destinationContent) { + auto shallowBuilder = navDestinationPattern->GetShallowBuilder(); + CHECK_NULL_VOID(shallowBuilder); + shallowBuilder->MarkIsExecuteDeepRenderDone(false); + if (mode == NavRouteMode::PUSH_WITH_RECREATE || mode == NavRouteMode::REPLACE) { + destinationContent->Clean(); + } + } + if (isOverride) { + LOGI("this onBackButtonPressed event returns false"); + return; + } + auto layoutProperty = navigation->GetLayoutProperty(); + CHECK_NULL_VOID(layoutProperty); + auto navigationPattern = navigation->GetPattern(); + CHECK_NULL_VOID(navigationPattern); + auto preNavDestination = AceType::DynamicCast( + navigationPattern->GetPreNavDestination(navDestinationPattern->GetName())); + if (layoutProperty->GetNavigationModeValue(NavigationMode::AUTO) == NavigationMode::STACK) { + if (preNavDestination) { + navigation->BackToPreNavDestination(preNavDestination, navDestination, navRouterPattern); + navigation->SetOnStateChangeFalse(preNavDestination, navDestination, true); + layoutProperty->UpdateDestinationChange(true); + return; + } + navigation->BackToNavBar(navDestination); + navigation->SetOnStateChangeFalse(navDestination, navDestination, true); + layoutProperty->UpdateDestinationChange(false); + return; + } + + if (layoutProperty->GetNavigationModeValue(NavigationMode::AUTO) == NavigationMode::SPLIT) { + if (preNavDestination) { + navigation->BackToPreNavDestination(preNavDestination, navDestination, navRouterPattern); + navigation->SetOnStateChangeFalse(preNavDestination, navDestination, true); + layoutProperty->UpdateDestinationChange(false); + return; + } + } + navigation->MarkModifyDone(); + }; // backButton event + + navDestination->SetNavDestinationBackButtonEvent(onBackButtonEvent); + auto clickEvent = AceType::MakeRefPtr(std::move(onBackButtonEvent)); + if (!backButtonEventHub->GetGestureEventHub()) { + return; + } + backButtonEventHub->GetOrCreateGestureEventHub()->AddClickEvent(clickEvent); +} + +void NavigationGroupNode::BackToNavBar(const RefPtr& navDestinationNode) +{ + auto navigationNode = AceType::WeakClaim(this).Upgrade(); + if (navigationNode->GetIsOnAnimation()) { + LOGI("navigation is on animation"); + return; + } + auto navBarNode = AceType::DynamicCast(navigationNode->GetNavBarNode()); + CHECK_NULL_VOID(navBarNode); + auto titleBarNode = AceType::DynamicCast(navBarNode->GetTitleBarNode()); + auto navDestination = AceType::DynamicCast(navDestinationNode); + auto destinationTitleBarNode = AceType::DynamicCast(navDestination->GetTitleBarNode()); + auto backButtonNode = AceType::DynamicCast(destinationTitleBarNode->GetBackButton()); + if (titleBarNode || destinationTitleBarNode) { + TitleTransitionOutAnimation(titleBarNode, destinationTitleBarNode); + } + if (backButtonNode) { + BackButtonAnimation(backButtonNode, false); + } + auto navigationContentNode = AceType::DynamicCast(navigationNode->GetContentNode()); + CHECK_NULL_VOID(navigationContentNode); + NavTransitionOutAnimation(navBarNode, navDestination, navigationContentNode); + auto navigationPattern = AceType::DynamicCast(navigationNode)->GetPattern(); + CHECK_NULL_VOID(navigationPattern); + navigationPattern->RemoveNavDestination(); +} + +void NavigationGroupNode::BackToPreNavDestination(const RefPtr& preNavDestinationNode, + const RefPtr& navDestinationNode, const RefPtr& navRouterPattern) +{ + auto navigationNode = AceType::WeakClaim(this).Upgrade(); + if (navigationNode->GetIsOnAnimation()) { + LOGI("navigation is on animation"); + return; + } + auto preNavDestination = AceType::DynamicCast(preNavDestinationNode); + CHECK_NULL_VOID(preNavDestination); + auto navigationContentNode = AceType::DynamicCast(navigationNode->GetContentNode()); + CHECK_NULL_VOID(navigationContentNode); + + auto navDestination = AceType::DynamicCast(navDestinationNode); + auto preDestinationTitleBarNode = AceType::DynamicCast(preNavDestination->GetTitleBarNode()); + auto destinationTitleBarNode = AceType::DynamicCast(navDestination->GetTitleBarNode()); + if (preDestinationTitleBarNode || destinationTitleBarNode) { + TitleTransitionOutAnimation(preDestinationTitleBarNode, destinationTitleBarNode); + } + auto backButtonNode = AceType::DynamicCast(destinationTitleBarNode->GetBackButton()); + if (backButtonNode) { + BackButtonAnimation(backButtonNode, false); + } + NavTransitionBackToPreAnimation(preNavDestination, navDestination, navigationContentNode); + + navigationContentNode->AddChild(preNavDestination); + auto navigationPattern = GetPattern(); + CHECK_NULL_VOID(navigationPattern); + auto navDestinationPattern = preNavDestination->GetPattern(); + auto navRouteMode = NavRouteMode::REPLACE; + RefPtr routeInfo; + if (navRouterPattern) { + routeInfo = navDestinationPattern->GetRouteInfo(); + } + if (routeInfo) { + auto name = routeInfo->GetName(); + navigationPattern->AddNavDestinationNode(name, preNavDestination, navRouteMode, routeInfo); + } else { + auto name = navDestinationPattern->GetName(); + navigationPattern->AddNavDestinationNode(name, preNavDestination, navRouteMode); + } +} + +void NavigationGroupNode::NavTransitionInAnimation( + const RefPtr& transitionOutNode, const RefPtr& navDestination) +{ + auto navigationNode = AceType::WeakClaim(this).Upgrade(); + if (navigationNode->GetIsOnAnimation()) { + LOGI("navigation is on animation"); + return; + } + AnimationOption option; + option.SetCurve(interpolatingSpringCurve); + option.SetFillMode(FillMode::FORWARDS); + option.SetDuration(DEFAULT_ANIMATION_DURATION); + + auto transitionOutNodeContext = transitionOutNode->GetRenderContext(); + auto transitionInNodeContext = navDestination->GetRenderContext(); + CHECK_NULL_VOID(transitionOutNodeContext && transitionInNodeContext); + auto size = navigationNode->GetGeometryNode()->GetFrameSize(); + auto nodeWidth = size.Width(); + auto nodeHeight = size.Height(); + option.SetOnFinishEvent( + [transitionOutNodeContextWK = WeakClaim(RawPtr(transitionOutNodeContext)), + navigationNodeWK = WeakClaim(RawPtr(navigationNode)), navDestinationWK = WeakClaim(RawPtr(navDestination)), + id = Container::CurrentId(), nodeHeight] { + ContainerScope scope(id); + auto context = PipelineContext::GetCurrentContext(); + CHECK_NULL_VOID_NOLOG(context); + auto taskExecutor = context->GetTaskExecutor(); + CHECK_NULL_VOID_NOLOG(taskExecutor); + taskExecutor->PostTask( + [transitionOutNodeContextWK, navigationNodeWK, navDestinationWK, id, nodeHeight]() { + auto transitionOutNodeContext = transitionOutNodeContextWK.Upgrade(); + auto navigationNode = navigationNodeWK.Upgrade(); + auto navDestination = navDestinationWK.Upgrade(); + ContainerScope scope(id); + if (transitionOutNodeContext) { + transitionOutNodeContext->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); + } + if (navDestination) { + navDestination->GetRenderContext()->ClipWithRRect( + RectF(0.0f, 0.0f, Infinity(), nodeHeight), RadiusF(EdgeF(0.0f, 0.0f))); + } + navigationNode->SetIsOnAnimation(false); + }, + TaskExecutor::TaskType::UI); + }); + + transitionOutNodeContext->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); + transitionInNodeContext->ClipWithRRect( + RectF(nodeWidth * HALF, 0.0f, nodeWidth, nodeHeight), RadiusF(EdgeF(0.0f, 0.0f))); + transitionInNodeContext->OnTransformTranslateUpdate({ nodeWidth * HALF, 0.0f, 0.0f }); + AnimationUtils::Animate( + option, + [transitionOutNodeContext, transitionInNodeContext, nodeWidth, nodeHeight, navigationNode]() { + navigationNode->SetIsOnAnimation(true); + transitionOutNodeContext->OnTransformTranslateUpdate({ -nodeWidth * PARENT_PAGE_OFFSET, 0.0f, 0.0f }); + transitionInNodeContext->ClipWithRRect( + RectF(0.0f, 0.0f, nodeWidth, nodeHeight), RadiusF(EdgeF(0.0f, 0.0f))); + transitionInNodeContext->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); + }, + option.GetOnFinishEvent()); + MaskAnimation(transitionOutNodeContext); +} + +void NavigationGroupNode::NavTransitionOutAnimation(const RefPtr& navBarNode, + const RefPtr& navDestination, const RefPtr& navigationContentNode) +{ + auto navigationNode = AceType::WeakClaim(this).Upgrade(); + if (navigationNode->GetIsOnAnimation()) { + LOGI("navigation is on animation"); + return; + } + AnimationOption option; + option.SetCurve(interpolatingSpringCurve); + option.SetFillMode(FillMode::FORWARDS); + option.SetDuration(DEFAULT_ANIMATION_DURATION); + auto navigationContext = navBarNode->GetRenderContext(); + CHECK_NULL_VOID(navigationContext); + auto navDestinationContext = navDestination->GetRenderContext(); + CHECK_NULL_VOID(navDestinationContext); + + auto node = AceType::DynamicCast(navigationNode); + auto size = node->GetGeometryNode()->GetFrameSize(); + auto nodeWidth = size.Width(); + auto nodeHeight = size.Height(); + + option.SetOnFinishEvent( + [navigationContentWK = WeakClaim(RawPtr(navigationContentNode)), + navigationNodeWK = WeakClaim(RawPtr(navigationNode)), id = Container::CurrentId(), nodeHeight] { + ContainerScope scope(id); + auto context = PipelineContext::GetCurrentContext(); + CHECK_NULL_VOID_NOLOG(context); + auto taskExecutor = context->GetTaskExecutor(); + CHECK_NULL_VOID_NOLOG(taskExecutor); + // animation finish event should be posted to UI thread. + taskExecutor->PostTask( + [navigationContentWK, navigationNodeWK, id, nodeHeight]() { + auto navigationContentNode = navigationContentWK.Upgrade(); + auto navigationNode = navigationNodeWK.Upgrade(); + CHECK_NULL_VOID(navigationNode && navigationContentNode); + navigationContentNode->GetRenderContext()->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); + navigationContentNode->GetRenderContext()->ClipWithRRect( + RectF(0.0f, 0.0f, Infinity(), nodeHeight), RadiusF(EdgeF(0.0f, 0.0f))); + ContainerScope scope(id); + navigationContentNode->MarkModifyDone(); + navigationNode->MarkModifyDone(); + navigationContentNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE); + navigationNode->SetIsOnAnimation(false); + }, + TaskExecutor::TaskType::UI); + }); + + navDestinationContext->ClipWithRRect(RectF(0.0f, 0.0f, nodeWidth, nodeHeight), RadiusF(EdgeF(0.0f, 0.0f))); + navDestinationContext->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); + navigationContext->OnTransformTranslateUpdate({ -nodeWidth * PARENT_PAGE_OFFSET, 0.0f, 0.0f }); + AnimationUtils::Animate( + option, + [navDestinationContext, navigationContext, nodeWidth, nodeHeight, navigationNode]() { + navigationNode->SetIsOnAnimation(true); + if (navDestinationContext) { + navDestinationContext->ClipWithRRect( + RectF(nodeWidth * HALF, 0.0f, nodeWidth, nodeHeight), RadiusF(EdgeF(0.0f, 0.0f))); + navDestinationContext->OnTransformTranslateUpdate({ nodeWidth * HALF, 0.0f, 0.0f }); + } + if (navigationContext) { + navigationContext->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); + } + }, + option.GetOnFinishEvent()); + + AnimationOption maskOption; + maskOption.SetCurve(Curves::FRICTION); + maskOption.SetDuration(MASK_DURATION); + maskOption.SetFillMode(FillMode::FORWARDS); + navigationContext->SetActualForegroundColor(MASK_COLOR); + AnimationUtils::Animate( + maskOption, [navigationContext]() { navigationContext->SetActualForegroundColor(DEFAULT_MASK_COLOR); }); +} + +void NavigationGroupNode::NavTransitionBackToPreAnimation(const RefPtr& preDestination, + const RefPtr& curNavDestination, const RefPtr& navigationContentNode) +{ + auto navigationNode = AceType::WeakClaim(this).Upgrade(); + CHECK_NULL_VOID(navigationNode); + if (navigationNode->GetIsOnAnimation()) { + LOGI("navigation is on animation"); + return; + } + AnimationOption option; + option.SetCurve(interpolatingSpringCurve); + option.SetFillMode(FillMode::FORWARDS); + option.SetDuration(DEFAULT_ANIMATION_DURATION); + auto preDestinationContext = preDestination->GetRenderContext(); + CHECK_NULL_VOID(preDestinationContext); + auto navDestinationContext = curNavDestination->GetRenderContext(); + CHECK_NULL_VOID(navDestinationContext); + + auto node = AceType::DynamicCast(navigationNode); + auto size = node->GetGeometryNode()->GetFrameSize(); + auto nodeWidth = size.Width(); + auto nodeHeight = size.Height(); + + option.SetOnFinishEvent([id = Container::CurrentId(), navigationNodeWK = WeakClaim(RawPtr(navigationNode)), + curNavDestinationWK = WeakClaim(RawPtr(curNavDestination)), + navigationContentNodeWK = WeakClaim(RawPtr(navigationContentNode)), nodeHeight] { + ContainerScope scope(id); + auto context = PipelineContext::GetCurrentContext(); + CHECK_NULL_VOID_NOLOG(context); + auto taskExecutor = context->GetTaskExecutor(); + CHECK_NULL_VOID_NOLOG(taskExecutor); + // animation finish event should be posted to UI thread. + taskExecutor->PostTask( + [curNavDestinationWK, navigationContentNodeWK, navigationNodeWK, id, nodeHeight]() { + auto curNavDestination = curNavDestinationWK.Upgrade(); + auto navigationContentNode = navigationContentNodeWK.Upgrade(); + auto navigationNode = navigationNodeWK.Upgrade(); + CHECK_NULL_VOID(navigationNode && curNavDestination && navigationContentNode); + curNavDestination->GetRenderContext()->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); + curNavDestination->GetRenderContext()->ClipWithRRect( + RectF(0.0f, 0.0f, Infinity(), nodeHeight), RadiusF(EdgeF(0.0f, 0.0f))); + ContainerScope scope(id); + navigationContentNode->MarkModifyDone(); + navigationNode->MarkModifyDone(); + navigationContentNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE); + navigationNode->SetIsOnAnimation(false); + }, + TaskExecutor::TaskType::UI); + }); + + navDestinationContext->ClipWithRRect(RectF(0.0f, 0.0f, nodeWidth, nodeHeight), RadiusF(EdgeF(0.0f, 0.0f))); + navDestinationContext->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); + preDestinationContext->OnTransformTranslateUpdate({ -nodeWidth * PARENT_PAGE_OFFSET, 0.0f, 0.0f }); + AnimationUtils::Animate( + option, + [navDestinationContext, preDestinationContext, nodeWidth, nodeHeight, navigationNode]() { + navigationNode->SetIsOnAnimation(true); + if (navDestinationContext) { + navDestinationContext->ClipWithRRect( + RectF(nodeWidth * HALF, 0.0f, nodeWidth, nodeHeight), RadiusF(EdgeF(0.0f, 0.0f))); + navDestinationContext->OnTransformTranslateUpdate({ nodeWidth * HALF, 0.0f, 0.0f }); + } + if (preDestinationContext) { + preDestinationContext->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); + } + }, + option.GetOnFinishEvent()); + + AnimationOption maskOption; + maskOption.SetCurve(Curves::FRICTION); + maskOption.SetDuration(MASK_DURATION); + maskOption.SetFillMode(FillMode::FORWARDS); + preDestinationContext->SetActualForegroundColor(MASK_COLOR); + AnimationUtils::Animate( + maskOption, [preDestinationContext]() { preDestinationContext->SetActualForegroundColor(DEFAULT_MASK_COLOR); }); +} + +void NavigationGroupNode::TitleTransitionInAnimation( + const RefPtr& titleBarNode, const RefPtr& destinationTitleBarNode) +{ + AnimationOption option; + option.SetCurve(interpolatingSpringCurve); + option.SetFillMode(FillMode::FORWARDS); + option.SetDuration(DEFAULT_ANIMATION_DURATION); + + auto transitionOutNodeContext = titleBarNode->GetRenderContext(); + auto transitionInNodeContext = destinationTitleBarNode->GetRenderContext(); + auto navigationNode = AceType::WeakClaim(this).Upgrade(); + auto size = navigationNode->GetGeometryNode()->GetFrameSize(); + auto nodeWidth = size.Width(); + + option.SetOnFinishEvent( + [transitionOutNodeContextWK = WeakClaim(RawPtr(transitionOutNodeContext)), id = Container::CurrentId()] { + ContainerScope scope(id); + auto context = PipelineContext::GetCurrentContext(); + CHECK_NULL_VOID_NOLOG(context); + auto taskExecutor = context->GetTaskExecutor(); + CHECK_NULL_VOID_NOLOG(taskExecutor); + // animation finish event should be posted to UI thread. + taskExecutor->PostTask( + [transitionOutNodeContextWK, id]() { + auto transitionOutNodeContext = transitionOutNodeContextWK.Upgrade(); + CHECK_NULL_VOID(transitionOutNodeContext); + ContainerScope scope(id); + transitionOutNodeContext->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); + }, + TaskExecutor::TaskType::UI); + }); + if (transitionOutNodeContext) { + transitionOutNodeContext->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); + } + if (transitionInNodeContext) { + transitionInNodeContext->OnTransformTranslateUpdate({ nodeWidth * HALF, 0.0f, 0.0f }); + } + AnimationUtils::Animate( + option, + [transitionOutNodeContext, transitionInNodeContext, nodeWidth]() { + if (transitionOutNodeContext) { + transitionOutNodeContext->OnTransformTranslateUpdate({ nodeWidth * PARENT_TITLE_OFFSET, 0.0f, 0.0f }); + } + if (transitionInNodeContext) { + transitionInNodeContext->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); + } + }, + option.GetOnFinishEvent()); + + AnimationOption opacityOption; + opacityOption.SetCurve(Curves::SHARP); + opacityOption.SetDelay(OPACITY_TITLE_IN_DELAY); + opacityOption.SetDuration(OPACITY_TITLE_DURATION); + opacityOption.SetFillMode(FillMode::FORWARDS); + transitionInNodeContext->OpacityAnimation(opacityOption, 0.0f, 1.0f); +} + +void NavigationGroupNode::TitleTransitionOutAnimation( + const RefPtr& titleBarNode, const RefPtr& destinationTitleBarNode) +{ + AnimationOption option; + option.SetCurve(interpolatingSpringCurve); + option.SetFillMode(FillMode::FORWARDS); + option.SetDuration(DEFAULT_ANIMATION_DURATION); + + auto transitionOutNodeContext = destinationTitleBarNode->GetRenderContext(); + CHECK_NULL_VOID(transitionOutNodeContext); + auto transitionInNodeContext = titleBarNode->GetRenderContext(); + CHECK_NULL_VOID(transitionInNodeContext); + auto navigationNode = AceType::WeakClaim(this).Upgrade(); + auto size = navigationNode->GetGeometryNode()->GetFrameSize(); + auto nodeWidth = size.Width(); + + option.SetOnFinishEvent( + [transitionOutNodeContextWK = WeakClaim(RawPtr(transitionOutNodeContext)), id = Container::CurrentId()] { + ContainerScope scope(id); + auto context = PipelineContext::GetCurrentContext(); + CHECK_NULL_VOID_NOLOG(context); + auto taskExecutor = context->GetTaskExecutor(); + CHECK_NULL_VOID_NOLOG(taskExecutor); + // animation finish event should be posted to UI thread. + taskExecutor->PostTask( + [transitionOutNodeContextWK, id]() { + auto transitionOutNodeContext = transitionOutNodeContextWK.Upgrade(); + CHECK_NULL_VOID(transitionOutNodeContext); + ContainerScope scope(id); + transitionOutNodeContext->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); + }, + TaskExecutor::TaskType::UI); + }); + + transitionOutNodeContext->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); + transitionInNodeContext->OnTransformTranslateUpdate({ nodeWidth * PARENT_TITLE_OFFSET, 0.0f, 0.0f }); + AnimationUtils::Animate( + option, + [transitionOutNodeContext, transitionInNodeContext, nodeWidth]() { + transitionOutNodeContext->OnTransformTranslateUpdate({ nodeWidth * HALF, 0.0f, 0.0f }); + transitionInNodeContext->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); + }, + option.GetOnFinishEvent()); + TitleOpacityAnimation(transitionOutNodeContext); +} + +void NavigationGroupNode::BackButtonAnimation(const RefPtr& backButtonNode, bool isTransitionIn) +{ + AnimationOption transitionOption; + transitionOption.SetCurve(Curves::SHARP); + transitionOption.SetFillMode(FillMode::FORWARDS); + auto backButtonNodeContext = backButtonNode->GetRenderContext(); + CHECK_NULL_VOID(backButtonNodeContext); + if (isTransitionIn) { + transitionOption.SetDelay(OPACITY_BACKBUTTON_IN_DELAY); + transitionOption.SetDuration(OPACITY_BACKBUTTON_IN_DURATION); + backButtonNodeContext->OpacityAnimation(transitionOption, 0.0, 1.0); + } else { + transitionOption.SetDuration(OPACITY_BACKBUTTON_OUT_DURATION); + transitionOption.SetOnFinishEvent( + [backButtonNodeContextWK = WeakClaim(RawPtr(backButtonNodeContext)), id = Container::CurrentId()] { + ContainerScope scope(id); + auto context = PipelineContext::GetCurrentContext(); + CHECK_NULL_VOID_NOLOG(context); + auto taskExecutor = context->GetTaskExecutor(); + CHECK_NULL_VOID_NOLOG(taskExecutor); + // animation finish event should be posted to UI thread. + taskExecutor->PostTask( + [backButtonNodeContextWK, id]() { + auto backButtonNodeContext = backButtonNodeContextWK.Upgrade(); + CHECK_NULL_VOID(backButtonNodeContext); + ContainerScope scope(id); + backButtonNodeContext->UpdateOpacity(1.0); + }, + TaskExecutor::TaskType::UI); + }); + backButtonNodeContext->OpacityAnimation(transitionOption, 1.0, 0.0); + } +} + +void NavigationGroupNode::MaskAnimation(const RefPtr& transitionOutNodeContext) +{ + AnimationOption maskOption; + maskOption.SetCurve(Curves::FRICTION); + maskOption.SetDuration(MASK_DURATION); + maskOption.SetFillMode(FillMode::FORWARDS); + maskOption.SetOnFinishEvent( + [transitionOutNodeContextWK = WeakClaim(RawPtr(transitionOutNodeContext)), id = Container::CurrentId()] { + ContainerScope scope(id); + auto context = PipelineContext::GetCurrentContext(); + CHECK_NULL_VOID_NOLOG(context); + auto taskExecutor = context->GetTaskExecutor(); + CHECK_NULL_VOID_NOLOG(taskExecutor); + taskExecutor->PostTask( + [transitionOutNodeContextWK, id]() { + auto transitionOutNodeContext = transitionOutNodeContextWK.Upgrade(); + ContainerScope scope(id); + if (transitionOutNodeContext) { + transitionOutNodeContext->SetActualForegroundColor(DEFAULT_MASK_COLOR); + } + }, + TaskExecutor::TaskType::UI); + }); + transitionOutNodeContext->SetActualForegroundColor(DEFAULT_MASK_COLOR); + AnimationUtils::Animate( + maskOption, [transitionOutNodeContext]() { transitionOutNodeContext->SetActualForegroundColor(MASK_COLOR); }, + maskOption.GetOnFinishEvent()); +} + +void NavigationGroupNode::TitleOpacityAnimation(const RefPtr& transitionOutNodeContext) +{ + AnimationOption opacityOption; + opacityOption.SetCurve(Curves::SHARP); + opacityOption.SetDelay(OPACITY_TITLE_OUT_DELAY); + opacityOption.SetDuration(OPACITY_TITLE_DURATION); + opacityOption.SetFillMode(FillMode::FORWARDS); + opacityOption.SetOnFinishEvent( + [transitionOutNodeContextWK = WeakClaim(RawPtr(transitionOutNodeContext)), id = Container::CurrentId()] { + ContainerScope scope(id); + auto context = PipelineContext::GetCurrentContext(); + CHECK_NULL_VOID_NOLOG(context); + auto taskExecutor = context->GetTaskExecutor(); + CHECK_NULL_VOID_NOLOG(taskExecutor); + // animation finish event should be posted to UI thread. + taskExecutor->PostTask( + [transitionOutNodeContextWK, id]() { + auto transitionOutNodeContext = transitionOutNodeContextWK.Upgrade(); + CHECK_NULL_VOID(transitionOutNodeContext); + ContainerScope scope(id); + transitionOutNodeContext->UpdateOpacity(1.0); + }, + TaskExecutor::TaskType::UI); + }); + transitionOutNodeContext->OpacityAnimation(opacityOption, 1.0, 0.0); +} + +void NavigationGroupNode::SetOnStateChangeFalse( + const RefPtr& preNavDestinationNode, const RefPtr& navDestinationNode, bool isBackButton) +{ + auto preNavDestination = AceType::DynamicCast(preNavDestinationNode); + CHECK_NULL_VOID(preNavDestination); + auto navDestination = AceType::DynamicCast(navDestinationNode); + CHECK_NULL_VOID(navDestination); + if (!isBackButton && navDestination == preNavDestination) { + return; + } + auto navigationNode = AceType::WeakClaim(this).Upgrade(); + CHECK_NULL_VOID(navigationNode); + auto navBarNode = AceType::DynamicCast(navigationNode->GetNavBarNode()); + CHECK_NULL_VOID(navBarNode); + auto navBarContentNode = navBarNode->GetNavBarContentNode(); + CHECK_NULL_VOID(navBarContentNode); + auto navigationPattern = navigationNode->GetPattern(); + CHECK_NULL_VOID(navigationPattern); + + auto navDestinationPattern = preNavDestination->GetPattern(); + CHECK_NULL_VOID(navDestinationPattern); + if (isBackButton && preNavDestination) { + auto eventHub = preNavDestination->GetEventHub(); + CHECK_NULL_VOID(eventHub); + eventHub->FireChangeEvent(true); + eventHub->FireOnShownEvent(); + } + + auto eventHub = navDestination->GetEventHub(); + CHECK_NULL_VOID(eventHub); + eventHub->FireChangeEvent(false); + eventHub->FireOnHiddenEvent(); +} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/navigation/navigation_group_node.h b/frameworks/core/components_ng/pattern/navigation/navigation_group_node.h index 1759a94c656..82ffdd56cd1 100644 --- a/frameworks/core/components_ng/pattern/navigation/navigation_group_node.h +++ b/frameworks/core/components_ng/pattern/navigation/navigation_group_node.h @@ -23,6 +23,8 @@ #include "core/components_ng/base/group_node.h" #include "core/components_ng/pattern/navigation/bar_item_node.h" #include "core/components_ng/pattern/navigation/navigation_declaration.h" +#include "core/components_ng/pattern/navigation/navigation_stack.h" +#include "core/components_ng/pattern/navrouter/navrouter_pattern.h" #include "core/components_ng/property/property.h" namespace OHOS::Ace::NG { @@ -35,7 +37,7 @@ public: {} ~NavigationGroupNode() override = default; void AddChildToGroup(const RefPtr& child, int32_t slot = DEFAULT_NODE_SLOT) override; - void AddNavDestinationToNavigation(const RefPtr& parent); + void AddNavDestinationToNavigation(); static RefPtr GetOrCreateGroupNode( const std::string& tag, int32_t nodeId, const std::function(void)>& patternCreator); @@ -95,15 +97,36 @@ public: } void ToJsonValue(std::unique_ptr& json) const override; - static RefPtr GetNavDestinationNode(RefPtr uiNode); + void SetBackButtonEvent( + const RefPtr& navDestinationNode, const RefPtr& navRouterPattern = nullptr); + void BackToNavBar(const RefPtr& navDestinationNode); + void BackToPreNavDestination(const RefPtr& preNavDestinationNode, const RefPtr& navDestinationNode, + const RefPtr& navRouterPattern = nullptr); + void AddBackButtonIconToNavDestination(const RefPtr& navDestinationNode); + void SetBackButtonVisible(const RefPtr& navDestinationNode); + void SetOnStateChangeFalse( + const RefPtr& preNavDestination, const RefPtr& navDestination, bool isBackButton = false); + + void NavTransitionInAnimation(const RefPtr& transitionOutNode, const RefPtr& navDestination); + void NavTransitionOutAnimation(const RefPtr& navBarNode, const RefPtr& navDestination, + const RefPtr& navigationContentNode); + void NavTransitionBackToPreAnimation(const RefPtr& preDestination, + const RefPtr& curNavDestination, const RefPtr& navigationContentNode); + void TitleTransitionInAnimation( + const RefPtr& titleBarNode, const RefPtr& destinationTitleBarNode); + void TitleTransitionOutAnimation( + const RefPtr& titleBarNode, const RefPtr& destinationTitleBarNode); + void BackButtonAnimation(const RefPtr& backButtonNode, bool isTransitionIn); + void MaskAnimation(const RefPtr& transitionOutNodeContext); + void TitleOpacityAnimation(const RefPtr& transitionOutNodeContext); private: RefPtr navBarNode_; RefPtr contentNode_; RefPtr dividerNode_; - bool isOnAnimation_ {false}; - bool isModeChange_ {false}; + bool isOnAnimation_ { false }; + bool isModeChange_ { false }; }; } // namespace OHOS::Ace::NG #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_NAVIGATION_GROUP_NODE_H diff --git a/frameworks/core/components_ng/pattern/navigation/navigation_pattern.cpp b/frameworks/core/components_ng/pattern/navigation/navigation_pattern.cpp index 066ab93f156..e9e9a0f90f2 100644 --- a/frameworks/core/components_ng/pattern/navigation/navigation_pattern.cpp +++ b/frameworks/core/components_ng/pattern/navigation/navigation_pattern.cpp @@ -134,7 +134,7 @@ void NavigationPattern::OnModifyDone() navigationStack_->SetNavPathList(navPathList_); auto contentNode = hostNode->GetContentNode(); contentNode->Clean(); - hostNode->AddNavDestinationToNavigation(hostNode); + hostNode->AddNavDestinationToNavigation(); auto newTopNavPath = GetTopNavPath(); if (preTopNavPath != newTopNavPath) { diff --git a/frameworks/core/components_ng/pattern/navrouter/navrouter_group_node.cpp b/frameworks/core/components_ng/pattern/navrouter/navrouter_group_node.cpp index 09a9f34483b..2b010d2d65c 100644 --- a/frameworks/core/components_ng/pattern/navrouter/navrouter_group_node.cpp +++ b/frameworks/core/components_ng/pattern/navrouter/navrouter_group_node.cpp @@ -18,21 +18,17 @@ #include "base/memory/ace_type.h" #include "base/memory/referenced.h" #include "base/utils/utils.h" -#include "core/common/container.h" #include "core/components_ng/base/frame_node.h" #include "core/components_ng/base/view_stack_processor.h" -#include "core/components_ng/pattern/image/image_layout_property.h" #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h" #include "core/components_ng/pattern/navigation/nav_bar_node.h" #include "core/components_ng/pattern/navigation/navigation_declaration.h" #include "core/components_ng/pattern/navigation/navigation_group_node.h" #include "core/components_ng/pattern/navigation/navigation_layout_property.h" #include "core/components_ng/pattern/navigation/navigation_pattern.h" -#include "core/components_ng/pattern/navigation/title_bar_layout_property.h" #include "core/components_ng/pattern/navigation/title_bar_node.h" #include "core/components_ng/pattern/navrouter/navdestination_event_hub.h" #include "core/components_ng/pattern/navrouter/navdestination_group_node.h" -#include "core/components_ng/pattern/navrouter/navdestination_layout_property.h" #include "core/components_ng/pattern/navrouter/navdestination_pattern.h" #include "core/components_ng/pattern/navrouter/navrouter_event_hub.h" #include "core/components_ng/pattern/navrouter/navrouter_pattern.h" @@ -40,23 +36,6 @@ #include "core/pipeline/base/constants.h" namespace OHOS::Ace::NG { -namespace { -constexpr double HALF = 0.5; -constexpr double PARENT_PAGE_OFFSET = 0.2; -constexpr double PARENT_TITLE_OFFSET = 0.02; -constexpr int32_t MASK_DURATION = 350; -constexpr int32_t OPACITY_TITLE_OUT_DELAY = 17; -constexpr int32_t OPACITY_TITLE_IN_DELAY = 33; -constexpr int32_t OPACITY_TITLE_DURATION = 150; -constexpr int32_t OPACITY_BACKBUTTON_IN_DELAY = 150; -constexpr int32_t OPACITY_BACKBUTTON_IN_DURATION = 200; -constexpr int32_t OPACITY_BACKBUTTON_OUT_DURATION = 67; -constexpr int32_t DEFAULT_ANIMATION_DURATION = 400; -const Color MASK_COLOR = Color::FromARGB(25, 0, 0, 0); -const Color DEFAULT_MASK_COLOR = Color::FromARGB(0, 0, 0, 0); -const RefPtr interpolatingSpringCurve = - AceType::MakeRefPtr(0.0f, 1.0f, 342.0f, 37.0f); -} // namespace RefPtr NavRouterGroupNode::GetOrCreateGroupNode( const std::string& tag, int32_t nodeId, const std::function(void)>& patternCreator) { @@ -121,7 +100,13 @@ void NavRouterGroupNode::OnAttachToMainTree(bool recursive) parent = parent->GetParent(); } SetDestinationChangeEvent(parent); - SetBackButtonEvent(parent); + auto navigationNode = AceType::DynamicCast(parent); + CHECK_NULL_VOID(navigationNode); + auto navDestinationNode = AceType::DynamicCast(GetNavDestinationNode()); + CHECK_NULL_VOID(navDestinationNode); + auto navRouterPattern = GetPattern(); + CHECK_NULL_VOID(navRouterPattern); + navigationNode->SetBackButtonEvent(navDestinationNode, navRouterPattern); } void NavRouterGroupNode::SetDestinationChangeEvent(const RefPtr& parent) @@ -143,115 +128,6 @@ void NavRouterGroupNode::SetDestinationChangeEvent(const RefPtr& parent) eventHub->SetOnDestinationChange(std::move(onDestinationChange)); } -void NavRouterGroupNode::AddBackButtonIconToNavDestination(const RefPtr& parent) -{ - auto navigationNode = AceType::DynamicCast(parent); - CHECK_NULL_VOID(navigationNode); - auto navigationLayoutProperty = navigationNode->GetLayoutProperty(); - CHECK_NULL_VOID(navigationLayoutProperty); - auto navDestination = AceType::DynamicCast(GetNavDestinationNode()); - CHECK_NULL_VOID(navDestination); - auto navDestinationLayoutProperty = navDestination->GetLayoutProperty(); - CHECK_NULL_VOID(navDestinationLayoutProperty); - - // back button icon - if (navigationLayoutProperty->HasNoPixMap()) { - if (navigationLayoutProperty->HasImageSource()) { - navDestinationLayoutProperty->UpdateImageSource(navigationLayoutProperty->GetImageSourceValue()); - } - if (navigationLayoutProperty->HasPixelMap()) { - navDestinationLayoutProperty->UpdatePixelMap(navigationLayoutProperty->GetPixelMapValue()); - } - navDestinationLayoutProperty->UpdateNoPixMap(navigationLayoutProperty->GetNoPixMapValue()); - navDestination->MarkModifyDone(); - } -} - -void NavRouterGroupNode::SetBackButtonEvent(const RefPtr& parent) -{ - AddBackButtonIconToNavDestination(parent); - auto navigationNode = AceType::DynamicCast(parent); - CHECK_NULL_VOID(navigationNode); - // navdestination under navrouter - auto navDestination = AceType::DynamicCast(GetNavDestinationNode()); - CHECK_NULL_VOID(navDestination); - auto titleBarNode = AceType::DynamicCast(navDestination->GetTitleBarNode()); - CHECK_NULL_VOID(titleBarNode); - auto backButtonNode = AceType::DynamicCast(titleBarNode->GetBackButton()); - CHECK_NULL_VOID(backButtonNode); - auto backButtonEventHub = backButtonNode->GetEventHub(); - CHECK_NULL_VOID(backButtonEventHub); - auto navRouterPattern = GetPattern(); - CHECK_NULL_VOID(navRouterPattern); - auto weak = WeakClaim(this); - auto navRouter = weak.Upgrade(); - CHECK_NULL_VOID(navRouter); - auto onBackButtonEvent = [navDestination = navDestination, navigation = navigationNode, navRouter = navRouter]( - GestureEvent& /*info*/) { - // the one before navdestination in the stack - auto navRouterPattern = navRouter->GetPattern(); - CHECK_NULL_VOID(navRouterPattern); - auto eventHub = navDestination->GetEventHub(); - CHECK_NULL_VOID(eventHub); - auto onBackPressed = eventHub->GetOnBackPressedEvent(); - bool isOverride = false; - if (onBackPressed != nullptr) { - isOverride = eventHub->FireOnBackPressedEvent(); - } - auto destinationContent = navDestination->GetContentNode(); - if (destinationContent) { - auto navDestinationPattern = navDestination->GetPattern(); - CHECK_NULL_VOID(navDestinationPattern); - auto shallowBuilder = navDestinationPattern->GetShallowBuilder(); - CHECK_NULL_VOID(shallowBuilder); - shallowBuilder->MarkIsExecuteDeepRenderDone(false); - auto mode = navRouterPattern->GetNavRouteMode(); - if (mode == NavRouteMode::PUSH_WITH_RECREATE || mode == NavRouteMode::REPLACE) { - destinationContent->Clean(); - } - } - if (isOverride) { - LOGI("this onBackButtonPressed event returns false"); - return; - } - auto layoutProperty = navigation->GetLayoutProperty(); - CHECK_NULL_VOID(layoutProperty); - auto navigationPattern = navigation->GetPattern(); - CHECK_NULL_VOID(navigationPattern); - auto preNavDestination = AceType::DynamicCast( - navigationPattern->GetPreNavDestination(navRouterPattern->GetNavDestination())); - if (layoutProperty->GetNavigationModeValue(NavigationMode::AUTO) == NavigationMode::STACK) { - if (preNavDestination) { - navRouter->BackToPreNavDestination(preNavDestination, navigation, navRouterPattern); - navRouter->SetOnStateChangeFalse(navDestination, navDestination, navigation, true); - layoutProperty->UpdateDestinationChange(true); - return; - } - navRouter->BackToNavBar(navigation); - navRouter->SetOnStateChangeFalse(navDestination, navDestination, navigation, true); - layoutProperty->UpdateDestinationChange(false); - return; - } - - if (layoutProperty->GetNavigationModeValue(NavigationMode::AUTO) == NavigationMode::SPLIT) { - if (preNavDestination) { - navRouter->BackToPreNavDestination(preNavDestination, navigation, navRouterPattern); - navRouter->SetOnStateChangeFalse(navDestination, navDestination, navigation, true); - layoutProperty->UpdateDestinationChange(false); - return; - } - } - navigation->MarkModifyDone(); - }; // backButton event - - navDestination->SetNavDestinationBackButtonEvent(onBackButtonEvent); - auto clickEvent = AceType::MakeRefPtr(std::move(onBackButtonEvent)); - if (!backButtonEventHub->GetGestureEventHub()) { - return; - } - backButtonEventHub->GetOrCreateGestureEventHub()->AddClickEvent(clickEvent); -} - void NavRouterGroupNode::AddNavDestinationToNavigation(const RefPtr& parent) { auto navigationNode = AceType::DynamicCast(parent); @@ -300,7 +176,7 @@ void NavRouterGroupNode::AddNavDestinationToNavigation(const RefPtr& par shallowBuilder->MarkIsExecuteDeepRenderDone(false); destinationContent->Clean(); } - SetOnStateChangeFalse(currentNavDestination, navDestination, parent); + navigationNode->SetOnStateChangeFalse(currentNavDestination, navDestination); } auto parentNode = GetParent(); @@ -320,7 +196,7 @@ void NavRouterGroupNode::AddNavDestinationToNavigation(const RefPtr& par if (!(navigationStack->Empty() && navigationLayoutProperty->GetNavigationModeValue(NavigationMode::AUTO) == NavigationMode::SPLIT)) { // add backButton except for the first level page in SPLIT mode - SetBackButtonVisible(navDestination); + navigationNode->SetBackButtonVisible(navDestination); } if (navigationLayoutProperty->GetNavigationModeValue(NavigationMode::AUTO) == NavigationMode::STACK) { if (navBarNode) { @@ -329,12 +205,12 @@ void NavRouterGroupNode::AddNavDestinationToNavigation(const RefPtr& par auto destinationTitleBarNode = AceType::DynamicCast(navDestination->GetTitleBarNode()); auto backButtonNode = AceType::DynamicCast(destinationTitleBarNode->GetBackButton()); if (titleBarNode || destinationTitleBarNode) { - TitleTransitionInAnimation(navigationNode, titleBarNode, destinationTitleBarNode); + navigationNode->TitleTransitionInAnimation(titleBarNode, destinationTitleBarNode); } if (backButtonNode) { - BackButtonAnimation(backButtonNode, true); + navigationNode->BackButtonAnimation(backButtonNode, true); } - NavTransitionInAnimation(navigationNode, navBarNode, navDestination); + navigationNode->NavTransitionInAnimation(navBarNode, navDestination); } else { // stack. More than one destination currentNavDestination = @@ -344,12 +220,12 @@ void NavRouterGroupNode::AddNavDestinationToNavigation(const RefPtr& par auto destinationTitleBarNode = AceType::DynamicCast(navDestination->GetTitleBarNode()); auto backButtonNode = AceType::DynamicCast(destinationTitleBarNode->GetBackButton()); if (curNavTitleBarNode || destinationTitleBarNode) { - TitleTransitionInAnimation(navigationNode, curNavTitleBarNode, destinationTitleBarNode); + navigationNode->TitleTransitionInAnimation(curNavTitleBarNode, destinationTitleBarNode); } if (backButtonNode) { - BackButtonAnimation(backButtonNode, true); + navigationNode->BackButtonAnimation(backButtonNode, true); } - NavTransitionInAnimation(navigationNode, currentNavDestination, navDestination); + navigationNode->NavTransitionInAnimation(currentNavDestination, navDestination); } } // remove if this navDestinationNode is already in the NavigationStack and not at the top, as the latter will @@ -368,111 +244,6 @@ void NavRouterGroupNode::AddNavDestinationToNavigation(const RefPtr& par navigationNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE); } -void NavRouterGroupNode::SetOnStateChangeFalse(const RefPtr& preNavDestination, - const RefPtr& navDestination, const RefPtr& navigation, bool isBackButton) -{ - auto navigationNode = AceType::DynamicCast(navigation); - CHECK_NULL_VOID(navigationNode); - auto navBarNode = AceType::DynamicCast(navigationNode->GetNavBarNode()); - CHECK_NULL_VOID(navBarNode); - auto navBarContentNode = navBarNode->GetNavBarContentNode(); - CHECK_NULL_VOID(navBarContentNode); - if (!isBackButton && navDestination == preNavDestination) { - return; - } - - auto navRouterPattern = GetPattern(); - CHECK_NULL_VOID(navRouterPattern); - auto navigationPattern = navigationNode->GetPattern(); - CHECK_NULL_VOID(navigationPattern); - auto newDestiantion = AceType::DynamicCast( - navigationPattern->GetPreNavDestination(navRouterPattern->GetNavDestination())); - if (isBackButton && newDestiantion) { - auto newEventHub = newDestiantion->GetEventHub(); - CHECK_NULL_VOID(newEventHub); - newEventHub->FireChangeEvent(true); - newEventHub->FireOnShownEvent(); - } - - auto preNavDestinationNode = AceType::DynamicCast(preNavDestination); - CHECK_NULL_VOID(preNavDestinationNode); - auto eventHub = preNavDestinationNode->GetEventHub(); - CHECK_NULL_VOID(eventHub); - eventHub->FireChangeEvent(false); -} - -void NavRouterGroupNode::BackToNavBar(const RefPtr& parent) -{ - auto navigationNode = AceType::DynamicCast(parent); - CHECK_NULL_VOID(navigationNode); - if (navigationNode->GetIsOnAnimation()) { - LOGI("navigation is on animation"); - return; - } - auto navBarNode = AceType::DynamicCast(navigationNode->GetNavBarNode()); - CHECK_NULL_VOID(navBarNode); - auto navigationContentNode = AceType::DynamicCast(navigationNode->GetContentNode()); - CHECK_NULL_VOID(navigationContentNode); - auto navDestination = AceType::DynamicCast(GetNavDestinationNode()); - CHECK_NULL_VOID(navDestination); - - auto titleBarNode = AceType::DynamicCast(navBarNode->GetTitleBarNode()); - auto destinationTitleBarNode = AceType::DynamicCast(navDestination->GetTitleBarNode()); - auto backButtonNode = AceType::DynamicCast(destinationTitleBarNode->GetBackButton()); - if (titleBarNode || destinationTitleBarNode) { - TitleTransitionOutAnimation(navigationNode, titleBarNode, destinationTitleBarNode); - } - if (backButtonNode) { - BackButtonAnimation(backButtonNode, false); - } - NavTransitionOutAnimation(navigationNode, navBarNode, navDestination, navigationContentNode); - auto navigationPattern = AceType::DynamicCast(navigationNode)->GetPattern(); - CHECK_NULL_VOID(navigationPattern); - navigationPattern->RemoveNavDestination(); -} - -void NavRouterGroupNode::BackToPreNavDestination(const RefPtr& preNavDestination, - const RefPtr& navigation, const RefPtr& navRouterPattern) -{ - auto navigationNode = AceType::DynamicCast(navigation); - CHECK_NULL_VOID(navigationNode); - if (navigationNode->GetIsOnAnimation()) { - LOGI("navigation is on animation"); - return; - } - auto navDestination = AceType::DynamicCast(preNavDestination); - CHECK_NULL_VOID(navDestination); - auto navigationContentNode = AceType::DynamicCast(navigationNode->GetContentNode()); - CHECK_NULL_VOID(navigationContentNode); - - auto curNavDestination = AceType::DynamicCast(GetNavDestinationNode()); - CHECK_NULL_VOID(curNavDestination); - auto preDestinationTitleBarNode = AceType::DynamicCast(navDestination->GetTitleBarNode()); - auto destinationTitleBarNode = AceType::DynamicCast(curNavDestination->GetTitleBarNode()); - if (preDestinationTitleBarNode || destinationTitleBarNode) { - TitleTransitionOutAnimation(navigationNode, preDestinationTitleBarNode, destinationTitleBarNode); - } - auto backButtonNode = AceType::DynamicCast(destinationTitleBarNode->GetBackButton()); - if (backButtonNode) { - BackButtonAnimation(backButtonNode, false); - } - NavTransitionBackToPreAnimation(navigationNode, navDestination, curNavDestination, navigationContentNode); - - navigationContentNode->AddChild(navDestination); - auto navigationPattern = AceType::DynamicCast(navigation)->GetPattern(); - CHECK_NULL_VOID(navigationPattern); - auto navDestinationPattern = navDestination->GetPattern(); - auto routeInfo = navDestinationPattern->GetRouteInfo(); - auto navRouteMode = NavRouteMode::REPLACE; - if (routeInfo) { - auto name = routeInfo->GetName(); - navigationPattern->AddNavDestinationNode(name, navDestination, navRouteMode, routeInfo); - } else { - auto name = navDestinationPattern->GetName(); - navigationPattern->AddNavDestinationNode(name, navDestination, navRouteMode); - } -} - bool NavRouterGroupNode::CleanNodeInNavigation(const RefPtr& parent) { auto navigationNode = AceType::DynamicCast(parent); @@ -502,431 +273,4 @@ bool NavRouterGroupNode::CleanNodeInNavigation(const RefPtr& parent) } return false; } - -void NavRouterGroupNode::SetBackButtonVisible(const RefPtr& navDestination) -{ - auto navDestinationNode = AceType::DynamicCast(navDestination); - CHECK_NULL_VOID(navDestination); - auto titleBarNode = AceType::DynamicCast(navDestinationNode->GetTitleBarNode()); - CHECK_NULL_VOID(titleBarNode); - auto titleBarLayoutProperty = titleBarNode->GetLayoutProperty(); - CHECK_NULL_VOID(titleBarLayoutProperty); - auto backButtonNode = AceType::DynamicCast(titleBarNode->GetBackButton()); - CHECK_NULL_VOID(backButtonNode); - auto backButtonLayoutProperty = backButtonNode->GetLayoutProperty(); - CHECK_NULL_VOID(backButtonLayoutProperty); - backButtonLayoutProperty->UpdateVisibility(VisibleType::VISIBLE); - backButtonNode->MarkModifyDone(); -} - -void NavRouterGroupNode::NavTransitionInAnimation(const RefPtr& navigation, - const RefPtr& transitionOutNode, const RefPtr& navDestination) -{ - auto navigationNode = AceType::DynamicCast(navigation); - CHECK_NULL_VOID(navigationNode); - if (navigationNode->GetIsOnAnimation()) { - LOGI("navigation is on animation"); - return; - } - AnimationOption option; - option.SetCurve(interpolatingSpringCurve); - option.SetFillMode(FillMode::FORWARDS); - option.SetDuration(DEFAULT_ANIMATION_DURATION); - - auto transitionOutNodeContext = transitionOutNode->GetRenderContext(); - auto transitionInNodeContext = navDestination->GetRenderContext(); - CHECK_NULL_VOID(transitionOutNodeContext && transitionInNodeContext); - auto size = navigationNode->GetGeometryNode()->GetFrameSize(); - auto nodeWidth = size.Width(); - auto nodeHeight = size.Height(); - option.SetOnFinishEvent( - [transitionOutNodeContextWK = WeakClaim(RawPtr(transitionOutNodeContext)), - navigationNodeWK = WeakClaim(RawPtr(navigationNode)), navDestinationWK = WeakClaim(RawPtr(navDestination)), - id = Container::CurrentId(), nodeHeight] { - ContainerScope scope(id); - auto context = PipelineContext::GetCurrentContext(); - CHECK_NULL_VOID_NOLOG(context); - auto taskExecutor = context->GetTaskExecutor(); - CHECK_NULL_VOID_NOLOG(taskExecutor); - taskExecutor->PostTask( - [transitionOutNodeContextWK, navigationNodeWK, navDestinationWK, id, nodeHeight]() { - auto transitionOutNodeContext = transitionOutNodeContextWK.Upgrade(); - auto navigationNode = navigationNodeWK.Upgrade(); - auto navDestination = navDestinationWK.Upgrade(); - ContainerScope scope(id); - if (transitionOutNodeContext) { - transitionOutNodeContext->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); - } - if (navDestination) { - navDestination->GetRenderContext()->ClipWithRRect( - RectF(0.0f, 0.0f, Infinity(), nodeHeight), RadiusF(EdgeF(0.0f, 0.0f))); - } - navigationNode->SetIsOnAnimation(false); - }, - TaskExecutor::TaskType::UI); - }); - - transitionOutNodeContext->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); - transitionInNodeContext->ClipWithRRect( - RectF(nodeWidth * HALF, 0.0f, nodeWidth, nodeHeight), RadiusF(EdgeF(0.0f, 0.0f))); - transitionInNodeContext->OnTransformTranslateUpdate({ nodeWidth * HALF, 0.0f, 0.0f }); - AnimationUtils::Animate( - option, - [transitionOutNodeContext, transitionInNodeContext, nodeWidth, nodeHeight, navigationNode]() { - navigationNode->SetIsOnAnimation(true); - transitionOutNodeContext->OnTransformTranslateUpdate({ -nodeWidth * PARENT_PAGE_OFFSET, 0.0f, 0.0f }); - transitionInNodeContext->ClipWithRRect( - RectF(0.0f, 0.0f, nodeWidth, nodeHeight), RadiusF(EdgeF(0.0f, 0.0f))); - transitionInNodeContext->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); - }, - option.GetOnFinishEvent()); - MaskAnimation(transitionOutNodeContext); -} - -void NavRouterGroupNode::MaskAnimation(const RefPtr& transitionOutNodeContext) -{ - AnimationOption maskOption; - maskOption.SetCurve(Curves::FRICTION); - maskOption.SetDuration(MASK_DURATION); - maskOption.SetFillMode(FillMode::FORWARDS); - maskOption.SetOnFinishEvent( - [transitionOutNodeContextWK = WeakClaim(RawPtr(transitionOutNodeContext)), id = Container::CurrentId()] { - ContainerScope scope(id); - auto context = PipelineContext::GetCurrentContext(); - CHECK_NULL_VOID_NOLOG(context); - auto taskExecutor = context->GetTaskExecutor(); - CHECK_NULL_VOID_NOLOG(taskExecutor); - taskExecutor->PostTask( - [transitionOutNodeContextWK, id]() { - auto transitionOutNodeContext = transitionOutNodeContextWK.Upgrade(); - ContainerScope scope(id); - if (transitionOutNodeContext) { - transitionOutNodeContext->SetActualForegroundColor(DEFAULT_MASK_COLOR); - } - }, - TaskExecutor::TaskType::UI); - }); - transitionOutNodeContext->SetActualForegroundColor(DEFAULT_MASK_COLOR); - AnimationUtils::Animate( - maskOption, [transitionOutNodeContext]() { transitionOutNodeContext->SetActualForegroundColor(MASK_COLOR); }, - maskOption.GetOnFinishEvent()); -} - -void NavRouterGroupNode::TitleTransitionInAnimation(const RefPtr& navigationNode, - const RefPtr& titleBarNode, const RefPtr& destinationTitleBarNode) -{ - AnimationOption option; - option.SetCurve(interpolatingSpringCurve); - option.SetFillMode(FillMode::FORWARDS); - option.SetDuration(DEFAULT_ANIMATION_DURATION); - - auto transitionOutNodeContext = titleBarNode->GetRenderContext(); - auto transitionInNodeContext = destinationTitleBarNode->GetRenderContext(); - auto size = navigationNode->GetGeometryNode()->GetFrameSize(); - auto nodeWidth = size.Width(); - - option.SetOnFinishEvent( - [transitionOutNodeContextWK = WeakClaim(RawPtr(transitionOutNodeContext)), id = Container::CurrentId()] { - ContainerScope scope(id); - auto context = PipelineContext::GetCurrentContext(); - CHECK_NULL_VOID_NOLOG(context); - auto taskExecutor = context->GetTaskExecutor(); - CHECK_NULL_VOID_NOLOG(taskExecutor); - // animation finish event should be posted to UI thread. - taskExecutor->PostTask( - [transitionOutNodeContextWK, id]() { - auto transitionOutNodeContext = transitionOutNodeContextWK.Upgrade(); - CHECK_NULL_VOID(transitionOutNodeContext); - ContainerScope scope(id); - transitionOutNodeContext->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); - }, - TaskExecutor::TaskType::UI); - }); - if (transitionOutNodeContext) { - transitionOutNodeContext->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); - } - if (transitionInNodeContext) { - transitionInNodeContext->OnTransformTranslateUpdate({ nodeWidth * HALF, 0.0f, 0.0f }); - } - AnimationUtils::Animate( - option, - [transitionOutNodeContext, transitionInNodeContext, nodeWidth]() { - if (transitionOutNodeContext) { - transitionOutNodeContext->OnTransformTranslateUpdate({ nodeWidth * PARENT_TITLE_OFFSET, 0.0f, 0.0f }); - } - if (transitionInNodeContext) { - transitionInNodeContext->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); - } - }, - option.GetOnFinishEvent()); - - AnimationOption opacityOption; - opacityOption.SetCurve(Curves::SHARP); - opacityOption.SetDelay(OPACITY_TITLE_IN_DELAY); - opacityOption.SetDuration(OPACITY_TITLE_DURATION); - opacityOption.SetFillMode(FillMode::FORWARDS); - transitionInNodeContext->OpacityAnimation(opacityOption, 0.0f, 1.0f); -} - -void NavRouterGroupNode::NavTransitionOutAnimation(const RefPtr& navigation, - const RefPtr& navBarNode, const RefPtr& navDestination, - const RefPtr& navigationContentNode) -{ - auto navigationNode = AceType::DynamicCast(navigation); - CHECK_NULL_VOID(navigationNode); - if (navigationNode->GetIsOnAnimation()) { - LOGI("navigation is on animation"); - return; - } - AnimationOption option; - option.SetCurve(interpolatingSpringCurve); - option.SetFillMode(FillMode::FORWARDS); - option.SetDuration(DEFAULT_ANIMATION_DURATION); - auto navigationContext = navBarNode->GetRenderContext(); - CHECK_NULL_VOID(navigationContext); - auto navDestinationContext = navDestination->GetRenderContext(); - CHECK_NULL_VOID(navDestinationContext); - - auto node = AceType::DynamicCast(navigationNode); - auto size = node->GetGeometryNode()->GetFrameSize(); - auto nodeWidth = size.Width(); - auto nodeHeight = size.Height(); - - option.SetOnFinishEvent( - [navigationContentWK = WeakClaim(RawPtr(navigationContentNode)), - navigationNodeWK = WeakClaim(RawPtr(navigationNode)), id = Container::CurrentId(), nodeHeight] { - ContainerScope scope(id); - auto context = PipelineContext::GetCurrentContext(); - CHECK_NULL_VOID_NOLOG(context); - auto taskExecutor = context->GetTaskExecutor(); - CHECK_NULL_VOID_NOLOG(taskExecutor); - // animation finish event should be posted to UI thread. - taskExecutor->PostTask( - [navigationContentWK, navigationNodeWK, id, nodeHeight]() { - auto navigationContentNode = navigationContentWK.Upgrade(); - auto navigationNode = navigationNodeWK.Upgrade(); - CHECK_NULL_VOID(navigationNode && navigationContentNode); - navigationContentNode->GetRenderContext()->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); - navigationContentNode->GetRenderContext()->ClipWithRRect( - RectF(0.0f, 0.0f, Infinity(), nodeHeight), RadiusF(EdgeF(0.0f, 0.0f))); - ContainerScope scope(id); - navigationContentNode->MarkModifyDone(); - navigationNode->MarkModifyDone(); - navigationContentNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE); - navigationNode->SetIsOnAnimation(false); - }, - TaskExecutor::TaskType::UI); - }); - - navDestinationContext->ClipWithRRect(RectF(0.0f, 0.0f, nodeWidth, nodeHeight), RadiusF(EdgeF(0.0f, 0.0f))); - navDestinationContext->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); - navigationContext->OnTransformTranslateUpdate({ -nodeWidth * PARENT_PAGE_OFFSET, 0.0f, 0.0f }); - AnimationUtils::Animate( - option, - [navDestinationContext, navigationContext, nodeWidth, nodeHeight, navigationNode]() { - navigationNode->SetIsOnAnimation(true); - if (navDestinationContext) { - navDestinationContext->ClipWithRRect( - RectF(nodeWidth * HALF, 0.0f, nodeWidth, nodeHeight), RadiusF(EdgeF(0.0f, 0.0f))); - navDestinationContext->OnTransformTranslateUpdate({ nodeWidth * HALF, 0.0f, 0.0f }); - } - if (navigationContext) { - navigationContext->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); - } - }, - option.GetOnFinishEvent()); - - AnimationOption maskOption; - maskOption.SetCurve(Curves::FRICTION); - maskOption.SetDuration(MASK_DURATION); - maskOption.SetFillMode(FillMode::FORWARDS); - navigationContext->SetActualForegroundColor(MASK_COLOR); - AnimationUtils::Animate( - maskOption, [navigationContext]() { navigationContext->SetActualForegroundColor(DEFAULT_MASK_COLOR); }); -} - -void NavRouterGroupNode::NavTransitionBackToPreAnimation(const RefPtr& navigation, - const RefPtr& preDestination, const RefPtr& curNavDestination, - const RefPtr& navigationContentNode) -{ - auto navigationNode = AceType::DynamicCast(navigation); - CHECK_NULL_VOID(navigationNode); - if (navigationNode->GetIsOnAnimation()) { - LOGI("navigation is on animation"); - return; - } - AnimationOption option; - option.SetCurve(interpolatingSpringCurve); - option.SetFillMode(FillMode::FORWARDS); - option.SetDuration(DEFAULT_ANIMATION_DURATION); - auto preDestinationContext = preDestination->GetRenderContext(); - CHECK_NULL_VOID(preDestinationContext); - auto navDestinationContext = curNavDestination->GetRenderContext(); - CHECK_NULL_VOID(navDestinationContext); - - auto node = AceType::DynamicCast(navigationNode); - auto size = node->GetGeometryNode()->GetFrameSize(); - auto nodeWidth = size.Width(); - auto nodeHeight = size.Height(); - - option.SetOnFinishEvent([id = Container::CurrentId(), navigationNodeWK = WeakClaim(RawPtr(navigationNode)), - curNavDestinationWK = WeakClaim(RawPtr(curNavDestination)), - navigationContentNodeWK = WeakClaim(RawPtr(navigationContentNode)), nodeHeight] { - ContainerScope scope(id); - auto context = PipelineContext::GetCurrentContext(); - CHECK_NULL_VOID_NOLOG(context); - auto taskExecutor = context->GetTaskExecutor(); - CHECK_NULL_VOID_NOLOG(taskExecutor); - // animation finish event should be posted to UI thread. - taskExecutor->PostTask( - [curNavDestinationWK, navigationContentNodeWK, navigationNodeWK, id, nodeHeight]() { - auto curNavDestination = curNavDestinationWK.Upgrade(); - auto navigationContentNode = navigationContentNodeWK.Upgrade(); - auto navigationNode = navigationNodeWK.Upgrade(); - CHECK_NULL_VOID(navigationNode && curNavDestination && navigationContentNode); - curNavDestination->GetRenderContext()->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); - curNavDestination->GetRenderContext()->ClipWithRRect( - RectF(0.0f, 0.0f, Infinity(), nodeHeight), RadiusF(EdgeF(0.0f, 0.0f))); - ContainerScope scope(id); - navigationContentNode->MarkModifyDone(); - navigationNode->MarkModifyDone(); - navigationContentNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE); - navigationNode->SetIsOnAnimation(false); - }, - TaskExecutor::TaskType::UI); - }); - - navDestinationContext->ClipWithRRect(RectF(0.0f, 0.0f, nodeWidth, nodeHeight), RadiusF(EdgeF(0.0f, 0.0f))); - navDestinationContext->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); - preDestinationContext->OnTransformTranslateUpdate({ -nodeWidth * PARENT_PAGE_OFFSET, 0.0f, 0.0f }); - AnimationUtils::Animate( - option, - [navDestinationContext, preDestinationContext, nodeWidth, nodeHeight, navigationNode]() { - navigationNode->SetIsOnAnimation(true); - if (navDestinationContext) { - navDestinationContext->ClipWithRRect( - RectF(nodeWidth * HALF, 0.0f, nodeWidth, nodeHeight), RadiusF(EdgeF(0.0f, 0.0f))); - navDestinationContext->OnTransformTranslateUpdate({ nodeWidth * HALF, 0.0f, 0.0f }); - } - if (preDestinationContext) { - preDestinationContext->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); - } - }, - option.GetOnFinishEvent()); - - AnimationOption maskOption; - maskOption.SetCurve(Curves::FRICTION); - maskOption.SetDuration(MASK_DURATION); - maskOption.SetFillMode(FillMode::FORWARDS); - preDestinationContext->SetActualForegroundColor(MASK_COLOR); - AnimationUtils::Animate( - maskOption, [preDestinationContext]() { preDestinationContext->SetActualForegroundColor(DEFAULT_MASK_COLOR); }); -} - -void NavRouterGroupNode::TitleTransitionOutAnimation(const RefPtr& navigationNode, - const RefPtr& titleBarNode, const RefPtr& destinationTitleBarNode) -{ - AnimationOption option; - option.SetCurve(interpolatingSpringCurve); - option.SetFillMode(FillMode::FORWARDS); - option.SetDuration(DEFAULT_ANIMATION_DURATION); - - auto transitionOutNodeContext = destinationTitleBarNode->GetRenderContext(); - CHECK_NULL_VOID(transitionOutNodeContext); - auto transitionInNodeContext = titleBarNode->GetRenderContext(); - CHECK_NULL_VOID(transitionInNodeContext); - auto size = navigationNode->GetGeometryNode()->GetFrameSize(); - auto nodeWidth = size.Width(); - - option.SetOnFinishEvent( - [transitionOutNodeContextWK = WeakClaim(RawPtr(transitionOutNodeContext)), id = Container::CurrentId()] { - ContainerScope scope(id); - auto context = PipelineContext::GetCurrentContext(); - CHECK_NULL_VOID_NOLOG(context); - auto taskExecutor = context->GetTaskExecutor(); - CHECK_NULL_VOID_NOLOG(taskExecutor); - // animation finish event should be posted to UI thread. - taskExecutor->PostTask( - [transitionOutNodeContextWK, id]() { - auto transitionOutNodeContext = transitionOutNodeContextWK.Upgrade(); - CHECK_NULL_VOID(transitionOutNodeContext); - ContainerScope scope(id); - transitionOutNodeContext->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); - }, - TaskExecutor::TaskType::UI); - }); - - transitionOutNodeContext->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); - transitionInNodeContext->OnTransformTranslateUpdate({ nodeWidth * PARENT_TITLE_OFFSET, 0.0f, 0.0f }); - AnimationUtils::Animate( - option, - [transitionOutNodeContext, transitionInNodeContext, nodeWidth]() { - transitionOutNodeContext->OnTransformTranslateUpdate({ nodeWidth * HALF, 0.0f, 0.0f }); - transitionInNodeContext->OnTransformTranslateUpdate({ 0.0f, 0.0f, 0.0f }); - }, - option.GetOnFinishEvent()); - TitleOpacityAnimation(transitionOutNodeContext); -} - -void NavRouterGroupNode::TitleOpacityAnimation(const RefPtr& transitionOutNodeContext) -{ - AnimationOption opacityOption; - opacityOption.SetCurve(Curves::SHARP); - opacityOption.SetDelay(OPACITY_TITLE_OUT_DELAY); - opacityOption.SetDuration(OPACITY_TITLE_DURATION); - opacityOption.SetFillMode(FillMode::FORWARDS); - opacityOption.SetOnFinishEvent( - [transitionOutNodeContextWK = WeakClaim(RawPtr(transitionOutNodeContext)), id = Container::CurrentId()] { - ContainerScope scope(id); - auto context = PipelineContext::GetCurrentContext(); - CHECK_NULL_VOID_NOLOG(context); - auto taskExecutor = context->GetTaskExecutor(); - CHECK_NULL_VOID_NOLOG(taskExecutor); - // animation finish event should be posted to UI thread. - taskExecutor->PostTask( - [transitionOutNodeContextWK, id]() { - auto transitionOutNodeContext = transitionOutNodeContextWK.Upgrade(); - CHECK_NULL_VOID(transitionOutNodeContext); - ContainerScope scope(id); - transitionOutNodeContext->UpdateOpacity(1.0); - }, - TaskExecutor::TaskType::UI); - }); - transitionOutNodeContext->OpacityAnimation(opacityOption, 1.0, 0.0); -} - -void NavRouterGroupNode::BackButtonAnimation(const RefPtr& backButtonNode, bool isTransitionIn) -{ - AnimationOption transitionOption; - transitionOption.SetCurve(Curves::SHARP); - transitionOption.SetFillMode(FillMode::FORWARDS); - auto backButtonNodeContext = backButtonNode->GetRenderContext(); - CHECK_NULL_VOID(backButtonNodeContext); - if (isTransitionIn) { - transitionOption.SetDelay(OPACITY_BACKBUTTON_IN_DELAY); - transitionOption.SetDuration(OPACITY_BACKBUTTON_IN_DURATION); - backButtonNodeContext->OpacityAnimation(transitionOption, 0.0, 1.0); - } else { - transitionOption.SetDuration(OPACITY_BACKBUTTON_OUT_DURATION); - transitionOption.SetOnFinishEvent( - [backButtonNodeContextWK = WeakClaim(RawPtr(backButtonNodeContext)), id = Container::CurrentId()] { - ContainerScope scope(id); - auto context = PipelineContext::GetCurrentContext(); - CHECK_NULL_VOID_NOLOG(context); - auto taskExecutor = context->GetTaskExecutor(); - CHECK_NULL_VOID_NOLOG(taskExecutor); - // animation finish event should be posted to UI thread. - taskExecutor->PostTask( - [backButtonNodeContextWK, id]() { - auto backButtonNodeContext = backButtonNodeContextWK.Upgrade(); - CHECK_NULL_VOID(backButtonNodeContext); - ContainerScope scope(id); - backButtonNodeContext->UpdateOpacity(1.0); - }, - TaskExecutor::TaskType::UI); - }); - backButtonNodeContext->OpacityAnimation(transitionOption, 1.0, 0.0); - } -} - } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/navrouter/navrouter_group_node.h b/frameworks/core/components_ng/pattern/navrouter/navrouter_group_node.h index 68724a73675..9071c02941e 100644 --- a/frameworks/core/components_ng/pattern/navrouter/navrouter_group_node.h +++ b/frameworks/core/components_ng/pattern/navrouter/navrouter_group_node.h @@ -21,7 +21,6 @@ #include "core/components_ng/base/frame_node.h" #include "core/components_ng/base/group_node.h" #include "core/components_ng/pattern/navigation/navigation_declaration.h" -#include "core/components_ng/pattern/navrouter/navrouter_pattern.h" #include "core/components_ng/property/property.h" namespace OHOS::Ace::NG { @@ -60,30 +59,8 @@ public: private: void AddNavDestinationToNavigation(const RefPtr& parent); void SetDestinationChangeEvent(const RefPtr& parent); - void SetBackButtonEvent(const RefPtr& parent); - void SetOnStateChangeFalse(const RefPtr& preNavDestination, const RefPtr& navDestination, - const RefPtr& navigation, bool isBackButton = false); - void BackToNavBar(const RefPtr& parent); - void BackToPreNavDestination(const RefPtr& preNavDestination, const RefPtr& navigation, - const RefPtr& navRouterPattern); - void AddBackButtonIconToNavDestination(const RefPtr& parent); bool CleanNodeInNavigation(const RefPtr& parent); - void SetBackButtonVisible(const RefPtr& navDestination); - void GetOpsForNavRouteMode(NavRouteMode mode, bool& stackOp, bool& mapOp); - void NavTransitionInAnimation(const RefPtr& navigationNode, - const RefPtr& transitionOutNode, const RefPtr& navDestination); - void NavTransitionOutAnimation(const RefPtr& navigationNode, const RefPtr& navBarNode, - const RefPtr& navDestination, const RefPtr& navigationContentNode); - void NavTransitionBackToPreAnimation(const RefPtr& navigationNode, const RefPtr& preDestination, - const RefPtr& curNavDestination, const RefPtr& navigationContentNode); - void TitleTransitionInAnimation(const RefPtr& navigationNode, - const RefPtr& titleBarNode, const RefPtr& destinationTitleBarNode); - void TitleTransitionOutAnimation(const RefPtr& navigationNode, - const RefPtr& titleBarNode, const RefPtr& destinationTitleBarNode); - void BackButtonAnimation(const RefPtr& backButtonNode, bool isTransitionIn); - void MaskAnimation(const RefPtr& transitionOutNodeContext); - void TitleOpacityAnimation(const RefPtr& transitionOutNodeContext); RefPtr navDestinationNode_; }; -- Gitee