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/common/properties/text_style.h" 26 #include "core/components/select/select_theme.h" 27 #include "core/components/theme/icon_theme.h" 28 #include "core/components_ng/base/frame_node.h" 29 #include "core/components_ng/event/event_hub.h" 30 #include "core/components_ng/pattern/pattern.h" 31 #include "core/components_ng/pattern/select/select_accessibility_property.h" 32 #include "core/components_ng/pattern/select/select_event_hub.h" 33 #include "core/components_ng/pattern/select/select_layout_algorithm.h" 34 #include "core/components_ng/pattern/select/select_layout_property.h" 35 #include "core/components_ng/pattern/select/select_model.h" 36 #include "core/components_ng/pattern/select/select_paint_property.h" 37 #include "core/components_ng/pattern/text/text_layout_property.h" 38 #include "core/components_ng/pattern/select/select_model_ng.h" 39 40 namespace OHOS::Ace::NG { 41 class InspectorFilter; 42 class MenuItemPattern; 43 44 class SelectPattern : public Pattern { 45 DECLARE_ACE_TYPE(SelectPattern, Pattern); 46 47 public: 48 SelectPattern() = default; 49 ~SelectPattern() override = default; 50 IsEnableMatchParent()51 bool IsEnableMatchParent() override 52 { 53 return true; 54 } 55 IsEnableFix()56 bool IsEnableFix() override 57 { 58 return true; 59 } 60 IsAtomicNode()61 bool IsAtomicNode() const override 62 { 63 return false; 64 } 65 CreateAccessibilityProperty()66 RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override 67 { 68 return MakeRefPtr<SelectAccessibilityProperty>(); 69 } 70 CreateLayoutAlgorithm()71 RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override 72 { 73 return MakeRefPtr<SelectLayoutAlgorithm>(); 74 } 75 CreateEventHub()76 RefPtr<EventHub> CreateEventHub() override 77 { 78 return MakeRefPtr<SelectEventHub>(); 79 } 80 81 void BuildChild(); 82 SetMenuNode(const RefPtr<FrameNode> & menuWrapper)83 void SetMenuNode(const RefPtr<FrameNode>& menuWrapper) 84 { 85 menuWrapper_ = menuWrapper; 86 } 87 GetMenuWrapper()88 const RefPtr<FrameNode>& GetMenuWrapper() const 89 { 90 return menuWrapper_; 91 } 92 GetMenuNode()93 RefPtr<FrameNode> GetMenuNode() const 94 { 95 CHECK_NULL_RETURN(menuWrapper_, nullptr); 96 return DynamicCast<FrameNode>(menuWrapper_->GetChildAtIndex(0)); 97 } 98 SetSelectSize(const SizeF & selectSize)99 void SetSelectSize(const SizeF& selectSize) 100 { 101 selectSize_ = selectSize; 102 } GetSelectSize()103 SizeF GetSelectSize() const 104 { 105 return selectSize_; 106 } 107 108 void AddOptionNode(const RefPtr<FrameNode>& option); 109 ClearOptions()110 void ClearOptions() 111 { 112 options_.clear(); 113 } 114 InitSelected()115 void InitSelected() 116 { 117 selected_ = -1; 118 } 119 GetSelected()120 int32_t GetSelected() const 121 { 122 return selected_; 123 } 124 125 void SetSelected(int32_t index); 126 127 // set properties of text node 128 void SetValue(const std::string& value); 129 void SetFontSize(const Dimension& value); 130 void SetItalicFontStyle(const Ace::FontStyle& value); 131 void SetFontWeight(const FontWeight& value); 132 void SetFontFamily(const std::vector<std::string>& value); 133 void SetFontColor(const Color& color); 134 135 // set props of option nodes 136 void SetOptionBgColor(const Color& color); 137 void SetOptionFontSize(const Dimension& value); 138 void SetOptionItalicFontStyle(const Ace::FontStyle& value); 139 void SetOptionFontWeight(const FontWeight& value); 140 void SetOptionFontFamily(const std::vector<std::string>& value); 141 void SetOptionFontColor(const Color& color); 142 143 // set props of option node when selected 144 void SetSelectedOptionBgColor(const Color& color); 145 void SetSelectedOptionFontSize(const Dimension& value); 146 void SetSelectedOptionItalicFontStyle(const Ace::FontStyle& value); 147 void SetSelectedOptionFontWeight(const FontWeight& value); 148 void SetSelectedOptionFontFamily(const std::vector<std::string>& value); 149 void SetSelectedOptionFontColor(const Color& color); 150 151 // set props of menu background 152 void SetMenuBackgroundColor(const Color& color); 153 void SetMenuBackgroundBlurStyle(const BlurStyleOption& blurStyle); 154 155 // Get functions for unit tests 156 const std::vector<RefPtr<FrameNode>>& GetOptions(); 157 GetFocusPattern()158 FocusPattern GetFocusPattern() const override 159 { 160 FocusPattern focusPattern = { FocusType::NODE, true, FocusStyleType::INNER_BORDER }; 161 auto pipelineContext = PipelineBase::GetCurrentContext(); 162 CHECK_NULL_RETURN(pipelineContext, focusPattern); 163 auto selectTheme = pipelineContext->GetTheme<SelectTheme>(); 164 CHECK_NULL_RETURN(selectTheme, focusPattern); 165 auto focusStyleType = 166 static_cast<FocusStyleType>(static_cast<int32_t>(selectTheme->GetSelectFocusStyleType_())); 167 focusPattern.SetStyleType(focusStyleType); 168 return focusPattern; 169 } 170 171 // update selected option props 172 void UpdateSelectedProps(int32_t index); 173 174 void UpdateLastSelectedProps(int32_t index); 175 176 // reset options props when selected index is -1 177 void ResetOptionProps(); 178 SetBgBlendColor(const Color & color)179 void SetBgBlendColor(const Color& color) 180 { 181 bgBlendColor_ = color; 182 } 183 GetBgBlendColor()184 Color GetBgBlendColor() const 185 { 186 return bgBlendColor_; 187 } 188 SetIsHover(bool isHover)189 void SetIsHover(bool isHover) 190 { 191 isHover_ = isHover; 192 } 193 IsHover()194 bool IsHover() const 195 { 196 return isHover_; 197 } 198 199 void SetShowInSubWindow(bool isShowInSubWindow); 200 void ResetShowInSubWindow(); 201 void SetShowDefaultSelectedIcon(bool show); 202 void ResetShowDefaultSelectedIcon(); 203 204 void SetItemSelected(int index, const std::string& value); 205 void PlayBgColorAnimation(bool isHoverChange = true); 206 void SetSpace(const Dimension& value); 207 void SetArrowPosition(const ArrowPosition value); 208 void SetMenuAlign(const MenuAlign& menuAlign); 209 void SetAvoidance(AvoidanceMode mode); 210 211 std::string GetValue(); 212 std::string ProvideRestoreInfo() override; 213 void OnRestoreInfo(const std::string& restoreInfo) override; 214 void OnColorConfigurationUpdate() override; 215 void OnLanguageConfigurationUpdate() override; 216 217 Dimension GetFontSize(); 218 void SetOptionWidth(const Dimension& value); 219 void SetOptionHeight(const Dimension& value); 220 void SetOptionWidthFitTrigger(bool isFitTrigger); 221 void ShowSelectMenu(); 222 void ShowSelectMenuInSubWindow(); 223 void SetHasOptionWidth(bool hasOptionWidth); 224 void SetControlSize(const ControlSize& controlSize); 225 void SetDivider(const SelectDivider& divider); 226 void SetDividerMode(const std::optional<DividerMode>& mode); 227 ControlSize GetControlSize(); 228 void SetLayoutDirection(TextDirection value); 229 Dimension GetSelectLeftRightMargin() const; 230 bool OnThemeScopeUpdate(int32_t themeScopeId) override; CreatePaintProperty()231 RefPtr<PaintProperty> CreatePaintProperty() override 232 { 233 return MakeRefPtr<SelectPaintProperty>(); 234 } CreateLayoutProperty()235 RefPtr<LayoutProperty> CreateLayoutProperty() override 236 { 237 return MakeRefPtr<SelectLayoutProperty>(); 238 } 239 void ResetFontColor(); 240 void SetMenuOutline(const MenuParam& menuParam); 241 void SetTextModifierApply(const std::function<void(WeakPtr<NG::FrameNode>)>& textApply); 242 void SetArrowModifierApply(const std::function<void(WeakPtr<NG::FrameNode>)>& arrowApply); 243 void SetArrowColor(const Color& color); 244 void SetOptionTextModifier(const std::function<void(WeakPtr<NG::FrameNode>)>& optionApply); 245 void SetSelectedOptionTextModifier(const std::function<void(WeakPtr<NG::FrameNode>)>& optionSelectedApply); 246 std::function<void(WeakPtr<NG::FrameNode>)>& GetTextModifier(); 247 std::function<void(WeakPtr<NG::FrameNode>)>& GetArrowModifier(); 248 void ResetOptionToInitProps( 249 const RefPtr<MenuItemPattern>& optionPattern, const RefPtr<MenuItemPattern>& selectingOptionPattern = nullptr); 250 void ResetSelectedOptionToInitProps(const RefPtr<MenuItemPattern>& optionPattern); 251 void UpdateOptionCustomProperties(const RefPtr<MenuItemPattern>& optionPattern); 252 void UpdateSelectedOptionCustomProperties(const RefPtr<MenuItemPattern>& optionPattern); 253 void ResetLastSelectedOptionFlags(const RefPtr<MenuItemPattern>& optionPattern); 254 void UpdateOptionFontFromPattern(const RefPtr<MenuItemPattern>& optionPattern); 255 void UpdateSelectedOptionFontFromPattern(const RefPtr<MenuItemPattern>& optionPattern); 256 void DumpInfo() override; 257 258 void UpdateComponentColor(const Color& color, const SelectColorType selectColorType); 259 void SetColorByUser(const RefPtr<FrameNode>& host, const RefPtr<SelectTheme>& theme); 260 void UpdateMenuOption(int32_t index, const std::string& value, const SelectOptionType optionType); 261 void SetMenuBackgroundColorByUser(const Color& color, const RefPtr<SelectPaintProperty>& props); 262 void SetModifierByUser(const RefPtr<SelectTheme>& theme, const RefPtr<SelectPaintProperty>& props); 263 void SetOptionBgColorByUser(const Color& color, const RefPtr<SelectPaintProperty>& props); 264 265 private: 266 void OnAttachToFrameNode() override; 267 void OnModifyDone() override; 268 void OnAfterModifyDone() override; 269 bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override; 270 void HandleFocusStyleTask(); 271 void HandleBlurStyleTask(); 272 void SetFocusStyle(); 273 void ClearFocusStyle(); 274 void ModFocusIconStyle(RefPtr<SelectTheme> selectTheme, bool focusedFlag); 275 void InitFocusEvent(); 276 void AddIsFocusActiveUpdateEvent(); 277 void RemoveIsFocusActiveUpdateEvent(); 278 void UpdateMenuScrollColorConfiguration(const RefPtr<FrameNode>& menuNode); 279 void SetOptionTextModifierByUser(const RefPtr<SelectTheme>& theme, const RefPtr<SelectPaintProperty>& props); 280 void SetSelectedOptionTextModifierByUser( 281 const RefPtr<SelectTheme>& theme, const RefPtr<SelectPaintProperty>& props); 282 void SetArrowModifierByUser(const RefPtr<SelectTheme>& theme, const RefPtr<SelectPaintProperty>& props); 283 void SetSelectedOptionBgColorByUser(const RefPtr<SelectTheme>& theme, const RefPtr<SelectPaintProperty>& props, 284 const RefPtr<SelectLayoutProperty>& layoutProps); HasRowNode()285 bool HasRowNode() const 286 { 287 return rowId_.has_value(); 288 } 289 HasTextNode()290 bool HasTextNode() const 291 { 292 return textId_.has_value(); 293 } 294 HasSpinnerNode()295 bool HasSpinnerNode() const 296 { 297 return spinnerId_.has_value(); 298 } 299 GetRowId()300 int32_t GetRowId() 301 { 302 if (!rowId_.has_value()) { 303 rowId_ = ElementRegister::GetInstance()->MakeUniqueId(); 304 } 305 return rowId_.value(); 306 } 307 GetTextId()308 int32_t GetTextId() 309 { 310 if (!textId_.has_value()) { 311 textId_ = ElementRegister::GetInstance()->MakeUniqueId(); 312 } 313 return textId_.value(); 314 } 315 GetSpinnerId()316 int32_t GetSpinnerId() 317 { 318 if (!spinnerId_.has_value()) { 319 spinnerId_ = ElementRegister::GetInstance()->MakeUniqueId(); 320 } 321 return spinnerId_.value(); 322 } 323 324 // change background color when pressed 325 void RegisterOnPress(); 326 // change background color when hovered 327 void RegisterOnHover(); 328 // add click event to show menu 329 void RegisterOnClick(); 330 void BindMenuTouch(FrameNode* targetNode, const RefPtr<GestureEventHub>& gestrueHub); 331 bool CheckSkipMenuShow(const RefPtr<FrameNode>& targetNode); 332 333 void RegisterOnKeyEvent(); 334 bool OnKeyEvent(const KeyEvent& event); 335 336 // callback when an option is selected 337 void CreateSelectedCallback(); 338 // change text and spinner color if disabled 339 void SetDisabledStyle(); 340 341 // update text to selected option's text 342 void UpdateText(int32_t index); 343 344 void InitTextProps(const RefPtr<TextLayoutProperty>& textProps); 345 void InitSpinner( 346 const RefPtr<FrameNode>& spinner, const RefPtr<IconTheme>& iconTheme, const RefPtr<SelectTheme>& selectTheme); 347 void InitSpinner(const RefPtr<FrameNode>& spinner, const RefPtr<SelectTheme>& selectTheme); 348 void ResetParams(); 349 void UpdateOptionsWidth(float selectWidth); 350 void UpdateTargetSize(); 351 bool GetShadowFromTheme(ShadowStyle shadowStyle, Shadow& shadow); 352 void ShowScrollBar(); 353 354 std::vector<RefPtr<FrameNode>> options_; 355 RefPtr<FrameNode> menuWrapper_ = nullptr; 356 RefPtr<FrameNode> text_ = nullptr; 357 RefPtr<FrameNode> spinner_ = nullptr; 358 SizeF selectSize_; 359 360 // index of selected option 361 int32_t selected_ = -1; 362 // props when selected 363 struct OptionFont { 364 // text style when selected 365 std::optional<Dimension> FontSize; 366 std::optional<Ace::FontStyle> FontStyle; 367 std::optional<FontWeight> FontWeight; 368 std::optional<std::vector<std::string>> FontFamily; 369 std::optional<Color> FontColor; 370 }; 371 OptionFont selectedFont_; 372 std::optional<Color> selectedBgColor_; 373 OptionFont optionFont_; 374 std::optional<Color> optionBgColor_; 375 std::optional<Color> fontColor_; 376 377 void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override; 378 void ToJsonSelectedOptionFontAndColor(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const; 379 void ToJsonArrowAndText(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const; 380 void ToJsonOptionAlign(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const; 381 void ToJsonMenuBackgroundStyle(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const; 382 void ToJsonDivider(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const; 383 void ToJsonDividerMode(std::unique_ptr<JsonValue>& json) const; 384 void ToJsonOptionMaxlines(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const; 385 // XTS inspector helper functions 386 std::string InspectorGetOptions() const; 387 std::string InspectorGetSelectedFont() const; 388 389 std::optional<int32_t> rowId_; 390 std::optional<int32_t> textId_; 391 std::optional<int32_t> spinnerId_; 392 393 Color bgBlendColor_ = Color::TRANSPARENT; 394 bool isHover_ = false; 395 bool isSelected_ = false; 396 MenuAlign menuAlign_; 397 std::string selectValue_; 398 bool isFitTrigger_ = false; 399 ControlSize controlSize_ = ControlSize::NORMAL; 400 bool bgColorModify_ = false; 401 bool scaleModify_ = false; 402 bool shadowModify_ = false; 403 std::function<void(bool)> isFocusActiveUpdateEvent_; 404 bool focusEventInitialized_ = false; 405 bool focusTextColorModify_ = false; 406 ACE_DISALLOW_COPY_AND_MOVE(SelectPattern); 407 std::function<void(WeakPtr<NG::FrameNode>)> arrowApply_ = nullptr; 408 std::function<void(WeakPtr<NG::FrameNode>)> textApply_ = nullptr; 409 std::function<void(WeakPtr<NG::FrameNode>)> textOptionApply_ = nullptr; 410 std::function<void(WeakPtr<NG::FrameNode>)> textSelectOptionApply_ = nullptr; 411 std::optional<Color> menuBackgroundColor_; 412 }; 413 414 } // namespace OHOS::Ace::NG 415 416 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SELECT_SELECT_PATTERN_H 417