1 /*
2  * Copyright (c) 2021-2022 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 "core/components/flex/flex_component_v2.h"
17 
18 #include "core/components/flex/flex_item_component.h"
19 #include "frameworks/core/components/ifelse/if_else_component.h"
20 
21 namespace OHOS::Ace {
22 
23 // If flexShrink is not defined, use 1.0 as default in Flex
ChangeShrinkValueInFlexComponent(const RefPtr<Component> & component)24 void FlexComponentV2::ChangeShrinkValueInFlexComponent(const RefPtr<Component>& component)
25 {
26     auto flexItem = AceType::DynamicCast<FlexItemComponent>(component);
27     if (!flexItem) {
28         return;
29     }
30     if (flexItem->GetFlexShrink() < 0) {
31         flexItem->SetFlexShrink(1.0);
32     }
33 }
34 
AddFlexItemComponent(const RefPtr<Component> & component)35 RefPtr<Component> FlexComponentV2::AddFlexItemComponent(const RefPtr<Component>& component)
36 {
37     if (AceType::InstanceOf<FlexItemComponent>(component)) {
38         ChangeShrinkValueInFlexComponent(component);
39         return component;
40     }
41     if (!component) {
42         return component;
43     }
44 
45     auto composedComponent = AceType::DynamicCast<ComposedComponent>(component);
46     if (composedComponent) {
47         auto composedChild = composedComponent->GetChild();
48         if (AceType::InstanceOf<FlexItemComponent>(composedChild)) {
49             ChangeShrinkValueInFlexComponent(composedChild);
50             return component;
51         }
52 
53         if (AceType::InstanceOf<ComposedComponent>(composedChild)) {
54             auto newComposedChild = AddFlexItemComponent(composedChild);
55             composedComponent->SetChild(newComposedChild);
56             return composedComponent;
57         }
58 
59         composedComponent->SetChild(nullptr);
60         auto newFlexItem = AceType::MakeRefPtr<FlexItemComponent>(0.0, 1.0, 0.0);
61         newFlexItem->SetChild(composedChild);
62         composedComponent->SetChild(newFlexItem);
63         if (composedChild && !composedChild->IsTailComponent()) {
64             // extend already marked component group with flex item component
65             Component::ExtendRSNode(newFlexItem, composedChild);
66         }
67         return component;
68     }
69 
70     auto multiComposedComponent = AceType::DynamicCast<MultiComposedComponent>(component);
71     if (!multiComposedComponent) {
72         auto newFlexItem = AceType::MakeRefPtr<FlexItemComponent>(0.0, 1.0, 0.0);
73         newFlexItem->SetChild(component);
74         if (component && !component->IsTailComponent()) {
75             // extend already marked component group with flex item component
76             Component::ExtendRSNode(newFlexItem, component);
77         }
78         return newFlexItem;
79     }
80 
81     auto children = multiComposedComponent->GetChildren();
82     multiComposedComponent->RemoveChildren();
83     for (const auto& childComponent : children) {
84         multiComposedComponent->AddChild(AddFlexItemComponent(childComponent));
85     }
86 
87     return component;
88 }
89 
OnChildAppended(const RefPtr<Component> & child)90 void FlexComponentV2::OnChildAppended(const RefPtr<Component>& child)
91 {
92     RefPtr<Component> newChild = AddFlexItemComponent(child);
93     if (newChild != child) {
94         RemoveChildDirectly(child);
95         AppendChildDirectly(newChild);
96     }
97 }
98 
99 } // namespace OHOS::Ace
100