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