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