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_SELECT_SELECT_PATTERN_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SELECT_SELECT_PATTERN_H 18 19 #include <cstdint> 20 #include <optional> 21 22 #include "base/memory/referenced.h" 23 #include "base/utils/utils.h" 24 #include "core/components/common/properties/color.h" 25 #include "core/components/select/select_theme.h" 26 #include "core/components/theme/icon_theme.h" 27 #include "core/components_ng/base/frame_node.h" 28 #include "core/components_ng/event/event_hub.h" 29 #include "core/components_ng/pattern/option/option_paint_method.h" 30 #include "core/components_ng/pattern/option/option_paint_property.h" 31 #include "core/components_ng/pattern/pattern.h" 32 #include "core/components_ng/pattern/select/select_accessibility_property.h" 33 #include "core/components_ng/pattern/select/select_event_hub.h" 34 #include "core/components_ng/pattern/select/select_layout_algorithm.h" 35 #include "core/components_ng/pattern/select/select_model.h" 36 #include "core/components_ng/pattern/text/text_layout_property.h" 37 #include "core/components_ng/pattern/select/select_model_ng.h" 38 39 namespace OHOS::Ace::NG { 40 class InspectorFilter; 41 42 class SelectPattern : public Pattern { 43 DECLARE_ACE_TYPE(SelectPattern, Pattern); 44 45 public: 46 SelectPattern() = default; 47 ~SelectPattern() override = default; 48 IsAtomicNode()49 bool IsAtomicNode() const override 50 { 51 return false; 52 } 53 CreateAccessibilityProperty()54 RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override 55 { 56 return MakeRefPtr<SelectAccessibilityProperty>(); 57 } 58 CreateLayoutAlgorithm()59 RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override 60 { 61 return MakeRefPtr<SelectLayoutAlgorithm>(); 62 } 63 CreateEventHub()64 RefPtr<EventHub> CreateEventHub() override 65 { 66 return MakeRefPtr<SelectEventHub>(); 67 } 68 69 void BuildChild(); 70 SetMenuNode(const RefPtr<FrameNode> & menuWrapper)71 void SetMenuNode(const RefPtr<FrameNode>& menuWrapper) 72 { 73 menuWrapper_ = menuWrapper; 74 } 75 GetMenuWrapper()76 const RefPtr<FrameNode>& GetMenuWrapper() const 77 { 78 return menuWrapper_; 79 } 80 GetMenuNode()81 RefPtr<FrameNode> GetMenuNode() const 82 { 83 CHECK_NULL_RETURN(menuWrapper_, nullptr); 84 return DynamicCast<FrameNode>(menuWrapper_->GetChildAtIndex(0)); 85 } 86 SetSelectSize(const SizeF & selectSize)87 void SetSelectSize(const SizeF& selectSize) 88 { 89 selectSize_ = selectSize; 90 } GetSelectSize()91 SizeF GetSelectSize() const 92 { 93 return selectSize_; 94 } 95 96 void AddOptionNode(const RefPtr<FrameNode>& option); 97 ClearOptions()98 void ClearOptions() 99 { 100 options_.clear(); 101 } 102 InitSelected()103 void InitSelected() 104 { 105 selected_ = -1; 106 } 107 GetSelected()108 int32_t GetSelected() const 109 { 110 return selected_; 111 } 112 113 void SetSelected(int32_t index); 114 115 // set properties of text node 116 void SetValue(const std::string& value); 117 void SetFontSize(const Dimension& value); 118 void SetItalicFontStyle(const Ace::FontStyle& value); 119 void SetFontWeight(const FontWeight& value); 120 void SetFontFamily(const std::vector<std::string>& value); 121 void SetFontColor(const Color& color); 122 123 // set props of option nodes 124 void SetOptionBgColor(const Color& color); 125 void SetOptionFontSize(const Dimension& value); 126 void SetOptionItalicFontStyle(const Ace::FontStyle& value); 127 void SetOptionFontWeight(const FontWeight& value); 128 void SetOptionFontFamily(const std::vector<std::string>& value); 129 void SetOptionFontColor(const Color& color); 130 131 // set props of option node when selected 132 void SetSelectedOptionBgColor(const Color& color); 133 void SetSelectedOptionFontSize(const Dimension& value); 134 void SetSelectedOptionItalicFontStyle(const Ace::FontStyle& value); 135 void SetSelectedOptionFontWeight(const FontWeight& value); 136 void SetSelectedOptionFontFamily(const std::vector<std::string>& value); 137 void SetSelectedOptionFontColor(const Color& color); 138 139 // set props of menu background 140 void SetMenuBackgroundColor(const Color& color); 141 void SetMenuBackgroundBlurStyle(const BlurStyleOption& blurStyle); 142 143 // Get functions for unit tests 144 const std::vector<RefPtr<FrameNode>>& GetOptions(); 145 GetFocusPattern()146 FocusPattern GetFocusPattern() const override 147 { 148 return { FocusType::NODE, true, FocusStyleType::INNER_BORDER }; 149 } 150 151 // update selected option props 152 void UpdateSelectedProps(int32_t index); 153 154 void UpdateLastSelectedProps(int32_t index); 155 156 // reset options props when selected index is -1 157 void ResetOptionProps(); 158 SetBgBlendColor(const Color & color)159 void SetBgBlendColor(const Color& color) 160 { 161 bgBlendColor_ = color; 162 } 163 GetBgBlendColor()164 Color GetBgBlendColor() const 165 { 166 return bgBlendColor_; 167 } 168 SetIsHover(bool isHover)169 void SetIsHover(bool isHover) 170 { 171 isHover_ = isHover; 172 } 173 IsHover()174 bool IsHover() const 175 { 176 return isHover_; 177 } 178 179 void SetItemSelected(int index, const std::string& value); 180 void PlayBgColorAnimation(bool isHoverChange = true); 181 void SetSpace(const Dimension& value); 182 void SetArrowPosition(const ArrowPosition value); 183 void SetMenuAlign(const MenuAlign& menuAlign); 184 185 std::string GetValue(); 186 std::string ProvideRestoreInfo() override; 187 void OnRestoreInfo(const std::string& restoreInfo) override; 188 void OnColorConfigurationUpdate() override; 189 void OnLanguageConfigurationUpdate() override; 190 191 Dimension GetFontSize(); 192 void SetSelectDefaultTheme(); 193 void SetOptionWidth(const Dimension& value); 194 void SetOptionHeight(const Dimension& value); 195 void SetOptionWidthFitTrigger(bool isFitTrigger); 196 void ShowSelectMenu(); 197 void SetHasOptionWidth(bool hasOptionWidth); 198 void SetControlSize(const ControlSize& controlSize); 199 void SetDivider(const SelectDivider& divider); 200 ControlSize GetControlSize(); 201 void SetLayoutDirection(TextDirection value); 202 203 private: 204 void OnAttachToFrameNode() override; 205 void OnModifyDone() override; 206 void OnAfterModifyDone() override; 207 bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override; 208 HasRowNode()209 bool HasRowNode() const 210 { 211 return rowId_.has_value(); 212 } 213 HasTextNode()214 bool HasTextNode() const 215 { 216 return textId_.has_value(); 217 } 218 HasSpinnerNode()219 bool HasSpinnerNode() const 220 { 221 return spinnerId_.has_value(); 222 } 223 GetRowId()224 int32_t GetRowId() 225 { 226 if (!rowId_.has_value()) { 227 rowId_ = ElementRegister::GetInstance()->MakeUniqueId(); 228 } 229 return rowId_.value(); 230 } 231 GetTextId()232 int32_t GetTextId() 233 { 234 if (!textId_.has_value()) { 235 textId_ = ElementRegister::GetInstance()->MakeUniqueId(); 236 } 237 return textId_.value(); 238 } 239 GetSpinnerId()240 int32_t GetSpinnerId() 241 { 242 if (!spinnerId_.has_value()) { 243 spinnerId_ = ElementRegister::GetInstance()->MakeUniqueId(); 244 } 245 return spinnerId_.value(); 246 } 247 248 // change background color when pressed 249 void RegisterOnPress(); 250 // change background color when hovered 251 void RegisterOnHover(); 252 // add click event to show menu 253 void RegisterOnClick(); 254 255 void RegisterOnKeyEvent(); 256 bool OnKeyEvent(const KeyEvent& event); 257 258 // callback when an option is selected 259 void CreateSelectedCallback(); 260 // change text and spinner color if disabled 261 void SetDisabledStyle(); 262 263 // update text to selected option's text 264 void UpdateText(int32_t index); 265 266 void InitTextProps(const RefPtr<TextLayoutProperty>& textProps, const RefPtr<SelectTheme>& theme); 267 void InitSpinner( 268 const RefPtr<FrameNode>& spinner, const RefPtr<IconTheme>& iconTheme, const RefPtr<SelectTheme>& selectTheme); 269 void InitSpinner(const RefPtr<FrameNode>& spinner, const RefPtr<SelectTheme>& selectTheme); 270 void UpdateOptionsWidth(float selectWidth); 271 void ResetParams(); 272 273 std::vector<RefPtr<FrameNode>> options_; 274 RefPtr<FrameNode> menuWrapper_ = nullptr; 275 RefPtr<FrameNode> text_ = nullptr; 276 RefPtr<FrameNode> spinner_ = nullptr; 277 SizeF selectSize_; 278 279 // index of selected option 280 int32_t selected_ = -1; 281 // props when selected 282 struct OptionFont { 283 // text style when selected 284 std::optional<Dimension> FontSize; 285 std::optional<Ace::FontStyle> FontStyle; 286 std::optional<FontWeight> FontWeight; 287 std::optional<std::vector<std::string>> FontFamily; 288 std::optional<Color> FontColor; 289 }; 290 OptionFont selectedFont_; 291 std::optional<Color> selectedBgColor_; 292 OptionFont optionFont_; 293 std::optional<Color> optionBgColor_; 294 295 void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override; 296 void ToJsonArrowAndText(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const; 297 void ToJsonOptionAlign(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const; 298 void ToJsonMenuBackgroundStyle(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const; 299 void ToJsonDivider(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const; 300 // XTS inspector helper functions 301 std::string InspectorGetOptions() const; 302 std::string InspectorGetSelectedFont() const; 303 304 std::optional<int32_t> rowId_; 305 std::optional<int32_t> textId_; 306 std::optional<int32_t> spinnerId_; 307 308 Color bgBlendColor_ = Color::TRANSPARENT; 309 bool isHover_ = false; 310 bool isSelected_ = false; 311 MenuAlign menuAlign_; 312 std::string selectValue_; 313 bool isFitTrigger_ = false; 314 Color selectDefaultBgColor_ = Color::TRANSPARENT; 315 ControlSize controlSize_ = ControlSize::NORMAL; 316 ACE_DISALLOW_COPY_AND_MOVE(SelectPattern); 317 }; 318 319 } // namespace OHOS::Ace::NG 320 321 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SELECT_SELECT_PATTERN_H 322