长按悬浮菜单Preview支持拖拽动效

Signed-off-by: limeng <limeng208@huawei.com>
This commit is contained in:
limeng 2023-10-18 16:56:20 +08:00
parent 34f2735f56
commit 3eddfe0bd0
14 changed files with 96 additions and 25 deletions

View File

@ -494,7 +494,7 @@ void SubwindowOhos::ShowMenuNG(const RefPtr<NG::FrameNode> menuNode, int32_t tar
overlay->ShowMenuInSubWindow(targetId, offset, menuNode);
}
void SubwindowOhos::HideMenuNG(bool showPreviewAnimation)
void SubwindowOhos::HideMenuNG(bool showPreviewAnimation, bool startDrag)
{
if (!isShowed_) {
return;
@ -508,7 +508,7 @@ void SubwindowOhos::HideMenuNG(bool showPreviewAnimation)
auto overlay = context->GetOverlayManager();
CHECK_NULL_VOID(overlay);
ContainerScope scope(childContainerId_);
overlay->HideMenuInSubWindow(showPreviewAnimation);
overlay->HideMenuInSubWindow(showPreviewAnimation, startDrag);
}
void SubwindowOhos::HideMenuNG(const RefPtr<NG::FrameNode>& menu, int32_t targetId)

View File

@ -60,7 +60,7 @@ public:
void ShowMenu(const RefPtr<Component>& newComponent) override;
void ShowMenuNG(const RefPtr<NG::FrameNode> menuNode, int32_t targetId, const NG::OffsetF& offset) override;
void HideMenuNG(const RefPtr<NG::FrameNode>& menu, int32_t targetId) override;
void HideMenuNG(bool showPreviewAnimation) override;
void HideMenuNG(bool showPreviewAnimation, bool startDrag) override;
void ShowPopup(const RefPtr<Component>& newComponent, bool disableTouchEvent = true) override;
void ShowPopupNG(int32_t targetId, const NG::PopupInfo& popupInfo) override;
void HidePopupNG(int32_t targetId) override;

View File

@ -40,7 +40,7 @@ public:
virtual void ShowMenu(const RefPtr<Component>& newComponent) = 0;
virtual void ShowMenuNG(const RefPtr<NG::FrameNode> menuNode, int32_t targetId, const NG::OffsetF& offset) = 0;
virtual void HideMenuNG(const RefPtr<NG::FrameNode>& menu, int32_t targetId) = 0;
virtual void HideMenuNG(bool showPreviewAnimation = true) = 0;
virtual void HideMenuNG(bool showPreviewAnimation = true, bool startDrag = false) = 0;
virtual void ShowPopup(const RefPtr<Component>& newComponent, bool disableTouchEvent = true) = 0;
virtual void ShowPopupNG(int32_t targetId, const NG::PopupInfo& popupInfo) = 0;
virtual void HidePopupNG(int32_t targetId) = 0;

View File

@ -204,11 +204,11 @@ void SubwindowManager::HideMenuNG(const RefPtr<NG::FrameNode>& menu, int32_t tar
}
}
void SubwindowManager::HideMenuNG(bool showPreviewAnimation)
void SubwindowManager::HideMenuNG(bool showPreviewAnimation, bool startDrag)
{
auto subwindow = GetCurrentWindow();
if (subwindow) {
subwindow->HideMenuNG(showPreviewAnimation);
subwindow->HideMenuNG(showPreviewAnimation, startDrag);
}
}

View File

@ -68,7 +68,7 @@ public:
void ShowMenuNG(const RefPtr<NG::FrameNode>& menuNode, int32_t targetId,
const NG::OffsetF& offset, bool isAboveApps = false);
void HideMenuNG(const RefPtr<NG::FrameNode>& menu, int32_t targetId);
void HideMenuNG(bool showPreviewAnimation = true);
void HideMenuNG(bool showPreviewAnimation = true, bool startDrag = false);
void ShowPopup(const RefPtr<Component>& newComponent, bool disableTouchEvent = true);
void ShowPopupNG(int32_t targetId, const NG::PopupInfo& popupInfo);
void HidePopupNG(int32_t targetId, int32_t instanceId = -1);

