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 LOGD("InsertChild: position: %{public}d, index: %{public}d", pos, item->GetIndex());
80 ComponentGroup::InsertChild(position, child);
81 auto labelIter = stepperLabels_.begin();
82 std::advance(labelIter, position);
83 stepperLabels_.insert(labelIter, item->GetLabel());
84 auto textIter = labelsTextStyles_.begin();
85 std::advance(textIter, position);
86 labelsTextStyles_.insert(textIter, item->GetTextStyle());
87 }
88
AppendChild(const RefPtr<Component> & child)89 void StepperComponent::AppendChild(const RefPtr<Component>& child)
90 {
91 auto stepperItemList = CollectItems(child);
92 if (!stepperItemList.empty()) {
93 for (const auto& item : stepperItemList) {
94 item->SetIndex(GetChildren().size());
95 ComponentGroup::AppendChild(item);
96 AppendLabel(item->GetLabel());
97 AppendTextStyle(item->GetTextStyle());
98 }
99 SetUpdateType(UpdateType::REBUILD);
100 return;
101 }
102
103 auto item = StepperItemComponent::GetStepperItem(child);
104 if (!item) {
105 LOGE("AppendChild: no stepper item in child");
106 return;
107 }
108 item->SetIndex(GetChildren().size());
109 LOGD("AppendChild: index: %{public}d", item->GetIndex());
110 ComponentGroup::AppendChild(child);
111 AppendLabel(item->GetLabel());
112 AppendTextStyle(item->GetTextStyle());
113 }
114
RemoveChild(const RefPtr<Component> & child)115 void StepperComponent::RemoveChild(const RefPtr<Component>& child)
116 {
117 auto item = StepperItemComponent::GetStepperItem(child);
118 if (!item) {
119 LOGE("RemoveChild: no stepper item in child");
120 return;
121 }
122 // removing children will reset label and styles
123 stepperLabels_.clear();
124 labelsTextStyles_.clear();
125 item->SetIndex(DEFAULT_NODE_INDEX);
126 ComponentGroup::RemoveChild(child);
127 }
128
CollectItems(const RefPtr<Component> & child)129 std::list<RefPtr<StepperItemComponent>> StepperComponent::CollectItems(const RefPtr<Component>& child)
130 {
131 std::list<RefPtr<StepperItemComponent>> stepperItemList;
132 auto ifElseComponent = AceType::DynamicCast<IfElseComponent>(child);
133 if (!ifElseComponent) {
134 return stepperItemList;
135 }
136
137 auto children = ifElseComponent->GetChildren();
138 for (auto& childComponent : children) {
139 auto itemComponent = StepperItemComponent::GetStepperItem(childComponent);
140 if (itemComponent) {
141 stepperItemList.emplace_back(itemComponent);
142 }
143 }
144 return stepperItemList;
145 }
146
147 } // namespace OHOS::Ace
148