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 SetBlockClick(bool blockClick)159 void SetBlockClick(bool blockClick) 160 { 161 blockClick_ = blockClick; 162 } 163 164 void PlayBgColorAnimation(bool isHoverChange = true); SetBgBlendColor(const Color & color)165 void SetBgBlendColor(const Color& color) 166 { 167 bgBlendColor_ = color; 168 } GetBgBlendColor()169 Color GetBgBlendColor() const 170 { 171 return bgBlendColor_; 172 } 173 bool IsDisabled(); 174 175 RefPtr<FrameNode> GetMenu(bool needTopMenu = false); 176 RefPtr<MenuPattern> GetMenuPattern(bool needTopMenu = false); 177 void UpdateTextNodes(); 178 179 void OnAttachToFrameNode() override; 180 void OnModifyDone() override; 181 void OnMountToParentDone() override; 182 HasSelectIcon()183 bool HasSelectIcon() const 184 { 185 return selectIcon_ != nullptr; 186 } HasStartIcon()187 bool HasStartIcon() const 188 { 189 return startIcon_ != nullptr; 190 } 191 SetClickMenuItemId(int32_t id)192 void SetClickMenuItemId(int32_t id) 193 { 194 clickMenuItemId_ = id; 195 } 196 GetClickMenuItemId()197 int32_t GetClickMenuItemId() const 198 { 199 return clickMenuItemId_; 200 } 201 SetOnClickAIMenuItem(std::function<void ()> onClickAIMenuItem)202 void SetOnClickAIMenuItem(std::function<void()> onClickAIMenuItem) 203 { 204 onClickAIMenuItem_ = onClickAIMenuItem; 205 } 206 207 void OnVisibleChange(bool isVisible) override; 208 void InitLongPressEvent(); 209 void UpdateNeedDivider(bool need); SetIndex(int32_t index)210 void SetIndex(int32_t index) 211 { 212 index_ = index; 213 } 214 float GetDividerStroke(); 215 GetExpandingMode()216 SubMenuExpandingMode GetExpandingMode() 217 { 218 return expandingMode_; 219 } 220 bool IsSubMenu(); 221 bool IsEmbedded(); SetIsStackSubmenuHeader()222 void SetIsStackSubmenuHeader() 223 { 224 isStackSubmenuHeader_ = true; 225 } IsStackSubmenuHeader()226 bool IsStackSubmenuHeader() 227 { 228 return isStackSubmenuHeader_; 229 } 230 RefPtr<FrameNode> FindTouchedEmbeddedMenuItem(const PointF& position); 231 void OnHover(bool isHover); 232 void NotifyPressStatus(bool isPress); 233 234 protected: 235 void RegisterOnKeyEvent(); 236 void RegisterOnTouch(); 237 void OnAfterModifyDone() override; 238 RefPtr<FrameNode> GetMenuWrapper(); 239 240 private: 241 friend class ServiceCollaborationMenuAceHelper; 242 // register menu item's callback 243 void RegisterOnClick(); 244 void RegisterOnHover(); 245 virtual void OnTouch(const TouchEventInfo& info); 246 virtual bool OnKeyEvent(const KeyEvent& event); IsCustomMenuItem()247 virtual bool IsCustomMenuItem() 248 { 249 return false; 250 } 251 void OnClick(); 252 253 void RegisterWrapperMouseEvent(); 254 255 void AddSelectIcon(RefPtr<FrameNode>& row); 256 void UpdateIcon(RefPtr<FrameNode>& row, bool isStart); 257 void AddExpandIcon(RefPtr<FrameNode>& row); 258 void AddClickableArea(); 259 void UpdateText(RefPtr<FrameNode>& row, RefPtr<MenuLayoutProperty>& menuProperty, bool isLabel); 260 void UpdateTextOverflow(RefPtr<TextLayoutProperty>& textProperty, RefPtr<SelectTheme>& theme); 261 void UpdateFont(RefPtr<MenuLayoutProperty>& menuProperty, RefPtr<SelectTheme>& theme, bool isLabel); 262 void UpdateMaxLinesFromTheme(RefPtr<TextLayoutProperty>& textProperty); 263 void AddStackSubMenuHeader(RefPtr<FrameNode>& menuNode); 264 RefPtr<FrameNode> GetClickableArea(); 265 void UpdateDisabledStyle(); 266 267 void ShowSubMenu(); 268 void UpdateSubmenuExpandingMode(RefPtr<UINode>& customNode); 269 void ShowSubMenuHelper(const RefPtr<FrameNode>& subMenu); 270 void HideSubMenu(); 271 void OnExpandChanged(const RefPtr<FrameNode>& expandableNode); 272 void HideEmbeddedExpandMenu(const RefPtr<FrameNode>& expandableNode); 273 void ShowEmbeddedExpandMenu(const RefPtr<FrameNode>& expandableNode); 274 275 OffsetF GetSubMenuPosition(const RefPtr<FrameNode>& targetNode); 276 277 void AddSelfHoverRegion(const RefPtr<FrameNode>& targetNode); 278 void SetAccessibilityAction(); 279 bool IsSelectOverlayMenu(); 280 void RecordChangeEvent() const; 281 void ParseMenuRadius(MenuParam& param); 282 void ModifyDivider(); 283 284 void InitFocusEvent(); 285 void HandleFocusEvent(); 286 void HandleBlurEvent(); 287 288 void UpdateSymbolNode(RefPtr<FrameNode>& row, RefPtr<FrameNode>& selectIcon); 289 void UpdateImageNode(RefPtr<FrameNode>& row, RefPtr<FrameNode>& selectIcon); 290 void UpdateSymbolIcon(RefPtr<FrameNode>& row, RefPtr<FrameNode>& iconNode, ImageSourceInfo& iconSrc, 291 std::function<void(WeakPtr<NG::FrameNode>)>& symbol, bool isStart); 292 void UpdateImageIcon(RefPtr<FrameNode>& row, RefPtr<FrameNode>& iconNode, ImageSourceInfo& iconSrc, 293 std::function<void(WeakPtr<NG::FrameNode>)>& symbol, bool isStart); 294 bool UseDefaultThemeIcon(const ImageSourceInfo& imageSourceInfo); 295 296 std::list<TouchRegion> hoverRegions_; 297 298 RefPtr<InputEvent> wrapperMouseEvent_; 299 300 bool isSelected_ = false; 301 bool isSubMenuShowed_ = false; 302 bool isSubMenuHovered_ = false; 303 304 bool isChanged_ = false; 305 bool isHovered_ = false; 306 bool isExpanded_ = false; 307 int32_t clickMenuItemId_ = -1; 308 std::function<void()> onClickAIMenuItem_ = nullptr; 309 int32_t index_ = 0; 310 311 std::function<void()> subBuilderFunc_ = nullptr; 312 313 int32_t subMenuId_ = -1; 314 RefPtr<FrameNode> subMenu_; 315 RefPtr<FrameNode> content_ = nullptr; 316 RefPtr<FrameNode> label_ = nullptr; 317 RefPtr<FrameNode> startIcon_ = nullptr; 318 RefPtr<FrameNode> endIcon_ = nullptr; 319 RefPtr<FrameNode> selectIcon_ = nullptr; 320 321 RefPtr<FrameNode> embeddedMenu_ = nullptr; 322 RefPtr<FrameNode> clickableArea_ = nullptr; 323 RefPtr<LongPressEvent> longPressEvent_; 324 RefPtr<TouchEventImpl> onTouchEvent_; 325 RefPtr<InputEvent> onHoverEvent_; 326 RefPtr<ClickEvent> onClickEvent_; 327 RefPtr<FrameNode> expandIcon_ = nullptr; 328 std::vector<RefPtr<FrameNode>> expandableItems_; 329 bool onTouchEventSet_ = false; 330 bool onHoverEventSet_ = false; 331 bool onKeyEventSet_ = false; 332 bool onClickEventSet_ = false; 333 SubMenuExpandingMode expandingMode_ = SubMenuExpandingMode::SIDE; 334 bool isStackSubmenuHeader_ = false; 335 bool expandingModeSet_ = false; 336 337 Color bgBlendColor_ = Color::TRANSPARENT; 338 339 bool blockClick_ = false; 340 341 ACE_DISALLOW_COPY_AND_MOVE(MenuItemPattern); 342 }; 343 344 class CustomMenuItemPattern : public MenuItemPattern { 345 DECLARE_ACE_TYPE(CustomMenuItemPattern, MenuItemPattern); 346 347 public: CreateLayoutAlgorithm()348 RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override 349 { 350 return MakeRefPtr<BoxLayoutAlgorithm>(); 351 } 352 void OnAttachToFrameNode() override; 353 354 private: 355 void OnTouch(const TouchEventInfo& info) override; 356 void HandleOnChange(); 357 bool OnKeyEvent(const KeyEvent& event) override; IsCustomMenuItem()358 bool IsCustomMenuItem() override 359 { 360 return true; 361 } 362 std::unique_ptr<Offset> lastTouchOffset_; 363 }; 364 } // namespace OHOS::Ace::NG 365 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_MENU_MENU_ITEM_PATTERN_H 366