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