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_DATE_PICKER_DATE_PICKER_COLUMN_PATTERN_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_DATE_PICKER_DATE_PICKER_COLUMN_PATTERN_H
18 
19 #include <utility>
20 
21 #include "base/i18n/localization.h"
22 #include "core/components/picker/picker_theme.h"
23 #include "core/components_ng/base/frame_node.h"
24 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
25 #include "core/components_ng/pattern/picker/datepicker_column_accessibility_property.h"
26 #include "core/components_ng/pattern/picker/datepicker_column_layout_algorithm.h"
27 #include "core/components_ng/pattern/picker/datepicker_event_hub.h"
28 #include "core/components_ng/pattern/picker/datepicker_layout_property.h"
29 #include "core/components_ng/pattern/picker/datepicker_paint_method.h"
30 #include "core/components_ng/pattern/picker/datepicker_row_layout_property.h"
31 #include "core/components_ng/pattern/picker/toss_animation_controller.h"
32 #include "core/components_ng/pattern/text/text_layout_property.h"
33 #include "core/pipeline_ng/ui_task_scheduler.h"
34 
35 namespace OHOS::Ace::NG {
36 
37 using ColumnChangeCallback = std::function<void(const RefPtr<FrameNode>&, bool, uint32_t, bool)>;
38 using ColumnFinishCallback = std::function<void(bool)>;
39 using EventCallback = std::function<void(bool)>;
40 
41 struct DateTextProperties {
42     Dimension upFontSize;
43     Dimension fontSize;
44     Dimension downFontSize;
45     FontWeight upFontWeight;
46     FontWeight fontWeight;
47     FontWeight downFontWeight;
48     Color upColor;
49     Color currentColor;
50     Color downColor;
51 };
52 
53 struct DatePickerOptionProperty {
54     float height = 0.0f;
55     float fontheight = 0.0f;
56     float prevDistance = 0.0f; // between the prev item and itself when scroll up
57     float nextDistance = 0.0f; // between the next item and itself when scroll down
58 };
59 
60 class DatePickerEventParam : public virtual AceType {
61     DECLARE_ACE_TYPE(DatePickerEventParam, AceType)
62 
63 public:
64     WeakPtr<FrameNode> instance_;
65     int32_t itemIndex_ = 0;
66     int32_t itemTotalCounts_ = 0;
67 };
68 
69 enum class DatePickerScrollDirection {
70     UP = 0,
71     DOWN,
72 };
73 enum class DatePickerOptionIndex {
74     COLUMN_INDEX_0 = 0,
75     COLUMN_INDEX_1,
76     COLUMN_INDEX_2,
77     COLUMN_INDEX_3,
78     COLUMN_INDEX_4,
79     COLUMN_INDEX_5,
80     COLUMN_INDEX_6,
81 };
82 
83 class DatePickerColumnPattern : public LinearLayoutPattern {
84     DECLARE_ACE_TYPE(DatePickerColumnPattern, LinearLayoutPattern);
85 
86 public:
DatePickerColumnPattern()87     DatePickerColumnPattern() : LinearLayoutPattern(true) {};
88 
89     ~DatePickerColumnPattern() override = default;
90 
CreateLayoutAlgorithm()91     RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override
92     {
93         auto layoutAlgorithm = MakeRefPtr<DatePickerColumnLayoutAlgorithm>();
94         if (algorithmOffset_.size() == 0) {
95             ResetAlgorithmOffset();
96         }
97         layoutAlgorithm->SetCurrentOffset(algorithmOffset_);
98         return layoutAlgorithm;
99     }
100 
CreateLayoutProperty()101     RefPtr<LayoutProperty> CreateLayoutProperty() override
102     {
103         return MakeRefPtr<DataPickerLayoutProperty>();
104     }
105 
CreateAccessibilityProperty()106     RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override
107     {
108         return MakeRefPtr<DatePickerColumnAccessibilityProperty>();
109     }
110 
111     void FlushCurrentOptions(
112         bool isDown = false, bool isUpateTextContentOnly = false, bool isUpdateAnimationProperties = false);
113 
114     bool NotLoopOptions() const;
115 
116     void UpdateColumnChildPosition(double offsetY);
117 
118     bool CanMove(bool isDown) const;
119 
120     bool InnerHandleScroll(bool isDown, bool isUpatePropertiesOnly = false, bool isUpdateAnimationProperties = false);
121 
GetCurrentIndex()122     uint32_t GetCurrentIndex() const
123     {
124         // currentIndex_ is year/month/day information, for example month [0, 11] is Equivalent to [1, 12]
125         return currentIndex_;
126     }
127 
SetCurrentIndex(uint32_t value)128     void SetCurrentIndex(uint32_t value)
129     {
130         currentIndex_ = value;
131     }
132 
GetCurrentOffset()133     double GetCurrentOffset() const
134     {
135         return deltaSize_;
136     }
137 
SetCurrentOffset(double deltaSize)138     void SetCurrentOffset(double deltaSize)
139     {
140         deltaSize_ = deltaSize;
141     }
142 
GetOptions()143     const std::map<WeakPtr<FrameNode>, std::vector<PickerDateF>>& GetOptions() const
144     {
145         return options_;
146     }
147 
SetOptions(const std::map<WeakPtr<FrameNode>,std::vector<PickerDateF>> & value)148     void SetOptions(const std::map<WeakPtr<FrameNode>, std::vector<PickerDateF>>& value)
149     {
150         options_ = value;
151     }
152 
GetShowCount()153     uint32_t GetShowCount() const
154     {
155         return showCount_;
156     }
157 
SetShowCount(const uint32_t showCount)158     void SetShowCount(const uint32_t showCount)
159     {
160         showCount_ = showCount;
161     }
162 
HandleChangeCallback(bool isAdd,bool needNotify)163     void HandleChangeCallback(bool isAdd, bool needNotify)
164     {
165         if (changeCallback_) {
166             changeCallback_(GetHost(), isAdd, GetCurrentIndex(), needNotify);
167         }
168     }
169 
GetChangeCallback()170     const ColumnChangeCallback& GetChangeCallback() const
171     {
172         return changeCallback_;
173     }
174 
SetChangeCallback(ColumnChangeCallback && value)175     void SetChangeCallback(ColumnChangeCallback&& value)
176     {
177         changeCallback_ = value;
178     }
179 
HandleEventCallback(bool refresh)180     void HandleEventCallback(bool refresh)
181     {
182         if (EventCallback_) {
183             EventCallback_(refresh);
184         }
185     }
186 
GetEventCallback()187     const EventCallback& GetEventCallback() const
188     {
189         return EventCallback_;
190     }
191 
SetEventCallback(EventCallback && value)192     void SetEventCallback(EventCallback&& value)
193     {
194         EventCallback_ = value;
195     }
196 
GetToss()197     const RefPtr<TossAnimationController>& GetToss() const
198     {
199         return tossAnimationController_;
200     }
201 
SetLocalDownDistance(float value)202     void SetLocalDownDistance(float value)
203     {
204         localDownDistance_ = value;
205     }
206 
GetLocalDownDistance()207     float GetLocalDownDistance() const
208     {
209         return localDownDistance_;
210     }
211 
212     void UpdateToss(double offsetY);
213 
214     void UpdateFinishToss(double offsetY);
215 
216     void TossStoped();
217 
SetYLast(double value)218     void SetYLast(double value)
219     {
220         yLast_ = value;
221     }
GetOffset()222     double GetOffset()
223     {
224         return offsetCurSet_;
225     }
226     void PlayRestAnimation();
227 
228     void TossAnimationStoped();
229 
GetMidShiftDistance()230     std::vector<DatePickerOptionProperty> GetMidShiftDistance()
231     {
232         return optionProperties_;
233     }
234 
SetMainVelocity(double mainVelocity)235     void SetMainVelocity(double mainVelocity)
236     {
237         mainVelocity_ = mainVelocity;
238     }
239 
GetMainVelocity()240     double GetMainVelocity() const
241     {
242         return mainVelocity_;
243     }
244 
SetTossStatus(bool status)245     void SetTossStatus(bool status)
246     {
247         isTossStatus_ = status;
248     }
249 
GetTossStatus()250     bool GetTossStatus()
251     {
252         return isTossStatus_;
253     }
254 
SetYOffset(double value)255     void SetYOffset(double value)
256     {
257         yOffset_ = value;
258     }
259 
GetTouchBreakStatus()260     bool GetTouchBreakStatus()
261     {
262         return touchBreak_;
263     }
264 
GetClickBreakStatus()265     bool GetClickBreakStatus()
266     {
267         return clickBreak_;
268     }
269 
SetclickBreak(bool value)270     void SetclickBreak(bool value)
271     {
272         clickBreak_ = value;
273     }
274 
275 private:
276     void OnModifyDone() override;
277     void OnAttachToFrameNode() override;
278     bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override;
279     void SetDividerHeight(uint32_t showOptionCount);
280     void OnTouchDown();
281     void OnTouchUp();
282     void ParseTouchListener();
283     void ParseMouseEvent();
284     void InitMouseAndPressEvent();
285     void HandleMouseEvent(bool isHover);
286     void SetButtonBackgroundColor(const Color& pressColor);
287     void PlayPressAnimation(const Color& pressColor);
288     void PlayHoverAnimation(const Color& color);
289 
290     std::vector<DatePickerOptionProperty> optionProperties_;
291     RefPtr<ClickEvent> CreateItemClickEventListener(RefPtr<DatePickerEventParam> param);
292     RefPtr<TouchEventImpl> CreateItemTouchEventListener();
293     void OnAroundButtonClick(RefPtr<DatePickerEventParam> param);
294     std::vector<int32_t> algorithmOffset_;
295     void ResetAlgorithmOffset();
296     void CalcAlgorithmOffset(DatePickerScrollDirection dir, double distancePercent);
297     void SetOptionShiftDistance();
298     float GetShiftDistanceForLandscape(uint32_t index, DatePickerScrollDirection dir);
299     float GetShiftDistance(uint32_t index, DatePickerScrollDirection dir);
300     int32_t CalcScrollIndex(int32_t totalOptionCount, int32_t currentIndex, bool canLoop, int32_t step);
301     void ShiftOptionProp(RefPtr<FrameNode> curNode, RefPtr<FrameNode> shiftNode);
302 
303     void InitPanEvent(const RefPtr<GestureEventHub>& gestureHub);
304     void HandleDragStart(const GestureEvent& event);
305     void HandleDragMove(const GestureEvent& event);
306     void HandleDragEnd();
307     void CreateAnimation();
308     void CreateAnimation(double from, double to);
309     void ScrollOption(double delta, bool isJump = false);
310     void UpdatePickerTextProperties(uint32_t index, uint32_t showOptionCount,
311         const RefPtr<TextLayoutProperty>& textLayoutProperty,
312         const RefPtr<DataPickerRowLayoutProperty>& dataPickerRowLayoutProperty);
313     void UpdateDisappearTextProperties(const RefPtr<PickerTheme>& pickerTheme,
314         const RefPtr<TextLayoutProperty>& textLayoutProperty,
315         const RefPtr<DataPickerRowLayoutProperty>& timePickerLayoutProperty);
316     void UpdateCandidateTextProperties(const RefPtr<PickerTheme>& pickerTheme,
317         const RefPtr<TextLayoutProperty>& textLayoutProperty,
318         const RefPtr<DataPickerRowLayoutProperty>& timePickerLayoutProperty);
319     void UpdateSelectedTextProperties(const RefPtr<PickerTheme>& pickerTheme,
320         const RefPtr<TextLayoutProperty>& textLayoutProperty,
321         const RefPtr<DataPickerRowLayoutProperty>& timePickerLayoutProperty);
322     void AddAnimationTextProperties(uint32_t currentIndex, const RefPtr<TextLayoutProperty>& textLayoutProperty);
323     void UpdateTextPropertiesLinear(bool isDown, double scale);
324     void TextPropertiesLinearAnimation(const RefPtr<TextLayoutProperty>& textLayoutProperty, uint32_t index,
325         uint32_t showCount, bool isDown, double scale);
326     void FlushAnimationTextProperties(bool isDown);
327     Dimension LinearFontSize(const Dimension& startFontSize, const Dimension& endFontSize, double percent);
328     void SetAccessibilityAction();
329     DimensionRect CalculateHotZone(int32_t index, int32_t midSize, float middleChildHeight, float otherChildHeight);
330     void AddHotZoneRectToText();
331     void InitTextFontFamily();
332 
333     float localDownDistance_ = 0.0f;
334     RefPtr<TouchEventImpl> touchListener_;
335     RefPtr<InputEvent> mouseEvent_;
336     std::map<WeakPtr<FrameNode>, std::vector<PickerDateF>> options_;
337     ColumnChangeCallback changeCallback_;
338     EventCallback EventCallback_;
339     uint32_t currentIndex_ = 0;
340     int32_t currentChildIndex_ = 0;
341     double yLast_ = 0.0;
342     double yOffset_ = 0.0;
343     double jumpInterval_ = 0.0;
344     uint32_t showCount_ = 0;
345     float gradientHeight_ = 0.0f;
346     float dividerHeight_ = 0.0f;
347     float dividerSpacingWidth_ = 0.0f;
348     double mainVelocity_ = 0.0;
349     float dividerSpacing_ = 0.0f;
350     FontWeight SelectedWeight_ = FontWeight::MEDIUM;
351     FontWeight CandidateWeight_ = FontWeight::REGULAR;
352     double offsetCurSet_ = 0.0;
353     double distancePercent_ = 0.0;
354     Color pressColor_;
355     Color hoverColor_;
356     bool isTossStatus_ = false;
357     bool clickBreak_ = false;
358     bool touchBreak_ = false;
359     bool animationBreak_ = false;
360     double deltaSize_ = 0.0;
361     RefPtr<PanEvent> panEvent_;
362     bool pressed_ = false;
363     bool hoverd_ = false;
364     double scrollDelta_ = 0.0;
365     bool animationCreated_ = false;
366     OffsetF offset_;
367     SizeF size_;
368     RefPtr<TossAnimationController> tossAnimationController_ = AceType::MakeRefPtr<TossAnimationController>();
369     std::vector<DateTextProperties> animationProperties_;
370 
371     RefPtr<NodeAnimatablePropertyFloat> scrollProperty_;
372     RefPtr<NodeAnimatablePropertyFloat> aroundClickProperty_;
373     std::shared_ptr<AnimationUtils::Animation> animation_;
374 
375     bool hasAppCustomFont_ = false;
376     bool hasUserDefinedDisappearFontFamily_ = false;
377     bool hasUserDefinedNormalFontFamily_ = false;
378     bool hasUserDefinedSelectedFontFamily_ = false;
379 
380     ACE_DISALLOW_COPY_AND_MOVE(DatePickerColumnPattern);
381 };
382 } // namespace OHOS::Ace::NG
383 
384 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_DATE_PICKER_DATE_PICKER_COLUMN_PATTERN_H
385