• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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