• 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_MENU_MENU_PATTERN_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_MENU_MENU_PATTERN_H
18 
19 #include <optional>
20 #include <vector>
21 
22 #include "base/geometry/dimension.h"
23 #include "base/geometry/ng/size_t.h"
24 #include "base/memory/referenced.h"
25 #include "base/utils/utils.h"
26 #include "core/components_ng/base/symbol_modifier.h"
27 #include "core/components_ng/pattern/menu/menu_accessibility_property.h"
28 #include "core/components_ng/pattern/menu/menu_layout_algorithm.h"
29 #include "core/components_ng/pattern/menu/menu_layout_property.h"
30 #include "core/components_ng/pattern/menu/menu_paint_method.h"
31 #include "core/components_ng/pattern/menu/menu_paint_property.h"
32 #include "core/components_ng/pattern/menu/menu_theme.h"
33 #include "core/components_ng/pattern/menu/wrapper/menu_wrapper_paint_method.h"
34 #include "core/components_ng/pattern/menu/wrapper/menu_wrapper_paint_property.h"
35 #include "core/components_ng/pattern/pattern.h"
36 #include "core/components_ng/pattern/select/select_model.h"
37 #include "core/components_ng/property/border_property.h"
38 #include "core/components_ng/property/menu_property.h"
39 #include "core/components_v2/inspector/inspector_constants.h"
40 
41 constexpr int32_t DEFAULT_CLICK_DISTANCE = 15;
42 constexpr uint32_t MAX_SEARCH_DEPTH = 5;
43 constexpr double MENU_ANIMATION_MAX_SCALE = 1.0f;
44 constexpr double MENU_ANIMATION_MIN_OPACITY = 0.0f;
45 constexpr double MENU_ANIMATION_MAX_OPACITY = 1.0f;
46 namespace OHOS::Ace::NG {
47 
48 struct SelectProperties {
49     std::string value;
50     std::string icon;
51     RefPtr<SymbolModifier> symbolModifier;
52     int index;
53     bool selected = false;
54     bool selectEnable = true;
55 };
56 
57 struct MenuItemInfo {
58     OffsetF originOffset = OffsetF();
59     OffsetF endOffset = OffsetF();
60     bool isFindTargetId = false;
61 };
62 
63 struct PreviewMenuAnimationInfo {
64     BorderRadiusProperty borderRadius = BorderRadiusProperty(Dimension(-1.0f));
65 
66     // for hoverScale animation
67     float clipRate = -1.0f;
68 };
69 
70 class MenuPattern : public Pattern, public FocusView {
71     DECLARE_ACE_TYPE(MenuPattern, Pattern, FocusView);
72 
73 public:
MenuPattern(int32_t targetId,std::string tag,MenuType type)74     MenuPattern(int32_t targetId, std::string tag, MenuType type)
75         : targetId_(targetId), targetTag_(std::move(tag)), type_(type)
76     {}
77     ~MenuPattern() override = default;
78 
IsAtomicNode()79     bool IsAtomicNode() const override
80     {
81         return false;
82     }
83 
GetFocusPattern()84     FocusPattern GetFocusPattern() const override
85     {
86         return { FocusType::SCOPE, true };
87     }
88 
GetRouteOfFirstScope()89     std::list<int32_t> GetRouteOfFirstScope() override
90     {
91         return { 0, 0 };
92     }
93 
IsEnableMatchParent()94     bool IsEnableMatchParent() override
95     {
96         return IsMultiMenu();
97     }
98 
IsEnableChildrenMatchParent()99     bool IsEnableChildrenMatchParent() override
100     {
101         return IsMultiMenu();
102     }
103 
IsEnableFix()104     bool IsEnableFix() override
105     {
106         return IsMultiMenu();
107     }
108 
ChildPreMeasureHelperEnabled()109     bool ChildPreMeasureHelperEnabled() override
110     {
111         return true;
112     }
113 
PostponedTaskForIgnoreEnabled()114     bool PostponedTaskForIgnoreEnabled() override
115     {
116         return true;
117     }
118 
IsEnabledContentForFixIdeal()119     bool IsEnabledContentForFixIdeal()
120     {
121         return IsMultiMenu();
122     }
123 
IsFocusViewLegal()124     bool IsFocusViewLegal() override
125     {
126         return type_ == MenuType::MENU || type_ == MenuType::CONTEXT_MENU || type_ == MenuType::SUB_MENU;
127     }
128 
CreateLayoutProperty()129     RefPtr<LayoutProperty> CreateLayoutProperty() override
130     {
131         return MakeRefPtr<MenuLayoutProperty>();
132     }
133 
CreateAccessibilityProperty()134     RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override
135     {
136         return MakeRefPtr<MenuAccessibilityProperty>();
137     }
138 
139     RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override;
140 
CreatePaintProperty()141     RefPtr<PaintProperty> CreatePaintProperty() override
142     {
143         return MakeRefPtr<MenuPaintProperty>();
144     }
145 
CreateNodePaintMethod()146     RefPtr<NodePaintMethod> CreateNodePaintMethod() override
147     {
148         return AceType::MakeRefPtr<MenuPaintMethod>();
149     }
150 
GetMenuType()151     MenuType GetMenuType() const
152     {
153         return type_;
154     }
155 
IsContextMenu()156     bool IsContextMenu() const
157     {
158         return type_ == MenuType::CONTEXT_MENU;
159     }
160 
SetPreviewMode(MenuPreviewMode mode)161     void SetPreviewMode(MenuPreviewMode mode)
162     {
163         previewMode_ = mode;
164     }
165 
GetPreviewMode()166     MenuPreviewMode GetPreviewMode() const
167     {
168         return previewMode_;
169     }
170 
SetPreviewBeforeAnimationScale(float scaleBeforeAnimation)171     void SetPreviewBeforeAnimationScale(float scaleBeforeAnimation)
172     {
173         previewAnimationOptions_.scaleFrom = scaleBeforeAnimation;
174     }
175 
GetPreviewBeforeAnimationScale()176     float GetPreviewBeforeAnimationScale() const
177     {
178         return previewAnimationOptions_.scaleFrom;
179     }
180 
SetPreviewAfterAnimationScale(float scaleAfterAnimation)181     void SetPreviewAfterAnimationScale(float scaleAfterAnimation)
182     {
183         previewAnimationOptions_.scaleTo = scaleAfterAnimation;
184     }
185 
GetPreviewAfterAnimationScale()186     float GetPreviewAfterAnimationScale() const
187     {
188         return previewAnimationOptions_.scaleTo;
189     }
190 
SetIsShowHoverImage(bool isShow)191     void SetIsShowHoverImage(bool isShow)
192     {
193         isShowHoverImage_ = isShow;
194     }
195 
GetIsShowHoverImage()196     bool GetIsShowHoverImage() const
197     {
198         return isShowHoverImage_;
199     }
200 
IsNavigationMenu()201     bool IsNavigationMenu() const
202     {
203         return type_ == MenuType::NAVIGATION_MENU;
204     }
205 
IsMultiMenu()206     bool IsMultiMenu() const
207     {
208         return type_ == MenuType::MULTI_MENU;
209     }
210 
IsDesktopMenu()211     bool IsDesktopMenu() const
212     {
213         return type_ == MenuType::DESKTOP_MENU;
214     }
215 
IsMenu()216     bool IsMenu() const
217     {
218         return type_ == MenuType::MENU;
219     }
220 
IsSubMenu()221     bool IsSubMenu() const
222     {
223         return type_ == MenuType::SUB_MENU;
224     }
225 
IsSelectOverlayExtensionMenu()226     bool IsSelectOverlayExtensionMenu() const
227     {
228         return type_ == MenuType::SELECT_OVERLAY_EXTENSION_MENU;
229     }
230 
IsSelectOverlayCustomMenu()231     bool IsSelectOverlayCustomMenu() const
232     {
233         return type_ == MenuType::SELECT_OVERLAY_CUSTOM_MENU;
234     }
235 
IsSelectOverlaySubMenu()236     bool IsSelectOverlaySubMenu() const
237     {
238         return type_ == MenuType::SELECT_OVERLAY_SUB_MENU;
239     }
240 
IsSelectOverlayRightClickMenu()241     bool IsSelectOverlayRightClickMenu() const
242     {
243         return type_ == MenuType::SELECT_OVERLAY_RIGHT_CLICK_MENU;
244     }
245 
SetParentMenuItem(const RefPtr<FrameNode> & parentMenuItem)246     void SetParentMenuItem(const RefPtr<FrameNode>& parentMenuItem)
247     {
248         parentMenuItem_ = parentMenuItem;
249     }
250 
GetParentMenuItem()251     RefPtr<FrameNode> GetParentMenuItem()
252     {
253         return parentMenuItem_;
254     }
255 
GetTargetId()256     int32_t GetTargetId() const
257     {
258         return targetId_;
259     }
260 
GetTargetTag()261     const std::string& GetTargetTag() const
262     {
263         return targetTag_;
264     }
265 
SetIsSelectMenu(bool isSelectMenu)266     void SetIsSelectMenu(bool isSelectMenu)
267     {
268         isSelectMenu_ = isSelectMenu;
269     }
IsSelectMenu()270     bool IsSelectMenu() const
271     {
272         return isSelectMenu_;
273     }
274 
SetHasOptionWidth(bool hasOptionWidth)275     void SetHasOptionWidth(bool hasOptionWidth)
276     {
277         hasOptionWidth_ = hasOptionWidth;
278     }
279 
GetHasOptionWidth()280     bool GetHasOptionWidth()
281     {
282         return hasOptionWidth_;
283     }
284 
AddOptionNode(const RefPtr<FrameNode> & option)285     void AddOptionNode(const RefPtr<FrameNode>& option)
286     {
287         CHECK_NULL_VOID(option);
288         options_.emplace_back(option);
289     }
290 
GetBuilderId()291     int32_t GetBuilderId()
292     {
293         auto node = builderNode_.Upgrade();
294         CHECK_NULL_RETURN(node, -1);
295         return node->GetId();
296     }
297 
PopOptionNode()298     void PopOptionNode()
299     {
300         if (options_.empty()) {
301             LOGW("options is empty.");
302             return;
303         }
304         options_.pop_back();
305     }
306 
GetOptions()307     const std::vector<RefPtr<FrameNode>>& GetOptions() const
308     {
309         return options_;
310     }
311 
GetEmbeddedMenuItems()312     std::vector<RefPtr<FrameNode>>& GetEmbeddedMenuItems()
313     {
314         return embeddedMenuItems_;
315     }
316 
AddEmbeddedMenuItem(const RefPtr<FrameNode> & menuItem)317     void AddEmbeddedMenuItem(const RefPtr<FrameNode>& menuItem)
318     {
319         embeddedMenuItems_.emplace_back(menuItem);
320     }
321 
RemoveEmbeddedMenuItem(const RefPtr<FrameNode> & menuItem)322     void RemoveEmbeddedMenuItem(const RefPtr<FrameNode>& menuItem)
323     {
324         auto iter = std::find(embeddedMenuItems_.begin(), embeddedMenuItems_.end(), menuItem);
325         if (iter != embeddedMenuItems_.end()) {
326             embeddedMenuItems_.erase(iter);
327         }
328     }
329 
330     void RemoveParentHoverStyle();
331 
332     void UpdateSelectParam(const std::vector<SelectParam>& params);
333 
SetNeedHideAfterTouch(bool needHideAfterTouch)334     void SetNeedHideAfterTouch(bool needHideAfterTouch)
335     {
336         needHideAfterTouch_ = needHideAfterTouch;
337     }
338 
HideMenu(const HideMenuType & reason)339     void HideMenu(const HideMenuType& reason)
340     {
341         HideMenu(false, OffsetF(), reason);
342     }
343 
344     void HideMenu(bool isMenuOnTouch = false, OffsetF position = OffsetF(),
345         const HideMenuType& reason = HideMenuType::NORMAL) const;
346 
347     bool HideStackExpandMenu(const OffsetF& position) const;
348 
349     void HideStackMenu() const;
350 
351     void MountOption(const RefPtr<FrameNode>& option);
352 
353     void RemoveOption();
354     RefPtr<FrameNode> DuplicateMenuNode(const RefPtr<FrameNode>& menuNode, const MenuParam& menuParam);
355 
356     RefPtr<FrameNode> GetMenuColumn() const;
357 
SetShowedSubMenu(const RefPtr<FrameNode> & subMenu)358     void SetShowedSubMenu(const RefPtr<FrameNode>& subMenu)
359     {
360         showedSubMenu_ = subMenu;
361     }
GetShowedSubMenu()362     const RefPtr<FrameNode>& GetShowedSubMenu() const
363     {
364         return showedSubMenu_;
365     }
366 
SetIsWidthModifiedBySelect(bool isModified)367     void SetIsWidthModifiedBySelect(bool isModified)
368     {
369         isWidthModifiedBySelect_ = isModified;
370     }
371 
IsWidthModifiedBySelect()372     bool IsWidthModifiedBySelect() const
373     {
374         return isWidthModifiedBySelect_;
375     }
376 
377     float GetSelectMenuWidth();
378     void HideSubMenu();
379     void OnModifyDone() override;
380 
381     // acquire first menu node in wrapper node by submenu node
382     RefPtr<MenuPattern> GetMainMenuPattern() const;
383     uint32_t GetInnerMenuCount() const;
384     void OnColorConfigurationUpdate() override;
385 
386     RefPtr<FrameNode> GetMenuWrapper() const;
387     RefPtr<FrameNode> GetFirstInnerMenu() const;
388     void DumpInfo() override;
389     void DumpInfo(std::unique_ptr<JsonValue>& json) override;
DumpSimplifyInfo(std::shared_ptr<JsonValue> & json)390     void DumpSimplifyInfo(std::shared_ptr<JsonValue>& json) override {}
SetFirstShow()391     void SetFirstShow()
392     {
393         isFirstShow_ = true;
394     }
395 
GetIsFirstShow()396     bool GetIsFirstShow() const
397     {
398         return isFirstShow_;
399     }
400 
SetOriginOffset(const OffsetF & offset)401     void SetOriginOffset(const OffsetF& offset)
402     {
403         originOffset_ = offset;
404     }
405 
SetEndOffset(const OffsetF & offset)406     void SetEndOffset(const OffsetF& offset)
407     {
408         endOffset_ = offset;
409     }
410 
GetEndOffset()411     OffsetF GetEndOffset() const
412     {
413         return endOffset_;
414     }
415 
SetSelectOverlayExtensionMenuShow()416     void SetSelectOverlayExtensionMenuShow()
417     {
418         isExtensionMenuShow_ = true;
419     }
420 
SetDisappearAnimation(bool hasAnimation)421     void SetDisappearAnimation(bool hasAnimation)
422     {
423         // false:exit from BOTTOM to TOP
424         // true:exit from LEFT_BOTTOM to RIGHT_TOP
425         hasAnimation_ = hasAnimation;
426     }
427 
GetDisappearAnimation()428     bool GetDisappearAnimation() const
429     {
430         return hasAnimation_;
431     }
432 
SetSubMenuShow(bool subMenuShowed)433     void SetSubMenuShow(bool subMenuShowed)
434     {
435         isSubMenuShow_ = subMenuShowed;
436     }
437 
SetMenuShow()438     void SetMenuShow()
439     {
440         isMenuShow_ = true;
441     }
442 
SetPreviewOriginOffset(const OffsetF & offset)443     void SetPreviewOriginOffset(const OffsetF& offset)
444     {
445         previewOriginOffset_ = offset;
446     }
447 
GetPreviewOriginOffset()448     OffsetF GetPreviewOriginOffset() const
449     {
450         return previewOriginOffset_;
451     }
452 
SetPreviewRect(RectF rect)453     void SetPreviewRect(RectF rect)
454     {
455         previewRect_ = rect;
456     }
457 
GetPreviewRect()458     RectF GetPreviewRect() const
459     {
460         return previewRect_;
461     }
462 
SetPreviewIdealSize(SizeF size)463     void SetPreviewIdealSize(SizeF size)
464     {
465         previewIdealSize_ = size;
466     }
467 
GetPreviewIdealSize()468     SizeF GetPreviewIdealSize() const
469     {
470         return previewIdealSize_;
471     }
472 
SetHasLaid(bool hasLaid)473     void SetHasLaid(bool hasLaid)
474     {
475         hasLaid_ = hasLaid;
476     }
477 
HasLaid()478     bool HasLaid() const
479     {
480         return hasLaid_;
481     }
482 
SetTargetSize(const SizeF & size)483     void SetTargetSize(const SizeF& size)
484     {
485         targetSize_ = size;
486     }
487 
GetTargetSize()488     SizeF GetTargetSize() const
489     {
490         return targetSize_;
491     }
492 
SetTargetOffset(const OffsetF & offset)493     void SetTargetOffset(const OffsetF& offset)
494     {
495         targetOffset_ = offset;
496     }
497 
GetTargetOffset()498     OffsetF GetTargetOffset() const
499     {
500         return targetOffset_;
501     }
502 
SetIsHeightModifiedBySelect(bool isModified)503     void SetIsHeightModifiedBySelect(bool isModified)
504     {
505         isHeightModifiedBySelect_ = isModified;
506     }
507 
IsHeightModifiedBySelect()508     bool IsHeightModifiedBySelect() const
509     {
510         return isHeightModifiedBySelect_;
511     }
512 
GetMenuExpandDisplay()513     bool GetMenuExpandDisplay() const
514     {
515         return expandDisplay_;
516     }
517 
518     void ShowMenuDisappearAnimation();
519     void ShowStackMenuDisappearAnimation(const RefPtr<FrameNode>& menuNode,
520         const RefPtr<FrameNode>& subMenuNode, AnimationOption& option) const;
521 
SetBuilderFunc(SelectMakeCallback && makeFunc)522     void SetBuilderFunc(SelectMakeCallback&& makeFunc)
523     {
524         makeFunc_ = std::move(makeFunc);
525     }
526 
ResetBuilderFunc()527     void ResetBuilderFunc()
528     {
529         makeFunc_ = std::nullopt;
530     }
531 
532     void UpdateSelectIndex(int32_t index);
533 
SetSelectProperties(const std::vector<SelectParam> & params)534     void SetSelectProperties(const std::vector<SelectParam>& params)
535     {
536         auto list = selectProperties_;
537         selectParams_ = params;
538         selectProperties_.clear();
539         for (size_t i = 0; i < params.size(); i++) {
540             SelectProperties selectProperty;
541             selectProperty.value = params[i].text;
542             selectProperty.icon = params[i].icon;
543             selectProperty.symbolModifier = params[i].symbolModifier;
544             selectProperty.index = static_cast<int>(i);
545             if (i < list.size()) {
546                 selectProperty.selected = list[i].selected;
547                 selectProperty.selectEnable = list[i].selectEnable;
548             }
549             selectProperties_.push_back(selectProperty);
550         }
551     }
552 
GetMenuDefaultShadowStyle()553     ShadowStyle GetMenuDefaultShadowStyle()
554     {
555         auto shadowStyle = ShadowStyle::OuterDefaultMD;
556 
557         auto host = GetHost();
558         CHECK_NULL_RETURN(host, shadowStyle);
559         auto pipeline = host->GetContextRefPtr();
560         CHECK_NULL_RETURN(pipeline, shadowStyle);
561         auto menuTheme = pipeline->GetTheme<MenuTheme>();
562         CHECK_NULL_RETURN(menuTheme, shadowStyle);
563         shadowStyle = menuTheme->GetMenuShadowStyle();
564         return shadowStyle;
565     }
566 
567     bool GetShadowFromTheme(ShadowStyle shadowStyle, Shadow& shadow);
568 
UseContentModifier()569     bool UseContentModifier()
570     {
571         return builderNode_.Upgrade() != nullptr;
572     }
573 
574     void FireBuilder();
575 
576     BorderRadiusProperty CalcIdealBorderRadius(const BorderRadiusProperty& borderRadius, const SizeF& menuSize);
577 
578     void OnItemPressed(const RefPtr<UINode>& parent, int32_t index, bool press, bool hover = false);
579 
GetLastSelectedItem()580     RefPtr<FrameNode> GetLastSelectedItem()
581     {
582         return lastSelectedItem_;
583     }
584 
SetLastSelectedItem(const RefPtr<FrameNode> & lastSelectedItem)585     void SetLastSelectedItem(const RefPtr<FrameNode>& lastSelectedItem)
586     {
587         lastSelectedItem_ = lastSelectedItem;
588     }
UpdateLastPosition(std::optional<OffsetF> lastPosition)589     void UpdateLastPosition(std::optional<OffsetF> lastPosition)
590     {
591         lastPosition_ = lastPosition;
592     }
593 
UpdateLastPlacement(std::optional<Placement> lastPlacement)594     void UpdateLastPlacement(std::optional<Placement> lastPlacement)
595     {
596         lastPlacement_ = lastPlacement;
597     }
598 
GetLastPlacement()599     std::optional<Placement> GetLastPlacement()
600     {
601         return lastPlacement_;
602     }
603 
SetIsEmbedded()604     void SetIsEmbedded()
605     {
606         isEmbedded_ = true;
607     }
IsEmbedded()608     bool IsEmbedded()
609     {
610         return isEmbedded_;
611     }
SetIsStackSubmenu()612     void SetIsStackSubmenu()
613     {
614         isStackSubmenu_ = true;
615     }
IsStackSubmenu()616     bool IsStackSubmenu()
617     {
618         return isStackSubmenu_;
619     }
SetMenuWindowRect(const Rect & menuWindowRect)620     void SetMenuWindowRect(const Rect& menuWindowRect)
621     {
622         menuWindowRect_ = menuWindowRect;
623     }
GetMenuWindowRect()624     Rect GetMenuWindowRect() const
625     {
626         return menuWindowRect_;
627     }
628 
SetMenuLayoutParam(const PreviewMenuParam & layoutParam)629     void SetMenuLayoutParam(const PreviewMenuParam& layoutParam)
630     {
631         layoutParam_ = layoutParam;
632     }
633 
GetMenuLayoutParam()634     PreviewMenuParam GetMenuLayoutParam() const
635     {
636         return layoutParam_;
637     }
638 
GetPreviewMenuDisappearPosition()639     OffsetF GetPreviewMenuDisappearPosition()
640     {
641         return disappearOffset_;
642     }
643 
644     void UpdateMenuPathParams(std::optional<MenuPathParams> pathParams);
645 
GetMenuPathParams()646     std::optional<MenuPathParams> GetMenuPathParams()
647     {
648         return pathParams_;
649     }
650 
SetCustomNode(WeakPtr<UINode> customNode)651     void SetCustomNode(WeakPtr<UINode> customNode)
652     {
653         customNode_ = customNode;
654     }
655 
GetCustomNode()656     RefPtr<UINode> GetCustomNode() const
657     {
658         return customNode_.Upgrade();
659     }
660 
661     void UpdateSelectOptionTextByIndex(int32_t index, const std::string& text);
662     void UpdateSelectOptionIconByIndex(int32_t index, const std::string& icon);
663 
664     void InitPreviewMenuAnimationInfo(const RefPtr<MenuTheme>& menuTheme);
665 
666     float GetSelectMenuWidthFromTheme() const;
667 
668     bool IsSelectOverlayDefaultModeRightClickMenu();
669     void RemoveLastNodeDivider(const RefPtr<UINode>& lastNode);
670     void UpdateMenuItemDivider();
671     void UpdateDividerProperty(const RefPtr<FrameNode>& dividerNode, const std::optional<V2::ItemDivider>& divider);
672     RefPtr<FrameNode> GetFirstMenuItem();
673     RefPtr<FrameNode> GetLastMenuItem();
674     std::pair<float, float> GetPreviewPositionY();
675 
GetTranslateYForStack()676     float GetTranslateYForStack()
677     {
678         return translateYForStack_;
679     }
680 
SetTranslateYForStack(float tmp)681     void SetTranslateYForStack(float tmp)
682     {
683         translateYForStack_ = tmp;
684     }
685 
GetOriginMenuYForStack()686     float GetOriginMenuYForStack()
687     {
688         return originMenuYForStack_;
689     }
690 
SetOriginMenuYForStack(float tmp)691     void SetOriginMenuYForStack(float tmp)
692     {
693         originMenuYForStack_ = tmp;
694     }
695 
GetOriginPreviewYForStack()696     float GetOriginPreviewYForStack()
697     {
698         return originPreviewYForStack_;
699     }
700 
SetOriginPreviewYForStack(float tmp)701     void SetOriginPreviewYForStack(float tmp)
702     {
703         originPreviewYForStack_ = tmp;
704     }
705 
706     void SetDisableMenuBgColorByUser(bool isSetByUser = false)
707     {
708         isDisableMenuBgColorByUser_ = isSetByUser;
709     }
710 
SetSubMenuDepth(int32_t depth)711     void SetSubMenuDepth(int32_t depth)
712     {
713         subMenuDepth_ = depth;
714     }
715 
GetSubMenuDepth()716     int32_t GetSubMenuDepth() const
717     {
718         return subMenuDepth_;
719     }
720 
721 protected:
722     void UpdateMenuItemChildren(const RefPtr<UINode>& host, RefPtr<UINode>& previousNode);
723     void SetMenuAttribute(RefPtr<FrameNode>& host);
724     void SetAccessibilityAction();
SetType(MenuType value)725     void SetType(MenuType value)
726     {
727         type_ = value;
728     }
ResetNeedDivider()729     void ResetNeedDivider()
730     {
731         isNeedDivider_ = false;
732     }
733     virtual void InitTheme(const RefPtr<FrameNode>& host);
734     virtual void UpdateBorderRadius(const RefPtr<FrameNode>& menuNode, const BorderRadiusProperty& borderRadius);
735 
736 private:
737     void UpdateMenuDividerWithMode(const RefPtr<UINode>& previousNode, const RefPtr<UINode>& currentNode,
738         const RefPtr<MenuLayoutProperty>& property, int32_t& index);
739     void AddGroupHeaderDivider(RefPtr<UINode>& previousNode, const RefPtr<UINode>& currentNode,
740         const RefPtr<MenuLayoutProperty>& property, int32_t& index);
741     void AddGroupFooterDivider(RefPtr<UINode>& previousNode, const RefPtr<UINode>& currentNode,
742         const RefPtr<MenuLayoutProperty>& property, int32_t& index);
743     void OnAttachToFrameNode() override;
744     int32_t RegisterHalfFoldHover(const RefPtr<FrameNode>& menuNode);
745     void OnDetachFromFrameNode(FrameNode* frameNode) override;
746     void OnDetachFromMainTree() override;
747 
748     void RegisterOnTouch();
749     void OnTouchEvent(const TouchEventInfo& info);
750     bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override;
751 
752     // If CustomBuilder is declared with <Menu> and <MenuItem>,
753     // reset outer menu container and only apply theme on the inner <Menu> node.
754     void ResetTheme(const RefPtr<FrameNode>& host, bool resetForDesktopMenu);
755     void ResetScrollTheme(const RefPtr<FrameNode>& host);
756     void ResetThemeByInnerMenuCount();
757     void CopyMenuAttr(const RefPtr<FrameNode>& menuNode) const;
758 
759     void RegisterOnKeyEvent(const RefPtr<FocusHub>& focusHub);
760     bool OnKeyEvent(const KeyEvent& event);
761 
762     void DisableTabInMenu();
763 
764     Offset GetTransformCenter() const;
765     OffsetF GetPreviewMenuAnimationOffset(const OffsetF& previewCenter, const SizeF& previewSize, float scale) const;
766     void ShowPreviewMenuAnimation();
767     void ShowPreviewPositionAnimation(AnimationOption& option, int32_t delay);
768     void ShowPreviewMenuScaleAnimation(const RefPtr<MenuTheme>& menuTheme, AnimationOption& option, int32_t delay);
769     void ShowMenuAppearAnimation();
770     void ShowStackMenuAppearAnimation();
771     std::pair<OffsetF, OffsetF> GetMenuOffset(const RefPtr<FrameNode>& mainMenu,
772         const RefPtr<FrameNode>& subMenu, bool isNeedRestoreNodeId = false) const;
773     MenuItemInfo GetInnerMenuOffset(const RefPtr<UINode>& child, const RefPtr<FrameNode>& subMenu,
774         bool isNeedRestoreNodeId) const;
775     MenuItemInfo GetMenuItemInfo(const RefPtr<UINode>& child, const RefPtr<FrameNode>& subMenu,
776         bool isNeedRestoreNodeId) const;
777     std::vector<RefPtr<RenderContext>> GetOtherMenuItemContext(const RefPtr<FrameNode>& subMenuNode) const;
778     void ShowArrowRotateAnimation() const;
779     void ShowArrowReverseRotateAnimation() const;
780     RefPtr<FrameNode> GetArrowNode(const RefPtr<FrameNode>& host) const; // arrowNode in subMenu
781 
782     void InitPanEvent(const RefPtr<GestureEventHub>& gestureHub);
783     void HandleDragEnd(float offsetX, float offsetY, float velocity);
784     void HandleScrollDragEnd(float offsetX, float offsetY, float velocity);
785     RefPtr<UINode> GetSyntaxNode(const RefPtr<UINode>& parent);
786     RefPtr<UINode> GetForEachMenuItem(const RefPtr<UINode>& parent, bool next);
787     RefPtr<UINode> GetOutsideForEachMenuItem(const RefPtr<UINode>& forEachNode, bool next);
788     RefPtr<UINode> GetIfElseMenuItem(const RefPtr<UINode>& parent, bool next);
789     void HandleNextPressed(const RefPtr<UINode>& parent, int32_t index, bool press, bool hover);
790     void HandlePrevPressed(const RefPtr<UINode>& parent, int32_t index, bool press);
791     void SetMenuBackGroundStyle(const RefPtr<FrameNode>& menuNode, const MenuParam& menuParam);
792     void UpdateMenuBorderAndBackgroundBlur();
793 
794     RefPtr<FrameNode> BuildContentModifierNode(int index);
795     bool IsMenuScrollable() const;
796     void UpdateClipPath(const RefPtr<LayoutWrapper>& dirty);
797     RefPtr<FrameNode> GetTitleContentNode(const RefPtr<FrameNode>& subMenuNode) const;
798     void ShowStackSubMenuAnimation(const RefPtr<FrameNode>& mainMenu, const RefPtr<FrameNode>& subMenuNode);
799     void ShowStackMainMenuAnimation(const RefPtr<FrameNode>& mainMenu, const RefPtr<FrameNode>& subMenuNode,
800         const RefPtr<FrameNode>& menuWrapper);
801     void ShowStackMainMenuOpacityAnimation(const RefPtr<FrameNode>& mainMenu);
802     void ShowStackSubMenuDisappearAnimation(const RefPtr<FrameNode>& menuNode,
803         const RefPtr<FrameNode>& subMenuNode) const;
804     void ShowStackMainMenuDisappearOpacityAnimation(const RefPtr<FrameNode>& menuNode,
805         AnimationOption& option) const;
806     void ShowStackMainMenuDisappearAnimation(const RefPtr<FrameNode>& menuNode,
807         const RefPtr<FrameNode>& subMenuNode, AnimationOption& option) const;
808 
809     RefPtr<ClickEvent> onClick_;
810     RefPtr<TouchEventImpl> onTouch_;
811     std::optional<Offset> lastTouchOffset_;
812     const int32_t targetId_ = -1;
813     const std::string targetTag_;
814     MenuType type_ = MenuType::MENU;
815     std::vector<SelectProperties> selectProperties_;
816     std::vector<SelectParam> selectParams_;
817     std::optional<SelectMakeCallback> makeFunc_;
818 
819     RefPtr<FrameNode> parentMenuItem_;
820     RefPtr<FrameNode> showedSubMenu_;
821     std::vector<RefPtr<FrameNode>> options_;
822     std::optional<int32_t> foldStatusChangedCallbackId_;
823     std::optional<int32_t> halfFoldHoverCallbackId_;
824 
825     bool isSelectMenu_ = false;
826     MenuPreviewMode previewMode_ = MenuPreviewMode::NONE;
827     MenuPreviewAnimationOptions previewAnimationOptions_;
828     bool isShowHoverImage_ = false;
829     bool isFirstShow_ = false;
830     bool isExtensionMenuShow_ = false;
831     bool isSubMenuShow_ = false;
832     bool isMenuShow_ = false;
833     bool hasAnimation_ = true;
834     bool needHideAfterTouch_ = true;
835 
836     std::optional<OffsetF> lastPosition_;
837     std::optional<Placement> lastPlacement_;
838     OffsetF originOffset_;
839     OffsetF endOffset_;
840     OffsetF disappearOffset_;
841     OffsetF previewOriginOffset_;
842     RectF previewRect_;
843     SizeF previewIdealSize_;
844     OffsetF statusOriginOffset_;
845 
846     WeakPtr<FrameNode> builderNode_;
847     bool isWidthModifiedBySelect_ = false;
848     bool isHeightModifiedBySelect_ = false;
849     bool hasLaid_ = false;
850     bool hasOptionWidth_ = false;
851     OffsetF targetOffset_;
852     SizeF targetSize_;
853     bool expandDisplay_ = false;
854     RefPtr<FrameNode> lastSelectedItem_ = nullptr;
855     bool isEmbedded_ = false;
856     std::vector<RefPtr<FrameNode>> embeddedMenuItems_;
857     bool isStackSubmenu_ = false;
858     bool isNeedDivider_ = false;
859     Rect menuWindowRect_;
860     PreviewMenuParam layoutParam_;
861     WeakPtr<UINode> customNode_ = nullptr;
862     std::optional<MenuPathParams> pathParams_ = std::nullopt;
863     float translateYForStack_ = 0.0f;
864     float originMenuYForStack_ = 0.0f;
865     float originPreviewYForStack_ = 0.0f;
866     bool isDisableMenuBgColorByUser_ = false;
867 
868     // only used for Side sub menu
869     int32_t subMenuDepth_ = 0;
870 
871     ACE_DISALLOW_COPY_AND_MOVE(MenuPattern);
872 };
873 
874 // pattern of inner menu, corersponds to <Menu> tag in the frontend
875 class InnerMenuPattern : public MenuPattern {
876     DECLARE_ACE_TYPE(InnerMenuPattern, MenuPattern);
877 
878 public:
InnerMenuPattern(int32_t targetId,std::string tag,MenuType type)879     InnerMenuPattern(int32_t targetId, std::string tag, MenuType type) : MenuPattern(targetId, std::move(tag), type) {}
880     ~InnerMenuPattern() override = default;
881     void OnModifyDone() override;
882     void BeforeCreateLayoutWrapper() override;
883     bool isHalfFoldStatus_ = false;
884 
885     void RecordItemsAndGroups();
886 
GetItemsAndGroups()887     const std::list<WeakPtr<UINode>>& GetItemsAndGroups() const
888     {
889         return itemsAndGroups_;
890     }
891 
892 private:
893     void InitTheme(const RefPtr<FrameNode>& host) override;
894     void UpdateBorderRadius(const RefPtr<FrameNode>& menuNode, const BorderRadiusProperty& borderRadius) override;
895     uint32_t FindSiblingMenuCount();
896     void ApplyDesktopMenuTheme();
897     void ApplyMultiMenuTheme();
898 
899     void InitDefaultBorder(const RefPtr<FrameNode>& host);
900 
901     // Record menu's items and groups at first level,
902     // use for group header and footer padding
903     std::list<WeakPtr<UINode>> itemsAndGroups_;
904 
905     ACE_DISALLOW_COPY_AND_MOVE(InnerMenuPattern);
906 };
907 } // namespace OHOS::Ace::NG
908 
909 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_MENU_MENU_PATTERN_H
910