• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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_MENU_MENU_ITEM_PATTERN_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_MENU_MENU_ITEM_PATTERN_H
18 
19 #include "base/memory/referenced.h"
20 #include "base/utils/noncopyable.h"
21 #include "base/thread/cancelable_callback.h"
22 #include "core/components/slider/render_slider.h"
23 #include "core/components_ng/base/view_abstract.h"
24 #include "core/components_ng/event/long_press_event.h"
25 #include "core/components_ng/pattern/menu/menu_item/menu_item_accessibility_property.h"
26 #include "core/components_ng/pattern/menu/menu_item/menu_item_event_hub.h"
27 #include "core/components_ng/pattern/menu/menu_item/menu_item_layout_algorithm.h"
28 #include "core/components_ng/pattern/menu/menu_item/menu_item_layout_property.h"
29 #include "core/components_ng/pattern/menu/menu_item/menu_item_paint_method.h"
30 #include "core/components_ng/pattern/menu/menu_item/menu_item_paint_property.h"
31 #include "core/components_ng/pattern/menu/menu_pattern.h"
32 #include "core/components_ng/pattern/menu/menu_theme.h"
33 #include "core/components_ng/pattern/pattern.h"
34 
35 namespace OHOS::Ace::NG {
36 enum class ShowSubMenuType : int32_t {
37     DEFAULT = 0,
38     HOVER = 1,
39     CLICK = 2,
40     LONG_PRESS = 3,
41     KEY_DPAD_RIGHT = 4,
42     ACTION = 5
43 };
44 class ACE_EXPORT MenuItemPattern : public Pattern {
45     DECLARE_ACE_TYPE(MenuItemPattern, Pattern);
46 
47 public:
index_(index)48     MenuItemPattern(bool isOptionPattern = false, int index = -1) : index_(index), isOptionPattern_(isOptionPattern) {}
49     ~MenuItemPattern() override = default;
50 
IsAtomicNode()51     inline bool IsAtomicNode() const override
52     {
53         return false;
54     }
55 
GetFocusPattern()56     inline FocusPattern GetFocusPattern() const override
57     {
58         FocusPattern focusPattern = { FocusType::NODE, true, FocusStyleType::INNER_BORDER };
59         auto host = GetHost();
60         CHECK_NULL_RETURN(host, focusPattern);
61         auto pipelineContext = host->GetContext();
62         CHECK_NULL_RETURN(pipelineContext, focusPattern);
63         if (isOptionPattern_) {
64             auto selectTheme = pipelineContext->GetTheme<SelectTheme>();
65             CHECK_NULL_RETURN(selectTheme, focusPattern);
66             auto focusStyleType =
67                 static_cast<FocusStyleType>(static_cast<int32_t>(selectTheme->GetOptionFocusStyleType_()));
68             focusPattern.SetStyleType(focusStyleType);
69             return focusPattern;
70         } else {
71             auto menuTheme = pipelineContext->GetTheme<MenuTheme>();
72             CHECK_NULL_RETURN(menuTheme, focusPattern);
73             auto focusStyleType =
74                 static_cast<FocusStyleType>(static_cast<int32_t>(menuTheme->GetFocusStyleType()));
75             focusPattern.SetStyleType(focusStyleType);
76             return focusPattern;
77         }
78     }
79 
CreateEventHub()80     inline RefPtr<EventHub> CreateEventHub() override
81     {
82         return MakeRefPtr<MenuItemEventHub>();
83     }
84 
CreateLayoutProperty()85     inline RefPtr<LayoutProperty> CreateLayoutProperty() override
86     {
87         return MakeRefPtr<MenuItemLayoutProperty>();
88     }
89 
CreateAccessibilityProperty()90     inline RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override
91     {
92         return MakeRefPtr<MenuItemAccessibilityProperty>(isOptionPattern_);
93     }
94 
CreateLayoutAlgorithm()95     inline RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override
96     {
97         return MakeRefPtr<MenuItemLayoutAlgorithm>(isOptionPattern_);
98     }
99 
CreateNodePaintMethod()100     inline RefPtr<NodePaintMethod> CreateNodePaintMethod() override
101     {
102         return MakeRefPtr<MenuItemPaintMethod>(isOptionPattern_);
103     }
104 
CreatePaintProperty()105     inline RefPtr<PaintProperty> CreatePaintProperty() override
106     {
107         return MakeRefPtr<MenuItemPaintProperty>(isOptionPattern_);
108     }
109 
110     void MarkIsSelected(bool isSelected);
SetSelected(bool isSelected)111     void SetSelected(bool isSelected)
112     {
113         isSelected_ = isSelected;
114         if (!isOptionPattern_) {
115             GetHost()->MarkModifyDone();
116         }
117         UpdateDividerSelectedStatus(isSelected_);
118     }
119 
IsSelected()120     bool IsSelected() const
121     {
122         return isSelected_;
123     }
124 
SetSubBuilder(const std::function<void ()> & subBuilderFunc)125     void SetSubBuilder(const std::function<void()>& subBuilderFunc)
126     {
127         subBuilderFunc_ = subBuilderFunc;
128     }
129 
GetSubBuilder()130     std::function<void()>& GetSubBuilder()
131     {
132         return subBuilderFunc_;
133     }
134 
IsSubMenuShowed()135     bool IsSubMenuShowed() const
136     {
137         return isSubMenuShowed_;
138     }
139 
SetIsSubMenuShowed(bool isSubMenuShowed)140     void SetIsSubMenuShowed(bool isSubMenuShowed)
141     {
142         isSubMenuShowed_ = isSubMenuShowed;
143     }
144 
IsSubMenuHovered()145     bool IsSubMenuHovered() const
146     {
147         return isSubMenuHovered_;
148     }
149 
SetIsSubMenuHovered(bool isSubMenuHovered)150     void SetIsSubMenuHovered(bool isSubMenuHovered)
151     {
152         isSubMenuHovered_ = isSubMenuHovered;
153     }
154 
155     void AddHoverRegions(const OffsetF& topLeftPoint, const OffsetF& bottomRightPoint);
156 
157     bool IsInHoverRegions(double x, double y);
158 
ClearHoverRegions()159     void ClearHoverRegions()
160     {
161         hoverRegions_.clear();
162     }
163 
ResetWrapperMouseEvent()164     void ResetWrapperMouseEvent()
165     {
166         wrapperMouseEvent_.Reset();
167     }
168 
SetChange()169     void SetChange()
170     {
171         isSelected_ = !isSelected_;
172         UpdateDividerSelectedStatus(isSelected_);
173     }
174 
IsChange()175     bool IsChange() const
176     {
177         return isChanged_;
178     }
179 
180     void CloseMenu();
181 
GetContentNode()182     RefPtr<FrameNode> GetContentNode()
183     {
184         return content_;
185     }
186 
GetLabelNode()187     RefPtr<FrameNode> GetLabelNode()
188     {
189         return label_;
190     }
191 
GetBottomDivider()192     RefPtr<FrameNode> GetBottomDivider()
193     {
194         return bottomDivider_;
195     }
196 
SetTopDivider(WeakPtr<FrameNode> topDivider)197     void SetTopDivider(WeakPtr<FrameNode> topDivider)
198     {
199         topDivider_ = topDivider;
200     }
201 
GetTopDivider()202     RefPtr<FrameNode> GetTopDivider()
203     {
204         return topDivider_.Upgrade();
205     }
206 
207     void PlayBgColorAnimation(bool isHoverChange = true);
SetBgBlendColor(const Color & color)208     void SetBgBlendColor(const Color& color)
209     {
210         bgBlendColor_ = color;
211     }
GetBgBlendColor()212     Color GetBgBlendColor() const
213     {
214         return bgBlendColor_;
215     }
216     bool IsDisabled();
217 
218     RefPtr<FrameNode> GetMenu(bool needTopMenu = false);
219     RefPtr<MenuPattern> GetMenuPattern(bool needTopMenu = false);
220     void UpdateTextNodes();
221 
222     void OnAttachToFrameNode() override;
223     void OnModifyDone() override;
224     void OnMountToParentDone() override;
225 
HasSelectIcon()226     bool HasSelectIcon() const
227     {
228         return selectIcon_ != nullptr;
229     }
HasStartIcon()230     bool HasStartIcon() const
231     {
232         return startIcon_ != nullptr;
233     }
234 
SetClickMenuItemId(int32_t id)235     void SetClickMenuItemId(int32_t id)
236     {
237         clickMenuItemId_ = id;
238     }
239 
GetClickMenuItemId()240     int32_t GetClickMenuItemId() const
241     {
242         return clickMenuItemId_;
243     }
244 
SetOnClickAIMenuItem(std::function<void ()> onClickAIMenuItem)245     void SetOnClickAIMenuItem(std::function<void()> onClickAIMenuItem)
246     {
247         onClickAIMenuItem_ = onClickAIMenuItem;
248     }
249 
250     void OnVisibleChange(bool isVisible) override;
251     void InitLongPressEvent();
252     void UpdateNeedDivider(bool need);
253     void CheckHideSubMenu(std::function<void()> callback, const PointF& mousePoint, const RectF& menuZone);
254     bool NeedPerformHideSubMenuImmediately(const PointF& mousePoint, const RectF& menuZone);
255     bool NeedStartHideMenuTask(const PointF& mousePoint, const RectF& menuZone);
256     bool NeedStartHideRightSubMenuTask(const PointF& lastInnerPoint, const PointF& mousePoint, const RectF& menuZone);
257     bool NeedStartHideLeftSubMenuTask(const PointF& lastInnerPoint, const PointF& mousePoint, const RectF& menuZone);
258     void CancelHideSubMenuTask(const PointF& mousePoint);
SetIndex(int32_t index)259     void SetIndex(int32_t index)
260     {
261         index_ = index;
262     }
263     float GetDividerStroke();
264 
GetExpandingMode()265     SubMenuExpandingMode GetExpandingMode()
266     {
267         return expandingMode_;
268     }
269     bool IsSubMenu();
270     bool IsEmbedded();
SetIsStackSubmenuHeader()271     void SetIsStackSubmenuHeader()
272     {
273         isStackSubmenuHeader_ = true;
274     }
IsStackSubmenuHeader()275     bool IsStackSubmenuHeader()
276     {
277         return isStackSubmenuHeader_;
278     }
279     RefPtr<FrameNode> FindTouchedEmbeddedMenuItem(const PointF& position);
GetEmbeddedMenu()280     RefPtr<FrameNode> GetEmbeddedMenu() const
281     {
282         return embeddedMenu_;
283     }
284     void HideEmbedded(bool isNeedAnimation = true);
285     void OnHover(bool isHover);
286     void NotifyPressStatus(bool isPress);
287     void SetBgColor(const Color& color);
288     void SetFontColor(const Color& color);
289     void SetFontFamily(const std::vector<std::string>& value);
290     void SetFontSize(const Dimension& value);
291     void SetFontWeight(const FontWeight& value);
292     void SetItalicFontStyle(const Ace::FontStyle& value);
293     void SetSelected(int32_t selected);
294     void SetBorderColor(const Color& color);
295     Color GetBorderColor() const;
296     void SetBorderWidth(const Dimension& value);
297     Dimension GetBorderWidth() const;
298     void UpdateIcon(const std::string& src, const std::function<void(WeakPtr<NG::FrameNode>)> symbolIcon);
299     void UpdateNextNodeDivider(bool needDivider);
300     void UpdateText(const std::string& content);
301     Color GetBgColor();
302     Color GetFontColor();
303     Dimension GetFontSize();
304     Ace::FontStyle GetItalicFontStyle();
305     FontWeight GetFontWeight();
306     std::vector<std::string> GetFontFamily();
307     std::string GetText();
308     // XTS inspector functions
309     std::string InspectorGetFont();
310     float GetSelectOptionWidth();
311 
SetIcon(const std::string & src)312     inline void SetIcon(const std::string& src)
313     {
314         iconSrc_ = src;
315     }
GetIcon()316     inline const std::string& GetIcon()
317     {
318         return iconSrc_;
319     }
SetIsHover(bool isHover)320     inline void SetIsHover(bool isHover)
321     {
322         isHover_ = isHover;
323     }
IsHover()324     inline bool IsHover() const
325     {
326         return isHover_;
327     }
SetMenu(const WeakPtr<FrameNode> & menuWeak)328     inline void SetMenu(const WeakPtr<FrameNode>& menuWeak)
329     {
330         menuWeak_ = menuWeak;
331     }
GetMenuWeak()332     inline const WeakPtr<FrameNode>& GetMenuWeak() const
333     {
334         return menuWeak_;
335     }
SetIsWidthModifiedBySelect(bool isModified)336     inline void SetIsWidthModifiedBySelect(bool isModified)
337     {
338         isWidthModifiedBySelect_ = isModified;
339     }
IsWidthModifiedBySelect()340     inline bool IsWidthModifiedBySelect() const
341     {
342         return isWidthModifiedBySelect_;
343     }
SetIsSelectOption(bool isSelect)344     inline void SetIsSelectOption(bool isSelect)
345     {
346         isSelectOption_ = isSelect;
347     }
IsSelectOption()348     inline bool IsSelectOption() const
349     {
350         return isSelectOption_;
351     }
SetHasOptionWidth(bool hasOptionWidth)352     inline void SetHasOptionWidth(bool hasOptionWidth)
353     {
354         hasOptionWidth_ = hasOptionWidth;
355     }
GetHasOptionWidth()356     inline bool GetHasOptionWidth()
357     {
358         return hasOptionWidth_;
359     }
GetSelectTheme()360     inline const RefPtr<SelectTheme>& GetSelectTheme() const
361     {
362         return selectTheme_;
363     }
SetBlockClick(bool blockClick)364     inline void SetBlockClick(bool blockClick)
365     {
366         blockClick_ = blockClick;
367     }
SetTextNode(const RefPtr<FrameNode> & text)368     inline void SetTextNode(const RefPtr<FrameNode>& text)
369     {
370         text_ = text;
371     }
GetTextNode()372     inline RefPtr<FrameNode> GetTextNode() const
373     {
374         return text_;
375     }
SetIconNode(const RefPtr<FrameNode> & icon)376     inline void SetIconNode(const RefPtr<FrameNode>& icon)
377     {
378         icon_ = icon;
379     }
SetPasteButton(const RefPtr<FrameNode> & pasteButton)380     inline void SetPasteButton(const RefPtr<FrameNode>& pasteButton)
381     {
382         pasteButton_ = pasteButton;
383     }
SetIsBGColorSetByUser(bool isSet)384     inline void SetIsBGColorSetByUser(bool isSet)
385     {
386         isBGColorSetByUser_ = isSet;
387     }
SetIsTextColorSetByUser(bool isSet)388     inline void SetIsTextColorSetByUser(bool isSet)
389     {
390         isTextColorSetByUser_ = isSet;
391     }
SetIsOptionFontColorSetByUser(bool isSet)392     inline void SetIsOptionFontColorSetByUser(bool isSet)
393     {
394         isOptionFontColorSetByUser_ = isSet;
395     }
SetSelectFontColor(const Color & color)396     inline void SetSelectFontColor(const Color& color)
397     {
398         selectFontColor_ = color;
399     }
SetOptionFontColor(const Color & color)400     inline void SetOptionFontColor(const Color& color)
401     {
402         optionFontColor_ = color;
403     }
SetIsOptionBgColorSetByUser(bool isSet)404     inline void SetIsOptionBgColorSetByUser(bool isSet)
405     {
406         isOptionBgColorSetByUser_ = isSet;
407     }
SetOptionBgColor(const Color & color)408     inline void SetOptionBgColor(const Color& color)
409     {
410         optionBgColor_ = color;
411     }
412     void AttachBottomDivider();
413     void RemoveBottomDivider();
414 
415 protected:
416     void RegisterOnKeyEvent();
417     void RegisterOnTouch();
418     void CreateBottomDivider();
419     void OnAfterModifyDone() override;
420     RefPtr<FrameNode> GetMenuWrapper();
421     void InitFocusPadding();
422     Dimension focusPadding_ = 0.0_vp;
423     double menuFocusType_ = 0.0;
424 
425 private:
426     friend class ServiceCollaborationMenuAceHelper;
427     // register menu item's callback
428     void RegisterOnClick();
429     void RegisterOnHover();
430     void CleanParentMenuItemBgColor();
431     void SendSubMenuOpenToAccessibility(RefPtr<FrameNode>& subMenu, ShowSubMenuType type);
432     virtual void OnTouch(const TouchEventInfo& info);
433     virtual bool OnKeyEvent(const KeyEvent& event);
IsCustomMenuItem()434     virtual bool IsCustomMenuItem()
435     {
436         return false;
437     }
438     bool OnClick();
439 
440     void RegisterWrapperMouseEvent();
441 
442     void AddSelectIcon(RefPtr<FrameNode>& row);
443     void UpdateIcon(RefPtr<FrameNode>& row, bool isStart);
444     void AddExpandIcon(RefPtr<FrameNode>& row);
445     void AddClickableArea();
446     void SetRowAccessibilityLevel();
447     void UpdateText(RefPtr<FrameNode>& row, RefPtr<MenuLayoutProperty>& menuProperty, bool isLabel);
448     void UpdateTextMarquee(bool isMarqueeStart);
449     void UpdateTextOverflow(RefPtr<TextLayoutProperty>& textProperty, RefPtr<SelectTheme>& theme);
450     void InitTextFadeOut();
451     void UpdateFont(RefPtr<MenuLayoutProperty>& menuProperty, RefPtr<SelectTheme>& theme, bool isLabel);
452     void SetThemeProps(const RefPtr<FrameNode>& host);
453     void UpdateMaxLinesFromTheme(RefPtr<TextLayoutProperty>& textProperty);
454     void AddStackSubMenuHeader(RefPtr<FrameNode>& menuNode);
455     RefPtr<FrameNode> GetClickableArea();
456     void UpdateDisabledStyle();
457 
458     void ShowSubMenu(ShowSubMenuType type = ShowSubMenuType::DEFAULT);
459     RefPtr<UINode> BuildSubMenuCustomNode();
460     RefPtr<FrameNode> GetSubMenu(RefPtr<UINode>& customNode);
461     void UpdateSubmenuExpandingMode(RefPtr<UINode>& customNode);
462     void ShowSubMenuHelper(const RefPtr<FrameNode>& subMenu);
463     void HideSubMenu();
464     void OnExpandChanged(const RefPtr<FrameNode>& expandableNode);
465     void HideEmbeddedExpandMenu(const RefPtr<FrameNode>& expandableNode, bool isNeedAnimation = true);
466     void ShowEmbeddedExpandMenu(const RefPtr<FrameNode>& expandableNode);
467     void SetShowEmbeddedMenuParams(const RefPtr<FrameNode>& expandableNode);
468     void UpdatePreviewPosition(SizeF oldMenuSize, SizeF menuSize);
469     void MenuRemoveChild(const RefPtr<FrameNode>& expandableNode, bool isOutFocus);
470 
471     OffsetF GetSubMenuPosition(const RefPtr<FrameNode>& targetNode);
472 
473     void AddSelfHoverRegion(const RefPtr<FrameNode>& targetNode);
474     void SetAccessibilityAction();
475     bool IsSelectOverlayMenu();
476     void RecordChangeEvent() const;
477     bool ParseMenuBlurStyleEffect(MenuParam& param, const RefPtr<RenderContext>& parseMenuBlurStyleEffect);
478     void ParseMenuRadius(MenuParam& param);
479     void ModifyDivider();
480 
481     void NeedFocusEvent();
482     void InitFocusEvent();
483     void HandleFocusEvent();
484     void HandleBlurEvent();
485     bool GetShadowFromTheme(ShadowStyle shadowStyle, Shadow& shadow);
486 
487     void UpdateSymbolNode(RefPtr<FrameNode>& row, RefPtr<FrameNode>& selectIcon);
488     void UpdateImageNode(RefPtr<FrameNode>& row, RefPtr<FrameNode>& selectIcon);
489     void UpdateSymbolIcon(RefPtr<FrameNode>& row, RefPtr<FrameNode>& iconNode, ImageSourceInfo& iconSrc,
490         std::function<void(WeakPtr<NG::FrameNode>)>& symbol, bool isStart);
491     void UpdateImageIcon(RefPtr<FrameNode>& row, RefPtr<FrameNode>& iconNode, ImageSourceInfo& iconSrc,
492         std::function<void(WeakPtr<NG::FrameNode>)>& symbol, bool isStart);
493     bool UseDefaultThemeIcon(const ImageSourceInfo& imageSourceInfo);
494 
495     void OnPress(const TouchEventInfo& info);
496     bool OnSelectProcess();
497     void OptionOnModifyDone(const RefPtr<FrameNode>& host);
498     void UpdateIconSrc();
499     bool UpdateOptionFocus(KeyCode code);
500     void UpdatePasteFontColor(const Color& fontColor);
501     void UpdatePasteDisabledOpacity(const double disabledColorAlpha);
502     void OptionHandleFocusEvent();
503     void OptionHandleBlurEvent();
504     void SetFocusStyle();
505     void ClearFocusStyle();
506     void PostHoverSubMenuTask();
507     void PerformHideSubMenu(std::function<void()> callback);
508     void UpdateDividerSelectedStatus(bool isSelected);
509     void UpdateDividerHoverStatus(bool isHover);
510     void UpdateDividerPressStatus(bool isPress);
IsOptionPattern()511     inline bool IsOptionPattern()
512     {
513         return isOptionPattern_;
514     }
515     // make render after measure and layout
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,const DirtySwapConfig & config)516     inline bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override
517     {
518         return !(config.skipMeasure && config.skipLayout);
519     }
520 
521     std::list<TouchRegion> hoverRegions_;
522 
523     RefPtr<InputEvent> wrapperMouseEvent_;
524 
525     bool isSelected_ = false;
526     bool isSubMenuShowed_ = false;
527     bool isSubMenuHovered_ = false;
528 
529     bool isChanged_ = false;
530     bool isHovered_ = false;
531     bool isExpanded_ = false;
532     int32_t clickMenuItemId_ = -1;
533     std::function<void()> onClickAIMenuItem_ = nullptr;
534     int32_t index_ = 0;
535 
536     std::function<void()> subBuilderFunc_ = nullptr;
537 
538     int32_t subMenuId_ = -1;
539     RefPtr<FrameNode> subMenu_;
540     RefPtr<FrameNode> content_ = nullptr;
541     RefPtr<FrameNode> label_ = nullptr;
542     RefPtr<FrameNode> startIcon_ = nullptr;
543     RefPtr<FrameNode> endIcon_ = nullptr;
544     RefPtr<FrameNode> selectIcon_ = nullptr;
545     RefPtr<FrameNode> expandIcon_ = nullptr;
546     RefPtr<FrameNode> embeddedMenu_ = nullptr;
547     RefPtr<FrameNode> clickableArea_ = nullptr;
548     RefPtr<FrameNode> bottomDivider_ = nullptr;
549     WeakPtr<FrameNode> topDivider_ = nullptr;
550     RefPtr<LongPressEvent> longPressEvent_;
551     RefPtr<TouchEventImpl> onTouchEvent_;
552     RefPtr<InputEvent> onHoverEvent_;
553     RefPtr<ClickEvent> onClickEvent_;
554     bool onTouchEventSet_ = false;
555     bool onHoverEventSet_ = false;
556     bool onKeyEventSet_ = false;
557     bool onClickEventSet_ = false;
558     SubMenuExpandingMode expandingMode_ = SubMenuExpandingMode::SIDE;
559     bool isStackSubmenuHeader_ = false;
560     bool expandingModeSet_ = false;
561 
562     Color bgBlendColor_ = Color::TRANSPARENT;
563     std::optional<Color> bgColor_;
564     std::optional<Color> selectFontColor_;
565     std::optional<Color> optionFontColor_;
566     std::optional<Color> optionBgColor_;
567     std::function<void(bool)> isFocusActiveUpdateEvent_;
568     // src of icon image, used in XTS inspector
569     std::string iconSrc_;
570     WeakPtr<FrameNode> menuWeak_;
571     RefPtr<FrameNode> text_;
572     RefPtr<FrameNode> icon_;
573     RefPtr<FrameNode> pasteButton_;
574     RefPtr<TextTheme> textTheme_;
575     RefPtr<SelectTheme> selectTheme_;
576 
577     bool blockClick_ = false;
578     bool hasOptionWidth_ = false;
579     bool isHover_ = false;
580     bool isOptionPattern_ = false;  // if it is OptionPattern
581     bool isSelectOption_ = false;
582     bool isWidthModifiedBySelect_ = false;
583 
584     bool isFocused_ = false;
585     bool isFocusShadowSet_ = false;
586     bool isFocusBGColorSet_ = false;
587     bool isTextFadeOut_ = false;
588     bool isBGColorSetByUser_ = false;
589     bool isTextColorSetByUser_ = false;
590     bool isOptionFontColorSetByUser_ = false;
591     bool isOptionBgColorSetByUser_ = false;
592     int32_t rowSelected_ = -1;
593     CancelableCallback<void()> showTask_;
594     CancelableCallback<void()> hideTask_;
595     std::optional<PointF> lastInnerPosition_ = std::nullopt;
596     std::optional<PointF> lastOutterPosition_ = std::nullopt;
597     bool leaveFromBottom_ = false;
598 
599     ACE_DISALLOW_COPY_AND_MOVE(MenuItemPattern);
600 };
601 
602 class CustomMenuItemPattern : public MenuItemPattern {
603     DECLARE_ACE_TYPE(CustomMenuItemPattern, MenuItemPattern);
604 
605 public:
CreateLayoutAlgorithm()606     RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override
607     {
608         return MakeRefPtr<BoxLayoutAlgorithm>();
609     }
610     void OnAttachToFrameNode() override;
611 
612 private:
613     void OnTouch(const TouchEventInfo& info) override;
614     void HandleOnChange();
615     bool OnKeyEvent(const KeyEvent& event) override;
IsCustomMenuItem()616     bool IsCustomMenuItem() override
617     {
618         return true;
619     }
620     std::unique_ptr<Offset> lastTouchOffset_;
621 };
622 } // namespace OHOS::Ace::NG
623 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_MENU_MENU_ITEM_PATTERN_H
624