diff --git a/frameworks/bridge/declarative_frontend/engine/jsEnumStyle.js b/frameworks/bridge/declarative_frontend/engine/jsEnumStyle.js index 8199e2b2883b78ec3b89dd0cc914a0ece8c26d56..ab6d17b60a5fde33c10c1d64cdebc736c3905e71 100644 --- a/frameworks/bridge/declarative_frontend/engine/jsEnumStyle.js +++ b/frameworks/bridge/declarative_frontend/engine/jsEnumStyle.js @@ -2487,6 +2487,12 @@ class WaterFlowSections { } } +var WaterFlowLayoutMode; +(function (WaterFlowLayoutMode) { + WaterFlowLayoutMode[WaterFlowLayoutMode["ALWAYS_TOP_DOWN"] = 0] = "ALWAYS_TOP_DOWN"; + WaterFlowLayoutMode[WaterFlowLayoutMode["SLIDING_WINDOW"] = 1] = "SLIDING_WINDOW"; +})(WaterFlowLayoutMode || (WaterFlowLayoutMode = {})); + class ChildrenMainSizeParamError extends Error { constructor(message, code) { super(message); diff --git a/frameworks/bridge/declarative_frontend/jsview/js_water_flow.cpp b/frameworks/bridge/declarative_frontend/jsview/js_water_flow.cpp index 5504dcb4429a34f8bf8e988a32d7964c586a3cc7..e570a2026c0750916c59df032291b9ad3652f57e 100644 --- a/frameworks/bridge/declarative_frontend/jsview/js_water_flow.cpp +++ b/frameworks/bridge/declarative_frontend/jsview/js_water_flow.cpp @@ -100,6 +100,26 @@ void ParseSections( } waterFlowSections->ChangeData(0, waterFlowSections->GetSectionInfo().size(), newSections); } + +void ParseScroller(const JSRef& obj) +{ + auto scroller = obj->GetProperty("scroller"); + if (scroller->IsObject()) { + auto* jsScroller = JSRef::Cast(scroller)->Unwrap(); + CHECK_NULL_VOID(jsScroller); + jsScroller->SetInstanceId(Container::CurrentId()); + auto positionController = WaterFlowModel::GetInstance()->CreateScrollController(); + jsScroller->SetController(positionController); + + // Init scroll bar proxy. + auto proxy = jsScroller->GetScrollBarProxy(); + if (!proxy) { + proxy = WaterFlowModel::GetInstance()->CreateScrollBarProxy(); + jsScroller->SetScrollBarProxy(proxy); + } + WaterFlowModel::GetInstance()->SetScroller(positionController, proxy); + } +} } // namespace void UpdateWaterFlowSections(const JSCallbackInfo& args, const JSRef& sections) @@ -147,22 +167,20 @@ void JSWaterFlow::Create(const JSCallbackInfo& args) } JSRef obj = JSRef::Cast(args[0]); - auto scroller = obj->GetProperty("scroller"); - if (scroller->IsObject()) { - auto* jsScroller = JSRef::Cast(scroller)->Unwrap(); - CHECK_NULL_VOID(jsScroller); - jsScroller->SetInstanceId(Container::CurrentId()); - auto positionController = WaterFlowModel::GetInstance()->CreateScrollController(); - jsScroller->SetController(positionController); - - // Init scroll bar proxy. - auto proxy = jsScroller->GetScrollBarProxy(); - if (!proxy) { - proxy = WaterFlowModel::GetInstance()->CreateScrollBarProxy(); - jsScroller->SetScrollBarProxy(proxy); + // set layout mode first. SetFooter is dependent to it + using LayoutMode = NG::WaterFlowLayoutMode; + auto mode = LayoutMode::TOP_DOWN; + auto jsMode = obj->GetProperty("layoutMode"); + if (jsMode->IsNumber()) { + mode = static_cast(jsMode->ToNumber()); + if (mode < LayoutMode::TOP_DOWN || mode > LayoutMode::SLIDING_WINDOW) { + mode = LayoutMode::TOP_DOWN; } - WaterFlowModel::GetInstance()->SetScroller(positionController, proxy); } + WaterFlowModel::GetInstance()->SetLayoutMode(mode); + + ParseScroller(obj); + auto sections = obj->GetProperty("sections"); auto footerObject = obj->GetProperty("footer"); if (sections->IsObject()) { diff --git a/frameworks/bridge/declarative_frontend/jsview/models/water_flow_model_impl.h b/frameworks/bridge/declarative_frontend/jsview/models/water_flow_model_impl.h index 1779c2d7e152f59c2d0667a3d8010d2ba5e7dedc..5e780519c3749b18adac8c5e2e2c4fd320458632 100644 --- a/frameworks/bridge/declarative_frontend/jsview/models/water_flow_model_impl.h +++ b/frameworks/bridge/declarative_frontend/jsview/models/water_flow_model_impl.h @@ -26,6 +26,7 @@ public: RefPtr CreateScrollController() override; RefPtr CreateScrollBarProxy() override; void SetScroller(RefPtr scroller, RefPtr proxy) override; + void SetLayoutMode(NG::WaterFlowLayoutMode mode) override {} void SetColumnsTemplate(const std::string& value) override; void SetRowsTemplate(const std::string& value) override; diff --git a/frameworks/core/components_ng/pattern/BUILD.gn b/frameworks/core/components_ng/pattern/BUILD.gn index f4de11ea2de8ca2452e46336b836000497dc8336..e6e98582d0a327dba4a9f2fb403c62bdf284b9ee 100644 --- a/frameworks/core/components_ng/pattern/BUILD.gn +++ b/frameworks/core/components_ng/pattern/BUILD.gn @@ -524,6 +524,8 @@ build_component_ng("pattern_ng") { "video/video_node.cpp", "video/video_pattern.cpp", "view_context/view_context_model_ng.cpp", + "waterflow/layout/sliding_window/water_flow_layout_info_sw.cpp", + "waterflow/layout/sliding_window/water_flow_layout_sw.cpp", "waterflow/water_flow_accessibility_property.cpp", "waterflow/water_flow_content_modifier.cpp", "waterflow/water_flow_item_model_ng.cpp", diff --git a/frameworks/core/components_ng/pattern/waterflow/layout/sliding_window/water_flow_layout_info_sw.cpp b/frameworks/core/components_ng/pattern/waterflow/layout/sliding_window/water_flow_layout_info_sw.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8259313ca46fb3fc8c252fcf8bf5b081f7eebb7c --- /dev/null +++ b/frameworks/core/components_ng/pattern/waterflow/layout/sliding_window/water_flow_layout_info_sw.cpp @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/waterflow/layout/sliding_window/water_flow_layout_info_sw.h b/frameworks/core/components_ng/pattern/waterflow/layout/sliding_window/water_flow_layout_info_sw.h new file mode 100644 index 0000000000000000000000000000000000000000..5f57dd12fb7fc6b4d4363f73fe3103f26c6262a5 --- /dev/null +++ b/frameworks/core/components_ng/pattern/waterflow/layout/sliding_window/water_flow_layout_info_sw.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_WATERFLOW_WATER_FLOW_LAYOUT_INFO_SW_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_WATERFLOW_WATER_FLOW_LAYOUT_INFO_SW_H +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_WATERFLOW_WATER_FLOW_LAYOUT_INFO_SW_H diff --git a/frameworks/core/components_ng/pattern/waterflow/layout/sliding_window/water_flow_layout_sw.cpp b/frameworks/core/components_ng/pattern/waterflow/layout/sliding_window/water_flow_layout_sw.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8259313ca46fb3fc8c252fcf8bf5b081f7eebb7c --- /dev/null +++ b/frameworks/core/components_ng/pattern/waterflow/layout/sliding_window/water_flow_layout_sw.cpp @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/waterflow/layout/sliding_window/water_flow_layout_sw.h b/frameworks/core/components_ng/pattern/waterflow/layout/sliding_window/water_flow_layout_sw.h new file mode 100644 index 0000000000000000000000000000000000000000..194b4a75d4d732df314750184df25697becc1818 --- /dev/null +++ b/frameworks/core/components_ng/pattern/waterflow/layout/sliding_window/water_flow_layout_sw.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_WATERFLOW_WATER_FLOW_SW_LAYOUT_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_WATERFLOW_WATER_FLOW_SW_LAYOUT_H + +#include "core/components_ng/pattern/waterflow/water_flow_layout_info_base.h" +#include "core/components_ng/pattern/waterflow/water_flow_layout_algorithm_base.h" + +namespace OHOS::Ace::NG { + +class ACE_EXPORT WaterFlowLayoutSW : public WaterFlowLayoutBase { + DECLARE_ACE_TYPE(WaterFlowLayoutSW, WaterFlowLayoutBase); + +public: + explicit WaterFlowLayoutSW(const RefPtr& info) : info_(info) {} + void SetCanOverScroll(bool canOverScroll) override {} + RefPtr info_; +}; +} // namespace OHOS::Ace::NG +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_WATERFLOW_WATER_FLOW_SW_LAYOUT_H diff --git a/frameworks/core/components_ng/pattern/waterflow/water_flow_item_node.cpp b/frameworks/core/components_ng/pattern/waterflow/water_flow_item_node.cpp index 4f774b02f419a838a908eb791a6653d8de3ae8c8..5b1167003d71cb7a135b1b5e7ec56e0d4a3d72e6 100644 --- a/frameworks/core/components_ng/pattern/waterflow/water_flow_item_node.cpp +++ b/frameworks/core/components_ng/pattern/waterflow/water_flow_item_node.cpp @@ -40,8 +40,9 @@ bool WaterFlowItemNode::RequestParentDirty() parent->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST); auto pattern = parent->GetPattern(); CHECK_NULL_RETURN(pattern, true); - // record index of dirty child, but only when using new Sectioned layout - if (pattern->GetSections() || SystemProperties::WaterFlowUseSegmentedLayout()) { + // record index of dirty child, but only when using new layout + if (pattern->GetLayoutMode() == WaterFlowLayoutMode::SLIDING_WINDOW || pattern->GetSections() || + SystemProperties::WaterFlowUseSegmentedLayout()) { auto idx = parent->GetChildTrueIndex(Claim(this)); if (idx > -1) { parent->ChildrenUpdatedFrom(idx); diff --git a/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_algorithm.cpp index 6d722979ec04ae7f6f4c4ed39ce79f79a7094b97..03955a9da46fe2372667f839c00afd7f3fbbdb82 100644 --- a/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_algorithm.cpp @@ -76,15 +76,15 @@ void WaterFlowLayoutAlgorithm::InitialItemsCrossSize( } // cross count changed by auto-fill and cross size change - if (!layoutInfo_.items_[0].empty() && crossLens.size() != layoutInfo_.items_[0].size()) { - layoutInfo_.Reset(); + if (!layoutInfo_->items_[0].empty() && crossLens.size() != layoutInfo_->items_[0].size()) { + layoutInfo_->Reset(); } int32_t index = 0; for (const auto& len : crossLens) { itemsCrossSize_.try_emplace(index, len); itemsCrossPosition_.try_emplace(index, ComputeCrossPosition(index)); - layoutInfo_.items_[0].try_emplace(index, std::map>()); + layoutInfo_->items_[0].try_emplace(index, std::map>()); ++index; } } @@ -110,59 +110,59 @@ void WaterFlowLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper) int32_t updateIdx = layoutWrapper->GetHostNode()->GetChildrenUpdated(); if (updateIdx != -1) { - layoutInfo_.Reset(updateIdx); + layoutInfo_->Reset(updateIdx); layoutWrapper->GetHostNode()->ChildrenUpdatedFrom(-1); } - layoutInfo_.childrenCount_ = layoutWrapper->GetTotalChildCount(); + layoutInfo_->childrenCount_ = layoutWrapper->GetTotalChildCount(); - InitialItemsCrossSize(layoutProperty, idealSize, layoutInfo_.childrenCount_); + InitialItemsCrossSize(layoutProperty, idealSize, layoutInfo_->childrenCount_); mainSize_ = GetMainAxisSize(idealSize, axis); - if (layoutInfo_.jumpIndex_ >= 0 && layoutInfo_.jumpIndex_ < layoutInfo_.childrenCount_) { - auto crossIndex = layoutInfo_.GetCrossIndex(layoutInfo_.jumpIndex_); + if (layoutInfo_->jumpIndex_ >= 0 && layoutInfo_->jumpIndex_ < layoutInfo_->childrenCount_) { + auto crossIndex = layoutInfo_->GetCrossIndex(layoutInfo_->jumpIndex_); if (crossIndex == -1) { // jump to out of cache } else { - layoutInfo_.JumpTo(layoutInfo_.items_[0][crossIndex][layoutInfo_.jumpIndex_]); + layoutInfo_->JumpTo(layoutInfo_->items_[0][crossIndex][layoutInfo_->jumpIndex_]); } } else { - layoutInfo_.jumpIndex_ = EMPTY_JUMP_INDEX; + layoutInfo_->jumpIndex_ = EMPTY_JUMP_INDEX; } FillViewport(mainSize_, layoutWrapper); - if (layoutInfo_.targetIndex_.has_value()) { + if (layoutInfo_->targetIndex_.has_value()) { MeasureForAnimation(layoutWrapper); } - if (layoutInfo_.jumpIndex_ != EMPTY_JUMP_INDEX) { - layoutInfo_.JumpTo({ footerMainStartPos_, footerMainSize_ }); + if (layoutInfo_->jumpIndex_ != EMPTY_JUMP_INDEX) { + layoutInfo_->JumpTo({ footerMainStartPos_, footerMainSize_ }); } if (matchChildren) { - mainSize_ = layoutInfo_.GetMaxMainHeight() + footerMainSize_; + mainSize_ = layoutInfo_->GetMaxMainHeight() + footerMainSize_; idealSize.SetMainSize(mainSize_, axis_); AddPaddingToSize(layoutProperty->CreatePaddingAndBorder(), idealSize); layoutWrapper->GetGeometryNode()->SetFrameSize(idealSize); } - layoutInfo_.lastMainSize_ = mainSize_; + layoutInfo_->lastMainSize_ = mainSize_; layoutWrapper->SetCacheCount(layoutProperty->GetCachedCountValue(1)); } void WaterFlowLayoutAlgorithm::MeasureForAnimation(LayoutWrapper* layoutWrapper) { - if (layoutInfo_.targetIndex_.value() > layoutInfo_.childrenCount_) { - layoutInfo_.targetIndex_.reset(); + if (layoutInfo_->targetIndex_.value() > layoutInfo_->childrenCount_) { + layoutInfo_->targetIndex_.reset(); return; } auto layoutProperty = AceType::DynamicCast(layoutWrapper->GetLayoutProperty()); - auto currentIndex = layoutInfo_.endIndex_; + auto currentIndex = layoutInfo_->endIndex_; auto position = GetItemPosition(currentIndex); - if (layoutInfo_.targetIndex_.value() == LAST_ITEM) { - layoutInfo_.targetIndex_ = layoutInfo_.childrenCount_ - 1; + if (layoutInfo_->targetIndex_.value() == LAST_ITEM) { + layoutInfo_->targetIndex_ = layoutInfo_->childrenCount_ - 1; } - while (layoutInfo_.targetIndex_.has_value() && (layoutInfo_.endIndex_ < layoutInfo_.targetIndex_.value())) { + while (layoutInfo_->targetIndex_.has_value() && (layoutInfo_->endIndex_ < layoutInfo_->targetIndex_.value())) { auto itemWrapper = layoutWrapper->GetOrCreateChildByIndex(GetChildIndexWithFooter(currentIndex)); if (!itemWrapper) { - layoutInfo_.targetIndex_.reset(); + layoutInfo_->targetIndex_.reset(); break; } auto itemCrossPosition = itemsCrossPosition_.find(position.crossIndex); @@ -173,19 +173,19 @@ void WaterFlowLayoutAlgorithm::MeasureForAnimation(LayoutWrapper* layoutWrapper) { itemCrossPosition->second, mainSize_, axis_ }, layoutProperty, itemWrapper)); auto itemSize = itemWrapper->GetGeometryNode()->GetMarginFrameSize(); auto itemHeight = GetMainAxisSize(itemSize, axis_); - auto item = layoutInfo_.items_[0][position.crossIndex].find(currentIndex); - if (item == layoutInfo_.items_[0][position.crossIndex].end()) { - layoutInfo_.items_[0][position.crossIndex][currentIndex] = + auto item = layoutInfo_->items_[0][position.crossIndex].find(currentIndex); + if (item == layoutInfo_->items_[0][position.crossIndex].end()) { + layoutInfo_->items_[0][position.crossIndex][currentIndex] = std::make_pair(position.startMainPos, itemHeight); } else { if (item->second.second != itemHeight) { item->second.second = itemHeight; - layoutInfo_.ClearCacheAfterIndex(currentIndex); + layoutInfo_->ClearCacheAfterIndex(currentIndex); TAG_LOGD(AceLogTag::ACE_WATERFLOW, "item size changed"); } } - if (layoutInfo_.targetIndex_.value() == currentIndex) { - layoutInfo_.targetIndex_.reset(); + if (layoutInfo_->targetIndex_.value() == currentIndex) { + layoutInfo_->targetIndex_.reset(); } currentIndex++; position = GetItemPosition(currentIndex); @@ -205,14 +205,14 @@ void WaterFlowLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper) MinusPaddingToSize(padding, size); auto childFrameOffset = OffsetF(padding.left.value_or(0.0f), padding.top.value_or(0.0f)); auto layoutProperty = AceType::DynamicCast(layoutWrapper->GetLayoutProperty()); - layoutInfo_.UpdateStartIndex(); - auto firstIndex = layoutInfo_.endIndex_; + layoutInfo_->UpdateStartIndex(); + auto firstIndex = layoutInfo_->endIndex_; auto crossSize = size.CrossSize(axis_); auto layoutDirection = layoutWrapper->GetLayoutProperty()->GetNonAutoLayoutDirection(); auto isRtl = (layoutDirection == TextDirection::RTL) && (axis_ == Axis::VERTICAL); - for (const auto& mainPositions : layoutInfo_.items_[0]) { + for (const auto& mainPositions : layoutInfo_->items_[0]) { for (const auto& item : mainPositions.second) { - if (item.first < layoutInfo_.startIndex_ || item.first > layoutInfo_.endIndex_) { + if (item.first < layoutInfo_->startIndex_ || item.first > layoutInfo_->endIndex_) { continue; } auto itemCrossPosition = itemsCrossPosition_.find(mainPositions.first); @@ -221,7 +221,7 @@ void WaterFlowLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper) } auto currentOffset = childFrameOffset; auto crossOffset = itemCrossPosition->second; - auto mainOffset = item.second.first + layoutInfo_.currentOffset_; + auto mainOffset = item.second.first + layoutInfo_->currentOffset_; if (isRtl) { crossOffset = crossSize - crossOffset - itemsCrossSize_.at(mainPositions.first); } @@ -240,8 +240,8 @@ void WaterFlowLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper) wrapper->GetGeometryNode()->SetMarginFrameOffset(currentOffset); wrapper->Layout(); // recode restore info - if (item.first == layoutInfo_.startIndex_) { - layoutInfo_.storedOffset_ = mainOffset; + if (item.first == layoutInfo_->startIndex_) { + layoutInfo_->storedOffset_ = mainOffset; } if (NonNegative(mainOffset + item.second.second)) { @@ -253,16 +253,16 @@ void WaterFlowLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper) } } } - layoutInfo_.firstIndex_ = firstIndex; + layoutInfo_->firstIndex_ = firstIndex; LayoutFooter(layoutWrapper, childFrameOffset, layoutProperty->IsReverse()); } void WaterFlowLayoutAlgorithm::LayoutFooter(LayoutWrapper* layoutWrapper, const OffsetF& childFrameOffset, bool reverse) { - if (layoutInfo_.itemEnd_ && layoutInfo_.footerIndex_ >= 0) { - auto footer = layoutWrapper->GetOrCreateChildByIndex(layoutInfo_.footerIndex_); + if (layoutInfo_->itemEnd_ && layoutInfo_->footerIndex_ >= 0) { + auto footer = layoutWrapper->GetOrCreateChildByIndex(layoutInfo_->footerIndex_); auto footerOffset = childFrameOffset; - auto mainOffset = layoutInfo_.GetMaxMainHeight() + layoutInfo_.currentOffset_; + auto mainOffset = layoutInfo_->GetMaxMainHeight() + layoutInfo_->currentOffset_; if (reverse) { mainOffset = mainSize_ - footerMainSize_ - mainOffset; } @@ -274,35 +274,37 @@ void WaterFlowLayoutAlgorithm::LayoutFooter(LayoutWrapper* layoutWrapper, const FlowItemPosition WaterFlowLayoutAlgorithm::GetItemPosition(int32_t index) { - auto crossIndex = layoutInfo_.GetCrossIndex(index); + auto crossIndex = layoutInfo_->GetCrossIndex(index); // already in layoutInfo if (crossIndex != -1) { - return { crossIndex, layoutInfo_.GetStartMainPos(crossIndex, index) }; + return { crossIndex, layoutInfo_->GetStartMainPos(crossIndex, index) }; } - auto itemIndex = layoutInfo_.GetCrossIndexForNextItem(layoutInfo_.GetSegment(index)); + auto itemIndex = layoutInfo_->GetCrossIndexForNextItem(layoutInfo_->GetSegment(index)); if (itemIndex.lastItemIndex < 0) { return { itemIndex.crossIndex, 0.0f }; } - auto mainHeight = layoutInfo_.GetMainHeight(itemIndex.crossIndex, itemIndex.lastItemIndex); + auto mainHeight = layoutInfo_->GetMainHeight(itemIndex.crossIndex, itemIndex.lastItemIndex); return { itemIndex.crossIndex, mainHeight + mainGap_ }; } void WaterFlowLayoutAlgorithm::FillViewport(float mainSize, LayoutWrapper* layoutWrapper) { - if (layoutInfo_.currentOffset_ >= 0) { + if (layoutInfo_->currentOffset_ >= 0) { if (!canOverScroll_) { - layoutInfo_.currentOffset_ = 0; + layoutInfo_->currentOffset_ = 0; } - layoutInfo_.itemStart_ = true; + layoutInfo_->itemStart_ = true; } else { - layoutInfo_.itemStart_ = false; + layoutInfo_->itemStart_ = false; } - layoutInfo_.UpdateStartIndex(); + + layoutInfo_->UpdateStartIndex(); auto layoutProperty = AceType::DynamicCast(layoutWrapper->GetLayoutProperty()); - auto currentIndex = layoutInfo_.startIndex_; + auto currentIndex = layoutInfo_->startIndex_; auto position = GetItemPosition(currentIndex); bool fill = false; - while (LessNotEqual(position.startMainPos + layoutInfo_.currentOffset_, mainSize) || layoutInfo_.jumpIndex_ >= 0) { + while ( + LessNotEqual(position.startMainPos + layoutInfo_->currentOffset_, mainSize) || layoutInfo_->jumpIndex_ >= 0) { auto itemWrapper = layoutWrapper->GetOrCreateChildByIndex(GetChildIndexWithFooter(currentIndex)); if (!itemWrapper) { break; @@ -315,88 +317,77 @@ void WaterFlowLayoutAlgorithm::FillViewport(float mainSize, LayoutWrapper* layou { itemCrossSize->second, mainSize_, axis_ }, layoutProperty, itemWrapper)); auto itemSize = itemWrapper->GetGeometryNode()->GetMarginFrameSize(); auto itemHeight = GetMainAxisSize(itemSize, axis_); - auto item = layoutInfo_.items_[0][position.crossIndex].find(currentIndex); - if (item == layoutInfo_.items_[0][position.crossIndex].end()) { - layoutInfo_.items_[0][position.crossIndex][currentIndex] = + auto item = layoutInfo_->items_[0][position.crossIndex].find(currentIndex); + if (item == layoutInfo_->items_[0][position.crossIndex].end()) { + layoutInfo_->items_[0][position.crossIndex][currentIndex] = std::make_pair(position.startMainPos, itemHeight); } else { if (item->second.second != itemHeight) { item->second.second = itemHeight; - layoutInfo_.ClearCacheAfterIndex(currentIndex); + layoutInfo_->ClearCacheAfterIndex(currentIndex); } } - if (layoutInfo_.jumpIndex_ == currentIndex) { - layoutInfo_.currentOffset_ = - layoutInfo_.JumpToTargetAlign(layoutInfo_.items_[0][position.crossIndex][currentIndex]); - layoutInfo_.currentOffset_ += layoutInfo_.restoreOffset_; + if (layoutInfo_->jumpIndex_ == currentIndex) { + layoutInfo_->currentOffset_ = + layoutInfo_->JumpToTargetAlign(layoutInfo_->items_[0][position.crossIndex][currentIndex]); + layoutInfo_->currentOffset_ += layoutInfo_->restoreOffset_; // restoreOffSet only be used once - layoutInfo_.restoreOffset_ = 0.0f; - layoutInfo_.align_ = ScrollAlign::START; - layoutInfo_.jumpIndex_ = EMPTY_JUMP_INDEX; - layoutInfo_.itemStart_ = false; + layoutInfo_->restoreOffset_ = 0.0f; + layoutInfo_->align_ = ScrollAlign::START; + layoutInfo_->jumpIndex_ = EMPTY_JUMP_INDEX; + layoutInfo_->itemStart_ = false; } position = GetItemPosition(++currentIndex); fill = true; } - layoutInfo_.endIndex_ = !fill ? currentIndex : currentIndex - 1; + layoutInfo_->endIndex_ = !fill ? currentIndex : currentIndex - 1; - layoutInfo_.itemEnd_ = GetChildIndexWithFooter(currentIndex) == layoutInfo_.childrenCount_; - if (layoutInfo_.itemEnd_) { + layoutInfo_->itemEnd_ = GetChildIndexWithFooter(currentIndex) == layoutInfo_->childrenCount_; + if (layoutInfo_->itemEnd_) { ModifyCurrentOffsetWhenReachEnd(mainSize, layoutWrapper); } else { - layoutInfo_.offsetEnd_ = false; + layoutInfo_->offsetEnd_ = false; } } void WaterFlowLayoutAlgorithm::ModifyCurrentOffsetWhenReachEnd(float mainSize, LayoutWrapper* layoutWrapper) { - auto maxItemHeight = layoutInfo_.GetMaxMainHeight(); - if (layoutInfo_.footerIndex_ >= 0) { + auto maxItemHeight = layoutInfo_->GetMaxMainHeight(); + if (layoutInfo_->footerIndex_ >= 0) { footerMainStartPos_ = maxItemHeight; - footerMainSize_ = MeasureFooter(layoutWrapper); + footerMainSize_ = WaterFlowLayoutUtils::MeasureFooter(layoutWrapper, axis_); maxItemHeight += footerMainSize_; } - layoutInfo_.maxHeight_ = maxItemHeight; + layoutInfo_->maxHeight_ = maxItemHeight; if (mainSize >= maxItemHeight) { if (!canOverScroll_) { - layoutInfo_.currentOffset_ = 0; + layoutInfo_->currentOffset_ = 0; } - layoutInfo_.offsetEnd_ = true; - layoutInfo_.itemStart_ = true; + layoutInfo_->offsetEnd_ = true; + layoutInfo_->itemStart_ = true; return; } - if (layoutInfo_.currentOffset_ + maxItemHeight <= mainSize) { - layoutInfo_.offsetEnd_ = true; + if (layoutInfo_->currentOffset_ + maxItemHeight <= mainSize) { + layoutInfo_->offsetEnd_ = true; if (!canOverScroll_) { - layoutInfo_.currentOffset_ = mainSize - maxItemHeight; + layoutInfo_->currentOffset_ = mainSize - maxItemHeight; } - auto oldStart = layoutInfo_.startIndex_; - layoutInfo_.UpdateStartIndex(); + auto oldStart = layoutInfo_->startIndex_; + layoutInfo_->UpdateStartIndex(); // lazyforeach - for (auto i = oldStart; i >= layoutInfo_.startIndex_; i--) { + for (auto i = oldStart; i >= layoutInfo_->startIndex_; i--) { auto itemWrapper = layoutWrapper->GetOrCreateChildByIndex(GetChildIndexWithFooter(i)); CHECK_NULL_VOID(itemWrapper); auto layoutProperty = AceType::DynamicCast(layoutWrapper->GetLayoutProperty()); - float crossSize = itemsCrossSize_.at(layoutInfo_.GetCrossIndex(i)); + float crossSize = itemsCrossSize_.at(layoutInfo_->GetCrossIndex(i)); itemWrapper->Measure(WaterFlowLayoutUtils::CreateChildConstraint( { crossSize, mainSize_, axis_ }, layoutProperty, itemWrapper)); } } else { - layoutInfo_.offsetEnd_ = false; + layoutInfo_->offsetEnd_ = false; } } - -float WaterFlowLayoutAlgorithm::MeasureFooter(LayoutWrapper* layoutWrapper) -{ - auto footer = layoutWrapper->GetOrCreateChildByIndex(layoutInfo_.footerIndex_); - auto layoutProperty = layoutWrapper->GetLayoutProperty(); - auto footerConstraint = layoutProperty->CreateChildConstraint(); - footer->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_CONTENT); - footer->Measure(footerConstraint); - auto itemSize = footer->GetGeometryNode()->GetMarginFrameSize(); - return GetMainAxisSize(itemSize, axis_); -} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_algorithm.h b/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_algorithm.h index 7463d92d47d173efd5b5354938168a6fc0bb14e6..426e6148f65c88d1001dd571049acc4e1c051fe9 100644 --- a/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_algorithm.h +++ b/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_algorithm.h @@ -16,34 +16,22 @@ #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_WATERFLOW_WATER_FLOW_LAYOUT_ALGORITHM_H #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_WATERFLOW_WATER_FLOW_LAYOUT_ALGORITHM_H -#include "core/components_ng/layout/layout_algorithm.h" +#include "core/components_ng/pattern/waterflow/water_flow_layout_algorithm_base.h" #include "core/components_ng/pattern/waterflow/water_flow_layout_info.h" #include "core/components_ng/pattern/waterflow/water_flow_layout_property.h" namespace OHOS::Ace::NG { -class WaterFlowLayoutBase : public LayoutAlgorithm { - DECLARE_ACE_TYPE(WaterFlowLayoutBase, LayoutAlgorithm); - -public: - virtual WaterFlowLayoutInfo GetLayoutInfo() = 0; - virtual void SetCanOverScroll(bool canOverScroll) = 0; -}; - class ACE_EXPORT WaterFlowLayoutAlgorithm : public WaterFlowLayoutBase { DECLARE_ACE_TYPE(WaterFlowLayoutAlgorithm, WaterFlowLayoutBase); public: - explicit WaterFlowLayoutAlgorithm(WaterFlowLayoutInfo layoutInfo) : layoutInfo_(std::move(layoutInfo)) {} + explicit WaterFlowLayoutAlgorithm(const RefPtr& layoutInfo) : layoutInfo_(layoutInfo) {} ~WaterFlowLayoutAlgorithm() override = default; void Measure(LayoutWrapper* layoutWrapper) override; void Layout(LayoutWrapper* layoutWrapper) override; - WaterFlowLayoutInfo GetLayoutInfo() override - { - return std::move(layoutInfo_); - } void SetCanOverScroll(bool canOverScroll) override { canOverScroll_ = canOverScroll; @@ -59,15 +47,16 @@ private: const RefPtr& layoutProperty, const SizeF& frameSize, int32_t childrenCount); int32_t GetChildIndexWithFooter(int32_t index) const { - return index + layoutInfo_.footerIndex_ + 1; + return index + layoutInfo_->footerIndex_ + 1; } - float MeasureFooter(LayoutWrapper* layoutWrapper); void LayoutFooter(LayoutWrapper* layoutWrapper, const OffsetF& childFrameOffset, bool reverse); std::map itemsCrossSize_; std::map itemsCrossPosition_; Axis axis_ = Axis::VERTICAL; + RefPtr layoutInfo_; + float mainGap_ = 0.0f; float crossGap_ = 0.0f; float mainSize_ = 0.0f; @@ -75,7 +64,6 @@ private: float footerMainStartPos_ = 0.0f; bool canOverScroll_ = false; bool skipMeasure_ = false; - WaterFlowLayoutInfo layoutInfo_; }; } // namespace OHOS::Ace::NG #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_WATERFLOW_WATER_FLOW_LAYOUT_ALGORITHM_H diff --git a/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_algorithm_base.h b/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_algorithm_base.h new file mode 100644 index 0000000000000000000000000000000000000000..4466c531fc41255c869ffb53bbd61d00cd2f4de2 --- /dev/null +++ b/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_algorithm_base.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_WATERFLOW_WATER_FLOW_LAYOUT_BASE_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_WATERFLOW_WATER_FLOW_LAYOUT_BASE_H +#include "core/components_ng/layout/layout_algorithm.h" + +namespace OHOS::Ace::NG { +class WaterFlowLayoutBase : public LayoutAlgorithm { + DECLARE_ACE_TYPE(WaterFlowLayoutBase, LayoutAlgorithm); + +public: + virtual void SetCanOverScroll(bool canOverScroll) = 0; +}; + +enum class WaterFlowLayoutMode { TOP_DOWN = 0, SLIDING_WINDOW = 1 }; +} // namespace OHOS::Ace::NG +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_WATERFLOW_WATER_FLOW_LAYOUT_BASE_H diff --git a/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_info.cpp b/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_info.cpp index d1e85250048472da2f7585becbef2019bda1ce53..878a481333df301e26047e5664dac0f5738da075 100644 --- a/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_info.cpp +++ b/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_info.cpp @@ -17,6 +17,7 @@ #include +#include "core/components_ng/pattern/waterflow/layout/sliding_window/water_flow_layout_info_sw.h" #include "core/components_ng/property/calc_length.h" #include "core/components_ng/property/measure_property.h" #include "core/components_ng/property/measure_utils.h" @@ -24,6 +25,16 @@ constexpr float HALF = 0.5f; namespace OHOS::Ace::NG { +RefPtr WaterFlowLayoutInfoBase::Create(WaterFlowLayoutMode mode) +{ + switch (mode) { + case WaterFlowLayoutMode::SLIDING_WINDOW: + return nullptr; + default: + return MakeRefPtr(); + } +} + int32_t WaterFlowLayoutInfo::GetCrossIndex(int32_t itemIndex) const { if (static_cast(itemIndex) < itemInfos_.size()) { @@ -157,6 +168,38 @@ float WaterFlowLayoutInfo::GetStartMainPos(int32_t crossIndex, int32_t itemIndex return result; } +OverScrollOffset WaterFlowLayoutInfo::GetOverScrolledDelta(float delta) const +{ + OverScrollOffset offset = { 0, 0 }; + if (startIndex_ == 0) { + auto startPos = currentOffset_; + auto newStartPos = startPos + delta; + if (startPos > 0 && newStartPos > 0) { + offset.start = delta; + } + if (startPos > 0 && newStartPos <= 0) { + offset.start = -startPos; + } + if (startPos <= 0 && newStartPos > 0) { + offset.start = newStartPos; + } + } + if (itemEnd_) { + auto endPos = currentOffset_ + maxHeight_; + auto newEndPos = endPos + delta; + if (endPos < lastMainSize_ && newEndPos < lastMainSize_) { + offset.end = delta; + } + if (endPos < lastMainSize_ && newEndPos >= lastMainSize_) { + offset.end = lastMainSize_ - endPos; + } + if (endPos >= lastMainSize_ && newEndPos < lastMainSize_) { + offset.end = newEndPos - lastMainSize_; + } + } + return offset; +} + bool WaterFlowLayoutInfo::IsAllCrossReachEnd(float mainSize) const { bool result = true; @@ -533,4 +576,34 @@ void WaterFlowLayoutInfo::JumpTo(const std::pair& item) align_ = ScrollAlign::START; jumpIndex_ = EMPTY_JUMP_INDEX; } + +void WaterFlowLayoutInfo::UpdateOffset(float delta) +{ + prevOffset_ = currentOffset_; + currentOffset_ += delta; +} + +float WaterFlowLayoutInfo::CalcTargetPosition(int32_t idx, int32_t crossIdx) const +{ + return -JumpToTargetAlign(items_[GetSegment(idx)].at(crossIdx).at(idx)); +} + +bool WaterFlowLayoutInfo::OutOfBounds() const +{ + bool outOfStart = itemStart_ && Positive(currentOffset_); + bool outOfEnd = offsetEnd_ && LessNotEqual(currentOffset_ + maxHeight_, lastMainSize_); + return outOfStart || outOfEnd; +} + +float WaterFlowLayoutInfo::CalcOverScroll(float mainSize, float delta) const +{ + float res = 0; + if (itemStart_) { + res = currentOffset_ + delta; + } + if (offsetEnd_) { + res = mainSize - (GetMaxMainHeight() + currentOffset_ - delta); + } + return res; +} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_info.h b/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_info.h index 844895d5b58df56f616212c50cea8a37cf6a898c..b505a803aee8506fd3ee3449f60d632381adcc2c 100644 --- a/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_info.h +++ b/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_info.h @@ -22,6 +22,8 @@ #include #include "core/components/scroll/scroll_controller_base.h" +#include "core/components_ng/pattern/waterflow/water_flow_layout_algorithm_base.h" +#include "core/components_ng/pattern/waterflow/water_flow_layout_info_base.h" #include "core/components_ng/pattern/waterflow/water_flow_sections.h" #include "core/components_ng/property/measure_property.h" @@ -36,15 +38,31 @@ struct FlowItemPosition { float startMainPos = 0; }; -constexpr int32_t EMPTY_JUMP_INDEX = -2; +class WaterFlowLayoutInfo : public WaterFlowLayoutInfoBase { + DECLARE_ACE_TYPE(WaterFlowLayoutInfo, WaterFlowLayoutInfoBase); -class WaterFlowLayoutInfo { public: - int32_t GetCrossIndex(int32_t itemIndex) const; - void UpdateStartIndex(); + WaterFlowLayoutInfo() = default; + ~WaterFlowLayoutInfo() override = default; + + WaterFlowLayoutMode Mode() const override + { + return WaterFlowLayoutMode::TOP_DOWN; + } + float Offset() const override + { + return currentOffset_; + } + int32_t FirstIdx() const override + { + return firstIndex_; + } + int32_t GetCrossIndex(int32_t itemIndex) const override; + + void UpdateStartIndex() override; int32_t GetEndIndexByOffset(float offset) const; float GetMaxMainHeight() const; - float GetContentHeight() const; + float GetContentHeight() const override; bool IsAllCrossReachEnd(float mainSize) const; /** @@ -57,14 +75,42 @@ public: float GetMainHeight(int32_t crossIndex, int32_t itemIndex) const; float GetStartMainPos(int32_t crossIndex, int32_t itemIndex) const; - void Reset(); + void Reset() override; void Reset(int32_t resetFrom); - int32_t GetCrossCount() const; - int32_t GetMainCount() const; + int32_t GetCrossCount() const override; + int32_t GetMainCount() const override; void ClearCacheAfterIndex(int32_t currentIndex); - bool ReachStart(float prevOffset, bool firstLayout) const; - bool ReachEnd(float prevOffset) const; + bool ReachStart(float prevOffset, bool firstLayout) const override; + bool ReachEnd(float prevOffset) const override; + bool OutOfBounds() const override; + + OverScrollOffset GetOverScrolledDelta(float delta) const override; + float CalcOverScroll(float mainSize, float delta) const override; + + void UpdateOffset(float delta) override; + + float CalcTargetPosition(int32_t idx, int32_t crossIdx) const override; + + float GetDelta(float prevPos) const override + { + return prevPos - currentOffset_; + } + + float CurrentPos() const override + { + return currentOffset_; + } + float TopFinalPos() const override + { + return 0.0f; + }; + float BottomFinalPos(float viewHeight) const override + { + float endOffset = viewHeight - GetContentHeight(); + return Negative(endOffset) ? endOffset : 0.0f; + }; + float JumpToTargetAlign(const std::pair& item) const; void JumpTo(const std::pair& item); @@ -82,7 +128,7 @@ public: * @param sections vector of Sections info. * @param start index of the first modified section, all sections prior to [start] remain the same. */ - void InitSegments(const std::vector& sections, int32_t start); + void InitSegments(const std::vector& sections, int32_t start) override; /** * @brief Initialize margin of each section, along with segmentStartPos_, which depends on margin_. @@ -135,32 +181,15 @@ public: */ void Sync(float mainSize, bool overScroll); - Axis axis_ = Axis::VERTICAL; + int32_t childrenCount_ = 0; + float currentOffset_ = 0.0f; float prevOffset_ = 0.0f; - float lastMainSize_ = 0.0f; // 0.0f until itemEnd_ is true float maxHeight_ = 0.0f; - // store offset for distributed migration - float storedOffset_ = 0.0f; - float restoreOffset_ = 0.0f; - - bool itemStart_ = false; - bool itemEnd_ = false; // last item is partially in viewport - bool offsetEnd_ = false; // last item's bottom is in viewport - - int32_t jumpIndex_ = EMPTY_JUMP_INDEX; - - ScrollAlign align_ = ScrollAlign::START; - - int32_t startIndex_ = 0; - int32_t endIndex_ = -1; - int32_t footerIndex_ = -1; - int32_t childrenCount_ = 0; // first index for onScrollIndex int32_t firstIndex_ = 0; - std::optional targetIndex_; // Map structure: [crossIndex, [index, {mainOffset, itemMainSize}]], using ItemMap = std::map>>; diff --git a/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_info_base.h b/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_info_base.h new file mode 100644 index 0000000000000000000000000000000000000000..0b43f02669b2b3d6ffebf0c7bc8d7a2fdf6b2c23 --- /dev/null +++ b/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_info_base.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_WATERFLOW_WATER_FLOW_LAYOUT_INFO_BASE_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_WATERFLOW_WATER_FLOW_LAYOUT_INFO_BASE_H + +#include "base/memory/ace_type.h" +#include "base/utils/noncopyable.h" +#include "core/components/scroll/scroll_controller_base.h" +#include "core/components_ng/pattern/scrollable/scrollable.h" +#include "core/components_ng/pattern/waterflow/water_flow_sections.h" + +namespace OHOS::Ace::NG { +constexpr int32_t EMPTY_JUMP_INDEX = -2; + +enum class WaterFlowLayoutMode; + +class WaterFlowLayoutInfoBase : public AceType { + DECLARE_ACE_TYPE(WaterFlowLayoutInfoBase, AceType); + +public: + WaterFlowLayoutInfoBase() = default; + ~WaterFlowLayoutInfoBase() override = default; + + /* Factory method */ + static RefPtr Create(WaterFlowLayoutMode mode); + + /* PURE GETTERs */ + virtual WaterFlowLayoutMode Mode() const = 0; + virtual float Offset() const = 0; // total offset of content + virtual int32_t FirstIdx() const = 0; // for compatibility + + virtual void UpdateOffset(float delta) = 0; + + /** + * @brief Get which cross-axis lane the item is in. + * + * @param itemIndex + * @return lane index + */ + virtual int32_t GetCrossIndex(int32_t itemIndex) const = 0; + + // implementation of WaterFlowPattern::GetOverScrollOffset + // returns the portion of [delta] that's in overScroll range + virtual OverScrollOffset GetOverScrolledDelta(float delta) const = 0; + + /** + * @param mainSize of viewport. + * @param delta change in content offset. + * @return amount of overScroll (distance to edge) after applying delta. + */ + virtual float CalcOverScroll(float mainSize, float delta) const = 0; + + /** + * @brief Check if WaterFlow just reached content top from the recent layout. + * For triggering events. + * + * @param prevPos previous layout position. + * @param firstLayout check this to emit ReachStart on the initial layout. + * @return true if current position just reached content top. + */ + virtual bool ReachStart(float prevPos, bool firstLayout) const = 0; + /** + * @brief Check if WaterFlow just reached content bottom from the recent layout. + * For triggering events. + * + * @param prevPos previous layout position. + * @return true if current position just reached content bottom. + */ + virtual bool ReachEnd(float prevPos) const = 0; + + virtual bool OutOfBounds() const = 0; + + /** + * @return total height of all recorded items. + */ + virtual float GetContentHeight() const = 0; + + /** + * @brief Get target item's position in order to perform scrollTo animation. + * + * @param idx item's index. + * @param crossIdx item's cross-axis lane index. + * @return absolute position to scroll to. + */ + virtual float CalcTargetPosition(int32_t idx, int32_t crossIdx) const = 0; + + /** + * @return change in position, comparing to [prevPos] + */ + virtual float GetDelta(float prevPos) const = 0; + + virtual int32_t GetMainCount() const = 0; + virtual int32_t GetCrossCount() const = 0; + + /* ======== provide position info for spring effect animation ========= */ + virtual float CurrentPos() const = 0; + /** + * @return final position to bounce back to after over-scrolling from top. + */ + virtual float TopFinalPos() const = 0; + /** + * @param viewHeight height of the viewport. + * @return final position to bounce back to after over-scrolling from bottom. + */ + virtual float BottomFinalPos(float viewHeight) const = 0; + /* ========================================== */ + + virtual void Reset() = 0; + + // for compatibility + virtual void InitSegments(const std::vector& sections, int32_t start) {} + // for compatibility + virtual void UpdateStartIndex() {}; + + bool itemStart_ = false; + bool itemEnd_ = false; // last item is partially in viewport + bool offsetEnd_ = false; // last item's bottom is in viewport + + Axis axis_ = Axis::VERTICAL; + + int32_t jumpIndex_ = EMPTY_JUMP_INDEX; + ScrollAlign align_ = ScrollAlign::START; + std::optional targetIndex_; + + int32_t startIndex_ = 0; + int32_t endIndex_ = -1; + int32_t footerIndex_ = -1; + + float lastMainSize_ = 0.0f; + + // store offset for distributed migration + float storedOffset_ = 0.0f; + float restoreOffset_ = 0.0f; + + ACE_DISALLOW_COPY_AND_MOVE(WaterFlowLayoutInfoBase); +}; + +} // namespace OHOS::Ace::NG +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_WATERFLOW_WATER_FLOW_LAYOUT_INFO_BASE_H diff --git a/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_utils.cpp b/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_utils.cpp index 330eee1bbba274456ea72f0bdab25d8f4af0780b..f12806cc5629066de8d80c2850410284bcd8b0ee 100644 --- a/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_utils.cpp +++ b/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_utils.cpp @@ -42,19 +42,20 @@ std::string WaterFlowLayoutUtils::PreParseArgs(const std::string& args) return rowsArgs; } -FlowItemPosition WaterFlowLayoutUtils::GetItemPosition(const WaterFlowLayoutInfo& info, int32_t index, float mainGap) +FlowItemPosition WaterFlowLayoutUtils::GetItemPosition( + const RefPtr& info, int32_t index, float mainGap) { - auto crossIndex = info.GetCrossIndex(index); + auto crossIndex = info->GetCrossIndex(index); // already in layoutInfo if (crossIndex != -1) { - return { crossIndex, info.GetStartMainPos(crossIndex, index) }; + return { crossIndex, info->GetStartMainPos(crossIndex, index) }; } - int32_t segment = info.GetSegment(index); - auto itemIndex = info.GetCrossIndexForNextItem(segment); + int32_t segment = info->GetSegment(index); + auto itemIndex = info->GetCrossIndexForNextItem(segment); if (itemIndex.lastItemIndex < 0) { - return { itemIndex.crossIndex, info.segmentStartPos_[segment] }; + return { itemIndex.crossIndex, info->segmentStartPos_[segment] }; } - auto mainHeight = info.GetMainHeight(itemIndex.crossIndex, itemIndex.lastItemIndex); + auto mainHeight = info->GetMainHeight(itemIndex.crossIndex, itemIndex.lastItemIndex); return { itemIndex.crossIndex, mainHeight + mainGap }; } @@ -118,4 +119,28 @@ LayoutConstraintF WaterFlowLayoutUtils::CreateChildConstraint( return itemConstraint; } + +std::pair WaterFlowLayoutUtils::PreMeasureSelf(LayoutWrapper* wrapper, Axis axis) +{ + const auto& props = wrapper->GetLayoutProperty(); + auto size = CreateIdealSize(props->GetLayoutConstraint().value(), axis, props->GetMeasureType(), true); + auto matchChildren = GreaterOrEqualToInfinity(GetMainAxisSize(size, axis)); + if (!matchChildren) { + wrapper->GetGeometryNode()->SetFrameSize(size); + } + MinusPaddingToSize(props->CreatePaddingAndBorder(), size); + wrapper->GetGeometryNode()->SetContentSize(size); + return { size, matchChildren }; +} + +float WaterFlowLayoutUtils::MeasureFooter(LayoutWrapper* wrapper, Axis axis) +{ + auto footer = wrapper->GetOrCreateChildByIndex(0); + auto layoutProperty = wrapper->GetLayoutProperty(); + auto footerConstraint = layoutProperty->CreateChildConstraint(); + footer->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_CONTENT); + footer->Measure(footerConstraint); + auto itemSize = footer->GetGeometryNode()->GetMarginFrameSize(); + return GetMainAxisSize(itemSize, axis); +} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_utils.h b/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_utils.h index 7bc6ee5e28ac059a73fca500587f5512f8d61292..74bf9b5f83cecbc59c4ec594fac43f9edca0b71e 100644 --- a/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_utils.h +++ b/frameworks/core/components_ng/pattern/waterflow/water_flow_layout_utils.h @@ -24,7 +24,7 @@ namespace OHOS::Ace::NG { class WaterFlowLayoutUtils { public: static std::string PreParseArgs(const std::string& args); - static FlowItemPosition GetItemPosition(const WaterFlowLayoutInfo& info, int32_t index, float mainGap); + static FlowItemPosition GetItemPosition(const RefPtr& info, int32_t index, float mainGap); struct ConstraintParams { float crossSize = 0.0f; @@ -33,6 +33,20 @@ public: }; static LayoutConstraintF CreateChildConstraint(const ConstraintParams& params, const RefPtr& props, const RefPtr& child); + + /** + * @brief Measure self before measuring children. + * + * @return [idealSize given by parent, whether measure is successful (need to adapt to children size if not)]. + */ + static std::pair PreMeasureSelf(LayoutWrapper* wrapper, Axis axis); + + /** + * @brief Helper to measure the footer node. + * REQUIRES: footer resides at index 0. + * @return main length of the footer node. + */ + static float MeasureFooter(LayoutWrapper* layoutWrapper, Axis axis); }; } // namespace OHOS::Ace::NG #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_WATERFLOW_WATER_FLOW_LAYOUT_UTILS_H diff --git a/frameworks/core/components_ng/pattern/waterflow/water_flow_model.h b/frameworks/core/components_ng/pattern/waterflow/water_flow_model.h index 6f2f01b48624264a9c39418a4a32cf6086036003..665f1dd132d9d22fb5da762334b2e0d689800683 100644 --- a/frameworks/core/components_ng/pattern/waterflow/water_flow_model.h +++ b/frameworks/core/components_ng/pattern/waterflow/water_flow_model.h @@ -22,6 +22,7 @@ #include "core/components/scroll/scroll_controller_base.h" #include "core/components/scroll_bar/scroll_proxy.h" #include "core/components_ng/pattern/scrollable/scrollable_properties.h" +#include "core/components_ng/pattern/waterflow/water_flow_layout_algorithm_base.h" #include "core/components_ng/pattern/waterflow/water_flow_sections.h" namespace OHOS::Ace { @@ -35,6 +36,7 @@ public: virtual RefPtr CreateScrollController() = 0; virtual RefPtr CreateScrollBarProxy() = 0; virtual void SetScroller(RefPtr scroller, RefPtr proxy) = 0; + virtual void SetLayoutMode(NG::WaterFlowLayoutMode mode) = 0; virtual void SetColumnsTemplate(const std::string& value) = 0; virtual void SetRowsTemplate(const std::string& value) = 0; diff --git a/frameworks/core/components_ng/pattern/waterflow/water_flow_model_ng.cpp b/frameworks/core/components_ng/pattern/waterflow/water_flow_model_ng.cpp index 7dc16041ed1e256824f6f016df909af9b0678977..7787f65df23c6f3fca2cc1226c48f78559cd24a5 100644 --- a/frameworks/core/components_ng/pattern/waterflow/water_flow_model_ng.cpp +++ b/frameworks/core/components_ng/pattern/waterflow/water_flow_model_ng.cpp @@ -90,6 +90,13 @@ void WaterFlowModelNG::SetScroller(RefPtr scroller, RefPtr waterFlow->SetScrollBarProxy(AceType::DynamicCast(proxy)); } +void WaterFlowModelNG::SetLayoutMode(WaterFlowLayoutMode mode) +{ + auto waterFlow = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern(); + CHECK_NULL_VOID(waterFlow); + waterFlow->SetLayoutMode(mode); +} + void WaterFlowModelNG::SetColumnsTemplate(const std::string& value) { if (value.empty()) { diff --git a/frameworks/core/components_ng/pattern/waterflow/water_flow_model_ng.h b/frameworks/core/components_ng/pattern/waterflow/water_flow_model_ng.h index 0b71db6d55d48b6675ddbd3147771f06dd451fa6..c2adbf58f877f267522db7703e0f4fb4e035d919 100644 --- a/frameworks/core/components_ng/pattern/waterflow/water_flow_model_ng.h +++ b/frameworks/core/components_ng/pattern/waterflow/water_flow_model_ng.h @@ -28,6 +28,7 @@ public: RefPtr CreateScrollController() override; RefPtr CreateScrollBarProxy() override; void SetScroller(RefPtr scroller, RefPtr proxy) override; + void SetLayoutMode(WaterFlowLayoutMode mode) override; void SetColumnsTemplate(const std::string& value) override; void SetRowsTemplate(const std::string& value) override; diff --git a/frameworks/core/components_ng/pattern/waterflow/water_flow_pattern.cpp b/frameworks/core/components_ng/pattern/waterflow/water_flow_pattern.cpp index b479b82bed562ec5d13f90ac83b9dc0125d89f19..6a2c9b203ec1b3b6991568ac5c8c969ae8bb9c7c 100644 --- a/frameworks/core/components_ng/pattern/waterflow/water_flow_pattern.cpp +++ b/frameworks/core/components_ng/pattern/waterflow/water_flow_pattern.cpp @@ -17,7 +17,9 @@ #include "base/utils/utils.h" #include "core/components/scroll/scroll_controller_base.h" +#include "core/components_ng/pattern/waterflow/layout/sliding_window/water_flow_layout_sw.h" #include "core/components_ng/pattern/waterflow/water_flow_layout_algorithm.h" +#include "core/components_ng/pattern/waterflow/water_flow_layout_info.h" #include "core/components_ng/pattern/waterflow/water_flow_paint_method.h" #include "core/components_ng/pattern/waterflow/water_flow_segmented_layout.h" @@ -47,31 +49,25 @@ bool WaterFlowPattern::UpdateCurrentOffset(float delta, int32_t source) FireAndCleanScrollingListener(); if (GetScrollEdgeEffect()) { // over scroll in drag update from normal to over scroll. - float overScroll = 0.0f; - if (layoutInfo_.itemStart_) { - overScroll = layoutInfo_.currentOffset_ + delta; - } - if (layoutInfo_.offsetEnd_) { - overScroll = GetMainContentSize() - (layoutInfo_.GetMaxMainHeight() + layoutInfo_.currentOffset_ - delta); - } + float overScroll = layoutInfo_->CalcOverScroll(GetMainContentSize(), delta); if (source == SCROLL_FROM_UPDATE) { auto friction = ScrollablePattern::CalculateFriction(std::abs(overScroll) / GetMainContentSize()); delta *= friction; } } else { - if (layoutInfo_.itemStart_ && delta > 0) { + if (layoutInfo_->itemStart_ && delta > 0) { return false; } - if (layoutInfo_.offsetEnd_ && delta < 0) { + if (layoutInfo_->offsetEnd_ && delta < 0) { return false; } - if (GreatNotEqual(delta, 0.0f)) { - delta = std::min(delta, -layoutInfo_.currentOffset_); + if (layoutInfo_->Mode() == LayoutMode::TOP_DOWN && GreatNotEqual(delta, 0.0f)) { + // adjust top overScroll + delta = std::min(delta, -layoutInfo_->Offset()); } } - auto userOffset = FireOnWillScroll(-delta); - layoutInfo_.prevOffset_ = layoutInfo_.currentOffset_; - layoutInfo_.currentOffset_ -= userOffset; + delta = -FireOnWillScroll(-delta); + layoutInfo_->UpdateOffset(delta); host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); return true; }; @@ -82,11 +78,11 @@ bool WaterFlowPattern::IsScrollable() const } bool WaterFlowPattern::IsAtTop() const { - return layoutInfo_.itemStart_; + return layoutInfo_->itemStart_; }; bool WaterFlowPattern::IsAtBottom() const { - return layoutInfo_.offsetEnd_; + return layoutInfo_->offsetEnd_; }; bool WaterFlowPattern::IsReverse() const { @@ -98,38 +94,14 @@ bool WaterFlowPattern::IsReverse() const } OverScrollOffset WaterFlowPattern::GetOverScrollOffset(double delta) const { - OverScrollOffset offset = { 0, 0 }; - if (layoutInfo_.startIndex_ == 0) { - auto startPos = layoutInfo_.currentOffset_; - auto newStartPos = startPos + delta; - if (startPos > 0 && newStartPos > 0) { - offset.start = delta; - } - if (startPos > 0 && newStartPos <= 0) { - offset.start = -startPos; - } - if (startPos <= 0 && newStartPos > 0) { - offset.start = newStartPos; - } - } - if (layoutInfo_.itemEnd_) { - auto endPos = layoutInfo_.currentOffset_ + layoutInfo_.maxHeight_; - auto newEndPos = endPos + delta; - if (endPos < layoutInfo_.lastMainSize_ && newEndPos < layoutInfo_.lastMainSize_) { - offset.end = delta; - } - if (endPos < layoutInfo_.lastMainSize_ && newEndPos >= layoutInfo_.lastMainSize_) { - offset.end = layoutInfo_.lastMainSize_ - endPos; - } - if (endPos >= layoutInfo_.lastMainSize_ && newEndPos < layoutInfo_.lastMainSize_) { - offset.end = newEndPos - layoutInfo_.lastMainSize_; - } - } - return offset; + return layoutInfo_->GetOverScrolledDelta(static_cast(delta)); } void WaterFlowPattern::UpdateScrollBarOffset() { + if (layoutInfo_->Mode() == LayoutMode::SLIDING_WINDOW) { + return; + } if (!GetScrollBar() && !GetScrollBarProxy()) { return; } @@ -138,25 +110,28 @@ void WaterFlowPattern::UpdateScrollBarOffset() auto geometryNode = host->GetGeometryNode(); auto viewSize = geometryNode->GetFrameSize(); auto overScroll = 0.0f; - if (Positive(layoutInfo_.currentOffset_)) { - overScroll = layoutInfo_.currentOffset_; + auto info = DynamicCast(layoutInfo_); + if (Positive(info->currentOffset_)) { + overScroll = info->currentOffset_; } else { - overScroll = GetMainContentSize() - (layoutInfo_.GetContentHeight() + layoutInfo_.currentOffset_); + overScroll = GetMainContentSize() - (info->GetContentHeight() + info->currentOffset_); overScroll = Positive(overScroll) ? overScroll : 0.0f; } HandleScrollBarOutBoundary(overScroll); - UpdateScrollBarRegion(-layoutInfo_.currentOffset_, layoutInfo_.GetContentHeight(), - Size(viewSize.Width(), viewSize.Height()), Offset(0.0f, 0.0f)); + UpdateScrollBarRegion( + -info->currentOffset_, info->GetContentHeight(), Size(viewSize.Width(), viewSize.Height()), Offset(0.0f, 0.0f)); }; RefPtr WaterFlowPattern::CreateLayoutAlgorithm() { if (targetIndex_.has_value()) { - layoutInfo_.targetIndex_ = targetIndex_; + layoutInfo_->targetIndex_ = targetIndex_; } RefPtr algorithm; if (sections_ || SystemProperties::WaterFlowUseSegmentedLayout()) { - algorithm = MakeRefPtr(layoutInfo_); + algorithm = MakeRefPtr(DynamicCast(layoutInfo_)); + } else if (layoutInfo_->Mode() == LayoutMode::SLIDING_WINDOW) { + algorithm = MakeRefPtr(layoutInfo_); } else { int32_t footerIndex = -1; auto footer = footer_.Upgrade(); @@ -166,8 +141,8 @@ RefPtr WaterFlowPattern::CreateLayoutAlgorithm() footerIndex = 0; } } - layoutInfo_.footerIndex_ = footerIndex; - algorithm = MakeRefPtr(layoutInfo_); + layoutInfo_->footerIndex_ = footerIndex; + algorithm = MakeRefPtr(DynamicCast(layoutInfo_)); } algorithm->SetCanOverScroll(CanOverScroll(GetScrollSource())); return algorithm; @@ -205,7 +180,9 @@ void WaterFlowPattern::OnModifyDone() auto paintProperty = GetPaintProperty(); CHECK_NULL_VOID(paintProperty); - if (paintProperty->GetScrollBarProperty()) { + if (layoutInfo_->Mode() == LayoutMode::SLIDING_WINDOW) { + SetScrollBar(DisplayMode::OFF); + } else if (paintProperty->GetScrollBarProperty()) { SetScrollBar(paintProperty->GetScrollBarProperty()); } SetAccessibilityAction(); @@ -226,45 +203,46 @@ bool WaterFlowPattern::OnDirtyLayoutWrapperSwap(const RefPtr& dir CHECK_NULL_RETURN(layoutAlgorithmWrapper, false); auto layoutAlgorithm = DynamicCast(layoutAlgorithmWrapper->GetLayoutAlgorithm()); CHECK_NULL_RETURN(layoutAlgorithm, false); - auto layoutInfo = layoutAlgorithm->GetLayoutInfo(); auto host = GetHost(); CHECK_NULL_RETURN(host, false); auto eventHub = host->GetEventHub(); CHECK_NULL_RETURN(eventHub, false); auto onScroll = eventHub->GetOnScroll(); - PrintOffsetLog(AceLogTag::ACE_WATERFLOW, host->GetId(), prevOffset_ - layoutInfo.currentOffset_); + float delta = layoutInfo_->GetDelta(prevOffset_); + PrintOffsetLog(AceLogTag::ACE_WATERFLOW, host->GetId(), delta); if (onScroll) { - FireOnScroll(prevOffset_ - layoutInfo.currentOffset_, onScroll); + FireOnScroll(delta, onScroll); } auto onDidScroll = eventHub->GetOnDidScroll(); if (onDidScroll) { - FireOnScroll(prevOffset_ - layoutInfo.currentOffset_, onDidScroll); + FireOnScroll(delta, onDidScroll); } - bool indexChanged = - layoutInfo_.firstIndex_ != layoutInfo.firstIndex_ || layoutInfo_.endIndex_ != layoutInfo.endIndex_; + bool indexChanged = itemRange_.first != layoutInfo_->FirstIdx() || itemRange_.second != layoutInfo_->endIndex_; if (indexChanged) { auto onScrollIndex = eventHub->GetOnScrollIndex(); + itemRange_ = { layoutInfo_->FirstIdx(), layoutInfo_->endIndex_ }; if (onScrollIndex) { - onScrollIndex(layoutInfo.firstIndex_, layoutInfo.endIndex_); + onScrollIndex(layoutInfo_->FirstIdx(), layoutInfo_->endIndex_); } } auto onReachStart = eventHub->GetOnReachStart(); - if (onReachStart && layoutInfo.ReachStart(prevOffset_, !isInitialized_)) { + if (onReachStart && layoutInfo_->ReachStart(prevOffset_, !isInitialized_)) { onReachStart(); } auto onReachEnd = eventHub->GetOnReachEnd(); - if (onReachEnd && layoutInfo.ReachEnd(prevOffset_)) { + if (onReachEnd && layoutInfo_->ReachEnd(prevOffset_)) { onReachEnd(); } OnScrollStop(eventHub->GetOnScrollStop()); - layoutInfo_ = std::move(layoutInfo); if (targetIndex_.has_value()) { ScrollToTargetIndex(targetIndex_.value()); targetIndex_.reset(); } - layoutInfo_.UpdateStartIndex(); - prevOffset_ = layoutInfo_.currentOffset_; + layoutInfo_->UpdateStartIndex(); + prevOffset_ = layoutInfo_->Offset(); + layoutInfo_->jumpIndex_ = EMPTY_JUMP_INDEX; + layoutInfo_->targetIndex_.reset(); UpdateScrollBarOffset(); CheckScrollable(); @@ -281,12 +259,11 @@ bool WaterFlowPattern::ScrollToTargetIndex(int32_t index) auto totalItemCount = host->TotalChildCount(); index = totalItemCount - 1; } - auto crossIndex = layoutInfo_.GetCrossIndex(index); + auto crossIndex = layoutInfo_->GetCrossIndex(index); if (crossIndex == -1) { return false; } - auto item = layoutInfo_.items_[layoutInfo_.GetSegment(index)].at(crossIndex).at(index); - float targetPosition = -layoutInfo_.JumpToTargetAlign(item); + float targetPosition = layoutInfo_->CalcTargetPosition(index, crossIndex); ScrollablePattern::AnimateTo(targetPosition, -1, nullptr, true); return true; } @@ -306,9 +283,9 @@ bool WaterFlowPattern::UpdateStartIndex(int32_t index) auto host = GetHost(); CHECK_NULL_RETURN(host, false); auto childCount = host->GetTotalChildCount(); - layoutInfo_.jumpIndex_ = (index == LAST_ITEM ? childCount - 1 : index); + layoutInfo_->jumpIndex_ = (index == LAST_ITEM ? childCount - 1 : index); //if target index is footer, fix align because it will jump after fillViewport. - if (layoutInfo_.footerIndex_ == 0 && layoutInfo_.jumpIndex_ == childCount - 1) { + if (layoutInfo_->footerIndex_ == 0 && layoutInfo_->jumpIndex_ == childCount - 1) { SetScrollAlign(ScrollAlign::END); } host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); @@ -320,7 +297,7 @@ int32_t WaterFlowPattern::GetRows() const auto layoutProperty = GetLayoutProperty(); CHECK_NULL_RETURN(layoutProperty, 0); - return layoutProperty->GetAxis() == Axis::VERTICAL ? layoutInfo_.GetMainCount() : layoutInfo_.GetCrossCount(); + return layoutProperty->GetAxis() == Axis::VERTICAL ? layoutInfo_->GetMainCount() : layoutInfo_->GetCrossCount(); } int32_t WaterFlowPattern::GetColumns() const @@ -328,7 +305,7 @@ int32_t WaterFlowPattern::GetColumns() const auto layoutProperty = GetLayoutProperty(); CHECK_NULL_RETURN(layoutProperty, 0); - return layoutProperty->GetAxis() == Axis::VERTICAL ? layoutInfo_.GetCrossCount() : layoutInfo_.GetMainCount(); + return layoutProperty->GetAxis() == Axis::VERTICAL ? layoutInfo_->GetCrossCount() : layoutInfo_->GetMainCount(); } void WaterFlowPattern::SetAccessibilityAction() @@ -367,8 +344,8 @@ void WaterFlowPattern::ScrollPage(bool reverse, bool smooth) auto mainContentSize = geometryNode->GetPaddingSize().MainSize(axis); if (smooth) { float distance = reverse ? mainContentSize : -mainContentSize; - float position = layoutInfo_.currentOffset_ + distance; - AnimateTo(-position, -1, nullptr, true); + float position = layoutInfo_->Offset() + distance; + ScrollablePattern::AnimateTo(-position, -1, nullptr, true); } else { UpdateCurrentOffset(reverse ? mainContentSize : -mainContentSize, SCROLL_FROM_JUMP); } @@ -398,10 +375,10 @@ void WaterFlowPattern::OnRestoreInfo(const std::string& restoreInfo) Rect WaterFlowPattern::GetItemRect(int32_t index) const { - if (index < 0 || index < layoutInfo_.startIndex_ || index > layoutInfo_.endIndex_) { + if (index < 0 || index < layoutInfo_->startIndex_ || index > layoutInfo_->endIndex_) { return Rect(); } - index += layoutInfo_.footerIndex_ + 1; + index += layoutInfo_->footerIndex_ + 1; auto host = GetHost(); CHECK_NULL_RETURN(host, Rect()); auto item = host->GetChildByIndex(index); @@ -412,8 +389,19 @@ Rect WaterFlowPattern::GetItemRect(int32_t index) const itemGeometry->GetFrameRect().Width(), itemGeometry->GetFrameRect().Height()); } +RefPtr WaterFlowPattern::GetSections() const +{ + if (layoutInfo_->Mode() == LayoutMode::SLIDING_WINDOW) { + return nullptr; + } + return sections_; +} + RefPtr WaterFlowPattern::GetOrCreateWaterFlowSections() { + if (layoutInfo_->Mode() == LayoutMode::SLIDING_WINDOW) { + return nullptr; + } if (sections_) { return sections_; } @@ -442,36 +430,50 @@ RefPtr WaterFlowPattern::GetOrCreateWaterFlowSections() void WaterFlowPattern::OnSectionChanged(int32_t start) { + // SlidingWindow mode should never reach this callback + if (layoutInfo_->Mode() == LayoutMode::SLIDING_WINDOW) { + return; + } + auto info = DynamicCast(layoutInfo_); + CHECK_NULL_VOID(info); auto host = GetHost(); CHECK_NULL_VOID(host); int32_t childUpdateIdx = host->GetChildrenUpdated(); - if (childUpdateIdx > -1 && layoutInfo_.GetSegment(childUpdateIdx - 1) == start && sections_->IsSpecialUpdate()) { + if (childUpdateIdx > -1 && info->GetSegment(childUpdateIdx - 1) == start && sections_->IsSpecialUpdate()) { // optimize adding or removing children in the last section. Prevent complete reset of that section. ++start; } - layoutInfo_.InitSegments(sections_->GetSectionInfo(), start); - layoutInfo_.margins_.clear(); + info->InitSegments(sections_->GetSectionInfo(), start); + info->margins_.clear(); MarkDirtyNodeSelf(); } void WaterFlowPattern::OnSectionChangedNow(int32_t start) { + if (layoutInfo_->Mode() == LayoutMode::SLIDING_WINDOW) { + return; + } + auto info = DynamicCast(layoutInfo_); + CHECK_NULL_VOID(info); auto host = GetHost(); CHECK_NULL_VOID(host); int32_t childUpdateIdx = host->GetChildrenUpdated(); if (sections_->IsSpecialUpdateCAPI(childUpdateIdx)) { start += sections_->GetSectionInfo().size(); } - layoutInfo_.InitSegments(sections_->GetSectionInfo(), start); - layoutInfo_.margins_.clear(); + info->InitSegments(sections_->GetSectionInfo(), start); + info->margins_.clear(); MarkDirtyNodeSelf(); } void WaterFlowPattern::ResetSections() { - layoutInfo_.Reset(); sections_.Reset(); + if (layoutInfo_->Mode() == LayoutMode::SLIDING_WINDOW) { + return; + } + layoutInfo_->Reset(); MarkDirtyNodeSelf(); } @@ -497,10 +499,7 @@ void WaterFlowPattern::ScrollToIndex(int32_t index, bool smooth, ScrollAlign ali bool WaterFlowPattern::IsOutOfBoundary(bool useCurrentDelta) { - bool outOfStart = layoutInfo_.itemStart_ && Positive(layoutInfo_.currentOffset_); - bool outOfEnd = layoutInfo_.offsetEnd_ && - LessNotEqual(layoutInfo_.currentOffset_ + layoutInfo_.maxHeight_, layoutInfo_.lastMainSize_); - return outOfStart || outOfEnd; + return layoutInfo_->OutOfBounds(); } void WaterFlowPattern::SetEdgeEffectCallback(const RefPtr& scrollEffect) @@ -508,28 +507,28 @@ void WaterFlowPattern::SetEdgeEffectCallback(const RefPtr& scr scrollEffect->SetCurrentPositionCallback([weak = AceType::WeakClaim(this)]() -> double { auto pattern = weak.Upgrade(); CHECK_NULL_RETURN(pattern, 0.0); - return pattern->layoutInfo_.currentOffset_; + return pattern->layoutInfo_->CurrentPos(); }); scrollEffect->SetLeadingCallback([weak = AceType::WeakClaim(this)]() -> double { auto pattern = weak.Upgrade(); CHECK_NULL_RETURN(pattern, 0.0); - auto leadOffset = pattern->GetMainContentSize() - pattern->layoutInfo_.GetContentHeight(); - if (pattern->GetAlwaysEnabled() && Positive(leadOffset)) { - return 0.0; - } - return Negative(leadOffset) ? leadOffset : 0.0; + return pattern->layoutInfo_->BottomFinalPos(pattern->GetMainContentSize()); + }); + scrollEffect->SetTrailingCallback([weak = AceType::WeakClaim(this)]() -> double { + auto pattern = weak.Upgrade(); + CHECK_NULL_RETURN(pattern, 0.0); + return pattern->layoutInfo_->TopFinalPos(); }); - scrollEffect->SetTrailingCallback([]() -> double { return 0.0; }); scrollEffect->SetInitLeadingCallback([weak = AceType::WeakClaim(this)]() -> double { auto pattern = weak.Upgrade(); CHECK_NULL_RETURN(pattern, 0.0); - auto leadOffset = pattern->GetMainContentSize() - pattern->layoutInfo_.GetContentHeight(); - if (pattern->GetAlwaysEnabled() && Positive(leadOffset)) { - return 0.0; - } - return Negative(leadOffset) ? leadOffset : 0.0; + return pattern->layoutInfo_->BottomFinalPos(pattern->GetMainContentSize()); + }); + scrollEffect->SetInitTrailingCallback([weak = AceType::WeakClaim(this)]() -> double { + auto pattern = weak.Upgrade(); + CHECK_NULL_RETURN(pattern, 0.0); + return pattern->layoutInfo_->TopFinalPos(); }); - scrollEffect->SetInitTrailingCallback([]() -> double { return 0.0; }); } void WaterFlowPattern::MarkDirtyNodeSelf() @@ -551,6 +550,23 @@ void WaterFlowPattern::OnAnimateStop() MarkDirtyNodeSelf(); } +void WaterFlowPattern::AnimateTo( + float position, float duration, const RefPtr& curve, bool smooth, bool canOverScroll) +{ + if (layoutInfo_->Mode() == WaterFlowLayoutMode::SLIDING_WINDOW) { + return; + } + ScrollablePattern::AnimateTo(position, duration, curve, smooth, canOverScroll); +} + +void WaterFlowPattern::ScrollTo(float position) +{ + if (layoutInfo_->Mode() == WaterFlowLayoutMode::SLIDING_WINDOW) { + return; + } + ScrollablePattern::ScrollTo(position); +} + bool WaterFlowPattern::NeedRender() { auto host = GetHost(); @@ -570,9 +586,9 @@ bool WaterFlowPattern::NeedRender() void WaterFlowPattern::ResetLayoutInfo() { - layoutInfo_.Reset(); + layoutInfo_->Reset(); if (sections_) { - layoutInfo_.InitSegments(sections_->GetSectionInfo(), 0); + layoutInfo_->InitSegments(sections_->GetSectionInfo(), 0); } } @@ -583,12 +599,32 @@ void WaterFlowPattern::AddFooter(const RefPtr& footer) CHECK_NULL_VOID(host); auto prevFooter = footer_.Upgrade(); if (!prevFooter) { - layoutInfo_.footerIndex_ = 0; host->AddChild(footer); + layoutInfo_->footerIndex_ = 0; } else { host->ReplaceChild(prevFooter, footer); } footer_ = footer; footer->SetActive(false); } + +void WaterFlowPattern::SetLayoutMode(LayoutMode mode) +{ + if (!layoutInfo_ || mode != layoutInfo_->Mode()) { + layoutInfo_ = WaterFlowLayoutInfoBase::Create(mode); + } + // footer index only set during first AddFooter call + if (footer_.Upgrade()) { + layoutInfo_->footerIndex_ = 0; + } +} + +int32_t WaterFlowPattern::GetChildrenCount() const +{ + auto host = GetHost(); + if (host) { + return host->GetTotalChildCount(); + } + return 0; +} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/waterflow/water_flow_pattern.h b/frameworks/core/components_ng/pattern/waterflow/water_flow_pattern.h index cf27e7b5e980092525d6ecd07d6b6acd268cf366..228cda014ac38f2334affba52067cb5b3976002b 100644 --- a/frameworks/core/components_ng/pattern/waterflow/water_flow_pattern.h +++ b/frameworks/core/components_ng/pattern/waterflow/water_flow_pattern.h @@ -20,7 +20,8 @@ #include "core/components_ng/pattern/waterflow/water_flow_accessibility_property.h" #include "core/components_ng/pattern/waterflow/water_flow_content_modifier.h" #include "core/components_ng/pattern/waterflow/water_flow_event_hub.h" -#include "core/components_ng/pattern/waterflow/water_flow_layout_info.h" +#include "core/components_ng/pattern/waterflow/water_flow_layout_algorithm_base.h" +#include "core/components_ng/pattern/waterflow/water_flow_layout_info_base.h" #include "core/components_ng/pattern/waterflow/water_flow_layout_property.h" #include "core/components_ng/pattern/waterflow/water_flow_sections.h" @@ -41,6 +42,13 @@ public: OverScrollOffset GetOverScrollOffset(double delta) const override; void UpdateScrollBarOffset() override; + using LayoutMode = WaterFlowLayoutMode; + void SetLayoutMode(LayoutMode mode); + LayoutMode GetLayoutMode() const + { + return layoutInfo_->Mode(); + } + RefPtr CreateLayoutAlgorithm() override; RefPtr CreateLayoutProperty() override @@ -75,22 +83,19 @@ public: int32_t GetBeginIndex() const { - return layoutInfo_.startIndex_; + return layoutInfo_->startIndex_; } int32_t GetEndIndex() const { - return layoutInfo_.endIndex_; + return layoutInfo_->endIndex_; } - int32_t GetChildrenCount() const - { - return layoutInfo_.childrenCount_; - } + int32_t GetChildrenCount() const; float GetTotalOffset() const override { - return -layoutInfo_.currentOffset_; + return -layoutInfo_->Offset(); } int32_t GetRows() const; @@ -100,6 +105,15 @@ public: void SetAccessibilityAction(); void OnAnimateStop() override; + /** + * @brief LayoutMode::SLIDING_WINDOW doesn't support scrollTo and animateTo + */ + void ScrollTo(float position) override; + /** + * @brief LayoutMode::SLIDING_WINDOW doesn't support animateTo + */ + void AnimateTo( + float position, float duration, const RefPtr& curve, bool smooth, bool canOverScroll) override; void ScrollPage(bool reverse, bool smooth = false) override; @@ -107,27 +121,24 @@ public: double GetStoredOffset() const { - return layoutInfo_.storedOffset_; + return layoutInfo_->storedOffset_; } void SetRestoreOffset(double restoreOffset) { - layoutInfo_.restoreOffset_ = restoreOffset; + layoutInfo_->restoreOffset_ = restoreOffset; } void SetScrollAlign(ScrollAlign align) { - layoutInfo_.align_ = align; + layoutInfo_->align_ = align; } std::string ProvideRestoreInfo() override; void OnRestoreInfo(const std::string& restoreInfo) override; Rect GetItemRect(int32_t index) const override; - RefPtr GetSections() const - { - return sections_; - } + RefPtr GetSections() const; RefPtr GetOrCreateWaterFlowSections(); void ResetSections(); @@ -156,11 +167,12 @@ private: bool ScrollToTargetIndex(int32_t index); bool NeedRender(); std::optional targetIndex_; - WaterFlowLayoutInfo layoutInfo_; + RefPtr layoutInfo_ = WaterFlowLayoutInfoBase::Create(LayoutMode::TOP_DOWN); RefPtr sections_; float prevOffset_ = 0.0f; SizeF lastSize_; + std::pair itemRange_ = { -1, -1 }; WeakPtr footer_; // clip padding of WaterFlow diff --git a/frameworks/core/components_ng/pattern/waterflow/water_flow_segmented_layout.cpp b/frameworks/core/components_ng/pattern/waterflow/water_flow_segmented_layout.cpp index 6236e9b795d19a49d05d1515ad96579108f7f5a7..11f33fba76241d920341ab8b1a1a043f3ce83d7a 100644 --- a/frameworks/core/components_ng/pattern/waterflow/water_flow_segmented_layout.cpp +++ b/frameworks/core/components_ng/pattern/waterflow/water_flow_segmented_layout.cpp @@ -32,15 +32,15 @@ namespace OHOS::Ace::NG { namespace { -bool IsDataValid(const WaterFlowLayoutInfo& info) +bool IsDataValid(const RefPtr& info) { - if (info.segmentTails_.empty()) { + if (info->segmentTails_.empty()) { return false; } - if (info.childrenCount_ - 1 != info.segmentTails_.back()) { + if (info->childrenCount_ - 1 != info->segmentTails_.back()) { TAG_LOGW(AceLogTag::ACE_WATERFLOW, "Children count = %{public}d and doesn't match the number provided in Sections, which is %{public}d.", - info.childrenCount_, info.segmentTails_.back() + 1); + info->childrenCount_, info->segmentTails_.back() + 1); return false; } return true; @@ -51,25 +51,25 @@ void WaterFlowSegmentedLayout::Measure(LayoutWrapper* wrapper) { wrapper_ = wrapper; auto props = DynamicCast(wrapper->GetLayoutProperty()); - info_.axis_ = axis_ = props->GetAxis(); - auto [idealSize, matchChildren] = PreMeasureSelf(); + info_->axis_ = axis_ = props->GetAxis(); + auto [idealSize, matchChildren] = WaterFlowLayoutUtils::PreMeasureSelf(wrapper_, axis_); Init(idealSize); if (!IsDataValid(info_)) { return; } - if (info_.childrenCount_ == 0) { + if (info_->childrenCount_ == 0) { return; } mainSize_ = GetMainAxisSize(idealSize, axis_); - if (info_.jumpIndex_ != EMPTY_JUMP_INDEX) { - MeasureOnJump(info_.jumpIndex_); - info_.jumpIndex_ = EMPTY_JUMP_INDEX; - } else if (info_.targetIndex_) { - MeasureToTarget(*info_.targetIndex_); - info_.targetIndex_.reset(); + if (info_->jumpIndex_ != EMPTY_JUMP_INDEX) { + MeasureOnJump(info_->jumpIndex_); + info_->jumpIndex_ = EMPTY_JUMP_INDEX; + } else if (info_->targetIndex_) { + MeasureToTarget(*info_->targetIndex_); + info_->targetIndex_.reset(); } else { MeasureOnOffset(); } @@ -77,7 +77,7 @@ void WaterFlowSegmentedLayout::Measure(LayoutWrapper* wrapper) if (matchChildren) { PostMeasureSelf(idealSize); } - info_.lastMainSize_ = mainSize_; + info_->lastMainSize_ = mainSize_; wrapper_->SetCacheCount(props->GetCachedCountValue(1)); } @@ -87,7 +87,7 @@ void WaterFlowSegmentedLayout::Layout(LayoutWrapper* wrapper) if (!IsDataValid(info_)) { return; } - if (info_.childrenCount_ == 0) { + if (info_->childrenCount_ == 0) { return; } @@ -104,7 +104,7 @@ void WaterFlowSegmentedLayout::Layout(LayoutWrapper* wrapper) auto isRtl = layoutDirection == TextDirection::RTL && axis_ == Axis::VERTICAL; // prepare crossPos for (size_t i = 0; i < segmentCnt; ++i) { - float pos = ((axis_ == Axis::VERTICAL) ? info_.margins_[i].left : info_.margins_[i].top).value_or(0.0f); + float pos = ((axis_ == Axis::VERTICAL) ? info_->margins_[i].left : info_->margins_[i].top).value_or(0.0f); for (const auto& len : itemsCrossSize_[i]) { crossPos[i].push_back(!isRtl ? pos : crossSize - pos - len); pos += len + crossGaps_[i]; @@ -112,13 +112,13 @@ void WaterFlowSegmentedLayout::Layout(LayoutWrapper* wrapper) } bool isReverse = props->IsReverse(); - for (int32_t i = info_.startIndex_; i <= info_.endIndex_; ++i) { - LayoutItem(i, crossPos[info_.GetSegment(i)][info_.itemInfos_[i].crossIdx], initialOffset, isReverse); + for (int32_t i = info_->startIndex_; i <= info_->endIndex_; ++i) { + LayoutItem(i, crossPos[info_->GetSegment(i)][info_->itemInfos_[i].crossIdx], initialOffset, isReverse); } - wrapper_->SetActiveChildRange(info_.startIndex_, info_.endIndex_); + wrapper_->SetActiveChildRange(info_->startIndex_, info_->endIndex_); // for compatibility - info_.firstIndex_ = info_.startIndex_; + info_->firstIndex_ = info_->startIndex_; } namespace { @@ -128,21 +128,21 @@ namespace { * @param info WaterFlowLayoutInfo * @return current StartItem's offset relative to the viewport. */ -float PrepareJump(WaterFlowLayoutInfo& info) +float PrepareJump(const RefPtr& info) { - if (info.endIndex_ == -1) { + if (info->endIndex_ == -1) { // implies that LayoutInfo has already been reset, no need to jump return 0.0f; } - info.jumpIndex_ = std::min(info.startIndex_, info.childrenCount_ - 1); - info.align_ = ScrollAlign::START; - float itemOffset = (info.itemInfos_.size() <= static_cast(info.startIndex_)) - ? info.storedOffset_ - : info.currentOffset_ + info.itemInfos_[info.startIndex_].mainOffset; + info->jumpIndex_ = std::min(info->startIndex_, info->childrenCount_ - 1); + info->align_ = ScrollAlign::START; + float itemOffset = (info->itemInfos_.size() <= static_cast(info->startIndex_)) + ? info->storedOffset_ + : info->currentOffset_ + info->itemInfos_[info->startIndex_].mainOffset; - info.startIndex_ = 0; - info.endIndex_ = -1; - info.currentOffset_ = 0.0f; + info->startIndex_ = 0; + info->endIndex_ = -1; + info->currentOffset_ = 0.0f; return itemOffset; } @@ -150,36 +150,36 @@ float PrepareJump(WaterFlowLayoutInfo& info) void WaterFlowSegmentedLayout::Init(const SizeF& frameSize) { - info_.childrenCount_ = wrapper_->GetTotalChildCount(); - if (info_.childrenCount_ == 0) { + info_->childrenCount_ = wrapper_->GetTotalChildCount(); + if (info_->childrenCount_ == 0) { return; } sections_ = wrapper_->GetHostNode()->GetPattern()->GetSections(); if (sections_) { const auto& sections = sections_->GetSectionInfo(); - if (info_.margins_.empty()) { + if (info_->margins_.empty()) { // empty margins_ implies a segment change auto constraint = wrapper_->GetLayoutProperty()->GetLayoutConstraint(); postJumpOffset_ = PrepareJump(info_); - info_.InitMargins(sections, constraint->scaleProperty, constraint->percentReference.Width()); + info_->InitMargins(sections, constraint->scaleProperty, constraint->percentReference.Width()); } SegmentInit(sections, frameSize); - if (info_.segmentTails_.empty()) { - info_.InitSegments(sections, 0); + if (info_->segmentTails_.empty()) { + info_->InitSegments(sections, 0); } } else { RegularInit(frameSize); - if (info_.footerIndex_ >= 0) { + if (info_->footerIndex_ >= 0) { InitFooter(frameSize.CrossSize(axis_)); } } int32_t updateIdx = wrapper_->GetHostNode()->GetChildrenUpdated(); if (updateIdx != -1) { - if (updateIdx <= info_.endIndex_) { + if (updateIdx <= info_->endIndex_) { postJumpOffset_ = PrepareJump(info_); } - info_.ClearCacheAfterIndex(updateIdx - 1); + info_->ClearCacheAfterIndex(updateIdx - 1); wrapper_->GetHostNode()->ChildrenUpdatedFrom(-1); return; } @@ -207,7 +207,7 @@ void WaterFlowSegmentedLayout::SegmentInit( std::swap(crossGaps_[i], mainGaps_[i]); } - const auto& margin = info_.margins_[i]; + const auto& margin = info_->margins_[i]; float crossSize = frameSize.CrossSize(axis_) - (axis_ == Axis::VERTICAL ? margin.Width() : margin.Height()); int32_t crossCnt = options[i].crossCount.value_or(1); itemsCrossSize_[i].resize(crossCnt); @@ -237,10 +237,10 @@ void WaterFlowSegmentedLayout::RegularInit(const SizeF& frameSize) std::pair, bool> cross; if (axis_ == Axis::VERTICAL) { cross = ParseTemplateArgs( - WaterFlowLayoutUtils::PreParseArgs(columnsTemplate), crossSize, crossGaps_[0], info_.childrenCount_); + WaterFlowLayoutUtils::PreParseArgs(columnsTemplate), crossSize, crossGaps_[0], info_->childrenCount_); } else { cross = ParseTemplateArgs( - WaterFlowLayoutUtils::PreParseArgs(rowsTemplate), crossSize, crossGaps_[0], info_.childrenCount_); + WaterFlowLayoutUtils::PreParseArgs(rowsTemplate), crossSize, crossGaps_[0], info_->childrenCount_); } crossLens = cross.first; if (crossLens.empty()) { @@ -252,18 +252,18 @@ void WaterFlowSegmentedLayout::RegularInit(const SizeF& frameSize) itemsCrossSize_ = { {} }; - if (crossLens.size() < info_.items_[0].size()) { - auto it = info_.items_[0].find(crossLens.size()); - info_.items_[0].erase(it, info_.items_[0].end()); + if (crossLens.size() < info_->items_[0].size()) { + auto it = info_->items_[0].find(crossLens.size()); + info_->items_[0].erase(it, info_->items_[0].end()); } int32_t index = 0; for (const auto& len : crossLens) { itemsCrossSize_[0].push_back(len); - info_.items_[0].try_emplace(index, std::map>()); + info_->items_[0].try_emplace(index, std::map>()); ++index; } - info_.margins_.resize(1); - info_.segmentTails_ = { (info_.footerIndex_ >= 0) ? info_.childrenCount_ - 2 : info_.childrenCount_ - 1 }; + info_->margins_.resize(1); + info_->segmentTails_ = { (info_->footerIndex_ >= 0) ? info_->childrenCount_ - 2 : info_->childrenCount_ - 1 }; } void WaterFlowSegmentedLayout::InitFooter(float crossSize) @@ -271,24 +271,24 @@ void WaterFlowSegmentedLayout::InitFooter(float crossSize) mainGaps_.emplace_back(0.0f); itemsCrossSize_.emplace_back(std::vector { crossSize }); - if (info_.items_.size() == 1) { - info_.items_.emplace_back(); - info_.items_.back().try_emplace(0); + if (info_->items_.size() == 1) { + info_->items_.emplace_back(); + info_->items_.back().try_emplace(0); } - info_.margins_.emplace_back(); - info_.segmentTails_.emplace_back(info_.childrenCount_ - 1); + info_->margins_.emplace_back(); + info_->segmentTails_.emplace_back(info_->childrenCount_ - 1); - if (info_.footerIndex_ != info_.childrenCount_ - 1) { - info_.footerIndex_ = std::min(info_.footerIndex_, info_.childrenCount_ - 1); - info_.ClearCacheAfterIndex(info_.footerIndex_ - 1); + if (info_->footerIndex_ != info_->childrenCount_ - 1) { + info_->footerIndex_ = std::min(info_->footerIndex_, info_->childrenCount_ - 1); + info_->ClearCacheAfterIndex(info_->footerIndex_ - 1); // re-insert at the end - auto footer = wrapper_->GetOrCreateChildByIndex(info_.footerIndex_); + auto footer = wrapper_->GetOrCreateChildByIndex(info_->footerIndex_); auto waterFlow = wrapper_->GetHostNode(); - waterFlow->RemoveChildAtIndex(info_.footerIndex_); + waterFlow->RemoveChildAtIndex(info_->footerIndex_); footer->GetHostNode()->MountToParent(waterFlow); footer->SetActive(false); - info_.segmentCache_.erase(info_.footerIndex_); - info_.footerIndex_ = info_.childrenCount_ - 1; + info_->segmentCache_.erase(info_->footerIndex_); + info_->footerIndex_ = info_->childrenCount_ - 1; } } @@ -310,62 +310,62 @@ float GetUserDefHeight(const RefPtr& sections, int32_t seg, i void WaterFlowSegmentedLayout::MeasureOnOffset() { - bool forward = LessOrEqual(info_.currentOffset_ - info_.prevOffset_, 0.0f) || info_.endIndex_ == -1; + bool forward = LessOrEqual(info_->currentOffset_ - info_->prevOffset_, 0.0f) || info_->endIndex_ == -1; if (forward) { - Fill(info_.endIndex_ + 1); + Fill(info_->endIndex_ + 1); } - int32_t oldStart = info_.startIndex_; - info_.Sync(mainSize_, overScroll_); + int32_t oldStart = info_->startIndex_; + info_->Sync(mainSize_, overScroll_); if (!forward) { // measure appearing items when scrolling upwards auto props = DynamicCast(wrapper_->GetLayoutProperty()); - for (int32_t i = info_.startIndex_; i < oldStart; ++i) { - MeasureItem(props, i, info_.itemInfos_[i].crossIdx, GetUserDefHeight(sections_, info_.GetSegment(i), i)); + for (int32_t i = info_->startIndex_; i < oldStart; ++i) { + MeasureItem(props, i, info_->itemInfos_[i].crossIdx, GetUserDefHeight(sections_, info_->GetSegment(i), i)); } } } void WaterFlowSegmentedLayout::MeasureOnJump(int32_t jumpIdx) { - if (jumpIdx >= info_.childrenCount_) { + if (jumpIdx >= info_->childrenCount_) { return; } if (jumpIdx == LAST_ITEM) { - jumpIdx = info_.childrenCount_ - 1; + jumpIdx = info_->childrenCount_ - 1; } - if (static_cast(jumpIdx) >= info_.itemInfos_.size()) { + if (static_cast(jumpIdx) >= info_->itemInfos_.size()) { // prepare items MeasureToTarget(jumpIdx); } // solve offset - const auto& item = info_.itemInfos_[jumpIdx]; - if (info_.align_ == ScrollAlign::AUTO) { - info_.align_ = TransformAutoScroll(item); + const auto& item = info_->itemInfos_[jumpIdx]; + if (info_->align_ == ScrollAlign::AUTO) { + info_->align_ = TransformAutoScroll(item); } - info_.currentOffset_ = SolveJumpOffset(item) + postJumpOffset_; + info_->currentOffset_ = SolveJumpOffset(item) + postJumpOffset_; Fill(jumpIdx); - info_.Sync(mainSize_, false); + info_->Sync(mainSize_, false); // only if range [startIndex, jumpIdx) isn't measured (used user-defined size) if (!sections_) { return; } auto props = DynamicCast(wrapper_->GetLayoutProperty()); - for (int32_t i = info_.startIndex_; i < jumpIdx; ++i) { - auto seg = info_.GetSegment(i); + for (int32_t i = info_->startIndex_; i < jumpIdx; ++i) { + auto seg = info_->GetSegment(i); if (sections_->GetSectionInfo()[seg].onGetItemMainSizeByIndex) { - MeasureItem(props, i, info_.itemInfos_[i].crossIdx, GetUserDefHeight(sections_, seg, i)); + MeasureItem(props, i, info_->itemInfos_[i].crossIdx, GetUserDefHeight(sections_, seg, i)); } } } ScrollAlign WaterFlowSegmentedLayout::TransformAutoScroll(const WaterFlowLayoutInfo::ItemInfo& item) const { - bool isAbove = LessNotEqual(info_.currentOffset_ + item.mainOffset, 0.0f); - bool isBelow = GreatNotEqual(info_.currentOffset_ + item.mainOffset + item.mainSize, mainSize_); + bool isAbove = LessNotEqual(info_->currentOffset_ + item.mainOffset, 0.0f); + bool isBelow = GreatNotEqual(info_->currentOffset_ + item.mainOffset + item.mainSize, mainSize_); if (isAbove && isBelow) { // possible when the item is larger than viewport return ScrollAlign::NONE; @@ -381,8 +381,8 @@ ScrollAlign WaterFlowSegmentedLayout::TransformAutoScroll(const WaterFlowLayoutI float WaterFlowSegmentedLayout::SolveJumpOffset(const WaterFlowLayoutInfo::ItemInfo& item) const { - float offset = info_.currentOffset_; - switch (info_.align_) { + float offset = info_->currentOffset_; + switch (info_->align_) { case ScrollAlign::START: offset = -item.mainOffset; break; @@ -404,9 +404,9 @@ float WaterFlowSegmentedLayout::SolveJumpOffset(const WaterFlowLayoutInfo::ItemI void WaterFlowSegmentedLayout::MeasureToTarget(int32_t targetIdx) { auto props = DynamicCast(wrapper_->GetLayoutProperty()); - targetIdx = std::min(targetIdx, info_.childrenCount_ - 1); - for (int32_t i = static_cast(info_.itemInfos_.size()); i <= targetIdx; ++i) { - int32_t seg = info_.GetSegment(i); + targetIdx = std::min(targetIdx, info_->childrenCount_ - 1); + for (int32_t i = static_cast(info_->itemInfos_.size()); i <= targetIdx; ++i) { + int32_t seg = info_->GetSegment(i); auto position = WaterFlowLayoutUtils::GetItemPosition(info_, i, mainGaps_[seg]); float itemHeight = GetUserDefHeight(sections_, seg, i); if (itemHeight < 0.0f) { @@ -415,25 +415,25 @@ void WaterFlowSegmentedLayout::MeasureToTarget(int32_t targetIdx) itemHeight = GetMainAxisSize(item->GetGeometryNode()->GetMarginFrameSize(), axis_); } } - info_.RecordItem(i, position, itemHeight); + info_->RecordItem(i, position, itemHeight); } } void WaterFlowSegmentedLayout::Fill(int32_t startIdx) { auto props = DynamicCast(wrapper_->GetLayoutProperty()); - for (int32_t i = startIdx; i < info_.childrenCount_; ++i) { - auto position = WaterFlowLayoutUtils::GetItemPosition(info_, i, mainGaps_[info_.GetSegment(i)]); - if (GreatOrEqual(position.startMainPos + info_.currentOffset_, mainSize_)) { + for (int32_t i = startIdx; i < info_->childrenCount_; ++i) { + auto position = WaterFlowLayoutUtils::GetItemPosition(info_, i, mainGaps_[info_->GetSegment(i)]); + if (GreatOrEqual(position.startMainPos + info_->currentOffset_, mainSize_)) { break; } - float itemHeight = GetUserDefHeight(sections_, info_.GetSegment(i), i); + float itemHeight = GetUserDefHeight(sections_, info_->GetSegment(i), i); auto item = MeasureItem(props, i, position.crossIndex, itemHeight); if (!item) { continue; } - if (info_.itemInfos_.size() <= static_cast(i)) { - info_.RecordItem(i, position, GetMainAxisSize(item->GetGeometryNode()->GetMarginFrameSize(), axis_)); + if (info_->itemInfos_.size() <= static_cast(i)) { + info_->RecordItem(i, position, GetMainAxisSize(item->GetGeometryNode()->GetMarginFrameSize(), axis_)); } } } @@ -457,26 +457,13 @@ RefPtr WaterFlowSegmentedLayout::MeasureItem( : CalcSize(CalcLength(userDefMainSize), crossSize)); } item->Measure(WaterFlowLayoutUtils::CreateChildConstraint( - { itemsCrossSize_[info_.GetSegment(idx)][crossIdx], mainSize_, axis_ }, props, item)); + { itemsCrossSize_[info_->GetSegment(idx)][crossIdx], mainSize_, axis_ }, props, item)); return item; } -std::pair WaterFlowSegmentedLayout::PreMeasureSelf() -{ - auto props = wrapper_->GetLayoutProperty(); - auto size = CreateIdealSize(props->GetLayoutConstraint().value(), axis_, props->GetMeasureType(), true); - auto matchChildren = GreaterOrEqualToInfinity(GetMainAxisSize(size, axis_)); - if (!matchChildren) { - wrapper_->GetGeometryNode()->SetFrameSize(size); - } - MinusPaddingToSize(props->CreatePaddingAndBorder(), size); - wrapper_->GetGeometryNode()->SetContentSize(size); - return { size, matchChildren }; -} - void WaterFlowSegmentedLayout::PostMeasureSelf(SizeF size) { - mainSize_ = info_.maxHeight_; + mainSize_ = info_->maxHeight_; size.SetMainSize(mainSize_, axis_); auto props = wrapper_->GetLayoutProperty(); AddPaddingToSize(props->CreatePaddingAndBorder(), size); @@ -485,8 +472,8 @@ void WaterFlowSegmentedLayout::PostMeasureSelf(SizeF size) void WaterFlowSegmentedLayout::LayoutItem(int32_t idx, float crossPos, const OffsetF& padding, bool isReverse) { - const auto& item = info_.itemInfos_[idx]; - auto mainOffset = item.mainOffset + info_.currentOffset_; + const auto& item = info_->itemInfos_[idx]; + auto mainOffset = item.mainOffset + info_->currentOffset_; if (isReverse) { mainOffset = mainSize_ - item.mainSize - mainOffset; } @@ -502,8 +489,8 @@ void WaterFlowSegmentedLayout::LayoutItem(int32_t idx, float crossPos, const Off } // recode restore info - if (idx == info_.startIndex_) { - info_.storedOffset_ = mainOffset; + if (idx == info_->startIndex_) { + info_->storedOffset_ = mainOffset; } } } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/waterflow/water_flow_segmented_layout.h b/frameworks/core/components_ng/pattern/waterflow/water_flow_segmented_layout.h index 18f8c0c4815eb1198f55abef9fb79937b62a3571..579394285335f0c32c8b68536fee56a8a26acf7d 100644 --- a/frameworks/core/components_ng/pattern/waterflow/water_flow_segmented_layout.h +++ b/frameworks/core/components_ng/pattern/waterflow/water_flow_segmented_layout.h @@ -25,18 +25,13 @@ class WaterFlowSegmentedLayout : public WaterFlowLayoutBase { DECLARE_ACE_TYPE(WaterFlowSegmentedLayout, WaterFlowLayoutBase); public: - explicit WaterFlowSegmentedLayout(WaterFlowLayoutInfo layoutInfo) : info_(std::move(layoutInfo)) {} + explicit WaterFlowSegmentedLayout(const RefPtr& layoutInfo) : info_(layoutInfo) {} ~WaterFlowSegmentedLayout() override = default; void Measure(LayoutWrapper* layoutWrapper) override; void Layout(LayoutWrapper* layoutWrapper) override; - WaterFlowLayoutInfo GetLayoutInfo() override - { - return std::move(info_); - } - void SetCanOverScroll(bool value) override { overScroll_ = value; @@ -66,13 +61,6 @@ private: void RegularInit(const SizeF& frameSize); void InitFooter(float crossSize); - /** - * @brief Measure self before measuring children. - * - * @return [idealSize given by parent, whether measure is successful (need to adapt to children size if not)]. - */ - std::pair PreMeasureSelf(); - /** * @brief Measure self after measuring children. Only when pre-measure failed. * @@ -157,7 +145,7 @@ private: // offset to apply after a ResetAndJump float postJumpOffset_ = 0.0f; - WaterFlowLayoutInfo info_; + RefPtr info_; // true if WaterFlow can be overScrolled bool overScroll_ = false; diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index e36bd592dcd6238f5de24a132aab058f1cb63343..afb2d9dec88038401b542aa1efae122b1aeaf9db 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -1046,6 +1046,8 @@ ohos_source_set("ace_components_pattern") { "$ace_root/frameworks/core/components_ng/pattern/video/video_node.cpp", "$ace_root/frameworks/core/components_ng/pattern/video/video_pattern.cpp", "$ace_root/frameworks/core/components_ng/pattern/view_context/view_context_model_ng.cpp", + "$ace_root/frameworks/core/components_ng/pattern/waterflow/layout/sliding_window/water_flow_layout_info_sw.cpp", + "$ace_root/frameworks/core/components_ng/pattern/waterflow/layout/sliding_window/water_flow_layout_sw.cpp", "$ace_root/frameworks/core/components_ng/pattern/waterflow/water_flow_accessibility_property.cpp", "$ace_root/frameworks/core/components_ng/pattern/waterflow/water_flow_content_modifier.cpp", "$ace_root/frameworks/core/components_ng/pattern/waterflow/water_flow_item_model_ng.cpp", diff --git a/test/unittest/core/BUILD.gn b/test/unittest/core/BUILD.gn index eda93b44ace11753eb551330ca483abbadfb8a39..2dfccf6f56909c51b2918bfe03a3860a7422294b 100644 --- a/test/unittest/core/BUILD.gn +++ b/test/unittest/core/BUILD.gn @@ -167,6 +167,7 @@ group("linux_core_unittest") { # "pattern/waterflow:water_flow_test_ng", "pattern/waterflow:water_flow_test_old", + "pattern/waterflow:water_flow_test_sw", # "pattern/xcomponent:xcomponent_test_ng", "property:core_property_unittest", diff --git a/test/unittest/core/pattern/BUILD.gn b/test/unittest/core/pattern/BUILD.gn index 0a02833d65a8f6834e1ae062369c8114111b85ef..e4ce9d3a06ae5236c4dbb15682d3feef401aa7c7 100644 --- a/test/unittest/core/pattern/BUILD.gn +++ b/test/unittest/core/pattern/BUILD.gn @@ -104,6 +104,7 @@ group("core_pattern_unittest") { "video:video_test_ng", "waterflow:water_flow_test_ng", "waterflow:water_flow_test_old", + "waterflow:water_flow_test_sw", "xcomponent:xcomponent_test_ng", ] } diff --git a/test/unittest/core/pattern/waterflow/BUILD.gn b/test/unittest/core/pattern/waterflow/BUILD.gn index b860f6a05604a33357271cfb5e2b89d7b96a055c..a1a27c9f6c2aea46f9871dd3d6afb685efdfa3ef 100644 --- a/test/unittest/core/pattern/waterflow/BUILD.gn +++ b/test/unittest/core/pattern/waterflow/BUILD.gn @@ -15,7 +15,11 @@ import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") ace_unittest("water_flow_test_old") { type = "new" - sources = [ "water_flow_test_ng.cpp" ] + sources = [ + "water_flow_regular_test.cpp", + "water_flow_test_ng.cpp", + "water_flow_top_down_test.cpp", + ] } ace_unittest("water_flow_test_ng") { @@ -26,5 +30,16 @@ ace_unittest("water_flow_test_ng") { "water_flow_scroller_test_ng.cpp", "water_flow_segment_layout_test.cpp", "water_flow_test_ng.cpp", + "water_flow_top_down_test.cpp", + ] +} + +ace_unittest("water_flow_test_sw") { + type = "new" + defines = [ "TEST_WATER_FLOW_SW" ] + sources = [ + "water_flow_regular_test.cpp", + "water_flow_sw_layout_test.cpp", + "water_flow_test_ng.cpp", ] } diff --git a/test/unittest/core/pattern/waterflow/water_flow_regular_test.cpp b/test/unittest/core/pattern/waterflow/water_flow_regular_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..12f61778ffd3480e094f570d6ce92923cabcb3fb --- /dev/null +++ b/test/unittest/core/pattern/waterflow/water_flow_regular_test.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "test/unittest/core/pattern/waterflow/water_flow_test_ng.h" + +namespace OHOS::Ace::NG { +// TEST non-segmented layout + +/** + * @tc.name: OffsetEnd001 + * @tc.desc: Check OffsetEnd value with footer + * @tc.type: FUNC + */ +HWTEST_F(WaterFlowTestNg, OffsetEnd001, TestSize.Level1) +{ + Create([](WaterFlowModelNG model) { + model.SetColumnsTemplate("1fr 1fr"); + model.SetFooter(GetDefaultHeaderBuilder()); + model.SetRowsGap(Dimension(5.0f)); + CreateItem(30); + }); + pattern_->ScrollToIndex(29, false, ScrollAlign::END); + auto info = pattern_->layoutInfo_; + FlushLayoutTask(frameNode_); + EXPECT_EQ(info->endIndex_, 29); + EXPECT_EQ(GetChildY(frameNode_, 30), 600.0f); + EXPECT_FALSE(info->offsetEnd_); + + UpdateCurrentOffset(-45.0f); + FlushLayoutTask(frameNode_); + EXPECT_EQ(info->endIndex_, 29); + EXPECT_FALSE(info->offsetEnd_); + + UpdateCurrentOffset(-5.0f); + FlushLayoutTask(frameNode_); + EXPECT_EQ(info->endIndex_, 29); + EXPECT_TRUE(info->offsetEnd_); + EXPECT_TRUE(info->ReachEnd(50.0f)); + + UpdateCurrentOffset(1.0f); + FlushLayoutTask(frameNode_); + EXPECT_FALSE(info->offsetEnd_); +} + +/** + * @tc.name: ScrollToEdge001 + * @tc.desc: Test ScrollToEdge func + * @tc.type: FUNC + */ +HWTEST_F(WaterFlowTestNg, ScrollToEdge001, TestSize.Level1) +{ + Create([](WaterFlowModelNG model) { + model.SetFooter(GetDefaultHeaderBuilder()); + model.SetColumnsTemplate("1fr 1fr"); + CreateItem(100); + }); + pattern_->ScrollToEdge(ScrollEdgeType::SCROLL_BOTTOM, false); + FlushLayoutTask(frameNode_); + auto info = pattern_->layoutInfo_; + EXPECT_EQ(info->endIndex_, 99); + EXPECT_EQ(GetChildY(frameNode_, 100), 550.0f); + EXPECT_EQ(GetChildOffset(frameNode_, info->footerIndex_), OffsetF(0.0f, 750.0f)); + // scrolled to footer +} +} // namespace OHOS::Ace::NG diff --git a/test/unittest/core/pattern/waterflow/water_flow_scroller_test_ng.cpp b/test/unittest/core/pattern/waterflow/water_flow_scroller_test_ng.cpp index ad8bfc99fed0c628d97aca20f8d0c5eb3066974a..3c1d684fd0bb136a760a34766287ef7e30705c05 100644 --- a/test/unittest/core/pattern/waterflow/water_flow_scroller_test_ng.cpp +++ b/test/unittest/core/pattern/waterflow/water_flow_scroller_test_ng.cpp @@ -88,44 +88,44 @@ HWTEST_F(WaterFlowScrollerTestNg, UpdateCurrentOffset002, TestSize.Level1) model.SetEdgeEffect(EdgeEffect::SPRING, false); CreateItem(TOTAL_LINE_NUMBER * 2); }); - EXPECT_EQ(pattern_->layoutInfo_.startIndex_, 0); - EXPECT_EQ(pattern_->layoutInfo_.endIndex_, 10); - EXPECT_TRUE(pattern_->layoutInfo_.itemStart_); - EXPECT_FALSE(pattern_->layoutInfo_.itemEnd_); - EXPECT_FALSE(pattern_->layoutInfo_.offsetEnd_); + EXPECT_EQ(pattern_->layoutInfo_->startIndex_, 0); + EXPECT_EQ(pattern_->layoutInfo_->endIndex_, 10); + EXPECT_TRUE(pattern_->layoutInfo_->itemStart_); + EXPECT_FALSE(pattern_->layoutInfo_->itemEnd_); + EXPECT_FALSE(pattern_->layoutInfo_->offsetEnd_); /** * @tc.steps: step2. Scroll down * @tc.expected: startIndex_ = 1 endIndex_ = 13. */ UpdateCurrentOffset(-2 * ITEM_HEIGHT); - EXPECT_EQ(pattern_->layoutInfo_.startIndex_, 1); - EXPECT_EQ(pattern_->layoutInfo_.endIndex_, 13); - EXPECT_FALSE(pattern_->layoutInfo_.itemStart_); - EXPECT_FALSE(pattern_->layoutInfo_.itemEnd_); - EXPECT_FALSE(pattern_->layoutInfo_.offsetEnd_); + EXPECT_EQ(pattern_->layoutInfo_->startIndex_, 1); + EXPECT_EQ(pattern_->layoutInfo_->endIndex_, 13); + EXPECT_FALSE(pattern_->layoutInfo_->itemStart_); + EXPECT_FALSE(pattern_->layoutInfo_->itemEnd_); + EXPECT_FALSE(pattern_->layoutInfo_->offsetEnd_); /** * @tc.steps: step3. scroll down * @tc.expected: startIndex_ = 11 endIndex_ = 19. */ UpdateCurrentOffset(-10000.f); - EXPECT_EQ(pattern_->layoutInfo_.startIndex_, 11); - EXPECT_EQ(pattern_->layoutInfo_.endIndex_, 19); - EXPECT_FALSE(pattern_->layoutInfo_.itemStart_); - EXPECT_TRUE(pattern_->layoutInfo_.itemEnd_); - EXPECT_TRUE(pattern_->layoutInfo_.offsetEnd_); + EXPECT_EQ(pattern_->layoutInfo_->startIndex_, 11); + EXPECT_EQ(pattern_->layoutInfo_->endIndex_, 19); + EXPECT_FALSE(pattern_->layoutInfo_->itemStart_); + EXPECT_TRUE(pattern_->layoutInfo_->itemEnd_); + EXPECT_TRUE(pattern_->layoutInfo_->offsetEnd_); /** * @tc.steps: step4. scroll up * @tc.expected: startIndex_ = 7 endIndex_ = 19. */ UpdateCurrentOffset(2 * ITEM_HEIGHT); - EXPECT_EQ(pattern_->layoutInfo_.startIndex_, 7); - EXPECT_EQ(pattern_->layoutInfo_.endIndex_, 19); - EXPECT_FALSE(pattern_->layoutInfo_.itemStart_); - EXPECT_TRUE(pattern_->layoutInfo_.itemEnd_); - EXPECT_FALSE(pattern_->layoutInfo_.offsetEnd_); + EXPECT_EQ(pattern_->layoutInfo_->startIndex_, 7); + EXPECT_EQ(pattern_->layoutInfo_->endIndex_, 19); + EXPECT_FALSE(pattern_->layoutInfo_->itemStart_); + EXPECT_TRUE(pattern_->layoutInfo_->itemEnd_); + EXPECT_FALSE(pattern_->layoutInfo_->offsetEnd_); } /** @@ -148,8 +148,8 @@ HWTEST_F(WaterFlowScrollerTestNg, UpdateCurrentOffset003, TestSize.Level1) pattern_->SetAnimateCanOverScroll(true); pattern_->UpdateCurrentOffset(10000, SCROLL_FROM_UPDATE); FlushLayoutTask(frameNode_); - EXPECT_EQ(pattern_->layoutInfo_.firstIndex_, 0); - EXPECT_EQ(pattern_->layoutInfo_.endIndex_, 0); + EXPECT_EQ(pattern_->layoutInfo_->FirstIdx(), 0); + EXPECT_EQ(pattern_->layoutInfo_->endIndex_, 0); /** * @tc.steps: step1. create waterFlow @@ -159,8 +159,8 @@ HWTEST_F(WaterFlowScrollerTestNg, UpdateCurrentOffset003, TestSize.Level1) pattern_->SetAnimateCanOverScroll(true); pattern_->UpdateCurrentOffset(-99999, SCROLL_FROM_UPDATE); FlushLayoutTask(frameNode_); - EXPECT_EQ(pattern_->layoutInfo_.firstIndex_, 19); - EXPECT_EQ(pattern_->layoutInfo_.endIndex_, 19); + EXPECT_EQ(pattern_->layoutInfo_->FirstIdx(), 19); + EXPECT_EQ(pattern_->layoutInfo_->endIndex_, 19); } /** @@ -192,9 +192,9 @@ HWTEST_F(WaterFlowScrollerTestNg, PositionController001, TestSize.Level1) * @tc.steps: step2. Test JumpTo func. */ controller->JumpTo(2, false, ScrollAlign::START, 0); - EXPECT_EQ(pattern_->layoutInfo_.jumpIndex_, 2); + EXPECT_EQ(pattern_->layoutInfo_->jumpIndex_, 2); controller->JumpTo(0, false, ScrollAlign::START, 0); - EXPECT_EQ(pattern_->layoutInfo_.jumpIndex_, 0); + EXPECT_EQ(pattern_->layoutInfo_->jumpIndex_, 0); } /** @@ -483,51 +483,51 @@ HWTEST_F(WaterFlowScrollerTestNg, ScrollToIndex002, TestSize.Level1) pattern_->ScrollToIndex(3, false, ScrollAlign::AUTO); FlushLayoutTask(frameNode_); - EXPECT_EQ(pattern_->layoutInfo_.startIndex_, 0); - EXPECT_EQ(pattern_->layoutInfo_.storedOffset_, 0); - EXPECT_EQ(pattern_->layoutInfo_.currentOffset_, 0); + EXPECT_EQ(pattern_->layoutInfo_->startIndex_, 0); + EXPECT_EQ(pattern_->layoutInfo_->storedOffset_, 0); + EXPECT_EQ(pattern_->layoutInfo_->Offset(), 0); pattern_->ScrollToIndex(15, false, ScrollAlign::START); FlushLayoutTask(frameNode_); - EXPECT_EQ(pattern_->layoutInfo_.startIndex_, 15); - EXPECT_EQ(pattern_->layoutInfo_.storedOffset_, 0); - EXPECT_EQ(pattern_->layoutInfo_.currentOffset_, -1100); + EXPECT_EQ(pattern_->layoutInfo_->startIndex_, 15); + EXPECT_EQ(pattern_->layoutInfo_->storedOffset_, 0); + EXPECT_EQ(pattern_->layoutInfo_->Offset(), -1100); pattern_->ScrollToIndex(LAST_ITEM); FlushLayoutTask(frameNode_); - EXPECT_EQ(pattern_->layoutInfo_.startIndex_, 19); - EXPECT_EQ(pattern_->layoutInfo_.storedOffset_, -100); - EXPECT_EQ(pattern_->layoutInfo_.currentOffset_, -1500); + EXPECT_EQ(pattern_->layoutInfo_->startIndex_, 19); + EXPECT_EQ(pattern_->layoutInfo_->storedOffset_, -100); + EXPECT_EQ(pattern_->layoutInfo_->Offset(), -1500); pattern_->ScrollToIndex(0, false, ScrollAlign::START); FlushLayoutTask(frameNode_); - EXPECT_EQ(pattern_->layoutInfo_.startIndex_, 0); - EXPECT_EQ(pattern_->layoutInfo_.storedOffset_, 0); - EXPECT_EQ(pattern_->layoutInfo_.currentOffset_, 0); + EXPECT_EQ(pattern_->layoutInfo_->startIndex_, 0); + EXPECT_EQ(pattern_->layoutInfo_->storedOffset_, 0); + EXPECT_EQ(pattern_->layoutInfo_->Offset(), 0); pattern_->ScrollToIndex(15, false, ScrollAlign::AUTO); FlushLayoutTask(frameNode_); - EXPECT_EQ(pattern_->layoutInfo_.startIndex_, 7); - EXPECT_EQ(pattern_->layoutInfo_.storedOffset_, 0); - EXPECT_EQ(pattern_->layoutInfo_.currentOffset_, -500); + EXPECT_EQ(pattern_->layoutInfo_->startIndex_, 7); + EXPECT_EQ(pattern_->layoutInfo_->storedOffset_, 0); + EXPECT_EQ(pattern_->layoutInfo_->Offset(), -500); pattern_->ScrollToIndex(7, false, ScrollAlign::CENTER); FlushLayoutTask(frameNode_); - EXPECT_EQ(pattern_->layoutInfo_.startIndex_, 3); - EXPECT_EQ(pattern_->layoutInfo_.storedOffset_, 0); - EXPECT_EQ(pattern_->layoutInfo_.currentOffset_, -200); + EXPECT_EQ(pattern_->layoutInfo_->startIndex_, 3); + EXPECT_EQ(pattern_->layoutInfo_->storedOffset_, 0); + EXPECT_EQ(pattern_->layoutInfo_->Offset(), -200); pattern_->ScrollToIndex(14, false, ScrollAlign::END); FlushLayoutTask(frameNode_); - EXPECT_EQ(pattern_->layoutInfo_.startIndex_, 3); - EXPECT_EQ(pattern_->layoutInfo_.storedOffset_, -100); - EXPECT_EQ(pattern_->layoutInfo_.currentOffset_, -300); + EXPECT_EQ(pattern_->layoutInfo_->startIndex_, 3); + EXPECT_EQ(pattern_->layoutInfo_->storedOffset_, -100); + EXPECT_EQ(pattern_->layoutInfo_->Offset(), -300); pattern_->ScrollToIndex(2, false, ScrollAlign::AUTO); FlushLayoutTask(frameNode_); - EXPECT_EQ(pattern_->layoutInfo_.startIndex_, 1); - EXPECT_EQ(pattern_->layoutInfo_.storedOffset_, -100); - EXPECT_EQ(pattern_->layoutInfo_.currentOffset_, -100); + EXPECT_EQ(pattern_->layoutInfo_->startIndex_, 1); + EXPECT_EQ(pattern_->layoutInfo_->storedOffset_, -100); + EXPECT_EQ(pattern_->layoutInfo_->Offset(), -100); } /** @@ -564,7 +564,7 @@ HWTEST_F(WaterFlowScrollerTestNg, ScrollToIndex003, TestSize.Level1) pattern_->ScrollPage(false); FlushLayoutTask(frameNode_); - EXPECT_LT(pattern_->layoutInfo_.currentOffset_, 0.f); + EXPECT_LT(pattern_->layoutInfo_->Offset(), 0.f); pattern_->ScrollToIndex(3, true, ScrollAlign::AUTO); FlushLayoutTask(frameNode_); diff --git a/test/unittest/core/pattern/waterflow/water_flow_segment_layout_test.cpp b/test/unittest/core/pattern/waterflow/water_flow_segment_layout_test.cpp index dede61128a7818a37349b3aa2232932fe72c3134..b5aa38546692b010387ecbae06eb80f48cdfa1b4 100644 --- a/test/unittest/core/pattern/waterflow/water_flow_segment_layout_test.cpp +++ b/test/unittest/core/pattern/waterflow/water_flow_segment_layout_test.cpp @@ -121,27 +121,27 @@ HWTEST_F(WaterFlowSegmentTest, Fill001, TestSize.Level1) }, false); - auto algo = AceType::MakeRefPtr(WaterFlowLayoutInfo {}); + auto algo = AceType::MakeRefPtr(AceType::MakeRefPtr()); algo->wrapper_ = AceType::RawPtr(frameNode_); algo->mainSize_ = 2000.0f; algo->itemsCrossSize_ = { { 50.0f, 50.0f, 50.0f, 50.0f }, {}, { 70.0f, 70.0f, 70.0f } }; algo->mainGaps_ = { 5.0f, 0.0f, 1.0f }; auto& info = algo->info_; - info.margins_ = { {}, {}, PaddingPropertyF { .top = 5.0f } }; - info.childrenCount_ = 10; + info->margins_ = { {}, {}, PaddingPropertyF { .top = 5.0f } }; + info->childrenCount_ = 10; - info.items_.resize(3); + info->items_.resize(3); for (int i = 0; i < 3; ++i) { - info.items_[0][i] = {}; - info.items_[2][i] = {}; + info->items_[0][i] = {}; + info->items_[2][i] = {}; } - info.items_[0][3] = {}; + info->items_[0][3] = {}; - info.segmentTails_ = SEGMENT_TAILS_1; + info->segmentTails_ = SEGMENT_TAILS_1; algo->Fill(0); - EXPECT_EQ(info.items_, ITEM_MAP_1); + EXPECT_EQ(info->items_, ITEM_MAP_1); } /** @@ -167,42 +167,42 @@ HWTEST_F(WaterFlowSegmentTest, MeasureOnOffset001, TestSize.Level1) layoutProperty_->layoutConstraint_ = constraint; layoutProperty_->contentConstraint_ = constraint; - auto algo = AceType::MakeRefPtr(WaterFlowLayoutInfo {}); + auto algo = AceType::MakeRefPtr(AceType::MakeRefPtr()); auto& info = algo->info_; - info.footerIndex_ = 0; + info->footerIndex_ = 0; for (int i = 0; i < 2; ++i) { algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.childrenCount_, 11); - EXPECT_EQ(info.items_, ITEM_MAP_2); - EXPECT_EQ(info.itemInfos_, ITEM_INFO_2); - EXPECT_EQ(info.segmentTails_, SEGMENT_TAILS_2); - EXPECT_EQ(info.endPosArray_, END_POS_ARRAY_2); - EXPECT_EQ(info.segmentStartPos_, SEGMENT_START_POS_2); + EXPECT_EQ(info->childrenCount_, 11); + EXPECT_EQ(info->items_, ITEM_MAP_2); + EXPECT_EQ(info->itemInfos_, ITEM_INFO_2); + EXPECT_EQ(info->segmentTails_, SEGMENT_TAILS_2); + EXPECT_EQ(info->endPosArray_, END_POS_ARRAY_2); + EXPECT_EQ(info->segmentStartPos_, SEGMENT_START_POS_2); } - info.prevOffset_ = 0.0f; - info.currentOffset_ = -100.0f; + info->prevOffset_ = 0.0f; + info->currentOffset_ = -100.0f; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.currentOffset_, 0.0f); - EXPECT_EQ(info.startIndex_, 0); - EXPECT_EQ(info.endIndex_, 10); + EXPECT_EQ(info->currentOffset_, 0.0f); + EXPECT_EQ(info->startIndex_, 0); + EXPECT_EQ(info->endIndex_, 10); algo->overScroll_ = true; - info.prevOffset_ = 0.0f; - info.currentOffset_ = -200.0f; + info->prevOffset_ = 0.0f; + info->currentOffset_ = -200.0f; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.currentOffset_, -200.0f); - EXPECT_EQ(info.startIndex_, 4); - EXPECT_EQ(info.endIndex_, 10); + EXPECT_EQ(info->currentOffset_, -200.0f); + EXPECT_EQ(info->startIndex_, 4); + EXPECT_EQ(info->endIndex_, 10); - info.Reset(); + info->Reset(); algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.currentOffset_, -200.0f); - EXPECT_EQ(info.startIndex_, 4); - EXPECT_EQ(info.endIndex_, 10); + EXPECT_EQ(info->currentOffset_, -200.0f); + EXPECT_EQ(info->startIndex_, 4); + EXPECT_EQ(info->endIndex_, 10); } /** @@ -221,9 +221,9 @@ HWTEST_F(WaterFlowSegmentTest, MeasureFooter001, TestSize.Level1) ViewStackProcessor::GetInstance()->Pop(); }); - auto& info = pattern_->layoutInfo_; - EXPECT_EQ(info.childrenCount_, 11); - EXPECT_EQ(info.footerIndex_, 10); + auto info = AceType::DynamicCast(pattern_->layoutInfo_); + EXPECT_EQ(info->childrenCount_, 11); + EXPECT_EQ(info->footerIndex_, 10); auto footer = WaterFlowItemNode::GetOrCreateFlowItem( V2::FLOW_ITEM_ETS_TAG, -1, []() { return AceType::MakeRefPtr(); }); footer->GetLayoutProperty()->UpdateUserDefinedIdealSize( @@ -236,17 +236,17 @@ HWTEST_F(WaterFlowSegmentTest, MeasureFooter001, TestSize.Level1) pattern_->MarkDirtyNodeSelf(); FlushLayoutTask(frameNode_); - EXPECT_EQ(GetChildFrameNode(frameNode_, info.footerIndex_), footer); + EXPECT_EQ(GetChildFrameNode(frameNode_, info->footerIndex_), footer); UpdateCurrentOffset(-1000.0f); - EXPECT_EQ(info.items_.size(), 2); - EXPECT_EQ(info.items_[1][0].size(), 1); - EXPECT_EQ(info.childrenCount_, 13); - EXPECT_EQ(info.endIndex_, 12); - EXPECT_EQ(info.segmentTails_[0], 11); - EXPECT_EQ(info.segmentTails_[1], 12); - EXPECT_EQ(info.footerIndex_, 12); - EXPECT_EQ(info.itemInfos_[12].mainOffset, 503.0f); - EXPECT_EQ(info.itemInfos_[12].mainSize, 200.0f); + EXPECT_EQ(info->items_.size(), 2); + EXPECT_EQ(info->items_[1][0].size(), 1); + EXPECT_EQ(info->childrenCount_, 13); + EXPECT_EQ(info->endIndex_, 12); + EXPECT_EQ(info->segmentTails_[0], 11); + EXPECT_EQ(info->segmentTails_[1], 12); + EXPECT_EQ(info->footerIndex_, 12); + EXPECT_EQ(info->itemInfos_[12].mainOffset, 503.0f); + EXPECT_EQ(info->itemInfos_[12].mainSize, 200.0f); } /** @@ -265,10 +265,10 @@ HWTEST_F(WaterFlowSegmentTest, MeasureFooter002, TestSize.Level1) ViewStackProcessor::GetInstance()->Pop(); }); - auto& info = pattern_->layoutInfo_; - EXPECT_EQ(info.childrenCount_, 11); - EXPECT_EQ(info.footerIndex_, 10); - EXPECT_EQ(info.itemInfos_[8].mainOffset, 202.0f); + auto info = AceType::DynamicCast(pattern_->layoutInfo_); + EXPECT_EQ(info->childrenCount_, 11); + EXPECT_EQ(info->footerIndex_, 10); + EXPECT_EQ(info->itemInfos_[8].mainOffset, 202.0f); auto footer = WaterFlowItemNode::GetOrCreateFlowItem( V2::FLOW_ITEM_ETS_TAG, -1, []() { return AceType::MakeRefPtr(); }); @@ -283,18 +283,18 @@ HWTEST_F(WaterFlowSegmentTest, MeasureFooter002, TestSize.Level1) pattern_->MarkDirtyNodeSelf(); FlushLayoutTask(frameNode_); - EXPECT_EQ(GetChildFrameNode(frameNode_, info.footerIndex_), footer); + EXPECT_EQ(GetChildFrameNode(frameNode_, info->footerIndex_), footer); UpdateCurrentOffset(-1000.0f); - EXPECT_EQ(info.items_.size(), 2); - EXPECT_EQ(info.items_[1][0].size(), 1); - EXPECT_EQ(info.segmentStartPos_[1], 401.0f); - EXPECT_EQ(info.childrenCount_, 9); - EXPECT_EQ(info.endIndex_, 8); - EXPECT_EQ(info.segmentTails_[0], 7); - EXPECT_EQ(info.segmentTails_[1], 8); - EXPECT_EQ(info.footerIndex_, 8); - EXPECT_EQ(info.itemInfos_[8].mainOffset, 401.0f); - EXPECT_EQ(info.itemInfos_[8].mainSize, 200.0f); + EXPECT_EQ(info->items_.size(), 2); + EXPECT_EQ(info->items_[1][0].size(), 1); + EXPECT_EQ(info->segmentStartPos_[1], 401.0f); + EXPECT_EQ(info->childrenCount_, 9); + EXPECT_EQ(info->endIndex_, 8); + EXPECT_EQ(info->segmentTails_[0], 7); + EXPECT_EQ(info->segmentTails_[1], 8); + EXPECT_EQ(info->footerIndex_, 8); + EXPECT_EQ(info->itemInfos_[8].mainOffset, 401.0f); + EXPECT_EQ(info->itemInfos_[8].mainSize, 200.0f); } /** @@ -306,10 +306,10 @@ HWTEST_F(WaterFlowSegmentTest, Layout001, TestSize.Level1) { SetUpConfig1(); - auto algo = AceType::MakeRefPtr(WaterFlowLayoutInfo {}); + auto algo = AceType::MakeRefPtr(AceType::MakeRefPtr()); auto& info = algo->info_; - info.footerIndex_ = 0; + info->footerIndex_ = 0; algo->Measure(AceType::RawPtr(frameNode_)); const std::vector> crossSize = { { 116.25f, 116.25f, 116.25f, 116.25f }, { 480.0f } }; @@ -337,18 +337,18 @@ HWTEST_F(WaterFlowSegmentTest, Layout002, TestSize.Level1) { SetUpConfig1(); - auto algo = AceType::MakeRefPtr(WaterFlowLayoutInfo {}); + auto algo = AceType::MakeRefPtr(AceType::MakeRefPtr()); auto& info = algo->info_; - info.footerIndex_ = 0; + info->footerIndex_ = 0; - info.prevOffset_ = 0.0f; - info.currentOffset_ = -100.0f; + info->prevOffset_ = 0.0f; + info->currentOffset_ = -100.0f; algo->overScroll_ = true; algo->Measure(AceType::RawPtr(frameNode_)); algo->Layout(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 1); - EXPECT_EQ(info.endIndex_, 10); + EXPECT_EQ(info->startIndex_, 1); + EXPECT_EQ(info->endIndex_, 10); EXPECT_EQ(GetChildOffset(frameNode_, 1), OffsetF(121.25f, -100.0f)); EXPECT_EQ(GetChildOffset(frameNode_, 2), OffsetF(242.5f, -100.0f)); EXPECT_EQ(GetChildOffset(frameNode_, 3), OffsetF(363.75f, -100.0f)); @@ -370,55 +370,55 @@ HWTEST_F(WaterFlowSegmentTest, MeasureOnOffset002, TestSize.Level1) { SetUpConfig2(); - auto algo = AceType::MakeRefPtr(WaterFlowLayoutInfo {}); + auto algo = AceType::MakeRefPtr(AceType::MakeRefPtr()); auto& info = algo->info_; - info.footerIndex_ = 0; + info->footerIndex_ = 0; for (int i = 0; i < 2; ++i) { algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.childrenCount_, 101); - EXPECT_EQ(info.items_.size(), 2); - EXPECT_EQ(info.startIndex_, 0); - EXPECT_EQ(info.endIndex_, 27); - EXPECT_EQ(info.segmentTails_, SEGMENT_TAILS_3); + EXPECT_EQ(info->childrenCount_, 101); + EXPECT_EQ(info->items_.size(), 2); + EXPECT_EQ(info->startIndex_, 0); + EXPECT_EQ(info->endIndex_, 27); + EXPECT_EQ(info->segmentTails_, SEGMENT_TAILS_3); } - info.prevOffset_ = 0.0f; - info.currentOffset_ = -100.0f; + info->prevOffset_ = 0.0f; + info->currentOffset_ = -100.0f; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.currentOffset_, -100.0f); - EXPECT_EQ(info.startIndex_, 1); - EXPECT_EQ(info.endIndex_, 30); + EXPECT_EQ(info->currentOffset_, -100.0f); + EXPECT_EQ(info->startIndex_, 1); + EXPECT_EQ(info->endIndex_, 30); - info.prevOffset_ = -100.0f; - info.currentOffset_ = -500.0f; + info->prevOffset_ = -100.0f; + info->currentOffset_ = -500.0f; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.currentOffset_, -500.0f); - EXPECT_EQ(info.startIndex_, 11); - EXPECT_EQ(info.endIndex_, 44); + EXPECT_EQ(info->currentOffset_, -500.0f); + EXPECT_EQ(info->startIndex_, 11); + EXPECT_EQ(info->endIndex_, 44); - const auto itemMap = info.items_; - const auto itemInfo = info.itemInfos_; - const auto endPosArr = info.endPosArray_; + const auto itemMap = info->items_; + const auto itemInfo = info->itemInfos_; + const auto endPosArr = info->endPosArray_; - info.prevOffset_ = -500.0f; - info.currentOffset_ = -300.0f; + info->prevOffset_ = -500.0f; + info->currentOffset_ = -300.0f; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.items_, itemMap); - EXPECT_EQ(info.itemInfos_, itemInfo); - EXPECT_EQ(info.endPosArray_, endPosArr); - EXPECT_EQ(info.startIndex_, 5); - EXPECT_EQ(info.endIndex_, 37); - EXPECT_EQ(info.segmentStartPos_, std::vector { 0.0f }); + EXPECT_EQ(info->items_, itemMap); + EXPECT_EQ(info->itemInfos_, itemInfo); + EXPECT_EQ(info->endPosArray_, endPosArr); + EXPECT_EQ(info->startIndex_, 5); + EXPECT_EQ(info->endIndex_, 37); + EXPECT_EQ(info->segmentStartPos_, std::vector { 0.0f }); - info.prevOffset_ = -300.0f; - info.currentOffset_ = -700.0f; + info->prevOffset_ = -300.0f; + info->currentOffset_ = -700.0f; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 19); - EXPECT_EQ(info.endIndex_, 50); - EXPECT_EQ(info.segmentStartPos_, std::vector { 0.0f }); + EXPECT_EQ(info->startIndex_, 19); + EXPECT_EQ(info->endIndex_, 50); + EXPECT_EQ(info->segmentStartPos_, std::vector { 0.0f }); } /** @@ -430,35 +430,35 @@ HWTEST_F(WaterFlowSegmentTest, MeasureOnJump001, TestSize.Level1) { SetUpConfig2(); - auto algo = AceType::MakeRefPtr(WaterFlowLayoutInfo {}); + auto algo = AceType::MakeRefPtr(AceType::MakeRefPtr()); auto& info = algo->info_; - info.footerIndex_ = 0; + info->footerIndex_ = 0; - info.align_ = ScrollAlign::END; - info.jumpIndex_ = 5; + info->align_ = ScrollAlign::END; + info->jumpIndex_ = 5; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 0); - EXPECT_EQ(info.endIndex_, 27); - EXPECT_EQ(info.currentOffset_, 0.0f); + EXPECT_EQ(info->startIndex_, 0); + EXPECT_EQ(info->endIndex_, 27); + EXPECT_EQ(info->currentOffset_, 0.0f); - info.jumpIndex_ = 99; + info->jumpIndex_ = 99; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 75); - EXPECT_EQ(info.endIndex_, 99); - EXPECT_EQ(info.currentOffset_, -2320.0f); + EXPECT_EQ(info->startIndex_, 75); + EXPECT_EQ(info->endIndex_, 99); + EXPECT_EQ(info->currentOffset_, -2320.0f); - info.jumpIndex_ = 100; + info->jumpIndex_ = 100; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 75); - EXPECT_EQ(info.endIndex_, 100); - EXPECT_EQ(info.currentOffset_, -2370.0f); + EXPECT_EQ(info->startIndex_, 75); + EXPECT_EQ(info->endIndex_, 100); + EXPECT_EQ(info->currentOffset_, -2370.0f); - info.jumpIndex_ = 105; + info->jumpIndex_ = 105; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 75); - EXPECT_EQ(info.endIndex_, 100); - EXPECT_EQ(info.currentOffset_, -2370.0f); + EXPECT_EQ(info->startIndex_, 75); + EXPECT_EQ(info->endIndex_, 100); + EXPECT_EQ(info->currentOffset_, -2370.0f); } /** @@ -470,47 +470,47 @@ HWTEST_F(WaterFlowSegmentTest, MeasureOnJump002, TestSize.Level1) { SetUpConfig2(); - auto algo = AceType::MakeRefPtr(WaterFlowLayoutInfo {}); + auto algo = AceType::MakeRefPtr(AceType::MakeRefPtr()); auto& info = algo->info_; - info.footerIndex_ = 0; + info->footerIndex_ = 0; - info.align_ = ScrollAlign::AUTO; - info.jumpIndex_ = 10; + info->align_ = ScrollAlign::AUTO; + info->jumpIndex_ = 10; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 0); - EXPECT_EQ(info.endIndex_, 27); - EXPECT_EQ(info.currentOffset_, 0.0f); - EXPECT_EQ(info.align_, ScrollAlign::NONE); + EXPECT_EQ(info->startIndex_, 0); + EXPECT_EQ(info->endIndex_, 27); + EXPECT_EQ(info->currentOffset_, 0.0f); + EXPECT_EQ(info->align_, ScrollAlign::NONE); - info.align_ = ScrollAlign::AUTO; - info.jumpIndex_ = 53; + info->align_ = ScrollAlign::AUTO; + info->jumpIndex_ = 53; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 29); - EXPECT_EQ(info.endIndex_, 58); - EXPECT_EQ(info.currentOffset_, -911.0f); - EXPECT_EQ(info.align_, ScrollAlign::END); + EXPECT_EQ(info->startIndex_, 29); + EXPECT_EQ(info->endIndex_, 58); + EXPECT_EQ(info->currentOffset_, -911.0f); + EXPECT_EQ(info->align_, ScrollAlign::END); - info.align_ = ScrollAlign::AUTO; - info.jumpIndex_ = 5; + info->align_ = ScrollAlign::AUTO; + info->jumpIndex_ = 5; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 1); - EXPECT_EQ(info.endIndex_, 30); - EXPECT_EQ(info.currentOffset_, -101.0f); - EXPECT_EQ(info.align_, ScrollAlign::START); + EXPECT_EQ(info->startIndex_, 1); + EXPECT_EQ(info->endIndex_, 30); + EXPECT_EQ(info->currentOffset_, -101.0f); + EXPECT_EQ(info->align_, ScrollAlign::START); - info.align_ = ScrollAlign::AUTO; - info.jumpIndex_ = 5; + info->align_ = ScrollAlign::AUTO; + info->jumpIndex_ = 5; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.align_, ScrollAlign::NONE); + EXPECT_EQ(info->align_, ScrollAlign::NONE); - info.align_ = ScrollAlign::AUTO; - info.jumpIndex_ = 7; + info->align_ = ScrollAlign::AUTO; + info->jumpIndex_ = 7; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 1); - EXPECT_EQ(info.endIndex_, 30); - EXPECT_EQ(info.currentOffset_, -101.0f); - EXPECT_EQ(info.align_, ScrollAlign::NONE); + EXPECT_EQ(info->startIndex_, 1); + EXPECT_EQ(info->endIndex_, 30); + EXPECT_EQ(info->currentOffset_, -101.0f); + EXPECT_EQ(info->align_, ScrollAlign::NONE); } /** @@ -522,36 +522,36 @@ HWTEST_F(WaterFlowSegmentTest, MeasureOnJump003, TestSize.Level1) { SetUpConfig2(); - auto algo = AceType::MakeRefPtr(WaterFlowLayoutInfo {}); + auto algo = AceType::MakeRefPtr(AceType::MakeRefPtr()); auto& info = algo->info_; - info.footerIndex_ = 0; + info->footerIndex_ = 0; - info.align_ = ScrollAlign::START; - info.jumpIndex_ = 10; + info->align_ = ScrollAlign::START; + info->jumpIndex_ = 10; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 5); - EXPECT_EQ(info.endIndex_, 34); - EXPECT_EQ(info.currentOffset_, -202.0f); + EXPECT_EQ(info->startIndex_, 5); + EXPECT_EQ(info->endIndex_, 34); + EXPECT_EQ(info->currentOffset_, -202.0f); - info.jumpIndex_ = 99; + info->jumpIndex_ = 99; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 75); - EXPECT_EQ(info.endIndex_, 100); - EXPECT_EQ(info.currentOffset_, -2370.0f); + EXPECT_EQ(info->startIndex_, 75); + EXPECT_EQ(info->endIndex_, 100); + EXPECT_EQ(info->currentOffset_, -2370.0f); - info.jumpIndex_ = 42; + info->jumpIndex_ = 42; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 37); - EXPECT_EQ(info.endIndex_, 67); - EXPECT_EQ(info.currentOffset_, -1207.0f); + EXPECT_EQ(info->startIndex_, 37); + EXPECT_EQ(info->endIndex_, 67); + EXPECT_EQ(info->currentOffset_, -1207.0f); // invalid - info.jumpIndex_ = 101; + info->jumpIndex_ = 101; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 37); - EXPECT_EQ(info.endIndex_, 67); - EXPECT_EQ(info.currentOffset_, -1207.0f); + EXPECT_EQ(info->startIndex_, 37); + EXPECT_EQ(info->endIndex_, 67); + EXPECT_EQ(info->currentOffset_, -1207.0f); } /** @@ -563,44 +563,44 @@ HWTEST_F(WaterFlowSegmentTest, MeasureOnJump004, TestSize.Level1) { SetUpConfig2(); - auto algo = AceType::MakeRefPtr(WaterFlowLayoutInfo {}); + auto algo = AceType::MakeRefPtr(AceType::MakeRefPtr()); auto& info = algo->info_; - info.footerIndex_ = 0; + info->footerIndex_ = 0; - info.align_ = ScrollAlign::CENTER; - info.jumpIndex_ = 10; + info->align_ = ScrollAlign::CENTER; + info->jumpIndex_ = 10; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 0); - EXPECT_EQ(info.endIndex_, 27); - EXPECT_EQ(info.currentOffset_, -0.0f); + EXPECT_EQ(info->startIndex_, 0); + EXPECT_EQ(info->endIndex_, 27); + EXPECT_EQ(info->currentOffset_, -0.0f); - info.jumpIndex_ = 99; + info->jumpIndex_ = 99; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 75); - EXPECT_EQ(info.endIndex_, 100); - EXPECT_EQ(info.currentOffset_, -2370.0f); - EXPECT_EQ(info.segmentStartPos_.size(), 2); + EXPECT_EQ(info->startIndex_, 75); + EXPECT_EQ(info->endIndex_, 100); + EXPECT_EQ(info->currentOffset_, -2370.0f); + EXPECT_EQ(info->segmentStartPos_.size(), 2); - info.jumpIndex_ = 42; + info->jumpIndex_ = 42; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 25); - EXPECT_EQ(info.endIndex_, 57); - EXPECT_EQ(info.currentOffset_, -857.0f); + EXPECT_EQ(info->startIndex_, 25); + EXPECT_EQ(info->endIndex_, 57); + EXPECT_EQ(info->currentOffset_, -857.0f); - info.jumpIndex_ = 0; + info->jumpIndex_ = 0; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 0); - EXPECT_EQ(info.endIndex_, 27); - EXPECT_EQ(info.currentOffset_, 0.0f); + EXPECT_EQ(info->startIndex_, 0); + EXPECT_EQ(info->endIndex_, 27); + EXPECT_EQ(info->currentOffset_, 0.0f); // invalid jumpIndex - info.jumpIndex_ = 500; + info->jumpIndex_ = 500; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 0); - EXPECT_EQ(info.endIndex_, 27); - EXPECT_EQ(info.currentOffset_, 0.0f); - EXPECT_EQ(info.jumpIndex_, EMPTY_JUMP_INDEX); + EXPECT_EQ(info->startIndex_, 0); + EXPECT_EQ(info->endIndex_, 27); + EXPECT_EQ(info->currentOffset_, 0.0f); + EXPECT_EQ(info->jumpIndex_, EMPTY_JUMP_INDEX); } /** @@ -612,27 +612,27 @@ HWTEST_F(WaterFlowSegmentTest, Reset001, TestSize.Level1) { SetUpConfig2(); - auto algo = AceType::MakeRefPtr(WaterFlowLayoutInfo {}); + auto algo = AceType::MakeRefPtr(AceType::MakeRefPtr()); auto& info = algo->info_; - info.footerIndex_ = 0; + info->footerIndex_ = 0; - info.align_ = ScrollAlign::CENTER; + info->align_ = ScrollAlign::CENTER; - info.jumpIndex_ = 99; + info->jumpIndex_ = 99; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 75); - EXPECT_EQ(info.endIndex_, 100); - EXPECT_EQ(info.currentOffset_, -2370.0f); - EXPECT_EQ(info.segmentStartPos_.size(), 2); + EXPECT_EQ(info->startIndex_, 75); + EXPECT_EQ(info->endIndex_, 100); + EXPECT_EQ(info->currentOffset_, -2370.0f); + EXPECT_EQ(info->segmentStartPos_.size(), 2); // change crossCount, should jump back to index 75 layoutProperty_->UpdateColumnsTemplate("1fr 1fr 1fr"); - info.Reset(); + info->Reset(); algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 45); - EXPECT_EQ(info.endIndex_, 64); - EXPECT_EQ(info.currentOffset_, -2370.0f); + EXPECT_EQ(info->startIndex_, 45); + EXPECT_EQ(info->endIndex_, 64); + EXPECT_EQ(info->currentOffset_, -2370.0f); EXPECT_EQ(algo->itemsCrossSize_[0].size(), 3); } @@ -645,55 +645,55 @@ HWTEST_F(WaterFlowSegmentTest, Reset002, TestSize.Level1) { SetUpConfig2(); - auto algo = AceType::MakeRefPtr(WaterFlowLayoutInfo {}); + auto algo = AceType::MakeRefPtr(AceType::MakeRefPtr()); auto& info = algo->info_; - info.footerIndex_ = 0; + info->footerIndex_ = 0; - info.align_ = ScrollAlign::CENTER; - info.jumpIndex_ = 99; + info->align_ = ScrollAlign::CENTER; + info->jumpIndex_ = 99; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 75); - EXPECT_EQ(info.endIndex_, 100); - EXPECT_EQ(info.currentOffset_, -2370.0f); - EXPECT_EQ(info.segmentStartPos_.size(), 2); + EXPECT_EQ(info->startIndex_, 75); + EXPECT_EQ(info->endIndex_, 100); + EXPECT_EQ(info->currentOffset_, -2370.0f); + EXPECT_EQ(info->segmentStartPos_.size(), 2); - info.Reset(); + info->Reset(); algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 75); - EXPECT_EQ(info.endIndex_, 100); - EXPECT_EQ(info.currentOffset_, -2370.0f); - EXPECT_EQ(info.segmentStartPos_.size(), 2); + EXPECT_EQ(info->startIndex_, 75); + EXPECT_EQ(info->endIndex_, 100); + EXPECT_EQ(info->currentOffset_, -2370.0f); + EXPECT_EQ(info->segmentStartPos_.size(), 2); - info.jumpIndex_ = 42; + info->jumpIndex_ = 42; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 25); - EXPECT_EQ(info.endIndex_, 57); - EXPECT_EQ(info.currentOffset_, -857.0f); + EXPECT_EQ(info->startIndex_, 25); + EXPECT_EQ(info->endIndex_, 57); + EXPECT_EQ(info->currentOffset_, -857.0f); // child requires fresh layout, should jump back to index 75 - layoutProperty_->propertyChangeFlag_ = PROPERTY_UPDATE_BY_CHILD_REQUEST; + layoutProperty_->UpdatePropertyChangeFlag(PROPERTY_UPDATE_BY_CHILD_REQUEST); frameNode_->ChildrenUpdatedFrom(0); algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 25); - EXPECT_EQ(info.endIndex_, 57); - EXPECT_EQ(info.currentOffset_, -857.0f); - EXPECT_EQ(info.align_, ScrollAlign::START); + EXPECT_EQ(info->startIndex_, 25); + EXPECT_EQ(info->endIndex_, 57); + EXPECT_EQ(info->currentOffset_, -857.0f); + EXPECT_EQ(info->align_, ScrollAlign::START); // items should be cleared before jumping - EXPECT_EQ(info.items_[1][0].size(), 0); - EXPECT_EQ(info.segmentStartPos_.size(), 1); - EXPECT_EQ(info.itemInfos_.size(), 58); + EXPECT_EQ(info->items_[1][0].size(), 0); + EXPECT_EQ(info->segmentStartPos_.size(), 1); + EXPECT_EQ(info->itemInfos_.size(), 58); - info.Reset(); - layoutProperty_->propertyChangeFlag_ = PROPERTY_UPDATE_BY_CHILD_REQUEST; + info->Reset(); + layoutProperty_->UpdatePropertyChangeFlag(PROPERTY_UPDATE_BY_CHILD_REQUEST); algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 25); - EXPECT_EQ(info.endIndex_, 57); - EXPECT_EQ(info.currentOffset_, -857.0f); + EXPECT_EQ(info->startIndex_, 25); + EXPECT_EQ(info->endIndex_, 57); + EXPECT_EQ(info->currentOffset_, -857.0f); // items should be cleared before jumping - EXPECT_EQ(info.items_[1][0].size(), 0); - EXPECT_EQ(info.segmentStartPos_.size(), 1); - EXPECT_EQ(info.itemInfos_.size(), 58); + EXPECT_EQ(info->items_[1][0].size(), 0); + EXPECT_EQ(info->segmentStartPos_.size(), 1); + EXPECT_EQ(info->itemInfos_.size(), 58); } /** @@ -705,47 +705,47 @@ HWTEST_F(WaterFlowSegmentTest, Reset003, TestSize.Level1) { SetUpConfig2(); - auto algo = AceType::MakeRefPtr(WaterFlowLayoutInfo {}); + auto algo = AceType::MakeRefPtr(AceType::MakeRefPtr()); auto& info = algo->info_; - info.footerIndex_ = 0; + info->footerIndex_ = 0; - info.align_ = ScrollAlign::CENTER; - info.jumpIndex_ = 99; + info->align_ = ScrollAlign::CENTER; + info->jumpIndex_ = 99; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 75); - EXPECT_EQ(info.endIndex_, 100); - EXPECT_EQ(info.currentOffset_, -2370.0f); - EXPECT_EQ(info.segmentStartPos_.size(), 2); - EXPECT_EQ(info.itemInfos_.size(), 101); + EXPECT_EQ(info->startIndex_, 75); + EXPECT_EQ(info->endIndex_, 100); + EXPECT_EQ(info->currentOffset_, -2370.0f); + EXPECT_EQ(info->segmentStartPos_.size(), 2); + EXPECT_EQ(info->itemInfos_.size(), 101); - info.jumpIndex_ = 42; + info->jumpIndex_ = 42; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 25); - EXPECT_EQ(info.endIndex_, 57); - EXPECT_EQ(info.currentOffset_, -857.0f); + EXPECT_EQ(info->startIndex_, 25); + EXPECT_EQ(info->endIndex_, 57); + EXPECT_EQ(info->currentOffset_, -857.0f); // index 70 doesn't affect the current layout frameNode_->ChildrenUpdatedFrom(70); algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 25); - EXPECT_EQ(info.endIndex_, 57); - EXPECT_EQ(info.currentOffset_, -857.0f); - EXPECT_EQ(info.align_, ScrollAlign::CENTER); + EXPECT_EQ(info->startIndex_, 25); + EXPECT_EQ(info->endIndex_, 57); + EXPECT_EQ(info->currentOffset_, -857.0f); + EXPECT_EQ(info->align_, ScrollAlign::CENTER); // items starting from 70 are cleared - EXPECT_EQ(info.items_[1][0].size(), 0); - EXPECT_EQ(info.segmentStartPos_.size(), 1); - EXPECT_EQ(info.itemInfos_.size(), 70); + EXPECT_EQ(info->items_[1][0].size(), 0); + EXPECT_EQ(info->segmentStartPos_.size(), 1); + EXPECT_EQ(info->itemInfos_.size(), 70); // index 20 would reset all and trigger jump frameNode_->ChildrenUpdatedFrom(20); algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 25); - EXPECT_EQ(info.endIndex_, 57); - EXPECT_EQ(info.currentOffset_, -857.0f); - EXPECT_EQ(info.align_, ScrollAlign::START); + EXPECT_EQ(info->startIndex_, 25); + EXPECT_EQ(info->endIndex_, 57); + EXPECT_EQ(info->currentOffset_, -857.0f); + EXPECT_EQ(info->align_, ScrollAlign::START); // items should be cleared before jumping - EXPECT_EQ(info.itemInfos_.size(), 58); + EXPECT_EQ(info->itemInfos_.size(), 58); } /** @@ -765,11 +765,11 @@ HWTEST_F(WaterFlowSegmentTest, Reset004, TestSize.Level1) }); UpdateCurrentOffset(-2000.0f); - auto& info = pattern_->layoutInfo_; - EXPECT_EQ(info.footerIndex_, 200); - EXPECT_EQ(info.endIndex_, 75); - EXPECT_EQ(info.startIndex_, 49); - EXPECT_EQ(info.itemInfos_[info.startIndex_].mainOffset + info.currentOffset_, -188.0f); + auto info = AceType::DynamicCast(pattern_->layoutInfo_); + EXPECT_EQ(info->footerIndex_, 200); + EXPECT_EQ(info->endIndex_, 75); + EXPECT_EQ(info->startIndex_, 49); + EXPECT_EQ(info->itemInfos_[info->startIndex_].mainOffset + info->currentOffset_, -188.0f); auto footer = WaterFlowItemNode::GetOrCreateFlowItem( V2::FLOW_ITEM_ETS_TAG, -1, []() { return AceType::MakeRefPtr(); }); footer->GetLayoutProperty()->UpdateUserDefinedIdealSize( @@ -782,9 +782,9 @@ HWTEST_F(WaterFlowSegmentTest, Reset004, TestSize.Level1) layoutProperty_->UpdateColumnsTemplate("1fr 1fr"); FlushLayoutTask(frameNode_); - EXPECT_EQ(GetChildFrameNode(frameNode_, info.footerIndex_), footer); - EXPECT_EQ(info.startIndex_, 25); - EXPECT_EQ(info.currentOffset_, -2000.0f); + EXPECT_EQ(GetChildFrameNode(frameNode_, info->footerIndex_), footer); + EXPECT_EQ(info->startIndex_, 25); + EXPECT_EQ(info->currentOffset_, -2000.0f); EXPECT_EQ(GetChildWidth(frameNode_, 25), 237.5f); } @@ -803,17 +803,17 @@ HWTEST_F(WaterFlowSegmentTest, Reset005, TestSize.Level1) CreateItem(200); ViewStackProcessor::GetInstance()->Pop(); }); - auto& info = pattern_->layoutInfo_; - EXPECT_EQ(info.startIndex_, 0); - EXPECT_EQ(info.endIndex_, 21); + auto info = AceType::DynamicCast(pattern_->layoutInfo_); + EXPECT_EQ(info->startIndex_, 0); + EXPECT_EQ(info->endIndex_, 21); for (int i = 0; i <= 21; ++i) { EXPECT_EQ(GetChildWidth(frameNode_, i), 116.25f); } layoutProperty_->UpdateColumnsGap(Dimension(1.0f)); FlushLayoutTask(frameNode_); - EXPECT_EQ(info.startIndex_, 0); - EXPECT_EQ(info.endIndex_, 21); + EXPECT_EQ(info->startIndex_, 0); + EXPECT_EQ(info->endIndex_, 21); for (int i = 0; i <= 21; ++i) { EXPECT_EQ(GetChildWidth(frameNode_, i), 119.25f); } @@ -840,32 +840,33 @@ HWTEST_F(WaterFlowSegmentTest, Segmented001, TestSize.Level1) layoutProperty_->layoutConstraint_ = constraint; layoutProperty_->contentConstraint_ = constraint; - auto algo = AceType::MakeRefPtr(pattern_->layoutInfo_); + auto algo = + AceType::MakeRefPtr(AceType::DynamicCast(pattern_->layoutInfo_)); auto& info = algo->info_; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.endIndex_, 12); - EXPECT_EQ(info.margins_.size(), 3); - EXPECT_EQ(info.segmentTails_, SEGMENT_TAILS_4); - EXPECT_EQ(info.currentOffset_, 0.0f); + EXPECT_EQ(info->endIndex_, 12); + EXPECT_EQ(info->margins_.size(), 3); + EXPECT_EQ(info->segmentTails_, SEGMENT_TAILS_4); + EXPECT_EQ(info->currentOffset_, 0.0f); const std::vector crossGaps = { 0.0f, 0.0f, 0.0f }; EXPECT_EQ(algo->mainGaps_.size(), 3); - info.currentOffset_ = -200.0f; + info->currentOffset_ = -200.0f; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 3); - EXPECT_EQ(info.endIndex_, 16); - EXPECT_EQ(info.currentOffset_, -200.0f); - EXPECT_EQ(info.segmentStartPos_.size(), 1); + EXPECT_EQ(info->startIndex_, 3); + EXPECT_EQ(info->endIndex_, 16); + EXPECT_EQ(info->currentOffset_, -200.0f); + EXPECT_EQ(info->segmentStartPos_.size(), 1); - info.prevOffset_ = -200.0f; - info.currentOffset_ = -4050.0f; + info->prevOffset_ = -200.0f; + info->currentOffset_ = -4050.0f; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 47); - EXPECT_EQ(info.endIndex_, 51); - EXPECT_EQ(info.segmentStartPos_.size(), 3); - EXPECT_EQ(info.endPosArray_.size(), 37); + EXPECT_EQ(info->startIndex_, 47); + EXPECT_EQ(info->endIndex_, 51); + EXPECT_EQ(info->segmentStartPos_.size(), 3); + EXPECT_EQ(info->endPosArray_.size(), 37); } /** @@ -889,30 +890,31 @@ HWTEST_F(WaterFlowSegmentTest, Segmented005, TestSize.Level1) layoutProperty_->layoutConstraint_ = constraint; layoutProperty_->contentConstraint_ = constraint; - auto algo = AceType::MakeRefPtr(pattern_->layoutInfo_); + auto algo = + AceType::MakeRefPtr(AceType::DynamicCast(pattern_->layoutInfo_)); auto& info = algo->info_; - info.jumpIndex_ = 50; - info.align_ = ScrollAlign::END; + info->jumpIndex_ = 50; + info->align_ = ScrollAlign::END; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 47); - EXPECT_EQ(info.endIndex_, 50); - EXPECT_EQ(info.currentOffset_, -4000.0f); - EXPECT_EQ(info.segmentStartPos_.size(), 3); + EXPECT_EQ(info->startIndex_, 47); + EXPECT_EQ(info->endIndex_, 50); + EXPECT_EQ(info->currentOffset_, -4000.0f); + EXPECT_EQ(info->segmentStartPos_.size(), 3); pattern_->layoutInfo_ = info; secObj->ChangeData(0, 3, SECTION_5); MockPipelineContext::GetCurrent()->FlushBuildFinishCallbacks(); EXPECT_EQ(secObj->GetSectionInfo().size(), 4); - info = pattern_->layoutInfo_; - EXPECT_EQ(info.startIndex_, 47); - EXPECT_EQ(info.segmentTails_.size(), 4); - EXPECT_EQ(info.segmentTails_[3], 59); - algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 47); - EXPECT_EQ(info.endIndex_, 54); - EXPECT_EQ(info.currentOffset_, -5546.0f); - EXPECT_EQ(info.segmentStartPos_.size(), 4); - EXPECT_EQ(info.align_, ScrollAlign::START); + info = AceType::DynamicCast(pattern_->layoutInfo_); + EXPECT_EQ(info->startIndex_, 47); + EXPECT_EQ(info->segmentTails_.size(), 4); + EXPECT_EQ(info->segmentTails_[3], 59); + algo->Measure(AceType::RawPtr(frameNode_)); + EXPECT_EQ(info->startIndex_, 47); + EXPECT_EQ(info->endIndex_, 54); + EXPECT_EQ(info->currentOffset_, -5546.0f); + EXPECT_EQ(info->segmentStartPos_.size(), 4); + EXPECT_EQ(info->align_, ScrollAlign::START); EXPECT_EQ(algo->crossGaps_, CROSS_GAP_5); EXPECT_EQ(algo->mainGaps_, MAIN_GAP_5); EXPECT_EQ(algo->itemsCrossSize_.size(), 4); @@ -927,45 +929,46 @@ HWTEST_F(WaterFlowSegmentTest, Segmented002, TestSize.Level1) { SetUpConfig5(); - auto algo = AceType::MakeRefPtr(pattern_->layoutInfo_); + auto algo = + AceType::MakeRefPtr(AceType::DynamicCast(pattern_->layoutInfo_)); auto& info = algo->info_; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 0); - EXPECT_EQ(info.endIndex_, 10); - EXPECT_EQ(info.margins_.size(), 4); - EXPECT_EQ(info.segmentTails_, SEGMENT_TAILS_5); - EXPECT_EQ(info.currentOffset_, 0.0f); + EXPECT_EQ(info->startIndex_, 0); + EXPECT_EQ(info->endIndex_, 10); + EXPECT_EQ(info->margins_.size(), 4); + EXPECT_EQ(info->segmentTails_, SEGMENT_TAILS_5); + EXPECT_EQ(info->currentOffset_, 0.0f); EXPECT_EQ(algo->crossGaps_, CROSS_GAP_5); EXPECT_EQ(algo->mainGaps_, MAIN_GAP_5); EXPECT_EQ(algo->itemsCrossSize_, ITEM_CROSS_SIZE_5); - info.currentOffset_ = -200.0f; + info->currentOffset_ = -200.0f; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 3); - EXPECT_EQ(info.endIndex_, 11); - EXPECT_EQ(info.segmentStartPos_.size(), 3); + EXPECT_EQ(info->startIndex_, 3); + EXPECT_EQ(info->endIndex_, 11); + EXPECT_EQ(info->segmentStartPos_.size(), 3); - info.currentOffset_ = -304.0f; + info->currentOffset_ = -304.0f; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 3); - EXPECT_EQ(info.endIndex_, 12); - EXPECT_EQ(info.segmentStartPos_.size(), 3); + EXPECT_EQ(info->startIndex_, 3); + EXPECT_EQ(info->endIndex_, 12); + EXPECT_EQ(info->segmentStartPos_.size(), 3); - info.currentOffset_ = -305.0f; + info->currentOffset_ = -305.0f; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 5); - EXPECT_EQ(info.endIndex_, 12); - EXPECT_EQ(info.segmentStartPos_.size(), 3); + EXPECT_EQ(info->startIndex_, 5); + EXPECT_EQ(info->endIndex_, 12); + EXPECT_EQ(info->segmentStartPos_.size(), 3); - info.Reset(); + info->Reset(); algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.currentOffset_, -305.0f); - EXPECT_EQ(info.startIndex_, 5); - EXPECT_EQ(info.endIndex_, 12); - EXPECT_EQ(info.margins_.size(), 4); - EXPECT_EQ(info.segmentTails_, SEGMENT_TAILS_5); + EXPECT_EQ(info->currentOffset_, -305.0f); + EXPECT_EQ(info->startIndex_, 5); + EXPECT_EQ(info->endIndex_, 12); + EXPECT_EQ(info->margins_.size(), 4); + EXPECT_EQ(info->segmentTails_, SEGMENT_TAILS_5); } /** @@ -976,46 +979,47 @@ HWTEST_F(WaterFlowSegmentTest, Segmented002, TestSize.Level1) HWTEST_F(WaterFlowSegmentTest, Segmented003, TestSize.Level1) { SetUpConfig5(); - auto algo = AceType::MakeRefPtr(pattern_->layoutInfo_); + auto algo = + AceType::MakeRefPtr(AceType::DynamicCast(pattern_->layoutInfo_)); auto& info = algo->info_; algo->Measure(AceType::RawPtr(frameNode_)); - info.currentOffset_ = -800.0f; + info->currentOffset_ = -800.0f; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 11); - EXPECT_EQ(info.endIndex_, 15); - EXPECT_EQ(info.segmentStartPos_.size(), 3); + EXPECT_EQ(info->startIndex_, 11); + EXPECT_EQ(info->endIndex_, 15); + EXPECT_EQ(info->segmentStartPos_.size(), 3); - info.currentOffset_ = -1200.0f; + info->currentOffset_ = -1200.0f; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 14); - EXPECT_EQ(info.endIndex_, 18); + EXPECT_EQ(info->startIndex_, 14); + EXPECT_EQ(info->endIndex_, 18); - info.currentOffset_ = -2300.0f; + info->currentOffset_ = -2300.0f; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 21); - EXPECT_EQ(info.endIndex_, 25); - EXPECT_EQ(info.segmentStartPos_.size(), 3); + EXPECT_EQ(info->startIndex_, 21); + EXPECT_EQ(info->endIndex_, 25); + EXPECT_EQ(info->segmentStartPos_.size(), 3); - info.prevOffset_ = -2300.0f; - info.currentOffset_ = -1800.0f; + info->prevOffset_ = -2300.0f; + info->currentOffset_ = -1800.0f; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 18); - EXPECT_EQ(info.endIndex_, 22); - EXPECT_EQ(info.segmentStartPos_.size(), 3); + EXPECT_EQ(info->startIndex_, 18); + EXPECT_EQ(info->endIndex_, 22); + EXPECT_EQ(info->segmentStartPos_.size(), 3); - info.currentOffset_ = -10000.0f; + info->currentOffset_ = -10000.0f; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 53); - EXPECT_EQ(info.endIndex_, 59); - EXPECT_EQ(info.currentOffset_, -6058.0f); - EXPECT_EQ(*info.margins_[1].top, 1.0f); - EXPECT_EQ(*info.margins_[1].bottom, 5.0f); - EXPECT_EQ(info.segmentStartPos_.size(), 4); - EXPECT_TRUE(info.offsetEnd_); - EXPECT_TRUE(info.itemEnd_); - EXPECT_FALSE(info.itemStart_); + EXPECT_EQ(info->startIndex_, 53); + EXPECT_EQ(info->endIndex_, 59); + EXPECT_EQ(info->currentOffset_, -6058.0f); + EXPECT_EQ(*info->margins_[1].top, 1.0f); + EXPECT_EQ(*info->margins_[1].bottom, 5.0f); + EXPECT_EQ(info->segmentStartPos_.size(), 4); + EXPECT_TRUE(info->offsetEnd_); + EXPECT_TRUE(info->itemEnd_); + EXPECT_FALSE(info->itemStart_); algo->Layout(AceType::RawPtr(frameNode_)); } @@ -1029,47 +1033,48 @@ HWTEST_F(WaterFlowSegmentTest, Segmented004, TestSize.Level1) { SetUpConfig5(); - auto algo = AceType::MakeRefPtr(pattern_->layoutInfo_); + auto algo = + AceType::MakeRefPtr(AceType::DynamicCast(pattern_->layoutInfo_)); auto& info = algo->info_; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.endIndex_, 10); - EXPECT_EQ(info.itemInfos_.size(), 11); + EXPECT_EQ(info->endIndex_, 10); + EXPECT_EQ(info->itemInfos_.size(), 11); - info.currentOffset_ = -800.0f; + info->currentOffset_ = -800.0f; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 11); - EXPECT_EQ(info.endIndex_, 15); - EXPECT_EQ(info.segmentStartPos_.size(), 3); - EXPECT_EQ(info.itemInfos_.size(), 16); + EXPECT_EQ(info->startIndex_, 11); + EXPECT_EQ(info->endIndex_, 15); + EXPECT_EQ(info->segmentStartPos_.size(), 3); + EXPECT_EQ(info->itemInfos_.size(), 16); algo->Layout(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.itemInfos_.size(), 16); + EXPECT_EQ(info->itemInfos_.size(), 16); pattern_->layoutInfo_ = info; auto secObj = pattern_->GetSections(); secObj->ChangeData(4, 0, ADD_SECTION_6); MockPipelineContext::GetCurrent()->FlushBuildFinishCallbacks(); AddItems(10); - info = pattern_->layoutInfo_; - EXPECT_EQ(info.itemInfos_.size(), 16); + info = AceType::DynamicCast(pattern_->layoutInfo_); + EXPECT_EQ(info->itemInfos_.size(), 16); algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.currentOffset_, -800.0f); - EXPECT_EQ(info.startIndex_, 11); - EXPECT_EQ(info.endIndex_, 15); - EXPECT_EQ(info.childrenCount_, 70); + EXPECT_EQ(info->currentOffset_, -800.0f); + EXPECT_EQ(info->startIndex_, 11); + EXPECT_EQ(info->endIndex_, 15); + EXPECT_EQ(info->childrenCount_, 70); algo->Layout(AceType::RawPtr(frameNode_)); - info.prevOffset_ = -800.0f; - info.currentOffset_ = -10000.0f; + info->prevOffset_ = -800.0f; + info->currentOffset_ = -10000.0f; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 63); - EXPECT_EQ(info.endIndex_, 69); - EXPECT_EQ(info.itemInfos_.size(), 70); - EXPECT_EQ(info.itemInfos_[69].mainOffset, 7283.0f); - EXPECT_EQ(info.itemInfos_[69].crossIdx, 0); - EXPECT_EQ(info.itemInfos_[69].mainSize, 200.0f); + EXPECT_EQ(info->startIndex_, 63); + EXPECT_EQ(info->endIndex_, 69); + EXPECT_EQ(info->itemInfos_.size(), 70); + EXPECT_EQ(info->itemInfos_[69].mainOffset, 7283.0f); + EXPECT_EQ(info->itemInfos_[69].crossIdx, 0); + EXPECT_EQ(info->itemInfos_[69].mainSize, 200.0f); algo->Layout(AceType::RawPtr(frameNode_)); } @@ -1092,33 +1097,33 @@ HWTEST_F(WaterFlowSegmentTest, Segmented006, TestSize.Level1) MockPipelineContext::GetCurrent()->FlushBuildFinishCallbacks(); FlushLayoutTask(frameNode_); - auto& info = pattern_->layoutInfo_; - EXPECT_EQ(*info.margins_[0].top, 5.0f); - EXPECT_EQ(info.segmentStartPos_[0], 5.0f); - EXPECT_EQ(info.segmentStartPos_[1], 408.0f); + auto info = AceType::DynamicCast(pattern_->layoutInfo_); + EXPECT_EQ(*info->margins_[0].top, 5.0f); + EXPECT_EQ(info->segmentStartPos_[0], 5.0f); + EXPECT_EQ(info->segmentStartPos_[1], 408.0f); UpdateCurrentOffset(-600.0f); - EXPECT_EQ(info.segmentStartPos_[2], 613.0f); - EXPECT_EQ(info.startIndex_, 6); + EXPECT_EQ(info->segmentStartPos_[2], 613.0f); + EXPECT_EQ(info->startIndex_, 6); layoutProperty_->UpdateRowsGap(10.0_vp); FlushLayoutTask(frameNode_); - EXPECT_EQ(info.currentOffset_, -600.0f); - EXPECT_EQ(info.startIndex_, 6); - EXPECT_EQ(info.segmentStartPos_[0], 5.0f); - EXPECT_EQ(info.segmentStartPos_[1], 438.0f); - EXPECT_EQ(info.itemInfos_[4].mainOffset, 438.0f); - EXPECT_EQ(info.segmentStartPos_[2], 653.0f); + EXPECT_EQ(info->currentOffset_, -600.0f); + EXPECT_EQ(info->startIndex_, 6); + EXPECT_EQ(info->segmentStartPos_[0], 5.0f); + EXPECT_EQ(info->segmentStartPos_[1], 438.0f); + EXPECT_EQ(info->itemInfos_[4].mainOffset, 438.0f); + EXPECT_EQ(info->segmentStartPos_[2], 653.0f); UpdateCurrentOffset(600.0f); layoutProperty_->UpdateRowsGap(11.0_vp); FlushLayoutTask(frameNode_); - EXPECT_EQ(info.currentOffset_, 0.0f); - EXPECT_EQ(info.startIndex_, 0); - EXPECT_EQ(info.endIndex_, 6); - EXPECT_EQ(info.segmentStartPos_[0], 5.0f); - EXPECT_EQ(info.segmentStartPos_[1], 441.0f); + EXPECT_EQ(info->currentOffset_, 0.0f); + EXPECT_EQ(info->startIndex_, 0); + EXPECT_EQ(info->endIndex_, 6); + EXPECT_EQ(info->segmentStartPos_[0], 5.0f); + EXPECT_EQ(info->segmentStartPos_[1], 441.0f); } /** @@ -1167,12 +1172,12 @@ HWTEST_F(WaterFlowSegmentTest, CheckHeight001, TestSize.Level1) MockPipelineContext::GetCurrent()->FlushBuildFinishCallbacks(); FlushLayoutTask(frameNode_); - auto& info = pattern_->layoutInfo_; + auto info = AceType::DynamicCast(pattern_->layoutInfo_); UpdateCurrentOffset(-10000.0f); - EXPECT_EQ(info.currentOffset_, -3074.0f); - EXPECT_EQ(info.startIndex_, 31); - EXPECT_EQ(info.endIndex_, 36); + EXPECT_EQ(info->currentOffset_, -3074.0f); + EXPECT_EQ(info->startIndex_, 31); + EXPECT_EQ(info->endIndex_, 36); for (int i = 31; i <= 36; ++i) { EXPECT_EQ(GetChildHeight(frameNode_, i), 100.0f); } @@ -1184,9 +1189,9 @@ HWTEST_F(WaterFlowSegmentTest, CheckHeight001, TestSize.Level1) } UpdateCurrentOffset(10000.0f); - EXPECT_EQ(info.currentOffset_, 0.0f); - EXPECT_EQ(info.startIndex_, 0); - EXPECT_EQ(info.endIndex_, 6); + EXPECT_EQ(info->currentOffset_, 0.0f); + EXPECT_EQ(info->startIndex_, 0); + EXPECT_EQ(info->endIndex_, 6); for (int i = 0; i <= 6; ++i) { EXPECT_EQ(GetChildHeight(frameNode_, i), 100.0f); } @@ -1201,14 +1206,15 @@ HWTEST_F(WaterFlowSegmentTest, TargetIndex001, TestSize.Level1) { SetUpConfig5(); - auto algo = AceType::MakeRefPtr(pattern_->layoutInfo_); + auto algo = + AceType::MakeRefPtr(AceType::DynamicCast(pattern_->layoutInfo_)); auto& info = algo->info_; - info.targetIndex_ = 50; + info->targetIndex_ = 50; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.currentOffset_, 0.0f); - EXPECT_EQ(info.segmentStartPos_.size(), 4); - EXPECT_EQ(info.itemInfos_.size(), 51); + EXPECT_EQ(info->currentOffset_, 0.0f); + EXPECT_EQ(info->segmentStartPos_.size(), 4); + EXPECT_EQ(info->itemInfos_.size(), 51); algo->Layout(AceType::RawPtr(frameNode_)); } @@ -1234,31 +1240,32 @@ HWTEST_F(WaterFlowSegmentTest, ChildrenCount001, TestSize.Level1) layoutProperty_->layoutConstraint_ = constraint; layoutProperty_->contentConstraint_ = constraint; - auto algo = AceType::MakeRefPtr(pattern_->layoutInfo_); + auto algo = + AceType::MakeRefPtr(AceType::DynamicCast(pattern_->layoutInfo_)); // cause layout abort auto& info = algo->info_; - info.targetIndex_ = 50; + info->targetIndex_ = 50; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.endIndex_, -1); - EXPECT_EQ(info.currentOffset_, 0.0f); - EXPECT_EQ(info.segmentStartPos_.size(), 1); - EXPECT_EQ(info.itemInfos_.size(), 0); + EXPECT_EQ(info->endIndex_, -1); + EXPECT_EQ(info->currentOffset_, 0.0f); + EXPECT_EQ(info->segmentStartPos_.size(), 1); + EXPECT_EQ(info->itemInfos_.size(), 0); algo->Layout(AceType::RawPtr(frameNode_)); - info.currentOffset_ = -1050.0f; + info->currentOffset_ = -1050.0f; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 0); - EXPECT_EQ(info.endIndex_, -1); - EXPECT_EQ(info.segmentStartPos_.size(), 1); + EXPECT_EQ(info->startIndex_, 0); + EXPECT_EQ(info->endIndex_, -1); + EXPECT_EQ(info->segmentStartPos_.size(), 1); - info.prevOffset_ = -1050.0f; - info.currentOffset_ = -10000.0f; + info->prevOffset_ = -1050.0f; + info->currentOffset_ = -10000.0f; algo->Measure(AceType::RawPtr(frameNode_)); // as long as no crash happens - EXPECT_EQ(info.segmentStartPos_.size(), 1); - EXPECT_EQ(info.itemInfos_.size(), 0); + EXPECT_EQ(info->segmentStartPos_.size(), 1); + EXPECT_EQ(info->itemInfos_.size(), 0); } /** @@ -1282,27 +1289,28 @@ HWTEST_F(WaterFlowSegmentTest, ChildrenCount002, TestSize.Level1) layoutProperty_->layoutConstraint_ = constraint; layoutProperty_->contentConstraint_ = constraint; - auto algo = AceType::MakeRefPtr(pattern_->layoutInfo_); + auto algo = + AceType::MakeRefPtr(AceType::DynamicCast(pattern_->layoutInfo_)); auto& info = algo->info_; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 0); - EXPECT_EQ(info.endIndex_, -1); - EXPECT_EQ(info.segmentStartPos_.size(), 1); + EXPECT_EQ(info->startIndex_, 0); + EXPECT_EQ(info->endIndex_, -1); + EXPECT_EQ(info->segmentStartPos_.size(), 1); - info.currentOffset_ = -10000.0f; + info->currentOffset_ = -10000.0f; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 0); - EXPECT_EQ(info.endIndex_, -1); - EXPECT_EQ(info.segmentStartPos_.size(), 1); - EXPECT_EQ(info.itemInfos_.size(), 0); + EXPECT_EQ(info->startIndex_, 0); + EXPECT_EQ(info->endIndex_, -1); + EXPECT_EQ(info->segmentStartPos_.size(), 1); + EXPECT_EQ(info->itemInfos_.size(), 0); algo->Layout(AceType::RawPtr(frameNode_)); - info.jumpIndex_ = 70; - info.align_ = ScrollAlign::AUTO; + info->jumpIndex_ = 70; + info->align_ = ScrollAlign::AUTO; algo->Measure(AceType::RawPtr(frameNode_)); - EXPECT_EQ(info.startIndex_, 0); - EXPECT_EQ(info.endIndex_, -1); + EXPECT_EQ(info->startIndex_, 0); + EXPECT_EQ(info->endIndex_, -1); algo->Layout(AceType::RawPtr(frameNode_)); } @@ -1325,15 +1333,15 @@ HWTEST_F(WaterFlowSegmentTest, Add001, TestSize.Level1) MockPipelineContext::GetCurrent()->FlushBuildFinishCallbacks(); FlushLayoutTask(frameNode_); - auto& info = pattern_->layoutInfo_; - EXPECT_EQ(info.startIndex_, 0); - EXPECT_EQ(info.endIndex_, 10); + auto info = AceType::DynamicCast(pattern_->layoutInfo_); + EXPECT_EQ(info->startIndex_, 0); + EXPECT_EQ(info->endIndex_, 10); UpdateCurrentOffset(-2000.0f); - EXPECT_EQ(info.currentOffset_, -2000.0f); - EXPECT_EQ(info.startIndex_, 19); - EXPECT_EQ(info.endIndex_, 23); - EXPECT_EQ(info.segmentTails_.size(), 4); + EXPECT_EQ(info->currentOffset_, -2000.0f); + EXPECT_EQ(info->startIndex_, 19); + EXPECT_EQ(info->endIndex_, 23); + EXPECT_EQ(info->segmentTails_.size(), 4); AddItems(10); secObj->ChangeData(4, 0, ADD_SECTION_6); @@ -1343,20 +1351,20 @@ HWTEST_F(WaterFlowSegmentTest, Add001, TestSize.Level1) EXPECT_EQ(secObj->GetSectionInfo()[4].crossCount, 2); FlushLayoutTask(frameNode_); - EXPECT_EQ(info.currentOffset_, -2000.0f); - EXPECT_EQ(info.startIndex_, 19); - EXPECT_EQ(info.endIndex_, 23); - EXPECT_EQ(info.segmentTails_.size(), 5); - EXPECT_EQ(info.childrenCount_, 70); + EXPECT_EQ(info->currentOffset_, -2000.0f); + EXPECT_EQ(info->startIndex_, 19); + EXPECT_EQ(info->endIndex_, 23); + EXPECT_EQ(info->segmentTails_.size(), 5); + EXPECT_EQ(info->childrenCount_, 70); UpdateCurrentOffset(-10000.0f); - EXPECT_EQ(info.currentOffset_, -6883.0f); - EXPECT_EQ(info.startIndex_, 63); - EXPECT_EQ(info.endIndex_, 69); - EXPECT_EQ(info.items_[4][1].size(), 4); - EXPECT_EQ(info.itemInfos_[60].mainOffset, 6658.0f); - EXPECT_EQ(info.itemInfos_[9].mainOffset, 306.0f); - EXPECT_EQ(info.itemInfos_[10].mainOffset, 511.0f); + EXPECT_EQ(info->currentOffset_, -6883.0f); + EXPECT_EQ(info->startIndex_, 63); + EXPECT_EQ(info->endIndex_, 69); + EXPECT_EQ(info->items_[4][1].size(), 4); + EXPECT_EQ(info->itemInfos_[60].mainOffset, 6658.0f); + EXPECT_EQ(info->itemInfos_[9].mainOffset, 306.0f); + EXPECT_EQ(info->itemInfos_[10].mainOffset, 511.0f); } /** @@ -1377,12 +1385,12 @@ HWTEST_F(WaterFlowSegmentTest, Splice001, TestSize.Level1) secObj->ChangeData(0, 0, SECTION_7); MockPipelineContext::GetCurrent()->FlushBuildFinishCallbacks(); FlushLayoutTask(frameNode_); - auto& info = pattern_->layoutInfo_; + auto info = AceType::DynamicCast(pattern_->layoutInfo_); UpdateCurrentOffset(-300.0f); - EXPECT_EQ(info.segmentStartPos_[2], 613.0f); - EXPECT_EQ(info.startIndex_, 2); + EXPECT_EQ(info->segmentStartPos_[2], 613.0f); + EXPECT_EQ(info->startIndex_, 2); // replace second section secObj->ChangeData(1, 1, ADD_SECTION_6); @@ -1396,18 +1404,18 @@ HWTEST_F(WaterFlowSegmentTest, Splice001, TestSize.Level1) EXPECT_EQ(secObj->GetSectionInfo()[2].itemsCount, 30); EXPECT_TRUE(secObj->GetSectionInfo()[1].onGetItemMainSizeByIndex); - EXPECT_EQ(info.currentOffset_, -300.0f); - EXPECT_EQ(info.startIndex_, 2); - EXPECT_EQ(info.endIndex_, 10); - EXPECT_EQ(info.segmentStartPos_.size(), 2); - EXPECT_EQ(info.segmentStartPos_[0], 5.0f); - EXPECT_EQ(info.segmentStartPos_[1], 408.0f); - EXPECT_EQ(info.itemInfos_[5].mainOffset, 408.0f); - EXPECT_EQ(info.itemInfos_[5].crossIdx, 1); + EXPECT_EQ(info->currentOffset_, -300.0f); + EXPECT_EQ(info->startIndex_, 2); + EXPECT_EQ(info->endIndex_, 10); + EXPECT_EQ(info->segmentStartPos_.size(), 2); + EXPECT_EQ(info->segmentStartPos_[0], 5.0f); + EXPECT_EQ(info->segmentStartPos_[1], 408.0f); + EXPECT_EQ(info->itemInfos_[5].mainOffset, 408.0f); + EXPECT_EQ(info->itemInfos_[5].crossIdx, 1); UpdateCurrentOffset(-1000.0f); - EXPECT_EQ(info.startIndex_, 14); - EXPECT_EQ(info.endIndex_, 20); + EXPECT_EQ(info->startIndex_, 14); + EXPECT_EQ(info->endIndex_, 20); } /** @@ -1428,9 +1436,9 @@ HWTEST_F(WaterFlowSegmentTest, Splice002, TestSize.Level1) secObj->ChangeData(0, 0, SECTION_7); MockPipelineContext::GetCurrent()->FlushBuildFinishCallbacks(); FlushLayoutTask(frameNode_); - auto& info = pattern_->layoutInfo_; - EXPECT_EQ(info.endIndex_, 6); - for (int i = 0; i < info.endIndex_; ++i) { + auto info = AceType::DynamicCast(pattern_->layoutInfo_); + EXPECT_EQ(info->endIndex_, 6); + for (int i = 0; i < info->endIndex_; ++i) { EXPECT_EQ(GetChildHeight(frameNode_, i), 100.0f); } @@ -1440,12 +1448,12 @@ HWTEST_F(WaterFlowSegmentTest, Splice002, TestSize.Level1) frameNode_->ChildrenUpdatedFrom(37); MockPipelineContext::GetCurrent()->FlushBuildFinishCallbacks(); FlushLayoutTask(frameNode_); - EXPECT_EQ(info.endIndex_, 10); - for (int i = 0; i < info.endIndex_; ++i) { + EXPECT_EQ(info->endIndex_, 10); + for (int i = 0; i < info->endIndex_; ++i) { EXPECT_TRUE(GetChildFrameNode(frameNode_, i)->IsActive()); EXPECT_EQ(GetChildHeight(frameNode_, i), 100.0f); } - EXPECT_EQ(info.segmentStartPos_[0], 0.0f); + EXPECT_EQ(info->segmentStartPos_[0], 0.0f); // replace FIRST section secObj->ChangeData(0, 3, SECTION_7); @@ -1455,9 +1463,9 @@ HWTEST_F(WaterFlowSegmentTest, Splice002, TestSize.Level1) frameNode_->ChildrenUpdatedFrom(0); MockPipelineContext::GetCurrent()->FlushBuildFinishCallbacks(); FlushLayoutTask(frameNode_); - EXPECT_EQ(info.childrenCount_, 37); - EXPECT_EQ(info.endIndex_, 6); - EXPECT_EQ(info.segmentStartPos_[0], 5.0f); + EXPECT_EQ(info->childrenCount_, 37); + EXPECT_EQ(info->endIndex_, 6); + EXPECT_EQ(info->segmentStartPos_[0], 5.0f); } /** @@ -1478,10 +1486,10 @@ HWTEST_F(WaterFlowSegmentTest, Delete001, TestSize.Level1) secObj->ChangeData(0, 0, SECTION_7); MockPipelineContext::GetCurrent()->FlushBuildFinishCallbacks(); FlushLayoutTask(frameNode_); - auto& info = pattern_->layoutInfo_; + auto info = AceType::DynamicCast(pattern_->layoutInfo_); UpdateCurrentOffset(-200.0f); - EXPECT_EQ(info.startIndex_, 1); + EXPECT_EQ(info->startIndex_, 1); secObj->ChangeData(1, 2, {}); for (int i = 0; i < 33; ++i) { @@ -1493,12 +1501,12 @@ HWTEST_F(WaterFlowSegmentTest, Delete001, TestSize.Level1) EXPECT_EQ(secObj->GetSectionInfo().size(), 1); EXPECT_EQ(secObj->GetSectionInfo()[0].itemsCount, 4); - EXPECT_EQ(info.childrenCount_, 4); - EXPECT_EQ(info.currentOffset_, 0.0f); - EXPECT_EQ(info.startIndex_, 0); - EXPECT_EQ(info.endIndex_, 3); - EXPECT_EQ(info.segmentStartPos_.size(), 1); - EXPECT_EQ(info.segmentStartPos_[0], 5.0f); + EXPECT_EQ(info->childrenCount_, 4); + EXPECT_EQ(info->currentOffset_, 0.0f); + EXPECT_EQ(info->startIndex_, 0); + EXPECT_EQ(info->endIndex_, 3); + EXPECT_EQ(info->segmentStartPos_.size(), 1); + EXPECT_EQ(info->segmentStartPos_[0], 5.0f); EXPECT_EQ(GetChildHeight(frameNode_, 0), 100.0f); EXPECT_EQ(GetChildWidth(frameNode_, 0), 400.0f); } @@ -1521,11 +1529,11 @@ HWTEST_F(WaterFlowSegmentTest, Delete002, TestSize.Level1) secObj->ChangeData(0, 0, SECTION_7); MockPipelineContext::GetCurrent()->FlushBuildFinishCallbacks(); FlushLayoutTask(frameNode_); - auto& info = pattern_->layoutInfo_; + auto info = AceType::DynamicCast(pattern_->layoutInfo_); UpdateCurrentOffset(-400.0f); - EXPECT_EQ(info.startIndex_, 3); - EXPECT_EQ(info.storedOffset_, -95.0f); + EXPECT_EQ(info->startIndex_, 3); + EXPECT_EQ(info->storedOffset_, -95.0f); secObj->ChangeData(0, 2, {}); for (int i = 0; i < 7; ++i) { @@ -1537,19 +1545,19 @@ HWTEST_F(WaterFlowSegmentTest, Delete002, TestSize.Level1) EXPECT_EQ(secObj->GetSectionInfo().size(), 1); EXPECT_EQ(secObj->GetSectionInfo()[0].itemsCount, 30); - EXPECT_EQ(info.currentOffset_, -406.0f); - EXPECT_EQ(info.storedOffset_, -95.0f); - EXPECT_EQ(info.startIndex_, 3); - EXPECT_EQ(info.endIndex_, 9); - EXPECT_EQ(info.segmentStartPos_.size(), 1); - EXPECT_EQ(info.segmentStartPos_[0], 5.0f); - EXPECT_EQ(info.itemInfos_[3].mainOffset, 311.0f); - EXPECT_EQ(info.itemInfos_[3].crossIdx, 0); + EXPECT_EQ(info->currentOffset_, -406.0f); + EXPECT_EQ(info->storedOffset_, -95.0f); + EXPECT_EQ(info->startIndex_, 3); + EXPECT_EQ(info->endIndex_, 9); + EXPECT_EQ(info->segmentStartPos_.size(), 1); + EXPECT_EQ(info->segmentStartPos_[0], 5.0f); + EXPECT_EQ(info->itemInfos_[3].mainOffset, 311.0f); + EXPECT_EQ(info->itemInfos_[3].crossIdx, 0); UpdateCurrentOffset(-10000.0f); - EXPECT_EQ(info.currentOffset_, -2466.0f); - EXPECT_EQ(info.startIndex_, 24); - EXPECT_EQ(info.endIndex_, 29); + EXPECT_EQ(info->currentOffset_, -2466.0f); + EXPECT_EQ(info->startIndex_, 24); + EXPECT_EQ(info->endIndex_, 29); } /** @@ -1570,10 +1578,10 @@ HWTEST_F(WaterFlowSegmentTest, Replace001, TestSize.Level1) secObj->ChangeData(0, 0, SECTION_7); MockPipelineContext::GetCurrent()->FlushBuildFinishCallbacks(); FlushLayoutTask(frameNode_); - auto& info = pattern_->layoutInfo_; + auto info = AceType::DynamicCast(pattern_->layoutInfo_); UpdateCurrentOffset(-205.0f); - EXPECT_EQ(info.startIndex_, 2); + EXPECT_EQ(info->startIndex_, 2); secObj->ChangeData(1, 2, ADD_SECTION_6); for (int i = 0; i < 23; ++i) { @@ -1585,25 +1593,25 @@ HWTEST_F(WaterFlowSegmentTest, Replace001, TestSize.Level1) EXPECT_EQ(secObj->GetSectionInfo().size(), 2); EXPECT_EQ(secObj->GetSectionInfo()[1].itemsCount, 10); - EXPECT_EQ(info.currentOffset_, -205.0f); - EXPECT_EQ(info.startIndex_, 2); - EXPECT_EQ(info.endIndex_, 9); - EXPECT_EQ(info.segmentStartPos_.size(), 2); - EXPECT_EQ(info.segmentStartPos_[1], 408.0f); - EXPECT_EQ(info.itemInfos_[3].mainOffset, 305.0f); - EXPECT_EQ(info.itemInfos_[3].crossIdx, 0); + EXPECT_EQ(info->currentOffset_, -205.0f); + EXPECT_EQ(info->startIndex_, 2); + EXPECT_EQ(info->endIndex_, 9); + EXPECT_EQ(info->segmentStartPos_.size(), 2); + EXPECT_EQ(info->segmentStartPos_[1], 408.0f); + EXPECT_EQ(info->itemInfos_[3].mainOffset, 305.0f); + EXPECT_EQ(info->itemInfos_[3].crossIdx, 0); UpdateCurrentOffset(-303.0f); - EXPECT_EQ(info.currentOffset_, -508.0f); - EXPECT_EQ(info.startIndex_, 5); - EXPECT_EQ(info.endIndex_, 13); - EXPECT_EQ(info.itemInfos_[7].mainOffset, 613.0f); - EXPECT_EQ(info.itemInfos_[7].crossIdx, 1); + EXPECT_EQ(info->currentOffset_, -508.0f); + EXPECT_EQ(info->startIndex_, 5); + EXPECT_EQ(info->endIndex_, 13); + EXPECT_EQ(info->itemInfos_[7].mainOffset, 613.0f); + EXPECT_EQ(info->itemInfos_[7].crossIdx, 1); UpdateCurrentOffset(1.0f); - EXPECT_EQ(info.currentOffset_, -507.0f); - EXPECT_EQ(info.startIndex_, 4); - EXPECT_EQ(info.endIndex_, 13); + EXPECT_EQ(info->currentOffset_, -507.0f); + EXPECT_EQ(info->startIndex_, 4); + EXPECT_EQ(info->endIndex_, 13); } /** @@ -1624,20 +1632,20 @@ HWTEST_F(WaterFlowSegmentTest, Replace002, TestSize.Level1) secObj->ChangeData(0, 0, SECTION_7); MockPipelineContext::GetCurrent()->FlushBuildFinishCallbacks(); FlushLayoutTask(frameNode_); - auto& info = pattern_->layoutInfo_; + auto info = AceType::DynamicCast(pattern_->layoutInfo_); UpdateCurrentOffset(-300.0f); - EXPECT_EQ(info.startIndex_, 2); - EXPECT_EQ(info.storedOffset_, -95); + EXPECT_EQ(info->startIndex_, 2); + EXPECT_EQ(info->storedOffset_, -95); // relative offset to the first item should remain constant secObj->ChangeData(0, 3, SECTION_7); MockPipelineContext::GetCurrent()->FlushBuildFinishCallbacks(); FlushLayoutTask(frameNode_); - EXPECT_EQ(info.currentOffset_, -300.0f); - EXPECT_EQ(info.startIndex_, 2); - EXPECT_EQ(info.storedOffset_, -95); + EXPECT_EQ(info->currentOffset_, -300.0f); + EXPECT_EQ(info->startIndex_, 2); + EXPECT_EQ(info->storedOffset_, -95); } /** @@ -1658,14 +1666,14 @@ HWTEST_F(WaterFlowSegmentTest, Replace003, TestSize.Level1) secObj->ChangeData(0, 0, SECTION_7); MockPipelineContext::GetCurrent()->FlushBuildFinishCallbacks(); FlushLayoutTask(frameNode_); - auto& info = pattern_->layoutInfo_; + auto info = AceType::DynamicCast(pattern_->layoutInfo_); UpdateCurrentOffset(-2000.0f); - EXPECT_EQ(info.segmentStartPos_[2], 613.0f); - EXPECT_EQ(info.currentOffset_, -2000.0f); - EXPECT_EQ(info.startIndex_, 20); - EXPECT_EQ(info.endIndex_, 26); - EXPECT_EQ(info.itemInfos_.size(), 27); - EXPECT_EQ(info.endPosArray_.size(), 26); + EXPECT_EQ(info->segmentStartPos_[2], 613.0f); + EXPECT_EQ(info->currentOffset_, -2000.0f); + EXPECT_EQ(info->startIndex_, 20); + EXPECT_EQ(info->endIndex_, 26); + EXPECT_EQ(info->itemInfos_.size(), 27); + EXPECT_EQ(info->endPosArray_.size(), 26); AddItems(10); frameNode_->ChildrenUpdatedFrom(37); @@ -1673,27 +1681,27 @@ HWTEST_F(WaterFlowSegmentTest, Replace003, TestSize.Level1) newSection[0].itemsCount = 40; secObj->ChangeData(2, 1, newSection); MockPipelineContext::GetCurrent()->FlushBuildFinishCallbacks(); - EXPECT_EQ(info.itemInfos_.size(), 27); - EXPECT_EQ(info.items_[2].at(0).size(), 20); - EXPECT_EQ(info.endPosArray_.size(), 26); - EXPECT_EQ(info.segmentStartPos_[2], 613.0f); - EXPECT_EQ(info.segmentStartPos_.size(), 3); - EXPECT_EQ(info.segmentTails_.size(), 3); - EXPECT_EQ(info.segmentTails_[2], 46); + EXPECT_EQ(info->itemInfos_.size(), 27); + EXPECT_EQ(info->items_[2].at(0).size(), 20); + EXPECT_EQ(info->endPosArray_.size(), 26); + EXPECT_EQ(info->segmentStartPos_[2], 613.0f); + EXPECT_EQ(info->segmentStartPos_.size(), 3); + EXPECT_EQ(info->segmentTails_.size(), 3); + EXPECT_EQ(info->segmentTails_[2], 46); FlushLayoutTask(frameNode_); - EXPECT_EQ(info.currentOffset_, -2000.0f); - EXPECT_EQ(info.startIndex_, 20); + EXPECT_EQ(info->currentOffset_, -2000.0f); + EXPECT_EQ(info->startIndex_, 20); EXPECT_EQ(GetChildY(frameNode_, 20), -61.0f); AddItems(7); frameNode_->ChildrenUpdatedFrom(7); secObj->ChangeData(1, 1, ADD_SECTION_7); MockPipelineContext::GetCurrent()->FlushBuildFinishCallbacks(); - EXPECT_EQ(info.itemInfos_.size(), 14); - EXPECT_EQ(info.segmentTails_[1], 13); + EXPECT_EQ(info->itemInfos_.size(), 14); + EXPECT_EQ(info->segmentTails_[1], 13); FlushLayoutTask(frameNode_); - EXPECT_EQ(info.startIndex_, 20); + EXPECT_EQ(info->startIndex_, 20); EXPECT_EQ(GetChildY(frameNode_, 20), -61.0f); } @@ -1715,7 +1723,7 @@ HWTEST_F(WaterFlowSegmentTest, Replace004, TestSize.Level1) secObj->ChangeData(0, 0, SECTION_9); MockPipelineContext::GetCurrent()->FlushBuildFinishCallbacks(); FlushLayoutTask(frameNode_); - auto& info = pattern_->layoutInfo_; + auto info = AceType::DynamicCast(pattern_->layoutInfo_); AddItems(100); frameNode_->ChildrenUpdatedFrom(6); @@ -1723,20 +1731,20 @@ HWTEST_F(WaterFlowSegmentTest, Replace004, TestSize.Level1) newSection[0].itemsCount = 106; secObj->ChangeData(0, 1, newSection); MockPipelineContext::GetCurrent()->FlushBuildFinishCallbacks(); - EXPECT_EQ(info.itemInfos_.size(), 6); - EXPECT_EQ(info.items_[0].at(0).size(), 2); - EXPECT_EQ(info.endPosArray_.size(), 2); - EXPECT_EQ(info.segmentStartPos_[0], 0.0f); - EXPECT_EQ(info.segmentStartPos_.size(), 1); - EXPECT_EQ(info.segmentTails_.size(), 1); - EXPECT_EQ(info.segmentTails_[0], 105); + EXPECT_EQ(info->itemInfos_.size(), 6); + EXPECT_EQ(info->items_[0].at(0).size(), 2); + EXPECT_EQ(info->endPosArray_.size(), 2); + EXPECT_EQ(info->segmentStartPos_[0], 0.0f); + EXPECT_EQ(info->segmentStartPos_.size(), 1); + EXPECT_EQ(info->segmentTails_.size(), 1); + EXPECT_EQ(info->segmentTails_[0], 105); FlushLayoutTask(frameNode_); - EXPECT_EQ(info.currentOffset_, 0.0f); - EXPECT_EQ(info.endIndex_, 17); - EXPECT_EQ(info.items_[0].at(0).size(), 6); + EXPECT_EQ(info->currentOffset_, 0.0f); + EXPECT_EQ(info->endIndex_, 17); + EXPECT_EQ(info->items_[0].at(0).size(), 6); UpdateCurrentOffset(-10000.0f); - EXPECT_EQ(info.currentOffset_, -3000.0f); + EXPECT_EQ(info->currentOffset_, -3000.0f); for (int i = 0; i < 100; ++i) { frameNode_->RemoveChildAtIndex(10); } @@ -1744,11 +1752,11 @@ HWTEST_F(WaterFlowSegmentTest, Replace004, TestSize.Level1) newSection[0].itemsCount = 10; secObj->ChangeData(0, 1, newSection); MockPipelineContext::GetCurrent()->FlushBuildFinishCallbacks(); - EXPECT_EQ(info.segmentTails_[0], 9); + EXPECT_EQ(info->segmentTails_[0], 9); FlushLayoutTask(frameNode_); - EXPECT_EQ(info.currentOffset_, 0.0f); - EXPECT_EQ(info.endIndex_, 9); - EXPECT_EQ(info.items_[0].at(0).size(), 4); + EXPECT_EQ(info->currentOffset_, 0.0f); + EXPECT_EQ(info->endIndex_, 9); + EXPECT_EQ(info->items_[0].at(0).size(), 4); } /** @@ -1769,11 +1777,11 @@ HWTEST_F(WaterFlowSegmentTest, Illegal001, TestSize.Level1) secObj->ChangeData(0, 0, {}); MockPipelineContext::GetCurrent()->FlushBuildFinishCallbacks(); FlushLayoutTask(frameNode_); - auto& info = pattern_->layoutInfo_; + auto info = AceType::DynamicCast(pattern_->layoutInfo_); UpdateCurrentOffset(-205.0f); - EXPECT_EQ(info.startIndex_, 0); - EXPECT_EQ(info.endIndex_, -1); + EXPECT_EQ(info->startIndex_, 0); + EXPECT_EQ(info->endIndex_, -1); } /** @@ -1794,14 +1802,14 @@ HWTEST_F(WaterFlowSegmentTest, Illegal002, TestSize.Level1) secObj->ChangeData(0, 0, SECTION_8); MockPipelineContext::GetCurrent()->FlushBuildFinishCallbacks(); FlushLayoutTask(frameNode_); - auto& info = pattern_->layoutInfo_; + auto info = AceType::DynamicCast(pattern_->layoutInfo_); // user-defined negative size would be treated as 0 UpdateCurrentOffset(-205.0f); - EXPECT_EQ(info.currentOffset_, 0.0f); - EXPECT_EQ(info.itemInfos_[0].mainSize, 0.0f); - EXPECT_EQ(info.startIndex_, 0); - EXPECT_EQ(info.endIndex_, 9); + EXPECT_EQ(info->currentOffset_, 0.0f); + EXPECT_EQ(info->itemInfos_[0].mainSize, 0.0f); + EXPECT_EQ(info->startIndex_, 0); + EXPECT_EQ(info->endIndex_, 9); } /** @@ -1824,8 +1832,8 @@ HWTEST_F(WaterFlowSegmentTest, Constraint001, TestSize.Level1) FlushLayoutTask(frameNode_); auto& info = pattern_->layoutInfo_; - EXPECT_EQ(info.startIndex_, 0); - EXPECT_EQ(info.endIndex_, 10); + EXPECT_EQ(info->startIndex_, 0); + EXPECT_EQ(info->endIndex_, 10); EXPECT_TRUE(IsEqual(pattern_->GetItemRect(0), Rect(0, 0, 400.f / 3, 100))); layoutProperty_->UpdateUserDefinedIdealSize(CalcSize(CalcLength(500.0f), CalcLength(Dimension(600.0f)))); @@ -1837,16 +1845,62 @@ HWTEST_F(WaterFlowSegmentTest, Constraint001, TestSize.Level1) EXPECT_EQ(GetChildWidth(frameNode_, i), (500.f - 3) / 5); } EXPECT_EQ(GetChildWidth(frameNode_, 10), 500.f); - EXPECT_EQ(info.endIndex_, 10); + EXPECT_EQ(info->endIndex_, 10); layoutProperty_->UpdateUserDefinedIdealSize(CalcSize(CalcLength(400.0f), CalcLength(Dimension(700.0f)))); FlushLayoutTask(frameNode_); EXPECT_TRUE(IsEqual(pattern_->GetItemRect(0), Rect(0, 0, 400.f / 3, 100))); - EXPECT_EQ(info.endIndex_, 11); + EXPECT_EQ(info->endIndex_, 11); layoutProperty_->UpdateUserDefinedIdealSize(CalcSize(CalcLength(500.0f), CalcLength(Dimension(700.0f)))); FlushLayoutTask(frameNode_); EXPECT_TRUE(IsEqual(pattern_->GetItemRect(0), Rect(0, 0, 500.f / 3, 100))); - EXPECT_EQ(info.endIndex_, 11); + EXPECT_EQ(info->endIndex_, 11); +} + +/** + * @tc.name: ResetSections001 + * @tc.desc: Layout WaterFlow and then reset to old layout + * @tc.type: FUNC + */ +HWTEST_F(WaterFlowSegmentTest, ResetSections001, TestSize.Level1) +{ + Create( + [](WaterFlowModelNG model) { + ViewAbstract::SetWidth(CalcLength(400.0f)); + ViewAbstract::SetHeight(CalcLength(600.f)); + CreateItem(60); + }, + false); + auto secObj = pattern_->GetOrCreateWaterFlowSections(); + secObj->ChangeData(0, 0, SECTION_5); + MockPipelineContext::GetCurrent()->FlushBuildFinishCallbacks(); + FlushLayoutTask(frameNode_); + auto info = AceType::DynamicCast(pattern_->layoutInfo_); + + UpdateCurrentOffset(-205.0f); + EXPECT_EQ(info->currentOffset_, -205.0f); + EXPECT_EQ(info->startIndex_, 3); + EXPECT_EQ(info->endIndex_, 11); + + // fallback to layout without sections + pattern_->ResetSections(); + FlushLayoutTask(frameNode_); + EXPECT_EQ(info->currentOffset_, -205.0f); + EXPECT_EQ(info->startIndex_, 1); + EXPECT_EQ(info->endIndex_, 5); + EXPECT_EQ(info->GetCrossCount(), 1); + if (SystemProperties::WaterFlowUseSegmentedLayout()) { + EXPECT_EQ(info->segmentTails_.size(), 1); + EXPECT_EQ(info->margins_.size(), 1); + } else { + EXPECT_TRUE(info->segmentTails_.empty()); + EXPECT_TRUE(info->margins_.empty()); + } + + UpdateCurrentOffset(250.0f); + EXPECT_EQ(info->currentOffset_, 0.0f); + EXPECT_EQ(info->startIndex_, 0); + EXPECT_EQ(info->endIndex_, 3); } } // namespace OHOS::Ace::NG diff --git a/test/unittest/core/pattern/waterflow/water_flow_sw_layout_test.cpp b/test/unittest/core/pattern/waterflow/water_flow_sw_layout_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8259313ca46fb3fc8c252fcf8bf5b081f7eebb7c --- /dev/null +++ b/test/unittest/core/pattern/waterflow/water_flow_sw_layout_test.cpp @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ \ No newline at end of file diff --git a/test/unittest/core/pattern/waterflow/water_flow_test_ng.cpp b/test/unittest/core/pattern/waterflow/water_flow_test_ng.cpp index 6299c8c324928bbbe18499da2d31d54a35987d86..b548ac4326d09175b35334bf476970f29f4bd49f 100644 --- a/test/unittest/core/pattern/waterflow/water_flow_test_ng.cpp +++ b/test/unittest/core/pattern/waterflow/water_flow_test_ng.cpp @@ -17,55 +17,41 @@ #include #include -#include "gtest/gtest.h" +#ifndef TEST_SEGMENTED_WATER_FLOW #include "test/mock/base/mock_system_properties.h" +#endif #include "test/mock/core/rosen/mock_canvas.h" -#include "water_flow_item_maps.h" -#include "base/utils/system_properties.h" #include "core/components/scroll/scroll_controller_base.h" +#include "core/components_ng/pattern/waterflow/water_flow_layout_info.h" +#include "core/components_ng/property/property.h" #define protected public #define private public -#include "test/mock/base/mock_task_executor.h" -#include "test/mock/core/common/mock_container.h" #include "test/mock/core/common/mock_theme_manager.h" #include "test/mock/core/pipeline/mock_pipeline_context.h" -#include "test/mock/core/render/mock_render_context.h" -#include "test/unittest/core/pattern/test_ng.h" #include "test/unittest/core/pattern/waterflow/water_flow_test_ng.h" +#include "water_flow_item_maps.h" -#include "base/geometry/dimension.h" -#include "base/geometry/ng/size_t.h" -#include "base/geometry/offset.h" -#include "base/memory/ace_type.h" -#include "base/utils/utils.h" #include "core/components/button/button_theme.h" #include "core/components/common/layout/constants.h" #include "core/components_ng/base/view_stack_processor.h" -#include "core/components_ng/pattern/button/button_layout_property.h" -#include "core/components_ng/pattern/button/button_model_ng.h" -#include "core/components_ng/pattern/button/button_pattern.h" #include "core/components_ng/pattern/linear_layout/row_model_ng.h" -#include "core/components_ng/pattern/pattern.h" #include "core/components_ng/pattern/scrollable/scrollable.h" #include "core/components_ng/pattern/waterflow/water_flow_accessibility_property.h" #include "core/components_ng/pattern/waterflow/water_flow_event_hub.h" #include "core/components_ng/pattern/waterflow/water_flow_item_model_ng.h" #include "core/components_ng/pattern/waterflow/water_flow_item_node.h" #include "core/components_ng/pattern/waterflow/water_flow_item_pattern.h" -#include "core/components_ng/pattern/waterflow/water_flow_layout_algorithm.h" #include "core/components_ng/pattern/waterflow/water_flow_layout_property.h" #include "core/components_ng/pattern/waterflow/water_flow_model_ng.h" #include "core/components_ng/pattern/waterflow/water_flow_pattern.h" #include "core/components_ng/property/measure_property.h" #include "core/components_v2/inspector/inspector_constants.h" -#include "core/pipeline/base/constants.h" #undef private #undef protected namespace OHOS::Ace::NG { -namespace {} // namespace void WaterFlowTestNg::SetUpTestSuite() { @@ -114,6 +100,9 @@ void WaterFlowTestNg::Create(const std::function& callba RefPtr positionController = model.CreateScrollController(); RefPtr scrollBarProxy = model.CreateScrollBarProxy(); model.Create(); +#ifdef TEST_WATER_FLOW_SW + model.SetLayoutMode(WaterFlowLayoutMode::SLIDING_WINDOW); +#endif ViewAbstract::SetWidth(CalcLength(WATERFLOW_WIDTH)); ViewAbstract::SetHeight(CalcLength(WATERFLOW_HEIGHT)); model.SetScroller(positionController, scrollBarProxy); @@ -568,6 +557,9 @@ HWTEST_F(WaterFlowTestNg, WaterFlowTest003, TestSize.Level1) model.SetColumnsTemplate("1fr 1fr 1fr"); }); FlushLayoutTask(frameNode_); + auto& info = pattern_->layoutInfo_; + EXPECT_EQ(info->startIndex_, 0); + EXPECT_EQ(info->endIndex_, 4); EXPECT_TRUE(GetChildFrameNode(frameNode_, 3)->IsActive()); EXPECT_TRUE(GetChildFrameNode(frameNode_, 4)->IsActive()); EXPECT_FALSE(GetChildFrameNode(frameNode_, 5)->IsActive()); @@ -633,26 +625,6 @@ HWTEST_F(WaterFlowTestNg, WaterFlowTest006, TestSize.Level1) EXPECT_FALSE(GetChildFrameNode(frameNode_, 7)->IsActive()); } -/** - * @tc.name: WaterFlowTest007 - * @tc.desc: waterFlow with fixed column, scroll to index not fully showed at last line - * @tc.type: FUNC - */ -HWTEST_F(WaterFlowTestNg, WaterFlowTest007, TestSize.Level1) -{ - CreateWithItem([](WaterFlowModelNG model) { - ViewAbstract::SetWidth(CalcLength(WATERFLOW_WIDTH)); - ViewAbstract::SetHeight(CalcLength(200.f)); - model.SetColumnsTemplate("1fr 1fr 1fr"); - }); - pattern_->UpdateStartIndex(8); - FlushLayoutTask(frameNode_); - EXPECT_FALSE(GetChildFrameNode(frameNode_, 3)->IsActive()); - EXPECT_FALSE(GetChildFrameNode(frameNode_, 4)->IsActive()); - EXPECT_TRUE(GetChildFrameNode(frameNode_, 5)->IsActive()); - EXPECT_TRUE(GetChildFrameNode(frameNode_, 6)->IsActive()); -} - /** * @tc.name: WaterFlowTest008 * @tc.desc: waterFlow with fixed column, scroll to index not fully showed at first line @@ -738,13 +710,22 @@ HWTEST_F(WaterFlowTestNg, WaterFlowTest011, TestSize.Level1) EXPECT_TRUE(IsEqual(pattern_->GetOverScrollOffset(0.f), { 0, 0 })); EXPECT_TRUE(IsEqual(pattern_->GetOverScrollOffset(-ITEM_HEIGHT), { 0, -ITEM_HEIGHT })); - pattern_->layoutInfo_.startIndex_ = 0; - pattern_->layoutInfo_.currentOffset_ = ITEM_HEIGHT; + // enable overScroll + pattern_->SetEdgeEffect(EdgeEffect::SPRING); + pattern_->animateOverScroll_ = true; + pattern_->layoutInfo_->startIndex_ = 0; + // total offset = ITEM_HEIGHT + pattern_->layoutInfo_->UpdateOffset(WATERFLOW_HEIGHT); + frameNode_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); + FlushLayoutTask(frameNode_); EXPECT_TRUE(IsEqual(pattern_->GetOverScrollOffset(ITEM_HEIGHT), { ITEM_HEIGHT, 0 })); EXPECT_TRUE(IsEqual(pattern_->GetOverScrollOffset(0.f), { 0, 0 })); EXPECT_TRUE(IsEqual(pattern_->GetOverScrollOffset(-ITEM_HEIGHT * 2), { -ITEM_HEIGHT, 0 })); - pattern_->layoutInfo_.currentOffset_ = -ITEM_HEIGHT * 3; + // total offset = -ITEM_HEIGHT * 3 + pattern_->layoutInfo_->UpdateOffset(-ITEM_HEIGHT * 4); + frameNode_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); + FlushLayoutTask(frameNode_); EXPECT_TRUE(IsEqual(pattern_->GetOverScrollOffset(ITEM_HEIGHT * 2), { 0, 0 })); EXPECT_TRUE(IsEqual(pattern_->GetOverScrollOffset(0.f), { 0, 0 })); EXPECT_TRUE(IsEqual(pattern_->GetOverScrollOffset(-ITEM_HEIGHT), { 0, 0 })); @@ -765,11 +746,14 @@ HWTEST_F(WaterFlowTestNg, WaterFlowTest012, TestSize.Level1) model.SetColumnsTemplate("1fr 1fr 1fr 1fr"); CreateItem(TOTAL_LINE_NUMBER); }); - EXPECT_TRUE(pattern_->layoutInfo_.itemStart_); - EXPECT_TRUE(pattern_->layoutInfo_.itemEnd_); - EXPECT_TRUE(pattern_->layoutInfo_.offsetEnd_); - EXPECT_EQ(pattern_->layoutInfo_.maxHeight_, 500); - EXPECT_EQ(pattern_->layoutInfo_.lastMainSize_, 800); + EXPECT_TRUE(pattern_->layoutInfo_->itemStart_); + EXPECT_TRUE(pattern_->layoutInfo_->itemEnd_); + EXPECT_TRUE(pattern_->layoutInfo_->offsetEnd_); + auto info = AceType::DynamicCast(pattern_->layoutInfo_); + if (info) { + EXPECT_EQ(info->maxHeight_, 500); + } + EXPECT_EQ(pattern_->layoutInfo_->lastMainSize_, 800); EXPECT_TRUE(IsEqual(pattern_->GetOverScrollOffset(ITEM_HEIGHT), { 100, 100 })); EXPECT_TRUE(IsEqual(pattern_->GetOverScrollOffset(3 * ITEM_HEIGHT), { 300, 300 })); @@ -844,8 +828,8 @@ HWTEST_F(WaterFlowTestNg, WaterFlowPatternTest002, TestSize.Level1) model.SetLayoutDirection(FlexDirection::COLUMN_REVERSE); CreateItem(TOTAL_LINE_NUMBER * 4); }); - EXPECT_EQ(pattern_->layoutInfo_.startIndex_, 0); - EXPECT_EQ(pattern_->layoutInfo_.endIndex_, 21); + EXPECT_EQ(pattern_->layoutInfo_->startIndex_, 0); + EXPECT_EQ(pattern_->layoutInfo_->endIndex_, 21); /** * @tc.steps: step2. UpdateCurrentOffset -100.f. @@ -853,18 +837,18 @@ HWTEST_F(WaterFlowTestNg, WaterFlowPatternTest002, TestSize.Level1) */ HandleDrag(-100.f); pattern_->UpdateScrollBarOffset(); - EXPECT_EQ(pattern_->layoutInfo_.currentOffset_, 0.f); - EXPECT_EQ(pattern_->layoutInfo_.startIndex_, 0); - EXPECT_EQ(pattern_->layoutInfo_.endIndex_, 21); + EXPECT_EQ(pattern_->layoutInfo_->Offset(), 0.f); + EXPECT_EQ(pattern_->layoutInfo_->startIndex_, 0); + EXPECT_EQ(pattern_->layoutInfo_->endIndex_, 21); /** * @tc.steps: step3. UpdateCurrentOffset 200.f. * @tc.expected: startIndex_ = 5 endIndex_ = 27. */ HandleDrag(200.f); - EXPECT_EQ(pattern_->layoutInfo_.currentOffset_, -ITEM_HEIGHT * 2); - EXPECT_EQ(pattern_->layoutInfo_.startIndex_, 5); - EXPECT_EQ(pattern_->layoutInfo_.endIndex_, 27); + EXPECT_EQ(pattern_->layoutInfo_->Offset(), -ITEM_HEIGHT * 2); + EXPECT_EQ(pattern_->layoutInfo_->startIndex_, 5); + EXPECT_EQ(pattern_->layoutInfo_->endIndex_, 27); } /** @@ -975,7 +959,7 @@ HWTEST_F(WaterFlowTestNg, WaterFlowFooterTest001, TestSize.Level1) * @tc.steps: step1. Run footer func. * @tc.expected: The return_value is correct. */ - auto footerRect = GetChildRect(frameNode_, pattern_->layoutInfo_.footerIndex_); + auto footerRect = GetChildRect(frameNode_, pattern_->layoutInfo_->footerIndex_); EXPECT_FLOAT_EQ(footerRect.GetY(), 200.f); } @@ -1023,6 +1007,7 @@ HWTEST_F(WaterFlowTestNg, Callback001, TestSize.Level1) * @tc.expected: Trigger reachend */ UpdateCurrentOffset(-WATERFLOW_HEIGHT); + EXPECT_TRUE(pattern_->layoutInfo_->offsetEnd_); EXPECT_TRUE(isReachEndCalled); /** @@ -1057,12 +1042,14 @@ HWTEST_F(WaterFlowTestNg, Callback002, TestSize.Level1) EXPECT_EQ(effect->currentPositionCallback_(), 0); pattern_->SetAlwaysEnabled(true); + frameNode_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); FlushLayoutTask(frameNode_); EXPECT_EQ(effect->leadingCallback_(), 0); EXPECT_EQ(effect->initLeadingCallback_(), 0); EXPECT_EQ(effect->currentPositionCallback_(), 0); - pattern_->layoutInfo_.Reset(); + pattern_->layoutInfo_->Reset(); + frameNode_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); FlushLayoutTask(frameNode_); EXPECT_EQ(effect->leadingCallback_(), 0); EXPECT_EQ(effect->initLeadingCallback_(), 0); @@ -1088,22 +1075,23 @@ HWTEST_F(WaterFlowTestNg, WaterFlowLayoutInfoTest001, TestSize.Level1) } }); + auto info = AceType::DynamicCast(pattern_->layoutInfo_); /** * @tc.steps: Test IsAllCrossReachEnd function * @tc.expected: step1. Check whether the return value is correct. */ - auto reached = pattern_->layoutInfo_.IsAllCrossReachEnd(ITEM_HEIGHT); + auto reached = info->IsAllCrossReachEnd(ITEM_HEIGHT); EXPECT_TRUE(reached); - reached = pattern_->layoutInfo_.IsAllCrossReachEnd(WATERFLOW_HEIGHT); + reached = info->IsAllCrossReachEnd(WATERFLOW_HEIGHT); EXPECT_TRUE(reached); /** * @tc.steps: Test GetEndIndexByOffset function * @tc.expected: step2. Check whether the return value is correct. */ - auto offset = pattern_->layoutInfo_.GetEndIndexByOffset(0); + auto offset = info->GetEndIndexByOffset(0); EXPECT_EQ(0, offset); - offset = pattern_->layoutInfo_.GetEndIndexByOffset(-100.f); + offset = info->GetEndIndexByOffset(-100.f); EXPECT_EQ(1, offset); } @@ -1140,8 +1128,8 @@ HWTEST_F(WaterFlowTestNg, WaterFlowPattern_distributed001, TestSize.Level1) * @tc.steps: step2. get pattern . * @tc.expected: function ProvideRestoreInfo is called. */ - pattern_->layoutInfo_.startIndex_ = 1; - pattern_->layoutInfo_.storedOffset_ = 1.0f; + pattern_->layoutInfo_->startIndex_ = 1; + pattern_->layoutInfo_->storedOffset_ = 1.0f; std::string ret = pattern_->ProvideRestoreInfo(); /** @@ -1150,8 +1138,8 @@ HWTEST_F(WaterFlowTestNg, WaterFlowPattern_distributed001, TestSize.Level1) */ // std::string restoreInfo = R"({"beginIndex":1,"offset":1.1})"; pattern_->OnRestoreInfo(ret); - EXPECT_EQ(pattern_->layoutInfo_.jumpIndex_, 1); - EXPECT_DOUBLE_EQ(pattern_->layoutInfo_.restoreOffset_, 1.0f); + EXPECT_EQ(pattern_->layoutInfo_->jumpIndex_, 1); + EXPECT_DOUBLE_EQ(pattern_->layoutInfo_->restoreOffset_, 1.0f); } /** @@ -1271,13 +1259,14 @@ HWTEST_F(WaterFlowTestNg, WaterFlowLayoutInfoTest002, TestSize.Level1) * @tc.steps: Test GetStartMainPos and GetMainHeight * @tc.expected: step2. Check whether the return value is correct. */ - int32_t crossIndex = pattern_->layoutInfo_.items_[0].rbegin()->first; - int32_t itemIndex = pattern_->layoutInfo_.items_[0].rbegin()->second.rbegin()->first; - EXPECT_EQ(pattern_->layoutInfo_.GetStartMainPos(crossIndex + 1, itemIndex), 0.0f); - EXPECT_EQ(pattern_->layoutInfo_.GetMainHeight(crossIndex + 1, itemIndex), 0.0f); - - EXPECT_EQ(pattern_->layoutInfo_.GetStartMainPos(crossIndex, itemIndex + 1), 0.0f); - EXPECT_EQ(pattern_->layoutInfo_.GetMainHeight(crossIndex, itemIndex + 1), 0.0f); + auto info = AceType::DynamicCast(pattern_->layoutInfo_); + int32_t crossIndex = info->items_[0].rbegin()->first; + int32_t itemIndex = info->items_[0].rbegin()->second.rbegin()->first; + EXPECT_EQ(info->GetStartMainPos(crossIndex + 1, itemIndex), 0.0f); + EXPECT_EQ(info->GetMainHeight(crossIndex + 1, itemIndex), 0.0f); + + EXPECT_EQ(info->GetStartMainPos(crossIndex, itemIndex + 1), 0.0f); + EXPECT_EQ(info->GetMainHeight(crossIndex, itemIndex + 1), 0.0f); } /** @@ -1293,20 +1282,22 @@ HWTEST_F(WaterFlowTestNg, WaterFlowLayoutInfoTest003, TestSize.Level1) * @tc.steps: Test GetMainCount function * @tc.expected: step2. Check whether the size is correct. */ - std::size_t waterFlowItemsSize = pattern_->layoutInfo_.items_[0].size(); - int32_t mainCount = pattern_->layoutInfo_.GetMainCount(); + auto info = AceType::DynamicCast(pattern_->layoutInfo_); - int32_t index = pattern_->layoutInfo_.items_[0].rbegin()->first; - pattern_->layoutInfo_.items_[0][index + 1] = std::map>(); - EXPECT_EQ(pattern_->layoutInfo_.items_[0].size(), waterFlowItemsSize + 1); - EXPECT_EQ(pattern_->layoutInfo_.GetMainCount(), mainCount); + std::size_t waterFlowItemsSize = info->items_[0].size(); + int32_t mainCount = info->GetMainCount(); - auto lastItem = pattern_->layoutInfo_.items_[0].begin()->second.rbegin(); + int32_t index = info->items_[0].rbegin()->first; + info->items_[0][index + 1] = std::map>(); + EXPECT_EQ(info->items_[0].size(), waterFlowItemsSize + 1); + EXPECT_EQ(info->GetMainCount(), mainCount); + + auto lastItem = info->items_[0].begin()->second.rbegin(); float mainSize = lastItem->second.first + lastItem->second.second - 1.0f; - EXPECT_FALSE(pattern_->layoutInfo_.IsAllCrossReachEnd(mainSize)); + EXPECT_FALSE(info->IsAllCrossReachEnd(mainSize)); - pattern_->layoutInfo_.ClearCacheAfterIndex(index + 1); - EXPECT_EQ(pattern_->layoutInfo_.items_[0].size(), waterFlowItemsSize + 1); + info->ClearCacheAfterIndex(index + 1); + EXPECT_EQ(info->items_[0].size(), waterFlowItemsSize + 1); } /** @@ -1322,12 +1313,14 @@ HWTEST_F(WaterFlowTestNg, WaterFlowLayoutInfoTest004, TestSize.Level1) * @tc.steps: Test Reset function * @tc.expected: step2. Check whether the endIndex_ is correct. */ - int32_t resetFrom = pattern_->layoutInfo_.endIndex_; - pattern_->layoutInfo_.Reset(resetFrom + 1); - EXPECT_EQ(pattern_->layoutInfo_.endIndex_, resetFrom); + auto info = AceType::DynamicCast(pattern_->layoutInfo_); + + int32_t resetFrom = pattern_->layoutInfo_->endIndex_; + info->Reset(resetFrom + 1); + EXPECT_EQ(pattern_->layoutInfo_->endIndex_, resetFrom); - pattern_->layoutInfo_.Reset(resetFrom - 1); - EXPECT_EQ(pattern_->layoutInfo_.endIndex_, resetFrom); + info->Reset(resetFrom - 1); + EXPECT_EQ(pattern_->layoutInfo_->endIndex_, resetFrom); } /** @@ -1343,19 +1336,21 @@ HWTEST_F(WaterFlowTestNg, WaterFlowLayoutInfoTest005, TestSize.Level1) * @tc.steps: Test GetMaxMainHeight function * @tc.expected: step2. Check whether the return value is correct. */ - float maxMainHeight = pattern_->layoutInfo_.GetMaxMainHeight(); - int32_t crossIndex = pattern_->layoutInfo_.items_[0].rbegin()->first; - pattern_->layoutInfo_.items_[0][crossIndex + 1][0] = std::pair(1.0f, maxMainHeight); - pattern_->layoutInfo_.itemInfos_.clear(); - pattern_->layoutInfo_.endPosArray_.clear(); - EXPECT_EQ(pattern_->layoutInfo_.GetMaxMainHeight(), maxMainHeight + 1.0f); + auto info = AceType::DynamicCast(pattern_->layoutInfo_); + + float maxMainHeight = info->GetMaxMainHeight(); + int32_t crossIndex = info->items_[0].rbegin()->first; + info->items_[0][crossIndex + 1][0] = std::pair(1.0f, maxMainHeight); + info->itemInfos_.clear(); + info->endPosArray_.clear(); + EXPECT_EQ(info->GetMaxMainHeight(), maxMainHeight + 1.0f); /** * @tc.steps: Test GetCrossIndexForNextItem function * @tc.expected: step3. Check whether the return value is correct. */ - pattern_->layoutInfo_.items_[0][crossIndex + 1][1] = std::pair(0.0f, 0.0f); - FlowItemIndex position = pattern_->layoutInfo_.GetCrossIndexForNextItem(0); + info->items_[0][crossIndex + 1][1] = std::pair(0.0f, 0.0f); + FlowItemIndex position = info->GetCrossIndexForNextItem(0); EXPECT_EQ(position.crossIndex, crossIndex + 1); EXPECT_EQ(position.lastItemIndex, 1); } @@ -1413,7 +1408,7 @@ HWTEST_F(WaterFlowTestNg, MeasureForAnimation001, TestSize.Level1) * @tc.steps: step2. Get value from pattern_ -> LayoutInfo_ . * @tc.expected: return value(crossIndex) is not -1. */ - auto crossIndex = pattern_->layoutInfo_.GetCrossIndex(10); + auto crossIndex = pattern_->layoutInfo_->GetCrossIndex(10); EXPECT_FALSE(IsEqual(crossIndex, -1)); } @@ -1424,40 +1419,42 @@ HWTEST_F(WaterFlowTestNg, MeasureForAnimation001, TestSize.Level1) */ HWTEST_F(WaterFlowTestNg, ResetSections001, TestSize.Level1) { - Create([](WaterFlowModelNG model) { - ViewAbstract::SetWidth(CalcLength(400.0f)); - ViewAbstract::SetHeight(CalcLength(600.f)); - CreateItem(60); - }, false); + Create( + [](WaterFlowModelNG model) { + ViewAbstract::SetWidth(CalcLength(400.0f)); + ViewAbstract::SetHeight(CalcLength(600.f)); + CreateItem(60); + }, + false); auto secObj = pattern_->GetOrCreateWaterFlowSections(); secObj->ChangeData(0, 0, SECTION_5); MockPipelineContext::GetCurrent()->FlushBuildFinishCallbacks(); FlushLayoutTask(frameNode_); - auto& info = pattern_->layoutInfo_; + auto info = AceType::DynamicCast(pattern_->layoutInfo_); UpdateCurrentOffset(-205.0f); - EXPECT_EQ(info.currentOffset_, -205.0f); - EXPECT_EQ(info.startIndex_, 3); - EXPECT_EQ(info.endIndex_, 11); + EXPECT_EQ(info->Offset(), -205.0f); + EXPECT_EQ(info->startIndex_, 3); + EXPECT_EQ(info->endIndex_, 11); // fallback to layout without sections pattern_->ResetSections(); FlushLayoutTask(frameNode_); - EXPECT_EQ(info.currentOffset_, -205.0f); - EXPECT_EQ(info.startIndex_, 1); - EXPECT_EQ(info.endIndex_, 5); - EXPECT_EQ(info.GetCrossCount(), 1); + EXPECT_EQ(info->Offset(), -205.0f); + EXPECT_EQ(info->startIndex_, 1); + EXPECT_EQ(info->endIndex_, 5); + EXPECT_EQ(info->GetCrossCount(), 1); if (SystemProperties::WaterFlowUseSegmentedLayout()) { - EXPECT_EQ(info.segmentTails_.size(), 1); - EXPECT_EQ(info.margins_.size(), 1); + EXPECT_EQ(info->segmentTails_.size(), 1); + EXPECT_EQ(info->margins_.size(), 1); } else { - EXPECT_TRUE(info.segmentTails_.empty()); - EXPECT_TRUE(info.margins_.empty()); + EXPECT_TRUE(info->segmentTails_.empty()); + EXPECT_TRUE(info->margins_.empty()); } UpdateCurrentOffset(250.0f); - EXPECT_EQ(info.currentOffset_, 0.0f); - EXPECT_EQ(info.startIndex_, 0); - EXPECT_EQ(info.endIndex_, 3); + EXPECT_EQ(info->Offset(), 0.0f); + EXPECT_EQ(info->startIndex_, 0); + EXPECT_EQ(info->endIndex_, 3); } } // namespace OHOS::Ace::NG diff --git a/test/unittest/core/pattern/waterflow/water_flow_test_ng.h b/test/unittest/core/pattern/waterflow/water_flow_test_ng.h index 7302e92a0f6ae6d56628b7f1fd316db6da793df3..a9d7a62f8a647706b93abac863bcb51294b45b2b 100644 --- a/test/unittest/core/pattern/waterflow/water_flow_test_ng.h +++ b/test/unittest/core/pattern/waterflow/water_flow_test_ng.h @@ -52,7 +52,7 @@ protected: static void TearDownTestSuite(); void SetUp() override; void TearDown() override; - void GetInstance(); + virtual void GetInstance(); void Create(const std::function& callback = nullptr, bool flushLayout = true); void CreateWithItem(const std::function& callback = nullptr); diff --git a/test/unittest/core/pattern/waterflow/water_flow_top_down_test.cpp b/test/unittest/core/pattern/waterflow/water_flow_top_down_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8259313ca46fb3fc8c252fcf8bf5b081f7eebb7c --- /dev/null +++ b/test/unittest/core/pattern/waterflow/water_flow_top_down_test.cpp @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ \ No newline at end of file