• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "frameworks/core/components_ng/pattern/stack/stack_layout_algorithm.h"
17 
18 #include "core/common/ace_application_info.h"
19 #include "core/components_ng/layout/layout_wrapper.h"
20 #include "core/components_ng/pattern/stack/stack_layout_property.h"
21 
22 namespace OHOS::Ace::NG {
23 
24 StackLayoutAlgorithm::StackLayoutAlgorithm() = default;
25 
Layout(LayoutWrapper * layoutWrapper)26 void StackLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper)
27 {
28     PerformLayout(layoutWrapper);
29     for (auto&& child : layoutWrapper->GetAllChildrenWithBuild()) {
30         child->Layout();
31     }
32 }
33 
34 // Called to perform layout render node and child.
PerformLayout(LayoutWrapper * layoutWrapper)35 void StackLayoutAlgorithm::PerformLayout(LayoutWrapper* layoutWrapper)
36 {
37     // update child position.
38     auto size = layoutWrapper->GetGeometryNode()->GetFrameSize();
39     const auto& padding = layoutWrapper->GetLayoutProperty()->CreatePaddingAndBorder();
40     auto layoutDirection = layoutWrapper->GetLayoutProperty()->GetLayoutDirection();
41     if (layoutDirection == TextDirection::AUTO) {
42         layoutDirection = AceApplicationInfo::GetInstance().IsRightToLeft() ? TextDirection::RTL : TextDirection::LTR;
43     }
44     MinusPaddingToSize(padding, size);
45     auto left = padding.left.value_or(0);
46     auto top = padding.top.value_or(0);
47     auto paddingOffset = OffsetF(left, top);
48     auto align = Alignment::CENTER;
49     auto layoutProperty = DynamicCast<StackLayoutProperty>(layoutWrapper->GetLayoutProperty());
50     CHECK_NULL_VOID(layoutProperty);
51     if (layoutProperty->GetPositionProperty()) {
52         align = layoutProperty->GetPositionProperty()->GetAlignment().value_or(Alignment::CENTER);
53     }
54     // Update child position.
55     for (const auto& child : layoutWrapper->GetAllChildrenWithBuild()) {
56         auto translate =
57             CalculateStackAlignment(size, child->GetGeometryNode()->GetMarginFrameSize(), align) + paddingOffset;
58         if (layoutDirection == TextDirection::RTL) {
59             translate.SetX(size.Width() - translate.GetX() - child->GetGeometryNode()->GetMarginFrameSize().Width());
60         }
61         child->GetGeometryNode()->SetMarginFrameOffset(translate);
62     }
63     // Update content position.
64     const auto& content = layoutWrapper->GetGeometryNode()->GetContent();
65     if (content) {
66         auto translate = CalculateStackAlignment(size, content->GetRect().GetSize(), align) + paddingOffset;
67         if (layoutDirection == TextDirection::RTL) {
68             translate.SetX(size.Width() - translate.GetX() - content->GetRect().GetSize().Width());
69         }
70         content->SetOffset(translate);
71     }
72 }
73 
CalculateStackAlignment(const NG::SizeF & parentSize,const NG::SizeF & childSize,const Alignment & alignment)74 NG::OffsetF StackLayoutAlgorithm::CalculateStackAlignment(
75     const NG::SizeF& parentSize, const NG::SizeF& childSize, const Alignment& alignment)
76 {
77     NG::OffsetF offset;
78     offset.SetX((1.0 + alignment.GetHorizontal()) * (parentSize.Width() - childSize.Width()) / 2.0);
79     offset.SetY((1.0 + alignment.GetVertical()) * (parentSize.Height() - childSize.Height()) / 2.0);
80     return offset;
81 }
82 } // namespace OHOS::Ace::NG
83