• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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_ng/pattern/stepper/stepper_pattern.h"
17 
18 #include <algorithm>
19 
20 #include "base/i18n/localization.h"
21 #include "base/utils/utils.h"
22 #include "core/components/stepper/stepper_theme.h"
23 #include "core/components_ng/pattern/button/button_event_hub.h"
24 #include "core/components_ng/pattern/button/button_pattern.h"
25 #include "core/components_ng/pattern/image/image_pattern.h"
26 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
27 #include "core/components_ng/pattern/loading_progress/loading_progress_pattern.h"
28 #include "core/components_ng/pattern/stepper/stepper_item_layout_property.h"
29 #include "core/components_ng/pattern/stepper/stepper_node.h"
30 #include "core/components_ng/pattern/swiper/swiper_pattern.h"
31 #include "core/components_ng/pattern/text/text_layout_property.h"
32 #include "core/components_ng/pattern/text/text_pattern.h"
33 #include "core/components_v2/inspector/inspector_constants.h"
34 #include "core/pipeline/pipeline_base.h"
35 
36 namespace OHOS::Ace::NG {
37 namespace {
38 constexpr int32_t PRESS_ANIMATION_DURATION = 100;
39 constexpr int32_t HOVER_ANIMATION_DURATION = 250;
40 
41 constexpr float BUTTON_ON_HOVER_BEZIER_CURVE_X0 = 0.2f;
42 constexpr float BUTTON_ON_HOVER_BEZIER_CURVE_Y0 = 0.0f;
43 constexpr float BUTTON_ON_HOVER_BEZIER_CURVE_X1 = 0.2f;
44 constexpr float BUTTON_ON_HOVER_BEZIER_CURVE_Y1 = 1.0f;
45 
46 constexpr float BUTTON_ON_PRESS_BEZIER_CURVE_X0 = 0.33f;
47 constexpr float BUTTON_ON_PRESS_BEZIER_CURVE_Y0 = 0.0f;
48 constexpr float BUTTON_ON_PRESS_BEZIER_CURVE_X1 = 0.67f;
49 constexpr float BUTTON_ON_PRESS_BEZIER_CURVE_Y1 = 1.0f;
50 } // namespace
51 
OnModifyDone()52 void StepperPattern::OnModifyDone()
53 {
54     Pattern::OnModifyDone();
55     auto hostNode = DynamicCast<StepperNode>(GetHost());
56     CHECK_NULL_VOID(hostNode);
57     auto swiperNode =
58         DynamicCast<FrameNode>(hostNode->GetChildAtIndex(hostNode->GetChildIndexById(hostNode->GetSwiperId())));
59     CHECK_NULL_VOID(swiperNode);
60     index_ = swiperNode->GetLayoutProperty<SwiperLayoutProperty>()->GetIndex().value_or(0);
61 
62     auto swiperEventHub = swiperNode->GetEventHub<SwiperEventHub>();
63     CHECK_NULL_VOID(swiperEventHub);
64     maxIndex_ = TotalCount();
65     if (index_ > maxIndex_) {
66         index_ = 0;
67         hostNode->GetLayoutProperty<StepperLayoutProperty>()->UpdateIndex(index_);
68         swiperNode->GetLayoutProperty<SwiperLayoutProperty>()->UpdateIndex(index_);
69         swiperNode->MarkModifyDone();
70         swiperNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
71     }
72     InitSwiperChangeEvent(swiperEventHub);
73     UpdateOrCreateLeftButtonNode(index_);
74     UpdateOrCreateRightButtonNode(index_);
75     InitButtonClickEvent();
76     SetAccessibilityAction();
77 }
78 
OnAttachToFrameNode()79 void StepperPattern::OnAttachToFrameNode()
80 {
81     auto host = GetHost();
82     CHECK_NULL_VOID(host);
83     host->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_PARENT);
84     host->GetRenderContext()->UpdateClipEdge(true);
85 }
86 
InitSwiperChangeEvent(const RefPtr<SwiperEventHub> & swiperEventHub)87 void StepperPattern::InitSwiperChangeEvent(const RefPtr<SwiperEventHub>& swiperEventHub)
88 {
89     ChangeEvent changeEvent = [weak = WeakClaim(this)](int32_t index) {
90         auto stepperPattern = weak.Upgrade();
91         CHECK_NULL_VOID_NOLOG(stepperPattern->TotalCount() > -1);
92         stepperPattern->UpdateIndexWithoutMeasure(index);
93         stepperPattern->UpdateOrCreateLeftButtonNode(index);
94         stepperPattern->UpdateOrCreateRightButtonNode(index);
95         stepperPattern->InitButtonClickEvent();
96     };
97     if (swiperChangeEvent_) {
98         (*swiperChangeEvent_).swap(changeEvent);
99     } else {
100         swiperChangeEvent_ = std::make_shared<ChangeEvent>(std::move(changeEvent));
101         swiperEventHub->AddOnChangeEvent(swiperChangeEvent_);
102     }
103 }
104 
UpdateIndexWithoutMeasure(int32_t index)105 void StepperPattern::UpdateIndexWithoutMeasure(int32_t index)
106 {
107     auto hostNode = DynamicCast<StepperNode>(GetHost());
108     CHECK_NULL_VOID(hostNode);
109     auto stepperLayoutProperty = hostNode->GetLayoutProperty<StepperLayoutProperty>();
110     CHECK_NULL_VOID(stepperLayoutProperty);
111     stepperLayoutProperty->UpdateIndexWithoutMeasure(index);
112 
113     auto swiperNode =
114         DynamicCast<FrameNode>(hostNode->GetChildAtIndex(hostNode->GetChildIndexById(hostNode->GetSwiperId())));
115     CHECK_NULL_VOID(swiperNode);
116     auto swiperLayoutProperty = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
117     CHECK_NULL_VOID(swiperLayoutProperty);
118     swiperLayoutProperty->UpdateIndexWithoutMeasure(index);
119 }
120 
UpdateOrCreateLeftButtonNode(int32_t index)121 void StepperPattern::UpdateOrCreateLeftButtonNode(int32_t index)
122 {
123     auto hostNode = DynamicCast<StepperNode>(GetHost());
124     CHECK_NULL_VOID(hostNode);
125     if (index <= 0) {
126         hostNode->RemoveLeftButtonNode();
127     } else if (!hostNode->HasLeftButtonNode()) {
128         CreateLeftButtonNode();
129         UpdateLeftButtonNode(index);
130     } else {
131         UpdateLeftButtonNode(index);
132     }
133     index_ = index;
134     hostNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
135 }
136 
CreateLeftButtonNode()137 void StepperPattern::CreateLeftButtonNode()
138 {
139     auto stepperTheme = GetTheme();
140     CHECK_NULL_VOID(stepperTheme);
141     auto hostNode = DynamicCast<StepperNode>(GetHost());
142     CHECK_NULL_VOID(hostNode);
143     // Create buttonNode
144     auto buttonId = hostNode->GetLeftButtonId();
145     auto buttonPattern = AceType::MakeRefPtr<NG::ButtonPattern>();
146     CHECK_NULL_VOID(buttonPattern);
147     buttonPattern->setComponentButtonType(ComponentButtonType::STEPPER);
148     buttonPattern->SetFocusBorderColor(stepperTheme->GetFocusColor());
149     auto buttonNode = FrameNode::CreateFrameNode(V2::BUTTON_ETS_TAG, buttonId, buttonPattern);
150     CHECK_NULL_VOID(buttonNode);
151     buttonNode->GetEventHub<ButtonEventHub>()->SetStateEffect(true);
152     buttonNode->GetLayoutProperty<ButtonLayoutProperty>()->UpdateType(ButtonType::NORMAL);
153     buttonNode->GetRenderContext()->UpdateBackgroundColor(stepperTheme->GetMouseHoverColor().ChangeOpacity(0));
154     buttonNode->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_CONTENT);
155     auto buttonRadius = stepperTheme->GetRadius();
156     buttonNode->GetLayoutProperty<ButtonLayoutProperty>()->UpdateBorderRadius(BorderRadiusProperty(buttonRadius));
157     buttonNode->MountToParent(hostNode);
158     buttonNode->MarkModifyDone();
159     InitButtonOnHoverEvent(buttonNode, true);
160     InitButtonTouchEvent(buttonNode);
161     // Create rowNode
162     auto rowNode = FrameNode::GetOrCreateFrameNode(V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
163         []() { return AceType::MakeRefPtr<LinearLayoutPattern>(false); });
164     rowNode->GetLayoutProperty<LinearLayoutProperty>()->UpdateSpace(stepperTheme->GetControlPadding());
165     rowNode->GetLayoutProperty()->UpdateMargin(
166         { CalcLength(stepperTheme->GetControlPadding()), CalcLength(stepperTheme->GetControlPadding()) });
167     rowNode->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_CONTENT);
168     rowNode->MountToParent(buttonNode);
169     rowNode->MarkModifyDone();
170     // Create imageNode
171     auto imageNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
172         []() { return AceType::MakeRefPtr<ImagePattern>(); });
173     imageNode->GetLayoutProperty()->UpdateUserDefinedIdealSize(
174         CalcSize(CalcLength(stepperTheme->GetArrowWidth()), CalcLength(stepperTheme->GetArrowHeight())));
175     imageNode->GetLayoutProperty<ImageLayoutProperty>()->UpdateImageFit(ImageFit::FILL);
176     ImageSourceInfo imageSourceInfo;
177     imageSourceInfo.SetResourceId(InternalResource::ResourceId::STEPPER_BACK_ARROW);
178     imageSourceInfo.SetFillColor(stepperTheme->GetArrowColor());
179     imageNode->GetLayoutProperty<ImageLayoutProperty>()->UpdateImageSourceInfo(imageSourceInfo);
180     SizeF sourceSize(static_cast<float>(stepperTheme->GetArrowWidth().ConvertToPx()),
181         static_cast<float>(stepperTheme->GetArrowHeight().ConvertToPx()));
182     imageNode->GetLayoutProperty<ImageLayoutProperty>()->UpdateSourceSize(sourceSize);
183     imageNode->MountToParent(rowNode);
184     imageNode->MarkModifyDone();
185     // Create textNode
186     auto textNode = FrameNode::GetOrCreateFrameNode(V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
187         []() { return AceType::MakeRefPtr<TextPattern>(); });
188     textNode->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_CONTENT);
189     textNode->GetRenderContext()->UpdateBackgroundColor(Color::TRANSPARENT);
190     auto textColor = stepperTheme->GetTextStyle().GetTextColor();
191     textNode->GetLayoutProperty<TextLayoutProperty>()->UpdateTextColor(textColor);
192     textNode->GetLayoutProperty<TextLayoutProperty>()->UpdateTextOverflow(TextOverflow::ELLIPSIS);
193     textNode->GetLayoutProperty<TextLayoutProperty>()->UpdateFontSize(stepperTheme->GetTextStyle().GetFontSize());
194     textNode->GetLayoutProperty<TextLayoutProperty>()->UpdateAdaptMinFontSize(stepperTheme->GetMinFontSize());
195     textNode->GetLayoutProperty<TextLayoutProperty>()->UpdateAdaptMaxFontSize(
196         stepperTheme->GetTextStyle().GetFontSize());
197     textNode->GetLayoutProperty<TextLayoutProperty>()->UpdateFontWeight(stepperTheme->GetTextStyle().GetFontWeight());
198     textNode->GetLayoutProperty<TextLayoutProperty>()->UpdateMaxLines(stepperTheme->GetTextMaxLines());
199     textNode->GetLayoutProperty()->UpdateAlignment(Alignment::CENTER);
200     textNode->GetFocusHub()->SetFocusable(true);
201     textNode->MountToParent(rowNode);
202     textNode->MarkModifyDone();
203 }
204 
UpdateLeftButtonNode(int32_t index)205 void StepperPattern::UpdateLeftButtonNode(int32_t index)
206 {
207     auto hostNode = DynamicCast<StepperNode>(GetHost());
208     CHECK_NULL_VOID(hostNode);
209     auto buttonNode = hostNode->GetChildAtIndex(hostNode->GetChildIndexById(hostNode->GetLeftButtonId()));
210     auto rowNode = buttonNode->GetChildAtIndex(0);
211     auto textNode = DynamicCast<FrameNode>(rowNode->GetChildAtIndex(1));
212 
213     auto swiperNode = hostNode->GetChildAtIndex(hostNode->GetChildIndexById(hostNode->GetSwiperId()));
214     auto stepperItemNode = DynamicCast<FrameNode>(swiperNode->GetChildAtIndex(static_cast<int32_t>(index)));
215     CHECK_NULL_VOID(stepperItemNode);
216     auto stepperItemLayoutProperty = stepperItemNode->GetLayoutProperty<StepperItemLayoutProperty>();
217     auto buttonBackText = Localization::GetInstance()->GetEntryLetters("stepper.back");
218     auto leftLabel = stepperItemLayoutProperty->GetLeftLabel().value_or(buttonBackText);
219     textNode->GetLayoutProperty<TextLayoutProperty>()->UpdateContent(leftLabel);
220 
221     textNode->MarkModifyDone();
222     textNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
223 }
224 
UpdateOrCreateRightButtonNode(int32_t index)225 void StepperPattern::UpdateOrCreateRightButtonNode(int32_t index)
226 {
227     auto hostNode = DynamicCast<StepperNode>(GetHost());
228     CHECK_NULL_VOID(hostNode);
229     if (!hostNode->HasRightButtonNode()) {
230         CreateRightButtonNode(index);
231     } else {
232         UpdateRightButtonNode(index);
233     }
234     index_ = index;
235     hostNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
236 }
CreateRightButtonNode(int32_t index)237 void StepperPattern::CreateRightButtonNode(int32_t index)
238 {
239     auto hostNode = DynamicCast<StepperNode>(GetHost());
240     CHECK_NULL_VOID(hostNode);
241     auto swiperNode = hostNode->GetChildAtIndex(hostNode->GetChildIndexById(hostNode->GetSwiperId()));
242     auto stepperItemNode = DynamicCast<FrameNode>(swiperNode->GetChildAtIndex(static_cast<int32_t>(index)));
243     CHECK_NULL_VOID(stepperItemNode);
244     auto labelStatus =
245         stepperItemNode->GetLayoutProperty<StepperItemLayoutProperty>()->GetLabelStatus().value_or("normal");
246     if (labelStatus == "normal") {
247         isRightLabelDisable_ = false;
248         if (index == maxIndex_) {
249             CreateArrowlessRightButtonNode(index, Localization::GetInstance()->GetEntryLetters("stepper.start"));
250         } else {
251             CreateArrowRightButtonNode(index, false);
252         }
253     } else if (labelStatus == "disabled") {
254         isRightLabelDisable_ = true;
255         CreateArrowRightButtonNode(index, true);
256     } else if (labelStatus == "waiting") {
257         isRightLabelDisable_ = false;
258         CreateWaitingRightButtonNode();
259     } else if (labelStatus == "skip") {
260         isRightLabelDisable_ = false;
261         CreateArrowlessRightButtonNode(index, Localization::GetInstance()->GetEntryLetters("stepper.skip"));
262     }
263 }
264 
CreateArrowRightButtonNode(int32_t index,bool isDisabled)265 void StepperPattern::CreateArrowRightButtonNode(int32_t index, bool isDisabled)
266 {
267     auto stepperTheme = GetTheme();
268     CHECK_NULL_VOID(stepperTheme);
269     auto hostNode = DynamicCast<StepperNode>(GetHost());
270     CHECK_NULL_VOID(hostNode);
271     // get rightLabel
272     auto swiperNode = hostNode->GetChildAtIndex(hostNode->GetChildIndexById(hostNode->GetSwiperId()));
273     auto stepperItemNode = DynamicCast<FrameNode>(swiperNode->GetChildAtIndex(static_cast<int32_t>(index)));
274     CHECK_NULL_VOID(stepperItemNode);
275     auto buttonNextText = Localization::GetInstance()->GetEntryLetters("stepper.next");
276     auto rightLabel =
277         stepperItemNode->GetLayoutProperty<StepperItemLayoutProperty>()->GetRightLabel().value_or(buttonNextText);
278     // Create buttonNode
279     auto buttonId = hostNode->GetRightButtonId();
280     auto buttonPattern = AceType::MakeRefPtr<NG::ButtonPattern>();
281     CHECK_NULL_VOID(buttonPattern);
282     buttonPattern->setComponentButtonType(ComponentButtonType::STEPPER);
283     buttonPattern->SetFocusBorderColor(stepperTheme->GetFocusColor());
284     auto buttonNode = FrameNode::CreateFrameNode(V2::BUTTON_ETS_TAG, buttonId, buttonPattern);
285     CHECK_NULL_VOID(buttonNode);
286     buttonNode->GetEventHub<ButtonEventHub>()->SetStateEffect(true);
287     buttonNode->GetLayoutProperty<ButtonLayoutProperty>()->UpdateType(ButtonType::NORMAL);
288     Color buttonBackgroundColor =
289         rightIsHover_ ? stepperTheme->GetMouseHoverColor() : stepperTheme->GetMouseHoverColor().ChangeOpacity(0);
290     buttonNode->GetRenderContext()->UpdateBackgroundColor(buttonBackgroundColor);
291     buttonNode->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_CONTENT);
292     auto buttonRadius = stepperTheme->GetRadius();
293     buttonNode->GetLayoutProperty<ButtonLayoutProperty>()->UpdateBorderRadius(BorderRadiusProperty(buttonRadius));
294     isRightLabelDisable_ ? buttonNode->GetEventHub<ButtonEventHub>()->SetEnabled(false)
295                          : buttonNode->GetEventHub<ButtonEventHub>()->SetEnabled(true);
296     buttonNode->MountToParent(hostNode);
297     buttonNode->MarkModifyDone();
298     InitButtonOnHoverEvent(buttonNode, false);
299     InitButtonTouchEvent(buttonNode);
300     // Create rowNode
301     auto rowNode = FrameNode::GetOrCreateFrameNode(V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
302         []() { return AceType::MakeRefPtr<LinearLayoutPattern>(false); });
303     rowNode->GetLayoutProperty<LinearLayoutProperty>()->UpdateSpace(stepperTheme->GetControlPadding());
304     rowNode->GetLayoutProperty()->UpdateMargin(
305         { CalcLength(stepperTheme->GetControlPadding()), CalcLength(stepperTheme->GetControlPadding()) });
306     rowNode->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_CONTENT);
307     rowNode->MountToParent(buttonNode);
308     rowNode->MarkModifyDone();
309     // Create textNode
310     auto textNode = FrameNode::GetOrCreateFrameNode(V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
311         []() { return AceType::MakeRefPtr<TextPattern>(); });
312     textNode->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_CONTENT);
313     textNode->GetRenderContext()->UpdateBackgroundColor(Color::TRANSPARENT);
314     textNode->GetLayoutProperty<TextLayoutProperty>()->UpdateContent(rightLabel);
315     auto textColor = stepperTheme->GetTextStyle().GetTextColor();
316     if (isDisabled) {
317         textColor = textColor.BlendOpacity(stepperTheme->GetDisabledAlpha());
318     }
319     textNode->GetLayoutProperty<TextLayoutProperty>()->UpdateTextColor(textColor);
320     textNode->GetLayoutProperty<TextLayoutProperty>()->UpdateTextOverflow(TextOverflow::ELLIPSIS);
321     textNode->GetLayoutProperty<TextLayoutProperty>()->UpdateFontSize(stepperTheme->GetTextStyle().GetFontSize());
322     textNode->GetLayoutProperty<TextLayoutProperty>()->UpdateAdaptMinFontSize(stepperTheme->GetMinFontSize());
323     textNode->GetLayoutProperty<TextLayoutProperty>()->UpdateAdaptMaxFontSize(
324         stepperTheme->GetTextStyle().GetFontSize());
325     textNode->GetLayoutProperty<TextLayoutProperty>()->UpdateFontWeight(stepperTheme->GetTextStyle().GetFontWeight());
326     textNode->GetLayoutProperty<TextLayoutProperty>()->UpdateMaxLines(stepperTheme->GetTextMaxLines());
327     textNode->GetLayoutProperty()->UpdateAlignment(Alignment::CENTER);
328     textNode->GetFocusHub()->SetFocusable(true);
329     textNode->MountToParent(rowNode);
330     textNode->MarkModifyDone();
331     // Create imageNode
332     auto imageNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
333         []() { return AceType::MakeRefPtr<ImagePattern>(); });
334     imageNode->GetLayoutProperty()->UpdateUserDefinedIdealSize(
335         CalcSize(CalcLength(stepperTheme->GetArrowWidth()), CalcLength(stepperTheme->GetArrowHeight())));
336     imageNode->GetLayoutProperty<ImageLayoutProperty>()->UpdateImageFit(ImageFit::FILL);
337     ImageSourceInfo imageSourceInfo;
338     imageSourceInfo.SetResourceId(InternalResource::ResourceId::STEPPER_NEXT_ARROW);
339     auto imageColor = stepperTheme->GetArrowColor();
340     if (isDisabled) {
341         imageColor = imageColor.BlendOpacity(stepperTheme->GetDisabledAlpha());
342     }
343     imageSourceInfo.SetFillColor(imageColor);
344     imageNode->GetLayoutProperty<ImageLayoutProperty>()->UpdateImageSourceInfo(imageSourceInfo);
345     SizeF sourceSize(static_cast<float>(stepperTheme->GetArrowWidth().ConvertToPx()),
346         static_cast<float>(stepperTheme->GetArrowHeight().ConvertToPx()));
347     imageNode->GetLayoutProperty<ImageLayoutProperty>()->UpdateSourceSize(sourceSize);
348     imageNode->MountToParent(rowNode);
349     imageNode->MarkModifyDone();
350 }
351 
CreateArrowlessRightButtonNode(int32_t index,const std::string & defaultContent)352 void StepperPattern::CreateArrowlessRightButtonNode(int32_t index, const std::string& defaultContent)
353 {
354     auto stepperTheme = GetTheme();
355     CHECK_NULL_VOID(stepperTheme);
356     auto hostNode = DynamicCast<StepperNode>(GetHost());
357     CHECK_NULL_VOID(hostNode);
358     // get rightLabel
359     auto swiperNode = hostNode->GetChildAtIndex(hostNode->GetChildIndexById(hostNode->GetSwiperId()));
360     auto stepperItemNode = DynamicCast<FrameNode>(swiperNode->GetChildAtIndex(static_cast<int32_t>(index)));
361     auto rightLabel =
362         stepperItemNode->GetLayoutProperty<StepperItemLayoutProperty>()->GetRightLabel().value_or(defaultContent);
363     // Create buttonNode
364     auto buttonId = hostNode->GetRightButtonId();
365     auto buttonPattern = AceType::MakeRefPtr<NG::ButtonPattern>();
366     CHECK_NULL_VOID(buttonPattern);
367     buttonPattern->setComponentButtonType(ComponentButtonType::STEPPER);
368     buttonPattern->SetFocusBorderColor(stepperTheme->GetFocusColor());
369     auto buttonNode = FrameNode::CreateFrameNode(V2::BUTTON_ETS_TAG, buttonId, buttonPattern);
370     CHECK_NULL_VOID(buttonNode);
371     buttonNode->GetEventHub<ButtonEventHub>()->SetStateEffect(true);
372     Color buttonBackgroundColor =
373         rightIsHover_ ? stepperTheme->GetMouseHoverColor() : stepperTheme->GetMouseHoverColor().ChangeOpacity(0);
374     buttonNode->GetLayoutProperty<ButtonLayoutProperty>()->UpdateType(ButtonType::NORMAL);
375     buttonNode->GetRenderContext()->UpdateBackgroundColor(buttonBackgroundColor);
376     buttonNode->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_CONTENT);
377     auto buttonRadius = stepperTheme->GetRadius();
378     buttonNode->GetLayoutProperty<ButtonLayoutProperty>()->UpdateBorderRadius(BorderRadiusProperty(buttonRadius));
379     buttonNode->MountToParent(hostNode);
380     buttonNode->MarkModifyDone();
381     InitButtonOnHoverEvent(buttonNode, false);
382     InitButtonTouchEvent(buttonNode);
383     // Create textNode
384     auto textNode = FrameNode::GetOrCreateFrameNode(V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
385         []() { return AceType::MakeRefPtr<TextPattern>(); });
386     textNode->GetRenderContext()->UpdateBackgroundColor(Color::TRANSPARENT);
387     textNode->GetLayoutProperty<TextLayoutProperty>()->UpdateContent(rightLabel);
388     textNode->GetLayoutProperty<TextLayoutProperty>()->UpdateFontSize(stepperTheme->GetTextStyle().GetFontSize());
389     textNode->GetLayoutProperty<TextLayoutProperty>()->UpdateFontWeight(stepperTheme->GetTextStyle().GetFontWeight());
390     auto textColor = stepperTheme->GetTextStyle().GetTextColor();
391     textNode->GetLayoutProperty<TextLayoutProperty>()->UpdateTextColor(textColor);
392     textNode->GetLayoutProperty<TextLayoutProperty>()->UpdateTextOverflow(TextOverflow::ELLIPSIS);
393     textNode->GetLayoutProperty()->UpdateAlignment(Alignment::CENTER);
394     textNode->GetLayoutProperty()->UpdateMargin(
395         { CalcLength(stepperTheme->GetControlPadding()), CalcLength(stepperTheme->GetControlPadding()) });
396     textNode->GetFocusHub()->SetFocusable(true);
397     textNode->MountToParent(buttonNode);
398     textNode->MarkModifyDone();
399 }
400 
CreateWaitingRightButtonNode()401 void StepperPattern::CreateWaitingRightButtonNode()
402 {
403     auto stepperTheme = GetTheme();
404     CHECK_NULL_VOID(stepperTheme);
405     auto hostNode = DynamicCast<StepperNode>(GetHost());
406     CHECK_NULL_VOID(hostNode);
407     // Create loadingProgressNode
408     auto buttonId = hostNode->GetRightButtonId();
409     auto loadingProgressNode = FrameNode::GetOrCreateFrameNode(
410         V2::LOADING_PROGRESS_ETS_TAG, buttonId, []() { return AceType::MakeRefPtr<LoadingProgressPattern>(); });
411     loadingProgressNode->GetLayoutProperty()->UpdateUserDefinedIdealSize(
412         CalcSize(CalcLength(stepperTheme->GetProgressDiameter()), CalcLength(stepperTheme->GetProgressDiameter())));
413     loadingProgressNode->GetPaintProperty<LoadingProgressPaintProperty>()->UpdateColor(
414         stepperTheme->GetProgressColor());
415     loadingProgressNode->GetRenderContext()->UpdateForegroundColor(stepperTheme->GetProgressColor());
416     loadingProgressNode->MountToParent(hostNode);
417     loadingProgressNode->MarkModifyDone();
418 }
419 
UpdateRightButtonNode(int32_t index)420 void StepperPattern::UpdateRightButtonNode(int32_t index)
421 {
422     auto hostNode = DynamicCast<StepperNode>(GetHost());
423     CHECK_NULL_VOID(hostNode);
424     hostNode->RemoveRightButtonNode();
425     CreateRightButtonNode(index);
426 }
427 
InitButtonOnHoverEvent(RefPtr<FrameNode> buttonNode,bool isLeft)428 void StepperPattern::InitButtonOnHoverEvent(RefPtr<FrameNode> buttonNode, bool isLeft)
429 {
430     CHECK_NULL_VOID(buttonNode);
431     auto buttonInputHub = buttonNode->GetOrCreateInputEventHub();
432     CHECK_NULL_VOID(buttonInputHub);
433     auto hoverCallback = [weak = WeakClaim(this), buttonNodeWeak = WeakPtr<FrameNode>(buttonNode), isLeft](
434                              bool isHovered) {
435         auto pattern = weak.Upgrade();
436         CHECK_NULL_VOID(pattern);
437         auto buttonNode = buttonNodeWeak.Upgrade();
438         CHECK_NULL_VOID(buttonNode);
439         pattern->ButtonOnHover(buttonNode, isHovered, isLeft);
440     };
441     buttonOnHoverListenr_ = MakeRefPtr<InputEvent>(std::move(hoverCallback));
442     buttonInputHub->AddOnHoverEvent(buttonOnHoverListenr_);
443 }
444 
ButtonOnHover(RefPtr<FrameNode> buttonNode,bool isHover,bool isLeft)445 void StepperPattern::ButtonOnHover(RefPtr<FrameNode> buttonNode, bool isHover, bool isLeft)
446 {
447     if (isLeft) {
448         if (leftIsHover_ == isHover) {
449             return;
450         }
451         leftIsHover_ = isHover;
452     } else {
453         if (rightIsHover_ == isHover) {
454             return;
455         }
456         rightIsHover_ = isHover;
457     }
458     if (isHover) {
459         ButtonHoverInAnimation(buttonNode);
460     } else {
461         ButtonHoverOutAnimation(buttonNode);
462     }
463 }
464 
ButtonHoverInAnimation(RefPtr<FrameNode> buttonNode)465 void StepperPattern::ButtonHoverInAnimation(RefPtr<FrameNode> buttonNode)
466 {
467     auto renderContext = buttonNode->GetRenderContext();
468     CHECK_NULL_VOID(renderContext);
469     AnimationOption option;
470     option.SetDuration(HOVER_ANIMATION_DURATION);
471     option.SetCurve(AceType::MakeRefPtr<CubicCurve>(BUTTON_ON_HOVER_BEZIER_CURVE_X0, BUTTON_ON_HOVER_BEZIER_CURVE_Y0,
472         BUTTON_ON_HOVER_BEZIER_CURVE_X1, BUTTON_ON_HOVER_BEZIER_CURVE_Y1));
473     auto stepperTheme = GetTheme();
474     CHECK_NULL_VOID(stepperTheme);
475     Color buttonBackgroundColor = stepperTheme->GetMouseHoverColor();
476     AnimationUtils::Animate(option,
477         [renderContext, buttonBackgroundColor]() { renderContext->UpdateBackgroundColor(buttonBackgroundColor); });
478 }
ButtonHoverOutAnimation(RefPtr<FrameNode> buttonNode)479 void StepperPattern::ButtonHoverOutAnimation(RefPtr<FrameNode> buttonNode)
480 {
481     auto renderContext = buttonNode->GetRenderContext();
482     CHECK_NULL_VOID(renderContext);
483     AnimationOption option;
484     option.SetDuration(HOVER_ANIMATION_DURATION);
485     option.SetCurve(AceType::MakeRefPtr<CubicCurve>(BUTTON_ON_HOVER_BEZIER_CURVE_X0, BUTTON_ON_HOVER_BEZIER_CURVE_Y0,
486         BUTTON_ON_HOVER_BEZIER_CURVE_X1, BUTTON_ON_HOVER_BEZIER_CURVE_Y1));
487     auto stepperTheme = GetTheme();
488     CHECK_NULL_VOID(stepperTheme);
489     Color buttonBackgroundColor = stepperTheme->GetMouseHoverColor().ChangeOpacity(0);
490     AnimationUtils::Animate(option,
491         [renderContext, buttonBackgroundColor]() { renderContext->UpdateBackgroundColor(buttonBackgroundColor); });
492 }
493 
InitButtonTouchEvent(RefPtr<FrameNode> buttonNode)494 void StepperPattern::InitButtonTouchEvent(RefPtr<FrameNode> buttonNode)
495 {
496     CHECK_NULL_VOID(buttonNode);
497     auto buttonEventHub = buttonNode->GetEventHub<ButtonEventHub>();
498     CHECK_NULL_VOID(buttonEventHub);
499     buttonEventHub->SetStateEffect(false);
500     auto buttonGestureHub = buttonNode->GetOrCreateGestureEventHub();
501     CHECK_NULL_VOID(buttonGestureHub);
502     auto touchCallback = [weak = WeakClaim(this), buttonNodeWeak = WeakPtr<FrameNode>(buttonNode)](
503                              const TouchEventInfo& info) {
504         auto pattern = weak.Upgrade();
505         CHECK_NULL_VOID(pattern);
506         auto buttonNode = buttonNodeWeak.Upgrade();
507         CHECK_NULL_VOID(buttonNode);
508         pattern->ButtonOnTouch(buttonNode, info.GetTouches().front().GetTouchType());
509     };
510     buttonTouchListenr_ = MakeRefPtr<TouchEventImpl>(std::move(touchCallback));
511     buttonGestureHub->AddTouchEvent(buttonTouchListenr_);
512 }
513 
ButtonOnTouch(RefPtr<FrameNode> buttonNode,TouchType touchType)514 void StepperPattern::ButtonOnTouch(RefPtr<FrameNode> buttonNode, TouchType touchType)
515 {
516     if (touchType == TouchType::DOWN) {
517         ButtonTouchDownAnimation(buttonNode);
518     }
519     if (touchType == TouchType::UP || touchType == TouchType::CANCEL) {
520         ButtonTouchUpAnimation(buttonNode);
521     }
522 }
523 
ButtonTouchDownAnimation(RefPtr<FrameNode> buttonNode)524 void StepperPattern::ButtonTouchDownAnimation(RefPtr<FrameNode> buttonNode)
525 {
526     auto renderContext = buttonNode->GetRenderContext();
527     CHECK_NULL_VOID(renderContext);
528     AnimationOption option;
529     option.SetDuration(PRESS_ANIMATION_DURATION);
530     option.SetCurve(AceType::MakeRefPtr<CubicCurve>(BUTTON_ON_PRESS_BEZIER_CURVE_X0, BUTTON_ON_PRESS_BEZIER_CURVE_Y0,
531         BUTTON_ON_PRESS_BEZIER_CURVE_X1, BUTTON_ON_PRESS_BEZIER_CURVE_Y1));
532     auto stepperTheme = GetTheme();
533     CHECK_NULL_VOID(stepperTheme);
534     Color buttonBackgroundColor = stepperTheme->GetButtonPressedColor();
535     AnimationUtils::Animate(option,
536         [renderContext, buttonBackgroundColor]() { renderContext->UpdateBackgroundColor(buttonBackgroundColor); });
537 }
538 
ButtonTouchUpAnimation(RefPtr<FrameNode> buttonNode)539 void StepperPattern::ButtonTouchUpAnimation(RefPtr<FrameNode> buttonNode)
540 {
541     auto renderContext = buttonNode->GetRenderContext();
542     CHECK_NULL_VOID(renderContext);
543     AnimationOption option;
544     option.SetDuration(PRESS_ANIMATION_DURATION);
545     option.SetCurve(AceType::MakeRefPtr<CubicCurve>(BUTTON_ON_PRESS_BEZIER_CURVE_X0, BUTTON_ON_PRESS_BEZIER_CURVE_Y0,
546         BUTTON_ON_PRESS_BEZIER_CURVE_X1, BUTTON_ON_PRESS_BEZIER_CURVE_Y1));
547     auto stepperTheme = GetTheme();
548     CHECK_NULL_VOID(stepperTheme);
549     Color buttonBackgroundColor =
550         rightIsHover_ ? stepperTheme->GetMouseHoverColor() : stepperTheme->GetMouseHoverColor().ChangeOpacity(0);
551     AnimationUtils::Animate(option,
552         [renderContext, buttonBackgroundColor]() { renderContext->UpdateBackgroundColor(buttonBackgroundColor); });
553 }
554 
InitButtonClickEvent()555 void StepperPattern::InitButtonClickEvent()
556 {
557     auto hostNode = DynamicCast<StepperNode>(GetHost());
558     CHECK_NULL_VOID(hostNode);
559 
560     if (hostNode->HasLeftButtonNode()) {
561         auto leftButtonNode =
562             DynamicCast<FrameNode>(hostNode->GetChildAtIndex(hostNode->GetChildIndexById(hostNode->GetLeftButtonId())));
563         CHECK_NULL_VOID(leftButtonNode);
564         auto leftGestureHub = leftButtonNode->GetOrCreateGestureEventHub();
565         CHECK_NULL_VOID(leftGestureHub);
566         if (leftGestureHub->IsClickEventsEmpty()) {
567             auto leftClickEvent = [weak = WeakClaim(this)](const GestureEvent& info) {
568                 auto stepperPattern = weak.Upgrade();
569                 CHECK_NULL_VOID_NOLOG(stepperPattern);
570                 stepperPattern->HandlingLeftButtonClickEvent();
571             };
572             leftGestureHub->AddClickEvent(MakeRefPtr<ClickEvent>(std::move(leftClickEvent)));
573         }
574     }
575 
576     auto rightButtonNode =
577         DynamicCast<FrameNode>(hostNode->GetChildAtIndex(hostNode->GetChildIndexById(hostNode->GetRightButtonId())));
578     CHECK_NULL_VOID(rightButtonNode);
579     auto rightGestureHub = rightButtonNode->GetOrCreateGestureEventHub();
580     CHECK_NULL_VOID(rightGestureHub);
581     if (rightGestureHub->IsClickEventsEmpty()) {
582         auto rightClickEvent = [weak = WeakClaim(this)](const GestureEvent& info) {
583             auto stepperPattern = weak.Upgrade();
584             CHECK_NULL_VOID_NOLOG(stepperPattern);
585             stepperPattern->HandlingRightButtonClickEvent();
586         };
587         rightGestureHub->AddClickEvent(MakeRefPtr<ClickEvent>(std::move(rightClickEvent)));
588     }
589 }
590 
HandlingLeftButtonClickEvent()591 void StepperPattern::HandlingLeftButtonClickEvent()
592 {
593     auto hostNode = DynamicCast<StepperNode>(GetHost());
594     CHECK_NULL_VOID(hostNode);
595     auto stepperHub = hostNode->GetEventHub<StepperEventHub>();
596     CHECK_NULL_VOID(stepperHub);
597     auto swiperNode =
598         DynamicCast<FrameNode>(hostNode->GetChildAtIndex(hostNode->GetChildIndexById(hostNode->GetSwiperId())));
599     auto swiperAnimationController = swiperNode->GetPattern<SwiperPattern>()->GetController();
600     if (swiperAnimationController && !swiperAnimationController->IsStopped()) {
601         return;
602     }
603     auto swiperController = swiperNode->GetPattern<SwiperPattern>()->GetSwiperController();
604     stepperHub->FireChangeEvent(index_, std::clamp<int32_t>(index_ - 1, 0, maxIndex_));
605     stepperHub->FirePreviousEvent(index_, std::clamp<int32_t>(index_ - 1, 0, maxIndex_));
606     swiperController->SwipeTo(std::clamp<int32_t>(index_ - 1, 0, maxIndex_));
607 }
608 
HandlingRightButtonClickEvent()609 void StepperPattern::HandlingRightButtonClickEvent()
610 {
611     auto hostNode = DynamicCast<StepperNode>(GetHost());
612     CHECK_NULL_VOID(hostNode);
613     auto stepperHub = hostNode->GetEventHub<StepperEventHub>();
614     CHECK_NULL_VOID(stepperHub);
615     auto swiperNode =
616         DynamicCast<FrameNode>(hostNode->GetChildAtIndex(hostNode->GetChildIndexById(hostNode->GetSwiperId())));
617     auto swiperAnimationController = swiperNode->GetPattern<SwiperPattern>()->GetController();
618     if (swiperAnimationController && !swiperAnimationController->IsStopped()) {
619         return;
620     }
621     auto stepperItemNode = DynamicCast<FrameNode>(swiperNode->GetChildAtIndex(static_cast<int32_t>(index_)));
622     CHECK_NULL_VOID(stepperItemNode);
623     auto labelStatus =
624         stepperItemNode->GetLayoutProperty<StepperItemLayoutProperty>()->GetLabelStatus().value_or("normal");
625     if (labelStatus == "skip") {
626         stepperHub->FireSkipEvent();
627     } else if (labelStatus == "normal") {
628         if (index_ == maxIndex_) {
629             stepperHub->FireFinishEvent();
630         } else {
631             stepperHub->FireChangeEvent(index_, std::clamp<int32_t>(index_ + 1, 0, maxIndex_));
632             stepperHub->FireNextEvent(index_, std::clamp<int32_t>(index_ + 1, 0, maxIndex_));
633             auto swiperController = swiperNode->GetPattern<SwiperPattern>()->GetSwiperController();
634             swiperController->SwipeTo(std::clamp<int32_t>(index_ + 1, 0, maxIndex_));
635         }
636     }
637 }
638 
TotalCount() const639 int32_t StepperPattern::TotalCount() const
640 {
641     auto hostNode = DynamicCast<StepperNode>(GetHost());
642     CHECK_NULL_RETURN(hostNode, 0);
643     auto swiperNode =
644         DynamicCast<FrameNode>(hostNode->GetChildAtIndex(hostNode->GetChildIndexById(hostNode->GetSwiperId())));
645     CHECK_NULL_RETURN(swiperNode, 0);
646     return swiperNode->TotalChildCount() - 1;
647 }
648 
SetAccessibilityAction()649 void StepperPattern::SetAccessibilityAction()
650 {
651     auto host = GetHost();
652     CHECK_NULL_VOID(host);
653     auto accessibilityProperty = host->GetAccessibilityProperty<AccessibilityProperty>();
654     CHECK_NULL_VOID(accessibilityProperty);
655     accessibilityProperty->SetActionScrollForward([weakPtr = WeakClaim(this)]() {
656         const auto& pattern = weakPtr.Upgrade();
657         CHECK_NULL_VOID(pattern);
658         pattern->HandlingRightButtonClickEvent();
659     });
660 
661     accessibilityProperty->SetActionScrollBackward([weakPtr = WeakClaim(this)]() {
662         const auto& pattern = weakPtr.Upgrade();
663         CHECK_NULL_VOID(pattern);
664         pattern->HandlingLeftButtonClickEvent();
665     });
666 }
667 
GetFocusNode(FocusStep step,const WeakPtr<FocusHub> & currentFocusNode)668 WeakPtr<FocusHub> StepperPattern::GetFocusNode(FocusStep step, const WeakPtr<FocusHub>& currentFocusNode)
669 {
670     auto curFocusNode = currentFocusNode.Upgrade();
671     CHECK_NULL_RETURN(curFocusNode, nullptr);
672     auto hostNode = DynamicCast<StepperNode>(GetHost());
673     CHECK_NULL_RETURN(hostNode, nullptr);
674 
675     auto swiperNode = hostNode->GetChildAtIndex(hostNode->GetChildIndexById(hostNode->GetSwiperId()));
676     CHECK_NULL_RETURN(swiperNode, nullptr);
677     auto stepperItemNode = DynamicCast<FrameNode>(swiperNode->GetChildAtIndex(static_cast<int32_t>(index_)));
678     CHECK_NULL_RETURN(stepperItemNode, nullptr);
679     auto buttonFocusHub = stepperItemNode->GetOrCreateFocusHub();
680     CHECK_NULL_RETURN(buttonFocusHub, nullptr);
681 
682     auto stepperItemLayoutProperty = stepperItemNode->GetLayoutProperty<StepperItemLayoutProperty>();
683     CHECK_NULL_RETURN(stepperItemLayoutProperty, nullptr);
684     auto labelStatus = stepperItemLayoutProperty->GetLabelStatus().value_or("normal");
685 
686     if (hostNode->HasLeftButtonNode()) {
687         auto leftButtonNode =
688             DynamicCast<FrameNode>(hostNode->GetChildAtIndex(hostNode->GetChildIndexById(hostNode->GetLeftButtonId())));
689         CHECK_NULL_RETURN(leftButtonNode, nullptr);
690         leftFocusHub_ = leftButtonNode->GetOrCreateFocusHub();
691     }
692 
693     auto rightButtonNode =
694         DynamicCast<FrameNode>(hostNode->GetChildAtIndex(hostNode->GetChildIndexById(hostNode->GetRightButtonId())));
695     CHECK_NULL_RETURN(rightButtonNode, nullptr);
696     auto rightFocusHub = rightButtonNode->GetOrCreateFocusHub();
697     CHECK_NULL_RETURN(rightFocusHub, nullptr);
698 
699     if (labelStatus == "normal" || labelStatus == "skip") {
700         if (step == FocusStep::UP || step == FocusStep::LEFT || step == FocusStep::SHIFT_TAB) {
701             return curFocusNode == leftFocusHub_ ? buttonFocusHub : leftFocusHub_;
702         }
703 
704         if (curFocusNode != leftFocusHub_ && curFocusNode != rightFocusHub) {
705             return hostNode->HasLeftButtonNode() ? leftFocusHub_ : rightFocusHub;
706         }
707 
708         if (curFocusNode == rightFocusHub && !hostNode->HasLeftButtonNode()) {
709             return buttonFocusHub;
710         }
711 
712         if (step == FocusStep::DOWN || step == FocusStep::RIGHT || step == FocusStep::TAB) {
713             return curFocusNode == buttonFocusHub ? leftFocusHub_ : rightFocusHub;
714         }
715     } else if (labelStatus == "disabled" || labelStatus == "waiting") {
716         return curFocusNode == leftFocusHub_ ? buttonFocusHub : leftFocusHub_;
717     }
718     return nullptr;
719 }
720 
OnColorConfigurationUpdate()721 void StepperPattern::OnColorConfigurationUpdate()
722 {
723     auto host = GetHost();
724     CHECK_NULL_VOID(host);
725     auto hostNode = DynamicCast<StepperNode>(GetHost());
726     CHECK_NULL_VOID(hostNode);
727     auto stepperTheme = GetTheme();
728     CHECK_NULL_VOID(stepperTheme);
729     auto textColor = stepperTheme->GetTextStyle().GetTextColor();
730     auto leftButtonNode = hostNode->GetChildAtIndex(hostNode->GetChildIndexById(hostNode->GetLeftButtonId()));
731     if (leftButtonNode) {
732         auto leftButtonFrameNode = DynamicCast<FrameNode>(leftButtonNode);
733         CHECK_NULL_VOID(leftButtonFrameNode);
734         ButtonSkipColorConfigurationUpdate(leftButtonFrameNode);
735         auto renderContext = leftButtonFrameNode->GetRenderContext();
736         CHECK_NULL_VOID(renderContext);
737         renderContext->UpdateBackgroundColor(stepperTheme->GetMouseHoverColor().ChangeOpacity(0));
738         auto rowNode = leftButtonFrameNode->GetChildAtIndex(0);
739         CHECK_NULL_VOID(rowNode);
740         auto textFrameNode = DynamicCast<FrameNode>(rowNode->GetChildAtIndex(1));
741         CHECK_NULL_VOID(textFrameNode);
742         auto layoutProperty = textFrameNode->GetLayoutProperty<TextLayoutProperty>();
743         CHECK_NULL_VOID(layoutProperty);
744         layoutProperty->UpdateTextColor(textColor);
745     }
746     auto rightButtonNode = hostNode->GetChildAtIndex(hostNode->GetChildIndexById(hostNode->GetRightButtonId()));
747     if (rightButtonNode) {
748         auto rightButtonFrameNode = DynamicCast<FrameNode>(rightButtonNode);
749         CHECK_NULL_VOID(rightButtonFrameNode);
750         ButtonSkipColorConfigurationUpdate(rightButtonFrameNode);
751         auto renderContext = rightButtonFrameNode->GetRenderContext();
752         CHECK_NULL_VOID(renderContext);
753         renderContext->UpdateBackgroundColor(stepperTheme->GetMouseHoverColor().ChangeOpacity(0));
754         auto firstChild = rightButtonFrameNode->GetFirstChild();
755         CHECK_NULL_VOID(firstChild);
756         if (firstChild->GetTag() == V2::ROW_ETS_TAG) {
757             auto textFrameNode = DynamicCast<FrameNode>(firstChild->GetChildAtIndex(0));
758             CHECK_NULL_VOID(textFrameNode);
759             auto layoutProperty = textFrameNode->GetLayoutProperty<TextLayoutProperty>();
760             CHECK_NULL_VOID(layoutProperty);
761             layoutProperty->UpdateTextColor(textColor);
762         }
763         if (firstChild->GetTag() == V2::TEXT_ETS_TAG) {
764             auto textFrameNode = DynamicCast<FrameNode>(firstChild);
765             CHECK_NULL_VOID(textFrameNode);
766             auto layoutProperty = textFrameNode->GetLayoutProperty<TextLayoutProperty>();
767             CHECK_NULL_VOID(layoutProperty);
768             layoutProperty->UpdateTextColor(textColor);
769         }
770     }
771 }
772 
ButtonSkipColorConfigurationUpdate(RefPtr<FrameNode> buttonNode)773 void StepperPattern::ButtonSkipColorConfigurationUpdate(RefPtr<FrameNode> buttonNode)
774 {
775     auto pattern = buttonNode->GetPattern<ButtonPattern>();
776     CHECK_NULL_VOID(pattern);
777     pattern->SetSkipColorConfigurationUpdate();
778 }
779 } // namespace OHOS::Ace::NG
780