View File

@ -39,7 +39,7 @@ void SubwindowManager::ShowPopupNG(int32_t targetId, const NG::PopupInfo& popupI
void SubwindowManager::HideMenuNG(const RefPtr<NG::FrameNode>& menu, int32_t targetId) {}
void SubwindowManager::HideMenuNG(bool showPreviewAnimation) {}
void SubwindowManager::HideMenuNG(bool showPreviewAnimation, bool startDrag) {}
void SubwindowManager::SetHotAreas(const std::vector<Rect>& rects, int32_t overlayId, int32_t instanceId) {}

View File

@ -154,7 +154,7 @@ void DragEventActuator::OnCollectTouchTarget(const OffsetF& coordinateOffset, co
HideEventColumn();
HidePixelMap(true, info.GetGlobalLocation().GetX(), info.GetGlobalLocation().GetY());
HideFilter();
SubwindowManager::GetInstance()->HideMenuNG(false);
SubwindowManager::GetInstance()->HideMenuNG(false, true);
AnimationOption option;
option.SetDuration(PIXELMAP_ANIMATION_DURATION);
option.SetCurve(Curves::SHARP);
@ -175,6 +175,17 @@ void DragEventActuator::OnCollectTouchTarget(const OffsetF& coordinateOffset, co
frameNode->SetDraggable(true);
textDragCallback_(info.GetGlobalLocation());
}
} else if (!isNotInPreviewState_ && (gestureHub->GetPreviewMode() != MenuPreviewMode::NONE)) {
HideEventColumn();
HidePixelMap(true, info.GetGlobalLocation().GetX(), info.GetGlobalLocation().GetY());
HideFilter();
SubwindowManager::GetInstance()->HideMenuNG(false, true);
AnimationOption option;
option.SetDuration(PIXELMAP_ANIMATION_DURATION);
option.SetCurve(Curves::SHARP);
AnimationUtils::Animate(
option, [renderContext]() { renderContext->UpdateOpacity(SCALE_NUMBER); },
option.GetOnFinishEvent());
}
}
@ -318,6 +329,11 @@ void DragEventActuator::OnCollectTouchTarget(const OffsetF& coordinateOffset, co
auto actuator = weak.Upgrade();
CHECK_NULL_VOID(actuator);
actuator->SetIsNotInPreviewState(true);
auto gestureHub = actuator->gestureEventHub_.Upgrade();
CHECK_NULL_VOID(gestureHub);
if (gestureHub->GetPreviewMode() != MenuPreviewMode::NONE) {
actuator->SetIsNotInPreviewState(false);
}
auto pipeline = PipelineContext::GetCurrentContext();
CHECK_NULL_VOID(pipeline);
auto dragDropManager = pipeline->GetDragDropManager();

View File

@ -1209,6 +1209,12 @@ void MenuLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper)
}
auto menuPosition = MenuLayoutAvoidAlgorithm(menuProp, menuPattern, size, didNeedArrow);
SetMenuPlacementForAnimation(layoutWrapper);
arrowPosition_ = GetArrowPositionWithPlacement(size);
if (didNeedArrow && arrowPlacement_ != Placement::NONE) {
LayoutArrow(layoutWrapper);
}
LOGD("Menu layout, offset = %{public}s", menuPosition.ToString().c_str());
geometryNode->SetFrameOffset(menuPosition);
auto pipeline = PipelineBase::GetCurrentContext();
CHECK_NULL_VOID(pipeline);
auto menuTheme = pipeline->GetTheme<NG::MenuTheme>();
@ -1221,12 +1227,6 @@ void MenuLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper)
auto menuEndOffset =
menuPosition - (previewOffset_ - previewOriginOffset_) + FixMenuOriginOffset(1.0f, afterAnimationScale);
menuPattern->SetEndOffset(menuEndOffset);
arrowPosition_ = GetArrowPositionWithPlacement(size);
if (didNeedArrow && arrowPlacement_ != Placement::NONE) {
LayoutArrow(layoutWrapper);
}
LOGD("Menu layout, offset = %{public}s", menuPosition.ToString().c_str());
geometryNode->SetFrameOffset(menuPosition);
}
// translate each option by the height of previous options

