1  /*
2   * Copyright (c) 2021-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  #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_STEPPER_RENDER_STEPPER_H
17  #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_STEPPER_RENDER_STEPPER_H
18  
19  #include <functional>
20  #include <map>
21  #include <vector>
22  
23  #include "base/memory/ace_type.h"
24  #include "core/animation/animation.h"
25  #include "core/animation/animator.h"
26  #include "core/animation/keyframe_animation.h"
27  #include "core/components/box/box_component.h"
28  #include "core/components/box/render_box.h"
29  #include "core/components/display/render_display.h"
30  #include "core/components/flex/flex_component.h"
31  #include "core/components/flex/render_flex.h"
32  #include "core/components/image/image_component.h"
33  #include "core/components/image/render_image.h"
34  #include "core/components/progress/render_loading_progress.h"
35  #include "core/components/stepper/stepper_animation_controller.h"
36  #include "core/components/stepper/stepper_component.h"
37  #include "core/components/text/render_text.h"
38  #include "core/components/text/text_component.h"
39  #include "core/gestures/click_recognizer.h"
40  #include "core/gestures/raw_recognizer.h"
41  #include "core/pipeline/base/render_node.h"
42  
43  namespace OHOS::Ace {
44  
45  enum class StepperButtonType {
46      TEXT_ARROW,
47      TEXT,
48      NONE,
49  };
50  
51  enum class StepperButtonStatus {
52      NORMAL,
53      DISABLED,
54      WAITING,
55      SKIP,
56  };
57  
58  struct ControlPanelData {
59      bool isLeft = true;
60      bool isClicked = false;
61      bool isHovered = false;
62      std::string text;
63      RefPtr<RenderDisplay> displayRender;
64      RefPtr<RenderFlex> flexRender;
65      RefPtr<RenderBox> hotBoxRender;
66      RefPtr<RenderBox> imageBoxRender;
67      RefPtr<RenderBox> textBoxRender;
68      RefPtr<RenderText> textRender;
69      RefPtr<TextComponent> textComponent;
70      RefPtr<ImageComponent> imageComponentLeft;
71      RefPtr<ImageComponent> imageComponentRight;
72      RefPtr<RenderImage> imageRenderLeft;
73      RefPtr<RenderImage> imageRenderRight;
74      RefPtr<DisplayComponent> displayComponent;
75      RefPtr<BoxComponent> hotBoxComponent;
76      StepperButtonType buttonType = StepperButtonType::NONE;
77      StepperButtonStatus buttonStatus = StepperButtonStatus::NORMAL;
78  };
79  
80  using StepperChangeEndListener = std::function<void(const int32_t)>;
81  using OnEventFunc = std::function<void(const std::string&)>;
82  using OnReturnEventFunc = std::function<void(const std::string&, std::string&)>;
83  
84  class RenderStepper : public RenderNode {
85      DECLARE_ACE_TYPE(RenderStepper, RenderNode)
86  
87  public:
88      static RefPtr<RenderNode> Create();
89      void Update(const RefPtr<Component>& component) override;
90      void PerformLayout() override;
GetCurrentIndex()91      int32_t GetCurrentIndex() const
92      {
93          return currentIndex_;
94      }
95      void RegisterChangeEndListener(int32_t listenerId, const StepperChangeEndListener& listener);
96      void UnRegisterChangeEndListener(int32_t listenerId);
97      void OnStatusChanged(RenderStatus renderStatus) override;
98      void UpdateButtonFocus(bool focus, bool isLeft);
99      void HandleButtonClick(bool isLeft);
100  
101      // for animation
102      void UpdateItemOpacity(uint8_t opacity, int32_t index);
103      void UpdateItemPosition(double offset, int32_t index);
GetFromIndex()104      int32_t GetFromIndex() const
105      {
106          return outItemIndex_;
107      }
GetToIndex()108      int32_t GetToIndex() const
109      {
110          return currentIndex_;
111      }
GetStepperWidth()112      double GetStepperWidth() const
113      {
114          return stepperWidth_;
115      }
116  
GetStepperComponent()117      RefPtr<StepperComponent> GetStepperComponent() const
118      {
119          return stepperComponent_;
120      }
121  
122  protected:
123      void OnTouchTestHit(
124          const Offset& coordinateOffset, const TouchRestrict& touchRestrict, TouchTestResult& result) override;
125      bool MouseHoverTest(const Point& parentLocalPoint) override;
126      void HandleClick(const ClickInfo& clickInfo);
127      void HandleTouchDown(const TouchEventInfo& info);
128      void HandleTouchUp(const TouchEventInfo& info);
129      void HandleTouchMove(const TouchEventInfo& info);
130  
131      RefPtr<StepperAnimationController> stepperAnimationController_;
132      double stepperWidth_ = 0.0;
133      bool leftOldHover_ = false;
134      bool rightOldHover_ = false;
135      RefPtr<StepperComponent> stepperComponent_;
136      std::vector<RefPtr<RenderNode>> childrenArray_;
137      int32_t totalItemCount_ = 0;
138      int32_t currentIndex_ = -1;
139      int32_t outItemIndex_ = 0;
140      bool needReverse_ = false;
141      bool onFocus_ = false;
142      std::vector<StepperLabels> stepperLabels_;
143      std::vector<TextStyle> textStyles_;
144      std::vector<Color> textColors_;
145      RefPtr<RenderLoadingProgress> renderProgress_;
146      Rect leftHotRect_;
147      Rect rightHotRect_;
148      ControlPanelData leftButtonData_;
149      ControlPanelData rightButtonData_;
150      int32_t fingerId_ = -1;
151  
152  private:
153      void Initialize();
154      void InitAttr();
155      void InitRecognizer();
156      void InitProgress(RefPtr<RenderLoadingProgress>& renderProgress);
157      void InitButton(ControlPanelData& buttonData);
158      void InitHotArea(ControlPanelData& buttonData);
159      void UpdateButton(ControlPanelData& buttonData);
160      void UpdateButtonStatus();
161      void UpdateRightButtonStatus(const std::string& status, const std::string& label);
162      void LoadDefaultButtonStatus(ControlPanelData& buttonDataPrev, ControlPanelData& buttonDataNext);
163      void LayoutButton(ControlPanelData& buttonData);
164      void LayoutProgress();
165      void SetRightButtonStatus(const std::string& status, const std::string& label);
166      void HandleRightButtonClick();
167      void HandleLeftButtonClick();
168      void FireFinishEvent() const;
169      void FireSkipEvent() const;
170      void FireChangedEvent(int32_t oldIndex, int32_t newIndex) const;
171      void FireNextEvent(int32_t currentIndex, int32_t& pendingIndex);
172      void FireBackEvent(int32_t currentIndex, int32_t& pendingIndex);
173      void FireItemEvent(int32_t index, bool isAppear) const;
174      int32_t GetPrevIndex() const;
175      int32_t GetNextIndex() const;
176      void StepperPrev();
177      void StepperNext();
178      void StepperTo(int32_t index, bool reverse);
179      void InitStepperToAnimation(int32_t fromIndex, int32_t toIndex, bool reverse);
180      void AddStepperToTranslateListener(int32_t fromIndex, int32_t toIndex);
181      void AddStepperToOpacityListener(int32_t fromIndex, int32_t toIndex);
182      void AddStepperToStopListener(int32_t fromIndex, int32_t toIndex);
183      void DoStepperToAnimation(int32_t fromIndex, int32_t toIndex, bool reverse);
184      void InitAccessibilityEventListener();
185      void InitChildrenArr();
GetMainAxisOffset(double offset)186      Offset GetMainAxisOffset(double offset) const
187      {
188          return Offset(offset, 0);
189      }
190  
191      bool isAnimation_ = false;
192      double prevItemOffset_ = 0.0;
193      double nextItemOffset_ = 0.0;
194      std::map<int32_t, std::function<void(const int32_t&)>> changeEndListeners_;
195      OnEventFunc finishEvent_;
196      OnEventFunc skipEvent_;
197      OnEventFunc changeEvent_;
198      OnReturnEventFunc nextEvent_;
199      OnReturnEventFunc backEvent_;
200      RefPtr<RawRecognizer> touchRecognizer_;
201      RefPtr<ClickRecognizer> clickRecognizer_;
202  
203      std::function<void()> onFinish_;
204      std::function<void()> onSkip_;
205      std::function<void(int32_t, int32_t)> onChange_;
206      std::function<void(int32_t, int32_t)> onNext_;
207      std::function<void(int32_t, int32_t)> onPrevious_;
208      // theme style
209      double defaultPaddingStart_ = 0.0;
210      double defaultPaddingEnd_ = 0.0;
211      Color progressColor_;
212      Dimension progressDiameter_;
213      double arrowWidth_ = 0.0;
214      double arrowHeight_ = 0.0;
215      Color arrowColor_;
216      Color disabledColor_;
217      double rrectRadius_ = 0.0;
218      Color buttonPressedColor_;
219      double buttonPressedHeight_ = 0.0;
220      double controlPanelHeight_ = 0.0;
221      double controlMargin_ = 0.0;
222      double controlPadding_ = 0.0;
223      Color focusColor_;
224      double focusBorderWidth_ = 0.0;
225      Color mouseHoverColor_;
226      double disabledAlpha_ = 0.4;
227  };
228  
229  } // namespace OHOS::Ace
230  
231  #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_STEPPER_RENDER_STEPPER_H
232