diff --git a/frameworks/core/components_ng/pattern/bubble/bubble_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/bubble/bubble_layout_algorithm.cpp index 5b082397c22c712a832afd45f6ddc04192cddb74..4eb1a472ca1177261386696ade9ba5d9c4de1523 100644 --- a/frameworks/core/components_ng/pattern/bubble/bubble_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/bubble/bubble_layout_algorithm.cpp @@ -228,9 +228,9 @@ void calculateArrowPoint(Dimension height, Dimension width) ARROW_REPLACE_END_HORIZON_P5_OFFSET_Y = p1x; } -void ResetTipsMaxLines(const RefPtr& childWrapper, bool followCursor) +void ResetTipsMaxLines(const RefPtr& childWrapper, bool isTips) { - if (!followCursor) { + if (!isTips) { return; } auto children = childWrapper->GetAllChildrenWithBuild(); @@ -338,9 +338,9 @@ void BubbleLayoutAlgorithm::FitAvailableRect(LayoutWrapper* layoutWrapper, bool if (showInSubWindow) { CHECK_EQUAL_VOID(container->IsSceneBoardWindow(), true); marginTop_ = std::max(marginTop_, - static_cast(availableRect.Top() + (followCursor_ ? TIPS_MARGIN_SPACE.ConvertToPx() : .0f))); + static_cast(availableRect.Top() + (isTips_ ? TIPS_MARGIN_SPACE.ConvertToPx() : .0f))); marginBottom_ = std::max(marginBottom_, static_cast(wrapperSize_.Height() - - availableRect.Top() - availableRect.Height() + (followCursor_ ? TIPS_MARGIN_SPACE.ConvertToPx() : .0f))); + - availableRect.Top() - availableRect.Height() + (isTips_ ? TIPS_MARGIN_SPACE.ConvertToPx() : .0f))); } else { auto displayWindowRect = pipelineContext->GetDisplayWindowRectInfo(); auto wrapperOffset = layoutWrapper->GetParentGlobalOffsetWithSafeArea(); @@ -449,10 +449,13 @@ void BubbleLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper) auto childProp = child->GetLayoutProperty(); CHECK_NULL_VOID(childProp); childProp->UpdatePropertyChangeFlag(PROPERTY_UPDATE_MEASURE); - ResetTipsMaxLines(child, followCursor_); + ResetTipsMaxLines(child, isTips_); child->Measure(childLayoutConstraint); measureChildSizeAfter_ = child->GetGeometryNode()->GetFrameSize(); - MeasureTipsRegion(child, childLayoutConstraint); + if (isTips_) { + followCursor_ ? MeasureTipsRegion(child, childLayoutConstraint) + : MeasureTipsFollowTarget(child, childLayoutConstraint); + } if (!NearEqual(measureChildSizeBefore_, measureChildSizeAfter_)) { auto childShowWidth = child->GetGeometryNode()->GetFrameSize().Width() + BUBBLE_ARROW_HEIGHT.ConvertToPx() * 2; auto childShowHeight = @@ -812,8 +815,8 @@ void BubbleLayoutAlgorithm::InitProps(const RefPtr& layout UpdateDumpInfo(); marginStart_ = (isTips_ ? TIPS_MARGIN_SPACE : MARGIN_SPACE + DRAW_EDGES_SPACE).ConvertToPx(); marginEnd_ = (isTips_ ? TIPS_MARGIN_SPACE : MARGIN_SPACE + DRAW_EDGES_SPACE).ConvertToPx(); - marginTop_ = top_ + (followCursor_ ? TIPS_MARGIN_SPACE : DRAW_EDGES_SPACE).ConvertToPx(); - marginBottom_ = bottom_ + (followCursor_ ? TIPS_MARGIN_SPACE : DRAW_EDGES_SPACE).ConvertToPx(); + marginTop_ = top_ + (isTips_ ? TIPS_MARGIN_SPACE : DRAW_EDGES_SPACE).ConvertToPx(); + marginBottom_ = bottom_ + (isTips_ ? TIPS_MARGIN_SPACE : DRAW_EDGES_SPACE).ConvertToPx(); HandleKeyboard(layoutWrapper, showInSubWindow); showArrow_ = false; minHeight_ = popupTheme->GetMinHeight(); @@ -1273,6 +1276,26 @@ void BubbleLayoutAlgorithm::MeasureTipsRegion( placement_ = origin; } +void BubbleLayoutAlgorithm::MeasureTipsFollowTarget( + const RefPtr& childWrapper, const LayoutConstraintF& childConstraint) +{ + CHECK_NULL_VOID(childWrapper); + const double maxTipsWidth = MAX_TIP_WIDTH.ConvertToPx(); + float height = isHalfFoldHover_ ? wrapperRect_.Height() : (wrapperSize_.Height() - marginTop_ - marginBottom_); + float width = std::min(wrapperSize_.Width() - marginEnd_ - marginStart_, static_cast(maxTipsWidth)); + SizeF newSize(width, height); + LayoutConstraintF columnConstraint = childConstraint; + columnConstraint.maxSize = newSize; + auto childProp = childWrapper->GetLayoutProperty(); + if (childProp) { + childProp->UpdatePropertyChangeFlag(PROPERTY_UPDATE_MEASURE); + } + UpdateTextNodeMaxLines(childWrapper, columnConstraint); + childWrapper->Measure(columnConstraint); + CHECK_NULL_VOID(childWrapper->GetGeometryNode()); + measureChildSizeAfter_ = childWrapper->GetGeometryNode()->GetFrameSize(); +} + Placement BubbleLayoutAlgorithm::CalculateTipsDirections(SizeF& newSize) { Placement placement = Placement::NONE; diff --git a/frameworks/core/components_ng/pattern/bubble/bubble_layout_algorithm.h b/frameworks/core/components_ng/pattern/bubble/bubble_layout_algorithm.h index b6ed1a6e33aeadf68e730a8dd69f36b73dd273df..6953022b2135b5686f3e2c5af63fec1240ec6366 100644 --- a/frameworks/core/components_ng/pattern/bubble/bubble_layout_algorithm.h +++ b/frameworks/core/components_ng/pattern/bubble/bubble_layout_algorithm.h @@ -267,6 +267,7 @@ private: void UpdateTextNodeMaxLines(const RefPtr& childWrapper, const LayoutConstraintF& layoutConstraint); void MeasureTipsRegion(const RefPtr& childWrapper, const LayoutConstraintF& childContraint); + void MeasureTipsFollowTarget(const RefPtr& childWrapper, const LayoutConstraintF& childContraint); Placement CalculateTipsDirections(SizeF& newSize); OffsetF GetChildPosition( diff --git a/frameworks/core/components_ng/pattern/bubble/bubble_paint_method.cpp b/frameworks/core/components_ng/pattern/bubble/bubble_paint_method.cpp index ce21d22d344b220cbea57e546f9c85ce182b3a98..9dc122bba45c9ad630d50fd6e2e9bab1dd0af7f1 100644 --- a/frameworks/core/components_ng/pattern/bubble/bubble_paint_method.cpp +++ b/frameworks/core/components_ng/pattern/bubble/bubble_paint_method.cpp @@ -243,7 +243,7 @@ bool BubblePaintMethod::IsPaintDoubleBorder(PaintWrapper* paintWrapper) if (paintProperty->GetShowAtAnchorValue(TipsAnchorType::TARGET) == TipsAnchorType::CURSOR) { return popupTheme->GetTipsDoubleBorderEnable(); } - return enableArrow_ && showArrow_ && popupTheme->GetTipsDoubleBorderEnable(); + return popupTheme->GetTipsDoubleBorderEnable(); } return popupTheme->GetPopupDoubleBorderEnable() && childSize_.IsPositive(); } diff --git a/frameworks/core/components_ng/pattern/bubble/bubble_pattern.cpp b/frameworks/core/components_ng/pattern/bubble/bubble_pattern.cpp index 70c45b8a1a92a6d0641893f201c2a278de69b5f2..8d2ec8dc72bd09352e5a5c9e6485db3cb29b6ab1 100644 --- a/frameworks/core/components_ng/pattern/bubble/bubble_pattern.cpp +++ b/frameworks/core/components_ng/pattern/bubble/bubble_pattern.cpp @@ -123,7 +123,7 @@ void BubblePattern::OnAttachToFrameNode() popupNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE); auto pattern = weak.Upgrade(); if (pattern) { - pattern->PopTipsBubble(); + pattern->PopBubble(true); } }; eventHub->AddInnerOnAreaChangedCallback(host->GetId(), std::move(onAreaChangedFunc)); @@ -374,7 +374,7 @@ RefPtr BubblePattern::GetButtonRowNode() return buttonRowNode; } -void BubblePattern::PopBubble() +void BubblePattern::PopBubble(bool tips) { auto host = GetHost(); CHECK_NULL_VOID(host); @@ -383,40 +383,7 @@ void BubblePattern::PopBubble() auto overlayManager = pipelineNg->GetOverlayManager(); CHECK_NULL_VOID(overlayManager); auto popupInfo = overlayManager->GetPopupInfo(targetNodeId_); - if (!popupInfo.isCurrentOnShow) { - return; - } - popupInfo.markNeedUpdate = true; - CHECK_NULL_VOID(host); - auto layoutProp = host->GetLayoutProperty(); - CHECK_NULL_VOID(layoutProp); - auto showInSubWindow = layoutProp->GetShowInSubWindow().value_or(false); - auto isTips = layoutProp->GetIsTips().value_or(false); - if (showInSubWindow) { - if (isTips) { - SubwindowManager::GetInstance()->HideTipsNG(targetNodeId_, 0); - } else { - SubwindowManager::GetInstance()->HidePopupNG(targetNodeId_); - } - } else { - if (isTips) { - overlayManager->HideTips(targetNodeId_, popupInfo, 0); - } else { - overlayManager->HidePopup(targetNodeId_, popupInfo); - } - } -} - -void BubblePattern::PopTipsBubble() -{ - auto host = GetHost(); - CHECK_NULL_VOID(host); - auto pipelineNg = host->GetContextRefPtr(); - CHECK_NULL_VOID(pipelineNg); - auto overlayManager = pipelineNg->GetOverlayManager(); - CHECK_NULL_VOID(overlayManager); - auto popupInfo = overlayManager->GetPopupInfo(targetNodeId_); - if (!popupInfo.isCurrentOnShow || !popupInfo.isTips) { + if (!popupInfo.isCurrentOnShow || (tips && !popupInfo.isTips)) { return; } popupInfo.markNeedUpdate = true; diff --git a/frameworks/core/components_ng/pattern/bubble/bubble_pattern.h b/frameworks/core/components_ng/pattern/bubble/bubble_pattern.h index b0c67e5f8e09d1d6801cd3bbfb96026deaa6ce3d..4219b335360bb4ff941514d8de42fe0848f43104 100644 --- a/frameworks/core/components_ng/pattern/bubble/bubble_pattern.h +++ b/frameworks/core/components_ng/pattern/bubble/bubble_pattern.h @@ -416,8 +416,7 @@ private: void RegisterButtonOnTouch(); void ButtonOnHover(bool isHover, const RefPtr& buttonNode); void ButtonOnPress(const TouchEventInfo& info, const RefPtr& buttonNode); - void PopBubble(); - void PopTipsBubble(); + void PopBubble(bool tips = false); void Animation( RefPtr& renderContext, const Color& endColor, int32_t duration, const RefPtr& curve); diff --git a/test/unittest/core/pattern/bubble/bubble_tips_test_ng.cpp b/test/unittest/core/pattern/bubble/bubble_tips_test_ng.cpp index 27cc5d8d7a9c1264c496a486d4415a0572e64359..8a5f006a56c263cb1e2f01ed3bd3c89cf7e29f0a 100755 --- a/test/unittest/core/pattern/bubble/bubble_tips_test_ng.cpp +++ b/test/unittest/core/pattern/bubble/bubble_tips_test_ng.cpp @@ -368,6 +368,7 @@ HWTEST_F(BubbleTipsTestNg, TipsFitAvailableRect001, TestSize.Level1) * @tc.steps: step2. test FitAvailableRect. */ pipelineContext->UpdateDisplayAvailableRect(Rect(0.0f, 0.0f, 0.0f, 0.0f)); + layoutAlgorithm->isTips_ = true; layoutAlgorithm->followCursor_ = true; layoutAlgorithm->expandDisplay_ = true; layoutAlgorithm->FitAvailableRect(AceType::RawPtr(layoutWrapper), true); @@ -605,6 +606,37 @@ HWTEST_F(BubbleTipsTestNg, IsPaintDoubleBorderTest001, TestSize.Level1) EXPECT_EQ(paintMethod->IsPaintDoubleBorder(AceType::RawPtr(paintWrapper)), true); } +/** + * @tc.name: IsPaintDoubleBorderTest002 + * @tc.desc: Test IsPaintDoubleBorder function. + * @tc.type: FUNC + */ +HWTEST_F(BubbleTipsTestNg, IsPaintDoubleBorderTest002, TestSize.Level1) +{ + /** + * @tc.steps: step1. create bubble and get frameNode. + */ + const int32_t version = 20; + auto param = CreateTipsParamForCursor(); + param->SetAnchorType(TipsAnchorType::TARGET); + auto tipsNode = CreateTipsNode(param, TIPS_MSG_1); + BubbleView::UpdateCommonParam(tipsNode->GetId(), param); + auto pipeline = tipsNode->GetContext(); + pipeline->minPlatformVersion_ = version; + auto pattern = tipsNode->GetPattern(); + auto paintMethod = AceType::DynamicCast(pattern->CreateNodePaintMethod()); + tipsNode->geometryNode_ = AceType::MakeRefPtr(); + auto paintWrapper = AceType::MakeRefPtr( + tipsNode->GetRenderContext(), tipsNode->geometryNode_, tipsNode->paintProperty_); + /** + * @tc.steps: step2. test IsPaintDoubleBorder. + */ + popupTheme->tipsDoubleBorderEnable_ = false; + EXPECT_EQ(paintMethod->IsPaintDoubleBorder(AceType::RawPtr(paintWrapper)), false); + popupTheme->tipsDoubleBorderEnable_ = true; + EXPECT_EQ(paintMethod->IsPaintDoubleBorder(AceType::RawPtr(paintWrapper)), true); +} + /** * @tc.name: FitMouseOffset001 * @tc.desc: Test FitMouseOffset. @@ -724,4 +756,39 @@ HWTEST_F(BubbleTipsTestNg, FitMouseOffset003, TestSize.Level1) EXPECT_EQ(layoutAlgorithm->targetOffset_, targetPosition); AceType::DynamicCast(AceEngine::Get().GetContainer(containerId))->isSubContainer_ = false; } + +/** + * @tc.name: MeasureTipsFollowTarget001 + * @tc.desc: Test MeasureTipsFollowTarget. + * @tc.type: FUNC + */ +HWTEST_F(BubbleTipsTestNg, MeasureTipsFollowTarget001, TestSize.Level1) +{ + /** + * @tc.steps: step1. create bubble and get frameNode. + */ + auto param = CreateTipsParamForCursor(); + param->SetAnchorType(TipsAnchorType::TARGET); + auto tipsNode = CreateTipsNode(param, TIPS_MSG_1); + auto layoutAlgorithm = + AceType::DynamicCast(tipsNode->layoutAlgorithm_->GetLayoutAlgorithm()); + layoutAlgorithm->wrapperRect_ = { 0, 0, DEVICE_WIDTH, DEVICE_HEIGHT }; + layoutAlgorithm->wrapperSize_ = { DEVICE_WIDTH, DEVICE_HEIGHT }; + layoutAlgorithm->measureChildSizeAfter_ = ConstructParagraphs(TIPS_MSG_1, 1); + + auto tipsLayoutWrapper = tipsNode->CreateLayoutWrapper(); + auto childWrapper = tipsLayoutWrapper->GetAllChildrenWithBuild().front(); + auto children = childWrapper->GetAllChildrenWithBuild(); + auto text = children.front(); + auto layoutProps = AceType::DynamicCast(text->GetLayoutProperty()); + ASSERT_NE(layoutProps, nullptr); + layoutProps->ResetMaxLines(); + + /** + * @tc.steps: step2. expect text node set maxlines. + */ + LayoutConstraintF childConstraint; + layoutAlgorithm->MeasureTipsFollowTarget(childWrapper, childConstraint); + EXPECT_TRUE(layoutProps->HasMaxLines()); +} } // namespace OHOS::Ace::NG diff --git a/test/unittest/core/pattern/overlay/overlay_manager_testthree_ng.cpp b/test/unittest/core/pattern/overlay/overlay_manager_testthree_ng.cpp index cf5d8cb2941a03332d9c60f6f7bdb142e20a8bd5..38522f066d4e0f59505aa569959db2664fdc221e 100644 --- a/test/unittest/core/pattern/overlay/overlay_manager_testthree_ng.cpp +++ b/test/unittest/core/pattern/overlay/overlay_manager_testthree_ng.cpp @@ -296,7 +296,7 @@ HWTEST_F(OverlayManagerTestThreeNg, GetTipsStatus001, TestSize.Level1) /** * @tc.name: PopTipsBubble1 - * @tc.desc: Test PopTipsBubble1 function. + * @tc.desc: Test PopBubble function. * @tc.type: FUNC */ HWTEST_F(OverlayManagerTestThreeNg, PopTipsBubble1, TestSize.Level1) @@ -318,7 +318,7 @@ HWTEST_F(OverlayManagerTestThreeNg, PopTipsBubble1, TestSize.Level1) auto overlayNode = FrameNode::CreateFrameNode(V2::ROOT_ETS_TAG, 1, AceType::MakeRefPtr()); ASSERT_NE(overlayNode, nullptr); auto overlayManager = AceType::MakeRefPtr(overlayNode); - bubblePattern->PopTipsBubble(); + bubblePattern->PopBubble(true); EXPECT_EQ(overlayManager->GetTipsStatus(1), false); } } // namespace OHOS::Ace::NG