mirror of
https://gitee.com/openharmony/arkui_ace_engine
synced 2024-11-30 10:43:03 +00:00
implement preload measure/layout
Signed-off-by: Tianer Zhou <zhoutianer@huawei.com> Change-Id: I2f7c83c88f4b0c745d4cfd4117c5c956a2027787
This commit is contained in:
parent
df131ffff4
commit
484c04f4fc
@ -13,6 +13,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "core/components_ng/pattern/grid/grid_layout_info.h"
|
||||
|
||||
#include <numeric>
|
||||
|
||||
#include "base/utils/utils.h"
|
||||
@ -701,6 +702,20 @@ MatIter GridLayoutInfo::FindInMatrix(int32_t index) const
|
||||
return SearchInReverse(gridMatrix_, index, crossCount_);
|
||||
}
|
||||
|
||||
std::pair<int32_t, int32_t> GridLayoutInfo::GetItemPos(int32_t itemIdx) const
|
||||
{
|
||||
auto it = FindInMatrix(itemIdx);
|
||||
if (it == gridMatrix_.end()) {
|
||||
return { -1, -1 };
|
||||
}
|
||||
for (auto col : it->second) {
|
||||
if (col.second == itemIdx) {
|
||||
return { col.first, it->first };
|
||||
}
|
||||
}
|
||||
return { -1, -1 };
|
||||
}
|
||||
|
||||
GridLayoutInfo::EndIndexInfo GridLayoutInfo::FindEndIdx(int32_t endLine) const
|
||||
{
|
||||
if (gridMatrix_.find(endLine) == gridMatrix_.end()) {
|
||||
@ -714,9 +729,7 @@ GridLayoutInfo::EndIndexInfo GridLayoutInfo::FindEndIdx(int32_t endLine) const
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
.itemIdx = 0, .y = 0, .x = 0
|
||||
};
|
||||
return { .itemIdx = 0, .y = 0, .x = 0 };
|
||||
}
|
||||
|
||||
void GridLayoutInfo::ClearMapsToEnd(int32_t idx)
|
||||
|
@ -188,6 +188,12 @@ struct GridLayoutInfo {
|
||||
*/
|
||||
std::map<int32_t, std::map<int32_t, int32_t>>::const_iterator FindInMatrix(int32_t index) const;
|
||||
|
||||
/**
|
||||
* @param itemIdx
|
||||
* @return position [col, row] of the item. [-1, -1] if item is not in matrix.
|
||||
*/
|
||||
std::pair<int32_t, int32_t> GetItemPos(int32_t itemIdx) const;
|
||||
|
||||
/**
|
||||
* @brief Tries to find the item between startMainLine and endMainLine.
|
||||
*
|
||||
|
@ -127,7 +127,13 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
GridLayoutInfo GetGridLayoutInfo() const
|
||||
const GridLayoutInfo& GetGridLayoutInfo() const
|
||||
{
|
||||
return gridLayoutInfo_;
|
||||
}
|
||||
|
||||
/* caution when using mutable reference */
|
||||
GridLayoutInfo& GetMutableLayoutInfo()
|
||||
{
|
||||
return gridLayoutInfo_;
|
||||
}
|
||||
|
@ -198,21 +198,19 @@ bool GridIrregularFiller::UpdateLength(float& len, float targetLen, int32_t& row
|
||||
return false;
|
||||
}
|
||||
|
||||
void GridIrregularFiller::MeasureItem(const FillParameters& params, int32_t itemIdx, int32_t col, int32_t row)
|
||||
LayoutConstraintF GridIrregularFiller::MeasureItem(const FillParameters& params, int32_t itemIdx, int32_t col, int32_t row)
|
||||
{
|
||||
auto child = wrapper_->GetOrCreateChildByIndex(itemIdx);
|
||||
CHECK_NULL_VOID(child);
|
||||
auto props = AceType::DynamicCast<GridLayoutProperty>(wrapper_->GetLayoutProperty());
|
||||
auto constraint = props->CreateChildConstraint();
|
||||
auto child = wrapper_->GetOrCreateChildByIndex(itemIdx);
|
||||
CHECK_NULL_RETURN(child, constraint);
|
||||
|
||||
const auto itemSize = GridLayoutUtils::GetItemSize(info_, wrapper_, itemIdx);
|
||||
// should cache child constraint result
|
||||
float crossLen = 0.0f;
|
||||
for (int32_t i = 0; i < itemSize.columns; ++i) {
|
||||
crossLen += params.crossLens[i + col];
|
||||
}
|
||||
crossLen += params.crossGap * (itemSize.columns - 1);
|
||||
|
||||
constraint.percentReference.SetCrossSize(crossLen, info_->axis_);
|
||||
if (info_->axis_ == Axis::VERTICAL) {
|
||||
constraint.maxSize = SizeF { crossLen, Infinity<float>() };
|
||||
@ -231,6 +229,7 @@ void GridIrregularFiller::MeasureItem(const FillParameters& params, int32_t item
|
||||
for (int32_t i = 0; i < itemSize.rows; ++i) {
|
||||
info_->lineHeightMap_[row + i] = std::max(info_->lineHeightMap_[row + i], heightPerRow);
|
||||
}
|
||||
return constraint;
|
||||
}
|
||||
|
||||
int32_t GridIrregularFiller::InitPosToLastItem(int32_t lineIdx)
|
||||
|
@ -125,6 +125,16 @@ public:
|
||||
*/
|
||||
void MeasureLineWithIrregulars(const FillParameters& params, int32_t line);
|
||||
|
||||
/**
|
||||
* @brief Measures a GridItem and updates the grid layout information.
|
||||
*
|
||||
* @param params The FillParameters object containing the fill parameters.
|
||||
* @param itemIdx The index of the GridItem.
|
||||
* @param col The column index where the item is being added.
|
||||
* @param row The row index where the item is being added.
|
||||
*/
|
||||
LayoutConstraintF MeasureItem(const FillParameters& params, int32_t itemIdx, int32_t col, int32_t row);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Fills one GridItem into the Grid.
|
||||
@ -144,16 +154,6 @@ private:
|
||||
*/
|
||||
bool UpdateLength(float& len, float targetLen, int32_t& row, int32_t rowBound, float mainGap) const;
|
||||
|
||||
/**
|
||||
* @brief Measures a GridItem at endIndex_ and updates the grid layout information.
|
||||
*
|
||||
* @param params The FillParameters object containing the fill parameters.
|
||||
* @param itemIdx The index of the GridItem.
|
||||
* @param col The column index where the item is being added.
|
||||
* @param row The row index where the item is being added.
|
||||
*/
|
||||
void MeasureItem(const FillParameters& params, int32_t itemIdx, int32_t col, int32_t row);
|
||||
|
||||
/**
|
||||
* @brief Initializes the position of the filler in the grid to GridLayoutInfo::startIndex_.
|
||||
*
|
||||
|
@ -55,7 +55,6 @@ void GridIrregularLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper)
|
||||
}
|
||||
|
||||
UpdateLayoutInfo();
|
||||
wrapper_->SetCacheCount(static_cast<int32_t>(props->GetCachedCountValue(1) * info_.crossCount_));
|
||||
}
|
||||
|
||||
void GridIrregularLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper)
|
||||
@ -72,25 +71,8 @@ void GridIrregularLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper)
|
||||
CHECK_NULL_VOID(props);
|
||||
const int32_t cacheCnt = props->GetCachedCountValue(1) * info.crossCount_;
|
||||
wrapper_->SetActiveChildRange(std::min(info.startIndex_, info.endIndex_), info.endIndex_, cacheCnt, cacheCnt);
|
||||
|
||||
std::list<int32_t> itemsToPreload;
|
||||
for (int32_t i = 1; i <= cacheCnt; ++i) {
|
||||
const int32_t l = info.startIndex_ - i;
|
||||
if (l >= 0 && !wrapper_->GetChildByIndex(l)) {
|
||||
itemsToPreload.push_back(l);
|
||||
}
|
||||
const int32_t r = info.endIndex_ + i;
|
||||
if (r < info.childrenCount_ && !wrapper_->GetChildByIndex(r)) {
|
||||
itemsToPreload.push_back(r);
|
||||
}
|
||||
}
|
||||
GridLayoutUtils::PreloadGridItems(wrapper_->GetHostNode()->GetPattern<GridPattern>(), std::move(itemsToPreload),
|
||||
[](const RefPtr<FrameNode>& host, int32_t itemIdx) {
|
||||
if (host) {
|
||||
host->GetOrCreateChildByIndex(itemIdx);
|
||||
};
|
||||
return false;
|
||||
});
|
||||
wrapper_->SetCacheCount(cacheCnt);
|
||||
PreloadItems(cacheCnt);
|
||||
}
|
||||
|
||||
float GridIrregularLayoutAlgorithm::MeasureSelf(const RefPtr<GridLayoutProperty>& props)
|
||||
@ -415,7 +397,7 @@ void GridIrregularLayoutAlgorithm::LayoutChildren(float mainOffset)
|
||||
if (itemIdx == 0 && (it->first > 0 || c > 0)) {
|
||||
continue;
|
||||
}
|
||||
auto child = wrapper_->GetOrCreateChildByIndex(itemIdx);
|
||||
auto child = wrapper_->GetChildByIndex(itemIdx);
|
||||
if (!child) {
|
||||
continue;
|
||||
}
|
||||
@ -474,6 +456,7 @@ int32_t GridIrregularLayoutAlgorithm::FindJumpLineIdx(int32_t jumpIdx)
|
||||
return jumpLine;
|
||||
}
|
||||
|
||||
using FillParams = GridIrregularFiller::FillParameters;
|
||||
void GridIrregularLayoutAlgorithm::PrepareLineHeight(float mainSize, int32_t& jumpLineIdx)
|
||||
{
|
||||
/* When mainSize can't be filled, adjust parameters and call function again. The maximum length of
|
||||
@ -482,7 +465,7 @@ void GridIrregularLayoutAlgorithm::PrepareLineHeight(float mainSize, int32_t& ju
|
||||
GridIrregularFiller filler(&info_, wrapper_);
|
||||
switch (info_.scrollAlign_) {
|
||||
case ScrollAlign::START: {
|
||||
const GridIrregularFiller::FillParameters params { crossLens_, crossGap_, mainGap_ };
|
||||
const FillParams params { crossLens_, crossGap_, mainGap_ };
|
||||
// call this to ensure irregular items on the first line are measured, not skipped
|
||||
filler.MeasureLineWithIrregulars(params, jumpLineIdx);
|
||||
|
||||
@ -570,7 +553,7 @@ int32_t GridIrregularLayoutAlgorithm::SkipLinesBackward() const
|
||||
void GridIrregularLayoutAlgorithm::MeasureToTarget()
|
||||
{
|
||||
GridIrregularFiller filler(&info_, wrapper_);
|
||||
GridIrregularFiller::FillParameters param { crossLens_, crossGap_, mainGap_ };
|
||||
FillParams param { crossLens_, crossGap_, mainGap_ };
|
||||
if (info_.targetIndex_ < info_.startIndex_) {
|
||||
auto it = info_.FindInMatrix(*info_.targetIndex_);
|
||||
filler.MeasureBackwardToTarget(param, it->first, info_.startMainLineIndex_);
|
||||
@ -590,4 +573,41 @@ bool GridIrregularLayoutAlgorithm::IsIrregularLine(int32_t lineIndex) const
|
||||
return std::any_of(line->second.begin(), line->second.end(),
|
||||
[opts](const auto& item) { return opts.irregularIndexes.count(std::abs(item.second)); });
|
||||
}
|
||||
|
||||
void GridIrregularLayoutAlgorithm::PreloadItems(int32_t cacheCnt)
|
||||
{
|
||||
std::list<int32_t> itemsToPreload;
|
||||
for (int32_t i = 1; i <= cacheCnt; ++i) {
|
||||
const int32_t l = info_.startIndex_ - i;
|
||||
if (l >= 0 && !wrapper_->GetChildByIndex(l)) {
|
||||
itemsToPreload.push_back(l);
|
||||
}
|
||||
const int32_t r = info_.endIndex_ + i;
|
||||
if (r < info_.childrenCount_ && !wrapper_->GetChildByIndex(r)) {
|
||||
itemsToPreload.push_back(r);
|
||||
}
|
||||
}
|
||||
|
||||
GridIrregularFiller filler(&info_, wrapper_);
|
||||
filler.FillMatrixOnly(std::min(info_.childrenCount_, info_.endIndex_ + cacheCnt));
|
||||
|
||||
GridLayoutUtils::PreloadGridItems(wrapper_->GetHostNode()->GetPattern<GridPattern>(), std::move(itemsToPreload),
|
||||
[crossLens = crossLens_, crossGap = crossGap_, mainGap = mainGap_](
|
||||
const RefPtr<FrameNode>& host, int32_t itemIdx) {
|
||||
CHECK_NULL_RETURN(host, false);
|
||||
auto pattern = host->GetPattern<GridPattern>();
|
||||
CHECK_NULL_RETURN(pattern, false);
|
||||
auto& info = pattern->GetMutableLayoutInfo();
|
||||
GridIrregularFiller filler(&info, RawPtr(host));
|
||||
const auto pos = info.GetItemPos(itemIdx);
|
||||
auto constraint = filler.MeasureItem(GridIrregularFiller::FillParameters { crossLens, crossGap, mainGap }, itemIdx,
|
||||
pos.first, pos.second);
|
||||
|
||||
auto item = DynamicCast<FrameNode>(host->GetChildByIndex(itemIdx));
|
||||
CHECK_NULL_RETURN(item, false);
|
||||
item->GetGeometryNode()->SetParentLayoutConstraint(constraint);
|
||||
FrameNode::ProcessOffscreenNode(item);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
} // namespace OHOS::Ace::NG
|
||||
|
@ -144,6 +144,8 @@ private:
|
||||
|
||||
bool IsIrregularLine(int32_t lineIndex) const override;
|
||||
|
||||
void PreloadItems(int32_t cacheCnt);
|
||||
|
||||
GridLayoutInfo& info_;
|
||||
LayoutWrapper* wrapper_ = nullptr;
|
||||
|
||||
|
@ -563,6 +563,8 @@ HWTEST_F(GridLayoutRangeTest, Cache001, TestSize.Level1)
|
||||
EXPECT_TRUE(pattern_->preloadItemList_.empty());
|
||||
for (const int32_t i : preloadList) {
|
||||
EXPECT_TRUE(frameNode_->GetChildByIndex(i));
|
||||
EXPECT_EQ(GetChildWidth(frameNode_, i), (GRID_WIDTH - 20.0f) / 3.0f);
|
||||
EXPECT_EQ(GetChildHeight(frameNode_, i), 200.0f);
|
||||
}
|
||||
pattern_->ScrollToIndex(49);
|
||||
FlushLayoutTask(frameNode_);
|
||||
|
Loading…
Reference in New Issue
Block a user