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 using EventCallback = std::function<void(bool)>; 33 using ColumnChangeCallback = std::function<void(const RefPtr<FrameNode>&, bool, uint32_t, bool)>; 34 35 namespace { 36 const Dimension TEXT_FOCUS_PAINT_WIDTH = 2.0_vp; 37 } 38 class TextPickerPattern : public LinearLayoutPattern { 39 DECLARE_ACE_TYPE(TextPickerPattern, LinearLayoutPattern); 40 41 public: TextPickerPattern()42 TextPickerPattern() : LinearLayoutPattern(false) {}; 43 44 ~TextPickerPattern() override = default; 45 IsAtomicNode()46 bool IsAtomicNode() const override 47 { 48 return true; 49 } 50 CreateEventHub()51 RefPtr<EventHub> CreateEventHub() override 52 { 53 return MakeRefPtr<TextPickerEventHub>(); 54 } 55 CreateLayoutProperty()56 RefPtr<LayoutProperty> CreateLayoutProperty() override 57 { 58 return MakeRefPtr<TextPickerLayoutProperty>(); 59 } 60 CreateAccessibilityProperty()61 RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override 62 { 63 return MakeRefPtr<TextPickerRowAccessibilityProperty>(); 64 } 65 CreateNodePaintMethod()66 RefPtr<NodePaintMethod> CreateNodePaintMethod() override 67 { 68 auto textPickerPaintMethod = MakeRefPtr<TextPickerPaintMethod>(WeakClaim(this)); 69 textPickerPaintMethod->SetDefaultPickerItemHeight(CalculateHeight()); 70 textPickerPaintMethod->SetEnabled(enabled_); 71 textPickerPaintMethod->SetBackgroundColor(backgroundColor_); 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 LOGE("input value of range is empty."); 110 return; 111 } 112 range_.clear(); 113 for (size_t i = 0; i < value.size(); i++) { 114 RangeContent content; 115 content.icon_ = value[i].icon_; 116 content.text_ = value[i].text_; 117 range_.emplace_back(content); 118 } 119 } 120 GetRange()121 std::vector<NG::RangeContent> GetRange() const 122 { 123 return range_; 124 } 125 SetColumnsKind(uint32_t columnKind)126 void SetColumnsKind(uint32_t columnKind) 127 { 128 columnsKind_ = columnKind; 129 } 130 ClearOption()131 void ClearOption() 132 { 133 options_.clear(); 134 } 135 AppendOption(const NG::RangeContent & value)136 void AppendOption(const NG::RangeContent& value) 137 { 138 options_.emplace_back(value); 139 } 140 GetOptionCount()141 uint32_t GetOptionCount() const 142 { 143 return options_.size(); 144 } 145 146 std::string GetSelectedObject(bool isColumnChange, int32_t status = 0) const; 147 GetOption(uint32_t index)148 std::string GetOption(uint32_t index) const 149 { 150 if (index >= GetOptionCount()) { 151 LOGE("index out of range."); 152 return ""; 153 } 154 return options_[index].text_; 155 } 156 SetBackgroundColor(const Color & color)157 void SetBackgroundColor(const Color& color) 158 { 159 if (backgroundColor_ == color) { 160 return; 161 } 162 auto host = GetHost(); 163 CHECK_NULL_VOID(host); 164 backgroundColor_ = color; 165 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER); 166 } 167 GetFocusPattern()168 FocusPattern GetFocusPattern() const override 169 { 170 auto pipeline = PipelineBase::GetCurrentContext(); 171 CHECK_NULL_RETURN(pipeline, FocusPattern()); 172 auto pickerTheme = pipeline->GetTheme<PickerTheme>(); 173 CHECK_NULL_RETURN(pickerTheme, FocusPattern()); 174 auto focusColor = pickerTheme->GetFocusColor(); 175 176 FocusPaintParam focusPaintParams; 177 focusPaintParams.SetPaintColor(focusColor); 178 focusPaintParams.SetPaintWidth(TEXT_FOCUS_PAINT_WIDTH); 179 180 return { FocusType::NODE, true, FocusStyleType::CUSTOM_REGION, focusPaintParams }; 181 } 182 183 void ToJsonValue(std::unique_ptr<JsonValue>& json) const override; 184 SetCascadeOptions(const std::vector<NG::TextCascadePickerOptions> & options,const std::vector<NG::TextCascadePickerOptions> & cascadeOptions)185 void SetCascadeOptions(const std::vector<NG::TextCascadePickerOptions>& options, 186 const std::vector<NG::TextCascadePickerOptions>& cascadeOptions) 187 { 188 cascadeOptions_.clear(); 189 cascadeOriginptions_.clear(); 190 for (auto& option : cascadeOptions) { 191 cascadeOptions_.emplace_back(std::move(option)); 192 } 193 for (auto& option : options) { 194 cascadeOriginptions_.emplace_back(std::move(option)); 195 } 196 } 197 GetCascadeOptionCount()198 uint32_t GetCascadeOptionCount() const 199 { 200 return cascadeOptions_.size(); 201 } 202 GetOptionCount(const RefPtr<FrameNode> & frmeNode)203 uint32_t GetOptionCount(const RefPtr<FrameNode>& frmeNode) 204 { 205 uint32_t count = 0; 206 if (optionsWithNode_.find(frmeNode) != optionsWithNode_.end()) { 207 count = optionsWithNode_[frmeNode].size(); 208 } 209 return count; 210 } 211 SetIsCascade(bool isCascade)212 void SetIsCascade(bool isCascade) 213 { 214 isCascade_ = isCascade; 215 } 216 GetIsCascade()217 bool GetIsCascade() const 218 { 219 return isCascade_; 220 } 221 SetConfirmNode(WeakPtr<FrameNode> buttonConfirmNode)222 void SetConfirmNode(WeakPtr<FrameNode> buttonConfirmNode) 223 { 224 weakButtonConfirm_ = buttonConfirmNode; 225 } 226 SetCancelNode(WeakPtr<FrameNode> buttonCancelNode)227 void SetCancelNode(WeakPtr<FrameNode> buttonCancelNode) 228 { 229 weakButtonCancel_ = buttonCancelNode; 230 } 231 232 void OnLanguageConfigurationUpdate() override; 233 SetValues(const std::vector<std::string> & values)234 void SetValues(const std::vector<std::string>& values) 235 { 236 values_.clear(); 237 for (auto& value : values) { 238 values_.emplace_back(value); 239 } 240 } 241 SetHasSelectAttr(bool value)242 void SetHasSelectAttr(bool value) 243 { 244 isHasSelectAttr_ = value; 245 } 246 SetResizePickerItemHeight(double resizePickerItemHeight)247 void SetResizePickerItemHeight(double resizePickerItemHeight) 248 { 249 resizePickerItemHeight_ = resizePickerItemHeight; 250 } 251 GetResizePickerItemHeight()252 double GetResizePickerItemHeight() const 253 { 254 return resizePickerItemHeight_; 255 } 256 SetResizeFlag(bool resizeFlag)257 void SetResizeFlag(bool resizeFlag) 258 { 259 resizeFlag_ = resizeFlag; 260 } 261 GetResizeFlag()262 bool GetResizeFlag() const 263 { 264 return resizeFlag_; 265 } 266 SetIsShowInDialog(bool isShowInDialog)267 void SetIsShowInDialog(bool isShowInDialog) 268 { 269 isShowInDialog_ = isShowInDialog; 270 } 271 GetIsShowInDialog()272 bool GetIsShowInDialog() const 273 { 274 return isShowInDialog_; 275 } 276 277 void SetSelecteds(const std::vector<uint32_t>& values); 278 279 void HandleColumnChange(const RefPtr<FrameNode>& tag, bool isAdd, uint32_t index, bool needNotify); 280 281 void SetChangeCallback(ColumnChangeCallback&& value); 282 283 void ProcessCascadeOptions(const std::vector<NG::TextCascadePickerOptions>& options, 284 std::vector<NG::TextCascadePickerOptions>& reOptions, uint32_t index); 285 286 size_t ProcessCascadeOptionDepth(const NG::TextCascadePickerOptions& option); 287 288 void OnColorConfigurationUpdate() override; 289 SetContentRowNode(RefPtr<FrameNode> & contentRowNode)290 void SetContentRowNode(RefPtr<FrameNode>& contentRowNode) 291 { 292 contentRowNode_ = contentRowNode; 293 } 294 SetPickerTag(bool isPicker)295 void SetPickerTag(bool isPicker) 296 { 297 isPicker_ = isPicker; 298 } 299 300 private: 301 void OnModifyDone() override; 302 void OnAttachToFrameNode() override; 303 bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override; 304 305 void InitOnKeyEvent(const RefPtr<FocusHub>& focusHub); 306 bool OnKeyEvent(const KeyEvent& event); 307 bool HandleDirectionKey(KeyCode code); 308 double CalculateHeight(); 309 310 void InitDisabled(); 311 void GetInnerFocusPaintRect(RoundRect& paintRect); 312 void PaintFocusState(); 313 void SetButtonIdeaSize(); 314 std::string GetRangeStr() const; 315 std::string GetOptionsMultiStr() const; 316 std::string GetOptionsMultiStrInternal() const; 317 std::string GetOptionsCascadeStr( 318 const std::vector<NG::TextCascadePickerOptions>& options) const; 319 bool ChangeCurrentOptionValue(NG::TextCascadePickerOptions& option, 320 uint32_t value, uint32_t curColumn, uint32_t replaceColumn); 321 void OnColumnsBuildingUnCascade(); 322 void OnColumnsBuildingCascade(); 323 std::string GetSelectedObjectMulti(const std::vector<std::string>& values, 324 const std::vector<uint32_t>& indexs, int32_t status) const; 325 void SupplementOption(const std::vector<NG::TextCascadePickerOptions>& reOptions, 326 std::vector<NG::RangeContent>& rangeContents, uint32_t patterIndex); 327 void ProcessCascadeOptionsValues(const std::vector<std::string>& rangeResultValue, uint32_t index); 328 void SetFocusCornerRadius(RoundRect& paintRect); 329 330 bool enabled_ = true; 331 int32_t focusKeyID_ = 0; 332 double defaultPickerItemHeight_; 333 double resizePickerItemHeight_; 334 uint32_t selectedIndex_ = 0; 335 std::vector<NG::RangeContent> range_; 336 std::vector<NG::RangeContent> options_; 337 uint32_t columnsKind_; 338 std::vector<NG::TextCascadePickerOptions> cascadeOptions_; 339 std::map<RefPtr<FrameNode>, std::vector<NG::RangeContent>> optionsWithNode_; 340 std::vector<NG::TextCascadePickerOptions> cascadeOriginptions_; 341 bool isCascade_ = false; 342 bool isHasSelectAttr_ = false; 343 WeakPtr<FrameNode> weakButtonConfirm_; 344 WeakPtr<FrameNode> weakButtonCancel_; 345 std::vector<std::string> values_; 346 std::vector<uint32_t> selecteds_; 347 Color backgroundColor_ = Color::WHITE; 348 bool resizeFlag_ = false; 349 bool isShowInDialog_ = false; 350 351 // inner focus switch 352 bool operationOn_ = false; 353 354 ACE_DISALLOW_COPY_AND_MOVE(TextPickerPattern); 355 356 RefPtr<NG::FrameNode> contentRowNode_; 357 bool isPicker_ = true; 358 }; 359 } // namespace OHOS::Ace::NG 360 361 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TEXT_PICKER_TEXT_PICKER_PATTERN_H 362