• 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 
HandleScrollStopEventCallback(bool refresh)241     void HandleScrollStopEventCallback(bool refresh)
242     {
243         if (scrollStopEventCallback_) {
244             scrollStopEventCallback_(refresh);
245         }
246     }
247 
GetScrollStopEventCallback()248     const EventCallback& GetScrollStopEventCallback() const
249     {
250         return scrollStopEventCallback_;
251     }
252 
SetScrollStopEventCallback(EventCallback && value)253     void SetScrollStopEventCallback(EventCallback&& value)
254     {
255         scrollStopEventCallback_ = value;
256     }
257 
SetLocalDownDistance(float value)258     void SetLocalDownDistance(float value)
259     {
260         localDownDistance_ = value;
261     }
262 
GetLocalDownDistance()263     float GetLocalDownDistance() const
264     {
265         return localDownDistance_;
266     }
267 
268     void UpdateToss(double offsetY);
269 
270     void TossStoped();
271 
272     void UpdateScrollDelta(double delta);
273 
CreateAccessibilityProperty()274     RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override
275     {
276         return MakeRefPtr<TextPickerAccessibilityProperty>();
277     }
278 
SetChangeCallback(ColumnChangeCallback && value)279     void SetChangeCallback(ColumnChangeCallback&& value)
280     {
281         changeCallback_ = value;
282     }
283 
HandleChangeCallback(bool isAdd,bool needNotify)284     void HandleChangeCallback(bool isAdd, bool needNotify)
285     {
286         if (changeCallback_) {
287             changeCallback_(GetHost(), isAdd, GetCurrentIndex(), needNotify);
288         }
289     }
290 
GetHalfDisplayCounts()291     int32_t GetHalfDisplayCounts() const
292     {
293         return halfDisplayCounts_;
294     }
295 
GetOffset()296     double GetOffset() const
297     {
298         return offsetCurSet_;
299     }
300 
SetYLast(double value)301     void SetYLast(double value)
302     {
303         yLast_ = value;
304     }
305 
306     void TossAnimationStoped();
307 
308     void PlayResetAnimation();
309 
GetMidShiftDistance()310     std::vector<TextPickerOptionProperty> GetMidShiftDistance() const
311     {
312         return optionProperties_;
313     }
314 
SetMainVelocity(double mainVelocity)315     void SetMainVelocity(double mainVelocity)
316     {
317         mainVelocity_ = mainVelocity;
318     }
319 
GetMainVelocity()320     double GetMainVelocity() const
321     {
322         return mainVelocity_;
323     }
324 
SetTossStatus(bool status)325     void SetTossStatus(bool status)
326     {
327         isTossStatus_ = status;
328         if (!status && NotLoopOptions() && !pressed_ && !isReboundInProgress_ && overscroller_.IsOverScroll()) {
329             // Start rebound animation when toss stoped
330             CreateReboundAnimation(overscroller_.GetOverScroll(), 0.0);
331             HandleScrollStopEventCallback(true);
332         }
333     }
334 
GetTossStatus()335     bool GetTossStatus() const
336     {
337         return isTossStatus_;
338     }
339 
SetYOffset(double value)340     void SetYOffset(double value)
341     {
342         yOffset_ = value;
343     }
344 
GetTouchBreakStatus()345     bool GetTouchBreakStatus() const
346     {
347         return touchBreak_;
348     }
349 
NeedResetOptionPropertyHeight(bool needOptionPropertyHeightReset)350     void NeedResetOptionPropertyHeight(bool needOptionPropertyHeightReset)
351     {
352         needOptionPropertyHeightReset_ = needOptionPropertyHeightReset;
353     }
354 
isHover()355     bool isHover() const
356     {
357         return isHover_;
358     }
359 
360     int32_t GetOverScrollDeltaIndex() const;
361     void SetCanLoop(bool isLoop);
362 
363     void ResetOptionPropertyHeight();
364     void ResetTotalDelta();
365 
SetDisableTextStyleAnimation(bool value)366     void SetDisableTextStyleAnimation(bool value)
367     {
368         isDisableTextStyleAnimation_ = value;
369     }
370 
371 private:
372     void OnModifyDone() override;
373     void OnAttachToFrameNode() override;
374     bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override;
375 
376     bool OnKeyEvent(const KeyEvent& event);
377     bool HandleDirectionKey(KeyCode code);
378 
379     void InitPanEvent(const RefPtr<GestureEventHub>& gestureHub);
380     void HandleDragStart(const GestureEvent& event);
381     void HandleDragMove(const GestureEvent& event);
382     void HandleDragEnd();
383     void CreateAnimation();
384     void CreateAnimation(double from, double to);
385     void CreateReboundAnimation(double from, double to);
386     void ScrollOption(double delta);
387     std::vector<TextPickerOptionProperty> optionProperties_;
388     std::vector<int32_t> algorithmOffset_;
389     void ResetAlgorithmOffset();
390     void CalcAlgorithmOffset(ScrollDirection dir, double distancePercent);
391     void SetOptionShiftDistance();
392     double GetShiftDistanceForLandscape(int32_t index, ScrollDirection dir);
393     double GetShiftDistance(int32_t index, ScrollDirection dir);
394     double GetSelectedDistance(int32_t index, int32_t nextIndex, ScrollDirection dir);
395     double GetUpCandidateDistance(int32_t index, int32_t nextIndex, ScrollDirection dir);
396     double GetDownCandidateDistance(int32_t index, int32_t nextIndex, ScrollDirection dir);
397     void OnTouchDown();
398     void OnTouchUp();
399     void ParseTouchListener();
400     void ParseMouseEvent();
401     void InitMouseAndPressEvent();
402     void HandleMouseEvent(bool isHover);
403     void SetButtonBackgroundColor(const Color& pressColor);
404     void PlayPressAnimation(const Color& pressColor);
405     void FlushCurrentTextOptions(const RefPtr<TextPickerLayoutProperty>& textPickerLayoutProperty,
406         bool isUpateTextContentOnly, bool isDirectlyClear);
407     void FlushCurrentImageOptions();
408     void FlushCurrentMixtureOptions(
409         const RefPtr<TextPickerLayoutProperty>& textPickerLayoutProperty, bool isUpateTextContentOnly);
410     void UpdatePickerTextProperties(const RefPtr<TextLayoutProperty>& textLayoutProperty,
411         const RefPtr<TextPickerLayoutProperty>& textPickerLayoutProperty, uint32_t currentIndex, uint32_t middleIndex,
412         uint32_t showCount);
413     void UpdateSelectedTextProperties(const RefPtr<PickerTheme>& pickerTheme,
414         const RefPtr<TextLayoutProperty>& textLayoutProperty,
415         const RefPtr<TextPickerLayoutProperty>& textPickerLayoutProperty);
416     void UpdateCandidateTextProperties(const RefPtr<PickerTheme>& pickerTheme,
417         const RefPtr<TextLayoutProperty>& textLayoutProperty,
418         const RefPtr<TextPickerLayoutProperty>& textPickerLayoutProperty);
419     void UpdateDisappearTextProperties(const RefPtr<PickerTheme>& pickerTheme,
420         const RefPtr<TextLayoutProperty>& textLayoutProperty,
421         const RefPtr<TextPickerLayoutProperty>& textPickerLayoutProperty);
422     void AddAnimationTextProperties(uint32_t currentIndex, const RefPtr<TextLayoutProperty>& textLayoutProperty);
423     void UpdateTextPropertiesLinear(bool isDown, double scale);
424     void TextPropertiesLinearAnimation(const RefPtr<TextLayoutProperty>& textLayoutProperty, uint32_t index,
425         uint32_t showCount, bool isDown, double scale);
426     void FlushAnimationTextProperties(bool isDown);
427     Dimension LinearFontSize(const Dimension& startFontSize, const Dimension& endFontSize, double percent);
428     void ClearCurrentTextOptions(const RefPtr<TextPickerLayoutProperty>& textPickerLayoutProperty,
429         bool isUpateTextContentOnly, bool isDirectlyClear);
430     void UpdateDefaultTextProperties(const RefPtr<TextLayoutProperty>& textLayoutProperty,
431         const RefPtr<TextPickerLayoutProperty>& textPickerLayoutProperty);
432 
433     RefPtr<TextPickerLayoutProperty> GetParentLayout() const;
434     RefPtr<TouchEventImpl> CreateItemTouchEventListener();
435     void OnAroundButtonClick(RefPtr<EventParam> param);
436     void OnMiddleButtonTouchDown();
437     void OnMiddleButtonTouchMove();
438     void OnMiddleButtonTouchUp();
439     int32_t GetMiddleButtonIndex();
440 
441     bool touchEventInit_ = false;
442     RefPtr<InputEvent> CreateMouseHoverEventListener(RefPtr<EventParam> param);
443     RefPtr<ClickEvent> CreateItemClickEventListener(RefPtr<EventParam> param);
444     void SetAccessibilityAction();
445 
446     void InitTextFontFamily();
447     bool SpringCurveTailMoveProcess(bool useRebound, double& dragDelta);
448     void SpringCurveTailEndProcess(bool useRebound, bool stopMove);
449     void UpdateTextAccessibilityProperty(RefPtr<FrameNode>& textNode, int32_t virtualIndex,
450         std::list<RefPtr<UINode>>::iterator& iter, bool virtualIndexValidate);
451 
452     float localDownDistance_ = 0.0f;
453     Color pressColor_;
454     Color hoverColor_;
455     EventCallback EventCallback_;
456     EventCallback scrollStopEventCallback_;
457     RefPtr<ClickEvent> clickEventListener_;
458     bool enabled_ = true;
459     int32_t focusKeyID_ = 0;
460     RefPtr<TouchEventImpl> touchListener_;
461     bool isPress_ = false;
462     bool isHover_ = false;
463     RefPtr<InputEvent> mouseEvent_;
464     double defaultPickerItemHeight_ = 0.0;
465     uint32_t selectedIndex_ = 0;
466     std::string selectedValue_;
467     std::vector<std::string> range_ { "" };
468     uint32_t currentIndex_ = 0;
469     std::vector<NG::RangeContent> options_;
470     int32_t columnkind_ = 0;
471     int32_t currentChildIndex_ = 0;
472     float deltaSize_ = 0.0f;
473     double totalDragDelta_ = 0.0;
474     double yLast_ = 0.0;
475     double yOffset_ = 0.0;
476     double jumpInterval_ = 0.0;
477     Size optionSize_;
478     Dimension fixHeight_;
479     bool isIndexChanged_ = false;
480 
481     RefPtr<PanEvent> panEvent_;
482     bool pressed_ = false;
483     double scrollDelta_ = 0.0;
484     bool animationCreated_ = false;
485     RefPtr<TextPickerTossAnimationController> tossAnimationController_ =
486         AceType::MakeRefPtr<TextPickerTossAnimationController>();
487     RefPtr<NodeAnimatablePropertyFloat> scrollProperty_;
488     RefPtr<NodeAnimatablePropertyFloat> aroundClickProperty_;
489     std::shared_ptr<AnimationUtils::Animation> animation_;
490     std::shared_ptr<AnimationUtils::Animation> reboundAnimation_;
491     std::vector<TextProperties> animationProperties_;
492     float dividerSpacing_ = 0.0f;
493     float gradientHeight_ = 0.0f;
494     bool isReboundInProgress_ = false;
495     TextPickerOverscroller overscroller_;
496     ColumnChangeCallback changeCallback_;
497 
498     int32_t halfDisplayCounts_ = 0;
499 
500     double mainVelocity_ = 0.0;
501     float offsetCurSet_ = 0.0f;
502     float distancePercent_ = 0.0f;
503     bool isTossStatus_ = false;
504     bool clickBreak_ = false;
505     bool touchBreak_ = false;
506     bool animationBreak_ = false;
507     bool needOptionPropertyHeightReset_ = false;
508     bool isLoop_ = true;
509 
510     bool hasAppCustomFont_ = false;
511     bool hasUserDefinedDisappearFontFamily_ = false;
512     bool hasUserDefinedNormalFontFamily_ = false;
513     bool hasUserDefinedSelectedFontFamily_ = false;
514 
515     bool isDisableTextStyleAnimation_ = false;
516 
517     ACE_DISALLOW_COPY_AND_MOVE(TextPickerColumnPattern);
518 };
519 } // namespace OHOS::Ace::NG
520 
521 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TEXT_PICKER_TEXT_PICKER_COLUMN_PATTERN_H
522