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