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_paint_method.h" 31 #include "core/components_ng/pattern/text_picker/toss_animation_controller.h" 32 33 namespace OHOS::Ace::NG { 34 using EventCallback = std::function<void(bool)>; 35 using ColumnChangeCallback = std::function<void(const RefPtr<FrameNode>&, bool, uint32_t, bool)>; 36 37 struct TextProperties { 38 Dimension upFontSize; 39 Dimension fontSize; 40 Dimension downFontSize; 41 Color upColor; 42 Color currentColor; 43 Color downColor; 44 }; 45 46 struct TextPickerOptionProperty { 47 float height = 0.0f; 48 float fontheight = 0.0f; 49 float prevDistance = 0.0f; // between the prev item and itself when scroll up 50 float nextDistance = 0.0f; // between the next item and itself when scroll down 51 }; 52 53 class EventParam : public virtual AceType { 54 DECLARE_ACE_TYPE(EventParam, AceType) 55 56 public: 57 RefPtr<FrameNode> instance; 58 int32_t itemIndex; 59 int32_t itemTotalCounts; 60 }; 61 62 enum class ScrollDirection { 63 UP = 0, 64 DOWN, 65 }; 66 67 enum class OptionIndex { COLUMN_INDEX_0 = 0, COLUMN_INDEX_1, COLUMN_INDEX_2, COLUMN_INDEX_3, COLUMN_INDEX_4 }; 68 69 class TextPickerColumnPattern : public LinearLayoutPattern { 70 DECLARE_ACE_TYPE(TextPickerColumnPattern, LinearLayoutPattern); 71 72 public: TextPickerColumnPattern()73 TextPickerColumnPattern() : LinearLayoutPattern(true) {}; 74 75 ~TextPickerColumnPattern() override = default; 76 IsAtomicNode()77 bool IsAtomicNode() const override 78 { 79 return true; 80 } 81 CreateLayoutAlgorithm()82 RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override 83 { 84 auto layoutAlgorithm = MakeRefPtr<TextPickerLayoutAlgorithm>(); 85 if (algorithmOffset_.size() == 0) { 86 ResetAlgorithmOffset(); 87 } 88 layoutAlgorithm->SetCurrentOffset(algorithmOffset_); 89 layoutAlgorithm->SetDefaultPickerItemHeight(defaultPickerItemHeight_); 90 return layoutAlgorithm; 91 } 92 CreateLayoutProperty()93 RefPtr<LayoutProperty> CreateLayoutProperty() override 94 { 95 return MakeRefPtr<LinearLayoutProperty>(true); 96 } 97 98 void FlushCurrentOptions(bool isDown = false, bool isUpateTextContentOnly = false, bool isDirectlyClear = false); 99 100 void InitilaScorllEvent(); 101 102 void UpdateCurrentOffset(float offset); 103 104 void UpdateColumnChildPosition(double offsetY, bool isUpatePropertiesOnly = true); 105 106 bool CanMove(bool isDown) const; 107 108 bool NotLoopOptions() const; 109 110 bool InnerHandleScroll(int32_t step, bool isUpatePropertiesOnly = false); 111 SetDefaultPickerItemHeight(double defaultPickerItemHeight)112 void SetDefaultPickerItemHeight(double defaultPickerItemHeight) 113 { 114 defaultPickerItemHeight_ = defaultPickerItemHeight; 115 } 116 117 uint32_t GetShowOptionCount() const; 118 119 std::string GetSelectedObject(bool isColumnChange, int32_t status = 0) const; 120 SetSelected(uint32_t value)121 void SetSelected(uint32_t value) 122 { 123 selectedIndex_ = value; 124 } GetSelected()125 uint32_t GetSelected() const 126 { 127 return selectedIndex_; 128 } 129 SetRange(const std::vector<std::string> & value)130 void SetRange(const std::vector<std::string>& value) 131 { 132 if (value.empty()) { 133 LOGE("input value of range is empty."); 134 return; 135 } 136 range_ = value; 137 } 138 GetRange()139 const std::vector<std::string>& GetRange() const 140 { 141 return range_; 142 } 143 GetCurrentText()144 std::string GetCurrentText() const 145 { 146 return GetOption(GetCurrentIndex()); 147 } 148 GetCurrentIndex()149 uint32_t GetCurrentIndex() const 150 { 151 return currentIndex_; 152 } SetCurrentIndex(uint32_t value)153 void SetCurrentIndex(uint32_t value) 154 { 155 if (value != currentIndex_) { 156 isIndexChanged_ = true; 157 currentIndex_ = value; 158 } 159 } 160 GetOptionCount()161 uint32_t GetOptionCount() const 162 { 163 return options_.size(); 164 } 165 GetOption(uint32_t index)166 std::string GetOption(uint32_t index) const 167 { 168 if (index >= GetOptionCount()) { 169 LOGE("index out of range."); 170 return ""; 171 } 172 return options_[index].text_; 173 } 174 SetOptions(std::vector<NG::RangeContent> & value)175 void SetOptions(std::vector<NG::RangeContent>& value) 176 { 177 options_.clear(); 178 for (auto& content : value) { 179 options_.emplace_back(content); 180 } 181 } 182 ClearOptions()183 void ClearOptions() 184 { 185 options_.clear(); 186 } 187 SetColumnKind(int32_t kind)188 void SetColumnKind(int32_t kind) 189 { 190 columnkind_ = kind; 191 } 192 GetCurrentOffset()193 float GetCurrentOffset() const 194 { 195 return deltaSize_; 196 } 197 SetCurrentOffset(float deltaSize)198 void SetCurrentOffset(float deltaSize) 199 { 200 deltaSize_ = deltaSize; 201 } 202 GetToss()203 const RefPtr<TextPickerTossAnimationController>& GetToss() const 204 { 205 return tossAnimationController_; 206 } 207 HandleEventCallback(bool refresh)208 void HandleEventCallback(bool refresh) 209 { 210 if (EventCallback_) { 211 EventCallback_(refresh); 212 } else { 213 LOGE("event callback is null."); 214 } 215 } 216 GetEventCallback()217 const EventCallback& GetEventCallback() const 218 { 219 return EventCallback_; 220 } 221 SetEventCallback(EventCallback && value)222 void SetEventCallback(EventCallback&& value) 223 { 224 EventCallback_ = value; 225 } 226 SetLocalDownDistance(float value)227 void SetLocalDownDistance(float value) 228 { 229 localDownDistance_ = value; 230 } 231 GetLocalDownDistance()232 float GetLocalDownDistance() const 233 { 234 return localDownDistance_; 235 } 236 237 void UpdateToss(double offsetY); 238 239 void TossStoped(); 240 241 void UpdateScrollDelta(double delta); 242 CreateAccessibilityProperty()243 RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override 244 { 245 return MakeRefPtr<TextPickerAccessibilityProperty>(); 246 } 247 SetChangeCallback(ColumnChangeCallback && value)248 void SetChangeCallback(ColumnChangeCallback&& value) 249 { 250 changeCallback_ = value; 251 } 252 HandleChangeCallback(bool isAdd,bool needNotify)253 void HandleChangeCallback(bool isAdd, bool needNotify) 254 { 255 if (changeCallback_) { 256 changeCallback_(GetHost(), isAdd, GetCurrentIndex(), needNotify); 257 } else { 258 LOGE("change callback is null."); 259 } 260 } 261 GetHalfDisplayCounts()262 int32_t GetHalfDisplayCounts() const 263 { 264 return halfDisplayCounts_; 265 } 266 267 private: 268 void OnModifyDone() override; 269 void OnAttachToFrameNode() override; 270 bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override; 271 272 bool OnKeyEvent(const KeyEvent& event); 273 bool HandleDirectionKey(KeyCode code); 274 275 void InitPanEvent(const RefPtr<GestureEventHub>& gestureHub); 276 void HandleDragStart(const GestureEvent& event); 277 void HandleDragMove(const GestureEvent& event); 278 void HandleDragEnd(); 279 void CreateAnimation(); 280 RefPtr<CurveAnimation<double>> CreateAnimation(double from, double to); 281 void HandleCurveStopped(); 282 void ScrollOption(double delta); 283 std::vector<TextPickerOptionProperty> optionProperties_; 284 std::vector<int32_t> algorithmOffset_; 285 void ResetAlgorithmOffset(); 286 void CalcAlgorithmOffset(ScrollDirection dir, double distancePercent); 287 void SetOptionShiftDistance(); 288 double GetShiftDistanceForLandscape(int32_t index, ScrollDirection dir); 289 double GetShiftDistance(int32_t index, ScrollDirection dir); 290 void OnTouchDown(); 291 void OnTouchUp(); 292 void InitMouseAndPressEvent(); 293 void HandleMouseEvent(bool isHover); 294 void SetButtonBackgroundColor(const Color& pressColor); 295 void PlayPressAnimation(const Color& pressColor); 296 void FlushCurrentTextOptions(const RefPtr<TextPickerLayoutProperty>& textPickerLayoutProperty, 297 bool isUpateTextContentOnly, bool isDirectlyClear); 298 void FlushCurrentImageOptions(); 299 void FlushCurrentMixtureOptions( 300 const RefPtr<TextPickerLayoutProperty>& textPickerLayoutProperty, bool isUpateTextContentOnly); 301 void UpdatePickerTextProperties(const RefPtr<TextLayoutProperty>& textLayoutProperty, 302 const RefPtr<TextPickerLayoutProperty>& textPickerLayoutProperty, uint32_t currentIndex, uint32_t middleIndex, 303 uint32_t showCount); 304 void UpdateSelectedTextProperties(const RefPtr<PickerTheme>& pickerTheme, 305 const RefPtr<TextLayoutProperty>& textLayoutProperty, 306 const RefPtr<TextPickerLayoutProperty>& textPickerLayoutProperty); 307 void UpdateCandidateTextProperties(const RefPtr<PickerTheme>& pickerTheme, 308 const RefPtr<TextLayoutProperty>& textLayoutProperty, 309 const RefPtr<TextPickerLayoutProperty>& textPickerLayoutProperty); 310 void UpdateDisappearTextProperties(const RefPtr<PickerTheme>& pickerTheme, 311 const RefPtr<TextLayoutProperty>& textLayoutProperty, 312 const RefPtr<TextPickerLayoutProperty>& textPickerLayoutProperty); 313 void AddAnimationTextProperties(uint32_t currentIndex, const RefPtr<TextLayoutProperty>& textLayoutProperty); 314 void UpdateTextPropertiesLinear(bool isDown, double scale); 315 void TextPropertiesLinearAnimation(const RefPtr<TextLayoutProperty>& textLayoutProperty, uint32_t index, 316 uint32_t showCount, bool isDown, double scale); 317 void FlushAnimationTextProperties(bool isDown); 318 Dimension LinearFontSize(const Dimension& startFontSize, const Dimension& endFontSize, double percent); 319 void ClearCurrentTextOptions(const RefPtr<TextPickerLayoutProperty>& textPickerLayoutProperty, 320 bool isUpateTextContentOnly, bool isDirectlyClear); 321 322 RefPtr<TextPickerLayoutProperty> GetParentLayout() const; 323 RefPtr<TouchEventImpl> CreateItemTouchEventListener(RefPtr<EventParam> param); 324 void OnAroundButtonClick(RefPtr<EventParam> param); 325 void OnMiddleButtonTouchDown(RefPtr<EventParam> param); 326 void OnMiddleButtonTouchMove(RefPtr<EventParam> param); 327 void OnMiddleButtonTouchUp(RefPtr<EventParam> param); 328 int32_t GetMiddleButtonIndex(); 329 330 bool touchEventInit_ = false; 331 RefPtr<InputEvent> CreateMouseHoverEventListener(RefPtr<EventParam> param); 332 RefPtr<ClickEvent> CreateItemClickEventListener(RefPtr<EventParam> param); 333 void SetAccessibilityAction(); 334 335 float localDownDistance_ = 0.0f; 336 Color pressColor_; 337 Color hoverColor_; 338 EventCallback EventCallback_; 339 RefPtr<ClickEvent> clickEventListener_; 340 bool enabled_ = true; 341 int32_t focusKeyID_ = 0; 342 RefPtr<TouchEventImpl> touchListener_; 343 bool isPress_ = false; 344 bool isHover_ = false; 345 RefPtr<InputEvent> mouseEvent_; 346 double defaultPickerItemHeight_; 347 uint32_t selectedIndex_ = 0; 348 std::string selectedValue_; 349 std::vector<std::string> range_ { "" }; 350 uint32_t currentIndex_ = 0; 351 std::vector<NG::RangeContent> options_; 352 int32_t columnkind_; 353 int32_t currentChildIndex_ = 0; 354 float deltaSize_ = 0.0f; 355 double yLast_ = 0.0; 356 double yOffset_ = 0.0; 357 double jumpInterval_; 358 Size optionSize_; 359 Dimension fixHeight_; 360 bool isIndexChanged_ = false; 361 362 RefPtr<PanEvent> panEvent_; 363 bool pressed_ = false; 364 double scrollDelta_ = 0.0; 365 bool animationCreated_ = false; 366 RefPtr<Animator> toController_; 367 RefPtr<Animator> fromController_; 368 RefPtr<CurveAnimation<double>> fromBottomCurve_; 369 RefPtr<CurveAnimation<double>> fromTopCurve_; 370 RefPtr<TextPickerTossAnimationController> tossAnimationController_ = 371 AceType::MakeRefPtr<TextPickerTossAnimationController>(); 372 std::vector<TextProperties> animationProperties_; 373 float dividerSpacing_ = 0.0f; 374 float gradientHeight_ = 0.0f; 375 bool isDragMoving_ = false; 376 377 ColumnChangeCallback changeCallback_; 378 379 int32_t halfDisplayCounts_ = 0; 380 381 ACE_DISALLOW_COPY_AND_MOVE(TextPickerColumnPattern); 382 }; 383 } // namespace OHOS::Ace::NG 384 385 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TEXT_PICKER_TEXT_PICKER_COLUMN_PATTERN_H 386