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 "core/components/slider/render_slider.h" 22 #include "core/components_ng/base/view_abstract.h" 23 #include "core/components_ng/event/long_press_event.h" 24 #include "core/components_ng/pattern/menu/menu_item/menu_item_accessibility_property.h" 25 #include "core/components_ng/pattern/menu/menu_item/menu_item_event_hub.h" 26 #include "core/components_ng/pattern/menu/menu_item/menu_item_layout_algorithm.h" 27 #include "core/components_ng/pattern/menu/menu_item/menu_item_layout_property.h" 28 #include "core/components_ng/pattern/menu/menu_item/menu_item_paint_method.h" 29 #include "core/components_ng/pattern/menu/menu_item/menu_item_paint_property.h" 30 #include "core/components_ng/pattern/menu/menu_pattern.h" 31 #include "core/components_ng/pattern/pattern.h" 32 33 namespace OHOS::Ace::NG { 34 class ACE_EXPORT MenuItemPattern : public Pattern { 35 DECLARE_ACE_TYPE(MenuItemPattern, Pattern); 36 37 public: 38 MenuItemPattern() = default; 39 ~MenuItemPattern() override = default; 40 IsAtomicNode()41 bool IsAtomicNode() const override 42 { 43 return false; 44 } 45 GetFocusPattern()46 FocusPattern GetFocusPattern() const override 47 { 48 return { FocusType::NODE, true, FocusStyleType::INNER_BORDER }; 49 } 50 CreateEventHub()51 RefPtr<EventHub> CreateEventHub() override 52 { 53 return MakeRefPtr<MenuItemEventHub>(); 54 } 55 CreateLayoutProperty()56 RefPtr<LayoutProperty> CreateLayoutProperty() override 57 { 58 return MakeRefPtr<MenuItemLayoutProperty>(); 59 } 60 CreateAccessibilityProperty()61 RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override 62 { 63 return MakeRefPtr<MenuItemAccessibilityProperty>(); 64 } 65 CreateLayoutAlgorithm()66 RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override 67 { 68 return MakeRefPtr<MenuItemLayoutAlgorithm>(); 69 } 70 CreateNodePaintMethod()71 RefPtr<NodePaintMethod> CreateNodePaintMethod() override 72 { 73 return MakeRefPtr<MenuItemPaintMethod>(); 74 } 75 CreatePaintProperty()76 RefPtr<PaintProperty> CreatePaintProperty() override 77 { 78 return MakeRefPtr<MenuItemPaintProperty>(); 79 } 80 81 void MarkIsSelected(bool isSelected); SetSelected(bool isSelected)82 void SetSelected(bool isSelected) 83 { 84 isSelected_ = isSelected; 85 GetHost()->MarkModifyDone(); 86 } 87 IsSelected()88 bool IsSelected() const 89 { 90 return isSelected_; 91 } 92 SetSubBuilder(const std::function<void ()> & subBuilderFunc)93 void SetSubBuilder(const std::function<void()>& subBuilderFunc) 94 { 95 subBuilderFunc_ = subBuilderFunc; 96 } 97 GetSubBuilder()98 std::function<void()>& GetSubBuilder() 99 { 100 return subBuilderFunc_; 101 } 102 IsSubMenuShowed()103 bool IsSubMenuShowed() const 104 { 105 return isSubMenuShowed_; 106 } 107 SetIsSubMenuShowed(bool isSubMenuShowed)108 void SetIsSubMenuShowed(bool isSubMenuShowed) 109 { 110 isSubMenuShowed_ = isSubMenuShowed; 111 } 112 IsSubMenuHovered()113 bool IsSubMenuHovered() const 114 { 115 return isSubMenuHovered_; 116 } 117 SetIsSubMenuHovered(bool isSubMenuHovered)118 void SetIsSubMenuHovered(bool isSubMenuHovered) 119 { 120 isSubMenuHovered_ = isSubMenuHovered; 121 } 122 123 void AddHoverRegions(const OffsetF& topLeftPoint, const OffsetF& bottomRightPoint); 124 125 bool IsInHoverRegions(double x, double y); 126 ClearHoverRegions()127 void ClearHoverRegions() 128 { 129 hoverRegions_.clear(); 130 } 131 ResetWrapperMouseEvent()132 void ResetWrapperMouseEvent() 133 { 134 wrapperMouseEvent_.Reset(); 135 } 136 SetChange()137 void SetChange() 138 { 139 isSelected_ = !isSelected_; 140 } 141 IsChange()142 bool IsChange() const 143 { 144 return isChanged_; 145 } 146 147 void CloseMenu(); 148 GetContentNode()149 RefPtr<FrameNode> GetContentNode() 150 { 151 return content_; 152 } 153 GetLabelNode()154 RefPtr<FrameNode> GetLabelNode() 155 { 156 return label_; 157 } 158 159 void PlayBgColorAnimation(bool isHoverChange = true); SetBgBlendColor(const Color & color)160 void SetBgBlendColor(const Color& color) 161 { 162 bgBlendColor_ = color; 163 } GetBgBlendColor()164 Color GetBgBlendColor() const 165 { 166 return bgBlendColor_; 167 } 168 bool IsDisabled(); 169 170 RefPtr<FrameNode> GetMenu(bool needTopMenu = false); 171 RefPtr<MenuPattern> GetMenuPattern(bool needTopMenu = false); 172 void UpdateTextNodes(); 173 174 void OnAttachToFrameNode() override; 175 void OnModifyDone() override; 176 void OnMountToParentDone() override; 177 HasSelectIcon()178 bool HasSelectIcon() const 179 { 180 return selectIcon_ != nullptr; 181 } HasStartIcon()182 bool HasStartIcon() const 183 { 184 return startIcon_ != nullptr; 185 } 186 SetClickMenuItemId(int32_t id)187 void SetClickMenuItemId(int32_t id) 188 { 189 clickMenuItemId_ = id; 190 } 191 GetClickMenuItemId()192 int32_t GetClickMenuItemId() const 193 { 194 return clickMenuItemId_; 195 } 196 SetOnClickAIMenuItem(std::function<void ()> onClickAIMenuItem)197 void SetOnClickAIMenuItem(std::function<void()> onClickAIMenuItem) 198 { 199 onClickAIMenuItem_ = onClickAIMenuItem; 200 } 201 202 void OnVisibleChange(bool isVisible) override; 203 void InitLongPressEvent(); 204 void UpdateNeedDivider(bool need); SetIndex(int32_t index)205 void SetIndex(int32_t index) 206 { 207 index_ = index; 208 } 209 float GetDividerStroke(); 210 GetExpandingMode()211 SubMenuExpandingMode GetExpandingMode() 212 { 213 return expandingMode_; 214 } 215 bool IsSubMenu(); 216 bool IsEmbedded(); SetIsStackSubmenuHeader()217 void SetIsStackSubmenuHeader() 218 { 219 isStackSubmenuHeader_ = true; 220 } IsStackSubmenuHeader()221 bool IsStackSubmenuHeader() 222 { 223 return isStackSubmenuHeader_; 224 } 225 RefPtr<FrameNode> FindTouchedEmbeddedMenuItem(const OffsetF& position); 226 void OnHover(bool isHover); 227 void NotifyPressStatus(bool isPress); 228 229 protected: 230 void RegisterOnKeyEvent(); 231 void RegisterOnTouch(); 232 void OnAfterModifyDone() override; 233 RefPtr<FrameNode> GetMenuWrapper(); 234 235 private: 236 friend class ServiceCollaborationMenuAceHelper; 237 // register menu item's callback 238 void RegisterOnClick(); 239 void RegisterOnHover(); 240 virtual void OnTouch(const TouchEventInfo& info); 241 virtual bool OnKeyEvent(const KeyEvent& event); IsCustomMenuItem()242 virtual bool IsCustomMenuItem() 243 { 244 return false; 245 } 246 void OnClick(); 247 248 void RegisterWrapperMouseEvent(); 249 250 void AddSelectIcon(RefPtr<FrameNode>& row); 251 void UpdateIcon(RefPtr<FrameNode>& row, bool isStart); 252 void AddExpandIcon(RefPtr<FrameNode>& row); 253 void AddClickableArea(); 254 void UpdateText(RefPtr<FrameNode>& row, RefPtr<MenuLayoutProperty>& menuProperty, bool isLabel); 255 void UpdateTextOverflow(RefPtr<TextLayoutProperty>& textProperty, RefPtr<SelectTheme>& theme); 256 void UpdateFont(RefPtr<MenuLayoutProperty>& menuProperty, RefPtr<SelectTheme>& theme, bool isLabel); 257 void UpdateMaxLinesFromTheme(RefPtr<TextLayoutProperty>& textProperty); 258 void AddStackSubMenuHeader(RefPtr<FrameNode>& menuNode); 259 RefPtr<FrameNode> GetClickableArea(); 260 void UpdateDisabledStyle(); 261 262 void ShowSubMenu(); 263 void UpdateSubmenuExpandingMode(RefPtr<UINode>& customNode); 264 void ShowSubMenuHelper(const RefPtr<FrameNode>& subMenu); 265 void HideSubMenu(); 266 void OnExpandChanged(const RefPtr<FrameNode>& expandableNode); 267 void HideEmbeddedExpandMenu(const RefPtr<FrameNode>& expandableNode); 268 void ShowEmbeddedExpandMenu(const RefPtr<FrameNode>& expandableNode); 269 270 OffsetF GetSubMenuPosition(const RefPtr<FrameNode>& targetNode); 271 272 void AddSelfHoverRegion(const RefPtr<FrameNode>& targetNode); 273 void SetAccessibilityAction(); 274 bool IsSelectOverlayMenu(); 275 void RecordChangeEvent() const; 276 void ParseMenuRadius(MenuParam& param); 277 void ModifyDivider(); 278 279 void InitFocusEvent(); 280 void HandleFocusEvent(); 281 void HandleBlurEvent(); 282 283 void UpdateSymbolNode(RefPtr<FrameNode>& row, RefPtr<FrameNode>& selectIcon); 284 void UpdateImageNode(RefPtr<FrameNode>& row, RefPtr<FrameNode>& selectIcon); 285 void UpdateSymbolIcon(RefPtr<FrameNode>& row, RefPtr<FrameNode>& iconNode, ImageSourceInfo& iconSrc, 286 std::function<void(WeakPtr<NG::FrameNode>)>& symbol, bool isStart); 287 void UpdateImageIcon(RefPtr<FrameNode>& row, RefPtr<FrameNode>& iconNode, ImageSourceInfo& iconSrc, 288 std::function<void(WeakPtr<NG::FrameNode>)>& symbol, bool isStart); 289 bool UseDefaultThemeIcon(const ImageSourceInfo& imageSourceInfo); 290 291 std::list<TouchRegion> hoverRegions_; 292 293 RefPtr<InputEvent> wrapperMouseEvent_; 294 295 bool isSelected_ = false; 296 bool isSubMenuShowed_ = false; 297 bool isSubMenuHovered_ = false; 298 299 bool isChanged_ = false; 300 bool isHovered_ = false; 301 bool isExpanded_ = false; 302 int32_t clickMenuItemId_ = -1; 303 std::function<void()> onClickAIMenuItem_ = nullptr; 304 int32_t index_ = 0; 305 306 std::function<void()> subBuilderFunc_ = nullptr; 307 308 int32_t subMenuId_ = -1; 309 RefPtr<FrameNode> subMenu_; 310 RefPtr<FrameNode> content_ = nullptr; 311 RefPtr<FrameNode> label_ = nullptr; 312 RefPtr<FrameNode> startIcon_ = nullptr; 313 RefPtr<FrameNode> endIcon_ = nullptr; 314 RefPtr<FrameNode> selectIcon_ = nullptr; 315 316 RefPtr<FrameNode> embeddedMenu_ = nullptr; 317 RefPtr<FrameNode> clickableArea_ = nullptr; 318 RefPtr<LongPressEvent> longPressEvent_; 319 RefPtr<TouchEventImpl> onTouchEvent_; 320 RefPtr<InputEvent> onHoverEvent_; 321 RefPtr<ClickEvent> onClickEvent_; 322 RefPtr<FrameNode> expandIcon_ = nullptr; 323 std::vector<RefPtr<FrameNode>> expandableItems_; 324 bool onTouchEventSet_ = false; 325 bool onHoverEventSet_ = false; 326 bool onKeyEventSet_ = false; 327 bool onClickEventSet_ = false; 328 SubMenuExpandingMode expandingMode_ = SubMenuExpandingMode::SIDE; 329 bool isStackSubmenuHeader_ = false; 330 bool expandingModeSet_ = false; 331 332 Color bgBlendColor_ = Color::TRANSPARENT; 333 334 ACE_DISALLOW_COPY_AND_MOVE(MenuItemPattern); 335 }; 336 337 class CustomMenuItemPattern : public MenuItemPattern { 338 DECLARE_ACE_TYPE(CustomMenuItemPattern, MenuItemPattern); 339 340 public: CreateLayoutAlgorithm()341 RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override 342 { 343 return MakeRefPtr<BoxLayoutAlgorithm>(); 344 } 345 void OnAttachToFrameNode() override; 346 347 private: 348 void OnTouch(const TouchEventInfo& info) override; 349 void HandleOnChange(); 350 bool OnKeyEvent(const KeyEvent& event) override; IsCustomMenuItem()351 bool IsCustomMenuItem() override 352 { 353 return true; 354 } 355 std::unique_ptr<Offset> lastTouchOffset_; 356 }; 357 } // namespace OHOS::Ace::NG 358 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_MENU_MENU_ITEM_PATTERN_H 359