1 /*
2  * Copyright (c) 2021 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/stepper/stepper_component.h"
17 
18 #include "core/components/ifelse/if_else_component.h"
19 #include "core/components/stepper/render_stepper.h"
20 #include "core/components/stepper/stepper_element.h"
21 
22 namespace OHOS::Ace {
23 namespace {
24 
25 constexpr int32_t DEFAULT_NODE_INDEX = -1;
26 
27 } // namespace
28 
StepperComponent(const std::list<RefPtr<Component>> & children)29 StepperComponent::StepperComponent(const std::list<RefPtr<Component>>& children) : ComponentGroup(children)
30 {
31     stepperController_ = AceType::MakeRefPtr<StepperController>();
32 }
33 
CreateElement()34 RefPtr<Element> StepperComponent::CreateElement()
35 {
36     return AceType::MakeRefPtr<StepperElement>();
37 }
38 
CreateRenderNode()39 RefPtr<RenderNode> StepperComponent::CreateRenderNode()
40 {
41     return RenderStepper::Create();
42 }
43 
SetStepperLabels(const std::vector<StepperLabels> & stepperLabels)44 void StepperComponent::SetStepperLabels(const std::vector<StepperLabels>& stepperLabels)
45 {
46     if (stepperLabels.empty()) {
47         LOGW("StepperLabels are empty.");
48         return;
49     }
50     stepperLabels_ = stepperLabels;
51 }
52 
GetStepperLabels() const53 const std::vector<StepperLabels>& StepperComponent::GetStepperLabels() const
54 {
55     return stepperLabels_;
56 }
57 
InsertChild(int32_t position,const RefPtr<Component> & child)58 void StepperComponent::InsertChild(int32_t position, const RefPtr<Component>& child)
59 {
60     if (position < 0) {
61         LOGE("InsertChild: the position is negative");
62         return;
63     }
64     auto item = StepperItemComponent::GetStepperItem(child);
65     if (!item) {
66         LOGE("InsertChild: no stepper item in child");
67         return;
68     }
69     auto pos = static_cast<uint32_t>(position);
70     const auto& children = GetChildren();
71     if (!child || pos > children.size()) {
72         return;
73     }
74     if (pos == children.size()) {
75         AppendChild(child);
76         return;
77     }
78     item->SetIndex(pos);
79     ComponentGroup::InsertChild(position, child);
80     auto labelIter = stepperLabels_.begin();
81     std::advance(labelIter, position);
82     stepperLabels_.insert(labelIter, item->GetLabel());
83     auto textIter = labelsTextStyles_.begin();
84     std::advance(textIter, position);
85     labelsTextStyles_.insert(textIter, item->GetTextStyle());
86 }
87 
AppendChild(const RefPtr<Component> & child)88 void StepperComponent::AppendChild(const RefPtr<Component>& child)
89 {
90     auto stepperItemList = CollectItems(child);
91     if (!stepperItemList.empty()) {
92         for (const auto& item : stepperItemList) {
93             item->SetIndex(GetChildren().size());
94             ComponentGroup::AppendChild(item);
95             AppendLabel(item->GetLabel());
96             AppendTextStyle(item->GetTextStyle());
97         }
98         SetUpdateType(UpdateType::REBUILD);
99         return;
100     }
101 
102     auto item = StepperItemComponent::GetStepperItem(child);
103     if (!item) {
104         LOGE("AppendChild: no stepper item in child");
105         return;
106     }
107     item->SetIndex(GetChildren().size());
108     ComponentGroup::AppendChild(child);
109     AppendLabel(item->GetLabel());
110     AppendTextStyle(item->GetTextStyle());
111 }
112 
RemoveChild(const RefPtr<Component> & child)113 void StepperComponent::RemoveChild(const RefPtr<Component>& child)
114 {
115     auto item = StepperItemComponent::GetStepperItem(child);
116     if (!item) {
117         LOGE("RemoveChild: no stepper item in child");
118         return;
119     }
120     // removing children will reset label and styles
121     stepperLabels_.clear();
122     labelsTextStyles_.clear();
123     item->SetIndex(DEFAULT_NODE_INDEX);
124     ComponentGroup::RemoveChild(child);
125 }
126 
CollectItems(const RefPtr<Component> & child)127 std::list<RefPtr<StepperItemComponent>> StepperComponent::CollectItems(const RefPtr<Component>& child)
128 {
129     std::list<RefPtr<StepperItemComponent>> stepperItemList;
130     auto ifElseComponent = AceType::DynamicCast<IfElseComponent>(child);
131     if (!ifElseComponent) {
132         return stepperItemList;
133     }
134 
135     auto children = ifElseComponent->GetChildren();
136     for (auto& childComponent : children) {
137         auto itemComponent = StepperItemComponent::GetStepperItem(childComponent);
138         if (itemComponent) {
139             stepperItemList.emplace_back(itemComponent);
140         }
141     }
142     return stepperItemList;
143 }
144 
145 } // namespace OHOS::Ace
146