View File

@ -68,6 +68,7 @@ public:
theme->previewBeforeAnimationScale_ = 0.95f;
theme->previewAfterAnimationScale_ = 1.1f;
theme->menuAnimationScale_ = 0.4f;
theme->menuDragAnimationScale_ = 0.95f;
theme->springMotionResponse_ = 0.416f;
theme->springMotionDampingFraction_ = 0.73f;
theme->contextMenuAppearDuration_ = 250;
@ -76,6 +77,7 @@ public:
theme->previewDisappearSpringMotionDampingFraction_ = 0.97f;
theme->filterRadius_ = Dimension(100.0f);
theme->previewBorderRadius_ = 16.0_vp;
theme->previewMenuScaleNumber_ = 0.95f;
}
};
@ -106,6 +108,11 @@ public:
return menuAnimationScale_;
}
float GetMenuDragAnimationScale() const
{
return menuDragAnimationScale_;
}
float GetSpringMotionResponse() const
{
return springMotionResponse_;
@ -136,6 +143,11 @@ public:
return previewDisappearSpringMotionDampingFraction_;
}
float GetPreviewMenuScaleNumber() const
{
return previewMenuScaleNumber_;
}
Dimension GetFilterRadius() const
{
return filterRadius_;
@ -155,12 +167,14 @@ private:
float previewBeforeAnimationScale_ = 1.0f;
float previewAfterAnimationScale_ = 1.0f;
float menuAnimationScale_ = 1.0f;
float menuDragAnimationScale_ = 1.0f;
float springMotionResponse_ = 0.0f;
float springMotionDampingFraction_ = 0.0f;
int32_t contextMenuAppearDuration_ = 0;
int32_t disappearDuration_ = 0;
float previewDisappearSpringMotionResponse_ = 0.0f;
float previewDisappearSpringMotionDampingFraction_ = 0.0f;
float previewMenuScaleNumber_ = 0.0f;
Dimension filterRadius_;
Dimension previewBorderRadius_;
};

View File

