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_PATTERN_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TEXT_PICKER_TEXT_PICKER_PATTERN_H 18 19 #include <optional> 20 21 #include "core/components/picker/picker_theme.h" 22 #include "core/components/dialog/dialog_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_picker/textpicker_row_accessibility_property.h" 26 #include "core/components_ng/pattern/text_picker/textpicker_event_hub.h" 27 #include "core/components_ng/pattern/text_picker/textpicker_layout_property.h" 28 #include "core/components_ng/pattern/text_picker/textpicker_paint_method.h" 29 #include "core/components_ng/pattern/text_picker/toss_animation_controller.h" 30 31 namespace OHOS::Ace::NG { 32 class InspectorFilter; 33 using EventCallback = std::function<void(bool)>; 34 using ColumnChangeCallback = std::function<void(const RefPtr<FrameNode>&, bool, uint32_t, bool)>; 35 36 namespace { 37 const Dimension TEXT_FOCUS_PAINT_WIDTH = 2.0_vp; 38 } 39 class TextPickerPattern : public LinearLayoutPattern { 40 DECLARE_ACE_TYPE(TextPickerPattern, LinearLayoutPattern); 41 42 public: TextPickerPattern()43 TextPickerPattern() : LinearLayoutPattern(false) {}; 44 45 ~TextPickerPattern() override = default; 46 IsAtomicNode()47 bool IsAtomicNode() const override 48 { 49 return true; 50 } 51 CreateEventHub()52 RefPtr<EventHub> CreateEventHub() override 53 { 54 return MakeRefPtr<TextPickerEventHub>(); 55 } 56 CreateLayoutProperty()57 RefPtr<LayoutProperty> CreateLayoutProperty() override 58 { 59 return MakeRefPtr<TextPickerLayoutProperty>(); 60 } 61 CreateAccessibilityProperty()62 RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override 63 { 64 return MakeRefPtr<TextPickerRowAccessibilityProperty>(); 65 } 66 CreateNodePaintMethod()67 RefPtr<NodePaintMethod> CreateNodePaintMethod() override 68 { 69 auto textPickerPaintMethod = MakeRefPtr<TextPickerPaintMethod>(WeakClaim(this)); 70 textPickerPaintMethod->SetDefaultPickerItemHeight(CalculateHeight()); 71 textPickerPaintMethod->SetEnabled(enabled_); 72 return textPickerPaintMethod; 73 } 74 CreateLayoutAlgorithm()75 RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override 76 { 77 return MakeRefPtr<LinearLayoutAlgorithm>(); 78 } 79 80 void SetEventCallback(EventCallback&& value); 81 82 void FireChangeEvent(bool refresh); 83 84 void SetScrollStopEventCallback(EventCallback&& value); 85 86 void FireScrollStopEvent(bool refresh); 87 88 void OnColumnsBuilding(); 89 90 void FlushOptions(); 91 92 void SetDefaultPickerItemHeight(); 93 94 std::map<uint32_t, RefPtr<FrameNode>> GetColumnNodes(); 95 96 RefPtr<FrameNode> GetColumnNode(); 97 98 uint32_t GetShowOptionCount() const; 99 SetSelected(uint32_t value)100 void SetSelected(uint32_t value) 101 { 102 selectedIndex_ = value; 103 } 104 GetSelected()105 uint32_t GetSelected() const 106 { 107 return selectedIndex_; 108 } 109 SetRange(const std::vector<NG::RangeContent> & value)110 void SetRange(const std::vector<NG::RangeContent>& value) 111 { 112 if (value.empty()) { 113 return; 114 } 115 range_.clear(); 116 for (size_t i = 0; i < value.size(); i++) { 117 RangeContent content; 118 content.icon_ = value[i].icon_; 119 content.text_ = value[i].text_; 120 range_.emplace_back(content); 121 } 122 } 123 GetRange()124 std::vector<NG::RangeContent> GetRange() const 125 { 126 return range_; 127 } 128 GetMultiOptions()129 std::vector<NG::TextCascadePickerOptions> GetMultiOptions() const 130 { 131 return cascadeOriginptions_; 132 } 133 SetColumnsKind(uint32_t columnKind)134 void SetColumnsKind(uint32_t columnKind) 135 { 136 columnsKind_ = columnKind; 137 } 138 ClearOption()139 void ClearOption() 140 { 141 options_.clear(); 142 } 143 AppendOption(const NG::RangeContent & value)144 void AppendOption(const NG::RangeContent& value) 145 { 146 options_.emplace_back(value); 147 } 148 GetOptionCount()149 uint32_t GetOptionCount() const 150 { 151 return options_.size(); 152 } 153 154 std::string GetSelectedObject(bool isColumnChange, int32_t status = 0) const; 155 GetOption(uint32_t index)156 std::string GetOption(uint32_t index) const 157 { 158 if (index >= GetOptionCount()) { 159 return ""; 160 } 161 return options_[index].text_; 162 } 163 SetBackgroundColor(const Color & color)164 void SetBackgroundColor(const Color& color) 165 { 166 if (backgroundColor_ == color) { 167 return; 168 } 169 auto host = GetHost(); 170 CHECK_NULL_VOID(host); 171 backgroundColor_ = color; 172 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER); 173 } 174 GetBackgroundColor()175 Color GetBackgroundColor() 176 { 177 return backgroundColor_; 178 } 179 GetFocusPattern()180 FocusPattern GetFocusPattern() const override 181 { 182 auto pipeline = PipelineBase::GetCurrentContext(); 183 CHECK_NULL_RETURN(pipeline, FocusPattern()); 184 auto pickerTheme = pipeline->GetTheme<PickerTheme>(); 185 CHECK_NULL_RETURN(pickerTheme, FocusPattern()); 186 auto focusColor = pickerTheme->GetFocusColor(); 187 188 FocusPaintParam focusPaintParams; 189 focusPaintParams.SetPaintColor(focusColor); 190 focusPaintParams.SetPaintWidth(TEXT_FOCUS_PAINT_WIDTH); 191 192 return { FocusType::NODE, true, FocusStyleType::CUSTOM_REGION, focusPaintParams }; 193 } 194 195 void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override; 196 SetCascadeOptions(const std::vector<NG::TextCascadePickerOptions> & options,const std::vector<NG::TextCascadePickerOptions> & cascadeOptions)197 void SetCascadeOptions(const std::vector<NG::TextCascadePickerOptions>& options, 198 const std::vector<NG::TextCascadePickerOptions>& cascadeOptions) 199 { 200 cascadeOptions_.clear(); 201 cascadeOriginptions_.clear(); 202 for (auto& option : cascadeOptions) { 203 cascadeOptions_.emplace_back(std::move(option)); 204 } 205 for (auto& option : options) { 206 cascadeOriginptions_.emplace_back(std::move(option)); 207 } 208 } 209 GetCascadeOptionCount()210 uint32_t GetCascadeOptionCount() const 211 { 212 return cascadeOptions_.size(); 213 } 214 GetOptionCount(const RefPtr<FrameNode> & frmeNode)215 uint32_t GetOptionCount(const RefPtr<FrameNode>& frmeNode) 216 { 217 uint32_t count = 0; 218 auto it = optionsWithNode_.find(frmeNode); 219 if (it != optionsWithNode_.end()) { 220 count = it->second.size(); 221 } 222 return count; 223 } 224 SetIsCascade(bool isCascade)225 void SetIsCascade(bool isCascade) 226 { 227 isCascade_ = isCascade; 228 } 229 GetIsCascade()230 bool GetIsCascade() const 231 { 232 return isCascade_; 233 } 234 SetConfirmNode(WeakPtr<FrameNode> buttonConfirmNode)235 void SetConfirmNode(WeakPtr<FrameNode> buttonConfirmNode) 236 { 237 weakButtonConfirm_ = buttonConfirmNode; 238 } 239 SetCancelNode(WeakPtr<FrameNode> buttonCancelNode)240 void SetCancelNode(WeakPtr<FrameNode> buttonCancelNode) 241 { 242 weakButtonCancel_ = buttonCancelNode; 243 } 244 SetForwardNode(WeakPtr<FrameNode> buttonForwardNode)245 void SetForwardNode(WeakPtr<FrameNode> buttonForwardNode) 246 { 247 weakButtonForward_ = buttonForwardNode; 248 } 249 SetBackwardNode(WeakPtr<FrameNode> buttonBackwardNode)250 void SetBackwardNode(WeakPtr<FrameNode> buttonBackwardNode) 251 { 252 weakButtonBackward_ = buttonBackwardNode; 253 } 254 255 void OnLanguageConfigurationUpdate() override; 256 void OnFontConfigurationUpdate() override; 257 SetValues(const std::vector<std::string> & values)258 void SetValues(const std::vector<std::string>& values) 259 { 260 values_.clear(); 261 for (auto& value : values) { 262 values_.emplace_back(value); 263 } 264 } 265 GetValues()266 const std::vector<std::string>& GetValues() 267 { 268 return values_; 269 } 270 GetSelecteds()271 const std::vector<uint32_t>& GetSelecteds() 272 { 273 return selecteds_; 274 } 275 SetHasSelectAttr(bool value)276 void SetHasSelectAttr(bool value) 277 { 278 isHasSelectAttr_ = value; 279 } 280 SetResizePickerItemHeight(double resizePickerItemHeight)281 void SetResizePickerItemHeight(double resizePickerItemHeight) 282 { 283 resizePickerItemHeight_ = resizePickerItemHeight; 284 } 285 GetResizePickerItemHeight()286 double GetResizePickerItemHeight() const 287 { 288 return resizePickerItemHeight_; 289 } 290 SetResizeFlag(bool resizeFlag)291 void SetResizeFlag(bool resizeFlag) 292 { 293 resizeFlag_ = resizeFlag; 294 } 295 GetResizeFlag()296 bool GetResizeFlag() const 297 { 298 return resizeFlag_; 299 } 300 SetIsShowInDialog(bool isShowInDialog)301 void SetIsShowInDialog(bool isShowInDialog) 302 { 303 isShowInDialog_ = isShowInDialog; 304 } 305 GetIsShowInDialog()306 bool GetIsShowInDialog() const 307 { 308 return isShowInDialog_; 309 } 310 GetDefaultPickerItemHeight()311 double GetDefaultPickerItemHeight() const 312 { 313 return defaultPickerItemHeight_; 314 } 315 316 void SetSelecteds(const std::vector<uint32_t>& values); 317 318 void HandleColumnChange(const RefPtr<FrameNode>& tag, bool isAdd, uint32_t index, bool needNotify); 319 320 void SetChangeCallback(ColumnChangeCallback&& value); 321 322 void ProcessCascadeOptions(const std::vector<NG::TextCascadePickerOptions>& options, 323 std::vector<NG::TextCascadePickerOptions>& reOptions, uint32_t index); 324 325 size_t ProcessCascadeOptionDepth(const NG::TextCascadePickerOptions& option); 326 327 void OnColorConfigurationUpdate() override; 328 329 void OnDirectionConfigurationUpdate() override; 330 SetContentRowNode(RefPtr<FrameNode> & contentRowNode)331 void SetContentRowNode(RefPtr<FrameNode>& contentRowNode) 332 { 333 contentRowNode_ = contentRowNode; 334 } 335 SetPickerTag(bool isPicker)336 void SetPickerTag(bool isPicker) 337 { 338 isPicker_ = isPicker; 339 } 340 341 void CheckAndUpdateColumnSize(SizeF& size, bool isNeedAdaptForAging = false); 342 bool NeedAdaptForAging(); 343 SetDivider(const ItemDivider & divider)344 void SetDivider(const ItemDivider& divider) 345 { 346 divider_ = divider; 347 } 348 GetDivider()349 ItemDivider GetDivider() 350 { 351 return divider_; 352 } 353 SetCustomDividerFlag(bool customDividerFlag)354 void SetCustomDividerFlag(bool customDividerFlag) 355 { 356 customDividerFlag_ = customDividerFlag; 357 } 358 GetCustomDividerFlag()359 bool GetCustomDividerFlag() 360 { 361 return customDividerFlag_; 362 } 363 SetGradientHeight(const Dimension & value)364 void SetGradientHeight(const Dimension& value) 365 { 366 value_ = value; 367 } 368 GetGradientHeight()369 Dimension GetGradientHeight() 370 { 371 return value_; 372 } 373 374 void SetCanLoop(bool isLoop); 375 GetCanLoop()376 bool GetCanLoop() 377 { 378 return canloop_; 379 } 380 SetRangeType(int32_t rangeType)381 void SetRangeType(int32_t rangeType) 382 { 383 rangeType_ = rangeType; 384 } 385 GetRangeType()386 int32_t GetRangeType() 387 { 388 return rangeType_; 389 } 390 HasUserDefinedDisappearFontFamily(bool isUserDefined)391 void HasUserDefinedDisappearFontFamily(bool isUserDefined) 392 { 393 hasUserDefinedDisappearFontFamily_ = isUserDefined; 394 } 395 GetHasUserDefinedDisappearFontFamily()396 bool GetHasUserDefinedDisappearFontFamily() 397 { 398 return hasUserDefinedDisappearFontFamily_; 399 } 400 HasUserDefinedNormalFontFamily(bool isUserDefined)401 void HasUserDefinedNormalFontFamily(bool isUserDefined) 402 { 403 hasUserDefinedNormalFontFamily_ = isUserDefined; 404 } 405 GetHasUserDefinedNormalFontFamily()406 bool GetHasUserDefinedNormalFontFamily() 407 { 408 return hasUserDefinedNormalFontFamily_; 409 } 410 HasUserDefinedSelectedFontFamily(bool isUserDefined)411 void HasUserDefinedSelectedFontFamily(bool isUserDefined) 412 { 413 hasUserDefinedSelectedFontFamily_ = isUserDefined; 414 } 415 GetHasUserDefinedSelectedFontFamily()416 bool GetHasUserDefinedSelectedFontFamily() 417 { 418 return hasUserDefinedSelectedFontFamily_; 419 } 420 updateFontConfigurationEvent(const std::function<void ()> & closeDialogEvent)421 void updateFontConfigurationEvent(const std::function<void()>& closeDialogEvent) 422 { 423 closeDialogEvent_ = closeDialogEvent; 424 } 425 GetTextProperties()426 const PickerTextProperties& GetTextProperties() const 427 { 428 return textProperties_; 429 } 430 SetTextProperties(const PickerTextProperties & properties)431 void SetTextProperties(const PickerTextProperties& properties) 432 { 433 textProperties_ = properties; 434 if (properties.disappearTextStyle_.fontSize.has_value() && properties.disappearTextStyle_.fontSize->IsValid()) { 435 isUserSetGradientFont_ = true; 436 gradientHeight_ = properties.disappearTextStyle_.fontSize.value(); 437 } 438 439 if (properties.normalTextStyle_.fontSize.has_value() && properties.normalTextStyle_.fontSize->IsValid()) { 440 isUserSetGradientFont_ = true; 441 gradientHeight_ = std::max(properties.normalTextStyle_.fontSize.value(), gradientHeight_); 442 } 443 444 if (properties.selectedTextStyle_.fontSize.has_value() && properties.selectedTextStyle_.fontSize->IsValid()) { 445 isUserSetDividerSpacingFont_ = true; 446 dividerSpacing_ = properties.selectedTextStyle_.fontSize.value(); 447 } 448 } 449 GetIsUserSetDividerSpacingFont()450 bool GetIsUserSetDividerSpacingFont() 451 { 452 return isUserSetDividerSpacingFont_; 453 } 454 GetIsUserSetGradientFont()455 bool GetIsUserSetGradientFont() 456 { 457 return isUserSetGradientFont_; 458 } 459 GetDividerSpacing()460 Dimension GetDividerSpacing() 461 { 462 return dividerSpacing_; 463 } 464 GetTextGradientHeight()465 Dimension GetTextGradientHeight() 466 { 467 return gradientHeight_; 468 } 469 SetPaintDividerSpacing(float & value)470 void SetPaintDividerSpacing(float& value) 471 { 472 paintDividerSpacing_ = value; 473 } 474 GetPaintDividerSpacing()475 float GetPaintDividerSpacing() 476 { 477 return paintDividerSpacing_; 478 } 479 SetUserDefinedOpacity(double opacity)480 void SetUserDefinedOpacity(double opacity) 481 { 482 curOpacity_ = opacity; 483 } 484 485 private: 486 void OnModifyDone() override; 487 void SetLayoutDirection(TextDirection textDirection); 488 void OnAttachToFrameNode() override; 489 bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override; 490 491 void InitOnKeyEvent(const RefPtr<FocusHub>& focusHub); 492 bool OnKeyEvent(const KeyEvent& event); 493 bool HandleDirectionKey(KeyCode code); 494 double CalculateHeight(); 495 496 void InitDisabled(); 497 void GetInnerFocusPaintRect(RoundRect& paintRect); 498 void PaintFocusState(); 499 void SetButtonIdeaSize(); 500 std::string GetRangeStr() const; 501 std::string GetOptionsMultiStr() const; 502 std::string GetOptionsMultiStrInternal() const; 503 std::string GetOptionsCascadeStr( 504 const std::vector<NG::TextCascadePickerOptions>& options) const; 505 bool ChangeCurrentOptionValue(NG::TextCascadePickerOptions& option, 506 uint32_t value, uint32_t curColumn, uint32_t replaceColumn); 507 void OnColumnsBuildingUnCascade(); 508 void OnColumnsBuildingCascade(); 509 std::string GetSelectedObjectMulti(const std::vector<std::string>& values, 510 const std::vector<uint32_t>& indexs, int32_t status) const; 511 void SupplementOption(const std::vector<NG::TextCascadePickerOptions>& reOptions, 512 std::vector<NG::RangeContent>& rangeContents, uint32_t patterIndex); 513 void ProcessCascadeOptionsValues(const std::vector<std::string>& rangeResultValue, uint32_t index); 514 void SetFocusCornerRadius(RoundRect& paintRect); 515 void UpdateConfirmButtonMargin( 516 const RefPtr<FrameNode>& buttonConfirmNode, const RefPtr<DialogTheme>& dialogTheme); 517 void UpdateCancelButtonMargin( 518 const RefPtr<FrameNode>& buttonCancelNode, const RefPtr<DialogTheme>& dialogTheme); 519 void CheckFocusID(int32_t childSize); 520 bool ParseDirectionKey(RefPtr<TextPickerColumnPattern>& textPickerColumnPattern, KeyCode& code, int32_t childSize); 521 RectF CalculatePaintRect(int32_t currentFocusIndex, 522 float centerX, float centerY, float piantRectWidth, float piantRectHeight, float columnWidth); 523 524 bool enabled_ = true; 525 int32_t focusKeyID_ = 0; 526 double defaultPickerItemHeight_ = 0.0; 527 double resizePickerItemHeight_ = 0.0; 528 uint32_t selectedIndex_ = 0; 529 std::vector<NG::RangeContent> range_; 530 std::vector<NG::RangeContent> options_; 531 uint32_t columnsKind_ = 0; 532 std::vector<NG::TextCascadePickerOptions> cascadeOptions_; 533 std::map<WeakPtr<FrameNode>, std::vector<NG::RangeContent>> optionsWithNode_; 534 std::vector<NG::TextCascadePickerOptions> cascadeOriginptions_; 535 bool isCascade_ = false; 536 bool isHasSelectAttr_ = false; 537 WeakPtr<FrameNode> weakButtonConfirm_; 538 WeakPtr<FrameNode> weakButtonCancel_; 539 WeakPtr<FrameNode> weakButtonForward_; 540 WeakPtr<FrameNode> weakButtonBackward_; 541 std::vector<std::string> values_; 542 std::vector<uint32_t> selecteds_; 543 Color backgroundColor_ = Color::WHITE; 544 bool resizeFlag_ = false; 545 bool isShowInDialog_ = false; 546 bool canloop_ = true; 547 548 // inner focus switch 549 bool operationOn_ = false; 550 551 bool hasUserDefinedDisappearFontFamily_ = false; 552 bool hasUserDefinedNormalFontFamily_ = false; 553 bool hasUserDefinedSelectedFontFamily_ = false; 554 555 double curOpacity_ = 1.0; 556 557 ACE_DISALLOW_COPY_AND_MOVE(TextPickerPattern); 558 559 WeakPtr<NG::FrameNode> contentRowNode_; 560 bool isPicker_ = true; 561 bool isFiredSelectsChange_ = false; 562 std::optional<std::string> firedSelectsStr_; 563 564 ItemDivider divider_; 565 bool customDividerFlag_ = false; 566 Dimension value_; 567 int32_t rangeType_ = 0; 568 std::function<void()> closeDialogEvent_; 569 bool isUserSetDividerSpacingFont_ = false; 570 bool isUserSetGradientFont_ = false; 571 Dimension gradientHeight_; 572 Dimension dividerSpacing_; 573 float paintDividerSpacing_ = 1.0f; 574 bool isNeedUpdateSelectedIndex_ = true; 575 PickerTextProperties textProperties_; 576 }; 577 } // namespace OHOS::Ace::NG 578 579 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TEXT_PICKER_TEXT_PICKER_PATTERN_H 580