From d235acfe98dad97f8879e3ba27a84c09781f6f64 Mon Sep 17 00:00:00 2001 From: zcdqs Date: Mon, 6 Mar 2023 22:34:08 +0800 Subject: [PATCH] grid item drag animation Signed-off-by: zcdqs Change-Id: I9e7cff34b8dcde93a4c6f51c8fe3e96c68f25c8e --- .../manager/drag_drop/drag_drop_manager.cpp | 28 ++-- .../core/components_ng/pattern/BUILD.gn | 1 + .../grid/grid_accessibility_property.cpp | 5 +- .../grid/grid_accessibility_property.h | 2 +- .../pattern/grid/grid_event_hub.cpp | 96 ++++++++++++- .../pattern/grid/grid_event_hub.h | 11 +- .../pattern/grid/grid_layout_info.cpp | 126 ++++++++++++++++++ .../pattern/grid/grid_layout_info.h | 35 ++--- .../pattern/grid/grid_pattern.cpp | 80 ++++++++++- .../components_ng/pattern/grid/grid_pattern.h | 8 ++ .../grid_scroll_layout_algorithm.cpp | 10 +- .../list/list_accessibility_property.cpp | 2 +- .../list/list_accessibility_property.h | 2 +- .../property/accessibility_property.h | 2 +- .../grid/mock_grid_accessibility_property.cpp | 2 +- .../mock/pattern/grid/mock_grid_event_hub.cpp | 12 ++ .../list/mock_list_accessibility_property.cpp | 2 +- .../components_ng/test/pattern/grid/BUILD.gn | 1 + 18 files changed, 376 insertions(+), 49 deletions(-) create mode 100644 frameworks/core/components_ng/pattern/grid/grid_layout_info.cpp diff --git a/frameworks/core/components_ng/manager/drag_drop/drag_drop_manager.cpp b/frameworks/core/components_ng/manager/drag_drop/drag_drop_manager.cpp index e415b72af3e..e8dbf4e0c36 100644 --- a/frameworks/core/components_ng/manager/drag_drop/drag_drop_manager.cpp +++ b/frameworks/core/components_ng/manager/drag_drop/drag_drop_manager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -19,7 +19,6 @@ #include "base/geometry/point.h" #include "base/utils/utils.h" #include "core/components_ng/pattern/grid/grid_event_hub.h" -#include "core/components_ng/pattern/grid/grid_pattern.h" #include "core/components_ng/pattern/list/list_event_hub.h" #include "core/components_ng/pattern/root/root_pattern.h" #include "core/components_ng/pattern/text_field/text_field_pattern.h" @@ -308,10 +307,16 @@ void DragDropManager::OnItemDragMove(float globalX, float globalY, int32_t dragg itemDragInfo.SetX(pipeline->ConvertPxToVp(Dimension(globalX, DimensionUnit::PX))); itemDragInfo.SetY(pipeline->ConvertPxToVp(Dimension(globalY, DimensionUnit::PX))); + // use -1 for grid item not in eventGrid + auto getDraggedIndex = [draggedGrid = draggedGridFrameNode_, draggedIndex, dragType](RefPtr& eventGrid) { + return (dragType == DragType::GRID) ? (eventGrid == draggedGrid ? draggedIndex : -1) : draggedIndex; + }; + auto dragFrameNode = FindDragFrameNodeByPosition(globalX, globalY, dragType); if (!dragFrameNode) { if (preGridTargetFrameNode_) { - FireOnItemDragEvent(preGridTargetFrameNode_, dragType, itemDragInfo, DragEventType::LEAVE, draggedIndex); + FireOnItemDragEvent(preGridTargetFrameNode_, dragType, itemDragInfo, DragEventType::LEAVE, + getDraggedIndex(preGridTargetFrameNode_)); preGridTargetFrameNode_ = nullptr; } return; @@ -319,15 +324,17 @@ void DragDropManager::OnItemDragMove(float globalX, float globalY, int32_t dragg if (dragFrameNode == preGridTargetFrameNode_) { int32_t insertIndex = GetItemIndex(dragFrameNode, dragType, globalX, globalY); - FireOnItemDragEvent(dragFrameNode, dragType, itemDragInfo, DragEventType::MOVE, draggedIndex, insertIndex); + FireOnItemDragEvent( + dragFrameNode, dragType, itemDragInfo, DragEventType::MOVE, getDraggedIndex(dragFrameNode), insertIndex); return; } if (preGridTargetFrameNode_) { - FireOnItemDragEvent(preGridTargetFrameNode_, dragType, itemDragInfo, DragEventType::LEAVE, draggedIndex); + FireOnItemDragEvent(preGridTargetFrameNode_, dragType, itemDragInfo, DragEventType::LEAVE, + getDraggedIndex(preGridTargetFrameNode_)); } - FireOnItemDragEvent(dragFrameNode, dragType, itemDragInfo, DragEventType::ENTER, draggedIndex); + FireOnItemDragEvent(dragFrameNode, dragType, itemDragInfo, DragEventType::ENTER, getDraggedIndex(dragFrameNode)); preGridTargetFrameNode_ = dragFrameNode; } @@ -430,9 +437,14 @@ int32_t DragDropManager::GetItemIndex( if (dragType == DragType::GRID) { auto eventHub = frameNode->GetEventHub(); CHECK_NULL_RETURN(eventHub, -1); + if (frameNode != draggedGridFrameNode_) { + return eventHub->GetInsertPosition(globalX, globalY); + } auto itemFrameNode = eventHub->FindGridItemByPosition(globalX, globalY); - if (!itemFrameNode && eventHub->CheckPostionInGrid(globalX, globalY)) { - return eventHub->GetFrameNodeChildSize(); + if (!itemFrameNode) { + if (eventHub->CheckPostionInGrid(globalX, globalY)) { + return eventHub->GetFrameNodeChildSize(); + } } else { return eventHub->GetGridItemIndex(itemFrameNode); } diff --git a/frameworks/core/components_ng/pattern/BUILD.gn b/frameworks/core/components_ng/pattern/BUILD.gn index d3bcffb381b..6bb6dd0cdb3 100644 --- a/frameworks/core/components_ng/pattern/BUILD.gn +++ b/frameworks/core/components_ng/pattern/BUILD.gn @@ -95,6 +95,7 @@ build_component_ng("pattern_ng") { "grid/grid_item_model_ng.cpp", "grid/grid_item_pattern.cpp", "grid/grid_layout/grid_layout_algorithm.cpp", + "grid/grid_layout_info.cpp", "grid/grid_layout_property.cpp", "grid/grid_model_ng.cpp", "grid/grid_paint_method.cpp", diff --git a/frameworks/core/components_ng/pattern/grid/grid_accessibility_property.cpp b/frameworks/core/components_ng/pattern/grid/grid_accessibility_property.cpp index a1aa1c30cbe..d80fb4b1a8e 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_accessibility_property.cpp +++ b/frameworks/core/components_ng/pattern/grid/grid_accessibility_property.cpp @@ -59,14 +59,13 @@ int32_t GridAccessibilityProperty::GetEndIndex() const return gridLayoutInfo.endIndex_; } -size_t GridAccessibilityProperty::GetCollectionItemCounts() const +int32_t GridAccessibilityProperty::GetCollectionItemCounts() const { auto frameNode = host_.Upgrade(); CHECK_NULL_RETURN(frameNode, 0); auto gridPattern = frameNode->GetPattern(); CHECK_NULL_RETURN(gridPattern, 0); - auto gridLayoutInfo = gridPattern->GetGridLayoutInfo(); - return gridLayoutInfo.childrenCount_; + return gridPattern->GetChildrenCount(); } AceCollectionInfo GridAccessibilityProperty::GetCollectionInfo() const diff --git a/frameworks/core/components_ng/pattern/grid/grid_accessibility_property.h b/frameworks/core/components_ng/pattern/grid/grid_accessibility_property.h index 76eba341d8f..9a3776e0a70 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_accessibility_property.h +++ b/frameworks/core/components_ng/pattern/grid/grid_accessibility_property.h @@ -36,7 +36,7 @@ public: int32_t GetEndIndex() const override; - size_t GetCollectionItemCounts() const override; + int32_t GetCollectionItemCounts() const override; AceCollectionInfo GetCollectionInfo() const override; diff --git a/frameworks/core/components_ng/pattern/grid/grid_event_hub.cpp b/frameworks/core/components_ng/pattern/grid/grid_event_hub.cpp index 066ea3b2f40..1b505005b2e 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_event_hub.cpp +++ b/frameworks/core/components_ng/pattern/grid/grid_event_hub.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -15,6 +15,7 @@ #include "core/components_ng/pattern/grid/grid_event_hub.h" +#include "core/animation/spring_curve.h" #include "core/components_ng/base/frame_node.h" #include "core/components_ng/pattern/grid/grid_item_pattern.h" #include "core/components_ng/pattern/grid/grid_layout_property.h" @@ -63,17 +64,46 @@ bool GridEventHub::CheckPostionInGrid(float x, float y) { auto host = GetFrameNode(); CHECK_NULL_RETURN(host, false); - auto size = host->GetGeometryNode()->GetFrameRect(); + auto size = host->GetRenderContext()->GetPaintRectWithTransform(); + size.SetOffset(host->GetTransformRelativeOffset()); return size.IsInRegion(PointF(x, y)); } +int32_t GridEventHub::GetInsertPosition(float x, float y) +{ + if (!CheckPostionInGrid(x, y)) { + return -1; + } + + auto host = GetFrameNode(); + CHECK_NULL_RETURN(host, -1); + auto pattern = AceType::DynamicCast(host->GetPattern()); + CHECK_NULL_RETURN(pattern, -1); + auto itemFrameNode = FindGridItemByPosition(x, y); + if (itemFrameNode) { + RefPtr itemPattern = itemFrameNode->GetPattern(); + CHECK_NULL_RETURN(itemPattern, 0); + auto mainIndex = itemPattern->GetMainIndex(); + auto crossIndex = itemPattern->GetCrossIndex(); + return mainIndex * pattern->GetCrossCount() + crossIndex; + } + + // on virtual grid item dragged in this grid + if (pattern->GetGridLayoutInfo().currentRect_.IsInRegion(PointF(x, y))) { + return pattern->GetOriginalIndex(); + } + + // in grid, but not on any grid item + return pattern->GetChildrenCount(); +} + int GridEventHub::GetFrameNodeChildSize() { auto host = GetFrameNode(); CHECK_NULL_RETURN(host, 0); - auto pattern = AceType::DynamicCast(host->GetPattern()); + auto pattern = host->GetPattern(); CHECK_NULL_RETURN(pattern, 0); - return pattern->GetGridLayoutInfo().childrenCount_; + return pattern->GetChildrenCount(); } RefPtr GridEventHub::FindGridItemByPosition(float x, float y) @@ -196,6 +226,12 @@ void GridEventHub::HandleOnItemDragEnd(const GestureEvent& info) draggingItem_->GetLayoutProperty()->UpdateVisibility(VisibleType::VISIBLE); draggingItem_ = nullptr; } + + auto host = GetFrameNode(); + CHECK_NULL_VOID(host); + auto pattern = AceType::DynamicCast(host->GetPattern()); + CHECK_NULL_VOID(pattern); + pattern->ClearDragState(); } void GridEventHub::HandleOnItemDragCancel() @@ -213,6 +249,12 @@ void GridEventHub::HandleOnItemDragCancel() draggingItem_->GetLayoutProperty()->UpdateVisibility(VisibleType::VISIBLE); draggingItem_ = nullptr; } + + auto host = GetFrameNode(); + CHECK_NULL_VOID(host); + auto pattern = AceType::DynamicCast(host->GetPattern()); + CHECK_NULL_VOID(pattern); + pattern->ClearDragState(); } void GridEventHub::FireOnItemDragEnter(const ItemDragInfo& dragInfo) @@ -224,6 +266,16 @@ void GridEventHub::FireOnItemDragEnter(const ItemDragInfo& dragInfo) void GridEventHub::FireOnItemDragLeave(const ItemDragInfo& dragInfo, int32_t itemIndex) { + LOGI("itemIndex:%{public}d, %{public}p", itemIndex, this); + if (itemIndex == -1) { + auto host = GetFrameNode(); + CHECK_NULL_VOID(host); + auto pattern = AceType::DynamicCast(host->GetPattern()); + CHECK_NULL_VOID(pattern); + auto insertIndex = pattern->GetChildrenCount(); + MoveItems(itemIndex, insertIndex); + } + if (onItemDragLeave_) { onItemDragLeave_(dragInfo, itemIndex); } @@ -231,6 +283,13 @@ void GridEventHub::FireOnItemDragLeave(const ItemDragInfo& dragInfo, int32_t ite void GridEventHub::FireOnItemDrop(const ItemDragInfo& dragInfo, int32_t itemIndex, int32_t insertIndex, bool isSuccess) { + LOGI("itemIndex:%{public}d, insertIndex:%{public}d, %{public}p", itemIndex, insertIndex, this); + auto host = GetFrameNode(); + CHECK_NULL_VOID(host); + auto pattern = AceType::DynamicCast(host->GetPattern()); + CHECK_NULL_VOID(pattern); + insertIndex = (itemIndex == -1 || insertIndex == -1) ? insertIndex : pattern->GetOriginalIndex(); + pattern->ClearDragState(); if (draggingItem_) { draggingItem_->GetLayoutProperty()->UpdateVisibility(VisibleType::VISIBLE); } @@ -238,4 +297,33 @@ void GridEventHub::FireOnItemDrop(const ItemDragInfo& dragInfo, int32_t itemInde onItemDrop_(dragInfo, itemIndex, insertIndex, isSuccess); } } + +void GridEventHub::FireOnItemDragMove(const ItemDragInfo& dragInfo, int32_t itemIndex, int32_t insertIndex) const +{ + MoveItems(itemIndex, insertIndex); + + if (onItemDragMove_) { + onItemDragMove_(dragInfo, itemIndex, insertIndex); + } +} + +void GridEventHub::MoveItems(int32_t itemIndex, int32_t insertIndex) const +{ + auto host = GetFrameNode(); + CHECK_NULL_VOID(host); + auto pattern = AceType::DynamicCast(host->GetPattern()); + CHECK_NULL_VOID(pattern); + constexpr float ANIMATION_CURVE_VELOCITY = 0.0f; // The move animation spring curve velocity is 0.0 + constexpr float ANIMATION_CURVE_MASS = 1.0f; // The move animation spring curve mass is 1.0 + constexpr float ANIMATION_CURVE_STIFFNESS = 400.0f; // The move animation spring curve stiffness is 110.0 + constexpr float ANIMATION_CURVE_DAMPING = 38.0f; // The move animation spring curve damping is 17.0 + AnimationOption option; + constexpr int32_t duration = 400; + option.SetDuration(duration); + auto curve = MakeRefPtr( + ANIMATION_CURVE_VELOCITY, ANIMATION_CURVE_MASS, ANIMATION_CURVE_STIFFNESS, ANIMATION_CURVE_DAMPING); + option.SetCurve(curve); + AnimationUtils::Animate( + option, [pattern, itemIndex, insertIndex]() { pattern->MoveItems(itemIndex, insertIndex); }, 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 index ba7cc4cff2b..cb751d981ae 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_event_hub.h +++ b/frameworks/core/components_ng/pattern/grid/grid_event_hub.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -87,12 +87,7 @@ public: void FireOnItemDragEnter(const ItemDragInfo& dragInfo); - void FireOnItemDragMove(const ItemDragInfo& dragInfo, int32_t itemIndex, int32_t insertIndex) const - { - if (onItemDragMove_) { - onItemDragMove_(dragInfo, itemIndex, insertIndex); - } - } + void FireOnItemDragMove(const ItemDragInfo& dragInfo, int32_t itemIndex, int32_t insertIndex) const; void FireOnItemDragLeave(const ItemDragInfo& dragInfo, int32_t itemIndex); @@ -111,10 +106,12 @@ public: RefPtr FindGridItemByPosition(float x, float y); int32_t GetGridItemIndex(const RefPtr& frameNode); bool CheckPostionInGrid(float x, float y); + int32_t GetInsertPosition(float x, float y); int GetFrameNodeChildSize(); private: bool GetEditable() const; + void MoveItems(int32_t itemIndex, int32_t insertIndex) const; ScrollToIndexFunc onScrollToIndex_; ItemDragStartFunc onItemDragStart_; diff --git a/frameworks/core/components_ng/pattern/grid/grid_layout_info.cpp b/frameworks/core/components_ng/pattern/grid/grid_layout_info.cpp new file mode 100644 index 00000000000..f98293e291d --- /dev/null +++ b/frameworks/core/components_ng/pattern/grid/grid_layout_info.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2023 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_info.h" + +#include "base/utils/utils.h" + +namespace OHOS::Ace::NG { +int32_t GridLayoutInfo::GetItemIndexByPosition(int32_t position) +{ + auto iter = positionItemIndexMap_.find(position); + if (iter != positionItemIndexMap_.end()) { + return iter->second; + } + return position; +} + +int32_t GridLayoutInfo::GetPositionByItemIndex(int32_t itemIndex) +{ + auto position = itemIndex; + for (const auto& iter : positionItemIndexMap_) { + if (iter.second == itemIndex) { + position = iter.first; + break; + } + } + return position; +} + +int32_t GridLayoutInfo::GetOriginalIndex() const +{ + return currentMovingItemPosition_; +} + +void GridLayoutInfo::ClearDragState() +{ + positionItemIndexMap_.clear(); + currentMovingItemPosition_ = -1; +} + +void GridLayoutInfo::MoveItemsBack(int32_t from, int32_t to, int32_t itemIndex) +{ + auto lastItemIndex = itemIndex; + for (int32_t i = from; i <= to; ++i) { + int32_t mainIndex = (i - startIndex_) / crossCount_ + startMainLineIndex_; + int32_t crossIndex = (i - startIndex_) % crossCount_; + if (i == from) { + gridMatrix_[mainIndex][crossIndex] = itemIndex; + } else { + auto index = GetItemIndexByPosition(i - 1); + gridMatrix_[mainIndex][crossIndex] = index; + positionItemIndexMap_[i - 1] = lastItemIndex; + lastItemIndex = index; + } + } + positionItemIndexMap_[from] = itemIndex; + positionItemIndexMap_[to] = lastItemIndex; + currentMovingItemPosition_ = from; +} + +void GridLayoutInfo::MoveItemsForward(int32_t from, int32_t to, int32_t itemIndex) +{ + for (int32_t i = from; i <= to; ++i) { + int32_t mainIndex = (i - startIndex_) / crossCount_ + startMainLineIndex_; + int32_t crossIndex = (i - startIndex_) % crossCount_; + if (i == to) { + gridMatrix_[mainIndex][crossIndex] = itemIndex; + } else { + auto index = GetItemIndexByPosition(i + 1); + gridMatrix_[mainIndex][crossIndex] = index; + positionItemIndexMap_[i] = index; + } + } + positionItemIndexMap_[to] = itemIndex; + currentMovingItemPosition_ = to; +} + +void GridLayoutInfo::SwapItems(int32_t itemIndex, int32_t insertIndex) +{ + currentMovingItemPosition_ = currentMovingItemPosition_ == -1 ? itemIndex : currentMovingItemPosition_; + auto insertPositon = insertIndex; + // drag from another grid + if (itemIndex == -1) { + if (currentMovingItemPosition_ == -1) { + MoveItemsBack(insertPositon, childrenCount_, itemIndex); + return; + } + } else { + insertPositon = GetPositionByItemIndex(insertIndex); + } + + if (currentMovingItemPosition_ > insertPositon) { + MoveItemsBack(insertPositon, currentMovingItemPosition_, itemIndex); + return; + } + + if (insertPositon > currentMovingItemPosition_) { + MoveItemsForward(currentMovingItemPosition_, insertPositon, itemIndex); + } +} + +void GridLayoutInfo::UpdateEndLine(float mainSize, float mainGap) +{ + if (mainSize >= lastMainSize_) { + return; + } + for (auto i = startMainLineIndex_; i < endMainLineIndex_; ++i) { + mainSize -= (lineHeightMap_[i] + mainGap); + if (LessOrEqual(mainSize + mainGap, 0)) { + endMainLineIndex_ = i; + break; + } + } +} +} // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/grid/grid_layout_info.h b/frameworks/core/components_ng/pattern/grid/grid_layout_info.h index ce082d1b201..bb6a2b41f05 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_layout_info.h +++ b/frameworks/core/components_ng/pattern/grid/grid_layout_info.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -19,6 +19,7 @@ #include #include "base/geometry/axis.h" +#include "base/geometry/ng/rect_t.h" namespace OHOS::Ace::NG { @@ -46,19 +47,12 @@ struct GridLayoutInfo { startIndex_ = startLine->second.begin()->second; } - void UpdateEndLine(float mainSize, float mainGap) - { - if (mainSize >= lastMainSize_) { - return; - } - for (auto i = startMainLineIndex_; i < endMainLineIndex_; ++i) { - mainSize -= (lineHeightMap_[i] + mainGap); - if (LessOrEqual(mainSize + mainGap, 0)) { - endMainLineIndex_ = i; - break; - } - } - } + void UpdateEndLine(float mainSize, float mainGap); + + void SwapItems(int32_t itemIndex, int32_t insertIndex); + int32_t GetOriginalIndex() const; + void ClearDragState(); + float GetAverageLineHeight() { float totalHeight = 0; @@ -95,7 +89,7 @@ struct GridLayoutInfo { int32_t jumpIndex_ = -1; uint32_t crossCount_ = 0; - uint32_t childrenCount_ = 0; + int32_t childrenCount_ = 0; bool reachEnd_ = false; bool reachStart_ = false; @@ -107,6 +101,17 @@ struct GridLayoutInfo { std::map> gridMatrix_; // in vertical grid, this map is like: [rowIndex: rowHeight] std::map lineHeightMap_; + + // rect of grid item dragged in + RectF currentRect_; + +private: + int32_t GetItemIndexByPosition(int32_t position); + int32_t GetPositionByItemIndex(int32_t itemIndex); + void MoveItemsBack(int32_t from, int32_t to, int32_t itemIndex); + void MoveItemsForward(int32_t from, int32_t to, int32_t itemIndex); + int32_t currentMovingItemPosition_ = -1; + std::map positionItemIndexMap_; }; } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/grid/grid_pattern.cpp b/frameworks/core/components_ng/pattern/grid/grid_pattern.cpp index c909876bcbb..dc1160e4b44 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_pattern.cpp +++ b/frameworks/core/components_ng/pattern/grid/grid_pattern.cpp @@ -199,8 +199,9 @@ void GridPattern::ClearMultiSelect() { auto host = GetHost(); CHECK_NULL_VOID(host); - - for (const auto& item : host->GetChildren()) { + std::list> children; + host->GenerateOneDepthAllFrame(children); + for (const auto& item : children) { if (!AceType::InstanceOf(item)) { continue; } @@ -422,7 +423,7 @@ std::pair GridPattern::GetNextIndexByStep( auto curMainEnd = gridLayoutInfo_.endMainLineIndex_; auto curChildStartIndex = gridLayoutInfo_.startIndex_; auto curChildEndIndex = gridLayoutInfo_.endIndex_; - auto childrenCount = static_cast(gridLayoutInfo_.childrenCount_); + auto childrenCount = gridLayoutInfo_.childrenCount_; auto curMaxCrossCount = static_cast((gridLayoutInfo_.gridMatrix_[curMainIndex]).size()); LOGD("Current main index start-end: %{public}d-%{public}d, Current cross count: %{public}d, Current child " "index start-end: %{public}d-%{public}d, Total children count: %{public}d", @@ -723,7 +724,7 @@ void GridPattern::UpdateScrollBarOffset() float estimatedHeight = 0.f; auto averageHeight_ = heightSum / itemCount; - if (itemCount >= (info.childrenCount_ - 1)) { + if (itemCount >= static_cast(info.childrenCount_ - 1)) { estimatedHeight = heightSum - mainGap; } else { estimatedHeight = heightSum + (info.childrenCount_ - itemCount) * averageHeight_; @@ -741,4 +742,75 @@ RefPtr GridPattern::CreatePaintProperty() property->UpdateScrollBarMode(NG::DisplayMode::OFF); return property; } + +int32_t GridPattern::GetInsertPosition(float x, float y) const +{ + if (gridLayoutInfo_.currentRect_.IsInRegion(PointF(x, y))) { + return gridLayoutInfo_.GetOriginalIndex(); + } + + return -1; +} + +int32_t GridPattern::GetOriginalIndex() const +{ + return gridLayoutInfo_.GetOriginalIndex(); +} + +int32_t GridPattern::GetCrossCount() const +{ + return gridLayoutInfo_.crossCount_; +} + +int32_t GridPattern::GetChildrenCount() const +{ + return gridLayoutInfo_.childrenCount_; +} + +void GridPattern::ClearDragState() +{ + gridLayoutInfo_.ClearDragState(); +} + +void GridPattern::UpdateRectOfDraggedInItem(int32_t insertIndex) +{ + auto host = GetHost(); + CHECK_NULL_VOID(host); + std::list> children; + host->GenerateOneDepthAllFrame(children); + for (const auto& item : children) { + auto itemPattern = item->GetPattern(); + CHECK_NULL_VOID(itemPattern); + auto mainIndex = itemPattern->GetMainIndex(); + auto crossIndex = itemPattern->GetCrossIndex(); + if (mainIndex * static_cast(gridLayoutInfo_.crossCount_) + crossIndex == insertIndex) { + auto size = item->GetRenderContext()->GetPaintRectWithTransform(); + size.SetOffset(item->GetTransformRelativeOffset()); + gridLayoutInfo_.currentRect_ = size; + break; + } + } +} + +void GridPattern::MoveItems(int32_t itemIndex, int32_t insertIndex) +{ + if (insertIndex < 0 || + insertIndex >= ((itemIndex == -1) ? (gridLayoutInfo_.childrenCount_ + 1) : gridLayoutInfo_.childrenCount_)) { + return; + } + + if (itemIndex == -1) { + UpdateRectOfDraggedInItem(insertIndex); + } + + gridLayoutInfo_.SwapItems(itemIndex, insertIndex); + + auto host = GetHost(); + CHECK_NULL_VOID(host); + host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); + auto pipeline = PipelineContext::GetCurrentContext(); + if (pipeline) { + pipeline->FlushUITasks(); + } +} } // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/grid/grid_pattern.h b/frameworks/core/components_ng/pattern/grid/grid_pattern.h index 6d9b9158c8b..9548a39879c 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_pattern.h +++ b/frameworks/core/components_ng/pattern/grid/grid_pattern.h @@ -151,6 +151,14 @@ public: bool OnScrollCallback(float offset, int32_t source) override; + int32_t GetInsertPosition(float x, float y) const; + int32_t GetOriginalIndex() const; + int32_t GetCrossCount() const; + int32_t GetChildrenCount() const; + void MoveItems(int32_t itemIndex, int32_t insertIndex); + void ClearDragState(); + void UpdateRectOfDraggedInItem(int32_t insertIndex); + private: void OnAttachToFrameNode() override; void OnModifyDone() override; diff --git a/frameworks/core/components_ng/pattern/grid/grid_scroll/grid_scroll_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/grid/grid_scroll/grid_scroll_layout_algorithm.cpp index d69d545596c..768627873ea 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_scroll/grid_scroll_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/grid/grid_scroll/grid_scroll_layout_algorithm.cpp @@ -541,6 +541,7 @@ bool GridScrollLayoutAlgorithm::UseCurrentLines( { bool runOutOfRecord = false; // Measure grid items row by row + int32_t tempEndIndex = -1; while (LessNotEqual(mainLength, mainSize)) { // If [gridMatrix_] does not contain record of line [currentMainLineIndex_], do [FillNewLineBackward] auto gridMatrixIter = gridLayoutInfo_.gridMatrix_.find(++currentMainLineIndex_); @@ -555,6 +556,10 @@ bool GridScrollLayoutAlgorithm::UseCurrentLines( continue; } currentIndex = gridItemRecord.second; + if (currentIndex == -1) { + // move from another grid + continue; + } auto itemWrapper = layoutWrapper->GetOrCreateChildByIndex(currentIndex); if (!itemWrapper) { LOGE("GridItem wrapper of index %{public}u null", currentIndex); @@ -565,7 +570,8 @@ bool GridScrollLayoutAlgorithm::UseCurrentLines( auto itemSize = itemWrapper->GetGeometryNode()->GetMarginFrameSize(); 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.second; + tempEndIndex = std::max(currentIndex, tempEndIndex); + gridLayoutInfo_.endIndex_ = tempEndIndex; } if (lineHeight > 0) { // Means at least one item has been measured @@ -664,7 +670,7 @@ void GridScrollLayoutAlgorithm::SkipBackwardLines(float mainSize, LayoutWrapper* auto averageHeight = estimatedHeight / gridLayoutInfo_.childrenCount_; int32_t estimatedIndex = (gridLayoutInfo_.currentOffset_) / averageHeight; gridLayoutInfo_.startIndex_ = std::min( - gridLayoutInfo_.startIndex_ - estimatedIndex, static_cast(gridLayoutInfo_.childrenCount_)); + gridLayoutInfo_.startIndex_ - estimatedIndex, gridLayoutInfo_.childrenCount_); gridLayoutInfo_.currentOffset_ = gridLayoutInfo_.prevOffset_; LOGI("estimatedIndex:%{public}d, currentOffset_:%{public}f", gridLayoutInfo_.startIndex_, gridLayoutInfo_.currentOffset_); diff --git a/frameworks/core/components_ng/pattern/list/list_accessibility_property.cpp b/frameworks/core/components_ng/pattern/list/list_accessibility_property.cpp index 18df1fe96ae..a6496e66255 100644 --- a/frameworks/core/components_ng/pattern/list/list_accessibility_property.cpp +++ b/frameworks/core/components_ng/pattern/list/list_accessibility_property.cpp @@ -47,7 +47,7 @@ int32_t ListAccessibilityProperty::GetEndIndex() const return listPattern->GetEndIndex(); } -size_t ListAccessibilityProperty::GetCollectionItemCounts() const +int32_t ListAccessibilityProperty::GetCollectionItemCounts() const { auto frameNode = host_.Upgrade(); CHECK_NULL_RETURN(frameNode, -1); diff --git a/frameworks/core/components_ng/pattern/list/list_accessibility_property.h b/frameworks/core/components_ng/pattern/list/list_accessibility_property.h index 8e61b0b7c0e..2a8e388a897 100644 --- a/frameworks/core/components_ng/pattern/list/list_accessibility_property.h +++ b/frameworks/core/components_ng/pattern/list/list_accessibility_property.h @@ -34,7 +34,7 @@ public: int32_t GetEndIndex() const override; - size_t GetCollectionItemCounts() const override; + int32_t GetCollectionItemCounts() const override; private: ACE_DISALLOW_COPY_AND_MOVE(ListAccessibilityProperty); diff --git a/frameworks/core/components_ng/property/accessibility_property.h b/frameworks/core/components_ng/property/accessibility_property.h index 9ab2862665a..1e6cc2d364e 100644 --- a/frameworks/core/components_ng/property/accessibility_property.h +++ b/frameworks/core/components_ng/property/accessibility_property.h @@ -160,7 +160,7 @@ public: return AceTextCategory::INPUT_TYPE_DEFAULT; } - virtual size_t GetCollectionItemCounts() const + virtual int32_t GetCollectionItemCounts() const { return 0; } diff --git a/frameworks/core/components_ng/test/mock/pattern/grid/mock_grid_accessibility_property.cpp b/frameworks/core/components_ng/test/mock/pattern/grid/mock_grid_accessibility_property.cpp index 6b98d5c5195..00a6723ed8c 100644 --- a/frameworks/core/components_ng/test/mock/pattern/grid/mock_grid_accessibility_property.cpp +++ b/frameworks/core/components_ng/test/mock/pattern/grid/mock_grid_accessibility_property.cpp @@ -36,7 +36,7 @@ int32_t GridAccessibilityProperty::GetEndIndex() const return -1; } -size_t GridAccessibilityProperty::GetCollectionItemCounts() const +int32_t GridAccessibilityProperty::GetCollectionItemCounts() const { return 0; } diff --git a/frameworks/core/components_ng/test/mock/pattern/grid/mock_grid_event_hub.cpp b/frameworks/core/components_ng/test/mock/pattern/grid/mock_grid_event_hub.cpp index 2b29dbf73cb..01627645aff 100644 --- a/frameworks/core/components_ng/test/mock/pattern/grid/mock_grid_event_hub.cpp +++ b/frameworks/core/components_ng/test/mock/pattern/grid/mock_grid_event_hub.cpp @@ -56,4 +56,16 @@ void GridEventHub::FireOnItemDrop(const ItemDragInfo& dragInfo, int32_t itemInde onItemDrop_(dragInfo, itemIndex, insertIndex, isSuccess); } } + +void GridEventHub::FireOnItemDragMove(const ItemDragInfo& dragInfo, int32_t itemIndex, int32_t insertIndex) const +{ + if (onItemDragMove_) { + onItemDragMove_(dragInfo, itemIndex, insertIndex); + } +} + +int32_t GridEventHub::GetInsertPosition(float x, float y) +{ + return -1; +} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/test/mock/pattern/list/mock_list_accessibility_property.cpp b/frameworks/core/components_ng/test/mock/pattern/list/mock_list_accessibility_property.cpp index b8992aedbe9..1445b1a5434 100644 --- a/frameworks/core/components_ng/test/mock/pattern/list/mock_list_accessibility_property.cpp +++ b/frameworks/core/components_ng/test/mock/pattern/list/mock_list_accessibility_property.cpp @@ -31,7 +31,7 @@ int32_t ListAccessibilityProperty::GetEndIndex() const return -1; } -size_t ListAccessibilityProperty::GetCollectionItemCounts() const +int32_t ListAccessibilityProperty::GetCollectionItemCounts() const { return -1; } diff --git a/frameworks/core/components_ng/test/pattern/grid/BUILD.gn b/frameworks/core/components_ng/test/pattern/grid/BUILD.gn index 352132acf47..23e0245edbb 100644 --- a/frameworks/core/components_ng/test/pattern/grid/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/grid/BUILD.gn @@ -57,6 +57,7 @@ ohos_unittest("grid_pattern_test_ng") { "$ace_root/frameworks/core/components_ng/pattern/grid/grid_item_model_ng.cpp", "$ace_root/frameworks/core/components_ng/pattern/grid/grid_item_pattern.cpp", "$ace_root/frameworks/core/components_ng/pattern/grid/grid_layout/grid_layout_algorithm.cpp", + "$ace_root/frameworks/core/components_ng/pattern/grid/grid_layout_info.cpp", "$ace_root/frameworks/core/components_ng/pattern/grid/grid_layout_property.cpp", "$ace_root/frameworks/core/components_ng/pattern/grid/grid_model_ng.cpp", "$ace_root/frameworks/core/components_ng/pattern/grid/grid_paint_method.cpp", -- Gitee