1 /* 2 * Copyright (c) 2022 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 21 #include "base/geometry/ng/offset_t.h" 22 #include "base/memory/referenced.h" 23 #include "base/utils/string_utils.h" 24 #include "base/utils/utils.h" 25 #include "core/components/common/properties/color.h" 26 #include "core/components_ng/pattern/menu/menu_layout_algorithm.h" 27 #include "core/components_ng/pattern/menu/menu_layout_property.h" 28 #include "core/components_ng/pattern/menu/menu_paint_method.h" 29 #include "core/components_ng/pattern/menu/navigation_menu_layout_algorithm.h" 30 #include "core/components_ng/pattern/option/option_pattern.h" 31 #include "core/components_ng/pattern/pattern.h" 32 #include "core/components_v2/inspector/inspector_constants.h" 33 #include "core/pipeline_ng/ui_task_scheduler.h" 34 35 namespace OHOS::Ace::NG { 36 enum class MenuType { MENU, CONTEXT_MENU, NAVIGATION_MENU, MULTI_MENU, SUB_MENU }; 37 38 class MenuPattern : public Pattern { 39 DECLARE_ACE_TYPE(MenuPattern, Pattern); 40 41 public: MenuPattern(int32_t targetId,MenuType type)42 explicit MenuPattern(int32_t targetId, MenuType type) : targetId_(targetId), type_(type) {} 43 ~MenuPattern() override = default; 44 IsAtomicNode()45 bool IsAtomicNode() const override 46 { 47 return false; 48 } 49 GetFocusPattern()50 FocusPattern GetFocusPattern() const override 51 { 52 return { FocusType::SCOPE, true }; 53 } 54 CreateNodePaintMethod()55 RefPtr<NodePaintMethod> CreateNodePaintMethod() override 56 { 57 return MakeRefPtr<MenuPaintMethod>(); 58 } 59 CreateLayoutProperty()60 RefPtr<LayoutProperty> CreateLayoutProperty() override 61 { 62 return MakeRefPtr<MenuLayoutProperty>(); 63 } 64 CreateLayoutAlgorithm()65 RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override 66 { 67 RefPtr<MenuLayoutAlgorithm> navigationMenu = MakeRefPtr<NavigationMenuLayoutAlgorithm>(); 68 return (type_ == MenuType::NAVIGATION_MENU) ? navigationMenu : MakeRefPtr<MenuLayoutAlgorithm>(); 69 } 70 IsContextMenu()71 bool IsContextMenu() const 72 { 73 return type_ == MenuType::CONTEXT_MENU; 74 } 75 IsNavigationMenu()76 bool IsNavigationMenu() const 77 { 78 return type_ == MenuType::NAVIGATION_MENU; 79 } 80 IsMultiMenu()81 bool IsMultiMenu() const 82 { 83 return type_ == MenuType::MULTI_MENU; 84 } 85 IsSubMenu()86 bool IsSubMenu() const 87 { 88 return type_ == MenuType::SUB_MENU; 89 } 90 SetFontSize(const Dimension & value)91 void SetFontSize(const Dimension& value) 92 { 93 fontSize_ = value; 94 } 95 FontSize()96 Dimension FontSize() const 97 { 98 auto context = PipelineBase::GetCurrentContext(); 99 CHECK_NULL_RETURN(context, Dimension()); 100 auto theme = context->GetTheme<SelectTheme>(); 101 CHECK_NULL_RETURN(theme, Dimension()); 102 return fontSize_.value_or(theme->GetMenuFontSize()); 103 } 104 SetParentMenuItem(const RefPtr<FrameNode> & parentMenuItem)105 void SetParentMenuItem(const RefPtr<FrameNode>& parentMenuItem) 106 { 107 parentMenuItem_ = parentMenuItem; 108 } 109 GetParentMenuItem()110 RefPtr<FrameNode> GetParentMenuItem() 111 { 112 return parentMenuItem_; 113 } 114 GetTargetId()115 int32_t GetTargetId() const 116 { 117 return targetId_; 118 } 119 SetIsSelectMenu(bool isSelectMenu)120 void SetIsSelectMenu(bool isSelectMenu) 121 { 122 isSelectMenu_ = isSelectMenu; 123 } IsSelectMenu()124 bool IsSelectMenu() const 125 { 126 return isSelectMenu_; 127 } 128 AddOptionNode(const RefPtr<FrameNode> & option)129 void AddOptionNode(const RefPtr<FrameNode>& option) 130 { 131 CHECK_NULL_VOID(option); 132 options_.emplace_back(option); 133 } 134 PopOptionNode()135 void PopOptionNode() 136 { 137 if (options_.empty()) { 138 LOGW("options is empty."); 139 return; 140 } 141 options_.pop_back(); 142 } 143 GetOptions()144 const std::vector<RefPtr<FrameNode>>& GetOptions() const 145 { 146 return options_; 147 } 148 149 void RemoveParentHoverStyle(); 150 151 void HideMenu() const; 152 153 void MountOption(const RefPtr<FrameNode>& option); 154 155 void RemoveOption(); 156 157 RefPtr<FrameNode> GetMenuColumn() const; 158 159 private: 160 void OnModifyDone() override; 161 void RegisterOnTouch(); 162 void OnTouchEvent(const TouchEventInfo& info); 163 bool IsMultiMenuOutside() const; 164 165 void RegisterOnKeyEvent(const RefPtr<FocusHub>& focusHub); 166 bool OnKeyEvent(const KeyEvent& event) const; 167 168 void DisableTabInMenu(); 169 170 RefPtr<FrameNode> GetMenuWrapper() const; 171 172 RefPtr<ClickEvent> onClick_; 173 RefPtr<TouchEventImpl> onTouch_; 174 std::optional<Offset> lastTouchOffset_; 175 int32_t targetId_ = -1; 176 MenuType type_ = MenuType::MENU; 177 178 RefPtr<FrameNode> parentMenuItem_; 179 std::vector<RefPtr<FrameNode>> options_; 180 181 std::optional<Dimension> fontSize_; 182 183 bool isSelectMenu_ = false; 184 185 ACE_DISALLOW_COPY_AND_MOVE(MenuPattern); 186 }; 187 } // namespace OHOS::Ace::NG 188 189 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_MENU_MENU_PATTERN_H 190