1 /*
2  * Copyright (c) 2022-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 
16 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_INDEXER_INDEXER_PATTERN_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_INDEXER_INDEXER_PATTERN_H
18 
19 #include <optional>
20 #include <stdint.h>
21 
22 #include "base/memory/referenced.h"
23 #include "core/animation/animator.h"
24 #include "core/components/indexer/indexer_theme.h"
25 #include "core/components_ng/event/event_hub.h"
26 #include "core/components_ng/event/gesture_event_hub.h"
27 #include "core/components_ng/pattern/indexer/indexer_accessibility_property.h"
28 #include "core/components_ng/pattern/indexer/indexer_event_hub.h"
29 #include "core/components_ng/pattern/indexer/indexer_layout_algorithm.h"
30 #include "core/components_ng/pattern/indexer/indexer_layout_property.h"
31 #include "core/components_ng/pattern/indexer/indexer_paint_property.h"
32 #include "core/components_ng/pattern/pattern.h"
33 
34 namespace OHOS::Ace::NG {
35 enum class IndexerCollapsingMode {
36     INVALID,
37     NONE, // all array should be displayed
38     FIVE, // 5 + 1 collapsing mode
39     SEVEN // 7 + 1 collapsing mode
40 };
41 
42 enum class PopupListGradientStatus {
43     NONE,
44     TOP,
45     BOTTOM,
46     BOTH
47 };
48 
49 class IndexerPattern : public Pattern {
50     DECLARE_ACE_TYPE(IndexerPattern, Pattern);
51 
52 public:
53     IndexerPattern() = default;
54     ~IndexerPattern() override = default;
55 
CreateEventHub()56     RefPtr<EventHub> CreateEventHub() override
57     {
58         return MakeRefPtr<IndexerEventHub>();
59     }
60 
CreateLayoutProperty()61     RefPtr<LayoutProperty> CreateLayoutProperty() override
62     {
63         return MakeRefPtr<IndexerLayoutProperty>();
64     }
65 
CreatePaintProperty()66     RefPtr<PaintProperty> CreatePaintProperty() override
67     {
68         return MakeRefPtr<IndexerPaintProperty>();
69     }
70 
CreateLayoutAlgorithm()71     RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override
72     {
73         auto indexerLayoutAlgorithm = MakeRefPtr<IndexerLayoutAlgorithm>(static_cast<int32_t>(fullArrayValue_.size()));
74         return indexerLayoutAlgorithm;
75     }
76 
CreateAccessibilityProperty()77     RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override
78     {
79         return MakeRefPtr<IndexerAccessibilityProperty>();
80     }
81 
SetIsTouch(bool isTouch)82     void SetIsTouch(bool isTouch)
83     {
84         isTouch_ = isTouch;
85     }
86 
GetFocusPattern()87     FocusPattern GetFocusPattern() const override
88     {
89         return { FocusType::NODE, true };
90     }
91 
GetSelected()92     int32_t GetSelected() const
93     {
94         return selected_;
95     }
96 
97     bool IsMeasureBoundary() const override;
98     void UpdateChildBoundary(RefPtr<FrameNode>& frameNode);
99 
100 private:
101     void OnModifyDone() override;
102     void InitArrayValue(bool& autoCollapseModeChanged, bool& itemCountChanged);
103     void InitTouchEvent(const RefPtr<GestureEventHub>& gestureHub);
104     bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override;
105     void DumpInfo() override;
106 
107     void BuildArrayValueItems();
108     void BuildFullArrayValue();
109     void CollapseArrayValue();
110     void ApplySevenPlusOneMode(int32_t fullArraySize);
111     void ApplyFivePlusOneMode(int32_t fullArraySize);
112     int32_t GetAutoCollapseIndex(int32_t propSelect);
113 
114     void OnTouchDown(const TouchEventInfo& info);
115     void OnTouchUp(const TouchEventInfo& info);
116     void MoveIndexByOffset(const Offset& offset);
117     bool MoveIndexByStep(int32_t step);
118     bool KeyIndexByStep(int32_t step);
119     bool MoveIndexBySearch(const std::string& searchStr);
120     void ApplyIndexChanged(
121         bool isTextNodeInTree, bool refreshBubble = true, bool fromTouchUp = false, bool indexerSizeChanged = false);
122     void OnSelect();
123     int32_t GetSkipChildIndex(int32_t step);
124     int32_t GetFocusChildIndex(const std::string& searchStr);
125 
126     void InitPanEvent(const RefPtr<GestureEventHub>& gestureHub);
127     void InitInputEvent();
128     void InitCurrentInputEvent();
129     void InitChildInputEvent(RefPtr<FrameNode>& itemNode, int32_t childIndex);
130     void InitPopupInputEvent();
131     void InitPopupPanEvent();
132     void InitOnKeyEvent();
133     bool OnKeyEvent(const KeyEvent& event);
134     void OnHover(bool isHover);
135     void OnChildHover(int32_t index, bool isHover);
136     void OnPopupHover(bool isHover);
137     void ResetStatus();
138     void OnKeyEventDisapear();
139     void UpdateBubbleListItem(std::vector<std::string>& currentListData, const RefPtr<FrameNode>& parentNode,
140         RefPtr<IndexerTheme>& indexerTheme);
141     void AddPopupTouchListener(RefPtr<FrameNode> popupNode);
142     void OnPopupTouchDown(const TouchEventInfo& info);
143     void AddListItemClickListener(RefPtr<FrameNode>& listItemNode, int32_t index);
144     void OnListItemClick(int32_t index);
145     void ClearClickStatus();
146     void ChangeListItemsSelectedStyle(int32_t clickIndex);
147     RefPtr<FrameNode> CreatePopupNode();
148     void UpdateBubbleView();
149     Shadow GetPopupShadow();
150     void UpdateBubbleSize();
151     void UpdateBubbleLetterView(bool showDivider, std::vector<std::string>& currentListData);
152     void CreateBubbleListView(std::vector<std::string>& currentListData);
153     void UpdateBubbleListView(std::vector<std::string>& currentListData);
154     void UpdatePopupOpacity(float ratio);
155     void UpdatePopupVisibility(VisibleType visible);
156     bool NeedShowPopupView();
157     bool NeedShowBubble();
158     void ShowBubble(bool fromTouchUp = false);
159     bool IfSelectIndexValid();
160     int32_t GetSelectChildIndex(const Offset& offset);
161     void StartBubbleAppearAnimation();
162     void StartDelayTask(uint32_t duration = INDEXER_BUBBLE_WAIT_DURATION);
163     void StartBubbleDisappearAnimation();
164     void IndexerHoverInAnimation();
165     void IndexerHoverOutAnimation();
166     void IndexerPressInAnimation();
167     void IndexerPressOutAnimation();
168     int32_t GenerateAnimationId();
169     void ItemSelectedInAnimation(RefPtr<FrameNode>& itemNode);
170     void ItemSelectedOutAnimation(RefPtr<FrameNode>& itemNode);
171     void FireOnSelect(int32_t selectIndex, bool fromPress);
172     void SetAccessibilityAction();
173     void SetActionSelect(RefPtr<FrameNode>& textNode, RefPtr<AccessibilityProperty>& accessibilityProperty);
174     void SetActionClearSelection(RefPtr<FrameNode>& textNode, RefPtr<AccessibilityProperty>& accessibilityProperty);
175     void RemoveBubble();
176     void UpdateBubbleBackgroundView();
177     CalcSize CalcBubbleListSize(int32_t popupSize, int32_t maxItemsSize);
178     GradientColor CreatePercentGradientColor(float percent, Color color);
179     void UpdateBubbleLetterStackAndLetterTextView();
180     void DrawPopupListGradient(PopupListGradientStatus gradientStatus);
181     void UpdatePopupListGradientView(int32_t popupSize, int32_t maxItemsSize);
182     RefPtr<FrameNode> GetLetterNode();
183     RefPtr<FrameNode> GetAutoCollapseLetterNode();
184     void UpdateBubbleListSize(std::vector<std::string>& currentListData);
185     void UpdateBubbleListItemContext(
186         const RefPtr<FrameNode>& listNode, RefPtr<IndexerTheme>& indexerTheme, uint32_t pos);
187     void UpdateBubbleListItemMarkModify(RefPtr<FrameNode>& textNode, RefPtr<FrameNode>& listItemNode);
188     void StartCollapseDelayTask(RefPtr<FrameNode>& hostNode, uint32_t duration = INDEXER_COLLAPSE_WAIT_DURATION);
189 
190     RefPtr<FrameNode> popupNode_;
191     RefPtr<TouchEventImpl> touchListener_;
192     RefPtr<PanEvent> panEvent_;
193     RefPtr<Animator> bubbleAnimator_;
194     bool isInputEventRegisted_ = false;
195     bool isKeyEventRegisted_ = false;
196     bool isTouch_ = false;
197     bool isHover_ = false;
198     bool isPopup_ = false;
199     bool isPopupHover_ = false;
200 
201      // the array of displayed items, ths second param in the pair
202      // indicates whether the item should be hidden and displayed as dot
203     std::vector<std::pair<std::string, bool>> arrayValue_;
204     // full array of items, used in auto-collapse mode
205     std::vector<std::string> fullArrayValue_;
206     // sharp item count is 0 or 1, indicates whether the first item is # in
207     // original array, used in auto-collapse mode
208     int32_t sharpItemCount_ = 0;
209     int32_t itemCount_ = 0;
210     int32_t selected_ = 0;
211     int32_t animateSelected_ = -1;
212     int32_t lastSelected_ = -1;
213     bool initialized_ = false;
214     int32_t childHoverIndex_ = -1;
215     int32_t childFocusIndex_ = -1;
216     int32_t childPressIndex_ = -1;
217     int32_t animationId_ = 0;
218     int32_t lastPopupIndex_ = -1;
219     uint32_t lastPopupSize_ = 0;
220     int32_t currentPopupIndex_ = -1;
221     float itemHeight_ = 0.0f;
222     int32_t popupClickedIndex_ = -1;
223     int32_t lastFireSelectIndex_ = -1;
224     float lastItemSize_ = -1.0f;
225     bool lastIndexFromPress_ = false;
226     bool selectChanged_ = false;
227     bool autoCollapse_ = true;
228     bool lastAutoCollapse_ = true;
229     bool enableHapticFeedback_ = true;
230     float maxContentHeight_ = 0.0f;
231     bool isNewHeightCalculated_ = false;
232     bool selectedChangedForHaptic_ = false;
233     IndexerCollapsingMode lastCollapsingMode_ = IndexerCollapsingMode::INVALID;
234     CancelableCallback<void()> delayTask_;
235     CancelableCallback<void()> delayCollapseTask_;
236 };
237 } // namespace OHOS::Ace::NG
238 
239 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_LIST_LIST_PATTERN_H
240