• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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