1 /*
2 * Copyright (c) 2024 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 #include "core/interfaces/native/node/node_indicator_modifier.h"
16
17 #include "base/geometry/calc_dimension.h"
18 #include "core/components/common/layout/constants.h"
19 #include "core/components_ng/base/frame_node.h"
20 #include "core/components_ng/base/view_abstract.h"
21 #include "core/components_ng/pattern/swiper_indicator/indicator_common/indicator_model_ng.h"
22 #include "core/pipeline/base/element_register.h"
23
24 namespace OHOS::Ace::NG {
25 constexpr int32_t INDICATOR_TYPE_INDEX = 0;
26 constexpr int32_t DEFAULT_DISPLAY_COUNT = 1;
27 constexpr int32_t DIGIT_INDICATOR_LEFT = 7;
28 constexpr int32_t DIGIT_INDICATOR_TOP = 8;
29 constexpr int32_t DIGIT_INDICATOR_RIGHT = 9;
30 constexpr int32_t DIGIT_INDICATOR_BOTTOM = 10;
31 constexpr int32_t DIGIT_INDICATOR_FONT_COLOR = 1;
32 constexpr int32_t DIGIT_INDICATOR_SELECTED_FONT_COLOR = 2;
33 constexpr int32_t DIGIT_INDICATOR_DIGIT_FONT_SIZE = 3;
34 constexpr int32_t DIGIT_INDICATOR_DIGIT_FONT_WEIGHT = 4;
35 constexpr int32_t DIGIT_INDICATOR_SELECTED_DIGIT_FONT_SIZE = 5;
36 constexpr int32_t DIGIT_INDICATOR_SELECTED_DIGIT_FONT_WEIGHT = 6;
37 constexpr int32_t DOT_INDICATOR_ITEM_WIDTH = 1;
38 constexpr int32_t DOT_INDICATOR_ITEM_HEIGHT = 2;
39 constexpr int32_t DOT_INDICATOR_SELECTED_ITEM_WIDTH = 3;
40 constexpr int32_t DOT_INDICATOR_SELECTED_ITEM_HEIGHT = 4;
41 constexpr int32_t DOT_INDICATOR_MASK = 5;
42 constexpr int32_t DOT_INDICATOR_COLOR = 6;
43 constexpr int32_t DOT_INDICATOR_SELECTED_COLOR = 7;
44 constexpr int32_t DOT_INDICATOR_LEFT = 8;
45 constexpr int32_t DOT_INDICATOR_TOP = 9;
46 constexpr int32_t DOT_INDICATOR_RIGHT = 10;
47 constexpr int32_t DOT_INDICATOR_BOTTOM = 11;
48 constexpr int32_t DOT_INDICATOR_INFO_SIZE = 11;
49 constexpr int32_t DOT_INDICATOR_MAX_DISPLAY_COUNT = 12;
50 namespace {
51
ParseIndicatorDimension(const std::string & value)52 std::optional<Dimension> ParseIndicatorDimension(const std::string& value)
53 {
54 std::optional<Dimension> indicatorDimension;
55 if (value.empty()) {
56 return indicatorDimension;
57 }
58 CalcDimension dimPosition = StringUtils::StringToCalcDimension(value, false, DimensionUnit::VP);
59 indicatorDimension = LessNotEqual(dimPosition.ConvertToPx(), 0.0f) ? 0.0_vp : dimPosition;
60 return indicatorDimension;
61 }
62
GetFontContent(const std::string & size,const std::string & weight,bool isSelected,SwiperDigitalParameters & digitalParameters)63 void GetFontContent(
64 const std::string& size, const std::string& weight, bool isSelected, SwiperDigitalParameters& digitalParameters)
65 {
66 auto pipelineContext = PipelineBase::GetCurrentContextSafely();
67 CHECK_NULL_VOID(pipelineContext);
68 auto indicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
69 CHECK_NULL_VOID(indicatorTheme);
70 CalcDimension fontSize = StringUtils::StringToCalcDimension(size, false, DimensionUnit::VP);
71 if (LessOrEqual(fontSize.Value(), 0.0) || fontSize.Unit() == DimensionUnit::PERCENT) {
72 fontSize = indicatorTheme->GetDigitalIndicatorTextStyle().GetFontSize();
73 }
74 if (isSelected) {
75 digitalParameters.selectedFontSize = fontSize;
76 } else {
77 digitalParameters.fontSize = fontSize;
78 }
79 if (!weight.empty()) {
80 if (isSelected) {
81 digitalParameters.selectedFontWeight = StringUtils::StringToFontWeight(weight, FontWeight::NORMAL);
82 } else {
83 digitalParameters.fontWeight = StringUtils::StringToFontWeight(weight, FontWeight::NORMAL);
84 }
85 } else {
86 if (isSelected) {
87 digitalParameters.selectedFontWeight = indicatorTheme->GetDigitalIndicatorTextStyle().GetFontWeight();
88 } else {
89 digitalParameters.fontWeight = indicatorTheme->GetDigitalIndicatorTextStyle().GetFontWeight();
90 }
91 }
92 }
93
GetInfoFromVectorByIndex(const std::vector<std::string> & dotIndicatorInfo,int32_t index)94 std::string GetInfoFromVectorByIndex(const std::vector<std::string>& dotIndicatorInfo, int32_t index)
95 {
96 auto dotIndicatorInfoSize = dotIndicatorInfo.size();
97 return dotIndicatorInfoSize < DOT_INDICATOR_INFO_SIZE
98 ? ""
99 : (dotIndicatorInfo[index] == "-" ? "" : dotIndicatorInfo[index]);
100 }
101
GetDigitIndicatorInfo(const std::vector<std::string> & digitIndicatorInfo)102 SwiperDigitalParameters GetDigitIndicatorInfo(const std::vector<std::string>& digitIndicatorInfo)
103 {
104 auto dotLeftValue = digitIndicatorInfo[DIGIT_INDICATOR_LEFT] == "-" ? "" : digitIndicatorInfo[DIGIT_INDICATOR_LEFT];
105 auto dotTopValue = digitIndicatorInfo[DIGIT_INDICATOR_TOP] == "-" ? "" : digitIndicatorInfo[DIGIT_INDICATOR_TOP];
106 auto dotRightValue =
107 digitIndicatorInfo[DIGIT_INDICATOR_RIGHT] == "-" ? "" : digitIndicatorInfo[DIGIT_INDICATOR_RIGHT];
108 auto dotBottomValue =
109 digitIndicatorInfo[DIGIT_INDICATOR_BOTTOM] == "-" ? "" : digitIndicatorInfo[DIGIT_INDICATOR_BOTTOM];
110 auto fontColorValue =
111 digitIndicatorInfo[DIGIT_INDICATOR_FONT_COLOR] == "-" ? "" : digitIndicatorInfo[DIGIT_INDICATOR_FONT_COLOR];
112 auto selectedFontColorValue = digitIndicatorInfo[DIGIT_INDICATOR_SELECTED_FONT_COLOR] == "-"
113 ? ""
114 : digitIndicatorInfo[DIGIT_INDICATOR_SELECTED_FONT_COLOR];
115 auto digitFontSize = digitIndicatorInfo[DIGIT_INDICATOR_DIGIT_FONT_SIZE] == "-"
116 ? ""
117 : digitIndicatorInfo[DIGIT_INDICATOR_DIGIT_FONT_SIZE];
118 auto digitFontWeight = digitIndicatorInfo[DIGIT_INDICATOR_DIGIT_FONT_WEIGHT] == "-"
119 ? ""
120 : digitIndicatorInfo[DIGIT_INDICATOR_DIGIT_FONT_WEIGHT];
121 auto selectedDigitFontSize = digitIndicatorInfo[DIGIT_INDICATOR_SELECTED_DIGIT_FONT_SIZE] == "-"
122 ? ""
123 : digitIndicatorInfo[DIGIT_INDICATOR_SELECTED_DIGIT_FONT_SIZE];
124 auto selectedDigitFontWeight = digitIndicatorInfo[DIGIT_INDICATOR_SELECTED_DIGIT_FONT_WEIGHT] == "-"
125 ? ""
126 : digitIndicatorInfo[DIGIT_INDICATOR_SELECTED_DIGIT_FONT_WEIGHT];
127 auto pipelineContext = PipelineBase::GetCurrentContextSafely();
128 CHECK_NULL_RETURN(pipelineContext, SwiperDigitalParameters());
129 auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
130 CHECK_NULL_RETURN(swiperIndicatorTheme, SwiperDigitalParameters());
131 bool parseOk = false;
132 SwiperDigitalParameters digitalParameters;
133 digitalParameters.dimLeft = ParseIndicatorDimension(dotLeftValue);
134 digitalParameters.dimTop = ParseIndicatorDimension(dotTopValue);
135 digitalParameters.dimRight = ParseIndicatorDimension(dotRightValue);
136 digitalParameters.dimBottom = ParseIndicatorDimension(dotBottomValue);
137 Color fontColor;
138 parseOk = Color::ParseColorString(fontColorValue, fontColor);
139 digitalParameters.fontColor =
140 parseOk ? fontColor : swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetTextColor();
141 parseOk = Color::ParseColorString(selectedFontColorValue, fontColor);
142 digitalParameters.selectedFontColor =
143 parseOk ? fontColor : swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetTextColor();
144 GetFontContent(digitFontSize, digitFontWeight, false, digitalParameters);
145 GetFontContent(selectedDigitFontSize, selectedDigitFontWeight, true, digitalParameters);
146 return digitalParameters;
147 }
148
SetItem4GetDotIndicatorInfo(SwiperParameters & indicatorParameters,FrameNode * frameNode,const std::vector<std::string> & dotIndicatorInfo)149 void SetItem4GetDotIndicatorInfo(
150 SwiperParameters& indicatorParameters, FrameNode* frameNode, const std::vector<std::string>& dotIndicatorInfo)
151 {
152 CHECK_NULL_VOID(frameNode);
153 auto pipelineContext = frameNode->GetContext();
154 CHECK_NULL_VOID(pipelineContext);
155 auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
156 CHECK_NULL_VOID(swiperIndicatorTheme);
157 auto itemWidthValue = GetInfoFromVectorByIndex(dotIndicatorInfo, DOT_INDICATOR_ITEM_WIDTH);
158 auto itemHeightValue = GetInfoFromVectorByIndex(dotIndicatorInfo, DOT_INDICATOR_ITEM_HEIGHT);
159 auto selectedItemWidthValue = GetInfoFromVectorByIndex(dotIndicatorInfo, DOT_INDICATOR_SELECTED_ITEM_WIDTH);
160 auto selectedItemHeightValue = GetInfoFromVectorByIndex(dotIndicatorInfo, DOT_INDICATOR_SELECTED_ITEM_HEIGHT);
161 CalcDimension dimPosition = StringUtils::StringToCalcDimension(itemWidthValue, false, DimensionUnit::VP);
162 auto defaultSize = swiperIndicatorTheme->GetSize();
163 bool parseItemWOk = !itemWidthValue.empty() && dimPosition.Unit() != DimensionUnit::PERCENT;
164 indicatorParameters.itemWidth = (parseItemWOk && (dimPosition > 0.0_vp)) ? dimPosition : defaultSize;
165 dimPosition = StringUtils::StringToCalcDimension(itemHeightValue, false, DimensionUnit::VP);
166 bool parseItemHOk = !itemHeightValue.empty() && dimPosition.Unit() != DimensionUnit::PERCENT;
167 indicatorParameters.itemHeight = (parseItemHOk && (dimPosition > 0.0_vp)) ? dimPosition : defaultSize;
168 dimPosition = StringUtils::StringToCalcDimension(selectedItemWidthValue, false, DimensionUnit::VP);
169 bool parseSeleItemWOk = !selectedItemWidthValue.empty() && dimPosition.Unit() != DimensionUnit::PERCENT;
170 indicatorParameters.selectedItemWidth = (parseSeleItemWOk && (dimPosition > 0.0_vp)) ? dimPosition : defaultSize;
171 dimPosition = StringUtils::StringToCalcDimension(selectedItemHeightValue, false, DimensionUnit::VP);
172 bool parseSeleItemHOk = !selectedItemHeightValue.empty() && dimPosition.Unit() != DimensionUnit::PERCENT;
173 indicatorParameters.selectedItemHeight = (parseSeleItemHOk && (dimPosition > 0.0_vp)) ? dimPosition : defaultSize;
174 if (!parseSeleItemWOk && !parseSeleItemHOk && !parseItemWOk && !parseItemHOk) {
175 IndicatorModelNG::SetIsIndicatorCustomSize(frameNode, false);
176 } else {
177 IndicatorModelNG::SetIsIndicatorCustomSize(frameNode, true);
178 }
179 }
180
GetDotIndicatorInfo(FrameNode * frameNode,const std::vector<std::string> & dotIndicatorInfo)181 SwiperParameters GetDotIndicatorInfo(FrameNode* frameNode, const std::vector<std::string>& dotIndicatorInfo)
182 {
183 auto maskValue = GetInfoFromVectorByIndex(dotIndicatorInfo, DOT_INDICATOR_MASK);
184 auto colorValue = GetInfoFromVectorByIndex(dotIndicatorInfo, DOT_INDICATOR_COLOR);
185 auto selectedColorValue = GetInfoFromVectorByIndex(dotIndicatorInfo, DOT_INDICATOR_SELECTED_COLOR);
186 CHECK_NULL_RETURN(frameNode, SwiperParameters());
187 auto pipelineContext = frameNode->GetContext();
188 CHECK_NULL_RETURN(pipelineContext, SwiperParameters());
189 auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
190 CHECK_NULL_RETURN(swiperIndicatorTheme, SwiperParameters());
191 bool parseOk = false;
192 SwiperParameters indicatorParameters;
193 SetItem4GetDotIndicatorInfo(indicatorParameters, frameNode, dotIndicatorInfo);
194 auto leftValue = GetInfoFromVectorByIndex(dotIndicatorInfo, DOT_INDICATOR_LEFT);
195 auto topValue = GetInfoFromVectorByIndex(dotIndicatorInfo, DOT_INDICATOR_TOP);
196 auto rightValue = GetInfoFromVectorByIndex(dotIndicatorInfo, DOT_INDICATOR_RIGHT);
197 auto bottomValue = GetInfoFromVectorByIndex(dotIndicatorInfo, DOT_INDICATOR_BOTTOM);
198 indicatorParameters.dimLeft = ParseIndicatorDimension(leftValue);
199 indicatorParameters.dimTop = ParseIndicatorDimension(topValue);
200 indicatorParameters.dimRight = ParseIndicatorDimension(rightValue);
201 indicatorParameters.dimBottom = ParseIndicatorDimension(bottomValue);
202 if (maskValue != "2") {
203 indicatorParameters.maskValue = (maskValue == "1");
204 }
205 Color colorVal;
206 parseOk = Color::ParseColorString(colorValue, colorVal);
207 indicatorParameters.colorVal = parseOk ? colorVal : swiperIndicatorTheme->GetColor();
208 parseOk = Color::ParseColorString(selectedColorValue, colorVal);
209 indicatorParameters.selectedColorVal = parseOk ? colorVal : swiperIndicatorTheme->GetSelectedColor();
210 auto maxDisplayCount = GetInfoFromVectorByIndex(dotIndicatorInfo, DOT_INDICATOR_MAX_DISPLAY_COUNT);
211 if (!maxDisplayCount.empty()) {
212 indicatorParameters.maxDisplayCountVal = StringUtils::StringToInt(maxDisplayCount);
213 }
214 return indicatorParameters;
215 }
216
SetInitialIndex(ArkUINodeHandle node,ArkUI_Int32 index)217 void SetInitialIndex(ArkUINodeHandle node, ArkUI_Int32 index)
218 {
219 auto* frameNode = reinterpret_cast<FrameNode*>(node);
220 CHECK_NULL_VOID(frameNode);
221 IndicatorModelNG::SetInitialIndex(frameNode, index);
222 }
223
ResetInitialIndex(ArkUINodeHandle node)224 void ResetInitialIndex(ArkUINodeHandle node)
225 {
226 auto* frameNode = reinterpret_cast<FrameNode*>(node);
227 CHECK_NULL_VOID(frameNode);
228 IndicatorModelNG::SetInitialIndex(frameNode, 0);
229 }
230
SetCount(ArkUINodeHandle node,ArkUI_Int32 count)231 void SetCount(ArkUINodeHandle node, ArkUI_Int32 count)
232 {
233 auto* frameNode = reinterpret_cast<FrameNode*>(node);
234 CHECK_NULL_VOID(frameNode);
235 if (count < 0) {
236 count = DEFAULT_CACHED_COUNT;
237 }
238 IndicatorModelNG::SetCount(frameNode, count);
239 }
240
ResetCount(ArkUINodeHandle node)241 void ResetCount(ArkUINodeHandle node)
242 {
243 auto* frameNode = reinterpret_cast<FrameNode*>(node);
244 CHECK_NULL_VOID(frameNode);
245 IndicatorModelNG::SetCount(frameNode, DEFAULT_DISPLAY_COUNT);
246 }
247
SetOnChange(ArkUINodeHandle node,void * callback)248 void SetOnChange(ArkUINodeHandle node, void* callback)
249 {
250 auto* frameNode = reinterpret_cast<FrameNode*>(node);
251 CHECK_NULL_VOID(frameNode);
252 if (callback) {
253 auto onChange = reinterpret_cast<std::function<void(const BaseEventInfo* info)>*>(callback);
254 IndicatorModelNG::SetOnChange(frameNode, std::move(*onChange));
255 } else {
256 IndicatorModelNG::SetOnChange(frameNode, nullptr);
257 }
258 }
259
ResetOnChange(ArkUINodeHandle node)260 void ResetOnChange(ArkUINodeHandle node)
261 {
262 auto* frameNode = reinterpret_cast<FrameNode*>(node);
263 CHECK_NULL_VOID(frameNode);
264 IndicatorModelNG::SetOnChange(frameNode, nullptr);
265 }
266
SetStyle(ArkUINodeHandle node,ArkUI_CharPtr indicatorStr)267 void SetStyle(ArkUINodeHandle node, ArkUI_CharPtr indicatorStr)
268 {
269 auto* frameNode = reinterpret_cast<FrameNode*>(node);
270 CHECK_NULL_VOID(frameNode);
271 std::vector<std::string> res;
272 std::string indicatorValues = std::string(indicatorStr);
273 StringUtils::StringSplitter(indicatorValues, '|', res);
274 std::string type = res[INDICATOR_TYPE_INDEX];
275 if (type == "ArkDigitIndicator") {
276 SwiperDigitalParameters digitalParameters = GetDigitIndicatorInfo(res);
277 IndicatorModelNG::SetDigitIndicatorStyle(frameNode, digitalParameters);
278 IndicatorModelNG::SetIndicatorType(frameNode, SwiperIndicatorType::DIGIT);
279 } else {
280 SwiperParameters indicatorParameters = GetDotIndicatorInfo(frameNode, res);
281 IndicatorModelNG::SetDotIndicatorStyle(frameNode, indicatorParameters);
282 IndicatorModelNG::SetIndicatorType(frameNode, SwiperIndicatorType::DOT);
283 }
284 }
285
ResetStyle(ArkUINodeHandle node)286 void ResetStyle(ArkUINodeHandle node)
287 {
288 auto* frameNode = reinterpret_cast<FrameNode*>(node);
289 CHECK_NULL_VOID(frameNode);
290 IndicatorModelNG::SetIndicatorType(frameNode, SwiperIndicatorType::DOT);
291 }
292
SetLoop(ArkUINodeHandle node,ArkUI_Bool loop)293 void SetLoop(ArkUINodeHandle node, ArkUI_Bool loop)
294 {
295 auto* frameNode = reinterpret_cast<FrameNode*>(node);
296 CHECK_NULL_VOID(frameNode);
297 IndicatorModelNG::SetLoop(frameNode, loop);
298 }
299
ResetLoop(ArkUINodeHandle node)300 void ResetLoop(ArkUINodeHandle node)
301 {
302 auto* frameNode = reinterpret_cast<FrameNode*>(node);
303 CHECK_NULL_VOID(frameNode);
304 IndicatorModelNG::SetLoop(frameNode, true);
305 }
306
SetVertical(ArkUINodeHandle node,ArkUI_Bool isVertical)307 void SetVertical(ArkUINodeHandle node, ArkUI_Bool isVertical)
308 {
309 auto* frameNode = reinterpret_cast<FrameNode*>(node);
310 CHECK_NULL_VOID(frameNode);
311 IndicatorModelNG::SetDirection(frameNode, isVertical ? Axis::VERTICAL : Axis::HORIZONTAL);
312 }
313
ResetVertical(ArkUINodeHandle node)314 void ResetVertical(ArkUINodeHandle node)
315 {
316 auto* frameNode = reinterpret_cast<FrameNode*>(node);
317 CHECK_NULL_VOID(frameNode);
318 IndicatorModelNG::SetDirection(frameNode, Axis::HORIZONTAL);
319 }
320 } // namespace
321 namespace NodeModifier {
GetIndicatorComponentModifier()322 const ArkUIIndicatorComponentModifier* GetIndicatorComponentModifier()
323 {
324 static const ArkUIIndicatorComponentModifier modifier = {
325 .setInitialIndex = SetInitialIndex,
326 .resetInitialIndex = ResetInitialIndex,
327 .setCount = SetCount,
328 .resetCount = ResetCount,
329 .setOnChange = SetOnChange,
330 .resetOnChange = ResetOnChange,
331 .setStyle = SetStyle,
332 .resetStyle = ResetStyle,
333 .setLoop = SetLoop,
334 .resetLoop = ResetLoop,
335 .setVertical = SetVertical,
336 .resetVertical = ResetVertical
337 };
338 return &modifier;
339 };
340
341 } // namespace NodeModifier
342 } // namespace OHOS::Ace::NG
343