• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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_TEXT_PICKER_TEXT_PICKER_COLUMN_PATTERN_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TEXT_PICKER_TEXT_PICKER_COLUMN_PATTERN_H
18 
19 #include <optional>
20 
21 #include "core/components/common/properties/color.h"
22 #include "core/components/picker/picker_theme.h"
23 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
24 #include "core/components_ng/pattern/picker/picker_type_define.h"
25 #include "core/components_ng/pattern/text/text_layout_property.h"
26 #include "core/components_ng/pattern/text_picker/textpicker_accessibility_property.h"
27 #include "core/components_ng/pattern/text_picker/textpicker_event_hub.h"
28 #include "core/components_ng/pattern/text_picker/textpicker_layout_algorithm.h"
29 #include "core/components_ng/pattern/text_picker/textpicker_layout_property.h"
30 #include "core/components_ng/pattern/text_picker/textpicker_overscroll.h"
31 #include "core/components_ng/pattern/text_picker/textpicker_paint_method.h"
32 #include "core/components_ng/pattern/text_picker/toss_animation_controller.h"
33 
34 namespace OHOS::Ace::NG {
35 using EventCallback = std::function<void(bool)>;
36 using ColumnChangeCallback = std::function<void(const RefPtr<FrameNode>&, bool, uint32_t, bool)>;
37 
38 struct TextProperties {
39     Dimension upFontSize;
40     Dimension fontSize;
41     Dimension downFontSize;
42     Color upColor;
43     Color currentColor;
44     Color downColor;
45     FontWeight upFontWeight;
46     FontWeight fontWeight;
47     FontWeight downFontWeight;
48 };
49 
50 struct TextPickerOptionProperty {
51     float height = 0.0f;
52     float fontheight = 0.0f;
53     float prevDistance = 0.0f; // between the prev item and itself when scroll up
54     float nextDistance = 0.0f; // between the next item and itself when scroll down
55 };
56 
57 class EventParam : public virtual AceType {
58     DECLARE_ACE_TYPE(EventParam, AceType)
59 
60 public:
61     WeakPtr<FrameNode> instance;
62     int32_t itemIndex = 0;
63     int32_t itemTotalCounts = 0;
64 };
65 
66 enum class ScrollDirection {
67     UP = 0,
68     DOWN,
69 };
70 
71 enum class OptionIndex {
72     COLUMN_INDEX_0 = 0,
73     COLUMN_INDEX_1,
74     COLUMN_INDEX_2,
75     COLUMN_INDEX_3,
76     COLUMN_INDEX_4,
77     COLUMN_INDEX_5,
78     COLUMN_INDEX_6
79 };
80 
81 class TextPickerColumnPattern : public LinearLayoutPattern {
82     DECLARE_ACE_TYPE(TextPickerColumnPattern, LinearLayoutPattern);
83 
84 public:
TextPickerColumnPattern()85     TextPickerColumnPattern() : LinearLayoutPattern(true) {};
86 
87     ~TextPickerColumnPattern() override = default;
88 
IsAtomicNode()89     bool IsAtomicNode() const override
90     {
91         return true;
92     }
93 
CreateLayoutAlgorithm()94     RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override
95     {
96         auto layoutAlgorithm = MakeRefPtr<TextPickerLayoutAlgorithm>();
97         if (algorithmOffset_.size() == 0) {
98             ResetAlgorithmOffset();
99         }
100         layoutAlgorithm->SetCurrentOffset(algorithmOffset_);
101         layoutAlgorithm->SetDefaultPickerItemHeight(defaultPickerItemHeight_);
102         return layoutAlgorithm;
103     }
104 
CreateLayoutProperty()105     RefPtr<LayoutProperty> CreateLayoutProperty() override
106     {
107         return MakeRefPtr<LinearLayoutProperty>(true);
108     }
109 
110     void FlushCurrentOptions(bool isDown = false, bool isUpateTextContentOnly = false, bool isDirectlyClear = false,
111         bool isUpdateAnimationProperties = false);
112 
113     void InitilaScorllEvent();
114 
115     void UpdateCurrentOffset(float offset);
116 
117     void UpdateColumnChildPosition(double offsetY);
118 
GetOverscroller()119     TextPickerOverscroller& GetOverscroller()
120     {
121         return overscroller_;
122     }
123 
124     bool CanMove(bool isDown) const;
125 
126     bool NotLoopOptions() const;
127 
128     bool InnerHandleScroll(bool isDown, bool isUpatePropertiesOnly = false, bool isUpdateAnimationProperties = false);
129 
SetDefaultPickerItemHeight(double defaultPickerItemHeight)130     void SetDefaultPickerItemHeight(double defaultPickerItemHeight)
131     {
132         defaultPickerItemHeight_ = defaultPickerItemHeight;
133     }
134 
135     uint32_t GetShowOptionCount() const;
136 
137     std::string GetSelectedObject(bool isColumnChange, int32_t status = 0) const;
138 
SetSelected(uint32_t value)139     void SetSelected(uint32_t value)
140     {
141         selectedIndex_ = value;
142     }
GetSelected()143     uint32_t GetSelected() const
144     {
145         return selectedIndex_;
146     }
147 
SetRange(const std::vector<std::string> & value)148     void SetRange(const std::vector<std::string>& value)
149     {
150         if (value.empty()) {
151             return;
152         }
153         range_ = value;
154     }
155 
GetRange()156     const std::vector<std::string>& GetRange() const
157     {
158         return range_;
159     }
160 
GetCurrentText()161     std::string GetCurrentText() const
162     {
163         return GetOption(GetCurrentIndex());
164     }
165 
GetCurrentIndex()166     uint32_t GetCurrentIndex() const
167     {
168         return currentIndex_;
169     }
SetCurrentIndex(uint32_t value)170     void SetCurrentIndex(uint32_t value)
171     {
172         if (value != currentIndex_) {
173             isIndexChanged_ = true;
174             currentIndex_ = value;
175         }
176     }
177 
GetOptionCount()178     uint32_t GetOptionCount() const
179     {
180         return options_.size();
181     }
182 
GetOption(uint32_t index)183     std::string GetOption(uint32_t index) const
184     {
185         if (index >= GetOptionCount()) {
186             return "";
187         }
188         return options_[index].text_;
189     }
190 
SetOptions(std::vector<NG::RangeContent> & value)191     void SetOptions(std::vector<NG::RangeContent>& value)
192     {
193         options_.clear();
194         for (auto& content : value) {
195             options_.emplace_back(content);
196         }
197     }
198 
ClearOptions()199     void ClearOptions()
200     {
201         options_.clear();
202     }
203 
SetColumnKind(int32_t kind)204     void SetColumnKind(int32_t kind)
205     {
206         columnkind_ = kind;
207     }
208 
GetCurrentOffset()209     float GetCurrentOffset() const
210     {
211         return deltaSize_;
212     }
213 
SetCurrentOffset(float deltaSize)214     void SetCurrentOffset(float deltaSize)
215     {
216         deltaSize_ = deltaSize;
217     }
218 
GetToss()219     const RefPtr<TextPickerTossAnimationController>& GetToss() const
220     {
221         return tossAnimationController_;
222     }
223 
HandleEventCallback(bool refresh)224     void HandleEventCallback(bool refresh)
225     {
226         if (EventCallback_) {
227             EventCallback_(refresh);
228         }
229     }
230 
GetEventCallback()231     const EventCallback& GetEventCallback() const
232     {
233         return EventCallback_;
234     }
235 
SetEventCallback(EventCallback && value)236     void SetEventCallback(EventCallback&& value)
237     {
238         EventCallback_ = value;
239     }
240 
SetLocalDownDistance(float value)241     void SetLocalDownDistance(float value)
242     {
243         localDownDistance_ = value;
244     }
245 
GetLocalDownDistance()246     float GetLocalDownDistance() const
247     {
248         return localDownDistance_;
249     }
250 
251     void UpdateToss(double offsetY);
252 
253     void TossStoped();
254 
255     void UpdateScrollDelta(double delta);
256 
CreateAccessibilityProperty()257     RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override
258     {
259         return MakeRefPtr<TextPickerAccessibilityProperty>();
260     }
261 
SetChangeCallback(ColumnChangeCallback && value)262     void SetChangeCallback(ColumnChangeCallback&& value)
263     {
264         changeCallback_ = value;
265     }
266 
HandleChangeCallback(bool isAdd,bool needNotify)267     void HandleChangeCallback(bool isAdd, bool needNotify)
268     {
269         if (changeCallback_) {
270             changeCallback_(GetHost(), isAdd, GetCurrentIndex(), needNotify);
271         }
272     }
273 
GetHalfDisplayCounts()274     int32_t GetHalfDisplayCounts() const
275     {
276         return halfDisplayCounts_;
277     }
278 
GetOffset()279     double GetOffset() const
280     {
281         return offsetCurSet_;
282     }
283 
SetYLast(double value)284     void SetYLast(double value)
285     {
286         yLast_ = value;
287     }
288 
289     void TossAnimationStoped();
290 
291     void PlayResetAnimation();
292 
GetMidShiftDistance()293     std::vector<TextPickerOptionProperty> GetMidShiftDistance() const
294     {
295         return optionProperties_;
296     }
297 
SetMainVelocity(double mainVelocity)298     void SetMainVelocity(double mainVelocity)
299     {
300         mainVelocity_ = mainVelocity;
301     }
302 
GetMainVelocity()303     double GetMainVelocity() const
304     {
305         return mainVelocity_;
306     }
307 
SetTossStatus(bool status)308     void SetTossStatus(bool status)
309     {
310         isTossStatus_ = status;
311         if (!status && NotLoopOptions() && !pressed_ && !isReboundInProgress_ && overscroller_.IsOverScroll()) {
312             // Start rebound animation when toss stoped
313             CreateReboundAnimation(overscroller_.GetOverScroll(), 0.0);
314         }
315     }
316 
GetTossStatus()317     bool GetTossStatus() const
318     {
319         return isTossStatus_;
320     }
321 
SetYOffset(double value)322     void SetYOffset(double value)
323     {
324         yOffset_ = value;
325     }
326 
GetTouchBreakStatus()327     bool GetTouchBreakStatus() const
328     {
329         return touchBreak_;
330     }
331 
NeedResetOptionPropertyHeight(bool needOptionPropertyHeightReset)332     void NeedResetOptionPropertyHeight(bool needOptionPropertyHeightReset)
333     {
334         needOptionPropertyHeightReset_ = needOptionPropertyHeightReset;
335     }
336 
isHover()337     bool isHover() const
338     {
339         return isHover_;
340     }
341 
342     int32_t GetOverScrollDeltaIndex() const;
343     void SetCanLoop(bool isLoop);
344 
SetScrollDirection(bool isDown)345     void SetScrollDirection(bool isDown)
346     {
347         isDownScroll_ = isDown;
348     }
349 
IsDownScroll()350     bool IsDownScroll()
351     {
352         return isDownScroll_;
353     }
354     void ResetOptionPropertyHeight();
355     void ResetTotalDelta();
356 
357 private:
358     void OnModifyDone() override;
359     void OnAttachToFrameNode() override;
360     bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override;
361 
362     bool OnKeyEvent(const KeyEvent& event);
363     bool HandleDirectionKey(KeyCode code);
364 
365     void InitPanEvent(const RefPtr<GestureEventHub>& gestureHub);
366     void HandleDragStart(const GestureEvent& event);
367     void HandleDragMove(const GestureEvent& event);
368     void HandleDragEnd();
369     void CreateAnimation();
370     void CreateAnimation(double from, double to);
371     void CreateReboundAnimation(double from, double to);
372     void ScrollOption(double delta);
373     std::vector<TextPickerOptionProperty> optionProperties_;
374     std::vector<int32_t> algorithmOffset_;
375     void ResetAlgorithmOffset();
376     void CalcAlgorithmOffset(double distancePercent);
377     void SetOptionShiftDistance();
378     double GetShiftDistanceForLandscape(int32_t index, ScrollDirection dir);
379     double GetShiftDistance(int32_t index, ScrollDirection dir);
380     double GetSelectedDistance(int32_t index, int32_t nextIndex, ScrollDirection dir);
381     double GetUpCandidateDistance(int32_t index, int32_t nextIndex, ScrollDirection dir);
382     double GetDownCandidateDistance(int32_t index, int32_t nextIndex, ScrollDirection dir);
383     void OnTouchDown();
384     void OnTouchUp();
385     void ParseTouchListener();
386     void ParseMouseEvent();
387     void InitMouseAndPressEvent();
388     void HandleMouseEvent(bool isHover);
389     void SetButtonBackgroundColor(const Color& pressColor);
390     void PlayPressAnimation(const Color& pressColor);
391     void FlushCurrentTextOptions(const RefPtr<TextPickerLayoutProperty>& textPickerLayoutProperty,
392         bool isUpateTextContentOnly, bool isDirectlyClear);
393     void FlushCurrentImageOptions();
394     void FlushCurrentMixtureOptions(
395         const RefPtr<TextPickerLayoutProperty>& textPickerLayoutProperty, bool isUpateTextContentOnly);
396     void UpdatePickerTextProperties(const RefPtr<TextLayoutProperty>& textLayoutProperty,
397         const RefPtr<TextPickerLayoutProperty>& textPickerLayoutProperty, uint32_t currentIndex, uint32_t middleIndex,
398         uint32_t showCount);
399     void UpdateSelectedTextProperties(const RefPtr<PickerTheme>& pickerTheme,
400         const RefPtr<TextLayoutProperty>& textLayoutProperty,
401         const RefPtr<TextPickerLayoutProperty>& textPickerLayoutProperty);
402     void UpdateCandidateTextProperties(const RefPtr<PickerTheme>& pickerTheme,
403         const RefPtr<TextLayoutProperty>& textLayoutProperty,
404         const RefPtr<TextPickerLayoutProperty>& textPickerLayoutProperty);
405     void UpdateDisappearTextProperties(const RefPtr<PickerTheme>& pickerTheme,
406         const RefPtr<TextLayoutProperty>& textLayoutProperty,
407         const RefPtr<TextPickerLayoutProperty>& textPickerLayoutProperty);
408     void AddAnimationTextProperties(uint32_t currentIndex, const RefPtr<TextLayoutProperty>& textLayoutProperty);
409     void UpdateTextPropertiesLinear(bool isDown, double scale);
410     void TextPropertiesLinearAnimation(const RefPtr<TextLayoutProperty>& textLayoutProperty, uint32_t index,
411         uint32_t showCount, bool isDown, double scale);
412     void FlushAnimationTextProperties(bool isDown);
413     Dimension LinearFontSize(const Dimension& startFontSize, const Dimension& endFontSize, double percent);
414     void ClearCurrentTextOptions(const RefPtr<TextPickerLayoutProperty>& textPickerLayoutProperty,
415         bool isUpateTextContentOnly, bool isDirectlyClear);
416 
417     RefPtr<TextPickerLayoutProperty> GetParentLayout() const;
418     RefPtr<TouchEventImpl> CreateItemTouchEventListener();
419     void OnAroundButtonClick(RefPtr<EventParam> param);
420     void OnMiddleButtonTouchDown();
421     void OnMiddleButtonTouchMove();
422     void OnMiddleButtonTouchUp();
423     int32_t GetMiddleButtonIndex();
424 
425     bool touchEventInit_ = false;
426     RefPtr<InputEvent> CreateMouseHoverEventListener(RefPtr<EventParam> param);
427     RefPtr<ClickEvent> CreateItemClickEventListener(RefPtr<EventParam> param);
428     void SetAccessibilityAction();
429 
430     void InitTextFontFamily();
431     bool SpringCurveTailMoveProcess(bool useRebound, double& dragDelta);
432     void SpringCurveTailEndProcess(bool useRebound, bool stopMove);
433 
434     float localDownDistance_ = 0.0f;
435     Color pressColor_;
436     Color hoverColor_;
437     EventCallback EventCallback_;
438     RefPtr<ClickEvent> clickEventListener_;
439     bool enabled_ = true;
440     int32_t focusKeyID_ = 0;
441     RefPtr<TouchEventImpl> touchListener_;
442     bool isPress_ = false;
443     bool isHover_ = false;
444     RefPtr<InputEvent> mouseEvent_;
445     double defaultPickerItemHeight_ = 0.0;
446     uint32_t selectedIndex_ = 0;
447     std::string selectedValue_;
448     std::vector<std::string> range_ { "" };
449     uint32_t currentIndex_ = 0;
450     std::vector<NG::RangeContent> options_;
451     int32_t columnkind_ = 0;
452     int32_t currentChildIndex_ = 0;
453     float deltaSize_ = 0.0f;
454     double totalDragDelta_ = 0.0;
455     double yLast_ = 0.0;
456     double yOffset_ = 0.0;
457     double jumpInterval_ = 0.0;
458     Size optionSize_;
459     Dimension fixHeight_;
460     bool isIndexChanged_ = false;
461 
462     RefPtr<PanEvent> panEvent_;
463     bool pressed_ = false;
464     double scrollDelta_ = 0.0;
465     bool animationCreated_ = false;
466     RefPtr<TextPickerTossAnimationController> tossAnimationController_ =
467         AceType::MakeRefPtr<TextPickerTossAnimationController>();
468     RefPtr<NodeAnimatablePropertyFloat> scrollProperty_;
469     RefPtr<NodeAnimatablePropertyFloat> aroundClickProperty_;
470     std::shared_ptr<AnimationUtils::Animation> animation_;
471     std::shared_ptr<AnimationUtils::Animation> reboundAnimation_;
472     std::vector<TextProperties> animationProperties_;
473     float dividerSpacing_ = 0.0f;
474     float gradientHeight_ = 0.0f;
475     bool isReboundInProgress_ = false;
476     TextPickerOverscroller overscroller_;
477     ColumnChangeCallback changeCallback_;
478 
479     int32_t halfDisplayCounts_ = 0;
480 
481     double mainVelocity_ = 0.0;
482     float offsetCurSet_ = 0.0f;
483     float distancePercent_ = 0.0f;
484     bool isTossStatus_ = false;
485     bool clickBreak_ = false;
486     bool touchBreak_ = false;
487     bool animationBreak_ = false;
488     bool needOptionPropertyHeightReset_ = false;
489     bool isLoop_ = true;
490     bool isDownScroll_ = false;
491 
492     bool hasAppCustomFont_ = false;
493     bool hasUserDefinedDisappearFontFamily_ = false;
494     bool hasUserDefinedNormalFontFamily_ = false;
495     bool hasUserDefinedSelectedFontFamily_ = false;
496 
497     ACE_DISALLOW_COPY_AND_MOVE(TextPickerColumnPattern);
498 };
499 } // namespace OHOS::Ace::NG
500 
501 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TEXT_PICKER_TEXT_PICKER_COLUMN_PATTERN_H
502