From 0b0fbf92a4055db9fbb278a9807cb617a3a32f4f Mon Sep 17 00:00:00 2001 From: caocan Date: Sun, 28 Aug 2022 15:13:36 +0800 Subject: [PATCH 1/3] =?UTF-8?q?[UI=E7=BB=84=E4=BB=B6=E9=87=8D=E6=9E=84]?= =?UTF-8?q?=E6=96=B0=E6=A1=86=E6=9E=B6=E6=94=AF=E6=8C=81Scroll=E7=BB=84?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: caocan Change-Id: I1d4aa3a70ddb43f2b1220f6f7b2ae3d6d9d9c464 --- .../declarative_frontend/jsview/js_scroll.cpp | 29 +++-- .../core/components_ng/pattern/BUILD.gn | 3 + .../scroll/scroll_layout_algorithm.cpp | 116 ++++++++++++++++++ .../pattern/scroll/scroll_layout_algorithm.h | 59 +++++++++ .../pattern/scroll/scroll_layout_property.h | 52 ++++++++ .../pattern/scroll/scroll_pattern.cpp | 84 +++++++++++++ .../pattern/scroll/scroll_pattern.h | 62 ++++++++++ .../pattern/scroll/scroll_view.cpp | 40 ++++++ .../pattern/scroll/scroll_view.h | 33 +++++ 9 files changed, 470 insertions(+), 8 deletions(-) create mode 100644 frameworks/core/components_ng/pattern/scroll/scroll_layout_algorithm.cpp create mode 100644 frameworks/core/components_ng/pattern/scroll/scroll_layout_algorithm.h create mode 100644 frameworks/core/components_ng/pattern/scroll/scroll_layout_property.h create mode 100644 frameworks/core/components_ng/pattern/scroll/scroll_pattern.cpp create mode 100644 frameworks/core/components_ng/pattern/scroll/scroll_pattern.h create mode 100644 frameworks/core/components_ng/pattern/scroll/scroll_view.cpp create mode 100644 frameworks/core/components_ng/pattern/scroll/scroll_view.h diff --git a/frameworks/bridge/declarative_frontend/jsview/js_scroll.cpp b/frameworks/bridge/declarative_frontend/jsview/js_scroll.cpp index 47beddaf868..0abdc8711c1 100644 --- a/frameworks/bridge/declarative_frontend/jsview/js_scroll.cpp +++ b/frameworks/bridge/declarative_frontend/jsview/js_scroll.cpp @@ -19,13 +19,20 @@ #include "bridge/declarative_frontend/jsview/js_view_common_def.h" #include "bridge/declarative_frontend/view_stack_processor.h" #include "core/components/scroll/scroll_component.h" +#include "core/components_ng/pattern/scroll/scroll_view.h" namespace OHOS::Ace::Framework { namespace { const std::vector DISPLAY_MODE = {DisplayMode::OFF, DisplayMode::AUTO, DisplayMode::ON}; + const std::vector AXIS = { Axis::VERTICAL, Axis::HORIZONTAL, Axis::FREE, Axis::NONE }; } void JSScroll::Create(const JSCallbackInfo& info) { + if (Container::IsCurrentUseNewPipeline()) { + NG::ScrollView::Create(); + return; + } + RefPtr child; auto scrollComponent = AceType::MakeRefPtr(child); ViewStackProcessor::GetInstance()->ClaimElementId(scrollComponent); @@ -59,14 +66,20 @@ void JSScroll::Create(const JSCallbackInfo& info) void JSScroll::SetScrollable(int32_t value) { - if (value >= 0 && value < 4) { // Number of scrolling methods - auto component = ViewStackProcessor::GetInstance()->GetMainComponent(); - auto scrollComponent = AceType::DynamicCast(component); - if (scrollComponent) { - scrollComponent->SetAxisDirection((Axis)value); - } - } else { - LOGE("invalid value for SetScrollable"); + if (value < 0 || value >= static_cast(AXIS.size())) { + LOGE("value is not valid: %{public}d", value); + return; + } + + if (Container::IsCurrentUseNewPipeline()) { + NG::ScrollView::SetAxis(AXIS[value]); + return; + } + + auto component = ViewStackProcessor::GetInstance()->GetMainComponent(); + auto scrollComponent = AceType::DynamicCast(component); + if (scrollComponent) { + scrollComponent->SetAxisDirection(AXIS[value]); } } diff --git a/frameworks/core/components_ng/pattern/BUILD.gn b/frameworks/core/components_ng/pattern/BUILD.gn index 5229c07eba2..3d029374045 100644 --- a/frameworks/core/components_ng/pattern/BUILD.gn +++ b/frameworks/core/components_ng/pattern/BUILD.gn @@ -37,6 +37,9 @@ build_component_ng("pattern_ng") { "list/list_pattern.cpp", "list/list_view.cpp", "page/page_pattern.cpp", + "scroll/scroll_layout_algorithm.cpp", + "scroll/scroll_pattern.cpp", + "scroll/scroll_view.cpp", "stack/stack_view.cpp", "stage/stage_manager.cpp", "swiper/swiper_layout_algorithm.cpp", diff --git a/frameworks/core/components_ng/pattern/scroll/scroll_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/scroll/scroll_layout_algorithm.cpp new file mode 100644 index 00000000000..42de44838d9 --- /dev/null +++ b/frameworks/core/components_ng/pattern/scroll/scroll_layout_algorithm.cpp @@ -0,0 +1,116 @@ +/* + * 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/scroll/scroll_layout_algorithm.h" +#include + +#include "base/geometry/axis.h" +#include "base/geometry/ng/offset_t.h" +#include "base/geometry/ng/size_t.h" +#include "base/log/ace_trace.h" +#include "base/utils/utils.h" +#include "core/components_ng/pattern/scroll/scroll_layout_property.h" +#include "core/components_ng/property/layout_constraint.h" +#include "core/components_ng/property/measure_property.h" +#include "core/components_ng/property/measure_utils.h" + +namespace OHOS::Ace::NG { +namespace { + +void UpdateChildConstraint(Axis axis, const SizeF& selfIdealSize, LayoutConstraintF& contentConstraint) +{ + contentConstraint.parentIdealSize = OptionalSizeF(selfIdealSize); + if (axis == Axis::VERTICAL) { + contentConstraint.maxSize.SetHeight(Infinity()); + } else { + contentConstraint.maxSize.SetWidth(Infinity()); + } +} + +} // namespace + +void ScrollLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper) +{ + auto layoutProperty = AceType::DynamicCast(layoutWrapper->GetLayoutProperty()); + CHECK_NULL_VOID(layoutProperty); + + auto axis = layoutProperty->GetAxis().value_or(Axis::VERTICAL); + auto constraint = layoutProperty->GetLayoutConstraint(); + auto idealSize = CreateIdealSize(constraint.value(), axis, layoutProperty->GetMeasureType(), true); + if (GetMainAxisSize(idealSize, axis) == Infinity()) { + LOGE("the scroll is infinity, error"); + return; + } + + // calculate child layout constraint. + auto childLayoutConstraint = layoutProperty->CreateChildConstraint(); + UpdateChildConstraint(axis, idealSize, childLayoutConstraint); + + auto childWrapper = layoutWrapper->GetOrCreateChildByIndex(0); + if (!childWrapper) { + return; + } + { + ACE_SCOPED_TRACE("ScrollLayoutAlgorithm::Measure child"); + childWrapper->Measure(childLayoutConstraint); + } + + auto childSize = childWrapper->GetGeometryNode()->GetFrameSize(); + if (!constraint->selfIdealSize.Width().has_value()) { + idealSize.SetWidth(childSize.Width()); + } + if (!constraint->selfIdealSize.Height().has_value()) { + idealSize.SetHeight(childSize.Height()); + } + + auto geometryNode = layoutWrapper->GetGeometryNode(); + CHECK_NULL_VOID(geometryNode); + geometryNode->SetFrameSize(idealSize); +} + +void ScrollLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper) +{ + CHECK_NULL_VOID(layoutWrapper); + auto layoutProperty = AceType::DynamicCast(layoutWrapper->GetLayoutProperty()); + CHECK_NULL_VOID(layoutProperty); + auto axis = layoutProperty->GetAxis().value_or(Axis::VERTICAL); + auto geometryNode = layoutWrapper->GetGeometryNode(); + CHECK_NULL_VOID(geometryNode); + auto size = geometryNode->GetFrameSize(); + auto padding = layoutProperty->CreatePaddingPropertyF(); + MinusPaddingToSize(padding, size); + auto left = padding.left.value_or(0.0f); + auto top = padding.top.value_or(0.0f); + auto paddingOffset = OffsetF(left, top); + + auto parentOffset = + layoutWrapper->GetGeometryNode()->GetParentGlobalOffset() + layoutWrapper->GetGeometryNode()->GetFrameOffset(); + + // layout child. + auto childWrapper = layoutWrapper->GetOrCreateChildByIndex(0); + CHECK_NULL_VOID(childWrapper); + auto childGeometryNode = childWrapper->GetGeometryNode(); + CHECK_NULL_VOID(childGeometryNode); + auto childSize = childGeometryNode->GetFrameSize(); + + auto scrollableDistance = GetMainAxisSize(childSize, axis) - GetMainAxisSize(size, axis); + currentOffset_ = std::clamp(currentOffset_, -scrollableDistance, 0.0f); + auto currentOffset = axis == Axis::VERTICAL ? OffsetF(0.0f, currentOffset_) : OffsetF(currentOffset_, 0.0f); + auto offset = paddingOffset + currentOffset; + childGeometryNode->SetFrameOffset(offset); + childWrapper->Layout(parentOffset); +} + +} // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/scroll/scroll_layout_algorithm.h b/frameworks/core/components_ng/pattern/scroll/scroll_layout_algorithm.h new file mode 100644 index 00000000000..e464aea1b66 --- /dev/null +++ b/frameworks/core/components_ng/pattern/scroll/scroll_layout_algorithm.h @@ -0,0 +1,59 @@ +/* + * 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_LIST_LIST_LAYOUT_ALGORITHM_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_LIST_LIST_LAYOUT_ALGORITHM_H + +#include + +#include "base/geometry/axis.h" +#include "base/memory/referenced.h" +#include "core/components_ng/layout/layout_algorithm.h" +#include "core/components_ng/layout/layout_wrapper.h" +#include "core/components/scroll/scroll_component.h" + +namespace OHOS::Ace::NG { + +// TextLayoutAlgorithm acts as the underlying text layout. +class ACE_EXPORT ScrollLayoutAlgorithm : public LayoutAlgorithm { + DECLARE_ACE_TYPE(ScrollLayoutAlgorithm, LayoutAlgorithm); + +public: + explicit ScrollLayoutAlgorithm(float currentOffset) : currentOffset_(currentOffset) {} + ~ScrollLayoutAlgorithm() override = default; + + void OnReset() override {} + + void SetCurrentOffset(float offset) + { + currentOffset_ = offset; + } + + float GetCurrentOffset() const + { + return currentOffset_; + } + + void Measure(LayoutWrapper* layoutWrapper) override; + + void Layout(LayoutWrapper* layoutWrapper) override; + +private: + float currentOffset_ = 0.0f; +}; + +} // namespace OHOS::Ace::NG + +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_LIST_LIST_LAYOUT_ALGORITHM_H diff --git a/frameworks/core/components_ng/pattern/scroll/scroll_layout_property.h b/frameworks/core/components_ng/pattern/scroll/scroll_layout_property.h new file mode 100644 index 00000000000..fbff0fa0227 --- /dev/null +++ b/frameworks/core/components_ng/pattern/scroll/scroll_layout_property.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_LIST_LIST_LAYOUT_PROPERTY_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_LIST_LIST_LAYOUT_PROPERTY_H + +#include "base/geometry/axis.h" +#include "base/utils/macros.h" +#include "core/components/common/layout/constants.h" +#include "core/components_ng/layout/layout_property.h" +#include "core/components_ng/property/property.h" + +namespace OHOS::Ace::NG { +class ACE_EXPORT ScrollLayoutProperty : public LayoutProperty { + DECLARE_ACE_TYPE(ScrollLayoutProperty, LayoutProperty); + +public: + ScrollLayoutProperty() = default; + ~ScrollLayoutProperty() override = default; + + RefPtr Clone() const override + { + auto value = MakeRefPtr(); + value->LayoutProperty::UpdateLayoutProperty(DynamicCast(this)); + value->propAxis_ = CloneAxis(); + return value; + } + + void Reset() override + { + LayoutProperty::Reset(); + ResetAxis(); + } + + ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Axis, Axis, PROPERTY_UPDATE_MEASURE); +}; + +} // namespace OHOS::Ace::NG + +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_LIST_LIST_LAYOUT_PROPERTY_H diff --git a/frameworks/core/components_ng/pattern/scroll/scroll_pattern.cpp b/frameworks/core/components_ng/pattern/scroll/scroll_pattern.cpp new file mode 100644 index 00000000000..ca3c296bc1c --- /dev/null +++ b/frameworks/core/components_ng/pattern/scroll/scroll_pattern.cpp @@ -0,0 +1,84 @@ +/* + * 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/scroll/scroll_pattern.h" + +#include "base/geometry/axis.h" +#include "base/utils/utils.h" +#include "core/components/scroll/scrollable.h" +#include "core/components_ng/property/measure_utils.h" +#include "core/components_ng/property/property.h" +#include "core/components_ng/pattern/scroll/scroll_layout_algorithm.h" +#include "core/components_ng/pattern/scroll/scroll_layout_property.h" + +namespace OHOS::Ace::NG { + +void ScrollPattern::OnAttachToFrameNode() +{ + auto host = GetHost(); + CHECK_NULL_VOID(host); + host->GetRenderContext()->SetClipToFrame(true); +} + +void ScrollPattern::OnModifyDone() +{ + auto host = GetHost(); + CHECK_NULL_VOID(host); + auto layoutProperty = host->GetLayoutProperty(); + CHECK_NULL_VOID(layoutProperty); + auto task = [weak = WeakClaim(this)](double offset, int32_t source) { + if (source != SCROLL_FROM_START) { + auto pattern = weak.Upgrade(); + if (pattern) { + pattern->UpdateCurrentOffset(static_cast(offset)); + } + } + return true; + }; + + auto hub = host->GetEventHub(); + CHECK_NULL_VOID(hub); + auto gestureHub = hub->GetOrCreateGestureEventHub(); + CHECK_NULL_VOID(gestureHub); + if (scrollableEvent_) { + gestureHub->RemoveScrollableEvent(scrollableEvent_); + } + scrollableEvent_ = MakeRefPtr(layoutProperty->GetAxis().value_or(Axis::VERTICAL)); + scrollableEvent_->SetScrollPositionCallback(std::move(task)); + gestureHub->AddScrollableEvent(scrollableEvent_); +} + +bool ScrollPattern::OnDirtyLayoutWrapperSwap(const RefPtr& dirty, bool skipMeasure, bool skipLayout) +{ + if (skipMeasure && skipLayout) { + return false; + } + auto layoutAlgorithmWrapper = DynamicCast(dirty->GetLayoutAlgorithm()); + CHECK_NULL_RETURN(layoutAlgorithmWrapper, false); + auto layoutAlgorithm = DynamicCast(layoutAlgorithmWrapper->GetLayoutAlgorithm()); + CHECK_NULL_RETURN(layoutAlgorithm, false); + currentOffset_ = layoutAlgorithm->GetCurrentOffset(); + return false; +} + +void ScrollPattern::UpdateCurrentOffset(float offset) +{ + auto host = GetHost(); + CHECK_NULL_VOID(host); + currentOffset_ = currentOffset_ + offset; + host->MarkDirtyNode(PROPERTY_REQUEST_NEW_CHILD_NODE); +} + +} // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/scroll/scroll_pattern.h b/frameworks/core/components_ng/pattern/scroll/scroll_pattern.h new file mode 100644 index 00000000000..0a251d48edf --- /dev/null +++ b/frameworks/core/components_ng/pattern/scroll/scroll_pattern.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLL_SCROLL_PATTERN_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLL_SCROLL_PATTERN_H + +#include "core/components_ng/event/event_hub.h" +#include "core/components_ng/pattern/pattern.h" +#include "core/components_ng/pattern/scroll/scroll_layout_algorithm.h" +#include "core/components_ng/pattern/scroll/scroll_layout_property.h" + +namespace OHOS::Ace::NG { + +class ScrollPattern : public Pattern { + DECLARE_ACE_TYPE(ScrollPattern, Pattern); + +public: + ScrollPattern() = default; + ~ScrollPattern() override = default; + + bool IsAtomicNode() const override + { + return false; + } + + RefPtr CreateLayoutProperty() override + { + return MakeRefPtr(); + } + + RefPtr CreateLayoutAlgorithm() override + { + auto layoutAlgorithm = MakeRefPtr(currentOffset_); + return layoutAlgorithm; + } + + void UpdateCurrentOffset(float offset); + +private: + void OnModifyDone() override; + void OnAttachToFrameNode() override; + bool OnDirtyLayoutWrapperSwap(const RefPtr& dirty, bool skipMeasure, bool skipLayout) override; + + RefPtr scrollableEvent_; + float currentOffset_ = 0.0; +}; + +} // namespace OHOS::Ace::NG + +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLL_SCROLL_PATTERN_H diff --git a/frameworks/core/components_ng/pattern/scroll/scroll_view.cpp b/frameworks/core/components_ng/pattern/scroll/scroll_view.cpp new file mode 100644 index 00000000000..3c7d99c13e8 --- /dev/null +++ b/frameworks/core/components_ng/pattern/scroll/scroll_view.cpp @@ -0,0 +1,40 @@ +/* + * 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/scroll/scroll_view.h" + +#include "core/components_ng/base/frame_node.h" +#include "core/components_ng/base/view_stack_processor.h" +#include "core/components_ng/pattern/scroll/scroll_pattern.h" +#include "core/components_v2/inspector/inspector_constants.h" + +namespace OHOS::Ace::NG { + +void ScrollView::Create() +{ + auto* stack = ViewStackProcessor::GetInstance(); + auto nodeId = stack->ClaimNodeId(); + auto frameNode = FrameNode::GetOrCreateFrameNode(V2::SCROLL_ETS_TAG, nodeId, + []() { return AceType::MakeRefPtr(); }); + stack->Push(frameNode); +} + +void ScrollView::SetAxis(Axis axis) +{ + ACE_UPDATE_LAYOUT_PROPERTY(ScrollLayoutProperty, Axis, axis); +} + + +} // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/scroll/scroll_view.h b/frameworks/core/components_ng/pattern/scroll/scroll_view.h new file mode 100644 index 00000000000..8e6fda67691 --- /dev/null +++ b/frameworks/core/components_ng/pattern/scroll/scroll_view.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLL_SCROLL_VIEW_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLL_SCROLL_VIEW_H + +#include "base/geometry/axis.h" +#include "base/utils/macros.h" +#include "core/components/common/layout/constants.h" + +namespace OHOS::Ace::NG { + +class ACE_EXPORT ScrollView { +public: + static void Create(); + static void SetAxis(Axis axis); +}; + +} // namespace OHOS::Ace::NG + +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLL_SCROLL_VIEW_H -- Gitee From 118f0e60ce52143c7dce5e0d9bdcee94f5bce5a1 Mon Sep 17 00:00:00 2001 From: caocan Date: Mon, 29 Aug 2022 11:24:32 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A3=80=E8=A7=86?= =?UTF-8?q?=E6=84=8F=E8=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: caocan Change-Id: I51114c49694372126b6e7971f45460a6315a1484 --- .../scroll/scroll_layout_algorithm.cpp | 37 ++++++++----------- .../pattern/scroll/scroll_layout_algorithm.h | 6 +-- .../pattern/scroll/scroll_layout_property.h | 6 +-- .../pattern/scroll/scroll_pattern.cpp | 10 ++++- .../pattern/scroll/scroll_pattern.h | 3 +- .../pattern/scroll/scroll_view.cpp | 1 - .../components_ng/property/measure_property.h | 21 +++++++++++ 7 files changed, 54 insertions(+), 30 deletions(-) diff --git a/frameworks/core/components_ng/pattern/scroll/scroll_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/scroll/scroll_layout_algorithm.cpp index 42de44838d9..84c0809a4e5 100644 --- a/frameworks/core/components_ng/pattern/scroll/scroll_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/scroll/scroll_layout_algorithm.cpp @@ -14,6 +14,7 @@ */ #include "core/components_ng/pattern/scroll/scroll_layout_algorithm.h" + #include #include "base/geometry/axis.h" @@ -49,24 +50,25 @@ void ScrollLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper) auto axis = layoutProperty->GetAxis().value_or(Axis::VERTICAL); auto constraint = layoutProperty->GetLayoutConstraint(); auto idealSize = CreateIdealSize(constraint.value(), axis, layoutProperty->GetMeasureType(), true); - if (GetMainAxisSize(idealSize, axis) == Infinity()) { + if (GreatOrEqual(GetMainAxisSize(idealSize, axis), Infinity())) { LOGE("the scroll is infinity, error"); return; } - // calculate child layout constraint. + // Calculate child layout constraint. + auto padding = layoutProperty->CreatePaddingPropertyF(); auto childLayoutConstraint = layoutProperty->CreateChildConstraint(); - UpdateChildConstraint(axis, idealSize, childLayoutConstraint); + UpdateChildConstraint(axis, idealSize - padding.Size(), childLayoutConstraint); + // Measure child. auto childWrapper = layoutWrapper->GetOrCreateChildByIndex(0); if (!childWrapper) { + LOGI("There is no child."); return; } - { - ACE_SCOPED_TRACE("ScrollLayoutAlgorithm::Measure child"); - childWrapper->Measure(childLayoutConstraint); - } + childWrapper->Measure(childLayoutConstraint); + // Use child size when self idea size of scroll is not setted. auto childSize = childWrapper->GetGeometryNode()->GetFrameSize(); if (!constraint->selfIdealSize.Width().has_value()) { idealSize.SetWidth(childSize.Width()); @@ -88,28 +90,21 @@ void ScrollLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper) auto axis = layoutProperty->GetAxis().value_or(Axis::VERTICAL); auto geometryNode = layoutWrapper->GetGeometryNode(); CHECK_NULL_VOID(geometryNode); - auto size = geometryNode->GetFrameSize(); - auto padding = layoutProperty->CreatePaddingPropertyF(); - MinusPaddingToSize(padding, size); - auto left = padding.left.value_or(0.0f); - auto top = padding.top.value_or(0.0f); - auto paddingOffset = OffsetF(left, top); - - auto parentOffset = - layoutWrapper->GetGeometryNode()->GetParentGlobalOffset() + layoutWrapper->GetGeometryNode()->GetFrameOffset(); - - // layout child. auto childWrapper = layoutWrapper->GetOrCreateChildByIndex(0); CHECK_NULL_VOID(childWrapper); auto childGeometryNode = childWrapper->GetGeometryNode(); CHECK_NULL_VOID(childGeometryNode); - auto childSize = childGeometryNode->GetFrameSize(); + auto parentOffset = + layoutWrapper->GetGeometryNode()->GetParentGlobalOffset() + layoutWrapper->GetGeometryNode()->GetFrameOffset(); + auto size = geometryNode->GetFrameSize(); + auto padding = layoutProperty->CreatePaddingPropertyF(); + MinusPaddingToSize(padding, size); + auto childSize = childGeometryNode->GetFrameSize(); auto scrollableDistance = GetMainAxisSize(childSize, axis) - GetMainAxisSize(size, axis); currentOffset_ = std::clamp(currentOffset_, -scrollableDistance, 0.0f); auto currentOffset = axis == Axis::VERTICAL ? OffsetF(0.0f, currentOffset_) : OffsetF(currentOffset_, 0.0f); - auto offset = paddingOffset + currentOffset; - childGeometryNode->SetFrameOffset(offset); + childGeometryNode->SetFrameOffset(padding.Offset() + currentOffset); childWrapper->Layout(parentOffset); } diff --git a/frameworks/core/components_ng/pattern/scroll/scroll_layout_algorithm.h b/frameworks/core/components_ng/pattern/scroll/scroll_layout_algorithm.h index e464aea1b66..7f2932c81db 100644 --- a/frameworks/core/components_ng/pattern/scroll/scroll_layout_algorithm.h +++ b/frameworks/core/components_ng/pattern/scroll/scroll_layout_algorithm.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_LIST_LIST_LAYOUT_ALGORITHM_H -#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_LIST_LIST_LAYOUT_ALGORITHM_H +#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_SCROLL_SCROLL_LAYOUT_ALGORITHM_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_SCROLL_SCROLL_LAYOUT_ALGORITHM_H #include @@ -56,4 +56,4 @@ private: } // namespace OHOS::Ace::NG -#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_LIST_LIST_LAYOUT_ALGORITHM_H +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_SCROLL_SCROLL_LAYOUT_ALGORITHM_H diff --git a/frameworks/core/components_ng/pattern/scroll/scroll_layout_property.h b/frameworks/core/components_ng/pattern/scroll/scroll_layout_property.h index fbff0fa0227..7e96fece4a8 100644 --- a/frameworks/core/components_ng/pattern/scroll/scroll_layout_property.h +++ b/frameworks/core/components_ng/pattern/scroll/scroll_layout_property.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_LIST_LIST_LAYOUT_PROPERTY_H -#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_LIST_LIST_LAYOUT_PROPERTY_H +#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_SCROLL_SCROLL_LAYOUT_PROPERTY_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_SCROLL_SCROLL_LAYOUT_PROPERTY_H #include "base/geometry/axis.h" #include "base/utils/macros.h" @@ -49,4 +49,4 @@ public: } // namespace OHOS::Ace::NG -#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_LIST_LIST_LAYOUT_PROPERTY_H +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_SCROLL_SCROLL_LAYOUT_PROPERTY_H diff --git a/frameworks/core/components_ng/pattern/scroll/scroll_pattern.cpp b/frameworks/core/components_ng/pattern/scroll/scroll_pattern.cpp index ca3c296bc1c..144f21b5c5e 100644 --- a/frameworks/core/components_ng/pattern/scroll/scroll_pattern.cpp +++ b/frameworks/core/components_ng/pattern/scroll/scroll_pattern.cpp @@ -38,6 +38,14 @@ void ScrollPattern::OnModifyDone() CHECK_NULL_VOID(host); auto layoutProperty = host->GetLayoutProperty(); CHECK_NULL_VOID(layoutProperty); + + auto axis = layoutProperty->GetAxis().value_or(Axis::VERTICAL); + if (axis_ == axis && scrollableEvent_) { + LOGE("Direction not changed, need't resister scroll event again."); + return; + } + + axis_ = axis; auto task = [weak = WeakClaim(this)](double offset, int32_t source) { if (source != SCROLL_FROM_START) { auto pattern = weak.Upgrade(); @@ -55,7 +63,7 @@ void ScrollPattern::OnModifyDone() if (scrollableEvent_) { gestureHub->RemoveScrollableEvent(scrollableEvent_); } - scrollableEvent_ = MakeRefPtr(layoutProperty->GetAxis().value_or(Axis::VERTICAL)); + scrollableEvent_ = MakeRefPtr(axis); scrollableEvent_->SetScrollPositionCallback(std::move(task)); gestureHub->AddScrollableEvent(scrollableEvent_); } diff --git a/frameworks/core/components_ng/pattern/scroll/scroll_pattern.h b/frameworks/core/components_ng/pattern/scroll/scroll_pattern.h index 0a251d48edf..c985e6c5f85 100644 --- a/frameworks/core/components_ng/pattern/scroll/scroll_pattern.h +++ b/frameworks/core/components_ng/pattern/scroll/scroll_pattern.h @@ -54,7 +54,8 @@ private: bool OnDirtyLayoutWrapperSwap(const RefPtr& dirty, bool skipMeasure, bool skipLayout) override; RefPtr scrollableEvent_; - float currentOffset_ = 0.0; + Axis axis_ = Axis::VERTICAL; + float currentOffset_ = 0.0f; }; } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/scroll/scroll_view.cpp b/frameworks/core/components_ng/pattern/scroll/scroll_view.cpp index 3c7d99c13e8..996b8a7c835 100644 --- a/frameworks/core/components_ng/pattern/scroll/scroll_view.cpp +++ b/frameworks/core/components_ng/pattern/scroll/scroll_view.cpp @@ -36,5 +36,4 @@ void ScrollView::SetAxis(Axis axis) ACE_UPDATE_LAYOUT_PROPERTY(ScrollLayoutProperty, Axis, axis); } - } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/property/measure_property.h b/frameworks/core/components_ng/property/measure_property.h index b7a6398fd80..43204825dfd 100644 --- a/frameworks/core/components_ng/property/measure_property.h +++ b/frameworks/core/components_ng/property/measure_property.h @@ -24,6 +24,7 @@ #include #include +#include "base/geometry/ng/offset_t.h" #include "base/utils/utils.h" #include "core/components_ng/property/calc_length.h" @@ -276,6 +277,26 @@ struct PaddingPropertyT { str.append("bottom: [").append(bottom.has_value() ? std::to_string(bottom.value()) : "NA").append("]"); return str; } + + float Width() const + { + return left.value_or(0.0f) + right.value_or(0.0f); + } + + float Height() const + { + return top.value_or(0.0f) + bottom.value_or(0.0f); + } + + SizeF Size() const + { + return SizeF(Width(), Height()); + } + + OffsetF Offset() const + { + return OffsetF(left.value_or(0.0f), top.value_or(0.0f)); + } }; using PaddingProperty = PaddingPropertyT; -- Gitee From 2aeb547507cc68de5e90f8cf03dc379e715c0e17 Mon Sep 17 00:00:00 2001 From: caocan Date: Mon, 29 Aug 2022 11:47:32 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A3=80=E8=A7=86?= =?UTF-8?q?=E6=84=8F=E8=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: caocan Change-Id: Ib4f7c8265ce6da216132ce4724c6ae6d21025abf --- .../components_ng/pattern/scroll/scroll_layout_algorithm.h | 1 - .../core/components_ng/pattern/scroll/scroll_pattern.cpp | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/frameworks/core/components_ng/pattern/scroll/scroll_layout_algorithm.h b/frameworks/core/components_ng/pattern/scroll/scroll_layout_algorithm.h index 7f2932c81db..ad9f7340369 100644 --- a/frameworks/core/components_ng/pattern/scroll/scroll_layout_algorithm.h +++ b/frameworks/core/components_ng/pattern/scroll/scroll_layout_algorithm.h @@ -26,7 +26,6 @@ namespace OHOS::Ace::NG { -// TextLayoutAlgorithm acts as the underlying text layout. class ACE_EXPORT ScrollLayoutAlgorithm : public LayoutAlgorithm { DECLARE_ACE_TYPE(ScrollLayoutAlgorithm, LayoutAlgorithm); diff --git a/frameworks/core/components_ng/pattern/scroll/scroll_pattern.cpp b/frameworks/core/components_ng/pattern/scroll/scroll_pattern.cpp index 144f21b5c5e..ca3db03c379 100644 --- a/frameworks/core/components_ng/pattern/scroll/scroll_pattern.cpp +++ b/frameworks/core/components_ng/pattern/scroll/scroll_pattern.cpp @@ -41,7 +41,7 @@ void ScrollPattern::OnModifyDone() auto axis = layoutProperty->GetAxis().value_or(Axis::VERTICAL); if (axis_ == axis && scrollableEvent_) { - LOGE("Direction not changed, need't resister scroll event again."); + LOGD("Direction not changed, need't resister scroll event again."); return; } @@ -86,7 +86,7 @@ void ScrollPattern::UpdateCurrentOffset(float offset) auto host = GetHost(); CHECK_NULL_VOID(host); currentOffset_ = currentOffset_ + offset; - host->MarkDirtyNode(PROPERTY_REQUEST_NEW_CHILD_NODE); + host->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT); } } // namespace OHOS::Ace::NG -- Gitee