@ -51,7 +51,6 @@ namespace OHOS::Ace::NG {
namespace {
#ifdef ENABLE_DRAG_FRAMEWORK
constexpr float SCALE_NUMBER = 0.95f;
constexpr float PAN_MAX_VELOCITY = 2000.0f;
#endif
// create menuWrapper and menu node, update menu props
@ -71,9 +70,23 @@ std::pair<RefPtr<FrameNode>, RefPtr<FrameNode>> CreateMenu(int32_t targetId, con
// create previewNode
auto previewNode = FrameNode::CreateFrameNode(V2::MENU_PREVIEW_ETS_TAG,
ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<MenuPreviewPattern>());
CHECK_NULL_RETURN(previewNode, std::make_pair(wrapperNode, menuNode));
previewNode->AddChild(previewCustomNode);
previewNode->MountToParent(wrapperNode);
previewNode->MarkModifyDone();
#ifdef ENABLE_DRAG_FRAMEWORK
auto eventHub = previewNode->GetEventHub<EventHub>();
CHECK_NULL_RETURN(eventHub, std::make_pair(wrapperNode, menuNode));
auto gestureHub = eventHub->GetGestureEventHub();
CHECK_NULL_RETURN(gestureHub, std::make_pair(wrapperNode, menuNode));
gestureHub->SetPreviewMode(MenuPreviewMode::CUSTOM);
gestureHub->InitDragDropEvent();
auto dragStart = [](const RefPtr<OHOS::Ace::DragEvent>& event, const std::string& extraParams) -> DragDropInfo {
DragDropInfo info;
return info;
};
eventHub->SetOnDragStart(std::move(dragStart));
#endif
}
return { wrapperNode, menuNode };
@ -278,13 +291,25 @@ void SetPixelMap(const RefPtr<FrameNode>& target, const RefPtr<FrameNode>& menuN
gestureHub = hub->GetOrCreateGestureEventHub();
CHECK_NULL_VOID(gestureHub);
InitPanEvent(gestureHub, menuNode);
gestureHub->SetPreviewMode(MenuPreviewMode::IMAGE);
auto dragStart = [](const RefPtr<OHOS::Ace::DragEvent>& event, const std::string& extraParams) -> DragDropInfo {
DragDropInfo info;
return info;
};
gestureHub->InitDragDropEvent();
hub->SetOnDragStart(std::move(dragStart));
imageNode->SetDraggable(true);
auto imageContext = imageNode->GetRenderContext();
CHECK_NULL_VOID(imageContext);
imageContext->UpdatePosition(OffsetT<Dimension>(Dimension(offsetX), Dimension(offsetY)));
auto pipeline = PipelineBase::GetCurrentContext();
CHECK_NULL_VOID(pipeline);
auto menuTheme = pipeline->GetTheme<NG::MenuTheme>();
CHECK_NULL_VOID(menuTheme);
ClickEffectInfo clickEffectInfo;
clickEffectInfo.level = ClickEffectLevel::LIGHT;
clickEffectInfo.scaleNumber = SCALE_NUMBER;
clickEffectInfo.scaleNumber = menuTheme->GetPreviewMenuScaleNumber();
imageContext->UpdateClickEffectLevel(clickEffectInfo);
imageNode->MarkModifyDone();
imageNode->MountToParent(menuNode);

View File

@ -57,6 +57,17 @@ void MenuPreviewPattern::OnModifyDone()
auto gestureHub = hub->GetOrCreateGestureEventHub();
CHECK_NULL_VOID(gestureHub);
InitPanEvent(gestureHub);
auto pipeline = PipelineBase::GetCurrentContext();
CHECK_NULL_VOID(pipeline);
auto menuTheme = pipeline->GetTheme<NG::MenuTheme>();
CHECK_NULL_VOID(menuTheme);
auto previewContext = host->GetRenderContext();
CHECK_NULL_VOID(previewContext);
ClickEffectInfo clickEffectInfo;
clickEffectInfo.level = ClickEffectLevel::LIGHT;
clickEffectInfo.scaleNumber = menuTheme->GetPreviewMenuScaleNumber();
previewContext->UpdateClickEffectLevel(clickEffectInfo);
}
bool MenuPreviewPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config)

View File

@ -156,7 +156,8 @@ void ShowPreviewDisappearAnimation(const RefPtr<MenuWrapperPattern>& menuWrapper
});
}
void ShowContextMenuDisappearAnimation(AnimationOption& option, const RefPtr<MenuWrapperPattern>& menuWrapperPattern)
void ShowContextMenuDisappearAnimation(
AnimationOption& option, const RefPtr<MenuWrapperPattern>& menuWrapperPattern, bool startDrag = false)
{
CHECK_NULL_VOID(menuWrapperPattern);
auto menuChild = menuWrapperPattern->GetMenu();
@ -171,6 +172,10 @@ void ShowContextMenuDisappearAnimation(AnimationOption& option, const RefPtr<Men
CHECK_NULL_VOID(pipelineContext);
auto menuTheme = pipelineContext->GetTheme<MenuTheme>();
CHECK_NULL_VOID(menuTheme);
if (startDrag) {
menuRenderContext->UpdateTransformScale(
VectorF(menuTheme->GetMenuDragAnimationScale(), menuTheme->GetMenuDragAnimationScale()));
}
auto springMotionResponse = menuTheme->GetPreviewDisappearSpringMotionResponse();
auto springMotionDampingFraction = menuTheme->GetPreviewDisappearSpringMotionDampingFraction();
AnimationOption positionOption;
@ -440,7 +445,7 @@ void OverlayManager::SetShowMenuAnimation(const RefPtr<FrameNode>& menu, bool is
menuPattern->SetFirstShow();
}
void OverlayManager::PopMenuAnimation(const RefPtr<FrameNode>& menu, bool showPreviewAnimation)
void OverlayManager::PopMenuAnimation(const RefPtr<FrameNode>& menu, bool showPreviewAnimation, bool startDrag)
{
ResetLowerNodeFocusable(menu);
@ -493,7 +498,7 @@ void OverlayManager::PopMenuAnimation(const RefPtr<FrameNode>& menu, bool showPr
} else {
ShowPreviewDisappearAnimation(menuWrapperPattern);
}
ShowContextMenuDisappearAnimation(option, menuWrapperPattern);
ShowContextMenuDisappearAnimation(option, menuWrapperPattern, startDrag);
} else {
AnimationUtils::Animate(
option,
@ -948,7 +953,7 @@ void OverlayManager::HideMenuInSubWindow(const RefPtr<FrameNode>& menu, int32_t
PopMenuAnimation(menu);
}
void OverlayManager::HideMenuInSubWindow(bool showPreviewAnimation)
void OverlayManager::HideMenuInSubWindow(bool showPreviewAnimation, bool startDrag)
{
LOGI("OverlayManager::HideMenuInSubWindow from close");
if (menuMap_.empty()) {
@ -958,7 +963,7 @@ void OverlayManager::HideMenuInSubWindow(bool showPreviewAnimation)
auto rootNode = rootNodeWeak_.Upgrade();
for (const auto& child : rootNode->GetChildren()) {
auto node = DynamicCast<FrameNode>(child);
PopMenuAnimation(node, showPreviewAnimation);
PopMenuAnimation(node, showPreviewAnimation, startDrag);
}
}

View File

@ -102,7 +102,7 @@ public:
void ShowMenuInSubWindow(int32_t targetId, const NG::OffsetF& offset, RefPtr<FrameNode> menu = nullptr);
void HideMenuInSubWindow(const RefPtr<FrameNode>& menu, int32_t targetId);
RefPtr<FrameNode> GetMenuNode(int32_t targetId);
void HideMenuInSubWindow(bool showPreviewAnimation = true);
void HideMenuInSubWindow(bool showPreviewAnimation = true, bool startDrag = false);
void CleanMenuInSubWindow();
void CleanPreviewInSubWindow();
void CleanMenuInSubWindowWithAnimation();
@ -307,7 +307,7 @@ private:
void OnDialogCloseEvent(const RefPtr<FrameNode>& node);
void SetShowMenuAnimation(const RefPtr<FrameNode>& menu, bool isInSubWindow = false);
void PopMenuAnimation(const RefPtr<FrameNode>& menu, bool showPreviewAnimation = true);
void PopMenuAnimation(const RefPtr<FrameNode>& menu, bool showPreviewAnimation = true, bool startDrag = false);
void OpenDialogAnimation(const RefPtr<FrameNode>& node);
void CloseDialogAnimation(const RefPtr<FrameNode>& node);

View File

@ -31,7 +31,7 @@ public:
MOCK_METHOD1(ShowMenu, void(const RefPtr<Component>& newComponent));
MOCK_METHOD3(ShowMenuNG, void(const RefPtr<NG::FrameNode> menuNode, int32_t targetId, const NG::OffsetF& offset));
MOCK_METHOD2(HideMenuNG, void(const RefPtr<NG::FrameNode>& menu, int32_t targetId));
MOCK_METHOD1(HideMenuNG, void(bool showPreviewAnimation));
MOCK_METHOD2(HideMenuNG, void(bool showPreviewAnimation, bool startDrag));
MOCK_METHOD2(ShowPopup, void(const RefPtr<Component>& newComponent, bool disableTouchEvent));
MOCK_METHOD2(ShowPopupNG, void(int32_t targetId, const NG::PopupInfo& popupInfo));
MOCK_METHOD1(HidePopupNG, void(int32_t targetId));