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/indexer/indexer_item_component.h"
17
18 #include "core/components/indexer/indexer_component.h"
19 #include "core/components/indexer/render_indexer_item.h"
20 #include "core/components/transform/transform_component.h"
21
22 namespace OHOS::Ace {
23
CreateRenderNode()24 RefPtr<RenderNode> IndexerItemComponent::CreateRenderNode()
25 {
26 return RenderIndexerItem::Create();
27 }
28
BuildItem()29 void IndexerItemComponent::BuildItem()
30 {
31 box_ = AceType::MakeRefPtr<BoxComponent>();
32 RefPtr<Component> tail = box_;
33 if (rotate_) {
34 image_ = AceType::MakeRefPtr<ImageComponent>(InternalResource::ResourceId::INDEXER_ARROW_PNG);
35 image_->SetHeight(itemSize_);
36 image_->SetWidth(itemSize_);
37 box_->SetChild(image_);
38 tail = image_;
39 } else {
40 text_ = AceType::MakeRefPtr<TextComponent>(StringUtils::Str16ToStr8(strLabel_));
41 TextStyle textStyle;
42 textStyle.SetTextAlign(TextAlign::CENTER);
43 textStyle.SetFontWeight(FontWeight::W400);
44 text_->SetTextStyle(textStyle);
45 box_->SetChild(text_);
46 tail = text_;
47 }
48 box_->SetFlex(BoxFlex::FLEX_NO);
49 box_->SetWidth(itemSize_.Value(), itemSize_.Unit());
50 box_->SetHeight(itemSize_.Value(), itemSize_.Unit());
51 box_->SetAlignment(Alignment::CENTER);
52 // generate background
53 RefPtr<Decoration> background = AceType::MakeRefPtr<Decoration>();
54 background->SetBackgroundColor(Color::TRANSPARENT);
55 // generate circle
56 Radius radius = circleMode_ ? Radius(itemSize_ / 2.0) : Radius(Dimension(4.0, DimensionUnit::VP));
57 background->SetBorderRadius(radius);
58 box_->SetBackDecoration(background);
59 if (rotate_) {
60 RefPtr<TransformComponent> rotate = AceType::MakeRefPtr<TransformComponent>();
61 rotate->SetChild(box_);
62 Component::MergeRSNode(rotate, tail);
63 SetChild(rotate);
64 } else {
65 Component::MergeRSNode(box_, tail);
66 SetChild(box_);
67 }
68 }
69
IsCorrectItem(const std::string & indexKey) const70 bool IndexerItemComponent::IsCorrectItem(const std::string& indexKey) const
71 {
72 // check whether the indexkey matched the section string
73 if (strSection_.empty()) {
74 LOGE("[indexer] IsCorrectItem invalid strSection_");
75 return false;
76 }
77
78 if (strSection_ == INDEXER_STR_SHARP) {
79 return false;
80 }
81
82 if (indexKey.empty()) {
83 LOGE("[indexer] IsCorrectItem NULL index key");
84 return false;
85 }
86
87 std::u16string u16IndexKey = StringUtils::Str8ToStr16(indexKey);
88 for (size_t i = 0; i < strSection_.size(); ++i) {
89 if (u16IndexKey[0] == strSection_[i]) {
90 return true;
91 }
92 }
93
94 return false;
95 }
96
AddIndexKey(const std::string & indexKey)97 uint32_t IndexerItemComponent::AddIndexKey(const std::string& indexKey)
98 {
99 uint32_t itemIndex = 0;
100
101 if (strSection_.empty()) {
102 LOGE("[indexer] AddIndexKey invalid strSection_");
103 return itemIndex;
104 }
105
106 if (strSection_ == INDEXER_STR_SHARP) {
107 return AddIndexKeyForSharp(indexKey);
108 }
109
110 if (indexKey.empty()) {
111 LOGE("[indexer] AddIndexKey NULL index key");
112 return itemIndex;
113 }
114
115 if (!IsCorrectItem(indexKey)) {
116 LOGE("[indexer] AddIndexKey index key does not match section");
117 return itemIndex;
118 }
119
120 auto it = indexKey_.begin();
121 for (; it != indexKey_.end(); ++it) {
122 if (indexKey.compare((*it)) < 0) {
123 itemIndex++;
124 indexKey_.insert(it, indexKey);
125 break;
126 } else {
127 itemIndex++;
128 }
129 }
130
131 if (it == indexKey_.end()) {
132 indexKey_.emplace_back(indexKey);
133 itemIndex++;
134 }
135
136 keyCount_++;
137 itemIndex += static_cast<uint32_t>(sectionIndex_);
138 if (circleMode_) {
139 itemIndex--;
140 }
141
142 return itemIndex;
143 }
144
AddIndexKeyForSharp(const std::string & indexKey)145 uint32_t IndexerItemComponent::AddIndexKeyForSharp(const std::string& indexKey)
146 {
147 uint32_t itemIndex = 0;
148 if (strSection_ != INDEXER_STR_SHARP) {
149 LOGE("[indexer] AddIndexKeyForSharp the section key is not #, section:%{public}s",
150 StringUtils::Str16ToStr8(strSection_).c_str());
151 return itemIndex;
152 }
153
154 auto item = indexKey_.begin();
155 if (indexKey.empty()) {
156 // add NULL key
157 for (; item != indexKey_.end(); ++item) {
158 itemIndex++;
159 if (!item->empty()) {
160 indexKey_.insert(item, indexKey);
161 break;
162 }
163 }
164 } else {
165 // add number key
166 for (; item != indexKey_.end(); ++item) {
167 itemIndex++;
168 if (indexKey.compare((*item)) < 0) {
169 indexKey_.insert(item, indexKey);
170 break;
171 }
172 }
173 }
174
175 if (item == indexKey_.end()) {
176 indexKey_.emplace_back(indexKey);
177 itemIndex++;
178 }
179
180 keyCount_++;
181 itemIndex += static_cast<uint32_t>(sectionIndex_);
182 if (circleMode_) {
183 itemIndex--;
184 }
185
186 return itemIndex;
187 }
188
RemoveIndexKey(const std::string & indexKey)189 bool IndexerItemComponent::RemoveIndexKey(const std::string& indexKey)
190 {
191 bool ret = false;
192 if (strSection_.empty()) {
193 LOGE("[indexer] RemoveIndexKey invalid strSection_");
194 return ret;
195 }
196
197 if (strSection_ == INDEXER_STR_SHARP) {
198 return RemoveIndexKeyForSharp(indexKey);
199 }
200
201 if (indexKey.empty()) {
202 LOGE("[indexer] RemoveIndexKey NULL index key");
203 return ret;
204 }
205
206 if (!IsCorrectItem(indexKey)) {
207 LOGE("[indexer] RemoveIndexKey index key does not match section");
208 return ret;
209 }
210
211 auto it = indexKey_.begin();
212 for (; it != indexKey_.end(); ++it) {
213 if (indexKey == *it) {
214 indexKey_.erase(it);
215 keyCount_--;
216 ret = true;
217 break;
218 }
219 }
220
221 return ret;
222 }
223
RemoveIndexKeyForSharp(const std::string & indexKey)224 bool IndexerItemComponent::RemoveIndexKeyForSharp(const std::string& indexKey)
225 {
226 bool ret = false;
227
228 if (strSection_ != INDEXER_STR_SHARP) {
229 LOGE("[indexer] RemoveIndexKeyForSharp the section key is not #, section:%{public}s",
230 StringUtils::Str16ToStr8(strSection_).c_str());
231 return ret;
232 }
233
234 auto item = indexKey_.begin();
235 if (indexKey.empty()) {
236 // remove NULL key
237 for (; item != indexKey_.end(); ++item) {
238 if (item->empty()) {
239 indexKey_.erase(item);
240 keyCount_--;
241 ret = true;
242 break;
243 }
244 }
245 } else {
246 // remove number key
247 for (; item != indexKey_.end(); ++item) {
248 if (indexKey == *item) {
249 indexKey_.erase(item);
250 keyCount_--;
251 ret = true;
252 break;
253 }
254 }
255 }
256
257 return ret;
258 }
259
PrintIndexerItem() const260 void IndexerItemComponent::PrintIndexerItem() const
261 {
262 int count = 1;
263 LOGI("[indexer] label:%{public}s section:%{public}s %{public}d",
264 StringUtils::Str16ToStr8(strLabel_).c_str(), StringUtils::Str16ToStr8(strSection_).c_str(), sectionIndex_);
265 for (auto it = indexKey_.begin(); it != indexKey_.end(); ++it) {
266 if (circleMode_) {
267 LOGI("[indexer] key:%{public}s %{public}d", it->c_str(), sectionIndex_ + count - 1);
268 } else {
269 LOGI("[indexer] key:%{public}s %{public}d", it->c_str(), sectionIndex_ + count);
270 }
271 count++;
272 }
273 }
274
SetTextStyle(bool active)275 void IndexerItemComponent::SetTextStyle(bool active)
276 {
277 if (!text_) {
278 LOGE("[indexer] Get child text failed.");
279 return;
280 }
281 if (active) {
282 text_->SetTextStyle(activeStyle_);
283 } else {
284 text_->SetTextStyle(normalStyle_);
285 }
286 }
287
288 } // namespace OHOS::Ace
289