• 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_TIME_PICKER_TIME_PICKER_COLUMN_PATTERN_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TIME_PICKER_TIME_PICKER_COLUMN_PATTERN_H
18 
19 #include <utility>
20 
21 #include "adapter/ohos/entrance/picker/picker_haptic_interface.h"
22 #include "base/i18n/localization.h"
23 #include "core/components/common/properties/color.h"
24 #include "core/components/picker/picker_base_component.h"
25 #include "core/components/picker/picker_date_component.h"
26 #include "core/components_ng/base/frame_node.h"
27 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
28 #include "core/components_ng/pattern/text/text_layout_property.h"
29 #include "core/components_ng/pattern/time_picker/timepicker_column_accessibility_property.h"
30 #include "core/components_ng/pattern/time_picker/timepicker_column_layout_algorithm.h"
31 #include "core/components_ng/pattern/time_picker/timepicker_layout_property.h"
32 #include "core/components_ng/pattern/time_picker/toss_animation_controller.h"
33 #include "core/components_ng/pattern/picker_utils/picker_column_pattern_utils.h"
34 #ifdef SUPPORT_DIGITAL_CROWN
35 #include "core/event/crown_event.h"
36 #endif
37 
38 namespace OHOS::Ace::NG {
39 
40 using ColumnChangeCallback = std::function<void(const RefPtr<FrameNode>&, bool, uint32_t, bool)>;
41 using ColumnFinishCallback = std::function<void(bool)>;
42 using EventCallback = std::function<void(bool)>;
43 
44 struct TimeTextProperties {
45     Dimension upFontSize;
46     Dimension fontSize;
47     Dimension downFontSize;
48     FontWeight upFontWeight;
49     FontWeight fontWeight;
50     FontWeight downFontWeight;
51     Color upColor;
52     Color currentColor;
53     Color downColor;
54 };
55 
56 struct TimePickerOptionProperty {
57     float height = 0.0f;
58     float fontheight = 0.0f;
59     float prevDistance = 0.0f; // between the prev item and itself when scroll up
60     float nextDistance = 0.0f; // between the next item and itself when scroll down
61 };
62 
63 class TimePickerEventParam : public virtual AceType {
64     DECLARE_ACE_TYPE(TimePickerEventParam, AceType)
65 
66 public:
67     WeakPtr<FrameNode> instance_;
68     int32_t itemIndex_ = 0;
69     int32_t itemTotalCounts_ = 0;
70 };
71 
72 enum class TimePickerScrollDirection {
73     UP = 0,
74     DOWN,
75 };
76 enum class TimePickerOptionIndex {
77     COLUMN_INDEX_0 = 0,
78     COLUMN_INDEX_1,
79     COLUMN_INDEX_2,
80     COLUMN_INDEX_3,
81     COLUMN_INDEX_4,
82     COLUMN_INDEX_5,
83     COLUMN_INDEX_6,
84 };
85 
86 class TimePickerColumnPattern : public LinearLayoutPattern {
87     DECLARE_ACE_TYPE(TimePickerColumnPattern, LinearLayoutPattern);
88 
89 public:
TimePickerColumnPattern()90     TimePickerColumnPattern() : LinearLayoutPattern(true) {};
~TimePickerColumnPattern()91     ~TimePickerColumnPattern() override
92     {
93         if (circleUtils_) {
94             delete circleUtils_;
95         }
96     }
97 
CreateLayoutAlgorithm()98     RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override
99     {
100         auto layoutAlgorithm = MakeRefPtr<TimePickerColumnLayoutAlgorithm>();
101         if (algorithmOffset_.size() == 0) {
102             ResetAlgorithmOffset();
103         }
104         layoutAlgorithm->SetCurrentOffset(algorithmOffset_);
105         return layoutAlgorithm;
106     }
107 
CreateLayoutProperty()108     RefPtr<LayoutProperty> CreateLayoutProperty() override
109     {
110         return MakeRefPtr<LinearLayoutProperty>(isVertical_);
111     }
112 
CreateAccessibilityProperty()113     RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override
114     {
115         return MakeRefPtr<TimePickerColumnAccessibilityProperty>();
116     }
117 
118     void FlushCurrentOptions(bool isDown = false, bool isUpateTextContentOnly = false);
119 
120     bool NotLoopOptions() const;
121 
122     void UpdateColumnChildPosition(double offsetY);
123 
124     bool CanMove(bool isDown) const;
125 
126     bool InnerHandleScroll(bool isDown, bool isUpatePropertiesOnly = false);
127 
128     void ScrollTimeColumn();
129 
130     void UpdateCurrentOffset(float offset);
131 
GetCurrentIndex()132     uint32_t GetCurrentIndex() const
133     {
134         return currentIndex_;
135     }
136 
SetCurrentIndex(uint32_t value)137     void SetCurrentIndex(uint32_t value)
138     {
139         // minute : [0, 59];
140         // AM_PM hour : [0, 11]; 24 hour : [0, 23]
141         currentIndex_ = value;
142     }
143 
GetCurrentOffset()144     float GetCurrentOffset() const
145     {
146         return deltaSize_;
147     }
148 
SetCurrentOffset(float deltaSize)149     void SetCurrentOffset(float deltaSize)
150     {
151         deltaSize_ = deltaSize;
152     }
153 
GetOptions()154     const std::map<WeakPtr<FrameNode>, uint32_t>& GetOptions() const
155     {
156         return optionsTotalCount_;
157     }
158 
SetOptions(const std::map<WeakPtr<FrameNode>,uint32_t> & value)159     void SetOptions(const std::map<WeakPtr<FrameNode>, uint32_t>& value)
160     {
161         optionsTotalCount_ = value;
162     }
163 
GetShowCount()164     uint32_t GetShowCount() const
165     {
166         return showCount_;
167     }
168 
SetShowCount(const uint32_t showCount)169     void SetShowCount(const uint32_t showCount)
170     {
171         showCount_ = showCount;
172         GetHost()->MarkModifyDone();
173     }
174 
HandleChangeCallback(bool isAdd,bool needNotify)175     void HandleChangeCallback(bool isAdd, bool needNotify)
176     {
177         if (changeCallback_) {
178             changeCallback_(GetHost(), isAdd, GetCurrentIndex(), needNotify);
179         }
180     }
181 
GetChangeCallback()182     const ColumnChangeCallback& GetChangeCallback() const
183     {
184         return changeCallback_;
185     }
186 
SetChangeCallback(ColumnChangeCallback && value)187     void SetChangeCallback(ColumnChangeCallback&& value)
188     {
189         changeCallback_ = value;
190     }
191 
HandleEventCallback(bool refresh)192     void HandleEventCallback(bool refresh)
193     {
194         if (EventCallback_) {
195             EventCallback_(refresh);
196         }
197     }
198 
GetEventCallback()199     const EventCallback& GetEventCallback() const
200     {
201         return EventCallback_;
202     }
203 
SetEventCallback(EventCallback && value)204     void SetEventCallback(EventCallback&& value)
205     {
206         EventCallback_ = value;
207     }
208 
GetFocusPattern()209     FocusPattern GetFocusPattern() const override
210     {
211         return { FocusType::NODE, true };
212     }
213 
SetHour24(bool value)214     void SetHour24(bool value)
215     {
216         hour24_ = value;
217     }
218 
GetHour24()219     bool GetHour24() const
220     {
221         return hour24_;
222     }
223 
GetWheelModeEnabled()224     bool GetWheelModeEnabled() const
225     {
226         return wheelModeEnabled_;
227     }
228 
SetWheelModeEnabled(bool value)229     void SetWheelModeEnabled(bool value)
230     {
231         wheelModeEnabled_ = value;
232     }
233 
GetToss()234     const RefPtr<TimePickerTossAnimationController>& GetToss() const
235     {
236         return tossAnimationController_;
237     }
238 
SetLocalDownDistance(float value)239     void SetLocalDownDistance(float value)
240     {
241         localDownDistance_ = value;
242     }
243 
GetLocalDownDistance()244     float GetLocalDownDistance() const
245     {
246         return localDownDistance_;
247     }
248 
249     void UpdateToss(double offsetY);
250 
251     void UpdateFinishToss(double offsetY);
252 
253     void TossStoped();
254 
255     void UpdateScrollDelta(double delta);
256 
SetYLast(double value)257     void SetYLast(double value)
258     {
259         yLast_ = value;
260     }
GetOffset()261     double GetOffset()
262     {
263         return offsetCurSet_;
264     }
265     void PlayRestAnimation();
266 
267     void TossAnimationStoped();
268 
GetMidShiftDistance()269     std::vector<TimePickerOptionProperty> GetMidShiftDistance()
270     {
271         return optionProperties_;
272     }
273 
SetMainVelocity(double mainVelocity)274     void SetMainVelocity(double mainVelocity)
275     {
276         mainVelocity_ = mainVelocity;
277     }
278 
GetMainVelocity()279     double GetMainVelocity() const
280     {
281         return mainVelocity_;
282     }
283 
SetTossStatus(bool status)284     void SetTossStatus(bool status)
285     {
286         isTossStatus_ = status;
287     }
288 
GetTossStatus()289     bool GetTossStatus()
290     {
291         return isTossStatus_;
292     }
293 
SetYOffset(double value)294     void SetYOffset(double value)
295     {
296         yOffset_ = value;
297     }
298 
GetTouchBreakStatus()299     bool GetTouchBreakStatus()
300     {
301         return touchBreak_;
302     }
303 
GetClickBreakStatus()304     bool GetClickBreakStatus()
305     {
306         return clickBreak_;
307     }
308 
SetclickBreak(bool value)309     void SetclickBreak(bool value)
310     {
311         clickBreak_ = value;
312     }
313 
314     void InitHapticController(const RefPtr<FrameNode>& host);
315     bool IsStartEndTimeDefined();
316 
317     void StopHaptic();
GetEnterIndex()318     uint32_t GetEnterIndex() const
319     {
320         return currentEnterIndex_;
321     }
322 
SetEnterIndex(uint32_t value)323     void SetEnterIndex(uint32_t value)
324     {
325         if (value != currentEnterIndex_) {
326             currentEnterIndex_ = value;
327         }
328     }
329 
HandleEnterSelectedAreaEventCallback(bool refresh)330     void HandleEnterSelectedAreaEventCallback(bool refresh)
331     {
332         if (enterSelectedAreaEventCallback_) {
333             enterSelectedAreaEventCallback_(refresh);
334         }
335     }
336 
GetEnterSelectedAreaEventCallback()337     const EventCallback& GetEnterSelectedAreaEventCallback() const
338     {
339         return enterSelectedAreaEventCallback_;
340     }
341 
SetEnterSelectedAreaEventCallback(EventCallback && value)342     void SetEnterSelectedAreaEventCallback(EventCallback&& value)
343     {
344         enterSelectedAreaEventCallback_ = value;
345     }
346 
347     void SetSelectedMarkListener(const std::function<void(const std::string& selectedColumnId)>& listener);
348     void SetSelectedMark(bool focus = true, bool notify = true, bool reRender = true);
349     void SetSelectedMarkId(const std::string &strColumnId);
350     void UpdateUserSetSelectColor();
351 #ifdef SUPPORT_DIGITAL_CROWN
352     std::string& GetSelectedColumnId();
353     bool IsCrownEventEnded();
354     int32_t GetDigitalCrownSensitivity();
355     void SetDigitalCrownSensitivity(int32_t crownSensitivity);
356     bool OnCrownEvent(const CrownEvent& event);
357 #endif
358 
359 private:
360     void OnModifyDone() override;
361     void OnAttachToFrameNode() override;
362     void OnDetachFromFrameNode(FrameNode* frameNode) override;
363     bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override;
364     void SetDividerHeight(uint32_t showOptionCount);
365     void ChangeTextStyle(uint32_t index, uint32_t showOptionCount, const RefPtr<TextLayoutProperty>& textLayoutProperty,
366         const RefPtr<TimePickerLayoutProperty>& timePickerLayoutProperty);
367     void ChangeAmPmTextStyle(uint32_t index, uint32_t showOptionCount,
368         const RefPtr<TextLayoutProperty>& textLayoutProperty,
369         const RefPtr<TimePickerLayoutProperty>& timePickerLayoutProperty);
370 
371     void InitOnKeyEvent(const RefPtr<FocusHub>& focusHub);
372     bool OnKeyEvent(const KeyEvent& event);
373     bool HandleDirectionKey(KeyCode code);
374     void SetSelectedMarkPaint(bool paint);
375     void UpdateSelectedTextColor(const RefPtr<PickerTheme>& pickerTheme);
376     void GetAnimationColor(uint32_t index, uint32_t showCount, Color& color, bool selectedMark = false);
377     void UpdateAnimationColor(const RefPtr<PickerTheme>& pickerTheme);
378 #ifdef SUPPORT_DIGITAL_CROWN
379     void HandleCrownBeginEvent(const CrownEvent& event);
380     void HandleCrownMoveEvent(const CrownEvent& event);
381     void HandleCrownEndEvent(const CrownEvent& event);
382 #endif
383     RefPtr<TouchEventImpl> CreateItemTouchEventListener();
384     void InitPanEvent(const RefPtr<GestureEventHub>& gestureHub);
385     void HandleDragStart(const GestureEvent& event);
386     void HandleDragMove(const GestureEvent& event);
387     void HandleDragEnd();
388     void CreateAnimation();
389     void CreateAnimation(double from, double to);
390     void ScrollOption(double delta, bool isJump = false);
391 
392     std::vector<TimePickerOptionProperty> optionProperties_;
393     RefPtr<ClickEvent> CreateItemClickEventListener(RefPtr<TimePickerEventParam> param);
394     void OnAroundButtonClick(RefPtr<TimePickerEventParam> param);
395     std::vector<int32_t> algorithmOffset_;
396     void ResetAlgorithmOffset();
397     void CalcAlgorithmOffset(TimePickerScrollDirection dir, double distancePercent);
398     void SetOptionShiftDistance();
399     float GetShiftDistanceForLandscape(uint32_t index, TimePickerScrollDirection dir);
400     float GetShiftDistance(uint32_t index, TimePickerScrollDirection dir);
401     void ShiftOptionProp(RefPtr<FrameNode> curNode, RefPtr<FrameNode> shiftNode);
402 
403     void OnTouchDown();
404     void OnTouchUp();
405     void ParseTouchListener();
406     void ParseMouseEvent();
407     void InitMouseAndPressEvent();
408     void HandleMouseEvent(bool isHover);
409     void SetButtonBackgroundColor(const Color& pressColor);
410     void PlayPressAnimation(const Color& pressColor);
411     void PlayHoverAnimation(const Color& color);
412     void UpdateDisappearTextProperties(const RefPtr<PickerTheme>& pickerTheme,
413         const RefPtr<TextLayoutProperty>& textLayoutProperty,
414         const RefPtr<TimePickerLayoutProperty>& timePickerLayoutProperty);
415     void UpdateCandidateTextProperties(const RefPtr<PickerTheme>& pickerTheme,
416         const RefPtr<TextLayoutProperty>& textLayoutProperty,
417         const RefPtr<TimePickerLayoutProperty>& timePickerLayoutProperty);
418     void UpdateSelectedTextProperties(const RefPtr<PickerTheme>& pickerTheme,
419         const RefPtr<TextLayoutProperty>& textLayoutProperty,
420         const RefPtr<TimePickerLayoutProperty>& timePickerLayoutProperty);
421     void AddAnimationTextProperties(uint32_t currentIndex, const RefPtr<TextLayoutProperty>& textLayoutProperty);
422     void UpdateTextPropertiesLinear(bool isDown, double scale);
423     void TextPropertiesLinearAnimation(const RefPtr<TextLayoutProperty>& textLayoutProperty, uint32_t index,
424         uint32_t showCount, bool isDown, double scale);
425     void FlushAnimationTextProperties(bool isDown);
426     Dimension LinearFontSize(const Dimension& startFontSize, const Dimension& endFontSize, double percent);
427     void SetAccessibilityAction();
428     DimensionRect CalculateHotZone(int32_t index, int32_t midSize, float middleChildHeight, float otherChildHeight);
429     void AddHotZoneRectToText();
430     void InitTextFontFamily();
431     void RegisterWindowStateChangedCallback();
432     void UnregisterWindowStateChangedCallback(FrameNode* frameNode);
433     void OnWindowHide() override;
434     void OnWindowShow() override;
435 
436     void HandleEnterSelectedArea(double scrollDelta, float shiftDistance, TimePickerScrollDirection dir);
437 
438     double mainVelocity_ = 0.0;
439     float localDownDistance_ = 0.0f;
440     Color pressColor_;
441     Color hoverColor_;
442     FontWeight SelectedWeight_ = FontWeight::MEDIUM;
443     FontWeight DisappearWeight_ = FontWeight::REGULAR;
444     RefPtr<TouchEventImpl> touchListener_;
445     RefPtr<InputEvent> mouseEvent_;
446     bool hour24_ = SystemProperties::Is24HourClock();
447     // column options number
448     std::map<WeakPtr<FrameNode>, uint32_t> optionsTotalCount_;
449     ColumnChangeCallback changeCallback_;
450     EventCallback EventCallback_;
451     EventCallback enterSelectedAreaEventCallback_;
452     uint32_t currentIndex_ = 0;
453     uint32_t currentEnterIndex_ = 0;
454     double yLast_ = 0.0;
455     double yOffset_ = 0.0;
456     double jumpInterval_ = 0.0;
457     uint32_t showCount_ = 0;
458     bool isVertical_ = true;
459     float gradientHeight_ = 0.0f;
460     float dividerHeight_ = 0.0f;
461     float dividerSpacingWidth_ = 0.0f;
462     double distancePercent_ = 0.0;
463     double offsetCurSet_ = 0.0;
464     bool isTossStatus_ = false;
465     bool clickBreak_ = false;
466     bool touchBreak_ = false;
467     bool animationBreak_ = false;
468     float deltaSize_ = 0.0f;
469     RefPtr<PanEvent> panEvent_;
470     bool pressed_ = false;
471     bool hoverd_ = false;
472     bool wheelModeEnabled_ = true;
473     double scrollDelta_ = 0.0;
474     double enterDelta_ = 0.0;
475     bool animationCreated_ = false;
476     OffsetF offset_;
477     SizeF size_;
478     RefPtr<TimePickerTossAnimationController> tossAnimationController_ =
479         AceType::MakeRefPtr<TimePickerTossAnimationController>();
480     RefPtr<NodeAnimatablePropertyFloat> scrollProperty_;
481     RefPtr<NodeAnimatablePropertyFloat> aroundClickProperty_;
482     std::shared_ptr<AnimationUtils::Animation> animation_;
483     std::vector<TimeTextProperties> animationProperties_;
484     float dividerSpacing_ = 0.0f;
485 
486     bool hasAppCustomFont_ = false;
487     bool hasUserDefinedDisappearFontFamily_ = false;
488     bool hasUserDefinedNormalFontFamily_ = false;
489     bool hasUserDefinedSelectedFontFamily_ = false;
490     bool isShow_ = true;
491     bool isEnableHaptic_ = true;
492     bool stopHaptic_ = false;
493     bool isTossReadyToStop_ = false;
494 
495     std::shared_ptr<IPickerAudioHaptic> hapticController_ = nullptr;
496     ACE_DISALLOW_COPY_AND_MOVE(TimePickerColumnPattern);
497 
498     friend class PickerColumnPatternCircleUtils<TimePickerColumnPattern>;
499     PickerColumnPatternCircleUtils<TimePickerColumnPattern> *circleUtils_ = nullptr;
500     std::string selectedColumnId_ = "";
501     bool selectedMarkPaint_ = false;
502     std::function<void(std::string& selectedColumnId)> focusedListerner_ = nullptr;
503     bool isUserSetSelectColor_ = false;
504 #ifdef SUPPORT_DIGITAL_CROWN
505     bool isCrownEventEnded_ = true;
506     int32_t crownSensitivity_ = INVALID_CROWNSENSITIVITY;
507 #endif
508 };
509 } // namespace OHOS::Ace::NG
510 
511 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TIME_PICKER_TIME_PICKER_COLUMN_PATTERN_H
512