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