1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "core/components_ng/pattern/grid/irregular/grid_layout_utils.h"
16
17 #include "core/components_ng/pattern/grid/grid_pattern.h"
18
19 namespace OHOS::Ace::NG {
GetItemSize(const GridLayoutInfo * info,const LayoutWrapper * wrapper,int32_t idx)20 GridItemSize GridLayoutUtils::GetItemSize(const GridLayoutInfo* info, const LayoutWrapper* wrapper, int32_t idx)
21 {
22 GridItemSize size { 1, 1 };
23 auto props = AceType::DynamicCast<GridLayoutProperty>(wrapper->GetLayoutProperty());
24 const auto& opts = *props->GetLayoutOptions();
25 if (opts.irregularIndexes.find(idx) != opts.irregularIndexes.end()) {
26 if (!opts.getSizeByIndex) {
27 // default irregular size = [1, full cross length]
28 size.rows = 1;
29 size.columns = info->crossCount_;
30 } else {
31 size = opts.getSizeByIndex(idx);
32 // assume [row] represents mainLength and [column] represents crossLength in this class, so flip sides if
33 // horizontal
34 if (info->axis_ == Axis::HORIZONTAL) {
35 std::swap(size.rows, size.columns);
36 }
37 }
38 }
39
40 // handle illegal size
41 if (size.columns > info->crossCount_) {
42 size.columns = info->crossCount_;
43 }
44 size.columns = std::max(1, size.columns);
45 size.rows = std::max(1, size.rows);
46 return size;
47 }
48
PreloadGridItems(const RefPtr<GridPattern> & pattern,std::list<GridPreloadItem> && items,const BuildGridItemCallback & buildCb)49 void GridLayoutUtils::PreloadGridItems(
50 const RefPtr<GridPattern>& pattern, std::list<GridPreloadItem>&& items, const BuildGridItemCallback& buildCb)
51 {
52 if (items.empty()) {
53 return;
54 }
55 CHECK_NULL_VOID(pattern);
56 const bool taskAdded = pattern->HasPreloadItemList();
57 pattern->SetPreloadItemList(std::move(items));
58 if (taskAdded) {
59 // task already in queue, only need to update item list
60 return;
61 }
62 PreloadGridItemsHelper(pattern, buildCb);
63 }
64
PreloadGridItemsHelper(const RefPtr<GridPattern> & pattern,const BuildGridItemCallback & buildCb)65 void GridLayoutUtils::PreloadGridItemsHelper(const RefPtr<GridPattern>& pattern, const BuildGridItemCallback& buildCb)
66 {
67 auto* context = pattern->GetContext();
68 CHECK_NULL_VOID(context);
69 context->AddPredictTask([weak = AceType::WeakClaim(AceType::RawPtr(pattern)), buildCb](int64_t deadline, bool _) {
70 ACE_SCOPED_TRACE("Grid preload items");
71 auto pattern = weak.Upgrade();
72 CHECK_NULL_VOID(pattern);
73 const auto items = pattern->MovePreloadItemList();
74 if (items.empty()) {
75 return;
76 }
77 auto it = items.begin();
78 if (pattern->IsPredictOutOfCacheRange(it->idx)) {
79 return;
80 }
81 bool needMarkDirty = false;
82 auto host = pattern->GetHost();
83 CHECK_NULL_VOID(host);
84 for (; it != items.end(); ++it) {
85 if (GetSysTimestamp() > deadline) {
86 break;
87 }
88 if (it->buildOnly) {
89 host->GetOrCreateChildByIndex(it->idx, false, true);
90 continue;
91 }
92 if (buildCb) {
93 needMarkDirty = buildCb(host, it->idx) || needMarkDirty;
94 }
95 }
96 if (needMarkDirty) {
97 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
98 }
99 if (it != items.end() && !needMarkDirty) {
100 pattern->SetPreloadItemList(std::list<GridPreloadItem>(it, items.end()));
101 PreloadGridItemsHelper(pattern, buildCb);
102 } else {
103 pattern->SetPreloadItemList({});
104 }
105 });
106 }
107 } // namespace OHOS::Ace::NG
108