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_PATTERN_MENU_MENU_LAYOUT_ALGORITHM_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_MENU_MENU_LAYOUT_ALGORITHM_H 18 19 #include <list> 20 21 #include "base/geometry/ng/offset_t.h" 22 #include "base/memory/referenced.h" 23 #include "core/components/common/properties/placement.h" 24 #include "core/components_ng/layout/box_layout_algorithm.h" 25 #include "core/components_ng/pattern/menu/menu_layout_property.h" 26 #include "core/components_ng/pattern/menu/menu_paint_property.h" 27 28 namespace OHOS::Ace::NG { 29 class MenuLayoutProperty; 30 class MenuPattern; 31 class MenuLayoutAlgorithm : public BoxLayoutAlgorithm { 32 DECLARE_ACE_TYPE(MenuLayoutAlgorithm, BoxLayoutAlgorithm) 33 public: 34 MenuLayoutAlgorithm(int32_t id, const std::string& tag); 35 MenuLayoutAlgorithm() = default; 36 ~MenuLayoutAlgorithm() override; 37 38 // override measureSelf and measureChildren. 39 void Measure(LayoutWrapper* layoutWrapper) override; 40 41 void Layout(LayoutWrapper* layoutWrapper) override; 42 43 protected: 44 float VerticalLayout(const SizeF& size, float clickPosition); 45 float HorizontalLayout(const SizeF& size, float clickPosition, bool IsSelectMenu = false); 46 47 RefPtr<MenuPaintProperty> GetPaintProperty(const LayoutWrapper* layoutWrapper); 48 OffsetF GetMenuWrapperOffset(const LayoutWrapper* layoutWrapper); 49 50 // position input is relative to main window left top point, 51 // menu show position is relative to menuWrapper. 52 OffsetF position_; 53 OffsetF positionOffset_; 54 SizeF wrapperSize_; 55 56 private: 57 enum class ErrorPositionType { 58 NORMAL = 0, 59 TOP_LEFT_ERROR, 60 BOTTOM_RIGHT_ERROR, 61 }; 62 void Initialize(LayoutWrapper* layoutWrapper); 63 void InitializePadding(LayoutWrapper* layoutWrapper); 64 void ModifyPositionToWrapper(LayoutWrapper* layoutWrapper, OffsetF& position); 65 LayoutConstraintF CreateChildConstraint(LayoutWrapper* layoutWrapper); 66 void UpdateConstraintWidth(LayoutWrapper* layoutWrapper, LayoutConstraintF& constraint); 67 void UpdateConstraintHeight(LayoutWrapper* layoutWrapper, LayoutConstraintF& constraint); 68 void UpdateConstraintBaseOnOptions(LayoutWrapper* layoutWrapper, LayoutConstraintF& constraint); 69 void UpdateOptionConstraint(std::list<RefPtr<LayoutWrapper>>& options, float width); 70 71 void ComputeMenuPositionByAlignType(const RefPtr<MenuLayoutProperty>& menuProp, const SizeF& menuSize); 72 OffsetF ComputeMenuPositionByOffset( 73 const RefPtr<MenuLayoutProperty>& menuProp, const RefPtr<GeometryNode>& geometryNode); 74 OffsetF MenuLayoutAvoidAlgorithm(const RefPtr<MenuLayoutProperty>& menuProp, const RefPtr<MenuPattern>& menuPattern, 75 const SizeF& size, bool didNeedArrow = false); 76 void SetMenuPlacementForAnimation(LayoutWrapper* layoutWrapper); 77 78 void LayoutArrow(const LayoutWrapper* layoutWrapper); 79 OffsetF GetArrowPositionWithPlacement(const SizeF& menuSize); 80 bool GetIfNeedArrow(const LayoutWrapper* layoutWrapper, const SizeF& menuSize); 81 void UpdateArrowOffsetWithMenuLimit(const SizeF& menuSize); 82 void UpdatePropArrowOffset(); 83 84 // get option LayoutWrapper for measure get max width 85 std::list<RefPtr<LayoutWrapper>> GetOptionsLayoutWrappper(LayoutWrapper* layoutWrapper); 86 87 OffsetF GetPositionWithPlacement(const SizeF& childSize, const OffsetF& topPosition, const OffsetF& bottomPosition); 88 void InitTargetSizeAndPosition(const LayoutWrapper* layoutWrapper, bool isContextMenu); 89 OffsetF GetChildPosition(const SizeF& childSize, bool didNeedArrow = false); 90 OffsetF FitToScreen(const OffsetF& position, const SizeF& childSize, bool didNeedArrow = false); 91 bool CheckPosition(const OffsetF& position, const SizeF& childSize); 92 93 OffsetF GetPositionWithPlacementTop(const SizeF&, const OffsetF&, const OffsetF&); 94 OffsetF GetPositionWithPlacementTopLeft(const SizeF&, const OffsetF&, const OffsetF&); 95 OffsetF GetPositionWithPlacementTopRight(const SizeF&, const OffsetF&, const OffsetF&); 96 OffsetF GetPositionWithPlacementBottom(const SizeF&, const OffsetF&, const OffsetF&); 97 OffsetF GetPositionWithPlacementBottomLeft(const SizeF&, const OffsetF&, const OffsetF&); 98 OffsetF GetPositionWithPlacementBottomRight(const SizeF&, const OffsetF&, const OffsetF&); 99 OffsetF GetPositionWithPlacementLeft(const SizeF&, const OffsetF&, const OffsetF&); 100 OffsetF GetPositionWithPlacementLeftTop(const SizeF&, const OffsetF&, const OffsetF&); 101 OffsetF GetPositionWithPlacementLeftBottom(const SizeF&, const OffsetF&, const OffsetF&); 102 OffsetF GetPositionWithPlacementRight(const SizeF&, const OffsetF&, const OffsetF&); 103 OffsetF GetPositionWithPlacementRightTop(const SizeF&, const OffsetF&, const OffsetF&); 104 OffsetF GetPositionWithPlacementRightBottom(const SizeF&, const OffsetF&, const OffsetF&); 105 OffsetF AddTargetSpace(const OffsetF& position); 106 OffsetF AddOffset(const OffsetF& position); 107 bool CheckPositionInPlacementRect(const Rect& rect, const OffsetF& position, const SizeF& childSize); 108 OffsetF AdjustPosition(const OffsetF& position, float width, float height, float space); 109 OffsetF GetAdjustPosition(std::vector<Placement>& currentPlacementStates, size_t step, const SizeF& childSize, 110 const OffsetF& topPosition, const OffsetF& bottomPosition); 111 112 RefPtr<PipelineContext> GetCurrentPipelineContext(); 113 114 OffsetF targetOffset_; 115 SizeF targetSize_; 116 Placement placement_ = Placement::BOTTOM_LEFT; 117 int32_t targetNodeId_ = -1; 118 std::string targetTag_; 119 120 // current page offset relative to window. 121 float topSpace_ = 0.0f; 122 float bottomSpace_ = 0.0f; 123 float leftSpace_ = 0.0f; 124 float rightSpace_ = 0.0f; 125 126 // arrow 127 float menuRadius_ = 0.0f; 128 float targetSpace_ = 0.0f; 129 float arrowMinLimit_ = 0.0f; 130 float arrowOffset_ = 0.0f; 131 float arrowWidth_ = 0.0f; 132 bool arrowInMenu_ = false; 133 bool propNeedArrow_ = false; 134 OffsetF arrowPosition_; 135 Dimension propArrowOffset_; 136 std::unordered_set<Placement> setHorizontal_; 137 std::unordered_set<Placement> setVertical_; 138 Placement arrowPlacement_ = Placement::NONE; 139 140 float margin_ = 0.0f; 141 float paddingStart_ = 0.0f; 142 float paddingEnd_ = 0.0f; 143 float paddingTop_ = 0.0f; 144 float paddingBottom_ = 0.0f; 145 float optionPadding_ = 0.0f; 146 147 using PlacementFunc = OffsetF (MenuLayoutAlgorithm::*)(const SizeF&, const OffsetF&, const OffsetF&); 148 std::map<Placement, PlacementFunc> placementFuncMap_; 149 150 ACE_DISALLOW_COPY_AND_MOVE(MenuLayoutAlgorithm); 151 }; 152 } // namespace OHOS::Ace::NG 153 154 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_MENU_MENU_LAYOUT_ALGORITHM_H 155