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_model.h" 35 #include "core/components_ng/pattern/select/select_paint_property.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 FocusPattern focusPattern = { FocusType::NODE, true, FocusStyleType::INNER_BORDER }; 149 auto pipelineContext = PipelineBase::GetCurrentContext(); 150 CHECK_NULL_RETURN(pipelineContext, focusPattern); 151 auto selectTheme = pipelineContext->GetTheme<SelectTheme>(); 152 CHECK_NULL_RETURN(selectTheme, focusPattern); 153 auto focusStyleType = 154 static_cast<FocusStyleType>(static_cast<int32_t>(selectTheme->GetSelectFocusStyleType_())); 155 focusPattern.SetStyleType(focusStyleType); 156 return focusPattern; 157 } 158 159 // update selected option props 160 void UpdateSelectedProps(int32_t index); 161 162 void UpdateLastSelectedProps(int32_t index); 163 164 // reset options props when selected index is -1 165 void ResetOptionProps(); 166 SetBgBlendColor(const Color & color)167 void SetBgBlendColor(const Color& color) 168 { 169 bgBlendColor_ = color; 170 } 171 GetBgBlendColor()172 Color GetBgBlendColor() const 173 { 174 return bgBlendColor_; 175 } 176 SetIsHover(bool isHover)177 void SetIsHover(bool isHover) 178 { 179 isHover_ = isHover; 180 } 181 IsHover()182 bool IsHover() const 183 { 184 return isHover_; 185 } 186 187 void SetItemSelected(int index, const std::string& value); 188 void PlayBgColorAnimation(bool isHoverChange = true); 189 void SetSpace(const Dimension& value); 190 void SetArrowPosition(const ArrowPosition value); 191 void SetMenuAlign(const MenuAlign& menuAlign); 192 void SetAvoidance(const Avoidance& avoidance); 193 194 std::string GetValue(); 195 std::string ProvideRestoreInfo() override; 196 void OnRestoreInfo(const std::string& restoreInfo) override; 197 void OnColorConfigurationUpdate() override; 198 void OnLanguageConfigurationUpdate() override; 199 void ShowSelectMenu(); 200 201 Dimension GetFontSize(); 202 void SetOptionWidth(const Dimension& value); 203 void SetOptionHeight(const Dimension& value); 204 void SetOptionWidthFitTrigger(bool isFitTrigger); 205 void SetHasOptionWidth(bool hasOptionWidth); 206 void SetControlSize(const ControlSize& controlSize); 207 void SetDivider(const SelectDivider& divider); 208 void SetDividerMode(const std::optional<DividerMode>& mode); 209 ControlSize GetControlSize(); 210 void SetLayoutDirection(TextDirection value); 211 Dimension GetSelectLeftRightMargin() const; 212 bool OnThemeScopeUpdate(int32_t themeScopeId) override; CreatePaintProperty()213 RefPtr<PaintProperty> CreatePaintProperty() override 214 { 215 return MakeRefPtr<SelectPaintProperty>(); 216 } 217 void ResetFontColor(); 218 219 private: 220 void OnAttachToFrameNode() override; 221 void OnModifyDone() override; 222 void OnAfterModifyDone() override; 223 bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override; 224 void HandleFocusStyleTask(); 225 void HandleBlurStyleTask(); 226 void SetFocusStyle(); 227 void ClearFocusStyle(); 228 void ModFocusIconStyle(RefPtr<SelectTheme> selectTheme, bool focusedFlag); 229 void InitFocusEvent(); 230 void AddIsFocusActiveUpdateEvent(); 231 void RemoveIsFocusActiveUpdateEvent(); HasRowNode()232 bool HasRowNode() const 233 { 234 return rowId_.has_value(); 235 } 236 HasTextNode()237 bool HasTextNode() const 238 { 239 return textId_.has_value(); 240 } 241 HasSpinnerNode()242 bool HasSpinnerNode() const 243 { 244 return spinnerId_.has_value(); 245 } 246 GetRowId()247 int32_t GetRowId() 248 { 249 if (!rowId_.has_value()) { 250 rowId_ = ElementRegister::GetInstance()->MakeUniqueId(); 251 } 252 return rowId_.value(); 253 } 254 GetTextId()255 int32_t GetTextId() 256 { 257 if (!textId_.has_value()) { 258 textId_ = ElementRegister::GetInstance()->MakeUniqueId(); 259 } 260 return textId_.value(); 261 } 262 GetSpinnerId()263 int32_t GetSpinnerId() 264 { 265 if (!spinnerId_.has_value()) { 266 spinnerId_ = ElementRegister::GetInstance()->MakeUniqueId(); 267 } 268 return spinnerId_.value(); 269 } 270 271 // change background color when pressed 272 void RegisterOnPress(); 273 // change background color when hovered 274 void RegisterOnHover(); 275 // add click event to show menu 276 void RegisterOnClick(); 277 278 void RegisterOnKeyEvent(); 279 bool OnKeyEvent(const KeyEvent& event); 280 281 // callback when an option is selected 282 void CreateSelectedCallback(); 283 // change text and spinner color if disabled 284 void SetDisabledStyle(); 285 286 // update text to selected option's text 287 void UpdateText(int32_t index); 288 289 void InitTextProps(const RefPtr<TextLayoutProperty>& textProps); 290 void InitSpinner( 291 const RefPtr<FrameNode>& spinner, const RefPtr<IconTheme>& iconTheme, const RefPtr<SelectTheme>& selectTheme); 292 void InitSpinner(const RefPtr<FrameNode>& spinner, const RefPtr<SelectTheme>& selectTheme); 293 void ResetParams(); 294 void UpdateOptionsWidth(float selectWidth); 295 void UpdateTargetSize(); 296 bool GetShadowFromTheme(ShadowStyle shadowStyle, Shadow& shadow); 297 298 std::vector<RefPtr<FrameNode>> options_; 299 RefPtr<FrameNode> menuWrapper_ = nullptr; 300 RefPtr<FrameNode> text_ = nullptr; 301 RefPtr<FrameNode> spinner_ = nullptr; 302 SizeF selectSize_; 303 304 // index of selected option 305 int32_t selected_ = -1; 306 // props when selected 307 struct OptionFont { 308 // text style when selected 309 std::optional<Dimension> FontSize; 310 std::optional<Ace::FontStyle> FontStyle; 311 std::optional<FontWeight> FontWeight; 312 std::optional<std::vector<std::string>> FontFamily; 313 std::optional<Color> FontColor; 314 }; 315 OptionFont selectedFont_; 316 std::optional<Color> selectedBgColor_; 317 OptionFont optionFont_; 318 std::optional<Color> optionBgColor_; 319 std::optional<Color> fontColor_; 320 321 void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override; 322 void ToJsonArrowAndText(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const; 323 void ToJsonOptionAlign(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const; 324 void ToJsonMenuBackgroundStyle(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const; 325 void ToJsonDivider(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const; 326 // XTS inspector helper functions 327 std::string InspectorGetOptions() const; 328 std::string InspectorGetSelectedFont() const; 329 330 std::optional<int32_t> rowId_; 331 std::optional<int32_t> textId_; 332 std::optional<int32_t> spinnerId_; 333 334 Color bgBlendColor_ = Color::TRANSPARENT; 335 bool isHover_ = false; 336 bool isSelected_ = false; 337 MenuAlign menuAlign_; 338 Avoidance avoidance_; 339 std::string selectValue_; 340 bool isFitTrigger_ = false; 341 ControlSize controlSize_ = ControlSize::NORMAL; 342 bool bgColorModify_ = false; 343 bool scaleModify_ = false; 344 bool shadowModify_ = false; 345 std::function<void(bool)> isFocusActiveUpdateEvent_; 346 bool focusEventInitialized_ = false; 347 bool focusTextColorModify_ = false; 348 ACE_DISALLOW_COPY_AND_MOVE(SelectPattern); 349 }; 350 351 } // namespace OHOS::Ace::NG 352 353 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SELECT_SELECT_PATTERN_H 354