diff --git a/frameworks/base/geometry/ng/size_t.h b/frameworks/base/geometry/ng/size_t.h index 199749286f52683ca73d73361e7f5326f5e2f0a8..078a802f5c49722b6fad77878a334d9516e29de1 100644 --- a/frameworks/base/geometry/ng/size_t.h +++ b/frameworks/base/geometry/ng/size_t.h @@ -54,6 +54,11 @@ public: return axis == Axis::HORIZONTAL ? width_ : height_; } + T CrossSize(Axis axis) const + { + return axis == Axis::HORIZONTAL ? height_ : width_; + } + void SetWidth(T width) { width_ = width; @@ -339,6 +344,11 @@ public: return axis == Axis::HORIZONTAL ? width_ : height_; } + const std::optional& CrossSize(Axis axis) const + { + return axis == Axis::HORIZONTAL ? height_ : width_; + } + void SetWidth(T width) { width_ = width; diff --git a/frameworks/bridge/declarative_frontend/jsview/js_grid.cpp b/frameworks/bridge/declarative_frontend/jsview/js_grid.cpp index 8a7750bd82796360bca042ec19198afeda18c2a1..0f9dd41a3371beec903fe3f58045425cdfba4e42 100644 --- a/frameworks/bridge/declarative_frontend/jsview/js_grid.cpp +++ b/frameworks/bridge/declarative_frontend/jsview/js_grid.cpp @@ -15,6 +15,7 @@ #include "frameworks/bridge/declarative_frontend/jsview/js_grid.h" +#include "base/utils/utils.h" #include "bridge/declarative_frontend/jsview/js_view_common_def.h" #include "core/common/ace_application_info.h" #include "core/common/container.h" @@ -136,6 +137,9 @@ void JSGrid::SetColumnsGap(const JSCallbackInfo& info) if (!ParseJsDimensionVp(info[0], colGap)) { return; } + + SET_PROP_FOR_NG(ColumnsGap, Dimension, colGap); + auto component = ViewStackProcessor::GetInstance()->GetMainComponent(); auto grid = AceType::DynamicCast(component); if (grid) { @@ -153,6 +157,9 @@ void JSGrid::SetRowsGap(const JSCallbackInfo& info) if (!ParseJsDimensionVp(info[0], rowGap)) { return; } + + SET_PROP_FOR_NG(RowsGap, Dimension, rowGap); + auto component = ViewStackProcessor::GetInstance()->GetMainComponent(); auto grid = AceType::DynamicCast(component); if (grid) { @@ -194,21 +201,37 @@ void JSGrid::JsGridHeight(const JSCallbackInfo& info) void JSGrid::JsOnScrollIndex(const JSCallbackInfo& info) { if (info[0]->IsFunction()) { - auto onScrolled = EventMarker( - [execCtx = info.GetExecutionContext(), func = JSRef::Cast(info[0])](const BaseEventInfo* event) { - JAVASCRIPT_EXECUTION_SCOPE(execCtx); - auto eventInfo = TypeInfoHelper::DynamicCast(event); - if (!eventInfo) { - return; - } - auto params = ConvertToJSValues(eventInfo->GetScrollIndex()); - func->Call(JSRef(), params.size(), params.data()); - }); - - auto grid = AceType::DynamicCast(ViewStackProcessor::GetInstance()->GetMainComponent()); - if (grid) { - grid->SetScrolledEvent(onScrolled); - } + LOGE("param not valid, need function"); + return; + } + + if (Container::IsCurrentUseNewPipeline()) { + auto jsOnScrollToIndexFunc = AceType::MakeRefPtr(JSRef(), JSRef::Cast(info[0])); + auto onScrollToIndex = [execCtx = info.GetExecutionContext(), func = std::move(jsOnScrollToIndexFunc)]( + int32_t index) { + JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); + ACE_SCORING_EVENT("Grid.onScrollToIndex"); + auto newJSVal = JSRef::Make(ToJSValue(index)); + func->ExecuteJS(1, &newJSVal); + }; + NG::GridView::SetOnScrollToIndex(std::move(onScrollToIndex)); + return; + } + + auto onScrolled = EventMarker( + [execCtx = info.GetExecutionContext(), func = JSRef::Cast(info[0])](const BaseEventInfo* event) { + JAVASCRIPT_EXECUTION_SCOPE(execCtx); + auto eventInfo = TypeInfoHelper::DynamicCast(event); + if (!eventInfo) { + return; + } + auto params = ConvertToJSValues(eventInfo->GetScrollIndex()); + func->Call(JSRef(), params.size(), params.data()); + }); + + auto grid = AceType::DynamicCast(ViewStackProcessor::GetInstance()->GetMainComponent()); + if (grid) { + grid->SetScrolledEvent(onScrolled); } } @@ -270,13 +293,17 @@ void JSGrid::SetScrollBar(int32_t displayMode) if (!grid) { return; } - if (displayMode >= 0 && displayMode < static_cast(DISPLAY_MODE.size())) { - grid->SetScrollBar(DISPLAY_MODE[displayMode]); + if (displayMode < 0 || displayMode >= static_cast(DISPLAY_MODE.size())) { + LOGE("Param is not valid"); + return; } + SET_PROP_FOR_NG(ScrollBarMode, DisplayMode, DISPLAY_MODE[displayMode]); + grid->SetScrollBar(DISPLAY_MODE[displayMode]); } void JSGrid::SetScrollBarColor(const std::string& color) { + SET_PROP_FOR_NG(ScrollBarColor, Color, Color::FromString(color)); auto component = ViewStackProcessor::GetInstance()->GetMainComponent(); auto grid = AceType::DynamicCast(component); if (grid) { @@ -286,6 +313,7 @@ void JSGrid::SetScrollBarColor(const std::string& color) void JSGrid::SetScrollBarWidth(const std::string& width) { + SET_PROP_FOR_NG(ScrollBarWidth, Dimension, StringUtils::StringToDimensionWithUnit(width)); auto component = ViewStackProcessor::GetInstance()->GetMainComponent(); auto grid = AceType::DynamicCast(component); if (grid) { @@ -295,6 +323,7 @@ void JSGrid::SetScrollBarWidth(const std::string& width) void JSGrid::SetCachedCount(int32_t cachedCount) { + SET_PROP_FOR_NG(CachedCount, int32_t, cachedCount); auto component = ViewStackProcessor::GetInstance()->GetMainComponent(); auto grid = AceType::DynamicCast(component); if (grid) { @@ -304,6 +333,7 @@ void JSGrid::SetCachedCount(int32_t cachedCount) void JSGrid::SetEditMode(bool editMode) { + SET_PROP_FOR_NG(Editable, bool, editMode); auto component = ViewStackProcessor::GetInstance()->GetMainComponent(); auto grid = AceType::DynamicCast(component); if (grid) { @@ -313,6 +343,7 @@ void JSGrid::SetEditMode(bool editMode) void JSGrid::SetMaxCount(int32_t maxCount) { + SET_PROP_FOR_NG(MaxCount, int32_t, maxCount); auto component = ViewStackProcessor::GetInstance()->GetMainComponent(); auto grid = AceType::DynamicCast(component); if (grid) { @@ -322,6 +353,7 @@ void JSGrid::SetMaxCount(int32_t maxCount) void JSGrid::SetMinCount(int32_t minCount) { + SET_PROP_FOR_NG(MinCount, int32_t, minCount); auto component = ViewStackProcessor::GetInstance()->GetMainComponent(); auto grid = AceType::DynamicCast(component); if (grid) { @@ -331,6 +363,7 @@ void JSGrid::SetMinCount(int32_t minCount) void JSGrid::CellLength(int32_t cellLength) { + SET_PROP_FOR_NG(CellLength, int32_t, cellLength); auto component = ViewStackProcessor::GetInstance()->GetMainComponent(); auto grid = AceType::DynamicCast(component); if (grid) { @@ -340,6 +373,7 @@ void JSGrid::CellLength(int32_t cellLength) void JSGrid::SetSupportAnimation(bool supportAnimation) { + SET_PROP_FOR_NG(SupportAnimation, bool, supportAnimation); auto component = ViewStackProcessor::GetInstance()->GetMainComponent(); auto grid = AceType::DynamicCast(component); if (grid) { @@ -369,12 +403,16 @@ void JSGrid::SetEdgeEffect(int32_t value) void JSGrid::SetLayoutDirection(int32_t value) { - if (value >= 0 && value < static_cast(LAYOUT_DIRECTION.size())) { - auto component = ViewStackProcessor::GetInstance()->GetMainComponent(); - auto grid = AceType::DynamicCast(component); - if (grid) { - grid->SetDirection(LAYOUT_DIRECTION[value]); - } + if (value < 0 && value >= static_cast(LAYOUT_DIRECTION.size())) { + LOGE("Param is not valid"); + return; + } + SET_PROP_FOR_NG(LayoutDirection, FlexDirection, LAYOUT_DIRECTION[value]); + + auto component = ViewStackProcessor::GetInstance()->GetMainComponent(); + auto grid = AceType::DynamicCast(component); + if (grid) { + grid->SetDirection(LAYOUT_DIRECTION[value]); } } @@ -402,6 +440,18 @@ void JSGrid::JsOnGridDragEnter(const JSCallbackInfo& info) return; } + if (Container::IsCurrentUseNewPipeline()) { + auto jsOnDragEnterFunc = AceType::MakeRefPtr(JSRef::Cast(info[0])); + auto onItemDragEnter = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEnterFunc)]( + const ItemDragInfo& dragInfo) { + JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); + ACE_SCORING_EVENT("Grid.onItemDragEnter"); + func->ItemDragEnterExecute(dragInfo); + }; + NG::GridView::SetOnItemDragEnter(std::move(onItemDragEnter)); + return; + } + RefPtr jsOnDragEnterFunc = AceType::MakeRefPtr(JSRef::Cast(info[0])); auto onItemDragEnterId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEnterFunc)]( const ItemDragInfo& dragInfo) { @@ -424,6 +474,18 @@ void JSGrid::JsOnGridDragMove(const JSCallbackInfo& info) return; } + if (Container::IsCurrentUseNewPipeline()) { + auto jsOnDragMoveFunc = AceType::MakeRefPtr(JSRef::Cast(info[0])); + auto onItemDragMove = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragMoveFunc)]( + 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); + }; + NG::GridView::SetOnItemDragMove(std::move(onItemDragMove)); + return; + } + RefPtr jsOnDragMoveFunc = AceType::MakeRefPtr(JSRef::Cast(info[0])); auto onItemDragMoveId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragMoveFunc)]( const ItemDragInfo& dragInfo, int32_t itemIndex, int32_t insertIndex) { @@ -446,6 +508,18 @@ void JSGrid::JsOnGridDragLeave(const JSCallbackInfo& info) return; } + if (Container::IsCurrentUseNewPipeline()) { + auto jsOnDragLeaveFunc = AceType::MakeRefPtr(JSRef::Cast(info[0])); + auto onItemDragLeave = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragLeaveFunc)]( + const ItemDragInfo& dragInfo, int32_t itemIndex) { + JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); + ACE_SCORING_EVENT("Grid.onItemDragLeave"); + func->ItemDragLeaveExecute(dragInfo, itemIndex); + }; + NG::GridView::SetOnItemDragLeave(std::move(onItemDragLeave)); + return; + } + RefPtr jsOnDragLeaveFunc = AceType::MakeRefPtr(JSRef::Cast(info[0])); auto onItemDragLeaveId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragLeaveFunc)]( const ItemDragInfo& dragInfo, int32_t itemIndex) { @@ -468,6 +542,38 @@ void JSGrid::JsOnGridDragStart(const JSCallbackInfo& info) return; } + if (Container::IsCurrentUseNewPipeline()) { + auto jsOnDragFunc = AceType::MakeRefPtr(JSRef::Cast(info[0])); + auto onItemDragStart = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragFunc)]( + const ItemDragInfo& dragInfo, int32_t itemIndex) -> RefPtr { + JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, nullptr); + ACE_SCORING_EVENT("Grid.onItemDragStart"); + auto ret = func->ItemDragStartExecute(dragInfo, itemIndex); + if (!ret->IsObject()) { + LOGE("builder param is not an object."); + return nullptr; + } + + auto builderObj = JSRef::Cast(ret); + auto builder = builderObj->GetProperty("builder"); + if (!builder->IsFunction()) { + LOGE("builder param is not a function."); + return nullptr; + } + auto builderFunc = AceType::MakeRefPtr(JSRef::Cast(builder)); + CHECK_NULL_RETURN(builderFunc, nullptr); + // use another VSP instance while executing the builder function + NG::ScopedViewStackProcessor builderViewStackProcessor; + { + builderFunc->Execute(); + } + auto customNode = NG::ViewStackProcessor::GetInstance()->Finish(); + return customNode; + }; + NG::GridView::SetOnItemDragStart(std::move(onItemDragStart)); + return; + } + RefPtr jsOnDragFunc = AceType::MakeRefPtr(JSRef::Cast(info[0])); auto onItemDragStartId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragFunc)]( const ItemDragInfo& dragInfo, int32_t itemIndex) -> RefPtr { @@ -517,6 +623,18 @@ void JSGrid::JsOnGridDrop(const JSCallbackInfo& info) return; } + if (Container::IsCurrentUseNewPipeline()) { + auto jsOnDropFunc = AceType::MakeRefPtr(JSRef::Cast(info[0])); + auto onItemDrop = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDropFunc)]( + 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); + }; + NG::GridView::SetOnItemDrop(std::move(onItemDrop)); + return; + } + RefPtr jsOnDropFunc = AceType::MakeRefPtr(JSRef::Cast(info[0])); auto onItemDropId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDropFunc)]( const ItemDragInfo& dragInfo, int32_t itemIndex, int32_t insertIndex, bool isSuccess) { @@ -534,6 +652,7 @@ void JSGrid::JsOnGridDrop(const JSCallbackInfo& info) void JSGrid::SetMultiSelectable(bool multiSelectable) { + SET_PROP_FOR_NG(MultiSelectable, bool, multiSelectable); auto component = ViewStackProcessor::GetInstance()->GetMainComponent(); auto grid = AceType::DynamicCast(component); if (grid) { diff --git a/frameworks/bridge/declarative_frontend/jsview/js_grid_item.cpp b/frameworks/bridge/declarative_frontend/jsview/js_grid_item.cpp index d1e96730fde25511ab0115bbfc518092248f9e31..b62469154d0747d915ad98064494460471c92981 100644 --- a/frameworks/bridge/declarative_frontend/jsview/js_grid_item.cpp +++ b/frameworks/bridge/declarative_frontend/jsview/js_grid_item.cpp @@ -17,12 +17,21 @@ #include "core/common/container.h" #include "core/components_ng/pattern/grid/grid_item_view.h" +#include "core/components_ng/pattern/grid/grid_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" namespace OHOS::Ace::Framework { +#define SET_PROP_FOR_NG(propName, propType, propValue) \ + do { \ + if (Container::IsCurrentUseNewPipeline()) { \ + NG::GridItemView::Set##propName(static_cast(propValue)); \ + return; \ + } \ + } while (0); + void JSGridItem::Create(const JSCallbackInfo& args) { if (Container::IsCurrentUseNewPipeline()) { @@ -119,6 +128,7 @@ void JSGridItem::CreateForNGPartialUpdate(const JSCallbackInfo& args) void JSGridItem::SetColumnStart(int32_t columnStart) { + SET_PROP_FOR_NG(ColumnStart, int32_t, std::max(0, columnStart)); auto gridItem = AceType::DynamicCast(ViewStackProcessor::GetInstance()->GetMainComponent()); if (gridItem) { @@ -129,6 +139,7 @@ void JSGridItem::SetColumnStart(int32_t columnStart) void JSGridItem::SetColumnEnd(int32_t columnEnd) { + SET_PROP_FOR_NG(ColumnEnd, int32_t, std::max(0, columnEnd)); // column end must be set after start. loader needs to make the method in order. auto gridItem = AceType::DynamicCast(ViewStackProcessor::GetInstance()->GetMainComponent()); @@ -140,6 +151,7 @@ void JSGridItem::SetColumnEnd(int32_t columnEnd) void JSGridItem::SetRowStart(int32_t rowStart) { + SET_PROP_FOR_NG(RowStart, int32_t, std::max(0, rowStart)); auto gridItem = AceType::DynamicCast(ViewStackProcessor::GetInstance()->GetMainComponent()); if (gridItem) { @@ -150,6 +162,7 @@ void JSGridItem::SetRowStart(int32_t rowStart) void JSGridItem::SetRowEnd(int32_t rowEnd) { + SET_PROP_FOR_NG(RowEnd, int32_t, std::max(0, rowEnd)); // row end must be set after start. loader needs to make the method in order. auto gridItem = AceType::DynamicCast(ViewStackProcessor::GetInstance()->GetMainComponent()); @@ -161,6 +174,7 @@ void JSGridItem::SetRowEnd(int32_t rowEnd) void JSGridItem::ForceRebuild(bool forceRebuild) { + SET_PROP_FOR_NG(ForceRebuild, bool, forceRebuild); auto gridItem = AceType::DynamicCast(ViewStackProcessor::GetInstance()->GetMainComponent()); if (gridItem) { @@ -200,6 +214,7 @@ void JSGridItem::JSBind(BindingTarget globalObj) void JSGridItem::SetSelectable(bool selectable) { + SET_PROP_FOR_NG(Selectable, bool, selectable); auto gridItem = AceType::DynamicCast(ViewStackProcessor::GetInstance()->GetMainComponent()); if (gridItem) { @@ -214,6 +229,17 @@ void JSGridItem::SelectCallback(const JSCallbackInfo& args) return; } + if (Container::IsCurrentUseNewPipeline()) { + auto jsOnSelectFunc = AceType::MakeRefPtr(JSRef::Cast(args[0])); + auto onSelect = [execCtx = args.GetExecutionContext(), func = std::move(jsOnSelectFunc)](bool isSelected) { + JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); + ACE_SCORING_EVENT("GridItem.onSelect"); + func->SelectExecute(isSelected); + }; + NG::GridItemView::SetOnSelect(std::move(onSelect)); + return; + } + RefPtr jsOnSelectFunc = AceType::MakeRefPtr(JSRef::Cast(args[0])); auto onSelectId = [execCtx = args.GetExecutionContext(), func = std::move(jsOnSelectFunc)](bool isSelected) { JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); diff --git a/frameworks/core/components_ng/pattern/BUILD.gn b/frameworks/core/components_ng/pattern/BUILD.gn index 2068315127abd7bf2cd9f3d4988921036c4a1043..66f7fa16271f5a59464c1c104267ce00807161a8 100644 --- a/frameworks/core/components_ng/pattern/BUILD.gn +++ b/frameworks/core/components_ng/pattern/BUILD.gn @@ -43,9 +43,12 @@ build_component_ng("pattern_ng") { "divider/divider_view.cpp", "flex/flex_layout_algorithm.cpp", "flex/flex_view.cpp", + "grid/grid_adaptive/grid_adaptive_layout_algorithm.cpp", "grid/grid_item_view.cpp", - "grid/grid_layout_algorithm.cpp", + "grid/grid_layout/grid_layout_algorithm.cpp", "grid/grid_pattern.cpp", + "grid/grid_scroll/grid_scroll_layout_algorithm.cpp", + "grid/grid_utils.cpp", "grid/grid_view.cpp", "image/image_layout_algorithm.cpp", "image/image_model_ng.cpp", diff --git a/frameworks/core/components_ng/pattern/grid/grid_adaptive/grid_adaptive_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/grid/grid_adaptive/grid_adaptive_layout_algorithm.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0f81d8af6ebbd2802fe561d0a7542e3319f0ea7a --- /dev/null +++ b/frameworks/core/components_ng/pattern/grid/grid_adaptive/grid_adaptive_layout_algorithm.cpp @@ -0,0 +1,168 @@ +/* + * 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_adaptive/grid_adaptive_layout_algorithm.h" + +#include +#include +#include +#include + +#include "base/geometry/dimension.h" +#include "base/utils/utils.h" +#include "core/components/common/layout/constants.h" +#include "core/components_ng/pattern/grid/grid_layout_property.h" +#include "core/components_ng/pattern/image/image_layout_property.h" +#include "core/components_ng/property/measure_utils.h" + +namespace OHOS::Ace::NG { + +void GridAdaptiveLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper) +{ + auto gridLayoutProperty = AceType::DynamicCast(layoutWrapper->GetLayoutProperty()); + CHECK_NULL_VOID(gridLayoutProperty); + auto layoutDirection = gridLayoutProperty->GetLayoutDirection().value_or(FlexDirection::ROW); + auto axis = (layoutDirection == FlexDirection::ROW || layoutDirection == FlexDirection::ROW_REVERSE) + ? Axis::HORIZONTAL + : Axis::VERTICAL; + auto idealSize = + CreateIdealSize(gridLayoutProperty->GetLayoutConstraint().value(), axis, MeasureType::MATCH_CONTENT); + MinusPaddingToSize(gridLayoutProperty->CreatePaddingAndBorder(), idealSize); + + auto firstChildWrapper = layoutWrapper->GetOrCreateChildByIndex(0); + CHECK_NULL_VOID(firstChildWrapper); + auto layoutConstraint = gridLayoutProperty->CreateChildConstraint(); + firstChildWrapper->Measure(layoutConstraint); + auto firstChildSize = firstChildWrapper->GetGeometryNode()->GetFrameSize(); + + // Calculate grid cell size. + gridCellSize_ = firstChildSize; + auto cellLength = gridLayoutProperty->GetCellLength(); + if (cellLength.has_value()) { + auto cellLengthInPx = static_cast(Dimension(cellLength.value(), DimensionUnit::VP).ConvertToPx()); + if (axis == Axis::HORIZONTAL) { + gridCellSize_.SetHeight(cellLengthInPx); + } else { + gridCellSize_.SetWidth(cellLengthInPx); + } + } + + // Calculate cell count and display count. + auto minCount = std::max(gridLayoutProperty->GetMinCount().value_or(1), 1); + auto maxCount = std::max(gridLayoutProperty->GetMaxCount().value_or(Infinity()), 1); + if (minCount > maxCount) { + std::swap(minCount, maxCount); + } + auto maxSize = gridLayoutProperty->GetLayoutConstraint()->maxSize; + auto refWidth = idealSize.Width().has_value() ? idealSize.Width().value() : maxSize.Width(); + auto refHeight = idealSize.Height().has_value() ? idealSize.Height().value() : maxSize.Height(); + auto scale = gridLayoutProperty->GetLayoutConstraint()->scaleProperty; + auto rowsGap = ConvertToPx(gridLayoutProperty->GetRowsGap().value_or(0.0_vp), scale, refHeight).value_or(0); + auto columnsGap = ConvertToPx(gridLayoutProperty->GetColumnsGap().value_or(0.0_vp), scale, refWidth).value_or(0); + auto childrenCount = layoutWrapper->GetTotalChildCount(); + auto mainGap = (axis == Axis::HORIZONTAL) ? columnsGap : rowsGap; + auto crossGap = (axis == Axis::HORIZONTAL) ? rowsGap : columnsGap; + mainCount_ = std::floor((idealSize.MainSize(axis).value_or(maxSize.MainSize(axis)) + mainGap) / + (gridCellSize_.MainSize(axis) + mainGap)); + mainCount_ = std::clamp(mainCount_, minCount, maxCount); + crossCount_ = std::floor((idealSize.CrossSize(axis).value_or(Infinity()) + crossGap) / + (gridCellSize_.CrossSize(axis) + crossGap)); + auto maxCrossCount = std::max(static_cast(std::ceil(childrenCount / mainCount_)), 1); + crossCount_ = std::clamp(crossCount_, 1, maxCrossCount); + displayCount_ = std::min(childrenCount, mainCount_ * crossCount_); + LOGI("axis: %{public}d, main count: %{public}d, cross count: %{public}d, displayCount: %{public}d, gridCellSize: " + "%{public}s", + axis, mainCount_, crossCount_, displayCount_, gridCellSize_.ToString().c_str()); + + // Update frame size. + auto rowCount = axis == Axis::HORIZONTAL ? crossCount_ : mainCount_; + auto columnCount = axis == Axis::HORIZONTAL ? mainCount_ : crossCount_; + idealSize.UpdateIllegalSizeWithCheck( + OptionalSizeF(columnCount * gridCellSize_.Width() + (columnCount - 1) * columnsGap, + rowCount * gridCellSize_.Height() + (rowCount - 1) * rowsGap)); + layoutWrapper->GetGeometryNode()->SetFrameSize(idealSize.ConvertToSizeT()); + + // Create child constraint. + auto childLayoutConstraint = gridLayoutProperty->CreateChildConstraint(); + childLayoutConstraint.maxSize.UpdateSizeWithCheck(gridCellSize_); + + // Measure children. + for (int32_t index = 0; index < displayCount_; ++index) { + auto childWrapper = layoutWrapper->GetOrCreateChildByIndex(index); + if (!childWrapper) { + continue; + } + childWrapper->Measure(childLayoutConstraint); + } +} + +void GridAdaptiveLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper) +{ + CHECK_NULL_VOID(layoutWrapper); + auto parentOffset = + layoutWrapper->GetGeometryNode()->GetParentGlobalOffset() + layoutWrapper->GetGeometryNode()->GetFrameOffset(); + + for (int32_t index = 0; index < displayCount_; ++index) { + auto childWrapper = layoutWrapper->GetOrCreateChildByIndex(index); + if (!childWrapper) { + continue; + } + childWrapper->GetGeometryNode()->SetFrameOffset(CalculateChildOffset(index, layoutWrapper)); + childWrapper->Layout(parentOffset); + } +} + +OffsetF GridAdaptiveLayoutAlgorithm::CalculateChildOffset(int32_t index, LayoutWrapper* layoutWrapper) const +{ + auto frameSize = layoutWrapper->GetGeometryNode()->GetFrameSize(); + auto layoutProperty = AceType::DynamicCast(layoutWrapper->GetLayoutProperty()); + CHECK_NULL_RETURN(layoutProperty, OffsetF()); + auto padding = layoutProperty->CreatePaddingAndBorder(); + auto layoutDirection = layoutProperty->GetLayoutDirection().value_or(FlexDirection::ROW); + auto scale = layoutProperty->GetLayoutConstraint()->scaleProperty; + auto rowsGap = ConvertToPx(layoutProperty->GetRowsGap().value_or(0.0_vp), scale, frameSize.Width()).value_or(0); + auto columnsGap = + ConvertToPx(layoutProperty->GetColumnsGap().value_or(0.0_vp), scale, frameSize.Height()).value_or(0); + + int32_t rowIndex = 0; + int32_t columnIndex = 0; + switch (layoutDirection) { + case FlexDirection::ROW: + rowIndex = index / mainCount_; + columnIndex = index % mainCount_; + break; + case FlexDirection::ROW_REVERSE: + rowIndex = index / mainCount_; + columnIndex = mainCount_ - index % mainCount_ - 1; + break; + case FlexDirection::COLUMN: + columnIndex = index / mainCount_; + rowIndex = index % mainCount_; + break; + case FlexDirection::COLUMN_REVERSE: + columnIndex = index / mainCount_; + rowIndex = mainCount_ - index % mainCount_ - 1; + break; + default: + LOGI("%{public}d is not support", layoutDirection); + break; + } + + auto positionX = columnIndex * (gridCellSize_.Width() + columnsGap); + auto positionY = rowIndex * (gridCellSize_.Height() + rowsGap); + return padding.Offset() + OffsetF(positionX, positionY); +} + +} // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/grid/grid_adaptive/grid_adaptive_layout_algorithm.h b/frameworks/core/components_ng/pattern/grid/grid_adaptive/grid_adaptive_layout_algorithm.h new file mode 100644 index 0000000000000000000000000000000000000000..26e1fe2aaa951d18efb05847ea2d34e216eef668 --- /dev/null +++ b/frameworks/core/components_ng/pattern/grid/grid_adaptive/grid_adaptive_layout_algorithm.h @@ -0,0 +1,58 @@ +/* + * 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_ADAPTIVE_GRID_ADAPTIVE_LAYOUT_ALGORITHM_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_ADAPTIVE_GRID_ADAPTIVE_LAYOUT_ALGORITHM_H + +#include "core/components_ng/layout/layout_algorithm.h" +#include "core/components_ng/layout/layout_wrapper.h" +#include "core/components_ng/pattern/grid/grid_layout_info.h" +#include "core/components_ng/pattern/grid/grid_layout_property.h" + +namespace OHOS::Ace::NG { + +// Effect when rowsTemplate and columnsTemplate are not setted, this algorithm effect these attribute: +// columnsGap | rowsGap | layoutDirection | maxCount | minCount | cellLength. +class ACE_EXPORT GridAdaptiveLayoutAlgorithm : public LayoutAlgorithm { + DECLARE_ACE_TYPE(GridAdaptiveLayoutAlgorithm, LayoutAlgorithm); + +public: + explicit GridAdaptiveLayoutAlgorithm(GridLayoutInfo gridLayoutInfo) : gridLayoutInfo_(std::move(gridLayoutInfo)) {}; + ~GridAdaptiveLayoutAlgorithm() override = default; + + void Measure(LayoutWrapper* layoutWrapper) override; + void Layout(LayoutWrapper* layoutWrapper) override; + + GridLayoutInfo GetGridLayoutInfo(); + +private: + OffsetF CalculateChildOffset(int32_t index, LayoutWrapper* layoutWrapper) const; + + GridLayoutInfo gridLayoutInfo_; + + // cell size of grid. + SizeF gridCellSize_; + // grid cell count in main axis. + int32_t mainCount_ = 0; + // grid cell count in cross axis. + int32_t crossCount_ = 0; + // total count has shown. + int32_t displayCount_ = 0; + + ACE_DISALLOW_COPY_AND_MOVE(GridAdaptiveLayoutAlgorithm); +}; + +} // namespace OHOS::Ace::NG +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_ADAPTIVE_GRID_ADAPTIVE_LAYOUT_ALGORITHM_H diff --git a/frameworks/core/components_ng/pattern/grid/grid_event_hub.cpp b/frameworks/core/components_ng/pattern/grid/grid_event_hub.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5df00b53ad6e63730478dcf8c0192bd0786a7319 --- /dev/null +++ b/frameworks/core/components_ng/pattern/grid/grid_event_hub.cpp @@ -0,0 +1,30 @@ +/* + * 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_event_hub.h" + +#include "core/components_ng/base/ui_node.h" + +namespace OHOS::Ace::NG { + +RefPtr GridEventHub::FireOnItemDragStart(const ItemDragInfo& dragInfo, int32_t itemIndex) const +{ + if (onItemDragStart_) { + return onItemDragStart_(dragInfo, itemIndex); + } + return nullptr; +} + +} // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/grid/grid_event_hub.h b/frameworks/core/components_ng/pattern/grid/grid_event_hub.h new file mode 100644 index 0000000000000000000000000000000000000000..3f029dfd1d82b5d2372b8a4f6c727e1465b2db94 --- /dev/null +++ b/frameworks/core/components_ng/pattern/grid/grid_event_hub.h @@ -0,0 +1,117 @@ +/* + * 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_EVENT_HUB_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_EVENT_HUB_H + +#include + +#include "base/memory/ace_type.h" +#include "core/components_ng/event/event_hub.h" + +namespace OHOS::Ace::NG { + +using ScrollToIndexFunc = std::function; +using ItemDragStartFunc = std::function(const ItemDragInfo&, int32_t)>; +using ItemDragEnterFunc = std::function; +using ItemDragMoveFunc = std::function; +using ItemDragLeaveFunc = std::function; +using ItemDropFunc = std::function; + +class GridEventHub : public EventHub { + DECLARE_ACE_TYPE(GridEventHub, EventHub) + +public: + GridEventHub() = default; + ~GridEventHub() override = default; + + void SetOnScrollToIndex(ScrollToIndexFunc&& onScrollToIndex) + { + onScrollToIndex_ = std::move(onScrollToIndex); + } + + void SetOnItemDragStart(ItemDragStartFunc&& onItemDragStart) + { + onItemDragStart_ = std::move(onItemDragStart); + } + + void SetOnItemDragEnter(ItemDragEnterFunc&& onItemDragEnter) + { + onItemDragEnter_ = std::move(onItemDragEnter); + } + + void SetOnItemDragMove(ItemDragMoveFunc&& onItemDragMove) + { + onItemDragMove_ = std::move(onItemDragMove); + } + + void SetOnItemDragLeave(ItemDragLeaveFunc&& onItemDragLeave) + { + onItemDragLeave_ = std::move(onItemDragLeave); + } + + void SetOnItemDrop(ItemDropFunc&& onItemDrop) + { + onItemDrop_ = std::move(onItemDrop); + } + + void FireOnScrollToIndex(int32_t param) const + { + if (onScrollToIndex_) { + onScrollToIndex_(param); + } + } + + RefPtr FireOnItemDragStart(const ItemDragInfo& dragInfo, int32_t itemIndex) const; + + void FireOnItemDragEnter(const ItemDragInfo& dragInfo) const + { + if (onItemDragEnter_) { + onItemDragEnter_(dragInfo); + } + } + + void FireOnItemDragMove(const ItemDragInfo& dragInfo, int32_t itemIndex, int32_t insertIndex) const + { + if (onItemDragMove_) { + onItemDragMove_(dragInfo, itemIndex, insertIndex); + } + } + + void FireOnItemDragLeave(const ItemDragInfo& dragInfo, int32_t itemIndex) const + { + if (onItemDragLeave_) { + onItemDragLeave_(dragInfo, itemIndex); + } + } + + void FireOnItemDrop(const ItemDragInfo& dragInfo, int32_t itemIndex, int32_t insertIndex, bool isSuccess) const + { + if (onItemDrop_) { + onItemDrop_(dragInfo, itemIndex, insertIndex, isSuccess); + } + } + +private: + ScrollToIndexFunc onScrollToIndex_; + ItemDragStartFunc onItemDragStart_; + ItemDragEnterFunc onItemDragEnter_; + ItemDragMoveFunc onItemDragMove_; + ItemDragLeaveFunc onItemDragLeave_; + ItemDropFunc onItemDrop_; +}; + +} // namespace OHOS::Ace::NG +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_EVENT_HUB_H \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/grid/grid_item_event_hub.h b/frameworks/core/components_ng/pattern/grid/grid_item_event_hub.h new file mode 100644 index 0000000000000000000000000000000000000000..42a5a5c7d57a71abea5ea8658cb326a0803c51e5 --- /dev/null +++ b/frameworks/core/components_ng/pattern/grid/grid_item_event_hub.h @@ -0,0 +1,52 @@ +/* + * 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_ITEM_EVENT_HUB_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_ITEM_EVENT_HUB_H + +#include + +#include "base/memory/ace_type.h" +#include "core/components_ng/event/event_hub.h" + +namespace OHOS::Ace::NG { + +using SelectFunc = std::function; + +class GridItemEventHub : public EventHub { + DECLARE_ACE_TYPE(GridItemEventHub, EventHub) + +public: + GridItemEventHub() = default; + ~GridItemEventHub() override = default; + + void SetOnSelect(SelectFunc&& onSelect) + { + onSelect_ = std::move(onSelect); + } + + void FireOnSelect(bool isSelected) const + { + if (onSelect_) { + onSelect_(isSelected); + } + } + +private: + SelectFunc onSelect_; +}; + +} // namespace OHOS::Ace::NG +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_ITEM_EVENT_HUB_H \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/grid/grid_item_layout_property.h b/frameworks/core/components_ng/pattern/grid/grid_item_layout_property.h new file mode 100644 index 0000000000000000000000000000000000000000..08e1d2633a882497455fa35b9a414ee7700827b2 --- /dev/null +++ b/frameworks/core/components_ng/pattern/grid/grid_item_layout_property.h @@ -0,0 +1,60 @@ +/* + * 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_ITEM_LAYOUT_PROPERTY_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_ITEM_LAYOUT_PROPERTY_H + +#include "core/components_ng/layout/layout_property.h" + +namespace OHOS::Ace::NG { + +class ACE_EXPORT GridItemLayoutProperty : public LayoutProperty { + DECLARE_ACE_TYPE(GridItemLayoutProperty, LayoutProperty); + +public: + GridItemLayoutProperty() = default; + ~GridItemLayoutProperty() override = default; + + RefPtr Clone() const override + { + auto value = MakeRefPtr(); + value->LayoutProperty::UpdateLayoutProperty(DynamicCast(this)); + value->propRowStart_ = CloneRowStart(); + value->propRowEnd_ = CloneRowEnd(); + value->propColumnStart_ = CloneColumnStart(); + value->propColumnEnd_ = CloneColumnEnd(); + return value; + } + + void Reset() override + { + LayoutProperty::Reset(); + ResetRowStart(); + ResetRowEnd(); + ResetColumnStart(); + ResetColumnEnd(); + } + + ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(RowStart, int32_t, PROPERTY_UPDATE_LAYOUT); + ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(RowEnd, int32_t, PROPERTY_UPDATE_LAYOUT); + ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(ColumnStart, int32_t, PROPERTY_UPDATE_LAYOUT); + ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(ColumnEnd, int32_t, PROPERTY_UPDATE_LAYOUT); + +private: + ACE_DISALLOW_COPY_AND_MOVE(GridItemLayoutProperty); +}; + +} // namespace OHOS::Ace::NG +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_ITEM_LAYOUT_PROPERTY_H diff --git a/frameworks/core/components_ng/pattern/grid/grid_item_pattern.h b/frameworks/core/components_ng/pattern/grid/grid_item_pattern.h index 570f7f260c71866d852d8677ceb04a17f92ad4ae..13ce3fef086ed231737ba9ef28d5030457a13295 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_item_pattern.h +++ b/frameworks/core/components_ng/pattern/grid/grid_item_pattern.h @@ -18,6 +18,7 @@ #include "base/memory/referenced.h" #include "base/utils/noncopyable.h" +#include "core/components_ng/pattern/grid/grid_item_layout_property.h" #include "core/components_ng/pattern/pattern.h" #include "core/components_ng/syntax/shallow_builder.h" @@ -35,6 +36,11 @@ public: return false; } + RefPtr CreateLayoutProperty() override + { + return MakeRefPtr(); + } + void BeforeCreateLayoutWrapper() override { if (shallowBuilder_ && !shallowBuilder_->IsExecuteDeepRenderDone()) { @@ -43,8 +49,30 @@ public: } } + void SetForceRebuild(bool forceRebuild) + { + forceRebuild_ = forceRebuild; + } + + void SetSelectable(bool selectable) + { + selectable_ = selectable; + } + + bool ForceRebuild() const + { + return forceRebuild_; + } + + bool Selectable() const + { + return selectable_; + } + private: RefPtr shallowBuilder_; + bool forceRebuild_ = false; + bool selectable_ = true; ACE_DISALLOW_COPY_AND_MOVE(GridItemPattern); }; diff --git a/frameworks/core/components_ng/pattern/grid/grid_item_view.cpp b/frameworks/core/components_ng/pattern/grid/grid_item_view.cpp index d9d2ced217fe2ed1e85e6d9fe8ab526588725920..a0e4d8a5825b53bcc8914d9d948e6d978c4cf624 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_item_view.cpp +++ b/frameworks/core/components_ng/pattern/grid/grid_item_view.cpp @@ -16,6 +16,7 @@ #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_layout_property.h" #include "core/components_ng/pattern/grid/grid_item_pattern.h" #include "core/components_v2/inspector/inspector_constants.h" @@ -46,4 +47,51 @@ void GridItemView::Create() stack->Push(frameNode); } +void GridItemView::SetRowStart(int32_t value) +{ + ACE_UPDATE_LAYOUT_PROPERTY(GridItemLayoutProperty, RowStart, value); +} + +void GridItemView::SetRowEnd(int32_t value) +{ + ACE_UPDATE_LAYOUT_PROPERTY(GridItemLayoutProperty, RowEnd, value); +} + +void GridItemView::SetColumnStart(int32_t value) +{ + ACE_UPDATE_LAYOUT_PROPERTY(GridItemLayoutProperty, ColumnStart, value); +} + +void GridItemView::SetColumnEnd(int32_t value) +{ + ACE_UPDATE_LAYOUT_PROPERTY(GridItemLayoutProperty, ColumnEnd, value); +} + +void GridItemView::SetForceRebuild(bool value) +{ + auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); + CHECK_NULL_VOID(frameNode); + auto pattern = frameNode->GetPattern(); + CHECK_NULL_VOID(pattern); + pattern->SetForceRebuild(value); +} + +void GridItemView::SetSelectable(bool value) +{ + auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); + CHECK_NULL_VOID(frameNode); + auto pattern = frameNode->GetPattern(); + CHECK_NULL_VOID(pattern); + pattern->SetSelectable(value); +} + +void GridItemView::SetOnSelect(SelectFunc&& onSelect) +{ + auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); + CHECK_NULL_VOID(frameNode); + auto eventHub = frameNode->GetEventHub(); + CHECK_NULL_VOID(eventHub); + eventHub->SetOnSelect(std::move(onSelect)); +} + } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/grid/grid_item_view.h b/frameworks/core/components_ng/pattern/grid/grid_item_view.h index d854acde9dddefe4c3c4e3437c2f886927d1f548..b38a5bbf9861370f25e7e3ea6b7fd1a87384d6c4 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_item_view.h +++ b/frameworks/core/components_ng/pattern/grid/grid_item_view.h @@ -19,13 +19,22 @@ #include #include "base/utils/macros.h" +#include "core/components_ng/pattern/grid/grid_item_event_hub.h" namespace OHOS::Ace::NG { + class ACE_EXPORT GridItemView { public: static void Create(std::function&& deepRenderFunc); static void Create(); + static void SetRowStart(int32_t value); + static void SetRowEnd(int32_t value); + static void SetColumnStart(int32_t value); + static void SetColumnEnd(int32_t value); + static void SetForceRebuild(bool value); + static void SetSelectable(bool value); + static void SetOnSelect(SelectFunc&& onSelect); }; -} // namespace OHOS::Ace::NG +} // namespace OHOS::Ace::NG #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_GRID_GRID_ITEM_VIEW_H diff --git a/frameworks/core/components_ng/pattern/grid/grid_layout/grid_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/grid/grid_layout/grid_layout_algorithm.cpp new file mode 100644 index 0000000000000000000000000000000000000000..be38b8d663952e962a27829fbfaa3a3fc430af60 --- /dev/null +++ b/frameworks/core/components_ng/pattern/grid/grid_layout/grid_layout_algorithm.cpp @@ -0,0 +1,282 @@ +/* + * 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/grid_layout_algorithm.h" + +#include + +#include "base/geometry/ng/offset_t.h" +#include "base/geometry/ng/size_t.h" +#include "base/utils/utils.h" +#include "core/components_ng/pattern/grid/grid_item_layout_property.h" +#include "core/components_ng/pattern/grid/grid_layout_property.h" +#include "core/components_ng/pattern/grid/grid_utils.h" +#include "core/components_ng/property/layout_constraint.h" +#include "core/components_ng/property/measure_utils.h" + +namespace OHOS::Ace::NG { + +LayoutConstraintF GridLayoutAlgorithm::CreateChildConstraint(const SizeF& idealSize, + const RefPtr& layoutProperty, int32_t row, int32_t col, int32_t& rowSpan, + int32_t& colSpan) const +{ + LayoutConstraintF layoutConstraint = layoutProperty->CreateChildConstraint(); + auto scale = layoutProperty->GetLayoutConstraint()->scaleProperty; + auto rowsGap = ConvertToPx(layoutProperty->GetRowsGap().value_or(0.0_vp), scale, idealSize.Width()).value_or(0); + auto columnsGap = + ConvertToPx(layoutProperty->GetColumnsGap().value_or(0.0_vp), scale, idealSize.Height()).value_or(0); + + float rowLen = 0.0; + for (int32_t i = 0; i < rowSpan; ++i) { + rowLen += gridCells_.at(row + i).at(col).Height(); + } + rowLen += (rowSpan - 1) * rowsGap; + + float colLen = 0.0; + for (int32_t i = 0; i < colSpan; ++i) { + colLen += gridCells_.at(row).at(col + i).Width(); + } + colLen += (colSpan - 1) * columnsGap; + + layoutConstraint.maxSize = SizeF(colLen, rowLen); + layoutConstraint.selfIdealSize.UpdateIllegalSizeWithCheck(SizeF(colLen, rowLen)); + return layoutConstraint; +} + +void GridLayoutAlgorithm::InitGridCeils(LayoutWrapper* layoutWrapper, const SizeF& idealSize) +{ + auto layoutProperty = DynamicCast(layoutWrapper->GetLayoutProperty()); + CHECK_NULL_VOID(layoutProperty); + auto scale = layoutProperty->GetLayoutConstraint()->scaleProperty; + auto rowsGap = ConvertToPx(layoutProperty->GetRowsGap().value_or(0.0_vp), scale, idealSize.Width()).value_or(0); + auto columnsGap = + ConvertToPx(layoutProperty->GetColumnsGap().value_or(0.0_vp), scale, idealSize.Height()).value_or(0); + auto rowsLen = GridUtils::ParseArgs(layoutProperty->GetRowsTemplate().value_or(""), idealSize.Height(), rowsGap); + auto colsLen = + GridUtils::ParseArgs(layoutProperty->GetColumnsTemplate().value_or(""), idealSize.Width(), columnsGap); + if (rowsLen.empty()) { + rowsLen.push_back(idealSize.Height()); + } + if (colsLen.empty()) { + colsLen.push_back(idealSize.Width()); + } + gridCells_.clear(); + int32_t row = 0; + for (const auto& height : rowsLen) { + int32_t col = 0; + for (const auto& width : colsLen) { + gridCells_[row][col] = SizeF(width, height); + ++col; + } + ++row; + } +} + +bool GridLayoutAlgorithm::CheckGridPlaced(int32_t index, int32_t row, int32_t col, int32_t& rowSpan, int32_t& colSpan) +{ + auto rowIter = gridMatrix_.find(row); + if (rowIter != gridMatrix_.end()) { + auto colIter = rowIter->second.find(col); + if (colIter != rowIter->second.end()) { + return false; + } + } + rowSpan = std::min(mainCount_ - row, rowSpan); + colSpan = std::min(crossCount_ - col, colSpan); + int32_t rSpan = 0; + int32_t cSpan = 0; + int32_t retColSpan = 1; + while (rSpan < rowSpan) { + rowIter = gridMatrix_.find(rSpan + row); + if (rowIter != gridMatrix_.end()) { + cSpan = 0; + while (cSpan < colSpan) { + if (rowIter->second.find(cSpan + col) != rowIter->second.end()) { + colSpan = cSpan; + break; + } + ++cSpan; + } + } else { + cSpan = colSpan; + } + if (retColSpan > cSpan) { + break; + } + retColSpan = cSpan; + ++rSpan; + } + + rowSpan = rSpan; + colSpan = retColSpan; + for (int32_t i = row; i < row + rowSpan; ++i) { + std::map rowMap; + auto iter = gridMatrix_.find(i); + if (iter != gridMatrix_.end()) { + rowMap = iter->second; + } + for (int32_t j = col; j < col + colSpan; ++j) { + rowMap.emplace(std::make_pair(j, index)); + } + gridMatrix_[i] = rowMap; + } + return true; +} + +void GridLayoutAlgorithm::GetNextGrid(int32_t& curRow, int32_t& curCol) const +{ + if (isVertical_) { + ++curCol; + if (curCol >= crossCount_) { + curCol = 0; + ++curRow; + } + } else { + ++curRow; + if (curRow >= mainCount_) { + curRow = 0; + ++curCol; + } + } +} + +OffsetF GridLayoutAlgorithm::ComputeItemPosition( + LayoutWrapper* layoutWrapper, int32_t row, int32_t col, int32_t& rowSpan, int32_t& colSpan) const +{ + auto layoutProperty = DynamicCast(layoutWrapper->GetLayoutProperty()); + CHECK_NULL_RETURN(layoutProperty, OffsetF()); + auto frameSize = layoutWrapper->GetGeometryNode()->GetFrameSize(); + auto scale = layoutProperty->GetLayoutConstraint()->scaleProperty; + auto rowsGap = ConvertToPx(layoutProperty->GetRowsGap().value_or(0.0_vp), scale, frameSize.Width()).value_or(0); + auto columnsGap = + ConvertToPx(layoutProperty->GetColumnsGap().value_or(0.0_vp), scale, frameSize.Height()).value_or(0); + + // Calculate the position for current child. + float positionX = 0.0f; + float positionY = 0.0f; + for (int32_t i = 0; i < row; ++i) { + positionY += gridCells_.at(i).at(0).Height(); + } + positionY += row * rowsGap; + for (int32_t i = 0; i < col; ++i) { + positionX += gridCells_.at(0).at(i).Width(); + } + positionX += col * columnsGap; + + // Calculate the size for current child. + float rowLen = 0.0f; + float colLen = 0.0f; + for (int32_t i = 0; i < rowSpan; ++i) { + rowLen += gridCells_.at(row + i).at(col).Height(); + } + rowLen += (rowSpan - 1) * rowsGap; + for (int32_t i = 0; i < colSpan; ++i) { + colLen += gridCells_.at(row).at(col + i).Width(); + } + colLen += (colSpan - 1) * columnsGap; + + // If RTL, place the item from right. + if (rightToLeft_) { + positionX = frameSize.Width() - positionX - colLen; + } + return OffsetF(positionX, positionY); +} + +void GridLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper) +{ + auto gridLayoutProperty = AceType::DynamicCast(layoutWrapper->GetLayoutProperty()); + CHECK_NULL_VOID(gridLayoutProperty); + Axis axis = gridLayoutInfo_.axis_; + auto idealSize = + CreateIdealSize(gridLayoutProperty->GetLayoutConstraint().value(), axis, MeasureType::MATCH_PARENT, true); + if (GreatOrEqual(GetMainAxisSize(idealSize, axis), Infinity())) { + LOGE("size of main axis value is infinity, please check"); + return; + } + + layoutWrapper->GetGeometryNode()->SetFrameSize(idealSize); + MinusPaddingToSize(gridLayoutProperty->CreatePaddingAndBorder(), idealSize); + InitGridCeils(layoutWrapper, idealSize); + + int32_t rowIndex = 0; + int32_t colIndex = 0; + int32_t itemIndex = 0; + itemsPosition_.clear(); + for (int32_t index = 0; index < mainCount_ * crossCount_; ++index) { + auto childLayoutWrapper = layoutWrapper->GetOrCreateChildByIndex(index); + if (!childLayoutWrapper) { + continue; + } + auto childLayoutProperty = DynamicCast(childLayoutWrapper->GetLayoutProperty()); + if (!childLayoutProperty) { + continue; + } + int32_t itemRowStart = childLayoutProperty->GetRowStart().value_or(-1); + int32_t itemColStart = childLayoutProperty->GetColumnStart().value_or(-1); + int32_t itemRowSpan = std::max(childLayoutProperty->GetRowEnd().value_or(-1) - itemRowStart + 1, 1); + int32_t itemColSpan = std::max(childLayoutProperty->GetColumnEnd().value_or(-1) - itemColStart + 1, 1); + if (itemRowStart >= 0 && itemRowStart < mainCount_ && itemColStart >= 0 && itemColStart < crossCount_ && + CheckGridPlaced(itemIndex, itemRowStart, itemColStart, itemRowSpan, itemColSpan)) { + childLayoutWrapper->Measure(CreateChildConstraint( + idealSize, gridLayoutProperty, itemRowStart, itemColStart, itemRowSpan, itemColSpan)); + itemsPosition_.try_emplace( + index, ComputeItemPosition(layoutWrapper, itemRowStart, itemColStart, itemRowSpan, itemColSpan)); + } else { + while (!CheckGridPlaced(itemIndex, rowIndex, colIndex, itemRowSpan, itemColSpan)) { + GetNextGrid(rowIndex, colIndex); + if (rowIndex >= mainCount_ || colIndex >= crossCount_) { + break; + } + } + if (rowIndex >= mainCount_ || colIndex >= crossCount_) { + continue; + } + childLayoutWrapper->Measure( + CreateChildConstraint(idealSize, gridLayoutProperty, rowIndex, colIndex, itemRowSpan, itemColSpan)); + itemsPosition_.try_emplace( + index, ComputeItemPosition(layoutWrapper, rowIndex, colIndex, itemRowSpan, itemColSpan)); + } + ++itemIndex; + } +} + +void GridLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper) +{ + CHECK_NULL_VOID(layoutWrapper); + auto layoutProperty = AceType::DynamicCast(layoutWrapper->GetLayoutProperty()); + CHECK_NULL_VOID(layoutProperty); + auto frameSize = layoutWrapper->GetGeometryNode()->GetFrameSize(); + auto padding = layoutProperty->CreatePaddingAndBorder(); + MinusPaddingToSize(padding, frameSize); + + auto parentOffset = + layoutWrapper->GetGeometryNode()->GetParentGlobalOffset() + layoutWrapper->GetGeometryNode()->GetFrameOffset(); + + for (int32_t index = 0; index < mainCount_ * crossCount_; ++index) { + auto childWrapper = layoutWrapper->GetOrCreateChildByIndex(index); + if (!childWrapper) { + continue; + } + OffsetF childOffset; + auto childPosition = itemsPosition_.find(index); + if (childPosition != itemsPosition_.end()) { + childOffset = itemsPosition_.at(index); + } + childWrapper->GetGeometryNode()->SetFrameOffset(padding.Offset() + childOffset); + childWrapper->Layout(parentOffset); + } +} + +} // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/grid/grid_layout/grid_layout_algorithm.h b/frameworks/core/components_ng/pattern/grid/grid_layout/grid_layout_algorithm.h new file mode 100644 index 0000000000000000000000000000000000000000..c4146e16f1585d8bff75c70fbb1a8ba0f860e731 --- /dev/null +++ b/frameworks/core/components_ng/pattern/grid/grid_layout/grid_layout_algorithm.h @@ -0,0 +1,73 @@ +/* + * 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_GRID_LAYOUT_ALGORITHM_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_LAYOUT_GRID_LAYOUT_ALGORITHM_H + +#include + +#include "core/components_ng/layout/layout_algorithm.h" +#include "core/components_ng/layout/layout_wrapper.h" +#include "core/components_ng/pattern/grid/grid_layout_info.h" +#include "core/components_ng/pattern/grid/grid_layout_property.h" +#include "core/components_ng/property/layout_constraint.h" + +namespace OHOS::Ace::NG { + +class ACE_EXPORT GridLayoutAlgorithm : public LayoutAlgorithm { + DECLARE_ACE_TYPE(GridLayoutAlgorithm, LayoutAlgorithm); + +public: + GridLayoutAlgorithm(GridLayoutInfo gridLayoutInfo, int32_t crossCount, int32_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() + { + return gridLayoutInfo_; + } + +private: + void InitGridCeils(LayoutWrapper* layoutWrapper, const SizeF& idealSize); + bool CheckGridPlaced(int32_t index, int32_t row, int32_t col, int32_t& rowSpan, int32_t& colSpan); + void GetNextGrid(int32_t& curRow, int32_t& curCol) const; + OffsetF ComputeItemPosition( + LayoutWrapper* layoutWrapper, int32_t row, int32_t col, int32_t& rowSpan, int32_t& colSpan) const; + LayoutConstraintF CreateChildConstraint(const SizeF& idealSize, const RefPtr& layoutProperty, + int32_t row, int32_t col, int32_t& rowSpan, int32_t& colSpan) const; + + GridLayoutInfo gridLayoutInfo_; + int32_t crossCount_ = 0; + int32_t mainCount_ = 0; + bool isVertical_ = true; + bool rightToLeft_ = false; + + // Map structure: [rowIndex, [columnIndex - (width, height)]]. + std::map> gridCells_; + + // Map structure: [rowIndex, [columnIndex, index]]. + std::map> gridMatrix_; + + // Map structure: [index, [positionX, positionY]], store position of each item. + std::map itemsPosition_; + + ACE_DISALLOW_COPY_AND_MOVE(GridLayoutAlgorithm); +}; + +} // namespace OHOS::Ace::NG +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_LAYOUT_GRID_LAYOUT_ALGORITHM_H diff --git a/frameworks/core/components_ng/pattern/grid/grid_layout_info.h b/frameworks/core/components_ng/pattern/grid/grid_layout_info.h new file mode 100644 index 0000000000000000000000000000000000000000..a222fb0267d4851ab39e3209e4c81d9499dc7704 --- /dev/null +++ b/frameworks/core/components_ng/pattern/grid/grid_layout_info.h @@ -0,0 +1,52 @@ +/* + * 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_INFO_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_LAYOUT_INFO_H + +#include + +#include "base/geometry/axis.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> gridMatrix_; + // in vertical grid, this map is like: [rowIndex: rowHeight] + std::map lineHeightMap_; +}; + +} // namespace OHOS::Ace::NG +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_LAYOUT_ALGORITHM_H \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/grid/grid_layout_property.h b/frameworks/core/components_ng/pattern/grid/grid_layout_property.h index 29e7ef7c918d6563b6e5dadbf60a251f20f7e5b4..a6cfac343b723e554877cde10ef00bb93daa0594 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_layout_property.h +++ b/frameworks/core/components_ng/pattern/grid/grid_layout_property.h @@ -16,9 +16,18 @@ #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/common/properties/scroll_bar.h" #include "core/components_ng/layout/layout_property.h" +#include "core/components_ng/property/property.h" namespace OHOS::Ace::NG { + +struct ScrollBarProperty { + ACE_DEFINE_PROPERTY_GROUP_ITEM(ScrollBarMode, DisplayMode); + ACE_DEFINE_PROPERTY_GROUP_ITEM(ScrollBarWidth, Dimension); + ACE_DEFINE_PROPERTY_GROUP_ITEM(ScrollBarColor, Color); +}; + class ACE_EXPORT GridLayoutProperty : public LayoutProperty { DECLARE_ACE_TYPE(GridLayoutProperty, LayoutProperty); @@ -30,8 +39,16 @@ public: { auto value = MakeRefPtr(); value->LayoutProperty::UpdateLayoutProperty(DynamicCast(this)); + value->propRowsTemplate_ = CloneRowsTemplate(); value->propColumnsTemplate_ = CloneColumnsTemplate(); - value->propColumnsTemplate_ = CloneColumnsTemplate(); + value->propRowsGap_ = CloneRowsGap(); + value->propColumnsGap_ = CloneColumnsGap(); + value->propCachedCount_ = CloneCachedCount(); + value->propLayoutDirection_ = CloneLayoutDirection(); + value->propMaxCount_ = CloneMaxCount(); + value->propMinCount_ = CloneMinCount(); + value->propCellLength_ = CloneCellLength(); + value->propScrollBarProperty_ = CloneScrollBarProperty(); return value; } @@ -40,7 +57,16 @@ public: LayoutProperty::Reset(); ResetColumnsTemplate(); ResetRowsTemplate(); + ResetColumnsGap(); + ResetRowsGap(); + ResetCachedCount(); + ResetLayoutDirection(); + ResetMaxCount(); + ResetMinCount(); + ResetCellLength(); + ResetScrollBarProperty(); } + bool IsVertical() const { bool columnsTemplateValid = propColumnsTemplate_.has_value() && !propColumnsTemplate_.value().empty(); @@ -48,6 +74,7 @@ public: return columnsTemplateValid || (!columnsTemplateValid && !rowsTemplateValid); // TODO: take layoutDirection into account } + bool IsConfiguredScrollable() const { bool columnsTemplateSet = !propColumnsTemplate_.value_or("").empty(); @@ -59,6 +86,19 @@ public: ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(ColumnsTemplate, std::string, PROPERTY_UPDATE_LAYOUT); ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(RowsTemplate, std::string, PROPERTY_UPDATE_LAYOUT); + ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(ColumnsGap, Dimension, PROPERTY_UPDATE_LAYOUT); + ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(RowsGap, Dimension, PROPERTY_UPDATE_LAYOUT); + ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(CachedCount, int32_t, PROPERTY_UPDATE_LAYOUT); + ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(LayoutDirection, FlexDirection, PROPERTY_UPDATE_LAYOUT); + ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(MaxCount, int32_t, PROPERTY_UPDATE_LAYOUT); + ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(MinCount, int32_t, PROPERTY_UPDATE_LAYOUT); + ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(CellLength, int32_t, PROPERTY_UPDATE_LAYOUT); + ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Editable, bool, PROPERTY_UPDATE_LAYOUT); + + ACE_DEFINE_PROPERTY_GROUP(ScrollBarProperty, ScrollBarProperty); + ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(ScrollBarProperty, ScrollBarMode, DisplayMode, PROPERTY_UPDATE_MEASURE); + ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(ScrollBarProperty, ScrollBarWidth, Dimension, PROPERTY_UPDATE_MEASURE); + ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(ScrollBarProperty, ScrollBarColor, Color, PROPERTY_UPDATE_RENDER); private: ACE_DISALLOW_COPY_AND_MOVE(GridLayoutProperty); diff --git a/frameworks/core/components_ng/pattern/grid/grid_pattern.cpp b/frameworks/core/components_ng/pattern/grid/grid_pattern.cpp index a84d11831198b81b3a913b089f44d65cdabe1a96..2464558715485989dbabf1124b2569613b55cb1e 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_pattern.cpp +++ b/frameworks/core/components_ng/pattern/grid/grid_pattern.cpp @@ -15,10 +15,36 @@ #include "core/components_ng/pattern/grid/grid_pattern.h" +#include "core/components_ng/pattern/grid/grid_adaptive/grid_adaptive_layout_algorithm.h" +#include "core/components_ng/pattern/grid/grid_layout/grid_layout_algorithm.h" +#include "core/components_ng/pattern/grid/grid_scroll/grid_scroll_layout_algorithm.h" #include "core/components_ng/property/property.h" namespace OHOS::Ace::NG { +RefPtr GridPattern::CreateLayoutAlgorithm() +{ + auto gridLayoutProperty = GetLayoutProperty(); + CHECK_NULL_RETURN(gridLayoutProperty, nullptr); + std::vector cols; + StringUtils::StringSplitter(gridLayoutProperty->GetColumnsTemplate().value_or(""), ' ', cols); + std::vector rows; + StringUtils::StringSplitter(gridLayoutProperty->GetRowsTemplate().value_or(""), ' ', rows); + auto crossCount = cols.empty() ? Infinity() : cols.size(); + auto mainCount = rows.empty() ? Infinity() : rows.size(); + if (!gridLayoutProperty->IsVertical()) { + std::swap(crossCount, mainCount); + } + + if (!rows.empty() && !cols.empty()) { + return MakeRefPtr(gridLayoutInfo_, crossCount, mainCount); + } + if (rows.empty() && cols.empty()) { + return MakeRefPtr(gridLayoutInfo_); + } + return MakeRefPtr(gridLayoutInfo_, crossCount, mainCount); +} + void GridPattern::OnAttachToFrameNode() { auto host = GetHost(); diff --git a/frameworks/core/components_ng/pattern/grid/grid_pattern.h b/frameworks/core/components_ng/pattern/grid/grid_pattern.h index 0d538c21179c1db59e76d0cd6518037865bbaeb7..a1278837ce00915626679fd6896f337944ef8154 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_pattern.h +++ b/frameworks/core/components_ng/pattern/grid/grid_pattern.h @@ -17,7 +17,7 @@ #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_info.h" #include "core/components_ng/pattern/grid/grid_layout_property.h" #include "core/components_ng/pattern/pattern.h" @@ -40,20 +40,26 @@ public: return MakeRefPtr(); } - RefPtr CreateLayoutAlgorithm() override + RefPtr CreateLayoutAlgorithm() override; + + void SetMultiSelectable(bool multiSelectable) + { + multiSelectable_ = multiSelectable; + } + + bool MultiSelectable() const { - auto gridLayoutProperty = GetLayoutProperty(); - CHECK_NULL_RETURN(gridLayoutProperty, nullptr); - std::vector cols; - StringUtils::StringSplitter(gridLayoutProperty->GetColumnsTemplate().value_or(""), ' ', cols); - std::vector rows; - StringUtils::StringSplitter(gridLayoutProperty->GetRowsTemplate().value_or(""), ' ', rows); - auto crossCount = cols.empty() ? Infinity() : cols.size(); - auto mainCount = rows.empty() ? Infinity() : rows.size(); - if (!gridLayoutProperty->IsVertical()) { - std::swap(crossCount, mainCount); - } - return MakeRefPtr(gridLayoutInfo_, crossCount, mainCount); + return multiSelectable_; + } + + void SetSupportAnimation(bool supportAnimation) + { + supportAnimation_ = supportAnimation; + } + + bool SupportAnimation() const + { + return supportAnimation_; } private: @@ -66,6 +72,9 @@ private: GridLayoutInfo gridLayoutInfo_; RefPtr scrollableEvent_; + bool multiSelectable_ = false; + bool supportAnimation_ = false; + ACE_DISALLOW_COPY_AND_MOVE(GridPattern); }; diff --git a/frameworks/core/components_ng/pattern/grid/grid_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/grid/grid_scroll/grid_scroll_layout_algorithm.cpp similarity index 93% rename from frameworks/core/components_ng/pattern/grid/grid_layout_algorithm.cpp rename to frameworks/core/components_ng/pattern/grid/grid_scroll/grid_scroll_layout_algorithm.cpp index fe48f9f8ff8bc6067ba92d361972f09116b62c56..c3346a00892f8a66e48827dd81d352acecb757ea 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/grid/grid_scroll/grid_scroll_layout_algorithm.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "core/components_ng/pattern/grid/grid_layout_algorithm.h" +#include "core/components_ng/pattern/grid/grid_scroll/grid_scroll_layout_algorithm.h" #include @@ -28,7 +28,7 @@ namespace OHOS::Ace::NG { -void GridLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper) +void GridScrollLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper) { auto gridLayoutProperty = AceType::DynamicCast(layoutWrapper->GetLayoutProperty()); CHECK_NULL_VOID(gridLayoutProperty); @@ -52,7 +52,7 @@ void GridLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper) StripItemsOutOfViewport(layoutWrapper); } -void GridLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper) +void GridScrollLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper) { auto gridLayoutProperty = AceType::DynamicCast(layoutWrapper->GetLayoutProperty()); CHECK_NULL_VOID(gridLayoutProperty); @@ -92,7 +92,7 @@ void GridLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper) } } -void GridLayoutAlgorithm::FillGridViewportAndMeasureChildren( +void GridScrollLayoutAlgorithm::FillGridViewportAndMeasureChildren( float mainSize, float crossSize, const RefPtr& gridLayoutProperty, LayoutWrapper* layoutWrapper) { float mainLength = gridLayoutInfo_.currentOffset_; @@ -115,7 +115,7 @@ void GridLayoutAlgorithm::FillGridViewportAndMeasureChildren( } } -void GridLayoutAlgorithm::FillBlankAtStart(float mainSize, float crossSize, +void GridScrollLayoutAlgorithm::FillBlankAtStart(float mainSize, float crossSize, const RefPtr& gridLayoutProperty, LayoutWrapper* layoutWrapper, float& mainLength) { if (LessOrEqual( @@ -139,7 +139,7 @@ void GridLayoutAlgorithm::FillBlankAtStart(float mainSize, float crossSize, // 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) +void GridScrollLayoutAlgorithm::ModifyCurrentOffsetWhenReachEnd(float mainSize) { // Step1. Calculate total length of all items in viewport. [lengthOfItemsInViewport] must be greater than or equal // to viewport height @@ -157,7 +157,7 @@ void GridLayoutAlgorithm::ModifyCurrentOffsetWhenReachEnd(float mainSize) gridLayoutInfo_.prevOffset_ = gridLayoutInfo_.currentOffset_; } -void GridLayoutAlgorithm::FillBlankAtEnd(float mainSize, float crossSize, +void GridScrollLayoutAlgorithm::FillBlankAtEnd(float mainSize, float crossSize, const RefPtr& gridLayoutProperty, LayoutWrapper* layoutWrapper, float& mainLength) { // When [mainLength] is still less than [mainSize], do [FillNewLineBackward] repeatedly until filling up the lower @@ -173,7 +173,7 @@ void GridLayoutAlgorithm::FillBlankAtEnd(float mainSize, float crossSize, }; } -void GridLayoutAlgorithm::MeasureRecordedItems(float mainSize, float crossSize, +void GridScrollLayoutAlgorithm::MeasureRecordedItems(float mainSize, float crossSize, const RefPtr& gridLayoutProperty, LayoutWrapper* layoutWrapper, float& mainLength) { currentMainLineIndex_ = gridLayoutInfo_.startMainLineIndex_ - 1; @@ -225,7 +225,7 @@ void GridLayoutAlgorithm::MeasureRecordedItems(float mainSize, float crossSize, gridLayoutInfo_.endMainLineIndex_ = runOutOfRecord ? --currentMainLineIndex_ : currentMainLineIndex_; } -float GridLayoutAlgorithm::FillNewLineForward( +float GridScrollLayoutAlgorithm::FillNewLineForward( float crossSize, float mainSize, const RefPtr& gridLayoutProperty, LayoutWrapper* layoutWrapper) { // To make the code more convinient to read, we name a param in situation of vertical, for exacmple: @@ -273,10 +273,10 @@ float GridLayoutAlgorithm::FillNewLineForward( return lineHeight; } -float GridLayoutAlgorithm::FillNewLineBackward( +float GridScrollLayoutAlgorithm::FillNewLineBackward( float crossSize, float mainSize, const RefPtr& gridLayoutProperty, LayoutWrapper* layoutWrapper) { - // To make the code more convinient to read, we name a param in situation of vertical, for exacmple: + // To make the code more convenient to read, we name a param in situation of vertical, for example: // 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. @@ -316,7 +316,7 @@ float GridLayoutAlgorithm::FillNewLineBackward( } return lineHeight; } -void GridLayoutAlgorithm::StripItemsOutOfViewport(LayoutWrapper* layoutWrapper) +void GridScrollLayoutAlgorithm::StripItemsOutOfViewport(LayoutWrapper* layoutWrapper) { // Erase records that are out of viewport // 1. Erase records that are on top of viewport @@ -345,7 +345,7 @@ void GridLayoutAlgorithm::StripItemsOutOfViewport(LayoutWrapper* layoutWrapper) LOGD("grid item size : %{public}d", static_cast(gridLayoutInfo_.gridMatrix_.size())); } -LayoutConstraintF GridLayoutAlgorithm::MakeMeasureConstraintForGridItem(float mainSize, float crossSize, +LayoutConstraintF GridScrollLayoutAlgorithm::MakeMeasureConstraintForGridItem(float mainSize, float crossSize, uint32_t itemFractionCount, const RefPtr& gridLayoutProperty) const { float itemMainSize = @@ -373,13 +373,13 @@ LayoutConstraintF GridLayoutAlgorithm::MakeMeasureConstraintForGridItem(float ma return itemConstraint; } -GridLayoutInfo GridLayoutAlgorithm::GetGridLayoutInfo() +GridLayoutInfo GridScrollLayoutAlgorithm::GetGridLayoutInfo() { return std::move(gridLayoutInfo_); } // only for debug use -void GridLayoutAlgorithm::PrintGridMatrix(const std::map>& gridMatrix) +void GridScrollLayoutAlgorithm::PrintGridMatrix(const std::map>& gridMatrix) { for (const auto& record : gridMatrix) { for (const auto& item : record.second) { @@ -390,7 +390,7 @@ void GridLayoutAlgorithm::PrintGridMatrix(const std::map& lineHeightMap) +void GridScrollLayoutAlgorithm::PrintLineHeightMap(const std::map& lineHeightMap) { for (const auto& record : lineHeightMap) { LOGD("line height -- line: %{public}d, lineHeight: %{public}f", record.first, record.second); diff --git a/frameworks/core/components_ng/pattern/grid/grid_layout_algorithm.h b/frameworks/core/components_ng/pattern/grid/grid_scroll/grid_scroll_layout_algorithm.h similarity index 68% rename from frameworks/core/components_ng/pattern/grid/grid_layout_algorithm.h rename to frameworks/core/components_ng/pattern/grid/grid_scroll/grid_scroll_layout_algorithm.h index c6412c34d0d6876077ab77a56db6f7453d7a38cd..8ab13943d1c9d7de5f54f0a945375e13b427a645 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_layout_algorithm.h +++ b/frameworks/core/components_ng/pattern/grid/grid_scroll/grid_scroll_layout_algorithm.h @@ -13,48 +13,23 @@ * 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 +#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_SCROLL_GRID_SCROLL_LAYOUT_ALGORITHM_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_SCROLL_GRID_SCROLL_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_info.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> gridMatrix_; - // in vertical grid, this map is like: [rowIndex: rowHeight] - std::map lineHeightMap_; -}; - -class ACE_EXPORT GridLayoutAlgorithm : public LayoutAlgorithm { - DECLARE_ACE_TYPE(GridLayoutAlgorithm, LayoutAlgorithm); +class ACE_EXPORT GridScrollLayoutAlgorithm : public LayoutAlgorithm { + DECLARE_ACE_TYPE(GridScrollLayoutAlgorithm, LayoutAlgorithm); public: - GridLayoutAlgorithm(GridLayoutInfo gridLayoutInfo, uint32_t crossCount, uint32_t mainCount) + GridScrollLayoutAlgorithm(GridLayoutInfo gridLayoutInfo, uint32_t crossCount, uint32_t mainCount) : gridLayoutInfo_(std::move(gridLayoutInfo)), crossCount_(crossCount), mainCount_(mainCount) {}; - ~GridLayoutAlgorithm() override = default; + ~GridScrollLayoutAlgorithm() override = default; void Measure(LayoutWrapper* layoutWrapper) override; void Layout(LayoutWrapper* layoutWrapper) override; @@ -93,8 +68,8 @@ private: uint32_t mainCount_ = 0; int32_t currentMainLineIndex_ = 0; // it equals to row index in vertical grid - ACE_DISALLOW_COPY_AND_MOVE(GridLayoutAlgorithm); + ACE_DISALLOW_COPY_AND_MOVE(GridScrollLayoutAlgorithm); }; -} // namespace OHOS::Ace::NG -#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_LAYOUT_ALGORITHM_H +} // namespace OHOS::Ace::NG +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_SCROLL_GRID_SCROLL_LAYOUT_ALGORITHM_H diff --git a/frameworks/core/components_ng/pattern/grid/grid_utils.cpp b/frameworks/core/components_ng/pattern/grid/grid_utils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5ebc1f6da4f5d5e43fb06b4564e7e0c1d2360c29 --- /dev/null +++ b/frameworks/core/components_ng/pattern/grid/grid_utils.cpp @@ -0,0 +1,55 @@ +/* + * 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_utils.h" + +#include +#include + +namespace OHOS::Ace::NG { +namespace { + +const char UNIT_RATIO[] = "fr"; + +} // namespace + +std::vector GridUtils::ParseArgs(const std::string& args, float size, float gap) +{ + std::vector lens; + if (args.empty()) { + return lens; + } + float frSum = 0.0f; + std::vector strs; + StringUtils::StringSplitter(args, ' ', strs); + for (const auto& str : strs) { + if (str.find(UNIT_RATIO) != std::string::npos) { + frSum += StringUtils::StringToFloat(str); + } + } + + float sizeLeft = size - (strs.size() - 1) * gap; + for (const auto& str : strs) { + float num = StringUtils::StringToFloat(str); + if (str.find(UNIT_RATIO) != std::string::npos) { + lens.push_back(NearZero(frSum) ? 0.0 : sizeLeft / frSum * num); + } else { + lens.push_back(0.0); + } + } + return lens; +} + +} // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/grid/grid_utils.h b/frameworks/core/components_ng/pattern/grid/grid_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..41aa7c45e5b65ab30037d6b8dcfa2a1898d9acf9 --- /dev/null +++ b/frameworks/core/components_ng/pattern/grid/grid_utils.h @@ -0,0 +1,35 @@ +/* + * 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_UTILS_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_UTILS_H + +#include "base/memory/referenced.h" +#include "base/utils/utils.h" +#include "core/components/common/layout/constants.h" +#include "core/components_ng/property/measure_utils.h" + +namespace OHOS::Ace::NG { + +class GridUtils { +public: + GridUtils() = delete; + ~GridUtils() = delete; + + static std::vector ParseArgs(const std::string& args, float size, float gap); +}; + +} // namespace OHOS::Ace::NG +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_UTILS_H diff --git a/frameworks/core/components_ng/pattern/grid/grid_view.cpp b/frameworks/core/components_ng/pattern/grid/grid_view.cpp index 4300c5dd8c032f0f3fd579975df39b557179d867..9e97fce9b44ee991eb0d1d00bc3d8c2b91500e6d 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_view.cpp +++ b/frameworks/core/components_ng/pattern/grid/grid_view.cpp @@ -15,8 +15,10 @@ #include "core/components_ng/pattern/grid/grid_view.h" +#include "base/utils/utils.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_event_hub.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" @@ -42,4 +44,131 @@ void GridView::SetRowsTemplate(const std::string& value) ACE_UPDATE_LAYOUT_PROPERTY(GridLayoutProperty, RowsTemplate, value); } +void GridView::SetColumnsGap(const Dimension& value) +{ + ACE_UPDATE_LAYOUT_PROPERTY(GridLayoutProperty, ColumnsGap, value); +} + +void GridView::SetRowsGap(const Dimension& value) +{ + ACE_UPDATE_LAYOUT_PROPERTY(GridLayoutProperty, RowsGap, value); +} + +void GridView::SetScrollBarMode(DisplayMode value) +{ + ACE_UPDATE_LAYOUT_PROPERTY(GridLayoutProperty, ScrollBarMode, value); +} + +void GridView::SetScrollBarColor(const Color& value) +{ + ACE_UPDATE_LAYOUT_PROPERTY(GridLayoutProperty, ScrollBarColor, value); +} + +void GridView::SetScrollBarWidth(const Dimension& value) +{ + ACE_UPDATE_LAYOUT_PROPERTY(GridLayoutProperty, ScrollBarWidth, value); +} + +void GridView::SetCachedCount(int32_t value) +{ + ACE_UPDATE_LAYOUT_PROPERTY(GridLayoutProperty, CachedCount, value); +} + +void GridView::SetEditable(bool value) +{ + ACE_UPDATE_LAYOUT_PROPERTY(GridLayoutProperty, Editable, value); +} + +void GridView::SetLayoutDirection(FlexDirection value) +{ + ACE_UPDATE_LAYOUT_PROPERTY(GridLayoutProperty, LayoutDirection, value); +} + +void GridView::SetMaxCount(int32_t value) +{ + ACE_UPDATE_LAYOUT_PROPERTY(GridLayoutProperty, MaxCount, value); +} + +void GridView::SetMinCount(int32_t value) +{ + ACE_UPDATE_LAYOUT_PROPERTY(GridLayoutProperty, MinCount, value); +} + +void GridView::SetCellLength(int32_t value) +{ + ACE_UPDATE_LAYOUT_PROPERTY(GridLayoutProperty, CellLength, value); +} + +void GridView::SetMultiSelectable(bool value) +{ + auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); + CHECK_NULL_VOID(frameNode); + auto pattern = frameNode->GetPattern(); + CHECK_NULL_VOID(pattern); + pattern->SetMultiSelectable(value); +} + +void GridView::SetSupportAnimation(bool value) +{ + auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); + CHECK_NULL_VOID(frameNode); + auto pattern = frameNode->GetPattern(); + CHECK_NULL_VOID(pattern); + pattern->SetSupportAnimation(value); +} + +void GridView::SetOnScrollToIndex(ScrollToIndexFunc&& value) +{ + auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); + CHECK_NULL_VOID(frameNode); + auto eventHub = frameNode->GetEventHub(); + CHECK_NULL_VOID(eventHub); + eventHub->SetOnScrollToIndex(std::move(value)); +} + +void GridView::SetOnItemDragStart(ItemDragStartFunc&& value) +{ + auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); + CHECK_NULL_VOID(frameNode); + auto eventHub = frameNode->GetEventHub(); + CHECK_NULL_VOID(eventHub); + eventHub->SetOnItemDragStart(std::move(value)); +} + +void GridView::SetOnItemDragEnter(ItemDragEnterFunc&& value) +{ + auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); + CHECK_NULL_VOID(frameNode); + auto eventHub = frameNode->GetEventHub(); + CHECK_NULL_VOID(eventHub); + eventHub->SetOnItemDragEnter(std::move(value)); +} + +void GridView::SetOnItemDragMove(ItemDragMoveFunc&& value) +{ + auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); + CHECK_NULL_VOID(frameNode); + auto eventHub = frameNode->GetEventHub(); + CHECK_NULL_VOID(eventHub); + eventHub->SetOnItemDragMove(std::move(value)); +} + +void GridView::SetOnItemDragLeave(ItemDragLeaveFunc&& value) +{ + auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); + CHECK_NULL_VOID(frameNode); + auto eventHub = frameNode->GetEventHub(); + CHECK_NULL_VOID(eventHub); + eventHub->SetOnItemDragLeave(std::move(value)); +} + +void GridView::SetOnItemDrop(ItemDropFunc&& value) +{ + auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); + CHECK_NULL_VOID(frameNode); + auto eventHub = frameNode->GetEventHub(); + CHECK_NULL_VOID(eventHub); + eventHub->SetOnItemDrop(std::move(value)); +} + } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/grid/grid_view.h b/frameworks/core/components_ng/pattern/grid/grid_view.h index e4d75a04cbcbb7e1b5778fa1194c192d288fabdd..efcfe05699c2bf88675af6c2fc96b3f12875389e 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_view.h +++ b/frameworks/core/components_ng/pattern/grid/grid_view.h @@ -18,8 +18,11 @@ #include +#include "base/geometry/dimension.h" #include "base/utils/macros.h" #include "core/components/common/layout/constants.h" +#include "core/components/common/properties/scroll_bar.h" +#include "core/components_ng/pattern/grid/grid_event_hub.h" namespace OHOS::Ace::NG { class ACE_EXPORT GridView { @@ -27,6 +30,25 @@ public: static void Create(); static void SetColumnsTemplate(const std::string& value); static void SetRowsTemplate(const std::string& value); + static void SetColumnsGap(const Dimension& value); + static void SetRowsGap(const Dimension& value); + static void SetScrollBarMode(DisplayMode value); + static void SetScrollBarColor(const Color& value); + static void SetScrollBarWidth(const Dimension& value); + static void SetCachedCount(int32_t value); + static void SetLayoutDirection(FlexDirection value); + static void SetMaxCount(int32_t value); + static void SetMinCount(int32_t value); + static void SetCellLength(int32_t value); + static void SetEditable(bool value); + static void SetMultiSelectable(bool value); + static void SetSupportAnimation(bool value); + static void SetOnScrollToIndex(ScrollToIndexFunc&& value); + static void SetOnItemDragStart(ItemDragStartFunc&& value); + static void SetOnItemDragEnter(ItemDragEnterFunc&& value); + static void SetOnItemDragMove(ItemDragMoveFunc&& value); + static void SetOnItemDragLeave(ItemDragLeaveFunc&& value); + static void SetOnItemDrop(ItemDropFunc&& value); }; } // namespace OHOS::Ace::NG