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_layout_info.h"
18 #include "core/components_ng/pattern/grid/grid_layout_property.h"
19 #include "core/components_ng/pattern/grid/grid_pattern.h"
20
21 namespace OHOS::Ace::NG {
GetItemSize(const GridLayoutInfo * info,const LayoutWrapper * wrapper,int32_t idx)22 GridItemSize GridLayoutUtils::GetItemSize(const GridLayoutInfo* info, const LayoutWrapper* wrapper, int32_t idx)
23 {
24 GridItemSize size { 1, 1 };
25 auto props = AceType::DynamicCast<GridLayoutProperty>(wrapper->GetLayoutProperty());
26 const auto& opts = *props->GetLayoutOptions();
27 if (opts.irregularIndexes.find(idx) != opts.irregularIndexes.end()) {
28 if (!opts.getSizeByIndex) {
29 // default irregular size = [1, full cross length]
30 size.rows = 1;
31 size.columns = info->crossCount_;
32 } else {
33 size = opts.getSizeByIndex(idx);
34 // assume [row] represents mainLength and [column] represents crossLength in this class, so flip sides if
35 // horizontal
36 if (info->axis_ == Axis::HORIZONTAL) {
37 std::swap(size.rows, size.columns);
38 }
39 }
40 }
41
42 // handle illegal size
43 if (size.columns > info->crossCount_) {
44 size.columns = info->crossCount_;
45 }
46 size.columns = std::max(1, size.columns);
47 size.rows = std::max(1, size.rows);
48 return size;
49 }
50
PreloadGridItems(const RefPtr<GridPattern> & pattern,std::list<GridPreloadItem> && items,const BuildGridItemCallback & buildCb)51 void GridLayoutUtils::PreloadGridItems(
52 const RefPtr<GridPattern>& pattern, std::list<GridPreloadItem>&& items, const BuildGridItemCallback& buildCb)
53 {
54 if (items.empty()) {
55 return;
56 }
57 CHECK_NULL_VOID(pattern);
58 const bool taskAdded = pattern->HasPreloadItemList();
59 pattern->SetPreloadItemList(std::move(items));
60 if (taskAdded) {
61 // task already in queue, only need to update item list
62 return;
63 }
64 PreloadGridItemsHelper(pattern, buildCb);
65 }
66
PreloadGridItemsHelper(const RefPtr<GridPattern> & pattern,const BuildGridItemCallback & buildCb)67 void GridLayoutUtils::PreloadGridItemsHelper(const RefPtr<GridPattern>& pattern, const BuildGridItemCallback& buildCb)
68 {
69 auto context = PipelineContext::GetCurrentContextSafely();
70 CHECK_NULL_VOID(context);
71 context->AddPredictTask([weak = AceType::WeakClaim(AceType::RawPtr(pattern)), buildCb](int64_t deadline, bool _) {
72 ACE_SCOPED_TRACE("Grid preload items");
73 auto pattern = weak.Upgrade();
74 CHECK_NULL_VOID(pattern);
75 const auto items = pattern->MovePreloadItemList();
76 if (items.empty()) {
77 return;
78 }
79 auto it = items.begin();
80 if (pattern->IsPredictOutOfRange(it->idx)) {
81 return;
82 }
83 bool needMarkDirty = false;
84 auto host = pattern->GetHost();
85 CHECK_NULL_VOID(host);
86 for (; it != items.end(); ++it) {
87 if (GetSysTimestamp() > deadline) {
88 break;
89 }
90 if (it->buildOnly) {
91 host->GetOrCreateChildByIndex(it->idx, false, true);
92 continue;
93 }
94 if (buildCb) {
95 needMarkDirty = buildCb(host, it->idx) || needMarkDirty;
96 }
97 }
98 if (needMarkDirty) {
99 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
100 }
101 if (it != items.end() && !needMarkDirty) {
102 pattern->SetPreloadItemList(std::list<GridPreloadItem>(it, items.end()));
103 PreloadGridItemsHelper(pattern, buildCb);
104 } else {
105 pattern->SetPreloadItemList({});
106 }
107 });
108 }
109 } // namespace OHOS::Ace::NG
110