!4484 【UI组件重构】grid组件支持columnsTemplate、rowsTemplate以及grid item组件不带任何属性

Merge pull request !4484 from chenxuankai1/poor_grid_and_grid_item
This commit is contained in:
openharmony_ci 2022-09-04 12:12:28 +00:00 committed by Gitee
commit cdb2755ed7
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
13 changed files with 963 additions and 6 deletions

View File

@ -18,6 +18,9 @@
#include "bridge/declarative_frontend/jsview/js_view_common_def.h"
#include "core/common/ace_application_info.h"
#include "core/common/container.h"
#include "core/components_ng/base/view_abstract.h"
#include "core/components_ng/base/view_stack_processor.h"
#include "core/components_ng/pattern/grid/grid_view.h"
#include "core/components_v2/grid/render_grid_scroll.h"
#include "frameworks/bridge/declarative_frontend/engine/functions/js_drag_function.h"
#include "frameworks/bridge/declarative_frontend/jsview/js_interactable_view.h"
@ -34,8 +37,20 @@ const std::vector<FlexDirection> LAYOUT_DIRECTION = { FlexDirection::ROW, FlexDi
} // namespace
#define SET_PROP_FOR_NG(propName, propType, propValue) \
do { \
if (Container::IsCurrentUseNewPipeline()) { \
NG::GridView::Set##propName(static_cast<propType>(propValue)); \
return; \
} \
} while (0);
void JSGrid::Create(const JSCallbackInfo& info)
{
if (Container::IsCurrentUseNewPipeline()) {
NG::GridView::Create();
return;
}
LOGD("Create component: Grid");
std::list<RefPtr<OHOS::Ace::Component>> componentChildren;
@ -69,6 +84,10 @@ void JSGrid::Create(const JSCallbackInfo& info)
void JSGrid::PopGrid(const JSCallbackInfo& info)
{
if (Container::IsCurrentUseNewPipeline()) {
NG::ViewStackProcessor::GetInstance()->PopContainer();
return;
}
ViewStackProcessor::GetInstance()->PopGrid();
}
@ -89,6 +108,7 @@ void JSGrid::UseProxy(const JSCallbackInfo& args)
void JSGrid::SetColumnsTemplate(const std::string& value)
{
SET_PROP_FOR_NG(ColumnsTemplate, std::string, value);
auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
auto grid = AceType::DynamicCast<GridLayoutComponent>(component);
if (grid) {
@ -98,6 +118,7 @@ void JSGrid::SetColumnsTemplate(const std::string& value)
void JSGrid::SetRowsTemplate(const std::string& value)
{
SET_PROP_FOR_NG(RowsTemplate, std::string, value);
auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
auto grid = AceType::DynamicCast<GridLayoutComponent>(component);
if (grid) {
@ -145,6 +166,19 @@ void JSGrid::JsGridHeight(const JSCallbackInfo& info)
LOGE("The arg is wrong, it is supposed to have at least 1 argument");
return;
}
if (Container::IsCurrentUseNewPipeline()) {
Dimension value;
if (!ParseJsDimensionVp(info[0], value)) {
LOGE("parse height fail for grid, please check.");
return;
}
if (LessNotEqual(value.Value(), 0.0)) {
value.SetValue(0.0);
}
NG::ViewAbstract::SetHeight(NG::CalcLength(value));
return;
}
JSViewAbstract::JsHeight(info);
Dimension height;
if (!ParseJsDimensionVp(info[0], height)) {
@ -157,7 +191,6 @@ void JSGrid::JsGridHeight(const JSCallbackInfo& info)
}
}
void JSGrid::JsOnScrollIndex(const JSCallbackInfo& info)
{
if (info[0]->IsFunction()) {
@ -367,7 +400,7 @@ void JSGrid::JsOnGridDragEnter(const JSCallbackInfo& info)
RefPtr<JsDragFunction> jsOnDragEnterFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
auto onItemDragEnterId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEnterFunc)](
const ItemDragInfo& dragInfo) {
const ItemDragInfo& dragInfo) {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
ACE_SCORING_EVENT("Grid.onItemDragEnter");
func->ItemDragEnterExecute(dragInfo);
@ -389,7 +422,7 @@ void JSGrid::JsOnGridDragMove(const JSCallbackInfo& info)
RefPtr<JsDragFunction> jsOnDragMoveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
auto onItemDragMoveId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragMoveFunc)](
const ItemDragInfo& dragInfo, int32_t itemIndex, int32_t insertIndex) {
const ItemDragInfo& dragInfo, int32_t itemIndex, int32_t insertIndex) {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
ACE_SCORING_EVENT("Grid.onItemDragMove");
func->ItemDragMoveExecute(dragInfo, itemIndex, insertIndex);
@ -411,7 +444,7 @@ void JSGrid::JsOnGridDragLeave(const JSCallbackInfo& info)
RefPtr<JsDragFunction> jsOnDragLeaveFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
auto onItemDragLeaveId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragLeaveFunc)](
const ItemDragInfo& dragInfo, int32_t itemIndex) {
const ItemDragInfo& dragInfo, int32_t itemIndex) {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
ACE_SCORING_EVENT("Grid.onItemDragLeave");
func->ItemDragLeaveExecute(dragInfo, itemIndex);
@ -433,7 +466,7 @@ void JSGrid::JsOnGridDragStart(const JSCallbackInfo& info)
RefPtr<JsDragFunction> jsOnDragFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
auto onItemDragStartId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragFunc)](
const ItemDragInfo& dragInfo, int32_t itemIndex) -> RefPtr<Component> {
const ItemDragInfo& dragInfo, int32_t itemIndex) -> RefPtr<Component> {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, nullptr);
auto ret = func->ItemDragStartExecute(dragInfo, itemIndex);
if (!ret->IsObject()) {
@ -482,7 +515,7 @@ void JSGrid::JsOnGridDrop(const JSCallbackInfo& info)
RefPtr<JsDragFunction> jsOnDropFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
auto onItemDropId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDropFunc)](
const ItemDragInfo& dragInfo, int32_t itemIndex, int32_t insertIndex, bool isSuccess) {
const ItemDragInfo& dragInfo, int32_t itemIndex, int32_t insertIndex, bool isSuccess) {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
ACE_SCORING_EVENT("Grid.onItemDrop");
func->ItemDropExecute(dragInfo, itemIndex, insertIndex, isSuccess);

View File

@ -16,6 +16,7 @@
#include "frameworks/bridge/declarative_frontend/jsview/js_grid_item.h"
#include "core/common/container.h"
#include "core/components_ng/pattern/grid/grid_item_view.h"
#include "frameworks/bridge/declarative_frontend/engine/functions/js_mouse_function.h"
#include "frameworks/bridge/declarative_frontend/view_stack_processor.h"
#include "frameworks/core/pipeline/base/element_register.h"
@ -24,6 +25,10 @@ namespace OHOS::Ace::Framework {
void JSGridItem::Create(const JSCallbackInfo& args)
{
if (Container::IsCurrentUseNewPipeline()) {
NG::GridItemView::Create();
return;
}
auto container = Container::Current();
if (!container) {
LOGE("fail to get container");

View File

@ -27,6 +27,10 @@ build_component_ng("pattern_ng") {
"divider/divider_view.cpp",
"flex/flex_layout_algorithm.cpp",
"flex/flex_view.cpp",
"grid/grid_item_view.cpp",
"grid/grid_layout_algorithm.cpp",
"grid/grid_pattern.cpp",
"grid/grid_view.cpp",
"image/image_layout_algorithm.cpp",
"image/image_pattern.cpp",
"image/image_view.cpp",

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2022 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_PATTERNS_GRID_GRID_ITEM_PATTERN_H
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_GRID_GRID_ITEM_PATTERN_H
#include "base/memory/referenced.h"
#include "base/utils/noncopyable.h"
#include "core/components_ng/pattern/pattern.h"
namespace OHOS::Ace::NG {
class ACE_EXPORT GridItemPattern : public Pattern {
DECLARE_ACE_TYPE(GridItemPattern, Pattern);
public:
GridItemPattern() = default;
~GridItemPattern() override = default;
bool IsAtomicNode() const override
{
return false;
}
private:
ACE_DISALLOW_COPY_AND_MOVE(GridItemPattern);
};
} // namespace OHOS::Ace::NG
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_GRID_GRID_ITEM_PATTERN_H

View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2022 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 "core/components_ng/pattern/grid/grid_item_view.h"
#include "core/components_ng/base/view_stack_processor.h"
#include "core/components_ng/pattern/grid/grid_item_pattern.h"
#include "core/components_v2/inspector/inspector_constants.h"
namespace OHOS::Ace::NG {
void GridItemView::Create()
{
auto* stack = ViewStackProcessor::GetInstance();
auto nodeId = stack->ClaimNodeId();
auto frameNode = FrameNode::GetOrCreateFrameNode(
V2::GRID_ITEM_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<GridItemPattern>(); });
stack->Push(frameNode);
}
} // namespace OHOS::Ace::NG

View File

@ -0,0 +1,28 @@
/*
* Copyright (c) 2022 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_PATTERNS_GRID_GRID_ITEM_VIEW_H
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_GRID_GRID_ITEM_VIEW_H
#include "base/utils/macros.h"
namespace OHOS::Ace::NG {
class ACE_EXPORT GridItemView {
public:
static void Create();
};
} // namespace OHOS::Ace::NG
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_GRID_GRID_ITEM_VIEW_H

View File

@ -0,0 +1,397 @@
/*
* Copyright (c) 2022 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 "core/components_ng/pattern/grid/grid_layout_algorithm.h"
#include "base/geometry/ng/offset_t.h"
#include "base/utils/utils.h"
#include "core/components_ng/property/layout_constraint.h"
#include "core/components_ng/property/measure_utils.h"
#ifdef NG_BUILD
#include "ace_shell/shell/common/window_manager.h"
#endif
namespace OHOS::Ace::NG {
void GridLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper)
{
auto gridLayoutProperty = AceType::DynamicCast<GridLayoutProperty>(layoutWrapper->GetLayoutProperty());
CHECK_NULL_VOID(gridLayoutProperty);
// Step1: Decide size of Grid
Axis axis = gridLayoutInfo_.axis_;
auto idealSize = CreateIdealSize(
gridLayoutProperty->GetLayoutConstraint().value(), axis, gridLayoutProperty->GetMeasureType(), true);
if (GreatOrEqual(GetMainAxisSize(idealSize, axis), Infinity<float>())) {
// TODO: use total height of all children as grid's main size when main size of ideal is infinite
LOGE("size of main axis value is infinity, please check");
return;
}
layoutWrapper->GetGeometryNode()->SetFrameSize(idealSize);
MinusPaddingToSize(gridLayoutProperty->CreatePaddingAndBorder(), idealSize);
// Step2: Measure children that can be displayed in viewport of Grid
float mainSize = GetMainAxisSize(idealSize, axis);
float crossSize = GetCrossAxisSize(idealSize, axis);
FillGridViewportAndMeasureChildren(mainSize, crossSize, gridLayoutProperty, layoutWrapper);
StripItemsOutOfViewport();
layoutWrapper->SetForceSyncRenderTree();
}
void GridLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper)
{
auto gridLayoutProperty = AceType::DynamicCast<GridLayoutProperty>(layoutWrapper->GetLayoutProperty());
CHECK_NULL_VOID(gridLayoutProperty);
auto size = layoutWrapper->GetGeometryNode()->GetFrameSize();
auto padding = layoutWrapper->GetLayoutProperty()->CreatePaddingAndBorder();
MinusPaddingToSize(padding, size);
auto childFrameOffset = OffsetF(padding.left.value_or(0.0f), padding.top.value_or(0.0f));
childFrameOffset += gridLayoutProperty->IsVertical() ? OffsetF(0.0f, gridLayoutInfo_.currentOffset_)
: OffsetF(gridLayoutInfo_.currentOffset_, 0.0f);
auto parentOffset =
layoutWrapper->GetGeometryNode()->GetParentGlobalOffset() + layoutWrapper->GetGeometryNode()->GetFrameOffset();
float crossFrWidth = GetCrossAxisSize(size, gridLayoutInfo_.axis_) / static_cast<float>(crossCount_);
// For e.g, when a vertical grid has two [GridItem] in first row, [gridMatrix_] is like {[0: {[0: 1fr], [1: 2fr]}]}
// TODO: Support horizontal Grid
float prevLineHeight = 0.0f;
for (const auto& line : gridLayoutInfo_.gridMatrix_) {
auto offset = childFrameOffset + OffsetF(0.0, prevLineHeight);
if (line.second.empty()) {
LOGE("line %{public}d should not be empty, please check.", line.first);
break;
}
float prevItemCrossSize = 0.0f;
for (auto iter = line.second.begin(); iter != line.second.end(); iter++) {
offset +=
gridLayoutProperty->IsVertical() ? OffsetF(prevItemCrossSize, 0.0) : OffsetF(0.0, prevItemCrossSize);
auto wrapper = layoutWrapper->GetOrCreateChildByIndex(iter->first);
if (!wrapper) {
LOGE("item wrapper of index: %{public}d is null, please check.", iter->first);
continue;
}
wrapper->GetGeometryNode()->SetFrameOffset(offset);
wrapper->Layout(parentOffset);
prevItemCrossSize = static_cast<float>(iter->second) * crossFrWidth;
}
prevLineHeight += gridLayoutInfo_.lineHeightMap_[line.first];
}
}
void GridLayoutAlgorithm::FillGridViewportAndMeasureChildren(
float mainSize, float crossSize, const RefPtr<GridLayoutProperty>& gridLayoutProperty, LayoutWrapper* layoutWrapper)
{
float mainLength = gridLayoutInfo_.currentOffset_;
// Step1: Measure [GridItem] that has been recorded to [gridMatrix_]
MeasureRecordedItems(mainSize, crossSize, gridLayoutProperty, layoutWrapper, mainLength);
// Step2: When done measure items in record, request new items to fill blank at end
FillBlankAtEnd(mainSize, crossSize, gridLayoutProperty, layoutWrapper, mainLength);
if (gridLayoutInfo_.reachEnd_) { // If it reaches end when [FillBlankAtEnd], modify [currentOffset_]
ModifyCurrentOffsetWhenReachEnd(mainSize);
return;
}
// Step3: Check if need to fill blank at start (in situation of grid items moving down)
FillBlankAtStart(mainSize, crossSize, gridLayoutProperty, layoutWrapper, mainLength);
if (gridLayoutInfo_.reachStart_) {
gridLayoutInfo_.currentOffset_ = 0.0;
gridLayoutInfo_.prevOffset_ = 0.0;
}
}
void GridLayoutAlgorithm::FillBlankAtStart(float mainSize, float crossSize,
const RefPtr<GridLayoutProperty>& gridLayoutProperty, LayoutWrapper* layoutWrapper, float& mainLength)
{
if (LessOrEqual(
gridLayoutInfo_.currentOffset_, 0.0)) { // If [currentOffset_] is none-positive, it means no blank at start
return;
}
auto blankAtStart = gridLayoutInfo_.currentOffset_;
while (GreatNotEqual(blankAtStart, 0.0)) {
float lineHeight = FillNewLineForward(crossSize, mainSize, gridLayoutProperty, layoutWrapper);
if (GreatNotEqual(lineHeight, 0.0)) {
gridLayoutInfo_.lineHeightMap_[gridLayoutInfo_.startMainLineIndex_] = lineHeight;
blankAtStart -= lineHeight;
continue;
}
gridLayoutInfo_.reachStart_ = true;
break;
}
gridLayoutInfo_.currentOffset_ = blankAtStart;
gridLayoutInfo_.prevOffset_ = gridLayoutInfo_.currentOffset_;
}
// When a moving up event comes, the [currrentOffset_] may have been reduced too much than the items really need to
// be moved up, so we need to modify [currrentOffset_] accrording to previous position.
void GridLayoutAlgorithm::ModifyCurrentOffsetWhenReachEnd(float mainSize)
{
// Step1. Calculate total length of all items in viewport. [lengthOfItemsInViewport] must be greater than or equal
// to viewport height
float lengthOfItemsInViewport = 0.0f;
for (auto i = gridLayoutInfo_.startMainLineIndex_; i <= gridLayoutInfo_.endMainLineIndex_; i++) {
lengthOfItemsInViewport += gridLayoutInfo_.lineHeightMap_[i];
}
// Step2. Calculate real offset that items can only be moved up by.
float realOffsetToMoveUp =
lengthOfItemsInViewport - mainSize + gridLayoutInfo_.prevOffset_; // Hint: [prevOffset_] is a non-positive value
// Step3. modify [currentOffset_]
gridLayoutInfo_.currentOffset_ = gridLayoutInfo_.prevOffset_ - realOffsetToMoveUp;
gridLayoutInfo_.prevOffset_ = gridLayoutInfo_.currentOffset_;
}
void GridLayoutAlgorithm::FillBlankAtEnd(float mainSize, float crossSize,
const RefPtr<GridLayoutProperty>& gridLayoutProperty, LayoutWrapper* layoutWrapper, float& mainLength)
{
// When [mainLength] is still less than [mainSize], do [FillNewLineBackward] repeatedly until filling up the lower
// part of the viewport
while (LessNotEqual(mainLength, mainSize)) {
float lineHeight = FillNewLineBackward(crossSize, mainSize, gridLayoutProperty, layoutWrapper);
if (GreatNotEqual(lineHeight, 0.0)) {
mainLength += lineHeight;
continue;
}
gridLayoutInfo_.reachEnd_ = true;
break;
};
}
void GridLayoutAlgorithm::MeasureRecordedItems(float mainSize, float crossSize,
const RefPtr<GridLayoutProperty>& gridLayoutProperty, LayoutWrapper* layoutWrapper, float& mainLength)
{
currentMainLineIndex_ = gridLayoutInfo_.startMainLineIndex_ - 1;
bool runOutOfRecord = false;
while (LessNotEqual(mainLength, mainSize)) { // Measure grid items row by row
auto gridMatrixIter = gridLayoutInfo_.gridMatrix_.find(++currentMainLineIndex_);
if (gridMatrixIter == gridLayoutInfo_.gridMatrix_.end()) {
runOutOfRecord = true;
break; // If [gridMatrix_] does not contain record of line [currentMainLineIndex_], do [FillNewLineBackward]
}
float lineHeight = -1.0f;
int32_t currentIndex = 0;
// One record is like [0: 1fr] or [1: 2fr]
for (const auto& gridItemRecord : gridMatrixIter->second) {
currentIndex = gridItemRecord.first;
auto itemWrapper = layoutWrapper->GetOrCreateChildByIndex(currentIndex);
if (!itemWrapper) {
LOGE("GridItem wrapper of index %{public}u null", currentIndex);
break;
}
itemWrapper->Measure(
MakeMeasureConstraintForGridItem(mainSize, crossSize, gridItemRecord.second, gridLayoutProperty));
auto itemSize = itemWrapper->GetGeometryNode()->GetFrameSize();
lineHeight = std::max(GetMainAxisSize(itemSize, gridLayoutInfo_.axis_), lineHeight);
// Record end index. When fill new line, the [endIndex_] will be the first item index to request
gridLayoutInfo_.endIndex_ = gridItemRecord.first;
}
if (lineHeight > 0) { // Means at least one item has been measured
gridLayoutInfo_.lineHeightMap_[currentMainLineIndex_] = lineHeight;
mainLength += lineHeight;
}
// If a line moves up out of viewport, update [startIndex_], [currentOffset_] and [startMainLineIndex_], and
// delete record in [gridMatrix_] and [lineHeightMap_]. The strip operation of [gridMatrix_] and
// [lineHeightMap_] will take place in [StripItemsOutOfViewport].
// TODO: inactive items
if (LessOrEqual(mainLength, 0.0)) {
gridLayoutInfo_.currentOffset_ = mainLength;
gridLayoutInfo_.startMainLineIndex_ = currentMainLineIndex_ + 1;
gridLayoutInfo_.startIndex_ = currentIndex + 1;
}
}
// Case 1. if this while-loop breaks due to running out of records, the [currentMainLineIndex_] is larger by 1 than
// real main line index, so reduce 1.
// Case 2. if this while-loop stops due to false result of [LessNotEqual(mainLength, mainSize)], the
// [currentMainLineIndex_] is exactly the real main line index. Update [endMainLineIndex_] when the recorded items
// are done measured.
gridLayoutInfo_.endMainLineIndex_ = runOutOfRecord ? --currentMainLineIndex_ : currentMainLineIndex_;
}
float GridLayoutAlgorithm::FillNewLineForward(
float crossSize, float mainSize, const RefPtr<GridLayoutProperty>& gridLayoutProperty, LayoutWrapper* layoutWrapper)
{
// To make the code more convinient to read, we name a param in situation of vertical, for exacmple:
// 1. [lineHight] means height of a row when the Grid is vertical;
// 2. [lineHight] means width of a column when the Grid is horizontal;
// Other params are also named according to this principle.
float lineHeight = -1.0f;
float measuredItemsWidth = 0.0f;
auto currentIndex = gridLayoutInfo_.startIndex_;
// TODO: need to consider [colunmStart]\[columsEnd] of [GridItem]
// TODO: shoule we use policy of adaptive layout according to size of [GridItem] ?
if (gridLayoutInfo_.startMainLineIndex_ - 1 < 0) {
LOGI("startMainLineIndex: %{public}d is alreay the first line, no forward line to make",
gridLayoutInfo_.startMainLineIndex_);
return -1.0f;
}
gridLayoutInfo_.startMainLineIndex_--;
bool doneCreateNewLine = false;
for (uint32_t i = 0; i < crossCount_; i++) {
if (currentIndex-- < 0) {
break;
}
// Step1. Get wrapper of [GridItem]
auto itemWrapper = layoutWrapper->GetOrCreateChildByIndex(currentIndex);
if (!itemWrapper) {
LOGE("GridItem wrapper of index %{public}u null", currentIndex);
break;
}
// Step2. Make constraint and measure child
// TODO: need to consider [colunmStart]\[columsEnd] of [GridItem]
// TODO: need to use [isScrollable_]
itemWrapper->Measure(MakeMeasureConstraintForGridItem(mainSize, crossSize, 1, gridLayoutProperty));
// Step3. Measure [GridItem]
auto itemSize = itemWrapper->GetGeometryNode()->GetFrameSize();
measuredItemsWidth += GetCrossAxisSize(itemSize, gridLayoutInfo_.axis_);
lineHeight = std::max(GetMainAxisSize(itemSize, gridLayoutInfo_.axis_), lineHeight);
// TODO: get [colunmStart]\[columsEnd] of [GridItem]
gridLayoutInfo_.gridMatrix_[gridLayoutInfo_.startMainLineIndex_][currentIndex] = 1;
gridLayoutInfo_.startIndex_ = currentIndex;
doneCreateNewLine = true;
}
// If it fails to create new line when [FillNewLineForward] is called, it means that it reaches start
if (!doneCreateNewLine) {
gridLayoutInfo_.reachStart_ = true;
}
return lineHeight;
}
float GridLayoutAlgorithm::FillNewLineBackward(
float crossSize, float mainSize, const RefPtr<GridLayoutProperty>& gridLayoutProperty, LayoutWrapper* layoutWrapper)
{
// To make the code more convinient to read, we name a param in situation of vertical, for exacmple:
// 1. [lineHight] means height of a row when the Grid is vertical;
// 2. [lineHight] means width of a column when the Grid is horizontal;
// Other params are also named according to this principle.
float lineHeight = -1.0f;
float measuredItemsWidth = 0.0f;
auto currentIndex = gridLayoutInfo_.endIndex_ + 1;
currentMainLineIndex_++; // if it fails to fill a new line backward, do [currentMainLineIndex_--]
// TODO: need to consider [colunmStart]\[columsEnd] of [GridItem]
// TODO: shoule we use policy of adaptive layout according to size of [GridItem] ?
bool doneFillLine = false;
for (uint32_t i = 0; i < crossCount_; i++) {
// Step1. Get wrapper of [GridItem]
auto itemWrapper = layoutWrapper->GetOrCreateChildByIndex(currentIndex);
if (!itemWrapper) {
LOGE("GridItem wrapper of index %{public}u null", currentIndex);
break;
}
// Step2. Make constraint and measure child
// TODO: need to consider [colunmStart]\[columsEnd] of [GridItem]
// TODO: need to use [isScrollable_]
itemWrapper->Measure(MakeMeasureConstraintForGridItem(mainSize, crossSize, 1, gridLayoutProperty));
// Step3. Measure [GridItem]
auto itemSize = itemWrapper->GetGeometryNode()->GetFrameSize();
measuredItemsWidth += GetCrossAxisSize(itemSize, gridLayoutInfo_.axis_);
lineHeight = std::max(GetMainAxisSize(itemSize, gridLayoutInfo_.axis_), lineHeight);
// TODO: get [colunmStart]\[columsEnd] of [GridItem]
gridLayoutInfo_.gridMatrix_[currentMainLineIndex_][currentIndex] = 1;
gridLayoutInfo_.endIndex_ = currentIndex;
currentIndex++;
doneFillLine = true;
}
if (!doneFillLine) {
// If it fails to fill a new line backward, do [currentMainLineIndex_--]
currentMainLineIndex_--;
} else {
gridLayoutInfo_.lineHeightMap_[currentMainLineIndex_] = lineHeight;
gridLayoutInfo_.endMainLineIndex_ = currentMainLineIndex_;
}
return lineHeight;
}
void GridLayoutAlgorithm::StripItemsOutOfViewport()
{
// Erase records that are out of viewport
// TODO: add cache and inactive item
// 1. Erase records that are on top of viewport
if (gridLayoutInfo_.lineHeightMap_.empty() || gridLayoutInfo_.gridMatrix_.empty()) {
return;
}
int32_t startIndexInMap = gridLayoutInfo_.lineHeightMap_.begin()->first;
for (int32_t i = startIndexInMap; i < gridLayoutInfo_.startMainLineIndex_; i++) {
gridLayoutInfo_.lineHeightMap_.erase(i);
gridLayoutInfo_.gridMatrix_.erase(i);
}
// 2. Erase records that are under viewport
if (gridLayoutInfo_.lineHeightMap_.empty() || gridLayoutInfo_.gridMatrix_.empty()) {
return;
}
for (int32_t i = gridLayoutInfo_.endMainLineIndex_ + 1;
i < static_cast<int32_t>(gridLayoutInfo_.lineHeightMap_.size()); i++) {
gridLayoutInfo_.lineHeightMap_.erase(i);
gridLayoutInfo_.gridMatrix_.erase(i);
}
}
LayoutConstraintF GridLayoutAlgorithm::MakeMeasureConstraintForGridItem(float mainSize, float crossSize,
uint32_t itemFractionCount, const RefPtr<GridLayoutProperty>& gridLayoutProperty) const
{
float itemMainSize =
gridLayoutProperty->IsConfiguredScrollable() ? Infinity<float>() : mainSize / static_cast<float>(mainCount_);
float fractionWidth = crossSize / static_cast<float>(crossCount_);
float itemCrossSize = fractionWidth * static_cast<float>(itemFractionCount);
SizeF itemIdealSize =
gridLayoutProperty->IsVertical() ? SizeF(itemCrossSize, itemMainSize) : SizeF(itemMainSize, itemCrossSize);
auto itemConstraint = gridLayoutProperty->CreateChildConstraint();
// The percent size of GridItem is based on the fraction size, for e.g., if a GridItem has width of "50%" in Grid
// configured with columnsTemplate = "1fr 1fr", rowsTemplate = "1fr 1fr", then tht GridItem width = [width of 1fr] *
// 50%
// [itemFractionCount] is now only in direction of cross axis
// TODO: consider rowStart/rowEnd
float widthPercentBase =
GreatOrEqual(crossCount_, Infinity<uint32_t>())
? itemConstraint.percentReference.Width()
: itemConstraint.percentReference.Width() / static_cast<float>(crossCount_ * itemFractionCount);
float heightPercentBase = GreatOrEqual(mainCount_, Infinity<uint32_t>())
? itemConstraint.percentReference.Height()
: itemConstraint.percentReference.Height() / static_cast<float>(mainCount_);
itemConstraint.percentReference = SizeF(widthPercentBase, heightPercentBase);
itemConstraint.maxSize = itemIdealSize;
return itemConstraint;
}
GridLayoutInfo GridLayoutAlgorithm::GetGridLayoutInfo()
{
return std::move(gridLayoutInfo_);
}
// only for debug use
void GridLayoutAlgorithm::PrintGridMatrix(const std::map<int32_t, std::map<int32_t, uint32_t>>& gridMatrix)
{
for (const auto& record : gridMatrix) {
for (const auto& item : record.second) {
LOGD("grid matrix -- line: %{public}d, item: %{public}d, fr: %{public}d", record.first, item.first,
item.second);
}
}
}
// only for debug use
void GridLayoutAlgorithm::PrintLineHeightMap(const std::map<int32_t, float>& lineHeightMap)
{
for (const auto& record : lineHeightMap) {
LOGD("line height -- line: %{public}d, lineHeight: %{public}f", record.first, record.second);
}
}
} // namespace OHOS::Ace::NG

View File

@ -0,0 +1,100 @@
/*
* Copyright (c) 2022 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_GRID_GRID_LAYOUT_ALGORITHM_H
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_LAYOUT_ALGORITHM_H
#include "core/components_ng/layout/box_layout_algorithm.h"
#include "core/components_ng/layout/layout_wrapper.h"
#include "core/components_ng/pattern/grid/grid_layout_property.h"
namespace OHOS::Ace::NG {
// Try not to add more variables in [GridLayoutInfo] because the more state variables, the more problematic and the
// harder it is to maintain
struct GridLayoutInfo {
Axis axis_ = Axis::VERTICAL;
float currentOffset_ = 0.0f;
float prevOffset_ = 0.0f;
// index of first and last GridItem in viewport
int32_t startIndex_ = 0;
int32_t endIndex_ = -1;
// index of first row and last row in viewport (assuming it's a vertical Grid)
int32_t startMainLineIndex_ = 0;
int32_t endMainLineIndex_ = 0;
bool reachEnd_ = false;
bool reachStart_ = false;
// in vertical grid, this map is like: [rowIndex: [itemIndex: fractionCount], [itemIndex: fractionCount]]
// for e.g, when a vertical grid has two [GridItem]s in first row, [gridMatrix_] is like [0: [0: 1fr], [1: 2fr]]
std::map<int32_t, std::map<int32_t, uint32_t>> gridMatrix_;
// in vertical grid, this map is like: [rowIndex: rowHeight]
std::map<int32_t, float> lineHeightMap_;
};
class ACE_EXPORT GridLayoutAlgorithm : public LayoutAlgorithm {
DECLARE_ACE_TYPE(GridLayoutAlgorithm, LayoutAlgorithm);
public:
GridLayoutAlgorithm(GridLayoutInfo gridLayoutInfo, uint32_t crossCount, uint32_t mainCount)
: gridLayoutInfo_(std::move(gridLayoutInfo)), crossCount_(crossCount), mainCount_(mainCount) {};
~GridLayoutAlgorithm() override = default;
void Measure(LayoutWrapper* layoutWrapper) override;
void Layout(LayoutWrapper* layoutWrapper) override;
GridLayoutInfo GetGridLayoutInfo();
static void PrintGridMatrix(const std::map<int32_t, std::map<int32_t, uint32_t>>& gridMatrix);
static void PrintLineHeightMap(const std::map<int32_t, float>& lineHeightMap);
private:
void FillGridViewportAndMeasureChildren(float mainSize, float crossSize,
const RefPtr<GridLayoutProperty>& gridLayoutProperty, LayoutWrapper* layoutWrapper);
void MeasureRecordedItems(float mainSize, float crossSize, const RefPtr<GridLayoutProperty>& gridLayoutProperty,
LayoutWrapper* layoutWrapper, float& mainLength);
// fill end of viewport
void FillBlankAtStart(float mainSize, float crossSize, const RefPtr<GridLayoutProperty>& gridLayoutProperty,
LayoutWrapper* layoutWrapper, float& mainLength);
float FillNewLineForward(float crossSize, float mainSize, const RefPtr<GridLayoutProperty>& gridLayoutProperty,
LayoutWrapper* layoutWrapper);
// fill start of viewport
void FillBlankAtEnd(float mainSize, float crossSize, const RefPtr<GridLayoutProperty>& gridLayoutProperty,
LayoutWrapper* layoutWrapper, float& mainLength);
float FillNewLineBackward(float crossSize, float mainSize, const RefPtr<GridLayoutProperty>& gridLayoutProperty,
LayoutWrapper* layoutWrapper);
LayoutConstraintF MakeMeasureConstraintForGridItem(float mainSize, float crossSize, uint32_t itemFractionCount,
const RefPtr<GridLayoutProperty>& gridLayoutProperty) const;
void StripItemsOutOfViewport();
void ModifyCurrentOffsetWhenReachEnd(float mainSize);
GridLayoutInfo gridLayoutInfo_;
uint32_t crossCount_ = 0;
uint32_t mainCount_ = 0;
int32_t currentMainLineIndex_ = 0; // it equals to row index in vertical grid
ACE_DISALLOW_COPY_AND_MOVE(GridLayoutAlgorithm);
};
} // namespace OHOS::Ace::NG
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_LAYOUT_ALGORITHM_H

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2022 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_GRID_GRID_LAYOUT_PROPERTY_H
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_LAYOUT_PROPERTY_H
#include "core/components_ng/layout/layout_property.h"
namespace OHOS::Ace::NG {
class ACE_EXPORT GridLayoutProperty : public LayoutProperty {
DECLARE_ACE_TYPE(GridLayoutProperty, LayoutProperty);
public:
GridLayoutProperty() = default;
~GridLayoutProperty() override = default;
RefPtr<LayoutProperty> Clone() const override
{
auto value = MakeRefPtr<GridLayoutProperty>();
value->LayoutProperty::UpdateLayoutProperty(DynamicCast<LayoutProperty>(this));
value->propColumnsTemplate_ = CloneColumnsTemplate();
value->propColumnsTemplate_ = CloneColumnsTemplate();
return value;
}
void Reset() override
{
LayoutProperty::Reset();
ResetColumnsTemplate();
ResetRowsTemplate();
}
bool IsVertical() const
{
bool columnsTemplateValid = propColumnsTemplate_.has_value() && !propColumnsTemplate_.value().empty();
bool rowsTemplateValid = propRowsTemplate_.has_value() && !propRowsTemplate_.value().empty();
return columnsTemplateValid ||
(!columnsTemplateValid && !rowsTemplateValid); // TODO: take layoutDirection into account
}
bool IsConfiguredScrollable() const
{
bool columnsTemplateSet = !propColumnsTemplate_.value_or("").empty();
bool rowsTemplateSet = !propRowsTemplate_.value_or("").empty();
bool verticalScrollable = (columnsTemplateSet && !rowsTemplateSet);
bool horizontalScrollable = (!columnsTemplateSet && rowsTemplateSet);
return verticalScrollable || horizontalScrollable;
}
ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(ColumnsTemplate, std::string, PROPERTY_UPDATE_LAYOUT);
ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(RowsTemplate, std::string, PROPERTY_UPDATE_LAYOUT);
private:
ACE_DISALLOW_COPY_AND_MOVE(GridLayoutProperty);
};
} // namespace OHOS::Ace::NG
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_LAYOUT_PROPERTY_H

View File

@ -0,0 +1,95 @@
/*
* Copyright (c) 2022 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 "core/components_ng/pattern/grid/grid_pattern.h"
namespace OHOS::Ace::NG {
void GridPattern::OnAttachToFrameNode()
{
auto host = GetHost();
CHECK_NULL_VOID(host);
host->GetRenderContext()->SetClipToFrame(true);
}
void GridPattern::OnModifyDone()
{
auto gridLayoutProperty = GetLayoutProperty<GridLayoutProperty>();
CHECK_NULL_VOID(gridLayoutProperty);
gridLayoutInfo_.axis_ = gridLayoutProperty->IsVertical() ? Axis::VERTICAL : Axis::HORIZONTAL;
AddScrollEvent();
}
void GridPattern::AddScrollEvent()
{
auto host = GetHost();
CHECK_NULL_VOID(host);
auto hub = host->GetEventHub<EventHub>();
CHECK_NULL_VOID(hub);
auto gestureHub = hub->GetOrCreateGestureEventHub();
CHECK_NULL_VOID(gestureHub);
if (scrollableEvent_) {
gestureHub->RemoveScrollableEvent(scrollableEvent_);
}
scrollableEvent_ = MakeRefPtr<ScrollableEvent>(gridLayoutInfo_.axis_);
auto scrollCallback = [weak = WeakClaim(this)](double offset, int32_t source) {
auto gridPattern = weak.Upgrade();
if (!gridPattern) {
LOGE("grid pattern upgrade fail when try handle scroll event.");
return false;
}
return gridPattern->UpdateScrollPosition(static_cast<float>(offset), source);
};
scrollableEvent_->SetScrollPositionCallback(std::move(scrollCallback));
gestureHub->AddScrollableEvent(scrollableEvent_);
}
bool GridPattern::UpdateScrollPosition(float offset, int32_t source)
{
auto host = GetHost();
CHECK_NULL_RETURN(host, false);
// When finger moves down, offset is positive.
// When finger moves up, offset is negative.
if (gridLayoutInfo_.reachEnd_) {
if (LessOrEqual(offset, 0)) {
return false;
}
gridLayoutInfo_.reachEnd_ = false;
}
if (gridLayoutInfo_.reachStart_) {
if (GreatOrEqual(offset, 0.0)) {
return false;
}
gridLayoutInfo_.reachStart_ = false;
}
gridLayoutInfo_.currentOffset_ += offset;
host->MarkDirtyNode(PROPERTY_REQUEST_NEW_CHILD_NODE);
return true;
}
bool GridPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, bool skipMeasure, bool skipLayout)
{
if (skipMeasure && skipLayout) {
return false;
}
auto layoutAlgorithmWrapper = DynamicCast<LayoutAlgorithmWrapper>(dirty->GetLayoutAlgorithm());
CHECK_NULL_RETURN(layoutAlgorithmWrapper, false);
auto gridLayoutAlgorithm = DynamicCast<GridLayoutAlgorithm>(layoutAlgorithmWrapper->GetLayoutAlgorithm());
CHECK_NULL_RETURN(gridLayoutAlgorithm, false);
gridLayoutInfo_ = gridLayoutAlgorithm->GetGridLayoutInfo();
return false;
}
} // namespace OHOS::Ace::NG

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 2022 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_PATTERNS_GRID_GRID_PATTERN_H
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_GRID_GRID_PATTERN_H
#include "base/memory/referenced.h"
#include "core/components_ng/pattern/grid/grid_layout_algorithm.h"
#include "core/components_ng/pattern/grid/grid_layout_property.h"
#include "core/components_ng/pattern/pattern.h"
namespace OHOS::Ace::NG {
class ACE_EXPORT GridPattern : public Pattern {
DECLARE_ACE_TYPE(GridPattern, Pattern);
public:
GridPattern() = default;
~GridPattern() override = default;
bool IsAtomicNode() const override
{
return false;
}
RefPtr<LayoutProperty> CreateLayoutProperty() override
{
return MakeRefPtr<GridLayoutProperty>();
}
RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override
{
auto gridLayoutProperty = GetLayoutProperty<GridLayoutProperty>();
CHECK_NULL_RETURN(gridLayoutProperty, nullptr);
std::vector<std::string> cols;
StringUtils::StringSplitter(gridLayoutProperty->GetColumnsTemplate().value_or(""), ' ', cols);
std::vector<std::string> rows;
StringUtils::StringSplitter(gridLayoutProperty->GetRowsTemplate().value_or(""), ' ', rows);
auto crossCount = cols.empty() ? Infinity<uint32_t>() : cols.size();
auto mainCount = rows.empty() ? Infinity<uint32_t>() : rows.size();
if (!gridLayoutProperty->IsVertical()) {
std::swap(crossCount, mainCount);
}
return MakeRefPtr<GridLayoutAlgorithm>(gridLayoutInfo_, crossCount, mainCount);
}
private:
void OnAttachToFrameNode() override;
void OnModifyDone() override;
void AddScrollEvent();
bool UpdateScrollPosition(float offset, int32_t source);
bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, bool skipMeasure, bool skipLayout) override;
GridLayoutInfo gridLayoutInfo_;
RefPtr<ScrollableEvent> scrollableEvent_;
ACE_DISALLOW_COPY_AND_MOVE(GridPattern);
};
} // namespace OHOS::Ace::NG
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_GRID_GRID_PATTERN_H

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2022 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 "core/components_ng/pattern/grid/grid_view.h"
#include "core/components_ng/base/frame_node.h"
#include "core/components_ng/base/view_stack_processor.h"
#include "core/components_ng/pattern/grid/grid_layout_property.h"
#include "core/components_ng/pattern/grid/grid_pattern.h"
#include "core/components_v2/inspector/inspector_constants.h"
namespace OHOS::Ace::NG {
void GridView::Create()
{
auto* stack = ViewStackProcessor::GetInstance();
auto nodeId = stack->ClaimNodeId();
auto frameNode =
FrameNode::GetOrCreateFrameNode(V2::GRID_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<GridPattern>(); });
stack->Push(frameNode);
}
void GridView::SetColumnsTemplate(const std::string& value)
{
ACE_UPDATE_LAYOUT_PROPERTY(GridLayoutProperty, ColumnsTemplate, value);
}
void GridView::SetRowsTemplate(const std::string& value)
{
ACE_UPDATE_LAYOUT_PROPERTY(GridLayoutProperty, RowsTemplate, value);
}
} // namespace OHOS::Ace::NG

View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2022 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_PATTERNS_GRIF_GRID_VIEW_H
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_GRIF_GRID_VIEW_H
#include <string>
#include "base/utils/macros.h"
#include "core/components/common/layout/constants.h"
namespace OHOS::Ace::NG {
class ACE_EXPORT GridView {
public:
static void Create();
static void SetColumnsTemplate(const std::string& value);
static void SetRowsTemplate(const std::string& value);
};
} // namespace OHOS::Ace::NG
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_GRIF_GRID_VIEW_H